fluidstate
Version:
Library for fine-grained reactivity state management
105 lines (101 loc) • 4.57 kB
JavaScript
;
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