@effect-app/infra 4.0.0-beta.22 → 4.0.0-beta.220
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 +1640 -0
- package/_check.sh +1 -1
- package/dist/CUPS.d.ts +7 -7
- package/dist/CUPS.d.ts.map +1 -1
- package/dist/CUPS.js +10 -12
- package/dist/Emailer/Sendgrid.d.ts +14 -14
- package/dist/Emailer/Sendgrid.d.ts.map +1 -1
- package/dist/Emailer/Sendgrid.js +16 -15
- package/dist/Emailer/fake.d.ts +1 -1
- package/dist/Emailer/service.d.ts +10 -4
- package/dist/Emailer/service.d.ts.map +1 -1
- package/dist/Emailer/service.js +3 -3
- package/dist/Emailer.d.ts +1 -1
- package/dist/MainFiberSet.d.ts +9 -9
- package/dist/MainFiberSet.d.ts.map +1 -1
- package/dist/MainFiberSet.js +3 -3
- package/dist/Model/Repository/Registry.d.ts +20 -0
- package/dist/Model/Repository/Registry.d.ts.map +1 -0
- package/dist/Model/Repository/Registry.js +17 -0
- package/dist/Model/Repository/ext.d.ts +33 -15
- package/dist/Model/Repository/ext.d.ts.map +1 -1
- package/dist/Model/Repository/ext.js +54 -2
- package/dist/Model/Repository/internal/internal.d.ts +6 -6
- package/dist/Model/Repository/internal/internal.d.ts.map +1 -1
- package/dist/Model/Repository/internal/internal.js +103 -51
- package/dist/Model/Repository/legacy.d.ts +1 -1
- package/dist/Model/Repository/makeRepo.d.ts +7 -6
- package/dist/Model/Repository/makeRepo.d.ts.map +1 -1
- package/dist/Model/Repository/makeRepo.js +5 -1
- package/dist/Model/Repository/service.d.ts +28 -23
- package/dist/Model/Repository/service.d.ts.map +1 -1
- package/dist/Model/Repository/validation.d.ts +46 -17
- package/dist/Model/Repository/validation.d.ts.map +1 -1
- package/dist/Model/Repository/validation.js +5 -5
- 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 +4 -4
- package/dist/Model/dsl.d.ts.map +1 -1
- 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 +139 -16
- package/dist/Model/query/dsl.d.ts.map +1 -1
- package/dist/Model/query/dsl.js +187 -1
- package/dist/Model/query/new-kid-interpreter.d.ts +76 -7
- package/dist/Model/query/new-kid-interpreter.d.ts.map +1 -1
- package/dist/Model/query/new-kid-interpreter.js +122 -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 +5 -7
- package/dist/QueueMaker/SQLQueue.d.ts.map +1 -1
- package/dist/QueueMaker/SQLQueue.js +130 -116
- package/dist/QueueMaker/errors.d.ts +2 -2
- package/dist/QueueMaker/errors.d.ts.map +1 -1
- package/dist/QueueMaker/memQueue.d.ts +7 -4
- package/dist/QueueMaker/memQueue.d.ts.map +1 -1
- package/dist/QueueMaker/memQueue.js +75 -63
- package/dist/QueueMaker/sbqueue.d.ts +6 -3
- package/dist/QueueMaker/sbqueue.d.ts.map +1 -1
- package/dist/QueueMaker/sbqueue.js +52 -53
- package/dist/QueueMaker/service.d.ts +1 -1
- package/dist/RequestContext.d.ts +74 -35
- package/dist/RequestContext.d.ts.map +1 -1
- package/dist/RequestContext.js +13 -14
- package/dist/RequestFiberSet.d.ts +7 -7
- package/dist/RequestFiberSet.d.ts.map +1 -1
- package/dist/RequestFiberSet.js +3 -3
- package/dist/Store/ContextMapContainer.d.ts +19 -3
- package/dist/Store/ContextMapContainer.d.ts.map +1 -1
- package/dist/Store/ContextMapContainer.js +13 -3
- package/dist/Store/Cosmos/query.d.ts +5 -1
- package/dist/Store/Cosmos/query.d.ts.map +1 -1
- package/dist/Store/Cosmos/query.js +113 -34
- package/dist/Store/Cosmos.d.ts +1 -1
- package/dist/Store/Cosmos.d.ts.map +1 -1
- package/dist/Store/Cosmos.js +335 -243
- package/dist/Store/Disk.d.ts +2 -2
- package/dist/Store/Disk.d.ts.map +1 -1
- package/dist/Store/Disk.js +72 -35
- package/dist/Store/Memory.d.ts +6 -4
- package/dist/Store/Memory.d.ts.map +1 -1
- package/dist/Store/Memory.js +242 -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 +231 -0
- package/dist/Store/SQL/query.d.ts +42 -0
- package/dist/Store/SQL/query.d.ts.map +1 -0
- package/dist/Store/SQL/query.js +479 -0
- package/dist/Store/SQL.d.ts +20 -0
- package/dist/Store/SQL.d.ts.map +1 -0
- package/dist/Store/SQL.js +446 -0
- package/dist/Store/codeFilter.d.ts +1 -1
- package/dist/Store/codeFilter.d.ts.map +1 -1
- package/dist/Store/codeFilter.js +4 -2
- package/dist/Store/index.d.ts +5 -2
- package/dist/Store/index.d.ts.map +1 -1
- package/dist/Store/index.js +15 -3
- package/dist/Store/service.d.ts +22 -8
- package/dist/Store/service.d.ts.map +1 -1
- package/dist/Store/service.js +24 -6
- package/dist/Store/utils.d.ts +1 -1
- package/dist/Store/utils.d.ts.map +1 -1
- package/dist/Store/utils.js +3 -4
- package/dist/Store.d.ts +1 -1
- package/dist/adapters/SQL/Model.d.ts +31 -42
- package/dist/adapters/SQL/Model.d.ts.map +1 -1
- package/dist/adapters/SQL/Model.js +29 -38
- package/dist/adapters/SQL.d.ts +1 -1
- package/dist/adapters/ServiceBus.d.ts +11 -11
- package/dist/adapters/ServiceBus.d.ts.map +1 -1
- package/dist/adapters/ServiceBus.js +25 -21
- package/dist/adapters/cosmos-client.d.ts +3 -3
- package/dist/adapters/cosmos-client.d.ts.map +1 -1
- package/dist/adapters/cosmos-client.js +3 -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 +1 -1
- package/dist/adapters/logger.d.ts.map +1 -1
- package/dist/adapters/memQueue.d.ts +3 -3
- package/dist/adapters/memQueue.d.ts.map +1 -1
- package/dist/adapters/memQueue.js +3 -3
- package/dist/adapters/mongo-client.d.ts +3 -3
- package/dist/adapters/mongo-client.d.ts.map +1 -1
- package/dist/adapters/mongo-client.js +3 -3
- package/dist/adapters/redis-client.d.ts +3 -3
- package/dist/adapters/redis-client.d.ts.map +1 -1
- package/dist/adapters/redis-client.js +3 -3
- package/dist/api/ContextProvider.d.ts +8 -8
- package/dist/api/ContextProvider.d.ts.map +1 -1
- package/dist/api/ContextProvider.js +6 -6
- package/dist/api/codec.d.ts +1 -1
- package/dist/api/internal/RequestContextMiddleware.d.ts +2 -2
- package/dist/api/internal/RequestContextMiddleware.d.ts.map +1 -1
- package/dist/api/internal/RequestContextMiddleware.js +9 -6
- package/dist/api/internal/auth.d.ts +44 -6
- package/dist/api/internal/auth.d.ts.map +1 -1
- package/dist/api/internal/auth.js +160 -29
- package/dist/api/internal/events.d.ts +3 -3
- package/dist/api/internal/events.d.ts.map +1 -1
- package/dist/api/internal/events.js +10 -8
- package/dist/api/internal/health.d.ts +1 -1
- package/dist/api/layerUtils.d.ts +6 -6
- package/dist/api/layerUtils.d.ts.map +1 -1
- package/dist/api/layerUtils.js +5 -5
- package/dist/api/middlewares.d.ts +1 -1
- package/dist/api/reportError.d.ts +1 -1
- package/dist/api/routing/middleware/RouterMiddleware.d.ts +4 -4
- package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/middleware.d.ts +39 -3
- package/dist/api/routing/middleware/middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/middleware.js +48 -16
- 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/tsort.d.ts +1 -1
- package/dist/api/routing/tsort.d.ts.map +1 -1
- package/dist/api/routing/utils.d.ts +3 -3
- package/dist/api/routing/utils.d.ts.map +1 -1
- package/dist/api/routing.d.ts +80 -37
- package/dist/api/routing.d.ts.map +1 -1
- package/dist/api/routing.js +109 -41
- package/dist/api/setupRequest.d.ts +8 -5
- package/dist/api/setupRequest.d.ts.map +1 -1
- package/dist/api/setupRequest.js +12 -7
- package/dist/api/util.d.ts +1 -1
- package/dist/arbs.d.ts +1 -1
- package/dist/arbs.d.ts.map +1 -1
- package/dist/arbs.js +5 -3
- package/dist/errorReporter.d.ts +4 -4
- package/dist/errorReporter.d.ts.map +1 -1
- package/dist/errorReporter.js +20 -25
- package/dist/errors.d.ts +1 -1
- package/dist/fileUtil.d.ts +1 -1
- package/dist/fileUtil.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/logger/jsonLogger.d.ts +1 -1
- package/dist/logger/logFmtLogger.d.ts +1 -1
- package/dist/logger/shared.d.ts +1 -1
- package/dist/logger/shared.js +2 -2
- 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 +9 -3
- package/dist/rateLimit.d.ts.map +1 -1
- package/dist/rateLimit.js +5 -11
- package/dist/test.d.ts +2 -2
- package/dist/test.d.ts.map +1 -1
- package/dist/test.js +1 -1
- package/dist/vitest.d.ts +1 -1
- package/examples/query.ts +42 -38
- package/package.json +46 -37
- package/src/CUPS.ts +9 -11
- package/src/Emailer/Sendgrid.ts +17 -14
- package/src/Emailer/service.ts +9 -3
- package/src/MainFiberSet.ts +5 -6
- package/src/Model/Repository/Registry.ts +33 -0
- package/src/Model/Repository/ext.ts +96 -10
- package/src/Model/Repository/internal/internal.ts +218 -149
- package/src/Model/Repository/makeRepo.ts +12 -10
- package/src/Model/Repository/service.ts +31 -22
- package/src/Model/Repository/validation.ts +4 -4
- package/src/Model/Repository.ts +1 -0
- package/src/Model/dsl.ts +3 -3
- package/src/Model/filter/types/path/eager.ts +1 -2
- package/src/Model/query/dsl.ts +348 -18
- package/src/Model/query/new-kid-interpreter.ts +206 -6
- package/src/Model.ts +1 -0
- package/src/QueueMaker/SQLQueue.ts +144 -152
- package/src/QueueMaker/memQueue.ts +104 -103
- package/src/QueueMaker/sbqueue.ts +70 -86
- package/src/RequestContext.ts +14 -16
- package/src/RequestFiberSet.ts +2 -2
- package/src/Store/ContextMapContainer.ts +41 -2
- package/src/Store/Cosmos/query.ts +140 -43
- package/src/Store/Cosmos.ts +482 -349
- package/src/Store/Disk.ts +102 -65
- package/src/Store/Memory.ts +275 -87
- package/src/Store/SQL/Pg.ts +361 -0
- package/src/Store/SQL/query.ts +539 -0
- package/src/Store/SQL.ts +731 -0
- package/src/Store/codeFilter.ts +3 -1
- package/src/Store/index.ts +17 -2
- package/src/Store/service.ts +41 -10
- package/src/Store/utils.ts +23 -22
- package/src/adapters/SQL/Model.ts +41 -40
- package/src/adapters/ServiceBus.ts +125 -121
- package/src/adapters/cosmos-client.ts +2 -2
- package/src/adapters/index.ts +7 -0
- package/src/adapters/memQueue.ts +2 -2
- package/src/adapters/mongo-client.ts +2 -2
- package/src/adapters/redis-client.ts +2 -2
- package/src/api/ContextProvider.ts +12 -13
- package/src/api/internal/RequestContextMiddleware.ts +15 -5
- package/src/api/internal/auth.ts +246 -44
- package/src/api/internal/events.ts +13 -9
- package/src/api/layerUtils.ts +8 -8
- package/src/api/routing/middleware/RouterMiddleware.ts +4 -4
- package/src/api/routing/middleware/middleware.ts +55 -14
- package/src/api/routing/middleware.ts +0 -2
- package/src/api/routing.ts +296 -131
- package/src/api/setupRequest.ts +28 -8
- package/src/arbs.ts +4 -2
- package/src/errorReporter.ts +62 -74
- package/src/logger/shared.ts +1 -1
- package/src/otel.ts +152 -0
- package/src/rateLimit.ts +30 -22
- package/src/test.ts +1 -1
- package/test/auth.test.ts +101 -0
- package/test/contextProvider.test.ts +11 -11
- package/test/controller.test.ts +21 -30
- 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 +26 -12
- package/test/dist/fixtures.d.ts.map +1 -1
- package/test/dist/fixtures.js +12 -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 +11 -9
- package/test/query.test.ts +813 -38
- package/test/rawQuery.test.ts +301 -20
- package/test/repository-ext.test.ts +60 -0
- package/test/requires.test.ts +6 -6
- package/test/router-generator.test.ts +183 -0
- package/test/routing-interruptibility.test.ts +63 -0
- package/test/rpc-e2e-invalidation.test.ts +251 -0
- package/test/rpc-multi-middleware.test.ts +78 -9
- package/test/rpc-stream-fullstack.test.ts +300 -0
- package/test/sql-store.test.ts +1592 -0
- package/test/validateSample.test.ts +15 -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,7 +1,6 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
|
|
3
|
-
import type
|
|
4
|
-
import { Array, Chunk, Effect, Equivalence, flow, type NonEmptyReadonlyArray, Option, pipe, Pipeable, PubSub, Result, S, SchemaAST, ServiceMap, Unify } from "effect-app"
|
|
2
|
+
|
|
3
|
+
import { Array, Chunk, Context, Effect, Equivalence, flow, type NonEmptyReadonlyArray, Option, pipe, Pipeable, PubSub, Result, S, SchemaAST, Unify } from "effect-app"
|
|
5
4
|
import { toNonEmptyArray } from "effect-app/Array"
|
|
6
5
|
import { NotFoundError } from "effect-app/client/errors"
|
|
7
6
|
import { flatMapOption } from "effect-app/Effect"
|
|
@@ -55,14 +54,14 @@ export function makeRepoInternal<
|
|
|
55
54
|
|
|
56
55
|
function make<RInitial = never, E = never, RPublish = never, RCtx = never>(
|
|
57
56
|
args: [Evt] extends [never] ? {
|
|
58
|
-
schemaContext?:
|
|
57
|
+
schemaContext?: Context.Context<RCtx>
|
|
59
58
|
makeInitial?: Effect.Effect<readonly T[], E, RInitial> | undefined
|
|
60
59
|
config?: Omit<StoreConfig<Encoded>, "partitionValue"> & {
|
|
61
60
|
partitionValue?: (e?: Encoded) => string
|
|
62
61
|
}
|
|
63
62
|
}
|
|
64
63
|
: {
|
|
65
|
-
schemaContext?:
|
|
64
|
+
schemaContext?: Context.Context<RCtx>
|
|
66
65
|
publishEvents: (evt: NonEmptyReadonlyArray<Evt>) => Effect.Effect<void, never, RPublish>
|
|
67
66
|
makeInitial?: Effect.Effect<readonly T[], E, RInitial> | undefined
|
|
68
67
|
config?: Omit<StoreConfig<Encoded>, "partitionValue"> & {
|
|
@@ -72,16 +71,16 @@ export function makeRepoInternal<
|
|
|
72
71
|
) {
|
|
73
72
|
return Effect
|
|
74
73
|
.gen(function*() {
|
|
75
|
-
const rctx:
|
|
74
|
+
const rctx: Context.Context<RCtx> = args.schemaContext ?? Context.empty() as any
|
|
76
75
|
const provideRctx = Effect.provide(rctx)
|
|
77
76
|
const encodeMany = flow(
|
|
78
77
|
S.encodeEffect(S.Array(schema)),
|
|
79
78
|
provideRctx,
|
|
80
|
-
Effect.withSpan("encodeMany", {}, { captureStackTrace: false })
|
|
79
|
+
Effect.withSpan("encodeMany", { attributes: { "app.entity": name } }, { captureStackTrace: false })
|
|
81
80
|
)
|
|
82
|
-
const decode = flow(S.
|
|
81
|
+
const decode = flow(S.decodeEffectConcurrently(schema), provideRctx)
|
|
83
82
|
const decodeMany = flow(
|
|
84
|
-
S.
|
|
83
|
+
S.decodeEffectConcurrently(S.Array(schema)),
|
|
85
84
|
provideRctx
|
|
86
85
|
)
|
|
87
86
|
|
|
@@ -104,7 +103,13 @@ export function makeRepoInternal<
|
|
|
104
103
|
allE,
|
|
105
104
|
(_) => decodeMany(_).pipe(Effect.orDie)
|
|
106
105
|
)
|
|
107
|
-
.pipe(
|
|
106
|
+
.pipe(
|
|
107
|
+
Effect.map((_) => _ as T[]),
|
|
108
|
+
Effect.withSpan("Repository.all", {
|
|
109
|
+
kind: "client",
|
|
110
|
+
attributes: { "app.entity": name }
|
|
111
|
+
}, { captureStackTrace: false })
|
|
112
|
+
)
|
|
108
113
|
|
|
109
114
|
const fieldsSchema = schema as unknown as { fields: any }
|
|
110
115
|
// assumes the id field never needs a service...
|
|
@@ -113,11 +118,14 @@ export function makeRepoInternal<
|
|
|
113
118
|
let ast = _.ast
|
|
114
119
|
if (ast._tag === "Declaration") ast = ast.typeParameters[0]!
|
|
115
120
|
|
|
116
|
-
// In v4, to get the encoded (from) side of a schema, use SchemaAST.toEncoded
|
|
117
121
|
const pickIdFromAst = (a: SchemaAST.AST) => {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
122
|
+
// Unwrap Declaration (e.g. TaggedClass) to get the underlying Objects AST
|
|
123
|
+
let inner = a
|
|
124
|
+
if (inner._tag === "Declaration") inner = inner.typeParameters[0]!
|
|
125
|
+
// Pick from the original AST to preserve the full encoding chain (e.g. decodeTo transformations).
|
|
126
|
+
// Using toEncoded would lose transformation info needed to encode Type -> Encoded.
|
|
127
|
+
if (SchemaAST.isObjects(inner)) {
|
|
128
|
+
const field = inner.propertySignatures.find((_) => _.name === idKey)
|
|
121
129
|
if (field) {
|
|
122
130
|
return S.Struct({ [idKey]: S.make(field.type) }) as unknown as Codec<T, Encoded>
|
|
123
131
|
}
|
|
@@ -138,7 +146,7 @@ export function makeRepoInternal<
|
|
|
138
146
|
Effect.map((_: Record<string, unknown>) => _[idKey as string] as Encoded[IdKey])
|
|
139
147
|
)
|
|
140
148
|
const findEId = Effect.fnUntraced(function*(id: Encoded[IdKey]) {
|
|
141
|
-
yield* Effect.annotateCurrentSpan({
|
|
149
|
+
yield* Effect.annotateCurrentSpan({ "app.entity.id": id })
|
|
142
150
|
|
|
143
151
|
return yield* Effect.flatMap(
|
|
144
152
|
store.find(id),
|
|
@@ -151,7 +159,7 @@ export function makeRepoInternal<
|
|
|
151
159
|
})
|
|
152
160
|
// TODO: select the particular field, instead of as struct
|
|
153
161
|
const findE = Effect.fnUntraced(function*(id: T[IdKey]) {
|
|
154
|
-
yield* Effect.annotateCurrentSpan({
|
|
162
|
+
yield* Effect.annotateCurrentSpan({ "app.entity.id": id })
|
|
155
163
|
|
|
156
164
|
return yield* pipe(
|
|
157
165
|
encodeId({ [idKey]: id } as any),
|
|
@@ -161,9 +169,11 @@ export function makeRepoInternal<
|
|
|
161
169
|
)
|
|
162
170
|
})
|
|
163
171
|
|
|
164
|
-
const find = Effect.fn("find"
|
|
165
|
-
|
|
166
|
-
|
|
172
|
+
const find = Effect.fn("Repository.find", {
|
|
173
|
+
kind: "client",
|
|
174
|
+
attributes: { "app.entity": name }
|
|
175
|
+
})(function*(id: T[IdKey]) {
|
|
176
|
+
yield* Effect.annotateCurrentSpan({ "app.entity.id": id })
|
|
167
177
|
return yield* flatMapOption(findE(id), (_) => Effect.orDie(decode(_)))
|
|
168
178
|
})
|
|
169
179
|
|
|
@@ -188,73 +198,96 @@ export function makeRepoInternal<
|
|
|
188
198
|
Effect.andThen(saveAllE)
|
|
189
199
|
)
|
|
190
200
|
|
|
191
|
-
const saveAndPublish = Effect.fn("saveAndPublish"
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
201
|
+
const saveAndPublish = Effect.fn("Repository.saveAndPublish", { attributes: { "app.entity": name } })(
|
|
202
|
+
function*(items: Iterable<T>, events: Iterable<Evt> = []) {
|
|
203
|
+
const it = Chunk.fromIterable(items)
|
|
204
|
+
const evts = [...events]
|
|
205
|
+
yield* Effect.annotateCurrentSpan({
|
|
206
|
+
"app.entity.ids": Chunk.map(it, (_) => _[idKey]),
|
|
207
|
+
"app.event.count": evts.length
|
|
208
|
+
})
|
|
209
|
+
return yield* saveAll(it)
|
|
210
|
+
.pipe(
|
|
211
|
+
Effect.andThen(Effect.sync(() => toNonEmptyArray(evts))),
|
|
212
|
+
// TODO: for full consistency the events should be stored within the same database transaction, and then picked up.
|
|
213
|
+
(_) => flatMapOption(_, pub),
|
|
214
|
+
Effect.andThen(PubSub.publish(changeFeed, [Chunk.toArray(it), "save"] as [T[], "save" | "remove"])),
|
|
215
|
+
Effect.asVoid
|
|
216
|
+
)
|
|
217
|
+
}
|
|
218
|
+
)
|
|
204
219
|
|
|
205
|
-
const removeAndPublish = Effect.fn("removeAndPublish"
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
)
|
|
216
|
-
|
|
217
|
-
|
|
220
|
+
const removeAndPublish = Effect.fn("Repository.removeAndPublish", { attributes: { "app.entity": name } })(
|
|
221
|
+
function*(a: Iterable<T>, events: Iterable<Evt> = []) {
|
|
222
|
+
const { set } = yield* cms
|
|
223
|
+
const it = [...a]
|
|
224
|
+
const evts = [...events]
|
|
225
|
+
yield* Effect.annotateCurrentSpan({
|
|
226
|
+
"app.entity.ids": it.map((_) => _[idKey]),
|
|
227
|
+
"app.event.count": evts.length
|
|
228
|
+
})
|
|
229
|
+
const items = yield* encodeMany(it).pipe(Effect.orDie)
|
|
230
|
+
if (Array.isReadonlyArrayNonEmpty(items)) {
|
|
231
|
+
yield* store.batchRemove(
|
|
232
|
+
items.map((_) => (_[idKey])),
|
|
233
|
+
args.config?.partitionValue?.(items[0])
|
|
234
|
+
)
|
|
235
|
+
for (const e of items) {
|
|
236
|
+
set(e[idKey], undefined)
|
|
237
|
+
}
|
|
238
|
+
yield* Effect
|
|
239
|
+
.sync(() => toNonEmptyArray(evts))
|
|
240
|
+
// TODO: for full consistency the events should be stored within the same database transaction, and then picked up.
|
|
241
|
+
.pipe((_) => flatMapOption(_, pub))
|
|
242
|
+
|
|
243
|
+
yield* PubSub.publish(changeFeed, [it, "remove"] as [T[], "save" | "remove"])
|
|
218
244
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
// TODO: for full consistency the events should be stored within the same database transaction, and then picked up.
|
|
222
|
-
.pipe((_) => flatMapOption(_, pub))
|
|
245
|
+
}
|
|
246
|
+
)
|
|
223
247
|
|
|
224
|
-
|
|
248
|
+
const removeById = Effect.fn("Repository.removeById", { attributes: { "app.entity": name } })(
|
|
249
|
+
function*(idOrIds: T[IdKey] | ReadonlyArray<T[IdKey]>) {
|
|
250
|
+
const ids = globalThis.Array.isArray(idOrIds)
|
|
251
|
+
? idOrIds as readonly T[IdKey][]
|
|
252
|
+
: [idOrIds as T[IdKey]]
|
|
253
|
+
if (!Array.isReadonlyArrayNonEmpty(ids)) {
|
|
254
|
+
return
|
|
255
|
+
}
|
|
256
|
+
const { set } = yield* cms
|
|
257
|
+
const eids = yield* Effect.forEach(ids, (_) => encodeIdOnly(_ as any)).pipe(Effect.orDie)
|
|
258
|
+
yield* Effect.annotateCurrentSpan({ "app.entity.ids": eids })
|
|
259
|
+
yield* store.batchRemove(eids)
|
|
260
|
+
for (const id of eids) {
|
|
261
|
+
set(id, undefined)
|
|
262
|
+
}
|
|
263
|
+
yield* PubSub.publish(changeFeed, [[], "remove"] as [T[], "save" | "remove"])
|
|
225
264
|
}
|
|
226
|
-
|
|
265
|
+
)
|
|
227
266
|
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
|
|
267
|
+
const parseMany = Effect.fn("parseMany", { attributes: { "app.entity": name } })(
|
|
268
|
+
function*(items: readonly PM[]) {
|
|
269
|
+
const cm = yield* cms
|
|
270
|
+
return yield* decodeMany(items.map((_) => mapReverse(_, cm.set))).pipe(Effect.orDie)
|
|
231
271
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
272
|
+
)
|
|
273
|
+
const decodeManyCache = new WeakMap<
|
|
274
|
+
S.Codec<any, any, any>,
|
|
275
|
+
(i: readonly any[]) => Effect.Effect<any, any, any>
|
|
276
|
+
>()
|
|
277
|
+
const getDecodeMany = (s: S.Codec<any, Encoded, any>) => {
|
|
278
|
+
let dec = decodeManyCache.get(s)
|
|
279
|
+
if (!dec) {
|
|
280
|
+
dec = S.decodeEffectConcurrently(S.Array(s))
|
|
281
|
+
decodeManyCache.set(s, dec)
|
|
238
282
|
}
|
|
239
|
-
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
.
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
const parseMany2 = <A, R>(
|
|
248
|
-
items: readonly PM[],
|
|
249
|
-
schema: S.Codec<A, Encoded, R>
|
|
250
|
-
) =>
|
|
251
|
-
Effect
|
|
252
|
-
.flatMap(cms, (cm) =>
|
|
253
|
-
S
|
|
254
|
-
.decodeEffect(S.Array(schema))(
|
|
255
|
-
items.map((_) => mapReverse(_, cm.set))
|
|
256
|
-
)
|
|
257
|
-
.pipe(Effect.orDie, Effect.withSpan("parseMany2", {}, { captureStackTrace: false })))
|
|
283
|
+
return dec
|
|
284
|
+
}
|
|
285
|
+
const parseMany2 = Effect.fn("parseMany2", { attributes: { "app.entity": name } })(
|
|
286
|
+
function*<A, R>(items: readonly PM[], schema: S.Codec<A, Encoded, R>) {
|
|
287
|
+
const cm = yield* cms
|
|
288
|
+
return yield* getDecodeMany(schema)(items.map((_) => mapReverse(_, cm.set))).pipe(Effect.orDie)
|
|
289
|
+
}
|
|
290
|
+
)
|
|
258
291
|
const filter = <U extends keyof Encoded = keyof Encoded>(args: FilterArgs<Encoded, U>) =>
|
|
259
292
|
store
|
|
260
293
|
.filter(
|
|
@@ -276,24 +309,28 @@ export function makeRepoInternal<
|
|
|
276
309
|
const query: {
|
|
277
310
|
<A, R, From extends FieldValues>(
|
|
278
311
|
q: Q.QueryProjection<Encoded extends From ? From : never, A, R>
|
|
279
|
-
): Effect.Effect<readonly A[], S.SchemaError, R
|
|
312
|
+
): Effect.Effect<readonly A[], S.SchemaError, Exclude<R, RCtx>>
|
|
280
313
|
<A, R, EncodedRefined extends Encoded = Encoded>(
|
|
281
314
|
q: Q.QAll<NoInfer<Encoded>, NoInfer<EncodedRefined>, A, R>
|
|
282
|
-
): Effect.Effect<readonly A[], never, R
|
|
315
|
+
): Effect.Effect<readonly A[], never, Exclude<R, RCtx>>
|
|
283
316
|
} = (<A, R, EncodedRefined extends Encoded = Encoded>(q: Q.QAll<Encoded, EncodedRefined, A, R>) => {
|
|
284
|
-
const a = Q.toFilter(q)
|
|
317
|
+
const a = Q.toFilter(q, schema)
|
|
318
|
+
// Mode dispatch — see `Q.project` JSDoc for the contract:
|
|
319
|
+
// project : decode raw encoded rows with schema; no PM reverse-mapping; SchemaError surfaces.
|
|
320
|
+
// collect : same as project, but schema yields Option and None rows are dropped.
|
|
321
|
+
// transform: PM reverse-map (re-inject _etag/PM state from cms cache) then decode; orDie.
|
|
285
322
|
const eff = a.mode === "project"
|
|
286
323
|
? filter(a)
|
|
287
324
|
// TODO: mapFrom but need to support per field and dependencies
|
|
288
325
|
.pipe(
|
|
289
|
-
Effect.andThen(flow(S.
|
|
326
|
+
Effect.andThen(flow(S.decodeEffectConcurrently(S.Array(a.schema ?? schema)), provideRctx))
|
|
290
327
|
)
|
|
291
328
|
: a.mode === "collect"
|
|
292
329
|
? filter(a)
|
|
293
330
|
// TODO: mapFrom but need to support per field and dependencies
|
|
294
331
|
.pipe(
|
|
295
332
|
Effect.flatMap(flow(
|
|
296
|
-
S.
|
|
333
|
+
S.decodeEffectConcurrently(S.Array(a.schema)),
|
|
297
334
|
Effect.map(Array.getSomes),
|
|
298
335
|
provideRctx
|
|
299
336
|
))
|
|
@@ -325,72 +362,89 @@ export function makeRepoInternal<
|
|
|
325
362
|
.map(eff, (_) => NonNegativeInt(_.length))
|
|
326
363
|
.pipe(Effect.catchTag("SchemaError", (e) => Effect.die(e)))
|
|
327
364
|
: eff,
|
|
328
|
-
Effect.
|
|
329
|
-
|
|
330
|
-
"
|
|
331
|
-
query
|
|
332
|
-
|
|
365
|
+
Effect.tap((r) =>
|
|
366
|
+
Effect.annotateCurrentSpan({
|
|
367
|
+
"app.query.ttype": a.ttype,
|
|
368
|
+
"app.query.mode": a.mode,
|
|
369
|
+
"db.response.returned_rows": Array.isArray(r) ? r.length : 1
|
|
370
|
+
})
|
|
371
|
+
),
|
|
372
|
+
Effect.withSpan("Repository.query", {
|
|
373
|
+
kind: "client",
|
|
374
|
+
attributes: { "app.entity": name }
|
|
333
375
|
}, { captureStackTrace: false })
|
|
334
376
|
)
|
|
335
377
|
}) as any
|
|
336
378
|
|
|
337
|
-
const validateSample = Effect.fn("validateSample")(
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
const
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
379
|
+
const validateSample = Effect.fn("Repository.validateSample", { attributes: { "app.entity": name } })(
|
|
380
|
+
function*(options?: {
|
|
381
|
+
percentage?: number
|
|
382
|
+
maxItems?: number
|
|
383
|
+
}) {
|
|
384
|
+
const percentage = options?.percentage ?? 0.1 // default 10%
|
|
385
|
+
const maxItems = options?.maxItems
|
|
386
|
+
|
|
387
|
+
// 1. get all IDs with projection (bypasses main schema decode)
|
|
388
|
+
const allIds = yield* store
|
|
389
|
+
.filter({
|
|
390
|
+
t: null as unknown as Encoded,
|
|
391
|
+
select: [idKey as keyof Encoded]
|
|
392
|
+
})
|
|
393
|
+
.pipe(Effect.withSpan("Repository.filter", {
|
|
394
|
+
kind: "client",
|
|
395
|
+
attributes: { "app.entity": name }
|
|
396
|
+
}, { captureStackTrace: false }))
|
|
397
|
+
|
|
398
|
+
// 2. random subset
|
|
399
|
+
const shuffled = [...allIds].sort(() => Math.random() - 0.5)
|
|
400
|
+
const sampleSize = Math.min(
|
|
401
|
+
maxItems ?? Infinity,
|
|
402
|
+
Math.ceil(allIds.length * percentage)
|
|
403
|
+
)
|
|
404
|
+
const sample = shuffled.slice(0, sampleSize)
|
|
405
|
+
|
|
406
|
+
// 3. validate each item
|
|
407
|
+
const errors: ValidationError[] = []
|
|
408
|
+
|
|
409
|
+
for (const item of sample) {
|
|
410
|
+
const id = item[idKey]
|
|
411
|
+
const rawResult = yield* store.find(id).pipe(
|
|
412
|
+
Effect.withSpan("Repository.find", {
|
|
413
|
+
kind: "client",
|
|
414
|
+
attributes: { "app.entity": name, "app.entity.id": id }
|
|
415
|
+
}, { captureStackTrace: false })
|
|
416
|
+
)
|
|
366
417
|
|
|
367
|
-
|
|
368
|
-
const jitMResult = mapFrom(rawData) // apply jitM
|
|
418
|
+
if (Option.isNone(rawResult)) continue
|
|
369
419
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
provideRctx
|
|
373
|
-
)
|
|
420
|
+
const rawData = rawResult.value as Encoded
|
|
421
|
+
const jitMResult = mapFrom(rawData) // apply jitM
|
|
374
422
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
id,
|
|
379
|
-
rawData,
|
|
380
|
-
jitMResult,
|
|
381
|
-
error: decodeResult.failure
|
|
382
|
-
})
|
|
423
|
+
const decodeResult = yield* S.decodeEffectConcurrently(schema)(jitMResult).pipe(
|
|
424
|
+
Effect.result,
|
|
425
|
+
provideRctx
|
|
383
426
|
)
|
|
427
|
+
|
|
428
|
+
if (Result.isFailure(decodeResult)) {
|
|
429
|
+
errors.push(
|
|
430
|
+
ValidationError.make({
|
|
431
|
+
id,
|
|
432
|
+
rawData,
|
|
433
|
+
jitMResult,
|
|
434
|
+
error: decodeResult.failure
|
|
435
|
+
})
|
|
436
|
+
)
|
|
437
|
+
}
|
|
384
438
|
}
|
|
385
|
-
}
|
|
386
439
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
440
|
+
return ValidationResult.make({
|
|
441
|
+
total: NonNegativeInt(allIds.length),
|
|
442
|
+
sampled: NonNegativeInt(sample.length),
|
|
443
|
+
valid: NonNegativeInt(sample.length - errors.length),
|
|
444
|
+
errors
|
|
445
|
+
})
|
|
446
|
+
}
|
|
447
|
+
)
|
|
394
448
|
|
|
395
449
|
const r = {
|
|
396
450
|
changeFeed,
|
|
@@ -401,10 +455,17 @@ export function makeRepoInternal<
|
|
|
401
455
|
saveAndPublish,
|
|
402
456
|
removeAndPublish,
|
|
403
457
|
removeById,
|
|
458
|
+
seedNamespace: (namespace: string) => store.seedNamespace(namespace),
|
|
404
459
|
validateSample,
|
|
405
460
|
queryRaw<A, Out, QR>(schema: S.Codec<A, Out, QR>, q: Q.RawQuery<Encoded, Out>) {
|
|
406
|
-
const dec = S.
|
|
407
|
-
return store.queryRaw(q).pipe(
|
|
461
|
+
const dec = S.decodeEffectConcurrently(S.Array(schema))
|
|
462
|
+
return store.queryRaw(q).pipe(
|
|
463
|
+
Effect.flatMap(dec),
|
|
464
|
+
Effect.withSpan("Repository.queryRaw", {
|
|
465
|
+
kind: "client",
|
|
466
|
+
attributes: { "app.entity": name }
|
|
467
|
+
}, { captureStackTrace: false })
|
|
468
|
+
)
|
|
408
469
|
},
|
|
409
470
|
query(q: any) {
|
|
410
471
|
// eslint-disable-next-line prefer-rest-params
|
|
@@ -414,15 +475,23 @@ export function makeRepoInternal<
|
|
|
414
475
|
* @internal
|
|
415
476
|
*/
|
|
416
477
|
mapped: <A, R>(schema: S.Codec<A, any, R>) => {
|
|
417
|
-
const dec = S.
|
|
478
|
+
const dec = S.decodeEffectConcurrently(schema)
|
|
418
479
|
const encMany = S.encodeEffect(S.Array(schema))
|
|
419
|
-
const decMany = S.
|
|
480
|
+
const decMany = S.decodeEffectConcurrently(S.Array(schema))
|
|
481
|
+
const spanAttrs = { kind: "client" as const, attributes: { "app.entity": name } }
|
|
420
482
|
return {
|
|
421
483
|
all: allE.pipe(
|
|
422
484
|
Effect.flatMap(decMany),
|
|
423
|
-
Effect.map((_) => _ as any[])
|
|
485
|
+
Effect.map((_) => _ as any[]),
|
|
486
|
+
Effect.withSpan("Repository.mapped.all", spanAttrs, { captureStackTrace: false })
|
|
424
487
|
),
|
|
425
|
-
find: (id: T[IdKey]) =>
|
|
488
|
+
find: (id: T[IdKey]) =>
|
|
489
|
+
flatMapOption(findE(id), dec).pipe(
|
|
490
|
+
Effect.withSpan("Repository.mapped.find", {
|
|
491
|
+
...spanAttrs,
|
|
492
|
+
attributes: { ...spanAttrs.attributes, "app.entity.id": id }
|
|
493
|
+
}, { captureStackTrace: false })
|
|
494
|
+
),
|
|
426
495
|
// query: (q: any) => {
|
|
427
496
|
// const a = Q.toFilter(q)
|
|
428
497
|
|
|
@@ -441,12 +510,12 @@ export function makeRepoInternal<
|
|
|
441
510
|
// },
|
|
442
511
|
save: (...xes: any[]) =>
|
|
443
512
|
Effect.flatMap(encMany(xes), (_) => saveAllE(_)).pipe(
|
|
444
|
-
Effect.withSpan("mapped.save",
|
|
513
|
+
Effect.withSpan("Repository.mapped.save", spanAttrs, { captureStackTrace: false })
|
|
445
514
|
)
|
|
446
515
|
}
|
|
447
516
|
}
|
|
448
517
|
}
|
|
449
|
-
return r as Repository<T, Encoded, Evt, ItemType, IdKey, Exclude<R, RCtx>, RPublish>
|
|
518
|
+
return r as Repository<T, Encoded, Evt, ItemType, IdKey, Exclude<R, RCtx>, RPublish, RCtx>
|
|
450
519
|
})
|
|
451
520
|
.pipe(Effect
|
|
452
521
|
// .withSpan("Repository.make [effect-app/infra]", { attributes: { "repository.model_name": name } })
|
|
@@ -513,7 +582,7 @@ export function makeStore<Encoded extends FieldValues>() {
|
|
|
513
582
|
.pipe(
|
|
514
583
|
Effect.flatMap(Effect.forEach(encodeToEncoded())),
|
|
515
584
|
setupRequestContextFromCurrent("Repository.makeInitial [effect-app/infra]", {
|
|
516
|
-
attributes: { "
|
|
585
|
+
attributes: { "app.entity": name }
|
|
517
586
|
})
|
|
518
587
|
)
|
|
519
588
|
: undefined,
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
6
6
|
|
|
7
7
|
// import type { ParserEnv } from "effect-app/Schema/custom/Parser"
|
|
8
|
-
|
|
9
|
-
import type
|
|
10
|
-
import { Effect, type NonEmptyReadonlyArray, type S, type ServiceMap } from "effect-app"
|
|
8
|
+
|
|
9
|
+
import { type Context, Effect, type NonEmptyReadonlyArray, type S } from "effect-app"
|
|
11
10
|
import type { StoreConfig, StoreMaker } from "../../Store.js"
|
|
12
11
|
import type { FieldValues } from "../filter/types.js"
|
|
13
12
|
import { type ExtendedRepository, extendRepo } from "./ext.js"
|
|
14
13
|
import { makeRepoInternal } from "./internal/internal.js"
|
|
14
|
+
import { RepositoryRegistry } from "./Registry.js"
|
|
15
15
|
import type { Repository } from "./service.js"
|
|
16
16
|
|
|
17
17
|
export interface RepositoryOptions<
|
|
@@ -52,11 +52,11 @@ export interface RepositoryOptions<
|
|
|
52
52
|
* Optional context to be provided to Schema decode/encode.
|
|
53
53
|
* Useful for effectful transformations like XWithItems, where items is a transformation retrieving elements from another database table or other source.
|
|
54
54
|
*/
|
|
55
|
-
schemaContext?:
|
|
55
|
+
schemaContext?: Context.Context<RCtx>
|
|
56
56
|
|
|
57
57
|
overrides?: (
|
|
58
|
-
repo: Repository<T, Encoded, Evt, ItemType, IdKey, Exclude<RSchema, RCtx>, RPublish>
|
|
59
|
-
) => Repository<T, Encoded, Evt, ItemType, IdKey, Exclude<RSchema, RCtx>, RPublish>
|
|
58
|
+
repo: Repository<T, Encoded, Evt, ItemType, IdKey, Exclude<RSchema, RCtx>, RPublish, RCtx>
|
|
59
|
+
) => Repository<T, Encoded, Evt, ItemType, IdKey, Exclude<RSchema, RCtx>, RPublish, RCtx>
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
/**
|
|
@@ -83,9 +83,9 @@ export const makeRepo: {
|
|
|
83
83
|
schema: S.Codec<T, Encoded, RSchema>,
|
|
84
84
|
options: RepositoryOptions<IdKey, Encoded, T, ItemType, Evt, RPublish, E, RInitial, RCtx, RSchema>
|
|
85
85
|
): Effect.Effect<
|
|
86
|
-
ExtendedRepository<T, Encoded, Evt, ItemType, IdKey, Exclude<RSchema, RCtx>, RPublish>,
|
|
86
|
+
ExtendedRepository<T, Encoded, Evt, ItemType, IdKey, Exclude<RSchema, RCtx>, RPublish, RCtx>,
|
|
87
87
|
E,
|
|
88
|
-
RInitial | StoreMaker
|
|
88
|
+
RInitial | StoreMaker | RepositoryRegistry
|
|
89
89
|
>
|
|
90
90
|
<
|
|
91
91
|
ItemType extends string,
|
|
@@ -102,9 +102,9 @@ export const makeRepo: {
|
|
|
102
102
|
schema: S.Codec<T, Encoded, RSchema>,
|
|
103
103
|
options: Omit<RepositoryOptions<"id", Encoded, T, ItemType, Evt, RPublish, E, RInitial, RCtx, RSchema>, "idKey">
|
|
104
104
|
): Effect.Effect<
|
|
105
|
-
ExtendedRepository<T, Encoded, Evt, ItemType, "id", Exclude<RSchema, RCtx>, RPublish>,
|
|
105
|
+
ExtendedRepository<T, Encoded, Evt, ItemType, "id", Exclude<RSchema, RCtx>, RPublish, RCtx>,
|
|
106
106
|
E,
|
|
107
|
-
RInitial | StoreMaker
|
|
107
|
+
RInitial | StoreMaker | RepositoryRegistry
|
|
108
108
|
>
|
|
109
109
|
} = <
|
|
110
110
|
ItemType extends string,
|
|
@@ -135,5 +135,7 @@ export const makeRepo: {
|
|
|
135
135
|
let r = yield* mkRepo.make<RInitial, E, RPublish, RCtx>(options as any)
|
|
136
136
|
if (options.overrides) r = options.overrides(r)
|
|
137
137
|
const repo = extendRepo(r)
|
|
138
|
+
const registry = yield* RepositoryRegistry
|
|
139
|
+
registry.register(itemType, repo)
|
|
138
140
|
return repo
|
|
139
141
|
})
|