fluidstate
Version:
Library for fine-grained reactivity state management
81 lines (80 loc) • 3.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.cloneInert = void 0;
var _reactiveChildren = require("../abstractions/reactive-children");
var _reactiveProxy = require("../abstractions/reactive-proxy");
var _reactiveUtils = require("../abstractions/reactive-utils");
/**
* Creates a deep or shallow clone of a reactive object, array, Set, or Map,
* returning an "inert" (non-reactive) version.
*
* This is useful for obtaining a snapshot of the reactive state at a specific moment
* without any reactive overhead.
*
* @param object The reactive (or non-reactive) data structure to clone.
* @param cloneInertOptions Options to control the cloning behavior (e.g., depth, exclusion of computed properties).
* @returns An inert clone of the input. The exact type depends on the input and options.
*/
const cloneInert = (object, cloneInertOptions) => {
return cloneAny(object, new Map(), cloneInertOptions, false);
};
exports.cloneInert = cloneInert;
const cloneAny = (object, visited, cloneInertOptions, requireSimpleObject = true) => {
if (!(0, _reactiveProxy.isReactive)(object) && (!(0, _reactiveChildren.isSimpleObject)(object) && requireSimpleObject || !(0, _reactiveUtils.isObject)(object) || Object.isFrozen(object))) {
return (0, _reactiveProxy.ensureInert)(object);
}
const inertObject = (0, _reactiveProxy.ensureInert)(object);
if (!visited.has(inertObject)) {
if (Array.isArray(inertObject)) {
return cloneReactiveArray(object, inertObject, visited, cloneInertOptions);
}
if (inertObject instanceof Set) {
return cloneReactiveSet(object, inertObject, visited, cloneInertOptions);
}
if (inertObject instanceof Map) {
return cloneReactiveMap(object, inertObject, visited, cloneInertOptions);
}
return cloneReactiveObject(object, inertObject, visited, cloneInertOptions);
}
return visited.get(inertObject);
};
const cloneReactiveObject = (proxy, inertObject, visited, cloneInertOptions) => {
const newObject = {};
visited.set(inertObject, newObject);
const ownKeys = Reflect.ownKeys(proxy);
const computedKeys = (0, _reactiveProxy.getProxyComputedKeys)(proxy);
const keys = cloneInertOptions?.excludeComputed === true ? new Set(ownKeys.filter(ownKey => !computedKeys.has(ownKey))) : new Set([...ownKeys, ...computedKeys]);
for (const key of keys) {
newObject[key] = cloneAny(proxy[key], visited, cloneInertOptions);
}
return newObject;
};
const cloneReactiveMap = (proxy, inertObject, visited, cloneInertOptions) => {
const newMap = new Map();
visited.set(inertObject, newMap);
for (const [key, value] of proxy) {
const newKey = cloneInertOptions?.deep == false ? key : cloneAny(key, visited, cloneInertOptions);
const newValue = cloneInertOptions?.deep == false ? value : cloneAny(value, visited, cloneInertOptions);
newMap.set(newKey, newValue);
}
return newMap;
};
const cloneReactiveArray = (proxy, inertObject, visited, cloneInertOptions) => {
const newArray = [];
visited.set(inertObject, newArray);
for (let i = 0; i < proxy.length; i++) {
newArray.push(cloneInertOptions?.deep === false ? proxy[i] : cloneAny(proxy[i], visited, cloneInertOptions));
}
return newArray;
};
const cloneReactiveSet = (proxy, inertObject, visited, cloneInertOptions) => {
const newSet = new Set();
visited.set(inertObject, newSet);
for (const value of proxy) {
newSet.add(cloneInertOptions?.deep === false ? value : cloneAny(value, visited, cloneInertOptions));
}
return newSet;
};
//# sourceMappingURL=reactive-deep-clone.js.map