UNPKG

fluidstate

Version:

Library for fine-grained reactivity state management

92 lines (88 loc) 3.45 kB
"use strict"; 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