deep-state-observer
Advanced tools
Comparing version 4.1.10 to 4.1.11
@@ -161,2 +161,3 @@ export interface PathInfo { | ||
parent: ProxyNode | null; | ||
mapOnly?: boolean; | ||
} | ||
@@ -194,2 +195,3 @@ declare class DeepState { | ||
constructor(data?: object, options?: Options); | ||
private deleteFromMap; | ||
private updateMapDown; | ||
@@ -196,0 +198,0 @@ private deleteMapReferences; |
69
index.ts
@@ -241,2 +241,3 @@ import WildcardObject from "./wildcard-object-scan"; | ||
parent: ProxyNode | null; | ||
mapOnly?: boolean; | ||
} | ||
@@ -331,6 +332,18 @@ | ||
}, | ||
deleteProperty: (obj: ProxyNode, prop) => { | ||
if (!(prop in obj)) return false; | ||
// delete property comes only from proxy | ||
const parentPath = obj[this.proxyProperty].path; | ||
delete obj[prop]; | ||
this.update(parentPath, (currentValue) => { | ||
// only notification because value is already deleted | ||
return currentValue; | ||
}); | ||
return true; | ||
}, | ||
}; | ||
private objectMapOnlyHandler = { | ||
set(obj: any, prop, value) { | ||
set: (obj: any, prop, value) => { | ||
if (prop === this.proxyProperty) return true; | ||
@@ -341,6 +354,14 @@ if (prop in obj && (this.same(obj[prop], value) || (this.isProxy(value) && obj[prop] === value))) { | ||
const path = obj[this.proxyProperty].path ? obj[this.proxyProperty].path + this.options.delimiter + prop : prop; | ||
this.updateMapDown(path, value, obj); | ||
obj[prop] = value; | ||
obj[prop] = this.updateMapDown(path, value, obj); | ||
return true; | ||
}, | ||
deleteProperty: (obj: any, prop) => { | ||
if (!(prop in obj)) return false; | ||
const path = obj[this.proxyProperty].path ? obj[this.proxyProperty].path + this.options.delimiter + prop : prop; | ||
this.deleteFromMap(path); | ||
// here we only deleting - we don't fire update because we are not using proxy observable | ||
// just object actualization | ||
delete obj[prop]; | ||
return true; | ||
}, | ||
}; | ||
@@ -356,10 +377,8 @@ public proxy: object; | ||
this.listeners = new Map(); | ||
this.handler.set = this.handler.set.bind(this); | ||
this.objectMapOnlyHandler.set = this.objectMapOnlyHandler.set.bind(this); | ||
this.options = { ...getDefaultOptions(), ...options }; | ||
if (this.options.useObjectMaps) { | ||
// updateMapDown will check if we are using proxy or not | ||
this.data = this.updateMapDown("", data, this.rootProxyNode, false); | ||
} | ||
if (this.options.useProxy && !this.options.useObjectMaps) { | ||
} else if (this.options.useProxy) { | ||
this.data = this.makeObservable(data, "", this.rootProxyNode); | ||
@@ -397,9 +416,13 @@ } | ||
private deleteFromMap(fullPath: string, map = this.map) { | ||
for (const key of map.keys()) { | ||
if (key === this.proxyProperty) continue; | ||
if (key.startsWith(fullPath)) map.delete(key); | ||
} | ||
} | ||
private updateMapDown(fullPath: string, value: any, parent: ProxyNode, deleteReferences = true, map = this.map) { | ||
if (!this.options.useObjectMaps) return value; | ||
if (deleteReferences) { | ||
for (const key of map.keys()) { | ||
if (key === this.proxyProperty) continue; | ||
if (key.startsWith(fullPath)) map.delete(key); | ||
} | ||
this.deleteFromMap(fullPath); | ||
} | ||
@@ -410,3 +433,12 @@ if (isObject(value)) { | ||
if (prop === this.proxyProperty) continue; | ||
this.updateMapDown(fullPath ? fullPath + this.options.delimiter + prop : prop, value[prop], value, false, map); | ||
if (this.isProxy(parent) && this.options.useProxy) this.setNodeSaving(value, prop); | ||
const valuePropWithProxy = this.updateMapDown( | ||
fullPath ? fullPath + this.options.delimiter + prop : prop, | ||
value[prop], | ||
value, | ||
false, | ||
map | ||
); | ||
value[prop] = valuePropWithProxy; | ||
if (this.isProxy(parent) && this.options.useProxy) this.unsetNodeSaving(value, prop); | ||
} | ||
@@ -416,3 +448,4 @@ } else if (Array.isArray(value)) { | ||
for (let i = 0, len = value.length; i < len; i++) { | ||
this.updateMapDown( | ||
if (this.isProxy(parent) && this.options.useProxy) this.setNodeSaving(value, i); | ||
const valueWithProxy = this.updateMapDown( | ||
fullPath ? fullPath + this.options.delimiter + String(i) : String(i), | ||
@@ -424,2 +457,4 @@ value[i], | ||
); | ||
value[i] = valueWithProxy; | ||
if (this.isProxy(parent) && this.options.useProxy) this.unsetNodeSaving(value, i); | ||
} | ||
@@ -492,3 +527,5 @@ } | ||
} | ||
if (!parent) { | ||
console.log("pathSet", pathChunks, obj, this.rootProxyNode, this.data); | ||
} | ||
value = this.updateMapDown(currentPath, value, parent as ProxyNode, !referencesDeleted); | ||
@@ -605,2 +642,3 @@ if (last) { | ||
if (typeof target[this.proxyProperty] === "undefined") { | ||
data.mapOnly = true; | ||
Object.defineProperty(target, this.proxyProperty, { | ||
@@ -622,3 +660,3 @@ enumerable: false, | ||
private isProxy(target: any) { | ||
return typeof target[this.proxyProperty] !== "undefined"; | ||
return target && typeof target[this.proxyProperty] !== "undefined"; | ||
} | ||
@@ -1499,2 +1537,3 @@ | ||
} | ||
// here we don't want to update maps if only maps are enabled because PathSet will update everything for us | ||
return { newValue, oldValue }; | ||
@@ -1501,0 +1540,0 @@ } |
{ | ||
"name": "deep-state-observer", | ||
"version": "4.1.10", | ||
"version": "4.1.11", | ||
"description": "Deep state observer is an state management library that will fire listeners only when specified object node (which also can be a wildcard) was changed.", | ||
@@ -5,0 +5,0 @@ "main": "index.cjs.js", |
@@ -315,5 +315,42 @@ const State = require("../index.cjs.js"); | ||
expect(values[0]).toEqual(1); | ||
//console.log("updating all"); | ||
state.update("", (oldValue) => { | ||
oldValue.x.byProxy = { test: 2 }; | ||
oldValue.aaa = { bbb: { ccc: { ddd: 10 } } }; | ||
oldValue.aaa.xxx = { test: 12 }; | ||
expect(state.isProxy(oldValue)).toEqual(true); | ||
expect(oldValue[state.proxyProperty].mapOnly).toEqual(true); | ||
expect(state.isProxy(oldValue.aaa)).toEqual(true); | ||
expect(oldValue.aaa[state.proxyProperty].mapOnly).toEqual(true); | ||
expect(state.isProxy(oldValue.aaa.bbb)).toEqual(true); | ||
expect(oldValue.aaa.bbb[state.proxyProperty].mapOnly).toEqual(true); | ||
// console.log( | ||
// "aaa === aaa from parent?", | ||
// oldValue.aaa === oldValue.aaa[state.proxyProperty].parent.aaa, | ||
// state.get("aaa") === oldValue.aaa, | ||
// state.data.aaa === oldValue.aaa | ||
// ); | ||
delete oldValue.aaa.bbb.ccc.ddd; | ||
delete oldValue.aaa.bbb.ccc; | ||
delete oldValue.aaa.bbb; | ||
delete oldValue.aaa.xxx.test; | ||
delete oldValue.aaa.xxx; | ||
delete oldValue.aaa; | ||
return { x: oldValue.x, xx: { yy: { zz: 1 } } }; | ||
}); | ||
expect(state.data.byProxy).toEqual(undefined); // because old value is stored in x and whole data is replaced | ||
expect(state.get("x.byProxy.test")).toEqual(2); | ||
expect(state.isProxy(state.data.x.byProxy)).toEqual(true); | ||
expect(state.isProxy(state.get("x.byProxy"))).toEqual(true); | ||
expect(state.data.x.byProxy[state.proxyProperty].mapOnly).toEqual(true); | ||
expect(state.data.x[state.proxyProperty].mapOnly).toEqual(true); | ||
expect(state.data[state.proxyProperty].mapOnly).toEqual(true); | ||
const root = state.get(""); | ||
expect(state.isProxy(root.x.byProxy)).toEqual(true); | ||
delete root.x.byProxy.test; | ||
expect("test" in state.data.x.byProxy).toEqual(false); | ||
expect(state.get("x.byProxy.test")).toEqual(undefined); | ||
delete root.x.byProxy; | ||
expect("byProxy" in state.data.x).toEqual(false); | ||
expect(state.get("x.byProxy")).toEqual(undefined); | ||
expect(state.data.xx.yy.zz).toEqual(1); | ||
@@ -320,0 +357,0 @@ expect(state.data[undefined]).toBeFalsy(); |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
640844
15589