diff --git a/reactive.js b/reactive.js index 637df35..63fc8a7 100644 --- a/reactive.js +++ b/reactive.js @@ -84,7 +84,7 @@ function Reactive( base: this, prop, path: localpath, - value: value ?? valueThoughtLocalPath, + value: value, oldValue, pathValues, prefix: this._prefix, @@ -142,10 +142,21 @@ function Reactive( } }, triggerUpTree: function () { - for (prop of this.keys()) { - this.triggerChange(prop); - if (this._target.data[prop].isReactive) { - this._target.data[prop].triggerUpTree(); + if (this.target.data.constructor.name === "Array") { + for (value of this.target.data) { + const prop = this.target.data.indexOf(value); + this.receiver.triggerChange(prop); + if (this.target.data[prop].isReactive) { + this.target.data[prop].triggerUpTree(); + } + } + } + if (this.target.data.constructor.name === "Object") { + for ([prop, value] of Object.entries(this.target.data)) { + this.receiver.triggerChange(prop); + if (this.target.data[prop].isReactive) { + this.target.data[prop].triggerUpTree(); + } } } }, @@ -219,10 +230,10 @@ function Reactive( case "_parent": case "_prefix": case "_proxy": + case "_const": return target[prop]; case "_target": return target; - case "_data": case "_": if (target.data.constructor.name === "Object") { const ret = Object.fromEntries( @@ -256,7 +267,7 @@ function Reactive( case "triggerChange": return target.triggerChange.bind(receiver); case "triggerUpTree": - return target.triggerUpTree.bind(receiver); + return target.triggerUpTree.bind({ target, receiver }); case "orphan": return target.orphan.bind({ receiver, target }); case "rebuildRelationships": @@ -294,12 +305,12 @@ function Reactive( let oldValue = target.data[prop]; //OBJECTS CAN BE CONST + if ( - this._const && - target.data[prop] && + target.data?.[prop]?._const && + value?.isReactive && target.data[prop].isReactive && - value.isReactive && - target.data[prop].constructor.name === "Object" && + target.data[prop]._target.data.constructor.name === "Object" && value?._target?.data.constructor.name === "Object" ) { //ON THIS CASE NO SELF CHANGE diff --git a/test/reactive.test.js b/test/reactive.test.js index 90b4168..1ec4216 100644 --- a/test/reactive.test.js +++ b/test/reactive.test.js @@ -249,7 +249,7 @@ it("Reactive Array", function () { ); }); -it("Remove reactive from parent as itself", function () { +it("Remove reactive from parent as itself, orphan function", function () { const target1 = Reactive(["IM 1"]); const target2 = Reactive(["IM 2"]); const item3 = Reactive(["IM 3"]); @@ -265,6 +265,7 @@ it("Remove reactive from parent as itself", function () { assert.equal(target2._target._parent.prop, 0); item3.orphan(); assert.equal(item3._target._parent, null); + item3.orphan(); }); it("Iterators", function () { @@ -303,3 +304,54 @@ it("Set inner properties", function () { assert.equal(child._parent, null); assert.equal(games._target._parent, null); }); + +it("Const reactive feature", function () { + const target1 = Reactive({ 1: 1, 2: 2, 3: 3, 4: 4, 5: 5 }, { const: true }); + const target2 = Reactive({ 6: 6 }); + const target3 = Reactive({ 2: 2, 4: 4, 6: 6, 8: 8 }); + const games = Reactive({ target1, target2, target3 }); + games.target1 = target2; + games.target3 = target2; + assert.equal(games.target1, target1); + assert.equal( + JSON.stringify(target1._), + JSON.stringify({ + 1: 1, + 2: 2, + 3: 3, + 4: 4, + 5: 5, + 6: 6, + }) + ); + assert.equal(games.target3, target2); +}); + +it("Uptree trigger", function () { + const games = Reactive( + { + number: 1, + level1: Reactive( + [ + Reactive( + { level3: Reactive({ ok: "OK" }, { prefix: "okTarget" }) }, + { prefix: "level2" } + ), + ], + { + prefix: "level1", + } + ), + }, + { prefix: "base" } + ); + //SUBSCRIBE to every change in Reactive chain + games.level1[0].level3.subscribe("ok", (data) => { + const { base, prop, path, pathValues, value, oldValue } = data; + assert.equal(JSON.stringify(data.path), JSON.stringify(["ok"])); + games.tree = "OK"; + }); + + games.triggerUpTree(); + assert.equal(games.tree, "OK"); +});