fluidstate
Version:
Library for fine-grained reactivity state management
65 lines (63 loc) • 2.88 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createComputedAtom = void 0;
var _reactiveLayer = require("./reactive-layer");
var _reactiveOptions = require("./reactive-options");
var _reactiveRemoteAtoms = require("./reactive-remote-atoms");
var _reactiveTracking = require("./reactive-tracking");
/**
* Creates a computed reactive atom that derives its value from other reactive sources.
*
* This function wraps the reactive layer's `createComputedAtom` primitive, adding
* handling of reactive remotes.
*
* The computed value is cached and only re-evaluated if its dependencies change,
* provided it's being observed by a reaction. Otherwise, it behaves like a
* regular getter, re-computing on each call.
*
* @param name - A descriptive name for the computed atom, useful for debugging.
* @param calculate - The function that computes the value of the atom. It will
* be re-run when its reactive dependencies change.
* @param options - Optional configuration for the computed atom, such as
* custom equality checks (`equals`) or lifecycle listeners (`onBecomeObservedListener`,
* `onBecomeUnobservedListener`).
* @returns A `ComputedAtom` instance.
*/
const createComputedAtom = (name, calculate, options) => {
const layerComputed = (0, _reactiveLayer.getReactiveLayer)().createComputedAtom(name, () => {
const previousDerivation = (0, _reactiveTracking.getTrackingDerivation)();
(0, _reactiveTracking.setTrackingDerivation)(computedAtom);
try {
// The calculation is wrapped with `untrackRemotes` because we'd like
// remotes to only depend on the computed atom, not on its dependencies
return (0, _reactiveTracking.untrackRemotes)(() => {
return calculate();
});
} finally {
(0, _reactiveTracking.setTrackingDerivation)(previousDerivation);
}
}, !options ? _reactiveOptions.defaultComputedOptions : {
..._reactiveOptions.defaultComputedOptions,
...options
});
const computedAtom = {
get() {
// When this computed atom is accessed, notify any reactive remotes
// that it is being observed. This allows remotes to establish their
// own dependencies on this atom if they are tracking.
(0, _reactiveRemoteAtoms.observeRemoteAtoms)(computedAtom, layerComputed, name);
// If we are in a tracking context, calling `get()` will establish a
// dependency in the underlying reactive layer. Otherwise, we wrap it
// in `untrack` to get the value without creating a dependency.
if ((0, _reactiveTracking.isTrackingDerivation)()) {
return layerComputed.get();
}
return (0, _reactiveLayer.getReactiveLayer)().untrack(() => layerComputed.get());
}
};
return computedAtom;
};
exports.createComputedAtom = createComputedAtom;
//# sourceMappingURL=reactive-computed.js.map