UNPKG

fluidstate

Version:

Library for fine-grained reactivity state management

107 lines (106 loc) 4.85 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createReactiveArray = void 0; var _reactiveNames = require("../extras/reactive-names"); var _reactivePluginArray = require("../extras/reactive-plugin-array"); var _reactivePlugin = require("../extras/reactive-plugin"); var _reactiveAtom = require("../primitives/reactive-atom"); var _reactiveOptions = require("../primitives/reactive-options"); var _reactiveChildren = require("./reactive-children"); var _reactiveProxy = require("./reactive-proxy"); const createReactiveArray = (inertArr, reactiveOptions, nameOptions) => { const atomName = (0, _reactiveNames.createAtomNameFromOptions)(nameOptions); const proxy = new Proxy(inertArr, new ReactiveArrayProxyHandler(atomName, { items: (0, _reactiveAtom.createAtom)((0, _reactiveNames.createArrayAtomName)(atomName)) }, () => proxy, reactiveOptions)); return proxy; }; exports.createReactiveArray = createReactiveArray; class ReactiveArrayProxyHandler { #atomName; #reactive; #getProxy; #options; constructor(atomName, reactive, getProxy, reactiveOptions) { this.#atomName = atomName; this.#reactive = reactive; this.#getProxy = getProxy; this.#options = { reactiveOptions }; } get(inertArr, property, receiver) { const p = property; const ownPropertyDescriptor = Reflect.getOwnPropertyDescriptor(inertArr, p); const isInherited = Reflect.has(inertArr, p) && !ownPropertyDescriptor; if (!isInherited) { this.#reactive.items.reportObserved(); } const result = Reflect.get(inertArr, p, receiver); return (0, _reactiveChildren.getChild)(this.#options, result, () => (0, _reactiveProxy.createProxy)(result, (0, _reactiveChildren.getChildOptions)(this.#options), { parentAtomName: this.#atomName, createAtomName: _reactiveNames.createArrayItemAtomName, childIndex: p.toString() })); } set(inertArr, property, newValue, receiver) { const p = property; const hasProperty = inertArr.hasOwnProperty(property); const newStoredValue = this.#options.reactiveOptions?.deep === false ? newValue : (0, _reactiveProxy.ensureInert)(newValue); const currentValue = Reflect.get(inertArr, property, receiver); const isChanged = !(0, _reactiveOptions.reactiveValueEquals)(currentValue, newValue); const previousLength = inertArr.length; const willChangeForPlugins = this.#hasPlugins() && (isChanged && p !== "length" || p === "length" && Number(newValue) !== previousLength || !hasProperty); const changes = !willChangeForPlugins ? null : (0, _reactivePluginArray.getArraySetChanges)(this.#getProxy(), inertArr, p, currentValue, newStoredValue, previousLength); if (changes) { (0, _reactivePlugin.beforeChange)(changes, this.#options.reactiveOptions?.plugins); } const result = Reflect.set(inertArr, property, newStoredValue, receiver); const isLengthChanged = previousLength !== inertArr.length; if (result) { // The length property does not automatically get trapped when, for example, // setting the value like this: `array[array.length] = 10`, because there // is no internal call to a function where `this` refers to a proxy; hence, // we have to manually check it after applying the update if (isChanged && p !== "length" || isLengthChanged || !hasProperty) { this.#reactive.items.reportChanged(); } } if (changes) { (0, _reactivePlugin.afterChange)(changes, this.#options.reactiveOptions?.plugins); } return result; } deleteProperty(inertArr, property) { const p = property; // p can be 'length' or a number here const hasProperty = inertArr.hasOwnProperty(property); const currentValue = Reflect.get(inertArr, property); const isChanged = !(0, _reactiveOptions.reactiveValueEquals)(currentValue, undefined); const previousLength = inertArr.length; const changes = !this.#hasPlugins() || !isChanged ? null : (0, _reactivePluginArray.getArrayDeleteChanges)(this.#getProxy(), p, currentValue); if (changes) { (0, _reactivePlugin.beforeChange)(changes, this.#options.reactiveOptions?.plugins); } const result = Reflect.deleteProperty(inertArr, property); const isLengthChanged = previousLength !== inertArr.length; if (result) { if (isChanged && p !== "length" || isLengthChanged || hasProperty) { this.#reactive.items.reportChanged(); } } if (changes) { (0, _reactivePlugin.afterChange)(changes, this.#options.reactiveOptions?.plugins); } return result; } ownKeys(inertArr) { this.#reactive.items.reportObserved(); return Reflect.ownKeys(inertArr); } #hasPlugins() { return (this.#options.reactiveOptions?.plugins?.length ?? 0) > 0; } } //# sourceMappingURL=reactive-array.js.map