@effect-app/infra 4.0.0-beta.33 → 4.0.0-beta.331
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/CHANGELOG.md +2562 -0
- package/_check.sh +1 -1
- package/dist/CUPS.d.ts +29 -10
- package/dist/CUPS.d.ts.map +1 -1
- package/dist/CUPS.js +36 -15
- package/dist/ClusterCosmos.d.ts +64 -0
- package/dist/ClusterCosmos.d.ts.map +1 -0
- package/dist/ClusterCosmos.js +576 -0
- package/dist/ClusterServiceBus.d.ts +67 -0
- package/dist/ClusterServiceBus.d.ts.map +1 -0
- package/dist/ClusterServiceBus.js +84 -0
- package/dist/ContextProvider.d.ts +34 -0
- package/dist/ContextProvider.d.ts.map +1 -0
- package/dist/ContextProvider.js +40 -0
- package/dist/Emailer/Sendgrid.d.ts +110 -146
- package/dist/Emailer/Sendgrid.d.ts.map +1 -1
- package/dist/Emailer/Sendgrid.js +24 -19
- package/dist/Emailer/fake.d.ts +1 -1
- package/dist/Emailer/fake.d.ts.map +1 -1
- package/dist/Emailer/fake.js +4 -4
- package/dist/MainFiberSet.d.ts +12 -8
- package/dist/MainFiberSet.d.ts.map +1 -1
- package/dist/MainFiberSet.js +23 -7
- package/dist/QueueMaker/errors.d.ts +4 -2
- package/dist/QueueMaker/errors.d.ts.map +1 -1
- package/dist/QueueMaker/errors.js +4 -2
- package/dist/{adapters/SQL → SQL}/Model.d.ts +31 -42
- package/dist/SQL/Model.d.ts.map +1 -0
- package/dist/SQL/Model.js +469 -0
- package/dist/SQL.d.ts.map +1 -0
- package/dist/{adapters/SQL.js → SQL.js} +1 -1
- package/dist/Store/Cosmos/query.d.ts +16 -4
- package/dist/Store/Cosmos/query.d.ts.map +1 -1
- package/dist/Store/Cosmos/query.js +238 -42
- package/dist/Store/Cosmos.d.ts +2 -2
- package/dist/Store/Cosmos.d.ts.map +1 -1
- package/dist/Store/Cosmos.js +395 -256
- package/dist/Store/Disk.d.ts +4 -4
- package/dist/Store/Disk.d.ts.map +1 -1
- package/dist/Store/Disk.js +93 -42
- package/dist/Store/Memory.d.ts +7 -10
- package/dist/Store/Memory.d.ts.map +1 -1
- package/dist/Store/Memory.js +349 -79
- package/dist/Store/SQL/Pg.d.ts +4 -0
- package/dist/Store/SQL/Pg.d.ts.map +1 -0
- package/dist/Store/SQL/Pg.js +261 -0
- package/dist/Store/SQL/query.d.ts +53 -0
- package/dist/Store/SQL/query.d.ts.map +1 -0
- package/dist/Store/SQL/query.js +656 -0
- package/dist/Store/SQL.d.ts +28 -0
- package/dist/Store/SQL.d.ts.map +1 -0
- package/dist/Store/SQL.js +483 -0
- package/dist/Store/codeFilter.d.ts +4 -4
- package/dist/Store/codeFilter.d.ts.map +1 -1
- package/dist/Store/codeFilter.js +71 -22
- package/dist/Store/index.d.ts +6 -4
- package/dist/Store/index.d.ts.map +1 -1
- package/dist/Store/index.js +18 -5
- package/dist/Store/jsonDocument.d.ts +67 -0
- package/dist/Store/jsonDocument.d.ts.map +1 -0
- package/dist/Store/jsonDocument.js +107 -0
- package/dist/Store/utils.d.ts +21 -2
- package/dist/Store/utils.d.ts.map +1 -1
- package/dist/Store/utils.js +253 -10
- package/dist/WorkflowEngineCosmos.d.ts +30 -0
- package/dist/WorkflowEngineCosmos.d.ts.map +1 -0
- package/dist/WorkflowEngineCosmos.js +542 -0
- package/dist/WorkflowEngineSqlite.d.ts +24 -0
- package/dist/WorkflowEngineSqlite.d.ts.map +1 -0
- package/dist/WorkflowEngineSqlite.js +550 -0
- package/dist/arbs.d.ts +6 -3
- package/dist/arbs.d.ts.map +1 -1
- package/dist/arbs.js +20 -4
- package/dist/codec.d.ts.map +1 -0
- package/dist/codec.js +5 -0
- package/dist/cosmos-client.d.ts +40 -0
- package/dist/cosmos-client.d.ts.map +1 -0
- package/dist/cosmos-client.js +41 -0
- package/dist/errorReporter.d.ts +6 -4
- package/dist/errorReporter.d.ts.map +1 -1
- package/dist/errorReporter.js +23 -27
- package/dist/fileUtil.d.ts +1 -1
- package/dist/fileUtil.d.ts.map +1 -1
- package/dist/fileUtil.js +2 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/internal/RequestContextMiddleware.d.ts +5 -0
- package/dist/internal/RequestContextMiddleware.d.ts.map +1 -0
- package/dist/internal/RequestContextMiddleware.js +45 -0
- package/dist/internal/auth.d.ts +53 -0
- package/dist/internal/auth.d.ts.map +1 -0
- package/dist/internal/auth.js +180 -0
- package/dist/internal/events.d.ts +11 -0
- package/dist/internal/events.d.ts.map +1 -0
- package/dist/internal/events.js +49 -0
- package/dist/internal/health.d.ts.map +1 -0
- package/dist/internal/health.js +5 -0
- package/dist/{api/layerUtils.d.ts → layerUtils.d.ts} +14 -6
- package/dist/layerUtils.d.ts.map +1 -0
- package/dist/layerUtils.js +17 -0
- package/dist/logger/jsonLogger.d.ts +1 -1
- package/dist/logger/jsonLogger.d.ts.map +1 -1
- package/dist/logger/jsonLogger.js +5 -3
- package/dist/logger/logFmtLogger.d.ts +1 -1
- package/dist/logger/logFmtLogger.d.ts.map +1 -1
- package/dist/logger/logFmtLogger.js +3 -3
- package/dist/logger/shared.d.ts +2 -2
- package/dist/logger/shared.d.ts.map +1 -1
- package/dist/logger/shared.js +6 -6
- package/dist/logger.d.ts +4 -4
- package/dist/logger.d.ts.map +1 -1
- package/dist/middlewares.d.ts.map +1 -0
- package/dist/{api/middlewares.js → middlewares.js} +1 -1
- package/dist/{adapters/mongo-client.d.ts → mongo-client.d.ts} +3 -2
- package/dist/mongo-client.d.ts.map +1 -0
- package/dist/mongo-client.js +15 -0
- package/dist/otel.d.ts +75 -0
- package/dist/otel.d.ts.map +1 -0
- package/dist/otel.js +84 -0
- package/dist/rateLimit.d.ts +11 -3
- package/dist/rateLimit.d.ts.map +1 -1
- package/dist/rateLimit.js +7 -12
- package/dist/{adapters/redis-client.d.ts → redis-client.d.ts} +5 -2
- package/dist/redis-client.d.ts.map +1 -0
- package/dist/redis-client.js +98 -0
- package/dist/{api/reportError.d.ts → reportError.d.ts} +1 -1
- package/dist/reportError.d.ts.map +1 -0
- package/dist/reportError.js +28 -0
- package/dist/{api/routing → routing}/middleware/RouterMiddleware.d.ts +4 -3
- package/dist/routing/middleware/RouterMiddleware.d.ts.map +1 -0
- package/dist/{api/routing → routing}/middleware/RouterMiddleware.js +1 -1
- package/dist/routing/middleware/middleware.d.ts +48 -0
- package/dist/routing/middleware/middleware.d.ts.map +1 -0
- package/dist/routing/middleware/middleware.js +152 -0
- package/dist/{api/routing → routing}/middleware.d.ts +0 -1
- package/dist/routing/middleware.d.ts.map +1 -0
- package/dist/{api/routing → routing}/middleware.js +1 -2
- package/dist/routing/schema/jwt.d.ts.map +1 -0
- package/dist/routing/schema/jwt.js +12 -0
- package/dist/routing/tsort.d.ts.map +1 -0
- package/dist/routing/tsort.js +51 -0
- package/dist/{api/routing → routing}/utils.d.ts +3 -3
- package/dist/routing/utils.d.ts.map +1 -0
- package/dist/routing/utils.js +45 -0
- package/dist/routing.d.ts +182 -0
- package/dist/routing.d.ts.map +1 -0
- package/dist/routing.js +256 -0
- package/dist/test.d.ts +2 -2
- package/dist/test.d.ts.map +1 -1
- package/dist/test.js +5 -5
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +14 -0
- package/docs/cluster-storage.md +26 -0
- package/docs/workflow-engine.md +262 -0
- package/examples/query.ts +25 -21
- package/package.json +38 -352
- package/src/CUPS.ts +54 -15
- package/src/ClusterCosmos.ts +1150 -0
- package/src/ClusterServiceBus.ts +244 -0
- package/src/{api/ContextProvider.ts → ContextProvider.ts} +20 -17
- package/src/Emailer/Sendgrid.ts +83 -60
- package/src/Emailer/fake.ts +4 -4
- package/src/MainFiberSet.ts +32 -13
- package/src/QueueMaker/errors.ts +3 -1
- package/src/{adapters/SQL → SQL}/Model.ts +42 -41
- package/src/SQL.ts +1 -0
- package/src/Store/Cosmos/query.ts +275 -55
- package/src/Store/Cosmos.ts +547 -366
- package/src/Store/Disk.ts +146 -73
- package/src/Store/Memory.ts +420 -115
- package/src/Store/SQL/Pg.ts +412 -0
- package/src/Store/SQL/query.ts +748 -0
- package/src/Store/SQL.ts +806 -0
- package/src/Store/codeFilter.ts +78 -28
- package/src/Store/index.ts +25 -10
- package/src/Store/jsonDocument.ts +143 -0
- package/src/Store/utils.ts +307 -30
- package/src/WorkflowEngineCosmos.ts +749 -0
- package/src/WorkflowEngineSqlite.ts +813 -0
- package/src/arbs.ts +25 -5
- package/src/cosmos-client.ts +72 -0
- package/src/errorReporter.ts +68 -78
- package/src/fileUtil.ts +1 -1
- package/src/index.ts +2 -1
- package/src/{api/internal → internal}/RequestContextMiddleware.ts +23 -6
- package/src/internal/auth.ts +272 -0
- package/src/{api/internal → internal}/events.ts +22 -13
- package/src/{api/layerUtils.ts → layerUtils.ts} +14 -10
- package/src/logger/jsonLogger.ts +5 -3
- package/src/logger/logFmtLogger.ts +3 -3
- package/src/logger/shared.ts +6 -5
- package/src/middlewares.ts +10 -0
- package/src/{adapters/mongo-client.ts → mongo-client.ts} +4 -2
- package/src/otel.ts +177 -0
- package/src/rateLimit.ts +35 -24
- package/src/{adapters/redis-client.ts → redis-client.ts} +7 -3
- package/src/{api/reportError.ts → reportError.ts} +3 -2
- package/src/{api/routing → routing}/middleware/RouterMiddleware.ts +5 -4
- package/src/routing/middleware/middleware.ts +196 -0
- package/src/routing/middleware.ts +4 -0
- package/src/{api/routing → routing}/schema/jwt.ts +2 -2
- package/src/{api/routing → routing}/utils.ts +2 -1
- package/src/routing.ts +823 -0
- package/src/test.ts +6 -6
- package/src/vitest.ts +1 -1
- package/test/arbs-magnitude.test.ts +33 -0
- package/test/arbs.test.ts +41 -0
- package/test/auth.test.ts +101 -0
- package/test/cluster-cosmos.test.ts +612 -0
- package/test/cluster-servicebus.test.ts +180 -0
- package/test/cluster-sqlite.test.ts +207 -0
- package/test/contextProvider.test.ts +15 -12
- package/test/controller.test.ts +27 -31
- package/test/cosmos-container-throughput.test.ts +80 -0
- package/test/cosmos-query.test.ts +368 -0
- package/test/dist/arbs-magnitude.test.d.ts.map +1 -0
- package/test/dist/arbs.test.d.ts.map +1 -0
- package/test/dist/auth.test.d.ts.map +1 -0
- package/test/dist/cluster-cosmos.test.d.ts.map +1 -0
- package/test/dist/cluster-servicebus.test.d.ts.map +1 -0
- package/test/dist/cluster-sqlite.test.d.ts.map +1 -0
- package/test/dist/contextProvider.test.d.ts.map +1 -1
- package/test/dist/controller.test.d.ts.map +1 -1
- package/test/dist/cosmos-container-throughput.test.d.ts.map +1 -0
- package/test/dist/cosmos-query.test.d.ts.map +1 -0
- package/test/dist/fixtures.d.ts +29 -11
- package/test/dist/fixtures.d.ts.map +1 -1
- package/test/dist/fixtures.js +17 -10
- package/test/dist/json-lower.test.d.ts.map +1 -0
- package/test/dist/query.test.d.ts.map +1 -1
- package/test/dist/rawQuery.test.d.ts.map +1 -1
- package/test/dist/repository-ext.test.d.ts.map +1 -0
- package/test/dist/repository-legacy-document.test.d.ts.map +1 -0
- package/test/dist/requires.test.d.ts.map +1 -1
- package/test/dist/router-generator.test.d.ts.map +1 -0
- package/test/dist/routing-interruptibility.test.d.ts.map +1 -0
- package/test/dist/rpc-context-map-streaming.test.d.ts.map +1 -0
- package/test/dist/rpc-e2e-invalidation.test.d.ts.map +1 -0
- package/test/dist/rpc-multi-middleware.test.d.ts.map +1 -1
- package/test/dist/rpc-stream-fullstack.test.d.ts.map +1 -0
- package/test/dist/sql-store.test.d.ts.map +1 -0
- package/test/dist/workflow-engine-cosmos.test.d.ts.map +1 -0
- package/test/dist/workflow-engine-sqlite.test.d.ts.map +1 -0
- package/test/fixtures.ts +16 -9
- package/test/json-lower.test.ts +129 -0
- package/test/layerUtils.test.ts +2 -2
- package/test/query.test.ts +1382 -44
- package/test/rawQuery.test.ts +433 -8
- package/test/repository-ext.test.ts +456 -0
- package/test/repository-legacy-document.test.ts +394 -0
- package/test/requires.test.ts +10 -5
- package/test/router-generator.test.ts +187 -0
- package/test/routing-interruptibility.test.ts +66 -0
- package/test/rpc-context-map-streaming.test.ts +265 -0
- package/test/rpc-e2e-invalidation.test.ts +421 -0
- package/test/rpc-multi-middleware.test.ts +85 -10
- package/test/rpc-stream-fullstack.test.ts +307 -0
- package/test/sql-store.test.ts +1931 -0
- package/test/validateSample.test.ts +71 -43
- package/test/workflow-engine-cosmos.test.ts +345 -0
- package/test/workflow-engine-sqlite.test.ts +297 -0
- package/tsconfig.examples.json +1 -1
- package/tsconfig.json +9 -2
- package/tsconfig.src.json +35 -35
- package/tsconfig.test.json +2 -2
- package/dist/Emailer/service.d.ts +0 -55
- package/dist/Emailer/service.d.ts.map +0 -1
- package/dist/Emailer/service.js +0 -6
- package/dist/Emailer.d.ts +0 -2
- package/dist/Emailer.d.ts.map +0 -1
- package/dist/Emailer.js +0 -2
- package/dist/Model/Repository/ext.d.ts +0 -41
- package/dist/Model/Repository/ext.d.ts.map +0 -1
- package/dist/Model/Repository/ext.js +0 -65
- package/dist/Model/Repository/internal/internal.d.ts +0 -59
- package/dist/Model/Repository/internal/internal.d.ts.map +0 -1
- package/dist/Model/Repository/internal/internal.js +0 -316
- package/dist/Model/Repository/legacy.d.ts +0 -19
- package/dist/Model/Repository/legacy.d.ts.map +0 -1
- package/dist/Model/Repository/legacy.js +0 -2
- package/dist/Model/Repository/makeRepo.d.ts +0 -49
- package/dist/Model/Repository/makeRepo.d.ts.map +0 -1
- package/dist/Model/Repository/makeRepo.js +0 -24
- package/dist/Model/Repository/service.d.ts +0 -89
- package/dist/Model/Repository/service.d.ts.map +0 -1
- package/dist/Model/Repository/service.js +0 -2
- package/dist/Model/Repository/validation.d.ts +0 -42
- package/dist/Model/Repository/validation.d.ts.map +0 -1
- package/dist/Model/Repository/validation.js +0 -32
- package/dist/Model/Repository.d.ts +0 -6
- package/dist/Model/Repository.d.ts.map +0 -1
- package/dist/Model/Repository.js +0 -6
- package/dist/Model/dsl.d.ts +0 -32
- package/dist/Model/dsl.d.ts.map +0 -1
- package/dist/Model/dsl.js +0 -44
- package/dist/Model/filter/filterApi.d.ts +0 -30
- package/dist/Model/filter/filterApi.d.ts.map +0 -1
- package/dist/Model/filter/filterApi.js +0 -2
- package/dist/Model/filter/types/errors.d.ts +0 -29
- package/dist/Model/filter/types/errors.d.ts.map +0 -1
- package/dist/Model/filter/types/errors.js +0 -2
- package/dist/Model/filter/types/fields.d.ts +0 -15
- package/dist/Model/filter/types/fields.d.ts.map +0 -1
- package/dist/Model/filter/types/fields.js +0 -2
- package/dist/Model/filter/types/path/common.d.ts +0 -316
- package/dist/Model/filter/types/path/common.d.ts.map +0 -1
- package/dist/Model/filter/types/path/common.js +0 -2
- package/dist/Model/filter/types/path/eager.d.ts +0 -95
- package/dist/Model/filter/types/path/eager.d.ts.map +0 -1
- package/dist/Model/filter/types/path/eager.js +0 -31
- package/dist/Model/filter/types/path/index.d.ts +0 -4
- package/dist/Model/filter/types/path/index.d.ts.map +0 -1
- package/dist/Model/filter/types/path/index.js +0 -3
- package/dist/Model/filter/types/utils.d.ts +0 -79
- package/dist/Model/filter/types/utils.d.ts.map +0 -1
- package/dist/Model/filter/types/utils.js +0 -2
- package/dist/Model/filter/types/validator.d.ts +0 -30
- package/dist/Model/filter/types/validator.d.ts.map +0 -1
- package/dist/Model/filter/types/validator.js +0 -2
- package/dist/Model/filter/types.d.ts +0 -5
- package/dist/Model/filter/types.d.ts.map +0 -1
- package/dist/Model/filter/types.js +0 -7
- package/dist/Model/query/dsl.d.ts +0 -248
- package/dist/Model/query/dsl.d.ts.map +0 -1
- package/dist/Model/query/dsl.js +0 -104
- package/dist/Model/query/new-kid-interpreter.d.ts +0 -28
- package/dist/Model/query/new-kid-interpreter.d.ts.map +0 -1
- package/dist/Model/query/new-kid-interpreter.js +0 -165
- package/dist/Model/query.d.ts +0 -15
- package/dist/Model/query.d.ts.map +0 -1
- package/dist/Model/query.js +0 -3
- package/dist/Model.d.ts +0 -4
- package/dist/Model.d.ts.map +0 -1
- package/dist/Model.js +0 -4
- package/dist/Operations.d.ts +0 -55
- package/dist/Operations.d.ts.map +0 -1
- package/dist/Operations.js +0 -102
- package/dist/OperationsRepo.d.ts +0 -41
- package/dist/OperationsRepo.d.ts.map +0 -1
- package/dist/OperationsRepo.js +0 -14
- package/dist/QueueMaker/SQLQueue.d.ts +0 -16
- package/dist/QueueMaker/SQLQueue.d.ts.map +0 -1
- package/dist/QueueMaker/SQLQueue.js +0 -130
- package/dist/QueueMaker/memQueue.d.ts +0 -11
- package/dist/QueueMaker/memQueue.d.ts.map +0 -1
- package/dist/QueueMaker/memQueue.js +0 -76
- package/dist/QueueMaker/sbqueue.d.ts +0 -12
- package/dist/QueueMaker/sbqueue.d.ts.map +0 -1
- package/dist/QueueMaker/sbqueue.js +0 -91
- package/dist/QueueMaker/service.d.ts +0 -11
- package/dist/QueueMaker/service.d.ts.map +0 -1
- package/dist/QueueMaker/service.js +0 -4
- package/dist/RequestContext.d.ts +0 -63
- package/dist/RequestContext.d.ts.map +0 -1
- package/dist/RequestContext.js +0 -49
- package/dist/RequestFiberSet.d.ts +0 -36
- package/dist/RequestFiberSet.d.ts.map +0 -1
- package/dist/RequestFiberSet.js +0 -78
- package/dist/Store/ContextMapContainer.d.ts +0 -14
- package/dist/Store/ContextMapContainer.d.ts.map +0 -1
- package/dist/Store/ContextMapContainer.js +0 -16
- package/dist/Store/service.d.ts +0 -108
- package/dist/Store/service.d.ts.map +0 -1
- package/dist/Store/service.js +0 -71
- package/dist/Store.d.ts +0 -2
- package/dist/Store.d.ts.map +0 -1
- package/dist/Store.js +0 -2
- package/dist/adapters/SQL/Model.d.ts.map +0 -1
- package/dist/adapters/SQL/Model.js +0 -478
- package/dist/adapters/SQL.d.ts.map +0 -1
- package/dist/adapters/ServiceBus.d.ts +0 -58
- package/dist/adapters/ServiceBus.d.ts.map +0 -1
- package/dist/adapters/ServiceBus.js +0 -99
- package/dist/adapters/cosmos-client.d.ts +0 -14
- package/dist/adapters/cosmos-client.d.ts.map +0 -1
- package/dist/adapters/cosmos-client.js +0 -9
- package/dist/adapters/index.d.ts +0 -2
- package/dist/adapters/index.d.ts.map +0 -1
- package/dist/adapters/index.js +0 -2
- package/dist/adapters/logger.d.ts +0 -9
- package/dist/adapters/logger.d.ts.map +0 -1
- package/dist/adapters/logger.js +0 -3
- package/dist/adapters/memQueue.d.ts +0 -13
- package/dist/adapters/memQueue.d.ts.map +0 -1
- package/dist/adapters/memQueue.js +0 -20
- package/dist/adapters/mongo-client.d.ts.map +0 -1
- package/dist/adapters/mongo-client.js +0 -13
- package/dist/adapters/redis-client.d.ts.map +0 -1
- package/dist/adapters/redis-client.js +0 -94
- package/dist/api/ContextProvider.d.ts +0 -31
- package/dist/api/ContextProvider.d.ts.map +0 -1
- package/dist/api/ContextProvider.js +0 -38
- package/dist/api/codec.d.ts.map +0 -1
- package/dist/api/codec.js +0 -5
- package/dist/api/internal/RequestContextMiddleware.d.ts +0 -5
- package/dist/api/internal/RequestContextMiddleware.d.ts.map +0 -1
- package/dist/api/internal/RequestContextMiddleware.js +0 -35
- package/dist/api/internal/auth.d.ts +0 -15
- package/dist/api/internal/auth.d.ts.map +0 -1
- package/dist/api/internal/auth.js +0 -47
- package/dist/api/internal/events.d.ts +0 -9
- package/dist/api/internal/events.d.ts.map +0 -1
- package/dist/api/internal/events.js +0 -42
- package/dist/api/internal/health.d.ts.map +0 -1
- package/dist/api/internal/health.js +0 -5
- package/dist/api/layerUtils.d.ts.map +0 -1
- package/dist/api/layerUtils.js +0 -16
- package/dist/api/middlewares.d.ts.map +0 -1
- package/dist/api/reportError.d.ts.map +0 -1
- package/dist/api/reportError.js +0 -27
- package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +0 -1
- package/dist/api/routing/middleware/middleware.d.ts +0 -9
- package/dist/api/routing/middleware/middleware.d.ts.map +0 -1
- package/dist/api/routing/middleware/middleware.js +0 -92
- package/dist/api/routing/middleware.d.ts.map +0 -1
- package/dist/api/routing/schema/jwt.d.ts.map +0 -1
- package/dist/api/routing/schema/jwt.js +0 -12
- package/dist/api/routing/tsort.d.ts.map +0 -1
- package/dist/api/routing/tsort.js +0 -51
- package/dist/api/routing/utils.d.ts.map +0 -1
- package/dist/api/routing/utils.js +0 -44
- package/dist/api/routing.d.ts +0 -138
- package/dist/api/routing.d.ts.map +0 -1
- package/dist/api/routing.js +0 -166
- package/dist/api/setupRequest.d.ts +0 -12
- package/dist/api/setupRequest.d.ts.map +0 -1
- package/dist/api/setupRequest.js +0 -44
- package/dist/api/util.d.ts.map +0 -1
- package/dist/api/util.js +0 -14
- package/eslint.config.mjs +0 -24
- package/src/Emailer/service.ts +0 -52
- package/src/Emailer.ts +0 -1
- package/src/Model/Repository/ext.ts +0 -283
- package/src/Model/Repository/internal/internal.ts +0 -577
- package/src/Model/Repository/legacy.ts +0 -27
- package/src/Model/Repository/makeRepo.ts +0 -139
- package/src/Model/Repository/service.ts +0 -627
- package/src/Model/Repository/validation.ts +0 -31
- package/src/Model/Repository.ts +0 -5
- package/src/Model/dsl.ts +0 -128
- package/src/Model/filter/filterApi.ts +0 -60
- package/src/Model/filter/types/errors.ts +0 -47
- package/src/Model/filter/types/fields.ts +0 -50
- package/src/Model/filter/types/path/common.ts +0 -404
- package/src/Model/filter/types/path/eager.ts +0 -298
- package/src/Model/filter/types/path/index.ts +0 -4
- package/src/Model/filter/types/utils.ts +0 -128
- package/src/Model/filter/types/validator.ts +0 -46
- package/src/Model/filter/types.ts +0 -6
- package/src/Model/query/dsl.ts +0 -2110
- package/src/Model/query/new-kid-interpreter.ts +0 -210
- package/src/Model/query.ts +0 -13
- package/src/Model.ts +0 -3
- package/src/Operations.ts +0 -235
- package/src/OperationsRepo.ts +0 -16
- package/src/QueueMaker/SQLQueue.ts +0 -189
- package/src/QueueMaker/memQueue.ts +0 -130
- package/src/QueueMaker/sbqueue.ts +0 -137
- package/src/QueueMaker/service.ts +0 -17
- package/src/RequestContext.ts +0 -63
- package/src/RequestFiberSet.ts +0 -105
- package/src/Store/ContextMapContainer.ts +0 -20
- package/src/Store/index.test.ts.bak +0 -112
- package/src/Store/service.ts +0 -184
- package/src/Store.ts +0 -1
- package/src/adapters/SQL.ts +0 -1
- package/src/adapters/ServiceBus.ts +0 -209
- package/src/adapters/cosmos-client.ts +0 -16
- package/src/adapters/index.ts +0 -0
- package/src/adapters/logger.ts +0 -3
- package/src/adapters/memQueue.ts +0 -21
- package/src/api/internal/auth.ts +0 -68
- package/src/api/middlewares.ts +0 -10
- package/src/api/routing/middleware/middleware.ts +0 -128
- package/src/api/routing/middleware.ts +0 -6
- package/src/api/routing.ts +0 -598
- package/src/api/setupRequest.ts +0 -84
- package/tsconfig.json.bak +0 -12
- /package/dist/{adapters/SQL.d.ts → SQL.d.ts} +0 -0
- /package/dist/{api/codec.d.ts → codec.d.ts} +0 -0
- /package/dist/{api/internal → internal}/health.d.ts +0 -0
- /package/dist/{api/middlewares.d.ts → middlewares.d.ts} +0 -0
- /package/dist/{api/routing → routing}/schema/jwt.d.ts +0 -0
- /package/dist/{api/routing → routing}/tsort.d.ts +0 -0
- /package/dist/{api/util.d.ts → util.d.ts} +0 -0
- /package/src/{api/codec.ts → codec.ts} +0 -0
- /package/src/{api/internal → internal}/health.ts +0 -0
- /package/src/{api/routing → routing}/tsort.ts +0 -0
- /package/src/{api/util.ts → util.ts} +0 -0
package/src/Store/Cosmos.ts
CHANGED
|
@@ -1,15 +1,26 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import * as Array from "effect-app/Array"
|
|
4
|
+
import type { NonEmptyReadonlyArray } from "effect-app/Array"
|
|
4
5
|
import { toNonEmptyArray } from "effect-app/Array"
|
|
6
|
+
import * as Effect from "effect-app/Effect"
|
|
7
|
+
import * as Layer from "effect-app/Layer"
|
|
8
|
+
import type { FieldValues } from "effect-app/Model/filter/types"
|
|
9
|
+
import { type ComputedProjectionIrExpression, type RawQuery } from "effect-app/Model/query"
|
|
10
|
+
import * as Option from "effect-app/Option"
|
|
11
|
+
import { type FilterArgs, type PersistenceModelType, type StorageConfig, type Store, type StoreConfig, storeId, StoreMaker } from "effect-app/Store"
|
|
5
12
|
import { dropUndefinedT, mutable } from "effect-app/utils"
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
+
import * as Duration from "effect/Duration"
|
|
14
|
+
import { pipe } from "effect/Function"
|
|
15
|
+
import * as Redacted from "effect/Redacted"
|
|
16
|
+
import * as Struct from "effect/Struct"
|
|
17
|
+
import { CosmosClient, CosmosClientLayer, createContainerIfNotExists } from "../cosmos-client.ts"
|
|
18
|
+
import { DatabaseError, OptimisticConcurrencyException } from "../errors.ts"
|
|
19
|
+
import { InfraLogger } from "../logger.ts"
|
|
20
|
+
import { annotateCosmosResponse, annotateDb } from "../otel.ts"
|
|
21
|
+
import { buildWhereCosmosQuery3, logQuery } from "./Cosmos/query.ts"
|
|
22
|
+
import { decodeStoredMany, decodeStoredOption, makeJsonDocumentCodec, makeStoredDecode } from "./jsonDocument.ts"
|
|
23
|
+
import { makeJsonLower } from "./utils.ts"
|
|
13
24
|
|
|
14
25
|
const makeMapId =
|
|
15
26
|
<IdKey extends keyof Encoded, Encoded extends FieldValues>(idKey: IdKey) => ({ [idKey]: id, ...e }: Encoded) => ({
|
|
@@ -21,152 +32,290 @@ const makeReverseMapId =
|
|
|
21
32
|
({ id, ...t }: PersistenceModelType<Omit<Encoded, IdKey> & { id: string }>) =>
|
|
22
33
|
({ ...t, [idKey]: id }) as any as PersistenceModelType<Encoded>
|
|
23
34
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
35
|
+
// Cosmos statuses worth retrying: request timeout, throttle, retry-with,
|
|
36
|
+
// internal, and service unavailable.
|
|
37
|
+
const RETRYABLE_COSMOS_STATUS = new Set([408, 429, 449, 500, 503])
|
|
38
|
+
const statusIsTransient = (code: number) => RETRYABLE_COSMOS_STATUS.has(code)
|
|
27
39
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
) =>
|
|
38
|
-
Effect.gen(function*() {
|
|
39
|
-
const mapId = makeMapId<IdKey, Encoded>(idKey)
|
|
40
|
-
const mapReverseId = makeReverseMapId<IdKey, Encoded>(idKey)
|
|
41
|
-
type PM = PersistenceModelType<Encoded>
|
|
42
|
-
type PMCosmos = PersistenceModelType<Omit<Encoded, IdKey> & { id: string }>
|
|
43
|
-
const containerId = `${prefix}${name}`
|
|
44
|
-
yield* Effect.promise(() =>
|
|
45
|
-
db.containers.createIfNotExists(dropUndefinedT({
|
|
46
|
-
id: containerId,
|
|
47
|
-
uniqueKeyPolicy: config?.uniqueKeys
|
|
48
|
-
? { uniqueKeys: config.uniqueKeys }
|
|
49
|
-
: undefined
|
|
50
|
-
}))
|
|
51
|
-
)
|
|
40
|
+
// A thrown SDK error is transient if its status/code is retryable or its message
|
|
41
|
+
// looks like a timeout / throttle / dropped connection.
|
|
42
|
+
const thrownIsTransient = (e: unknown): boolean => {
|
|
43
|
+
const code = (e as any)?.code ?? (e as any)?.statusCode
|
|
44
|
+
if (typeof code === "number" && RETRYABLE_COSMOS_STATUS.has(code)) return true
|
|
45
|
+
const msg = e instanceof Error ? e.message : String(e)
|
|
46
|
+
return /request timed out|timed out|\btimeout\b|ETIMEDOUT|ECONNRESET|ECONNREFUSED|EAI_AGAIN|socket hang up|ServiceUnavailable|RequestTimeout|TooManyRequests|throttl/i
|
|
47
|
+
.test(msg)
|
|
48
|
+
}
|
|
52
49
|
|
|
53
|
-
|
|
50
|
+
// Wrap a Cosmos SDK promise so a rejection becomes a typed, serializable
|
|
51
|
+
// `DatabaseError` (transient-classified) instead of a bare-`Error` defect — the
|
|
52
|
+
// latter both bypasses retry and breaks JSON encoding of the failure channel.
|
|
53
|
+
const tryCosmos = <A>(f: () => Promise<A>): Effect.Effect<A, DatabaseError> =>
|
|
54
|
+
Effect.tryPromise({
|
|
55
|
+
try: f,
|
|
56
|
+
catch: (e) =>
|
|
57
|
+
new DatabaseError({
|
|
58
|
+
message: `Cosmos request failed: ${e instanceof Error ? e.message : String(e)}`,
|
|
59
|
+
transient: thrownIsTransient(e),
|
|
60
|
+
cause: e
|
|
61
|
+
})
|
|
62
|
+
})
|
|
54
63
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const execBatch = container.items.batch.bind(container.items)
|
|
59
|
-
// TODO: move the marker to a separate container and get rid of the checks on every query
|
|
60
|
-
// then need to clean up the actual data.. perhaps first do with a config toggle to prescribe to it.
|
|
61
|
-
const importedMarkerId = containerId
|
|
64
|
+
const respBytes = (
|
|
65
|
+
resp: { diagnostics?: { clientSideRequestStatistics?: { totalResponsePayloadLengthInBytes?: number } } }
|
|
66
|
+
) => resp.diagnostics?.clientSideRequestStatistics?.totalResponsePayloadLengthInBytes ?? 0
|
|
62
67
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
68
|
+
const annotateFeed = (resp: {
|
|
69
|
+
resources: readonly unknown[]
|
|
70
|
+
requestCharge?: number
|
|
71
|
+
diagnostics?: { clientSideRequestStatistics?: { totalResponsePayloadLengthInBytes?: number } }
|
|
72
|
+
}) =>
|
|
73
|
+
annotateCosmosResponse({
|
|
74
|
+
requestCharge: resp.requestCharge,
|
|
75
|
+
returnedRows: resp.resources.length,
|
|
76
|
+
responseBytes: respBytes(resp)
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
const annotateItem = (resp: {
|
|
80
|
+
requestCharge?: number
|
|
81
|
+
statusCode?: number
|
|
82
|
+
diagnostics?: { clientSideRequestStatistics?: { totalResponsePayloadLengthInBytes?: number } }
|
|
83
|
+
}) =>
|
|
84
|
+
annotateCosmosResponse({
|
|
85
|
+
requestCharge: resp.requestCharge,
|
|
86
|
+
statusCode: resp.statusCode,
|
|
87
|
+
responseBytes: respBytes(resp)
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
const makeCosmosStore = Effect.fnUntraced(function*({ autoscaleMaxThroughput, prefix }: StorageConfig) {
|
|
91
|
+
const { db } = yield* CosmosClient
|
|
92
|
+
return {
|
|
93
|
+
make: Effect.fnUntraced(function*<IdKey extends keyof Encoded, Encoded extends FieldValues, R = never, E = never>(
|
|
94
|
+
name: string,
|
|
95
|
+
idKey: IdKey,
|
|
96
|
+
seed?: Effect.Effect<Iterable<Encoded>, E, R>,
|
|
97
|
+
config?: StoreConfig<Encoded>
|
|
98
|
+
) {
|
|
99
|
+
const mapId = makeMapId<IdKey, Encoded>(idKey)
|
|
100
|
+
const mapReverseId = makeReverseMapId<IdKey, Encoded>(idKey)
|
|
101
|
+
const codec = makeJsonDocumentCodec<Encoded>(config?.schema)
|
|
102
|
+
const decodeStored = makeStoredDecode<Encoded>(config?.schema, config?.jitM)
|
|
103
|
+
const json = makeJsonLower(config)
|
|
104
|
+
const defaultValues = json.toJson(config?.defaultValues ?? {}) as Partial<Encoded>
|
|
105
|
+
// stored JSON -> defaultValues -> jitM -> JSON→Encoded decode
|
|
106
|
+
const fromStored = (raw: Encoded) => decodeStored({ ...defaultValues, ...mapReverseId(raw as any) })
|
|
107
|
+
type PM = PersistenceModelType<Encoded>
|
|
108
|
+
type PMCosmos = PersistenceModelType<Omit<Encoded, IdKey> & { id: string }>
|
|
109
|
+
const containerId = `${prefix}${name}`
|
|
110
|
+
yield* Effect.promise(() =>
|
|
111
|
+
createContainerIfNotExists(
|
|
112
|
+
db,
|
|
113
|
+
dropUndefinedT({
|
|
114
|
+
id: containerId,
|
|
115
|
+
uniqueKeyPolicy: config?.uniqueKeys
|
|
116
|
+
? { uniqueKeys: config.uniqueKeys }
|
|
117
|
+
: undefined,
|
|
118
|
+
partitionKey: {
|
|
119
|
+
paths: ["/_partitionKey"],
|
|
120
|
+
version: 2 // support large partitionkeys so that the hash is not based on just the first 100 bytes!
|
|
121
|
+
}
|
|
122
|
+
}),
|
|
123
|
+
{ autoscaleMaxThroughput }
|
|
124
|
+
)
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
const basePartitionKey = config?.partitionValue() ?? "primary"
|
|
128
|
+
const nsPrefix = (ns: string) => ns === "primary" ? "" : `${ns}::`
|
|
129
|
+
const nsPartitionValue = (ns: string, e?: Encoded) => {
|
|
130
|
+
const base = config?.partitionValue(e) ?? "primary"
|
|
131
|
+
return `${nsPrefix(ns)}${base}`
|
|
132
|
+
}
|
|
133
|
+
const nsBasePartitionKey = (ns: string) => `${nsPrefix(ns)}${basePartitionKey}`
|
|
134
|
+
const resolveNamespace = !config?.allowNamespace
|
|
135
|
+
? Effect.succeed("primary")
|
|
136
|
+
: storeId.pipe(Effect.map((namespace) => {
|
|
137
|
+
if (namespace !== "primary" && !config.allowNamespace!(namespace)) {
|
|
138
|
+
throw new Error(`Namespace ${namespace} not allowed!`)
|
|
139
|
+
}
|
|
140
|
+
return namespace
|
|
141
|
+
}))
|
|
142
|
+
|
|
143
|
+
const container = db.container(containerId)
|
|
144
|
+
const bulk = container.items.bulk.bind(container.items)
|
|
145
|
+
const execBatch = container.items.batch.bind(container.items)
|
|
146
|
+
// TODO: move the marker to a separate container and get rid of the checks on every query
|
|
147
|
+
// then need to clean up the actual data.. perhaps first do with a config toggle to prescribe to it.
|
|
148
|
+
const importedMarkerId = containerId
|
|
149
|
+
|
|
150
|
+
const ctx = yield* Effect.context<R>()
|
|
151
|
+
const seedCache = new Map<string, Effect.Effect<void>>()
|
|
152
|
+
const makeSeedEffect = (ns: string) => {
|
|
153
|
+
const markerId = ns === "primary" ? importedMarkerId : `${importedMarkerId}::${ns}`
|
|
154
|
+
return Effect
|
|
155
|
+
.promise(() =>
|
|
156
|
+
container
|
|
157
|
+
.item(markerId, markerId)
|
|
158
|
+
.read<{ id: string }>()
|
|
159
|
+
.then(({ resource }) => Option.fromNullishOr(resource))
|
|
160
|
+
)
|
|
161
|
+
.pipe(
|
|
162
|
+
Effect.flatMap((marker) => {
|
|
163
|
+
if (Option.isSome(marker)) return Effect.void
|
|
164
|
+
return InfraLogger.logInfo(`Creating mock data for ${name} (namespace: ${ns})`).pipe(
|
|
165
|
+
Effect.andThen(seed!),
|
|
166
|
+
Effect.flatMap((m) =>
|
|
167
|
+
Effect.flatMapOption(
|
|
168
|
+
Effect.succeed(toNonEmptyArray([...m])),
|
|
169
|
+
(a) => bulkSetInternal(a, ns).pipe(Effect.orDie)
|
|
170
|
+
)
|
|
171
|
+
),
|
|
172
|
+
Effect.andThen(
|
|
173
|
+
Effect.promise(() =>
|
|
174
|
+
container.items.create({
|
|
175
|
+
_partitionKey: markerId,
|
|
176
|
+
id: markerId,
|
|
177
|
+
ttl: -1
|
|
178
|
+
})
|
|
100
179
|
)
|
|
101
|
-
|
|
180
|
+
),
|
|
181
|
+
Effect.provide(ctx),
|
|
182
|
+
Effect.orDie
|
|
183
|
+
)
|
|
184
|
+
}),
|
|
185
|
+
Effect.withLogSpan(`Cosmos.seedCheck ${name} in ${ns} [effect-app/infra/Store]`),
|
|
186
|
+
annotateDb({
|
|
187
|
+
operation: "seed",
|
|
188
|
+
system: "cosmosdb",
|
|
189
|
+
collection: containerId,
|
|
190
|
+
namespace: ns,
|
|
191
|
+
entity: name
|
|
192
|
+
})
|
|
193
|
+
)
|
|
194
|
+
}
|
|
195
|
+
const seedNamespace = Effect.fn("seedNamespace")(function*(ns: string) {
|
|
196
|
+
if (!seed) return
|
|
197
|
+
let cached = seedCache.get(ns)
|
|
198
|
+
if (!cached) {
|
|
199
|
+
cached = yield* Effect.cached(Effect.uninterruptible(makeSeedEffect(ns)))
|
|
200
|
+
seedCache.set(ns, cached)
|
|
201
|
+
}
|
|
202
|
+
yield* cached
|
|
203
|
+
})
|
|
204
|
+
const bulkSetInternal = (items: NonEmptyReadonlyArray<PM>, ns: string) =>
|
|
205
|
+
Effect
|
|
206
|
+
.gen(function*() {
|
|
207
|
+
// TODO: disable batching if need atomicity
|
|
208
|
+
// we delay and batch to keep low amount of RUs
|
|
209
|
+
const b = [...items]
|
|
210
|
+
.map(
|
|
211
|
+
(x) =>
|
|
212
|
+
[
|
|
213
|
+
x,
|
|
214
|
+
Option.match(Option.fromNullishOr(x._etag), {
|
|
215
|
+
onNone: () =>
|
|
216
|
+
dropUndefinedT({
|
|
217
|
+
operationType: "Create" as const,
|
|
218
|
+
resourceBody: {
|
|
219
|
+
...Struct.omit(codec.encode(x), ["_etag", idKey]),
|
|
220
|
+
id: x[idKey],
|
|
221
|
+
_partitionKey: nsPartitionValue(ns, x)
|
|
222
|
+
}
|
|
223
|
+
// don't use this or we get an error that the request and some item partition key dont match - makese no sense
|
|
224
|
+
// partitionKey: config?.partitionValue(x)
|
|
225
|
+
}),
|
|
226
|
+
onSome: (eTag) =>
|
|
227
|
+
dropUndefinedT({
|
|
228
|
+
operationType: "Replace" as const,
|
|
229
|
+
id: x[idKey],
|
|
230
|
+
resourceBody: {
|
|
231
|
+
...Struct.omit(codec.encode(x), ["_etag", idKey]),
|
|
232
|
+
id: x[idKey],
|
|
233
|
+
_partitionKey: nsPartitionValue(ns, x)
|
|
234
|
+
},
|
|
235
|
+
ifMatch: eTag
|
|
236
|
+
// don't use this or we get an error that the request and some item partition key dont match - makese no sense
|
|
237
|
+
// partitionKey: config?.partitionValue(x)
|
|
238
|
+
})
|
|
239
|
+
})
|
|
240
|
+
] as const
|
|
241
|
+
)
|
|
242
|
+
const batches = Array.chunksOf(b, config?.maxBulkSize ?? 10)
|
|
102
243
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
244
|
+
const batchResult = yield* Effect.forEach(
|
|
245
|
+
batches
|
|
246
|
+
.map((x, i) => [i, x] as const),
|
|
247
|
+
([i, batch]) =>
|
|
248
|
+
tryCosmos(() => bulk(batch.map(([, op]) => op)))
|
|
249
|
+
.pipe(
|
|
107
250
|
Effect
|
|
108
|
-
.
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
code: r.statusCode,
|
|
125
|
-
raw: responses
|
|
126
|
-
}
|
|
127
|
-
)
|
|
128
|
-
)
|
|
129
|
-
}
|
|
130
|
-
const r2 = responses.find(
|
|
131
|
-
(x) => x.statusCode !== 424 && (x.statusCode > 299 || x.statusCode < 200)
|
|
132
|
-
)
|
|
133
|
-
if (r2) {
|
|
134
|
-
return yield* Effect.die(
|
|
135
|
-
new CosmosDbOperationError(
|
|
136
|
-
"not able to update records: " + r2.statusCode,
|
|
137
|
-
responses
|
|
138
|
-
)
|
|
139
|
-
)
|
|
140
|
-
}
|
|
141
|
-
const r3 = responses.find(
|
|
142
|
-
(x) => x.statusCode > 299 || x.statusCode < 200
|
|
251
|
+
.delay(Duration.millis(i === 0 ? 0 : 150)),
|
|
252
|
+
Effect
|
|
253
|
+
.flatMap((responses) =>
|
|
254
|
+
Effect.gen(function*() {
|
|
255
|
+
const r = responses.find((x) =>
|
|
256
|
+
x.statusCode === 412 || x.statusCode === 404 || x.statusCode === 409
|
|
257
|
+
)
|
|
258
|
+
if (r) {
|
|
259
|
+
return yield* Effect.fail(
|
|
260
|
+
new OptimisticConcurrencyException(
|
|
261
|
+
{
|
|
262
|
+
type: name,
|
|
263
|
+
id: JSON.stringify(r.resourceBody?.["id"]),
|
|
264
|
+
code: r.statusCode,
|
|
265
|
+
raw: responses
|
|
266
|
+
}
|
|
143
267
|
)
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
155
|
-
_etag: responses[i]!.eTag
|
|
156
|
-
}))
|
|
268
|
+
)
|
|
269
|
+
}
|
|
270
|
+
const r2 = responses.find(
|
|
271
|
+
(x) => x.statusCode !== 424 && (x.statusCode > 299 || x.statusCode < 200)
|
|
272
|
+
)
|
|
273
|
+
if (r2) {
|
|
274
|
+
return yield* new DatabaseError({
|
|
275
|
+
message: "not able to update records: " + r2.statusCode,
|
|
276
|
+
transient: statusIsTransient(r2.statusCode),
|
|
277
|
+
cause: responses
|
|
157
278
|
})
|
|
279
|
+
}
|
|
280
|
+
const r3 = responses.find(
|
|
281
|
+
(x) => x.statusCode > 299 || x.statusCode < 200
|
|
158
282
|
)
|
|
283
|
+
if (r3) {
|
|
284
|
+
return yield* new DatabaseError({
|
|
285
|
+
message: "not able to update records: " + r3.statusCode,
|
|
286
|
+
transient: statusIsTransient(r3.statusCode),
|
|
287
|
+
cause: responses
|
|
288
|
+
})
|
|
289
|
+
}
|
|
290
|
+
return batch.map(([e], i) => ({
|
|
291
|
+
...e,
|
|
292
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
293
|
+
_etag: responses[i]!.eTag
|
|
294
|
+
}))
|
|
295
|
+
})
|
|
159
296
|
)
|
|
160
|
-
|
|
297
|
+
)
|
|
298
|
+
)
|
|
161
299
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
300
|
+
return batchResult.flat() as unknown as NonEmptyReadonlyArray<Encoded>
|
|
301
|
+
})
|
|
302
|
+
.pipe(
|
|
303
|
+
annotateDb({
|
|
304
|
+
operation: "bulkSet",
|
|
305
|
+
system: "cosmosdb",
|
|
306
|
+
collection: containerId,
|
|
307
|
+
namespace: ns,
|
|
308
|
+
entity: name
|
|
309
|
+
})
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
const bulkSet = (items: NonEmptyReadonlyArray<PM>) =>
|
|
313
|
+
resolveNamespace.pipe(Effect.flatMap((ns) => bulkSetInternal(items, ns)))
|
|
167
314
|
|
|
168
|
-
|
|
169
|
-
|
|
315
|
+
const batchSet = (items: NonEmptyReadonlyArray<PM>) => {
|
|
316
|
+
return resolveNamespace
|
|
317
|
+
.pipe(Effect.flatMap((ns) =>
|
|
318
|
+
Effect
|
|
170
319
|
.suspend(() => {
|
|
171
320
|
const batch = [...items].map(
|
|
172
321
|
(x) =>
|
|
@@ -176,9 +325,9 @@ function makeCosmosStore({ prefix }: StorageConfig) {
|
|
|
176
325
|
onNone: () => ({
|
|
177
326
|
operationType: "Create" as const,
|
|
178
327
|
resourceBody: {
|
|
179
|
-
...Struct.omit(x, ["_etag", idKey]),
|
|
328
|
+
...Struct.omit(codec.encode(x), ["_etag", idKey]),
|
|
180
329
|
id: x[idKey],
|
|
181
|
-
_partitionKey:
|
|
330
|
+
_partitionKey: nsPartitionValue(ns, x)
|
|
182
331
|
}
|
|
183
332
|
// don't use this or we get an error that the request and some item partition key dont match - makese no sense
|
|
184
333
|
// partitionKey: config?.partitionValue(x)
|
|
@@ -187,9 +336,9 @@ function makeCosmosStore({ prefix }: StorageConfig) {
|
|
|
187
336
|
operationType: "Replace" as const,
|
|
188
337
|
id: x[idKey],
|
|
189
338
|
resourceBody: {
|
|
190
|
-
...Struct.omit(x, ["_etag", idKey]),
|
|
339
|
+
...Struct.omit(codec.encode(x), ["_etag", idKey]),
|
|
191
340
|
id: x[idKey],
|
|
192
|
-
_partitionKey:
|
|
341
|
+
_partitionKey: nsPartitionValue(ns, x)
|
|
193
342
|
},
|
|
194
343
|
// don't use this or we get an error that the request and some item partition key dont match - makese no sense
|
|
195
344
|
// partitionKey: config?.partitionValue(x)
|
|
@@ -201,8 +350,7 @@ function makeCosmosStore({ prefix }: StorageConfig) {
|
|
|
201
350
|
|
|
202
351
|
const ex = batch.map(([, c]) => c)
|
|
203
352
|
|
|
204
|
-
return
|
|
205
|
-
.promise(() => execBatch(ex, ex[0]?.resourceBody._partitionKey))
|
|
353
|
+
return tryCosmos(() => execBatch(ex, ex[0]?.resourceBody._partitionKey))
|
|
206
354
|
.pipe(Effect.flatMap(Effect.fnUntraced(function*(x) {
|
|
207
355
|
const result = x.result ?? []
|
|
208
356
|
const firstFailed = result.find(
|
|
@@ -214,9 +362,11 @@ function makeCosmosStore({ prefix }: StorageConfig) {
|
|
|
214
362
|
return yield* new OptimisticConcurrencyException({ type: name, id: "batch", code })
|
|
215
363
|
}
|
|
216
364
|
|
|
217
|
-
return yield*
|
|
218
|
-
|
|
219
|
-
|
|
365
|
+
return yield* new DatabaseError({
|
|
366
|
+
message: "not able to update record: " + code,
|
|
367
|
+
transient: statusIsTransient(code),
|
|
368
|
+
cause: x
|
|
369
|
+
})
|
|
220
370
|
}
|
|
221
371
|
|
|
222
372
|
return batch.map(([e], i) => ({
|
|
@@ -225,249 +375,280 @@ function makeCosmosStore({ prefix }: StorageConfig) {
|
|
|
225
375
|
})) as unknown as NonEmptyReadonlyArray<Encoded>
|
|
226
376
|
})))
|
|
227
377
|
})
|
|
228
|
-
.pipe(
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
378
|
+
.pipe(annotateDb({
|
|
379
|
+
operation: "batchSet",
|
|
380
|
+
system: "cosmosdb",
|
|
381
|
+
collection: containerId,
|
|
382
|
+
namespace: ns,
|
|
383
|
+
entity: name
|
|
384
|
+
}))
|
|
385
|
+
))
|
|
386
|
+
}
|
|
233
387
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
resources.map(
|
|
248
|
-
(_) => ({ ...defaultValues, ...mapReverseId(_ as any) }) as Out
|
|
249
|
-
)
|
|
250
|
-
)
|
|
388
|
+
const s: Store<IdKey, Encoded> = {
|
|
389
|
+
seedNamespace: (ns) => seedNamespace(ns),
|
|
390
|
+
|
|
391
|
+
queryRaw: <Out>(query: RawQuery<Encoded, Out>) =>
|
|
392
|
+
Effect
|
|
393
|
+
.all({ q: Effect.sync(() => query.cosmos({ name })), ns: resolveNamespace })
|
|
394
|
+
.pipe(
|
|
395
|
+
Effect.tap(({ q }) => logQuery(q)),
|
|
396
|
+
Effect.flatMap(({ ns, q }) =>
|
|
397
|
+
Effect
|
|
398
|
+
.gen(function*() {
|
|
399
|
+
const response = yield* tryCosmos(() =>
|
|
400
|
+
container.items.query<Out>(q, { partitionKey: nsBasePartitionKey(ns) }).fetchAll()
|
|
251
401
|
)
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
// don't use this or we get an error that the request and some item partition key dont match - makese no sense
|
|
266
|
-
// partitionKey: config?.partitionValue({ [idKey]: id } as Encoded)
|
|
402
|
+
yield* annotateFeed(response)
|
|
403
|
+
return response.resources.map(
|
|
404
|
+
(_) => ({ ...defaultValues, ...mapReverseId(_ as any) }) as Out
|
|
405
|
+
)
|
|
406
|
+
})
|
|
407
|
+
.pipe(
|
|
408
|
+
annotateDb({
|
|
409
|
+
operation: "queryRaw",
|
|
410
|
+
system: "cosmosdb",
|
|
411
|
+
collection: containerId,
|
|
412
|
+
namespace: ns,
|
|
413
|
+
entity: name,
|
|
414
|
+
query: q.query
|
|
267
415
|
})
|
|
268
|
-
)
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
416
|
+
)
|
|
417
|
+
)
|
|
418
|
+
),
|
|
419
|
+
batchRemove: (ids, partitionKey?: string) =>
|
|
420
|
+
resolveNamespace.pipe(Effect.flatMap((ns) =>
|
|
421
|
+
tryCosmos(() =>
|
|
422
|
+
execBatch(
|
|
423
|
+
mutable(ids.map((id) =>
|
|
424
|
+
dropUndefinedT({
|
|
425
|
+
operationType: "Delete" as const,
|
|
426
|
+
id
|
|
427
|
+
// don't use this or we get an error that the request and some item partition key dont match - makese no sense
|
|
428
|
+
// partitionKey: config?.partitionValue({ [idKey]: id } as Encoded)
|
|
429
|
+
})
|
|
430
|
+
)),
|
|
431
|
+
partitionKey ?? nsBasePartitionKey(ns)
|
|
432
|
+
)
|
|
433
|
+
)
|
|
277
434
|
.pipe(
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
435
|
+
annotateDb({
|
|
436
|
+
operation: "batchRemove",
|
|
437
|
+
system: "cosmosdb",
|
|
438
|
+
collection: containerId,
|
|
439
|
+
namespace: ns,
|
|
440
|
+
entity: name
|
|
441
|
+
})
|
|
442
|
+
)
|
|
443
|
+
)),
|
|
444
|
+
all: Effect
|
|
445
|
+
.all({
|
|
446
|
+
q: Effect.sync(() => ({
|
|
447
|
+
query: `SELECT * FROM ${name}`,
|
|
448
|
+
parameters: []
|
|
449
|
+
})),
|
|
450
|
+
ns: resolveNamespace
|
|
451
|
+
})
|
|
452
|
+
.pipe(
|
|
453
|
+
Effect.tap(({ q }) => logQuery(q)),
|
|
454
|
+
Effect.flatMap(({ ns, q }) =>
|
|
455
|
+
Effect
|
|
456
|
+
.gen(function*() {
|
|
457
|
+
const response = yield* tryCosmos(() =>
|
|
458
|
+
container.items.query<PMCosmos>(q, { partitionKey: nsBasePartitionKey(ns) }).fetchAll()
|
|
290
459
|
)
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
attributes: { "repository.container_id": containerId, "repository.model_name": name }
|
|
295
|
-
}, { captureStackTrace: false })
|
|
296
|
-
),
|
|
297
|
-
/**
|
|
298
|
-
* May return duplicate results for "join_find", when matching more than once.
|
|
299
|
-
*/
|
|
300
|
-
filter: <U extends keyof Encoded = never>(
|
|
301
|
-
f: FilterArgs<Encoded, U>
|
|
302
|
-
) => {
|
|
303
|
-
const skip = f?.skip
|
|
304
|
-
const limit = f?.limit
|
|
305
|
-
const filter = f.filter
|
|
306
|
-
type M = U extends undefined ? Encoded : Pick<Encoded, U>
|
|
307
|
-
return Effect
|
|
308
|
-
.sync(() =>
|
|
309
|
-
buildWhereCosmosQuery3(
|
|
310
|
-
idKey,
|
|
311
|
-
filter ? [{ t: "where-scope", result: filter, relation: "some" }] : [],
|
|
312
|
-
name,
|
|
313
|
-
defaultValues,
|
|
314
|
-
f.select as NonEmptyReadonlyArray<string | { key: string; subKeys: readonly string[] }> | undefined,
|
|
315
|
-
f.order as NonEmptyReadonlyArray<{ key: string; direction: "ASC" | "DESC" }> | undefined,
|
|
316
|
-
skip,
|
|
317
|
-
limit
|
|
460
|
+
yield* annotateFeed(response)
|
|
461
|
+
return yield* Effect.fromResult(
|
|
462
|
+
decodeStoredMany(response.resources, (_) => fromStored(_ as unknown as Encoded))
|
|
318
463
|
)
|
|
319
|
-
)
|
|
464
|
+
})
|
|
320
465
|
.pipe(
|
|
321
|
-
|
|
466
|
+
annotateDb({
|
|
467
|
+
operation: "all",
|
|
468
|
+
system: "cosmosdb",
|
|
469
|
+
collection: containerId,
|
|
470
|
+
namespace: ns,
|
|
471
|
+
entity: name,
|
|
472
|
+
query: q.query
|
|
473
|
+
})
|
|
474
|
+
)
|
|
475
|
+
)
|
|
476
|
+
),
|
|
477
|
+
/**
|
|
478
|
+
* May return duplicate results for "join_find", when matching more than once.
|
|
479
|
+
*/
|
|
480
|
+
filter: <U extends keyof Encoded = never>(
|
|
481
|
+
f: FilterArgs<Encoded, U>
|
|
482
|
+
) => {
|
|
483
|
+
const skip = f?.skip
|
|
484
|
+
const limit = f?.limit
|
|
485
|
+
const filter = f.filter
|
|
486
|
+
type M = U extends undefined ? Encoded : Pick<Encoded, U>
|
|
487
|
+
return Effect
|
|
488
|
+
.all({
|
|
489
|
+
q: Effect.sync(() =>
|
|
490
|
+
buildWhereCosmosQuery3(
|
|
491
|
+
idKey,
|
|
492
|
+
filter ? [{ t: "where-scope", result: filter, relation: "some" }] : [],
|
|
493
|
+
name,
|
|
494
|
+
defaultValues,
|
|
495
|
+
f.select as
|
|
496
|
+
| NonEmptyReadonlyArray<
|
|
497
|
+
string | {
|
|
498
|
+
key: string
|
|
499
|
+
subKeys: readonly string[]
|
|
500
|
+
} | {
|
|
501
|
+
key: string
|
|
502
|
+
computed: ComputedProjectionIrExpression
|
|
503
|
+
}
|
|
504
|
+
>
|
|
505
|
+
| undefined,
|
|
506
|
+
f.order as NonEmptyReadonlyArray<{ key: string; direction: "ASC" | "DESC" }> | undefined,
|
|
507
|
+
skip,
|
|
508
|
+
limit,
|
|
509
|
+
json
|
|
510
|
+
)
|
|
511
|
+
),
|
|
512
|
+
ns: resolveNamespace
|
|
513
|
+
})
|
|
514
|
+
.pipe(
|
|
515
|
+
Effect.tap(({ q }) => logQuery(q)),
|
|
516
|
+
Effect
|
|
517
|
+
.flatMap(({ ns, q }) =>
|
|
322
518
|
Effect
|
|
323
|
-
.
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
.then(({ resources }) =>
|
|
344
|
-
resources.map(({ f }) => ({ ...defaultValues, ...mapReverseId(f as any) }) as any)
|
|
345
|
-
)
|
|
519
|
+
.gen(function*() {
|
|
520
|
+
if (f.select) {
|
|
521
|
+
const response = yield* tryCosmos(() =>
|
|
522
|
+
container.items.query<M>(q, { partitionKey: nsBasePartitionKey(ns) }).fetchAll()
|
|
523
|
+
)
|
|
524
|
+
yield* annotateFeed(response)
|
|
525
|
+
return response.resources.map((_) => ({
|
|
526
|
+
...pipe(
|
|
527
|
+
defaultValues,
|
|
528
|
+
Struct.pick(f.select!.filter((_) => typeof _ === "string") as never[])
|
|
529
|
+
),
|
|
530
|
+
...mapReverseId(_ as any)
|
|
531
|
+
}))
|
|
532
|
+
}
|
|
533
|
+
const response = yield* tryCosmos(() =>
|
|
534
|
+
container.items.query<{ f: M }>(q, { partitionKey: nsBasePartitionKey(ns) }).fetchAll()
|
|
535
|
+
)
|
|
536
|
+
yield* annotateFeed(response)
|
|
537
|
+
const decoded = yield* Effect.fromResult(
|
|
538
|
+
decodeStoredMany(response.resources, ({ f }) => fromStored(f as Encoded))
|
|
346
539
|
)
|
|
540
|
+
return decoded as any
|
|
541
|
+
})
|
|
542
|
+
.pipe(
|
|
543
|
+
annotateDb({
|
|
544
|
+
operation: "filter",
|
|
545
|
+
system: "cosmosdb",
|
|
546
|
+
collection: containerId,
|
|
547
|
+
namespace: ns,
|
|
548
|
+
entity: name,
|
|
549
|
+
query: q.query
|
|
550
|
+
})
|
|
347
551
|
)
|
|
348
552
|
)
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
Effect
|
|
357
|
-
.promise(() =>
|
|
553
|
+
)
|
|
554
|
+
},
|
|
555
|
+
find: (id) =>
|
|
556
|
+
resolveNamespace.pipe(Effect.flatMap((ns) =>
|
|
557
|
+
Effect
|
|
558
|
+
.gen(function*() {
|
|
559
|
+
const response = yield* tryCosmos(() =>
|
|
358
560
|
container
|
|
359
|
-
.item(id,
|
|
561
|
+
.item(id, nsPartitionValue(ns, { [idKey]: id } as Encoded))
|
|
360
562
|
.read<Encoded>()
|
|
361
|
-
.then(({ resource }) =>
|
|
362
|
-
Option.fromNullishOr(resource).pipe(Option.map((_) => ({ ...defaultValues, ...mapReverseId(_) })))
|
|
363
|
-
)
|
|
364
563
|
)
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
564
|
+
yield* annotateItem(response)
|
|
565
|
+
return yield* Effect.fromResult(
|
|
566
|
+
decodeStoredOption(Option.fromNullishOr(response.resource), fromStored)
|
|
567
|
+
)
|
|
568
|
+
})
|
|
569
|
+
.pipe(annotateDb({
|
|
570
|
+
operation: "find",
|
|
571
|
+
system: "cosmosdb",
|
|
572
|
+
collection: containerId,
|
|
573
|
+
namespace: ns,
|
|
574
|
+
entity: name,
|
|
575
|
+
extra: {
|
|
576
|
+
"azure.cosmosdb.operation.partition_key": nsPartitionValue(ns, { [idKey]: id } as Encoded),
|
|
577
|
+
"app.entity.id": id
|
|
578
|
+
}
|
|
579
|
+
}))
|
|
580
|
+
)),
|
|
581
|
+
set: (e) =>
|
|
582
|
+
resolveNamespace.pipe(Effect.flatMap((ns) =>
|
|
583
|
+
// Annotate the result so the create/replace promise union collapses to
|
|
584
|
+
// one type (otherwise `A` infers as `unknown` and the chain degrades).
|
|
585
|
+
tryCosmos((): Promise<{ statusCode: number; etag: string }> =>
|
|
375
586
|
Option
|
|
376
587
|
.match(
|
|
377
588
|
Option
|
|
378
589
|
.fromNullishOr(e._etag),
|
|
379
590
|
{
|
|
380
591
|
onNone: () =>
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
})
|
|
386
|
-
),
|
|
592
|
+
container.items.create({
|
|
593
|
+
...mapId(codec.encode(e)),
|
|
594
|
+
_partitionKey: nsPartitionValue(ns, e)
|
|
595
|
+
}),
|
|
387
596
|
onSome: (eTag) =>
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
{
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
condition: eTag
|
|
395
|
-
}
|
|
597
|
+
container.item(e[idKey], nsPartitionValue(ns, e)).replace(
|
|
598
|
+
{ ...mapId(codec.encode(e)), _partitionKey: nsPartitionValue(ns, e) },
|
|
599
|
+
{
|
|
600
|
+
accessCondition: {
|
|
601
|
+
type: "IfMatch",
|
|
602
|
+
condition: eTag
|
|
396
603
|
}
|
|
397
|
-
|
|
604
|
+
}
|
|
398
605
|
)
|
|
399
606
|
}
|
|
400
607
|
)
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
)
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
608
|
+
)
|
|
609
|
+
.pipe(
|
|
610
|
+
Effect
|
|
611
|
+
.flatMap((x): Effect.Effect<PM, OptimisticConcurrencyException | DatabaseError> => {
|
|
612
|
+
if (x.statusCode === 412 || x.statusCode === 404 || x.statusCode === 409) {
|
|
613
|
+
return Effect.fail(
|
|
614
|
+
new OptimisticConcurrencyException({ type: name, id: e[idKey], code: x.statusCode })
|
|
615
|
+
)
|
|
616
|
+
}
|
|
617
|
+
if (x.statusCode > 299 || x.statusCode < 200) {
|
|
618
|
+
return Effect.fail(
|
|
619
|
+
new DatabaseError({
|
|
620
|
+
message: "not able to update record: " + x.statusCode,
|
|
621
|
+
transient: statusIsTransient(x.statusCode),
|
|
622
|
+
cause: x
|
|
623
|
+
})
|
|
624
|
+
)
|
|
625
|
+
}
|
|
626
|
+
return Effect.sync(() => ({
|
|
627
|
+
...e,
|
|
628
|
+
_etag: x.etag
|
|
629
|
+
}))
|
|
630
|
+
}),
|
|
631
|
+
annotateDb({
|
|
632
|
+
operation: "set",
|
|
633
|
+
system: "cosmosdb",
|
|
634
|
+
collection: containerId,
|
|
635
|
+
namespace: ns,
|
|
636
|
+
entity: name,
|
|
637
|
+
extra: { "app.entity.id": e[idKey] }
|
|
638
|
+
})
|
|
639
|
+
)
|
|
640
|
+
)),
|
|
641
|
+
batchSet,
|
|
642
|
+
bulkSet
|
|
643
|
+
}
|
|
433
644
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
container
|
|
437
|
-
.item(importedMarkerId, importedMarkerId)
|
|
438
|
-
.read<{ id: string }>()
|
|
439
|
-
.then(({ resource }) => Option.fromNullishOr(resource))
|
|
440
|
-
)
|
|
645
|
+
// Eagerly seed primary namespace on initialization
|
|
646
|
+
yield* seedNamespace("primary")
|
|
441
647
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
yield* Effect.flatMapOption(
|
|
447
|
-
Effect.succeed(toNonEmptyArray([...m])),
|
|
448
|
-
(a) =>
|
|
449
|
-
s.bulkSet(a).pipe(
|
|
450
|
-
Effect.orDie,
|
|
451
|
-
Effect
|
|
452
|
-
// we delay extra here, so that initial creation between Companies/POs also have an interval between them.
|
|
453
|
-
.delay(Duration.millis(1100))
|
|
454
|
-
)
|
|
455
|
-
)
|
|
456
|
-
}
|
|
457
|
-
// Mark as imported
|
|
458
|
-
yield* Effect.promise(() =>
|
|
459
|
-
container.items.create({
|
|
460
|
-
_partitionKey: importedMarkerId,
|
|
461
|
-
id: importedMarkerId,
|
|
462
|
-
ttl: -1
|
|
463
|
-
})
|
|
464
|
-
)
|
|
465
|
-
}
|
|
466
|
-
return s
|
|
467
|
-
})
|
|
468
|
-
}
|
|
469
|
-
})
|
|
470
|
-
}
|
|
648
|
+
return s
|
|
649
|
+
})
|
|
650
|
+
}
|
|
651
|
+
})
|
|
471
652
|
|
|
472
653
|
export function CosmosStoreLayer(cfg: StorageConfig) {
|
|
473
654
|
return StoreMaker
|