{"version":3,"file":"index.cjs","sources":["../core/src//main/index.ts","../core/src//constants.ts"],"sourcesContent":["import { instance } from '@cachemap/controller';\nimport { MapStore } from '@cachemap/map';\nimport { type DehydratedMetadata, type Metadata, type Store, type Tag } from '@cachemap/types';\nimport {\n  ArgsError,\n  GroupedError,\n  PositionError,\n  ValueFormat,\n  constants,\n  dehydrateMetadata,\n  isJsonValue,\n  prepareGetEntry,\n  prepareSetEntry,\n  rehydrateMetadata,\n  sizeOf,\n} from '@cachemap/utils';\nimport { Cacheability } from 'cacheability';\nimport { EventEmitter } from 'eventemitter3';\nimport { castArray, get, isArray, isFunction, isNumber, isPlainObject, isString, isUndefined } from 'lodash-es';\nimport { Md5 } from 'ts-md5';\nimport { type JsonValue } from 'type-fest';\nimport { DEFAULT_BACKUP_INTERVAL, DEFAULT_MAX_HEAP_SIZE } from '../constants.ts';\nimport {\n  type CacheHeaders,\n  type ConstructorOptions,\n  type ControllerEvent,\n  type ExportOptions,\n  type ExportResult,\n  type FilterByValue,\n  type ImportOptions,\n  type MethodName,\n  type Reaper,\n  type ReaperInit,\n  type RequestQueue,\n} from '../types.ts';\n\nexport class Core {\n  public events = {\n    ENTRY_DELETED: 'ENTRY_DELETED',\n  };\n\n  private static _sortComparator = (a: Metadata, b: Metadata): number => {\n    let index;\n\n    if (a.accessedCount > b.accessedCount) {\n      index = -1;\n    } else if (a.accessedCount < b.accessedCount) {\n      index = 1;\n    } else if (a.lastAccessed > b.lastAccessed) {\n      index = -1;\n    } else if (a.lastAccessed < b.lastAccessed) {\n      index = 1;\n    } else if (a.lastUpdated > b.lastUpdated) {\n      index = -1;\n    } else if (a.lastUpdated < b.lastUpdated) {\n      index = 1;\n    } else if (a.added > b.added) {\n      index = -1;\n    } else if (a.added < b.added) {\n      index = 1;\n    } else if (a.size < b.size) {\n      index = -1;\n    } else if (a.size > b.size) {\n      index = 1;\n    } else {\n      index = 0;\n    }\n\n    return index;\n  };\n\n  private _handleClearEvent = ({ name, type }: ControllerEvent): void => {\n    if ((isString(name) && name === this._name) || (isString(type) && type === this._type)) {\n      void this._clear();\n    }\n  };\n\n  private _handleStartReaperEvent = ({ name, type }: ControllerEvent): void => {\n    if ((isString(name) && name === this._name) || (isString(type) && type === this._type)) {\n      this._reaper?.start();\n    }\n  };\n\n  private _handleStopReaperEvent = ({ name, type }: ControllerEvent): void => {\n    if ((isString(name) && name === this._name) || (isString(type) && type === this._type)) {\n      this._reaper?.stop();\n    }\n  };\n\n  private _handleStartBackupEvent = ({ name, type }: ControllerEvent): void => {\n    if ((isString(name) && name === this._name) || (isString(type) && type === this._type)) {\n      this._startBackup();\n    }\n  };\n\n  private _handleStopBackupEvent = ({ name, type }: ControllerEvent): void => {\n    if ((isString(name) && name === this._name) || (isString(type) && type === this._type)) {\n      this._stopBackup();\n    }\n  };\n\n  private _backupInterval: number = DEFAULT_BACKUP_INTERVAL;\n  private _backupIntervalID?: NodeJS.Timeout;\n  private _backupStore?: Store;\n  private readonly _disableCacheInvalidation: boolean;\n  private _emitter: EventEmitter = new EventEmitter();\n  private readonly _encryptionSecret: string | undefined;\n  private _maxHeapSize: number = DEFAULT_MAX_HEAP_SIZE;\n  private _metadata: Metadata[] = [];\n  private readonly _name: string;\n  private _persistedStore = true;\n  private _processing: string[] = [];\n  private _ready = false;\n  private readonly _reaper?: Reaper;\n  private _requestQueue: RequestQueue = [];\n  private readonly _sharedCache: boolean;\n  private _store?: Store;\n  private readonly _type: string;\n  private _usedHeapSize = 0;\n  private readonly _valueFormatting: ValueFormat = ValueFormat.String;\n\n  constructor(options: ConstructorOptions) {\n    const errors: ArgsError[] = [];\n\n    if (!isPlainObject(options)) {\n      errors.push(new ArgsError('@cachemap/core expected options to be a plain object.'));\n    }\n\n    if (!isString(options.name)) {\n      errors.push(new ArgsError('@cachemap/core expected options.name to be a string.'));\n    }\n\n    if (!isFunction(options.store)) {\n      errors.push(new ArgsError('@cachemap/core expected options.store to be a function.'));\n    }\n\n    if (!isString(options.type)) {\n      errors.push(new ArgsError('@cachemap/core expected options.type to be a string.'));\n    }\n\n    if (options.valueFormatting === ValueFormat.Ecrypt && !options.encryptionSecret) {\n      errors.push(\n        new ArgsError('@cachemap/core expected encryptionSecret to be set when valueFormatting is \"encrypt\"'),\n      );\n    }\n\n    if (errors.length > 0) {\n      throw new GroupedError('@cachemap/core constructor argument validation errors.', errors);\n    }\n\n    const {\n      backupInterval,\n      backupStore,\n      disableCacheInvalidation = false,\n      encryptionSecret,\n      name,\n      reaper,\n      sharedCache = false,\n      sortComparator,\n      startBackup,\n      store: storeInit,\n      type,\n      valueFormatting,\n    } = options;\n\n    this._disableCacheInvalidation = disableCacheInvalidation;\n\n    if (valueFormatting) {\n      this._valueFormatting = valueFormatting;\n    }\n\n    if (isString(encryptionSecret)) {\n      this._encryptionSecret = encryptionSecret;\n    }\n\n    this._name = name;\n\n    if (isFunction(reaper)) {\n      this._reaper = this._initializeReaper(reaper);\n    }\n\n    this._sharedCache = sharedCache;\n\n    if (isFunction(sortComparator)) {\n      Core._sortComparator = sortComparator;\n    }\n\n    this._type = type;\n    this._addControllerEventListeners();\n\n    void Promise.resolve(storeInit({ name })).then(async store => {\n      this._maxHeapSize = store.maxHeapSize;\n\n      if (backupStore) {\n        if (store.type === 'map') {\n          throw new ArgsError(\"@cachemap/core expected store.type not to be 'map' when backupStore is true.\");\n        }\n\n        if (isNumber(backupInterval)) {\n          this._backupInterval = backupInterval;\n        }\n\n        this._backupStore = store;\n        this._persistedStore = true;\n        this._store = new MapStore({ maxHeapSize: store.maxHeapSize, name });\n        await this._backupStoreEntriesToStore();\n        this._ready = true;\n        void this._releaseQueuedRequests();\n\n        if (startBackup) {\n          this._startBackup();\n        }\n      } else {\n        this._persistedStore = store.type !== 'map';\n        this._store = store;\n        await this._retreiveMetadataFromStore();\n        this._ready = true;\n        void this._releaseQueuedRequests();\n      }\n    });\n  }\n\n  public async clear(): Promise<void> {\n    return this._clear();\n  }\n\n  public async delete(key: string, options: { hashKey?: boolean } = {}): Promise<boolean> {\n    const errors: ArgsError[] = [];\n\n    if (!isString(key)) {\n      errors.push(new ArgsError('@cachemap/core expected key to be a string.'));\n    }\n\n    if (!isPlainObject(options)) {\n      errors.push(new ArgsError('@cachemap/core expected options to be a plain object.'));\n    }\n\n    if (errors.length > 0) {\n      throw new GroupedError('@cachemap/core delete argument validation errors.', errors);\n    }\n\n    return this._delete(key, options);\n  }\n\n  get emitter(): EventEmitter {\n    return this._emitter;\n  }\n\n  public async entries<T>(keys?: string[]): Promise<[string, T][]> {\n    if (keys && !isArray(keys)) {\n      throw new ArgsError('@cachemap/core expected keys to be an array.');\n    }\n\n    const entries = await this._entries<T>(keys);\n\n    return entries.sort(([a], [b]) => {\n      if (a < b) {\n        return -1;\n      }\n\n      if (a > b) {\n        return 1;\n      }\n\n      return 0;\n    });\n  }\n\n  public async export<T>(options: ExportOptions = {}): Promise<ExportResult<T>> {\n    const errors: ArgsError[] = [];\n\n    if (!isPlainObject(options)) {\n      errors.push(new ArgsError('@cachemap/core expected options to be an plain object.'));\n    }\n\n    if (options.keys && !isArray(options.keys)) {\n      errors.push(new ArgsError('@cachemap/core expected options.keys to be an array.'));\n    }\n\n    if (errors.length > 0) {\n      throw new GroupedError('@cachemap/core export argument validation errors.', errors);\n    }\n\n    const { entries, metadata } = await this._export<T>(options);\n\n    return {\n      entries: entries.sort(([a], [b]) => {\n        if (a < b) {\n          return -1;\n        }\n\n        if (a > b) {\n          return 1;\n        }\n\n        return 0;\n      }),\n      metadata: metadata.sort((a, b) => {\n        if (a.key < b.key) {\n          return -1;\n        }\n\n        if (a.key > b.key) {\n          return 1;\n        }\n\n        return 0;\n      }),\n    };\n  }\n\n  public async get<T>(key: string, options: { hashKey?: boolean } = {}): Promise<T | undefined> {\n    const errors: ArgsError[] = [];\n\n    if (!isString(key)) {\n      errors.push(new ArgsError('@cachemap/core expected key to be a string.'));\n    }\n\n    if (!isPlainObject(options)) {\n      errors.push(new ArgsError('@cachemap/core expected options to be a plain object.'));\n    }\n\n    if (errors.length > 0) {\n      throw new GroupedError('@cachemap/core get argument validation errors.', errors);\n    }\n\n    return this._get<T>(key, options);\n  }\n\n  public async has(\n    key: string,\n    options: { deleteExpired?: boolean; hashKey?: boolean } = {},\n  ): Promise<false | Cacheability> {\n    const errors: ArgsError[] = [];\n\n    if (!isString(key)) {\n      errors.push(new ArgsError('@cachemap/core expected key to be a string.'));\n    }\n\n    if (!isPlainObject(options)) {\n      errors.push(new ArgsError('@cachemap/core expected opts to be a plain object.'));\n    }\n\n    if (errors.length > 0) {\n      throw new GroupedError('@cachemap/core has argument validation errors.', errors);\n    }\n\n    return this._has(key, options);\n  }\n\n  public async import(options: ImportOptions): Promise<void> {\n    if (!isPlainObject(options)) {\n      throw new ArgsError('@cachemap/core expected options to be a plain object.');\n    }\n\n    const { entries, metadata } = options;\n    const errors: ArgsError[] = [];\n\n    if (!isArray(entries)) {\n      errors.push(new ArgsError('@cachemap/core expected entries to be an array.'));\n    }\n\n    if (!isArray(metadata)) {\n      errors.push(new ArgsError('@cachemap/core expected metadata to be an array.'));\n    }\n\n    if (errors.length > 0) {\n      throw new GroupedError('@cachemap/core has argument validation errors.', errors);\n    }\n\n    return this._import(options);\n  }\n\n  get metadata(): Metadata[] {\n    return this._metadata;\n  }\n\n  get name(): string {\n    return this._name;\n  }\n\n  get reaper(): Reaper | undefined {\n    return this._reaper;\n  }\n\n  public async set(\n    key: string,\n    value: unknown,\n    options: { cacheHeaders?: CacheHeaders; hashKey?: boolean; tag?: Tag } = {},\n  ): Promise<void> {\n    const errors: ArgsError[] = [];\n\n    if (!isString(key)) {\n      errors.push(new ArgsError('@cachemap/core expected key to be a string.'));\n    }\n\n    if (!isPlainObject(options)) {\n      errors.push(new ArgsError('@cachemap/core expected options to be a plain object.'));\n    }\n\n    if (!isJsonValue(value)) {\n      errors.push(new ArgsError('@cachemap/core expected value to be JSON serializable.'));\n    }\n\n    if (errors.length > 0) {\n      throw new GroupedError('@cachemap/core set argument validation errors.', errors);\n    }\n\n    // typescript not deriving value is JsonValue from above type guard.\n    // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n    return this._set(key, value as JsonValue, options);\n  }\n\n  public async size(): Promise<number> {\n    return this._size();\n  }\n\n  public startBackup(): void {\n    this._startBackup();\n  }\n\n  public stopBackup(): void {\n    this._stopBackup();\n  }\n\n  get storeType(): string {\n    return this._store?.type ?? 'none';\n  }\n\n  get type(): string {\n    return this._type;\n  }\n\n  get usedHeapSize(): number {\n    return this._usedHeapSize;\n  }\n\n  private _addControllerEventListeners() {\n    instance.on(constants.CLEAR, this._handleClearEvent);\n    instance.on(constants.START_REAPER, this._handleStartReaperEvent);\n    instance.on(constants.STOP_REAPER, this._handleStopReaperEvent);\n    instance.on(constants.START_BACKUP, this._handleStartBackupEvent);\n    instance.on(constants.STOP_BACKUP, this._handleStopBackupEvent);\n  }\n\n  private async _addMetadata(key: string, size: number, cacheability: Cacheability, tag?: Tag): Promise<void> {\n    this._metadata.push({\n      accessedCount: 0,\n      added: Date.now(),\n      cacheability,\n      key,\n      lastAccessed: Date.now(),\n      lastUpdated: Date.now(),\n      size,\n      tags: tag ? [tag] : [],\n      updatedCount: 0,\n    });\n\n    this._sortMetadata();\n    this._updateHeapSize();\n    return this._backupMetadata();\n  }\n\n  private _addRequestToQueue<T>(methodName: MethodName, ...payload: unknown[]) {\n    return new Promise((resolve: (value: T) => void) => {\n      this._requestQueue.push([resolve, methodName, payload]);\n    });\n  }\n\n  private async _backupMetadata(): Promise<void> {\n    if (!this._store || !this._persistedStore) {\n      return;\n    }\n\n    const store = this._backupStore ?? this._store;\n\n    return store.set(\n      constants.METADATA,\n      // metadata is serializable as JSON.\n      // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n      prepareSetEntry(dehydrateMetadata(this._metadata) as JsonValue, this._valueFormatting, this._encryptionSecret),\n    );\n  }\n\n  private async _backupStoreEntriesToStore(): Promise<void> {\n    if (!(this._backupStore && this._store)) {\n      throw new PositionError(\n        '@cachemap/core expected backupStoreEntriesToStore to be called after setting the backupStore and store.',\n      );\n    }\n\n    this._metadata = [];\n    const backupMetadata = await this._backupStore.get(constants.METADATA);\n\n    if (backupMetadata) {\n      const metadata = prepareGetEntry<DehydratedMetadata[]>(\n        backupMetadata,\n        this._valueFormatting,\n        this._encryptionSecret,\n      );\n\n      if (metadata.length > 0) {\n        const keys = metadata.map(entry => entry.key);\n        await this._store.import(await this._backupStore.entries(keys));\n        this._metadata = rehydrateMetadata(metadata);\n      }\n    }\n  }\n\n  private _calcReductionChunk(): number | undefined {\n    const reductionSize = Math.round(this._maxHeapSize * 0.2);\n    let chunkSize = 0;\n    let chunk: number | undefined;\n\n    for (let index = this._metadata.length - 1; index >= 0; index -= 1) {\n      // Based on surrounding code context, this cannot be undefined.\n      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n      chunkSize += this._metadata[index]!.size;\n\n      if (chunkSize > reductionSize) {\n        chunk = index;\n        break;\n      }\n    }\n\n    return chunk;\n  }\n\n  private async _clear(): Promise<void> {\n    if (!this._ready || !this._store) {\n      return this._addRequestToQueue(constants.CLEAR);\n    }\n\n    await this._store.clear();\n    this._metadata = [];\n    this._processing = [];\n    this._updateHeapSize();\n    return this._backupMetadata();\n  }\n\n  private async _delete(key: string, options: { hashKey?: boolean } = {}): Promise<boolean> {\n    if (!this._ready || !this._store) {\n      return this._addRequestToQueue(constants.DELETE, key, options);\n    }\n\n    const deleteKey = options.hashKey ? Md5.hashStr(key) : key;\n    const deleted = await this._store.delete(deleteKey);\n\n    if (!deleted) {\n      return false;\n    }\n\n    await this._deleteMetadata(deleteKey);\n    return true;\n  }\n\n  private async _deleteMetadata(key: string): Promise<void> {\n    const index = this._metadata.findIndex(metadata => metadata.key === key);\n\n    if (index === -1) {\n      return;\n    }\n\n    this._metadata.splice(index, 1);\n    this._sortMetadata();\n    this._updateHeapSize();\n    return this._backupMetadata();\n  }\n\n  private async _entries<T>(keys?: string[]): Promise<[string, T][]> {\n    if (!this._ready || !this._store) {\n      return this._addRequestToQueue(constants.ENTRIES, keys);\n    }\n\n    const entryKeys = keys ?? this._metadata.map(metadata => metadata.key);\n    const entries = await this._store.entries(entryKeys);\n    return entries.map(([key, data]) => [key, prepareGetEntry(data, this._valueFormatting, this._encryptionSecret)]);\n  }\n\n  private async _export<T>({\n    filterByValue,\n    keys,\n    tag,\n  }: {\n    filterByValue?: FilterByValue | FilterByValue[];\n    keys?: string[];\n    tag?: Tag;\n  }): Promise<ExportResult<T>> {\n    let exportKeys: string[] | undefined;\n    let metadata = this._metadata;\n\n    if (tag) {\n      metadata = this._metadata.filter(meta => meta.tags.includes(tag));\n      exportKeys = metadata.map(meta => meta.key);\n    } else if (keys) {\n      metadata = this._metadata.filter(meta => keys.includes(meta.key));\n      exportKeys = keys;\n    }\n\n    let entries = await this._entries<T>(exportKeys);\n\n    if (filterByValue) {\n      const castFilterByValue = castArray(filterByValue);\n\n      entries = entries.filter(([, data]) =>\n        castFilterByValue.every(({ comparator, keyChain }) => get(data, keyChain) === comparator),\n      );\n\n      metadata = metadata.filter(meta => entries.some(([key]) => key === meta.key));\n    }\n\n    return { entries, metadata };\n  }\n\n  private async _get<T>(key: string, options: { hashKey?: boolean }): Promise<T | undefined> {\n    if (!this._ready || !this._store) {\n      return this._addRequestToQueue(constants.GET, key, options);\n    }\n\n    const getKey = options.hashKey ? Md5.hashStr(key) : key;\n    const value = await this._store.get(getKey);\n\n    if (!value) {\n      return;\n    }\n\n    await this._updateMetadata(getKey);\n    return prepareGetEntry(value, this._valueFormatting, this._encryptionSecret);\n  }\n\n  private _getCacheability(key: string): Cacheability | undefined {\n    const metadata = this._getMetadataEntry(key);\n    return metadata ? metadata.cacheability : undefined;\n  }\n\n  private _getMetadataEntry(key: string): Metadata | undefined {\n    return this._metadata.find(metadata => metadata.key === key);\n  }\n\n  private async _has(\n    key: string,\n    options: { deleteExpired?: boolean; hashKey?: boolean },\n  ): Promise<false | Cacheability> {\n    if (!this._ready || !this._store) {\n      return this._addRequestToQueue(constants.HAS, key, options);\n    }\n\n    const hasKey = options.hashKey ? Md5.hashStr(key) : key;\n    const exists = await this._store.has(hasKey);\n\n    if (!exists) {\n      return false;\n    }\n\n    if (options.deleteExpired && this._hasCacheEntryExpired(hasKey)) {\n      await this.delete(hasKey);\n      return false;\n    }\n\n    return this._getCacheability(hasKey) ?? false;\n  }\n\n  private _hasCacheEntryExpired(key: string): boolean {\n    if (this._disableCacheInvalidation) {\n      return false;\n    }\n\n    const cacheability = this._getCacheability(key);\n    return cacheability ? !cacheability.checkTTL() : false;\n  }\n\n  private async _import(options: ImportOptions): Promise<void> {\n    if (!this._ready || !this._store) {\n      return this._addRequestToQueue(constants.IMPORT, options);\n    }\n\n    let filtered: Metadata[] = [];\n\n    if (this._metadata.length > 0) {\n      filtered = this._metadata.filter(metadata => {\n        return !options.metadata.some(optionsMetadata => metadata.key === optionsMetadata.key);\n      });\n    }\n\n    const entries = options.entries.map(\n      // typescript is not seeing this as a string tuple.\n      // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n      ([key, data]) => [key, prepareSetEntry(data, this._valueFormatting, this._encryptionSecret)] as [string, string],\n    );\n\n    await this._store.import(entries);\n    this._metadata = rehydrateMetadata([...filtered, ...options.metadata]);\n    this._sortMetadata();\n    await this._backupMetadata();\n    this._updateHeapSize();\n  }\n\n  private _initializeReaper(reaperInit: ReaperInit): Reaper {\n    return reaperInit({\n      deleteCallback: async (key: string, tags?: Tag[]) => {\n        this.emitter.emit(this.events.ENTRY_DELETED, { deleted: await this._delete(key), key, tags });\n      },\n      metadataCallback: () => this._metadata,\n    });\n  }\n\n  private _processed(key: string): void {\n    this._processing = this._processing.filter(value => value !== key);\n  }\n\n  private _reduceHeapSize(): void {\n    const index = this._calcReductionChunk();\n\n    if (!index || !this._reaper) {\n      return;\n    }\n\n    void this._reaper.cull(this._metadata.slice(index));\n  }\n\n  private async _releaseQueuedRequests() {\n    for (const [resolve, methodName, payload] of this._requestQueue) {\n      // @ts-expect-error complicated\n      resolve(await this[methodName](...payload));\n    }\n\n    this._requestQueue = [];\n  }\n\n  private async _retreiveMetadataFromStore(): Promise<void> {\n    if (!this._store || !this._persistedStore) {\n      return;\n    }\n\n    const metadata = await this._store.get(constants.METADATA);\n\n    if (metadata) {\n      this._metadata = rehydrateMetadata(prepareGetEntry(metadata, this._valueFormatting, this._encryptionSecret));\n    }\n  }\n\n  private async _set(\n    key: string,\n    value: JsonValue,\n    options: { cacheHeaders?: CacheHeaders; hashKey?: boolean; tag?: Tag },\n  ): Promise<void> {\n    if (!this._ready || !this._store) {\n      return this._addRequestToQueue(constants.SET, key, value, options);\n    }\n\n    const cacheability = new Cacheability({ headers: options.cacheHeaders });\n    const { cacheControl } = cacheability.metadata;\n\n    if (cacheControl.noStore || (this._sharedCache && cacheControl.private)) {\n      return;\n    }\n\n    const setKey = options.hashKey ? Md5.hashStr(key) : key;\n    const processing = this._processing.includes(setKey);\n\n    if (!processing) {\n      this._processing.push(setKey);\n    }\n\n    try {\n      const exists = (await this._store.has(setKey)) || processing;\n      const preparedSetValue = prepareSetEntry(value, this._valueFormatting, this._encryptionSecret);\n      await this._store.set(setKey, preparedSetValue);\n\n      await (exists\n        ? this._updateMetadata(setKey, sizeOf(preparedSetValue), cacheability, options.tag)\n        : this._addMetadata(setKey, sizeOf(preparedSetValue), cacheability, options.tag));\n\n      this._processed(setKey);\n    } catch (error) {\n      this._processed(setKey);\n      throw error;\n    }\n  }\n\n  private async _size(): Promise<number> {\n    if (!this._ready || !this._store) {\n      return this._addRequestToQueue(constants.SIZE);\n    }\n\n    return this._store.size();\n  }\n\n  private _sortMetadata(): void {\n    this._metadata.sort(Core._sortComparator);\n  }\n\n  private _startBackup(): void {\n    this._backupIntervalID = setInterval(() => {\n      void this._storeEntriesToBackupStore();\n    }, this._backupInterval);\n  }\n\n  private _stopBackup(): void {\n    if (this._backupIntervalID) {\n      clearInterval(this._backupIntervalID);\n    }\n  }\n\n  private async _storeEntriesToBackupStore(): Promise<void> {\n    if (!(this._backupStore && this._store)) {\n      return;\n    }\n\n    await this._backupStore.clear();\n    const keys = this._metadata.map(entry => entry.key);\n    void this._backupStore.import(await this._store.entries(keys));\n  }\n\n  private _updateHeapSize(): void {\n    this._usedHeapSize = this._metadata.reduce((acc, value) => acc + value.size, 0);\n\n    if (!this._disableCacheInvalidation && this._usedHeapSize > this._maxHeapSize) {\n      this._reduceHeapSize();\n    }\n  }\n\n  private async _updateMetadata(key: string, size?: number, cacheability?: Cacheability, tag?: Tag): Promise<void> {\n    const entry = this._getMetadataEntry(key);\n\n    if (!entry) {\n      return;\n    }\n\n    if (size) {\n      entry.size = size;\n      entry.lastUpdated = Date.now();\n      entry.updatedCount += 1;\n    } else {\n      entry.accessedCount += 1;\n      entry.lastAccessed = Date.now();\n    }\n\n    if (cacheability) {\n      entry.cacheability = cacheability;\n    }\n\n    if (!isUndefined(tag)) {\n      entry.tags.push(tag);\n    }\n\n    this._sortMetadata();\n    this._updateHeapSize();\n    return this._backupMetadata();\n  }\n}\n","export const DEFAULT_MAX_HEAP_SIZE = 4_194_304;\nexport const DEFAULT_BACKUP_INTERVAL = 10_000;\n"],"names":["Core","_sortComparator","a","b","index","accessedCount","lastAccessed","lastUpdated","added","size","constructor","options","events","ENTRY_DELETED","_handleClearEvent","name","type","isString","this","_name","_type","_clear","_handleStartReaperEvent","_reaper","start","_handleStopReaperEvent","stop","_handleStartBackupEvent","_startBackup","_handleStopBackupEvent","_stopBackup","_backupInterval","_emitter","EventEmitter","_maxHeapSize","_metadata","_persistedStore","_processing","_ready","_requestQueue","_usedHeapSize","_valueFormatting","ValueFormat","String","errors","isPlainObject","push","ArgsError","isFunction","store","valueFormatting","Ecrypt","encryptionSecret","length","GroupedError","backupInterval","backupStore","disableCacheInvalidation","reaper","sharedCache","sortComparator","startBackup","storeInit","_disableCacheInvalidation","_encryptionSecret","_initializeReaper","_sharedCache","_addControllerEventListeners","Promise","resolve","then","async","maxHeapSize","isNumber","_backupStore","_store","MapStore","_backupStoreEntriesToStore","_releaseQueuedRequests","_retreiveMetadataFromStore","clear","delete","key","_delete","emitter","entries","keys","isArray","_entries","sort","export","metadata","_export","get","_get","has","_has","import","_import","set","value","isJsonValue","_set","_size","stopBackup","storeType","usedHeapSize","instance","on","constants","CLEAR","START_REAPER","STOP_REAPER","START_BACKUP","STOP_BACKUP","_addMetadata","cacheability","tag","Date","now","tags","updatedCount","_sortMetadata","_updateHeapSize","_backupMetadata","_addRequestToQueue","methodName","payload","METADATA","prepareSetEntry","dehydrateMetadata","PositionError","backupMetadata","prepareGetEntry","map","entry","rehydrateMetadata","_calcReductionChunk","reductionSize","Math","round","chunk","chunkSize","DELETE","deleteKey","hashKey","Md5","hashStr","_deleteMetadata","findIndex","splice","ENTRIES","entryKeys","data","filterByValue","exportKeys","filter","meta","includes","castFilterByValue","castArray","every","comparator","keyChain","some","GET","getKey","_updateMetadata","_getCacheability","_getMetadataEntry","undefined","find","HAS","hasKey","deleteExpired","_hasCacheEntryExpired","checkTTL","IMPORT","filtered","optionsMetadata","reaperInit","deleteCallback","emit","deleted","metadataCallback","_processed","_reduceHeapSize","cull","slice","SET","Cacheability","headers","cacheHeaders","cacheControl","noStore","private","setKey","processing","exists","preparedSetValue","sizeOf","error","SIZE","_backupIntervalID","setInterval","_storeEntriesToBackupStore","clearInterval","reduce","acc","isUndefined"],"mappings":"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"}