@effect-app/infra 4.0.0-beta.22 → 4.0.0-beta.221
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 +1648 -0
- package/_check.sh +1 -1
- package/dist/CUPS.d.ts +12 -7
- package/dist/CUPS.d.ts.map +1 -1
- package/dist/CUPS.js +16 -12
- package/dist/Emailer/Sendgrid.d.ts +15 -15
- package/dist/Emailer/Sendgrid.d.ts.map +1 -1
- package/dist/Emailer/Sendgrid.js +20 -16
- package/dist/Emailer/fake.d.ts +1 -1
- package/dist/Emailer/fake.js +2 -2
- package/dist/Emailer/service.d.ts +13 -4
- package/dist/Emailer/service.d.ts.map +1 -1
- package/dist/Emailer/service.js +4 -3
- package/dist/Emailer.d.ts +1 -1
- package/dist/MainFiberSet.d.ts +12 -9
- package/dist/MainFiberSet.d.ts.map +1 -1
- package/dist/MainFiberSet.js +7 -3
- package/dist/Model/Repository/Registry.d.ts +21 -0
- package/dist/Model/Repository/Registry.d.ts.map +1 -0
- package/dist/Model/Repository/Registry.js +18 -0
- package/dist/Model/Repository/ext.d.ts +35 -16
- package/dist/Model/Repository/ext.d.ts.map +1 -1
- package/dist/Model/Repository/ext.js +60 -3
- package/dist/Model/Repository/internal/internal.d.ts +9 -6
- package/dist/Model/Repository/internal/internal.d.ts.map +1 -1
- package/dist/Model/Repository/internal/internal.js +115 -51
- package/dist/Model/Repository/legacy.d.ts +4 -2
- package/dist/Model/Repository/legacy.d.ts.map +1 -1
- package/dist/Model/Repository/makeRepo.d.ts +10 -6
- package/dist/Model/Repository/makeRepo.d.ts.map +1 -1
- package/dist/Model/Repository/makeRepo.js +5 -2
- package/dist/Model/Repository/service.d.ts +32 -24
- package/dist/Model/Repository/service.d.ts.map +1 -1
- package/dist/Model/Repository/validation.d.ts +47 -18
- package/dist/Model/Repository/validation.d.ts.map +1 -1
- package/dist/Model/Repository/validation.js +6 -6
- package/dist/Model/Repository.d.ts +2 -1
- package/dist/Model/Repository.d.ts.map +1 -1
- package/dist/Model/Repository.js +2 -1
- package/dist/Model/dsl.d.ts +6 -5
- package/dist/Model/dsl.d.ts.map +1 -1
- package/dist/Model/dsl.js +2 -3
- package/dist/Model/filter/filterApi.d.ts +5 -5
- package/dist/Model/filter/filterApi.d.ts.map +1 -1
- package/dist/Model/filter/types/errors.d.ts +1 -1
- package/dist/Model/filter/types/fields.d.ts +1 -1
- package/dist/Model/filter/types/path/common.d.ts +1 -1
- package/dist/Model/filter/types/path/eager.d.ts +1 -1
- package/dist/Model/filter/types/path/eager.d.ts.map +1 -1
- package/dist/Model/filter/types/path/eager.js +1 -1
- package/dist/Model/filter/types/path/index.d.ts +1 -1
- package/dist/Model/filter/types/utils.d.ts +1 -1
- package/dist/Model/filter/types/validator.d.ts +1 -1
- package/dist/Model/filter/types.d.ts +1 -1
- package/dist/Model/query/dsl.d.ts +142 -17
- package/dist/Model/query/dsl.d.ts.map +1 -1
- package/dist/Model/query/dsl.js +190 -5
- package/dist/Model/query/new-kid-interpreter.d.ts +77 -8
- package/dist/Model/query/new-kid-interpreter.d.ts.map +1 -1
- package/dist/Model/query/new-kid-interpreter.js +127 -6
- package/dist/Model/query.d.ts +1 -1
- package/dist/Model.d.ts +2 -1
- package/dist/Model.d.ts.map +1 -1
- package/dist/Model.js +2 -1
- package/dist/QueueMaker/SQLQueue.d.ts +7 -8
- package/dist/QueueMaker/SQLQueue.d.ts.map +1 -1
- package/dist/QueueMaker/SQLQueue.js +135 -117
- 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 +9 -5
- package/dist/QueueMaker/memQueue.d.ts.map +1 -1
- package/dist/QueueMaker/memQueue.js +81 -65
- package/dist/QueueMaker/sbqueue.d.ts +8 -4
- package/dist/QueueMaker/sbqueue.d.ts.map +1 -1
- package/dist/QueueMaker/sbqueue.js +57 -55
- package/dist/QueueMaker/service.d.ts +4 -2
- package/dist/QueueMaker/service.d.ts.map +1 -1
- package/dist/QueueMaker/service.js +1 -1
- package/dist/RequestContext.d.ts +75 -35
- package/dist/RequestContext.d.ts.map +1 -1
- package/dist/RequestContext.js +14 -14
- package/dist/RequestFiberSet.d.ts +10 -7
- package/dist/RequestFiberSet.d.ts.map +1 -1
- package/dist/RequestFiberSet.js +8 -3
- package/dist/Store/ContextMapContainer.d.ts +22 -3
- package/dist/Store/ContextMapContainer.d.ts.map +1 -1
- package/dist/Store/ContextMapContainer.js +17 -3
- package/dist/Store/Cosmos/query.d.ts +7 -2
- package/dist/Store/Cosmos/query.d.ts.map +1 -1
- package/dist/Store/Cosmos/query.js +115 -35
- package/dist/Store/Cosmos.d.ts +2 -2
- package/dist/Store/Cosmos.d.ts.map +1 -1
- package/dist/Store/Cosmos.js +343 -244
- package/dist/Store/Disk.d.ts +3 -3
- package/dist/Store/Disk.d.ts.map +1 -1
- package/dist/Store/Disk.js +76 -36
- package/dist/Store/Memory.d.ts +7 -4
- package/dist/Store/Memory.d.ts.map +1 -1
- package/dist/Store/Memory.js +251 -58
- 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 +233 -0
- package/dist/Store/SQL/query.d.ts +43 -0
- package/dist/Store/SQL/query.d.ts.map +1 -0
- package/dist/Store/SQL/query.js +478 -0
- package/dist/Store/SQL.d.ts +21 -0
- package/dist/Store/SQL.d.ts.map +1 -0
- package/dist/Store/SQL.js +450 -0
- package/dist/Store/codeFilter.d.ts +2 -2
- package/dist/Store/codeFilter.d.ts.map +1 -1
- package/dist/Store/codeFilter.js +6 -3
- package/dist/Store/index.d.ts +6 -3
- package/dist/Store/index.d.ts.map +1 -1
- package/dist/Store/index.js +18 -4
- package/dist/Store/service.d.ts +26 -8
- package/dist/Store/service.d.ts.map +1 -1
- package/dist/Store/service.js +25 -6
- package/dist/Store/utils.d.ts +3 -2
- package/dist/Store/utils.d.ts.map +1 -1
- package/dist/Store/utils.js +5 -5
- package/dist/Store.d.ts +1 -1
- package/dist/adapters/SQL/Model.d.ts +32 -43
- package/dist/adapters/SQL/Model.d.ts.map +1 -1
- package/dist/adapters/SQL/Model.js +30 -39
- package/dist/adapters/SQL.d.ts +1 -1
- package/dist/adapters/ServiceBus.d.ts +14 -11
- package/dist/adapters/ServiceBus.d.ts.map +1 -1
- package/dist/adapters/ServiceBus.js +30 -21
- package/dist/adapters/cosmos-client.d.ts +5 -3
- package/dist/adapters/cosmos-client.d.ts.map +1 -1
- package/dist/adapters/cosmos-client.js +5 -3
- package/dist/adapters/index.d.ts +8 -2
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +8 -2
- package/dist/adapters/logger.d.ts +2 -2
- package/dist/adapters/logger.d.ts.map +1 -1
- package/dist/adapters/memQueue.d.ts +5 -3
- package/dist/adapters/memQueue.d.ts.map +1 -1
- package/dist/adapters/memQueue.js +6 -5
- package/dist/adapters/mongo-client.d.ts +4 -3
- package/dist/adapters/mongo-client.d.ts.map +1 -1
- package/dist/adapters/mongo-client.js +5 -3
- package/dist/adapters/redis-client.d.ts +6 -3
- package/dist/adapters/redis-client.d.ts.map +1 -1
- package/dist/adapters/redis-client.js +7 -3
- package/dist/api/ContextProvider.d.ts +12 -8
- package/dist/api/ContextProvider.d.ts.map +1 -1
- package/dist/api/ContextProvider.js +9 -7
- package/dist/api/codec.d.ts +1 -1
- package/dist/api/internal/RequestContextMiddleware.d.ts +3 -3
- package/dist/api/internal/RequestContextMiddleware.d.ts.map +1 -1
- package/dist/api/internal/RequestContextMiddleware.js +10 -6
- package/dist/api/internal/auth.d.ts +45 -7
- package/dist/api/internal/auth.d.ts.map +1 -1
- package/dist/api/internal/auth.js +162 -29
- package/dist/api/internal/events.d.ts +6 -4
- package/dist/api/internal/events.d.ts.map +1 -1
- package/dist/api/internal/events.js +16 -9
- package/dist/api/internal/health.d.ts +1 -1
- package/dist/api/layerUtils.d.ts +10 -6
- package/dist/api/layerUtils.d.ts.map +1 -1
- package/dist/api/layerUtils.js +7 -6
- package/dist/api/middlewares.d.ts +1 -1
- package/dist/api/reportError.d.ts +2 -2
- package/dist/api/reportError.d.ts.map +1 -1
- package/dist/api/reportError.js +3 -2
- package/dist/api/routing/middleware/RouterMiddleware.d.ts +5 -4
- package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/middleware.d.ts +42 -3
- package/dist/api/routing/middleware/middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/middleware.js +53 -17
- package/dist/api/routing/middleware.d.ts +1 -2
- package/dist/api/routing/middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware.js +1 -2
- package/dist/api/routing/schema/jwt.d.ts +1 -1
- package/dist/api/routing/schema/jwt.d.ts.map +1 -1
- package/dist/api/routing/schema/jwt.js +3 -2
- package/dist/api/routing/tsort.d.ts +1 -1
- package/dist/api/routing/tsort.d.ts.map +1 -1
- package/dist/api/routing/utils.d.ts +4 -4
- package/dist/api/routing/utils.d.ts.map +1 -1
- package/dist/api/routing/utils.js +3 -2
- package/dist/api/routing.d.ts +84 -37
- package/dist/api/routing.d.ts.map +1 -1
- package/dist/api/routing.js +115 -45
- package/dist/api/setupRequest.d.ts +10 -6
- package/dist/api/setupRequest.d.ts.map +1 -1
- package/dist/api/setupRequest.js +15 -7
- package/dist/api/util.d.ts +1 -1
- package/dist/arbs.d.ts +2 -2
- package/dist/arbs.d.ts.map +1 -1
- package/dist/arbs.js +5 -3
- package/dist/errorReporter.d.ts +7 -5
- package/dist/errorReporter.d.ts.map +1 -1
- package/dist/errorReporter.js +22 -26
- 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 +1 -1
- package/dist/logger/jsonLogger.d.ts +2 -2
- package/dist/logger/jsonLogger.d.ts.map +1 -1
- package/dist/logger/jsonLogger.js +4 -2
- package/dist/logger/logFmtLogger.d.ts +2 -2
- package/dist/logger/logFmtLogger.d.ts.map +1 -1
- package/dist/logger/logFmtLogger.js +2 -2
- package/dist/logger/shared.d.ts +2 -2
- package/dist/logger/shared.d.ts.map +1 -1
- package/dist/logger/shared.js +3 -3
- package/dist/logger.d.ts +1 -1
- package/dist/logger.d.ts.map +1 -1
- 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/test.d.ts +3 -3
- package/dist/test.d.ts.map +1 -1
- package/dist/test.js +2 -2
- package/dist/vitest.d.ts +1 -1
- package/examples/query.ts +46 -38
- package/package.json +46 -37
- package/src/CUPS.ts +15 -11
- package/src/Emailer/Sendgrid.ts +21 -15
- package/src/Emailer/fake.ts +1 -1
- package/src/Emailer/service.ts +13 -3
- package/src/MainFiberSet.ts +9 -6
- package/src/Model/Repository/Registry.ts +34 -0
- package/src/Model/Repository/ext.ts +103 -11
- package/src/Model/Repository/internal/internal.ts +231 -149
- package/src/Model/Repository/legacy.ts +3 -1
- package/src/Model/Repository/makeRepo.ts +15 -10
- package/src/Model/Repository/service.ts +35 -23
- package/src/Model/Repository/validation.ts +5 -5
- package/src/Model/Repository.ts +1 -0
- package/src/Model/dsl.ts +5 -4
- package/src/Model/filter/types/path/eager.ts +1 -2
- package/src/Model/query/dsl.ts +353 -19
- package/src/Model/query/new-kid-interpreter.ts +211 -6
- package/src/Model.ts +1 -0
- package/src/QueueMaker/SQLQueue.ts +150 -153
- package/src/QueueMaker/errors.ts +3 -1
- package/src/QueueMaker/memQueue.ts +111 -105
- package/src/QueueMaker/sbqueue.ts +76 -88
- package/src/QueueMaker/service.ts +3 -1
- package/src/RequestContext.ts +15 -16
- package/src/RequestFiberSet.ts +8 -2
- package/src/Store/ContextMapContainer.ts +45 -2
- package/src/Store/Cosmos/query.ts +143 -44
- package/src/Store/Cosmos.ts +491 -350
- package/src/Store/Disk.ts +106 -66
- package/src/Store/Memory.ts +285 -87
- package/src/Store/SQL/Pg.ts +364 -0
- package/src/Store/SQL/query.ts +540 -0
- package/src/Store/SQL.ts +736 -0
- package/src/Store/codeFilter.ts +5 -2
- package/src/Store/index.ts +20 -3
- package/src/Store/service.ts +45 -10
- package/src/Store/utils.ts +25 -23
- package/src/adapters/SQL/Model.ts +42 -41
- package/src/adapters/ServiceBus.ts +131 -121
- package/src/adapters/cosmos-client.ts +4 -2
- package/src/adapters/index.ts +7 -0
- package/src/adapters/memQueue.ts +5 -4
- package/src/adapters/mongo-client.ts +4 -2
- package/src/adapters/redis-client.ts +6 -2
- package/src/api/ContextProvider.ts +17 -13
- package/src/api/internal/RequestContextMiddleware.ts +16 -5
- package/src/api/internal/auth.ts +248 -44
- package/src/api/internal/events.ts +19 -10
- package/src/api/layerUtils.ts +12 -8
- package/src/api/reportError.ts +2 -1
- package/src/api/routing/middleware/RouterMiddleware.ts +5 -4
- package/src/api/routing/middleware/middleware.ts +60 -15
- package/src/api/routing/middleware.ts +0 -2
- package/src/api/routing/schema/jwt.ts +2 -1
- package/src/api/routing/utils.ts +2 -1
- package/src/api/routing.ts +304 -131
- package/src/api/setupRequest.ts +31 -8
- package/src/arbs.ts +5 -3
- package/src/errorReporter.ts +65 -75
- package/src/fileUtil.ts +1 -1
- package/src/logger/jsonLogger.ts +3 -1
- package/src/logger/logFmtLogger.ts +1 -1
- package/src/logger/shared.ts +3 -2
- package/src/otel.ts +152 -0
- package/src/rateLimit.ts +34 -23
- package/src/test.ts +2 -2
- package/test/auth.test.ts +101 -0
- package/test/contextProvider.test.ts +14 -11
- package/test/controller.test.ts +25 -29
- package/test/dist/auth.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/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-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/fixtures.ts +16 -9
- package/test/layerUtils.test.ts +1 -1
- package/test/query.test.ts +819 -38
- package/test/rawQuery.test.ts +312 -20
- 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-e2e-invalidation.test.ts +256 -0
- package/test/rpc-multi-middleware.test.ts +84 -9
- package/test/rpc-stream-fullstack.test.ts +304 -0
- package/test/sql-store.test.ts +1592 -0
- package/test/validateSample.test.ts +17 -12
- package/tsconfig.examples.json +1 -1
- package/tsconfig.json +0 -1
- package/tsconfig.json.bak +2 -2
- package/tsconfig.src.json +35 -35
- package/tsconfig.test.json +2 -2
- 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/eslint.config.mjs +0 -24
- package/src/Operations.ts +0 -235
- package/src/OperationsRepo.ts +0 -16
|
@@ -1,13 +1,94 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
3
|
-
import
|
|
3
|
+
import * as Array from "effect-app/Array"
|
|
4
4
|
import { toNonEmptyArray } from "effect-app/Array"
|
|
5
|
+
import * as Option from "effect-app/Option"
|
|
6
|
+
import * as S from "effect-app/Schema"
|
|
5
7
|
import { dropUndefinedT } from "effect-app/utils"
|
|
8
|
+
import { identity, pipe } from "effect/Function"
|
|
9
|
+
import * as Match from "effect/Match"
|
|
10
|
+
import * as SchemaAST from "effect/SchemaAST"
|
|
6
11
|
import type { FilterResult } from "../filter/filterApi.js"
|
|
7
12
|
import type { FieldValues } from "../filter/types.js"
|
|
8
13
|
import type { FieldPath } from "../filter/types/path/eager.js"
|
|
9
14
|
import { make, type Q, type QAll } from "../query/dsl.js"
|
|
10
15
|
|
|
16
|
+
export type ComputedProjectionMathIrExpression =
|
|
17
|
+
| {
|
|
18
|
+
readonly _tag: "field"
|
|
19
|
+
readonly field: string
|
|
20
|
+
}
|
|
21
|
+
| {
|
|
22
|
+
readonly _tag: "mul"
|
|
23
|
+
readonly left: ComputedProjectionMathIrExpression
|
|
24
|
+
readonly right: ComputedProjectionMathIrExpression
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type ComputedProjectionIrExpression =
|
|
28
|
+
| {
|
|
29
|
+
readonly _tag: "relation-count"
|
|
30
|
+
readonly path: string
|
|
31
|
+
readonly filter: readonly FilterResult[]
|
|
32
|
+
}
|
|
33
|
+
| {
|
|
34
|
+
readonly _tag: "relation-any"
|
|
35
|
+
readonly path: string
|
|
36
|
+
readonly filter: readonly FilterResult[]
|
|
37
|
+
}
|
|
38
|
+
| {
|
|
39
|
+
readonly _tag: "relation-every"
|
|
40
|
+
readonly path: string
|
|
41
|
+
readonly filter: readonly FilterResult[]
|
|
42
|
+
}
|
|
43
|
+
| {
|
|
44
|
+
readonly _tag: "relation-distinct-count"
|
|
45
|
+
readonly path: string
|
|
46
|
+
readonly field: string
|
|
47
|
+
readonly filter: readonly FilterResult[]
|
|
48
|
+
}
|
|
49
|
+
| {
|
|
50
|
+
readonly _tag: "relation-sum"
|
|
51
|
+
readonly path: string
|
|
52
|
+
readonly field: string
|
|
53
|
+
readonly filter: readonly FilterResult[]
|
|
54
|
+
}
|
|
55
|
+
| {
|
|
56
|
+
readonly _tag: "relation-sum-expr"
|
|
57
|
+
readonly path: string
|
|
58
|
+
readonly expression: ComputedProjectionMathIrExpression
|
|
59
|
+
readonly filter: readonly FilterResult[]
|
|
60
|
+
}
|
|
61
|
+
| {
|
|
62
|
+
readonly _tag: "relation-sum-expr-by"
|
|
63
|
+
readonly path: string
|
|
64
|
+
readonly expression: ComputedProjectionMathIrExpression
|
|
65
|
+
readonly unit: string
|
|
66
|
+
readonly filter: readonly FilterResult[]
|
|
67
|
+
}
|
|
68
|
+
| {
|
|
69
|
+
readonly _tag: "relation-sum-expr-normalized"
|
|
70
|
+
readonly path: string
|
|
71
|
+
readonly expression: ComputedProjectionMathIrExpression
|
|
72
|
+
readonly unit: string
|
|
73
|
+
readonly toBase: string
|
|
74
|
+
readonly factors: Readonly<Record<string, number>>
|
|
75
|
+
readonly filter: readonly FilterResult[]
|
|
76
|
+
}
|
|
77
|
+
| {
|
|
78
|
+
readonly _tag: "relation-collect"
|
|
79
|
+
readonly path: string
|
|
80
|
+
readonly field: string
|
|
81
|
+
readonly distinct: boolean
|
|
82
|
+
readonly filter: readonly FilterResult[]
|
|
83
|
+
}
|
|
84
|
+
| {
|
|
85
|
+
readonly _tag: "relation-collect-fields"
|
|
86
|
+
readonly path: string
|
|
87
|
+
readonly fields: readonly string[]
|
|
88
|
+
readonly distinct: boolean
|
|
89
|
+
readonly filter: readonly FilterResult[]
|
|
90
|
+
}
|
|
91
|
+
|
|
11
92
|
type Result<TFieldValues extends FieldValues, A = TFieldValues, R = never> = {
|
|
12
93
|
filter: FilterResult[]
|
|
13
94
|
schema: S.Codec<A, TFieldValues, R> | undefined
|
|
@@ -16,6 +97,7 @@ type Result<TFieldValues extends FieldValues, A = TFieldValues, R = never> = {
|
|
|
16
97
|
order: { key: FieldPath<TFieldValues>; direction: "ASC" | "DESC" }[]
|
|
17
98
|
ttype: "one" | "many" | "count" | undefined
|
|
18
99
|
mode: "collect" | "project" | "transform" | undefined
|
|
100
|
+
computed: Record<string, ComputedProjectionIrExpression> | undefined
|
|
19
101
|
}
|
|
20
102
|
|
|
21
103
|
const interpret = <
|
|
@@ -33,7 +115,8 @@ const interpret = <
|
|
|
33
115
|
skip: undefined,
|
|
34
116
|
order: [],
|
|
35
117
|
ttype: undefined,
|
|
36
|
-
mode: undefined
|
|
118
|
+
mode: undefined,
|
|
119
|
+
computed: undefined
|
|
37
120
|
}
|
|
38
121
|
|
|
39
122
|
const upd = (
|
|
@@ -46,6 +129,7 @@ const interpret = <
|
|
|
46
129
|
if (v.ttype !== undefined) data.ttype = v.ttype
|
|
47
130
|
if (v.schema !== undefined) data.schema = v.schema
|
|
48
131
|
if (v.mode !== undefined) data.mode = v.mode
|
|
132
|
+
if (v.computed !== undefined) data.computed = v.computed
|
|
49
133
|
}
|
|
50
134
|
|
|
51
135
|
const applyPath = (path: string) => (_: FilterResult): FilterResult =>
|
|
@@ -135,8 +219,84 @@ const interpret = <
|
|
|
135
219
|
},
|
|
136
220
|
project: (v) => {
|
|
137
221
|
upd(interpret(v.current))
|
|
222
|
+
if (v.computed && v.mode === "transform") {
|
|
223
|
+
throw new Error("Computed projections require mode 'project' or 'collect', not 'transform'")
|
|
224
|
+
}
|
|
138
225
|
data.schema = v.schema
|
|
139
|
-
data.mode = v.
|
|
226
|
+
data.mode = v.computed
|
|
227
|
+
? v.mode === "collect" ? "collect" : "project"
|
|
228
|
+
: v.mode
|
|
229
|
+
data.computed = v.computed
|
|
230
|
+
? Object.fromEntries(
|
|
231
|
+
Object.entries(v.computed).map(([key, expression]) => {
|
|
232
|
+
const e = expression
|
|
233
|
+
const filter = e.operation ? interpret(e.operation(make())).filter.map(applyPath(e.path)) : []
|
|
234
|
+
switch (e._tag) {
|
|
235
|
+
case "relation-count":
|
|
236
|
+
case "relation-any":
|
|
237
|
+
case "relation-every":
|
|
238
|
+
return [key, { _tag: e._tag, path: e.path, filter } as ComputedProjectionIrExpression]
|
|
239
|
+
case "relation-distinct-count":
|
|
240
|
+
case "relation-sum":
|
|
241
|
+
return [
|
|
242
|
+
key,
|
|
243
|
+
{ _tag: e._tag, path: e.path, field: e.field, filter } as ComputedProjectionIrExpression
|
|
244
|
+
]
|
|
245
|
+
case "relation-sum-expr":
|
|
246
|
+
return [
|
|
247
|
+
key,
|
|
248
|
+
{ _tag: e._tag, path: e.path, expression: e.expression, filter } as ComputedProjectionIrExpression
|
|
249
|
+
]
|
|
250
|
+
case "relation-sum-expr-by":
|
|
251
|
+
return [
|
|
252
|
+
key,
|
|
253
|
+
{
|
|
254
|
+
_tag: e._tag,
|
|
255
|
+
path: e.path,
|
|
256
|
+
expression: e.expression,
|
|
257
|
+
unit: e.unit,
|
|
258
|
+
filter
|
|
259
|
+
} as ComputedProjectionIrExpression
|
|
260
|
+
]
|
|
261
|
+
case "relation-sum-expr-normalized":
|
|
262
|
+
return [
|
|
263
|
+
key,
|
|
264
|
+
{
|
|
265
|
+
_tag: e._tag,
|
|
266
|
+
path: e.path,
|
|
267
|
+
expression: e.expression,
|
|
268
|
+
unit: e.unit,
|
|
269
|
+
toBase: e.toBase,
|
|
270
|
+
factors: e.factors,
|
|
271
|
+
filter
|
|
272
|
+
} as ComputedProjectionIrExpression
|
|
273
|
+
]
|
|
274
|
+
case "relation-collect":
|
|
275
|
+
return [
|
|
276
|
+
key,
|
|
277
|
+
{
|
|
278
|
+
_tag: e._tag,
|
|
279
|
+
path: e.path,
|
|
280
|
+
field: e.field,
|
|
281
|
+
distinct: e.distinct,
|
|
282
|
+
filter
|
|
283
|
+
} as ComputedProjectionIrExpression
|
|
284
|
+
]
|
|
285
|
+
case "relation-collect-fields":
|
|
286
|
+
return [
|
|
287
|
+
key,
|
|
288
|
+
{
|
|
289
|
+
_tag: e._tag,
|
|
290
|
+
path: e.path,
|
|
291
|
+
fields: e.fields,
|
|
292
|
+
distinct: e.distinct,
|
|
293
|
+
filter
|
|
294
|
+
} as ComputedProjectionIrExpression
|
|
295
|
+
]
|
|
296
|
+
}
|
|
297
|
+
})
|
|
298
|
+
)
|
|
299
|
+
: undefined
|
|
140
300
|
}
|
|
141
301
|
})
|
|
142
302
|
)
|
|
@@ -157,15 +317,19 @@ export const toFilter = <
|
|
|
157
317
|
R,
|
|
158
318
|
TFieldValuesRefined extends TFieldValues = TFieldValues
|
|
159
319
|
>(
|
|
160
|
-
q: QAll<TFieldValues, TFieldValuesRefined, A, R
|
|
320
|
+
q: QAll<TFieldValues, TFieldValuesRefined, A, R>,
|
|
321
|
+
baseSchema?: S.Schema<unknown>
|
|
161
322
|
) => {
|
|
162
323
|
// TODO: Native interpreter for each db adapter, instead of the intermediate "new-kid" format
|
|
163
324
|
const a = interpret(q)
|
|
164
325
|
const schema = a.schema
|
|
165
|
-
let select: (keyof TFieldValues | { key: string; subKeys: string[] }
|
|
326
|
+
let select: (keyof TFieldValues | { key: string; subKeys: string[] } | {
|
|
327
|
+
key: string
|
|
328
|
+
computed: ComputedProjectionIrExpression
|
|
329
|
+
})[] = []
|
|
166
330
|
// TODO: support more complex (nested) schemas?
|
|
167
331
|
if (schema) {
|
|
168
|
-
const t = walkTransformation(schema.ast)
|
|
332
|
+
const t = walkTransformation(SchemaAST.toEncoded(schema.ast))
|
|
169
333
|
if (S.AST.isObjects(t)) {
|
|
170
334
|
select = t.propertySignatures.map((_) => _.name as string)
|
|
171
335
|
for (const prop of t.propertySignatures) {
|
|
@@ -194,12 +358,53 @@ export const toFilter = <
|
|
|
194
358
|
}
|
|
195
359
|
}
|
|
196
360
|
}
|
|
361
|
+
const computed = a.computed
|
|
362
|
+
const getSelectKey = (_: (typeof select)[number]) => {
|
|
363
|
+
if (typeof _ === "string") {
|
|
364
|
+
return _
|
|
365
|
+
}
|
|
366
|
+
if (typeof _ === "object" && _ !== null && "key" in _) {
|
|
367
|
+
return _.key
|
|
368
|
+
}
|
|
369
|
+
return String(_)
|
|
370
|
+
}
|
|
371
|
+
const schemaKeys = select.map(getSelectKey)
|
|
372
|
+
const nonEncodedSchemaKeys = (() => {
|
|
373
|
+
if (!baseSchema) {
|
|
374
|
+
return [] as string[]
|
|
375
|
+
}
|
|
376
|
+
const encoded = walkTransformation(SchemaAST.toEncoded(baseSchema.ast))
|
|
377
|
+
if (!S.AST.isObjects(encoded)) {
|
|
378
|
+
return [] as string[]
|
|
379
|
+
}
|
|
380
|
+
const encodedKeys = encoded.propertySignatures.map((_) => _.name as string)
|
|
381
|
+
return schemaKeys.filter((key) => !encodedKeys.includes(key))
|
|
382
|
+
})()
|
|
383
|
+
const missingComputedKeys = nonEncodedSchemaKeys.filter((key) => !(computed && key in computed))
|
|
384
|
+
|
|
385
|
+
if (Array.isArrayNonEmpty(missingComputedKeys)) {
|
|
386
|
+
throw new Error(`Missing computed projections for schema keys: ${missingComputedKeys.join(", ")}`)
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
if (computed) {
|
|
390
|
+
const computedKeys = Object.keys(computed)
|
|
391
|
+
const extraComputedKeys = computedKeys.filter((key) => !schemaKeys.includes(key))
|
|
392
|
+
if (Array.isArrayNonEmpty(extraComputedKeys)) {
|
|
393
|
+
throw new Error(`Computed projection keys must exist in projection schema: ${extraComputedKeys.join(", ")}`)
|
|
394
|
+
}
|
|
395
|
+
select = select.filter((_) => {
|
|
396
|
+
const key = getSelectKey(_)
|
|
397
|
+
return !(key in computed)
|
|
398
|
+
})
|
|
399
|
+
select.push(...Object.entries(computed).map(([key, expression]) => ({ key, computed: expression })))
|
|
400
|
+
}
|
|
197
401
|
return dropUndefinedT({
|
|
198
402
|
t: null as unknown as TFieldValues,
|
|
199
403
|
limit: a.limit,
|
|
200
404
|
skip: a.skip,
|
|
201
405
|
select: Option.getOrUndefined(toNonEmptyArray(select)),
|
|
202
406
|
schema,
|
|
407
|
+
computed,
|
|
203
408
|
order: Option.getOrUndefined(toNonEmptyArray(a.order)),
|
|
204
409
|
ttype: a.ttype,
|
|
205
410
|
mode: a.mode ?? "transform",
|
package/src/Model.ts
CHANGED
|
@@ -2,18 +2,24 @@ import { getRequestContext, setupRequestContextWithCustomSpan } from "@effect-ap
|
|
|
2
2
|
import { reportNonInterruptedFailure } from "@effect-app/infra/QueueMaker/errors"
|
|
3
3
|
import { type QueueBase, QueueMeta } from "@effect-app/infra/QueueMaker/service"
|
|
4
4
|
import { subMinutes } from "date-fns"
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
5
|
+
import type { NonEmptyReadonlyArray } from "effect-app/Array"
|
|
6
|
+
import * as Effect from "effect-app/Effect"
|
|
7
|
+
import * as Option from "effect-app/Option"
|
|
8
|
+
import * as S from "effect-app/Schema"
|
|
9
|
+
import { type NonEmptyString255 } from "effect-app/Schema"
|
|
7
10
|
import { pretty } from "effect-app/utils"
|
|
11
|
+
import * as Fiber from "effect/Fiber"
|
|
12
|
+
import * as Tracer from "effect/Tracer"
|
|
8
13
|
import { SqlClient } from "effect/unstable/sql"
|
|
9
14
|
import { SQLModel } from "../adapters/SQL.js"
|
|
10
15
|
import { InfraLogger } from "../logger.js"
|
|
16
|
+
import { messagingSpanArgs } from "../otel.js"
|
|
11
17
|
|
|
12
|
-
export const QueueId = S.
|
|
18
|
+
export const QueueId = S.Finite.pipe(S.brand("QueueId"))
|
|
13
19
|
export type QueueId = typeof QueueId.Type
|
|
14
20
|
|
|
15
21
|
// TODO: let the model track and Auto Generate versionColumn on every update instead
|
|
16
|
-
export
|
|
22
|
+
export const makeSQLQueue = Effect.fnUntraced(function*<
|
|
17
23
|
Evt extends { id: S.StringId; _tag: string },
|
|
18
24
|
DrainEvt extends { id: S.StringId; _tag: string },
|
|
19
25
|
EvtE,
|
|
@@ -24,166 +30,157 @@ export function makeSQLQueue<
|
|
|
24
30
|
schema: S.Codec<Evt, EvtE>,
|
|
25
31
|
drainSchema: S.Codec<DrainEvt, DrainEvtE>
|
|
26
32
|
) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const sql = yield* SqlClient.SqlClient
|
|
33
|
+
const base = {
|
|
34
|
+
id: SQLModel.Generated(QueueId),
|
|
35
|
+
meta: SQLModel.JsonFromString(QueueMeta),
|
|
36
|
+
name: S.NonEmptyString255,
|
|
37
|
+
createdAt: SQLModel.DateTimeInsert,
|
|
38
|
+
updatedAt: SQLModel.DateTimeUpdate,
|
|
39
|
+
// TODO: at+owner
|
|
40
|
+
processingAt: SQLModel.FieldOption(S.Date),
|
|
41
|
+
finishedAt: SQLModel.FieldOption(S.Date),
|
|
42
|
+
etag: S.String // TODO: use a SQLModel thing that auto updates it?
|
|
43
|
+
// TODO: record locking.. / optimistic locking
|
|
44
|
+
// rowVersion: SQLModel.DateTimeFromNumberWithNow
|
|
45
|
+
}
|
|
46
|
+
class Queue extends SQLModel.Class<Queue>("Queue")({
|
|
47
|
+
body: SQLModel.JsonFromString(schema),
|
|
48
|
+
...base
|
|
49
|
+
}) {}
|
|
50
|
+
class Drain extends SQLModel.Class<Drain>("Drain")({
|
|
51
|
+
body: SQLModel.JsonFromString(drainSchema),
|
|
52
|
+
...base
|
|
53
|
+
}) {}
|
|
54
|
+
const sql = yield* SqlClient.SqlClient
|
|
50
55
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
const queueRepo = yield* SQLModel.makeRepository(Queue, {
|
|
57
|
+
tableName: "queue",
|
|
58
|
+
spanPrefix: "QueueRepo",
|
|
59
|
+
idColumn: "id",
|
|
60
|
+
versionColumn: "etag"
|
|
61
|
+
})
|
|
57
62
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
63
|
+
const drainRepo = yield* SQLModel.makeRepository(Drain, {
|
|
64
|
+
tableName: "queue",
|
|
65
|
+
spanPrefix: "DrainRepo",
|
|
66
|
+
idColumn: "id",
|
|
67
|
+
versionColumn: "etag"
|
|
68
|
+
})
|
|
64
69
|
|
|
65
|
-
|
|
70
|
+
const decodeDrain = S.decodeEffectConcurrently(Drain)
|
|
66
71
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
Effect
|
|
71
|
-
.andThen((limit) =>
|
|
72
|
-
sql<typeof Drain.Encoded>`SELECT *
|
|
72
|
+
const drain = Effect.gen(function*() {
|
|
73
|
+
const limit = subMinutes(new Date(), 15)
|
|
74
|
+
return yield* sql<typeof Drain.Encoded>`SELECT *
|
|
73
75
|
FROM queue
|
|
74
76
|
WHERE name = ${queueDrainName} AND finishedAt IS NULL AND (processingAt IS NULL OR processingAt < ${limit.getTime()})
|
|
75
77
|
LIMIT 1`
|
|
76
|
-
|
|
77
|
-
)
|
|
78
|
+
})
|
|
78
79
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
if (first) return first
|
|
101
|
-
yield* Effect.sleep(250)
|
|
80
|
+
const q = {
|
|
81
|
+
offer: Effect.fnUntraced(function*(body: Evt, meta: typeof QueueMeta.Type) {
|
|
82
|
+
yield* queueRepo.insertVoid(Queue.insert.make({
|
|
83
|
+
body,
|
|
84
|
+
meta,
|
|
85
|
+
name: queueName,
|
|
86
|
+
processingAt: Option.none(),
|
|
87
|
+
finishedAt: Option.none(),
|
|
88
|
+
etag: crypto.randomUUID()
|
|
89
|
+
}))
|
|
90
|
+
}),
|
|
91
|
+
take: Effect.gen(function*() {
|
|
92
|
+
while (true) {
|
|
93
|
+
const [first] = yield* drain.pipe(Effect.withTracerEnabled(false)) // disable sql tracer otherwise we spam it..
|
|
94
|
+
if (first) {
|
|
95
|
+
const dec = yield* decodeDrain(first)
|
|
96
|
+
const { createdAt, updatedAt, ...rest } = dec
|
|
97
|
+
return yield* drainRepo.update(
|
|
98
|
+
Drain.update.make({ ...rest, processingAt: Option.some(new Date()) }) // auto in lib , etag: crypto.randomUUID()
|
|
99
|
+
)
|
|
102
100
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
101
|
+
if (first) return first
|
|
102
|
+
yield* Effect.sleep(250)
|
|
103
|
+
}
|
|
104
|
+
}),
|
|
105
|
+
finish: Effect.fn(function*({ createdAt, updatedAt, ...q }: Drain) {
|
|
106
|
+
return yield* drainRepo.updateVoid(Drain.update.make({ ...q, finishedAt: Option.some(new Date()) })) // auto in lib , etag: crypto.randomUUID()
|
|
107
|
+
})
|
|
108
|
+
}
|
|
109
|
+
const queue = {
|
|
110
|
+
publish: Effect.fn(`publish ${queueName}`, {
|
|
111
|
+
kind: "producer",
|
|
112
|
+
attributes: {
|
|
113
|
+
"messaging.system": "sql",
|
|
114
|
+
"messaging.operation.name": "publish",
|
|
115
|
+
"messaging.destination.name": queueName
|
|
116
|
+
}
|
|
117
|
+
})(function*(
|
|
118
|
+
...messages: NonEmptyReadonlyArray<Evt>
|
|
119
|
+
) {
|
|
120
|
+
yield* Effect.annotateCurrentSpan({
|
|
121
|
+
"messaging.batch.message_count": messages.length,
|
|
122
|
+
"messaging.message.types": messages.map((_) => _._tag)
|
|
123
|
+
})
|
|
124
|
+
const requestContext = yield* getRequestContext
|
|
125
|
+
yield* Effect.forEach(messages, (m) => q.offer(m, requestContext), { discard: true })
|
|
126
|
+
}),
|
|
127
|
+
drain: <DrainE, DrainR>(
|
|
128
|
+
handleEvent: (ks: DrainEvt) => Effect.Effect<void, DrainE, DrainR>,
|
|
129
|
+
sessionId?: string
|
|
130
|
+
) => {
|
|
131
|
+
const silenceAndReportError = reportNonInterruptedFailure({ name: "MemQueue.drain." + queueDrainName })
|
|
132
|
+
const processMessage = Effect.fnUntraced(function*({ body, meta }: Drain) {
|
|
133
|
+
let effect = InfraLogger
|
|
134
|
+
.logDebug(`[${queueDrainName}] Processing incoming message`)
|
|
110
135
|
.pipe(
|
|
111
|
-
Effect.
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
const processMessage = (msg: Drain) =>
|
|
132
|
-
Effect
|
|
133
|
-
.succeed(msg)
|
|
134
|
-
.pipe(Effect
|
|
135
|
-
.flatMap(({ body, meta }) => {
|
|
136
|
-
let effect = InfraLogger
|
|
137
|
-
.logDebug(`[${queueDrainName}] Processing incoming message`)
|
|
138
|
-
.pipe(
|
|
139
|
-
Effect.annotateLogs({ body: pretty(body), meta: pretty(meta) }),
|
|
140
|
-
Effect.andThen(handleEvent(body)),
|
|
141
|
-
silenceAndReportError,
|
|
142
|
-
(_) =>
|
|
143
|
-
setupRequestContextWithCustomSpan(
|
|
144
|
-
_,
|
|
145
|
-
meta,
|
|
146
|
-
`queue.drain: ${queueDrainName}.${body._tag}`,
|
|
147
|
-
{
|
|
148
|
-
captureStackTrace: false,
|
|
149
|
-
kind: "consumer",
|
|
150
|
-
attributes: {
|
|
151
|
-
"queue.name": queueDrainName,
|
|
152
|
-
"queue.sessionId": sessionId,
|
|
153
|
-
"queue.input": body
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
)
|
|
157
|
-
)
|
|
158
|
-
if (meta.span) {
|
|
159
|
-
effect = Effect.withParentSpan(effect, Tracer.externalSpan(meta.span))
|
|
136
|
+
Effect.annotateLogs({ body: pretty(body), meta: pretty(meta) }),
|
|
137
|
+
Effect.andThen(handleEvent(body)),
|
|
138
|
+
silenceAndReportError,
|
|
139
|
+
(_) => {
|
|
140
|
+
const args = messagingSpanArgs({
|
|
141
|
+
operation: "process",
|
|
142
|
+
system: "sql",
|
|
143
|
+
destination: queueDrainName,
|
|
144
|
+
messageId: body.id,
|
|
145
|
+
conversationId: sessionId,
|
|
146
|
+
extra: { "messaging.message.type": body._tag, "messaging.message.body": body }
|
|
147
|
+
}, "consumer")
|
|
148
|
+
return setupRequestContextWithCustomSpan(
|
|
149
|
+
_,
|
|
150
|
+
meta,
|
|
151
|
+
args.name,
|
|
152
|
+
{
|
|
153
|
+
captureStackTrace: false,
|
|
154
|
+
kind: args.kind,
|
|
155
|
+
attributes: args.attributes
|
|
160
156
|
}
|
|
161
|
-
return effect
|
|
162
|
-
}))
|
|
163
|
-
|
|
164
|
-
return q
|
|
165
|
-
.take
|
|
166
|
-
.pipe(
|
|
167
|
-
Effect.flatMap((x) =>
|
|
168
|
-
processMessage(x).pipe(
|
|
169
|
-
Effect.uninterruptible,
|
|
170
|
-
Effect.forkChild,
|
|
171
|
-
Effect.flatMap(Fiber.join),
|
|
172
|
-
Effect.tap(q.finish(x))
|
|
173
157
|
)
|
|
174
|
-
|
|
175
|
-
silenceAndReportError,
|
|
176
|
-
Effect.withSpan(`queue.drain: ${queueDrainName}`, {
|
|
177
|
-
attributes: {
|
|
178
|
-
"queue.type": "sql",
|
|
179
|
-
"queue.name": queueDrainName,
|
|
180
|
-
"queue.sessionId": sessionId
|
|
181
|
-
}
|
|
182
|
-
}),
|
|
183
|
-
Effect.forever
|
|
158
|
+
}
|
|
184
159
|
)
|
|
185
|
-
|
|
160
|
+
if (meta.span) {
|
|
161
|
+
effect = Effect.withParentSpan(effect, Tracer.externalSpan(meta.span))
|
|
162
|
+
}
|
|
163
|
+
return yield* effect
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
return Effect.fn(`receive ${queueDrainName}`, {
|
|
167
|
+
kind: "consumer",
|
|
168
|
+
attributes: {
|
|
169
|
+
"messaging.system": "sql",
|
|
170
|
+
"messaging.operation.name": "receive",
|
|
171
|
+
"messaging.destination.name": queueDrainName,
|
|
172
|
+
...(sessionId !== undefined && { "messaging.message.conversation_id": sessionId })
|
|
173
|
+
}
|
|
174
|
+
})(function*() {
|
|
175
|
+
const x = yield* q.take
|
|
176
|
+
yield* processMessage(x).pipe(
|
|
177
|
+
Effect.uninterruptible,
|
|
178
|
+
Effect.forkChild,
|
|
179
|
+
Effect.flatMap(Fiber.join),
|
|
180
|
+
Effect.tap(q.finish(x))
|
|
181
|
+
)
|
|
182
|
+
}, (effect) => effect.pipe(silenceAndReportError, Effect.forever))()
|
|
186
183
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
}
|
|
184
|
+
}
|
|
185
|
+
return queue as QueueBase<Evt, DrainEvt>
|
|
186
|
+
})
|
package/src/QueueMaker/errors.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { reportError } from "@effect-app/infra/errorReporter"
|
|
2
|
-
import
|
|
2
|
+
import * as Effect from "effect-app/Effect"
|
|
3
|
+
import * as Cause from "effect/Cause"
|
|
4
|
+
import * as Exit from "effect/Exit"
|
|
3
5
|
|
|
4
6
|
const reportQueueError_ = reportError("Queue")
|
|
5
7
|
|