From eb6975c7de0e0c60e898a103f6e2a0c27c7f9c47 Mon Sep 17 00:00:00 2001 From: metacryst Date: Fri, 26 Dec 2025 04:22:22 -0600 Subject: [PATCH] state array working --- Test/state/state.test.js | 2 +- index.js | 65 ++++++++++++++++++++++++++++++---------- 2 files changed, 50 insertions(+), 17 deletions(-) diff --git a/Test/state/state.test.js b/Test/state/state.test.js index b8ea51d..f124ab7 100644 --- a/Test/state/state.test.js +++ b/Test/state/state.test.js @@ -33,7 +33,7 @@ window.testSuites.push( class testState { .fontSize(() => {return this.state.logs.length > 0 ? [2, em] : [1, em]}) }) .onAppear(() => { - this.state.logs = ["one", "two"] + this.state.logs.push("one") }) } } diff --git a/index.js b/index.js index 1c3c315..e089540 100644 --- a/index.js +++ b/index.js @@ -228,25 +228,58 @@ window.register = (el, tagname) => { window[el.prototype.constructor.name] = function (...params) { let instance = new el(...params) if(instance.state) { - let proxy = new Proxy(instance.state, { - get(target, prop, receiver) { - if (typeof prop === "symbol") { // Ignore internal / symbol accesses - return Reflect.get(target, prop, receiver); - } + const proxyCache = new WeakMap(); - quill.lastLastState = quill.lastState - quill.lastState = prop; - return Reflect.get(target, prop, receiver); - }, - set(target, prop, value, receiver) { - const oldValue = target[prop]; - if (oldValue === value) return true; + function reactive(value, path=[]) { + if (value && typeof value === "object") { + if (proxyCache.has(value)) return proxyCache.get(value); - const result = Reflect.set(target, prop, value, receiver); - instance.stateWatchers[prop].forEach((cb) => cb()) - return result; + const p = new Proxy(value, createHandlers(path)); + proxyCache.set(value, p); + return p; } - }); + return value; + } + + function isNumericKey(prop) { + return typeof prop === "string" && prop !== "" && String(+prop) === prop; + } + + function createHandlers(path) { + return { + get(target, prop, receiver) { + if (typeof prop === "symbol") { + return Reflect.get(target, prop, receiver); + } + + let nextPath = (Array.isArray(target) && !isNumericKey(prop)) ? path : path.concat(prop) // To filter out arr.length, arr.map, arr.forEach, etc. + quill.lastState = nextPath.join("."); + + const v = Reflect.get(target, prop, receiver); + return reactive(v, nextPath); + }, + + set(target, prop, value, receiver) { + const oldLength = Array.isArray(target) ? target.length : undefined; + const oldValue = target[prop]; + if (oldValue === value) return true; + + const result = Reflect.set(target, prop, value, receiver); + + let changedPath = (Array.isArray(target) && (!isNumericKey(prop) || target.length !== oldLength)) ? path : path.concat(prop).join("."); // To filter out arr.length, arr.map, arr.forEach, and also a push/pop/unshift. + const watchers = instance.stateWatchers[changedPath]; + + if (watchers) { + watchers.forEach(cb => cb()); + } + + return result; + } + }; + } + + let proxy = reactive(instance.state) + Object.defineProperty(instance, "state", { value: proxy, writable: false,