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