fluidstate
Version:
Library for fine-grained reactivity state management
92 lines (88 loc) • 3.45 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.runTransaction = exports.runRemoteActions = exports.runAction = exports.createAction = void 0;
var _reactiveLayer = require("./reactive-layer");
var _reactiveRemotesData = require("./reactive-remotes-data");
var _recursiveUtils = require("./recursive-utils");
const isAction = new WeakSet();
const functionActionMap = new WeakMap();
const runRemoteActions = action => {
return (0, _recursiveUtils.applyRecursive)([..._reactiveRemotesData.reactiveRemotes.values()].map(remote => remote.runAction), action);
};
/**
* Runs the provided `action` function within a transaction block for the main
* reactive layer and all registered reactive remotes.
*
* Transactions ensure that multiple state changes are batched, and reactions
* are triggered only after the entire transaction completes. This is a
* lower-level API compared to `runAction`.
*
* @param action - The function to execute within the transaction.
* @returns The result of the `action` function.
*/
exports.runRemoteActions = runRemoteActions;
const runTransaction = action => {
return (0, _reactiveLayer.getReactiveLayer)().runTransaction(() => {
return (0, _recursiveUtils.applyRecursive)([..._reactiveRemotesData.reactiveRemotes.values()].map(remote => remote.runTransaction), action);
});
};
/**
* Runs the provided `action` function, ensuring that all reactive state
* mutations within it are treated as a single atomic operation for both the
* main reactive layer and all registered reactive remotes.
*
* This function is similar to `runTransaction` but is the preferred higher-level
* API for batching state changes. Reactive systems might enforce that all
* state mutations occur within an action.
*
* @param action - The function to execute, which may contain state mutations.
* @returns The result of the `action` function.
*/
exports.runTransaction = runTransaction;
const runAction = action => {
return (0, _reactiveLayer.getReactiveLayer)().runAction(() => {
return runRemoteActions(action);
});
};
exports.runAction = runAction;
const actionProxyHandler = {
apply(target, thisArg, argArray) {
let result;
runAction(() => {
result = Reflect.apply(target, thisArg, argArray);
});
return result;
}
};
/**
* Wraps a given function `fn` to ensure that its execution is treated as a
* reactive action. When the wrapped function is called, any state mutations
* performed within it are batched, and reactive updates are deferred until
* the function completes.
*
* This is useful for methods or functions that perform multiple state changes
* which should be seen as a single atomic update by the reactive system.
*
* The function memoizes the created action, so calling `createAction` multiple
* times with the same original function will return the same wrapped action.
*
* @template T The type of the function to wrap.
* @param fn The function to be wrapped as an action.
* @returns A new function that, when called, executes `fn` within a reactive action.
*/
const createAction = fn => {
if (isAction.has(fn)) {
return fn;
}
let action = functionActionMap.get(fn);
if (!action) {
action = new Proxy(fn, actionProxyHandler);
isAction.add(action);
functionActionMap.set(fn, action);
}
return action;
};
exports.createAction = createAction;
//# sourceMappingURL=reactive-action.js.map