@effect-app/infra 4.0.0-beta.99 → 4.0.0
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 +2884 -0
- package/_check.sh +1 -1
- package/dist/CUPS.d.ts +28 -9
- package/dist/CUPS.d.ts.map +1 -1
- package/dist/CUPS.js +35 -14
- package/dist/ClusterCosmos.d.ts +67 -0
- package/dist/ClusterCosmos.d.ts.map +1 -0
- package/dist/ClusterCosmos.js +588 -0
- package/dist/ClusterServiceBus.d.ts +67 -0
- package/dist/ClusterServiceBus.d.ts.map +1 -0
- package/dist/ClusterServiceBus.js +84 -0
- package/dist/{api/ContextProvider.d.ts → ContextProvider.d.ts} +7 -4
- 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 +11 -7
- package/dist/MainFiberSet.d.ts.map +1 -1
- package/dist/MainFiberSet.js +22 -6
- package/dist/QueueMaker/errors.d.ts +3 -1
- package/dist/QueueMaker/errors.d.ts.map +1 -1
- package/dist/QueueMaker/errors.js +4 -2
- package/dist/{adapters/SQL → SQL}/Model.d.ts +34 -45
- 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 +394 -319
- package/dist/Store/Disk.d.ts +4 -4
- package/dist/Store/Disk.d.ts.map +1 -1
- package/dist/Store/Disk.js +91 -39
- package/dist/Store/Memory.d.ts +7 -10
- package/dist/Store/Memory.d.ts.map +1 -1
- package/dist/Store/Memory.js +348 -78
- package/dist/Store/SQL/Pg.d.ts +2 -2
- package/dist/Store/SQL/Pg.d.ts.map +1 -1
- package/dist/Store/SQL/Pg.js +229 -154
- package/dist/Store/SQL/query.d.ts +19 -3
- package/dist/Store/SQL/query.d.ts.map +1 -1
- package/dist/Store/SQL/query.js +306 -12
- package/dist/Store/SQL.d.ts +22 -5
- package/dist/Store/SQL.d.ts.map +1 -1
- package/dist/Store/SQL.js +369 -98
- 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 +9 -6
- 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/{api/internal → internal}/health.d.ts +1 -1
- 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} +10 -2
- 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.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} +2 -1
- 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} +4 -1
- 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 +2 -1
- package/dist/routing/middleware/RouterMiddleware.d.ts.map +1 -0
- package/dist/{api/routing → routing}/middleware/RouterMiddleware.js +1 -1
- package/dist/{api/routing → routing}/middleware/middleware.d.ts +11 -6
- 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 +23 -19
- package/package.json +36 -364
- package/src/CUPS.ts +53 -14
- package/src/ClusterCosmos.ts +1170 -0
- package/src/ClusterServiceBus.ts +244 -0
- package/src/{api/ContextProvider.ts → ContextProvider.ts} +10 -7
- package/src/Emailer/Sendgrid.ts +83 -60
- package/src/Emailer/fake.ts +4 -4
- package/src/MainFiberSet.ts +31 -12
- package/src/QueueMaker/errors.ts +3 -1
- package/src/{adapters/SQL → SQL}/Model.ts +48 -47
- package/src/SQL.ts +1 -0
- package/src/Store/Cosmos/query.ts +275 -55
- package/src/Store/Cosmos.ts +597 -511
- package/src/Store/Disk.ts +145 -71
- package/src/Store/Memory.ts +420 -115
- package/src/Store/SQL/Pg.ts +352 -268
- package/src/Store/SQL/query.ts +366 -20
- package/src/Store/SQL.ts +742 -293
- package/src/Store/codeFilter.ts +78 -28
- package/src/Store/index.ts +18 -13
- 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 +18 -9
- package/src/{api/layerUtils.ts → layerUtils.ts} +7 -3
- 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} +3 -1
- package/src/otel.ts +177 -0
- package/src/rateLimit.ts +35 -24
- package/src/{adapters/redis-client.ts → redis-client.ts} +6 -2
- package/src/{api/reportError.ts → reportError.ts} +3 -2
- package/src/{api/routing → routing}/middleware/RouterMiddleware.ts +2 -1
- package/src/{api/routing → routing}/middleware/middleware.ts +75 -50
- 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 +634 -0
- package/test/cluster-servicebus.test.ts +180 -0
- package/test/cluster-sqlite.test.ts +207 -0
- package/test/contextProvider.test.ts +11 -8
- package/test/controller.test.ts +23 -28
- 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 +17 -9
- package/test/dist/fixtures.d.ts.map +1 -1
- package/test/dist/fixtures.js +8 -3
- 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/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 +7 -2
- package/test/json-lower.test.ts +129 -0
- package/test/layerUtils.test.ts +2 -2
- package/test/query.test.ts +1232 -42
- package/test/rawQuery.test.ts +432 -7
- package/test/repository-ext.test.ts +456 -0
- package/test/repository-legacy-document.test.ts +394 -0
- package/test/requires.test.ts +7 -3
- 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 +17 -11
- package/test/rpc-stream-fullstack.test.ts +307 -0
- package/test/sql-store.test.ts +1202 -47
- package/test/validateSample.test.ts +70 -42
- 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 -1
- 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 -320
- 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 -43
- 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 -14
- package/dist/QueueMaker/SQLQueue.d.ts.map +0 -1
- package/dist/QueueMaker/SQLQueue.js +0 -132
- 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 -68
- 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 -25
- package/dist/Store/ContextMapContainer.d.ts.map +0 -1
- package/dist/Store/ContextMapContainer.js +0 -77
- package/dist/Store/service.d.ts +0 -111
- package/dist/Store/service.d.ts.map +0 -1
- package/dist/Store/service.js +0 -79
- 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.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.map +0 -1
- package/dist/api/routing/middleware/middleware.js +0 -130
- 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 -134
- package/dist/api/routing.d.ts.map +0 -1
- package/dist/api/routing.js +0 -167
- package/dist/api/setupRequest.d.ts +0 -15
- package/dist/api/setupRequest.d.ts.map +0 -1
- package/dist/api/setupRequest.js +0 -49
- 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 -580
- 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 -190
- 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 -116
- package/src/Store/index.test.ts.bak +0 -112
- package/src/Store/service.ts +0 -193
- 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.ts +0 -6
- package/src/api/routing.ts +0 -598
- package/src/api/setupRequest.ts +0 -104
- package/test/dist/date-query.test.d.ts.map +0 -1
- 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/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
|
@@ -0,0 +1,542 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cosmos DB backed {@link WorkflowEngine} implementation.
|
|
3
|
+
*
|
|
4
|
+
* Persists workflow state in a single container partitioned by `executionId`
|
|
5
|
+
* so per-execution writes share a partition key (eligible for Cosmos
|
|
6
|
+
* TransactionalBatch). Optimistic concurrency is enforced with `_etag` +
|
|
7
|
+
* `IfMatch` on Replace, and create-only batch ops give first-writer-wins
|
|
8
|
+
* semantics for activity results and durable-deferred completions.
|
|
9
|
+
*
|
|
10
|
+
* Durability — everything that crosses the storage boundary is round-tripped
|
|
11
|
+
* through schema codecs (`S.fromJsonString(S.toCodecJson(...))`), exactly like
|
|
12
|
+
* the cluster engine, instead of dumping live runtime objects as JSON:
|
|
13
|
+
*
|
|
14
|
+
* - The workflow payload and the top-level workflow result are encoded with the
|
|
15
|
+
* workflow's own `payloadSchema` / `successSchema` / `errorSchema`, so typed
|
|
16
|
+
* values (dates, branded ids, schema classes) survive a restart.
|
|
17
|
+
* - Activity results flow through the engine already encoded, so they are
|
|
18
|
+
* persisted with an opaque `Workflow.Result({ success: AnyOrVoid, error:
|
|
19
|
+
* AnyOrVoid })` codec — same trick the cluster `ActivityRpc` uses.
|
|
20
|
+
* - Durable-deferred exits and clock completions use an opaque `Exit` codec.
|
|
21
|
+
*
|
|
22
|
+
* Crash recovery: each driver holds a time-bound lease (`worker` +
|
|
23
|
+
* `leaseExpiresAt`) on the exec doc and renews it via a heartbeat fiber. A
|
|
24
|
+
* scope-bound recovery poller queries for exec docs whose lease has lapsed and
|
|
25
|
+
* re-drives them in the local process, decoding the persisted payload and
|
|
26
|
+
* picking up persisted activity results from where the crashed driver left off.
|
|
27
|
+
*
|
|
28
|
+
* Durable clocks: `scheduleClock` writes a clock doc (`fireAt`, `deferredName`)
|
|
29
|
+
* and arms an in-process timer. A cross-partition clock poller fires any clock
|
|
30
|
+
* whose `fireAt` is due, completing the deferred idempotently (create-only) and
|
|
31
|
+
* deleting the doc. Survives restarts.
|
|
32
|
+
*/
|
|
33
|
+
import * as Effect from "effect-app/Effect";
|
|
34
|
+
import * as Layer from "effect-app/Layer";
|
|
35
|
+
import * as Option from "effect-app/Option";
|
|
36
|
+
import * as S from "effect-app/Schema";
|
|
37
|
+
import * as Cause from "effect/Cause";
|
|
38
|
+
import * as Duration from "effect/Duration";
|
|
39
|
+
import * as Exit from "effect/Exit";
|
|
40
|
+
import * as Fiber from "effect/Fiber";
|
|
41
|
+
import * as FiberMap from "effect/FiberMap";
|
|
42
|
+
import * as Redacted from "effect/Redacted";
|
|
43
|
+
import * as Schedule from "effect/Schedule";
|
|
44
|
+
import * as Workflow from "effect/workflow/Workflow";
|
|
45
|
+
import { makeUnsafe, WorkflowEngine, WorkflowInstance } from "effect/workflow/WorkflowEngine";
|
|
46
|
+
import { randomUUID } from "node:crypto";
|
|
47
|
+
import { CosmosClient, CosmosClientLayer, createContainerIfNotExists } from "./cosmos-client.js";
|
|
48
|
+
import { OptimisticConcurrencyException } from "./errors.js";
|
|
49
|
+
import { annotateCosmosResponse, annotateDb } from "./otel.js";
|
|
50
|
+
// Cosmos forbids '/', '\', '#', '?' in a resource id; workflow/deferred/clock
|
|
51
|
+
// names routinely contain '/', so every doc id is URI-encoded (mirrors
|
|
52
|
+
// `cosmosId` in ClusterCosmos). Partition keys (executionId) are exempt.
|
|
53
|
+
const cosmosId = (id) => encodeURIComponent(id);
|
|
54
|
+
const execId = "exec";
|
|
55
|
+
const activityKey = (name, attempt) => cosmosId(`activity::${name}::${attempt}`);
|
|
56
|
+
const deferredKey = (name) => cosmosId(`deferred::${name}`);
|
|
57
|
+
const clockKey = (name) => cosmosId(`clock::${name}`);
|
|
58
|
+
// Single-item Cosmos writes (`replace`) *throw* on 409/412/404 rather than
|
|
59
|
+
// returning the status code (only `read` and batch ops surface codes), so OCC
|
|
60
|
+
// conflicts must be matched on the thrown error — mirrors ClusterCosmos.
|
|
61
|
+
const isCosmosStatus = (u, code) => Cause.isUnknownError(u)
|
|
62
|
+
? isCosmosStatus(u.cause, code)
|
|
63
|
+
: typeof u === "object" && u !== null && "code" in u && u.code === code;
|
|
64
|
+
const isOptimisticError = (u) => isCosmosStatus(u, 409) || isCosmosStatus(u, 412) || isCosmosStatus(u, 404);
|
|
65
|
+
// --- Storage codecs ----------------------------------------------------------
|
|
66
|
+
// Values flowing through the engine's activity / deferred boundary are already
|
|
67
|
+
// schema-encoded, so the structure is round-tripped while the payload stays
|
|
68
|
+
// opaque (mirrors the cluster engine's `AnyOrVoid` usage).
|
|
69
|
+
const AnyOrVoid = S.Union([S.Any, S.Void]);
|
|
70
|
+
const ActivityResultCodec = S.fromJsonString(S.toCodecJson(Workflow.Result({ success: AnyOrVoid, error: AnyOrVoid })));
|
|
71
|
+
const DeferredExitCodec = S.fromJsonString(S.toCodecJson(S.Exit(AnyOrVoid, AnyOrVoid, S.Defect())));
|
|
72
|
+
const encodeActivityResult = (r) => Effect.orDie(S.encodeEffect(ActivityResultCodec)(r));
|
|
73
|
+
const decodeActivityResult = (s) => Effect.orDie(S.decodeEffect(ActivityResultCodec)(s));
|
|
74
|
+
const encodeDeferredExit = (e) => Effect.orDie(S.encodeEffect(DeferredExitCodec)(e));
|
|
75
|
+
const decodeDeferredExit = (s) => Effect.orDie(S.decodeEffect(DeferredExitCodec)(s));
|
|
76
|
+
const makeCosmosWorkflowEngine = Effect.fnUntraced(function* (cfg) {
|
|
77
|
+
const { db } = yield* CosmosClient;
|
|
78
|
+
const containerId = `${cfg.prefix ?? ""}workflow-engine`;
|
|
79
|
+
yield* Effect.promise(() => createContainerIfNotExists(db, {
|
|
80
|
+
id: containerId,
|
|
81
|
+
partitionKey: { paths: ["/_partitionKey"], version: 2 }
|
|
82
|
+
}, cfg));
|
|
83
|
+
const container = db.container(containerId);
|
|
84
|
+
const scope = yield* Effect.scope;
|
|
85
|
+
const workerId = cfg.workerId ?? randomUUID();
|
|
86
|
+
const leaseTtl = cfg.leaseTtl ?? Duration.seconds(30);
|
|
87
|
+
const heartbeatInterval = cfg.heartbeatInterval ?? Duration.seconds(10);
|
|
88
|
+
const recoveryInterval = cfg.recoveryInterval ?? Duration.seconds(15);
|
|
89
|
+
const clockPollInterval = cfg.clockPollInterval ?? Duration.seconds(5);
|
|
90
|
+
const annotate = (operation, executionId) => annotateDb({
|
|
91
|
+
operation,
|
|
92
|
+
system: "cosmosdb",
|
|
93
|
+
collection: containerId,
|
|
94
|
+
entity: "workflow",
|
|
95
|
+
extra: executionId !== undefined
|
|
96
|
+
? { "azure.cosmosdb.operation.partition_key": executionId, "app.entity.id": executionId }
|
|
97
|
+
: undefined
|
|
98
|
+
});
|
|
99
|
+
const workflows = new Map();
|
|
100
|
+
const locals = new Map();
|
|
101
|
+
const clocks = yield* FiberMap.make();
|
|
102
|
+
// Per-workflow codecs for the typed payload + top-level result. Cached by
|
|
103
|
+
// workflow name; derived from the workflow's own schemas so typed values
|
|
104
|
+
// (dates, branded ids, schema classes) survive the storage round-trip.
|
|
105
|
+
const makePayloadCodec = (workflow) => S.fromJsonString(S.toCodecJson(workflow.payloadSchema));
|
|
106
|
+
const payloadCodecCache = new Map();
|
|
107
|
+
const payloadCodecFor = (workflow) => {
|
|
108
|
+
let c = payloadCodecCache.get(workflow._tag);
|
|
109
|
+
if (!c) {
|
|
110
|
+
c = makePayloadCodec(workflow);
|
|
111
|
+
payloadCodecCache.set(workflow._tag, c);
|
|
112
|
+
}
|
|
113
|
+
return c;
|
|
114
|
+
};
|
|
115
|
+
const makeResultCodec = (workflow) => S.fromJsonString(S.toCodecJson(Workflow.Result({ success: workflow.successSchema, error: workflow.errorSchema })));
|
|
116
|
+
const resultCodecCache = new Map();
|
|
117
|
+
const resultCodecFor = (workflow) => {
|
|
118
|
+
let c = resultCodecCache.get(workflow._tag);
|
|
119
|
+
if (!c) {
|
|
120
|
+
c = makeResultCodec(workflow);
|
|
121
|
+
resultCodecCache.set(workflow._tag, c);
|
|
122
|
+
}
|
|
123
|
+
return c;
|
|
124
|
+
};
|
|
125
|
+
const encodePayload = (workflow, payload) => Effect.orDie(S.encodeEffect(payloadCodecFor(workflow))(payload));
|
|
126
|
+
const decodePayload = (workflow, s) => Effect.orDie(S.decodeEffect(payloadCodecFor(workflow))(s));
|
|
127
|
+
const encodeResult = (workflow, r) => Effect.orDie(S.encodeEffect(resultCodecFor(workflow))(r));
|
|
128
|
+
const decodeResult = (workflow, s) => Effect.orDie(S.decodeEffect(resultCodecFor(workflow))(s));
|
|
129
|
+
// --- Cosmos primitives -------------------------------------------------
|
|
130
|
+
const readExec = (executionId) => Effect
|
|
131
|
+
.gen(function* () {
|
|
132
|
+
const resp = yield* Effect.promise(() => container.item(execId, executionId).read());
|
|
133
|
+
yield* annotateCosmosResponse({ requestCharge: resp.requestCharge, statusCode: resp.statusCode });
|
|
134
|
+
return Option.fromNullishOr(resp.resource).pipe(Option.map((r) => ({ ...r, _etag: resp.etag })));
|
|
135
|
+
})
|
|
136
|
+
.pipe(annotate("readExec", executionId));
|
|
137
|
+
const replaceExec = (doc) => Effect
|
|
138
|
+
.gen(function* () {
|
|
139
|
+
const resp = yield* Effect.tryPromise(() => container.item(execId, doc._partitionKey).replace(doc, {
|
|
140
|
+
accessCondition: { type: "IfMatch", condition: doc._etag ?? "" }
|
|
141
|
+
}));
|
|
142
|
+
yield* annotateCosmosResponse({ requestCharge: resp.requestCharge, statusCode: resp.statusCode });
|
|
143
|
+
return { ...doc, _etag: resp.etag };
|
|
144
|
+
})
|
|
145
|
+
.pipe(Effect.catch((u) => isOptimisticError(u)
|
|
146
|
+
? Effect.fail(new OptimisticConcurrencyException({ type: "workflow.exec", id: doc._partitionKey, code: 412 }))
|
|
147
|
+
: Effect.die(u)), annotate("replaceExec", doc._partitionKey));
|
|
148
|
+
// Atomic create-or-noop using a single-op batch — returns true if created.
|
|
149
|
+
const createIfMissing = (body) => Effect.gen(function* () {
|
|
150
|
+
const resp = yield* Effect.promise(() => container.items.batch([{ operationType: "Create", resourceBody: body }], body._partitionKey));
|
|
151
|
+
const r = resp.result?.[0];
|
|
152
|
+
const code = r?.statusCode ?? 0;
|
|
153
|
+
if (code === 201)
|
|
154
|
+
return true;
|
|
155
|
+
if (code === 409)
|
|
156
|
+
return false;
|
|
157
|
+
return yield* Effect.die(new Error(`workflow-engine cosmos createIfMissing for ${body.id} failed: ${code}`));
|
|
158
|
+
});
|
|
159
|
+
// Last-writer-wins upsert — used to overwrite a persisted *suspended* activity
|
|
160
|
+
// result once it finally completes (create-only ops can't transition it).
|
|
161
|
+
const upsert = (body) => Effect.gen(function* () {
|
|
162
|
+
const resp = yield* Effect.promise(() => container.items.upsert(body));
|
|
163
|
+
yield* annotateCosmosResponse({ requestCharge: resp.requestCharge, statusCode: resp.statusCode });
|
|
164
|
+
});
|
|
165
|
+
const readPoint = (id, executionId) => Effect.promise(() => container.item(id, executionId).read()).pipe(Effect.map((r) => Option.fromNullishOr(r.resource)));
|
|
166
|
+
// --- Workflow result helpers ------------------------------------------
|
|
167
|
+
const completeResult = (workflow, state) => state.status === "complete" && state.completedResult
|
|
168
|
+
? Effect.map(decodeResult(workflow, state.completedResult), Option.some)
|
|
169
|
+
: Effect.succeedNone;
|
|
170
|
+
// --- Lease / claim ----------------------------------------------------
|
|
171
|
+
const leaseActive = (state, now) => state.worker !== undefined
|
|
172
|
+
&& state.worker !== workerId
|
|
173
|
+
&& state.leaseExpiresAt !== undefined
|
|
174
|
+
&& Date.parse(state.leaseExpiresAt) > now;
|
|
175
|
+
/**
|
|
176
|
+
* Try to claim a lease on `state`. Returns the updated doc on success, `None`
|
|
177
|
+
* if another worker holds an active lease, or on OCC conflict (caller may
|
|
178
|
+
* retry by re-reading).
|
|
179
|
+
*/
|
|
180
|
+
const tryClaim = (state) => Effect.gen(function* () {
|
|
181
|
+
const now = Date.now();
|
|
182
|
+
if (leaseActive(state, now))
|
|
183
|
+
return Option.none();
|
|
184
|
+
const updated = {
|
|
185
|
+
...state,
|
|
186
|
+
worker: workerId,
|
|
187
|
+
leaseExpiresAt: new Date(now + Duration.toMillis(leaseTtl)).toISOString()
|
|
188
|
+
};
|
|
189
|
+
return yield* replaceExec(updated).pipe(Effect.map(Option.some), Effect.catchTag("OptimisticConcurrencyException", () => Effect.succeed(Option.none())));
|
|
190
|
+
});
|
|
191
|
+
/**
|
|
192
|
+
* Renew lease until the local fiber stops or another worker takes the claim.
|
|
193
|
+
* Best-effort: failures are swallowed; loop simply retries on next tick.
|
|
194
|
+
*/
|
|
195
|
+
const heartbeat = (executionId) => Effect.gen(function* () {
|
|
196
|
+
while (true) {
|
|
197
|
+
yield* Effect.sleep(heartbeatInterval);
|
|
198
|
+
const local = locals.get(executionId);
|
|
199
|
+
const polled = local?.fiber?.pollUnsafe();
|
|
200
|
+
if (!local?.fiber || polled)
|
|
201
|
+
return;
|
|
202
|
+
const cur = yield* readExec(executionId).pipe(Effect.catchCause(() => Effect.succeed(Option.none())));
|
|
203
|
+
if (Option.isNone(cur))
|
|
204
|
+
continue;
|
|
205
|
+
const state = cur.value;
|
|
206
|
+
if (state.status === "complete" || state.worker !== workerId)
|
|
207
|
+
return;
|
|
208
|
+
yield* replaceExec({
|
|
209
|
+
...state,
|
|
210
|
+
leaseExpiresAt: new Date(Date.now() + Duration.toMillis(leaseTtl)).toISOString()
|
|
211
|
+
})
|
|
212
|
+
.pipe(Effect.catchTag("OptimisticConcurrencyException", () => Effect.void), Effect.catchCause(() => Effect.void));
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
// --- Drive logic -------------------------------------------------------
|
|
216
|
+
const drive = (executionId, payload, parent, entry) => Effect.gen(function* () {
|
|
217
|
+
let local = locals.get(executionId);
|
|
218
|
+
if (local?.fiber) {
|
|
219
|
+
const polled = local.fiber.pollUnsafe();
|
|
220
|
+
const stillRunning = !polled;
|
|
221
|
+
const completedNotResume = polled && polled._tag === "Success" && polled.value._tag === "Complete";
|
|
222
|
+
if (stillRunning || completedNotResume)
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
const stateOpt = yield* readExec(executionId);
|
|
226
|
+
if (Option.isNone(stateOpt) || stateOpt.value.status === "complete")
|
|
227
|
+
return;
|
|
228
|
+
// Best-effort claim: takes lease so recovery poller leaves us alone.
|
|
229
|
+
// Failure is tolerated — local fiber still drives; OCC guards persisted
|
|
230
|
+
// state so split-brain stays correct.
|
|
231
|
+
const claimed = yield* tryClaim(stateOpt.value);
|
|
232
|
+
const state = Option.isSome(claimed) ? claimed.value : stateOpt.value;
|
|
233
|
+
const instance = WorkflowInstance.initial(entry.workflow, executionId);
|
|
234
|
+
instance.interrupted = state.interrupted;
|
|
235
|
+
if (!local) {
|
|
236
|
+
local = { instance, fiber: undefined, parent };
|
|
237
|
+
locals.set(executionId, local);
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
local.instance = instance;
|
|
241
|
+
}
|
|
242
|
+
const onComplete = Effect.fnUntraced(function* (result) {
|
|
243
|
+
const current = yield* readExec(executionId);
|
|
244
|
+
if (Option.isNone(current) || current.value.status === "complete")
|
|
245
|
+
return;
|
|
246
|
+
const isComplete = result._tag === "Complete";
|
|
247
|
+
const completedResult = isComplete ? yield* encodeResult(entry.workflow, result) : undefined;
|
|
248
|
+
yield* replaceExec({
|
|
249
|
+
...current.value,
|
|
250
|
+
status: isComplete ? "complete" : current.value.status,
|
|
251
|
+
suspended: result._tag === "Suspended",
|
|
252
|
+
// Never downgrade a persisted interrupt: a concurrent `interrupt` may
|
|
253
|
+
// have set the flag while this driver was suspending. Losing it would
|
|
254
|
+
// leave a re-drive unable to collapse the suspension.
|
|
255
|
+
interrupted: instance.interrupted || current.value.interrupted,
|
|
256
|
+
completedResult,
|
|
257
|
+
// Release lease on completion so the doc isn't seen as orphaned.
|
|
258
|
+
worker: isComplete ? undefined : current.value.worker,
|
|
259
|
+
leaseExpiresAt: isComplete ? undefined : current.value.leaseExpiresAt
|
|
260
|
+
})
|
|
261
|
+
.pipe(Effect.catchTag("OptimisticConcurrencyException", () => Effect.void));
|
|
262
|
+
if (parent && isComplete) {
|
|
263
|
+
yield* Effect.forkIn(driveById(parent), scope);
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
local.fiber = yield* entry.execute(payload, executionId).pipe(Effect.onExit(() => {
|
|
267
|
+
if (!instance.interrupted)
|
|
268
|
+
return Effect.void;
|
|
269
|
+
instance.suspended = false;
|
|
270
|
+
return Effect.withFiber((fiber) => Effect.interruptible(Fiber.interrupt(fiber)));
|
|
271
|
+
}), Workflow.intoResult, Effect.provideService(WorkflowInstance, instance), Effect.provideService(WorkflowEngine, engine), Effect.tap(onComplete), Effect.forkIn(entry.scope));
|
|
272
|
+
if (Option.isSome(claimed)) {
|
|
273
|
+
yield* Effect.forkIn(heartbeat(executionId), scope);
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
const driveById = (executionId) => Effect.gen(function* () {
|
|
277
|
+
const stateOpt = yield* readExec(executionId);
|
|
278
|
+
if (Option.isNone(stateOpt))
|
|
279
|
+
return;
|
|
280
|
+
const state = stateOpt.value;
|
|
281
|
+
const entry = workflows.get(state.workflowName);
|
|
282
|
+
if (!entry)
|
|
283
|
+
return;
|
|
284
|
+
const payload = yield* decodePayload(entry.workflow, state.payload);
|
|
285
|
+
yield* drive(executionId, payload, state.parent, entry);
|
|
286
|
+
});
|
|
287
|
+
// --- Clock firing -----------------------------------------------------
|
|
288
|
+
// Persist deferred completion (first-writer-wins via createIfMissing),
|
|
289
|
+
// resume the workflow, then clean up the clock doc.
|
|
290
|
+
const fireClock = (doc) => Effect.gen(function* () {
|
|
291
|
+
const created = yield* createIfMissing({
|
|
292
|
+
id: deferredKey(doc.deferredName),
|
|
293
|
+
_partitionKey: doc._partitionKey,
|
|
294
|
+
type: "deferred",
|
|
295
|
+
exit: yield* encodeDeferredExit(Exit.void)
|
|
296
|
+
})
|
|
297
|
+
.pipe(annotate("clockFire", doc._partitionKey));
|
|
298
|
+
if (created)
|
|
299
|
+
yield* driveById(doc._partitionKey);
|
|
300
|
+
yield* Effect.promise(() => container.item(doc.id, doc._partitionKey).delete()).pipe(Effect.catchCause(() => Effect.void));
|
|
301
|
+
});
|
|
302
|
+
// Persist `interrupted: true`, retrying on OCC. A suspending driver's
|
|
303
|
+
// onComplete (or a heartbeat renewal) can win the etag race; silently
|
|
304
|
+
// dropping the flag would leave the subsequent re-drive reading
|
|
305
|
+
// `interrupted: false` and re-suspending forever. Retry until the flag is
|
|
306
|
+
// durably set (or the exec is already complete/gone). Unlike SQLite — whose
|
|
307
|
+
// synchronous writes never interleave here — Cosmos round-trips open a real
|
|
308
|
+
// race window, so the write must converge rather than swallow the conflict.
|
|
309
|
+
const markInterrupted = (executionId) => Effect.gen(function* () {
|
|
310
|
+
while (true) {
|
|
311
|
+
const current = yield* readExec(executionId);
|
|
312
|
+
if (Option.isNone(current) || current.value.status === "complete" || current.value.interrupted) {
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
const persisted = yield* replaceExec({ ...current.value, interrupted: true }).pipe(Effect.as(true), Effect.catchTag("OptimisticConcurrencyException", () => Effect.succeed(false)));
|
|
316
|
+
if (persisted)
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
// --- Encoded engine ----------------------------------------------------
|
|
321
|
+
const encoded = {
|
|
322
|
+
register: Effect.fnUntraced(function* (workflow, execute) {
|
|
323
|
+
workflows.set(workflow._tag, {
|
|
324
|
+
workflow,
|
|
325
|
+
execute,
|
|
326
|
+
scope: yield* Effect.scope
|
|
327
|
+
});
|
|
328
|
+
}),
|
|
329
|
+
execute: Effect.fnUntraced(function* (workflow, options) {
|
|
330
|
+
const entry = workflows.get(workflow._tag);
|
|
331
|
+
if (!entry) {
|
|
332
|
+
return yield* Effect.orDie(Effect.fail(`Workflow ${workflow._tag} is not registered`));
|
|
333
|
+
}
|
|
334
|
+
const initial = {
|
|
335
|
+
id: execId,
|
|
336
|
+
_partitionKey: options.executionId,
|
|
337
|
+
type: "exec",
|
|
338
|
+
workflowName: workflow._tag,
|
|
339
|
+
payload: yield* encodePayload(workflow, options.payload),
|
|
340
|
+
parent: options.parent?.executionId,
|
|
341
|
+
status: "running",
|
|
342
|
+
suspended: false,
|
|
343
|
+
interrupted: false
|
|
344
|
+
};
|
|
345
|
+
yield* createIfMissing(initial).pipe(annotate("execute.claim", options.executionId));
|
|
346
|
+
// Drive unconditionally; `drive`'s own guard short-circuits a still-running
|
|
347
|
+
// or completed fiber and re-drives a suspended one (matches Sqlite).
|
|
348
|
+
yield* drive(options.executionId, options.payload, options.parent?.executionId, entry);
|
|
349
|
+
if (options.discard)
|
|
350
|
+
return undefined;
|
|
351
|
+
const local = locals.get(options.executionId);
|
|
352
|
+
if (local?.fiber) {
|
|
353
|
+
return (yield* Fiber.join(local.fiber));
|
|
354
|
+
}
|
|
355
|
+
// Foreign-owned execution: poll until exec doc reports complete.
|
|
356
|
+
while (true) {
|
|
357
|
+
const cur = yield* readExec(options.executionId);
|
|
358
|
+
if (Option.isSome(cur)) {
|
|
359
|
+
const c = yield* completeResult(workflow, cur.value);
|
|
360
|
+
if (Option.isSome(c))
|
|
361
|
+
return c.value;
|
|
362
|
+
}
|
|
363
|
+
yield* Effect.sleep(Duration.millis(500));
|
|
364
|
+
}
|
|
365
|
+
}),
|
|
366
|
+
poll: (workflow, executionId) => Effect.gen(function* () {
|
|
367
|
+
const local = locals.get(executionId);
|
|
368
|
+
if (local?.fiber) {
|
|
369
|
+
const exit = local.fiber.pollUnsafe();
|
|
370
|
+
if (!exit)
|
|
371
|
+
return Option.none();
|
|
372
|
+
if (exit._tag !== "Success")
|
|
373
|
+
return yield* Effect.die(exit.cause);
|
|
374
|
+
return Option.some(exit.value);
|
|
375
|
+
}
|
|
376
|
+
const state = yield* readExec(executionId);
|
|
377
|
+
if (Option.isNone(state))
|
|
378
|
+
return Option.none();
|
|
379
|
+
return yield* completeResult(workflow, state.value);
|
|
380
|
+
}),
|
|
381
|
+
interrupt: Effect.fnUntraced(function* (_workflow, executionId) {
|
|
382
|
+
const local = locals.get(executionId);
|
|
383
|
+
if (local)
|
|
384
|
+
local.instance.interrupted = true;
|
|
385
|
+
yield* markInterrupted(executionId);
|
|
386
|
+
yield* driveById(executionId);
|
|
387
|
+
}),
|
|
388
|
+
interruptUnsafe: Effect.fnUntraced(function* (_workflow, executionId) {
|
|
389
|
+
const local = locals.get(executionId);
|
|
390
|
+
if (local)
|
|
391
|
+
local.instance.interrupted = true;
|
|
392
|
+
yield* markInterrupted(executionId);
|
|
393
|
+
if (local?.fiber)
|
|
394
|
+
yield* Fiber.interrupt(local.fiber);
|
|
395
|
+
}),
|
|
396
|
+
resume: (_workflow, executionId) => driveById(executionId),
|
|
397
|
+
activityExecute: Effect.fnUntraced(function* (activity, attempt) {
|
|
398
|
+
const instance = yield* WorkflowInstance;
|
|
399
|
+
const id = activityKey(activity.name, attempt);
|
|
400
|
+
const existing = yield* readPoint(id, instance.executionId).pipe(annotate("activityRead", instance.executionId));
|
|
401
|
+
if (Option.isSome(existing)) {
|
|
402
|
+
const prev = yield* decodeActivityResult(existing.value.result);
|
|
403
|
+
// A completed activity is replayed from its persisted result; a
|
|
404
|
+
// suspended one must re-run (it parked on a clock/deferred).
|
|
405
|
+
if (prev._tag === "Complete")
|
|
406
|
+
return prev;
|
|
407
|
+
}
|
|
408
|
+
const activityInstance = WorkflowInstance.initial(instance.workflow, instance.executionId);
|
|
409
|
+
activityInstance.interrupted = instance.interrupted;
|
|
410
|
+
const result = yield* activity.executeEncoded.pipe(Workflow.intoResult, Effect.provideService(WorkflowInstance, activityInstance));
|
|
411
|
+
const doc = {
|
|
412
|
+
id,
|
|
413
|
+
_partitionKey: instance.executionId,
|
|
414
|
+
type: "activity",
|
|
415
|
+
result: yield* encodeActivityResult(result)
|
|
416
|
+
};
|
|
417
|
+
if (Option.isSome(existing)) {
|
|
418
|
+
// Overwrite the previously persisted *suspended* doc with the new result.
|
|
419
|
+
yield* upsert(doc).pipe(annotate("activityPersist", instance.executionId));
|
|
420
|
+
return result;
|
|
421
|
+
}
|
|
422
|
+
// First-writer-wins: if persistence loses the race, use the persisted result.
|
|
423
|
+
const persisted = yield* createIfMissing(doc).pipe(annotate("activityPersist", instance.executionId));
|
|
424
|
+
if (persisted)
|
|
425
|
+
return result;
|
|
426
|
+
const winner = yield* readPoint(id, instance.executionId);
|
|
427
|
+
if (Option.isSome(winner)) {
|
|
428
|
+
const w = yield* decodeActivityResult(winner.value.result);
|
|
429
|
+
if (w._tag === "Complete")
|
|
430
|
+
return w;
|
|
431
|
+
}
|
|
432
|
+
return result;
|
|
433
|
+
}),
|
|
434
|
+
deferredResult: Effect.fnUntraced(function* (deferred) {
|
|
435
|
+
const instance = yield* WorkflowInstance;
|
|
436
|
+
const got = yield* readPoint(deferredKey(deferred.name), instance.executionId).pipe(annotate("deferredRead", instance.executionId));
|
|
437
|
+
if (Option.isNone(got))
|
|
438
|
+
return Option.none();
|
|
439
|
+
return Option.some(yield* decodeDeferredExit(got.value.exit));
|
|
440
|
+
}),
|
|
441
|
+
deferredDone: Effect.fnUntraced(function* (options) {
|
|
442
|
+
const created = yield* createIfMissing({
|
|
443
|
+
id: deferredKey(options.deferredName),
|
|
444
|
+
_partitionKey: options.executionId,
|
|
445
|
+
type: "deferred",
|
|
446
|
+
exit: yield* encodeDeferredExit(options.exit)
|
|
447
|
+
})
|
|
448
|
+
.pipe(annotate("deferredPersist", options.executionId));
|
|
449
|
+
if (!created)
|
|
450
|
+
return;
|
|
451
|
+
yield* driveById(options.executionId);
|
|
452
|
+
}),
|
|
453
|
+
scheduleClock: (workflow, options) => {
|
|
454
|
+
const fireAt = new Date(Date.now() + Duration.toMillis(options.clock.duration)).toISOString();
|
|
455
|
+
const clockDoc = {
|
|
456
|
+
id: clockKey(options.clock.name),
|
|
457
|
+
_partitionKey: options.executionId,
|
|
458
|
+
type: "clock",
|
|
459
|
+
workflowName: workflow._tag,
|
|
460
|
+
deferredName: options.clock.deferred.name,
|
|
461
|
+
fireAt
|
|
462
|
+
};
|
|
463
|
+
return Effect.gen(function* () {
|
|
464
|
+
yield* createIfMissing(clockDoc).pipe(annotate("clockPersist", options.executionId));
|
|
465
|
+
// Fast-path in-process timer. If this process dies, the clock poller
|
|
466
|
+
// picks up the persisted doc and fires the deferred.
|
|
467
|
+
yield* fireClock(clockDoc).pipe(Effect.delay(options.clock.duration), FiberMap.run(clocks, `${options.executionId}/${options.clock.name}`, { onlyIfMissing: true }), Effect.asVoid);
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
};
|
|
471
|
+
const engine = makeUnsafe(encoded);
|
|
472
|
+
// --- Recovery poller --------------------------------------------------
|
|
473
|
+
// Scan for executions whose lease has lapsed (or was never set) and
|
|
474
|
+
// re-drive them locally. driveById will go through claim → fork fiber,
|
|
475
|
+
// resuming activities from persisted results.
|
|
476
|
+
if (Duration.toMillis(recoveryInterval) > 0) {
|
|
477
|
+
const recoverStep = Effect
|
|
478
|
+
.gen(function* () {
|
|
479
|
+
const nowIso = new Date().toISOString();
|
|
480
|
+
const stale = yield* Effect.promise(() => container
|
|
481
|
+
.items
|
|
482
|
+
.query({
|
|
483
|
+
query: "SELECT c._partitionKey, c.workflowName FROM c WHERE c.type = 'exec' AND c.status = 'running' AND (NOT IS_DEFINED(c.leaseExpiresAt) OR c.leaseExpiresAt <= @now)",
|
|
484
|
+
parameters: [{ name: "@now", value: nowIso }]
|
|
485
|
+
})
|
|
486
|
+
.fetchAll());
|
|
487
|
+
for (const row of stale.resources) {
|
|
488
|
+
if (!workflows.has(row.workflowName))
|
|
489
|
+
continue;
|
|
490
|
+
const local = locals.get(row._partitionKey);
|
|
491
|
+
if (local?.fiber && !local.fiber.pollUnsafe())
|
|
492
|
+
continue;
|
|
493
|
+
yield* Effect.forkIn(driveById(row._partitionKey), scope);
|
|
494
|
+
}
|
|
495
|
+
})
|
|
496
|
+
.pipe(annotate("recoveryScan"), Effect.catchCause(() => Effect.void));
|
|
497
|
+
yield* recoverStep.pipe(Effect.repeat(Schedule.spaced(recoveryInterval)), Effect.forkIn(scope));
|
|
498
|
+
}
|
|
499
|
+
// --- Clock poller -----------------------------------------------------
|
|
500
|
+
// Cross-partition scan for clocks whose fireAt is due. Fires the deferred
|
|
501
|
+
// via createIfMissing (idempotent) so multiple pollers across processes
|
|
502
|
+
// converge. Also acts as the restart recovery path for clocks scheduled
|
|
503
|
+
// before a crash.
|
|
504
|
+
if (Duration.toMillis(clockPollInterval) > 0) {
|
|
505
|
+
const clockStep = Effect
|
|
506
|
+
.gen(function* () {
|
|
507
|
+
const nowIso = new Date().toISOString();
|
|
508
|
+
const due = yield* Effect.promise(() => container
|
|
509
|
+
.items
|
|
510
|
+
.query({
|
|
511
|
+
query: "SELECT c.id, c._partitionKey, c.workflowName, c.deferredName FROM c WHERE c.type = 'clock' AND c.fireAt <= @now",
|
|
512
|
+
parameters: [{ name: "@now", value: nowIso }]
|
|
513
|
+
})
|
|
514
|
+
.fetchAll());
|
|
515
|
+
for (const row of due.resources) {
|
|
516
|
+
yield* Effect.forkIn(fireClock({
|
|
517
|
+
id: row.id,
|
|
518
|
+
_partitionKey: row._partitionKey,
|
|
519
|
+
type: "clock",
|
|
520
|
+
workflowName: row.workflowName,
|
|
521
|
+
deferredName: row.deferredName,
|
|
522
|
+
fireAt: nowIso
|
|
523
|
+
}), scope);
|
|
524
|
+
}
|
|
525
|
+
})
|
|
526
|
+
.pipe(annotate("clockScan"), Effect.catchCause(() => Effect.void));
|
|
527
|
+
yield* clockStep.pipe(Effect.repeat(Schedule.spaced(clockPollInterval)), Effect.forkIn(scope));
|
|
528
|
+
}
|
|
529
|
+
return engine;
|
|
530
|
+
});
|
|
531
|
+
/**
|
|
532
|
+
* Cosmos DB backed `WorkflowEngine` layer.
|
|
533
|
+
*
|
|
534
|
+
* Per-execution writes share a partition key (TransactionalBatch-eligible) and
|
|
535
|
+
* use OCC via `_etag`/IfMatch, giving first-writer-wins semantics for activity
|
|
536
|
+
* results, durable-deferred completions, and exec-state transitions. All
|
|
537
|
+
* persisted payloads/results/exits are round-tripped through schema codecs.
|
|
538
|
+
*/
|
|
539
|
+
export const layerCosmos = (cfg) => Layer
|
|
540
|
+
.effect(WorkflowEngine)(makeCosmosWorkflowEngine(cfg))
|
|
541
|
+
.pipe(Layer.provide(CosmosClientLayer(Redacted.value(cfg.url), cfg.dbName)));
|
|
542
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiV29ya2Zsb3dFbmdpbmVDb3Ntb3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvV29ya2Zsb3dFbmdpbmVDb3Ntb3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0ErQkc7QUFDSCxPQUFPLEtBQUssTUFBTSxNQUFNLG1CQUFtQixDQUFBO0FBQzNDLE9BQU8sS0FBSyxLQUFLLE1BQU0sa0JBQWtCLENBQUE7QUFDekMsT0FBTyxLQUFLLE1BQU0sTUFBTSxtQkFBbUIsQ0FBQTtBQUMzQyxPQUFPLEtBQUssQ0FBQyxNQUFNLG1CQUFtQixDQUFBO0FBQ3RDLE9BQU8sS0FBSyxLQUFLLE1BQU0sY0FBYyxDQUFBO0FBQ3JDLE9BQU8sS0FBSyxRQUFRLE1BQU0saUJBQWlCLENBQUE7QUFDM0MsT0FBTyxLQUFLLElBQUksTUFBTSxhQUFhLENBQUE7QUFDbkMsT0FBTyxLQUFLLEtBQUssTUFBTSxjQUFjLENBQUE7QUFDckMsT0FBTyxLQUFLLFFBQVEsTUFBTSxpQkFBaUIsQ0FBQTtBQUMzQyxPQUFPLEtBQUssUUFBUSxNQUFNLGlCQUFpQixDQUFBO0FBQzNDLE9BQU8sS0FBSyxRQUFRLE1BQU0saUJBQWlCLENBQUE7QUFFM0MsT0FBTyxLQUFLLFFBQVEsTUFBTSwwQkFBMEIsQ0FBQTtBQUNwRCxPQUFPLEVBQWdCLFVBQVUsRUFBRSxjQUFjLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQTtBQUMzRyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sYUFBYSxDQUFBO0FBQ3hDLE9BQU8sRUFBRSxZQUFZLEVBQUUsaUJBQWlCLEVBQWtDLDBCQUEwQixFQUFFLE1BQU0sb0JBQW9CLENBQUE7QUFDaEksT0FBTyxFQUFFLDhCQUE4QixFQUFFLE1BQU0sYUFBYSxDQUFBO0FBQzVELE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxVQUFVLEVBQUUsTUFBTSxXQUFXLENBQUE7QUErRDlELDhF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
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as Layer from "effect-app/Layer";
|
|
2
|
+
import * as Duration from "effect/Duration";
|
|
3
|
+
import { SqlClient } from "effect/sql";
|
|
4
|
+
import { WorkflowEngine } from "effect/workflow/WorkflowEngine";
|
|
5
|
+
export interface WorkflowEngineSqliteConfig {
|
|
6
|
+
/** Optional prefix for table names (e.g. `tenant_`). */
|
|
7
|
+
readonly prefix?: string;
|
|
8
|
+
/** Lease duration before a claim is considered stale. Default 30s. */
|
|
9
|
+
readonly leaseTtl?: Duration.Duration;
|
|
10
|
+
/** Renewal cadence — should be < leaseTtl. Default 10s. */
|
|
11
|
+
readonly heartbeatInterval?: Duration.Duration;
|
|
12
|
+
/** Cadence for scanning stale leases. Default 15s. Set to `Duration.zero` to disable. */
|
|
13
|
+
readonly recoveryInterval?: Duration.Duration;
|
|
14
|
+
/** Cadence for scanning due clocks. Default 5s. Set to `Duration.zero` to disable. */
|
|
15
|
+
readonly clockPollInterval?: Duration.Duration;
|
|
16
|
+
/** Stable worker identity; defaults to a random UUID per process. */
|
|
17
|
+
readonly workerId?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* SQLite backed `WorkflowEngine` layer. Requires an ambient `SqlClient`
|
|
21
|
+
* (`@effect/sql-sqlite-node` or a compatible client).
|
|
22
|
+
*/
|
|
23
|
+
export declare const layerSqlite: (cfg?: WorkflowEngineSqliteConfig) => Layer.Layer<WorkflowEngine, never, SqlClient.SqlClient>;
|
|
24
|
+
//# sourceMappingURL=WorkflowEngineSqlite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkflowEngineSqlite.d.ts","sourceRoot":"","sources":["../src/WorkflowEngineSqlite.ts"],"names":[],"mappings":"AAoCA,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAA;AAGzC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAM3C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAEtC,OAAO,EAA4B,cAAc,EAAoB,MAAM,gCAAgC,CAAA;AAK3G,MAAM,WAAW,0BAA0B;IACzC,wDAAwD;IACxD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,sEAAsE;IACtE,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAA;IACrC,2DAA2D;IAC3D,QAAQ,CAAC,iBAAiB,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAA;IAC9C,yFAAyF;IACzF,QAAQ,CAAC,gBAAgB,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAA;IAC7C,sFAAsF;IACtF,QAAQ,CAAC,iBAAiB,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAA;IAC9C,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAC3B;AAouBD;;;GAGG;AACH,eAAO,MAAM,WAAW,SACjB,0BAA0B,KAC9B,KAAK,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,EAAE,SAAS,CAAC,SAAS,CACI,CAAA"}
|