synapse-storage 4.1.2 → 5.0.3
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/README.md +142 -12
- package/dist/_utils/chunk.util.d.ts +0 -1
- package/dist/_utils/deepMerge.util.d.ts +0 -1
- package/dist/_utils/error-handling.util.d.ts +0 -1
- package/dist/_utils/flatMap.util.d.ts +0 -1
- package/dist/_utils/index.d.ts +0 -1
- package/dist/_utils/logger-console.util.d.ts +0 -1
- package/dist/api/api.module.d.ts +0 -1
- package/dist/api/components/endpoint.d.ts +11 -12
- package/dist/api/components/endpoint.js.map +1 -1
- package/dist/api/components/query-storage.d.ts +0 -1
- package/dist/api/components/query-storage.js +1 -1
- package/dist/api/components/query-storage.js.map +1 -1
- package/dist/api/index.d.ts +0 -1
- package/dist/api/types/api.interface.d.ts +0 -1
- package/dist/api/types/endpoint.interface.d.ts +0 -1
- package/dist/api/types/query.interface.d.ts +0 -1
- package/dist/api/utils/api-helpers.d.ts +0 -1
- package/dist/{core/storage → api}/utils/cache.util.d.ts +3 -6
- package/dist/{core/storage → api}/utils/cache.util.js +4 -7
- package/dist/api/utils/cache.util.js.map +1 -0
- package/dist/api/utils/create-header-context.d.ts +0 -1
- package/dist/api/utils/endpoint-headers.d.ts +0 -1
- package/dist/api/utils/fetch-base-query.d.ts +0 -1
- package/dist/api/utils/file-utils.d.ts +0 -1
- package/dist/api/utils/get-cacheable-headers.d.ts +0 -1
- package/dist/core/index.d.ts +0 -1
- package/dist/core/selector/index.d.ts +1 -1
- package/dist/core/selector/index.js +2 -0
- package/dist/core/selector/index.js.map +1 -1
- package/dist/core/selector/selector.interface.d.ts +15 -30
- package/dist/core/selector/selector.interface.js +2 -2
- package/dist/core/selector/selector.interface.js.map +1 -1
- package/dist/core/selector/selector.module.d.ts +16 -1
- package/dist/core/selector/selector.module.js +82 -20
- package/dist/core/selector/selector.module.js.map +1 -1
- package/dist/core/selector/selectors.base.d.ts +56 -0
- package/dist/core/selector/selectors.base.js +118 -0
- package/dist/core/selector/selectors.base.js.map +1 -0
- package/dist/core/storage/adapters/async-base-storage.service.d.ts +15 -4
- package/dist/core/storage/adapters/async-base-storage.service.js +106 -36
- package/dist/core/storage/adapters/async-base-storage.service.js.map +1 -1
- package/dist/core/storage/adapters/indexed-DB.service.d.ts +4 -5
- package/dist/core/storage/adapters/indexed-DB.service.js +66 -14
- package/dist/core/storage/adapters/indexed-DB.service.js.map +1 -1
- package/dist/core/storage/adapters/local-storage.service.d.ts +9 -4
- package/dist/core/storage/adapters/local-storage.service.js +25 -5
- package/dist/core/storage/adapters/local-storage.service.js.map +1 -1
- package/dist/core/storage/adapters/memory-storage.service.d.ts +2 -4
- package/dist/core/storage/adapters/memory-storage.service.js +5 -5
- package/dist/core/storage/adapters/memory-storage.service.js.map +1 -1
- package/dist/core/storage/adapters/path.utils.d.ts +0 -1
- package/dist/core/storage/adapters/storage-core.d.ts +6 -2
- package/dist/core/storage/adapters/storage-core.js +6 -3
- package/dist/core/storage/adapters/storage-core.js.map +1 -1
- package/dist/core/storage/adapters/sync-base-storage.service.d.ts +20 -4
- package/dist/core/storage/adapters/sync-base-storage.service.js +110 -35
- package/dist/core/storage/adapters/sync-base-storage.service.js.map +1 -1
- package/dist/core/storage/index.d.ts +2 -5
- package/dist/core/storage/index.js +1 -5
- package/dist/core/storage/index.js.map +1 -1
- package/dist/core/storage/middlewares/broadcast.middleware.d.ts +0 -1
- package/dist/core/storage/middlewares/index.d.ts +3 -1
- package/dist/core/storage/middlewares/index.js +6 -0
- package/dist/core/storage/middlewares/index.js.map +1 -1
- package/dist/core/storage/middlewares/storage-batching.middleware.d.ts +0 -1
- package/dist/core/storage/middlewares/storage-logger.middleware.d.ts +20 -0
- package/dist/core/storage/middlewares/storage-logger.middleware.js +53 -0
- package/dist/core/storage/middlewares/storage-logger.middleware.js.map +1 -0
- package/dist/core/storage/middlewares/storage-shallow-compare.middleware.d.ts +0 -1
- package/dist/core/storage/middlewares/storage-shallow-compare.middleware.js +4 -10
- package/dist/core/storage/middlewares/storage-shallow-compare.middleware.js.map +1 -1
- package/dist/core/storage/middlewares/sync-broadcast.middleware.d.ts +0 -1
- package/dist/core/storage/middlewares/sync-storage-batching.middleware.d.ts +0 -1
- package/dist/core/storage/middlewares/sync-storage-logger.middleware.d.ts +7 -0
- package/dist/core/storage/middlewares/sync-storage-logger.middleware.js +48 -0
- package/dist/core/storage/middlewares/sync-storage-logger.middleware.js.map +1 -0
- package/dist/core/storage/middlewares/sync-storage-shallow-compare.middleware.d.ts +0 -1
- package/dist/core/storage/middlewares/sync-storage-shallow-compare.middleware.js +4 -10
- package/dist/core/storage/middlewares/sync-storage-shallow-compare.middleware.js.map +1 -1
- package/dist/core/storage/modules/singleton/mixin.util.d.ts +0 -1
- package/dist/core/storage/modules/singleton/models.d.ts +0 -1
- package/dist/core/storage/modules/singleton/singleton.util.d.ts +0 -1
- package/dist/core/storage/storage.interface.d.ts +59 -4
- package/dist/core/storage/storage.interface.js +0 -2
- package/dist/core/storage/storage.interface.js.map +1 -1
- package/dist/core/storage/utils/broadcast.util.d.ts +0 -1
- package/dist/core/storage/utils/middleware-module.d.ts +0 -3
- package/dist/core/storage/utils/middleware-module.js +0 -8
- package/dist/core/storage/utils/middleware-module.js.map +1 -1
- package/dist/core/storage/utils/migration.util.d.ts +38 -0
- package/dist/core/storage/utils/migration.util.js +48 -0
- package/dist/core/storage/utils/migration.util.js.map +1 -0
- package/dist/core/storage/utils/path-selector.util.d.ts +0 -1
- package/dist/core/storage/utils/state-diff.util.d.ts +8 -1
- package/dist/core/storage/utils/state-diff.util.js +17 -1
- package/dist/core/storage/utils/state-diff.util.js.map +1 -1
- package/dist/core/storage/utils/storage-factory.util.d.ts +7 -9
- package/dist/core/storage/utils/storage-factory.util.js +10 -10
- package/dist/core/storage/utils/storage-factory.util.js.map +1 -1
- package/dist/core/storage/utils/storage-key.d.ts +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/react/hooks/index.d.ts +2 -1
- package/dist/react/hooks/index.js +4 -0
- package/dist/react/hooks/index.js.map +1 -1
- package/dist/react/hooks/useCreateStorage.d.ts +5 -6
- package/dist/react/hooks/useCreateStorage.js +2 -2
- package/dist/react/hooks/useCreateStorage.js.map +1 -1
- package/dist/react/hooks/useObservable.d.ts +17 -0
- package/dist/react/hooks/useObservable.js +38 -0
- package/dist/react/hooks/useObservable.js.map +1 -0
- package/dist/react/hooks/useSelector.d.ts +0 -1
- package/dist/react/hooks/useSelector.js +5 -2
- package/dist/react/hooks/useSelector.js.map +1 -1
- package/dist/react/hooks/useStorage.d.ts +0 -1
- package/dist/react/hooks/useStorageSubscribe.d.ts +0 -1
- package/dist/react/hooks/useSubscription.d.ts +13 -0
- package/dist/react/hooks/useSubscription.js +23 -0
- package/dist/react/hooks/useSubscription.js.map +1 -0
- package/dist/react/index.d.ts +0 -1
- package/dist/react/utils/awaitSynapse.d.ts +9 -10
- package/dist/react/utils/awaitSynapse.js +3 -2
- package/dist/react/utils/awaitSynapse.js.map +1 -1
- package/dist/react/utils/createSynapseCtx.d.ts +18 -23
- package/dist/react/utils/createSynapseCtx.js +64 -39
- package/dist/react/utils/createSynapseCtx.js.map +1 -1
- package/dist/react/utils/index.d.ts +0 -1
- package/dist/reactive/dispatcher/dispatcher.base.d.ts +122 -0
- package/dist/reactive/dispatcher/dispatcher.base.js +294 -0
- package/dist/reactive/dispatcher/dispatcher.base.js.map +1 -0
- package/dist/reactive/dispatcher/dispatcher.module.d.ts +12 -67
- package/dist/reactive/dispatcher/dispatcher.module.js +13 -72
- package/dist/reactive/dispatcher/dispatcher.module.js.map +1 -1
- package/dist/reactive/dispatcher/index.d.ts +1 -1
- package/dist/reactive/dispatcher/index.js +2 -0
- package/dist/reactive/dispatcher/index.js.map +1 -1
- package/dist/reactive/dispatcher/middlewares/index.d.ts +0 -1
- package/dist/reactive/dispatcher/middlewares/logger.middleware.d.ts +0 -1
- package/dist/reactive/dispatcher/path.util.d.ts +15 -0
- package/dist/reactive/dispatcher/path.util.js +34 -0
- package/dist/reactive/dispatcher/path.util.js.map +1 -0
- package/dist/reactive/dispatcher/standalone.d.ts +1 -150
- package/dist/reactive/dispatcher/standalone.js +6 -217
- package/dist/reactive/dispatcher/standalone.js.map +1 -1
- package/dist/reactive/effects/effects.base.d.ts +62 -0
- package/dist/reactive/effects/effects.base.js +90 -0
- package/dist/reactive/effects/effects.base.js.map +1 -0
- package/dist/reactive/effects/effects.module.d.ts +122 -11
- package/dist/reactive/effects/effects.module.js +129 -17
- package/dist/reactive/effects/effects.module.js.map +1 -1
- package/dist/reactive/effects/index.d.ts +1 -1
- package/dist/reactive/effects/index.js +2 -0
- package/dist/reactive/effects/index.js.map +1 -1
- package/dist/reactive/effects/utils/chunkRequestConsistent.d.ts +0 -1
- package/dist/reactive/effects/utils/chunkRequestParallel.d.ts +0 -1
- package/dist/reactive/effects/utils/fromRequest.d.ts +0 -1
- package/dist/reactive/effects/utils/index.d.ts +0 -1
- package/dist/reactive/effects/utils/toObservable.d.ts +0 -1
- package/dist/reactive/index.d.ts +0 -1
- package/dist/utils/createEventBus.d.ts +47 -46
- package/dist/utils/createEventBus.js +152 -174
- package/dist/utils/createEventBus.js.map +1 -1
- package/dist/utils/createSynapse/createSynapse.d.ts +25 -7
- package/dist/utils/createSynapse/createSynapse.js +28 -98
- package/dist/utils/createSynapse/createSynapse.js.map +1 -1
- package/dist/utils/createSynapse/factory.d.ts +6 -0
- package/dist/utils/createSynapse/factory.js +256 -0
- package/dist/utils/createSynapse/factory.js.map +1 -0
- package/dist/utils/createSynapse/index.d.ts +2 -2
- package/dist/utils/createSynapse/index.js.map +1 -1
- package/dist/utils/createSynapse/synapse.types.d.ts +87 -0
- package/dist/utils/createSynapse/synapse.types.js +11 -0
- package/dist/utils/createSynapse/synapse.types.js.map +1 -0
- package/dist/utils/createSynapse/types.d.ts +6 -85
- package/dist/utils/createSynapse/types.js +2 -1
- package/dist/utils/createSynapse/types.js.map +1 -1
- package/dist/utils/createSynapse/waitForDependencies.d.ts +0 -1
- package/dist/utils/createSynapse/waitForDependencies.js +1 -1
- package/dist/utils/createSynapse/waitForDependencies.js.map +1 -1
- package/dist/utils/createSynapseAwaiter.d.ts +13 -10
- package/dist/utils/createSynapseAwaiter.js +30 -3
- package/dist/utils/createSynapseAwaiter.js.map +1 -1
- package/dist/utils/dehydrateModule.d.ts +6 -0
- package/dist/utils/dehydrateModule.js +43 -0
- package/dist/utils/dehydrateModule.js.map +1 -0
- package/dist/utils/index.d.ts +3 -3
- package/dist/utils/index.js +3 -0
- package/dist/utils/index.js.map +1 -1
- package/package.json +12 -2
- package/dist/_utils/chunk.util.d.ts.map +0 -1
- package/dist/_utils/deepMerge.util.d.ts.map +0 -1
- package/dist/_utils/error-handling.util.d.ts.map +0 -1
- package/dist/_utils/flatMap.util.d.ts.map +0 -1
- package/dist/_utils/index.d.ts.map +0 -1
- package/dist/_utils/logger-console.util.d.ts.map +0 -1
- package/dist/api/api.module.d.ts.map +0 -1
- package/dist/api/components/endpoint.d.ts.map +0 -1
- package/dist/api/components/query-storage.d.ts.map +0 -1
- package/dist/api/example.d.ts +0 -83
- package/dist/api/example.d.ts.map +0 -1
- package/dist/api/example.js +0 -90
- package/dist/api/example.js.map +0 -1
- package/dist/api/index.d.ts.map +0 -1
- package/dist/api/types/api.interface.d.ts.map +0 -1
- package/dist/api/types/endpoint.interface.d.ts.map +0 -1
- package/dist/api/types/query.interface.d.ts.map +0 -1
- package/dist/api/utils/api-helpers.d.ts.map +0 -1
- package/dist/api/utils/create-header-context.d.ts.map +0 -1
- package/dist/api/utils/endpoint-headers.d.ts.map +0 -1
- package/dist/api/utils/fetch-base-query.d.ts.map +0 -1
- package/dist/api/utils/file-utils.d.ts.map +0 -1
- package/dist/api/utils/get-cacheable-headers.d.ts.map +0 -1
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/selector/index.d.ts.map +0 -1
- package/dist/core/selector/selector.interface.d.ts.map +0 -1
- package/dist/core/selector/selector.module.d.ts.map +0 -1
- package/dist/core/storage/adapters/async-base-storage.service.d.ts.map +0 -1
- package/dist/core/storage/adapters/indexed-DB.service.d.ts.map +0 -1
- package/dist/core/storage/adapters/local-storage.service.d.ts.map +0 -1
- package/dist/core/storage/adapters/memory-storage.service.d.ts.map +0 -1
- package/dist/core/storage/adapters/path.utils.d.ts.map +0 -1
- package/dist/core/storage/adapters/storage-core.d.ts.map +0 -1
- package/dist/core/storage/adapters/sync-base-storage.service.d.ts.map +0 -1
- package/dist/core/storage/index.d.ts.map +0 -1
- package/dist/core/storage/middlewares/broadcast.middleware.d.ts.map +0 -1
- package/dist/core/storage/middlewares/index.d.ts.map +0 -1
- package/dist/core/storage/middlewares/storage-batching.middleware.d.ts.map +0 -1
- package/dist/core/storage/middlewares/storage-shallow-compare.middleware.d.ts.map +0 -1
- package/dist/core/storage/middlewares/sync-broadcast.middleware.d.ts.map +0 -1
- package/dist/core/storage/middlewares/sync-storage-batching.middleware.d.ts.map +0 -1
- package/dist/core/storage/middlewares/sync-storage-shallow-compare.middleware.d.ts.map +0 -1
- package/dist/core/storage/modules/plugin/plugin.interface.d.ts +0 -101
- package/dist/core/storage/modules/plugin/plugin.interface.d.ts.map +0 -1
- package/dist/core/storage/modules/plugin/plugin.interface.js +0 -8
- package/dist/core/storage/modules/plugin/plugin.interface.js.map +0 -1
- package/dist/core/storage/modules/plugin/plugin.service.d.ts +0 -49
- package/dist/core/storage/modules/plugin/plugin.service.d.ts.map +0 -1
- package/dist/core/storage/modules/plugin/plugin.service.js +0 -406
- package/dist/core/storage/modules/plugin/plugin.service.js.map +0 -1
- package/dist/core/storage/modules/singleton/mixin.util.d.ts.map +0 -1
- package/dist/core/storage/modules/singleton/models.d.ts.map +0 -1
- package/dist/core/storage/modules/singleton/singleton.util.d.ts.map +0 -1
- package/dist/core/storage/storage.interface.d.ts.map +0 -1
- package/dist/core/storage/utils/broadcast.util.d.ts.map +0 -1
- package/dist/core/storage/utils/cache.util.d.ts.map +0 -1
- package/dist/core/storage/utils/cache.util.js.map +0 -1
- package/dist/core/storage/utils/middleware-module.d.ts.map +0 -1
- package/dist/core/storage/utils/path-selector.util.d.ts.map +0 -1
- package/dist/core/storage/utils/state-diff.util.d.ts.map +0 -1
- package/dist/core/storage/utils/storage-factory.util.d.ts.map +0 -1
- package/dist/core/storage/utils/storage-key.d.ts.map +0 -1
- package/dist/core/storage/utils/storage.utils.d.ts +0 -17
- package/dist/core/storage/utils/storage.utils.d.ts.map +0 -1
- package/dist/core/storage/utils/storage.utils.js +0 -57
- package/dist/core/storage/utils/storage.utils.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/react/hooks/index.d.ts.map +0 -1
- package/dist/react/hooks/useCreateStorage.d.ts.map +0 -1
- package/dist/react/hooks/useSelector.d.ts.map +0 -1
- package/dist/react/hooks/useStorage.d.ts.map +0 -1
- package/dist/react/hooks/useStorageSubscribe.d.ts.map +0 -1
- package/dist/react/index.d.ts.map +0 -1
- package/dist/react/utils/awaitSynapse.d.ts.map +0 -1
- package/dist/react/utils/createSynapseCtx.d.ts.map +0 -1
- package/dist/react/utils/index.d.ts.map +0 -1
- package/dist/reactive/dispatcher/dispatcher.module.d.ts.map +0 -1
- package/dist/reactive/dispatcher/index.d.ts.map +0 -1
- package/dist/reactive/dispatcher/middlewares/index.d.ts.map +0 -1
- package/dist/reactive/dispatcher/middlewares/logger.middleware.d.ts.map +0 -1
- package/dist/reactive/dispatcher/standalone.d.ts.map +0 -1
- package/dist/reactive/effects/effects.module.d.ts.map +0 -1
- package/dist/reactive/effects/index.d.ts.map +0 -1
- package/dist/reactive/effects/utils/chunkRequestConsistent.d.ts.map +0 -1
- package/dist/reactive/effects/utils/chunkRequestParallel.d.ts.map +0 -1
- package/dist/reactive/effects/utils/fromRequest.d.ts.map +0 -1
- package/dist/reactive/effects/utils/index.d.ts.map +0 -1
- package/dist/reactive/effects/utils/toObservable.d.ts.map +0 -1
- package/dist/reactive/index.d.ts.map +0 -1
- package/dist/utils/createEventBus.d.ts.map +0 -1
- package/dist/utils/createSynapse/createSynapse.d.ts.map +0 -1
- package/dist/utils/createSynapse/index.d.ts.map +0 -1
- package/dist/utils/createSynapse/types.d.ts.map +0 -1
- package/dist/utils/createSynapse/validate.d.ts +0 -2
- package/dist/utils/createSynapse/validate.d.ts.map +0 -1
- package/dist/utils/createSynapse/validate.js +0 -76
- package/dist/utils/createSynapse/validate.js.map +0 -1
- package/dist/utils/createSynapse/waitForDependencies.d.ts.map +0 -1
- package/dist/utils/createSynapseAwaiter.d.ts.map +0 -1
- package/dist/utils/index.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core/storage/adapters/memory-storage.service.js","sources":["../../../../src/core/storage/adapters/memory-storage.service.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"core/storage/adapters/memory-storage.service.js","sources":["../../../../src/core/storage/adapters/memory-storage.service.ts"],"sourcesContent":["import { SingletonMixin } from '../modules/singleton/mixin.util'\nimport { IEventEmitter, ILogger, MemoryStorageConfig, StorageType } from '../storage.interface'\nimport { StorageKey, StorageKeyType } from '../utils/storage-key'\nimport { getValueByPath, parsePath, setValueByPath } from './path.utils'\nimport { SyncBaseStorage } from './sync-base-storage.service'\n\nexport class MemoryStorage<T extends Record<string, any>> extends SyncBaseStorage<T> {\n protected static readonly STORAGE_TYPE: StorageType = 'memory'\n readonly type: StorageType = 'memory'\n\n private storage = new Map<string, any>()\n\n constructor(config: MemoryStorageConfig<T>, eventEmitter?: IEventEmitter, logger?: ILogger) {\n super(config, eventEmitter, logger)\n }\n\n static create<T extends Record<string, any>>(config: MemoryStorageConfig<T>, eventEmitter?: IEventEmitter, logger?: ILogger): MemoryStorage<T> {\n return SingletonMixin.handleSingletonCreation(\n config,\n this.STORAGE_TYPE,\n (finalConfig) => new MemoryStorage<T>(finalConfig as MemoryStorageConfig<T>, eventEmitter, logger),\n logger,\n )\n }\n\n protected async doInitialize(): Promise<this> {\n try {\n this.logger?.debug(`Initializing MemoryStorage \"${this.name}\"`)\n\n this.initializeMiddlewares()\n this.initializeWithMiddlewares()\n\n this.logger?.debug(`MemoryStorage \"${this.name}\" initialized successfully`)\n return this\n } catch (error) {\n this.logger?.error('Error initializing MemoryStorage', { error })\n throw error\n }\n }\n\n protected doGet(key: StorageKeyType): any {\n const state = this.storage.get(this.name)\n if (!state) return undefined\n\n if (key instanceof StorageKey && key.isUnparseable()) {\n return state[key.valueOf()]\n }\n\n return getValueByPath(state, key)\n }\n\n protected doSet(key: StorageKeyType, value: any): void {\n const state = this.storage.get(this.name) || {}\n\n if (key instanceof StorageKey && key.isUnparseable()) {\n state[key.valueOf()] = value\n this.storage.set(this.name, state)\n return\n }\n\n const newState = setValueByPath({ ...state }, key, value)\n this.storage.set(this.name, newState)\n }\n\n protected doRemove(key: StorageKeyType): boolean {\n const state = this.storage.get(this.name)\n if (!state) return false\n\n if (key instanceof StorageKey && key.isUnparseable()) {\n const rawKey = key.valueOf()\n if (!(rawKey in state)) return false\n delete state[rawKey]\n this.storage.set(this.name, state)\n return true\n }\n\n const pathParts = parsePath(key)\n const parentPath = pathParts.slice(0, -1).join('.')\n const lastKey = pathParts[pathParts.length - 1]\n const parent = parentPath ? getValueByPath(state, parentPath) : state\n\n if (!parent || !(lastKey in parent)) return false\n\n delete parent[lastKey]\n this.storage.set(this.name, state)\n return true\n }\n\n protected doUpdate(updates: Array<{ key: StorageKeyType; value: any }>): void {\n const currentState = this.storage.get(this.name) || {}\n const newState = { ...currentState }\n\n for (const { key, value } of updates) {\n if (key instanceof StorageKey && key.isUnparseable()) {\n newState[key.valueOf()] = value\n } else {\n setValueByPath(newState, key, value)\n }\n }\n\n this.storage.set(this.name, newState)\n }\n\n protected doClear(): void {\n this.storage.delete(this.name)\n }\n\n protected doKeys(): string[] {\n const state = this.storage.get(this.name)\n if (!state) return []\n return Object.keys(state)\n }\n\n protected doHas(key: StorageKeyType): boolean {\n const value = this.doGet(key)\n return value !== undefined\n }\n\n protected async doDestroy(): Promise<void> {\n // Очистка управляется флагом config.clearOnDestroy в performCleanup (memory → по умолчанию true).\n }\n}\n"],"names":["SingletonMixin","StorageKey","getValueByPath","parsePath","setValueByPath","SyncBaseStorage","MemoryStorage","Map","config","eventEmitter","logger","finalConfig","error","key","state","undefined","value","newState","rawKey","pathParts","parentPath","lastKey","parent","updates","currentState","Object"],"mappings":"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"}
|
|
@@ -2,4 +2,3 @@ import { StorageKey } from '../utils/storage-key';
|
|
|
2
2
|
export declare function parsePath(path: string | StorageKey): string[];
|
|
3
3
|
export declare function getValueByPath(obj: any, path: string | StorageKey): any;
|
|
4
4
|
export declare function setValueByPath(obj: any, path: string | StorageKey, value: any): any;
|
|
5
|
-
//# sourceMappingURL=path.utils.d.ts.map
|
|
@@ -25,7 +25,6 @@ export declare abstract class StorageCore<T extends Record<string, any>> impleme
|
|
|
25
25
|
private statusSubscribers;
|
|
26
26
|
protected subscribers: Map<StorageKeyType, Set<(value: any) => void>>;
|
|
27
27
|
protected _stateCache: T;
|
|
28
|
-
protected keyVersions: Map<string, number>;
|
|
29
28
|
constructor(coreConfig: BaseStorageConfig<T>, eventEmitter?: IEventEmitter | undefined, logger?: ILogger | undefined);
|
|
30
29
|
get initStatus(): StorageInitStatus;
|
|
31
30
|
waitForReady(): Promise<this>;
|
|
@@ -43,6 +42,12 @@ export declare abstract class StorageCore<T extends Record<string, any>> impleme
|
|
|
43
42
|
subscribe<R>(pathSelector: PathSelector<T, R>, callback: (value: R) => void): VoidFunction;
|
|
44
43
|
protected abstract subscribeByKey(key: string, callback: (value: any) => void): VoidFunction;
|
|
45
44
|
protected abstract subscribeBySelector<R>(pathSelector: PathSelector<T, R>, callback: (value: R) => void): VoidFunction;
|
|
45
|
+
/**
|
|
46
|
+
* Хук изменения ключа. По умолчанию no-op.
|
|
47
|
+
* Async-хранилища переопределяют для защиты от race condition в subscribeByKey
|
|
48
|
+
* (см. AsyncBaseStorage). Sync версии не нужен — get() синхронный.
|
|
49
|
+
*/
|
|
50
|
+
protected trackKeyVersion(_keyStr: string): void;
|
|
46
51
|
protected notifySubscribers(key: StorageKeyType, value: any): void;
|
|
47
52
|
initialize(): Promise<this>;
|
|
48
53
|
/**
|
|
@@ -58,4 +63,3 @@ export declare abstract class StorageCore<T extends Record<string, any>> impleme
|
|
|
58
63
|
protected abstract performCleanup(): Promise<void>;
|
|
59
64
|
protected emitEvent(event: StorageEvent): Promise<void>;
|
|
60
65
|
}
|
|
61
|
-
//# sourceMappingURL=storage-core.d.ts.map
|
|
@@ -28,7 +28,6 @@ import { StorageEvents, StorageStatus } from "../storage.interface.js";
|
|
|
28
28
|
statusSubscribers = new Set();
|
|
29
29
|
subscribers = new Map();
|
|
30
30
|
_stateCache = {};
|
|
31
|
-
keyVersions = new Map();
|
|
32
31
|
constructor(coreConfig, eventEmitter, logger){
|
|
33
32
|
this.coreConfig = coreConfig;
|
|
34
33
|
this.eventEmitter = eventEmitter;
|
|
@@ -119,10 +118,14 @@ import { StorageEvents, StorageStatus } from "../storage.interface.js";
|
|
|
119
118
|
}
|
|
120
119
|
return this.subscribeBySelector(keyOrSelector, callback);
|
|
121
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Хук изменения ключа. По умолчанию no-op.
|
|
123
|
+
* Async-хранилища переопределяют для защиты от race condition в subscribeByKey
|
|
124
|
+
* (см. AsyncBaseStorage). Sync версии не нужен — get() синхронный.
|
|
125
|
+
*/ trackKeyVersion(_keyStr) {}
|
|
122
126
|
notifySubscribers(key, value) {
|
|
123
127
|
const keyStr = key.toString();
|
|
124
|
-
|
|
125
|
-
this.keyVersions.set(keyStr, (this.keyVersions.get(keyStr) ?? 0) + 1);
|
|
128
|
+
this.trackKeyVersion(keyStr);
|
|
126
129
|
const exactSubscribers = this.subscribers.get(keyStr);
|
|
127
130
|
if (exactSubscribers?.size) {
|
|
128
131
|
const subscribersCopy = new Set(exactSubscribers);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core/storage/adapters/storage-core.js","sources":["../../../../src/core/storage/adapters/storage-core.ts"],"sourcesContent":["import { SingletonKeyGenerator, SingletonManager } from '../modules/singleton/singleton.util'\nimport { BaseStorageConfig, IEventEmitter, ILogger, IStorageBase, StorageEvent, StorageEvents, StorageInitStatus, StorageStatus, StorageType } from '../storage.interface'\nimport { StorageKeyType } from '../utils/storage-key'\n\nexport type PathSelector<T, R> = (state: T) => R\n\n/**\n * Общая константа для глобальной подписки.\n * Используется в StorageCore и наследниках.\n */\nexport const GLOBAL_SUBSCRIPTION_KEY = '*'\n\n/**\n * Абстрактный базовый класс с общей инфраструктурой хранилища.\n *\n * Содержит: status management, subscriptions, lifecycle wrappers,\n * state cache, event emission, singleton cleanup.\n *\n * Не содержит: middleware, plugin executor, do* методы, публичные CRUD-операции.\n */\nexport abstract class StorageCore<T extends Record<string, any>> implements IStorageBase<T> {\n name: string\n abstract readonly type: StorageType\n\n private _initStatus: StorageInitStatus = { status: StorageStatus.IDLE }\n private _isDestroyed = false\n private statusSubscribers = new Set<(status: StorageInitStatus) => void>()\n\n protected subscribers = new Map<StorageKeyType, Set<(value: any) => void>>()\n protected _stateCache: T = {} as T\n protected keyVersions = new Map<string, number>()\n\n constructor(\n protected readonly coreConfig: BaseStorageConfig<T>,\n protected readonly eventEmitter?: IEventEmitter,\n protected readonly logger?: ILogger,\n ) {\n this.name = coreConfig.name\n }\n\n // ─── Status Management ──────────────────────────────────────────────────────\n\n get initStatus(): StorageInitStatus {\n return { ...this._initStatus }\n }\n\n async waitForReady(): Promise<this> {\n if (this._initStatus.status === StorageStatus.READY) return this\n if (this._initStatus.status === StorageStatus.ERROR) {\n throw this._initStatus.error || new Error('Storage initialization failed')\n }\n\n return new Promise((resolve, reject) => {\n const unsubscribe = this.onStatusChange((status) => {\n if (status.status === StorageStatus.READY) {\n unsubscribe()\n resolve(this)\n } else if (status.status === StorageStatus.ERROR) {\n unsubscribe()\n reject(status.error || new Error('Storage initialization failed'))\n }\n })\n })\n }\n\n onStatusChange(callback: (status: StorageInitStatus) => void): VoidFunction {\n this.statusSubscribers.add(callback)\n callback(this.initStatus)\n\n return () => {\n this.statusSubscribers.delete(callback)\n }\n }\n\n protected updateInitStatus(update: Partial<StorageInitStatus>): void {\n const previousStatus = this._initStatus.status\n\n this._initStatus = { ...this._initStatus, ...update }\n\n if (previousStatus !== this._initStatus.status) {\n this.logger?.debug(`Storage \"${this.name}\" status changed: ${previousStatus} -> ${this._initStatus.status}`)\n }\n\n const statusCopy = this.initStatus\n this.statusSubscribers.forEach((callback) => {\n try {\n callback(statusCopy)\n } catch (error) {\n this.logger?.error('Error in status change callback', { error })\n }\n })\n }\n\n protected ensureReady(): void {\n if (this._isDestroyed) {\n throw new Error(`Storage \"${this.name}\" has been destroyed`)\n }\n if (this._initStatus.status !== StorageStatus.READY) {\n throw new Error(`Storage \"${this.name}\" is not ready. Current status: ${this._initStatus.status}`)\n }\n }\n\n // ─── State Cache ────────────────────────────────────────────────────────────\n\n public getStateSync(): T {\n return this._stateCache\n }\n\n // ─── Subscriptions ──────────────────────────────────────────────────────────\n\n public subscribeToAll(callback: (event: { type: string; key?: StorageKeyType[] | StorageKeyType; value?: any; changedPaths?: string[] }) => void): VoidFunction {\n if (!this.subscribers.has(GLOBAL_SUBSCRIPTION_KEY)) {\n this.subscribers.set(GLOBAL_SUBSCRIPTION_KEY, new Set())\n }\n\n this.subscribers.get(GLOBAL_SUBSCRIPTION_KEY)!.add(callback)\n\n return () => {\n const subscribers = this.subscribers.get(GLOBAL_SUBSCRIPTION_KEY)\n if (subscribers) {\n subscribers.delete(callback)\n if (subscribers.size === 0) {\n this.subscribers.delete(GLOBAL_SUBSCRIPTION_KEY)\n }\n }\n }\n }\n\n public subscribe(key: string, callback: (value: any) => void): VoidFunction\n public subscribe<R>(pathSelector: PathSelector<T, R>, callback: (value: R) => void): VoidFunction\n public subscribe<R>(keyOrSelector: string | PathSelector<T, R>, callback: (value: any) => void): VoidFunction {\n if (typeof keyOrSelector === 'string') {\n return this.subscribeByKey(keyOrSelector, callback)\n }\n return this.subscribeBySelector(keyOrSelector, callback)\n }\n\n protected abstract subscribeByKey(key: string, callback: (value: any) => void): VoidFunction\n protected abstract subscribeBySelector<R>(pathSelector: PathSelector<T, R>, callback: (value: R) => void): VoidFunction\n\n protected notifySubscribers(key: StorageKeyType, value: any): void {\n const keyStr = key.toString()\n\n // Инкрементируем версию ключа — используется для защиты от race condition в subscribeByKey (async)\n this.keyVersions.set(keyStr, (this.keyVersions.get(keyStr) ?? 0) + 1)\n\n const exactSubscribers = this.subscribers.get(keyStr)\n if (exactSubscribers?.size) {\n const subscribersCopy = new Set(exactSubscribers)\n subscribersCopy.forEach((callback) => {\n try {\n callback(value)\n } catch (error) {\n this.logger?.error('Ошибка в подписчике на колбэк', { key: keyStr, error })\n }\n })\n }\n }\n\n // ─── Lifecycle ──────────────────────────────────────────────────────────────\n\n public async initialize(): Promise<this> {\n if (this._initStatus.status === StorageStatus.READY) return this\n if (this._initStatus.status === StorageStatus.LOADING) return this.waitForReady()\n\n // Allow re-initialization after destroy\n this._isDestroyed = false\n\n this.updateInitStatus({ status: StorageStatus.LOADING, error: undefined })\n\n try {\n await this.performInitialize()\n this.updateInitStatus({ status: StorageStatus.READY, error: undefined })\n return this\n } catch (error) {\n this.updateInitStatus({\n status: StorageStatus.ERROR,\n error: error instanceof Error ? error : new Error(String(error)),\n })\n throw error\n }\n }\n\n /**\n * Subclass-specific initialization.\n * Called inside initialize() wrapper after status is set to LOADING.\n */\n protected abstract performInitialize(): Promise<void>\n\n public async destroy(): Promise<void> {\n if (this._isDestroyed) return\n this._isDestroyed = true\n\n try {\n if (this._initStatus.status === StorageStatus.LOADING) {\n try {\n await this.waitForReady()\n } catch {\n // Инициализация упала — продолжаем destroy\n }\n }\n\n if (this._initStatus.status === StorageStatus.READY) {\n await this.performCleanup()\n }\n\n this.statusSubscribers.clear()\n\n if (this.coreConfig.singleton?.enabled) {\n const key = SingletonKeyGenerator.generate(this.coreConfig as any, this.type)\n SingletonManager.remove(key)\n }\n\n this._stateCache = {} as T\n this.updateInitStatus({ status: StorageStatus.IDLE })\n\n await this.emitEvent({ type: StorageEvents.STORAGE_DESTROY })\n } catch (error) {\n this.logger?.error('Error destroying storage', { error })\n throw error\n }\n }\n\n /**\n * Subclass-specific cleanup during destroy.\n * Should clear storage data, call doDestroy, cleanup middlewares.\n */\n protected abstract performCleanup(): Promise<void>\n\n // ─── Events ─────────────────────────────────────────────────────────────────\n\n protected async emitEvent(event: StorageEvent): Promise<void> {\n try {\n await this.eventEmitter?.emit({\n ...event,\n metadata: {\n ...(event.metadata || {}),\n timestamp: Date.now(),\n storageName: this.name,\n },\n })\n } catch (error) {\n this.logger?.error('Error emitting event', { event, error })\n }\n }\n}\n"],"names":["SingletonKeyGenerator","SingletonManager","StorageEvents","StorageStatus","GLOBAL_SUBSCRIPTION_KEY","StorageCore","Set","Map","coreConfig","eventEmitter","logger","Error","Promise","resolve","reject","unsubscribe","status","callback","update","previousStatus","statusCopy","error","subscribers","keyOrSelector","key","value","keyStr","exactSubscribers","subscribersCopy","undefined","String","event","Date"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"core/storage/adapters/storage-core.js","sources":["../../../../src/core/storage/adapters/storage-core.ts"],"sourcesContent":["import { SingletonKeyGenerator, SingletonManager } from '../modules/singleton/singleton.util'\nimport { BaseStorageConfig, IEventEmitter, ILogger, IStorageBase, StorageEvent, StorageEvents, StorageInitStatus, StorageStatus, StorageType } from '../storage.interface'\nimport { StorageKeyType } from '../utils/storage-key'\n\nexport type PathSelector<T, R> = (state: T) => R\n\n/**\n * Общая константа для глобальной подписки.\n * Используется в StorageCore и наследниках.\n */\nexport const GLOBAL_SUBSCRIPTION_KEY = '*'\n\n/**\n * Абстрактный базовый класс с общей инфраструктурой хранилища.\n *\n * Содержит: status management, subscriptions, lifecycle wrappers,\n * state cache, event emission, singleton cleanup.\n *\n * Не содержит: middleware, plugin executor, do* методы, публичные CRUD-операции.\n */\nexport abstract class StorageCore<T extends Record<string, any>> implements IStorageBase<T> {\n name: string\n abstract readonly type: StorageType\n\n private _initStatus: StorageInitStatus = { status: StorageStatus.IDLE }\n private _isDestroyed = false\n private statusSubscribers = new Set<(status: StorageInitStatus) => void>()\n\n protected subscribers = new Map<StorageKeyType, Set<(value: any) => void>>()\n protected _stateCache: T = {} as T\n\n constructor(\n protected readonly coreConfig: BaseStorageConfig<T>,\n protected readonly eventEmitter?: IEventEmitter,\n protected readonly logger?: ILogger,\n ) {\n this.name = coreConfig.name\n }\n\n // ─── Status Management ──────────────────────────────────────────────────────\n\n get initStatus(): StorageInitStatus {\n return { ...this._initStatus }\n }\n\n async waitForReady(): Promise<this> {\n if (this._initStatus.status === StorageStatus.READY) return this\n if (this._initStatus.status === StorageStatus.ERROR) {\n throw this._initStatus.error || new Error('Storage initialization failed')\n }\n\n return new Promise((resolve, reject) => {\n const unsubscribe = this.onStatusChange((status) => {\n if (status.status === StorageStatus.READY) {\n unsubscribe()\n resolve(this)\n } else if (status.status === StorageStatus.ERROR) {\n unsubscribe()\n reject(status.error || new Error('Storage initialization failed'))\n }\n })\n })\n }\n\n onStatusChange(callback: (status: StorageInitStatus) => void): VoidFunction {\n this.statusSubscribers.add(callback)\n callback(this.initStatus)\n\n return () => {\n this.statusSubscribers.delete(callback)\n }\n }\n\n protected updateInitStatus(update: Partial<StorageInitStatus>): void {\n const previousStatus = this._initStatus.status\n\n this._initStatus = { ...this._initStatus, ...update }\n\n if (previousStatus !== this._initStatus.status) {\n this.logger?.debug(`Storage \"${this.name}\" status changed: ${previousStatus} -> ${this._initStatus.status}`)\n }\n\n const statusCopy = this.initStatus\n this.statusSubscribers.forEach((callback) => {\n try {\n callback(statusCopy)\n } catch (error) {\n this.logger?.error('Error in status change callback', { error })\n }\n })\n }\n\n protected ensureReady(): void {\n if (this._isDestroyed) {\n throw new Error(`Storage \"${this.name}\" has been destroyed`)\n }\n if (this._initStatus.status !== StorageStatus.READY) {\n throw new Error(`Storage \"${this.name}\" is not ready. Current status: ${this._initStatus.status}`)\n }\n }\n\n // ─── State Cache ────────────────────────────────────────────────────────────\n\n public getStateSync(): T {\n return this._stateCache\n }\n\n // ─── Subscriptions ──────────────────────────────────────────────────────────\n\n public subscribeToAll(callback: (event: { type: string; key?: StorageKeyType[] | StorageKeyType; value?: any; changedPaths?: string[] }) => void): VoidFunction {\n if (!this.subscribers.has(GLOBAL_SUBSCRIPTION_KEY)) {\n this.subscribers.set(GLOBAL_SUBSCRIPTION_KEY, new Set())\n }\n\n this.subscribers.get(GLOBAL_SUBSCRIPTION_KEY)!.add(callback)\n\n return () => {\n const subscribers = this.subscribers.get(GLOBAL_SUBSCRIPTION_KEY)\n if (subscribers) {\n subscribers.delete(callback)\n if (subscribers.size === 0) {\n this.subscribers.delete(GLOBAL_SUBSCRIPTION_KEY)\n }\n }\n }\n }\n\n public subscribe(key: string, callback: (value: any) => void): VoidFunction\n public subscribe<R>(pathSelector: PathSelector<T, R>, callback: (value: R) => void): VoidFunction\n public subscribe<R>(keyOrSelector: string | PathSelector<T, R>, callback: (value: any) => void): VoidFunction {\n if (typeof keyOrSelector === 'string') {\n return this.subscribeByKey(keyOrSelector, callback)\n }\n return this.subscribeBySelector(keyOrSelector, callback)\n }\n\n protected abstract subscribeByKey(key: string, callback: (value: any) => void): VoidFunction\n protected abstract subscribeBySelector<R>(pathSelector: PathSelector<T, R>, callback: (value: R) => void): VoidFunction\n\n /**\n * Хук изменения ключа. По умолчанию no-op.\n * Async-хранилища переопределяют для защиты от race condition в subscribeByKey\n * (см. AsyncBaseStorage). Sync версии не нужен — get() синхронный.\n */\n protected trackKeyVersion(_keyStr: string): void {}\n\n protected notifySubscribers(key: StorageKeyType, value: any): void {\n const keyStr = key.toString()\n\n this.trackKeyVersion(keyStr)\n\n const exactSubscribers = this.subscribers.get(keyStr)\n if (exactSubscribers?.size) {\n const subscribersCopy = new Set(exactSubscribers)\n subscribersCopy.forEach((callback) => {\n try {\n callback(value)\n } catch (error) {\n this.logger?.error('Ошибка в подписчике на колбэк', { key: keyStr, error })\n }\n })\n }\n }\n\n // ─── Lifecycle ──────────────────────────────────────────────────────────────\n\n public async initialize(): Promise<this> {\n if (this._initStatus.status === StorageStatus.READY) return this\n if (this._initStatus.status === StorageStatus.LOADING) return this.waitForReady()\n\n // Allow re-initialization after destroy\n this._isDestroyed = false\n\n this.updateInitStatus({ status: StorageStatus.LOADING, error: undefined })\n\n try {\n await this.performInitialize()\n this.updateInitStatus({ status: StorageStatus.READY, error: undefined })\n return this\n } catch (error) {\n this.updateInitStatus({\n status: StorageStatus.ERROR,\n error: error instanceof Error ? error : new Error(String(error)),\n })\n throw error\n }\n }\n\n /**\n * Subclass-specific initialization.\n * Called inside initialize() wrapper after status is set to LOADING.\n */\n protected abstract performInitialize(): Promise<void>\n\n public async destroy(): Promise<void> {\n if (this._isDestroyed) return\n this._isDestroyed = true\n\n try {\n if (this._initStatus.status === StorageStatus.LOADING) {\n try {\n await this.waitForReady()\n } catch {\n // Инициализация упала — продолжаем destroy\n }\n }\n\n if (this._initStatus.status === StorageStatus.READY) {\n await this.performCleanup()\n }\n\n this.statusSubscribers.clear()\n\n if (this.coreConfig.singleton?.enabled) {\n const key = SingletonKeyGenerator.generate(this.coreConfig as any, this.type)\n SingletonManager.remove(key)\n }\n\n this._stateCache = {} as T\n this.updateInitStatus({ status: StorageStatus.IDLE })\n\n await this.emitEvent({ type: StorageEvents.STORAGE_DESTROY })\n } catch (error) {\n this.logger?.error('Error destroying storage', { error })\n throw error\n }\n }\n\n /**\n * Subclass-specific cleanup during destroy.\n * Should clear storage data, call doDestroy, cleanup middlewares.\n */\n protected abstract performCleanup(): Promise<void>\n\n // ─── Events ─────────────────────────────────────────────────────────────────\n\n protected async emitEvent(event: StorageEvent): Promise<void> {\n try {\n await this.eventEmitter?.emit({\n ...event,\n metadata: {\n ...(event.metadata || {}),\n timestamp: Date.now(),\n storageName: this.name,\n },\n })\n } catch (error) {\n this.logger?.error('Error emitting event', { event, error })\n }\n }\n}\n"],"names":["SingletonKeyGenerator","SingletonManager","StorageEvents","StorageStatus","GLOBAL_SUBSCRIPTION_KEY","StorageCore","Set","Map","coreConfig","eventEmitter","logger","Error","Promise","resolve","reject","unsubscribe","status","callback","update","previousStatus","statusCopy","error","subscribers","keyOrSelector","_keyStr","key","value","keyStr","exactSubscribers","subscribersCopy","undefined","String","event","Date"],"mappings":";;;;;AAA6F;AAC6E;AAK1K;;;CAGC,GACM,MAAMI,uBAAuBA,GAAG,IAAG;AAE1C;;;;;;;CAOC,GACM,MAAeC,WAAWA;;;;IAC/B,KAAY;IAGJ,cAAiC;QAAE,QAAQF,kBAAkB;IAAC,EAAC;IAC/D,eAAe,MAAK;IACpB,oBAAoB,IAAIG,MAA0C;IAEhE,cAAc,IAAIC,MAAgD;IAClE,cAAiB,CAAC,EAAM;IAElC,YACqBC,UAAgC,EAChCC,YAA4B,EAC5BC,MAAgB,CACnC;aAHmBF,aAAAA;aACAC,eAAAA;aACAC,SAAAA;QAEnB,IAAI,CAAC,IAAI,GAAGF,WAAW,IAAI;IAC7B;IAEA,+EAA+E;IAE/E,IAAI,aAAgC;QAClC,OAAO;YAAE,GAAG,IAAI,CAAC,WAAW;QAAC;IAC/B;IAEA,MAAM,eAA8B;QAClC,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,KAAKL,mBAAmB,EAAE,OAAO,IAAI;QAChE,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,KAAKA,mBAAmB,EAAE;YACnD,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,IAAI,IAAIQ,MAAM;QAC5C;QAEA,OAAO,IAAIC,QAAQ,CAACC,SAASC;YAC3B,MAAMC,cAAc,IAAI,CAAC,cAAc,CAAC,CAACC;gBACvC,IAAIA,OAAO,MAAM,KAAKb,mBAAmB,EAAE;oBACzCY;oBACAF,QAAQ,IAAI;gBACd,OAAO,IAAIG,OAAO,MAAM,KAAKb,mBAAmB,EAAE;oBAChDY;oBACAD,OAAOE,OAAO,KAAK,IAAI,IAAIL,MAAM;gBACnC;YACF;QACF;IACF;IAEA,eAAeM,QAA6C,EAAgB;QAC1E,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAACA;QAC3BA,SAAS,IAAI,CAAC,UAAU;QAExB,OAAO;YACL,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAACA;QAChC;IACF;IAEU,iBAAiBC,MAAkC,EAAQ;QACnE,MAAMC,iBAAiB,IAAI,CAAC,WAAW,CAAC,MAAM;QAE9C,IAAI,CAAC,WAAW,GAAG;YAAE,GAAG,IAAI,CAAC,WAAW;YAAE,GAAGD,MAAM;QAAC;QAEpD,IAAIC,mBAAmB,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE;YAC9C,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAEA,eAAe,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE;QAC7G;QAEA,MAAMC,aAAa,IAAI,CAAC,UAAU;QAClC,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAACH;YAC9B,IAAI;gBACFA,SAASG;YACX,EAAE,OAAOC,OAAO;gBACd,IAAI,CAAC,MAAM,EAAE,MAAM,mCAAmC;oBAAEA;gBAAM;YAChE;QACF;IACF;IAEU,cAAoB;QAC5B,IAAI,IAAI,CAAC,YAAY,EAAE;YACrB,MAAM,IAAIV,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC;QAC7D;QACA,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,KAAKR,mBAAmB,EAAE;YACnD,MAAM,IAAIQ,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,gCAAgC,EAAE,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE;QACnG;IACF;IAEA,+EAA+E;IAExE,eAAkB;QACvB,OAAO,IAAI,CAAC,WAAW;IACzB;IAEA,+EAA+E;IAExE,eAAeM,QAA0H,EAAgB;QAC9J,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAACb,uBAAuBA,GAAG;YAClD,IAAI,CAAC,WAAW,CAAC,GAAG,CAACA,uBAAuBA,EAAE,IAAIE;QACpD;QAEA,IAAI,CAAC,WAAW,CAAC,GAAG,CAACF,uBAAuBA,EAAG,GAAG,CAACa;QAEnD,OAAO;YACL,MAAMK,cAAc,IAAI,CAAC,WAAW,CAAC,GAAG,CAAClB,uBAAuBA;YAChE,IAAIkB,aAAa;gBACfA,YAAY,MAAM,CAACL;gBACnB,IAAIK,YAAY,IAAI,KAAK,GAAG;oBAC1B,IAAI,CAAC,WAAW,CAAC,MAAM,CAAClB,uBAAuBA;gBACjD;YACF;QACF;IACF;IAIO,UAAamB,aAA0C,EAAEN,QAA8B,EAAgB;QAC5G,IAAI,OAAOM,kBAAkB,UAAU;YACrC,OAAO,IAAI,CAAC,cAAc,CAACA,eAAeN;QAC5C;QACA,OAAO,IAAI,CAAC,mBAAmB,CAACM,eAAeN;IACjD;IAKA;;;;GAIC,GACS,gBAAgBO,OAAe,EAAQ,CAAC;IAExC,kBAAkBC,GAAmB,EAAEC,KAAU,EAAQ;QACjE,MAAMC,SAASF,IAAI,QAAQ;QAE3B,IAAI,CAAC,eAAe,CAACE;QAErB,MAAMC,mBAAmB,IAAI,CAAC,WAAW,CAAC,GAAG,CAACD;QAC9C,IAAIC,kBAAkB,MAAM;YAC1B,MAAMC,kBAAkB,IAAIvB,IAAIsB;YAChCC,gBAAgB,OAAO,CAAC,CAACZ;gBACvB,IAAI;oBACFA,SAASS;gBACX,EAAE,OAAOL,OAAO;oBACd,IAAI,CAAC,MAAM,EAAE,MAAM,iCAAiC;wBAAE,KAAKM;wBAAQN;oBAAM;gBAC3E;YACF;QACF;IACF;IAEA,+EAA+E;IAE/E,MAAa,aAA4B;QACvC,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,KAAKlB,mBAAmB,EAAE,OAAO,IAAI;QAChE,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,KAAKA,qBAAqB,EAAE,OAAO,IAAI,CAAC,YAAY;QAE/E,wCAAwC;QACxC,IAAI,CAAC,YAAY,GAAG;QAEpB,IAAI,CAAC,gBAAgB,CAAC;YAAE,QAAQA,qBAAqB;YAAE,OAAO2B;QAAU;QAExE,IAAI;YACF,MAAM,IAAI,CAAC,iBAAiB;YAC5B,IAAI,CAAC,gBAAgB,CAAC;gBAAE,QAAQ3B,mBAAmB;gBAAE,OAAO2B;YAAU;YACtE,OAAO,IAAI;QACb,EAAE,OAAOT,OAAO;YACd,IAAI,CAAC,gBAAgB,CAAC;gBACpB,QAAQlB,mBAAmB;gBAC3B,OAAOkB,iBAAiBV,QAAQU,QAAQ,IAAIV,MAAMoB,OAAOV;YAC3D;YACA,MAAMA;QACR;IACF;IAQA,MAAa,UAAyB;QACpC,IAAI,IAAI,CAAC,YAAY,EAAE;QACvB,IAAI,CAAC,YAAY,GAAG;QAEpB,IAAI;YACF,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,KAAKlB,qBAAqB,EAAE;gBACrD,IAAI;oBACF,MAAM,IAAI,CAAC,YAAY;gBACzB,EAAE,OAAM;gBACN,2CAA2C;gBAC7C;YACF;YAEA,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,KAAKA,mBAAmB,EAAE;gBACnD,MAAM,IAAI,CAAC,cAAc;YAC3B;YAEA,IAAI,CAAC,iBAAiB,CAAC,KAAK;YAE5B,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,SAAS;gBACtC,MAAMsB,MAAMzB,8BAA8B,CAAC,IAAI,CAAC,UAAU,EAAS,IAAI,CAAC,IAAI;gBAC5EC,uBAAuB,CAACwB;YAC1B;YAEA,IAAI,CAAC,WAAW,GAAG,CAAC;YACpB,IAAI,CAAC,gBAAgB,CAAC;gBAAE,QAAQtB,kBAAkB;YAAC;YAEnD,MAAM,IAAI,CAAC,SAAS,CAAC;gBAAE,MAAMD,6BAA6B;YAAC;QAC7D,EAAE,OAAOmB,OAAO;YACd,IAAI,CAAC,MAAM,EAAE,MAAM,4BAA4B;gBAAEA;YAAM;YACvD,MAAMA;QACR;IACF;IAQA,+EAA+E;IAE/E,MAAgB,UAAUW,KAAmB,EAAiB;QAC5D,IAAI;YACF,MAAM,IAAI,CAAC,YAAY,EAAE,KAAK;gBAC5B,GAAGA,KAAK;gBACR,UAAU;oBACR,GAAIA,MAAM,QAAQ,IAAI,CAAC,CAAC;oBACxB,WAAWC,KAAK,GAAG;oBACnB,aAAa,IAAI,CAAC,IAAI;gBACxB;YACF;QACF,EAAE,OAAOZ,OAAO;YACd,IAAI,CAAC,MAAM,EAAE,MAAM,wBAAwB;gBAAEW;gBAAOX;YAAM;QAC5D;IACF;AACF"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { ISyncPluginExecutor } from '../modules/plugin/plugin.interface';
|
|
2
1
|
import { IEventEmitter, ILogger, ISyncStorage, StorageType, SyncDefaultMiddlewares, SyncStorageConfig } from '../storage.interface';
|
|
3
2
|
import { StorageKeyType } from '../utils/storage-key';
|
|
4
3
|
import { PathSelector, StorageCore } from './storage-core';
|
|
@@ -11,12 +10,11 @@ import { PathSelector, StorageCore } from './storage-core';
|
|
|
11
10
|
*/
|
|
12
11
|
export declare abstract class SyncBaseStorage<T extends Record<string, any>> extends StorageCore<T> implements ISyncStorage<T> {
|
|
13
12
|
protected readonly config: SyncStorageConfig<T>;
|
|
14
|
-
protected readonly pluginExecutor?: ISyncPluginExecutor | undefined;
|
|
15
13
|
abstract readonly type: StorageType;
|
|
16
14
|
private middlewareModule;
|
|
17
15
|
private initializedMiddlewares;
|
|
18
16
|
private selectorPathCache;
|
|
19
|
-
constructor(config: SyncStorageConfig<T>,
|
|
17
|
+
constructor(config: SyncStorageConfig<T>, eventEmitter?: IEventEmitter, logger?: ILogger);
|
|
20
18
|
protected abstract doGet(key: StorageKeyType): any;
|
|
21
19
|
protected abstract doSet(key: StorageKeyType, value: any): void;
|
|
22
20
|
protected abstract doUpdate(updates: Array<{
|
|
@@ -32,10 +30,21 @@ export declare abstract class SyncBaseStorage<T extends Record<string, any>> ext
|
|
|
32
30
|
/** Lifecycle — всегда async */
|
|
33
31
|
protected abstract doDestroy(): Promise<void>;
|
|
34
32
|
protected performInitialize(): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Дефолт для `config.clearOnDestroy`, если он не задан.
|
|
35
|
+
* Memory: `true` (эфемерное). LocalStorage переопределяет на `false` (персистентное).
|
|
36
|
+
*/
|
|
37
|
+
protected get clearOnDestroyDefault(): boolean;
|
|
35
38
|
protected performCleanup(): Promise<void>;
|
|
36
39
|
protected initializeMiddlewares(): void;
|
|
37
40
|
protected getDefaultMiddleware(): SyncDefaultMiddlewares;
|
|
38
41
|
protected initializeWithMiddlewares(): void;
|
|
42
|
+
/** Читает сохранённую версию схемы. По умолчанию `undefined` (эфемерные хранилища). */
|
|
43
|
+
protected readPersistedVersion(): number | undefined;
|
|
44
|
+
/** Сохраняет версию схемы рядом с данными. По умолчанию no-op (эфемерные хранилища). */
|
|
45
|
+
protected writePersistedVersion(_version: number): void;
|
|
46
|
+
/** Удаляет сохранённую версию схемы (вызывается при destroy с `clearOnDestroy`). */
|
|
47
|
+
protected clearPersistedVersion(): void;
|
|
39
48
|
private getRawState;
|
|
40
49
|
get<R>(key: StorageKeyType): R | undefined;
|
|
41
50
|
set<R>(key: StorageKeyType, value: R): void;
|
|
@@ -43,6 +52,14 @@ export declare abstract class SyncBaseStorage<T extends Record<string, any>> ext
|
|
|
43
52
|
remove(key: StorageKeyType): void;
|
|
44
53
|
clear(): void;
|
|
45
54
|
reset(): void;
|
|
55
|
+
/**
|
|
56
|
+
* SSR-гидрация: заменяет всё состояние переданным снапшотом. Намеренно НЕ требует
|
|
57
|
+
* `ready()` — типичный сценарий вызвать её до `initialize()`, чтобы инициализация
|
|
58
|
+
* не перезатёрла серверное состояние `initialState`-ом (см. `initializeWithMiddlewares`).
|
|
59
|
+
*/
|
|
60
|
+
hydrate(state: T): void;
|
|
61
|
+
/** Уведомляет подписчиков о замене состояния гидрацией (no-op до initialize/без подписок). */
|
|
62
|
+
private notifyHydration;
|
|
46
63
|
keys(): string[];
|
|
47
64
|
has(key: StorageKeyType): boolean;
|
|
48
65
|
getState(): T;
|
|
@@ -53,4 +70,3 @@ export declare abstract class SyncBaseStorage<T extends Record<string, any>> ext
|
|
|
53
70
|
protected subscribeByKey(key: string, callback: (value: any) => void): VoidFunction;
|
|
54
71
|
protected subscribeBySelector<R>(pathSelector: PathSelector<T, R>, callback: (value: R) => void): VoidFunction;
|
|
55
72
|
}
|
|
56
|
-
//# sourceMappingURL=sync-base-storage.service.d.ts.map
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { syncBatchingMiddleware } from "../middlewares/sync-storage-batching.middleware.js";
|
|
2
|
+
import { syncLoggerMiddleware } from "../middlewares/sync-storage-logger.middleware.js";
|
|
2
3
|
import { syncShallowCompareMiddleware } from "../middlewares/sync-storage-shallow-compare.middleware.js";
|
|
3
4
|
import { StorageEvents } from "../storage.interface.js";
|
|
4
5
|
import { SyncMiddlewareModule, VALUE_NOT_CHANGED } from "../utils/middleware-module.js";
|
|
6
|
+
import { decideMigration } from "../utils/migration.util.js";
|
|
5
7
|
import { createDummyState, extractPath } from "../utils/path-selector.util.js";
|
|
6
8
|
import { createLazyClone, findChangedPaths, isEqual } from "../utils/state-diff.util.js";
|
|
7
9
|
import { getValueByPath } from "./path.utils.js";
|
|
@@ -22,6 +24,10 @@ import { GLOBAL_SUBSCRIPTION_KEY, StorageCore } from "./storage-core.js";
|
|
|
22
24
|
|
|
23
25
|
|
|
24
26
|
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
25
31
|
|
|
26
32
|
/**
|
|
27
33
|
* Базовый класс для синхронных хранилищ (Memory, LocalStorage).
|
|
@@ -31,12 +37,11 @@ import { GLOBAL_SUBSCRIPTION_KEY, StorageCore } from "./storage-core.js";
|
|
|
31
37
|
* subscribeByKey упрощён — нет race condition без async get.
|
|
32
38
|
*/ class SyncBaseStorage extends StorageCore {
|
|
33
39
|
config;
|
|
34
|
-
pluginExecutor;
|
|
35
40
|
middlewareModule;
|
|
36
41
|
initializedMiddlewares = null;
|
|
37
42
|
selectorPathCache = new WeakMap();
|
|
38
|
-
constructor(config,
|
|
39
|
-
super(config, eventEmitter, logger), this.config = config
|
|
43
|
+
constructor(config, eventEmitter, logger){
|
|
44
|
+
super(config, eventEmitter, logger), this.config = config;
|
|
40
45
|
this.middlewareModule = new SyncMiddlewareModule({
|
|
41
46
|
getState: ()=>this.getRawState(),
|
|
42
47
|
doGet: this.doGet.bind(this),
|
|
@@ -53,10 +58,18 @@ import { GLOBAL_SUBSCRIPTION_KEY, StorageCore } from "./storage-core.js";
|
|
|
53
58
|
await this.doInitialize();
|
|
54
59
|
this._stateCache = this.getRawState();
|
|
55
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Дефолт для `config.clearOnDestroy`, если он не задан.
|
|
63
|
+
* Memory: `true` (эфемерное). LocalStorage переопределяет на `false` (персистентное).
|
|
64
|
+
*/ get clearOnDestroyDefault() {
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
56
67
|
async performCleanup() {
|
|
57
68
|
// Обходим публичный clear() (избегая ensureReady после _isDestroyed = true)
|
|
58
|
-
this.
|
|
59
|
-
|
|
69
|
+
if (this.config.clearOnDestroy ?? this.clearOnDestroyDefault) {
|
|
70
|
+
this.doClear();
|
|
71
|
+
this.clearPersistedVersion();
|
|
72
|
+
}
|
|
60
73
|
await this.doDestroy();
|
|
61
74
|
if (this.initializedMiddlewares) {
|
|
62
75
|
this.initializedMiddlewares.forEach((m)=>m.cleanup?.());
|
|
@@ -73,18 +86,59 @@ import { GLOBAL_SUBSCRIPTION_KEY, StorageCore } from "./storage-core.js";
|
|
|
73
86
|
getDefaultMiddleware() {
|
|
74
87
|
return {
|
|
75
88
|
batching: (options = {})=>syncBatchingMiddleware(options),
|
|
76
|
-
shallowCompare: (options = {})=>syncShallowCompareMiddleware(options)
|
|
89
|
+
shallowCompare: (options = {})=>syncShallowCompareMiddleware(options),
|
|
90
|
+
logger: (options = {})=>syncLoggerMiddleware(options)
|
|
77
91
|
};
|
|
78
92
|
}
|
|
79
93
|
initializeWithMiddlewares() {
|
|
80
94
|
try {
|
|
81
95
|
const state = this.getRawState();
|
|
82
96
|
const hasExistingState = Object.keys(state).length > 0;
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
97
|
+
// Миграция выключена (version не задан) — прежнее поведение: засеять initialState на пустом.
|
|
98
|
+
if (this.config.version === undefined) {
|
|
99
|
+
if (!hasExistingState && this.config.initialState) {
|
|
100
|
+
this.middlewareModule.dispatch({
|
|
101
|
+
type: 'init',
|
|
102
|
+
value: this.config.initialState
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const decision = decideMigration({
|
|
108
|
+
hasExisting: hasExistingState,
|
|
109
|
+
existingState: state,
|
|
110
|
+
persistedVersion: this.readPersistedVersion(),
|
|
111
|
+
targetVersion: this.config.version,
|
|
112
|
+
migrate: this.config.migrate
|
|
113
|
+
});
|
|
114
|
+
switch(decision.kind){
|
|
115
|
+
case 'seed':
|
|
116
|
+
{
|
|
117
|
+
if (this.config.initialState) {
|
|
118
|
+
this.middlewareModule.dispatch({
|
|
119
|
+
type: 'init',
|
|
120
|
+
value: this.config.initialState
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
this.writePersistedVersion(this.config.version);
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
case 'migrate':
|
|
127
|
+
{
|
|
128
|
+
this.middlewareModule.dispatch({
|
|
129
|
+
type: 'reset',
|
|
130
|
+
value: decision.state
|
|
131
|
+
});
|
|
132
|
+
this.writePersistedVersion(this.config.version);
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
case 'bump':
|
|
136
|
+
{
|
|
137
|
+
this.writePersistedVersion(this.config.version);
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
case 'none':
|
|
141
|
+
break;
|
|
88
142
|
}
|
|
89
143
|
} catch (error) {
|
|
90
144
|
this.logger?.error('Ошибка инициализации хранилища', {
|
|
@@ -93,6 +147,12 @@ import { GLOBAL_SUBSCRIPTION_KEY, StorageCore } from "./storage-core.js";
|
|
|
93
147
|
throw error;
|
|
94
148
|
}
|
|
95
149
|
}
|
|
150
|
+
// ─── Persisted schema version (persist-migration) ───────────────────────────
|
|
151
|
+
/** Читает сохранённую версию схемы. По умолчанию `undefined` (эфемерные хранилища). */ readPersistedVersion() {
|
|
152
|
+
return undefined;
|
|
153
|
+
}
|
|
154
|
+
/** Сохраняет версию схемы рядом с данными. По умолчанию no-op (эфемерные хранилища). */ writePersistedVersion(_version) {}
|
|
155
|
+
/** Удаляет сохранённую версию схемы (вызывается при destroy с `clearOnDestroy`). */ clearPersistedVersion() {}
|
|
96
156
|
// ─── Internal state access ──────────────────────────────────────────────────
|
|
97
157
|
getRawState() {
|
|
98
158
|
try {
|
|
@@ -114,19 +174,12 @@ import { GLOBAL_SUBSCRIPTION_KEY, StorageCore } from "./storage-core.js";
|
|
|
114
174
|
timestamp: Date.now(),
|
|
115
175
|
key
|
|
116
176
|
};
|
|
117
|
-
const
|
|
177
|
+
const finalResult = this.middlewareModule.dispatch({
|
|
118
178
|
type: 'get',
|
|
119
179
|
key,
|
|
120
180
|
metadata
|
|
121
181
|
});
|
|
122
|
-
|
|
123
|
-
this.emitEvent({
|
|
124
|
-
type: StorageEvents.STORAGE_SELECT,
|
|
125
|
-
payload: {
|
|
126
|
-
key,
|
|
127
|
-
value: finalResult
|
|
128
|
-
}
|
|
129
|
-
});
|
|
182
|
+
// Чтения не эмитят событий — это горячий путь, а STORAGE_SELECT нигде не потребляется.
|
|
130
183
|
return finalResult;
|
|
131
184
|
} catch (error) {
|
|
132
185
|
this.logger?.error('Error getting value', {
|
|
@@ -144,15 +197,13 @@ import { GLOBAL_SUBSCRIPTION_KEY, StorageCore } from "./storage-core.js";
|
|
|
144
197
|
timestamp: Date.now(),
|
|
145
198
|
key
|
|
146
199
|
};
|
|
147
|
-
const
|
|
148
|
-
const middlewareResult = this.middlewareModule.dispatch({
|
|
200
|
+
const finalResult = this.middlewareModule.dispatch({
|
|
149
201
|
type: 'set',
|
|
150
202
|
key,
|
|
151
|
-
value
|
|
203
|
+
value,
|
|
152
204
|
metadata
|
|
153
205
|
});
|
|
154
|
-
if (
|
|
155
|
-
const finalResult = this.pluginExecutor?.executeAfterSet(key, middlewareResult, metadata) ?? middlewareResult;
|
|
206
|
+
if (finalResult === VALUE_NOT_CHANGED) return;
|
|
156
207
|
this._stateCache = this.getRawState();
|
|
157
208
|
const keyStr = key.toString();
|
|
158
209
|
const changedPaths = [
|
|
@@ -204,14 +255,9 @@ import { GLOBAL_SUBSCRIPTION_KEY, StorageCore } from "./storage-core.js";
|
|
|
204
255
|
changedTopLevelKeys.add(path.split('.')[0]);
|
|
205
256
|
}
|
|
206
257
|
const updates = Array.from(changedTopLevelKeys).map((key)=>{
|
|
207
|
-
const keyMetadata = {
|
|
208
|
-
...metadata,
|
|
209
|
-
key
|
|
210
|
-
};
|
|
211
|
-
const processedValue = this.pluginExecutor?.executeBeforeSet(newState[key], keyMetadata) ?? newState[key];
|
|
212
258
|
return {
|
|
213
259
|
key,
|
|
214
|
-
value:
|
|
260
|
+
value: newState[key]
|
|
215
261
|
};
|
|
216
262
|
});
|
|
217
263
|
const result = this.middlewareModule.dispatch({
|
|
@@ -302,15 +348,12 @@ import { GLOBAL_SUBSCRIPTION_KEY, StorageCore } from "./storage-core.js";
|
|
|
302
348
|
timestamp: Date.now(),
|
|
303
349
|
key
|
|
304
350
|
};
|
|
305
|
-
const preventDeletion = this.pluginExecutor?.executeBeforeDelete(key, metadata);
|
|
306
|
-
if (preventDeletion === false) return;
|
|
307
351
|
const middlewareResult = this.middlewareModule.dispatch({
|
|
308
352
|
type: 'delete',
|
|
309
353
|
key,
|
|
310
354
|
metadata
|
|
311
355
|
});
|
|
312
356
|
if (middlewareResult === false) return;
|
|
313
|
-
this.pluginExecutor?.executeAfterDelete(key, metadata);
|
|
314
357
|
this._stateCache = this.getRawState();
|
|
315
358
|
const keyStr = key.toString();
|
|
316
359
|
const changedPaths = [
|
|
@@ -344,7 +387,6 @@ import { GLOBAL_SUBSCRIPTION_KEY, StorageCore } from "./storage-core.js";
|
|
|
344
387
|
clear() {
|
|
345
388
|
this.ensureReady();
|
|
346
389
|
try {
|
|
347
|
-
this.pluginExecutor?.executeOnClear();
|
|
348
390
|
this.middlewareModule.dispatch({
|
|
349
391
|
type: 'clear'
|
|
350
392
|
});
|
|
@@ -385,6 +427,39 @@ import { GLOBAL_SUBSCRIPTION_KEY, StorageCore } from "./storage-core.js";
|
|
|
385
427
|
throw error;
|
|
386
428
|
}
|
|
387
429
|
}
|
|
430
|
+
/**
|
|
431
|
+
* SSR-гидрация: заменяет всё состояние переданным снапшотом. Намеренно НЕ требует
|
|
432
|
+
* `ready()` — типичный сценарий вызвать её до `initialize()`, чтобы инициализация
|
|
433
|
+
* не перезатёрла серверное состояние `initialState`-ом (см. `initializeWithMiddlewares`).
|
|
434
|
+
*/ hydrate(state) {
|
|
435
|
+
try {
|
|
436
|
+
this.doSet('', state);
|
|
437
|
+
this._stateCache = this.getRawState();
|
|
438
|
+
// Если включён persist-migration — фиксируем текущую версию: серверный снапшот
|
|
439
|
+
// уже в актуальной схеме, миграцию на нём запускать не нужно.
|
|
440
|
+
if (this.config.version !== undefined) {
|
|
441
|
+
this.writePersistedVersion(this.config.version);
|
|
442
|
+
}
|
|
443
|
+
this.notifyHydration(this._stateCache);
|
|
444
|
+
} catch (error) {
|
|
445
|
+
this.logger?.error('Error hydrating storage', {
|
|
446
|
+
error
|
|
447
|
+
});
|
|
448
|
+
throw error;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
/** Уведомляет подписчиков о замене состояния гидрацией (no-op до initialize/без подписок). */ notifyHydration(state) {
|
|
452
|
+
const changedPaths = Object.keys(state);
|
|
453
|
+
for (const key of changedPaths){
|
|
454
|
+
this.notifySubscribers(key, state[key]);
|
|
455
|
+
}
|
|
456
|
+
this.notifySubscribers(GLOBAL_SUBSCRIPTION_KEY, {
|
|
457
|
+
type: StorageEvents.STORAGE_UPDATE,
|
|
458
|
+
key: changedPaths,
|
|
459
|
+
value: state,
|
|
460
|
+
changedPaths
|
|
461
|
+
});
|
|
462
|
+
}
|
|
388
463
|
keys() {
|
|
389
464
|
this.ensureReady();
|
|
390
465
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core/storage/adapters/sync-base-storage.service.js","sources":["../../../../src/core/storage/adapters/sync-base-storage.service.ts"],"sourcesContent":["import { syncBatchingMiddleware } from '../middlewares/sync-storage-batching.middleware'\nimport { syncShallowCompareMiddleware } from '../middlewares/sync-storage-shallow-compare.middleware'\nimport { ISyncPluginExecutor } from '../modules/plugin/plugin.interface'\nimport { IEventEmitter, ILogger, ISyncStorage, StorageEvents, StorageType, SyncDefaultMiddlewares, SyncStorageConfig } from '../storage.interface'\nimport { SyncMiddleware, SyncMiddlewareModule, VALUE_NOT_CHANGED } from '../utils/middleware-module'\nimport { createDummyState, extractPath } from '../utils/path-selector.util'\nimport { createLazyClone, findChangedPaths, isEqual } from '../utils/state-diff.util'\nimport { StorageKeyType } from '../utils/storage-key'\nimport { getValueByPath } from './path.utils'\nimport { GLOBAL_SUBSCRIPTION_KEY, PathSelector, StorageCore } from './storage-core'\n\n/**\n * Базовый класс для синхронных хранилищ (Memory, LocalStorage).\n *\n * Все CRUD-операции выполняются синхронно.\n * Lifecycle (initialize, destroy) остаётся async.\n * subscribeByKey упрощён — нет race condition без async get.\n */\nexport abstract class SyncBaseStorage<T extends Record<string, any>> extends StorageCore<T> implements ISyncStorage<T> {\n abstract readonly type: StorageType\n\n private middlewareModule: SyncMiddlewareModule\n private initializedMiddlewares: SyncMiddleware[] | null = null\n private selectorPathCache = new WeakMap<PathSelector<any, any>, string>()\n\n constructor(\n protected readonly config: SyncStorageConfig<T>,\n protected readonly pluginExecutor?: ISyncPluginExecutor,\n eventEmitter?: IEventEmitter,\n logger?: ILogger,\n ) {\n super(config, eventEmitter, logger)\n this.middlewareModule = new SyncMiddlewareModule({\n getState: () => this.getRawState(),\n doGet: this.doGet.bind(this),\n doSet: this.doSet.bind(this),\n doUpdate: this.doUpdate.bind(this),\n doRemove: this.doRemove.bind(this),\n doClear: this.doClear.bind(this),\n doKeys: this.doKeys.bind(this),\n notifySubscribers: this.notifySubscribers.bind(this),\n })\n }\n\n // ─── Abstract sync do* methods ──────────────────────────────────────────────\n\n protected abstract doGet(key: StorageKeyType): any\n protected abstract doSet(key: StorageKeyType, value: any): void\n protected abstract doUpdate(updates: Array<{ key: StorageKeyType; value: any }>): void\n protected abstract doRemove(key: StorageKeyType): boolean\n protected abstract doClear(): void\n protected abstract doKeys(): string[]\n protected abstract doHas(key: StorageKeyType): boolean\n\n /** Lifecycle — всегда async */\n protected abstract doInitialize(): Promise<this>\n /** Lifecycle — всегда async */\n protected abstract doDestroy(): Promise<void>\n\n // ─── Lifecycle hooks ────────────────────────────────────────────────────────\n\n protected async performInitialize(): Promise<void> {\n await this.doInitialize()\n this._stateCache = this.getRawState()\n }\n\n protected async performCleanup(): Promise<void> {\n // Обходим публичный clear() (избегая ensureReady после _isDestroyed = true)\n this.pluginExecutor?.executeOnClear()\n this.doClear()\n\n await this.doDestroy()\n\n if (this.initializedMiddlewares) {\n this.initializedMiddlewares.forEach((m) => m.cleanup?.())\n this.initializedMiddlewares = null\n }\n }\n\n // ─── Middleware initialization ──────────────────────────────────────────────\n\n protected initializeMiddlewares(): void {\n if (this.config.middlewares && !this.initializedMiddlewares) {\n this.initializedMiddlewares = this.config.middlewares(() => this.getDefaultMiddleware())\n this.initializedMiddlewares.forEach((middleware) => this.middlewareModule.use(middleware))\n }\n }\n\n protected getDefaultMiddleware(): SyncDefaultMiddlewares {\n return {\n batching: (options = {}) => syncBatchingMiddleware(options),\n shallowCompare: (options = {}) => syncShallowCompareMiddleware(options),\n }\n }\n\n protected initializeWithMiddlewares(): void {\n try {\n const state = this.getRawState()\n const hasExistingState = Object.keys(state).length > 0\n\n if (!hasExistingState && this.config.initialState) {\n this.middlewareModule.dispatch({\n type: 'init',\n value: this.config.initialState,\n })\n }\n } catch (error) {\n this.logger?.error('Ошибка инициализации хранилища', { error })\n throw error\n }\n }\n\n // ─── Internal state access ──────────────────────────────────────────────────\n\n private getRawState(): T {\n try {\n const value = this.doGet('')\n return value || {}\n } catch (error) {\n this.logger?.error('Error getting state', { error })\n throw error\n }\n }\n\n // ─── Public sync API ────────────────────────────────────────────────────────\n\n public get<R>(key: StorageKeyType): R | undefined {\n this.ensureReady()\n\n try {\n const metadata = { operation: 'get', timestamp: Date.now(), key }\n\n const middlewareResult = this.middlewareModule.dispatch({\n type: 'get',\n key,\n metadata,\n })\n\n const finalResult = this.pluginExecutor?.executeAfterGet(key, middlewareResult, metadata) ?? middlewareResult\n\n this.emitEvent({\n type: StorageEvents.STORAGE_SELECT,\n payload: { key, value: finalResult },\n })\n\n return finalResult\n } catch (error) {\n this.logger?.error('Error getting value', { key, error })\n throw error\n }\n }\n\n public set<R>(key: StorageKeyType, value: R): void {\n this.ensureReady()\n\n try {\n const metadata = { operation: 'set', timestamp: Date.now(), key }\n\n const processedValue = this.pluginExecutor?.executeBeforeSet(value, metadata) ?? value\n\n const middlewareResult = this.middlewareModule.dispatch({\n type: 'set',\n key,\n value: processedValue,\n metadata,\n })\n\n if (middlewareResult === VALUE_NOT_CHANGED) return\n\n const finalResult = this.pluginExecutor?.executeAfterSet(key, middlewareResult, metadata) ?? middlewareResult\n\n this._stateCache = this.getRawState()\n\n const keyStr = key.toString()\n const changedPaths = [keyStr]\n\n this.notifySubscribers(key, finalResult)\n\n this.notifySubscribers(GLOBAL_SUBSCRIPTION_KEY, {\n type: StorageEvents.STORAGE_UPDATE,\n key,\n value: finalResult,\n changedPaths,\n })\n\n this.emitEvent({\n type: StorageEvents.STORAGE_UPDATE,\n payload: { key, value: finalResult, changedPaths },\n })\n } catch (error) {\n this.logger?.error('Error setting value', { key, error })\n throw error\n }\n }\n\n public update(updater: (state: T) => void): void {\n this.ensureReady()\n\n try {\n const metadata = { operation: 'update', timestamp: Date.now() }\n\n const currentState = this.getState()\n const newState = createLazyClone(currentState)\n updater(newState)\n\n const changedPaths = findChangedPaths(currentState, newState)\n\n if (changedPaths.size === 0) {\n this.logger?.debug?.('No changes detected in update')\n return\n }\n\n this.logger?.debug?.('Changed paths:', { paths: Array.from(changedPaths) })\n\n const changedTopLevelKeys = new Set<string>()\n for (const path of changedPaths) {\n changedTopLevelKeys.add(path.split('.')[0])\n }\n\n const updates = Array.from(changedTopLevelKeys).map((key) => {\n const keyMetadata = { ...metadata, key }\n const processedValue = this.pluginExecutor?.executeBeforeSet(newState[key], keyMetadata) ?? newState[key]\n return { key, value: processedValue }\n })\n\n const result = this.middlewareModule.dispatch({\n type: 'update',\n value: updates,\n metadata: {\n ...metadata,\n batchUpdate: true,\n changedPaths: Array.from(changedPaths),\n },\n })\n\n let updatedValues: Record<string, any> = {}\n if (Array.isArray(result)) {\n result.forEach((update: any) => {\n if (update && typeof update === 'object' && 'key' in update && 'value' in update) {\n updatedValues[update.key as string] = update.value\n }\n })\n } else if (result && typeof result === 'object') {\n updatedValues = { ...result }\n }\n\n const actuallyChangedKeys = Object.keys(updatedValues).filter((key) => !isEqual(currentState[key], updatedValues[key]))\n\n if (actuallyChangedKeys.length === 0) {\n this.logger?.debug?.('No actual changes after middleware processing')\n return\n }\n\n const finalUpdates: Record<string, any> = {}\n actuallyChangedKeys.forEach((key) => {\n finalUpdates[key] = updatedValues[key]\n })\n\n this.logger?.debug?.('Notifying subscribers about changes:', { keys: actuallyChangedKeys })\n\n this._stateCache = { ...currentState, ...finalUpdates } as T\n\n this.notifySubscribers(GLOBAL_SUBSCRIPTION_KEY, {\n type: StorageEvents.STORAGE_UPDATE,\n key: actuallyChangedKeys,\n value: finalUpdates,\n changedPaths: Array.from(changedPaths),\n })\n\n for (const path of changedPaths) {\n try {\n const topLevelKey = path.split('.')[0]\n if (topLevelKey in finalUpdates) {\n let value\n if (path === topLevelKey) {\n value = finalUpdates[topLevelKey]\n } else {\n const restPath = path.substring(topLevelKey.length + 1)\n value = getValueByPath(finalUpdates[topLevelKey], restPath)\n }\n if (value !== undefined) {\n this.notifySubscribers(path, value)\n }\n }\n } catch (error) {\n this.logger?.error('Error notifying path subscribers', { path, error })\n }\n }\n\n this.emitEvent({\n type: StorageEvents.STORAGE_UPDATE,\n payload: {\n state: finalUpdates,\n key: actuallyChangedKeys,\n changedPaths: Array.from(changedPaths),\n },\n })\n } catch (error) {\n this.logger?.error('Error updating state', { error })\n throw error\n }\n }\n\n public remove(key: StorageKeyType): void {\n this.ensureReady()\n\n try {\n const metadata = { operation: 'delete', timestamp: Date.now(), key }\n\n const preventDeletion = this.pluginExecutor?.executeBeforeDelete(key, metadata)\n if (preventDeletion === false) return\n\n const middlewareResult = this.middlewareModule.dispatch({\n type: 'delete',\n key,\n metadata,\n })\n\n if (middlewareResult === false) return\n\n this.pluginExecutor?.executeAfterDelete(key, metadata)\n\n this._stateCache = this.getRawState()\n\n const keyStr = key.toString()\n const changedPaths = [keyStr]\n\n this.notifySubscribers(key, undefined)\n this.notifySubscribers(GLOBAL_SUBSCRIPTION_KEY, {\n type: StorageEvents.STORAGE_UPDATE,\n key,\n value: undefined,\n result: middlewareResult,\n changedPaths,\n })\n\n this.emitEvent({\n type: StorageEvents.STORAGE_UPDATE,\n payload: { key, value: undefined, result: middlewareResult, changedPaths },\n })\n } catch (error) {\n this.logger?.error('Error deleting value', { key, error })\n throw error\n }\n }\n\n public clear(): void {\n this.ensureReady()\n\n try {\n this.pluginExecutor?.executeOnClear()\n\n this.middlewareModule.dispatch({ type: 'clear' })\n\n this._stateCache = {} as T\n } catch (error) {\n this.logger?.error('Error clearing storage', { error })\n throw error\n }\n }\n\n public reset(): void {\n this.ensureReady()\n\n try {\n const initialState = this.config.initialState\n\n this.middlewareModule.dispatch({\n type: 'reset',\n value: initialState,\n })\n\n this._stateCache = initialState ? ({ ...initialState } as T) : ({} as T)\n\n const changedPaths = Object.keys(this._stateCache)\n\n this.notifySubscribers(GLOBAL_SUBSCRIPTION_KEY, {\n type: StorageEvents.STORAGE_CLEAR,\n changedPaths,\n })\n\n this.emitEvent({\n type: StorageEvents.STORAGE_CLEAR,\n payload: { changedPaths },\n })\n } catch (error) {\n this.logger?.error('Error resetting storage', { error })\n throw error\n }\n }\n\n public keys(): string[] {\n this.ensureReady()\n\n try {\n return this.middlewareModule.dispatch({ type: 'keys' })\n } catch (error) {\n this.logger?.error('Error getting keys', { error })\n throw error\n }\n }\n\n public has(key: StorageKeyType): boolean {\n this.ensureReady()\n try {\n return this.doHas(key)\n } catch (error) {\n this.logger?.error('Error checking value existence', { key, error })\n throw error\n }\n }\n\n public getState(): T {\n this.ensureReady()\n return this.getRawState()\n }\n\n // ─── Subscriptions (4.4 — simplified for sync) ─────────────────────────────\n\n /**\n * Sync-версия subscribeByKey.\n * Нет race condition (get() синхронный) → не нужен keyVersions tracking.\n */\n protected subscribeByKey(key: string, callback: (value: any) => void): VoidFunction {\n if (!this.subscribers.has(key)) {\n this.subscribers.set(key, new Set())\n }\n this.subscribers.get(key)!.add(callback)\n\n // Синхронно получаем начальное значение и сразу вызываем callback\n try {\n const value = this.get(key)\n callback(value)\n } catch (error) {\n this.logger?.error('Error in initial callback', { key, error })\n }\n\n return () => {\n const subscribers = this.subscribers.get(key)\n if (subscribers) {\n subscribers.delete(callback)\n if (subscribers.size === 0) {\n this.subscribers.delete(key)\n }\n }\n }\n }\n\n protected subscribeBySelector<R>(pathSelector: PathSelector<T, R>, callback: (value: R) => void): VoidFunction {\n const dummyState = createDummyState<T>()\n const fullPath = extractPath(pathSelector, dummyState, this.selectorPathCache)\n\n this.logger?.debug?.('Subscribing to path:', { path: fullPath })\n\n // Sync-обёртка: получаем текущее состояние синхронно и применяем селектор\n const wrappedCallback = (value: any) => {\n try {\n if (value === undefined || value === null || typeof value === 'object') {\n const currentState = this.getState()\n const selectedValue = pathSelector(currentState)\n callback(selectedValue as R)\n return\n }\n callback(value as R)\n } catch (error) {\n this.logger?.error('Error in selector callback', { path: fullPath, error })\n callback(value as R)\n }\n }\n\n if (!fullPath) {\n return this.subscribeToAll(() => {\n callback(pathSelector(this.getState()))\n })\n }\n\n return this.subscribeByKey(fullPath, wrappedCallback)\n }\n}\n"],"names":["syncBatchingMiddleware","syncShallowCompareMiddleware","StorageEvents","SyncMiddlewareModule","VALUE_NOT_CHANGED","createDummyState","extractPath","createLazyClone","findChangedPaths","isEqual","getValueByPath","GLOBAL_SUBSCRIPTION_KEY","StorageCore","SyncBaseStorage","WeakMap","config","pluginExecutor","eventEmitter","logger","m","middleware","options","state","hasExistingState","Object","error","value","key","metadata","Date","middlewareResult","finalResult","processedValue","keyStr","changedPaths","updater","currentState","newState","Array","changedTopLevelKeys","Set","path","updates","keyMetadata","result","updatedValues","update","actuallyChangedKeys","finalUpdates","topLevelKey","restPath","undefined","preventDeletion","initialState","callback","subscribers","pathSelector","dummyState","fullPath","wrappedCallback","selectedValue"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"core/storage/adapters/sync-base-storage.service.js","sources":["../../../../src/core/storage/adapters/sync-base-storage.service.ts"],"sourcesContent":["import { syncBatchingMiddleware } from '../middlewares/sync-storage-batching.middleware'\nimport { syncLoggerMiddleware } from '../middlewares/sync-storage-logger.middleware'\nimport { syncShallowCompareMiddleware } from '../middlewares/sync-storage-shallow-compare.middleware'\nimport { IEventEmitter, ILogger, ISyncStorage, StorageEvents, StorageType, SyncDefaultMiddlewares, SyncStorageConfig } from '../storage.interface'\nimport { SyncMiddleware, SyncMiddlewareModule, VALUE_NOT_CHANGED } from '../utils/middleware-module'\nimport { decideMigration } from '../utils/migration.util'\nimport { createDummyState, extractPath } from '../utils/path-selector.util'\nimport { createLazyClone, findChangedPaths, isEqual } from '../utils/state-diff.util'\nimport { StorageKeyType } from '../utils/storage-key'\nimport { getValueByPath } from './path.utils'\nimport { GLOBAL_SUBSCRIPTION_KEY, PathSelector, StorageCore } from './storage-core'\n\n/**\n * Базовый класс для синхронных хранилищ (Memory, LocalStorage).\n *\n * Все CRUD-операции выполняются синхронно.\n * Lifecycle (initialize, destroy) остаётся async.\n * subscribeByKey упрощён — нет race condition без async get.\n */\nexport abstract class SyncBaseStorage<T extends Record<string, any>> extends StorageCore<T> implements ISyncStorage<T> {\n abstract readonly type: StorageType\n\n private middlewareModule: SyncMiddlewareModule\n private initializedMiddlewares: SyncMiddleware[] | null = null\n private selectorPathCache = new WeakMap<PathSelector<any, any>, string>()\n\n constructor(\n protected readonly config: SyncStorageConfig<T>,\n eventEmitter?: IEventEmitter,\n logger?: ILogger,\n ) {\n super(config, eventEmitter, logger)\n this.middlewareModule = new SyncMiddlewareModule({\n getState: () => this.getRawState(),\n doGet: this.doGet.bind(this),\n doSet: this.doSet.bind(this),\n doUpdate: this.doUpdate.bind(this),\n doRemove: this.doRemove.bind(this),\n doClear: this.doClear.bind(this),\n doKeys: this.doKeys.bind(this),\n notifySubscribers: this.notifySubscribers.bind(this),\n })\n }\n\n // ─── Abstract sync do* methods ──────────────────────────────────────────────\n\n protected abstract doGet(key: StorageKeyType): any\n protected abstract doSet(key: StorageKeyType, value: any): void\n protected abstract doUpdate(updates: Array<{ key: StorageKeyType; value: any }>): void\n protected abstract doRemove(key: StorageKeyType): boolean\n protected abstract doClear(): void\n protected abstract doKeys(): string[]\n protected abstract doHas(key: StorageKeyType): boolean\n\n /** Lifecycle — всегда async */\n protected abstract doInitialize(): Promise<this>\n /** Lifecycle — всегда async */\n protected abstract doDestroy(): Promise<void>\n\n // ─── Lifecycle hooks ────────────────────────────────────────────────────────\n\n protected async performInitialize(): Promise<void> {\n await this.doInitialize()\n this._stateCache = this.getRawState()\n }\n\n /**\n * Дефолт для `config.clearOnDestroy`, если он не задан.\n * Memory: `true` (эфемерное). LocalStorage переопределяет на `false` (персистентное).\n */\n protected get clearOnDestroyDefault(): boolean {\n return true\n }\n\n protected async performCleanup(): Promise<void> {\n // Обходим публичный clear() (избегая ensureReady после _isDestroyed = true)\n if (this.config.clearOnDestroy ?? this.clearOnDestroyDefault) {\n this.doClear()\n this.clearPersistedVersion()\n }\n\n await this.doDestroy()\n\n if (this.initializedMiddlewares) {\n this.initializedMiddlewares.forEach((m) => m.cleanup?.())\n this.initializedMiddlewares = null\n }\n }\n\n // ─── Middleware initialization ──────────────────────────────────────────────\n\n protected initializeMiddlewares(): void {\n if (this.config.middlewares && !this.initializedMiddlewares) {\n this.initializedMiddlewares = this.config.middlewares(() => this.getDefaultMiddleware())\n this.initializedMiddlewares.forEach((middleware) => this.middlewareModule.use(middleware))\n }\n }\n\n protected getDefaultMiddleware(): SyncDefaultMiddlewares {\n return {\n batching: (options = {}) => syncBatchingMiddleware(options),\n shallowCompare: (options = {}) => syncShallowCompareMiddleware(options),\n logger: (options = {}) => syncLoggerMiddleware(options),\n }\n }\n\n protected initializeWithMiddlewares(): void {\n try {\n const state = this.getRawState()\n const hasExistingState = Object.keys(state).length > 0\n\n // Миграция выключена (version не задан) — прежнее поведение: засеять initialState на пустом.\n if (this.config.version === undefined) {\n if (!hasExistingState && this.config.initialState) {\n this.middlewareModule.dispatch({ type: 'init', value: this.config.initialState })\n }\n return\n }\n\n const decision = decideMigration({\n hasExisting: hasExistingState,\n existingState: state,\n persistedVersion: this.readPersistedVersion(),\n targetVersion: this.config.version,\n migrate: this.config.migrate,\n })\n\n switch (decision.kind) {\n case 'seed': {\n if (this.config.initialState) {\n this.middlewareModule.dispatch({ type: 'init', value: this.config.initialState })\n }\n this.writePersistedVersion(this.config.version)\n break\n }\n case 'migrate': {\n this.middlewareModule.dispatch({ type: 'reset', value: decision.state })\n this.writePersistedVersion(this.config.version)\n break\n }\n case 'bump': {\n this.writePersistedVersion(this.config.version)\n break\n }\n case 'none':\n break\n }\n } catch (error) {\n this.logger?.error('Ошибка инициализации хранилища', { error })\n throw error\n }\n }\n\n // ─── Persisted schema version (persist-migration) ───────────────────────────\n\n /** Читает сохранённую версию схемы. По умолчанию `undefined` (эфемерные хранилища). */\n protected readPersistedVersion(): number | undefined {\n return undefined\n }\n\n /** Сохраняет версию схемы рядом с данными. По умолчанию no-op (эфемерные хранилища). */\n protected writePersistedVersion(_version: number): void {}\n\n /** Удаляет сохранённую версию схемы (вызывается при destroy с `clearOnDestroy`). */\n protected clearPersistedVersion(): void {}\n\n // ─── Internal state access ──────────────────────────────────────────────────\n\n private getRawState(): T {\n try {\n const value = this.doGet('')\n return value || {}\n } catch (error) {\n this.logger?.error('Error getting state', { error })\n throw error\n }\n }\n\n // ─── Public sync API ────────────────────────────────────────────────────────\n\n public get<R>(key: StorageKeyType): R | undefined {\n this.ensureReady()\n\n try {\n const metadata = { operation: 'get', timestamp: Date.now(), key }\n\n const finalResult = this.middlewareModule.dispatch({\n type: 'get',\n key,\n metadata,\n })\n\n // Чтения не эмитят событий — это горячий путь, а STORAGE_SELECT нигде не потребляется.\n return finalResult\n } catch (error) {\n this.logger?.error('Error getting value', { key, error })\n throw error\n }\n }\n\n public set<R>(key: StorageKeyType, value: R): void {\n this.ensureReady()\n\n try {\n const metadata = { operation: 'set', timestamp: Date.now(), key }\n\n const finalResult = this.middlewareModule.dispatch({\n type: 'set',\n key,\n value,\n metadata,\n })\n\n if (finalResult === VALUE_NOT_CHANGED) return\n\n this._stateCache = this.getRawState()\n\n const keyStr = key.toString()\n const changedPaths = [keyStr]\n\n this.notifySubscribers(key, finalResult)\n\n this.notifySubscribers(GLOBAL_SUBSCRIPTION_KEY, {\n type: StorageEvents.STORAGE_UPDATE,\n key,\n value: finalResult,\n changedPaths,\n })\n\n this.emitEvent({\n type: StorageEvents.STORAGE_UPDATE,\n payload: { key, value: finalResult, changedPaths },\n })\n } catch (error) {\n this.logger?.error('Error setting value', { key, error })\n throw error\n }\n }\n\n public update(updater: (state: T) => void): void {\n this.ensureReady()\n\n try {\n const metadata = { operation: 'update', timestamp: Date.now() }\n\n const currentState = this.getState()\n const newState = createLazyClone(currentState)\n updater(newState)\n\n const changedPaths = findChangedPaths(currentState, newState)\n\n if (changedPaths.size === 0) {\n this.logger?.debug?.('No changes detected in update')\n return\n }\n\n this.logger?.debug?.('Changed paths:', { paths: Array.from(changedPaths) })\n\n const changedTopLevelKeys = new Set<string>()\n for (const path of changedPaths) {\n changedTopLevelKeys.add(path.split('.')[0])\n }\n\n const updates = Array.from(changedTopLevelKeys).map((key) => {\n return { key, value: newState[key] }\n })\n\n const result = this.middlewareModule.dispatch({\n type: 'update',\n value: updates,\n metadata: {\n ...metadata,\n batchUpdate: true,\n changedPaths: Array.from(changedPaths),\n },\n })\n\n let updatedValues: Record<string, any> = {}\n if (Array.isArray(result)) {\n result.forEach((update: any) => {\n if (update && typeof update === 'object' && 'key' in update && 'value' in update) {\n updatedValues[update.key as string] = update.value\n }\n })\n } else if (result && typeof result === 'object') {\n updatedValues = { ...result }\n }\n\n const actuallyChangedKeys = Object.keys(updatedValues).filter((key) => !isEqual(currentState[key], updatedValues[key]))\n\n if (actuallyChangedKeys.length === 0) {\n this.logger?.debug?.('No actual changes after middleware processing')\n return\n }\n\n const finalUpdates: Record<string, any> = {}\n actuallyChangedKeys.forEach((key) => {\n finalUpdates[key] = updatedValues[key]\n })\n\n this.logger?.debug?.('Notifying subscribers about changes:', { keys: actuallyChangedKeys })\n\n this._stateCache = { ...currentState, ...finalUpdates } as T\n\n this.notifySubscribers(GLOBAL_SUBSCRIPTION_KEY, {\n type: StorageEvents.STORAGE_UPDATE,\n key: actuallyChangedKeys,\n value: finalUpdates,\n changedPaths: Array.from(changedPaths),\n })\n\n for (const path of changedPaths) {\n try {\n const topLevelKey = path.split('.')[0]\n if (topLevelKey in finalUpdates) {\n let value\n if (path === topLevelKey) {\n value = finalUpdates[topLevelKey]\n } else {\n const restPath = path.substring(topLevelKey.length + 1)\n value = getValueByPath(finalUpdates[topLevelKey], restPath)\n }\n if (value !== undefined) {\n this.notifySubscribers(path, value)\n }\n }\n } catch (error) {\n this.logger?.error('Error notifying path subscribers', { path, error })\n }\n }\n\n this.emitEvent({\n type: StorageEvents.STORAGE_UPDATE,\n payload: {\n state: finalUpdates,\n key: actuallyChangedKeys,\n changedPaths: Array.from(changedPaths),\n },\n })\n } catch (error) {\n this.logger?.error('Error updating state', { error })\n throw error\n }\n }\n\n public remove(key: StorageKeyType): void {\n this.ensureReady()\n\n try {\n const metadata = { operation: 'delete', timestamp: Date.now(), key }\n\n const middlewareResult = this.middlewareModule.dispatch({\n type: 'delete',\n key,\n metadata,\n })\n\n if (middlewareResult === false) return\n\n this._stateCache = this.getRawState()\n\n const keyStr = key.toString()\n const changedPaths = [keyStr]\n\n this.notifySubscribers(key, undefined)\n this.notifySubscribers(GLOBAL_SUBSCRIPTION_KEY, {\n type: StorageEvents.STORAGE_UPDATE,\n key,\n value: undefined,\n result: middlewareResult,\n changedPaths,\n })\n\n this.emitEvent({\n type: StorageEvents.STORAGE_UPDATE,\n payload: { key, value: undefined, result: middlewareResult, changedPaths },\n })\n } catch (error) {\n this.logger?.error('Error deleting value', { key, error })\n throw error\n }\n }\n\n public clear(): void {\n this.ensureReady()\n\n try {\n this.middlewareModule.dispatch({ type: 'clear' })\n\n this._stateCache = {} as T\n } catch (error) {\n this.logger?.error('Error clearing storage', { error })\n throw error\n }\n }\n\n public reset(): void {\n this.ensureReady()\n\n try {\n const initialState = this.config.initialState\n\n this.middlewareModule.dispatch({\n type: 'reset',\n value: initialState,\n })\n\n this._stateCache = initialState ? ({ ...initialState } as T) : ({} as T)\n\n const changedPaths = Object.keys(this._stateCache)\n\n this.notifySubscribers(GLOBAL_SUBSCRIPTION_KEY, {\n type: StorageEvents.STORAGE_CLEAR,\n changedPaths,\n })\n\n this.emitEvent({\n type: StorageEvents.STORAGE_CLEAR,\n payload: { changedPaths },\n })\n } catch (error) {\n this.logger?.error('Error resetting storage', { error })\n throw error\n }\n }\n\n /**\n * SSR-гидрация: заменяет всё состояние переданным снапшотом. Намеренно НЕ требует\n * `ready()` — типичный сценарий вызвать её до `initialize()`, чтобы инициализация\n * не перезатёрла серверное состояние `initialState`-ом (см. `initializeWithMiddlewares`).\n */\n public hydrate(state: T): void {\n try {\n this.doSet('', state)\n this._stateCache = this.getRawState()\n\n // Если включён persist-migration — фиксируем текущую версию: серверный снапшот\n // уже в актуальной схеме, миграцию на нём запускать не нужно.\n if (this.config.version !== undefined) {\n this.writePersistedVersion(this.config.version)\n }\n\n this.notifyHydration(this._stateCache)\n } catch (error) {\n this.logger?.error('Error hydrating storage', { error })\n throw error\n }\n }\n\n /** Уведомляет подписчиков о замене состояния гидрацией (no-op до initialize/без подписок). */\n private notifyHydration(state: T): void {\n const changedPaths = Object.keys(state)\n\n for (const key of changedPaths) {\n this.notifySubscribers(key, (state as Record<string, any>)[key])\n }\n\n this.notifySubscribers(GLOBAL_SUBSCRIPTION_KEY, {\n type: StorageEvents.STORAGE_UPDATE,\n key: changedPaths,\n value: state,\n changedPaths,\n })\n }\n\n public keys(): string[] {\n this.ensureReady()\n\n try {\n return this.middlewareModule.dispatch({ type: 'keys' })\n } catch (error) {\n this.logger?.error('Error getting keys', { error })\n throw error\n }\n }\n\n public has(key: StorageKeyType): boolean {\n this.ensureReady()\n try {\n return this.doHas(key)\n } catch (error) {\n this.logger?.error('Error checking value existence', { key, error })\n throw error\n }\n }\n\n public getState(): T {\n this.ensureReady()\n return this.getRawState()\n }\n\n // ─── Subscriptions (4.4 — simplified for sync) ─────────────────────────────\n\n /**\n * Sync-версия subscribeByKey.\n * Нет race condition (get() синхронный) → не нужен keyVersions tracking.\n */\n protected subscribeByKey(key: string, callback: (value: any) => void): VoidFunction {\n if (!this.subscribers.has(key)) {\n this.subscribers.set(key, new Set())\n }\n this.subscribers.get(key)!.add(callback)\n\n // Синхронно получаем начальное значение и сразу вызываем callback\n try {\n const value = this.get(key)\n callback(value)\n } catch (error) {\n this.logger?.error('Error in initial callback', { key, error })\n }\n\n return () => {\n const subscribers = this.subscribers.get(key)\n if (subscribers) {\n subscribers.delete(callback)\n if (subscribers.size === 0) {\n this.subscribers.delete(key)\n }\n }\n }\n }\n\n protected subscribeBySelector<R>(pathSelector: PathSelector<T, R>, callback: (value: R) => void): VoidFunction {\n const dummyState = createDummyState<T>()\n const fullPath = extractPath(pathSelector, dummyState, this.selectorPathCache)\n\n this.logger?.debug?.('Subscribing to path:', { path: fullPath })\n\n // Sync-обёртка: получаем текущее состояние синхронно и применяем селектор\n const wrappedCallback = (value: any) => {\n try {\n if (value === undefined || value === null || typeof value === 'object') {\n const currentState = this.getState()\n const selectedValue = pathSelector(currentState)\n callback(selectedValue as R)\n return\n }\n callback(value as R)\n } catch (error) {\n this.logger?.error('Error in selector callback', { path: fullPath, error })\n callback(value as R)\n }\n }\n\n if (!fullPath) {\n return this.subscribeToAll(() => {\n callback(pathSelector(this.getState()))\n })\n }\n\n return this.subscribeByKey(fullPath, wrappedCallback)\n }\n}\n"],"names":["syncBatchingMiddleware","syncLoggerMiddleware","syncShallowCompareMiddleware","StorageEvents","SyncMiddlewareModule","VALUE_NOT_CHANGED","decideMigration","createDummyState","extractPath","createLazyClone","findChangedPaths","isEqual","getValueByPath","GLOBAL_SUBSCRIPTION_KEY","StorageCore","SyncBaseStorage","WeakMap","config","eventEmitter","logger","m","middleware","options","state","hasExistingState","Object","undefined","decision","error","_version","value","key","metadata","Date","finalResult","keyStr","changedPaths","updater","currentState","newState","Array","changedTopLevelKeys","Set","path","updates","result","updatedValues","update","actuallyChangedKeys","finalUpdates","topLevelKey","restPath","middlewareResult","initialState","callback","subscribers","pathSelector","dummyState","fullPath","wrappedCallback","selectedValue"],"mappings":"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"}
|