@effect-app/infra 4.0.0-beta.26 → 4.0.0-beta.261
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 +1973 -0
- package/_check.sh +1 -1
- package/dist/CUPS.d.ts +30 -11
- package/dist/CUPS.d.ts.map +1 -1
- package/dist/CUPS.js +35 -14
- package/dist/ClusterCosmos.d.ts +64 -0
- package/dist/ClusterCosmos.d.ts.map +1 -0
- package/dist/ClusterCosmos.js +501 -0
- package/dist/ClusterServiceBus.d.ts +67 -0
- package/dist/ClusterServiceBus.d.ts.map +1 -0
- package/dist/ClusterServiceBus.js +82 -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 +111 -147
- package/dist/Emailer/Sendgrid.d.ts.map +1 -1
- package/dist/Emailer/Sendgrid.js +24 -19
- package/dist/Emailer/fake.d.ts +2 -2
- package/dist/Emailer/fake.d.ts.map +1 -1
- package/dist/Emailer/fake.js +4 -4
- package/dist/MainFiberSet.d.ts +12 -9
- package/dist/MainFiberSet.d.ts.map +1 -1
- package/dist/MainFiberSet.js +10 -6
- package/dist/QueueMaker/SQLQueue.d.ts +8 -9
- package/dist/QueueMaker/SQLQueue.d.ts.map +1 -1
- package/dist/QueueMaker/SQLQueue.js +138 -120
- package/dist/QueueMaker/errors.d.ts +5 -3
- package/dist/QueueMaker/errors.d.ts.map +1 -1
- package/dist/QueueMaker/errors.js +4 -2
- package/dist/QueueMaker/memQueue.d.ts +10 -6
- package/dist/QueueMaker/memQueue.d.ts.map +1 -1
- package/dist/QueueMaker/memQueue.js +84 -68
- package/dist/QueueMaker/sbqueue.d.ts +9 -5
- package/dist/QueueMaker/sbqueue.d.ts.map +1 -1
- package/dist/QueueMaker/sbqueue.js +60 -58
- package/dist/RequestFiberSet.d.ts +10 -7
- package/dist/RequestFiberSet.d.ts.map +1 -1
- package/dist/RequestFiberSet.js +13 -8
- package/dist/SQL/Model.d.ts +468 -0
- package/dist/SQL/Model.d.ts.map +1 -0
- package/dist/SQL/Model.js +469 -0
- package/dist/SQL.d.ts +2 -0
- package/dist/SQL.d.ts.map +1 -0
- package/dist/{adapters/SQL.js → SQL.js} +1 -1
- package/dist/ServiceBus.d.ts +61 -0
- package/dist/ServiceBus.d.ts.map +1 -0
- package/dist/ServiceBus.js +108 -0
- package/dist/Store/Cosmos/query.d.ts +15 -4
- package/dist/Store/Cosmos/query.d.ts.map +1 -1
- package/dist/Store/Cosmos/query.js +179 -41
- package/dist/Store/Cosmos.d.ts +3 -3
- package/dist/Store/Cosmos.d.ts.map +1 -1
- package/dist/Store/Cosmos.js +344 -246
- package/dist/Store/Disk.d.ts +5 -5
- package/dist/Store/Disk.d.ts.map +1 -1
- package/dist/Store/Disk.js +78 -38
- package/dist/Store/Memory.d.ts +7 -10
- package/dist/Store/Memory.d.ts.map +1 -1
- package/dist/Store/Memory.js +326 -66
- 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 +232 -0
- package/dist/Store/SQL/query.d.ts +49 -0
- package/dist/Store/SQL/query.d.ts.map +1 -0
- package/dist/Store/SQL/query.js +527 -0
- package/dist/Store/SQL.d.ts +21 -0
- package/dist/Store/SQL.d.ts.map +1 -0
- package/dist/Store/SQL.js +449 -0
- package/dist/Store/codeFilter.d.ts +5 -5
- package/dist/Store/codeFilter.d.ts.map +1 -1
- package/dist/Store/codeFilter.js +6 -3
- package/dist/Store/index.d.ts +7 -5
- package/dist/Store/index.d.ts.map +1 -1
- package/dist/Store/index.js +18 -5
- package/dist/Store/utils.d.ts +4 -3
- package/dist/Store/utils.d.ts.map +1 -1
- package/dist/Store/utils.js +5 -5
- package/dist/WorkflowEngineCosmos.d.ts +29 -0
- package/dist/WorkflowEngineCosmos.d.ts.map +1 -0
- package/dist/WorkflowEngineCosmos.js +521 -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 +2 -2
- package/dist/arbs.d.ts.map +1 -1
- package/dist/arbs.js +5 -3
- package/dist/codec.d.ts +5 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/codec.js +5 -0
- package/dist/cosmos-client.d.ts +16 -0
- package/dist/cosmos-client.d.ts.map +1 -0
- package/dist/cosmos-client.js +11 -0
- package/dist/errorReporter.d.ts +7 -5
- package/dist/errorReporter.d.ts.map +1 -1
- package/dist/errorReporter.js +23 -27
- package/dist/errors.d.ts +1 -1
- package/dist/fileUtil.d.ts +2 -2
- package/dist/fileUtil.d.ts.map +1 -1
- package/dist/fileUtil.js +2 -2
- package/dist/index.d.ts +3 -2
- 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 +3 -0
- package/dist/internal/health.d.ts.map +1 -0
- package/dist/internal/health.js +5 -0
- package/dist/layerUtils.d.ts +32 -0
- package/dist/layerUtils.d.ts.map +1 -0
- package/dist/layerUtils.js +17 -0
- package/dist/logger/jsonLogger.d.ts +2 -2
- package/dist/logger/jsonLogger.d.ts.map +1 -1
- package/dist/logger/jsonLogger.js +5 -3
- package/dist/logger/logFmtLogger.d.ts +2 -2
- package/dist/logger/logFmtLogger.d.ts.map +1 -1
- package/dist/logger/logFmtLogger.js +3 -3
- package/dist/logger/shared.d.ts +3 -3
- package/dist/logger/shared.d.ts.map +1 -1
- package/dist/logger/shared.js +5 -5
- package/dist/logger.d.ts +1 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/memQueue.d.ts +15 -0
- package/dist/memQueue.d.ts.map +1 -0
- package/dist/memQueue.js +21 -0
- package/dist/middlewares.d.ts +10 -0
- package/dist/middlewares.d.ts.map +1 -0
- package/dist/{api/middlewares.js → middlewares.js} +1 -1
- package/dist/mongo-client.d.ts +11 -0
- 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 +65 -0
- package/dist/rateLimit.d.ts +12 -4
- package/dist/rateLimit.d.ts.map +1 -1
- package/dist/rateLimit.js +7 -12
- package/dist/redis-client.d.ts +42 -0
- package/dist/redis-client.d.ts.map +1 -0
- package/dist/redis-client.js +98 -0
- package/dist/reportError.d.ts +4 -0
- package/dist/reportError.d.ts.map +1 -0
- package/dist/reportError.js +28 -0
- package/dist/routing/middleware/RouterMiddleware.d.ts +16 -0
- 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 +128 -0
- package/dist/routing/middleware.d.ts +3 -0
- 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 +4 -0
- package/dist/routing/schema/jwt.d.ts.map +1 -0
- package/dist/routing/schema/jwt.js +13 -0
- package/dist/routing/tsort.d.ts +8 -0
- package/dist/routing/tsort.d.ts.map +1 -0
- package/dist/routing/tsort.js +51 -0
- package/dist/routing/utils.d.ts +19 -0
- package/dist/routing/utils.d.ts.map +1 -0
- package/dist/routing/utils.js +45 -0
- package/dist/routing.d.ts +184 -0
- package/dist/routing.d.ts.map +1 -0
- package/dist/routing.js +236 -0
- package/dist/test.d.ts +3 -3
- package/dist/test.d.ts.map +1 -1
- package/dist/test.js +2 -2
- package/dist/util.d.ts +3 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +14 -0
- package/dist/vitest.d.ts +1 -1
- package/docs/cluster-storage.md +26 -0
- package/docs/workflow-engine.md +262 -0
- package/examples/query.ts +47 -39
- package/package.json +31 -345
- package/run.sh +1 -0
- package/src/CUPS.ts +52 -13
- package/src/ClusterCosmos.ts +984 -0
- package/src/ClusterServiceBus.ts +242 -0
- package/src/{api/ContextProvider.ts → ContextProvider.ts} +19 -16
- package/src/Emailer/Sendgrid.ts +82 -59
- package/src/Emailer/fake.ts +3 -3
- package/src/MainFiberSet.ts +12 -10
- package/src/QueueMaker/SQLQueue.ts +153 -156
- package/src/QueueMaker/errors.ts +3 -1
- package/src/QueueMaker/memQueue.ts +113 -107
- package/src/QueueMaker/sbqueue.ts +78 -90
- package/src/RequestFiberSet.ts +13 -8
- package/src/{adapters/SQL → SQL}/Model.ts +42 -41
- package/src/ServiceBus.ts +219 -0
- package/src/Store/Cosmos/query.ts +216 -52
- package/src/Store/Cosmos.ts +493 -353
- package/src/Store/Disk.ts +109 -69
- package/src/Store/Memory.ts +365 -96
- package/src/Store/SQL/Pg.ts +363 -0
- package/src/Store/SQL/query.ts +603 -0
- package/src/Store/SQL.ts +735 -0
- package/src/Store/codeFilter.ts +8 -5
- package/src/Store/index.ts +21 -6
- package/src/Store/utils.ts +26 -24
- package/src/WorkflowEngineCosmos.ts +719 -0
- package/src/WorkflowEngineSqlite.ts +813 -0
- package/src/arbs.ts +5 -3
- package/src/{adapters/cosmos-client.ts → cosmos-client.ts} +5 -3
- package/src/errorReporter.ts +66 -76
- 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 +4 -2
- package/src/logger/logFmtLogger.ts +2 -2
- package/src/logger/shared.ts +5 -4
- package/src/{adapters/memQueue.ts → memQueue.ts} +5 -4
- package/src/{adapters/mongo-client.ts → mongo-client.ts} +4 -2
- package/src/otel.ts +152 -0
- package/src/rateLimit.ts +34 -23
- 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/{api/routing → routing}/middleware/middleware.ts +62 -17
- package/src/routing/middleware.ts +4 -0
- package/src/{api/routing → routing}/schema/jwt.ts +2 -1
- package/src/{api/routing → routing}/utils.ts +2 -1
- package/src/routing.ts +768 -0
- package/src/test.ts +2 -2
- package/test/auth.test.ts +101 -0
- package/test/cluster-cosmos.test.ts +590 -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 +28 -32
- package/test/cosmos-query.test.ts +159 -0
- package/test/dist/_check-agg-infer.test-d.d.ts +2 -0
- package/test/dist/_check-agg-infer.test-d.d.ts.map +1 -0
- package/test/dist/_check-agg-infer.test-d.js +19 -0
- package/test/dist/_check-proj-infer.test-d.d.ts +2 -0
- package/test/dist/_check-proj-infer.test-d.d.ts.map +1 -0
- package/test/dist/_check-proj-infer.test-d.js +16 -0
- package/test/dist/_check-tighten.test-d.d.ts +2 -0
- package/test/dist/_check-tighten.test-d.d.ts.map +1 -0
- package/test/dist/_check-tighten.test-d.js +21 -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-query.test.d.ts.map +1 -0
- package/test/dist/date-query.test.d.ts.map +1 -0
- package/test/dist/fixtures.d.ts +30 -12
- package/test/dist/fixtures.d.ts.map +1 -1
- package/test/dist/fixtures.js +17 -10
- 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/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/layerUtils.test.ts +2 -2
- package/test/query.test.ts +905 -40
- package/test/rawQuery.test.ts +340 -22
- package/test/repository-ext.test.ts +62 -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 +262 -0
- package/test/rpc-e2e-invalidation.test.ts +256 -0
- package/test/rpc-multi-middleware.test.ts +85 -10
- package/test/rpc-stream-fullstack.test.ts +304 -0
- package/test/sql-store.test.ts +1711 -0
- package/test/validateSample.test.ts +26 -14
- package/test/workflow-engine-cosmos.test.ts +354 -0
- package/test/workflow-engine-sqlite.test.ts +299 -0
- package/tsconfig.examples.json +1 -1
- package/tsconfig.json +2 -1
- package/tsconfig.json.bak +2 -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/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/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 +0 -479
- package/dist/adapters/SQL/Model.d.ts.map +0 -1
- package/dist/adapters/SQL/Model.js +0 -478
- package/dist/adapters/SQL.d.ts +0 -2
- 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 +0 -10
- 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 +0 -39
- 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 +0 -5
- 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 +0 -3
- package/dist/api/internal/health.d.ts.map +0 -1
- package/dist/api/internal/health.js +0 -5
- package/dist/api/layerUtils.d.ts +0 -24
- package/dist/api/layerUtils.d.ts.map +0 -1
- package/dist/api/layerUtils.js +0 -16
- package/dist/api/middlewares.d.ts +0 -10
- package/dist/api/middlewares.d.ts.map +0 -1
- package/dist/api/reportError.d.ts +0 -4
- package/dist/api/reportError.d.ts.map +0 -1
- package/dist/api/reportError.js +0 -27
- package/dist/api/routing/middleware/RouterMiddleware.d.ts +0 -15
- 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 +0 -4
- package/dist/api/routing/middleware.d.ts.map +0 -1
- package/dist/api/routing/schema/jwt.d.ts +0 -4
- 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 +0 -8
- 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 +0 -19
- 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 +0 -3
- 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/service.ts +0 -17
- package/src/RequestContext.ts +0 -63
- package/src/Store/ContextMapContainer.ts +0 -20
- package/src/Store/service.ts +0 -184
- package/src/Store.ts +0 -1
- package/src/adapters/ServiceBus.ts +0 -209
- package/src/adapters/index.ts +0 -0
- package/src/adapters/logger.ts +0 -3
- package/src/api/internal/auth.ts +0 -68
- package/src/api/routing/middleware.ts +0 -6
- package/src/api/routing.ts +0 -598
- package/src/api/setupRequest.ts +0 -84
- /package/src/{adapters/SQL.ts → SQL.ts} +0 -0
- /package/src/{api/codec.ts → codec.ts} +0 -0
- /package/src/{api/internal → internal}/health.ts +0 -0
- /package/src/{api/middlewares.ts → middlewares.ts} +0 -0
- /package/src/{api/routing → routing}/tsort.ts +0 -0
- /package/src/{api/util.ts → util.ts} +0 -0
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import type { NonEmptyReadonlyArray } from "effect-app/Array"
|
|
3
|
+
import * as Context from "effect-app/Context"
|
|
4
|
+
import * as Effect from "effect-app/Effect"
|
|
5
|
+
import type * as Layer from "effect-app/Layer"
|
|
6
|
+
import * as Option from "effect-app/Option"
|
|
7
|
+
import { InfraLogger } from "./logger.js"
|
|
4
8
|
|
|
5
9
|
// TODO: These LayerUtils are flaky, like in dependencies as a readonly array, it breaks when there are two entries
|
|
6
10
|
// we should look at Service.MakeDeps[E/RIn/ROut] etc.
|
|
@@ -27,38 +31,38 @@ export namespace LayerUtils {
|
|
|
27
31
|
}
|
|
28
32
|
|
|
29
33
|
export type ContextTagWithDefault<Id, A, LayerE, LayerR> =
|
|
30
|
-
&
|
|
34
|
+
& Context.Service<Id, A>
|
|
31
35
|
& {
|
|
32
36
|
Default: Layer.Layer<Id, LayerE, LayerR>
|
|
33
37
|
}
|
|
34
38
|
|
|
35
39
|
export namespace ContextTagWithDefault {
|
|
36
|
-
export type Base<A> =
|
|
40
|
+
export type Base<A> = { readonly Service: A } & { Default: Layer.Layer<any, any, any> }
|
|
37
41
|
}
|
|
38
42
|
|
|
39
|
-
export type GetContext<T> = T extends
|
|
43
|
+
export type GetContext<T> = T extends Context.Context<infer Y> ? Y : never
|
|
40
44
|
|
|
41
45
|
export const mergeContexts = Effect.fnUntraced(
|
|
42
46
|
function*<
|
|
43
47
|
T extends readonly {
|
|
44
48
|
maker: any
|
|
45
|
-
handle: Effect.Effect<
|
|
49
|
+
handle: Effect.Effect<Context.Context<any> | Option.Option<Context.Context<any>>>
|
|
46
50
|
}[]
|
|
47
51
|
>(
|
|
48
52
|
makers: T
|
|
49
53
|
) {
|
|
50
|
-
let context =
|
|
54
|
+
let context = Context.empty()
|
|
51
55
|
for (const mw of makers) {
|
|
52
56
|
const ctx = yield* mw.handle.pipe(Effect.provide(context))
|
|
53
|
-
const moreContext =
|
|
57
|
+
const moreContext = Context.isContext(ctx) ? Option.some(ctx) : ctx
|
|
54
58
|
yield* InfraLogger.logDebug(
|
|
55
59
|
"Built dynamic context for middleware" + (mw.maker.key ?? mw.maker),
|
|
56
60
|
Option.map(moreContext, (c) => (c as any).toJSON().services)
|
|
57
61
|
)
|
|
58
62
|
if (moreContext.value) {
|
|
59
|
-
context =
|
|
63
|
+
context = Context.merge(context, moreContext.value)
|
|
60
64
|
}
|
|
61
65
|
}
|
|
62
|
-
return context as
|
|
66
|
+
return context as Context.Context<Effect.Success<T[number]["handle"]>>
|
|
63
67
|
}
|
|
64
68
|
)
|
package/src/logger/jsonLogger.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as Array from "effect-app/Array"
|
|
2
|
+
import { spanAttributes } from "effect-app/RequestContext"
|
|
3
|
+
import * as Cause from "effect/Cause"
|
|
4
|
+
import * as Logger from "effect/Logger"
|
|
2
5
|
import { CurrentLogAnnotations, CurrentLogSpans } from "effect/References"
|
|
3
|
-
import { spanAttributes } from "../RequestContext.js"
|
|
4
6
|
import { getRequestContextFromFiber } from "./shared.js"
|
|
5
7
|
|
|
6
8
|
export const jsonLogger = Logger.make<unknown, void>(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { spanAttributes } from "effect-app/RequestContext"
|
|
2
|
+
import * as Logger from "effect/Logger"
|
|
3
3
|
import { getRequestContextFromFiber } from "./shared.js"
|
|
4
4
|
|
|
5
5
|
export const logfmtLogger = Logger.make<unknown, void>(
|
package/src/logger/shared.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as Option from "effect-app/Option"
|
|
2
|
+
import { LocaleRef, RequestContext } from "effect-app/RequestContext"
|
|
2
3
|
import { NonEmptyString255 } from "effect-app/Schema"
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
4
|
+
import { storeId } from "effect-app/Store"
|
|
5
|
+
import type * as Fiber from "effect/Fiber"
|
|
5
6
|
|
|
6
7
|
export function getRequestContextFromFiber(fiber: Fiber.Fiber<unknown, unknown>) {
|
|
7
8
|
const span = Option.fromNullishOr(fiber.currentSpan)
|
|
8
9
|
const locale = fiber.getRef(LocaleRef)
|
|
9
10
|
const namespace = fiber.getRef(storeId)
|
|
10
|
-
return
|
|
11
|
+
return RequestContext.make({
|
|
11
12
|
span: Option.map(span, (s) => ({ spanId: s.spanId, traceId: s.traceId, sampled: s.sampled })).pipe(
|
|
12
13
|
Option.getOrElse(() => ({ spanId: "bogus", sampled: true, traceId: "bogus" }))
|
|
13
14
|
),
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import * as
|
|
1
|
+
import * as Context from "effect-app/Context"
|
|
2
|
+
import * as Effect from "effect-app/Effect"
|
|
3
|
+
import * as Queue from "effect/Queue"
|
|
3
4
|
|
|
4
5
|
const make = Effect
|
|
5
6
|
.gen(function*() {
|
|
@@ -9,13 +10,13 @@ const make = Effect
|
|
|
9
10
|
getOrCreateQueue: Effect.fnUntraced(function*(k: string) {
|
|
10
11
|
const q = store.get(k)
|
|
11
12
|
if (q) return q
|
|
12
|
-
const newQ = yield*
|
|
13
|
+
const newQ = yield* Queue.unbounded<string>()
|
|
13
14
|
store.set(k, newQ)
|
|
14
15
|
return newQ
|
|
15
16
|
})
|
|
16
17
|
}
|
|
17
18
|
})
|
|
18
19
|
|
|
19
|
-
export class MemQueue extends
|
|
20
|
+
export class MemQueue extends Context.Opaque<MemQueue>()("effect-app/MemQueue", { make }) {
|
|
20
21
|
static readonly Live = this.toLayer(this.make)
|
|
21
22
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as Context from "effect-app/Context"
|
|
2
|
+
import * as Effect from "effect-app/Effect"
|
|
3
|
+
import * as Layer from "effect-app/Layer"
|
|
2
4
|
import { MongoClient as MongoClient_ } from "mongodb"
|
|
3
5
|
|
|
4
6
|
// TODO: we should probably share a single client...
|
|
@@ -15,7 +17,7 @@ const withClient = (url: string) =>
|
|
|
15
17
|
|
|
16
18
|
const makeMongoClient = (url: string, dbName?: string) => Effect.map(withClient(url), (x) => ({ db: x.db(dbName) }))
|
|
17
19
|
|
|
18
|
-
export class MongoClient extends
|
|
20
|
+
export class MongoClient extends Context.Service<MongoClient, {
|
|
19
21
|
readonly db: ReturnType<InstanceType<typeof MongoClient_>["db"]>
|
|
20
22
|
}>()("@services/MongoClient") {}
|
|
21
23
|
|
package/src/otel.ts
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenTelemetry semantic-convention helpers for span attributes.
|
|
3
|
+
*
|
|
4
|
+
* Aligns repository / queue / cache adapters with stable OTel semconv keys so
|
|
5
|
+
* downstream collectors and dashboards work without per-adapter mappings.
|
|
6
|
+
*
|
|
7
|
+
* - Database: https://opentelemetry.io/docs/specs/semconv/database/
|
|
8
|
+
* - Messaging: https://opentelemetry.io/docs/specs/semconv/messaging/
|
|
9
|
+
* - Cosmos DB: https://opentelemetry.io/docs/specs/semconv/database/cosmosdb/
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import * as Effect from "effect-app/Effect"
|
|
13
|
+
|
|
14
|
+
export type DbSystem =
|
|
15
|
+
| "postgresql"
|
|
16
|
+
| "sqlite"
|
|
17
|
+
| "cosmosdb"
|
|
18
|
+
| "mongodb"
|
|
19
|
+
| "redis"
|
|
20
|
+
| "other_sql"
|
|
21
|
+
| "memory"
|
|
22
|
+
| "disk"
|
|
23
|
+
|
|
24
|
+
export interface DbSpanOptions {
|
|
25
|
+
/** OTel `db.operation.name` (e.g. `find`, `all`, `filter`, `set`). */
|
|
26
|
+
readonly operation: string
|
|
27
|
+
readonly system: DbSystem
|
|
28
|
+
/** Logical collection / table / container name. */
|
|
29
|
+
readonly collection: string
|
|
30
|
+
/** Tenant / namespace / database name. */
|
|
31
|
+
readonly namespace?: string | undefined
|
|
32
|
+
/** Application-level entity / model name (custom: `app.entity`). */
|
|
33
|
+
readonly entity?: string | undefined
|
|
34
|
+
/** Sanitized / parameterized query text. Never include bound values. */
|
|
35
|
+
readonly query?: string | undefined
|
|
36
|
+
/** Optional fragments merged into final attributes (e.g. id, partition). */
|
|
37
|
+
readonly extra?: Record<string, unknown> | undefined
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const dbAttributes = (a: DbSpanOptions): Record<string, unknown> => ({
|
|
41
|
+
"db.system.name": a.system,
|
|
42
|
+
"db.operation.name": a.operation,
|
|
43
|
+
"db.collection.name": a.collection,
|
|
44
|
+
...(a.namespace !== undefined && { "db.namespace": a.namespace }),
|
|
45
|
+
...(a.query !== undefined && { "db.query.text": a.query }),
|
|
46
|
+
...(a.entity !== undefined && { "app.entity": a.entity }),
|
|
47
|
+
...a.extra
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Wrap an effect with an OTel-semconv database span.
|
|
52
|
+
*
|
|
53
|
+
* Span name follows the low-cardinality convention: `<operation> <collection>`.
|
|
54
|
+
*/
|
|
55
|
+
export const withDbSpan = (a: DbSpanOptions) =>
|
|
56
|
+
Effect.withSpan(
|
|
57
|
+
`${a.operation} ${a.collection}`,
|
|
58
|
+
{ attributes: dbAttributes(a), kind: "client" as const },
|
|
59
|
+
{ captureStackTrace: false }
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Annotate the current span with OTel-semconv database attributes.
|
|
64
|
+
*
|
|
65
|
+
* Use when the caller already owns the span (e.g. a repository) and the
|
|
66
|
+
* adapter should only contribute db.* semconv attrs without opening a child.
|
|
67
|
+
* Annotates before running so attrs persist even on failure.
|
|
68
|
+
* No-op if there is no current span.
|
|
69
|
+
*/
|
|
70
|
+
export const annotateDb = (a: DbSpanOptions) => <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>
|
|
71
|
+
Effect.flatMap(Effect.annotateCurrentSpan(dbAttributes(a)), () => self)
|
|
72
|
+
|
|
73
|
+
/** Annotate the current span with response metrics from a DB call. */
|
|
74
|
+
export const annotateDbResponse = (m: {
|
|
75
|
+
readonly returnedRows?: number | undefined
|
|
76
|
+
readonly responseBytes?: number | undefined
|
|
77
|
+
}) =>
|
|
78
|
+
Effect.annotateCurrentSpan({
|
|
79
|
+
...(m.returnedRows !== undefined && { "db.response.returned_rows": m.returnedRows }),
|
|
80
|
+
...(m.responseBytes !== undefined && { "db.response.body.size": m.responseBytes })
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
/** Cosmos-specific response annotations. */
|
|
84
|
+
export const annotateCosmosResponse = (m: {
|
|
85
|
+
readonly requestCharge?: number | undefined
|
|
86
|
+
readonly returnedRows?: number | undefined
|
|
87
|
+
readonly responseBytes?: number | undefined
|
|
88
|
+
readonly statusCode?: number | undefined
|
|
89
|
+
}) =>
|
|
90
|
+
Effect.annotateCurrentSpan({
|
|
91
|
+
...(m.requestCharge !== undefined && { "azure.cosmosdb.operation.request_charge": m.requestCharge }),
|
|
92
|
+
...(m.statusCode !== undefined && { "db.response.status_code": String(m.statusCode) }),
|
|
93
|
+
...(m.returnedRows !== undefined && { "db.response.returned_rows": m.returnedRows }),
|
|
94
|
+
...(m.responseBytes !== undefined && { "db.response.body.size": m.responseBytes })
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
export type MessagingSystem =
|
|
98
|
+
| "servicebus"
|
|
99
|
+
| "rabbitmq"
|
|
100
|
+
| "kafka"
|
|
101
|
+
| "memory"
|
|
102
|
+
| "sql"
|
|
103
|
+
|
|
104
|
+
export type MessagingOperation =
|
|
105
|
+
| "publish"
|
|
106
|
+
| "create"
|
|
107
|
+
| "receive"
|
|
108
|
+
| "process"
|
|
109
|
+
| "settle"
|
|
110
|
+
|
|
111
|
+
export interface MessagingSpanOptions {
|
|
112
|
+
readonly operation: MessagingOperation
|
|
113
|
+
readonly system: MessagingSystem
|
|
114
|
+
/** Queue / topic name. */
|
|
115
|
+
readonly destination: string
|
|
116
|
+
readonly messageId?: string | undefined
|
|
117
|
+
readonly conversationId?: string | undefined
|
|
118
|
+
readonly bodySize?: number | undefined
|
|
119
|
+
readonly extra?: Record<string, unknown> | undefined
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const messagingAttributes = (a: MessagingSpanOptions): Record<string, unknown> => ({
|
|
123
|
+
"messaging.system": a.system,
|
|
124
|
+
"messaging.operation.name": a.operation,
|
|
125
|
+
"messaging.destination.name": a.destination,
|
|
126
|
+
...(a.messageId !== undefined && { "messaging.message.id": a.messageId }),
|
|
127
|
+
...(a.conversationId !== undefined && { "messaging.message.conversation_id": a.conversationId }),
|
|
128
|
+
...(a.bodySize !== undefined && { "messaging.message.body.size": a.bodySize }),
|
|
129
|
+
...a.extra
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
/** Wrap an effect with an OTel-semconv messaging span. */
|
|
133
|
+
export const withMessagingSpan = (
|
|
134
|
+
a: MessagingSpanOptions,
|
|
135
|
+
kind: "producer" | "consumer"
|
|
136
|
+
) =>
|
|
137
|
+
Effect.withSpan(
|
|
138
|
+
`${a.operation} ${a.destination}`,
|
|
139
|
+
{ kind, attributes: messagingAttributes(a) },
|
|
140
|
+
{ captureStackTrace: false }
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
/** Build messaging span options without wrapping (for Effect.fn / setupRequestContextWithCustomSpan). */
|
|
144
|
+
export const messagingSpanArgs = (
|
|
145
|
+
a: MessagingSpanOptions,
|
|
146
|
+
kind: "producer" | "consumer"
|
|
147
|
+
) =>
|
|
148
|
+
({
|
|
149
|
+
name: `${a.operation} ${a.destination}`,
|
|
150
|
+
kind,
|
|
151
|
+
attributes: messagingAttributes(a)
|
|
152
|
+
}) as const
|
package/src/rateLimit.ts
CHANGED
|
@@ -20,8 +20,13 @@
|
|
|
20
20
|
// }
|
|
21
21
|
// }
|
|
22
22
|
|
|
23
|
-
import
|
|
23
|
+
import * as Array from "effect-app/Array"
|
|
24
|
+
import type { NonEmptyArray } from "effect-app/Array"
|
|
25
|
+
import * as Effect from "effect-app/Effect"
|
|
26
|
+
import { dual } from "effect-app/Function"
|
|
27
|
+
import type * as Duration from "effect/Duration"
|
|
24
28
|
import type { Semaphore } from "effect/Semaphore"
|
|
29
|
+
import type { Concurrency } from "effect/Types"
|
|
25
30
|
|
|
26
31
|
/**
|
|
27
32
|
* Executes the specified effect, acquiring the specified number of permits
|
|
@@ -45,36 +50,42 @@ export function SEM_withPermitsDuration(permits: number, duration: Duration.Dura
|
|
|
45
50
|
}
|
|
46
51
|
}
|
|
47
52
|
|
|
48
|
-
export
|
|
49
|
-
|
|
50
|
-
forEachItem: (item: T, iWithinBatch: number, batchI: number) => Effect.Effect<A, E, R>,
|
|
51
|
-
forEachBatch: (a: NonEmptyArray<A>, i: number) => Effect.Effect<A2, E2, R2>
|
|
52
|
-
) {
|
|
53
|
-
return (items: Iterable<T>) =>
|
|
54
|
-
Effect.forEach(
|
|
55
|
-
Array.chunksOf(items, n),
|
|
56
|
-
(_, i) =>
|
|
57
|
-
Effect
|
|
58
|
-
.forEach(_, (_, j) => forEachItem(_, j, i), { concurrency: "inherit" })
|
|
59
|
-
.pipe(Effect.flatMap((_) => forEachBatch(_, i))),
|
|
60
|
-
{ concurrency: "inherit" }
|
|
61
|
-
)
|
|
53
|
+
export interface BatchOptions {
|
|
54
|
+
readonly concurrency?: Concurrency | undefined
|
|
62
55
|
}
|
|
63
56
|
|
|
64
|
-
export
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
)
|
|
69
|
-
|
|
57
|
+
export const batch: {
|
|
58
|
+
<T, A, E, R, A2, E2, R2>(
|
|
59
|
+
n: number,
|
|
60
|
+
forEachItem: (item: T, iWithinBatch: number, batchI: number) => Effect.Effect<A, E, R>,
|
|
61
|
+
forEachBatch: (a: NonEmptyArray<A>, i: number) => Effect.Effect<A2, E2, R2>,
|
|
62
|
+
options?: BatchOptions
|
|
63
|
+
): (items: Iterable<T>) => Effect.Effect<Array<A2>, E | E2, R | R2>
|
|
64
|
+
<T, A, E, R, A2, E2, R2>(
|
|
65
|
+
items: Iterable<T>,
|
|
66
|
+
n: number,
|
|
67
|
+
forEachItem: (item: T, iWithinBatch: number, batchI: number) => Effect.Effect<A, E, R>,
|
|
68
|
+
forEachBatch: (a: NonEmptyArray<A>, i: number) => Effect.Effect<A2, E2, R2>,
|
|
69
|
+
options?: BatchOptions
|
|
70
|
+
): Effect.Effect<Array<A2>, E | E2, R | R2>
|
|
71
|
+
} = dual(
|
|
72
|
+
(args) => typeof args[0] !== "number",
|
|
73
|
+
<T, A, E, R, A2, E2, R2>(
|
|
74
|
+
items: Iterable<T>,
|
|
75
|
+
n: number,
|
|
76
|
+
forEachItem: (item: T, iWithinBatch: number, batchI: number) => Effect.Effect<A, E, R>,
|
|
77
|
+
forEachBatch: (a: NonEmptyArray<A>, i: number) => Effect.Effect<A2, E2, R2>,
|
|
78
|
+
options?: BatchOptions
|
|
79
|
+
) =>
|
|
70
80
|
Effect.forEach(
|
|
71
81
|
Array.chunksOf(items, n),
|
|
72
82
|
(_, i) =>
|
|
73
83
|
Effect
|
|
74
84
|
.forEach(_, (_, j) => forEachItem(_, j, i), { concurrency: "inherit" })
|
|
75
|
-
.pipe(Effect.flatMap((_) => forEachBatch(_, i)))
|
|
85
|
+
.pipe(Effect.flatMap((_) => forEachBatch(_, i))),
|
|
86
|
+
{ concurrency: options?.concurrency }
|
|
76
87
|
)
|
|
77
|
-
|
|
88
|
+
)
|
|
78
89
|
|
|
79
90
|
// export function rateLimit(
|
|
80
91
|
// n: number,
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as Context from "effect-app/Context"
|
|
2
|
+
import * as Effect from "effect-app/Effect"
|
|
3
|
+
import * as Layer from "effect-app/Layer"
|
|
4
|
+
import * as Option from "effect-app/Option"
|
|
5
|
+
import * as Data from "effect/Data"
|
|
2
6
|
import type { RedisClient as Client } from "redis"
|
|
3
7
|
import Redlock from "redlock"
|
|
4
8
|
|
|
5
9
|
export class ConnectionException extends Data.TaggedError("ConnectionException")<{ cause: Error; message: string }> {
|
|
6
10
|
constructor(cause: Error) {
|
|
7
|
-
super({ message: "A connection error
|
|
11
|
+
super({ message: "A connection error occurred", cause })
|
|
8
12
|
}
|
|
9
13
|
}
|
|
10
14
|
|
|
@@ -90,7 +94,7 @@ export const makeRedisClient = (makeClient: () => Client) =>
|
|
|
90
94
|
.pipe(Effect.uninterruptible, Effect.orDie)
|
|
91
95
|
)
|
|
92
96
|
|
|
93
|
-
export class RedisClient extends
|
|
97
|
+
export class RedisClient extends Context.Service<RedisClient, {
|
|
94
98
|
readonly client: Client
|
|
95
99
|
readonly lock: Redlock
|
|
96
100
|
readonly get: (key: string) => Effect.Effect<Option.Option<string>, ConnectionException>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import * as Effect from "effect-app/Effect"
|
|
2
|
+
import * as Cause from "effect/Cause"
|
|
3
|
+
import { logError, reportError } from "./errorReporter.js"
|
|
3
4
|
|
|
4
5
|
// const onExitReportError = (name: string, unknownOnly?: boolean) => {
|
|
5
6
|
// const report = reportError(name)
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
3
3
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
4
|
-
import
|
|
4
|
+
import type * as Context from "effect-app/Context"
|
|
5
|
+
import type * as Layer from "effect-app/Layer"
|
|
5
6
|
import { type GetContextConfig, type RpcContextMap } from "effect-app/rpc/RpcContextMap"
|
|
6
7
|
import { type RpcMiddlewareV4 } from "effect-app/rpc/RpcMiddleware"
|
|
7
8
|
// module:
|
|
8
9
|
//
|
|
9
10
|
|
|
10
|
-
// v4: middleware tags are
|
|
11
|
+
// v4: middleware tags are Context.Service (not Effect) — they carry the RpcMiddlewareV4 as their service Shape
|
|
11
12
|
export type RouterMiddleware<
|
|
12
13
|
Self,
|
|
13
14
|
RequestContextMap extends Record<string, RpcContextMap.Any>, // what services will the middlware provide dynamically to the next, or raise errors.
|
|
@@ -18,9 +19,9 @@ export type RouterMiddleware<
|
|
|
18
19
|
_ContextProviderR, // what the context provider requires
|
|
19
20
|
RequestContextId
|
|
20
21
|
> =
|
|
21
|
-
&
|
|
22
|
+
& Context.Service<Self, RpcMiddlewareV4<ContextProviderA, ContextProviderE, never>>
|
|
22
23
|
& {
|
|
23
24
|
readonly Default: Layer.Layer<Self, MakeMiddlewareE, MakeMiddlewareR>
|
|
24
|
-
readonly requestContext:
|
|
25
|
+
readonly requestContext: Context.Service<RequestContextId, GetContextConfig<RequestContextMap>>
|
|
25
26
|
readonly requestContextMap: RequestContextMap
|
|
26
27
|
}
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
import { Cause, Config, Effect, Layer, Schema } from "effect"
|
|
3
2
|
import { ConfigureInterruptibilityMiddleware, DevMode, DevModeMiddleware, LoggerMiddleware, RequestCacheMiddleware } from "effect-app/middleware"
|
|
3
|
+
import { RpcContextMap, type RpcMiddleware } from "effect-app/rpc"
|
|
4
4
|
import { pretty } from "effect-app/utils"
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
5
|
+
import * as Array from "effect/Array"
|
|
6
|
+
import * as Cause from "effect/Cause"
|
|
7
|
+
import * as Config from "effect/Config"
|
|
8
|
+
import * as Context from "effect/Context"
|
|
9
|
+
import * as Effect from "effect/Effect"
|
|
10
|
+
import * as Layer from "effect/Layer"
|
|
11
|
+
import * as Schema from "effect/Schema"
|
|
12
|
+
import { type Rpc } from "effect/unstable/rpc"
|
|
13
|
+
import { logError, reportError } from "../../errorReporter.js"
|
|
14
|
+
import { InfraLogger } from "../../logger.js"
|
|
15
|
+
import { WithNsTransaction } from "../../Store/SQL.js"
|
|
8
16
|
|
|
9
17
|
const logRequestError = logError("Request")
|
|
10
18
|
const reportRequestError = reportError("Request")
|
|
@@ -26,22 +34,20 @@ export const RequestCacheMiddlewareLive = Layer.succeed(
|
|
|
26
34
|
const isOptimisticConcurrencyException = (input: unknown) =>
|
|
27
35
|
typeof input === "object" && input !== null && "_tag" in input && input._tag === "OptimisticConcurrencyException"
|
|
28
36
|
|
|
37
|
+
export const RequestType = Context.Reference<"command" | "query">(
|
|
38
|
+
"@effect-app/infra/routing/RequestType",
|
|
39
|
+
{ defaultValue: () => "query" }
|
|
40
|
+
)
|
|
41
|
+
|
|
29
42
|
export const ConfigureInterruptibilityMiddlewareLive = Layer.effect(
|
|
30
43
|
ConfigureInterruptibilityMiddleware,
|
|
31
44
|
Effect.gen(function*() {
|
|
32
|
-
const cache = new Map()
|
|
33
|
-
const getCached = (key: string, schema: Schema.Top) => {
|
|
34
|
-
const existing = cache.get(key)
|
|
35
|
-
if (existing) return existing
|
|
36
|
-
const n = determineMethod(key, schema)
|
|
37
|
-
cache.set(key, n)
|
|
38
|
-
return n
|
|
39
|
-
}
|
|
40
45
|
return (effect, { rpc }) => {
|
|
41
|
-
const
|
|
46
|
+
const requestType = Context.get(rpc.annotations, RequestType)
|
|
47
|
+
const isCommand = requestType === "command"
|
|
42
48
|
|
|
43
|
-
effect = isCommand
|
|
44
|
-
? Effect.retry(
|
|
49
|
+
effect = isCommand
|
|
50
|
+
? Effect.retry(effect, { times: 1, while: isOptimisticConcurrencyException })
|
|
45
51
|
: Effect.interruptible(effect)
|
|
46
52
|
|
|
47
53
|
return effect
|
|
@@ -57,8 +63,8 @@ export const LoggerMiddlewareLive = Layer
|
|
|
57
63
|
return (effect, { headers, payload, rpc }) =>
|
|
58
64
|
Effect
|
|
59
65
|
.annotateCurrentSpan({
|
|
60
|
-
"
|
|
61
|
-
"
|
|
66
|
+
"rpc.method": rpc._tag,
|
|
67
|
+
"rpc.request.payload": typeof payload === "object" && payload !== null
|
|
62
68
|
? Object.entries(payload).reduce((prev, [key, value]: [string, unknown]) => {
|
|
63
69
|
prev[key] = key === "password"
|
|
64
70
|
? "<redacted>"
|
|
@@ -126,3 +132,42 @@ export const DefaultGenericMiddlewaresLive = Layer.mergeAll(
|
|
|
126
132
|
LoggerMiddlewareLive,
|
|
127
133
|
DevModeMiddlewareLive
|
|
128
134
|
)
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Config entry for `RequestContextMap` that controls per-RPC transaction wrapping.
|
|
138
|
+
* Defaults to `false` (no transaction). Set `requiresTransaction: true` on a route to enable.
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```ts
|
|
142
|
+
* class RequestContextMap extends RpcContextMap.makeMap({
|
|
143
|
+
* requiresTransaction: requiresTransactionConfig,
|
|
144
|
+
* // ...
|
|
145
|
+
* }) {}
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
export const requiresTransactionConfig = RpcContextMap.makeCustom()(Schema.Never, false)
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Creates the middleware Effect for SQL transaction wrapping.
|
|
152
|
+
* Requires `WithNsTransaction` service.
|
|
153
|
+
* Reads `requiresTransaction` from the RPC config; defaults to `false`.
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* ```ts
|
|
157
|
+
* const SqlTransactionMiddlewareLive = Layer.effect(
|
|
158
|
+
* SqlTransactionMiddleware,
|
|
159
|
+
* makeSqlTransactionMiddleware(RequestContextMap)
|
|
160
|
+
* )
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
export const makeSqlTransactionMiddleware = Effect.fnUntraced(function*(
|
|
164
|
+
rcm: { getConfig: (rpc: Rpc.AnyWithProps) => { readonly requiresTransaction?: boolean } }
|
|
165
|
+
) {
|
|
166
|
+
const withTx = yield* WithNsTransaction
|
|
167
|
+
const mw: RpcMiddleware.RpcMiddlewareV4<never, never, never> = (effect, { rpc }) => {
|
|
168
|
+
const { requiresTransaction } = rcm.getConfig(rpc)
|
|
169
|
+
if (requiresTransaction !== true) return effect
|
|
170
|
+
return withTx(effect)
|
|
171
|
+
}
|
|
172
|
+
return mw
|
|
173
|
+
})
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3
|
-
import { Effect, Option } from "effect"
|
|
4
3
|
import * as S from "effect-app/Schema"
|
|
4
|
+
import * as Effect from "effect/Effect"
|
|
5
|
+
import * as Option from "effect/Option"
|
|
5
6
|
import { jwtDecode, type JwtDecodeOptions } from "jwt-decode"
|
|
6
7
|
|
|
7
8
|
export const parseJwt = <Sch extends S.Top>(
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as S from "effect-app/Schema"
|
|
2
2
|
import type { AST } from "effect-app/Schema"
|
|
3
|
+
import * as SchemaAST from "effect/SchemaAST"
|
|
3
4
|
|
|
4
5
|
const get = ["Get", "Index", "List", "All", "Find", "Search"]
|
|
5
6
|
const del = ["Delete", "Remove", "Destroy"]
|