UNPKG

fluidstate

Version:

Library for fine-grained reactivity state management

149 lines (142 loc) 5.24 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.setProxy = exports.isReactive = exports.getReactive = exports.getProxyComputedKeys = exports.getInert = exports.getComputedKeys = exports.ensureInert = exports.createReactive = exports.createProxy = void 0; var _reactiveArray = require("./reactive-array"); var _reactiveMap = require("./reactive-map"); var _reactiveObject = require("./reactive-object"); var _reactivePromise = require("./reactive-promise"); var _reactiveSet = require("./reactive-set"); var _reactiveUtils = require("./reactive-utils"); const inertProxyMap = new WeakMap(); const proxyInertMap = new WeakMap(); const isProxySet = new WeakSet(); /** * Creates a reactive version of the provided object. * This is the primary entry point for making data structures reactive. * It supports objects, arrays, Sets, Maps, and Promises. * * @param value The object to make reactive. * @param reactiveOptions Optional configuration for the reactive instance. * @returns A reactive proxy of the input object, or the value itself if it cannot be made reactive. */ const createReactive = (value, reactiveOptions) => { const { name, ...otherReactiveOptions } = reactiveOptions ?? {}; return createProxy(value, otherReactiveOptions, name ? { atomName: name } : undefined); }; exports.createReactive = createReactive; const createProxy = (value, reactiveOptions, nameOptions) => { if ((0, _reactiveUtils.isObject)(value) && Object.isFrozen(value)) { return ensureInert(value); } if ((0, _reactiveUtils.isObject)(value)) { const proxy = getReactive(value); if (proxy) { return proxy; } } if (Array.isArray(value)) { const proxy = (0, _reactiveArray.createReactiveArray)(value, reactiveOptions, nameOptions); return setProxy(value, proxy); } else if ((0, _reactiveUtils.isObject)(value)) { if (value instanceof Set) { const proxy = (0, _reactiveSet.createReactiveSet)(value, reactiveOptions, nameOptions); return setProxy(value, proxy); } else if (value instanceof Map) { const proxy = (0, _reactiveMap.createReactiveMap)(value, reactiveOptions, nameOptions); return setProxy(value, proxy); } else if (value instanceof Promise) { (0, _reactivePromise.providePromiseAtomName)(value, nameOptions); return value; } else { const proxy = (0, _reactiveObject.createReactiveObject)(value, reactiveOptions, nameOptions); return setProxy(value, proxy); } } return value; }; exports.createProxy = createProxy; const setProxy = (inertObject, proxy) => { inertProxyMap.set(inertObject, proxy); proxyInertMap.set(proxy, inertObject); isProxySet.add(proxy); return proxy; }; /** * Checks if a given value is a reactive proxy. * * @param value The value to check. * @returns `true` if the value is a reactive proxy, `false` otherwise. */ exports.setProxy = setProxy; const isReactive = value => { return isProxySet.has(value); }; /** * Retrieves the reactive proxy associated with a given object. * If the object itself is a proxy, it is returned. * If the object is an inert (original) object that has a reactive proxy, that proxy is returned. * * @param value The object for which to get the reactive proxy. * @returns The reactive proxy if one exists, otherwise `null`. */ exports.isReactive = isReactive; const getReactive = value => { if (isProxySet.has(value)) { return value; } else { const proxy = inertProxyMap.get(value); if (proxy) { return proxy; } } return null; }; /** * Retrieves the original, underlying non-reactive (inert) object from a reactive proxy. * * @param proxy The reactive proxy. * @returns The underlying inert object if `proxy` is a known reactive proxy, otherwise `null`. */ exports.getReactive = getReactive; const getInert = proxy => { return proxyInertMap.get(proxy) ?? null; }; /** * Ensures that the returned value is the inert (non-reactive) version of the input. * If the input is a reactive proxy, its underlying inert version is returned. * Otherwise, the input value is returned as is. * * @param value The value to ensure is inert. * @returns The underlying inert version of the value. */ exports.getInert = getInert; const ensureInert = value => { return (0, _reactiveUtils.isObject)(value) && getInert(value) || value; }; /** * Retrieves a set of keys that correspond to computed properties (getters) on a reactive object. * For non-object types or non-reactive objects, an empty set is returned. * * @param object The reactive object (or any value). * @returns A `Set` of string or symbol keys representing computed properties. */ exports.ensureInert = ensureInert; const getComputedKeys = object => { if ((0, _reactiveUtils.isObject)(object) && !Array.isArray(object) && !(object instanceof Set) && !(object instanceof Map)) { return getProxyComputedKeys(object); } return new Set(); }; exports.getComputedKeys = getComputedKeys; const getProxyComputedKeys = proxy => { return (0, _reactiveUtils.getAllGetterKeys)(ensureInert(proxy)); }; exports.getProxyComputedKeys = getProxyComputedKeys; //# sourceMappingURL=reactive-proxy.js.map