UNPKG

fluidstate

Version:

Library for fine-grained reactivity state management

105 lines (101 loc) 4.57 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.removeReactiveRemote = exports.getReactiveInstance = exports.addReactiveRemote = void 0; var _reactiveAtom = require("./reactive-atom"); var _reactiveComputed = require("./reactive-computed"); var _reactiveReaction = require("./reactive-reaction"); var _reactiveTracking = require("./reactive-tracking"); var _reactiveAction = require("./reactive-action"); var _reactiveRemotesData = require("./reactive-remotes-data"); const REACTIVE_INSTANCE = { createAtom: _reactiveAtom.createAtom, createComputedAtom: _reactiveComputed.createComputedAtom, createReaction: _reactiveReaction.createReaction, isTracking: _reactiveTracking.isTracking, untrack: _reactiveTracking.untrack, runTransaction: _reactiveAction.runTransaction, runAction: _reactiveAction.runAction }; /** * Creates and returns a new `ReactiveInstance` object. * * A `ReactiveInstance` encapsulates a set of reactive primitive functions * (`createAtom`, `createComputedAtom`, `createReaction`, etc.) operating * on the currently provided reactive layer. * * This function is typically used by a system (e.g., a UI library or a game engine module) * to obtain its own handle to the reactive capabilities. This handle can then be * passed to another system to establish a "remote" reactive relationship, * allowing for controlled interaction and data synchronization between them. * * @returns A `ReactiveInstance` object. */ const getReactiveInstance = () => { return REACTIVE_INSTANCE; }; /** * Adds an external `ReactiveInstance` as a "remote" to the current reactive system. * * This establishes a relationship where the local system can be aware of the remote * system. If a `scheduler` is provided in the options, reactions originating from * (or related to) the remote instance that depend on local data can be scheduled * according to the local system's defined timing. * * This is crucial for scenarios where one reactive system (e.g., a game engine) * needs to integrate with another (e.g., a user's application state) * while maintaining control over update cycles. * * @param reactiveInstance - The external `ReactiveInstance` to be added. * @param options - Optional configuration for the remote connection, * primarily for providing a custom `scheduler`. * @returns The `reactiveInstance` that was added. * @throws Error if the `reactiveInstance` has already been added or when * trying to add instance as its own remote. */ exports.getReactiveInstance = getReactiveInstance; const addReactiveRemote = (reactiveInstance, options) => { if (reactiveInstance === REACTIVE_INSTANCE) { throw new Error(`Cannot add reactive instance as its own remote`); } if (_reactiveRemotesData.reactiveRemotes.has(reactiveInstance)) { throw new Error(`Reactive remote was already added`); } _reactiveRemotesData.reactiveRemotes.add(reactiveInstance); _reactiveRemotesData.remoteOptionsMap.set(reactiveInstance, options ?? null); _reactiveRemotesData.remoteReactionsMap.set(reactiveInstance, new Set()); return reactiveInstance; }; /** * Removes a `ReactiveInstance` that was previously added as a remote. * * This function cleans up the remote connection by: * 1. Stopping any reactions that were specifically associated with this remote instance * (e.g., reactions created by the local system to observe the remote system's data, * or reactions whose scheduling was managed due to this remote connection). * 2. Removing the `reactiveInstance` from the internal tracking collections. * * @param reactiveInstance - The `ReactiveInstance` to remove. * @throws Error if the `reactiveInstance` was not found in the set of active remotes. */ exports.addReactiveRemote = addReactiveRemote; const removeReactiveRemote = reactiveInstance => { if (!_reactiveRemotesData.reactiveRemotes.has(reactiveInstance)) { throw new Error(`Remote was not found`); } stopRemoteReactions(reactiveInstance); _reactiveRemotesData.reactiveRemotes.delete(reactiveInstance); _reactiveRemotesData.remoteOptionsMap.delete(reactiveInstance); _reactiveRemotesData.remoteReactionsMap.delete(reactiveInstance); }; exports.removeReactiveRemote = removeReactiveRemote; const stopRemoteReactions = reactiveInstance => { const remoteReactions = _reactiveRemotesData.remoteReactionsMap.get(reactiveInstance); if (remoteReactions) { for (const reaction of remoteReactions) { reaction.stop(); } } }; //# sourceMappingURL=reactive-remotes.js.map