synapse-storage 3.0.19 → 4.0.1
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 +28 -168
- package/dist/_utils/chunk.util.d.ts +8 -0
- package/dist/_utils/chunk.util.d.ts.map +1 -0
- package/dist/_utils/chunk.util.js +21 -0
- package/dist/_utils/chunk.util.js.map +1 -0
- package/dist/_utils/deepMerge.util.d.ts +2 -0
- package/dist/_utils/deepMerge.util.d.ts.map +1 -0
- package/dist/_utils/deepMerge.util.js +19 -0
- package/dist/_utils/deepMerge.util.js.map +1 -0
- package/dist/_utils/error-handling.util.d.ts +50 -0
- package/dist/_utils/error-handling.util.d.ts.map +1 -0
- package/dist/_utils/error-handling.util.js +67 -0
- package/dist/_utils/error-handling.util.js.map +1 -0
- package/dist/_utils/flatMap.util.d.ts +10 -0
- package/dist/_utils/flatMap.util.d.ts.map +1 -0
- package/dist/_utils/flatMap.util.js +23 -0
- package/dist/_utils/flatMap.util.js.map +1 -0
- package/dist/_utils/index.d.ts +6 -0
- package/dist/_utils/index.d.ts.map +1 -0
- package/dist/_utils/index.js +13 -0
- package/dist/_utils/index.js.map +1 -0
- package/dist/_utils/logger-console.util.d.ts +9 -0
- package/dist/_utils/logger-console.util.d.ts.map +1 -0
- package/dist/_utils/logger-console.util.js +14 -0
- package/dist/_utils/logger-console.util.js.map +1 -0
- package/dist/api/api.module.d.ts +46 -0
- package/dist/api/api.module.d.ts.map +1 -0
- package/dist/api/api.module.js +121 -0
- package/dist/api/api.module.js.map +1 -0
- package/dist/api/components/endpoint.d.ts +57 -0
- package/dist/api/components/endpoint.d.ts.map +1 -0
- package/dist/api/components/endpoint.js +385 -0
- package/dist/api/components/endpoint.js.map +1 -0
- package/dist/api/components/query-storage.d.ts +100 -0
- package/dist/api/components/query-storage.d.ts.map +1 -0
- package/dist/api/components/query-storage.js +293 -0
- package/dist/api/components/query-storage.js.map +1 -0
- package/dist/api/example.d.ts +83 -0
- package/dist/api/example.d.ts.map +1 -0
- package/dist/api/example.js +90 -0
- package/dist/api/example.js.map +1 -0
- package/dist/api/index.d.ts +4 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +11 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/types/api.interface.d.ts +126 -0
- package/dist/api/types/api.interface.d.ts.map +1 -0
- package/dist/api/types/api.interface.js +15 -0
- package/dist/api/types/api.interface.js.map +1 -0
- package/dist/api/types/endpoint.interface.d.ts +118 -0
- package/dist/api/types/endpoint.interface.d.ts.map +1 -0
- package/dist/api/types/endpoint.interface.js +6 -0
- package/dist/api/types/endpoint.interface.js.map +1 -0
- package/dist/api/types/query.interface.d.ts +85 -0
- package/dist/api/types/query.interface.d.ts.map +1 -0
- package/dist/api/types/query.interface.js +6 -0
- package/dist/api/types/query.interface.js.map +1 -0
- package/dist/api/utils/api-helpers.d.ts +22 -0
- package/dist/api/utils/api-helpers.d.ts.map +1 -0
- package/dist/api/utils/api-helpers.js +44 -0
- package/dist/api/utils/api-helpers.js.map +1 -0
- package/dist/api/utils/create-header-context.d.ts +10 -0
- package/dist/api/utils/create-header-context.d.ts.map +1 -0
- package/dist/api/utils/create-header-context.js +40 -0
- package/dist/api/utils/create-header-context.js.map +1 -0
- package/dist/api/utils/endpoint-headers.d.ts +23 -0
- package/dist/api/utils/endpoint-headers.d.ts.map +1 -0
- package/dist/api/utils/endpoint-headers.js +61 -0
- package/dist/api/utils/endpoint-headers.js.map +1 -0
- package/dist/api/utils/fetch-base-query.d.ts +9 -0
- package/dist/api/utils/fetch-base-query.d.ts.map +1 -0
- package/dist/api/utils/fetch-base-query.js +242 -0
- package/dist/api/utils/fetch-base-query.js.map +1 -0
- package/dist/api/utils/file-utils.d.ts +43 -0
- package/dist/api/utils/file-utils.d.ts.map +1 -0
- package/dist/api/utils/file-utils.js +102 -0
- package/dist/api/utils/file-utils.js.map +1 -0
- package/dist/api/utils/get-cacheable-headers.d.ts +8 -0
- package/dist/api/utils/get-cacheable-headers.d.ts.map +1 -0
- package/dist/api/utils/get-cacheable-headers.js +23 -0
- package/dist/api/utils/get-cacheable-headers.js.map +1 -0
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +7 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/selector/index.d.ts +3 -0
- package/dist/core/selector/index.d.ts.map +1 -0
- package/dist/core/selector/index.js +5 -0
- package/dist/core/selector/index.js.map +1 -0
- package/dist/{selector.interface-CA5y-kD_.d.ts → core/selector/selector.interface.d.ts} +41 -8
- package/dist/core/selector/selector.interface.d.ts.map +1 -0
- package/dist/core/selector/selector.interface.js +7 -0
- package/dist/core/selector/selector.interface.js.map +1 -0
- package/dist/core/selector/selector.module.d.ts +36 -0
- package/dist/core/selector/selector.module.d.ts.map +1 -0
- package/dist/core/selector/selector.module.js +412 -0
- package/dist/core/selector/selector.module.js.map +1 -0
- package/dist/core/storage/adapters/async-base-storage.service.d.ts +49 -0
- package/dist/core/storage/adapters/async-base-storage.service.d.ts.map +1 -0
- package/dist/core/storage/adapters/async-base-storage.service.js +505 -0
- package/dist/core/storage/adapters/async-base-storage.service.js.map +1 -0
- package/dist/core/storage/adapters/indexed-DB.service.d.ts +89 -0
- package/dist/core/storage/adapters/indexed-DB.service.d.ts.map +1 -0
- package/dist/core/storage/adapters/indexed-DB.service.js +596 -0
- package/dist/core/storage/adapters/indexed-DB.service.js.map +1 -0
- package/dist/core/storage/adapters/local-storage.service.d.ts +23 -0
- package/dist/core/storage/adapters/local-storage.service.d.ts.map +1 -0
- package/dist/core/storage/adapters/local-storage.service.js +111 -0
- package/dist/core/storage/adapters/local-storage.service.js.map +1 -0
- package/dist/core/storage/adapters/memory-storage.service.d.ts +24 -0
- package/dist/core/storage/adapters/memory-storage.service.d.ts.map +1 -0
- package/dist/core/storage/adapters/memory-storage.service.js +110 -0
- package/dist/core/storage/adapters/memory-storage.service.js.map +1 -0
- package/dist/core/storage/adapters/path.utils.d.ts +5 -0
- package/dist/core/storage/adapters/path.utils.d.ts.map +1 -0
- package/dist/core/storage/adapters/path.utils.js +42 -0
- package/dist/core/storage/adapters/path.utils.js.map +1 -0
- package/dist/core/storage/adapters/storage-core.d.ts +61 -0
- package/dist/core/storage/adapters/storage-core.d.ts.map +1 -0
- package/dist/core/storage/adapters/storage-core.js +221 -0
- package/dist/core/storage/adapters/storage-core.js.map +1 -0
- package/dist/core/storage/adapters/sync-base-storage.service.d.ts +56 -0
- package/dist/core/storage/adapters/sync-base-storage.service.d.ts.map +1 -0
- package/dist/core/storage/adapters/sync-base-storage.service.js +481 -0
- package/dist/core/storage/adapters/sync-base-storage.service.js.map +1 -0
- package/dist/core/storage/index.d.ts +16 -0
- package/dist/core/storage/index.d.ts.map +1 -0
- package/dist/core/storage/index.js +38 -0
- package/dist/core/storage/index.js.map +1 -0
- package/dist/core/storage/middlewares/broadcast.middleware.d.ts +9 -0
- package/dist/core/storage/middlewares/broadcast.middleware.d.ts.map +1 -0
- package/dist/core/storage/middlewares/broadcast.middleware.js +197 -0
- package/dist/core/storage/middlewares/broadcast.middleware.js.map +1 -0
- package/dist/core/storage/middlewares/index.d.ts +9 -0
- package/dist/core/storage/middlewares/index.d.ts.map +1 -0
- package/dist/core/storage/middlewares/index.js +17 -0
- package/dist/core/storage/middlewares/index.js.map +1 -0
- package/dist/core/storage/middlewares/storage-batching.middleware.d.ts +7 -0
- package/dist/core/storage/middlewares/storage-batching.middleware.d.ts.map +1 -0
- package/dist/core/storage/middlewares/storage-batching.middleware.js +108 -0
- package/dist/core/storage/middlewares/storage-batching.middleware.js.map +1 -0
- package/dist/core/storage/middlewares/storage-shallow-compare.middleware.d.ts +7 -0
- package/dist/core/storage/middlewares/storage-shallow-compare.middleware.d.ts.map +1 -0
- package/dist/core/storage/middlewares/storage-shallow-compare.middleware.js +43 -0
- package/dist/core/storage/middlewares/storage-shallow-compare.middleware.js.map +1 -0
- package/dist/core/storage/middlewares/sync-broadcast.middleware.d.ts +9 -0
- package/dist/core/storage/middlewares/sync-broadcast.middleware.d.ts.map +1 -0
- package/dist/core/storage/middlewares/sync-broadcast.middleware.js +177 -0
- package/dist/core/storage/middlewares/sync-broadcast.middleware.js.map +1 -0
- package/dist/core/storage/middlewares/sync-storage-batching.middleware.d.ts +6 -0
- package/dist/core/storage/middlewares/sync-storage-batching.middleware.d.ts.map +1 -0
- package/dist/core/storage/middlewares/sync-storage-batching.middleware.js +56 -0
- package/dist/core/storage/middlewares/sync-storage-batching.middleware.js.map +1 -0
- package/dist/core/storage/middlewares/sync-storage-shallow-compare.middleware.d.ts +7 -0
- package/dist/core/storage/middlewares/sync-storage-shallow-compare.middleware.d.ts.map +1 -0
- package/dist/core/storage/middlewares/sync-storage-shallow-compare.middleware.js +39 -0
- package/dist/core/storage/middlewares/sync-storage-shallow-compare.middleware.js.map +1 -0
- package/dist/core/storage/modules/plugin/plugin.interface.d.ts +101 -0
- package/dist/core/storage/modules/plugin/plugin.interface.d.ts.map +1 -0
- package/dist/core/storage/modules/plugin/plugin.interface.js +8 -0
- package/dist/core/storage/modules/plugin/plugin.interface.js.map +1 -0
- package/dist/core/storage/modules/plugin/plugin.service.d.ts +49 -0
- package/dist/core/storage/modules/plugin/plugin.service.d.ts.map +1 -0
- package/dist/core/storage/modules/plugin/plugin.service.js +406 -0
- package/dist/core/storage/modules/plugin/plugin.service.js.map +1 -0
- package/dist/core/storage/modules/singleton/mixin.util.d.ts +6 -0
- package/dist/core/storage/modules/singleton/mixin.util.d.ts.map +1 -0
- package/dist/core/storage/modules/singleton/mixin.util.js +30 -0
- package/dist/core/storage/modules/singleton/mixin.util.js.map +1 -0
- package/dist/core/storage/modules/singleton/models.d.ts +143 -0
- package/dist/core/storage/modules/singleton/models.d.ts.map +1 -0
- package/dist/core/storage/modules/singleton/models.js +60 -0
- package/dist/core/storage/modules/singleton/models.js.map +1 -0
- package/dist/core/storage/modules/singleton/singleton.util.d.ts +36 -0
- package/dist/core/storage/modules/singleton/singleton.util.d.ts.map +1 -0
- package/dist/core/storage/modules/singleton/singleton.util.js +216 -0
- package/dist/core/storage/modules/singleton/singleton.util.js.map +1 -0
- package/dist/core/storage/storage.interface.d.ts +168 -0
- package/dist/core/storage/storage.interface.d.ts.map +1 -0
- package/dist/core/storage/storage.interface.js +23 -0
- package/dist/core/storage/storage.interface.js.map +1 -0
- package/dist/core/storage/utils/broadcast.util.d.ts +49 -0
- package/dist/core/storage/utils/broadcast.util.d.ts.map +1 -0
- package/dist/core/storage/utils/broadcast.util.js +141 -0
- package/dist/core/storage/utils/broadcast.util.js.map +1 -0
- package/dist/core/storage/utils/cache.util.d.ts +33 -0
- package/dist/core/storage/utils/cache.util.d.ts.map +1 -0
- package/dist/core/storage/utils/cache.util.js +54 -0
- package/dist/core/storage/utils/cache.util.js.map +1 -0
- package/dist/core/storage/utils/middleware-module.d.ts +94 -0
- package/dist/core/storage/utils/middleware-module.d.ts.map +1 -0
- package/dist/core/storage/utils/middleware-module.js +258 -0
- package/dist/core/storage/utils/middleware-module.js.map +1 -0
- package/dist/core/storage/utils/path-selector.util.d.ts +15 -0
- package/dist/core/storage/utils/path-selector.util.d.ts.map +1 -0
- package/dist/core/storage/utils/path-selector.util.js +58 -0
- package/dist/core/storage/utils/path-selector.util.js.map +1 -0
- package/dist/core/storage/utils/state-diff.util.d.ts +14 -0
- package/dist/core/storage/utils/state-diff.util.d.ts.map +1 -0
- package/dist/core/storage/utils/state-diff.util.js +88 -0
- package/dist/core/storage/utils/state-diff.util.js.map +1 -0
- package/dist/core/storage/utils/storage-factory.util.d.ts +21 -0
- package/dist/core/storage/utils/storage-factory.util.d.ts.map +1 -0
- package/dist/core/storage/utils/storage-factory.util.js +40 -0
- package/dist/core/storage/utils/storage-factory.util.js.map +1 -0
- package/dist/core/storage/utils/storage-key.d.ts +11 -0
- package/dist/core/storage/utils/storage-key.d.ts.map +1 -0
- package/dist/core/storage/utils/storage-key.js +24 -0
- package/dist/core/storage/utils/storage-key.js.map +1 -0
- package/dist/core/storage/utils/storage.utils.d.ts +17 -0
- package/dist/core/storage/utils/storage.utils.d.ts.map +1 -0
- package/dist/core/storage/utils/storage.utils.js +57 -0
- package/dist/core/storage/utils/storage.utils.js.map +1 -0
- package/dist/index.d.ts +10 -12
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -1
- package/dist/index.js.map +1 -0
- package/dist/react/hooks/index.d.ts +5 -0
- package/dist/react/hooks/index.d.ts.map +1 -0
- package/dist/react/hooks/index.js +11 -0
- package/dist/react/hooks/index.js.map +1 -0
- package/dist/react/hooks/useCreateStorage.d.ts +39 -0
- package/dist/react/hooks/useCreateStorage.d.ts.map +1 -0
- package/dist/react/hooks/useCreateStorage.js +137 -0
- package/dist/react/hooks/useCreateStorage.js.map +1 -0
- package/dist/react/hooks/useSelector.d.ts +21 -0
- package/dist/react/hooks/useSelector.d.ts.map +1 -0
- package/dist/react/hooks/useSelector.js +56 -0
- package/dist/react/hooks/useSelector.js.map +1 -0
- package/dist/react/hooks/useStorage.d.ts +39 -0
- package/dist/react/hooks/useStorage.d.ts.map +1 -0
- package/dist/react/hooks/useStorage.js +78 -0
- package/dist/react/hooks/useStorage.js.map +1 -0
- package/dist/react/hooks/useStorageSubscribe.d.ts +16 -0
- package/dist/react/hooks/useStorageSubscribe.d.ts.map +1 -0
- package/dist/react/hooks/useStorageSubscribe.js +55 -0
- package/dist/react/hooks/useStorageSubscribe.js.map +1 -0
- package/dist/react/index.d.ts +3 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +7 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/utils/awaitSynapse.d.ts +34 -0
- package/dist/react/utils/awaitSynapse.d.ts.map +1 -0
- package/dist/react/utils/awaitSynapse.js +87 -0
- package/dist/react/utils/awaitSynapse.js.map +1 -0
- package/dist/react/utils/createSynapseCtx.d.ts +33 -0
- package/dist/react/utils/createSynapseCtx.d.ts.map +1 -0
- package/dist/react/utils/createSynapseCtx.js +139 -0
- package/dist/react/utils/createSynapseCtx.js.map +1 -0
- package/dist/react/utils/index.d.ts +3 -0
- package/dist/react/utils/index.d.ts.map +1 -0
- package/dist/react/utils/index.js +9 -0
- package/dist/react/utils/index.js.map +1 -0
- package/dist/reactive/dispatcher/dispatcher.module.d.ts +216 -0
- package/dist/reactive/dispatcher/dispatcher.module.d.ts.map +1 -0
- package/dist/reactive/dispatcher/dispatcher.module.js +384 -0
- package/dist/reactive/dispatcher/dispatcher.module.js.map +1 -0
- package/dist/reactive/dispatcher/index.d.ts +4 -0
- package/dist/reactive/dispatcher/index.d.ts.map +1 -0
- package/dist/reactive/dispatcher/index.js +9 -0
- package/dist/reactive/dispatcher/index.js.map +1 -0
- package/dist/reactive/dispatcher/middlewares/index.d.ts +2 -0
- package/dist/reactive/dispatcher/middlewares/index.d.ts.map +1 -0
- package/dist/reactive/dispatcher/middlewares/index.js +5 -0
- package/dist/reactive/dispatcher/middlewares/index.js.map +1 -0
- package/dist/reactive/dispatcher/middlewares/logger.middleware.d.ts +37 -0
- package/dist/reactive/dispatcher/middlewares/logger.middleware.d.ts.map +1 -0
- package/dist/reactive/dispatcher/middlewares/logger.middleware.js +188 -0
- package/dist/reactive/dispatcher/middlewares/logger.middleware.js.map +1 -0
- package/dist/reactive/dispatcher/standalone.d.ts +112 -0
- package/dist/reactive/dispatcher/standalone.d.ts.map +1 -0
- package/dist/reactive/dispatcher/standalone.js +142 -0
- package/dist/reactive/dispatcher/standalone.js.map +1 -0
- package/dist/reactive/effects/effects.module.d.ts +225 -0
- package/dist/reactive/effects/effects.module.d.ts.map +1 -0
- package/dist/reactive/effects/effects.module.js +356 -0
- package/dist/reactive/effects/effects.module.js.map +1 -0
- package/dist/reactive/effects/index.d.ts +4 -0
- package/dist/reactive/effects/index.d.ts.map +1 -0
- package/dist/reactive/effects/index.js +11 -0
- package/dist/reactive/effects/index.js.map +1 -0
- package/dist/reactive/effects/utils/chunkRequestConsistent.d.ts +12 -0
- package/dist/reactive/effects/utils/chunkRequestConsistent.d.ts.map +1 -0
- package/dist/reactive/effects/utils/chunkRequestConsistent.js +25 -0
- package/dist/reactive/effects/utils/chunkRequestConsistent.js.map +1 -0
- package/dist/reactive/effects/utils/chunkRequestParallel.d.ts +12 -0
- package/dist/reactive/effects/utils/chunkRequestParallel.d.ts.map +1 -0
- package/dist/reactive/effects/utils/chunkRequestParallel.js +22 -0
- package/dist/reactive/effects/utils/chunkRequestParallel.js.map +1 -0
- package/dist/reactive/effects/utils/fromRequest.d.ts +40 -0
- package/dist/reactive/effects/utils/fromRequest.d.ts.map +1 -0
- package/dist/reactive/effects/utils/fromRequest.js +64 -0
- package/dist/reactive/effects/utils/fromRequest.js.map +1 -0
- package/dist/reactive/effects/utils/index.d.ts +5 -0
- package/dist/reactive/effects/utils/index.d.ts.map +1 -0
- package/dist/reactive/effects/utils/index.js +11 -0
- package/dist/reactive/effects/utils/index.js.map +1 -0
- package/dist/reactive/effects/utils/toObservable.d.ts +23 -0
- package/dist/reactive/effects/utils/toObservable.d.ts.map +1 -0
- package/dist/reactive/effects/utils/toObservable.js +39 -0
- package/dist/reactive/effects/utils/toObservable.js.map +1 -0
- package/dist/reactive/index.d.ts +3 -0
- package/dist/reactive/index.d.ts.map +1 -0
- package/dist/reactive/index.js +7 -0
- package/dist/reactive/index.js.map +1 -0
- package/dist/utils/createEventBus.d.ts +87 -0
- package/dist/utils/createEventBus.d.ts.map +1 -0
- package/dist/utils/createEventBus.js +215 -0
- package/dist/utils/createEventBus.js.map +1 -0
- package/dist/utils/createSynapse/createSynapse.d.ts +9 -0
- package/dist/utils/createSynapse/createSynapse.d.ts.map +1 -0
- package/dist/utils/createSynapse/createSynapse.js +103 -0
- package/dist/utils/createSynapse/createSynapse.js.map +1 -0
- package/dist/utils/createSynapse/index.d.ts +3 -0
- package/dist/utils/createSynapse/index.d.ts.map +1 -0
- package/dist/utils/createSynapse/index.js +6 -0
- package/dist/utils/createSynapse/index.js.map +1 -0
- package/dist/utils/createSynapse/types.d.ts +93 -0
- package/dist/utils/createSynapse/types.d.ts.map +1 -0
- package/dist/utils/createSynapse/types.js +6 -0
- package/dist/utils/createSynapse/types.js.map +1 -0
- package/dist/utils/createSynapse/validate.d.ts +2 -0
- package/dist/utils/createSynapse/validate.d.ts.map +1 -0
- package/dist/utils/createSynapse/validate.js +76 -0
- package/dist/utils/createSynapse/validate.js.map +1 -0
- package/dist/utils/createSynapse/waitForDependencies.d.ts +3 -0
- package/dist/utils/createSynapse/waitForDependencies.d.ts.map +1 -0
- package/dist/utils/createSynapse/waitForDependencies.js +40 -0
- package/dist/utils/createSynapse/waitForDependencies.js.map +1 -0
- package/dist/utils/createSynapseAwaiter.d.ts +46 -0
- package/dist/utils/createSynapseAwaiter.d.ts.map +1 -0
- package/dist/utils/createSynapseAwaiter.js +102 -0
- package/dist/utils/createSynapseAwaiter.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +12 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +17 -21
- package/dist/api.d.ts +0 -365
- package/dist/api.js +0 -1
- package/dist/core.d.ts +0 -106
- package/dist/core.js +0 -1
- package/dist/createSynapse-vkfKjRob.d.ts +0 -97
- package/dist/dispatcher.module-BOsMHbD5.d.ts +0 -360
- package/dist/react.d.ts +0 -119
- package/dist/react.js +0 -1
- package/dist/reactive.d.ts +0 -35
- package/dist/reactive.js +0 -1
- package/dist/storage.interface-BA_ktyDz.d.ts +0 -591
- package/dist/utils.d.ts +0 -139
- package/dist/utils.js +0 -1
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { IStorage, StorageKeyType } from '../../core';
|
|
2
|
+
import { CacheConfig, CreateApiClientOptions, StorageOption } from '../types/api.interface';
|
|
3
|
+
import { EndpointConfig } from '../types/endpoint.interface';
|
|
4
|
+
import { QueryOptions } from '../types/query.interface';
|
|
5
|
+
/**
|
|
6
|
+
* Менеджер хранилища для API
|
|
7
|
+
* Объединяет в себе функционал хранилища и управления кэшем
|
|
8
|
+
*/
|
|
9
|
+
export declare class QueryStorage {
|
|
10
|
+
private readonly storageExternal;
|
|
11
|
+
private readonly globalCacheConfig;
|
|
12
|
+
/** Экземпляр хранилища */
|
|
13
|
+
private storage;
|
|
14
|
+
private cleanupInterval;
|
|
15
|
+
/** Индекс тегов: tag → Set<cacheKey> для быстрой инвалидации */
|
|
16
|
+
private tagIndex;
|
|
17
|
+
/** Настройки кэша по умолчанию */
|
|
18
|
+
private defaultCacheOptions;
|
|
19
|
+
/** Флаг завершённой инициализации */
|
|
20
|
+
private _initialized;
|
|
21
|
+
/** Промис текущей инициализации */
|
|
22
|
+
private _initPromise;
|
|
23
|
+
constructor(storageExternal: StorageOption, globalCacheConfig: CreateApiClientOptions['cache']);
|
|
24
|
+
initialize(): Promise<this>;
|
|
25
|
+
private _doInitialize;
|
|
26
|
+
private createStorage;
|
|
27
|
+
private startCleanupInterval;
|
|
28
|
+
/**
|
|
29
|
+
* Получает экземпляр хранилища
|
|
30
|
+
*/
|
|
31
|
+
getStorage(): IStorage | null;
|
|
32
|
+
/**
|
|
33
|
+
* Создает ключ кэша для запроса с учетом заголовков
|
|
34
|
+
* @param endpoint Имя эндпоинта
|
|
35
|
+
* @param params Параметры запроса (все что посчитаем нужным)
|
|
36
|
+
*/
|
|
37
|
+
createCacheKey<CacheParams extends Record<string, any>>(endpoint: string, params: CacheParams): [StorageKeyType, Record<string, any> | undefined];
|
|
38
|
+
/**
|
|
39
|
+
* Получает результат запроса из кэша
|
|
40
|
+
*/
|
|
41
|
+
getCachedResult<T>(cacheKey: StorageKeyType): Promise<T | undefined>;
|
|
42
|
+
/**
|
|
43
|
+
* Сохраняет результат запроса в кэш
|
|
44
|
+
* @param cacheKey Ключ кэша
|
|
45
|
+
* @param data Данные для кэширования
|
|
46
|
+
* @param cacheOptions Метаданные
|
|
47
|
+
* @param cacheParams Параметры которые влияли на создание ключа
|
|
48
|
+
* @param tags Тэги эндпоинта
|
|
49
|
+
*/
|
|
50
|
+
setCachedResult<T, CacheParams extends Record<string, any>>(cacheKey: StorageKeyType, data: T, cacheOptions: Exclude<CacheConfig, boolean>, cacheParams: CacheParams, tags: string[]): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Проверяет, должен ли запрос быть кэширован
|
|
53
|
+
* @param endpointConfig Конфигурация эндпоинта
|
|
54
|
+
* @param options Опции запроса
|
|
55
|
+
* @param method HTTP-метод запроса (только GET кэшируется по REST-стандарту)
|
|
56
|
+
* @returns true если запрос должен кэшироваться
|
|
57
|
+
*/
|
|
58
|
+
shouldCache(endpointConfig?: EndpointConfig, options?: QueryOptions, method?: string): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Создает итоговую конфигурацию кэширования для конкретного эндпоинта
|
|
61
|
+
* Объединяет глобальный конфиг с текущим
|
|
62
|
+
* @param endpointConfig Конфигурация эндпоинта
|
|
63
|
+
*/
|
|
64
|
+
createCacheConfig(endpointConfig?: EndpointConfig): {
|
|
65
|
+
ttl?: number;
|
|
66
|
+
cleanup?: {
|
|
67
|
+
enabled: boolean;
|
|
68
|
+
interval?: number;
|
|
69
|
+
};
|
|
70
|
+
invalidateOnError?: boolean;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Инвалидирует кэш по тегам (использует индекс для O(1) поиска по тегу)
|
|
74
|
+
* @param tags Теги для инвалидации
|
|
75
|
+
*/
|
|
76
|
+
invalidateCacheByTags(tags: string[]): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* Инвалидирует кэш по ключу
|
|
79
|
+
* @param cacheKey Ключ кэша
|
|
80
|
+
*/
|
|
81
|
+
invalidateCache(cacheKey: StorageKeyType): Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* Выполняет очистку всех просроченных записей кэша
|
|
84
|
+
*/
|
|
85
|
+
cleanup(): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* Уничтожает хранилище и освобождает ресурсы
|
|
88
|
+
*/
|
|
89
|
+
destroy(): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* Перестраивает индекс тегов из существующих записей в storage
|
|
92
|
+
* Вызывается при инициализации для восстановления после перезагрузки
|
|
93
|
+
*/
|
|
94
|
+
private rebuildTagIndex;
|
|
95
|
+
/**
|
|
96
|
+
* Удаляет ключ из индекса тегов
|
|
97
|
+
*/
|
|
98
|
+
private removeKeyFromTagIndex;
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=query-storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-storage.d.ts","sourceRoot":"","sources":["../../../src/api/components/query-storage.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAErD,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAC3F,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAEvD;;;GAGG;AACH,qBAAa,YAAY;IA0BrB,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IA1BpC,0BAA0B;IAC1B,OAAO,CAAC,OAAO,CAAwB;IAEvC,OAAO,CAAC,eAAe,CAAuC;IAE9D,gEAAgE;IAChE,OAAO,CAAC,QAAQ,CAAiC;IAEjD,kCAAkC;IAClC,OAAO,CAAC,mBAAmB,CAO1B;IAED,qCAAqC;IACrC,OAAO,CAAC,YAAY,CAAQ;IAE5B,mCAAmC;IACnC,OAAO,CAAC,YAAY,CAA6B;gBAG9B,eAAe,EAAE,aAAa,EAC9B,iBAAiB,EAAE,sBAAsB,CAAC,OAAO,CAAC;IAGxD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YAQ1B,aAAa;YAiBb,aAAa;IAY3B,OAAO,CAAC,oBAAoB;IAiB5B;;OAEG;IACI,UAAU,IAAI,QAAQ,GAAG,IAAI;IAIpC;;;;OAIG;IACI,cAAc,CAAC,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW;IAIpG;;OAEG;IACU,eAAe,CAAC,CAAC,EAAE,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAuBjF;;;;;;;OAOG;IACU,eAAe,CAAC,CAAC,EAAE,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACrE,QAAQ,EAAE,cAAc,EACxB,IAAI,EAAE,CAAC,EACP,YAAY,EAAE,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,EAC3C,WAAW,EAAE,WAAW,EACxB,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,IAAI,CAAC;IA2BhB;;;;;;OAMG;IACI,WAAW,CAAC,cAAc,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,MAAM;IAiB3F;;;;OAIG;IACI,iBAAiB,CAAC,cAAc,CAAC,EAAE,cAAc;;;;oBAvLpD,CAAN;;;;IA2ME;;;OAGG;IACU,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBjE;;;OAGG;IACU,eAAe,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAYrE;;OAEG;IACU,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAerC;;OAEG;IACU,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAqBrC;;;OAGG;YACW,eAAe;IA4B7B;;OAEG;IACH,OAAO,CAAC,qBAAqB;CAU9B"}
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import { handleCleanupError, handleOperationError } from "../../_utils/error-handling.util.js";
|
|
2
|
+
import { CacheUtils } from "../../core/storage/utils/cache.util.js";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Менеджер хранилища для API
|
|
10
|
+
* Объединяет в себе функционал хранилища и управления кэшем
|
|
11
|
+
*/ class QueryStorage {
|
|
12
|
+
storageExternal;
|
|
13
|
+
globalCacheConfig;
|
|
14
|
+
/** Экземпляр хранилища */ storage = null;
|
|
15
|
+
cleanupInterval = null;
|
|
16
|
+
/** Индекс тегов: tag → Set<cacheKey> для быстрой инвалидации */ tagIndex = new Map();
|
|
17
|
+
/** Настройки кэша по умолчанию */ defaultCacheOptions = {
|
|
18
|
+
ttl: 5 * 60 * 1000,
|
|
19
|
+
cleanup: {
|
|
20
|
+
enabled: true,
|
|
21
|
+
interval: 10 * 60 * 1000
|
|
22
|
+
},
|
|
23
|
+
invalidateOnError: true
|
|
24
|
+
};
|
|
25
|
+
/** Флаг завершённой инициализации */ _initialized = false;
|
|
26
|
+
/** Промис текущей инициализации */ _initPromise = null;
|
|
27
|
+
constructor(storageExternal, globalCacheConfig){
|
|
28
|
+
this.storageExternal = storageExternal;
|
|
29
|
+
this.globalCacheConfig = globalCacheConfig;
|
|
30
|
+
}
|
|
31
|
+
async initialize() {
|
|
32
|
+
if (this._initialized) return this;
|
|
33
|
+
if (this._initPromise) return this._initPromise;
|
|
34
|
+
this._initPromise = this._doInitialize();
|
|
35
|
+
return this._initPromise;
|
|
36
|
+
}
|
|
37
|
+
async _doInitialize() {
|
|
38
|
+
try {
|
|
39
|
+
// 1. Создаем хранилище
|
|
40
|
+
await this.createStorage();
|
|
41
|
+
// 2. Перестраиваем индекс тегов из существующих записей в storage
|
|
42
|
+
await this.rebuildTagIndex();
|
|
43
|
+
// 3. Запускаем периодическую очистку, если это указано в настройках
|
|
44
|
+
this.startCleanupInterval();
|
|
45
|
+
this._initialized = true;
|
|
46
|
+
return this;
|
|
47
|
+
} catch (error) {
|
|
48
|
+
this._initPromise = null;
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async createStorage() {
|
|
53
|
+
try {
|
|
54
|
+
// Резолвим storage: может быть инстанс или фабрика
|
|
55
|
+
const s = typeof this.storageExternal === 'function' ? await this.storageExternal() : this.storageExternal;
|
|
56
|
+
await s.initialize();
|
|
57
|
+
this.storage = s;
|
|
58
|
+
} catch (error) {
|
|
59
|
+
handleOperationError('QueryStorage: storage initialization error', error);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
startCleanupInterval() {
|
|
63
|
+
if (this.cleanupInterval) {
|
|
64
|
+
clearInterval(this.cleanupInterval);
|
|
65
|
+
this.cleanupInterval = null;
|
|
66
|
+
}
|
|
67
|
+
// Получаем настройки очистки
|
|
68
|
+
const cleanupConfig = typeof this.globalCacheConfig === 'object' ? this.globalCacheConfig.cleanup : this.defaultCacheOptions.cleanup;
|
|
69
|
+
// Запускаем интервал очистки, если он включен
|
|
70
|
+
if (cleanupConfig?.enabled && cleanupConfig.interval) {
|
|
71
|
+
this.cleanupInterval = setInterval(()=>{
|
|
72
|
+
this.cleanup().catch((err)=>handleCleanupError('QueryStorage: cache cleanup error', err));
|
|
73
|
+
}, cleanupConfig.interval);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Получает экземпляр хранилища
|
|
78
|
+
*/ getStorage() {
|
|
79
|
+
return this.storage;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Создает ключ кэша для запроса с учетом заголовков
|
|
83
|
+
* @param endpoint Имя эндпоинта
|
|
84
|
+
* @param params Параметры запроса (все что посчитаем нужным)
|
|
85
|
+
*/ createCacheKey(endpoint, params) {
|
|
86
|
+
return CacheUtils.createApiKey(endpoint, params);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Получает результат запроса из кэша
|
|
90
|
+
*/ async getCachedResult(cacheKey) {
|
|
91
|
+
if (!this.storage) throw new Error('Хранилище не инициализировано');
|
|
92
|
+
const cachedEntry = await this.storage.get(cacheKey);
|
|
93
|
+
if (!cachedEntry) return undefined;
|
|
94
|
+
// Проверяем срок годности кэша
|
|
95
|
+
if (CacheUtils.isExpired(cachedEntry.metadata)) {
|
|
96
|
+
this.removeKeyFromTagIndex(String(cacheKey), cachedEntry.metadata.tags);
|
|
97
|
+
await this.storage.remove(cacheKey);
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
// Обновляем метаданные кэша (счетчик доступа, время обновления)
|
|
101
|
+
const updatedEntry = {
|
|
102
|
+
...cachedEntry,
|
|
103
|
+
metadata: CacheUtils.updateMetadata(cachedEntry.metadata)
|
|
104
|
+
};
|
|
105
|
+
await this.storage.set(cacheKey, updatedEntry);
|
|
106
|
+
return cachedEntry.data;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Сохраняет результат запроса в кэш
|
|
110
|
+
* @param cacheKey Ключ кэша
|
|
111
|
+
* @param data Данные для кэширования
|
|
112
|
+
* @param cacheOptions Метаданные
|
|
113
|
+
* @param cacheParams Параметры которые влияли на создание ключа
|
|
114
|
+
* @param tags Тэги эндпоинта
|
|
115
|
+
*/ async setCachedResult(cacheKey, data, cacheOptions, cacheParams, tags) {
|
|
116
|
+
if (!this.storage) throw new Error('Хранилище не инициализировано');
|
|
117
|
+
// Создаем метаданные кэша
|
|
118
|
+
const cacheMetadata = CacheUtils.createMetadata(cacheOptions.ttl, tags);
|
|
119
|
+
// Создаем запись кэша
|
|
120
|
+
const cacheEntry = {
|
|
121
|
+
data,
|
|
122
|
+
metadata: cacheMetadata,
|
|
123
|
+
params: cacheParams
|
|
124
|
+
};
|
|
125
|
+
await this.storage.set(cacheKey, cacheEntry);
|
|
126
|
+
// Обновляем индекс тегов
|
|
127
|
+
const keyStr = String(cacheKey);
|
|
128
|
+
for (const tag of tags){
|
|
129
|
+
let keys = this.tagIndex.get(tag);
|
|
130
|
+
if (!keys) {
|
|
131
|
+
keys = new Set();
|
|
132
|
+
this.tagIndex.set(tag, keys);
|
|
133
|
+
}
|
|
134
|
+
keys.add(keyStr);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Проверяет, должен ли запрос быть кэширован
|
|
139
|
+
* @param endpointConfig Конфигурация эндпоинта
|
|
140
|
+
* @param options Опции запроса
|
|
141
|
+
* @param method HTTP-метод запроса (только GET кэшируется по REST-стандарту)
|
|
142
|
+
* @returns true если запрос должен кэшироваться
|
|
143
|
+
*/ shouldCache(endpointConfig, options, method) {
|
|
144
|
+
// Мутации (POST/PUT/DELETE/PATCH) не кэшируются по REST-стандарту
|
|
145
|
+
if (method && method !== 'GET') return false;
|
|
146
|
+
// Если глобальный кэш отключен, возвращаем false
|
|
147
|
+
if (this.globalCacheConfig === false) return false;
|
|
148
|
+
// Если эндпоинт явно отключает кэш, возвращаем false
|
|
149
|
+
if (endpointConfig?.cache === false) return false;
|
|
150
|
+
// Если по какой то причине указали время кэша 0
|
|
151
|
+
if (typeof endpointConfig?.cache === 'object' && endpointConfig?.cache.ttl === 0) return false;
|
|
152
|
+
// Если при вызове самого запроса явно указали НЕ кэшировать
|
|
153
|
+
if (options?.disableCache === true) return false;
|
|
154
|
+
// Если настройки нигде не указаны - по умолчанию НЕ кэшируем
|
|
155
|
+
if (this.globalCacheConfig === undefined && endpointConfig?.cache === undefined) return false;
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Создает итоговую конфигурацию кэширования для конкретного эндпоинта
|
|
160
|
+
* Объединяет глобальный конфиг с текущим
|
|
161
|
+
* @param endpointConfig Конфигурация эндпоинта
|
|
162
|
+
*/ createCacheConfig(endpointConfig) {
|
|
163
|
+
// Создаем опции по умолчанию
|
|
164
|
+
let resultConfig = this.defaultCacheOptions;
|
|
165
|
+
// Если в глобальном конфиге кэш передан как объект а не boolean - по умолчанию станет он
|
|
166
|
+
if (typeof this.globalCacheConfig === 'object') {
|
|
167
|
+
resultConfig = this.globalCacheConfig;
|
|
168
|
+
}
|
|
169
|
+
// Если в настройках эндпоинта кэш как объект - дополняем этими параметрами итоговый объект кэша
|
|
170
|
+
if (typeof endpointConfig?.cache === 'object') {
|
|
171
|
+
const endpointCache = endpointConfig.cache;
|
|
172
|
+
resultConfig = {
|
|
173
|
+
...resultConfig,
|
|
174
|
+
...endpointCache
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
return resultConfig;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Инвалидирует кэш по тегам (использует индекс для O(1) поиска по тегу)
|
|
181
|
+
* @param tags Теги для инвалидации
|
|
182
|
+
*/ async invalidateCacheByTags(tags) {
|
|
183
|
+
if (!this.storage) throw new Error('Хранилище не инициализировано');
|
|
184
|
+
// Собираем все ключи для удаления через индекс
|
|
185
|
+
const keysToRemove = new Set();
|
|
186
|
+
for (const tag of tags){
|
|
187
|
+
const keys = this.tagIndex.get(tag);
|
|
188
|
+
if (keys) {
|
|
189
|
+
keys.forEach((k)=>keysToRemove.add(k));
|
|
190
|
+
this.tagIndex.delete(tag);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
// Удаляем из остальных тегов индекса (ключ может быть в нескольких тегах)
|
|
194
|
+
for (const key of keysToRemove){
|
|
195
|
+
for (const [tag, keys] of this.tagIndex){
|
|
196
|
+
keys.delete(key);
|
|
197
|
+
if (keys.size === 0) this.tagIndex.delete(tag);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
// Удаляем записи из хранилища
|
|
201
|
+
await Promise.all([
|
|
202
|
+
...keysToRemove
|
|
203
|
+
].map((key)=>this.storage.remove(key)));
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Инвалидирует кэш по ключу
|
|
207
|
+
* @param cacheKey Ключ кэша
|
|
208
|
+
*/ async invalidateCache(cacheKey) {
|
|
209
|
+
if (!this.storage) throw new Error('Хранилище не инициализировано');
|
|
210
|
+
// Читаем теги записи для очистки индекса
|
|
211
|
+
const cachedEntry = await this.storage.get(cacheKey);
|
|
212
|
+
if (cachedEntry) {
|
|
213
|
+
this.removeKeyFromTagIndex(String(cacheKey), cachedEntry.metadata.tags);
|
|
214
|
+
}
|
|
215
|
+
await this.storage.remove(cacheKey);
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Выполняет очистку всех просроченных записей кэша
|
|
219
|
+
*/ async cleanup() {
|
|
220
|
+
if (!this.storage) {
|
|
221
|
+
throw new Error('Хранилище не инициализировано');
|
|
222
|
+
}
|
|
223
|
+
const keys = await this.storage.keys();
|
|
224
|
+
for (const key of keys){
|
|
225
|
+
const value = await this.storage.get(key);
|
|
226
|
+
if (value && CacheUtils.isExpired(value.metadata)) {
|
|
227
|
+
this.removeKeyFromTagIndex(String(key), value.metadata.tags);
|
|
228
|
+
await this.storage.remove(key);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Уничтожает хранилище и освобождает ресурсы
|
|
234
|
+
*/ async destroy() {
|
|
235
|
+
// Останавливаем интервал очистки
|
|
236
|
+
if (this.cleanupInterval) {
|
|
237
|
+
globalThis.clearInterval(this.cleanupInterval);
|
|
238
|
+
this.cleanupInterval = null;
|
|
239
|
+
}
|
|
240
|
+
// Очищаем индекс тегов
|
|
241
|
+
this.tagIndex.clear();
|
|
242
|
+
// Очищаем хранилище
|
|
243
|
+
if (this.storage) {
|
|
244
|
+
await this.storage.destroy();
|
|
245
|
+
this.storage = null;
|
|
246
|
+
}
|
|
247
|
+
// Сбрасываем состояние инициализации
|
|
248
|
+
this._initialized = false;
|
|
249
|
+
this._initPromise = null;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Перестраивает индекс тегов из существующих записей в storage
|
|
253
|
+
* Вызывается при инициализации для восстановления после перезагрузки
|
|
254
|
+
*/ async rebuildTagIndex() {
|
|
255
|
+
if (!this.storage) return;
|
|
256
|
+
this.tagIndex.clear();
|
|
257
|
+
const keys = await this.storage.keys();
|
|
258
|
+
for (const key of keys){
|
|
259
|
+
const entry = await this.storage.get(key);
|
|
260
|
+
if (!entry?.metadata?.tags) continue;
|
|
261
|
+
// Удаляем протухшие записи сразу
|
|
262
|
+
if (CacheUtils.isExpired(entry.metadata)) {
|
|
263
|
+
await this.storage.remove(key);
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
const keyStr = String(key);
|
|
267
|
+
for (const tag of entry.metadata.tags){
|
|
268
|
+
let tagKeys = this.tagIndex.get(tag);
|
|
269
|
+
if (!tagKeys) {
|
|
270
|
+
tagKeys = new Set();
|
|
271
|
+
this.tagIndex.set(tag, tagKeys);
|
|
272
|
+
}
|
|
273
|
+
tagKeys.add(keyStr);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Удаляет ключ из индекса тегов
|
|
279
|
+
*/ removeKeyFromTagIndex(key, tags) {
|
|
280
|
+
if (!tags) return;
|
|
281
|
+
for (const tag of tags){
|
|
282
|
+
const keys = this.tagIndex.get(tag);
|
|
283
|
+
if (keys) {
|
|
284
|
+
keys.delete(key);
|
|
285
|
+
if (keys.size === 0) this.tagIndex.delete(tag);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
export { QueryStorage };
|
|
292
|
+
|
|
293
|
+
//# sourceMappingURL=query-storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api/components/query-storage.js","sources":["../../../src/api/components/query-storage.ts"],"sourcesContent":["import { handleCleanupError, handleOperationError } from '../../_utils/error-handling.util'\nimport { IStorage, StorageKeyType } from '../../core'\nimport { CacheEntry, CacheUtils } from '../../core/storage/utils/cache.util'\nimport { CacheConfig, CreateApiClientOptions, StorageOption } from '../types/api.interface'\nimport { EndpointConfig } from '../types/endpoint.interface'\nimport { QueryOptions } from '../types/query.interface'\n\n/**\n * Менеджер хранилища для API\n * Объединяет в себе функционал хранилища и управления кэшем\n */\nexport class QueryStorage {\n /** Экземпляр хранилища */\n private storage: IStorage | null = null\n\n private cleanupInterval: NodeJS.Timeout | number | null = null\n\n /** Индекс тегов: tag → Set<cacheKey> для быстрой инвалидации */\n private tagIndex = new Map<string, Set<string>>()\n\n /** Настройки кэша по умолчанию */\n private defaultCacheOptions: Exclude<CacheConfig, boolean> = {\n ttl: 5 * 60 * 1000, // 5 минут по умолчанию\n cleanup: {\n enabled: true,\n interval: 10 * 60 * 1000, // 10 минут\n },\n invalidateOnError: true,\n }\n\n /** Флаг завершённой инициализации */\n private _initialized = false\n\n /** Промис текущей инициализации */\n private _initPromise: Promise<this> | null = null\n\n constructor(\n private readonly storageExternal: StorageOption,\n private readonly globalCacheConfig: CreateApiClientOptions['cache'],\n ) {}\n\n public async initialize(): Promise<this> {\n if (this._initialized) return this\n if (this._initPromise) return this._initPromise\n\n this._initPromise = this._doInitialize()\n return this._initPromise\n }\n\n private async _doInitialize(): Promise<this> {\n try {\n // 1. Создаем хранилище\n await this.createStorage()\n // 2. Перестраиваем индекс тегов из существующих записей в storage\n await this.rebuildTagIndex()\n // 3. Запускаем периодическую очистку, если это указано в настройках\n this.startCleanupInterval()\n\n this._initialized = true\n return this\n } catch (error) {\n this._initPromise = null\n throw error\n }\n }\n\n private async createStorage() {\n try {\n // Резолвим storage: может быть инстанс или фабрика\n const s: IStorage = typeof this.storageExternal === 'function' ? await this.storageExternal() : this.storageExternal\n\n await s.initialize()\n this.storage = s\n } catch (error) {\n handleOperationError('QueryStorage: storage initialization error', error)\n }\n }\n\n private startCleanupInterval(): void {\n if (this.cleanupInterval) {\n clearInterval(this.cleanupInterval)\n this.cleanupInterval = null\n }\n\n // Получаем настройки очистки\n const cleanupConfig = typeof this.globalCacheConfig === 'object' ? this.globalCacheConfig.cleanup : this.defaultCacheOptions.cleanup\n\n // Запускаем интервал очистки, если он включен\n if (cleanupConfig?.enabled && cleanupConfig.interval) {\n this.cleanupInterval = setInterval(() => {\n this.cleanup().catch((err) => handleCleanupError('QueryStorage: cache cleanup error', err))\n }, cleanupConfig.interval)\n }\n }\n\n /**\n * Получает экземпляр хранилища\n */\n public getStorage(): IStorage | null {\n return this.storage\n }\n\n /**\n * Создает ключ кэша для запроса с учетом заголовков\n * @param endpoint Имя эндпоинта\n * @param params Параметры запроса (все что посчитаем нужным)\n */\n public createCacheKey<CacheParams extends Record<string, any>>(endpoint: string, params: CacheParams) {\n return CacheUtils.createApiKey(endpoint, params)\n }\n\n /**\n * Получает результат запроса из кэша\n */\n public async getCachedResult<T>(cacheKey: StorageKeyType): Promise<T | undefined> {\n if (!this.storage) throw new Error('Хранилище не инициализировано')\n\n const cachedEntry = await this.storage.get<CacheEntry<T>>(cacheKey)\n if (!cachedEntry) return undefined\n\n // Проверяем срок годности кэша\n if (CacheUtils.isExpired(cachedEntry.metadata)) {\n this.removeKeyFromTagIndex(String(cacheKey), cachedEntry.metadata.tags)\n await this.storage.remove(cacheKey)\n return undefined\n }\n\n // Обновляем метаданные кэша (счетчик доступа, время обновления)\n const updatedEntry: CacheEntry<T> = {\n ...cachedEntry,\n metadata: CacheUtils.updateMetadata(cachedEntry.metadata),\n }\n await this.storage.set(cacheKey, updatedEntry)\n\n return cachedEntry.data\n }\n\n /**\n * Сохраняет результат запроса в кэш\n * @param cacheKey Ключ кэша\n * @param data Данные для кэширования\n * @param cacheOptions Метаданные\n * @param cacheParams Параметры которые влияли на создание ключа\n * @param tags Тэги эндпоинта\n */\n public async setCachedResult<T, CacheParams extends Record<string, any>>(\n cacheKey: StorageKeyType,\n data: T,\n cacheOptions: Exclude<CacheConfig, boolean>,\n cacheParams: CacheParams,\n tags: string[],\n ): Promise<void> {\n if (!this.storage) throw new Error('Хранилище не инициализировано')\n\n // Создаем метаданные кэша\n const cacheMetadata = CacheUtils.createMetadata(cacheOptions.ttl, tags)\n\n // Создаем запись кэша\n const cacheEntry: CacheEntry<T> = {\n data,\n metadata: cacheMetadata,\n params: cacheParams,\n }\n\n await this.storage.set(cacheKey, cacheEntry)\n\n // Обновляем индекс тегов\n const keyStr = String(cacheKey)\n for (const tag of tags) {\n let keys = this.tagIndex.get(tag)\n if (!keys) {\n keys = new Set()\n this.tagIndex.set(tag, keys)\n }\n keys.add(keyStr)\n }\n }\n\n /**\n * Проверяет, должен ли запрос быть кэширован\n * @param endpointConfig Конфигурация эндпоинта\n * @param options Опции запроса\n * @param method HTTP-метод запроса (только GET кэшируется по REST-стандарту)\n * @returns true если запрос должен кэшироваться\n */\n public shouldCache(endpointConfig?: EndpointConfig, options?: QueryOptions, method?: string) {\n // Мутации (POST/PUT/DELETE/PATCH) не кэшируются по REST-стандарту\n if (method && method !== 'GET') return false\n // Если глобальный кэш отключен, возвращаем false\n if (this.globalCacheConfig === false) return false\n // Если эндпоинт явно отключает кэш, возвращаем false\n if (endpointConfig?.cache === false) return false\n // Если по какой то причине указали время кэша 0\n if (typeof endpointConfig?.cache === 'object' && endpointConfig?.cache.ttl === 0) return false\n // Если при вызове самого запроса явно указали НЕ кэшировать\n if (options?.disableCache === true) return false\n // Если настройки нигде не указаны - по умолчанию НЕ кэшируем\n if (this.globalCacheConfig === undefined && endpointConfig?.cache === undefined) return false\n\n return true\n }\n\n /**\n * Создает итоговую конфигурацию кэширования для конкретного эндпоинта\n * Объединяет глобальный конфиг с текущим\n * @param endpointConfig Конфигурация эндпоинта\n */\n public createCacheConfig(endpointConfig?: EndpointConfig) {\n // Создаем опции по умолчанию\n let resultConfig = this.defaultCacheOptions\n\n // Если в глобальном конфиге кэш передан как объект а не boolean - по умолчанию станет он\n if (typeof this.globalCacheConfig === 'object') {\n resultConfig = this.globalCacheConfig\n }\n // Если в настройках эндпоинта кэш как объект - дополняем этими параметрами итоговый объект кэша\n if (typeof endpointConfig?.cache === 'object') {\n const endpointCache = endpointConfig.cache as Exclude<CacheConfig, boolean>\n resultConfig = {\n ...resultConfig,\n ...endpointCache,\n }\n }\n\n return resultConfig\n }\n\n /**\n * Инвалидирует кэш по тегам (использует индекс для O(1) поиска по тегу)\n * @param tags Теги для инвалидации\n */\n public async invalidateCacheByTags(tags: string[]): Promise<void> {\n if (!this.storage) throw new Error('Хранилище не инициализировано')\n\n // Собираем все ключи для удаления через индекс\n const keysToRemove = new Set<string>()\n for (const tag of tags) {\n const keys = this.tagIndex.get(tag)\n if (keys) {\n keys.forEach((k) => keysToRemove.add(k))\n this.tagIndex.delete(tag)\n }\n }\n\n // Удаляем из остальных тегов индекса (ключ может быть в нескольких тегах)\n for (const key of keysToRemove) {\n for (const [tag, keys] of this.tagIndex) {\n keys.delete(key)\n if (keys.size === 0) this.tagIndex.delete(tag)\n }\n }\n\n // Удаляем записи из хранилища\n await Promise.all([...keysToRemove].map((key) => this.storage!.remove(key)))\n }\n\n /**\n * Инвалидирует кэш по ключу\n * @param cacheKey Ключ кэша\n */\n public async invalidateCache(cacheKey: StorageKeyType): Promise<void> {\n if (!this.storage) throw new Error('Хранилище не инициализировано')\n\n // Читаем теги записи для очистки индекса\n const cachedEntry = await this.storage.get<CacheEntry<any>>(cacheKey)\n if (cachedEntry) {\n this.removeKeyFromTagIndex(String(cacheKey), cachedEntry.metadata.tags)\n }\n\n await this.storage.remove(cacheKey)\n }\n\n /**\n * Выполняет очистку всех просроченных записей кэша\n */\n public async cleanup(): Promise<void> {\n if (!this.storage) {\n throw new Error('Хранилище не инициализировано')\n }\n\n const keys = await this.storage.keys()\n for (const key of keys) {\n const value = await this.storage.get<CacheEntry<any>>(key)\n if (value && CacheUtils.isExpired(value.metadata)) {\n this.removeKeyFromTagIndex(String(key), value.metadata.tags)\n await this.storage.remove(key)\n }\n }\n }\n\n /**\n * Уничтожает хранилище и освобождает ресурсы\n */\n public async destroy(): Promise<void> {\n // Останавливаем интервал очистки\n if (this.cleanupInterval) {\n globalThis.clearInterval(this.cleanupInterval)\n this.cleanupInterval = null\n }\n\n // Очищаем индекс тегов\n this.tagIndex.clear()\n\n // Очищаем хранилище\n if (this.storage) {\n await this.storage.destroy()\n this.storage = null\n }\n\n // Сбрасываем состояние инициализации\n this._initialized = false\n this._initPromise = null\n }\n\n /**\n * Перестраивает индекс тегов из существующих записей в storage\n * Вызывается при инициализации для восстановления после перезагрузки\n */\n private async rebuildTagIndex(): Promise<void> {\n if (!this.storage) return\n\n this.tagIndex.clear()\n const keys = await this.storage.keys()\n\n for (const key of keys) {\n const entry = await this.storage.get<CacheEntry<any>>(key)\n if (!entry?.metadata?.tags) continue\n\n // Удаляем протухшие записи сразу\n if (CacheUtils.isExpired(entry.metadata)) {\n await this.storage.remove(key)\n continue\n }\n\n const keyStr = String(key)\n for (const tag of entry.metadata.tags) {\n let tagKeys = this.tagIndex.get(tag)\n if (!tagKeys) {\n tagKeys = new Set()\n this.tagIndex.set(tag, tagKeys)\n }\n tagKeys.add(keyStr)\n }\n }\n }\n\n /**\n * Удаляет ключ из индекса тегов\n */\n private removeKeyFromTagIndex(key: string, tags?: string[]): void {\n if (!tags) return\n for (const tag of tags) {\n const keys = this.tagIndex.get(tag)\n if (keys) {\n keys.delete(key)\n if (keys.size === 0) this.tagIndex.delete(tag)\n }\n }\n }\n}\n"],"names":["handleCleanupError","handleOperationError","CacheUtils","QueryStorage","Map","storageExternal","globalCacheConfig","error","s","clearInterval","cleanupConfig","setInterval","err","endpoint","params","cacheKey","Error","cachedEntry","undefined","String","updatedEntry","data","cacheOptions","cacheParams","tags","cacheMetadata","cacheEntry","keyStr","tag","keys","Set","endpointConfig","options","method","resultConfig","endpointCache","keysToRemove","k","key","Promise","value","globalThis","entry","tagKeys"],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { ApiClient } from './api.module';
|
|
2
|
+
export interface PokemonListResponse {
|
|
3
|
+
count: number;
|
|
4
|
+
next: string | null;
|
|
5
|
+
previous: string | null;
|
|
6
|
+
results: {
|
|
7
|
+
name: string;
|
|
8
|
+
url: string;
|
|
9
|
+
}[];
|
|
10
|
+
}
|
|
11
|
+
export interface PokemonDetails {
|
|
12
|
+
id: number;
|
|
13
|
+
name: string;
|
|
14
|
+
height: number;
|
|
15
|
+
weight: number;
|
|
16
|
+
sprites: {
|
|
17
|
+
front_default: string;
|
|
18
|
+
back_default: string;
|
|
19
|
+
other?: {
|
|
20
|
+
'official-artwork'?: {
|
|
21
|
+
front_default: string;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
types: {
|
|
26
|
+
slot: number;
|
|
27
|
+
type: {
|
|
28
|
+
name: string;
|
|
29
|
+
url: string;
|
|
30
|
+
};
|
|
31
|
+
}[];
|
|
32
|
+
abilities: {
|
|
33
|
+
ability: {
|
|
34
|
+
name: string;
|
|
35
|
+
url: string;
|
|
36
|
+
};
|
|
37
|
+
is_hidden: boolean;
|
|
38
|
+
slot: number;
|
|
39
|
+
}[];
|
|
40
|
+
stats: {
|
|
41
|
+
base_stat: number;
|
|
42
|
+
effort: number;
|
|
43
|
+
stat: {
|
|
44
|
+
name: string;
|
|
45
|
+
url: string;
|
|
46
|
+
};
|
|
47
|
+
}[];
|
|
48
|
+
}
|
|
49
|
+
export interface PokemonSearchParams {
|
|
50
|
+
limit?: number;
|
|
51
|
+
offset?: number;
|
|
52
|
+
}
|
|
53
|
+
export declare const api: ApiClient<(create: import("./types/endpoint.interface").CreateEndpoint) => Promise<{
|
|
54
|
+
updatePokemonById: import("./types/endpoint.interface").EndpointConfig<{
|
|
55
|
+
id: number;
|
|
56
|
+
}, PokemonDetails>;
|
|
57
|
+
getPokemonById: import("./types/endpoint.interface").EndpointConfig<{
|
|
58
|
+
id: number;
|
|
59
|
+
}, PokemonDetails>;
|
|
60
|
+
getPokemonList: import("./types/endpoint.interface").EndpointConfig<PokemonSearchParams, PokemonListResponse>;
|
|
61
|
+
}>>;
|
|
62
|
+
export declare const pokemonApi: ApiClient<(create: import("./types/endpoint.interface").CreateEndpoint) => Promise<{
|
|
63
|
+
updatePokemonById: import("./types/endpoint.interface").EndpointConfig<{
|
|
64
|
+
id: number;
|
|
65
|
+
}, PokemonDetails>;
|
|
66
|
+
getPokemonById: import("./types/endpoint.interface").EndpointConfig<{
|
|
67
|
+
id: number;
|
|
68
|
+
}, PokemonDetails>;
|
|
69
|
+
getPokemonList: import("./types/endpoint.interface").EndpointConfig<PokemonSearchParams, PokemonListResponse>;
|
|
70
|
+
}>>;
|
|
71
|
+
export declare const pokemonEndpoints: {
|
|
72
|
+
updatePokemonById: import("./types/endpoint.interface").Endpoint<{
|
|
73
|
+
id: number;
|
|
74
|
+
}, PokemonDetails>;
|
|
75
|
+
getPokemonById: import("./types/endpoint.interface").Endpoint<{
|
|
76
|
+
id: number;
|
|
77
|
+
}, PokemonDetails>;
|
|
78
|
+
getPokemonList: import("./types/endpoint.interface").Endpoint<PokemonSearchParams, PokemonListResponse>;
|
|
79
|
+
};
|
|
80
|
+
export declare const getPokemonById: (params: {
|
|
81
|
+
id: number;
|
|
82
|
+
}, options?: import("./types/query.interface").QueryOptions) => import("./types/endpoint.interface").RequestResponseModify<PokemonDetails, any>;
|
|
83
|
+
//# sourceMappingURL=example.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"example.d.ts","sourceRoot":"","sources":["../../src/api/example.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAIxC,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAA;QACZ,GAAG,EAAE,MAAM,CAAA;KACZ,EAAE,CAAA;CACJ;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE;QACP,aAAa,EAAE,MAAM,CAAA;QACrB,YAAY,EAAE,MAAM,CAAA;QACpB,KAAK,CAAC,EAAE;YACN,kBAAkB,CAAC,EAAE;gBACnB,aAAa,EAAE,MAAM,CAAA;aACtB,CAAA;SACF,CAAA;KACF,CAAA;IACD,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE;YACJ,IAAI,EAAE,MAAM,CAAA;YACZ,GAAG,EAAE,MAAM,CAAA;SACZ,CAAA;KACF,EAAE,CAAA;IACH,SAAS,EAAE;QACT,OAAO,EAAE;YACP,IAAI,EAAE,MAAM,CAAA;YACZ,GAAG,EAAE,MAAM,CAAA;SACZ,CAAA;QACD,SAAS,EAAE,OAAO,CAAA;QAClB,IAAI,EAAE,MAAM,CAAA;KACb,EAAE,CAAA;IACH,KAAK,EAAE;QACL,SAAS,EAAE,MAAM,CAAA;QACjB,MAAM,EAAE,MAAM,CAAA;QACd,IAAI,EAAE;YACJ,IAAI,EAAE,MAAM,CAAA;YACZ,GAAG,EAAE,MAAM,CAAA;SACZ,CAAA;KACF,EAAE,CAAA;CACJ;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAkCD,eAAO,MAAM,GAAG;;YAmBoB,MAAM;;;YAQT,MAAM;;;GA2BrC,CAAA;AAEF,eAAO,MAAM,UAAU;;YArCa,MAAM;;;YAQT,MAAM;;;GA6BG,CAAA;AAC1C,eAAO,MAAM,gBAAgB;;YAtCO,MAAM;;;YAQT,MAAM;;;CA8BkB,CAAA;AACzD,eAAO,MAAM,cAAc;QA/BM,MAAM;+IA+B8B,CAAA"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { IndexedDBStorage, MemoryStorage } from "../core/index.js";
|
|
2
|
+
import { ApiClient } from "./api.module.js";
|
|
3
|
+
import { ResponseFormat } from "./types/api.interface.js";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
// Создаем базу данных в indexedDB
|
|
12
|
+
const { pokemonStorageIdb: pokemonStorageIdb } = await IndexedDBStorage.createStorages('pokemon-api-cache', {
|
|
13
|
+
// Создаем хранилище в базе данных
|
|
14
|
+
pokemonStorageIdb: {
|
|
15
|
+
name: 'pokemon-api'
|
|
16
|
+
},
|
|
17
|
+
// И так далее
|
|
18
|
+
myStorage1: {
|
|
19
|
+
name: 'some-api-1'
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
// Для MemoryStorage и LocalStorage как обычно
|
|
23
|
+
const pokemonStorageMemory = await new MemoryStorage({
|
|
24
|
+
name: 'pokemon-api'
|
|
25
|
+
}).initialize();
|
|
26
|
+
const api = new ApiClient({
|
|
27
|
+
cacheableHeaderKeys: [
|
|
28
|
+
'X-Global-Header'
|
|
29
|
+
],
|
|
30
|
+
// Передаем готовое хранилище
|
|
31
|
+
storage: pokemonStorageIdb,
|
|
32
|
+
cache: true,
|
|
33
|
+
// Базовый запрос
|
|
34
|
+
baseQuery: {
|
|
35
|
+
baseUrl: 'https://pokeapi.co/api/v2',
|
|
36
|
+
timeout: 10000,
|
|
37
|
+
prepareHeaders: async (headers, context)=>{
|
|
38
|
+
// Устанавливаем заголовки для тестирования
|
|
39
|
+
headers.set('X-Global-Header', 'global-value');
|
|
40
|
+
headers.set('X-BaseQuery-Header', 'basequery-value');
|
|
41
|
+
return headers;
|
|
42
|
+
},
|
|
43
|
+
credentials: 'same-origin'
|
|
44
|
+
},
|
|
45
|
+
// Типизированные endpoints
|
|
46
|
+
endpoints: async (create)=>({
|
|
47
|
+
updatePokemonById: create({
|
|
48
|
+
request: ({ id })=>({
|
|
49
|
+
path: `/pokemon/${id}`,
|
|
50
|
+
method: 'PUT',
|
|
51
|
+
body: {}
|
|
52
|
+
})
|
|
53
|
+
}),
|
|
54
|
+
// Запрос деталей покемона по ID (с явно включенным кэшированием)
|
|
55
|
+
getPokemonById: create({
|
|
56
|
+
request: (params)=>({
|
|
57
|
+
path: `/pokemon/${params.id}`,
|
|
58
|
+
method: 'GET',
|
|
59
|
+
responseFormat: ResponseFormat.Json
|
|
60
|
+
}),
|
|
61
|
+
// Включаем кэширование с настройками по умолчанию
|
|
62
|
+
// cache: {},
|
|
63
|
+
tags: [
|
|
64
|
+
'pokemon-details'
|
|
65
|
+
]
|
|
66
|
+
}),
|
|
67
|
+
// Запрос списка покемонов (без кэширования)
|
|
68
|
+
getPokemonList: create({
|
|
69
|
+
request: (params = {
|
|
70
|
+
limit: 20,
|
|
71
|
+
offset: 0
|
|
72
|
+
})=>({
|
|
73
|
+
path: '/pokemon',
|
|
74
|
+
method: 'GET',
|
|
75
|
+
query: params,
|
|
76
|
+
responseFormat: ResponseFormat.Json
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
})
|
|
80
|
+
});
|
|
81
|
+
console.log('Starting API initialization...');
|
|
82
|
+
const pokemonApi = await api.init();
|
|
83
|
+
const pokemonEndpoints = pokemonApi.getEndpoints();
|
|
84
|
+
const getPokemonById = pokemonEndpoints.getPokemonById.request;
|
|
85
|
+
// const t = pokemonEndpoints.getPokemonById.request({ id: 1 }, { disableCache: true })
|
|
86
|
+
console.log('Endpoints received');
|
|
87
|
+
|
|
88
|
+
export { api, getPokemonById, pokemonApi, pokemonEndpoints };
|
|
89
|
+
|
|
90
|
+
//# sourceMappingURL=example.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api/example.js","sources":["../../src/api/example.ts"],"sourcesContent":["import { IndexedDBStorage, LocalStorage, MemoryStorage } from '../core'\nimport { ApiClient } from './api.module'\nimport { ResponseFormat } from './types/api.interface'\n\n// Типы данных для PokeAPI\nexport interface PokemonListResponse {\n count: number\n next: string | null\n previous: string | null\n results: {\n name: string\n url: string\n }[]\n}\n\nexport interface PokemonDetails {\n id: number\n name: string\n height: number\n weight: number\n sprites: {\n front_default: string\n back_default: string\n other?: {\n 'official-artwork'?: {\n front_default: string\n }\n }\n }\n types: {\n slot: number\n type: {\n name: string\n url: string\n }\n }[]\n abilities: {\n ability: {\n name: string\n url: string\n }\n is_hidden: boolean\n slot: number\n }[]\n stats: {\n base_stat: number\n effort: number\n stat: {\n name: string\n url: string\n }\n }[]\n}\n\nexport interface PokemonSearchParams {\n limit?: number\n offset?: number\n}\n\n// Создаем базу данных в indexedDB\nconst { pokemonStorageIdb } = await IndexedDBStorage.createStorages<{\n pokemonStorageIdb: Record<string, any>\n myStorage1: Record<string, any>\n}>('pokemon-api-cache', {\n // Создаем хранилище в базе данных\n pokemonStorageIdb: {\n name: 'pokemon-api',\n },\n // И так далее\n myStorage1: {\n name: 'some-api-1',\n // Тоже самое что при\n // initialState: ,\n // middlewares: ,\n // pluginExecutor: ,\n // eventEmitter: ,\n },\n})\n\n// Для MemoryStorage и LocalStorage как обычно\nconst pokemonStorageMemory = await new MemoryStorage(\n {\n name: 'pokemon-api',\n // middlewares: ,\n // initialState: {},\n },\n // pluginExecutor: , // IPluginExecutor\n // eventEmitter: , // IEventEmitter\n // logger: , // ILogger\n).initialize()\n\nexport const api = new ApiClient({\n cacheableHeaderKeys: ['X-Global-Header'],\n // Передаем готовое хранилище\n storage: pokemonStorageIdb, // или pokemonStorageMemory\n cache: true,\n // Базовый запрос\n baseQuery: {\n baseUrl: 'https://pokeapi.co/api/v2',\n timeout: 10000,\n prepareHeaders: async (headers, context) => {\n // Устанавливаем заголовки для тестирования\n headers.set('X-Global-Header', 'global-value')\n headers.set('X-BaseQuery-Header', 'basequery-value')\n return headers\n },\n credentials: 'same-origin',\n },\n // Типизированные endpoints\n endpoints: async (create) => ({\n updatePokemonById: create<{ id: number }, PokemonDetails>({\n request: ({ id }) => ({\n path: `/pokemon/${id}`,\n method: 'PUT',\n body: {},\n }),\n }),\n // Запрос деталей покемона по ID (с явно включенным кэшированием)\n getPokemonById: create<{ id: number }, PokemonDetails>({\n request: (params) => ({\n path: `/pokemon/${params.id}`,\n method: 'GET',\n responseFormat: ResponseFormat.Json,\n }),\n // Включаем кэширование с настройками по умолчанию\n // cache: {},\n tags: ['pokemon-details'],\n }),\n // Запрос списка покемонов (без кэширования)\n getPokemonList: create<PokemonSearchParams, PokemonListResponse>({\n request: (\n params = {\n limit: 20,\n offset: 0,\n },\n ) => ({\n path: '/pokemon',\n method: 'GET',\n query: params,\n responseFormat: ResponseFormat.Json,\n }),\n // Явное отключение кэша для этого эндпоинта\n // cache: false,\n }),\n }),\n})\nconsole.log('Starting API initialization...')\nexport const pokemonApi = await api.init()\nexport const pokemonEndpoints = pokemonApi.getEndpoints()\nexport const getPokemonById = pokemonEndpoints.getPokemonById.request\n\n// const t = pokemonEndpoints.getPokemonById.request({ id: 1 }, { disableCache: true })\nconsole.log('Endpoints received')\n"],"names":["IndexedDBStorage","MemoryStorage","ApiClient","ResponseFormat","pokemonStorageIdb","pokemonStorageMemory","api","headers","context","create","id","params","console","pokemonApi","pokemonEndpoints","getPokemonById"],"mappings":";;;;;;;AAAuE;AAC/B;AACc;AAyDtD,kCAAkC;AAClC,MAAM,EAAEI,oCAAiB,EAAE,GAAG,MAAMJ,+BAA+B,CAGhE,qBAAqB;IACtB,kCAAkC;IAClC,mBAAmB;QACjB,MAAM;IACR;IACA,cAAc;IACd,YAAY;QACV,MAAM;IAMR;AACF;AAEA,8CAA8C;AAC9C,MAAMK,oBAAoBA,GAAG,MAAM,IAAIJ,aAAaA,CAClD;IACE,MAAM;AAGR,GAIA,UAAU;AAEL,MAAMK,GAAGA,GAAG,IAAIJ,SAASA,CAAC;IAC/B,qBAAqB;QAAC;KAAkB;IACxC,6BAA6B;IAC7B,SAASE,iBAAiBA;IAC1B,OAAO;IACP,iBAAiB;IACjB,WAAW;QACT,SAAS;QACT,SAAS;QACT,gBAAgB,OAAOG,SAASC;YAC9B,2CAA2C;YAC3CD,QAAQ,GAAG,CAAC,mBAAmB;YAC/BA,QAAQ,GAAG,CAAC,sBAAsB;YAClC,OAAOA;QACT;QACA,aAAa;IACf;IACA,2BAA2B;IAC3B,WAAW,OAAOE,SAAY;YAC5B,mBAAmBA,OAAuC;gBACxD,SAAS,CAAC,EAAEC,EAAE,EAAE,GAAM;wBACpB,MAAM,CAAC,SAAS,EAAEA,IAAI;wBACtB,QAAQ;wBACR,MAAM,CAAC;oBACT;YACF;YACA,iEAAiE;YACjE,gBAAgBD,OAAuC;gBACrD,SAAS,CAACE,SAAY;wBACpB,MAAM,CAAC,SAAS,EAAEA,OAAO,EAAE,EAAE;wBAC7B,QAAQ;wBACR,gBAAgBR,mBAAmB;oBACrC;gBACA,kDAAkD;gBAClD,aAAa;gBACb,MAAM;oBAAC;iBAAkB;YAC3B;YACA,4CAA4C;YAC5C,gBAAgBM,OAAiD;gBAC/D,SAAS,CACPE,SAAS;oBACP,OAAO;oBACP,QAAQ;gBACV,CAAC,GACG;wBACJ,MAAM;wBACN,QAAQ;wBACR,OAAOA;wBACP,gBAAgBR,mBAAmB;oBACrC;YAGF;QACF;AACF,GAAE;AACFS,QAAQ,GAAG,CAAC;AACL,MAAMC,UAAUA,GAAG,MAAMP,GAAGA,CAAC,IAAI,GAAE;AACnC,MAAMQ,gBAAgBA,GAAGD,UAAUA,CAAC,YAAY,GAAE;AAClD,MAAME,cAAcA,GAAGD,gBAAgBA,CAAC,cAAc,CAAC,OAAO;AAErE,uFAAuF;AACvFF,QAAQ,GAAG,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAA;AAC5B,OAAO,EAAE,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACxE,cAAc,qBAAqB,CAAA"}
|