synapse-storage 4.1.1 → 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 +9 -2
- package/dist/core/storage/utils/state-diff.util.js +30 -3
- 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,4 +1,3 @@
|
|
|
1
|
-
import { IAsyncPluginExecutor } from '../modules/plugin/plugin.interface';
|
|
2
1
|
import { ConfigureAsyncMiddlewares, IEventEmitter, ILogger, IndexedDBStorageConfig, StorageType } from '../storage.interface';
|
|
3
2
|
import { StorageKey, StorageKeyType } from '../utils/storage-key';
|
|
4
3
|
import { AsyncBaseStorage } from './async-base-storage.service';
|
|
@@ -46,15 +45,14 @@ export declare class IndexedDBStorage<T extends Record<string, any>> extends Asy
|
|
|
46
45
|
private readonly DB_NAME;
|
|
47
46
|
private readonly STORE_NAME;
|
|
48
47
|
private dbManager;
|
|
49
|
-
constructor(config: IndexedDBStorageConfig<T>,
|
|
50
|
-
static create<T extends Record<string, any>>(config: IndexedDBStorageConfig,
|
|
48
|
+
constructor(config: IndexedDBStorageConfig<T>, eventEmitter?: IEventEmitter, logger?: ILogger);
|
|
49
|
+
static create<T extends Record<string, any>>(config: IndexedDBStorageConfig, eventEmitter?: IEventEmitter, logger?: ILogger): IndexedDBStorage<T>;
|
|
51
50
|
protected doInitialize(): Promise<this>;
|
|
52
51
|
static createStorages<S extends Record<string, any>>(dbName: string, configs: {
|
|
53
52
|
[K in keyof S]: {
|
|
54
53
|
name: string;
|
|
55
54
|
initialState?: S[K];
|
|
56
55
|
middlewares?: ConfigureAsyncMiddlewares;
|
|
57
|
-
pluginExecutor?: IAsyncPluginExecutor;
|
|
58
56
|
eventEmitter?: IEventEmitter;
|
|
59
57
|
};
|
|
60
58
|
}, logger?: ILogger): Promise<{
|
|
@@ -93,6 +91,8 @@ export declare class IndexedDBStorage<T extends Record<string, any>> extends Asy
|
|
|
93
91
|
protected doDelete(key: StorageKeyType): Promise<boolean>;
|
|
94
92
|
protected doClear(): Promise<void>;
|
|
95
93
|
protected doKeys(): Promise<string[]>;
|
|
94
|
+
protected readPersistedVersion(): Promise<number | undefined>;
|
|
95
|
+
protected writePersistedVersion(version: number): Promise<void>;
|
|
96
96
|
protected doHas(key: StorageKeyType): Promise<boolean>;
|
|
97
97
|
/**
|
|
98
98
|
* Override performCleanup: persistent storage should NOT clear data on destroy.
|
|
@@ -101,4 +101,3 @@ export declare class IndexedDBStorage<T extends Record<string, any>> extends Asy
|
|
|
101
101
|
protected performCleanup(): Promise<void>;
|
|
102
102
|
protected doDestroy(): Promise<void>;
|
|
103
103
|
}
|
|
104
|
-
//# sourceMappingURL=indexed-DB.service.d.ts.map
|
|
@@ -11,6 +11,11 @@ import { getValueByPath, parsePath, setValueByPath } from "./path.utils.js";
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Reserved-ключ записи с версией схемы (persist-migration). Хранится в том же сторе, что и
|
|
16
|
+
* данные, но исключается из `getState()`/`keys()` и переживает `clear()`/`set('')`, когда
|
|
17
|
+
* задана `config.version` (иначе — обычный быстрый `store.clear()`).
|
|
18
|
+
*/ const VERSION_META_KEY = '__synapse_version__';
|
|
14
19
|
// Управляет соединением с базой данных
|
|
15
20
|
class IndexedDBManager {
|
|
16
21
|
dbName;
|
|
@@ -198,15 +203,15 @@ class IndexedDBStorage extends AsyncBaseStorage {
|
|
|
198
203
|
DB_NAME;
|
|
199
204
|
STORE_NAME;
|
|
200
205
|
dbManager;
|
|
201
|
-
constructor(config,
|
|
202
|
-
super(config,
|
|
206
|
+
constructor(config, eventEmitter, logger){
|
|
207
|
+
super(config, eventEmitter, logger);
|
|
203
208
|
this.DB_NAME = config.options?.dbName || 'app_storage';
|
|
204
209
|
this.STORE_NAME = config.name;
|
|
205
210
|
// Get database manager instance (version is auto-detected internally)
|
|
206
211
|
this.dbManager = IndexedDBManager.getInstance(this.DB_NAME, 1, logger);
|
|
207
212
|
}
|
|
208
|
-
static create(config,
|
|
209
|
-
return SingletonMixin.handleSingletonCreation(config, this.STORAGE_TYPE, (finalConfig)=>new IndexedDBStorage(finalConfig,
|
|
213
|
+
static create(config, eventEmitter, logger) {
|
|
214
|
+
return SingletonMixin.handleSingletonCreation(config, this.STORAGE_TYPE, (finalConfig)=>new IndexedDBStorage(finalConfig, eventEmitter, logger), logger);
|
|
210
215
|
}
|
|
211
216
|
async doInitialize() {
|
|
212
217
|
try {
|
|
@@ -246,7 +251,7 @@ class IndexedDBStorage extends AsyncBaseStorage {
|
|
|
246
251
|
options: {
|
|
247
252
|
dbName
|
|
248
253
|
}
|
|
249
|
-
}, config.
|
|
254
|
+
}, config.eventEmitter, logger);
|
|
250
255
|
// Инициализируем хранилище
|
|
251
256
|
result[key] = await storage.initialize();
|
|
252
257
|
}
|
|
@@ -337,7 +342,7 @@ class IndexedDBStorage extends AsyncBaseStorage {
|
|
|
337
342
|
const allKeys = store.getAllKeys();
|
|
338
343
|
allKeys.onsuccess = ()=>{
|
|
339
344
|
const state = allKeys.result.reduce((acc, k, index)=>{
|
|
340
|
-
if (k !== 'root') {
|
|
345
|
+
if (k !== 'root' && k !== VERSION_META_KEY) {
|
|
341
346
|
acc[k] = allValues[index];
|
|
342
347
|
}
|
|
343
348
|
return acc;
|
|
@@ -385,6 +390,7 @@ class IndexedDBStorage extends AsyncBaseStorage {
|
|
|
385
390
|
// Для пустого ключа устанавливаем все состояние
|
|
386
391
|
if (key === '') {
|
|
387
392
|
const store = await this.getObjectStore('readwrite');
|
|
393
|
+
const preserveVersion = this.config.version !== undefined;
|
|
388
394
|
return new Promise((resolve, reject)=>{
|
|
389
395
|
const tx = store.transaction;
|
|
390
396
|
tx.oncomplete = ()=>{
|
|
@@ -393,16 +399,28 @@ class IndexedDBStorage extends AsyncBaseStorage {
|
|
|
393
399
|
tx.onerror = ()=>{
|
|
394
400
|
reject(tx.error);
|
|
395
401
|
};
|
|
396
|
-
const
|
|
397
|
-
clearRequest.onsuccess = ()=>{
|
|
402
|
+
const writeEntries = ()=>{
|
|
398
403
|
const entries = Object.entries(value);
|
|
399
404
|
for (const [entryKey, entryValue] of entries){
|
|
405
|
+
if (entryKey === VERSION_META_KEY) continue;
|
|
400
406
|
store.put(entryValue, entryKey);
|
|
401
407
|
}
|
|
402
408
|
};
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
409
|
+
// С persist-migration сохраняем reserved version-запись при перезаписи всего состояния.
|
|
410
|
+
if (preserveVersion) {
|
|
411
|
+
const keysReq = store.getAllKeys();
|
|
412
|
+
keysReq.onerror = ()=>reject(keysReq.error);
|
|
413
|
+
keysReq.onsuccess = ()=>{
|
|
414
|
+
for (const k of keysReq.result){
|
|
415
|
+
if (k !== VERSION_META_KEY) store.delete(k);
|
|
416
|
+
}
|
|
417
|
+
writeEntries();
|
|
418
|
+
};
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
const clearRequest = store.clear();
|
|
422
|
+
clearRequest.onsuccess = ()=>writeEntries();
|
|
423
|
+
clearRequest.onerror = ()=>reject(clearRequest.error);
|
|
406
424
|
});
|
|
407
425
|
}
|
|
408
426
|
const store = await this.getObjectStore('readwrite');
|
|
@@ -539,7 +557,10 @@ class IndexedDBStorage extends AsyncBaseStorage {
|
|
|
539
557
|
resolve(false);
|
|
540
558
|
return;
|
|
541
559
|
}
|
|
542
|
-
|
|
560
|
+
// rootValue уже соответствует parts[0] (каждый top-level ключ — отдельная запись стора),
|
|
561
|
+
// поэтому путь к родителю отсчитывается ВНУТРИ rootValue: parts.slice(1, -1) (ср. doGet).
|
|
562
|
+
const innerParentPath = parts.slice(1, -1).join('.');
|
|
563
|
+
const parent = innerParentPath ? getValueByPath(rootValue, innerParentPath) : rootValue;
|
|
543
564
|
const lastKey = parts[parts.length - 1];
|
|
544
565
|
if (!parent || !(lastKey in parent)) {
|
|
545
566
|
resolve(false);
|
|
@@ -564,6 +585,21 @@ class IndexedDBStorage extends AsyncBaseStorage {
|
|
|
564
585
|
}
|
|
565
586
|
async doClear() {
|
|
566
587
|
const store = await this.getObjectStore('readwrite');
|
|
588
|
+
// С persist-migration сохраняем reserved version-запись (она описывает схему, не данные).
|
|
589
|
+
if (this.config.version !== undefined) {
|
|
590
|
+
return new Promise((resolve, reject)=>{
|
|
591
|
+
const tx = store.transaction;
|
|
592
|
+
tx.oncomplete = ()=>resolve();
|
|
593
|
+
tx.onerror = ()=>reject(tx.error);
|
|
594
|
+
const keysReq = store.getAllKeys();
|
|
595
|
+
keysReq.onerror = ()=>reject(keysReq.error);
|
|
596
|
+
keysReq.onsuccess = ()=>{
|
|
597
|
+
for (const k of keysReq.result){
|
|
598
|
+
if (k !== VERSION_META_KEY) store.delete(k);
|
|
599
|
+
}
|
|
600
|
+
};
|
|
601
|
+
});
|
|
602
|
+
}
|
|
567
603
|
return new Promise((resolve, reject)=>{
|
|
568
604
|
const request = store.clear();
|
|
569
605
|
request.onsuccess = ()=>resolve();
|
|
@@ -575,11 +611,28 @@ class IndexedDBStorage extends AsyncBaseStorage {
|
|
|
575
611
|
const request = store.getAllKeys();
|
|
576
612
|
return new Promise((resolve, reject)=>{
|
|
577
613
|
request.onsuccess = ()=>{
|
|
578
|
-
resolve(request.result);
|
|
614
|
+
resolve(request.result.filter((k)=>k !== VERSION_META_KEY));
|
|
579
615
|
};
|
|
580
616
|
request.onerror = ()=>reject(request.error);
|
|
581
617
|
});
|
|
582
618
|
}
|
|
619
|
+
// ─── Persisted schema version (persist-migration) ───────────────────────────
|
|
620
|
+
async readPersistedVersion() {
|
|
621
|
+
const store = await this.getObjectStore();
|
|
622
|
+
return new Promise((resolve)=>{
|
|
623
|
+
const request = store.get(VERSION_META_KEY);
|
|
624
|
+
request.onsuccess = ()=>resolve(typeof request.result === 'number' ? request.result : undefined);
|
|
625
|
+
request.onerror = ()=>resolve(undefined);
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
async writePersistedVersion(version) {
|
|
629
|
+
const store = await this.getObjectStore('readwrite');
|
|
630
|
+
return new Promise((resolve, reject)=>{
|
|
631
|
+
const request = store.put(version, VERSION_META_KEY);
|
|
632
|
+
request.onsuccess = ()=>resolve();
|
|
633
|
+
request.onerror = ()=>reject(request.error);
|
|
634
|
+
});
|
|
635
|
+
}
|
|
583
636
|
async doHas(key) {
|
|
584
637
|
const value = await this.doGet(key);
|
|
585
638
|
return value !== undefined;
|
|
@@ -588,7 +641,6 @@ class IndexedDBStorage extends AsyncBaseStorage {
|
|
|
588
641
|
* Override performCleanup: persistent storage should NOT clear data on destroy.
|
|
589
642
|
* Only clean up middleware and runtime resources, not persisted data.
|
|
590
643
|
*/ async performCleanup() {
|
|
591
|
-
await this.pluginExecutor?.executeOnClear();
|
|
592
644
|
await this.doDestroy();
|
|
593
645
|
}
|
|
594
646
|
async doDestroy() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core/storage/adapters/indexed-DB.service.js","sources":["../../../../src/core/storage/adapters/indexed-DB.service.ts"],"sourcesContent":["import { IAsyncPluginExecutor } from '../modules/plugin/plugin.interface'\nimport { SingletonMixin } from '../modules/singleton/mixin.util'\nimport { ConfigureAsyncMiddlewares, IEventEmitter, ILogger, IndexedDBStorageConfig, StorageType } from '../storage.interface'\nimport { StorageKey, StorageKeyType } from '../utils/storage-key'\nimport { AsyncBaseStorage } from './async-base-storage.service'\nimport { getValueByPath, parsePath, setValueByPath } from './path.utils'\n\nexport interface IndexedDBConfig {\n dbName?: string\n}\n\n// Управляет соединением с базой данных\nexport class IndexedDBManager {\n private static instances = new Map<string, IndexedDBManager>()\n private db: IDBDatabase | null = null\n private initPromise: Promise<IDBDatabase> | null = null\n private storeNames: Set<string> = new Set()\n private dbVersion: number\n // Последовательная очередь операций изменения схемы (создание сторов).\n // На одну БД (singleton по dbName) обычно инициализируется сразу несколько\n // ApiClient-ов (comments, posts, reactions, ...). Без сериализации их\n // ensureStoreExists перекрывались: один обнулял this.db между close() и\n // переоткрытием, второй в этот момент читал this.db.objectStoreNames → null.\n private opQueue: Promise<unknown> = Promise.resolve()\n\n private constructor(\n private readonly dbName: string,\n dbVersion: number,\n private readonly logger?: ILogger,\n ) {\n this.dbVersion = dbVersion\n }\n\n static getInstance(dbName: string, dbVersion: number = 1, logger?: ILogger): IndexedDBManager {\n if (!IndexedDBManager.instances.has(dbName)) {\n IndexedDBManager.instances.set(dbName, new IndexedDBManager(dbName, dbVersion, logger))\n }\n\n const instance = IndexedDBManager.instances.get(dbName)!\n\n // Update version if higher version is requested\n if (dbVersion > instance.dbVersion) {\n instance.dbVersion = dbVersion\n }\n\n return instance\n }\n\n async initialize(): Promise<IDBDatabase> {\n if (this.db) {\n return this.db\n }\n\n if (!this.initPromise) {\n this.initPromise = this.autoDetectAndOpen()\n }\n\n return this.initPromise\n }\n\n private async autoDetectAndOpen(): Promise<IDBDatabase> {\n // Auto-detect the current DB version to avoid VersionError\n const currentVersion = await this.detectCurrentVersion()\n if (currentVersion > this.dbVersion) {\n this.logger?.debug(`Auto-detected higher DB version: ${currentVersion} (requested: ${this.dbVersion})`)\n this.dbVersion = currentVersion\n }\n return this.openDatabase()\n }\n\n private detectCurrentVersion(): Promise<number> {\n return new Promise<number>((resolve) => {\n try {\n const request = indexedDB.open(this.dbName)\n request.onsuccess = () => {\n const version = request.result.version\n request.result.close()\n resolve(version)\n }\n request.onerror = () => resolve(0)\n } catch {\n resolve(0)\n }\n })\n }\n\n async ensureStoreExists(storeName: string): Promise<IDBDatabase> {\n return this.enqueue(() => this.ensureStoresInternal([storeName]))\n }\n\n /**\n * Ставит операцию изменения схемы в последовательную очередь, чтобы создания\n * сторов на одной БД не перекрывались между await-точками. Очередь не должна\n * \"застревать\" из-за упавшей операции — ошибку прокидываем вызывающему, но\n * следующий элемент очереди стартует независимо от результата предыдущего.\n */\n private enqueue<R>(operation: () => Promise<R>): Promise<R> {\n const result = this.opQueue.then(operation, operation)\n this.opQueue = result.then(\n () => undefined,\n () => undefined,\n )\n return result\n }\n\n /**\n * Идемпотентно гарантирует наличие переданных сторов. Никогда не обращается к\n * this.db после await — работает с локальной ссылкой, возвращённой initialize()\n * / openDatabase(), поэтому параллельное обнуление this.db (другим клиентом\n * или onversionchange) не приводит к чтению свойств у null.\n */\n private async ensureStoresInternal(storeNames: string[]): Promise<IDBDatabase> {\n let db = await this.initialize()\n\n const missingStores = storeNames.filter((name) => !db.objectStoreNames.contains(name))\n if (missingStores.length === 0) {\n for (const name of storeNames) this.storeNames.add(name)\n return db\n }\n\n this.logger?.debug(`Создание недостающих хранилищ: ${missingStores.join(', ')}`, {\n dbName: this.dbName,\n currentStores: Array.from(db.objectStoreNames),\n })\n\n db.close()\n this.db = null\n\n this.dbVersion++\n this.initPromise = this.openDatabase(missingStores)\n db = await this.initPromise\n\n for (const name of storeNames) this.storeNames.add(name)\n return db\n }\n\n private async openDatabase(newStores: string[] = []): Promise<IDBDatabase> {\n return new Promise<IDBDatabase>((resolve, reject) => {\n this.logger?.debug(`Opening database \"${this.dbName}\" with version ${this.dbVersion}`)\n\n const request = indexedDB.open(this.dbName, this.dbVersion)\n\n request.onerror = () => {\n this.logger?.error(`Failed to open database \"${this.dbName}\"`, { error: request.error })\n reject(request.error)\n }\n\n request.onblocked = () => {\n this.logger?.warn(`Database \"${this.dbName}\" upgrade blocked by another connection. Close other tabs or connections.`)\n reject(new Error(`Database \"${this.dbName}\" upgrade blocked — close other tabs using this database`))\n }\n\n request.onsuccess = () => {\n this.db = request.result\n\n // Auto-close when another connection requests a version upgrade\n this.db.onversionchange = () => {\n this.db?.close()\n this.db = null\n this.initPromise = null\n }\n\n // Add existing stores to our set\n for (let i = 0; i < this.db.objectStoreNames.length; i++) {\n this.storeNames.add(this.db.objectStoreNames[i])\n }\n\n this.logger?.debug(`Database \"${this.dbName}\" opened successfully`, {\n version: this.db.version,\n stores: Array.from(this.db.objectStoreNames),\n })\n\n resolve(this.db)\n }\n\n request.onupgradeneeded = (event) => {\n const db = (event.target as IDBOpenDBRequest).result\n this.logger?.debug(`Upgrading database \"${this.dbName}\" to version ${this.dbVersion}`)\n\n // Create new stores that don't exist yet\n for (const storeName of newStores) {\n if (!db.objectStoreNames.contains(storeName)) {\n this.logger?.debug(`Creating store \"${storeName}\"`)\n db.createObjectStore(storeName)\n }\n }\n }\n })\n }\n\n closeDatabase(): void {\n if (this.db) {\n this.db.close()\n this.db = null\n this.initPromise = null\n }\n }\n\n async deleteDatabase(): Promise<void> {\n this.closeDatabase()\n\n return new Promise<void>((resolve, reject) => {\n const request = indexedDB.deleteDatabase(this.dbName)\n request.onsuccess = () => {\n this.logger?.debug(`Database \"${this.dbName}\" deleted successfully`)\n IndexedDBManager.instances.delete(this.dbName)\n this.storeNames.clear()\n resolve()\n }\n request.onerror = () => {\n this.logger?.error(`Failed to delete database \"${this.dbName}\"`, { error: request.error })\n reject(request.error)\n }\n })\n }\n async ensureStoresExist(storeNames: string[]): Promise<IDBDatabase> {\n return this.enqueue(() => this.ensureStoresInternal(storeNames))\n }\n\n // Метод для получения текущей версии\n getCurrentVersion(): number {\n return this.dbVersion\n }\n}\n\nexport class IndexedDBStorage<T extends Record<string, any>> extends AsyncBaseStorage<T> {\n protected static readonly STORAGE_TYPE: StorageType = 'indexedDB'\n readonly type: StorageType = 'indexedDB'\n\n private readonly DB_NAME: string\n private readonly STORE_NAME: string\n private dbManager: IndexedDBManager\n\n constructor(config: IndexedDBStorageConfig<T>, pluginExecutor?: IAsyncPluginExecutor, eventEmitter?: IEventEmitter, logger?: ILogger) {\n super(config, pluginExecutor, eventEmitter, logger)\n\n this.DB_NAME = config.options?.dbName || 'app_storage'\n this.STORE_NAME = config.name\n\n // Get database manager instance (version is auto-detected internally)\n this.dbManager = IndexedDBManager.getInstance(this.DB_NAME, 1, logger)\n }\n\n static create<T extends Record<string, any>>(\n config: IndexedDBStorageConfig,\n pluginExecutor?: IAsyncPluginExecutor,\n eventEmitter?: IEventEmitter,\n logger?: ILogger,\n ): IndexedDBStorage<T> {\n return SingletonMixin.handleSingletonCreation(\n config,\n this.STORAGE_TYPE,\n (finalConfig) => new IndexedDBStorage<T>(finalConfig as IndexedDBStorageConfig<T>, pluginExecutor, eventEmitter, logger),\n logger,\n )\n }\n\n protected async doInitialize(): Promise<this> {\n try {\n this.logger?.debug(`Initializing IndexedDB storage \"${this.STORE_NAME}\"`)\n\n // Создаем store в базе данных\n await this.dbManager.ensureStoreExists(this.STORE_NAME)\n\n // Проверяем, что хранилище доступно\n const db = await this.dbManager.initialize()\n if (!db.objectStoreNames.contains(this.STORE_NAME)) {\n throw new Error(`Store \"${this.STORE_NAME}\" not found after initialization`)\n }\n\n // Инициализируем middleware\n this.initializeMiddlewares()\n\n // Инициализируем с middleware\n await this.initializeWithMiddlewares()\n\n this.logger?.debug(`IndexedDB storage \"${this.STORE_NAME}\" initialized successfully`)\n return this\n } catch (error) {\n this.logger?.error(`Ошибка инициализации IndexedDB \"${this.name}\"`, { error })\n throw error\n }\n }\n\n static async createStorages<S extends Record<string, any>>(\n dbName: string,\n configs: {\n [K in keyof S]: {\n name: string\n initialState?: S[K]\n middlewares?: ConfigureAsyncMiddlewares\n pluginExecutor?: IAsyncPluginExecutor\n eventEmitter?: IEventEmitter\n }\n },\n logger?: ILogger,\n ): Promise<{ [K in keyof S]: IndexedDBStorage<S[K]> }> {\n // Используем единый IndexedDBManager (версия определяется автоматически)\n const dbManager = IndexedDBManager.getInstance(dbName, 1, logger)\n\n // Получаем имена всех хранилищ, которые нужно создать\n const storeNames = Object.values(configs).map((config) => config.name)\n\n // Предварительно создаем все хранилища в рамках одной операции\n await dbManager.ensureStoresExist(storeNames)\n\n // Создаем и инициализируем все хранилища\n const result: Record<string, IndexedDBStorage<any>> = {}\n\n for (const [key, config] of Object.entries(configs)) {\n const storage = new IndexedDBStorage(\n {\n ...config,\n options: { dbName },\n },\n config.pluginExecutor,\n config.eventEmitter,\n logger,\n )\n\n // Инициализируем хранилище\n result[key] = await storage.initialize()\n }\n\n return result as { [K in keyof S]: IndexedDBStorage<S[K]> }\n }\n\n // ─── IndexedDB-specific API ────────────────────────────────────────────────\n\n /**\n * Выполняет операцию в рамках IDB-транзакции.\n * Обёртка для низкоуровневого IDB transaction API.\n *\n * @param mode - Режим транзакции ('readonly' | 'readwrite')\n * @param fn - Callback, получающий IDBObjectStore. Возвращает результат операции.\n * @returns Promise с результатом callback-а\n */\n async transaction<R>(mode: IDBTransactionMode, fn: (store: IDBObjectStore) => IDBRequest<R> | R): Promise<R> {\n const store = await this.getObjectStore(mode)\n\n return new Promise<R>((resolve, reject) => {\n const tx = store.transaction\n\n tx.onerror = () => reject(tx.error)\n tx.onabort = () => reject(tx.error || new Error('Transaction aborted'))\n\n try {\n const result = fn(store)\n\n if (result instanceof IDBRequest) {\n result.onsuccess = () => resolve(result.result)\n result.onerror = () => reject(result.error)\n } else {\n // Sync result — resolve when transaction completes\n tx.oncomplete = () => resolve(result)\n }\n } catch (error) {\n reject(error)\n }\n })\n }\n\n /**\n * Текущая версия базы данных.\n */\n get dbVersion(): number {\n return this.dbManager.getCurrentVersion()\n }\n\n /**\n * Имя базы данных.\n */\n get dbName(): string {\n return this.DB_NAME\n }\n\n /**\n * Имя object store в IndexedDB.\n */\n get storeName(): string {\n return this.STORE_NAME\n }\n\n // ─── Private helpers ───────────────────────────────────────────────────────\n\n private async getTransaction(mode: IDBTransactionMode = 'readonly'): Promise<IDBTransaction> {\n try {\n // Ensure database is open and our store exists\n const db = await this.dbManager.ensureStoreExists(this.STORE_NAME)\n\n // Проверяем существование хранилища перед созданием транзакции\n if (!db.objectStoreNames.contains(this.STORE_NAME)) {\n // Попытка исправить проблему - закрываем и снова открываем\n this.logger?.warn(`Object store \"${this.STORE_NAME}\" not found, attempting to repair`)\n\n db.close()\n this.dbManager.closeDatabase()\n\n // Пробуем заново создать хранилище с инкрементом версии\n const newDb = await this.dbManager.ensureStoreExists(this.STORE_NAME)\n\n if (!newDb.objectStoreNames.contains(this.STORE_NAME)) {\n throw new Error(`Object store \"${this.STORE_NAME}\" still doesn't exist after repair attempt`)\n }\n\n return newDb.transaction(this.STORE_NAME, mode)\n }\n\n return db.transaction(this.STORE_NAME, mode)\n } catch (error) {\n this.logger?.error(`Failed to create transaction for store \"${this.STORE_NAME}\"`, { error })\n throw error\n }\n }\n\n private async getObjectStore(mode: IDBTransactionMode = 'readonly'): Promise<IDBObjectStore> {\n const transaction = await this.getTransaction(mode)\n return transaction.objectStore(this.STORE_NAME)\n }\n\n protected async doGet(key: StorageKeyType): Promise<any> {\n const store = await this.getObjectStore()\n\n // Для пустого ключа возвращаем все состояние\n if (key === '') {\n return new Promise((resolve, reject) => {\n const request = store.getAll()\n request.onerror = () => reject(request.error)\n request.onsuccess = () => {\n const allValues = request.result\n const allKeys = store.getAllKeys()\n\n allKeys.onsuccess = () => {\n const state = allKeys.result.reduce(\n (acc, k, index) => {\n if (k !== 'root') {\n acc[k as string] = allValues[index]\n }\n return acc\n },\n {} as Record<string, any>,\n )\n resolve(state)\n }\n allKeys.onerror = () => reject(allKeys.error)\n }\n })\n }\n\n // Проверяем, является ли ключ \"сырым\"\n if (key instanceof StorageKey && key.isUnparseable()) {\n return new Promise((resolve, reject) => {\n const request = store.get(key.valueOf())\n request.onerror = () => reject(request.error)\n request.onsuccess = () => resolve(request.result)\n })\n }\n\n // Для вложенного пути\n const parts = parsePath(key)\n if (parts.length > 1) {\n const rootKey = parts[0]\n return new Promise((resolve, reject) => {\n const request = store.get(rootKey)\n request.onerror = () => reject(request.error)\n request.onsuccess = () => {\n const rootValue = request.result\n if (!rootValue) {\n resolve(undefined)\n return\n }\n const value = getValueByPath(rootValue, parts.slice(1).join('.'))\n resolve(value)\n }\n })\n }\n\n // Для простого ключа\n return new Promise((resolve, reject) => {\n const request = store.get(parts[0])\n request.onerror = () => reject(request.error)\n request.onsuccess = () => resolve(request.result)\n })\n }\n\n protected async doSet(key: StorageKeyType, value: any): Promise<void> {\n // Для пустого ключа устанавливаем все состояние\n if (key === '') {\n const store = await this.getObjectStore('readwrite')\n return new Promise((resolve, reject) => {\n const tx = store.transaction\n\n tx.oncomplete = () => {\n resolve()\n }\n\n tx.onerror = () => {\n reject(tx.error)\n }\n\n const clearRequest = store.clear()\n\n clearRequest.onsuccess = () => {\n const entries = Object.entries(value)\n for (const [entryKey, entryValue] of entries) {\n store.put(entryValue, entryKey)\n }\n }\n\n clearRequest.onerror = () => {\n reject(clearRequest.error)\n }\n })\n }\n\n const store = await this.getObjectStore('readwrite')\n\n // Для \"сырого\" ключа\n if (key instanceof StorageKey && key.isUnparseable()) {\n await this.putValueInStore(store, key.valueOf(), value)\n return\n }\n\n // Для вложенного пути\n const parts = parsePath(key)\n if (parts.length > 1) {\n const rootKey = parts[0]\n return new Promise((resolve, reject) => {\n const request = store.get(rootKey)\n request.onerror = () => reject(request.error)\n request.onsuccess = () => {\n const rootValue = request.result || {}\n const updatedValue = setValueByPath(rootValue, parts.slice(1).join('.'), value)\n const putRequest = store.put(updatedValue, rootKey)\n putRequest.onerror = () => reject(putRequest.error)\n putRequest.onsuccess = () => resolve()\n }\n })\n }\n\n // Для простого ключа\n await this.putValueInStore(store, parts[0], value)\n }\n\n private async putValueInStore(store: IDBObjectStore, key: StorageKeyType, value: any): Promise<void> {\n return new Promise((resolve, reject) => {\n const request = store.put(value, key.valueOf())\n request.onerror = () => reject(request.error)\n request.onsuccess = () => resolve()\n })\n }\n\n protected async doUpdate(updates: Array<{ key: string | StorageKey; value: any }>): Promise<void> {\n // Группируем обновления\n const updatesByRoot = new Map<string, Array<{ path: string[]; value: any }>>()\n const rawUpdates: Array<{ key: string; value: any }> = []\n\n // Разделяем обновления на \"сырые\" и обычные\n for (const { key, value } of updates) {\n if (key instanceof StorageKey && key.isUnparseable()) {\n rawUpdates.push({ key: key.valueOf(), value })\n continue\n }\n\n const parts = parsePath(key)\n const rootKey = parts[0]\n const path = parts.slice(1)\n\n if (!updatesByRoot.has(rootKey)) {\n updatesByRoot.set(rootKey, [])\n }\n updatesByRoot.get(rootKey)!.push({ path, value })\n }\n\n // Одна транзакция на весь doUpdate — атомарность\n const transaction = await this.getTransaction('readwrite')\n const store = transaction.objectStore(this.STORE_NAME)\n\n return new Promise<void>((resolve, reject) => {\n transaction.oncomplete = () => resolve()\n transaction.onerror = () => {\n this.logger?.error('Error during update:', { error: transaction.error })\n reject(transaction.error)\n }\n transaction.onabort = () => {\n this.logger?.error('Update transaction aborted:', { error: transaction.error })\n reject(transaction.error || new Error('Transaction aborted'))\n }\n\n // Обрабатываем \"сырые\" обновления\n for (const { key, value } of rawUpdates) {\n store.put(value, key)\n }\n\n // Обрабатываем сгруппированные обновления\n // Для каждого rootKey: читаем текущее значение, применяем все path-обновления, записываем обратно\n const rootKeys = Array.from(updatesByRoot.keys())\n\n if (rootKeys.length === 0) {\n // Нет сгруппированных обновлений — транзакция завершится сама\n return\n }\n\n for (const rootKey of rootKeys) {\n const getRequest = store.get(rootKey)\n\n getRequest.onsuccess = () => {\n const rootValue = getRequest.result || {}\n let updatedValue = { ...rootValue }\n const pathUpdates = updatesByRoot.get(rootKey)!\n\n for (const { path, value } of pathUpdates) {\n if (path.length === 0) {\n updatedValue = value\n } else {\n updatedValue = setValueByPath(updatedValue, path.join('.'), value)\n }\n }\n\n store.put(updatedValue, rootKey)\n }\n }\n })\n }\n\n protected async doDelete(key: StorageKeyType): Promise<boolean> {\n const store = await this.getObjectStore('readwrite')\n\n // Для \"сырого\" ключа\n if (key instanceof StorageKey && key.isUnparseable()) {\n return new Promise((resolve, reject) => {\n const request = store.delete(key.valueOf())\n request.onerror = () => reject(request.error)\n request.onsuccess = () => resolve(true)\n })\n }\n\n const parts = parsePath(key)\n\n // Для простого ключа\n if (parts.length === 1) {\n return new Promise((resolve, reject) => {\n const request = store.delete(parts[0])\n request.onerror = () => reject(request.error)\n request.onsuccess = () => resolve(true)\n })\n }\n\n // Для вложенного пути\n const rootKey = parts[0]\n return new Promise((resolve, reject) => {\n const getRequest = store.get(rootKey)\n getRequest.onerror = () => reject(getRequest.error)\n getRequest.onsuccess = () => {\n const rootValue = getRequest.result\n if (!rootValue) {\n resolve(false)\n return\n }\n\n const parent = getValueByPath(rootValue, parts.slice(0, -1).join('.'))\n const lastKey = parts[parts.length - 1]\n\n if (!parent || !(lastKey in parent)) {\n resolve(false)\n return\n }\n\n if (Array.isArray(parent)) {\n const index = parseInt(lastKey, 10)\n if (!isNaN(index)) {\n parent.splice(index, 1)\n } else {\n // @ts-ignore\n delete parent[lastKey]\n }\n } else {\n delete parent[lastKey]\n }\n\n const putRequest = store.put(rootValue, rootKey)\n putRequest.onerror = () => reject(putRequest.error)\n putRequest.onsuccess = () => resolve(true)\n }\n })\n }\n\n protected async doClear(): Promise<void> {\n const store = await this.getObjectStore('readwrite')\n return new Promise((resolve, reject) => {\n const request = store.clear()\n request.onsuccess = () => resolve()\n request.onerror = () => reject(request.error)\n })\n }\n\n protected async doKeys(): Promise<string[]> {\n const store = await this.getObjectStore()\n const request = store.getAllKeys()\n return new Promise((resolve, reject) => {\n request.onsuccess = () => {\n resolve(request.result as string[])\n }\n request.onerror = () => reject(request.error)\n })\n }\n\n protected async doHas(key: StorageKeyType): Promise<boolean> {\n const value = await this.doGet(key)\n return value !== undefined\n }\n\n /**\n * Override performCleanup: persistent storage should NOT clear data on destroy.\n * Only clean up middleware and runtime resources, not persisted data.\n */\n protected async performCleanup(): Promise<void> {\n await this.pluginExecutor?.executeOnClear()\n await this.doDestroy()\n }\n\n protected async doDestroy(): Promise<void> {\n // Persistent storage: do NOT clear data on destroy.\n // Only release runtime resources. Data persists across component lifecycles.\n }\n}\n"],"names":["SingletonMixin","StorageKey","AsyncBaseStorage","getValueByPath","parsePath","setValueByPath","IndexedDBManager","Map","Set","Promise","dbName","dbVersion","logger","instance","currentVersion","resolve","request","indexedDB","version","storeName","operation","result","undefined","storeNames","db","missingStores","name","Array","newStores","reject","Error","i","event","IndexedDBStorage","config","pluginExecutor","eventEmitter","finalConfig","error","configs","dbManager","Object","key","storage","mode","fn","store","tx","IDBRequest","newDb","transaction","allValues","allKeys","state","acc","k","index","parts","rootKey","rootValue","value","clearRequest","entries","entryKey","entryValue","updatedValue","putRequest","updates","updatesByRoot","rawUpdates","path","rootKeys","getRequest","pathUpdates","parent","lastKey","parseInt","isNaN"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"core/storage/adapters/indexed-DB.service.js","sources":["../../../../src/core/storage/adapters/indexed-DB.service.ts"],"sourcesContent":["import { SingletonMixin } from '../modules/singleton/mixin.util'\nimport { ConfigureAsyncMiddlewares, IEventEmitter, ILogger, IndexedDBStorageConfig, StorageType } from '../storage.interface'\nimport { StorageKey, StorageKeyType } from '../utils/storage-key'\nimport { AsyncBaseStorage } from './async-base-storage.service'\nimport { getValueByPath, parsePath, setValueByPath } from './path.utils'\n\nexport interface IndexedDBConfig {\n dbName?: string\n}\n\n/**\n * Reserved-ключ записи с версией схемы (persist-migration). Хранится в том же сторе, что и\n * данные, но исключается из `getState()`/`keys()` и переживает `clear()`/`set('')`, когда\n * задана `config.version` (иначе — обычный быстрый `store.clear()`).\n */\nconst VERSION_META_KEY = '__synapse_version__'\n\n// Управляет соединением с базой данных\nexport class IndexedDBManager {\n private static instances = new Map<string, IndexedDBManager>()\n private db: IDBDatabase | null = null\n private initPromise: Promise<IDBDatabase> | null = null\n private storeNames: Set<string> = new Set()\n private dbVersion: number\n // Последовательная очередь операций изменения схемы (создание сторов).\n // На одну БД (singleton по dbName) обычно инициализируется сразу несколько\n // ApiClient-ов (comments, posts, reactions, ...). Без сериализации их\n // ensureStoreExists перекрывались: один обнулял this.db между close() и\n // переоткрытием, второй в этот момент читал this.db.objectStoreNames → null.\n private opQueue: Promise<unknown> = Promise.resolve()\n\n private constructor(\n private readonly dbName: string,\n dbVersion: number,\n private readonly logger?: ILogger,\n ) {\n this.dbVersion = dbVersion\n }\n\n static getInstance(dbName: string, dbVersion: number = 1, logger?: ILogger): IndexedDBManager {\n if (!IndexedDBManager.instances.has(dbName)) {\n IndexedDBManager.instances.set(dbName, new IndexedDBManager(dbName, dbVersion, logger))\n }\n\n const instance = IndexedDBManager.instances.get(dbName)!\n\n // Update version if higher version is requested\n if (dbVersion > instance.dbVersion) {\n instance.dbVersion = dbVersion\n }\n\n return instance\n }\n\n async initialize(): Promise<IDBDatabase> {\n if (this.db) {\n return this.db\n }\n\n if (!this.initPromise) {\n this.initPromise = this.autoDetectAndOpen()\n }\n\n return this.initPromise\n }\n\n private async autoDetectAndOpen(): Promise<IDBDatabase> {\n // Auto-detect the current DB version to avoid VersionError\n const currentVersion = await this.detectCurrentVersion()\n if (currentVersion > this.dbVersion) {\n this.logger?.debug(`Auto-detected higher DB version: ${currentVersion} (requested: ${this.dbVersion})`)\n this.dbVersion = currentVersion\n }\n return this.openDatabase()\n }\n\n private detectCurrentVersion(): Promise<number> {\n return new Promise<number>((resolve) => {\n try {\n const request = indexedDB.open(this.dbName)\n request.onsuccess = () => {\n const version = request.result.version\n request.result.close()\n resolve(version)\n }\n request.onerror = () => resolve(0)\n } catch {\n resolve(0)\n }\n })\n }\n\n async ensureStoreExists(storeName: string): Promise<IDBDatabase> {\n return this.enqueue(() => this.ensureStoresInternal([storeName]))\n }\n\n /**\n * Ставит операцию изменения схемы в последовательную очередь, чтобы создания\n * сторов на одной БД не перекрывались между await-точками. Очередь не должна\n * \"застревать\" из-за упавшей операции — ошибку прокидываем вызывающему, но\n * следующий элемент очереди стартует независимо от результата предыдущего.\n */\n private enqueue<R>(operation: () => Promise<R>): Promise<R> {\n const result = this.opQueue.then(operation, operation)\n this.opQueue = result.then(\n () => undefined,\n () => undefined,\n )\n return result\n }\n\n /**\n * Идемпотентно гарантирует наличие переданных сторов. Никогда не обращается к\n * this.db после await — работает с локальной ссылкой, возвращённой initialize()\n * / openDatabase(), поэтому параллельное обнуление this.db (другим клиентом\n * или onversionchange) не приводит к чтению свойств у null.\n */\n private async ensureStoresInternal(storeNames: string[]): Promise<IDBDatabase> {\n let db = await this.initialize()\n\n const missingStores = storeNames.filter((name) => !db.objectStoreNames.contains(name))\n if (missingStores.length === 0) {\n for (const name of storeNames) this.storeNames.add(name)\n return db\n }\n\n this.logger?.debug(`Создание недостающих хранилищ: ${missingStores.join(', ')}`, {\n dbName: this.dbName,\n currentStores: Array.from(db.objectStoreNames),\n })\n\n db.close()\n this.db = null\n\n this.dbVersion++\n this.initPromise = this.openDatabase(missingStores)\n db = await this.initPromise\n\n for (const name of storeNames) this.storeNames.add(name)\n return db\n }\n\n private async openDatabase(newStores: string[] = []): Promise<IDBDatabase> {\n return new Promise<IDBDatabase>((resolve, reject) => {\n this.logger?.debug(`Opening database \"${this.dbName}\" with version ${this.dbVersion}`)\n\n const request = indexedDB.open(this.dbName, this.dbVersion)\n\n request.onerror = () => {\n this.logger?.error(`Failed to open database \"${this.dbName}\"`, { error: request.error })\n reject(request.error)\n }\n\n request.onblocked = () => {\n this.logger?.warn(`Database \"${this.dbName}\" upgrade blocked by another connection. Close other tabs or connections.`)\n reject(new Error(`Database \"${this.dbName}\" upgrade blocked — close other tabs using this database`))\n }\n\n request.onsuccess = () => {\n this.db = request.result\n\n // Auto-close when another connection requests a version upgrade\n this.db.onversionchange = () => {\n this.db?.close()\n this.db = null\n this.initPromise = null\n }\n\n // Add existing stores to our set\n for (let i = 0; i < this.db.objectStoreNames.length; i++) {\n this.storeNames.add(this.db.objectStoreNames[i])\n }\n\n this.logger?.debug(`Database \"${this.dbName}\" opened successfully`, {\n version: this.db.version,\n stores: Array.from(this.db.objectStoreNames),\n })\n\n resolve(this.db)\n }\n\n request.onupgradeneeded = (event) => {\n const db = (event.target as IDBOpenDBRequest).result\n this.logger?.debug(`Upgrading database \"${this.dbName}\" to version ${this.dbVersion}`)\n\n // Create new stores that don't exist yet\n for (const storeName of newStores) {\n if (!db.objectStoreNames.contains(storeName)) {\n this.logger?.debug(`Creating store \"${storeName}\"`)\n db.createObjectStore(storeName)\n }\n }\n }\n })\n }\n\n closeDatabase(): void {\n if (this.db) {\n this.db.close()\n this.db = null\n this.initPromise = null\n }\n }\n\n async deleteDatabase(): Promise<void> {\n this.closeDatabase()\n\n return new Promise<void>((resolve, reject) => {\n const request = indexedDB.deleteDatabase(this.dbName)\n request.onsuccess = () => {\n this.logger?.debug(`Database \"${this.dbName}\" deleted successfully`)\n IndexedDBManager.instances.delete(this.dbName)\n this.storeNames.clear()\n resolve()\n }\n request.onerror = () => {\n this.logger?.error(`Failed to delete database \"${this.dbName}\"`, { error: request.error })\n reject(request.error)\n }\n })\n }\n async ensureStoresExist(storeNames: string[]): Promise<IDBDatabase> {\n return this.enqueue(() => this.ensureStoresInternal(storeNames))\n }\n\n // Метод для получения текущей версии\n getCurrentVersion(): number {\n return this.dbVersion\n }\n}\n\nexport class IndexedDBStorage<T extends Record<string, any>> extends AsyncBaseStorage<T> {\n protected static readonly STORAGE_TYPE: StorageType = 'indexedDB'\n readonly type: StorageType = 'indexedDB'\n\n private readonly DB_NAME: string\n private readonly STORE_NAME: string\n private dbManager: IndexedDBManager\n\n constructor(config: IndexedDBStorageConfig<T>, eventEmitter?: IEventEmitter, logger?: ILogger) {\n super(config, eventEmitter, logger)\n\n this.DB_NAME = config.options?.dbName || 'app_storage'\n this.STORE_NAME = config.name\n\n // Get database manager instance (version is auto-detected internally)\n this.dbManager = IndexedDBManager.getInstance(this.DB_NAME, 1, logger)\n }\n\n static create<T extends Record<string, any>>(config: IndexedDBStorageConfig, eventEmitter?: IEventEmitter, logger?: ILogger): IndexedDBStorage<T> {\n return SingletonMixin.handleSingletonCreation(\n config,\n this.STORAGE_TYPE,\n (finalConfig) => new IndexedDBStorage<T>(finalConfig as IndexedDBStorageConfig<T>, eventEmitter, logger),\n logger,\n )\n }\n\n protected async doInitialize(): Promise<this> {\n try {\n this.logger?.debug(`Initializing IndexedDB storage \"${this.STORE_NAME}\"`)\n\n // Создаем store в базе данных\n await this.dbManager.ensureStoreExists(this.STORE_NAME)\n\n // Проверяем, что хранилище доступно\n const db = await this.dbManager.initialize()\n if (!db.objectStoreNames.contains(this.STORE_NAME)) {\n throw new Error(`Store \"${this.STORE_NAME}\" not found after initialization`)\n }\n\n // Инициализируем middleware\n this.initializeMiddlewares()\n\n // Инициализируем с middleware\n await this.initializeWithMiddlewares()\n\n this.logger?.debug(`IndexedDB storage \"${this.STORE_NAME}\" initialized successfully`)\n return this\n } catch (error) {\n this.logger?.error(`Ошибка инициализации IndexedDB \"${this.name}\"`, { error })\n throw error\n }\n }\n\n static async createStorages<S extends Record<string, any>>(\n dbName: string,\n configs: {\n [K in keyof S]: {\n name: string\n initialState?: S[K]\n middlewares?: ConfigureAsyncMiddlewares\n eventEmitter?: IEventEmitter\n }\n },\n logger?: ILogger,\n ): Promise<{ [K in keyof S]: IndexedDBStorage<S[K]> }> {\n // Используем единый IndexedDBManager (версия определяется автоматически)\n const dbManager = IndexedDBManager.getInstance(dbName, 1, logger)\n\n // Получаем имена всех хранилищ, которые нужно создать\n const storeNames = Object.values(configs).map((config) => config.name)\n\n // Предварительно создаем все хранилища в рамках одной операции\n await dbManager.ensureStoresExist(storeNames)\n\n // Создаем и инициализируем все хранилища\n const result: Record<string, IndexedDBStorage<any>> = {}\n\n for (const [key, config] of Object.entries(configs)) {\n const storage = new IndexedDBStorage(\n {\n ...config,\n options: { dbName },\n },\n config.eventEmitter,\n logger,\n )\n\n // Инициализируем хранилище\n result[key] = await storage.initialize()\n }\n\n return result as { [K in keyof S]: IndexedDBStorage<S[K]> }\n }\n\n // ─── IndexedDB-specific API ────────────────────────────────────────────────\n\n /**\n * Выполняет операцию в рамках IDB-транзакции.\n * Обёртка для низкоуровневого IDB transaction API.\n *\n * @param mode - Режим транзакции ('readonly' | 'readwrite')\n * @param fn - Callback, получающий IDBObjectStore. Возвращает результат операции.\n * @returns Promise с результатом callback-а\n */\n async transaction<R>(mode: IDBTransactionMode, fn: (store: IDBObjectStore) => IDBRequest<R> | R): Promise<R> {\n const store = await this.getObjectStore(mode)\n\n return new Promise<R>((resolve, reject) => {\n const tx = store.transaction\n\n tx.onerror = () => reject(tx.error)\n tx.onabort = () => reject(tx.error || new Error('Transaction aborted'))\n\n try {\n const result = fn(store)\n\n if (result instanceof IDBRequest) {\n result.onsuccess = () => resolve(result.result)\n result.onerror = () => reject(result.error)\n } else {\n // Sync result — resolve when transaction completes\n tx.oncomplete = () => resolve(result)\n }\n } catch (error) {\n reject(error)\n }\n })\n }\n\n /**\n * Текущая версия базы данных.\n */\n get dbVersion(): number {\n return this.dbManager.getCurrentVersion()\n }\n\n /**\n * Имя базы данных.\n */\n get dbName(): string {\n return this.DB_NAME\n }\n\n /**\n * Имя object store в IndexedDB.\n */\n get storeName(): string {\n return this.STORE_NAME\n }\n\n // ─── Private helpers ───────────────────────────────────────────────────────\n\n private async getTransaction(mode: IDBTransactionMode = 'readonly'): Promise<IDBTransaction> {\n try {\n // Ensure database is open and our store exists\n const db = await this.dbManager.ensureStoreExists(this.STORE_NAME)\n\n // Проверяем существование хранилища перед созданием транзакции\n if (!db.objectStoreNames.contains(this.STORE_NAME)) {\n // Попытка исправить проблему - закрываем и снова открываем\n this.logger?.warn(`Object store \"${this.STORE_NAME}\" not found, attempting to repair`)\n\n db.close()\n this.dbManager.closeDatabase()\n\n // Пробуем заново создать хранилище с инкрементом версии\n const newDb = await this.dbManager.ensureStoreExists(this.STORE_NAME)\n\n if (!newDb.objectStoreNames.contains(this.STORE_NAME)) {\n throw new Error(`Object store \"${this.STORE_NAME}\" still doesn't exist after repair attempt`)\n }\n\n return newDb.transaction(this.STORE_NAME, mode)\n }\n\n return db.transaction(this.STORE_NAME, mode)\n } catch (error) {\n this.logger?.error(`Failed to create transaction for store \"${this.STORE_NAME}\"`, { error })\n throw error\n }\n }\n\n private async getObjectStore(mode: IDBTransactionMode = 'readonly'): Promise<IDBObjectStore> {\n const transaction = await this.getTransaction(mode)\n return transaction.objectStore(this.STORE_NAME)\n }\n\n protected async doGet(key: StorageKeyType): Promise<any> {\n const store = await this.getObjectStore()\n\n // Для пустого ключа возвращаем все состояние\n if (key === '') {\n return new Promise((resolve, reject) => {\n const request = store.getAll()\n request.onerror = () => reject(request.error)\n request.onsuccess = () => {\n const allValues = request.result\n const allKeys = store.getAllKeys()\n\n allKeys.onsuccess = () => {\n const state = allKeys.result.reduce(\n (acc, k, index) => {\n if (k !== 'root' && k !== VERSION_META_KEY) {\n acc[k as string] = allValues[index]\n }\n return acc\n },\n {} as Record<string, any>,\n )\n resolve(state)\n }\n allKeys.onerror = () => reject(allKeys.error)\n }\n })\n }\n\n // Проверяем, является ли ключ \"сырым\"\n if (key instanceof StorageKey && key.isUnparseable()) {\n return new Promise((resolve, reject) => {\n const request = store.get(key.valueOf())\n request.onerror = () => reject(request.error)\n request.onsuccess = () => resolve(request.result)\n })\n }\n\n // Для вложенного пути\n const parts = parsePath(key)\n if (parts.length > 1) {\n const rootKey = parts[0]\n return new Promise((resolve, reject) => {\n const request = store.get(rootKey)\n request.onerror = () => reject(request.error)\n request.onsuccess = () => {\n const rootValue = request.result\n if (!rootValue) {\n resolve(undefined)\n return\n }\n const value = getValueByPath(rootValue, parts.slice(1).join('.'))\n resolve(value)\n }\n })\n }\n\n // Для простого ключа\n return new Promise((resolve, reject) => {\n const request = store.get(parts[0])\n request.onerror = () => reject(request.error)\n request.onsuccess = () => resolve(request.result)\n })\n }\n\n protected async doSet(key: StorageKeyType, value: any): Promise<void> {\n // Для пустого ключа устанавливаем все состояние\n if (key === '') {\n const store = await this.getObjectStore('readwrite')\n const preserveVersion = this.config.version !== undefined\n return new Promise((resolve, reject) => {\n const tx = store.transaction\n\n tx.oncomplete = () => {\n resolve()\n }\n\n tx.onerror = () => {\n reject(tx.error)\n }\n\n const writeEntries = () => {\n const entries = Object.entries(value)\n for (const [entryKey, entryValue] of entries) {\n if (entryKey === VERSION_META_KEY) continue\n store.put(entryValue, entryKey)\n }\n }\n\n // С persist-migration сохраняем reserved version-запись при перезаписи всего состояния.\n if (preserveVersion) {\n const keysReq = store.getAllKeys()\n keysReq.onerror = () => reject(keysReq.error)\n keysReq.onsuccess = () => {\n for (const k of keysReq.result) {\n if (k !== VERSION_META_KEY) store.delete(k)\n }\n writeEntries()\n }\n return\n }\n\n const clearRequest = store.clear()\n clearRequest.onsuccess = () => writeEntries()\n clearRequest.onerror = () => reject(clearRequest.error)\n })\n }\n\n const store = await this.getObjectStore('readwrite')\n\n // Для \"сырого\" ключа\n if (key instanceof StorageKey && key.isUnparseable()) {\n await this.putValueInStore(store, key.valueOf(), value)\n return\n }\n\n // Для вложенного пути\n const parts = parsePath(key)\n if (parts.length > 1) {\n const rootKey = parts[0]\n return new Promise((resolve, reject) => {\n const request = store.get(rootKey)\n request.onerror = () => reject(request.error)\n request.onsuccess = () => {\n const rootValue = request.result || {}\n const updatedValue = setValueByPath(rootValue, parts.slice(1).join('.'), value)\n const putRequest = store.put(updatedValue, rootKey)\n putRequest.onerror = () => reject(putRequest.error)\n putRequest.onsuccess = () => resolve()\n }\n })\n }\n\n // Для простого ключа\n await this.putValueInStore(store, parts[0], value)\n }\n\n private async putValueInStore(store: IDBObjectStore, key: StorageKeyType, value: any): Promise<void> {\n return new Promise((resolve, reject) => {\n const request = store.put(value, key.valueOf())\n request.onerror = () => reject(request.error)\n request.onsuccess = () => resolve()\n })\n }\n\n protected async doUpdate(updates: Array<{ key: string | StorageKey; value: any }>): Promise<void> {\n // Группируем обновления\n const updatesByRoot = new Map<string, Array<{ path: string[]; value: any }>>()\n const rawUpdates: Array<{ key: string; value: any }> = []\n\n // Разделяем обновления на \"сырые\" и обычные\n for (const { key, value } of updates) {\n if (key instanceof StorageKey && key.isUnparseable()) {\n rawUpdates.push({ key: key.valueOf(), value })\n continue\n }\n\n const parts = parsePath(key)\n const rootKey = parts[0]\n const path = parts.slice(1)\n\n if (!updatesByRoot.has(rootKey)) {\n updatesByRoot.set(rootKey, [])\n }\n updatesByRoot.get(rootKey)!.push({ path, value })\n }\n\n // Одна транзакция на весь doUpdate — атомарность\n const transaction = await this.getTransaction('readwrite')\n const store = transaction.objectStore(this.STORE_NAME)\n\n return new Promise<void>((resolve, reject) => {\n transaction.oncomplete = () => resolve()\n transaction.onerror = () => {\n this.logger?.error('Error during update:', { error: transaction.error })\n reject(transaction.error)\n }\n transaction.onabort = () => {\n this.logger?.error('Update transaction aborted:', { error: transaction.error })\n reject(transaction.error || new Error('Transaction aborted'))\n }\n\n // Обрабатываем \"сырые\" обновления\n for (const { key, value } of rawUpdates) {\n store.put(value, key)\n }\n\n // Обрабатываем сгруппированные обновления\n // Для каждого rootKey: читаем текущее значение, применяем все path-обновления, записываем обратно\n const rootKeys = Array.from(updatesByRoot.keys())\n\n if (rootKeys.length === 0) {\n // Нет сгруппированных обновлений — транзакция завершится сама\n return\n }\n\n for (const rootKey of rootKeys) {\n const getRequest = store.get(rootKey)\n\n getRequest.onsuccess = () => {\n const rootValue = getRequest.result || {}\n let updatedValue = { ...rootValue }\n const pathUpdates = updatesByRoot.get(rootKey)!\n\n for (const { path, value } of pathUpdates) {\n if (path.length === 0) {\n updatedValue = value\n } else {\n updatedValue = setValueByPath(updatedValue, path.join('.'), value)\n }\n }\n\n store.put(updatedValue, rootKey)\n }\n }\n })\n }\n\n protected async doDelete(key: StorageKeyType): Promise<boolean> {\n const store = await this.getObjectStore('readwrite')\n\n // Для \"сырого\" ключа\n if (key instanceof StorageKey && key.isUnparseable()) {\n return new Promise((resolve, reject) => {\n const request = store.delete(key.valueOf())\n request.onerror = () => reject(request.error)\n request.onsuccess = () => resolve(true)\n })\n }\n\n const parts = parsePath(key)\n\n // Для простого ключа\n if (parts.length === 1) {\n return new Promise((resolve, reject) => {\n const request = store.delete(parts[0])\n request.onerror = () => reject(request.error)\n request.onsuccess = () => resolve(true)\n })\n }\n\n // Для вложенного пути\n const rootKey = parts[0]\n return new Promise((resolve, reject) => {\n const getRequest = store.get(rootKey)\n getRequest.onerror = () => reject(getRequest.error)\n getRequest.onsuccess = () => {\n const rootValue = getRequest.result\n if (!rootValue) {\n resolve(false)\n return\n }\n\n // rootValue уже соответствует parts[0] (каждый top-level ключ — отдельная запись стора),\n // поэтому путь к родителю отсчитывается ВНУТРИ rootValue: parts.slice(1, -1) (ср. doGet).\n const innerParentPath = parts.slice(1, -1).join('.')\n const parent = innerParentPath ? getValueByPath(rootValue, innerParentPath) : rootValue\n const lastKey = parts[parts.length - 1]\n\n if (!parent || !(lastKey in parent)) {\n resolve(false)\n return\n }\n\n if (Array.isArray(parent)) {\n const index = parseInt(lastKey, 10)\n if (!isNaN(index)) {\n parent.splice(index, 1)\n } else {\n // @ts-ignore\n delete parent[lastKey]\n }\n } else {\n delete parent[lastKey]\n }\n\n const putRequest = store.put(rootValue, rootKey)\n putRequest.onerror = () => reject(putRequest.error)\n putRequest.onsuccess = () => resolve(true)\n }\n })\n }\n\n protected async doClear(): Promise<void> {\n const store = await this.getObjectStore('readwrite')\n\n // С persist-migration сохраняем reserved version-запись (она описывает схему, не данные).\n if (this.config.version !== undefined) {\n return new Promise((resolve, reject) => {\n const tx = store.transaction\n tx.oncomplete = () => resolve()\n tx.onerror = () => reject(tx.error)\n const keysReq = store.getAllKeys()\n keysReq.onerror = () => reject(keysReq.error)\n keysReq.onsuccess = () => {\n for (const k of keysReq.result) {\n if (k !== VERSION_META_KEY) store.delete(k)\n }\n }\n })\n }\n\n return new Promise((resolve, reject) => {\n const request = store.clear()\n request.onsuccess = () => resolve()\n request.onerror = () => reject(request.error)\n })\n }\n\n protected async doKeys(): Promise<string[]> {\n const store = await this.getObjectStore()\n const request = store.getAllKeys()\n return new Promise((resolve, reject) => {\n request.onsuccess = () => {\n resolve((request.result as string[]).filter((k) => k !== VERSION_META_KEY))\n }\n request.onerror = () => reject(request.error)\n })\n }\n\n // ─── Persisted schema version (persist-migration) ───────────────────────────\n\n protected async readPersistedVersion(): Promise<number | undefined> {\n const store = await this.getObjectStore()\n return new Promise((resolve) => {\n const request = store.get(VERSION_META_KEY)\n request.onsuccess = () => resolve(typeof request.result === 'number' ? request.result : undefined)\n request.onerror = () => resolve(undefined)\n })\n }\n\n protected async writePersistedVersion(version: number): Promise<void> {\n const store = await this.getObjectStore('readwrite')\n return new Promise((resolve, reject) => {\n const request = store.put(version, VERSION_META_KEY)\n request.onsuccess = () => resolve()\n request.onerror = () => reject(request.error)\n })\n }\n\n protected async doHas(key: StorageKeyType): Promise<boolean> {\n const value = await this.doGet(key)\n return value !== undefined\n }\n\n /**\n * Override performCleanup: persistent storage should NOT clear data on destroy.\n * Only clean up middleware and runtime resources, not persisted data.\n */\n protected async performCleanup(): Promise<void> {\n await this.doDestroy()\n }\n\n protected async doDestroy(): Promise<void> {\n // Persistent storage: do NOT clear data on destroy.\n // Only release runtime resources. Data persists across component lifecycles.\n }\n}\n"],"names":["SingletonMixin","StorageKey","AsyncBaseStorage","getValueByPath","parsePath","setValueByPath","VERSION_META_KEY","IndexedDBManager","Map","Set","Promise","dbName","dbVersion","logger","instance","currentVersion","resolve","request","indexedDB","version","storeName","operation","result","undefined","storeNames","db","missingStores","name","Array","newStores","reject","Error","i","event","IndexedDBStorage","config","eventEmitter","finalConfig","error","configs","dbManager","Object","key","storage","mode","fn","store","tx","IDBRequest","newDb","transaction","allValues","allKeys","state","acc","k","index","parts","rootKey","rootValue","value","preserveVersion","writeEntries","entries","entryKey","entryValue","keysReq","clearRequest","updatedValue","putRequest","updates","updatesByRoot","rawUpdates","path","rootKeys","getRequest","pathUpdates","innerParentPath","parent","lastKey","parseInt","isNaN"],"mappings":"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"}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import { ISyncPluginExecutor } from '../modules/plugin/plugin.interface';
|
|
2
1
|
import { IEventEmitter, ILogger, LocalStorageConfig, StorageType } from '../storage.interface';
|
|
3
2
|
import { StorageKeyType } from '../utils/storage-key';
|
|
4
3
|
import { SyncBaseStorage } from './sync-base-storage.service';
|
|
5
4
|
export declare class LocalStorage<T extends Record<string, any>> extends SyncBaseStorage<T> {
|
|
6
5
|
protected static readonly STORAGE_TYPE: StorageType;
|
|
7
6
|
readonly type: StorageType;
|
|
8
|
-
constructor(config: LocalStorageConfig<T>,
|
|
9
|
-
static create<T extends Record<string, any>>(config: LocalStorageConfig,
|
|
7
|
+
constructor(config: LocalStorageConfig<T>, eventEmitter?: IEventEmitter, logger?: ILogger);
|
|
8
|
+
static create<T extends Record<string, any>>(config: LocalStorageConfig, eventEmitter?: IEventEmitter, logger?: ILogger): LocalStorage<T>;
|
|
10
9
|
protected doInitialize(): Promise<this>;
|
|
11
10
|
protected doGet(key: StorageKeyType): any;
|
|
12
11
|
protected doSet(key: StorageKeyType, value: any): void;
|
|
@@ -18,6 +17,12 @@ export declare class LocalStorage<T extends Record<string, any>> extends SyncBas
|
|
|
18
17
|
protected doClear(): void;
|
|
19
18
|
protected doKeys(): string[];
|
|
20
19
|
protected doHas(key: StorageKeyType): boolean;
|
|
20
|
+
/** Персистентное хранилище: по умолчанию НЕ чистим данные на destroy (симметрично IndexedDB). */
|
|
21
|
+
protected get clearOnDestroyDefault(): boolean;
|
|
22
|
+
/** Версия схемы хранится отдельным sidecar-ключом, не засоряя сам state. */
|
|
23
|
+
private get versionStorageKey();
|
|
24
|
+
protected readPersistedVersion(): number | undefined;
|
|
25
|
+
protected writePersistedVersion(version: number): void;
|
|
26
|
+
protected clearPersistedVersion(): void;
|
|
21
27
|
protected doDestroy(): Promise<void>;
|
|
22
28
|
}
|
|
23
|
-
//# sourceMappingURL=local-storage.service.d.ts.map
|
|
@@ -14,11 +14,11 @@ import { SyncBaseStorage } from "./sync-base-storage.service.js";
|
|
|
14
14
|
class LocalStorage extends SyncBaseStorage {
|
|
15
15
|
static STORAGE_TYPE = 'localStorage';
|
|
16
16
|
type = 'localStorage';
|
|
17
|
-
constructor(config,
|
|
18
|
-
super(config,
|
|
17
|
+
constructor(config, eventEmitter, logger){
|
|
18
|
+
super(config, eventEmitter, logger);
|
|
19
19
|
}
|
|
20
|
-
static create(config,
|
|
21
|
-
return SingletonMixin.handleSingletonCreation(config, this.STORAGE_TYPE, (finalConfig)=>new LocalStorage(finalConfig,
|
|
20
|
+
static create(config, eventEmitter, logger) {
|
|
21
|
+
return SingletonMixin.handleSingletonCreation(config, this.STORAGE_TYPE, (finalConfig)=>new LocalStorage(finalConfig, eventEmitter, logger), logger);
|
|
22
22
|
}
|
|
23
23
|
async doInitialize() {
|
|
24
24
|
try {
|
|
@@ -101,8 +101,28 @@ class LocalStorage extends SyncBaseStorage {
|
|
|
101
101
|
const value = this.doGet(key);
|
|
102
102
|
return value !== undefined;
|
|
103
103
|
}
|
|
104
|
+
/** Персистентное хранилище: по умолчанию НЕ чистим данные на destroy (симметрично IndexedDB). */ get clearOnDestroyDefault() {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
// ─── Persisted schema version (persist-migration) ───────────────────────────
|
|
108
|
+
/** Версия схемы хранится отдельным sidecar-ключом, не засоряя сам state. */ get versionStorageKey() {
|
|
109
|
+
return `${this.name}::__synapse_version__`;
|
|
110
|
+
}
|
|
111
|
+
readPersistedVersion() {
|
|
112
|
+
const raw = localStorage.getItem(this.versionStorageKey);
|
|
113
|
+
if (raw == null) return undefined;
|
|
114
|
+
const parsed = Number(raw);
|
|
115
|
+
return Number.isFinite(parsed) ? parsed : undefined;
|
|
116
|
+
}
|
|
117
|
+
writePersistedVersion(version) {
|
|
118
|
+
localStorage.setItem(this.versionStorageKey, String(version));
|
|
119
|
+
}
|
|
120
|
+
clearPersistedVersion() {
|
|
121
|
+
localStorage.removeItem(this.versionStorageKey);
|
|
122
|
+
}
|
|
104
123
|
async doDestroy() {
|
|
105
|
-
|
|
124
|
+
// Персистентное хранилище: данные не стираются на destroy.
|
|
125
|
+
// Очистка управляется флагом config.clearOnDestroy в performCleanup.
|
|
106
126
|
}
|
|
107
127
|
}
|
|
108
128
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core/storage/adapters/local-storage.service.js","sources":["../../../../src/core/storage/adapters/local-storage.service.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"core/storage/adapters/local-storage.service.js","sources":["../../../../src/core/storage/adapters/local-storage.service.ts"],"sourcesContent":["import { SingletonMixin } from '../modules/singleton/mixin.util'\nimport { IEventEmitter, ILogger, LocalStorageConfig, 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 LocalStorage<T extends Record<string, any>> extends SyncBaseStorage<T> {\n protected static readonly STORAGE_TYPE: StorageType = 'localStorage'\n readonly type: StorageType = 'localStorage'\n\n constructor(config: LocalStorageConfig<T>, eventEmitter?: IEventEmitter, logger?: ILogger) {\n super(config, eventEmitter, logger)\n }\n\n static create<T extends Record<string, any>>(config: LocalStorageConfig, eventEmitter?: IEventEmitter, logger?: ILogger): LocalStorage<T> {\n return SingletonMixin.handleSingletonCreation(\n config,\n this.STORAGE_TYPE,\n (finalConfig) => new LocalStorage<T>(finalConfig as LocalStorageConfig<T>, eventEmitter, logger),\n logger,\n )\n }\n\n protected async doInitialize(): Promise<this> {\n try {\n this.logger?.debug(`Initializing LocalStorage \"${this.name}\"`)\n\n this.initializeMiddlewares()\n this.initializeWithMiddlewares()\n\n this.logger?.debug(`LocalStorage \"${this.name}\" initialized successfully`)\n return this\n } catch (error) {\n this.logger?.error('Error initializing LocalStorage', { error })\n throw error\n }\n }\n\n protected doGet(key: StorageKeyType): any {\n const storageData = localStorage.getItem(this.name)\n if (!storageData) return undefined\n\n const state = JSON.parse(storageData)\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 storageData = localStorage.getItem(this.name)\n const state = storageData ? JSON.parse(storageData) : {}\n\n if (key instanceof StorageKey && key.isUnparseable()) {\n state[key.valueOf()] = value\n localStorage.setItem(this.name, JSON.stringify(state))\n return\n }\n\n const newState = setValueByPath({ ...state }, key, value)\n localStorage.setItem(this.name, JSON.stringify(newState))\n }\n\n protected doRemove(key: StorageKeyType): boolean {\n const storageData = localStorage.getItem(this.name)\n if (!storageData) return false\n\n const state = JSON.parse(storageData)\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 localStorage.setItem(this.name, JSON.stringify(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\n const parent = parentPath ? getValueByPath(state, parentPath) : state\n\n if (!parent || !(lastKey in parent)) return false\n\n delete parent[lastKey]\n localStorage.setItem(this.name, JSON.stringify(state))\n return true\n }\n\n protected doUpdate(updates: Array<{ key: StorageKeyType; value: any }>): void {\n const storageData = localStorage.getItem(this.name)\n const state = storageData ? JSON.parse(storageData) : {}\n\n for (const { key, value } of updates) {\n if (key instanceof StorageKey && key.isUnparseable()) {\n state[key.valueOf()] = value\n } else {\n setValueByPath(state, key, value)\n }\n }\n\n localStorage.setItem(this.name, JSON.stringify(state))\n }\n\n protected doClear(): void {\n localStorage.removeItem(this.name)\n }\n\n protected doKeys(): string[] {\n const storageData = localStorage.getItem(this.name)\n if (!storageData) return []\n\n const state = JSON.parse(storageData)\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 /** Персистентное хранилище: по умолчанию НЕ чистим данные на destroy (симметрично IndexedDB). */\n protected get clearOnDestroyDefault(): boolean {\n return false\n }\n\n // ─── Persisted schema version (persist-migration) ───────────────────────────\n\n /** Версия схемы хранится отдельным sidecar-ключом, не засоряя сам state. */\n private get versionStorageKey(): string {\n return `${this.name}::__synapse_version__`\n }\n\n protected readPersistedVersion(): number | undefined {\n const raw = localStorage.getItem(this.versionStorageKey)\n if (raw == null) return undefined\n const parsed = Number(raw)\n return Number.isFinite(parsed) ? parsed : undefined\n }\n\n protected writePersistedVersion(version: number): void {\n localStorage.setItem(this.versionStorageKey, String(version))\n }\n\n protected clearPersistedVersion(): void {\n localStorage.removeItem(this.versionStorageKey)\n }\n\n protected async doDestroy(): Promise<void> {\n // Персистентное хранилище: данные не стираются на destroy.\n // Очистка управляется флагом config.clearOnDestroy в performCleanup.\n }\n}\n"],"names":["SingletonMixin","StorageKey","getValueByPath","parsePath","setValueByPath","SyncBaseStorage","LocalStorage","config","eventEmitter","logger","finalConfig","error","key","storageData","localStorage","undefined","state","JSON","value","newState","rawKey","pathParts","parentPath","lastKey","parent","updates","Object","raw","parsed","Number","version","String"],"mappings":"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"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { ISyncPluginExecutor } from '../modules/plugin/plugin.interface';
|
|
2
1
|
import { IEventEmitter, ILogger, MemoryStorageConfig, StorageType } from '../storage.interface';
|
|
3
2
|
import { StorageKeyType } from '../utils/storage-key';
|
|
4
3
|
import { SyncBaseStorage } from './sync-base-storage.service';
|
|
@@ -6,8 +5,8 @@ export declare class MemoryStorage<T extends Record<string, any>> extends SyncBa
|
|
|
6
5
|
protected static readonly STORAGE_TYPE: StorageType;
|
|
7
6
|
readonly type: StorageType;
|
|
8
7
|
private storage;
|
|
9
|
-
constructor(config: MemoryStorageConfig<T>,
|
|
10
|
-
static create<T extends Record<string, any>>(config: MemoryStorageConfig<T>,
|
|
8
|
+
constructor(config: MemoryStorageConfig<T>, eventEmitter?: IEventEmitter, logger?: ILogger);
|
|
9
|
+
static create<T extends Record<string, any>>(config: MemoryStorageConfig<T>, eventEmitter?: IEventEmitter, logger?: ILogger): MemoryStorage<T>;
|
|
11
10
|
protected doInitialize(): Promise<this>;
|
|
12
11
|
protected doGet(key: StorageKeyType): any;
|
|
13
12
|
protected doSet(key: StorageKeyType, value: any): void;
|
|
@@ -21,4 +20,3 @@ export declare class MemoryStorage<T extends Record<string, any>> extends SyncBa
|
|
|
21
20
|
protected doHas(key: StorageKeyType): boolean;
|
|
22
21
|
protected doDestroy(): Promise<void>;
|
|
23
22
|
}
|
|
24
|
-
//# sourceMappingURL=memory-storage.service.d.ts.map
|
|
@@ -15,11 +15,11 @@ class MemoryStorage extends SyncBaseStorage {
|
|
|
15
15
|
static STORAGE_TYPE = 'memory';
|
|
16
16
|
type = 'memory';
|
|
17
17
|
storage = new Map();
|
|
18
|
-
constructor(config,
|
|
19
|
-
super(config,
|
|
18
|
+
constructor(config, eventEmitter, logger){
|
|
19
|
+
super(config, eventEmitter, logger);
|
|
20
20
|
}
|
|
21
|
-
static create(config,
|
|
22
|
-
return SingletonMixin.handleSingletonCreation(config, this.STORAGE_TYPE, (finalConfig)=>new MemoryStorage(finalConfig,
|
|
21
|
+
static create(config, eventEmitter, logger) {
|
|
22
|
+
return SingletonMixin.handleSingletonCreation(config, this.STORAGE_TYPE, (finalConfig)=>new MemoryStorage(finalConfig, eventEmitter, logger), logger);
|
|
23
23
|
}
|
|
24
24
|
async doInitialize() {
|
|
25
25
|
try {
|
|
@@ -101,7 +101,7 @@ class MemoryStorage extends SyncBaseStorage {
|
|
|
101
101
|
return value !== undefined;
|
|
102
102
|
}
|
|
103
103
|
async doDestroy() {
|
|
104
|
-
|
|
104
|
+
// Очистка управляется флагом config.clearOnDestroy в performCleanup (memory → по умолчанию true).
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
|