Skip to content

Commit 58c05e7

Browse files
committed
Merge branch 'persistence/persistableFixableAtom-areEqualFunction' into rubenthoms/persistence/module-states
2 parents e67eb14 + 0a166dd commit 58c05e7

File tree

1 file changed

+30
-10
lines changed

1 file changed

+30
-10
lines changed

frontend/src/framework/utils/atomUtils.ts

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@ type PersistableFixableAtomOptionsWithPrecompute<TValue, TPrecomputedValue> = {
9090
*/
9191
initialValue: TValue;
9292

93+
/**
94+
* A function to compare two values for equality.
95+
* This is used to optimize updates by preventing unnecessary re-renders.
96+
*/
97+
areEqualFunction?: (a: TValue, b: TValue) => boolean;
98+
9399
precomputeFunction: (options: { value: TValue; get: Getter }) => TPrecomputedValue;
94100
/**
95101
* A function to validate whether the given value is valid in the current application context.
@@ -123,6 +129,12 @@ type PersistableFixableAtomOptionsWithoutPrecompute<TValue> = {
123129
*/
124130
initialValue: TValue;
125131

132+
/**
133+
* A function to compare two values for equality.
134+
* This is used to optimize updates by preventing unnecessary re-renders.
135+
*/
136+
areEqualFunction?: (a: TValue, b: TValue) => boolean;
137+
126138
/**
127139
* A function to validate whether the given value is valid in the current application context.
128140
* Called whenever the atom is read to determine if a persisted value is still valid.
@@ -226,20 +238,28 @@ export function persistableFixableAtom<TValue, TPrecomputedValue>(
226238
_source: internalState._source,
227239
};
228240
},
229-
(_, set, update: TValue | PersistableAtomState<TValue>) => {
241+
(get, set, update: TValue | PersistableAtomState<TValue>) => {
242+
const areEqualFunc = options.areEqualFunction;
243+
const currentState = get(internalStateAtom);
244+
230245
if (isInternalState(update)) {
231-
set(internalStateAtom, {
232-
...update,
233-
});
246+
if (areEqualFunc && areEqualFunc(currentState.value, update.value)) {
247+
// If values are equal, preserve value reference, but update source if different
248+
if (currentState._source !== update._source) {
249+
set(internalStateAtom, { value: currentState.value, _source: update._source });
250+
}
251+
return;
252+
}
253+
set(internalStateAtom, { ...update });
234254
return;
235255
}
236256

237-
const newInternalState: PersistableAtomState<TValue> = {
238-
value: update,
239-
_source: Source.USER,
240-
};
241-
242-
set(internalStateAtom, newInternalState);
257+
// Handle direct value updates (non-internal state)
258+
const value =
259+
areEqualFunc && areEqualFunc(currentState.value, update)
260+
? currentState.value // Preserve reference when equal
261+
: update;
262+
set(internalStateAtom, { value, _source: Source.USER });
243263
},
244264
);
245265

0 commit comments

Comments
 (0)