UNPKG

rvx

Version:

A signal based rendering library

103 lines 3.29 kB
import { $, batch, isTracking } from "../core/signals.js"; import { ProbeMap } from "./probes.js"; export function createReactiveArrayProxy(target, barrier) { const length = $(target.length); const indexProbes = new ProbeMap(i => target[i]); return new Proxy(target, { get(target, prop, recv) { if (prop === "length") { length.access(); return target.length; } const index = asCanonicalIndex(prop); if (index !== undefined) { indexProbes.access(index); return barrier.wrap(target[index]); } if (Object.hasOwn(replacements, prop)) { return replacements[prop]; } return Reflect.get(target, prop, recv); }, set(target, prop, value, recv) { if (prop === "length") { batch(() => { const previous = target.length; target.length = value; for (let i = previous; i >= target.length; i--) { indexProbes.update(i, undefined); } length.value = Number(value); }); return true; } const index = asCanonicalIndex(prop); if (index !== undefined) { batch(() => { value = barrier.unwrap(value); target[index] = value; indexProbes.update(index, value); }); return true; } return Reflect.set(target, prop, value, recv); }, has(target, prop) { const cIndex = asCanonicalIndex(prop); if (cIndex !== undefined) { indexProbes.access(cIndex); return cIndex in target; } return Reflect.has(target, prop); }, deleteProperty(target, prop) { const index = asCanonicalIndex(prop); if (index !== undefined) { batch(() => { delete target[index]; indexProbes.update(index, undefined); }); return true; } return Reflect.deleteProperty(target, prop); }, ownKeys(target) { if (isTracking()) { length.access(); for (let i = 0; i < target.length; i++) { indexProbes.access(i); } } return Reflect.ownKeys(target); }, }); } const replacements = Object.create(null); for (const key of [ "copyWithin", "fill", "pop", "push", "reverse", "shift", "sort", "splice", "unshift", ]) { replacements[key] = function (...args) { return batch(() => { return Array.prototype[key].call(this, ...args); }); }; } function asCanonicalIndex(value) { if (typeof value === "symbol") { return undefined; } const index = Number(value); if (Number.isSafeInteger(index) && index >= 0 && index <= 0xFFFFFFFF) { return index; } return undefined; } //# sourceMappingURL=reactive-array-proxy.js.map