{"version":3,"sources":["storage.ts"],"sourcesContent":["// deno-lint-ignore-file no-namespace\nimport { Runtime } from \"../runtime/runtime.ts\";\n\nimport type { ExecConditions, PointerSource } from \"../utils/global_types.ts\";\nimport { logger } from \"../utils/global_values.ts\";\nimport { client_type } from \"../utils/constants.ts\";\nimport { NOT_EXISTING } from \"../runtime/constants.ts\";\nimport { Pointer, type MinimalJSRef, ReactiveValue } from \"../runtime/pointers.ts\";\nimport { localStorage } from \"./storage-locations/local-storage-compat.ts\";\nimport { MessageLogger } from \"../utils/message_logger.ts\";\nimport { Type } from \"../types/type.ts\";\nimport { addPersistentListener } from \"../utils/persistent-listeners.ts\";\nimport { Endpoint, LOCAL_ENDPOINT } from \"../types/addressing.ts\";\nimport { ESCAPE_SEQUENCES, verboseArg } from \"../utils/logger.ts\";\nimport { StorageMap } from \"../types/storage-map.ts\";\nimport { StorageSet } from \"../types/storage-set.ts\";\nimport { IterableWeakSet } from \"../utils/iterable-weak-set.ts\";\nimport { LazyPointer } from \"../runtime/lazy-pointer.ts\";\nimport { AutoMap } from \"../utils/auto_map.ts\";\nimport { hasDebugCookie } from \"../utils/debug-cookie.ts\";\nimport { setStorage } from \"../runtime/reset.ts\";\nimport { KnownError, handleError } from \"../utils/error-handling.ts\";\n\n\n// displayInit();\n\n/***** imports and definitions with top-level await - node.js / browser interoperability *******************************/\nexport const site_suffix = (()=>{\n    // remove hash from url\n    if (globalThis.location?.origin) {\n        // const url = new URL(globalThis.location.href)\n        // url.hash = \"\";\n        // return url.toString();\n        return globalThis.location.origin\n    }\n    else return \"\"\n})();\n\n\ntype AtomicMatchInput<T> = T |\n    (\n        T extends string ? \n            RegExp :\n            never\n    )\n\ntype _MatchInput<T> = \n    MatchCondition<MatchConditionType, T> |\n    (\n        T extends object ? \n        {\n            [K in Exclude<keyof T,\"$\"|\"$$\">]?: MatchInputValue<T[K]>\n        } :\n        AtomicMatchInput<T>|AtomicMatchInput<T>[]\n    )\ntype MatchInputValue<T> = \n\t_MatchInput<T>| // exact match\n\t_MatchInput<T>[] // or match\n\nexport type MatchInput<T extends object> = MatchInputValue<T>\n\ntype ObjectKeyPaths<T> = \n    T extends object ?\n        (\n            ObjectKeyPaths<T[keyof T]> extends never ? \n            `${string & Exclude<keyof T, \"$\"|\"$$\">}` :\n            `${string & Exclude<keyof T, \"$\"|\"$$\">}`|`${string & Exclude<keyof T, \"$\"|\"$$\">}.${ObjectKeyPaths<T[Exclude<keyof T, \"$\"|\"$$\">]>}`\n        ):\n        never\n\nexport type MatchOptions<T = unknown> = {\n    /**\n     * Maximum number of matches to return\n     */\n    limit?: number,\n    /**\n     * Sort by key (e.g. address.street)\n     */\n    sortBy?: string // TODO: T extends object ? ObjectKeyPaths<T> : string,\n    /**\n     * Sort in descending order (only if sortBy is set)\n     */\n    sortDesc?: boolean,\n    /**\n     * Offset for match results\n     */\n    offset?: number,\n    /**\n     * Return advanced match results (e.g. total count of matches)\n     */\n    returnAdvanced?: boolean,\n    /**\n     * Provide a list of properties that should be returned as raw values. If provided, only the raw properties are returned\n     * and pointers are not loaded\n     */\n    returnRaw?: string[]\n    /**\n     * Return pointer ids of matched items\n     */\n    returnPointerIds?: boolean,\n    /**\n     * Return map keys (only works with StorageMaps)\n     */\n    returnKeys?: boolean,\n    /**\n     * Custom computed properties for match query\n     */\n    computedProperties?: Record<string, ComputedProperty<ComputedPropertyType>>\n}\n\nexport type MatchResult<T, Options extends MatchOptions> = Options[\"returnAdvanced\"] extends true ?\n    AdvancedMatchResult<T> & (\n        Options[\"returnPointerIds\"] extends true ?\n            {\n                pointerIds: Set<string>\n            } :\n            unknown\n    ) :\n    Set<T>\n\nexport type AdvancedMatchResult<T> = {\n    total: number,\n    pointerIds?: Set<string>,\n    matches: Set<T>\n}\n\nexport enum MatchConditionType {\n    BETWEEN = \"BETWEEN\",\n    LESS_THAN = \"LESS_THAN\",\n    GREATER_THAN = \"GREATER_THAN\",\n    LESS_OR_EQUAL = \"LESS_OR_EQUAL\",\n    GREATER_OR_EQUAL = \"GREATER_OR_EQUAL\",\n    NOT_EQUAL = \"NOT_EQUAL\",\n    CONTAINS = \"CONTAINS\",\n    POINTER_ID = \"POINTER_ID\",\n}\nexport type MatchConditionData<T extends MatchConditionType, V> = \n    T extends MatchConditionType.BETWEEN ? \n        [V, V] :\n    T extends MatchConditionType.LESS_THAN|MatchConditionType.GREATER_THAN|MatchConditionType.LESS_OR_EQUAL|MatchConditionType.GREATER_OR_EQUAL|MatchConditionType.NOT_EQUAL ?\n        V :\n    T extends MatchConditionType.CONTAINS ?\n        V :\n    T extends MatchConditionType.POINTER_ID ?\n        string[] :\n    never\n\nexport class MatchCondition<Type extends MatchConditionType, V> {\n    \n    private constructor(\n        public type: Type, \n        public data: MatchConditionData<Type, V>\n    ) {}\n\n    static between<V>(lower: V, upper: V) {\n        return new MatchCondition(MatchConditionType.BETWEEN, [lower, upper])\n    }\n\n    static lessThan<V>(value: V) {\n        return new MatchCondition(MatchConditionType.LESS_THAN, value)\n    }\n\n    static greaterThan<V>(value: V) {\n        return new MatchCondition(MatchConditionType.GREATER_THAN, value)\n    }\n\n    static lessOrEqual<V>(value: V) {\n        return new MatchCondition(MatchConditionType.LESS_OR_EQUAL, value)\n    }\n\n    static greaterOrEqual<V>(value: V) {\n        return new MatchCondition(MatchConditionType.GREATER_OR_EQUAL, value)\n    }\n\n    static notEqual<V>(value: V) {\n        return new MatchCondition(MatchConditionType.NOT_EQUAL, value)\n    }\n\n    static contains<V>(...values: V[]) {\n        return new MatchCondition(MatchConditionType.CONTAINS, new Set(values))\n    }\n\n    static pointerId(id: string): MatchCondition<MatchConditionType.POINTER_ID, string>\n    static pointerId(ids: string[]): MatchCondition<MatchConditionType.POINTER_ID, string>\n    static pointerId(id: string|string[]) {\n        return new MatchCondition(MatchConditionType.POINTER_ID, id instanceof Array ? id : [id])\n    }\n}\n\nexport enum ComputedPropertyType {\n    GEOGRAPHIC_DISTANCE = \"GEOGRAPHIC_DISTANCE\",\n    SUM = \"SUM\",\n}\n\nexport type ComputedPropertyData<Type extends ComputedPropertyType> =\n    Type extends ComputedPropertyType.GEOGRAPHIC_DISTANCE ?\n        {pointA: {lat: number|string, lon: number|string}, pointB: {lat: number|string, lon: number|string}} :\n    Type extends ComputedPropertyType.SUM ?\n        (number|string)[] :\n    never\n\nexport class ComputedProperty<Type extends ComputedPropertyType> {\n\n    private constructor(\n        public type: Type,\n        public data: ComputedPropertyData<Type>\n    ) {}\n\n    static geographicDistance(pointA: {lat: number|string, lon: number|string}, pointB: {lat: number|string, lon: number|string}) {\n        return new ComputedProperty(ComputedPropertyType.GEOGRAPHIC_DISTANCE, {pointA, pointB})\n    }\n\n    static sum(...values: (number|string)[]) {\n        return new ComputedProperty(ComputedPropertyType.SUM, values)\n    }\n}\n\n\nexport interface StorageLocation<SupportedModes extends Storage.Mode = Storage.Mode> {\n    name: string\n    isAsync: boolean\n    /**\n     * This storage location supports exec conditions for get operations\n     */\n    supportsExecConditions?: boolean\n    /**\n     * This storage location supports prefix selection for get operations\n     */\n    supportsPrefixSelection?: boolean\n    /**\n     * This storage location supports match selection for get operations\n     * Must implement supportsMatchForType if true\n     */\n    supportsMatchSelection?: boolean\n    /**\n     * This storage location supports partial updates for setPointer operations\n     */\n    supportsPartialUpdates?: boolean\n\n    isSupported(): boolean\n    onAfterExit?(): void // called when deno process exits\n    onAfterSnapshot?(isExit: boolean): void // called after a snapshot was saved to the storage (e.g. triggered by interval or exit event)\n\n    setItem(key:string, value:unknown): Promise<Set<Pointer>>|Set<Pointer>\n    getItem(key:string, conditions?:ExecConditions): Promise<unknown>|unknown\n    hasItem(key:string):Promise<boolean>|boolean\n    removeItem(key:string): Promise<void>|void\n    getItemValueDXB(key:string): Promise<ArrayBuffer|null>|ArrayBuffer|null\n    setItemValueDXB(key:string, value: ArrayBuffer):Promise<void>|void\n    getItemKeys(prefix?:string): Promise<Generator<string, void, unknown>> | Generator<string, void, unknown>\n    getItemKey?(value: unknown): Promise<string|undefined>|string|undefined\n\n    setPointer(pointer:Pointer, partialUpdateKey: unknown|typeof NOT_EXISTING): Promise<Set<Pointer>>|Set<Pointer>\n    getPointerValue(pointerId:string, outer_serialized:boolean, conditions?:ExecConditions):Promise<unknown>|unknown\n    removePointer(pointerId:string):Promise<void>|void\n    hasPointer(pointerId:string):Promise<boolean>|boolean\n    getPointerIds(): Promise<Generator<string, void, unknown>> | Generator<string, void, unknown>\n    getPointerValueDXB(pointerId:string): Promise<ArrayBuffer|null>|ArrayBuffer|null\n    setPointerValueDXB(pointerId:string, value: ArrayBuffer):Promise<void>|void\n\n    supportsMatchForType?(type: Type): Promise<boolean>|boolean\n    matchQuery?<T extends object, Options extends MatchOptions<T>>(itemPrefix: string, valueType: Type<T>, match: MatchInput<T>, options:Options): Promise<MatchResult<T, Options>>|MatchResult<T, Options>\n    clear(): Promise<void>|void\n    \n}\nexport abstract class SyncStorageLocation implements StorageLocation<Storage.Mode.SAVE_ON_CHANGE|Storage.Mode.SAVE_PERIODICALLY|Storage.Mode.SAVE_ON_EXIT> {\n\n    abstract name: string;\n    readonly isAsync = false;\n\n    abstract isSupported(): boolean\n    onAfterExit() {}\n\n    abstract setItem(key: string,value: unknown): Set<Pointer>\n    abstract getItem(key:string, conditions?:ExecConditions): Promise<unknown>|unknown\n    abstract hasItem(key:string): boolean\n    abstract getItemKeys(prefix?:string): Generator<string, void, unknown>\n    abstract getItemKey?(value: unknown): string|undefined\n\n    abstract removeItem(key: string): void\n    abstract getItemValueDXB(key: string): ArrayBuffer|null\n    abstract setItemValueDXB(key:string, value: ArrayBuffer):void\n\n    abstract setPointer(pointer: Pointer, partialUpdateKey: unknown|typeof NOT_EXISTING): Set<Pointer>\n    abstract getPointerValue(pointerId: string, outer_serialized:boolean, conditions?:ExecConditions): unknown\n    abstract getPointerIds(): Generator<string, void, unknown>\n\n    abstract removePointer(pointerId: string): void\n    abstract getPointerValueDXB(pointerId: string): ArrayBuffer|null\n    abstract setPointerValueDXB(pointerId:string, value: ArrayBuffer):void\n    abstract hasPointer(pointerId: string): boolean\n\n    supportsMatchForType?(type: Type): boolean\n    matchQuery?<T extends object, Options extends MatchOptions<T>>(itemPrefix: string, valueType: Type<T>, match: MatchInput<T>, options:Options): MatchResult<T, Options>\n\n    abstract clear(): void\n}\n\nexport abstract class AsyncStorageLocation implements StorageLocation<Storage.Mode.SAVE_ON_CHANGE|Storage.Mode.SAVE_PERIODICALLY> {\n    abstract name: string;\n    readonly isAsync = true;\n\n    abstract isSupported(): boolean\n    onAfterExit() {}\n\n    abstract setItem(key: string,value: unknown): Promise<Set<Pointer>>\n    abstract getItem(key:string, conditions?:ExecConditions): Promise<unknown>\n    abstract hasItem(key:string): Promise<boolean>\n    abstract getItemKeys(prefix?:string): Promise<Generator<string, void, unknown>>\n    abstract getItemKey?(value: unknown): Promise<string|undefined>\n\n    abstract removeItem(key: string): Promise<void>\n    abstract getItemValueDXB(key: string): Promise<ArrayBuffer|null> \n    abstract setItemValueDXB(key:string, value: ArrayBuffer):Promise<void>\n\n    abstract setPointer(pointer: Pointer, partialUpdateKey: unknown|typeof NOT_EXISTING): Promise<Set<Pointer>>\n    abstract getPointerValue(pointerId: string, outer_serialized:boolean, conditions?:ExecConditions): Promise<unknown>\n    abstract getPointerIds(): Promise<Generator<string, void, unknown>>\n\n    abstract removePointer(pointerId: string): Promise<void>\n    abstract getPointerValueDXB(pointerId: string): Promise<ArrayBuffer|null>\n    abstract setPointerValueDXB(pointerId:string, value: ArrayBuffer):Promise<void>\n    abstract hasPointer(pointerId: string): Promise<boolean>\n\n    supportsMatchForType?(type: Type): Promise<boolean>|boolean\n    matchQuery?<T extends object, Options extends MatchOptions<T>>(itemPrefix: string, valueType: Type<T>, match: MatchInput<T>, options:Options): Promise<MatchResult<T, Options>>\n\n    abstract clear(): Promise<void>\n}\n\ntype storage_options<M extends Storage.Mode> = {\n    modes: M[]\n    primary?: boolean // indicates if this storage should be used as the primary storage location\n    interval?: number\n}\n\ntype storage_location_options<L extends StorageLocation> = \n    L extends StorageLocation<infer T> ? storage_options<T> : never\n\ntype StorageSnapshotOptions = {\n    /**\n     * Display all internally used items (e.g. for garbage collection)\n     */\n    internalItems: boolean,\n    /**\n     * List all items and pointers of storage maps and sets\n     */\n    expandStorageMapsAndSets: boolean,\n    /**\n     * Only display items (and related pointers) that contain the given string in their key\n     */\n    itemFilter?: string,\n    /**\n     * Only display general information about storage data, no items or pointers\n     */\n    onlyHeaders?: boolean\n}\n\nexport class Storage {\n    \n    static cache:Map<string,any> = new Map(); // save stored values in a Map, return when calling getItem\n\n\n    static state_prefix = \"dxstate::\"\n\n    static pointer_prefix = \"dxptr::\"+site_suffix+\"::\"\n    static item_prefix = \"dxitem::\"+site_suffix+\"::\"\n\n    static meta_prefix = \"dxmeta::\"+site_suffix+\"::\"\n    static rc_prefix = \"rc::\"\n    static pointer_deps_prefix = \"deps::dxptr::\"\n    static item_deps_prefix = \"deps::dxitem::\"\n    static subscriber_cache_prefix = \"subscribers::\"\n\n    static #storage_active_pointers = new IterableWeakSet<Pointer>();\n    static #storage_active_pointer_ids = new Set<string>();\n    static #scheduledUpdates = new Set<()=>void|Promise<void>>();\n\n    /**\n     * Try to cache the actual pointer if it is stored in storage.\n     * Called from pointer once the value is initialized.\n     * @returns true if the pointer is stored in storage\n     */\n    static providePointer(ptr: Pointer) {\n        if (this.#storage_active_pointer_ids.has(ptr.id)) {\n            this.#storage_active_pointers.add(ptr);\n            this.#storage_active_pointer_ids.delete(ptr.id);\n            ptr.isStored = true;\n            return true;\n        }\n        return false;\n    }\n\n    static DEFAULT_INTERVAL = 60; // 60s\n\n    static #primary_location?: StorageLocation;\n    static #trusted_location?: StorageLocation;\n    static #trusted_pointers = new Set<string>()\n\n    // location which did that last complete backup in the last session, if none found, use the current primary location\n    static set trusted_location(location: StorageLocation | undefined) {\n        this.#trusted_location = location;\n        if (location != undefined) {\n            logger.debug `trusted storage location: #bold${location.name}`\n        }\n    }\n    static get trusted_location () {return this.#trusted_location}\n\n    // default location for saving pointers/items\n    static set primary_location(location: StorageLocation | undefined) {\n        this.#primary_location = location;\n    }\n    static get primary_location () {return this.#primary_location}\n\n    static #locations = new Map<StorageLocation, storage_location_options<StorageLocation>>()\n    static #auto_sync_enabled = false;\n\n    public static get locations() {\n        return this.#locations;\n    }\n\n    // set options for storage location and enable\n    public static addLocation<L extends StorageLocation>(location:L, options:storage_location_options<L>) {\n        this.#locations.set(location, options);\n\n        if (options.interval && !options.modes.includes(Storage.Mode.SAVE_PERIODICALLY)) {\n            throw new Error(\"The 'interval' option can only be used for the storage mode SAVE_PERIODICALLY\");\n        }\n\n        for (const mode of options.modes) {\n            // asynchronous saving on exit not possible\n            if (mode == Storage.Mode.SAVE_ON_EXIT && location.isAsync) throw new Error(\"Invalid DATEX Storage location: \"+location.name+\" is async and not compatible with SAVE_ON_EXIT mode\");\n            // supported? e.g. localStorage undefined in web worker\n            if (!location.isSupported()) {\n                throw new Error(\"Invalid DATEX Storage location: \"+location.name+\", not supported in this context\");\n            }\n        \n            if (mode == Storage.Mode.SAVE_PERIODICALLY) {\n                this.addSaveInterval(location, options.interval ?? this.DEFAULT_INTERVAL)\n            }\n        }\n\n        // update auto_sync_enabled\n        this.#auto_sync_enabled = false\n        for (const [_loc,options] of this.#locations) {\n            if (options.modes.includes(Storage.Mode.SAVE_ON_CHANGE)) this.#auto_sync_enabled = true;\n        }\n\n        logger.debug `using ${options.primary?'primary':'secondary'} storage location #bold${location.name}:#color(grey) ${options.modes.map(m=>Storage.Mode[m]).join(', ')}`\n\n        if (options.primary) {\n            this.primary_location = location;\n        }\n\n        this.determineTrustedLocation();\n\n        return this.restoreDirtyState()\n    }\n\n    // disable storage location\n    public static removeLocation(location:StorageLocation) {\n        const options = this.#locations.get(location);\n        this.#locations.delete(location);\n        if (options?.primary) this.primary_location = undefined;\n        if (options?.interval != undefined) clearInterval(this.#save_interval_refs.get(location))\n    }\n\n\n    static #save_interval_refs = new Map<StorageLocation, number>()\n\n    /**\n     * set the interval (in s) in which the current pointer should be saved in a storage storage\n     */\n    private static addSaveInterval(location:StorageLocation, interval:number) {\n        if (this.#save_interval_refs.has(location)) clearInterval(this.#save_interval_refs.get(location))\n        if (interval != 0) {\n            this.#save_interval_refs.set(location, setInterval(()=>this.saveCurrentState(location), interval * 1000))\n        }\n    }\n\n    static #exiting = false\n\n    static handleExit(){\n        if (this.#exiting) return;\n        this.#exiting = true\n        // TODO: add race promise with timeout to return if cache takes too long\n        // if (globalThis.Deno) setTimeout(()=>{Deno.exit(1)},20_000)\n\n        // first run remaining scheduled updates (only sync supported)\n        for (const update of this.#scheduledUpdates) {\n            const res = update()\n            if (res instanceof Promise) logger.error(\"Cannot store state in async storage location on exit\");\n        }\n\n        this.saveDirtyState();\n        \n        if (this.#dirty || this.dirtyValues.size) {\n            logger.debug(\"Storage has dirty flag set, following values could not be stored\", this.dirtyValues);\n        }\n        \n        for (const [loc,options] of this.#locations) {\n            if (options.modes.includes(<any>Storage.Mode.SAVE_ON_EXIT)) Storage.saveCurrentState(loc, true);\n            loc.onAfterExit?.();\n        }\n\n        // also save deno localstorage file, also if no local storage location set, metadata must stil be stored\n        if (localStorage.saveFile) localStorage.saveFile();\n\n        logger.debug(\"\\nexit - state saved in cache\");\n    }\n\n\n    // call to reload page without saving any data (for resetting)\n    static #exit_without_save = false;\n    public static allowExitWithoutSave(){\n        this.#exit_without_save = true;\n    }\n\n    private static saveCurrentState(location:StorageLocation, isExit = false){\n        if (this.#exit_without_save) {\n            // console.log(`exiting without save`);\n            return;\n        }\n\n        try {\n            // update items\n            let c = 0;\n            for (const [key, val] of Storage.cache) {\n                try {\n                    c++;\n                    const res = this.setItem(key, val, true, location);\n                    if (res instanceof Promise) res.catch(()=>{})\n                } catch (e) {}\n            }\n\n            // update pointers\n            for (const ptr of [...this.#storage_active_pointers]) {\n                try {\n                    c++;\n                    const res = this.setPointer(ptr, true, location);\n                    if (res instanceof Promise) res.catch(()=>{})\n                } catch (e) {}\n            }\n            for (const id of [...this.#storage_active_pointer_ids]) {\n                try {\n                    c++;\n                    const ptr = Pointer.get(id);\n                    if (ptr?.value_initialized) this.setPointer(ptr, true, location);\n                } catch (e) {}\n            }\n\n            this.updateSaveTime(location); // last full backup to this storage location\n            logger.debug(`current state saved to ${location.name} (${c} items)`);\n            location.onAfterSnapshot?.(isExit);\n        }\n        catch (e) {\n            console.error(e)\n        }\n     \n    }\n    \n    // called when a full backup to this storage location was made\n    private static updateSaveTime(location:StorageLocation) {\n        if (this.#exit_without_save) return; // currently exiting\n        localStorage.setItem(this.meta_prefix+'__saved__' + location.name, new Date().getTime().toString());\n    }\n\n    private static deleteSaveTime(location:StorageLocation) {\n        localStorage.removeItem(this.meta_prefix+'__saved__' + location.name);\n    }\n\n    private static getSaveTime(location:StorageLocation) {\n        return Number(localStorage.getItem(this.meta_prefix+'__saved__' + location.name) ?? 0);\n    }\n\n    // handle dirty states for async storage operations:\n    static #dirty_locations = new Map<StorageLocation, number>()\n\n    static dirtyValues = new Set<string>();\n    // called when a full backup to this storage location was made\n    public static setDirty(location:StorageLocation, dirty = true, metadata = '') {\n        // update counter\n        if (dirty) {\n            this.dirtyValues.add(metadata);\n            const currentCount = this.#dirty_locations.get(location)??0;\n            this.#dirty_locations.set(location, currentCount + 1);\n        }\n        else {\n            if (!this.#dirty_locations.has(location)) {\n                logger.warn(\"Invalid dirty state reset for location '\"+location.name + \"', dirty state was not set\", metadata);\n            }\n            else {\n                const newCount = this.#dirty_locations.get(location)! - 1;\n                if (newCount <= 0) {\n                    this.#dirty_locations.delete(location);\n                }\n                else this.#dirty_locations.set(location, newCount);\n                this.dirtyValues.delete(metadata);\n            }\n        }\n    }\n\n    static #dirty = false;\n    private static isInDirtyState(location:StorageLocation) {\n        this.#dirty = !!localStorage.getItem(this.meta_prefix+'__dirty__' + location.name)\n        return this.#dirty;\n    }\n\n    /**\n     * save current dirty states in localstorage\n     */\n    private static saveDirtyState(){\n        if (this.#exit_without_save) return; // currently exiting\n        for (const [location] of this.#dirty_locations) {\n            localStorage.setItem(this.meta_prefix+'__dirty__' + location.name, new Date().getTime().toString());\n        }\n    }\n\n    /**\n     * clear the dirty state in localstorage\n     */\n    private static clearDirtyState(location: StorageLocation){\n        localStorage.removeItem(this.meta_prefix+'__dirty__' + location.name);\n    }\n    \n\n    private static determineTrustedLocation(fromLocations: StorageLocation[] = [...this.#locations.keys()]) {\n        // primary is already trusted, use this\n        if (this.trusted_location === this.primary_location) return this.trusted_location;\n\n        let last:StorageLocation|undefined = this.trusted_location;\n        let last_time = last ? this.getSaveTime(last) : 0;\n\n        for (const location of fromLocations) {\n            if (this.isInDirtyState(location)) continue;\n            // found trusted primary location, use this\n            if (location === this.primary_location) {\n                last = location\n                break;\n            }\n\n            // find location with latest update\n\t\t\tconst time = this.getSaveTime(location)\n            if (time > last_time) {\n\t\t\t\tlast_time = time;\n\t\t\t\tlast = location\n\t\t\t}\n\t\t\tthis.deleteSaveTime(location); // no longer valid after this session\n        }\n        if (this.trusted_location !== last) this.trusted_location = last\n        return this.trusted_location;\n    }\n\n    static #unresolvedLocalItems = new Map<string, unknown>()\n    static #unresolvedLocalPointers = new IterableWeakSet<Pointer>()\n\n\n    static setItem(key:string, value:any, listen_for_pointer_changes = true, location:StorageLocation|null|undefined = this.#primary_location):Promise<boolean>|boolean {\n        Storage.cache.set(key, value); // save in cache\n\n        // cache deletion does not work, problems with storage item backup\n        // setTimeout(()=>Storage.cache.delete(key), 10000);\n\n\t\tif (location)  {\n\t\t\tif (location.isAsync) return this.setItemAsync(location as AsyncStorageLocation, key, value, listen_for_pointer_changes);\n\t\t\telse return this.setItemSync(location as SyncStorageLocation, key, value, listen_for_pointer_changes);\n\t\t}\n        else return false;\n    }\n\n\tstatic async setItemAsync(location:AsyncStorageLocation, key: string, value: unknown,listen_for_pointer_changes: boolean) {\n        const metadata = this.isDebugMode ? (key + \": \" +Runtime.valueToDatexString(value)) : undefined;\n        this.setDirty(location, true, metadata);\n        const itemExisted = await location.hasItem(key);\n        // store value (might be pointer reference)\n        const dependencies = await location.setItem(key, value);\n        if (Pointer.is_local) this.checkUnresolvedLocalDependenciesForItem(key, value, dependencies);\n        await this.updateItemDependencies(key, [...dependencies].map(p=>p.id));\n        await this.saveDependencyPointersAsync(dependencies, listen_for_pointer_changes, location);\n        this.setDirty(location, false, metadata);\n        return itemExisted;\n\t}\n\n\tstatic setItemSync(location:SyncStorageLocation, key: string, value: unknown,listen_for_pointer_changes: boolean) {\n        const itemExisted = location.hasItem(key);\n        const dependencies = location.setItem(key, value);\n        if (Pointer.is_local) this.checkUnresolvedLocalDependenciesForItem(key, value, dependencies);\n        this.updateItemDependencies(key, [...dependencies].map(p=>p.id)).catch(e=>console.error(e));\n        this.saveDependencyPointersSync(dependencies, listen_for_pointer_changes, location);\n        return itemExisted;\n\t}\n\n    /**\n     * Collects all pointer dependencies of an itemr entry with a @@local origin.\n     * Once the endpoint is initialized, the entry is updated with the correct pointer ids.\n     */\n    private static checkUnresolvedLocalDependenciesForItem(key: string, value:unknown, dependencies: Set<Pointer>) {\n        const hasUnresolvedLocalDependency = [...dependencies].some(p=>p.origin == LOCAL_ENDPOINT);\n        if (hasUnresolvedLocalDependency) this.#unresolvedLocalItems.set(key, value);\n    }\n\n    /**\n     * Collects all pointer dependencies of a pointer entry with a @@local origin.\n     * Once the endpoint is initialized, the entry is updated with the correct pointer ids.\n     */\n    private static checkUnresolvedLocalDependenciesForPointer(pointer: Pointer, dependencies: Set<Pointer>) {\n        const hasUnresolvedLocalDependency = [...dependencies].some(p=>p.origin == LOCAL_ENDPOINT);\n        if (hasUnresolvedLocalDependency) this.#unresolvedLocalPointers.add(pointer);\n    }\n\n    /**\n     * Updates all item/pointer entries in storage that still are stored with unresolved @@local pointers\n     */\n    static updateEntriesWithUnresolvedLocalDependencies() {\n        for (const [key, value] of this.#unresolvedLocalItems) {\n            logger.debug(\"update item containing pointers with @@local origin: \" +  key)\n            this.setItem(key, value)\n        }\n        this.#unresolvedLocalItems.clear()\n\n        for (const ptr of this.#unresolvedLocalPointers) {\n            logger.debug(\"update pointer containing pointers with @@local origin: \" + ptr.idString())\n            this.setPointer(ptr as Pointer)\n        }\n        this.#unresolvedLocalPointers.clear()\n    }\n\n\n    public static setPointer(pointer:Pointer, listen_for_changes = true, location:StorageLocation|undefined = this.#primary_location, partialUpdateKey: unknown = NOT_EXISTING, force_listen_for_deps = false): Promise<boolean>|boolean {\n        if (!pointer.value_initialized) {\n            // logger.warn(\"pointer value \" + pointer.idString() + \" not available, cannot save in storage\");\n            this.#storage_active_pointers.delete(pointer);\n            this.#storage_active_pointer_ids.delete(pointer.id);\n            return false\n        }\n        \n\t\tif (location)  {\n\t\t\tif (location.isAsync) return this.initPointerAsync(location as AsyncStorageLocation, pointer, listen_for_changes, partialUpdateKey, force_listen_for_deps);\n\t\t\telse return this.initPointerSync(location as SyncStorageLocation, pointer, listen_for_changes, partialUpdateKey, force_listen_for_deps);\n\t\t}\n\t\telse return false;\n    }\n\n    private static initPointerSync(location: SyncStorageLocation, pointer:Pointer, listen_for_changes = true, partialUpdateKey: unknown = NOT_EXISTING, force_listen_for_deps = false):boolean {\n        // if (pointer.transform_scope && this.hasPointer(pointer)) return true; // ignore transform pointer, initial transform scope already stored, does not change\n        // was garbage collected in the meantime\n        if (pointer.garbage_collected) {\n            return false\n        }\n\n        const dependencies = this.updatePointerSync(location, pointer, partialUpdateKey);\n        dependencies.delete(pointer);\n        if (Pointer.is_local) this.checkUnresolvedLocalDependenciesForPointer(pointer, dependencies);\n        this.updatePointerDependencies(pointer.id, [...dependencies].map(p=>p.id)).catch(e=>console.error(e));\n        this.saveDependencyPointersSync(dependencies, force_listen_for_deps || listen_for_changes, location);\n\n        // listen for changes\n        if (listen_for_changes) this.syncPointer(pointer, location);\n\n        this.#storage_active_pointers.add(pointer);\n        // remember that this pointer is stored in storage\n        pointer.isStored = true;\n\n        return true;\n    }\n\n    private static updatePointerSync(location: SyncStorageLocation, pointer:Pointer, partialUpdateKey: unknown = NOT_EXISTING): Set<Pointer>{\n        // was garbage collected in the meantime\n        if (pointer.garbage_collected) {\n            return new Set();\n        }\n\t\treturn location.setPointer(pointer, partialUpdateKey);\n    }\n\n    private static async initPointerAsync(location: AsyncStorageLocation, pointer:Pointer, listen_for_changes = true, partialUpdateKey: unknown = NOT_EXISTING, force_listen_for_deps = false):Promise<boolean>{\n        // if (pointer.transform_scope && await this.hasPointer(pointer)) return true; // ignore transform pointer, initial transform scope already stored, does not change\n        // was garbage collected in the meantime\n        if (pointer.garbage_collected) {\n            return false\n        }\n\n        const dependencies = await this.updatePointerAsync(location, pointer, partialUpdateKey);\n        dependencies.delete(pointer);\n        if (Pointer.is_local) this.checkUnresolvedLocalDependenciesForPointer(pointer, dependencies);\n        await this.updatePointerDependencies(pointer.id, [...dependencies].map(p=>p.id));\n        await this.saveDependencyPointersAsync(dependencies, force_listen_for_deps || listen_for_changes, location);\n\n        // listen for changes\n        if (listen_for_changes) this.syncPointer(pointer, location);\n\n        this.#storage_active_pointers.add(pointer);\n        // remember that this pointer is stored in storage\n        pointer.isStored = true;\n\n        return true;\n    }\n\n    private static get isDebugMode(): boolean {\n        return (verboseArg || hasDebugCookie());\n    }\n\n    private static async updatePointerAsync(location: AsyncStorageLocation, pointer:Pointer, partialUpdateKey: unknown = NOT_EXISTING): Promise<Set<Pointer>> {\n        // was garbage collected in the meantime\n        if (pointer.garbage_collected) {\n            return new Set();\n        }\n        const metadata = this.isDebugMode ? `${pointer.id}: ${Runtime.valueToDatexString(pointer.val)}` : undefined;\n        this.setDirty(location, true, metadata);\n        const res = await location.setPointer(pointer, partialUpdateKey);\n        this.setDirty(location, false, metadata);\n        return res;\n    }\n\n    /**\n     * Save dependency pointers to storage (SyncStorageLocation)\n     * Not all pointers in the set are saved, only those which are not yet in storage or not accessible in other ways\n     * @param dependencies List of dependency pointers\n     * @param listen_for_changes should update pointers in storage when value changes\n     * @param location storage location\n     */\n    private static saveDependencyPointersSync(dependencies: Set<Pointer>, listen_for_changes = true, location: SyncStorageLocation) {\n        for (const ptr of dependencies) {\n            // add if not yet in storage\n            if (!location.hasPointer(ptr.id)) this.setPointer(ptr, listen_for_changes, location)\n        }\n    }\n\n    /**\n     * Save dependency pointers to storage (AsyncStorageLocation)\n     * Not all pointers in the set are saved, only those which are not yet in storage or not accessible in other ways\n     * @param dependencies List of dependency pointers\n     * @param listen_for_changes should update pointers in storage when value changes\n     * @param location storage location\n     */\n    private static async saveDependencyPointersAsync(dependencies: Set<Pointer>, listen_for_changes = true, location: AsyncStorageLocation) {\n        await Promise.all([...dependencies].map(async ptr=>{\n            // add if not yet in storage\n            if (!await location.hasPointer(ptr.id)) await this.setPointer(ptr, listen_for_changes, location)\n        }));\n    }\n\n\n    private static synced_pointers = new WeakSet<Pointer>();\n\n    static syncPointer(pointer: Pointer, location: StorageLocation|undefined = this.#primary_location) {\n        if (!this.#auto_sync_enabled) return;\n\n        if (!pointer) {\n            logger.error(\"tried to sync non-existing pointer with storage\")\n            return;\n        }\n        if (!location) {\n            logger.error(\"location required for syncPointer\")\n            return;\n        }\n\n        // already syncing?\n        if (this.synced_pointers.has(pointer)) return;\n        this.synced_pointers.add(pointer)\n\n        // any value change\n        let saving = false;\n\n\n        const handler = (v:unknown,key:unknown,t?:ReactiveValue.UPDATE_TYPE)=>{\n            if (saving) return;\n\n            // don't block saving if only partial update\n            if (!(location.supportsPartialUpdates && key !== NOT_EXISTING)) saving = true;\n            const metadata = this.isDebugMode ? `${pointer.id}: ${Runtime.valueToDatexString(pointer.val)}` : undefined;\n\n            this.scheduleStorageUpdate(()=>{\n                // set pointer (async)\n                saving = false;\n                const res = this.setPointer(pointer, false, location, key, true); // update value and add new dependencies recursively\n                if (res instanceof Promise) {\n                    return res.then((couldSave)=>{\n                        if (couldSave) {\n                            logger.debug(\"updated \" + pointer.idString() + \" in storage\");\n                        }\n                        else {\n                            pointer.unobserve(handler);\n                        }\n                    });\n                }\n                else {\n                    const couldSave = res; \n                    if (couldSave) {\n                        logger.debug(\"updated \" + pointer.idString() + \" in storage\");\n                    }\n                    else {\n                        pointer.unobserve(handler);\n                    }\n                }\n            }, location, metadata);\n        };\n\n        pointer.observe(handler, undefined, undefined, {ignore_transforms:true, recursive:false});   \n    }\n\n\n    /**\n     * Run a pointer update after 1s or on process exit and keep the dirty state until the update is finished\n     */\n    private static scheduleStorageUpdate(update:()=>void|Promise<void>, location: StorageLocation, metadata?: string) {\n        \n        this.setDirty(location, true, metadata);\n        const updateFn = () => {\n            clearTimeout(timeout);\n            const res = update();\n            if (res instanceof Promise) {\n                return res.then(()=>{\n                    this.setDirty(location, false, metadata);\n                    this.#scheduledUpdates.delete(updateFn);\n                }).catch(e => console.error(e));\n            }\n            else {\n                this.#scheduledUpdates.delete(updateFn);\n                this.setDirty(location, false, metadata);\n            }\n        }\n\n        this.#scheduledUpdates.add(updateFn);\n        const timeout = setTimeout(updateFn, 1000);\n    }\n \n    public static hasPointer(pointer:Pointer, location:StorageLocation|undefined = this.#trusted_location) {\n\t\tif (location)  {\n\t\t\treturn location.hasPointer(pointer.id);\n\t\t}\n\t\telse return false;\n    }\n\n    private static getLocationPriorityOrder(pointer_id:string) {\n        if (this.#trusted_pointers.has(pointer_id)) return [this.#primary_location, this.#trusted_location]; // value already loaded from trusted location, use primary location now\n        else return [this.#trusted_location, this.#primary_location] // first try to get from trusted location\n    }\n\n    private static initPointerFromTrustedLocation(id:string, maybe_trusted_location:StorageLocation) {\n        if (this.#primary_location == undefined) return;\n        if (this.#primary_location == this.#trusted_location) return;\n\n        // wait until pointer loaded, TODO: timeout or return promise?\n        setTimeout(async ()=>{\n            if (this.#primary_location == maybe_trusted_location) {\n                const pointer = Pointer.get(id);\n                if (pointer?.value_initialized) {\n                    await this.setPointer(pointer, true, this.#primary_location)\n                    this.#trusted_pointers.add(id)\n                }\n                else {\n                    console.log(\"cannot init pointer \" +id)\n                }\n            }\n        }, 3000);\n\n    }\n\n    private static async initItemFromTrustedLocation(key: string, value:any, maybe_trusted_location:StorageLocation) {\n        if (this.#primary_location == undefined) return;\n        if (this.#primary_location == this.#trusted_location) return;\n\n        if (this.#primary_location == maybe_trusted_location) {\n            await this.setItem(key, value, true, this.#primary_location)\n        }\n\n    }\n\n\n    private static async restoreDirtyState() {\n        if (this.#primary_location != undefined && this.isInDirtyState(this.#primary_location) && this.#trusted_location != undefined && this.#trusted_location!=this.#primary_location) {\n            await this.copyStorage(this.#trusted_location, this.#primary_location)\n            logger.warn `restored dirty state of ${this.#primary_location.name} from trusted location ${this.#trusted_location.name}`\n            if (this.#dirty_locations.has(this.#primary_location)) this.setDirty(this.#primary_location, false) // remove from dirty set\n            this.clearDirtyState(this.#primary_location) // remove from localstorage\n            this.#dirty = false;\n            // primary location is now trusted, update\n            this.determineTrustedLocation()\n            // this.trusted_location = this.#primary_location\n        }\n    }\n\n    private static handleDirtyStateError() {\n        handleError(new KnownError(\n            `Cannot restore dirty eternal state (location: ${this.#primary_location!.name})`,\n            [],\n            [\n                {\n                    description: \"Do you want to reset the current application state? (THIS IS IRREVERSIBLE)\",\n                    fix: () => {\n                        this.clearAndReload();\n                    }\n                }\n            ]\n        ))\n    }\n\n\n    /**\n     * Maps pointer ids to existing subscriber caches that were preloaded from storage\n     */\n    public static subscriberCaches = new Map<string, Set<Endpoint>>()\n\n    /**\n     * gets the value of a pointer from storage\n     * @param pointer_id id string\n     * @param pointerify creates DATEX Pointer if true, otherwise just returns the value\n     * @param outer_serialized if true, the outer value type is not evaluated and only the serialized value is returned\n     * @returns value from pointer storage\n     */\n    public static async getPointer(pointer_id:string, pointerify?:boolean, bind?:any, location?:StorageLocation, conditions?: ExecConditions):Promise<any> {\n\n        if (this.#dirty) {\n            this.handleDirtyStateError();\n        }\n\n        // try to find pointer at a storage location\n        for (const loc of (location!=undefined ? [location] : this.getLocationPriorityOrder(pointer_id))) {\n            if (loc==undefined) continue;\n            const val = await this.getPointerFromLocation(pointer_id, pointerify, bind, loc, conditions);\n            if (val !== NOT_EXISTING) return val;\n        }\n        \n        return NOT_EXISTING\n    }\n\n    private static async getPointerFromLocation(pointer_id:string, pointerify: boolean|undefined, bind:any|undefined, location:StorageLocation, conditions?: ExecConditions) {\n        const val = await this.getPointerAsync(location, pointer_id, pointerify, bind, conditions);\n\t\tif (val == NOT_EXISTING) return NOT_EXISTING;\n        \n\t\tawait this.initPointerFromTrustedLocation(pointer_id, location)\n        return val;\n    }\n\n    private static async getPointerAsync(location:StorageLocation, pointer_id:string, pointerify?:boolean, bind?:any, conditions?: ExecConditions) {\n\n        let pointer:Pointer|undefined;\n\t\tif (pointerify && (pointer = Pointer.get(pointer_id))?.value_initialized) {\n            return pointer.val; // pointer exists in runtime\n        }\n\n\n        // load from storage\n\t\tlet val = await location.getPointerValue(pointer_id, !!bind, conditions);\n\n        if (val == NOT_EXISTING) return NOT_EXISTING;\n\n        // bind serialized val to existing value\n        if (bind) {\n            Type.ofValue(bind).updateValue(bind, val);\n            val = bind;\n        }\n\n        // create pointer with saved id and value + start syncing, if pointer not already created in DATEX\n        if (pointerify) {\n            let pointer = Pointer.get(pointer_id)\n\n            // if the value is a pointer with a tranform scope, copy the transform, not the value (TODO still just a workaround to preserve transforms in storage, maybe better solution?)\n            if (val instanceof Pointer && val.transform_scope) {\n                console.log(\"init value\",val);\n                pointer = await Pointer.createTransformAsync(val.transform_scope.internal_vars, val.transform_scope);\n            }\n            // set value of existing pointer\n            else if (pointer) {\n                if (pointer.value_initialized) logger.warn(\"pointer value \" + pointer.idString() + \" already initialized, setting new value from storage\");\n                pointer = pointer.setValue(val);\n            }\n            // create new pointer from value\n            else {\n                pointer = Pointer.create(pointer_id, val, false, Runtime.endpoint);\n            }\n\n            this.syncPointer(pointer);\n            this.#storage_active_pointers.add(pointer);\n            pointer.isStored = true;\n            if (pointer.is_js_primitive) return pointer;\n            else return pointer.val;\n        }\n\n        else {\n            this.#storage_active_pointer_ids.add(pointer_id);\n            return val;\n        }\n    }\n\n    private static async removePointer(pointer_id:string, location?:StorageLocation, force_remove = false) {\n        const count = await this.getReferenceCount(pointer_id);\n        if (count == -1) {\n            console.error(\"Cannot remove pointer\"  + pointer_id + \", reference count not available\");\n            return;\n        }\n        if (!force_remove && count > 0) {\n            logger.warn(\"Cannot remove pointer $\" + pointer_id + \", still referenced\");\n            return;\n        }\n        logger.debug(\"Removing pointer $\" + pointer_id + \" from storage\" + (location ? \" (\" + location.name  + \")\" : \"\"));\n\n        // remove from specific location\n\t\tif (location) return location.removePointer(pointer_id);\n\t\t// remove from all\n\t\telse {\n\n            const ptr = Pointer.get(pointer_id)\n            if (ptr) {\n                this.#storage_active_pointers.delete(ptr);\n                // remember that this pointer is not stored in storage             \n                ptr.isStored = false;\n            }\n            this.#storage_active_pointer_ids.delete(pointer_id);\n\n            const promises = []\n\n            // remove pointer from all locations\n\t\t\tfor (const location of this.#locations.keys()) {\n\t\t\t\tpromises.push(location.removePointer(pointer_id));\n\t\t\t}\n\n            // remove subscriber cache\n            promises.push(this.removePointerSubscriberCache(pointer_id));\n\n            await Promise.all(promises);\n\n            // clear dependencies\n            await this.updatePointerDependencies(pointer_id, [])\n\t\t}\n    }\n\n    public static async getPointerDecompiled(pointer_id:string, colorized = false, location?:StorageLocation):Promise<string|undefined|typeof NOT_EXISTING> {\n        // try to find pointer at a storage location\n        for (const loc of (location!=undefined ? [location] : this.getLocationPriorityOrder(pointer_id))) {\n            if (loc==undefined) continue;\n            const val = await this.getPointerDecompiledFromLocation(pointer_id, colorized, loc);\n            if (val !== NOT_EXISTING) return val;\n        }\n        return NOT_EXISTING;\n    }\n\n\n    private static async getPointerDecompiledFromLocation(pointer_id:string, colorized = false, location:StorageLocation) {\n\t\tconst buffer = await location.getPointerValueDXB(pointer_id);\n\t\tif (buffer != null) return MessageLogger.decompile(buffer, false, colorized);\n        return NOT_EXISTING;\n    }\n\n    /**\n     * Gets a subscriber cache for a pointer if it exists\n     */\n    public static async getPointerSubscriberCache(pointer_id:string) {\n        // return existing cache from memory\n        if (this.subscriberCaches.has(pointer_id)) return this.subscriberCaches.get(pointer_id);\n        // load from storage\n        const id = this.subscriber_cache_prefix + pointer_id;\n        const subscribers = await this.getItem(id) as Set<Endpoint>|undefined;\n        if (subscribers) this.subscriberCaches.set(pointer_id, subscribers);\n        return subscribers;\n    }\n\n    /**\n     * Removes the subscriber cache from memory and storage\n     * @returns \n     */\n    private static removePointerSubscriberCache(pointer_id:string) {\n        const id = this.subscriber_cache_prefix + pointer_id;\n        this.subscriberCaches.delete(pointer_id);\n        return this.removeItem(id);\n    }\n\n    /**\n     * Gets or creates a new subscriber cache for a pointer and\n     * puts it into the subscriberCaches map\n     * @returns \n     */\n    public static async requestSubscriberCache(pointer_id:string) {\n        // return existing cache\n        const existingCache = await this.getPointerSubscriberCache(pointer_id);\n        if (existingCache) return existingCache;\n        // create new cache\n        const id = this.subscriber_cache_prefix + pointer_id;\n        const subscribers = Pointer.createOrGet(new Set<Endpoint>()).val;\n        this.subscriberCaches.set(pointer_id, subscribers);\n        await this.setItem(id, subscribers);\n        return subscribers;\n    }\n\n    public static async getItemDecompiled(key:string, colorized = false, location?:StorageLocation) {\n        // try to find pointer at a storage location\n        for (const loc of (location!=undefined ? [location] : this.getLocationPriorityOrder(key))) {\n            if (loc==undefined) continue;\n            const val = await this.getItemDecompiledFromLocation(key, colorized, loc);\n            if (val !== NOT_EXISTING) return val;\n        }\n        return NOT_EXISTING;\n    }\n\n    public static async getItemDecompiledFromLocation(key:string, colorized = false, location:StorageLocation) {\n\t\tconst buffer = await location.getItemValueDXB(key);\n\t\tif (buffer != null) return MessageLogger.decompile(buffer, false, colorized);\n        return NOT_EXISTING;\n    }\n\n    public static async getItemKeys(location?:StorageLocation, prefix?: string){\n\n\t\t// for specific location\n\t\tif (location) return location.getItemKeys(prefix);\n\n\t\t// ... iterate over keys from all locations\n\n\t\tconst generators = [];\n\t\tfor (const location of this.#locations.keys()) {\n\t\t\tgenerators.push(await location.getItemKeys(prefix))\n\t\t}\n\n        return (function*(){\n            const used = new Set<string>();\n\n\t\t\tfor (const generator of generators) {\n\t\t\t\tfor (const key of generator) {\n                    if (used.has(key)) continue;\n                    used.add(key);\n                    yield key;\n                } \n\t\t\t}\n        })()\n    }\n\n\n    public static async getItemKeysStartingWith(prefix:string, location?:StorageLocation) {\n        const keyIterator = await Storage.getItemKeys(location, prefix);\n        return (function*(){\n            for (const key of keyIterator) {\n                if (key.startsWith(prefix)) yield key;\n            }\n        })()\n    }\n\n    public static async getItemCountStartingWith(prefix:string, location?:StorageLocation) {\n        const keyIterator = await Storage.getItemKeys(location, prefix);\n        let count = 0;\n        for (const key of keyIterator) {\n            if (key.startsWith(prefix)) count++;\n        }\n        return count\n    }\n\n    public static async supportsMatchQueries(type: Type) {\n        return (this.#primary_location?.supportsMatchSelection && await this.#primary_location?.supportsMatchForType!(type)) ?? false;\n    }\n\n    public static itemMatchQuery<T extends object, Options extends MatchOptions<T>>(itemPrefix: string, valueType:Type<T>, match: MatchInput<T>, options?:Options) {\n        options ??= {} as Options;\n        if (!this.#primary_location?.supportsMatchSelection) throw new Error(\"Primary storage location does not support match queries\");\n        return this.#primary_location!.matchQuery!(itemPrefix, valueType, match, options);\n    }\n\n\n    public static async getPointerIds(location?:StorageLocation){\n\n\t\t// for specific location\n\t\tif (location) return location.getPointerIds();\n\n\t\t// ... iterate over keys from all locations\n\n\t\tconst generators = [];\n\t\tfor (const location of this.#locations.keys()) {\n\t\t\tgenerators.push(await location.getPointerIds())\n\t\t}\n\n        return (function*(){\n            const used = new Set<string>();\n\n\t\t\tfor (const generator of generators) {\n\t\t\t\tfor (const id of generator) {\n                    if (used.has(id)) continue;\n                    used.add(id);\n                    yield id;\n                } \n\t\t\t}\n        })()         \n    }\n\n    private static async copyStorage(from:StorageLocation, to:StorageLocation) {\n\n        await this.clear(to);\n\n        const promises = [];\n        \n        for (const pointer_id of await this.getPointerIds(from)) {\n\t\t\tconst buffer = await from.getPointerValueDXB(pointer_id);\n\t\t\tif (!buffer) logger.error(\"could not copy empty pointer value: \" + pointer_id)\n\t\t\telse promises.push(to.setPointerValueDXB(pointer_id, buffer))\n        }\n\n        for (const key of await this.getItemKeys(from)) {\n            const buffer = await from.getItemValueDXB(key);\n\t\t\tif (!buffer) logger.error(\"could not copy empty item value: \" + key)\n\t\t\telse promises.push(to.setItemValueDXB(key, buffer))\n        }\n\n        await Promise.all(promises);\n    }\n\n    public static async getItem(key:string, location?:StorageLocation|undefined/* = this.#primary_location*/, conditions?: ExecConditions):Promise<any> {\n\n        if (this.#dirty) {\n            this.handleDirtyStateError();\n        }\n\n        // get from cache\n        if (Storage.cache.has(key)) return Storage.cache.get(key);\n\n        // try to find item at a storage location\n        for (const loc of (location!=undefined ? [location] : this.getLocationPriorityOrder(key))) {\n            if (loc==undefined) continue;\n            const val = await this.getItemFromLocation(key, loc, conditions);\n            if (val!==NOT_EXISTING) return val;\n        }\n\n        return undefined;\n    }\n\n\n    public static async getItemFromLocation(key:string, location:StorageLocation/* = this.#primary_location*/, conditions?: ExecConditions):Promise<any> {\n\n        if (!location.supportsExecConditions && conditions) throw new Error(`Storage Location ${location.name} does not support exec conditions`);\n\n\t\tconst val = await location.getItem(key, conditions);\n\t\tif (val == NOT_EXISTING) return NOT_EXISTING;\n\n\t\tStorage.cache.set(key, val);\n\t\tawait this.initItemFromTrustedLocation(key, val, location)\n\n\t\treturn val;\n    }\n\n    public static async getItemKey(value: any, location?:StorageLocation|undefined):Promise<string|undefined> {\n        // try to find item at a storage location\n        for (const loc of (location!=undefined ? [location] : this.getLocationPriorityOrder(\"\"))) {\n            if (loc==undefined) continue;\n            const val = await this.getItemKeyFromLocation(value, loc);\n            if (val !== undefined) return val;\n        }\n        return undefined;\n    }\n\n    public static getItemKeyFromLocation(value: any, location:StorageLocation):Promise<string|undefined>|string|undefined {\n        if (!location.supportsMatchSelection) throw new Error(`Storage Location ${location.name} does not support match queries (getItemKey)`);\n        return location.getItemKey?.(value);\n    }\n\n    \n    public static async hasItem(key:string, location?:StorageLocation):Promise<boolean> {\n        \n        if (Storage.cache.has(key)) return true; // get from cache\n \n        // try to find item at a storage location\n        for (const loc of (location!=undefined ? [location] : this.getLocationPriorityOrder(key))) {\n            if (loc==undefined) continue;\n            const val = await this.hasItemFromLocation(key, loc);\n            if (val) return true;\n        }\n\n        return false;\n    }\n\n    public static hasItemFromLocation(key:string, location:StorageLocation):Promise<boolean>|boolean {\n\t\tif (location)  {\n\t\t\treturn location.hasItem(key);\n\t\t}\n\t\telse return false;\n    }\n\n    /**\n     * Remove an item from storage, returns true if the item existed\n     */\n    public static async removeItem(key:string, location?:StorageLocation):Promise<boolean> {\n\n        logger.debug(\"Removing item '\" + key + \"' from storage\" + (location ? \" (\" + location.name + \")\" : \"\"))\n\n\t\t// remove from specific location\n\t\tif (location) {\n            // TODO: handle hasItem() internally in storage locations\n            const itemExists = await location.hasItem(key);\n            await location.removeItem(key);\n            return itemExists;\n        }\n\t\t// remove from all\n\t\telse {\n            Storage.cache.delete(key); // delete from cache\n            \n            let itemExists = false;\n\t\t\tfor (const location of this.#locations.keys()) {\n                // TODO: handle hasItem() internally in storage locations\n                if (!itemExists) itemExists = await location.hasItem(key);\n\t\t\t\tawait location.removeItem(key);\n\t\t\t}\n\n            // clear dependencies\n            await this.updateItemDependencies(key, [])\n\n            return itemExists;\n\t\t}\n    }\n\n    /**\n     * Increase the reference count of a pointer in storage\n     */\n    private static async increaseReferenceCount(ptrId:string) {\n        const count = await this.getReferenceCount(ptrId);\n        if (count == -1) {\n            console.log(\"Cannot increment unknown rc for pointer \" + ptrId);\n            return;\n        }\n        await this.setItem(this.rc_prefix+ptrId, (count + 1).toString());\n    }\n    /**\n     * Decrease the reference count of a pointer in storage\n     */\n    private static async decreaseReferenceCount(ptrId:string) {\n        const count = await this.getReferenceCount(ptrId);\n        if (count == -1) {\n            console.log(\"Cannot decrement unknown rc for pointer \" + ptrId);\n            return;\n        }\n        const newCount = count - 1;\n        // RC is 0, delete pointer from storage\n        if (newCount <= 0) {\n            this.removeItem(this.rc_prefix+ptrId)\n                .catch(e=>console.error(e));\n            this.removePointer(ptrId, undefined, true)\n                .catch(e=>console.error(e))\n        }\n        // decrease RC\n        else await this.setItem(this.rc_prefix+ptrId, newCount.toString())\n    }\n    /**\n     * Get the current reference count of a pointer (number of entries that have a reference to this pointer)\n     * @returns \n     */\n    private static async getReferenceCount(ptrId:string) {\n        const entry = await this.getItem(this.rc_prefix+ptrId);\n        return entry ? Number(entry) : 0;\n    }\n\n    private static async setDependencies(key:string, depPtrIds:string[], prefix:string) {\n        const uniqueKey = prefix+key;\n        if (!depPtrIds.length) await this.removeItem(uniqueKey);\n        else await this.setItem(uniqueKey, depPtrIds.join(\",\"));\n    }\n\n    private static setItemDependencies(key:string, depPtrIds:string[]) {\n        return this.setDependencies(key, depPtrIds, this.item_deps_prefix);\n    }\n    private static setPointerDependencies(key:string, depPtrIds:string[]) {\n        return this.setDependencies(key, depPtrIds, this.pointer_deps_prefix);\n    }\n    private static async getItemDependencies(key:string): Promise<string[]> {\n        const uniqueKey = this.item_deps_prefix+key;\n        return ((await this.getItem(uniqueKey))?.split(\",\")) ?? [];\n    }\n    private static async getPointerDependencies(key:string): Promise<string[]> {\n        const uniqueKey = this.pointer_deps_prefix+key;\n        return ((await this.getItem(uniqueKey))?.split(\",\")) ?? [];\n    }\n\n    private static async updateItemDependencies(key:string, newDeps:string[]) {\n        // ignore if rc:: or deps:: key\n        if (key.startsWith(this.rc_prefix) || key.startsWith(this.item_deps_prefix) || key.startsWith(this.pointer_deps_prefix)) return;\n        const oldDeps = await this.getItemDependencies(key);\n        const added = newDeps.filter(p=>!oldDeps.includes(p));\n        const removed = oldDeps.filter(p=>!newDeps.includes(p));\n        for (const ptrId of added) this.increaseReferenceCount(ptrId).catch(e=>console.error(e));\n        for (const ptrId of removed) this.decreaseReferenceCount(ptrId).catch(e=>console.error(e));\n        this.setItemDependencies(key, newDeps).catch(e=>console.error(e));\n    }\n    private static async updatePointerDependencies(key:string, newDeps:string[]) {\n        // ignore if rc:: or deps:: key\n        if (key.startsWith(this.rc_prefix) || key.startsWith(this.item_deps_prefix) || key.startsWith(this.pointer_deps_prefix)) return;\n        const oldDeps = await this.getPointerDependencies(key);\n        const added = newDeps.filter(p=>!oldDeps.includes(p));\n        const removed = oldDeps.filter(p=>!newDeps.includes(p));\n        for (const ptrId of added) this.increaseReferenceCount(ptrId).catch(e=>console.error(e));\n        for (const ptrId of removed) this.decreaseReferenceCount(ptrId).catch(e=>console.error(e));\n        this.setPointerDependencies(key, newDeps).catch(e=>console.error(e));\n    }\n    \n\n    public static clearAll(){\n        return this.clear()\n    }\n\n    // clear all storages\n    public static async clear(onlyLocation?:StorageLocation):Promise<void> {\n\n\t\tfor (const location of this.#locations.keys()) {\n\t\t\tif (onlyLocation == undefined || location === onlyLocation) {\n\t\t\t\tthis.deleteSaveTime(location);\n\t\t\t\tthis.clearDirtyState(location)\n\t\t\t\tawait location.clear()\n\t\t\t}\n\t\t}\n        \n    }\n\n    /**\n     * reset state, \n     */\n    public static async clearAndReload() {\n        await Storage.clearAll();\n        Storage.allowExitWithoutSave();\n        if (client_type === \"deno\") Deno.exit(1);\n        else if (globalThis.window?.location) {\n            globalThis.location.reload();\n        }\n        else logger.error(\"Could not reload in non-browser or Deno context\")\n    }\n\n    // load saved state\n    public static async loadOrCreate<T>(id:string|number, create?:()=>Promise<T>|T, conditions?: ExecConditions, override = false):Promise<MinimalJSRef<T>> {\n        const state_name = this.state_prefix+id.toString();\n\n        // already has a saved state\n        if (!override && await this.hasItem(state_name)) {\n            return await this.getItem(state_name, undefined, conditions)\n        }\n        // create state\n        else if (create){\n            const state = Pointer.createOrGet(await create());\n\n            // workaround: update item as soon as pointer id is changed with actual endpoint id (e.g. for Datex.Runtime.ENV)\n            if (Runtime.endpoint === LOCAL_ENDPOINT) {\n                Runtime.onEndpointChanged(() => {\n                    this.setItem(state_name, state.js_value, true);\n                })\n            }\n\n            await this.setItem(state_name, state.js_value, true);\n            return <any>state.js_value;\n        }\n        else throw new Error(\"Cannot find or create the state '\" + id + \"'\")\n    }\n\n\n    public static async printSnapshot(options: StorageSnapshotOptions = {internalItems: false, expandStorageMapsAndSets: true, onlyHeaders: false}) {\n        const {items, pointers} = await this.getSnapshot(options);\n\n        const COLOR_PTR = `\\x1b[38;2;${[65,102,238].join(';')}m`\n        const COLOR_NUMBER = `\\x1b[38;2;${[253,139,25].join(';')}m`\n\n        let string = ESCAPE_SEQUENCES.BOLD+\"Storage Locations\\n\\n\"+ESCAPE_SEQUENCES.RESET\n        string += `${ESCAPE_SEQUENCES.ITALIC}A list of all currently used storage locations and their corresponding store strategies.\\n${ESCAPE_SEQUENCES.RESET}`\n\n        for (const [location, options] of this.#locations) {\n            string += `\\n  • ${location.name} ${ESCAPE_SEQUENCES.GREY}(${options.modes.map(m=>Storage.Mode[m]).join(', ')})${ESCAPE_SEQUENCES.RESET}`\n        }\n\n        string += `\\n\\n${ESCAPE_SEQUENCES.BOLD}Trusted Location:${ESCAPE_SEQUENCES.RESET} ${this.#trusted_location?.name ?? \"none\"}`\n        string += `\\n${ESCAPE_SEQUENCES.BOLD}Primary Location:${ESCAPE_SEQUENCES.RESET} ${this.#primary_location?.name ?? \"none\"}`\n\n        console.log(string+\"\\n\\n\");\n\n        // pointers\n        string = ESCAPE_SEQUENCES.BOLD+\"Pointers\\n\\n\"+ESCAPE_SEQUENCES.RESET\n        string += `${ESCAPE_SEQUENCES.ITALIC}A list of all pointers stored in any storage location. Pointers are only stored as long as they are referenced somewhere else in the storage.\\n\\n${ESCAPE_SEQUENCES.RESET}`\n\n        const pointersInMemory = [...pointers.snapshot.keys()].filter(id => Pointer.get(id)).length;\n        string += `\\nTotal:     ${ESCAPE_SEQUENCES.BOLD}${pointers.snapshot.size}${ESCAPE_SEQUENCES.RESET} pointers`\n        string += `\\nIn memory: ${ESCAPE_SEQUENCES.BOLD}${pointersInMemory}${ESCAPE_SEQUENCES.RESET} pointers\\n\\n`\n\n        if (!options.onlyHeaders) {\n            for (const [key, storageMap] of pointers.snapshot) {\n                // check if stored in all locations, otherwise print in which location it is stored (functional programming)\n                const locations = [...storageMap.keys()]\n                const storedInAll = [...this.#locations.keys()].every(l => locations.includes(l));\n                \n                const value = [...storageMap.values()][0];\n                string += `  • ${COLOR_PTR}$${key}${ESCAPE_SEQUENCES.GREY}${storedInAll ? \"\" : (` (only in ${locations.map(l=>l.name).join(\",\")})`)} = ${value.replaceAll(\"\\n\", \"\\n    \")}\\n`\n            }\n        }\n        console.log(string+\"\\n\");\n\n        // items\n        string = ESCAPE_SEQUENCES.BOLD+\"Items\\n\\n\"+ESCAPE_SEQUENCES.RESET\n        string += `${ESCAPE_SEQUENCES.ITALIC}A list of all named items stored in any storage location.\\n\\n${ESCAPE_SEQUENCES.RESET}`\n\n        if (!options.onlyHeaders) {\n            for (const [key, storageMap] of items.snapshot) {\n                \n                // skip rc:: and deps:: items\n                if (key.startsWith(this.rc_prefix) || key.startsWith(this.item_deps_prefix) || key.startsWith(this.pointer_deps_prefix)) continue;\n\n                // check if stored in all locations, otherwise print in which location it is stored (functional programming)\n                const locations = [...storageMap.keys()]\n                const storedInAll = [...this.#locations.keys()].every(l => locations.includes(l));\n                \n                const value = [...storageMap.values()][0];\n                string += `  • ${key}${ESCAPE_SEQUENCES.GREY}${storedInAll ? \"\" : (` (only in ${locations.map(l=>l.name).join(\",\")})`)} = ${value}\\n`\n            }\n        }\n        console.log(string+\"\\n\");\n\n        // memory management\n        if (options?.internalItems) {\n            string = ESCAPE_SEQUENCES.BOLD+\"Memory Management\\n\\n\"+ESCAPE_SEQUENCES.RESET\n            string += `${ESCAPE_SEQUENCES.ITALIC}This section shows the reference count (rc::) of pointers and the dependencies (deps::) of items and pointers. The reference count of a pointer tracks the number of items and pointers that reference this pointer.\\n\\n${ESCAPE_SEQUENCES.RESET}`\n            let rc_string = \"\"\n            let item_deps_string = \"\"\n            let pointer_deps_string = \"\"\n            if (!options.onlyHeaders) {\n                for (const key of await this.getItemKeysStartingWith(this.rc_prefix)) {\n                    const ptrId = key.substring(this.rc_prefix.length);\n                    const count = await this.getReferenceCount(ptrId);\n                    rc_string += `\\x1b[0m  • ${key} = ${COLOR_NUMBER}${count}\\n`\n                }\n\n                for (const key of await this.getItemKeysStartingWith(this.item_deps_prefix)) {\n                    const depsRaw = await this.getItem(key);\n                    // single entry\n                    if (!depsRaw?.includes(\",\")) {\n                        item_deps_string += `\\x1b[0m  • ${key} = (${COLOR_PTR}${depsRaw}\\x1b[0m)\\n`\n                    }\n                    // multiple entries\n                    else {\n                        let deps = (await this.getItem(key))!.split(\",\").join(`\\x1b[0m,\\n      ${COLOR_PTR}$`)\n                        if (deps) deps = `      ${COLOR_PTR}$`+deps\n                        item_deps_string += `\\x1b[0m  • ${key} = (\\n${COLOR_PTR}${deps}\\x1b[0m\\n    )\\n`\n                    }\n                }\n\n                for (const key of await this.getItemKeysStartingWith(this.pointer_deps_prefix)) {\n                    const depsRaw = await this.getItem(key);\n                    // single entry\n                    if (!depsRaw?.includes(\",\")) {\n                        pointer_deps_string += `\\x1b[0m  • ${key} = (${COLOR_PTR}${depsRaw}\\x1b[0m)\\n`\n                    }\n                    // multiple entries\n                    else {\n                        let deps = (await this.getItem(key))!.split(\",\").join(`\\x1b[0m,\\n      ${COLOR_PTR}$`)\n                        if (deps) deps = `      ${COLOR_PTR}$`+deps\n                        pointer_deps_string += `\\x1b[0m  • ${key} = (\\n${COLOR_PTR}${deps}\\x1b[0m\\n    )\\n`\n                    }\n                }\n\n            }\n\n            string += rc_string + \"\\n\" + item_deps_string + \"\\n\" + pointer_deps_string;\n            console.log(string+\"\\n\");\n        }\n\n        // inconsistencies\n        if (pointers.inconsistencies.size > 0 || items.inconsistencies.size > 0) {\n            string = ESCAPE_SEQUENCES.BOLD+\"Inconsistencies\\n\\n\"+ESCAPE_SEQUENCES.RESET\n            string += `${ESCAPE_SEQUENCES.ITALIC}Inconsistencies between storage locations don't necessarily indicate that something is wrong. They can occur when a storage location is not updated immediately (e.g. when only using SAVE_ON_EXIT).\\n\\n${ESCAPE_SEQUENCES.RESET}`\n            \n            \n            if (!options.onlyHeaders) {\n                for (const [key, storageMap] of pointers.inconsistencies) {\n                    for (const [location, value] of storageMap) {\n                        string += `  • ${COLOR_PTR}$${key}${ESCAPE_SEQUENCES.GREY} (${(location.name+\")\").padEnd(15, \" \")} = ${value.replaceAll(\"\\n\", \"\\n    \")}\\n`\n                    }\n                    string += `\\n`\n                }\n                for (const [key, storageMap] of items.inconsistencies) {\n                    for (const [location, value] of storageMap) {\n                        string += `  • ${key}${ESCAPE_SEQUENCES.GREY} (${(location.name+\")\").padEnd(15, \" \")} = ${value}\\n`\n                    }\n                    string += `\\n`\n                }\n            }\n\n            console.info(string+\"\\n\");\n        }\n        \n\n    }\n\n    public static removeTrailingSemicolon(str:string) {\n        // replace ; and reset sequences with nothing\n        return str.replace(/;(\\x1b\\[0m)?$/g, \"\")\n    }\n\n    public static async getSnapshot(options: StorageSnapshotOptions = {internalItems: false, expandStorageMapsAndSets: true}) {\n        const allowedPointerIds = options.itemFilter ? new Set<string>() : undefined;\n        const items = await this.createSnapshot(this.getItemKeys.bind(this), this.getItemDecompiled.bind(this), options.itemFilter, allowedPointerIds);\n        const pointers = await this.createSnapshot(this.getPointerIds.bind(this), this.getPointerDecompiledFromLocation.bind(this), options.itemFilter, allowedPointerIds);\n\n        // remove keys items that are unrelated to normal storage\n        for (const [key] of items.snapshot) {\n            if (key.startsWith(\"keys_\") || key.startsWith(\"hash_keys_\")) {\n                if (options.internalItems) {\n                    for (const [location, _value] of items.snapshot.get(key)!) {\n                        items.snapshot.get(key)!.set(location, \"...\" + ESCAPE_SEQUENCES.RESET);\n                    }\n                }\n                else items.snapshot.delete(key);\n            }\n        }\n\n        // additional pointer entries from storage maps/sets\n        const additionalEntries = new Set<string>();\n\n        // iterate over storage maps and sets and render all entries\n        if (options.expandStorageMapsAndSets) {\n            for (const [ptrId, storageMap] of pointers.snapshot) {\n                // display entry from first storage\n                const [location, value] = [...storageMap.entries()][0];\n\n                if (value.startsWith(\"\\x1b[38;2;50;153;220m<StorageMap>\") || value.startsWith(\"\\x1b[38;2;50;153;220m<StorageSet>\")) {\n                    const ptr = await Pointer.load(ptrId, undefined, true);\n                    if (ptr instanceof LazyPointer) {\n                        console.error(\"LazyPointer in StorageMap/StorageSet\");\n                        continue;\n                    }\n                    if (ptr.val instanceof StorageMap) {\n                        const map = ptr.val;\n                        const keyIterator = await this.getItemKeysStartingWith((map as any)._prefix)\n                        const pointerIds = new Set<string>();\n                        let inner = \"\";\n                        for await (const key of keyIterator) {\n                            const valString = await this.getItemDecompiled(key, true, location);\n                            if (valString === NOT_EXISTING) {\n                                logger.error(\"Invalid entry in storage (\" + location.name + \"): \" + key);\n                                continue;\n                            }\n                            const keyString = await this.getItemDecompiled('key.' + key, true, location);\n                            if (keyString === NOT_EXISTING) {\n                                logger.error(\"Invalid key in storage (\" + location.name + \"): \" + key);\n                                continue;\n                            }\n                            inner += `   ${this.removeTrailingSemicolon(keyString)}\\x1b[0m => ${this.removeTrailingSemicolon(valString)}\\n`\n\n                            // additional pointer ids included in value or key\n                            if (allowedPointerIds) {\n                                const valMatches = valString.match(/\\$[a-zA-Z0-9]+/g)??[]\n                                const keyMatches = keyString.match(/\\$[a-zA-Z0-9]+/g)??[];\n\n                                for (const match of valMatches) {\n                                    const id = match.substring(1);\n                                    pointerIds.add(id)\n                                    if (!allowedPointerIds.has(id)) additionalEntries.add(id);\n                                }\n                                for (const match of keyMatches) {\n                                    const id = match.substring(1);\n                                    if (!allowedPointerIds.has(id)) additionalEntries.add(id);\n                                \n                                }\n                            }\n                        }\n\n                        // size in memory / total size\n                        const totalSize = await (ptr.val as StorageMap<unknown,unknown>).getSize();\n                        const totalDirectPointerSize = pointerIds.size;\n                        const inMemoryPointersSize= [...pointerIds].filter(id => Pointer.get(id)).length;\n                        const sizeInfo = `   ${ESCAPE_SEQUENCES.GREY}total size: ${totalSize}, in memory: ${inMemoryPointersSize}/${totalDirectPointerSize} pointers${ESCAPE_SEQUENCES.RESET}\\n`\n\n                        // substring: remove last \\n\n                        if (inner) storageMap.set(location, \"\\x1b[38;2;50;153;220m<StorageMap> \\x1b[0m{\\n\"+sizeInfo+inner.substring(0, inner.length-1)+\"\\x1b[0m\\n}\")\n                    }\n                    else if (ptr.val instanceof StorageSet) {\n                        const set = ptr.val;\n                        const keyIterator = await this.getItemKeysStartingWith((set as any)._prefix)\n                        const pointerIds = new Set<string>();\n\n                        let inner = \"\";\n                        for await (const key of keyIterator) {\n                            const valString = await this.getItemDecompiled(key, true, location);\n                            if (valString === NOT_EXISTING) {\n                                logger.error(\"Invalid entry in storage (\" + location.name + \"): \" + key);\n                                continue;\n                            }\n                            inner += `   ${this.removeTrailingSemicolon(valString)},\\n`\n\n                            // additional pointer ids included in value\n                            if (allowedPointerIds) {\n                                const matches = valString.match(/\\$[a-zA-Z0-9]+/g)??[];\n                                for (const match of matches) {\n                                    const id = match.substring(1);\n                                    pointerIds.add(id)\n                                    if (!allowedPointerIds.has(id)) additionalEntries.add(id);\n                                }\n                            }\n                        }\n\n                        // size in memory / total size\n                        const totalSize = await (ptr.val as StorageSet<unknown>).getSize();\n                        const totalDirectPointerSize = pointerIds.size;\n                        const inMemoryPointersSize= [...pointerIds].filter(id => Pointer.get(id)).length;\n                        const sizeInfo = `   ${ESCAPE_SEQUENCES.GREY}total size: ${totalSize}, in memory: ${inMemoryPointersSize}/${totalDirectPointerSize} pointers${ESCAPE_SEQUENCES.RESET}\\n`\n\n                        // substring: remove last \\n\n                        if (inner) storageMap.set(location, \"\\x1b[38;2;50;153;220m<StorageSet> \\x1b[0m{\\n\"+sizeInfo+inner.substring(0, inner.length-1)+\"\\x1b[0m\\n}\")\n                    }\n                }\n            }\n        }\n\n        if (additionalEntries.size > 0) {\n            await this.createSnapshot(this.getPointerIds.bind(this), this.getPointerDecompiledFromLocation.bind(this), options.itemFilter, additionalEntries, {\n                snapshot: pointers.snapshot,\n                inconsistencies: pointers.inconsistencies\n            });\n        }\n\n        return {items, pointers}\n    }\n\n    private static async createSnapshot(\n        keyGenerator: (location?: StorageLocation<Storage.Mode> | undefined) => Promise<Generator<string, void, unknown>>,\n        itemGetter: (key: string, colorized: boolean, location: StorageLocation<Storage.Mode>) => Promise<string|symbol>,\n        filter?: string,\n        allowedPointerIds?: Set<string>,\n        baseSnapshot?: {\n            snapshot: AutoMap<string, Map<StorageLocation<Storage.Mode>, string>>;\n            inconsistencies: AutoMap<string, Map<StorageLocation<Storage.Mode>, string>>;\n        }\n    ) {\n        const snapshot = baseSnapshot?.snapshot ?? new Map<string, Map<StorageLocation, string>>().setAutoDefault(Map);\n        const inconsistencies = baseSnapshot?.inconsistencies ?? new Map<string, Map<StorageLocation, string>>().setAutoDefault(Map);\n\n        const skippedEntries = new Set<string>();\n        const additionalEntries = new Set<string>();\n\n        for (const location of new Set([this.#primary_location!, ...this.#locations.keys()].filter(l=>!!l))) {\n            for (const key of await keyGenerator(location)) {\n                if (filter && !key.includes(filter) && !allowedPointerIds?.has(key)) {\n                    if (allowedPointerIds) skippedEntries.add(key); // remember skipped entries that might be added later\n                    continue;\n                }\n                const decompiled = await itemGetter(key, true, location);\n\n                if (typeof decompiled !== \"string\") {\n                    console.error(\"Invalid entry in storage (\" + location.name + \"): \" + key);\n                    continue;\n                }\n\n                // collect referenced pointer ids\n                if (allowedPointerIds) {\n                    const matches = decompiled.match(/\\$[a-zA-Z0-9]+/g);\n                    if (matches) {\n                        for (const match of matches) {\n                            const id = match.substring(1);\n                            if (skippedEntries.has(id)) additionalEntries.add(id);\n                            allowedPointerIds.add(id);\n                        }\n                    }\n                }\n                snapshot.getAuto(key).set(location, this.removeTrailingSemicolon(decompiled));\n            }\n        }\n        \n        // run again with additional entries\n        if (additionalEntries.size > 0) {\n            await this.createSnapshot(keyGenerator, itemGetter, filter, additionalEntries, {\n                snapshot,\n                inconsistencies\n            });\n        }\n\n        // find inconsistencies\n        for (const [key, storageMap] of snapshot) {\n            const [location, value] = [...storageMap.entries()][0];\n            // compare with first entry\n            for (const [location2, value2] of storageMap) {\n                if (value !== value2) {\n                    inconsistencies.getAuto(key).set(location, value);\n                    inconsistencies.getAuto(key).set(location2, value2);\n                }\n            }\n        }\n\n        return {snapshot, inconsistencies};\n    }\n\n}\n\nsetStorage(Storage);\n\nexport namespace Storage {\n\n\texport enum Mode {\n        SAVE_ON_EXIT, // save pointers on program exit / tab close\n        SAVE_ON_CHANGE, // save a pointer immediately when the value changes\n        SAVE_PERIODICALLY // save in fix interval\n    }\n}\n\n\n// TODO: convert to static block (saFrari) --------------------------------------\n// // @ts-ignore NO_INIT\n// if (!globalThis.NO_INIT) {\n//     Storage.determineTrustedLocation([]);\n// }\n\n// @ts-ignore NO_INIT\nif (!globalThis.NO_INIT) {\n    if (client_type == \"deno\") addEventListener(\"unload\", ()=>Storage.handleExit(), {capture: true});\n    addPersistentListener(globalThis, \"beforeunload\", ()=>Storage.handleExit(), {capture: true})\n    // @ts-ignore document\n    if (globalThis.document) addEventListener(\"visibilitychange\", ()=>{\n        // @ts-ignore document\n        if (document.visibilityState === 'hidden') Storage.handleExit()\n    });\n    if (client_type == \"deno\") {\n        Deno.addSignalListener(\"SIGINT\", ()=>Deno.exit())\n        try {\n            // not supported by WiNdoWs\n            await Deno.addSignalListener(\"SIGTERM\", ()=>Deno.exit(1))\n            await Deno.addSignalListener(\"SIGQUIT\", ()=>Deno.exit())\n        }\n        catch {}\n    }\n}\n// ------------------------------------------------------------------------------\n\n// proxy for Storage\nclass DatexStoragePointerSource implements PointerSource {\n    getPointer(pointer_id:string, pointerify?:boolean, localOnly?: boolean) {\n        return Storage.getPointer(pointer_id, pointerify, undefined, undefined, localOnly ? {onlyLocalPointers: true} : undefined)\n    }\n    syncPointer(pointer:Pointer) {\n        return Storage.syncPointer(pointer)\n    }\n}\n\nexport function registerStorageAsPointerSource() {\n\tPointer.registerPointerSource(new DatexStoragePointerSource());\n}\n\n"],"names":["MatchConditionType","ComputedPropertyType","Storage","Mode","Runtime","logger","client_type","NOT_EXISTING","Pointer","localStorage","MessageLogger","Type","addPersistentListener","LOCAL_ENDPOINT","ESCAPE_SEQUENCES","verboseArg","StorageMap","StorageSet","IterableWeakSet","LazyPointer","hasDebugCookie","setStorage","KnownError","handleError","site_suffix","globalThis","location","origin","MatchCondition","type","data","between","lower","upper","lessThan","value","greaterThan","lessOrEqual","greaterOrEqual","notEqual","contains","values","Set","pointerId","id","Array","ComputedProperty","geographicDistance","pointA","pointB","sum","SyncStorageLocation","isAsync","onAfterExit","AsyncStorageLocation","cache","Map","state_prefix","pointer_prefix","item_prefix","meta_prefix","rc_prefix","pointer_deps_prefix","item_deps_prefix","subscriber_cache_prefix","providePointer","ptr","has","add","delete","isStored","DEFAULT_INTERVAL","trusted_location","undefined","debug","name","primary_location","locations","addLocation","options","set","interval","modes","includes","SAVE_PERIODICALLY","Error","mode","SAVE_ON_EXIT","isSupported","addSaveInterval","_loc","SAVE_ON_CHANGE","primary","map","m","join","determineTrustedLocation","restoreDirtyState","removeLocation","get","clearInterval","setInterval","saveCurrentState","handleExit","update","Promise","error","loc","saveDirtyState","dirtyValues","size","saveFile","allowExitWithoutSave","isExit","c","key","val","res","setItem","catch","e","setPointer","value_initialized","updateSaveTime","onAfterSnapshot","console","Date","getTime","toString","deleteSaveTime","removeItem","getSaveTime","Number","getItem","setDirty","dirty","metadata","currentCount","newCount","warn","isInDirtyState","clearDirtyState","fromLocations","keys","last","last_time","time","listen_for_pointer_changes","setItemAsync","setItemSync","isDebugMode","valueToDatexString","itemExisted","hasItem","dependencies","is_local","checkUnresolvedLocalDependenciesForItem","updateItemDependencies","p","saveDependencyPointersAsync","saveDependencyPointersSync","some","checkUnresolvedLocalDependenciesForPointer","pointer","updateEntriesWithUnresolvedLocalDependencies","clear","idString","listen_for_changes","partialUpdateKey","force_listen_for_deps","initPointerAsync","initPointerSync","garbage_collected","updatePointerSync","updatePointerDependencies","syncPointer","updatePointerAsync","hasPointer","all","synced_pointers","WeakSet","saving","handler","v","t","supportsPartialUpdates","scheduleStorageUpdate","then","couldSave","unobserve","observe","ignore_transforms","recursive","updateFn","clearTimeout","timeout","setTimeout","getLocationPriorityOrder","pointer_id","initPointerFromTrustedLocation","maybe_trusted_location","log","initItemFromTrustedLocation","copyStorage","handleDirtyStateError","description","fix","clearAndReload","subscriberCaches","getPointer","pointerify","bind","conditions","getPointerFromLocation","getPointerAsync","getPointerValue","ofValue","updateValue","transform_scope","createTransformAsync","internal_vars","setValue","create","endpoint","is_js_primitive","removePointer","force_remove","count","getReferenceCount","promises","push","removePointerSubscriberCache","getPointerDecompiled","colorized","getPointerDecompiledFromLocation","buffer","getPointerValueDXB","decompile","getPointerSubscriberCache","subscribers","requestSubscriberCache","existingCache","createOrGet","getItemDecompiled","getItemDecompiledFromLocation","getItemValueDXB","getItemKeys","prefix","generators","used","generator","getItemKeysStartingWith","keyIterator","startsWith","getItemCountStartingWith","supportsMatchQueries","supportsMatchSelection","supportsMatchForType","itemMatchQuery","itemPrefix","valueType","match","matchQuery","getPointerIds","from","to","setPointerValueDXB","setItemValueDXB","getItemFromLocation","supportsExecConditions","getItemKey","getItemKeyFromLocation","hasItemFromLocation","itemExists","increaseReferenceCount","ptrId","decreaseReferenceCount","entry","setDependencies","depPtrIds","uniqueKey","length","setItemDependencies","setPointerDependencies","getItemDependencies","split","getPointerDependencies","newDeps","oldDeps","added","filter","removed","clearAll","onlyLocation","Deno","exit","window","reload","loadOrCreate","override","state_name","state","onEndpointChanged","js_value","printSnapshot","internalItems","expandStorageMapsAndSets","onlyHeaders","items","pointers","getSnapshot","COLOR_PTR","COLOR_NUMBER","string","BOLD","RESET","ITALIC","GREY","pointersInMemory","snapshot","storageMap","storedInAll","every","l","replaceAll","rc_string","item_deps_string","pointer_deps_string","substring","depsRaw","deps","inconsistencies","padEnd","info","removeTrailingSemicolon","str","replace","allowedPointerIds","itemFilter","createSnapshot","_value","additionalEntries","entries","load","_prefix","pointerIds","inner","valString","keyString","valMatches","keyMatches","totalSize","getSize","totalDirectPointerSize","inMemoryPointersSize","sizeInfo","keyGenerator","itemGetter","baseSnapshot","setAutoDefault","skippedEntries","decompiled","matches","getAuto","location2","value2","NO_INIT","addEventListener","capture","document","visibilityState","addSignalListener","DatexStoragePointerSource","localOnly","onlyLocalPointers","registerStorageAsPointerSource","registerPointerSource"],"mappings":"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","sourceRoot":"/lib/datex-core-js-legacy-0.3.15/storage/","file":"storage.ts"}