{"version":3,"sources":["iterable-handler.ts"],"sourcesContent":["import { Datex } from \"../mod.ts\";\nimport { ValueError } from \"../datex_all.ts\";\nimport { weakAction } from \"./weak-action.ts\";\n\n\nfunction workaroundGetHandler(iterableHandler: WeakRef<IterableHandler<any>>) {\n\treturn (v:any, k:any, t:any) => {\n\t\tconst deref = iterableHandler.deref();\n\t\tif (!deref) {\n\t\t\tconsole.warn(\"Undetected garbage collection (datex-w0001)\");\n\t\t\treturn;\n\t\t}\n\t\tderef.onValueChanged(v, k, t)\n\t}\n}\n\nexport class IterableHandler<T, U = T> {\n\n\tprivate map: ((value: T, index: number, array: Iterable<T>) => U) | undefined\n\tprivate filter: ((value: T, index: number, array: Iterable<T>) => value is T&U) | undefined\n\n\tprivate onNewEntry: (entry:U, key:number,) => void\n\tprivate onEntryRemoved: (entry:U, key:number,) => void\n\tprivate onEmpty?: () => void\n\n\t\n\tconstructor(private iterable: Datex.RefOrValue<Iterable<T>>, callbacks: {\n\t\tmap?: (value: T, index: number, array: Iterable<T>) => U,\n\t\t// TODO:\n\t\t// filter?: (value: T, index: number, array: Iterable<T>) => value is T&U,\n\t\tonNewEntry: (this: IterableHandler<T, U>, entry:U, key:number) => void\n\t\tonEntryRemoved: (entry: U, key:number) => void,\n\t\tonEmpty?: () => void\n\t}) {\n\t\tthis.map = callbacks.map;\n\t\t// this.filter = callbacks.filter;\n\t\tthis.onNewEntry = callbacks.onNewEntry;\n\t\tthis.onEntryRemoved = callbacks.onEntryRemoved;\n\t\tthis.onEmpty = callbacks.onEmpty;\n\n\t\tthis.checkEmpty();\n\t\tthis.observe()\n\t}\n\n\tobserve() {\n\t\t// deno-lint-ignore no-this-alias\n\t\tconst self = this;\n\t\tconst iterableRef = new WeakRef(this.iterable);\n\n\t\t// const handler = this.workaroundGetHandler(self)\n\t\t// Datex.Ref.observeAndInit(iterable, handler);\n\n\t\tweakAction(\n\t\t\t{self}, \n\t\t\t({self}) => {\n\t\t\t\tuse (\"allow-globals\", iterableRef, Datex);\n\n\t\t\t\tconst iterable = iterableRef.deref()! // only here to fix closure scope bug, should always exist at this point\n\t\t\t\tconst callback = (v:any, k:any, t:any) => {\n\t\t\t\t\tconst deref = self.deref();\n\t\t\t\t\tif (!deref) {\n\t\t\t\t\t\tconsole.warn(\"Undetected garbage collection (datex-w0001)\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tderef.onValueChanged(v, k, t)\n\t\t\t\t}\n\t\t\t\tDatex.ReactiveValue.observeAndInit(iterable, callback);\n\t\t\t\treturn callback;\n\t\t\t},\n\t\t\t(callback) => {\n\t\t\t\tuse (\"allow-globals\", iterableRef, Datex);\n\n\t\t\t\tconst deref = iterableRef.deref()\n\t\t\t\tif (deref) Datex.ReactiveValue.unobserve(deref, callback);\n\t\t\t}\n\t\t);\n\t}\n\n\t[Symbol.dispose]() {\n\t\t// TODO: unobserve\n\t}\n\n\n\t#entries?: Map<number, U>;\n\tpublic get entries() {\n\t\tif (!this.#entries) this.#entries = new Map<number, U>();\n\t\treturn this.#entries;\n\t}\n\n\tprivate isPseudoIndex(){\n\t\treturn !(this.iterable instanceof Array)\n\t}\n\n\t// for map etc. shift entries to fill from start\n\t//    1=>x 3=>y 4=>z\n\t// to 1=>x 2=>y 3=>z\n\tprivate shiftEntries(key:number){\n\t\tconst max = [...this.entries.keys()].at(-1) || 0;\n\t\tif (key > max) return;\n\t\tfor (let k = key; k<max; k++) {\n\t\t\tthis.entries.set(k, this.entries.get(k+1)!)\n\t\t}\n\t\tthis.entries.delete(max);\n\t}\n\n\tprivate deleteEntry(key:number) {\n\t\tif (this.isPseudoIndex()) this.shiftEntries(key); // for map etc. shift entries to fill from start\n\t\telse this.entries.delete(key)\n\t}\n\n\t// pseudo keys for Sets, Maps and Objects which have no index\n\tprivate getPseudoIndex(key: unknown, value:T): number {\n\t\tif (this.iterable instanceof Set) return this.findIndex(this.iterable, value)\n\t\tif (this.iterable instanceof Map) return this.findIndex(this.iterable.keys(), key);\n\t\tif (this.iterable instanceof Object) return this.findIndex(Object.keys(this.iterable), key);\n\t\treturn -1;\n\t}\n\n\tprivate findIndex<T>(iterable: Iterable<T>, value: T) {\n\t\tlet i = 0;\n\t\tfor (const entry of iterable) {\n\t\t\tif (entry === value) return i;\n\t\t\ti++;\n\t\t}\n\t\treturn -1;\n\t}\n\n\t// pseudo keys for Sets which have no index\n\tprotected iterator(iterable:Set<any>|Map<any,any>|Object|Array<any>) {\n\t\tif (iterable instanceof Set) return iterable;\n\t\tif (iterable instanceof Array) return iterable;\n\t\tif (iterable instanceof Map) return iterable.entries();\n\t\tif (iterable instanceof Object) return Object.values(iterable);\n\t}\n\n\tprotected onValueChanged(value: Iterable<T>|T, key: number|undefined, type:Datex.ReactiveValue.UPDATE_TYPE) {\n\t\tif (type == Datex.ReactiveValue.UPDATE_TYPE.DELETE) return; // ignore DELETE event, only use BEFORE_DELETE event\n\t\tif (type == Datex.ReactiveValue.UPDATE_TYPE.REMOVE) return; // ignore REMOVE event, only use BEFORE_REMOVE event\n\n\t\t// compatibility with key-value iterables\n\t\t// Map or Object\n\t\tif (type != Datex.ReactiveValue.UPDATE_TYPE.INIT && type != Datex.ReactiveValue.UPDATE_TYPE.CLEAR && (this.iterable instanceof Map || !(this.iterable instanceof Set || this.iterable instanceof Array))) {\n\t\t\tconst original_value = value;\n\t\t\t// TODO: required?\n\t\t\tif (this.iterable instanceof Map) value = <Iterable<T>>[key, value]\n\t\t\tkey = this.getPseudoIndex(key, <T>original_value)\n\t\t\tif (key == -1) {\n\t\t\t\tconsole.log(original_value,value,key,type)\n\t\t\t\tthrow new ValueError(\"IterableValue: value not found in iterable\")\n\t\t\t}\n\t\t}\n\n\t\t// single property update\n\t\tif (type == Datex.ReactiveValue.UPDATE_TYPE.SET) this.handleNewEntry(<T>value, key)\n\t\telse if (type == Datex.ReactiveValue.UPDATE_TYPE.ADD) this.handleNewEntry(<T>value, this.getPseudoIndex(key, <T>value));\n\t\t// clear all\n\t\telse if (type == Datex.ReactiveValue.UPDATE_TYPE.CLEAR) {\n\t\t\t// handle onEmpty\n\t\t\tif (this.onEmpty) {\n\t\t\t\tthis.onEmpty.call ? this.onEmpty.call(this) : this.onEmpty();\n\t\t\t}\n\t\t\t// alternative: delete all entries individually\n\t\t\telse {\n\t\t\t\tfor (const [key,] of [...this.#entries??[]].toReversed()) {\n\t\t\t\t\tthis.handleRemoveEntry(key);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse if (type == Datex.ReactiveValue.UPDATE_TYPE.BEFORE_DELETE) this.handleRemoveEntry(key);\n\t\telse if (type == Datex.ReactiveValue.UPDATE_TYPE.BEFORE_REMOVE) this.handleRemoveEntry(this.getPseudoIndex(key, <T>value));\n\t\t// completely new value\n\t\telse if (type == Datex.ReactiveValue.UPDATE_TYPE.INIT) {\n\t\t\tfor (const e of this.entries.keys()) this.handleRemoveEntry(e); // clear all entries\n\t\t\tlet key = 0;\n\t\t\tfor (const child of <Iterable<T>>this.iterator(value??[])) this.handleNewEntry(child, key++);\n\t\t}\n\t}\n\n\t// can be overriden\n\tprotected valueToEntry(value:T, key?: number):U {\n\t\tkey = Number(key);\n\t\treturn this.map ? this.map(value, key??0, val(this.iterable)) : value as unknown as U;\n\t}\n\n\t// call valueToEntry and save entry in this.#entries\n\tprivate handleNewEntry(value:T, key:number) {\n\t\tkey = Number(key);\n\t\tconst entry = this.valueToEntry(value, key)\n\n\t\t// TODO: remove entries inbetween\n\t\t// if (this.filter && !this.filter(value, key, val(this.iterable))) {\n\t\t// \treturn;\n\t\t// }\n\n\t\tif (key != undefined) {\n\t\t\t// TODO: is this correct\n\t\t\tif (!this.isPseudoIndex() && this.entries.has(key)) this.handleRemoveEntry(key) // entry is overridden\n\t\t\tthis.entries.set(key, entry);\n\t\t}\n\t\tthis.onNewEntry.call ? this.onNewEntry.call(this, entry, Number(key)) : this.onNewEntry(entry, Number(key)); // new entry handler\n\t\tthis.checkEmpty();\n\t}\n\n\tprivate handleRemoveEntry(key:number) {\n\t\tkey = Number(key)\n\t\tconst entry = this.entries.get(key)!;\n\t\tthis.deleteEntry(key);\n\t\tthis.onEntryRemoved.call ? this.onEntryRemoved.call(this, entry, key) : this.onEntryRemoved(entry, key);\n\n\t\tthis.checkEmpty();\n\t}\n\n\tprivate checkEmpty() {\n\t\tif (this.onEmpty && this.#entries?.size == 0) this.onEmpty.call ? this.onEmpty.call(this) : this.onEmpty();\n\t}\n\n}"],"names":["Datex","ValueError","weakAction","Symbol","dispose","IterableHandler","map","filter","onNewEntry","onEntryRemoved","onEmpty","constructor","iterable","callbacks","checkEmpty","observe","iterableRef","WeakRef","self","use","deref","callback","v","k","t","console","warn","onValueChanged","ReactiveValue","observeAndInit","unobserve","entries","Map","isPseudoIndex","Array","shiftEntries","key","max","keys","at","set","get","delete","deleteEntry","getPseudoIndex","value","Set","findIndex","Object","i","entry","iterator","values","type","UPDATE_TYPE","DELETE","REMOVE","INIT","CLEAR","original_value","log","SET","handleNewEntry","ADD","call","toReversed","handleRemoveEntry","BEFORE_DELETE","BEFORE_REMOVE","e","child","valueToEntry","Number","val","undefined","has","size"],"mappings":"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","sourceRoot":"/core-lib/datex-core-js-legacy/utils/","file":"iterable-handler.ts"}