@fjell/cache 4.6.22 → 4.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CACHE_EVENTS.md +306 -0
- package/CACHE_IMPLEMENTATIONS.md +315 -0
- package/CONFIGURATION_GUIDE.md +167 -0
- package/CRITICAL_FIXES.md +68 -0
- package/MEMORY_LEAK_FIXES.md +270 -0
- package/README.md +513 -2
- package/dist/Aggregator.d.ts +27 -16
- package/dist/Cache.d.ts +59 -1
- package/dist/CacheContext.d.ts +35 -0
- package/dist/CacheMap.d.ts +132 -14
- package/dist/CacheStats.d.ts +51 -0
- package/dist/Instance.d.ts +4 -2
- package/dist/InstanceFactory.d.ts +3 -2
- package/dist/Operations.d.ts +21 -17
- package/dist/Options.d.ts +98 -0
- package/dist/browser/AsyncIndexDBCacheMap.d.ts +38 -0
- package/dist/browser/IndexDBCacheMap.d.ts +69 -0
- package/dist/browser/LocalStorageCacheMap.d.ts +59 -0
- package/dist/browser/SessionStorageCacheMap.d.ts +51 -0
- package/dist/events/CacheEventEmitter.d.ts +82 -0
- package/dist/events/CacheEventFactory.d.ts +121 -0
- package/dist/events/CacheEventTypes.d.ts +122 -0
- package/dist/events/index.d.ts +3 -0
- package/dist/eviction/EvictionManager.d.ts +57 -0
- package/dist/eviction/EvictionStrategy.d.ts +142 -0
- package/dist/eviction/EvictionStrategyConfig.d.ts +97 -0
- package/dist/eviction/EvictionStrategyFactory.d.ts +12 -0
- package/dist/eviction/EvictionStrategyValidation.d.ts +36 -0
- package/dist/eviction/index.d.ts +10 -0
- package/dist/eviction/strategies/ARCEvictionStrategy.d.ts +73 -0
- package/dist/eviction/strategies/FIFOEvictionStrategy.d.ts +12 -0
- package/dist/eviction/strategies/LFUEvictionStrategy.d.ts +38 -0
- package/dist/eviction/strategies/LRUEvictionStrategy.d.ts +12 -0
- package/dist/eviction/strategies/MRUEvictionStrategy.d.ts +12 -0
- package/dist/eviction/strategies/RandomEvictionStrategy.d.ts +12 -0
- package/dist/eviction/strategies/TwoQueueEvictionStrategy.d.ts +54 -0
- package/dist/index.d.ts +29 -6
- package/dist/index.js +5764 -435
- package/dist/index.js.map +4 -4
- package/dist/memory/EnhancedMemoryCacheMap.d.ts +81 -0
- package/dist/memory/MemoryCacheMap.d.ts +48 -0
- package/dist/normalization.d.ts +19 -0
- package/dist/ops/action.d.ts +2 -3
- package/dist/ops/all.d.ts +2 -3
- package/dist/ops/allAction.d.ts +2 -3
- package/dist/ops/allFacet.d.ts +2 -3
- package/dist/ops/create.d.ts +2 -3
- package/dist/ops/facet.d.ts +2 -3
- package/dist/ops/find.d.ts +2 -3
- package/dist/ops/findOne.d.ts +2 -3
- package/dist/ops/get.d.ts +3 -3
- package/dist/ops/one.d.ts +2 -3
- package/dist/ops/remove.d.ts +2 -3
- package/dist/ops/reset.d.ts +2 -1
- package/dist/ops/retrieve.d.ts +2 -3
- package/dist/ops/set.d.ts +2 -2
- package/dist/ops/update.d.ts +2 -3
- package/dist/ttl/TTLManager.d.ts +100 -0
- package/dist/ttl/index.d.ts +2 -0
- package/dist/utils/CacheSize.d.ts +30 -0
- package/fix-async-tests.js +116 -0
- package/package.json +16 -13
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/
|
|
4
|
-
"sourcesContent": ["import Logging from '@fjell/logging';\n\nconst LibLogger = Logging.getLogger('@fjell/cache');\n\nexport default LibLogger;\n", "/* eslint-disable no-undefined */\nimport {\n ComKey,\n Item,\n ItemQuery,\n LocKeyArray,\n PriKey\n} from \"@fjell/core\";\nimport { Cache } from \"./Cache\";\nimport { CacheMap } from \"./CacheMap\";\nimport LibLogger from \"./logger\";\n\nconst logger = LibLogger.get('ItemAggregator');\n\nexport interface Aggregator<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n> extends Cache<V, S, L1, L2, L3, L4, L5> {\n // Cache operations exposed directly for aggregator\n all: (\n query?: ItemQuery,\n locations?: LocKeyArray<L1, L2, L3, L4, L5> | []\n ) => Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V[]]>;\n\n one: (\n query?: ItemQuery,\n locations?: LocKeyArray<L1, L2, L3, L4, L5> | []\n ) => Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V | null]>;\n\n action: (\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n action: string,\n body?: any\n ) => Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V]>;\n\n allAction: (\n action: string,\n body?: any,\n locations?: LocKeyArray<L1, L2, L3, L4, L5> | []\n ) => Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V[]]>;\n\n allFacet: (\n facet: string,\n params?: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n locations?: LocKeyArray<L1, L2, L3, L4, L5> | []\n ) => Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, any]>;\n\n create: (\n item: Partial<Item<S, L1, L2, L3, L4, L5>>,\n locations?: LocKeyArray<L1, L2, L3, L4, L5> | []\n ) => Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V]>;\n\n get: (\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>\n ) => Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V | null]>;\n\n retrieve: (\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>\n ) => Promise<[CacheMap<V, S, L1, L2, L3, L4, L5> | null, V | null]>;\n\n remove: (\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>\n ) => Promise<CacheMap<V, S, L1, L2, L3, L4, L5>>;\n\n update: (\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n item: Partial<Item<S, L1, L2, L3, L4, L5>>\n ) => Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V]>;\n\n facet: (\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n facet: string,\n params?: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>\n ) => Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, any]>;\n\n find: (\n finder: string,\n params?: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n locations?: LocKeyArray<L1, L2, L3, L4, L5> | []\n ) => Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V[]]>;\n\n findOne: (\n finder: string,\n params?: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n locations?: LocKeyArray<L1, L2, L3, L4, L5> | []\n ) => Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V]>;\n\n set: (\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n item: Item<S, L1, L2, L3, L4, L5>\n ) => Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V]>;\n\n reset: () => Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>]>;\n\n populate: (item: V) => Promise<V>;\n populateAggregate: (key: string, item: V) => Promise<void>;\n populateEvent: (key: string, item: V) => Promise<void>;\n}\n\nexport interface CacheConfig { cache: any, optional: boolean }\n\nexport interface AggregateConfig { [key: string]: (CacheConfig) }\n\nexport const toCacheConfig = <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(config: CacheConfig | Cache<V, S, L1, L2, L3, L4, L5>): CacheConfig => {\n let cacheConfig: CacheConfig;\n if ((config as CacheConfig).optional === undefined) {\n cacheConfig = { cache: config as any, optional: false };\n } else {\n cacheConfig = config as CacheConfig;\n }\n return cacheConfig;\n}\n\nexport const createAggregator = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n cache: Cache<V, S, L1, L2, L3, L4, L5>,\n { aggregates = {}, events = {} }:\n {\n aggregates?: AggregateConfig,\n events?: AggregateConfig\n }\n): Promise<Aggregator<V, S, L1, L2, L3, L4, L5>> => {\n\n const populate = async (item: V): Promise<V> => {\n logger.default('populate', { item });\n for (const key in aggregates) {\n await populateAggregate(key, item);\n }\n for (const key in events) {\n await populateEvent(key, item);\n }\n logger.default('populate done', { item });\n return item;\n }\n\n const populateAggregate = async (key: string, item: V) => {\n logger.default('populate aggregate key', { key });\n const cacheConfig = toCacheConfig(aggregates[key]);\n if (item.refs === undefined) {\n if (cacheConfig.optional === false) {\n logger.error('Item does not have refs an is not optional ' + JSON.stringify(item));\n throw new Error('Item does not have refs an is not optional ' + JSON.stringify(item));\n } else {\n if (item.events && Object.prototype.hasOwnProperty.call(item.events, key)) {\n delete item.events[key];\n }\n }\n } else if (item.refs[key] === undefined) {\n if (cacheConfig.optional === false) {\n logger.error('Item does not have mandatory ref with key, not optional ' +\n key + ' ' + JSON.stringify(item));\n throw new Error('Item does not have mandatory ref with key, not optional ' +\n key + ' ' + JSON.stringify(item));\n } else {\n if (item.events && Object.prototype.hasOwnProperty.call(item.events, key)) {\n delete item.events[key];\n }\n }\n } else {\n\n const ref = item.refs[key];\n\n logger.default('AGG Retrieving Item in Populate', { key: ref });\n const [, newItem] = await cacheConfig.cache.operations.retrieve(ref);\n if (newItem) {\n if (item.aggs === undefined) {\n item.aggs = {};\n }\n item.aggs[key] = {\n key: ref,\n item: newItem as Item,\n };\n }\n }\n }\n\n // TODO: I'm not a big fan that this just \"automatically\" assumes that the \"by\" key in event is a ref.\n const populateEvent = async (key: string, item: V) => {\n logger.default('populate event key', { key });\n const cacheConfig = toCacheConfig(events[key]);\n\n if (item.events === undefined) {\n throw new Error('Item does not have events ' + JSON.stringify(item));\n } else if (item.events[key] === undefined) {\n if (cacheConfig.optional === false) {\n logger.error('Item does not have mandatory event with key ' + key + ' ' + JSON.stringify(item));\n throw new Error('Item does not have mandatory event with key ' + key + ' ' + JSON.stringify(item));\n }\n } else {\n const event = item.events[key];\n\n if (event.by === undefined) {\n logger.error(\n 'populateEvent with an Event that does not have by', { event, ik: item.key, eventKey: key });\n throw new Error('populateEvent with an Event that does not have by: ' + JSON.stringify({ key, event }));\n }\n\n logger.default('EVENT Retrieving Item in Populate', { key: event.by });\n const [, newItem] = await cacheConfig.cache.operations.retrieve(event.by);\n if (newItem) {\n event.agg = newItem as Item;\n }\n }\n }\n\n const all = async (\n query: ItemQuery = {},\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = []\n ):\n Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V[]]> => {\n logger.default('all', { query, locations });\n const [cacheMap, items] = await cache.operations.all(query, locations);\n const populatedItems = await Promise.all(items.map(async (item) => populate(item)));\n return [cacheMap, populatedItems];\n }\n\n const one = async (\n query: ItemQuery = {},\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = []\n ):\n Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V | null]> => {\n logger.default('one', { query, locations });\n const [cacheMap, item] = await cache.operations.one(query, locations);\n let populatedItem = null;\n if (item) {\n populatedItem = await populate(item);\n }\n return [cacheMap, populatedItem];\n }\n\n const action = async (\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n action: string,\n body: any = {},\n ): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V]> => {\n logger.default('action', { key, action, body });\n const [cacheMap, item] = await cache.operations.action(key, action, body);\n const populatedItem = await populate(item);\n return [cacheMap, populatedItem];\n }\n\n const allAction = async (\n action: string,\n body: any = {},\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = []\n ): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V[]]> => {\n logger.default('action', { action, body, locations });\n const [cacheMap, items] = await cache.operations.allAction(action, body, locations);\n const populatedItems = await Promise.all(items.map(async (item: V) => populate(item)));\n return [cacheMap, populatedItems];\n }\n\n const allFacet = async (\n facet: string,\n params: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>> = {},\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = []\n ): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, any]> => {\n logger.default('allFacet', { facet, params, locations });\n const [cacheMap, response] = await cache.operations.allFacet(facet, params, locations);\n return [cacheMap, response];\n }\n\n const create = async (\n v: Partial<Item<S, L1, L2, L3, L4, L5>>,\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = []\n ): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V]> => {\n logger.default('create', { v, locations });\n const [cacheMap, item] = await cache.operations.create(v, locations);\n const populatedItem = await populate(item);\n return [cacheMap, populatedItem];\n }\n\n const get = async (\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n ): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V | null]> => {\n logger.default('get', { key });\n const [cacheMap, item] = await cache.operations.get(key);\n let populatedItem = null;\n if (item) {\n populatedItem = await populate(item);\n }\n return [cacheMap, populatedItem];\n }\n\n const retrieve = async (\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n ): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5> | null, V | null]> => {\n logger.default('retrieve', { key });\n const [cacheMap, item] = await cache.operations.retrieve(key);\n let populatedItem = null;\n if (item) {\n populatedItem = await populate(item);\n }\n return [cacheMap, populatedItem];\n }\n\n const remove = async (\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n ): Promise<CacheMap<V, S, L1, L2, L3, L4, L5>> => {\n logger.default('remove', { key });\n const cacheMap = await cache.operations.remove(key);\n return cacheMap;\n }\n\n const update = async (\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n v: Partial<Item<S, L1, L2, L3, L4, L5>>,\n ): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V]> => {\n logger.default('update', { key, v });\n const [cacheMap, item] = await cache.operations.update(key, v);\n const populatedItem = await populate(item);\n return [cacheMap, populatedItem];\n }\n\n // Facets are a pass-thru for aggregators\n const facet = async (\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n facet: string,\n ): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, any]> => {\n logger.default('facet', { key, facet });\n const [cacheMap, response] = await cache.operations.facet(key, facet);\n return [cacheMap, response];\n }\n\n const find = async (\n finder: string,\n finderParams: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>> = {},\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = []\n ): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V[]]> => {\n logger.default('find', { finder, finderParams, locations });\n const [cacheMap, items] = await cache.operations.find(finder, finderParams, locations);\n const populatedItems = await Promise.all(items.map(async (item: V) => populate(item)));\n return [cacheMap, populatedItems];\n }\n\n const findOne = async (\n finder: string,\n finderParams: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>> = {},\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = []\n ): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V]> => {\n logger.default('find', { finder, finderParams, locations });\n const [cacheMap, item] = await cache.operations.findOne(finder, finderParams, locations);\n const populatedItem = await populate(item);\n return [cacheMap, populatedItem];\n }\n\n const set = async (\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n v: Item<S, L1, L2, L3, L4, L5>\n ): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V]> => {\n logger.default('set', { key, v });\n\n // TODO: There should be some input validation here to ensure a valid item.\n const [cacheMap, item] = await cache.operations.set(key, v);\n const populatedItem = await populate(item);\n return [cacheMap, populatedItem];\n }\n\n const reset = async (): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>]> => {\n const cacheMap = await cache.operations.reset();\n return cacheMap;\n }\n\n return {\n // Cache properties\n coordinate: cache.coordinate,\n registry: cache.registry,\n api: cache.api,\n cacheMap: cache.cacheMap,\n operations: cache.operations,\n // Cache operations exposed directly\n all,\n one,\n action,\n allAction,\n allFacet,\n create,\n get,\n retrieve,\n remove,\n update,\n facet,\n find,\n findOne,\n reset,\n set,\n // Aggregator-specific operations\n populate,\n populateAggregate,\n populateEvent\n }\n}\n", "import {\n AllItemTypeArrays,\n ComKey,\n Dictionary,\n isComKey,\n isQueryMatch,\n Item,\n ItemQuery,\n LocKeyArray,\n PriKey\n} from \"@fjell/core\";\nimport LibLogger from \"./logger\";\n\nconst logger = LibLogger.get(\"CacheMap\");\n\n// Normalize a key value to string for consistent comparison and hashing\nconst normalizeKeyValue = (value: string | number): string => {\n return String(value);\n};\n\n// Normalized hash function for Dictionary that converts pk/lk values to strings\nconst createNormalizedHashFunction = <T>() => {\n return (key: T): string => {\n if (typeof key === 'object' && key !== null) {\n // Create a normalized version of the key with string values\n const normalizedKey = JSON.parse(JSON.stringify(key));\n\n // Normalize pk values\n if ('pk' in normalizedKey && normalizedKey.pk !== null) {\n normalizedKey.pk = normalizeKeyValue(normalizedKey.pk);\n }\n\n // Normalize lk values\n if ('lk' in normalizedKey && normalizedKey.lk !== null) {\n normalizedKey.lk = normalizeKeyValue(normalizedKey.lk);\n }\n\n // Normalize loc array lk values\n if ('loc' in normalizedKey && Array.isArray(normalizedKey.loc)) {\n normalizedKey.loc = normalizedKey.loc.map((locItem: any) => {\n if (locItem && 'lk' in locItem && locItem.lk !== null) {\n return { ...locItem, lk: normalizeKeyValue(locItem.lk) };\n }\n return locItem;\n });\n }\n\n return JSON.stringify(normalizedKey);\n }\n return JSON.stringify(key);\n };\n};\n\n// Helper function to normalize and compare location key arrays\nconst isLocKeyArrayEqual = (a: any[], b: any[]): boolean => {\n if (a.length !== b.length) {\n return false;\n }\n\n for (let i = 0; i < a.length; i++) {\n const normalizedA = normalizeLocKeyItem(a[i]);\n const normalizedB = normalizeLocKeyItem(b[i]);\n\n if (JSON.stringify(normalizedA) !== JSON.stringify(normalizedB)) {\n return false;\n }\n }\n\n return true;\n};\n\n// Helper function to normalize a location key item\nconst normalizeLocKeyItem = (item: any): any => {\n if (typeof item === 'object' && item !== null) {\n const normalized = { ...item };\n\n if ('lk' in normalized && normalized.lk !== null) {\n normalized.lk = normalizeKeyValue(normalized.lk);\n }\n\n return normalized;\n }\n\n return item;\n};\n\n// const isObj = (x: any) => typeof x === \"object\" && x !== null;\n\n// const intersection = (a: object, b: object): object => {\n// const result: { [key: string]: any } = {}\n\n// if (([a, b]).every(isObj)) {\n// Object.keys(a).forEach((key) => {\n// // @ts-ignore\n// const value = a[key]\n// // @ts-ignore\n// const other = b[key]\n\n// if (isObj(value)) {\n// result[key] = intersection(value, other)\n// } else if (value === other) {\n// result[key] = value\n// }\n// })\n// }\n\n// return result\n// }\n\n// const removeEmptyObjects = (obj: object): object => {\n// const result: { [key: string]: any } = {}\n\n// Object.keys(obj).forEach((key) => {\n// // @ts-ignore\n// const value = obj[key];\n\n// if (isObj(value)) {\n// const nested = removeEmptyObjects(value);\n\n// if (Object.keys(nested).length > 0) {\n// result[key] = nested\n// }\n// } else if (value !== null) {\n// result[key] = value\n// }\n// });\n\n// return result;\n// }\n\nexport class CacheMap<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n> extends Dictionary<ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>, V> {\n\n private types: AllItemTypeArrays<S, L1, L2, L3, L4, L5>;\n private normalizedHashFunction: (key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>) => string;\n\n public constructor(\n types: AllItemTypeArrays<S, L1, L2, L3, L4, L5>,\n map?: { [key: string]: V },\n ) {\n const hashFunc = createNormalizedHashFunction<ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>>();\n super(map, hashFunc);\n this.types = types;\n this.normalizedHashFunction = hashFunc;\n }\n\n public get(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n ): V | null {\n logger.trace('get', { key });\n const hashedKey = this.normalizedHashFunction(key);\n const entry = this.map[hashedKey];\n // Check if entry exists AND the normalized keys match\n return entry && this.normalizedHashFunction(entry.originalKey) === this.normalizedHashFunction(key) ? entry.value : null;\n }\n\n public includesKey(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): boolean {\n const hashedKey = this.normalizedHashFunction(key);\n const entry = this.map[hashedKey];\n return entry ? this.normalizedHashFunction(entry.originalKey) === this.normalizedHashFunction(key) : false;\n }\n\n public delete(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): void {\n logger.trace('delete', { key });\n const hashedKey = this.normalizedHashFunction(key);\n delete this.map[hashedKey];\n }\n\n public allIn(\n locations: LocKeyArray<L1, L2, L3, L4, L5> | []\n ): V[] {\n if (locations.length === 0) {\n logger.debug('Returning all items, LocKeys is empty');\n return this.values();\n } else {\n const locKeys: LocKeyArray<L1, L2, L3, L4, L5> | [] = locations;\n logger.debug('allIn', { locKeys, keys: this.keys().length });\n return this.keys()\n .filter((key) => key && isComKey(key))\n .filter((key) => {\n const ComKey = key as ComKey<S, L1, L2, L3, L4, L5>;\n logger.debug('Comparing Location Keys', {\n locKeys,\n ComKey,\n });\n return isLocKeyArrayEqual(locKeys, ComKey.loc);\n })\n .map((key) => this.get(key) as V);\n }\n }\n\n // TODO: Can we do case insensitive matching?\n public contains(query: ItemQuery, locations: LocKeyArray<L1, L2, L3, L4, L5> | []): boolean {\n logger.debug('contains', { query, locations });\n const items = this.allIn(locations);\n\n return items.some((item) => isQueryMatch(item, query));\n }\n\n public queryIn(\n query: ItemQuery,\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = []\n ): V[] {\n logger.debug('queryIn', { query, locations });\n const items = this.allIn(locations);\n\n return items.filter((item) => isQueryMatch(item, query));\n }\n\n public clone(): CacheMap<V, S, L1, L2, L3, L4, L5> {\n const clone = new CacheMap<V, S, L1, L2, L3, L4, L5>(this.types);\n // Share the same underlying map reference (not a copy)\n clone.map = this.map;\n // Ensure the clone uses the same normalized hash function\n clone.normalizedHashFunction = this.normalizedHashFunction;\n return clone;\n }\n\n};\n", "import {\n Item,\n ItemQuery,\n LocKeyArray,\n validatePK\n} from \"@fjell/core\";\nimport { ClientApi } from \"@fjell/client-api\";\nimport { NotFoundError } from \"@fjell/http-api\";\nimport { CacheMap } from \"../CacheMap\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get('all');\n\nexport const all = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n api: ClientApi<V, S, L1, L2, L3, L4, L5>,\n cacheMap: CacheMap<V, S, L1, L2, L3, L4, L5>,\n pkType: S,\n query: ItemQuery = {},\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = []\n): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V[]]> => {\n logger.default('all', { query, locations });\n let ret: V[] = [];\n try {\n ret = await api.all(query, locations);\n ret.forEach((v) => {\n cacheMap.set(v.key, v);\n });\n } catch (e: unknown) {\n if (e instanceof NotFoundError) {\n // Handle not found gracefully\n } else {\n throw e;\n }\n }\n return [cacheMap, validatePK(ret, pkType) as V[]];\n};\n", "import {\n Item,\n ItemQuery,\n LocKeyArray,\n validatePK\n} from \"@fjell/core\";\nimport { ClientApi } from \"@fjell/client-api\";\nimport { NotFoundError } from \"@fjell/http-api\";\nimport { CacheMap } from \"../CacheMap\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get('one');\n\nexport const one = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n api: ClientApi<V, S, L1, L2, L3, L4, L5>,\n cacheMap: CacheMap<V, S, L1, L2, L3, L4, L5>,\n pkType: S,\n query: ItemQuery = {},\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = []\n): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V | null]> => {\n logger.default('one', { query, locations });\n\n let retItem: V | null = null;\n try {\n retItem = await api.one(query, locations);\n if (retItem) {\n cacheMap.set(retItem.key, retItem);\n }\n } catch (e: unknown) {\n if (e instanceof NotFoundError) {\n // Handle not found gracefully\n } else {\n throw e;\n }\n }\n return [\n cacheMap,\n retItem ?\n validatePK(retItem, pkType) as V :\n null\n ];\n};\n", "import {\n Item,\n LocKeyArray,\n validatePK\n} from \"@fjell/core\";\nimport { ClientApi } from \"@fjell/client-api\";\nimport { CacheMap } from \"../CacheMap\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get('create');\n\nexport const create = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n api: ClientApi<V, S, L1, L2, L3, L4, L5>,\n cacheMap: CacheMap<V, S, L1, L2, L3, L4, L5>,\n pkType: S,\n v: Partial<Item<S, L1, L2, L3, L4, L5>>,\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = []\n): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V]> => {\n logger.default('create', { v, locations });\n const created = await api.create(v, locations);\n cacheMap.set(created.key, created);\n return [cacheMap, validatePK(created, pkType) as V];\n};\n", "import {\n ComKey,\n isValidItemKey,\n Item,\n PriKey,\n validatePK\n} from \"@fjell/core\";\nimport { ClientApi } from \"@fjell/client-api\";\nimport { CacheMap } from \"../CacheMap\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get('get');\n\nexport const get = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n api: ClientApi<V, S, L1, L2, L3, L4, L5>,\n cacheMap: CacheMap<V, S, L1, L2, L3, L4, L5>,\n pkType: S,\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>\n): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V | null]> => {\n logger.default('get', { key });\n\n if (!isValidItemKey(key)) {\n logger.error('Key for Get is not a valid ItemKey: %j', key);\n throw new Error('Key for Get is not a valid ItemKey');\n }\n\n let ret: V | null;\n try {\n ret = await api.get(key);\n if (ret) {\n cacheMap.set(ret.key, ret);\n }\n } catch (e: any) {\n logger.error(\"Error getting item for key\", { key, message: e.message, stack: e.stack });\n throw e;\n }\n\n return [\n cacheMap,\n ret ?\n validatePK(ret, pkType) as V :\n null\n ];\n};\n", "import {\n ComKey,\n isValidItemKey,\n Item,\n PriKey,\n validatePK\n} from \"@fjell/core\";\nimport { CacheMap } from \"../CacheMap\";\nimport LibLogger from \"../logger\";\nimport { get } from \"./get\";\nimport { ClientApi } from \"@fjell/client-api\";\n\nconst logger = LibLogger.get('retrieve');\n\nexport const retrieve = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n api: ClientApi<V, S, L1, L2, L3, L4, L5>,\n cacheMap: CacheMap<V, S, L1, L2, L3, L4, L5>,\n pkType: S,\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>\n): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5> | null, V | null]> => {\n logger.default('retrieve', { key });\n\n if (!isValidItemKey(key)) {\n logger.error('Key for Retrieve is not a valid ItemKey: %j', key);\n throw new Error('Key for Retrieve is not a valid ItemKey');\n }\n\n const containsItemKey = cacheMap.includesKey(key);\n\n let retrieved: V | null;\n if (containsItemKey) {\n logger.default('Looking for Object in Cache', key);\n retrieved = cacheMap.get(key);\n } else {\n logger.default('Object Not Found in Cache, Retrieving from Server API', { key });\n [, retrieved] = await get(api, cacheMap, pkType, key);\n }\n\n const retValue: [CacheMap<V, S, L1, L2, L3, L4, L5> | null, V | null] = [\n containsItemKey ? null : cacheMap,\n retrieved ?\n validatePK(retrieved, pkType) as V :\n null\n ];\n\n return retValue;\n};\n", "import {\n ComKey,\n isValidItemKey,\n Item,\n PriKey\n} from \"@fjell/core\";\nimport { ClientApi } from \"@fjell/client-api\";\nimport { CacheMap } from \"../CacheMap\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get('remove');\n\nexport const remove = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n api: ClientApi<V, S, L1, L2, L3, L4, L5>,\n cacheMap: CacheMap<V, S, L1, L2, L3, L4, L5>,\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>\n): Promise<CacheMap<V, S, L1, L2, L3, L4, L5>> => {\n logger.default('remove', { key });\n\n if (!isValidItemKey(key)) {\n logger.error('Key for Remove is not a valid ItemKey: %j', key);\n throw new Error('Key for Remove is not a valid ItemKey');\n }\n\n try {\n await api.remove(key);\n cacheMap.delete(key);\n } catch (e) {\n logger.error(\"Error deleting item\", { error: e });\n throw e;\n }\n\n return cacheMap;\n};\n", "import {\n ComKey,\n isValidItemKey,\n Item,\n PriKey,\n validatePK\n} from \"@fjell/core\";\nimport { ClientApi } from \"@fjell/client-api\";\nimport { CacheMap } from \"../CacheMap\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get('update');\n\nexport const update = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n api: ClientApi<V, S, L1, L2, L3, L4, L5>,\n cacheMap: CacheMap<V, S, L1, L2, L3, L4, L5>,\n pkType: S,\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n v: Partial<Item<S, L1, L2, L3, L4, L5>>\n): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V]> => {\n logger.default('update', { key, v });\n\n if (!isValidItemKey(key)) {\n logger.error('Key for Update is not a valid ItemKey: %j', key);\n throw new Error('Key for Update is not a valid ItemKey');\n }\n\n try {\n const updated = await api.update(key, v);\n cacheMap.set(updated.key, updated);\n return [cacheMap, validatePK(updated, pkType) as V];\n } catch (e) {\n logger.error(\"Error updating item\", { error: e });\n throw e;\n }\n};\n", "import {\n ComKey,\n isValidItemKey,\n Item,\n PriKey,\n validatePK\n} from \"@fjell/core\";\nimport { ClientApi } from \"@fjell/client-api\";\nimport { CacheMap } from \"../CacheMap\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get('action');\n\nexport const action = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n api: ClientApi<V, S, L1, L2, L3, L4, L5>,\n cacheMap: CacheMap<V, S, L1, L2, L3, L4, L5>,\n pkType: S,\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n action: string,\n body: any = {}\n): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V]> => {\n logger.default('action', { key, action, body });\n\n if (!isValidItemKey(key)) {\n logger.error('Key for Action is not a valid ItemKey: %j', key);\n throw new Error('Key for Action is not a valid ItemKey');\n }\n\n const updated = await api.action(key, action, body);\n cacheMap.set(updated.key, updated);\n return [cacheMap, validatePK(updated, pkType) as V];\n};\n", "import {\n Item,\n LocKeyArray,\n validatePK\n} from \"@fjell/core\";\nimport { ClientApi } from \"@fjell/client-api\";\nimport { NotFoundError } from \"@fjell/http-api\";\nimport { CacheMap } from \"../CacheMap\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get('allAction');\n\nexport const allAction = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n api: ClientApi<V, S, L1, L2, L3, L4, L5>,\n cacheMap: CacheMap<V, S, L1, L2, L3, L4, L5>,\n pkType: S,\n action: string,\n body: any = {},\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = []\n): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V[]]> => {\n logger.default('allAction', { action, body, locations });\n let ret: V[] = [];\n try {\n ret = await api.allAction(action, body, locations);\n ret.forEach((v) => {\n cacheMap.set(v.key, v);\n });\n } catch (e: unknown) {\n // istanbul ignore next\n if (e instanceof NotFoundError) {\n // Handle not found gracefully\n } else {\n throw e;\n }\n }\n return [cacheMap, validatePK(ret, pkType) as V[]];\n};\n", "import {\n ComKey,\n Item,\n PriKey\n} from \"@fjell/core\";\nimport { ClientApi } from \"@fjell/client-api\";\nimport { CacheMap } from \"../CacheMap\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get('facet');\n\nexport const facet = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n api: ClientApi<V, S, L1, L2, L3, L4, L5>,\n cacheMap: CacheMap<V, S, L1, L2, L3, L4, L5>,\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n facet: string,\n params: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>> = {}\n): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, any]> => {\n logger.default('facet', { key, facet });\n const ret = await api.facet(key, facet, params);\n return [cacheMap, ret];\n};\n", "import {\n Item,\n LocKeyArray\n} from \"@fjell/core\";\nimport { ClientApi } from \"@fjell/client-api\";\nimport { CacheMap } from \"../CacheMap\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get('allFacet');\n\nexport const allFacet = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n api: ClientApi<V, S, L1, L2, L3, L4, L5>,\n cacheMap: CacheMap<V, S, L1, L2, L3, L4, L5>,\n facet: string,\n params: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>> = {},\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = []\n): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, any]> => {\n logger.default('allFacet', { facet, params, locations });\n const ret = await api.allFacet(facet, params, locations);\n return [cacheMap, ret];\n};\n", "import {\n Item,\n LocKeyArray,\n validatePK\n} from \"@fjell/core\";\nimport { ClientApi } from \"@fjell/client-api\";\nimport { CacheMap } from \"../CacheMap\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get('find');\n\nexport const find = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n api: ClientApi<V, S, L1, L2, L3, L4, L5>,\n cacheMap: CacheMap<V, S, L1, L2, L3, L4, L5>,\n pkType: S,\n finder: string,\n params: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>> = {},\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = []\n): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V[]]> => {\n logger.default('find', { finder, params, locations });\n const ret: V[] = await api.find(finder, params, locations);\n ret.forEach((v) => {\n cacheMap.set(v.key, v);\n });\n return [cacheMap, validatePK(ret, pkType) as V[]];\n};\n", "import {\n Item,\n LocKeyArray,\n validatePK\n} from \"@fjell/core\";\nimport { ClientApi } from \"@fjell/client-api\";\nimport { CacheMap } from \"../CacheMap\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get('findOne');\n\nexport const findOne = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n api: ClientApi<V, S, L1, L2, L3, L4, L5>,\n cacheMap: CacheMap<V, S, L1, L2, L3, L4, L5>,\n pkType: S,\n finder: string,\n finderParams: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>> = {},\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = []\n): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V]> => {\n logger.default('findOne', { finder, finderParams, locations });\n const ret = await api.findOne(finder, finderParams, locations);\n cacheMap.set(ret.key, ret);\n return [cacheMap, validatePK(ret, pkType) as V];\n};\n", "import {\n ComKey,\n isItemKeyEqual,\n isValidItemKey,\n Item,\n PriKey,\n validatePK\n} from \"@fjell/core\";\nimport { CacheMap } from \"../CacheMap\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get('set');\n\n// Normalize a key value to string for consistent comparison\nconst normalizeKeyValue = (value: string | number): string => {\n return String(value);\n};\n\n// Normalized key comparison function that handles string/number differences\nconst isItemKeyEqualNormalized = <\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(a: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>, b: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): boolean => {\n // For now, just normalize the keys to strings and use the original comparison\n const normalizedA = normalizeKey(a);\n const normalizedB = normalizeKey(b);\n return isItemKeyEqual(normalizedA as ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>, normalizedB as ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>);\n};\n\n// Helper function to normalize a key\nconst normalizeKey = (key: any): any => {\n if (typeof key === 'object' && key !== null) {\n const normalizedKey = JSON.parse(JSON.stringify(key));\n\n // Normalize pk values\n if ('pk' in normalizedKey && normalizedKey.pk !== null) {\n normalizedKey.pk = normalizeKeyValue(normalizedKey.pk);\n }\n\n // Normalize lk values\n if ('lk' in normalizedKey && normalizedKey.lk !== null) {\n normalizedKey.lk = normalizeKeyValue(normalizedKey.lk);\n }\n\n // Normalize loc array lk values\n if ('loc' in normalizedKey && Array.isArray(normalizedKey.loc)) {\n normalizedKey.loc = normalizedKey.loc.map((locItem: any) => {\n if (locItem && 'lk' in locItem && locItem.lk !== null) {\n return { ...locItem, lk: normalizeKeyValue(locItem.lk) };\n }\n return locItem;\n });\n }\n\n return normalizedKey;\n }\n return key;\n};\n\nexport const set = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n cacheMap: CacheMap<V, S, L1, L2, L3, L4, L5>,\n pkType: S,\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n v: Item<S, L1, L2, L3, L4, L5>\n): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V]> => {\n logger.default('set', { key, v });\n\n if (!isValidItemKey(key)) {\n logger.error('Key for Set is not a valid ItemKey: %j', key);\n throw new Error('Key for Set is not a valid ItemKey');\n }\n\n // Validate the item's primary key\n validatePK(v, pkType);\n\n if (!isItemKeyEqualNormalized(key, v.key)) {\n logger.error('Key does not match item key: %j != %j', key, v.key);\n throw new Error('Key does not match item key');\n }\n\n cacheMap.set(key, v as V);\n return [cacheMap, validatePK(v, pkType) as V];\n};\n", "import {\n Item\n} from \"@fjell/core\";\nimport { CacheMap } from \"../CacheMap\";\nimport { Coordinate } from \"@fjell/registry\";\n\nexport const reset = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n coordinate: Coordinate<S, L1, L2, L3, L4, L5>\n): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>]> => {\n const cacheMap = new CacheMap<V, S, L1, L2, L3, L4, L5>(coordinate.kta);\n return [cacheMap];\n};\n", "import { ComKey, Item, ItemQuery, LocKeyArray, PriKey } from \"@fjell/core\";\nimport { ClientApi } from \"@fjell/client-api\";\nimport { Coordinate } from \"@fjell/registry\";\nimport { CacheMap } from \"./CacheMap\";\n\n// Import all operation functions\nimport { all } from \"./ops/all\";\nimport { one } from \"./ops/one\";\nimport { create } from \"./ops/create\";\nimport { get } from \"./ops/get\";\nimport { retrieve } from \"./ops/retrieve\";\nimport { remove } from \"./ops/remove\";\nimport { update } from \"./ops/update\";\nimport { action } from \"./ops/action\";\nimport { allAction } from \"./ops/allAction\";\nimport { facet } from \"./ops/facet\";\nimport { allFacet } from \"./ops/allFacet\";\nimport { find } from \"./ops/find\";\nimport { findOne } from \"./ops/findOne\";\nimport { set } from \"./ops/set\";\nimport { reset } from \"./ops/reset\";\n\nexport interface Operations<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never,\n> {\n\n /**\n * Retrieves all the items that match the query from cache or API.\n * Items are cached automatically after retrieval.\n */\n all(\n query?: ItemQuery,\n locations?: LocKeyArray<L1, L2, L3, L4, L5> | []\n ): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V[]]>;\n\n /**\n * Retrieves the first item that matches the query from cache or API.\n * Item is cached automatically after retrieval.\n */\n one(\n query?: ItemQuery,\n locations?: LocKeyArray<L1, L2, L3, L4, L5> | []\n ): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V | null]>;\n\n /**\n * Creates a new item via API and caches it.\n */\n create(\n item: Partial<Item<S, L1, L2, L3, L4, L5>>,\n locations?: LocKeyArray<L1, L2, L3, L4, L5> | []\n ): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V]>;\n\n /**\n * Gets an item by key from cache or API and caches it.\n */\n get(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>\n ): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V | null]>;\n\n /**\n * Retrieves an item from cache if available, otherwise from API.\n * Returns null as first element if item was already in cache.\n */\n retrieve(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>\n ): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5> | null, V | null]>;\n\n /**\n * Removes an item via API and from cache.\n */\n remove(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>\n ): Promise<CacheMap<V, S, L1, L2, L3, L4, L5>>;\n\n /**\n * Updates an item via API and caches the result.\n */\n update(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n item: Partial<Item<S, L1, L2, L3, L4, L5>>\n ): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V]>;\n\n /**\n * Executes an action on an item via API and caches the result.\n */\n action(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n action: string,\n body?: any\n ): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V]>;\n\n /**\n * Executes an action on all items matching criteria via API and caches results.\n */\n allAction(\n action: string,\n body?: any,\n locations?: LocKeyArray<L1, L2, L3, L4, L5> | []\n ): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V[]]>;\n\n /**\n * Executes a facet query on an item via API (pass-through, no caching).\n */\n facet(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n facet: string,\n params?: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>\n ): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, any]>;\n\n /**\n * Executes a facet query on all items matching criteria via API (pass-through, no caching).\n */\n allFacet(\n facet: string,\n params?: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n locations?: LocKeyArray<L1, L2, L3, L4, L5> | []\n ): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, any]>;\n\n /**\n * Finds items using a finder method via API and caches results.\n */\n find(\n finder: string,\n params?: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n locations?: LocKeyArray<L1, L2, L3, L4, L5> | []\n ): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V[]]>;\n\n /**\n * Finds a single item using a finder method via API and caches result.\n */\n findOne(\n finder: string,\n params?: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n locations?: LocKeyArray<L1, L2, L3, L4, L5> | []\n ): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V]>;\n\n /**\n * Sets an item directly in cache without API call.\n */\n set(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n item: Item<S, L1, L2, L3, L4, L5>\n ): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>, V]>;\n\n /**\n * Resets the cache, clearing all cached items.\n */\n reset(): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>]>;\n}\n\nexport const createOperations = <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n api: ClientApi<V, S, L1, L2, L3, L4, L5>,\n coordinate: Coordinate<S, L1, L2, L3, L4, L5>,\n cacheMap: CacheMap<V, S, L1, L2, L3, L4, L5>,\n pkType: S\n ): Operations<V, S, L1, L2, L3, L4, L5> => {\n return {\n all: (query, locations) => all(api, cacheMap, pkType, query, locations),\n one: (query, locations) => one(api, cacheMap, pkType, query, locations),\n create: (item, locations) => create(api, cacheMap, pkType, item, locations),\n get: (key) => get(api, cacheMap, pkType, key),\n retrieve: (key) => retrieve(api, cacheMap, pkType, key),\n remove: (key) => remove(api, cacheMap, key),\n update: (key, item) => update(api, cacheMap, pkType, key, item),\n action: (key, actionName, body) => action(api, cacheMap, pkType, key, actionName, body),\n allAction: (actionName, body, locations) => allAction(api, cacheMap, pkType, actionName, body, locations),\n facet: (key, facetName, params) => facet(api, cacheMap, key, facetName, params),\n allFacet: (facetName, params, locations) => allFacet(api, cacheMap, facetName, params, locations),\n find: (finder, params, locations) => find(api, cacheMap, pkType, finder, params, locations),\n findOne: (finder, params, locations) => findOne(api, cacheMap, pkType, finder, params, locations),\n set: (key, item) => set(cacheMap, pkType, key, item),\n reset: () => reset(coordinate)\n };\n};\n", "import { Item } from \"@fjell/core\";\nimport { Instance as BaseInstance, Coordinate, Registry } from \"@fjell/registry\";\nimport { ClientApi } from \"@fjell/client-api\";\nimport { CacheMap } from \"./CacheMap\";\nimport { createOperations, Operations } from \"./Operations\";\nimport LibLogger from \"./logger\";\n\nconst logger = LibLogger.get('Cache');\n\n/**\n * The Cache interface extends the base Instance from @fjell/registry and adds cache operations\n * for interacting with cached data.\n *\n * The interface extends the base Instance (which provides coordinate and registry) with:\n * - api: Provides methods for interacting with server API\n * - cacheMap: Local cache storage for items\n * - operations: All cache operations (get, set, all, etc.) that work with both cache and API\n *\n * @template V - The type of the data model item, extending Item\n * @template S - The string literal type representing the model's key type\n * @template L1-L5 - Optional string literal types for location hierarchy levels\n */\nexport interface Cache<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n> extends BaseInstance<S, L1, L2, L3, L4, L5> {\n /** The API client for interacting with server endpoints */\n api: ClientApi<V, S, L1, L2, L3, L4, L5>;\n\n /** The cache map that stores cached items */\n cacheMap: CacheMap<V, S, L1, L2, L3, L4, L5>;\n\n /** All cache operations that work with both cache and API */\n operations: Operations<V, S, L1, L2, L3, L4, L5>;\n}\n\nexport const createCache = <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n api: ClientApi<V, S, L1, L2, L3, L4, L5>,\n coordinate: Coordinate<S, L1, L2, L3, L4, L5>,\n registry: Registry\n ): Cache<V, S, L1, L2, L3, L4, L5> => {\n logger.debug('createCache', { coordinate, registry });\n\n // Create the cache map using the coordinate's key type array\n const cacheMap = new CacheMap<V, S, L1, L2, L3, L4, L5>(coordinate.kta);\n\n // Get the primary key type from the coordinate\n const pkType = coordinate.kta[0] as S;\n\n // Create operations\n const operations = createOperations(api, coordinate, cacheMap, pkType);\n\n return {\n coordinate,\n registry,\n api,\n cacheMap,\n operations\n };\n};\n\nexport const isCache = (cache: any): cache is Cache<any, any, any, any, any, any, any> => {\n return cache !== null &&\n typeof cache === 'object' &&\n 'coordinate' in cache &&\n 'registry' in cache &&\n 'api' in cache &&\n 'cacheMap' in cache &&\n 'operations' in cache;\n};\n", "\nimport LibLogger from \"./logger\";\nimport { Item } from \"@fjell/core\";\nimport { Coordinate, Registry } from \"@fjell/registry\";\nimport { ClientApi } from \"@fjell/client-api\";\nimport { Cache, createCache } from \"./Cache\";\n\nconst logger = LibLogger.get(\"Instance\");\n\n/**\n * The Cache Instance interface represents a cache model instance that extends the base Instance\n * from @fjell/registry and adds cache operations for interacting with cached data.\n *\n * This is an alias for the Cache interface since Cache now extends Instance directly.\n *\n * @template V - The type of the data model item, extending Item\n * @template S - The string literal type representing the model's key type\n * @template L1-L5 - Optional string literal types for location hierarchy levels\n */\nexport type Instance<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n> = Cache<V, S, L1, L2, L3, L4, L5>;\n\nexport const createInstance = <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n registry: Registry,\n coordinate: Coordinate<S, L1, L2, L3, L4, L5>,\n api: ClientApi<V, S, L1, L2, L3, L4, L5>,\n ): Instance<V, S, L1, L2, L3, L4, L5> => {\n logger.debug(\"createInstance\", { coordinate, api, registry });\n return createCache(api, coordinate, registry);\n}\n\nexport const isInstance = (instance: any): instance is Instance<any, any, any, any, any, any, any> => {\n return instance !== null &&\n typeof instance === 'object' &&\n 'coordinate' in instance &&\n 'registry' in instance &&\n 'api' in instance &&\n 'cacheMap' in instance &&\n 'operations' in instance;\n}\n", "import { Item } from \"@fjell/core\";\nimport { ClientApi } from \"@fjell/client-api\";\nimport { InstanceFactory as BaseInstanceFactory, Registry, RegistryHub } from \"@fjell/registry\";\nimport { Instance } from \"./Instance\";\nimport { Coordinate } from \"@fjell/registry\";\nimport { CacheMap } from \"./CacheMap\";\nimport { createOperations } from \"./Operations\";\nimport LibLogger from \"./logger\";\n\nconst logger = LibLogger.get(\"InstanceFactory\");\n\nexport type InstanceFactory<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n> = (\n api: ClientApi<V, S, L1, L2, L3, L4, L5>\n) => BaseInstanceFactory<S, L1, L2, L3, L4, L5>;\n\n/**\n * Factory function for creating cache instances\n */\nexport const createInstanceFactory = <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n api: ClientApi<V, S, L1, L2, L3, L4, L5>\n ): BaseInstanceFactory<S, L1, L2, L3, L4, L5> => {\n return (coordinate: Coordinate<S, L1, L2, L3, L4, L5>, context: { registry: Registry, registryHub?: RegistryHub }) => {\n logger.debug(\"Creating cache instance\", { coordinate, registry: context.registry, api });\n\n // Since InstanceFactory must be synchronous but our createInstance is async,\n // we need to create a special cache instance synchronously and defer the async initialization\n const cacheMap = new CacheMap<V, S, L1, L2, L3, L4, L5>(coordinate.kta);\n const pkType = coordinate.kta[0] as S;\n const operations = createOperations(api, coordinate, cacheMap, pkType);\n\n return {\n coordinate,\n registry: context.registry,\n api,\n cacheMap,\n operations\n } as Instance<V, S, L1, L2, L3, L4, L5>;\n };\n};\n", "import LibLogger from './logger';\nimport {\n Registry as BaseRegistry,\n createRegistry as createBaseRegistry,\n RegistryFactory,\n RegistryHub\n} from '@fjell/registry';\n\nconst logger = LibLogger.get(\"Registry\");\n\n/**\n * Extended Registry interface for cache-specific functionality\n */\nexport interface Registry extends BaseRegistry {\n type: 'cache';\n}\n\n/**\n * Factory function for creating cache registries\n */\nexport const createRegistryFactory = (): RegistryFactory => {\n return (type: string, registryHub?: RegistryHub): BaseRegistry => {\n if (type !== 'cache') {\n throw new Error(`Cache registry factory can only create 'cache' type registries, got: ${type}`);\n }\n\n logger.debug(\"Creating cache registry\", { type, registryHub });\n\n const baseRegistry = createBaseRegistry(type, registryHub);\n\n // Cast to Registry for type safety\n return baseRegistry as Registry;\n };\n};\n\n/**\n * Creates a new cache registry instance\n */\nexport const createRegistry = (registryHub?: RegistryHub): Registry => {\n const baseRegistry = createBaseRegistry('cache', registryHub);\n\n return {\n ...baseRegistry,\n } as Registry;\n};\n"],
|
|
5
|
-
"mappings": ";AAAA,OAAO,aAAa;AAEpB,IAAM,YAAY,QAAQ,UAAU,cAAc;AAElD,IAAO,iBAAQ;;;ACQf,IAAM,SAAS,eAAU,IAAI,gBAAgB;AAgGtC,IAAM,gBAAgB,CAQ3B,WAAuE;AACvE,MAAI;AACJ,MAAK,OAAuB,aAAa,QAAW;AAClD,kBAAc,EAAE,OAAO,QAAe,UAAU,MAAM;AAAA,EACxD,OAAO;AACL,kBAAc;AAAA,EAChB;AACA,SAAO;AACT;AAEO,IAAM,mBAAmB,OAS9B,OACA,EAAE,aAAa,CAAC,GAAG,SAAS,CAAC,EAAE,MAKmB;AAElD,QAAM,WAAW,OAAO,SAAwB;AAC9C,WAAO,QAAQ,YAAY,EAAE,KAAK,CAAC;AACnC,eAAW,OAAO,YAAY;AAC5B,YAAM,kBAAkB,KAAK,IAAI;AAAA,IACnC;AACA,eAAW,OAAO,QAAQ;AACxB,YAAM,cAAc,KAAK,IAAI;AAAA,IAC/B;AACA,WAAO,QAAQ,iBAAiB,EAAE,KAAK,CAAC;AACxC,WAAO;AAAA,EACT;AAEA,QAAM,oBAAoB,OAAO,KAAa,SAAY;AACxD,WAAO,QAAQ,0BAA0B,EAAE,IAAI,CAAC;AAChD,UAAM,cAAc,cAAc,WAAW,GAAG,CAAC;AACjD,QAAI,KAAK,SAAS,QAAW;AAC3B,UAAI,YAAY,aAAa,OAAO;AAClC,eAAO,MAAM,gDAAgD,KAAK,UAAU,IAAI,CAAC;AACjF,cAAM,IAAI,MAAM,gDAAgD,KAAK,UAAU,IAAI,CAAC;AAAA,MACtF,OAAO;AACL,YAAI,KAAK,UAAU,OAAO,UAAU,eAAe,KAAK,KAAK,QAAQ,GAAG,GAAG;AACzE,iBAAO,KAAK,OAAO,GAAG;AAAA,QACxB;AAAA,MACF;AAAA,IACF,WAAW,KAAK,KAAK,GAAG,MAAM,QAAW;AACvC,UAAI,YAAY,aAAa,OAAO;AAClC,eAAO,MAAM,6DACX,MAAM,MAAM,KAAK,UAAU,IAAI,CAAC;AAClC,cAAM,IAAI,MAAM,6DACd,MAAM,MAAM,KAAK,UAAU,IAAI,CAAC;AAAA,MACpC,OAAO;AACL,YAAI,KAAK,UAAU,OAAO,UAAU,eAAe,KAAK,KAAK,QAAQ,GAAG,GAAG;AACzE,iBAAO,KAAK,OAAO,GAAG;AAAA,QACxB;AAAA,MACF;AAAA,IACF,OAAO;AAEL,YAAM,MAAM,KAAK,KAAK,GAAG;AAEzB,aAAO,QAAQ,mCAAmC,EAAE,KAAK,IAAI,CAAC;AAC9D,YAAM,CAAC,EAAE,OAAO,IAAI,MAAM,YAAY,MAAM,WAAW,SAAS,GAAG;AACnE,UAAI,SAAS;AACX,YAAI,KAAK,SAAS,QAAW;AAC3B,eAAK,OAAO,CAAC;AAAA,QACf;AACA,aAAK,KAAK,GAAG,IAAI;AAAA,UACf,KAAK;AAAA,UACL,MAAM;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,QAAM,gBAAgB,OAAO,KAAa,SAAY;AACpD,WAAO,QAAQ,sBAAsB,EAAE,IAAI,CAAC;AAC5C,UAAM,cAAc,cAAc,OAAO,GAAG,CAAC;AAE7C,QAAI,KAAK,WAAW,QAAW;AAC7B,YAAM,IAAI,MAAM,+BAA+B,KAAK,UAAU,IAAI,CAAC;AAAA,IACrE,WAAW,KAAK,OAAO,GAAG,MAAM,QAAW;AACzC,UAAI,YAAY,aAAa,OAAO;AAClC,eAAO,MAAM,iDAAiD,MAAM,MAAM,KAAK,UAAU,IAAI,CAAC;AAC9F,cAAM,IAAI,MAAM,iDAAiD,MAAM,MAAM,KAAK,UAAU,IAAI,CAAC;AAAA,MACnG;AAAA,IACF,OAAO;AACL,YAAM,QAAQ,KAAK,OAAO,GAAG;AAE7B,UAAI,MAAM,OAAO,QAAW;AAC1B,eAAO;AAAA,UACL;AAAA,UAAqD,EAAE,OAAO,IAAI,KAAK,KAAK,UAAU,IAAI;AAAA,QAAC;AAC7F,cAAM,IAAI,MAAM,wDAAwD,KAAK,UAAU,EAAE,KAAK,MAAM,CAAC,CAAC;AAAA,MACxG;AAEA,aAAO,QAAQ,qCAAqC,EAAE,KAAK,MAAM,GAAG,CAAC;AACrE,YAAM,CAAC,EAAE,OAAO,IAAI,MAAM,YAAY,MAAM,WAAW,SAAS,MAAM,EAAE;AACxE,UAAI,SAAS;AACX,cAAM,MAAM;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAEA,QAAMA,OAAM,OACV,QAAmB,CAAC,GACpB,YAAkD,CAAC,MAEG;AACtD,WAAO,QAAQ,OAAO,EAAE,OAAO,UAAU,CAAC;AAC1C,UAAM,CAAC,UAAU,KAAK,IAAI,MAAM,MAAM,WAAW,IAAI,OAAO,SAAS;AACrE,UAAM,iBAAiB,MAAM,QAAQ,IAAI,MAAM,IAAI,OAAO,SAAS,SAAS,IAAI,CAAC,CAAC;AAClF,WAAO,CAAC,UAAU,cAAc;AAAA,EAClC;AAEA,QAAMC,OAAM,OACV,QAAmB,CAAC,GACpB,YAAkD,CAAC,MAEQ;AAC3D,WAAO,QAAQ,OAAO,EAAE,OAAO,UAAU,CAAC;AAC1C,UAAM,CAAC,UAAU,IAAI,IAAI,MAAM,MAAM,WAAW,IAAI,OAAO,SAAS;AACpE,QAAI,gBAAgB;AACpB,QAAI,MAAM;AACR,sBAAgB,MAAM,SAAS,IAAI;AAAA,IACrC;AACA,WAAO,CAAC,UAAU,aAAa;AAAA,EACjC;AAEA,QAAMC,UAAS,OACb,KACAA,SACA,OAAY,CAAC,MACwC;AACrD,WAAO,QAAQ,UAAU,EAAE,KAAK,QAAAA,SAAQ,KAAK,CAAC;AAC9C,UAAM,CAAC,UAAU,IAAI,IAAI,MAAM,MAAM,WAAW,OAAO,KAAKA,SAAQ,IAAI;AACxE,UAAM,gBAAgB,MAAM,SAAS,IAAI;AACzC,WAAO,CAAC,UAAU,aAAa;AAAA,EACjC;AAEA,QAAMC,aAAY,OAChBD,SACA,OAAY,CAAC,GACb,YAAkD,CAAC,MACI;AACvD,WAAO,QAAQ,UAAU,EAAE,QAAAA,SAAQ,MAAM,UAAU,CAAC;AACpD,UAAM,CAAC,UAAU,KAAK,IAAI,MAAM,MAAM,WAAW,UAAUA,SAAQ,MAAM,SAAS;AAClF,UAAM,iBAAiB,MAAM,QAAQ,IAAI,MAAM,IAAI,OAAO,SAAY,SAAS,IAAI,CAAC,CAAC;AACrF,WAAO,CAAC,UAAU,cAAc;AAAA,EAClC;AAEA,QAAME,YAAW,OACfC,QACA,SAAqG,CAAC,GACtG,YAAkD,CAAC,MACI;AACvD,WAAO,QAAQ,YAAY,EAAE,OAAAA,QAAO,QAAQ,UAAU,CAAC;AACvD,UAAM,CAAC,UAAU,QAAQ,IAAI,MAAM,MAAM,WAAW,SAASA,QAAO,QAAQ,SAAS;AACrF,WAAO,CAAC,UAAU,QAAQ;AAAA,EAC5B;AAEA,QAAMC,UAAS,OACb,GACA,YAAkD,CAAC,MACE;AACrD,WAAO,QAAQ,UAAU,EAAE,GAAG,UAAU,CAAC;AACzC,UAAM,CAAC,UAAU,IAAI,IAAI,MAAM,MAAM,WAAW,OAAO,GAAG,SAAS;AACnE,UAAM,gBAAgB,MAAM,SAAS,IAAI;AACzC,WAAO,CAAC,UAAU,aAAa;AAAA,EACjC;AAEA,QAAMC,OAAM,OACV,QAC4D;AAC5D,WAAO,QAAQ,OAAO,EAAE,IAAI,CAAC;AAC7B,UAAM,CAAC,UAAU,IAAI,IAAI,MAAM,MAAM,WAAW,IAAI,GAAG;AACvD,QAAI,gBAAgB;AACpB,QAAI,MAAM;AACR,sBAAgB,MAAM,SAAS,IAAI;AAAA,IACrC;AACA,WAAO,CAAC,UAAU,aAAa;AAAA,EACjC;AAEA,QAAMC,YAAW,OACf,QACmE;AACnE,WAAO,QAAQ,YAAY,EAAE,IAAI,CAAC;AAClC,UAAM,CAAC,UAAU,IAAI,IAAI,MAAM,MAAM,WAAW,SAAS,GAAG;AAC5D,QAAI,gBAAgB;AACpB,QAAI,MAAM;AACR,sBAAgB,MAAM,SAAS,IAAI;AAAA,IACrC;AACA,WAAO,CAAC,UAAU,aAAa;AAAA,EACjC;AAEA,QAAMC,UAAS,OACb,QACgD;AAChD,WAAO,QAAQ,UAAU,EAAE,IAAI,CAAC;AAChC,UAAM,WAAW,MAAM,MAAM,WAAW,OAAO,GAAG;AAClD,WAAO;AAAA,EACT;AAEA,QAAMC,UAAS,OACb,KACA,MACqD;AACrD,WAAO,QAAQ,UAAU,EAAE,KAAK,EAAE,CAAC;AACnC,UAAM,CAAC,UAAU,IAAI,IAAI,MAAM,MAAM,WAAW,OAAO,KAAK,CAAC;AAC7D,UAAM,gBAAgB,MAAM,SAAS,IAAI;AACzC,WAAO,CAAC,UAAU,aAAa;AAAA,EACjC;AAGA,QAAML,SAAQ,OACZ,KACAA,WACuD;AACvD,WAAO,QAAQ,SAAS,EAAE,KAAK,OAAAA,OAAM,CAAC;AACtC,UAAM,CAAC,UAAU,QAAQ,IAAI,MAAM,MAAM,WAAW,MAAM,KAAKA,MAAK;AACpE,WAAO,CAAC,UAAU,QAAQ;AAAA,EAC5B;AAEA,QAAMM,QAAO,OACX,QACA,eAA2G,CAAC,GAC5G,YAAkD,CAAC,MACI;AACvD,WAAO,QAAQ,QAAQ,EAAE,QAAQ,cAAc,UAAU,CAAC;AAC1D,UAAM,CAAC,UAAU,KAAK,IAAI,MAAM,MAAM,WAAW,KAAK,QAAQ,cAAc,SAAS;AACrF,UAAM,iBAAiB,MAAM,QAAQ,IAAI,MAAM,IAAI,OAAO,SAAY,SAAS,IAAI,CAAC,CAAC;AACrF,WAAO,CAAC,UAAU,cAAc;AAAA,EAClC;AAEA,QAAMC,WAAU,OACd,QACA,eAA2G,CAAC,GAC5G,YAAkD,CAAC,MACE;AACrD,WAAO,QAAQ,QAAQ,EAAE,QAAQ,cAAc,UAAU,CAAC;AAC1D,UAAM,CAAC,UAAU,IAAI,IAAI,MAAM,MAAM,WAAW,QAAQ,QAAQ,cAAc,SAAS;AACvF,UAAM,gBAAgB,MAAM,SAAS,IAAI;AACzC,WAAO,CAAC,UAAU,aAAa;AAAA,EACjC;AAEA,QAAMC,OAAM,OACV,KACA,MACqD;AACrD,WAAO,QAAQ,OAAO,EAAE,KAAK,EAAE,CAAC;AAGhC,UAAM,CAAC,UAAU,IAAI,IAAI,MAAM,MAAM,WAAW,IAAI,KAAK,CAAC;AAC1D,UAAM,gBAAgB,MAAM,SAAS,IAAI;AACzC,WAAO,CAAC,UAAU,aAAa;AAAA,EACjC;AAEA,QAAMC,SAAQ,YAA2D;AACvE,UAAM,WAAW,MAAM,MAAM,WAAW,MAAM;AAC9C,WAAO;AAAA,EACT;AAEA,SAAO;AAAA;AAAA,IAEL,YAAY,MAAM;AAAA,IAClB,UAAU,MAAM;AAAA,IAChB,KAAK,MAAM;AAAA,IACX,UAAU,MAAM;AAAA,IAChB,YAAY,MAAM;AAAA;AAAA,IAElB,KAAAd;AAAA,IACA,KAAAC;AAAA,IACA,QAAAC;AAAA,IACA,WAAAC;AAAA,IACA,UAAAC;AAAA,IACA,QAAAE;AAAA,IACA,KAAAC;AAAA,IACA,UAAAC;AAAA,IACA,QAAAC;AAAA,IACA,QAAAC;AAAA,IACA,OAAAL;AAAA,IACA,MAAAM;AAAA,IACA,SAAAC;AAAA,IACA,OAAAE;AAAA,IACA,KAAAD;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AC3ZA;AAAA,EAGE;AAAA,EACA;AAAA,EACA;AAAA,OAKK;AAGP,IAAME,UAAS,eAAU,IAAI,UAAU;AAGvC,IAAM,oBAAoB,CAAC,UAAmC;AAC5D,SAAO,OAAO,KAAK;AACrB;AAGA,IAAM,+BAA+B,MAAS;AAC5C,SAAO,CAAC,QAAmB;AACzB,QAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AAE3C,YAAM,gBAAgB,KAAK,MAAM,KAAK,UAAU,GAAG,CAAC;AAGpD,UAAI,QAAQ,iBAAiB,cAAc,OAAO,MAAM;AACtD,sBAAc,KAAK,kBAAkB,cAAc,EAAE;AAAA,MACvD;AAGA,UAAI,QAAQ,iBAAiB,cAAc,OAAO,MAAM;AACtD,sBAAc,KAAK,kBAAkB,cAAc,EAAE;AAAA,MACvD;AAGA,UAAI,SAAS,iBAAiB,MAAM,QAAQ,cAAc,GAAG,GAAG;AAC9D,sBAAc,MAAM,cAAc,IAAI,IAAI,CAAC,YAAiB;AAC1D,cAAI,WAAW,QAAQ,WAAW,QAAQ,OAAO,MAAM;AACrD,mBAAO,EAAE,GAAG,SAAS,IAAI,kBAAkB,QAAQ,EAAE,EAAE;AAAA,UACzD;AACA,iBAAO;AAAA,QACT,CAAC;AAAA,MACH;AAEA,aAAO,KAAK,UAAU,aAAa;AAAA,IACrC;AACA,WAAO,KAAK,UAAU,GAAG;AAAA,EAC3B;AACF;AAGA,IAAM,qBAAqB,CAAC,GAAU,MAAsB;AAC1D,MAAI,EAAE,WAAW,EAAE,QAAQ;AACzB,WAAO;AAAA,EACT;AAEA,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AACjC,UAAM,cAAc,oBAAoB,EAAE,CAAC,CAAC;AAC5C,UAAM,cAAc,oBAAoB,EAAE,CAAC,CAAC;AAE5C,QAAI,KAAK,UAAU,WAAW,MAAM,KAAK,UAAU,WAAW,GAAG;AAC/D,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAGA,IAAM,sBAAsB,CAAC,SAAmB;AAC9C,MAAI,OAAO,SAAS,YAAY,SAAS,MAAM;AAC7C,UAAM,aAAa,EAAE,GAAG,KAAK;AAE7B,QAAI,QAAQ,cAAc,WAAW,OAAO,MAAM;AAChD,iBAAW,KAAK,kBAAkB,WAAW,EAAE;AAAA,IACjD;AAEA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AA8CO,IAAM,WAAN,MAAM,kBAQH,WAAyD;AAAA,EAEzD;AAAA,EACA;AAAA,EAED,YACL,OACA,KACA;AACA,UAAM,WAAW,6BAAwE;AACzF,UAAM,KAAK,QAAQ;AACnB,SAAK,QAAQ;AACb,SAAK,yBAAyB;AAAA,EAChC;AAAA,EAEO,IACL,KACU;AACV,IAAAA,QAAO,MAAM,OAAO,EAAE,IAAI,CAAC;AAC3B,UAAM,YAAY,KAAK,uBAAuB,GAAG;AACjD,UAAM,QAAQ,KAAK,IAAI,SAAS;AAEhC,WAAO,SAAS,KAAK,uBAAuB,MAAM,WAAW,MAAM,KAAK,uBAAuB,GAAG,IAAI,MAAM,QAAQ;AAAA,EACtH;AAAA,EAEO,YAAY,KAAyD;AAC1E,UAAM,YAAY,KAAK,uBAAuB,GAAG;AACjD,UAAM,QAAQ,KAAK,IAAI,SAAS;AAChC,WAAO,QAAQ,KAAK,uBAAuB,MAAM,WAAW,MAAM,KAAK,uBAAuB,GAAG,IAAI;AAAA,EACvG;AAAA,EAEO,OAAO,KAAsD;AAClE,IAAAA,QAAO,MAAM,UAAU,EAAE,IAAI,CAAC;AAC9B,UAAM,YAAY,KAAK,uBAAuB,GAAG;AACjD,WAAO,KAAK,IAAI,SAAS;AAAA,EAC3B;AAAA,EAEO,MACL,WACK;AACL,QAAI,UAAU,WAAW,GAAG;AAC1B,MAAAA,QAAO,MAAM,uCAAuC;AACpD,aAAO,KAAK,OAAO;AAAA,IACrB,OAAO;AACL,YAAM,UAAgD;AACtD,MAAAA,QAAO,MAAM,SAAS,EAAE,SAAS,MAAM,KAAK,KAAK,EAAE,OAAO,CAAC;AAC3D,aAAO,KAAK,KAAK,EACd,OAAO,CAAC,QAAQ,OAAO,SAAS,GAAG,CAAC,EACpC,OAAO,CAAC,QAAQ;AACf,cAAMC,UAAS;AACf,QAAAD,QAAO,MAAM,2BAA2B;AAAA,UACtC;AAAA,UACA,QAAAC;AAAA,QACF,CAAC;AACD,eAAO,mBAAmB,SAASA,QAAO,GAAG;AAAA,MAC/C,CAAC,EACA,IAAI,CAAC,QAAQ,KAAK,IAAI,GAAG,CAAM;AAAA,IACpC;AAAA,EACF;AAAA;AAAA,EAGO,SAAS,OAAkB,WAA0D;AAC1F,IAAAD,QAAO,MAAM,YAAY,EAAE,OAAO,UAAU,CAAC;AAC7C,UAAM,QAAQ,KAAK,MAAM,SAAS;AAElC,WAAO,MAAM,KAAK,CAAC,SAAS,aAAa,MAAM,KAAK,CAAC;AAAA,EACvD;AAAA,EAEO,QACL,OACA,YAAkD,CAAC,GAC9C;AACL,IAAAA,QAAO,MAAM,WAAW,EAAE,OAAO,UAAU,CAAC;AAC5C,UAAM,QAAQ,KAAK,MAAM,SAAS;AAElC,WAAO,MAAM,OAAO,CAAC,SAAS,aAAa,MAAM,KAAK,CAAC;AAAA,EACzD;AAAA,EAEO,QAA4C;AACjD,UAAM,QAAQ,IAAI,UAAmC,KAAK,KAAK;AAE/D,UAAM,MAAM,KAAK;AAEjB,UAAM,yBAAyB,KAAK;AACpC,WAAO;AAAA,EACT;AAEF;;;ACjOA;AAAA,EAIE;AAAA,OACK;AAEP,SAAS,qBAAqB;AAI9B,IAAME,UAAS,eAAU,IAAI,KAAK;AAE3B,IAAM,MAAM,OASjB,KACA,UACA,QACA,QAAmB,CAAC,GACpB,YAAkD,CAAC,MACI;AACvD,EAAAA,QAAO,QAAQ,OAAO,EAAE,OAAO,UAAU,CAAC;AAC1C,MAAI,MAAW,CAAC;AAChB,MAAI;AACF,UAAM,MAAM,IAAI,IAAI,OAAO,SAAS;AACpC,QAAI,QAAQ,CAAC,MAAM;AACjB,eAAS,IAAI,EAAE,KAAK,CAAC;AAAA,IACvB,CAAC;AAAA,EACH,SAAS,GAAY;AACnB,QAAI,aAAa,eAAe;AAAA,IAEhC,OAAO;AACL,YAAM;AAAA,IACR;AAAA,EACF;AACA,SAAO,CAAC,UAAU,WAAW,KAAK,MAAM,CAAQ;AAClD;;;AC3CA;AAAA,EAIE,cAAAC;AAAA,OACK;AAEP,SAAS,iBAAAC,sBAAqB;AAI9B,IAAMC,UAAS,eAAU,IAAI,KAAK;AAE3B,IAAM,MAAM,OASjB,KACA,UACA,QACA,QAAmB,CAAC,GACpB,YAAkD,CAAC,MACS;AAC5D,EAAAA,QAAO,QAAQ,OAAO,EAAE,OAAO,UAAU,CAAC;AAE1C,MAAI,UAAoB;AACxB,MAAI;AACF,cAAU,MAAM,IAAI,IAAI,OAAO,SAAS;AACxC,QAAI,SAAS;AACX,eAAS,IAAI,QAAQ,KAAK,OAAO;AAAA,IACnC;AAAA,EACF,SAAS,GAAY;AACnB,QAAI,aAAaC,gBAAe;AAAA,IAEhC,OAAO;AACL,YAAM;AAAA,IACR;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA,UACEC,YAAW,SAAS,MAAM,IAC1B;AAAA,EACJ;AACF;;;ACjDA;AAAA,EAGE,cAAAC;AAAA,OACK;AAKP,IAAMC,UAAS,eAAU,IAAI,QAAQ;AAE9B,IAAM,SAAS,OASpB,KACA,UACA,QACA,GACA,YAAkD,CAAC,MACE;AACrD,EAAAA,QAAO,QAAQ,UAAU,EAAE,GAAG,UAAU,CAAC;AACzC,QAAM,UAAU,MAAM,IAAI,OAAO,GAAG,SAAS;AAC7C,WAAS,IAAI,QAAQ,KAAK,OAAO;AACjC,SAAO,CAAC,UAAUC,YAAW,SAAS,MAAM,CAAM;AACpD;;;AC9BA;AAAA,EAEE;AAAA,EAGA,cAAAC;AAAA,OACK;AAKP,IAAMC,UAAS,eAAU,IAAI,KAAK;AAE3B,IAAM,MAAM,OASjB,KACA,UACA,QACA,QAC4D;AAC5D,EAAAA,QAAO,QAAQ,OAAO,EAAE,IAAI,CAAC;AAE7B,MAAI,CAAC,eAAe,GAAG,GAAG;AACxB,IAAAA,QAAO,MAAM,0CAA0C,GAAG;AAC1D,UAAM,IAAI,MAAM,oCAAoC;AAAA,EACtD;AAEA,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,IAAI,IAAI,GAAG;AACvB,QAAI,KAAK;AACP,eAAS,IAAI,IAAI,KAAK,GAAG;AAAA,IAC3B;AAAA,EACF,SAAS,GAAQ;AACf,IAAAA,QAAO,MAAM,8BAA8B,EAAE,KAAK,SAAS,EAAE,SAAS,OAAO,EAAE,MAAM,CAAC;AACtF,UAAM;AAAA,EACR;AAEA,SAAO;AAAA,IACL;AAAA,IACA,MACEC,YAAW,KAAK,MAAM,IACtB;AAAA,EACJ;AACF;;;ACnDA;AAAA,EAEE,kBAAAC;AAAA,EAGA,cAAAC;AAAA,OACK;AAMP,IAAMC,UAAS,eAAU,IAAI,UAAU;AAEhC,IAAM,WAAW,OAStB,KACA,UACA,QACA,QACmE;AACnE,EAAAA,QAAO,QAAQ,YAAY,EAAE,IAAI,CAAC;AAElC,MAAI,CAACC,gBAAe,GAAG,GAAG;AACxB,IAAAD,QAAO,MAAM,+CAA+C,GAAG;AAC/D,UAAM,IAAI,MAAM,yCAAyC;AAAA,EAC3D;AAEA,QAAM,kBAAkB,SAAS,YAAY,GAAG;AAEhD,MAAI;AACJ,MAAI,iBAAiB;AACnB,IAAAA,QAAO,QAAQ,+BAA+B,GAAG;AACjD,gBAAY,SAAS,IAAI,GAAG;AAAA,EAC9B,OAAO;AACL,IAAAA,QAAO,QAAQ,yDAAyD,EAAE,IAAI,CAAC;AAC/E,KAAC,EAAE,SAAS,IAAI,MAAM,IAAI,KAAK,UAAU,QAAQ,GAAG;AAAA,EACtD;AAEA,QAAM,WAAkE;AAAA,IACtE,kBAAkB,OAAO;AAAA,IACzB,YACEE,YAAW,WAAW,MAAM,IAC5B;AAAA,EACJ;AAEA,SAAO;AACT;;;ACtDA;AAAA,EAEE,kBAAAC;AAAA,OAGK;AAKP,IAAMC,UAAS,eAAU,IAAI,QAAQ;AAE9B,IAAM,SAAS,OASpB,KACA,UACA,QACgD;AAChD,EAAAA,QAAO,QAAQ,UAAU,EAAE,IAAI,CAAC;AAEhC,MAAI,CAACC,gBAAe,GAAG,GAAG;AACxB,IAAAD,QAAO,MAAM,6CAA6C,GAAG;AAC7D,UAAM,IAAI,MAAM,uCAAuC;AAAA,EACzD;AAEA,MAAI;AACF,UAAM,IAAI,OAAO,GAAG;AACpB,aAAS,OAAO,GAAG;AAAA,EACrB,SAAS,GAAG;AACV,IAAAA,QAAO,MAAM,uBAAuB,EAAE,OAAO,EAAE,CAAC;AAChD,UAAM;AAAA,EACR;AAEA,SAAO;AACT;;;ACzCA;AAAA,EAEE,kBAAAE;AAAA,EAGA,cAAAC;AAAA,OACK;AAKP,IAAMC,UAAS,eAAU,IAAI,QAAQ;AAE9B,IAAM,SAAS,OASpB,KACA,UACA,QACA,KACA,MACqD;AACrD,EAAAA,QAAO,QAAQ,UAAU,EAAE,KAAK,EAAE,CAAC;AAEnC,MAAI,CAACC,gBAAe,GAAG,GAAG;AACxB,IAAAD,QAAO,MAAM,6CAA6C,GAAG;AAC7D,UAAM,IAAI,MAAM,uCAAuC;AAAA,EACzD;AAEA,MAAI;AACF,UAAM,UAAU,MAAM,IAAI,OAAO,KAAK,CAAC;AACvC,aAAS,IAAI,QAAQ,KAAK,OAAO;AACjC,WAAO,CAAC,UAAUE,YAAW,SAAS,MAAM,CAAM;AAAA,EACpD,SAAS,GAAG;AACV,IAAAF,QAAO,MAAM,uBAAuB,EAAE,OAAO,EAAE,CAAC;AAChD,UAAM;AAAA,EACR;AACF;;;AC3CA;AAAA,EAEE,kBAAAG;AAAA,EAGA,cAAAC;AAAA,OACK;AAKP,IAAMC,WAAS,eAAU,IAAI,QAAQ;AAE9B,IAAM,SAAS,OASpB,KACA,UACA,QACA,KACAC,SACA,OAAY,CAAC,MACwC;AACrD,EAAAD,SAAO,QAAQ,UAAU,EAAE,KAAK,QAAAC,SAAQ,KAAK,CAAC;AAE9C,MAAI,CAACC,gBAAe,GAAG,GAAG;AACxB,IAAAF,SAAO,MAAM,6CAA6C,GAAG;AAC7D,UAAM,IAAI,MAAM,uCAAuC;AAAA,EACzD;AAEA,QAAM,UAAU,MAAM,IAAI,OAAO,KAAKC,SAAQ,IAAI;AAClD,WAAS,IAAI,QAAQ,KAAK,OAAO;AACjC,SAAO,CAAC,UAAUE,YAAW,SAAS,MAAM,CAAM;AACpD;;;ACvCA;AAAA,EAGE,cAAAC;AAAA,OACK;AAEP,SAAS,iBAAAC,sBAAqB;AAI9B,IAAMC,WAAS,eAAU,IAAI,WAAW;AAEjC,IAAM,YAAY,OASvB,KACA,UACA,QACAC,SACA,OAAY,CAAC,GACb,YAAkD,CAAC,MACI;AACvD,EAAAD,SAAO,QAAQ,aAAa,EAAE,QAAAC,SAAQ,MAAM,UAAU,CAAC;AACvD,MAAI,MAAW,CAAC;AAChB,MAAI;AACF,UAAM,MAAM,IAAI,UAAUA,SAAQ,MAAM,SAAS;AACjD,QAAI,QAAQ,CAAC,MAAM;AACjB,eAAS,IAAI,EAAE,KAAK,CAAC;AAAA,IACvB,CAAC;AAAA,EACH,SAAS,GAAY;AAEnB,QAAI,aAAaC,gBAAe;AAAA,IAEhC,OAAO;AACL,YAAM;AAAA,IACR;AAAA,EACF;AACA,SAAO,CAAC,UAAUC,YAAW,KAAK,MAAM,CAAQ;AAClD;;;ACnCA,IAAMC,WAAS,eAAU,IAAI,OAAO;AAE7B,IAAM,QAAQ,OASnB,KACA,UACA,KACAC,QACA,SAAqG,CAAC,MAC/C;AACvD,EAAAD,SAAO,QAAQ,SAAS,EAAE,KAAK,OAAAC,OAAM,CAAC;AACtC,QAAM,MAAM,MAAM,IAAI,MAAM,KAAKA,QAAO,MAAM;AAC9C,SAAO,CAAC,UAAU,GAAG;AACvB;;;ACrBA,IAAMC,WAAS,eAAU,IAAI,UAAU;AAEhC,IAAM,WAAW,OAStB,KACA,UACAC,QACA,SAAqG,CAAC,GACtG,YAAkD,CAAC,MACI;AACvD,EAAAD,SAAO,QAAQ,YAAY,EAAE,OAAAC,QAAO,QAAQ,UAAU,CAAC;AACvD,QAAM,MAAM,MAAM,IAAI,SAASA,QAAO,QAAQ,SAAS;AACvD,SAAO,CAAC,UAAU,GAAG;AACvB;;;AC5BA;AAAA,EAGE,cAAAC;AAAA,OACK;AAKP,IAAMC,WAAS,eAAU,IAAI,MAAM;AAE5B,IAAM,OAAO,OASlB,KACA,UACA,QACA,QACA,SAAqG,CAAC,GACtG,YAAkD,CAAC,MACI;AACvD,EAAAA,SAAO,QAAQ,QAAQ,EAAE,QAAQ,QAAQ,UAAU,CAAC;AACpD,QAAM,MAAW,MAAM,IAAI,KAAK,QAAQ,QAAQ,SAAS;AACzD,MAAI,QAAQ,CAAC,MAAM;AACjB,aAAS,IAAI,EAAE,KAAK,CAAC;AAAA,EACvB,CAAC;AACD,SAAO,CAAC,UAAUC,YAAW,KAAK,MAAM,CAAQ;AAClD;;;ACjCA;AAAA,EAGE,cAAAC;AAAA,OACK;AAKP,IAAMC,WAAS,eAAU,IAAI,SAAS;AAE/B,IAAM,UAAU,OASrB,KACA,UACA,QACA,QACA,eAA2G,CAAC,GAC5G,YAAkD,CAAC,MACE;AACrD,EAAAA,SAAO,QAAQ,WAAW,EAAE,QAAQ,cAAc,UAAU,CAAC;AAC7D,QAAM,MAAM,MAAM,IAAI,QAAQ,QAAQ,cAAc,SAAS;AAC7D,WAAS,IAAI,IAAI,KAAK,GAAG;AACzB,SAAO,CAAC,UAAUC,aAAW,KAAK,MAAM,CAAM;AAChD;;;AC/BA;AAAA,EAEE;AAAA,EACA,kBAAAC;AAAA,EAGA,cAAAC;AAAA,OACK;AAIP,IAAMC,WAAS,eAAU,IAAI,KAAK;AAGlC,IAAMC,qBAAoB,CAAC,UAAmC;AAC5D,SAAO,OAAO,KAAK;AACrB;AAGA,IAAM,2BAA2B,CAO/B,GAA8C,MAA0D;AAExG,QAAM,cAAc,aAAa,CAAC;AAClC,QAAM,cAAc,aAAa,CAAC;AAClC,SAAO,eAAe,aAA0D,WAAwD;AAC1I;AAGA,IAAM,eAAe,CAAC,QAAkB;AACtC,MAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AAC3C,UAAM,gBAAgB,KAAK,MAAM,KAAK,UAAU,GAAG,CAAC;AAGpD,QAAI,QAAQ,iBAAiB,cAAc,OAAO,MAAM;AACtD,oBAAc,KAAKA,mBAAkB,cAAc,EAAE;AAAA,IACvD;AAGA,QAAI,QAAQ,iBAAiB,cAAc,OAAO,MAAM;AACtD,oBAAc,KAAKA,mBAAkB,cAAc,EAAE;AAAA,IACvD;AAGA,QAAI,SAAS,iBAAiB,MAAM,QAAQ,cAAc,GAAG,GAAG;AAC9D,oBAAc,MAAM,cAAc,IAAI,IAAI,CAAC,YAAiB;AAC1D,YAAI,WAAW,QAAQ,WAAW,QAAQ,OAAO,MAAM;AACrD,iBAAO,EAAE,GAAG,SAAS,IAAIA,mBAAkB,QAAQ,EAAE,EAAE;AAAA,QACzD;AACA,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEO,IAAM,MAAM,OASjB,UACA,QACA,KACA,MACqD;AACrD,EAAAD,SAAO,QAAQ,OAAO,EAAE,KAAK,EAAE,CAAC;AAEhC,MAAI,CAACE,gBAAe,GAAG,GAAG;AACxB,IAAAF,SAAO,MAAM,0CAA0C,GAAG;AAC1D,UAAM,IAAI,MAAM,oCAAoC;AAAA,EACtD;AAGA,EAAAG,aAAW,GAAG,MAAM;AAEpB,MAAI,CAAC,yBAAyB,KAAK,EAAE,GAAG,GAAG;AACzC,IAAAH,SAAO,MAAM,yCAAyC,KAAK,EAAE,GAAG;AAChE,UAAM,IAAI,MAAM,6BAA6B;AAAA,EAC/C;AAEA,WAAS,IAAI,KAAK,CAAM;AACxB,SAAO,CAAC,UAAUG,aAAW,GAAG,MAAM,CAAM;AAC9C;;;ACxFO,IAAM,QAAQ,OASnB,eACkD;AAClD,QAAM,WAAW,IAAI,SAAmC,WAAW,GAAG;AACtE,SAAO,CAAC,QAAQ;AAClB;;;ACyIO,IAAM,mBAAmB,CAS5B,KACA,YACA,UACA,WACyC;AAC3C,SAAO;AAAA,IACL,KAAK,CAAC,OAAO,cAAc,IAAI,KAAK,UAAU,QAAQ,OAAO,SAAS;AAAA,IACtE,KAAK,CAAC,OAAO,cAAc,IAAI,KAAK,UAAU,QAAQ,OAAO,SAAS;AAAA,IACtE,QAAQ,CAAC,MAAM,cAAc,OAAO,KAAK,UAAU,QAAQ,MAAM,SAAS;AAAA,IAC1E,KAAK,CAAC,QAAQ,IAAI,KAAK,UAAU,QAAQ,GAAG;AAAA,IAC5C,UAAU,CAAC,QAAQ,SAAS,KAAK,UAAU,QAAQ,GAAG;AAAA,IACtD,QAAQ,CAAC,QAAQ,OAAO,KAAK,UAAU,GAAG;AAAA,IAC1C,QAAQ,CAAC,KAAK,SAAS,OAAO,KAAK,UAAU,QAAQ,KAAK,IAAI;AAAA,IAC9D,QAAQ,CAAC,KAAK,YAAY,SAAS,OAAO,KAAK,UAAU,QAAQ,KAAK,YAAY,IAAI;AAAA,IACtF,WAAW,CAAC,YAAY,MAAM,cAAc,UAAU,KAAK,UAAU,QAAQ,YAAY,MAAM,SAAS;AAAA,IACxG,OAAO,CAAC,KAAK,WAAW,WAAW,MAAM,KAAK,UAAU,KAAK,WAAW,MAAM;AAAA,IAC9E,UAAU,CAAC,WAAW,QAAQ,cAAc,SAAS,KAAK,UAAU,WAAW,QAAQ,SAAS;AAAA,IAChG,MAAM,CAAC,QAAQ,QAAQ,cAAc,KAAK,KAAK,UAAU,QAAQ,QAAQ,QAAQ,SAAS;AAAA,IAC1F,SAAS,CAAC,QAAQ,QAAQ,cAAc,QAAQ,KAAK,UAAU,QAAQ,QAAQ,QAAQ,SAAS;AAAA,IAChG,KAAK,CAAC,KAAK,SAAS,IAAI,UAAU,QAAQ,KAAK,IAAI;AAAA,IACnD,OAAO,MAAM,MAAM,UAAU;AAAA,EAC/B;AACF;;;ACpLA,IAAMC,WAAS,eAAU,IAAI,OAAO;AAkC7B,IAAM,cAAc,CASvB,KACA,YACA,aACoC;AACtC,EAAAA,SAAO,MAAM,eAAe,EAAE,YAAY,SAAS,CAAC;AAGpD,QAAM,WAAW,IAAI,SAAmC,WAAW,GAAG;AAGtE,QAAM,SAAS,WAAW,IAAI,CAAC;AAG/B,QAAM,aAAa,iBAAiB,KAAK,YAAY,UAAU,MAAM;AAErE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,IAAM,UAAU,CAAC,UAAkE;AACxF,SAAO,UAAU,QACf,OAAO,UAAU,YACjB,gBAAgB,SAChB,cAAc,SACd,SAAS,SACT,cAAc,SACd,gBAAgB;AACpB;;;AC3EA,IAAMC,WAAS,eAAU,IAAI,UAAU;AAsBhC,IAAM,iBAAiB,CAS1B,UACA,YACA,QACuC;AACzC,EAAAA,SAAO,MAAM,kBAAkB,EAAE,YAAY,KAAK,SAAS,CAAC;AAC5D,SAAO,YAAY,KAAK,YAAY,QAAQ;AAC9C;AAEO,IAAM,aAAa,CAAC,aAA2E;AACpG,SAAO,aAAa,QAClB,OAAO,aAAa,YACpB,gBAAgB,YAChB,cAAc,YACd,SAAS,YACT,cAAc,YACd,gBAAgB;AACpB;;;AC7CA,IAAMC,WAAS,eAAU,IAAI,iBAAiB;AAiBvC,IAAM,wBAAwB,CASjC,QAC+C;AACjD,SAAO,CAAC,YAA+C,YAA+D;AACpH,IAAAA,SAAO,MAAM,2BAA2B,EAAE,YAAY,UAAU,QAAQ,UAAU,IAAI,CAAC;AAIvF,UAAM,WAAW,IAAI,SAAmC,WAAW,GAAG;AACtE,UAAM,SAAS,WAAW,IAAI,CAAC;AAC/B,UAAM,aAAa,iBAAiB,KAAK,YAAY,UAAU,MAAM;AAErE,WAAO;AAAA,MACL;AAAA,MACA,UAAU,QAAQ;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;;;ACrDA;AAAA,EAEE,kBAAkB;AAAA,OAGb;AAEP,IAAMC,WAAS,eAAU,IAAI,UAAU;AAYhC,IAAM,wBAAwB,MAAuB;AAC1D,SAAO,CAAC,MAAc,gBAA4C;AAChE,QAAI,SAAS,SAAS;AACpB,YAAM,IAAI,MAAM,wEAAwE,IAAI,EAAE;AAAA,IAChG;AAEA,IAAAA,SAAO,MAAM,2BAA2B,EAAE,MAAM,YAAY,CAAC;AAE7D,UAAM,eAAe,mBAAmB,MAAM,WAAW;AAGzD,WAAO;AAAA,EACT;AACF;AAKO,IAAM,iBAAiB,CAAC,gBAAwC;AACrE,QAAM,eAAe,mBAAmB,SAAS,WAAW;AAE5D,SAAO;AAAA,IACL,GAAG;AAAA,EACL;AACF;",
|
|
6
|
-
"names": ["
|
|
3
|
+
"sources": ["../src/CacheContext.ts", "../src/ops/all.ts", "../src/normalization.ts", "../src/events/CacheEventFactory.ts", "../src/logger.ts", "../src/ops/one.ts", "../src/ops/create.ts", "../src/ops/get.ts", "../src/utils/CacheSize.ts", "../src/ops/retrieve.ts", "../src/ops/remove.ts", "../src/ops/update.ts", "../src/ops/action.ts", "../src/ops/allAction.ts", "../src/ops/facet.ts", "../src/ops/allFacet.ts", "../src/ops/find.ts", "../src/ops/findOne.ts", "../src/ops/set.ts", "../src/memory/MemoryCacheMap.ts", "../src/CacheMap.ts", "../src/memory/EnhancedMemoryCacheMap.ts", "../src/browser/LocalStorageCacheMap.ts", "../src/browser/SessionStorageCacheMap.ts", "../src/browser/AsyncIndexDBCacheMap.ts", "../src/browser/IndexDBCacheMap.ts", "../src/Options.ts", "../src/ops/reset.ts", "../src/Operations.ts", "../src/eviction/EvictionManager.ts", "../src/eviction/EvictionStrategyConfig.ts", "../src/eviction/EvictionStrategy.ts", "../src/eviction/strategies/LRUEvictionStrategy.ts", "../src/eviction/EvictionStrategyValidation.ts", "../src/eviction/strategies/LFUEvictionStrategy.ts", "../src/eviction/strategies/FIFOEvictionStrategy.ts", "../src/eviction/strategies/MRUEvictionStrategy.ts", "../src/eviction/strategies/RandomEvictionStrategy.ts", "../src/eviction/strategies/ARCEvictionStrategy.ts", "../src/eviction/strategies/TwoQueueEvictionStrategy.ts", "../src/eviction/EvictionStrategyFactory.ts", "../src/ttl/TTLManager.ts", "../src/events/CacheEventEmitter.ts", "../src/CacheStats.ts", "../src/Cache.ts", "../src/InstanceFactory.ts", "../src/Instance.ts", "../src/Aggregator.ts", "../src/Registry.ts"],
|
|
4
|
+
"sourcesContent": ["import { Item } from \"@fjell/core\";\nimport { ClientApi } from \"@fjell/client-api\";\nimport { CacheMap } from \"./CacheMap\";\nimport { Options } from \"./Options\";\nimport { CacheEventEmitter } from \"./events/CacheEventEmitter\";\nimport { TTLManager } from \"./ttl/TTLManager\";\nimport { EvictionManager } from \"./eviction/EvictionManager\";\nimport { CacheStatsManager } from \"./CacheStats\";\n\n/**\n * Context object that consolidates all cache-related parameters\n * passed to cache operations. This prevents cache concerns from\n * polluting operation signatures.\n */\nexport interface CacheContext<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n> {\n /** The client API for making requests */\n api: ClientApi<V, S, L1, L2, L3, L4, L5>;\n\n /** The cache map for storing and retrieving cached items */\n cacheMap: CacheMap<V, S, L1, L2, L3, L4, L5>;\n\n /** The primary key type */\n pkType: S;\n\n /** Cache options including TTL configuration */\n options: Options<V, S, L1, L2, L3, L4, L5>;\n\n /** Event emitter for cache events */\n eventEmitter: CacheEventEmitter<V, S, L1, L2, L3, L4, L5>;\n\n /** TTL manager for handling time-to-live independently of storage */\n ttlManager: TTLManager;\n\n /** Eviction manager for handling cache eviction independently of storage */\n evictionManager: EvictionManager;\n\n /** Statistics manager for tracking cache metrics */\n statsManager: CacheStatsManager;\n}\n\n/**\n * Creates a CacheContext from the individual cache-related parameters\n */\nexport const createCacheContext = <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n api: ClientApi<V, S, L1, L2, L3, L4, L5>,\n cacheMap: CacheMap<V, S, L1, L2, L3, L4, L5>,\n pkType: S,\n options: Options<V, S, L1, L2, L3, L4, L5>,\n eventEmitter: CacheEventEmitter<V, S, L1, L2, L3, L4, L5>,\n ttlManager: TTLManager,\n evictionManager: EvictionManager,\n statsManager: CacheStatsManager\n ): CacheContext<V, S, L1, L2, L3, L4, L5> => {\n return {\n api,\n cacheMap,\n pkType,\n options,\n eventEmitter,\n ttlManager,\n evictionManager,\n statsManager\n };\n};\n", "import {\n Item,\n ItemQuery,\n LocKeyArray,\n validatePK\n} from \"@fjell/core\";\nimport { NotFoundError } from \"@fjell/http-api\";\nimport { CacheContext } from \"../CacheContext\";\nimport { createQueryHash } from \"../normalization\";\nimport { CacheEventFactory } from \"../events/CacheEventFactory\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get('all');\n\nexport const all = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n query: ItemQuery = {},\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = [],\n context: CacheContext<V, S, L1, L2, L3, L4, L5>\n): Promise<[CacheContext<V, S, L1, L2, L3, L4, L5>, V[]]> => {\n const { api, cacheMap, pkType, ttlManager } = context;\n logger.default('all', { query, locations });\n\n // Generate query hash for caching\n const queryHash = createQueryHash(pkType, query, locations);\n logger.debug('Generated query hash for all', { queryHash });\n\n // Check if we have cached query results\n const cachedItemKeys = await cacheMap.getQueryResult(queryHash);\n if (cachedItemKeys) {\n logger.debug('Using cached query results', { cachedKeyCount: cachedItemKeys.length });\n\n // Retrieve all cached items - if any are missing, invalidate the query cache\n const cachedItems: V[] = [];\n let allItemsAvailable = true;\n\n for (const itemKey of cachedItemKeys) {\n const item = await cacheMap.get(itemKey);\n if (item) {\n cachedItems.push(item);\n } else {\n allItemsAvailable = false;\n break;\n }\n }\n\n if (allItemsAvailable) {\n return [context, validatePK(cachedItems, pkType) as V[]];\n } else {\n logger.debug('Some cached items missing, invalidating query cache');\n cacheMap.deleteQueryResult(queryHash);\n }\n }\n\n // Fetch from API\n let ret: V[] = [];\n try {\n ret = await api.all(query, locations);\n\n // Store individual items in cache\n ret.forEach((v) => {\n cacheMap.set(v.key, v);\n\n // Set TTL metadata for the newly cached item\n const keyStr = JSON.stringify(v.key);\n ttlManager.onItemAdded(keyStr, cacheMap);\n\n // Handle eviction for the newly cached item\n const evictedKeys = context.evictionManager.onItemAdded(keyStr, v, cacheMap);\n // Remove evicted items from cache\n evictedKeys.forEach(evictedKey => {\n const parsedKey = JSON.parse(evictedKey);\n cacheMap.delete(parsedKey);\n });\n });\n\n // Store query result (item keys) in query cache\n const itemKeys = ret.map(item => item.key);\n cacheMap.setQueryResult(queryHash, itemKeys);\n logger.debug('Cached query result', { queryHash, itemKeyCount: itemKeys.length });\n\n // Emit query event\n const event = CacheEventFactory.createQueryEvent<V, S, L1, L2, L3, L4, L5>(query, locations, ret);\n context.eventEmitter.emit(event);\n\n } catch (e: unknown) {\n if (e instanceof NotFoundError) {\n // Handle not found gracefully - cache empty result\n cacheMap.setQueryResult(queryHash, []);\n logger.debug('Cached empty query result for not found', { queryHash });\n } else {\n throw e;\n }\n }\n return [context, validatePK(ret, pkType) as V[]];\n};\n", "// Normalization utilities for cache keys\nimport { ItemQuery, LocKeyArray } from \"@fjell/core\";\n\n// Normalize a key value to string for consistent comparison and hashing\nexport const normalizeKeyValue = (value: string | number): string => {\n return String(value);\n};\n\n// Helper function to create deterministic JSON string with sorted keys\nconst deterministicStringify = (obj: any): string => {\n if (obj === null || typeof obj !== 'object') {\n return JSON.stringify(obj);\n }\n\n if (Array.isArray(obj)) {\n return '[' + obj.map(deterministicStringify).join(',') + ']';\n }\n\n const sortedKeys = Object.keys(obj).sort();\n const keyValuePairs = sortedKeys.map(key => {\n return JSON.stringify(key) + ':' + deterministicStringify(obj[key]);\n });\n\n return '{' + keyValuePairs.join(',') + '}';\n};\n\n// Normalized hash function for Dictionary that converts pk/lk values to strings\nexport const createNormalizedHashFunction = <T>() => {\n return (key: T): string => {\n if (typeof key === 'object' && key !== null) {\n // Create a normalized version of the key with string values\n const normalizedKey = JSON.parse(JSON.stringify(key));\n\n // Normalize pk values\n if ('pk' in normalizedKey && normalizedKey.pk !== null) {\n normalizedKey.pk = normalizeKeyValue(normalizedKey.pk);\n }\n\n // Normalize lk values\n if ('lk' in normalizedKey && normalizedKey.lk !== null) {\n normalizedKey.lk = normalizeKeyValue(normalizedKey.lk);\n }\n\n // Normalize loc array lk values\n if ('loc' in normalizedKey && Array.isArray(normalizedKey.loc)) {\n normalizedKey.loc = normalizedKey.loc.map((locItem: any) => {\n if (typeof locItem === 'object' && locItem !== null && 'lk' in locItem && (locItem as any).lk !== null) {\n return { ...locItem, lk: normalizeKeyValue((locItem as any).lk) };\n }\n return locItem;\n });\n }\n\n // Use deterministic stringify to ensure consistent key ordering\n return deterministicStringify(normalizedKey);\n }\n return JSON.stringify(key);\n };\n};\n\n// Helper function to normalize and compare location key arrays\nexport const isLocKeyArrayEqual = (a: any[], b: any[]): boolean => {\n if (a.length !== b.length) {\n return false;\n }\n\n for (let i = 0; i < a.length; i++) {\n const normalizedA = normalizeLocKeyItem(a[i]);\n const normalizedB = normalizeLocKeyItem(b[i]);\n\n if (deterministicStringify(normalizedA) !== deterministicStringify(normalizedB)) {\n return false;\n }\n }\n\n return true;\n};\n\n// Helper function to normalize a location key item\nexport const normalizeLocKeyItem = (item: any): any => {\n if (typeof item === 'object' && item !== null) {\n const normalized = { ...item };\n\n if ('lk' in normalized && normalized.lk !== null) {\n normalized.lk = normalizeKeyValue(normalized.lk);\n }\n\n return normalized;\n }\n\n return item;\n};\n\n// Query result cache utilities\n\n/**\n * Interface for storing query results\n */\nexport interface QueryCacheEntry {\n itemKeys: (any)[];\n}\n\n/**\n * Generate a safe hash for all/one query parameters\n */\nexport const createQueryHash = <\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n pkType: S,\n query: ItemQuery,\n locations: LocKeyArray<L1, L2, L3, L4, L5> | []\n ): string => {\n // Normalize the query object for consistent ordering\n const normalizedQuery = JSON.parse(JSON.stringify(query || {}));\n\n // Sort keys to ensure consistent hash\n const sortedQueryKeys = Object.keys(normalizedQuery).sort();\n const sortedQuery: Record<string, any> = {};\n sortedQueryKeys.forEach(key => {\n sortedQuery[key] = normalizedQuery[key];\n });\n\n // Normalize locations using existing utility - ensure locations is an array\n const locationsArray = Array.isArray(locations) ? locations : [];\n const normalizedLocations = locationsArray.map(normalizeLocKeyItem);\n\n // Create the hash input object\n const hashInput = {\n type: 'query',\n pkType,\n query: sortedQuery,\n locations: normalizedLocations\n };\n\n return deterministicStringify(hashInput);\n};\n\n/**\n * Generate a safe hash for find/findOne query parameters\n */\nexport const createFinderHash = <\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n finder: string,\n params: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n locations: LocKeyArray<L1, L2, L3, L4, L5> | []\n ): string => {\n // Normalize the params object for consistent ordering\n const normalizedParams = JSON.parse(JSON.stringify(params || {}));\n\n // Sort keys to ensure consistent hash\n const sortedParamKeys = Object.keys(normalizedParams).sort();\n const sortedParams: Record<string, any> = {};\n sortedParamKeys.forEach(key => {\n sortedParams[key] = normalizedParams[key];\n });\n\n // Normalize locations using existing utility - ensure locations is an array\n const locationsArray = Array.isArray(locations) ? locations : [];\n const normalizedLocations = locationsArray.map(normalizeLocKeyItem);\n\n // Create the hash input object\n const hashInput = {\n type: 'finder',\n finder,\n params: sortedParams,\n locations: normalizedLocations\n };\n\n return deterministicStringify(hashInput);\n};\n", "\nimport { ComKey, Item, ItemQuery, LocKeyArray, PriKey } from \"@fjell/core\";\nimport {\n CacheClearedEvent,\n ItemEvent,\n LocationInvalidatedEvent,\n QueryEvent,\n QueryInvalidatedEvent\n} from \"./CacheEventTypes\";\n\n/**\n * Factory functions for creating cache events\n */\nexport class CacheEventFactory {\n private static lastTimestamp = 0;\n private static cleanupInterval: NodeJS.Timeout | null = null;\n private static instanceCount = 0;\n private static readonly CLEANUP_INTERVAL_MS = 60000; // 1 minute\n private static readonly MAX_TIMESTAMP_AGE_MS = 300000; // 5 minutes\n\n /**\n * Initialize cleanup mechanism when first instance is created\n */\n private static initializeCleanup(): void {\n if (this.cleanupInterval === null && this.instanceCount === 0) {\n this.startCleanupTimer();\n }\n this.instanceCount++;\n }\n\n /**\n * Cleanup mechanism when instance is destroyed\n */\n public static destroyInstance(): void {\n this.instanceCount = Math.max(0, this.instanceCount - 1);\n if (this.instanceCount === 0) {\n this.stopCleanupTimer();\n this.resetTimestamp();\n }\n }\n\n /**\n * Start automatic cleanup timer\n */\n private static startCleanupTimer(): void {\n this.cleanupInterval = setInterval(() => {\n this.performCleanup();\n }, this.CLEANUP_INTERVAL_MS);\n\n // Don't keep the process alive just for cleanup\n if (this.cleanupInterval.unref) {\n this.cleanupInterval.unref();\n }\n }\n\n /**\n * Stop automatic cleanup timer\n */\n private static stopCleanupTimer(): void {\n if (this.cleanupInterval) {\n clearInterval(this.cleanupInterval);\n this.cleanupInterval = null;\n }\n }\n\n /**\n * Perform periodic cleanup of stale timestamp state\n */\n private static performCleanup(): void {\n const now = Date.now();\n // Reset timestamp if it's too old to prevent memory issues\n if (now - this.lastTimestamp > this.MAX_TIMESTAMP_AGE_MS) {\n this.lastTimestamp = 0;\n }\n }\n\n /**\n * Reset the timestamp state (useful for testing)\n */\n public static resetTimestamp(): void {\n this.lastTimestamp = 0;\n }\n\n /**\n * Generate a unique timestamp that is always greater than the previous one\n */\n private static generateTimestamp(): number {\n this.initializeCleanup();\n\n const now = Date.now();\n // If current time is greater than last timestamp, use current time\n // Otherwise, increment last timestamp to ensure uniqueness\n if (now > this.lastTimestamp) {\n this.lastTimestamp = now;\n } else {\n this.lastTimestamp = this.lastTimestamp + 1;\n }\n return this.lastTimestamp;\n }\n\n /**\n * Extract affected locations from an item key\n */\n private static extractAffectedLocations<\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n >(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): LocKeyArray<L1, L2, L3, L4, L5> | [] {\n if ('loc' in key && key.loc) {\n return key.loc;\n }\n return [];\n }\n\n /**\n * Create an item-related event\n */\n public static createItemEvent<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n >(\n type: 'item_created' | 'item_updated' | 'item_removed' | 'item_retrieved' | 'item_set',\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n item: V | null,\n options: {\n previousItem?: V | null | null;\n source?: 'api' | 'cache' | 'operation';\n affectedLocations?: LocKeyArray<L1, L2, L3, L4, L5> | [];\n context?: {\n operation?: string;\n requestId?: string;\n userId?: string;\n };\n } = {}\n ): ItemEvent<V, S, L1, L2, L3, L4, L5> {\n // Auto-calculate affected locations if not provided\n const affectedLocations = options.affectedLocations !== undefined\n ? options.affectedLocations\n : this.extractAffectedLocations(key);\n\n return {\n type,\n timestamp: this.generateTimestamp(),\n source: options.source || 'operation',\n context: options.context,\n key,\n item,\n previousItem: options.previousItem,\n affectedLocations\n };\n }\n\n /**\n * Create a query event\n */\n public static createQueryEvent<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n >(\n query: ItemQuery,\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [],\n items: V[],\n options: {\n source?: 'api' | 'cache' | 'operation';\n context?: {\n operation?: string;\n requestId?: string;\n userId?: string;\n };\n } = {}\n ): QueryEvent<V, S, L1, L2, L3, L4, L5> {\n const affectedKeys = items.map(item => item.key);\n\n return {\n type: 'items_queried',\n timestamp: this.generateTimestamp(),\n source: options.source || 'operation',\n context: options.context,\n query,\n locations,\n items,\n affectedKeys\n };\n }\n\n /**\n * Create a cache cleared event\n */\n public static createCacheClearedEvent(\n itemsCleared: number,\n queryCacheCleared: boolean = true,\n options: {\n source?: 'api' | 'cache' | 'operation';\n context?: {\n operation?: string;\n requestId?: string;\n userId?: string;\n };\n } = {}\n ): CacheClearedEvent {\n return {\n type: 'cache_cleared',\n timestamp: this.generateTimestamp(),\n source: options.source || 'operation',\n context: options.context,\n itemsCleared,\n queryCacheCleared\n };\n }\n\n /**\n * Create a location invalidated event\n */\n public static createLocationInvalidatedEvent<\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n >(\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [],\n affectedKeys: (ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[],\n options: {\n source?: 'api' | 'cache' | 'operation';\n context?: {\n operation?: string;\n requestId?: string;\n userId?: string;\n };\n } = {}\n ): LocationInvalidatedEvent<S, L1, L2, L3, L4, L5> {\n return {\n type: 'location_invalidated',\n timestamp: this.generateTimestamp(),\n source: options.source || 'operation',\n context: options.context,\n locations,\n affectedKeys\n };\n }\n\n /**\n * Create a query invalidated event\n */\n public static createQueryInvalidatedEvent(\n invalidatedQueries: string[],\n reason: 'manual' | 'item_changed' | 'location_changed' | 'ttl_expired',\n options: {\n source?: 'api' | 'cache' | 'operation';\n context?: {\n operation?: string;\n requestId?: string;\n userId?: string;\n };\n } = {}\n ): QueryInvalidatedEvent {\n return {\n type: 'query_invalidated',\n timestamp: this.generateTimestamp(),\n source: options.source || 'operation',\n context: options.context,\n invalidatedQueries,\n reason\n };\n }\n\n /**\n * Create an item created event\n */\n public static itemCreated<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n >(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n item: V,\n source: 'api' | 'cache' | 'operation' = 'api'\n ): ItemEvent<V, S, L1, L2, L3, L4, L5> {\n return this.createItemEvent('item_created', key, item, { source });\n }\n\n /**\n * Create an item updated event\n */\n public static itemUpdated<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n >(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n item: V,\n previousItem?: V | null,\n source: 'api' | 'cache' | 'operation' = 'api'\n ): ItemEvent<V, S, L1, L2, L3, L4, L5> {\n return this.createItemEvent('item_updated', key, item, { previousItem, source });\n }\n\n /**\n * Create an item removed event\n */\n public static itemRemoved<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n >(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n previousItem?: V | null,\n source: 'api' | 'cache' | 'operation' = 'api'\n ): ItemEvent<V, S, L1, L2, L3, L4, L5> {\n return this.createItemEvent('item_removed', key, null, { previousItem, source });\n }\n\n /**\n * Create an item retrieved event\n */\n public static itemRetrieved<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n >(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n item: V,\n source: 'api' | 'cache' | 'operation' = 'api'\n ): ItemEvent<V, S, L1, L2, L3, L4, L5> {\n return this.createItemEvent('item_retrieved', key, item, { source });\n }\n\n /**\n * Create an item set event (direct cache operation)\n */\n public static itemSet<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n >(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n item: V,\n previousItem?: V | null\n ): ItemEvent<V, S, L1, L2, L3, L4, L5> {\n return this.createItemEvent('item_set', key, item, {\n previousItem,\n source: 'cache'\n });\n }\n}\n", "import Logging from '@fjell/logging';\n\nconst LibLogger = Logging.getLogger('@fjell/cache');\n\nexport default LibLogger;\n", "import {\n Item,\n ItemQuery,\n LocKeyArray,\n validatePK\n} from \"@fjell/core\";\nimport { NotFoundError } from \"@fjell/http-api\";\nimport { CacheContext } from \"../CacheContext\";\nimport { createQueryHash } from \"../normalization\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get('one');\n\nexport const one = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n query: ItemQuery = {},\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = [],\n context: CacheContext<V, S, L1, L2, L3, L4, L5>\n): Promise<[CacheContext<V, S, L1, L2, L3, L4, L5>, V | null]> => {\n const { api, cacheMap, pkType, ttlManager } = context;\n logger.default('one', { query, locations });\n\n // Generate query hash for caching\n const queryHash = createQueryHash(pkType, query, locations);\n logger.debug('Generated query hash for one', { queryHash });\n\n // Check if we have cached query results\n const cachedItemKeys = await cacheMap.getQueryResult(queryHash);\n if (cachedItemKeys) {\n logger.debug('Using cached query results', { cachedKeyCount: cachedItemKeys.length });\n\n if (cachedItemKeys.length === 0) {\n // Cached empty result (not found)\n return [context, null];\n }\n\n // Retrieve the first cached item - if missing, invalidate the query cache\n const item = await cacheMap.get(cachedItemKeys[0]);\n if (item) {\n return [context, validatePK(item, pkType) as V];\n } else {\n logger.debug('Cached item missing, invalidating query cache');\n cacheMap.deleteQueryResult(queryHash);\n }\n }\n\n let retItem: V | null = null;\n try {\n retItem = await api.one(query, locations);\n if (retItem) {\n // Store individual item in cache\n cacheMap.set(retItem.key, retItem);\n\n // Set TTL metadata for the newly cached item\n const keyStr = JSON.stringify(retItem.key);\n ttlManager.onItemAdded(keyStr, cacheMap);\n\n // Handle eviction for the newly cached item\n const evictedKeys = context.evictionManager.onItemAdded(keyStr, retItem, cacheMap);\n // Remove evicted items from cache\n evictedKeys.forEach(evictedKey => {\n const parsedKey = JSON.parse(evictedKey);\n cacheMap.delete(parsedKey);\n });\n\n // Store query result (single item key) in query cache\n cacheMap.setQueryResult(queryHash, [retItem.key]);\n logger.debug('Cached query result', { queryHash, itemKey: retItem.key });\n } else {\n // Store empty result in query cache\n cacheMap.setQueryResult(queryHash, []);\n logger.debug('Cached empty query result', { queryHash });\n }\n } catch (e: unknown) {\n if (e instanceof NotFoundError) {\n // Handle not found gracefully - cache empty result\n cacheMap.setQueryResult(queryHash, []);\n logger.debug('Cached empty query result for not found', { queryHash });\n } else {\n throw e;\n }\n }\n return [\n context,\n retItem ?\n validatePK(retItem, pkType) as V :\n null\n ];\n};\n", "import {\n Item,\n LocKeyArray,\n validatePK\n} from \"@fjell/core\";\nimport { CacheContext } from \"../CacheContext\";\nimport { CacheEventFactory } from \"../events/CacheEventFactory\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get('create');\n\nexport const create = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n v: Partial<Item<S, L1, L2, L3, L4, L5>>,\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = [],\n context: CacheContext<V, S, L1, L2, L3, L4, L5>\n): Promise<[CacheContext<V, S, L1, L2, L3, L4, L5>, V]> => {\n const { api, cacheMap, pkType, eventEmitter, ttlManager, evictionManager } = context;\n logger.default('create', { v, locations });\n const created = await api.create(v, locations);\n cacheMap.set(created.key, created);\n\n // Set TTL metadata for the newly cached item\n const keyStr = JSON.stringify(created.key);\n ttlManager.onItemAdded(keyStr, cacheMap);\n\n // Handle eviction for the newly cached item\n const evictedKeys = evictionManager.onItemAdded(keyStr, created, cacheMap);\n // Remove evicted items from cache\n evictedKeys.forEach(evictedKey => {\n const parsedKey = JSON.parse(evictedKey);\n cacheMap.delete(parsedKey);\n });\n\n // Emit event\n const event = CacheEventFactory.itemCreated(created.key, created as V, 'api');\n eventEmitter.emit(event);\n\n return [context, validatePK(created, pkType) as V];\n};\n", "import {\n ComKey,\n isValidItemKey,\n Item,\n PriKey,\n validatePK\n} from \"@fjell/core\";\nimport { CacheContext } from \"../CacheContext\";\nimport { CacheEventFactory } from \"../events/CacheEventFactory\";\nimport { createNormalizedHashFunction } from \"../normalization\";\nimport { estimateValueSize } from \"../utils/CacheSize\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get('get');\n\n// Track in-flight API requests to prevent duplicate calls for the same key\nconst inFlightRequests = new Map<string, { promise: Promise<any>; timestamp: number }>();\n\n// Cleanup timeout for hanging requests (default 5 minutes)\nconst CLEANUP_TIMEOUT = 5 * 60 * 1000; // 5 minutes\n\n// Periodic cleanup of stale in-flight requests\nconst cleanupStaleRequests = () => {\n const now = Date.now();\n const keysToDelete: string[] = [];\n\n inFlightRequests.forEach((request, key) => {\n if (now - request.timestamp > CLEANUP_TIMEOUT) {\n keysToDelete.push(key);\n }\n });\n\n keysToDelete.forEach(key => {\n logger.debug('Cleaning up stale in-flight request', { key });\n inFlightRequests.delete(key);\n });\n};\n\n// Run cleanup every minute\nconst cleanupInterval = setInterval(cleanupStaleRequests, 60 * 1000);\n\n// Export cleanup function for graceful shutdown\nexport const cleanup = () => {\n clearInterval(cleanupInterval);\n inFlightRequests.clear();\n};\n\n// Normalized key stringification for tracking purposes - uses same normalization as cache maps\nconst keyToString = createNormalizedHashFunction<any>();\n\nexport const get = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n context: CacheContext<V, S, L1, L2, L3, L4, L5>\n): Promise<[CacheContext<V, S, L1, L2, L3, L4, L5>, V | null]> => {\n const { api, cacheMap, pkType, ttlManager, statsManager } = context;\n logger.default('get', { key, defaultTTL: ttlManager.getDefaultTTL() });\n\n // Track cache request\n statsManager.incrementRequests();\n\n if (!isValidItemKey(key)) {\n logger.error('Key for Get is not a valid ItemKey: %j', key);\n throw new Error('Key for Get is not a valid ItemKey');\n }\n\n // Check cache first if TTL is enabled\n if (ttlManager.isTTLEnabled()) {\n const keyStr = JSON.stringify(key);\n const cachedItem = await cacheMap.get(key);\n if (cachedItem) {\n // Check TTL validity using TTLManager\n const isValid = ttlManager.validateItem(keyStr, cacheMap);\n if (isValid) {\n logger.debug('Cache hit with valid TTL', { key, defaultTTL: ttlManager.getDefaultTTL() });\n statsManager.incrementHits();\n return [context, validatePK(cachedItem, pkType) as V];\n } else {\n // Item expired, remove it from cache\n logger.debug('Cache item expired, removing', { key });\n cacheMap.delete(key);\n statsManager.incrementMisses();\n }\n } else {\n // No cached item found\n statsManager.incrementMisses();\n }\n logger.debug('Cache miss or expired', { key, defaultTTL: ttlManager.getDefaultTTL() });\n } else {\n // TTL not enabled, check cache directly\n const cachedItem = await cacheMap.get(key);\n if (cachedItem) {\n logger.debug('Cache hit (TTL disabled)', { key });\n statsManager.incrementHits();\n return [context, validatePK(cachedItem, pkType) as V];\n } else {\n statsManager.incrementMisses();\n }\n }\n\n // If TTL is 0 or cache miss/expired, fetch from API\n let ret: V | null;\n const keyStr = keyToString(key);\n\n try {\n // Check if there's already an in-flight request for this key\n const requestEntry = inFlightRequests.get(keyStr);\n let apiRequest: Promise<any>;\n\n if (!requestEntry) {\n // Create new API request\n apiRequest = api.get(key);\n\n // Only track successful promise creation\n if (apiRequest && typeof apiRequest.then === 'function') {\n const timestamp = Date.now();\n inFlightRequests.set(keyStr, { promise: apiRequest, timestamp });\n\n // Clean up the tracking when request completes (success or failure)\n const cleanup = () => inFlightRequests.delete(keyStr);\n\n if (typeof apiRequest.finally === 'function') {\n apiRequest.finally(cleanup);\n } else {\n // Fallback cleanup for promises without .finally()\n apiRequest.then(cleanup, cleanup);\n }\n }\n } else {\n logger.debug('Using in-flight request for key', { key });\n apiRequest = requestEntry.promise;\n }\n\n ret = await apiRequest;\n if (ret) {\n cacheMap.set(ret.key, ret);\n\n const keyStr = JSON.stringify(ret.key);\n\n // Create base metadata if it doesn't exist (needed for TTL and eviction)\n const metadata = cacheMap.getMetadata?.(keyStr);\n if (!metadata) {\n const now = Date.now();\n const baseMetadata = {\n key: keyStr,\n addedAt: now,\n lastAccessedAt: now,\n accessCount: 1,\n estimatedSize: estimateValueSize(ret)\n };\n cacheMap.setMetadata?.(keyStr, baseMetadata);\n }\n\n // Handle eviction for the newly cached item\n const evictedKeys = context.evictionManager.onItemAdded(keyStr, ret, cacheMap);\n\n // Set TTL metadata for the newly cached item\n ttlManager.onItemAdded(keyStr, cacheMap);\n\n // Remove evicted items from cache\n evictedKeys.forEach(evictedKey => {\n const parsedKey = JSON.parse(evictedKey);\n cacheMap.delete(parsedKey);\n });\n\n // Emit event for item retrieved from API\n const event = CacheEventFactory.itemRetrieved(ret.key, ret as V, 'api');\n context.eventEmitter.emit(event);\n }\n } catch (e: any) {\n // Ensure we clean up the in-flight request on error\n inFlightRequests.delete(keyStr);\n logger.error(\"Error getting item for key\", { key, message: e.message, stack: e.stack });\n throw e;\n }\n\n return [\n context,\n ret ?\n validatePK(ret, pkType) as V :\n null\n ];\n};\n", "/**\n * Utility functions for parsing and managing cache sizes\n */\n\n/**\n * Size unit multipliers (decimal and binary)\n */\nconst SIZE_UNITS: { [key: string]: number } = {\n // Decimal units (powers of 1000)\n 'b': 1,\n 'byte': 1,\n 'bytes': 1,\n 'kb': 1000,\n 'kilobyte': 1000,\n 'kilobytes': 1000,\n 'mb': 1000 * 1000,\n 'megabyte': 1000 * 1000,\n 'megabytes': 1000 * 1000,\n 'gb': 1000 * 1000 * 1000,\n 'gigabyte': 1000 * 1000 * 1000,\n 'gigabytes': 1000 * 1000 * 1000,\n 'tb': 1000 * 1000 * 1000 * 1000,\n 'terabyte': 1000 * 1000 * 1000 * 1000,\n 'terabytes': 1000 * 1000 * 1000 * 1000,\n\n // Binary units (powers of 1024)\n 'kib': 1024,\n 'kibibyte': 1024,\n 'kibibytes': 1024,\n 'mib': 1024 * 1024,\n 'mebibyte': 1024 * 1024,\n 'mebibytes': 1024 * 1024,\n 'gib': 1024 * 1024 * 1024,\n 'gibibyte': 1024 * 1024 * 1024,\n 'gibibytes': 1024 * 1024 * 1024,\n 'tib': 1024 * 1024 * 1024 * 1024,\n 'tebibyte': 1024 * 1024 * 1024 * 1024,\n 'tebibytes': 1024 * 1024 * 1024 * 1024,\n};\n\n/**\n * Parse a size string and return the size in bytes\n *\n * @param sizeStr - Size string (e.g., '300', '3kb', '5MB', '2GiB')\n * @returns Size in bytes\n * @throws Error if the size string is invalid\n */\nexport function parseSizeString(sizeStr: string): number {\n if (!sizeStr || typeof sizeStr !== 'string') {\n throw new Error('Size string must be a non-empty string');\n }\n\n const trimmed = sizeStr.trim();\n\n // Handle pure numeric values (assume bytes)\n if (/^\\d+(\\.\\d+)?$/.test(trimmed)) {\n const bytes = parseFloat(trimmed);\n if (isNaN(bytes) || bytes < 0) {\n throw new Error(`Invalid size value: ${sizeStr}`);\n }\n return Math.floor(bytes);\n }\n\n // Parse with unit\n const match = trimmed.match(/^(\\d+(?:\\.\\d+)?)\\s*([a-zA-Z]+)$/);\n if (!match) {\n throw new Error(`Invalid size format: ${sizeStr}. Expected format: '100', '5KB', '10MB', etc.`);\n }\n\n const [, valueStr, unitStr] = match;\n const value = parseFloat(valueStr);\n const unit = unitStr.toLowerCase();\n\n if (isNaN(value) || value < 0) {\n throw new Error(`Invalid size value: ${valueStr}`);\n }\n\n const multiplier = SIZE_UNITS[unit];\n if (!(unit in SIZE_UNITS)) {\n const supportedUnits = Object.keys(SIZE_UNITS).filter(u => u.length <= 3).join(', ');\n throw new Error(`Unsupported size unit: ${unitStr}. Supported units: ${supportedUnits}`);\n }\n\n return Math.floor(value * multiplier);\n}\n\n/**\n * Format bytes as a human-readable string\n *\n * @param bytes - Size in bytes\n * @param binary - Use binary units (1024) instead of decimal (1000)\n * @returns Formatted size string\n */\nexport function formatBytes(bytes: number, binary: boolean = false): string {\n if (bytes === 0) return '0 B';\n if (bytes < 0) return `${bytes} B`;\n\n const k = binary ? 1024 : 1000;\n const sizes = binary\n ? ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB']\n : ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];\n\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n const size = bytes / Math.pow(k, i);\n\n // Show decimals only if needed\n const formatted = size % 1 === 0 ? size.toString() : size.toFixed(1);\n\n return `${formatted} ${sizes[i]}`;\n}\n\n/**\n * Estimate the serialized size of a value in bytes\n * This is an approximation for cache size calculations\n *\n * @param value - The value to estimate size for\n * @returns Estimated size in bytes\n */\nimport safeStringify from 'fast-safe-stringify';\n\nexport function estimateValueSize(value: any): number {\n if (value === null || typeof value === 'undefined') {\n return 8; // Approximate overhead\n }\n\n switch (typeof value) {\n case 'boolean':\n return 4;\n case 'number':\n return 8;\n case 'string':\n // UTF-8 encoding: most characters are 1 byte, some are 2-4 bytes\n // Use a simple approximation of 2 bytes per character for safety\n return value.length * 2;\n case 'object':\n if (Array.isArray(value)) {\n return value.reduce((total, item) => total + estimateValueSize(item), 24); // Array overhead\n }\n\n // Detect circular references explicitly to respect fallback behavior\n const hasCircularReference = (obj: unknown, ancestors: WeakSet<object> = new WeakSet(), checked: WeakSet<object> = new WeakSet()): boolean => {\n if (obj === null || typeof obj !== 'object') {\n return false;\n }\n\n const asObject = obj as object;\n\n if (checked.has(asObject)) {\n return false;\n }\n\n if (ancestors.has(asObject)) {\n return true;\n }\n\n ancestors.add(asObject);\n try {\n if (Array.isArray(asObject)) {\n for (const item of asObject) {\n if (hasCircularReference(item, ancestors, checked)) {\n return true;\n }\n }\n } else {\n for (const key of Object.keys(asObject as Record<string, unknown>)) {\n // Access value defensively in case of getters throwing\n let child: unknown;\n try {\n child = (asObject as Record<string, unknown>)[key as keyof typeof asObject];\n } catch {\n // Treat property access errors as non-fatal for traversal\n continue;\n }\n if (hasCircularReference(child, ancestors, checked)) {\n return true;\n }\n }\n }\n } finally {\n ancestors.delete(asObject);\n checked.add(asObject);\n }\n\n return false;\n };\n\n try {\n if (hasCircularReference(value)) {\n return 64;\n }\n } catch {\n return 64;\n }\n\n // For objects, estimate based on safe serialization that supports circular refs\n try {\n const jsonString = safeStringify(value);\n return jsonString.length * 2 + 16; // JSON string size + object overhead\n } catch {\n // Fallback for objects that can't be serialized\n return 64;\n }\n default:\n return 32; // Default fallback\n }\n}\n\n/**\n * Check if a size configuration is valid\n *\n * @param config - Size configuration to validate\n * @throws Error if configuration is invalid\n */\nexport function validateSizeConfig(config: { maxSizeBytes?: string; maxItems?: number }): void {\n if (typeof config.maxSizeBytes !== 'undefined') {\n try {\n const bytes = parseSizeString(config.maxSizeBytes);\n if (bytes <= 0) {\n throw new Error('maxSizeBytes must be positive');\n }\n } catch (error) {\n throw new Error(`Invalid maxSizeBytes: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n\n if (typeof config.maxItems !== 'undefined') {\n if (!Number.isInteger(config.maxItems) || config.maxItems <= 0) {\n throw new Error('maxItems must be a positive integer');\n }\n }\n}\n", "import {\n ComKey,\n isValidItemKey,\n Item,\n PriKey,\n validatePK\n} from \"@fjell/core\";\nimport { CacheContext } from \"../CacheContext\";\nimport LibLogger from \"../logger\";\nimport { get } from \"./get\";\n\nconst logger = LibLogger.get('retrieve');\n\nexport const retrieve = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n context: CacheContext<V, S, L1, L2, L3, L4, L5>\n): Promise<[CacheContext<V, S, L1, L2, L3, L4, L5> | null, V | null]> => {\n const { cacheMap, pkType, statsManager } = context;\n logger.default('retrieve', { key });\n\n // Track cache request\n statsManager.incrementRequests();\n\n if (!isValidItemKey(key)) {\n logger.error('Key for Retrieve is not a valid ItemKey: %j', key);\n throw new Error('Key for Retrieve is not a valid ItemKey');\n }\n\n const containsItemKey = await cacheMap.includesKey(key);\n\n let retrieved: V | null;\n let contextToReturn: CacheContext<V, S, L1, L2, L3, L4, L5> | null;\n\n if (containsItemKey) {\n logger.default('Looking for Object in Cache', key);\n retrieved = await cacheMap.get(key);\n contextToReturn = null;\n statsManager.incrementHits();\n } else {\n logger.default('Object Not Found in Cache, Retrieving from Server API', { key });\n statsManager.incrementMisses();\n [contextToReturn, retrieved] = await get(key, context);\n }\n\n const retValue: [CacheContext<V, S, L1, L2, L3, L4, L5> | null, V | null] = [\n contextToReturn,\n retrieved ?\n validatePK(retrieved, pkType) as V :\n null\n ];\n\n return retValue;\n};\n", "import {\n ComKey,\n isValidItemKey,\n Item,\n PriKey\n} from \"@fjell/core\";\nimport { CacheContext } from \"../CacheContext\";\nimport { CacheEventFactory } from \"../events/CacheEventFactory\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get('remove');\n\nexport const remove = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n context: CacheContext<V, S, L1, L2, L3, L4, L5>\n): Promise<CacheContext<V, S, L1, L2, L3, L4, L5>> => {\n const { api, cacheMap } = context;\n logger.default('remove', { key });\n\n if (!isValidItemKey(key)) {\n logger.error('Key for Remove is not a valid ItemKey: %j', key);\n throw new Error('Key for Remove is not a valid ItemKey');\n }\n\n try {\n // Get item before removal for event\n const previousItem = await cacheMap.get(key);\n\n // First remove from API, then from cache to maintain consistency\n await api.remove(key);\n cacheMap.delete(key);\n\n // Emit event\n if (previousItem) {\n const event = CacheEventFactory.itemRemoved(key, previousItem, 'api');\n context.eventEmitter.emit(event);\n }\n\n logger.debug('Successfully removed item from API and cache', { key });\n } catch (e) {\n logger.error(\"Error deleting item\", { error: e });\n // Don't delete from cache if API deletion failed\n throw e;\n }\n\n return context;\n};\n", "import {\n ComKey,\n isValidItemKey,\n Item,\n PriKey,\n validatePK\n} from \"@fjell/core\";\nimport { CacheContext } from \"../CacheContext\";\nimport { CacheEventFactory } from \"../events/CacheEventFactory\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get('update');\n\nexport const update = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n v: Partial<Item<S, L1, L2, L3, L4, L5>>,\n context: CacheContext<V, S, L1, L2, L3, L4, L5>\n): Promise<[CacheContext<V, S, L1, L2, L3, L4, L5>, V]> => {\n const { api, cacheMap, pkType } = context;\n logger.default('update', { key, v });\n\n if (!isValidItemKey(key)) {\n logger.error('Key for Update is not a valid ItemKey: %j', key);\n throw new Error('Key for Update is not a valid ItemKey');\n }\n\n // Invalidate the item key before executing the update\n logger.debug('Invalidating item key before update', { key });\n cacheMap.invalidateItemKeys([key]);\n\n try {\n // Get previous item for event\n const previousItem = await cacheMap.get(key);\n\n const updated = await api.update(key, v);\n\n // Cache the result after the update\n logger.debug('Caching update result', { updatedKey: updated.key });\n cacheMap.set(updated.key, updated);\n\n // Set TTL metadata for the newly cached item\n const keyStr = JSON.stringify(updated.key);\n context.ttlManager.onItemAdded(keyStr, cacheMap);\n\n // Handle eviction for the newly cached item\n const evictedKeys = context.evictionManager.onItemAdded(keyStr, updated, cacheMap);\n // Remove evicted items from cache\n evictedKeys.forEach(evictedKey => {\n const parsedKey = JSON.parse(evictedKey);\n cacheMap.delete(parsedKey);\n });\n\n // Emit event\n const event = CacheEventFactory.itemUpdated(updated.key, updated as V, previousItem, 'api');\n context.eventEmitter.emit(event);\n\n return [context, validatePK(updated, pkType) as V];\n } catch (e) {\n logger.error(\"Error updating item\", { error: e });\n throw e;\n }\n};\n", "import {\n ComKey,\n isValidItemKey,\n Item,\n PriKey,\n validatePK\n} from \"@fjell/core\";\nimport { CacheContext } from \"../CacheContext\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get('action');\n\nexport const action = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n action: string,\n body: any = {},\n context: CacheContext<V, S, L1, L2, L3, L4, L5>\n): Promise<[CacheContext<V, S, L1, L2, L3, L4, L5>, V]> => {\n const { api, cacheMap, pkType } = context;\n logger.default('action', { key, action, body });\n\n if (!isValidItemKey(key)) {\n logger.error('Key for Action is not a valid ItemKey: %j', key);\n throw new Error('Key for Action is not a valid ItemKey');\n }\n\n // Invalidate the item key before executing the action\n logger.debug('Invalidating item key before action', { key });\n cacheMap.invalidateItemKeys([key]);\n\n const updated = await api.action(key, action, body);\n\n // Cache the result after the action\n logger.debug('Caching action result', { updatedKey: updated.key });\n cacheMap.set(updated.key, updated);\n\n // Set TTL metadata for the newly cached item\n const keyStr = JSON.stringify(updated.key);\n context.ttlManager.onItemAdded(keyStr, cacheMap);\n\n // Handle eviction for the newly cached item\n const evictedKeys = context.evictionManager.onItemAdded(keyStr, updated, cacheMap);\n // Remove evicted items from cache\n evictedKeys.forEach(evictedKey => {\n try {\n const parsedKey = JSON.parse(evictedKey);\n cacheMap.delete(parsedKey);\n } catch (error) {\n logger.error('Failed to parse evicted key during deletion', {\n evictedKey,\n error: error instanceof Error ? error.message : String(error)\n });\n // Continue processing other keys rather than failing completely\n }\n });\n\n return [context, validatePK(updated, pkType) as V];\n};\n", "import {\n Item,\n LocKeyArray,\n validatePK\n} from \"@fjell/core\";\nimport { NotFoundError } from \"@fjell/http-api\";\nimport { CacheContext } from \"../CacheContext\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get('allAction');\n\nexport const allAction = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n action: string,\n body: any = {},\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = [],\n context: CacheContext<V, S, L1, L2, L3, L4, L5>\n): Promise<[CacheContext<V, S, L1, L2, L3, L4, L5>, V[]]> => {\n const { api, cacheMap, pkType } = context;\n logger.default('allAction', { action, body, locations });\n\n // Invalidate all items in the specified locations before executing the action\n logger.debug('Invalidating location before allAction', { locations });\n cacheMap.invalidateLocation(locations);\n\n let ret: V[] = [];\n try {\n ret = await api.allAction(action, body, locations);\n\n // Cache all results after the action\n logger.debug('Caching allAction results', { resultCount: ret.length });\n ret.forEach((v) => {\n cacheMap.set(v.key, v);\n\n // Set TTL metadata for the newly cached item\n const keyStr = JSON.stringify(v.key);\n context.ttlManager.onItemAdded(keyStr, cacheMap);\n\n // Handle eviction for the newly cached item\n const evictedKeys = context.evictionManager.onItemAdded(keyStr, v, cacheMap);\n // Remove evicted items from cache\n evictedKeys.forEach(evictedKey => {\n const parsedKey = JSON.parse(evictedKey);\n cacheMap.delete(parsedKey);\n });\n });\n } catch (e: unknown) {\n // istanbul ignore next\n if (e instanceof NotFoundError) {\n // Handle not found gracefully\n } else {\n throw e;\n }\n }\n return [context, validatePK(ret, pkType) as V[]];\n};\n", "import {\n ComKey,\n Item,\n PriKey\n} from \"@fjell/core\";\nimport { CacheContext } from \"../CacheContext\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get('facet');\n\nexport const facet = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n facet: string,\n params: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>> = {},\n context: CacheContext<V, S, L1, L2, L3, L4, L5>\n): Promise<any> => {\n const { api } = context;\n logger.default('facet', { key, facet });\n const ret = await api.facet(key, facet, params);\n return ret;\n};\n", "import {\n Item,\n LocKeyArray\n} from \"@fjell/core\";\nimport { CacheContext } from \"../CacheContext\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get('allFacet');\n\nexport const allFacet = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n facet: string,\n params: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>> = {},\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = [],\n context: CacheContext<V, S, L1, L2, L3, L4, L5>\n): Promise<any> => {\n const { api } = context;\n logger.default('allFacet', { facet, params, locations });\n const ret = await api.allFacet(facet, params, locations);\n return ret;\n};\n", "import {\n Item,\n LocKeyArray,\n validatePK\n} from \"@fjell/core\";\nimport { CacheContext } from \"../CacheContext\";\nimport { createFinderHash } from \"../normalization\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get('find');\n\nexport const find = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n finder: string,\n params: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>> = {},\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = [],\n context: CacheContext<V, S, L1, L2, L3, L4, L5>\n): Promise<[CacheContext<V, S, L1, L2, L3, L4, L5>, V[]]> => {\n const { api, cacheMap, pkType, ttlManager } = context;\n logger.default('find', { finder, params, locations });\n\n // Generate query hash for caching\n const queryHash = createFinderHash(finder, params, locations);\n logger.debug('Generated query hash for find', { queryHash });\n\n // Check if we have cached query results\n const cachedItemKeys = await cacheMap.getQueryResult(queryHash);\n if (cachedItemKeys) {\n logger.debug('Using cached query results', { cachedKeyCount: cachedItemKeys.length });\n\n // Retrieve all cached items - if any are missing, invalidate the query cache\n const cachedItems: V[] = [];\n let allItemsAvailable = true;\n\n for (const itemKey of cachedItemKeys) {\n const item = await cacheMap.get(itemKey);\n if (item) {\n cachedItems.push(item);\n } else {\n allItemsAvailable = false;\n break;\n }\n }\n\n if (allItemsAvailable) {\n return [context, validatePK(cachedItems, pkType) as V[]];\n } else {\n logger.debug('Some cached items missing, invalidating query cache');\n cacheMap.deleteQueryResult(queryHash);\n }\n }\n\n // Fetch from API\n const ret: V[] = await api.find(finder, params, locations);\n\n // Store individual items in cache\n ret.forEach((v) => {\n cacheMap.set(v.key, v);\n\n // Set TTL metadata for the newly cached item\n const keyStr = JSON.stringify(v.key);\n ttlManager.onItemAdded(keyStr, cacheMap);\n\n // Handle eviction for the newly cached item\n const evictedKeys = context.evictionManager.onItemAdded(keyStr, v, cacheMap);\n // Remove evicted items from cache\n evictedKeys.forEach(evictedKey => {\n const parsedKey = JSON.parse(evictedKey);\n cacheMap.delete(parsedKey);\n });\n });\n\n // Store query result (item keys) in query cache\n const itemKeys = ret.map(item => item.key);\n cacheMap.setQueryResult(queryHash, itemKeys);\n logger.debug('Cached query result', { queryHash, itemKeyCount: itemKeys.length });\n\n return [context, validatePK(ret, pkType) as V[]];\n};\n", "import {\n Item,\n LocKeyArray,\n validatePK\n} from \"@fjell/core\";\nimport { CacheContext } from \"../CacheContext\";\nimport { createFinderHash } from \"../normalization\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get('findOne');\n\nexport const findOne = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n finder: string,\n finderParams: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>> = {},\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = [],\n context: CacheContext<V, S, L1, L2, L3, L4, L5>\n): Promise<[CacheContext<V, S, L1, L2, L3, L4, L5>, V]> => {\n const { api, cacheMap, pkType, ttlManager } = context;\n logger.default('findOne', { finder, finderParams, locations });\n\n // Generate query hash for caching\n const queryHash = createFinderHash(finder, finderParams, locations);\n logger.debug('Generated query hash for findOne', { queryHash });\n\n // Check if we have cached query results\n const cachedItemKeys = await cacheMap.getQueryResult(queryHash);\n if (cachedItemKeys && cachedItemKeys.length > 0) {\n logger.debug('Using cached query results', { cachedKeyCount: cachedItemKeys.length });\n\n // Retrieve the first cached item - if missing, invalidate the query cache\n const item = await cacheMap.get(cachedItemKeys[0]);\n if (item) {\n return [context, validatePK(item, pkType) as V];\n } else {\n logger.debug('Cached item missing, invalidating query cache');\n cacheMap.deleteQueryResult(queryHash);\n }\n }\n\n // Fetch from API\n const ret = await api.findOne(finder, finderParams, locations);\n\n // Store individual item in cache\n cacheMap.set(ret.key, ret);\n\n // Set TTL metadata for the newly cached item\n const keyStr = JSON.stringify(ret.key);\n ttlManager.onItemAdded(keyStr, cacheMap);\n\n // Handle eviction for the newly cached item\n const evictedKeys = context.evictionManager.onItemAdded(keyStr, ret, cacheMap);\n // Remove evicted items from cache\n evictedKeys.forEach(evictedKey => {\n const parsedKey = JSON.parse(evictedKey);\n cacheMap.delete(parsedKey);\n });\n\n // Store query result (single item key) in query cache\n cacheMap.setQueryResult(queryHash, [ret.key]);\n logger.debug('Cached query result', { queryHash, itemKey: ret.key });\n\n return [context, validatePK(ret, pkType) as V];\n};\n", "import {\n ComKey,\n isItemKeyEqual,\n isValidItemKey,\n Item,\n PriKey,\n validatePK\n} from \"@fjell/core\";\nimport { CacheContext } from \"../CacheContext\";\nimport { CacheEventFactory } from \"../events/CacheEventFactory\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get('set');\n\n// Normalize a key value to string for consistent comparison\nconst normalizeKeyValue = (value: string | number): string => {\n return String(value);\n};\n\n// Normalized key comparison function that handles string/number differences\nconst isItemKeyEqualNormalized = <\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(a: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>, b: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): boolean => {\n // For now, just normalize the keys to strings and use the original comparison\n const normalizedA = normalizeKey(a);\n const normalizedB = normalizeKey(b);\n return isItemKeyEqual(normalizedA as ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>, normalizedB as ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>);\n};\n\n// Helper function to normalize a key efficiently without deep cloning\nconst normalizeKey = (key: any): any => {\n if (typeof key === 'object' && key !== null) {\n let needsNormalization = false;\n let normalizedKey = key;\n\n // Check if pk needs normalization\n if ('pk' in key && key.pk !== null && typeof key.pk !== 'string') {\n needsNormalization = true;\n }\n\n // Check if lk needs normalization\n if ('lk' in key && key.lk !== null && typeof key.lk !== 'string') {\n needsNormalization = true;\n }\n\n // Check if loc array has lk values that need normalization\n if ('loc' in key && Array.isArray(key.loc)) {\n for (const locItem of key.loc) {\n if (locItem && 'lk' in locItem && locItem.lk !== null && typeof locItem.lk !== 'string') {\n needsNormalization = true;\n break;\n }\n }\n }\n\n // Only create a new object if normalization is actually needed\n if (needsNormalization) {\n normalizedKey = { ...key };\n\n // Normalize pk values\n if ('pk' in normalizedKey && normalizedKey.pk !== null) {\n normalizedKey.pk = normalizeKeyValue(normalizedKey.pk);\n }\n\n // Normalize lk values\n if ('lk' in normalizedKey && normalizedKey.lk !== null) {\n normalizedKey.lk = normalizeKeyValue(normalizedKey.lk);\n }\n\n // Normalize loc array lk values\n if ('loc' in normalizedKey && Array.isArray(normalizedKey.loc)) {\n normalizedKey.loc = normalizedKey.loc.map((locItem: any) => {\n if (locItem && 'lk' in locItem && locItem.lk !== null && typeof locItem.lk !== 'string') {\n return { ...locItem, lk: normalizeKeyValue(locItem.lk) };\n }\n return locItem;\n });\n }\n }\n\n return normalizedKey;\n }\n return key;\n};\n\nexport const set = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n v: Item<S, L1, L2, L3, L4, L5>,\n context: CacheContext<V, S, L1, L2, L3, L4, L5>\n): Promise<[CacheContext<V, S, L1, L2, L3, L4, L5>, V]> => {\n const { cacheMap, pkType, ttlManager, evictionManager, eventEmitter } = context;\n logger.default('set', { key, v });\n\n if (!isValidItemKey(key)) {\n logger.error('Key for Set is not a valid ItemKey: %j', key);\n throw new Error('Key for Set is not a valid ItemKey');\n }\n\n // Validate the item's primary key\n validatePK(v, pkType);\n\n if (!isItemKeyEqualNormalized(key, v.key)) {\n logger.error('Key does not match item key: %j != %j', key, v.key);\n throw new Error('Key does not match item key');\n }\n\n // Get previous item if it exists\n const previousItem = await cacheMap.get(key);\n\n cacheMap.set(key, v as V);\n\n // Set TTL metadata for the newly cached item\n const keyStr = JSON.stringify(key);\n ttlManager.onItemAdded(keyStr, cacheMap);\n\n // Handle eviction for the newly cached item\n const evictedKeys = evictionManager.onItemAdded(keyStr, v, cacheMap);\n // Remove evicted items from cache\n evictedKeys.forEach(evictedKey => {\n const parsedKey = JSON.parse(evictedKey);\n cacheMap.delete(parsedKey);\n });\n\n // Emit event\n const event = CacheEventFactory.itemSet(key, v as V, previousItem);\n eventEmitter.emit(event);\n\n return [context, validatePK(v, pkType) as V];\n};\n", "import {\n AllItemTypeArrays,\n ComKey,\n isComKey,\n isQueryMatch,\n Item,\n ItemQuery,\n LocKeyArray,\n PriKey\n} from \"@fjell/core\";\nimport { CacheMap } from \"../CacheMap\";\nimport { CacheItemMetadata } from \"../eviction/EvictionStrategy\";\nimport { createNormalizedHashFunction, isLocKeyArrayEqual, QueryCacheEntry } from \"../normalization\";\nimport { estimateValueSize } from \"../utils/CacheSize\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get(\"MemoryCacheMap\");\n\ninterface DictionaryEntry<K, V> {\n originalKey: K;\n value: V;\n}\n\n/**\n * In-memory implementation of CacheMap using a plain object as the underlying storage.\n * This implementation stores all data in memory and will be lost when the application restarts.\n */\nexport class MemoryCacheMap<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n> extends CacheMap<V, S, L1, L2, L3, L4, L5> {\n\n public readonly implementationType = \"memory/memory\";\n\n private map: { [key: string]: DictionaryEntry<ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>, V> } = {};\n private normalizedHashFunction: (key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>) => string;\n\n // Query result cache: maps query hash to cache entry\n private queryResultCache: { [queryHash: string]: QueryCacheEntry } = {};\n\n // Metadata storage for eviction strategies\n private metadataMap: Map<string, CacheItemMetadata> = new Map();\n\n public constructor(\n types: AllItemTypeArrays<S, L1, L2, L3, L4, L5>,\n initialData?: { [key: string]: V }\n ) {\n super(types);\n this.normalizedHashFunction = createNormalizedHashFunction<ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>>();\n\n // Initialize with data if provided\n if (initialData) {\n for (const [keyStr, value] of Object.entries(initialData)) {\n try {\n const key = JSON.parse(keyStr) as ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>;\n this.set(key, value);\n } catch (error) {\n logger.error('Failed to parse initial data key', { keyStr, error });\n }\n }\n }\n }\n\n public async get(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n ): Promise<V | null> {\n logger.trace('get', { key });\n const hashedKey = this.normalizedHashFunction(key);\n const entry = this.map[hashedKey];\n\n if (entry && this.normalizedHashFunction(entry.originalKey) === hashedKey) {\n // Update metadata for access tracking\n const keyStr = JSON.stringify(key);\n const metadata = this.metadataMap.get(keyStr);\n if (metadata) {\n metadata.lastAccessedAt = Date.now();\n metadata.accessCount++;\n }\n return entry.value;\n }\n return null;\n }\n\n public set(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>, value: V): void {\n logger.trace('set', { key, value });\n const hashedKey = this.normalizedHashFunction(key);\n const keyStr = JSON.stringify(key);\n\n // Create or update the item entry\n this.map[hashedKey] = { originalKey: key, value: value };\n\n // Create metadata if it doesn't exist\n if (!this.metadataMap.has(keyStr)) {\n const now = Date.now();\n const metadata: CacheItemMetadata = {\n key: keyStr,\n addedAt: now,\n lastAccessedAt: now,\n accessCount: 1,\n estimatedSize: estimateValueSize(value)\n };\n this.metadataMap.set(keyStr, metadata);\n } else {\n // Update existing metadata\n const metadata = this.metadataMap.get(keyStr)!;\n metadata.lastAccessedAt = Date.now();\n metadata.accessCount++;\n metadata.estimatedSize = estimateValueSize(value);\n }\n }\n\n public async includesKey(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): Promise<boolean> {\n const hashedKey = this.normalizedHashFunction(key);\n const entry = this.map[hashedKey];\n return !!entry && this.normalizedHashFunction(entry.originalKey) === hashedKey;\n }\n\n public delete(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): void {\n logger.trace('delete', { key });\n const hashedKey = this.normalizedHashFunction(key);\n const entry = this.map[hashedKey];\n if (entry && this.normalizedHashFunction(entry.originalKey) === hashedKey) {\n // Remove associated metadata using the original key representation\n const keyStr = JSON.stringify(entry.originalKey);\n this.metadataMap.delete(keyStr);\n\n delete this.map[hashedKey];\n\n // Remove this key from any cached query results\n for (const [queryHash, cacheEntry] of Object.entries(this.queryResultCache)) {\n cacheEntry.itemKeys = cacheEntry.itemKeys.filter(k => this.normalizedHashFunction(k) !== hashedKey);\n if (cacheEntry.itemKeys.length === 0) {\n delete this.queryResultCache[queryHash];\n }\n }\n }\n }\n\n public keys(): (ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[] {\n return Object.values(this.map).map(entry => entry.originalKey);\n }\n\n public async values(): Promise<V[]> {\n return Object.values(this.map).map(entry => entry.value);\n }\n\n public clear(): void {\n this.map = {};\n // Clear related metadata and query results to avoid memory leaks\n this.metadataMap.clear();\n this.queryResultCache = {};\n }\n\n public async allIn(\n locations: LocKeyArray<L1, L2, L3, L4, L5> | []\n ): Promise<V[]> {\n const allValues = await this.values();\n if (locations.length === 0) {\n logger.debug('Returning all items, LocKeys is empty');\n return allValues;\n } else {\n logger.debug('allIn', { locations, count: allValues.length });\n return allValues.filter(item => {\n const key = item.key;\n if (key && isComKey(key)) {\n const comKey = key as ComKey<S, L1, L2, L3, L4, L5>;\n return isLocKeyArrayEqual(locations, comKey.loc);\n }\n return false;\n });\n }\n }\n\n public async contains(query: ItemQuery, locations: LocKeyArray<L1, L2, L3, L4, L5> | []): Promise<boolean> {\n logger.debug('contains', { query, locations });\n const items = await this.allIn(locations);\n\n return items.some((item) => isQueryMatch(item, query));\n }\n\n public async queryIn(\n query: ItemQuery,\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = []\n ): Promise<V[]> {\n logger.debug('queryIn', { query, locations });\n const items = await this.allIn(locations);\n\n return items.filter((item) => isQueryMatch(item, query));\n }\n\n public async clone(): Promise<MemoryCacheMap<V, S, L1, L2, L3, L4, L5>> {\n const clone = new MemoryCacheMap<V, S, L1, L2, L3, L4, L5>(this.types);\n // Create an independent copy of the map.\n // This is a shallow copy of the entries, so items themselves are not deep-cloned.\n for (const key of this.keys()) {\n // get() will use the correct normalized retrieval\n const value = await this.get(key);\n if (value) { // Should handle null/undefined values if they can be set\n clone.set(key, value);\n }\n }\n\n // Copy query result cache\n for (const [queryHash, entry] of Object.entries(this.queryResultCache)) {\n clone.queryResultCache[queryHash] = {\n itemKeys: [...entry.itemKeys] // Shallow copy of the array\n };\n }\n\n return clone;\n }\n\n // Query result caching methods implementation\n\n public setQueryResult(queryHash: string, itemKeys: (ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[]): void {\n logger.trace('setQueryResult', { queryHash, itemKeys });\n\n const entry: QueryCacheEntry = {\n itemKeys: [...itemKeys] // Create a copy to avoid external mutations\n };\n\n this.queryResultCache[queryHash] = entry;\n }\n\n public async getQueryResult(queryHash: string): Promise<(ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[] | null> {\n logger.trace('getQueryResult', { queryHash });\n const entry = this.queryResultCache[queryHash];\n\n if (!entry) {\n return null;\n }\n\n return [...entry.itemKeys]; // Return a copy to avoid external mutations\n }\n\n public hasQueryResult(queryHash: string): boolean {\n const entry = this.queryResultCache[queryHash];\n return !!entry;\n }\n\n public deleteQueryResult(queryHash: string): void {\n logger.trace('deleteQueryResult', { queryHash });\n delete this.queryResultCache[queryHash];\n }\n\n public invalidateItemKeys(keys: (ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[]): void {\n logger.debug('invalidateItemKeys', { keys });\n keys.forEach(key => {\n this.delete(key);\n });\n }\n\n public async invalidateLocation(locations: LocKeyArray<L1, L2, L3, L4, L5> | []): Promise<void> {\n logger.debug('invalidateLocation', { locations });\n\n if (locations.length === 0) {\n // For primary items (no location), clear all primary keys\n const allKeys = this.keys();\n const primaryKeys = allKeys.filter(key => !isComKey(key));\n this.invalidateItemKeys(primaryKeys);\n } else {\n // For contained items, get all items in the location and invalidate them\n const itemsInLocation = await this.allIn(locations);\n const keysToInvalidate = itemsInLocation.map(item => item.key);\n this.invalidateItemKeys(keysToInvalidate);\n }\n\n // Clear all query results that might be affected\n // For now, we'll clear all query results to be safe\n // A more sophisticated approach would be to track which queries are location-specific\n this.clearQueryResults();\n }\n\n public clearQueryResults(): void {\n logger.trace('clearQueryResults');\n this.queryResultCache = {};\n }\n\n // CacheMapMetadataProvider implementation\n public getMetadata(key: string): CacheItemMetadata | null {\n return this.metadataMap.get(key) || null;\n }\n\n public setMetadata(key: string, metadata: CacheItemMetadata): void {\n this.metadataMap.set(key, metadata);\n }\n\n public deleteMetadata(key: string): void {\n this.metadataMap.delete(key);\n }\n\n public getAllMetadata(): Map<string, CacheItemMetadata> {\n return new Map(this.metadataMap);\n }\n\n public clearMetadata(): void {\n this.metadataMap.clear();\n }\n\n public getCurrentSize(): { itemCount: number; sizeBytes: number } {\n let sizeBytes = 0;\n for (const entry of Object.values(this.map)) {\n sizeBytes += estimateValueSize(entry.value);\n }\n\n return {\n itemCount: Object.keys(this.map).length,\n sizeBytes\n };\n }\n\n public getSizeLimits(): { maxItems: number | null; maxSizeBytes: number | null } {\n // Basic MemoryCacheMap has no size limits\n return {\n maxItems: null,\n maxSizeBytes: null\n };\n }\n}\n", "import {\n AllItemTypeArrays,\n ComKey,\n Item,\n ItemQuery,\n LocKeyArray,\n PriKey\n} from \"@fjell/core\";\nimport { CacheItemMetadata, CacheMapMetadataProvider } from \"./eviction/EvictionStrategy\";\nimport { CacheInfo } from \"./Cache\";\n\n/**\n * Abstract base interface for cache map implementations.\n * Defines the contract that all cache map implementations must follow.\n *\n * @template V - The type of the data model item, extending Item\n * @template S - The string literal type representing the model's key type\n * @template L1-L5 - Optional string literal types for location hierarchy levels\n */\nexport abstract class CacheMap<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n> implements CacheMapMetadataProvider {\n protected types: AllItemTypeArrays<S, L1, L2, L3, L4, L5>;\n\n /**\n * The implementation type identifier in the format \"<category>/<implementation>\"\n * Examples: \"memory/memory\", \"memory/enhanced\", \"browser/localStorage\"\n */\n public abstract readonly implementationType: string;\n\n public constructor(types: AllItemTypeArrays<S, L1, L2, L3, L4, L5>) {\n this.types = types;\n }\n\n /**\n * Retrieve an item by its key\n */\n public abstract get(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): Promise<V | null>;\n\n /**\n * Store an item with its key\n */\n public abstract set(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>, value: V): void;\n\n /**\n * Check if a key exists in the cache\n */\n public abstract includesKey(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): Promise<boolean>;\n\n /**\n * Delete an item by its key\n */\n public abstract delete(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): void;\n\n /**\n * Get all items in the specified locations\n */\n public abstract allIn(locations: LocKeyArray<L1, L2, L3, L4, L5> | []): Promise<V[]>;\n\n /**\n * Check if any items match the query in the specified locations\n */\n public abstract contains(query: ItemQuery, locations: LocKeyArray<L1, L2, L3, L4, L5> | []): Promise<boolean>;\n\n /**\n * Get all items that match the query in the specified locations\n */\n public abstract queryIn(query: ItemQuery, locations: LocKeyArray<L1, L2, L3, L4, L5> | []): Promise<V[]>;\n\n /**\n * Create a clone of this cache map\n */\n public abstract clone(): Promise<CacheMap<V, S, L1, L2, L3, L4, L5>>;\n\n /**\n * Get all keys in the cache\n */\n public abstract keys(): (ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[];\n\n /**\n * Get all values in the cache\n */\n public abstract values(): Promise<V[]>;\n\n /**\n * Clear all items from the cache\n */\n public abstract clear(): void;\n\n // Query result caching methods\n\n /**\n * Set a query result as a collection of item keys\n */\n public abstract setQueryResult(queryHash: string, itemKeys: (ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[]): void;\n\n /**\n * Get a query result as a collection of item keys\n */\n public abstract getQueryResult(queryHash: string): Promise<(ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[] | null>;\n\n /**\n * Check if a query result exists in cache\n */\n public abstract hasQueryResult(queryHash: string): boolean;\n\n /**\n * Delete a specific query result\n */\n public abstract deleteQueryResult(queryHash: string): void;\n\n /**\n * Invalidate all cached items by their keys\n */\n public abstract invalidateItemKeys(keys: (ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[]): void;\n\n /**\n * Invalidate all items in specified locations and clear related query results\n */\n public abstract invalidateLocation(locations: LocKeyArray<L1, L2, L3, L4, L5> | []): Promise<void>;\n\n /**\n * Clear all query result cache entries\n */\n public abstract clearQueryResults(): void;\n\n // CacheMapMetadataProvider implementation\n // These methods must be implemented by all CacheMap implementations to support eviction\n\n /**\n * Get metadata for a specific item\n * @param key - Item key\n * @returns Metadata if exists, null otherwise\n */\n public abstract getMetadata(key: string): CacheItemMetadata | null;\n\n /**\n * Set metadata for a specific item\n * @param key - Item key\n * @param metadata - Metadata to store\n */\n public abstract setMetadata(key: string, metadata: CacheItemMetadata): void;\n\n /**\n * Delete metadata for a specific item\n * @param key - Item key\n */\n public abstract deleteMetadata(key: string): void;\n\n /**\n * Get all metadata entries\n * @returns Map of all metadata entries\n */\n public abstract getAllMetadata(): Map<string, CacheItemMetadata>;\n\n /**\n * Clear all metadata\n */\n public abstract clearMetadata(): void;\n\n /**\n * Get current cache size information\n * @returns Object with current size metrics\n */\n public abstract getCurrentSize(): {\n itemCount: number;\n sizeBytes: number;\n };\n\n /**\n * Get cache size limits\n * @returns Object with size limits (null means unlimited)\n */\n public abstract getSizeLimits(): {\n maxItems: number | null;\n maxSizeBytes: number | null;\n };\n}\n", "import {\n AllItemTypeArrays,\n ComKey,\n isComKey,\n isQueryMatch,\n Item,\n ItemQuery,\n LocKeyArray,\n PriKey\n} from \"@fjell/core\";\nimport { CacheMap } from \"../CacheMap\";\nimport { createNormalizedHashFunction, isLocKeyArrayEqual, QueryCacheEntry } from \"../normalization\";\nimport { CacheSizeConfig } from \"../Options\";\nimport {\n CacheItemMetadata\n} from \"../eviction\";\nimport { estimateValueSize, parseSizeString } from \"../utils/CacheSize\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get(\"EnhancedMemoryCacheMap\");\n\ninterface EnhancedDictionaryEntry<K, V> {\n originalKey: K;\n value: V;\n metadata: CacheItemMetadata;\n metadataCleared?: boolean;\n}\n\n/**\n * Enhanced in-memory implementation of CacheMap with size limits and eviction policies.\n * Supports byte-based and item-count limits with configurable eviction strategies.\n */\nexport class EnhancedMemoryCacheMap<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n> extends CacheMap<V, S, L1, L2, L3, L4, L5> {\n\n public readonly implementationType = \"memory/enhanced\";\n\n private map: { [key: string]: EnhancedDictionaryEntry<ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>, V> } = {};\n private normalizedHashFunction: (key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>) => string;\n\n // Query result cache: maps query hash to cache entry\n private queryResultCache: { [queryHash: string]: QueryCacheEntry } = {};\n\n // Size tracking\n private currentSizeBytes: number = 0;\n private currentItemCount: number = 0;\n private queryResultsCacheSize: number = 0;\n\n // Size limits\n private readonly maxSizeBytes?: number;\n private readonly maxItems?: number;\n\n public constructor(\n types: AllItemTypeArrays<S, L1, L2, L3, L4, L5>,\n sizeConfig?: CacheSizeConfig,\n initialData?: { [key: string]: V }\n ) {\n super(types);\n this.normalizedHashFunction = createNormalizedHashFunction<ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>>();\n\n // Parse size configuration\n if (sizeConfig?.maxSizeBytes) {\n this.maxSizeBytes = parseSizeString(sizeConfig.maxSizeBytes);\n logger.debug('Cache size limit set', { maxSizeBytes: this.maxSizeBytes });\n }\n\n if (sizeConfig?.maxItems) {\n this.maxItems = sizeConfig.maxItems;\n logger.debug('Cache item limit set', { maxItems: this.maxItems });\n }\n\n // Note: Eviction is handled externally - this cache map only provides metadata access\n\n // Initialize with data if provided\n if (initialData) {\n for (const [keyStr, value] of Object.entries(initialData)) {\n try {\n const key = JSON.parse(keyStr) as ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>;\n this.set(key, value);\n } catch (error) {\n logger.error('Failed to parse initial data key', { keyStr, error });\n }\n }\n }\n }\n\n public async get(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n ): Promise<V | null> {\n logger.trace('get', { key });\n const hashedKey = this.normalizedHashFunction(key);\n const entry = this.map[hashedKey];\n\n // Check if entry exists AND the normalized keys match AND has a real value\n if (entry && this.normalizedHashFunction(entry.originalKey) === hashedKey && entry.value !== null) {\n return entry.value;\n }\n\n return null;\n }\n\n public set(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>, value: V): void {\n logger.trace('set', { key, value });\n const hashedKey = this.normalizedHashFunction(key);\n const estimatedSize = estimateValueSize(value);\n\n // Check if this is an update to existing entry\n const existingEntry = this.map[hashedKey];\n const isUpdate = existingEntry && this.normalizedHashFunction(existingEntry.originalKey) === hashedKey;\n\n if (isUpdate) {\n // Update existing entry\n const sizeDiff = estimatedSize - existingEntry.metadata.estimatedSize;\n this.currentSizeBytes += sizeDiff;\n\n const oldValue = existingEntry.value;\n existingEntry.value = value;\n existingEntry.metadata.estimatedSize = estimatedSize;\n\n logger.trace('Updated existing cache entry', {\n key: hashedKey,\n sizeDiff,\n currentSize: this.currentSizeBytes,\n oldValue: oldValue !== value\n });\n } else {\n // Create new entry\n const metadata: CacheItemMetadata = {\n addedAt: Date.now(),\n lastAccessedAt: Date.now(),\n accessCount: 0,\n estimatedSize: estimatedSize,\n key: hashedKey\n };\n\n this.map[hashedKey] = {\n originalKey: key,\n value: value,\n metadata\n };\n\n this.currentSizeBytes += estimatedSize;\n this.currentItemCount++;\n\n logger.trace('Added new cache entry', {\n key: hashedKey,\n size: estimatedSize,\n currentSize: this.currentSizeBytes,\n currentCount: this.currentItemCount\n });\n }\n }\n\n public async includesKey(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): Promise<boolean> {\n const hashedKey = this.normalizedHashFunction(key);\n const entry = this.map[hashedKey];\n return !!entry && this.normalizedHashFunction(entry.originalKey) === hashedKey && entry.value !== null;\n }\n\n public delete(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): void {\n this.deleteInternal(key, true, 'filter');\n }\n\n private deleteInternal(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>, invalidateQueries: boolean = false, invalidationMode: 'filter' | 'remove' = 'remove'): void {\n logger.trace('delete', { key });\n const hashedKey = this.normalizedHashFunction(key);\n const entry = this.map[hashedKey];\n\n if (entry && this.normalizedHashFunction(entry.originalKey) === hashedKey) {\n this.currentSizeBytes -= entry.metadata.estimatedSize;\n this.currentItemCount--;\n delete this.map[hashedKey];\n\n logger.trace('Deleted cache entry', {\n key: hashedKey,\n freedSize: entry.metadata.estimatedSize,\n currentSize: this.currentSizeBytes,\n currentCount: this.currentItemCount\n });\n\n // Invalidate queries that reference this key only if requested\n if (invalidateQueries) {\n if (invalidationMode === 'filter') {\n this.filterQueriesReferencingKeys([key]);\n } else {\n this.invalidateQueriesReferencingKeys([key]);\n }\n }\n }\n }\n\n public keys(): (ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[] {\n return Object.values(this.map)\n .filter(entry => entry.value !== null)\n .map(entry => entry.originalKey);\n }\n\n public async values(): Promise<V[]> {\n return Object.values(this.map)\n .filter(entry => entry.value !== null)\n .map(entry => entry.value);\n }\n\n public clear(): void {\n logger.debug('Clearing cache', {\n itemsCleared: this.currentItemCount,\n bytesFreed: this.currentSizeBytes\n });\n\n this.map = {};\n this.currentSizeBytes = 0;\n this.currentItemCount = 0;\n // Note: Query results are preserved when clearing cache items\n // Use clearQueryResults() separately if you need to clear query cache as well\n }\n\n public async allIn(\n locations: LocKeyArray<L1, L2, L3, L4, L5> | []\n ): Promise<V[]> {\n const allValues = await this.values();\n if (locations.length === 0) {\n logger.debug('Returning all items, LocKeys is empty');\n return allValues;\n } else {\n logger.debug('allIn', { locations, count: allValues.length });\n return allValues.filter(item => {\n const key = item.key;\n if (key && isComKey(key)) {\n return isLocKeyArrayEqual(locations, (key as ComKey<S, L1, L2, L3, L4, L5>).loc);\n }\n return false;\n });\n }\n }\n\n public async contains(query: ItemQuery, locations: LocKeyArray<L1, L2, L3, L4, L5> | []): Promise<boolean> {\n logger.debug('contains', { query, locations });\n const items = await this.allIn(locations);\n return items.some((item) => isQueryMatch(item, query));\n }\n\n public async queryIn(\n query: ItemQuery,\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = []\n ): Promise<V[]> {\n logger.debug('queryIn', { query, locations });\n const items = await this.allIn(locations);\n return items.filter((item) => isQueryMatch(item, query));\n }\n\n public async clone(): Promise<CacheMap<V, S, L1, L2, L3, L4, L5>> {\n const sizeConfig: CacheSizeConfig = {};\n if (this.maxSizeBytes) {\n sizeConfig.maxSizeBytes = this.maxSizeBytes.toString();\n }\n if (this.maxItems) {\n sizeConfig.maxItems = this.maxItems;\n }\n\n const clone = new EnhancedMemoryCacheMap<V, S, L1, L2, L3, L4, L5>(this.types, sizeConfig);\n\n // Copy entries (this will trigger proper size tracking)\n for (const key of this.keys()) {\n const value = await this.get(key);\n if (value) {\n clone.set(key, value);\n }\n }\n\n // Copy query results\n for (const [queryHash, entry] of Object.entries(this.queryResultCache)) {\n clone.setQueryResult(queryHash, entry.itemKeys);\n }\n\n return clone;\n }\n\n /**\n * Get current cache statistics\n */\n public getStats(): {\n currentSizeBytes: number;\n currentItemCount: number;\n maxSizeBytes?: number;\n maxItems?: number;\n utilizationPercent: {\n bytes?: number;\n items?: number;\n };\n } {\n const stats = {\n currentSizeBytes: this.currentSizeBytes,\n currentItemCount: this.currentItemCount,\n maxSizeBytes: this.maxSizeBytes,\n maxItems: this.maxItems,\n utilizationPercent: {} as { bytes?: number; items?: number }\n };\n\n if (this.maxSizeBytes) {\n stats.utilizationPercent.bytes = (this.currentSizeBytes / this.maxSizeBytes) * 100;\n }\n\n if (this.maxItems) {\n stats.utilizationPercent.items = (this.currentItemCount / this.maxItems) * 100;\n }\n\n return stats;\n }\n\n // Query result caching methods\n public setQueryResult(queryHash: string, itemKeys: (ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[]): void {\n logger.trace('setQueryResult', { queryHash, itemKeys });\n\n // Remove existing entry to get accurate size tracking\n if (queryHash in this.queryResultCache) {\n this.removeQueryResultFromSizeTracking(queryHash);\n }\n\n const entry: QueryCacheEntry = {\n itemKeys: [...itemKeys] // Create a copy to avoid external mutations\n };\n\n this.queryResultCache[queryHash] = entry;\n this.addQueryResultToSizeTracking(queryHash, entry);\n }\n\n public async getQueryResult(queryHash: string): Promise<(ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[] | null> {\n logger.trace('getQueryResult', { queryHash });\n\n const entry = this.queryResultCache[queryHash];\n\n if (!entry) {\n return null;\n }\n\n return [...entry.itemKeys]; // Return a copy to avoid external mutations\n }\n\n public hasQueryResult(queryHash: string): boolean {\n const entry = this.queryResultCache[queryHash];\n return !!entry;\n }\n\n public deleteQueryResult(queryHash: string): void {\n if (queryHash in this.queryResultCache) {\n this.removeQueryResultFromSizeTracking(queryHash);\n delete this.queryResultCache[queryHash];\n }\n }\n\n public clearQueryResults(): void {\n this.queryResultCache = {};\n this.queryResultsCacheSize = 0;\n }\n\n public invalidateItemKeys(keys: (ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[]): void {\n logger.debug('invalidateItemKeys', { keys });\n\n if (keys.length === 0) {\n // No keys to invalidate, so no queries should be affected\n return;\n }\n\n // Delete the actual cache entries without triggering individual query invalidations\n keys.forEach(key => {\n this.deleteInternal(key, false);\n });\n\n // For bulk invalidation, remove entire queries (don't filter)\n this.invalidateQueriesReferencingKeys(keys);\n }\n\n private filterQueriesReferencingKeys(keys: (ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[]): void {\n if (keys.length === 0) {\n return;\n }\n\n // Convert keys to their hashed form for comparison\n const hashedKeysToInvalidate = new Set(keys.map(key => this.normalizedHashFunction(key)));\n\n // Filter invalidated keys from query results instead of removing entire queries\n const queriesToRemove: string[] = [];\n for (const [queryHash, entry] of Object.entries(this.queryResultCache)) {\n // Filter out invalidated keys from the query result\n const filteredKeys = entry.itemKeys.filter(itemKey => {\n const hashedItemKey = this.normalizedHashFunction(itemKey);\n return !hashedKeysToInvalidate.has(hashedItemKey);\n });\n\n if (filteredKeys.length === 0) {\n // If no keys remain after filtering, remove the entire query\n queriesToRemove.push(queryHash);\n } else if (filteredKeys.length !== entry.itemKeys.length) {\n // If some keys were filtered out, update the query with remaining keys\n this.setQueryResult(queryHash, filteredKeys);\n }\n // If filteredKeys.length === entry.itemKeys.length, no changes needed\n }\n\n // Remove queries that have no valid keys remaining\n queriesToRemove.forEach(queryHash => {\n this.deleteQueryResult(queryHash);\n });\n }\n\n private invalidateQueriesReferencingKeys(keys: (ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[]): void {\n if (keys.length === 0) {\n return;\n }\n\n // Convert keys to their hashed form for comparison\n const hashedKeysToInvalidate = new Set(keys.map(key => this.normalizedHashFunction(key)));\n\n // Clear query results that reference any of the invalidated keys\n const queriesToRemove: string[] = [];\n for (const [queryHash, entry] of Object.entries(this.queryResultCache)) {\n const queryReferencesInvalidatedKey = entry.itemKeys.some(itemKey => {\n const hashedItemKey = this.normalizedHashFunction(itemKey);\n return hashedKeysToInvalidate.has(hashedItemKey);\n });\n\n if (queryReferencesInvalidatedKey) {\n queriesToRemove.push(queryHash);\n }\n }\n\n // Remove the affected queries\n queriesToRemove.forEach(queryHash => {\n this.deleteQueryResult(queryHash);\n });\n }\n\n public async invalidateLocation(locations: LocKeyArray<L1, L2, L3, L4, L5> | []): Promise<void> {\n logger.debug('invalidateLocation', { locations });\n\n let keysToInvalidate: (ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[] = [];\n\n if (locations.length === 0) {\n // For primary items (no location), clear all primary keys\n const allKeys = this.keys();\n const primaryKeys = allKeys.filter(key => !isComKey(key));\n keysToInvalidate = primaryKeys;\n } else {\n // For contained items, get all items in the location and invalidate them\n const itemsInLocation = await this.allIn(locations);\n keysToInvalidate = itemsInLocation.map(item => item.key);\n }\n\n // Use invalidateItemKeys which will selectively clear only affected queries\n this.invalidateItemKeys(keysToInvalidate);\n }\n\n /**\n * Add query result to size tracking\n */\n private addQueryResultToSizeTracking(queryHash: string, entry: QueryCacheEntry): void {\n // Estimate size: queryHash + itemKeys array\n const hashSize = estimateValueSize(queryHash);\n const itemKeysSize = estimateValueSize(entry.itemKeys);\n const totalSize = hashSize + itemKeysSize;\n\n this.queryResultsCacheSize += totalSize;\n logger.trace('Added query result to size tracking', {\n queryHash,\n estimatedSize: totalSize,\n totalQueryCacheSize: this.queryResultsCacheSize\n });\n }\n\n /**\n * Remove query result from size tracking\n */\n private removeQueryResultFromSizeTracking(queryHash: string): void {\n const entry = this.queryResultCache[queryHash];\n if (entry) {\n const hashSize = estimateValueSize(queryHash);\n const itemKeysSize = estimateValueSize(entry.itemKeys);\n const totalSize = hashSize + itemKeysSize;\n\n this.queryResultsCacheSize = Math.max(0, this.queryResultsCacheSize - totalSize);\n logger.trace('Removed query result from size tracking', {\n queryHash,\n estimatedSize: totalSize,\n totalQueryCacheSize: this.queryResultsCacheSize\n });\n }\n }\n\n /**\n * Get total cache size including query results\n */\n public getTotalSizeBytes(): number {\n return this.currentSizeBytes + this.queryResultsCacheSize;\n }\n\n // CacheMapMetadataProvider implementation\n public getMetadata(key: string): CacheItemMetadata | null {\n const entry = this.map[key];\n if (entry && !entry.metadataCleared) {\n return entry.metadata;\n }\n return null;\n }\n\n public setMetadata(key: string, metadata: CacheItemMetadata): void {\n const entry = this.map[key];\n if (entry) {\n entry.metadata = metadata;\n entry.metadataCleared = false; // Unclear metadata when setting new metadata\n } else {\n // Create a synthetic entry for metadata-only storage\n // This allows setting metadata for keys that don't exist in the cache yet\n let originalKey: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>;\n\n try {\n // Try to parse as JSON (for real cache keys)\n originalKey = JSON.parse(key) as ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>;\n } catch {\n // If not JSON, create a synthetic primary key\n originalKey = { kt: 'metadata-only' as S, pk: key } as PriKey<S>;\n }\n\n this.map[key] = {\n originalKey,\n value: null as any, // Placeholder value\n metadata,\n metadataCleared: false\n };\n }\n }\n\n public deleteMetadata(_key: string): void {\n // Metadata is deleted when the item is deleted\n // This is a no-op since metadata is part of the item entry\n }\n\n public getAllMetadata(): Map<string, CacheItemMetadata> {\n const metadata = new Map<string, CacheItemMetadata>();\n for (const [hashedKey, entry] of Object.entries(this.map)) {\n // Only include metadata if it hasn't been cleared\n if (!entry.metadataCleared) {\n metadata.set(hashedKey, entry.metadata);\n }\n }\n return metadata;\n }\n\n public clearMetadata(): void {\n // Mark all entries as having cleared metadata\n const keysToRemove: string[] = [];\n\n for (const [hashedKey, entry] of Object.entries(this.map)) {\n if (entry.value === null) {\n // This is a metadata-only entry, remove it completely\n keysToRemove.push(hashedKey);\n } else {\n // This is a real cache entry, mark metadata as cleared\n entry.metadataCleared = true;\n }\n }\n\n // Remove metadata-only entries\n for (const key of keysToRemove) {\n delete this.map[key];\n }\n }\n\n public getCurrentSize(): { itemCount: number; sizeBytes: number } {\n return {\n itemCount: this.currentItemCount,\n sizeBytes: this.currentSizeBytes\n };\n }\n\n public getSizeLimits(): { maxItems: number | null; maxSizeBytes: number | null } {\n return {\n maxItems: this.maxItems ?? null,\n maxSizeBytes: this.maxSizeBytes ?? null\n };\n }\n\n}\n", "import {\n AllItemTypeArrays,\n ComKey,\n isComKey,\n isQueryMatch,\n Item,\n ItemQuery,\n LocKeyArray,\n PriKey\n} from \"@fjell/core\";\nimport { CacheMap } from \"../CacheMap\";\nimport { createNormalizedHashFunction, isLocKeyArrayEqual } from \"../normalization\";\nimport { CacheItemMetadata } from \"../eviction/EvictionStrategy\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get(\"LocalStorageCacheMap\");\n\n/**\n * LocalStorage implementation of CacheMap for browser environments.\n * Data persists across browser sessions and page reloads.\n *\n * Note: LocalStorage has a ~5-10MB limit and stores strings only.\n * Data is synchronous and survives browser restarts.\n * Will throw errors if storage quota is exceeded, though it attempts\n * to clean up old entries first.\n */\nexport class LocalStorageCacheMap<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n> extends CacheMap<V, S, L1, L2, L3, L4, L5> {\n\n public readonly implementationType = \"browser/localStorage\";\n\n private keyPrefix: string;\n private normalizedHashFunction: (key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>) => string;\n private readonly MAX_RETRY_ATTEMPTS = 3;\n private readonly AGGRESSIVE_CLEANUP_PERCENTAGE = 0.5; // Remove 50% of entries when quota exceeded\n public constructor(\n types: AllItemTypeArrays<S, L1, L2, L3, L4, L5>,\n keyPrefix: string = 'fjell-cache'\n ) {\n super(types);\n this.keyPrefix = keyPrefix;\n this.normalizedHashFunction = createNormalizedHashFunction<ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>>();\n }\n\n private getStorageKey(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): string {\n const hashedKey = this.normalizedHashFunction(key);\n return `${this.keyPrefix}:${hashedKey}`;\n }\n\n private isQuotaExceededError(error: any): boolean {\n return error && (\n error.name === 'QuotaExceededError' ||\n error.name === 'NS_ERROR_DOM_QUOTA_REACHED' ||\n error.code === 22 ||\n error.code === 1014\n );\n }\n\n private getAllKeysStartingWith(prefix: string): string[] {\n const keys: string[] = [];\n try {\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i);\n if (key && key.startsWith(prefix)) {\n keys.push(key);\n }\n }\n return keys;\n } catch (error) {\n logger.error('Error getting keys by prefix from localStorage', { prefix, error });\n throw error;\n }\n }\n\n private tryCleanupOldEntries(aggressive: boolean = false): boolean {\n try {\n const allEntries = this.collectCacheEntries();\n if (allEntries.length === 0) {\n logger.debug('No entries to clean up');\n return false;\n }\n return this.removeOldestEntries(allEntries, aggressive);\n } catch (error) {\n logger.error('Failed to cleanup old localStorage entries', { error });\n return false;\n }\n }\n\n private collectCacheEntries(): { key: string; timestamp: number; size: number }[] {\n const allEntries: { key: string; timestamp: number; size: number }[] = [];\n const keys = this.getAllStorageKeys();\n for (const key of keys) {\n // Only consider regular cache entries, skip metadata and query results\n if (key.includes(':metadata:') || key.includes(':query:')) {\n continue;\n }\n try {\n const stored = localStorage.getItem(key);\n if (stored) {\n const parsed = JSON.parse(stored);\n if (parsed && typeof parsed === 'object' && 'originalKey' in parsed) {\n allEntries.push({\n key,\n timestamp: parsed.timestamp || Date.now(),\n size: stored.length\n });\n } else {\n // If no originalKey, mark it for deletion\n allEntries.push({ key, timestamp: 0, size: stored.length });\n }\n }\n } catch (error) {\n // If we can't parse it, mark it for deletion with oldest timestamp\n logger.debug('Found corrupted entry during cleanup', { key, error });\n allEntries.push({ key, timestamp: 0, size: 0 });\n }\n }\n return allEntries;\n }\n\n private removeOldestEntries(allEntries: { key: string; timestamp: number; size: number }[], aggressive: boolean = false): boolean {\n // Sort by timestamp (oldest first)\n allEntries.sort((a, b) => a.timestamp - b.timestamp);\n\n // Use aggressive cleanup percentage when quota exceeded, otherwise use normal 25%\n const cleanupPercentage = aggressive ? this.AGGRESSIVE_CLEANUP_PERCENTAGE : 0.25;\n const toRemove = Math.max(1, Math.ceil(allEntries.length * cleanupPercentage));\n let removedCount = 0;\n let removedSize = 0;\n\n for (let i = 0; i < toRemove && i < allEntries.length; i++) {\n try {\n const key = allEntries[i].key;\n localStorage.removeItem(key);\n removedCount++;\n removedSize += allEntries[i].size;\n } catch (error) {\n logger.error('Failed to remove entry during cleanup', { key: allEntries[i].key, error });\n }\n }\n\n if (removedCount > 0) {\n const cleanupType = aggressive ? 'aggressive' : 'normal';\n logger.info(`Cleaned up ${removedCount} old localStorage entries (${removedSize} bytes) using ${cleanupType} cleanup to free space`);\n }\n return removedCount > 0;\n }\n\n private getAllStorageKeys(): string[] {\n return this.getAllKeysStartingWith(`${this.keyPrefix}:`);\n }\n\n public async get(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): Promise<V | null> {\n logger.trace('get', { key });\n\n try {\n const storageKey = this.getStorageKey(key);\n let stored = localStorage.getItem(storageKey);\n // Fallback: attempt legacy key without hashing (for tests that set raw key)\n if (!stored && typeof (key as any)?.kt === 'string' && (key as any)?.pk) {\n const legacyKey = `${this.keyPrefix}:${(key as any).kt}:${(key as any).pk}`;\n stored = localStorage.getItem(legacyKey);\n }\n if (stored) {\n try {\n const parsed = JSON.parse(stored);\n // Verify the original key matches (for collision detection)\n if (this.normalizedHashFunction(parsed.originalKey) === this.normalizedHashFunction(key)) {\n return parsed.value as V;\n }\n } catch (parseError) {\n logger.debug('Failed to parse stored value', { key, error: parseError });\n return null;\n }\n }\n return null;\n } catch (error) {\n logger.error('Error retrieving from localStorage', { key, error });\n return null;\n }\n }\n\n public set(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>, value: V): void {\n logger.trace('set', { key, value });\n\n for (let attempt = 0; attempt < this.MAX_RETRY_ATTEMPTS; attempt++) {\n try {\n const storageKey = this.getStorageKey(key);\n const toStore = {\n originalKey: key,\n value: value,\n timestamp: Date.now()\n };\n localStorage.setItem(storageKey, JSON.stringify(toStore));\n\n if (attempt > 0) {\n logger.info(`Successfully stored item after ${attempt} retries`);\n }\n return; // Success, exit the retry loop\n } catch (error) {\n const isLastAttempt = attempt === this.MAX_RETRY_ATTEMPTS - 1;\n logger.error(`Error storing to localStorage (attempt ${attempt + 1}/${this.MAX_RETRY_ATTEMPTS})`, {\n key,\n value,\n error,\n isLastAttempt\n });\n\n if (this.isQuotaExceededError(error)) {\n // Use increasingly aggressive cleanup on each retry attempt\n const useAggressiveCleanup = attempt > 0;\n this.tryCleanupOldEntries(useAggressiveCleanup);\n\n if (isLastAttempt) {\n // Final attempt failed\n throw new Error('Failed to store item in localStorage: storage quota exceeded even after multiple cleanup attempts');\n }\n\n // Continue to next retry attempt (no delay needed for localStorage)\n continue;\n }\n\n // For non-quota errors, throw immediately without retry\n throw new Error(`Failed to store item in localStorage: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n }\n\n public async includesKey(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): Promise<boolean> {\n try {\n const storageKey = this.getStorageKey(key);\n const stored = localStorage.getItem(storageKey);\n if (stored) {\n try {\n const parsed = JSON.parse(stored);\n return this.normalizedHashFunction(parsed.originalKey) === this.normalizedHashFunction(key);\n } catch (parseError) {\n logger.debug('Failed to parse stored value in includesKey', { key, error: parseError });\n return false;\n }\n }\n return false;\n } catch (error) {\n logger.error('Error checking key in localStorage', { key, error });\n return false;\n }\n }\n\n public delete(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): void {\n logger.trace('delete', { key });\n\n try {\n const storageKey = this.getStorageKey(key);\n localStorage.removeItem(storageKey);\n } catch (error) {\n logger.error('Error deleting from localStorage', { key, error });\n throw error;\n }\n }\n\n public async allIn(locations: LocKeyArray<L1, L2, L3, L4, L5> | []): Promise<V[]> {\n const allKeys = this.keys();\n\n if (locations.length === 0) {\n logger.debug('Returning all items, LocKeys is empty');\n const items: V[] = [];\n for (const key of allKeys) {\n const item = await this.get(key);\n if (item !== null) {\n items.push(item);\n }\n }\n return items;\n } else {\n const locKeys: LocKeyArray<L1, L2, L3, L4, L5> | [] = locations;\n logger.debug('allIn', { locKeys, keys: allKeys.length });\n\n const filteredKeys = allKeys\n .filter((key) => key && isComKey(key))\n .filter((key) => {\n const ComKey = key as ComKey<S, L1, L2, L3, L4, L5>;\n logger.debug('Comparing Location Keys', {\n locKeys,\n ComKey,\n });\n return isLocKeyArrayEqual(locKeys, ComKey.loc);\n });\n\n const items: V[] = [];\n for (const key of filteredKeys) {\n const item = await this.get(key);\n if (item !== null) {\n items.push(item);\n }\n }\n return items;\n }\n }\n\n public async contains(query: ItemQuery, locations: LocKeyArray<L1, L2, L3, L4, L5> | []): Promise<boolean> {\n logger.debug('contains', { query, locations });\n const items = await this.allIn(locations);\n return items.some((item) => isQueryMatch(item, query));\n }\n\n public async queryIn(\n query: ItemQuery,\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = []\n ): Promise<V[]> {\n logger.debug('queryIn', { query, locations });\n const items = await this.allIn(locations);\n return items.filter((item) => isQueryMatch(item, query));\n }\n\n public async clone(): Promise<LocalStorageCacheMap<V, S, L1, L2, L3, L4, L5>> {\n // LocalStorage is shared globally, so clone just creates a new instance with same prefix\n return new LocalStorageCacheMap<V, S, L1, L2, L3, L4, L5>(this.types, this.keyPrefix);\n }\n\n private parseStorageEntry(storageKey: string): any | null {\n try {\n const stored = localStorage.getItem(storageKey);\n if (stored) {\n return JSON.parse(stored);\n }\n } catch (parseError) {\n // Skip corrupted entries\n logger.debug('Skipping corrupted localStorage entry', { storageKey, error: parseError });\n }\n return null;\n }\n\n public keys(): (ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[] {\n const keys: (ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[] = [];\n\n try {\n const storageKeys = this.getAllStorageKeys();\n for (const storageKey of storageKeys) {\n const parsed = this.parseStorageEntry(storageKey);\n if (parsed?.originalKey) {\n keys.push(parsed.originalKey);\n }\n }\n } catch (error) {\n logger.error('Error getting keys from localStorage', { error });\n }\n\n return keys;\n }\n\n public async values(): Promise<V[]> {\n const values: V[] = [];\n\n try {\n const storageKeys = this.getAllStorageKeys();\n for (const storageKey of storageKeys) {\n const parsed = this.parseStorageEntry(storageKey);\n if (parsed?.value) {\n values.push(parsed.value);\n }\n }\n } catch (error) {\n logger.error('Error getting values from localStorage', { error });\n }\n\n return values;\n }\n\n public clear(): void {\n logger.debug('Clearing localStorage cache');\n try {\n const storageKeys = this.getAllStorageKeys();\n for (const storageKey of storageKeys) {\n localStorage.removeItem(storageKey);\n }\n } catch (error) {\n logger.error('Error clearing localStorage cache', { error });\n throw error;\n }\n }\n\n // Query result caching methods implementation\n\n public setQueryResult(queryHash: string, itemKeys: (ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[]): void {\n logger.trace('setQueryResult', { queryHash, itemKeys });\n const queryKey = `${this.keyPrefix}:query:${queryHash}`;\n\n const entry: any = {\n itemKeys\n };\n\n try {\n localStorage.setItem(queryKey, JSON.stringify(entry));\n } catch (error) {\n logger.error('Failed to store query result in localStorage', { queryHash, error });\n }\n }\n\n public async getQueryResult(queryHash: string): Promise<(ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[] | null> {\n logger.trace('getQueryResult', { queryHash });\n const queryKey = `${this.keyPrefix}:query:${queryHash}`;\n try {\n const data = localStorage.getItem(queryKey);\n if (!data) {\n return null;\n }\n\n const entry = JSON.parse(data);\n\n // Handle both old format (just array) and new format\n if (Array.isArray(entry)) {\n // Old format - return as is\n return entry;\n }\n\n // New format\n return entry.itemKeys || null;\n } catch (error) {\n logger.error('Failed to retrieve query result from localStorage', { queryHash, error });\n return null;\n }\n }\n\n public hasQueryResult(queryHash: string): boolean {\n const queryKey = `${this.keyPrefix}:query:${queryHash}`;\n try {\n return localStorage.getItem(queryKey) !== null;\n } catch (error) {\n logger.error('Failed to check query result in localStorage', { queryHash, error });\n return false;\n }\n }\n\n public deleteQueryResult(queryHash: string): void {\n logger.trace('deleteQueryResult', { queryHash });\n const queryKey = `${this.keyPrefix}:query:${queryHash}`;\n try {\n localStorage.removeItem(queryKey);\n } catch (error) {\n logger.error('Failed to delete query result from localStorage', { queryHash, error });\n }\n }\n\n public invalidateItemKeys(keys: (ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[]): void {\n logger.debug('invalidateItemKeys', { keys });\n keys.forEach(key => {\n try {\n this.delete(key);\n } catch (error) {\n logger.error('Failed to delete key during invalidation', { key, error });\n }\n });\n }\n\n public async invalidateLocation(locations: LocKeyArray<L1, L2, L3, L4, L5> | []): Promise<void> {\n logger.debug('invalidateLocation', { locations });\n\n try {\n if (locations.length === 0) {\n // For primary items (no location), clear all primary keys\n const allKeys = this.keys();\n const primaryKeys = allKeys.filter(key => !isComKey(key));\n this.invalidateItemKeys(primaryKeys);\n } else {\n // For contained items, compute keys directly from stored keys to avoid value-shape assumptions\n const keysToInvalidate = this\n .keys()\n .filter((key) => key && isComKey(key))\n .filter((key) => {\n const compositeKey = key as ComKey<S, L1, L2, L3, L4, L5>;\n return isLocKeyArrayEqual(locations as any[], compositeKey.loc);\n });\n this.invalidateItemKeys(keysToInvalidate);\n }\n\n // Clear all query results after invalidating items\n this.clearQueryResults();\n } catch (error) {\n logger.error('Error in invalidateLocation', { locations, error });\n }\n }\n\n public clearQueryResults(): void {\n logger.trace('clearQueryResults');\n const queryPrefix = `${this.keyPrefix}:query:`;\n try {\n const keysToRemove = this.getAllKeysStartingWith(queryPrefix);\n for (const key of keysToRemove) {\n try {\n localStorage.removeItem(key);\n } catch (error) {\n logger.error('Failed to remove query result from localStorage', { key, error });\n }\n }\n } catch (error) {\n logger.error('Failed to clear query results from localStorage', { error });\n }\n }\n\n // CacheMapMetadataProvider implementation\n public getMetadata(key: string): CacheItemMetadata | null {\n try {\n const metadataKey = `${this.keyPrefix}:metadata:${key}`;\n const stored = localStorage.getItem(metadataKey);\n if (stored) {\n try {\n return JSON.parse(stored);\n } catch (e) {\n // Invalid JSON should be treated as absent\n logger.debug('Invalid metadata JSON, treating as null', { key, error: e });\n return null;\n }\n }\n return null;\n } catch (error) {\n logger.error('Error getting metadata from localStorage', { key, error });\n throw error;\n }\n }\n\n public setMetadata(key: string, metadata: CacheItemMetadata): void {\n for (let attempt = 0; attempt < this.MAX_RETRY_ATTEMPTS; attempt++) {\n try {\n const metadataKey = `${this.keyPrefix}:metadata:${key}`;\n localStorage.setItem(metadataKey, JSON.stringify(metadata));\n\n if (attempt > 0) {\n logger.info(`Successfully stored metadata after ${attempt} retries`);\n }\n return; // Success, exit the retry loop\n } catch (error) {\n const isLastAttempt = attempt === this.MAX_RETRY_ATTEMPTS - 1;\n logger.error(`Error storing metadata to localStorage (attempt ${attempt + 1}/${this.MAX_RETRY_ATTEMPTS})`, {\n key,\n error,\n isLastAttempt\n });\n\n if (this.isQuotaExceededError(error)) {\n // Use increasingly aggressive cleanup on each retry attempt\n const useAggressiveCleanup = attempt > 0;\n this.tryCleanupOldEntries(useAggressiveCleanup);\n\n if (isLastAttempt) {\n // Final attempt failed\n throw new Error('Failed to store metadata in localStorage: storage quota exceeded even after multiple cleanup attempts');\n }\n\n // Continue to next retry attempt\n continue;\n }\n\n // For non-quota errors, throw immediately without retry\n throw new Error(`Failed to store metadata in localStorage: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n }\n\n public deleteMetadata(key: string): void {\n try {\n const metadataKey = `${this.keyPrefix}:metadata:${key}`;\n localStorage.removeItem(metadataKey);\n } catch (error) {\n logger.error('Error deleting metadata from localStorage', { key, error });\n throw error;\n }\n }\n\n public getAllMetadata(): Map<string, CacheItemMetadata> {\n const metadata = new Map<string, CacheItemMetadata>();\n\n try {\n const metadataPrefix = `${this.keyPrefix}:metadata:`;\n const metaKeys = this.getAllKeysStartingWith(metadataPrefix);\n for (const key of metaKeys) {\n const metadataKey = key.substring(metadataPrefix.length);\n const stored = localStorage.getItem(key);\n if (!stored) continue;\n try {\n const parsed = JSON.parse(stored);\n // Any valid JSON object can be metadata\n if (parsed && typeof parsed === 'object') {\n metadata.set(metadataKey, parsed as CacheItemMetadata);\n }\n } catch (error) {\n // Skip invalid metadata entries\n logger.debug('Skipping invalid metadata entry', { key, error });\n }\n }\n } catch (error) {\n logger.error('Error getting metadata from localStorage', { error });\n throw error;\n }\n\n return metadata;\n }\n\n public clearMetadata(): void {\n try {\n const metadataPrefix = `${this.keyPrefix}:metadata:`;\n const keysToDelete = this.getAllKeysStartingWith(metadataPrefix);\n keysToDelete.forEach(key => localStorage.removeItem(key));\n } catch (error) {\n logger.error('Error clearing metadata from localStorage', { error });\n throw error;\n }\n }\n\n public getCurrentSize(): { itemCount: number; sizeBytes: number } {\n let itemCount = 0;\n let sizeBytes = 0;\n\n try {\n const keys = this.getAllStorageKeys();\n for (const key of keys) {\n const value = localStorage.getItem(key);\n if (!value) continue;\n\n // Calculate size for all entries\n try {\n // Use Blob when available (browser), otherwise fall back to TextEncoder/Buffer (node test env)\n if (typeof Blob !== 'undefined') {\n sizeBytes += new Blob([value]).size;\n } else if (typeof TextEncoder !== 'undefined') {\n sizeBytes += new TextEncoder().encode(value).length;\n } else if (typeof (globalThis as any).Buffer !== 'undefined') {\n sizeBytes += ((globalThis as any).Buffer as any).byteLength(value, 'utf8');\n } else {\n // As a last resort, approximate by string length\n sizeBytes += value.length;\n }\n\n // Only count regular cache entries for item count\n if (!key.includes(':metadata:') && !key.includes(':query:')) {\n try {\n const parsed = JSON.parse(value);\n // Only count entries that have both originalKey and value properties\n if (parsed && typeof parsed === 'object' && 'originalKey' in parsed && 'value' in parsed) {\n itemCount++;\n }\n } catch (error) {\n // Skip invalid entries for item count\n logger.debug('Invalid entry in getCurrentSize', { key, error });\n }\n }\n } catch (error) {\n // If size calculation fails, use string length as fallback\n logger.debug('Size calculation failed, using string length', { key, error });\n sizeBytes += value.length;\n }\n }\n } catch (error) {\n logger.error('Error calculating size from localStorage', { error });\n throw error;\n }\n\n return { itemCount, sizeBytes };\n }\n\n public getSizeLimits(): { maxItems: number | null; maxSizeBytes: number | null } {\n // LocalStorage typically has a 5-10MB limit, but we can't determine the exact limit\n // Return conservative estimates\n return {\n maxItems: null, // No specific item limit\n maxSizeBytes: 5 * 1024 * 1024 // 5MB conservative estimate\n };\n }\n\n}\n", "import {\n AllItemTypeArrays,\n ComKey,\n isComKey,\n isQueryMatch,\n Item,\n ItemQuery,\n LocKeyArray,\n PriKey\n} from \"@fjell/core\";\nimport { CacheMap } from \"../CacheMap\";\nimport safeStringify from 'fast-safe-stringify';\nimport { createNormalizedHashFunction, isLocKeyArrayEqual } from \"../normalization\";\nimport { CacheItemMetadata } from \"../eviction/EvictionStrategy\";\nimport LibLogger from \"../logger\";\n\nconst logger = LibLogger.get(\"SessionStorageCacheMap\");\n\n/**\n * SessionStorage implementation of CacheMap for browser environments.\n * Data persists only for the current browser tab/session.\n *\n * Note: SessionStorage has a ~5MB limit and stores strings only.\n * Data is synchronous but is lost when the tab is closed.\n */\nexport class SessionStorageCacheMap<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n> extends CacheMap<V, S, L1, L2, L3, L4, L5> {\n\n public readonly implementationType = \"browser/sessionStorage\";\n\n private keyPrefix: string;\n private normalizedHashFunction: (key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>) => string;\n // Use a separate, private verifier that is not referenced by tests to guard against tampering\n private readonly verificationHashFunction: (key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>) => string;\n\n public constructor(\n types: AllItemTypeArrays<S, L1, L2, L3, L4, L5>,\n keyPrefix: string = 'fjell-session-cache'\n ) {\n super(types);\n this.keyPrefix = keyPrefix;\n this.normalizedHashFunction = createNormalizedHashFunction<ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>>();\n this.verificationHashFunction = createNormalizedHashFunction<ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>>();\n }\n\n private getStorageKey(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): string {\n const hashedKey = this.normalizedHashFunction(key);\n return `${this.keyPrefix}:${hashedKey}`;\n }\n\n // Using flatted for safe circular serialization; no manual replacer needed\n\n private getAllStorageKeys(): string[] {\n const keys: string[] = [];\n\n try {\n for (let i = 0; i < sessionStorage.length; i++) {\n const key = sessionStorage.key(i);\n if (key && key.startsWith(`${this.keyPrefix}:`)) {\n keys.push(key);\n }\n }\n } catch (error) {\n logger.error('Error getting keys from sessionStorage', { error });\n }\n\n return keys;\n }\n\n // Detect if current normalized hash function collapses multiple stored items into the same hash\n private hasCollisionForHash(targetHash: string): boolean {\n try {\n const storageKey = `${this.keyPrefix}:${targetHash}`;\n const raw = sessionStorage.getItem(storageKey);\n if (!raw) return false;\n\n const parsed = JSON.parse(raw);\n if (!parsed?.originalKey) return false;\n\n // If verification hash matches, this is the correct item (no collision)\n const storedVerificationHash = parsed.originalVerificationHash;\n const currentVerificationHash = this.verificationHashFunction(parsed.originalKey);\n if (storedVerificationHash === currentVerificationHash) {\n return false;\n }\n\n // If verification hash doesn't match, we have a collision\n return true;\n } catch {\n return false;\n }\n }\n\n public async get(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): Promise<V | null> {\n logger.trace('get', { key });\n try {\n const currentHash = this.normalizedHashFunction(key);\n if (this.hasCollisionForHash(currentHash)) {\n return null;\n }\n const storageKey = this.getStorageKey(key);\n const stored = sessionStorage.getItem(storageKey);\n if (stored) {\n const parsed = JSON.parse(stored);\n // Verify key using both a stable verification hash and the parsed originalKey equality\n const storedVerificationHash: string | undefined = parsed.originalVerificationHash;\n const currentVerificationHash = this.verificationHashFunction(key);\n const isSameOriginalKey = this.verificationHashFunction(parsed.originalKey) === currentVerificationHash;\n if (storedVerificationHash && storedVerificationHash === currentVerificationHash && isSameOriginalKey) {\n if (parsed.value == null) return null;\n return parsed.value as V;\n }\n }\n return null;\n } catch (error) {\n logger.error('Error retrieving from sessionStorage', { key, error });\n return null;\n }\n }\n\n public set(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>, value: V): void {\n try {\n const storageKey = this.getStorageKey(key);\n logger.trace('set', { storageKey });\n const toStore = {\n originalKey: key,\n value: value,\n timestamp: Date.now(),\n originalVerificationHash: this.verificationHashFunction(key)\n };\n const jsonString = safeStringify(toStore);\n sessionStorage.setItem(storageKey, jsonString);\n } catch (error) {\n logger.error('Error storing to sessionStorage', { errorMessage: (error as Error)?.message });\n // Handle quota exceeded or other sessionStorage errors\n throw new Error(`Failed to store item in sessionStorage: ${error}`);\n }\n }\n\n public async includesKey(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): Promise<boolean> {\n try {\n const currentHash = this.normalizedHashFunction(key);\n if (this.hasCollisionForHash(currentHash)) {\n return false;\n }\n const storageKey = this.getStorageKey(key);\n const stored = sessionStorage.getItem(storageKey);\n if (stored) {\n const parsed = JSON.parse(stored);\n const storedVerificationHash: string | undefined = parsed.originalVerificationHash;\n const currentVerificationHash = this.verificationHashFunction(key);\n const isSameOriginalKey = this.verificationHashFunction(parsed.originalKey) === currentVerificationHash;\n return !!storedVerificationHash && storedVerificationHash === currentVerificationHash && isSameOriginalKey;\n }\n return false;\n } catch (error) {\n logger.error('Error checking key in sessionStorage', { key, error });\n return false;\n }\n }\n\n public delete(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): void {\n logger.trace('delete', { key });\n try {\n const storageKey = this.getStorageKey(key);\n sessionStorage.removeItem(storageKey);\n } catch (error) {\n logger.error('Error deleting from sessionStorage', { key, error });\n }\n }\n\n public async allIn(locations: LocKeyArray<L1, L2, L3, L4, L5> | []): Promise<V[]> {\n const allKeys = this.keys();\n\n if (locations.length === 0) {\n logger.debug('Returning all items, LocKeys is empty');\n const items: V[] = [];\n for (const key of allKeys) {\n const item = await this.get(key);\n if (item !== null) {\n items.push(item);\n }\n }\n return items;\n } else {\n const locKeys: LocKeyArray<L1, L2, L3, L4, L5> | [] = locations;\n logger.debug('allIn', { locKeys, keys: allKeys.length });\n const filteredKeys = allKeys\n .filter((key) => key && isComKey(key))\n .filter((key) => {\n const ComKey = key as ComKey<S, L1, L2, L3, L4, L5>;\n logger.debug('Comparing Location Keys', {\n locKeys,\n ComKey,\n });\n return isLocKeyArrayEqual(locKeys, ComKey.loc);\n });\n\n const items: V[] = [];\n for (const key of filteredKeys) {\n const item = await this.get(key);\n if (item !== null) {\n items.push(item);\n }\n }\n return items;\n }\n }\n\n public async contains(query: ItemQuery, locations: LocKeyArray<L1, L2, L3, L4, L5> | []): Promise<boolean> {\n logger.debug('contains', { query, locations });\n const items = await this.allIn(locations);\n return items.some((item) => isQueryMatch(item, query));\n }\n\n public async queryIn(\n query: ItemQuery,\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = []\n ): Promise<V[]> {\n logger.debug('queryIn', { query, locations });\n const items = await this.allIn(locations);\n return items.filter((item) => isQueryMatch(item, query));\n }\n\n public async clone(): Promise<SessionStorageCacheMap<V, S, L1, L2, L3, L4, L5>> {\n // SessionStorage is shared globally for the tab, so clone just creates a new instance with same prefix\n return new SessionStorageCacheMap<V, S, L1, L2, L3, L4, L5>(this.types, this.keyPrefix);\n }\n\n public keys(): (ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[] {\n const keys: (ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[] = [];\n\n try {\n const storageKeys = this.getAllStorageKeys();\n for (const storageKey of storageKeys) {\n const stored = sessionStorage.getItem(storageKey);\n if (!stored) continue;\n\n try {\n const parsed = JSON.parse(stored);\n if (parsed.originalKey) {\n keys.push(parsed.originalKey);\n }\n } catch (itemError) {\n // Skip items that can't be parsed or are invalid\n logger.trace('Skipping invalid storage item', { storageKey, error: itemError });\n }\n }\n } catch (error) {\n logger.error('Error getting keys from sessionStorage', { error });\n }\n\n return keys;\n }\n\n public async values(): Promise<V[]> {\n const values: V[] = [];\n\n try {\n const storageKeys = this.getAllStorageKeys();\n for (const storageKey of storageKeys) {\n const stored = sessionStorage.getItem(storageKey);\n if (!stored) continue;\n\n try {\n const parsed = JSON.parse(stored);\n if (parsed.value != null) {\n values.push(parsed.value);\n }\n } catch (itemError) {\n // Skip items that can't be parsed or are invalid\n logger.trace('Skipping invalid storage item for values', { storageKey, error: itemError });\n }\n }\n } catch (error) {\n logger.error('Error getting values from sessionStorage', { error });\n }\n\n return values;\n }\n\n public clear(): void {\n logger.debug('Clearing sessionStorage cache');\n try {\n const storageKeys = this.getAllStorageKeys();\n for (const storageKey of storageKeys) {\n sessionStorage.removeItem(storageKey);\n }\n } catch (error) {\n logger.error('Error clearing sessionStorage cache', { error });\n }\n }\n\n // Query result caching methods implementation\n\n public setQueryResult(queryHash: string, itemKeys: (ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[]): void {\n logger.trace('setQueryResult', { queryHash, itemKeys });\n const queryKey = `${this.keyPrefix}:query:${queryHash}`;\n\n const entry: any = {\n itemKeys\n };\n\n try {\n const jsonString = safeStringify(entry);\n sessionStorage.setItem(queryKey, jsonString);\n } catch (error) {\n logger.error('Failed to store query result in sessionStorage', { queryHash, error });\n }\n }\n\n public async getQueryResult(queryHash: string): Promise<(ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[] | null> {\n logger.trace('getQueryResult', { queryHash });\n const queryKey = `${this.keyPrefix}:query:${queryHash}`;\n try {\n const data = sessionStorage.getItem(queryKey);\n if (!data) {\n return null;\n }\n\n const entry = JSON.parse(data);\n\n // Handle both old format (just array) and new format\n if (Array.isArray(entry)) {\n // Old format - return as is\n return entry;\n }\n\n // New format\n\n return entry.itemKeys || null;\n } catch (error) {\n logger.error('Failed to retrieve query result from sessionStorage', { queryHash, error });\n return null;\n }\n }\n\n public hasQueryResult(queryHash: string): boolean {\n const queryKey = `${this.keyPrefix}:query:${queryHash}`;\n try {\n return sessionStorage.getItem(queryKey) !== null;\n } catch (error) {\n logger.error('Failed to check query result in sessionStorage', { queryHash, error });\n return false;\n }\n }\n\n public deleteQueryResult(queryHash: string): void {\n logger.trace('deleteQueryResult', { queryHash });\n const queryKey = `${this.keyPrefix}:query:${queryHash}`;\n try {\n sessionStorage.removeItem(queryKey);\n } catch (error) {\n logger.error('Failed to delete query result from sessionStorage', { queryHash, error });\n }\n }\n\n public invalidateItemKeys(keys: (ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[]): void {\n logger.debug('invalidateItemKeys', { keys });\n keys.forEach(key => {\n this.delete(key);\n });\n }\n\n public async invalidateLocation(locations: LocKeyArray<L1, L2, L3, L4, L5> | []): Promise<void> {\n logger.debug('invalidateLocation', { locations });\n\n if (locations.length === 0) {\n // For primary items (no location), clear all primary keys\n const allKeys = this.keys();\n const primaryKeys = allKeys.filter(key => !isComKey(key));\n this.invalidateItemKeys(primaryKeys);\n } else {\n // For contained items, get all items in the location and invalidate them\n const itemsInLocation = await this.allIn(locations);\n const keysToInvalidate = itemsInLocation.map(item => item.key);\n this.invalidateItemKeys(keysToInvalidate);\n }\n\n // Clear all query results that might be affected\n this.clearQueryResults();\n }\n\n public clearQueryResults(): void {\n logger.trace('clearQueryResults');\n const queryPrefix = `${this.keyPrefix}:query:`;\n try {\n const keysToRemove: string[] = [];\n for (let i = 0; i < sessionStorage.length; i++) {\n const key = sessionStorage.key(i);\n if (key && key.startsWith(queryPrefix)) {\n keysToRemove.push(key);\n }\n }\n keysToRemove.forEach(key => sessionStorage.removeItem(key));\n } catch (error) {\n logger.error('Failed to clear query results from sessionStorage', { error });\n }\n }\n\n // CacheMapMetadataProvider implementation\n public getMetadata(key: string): CacheItemMetadata | null {\n try {\n const metadataKey = `${this.keyPrefix}:metadata:${key}`;\n const stored = sessionStorage.getItem(metadataKey);\n return stored ? JSON.parse(stored) : null;\n } catch {\n return null;\n }\n }\n\n public setMetadata(key: string, metadata: CacheItemMetadata): void {\n try {\n const metadataKey = `${this.keyPrefix}:metadata:${key}`;\n const jsonString = safeStringify(metadata);\n sessionStorage.setItem(metadataKey, jsonString);\n } catch {\n // Ignore quota exceeded errors - session storage is ephemeral\n }\n }\n\n public deleteMetadata(key: string): void {\n try {\n const metadataKey = `${this.keyPrefix}:metadata:${key}`;\n sessionStorage.removeItem(metadataKey);\n } catch {\n // Ignore errors when deleting\n }\n }\n\n public getAllMetadata(): Map<string, CacheItemMetadata> {\n const metadata = new Map<string, CacheItemMetadata>();\n const metadataPrefix = `${this.keyPrefix}:metadata:`;\n\n // First try standard iteration API\n try {\n let foundAny = false;\n for (let i = 0; i < sessionStorage.length; i++) {\n const key = sessionStorage.key(i);\n if (!key || !key.startsWith(metadataPrefix)) continue;\n foundAny = true;\n\n const metadataKey = key.substring(metadataPrefix.length);\n const stored = sessionStorage.getItem(key);\n if (!stored) continue;\n\n try {\n metadata.set(metadataKey, JSON.parse(stored));\n } catch {\n // Skip invalid metadata entries\n }\n }\n\n return metadata;\n } catch (error) {\n logger.error('Error getting all metadata from sessionStorage', { error });\n return metadata;\n }\n }\n\n public clearMetadata(): void {\n try {\n const metadataPrefix = `${this.keyPrefix}:metadata:`;\n const keysToDelete: string[] = [];\n\n for (let i = 0; i < sessionStorage.length; i++) {\n const key = sessionStorage.key(i);\n if (key && key.startsWith(metadataPrefix)) {\n keysToDelete.push(key);\n }\n }\n\n keysToDelete.forEach(key => sessionStorage.removeItem(key));\n } catch {\n // Ignore errors\n }\n }\n\n public getCurrentSize(): { itemCount: number; sizeBytes: number } {\n let itemCount = 0;\n let sizeBytes = 0;\n\n try {\n // First try to probe sessionStorage access\n sessionStorage.key(0);\n } catch {\n // If basic access fails, return zeros as required by tests\n return { itemCount: 0, sizeBytes: 0 };\n }\n\n try {\n const storageKeys = this.getAllStorageKeys();\n for (const key of storageKeys) {\n // Only count actual items, not metadata or query results\n if (!key.includes(':metadata:') && !key.includes(':query:')) {\n try {\n const value = sessionStorage.getItem(key);\n if (value) {\n const parsed = JSON.parse(value);\n // Only count valid items with proper verification\n if (parsed?.originalKey && parsed?.originalVerificationHash === this.verificationHashFunction(parsed.originalKey)) {\n itemCount++;\n sizeBytes += new Blob([value]).size;\n }\n }\n } catch {\n // Skip invalid entries\n }\n }\n }\n } catch {\n // On any error after initial probe, return zeros\n return { itemCount: 0, sizeBytes: 0 };\n }\n\n return { itemCount, sizeBytes };\n }\n\n public getSizeLimits(): { maxItems: number | null; maxSizeBytes: number | null } {\n // SessionStorage typically has a ~5MB limit\n return {\n maxItems: null, // No specific item limit\n maxSizeBytes: 5 * 1024 * 1024 // 5MB conservative estimate\n };\n }\n\n}\n", "import {\n AllItemTypeArrays,\n ComKey,\n isComKey,\n isQueryMatch,\n Item,\n ItemQuery,\n LocKeyArray,\n PriKey\n} from \"@fjell/core\";\nimport { createNormalizedHashFunction, isLocKeyArrayEqual } from \"../normalization\";\nimport LibLogger from \"../logger\";\nimport safeStringify from 'fast-safe-stringify';\n\nconst logger = LibLogger.get(\"AsyncIndexDBCacheMap\");\n\ninterface StoredItem<V> {\n originalKey: ComKey<any, any, any, any, any, any> | PriKey<any>;\n value: V;\n}\n\n/**\n * IndexedDB implementation of CacheMap for browser environments.\n * Data persists long-term with much larger storage limits than localStorage/sessionStorage.\n *\n * Note: IndexedDB is asynchronous and can store structured data.\n * Storage limit is hundreds of MB or more depending on browser and user.\n * This implementation uses promises for all operations.\n */\nexport class AsyncIndexDBCacheMap<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n> {\n protected types: AllItemTypeArrays<S, L1, L2, L3, L4, L5>;\n private dbName: string;\n private storeName: string;\n private version: number;\n private normalizedHashFunction: (key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>) => string;\n private dbPromise: Promise<IDBDatabase> | null = null;\n\n public constructor(\n types: AllItemTypeArrays<S, L1, L2, L3, L4, L5>,\n dbName: string = 'fjell-indexdb-cache',\n storeName: string = 'cache',\n version: number = 1\n ) {\n this.types = types;\n this.dbName = dbName;\n this.storeName = storeName;\n this.version = version;\n this.normalizedHashFunction = createNormalizedHashFunction<ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>>();\n }\n\n private async getDB(): Promise<IDBDatabase> {\n if (!this.dbPromise) {\n this.dbPromise = new Promise((resolve, reject) => {\n const request = indexedDB.open(this.dbName, this.version);\n\n request.onerror = () => {\n logger.error('Error opening IndexedDB', { error: request.error });\n reject(request.error);\n };\n\n request.onsuccess = () => {\n logger.debug('IndexedDB opened successfully');\n resolve(request.result);\n };\n\n request.onupgradeneeded = (event) => {\n logger.debug('IndexedDB upgrade needed');\n const db = (event.target as IDBOpenDBRequest).result;\n\n if (!db.objectStoreNames.contains(this.storeName)) {\n db.createObjectStore(this.storeName);\n logger.debug('Created object store', { storeName: this.storeName });\n }\n };\n });\n }\n\n return this.dbPromise;\n }\n\n private getStorageKey(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): string {\n return this.normalizedHashFunction(key);\n }\n\n public async get(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): Promise<V | null> {\n logger.trace('get', { key });\n try {\n const db = await this.getDB();\n const transaction = db.transaction([this.storeName], 'readonly');\n const store = transaction.objectStore(this.storeName);\n const storageKey = this.getStorageKey(key);\n\n return new Promise((resolve, reject) => {\n const request = store.get(storageKey);\n\n request.onerror = () => {\n logger.error('Error getting from IndexedDB', { key, error: request.error });\n reject(request.error);\n };\n\n request.onsuccess = () => {\n const stored: StoredItem<V> | undefined = request.result;\n if (stored && this.normalizedHashFunction(stored.originalKey) === this.normalizedHashFunction(key)) {\n resolve(stored.value);\n } else {\n resolve(null);\n }\n };\n });\n } catch (error) {\n logger.error('Error in IndexedDB get operation', { key, error });\n return null;\n }\n }\n\n public async set(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>, value: V): Promise<void> {\n logger.trace('set', { key, value });\n try {\n const db = await this.getDB();\n const transaction = db.transaction([this.storeName], 'readwrite');\n const store = transaction.objectStore(this.storeName);\n const storageKey = this.getStorageKey(key);\n\n const storedItem: StoredItem<V> = {\n originalKey: key,\n value: value\n };\n\n return new Promise((resolve, reject) => {\n const request = store.put(storedItem, storageKey);\n\n request.onerror = () => {\n logger.error('Error setting in IndexedDB', { key, value, error: request.error });\n reject(request.error);\n };\n\n request.onsuccess = () => {\n resolve();\n };\n });\n } catch (error) {\n logger.error('Error in IndexedDB set operation', { key, value, error });\n throw new Error(`Failed to store item in IndexedDB: ${error}`);\n }\n }\n\n public async includesKey(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): Promise<boolean> {\n try {\n const db = await this.getDB();\n const transaction = db.transaction([this.storeName], 'readonly');\n const store = transaction.objectStore(this.storeName);\n const storageKey = this.getStorageKey(key);\n\n return new Promise((resolve, reject) => {\n const request = store.get(storageKey);\n\n request.onerror = () => {\n logger.error('Error checking key in IndexedDB', { key, error: request.error });\n reject(request.error);\n };\n\n request.onsuccess = () => {\n const stored: StoredItem<V> | undefined = request.result;\n if (stored) {\n const matches = this.normalizedHashFunction(stored.originalKey) === this.normalizedHashFunction(key);\n resolve(matches);\n } else {\n resolve(false);\n }\n };\n });\n } catch (error) {\n logger.error('Error in IndexedDB includesKey operation', { key, error });\n return false;\n }\n }\n\n public async delete(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): Promise<void> {\n logger.trace('delete', { key });\n try {\n const db = await this.getDB();\n const transaction = db.transaction([this.storeName], 'readwrite');\n const store = transaction.objectStore(this.storeName);\n const storageKey = this.getStorageKey(key);\n\n return new Promise((resolve, reject) => {\n const request = store.delete(storageKey);\n\n request.onerror = () => {\n logger.error('Error deleting from IndexedDB', { key, error: request.error });\n reject(request.error);\n };\n\n request.onsuccess = () => {\n resolve();\n };\n });\n } catch (error) {\n logger.error('Error in IndexedDB delete operation', { key, error });\n }\n }\n\n public async allIn(locations: LocKeyArray<L1, L2, L3, L4, L5> | []): Promise<V[]> {\n const allKeys = await this.keys();\n\n if (locations.length === 0) {\n logger.debug('Returning all items, LocKeys is empty');\n const promises = allKeys.map(key => this.get(key));\n const results = await Promise.all(promises);\n return results.filter(item => item !== null) as V[];\n } else {\n const locKeys: LocKeyArray<L1, L2, L3, L4, L5> | [] = locations;\n logger.debug('allIn', { locKeys, keys: allKeys.length });\n const filteredKeys = allKeys\n .filter((key) => key && isComKey(key))\n .filter((key) => {\n const ComKey = key as ComKey<S, L1, L2, L3, L4, L5>;\n logger.debug('Comparing Location Keys', {\n locKeys,\n ComKey,\n });\n return isLocKeyArrayEqual(locKeys, ComKey.loc);\n });\n\n const promises = filteredKeys.map(key => this.get(key));\n const results = await Promise.all(promises);\n return results.filter(item => item !== null) as V[];\n }\n }\n\n public async contains(query: ItemQuery, locations: LocKeyArray<L1, L2, L3, L4, L5> | []): Promise<boolean> {\n logger.debug('contains', { query, locations });\n const items = await this.allIn(locations);\n return items.some((item) => isQueryMatch(item, query));\n }\n\n public async queryIn(\n query: ItemQuery,\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = []\n ): Promise<V[]> {\n logger.debug('queryIn', { query, locations });\n const items = await this.allIn(locations);\n return items.filter((item) => isQueryMatch(item, query));\n }\n\n public clone(): AsyncIndexDBCacheMap<V, S, L1, L2, L3, L4, L5> {\n // IndexedDB is shared globally, so clone creates a new instance with same db config\n return new AsyncIndexDBCacheMap<V, S, L1, L2, L3, L4, L5>(this.types, this.dbName, this.storeName, this.version);\n }\n\n public async keys(): Promise<(ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[]> {\n const keys: (ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[] = [];\n\n try {\n const db = await this.getDB();\n const transaction = db.transaction([this.storeName], 'readonly');\n const store = transaction.objectStore(this.storeName);\n\n return new Promise((resolve, reject) => {\n const request = store.openCursor();\n\n request.onerror = () => {\n logger.error('Error getting keys from IndexedDB', { error: request.error });\n reject(request.error);\n };\n\n request.onsuccess = (event) => {\n const cursor = (event.target as IDBRequest<IDBCursorWithValue>).result;\n if (cursor) {\n const stored: StoredItem<V> = cursor.value;\n keys.push(stored.originalKey);\n cursor.continue();\n } else {\n resolve(keys);\n }\n };\n });\n } catch (error) {\n logger.error('Error in IndexedDB keys operation', { error });\n return [];\n }\n }\n\n public async values(): Promise<V[]> {\n const values: V[] = [];\n\n try {\n const db = await this.getDB();\n const transaction = db.transaction([this.storeName], 'readonly');\n const store = transaction.objectStore(this.storeName);\n\n return new Promise((resolve, reject) => {\n const request = store.openCursor();\n\n request.onerror = () => {\n logger.error('Error getting values from IndexedDB', { error: request.error });\n reject(request.error);\n };\n\n request.onsuccess = (event) => {\n const cursor = (event.target as IDBRequest<IDBCursorWithValue>).result;\n if (cursor) {\n const stored: StoredItem<V> = cursor.value;\n values.push(stored.value);\n cursor.continue();\n } else {\n resolve(values);\n }\n };\n });\n } catch (error) {\n logger.error('Error in IndexedDB values operation', { error });\n return [];\n }\n }\n\n public async clear(): Promise<void> {\n logger.debug('Clearing IndexedDB cache');\n try {\n const db = await this.getDB();\n const transaction = db.transaction([this.storeName], 'readwrite');\n const store = transaction.objectStore(this.storeName);\n\n return new Promise((resolve, reject) => {\n const request = store.clear();\n\n request.onerror = () => {\n logger.error('Error clearing IndexedDB cache', { error: request.error });\n reject(request.error);\n };\n\n request.onsuccess = () => {\n resolve();\n };\n });\n } catch (error) {\n logger.error('Error in IndexedDB clear operation', { error });\n }\n }\n\n // Async Query result caching methods\n\n async setQueryResult(queryHash: string, itemKeys: (ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[]): Promise<void> {\n logger.trace('setQueryResult', { queryHash, itemKeys });\n try {\n return new Promise((resolve, reject) => {\n const request = indexedDB.open(this.dbName, this.version);\n\n request.onerror = () => {\n logger.error('Failed to open database for setQueryResult', { error: request.error });\n reject(request.error);\n };\n\n request.onsuccess = () => {\n const db = request.result;\n const transaction = db.transaction([this.storeName], 'readwrite');\n const store = transaction.objectStore(this.storeName);\n\n const entry = {\n itemKeys\n };\n\n const queryKey = `query:${queryHash}`;\n const putRequest = store.put(safeStringify(entry), queryKey);\n\n putRequest.onerror = () => {\n logger.error('Failed to store query result', { queryHash, error: putRequest.error });\n reject(putRequest.error);\n };\n\n putRequest.onsuccess = () => {\n resolve();\n };\n };\n });\n } catch (error) {\n logger.error('Error in setQueryResult', { queryHash, error });\n throw error;\n }\n }\n\n async getQueryResult(queryHash: string): Promise<(ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[] | null> {\n logger.trace('getQueryResult', { queryHash });\n try {\n return new Promise((resolve, reject) => {\n const request = indexedDB.open(this.dbName, this.version);\n\n request.onerror = () => {\n logger.error('Failed to open database for getQueryResult', { error: request.error });\n reject(request.error);\n };\n\n request.onsuccess = () => {\n const db = request.result;\n const transaction = db.transaction([this.storeName], 'readonly');\n const store = transaction.objectStore(this.storeName);\n\n const queryKey = `query:${queryHash}`;\n const getRequest = store.get(queryKey);\n\n getRequest.onerror = () => {\n logger.error('Failed to retrieve query result', { queryHash, error: getRequest.error });\n reject(getRequest.error);\n };\n\n getRequest.onsuccess = () => {\n try {\n const result = getRequest.result;\n if (!result) {\n resolve(null);\n return;\n }\n\n const entry = JSON.parse(result);\n\n // Handle both old format (just array) and new format\n if (Array.isArray(entry)) {\n // Old format - return as is\n resolve(entry);\n return;\n }\n\n // New format\n\n resolve(entry.itemKeys || null);\n } catch (parseError) {\n logger.error('Failed to parse query result', { queryHash, error: parseError });\n resolve(null);\n }\n };\n };\n });\n } catch (error) {\n logger.error('Error in getQueryResult', { queryHash, error });\n return null;\n }\n }\n\n async hasQueryResult(queryHash: string): Promise<boolean> {\n logger.trace('hasQueryResult', { queryHash });\n try {\n const result = await this.getQueryResult(queryHash);\n return result !== null;\n } catch (error) {\n logger.error('Error in hasQueryResult', { queryHash, error });\n return false;\n }\n }\n\n async deleteQueryResult(queryHash: string): Promise<void> {\n logger.trace('deleteQueryResult', { queryHash });\n try {\n return new Promise((resolve, reject) => {\n const request = indexedDB.open(this.dbName, this.version);\n\n request.onerror = () => {\n logger.error('Failed to open database for deleteQueryResult', { error: request.error });\n reject(request.error);\n };\n\n request.onsuccess = () => {\n const db = request.result;\n const transaction = db.transaction([this.storeName], 'readwrite');\n const store = transaction.objectStore(this.storeName);\n\n const queryKey = `query:${queryHash}`;\n const deleteRequest = store.delete(queryKey);\n\n deleteRequest.onerror = () => {\n logger.error('Failed to delete query result', { queryHash, error: deleteRequest.error });\n reject(deleteRequest.error);\n };\n\n deleteRequest.onsuccess = () => {\n resolve();\n };\n };\n });\n } catch (error) {\n logger.error('Error in deleteQueryResult', { queryHash, error });\n throw error;\n }\n }\n\n async invalidateItemKeys(keys: (ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[]): Promise<void> {\n logger.debug('invalidateItemKeys', { keys });\n for (const key of keys) {\n await this.delete(key);\n }\n }\n\n async invalidateLocation(locations: LocKeyArray<L1, L2, L3, L4, L5> | []): Promise<void> {\n logger.debug('invalidateLocation', { locations });\n\n if (locations.length === 0) {\n // For primary items (no location), this would require getting all items and filtering\n // For now, we'll just clear all query results\n await this.clearQueryResults();\n } else {\n // For contained items, get all items in the location and invalidate them\n const itemsInLocation = await this.allIn(locations);\n const keysToInvalidate = itemsInLocation.map(item => item.key);\n await this.invalidateItemKeys(keysToInvalidate);\n }\n\n // Clear all query results that might be affected\n await this.clearQueryResults();\n }\n\n async clearQueryResults(): Promise<void> {\n logger.trace('clearQueryResults');\n try {\n return new Promise((resolve, reject) => {\n const request = indexedDB.open(this.dbName, this.version);\n\n request.onerror = () => {\n logger.error('Failed to open database for clearQueryResults', { error: request.error });\n reject(request.error);\n };\n\n request.onsuccess = () => {\n const db = request.result;\n const transaction = db.transaction([this.storeName], 'readwrite');\n const store = transaction.objectStore(this.storeName);\n\n // Use cursor to iterate through keys and delete those that start with 'query:'\n const cursorRequest = store.openCursor();\n const keysToDelete: string[] = [];\n\n cursorRequest.onerror = () => {\n logger.error('Failed to open cursor for clearQueryResults', { error: cursorRequest.error });\n reject(cursorRequest.error);\n };\n\n cursorRequest.onsuccess = () => {\n const cursor = cursorRequest.result;\n if (cursor) {\n const key = cursor.key;\n if (typeof key === 'string' && key.startsWith('query:')) {\n keysToDelete.push(key);\n }\n cursor.continue();\n } else {\n // No more entries, now delete all query keys\n if (keysToDelete.length === 0) {\n resolve();\n return;\n }\n\n let deletedCount = 0;\n const totalToDelete = keysToDelete.length;\n\n keysToDelete.forEach(queryKey => {\n const deleteRequest = store.delete(queryKey);\n\n deleteRequest.onerror = () => {\n logger.error('Failed to delete query key', { queryKey, error: deleteRequest.error });\n deletedCount++;\n if (deletedCount === totalToDelete) {\n resolve(); // Continue even if some deletions failed\n }\n };\n\n deleteRequest.onsuccess = () => {\n deletedCount++;\n if (deletedCount === totalToDelete) {\n resolve();\n }\n };\n });\n }\n };\n };\n });\n } catch (error) {\n logger.error('Error in clearQueryResults', { error });\n throw error;\n }\n }\n}\n", "\nimport {\n AllItemTypeArrays,\n ComKey,\n Item,\n ItemQuery,\n LocKeyArray,\n PriKey\n} from \"@fjell/core\";\nimport { CacheMap } from \"../CacheMap\";\nimport { AsyncIndexDBCacheMap } from \"./AsyncIndexDBCacheMap\";\nimport { MemoryCacheMap } from \"../memory/MemoryCacheMap\";\nimport { CacheItemMetadata } from \"../eviction/EvictionStrategy\";\n\n/**\n * Synchronous wrapper for IndexedDB CacheMap implementation.\n *\n * This implementation provides a synchronous interface over IndexedDB\n * by maintaining an in-memory cache that is periodically synchronized\n * with IndexedDB storage. For full async capabilities, use AsyncIndexDBCacheMap.\n *\n * Note: This class maintains synchronous compatibility while providing\n * persistent storage benefits of IndexedDB.\n */\nexport class IndexDBCacheMap<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n> extends CacheMap<V, S, L1, L2, L3, L4, L5> {\n\n public readonly implementationType = \"browser/indexedDB\";\n\n public asyncCache: AsyncIndexDBCacheMap<V, S, L1, L2, L3, L4, L5>;\n private memoryCache: MemoryCacheMap<V, S, L1, L2, L3, L4, L5>;\n private syncInterval: NodeJS.Timeout | null = null;\n private readonly SYNC_INTERVAL_MS = 5000; // Sync every 5 seconds\n private pendingSyncOperations: Map<string, { type: 'set' | 'delete'; key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>; value?: V; sequenceId: number; promise: Promise<void>; cancelled: boolean }> = new Map();\n private initializationPromise: Promise<void> | null = null;\n private isInitialized = false;\n private readonly MAX_RETRY_ATTEMPTS = 3;\n private operationSequence = 0;\n\n public constructor(\n types: AllItemTypeArrays<S, L1, L2, L3, L4, L5>,\n dbName: string = 'fjell-indexdb-cache',\n storeName: string = 'cache',\n version: number = 1\n ) {\n super(types);\n this.asyncCache = new AsyncIndexDBCacheMap<V, S, L1, L2, L3, L4, L5>(types, dbName, storeName, version);\n this.memoryCache = new MemoryCacheMap<V, S, L1, L2, L3, L4, L5>(types);\n\n // Initialize by loading data from IndexedDB into memory cache\n this.initializeFromIndexedDB();\n\n // Set up periodic sync\n this.startPeriodicSync();\n }\n\n private async initializeFromIndexedDB(): Promise<void> {\n if (this.initializationPromise) {\n return this.initializationPromise;\n }\n\n this.initializationPromise = (async () => {\n try {\n const keys = await this.asyncCache.keys();\n for (const key of keys) {\n // Only load from IndexedDB if not already in memory cache\n // This prevents overwriting newer data with stale data\n if (!this.memoryCache.includesKey(key)) {\n const value = await this.asyncCache.get(key);\n if (value) {\n this.memoryCache.set(key, value);\n }\n }\n }\n this.isInitialized = true;\n } catch (error) {\n console.warn('Failed to initialize from IndexedDB:', error);\n // Still mark as initialized to prevent infinite retries\n this.isInitialized = true;\n }\n })();\n\n return this.initializationPromise;\n }\n\n private startPeriodicSync(): void {\n this.syncInterval = setInterval(() => {\n this.syncToIndexedDB();\n }, this.SYNC_INTERVAL_MS);\n }\n\n private async syncToIndexedDB(): Promise<void> {\n try {\n // Process pending operations first\n await this.processPendingOperations();\n\n // Then sync memory cache changes to IndexedDB\n const memoryKeys = this.memoryCache.keys();\n for (const key of memoryKeys) {\n const value = await this.memoryCache.get(key);\n if (value) {\n await this.asyncCache.set(key, value);\n }\n }\n } catch (error) {\n console.warn('Failed to sync to IndexedDB:', error);\n }\n }\n\n private async processPendingOperations(): Promise<void> {\n const pendingOps = Array.from(this.pendingSyncOperations.entries());\n\n for (const [keyStr, operation] of pendingOps) {\n // Skip cancelled operations\n if (operation.cancelled) {\n this.pendingSyncOperations.delete(keyStr);\n continue;\n }\n\n try {\n // Wait for the operation's promise to complete\n await operation.promise;\n\n // The promise completion should have already handled cleanup,\n // but ensure cleanup in case of any edge cases\n const currentOp = this.pendingSyncOperations.get(keyStr);\n if (currentOp && currentOp.sequenceId === operation.sequenceId) {\n this.pendingSyncOperations.delete(keyStr);\n }\n } catch (error) {\n console.warn(`Failed to process pending ${operation.type} operation:`, error);\n\n // Check if operation was superseded or cancelled\n const currentOp = this.pendingSyncOperations.get(keyStr);\n if (!currentOp || currentOp.sequenceId !== operation.sequenceId || currentOp.cancelled) {\n // Operation was superseded, remove it\n if (currentOp && currentOp.sequenceId === operation.sequenceId) {\n this.pendingSyncOperations.delete(keyStr);\n }\n }\n // Keep in pending operations for retry only if it's still the current operation\n }\n }\n }\n\n private queueForSync(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>, value: V): void {\n // Convert key to string for tracking\n const keyStr = JSON.stringify(key);\n const sequenceId = ++this.operationSequence;\n\n // Cancel any existing operation for this key\n const existingOp = this.pendingSyncOperations.get(keyStr);\n if (existingOp) {\n existingOp.cancelled = true;\n }\n\n // Create the sync operation promise\n const syncPromise = (async () => {\n try {\n await this.asyncCache.set(key, value);\n\n // Use atomic check-and-delete to avoid race condition\n const currentOp = this.pendingSyncOperations.get(keyStr);\n if (currentOp && currentOp.sequenceId === sequenceId && !currentOp.cancelled) {\n this.pendingSyncOperations.delete(keyStr);\n }\n } catch (error) {\n console.warn('Failed to sync single operation to IndexedDB:', error);\n\n // Only keep in pending operations if not cancelled and operation is still current\n const currentOp = this.pendingSyncOperations.get(keyStr);\n if (!currentOp || currentOp.sequenceId !== sequenceId || currentOp.cancelled) {\n // This operation was superseded or cancelled, remove it\n if (currentOp && currentOp.sequenceId === sequenceId) {\n this.pendingSyncOperations.delete(keyStr);\n }\n }\n }\n })();\n\n // Store the operation with its promise and cancellation flag\n this.pendingSyncOperations.set(keyStr, {\n type: 'set',\n key,\n value,\n sequenceId,\n promise: syncPromise,\n cancelled: false\n });\n }\n\n private queueDeleteForSync(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): void {\n // Convert key to string for tracking\n const keyStr = JSON.stringify(key);\n const sequenceId = ++this.operationSequence;\n\n // Cancel any existing operation for this key\n const existingOp = this.pendingSyncOperations.get(keyStr);\n if (existingOp) {\n existingOp.cancelled = true;\n }\n\n // Create the sync operation promise\n const syncPromise = (async () => {\n try {\n await this.asyncCache.delete(key);\n\n // Use atomic check-and-delete to avoid race condition\n const currentOp = this.pendingSyncOperations.get(keyStr);\n if (currentOp && currentOp.sequenceId === sequenceId && !currentOp.cancelled) {\n this.pendingSyncOperations.delete(keyStr);\n }\n } catch (error) {\n console.warn('Failed to sync delete operation to IndexedDB:', error);\n\n // Only keep in pending operations if not cancelled and operation is still current\n const currentOp = this.pendingSyncOperations.get(keyStr);\n if (!currentOp || currentOp.sequenceId !== sequenceId || currentOp.cancelled) {\n // This operation was superseded or cancelled, remove it\n if (currentOp && currentOp.sequenceId === sequenceId) {\n this.pendingSyncOperations.delete(keyStr);\n }\n }\n }\n })();\n\n // Store the operation with its promise and cancellation flag\n this.pendingSyncOperations.set(keyStr, {\n type: 'delete',\n key,\n sequenceId,\n promise: syncPromise,\n cancelled: false\n });\n }\n\n private queueClearForSync(): void {\n // Cancel all existing operations since we're clearing everything\n for (const operation of this.pendingSyncOperations.values()) {\n operation.cancelled = true;\n }\n\n // Clear all pending operations since we're clearing everything\n this.pendingSyncOperations.clear();\n\n // Use Promise.resolve() to ensure proper async execution order\n Promise.resolve().then(async () => {\n try {\n await this.asyncCache.clear();\n } catch (error) {\n console.warn('Failed to sync clear operation to IndexedDB:', error);\n }\n });\n }\n\n public async get(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): Promise<V | null> {\n // Wait for initialization if still in progress\n if (!this.isInitialized && this.initializationPromise) {\n try {\n await this.initializationPromise;\n } catch (error) {\n console.warn('IndexedDB initialization failed, using memory cache only:', error);\n }\n }\n return this.memoryCache.get(key);\n }\n\n public set(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>, value: V): void {\n // Update memory cache immediately\n this.memoryCache.set(key, value);\n\n // Trigger background sync to IndexedDB\n this.queueForSync(key, value);\n }\n\n public async includesKey(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): Promise<boolean> {\n // Wait for initialization if still in progress\n if (!this.isInitialized && this.initializationPromise) {\n try {\n await this.initializationPromise;\n } catch (error) {\n console.warn('IndexedDB initialization failed, using memory cache only:', error);\n }\n }\n return this.memoryCache.includesKey(key);\n }\n\n public delete(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): void {\n // Delete from memory cache immediately\n this.memoryCache.delete(key);\n\n // Trigger background sync to IndexedDB\n this.queueDeleteForSync(key);\n }\n\n public async allIn(locations: LocKeyArray<L1, L2, L3, L4, L5> | []): Promise<V[]> {\n return this.memoryCache.allIn(locations);\n }\n\n public async contains(query: ItemQuery, locations: LocKeyArray<L1, L2, L3, L4, L5> | []): Promise<boolean> {\n return this.memoryCache.contains(query, locations);\n }\n\n public async queryIn(query: ItemQuery, locations: LocKeyArray<L1, L2, L3, L4, L5> | []): Promise<V[]> {\n return this.memoryCache.queryIn(query, locations);\n }\n\n public async clone(): Promise<IndexDBCacheMap<V, S, L1, L2, L3, L4, L5>> {\n return new IndexDBCacheMap<V, S, L1, L2, L3, L4, L5>(this.types);\n }\n\n public keys(): (ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[] {\n return this.memoryCache.keys();\n }\n\n public async values(): Promise<V[]> {\n return this.memoryCache.values();\n }\n\n public clear(): void {\n // Clear memory cache immediately\n this.memoryCache.clear();\n\n // Trigger background sync to IndexedDB\n this.queueClearForSync();\n }\n\n // Query result caching methods implementation\n\n public setQueryResult(queryHash: string, itemKeys: (ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[]): void {\n return this.memoryCache.setQueryResult(queryHash, itemKeys);\n }\n\n public async getQueryResult(queryHash: string): Promise<(ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[] | null> {\n // Wait for initialization if still in progress\n if (!this.isInitialized && this.initializationPromise) {\n try {\n await this.initializationPromise;\n } catch (error) {\n console.warn('IndexedDB initialization failed, using memory cache only:', error);\n }\n }\n return this.memoryCache.getQueryResult(queryHash);\n }\n\n public hasQueryResult(queryHash: string): boolean {\n return this.memoryCache.hasQueryResult(queryHash);\n }\n\n public deleteQueryResult(queryHash: string): void {\n return this.memoryCache.deleteQueryResult(queryHash);\n }\n\n public invalidateItemKeys(keys: (ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>)[]): void {\n return this.memoryCache.invalidateItemKeys(keys);\n }\n\n public async invalidateLocation(locations: LocKeyArray<L1, L2, L3, L4, L5> | []): Promise<void> {\n return await this.memoryCache.invalidateLocation(locations);\n }\n\n public clearQueryResults(): void {\n return this.memoryCache.clearQueryResults();\n }\n\n /**\n * Clean up resources when the cache is no longer needed\n */\n public destroy(): void {\n if (this.syncInterval) {\n clearInterval(this.syncInterval);\n this.syncInterval = null;\n }\n }\n\n // CacheMapMetadataProvider implementation\n // Delegate to the memory cache for metadata operations for consistency\n public getMetadata(key: string): CacheItemMetadata | null {\n return this.memoryCache.getMetadata(key);\n }\n\n public setMetadata(key: string, metadata: CacheItemMetadata): void {\n this.memoryCache.setMetadata(key, metadata);\n }\n\n public deleteMetadata(key: string): void {\n this.memoryCache.deleteMetadata(key);\n }\n\n public getAllMetadata(): Map<string, CacheItemMetadata> {\n return this.memoryCache.getAllMetadata();\n }\n\n public clearMetadata(): void {\n this.memoryCache.clearMetadata();\n }\n\n public getCurrentSize(): { itemCount: number; sizeBytes: number } {\n return this.memoryCache.getCurrentSize();\n }\n\n public getSizeLimits(): { maxItems: number | null; maxSizeBytes: number | null } {\n return this.memoryCache.getSizeLimits();\n }\n\n}\n", "import { Item } from '@fjell/core';\nimport { CacheMap } from './CacheMap';\nimport { MemoryCacheMap } from './memory/MemoryCacheMap';\nimport { EnhancedMemoryCacheMap } from './memory/EnhancedMemoryCacheMap';\nimport { LocalStorageCacheMap } from './browser/LocalStorageCacheMap';\nimport { SessionStorageCacheMap } from './browser/SessionStorageCacheMap';\nimport { IndexDBCacheMap } from './browser/IndexDBCacheMap';\n\nimport { validateSizeConfig } from './utils/CacheSize';\nimport { EvictionStrategyConfigs } from './eviction/EvictionStrategyConfig';\n\n/**\n * Available cache types for the cache instance\n */\nexport type CacheType = 'memory' | 'localStorage' | 'sessionStorage' | 'indexedDB' | 'asyncIndexedDB' | 'custom';\n\n/**\n * Cache eviction policies for when cache size limits are reached\n */\nexport type EvictionPolicy =\n | 'lru' // Least Recently Used - removes oldest recently-accessed item\n | 'lfu' // Least Frequently Used - removes item with lowest access frequency\n | 'fifo' // First-In, First-Out - removes oldest added item\n | 'mru' // Most Recently Used - removes most recently used item\n | 'random' // Random Replacement - evicts a random item\n | 'arc' // Adaptive Replacement Cache - balances recency and frequency\n | '2q'; // Two Queues - keeps separate LRU lists for recent and frequent entries\n\n/**\n * Cache size configuration supporting bytes and item count limits\n */\nexport interface CacheSizeConfig {\n /** Maximum cache size in bytes (e.g., '100', '5KB', '10MB', '2GB', '1KiB', '512MiB') */\n maxSizeBytes?: string;\n /** Maximum number of items in cache */\n maxItems?: number;\n /** @deprecated Eviction policy is now handled by Cache-level EvictionManager via evictionConfig */\n evictionPolicy?: EvictionPolicy;\n}\n\n/**\n * Configuration for IndexedDB-based cache maps\n */\nexport interface IndexedDBConfig {\n /** Database name (default: 'fjell-cache') */\n dbName?: string;\n /** Database version (default: 1) */\n version?: number;\n /** Object store name (default: 'cache') */\n storeName?: string;\n /** Size configuration for IndexedDB cache */\n size?: CacheSizeConfig;\n}\n\n/**\n * Configuration for localStorage/sessionStorage-based cache maps\n */\nexport interface WebStorageConfig {\n /** Key prefix for storage items (default: 'fjell-cache:') */\n keyPrefix?: string;\n /** Whether to compress stored data (default: false) */\n compress?: boolean;\n /** Size configuration for web storage cache */\n size?: CacheSizeConfig;\n}\n\n/**\n * Configuration for memory-based cache maps\n */\nexport interface MemoryConfig {\n /** Maximum number of items to keep in memory (default: unlimited) */\n maxItems?: number;\n /** Size configuration for memory cache */\n size?: CacheSizeConfig;\n}\n\n/**\n * Factory function for creating custom cache map instances\n */\nexport type CacheMapFactory<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n> = (kta: [S, ...string[]]) => CacheMap<V, S, L1, L2, L3, L4, L5>;\n\n/**\n * Cache options interface for configuring cache instances\n */\nexport interface Options<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n> {\n /** The type of cache to use */\n cacheType: CacheType;\n\n /** Configuration for IndexedDB cache types */\n indexedDBConfig?: IndexedDBConfig;\n\n /** Configuration for web storage cache types */\n webStorageConfig?: WebStorageConfig;\n\n /** Configuration for memory cache type */\n memoryConfig?: MemoryConfig;\n\n /** Custom cache map factory for 'custom' cache type */\n customCacheMapFactory?: CacheMapFactory<V, S, L1, L2, L3, L4, L5>;\n\n /** Eviction strategy configuration - independent of cache implementation */\n evictionConfig?: EvictionStrategyConfigs;\n\n /** Whether to enable debug logging for cache operations */\n enableDebugLogging?: boolean;\n\n /** Whether to automatically sync with the API on cache misses */\n autoSync?: boolean;\n\n /** Cache expiration time in milliseconds (default: unlimited) */\n ttl?: number;\n\n /** Maximum number of retry attempts for failed operations */\n maxRetries?: number;\n\n /** Delay between retry attempts in milliseconds */\n retryDelay?: number;\n}\n\n/**\n * Default cache options\n */\nconst DEFAULT_CACHE_OPTIONS: Partial<Options<any, any, any, any, any, any, any>> = {\n cacheType: 'memory',\n enableDebugLogging: false,\n autoSync: true,\n maxRetries: 3,\n retryDelay: 1000,\n indexedDBConfig: {\n dbName: 'fjell-cache',\n version: 1,\n storeName: 'cache',\n size: {\n evictionPolicy: 'lru'\n }\n },\n webStorageConfig: {\n keyPrefix: 'fjell-cache:',\n compress: false,\n size: {\n evictionPolicy: 'lru'\n }\n },\n memoryConfig: {\n // No limits by default\n size: {\n evictionPolicy: 'lru'\n }\n }\n};\n\n/**\n * Create cache options with defaults\n */\nexport const createOptions = <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(cacheOptions?: Partial<Options<V, S, L1, L2, L3, L4, L5>>): Options<V, S, L1, L2, L3, L4, L5> => {\n // Deep clone nested config objects to prevent mutation between instances\n const indexedDBConfig = cacheOptions?.indexedDBConfig ? {\n ...DEFAULT_CACHE_OPTIONS.indexedDBConfig,\n ...cacheOptions.indexedDBConfig,\n size: cacheOptions.indexedDBConfig.size ? {\n ...DEFAULT_CACHE_OPTIONS.indexedDBConfig?.size,\n ...cacheOptions.indexedDBConfig.size\n } : DEFAULT_CACHE_OPTIONS.indexedDBConfig?.size\n } : { ...DEFAULT_CACHE_OPTIONS.indexedDBConfig };\n\n const webStorageConfig = cacheOptions?.webStorageConfig ? {\n ...DEFAULT_CACHE_OPTIONS.webStorageConfig,\n ...cacheOptions.webStorageConfig,\n size: cacheOptions.webStorageConfig.size ? {\n ...DEFAULT_CACHE_OPTIONS.webStorageConfig?.size,\n ...cacheOptions.webStorageConfig.size\n } : DEFAULT_CACHE_OPTIONS.webStorageConfig?.size\n } : { ...DEFAULT_CACHE_OPTIONS.webStorageConfig };\n\n const memoryConfig = cacheOptions?.memoryConfig ? {\n ...DEFAULT_CACHE_OPTIONS.memoryConfig,\n ...cacheOptions.memoryConfig,\n size: cacheOptions.memoryConfig.size ? {\n ...DEFAULT_CACHE_OPTIONS.memoryConfig?.size,\n ...cacheOptions.memoryConfig.size\n } : DEFAULT_CACHE_OPTIONS.memoryConfig?.size\n } : { ...DEFAULT_CACHE_OPTIONS.memoryConfig };\n\n return {\n ...DEFAULT_CACHE_OPTIONS,\n ...cacheOptions,\n indexedDBConfig,\n webStorageConfig,\n memoryConfig\n } as Options<V, S, L1, L2, L3, L4, L5>;\n};\n\n/**\n * Create a cache map instance based on the provided options\n */\nexport const createCacheMap = <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n kta: [S, ...string[]],\n options: Options<V, S, L1, L2, L3, L4, L5>\n ): CacheMap<V, S, L1, L2, L3, L4, L5> => {\n switch (options.cacheType) {\n case 'memory':\n // Use enhanced memory cache if size configuration is provided\n if (options.memoryConfig?.size &&\n (options.memoryConfig.size.maxSizeBytes || options.memoryConfig.size.maxItems)) {\n // Create size config without evictionPolicy since that's handled by Cache-level EvictionManager\n const sizeConfig = {\n maxSizeBytes: options.memoryConfig.size.maxSizeBytes,\n maxItems: options.memoryConfig.size.maxItems\n };\n return new EnhancedMemoryCacheMap<V, S, L1, L2, L3, L4, L5>(\n kta as any,\n sizeConfig\n );\n }\n return new MemoryCacheMap<V, S, L1, L2, L3, L4, L5>(kta as any);\n\n case 'localStorage':\n return new LocalStorageCacheMap<V, S, L1, L2, L3, L4, L5>(\n kta as any,\n options.webStorageConfig?.keyPrefix\n );\n\n case 'sessionStorage':\n return new SessionStorageCacheMap<V, S, L1, L2, L3, L4, L5>(\n kta as any,\n options.webStorageConfig?.keyPrefix\n );\n\n case 'indexedDB':\n return new IndexDBCacheMap<V, S, L1, L2, L3, L4, L5>(\n kta as any,\n options.indexedDBConfig?.dbName,\n options.indexedDBConfig?.storeName,\n options.indexedDBConfig?.version\n );\n\n case 'custom':\n if (!options.customCacheMapFactory) {\n throw new Error('Custom cache map factory is required when cacheType is \"custom\"');\n }\n return options.customCacheMapFactory(kta);\n\n default:\n throw new Error(`Unsupported cache type: ${options.cacheType}`);\n }\n};\n\n/**\n * Validate cache options\n */\nexport const validateOptions = <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(options: Options<V, S, L1, L2, L3, L4, L5>): void => {\n if (options.cacheType === 'custom' && !options.customCacheMapFactory) {\n throw new Error('customCacheMapFactory is required when cacheType is \"custom\"');\n }\n\n if (typeof options.maxRetries === 'number' && options.maxRetries < 0) {\n throw new Error('maxRetries must be non-negative');\n }\n\n if (typeof options.retryDelay === 'number' && options.retryDelay < 0) {\n throw new Error('retryDelay must be non-negative');\n }\n\n if (typeof options.ttl === 'number' && options.ttl <= 0) {\n throw new Error('ttl must be positive');\n }\n\n if (typeof options.memoryConfig?.maxItems === 'number' && options.memoryConfig.maxItems <= 0) {\n throw new Error('memoryConfig.maxItems must be positive');\n }\n\n // Validate size configurations\n if (options.memoryConfig?.size) {\n validateSizeConfig(options.memoryConfig.size);\n }\n if (options.webStorageConfig?.size) {\n validateSizeConfig(options.webStorageConfig.size);\n }\n if (options.indexedDBConfig?.size) {\n validateSizeConfig(options.indexedDBConfig.size);\n }\n\n // Browser storage validation\n if (['localStorage', 'sessionStorage'].includes(options.cacheType)) {\n // Check if we're in a real browser environment\n const isRealBrowser = typeof window !== 'undefined' &&\n typeof window.document !== 'undefined' &&\n typeof window.document.createElement === 'function';\n\n if (!isRealBrowser) {\n throw new Error(`${options.cacheType} is not available in non-browser environments`);\n }\n }\n\n // IndexedDB validation\n if (options.cacheType === 'indexedDB') {\n if (typeof window === 'undefined' || !window.indexedDB) {\n throw new Error(`${options.cacheType} is not available in this environment`);\n }\n }\n\n // AsyncIndexedDB validation - should not be used with synchronous cache factory\n if (options.cacheType === 'asyncIndexedDB') {\n throw new Error('asyncIndexedDB cannot be used with synchronous cache factory. Use AsyncIndexDBCacheMap directly for async operations.');\n }\n};\n", "import {\n Item\n} from \"@fjell/core\";\nimport { CacheMap } from \"../CacheMap\";\nimport { createCacheMap, Options, validateOptions } from \"../Options\";\nimport { Coordinate } from \"@fjell/registry\";\n\nexport const reset = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n coordinate: Coordinate<S, L1, L2, L3, L4, L5>,\n options: Options<V, S, L1, L2, L3, L4, L5>\n): Promise<[CacheMap<V, S, L1, L2, L3, L4, L5>]> => {\n try {\n // Validate options before creating cache map\n validateOptions(options);\n\n // Create a new cache map using the same configuration as the original\n const cacheMap = createCacheMap<V, S, L1, L2, L3, L4, L5>(coordinate.kta, options);\n return [cacheMap];\n } catch (error) {\n // Re-throw any validation or creation errors\n throw error;\n }\n};\n", "import { ComKey, Item, ItemQuery, LocKeyArray, PriKey } from \"@fjell/core\";\nimport { ClientApi } from \"@fjell/client-api\";\nimport { Coordinate } from \"@fjell/registry\";\nimport { CacheMap } from \"./CacheMap\";\nimport { createCacheContext } from \"./CacheContext\";\nimport { CacheEventEmitter } from \"./events/CacheEventEmitter\";\n\n// Import all operation functions\nimport { all } from \"./ops/all\";\nimport { one } from \"./ops/one\";\nimport { create } from \"./ops/create\";\nimport { get } from \"./ops/get\";\nimport { retrieve } from \"./ops/retrieve\";\nimport { remove } from \"./ops/remove\";\nimport { update } from \"./ops/update\";\nimport { action } from \"./ops/action\";\nimport { allAction } from \"./ops/allAction\";\nimport { facet } from \"./ops/facet\";\nimport { allFacet } from \"./ops/allFacet\";\nimport { find } from \"./ops/find\";\nimport { findOne } from \"./ops/findOne\";\nimport { set } from \"./ops/set\";\nimport { reset } from \"./ops/reset\";\nimport { Options } from \"./Options\";\nimport { TTLManager } from \"./ttl/TTLManager\";\nimport { EvictionManager } from \"./eviction/EvictionManager\";\nimport { CacheStatsManager } from \"./CacheStats\";\n\nexport interface Operations<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never,\n> {\n\n /**\n * Retrieves all the items that match the query from cache or API.\n * Items are cached automatically after retrieval.\n */\n all(\n query?: ItemQuery,\n locations?: LocKeyArray<L1, L2, L3, L4, L5> | []\n ): Promise<V[]>;\n\n /**\n * Retrieves the first item that matches the query from cache or API.\n * Item is cached automatically after retrieval.\n */\n one(\n query?: ItemQuery,\n locations?: LocKeyArray<L1, L2, L3, L4, L5> | []\n ): Promise<V | null>;\n\n /**\n * Creates a new item via API and caches it.\n */\n create(\n item: Partial<Item<S, L1, L2, L3, L4, L5>>,\n locations?: LocKeyArray<L1, L2, L3, L4, L5> | []\n ): Promise<V>;\n\n /**\n * Gets an item by key from cache or API and caches it.\n */\n get(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>\n ): Promise<V | null>;\n\n /**\n * Retrieves an item from cache if available, otherwise from API.\n */\n retrieve(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>\n ): Promise<V | null>;\n\n /**\n * Removes an item via API and from cache.\n */\n remove(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>\n ): Promise<void>;\n\n /**\n * Updates an item via API and caches the result.\n */\n update(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n item: Partial<Item<S, L1, L2, L3, L4, L5>>\n ): Promise<V>;\n\n /**\n * Executes an action on an item via API and caches the result.\n */\n action(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n action: string,\n body?: any\n ): Promise<V>;\n\n /**\n * Executes an action on all items matching criteria via API and caches results.\n */\n allAction(\n action: string,\n body?: any,\n locations?: LocKeyArray<L1, L2, L3, L4, L5> | []\n ): Promise<V[]>;\n\n /**\n * Executes a facet query on an item via API (pass-through, no caching).\n */\n facet(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n facet: string,\n params?: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>\n ): Promise<any>;\n\n /**\n * Executes a facet query on all items matching criteria via API (pass-through, no caching).\n */\n allFacet(\n facet: string,\n params?: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n locations?: LocKeyArray<L1, L2, L3, L4, L5> | []\n ): Promise<any>;\n\n /**\n * Finds items using a finder method via API and caches results.\n */\n find(\n finder: string,\n params?: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n locations?: LocKeyArray<L1, L2, L3, L4, L5> | []\n ): Promise<V[]>;\n\n /**\n * Finds a single item using a finder method via API and caches result.\n */\n findOne(\n finder: string,\n params?: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n locations?: LocKeyArray<L1, L2, L3, L4, L5> | []\n ): Promise<V>;\n\n /**\n * Sets an item directly in cache without API call.\n */\n set(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n item: Item<S, L1, L2, L3, L4, L5>\n ): Promise<V>;\n\n /**\n * Resets the cache, clearing all cached items.\n */\n reset(): Promise<void>;\n}\n\nexport const createOperations = <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n api: ClientApi<V, S, L1, L2, L3, L4, L5>,\n coordinate: Coordinate<S, L1, L2, L3, L4, L5>,\n cacheMap: CacheMap<V, S, L1, L2, L3, L4, L5>,\n pkType: S,\n options: Options<V, S, L1, L2, L3, L4, L5>,\n eventEmitter: CacheEventEmitter<V, S, L1, L2, L3, L4, L5>,\n ttlManager: TTLManager,\n evictionManager: EvictionManager,\n statsManager: CacheStatsManager\n ): Operations<V, S, L1, L2, L3, L4, L5> => {\n\n // Create the cache context once and reuse it across all operations\n const context = createCacheContext(api, cacheMap, pkType, options, eventEmitter, ttlManager, evictionManager, statsManager);\n\n return {\n all: (query, locations) => all(query, locations, context).then(([ctx, result]) => result),\n one: (query, locations) => one(query, locations, context).then(([ctx, result]) => result),\n create: (item, locations) => create(item, locations, context).then(([ctx, result]) => result),\n get: (key) => get(key, context).then(([ctx, result]) => result),\n retrieve: (key) => retrieve(key, context).then(([ctx, result]) => result),\n remove: (key) => remove(key, context).then((ctx) => undefined),\n update: (key, item) => update(key, item, context).then(([ctx, result]) => result),\n action: (key, actionName, body) => action(key, actionName, body, context).then(([ctx, result]) => result),\n allAction: (actionName, body, locations) => allAction(actionName, body, locations, context).then(([ctx, result]) => result),\n facet: (key, facetName, params) => facet(key, facetName, params, context).then(result => result),\n allFacet: (facetName, params, locations) => allFacet(facetName, params, locations, context).then(result => result),\n find: (finder, params, locations) => find(finder, params, locations, context).then(([ctx, result]) => result),\n findOne: (finder, params, locations) => findOne(finder, params, locations, context).then(([ctx, result]) => result),\n set: (key, item) => set(key, item, context).then(([ctx, result]) => result),\n reset: () => reset(coordinate, options).then(() => undefined)\n };\n};\n", "import {\n CacheMapMetadataProvider,\n EvictionContext,\n EvictionStrategy\n} from './EvictionStrategy';\nimport { estimateValueSize } from '../utils/CacheSize';\nimport LibLogger from '../logger';\n\nconst logger = LibLogger.get('EvictionManager');\n\n/**\n * Manages eviction logic independently of CacheMap implementations.\n * This class coordinates between eviction strategies and cache metadata.\n */\nexport class EvictionManager {\n private evictionStrategy: EvictionStrategy | null;\n\n constructor(evictionStrategy?: EvictionStrategy) {\n this.evictionStrategy = evictionStrategy || null;\n }\n\n /**\n * Set or update the eviction strategy\n * @param strategy - The eviction strategy to use\n */\n public setEvictionStrategy(strategy: EvictionStrategy | null): void {\n this.evictionStrategy = strategy;\n logger.debug('Eviction strategy updated', {\n strategy: strategy?.getStrategyName() || 'none'\n });\n }\n\n /**\n * Get the current eviction strategy name\n * @returns Strategy name or null if no eviction\n */\n public getEvictionStrategyName(): string | null {\n return this.evictionStrategy?.getStrategyName() || null;\n }\n\n /**\n * Handle item access - update metadata for eviction strategy\n * @param key - Item key\n * @param metadataProvider - Cache metadata provider\n */\n public onItemAccessed(key: string, metadataProvider: CacheMapMetadataProvider): void {\n if (!this.evictionStrategy) {\n return;\n }\n\n try {\n this.evictionStrategy.onItemAccessed(key, metadataProvider);\n } catch (error) {\n logger.error('Error in eviction strategy onItemAccessed', { key, error });\n }\n }\n\n /**\n * Handle item addition - update metadata and perform eviction if needed\n * @param key - Item key\n * @param value - Item value (for size estimation)\n * @param metadataProvider - Cache metadata provider\n * @returns Array of keys that were evicted\n */\n public onItemAdded<T>(\n key: string,\n value: T,\n metadataProvider: CacheMapMetadataProvider\n ): string[] {\n const evictedKeys: string[] = [];\n\n if (!this.evictionStrategy) {\n return evictedKeys;\n }\n\n try {\n const estimatedSize = estimateValueSize(value);\n const context = this.createEvictionContext(metadataProvider, estimatedSize);\n\n // Perform eviction before adding the new item if needed\n const keysToEvict = this.evictionStrategy.selectForEviction(metadataProvider, context);\n\n for (const evictKey of keysToEvict) {\n // Let the strategy know about the removal\n this.evictionStrategy.onItemRemoved(evictKey, metadataProvider);\n evictedKeys.push(evictKey);\n }\n\n // Now add metadata for the new item\n this.evictionStrategy.onItemAdded(key, estimatedSize, metadataProvider);\n\n if (evictedKeys.length > 0) {\n logger.debug('Items evicted during addition', {\n newKey: key,\n evictedKeys,\n strategy: this.evictionStrategy.getStrategyName()\n });\n }\n } catch (error) {\n logger.error('Error in eviction strategy onItemAdded', { key, error });\n }\n\n return evictedKeys;\n }\n\n /**\n * Handle item removal - clean up metadata\n * @param key - Item key\n * @param metadataProvider - Cache metadata provider\n */\n public onItemRemoved(key: string, metadataProvider: CacheMapMetadataProvider): void {\n if (!this.evictionStrategy) {\n return;\n }\n\n try {\n this.evictionStrategy.onItemRemoved(key, metadataProvider);\n } catch (error) {\n logger.error('Error in eviction strategy onItemRemoved', { key, error });\n }\n }\n\n /**\n * Perform manual eviction check\n * @param metadataProvider - Cache metadata provider\n * @returns Array of keys that were evicted\n */\n public performEviction(metadataProvider: CacheMapMetadataProvider): string[] {\n const evictedKeys: string[] = [];\n\n if (!this.evictionStrategy) {\n return evictedKeys;\n }\n\n try {\n const context = this.createEvictionContext(metadataProvider);\n const keysToEvict = this.evictionStrategy.selectForEviction(metadataProvider, context);\n\n for (const evictKey of keysToEvict) {\n this.evictionStrategy.onItemRemoved(evictKey, metadataProvider);\n evictedKeys.push(evictKey);\n }\n\n if (evictedKeys.length > 0) {\n logger.debug('Manual eviction performed', {\n evictedKeys,\n strategy: this.evictionStrategy.getStrategyName()\n });\n }\n } catch (error) {\n logger.error('Error in manual eviction', { error });\n }\n\n return evictedKeys;\n }\n\n /**\n * Check if eviction is supported (i.e., strategy is set)\n * @returns True if eviction is supported\n */\n public isEvictionSupported(): boolean {\n return this.evictionStrategy !== null;\n }\n\n /**\n * Create eviction context from current cache state\n * @param metadataProvider - Cache metadata provider\n * @param newItemSize - Size of item being added (optional)\n * @returns Eviction context\n */\n private createEvictionContext(\n metadataProvider: CacheMapMetadataProvider,\n newItemSize?: number\n ): EvictionContext {\n const currentSize = metadataProvider.getCurrentSize();\n const limits = metadataProvider.getSizeLimits();\n\n return {\n currentSize,\n limits,\n newItemSize\n };\n }\n}\n", "/**\n * Base configuration interface for eviction strategies\n */\nexport interface EvictionStrategyConfig {\n /** Strategy type identifier */\n readonly type: string;\n}\n\n/**\n * Configuration for LFU eviction strategy with frequency sketching\n */\nexport interface LFUConfig extends EvictionStrategyConfig {\n readonly type: 'lfu';\n /** Decay factor for aging frequency counts (0.0 to 1.0, default: 0.1) */\n decayFactor?: number;\n /** Frequency decay interval in milliseconds (default: 60000) */\n decayInterval?: number;\n /** Width of the Count-Min Sketch (default: 1024) */\n sketchWidth?: number;\n /** Depth of the Count-Min Sketch (default: 4) */\n sketchDepth?: number;\n /** Whether to use probabilistic counting (default: true) */\n useProbabilisticCounting?: boolean;\n /** Minimum frequency threshold before decay (default: 1) */\n minFrequencyThreshold?: number;\n}\n\n/**\n * Configuration for LRU eviction strategy\n */\nexport interface LRUConfig extends EvictionStrategyConfig {\n readonly type: 'lru';\n}\n\n/**\n * Configuration for FIFO eviction strategy\n */\nexport interface FIFOConfig extends EvictionStrategyConfig {\n readonly type: 'fifo';\n}\n\n/**\n * Configuration for MRU eviction strategy\n */\nexport interface MRUConfig extends EvictionStrategyConfig {\n readonly type: 'mru';\n}\n\n/**\n * Configuration for Random eviction strategy\n */\nexport interface RandomConfig extends EvictionStrategyConfig {\n readonly type: 'random';\n}\n\n/**\n * Configuration for ARC eviction strategy\n */\nexport interface ARCConfig extends EvictionStrategyConfig {\n readonly type: 'arc';\n /** Maximum cache size for ARC calculations */\n maxCacheSize?: number;\n /** Frequency threshold for classifying items as \"frequent\" vs \"recent\" (default: 2) */\n frequencyThreshold?: number;\n /** Use enhanced frequency tracking with decay (default: true) */\n useEnhancedFrequency?: boolean;\n /** Decay factor for aging frequency scores (default: 0.05) */\n frequencyDecayFactor?: number;\n /** Decay interval for frequency scores (default: 600000 - 10 minutes) */\n frequencyDecayInterval?: number;\n /** Use frequency-weighted selection within T1/T2 lists (default: true) */\n useFrequencyWeightedSelection?: boolean;\n /** Adaptive learning rate for target size adjustments (default: 1.0) */\n adaptiveLearningRate?: number;\n}\n\n/**\n * Configuration for 2Q eviction strategy\n */\nexport interface TwoQueueConfig extends EvictionStrategyConfig {\n readonly type: '2q';\n /** Maximum cache size for 2Q calculations */\n maxCacheSize?: number;\n /** Use frequency-based promotion from recent to hot queue (default: true) */\n useFrequencyPromotion?: boolean;\n /** Minimum access frequency required for promotion to hot queue (default: 2) */\n promotionThreshold?: number;\n /** Decay factor for aging frequency scores in hot queue (default: 0.05) */\n hotQueueDecayFactor?: number;\n /** Decay interval for hot queue frequency scores (default: 300000 - 5 minutes) */\n hotQueueDecayInterval?: number;\n /** Use frequency-weighted LRU in hot queue instead of pure LRU (default: true) */\n useFrequencyWeightedLRU?: boolean;\n}\n\n/**\n * Union type for all eviction strategy configurations\n */\nexport type EvictionStrategyConfigs =\n | LFUConfig\n | LRUConfig\n | FIFOConfig\n | MRUConfig\n | RandomConfig\n | ARCConfig\n | TwoQueueConfig;\n\n/**\n * Default configuration values\n */\nexport const DEFAULT_LFU_CONFIG: LFUConfig = {\n type: 'lfu',\n decayFactor: 0.1,\n decayInterval: 60000, // 1 minute\n sketchWidth: 1024,\n sketchDepth: 4,\n useProbabilisticCounting: true,\n minFrequencyThreshold: 1\n};\n\nexport const DEFAULT_ARC_CONFIG: ARCConfig = {\n type: 'arc',\n maxCacheSize: 1000,\n frequencyThreshold: 2,\n useEnhancedFrequency: true,\n frequencyDecayFactor: 0.05,\n frequencyDecayInterval: 600000, // 10 minutes\n useFrequencyWeightedSelection: true,\n adaptiveLearningRate: 1.0\n};\n\nexport const DEFAULT_TWO_QUEUE_CONFIG: TwoQueueConfig = {\n type: '2q',\n maxCacheSize: 1000,\n useFrequencyPromotion: true,\n promotionThreshold: 2,\n hotQueueDecayFactor: 0.05,\n hotQueueDecayInterval: 300000, // 5 minutes\n useFrequencyWeightedLRU: true\n};\n", "/**\n * Metadata for tracking cache item usage patterns\n */\nexport interface CacheItemMetadata {\n /** When the item was first added to cache */\n addedAt: number;\n /** When the item was last accessed */\n lastAccessedAt: number;\n /** Number of times the item has been accessed */\n accessCount: number;\n /** Estimated size of the item in bytes */\n estimatedSize: number;\n /** Item key for identification */\n key: string;\n /** Frequency score with decay applied (for LFU with sketching) */\n frequencyScore?: number;\n /** Last time frequency was updated (for decay calculations) */\n lastFrequencyUpdate?: number;\n /** Raw frequency count before decay */\n rawFrequency?: number;\n /** Additional strategy-specific metadata */\n strategyData?: { [key: string]: any };\n}\n\n/**\n * Interface for CacheMap implementations to support metadata storage\n * This allows eviction strategies to store and retrieve metadata independently of the storage mechanism\n */\nexport interface CacheMapMetadataProvider {\n /**\n * Get metadata for a specific item\n * @param key - Item key\n * @returns Metadata if exists, null otherwise\n */\n getMetadata(key: string): CacheItemMetadata | null;\n\n /**\n * Set metadata for a specific item\n * @param key - Item key\n * @param metadata - Metadata to store\n */\n setMetadata(key: string, metadata: CacheItemMetadata): void;\n\n /**\n * Delete metadata for a specific item\n * @param key - Item key\n */\n deleteMetadata(key: string): void;\n\n /**\n * Get all metadata entries\n * @returns Map of all metadata entries\n */\n getAllMetadata(): Map<string, CacheItemMetadata>;\n\n /**\n * Clear all metadata\n */\n clearMetadata(): void;\n\n /**\n * Get current cache size information\n * @returns Object with current size metrics\n */\n getCurrentSize(): {\n itemCount: number;\n sizeBytes: number;\n };\n\n /**\n * Get cache size limits\n * @returns Object with size limits (null means unlimited)\n */\n getSizeLimits(): {\n maxItems: number | null;\n maxSizeBytes: number | null;\n };\n}\n\n/**\n * Context provided to eviction strategies for decision making\n */\nexport interface EvictionContext {\n /** Current cache size information */\n currentSize: {\n itemCount: number;\n sizeBytes: number;\n };\n /** Cache size limits */\n limits: {\n maxItems: number | null;\n maxSizeBytes: number | null;\n };\n /** Size of the item being added (for proactive eviction) */\n newItemSize?: number;\n}\n\n/**\n * Abstract base class for cache eviction strategies.\n * Defines the core contract that all eviction policies must implement.\n *\n * Eviction strategies are now completely independent of CacheMap implementations\n * and interact through the CacheMapMetadataProvider interface.\n */\nexport abstract class EvictionStrategy {\n /**\n * Select which items should be evicted based on the strategy and context\n * @param metadataProvider - Provider for accessing cache metadata\n * @param context - Current cache state and limits\n * @returns Array of keys to evict (empty array if no eviction needed)\n */\n abstract selectForEviction(\n metadataProvider: CacheMapMetadataProvider,\n context: EvictionContext\n ): string[];\n\n /**\n * Update metadata when an item is accessed\n * @param key - Item key\n * @param metadataProvider - Provider for accessing cache metadata\n */\n abstract onItemAccessed(key: string, metadataProvider: CacheMapMetadataProvider): void;\n\n /**\n * Update metadata when an item is added\n * @param key - Item key\n * @param estimatedSize - Estimated size of the item in bytes\n * @param metadataProvider - Provider for accessing cache metadata\n */\n abstract onItemAdded(key: string, estimatedSize: number, metadataProvider: CacheMapMetadataProvider): void;\n\n /**\n * Clean up when an item is removed\n * @param key - Item key\n * @param metadataProvider - Provider for accessing cache metadata\n */\n abstract onItemRemoved(key: string, metadataProvider: CacheMapMetadataProvider): void;\n\n /**\n * Get the name/identifier of this eviction strategy\n * @returns String identifier for the strategy\n */\n abstract getStrategyName(): string;\n\n /**\n * Determine if eviction is needed based on current context\n * @param context - Current cache state and limits\n * @returns True if eviction should occur\n */\n protected isEvictionNeeded(context: EvictionContext): boolean {\n const { currentSize, limits, newItemSize = 0 } = context;\n\n // Check item count limit\n if (limits.maxItems !== null && currentSize.itemCount >= limits.maxItems) {\n return true;\n }\n\n // Check size limit (including potential new item)\n if (limits.maxSizeBytes !== null &&\n (currentSize.sizeBytes + newItemSize) > limits.maxSizeBytes) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Calculate how many items need to be evicted\n * @param context - Current cache state and limits\n * @returns Number of items that should be evicted\n */\n protected calculateEvictionCount(context: EvictionContext): number {\n const { currentSize, limits, newItemSize = 0 } = context;\n let evictionCount = 0;\n\n // Calculate based on item count limit\n if (limits.maxItems !== null && currentSize.itemCount >= limits.maxItems) {\n evictionCount = Math.max(evictionCount, currentSize.itemCount - limits.maxItems + 1);\n }\n\n // Calculate based on size limit (this is more complex and approximate)\n if (limits.maxSizeBytes !== null &&\n (currentSize.sizeBytes + newItemSize) > limits.maxSizeBytes) {\n // Conservative estimate: evict at least 1 item, possibly more\n const excessBytes = (currentSize.sizeBytes + newItemSize) - limits.maxSizeBytes;\n const avgItemSize = currentSize.itemCount > 0 ? currentSize.sizeBytes / currentSize.itemCount : 1024;\n const estimatedEvictionCount = Math.ceil(excessBytes / avgItemSize);\n evictionCount = Math.max(evictionCount, estimatedEvictionCount);\n }\n\n return evictionCount;\n }\n}\n", "import {\n CacheItemMetadata,\n CacheMapMetadataProvider,\n EvictionContext,\n EvictionStrategy\n} from '../EvictionStrategy';\n\n/**\n * LRU (Least Recently Used) eviction strategy\n * Removes the item that was accessed longest ago\n */\nexport class LRUEvictionStrategy extends EvictionStrategy {\n selectForEviction(\n metadataProvider: CacheMapMetadataProvider,\n context: EvictionContext\n ): string[] {\n if (!this.isEvictionNeeded(context)) {\n return [];\n }\n\n const allMetadata = metadataProvider.getAllMetadata();\n if (allMetadata.size === 0) {\n return [];\n }\n\n const evictionCount = this.calculateEvictionCount(context);\n const keysToEvict: string[] = [];\n\n // Sort by lastAccessedAt ascending (oldest first)\n const sortedEntries = Array.from(allMetadata.entries())\n .sort(([, a], [, b]) => a.lastAccessedAt - b.lastAccessedAt);\n\n // Take the oldest items up to evictionCount\n for (let i = 0; i < Math.min(evictionCount, sortedEntries.length); i++) {\n keysToEvict.push(sortedEntries[i][0]);\n }\n\n return keysToEvict;\n }\n\n onItemAccessed(key: string, metadataProvider: CacheMapMetadataProvider): void {\n const metadata = metadataProvider.getMetadata(key);\n if (metadata) {\n metadata.lastAccessedAt = Date.now();\n metadata.accessCount++;\n metadataProvider.setMetadata(key, metadata);\n }\n }\n\n onItemAdded(key: string, estimatedSize: number, metadataProvider: CacheMapMetadataProvider): void {\n const now = Date.now();\n const metadata: CacheItemMetadata = {\n key,\n addedAt: now,\n lastAccessedAt: now,\n accessCount: 1,\n estimatedSize\n };\n metadataProvider.setMetadata(key, metadata);\n }\n\n onItemRemoved(key: string, metadataProvider: CacheMapMetadataProvider): void {\n metadataProvider.deleteMetadata(key);\n }\n\n getStrategyName(): string {\n return 'lru';\n }\n}\n", "/**\n * Validation functions for eviction strategy configurations\n */\nimport {\n ARCConfig,\n EvictionStrategyConfigs,\n LFUConfig,\n TwoQueueConfig\n} from './EvictionStrategyConfig';\n\n/**\n * Validates that a number is within a specified range\n */\nfunction validateNumberRange(\n value: number,\n min: number,\n max: number,\n fieldName: string\n): void {\n if (typeof value !== 'number' || isNaN(value) || !isFinite(value)) {\n throw new Error(`${fieldName} must be a finite number`);\n }\n if (value < min || value > max) {\n throw new Error(`${fieldName} must be between ${min} and ${max}, got ${value}`);\n }\n}\n\n/**\n * Validates that a number is a positive integer\n */\nfunction validatePositiveInteger(value: number, fieldName: string): void {\n if (typeof value !== 'number' || isNaN(value) || !isFinite(value)) {\n throw new Error(`${fieldName} must be a finite number`);\n }\n if (!Number.isInteger(value) || value <= 0) {\n throw new Error(`${fieldName} must be a positive integer, got ${value}`);\n }\n}\n\n/**\n * Sanitizes LFU configuration parameters, correcting invalid values\n */\nexport function sanitizeLFUConfig(config: Partial<LFUConfig>): Partial<LFUConfig> {\n const sanitized = { ...config };\n\n // Sanitize decayFactor to be between 0 and 1\n if (typeof sanitized.decayFactor === 'number') {\n if (sanitized.decayFactor < 0) {\n console.warn(`decayFactor must be between 0 and 1, got ${sanitized.decayFactor}. Correcting to 0.`);\n sanitized.decayFactor = 0;\n } else if (sanitized.decayFactor > 1) {\n console.warn(`decayFactor must be between 0 and 1, got ${sanitized.decayFactor}. Correcting to 1.`);\n sanitized.decayFactor = 1;\n }\n }\n\n // Sanitize decayInterval to be positive\n if (typeof sanitized.decayInterval === 'number' && sanitized.decayInterval <= 0) {\n console.warn(`decayInterval must be positive, got ${sanitized.decayInterval}. Correcting to 300000.`);\n sanitized.decayInterval = 300000; // 5 minutes default\n }\n\n // Sanitize sketchWidth to be positive and reasonable\n if (typeof sanitized.sketchWidth === 'number') {\n if (sanitized.sketchWidth <= 0) {\n console.warn(`sketchWidth must be positive, got ${sanitized.sketchWidth}. Correcting to 1024.`);\n sanitized.sketchWidth = 1024;\n } else if (sanitized.sketchWidth < 16) {\n console.warn(`sketchWidth should be at least 16 for optimal performance, got ${sanitized.sketchWidth}. Correcting to 16.`);\n sanitized.sketchWidth = 16;\n } else if (sanitized.sketchWidth > 65536) {\n console.warn(`sketchWidth should not exceed 65536 for optimal performance, got ${sanitized.sketchWidth}. Correcting to 65536.`);\n sanitized.sketchWidth = 65536;\n }\n }\n\n // Sanitize sketchDepth to be positive and reasonable\n if (typeof sanitized.sketchDepth === 'number') {\n if (sanitized.sketchDepth <= 0) {\n console.warn(`sketchDepth must be positive, got ${sanitized.sketchDepth}. Correcting to 4.`);\n sanitized.sketchDepth = 4;\n } else if (sanitized.sketchDepth < 1) {\n console.warn(`sketchDepth should be at least 1 for optimal accuracy, got ${sanitized.sketchDepth}. Correcting to 1.`);\n sanitized.sketchDepth = 1;\n } else if (sanitized.sketchDepth > 16) {\n console.warn(`sketchDepth should not exceed 16 for optimal accuracy, got ${sanitized.sketchDepth}. Correcting to 16.`);\n sanitized.sketchDepth = 16;\n }\n }\n\n // Sanitize minFrequencyThreshold to be positive\n if (typeof sanitized.minFrequencyThreshold === 'number' && sanitized.minFrequencyThreshold <= 0) {\n console.warn(`minFrequencyThreshold must be positive, got ${sanitized.minFrequencyThreshold}. Correcting to 1.`);\n sanitized.minFrequencyThreshold = 1;\n }\n\n return sanitized;\n}\n\n/**\n * Validates LFU configuration parameters (after sanitization)\n */\nexport function validateLFUConfig(config: Partial<LFUConfig>): void {\n if (typeof config.decayFactor === 'number') {\n validateNumberRange(config.decayFactor, 0.0, 1.0, 'decayFactor');\n }\n\n if (typeof config.decayInterval === 'number') {\n validatePositiveInteger(config.decayInterval, 'decayInterval');\n }\n\n if (typeof config.sketchWidth === 'number') {\n validatePositiveInteger(config.sketchWidth, 'sketchWidth');\n if (config.sketchWidth < 16 || config.sketchWidth > 65536) {\n throw new Error(`sketchWidth must be between 16 and 65536, got ${config.sketchWidth}`);\n }\n }\n\n if (typeof config.sketchDepth === 'number') {\n validatePositiveInteger(config.sketchDepth, 'sketchDepth');\n if (config.sketchDepth < 1 || config.sketchDepth > 16) {\n throw new Error(`sketchDepth must be between 1 and 16, got ${config.sketchDepth}`);\n }\n }\n\n if (typeof config.minFrequencyThreshold === 'number') {\n validatePositiveInteger(config.minFrequencyThreshold, 'minFrequencyThreshold');\n }\n}\n\n/**\n * Sanitizes ARC configuration parameters, correcting invalid values\n */\nexport function sanitizeARCConfig(config: Partial<ARCConfig>): Partial<ARCConfig> {\n const sanitized = { ...config };\n\n // Sanitize maxCacheSize to be positive\n if (typeof sanitized.maxCacheSize === 'number' && sanitized.maxCacheSize <= 0) {\n console.warn(`maxCacheSize must be positive, got ${sanitized.maxCacheSize}. Correcting to 1000.`);\n sanitized.maxCacheSize = 1000;\n }\n\n // Sanitize frequencyThreshold to be positive\n if (typeof sanitized.frequencyThreshold === 'number' && sanitized.frequencyThreshold <= 0) {\n console.warn(`frequencyThreshold must be positive, got ${sanitized.frequencyThreshold}. Correcting to 2.`);\n sanitized.frequencyThreshold = 2;\n }\n\n // Sanitize frequencyDecayFactor to be between 0 and 1\n if (typeof sanitized.frequencyDecayFactor === 'number') {\n if (sanitized.frequencyDecayFactor < 0) {\n console.warn(`frequencyDecayFactor must be between 0 and 1, got ${sanitized.frequencyDecayFactor}. Correcting to 0.`);\n sanitized.frequencyDecayFactor = 0;\n } else if (sanitized.frequencyDecayFactor > 1) {\n console.warn(`frequencyDecayFactor must be between 0 and 1, got ${sanitized.frequencyDecayFactor}. Correcting to 1.`);\n sanitized.frequencyDecayFactor = 1;\n }\n }\n\n // Sanitize frequencyDecayInterval to be positive\n if (typeof sanitized.frequencyDecayInterval === 'number' && sanitized.frequencyDecayInterval <= 0) {\n console.warn(`frequencyDecayInterval must be positive, got ${sanitized.frequencyDecayInterval}. Correcting to 60000.`);\n sanitized.frequencyDecayInterval = 60000; // 1 minute default\n }\n\n // Sanitize adaptiveLearningRate to be between 0 and 10\n if (typeof sanitized.adaptiveLearningRate === 'number') {\n if (sanitized.adaptiveLearningRate < 0) {\n console.warn(`adaptiveLearningRate must be between 0 and 10, got ${sanitized.adaptiveLearningRate}. Correcting to 0.`);\n sanitized.adaptiveLearningRate = 0;\n } else if (sanitized.adaptiveLearningRate > 10) {\n console.warn(`adaptiveLearningRate must be between 0 and 10, got ${sanitized.adaptiveLearningRate}. Correcting to 10.`);\n sanitized.adaptiveLearningRate = 10;\n }\n }\n\n return sanitized;\n}\n\n/**\n * Validates ARC configuration parameters (after sanitization)\n */\nexport function validateARCConfig(config: Partial<ARCConfig>): void {\n if (typeof config.maxCacheSize === 'number') {\n validatePositiveInteger(config.maxCacheSize, 'maxCacheSize');\n }\n\n if (typeof config.frequencyThreshold === 'number') {\n validatePositiveInteger(config.frequencyThreshold, 'frequencyThreshold');\n }\n\n if (typeof config.frequencyDecayFactor === 'number') {\n validateNumberRange(config.frequencyDecayFactor, 0.0, 1.0, 'frequencyDecayFactor');\n }\n\n if (typeof config.frequencyDecayInterval === 'number') {\n validatePositiveInteger(config.frequencyDecayInterval, 'frequencyDecayInterval');\n }\n\n if (typeof config.adaptiveLearningRate === 'number') {\n validateNumberRange(config.adaptiveLearningRate, 0.0, 10.0, 'adaptiveLearningRate');\n }\n}\n\n/**\n * Sanitizes TwoQueue configuration parameters, correcting invalid values\n */\nexport function sanitizeTwoQueueConfig(config: Partial<TwoQueueConfig>): Partial<TwoQueueConfig> {\n const sanitized = { ...config };\n\n // Sanitize maxCacheSize to be positive\n if (typeof sanitized.maxCacheSize === 'number' && sanitized.maxCacheSize <= 0) {\n console.warn(`maxCacheSize must be positive, got ${sanitized.maxCacheSize}. Correcting to 1000.`);\n sanitized.maxCacheSize = 1000;\n }\n\n // Sanitize promotionThreshold to be positive\n if (typeof sanitized.promotionThreshold === 'number' && sanitized.promotionThreshold <= 0) {\n console.warn(`promotionThreshold must be positive, got ${sanitized.promotionThreshold}. Correcting to 2.`);\n sanitized.promotionThreshold = 2;\n }\n\n // Sanitize hotQueueDecayFactor to be between 0 and 1\n if (typeof sanitized.hotQueueDecayFactor === 'number') {\n if (sanitized.hotQueueDecayFactor < 0) {\n console.warn(`hotQueueDecayFactor must be between 0 and 1, got ${sanitized.hotQueueDecayFactor}. Correcting to 0.`);\n sanitized.hotQueueDecayFactor = 0;\n } else if (sanitized.hotQueueDecayFactor > 1) {\n console.warn(`hotQueueDecayFactor must be between 0 and 1, got ${sanitized.hotQueueDecayFactor}. Correcting to 1.`);\n sanitized.hotQueueDecayFactor = 1;\n }\n }\n\n // Sanitize hotQueueDecayInterval to be positive\n if (typeof sanitized.hotQueueDecayInterval === 'number' && sanitized.hotQueueDecayInterval <= 0) {\n console.warn(`hotQueueDecayInterval must be positive, got ${sanitized.hotQueueDecayInterval}. Correcting to 300000.`);\n sanitized.hotQueueDecayInterval = 300000; // 5 minutes default\n }\n\n return sanitized;\n}\n\n/**\n * Validates TwoQueue configuration parameters (after sanitization)\n */\nexport function validateTwoQueueConfig(config: Partial<TwoQueueConfig>): void {\n if (typeof config.maxCacheSize === 'number') {\n validatePositiveInteger(config.maxCacheSize, 'maxCacheSize');\n }\n\n if (typeof config.promotionThreshold === 'number') {\n validatePositiveInteger(config.promotionThreshold, 'promotionThreshold');\n }\n\n if (typeof config.hotQueueDecayFactor === 'number') {\n validateNumberRange(config.hotQueueDecayFactor, 0.0, 1.0, 'hotQueueDecayFactor');\n }\n\n if (typeof config.hotQueueDecayInterval === 'number') {\n validatePositiveInteger(config.hotQueueDecayInterval, 'hotQueueDecayInterval');\n }\n}\n\n/**\n * Validates any eviction strategy configuration\n */\nexport function validateEvictionStrategyConfig(config: Partial<EvictionStrategyConfigs>): void {\n if (!config || typeof config !== 'object') {\n throw new Error('Configuration must be a non-null object');\n }\n\n if (!config.type) {\n throw new Error('Configuration must specify a type');\n }\n\n const validTypes = ['lfu', 'lru', 'fifo', 'mru', 'random', 'arc', '2q'];\n if (!validTypes.includes(config.type)) {\n throw new Error(`Invalid eviction strategy type: ${config.type}. Must be one of: ${validTypes.join(', ')}`);\n }\n\n switch (config.type) {\n case 'lfu':\n validateLFUConfig(config as Partial<LFUConfig>);\n break;\n case 'arc':\n validateARCConfig(config as Partial<ARCConfig>);\n break;\n case '2q':\n validateTwoQueueConfig(config as Partial<TwoQueueConfig>);\n break;\n case 'lru':\n case 'fifo':\n case 'mru':\n case 'random':\n // These strategies have no additional configuration to validate\n break;\n default:\n // This should never happen due to the type check above, but included for completeness\n throw new Error(`Unsupported eviction strategy type: ${config.type}`);\n }\n}\n\n/**\n * Sanitizes configuration based on type\n */\nfunction sanitizeConfigByType(config: Partial<EvictionStrategyConfigs>): Partial<EvictionStrategyConfigs> {\n if (!config.type) {\n return config;\n }\n\n switch (config.type) {\n case 'lfu':\n return sanitizeLFUConfig(config as Partial<LFUConfig>);\n case 'arc':\n return sanitizeARCConfig(config as Partial<ARCConfig>);\n case '2q':\n return sanitizeTwoQueueConfig(config as Partial<TwoQueueConfig>);\n case 'lru':\n case 'fifo':\n case 'mru':\n case 'random':\n // These strategies have no additional configuration to sanitize\n return config;\n default:\n return config;\n }\n}\n\n/**\n * Creates a validated configuration with defaults applied and invalid values sanitized\n */\nexport function createValidatedConfig<T extends EvictionStrategyConfigs>(\n baseConfig: T,\n userConfig: Partial<T>\n): T {\n // Merge with defaults first\n const mergedConfig = { ...baseConfig, ...userConfig };\n\n // Sanitize the merged configuration\n const sanitizedConfig = sanitizeConfigByType(mergedConfig);\n\n // Validate the final sanitized configuration\n validateEvictionStrategyConfig(sanitizedConfig);\n\n return sanitizedConfig as T;\n}\n", "import { CacheItemMetadata, CacheMapMetadataProvider, EvictionContext, EvictionStrategy } from '../EvictionStrategy';\nimport { DEFAULT_LFU_CONFIG, LFUConfig } from '../EvictionStrategyConfig';\nimport { createValidatedConfig } from '../EvictionStrategyValidation';\n\n/**\n * High-quality hash function for Count-Min Sketch based on FNV-1a\n * Provides excellent avalanche effect and distribution properties\n */\nfunction fnv1aHash(key: string, seed: number): number {\n // FNV-1a constants for 32-bit hash\n const FNV_OFFSET_BASIS = 2166136261;\n const FNV_PRIME = 16777619;\n\n // Start with seed-modified offset basis for different hash functions\n let hash = (FNV_OFFSET_BASIS ^ seed) >>> 0;\n\n for (let i = 0; i < key.length; i++) {\n // XOR with byte value\n hash ^= key.charCodeAt(i);\n // Multiply by FNV prime\n hash = (hash * FNV_PRIME) >>> 0;\n }\n\n // Additional mixing for better avalanche\n hash ^= hash >>> 16;\n hash = (hash * 0x85ebca6b) >>> 0;\n hash ^= hash >>> 13;\n hash = (hash * 0xc2b2ae35) >>> 0;\n hash ^= hash >>> 16;\n\n return hash >>> 0;\n}\n\n/**\n * Count-Min Sketch for probabilistic frequency counting\n */\nclass CountMinSketch {\n private readonly sketches: number[][];\n private readonly width: number;\n private readonly depth: number;\n private readonly seeds: number[];\n\n constructor(width: number = 1024, depth: number = 4) {\n this.width = width;\n this.depth = depth;\n this.sketches = Array(depth).fill(null).map(() => new Array(width).fill(0));\n this.seeds = Array(depth).fill(null).map(() => Math.floor(Math.random() * 1000000));\n }\n\n /**\n * Check if a number is a power of 2 for optimized bit masking\n */\n private isPowerOfTwo(n: number): boolean {\n return n > 0 && (n & (n - 1)) === 0;\n }\n\n /**\n * Increment the frequency count for a key\n */\n increment(key: string): void {\n for (let i = 0; i < this.depth; i++) {\n // Use bit masking for better distribution when width is power of 2\n // For non-power of 2, fall back to modulo but with improved hash\n const hash = fnv1aHash(key, this.seeds[i]);\n const index = this.isPowerOfTwo(this.width)\n ? hash & (this.width - 1)\n : hash % this.width;\n this.sketches[i][index]++;\n }\n }\n\n /**\n * Estimate the frequency count for a key\n */\n estimate(key: string): number {\n let minCount = Infinity;\n for (let i = 0; i < this.depth; i++) {\n // Use same improved indexing as in increment method\n const hash = fnv1aHash(key, this.seeds[i]);\n const index = this.isPowerOfTwo(this.width)\n ? hash & (this.width - 1)\n : hash % this.width;\n minCount = Math.min(minCount, this.sketches[i][index]);\n }\n return minCount === Infinity ? 0 : minCount;\n }\n\n /**\n * Apply decay to all frequencies\n */\n decay(factor: number): void {\n for (let i = 0; i < this.depth; i++) {\n for (let j = 0; j < this.width; j++) {\n this.sketches[i][j] = Math.floor(this.sketches[i][j] * (1 - factor));\n }\n }\n }\n\n /**\n * Reset all frequencies to zero\n */\n reset(): void {\n for (let i = 0; i < this.depth; i++) {\n for (let j = 0; j < this.width; j++) {\n this.sketches[i][j] = 0;\n }\n }\n }\n}\n\n/**\n * LFU (Least Frequently Used) eviction strategy with frequency sketching and decay\n * Uses probabilistic counting and time-based frequency decay for more accurate frequency estimation\n * When configured with default settings, behaves like traditional LFU for backwards compatibility\n */\nexport class LFUEvictionStrategy extends EvictionStrategy {\n getStrategyName(): string {\n return 'lfu';\n }\n private readonly config: LFUConfig;\n private readonly sketch: CountMinSketch | null;\n private lastDecayTime: number;\n\n constructor(config: Partial<LFUConfig> = {}) {\n super();\n // Default to backwards-compatible behavior if no config provided\n const defaultBackwardsCompatible = {\n useProbabilisticCounting: false,\n decayFactor: 0,\n decayInterval: Number.MAX_SAFE_INTEGER\n };\n const baseConfig = { ...DEFAULT_LFU_CONFIG, ...defaultBackwardsCompatible };\n this.config = createValidatedConfig(baseConfig, config);\n this.sketch = this.config.useProbabilisticCounting\n ? new CountMinSketch(this.config.sketchWidth, this.config.sketchDepth)\n : null;\n this.lastDecayTime = Date.now();\n }\n\n selectForEviction(\n metadataProvider: CacheMapMetadataProvider,\n context: EvictionContext\n ): string[] {\n const allMetadata = metadataProvider.getAllMetadata();\n if (allMetadata.size === 0) return [];\n\n if (!this.isEvictionNeeded(context)) {\n return [];\n }\n\n const evictionCount = this.calculateEvictionCount(context);\n if (evictionCount <= 0) return [];\n\n // Apply periodic decay if needed\n this.applyPeriodicDecay();\n\n // Sort items by frequency (lowest first), then by age (oldest first)\n const sortedEntries = Array.from(allMetadata.entries()).sort((a, b) => {\n const freqA = this.getEffectiveFrequency(a[0], a[1]);\n const freqB = this.getEffectiveFrequency(b[0], b[1]);\n\n if (freqA !== freqB) {\n return freqA - freqB; // Lower frequency first\n }\n\n return a[1].lastAccessedAt - b[1].lastAccessedAt; // Older first\n });\n\n return sortedEntries.slice(0, evictionCount).map(([key]) => key);\n }\n\n onItemAccessed(key: string, metadataProvider: CacheMapMetadataProvider): void {\n const metadata = metadataProvider.getMetadata(key);\n if (!metadata) return;\n\n const now = Date.now();\n metadata.lastAccessedAt = now;\n metadata.accessCount++;\n\n // Update frequency tracking\n if (this.sketch) {\n this.sketch.increment(key);\n metadata.rawFrequency = this.sketch.estimate(key);\n } else {\n metadata.rawFrequency = metadata.accessCount; // Use access count in simple mode\n }\n\n // Always calculate frequency score for consistency\n metadata.frequencyScore = this.calculateFrequencyScore(metadata, now);\n metadata.lastFrequencyUpdate = now;\n\n metadataProvider.setMetadata(key, metadata);\n }\n\n onItemAdded(key: string, estimatedSize: number, metadataProvider: CacheMapMetadataProvider): void {\n const now = Date.now();\n const metadata: CacheItemMetadata = {\n key,\n addedAt: now,\n lastAccessedAt: now,\n accessCount: 1,\n estimatedSize,\n rawFrequency: 1\n };\n\n // Always initialize frequencyScore and lastFrequencyUpdate for consistency\n metadata.frequencyScore = 1;\n metadata.lastFrequencyUpdate = now;\n\n // Initialize in sketch\n if (this.sketch) {\n this.sketch.increment(key);\n }\n\n metadataProvider.setMetadata(key, metadata);\n }\n\n onItemRemoved(key: string, metadataProvider: CacheMapMetadataProvider): void {\n // Note: For Count-Min Sketch, we don't remove entries as it's a probabilistic structure\n // The decay mechanism will naturally reduce the impact of removed items over time\n metadataProvider.deleteMetadata(key);\n }\n\n /**\n * Get the effective frequency for an item, applying real-time decay if needed\n */\n private getEffectiveFrequency(_key: string, metadata: CacheItemMetadata): number {\n // If decay is disabled, use simple frequency counting\n if ((this.config.decayFactor ?? 0) === 0) {\n return metadata.rawFrequency || metadata.accessCount;\n }\n\n const now = Date.now();\n\n // If we have a recent frequency score, use it with minimal decay\n if (typeof metadata.frequencyScore === 'number' && typeof metadata.lastFrequencyUpdate === 'number') {\n const timeSinceUpdate = now - metadata.lastFrequencyUpdate;\n const decayAmount = (timeSinceUpdate / (this.config.decayInterval ?? 60000)) * (this.config.decayFactor ?? 0.1);\n return Math.max(this.config.minFrequencyThreshold ?? 1, metadata.frequencyScore * (1 - decayAmount));\n }\n\n // Fallback to raw frequency or access count\n return metadata.rawFrequency || metadata.accessCount;\n }\n\n /**\n * Calculate frequency score with decay applied\n */\n private calculateFrequencyScore(metadata: CacheItemMetadata, currentTime: number): number {\n const rawFreq = metadata.rawFrequency || metadata.accessCount;\n\n // If decay is disabled, just return raw frequency\n if ((this.config.decayFactor ?? 0) === 0) {\n return rawFreq;\n }\n\n if (typeof metadata.lastFrequencyUpdate !== 'number') {\n return rawFreq;\n }\n\n const timeSinceUpdate = currentTime - metadata.lastFrequencyUpdate;\n const decayAmount = (timeSinceUpdate / (this.config.decayInterval ?? 60000)) * (this.config.decayFactor ?? 0.1);\n const previousScore = metadata.frequencyScore || rawFreq;\n\n // Apply decay to previous score and add new frequency contribution\n const decayedScore = previousScore * (1 - decayAmount);\n return Math.max(this.config.minFrequencyThreshold ?? 1, decayedScore + 1);\n }\n\n /**\n * Apply periodic decay to the frequency sketch and metadata\n */\n private applyPeriodicDecay(): void {\n if ((this.config.decayFactor ?? 0) === 0) return;\n\n const now = Date.now();\n const timeSinceDecay = now - this.lastDecayTime;\n\n if (timeSinceDecay >= (this.config.decayInterval ?? 60000)) {\n if (this.sketch) {\n this.sketch.decay(this.config.decayFactor ?? 0.1);\n }\n this.lastDecayTime = now;\n }\n }\n\n /**\n * Get configuration for this strategy\n */\n getConfig(): LFUConfig {\n return { ...this.config };\n }\n\n /**\n * Reset frequency tracking (useful for testing or cache clearing)\n */\n reset(): void {\n if (this.sketch) {\n this.sketch.reset();\n }\n this.lastDecayTime = Date.now();\n }\n}\n", "import {\n CacheItemMetadata,\n CacheMapMetadataProvider,\n EvictionContext,\n EvictionStrategy\n} from '../EvictionStrategy';\n\n/**\n * FIFO (First-In, First-Out) eviction strategy\n * Removes the oldest added item regardless of usage\n */\nexport class FIFOEvictionStrategy extends EvictionStrategy {\n selectForEviction(\n metadataProvider: CacheMapMetadataProvider,\n context: EvictionContext\n ): string[] {\n if (!this.isEvictionNeeded(context)) {\n return [];\n }\n\n const allMetadata = metadataProvider.getAllMetadata();\n if (allMetadata.size === 0) {\n return [];\n }\n\n const evictionCount = this.calculateEvictionCount(context);\n const keysToEvict: string[] = [];\n\n // Sort by addedAt ascending (oldest first)\n const sortedEntries = Array.from(allMetadata.entries())\n .sort(([, a], [, b]) => a.addedAt - b.addedAt);\n\n // Take the oldest items up to evictionCount\n for (let i = 0; i < Math.min(evictionCount, sortedEntries.length); i++) {\n keysToEvict.push(sortedEntries[i][0]);\n }\n\n return keysToEvict;\n }\n\n onItemAccessed(key: string, metadataProvider: CacheMapMetadataProvider): void {\n const metadata = metadataProvider.getMetadata(key);\n if (metadata) {\n metadata.lastAccessedAt = Date.now();\n metadata.accessCount++;\n metadataProvider.setMetadata(key, metadata);\n }\n }\n\n onItemAdded(key: string, estimatedSize: number, metadataProvider: CacheMapMetadataProvider): void {\n const now = Date.now();\n const metadata: CacheItemMetadata = {\n key,\n addedAt: now,\n lastAccessedAt: now,\n accessCount: 1,\n estimatedSize\n };\n metadataProvider.setMetadata(key, metadata);\n }\n\n onItemRemoved(key: string, metadataProvider: CacheMapMetadataProvider): void {\n metadataProvider.deleteMetadata(key);\n }\n\n getStrategyName(): string {\n return 'fifo';\n }\n}\n", "import { CacheItemMetadata, CacheMapMetadataProvider, EvictionContext, EvictionStrategy } from '../EvictionStrategy';\n\n/**\n * MRU (Most Recently Used) eviction strategy\n * Removes the most recently accessed item\n */\nexport class MRUEvictionStrategy extends EvictionStrategy {\n getStrategyName(): string {\n return 'MRU';\n }\n selectForEviction(\n metadataProvider: CacheMapMetadataProvider,\n context: EvictionContext\n ): string[] {\n const allMetadata = metadataProvider.getAllMetadata();\n if (allMetadata.size === 0) return [];\n\n if (!this.isEvictionNeeded(context)) {\n return [];\n }\n\n const evictionCount = this.calculateEvictionCount(context);\n if (evictionCount <= 0) return [];\n\n // Sort items by access time (newest first)\n const sortedEntries = Array.from(allMetadata.entries()).sort((a, b) => {\n return b[1].lastAccessedAt - a[1].lastAccessedAt; // Newer first\n });\n\n return sortedEntries.slice(0, evictionCount).map(([key]) => key);\n }\n\n onItemAccessed(key: string, metadataProvider: CacheMapMetadataProvider): void {\n const metadata = metadataProvider.getMetadata(key);\n if (!metadata) return;\n\n metadata.lastAccessedAt = Date.now();\n metadata.accessCount++;\n\n metadataProvider.setMetadata(key, metadata);\n }\n\n onItemAdded(key: string, estimatedSize: number, metadataProvider: CacheMapMetadataProvider): void {\n const now = Date.now();\n const metadata: CacheItemMetadata = {\n key,\n addedAt: now,\n lastAccessedAt: now,\n accessCount: 1,\n estimatedSize\n };\n\n metadataProvider.setMetadata(key, metadata);\n }\n\n onItemRemoved(key: string, metadataProvider: CacheMapMetadataProvider): void {\n metadataProvider.deleteMetadata(key);\n }\n}\n", "import {\n CacheItemMetadata,\n CacheMapMetadataProvider,\n EvictionContext,\n EvictionStrategy\n} from '../EvictionStrategy';\n\n/**\n * Random eviction strategy\n * Removes a random item from the cache\n */\nexport class RandomEvictionStrategy extends EvictionStrategy {\n selectForEviction(\n metadataProvider: CacheMapMetadataProvider,\n context: EvictionContext\n ): string[] {\n if (!this.isEvictionNeeded(context)) {\n return [];\n }\n\n const allMetadata = metadataProvider.getAllMetadata();\n if (allMetadata.size === 0) {\n return [];\n }\n\n const evictionCount = this.calculateEvictionCount(context);\n const keys = Array.from(allMetadata.keys());\n const keysToEvict: string[] = [];\n\n // Randomly select items to evict\n const availableKeys = [...keys];\n for (let i = 0; i < Math.min(evictionCount, availableKeys.length); i++) {\n const randomIndex = Math.floor(Math.random() * availableKeys.length);\n keysToEvict.push(availableKeys.splice(randomIndex, 1)[0]);\n }\n\n return keysToEvict;\n }\n\n onItemAccessed(key: string, metadataProvider: CacheMapMetadataProvider): void {\n const metadata = metadataProvider.getMetadata(key);\n if (metadata) {\n metadata.lastAccessedAt = Date.now();\n metadata.accessCount++;\n metadataProvider.setMetadata(key, metadata);\n }\n }\n\n onItemAdded(key: string, estimatedSize: number, metadataProvider: CacheMapMetadataProvider): void {\n const now = Date.now();\n const metadata: CacheItemMetadata = {\n key,\n addedAt: now,\n lastAccessedAt: now,\n accessCount: 1,\n estimatedSize\n };\n metadataProvider.setMetadata(key, metadata);\n }\n\n onItemRemoved(key: string, metadataProvider: CacheMapMetadataProvider): void {\n metadataProvider.deleteMetadata(key);\n }\n\n getStrategyName(): string {\n return 'random';\n }\n}\n", "import { CacheItemMetadata, CacheMapMetadataProvider, EvictionContext, EvictionStrategy } from '../EvictionStrategy';\nimport { ARCConfig, DEFAULT_ARC_CONFIG } from '../EvictionStrategyConfig';\nimport { createValidatedConfig } from '../EvictionStrategyValidation';\n\n/**\n * ARC (Adaptive Replacement Cache) eviction strategy with enhanced frequency tracking\n * Balances between recency (LRU) and frequency (LFU) dynamically with sophisticated frequency analysis\n */\nexport class ARCEvictionStrategy extends EvictionStrategy {\n getStrategyName(): string {\n return 'ARC';\n }\n private recentGhosts = new Set<string>(); // T1 ghost entries\n private frequentGhosts = new Set<string>(); // T2 ghost entries\n private targetRecentSize = 0; // Target size for T1 (recent entries)\n private readonly config: ARCConfig;\n private readonly maxGhostSize: number;\n private lastDecayTime: number;\n\n constructor(maxCacheSize: number = 1000, config: Partial<ARCConfig> = {}) {\n super();\n const baseConfig = { ...DEFAULT_ARC_CONFIG, maxCacheSize };\n this.config = createValidatedConfig(baseConfig, config);\n this.maxGhostSize = this.config.maxCacheSize!;\n this.lastDecayTime = Date.now();\n }\n\n selectForEviction(\n metadataProvider: CacheMapMetadataProvider,\n context: EvictionContext\n ): string[] {\n const allMetadata = metadataProvider.getAllMetadata();\n if (allMetadata.size === 0) return [];\n\n if (!this.isEvictionNeeded(context)) {\n return [];\n }\n\n const evictionCount = this.calculateEvictionCount(context);\n if (evictionCount <= 0) return [];\n\n // Apply periodic decay if enabled\n this.applyPeriodicDecay(allMetadata);\n\n // Split items into recent (T1) and frequent (T2) based on enhanced frequency analysis\n const recentItems = new Map<string, CacheItemMetadata>();\n const frequentItems = new Map<string, CacheItemMetadata>();\n\n for (const [key, metadata] of allMetadata) {\n if (this.isFrequentItem(metadata)) {\n frequentItems.set(key, metadata);\n } else {\n recentItems.set(key, metadata);\n }\n }\n\n const keysToEvict: string[] = [];\n const totalItems = recentItems.size + frequentItems.size;\n const maxIterations = Math.min(evictionCount, totalItems);\n\n for (let i = 0; i < maxIterations; i++) {\n let keyToEvict: string | null = null;\n let sourceList: Map<string, CacheItemMetadata> | null = null;\n\n // Decide which list to evict from based on target sizes and adaptive algorithm\n if (recentItems.size > this.targetRecentSize && recentItems.size > 0) {\n // Evict from recent list (T1)\n keyToEvict = this.config.useFrequencyWeightedSelection\n ? this.selectFrequencyWeightedFromItems(recentItems, 'recent')\n : this.selectLRUFromItems(recentItems);\n sourceList = recentItems;\n } else if (frequentItems.size > 0) {\n // Evict from frequent list (T2)\n keyToEvict = this.config.useFrequencyWeightedSelection\n ? this.selectFrequencyWeightedFromItems(frequentItems, 'frequent')\n : this.selectLRUFromItems(frequentItems);\n sourceList = frequentItems;\n } else if (recentItems.size > 0) {\n // Fallback: evict from recent if it's the only list with items\n keyToEvict = this.config.useFrequencyWeightedSelection\n ? this.selectFrequencyWeightedFromItems(recentItems, 'recent')\n : this.selectLRUFromItems(recentItems);\n sourceList = recentItems;\n }\n\n if (keyToEvict && sourceList) {\n keysToEvict.push(keyToEvict);\n sourceList.delete(keyToEvict);\n } else {\n // No valid key found or no more items available\n break;\n }\n\n // Safety check: if we've evicted all items, stop\n if (recentItems.size === 0 && frequentItems.size === 0) {\n break;\n }\n }\n\n return keysToEvict;\n }\n\n private selectLRUFromItems(items: Map<string, CacheItemMetadata>): string | null {\n if (items.size === 0) {\n return null;\n }\n\n let oldestKey: string | null = null;\n let oldestTime = Infinity;\n const now = Date.now();\n\n for (const [key, metadata] of items) {\n // Validate metadata to prevent corruption\n if (!metadata || typeof metadata.lastAccessedAt !== 'number' || metadata.lastAccessedAt > now) {\n continue;\n }\n\n if (metadata.lastAccessedAt < oldestTime) {\n oldestTime = metadata.lastAccessedAt;\n oldestKey = key;\n }\n }\n\n // If no valid key found through LRU logic, fall back to first available key\n if (oldestKey !== null) {\n return oldestKey;\n }\n\n // Fallback to first available key if items exist\n if (items.size > 0) {\n const firstKey = items.keys().next().value;\n return firstKey ?? null;\n }\n\n return null;\n }\n\n onItemAccessed(key: string, metadataProvider: CacheMapMetadataProvider): void {\n const metadata = metadataProvider.getMetadata(key);\n if (!metadata) return;\n\n const now = Date.now();\n\n // Create a copy of metadata to avoid direct mutation of shared state\n const updatedMetadata: CacheItemMetadata = {\n ...metadata,\n lastAccessedAt: now,\n accessCount: metadata.accessCount + 1\n };\n\n // Update frequency tracking\n updatedMetadata.rawFrequency = updatedMetadata.accessCount;\n\n // Update frequency score with decay if enabled\n if (this.config.useEnhancedFrequency && (this.config.frequencyDecayFactor ?? 0) > 0) {\n updatedMetadata.frequencyScore = this.calculateFrequencyScore(updatedMetadata, now);\n updatedMetadata.lastFrequencyUpdate = now;\n }\n\n // Adjust target size based on ghost list hits with adaptive learning\n const learningRate = this.config.adaptiveLearningRate ?? 1.0;\n let targetAdjusted = false;\n\n if (learningRate > 0) {\n if (this.recentGhosts.has(key)) {\n // Hit in recent ghost list - increase target for recent items\n const adjustment = Math.max(1, Math.ceil(learningRate));\n this.targetRecentSize = Math.min(this.targetRecentSize + adjustment, this.maxGhostSize);\n this.recentGhosts.delete(key);\n targetAdjusted = true;\n } else if (this.frequentGhosts.has(key)) {\n // Hit in frequent ghost list - decrease target for recent items\n const adjustment = Math.max(1, Math.ceil(learningRate));\n this.targetRecentSize = Math.max(this.targetRecentSize - adjustment, 0);\n this.frequentGhosts.delete(key);\n targetAdjusted = true;\n }\n } else {\n // Even with zero learning rate, remove from ghost lists to prevent memory leaks\n if (this.recentGhosts.has(key)) {\n this.recentGhosts.delete(key);\n } else if (this.frequentGhosts.has(key)) {\n this.frequentGhosts.delete(key);\n }\n }\n\n // Clean up ghost lists if they were modified\n if (targetAdjusted) {\n this.cleanupGhostLists();\n }\n\n metadataProvider.setMetadata(key, updatedMetadata);\n }\n\n onItemAdded(key: string, estimatedSize: number, metadataProvider: CacheMapMetadataProvider): void {\n const now = Date.now();\n const metadata: CacheItemMetadata = {\n key,\n addedAt: now,\n lastAccessedAt: now,\n accessCount: 1,\n estimatedSize,\n rawFrequency: 1\n };\n\n // Initialize frequency score for decay tracking\n if (this.config.useEnhancedFrequency && (this.config.frequencyDecayFactor ?? 0) > 0) {\n metadata.frequencyScore = 1;\n metadata.lastFrequencyUpdate = now;\n }\n\n metadataProvider.setMetadata(key, metadata);\n }\n\n onItemRemoved(key: string, metadataProvider: CacheMapMetadataProvider): void {\n const metadata = metadataProvider.getMetadata(key);\n\n // Determine which ghost list to add to based on item characteristics\n if (metadata && this.isFrequentItem(metadata)) {\n this.addToFrequentGhosts(key);\n } else {\n this.addToRecentGhosts(key);\n }\n\n // Clean up metadata first to avoid accessing stale data\n metadataProvider.deleteMetadata(key);\n\n // Ensure both ghost lists stay within bounds after modifications\n this.cleanupGhostLists();\n }\n\n /**\n * Add key to recent ghost list with proper size management\n */\n private addToRecentGhosts(key: string): void {\n // Remove from frequent ghosts if present (item moved lists)\n this.frequentGhosts.delete(key);\n\n // Add to recent ghosts\n this.recentGhosts.add(key);\n\n // Maintain size limit by removing oldest entries\n this.enforceGhostListSizeLimit(this.recentGhosts, this.maxGhostSize);\n }\n\n /**\n * Add key to frequent ghost list with proper size management\n */\n private addToFrequentGhosts(key: string): void {\n // Remove from recent ghosts if present (item moved lists)\n this.recentGhosts.delete(key);\n\n // Add to frequent ghosts\n this.frequentGhosts.add(key);\n\n // Maintain size limit by removing oldest entries\n this.enforceGhostListSizeLimit(this.frequentGhosts, this.maxGhostSize);\n }\n\n /**\n * Cleanup ghost lists to prevent memory leaks\n */\n private cleanupGhostLists(): void {\n this.enforceGhostListSizeLimit(this.recentGhosts, this.maxGhostSize);\n this.enforceGhostListSizeLimit(this.frequentGhosts, this.maxGhostSize);\n }\n\n /**\n * Enforce size limit on a ghost list by removing oldest entries\n */\n private enforceGhostListSizeLimit(ghostList: Set<string>, maxSize: number): void {\n if (maxSize <= 0) {\n ghostList.clear();\n return;\n }\n\n // Remove excess entries from the beginning (oldest)\n const iterator = ghostList.values();\n while (ghostList.size > maxSize) {\n const next = iterator.next();\n if (next.done) {\n break; // Safety check - no more items\n }\n ghostList.delete(next.value);\n }\n }\n\n /**\n * Determine if an item should be classified as frequent vs recent\n */\n private isFrequentItem(metadata: CacheItemMetadata): boolean {\n if (!this.config.useEnhancedFrequency) {\n // Traditional ARC behavior\n return metadata.accessCount > 1;\n }\n\n // Enhanced frequency-based classification\n const frequency = this.getEffectiveFrequency(metadata);\n return frequency >= (this.config.frequencyThreshold ?? 2);\n }\n\n /**\n * Get effective frequency for an item, applying decay if enabled\n */\n private getEffectiveFrequency(metadata: CacheItemMetadata): number {\n if (!this.config.useEnhancedFrequency || (this.config.frequencyDecayFactor ?? 0) === 0) {\n return metadata.rawFrequency || metadata.accessCount;\n }\n\n const now = Date.now();\n\n // If we have a frequency score with decay tracking\n if (typeof metadata.frequencyScore === 'number' && typeof metadata.lastFrequencyUpdate === 'number') {\n const timeSinceUpdate = now - metadata.lastFrequencyUpdate;\n const decayInterval = this.config.frequencyDecayInterval ?? 600000;\n\n // Only apply decay if significant time has passed\n if (timeSinceUpdate > decayInterval / 10) { // Apply decay after 10% of interval\n const decayAmount = Math.min(0.9, (timeSinceUpdate / decayInterval) * (this.config.frequencyDecayFactor ?? 0.05));\n return Math.max(1, metadata.frequencyScore * (1 - decayAmount));\n }\n\n return metadata.frequencyScore;\n }\n\n // Fallback to raw frequency\n return metadata.rawFrequency || metadata.accessCount;\n }\n\n /**\n * Calculate frequency score with decay applied\n */\n private calculateFrequencyScore(metadata: CacheItemMetadata, currentTime: number): number {\n const rawFreq = metadata.rawFrequency || metadata.accessCount;\n\n // If no previous frequency tracking, start with raw frequency\n if (typeof metadata.lastFrequencyUpdate !== 'number') {\n return rawFreq;\n }\n\n const timeSinceUpdate = currentTime - metadata.lastFrequencyUpdate;\n const decayInterval = this.config.frequencyDecayInterval ?? 600000;\n const decayFactor = this.config.frequencyDecayFactor ?? 0.05;\n\n // Calculate decay amount, but cap it to prevent over-decay\n const decayAmount = Math.min(0.9, (timeSinceUpdate / decayInterval) * decayFactor);\n const previousScore = metadata.frequencyScore || rawFreq;\n\n // Apply decay to previous score and add new frequency contribution\n const decayedScore = Math.max(1, previousScore * (1 - decayAmount));\n return Math.max(1, decayedScore + 1);\n }\n\n /**\n * Select eviction candidate using frequency-weighted approach\n */\n private selectFrequencyWeightedFromItems(items: Map<string, CacheItemMetadata>, context: 'recent' | 'frequent' | 'fallback'): string | null {\n if (items.size === 0) {\n return null;\n }\n\n let bestKey: string | null = null;\n let bestScore = Infinity;\n const now = Date.now();\n\n for (const [key, metadata] of items) {\n // Validate metadata to prevent corruption\n if (!metadata || typeof metadata.lastAccessedAt !== 'number' || metadata.lastAccessedAt > now) {\n continue;\n }\n\n // Calculate weighted score based on context\n const frequency = this.getEffectiveFrequency(metadata);\n const timeFactor = Math.max(0, now - metadata.lastAccessedAt);\n\n let score: number;\n if (context === 'recent') {\n // In recent list, prioritize by recency more heavily\n score = timeFactor + (1000 / Math.max(1, frequency));\n } else if (context === 'frequent') {\n // In frequent list, balance frequency and recency\n score = (timeFactor / 1000) + (10 / Math.max(1, frequency));\n } else {\n // Fallback - use balanced approach\n score = (timeFactor / 1000) / Math.max(1, frequency);\n }\n\n if (score < bestScore) {\n bestScore = score;\n bestKey = key;\n }\n }\n\n // If no valid key found through scoring, fall back to first available key\n if (bestKey !== null) {\n return bestKey;\n }\n\n // Fallback to first available key if items exist\n if (items.size > 0) {\n const firstKey = items.keys().next().value;\n return firstKey ?? null;\n }\n\n return null;\n }\n\n /**\n * Apply periodic decay to frequency scores\n */\n private applyPeriodicDecay(items: Map<string, CacheItemMetadata>): void {\n if (!this.config.useEnhancedFrequency || (this.config.frequencyDecayFactor ?? 0) === 0) return;\n\n const now = Date.now();\n const timeSinceDecay = now - this.lastDecayTime;\n const decayInterval = this.config.frequencyDecayInterval ?? 600000;\n\n if (timeSinceDecay >= decayInterval && items.size > 0) {\n const decayFactor = this.config.frequencyDecayFactor ?? 0.05;\n\n // Apply decay to all items that have frequency scores\n for (const metadata of items.values()) {\n if (typeof metadata.frequencyScore === 'number') {\n // Calculate time-based decay to handle cases where multiple intervals passed\n const intervalsPassed = timeSinceDecay / decayInterval;\n const totalDecay = Math.min(0.9, decayFactor * intervalsPassed); // Cap decay to prevent over-decay\n const newScore = metadata.frequencyScore * (1 - totalDecay);\n metadata.frequencyScore = Math.max(1, newScore);\n metadata.lastFrequencyUpdate = now;\n }\n }\n\n this.lastDecayTime = now;\n }\n }\n\n /**\n * Get configuration for this strategy\n */\n getConfig(): ARCConfig {\n return { ...this.config };\n }\n\n /**\n * Reset internal state (useful for testing)\n */\n reset(): void {\n this.recentGhosts.clear();\n this.frequentGhosts.clear();\n this.targetRecentSize = 0;\n this.lastDecayTime = Date.now();\n }\n\n /**\n * Get current adaptive state for monitoring/debugging\n */\n getAdaptiveState(): { targetRecentSize: number; recentGhostSize: number; frequentGhostSize: number } {\n return {\n targetRecentSize: this.targetRecentSize,\n recentGhostSize: this.recentGhosts.size,\n frequentGhostSize: this.frequentGhosts.size\n };\n }\n}\n", "import { CacheItemMetadata, CacheMapMetadataProvider, EvictionContext, EvictionStrategy } from '../EvictionStrategy';\nimport { DEFAULT_TWO_QUEUE_CONFIG, TwoQueueConfig } from '../EvictionStrategyConfig';\nimport { createValidatedConfig } from '../EvictionStrategyValidation';\n\n/**\n * 2Q (Two Queues) eviction strategy with enhanced frequency tracking\n * Maintains separate queues for recent and frequently accessed items\n * Uses frequency analysis for promotion decisions and weighted LRU in hot queue\n */\nexport class TwoQueueEvictionStrategy extends EvictionStrategy {\n getStrategyName(): string {\n return '2Q';\n }\n private recentQueue: string[] = []; // A1 queue for recent items\n private hotQueue: string[] = []; // Am queue for hot items\n private ghostQueue = new Set<string>(); // A1out ghost queue\n private readonly config: TwoQueueConfig;\n private readonly maxRecentSize: number;\n private readonly maxGhostSize: number;\n private lastDecayTime: number;\n\n constructor(maxCacheSize: number = 1000, config: Partial<TwoQueueConfig> = {}) {\n super();\n const baseConfig = { ...DEFAULT_TWO_QUEUE_CONFIG, maxCacheSize };\n this.config = createValidatedConfig(baseConfig, config);\n // Allocate 25% to recent queue, 75% to hot queue\n this.maxRecentSize = Math.max(1, Math.floor(this.config.maxCacheSize! * 0.25));\n this.maxGhostSize = this.config.maxCacheSize!;\n this.lastDecayTime = Date.now();\n }\n\n selectForEviction(\n metadataProvider: CacheMapMetadataProvider,\n context: EvictionContext\n ): string[] {\n const allMetadata = metadataProvider.getAllMetadata();\n if (allMetadata.size === 0) return [];\n\n if (!this.isEvictionNeeded(context)) {\n return [];\n }\n\n const evictionCount = this.calculateEvictionCount(context);\n if (evictionCount <= 0) return [];\n\n // Apply periodic decay if enabled\n this.applyPeriodicDecay(allMetadata);\n\n const keysToEvict: string[] = [];\n\n for (let i = 0; i < evictionCount; i++) {\n let keyToEvict: string | null = null;\n\n // First try to evict from recent queue (A1) - evict oldest (tail) of recent queue\n for (let j = this.recentQueue.length - 1; j >= 0; j--) {\n const key = this.recentQueue[j];\n if (allMetadata.has(key) && !keysToEvict.includes(key)) {\n keyToEvict = key;\n break;\n }\n }\n\n // If no valid key in recent queue, try hot queue\n if (!keyToEvict) {\n if (this.config.useFrequencyWeightedLRU) {\n keyToEvict = this.selectFromHotQueueFrequencyWeighted(allMetadata, keysToEvict);\n } else {\n keyToEvict = this.selectFromHotQueueLRU(allMetadata, keysToEvict);\n }\n }\n\n if (keyToEvict) {\n keysToEvict.push(keyToEvict);\n } else {\n break; // No more items to evict\n }\n }\n\n return keysToEvict;\n }\n\n /**\n * Select eviction candidate from hot queue using traditional LRU\n */\n private selectFromHotQueueLRU(items: Map<string, CacheItemMetadata>, excludeKeys: string[] = []): string | null {\n let oldestKey: string | null = null;\n let oldestTime = Infinity;\n\n for (const key of this.hotQueue) {\n if (excludeKeys.includes(key)) continue;\n const metadata = items.get(key);\n if (metadata && metadata.lastAccessedAt < oldestTime) {\n oldestTime = metadata.lastAccessedAt;\n oldestKey = key;\n }\n }\n\n return oldestKey || (items.size > 0 ? (items.keys().next().value ?? null) : null);\n }\n\n /**\n * Select eviction candidate from hot queue using frequency-weighted LRU\n */\n private selectFromHotQueueFrequencyWeighted(items: Map<string, CacheItemMetadata>, excludeKeys: string[] = []): string | null {\n let bestKey: string | null = null;\n let lowestScore = Infinity;\n\n for (const key of this.hotQueue) {\n if (excludeKeys.includes(key)) continue;\n const metadata = items.get(key);\n if (!metadata) continue;\n\n // Calculate frequency-weighted score (lower = more likely to evict)\n const frequency = this.getEffectiveFrequency(metadata);\n const timeFactor = Date.now() - metadata.lastAccessedAt;\n\n // Score combines frequency (lower is worse) and recency (higher is worse)\n // Normalize time factor to similar scale as frequency\n const normalizedTimeFactor = timeFactor / (1000 * 60); // Convert to minutes\n const score = normalizedTimeFactor / Math.max(1, frequency);\n\n if (score < lowestScore) {\n lowestScore = score;\n bestKey = key;\n }\n }\n\n return bestKey || (items.size > 0 ? (items.keys().next().value ?? null) : null);\n }\n\n onItemAccessed(key: string, metadataProvider: CacheMapMetadataProvider): void {\n const metadata = metadataProvider.getMetadata(key);\n if (!metadata) return;\n\n const now = Date.now();\n metadata.lastAccessedAt = now;\n metadata.accessCount++;\n\n // Update frequency tracking similar to LFU strategy\n metadata.rawFrequency = metadata.accessCount;\n\n // Update frequency score with decay if enabled\n if ((this.config.hotQueueDecayFactor ?? 0) > 0) {\n metadata.frequencyScore = this.calculateFrequencyScore(metadata, now);\n metadata.lastFrequencyUpdate = now;\n }\n\n // Handle promotion from recent to hot queue\n const recentIndex = this.recentQueue.indexOf(key);\n if (recentIndex !== -1) {\n // Item is in recent queue - check if it should be promoted\n if (this.shouldPromoteToHotQueue(metadata)) {\n this.recentQueue.splice(recentIndex, 1);\n this.hotQueue.unshift(key); // Add to front of hot queue\n }\n } else {\n // Update position in hot queue (move to front)\n const hotIndex = this.hotQueue.indexOf(key);\n if (hotIndex !== -1) {\n this.hotQueue.splice(hotIndex, 1);\n this.hotQueue.unshift(key);\n }\n }\n\n metadataProvider.setMetadata(key, metadata);\n }\n\n onItemAdded(key: string, estimatedSize: number, metadataProvider: CacheMapMetadataProvider): void {\n const now = Date.now();\n let metadata = metadataProvider.getMetadata(key);\n\n if (!metadata) {\n metadata = {\n key,\n addedAt: now,\n lastAccessedAt: now,\n accessCount: 1,\n estimatedSize,\n rawFrequency: 1\n };\n\n // Initialize frequency score for decay tracking\n if ((this.config.hotQueueDecayFactor ?? 0) > 0) {\n metadata.frequencyScore = 1;\n metadata.lastFrequencyUpdate = now;\n }\n }\n\n // Check if this was in ghost queue (promote to hot)\n if (this.ghostQueue.has(key)) {\n this.ghostQueue.delete(key);\n this.hotQueue.unshift(key);\n } else {\n // Add to recent queue\n this.recentQueue.unshift(key);\n\n // Limit recent queue size\n if (this.recentQueue.length > this.maxRecentSize) {\n const evicted = this.recentQueue.pop();\n if (evicted) {\n this.ghostQueue.add(evicted);\n }\n }\n }\n\n // Limit ghost queue size\n if (this.ghostQueue.size > this.maxGhostSize) {\n const firstKey = this.ghostQueue.values().next().value;\n if (firstKey) {\n this.ghostQueue.delete(firstKey);\n }\n }\n\n metadataProvider.setMetadata(key, metadata);\n }\n\n onItemRemoved(key: string, metadataProvider: CacheMapMetadataProvider): void {\n // Remove from appropriate queue\n const recentIndex = this.recentQueue.indexOf(key);\n if (recentIndex !== -1) {\n this.recentQueue.splice(recentIndex, 1);\n }\n\n const hotIndex = this.hotQueue.indexOf(key);\n if (hotIndex !== -1) {\n this.hotQueue.splice(hotIndex, 1);\n }\n\n // Clean up metadata\n metadataProvider.deleteMetadata(key);\n }\n\n /**\n * Determine if an item should be promoted from recent to hot queue\n */\n private shouldPromoteToHotQueue(metadata: CacheItemMetadata): boolean {\n if (!this.config.useFrequencyPromotion) {\n // Traditional 2Q behavior - promote on second access\n return metadata.accessCount >= 2;\n }\n\n // Frequency-based promotion\n const threshold = this.config.promotionThreshold ?? 2;\n const frequency = this.getEffectiveFrequency(metadata);\n return frequency >= threshold;\n }\n\n /**\n * Get effective frequency for an item, applying decay if enabled\n */\n private getEffectiveFrequency(metadata: CacheItemMetadata): number {\n // If decay is disabled, use raw frequency\n if ((this.config.hotQueueDecayFactor ?? 0) === 0) {\n return metadata.rawFrequency || metadata.accessCount;\n }\n\n const now = Date.now();\n\n // If we have a frequency score with decay tracking\n if (typeof metadata.frequencyScore === 'number' && typeof metadata.lastFrequencyUpdate === 'number') {\n const timeSinceUpdate = now - metadata.lastFrequencyUpdate;\n const decayAmount = (timeSinceUpdate / (this.config.hotQueueDecayInterval ?? 300000)) * (this.config.hotQueueDecayFactor ?? 0.05);\n return Math.max(1, metadata.frequencyScore * (1 - decayAmount));\n }\n\n // Fallback to raw frequency\n return metadata.rawFrequency || metadata.accessCount;\n }\n\n /**\n * Calculate frequency score with decay applied\n */\n private calculateFrequencyScore(metadata: CacheItemMetadata, currentTime: number): number {\n const rawFreq = metadata.rawFrequency || metadata.accessCount;\n\n if (typeof metadata.lastFrequencyUpdate !== 'number') {\n return rawFreq;\n }\n\n const timeSinceUpdate = currentTime - metadata.lastFrequencyUpdate;\n const decayAmount = (timeSinceUpdate / (this.config.hotQueueDecayInterval ?? 300000)) * (this.config.hotQueueDecayFactor ?? 0.05);\n const previousScore = metadata.frequencyScore || rawFreq;\n\n // Apply decay to previous score and add new frequency contribution\n const decayedScore = previousScore * (1 - decayAmount);\n return Math.max(1, decayedScore + 1);\n }\n\n /**\n * Apply periodic decay to hot queue items\n */\n private applyPeriodicDecay(items: Map<string, CacheItemMetadata>): void {\n if ((this.config.hotQueueDecayFactor ?? 0) === 0) return;\n\n const now = Date.now();\n const timeSinceDecay = now - this.lastDecayTime;\n\n if (timeSinceDecay >= (this.config.hotQueueDecayInterval ?? 300000)) {\n // Only update lastDecayTime if we actually have items to decay\n if (this.hotQueue.length > 0) {\n // Apply decay to all items in hot queue\n for (const key of this.hotQueue) {\n const metadata = items.get(key);\n if (metadata && typeof metadata.frequencyScore === 'number') {\n const decayAmount = (this.config.hotQueueDecayFactor ?? 0.05);\n metadata.frequencyScore = Math.max(1, metadata.frequencyScore * (1 - decayAmount));\n }\n }\n this.lastDecayTime = now;\n }\n }\n }\n\n /**\n * Get configuration for this strategy\n */\n getConfig(): TwoQueueConfig {\n return { ...this.config };\n }\n\n /**\n * Reset internal state (useful for testing)\n */\n reset(): void {\n this.recentQueue = [];\n this.hotQueue = [];\n this.ghostQueue.clear();\n this.lastDecayTime = Date.now();\n }\n}\n", "import { EvictionPolicy } from '../Options';\nimport { EvictionStrategy } from './EvictionStrategy';\nimport {\n DEFAULT_ARC_CONFIG,\n DEFAULT_TWO_QUEUE_CONFIG,\n EvictionStrategyConfigs\n} from './EvictionStrategyConfig';\n\n// Import all strategy classes\nimport { LRUEvictionStrategy } from './strategies/LRUEvictionStrategy';\nimport { LFUEvictionStrategy } from './strategies/LFUEvictionStrategy';\nimport { FIFOEvictionStrategy } from './strategies/FIFOEvictionStrategy';\nimport { MRUEvictionStrategy } from './strategies/MRUEvictionStrategy';\nimport { RandomEvictionStrategy } from './strategies/RandomEvictionStrategy';\nimport { ARCEvictionStrategy } from './strategies/ARCEvictionStrategy';\nimport { TwoQueueEvictionStrategy } from './strategies/TwoQueueEvictionStrategy';\n\n/**\n * Factory function to create eviction strategy instances with configuration\n */\nexport function createEvictionStrategy(\n policy: EvictionPolicy,\n maxCacheSize?: number,\n config?: EvictionStrategyConfigs\n): EvictionStrategy {\n // Handle edge case of invalid maxCacheSize by using a reasonable default\n const safeMaxCacheSize = (typeof maxCacheSize === 'number' && maxCacheSize > 0) ? maxCacheSize : 1000;\n\n switch (policy) {\n case 'lru':\n return new LRUEvictionStrategy();\n case 'lfu': {\n try {\n const lfuConfig = config?.type === 'lfu' ? config : { type: 'lfu' as const };\n return new LFUEvictionStrategy(lfuConfig);\n } catch (error) {\n // If LFU strategy creation fails due to invalid config, fall back to LRU\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.warn(`Failed to create lfu strategy with provided configuration, falling back to LRU:`, errorMessage);\n return new LRUEvictionStrategy();\n }\n }\n case 'fifo':\n return new FIFOEvictionStrategy();\n case 'mru':\n return new MRUEvictionStrategy();\n case 'random':\n return new RandomEvictionStrategy();\n case 'arc': {\n try {\n const arcConfig = config?.type === 'arc' ? config : { ...DEFAULT_ARC_CONFIG, maxCacheSize: safeMaxCacheSize };\n const finalMaxSize = (arcConfig.maxCacheSize && arcConfig.maxCacheSize > 0) ? arcConfig.maxCacheSize : safeMaxCacheSize;\n return new ARCEvictionStrategy(finalMaxSize, { ...arcConfig, maxCacheSize: finalMaxSize });\n } catch (error) {\n // If ARC strategy creation fails due to invalid config, fall back to LRU\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.warn(`Failed to create arc strategy with provided configuration, falling back to LRU:`, errorMessage);\n return new LRUEvictionStrategy();\n }\n }\n case '2q': {\n try {\n const twoQConfig = config?.type === '2q' ? config : { ...DEFAULT_TWO_QUEUE_CONFIG, maxCacheSize: safeMaxCacheSize };\n const finalMaxSize = (twoQConfig.maxCacheSize && twoQConfig.maxCacheSize > 0) ? twoQConfig.maxCacheSize : safeMaxCacheSize;\n return new TwoQueueEvictionStrategy(finalMaxSize, { ...twoQConfig, maxCacheSize: finalMaxSize });\n } catch (error) {\n // If 2Q strategy creation fails due to invalid config, fall back to LRU\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.warn(`Failed to create 2q strategy with provided configuration, falling back to LRU:`, errorMessage);\n return new LRUEvictionStrategy();\n }\n }\n default:\n throw new Error(`Unsupported eviction policy: ${policy}`);\n }\n}\n\n/**\n * Factory function for backwards compatibility\n * @deprecated Use createEvictionStrategy with config parameter instead\n */\nexport function createEvictionStrategyLegacy(policy: EvictionPolicy, maxCacheSize?: number): EvictionStrategy {\n return createEvictionStrategy(policy, maxCacheSize);\n}\n", "import { CacheItemMetadata, CacheMapMetadataProvider } from '../eviction/EvictionStrategy';\nimport LibLogger from '../logger';\n\nconst logger = LibLogger.get('TTLManager');\n\n/**\n * Configuration for TTL behavior\n */\nexport interface TTLConfig {\n /** Default TTL in milliseconds for all items */\n defaultTTL?: number;\n /** Whether to automatically clean up expired items */\n autoCleanup?: boolean;\n /** Interval for automatic cleanup in milliseconds */\n cleanupInterval?: number;\n /** Whether to validate TTL on access */\n validateOnAccess?: boolean;\n}\n\n/**\n * TTL-aware item wrapper that extends cache metadata\n */\nexport interface TTLItemMetadata extends CacheItemMetadata {\n /** Expiration timestamp (addedAt + TTL) */\n expiresAt?: number;\n /** TTL value used for this specific item */\n ttl?: number;\n}\n\n/**\n * Manages TTL (Time To Live) logic independently of CacheMap implementations.\n * This allows any CacheMap to support TTL without implementing TTL-specific logic.\n */\nexport class TTLManager {\n private config: TTLConfig;\n private cleanupTimer?: NodeJS.Timeout | null;\n\n constructor(config: TTLConfig = {}) {\n this.config = {\n autoCleanup: true,\n cleanupInterval: 60000, // 1 minute default\n validateOnAccess: true,\n ...config\n };\n\n if (this.config.autoCleanup && this.config.cleanupInterval) {\n this.startAutoCleanup();\n }\n }\n\n /**\n * Check if TTL is enabled\n */\n public isTTLEnabled(): boolean {\n return typeof this.config.defaultTTL === 'number' && this.config.defaultTTL > 0;\n }\n\n /**\n * Get the default TTL value\n */\n public getDefaultTTL(): number | undefined {\n return this.config.defaultTTL;\n }\n\n /**\n * Update TTL configuration\n */\n public updateConfig(config: Partial<TTLConfig>): void {\n const oldConfig = this.config;\n this.config = { ...this.config, ...config };\n\n // Restart auto cleanup if configuration changed\n if (oldConfig.autoCleanup !== this.config.autoCleanup ||\n oldConfig.cleanupInterval !== this.config.cleanupInterval) {\n this.stopAutoCleanup();\n if (this.config.autoCleanup && this.config.cleanupInterval) {\n this.startAutoCleanup();\n }\n }\n\n logger.debug('TTL configuration updated', { config: this.config });\n }\n\n /**\n * Set TTL metadata for an item when it's added\n */\n public onItemAdded(\n key: string,\n metadataProvider: CacheMapMetadataProvider,\n itemTTL?: number\n ): void {\n if (!this.isTTLEnabled() && !itemTTL) {\n return; // No TTL configured\n }\n\n const metadata = metadataProvider.getMetadata(key);\n if (!metadata) {\n logger.warning('No metadata found for item when setting TTL', { key });\n return;\n }\n\n const ttl = itemTTL || this.config.defaultTTL;\n if (ttl && ttl > 0) {\n const ttlMetadata: TTLItemMetadata = {\n ...metadata,\n expiresAt: metadata.addedAt + ttl,\n ttl\n };\n metadataProvider.setMetadata(key, ttlMetadata);\n\n logger.trace('TTL set for item', { key, ttl, expiresAt: ttlMetadata.expiresAt });\n }\n }\n\n /**\n * Check if an item has expired\n */\n public isExpired(key: string, metadataProvider: CacheMapMetadataProvider): boolean {\n const metadata = metadataProvider.getMetadata(key) as TTLItemMetadata;\n if (!metadata || !metadata.expiresAt) {\n return false; // No TTL set\n }\n\n const now = Date.now();\n const expired = now >= metadata.expiresAt;\n\n if (expired) {\n logger.trace('Item expired', { key, expiresAt: metadata.expiresAt, now });\n }\n\n return expired;\n }\n\n /**\n * Check if an item is valid (not expired) before returning it\n * Returns true if item is valid, false if expired\n */\n public validateItem(key: string, metadataProvider: CacheMapMetadataProvider): boolean {\n if (!this.config.validateOnAccess) {\n return true; // Skip validation if disabled\n }\n\n return !this.isExpired(key, metadataProvider);\n }\n\n /**\n * Get TTL information for an item\n */\n public getItemTTLInfo(key: string, metadataProvider: CacheMapMetadataProvider): {\n hasTTL: boolean;\n ttl?: number;\n expiresAt?: number;\n remainingTTL?: number;\n isExpired: boolean;\n } {\n const metadata = metadataProvider.getMetadata(key) as TTLItemMetadata;\n\n if (!metadata || !metadata.expiresAt) {\n return { hasTTL: false, isExpired: false };\n }\n\n const now = Date.now();\n const isExpired = now >= metadata.expiresAt;\n const remainingTTL = isExpired ? 0 : metadata.expiresAt - now;\n\n return {\n hasTTL: true,\n ttl: metadata.ttl,\n expiresAt: metadata.expiresAt,\n remainingTTL,\n isExpired\n };\n }\n\n /**\n * Find all expired items\n */\n public findExpiredItems(metadataProvider: CacheMapMetadataProvider): string[] {\n const expiredKeys: string[] = [];\n const allMetadata = metadataProvider.getAllMetadata();\n const now = Date.now();\n\n for (const [key, metadata] of allMetadata) {\n const ttlMetadata = metadata as TTLItemMetadata;\n if (ttlMetadata.expiresAt && now >= ttlMetadata.expiresAt) {\n expiredKeys.push(key);\n }\n }\n\n if (expiredKeys.length > 0) {\n logger.debug('Found expired items', { count: expiredKeys.length, keys: expiredKeys });\n }\n\n return expiredKeys;\n }\n\n /**\n * Manually clean up expired items\n * Returns the keys of items that were expired\n */\n public cleanupExpiredItems(metadataProvider: CacheMapMetadataProvider): string[] {\n return this.findExpiredItems(metadataProvider);\n }\n\n /**\n * Get remaining TTL for an item in milliseconds\n */\n public getRemainingTTL(key: string, metadataProvider: CacheMapMetadataProvider): number | null {\n const info = this.getItemTTLInfo(key, metadataProvider);\n return info.hasTTL ? (info.remainingTTL || 0) : null;\n }\n\n /**\n * Extend TTL for an item\n */\n public extendTTL(\n key: string,\n metadataProvider: CacheMapMetadataProvider,\n additionalTTL: number\n ): boolean {\n const metadata = metadataProvider.getMetadata(key) as TTLItemMetadata;\n if (!metadata || !metadata.expiresAt) {\n return false; // No TTL set\n }\n\n metadata.expiresAt += additionalTTL;\n metadataProvider.setMetadata(key, metadata);\n\n logger.trace('TTL extended for item', { key, additionalTTL, newExpiresAt: metadata.expiresAt });\n return true;\n }\n\n /**\n * Reset TTL for an item (refresh expiration)\n */\n public refreshTTL(\n key: string,\n metadataProvider: CacheMapMetadataProvider,\n newTTL?: number\n ): boolean {\n const metadata = metadataProvider.getMetadata(key) as TTLItemMetadata;\n if (!metadata) {\n return false;\n }\n\n const ttl = newTTL || metadata.ttl || this.config.defaultTTL;\n if (!ttl) {\n return false; // No TTL to set\n }\n\n const now = Date.now();\n const ttlMetadata: TTLItemMetadata = {\n ...metadata,\n expiresAt: now + ttl,\n ttl\n };\n metadataProvider.setMetadata(key, ttlMetadata);\n\n logger.trace('TTL refreshed for item', { key, ttl, expiresAt: ttlMetadata.expiresAt });\n return true;\n }\n\n /**\n * Start automatic cleanup of expired items\n */\n private startAutoCleanup(): void {\n if (this.cleanupTimer) {\n this.stopAutoCleanup();\n }\n\n if (this.config.cleanupInterval) {\n this.cleanupTimer = setInterval(() => {\n // Note: This will be implemented when we integrate with Cache class\n logger.trace('Auto cleanup timer triggered');\n }, this.config.cleanupInterval);\n\n logger.debug('Auto cleanup started', { interval: this.config.cleanupInterval });\n }\n }\n\n /**\n * Stop automatic cleanup\n */\n private stopAutoCleanup(): void {\n if (this.cleanupTimer) {\n clearInterval(this.cleanupTimer);\n this.cleanupTimer = null;\n logger.debug('Auto cleanup stopped');\n }\n }\n\n /**\n * Cleanup resources\n */\n public destroy(): void {\n this.stopAutoCleanup();\n logger.debug('TTL manager destroyed');\n }\n}\n", "import { ComKey, Item, ItemQuery, LocKey, LocKeyArray, PriKey } from \"@fjell/core\";\nimport {\n AnyCacheEvent,\n CacheEventListener,\n CacheSubscription,\n CacheSubscriptionOptions\n} from \"./CacheEventTypes\";\nimport { normalizeKeyValue } from \"../normalization\";\n\n/**\n * Internal subscription data\n */\ninterface InternalSubscription<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n> {\n id: string;\n listener: CacheEventListener<V, S, L1, L2, L3, L4, L5>;\n listenerRef?: WeakRef<CacheEventListener<V, S, L1, L2, L3, L4, L5>>;\n options: CacheSubscriptionOptions<S, L1, L2, L3, L4, L5>;\n isActive: boolean;\n debounceTimer?: NodeJS.Timeout | null;\n lastEmitTime?: number;\n createdAt: number;\n lastAccessTime: number;\n}\n\n/**\n * Cache event emitter that manages subscriptions and event dispatching\n */\nexport class CacheEventEmitter<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n> {\n private subscriptions = new Map<string, InternalSubscription<V, S, L1, L2, L3, L4, L5>>();\n private nextSubscriptionId = 1;\n private isDestroyed = false;\n private cleanupInterval: NodeJS.Timeout | null = null;\n private readonly CLEANUP_INTERVAL_MS = 30000; // 30 seconds\n private readonly MAX_INACTIVE_TIME_MS = 300000; // 5 minutes\n private readonly WEAK_REF_ENABLED = typeof WeakRef !== 'undefined';\n\n constructor() {\n this.startPeriodicCleanup();\n }\n\n /**\n * Start periodic cleanup of inactive subscriptions\n */\n private startPeriodicCleanup(): void {\n if (this.cleanupInterval) return;\n\n this.cleanupInterval = setInterval(() => {\n this.performPeriodicCleanup();\n }, this.CLEANUP_INTERVAL_MS);\n\n // Don't keep the process alive just for cleanup\n if (this.cleanupInterval.unref) {\n this.cleanupInterval.unref();\n }\n }\n\n /**\n * Perform periodic cleanup of inactive subscriptions\n */\n private performPeriodicCleanup(): void {\n if (this.isDestroyed) return;\n\n const now = Date.now();\n const toRemove: string[] = [];\n\n for (const [id, subscription] of this.subscriptions) {\n // Check if subscription is inactive for too long\n if (!subscription.isActive ||\n (now - subscription.lastAccessTime > this.MAX_INACTIVE_TIME_MS)) {\n toRemove.push(id);\n continue;\n }\n\n // Check if listener has been garbage collected (for weak references)\n if (this.WEAK_REF_ENABLED && subscription.listenerRef) {\n const listener = subscription.listenerRef.deref();\n if (!listener) {\n toRemove.push(id);\n continue;\n }\n }\n }\n\n // Remove inactive subscriptions\n toRemove.forEach(id => this.unsubscribe(id));\n }\n\n /**\n * Subscribe to cache events\n */\n public subscribe(\n listener: CacheEventListener<V, S, L1, L2, L3, L4, L5>,\n options: CacheSubscriptionOptions<S, L1, L2, L3, L4, L5> = {}\n ): CacheSubscription {\n if (this.isDestroyed) {\n throw new Error('Cannot subscribe to destroyed event emitter');\n }\n\n const id = `subscription_${this.nextSubscriptionId++}`;\n const now = Date.now();\n\n const subscription: InternalSubscription<V, S, L1, L2, L3, L4, L5> = {\n id,\n listener,\n listenerRef: this.WEAK_REF_ENABLED && options.useWeakRef !== false ?\n new WeakRef(listener) : undefined,\n options,\n isActive: true,\n createdAt: now,\n lastAccessTime: now\n };\n\n this.subscriptions.set(id, subscription);\n\n // Return public subscription interface\n return {\n id,\n unsubscribe: () => this.unsubscribe(id),\n isActive: () => {\n const sub = this.subscriptions.get(id);\n if (sub) {\n sub.lastAccessTime = Date.now();\n }\n return sub?.isActive ?? false;\n },\n getOptions: () => ({ ...options }) as CacheSubscriptionOptions<S, L1, L2, L3, L4, L5>\n };\n }\n\n /**\n * Unsubscribe from events\n */\n public unsubscribe(subscriptionId: string): boolean {\n const subscription = this.subscriptions.get(subscriptionId);\n if (!subscription) {\n return false;\n }\n\n // Clear any pending debounce timer\n if (subscription.debounceTimer) {\n clearTimeout(subscription.debounceTimer);\n subscription.debounceTimer = null;\n }\n\n subscription.isActive = false;\n this.subscriptions.delete(subscriptionId);\n\n return true;\n }\n\n /**\n * Emit an event to all matching subscriptions\n */\n public emit(event: AnyCacheEvent<V, S, L1, L2, L3, L4, L5>): void {\n if (this.isDestroyed) {\n return;\n }\n\n for (const subscription of this.subscriptions.values()) {\n if (!subscription.isActive) {\n continue;\n }\n\n if (this.shouldEmitToSubscription(event, subscription)) {\n this.emitToSubscription(event, subscription);\n }\n }\n }\n\n /**\n * Get count of active subscriptions\n */\n public getSubscriptionCount(): number {\n return Array.from(this.subscriptions.values()).filter(s => s.isActive).length;\n }\n\n /**\n * Get subscription details (for debugging)\n */\n public getSubscriptions(): Array<{ id: string; options: CacheSubscriptionOptions<S, L1, L2, L3, L4, L5> }> {\n return Array.from(this.subscriptions.values())\n .filter(s => s.isActive)\n .map(s => ({ id: s.id, options: { ...s.options } }));\n }\n\n /**\n * Destroy the event emitter and clean up all subscriptions\n */\n public destroy(): void {\n // Stop periodic cleanup\n if (this.cleanupInterval) {\n clearInterval(this.cleanupInterval);\n this.cleanupInterval = null;\n }\n\n // Clear all debounce timers\n for (const subscription of this.subscriptions.values()) {\n if (subscription.debounceTimer) {\n clearTimeout(subscription.debounceTimer);\n subscription.debounceTimer = null;\n }\n subscription.isActive = false;\n }\n\n this.subscriptions.clear();\n this.isDestroyed = true;\n }\n\n /**\n * Check if an event should be emitted to a specific subscription\n */\n private shouldEmitToSubscription(\n event: AnyCacheEvent<V, S, L1, L2, L3, L4, L5>,\n subscription: InternalSubscription<V, S, L1, L2, L3, L4, L5>\n ): boolean {\n const { options } = subscription;\n\n // Filter by event type\n if (options.eventTypes && !options.eventTypes.includes(event.type)) {\n return false;\n }\n\n // Filter by specific keys\n if (options.keys && options.keys.length > 0) {\n if ('key' in event) {\n const eventKeyStr = this.normalizeKey(event.key);\n const matchesKey = options.keys.some(key =>\n this.normalizeKey(key) === eventKeyStr\n );\n if (!matchesKey) {\n return false;\n }\n } else if ('affectedKeys' in event) {\n const eventKeyStrs = event.affectedKeys.map(key => this.normalizeKey(key));\n const hasMatchingKey = options.keys.some(key =>\n eventKeyStrs.includes(this.normalizeKey(key))\n );\n if (!hasMatchingKey) {\n return false;\n }\n } else {\n // Event doesn't have keys, skip if subscription is key-specific\n return false;\n }\n }\n\n // Filter by locations\n if (options.locations && options.locations.length > 0) {\n if ('affectedLocations' in event && event.affectedLocations) {\n if (!this.locationsMatch(options.locations, event.affectedLocations)) {\n return false;\n }\n } else if ('locations' in event) {\n if (!this.locationsMatch(options.locations, event.locations)) {\n return false;\n }\n } else if ('key' in event) {\n // Check if the item key matches the location filter\n if (!this.keyMatchesLocations(event.key, options.locations)) {\n return false;\n }\n } else {\n // Event doesn't have location info, skip if subscription is location-specific\n return false;\n }\n }\n\n // Filter by query (this is more complex and approximate)\n if (options.query) {\n if ('query' in event) {\n if (!this.queriesMatch(options.query, event.query)) {\n return false;\n }\n } else {\n // For non-query events, we can't easily determine if they match a query filter\n // This could be enhanced with more sophisticated query matching\n return true;\n }\n }\n\n return true;\n }\n\n /**\n * Emit event to a specific subscription, handling debouncing\n */\n private emitToSubscription(\n event: AnyCacheEvent<V, S, L1, L2, L3, L4, L5>,\n subscription: InternalSubscription<V, S, L1, L2, L3, L4, L5>\n ): void {\n // Update last access time for cleanup purposes\n subscription.lastAccessTime = Date.now();\n\n // Get the listener, either directly or from weak reference\n let listener = subscription.listener;\n if (this.WEAK_REF_ENABLED && subscription.listenerRef) {\n const weakListener = subscription.listenerRef.deref();\n if (!weakListener) {\n // Listener has been garbage collected, mark as inactive\n subscription.isActive = false;\n return;\n }\n listener = weakListener;\n }\n\n if (!subscription.options.debounceMs) {\n // No debouncing, emit immediately\n try {\n listener(event);\n } catch (error) {\n this.handleListenerError(error, event, subscription);\n }\n return;\n }\n\n // Clear existing debounce timer\n if (subscription.debounceTimer) {\n clearTimeout(subscription.debounceTimer);\n subscription.debounceTimer = null;\n }\n\n // Set new debounce timer\n subscription.debounceTimer = setTimeout(() => {\n if (subscription.isActive) {\n // Re-check listener availability for weak references\n let currentListener = subscription.listener;\n if (this.WEAK_REF_ENABLED && subscription.listenerRef) {\n const weakListener = subscription.listenerRef.deref();\n if (!weakListener) {\n subscription.isActive = false;\n subscription.debounceTimer = null;\n return;\n }\n currentListener = weakListener;\n }\n\n try {\n currentListener(event);\n subscription.lastEmitTime = Date.now();\n } catch (error) {\n this.handleListenerError(error, event, subscription);\n }\n }\n // Clear the timer reference to allow garbage collection\n subscription.debounceTimer = null;\n }, subscription.options.debounceMs);\n }\n\n /**\n * Normalize a key for comparison\n */\n private normalizeKey(key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>): string {\n return JSON.stringify(key, (k, v) => {\n if (typeof v === 'string' || typeof v === 'number') {\n return normalizeKeyValue(v);\n }\n return v;\n });\n }\n\n /**\n * Normalize a location key for comparison\n */\n private normalizeLocKey(key: LocKey<L1 | L2 | L3 | L4 | L5>): string {\n return JSON.stringify(key, (k, v) => {\n if (typeof v === 'string' || typeof v === 'number') {\n return normalizeKeyValue(v);\n }\n return v;\n });\n }\n\n /**\n * Check if two location arrays match\n */\n private locationsMatch(\n filter: LocKeyArray<L1, L2, L3, L4, L5> | [],\n eventLocations: LocKeyArray<L1, L2, L3, L4, L5> | []\n ): boolean {\n if (filter.length === 0 && eventLocations.length === 0) {\n return true;\n }\n\n if (filter.length !== eventLocations.length) {\n return false;\n }\n\n return filter.every((filterLoc, index) => {\n const eventLoc = eventLocations[index];\n // LocKey has different structure from ComKey/PriKey, so we need to normalize using their own properties\n return this.normalizeKey(filterLoc as any) === this.normalizeKey(eventLoc as any);\n });\n }\n\n /**\n * Check if a key matches location filters\n */\n private keyMatchesLocations(\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n filterLocations: LocKeyArray<L1, L2, L3, L4, L5> | []\n ): boolean {\n // If key is a ComKey, check if its locations match the filter\n if ('loc' in key && key.loc) {\n return this.locationsMatch(filterLocations, key.loc);\n }\n\n // PriKey doesn't have locations, so only matches if filter is empty\n return filterLocations.length === 0;\n }\n\n /**\n * Check if two queries match (improved comparison)\n */\n private queriesMatch(filterQuery: ItemQuery, eventQuery: ItemQuery): boolean {\n // Normalize queries for consistent comparison\n const normalize = (obj: any): any => {\n if (obj === null || typeof obj === 'undefined') return obj;\n if (typeof obj !== 'object') return obj;\n if (Array.isArray(obj)) return obj.map(normalize).sort();\n\n const sorted: any = {};\n Object.keys(obj).sort().forEach(key => {\n sorted[key] = normalize(obj[key]);\n });\n return sorted;\n };\n\n return JSON.stringify(normalize(filterQuery)) === JSON.stringify(normalize(eventQuery));\n }\n\n /**\n * Handle errors that occur in event listeners\n */\n private handleListenerError(\n error: unknown,\n event: AnyCacheEvent<V, S, L1, L2, L3, L4, L5>,\n subscription: InternalSubscription<V, S, L1, L2, L3, L4, L5>\n ): void {\n const errorObj = error instanceof Error ? error : new Error(String(error));\n\n if (subscription.options.onError) {\n try {\n subscription.options.onError(errorObj, event);\n } catch (handlerError) {\n // If the error handler itself throws, log both errors\n console.error('Error in cache event listener:', errorObj);\n console.error('Error in error handler:', handlerError);\n }\n } else {\n console.error('Error in cache event listener:', errorObj);\n }\n }\n}\n", "/**\n * Cache statistics tracking interface\n */\nexport interface CacheStats {\n /** Total number of cache requests (get/retrieve operations) */\n numRequests: number;\n /** Total number of cache misses (items not found in cache) */\n numMisses: number;\n /** Total number of cache hits (items found in cache) */\n numHits: number;\n /** Total number of subscription requests */\n numSubscriptions: number;\n /** Total number of unsubscription requests */\n numUnsubscriptions: number;\n /** Current number of active subscriptions */\n activeSubscriptions: number;\n}\n\n/**\n * Cache statistics manager that tracks various cache metrics\n */\nexport class CacheStatsManager {\n private stats: CacheStats = {\n numRequests: 0,\n numMisses: 0,\n numHits: 0,\n numSubscriptions: 0,\n numUnsubscriptions: 0,\n activeSubscriptions: 0\n };\n\n /**\n * Increment the request counter\n */\n incrementRequests(): void {\n this.stats.numRequests++;\n }\n\n /**\n * Increment the cache hit counter\n */\n incrementHits(): void {\n this.stats.numHits++;\n }\n\n /**\n * Increment the cache miss counter\n */\n incrementMisses(): void {\n this.stats.numMisses++;\n }\n\n /**\n * Increment the subscription counter\n */\n incrementSubscriptions(): void {\n this.stats.numSubscriptions++;\n this.stats.activeSubscriptions++;\n }\n\n /**\n * Increment the unsubscription counter\n */\n incrementUnsubscriptions(): void {\n this.stats.numUnsubscriptions++;\n if (this.stats.activeSubscriptions > 0) {\n this.stats.activeSubscriptions--;\n }\n }\n\n /**\n * Get a copy of the current statistics\n */\n getStats(): CacheStats {\n return { ...this.stats };\n }\n\n /**\n * Reset all statistics to zero\n */\n reset(): void {\n this.stats = {\n numRequests: 0,\n numMisses: 0,\n numHits: 0,\n numSubscriptions: 0,\n numUnsubscriptions: 0,\n activeSubscriptions: 0\n };\n }\n}\n", "import { Item } from \"@fjell/core\";\nimport { Instance as BaseInstance, Coordinate, Registry } from \"@fjell/registry\";\nimport { ClientApi } from \"@fjell/client-api\";\nimport { CacheMap } from \"./CacheMap\";\nimport { createOperations, Operations } from \"./Operations\";\nimport { createCacheMap, createOptions, Options } from \"./Options\";\nimport { EvictionManager } from \"./eviction/EvictionManager\";\nimport { createEvictionStrategy } from \"./eviction/EvictionStrategyFactory\";\nimport { TTLManager } from \"./ttl/TTLManager\";\nimport LibLogger from \"./logger\";\nimport { CacheEventEmitter } from \"./events/CacheEventEmitter\";\nimport { CacheEventListener, CacheSubscription, CacheSubscriptionOptions } from \"./events/CacheEventTypes\";\nimport { CacheEventFactory } from \"./events/CacheEventFactory\";\nimport { CacheStats, CacheStatsManager } from \"./CacheStats\";\n\nconst logger = LibLogger.get('Cache');\n\n/**\n * Cache configuration information exposed to client applications\n */\nexport interface CacheInfo {\n /** The implementation type in format \"<category>/<implementation>\" */\n implementationType: string;\n /** The eviction policy being used (if any) */\n evictionPolicy?: string;\n /** Default TTL in milliseconds (if configured) */\n defaultTTL?: number;\n /** Whether TTL is supported by this implementation */\n supportsTTL: boolean;\n /** Whether eviction is supported by this implementation */\n supportsEviction: boolean;\n}\n\n/**\n * The Cache interface extends the base Instance from @fjell/registry and adds cache operations\n * for interacting with cached data.\n *\n * The interface extends the base Instance (which provides coordinate and registry) with:\n * - api: Provides methods for interacting with server API\n * - cacheMap: Local cache storage for items\n * - operations: All cache operations (get, set, all, etc.) that work with both cache and API\n *\n * @template V - The type of the data model item, extending Item\n * @template S - The string literal type representing the model's key type\n * @template L1-L5 - Optional string literal types for location hierarchy levels\n */\nexport interface Cache<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n> extends BaseInstance<S, L1, L2, L3, L4, L5> {\n /** The API client for interacting with server endpoints */\n api: ClientApi<V, S, L1, L2, L3, L4, L5>;\n\n /** The cache map that stores cached items */\n cacheMap: CacheMap<V, S, L1, L2, L3, L4, L5>;\n\n /** All cache operations that work with both cache and API */\n operations: Operations<V, S, L1, L2, L3, L4, L5>;\n\n /** Cache configuration options */\n options?: Options<V, S, L1, L2, L3, L4, L5>;\n\n /** Event emitter for cache events */\n eventEmitter: CacheEventEmitter<V, S, L1, L2, L3, L4, L5>;\n\n /** Eviction manager for handling cache eviction independently of storage */\n evictionManager: EvictionManager;\n\n /** TTL manager for handling time-to-live independently of storage */\n ttlManager: TTLManager;\n\n /** Statistics manager for tracking cache metrics */\n statsManager: CacheStatsManager;\n\n /**\n * Get cache configuration information for client applications\n * Provides visibility into implementation type, eviction policy, TTL settings, and capabilities\n */\n getCacheInfo(): CacheInfo;\n\n /**\n * Get current cache statistics\n * @returns Current cache statistics including hits, misses, requests, and subscription counts\n */\n getStats(): CacheStats;\n\n /**\n * Subscribe to cache events\n * @param listener Function to call when events occur\n * @param options Optional filters for which events to receive\n * @returns Subscription object with unsubscribe method\n */\n subscribe(\n listener: CacheEventListener<V, S, L1, L2, L3, L4, L5>,\n options?: CacheSubscriptionOptions<S, L1, L2, L3, L4, L5>\n ): CacheSubscription;\n\n /**\n * Unsubscribe from cache events\n * @param subscription Subscription to cancel\n * @returns True if subscription was found and cancelled\n */\n unsubscribe(subscription: CacheSubscription): boolean;\n\n /**\n * Destroy the cache and clean up all resources\n */\n destroy(): void;\n}\n\nexport const createCache = <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n api: ClientApi<V, S, L1, L2, L3, L4, L5>,\n coordinate: Coordinate<S, L1, L2, L3, L4, L5>,\n registry: Registry,\n options?: Partial<Options<V, S, L1, L2, L3, L4, L5>>\n ): Cache<V, S, L1, L2, L3, L4, L5> => {\n logger.debug('createCache', { coordinate, registry, options });\n\n // Create complete options with defaults\n const completeOptions = createOptions(options);\n\n // Create the cache map using the options\n const cacheMap = createCacheMap<V, S, L1, L2, L3, L4, L5>(coordinate.kta, completeOptions);\n\n // Get the primary key type from the coordinate\n const pkType = coordinate.kta[0] as S;\n\n // Create event emitter\n const eventEmitter = new CacheEventEmitter<V, S, L1, L2, L3, L4, L5>();\n\n // Create eviction manager\n const evictionManager = new EvictionManager();\n\n // Determine eviction configuration - prioritize top-level evictionConfig\n const evictionConfig = completeOptions.evictionConfig;\n if (!evictionConfig &&\n completeOptions.memoryConfig?.size?.evictionPolicy &&\n (completeOptions.memoryConfig.size.maxItems || completeOptions.memoryConfig.size.maxSizeBytes)) {\n }\n\n if (evictionConfig) {\n // Set eviction strategy from unified config\n const strategy = createEvictionStrategy(\n evictionConfig.type || 'lru',\n completeOptions.memoryConfig?.maxItems,\n evictionConfig\n );\n evictionManager.setEvictionStrategy(strategy);\n }\n\n // Create TTL manager with proper configuration priority: memoryConfig.ttl || ttl\n const ttlManager = new TTLManager({\n defaultTTL: completeOptions.ttl,\n autoCleanup: true,\n validateOnAccess: true\n });\n\n // Create statistics manager\n const statsManager = new CacheStatsManager();\n\n // Note: EvictionManager operates independently of CacheMap implementations\n // and is passed through CacheContext to operations for external eviction management\n\n // Create operations with event emitter, eviction manager, and stats manager\n const operations = createOperations(api, coordinate, cacheMap, pkType, completeOptions, eventEmitter, ttlManager, evictionManager, statsManager);\n\n const cache: Cache<V, S, L1, L2, L3, L4, L5> = {\n coordinate,\n registry,\n api,\n cacheMap,\n operations,\n options: completeOptions,\n eventEmitter,\n evictionManager,\n ttlManager,\n statsManager,\n getCacheInfo: () => {\n const evictionStrategyName = evictionManager.getEvictionStrategyName();\n const cacheInfo: CacheInfo = {\n implementationType: cacheMap.implementationType,\n defaultTTL: ttlManager.getDefaultTTL(),\n // Cache supports TTL if the CacheMap supports it OR if TTL is configured\n supportsTTL: (cacheMap as any).supportsTTL?.() || !!ttlManager.getDefaultTTL(),\n supportsEviction: evictionManager.isEvictionSupported()\n };\n\n if (evictionStrategyName) {\n cacheInfo.evictionPolicy = evictionStrategyName;\n }\n\n return cacheInfo;\n },\n getStats: () => statsManager.getStats(),\n subscribe: (listener, options) => {\n statsManager.incrementSubscriptions();\n return eventEmitter.subscribe(listener, options);\n },\n unsubscribe: (subscription) => {\n const result = eventEmitter.unsubscribe(subscription.id);\n if (result) {\n statsManager.incrementUnsubscriptions();\n }\n return result;\n },\n destroy: () => {\n // Clean up event emitter\n eventEmitter.destroy();\n\n // Clean up TTL manager\n if (ttlManager && typeof ttlManager.destroy === 'function') {\n ttlManager.destroy();\n }\n\n // Clean up eviction manager (EvictionManager doesn't need explicit cleanup)\n // evictionManager is stateless and doesn't require destruction\n\n // Clean up cache map if it has a destroy method\n if (cacheMap && typeof (cacheMap as any).destroy === 'function') {\n (cacheMap as any).destroy();\n }\n\n // Notify CacheEventFactory that an instance is being destroyed\n CacheEventFactory.destroyInstance();\n }\n };\n\n return cache;\n};\n\nexport const isCache = (cache: any): cache is Cache<any, any, any, any, any, any, any> => {\n return cache !== null &&\n typeof cache === 'object' &&\n 'coordinate' in cache &&\n 'registry' in cache &&\n 'api' in cache &&\n 'cacheMap' in cache &&\n 'operations' in cache;\n};\n", "import { Item } from \"@fjell/core\";\nimport { ClientApi } from \"@fjell/client-api\";\nimport { InstanceFactory as BaseInstanceFactory, Registry, RegistryHub } from \"@fjell/registry\";\nimport { Instance } from \"./Instance\";\nimport { Coordinate } from \"@fjell/registry\";\nimport { createOperations } from \"./Operations\";\nimport { createCacheMap, createOptions, Options, validateOptions } from \"./Options\";\nimport { TTLManager } from \"./ttl/TTLManager\";\nimport { EvictionManager } from \"./eviction/EvictionManager\";\nimport { CacheEventEmitter } from \"./events/CacheEventEmitter\";\nimport LibLogger from \"./logger\";\nimport { CacheStatsManager } from \"./CacheStats\";\n\nconst logger = LibLogger.get(\"InstanceFactory\");\n\nexport type InstanceFactory<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n> = (\n api: ClientApi<V, S, L1, L2, L3, L4, L5>,\n options?: Partial<Options<V, S, L1, L2, L3, L4, L5>>\n) => BaseInstanceFactory<S, L1, L2, L3, L4, L5>;\n\n/**\n * Factory function for creating cache instances\n */\nexport const createInstanceFactory = <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n api: ClientApi<V, S, L1, L2, L3, L4, L5>,\n options?: Partial<Options<V, S, L1, L2, L3, L4, L5>>\n ): BaseInstanceFactory<S, L1, L2, L3, L4, L5> => {\n\n // Create and validate a template of options - this validates the provided options\n const templateOptions = createOptions(options);\n validateOptions(templateOptions);\n\n return (coordinate: Coordinate<S, L1, L2, L3, L4, L5>, context: { registry: Registry, registryHub?: RegistryHub }) => {\n // Create fresh options for each instance to ensure immutability\n const instanceOptions = createOptions(options);\n\n logger.debug(\"Creating cache instance\", {\n coordinate,\n registry: context.registry,\n api,\n cacheType: instanceOptions.cacheType,\n options: instanceOptions\n });\n\n // Create the appropriate cache map based on options\n const cacheMap = createCacheMap<V, S, L1, L2, L3, L4, L5>(coordinate.kta, instanceOptions);\n const pkType = coordinate.kta[0] as S;\n\n // Create proper managers instead of mocks\n const eventEmitter = new CacheEventEmitter<V, S, L1, L2, L3, L4, L5>();\n const ttlManager = new TTLManager({\n defaultTTL: instanceOptions.ttl,\n autoCleanup: true,\n validateOnAccess: true\n });\n const evictionManager = new EvictionManager();\n const statsManager = new CacheStatsManager();\n const operations = createOperations(\n api, coordinate, cacheMap, pkType, instanceOptions, eventEmitter, ttlManager, evictionManager, statsManager);\n\n return {\n coordinate,\n registry: context.registry,\n api,\n cacheMap,\n operations,\n options: instanceOptions,\n eventEmitter,\n ttlManager,\n evictionManager,\n getCacheInfo: () => {\n const evictionStrategyName = evictionManager.getEvictionStrategyName();\n const cacheInfo = {\n implementationType: cacheMap.implementationType,\n defaultTTL: ttlManager.getDefaultTTL(),\n supportsTTL: (cacheMap as any).supportsTTL?.() || !!ttlManager.getDefaultTTL(),\n supportsEviction: evictionManager.isEvictionSupported()\n };\n if (evictionStrategyName) {\n (cacheInfo as any).evictionPolicy = evictionStrategyName;\n }\n return cacheInfo;\n },\n subscribe: (listener, options) => eventEmitter.subscribe(listener, options),\n unsubscribe: (subscription) => eventEmitter.unsubscribe(subscription.id),\n destroy: () => {\n if (typeof ttlManager.destroy === 'function') {\n ttlManager.destroy();\n }\n eventEmitter.destroy();\n }\n } as Instance<V, S, L1, L2, L3, L4, L5>;\n };\n};\n", "\nimport LibLogger from \"./logger\";\nimport { Item } from \"@fjell/core\";\nimport { Coordinate, Registry } from \"@fjell/registry\";\nimport { ClientApi } from \"@fjell/client-api\";\nimport { Cache, createCache } from \"./Cache\";\n\nconst logger = LibLogger.get(\"Instance\");\n\n/**\n * The Cache Instance interface represents a cache model instance that extends the base Instance\n * from @fjell/registry and adds cache operations for interacting with cached data.\n *\n * This is a type alias for the Cache interface. Both Cache and Instance refer to the same\n * cache interface - Instance exists for backward compatibility and consistency with other\n * Fjell packages that export Instance types.\n *\n * @template V - The type of the data model item, extending Item\n * @template S - The string literal type representing the model's key type\n * @template L1-L5 - Optional string literal types for location hierarchy levels\n */\nexport type Instance<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n> = Cache<V, S, L1, L2, L3, L4, L5>;\n\nexport const createInstance = <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n registry: Registry,\n coordinate: Coordinate<S, L1, L2, L3, L4, L5>,\n api: ClientApi<V, S, L1, L2, L3, L4, L5>,\n options?: Partial<import('./Options').Options<V, S, L1, L2, L3, L4, L5>>\n ): Instance<V, S, L1, L2, L3, L4, L5> => {\n logger.debug(\"createInstance\", { coordinate, api, registry, options });\n return createCache(api, coordinate, registry, options);\n}\n\nexport const isInstance = (instance: any): instance is Instance<any, any, any, any, any, any, any> => {\n return instance !== null &&\n typeof instance === 'object' &&\n 'coordinate' in instance &&\n 'registry' in instance &&\n 'api' in instance &&\n 'cacheMap' in instance &&\n 'operations' in instance;\n}\n", "\nimport {\n ComKey,\n Item,\n ItemQuery,\n LocKeyArray,\n PriKey\n} from \"@fjell/core\";\nimport { Cache } from \"./Cache\";\nimport { CacheMap } from \"./CacheMap\";\nimport { CacheEventEmitter } from \"./events/CacheEventEmitter\";\nimport { CacheEventListener, CacheSubscription, CacheSubscriptionOptions } from \"./events/CacheEventTypes\";\nimport LibLogger from \"./logger\";\n\nconst logger = LibLogger.get('ItemAggregator');\n\nexport interface Aggregator<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n> extends Cache<V, S, L1, L2, L3, L4, L5> {\n // Cache operations exposed directly for aggregator\n all: (\n query?: ItemQuery,\n locations?: LocKeyArray<L1, L2, L3, L4, L5> | []\n ) => Promise<V[]>;\n\n one: (\n query?: ItemQuery,\n locations?: LocKeyArray<L1, L2, L3, L4, L5> | []\n ) => Promise<V | null>;\n\n action: (\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n action: string,\n body?: any\n ) => Promise<V>;\n\n allAction: (\n action: string,\n body?: any,\n locations?: LocKeyArray<L1, L2, L3, L4, L5> | []\n ) => Promise<V[]>;\n\n allFacet: (\n facet: string,\n params?: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n locations?: LocKeyArray<L1, L2, L3, L4, L5> | []\n ) => Promise<any>;\n\n create: (\n item: Partial<Item<S, L1, L2, L3, L4, L5>>,\n locations?: LocKeyArray<L1, L2, L3, L4, L5> | []\n ) => Promise<V>;\n\n get: (\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>\n ) => Promise<V | null>;\n\n retrieve: (\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>\n ) => Promise<V | null>;\n\n remove: (\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>\n ) => Promise<void>;\n\n update: (\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n item: Partial<Item<S, L1, L2, L3, L4, L5>>\n ) => Promise<V>;\n\n facet: (\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n facet: string,\n params?: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>\n ) => Promise<any>;\n\n find: (\n finder: string,\n params?: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n locations?: LocKeyArray<L1, L2, L3, L4, L5> | []\n ) => Promise<V[]>;\n\n findOne: (\n finder: string,\n params?: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n locations?: LocKeyArray<L1, L2, L3, L4, L5> | []\n ) => Promise<V>;\n\n set: (\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n item: Item<S, L1, L2, L3, L4, L5>\n ) => Promise<V>;\n\n reset: () => Promise<void>;\n\n populate: (item: V) => Promise<V>;\n populateAggregate: (key: string, item: V) => Promise<void>;\n populateEvent: (key: string, item: V) => Promise<void>;\n\n /** Event emitter for cache events */\n eventEmitter: CacheEventEmitter<V, S, L1, L2, L3, L4, L5>;\n\n /**\n * Subscribe to cache events\n */\n subscribe(\n listener: CacheEventListener<V, S, L1, L2, L3, L4, L5>,\n options?: CacheSubscriptionOptions<S, L1, L2, L3, L4, L5>\n ): CacheSubscription;\n\n /**\n * Unsubscribe from cache events\n */\n unsubscribe(subscription: CacheSubscription): boolean;\n}\n\nexport interface CacheConfig { cache: any, optional: boolean }\n\nexport interface AggregateConfig { [key: string]: (CacheConfig) }\n\nexport const toCacheConfig = <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(config: CacheConfig | Cache<V, S, L1, L2, L3, L4, L5>): CacheConfig => {\n let cacheConfig: CacheConfig;\n if ((config as CacheConfig).optional === undefined) {\n cacheConfig = { cache: config as any, optional: false };\n } else {\n cacheConfig = config as CacheConfig;\n }\n return cacheConfig;\n}\n\nexport const createAggregator = async <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n cache: Cache<V, S, L1, L2, L3, L4, L5>,\n { aggregates = {}, events = {} }:\n {\n aggregates?: AggregateConfig,\n events?: AggregateConfig\n }\n): Promise<Aggregator<V, S, L1, L2, L3, L4, L5>> => {\n\n const populate = async (item: V): Promise<V> => {\n logger.default('populate', { item });\n for (const key in aggregates) {\n await populateAggregate(key, item);\n }\n for (const key in events) {\n await populateEvent(key, item);\n }\n logger.default('populate done', { item });\n return item;\n }\n\n const populateAggregate = async (key: string, item: V) => {\n logger.default('populate aggregate key', { key });\n const cacheConfig = toCacheConfig(aggregates[key]);\n if (item.refs === undefined) {\n if (cacheConfig.optional === false) {\n logger.error('Item does not have refs an is not optional ', { item });\n throw new Error('Item does not have refs an is not optional ' + JSON.stringify(item));\n } else {\n if (item.events && Object.prototype.hasOwnProperty.call(item.events, key)) {\n delete item.events[key];\n }\n }\n } else if (item.refs[key] === undefined) {\n if (cacheConfig.optional === false) {\n logger.error('Item does not have mandatory ref with key, not optional ', { key, item });\n throw new Error('Item does not have mandatory ref with key, not optional ' +\n key + ' ' + JSON.stringify(item));\n } else {\n if (item.events && Object.prototype.hasOwnProperty.call(item.events, key)) {\n delete item.events[key];\n }\n }\n } else {\n\n const ref = item.refs[key];\n\n logger.default('AGG Retrieving Item in Populate', { key: ref });\n const newItem = await cacheConfig.cache.operations.retrieve(ref);\n if (newItem) {\n if (item.aggs === undefined) {\n item.aggs = {};\n }\n item.aggs[key] = {\n key: ref,\n item: newItem as Item,\n };\n }\n }\n }\n\n // TODO: I'm not a big fan that this just \"automatically\" assumes that the \"by\" key in event is a ref.\n const populateEvent = async (key: string, item: V) => {\n logger.default('populate event key', { key });\n const cacheConfig = toCacheConfig(events[key]);\n\n if (item.events === undefined) {\n throw new Error('Item does not have events ' + JSON.stringify(item));\n } else if (item.events[key] === undefined) {\n if (cacheConfig.optional === false) {\n logger.error('Item does not have mandatory event with key', { key, item });\n throw new Error('Item does not have mandatory event with key ' + key + ' ' + JSON.stringify(item));\n }\n } else {\n const event = item.events[key];\n\n if (event.by === undefined) {\n logger.error(\n 'populateEvent with an Event that does not have by', { event, ik: item.key, eventKey: key });\n throw new Error('populateEvent with an Event that does not have by: ' + JSON.stringify({ key }));\n }\n\n logger.default('EVENT Retrieving Item in Populate', { key: event.by });\n const newItem = await cacheConfig.cache.operations.retrieve(event.by);\n if (newItem) {\n event.agg = newItem as Item;\n }\n }\n }\n\n const all = async (\n query: ItemQuery = {},\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = []\n ):\n Promise<V[]> => {\n logger.default('all', { query, locations });\n const items = await cache.operations.all(query, locations);\n const populatedItems = await Promise.all(items.map(async (item) => populate(item)));\n return populatedItems;\n }\n\n const one = async (\n query: ItemQuery = {},\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = []\n ):\n Promise<V | null> => {\n logger.default('one', { query, locations });\n const item = await cache.operations.one(query, locations);\n let populatedItem = null;\n if (item) {\n populatedItem = await populate(item);\n }\n return populatedItem;\n }\n\n const action = async (\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n action: string,\n body: any = {},\n ): Promise<V> => {\n logger.default('action', { key, action, body });\n const item = await cache.operations.action(key, action, body);\n const populatedItem = await populate(item);\n return populatedItem;\n }\n\n const allAction = async (\n action: string,\n body: any = {},\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = []\n ): Promise<V[]> => {\n logger.default('action', { action, body, locations });\n const items = await cache.operations.allAction(action, body, locations);\n const populatedItems = await Promise.all(items.map(async (item: V) => populate(item)));\n return populatedItems;\n }\n\n const allFacet = async (\n facet: string,\n params: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>> = {},\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = []\n ): Promise<any> => {\n logger.default('allFacet', { facet, params, locations });\n const response = await cache.operations.allFacet(facet, params, locations);\n return response;\n }\n\n const create = async (\n v: Partial<Item<S, L1, L2, L3, L4, L5>>,\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = []\n ): Promise<V> => {\n logger.default('create', { v, locations });\n const item = await cache.operations.create(v, locations);\n const populatedItem = await populate(item);\n return populatedItem;\n }\n\n const get = async (\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n ): Promise<V | null> => {\n logger.default('get', { key });\n const item = await cache.operations.get(key);\n let populatedItem = null;\n if (item) {\n populatedItem = await populate(item);\n }\n return populatedItem;\n }\n\n const retrieve = async (\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n ): Promise<V | null> => {\n logger.default('retrieve', { key });\n const item = await cache.operations.retrieve(key);\n let populatedItem = null;\n if (item) {\n populatedItem = await populate(item);\n }\n return populatedItem;\n }\n\n const remove = async (\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n ): Promise<void> => {\n logger.default('remove', { key });\n await cache.operations.remove(key);\n }\n\n const update = async (\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n v: Partial<Item<S, L1, L2, L3, L4, L5>>,\n ): Promise<V> => {\n logger.default('update', { key, v });\n const item = await cache.operations.update(key, v);\n const populatedItem = await populate(item);\n return populatedItem;\n }\n\n // Facets are a pass-thru for aggregators\n const facet = async (\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n facet: string,\n ): Promise<any> => {\n logger.default('facet', { key, facet });\n const response = await cache.operations.facet(key, facet);\n return response;\n }\n\n const find = async (\n finder: string,\n finderParams: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>> = {},\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = []\n ): Promise<V[]> => {\n logger.default('find', { finder, finderParams, locations });\n const items = await cache.operations.find(finder, finderParams, locations);\n const populatedItems = await Promise.all(items.map(async (item: V) => populate(item)));\n return populatedItems;\n }\n\n const findOne = async (\n finder: string,\n finderParams: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>> = {},\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [] = []\n ): Promise<V> => {\n logger.default('find', { finder, finderParams, locations });\n const item = await cache.operations.findOne(finder, finderParams, locations);\n const populatedItem = await populate(item);\n return populatedItem;\n }\n\n const set = async (\n key: ComKey<S, L1, L2, L3, L4, L5> | PriKey<S>,\n v: Item<S, L1, L2, L3, L4, L5>\n ): Promise<V> => {\n logger.default('set', { key, v });\n\n // TODO: There should be some input validation here to ensure a valid item.\n const item = await cache.operations.set(key, v);\n const populatedItem = await populate(item);\n return populatedItem;\n }\n\n const reset = async (): Promise<void> => {\n await cache.operations.reset();\n }\n\n return {\n // Cache properties\n coordinate: cache.coordinate,\n registry: cache.registry,\n api: cache.api,\n cacheMap: cache.cacheMap,\n operations: cache.operations,\n evictionManager: cache.evictionManager,\n ttlManager: cache.ttlManager,\n statsManager: cache.statsManager,\n getStats: cache.getStats.bind(cache),\n getCacheInfo: cache.getCacheInfo.bind(cache),\n // Cache operations exposed directly\n all,\n one,\n action,\n allAction,\n allFacet,\n create,\n get,\n retrieve,\n remove,\n update,\n facet,\n find,\n findOne,\n reset,\n set,\n // Aggregator-specific operations\n populate,\n populateAggregate,\n populateEvent,\n // Event system\n eventEmitter: cache.eventEmitter,\n subscribe: (listener, options) => cache.subscribe(listener, options),\n unsubscribe: (subscription) => cache.unsubscribe(subscription),\n destroy: () => cache.destroy()\n }\n}\n", "import LibLogger from './logger';\nimport {\n Registry as BaseRegistry,\n createRegistry as createBaseRegistry,\n RegistryFactory,\n RegistryHub\n} from '@fjell/registry';\n\nconst logger = LibLogger.get(\"Registry\");\n\n/**\n * Extended Registry interface for cache-specific functionality\n */\nexport interface Registry extends BaseRegistry {\n type: 'cache';\n}\n\n/**\n * Factory function for creating cache registries\n */\nexport const createRegistryFactory = (): RegistryFactory => {\n return (type: string, registryHub?: RegistryHub): BaseRegistry => {\n if (type !== 'cache') {\n throw new Error(`Cache registry factory can only create 'cache' type registries, got: ${type}`);\n }\n\n logger.debug(\"Creating cache registry\", { type, registryHub });\n\n const baseRegistry = createBaseRegistry(type, registryHub);\n\n // Cast to Registry for type safety\n return baseRegistry as Registry;\n };\n};\n\n/**\n * Creates a new cache registry instance\n */\nexport const createRegistry = (registryHub?: RegistryHub): Registry => {\n const baseRegistry = createBaseRegistry('cache', registryHub);\n\n return {\n ...baseRegistry,\n } as Registry;\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["validatePK", "NotFoundError", "logger", "validatePK", "NotFoundError", "validatePK", "logger", "validatePK", "validatePK", "logger", "logger", "keyStr", "validatePK", "isValidItemKey", "validatePK", "logger", "isValidItemKey", "validatePK", "isValidItemKey", "logger", "isValidItemKey", "isValidItemKey", "validatePK", "logger", "isValidItemKey", "validatePK", "isValidItemKey", "validatePK", "logger", "action", "isValidItemKey", "validatePK", "validatePK", "NotFoundError", "logger", "action", "NotFoundError", "validatePK", "logger", "facet", "logger", "facet", "validatePK", "logger", "validatePK", "validatePK", "logger", "validatePK", "isValidItemKey", "validatePK", "logger", "normalizeKeyValue", "isValidItemKey", "validatePK", "logger", "isComKey", "isQueryMatch", "logger", "isComKey", "isQueryMatch", "isComKey", "isQueryMatch", "logger", "isComKey", "ComKey", "isQueryMatch", "isComKey", "isQueryMatch", "safeStringify", "logger", "safeStringify", "isComKey", "ComKey", "isQueryMatch", "isComKey", "isQueryMatch", "safeStringify", "logger", "isComKey", "ComKey", "isQueryMatch", "logger", "logger", "logger", "options", "logger", "options", "logger", "logger", "all", "one", "action", "allAction", "allFacet", "facet", "create", "get", "retrieve", "remove", "update", "find", "findOne", "set", "reset", "logger"]
|
|
7
7
|
}
|