deep-state-observer
Advanced tools
Comparing version 5.3.0 to 5.4.0
@@ -40,3 +40,3 @@ export interface PathInfo { | ||
ignore?: string[]; | ||
group?: boolean; | ||
group?: boolean | string; | ||
} | ||
@@ -55,3 +55,3 @@ export interface UpdateOptions { | ||
id?: number; | ||
groupId: number | null; | ||
groupId: number | string | null; | ||
} | ||
@@ -65,3 +65,3 @@ export interface Queue { | ||
options: ListenerOptions; | ||
groupId: number; | ||
groupId: number | string | null; | ||
} | ||
@@ -129,3 +129,3 @@ export interface GroupedListener { | ||
index: number; | ||
groupId: number; | ||
groupId: number | string | null; | ||
} | ||
@@ -175,2 +175,4 @@ export interface TraceValue { | ||
private groupId; | ||
private namedGroups; | ||
private numberGroups; | ||
private traceId; | ||
@@ -177,0 +179,0 @@ private pathGet; |
481
index.ts
@@ -1,4 +0,4 @@ | ||
import WildcardObject from './wildcard-object-scan'; | ||
import Path from './ObjectPath'; | ||
import init, { is_match } from './wildcard_matcher.js'; | ||
import WildcardObject from "./wildcard-object-scan"; | ||
import Path from "./ObjectPath"; | ||
import init, { is_match } from "./wildcard_matcher.js"; | ||
@@ -20,6 +20,3 @@ export interface PathInfo { | ||
export type ListenerFunction = ( | ||
value: any, | ||
eventInfo: ListenerFunctionEventInfo | ||
) => void; | ||
export type ListenerFunction = (value: any, eventInfo: ListenerFunctionEventInfo) => void; | ||
export type Match = (path: string, debug?: boolean) => boolean; | ||
@@ -52,3 +49,3 @@ | ||
ignore?: string[]; | ||
group?: boolean; | ||
group?: boolean | string; | ||
} | ||
@@ -69,3 +66,3 @@ | ||
id?: number; | ||
groupId: number | null; | ||
groupId: number | string | null; | ||
} | ||
@@ -80,3 +77,3 @@ | ||
options: ListenerOptions; | ||
groupId: number; | ||
groupId: number | string | null; | ||
} | ||
@@ -161,3 +158,3 @@ | ||
index: number; | ||
groupId: number; | ||
groupId: number | string | null; | ||
} | ||
@@ -187,3 +184,3 @@ | ||
only: [], | ||
source: '', | ||
source: "", | ||
debug: false, | ||
@@ -196,7 +193,3 @@ data: undefined, | ||
export interface Multi { | ||
update: ( | ||
updatePath: string, | ||
fn: Updater | any, | ||
options?: UpdateOptions | ||
) => Multi; | ||
update: (updatePath: string, fn: Updater | any, options?: UpdateOptions) => Multi; | ||
done: () => void; | ||
@@ -216,6 +209,3 @@ getStack: () => UpdateStack[]; | ||
type PathValue< | ||
T, | ||
P extends PossiblePath<T> | ||
> = P extends `${infer K}.${infer Rest}` | ||
type PathValue<T, P extends PossiblePath<T>> = P extends `${infer K}.${infer Rest}` | ||
? K extends keyof T | ||
@@ -261,3 +251,3 @@ ? Rest extends PossiblePath<T[K]> | ||
debug: false, | ||
source: '', | ||
source: "", | ||
data: undefined, | ||
@@ -276,5 +266,5 @@ queue: false, | ||
if (item && item.constructor) { | ||
return item.constructor.name === 'Object'; | ||
return item.constructor.name === "Object"; | ||
} | ||
return typeof item === 'object' && item !== null; | ||
return typeof item === "object" && item !== null; | ||
} | ||
@@ -292,6 +282,3 @@ | ||
private subscribeQueue = []; | ||
private listenersIgnoreCache: WeakMap< | ||
Listener, | ||
{ truthy: string[]; falsy: string[] } | ||
> = new WeakMap(); | ||
private listenersIgnoreCache: WeakMap<Listener, { truthy: string[]; falsy: string[] }> = new WeakMap(); | ||
private is_match: any = null; | ||
@@ -304,2 +291,4 @@ private destroyed = false; | ||
private groupId: number = 0; | ||
private namedGroups: string[] = []; | ||
private numberGroups: number[] = []; | ||
private traceId: number = 0; | ||
@@ -337,15 +326,7 @@ private pathGet: typeof Path.get; | ||
this.mutedListeners = new Set(); | ||
this.scan = new WildcardObject( | ||
this.data, | ||
this.options.delimiter, | ||
this.options.wildcard | ||
); | ||
this.scan = new WildcardObject(this.data, this.options.delimiter, this.options.wildcard); | ||
this.destroyed = false; | ||
} | ||
private cacheGet( | ||
pathChunks: string[], | ||
data: any = this.data, | ||
create = false | ||
) { | ||
private cacheGet(pathChunks: string[], data: any = this.data, create = false) { | ||
const path = pathChunks.join(this.options.delimiter); | ||
@@ -394,8 +375,3 @@ const weakRefValue = this.cache.get(path); | ||
this.is_match = is_match; | ||
this.scan = new WildcardObject( | ||
this.data, | ||
this.options.delimiter, | ||
this.options.wildcard, | ||
this.is_match | ||
); | ||
this.scan = new WildcardObject(this.data, this.options.delimiter, this.options.wildcard, this.is_match); | ||
} | ||
@@ -405,4 +381,3 @@ | ||
return ( | ||
(['number', 'string', 'undefined', 'boolean'].includes(typeof newValue) || | ||
newValue === null) && | ||
(["number", "string", "undefined", "boolean"].includes(typeof newValue) || newValue === null) && | ||
oldValue === newValue | ||
@@ -425,15 +400,9 @@ ); | ||
private match( | ||
first: string, | ||
second: string, | ||
nested: boolean = true | ||
): boolean { | ||
private match(first: string, second: string, nested: boolean = true): boolean { | ||
if (this.is_match) return this.is_match(first, second); | ||
if (first === second) return true; | ||
if (first === this.options.wildcard || second === this.options.wildcard) | ||
return true; | ||
if (first === this.options.wildcard || second === this.options.wildcard) return true; | ||
if ( | ||
!nested && | ||
this.getIndicesCount(this.options.delimiter, first) < | ||
this.getIndicesCount(this.options.delimiter, second) | ||
this.getIndicesCount(this.options.delimiter, first) < this.getIndicesCount(this.options.delimiter, second) | ||
) { | ||
@@ -480,6 +449,3 @@ // first < second because first is a listener path and may be longer but not shorter | ||
if (longer === shorter) return longer; | ||
const shorterPartsLen = this.getIndicesCount( | ||
this.options.delimiter, | ||
shorter | ||
); | ||
const shorterPartsLen = this.getIndicesCount(this.options.delimiter, shorter); | ||
const longerParts = this.getIndicesOf(this.options.delimiter, longer); | ||
@@ -498,3 +464,3 @@ return longer.substr(0, longerParts[shorterPartsLen]); | ||
private split(path: string) { | ||
if (path === '') return []; | ||
if (path === "") return []; | ||
if (!this.options.useSplitCache) { | ||
@@ -521,5 +487,3 @@ return path.split(this.options.delimiter); | ||
private cleanNotRecursivePath(path: string): string { | ||
return this.isNotRecursive(path) | ||
? path.substring(0, path.length - 1) | ||
: path; | ||
return this.isNotRecursive(path) ? path.substring(0, path.length - 1) : path; | ||
} | ||
@@ -532,3 +496,3 @@ | ||
private getParamsInfo(path: string): ParamsInfo { | ||
let paramsInfo: ParamsInfo = { replaced: '', original: path, params: {} }; | ||
let paramsInfo: ParamsInfo = { replaced: "", original: path, params: {} }; | ||
let partIndex = 0; | ||
@@ -539,9 +503,6 @@ let fullReplaced = []; | ||
original: part, | ||
replaced: '', | ||
name: '', | ||
replaced: "", | ||
name: "", | ||
}; | ||
const reg = new RegExp( | ||
`\\${this.options.param}([^\\${this.options.delimiter}\\${this.options.param}]+)`, | ||
'g' | ||
); | ||
const reg = new RegExp(`\\${this.options.param}([^\\${this.options.delimiter}\\${this.options.param}]+)`, "g"); | ||
let param = reg.exec(part); | ||
@@ -557,6 +518,3 @@ if (param) { | ||
reg.lastIndex = 0; | ||
paramsInfo.params[partIndex].replaced = part.replace( | ||
reg, | ||
this.options.wildcard | ||
); | ||
paramsInfo.params[partIndex].replaced = part.replace(reg, this.options.wildcard); | ||
fullReplaced.push(paramsInfo.params[partIndex].replaced); | ||
@@ -633,5 +591,10 @@ partIndex++; | ||
let index = 0; | ||
if (options.group) { | ||
let groupId = null; | ||
if (typeof options.group === "boolean" && options.group) { | ||
this.groupId++; | ||
groupId = this.groupId; | ||
options.bulk = true; | ||
} else if (typeof options.group === "string") { | ||
options.bulk = true; | ||
groupId = options.group; | ||
} | ||
@@ -643,3 +606,3 @@ for (const userPath of userPaths) { | ||
index, | ||
groupId: options.group ? this.groupId : null, | ||
groupId, | ||
}) | ||
@@ -671,6 +634,3 @@ ); | ||
private getCleanListener( | ||
fn: ListenerFunction, | ||
options: ListenerOptions = defaultListenerOptions | ||
): Listener { | ||
private getCleanListener(fn: ListenerFunction, options: ListenerOptions = defaultListenerOptions): Listener { | ||
return { | ||
@@ -683,7 +643,3 @@ fn, | ||
private getListenerCollectionMatch( | ||
listenerPath: string, | ||
isRecursive: boolean, | ||
isWildcard: boolean | ||
) { | ||
private getListenerCollectionMatch(listenerPath: string, isRecursive: boolean, isWildcard: boolean) { | ||
listenerPath = this.cleanNotRecursivePath(listenerPath); | ||
@@ -696,9 +652,6 @@ const self = this; | ||
} else { | ||
scopedListenerPath = self.cutPath( | ||
self.cleanNotRecursivePath(listenerPath), | ||
path | ||
); | ||
scopedListenerPath = self.cutPath(self.cleanNotRecursivePath(listenerPath), path); | ||
} | ||
if (debug) { | ||
console.log('[getListenerCollectionMatch]', { | ||
console.log("[getListenerCollectionMatch]", { | ||
listenerPath, | ||
@@ -711,4 +664,3 @@ scopedListenerPath, | ||
} | ||
if (isWildcard && self.match(scopedListenerPath, path, isRecursive)) | ||
return true; | ||
if (isWildcard && self.match(scopedListenerPath, path, isRecursive)) return true; | ||
return scopedListenerPath === path; | ||
@@ -718,6 +670,3 @@ }; | ||
private getListenersCollection( | ||
listenerPath: string, | ||
listener: Listener | ||
): ListenersCollection { | ||
private getListenersCollection(listenerPath: string, listener: Listener): ListenersCollection { | ||
if (this.listeners.has(listenerPath)) { | ||
@@ -747,7 +696,3 @@ let listenersCollection = this.listeners.get(listenerPath); | ||
...collCfg, | ||
match: this.getListenerCollectionMatch( | ||
collCfg.path, | ||
collCfg.isRecursive, | ||
collCfg.isWildcard | ||
), | ||
match: this.getListenerCollectionMatch(collCfg.path, collCfg.isRecursive, collCfg.isWildcard), | ||
}); | ||
@@ -768,3 +713,3 @@ this.id++; | ||
index: 0, | ||
groupId: this.groupId, | ||
groupId: null, | ||
} | ||
@@ -774,19 +719,35 @@ ) { | ||
this.jobsRunning++; | ||
const type = 'subscribe'; | ||
const type = "subscribe"; | ||
let listener = this.getCleanListener(fn, options); | ||
if (options.group) listener.groupId = subscribeAllOptions.groupId; | ||
if (options.group) { | ||
options.bulk = true; | ||
if (typeof options.group === "string") { | ||
listener.groupId = options.group; | ||
} else if (subscribeAllOptions.groupId) { | ||
listener.groupId = subscribeAllOptions.groupId; | ||
} | ||
} | ||
this.listenersIgnoreCache.set(listener, { truthy: [], falsy: [] }); | ||
const listenersCollection = this.getListenersCollection( | ||
listenerPath as string, | ||
listener | ||
); | ||
const listenersCollection = this.getListenersCollection(listenerPath as string, listener); | ||
if (options.debug) { | ||
console.log('[subscribe]', { listenerPath, options }); | ||
console.log("[subscribe]", { listenerPath, options }); | ||
} | ||
listenersCollection.count++; | ||
if ( | ||
!options.group || | ||
(options.group && | ||
subscribeAllOptions.all.length - 1 === subscribeAllOptions.index) | ||
) { | ||
let shouldFire = true; | ||
if (listener.groupId) { | ||
if (typeof listener.groupId === "string") { | ||
if (this.namedGroups.includes(listener.groupId)) { | ||
shouldFire = false; | ||
} else { | ||
this.namedGroups.push(listener.groupId); | ||
} | ||
} else if (typeof listener.groupId === "number") { | ||
if (this.numberGroups.includes(listener.groupId)) { | ||
shouldFire = false; | ||
} else { | ||
this.numberGroups.push(listener.groupId); | ||
} | ||
} | ||
} | ||
if (shouldFire) { | ||
const cleanPath = this.cleanNotRecursivePath(listenersCollection.path); | ||
@@ -886,3 +847,3 @@ const cleanPathChunks = this.split(cleanPath); | ||
this.queueRuns = 0; | ||
throw new Error('Maximal number of queue runs exhausted.'); | ||
throw new Error("Maximal number of queue runs exhausted."); | ||
} else { | ||
@@ -898,6 +859,3 @@ Promise.resolve() | ||
private getQueueNotifyListeners( | ||
groupedListeners: GroupedListeners, | ||
queue: Queue[] = [] | ||
): Queue[] { | ||
private getQueueNotifyListeners(groupedListeners: GroupedListeners, queue: Queue[] = []): Queue[] { | ||
for (const path in groupedListeners) { | ||
@@ -908,11 +866,5 @@ if (this.isMuted(path)) continue; | ||
let alreadyInQueue = false; | ||
let resolvedIdPath = | ||
singleListener.listener.id + | ||
':' + | ||
singleListener.eventInfo.path.resolved; | ||
let resolvedIdPath = singleListener.listener.id + ":" + singleListener.eventInfo.path.resolved; | ||
if (!singleListener.eventInfo.path.resolved) { | ||
resolvedIdPath = | ||
singleListener.listener.id + | ||
':' + | ||
singleListener.eventInfo.path.listener; | ||
resolvedIdPath = singleListener.listener.id + ":" + singleListener.eventInfo.path.listener; | ||
} | ||
@@ -932,17 +884,8 @@ for (const excludedListener of queue) { | ||
this.subscribeQueue.push(() => { | ||
singleListener.listener.fn( | ||
singleListener.value(), | ||
singleListener.eventInfo | ||
); | ||
singleListener.listener.fn(singleListener.value(), singleListener.eventInfo); | ||
}); | ||
} else { | ||
let resolvedIdPath = | ||
singleListener.listener.id + | ||
':' + | ||
singleListener.eventInfo.path.resolved; | ||
let resolvedIdPath = singleListener.listener.id + ":" + singleListener.eventInfo.path.resolved; | ||
if (!singleListener.eventInfo.path.resolved) { | ||
resolvedIdPath = | ||
singleListener.listener.id + | ||
':' + | ||
singleListener.eventInfo.path.listener; | ||
resolvedIdPath = singleListener.listener.id + ":" + singleListener.eventInfo.path.listener; | ||
} | ||
@@ -955,6 +898,3 @@ queue.push({ | ||
fn: () => { | ||
singleListener.listener.fn( | ||
singleListener.value(), | ||
singleListener.eventInfo | ||
); | ||
singleListener.listener.fn(singleListener.value(), singleListener.eventInfo); | ||
}, | ||
@@ -993,11 +933,5 @@ options: singleListener.listener.options, | ||
} else { | ||
let resolvedIdPath = | ||
bulkListener.listener.id + | ||
':' + | ||
bulkListener.eventInfo.path.resolved; | ||
let resolvedIdPath = bulkListener.listener.id + ":" + bulkListener.eventInfo.path.resolved; | ||
if (!bulkListener.eventInfo.path.resolved) { | ||
resolvedIdPath = | ||
bulkListener.listener.id + | ||
':' + | ||
bulkListener.eventInfo.path.listener; | ||
resolvedIdPath = bulkListener.listener.id + ":" + bulkListener.eventInfo.path.listener; | ||
} | ||
@@ -1046,3 +980,3 @@ queue.push({ | ||
options: UpdateOptions, | ||
type: string = 'update', | ||
type: string = "update", | ||
originalPath: string = null | ||
@@ -1059,4 +993,3 @@ ): GroupedListeners { | ||
const cutPath = this.cutPath(updatePath, listenerPath); | ||
const traverse = | ||
listenersCollection.isRecursive || listenersCollection.isWildcard; | ||
const traverse = listenersCollection.isRecursive || listenersCollection.isWildcard; | ||
const value = traverse ? () => this.get(cutPath) : () => newValue; | ||
@@ -1067,9 +1000,6 @@ const bulkValue: Bulk[] = [{ value, path: updatePath, params }]; | ||
if (listener.options.debug) { | ||
console.log( | ||
`[getSubscribedListeners] Listener was not fired because it was ignored.`, | ||
{ | ||
listener, | ||
listenersCollection, | ||
} | ||
); | ||
console.log(`[getSubscribedListeners] Listener was not fired because it was ignored.`, { | ||
listener, | ||
listenersCollection, | ||
}); | ||
} | ||
@@ -1120,10 +1050,7 @@ continue; | ||
showMatch = true; | ||
console.log( | ||
`[getSubscribedListeners] Listener was not fired because there was no match.`, | ||
{ | ||
listener, | ||
listenersCollection, | ||
updatePath, | ||
} | ||
); | ||
console.log(`[getSubscribedListeners] Listener was not fired because there was no match.`, { | ||
listener, | ||
listenersCollection, | ||
updatePath, | ||
}); | ||
} | ||
@@ -1143,14 +1070,6 @@ } | ||
options: UpdateOptions, | ||
type: string = 'update', | ||
type: string = "update", | ||
originalPath: string = null | ||
): Queue[] { | ||
return this.getQueueNotifyListeners( | ||
this.getSubscribedListeners( | ||
updatePath, | ||
newValue, | ||
options, | ||
type, | ||
originalPath | ||
) | ||
); | ||
return this.getQueueNotifyListeners(this.getSubscribedListeners(updatePath, newValue, options, type, originalPath)); | ||
} | ||
@@ -1162,3 +1081,3 @@ | ||
options: UpdateOptions, | ||
type: string = 'update', | ||
type: string = "update", | ||
originalPath: string = null | ||
@@ -1175,12 +1094,6 @@ ): GroupedListeners { | ||
// listener is listening below updated node | ||
const restBelowPathCut = this.trimPath( | ||
listenerPath.substr(currentAbovePathCut.length) | ||
); | ||
const restBelowPathCut = this.trimPath(listenerPath.substr(currentAbovePathCut.length)); | ||
const wildcardNewValues = restBelowValues[restBelowPathCut] | ||
? restBelowValues[restBelowPathCut] // if those values are already calculated use it | ||
: new WildcardObject( | ||
newValue, | ||
this.options.delimiter, | ||
this.options.wildcard | ||
).get(restBelowPathCut); | ||
: new WildcardObject(newValue, this.options.delimiter, this.options.wildcard).get(restBelowPathCut); | ||
@@ -1195,5 +1108,3 @@ restBelowValues[restBelowPathCut] = wildcardNewValues; | ||
const value = () => wildcardNewValues[currentRestPath]; | ||
const fullPath = [updatePath, currentRestPath].join( | ||
this.options.delimiter | ||
); | ||
const fullPath = [updatePath, currentRestPath].join(this.options.delimiter); | ||
for (const [listenerId, listener] of listenersCollection.listeners) { | ||
@@ -1251,11 +1162,8 @@ const eventInfo = { | ||
if (listener.options.debug) { | ||
console.log( | ||
'[getNestedListeners] Listener was not fired because there was no match.', | ||
{ | ||
listener, | ||
listenersCollection, | ||
currentCutPath: currentAbovePathCut, | ||
updatePath, | ||
} | ||
); | ||
console.log("[getNestedListeners] Listener was not fired because there was no match.", { | ||
listener, | ||
listenersCollection, | ||
currentCutPath: currentAbovePathCut, | ||
updatePath, | ||
}); | ||
} | ||
@@ -1272,3 +1180,3 @@ } | ||
options: UpdateOptions, | ||
type: string = 'update', | ||
type: string = "update", | ||
queue: Queue[], | ||
@@ -1278,9 +1186,3 @@ originalPath: string = null | ||
return this.getQueueNotifyListeners( | ||
this.getNestedListeners( | ||
updatePath, | ||
newValue, | ||
options, | ||
type, | ||
originalPath | ||
), | ||
this.getNestedListeners(updatePath, newValue, options, type, originalPath), | ||
queue | ||
@@ -1294,3 +1196,3 @@ ); | ||
options: UpdateOptions, | ||
type: string = 'update', | ||
type: string = "update", | ||
originalPath: string = null | ||
@@ -1300,5 +1202,5 @@ ): GroupedListeners { | ||
if ( | ||
typeof options.only !== 'object' || | ||
typeof options.only !== "object" || | ||
!Array.isArray(options.only) || | ||
typeof options.only[0] === 'undefined' || | ||
typeof options.only[0] === "undefined" || | ||
!this.canBeNested(newValue) | ||
@@ -1309,7 +1211,5 @@ ) { | ||
for (const notifyPath of options.only) { | ||
const wildcardScanNewValue = new WildcardObject( | ||
newValue, | ||
this.options.delimiter, | ||
this.options.wildcard | ||
).get(notifyPath); | ||
const wildcardScanNewValue = new WildcardObject(newValue, this.options.delimiter, this.options.wildcard).get( | ||
notifyPath | ||
); | ||
listeners[notifyPath] = { bulk: [], single: [] }; | ||
@@ -1340,7 +1240,3 @@ for (const wildcardPath in wildcardScanNewValue) { | ||
if (listener.options.bulk) { | ||
if ( | ||
!listeners[notifyPath].bulk.some( | ||
(bulkListener) => bulkListener.listener === listener | ||
) | ||
) { | ||
if (!listeners[notifyPath].bulk.some((bulkListener) => bulkListener.listener === listener)) { | ||
listeners[notifyPath].bulk.push({ | ||
@@ -1397,13 +1293,7 @@ listener, | ||
options: UpdateOptions, | ||
type: string = 'update', | ||
originalPath: string = '' | ||
type: string = "update", | ||
originalPath: string = "" | ||
) { | ||
const queue = this.getQueueNotifyListeners( | ||
this.getNotifyOnlyListeners( | ||
updatePath, | ||
newValue, | ||
options, | ||
type, | ||
originalPath | ||
) | ||
this.getNotifyOnlyListeners(updatePath, newValue, options, type, originalPath) | ||
); | ||
@@ -1414,3 +1304,3 @@ this.sortAndRunQueue(queue, updatePath); | ||
private canBeNested(newValue): boolean { | ||
return typeof newValue === 'object' && newValue !== null; | ||
return typeof newValue === "object" && newValue !== null; | ||
} | ||
@@ -1420,3 +1310,3 @@ | ||
let newValue = fn; | ||
if (typeof fn === 'function') { | ||
if (typeof fn === "function") { | ||
newValue = fn(oldValue); | ||
@@ -1463,34 +1353,10 @@ } | ||
if (options.only.length) { | ||
groupedListenersPack.push( | ||
this.getNotifyOnlyListeners( | ||
path, | ||
newValue, | ||
options, | ||
'update', | ||
updatePath | ||
) | ||
); | ||
groupedListenersPack.push(this.getNotifyOnlyListeners(path, newValue, options, "update", updatePath)); | ||
} else { | ||
groupedListenersPack.push( | ||
this.getSubscribedListeners( | ||
path, | ||
newValue, | ||
options, | ||
'update', | ||
updatePath | ||
) | ||
); | ||
groupedListenersPack.push(this.getSubscribedListeners(path, newValue, options, "update", updatePath)); | ||
if (this.canBeNested(newValue)) { | ||
groupedListenersPack.push( | ||
this.getNestedListeners( | ||
path, | ||
newValue, | ||
options, | ||
'update', | ||
updatePath | ||
) | ||
); | ||
groupedListenersPack.push(this.getNestedListeners(path, newValue, options, "update", updatePath)); | ||
} | ||
} | ||
options.debug && this.options.log('Wildcard update', { path, newValue }); | ||
options.debug && this.options.log("Wildcard update", { path, newValue }); | ||
waitingPaths.push(path); | ||
@@ -1511,31 +1377,13 @@ } | ||
if (this.destroyed) return; | ||
while ( | ||
this.updateQueue.length && | ||
this.updateQueue.length < this.options.maxSimultaneousJobs | ||
) { | ||
while (this.updateQueue.length && this.updateQueue.length < this.options.maxSimultaneousJobs) { | ||
const params = this.updateQueue.shift(); | ||
params.options.queue = false; // prevent infinite loop | ||
this.update( | ||
params.updatePath, | ||
params.fnOrValue, | ||
params.options, | ||
params.multi | ||
); | ||
this.update(params.updatePath, params.fnOrValue, params.options, params.multi); | ||
} | ||
} | ||
private updateNotify( | ||
updatePath: string, | ||
newValue: unknown, | ||
options: UpdateOptions | ||
) { | ||
private updateNotify(updatePath: string, newValue: unknown, options: UpdateOptions) { | ||
const queue = this.notifySubscribedListeners(updatePath, newValue, options); | ||
if (this.canBeNested(newValue)) { | ||
this.notifyNestedListeners( | ||
updatePath, | ||
newValue, | ||
options, | ||
'update', | ||
queue | ||
); | ||
this.notifyNestedListeners(updatePath, newValue, options, "update", queue); | ||
} | ||
@@ -1561,17 +1409,5 @@ this.sortAndRunQueue(queue, updatePath); | ||
} | ||
queue = queue.concat( | ||
this.notifySubscribedListeners( | ||
current.updatePath, | ||
value, | ||
current.options | ||
) | ||
); | ||
queue = queue.concat(this.notifySubscribedListeners(current.updatePath, value, current.options)); | ||
if (this.canBeNested(current.newValue)) { | ||
this.notifyNestedListeners( | ||
current.updatePath, | ||
value, | ||
current.options, | ||
'update', | ||
queue | ||
); | ||
this.notifyNestedListeners(current.updatePath, value, current.options, "update", queue); | ||
} | ||
@@ -1606,3 +1442,3 @@ } | ||
if (jobsRunning > this.options.maxSimultaneousJobs) { | ||
throw new Error('Maximal simultaneous jobs limit reached.'); | ||
throw new Error("Maximal simultaneous jobs limit reached."); | ||
} | ||
@@ -1628,11 +1464,6 @@ this.updateQueue.push({ updatePath, fnOrValue, options, multi }); | ||
if (options.debug) { | ||
this.options.log( | ||
`Updating ${updatePath} ${ | ||
options.source ? `from ${options.source}` : '' | ||
}`, | ||
{ | ||
oldValue, | ||
newValue, | ||
} | ||
); | ||
this.options.log(`Updating ${updatePath} ${options.source ? `from ${options.source}` : ""}`, { | ||
oldValue, | ||
newValue, | ||
}); | ||
} | ||
@@ -1698,7 +1529,3 @@ | ||
const multiObject: Multi = { | ||
update( | ||
updatePath: string, | ||
fnOrValue: Updater | any, | ||
options: UpdateOptions = defaultUpdateOptions | ||
) { | ||
update(updatePath: string, fnOrValue: Updater | any, options: UpdateOptions = defaultUpdateOptions) { | ||
if (grouped) { | ||
@@ -1708,3 +1535,3 @@ const split = self.split(updatePath); | ||
const currentValue = self.pathGet(split, self.data); | ||
if (typeof value === 'function') { | ||
if (typeof value === "function") { | ||
value = value(currentValue); | ||
@@ -1767,3 +1594,3 @@ } | ||
if (this.destroyed) return; | ||
if (typeof userPath === 'undefined' || userPath === '') { | ||
if (typeof userPath === "undefined" || userPath === "") { | ||
return this.data; | ||
@@ -1795,3 +1622,3 @@ } | ||
if (!this.options.useMute) return false; | ||
if (typeof pathOrListenerFunction === 'function') { | ||
if (typeof pathOrListenerFunction === "function") { | ||
return this.isMutedListener(pathOrListenerFunction); | ||
@@ -1818,3 +1645,3 @@ } | ||
public mute(pathOrListenerFunction: string | ListenerFunction) { | ||
if (typeof pathOrListenerFunction === 'function') { | ||
if (typeof pathOrListenerFunction === "function") { | ||
return this.mutedListeners.add(pathOrListenerFunction); | ||
@@ -1826,3 +1653,3 @@ } | ||
public unmute(pathOrListenerFunction: string | ListenerFunction) { | ||
if (typeof pathOrListenerFunction === 'function') { | ||
if (typeof pathOrListenerFunction === "function") { | ||
return this.mutedListeners.delete(pathOrListenerFunction); | ||
@@ -1833,9 +1660,5 @@ } | ||
private debugSubscribe( | ||
listener: Listener, | ||
listenersCollection: ListenersCollection, | ||
listenerPath: string | ||
) { | ||
private debugSubscribe(listener: Listener, listenersCollection: ListenersCollection, listenerPath: string) { | ||
if (listener.options.debug) { | ||
this.options.log('listener subscribed', { | ||
this.options.log("listener subscribed", { | ||
listenerPath, | ||
@@ -1849,7 +1672,4 @@ listener, | ||
private debugListener(time: number, groupedListener: GroupedListener) { | ||
if ( | ||
groupedListener.eventInfo.options.debug || | ||
groupedListener.listener.options.debug | ||
) { | ||
this.options.log('Listener fired', { | ||
if (groupedListener.eventInfo.options.debug || groupedListener.listener.options.debug) { | ||
this.options.log("Listener fired", { | ||
time: Date.now() - time, | ||
@@ -1862,6 +1682,3 @@ info: groupedListener, | ||
private debugTime(groupedListener: GroupedListener): number { | ||
return groupedListener.listener.options.debug || | ||
groupedListener.eventInfo.options.debug | ||
? Date.now() | ||
: 0; | ||
return groupedListener.listener.options.debug || groupedListener.eventInfo.options.debug ? Date.now() : 0; | ||
} | ||
@@ -1871,3 +1688,3 @@ | ||
this.traceId++; | ||
const id = this.traceId + ':' + name; | ||
const id = this.traceId + ":" + name; | ||
this.traceMap.set(id, { | ||
@@ -1874,0 +1691,0 @@ id, |
{ | ||
"name": "deep-state-observer", | ||
"version": "5.3.0", | ||
"version": "5.4.0", | ||
"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", |
const State = require("../index.cjs.js"); | ||
const path = require("path"); | ||
const fs = require("fs"); | ||
@@ -77,3 +75,3 @@ describe("Group", () => { | ||
state.update("n-1.*.id", "new id"); | ||
expect(results.length).toEqual(5); | ||
expect(results.length).toEqual(5); // because of second subscribeAll is without bulk | ||
state.update("n-1.*.id", "new id 2"); | ||
@@ -83,2 +81,30 @@ expect(results.length).toEqual(8); | ||
it("it should fire grouped listeners separately", () => { | ||
const state = new State({ | ||
"n-1": { | ||
"n-1-1": { | ||
id: "1-1", | ||
val: "v1-1", | ||
}, | ||
"n-1-2": { | ||
id: "1-2", | ||
val: "v1-2", | ||
}, | ||
}, | ||
}); | ||
const results = []; | ||
function fn(bulk, eventInfo) { | ||
results.push(eventInfo.path); | ||
} | ||
state.subscribeAll(["n-1.n-1-1.id", "n-1.n-1-2.val"], fn, { | ||
group: true, | ||
}); | ||
state.subscribeAll(["n-1", "n-1.n-1-2"], fn, { group: true }); | ||
expect(results.length).toEqual(2); | ||
state.update("n-1.*.id", "new id"); | ||
expect(results.length).toEqual(4); | ||
state.update("n-1.*.id", "new id 2"); | ||
expect(results.length).toEqual(6); | ||
}); | ||
it("it should fire once grouped listeners (bulk)", () => { | ||
@@ -85,0 +111,0 @@ const state = new State({ |
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
542969
41
14003
2