@effect-app/infra 4.0.0-beta.21 → 4.0.0-beta.211
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 +1556 -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 +98 -50
- 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 +16 -16
- package/dist/Model/query/dsl.d.ts.map +1 -1
- package/dist/Model/query/new-kid-interpreter.d.ts +6 -6
- package/dist/Model/query/new-kid-interpreter.d.ts.map +1 -1
- package/dist/Model/query/new-kid-interpreter.js +3 -3
- 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 +1 -1
- package/dist/Store/Cosmos/query.d.ts.map +1 -1
- package/dist/Store/Cosmos/query.js +10 -12
- 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 +90 -57
- 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 +38 -0
- package/dist/Store/SQL/query.d.ts.map +1 -0
- package/dist/Store/SQL/query.js +367 -0
- package/dist/Store/SQL.d.ts +20 -0
- package/dist/Store/SQL.d.ts.map +1 -0
- package/dist/Store/SQL.js +464 -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 +18 -7
- 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 +2 -2
- 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 +2 -2
- 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 +112 -40
- 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 +39 -35
- package/package.json +45 -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 +213 -148
- 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 +18 -18
- package/src/Model/query/new-kid-interpreter.ts +2 -2
- 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 +16 -20
- package/src/Store/Cosmos.ts +473 -348
- package/src/Store/Disk.ts +102 -65
- package/src/Store/Memory.ts +118 -83
- package/src/Store/SQL/Pg.ts +352 -0
- package/src/Store/SQL/query.ts +409 -0
- package/src/Store/SQL.ts +734 -0
- package/src/Store/codeFilter.ts +3 -1
- package/src/Store/index.ts +17 -2
- package/src/Store/service.ts +32 -8
- 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 +1 -1
- 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 +298 -128
- 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 +216 -34
- package/test/rawQuery.test.ts +23 -19
- 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 +1064 -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,24 @@ 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
317
|
const a = Q.toFilter(q)
|
|
285
318
|
const eff = a.mode === "project"
|
|
286
319
|
? filter(a)
|
|
287
320
|
// TODO: mapFrom but need to support per field and dependencies
|
|
288
321
|
.pipe(
|
|
289
|
-
Effect.andThen(flow(S.
|
|
322
|
+
Effect.andThen(flow(S.decodeEffectConcurrently(S.Array(a.schema ?? schema)), provideRctx))
|
|
290
323
|
)
|
|
291
324
|
: a.mode === "collect"
|
|
292
325
|
? filter(a)
|
|
293
326
|
// TODO: mapFrom but need to support per field and dependencies
|
|
294
327
|
.pipe(
|
|
295
328
|
Effect.flatMap(flow(
|
|
296
|
-
S.
|
|
329
|
+
S.decodeEffectConcurrently(S.Array(a.schema)),
|
|
297
330
|
Effect.map(Array.getSomes),
|
|
298
331
|
provideRctx
|
|
299
332
|
))
|
|
@@ -325,72 +358,89 @@ export function makeRepoInternal<
|
|
|
325
358
|
.map(eff, (_) => NonNegativeInt(_.length))
|
|
326
359
|
.pipe(Effect.catchTag("SchemaError", (e) => Effect.die(e)))
|
|
327
360
|
: eff,
|
|
328
|
-
Effect.
|
|
329
|
-
|
|
330
|
-
"
|
|
331
|
-
query
|
|
332
|
-
|
|
361
|
+
Effect.tap((r) =>
|
|
362
|
+
Effect.annotateCurrentSpan({
|
|
363
|
+
"app.query.ttype": a.ttype,
|
|
364
|
+
"app.query.mode": a.mode,
|
|
365
|
+
"db.response.returned_rows": Array.isArray(r) ? r.length : 1
|
|
366
|
+
})
|
|
367
|
+
),
|
|
368
|
+
Effect.withSpan("Repository.query", {
|
|
369
|
+
kind: "client",
|
|
370
|
+
attributes: { "app.entity": name }
|
|
333
371
|
}, { captureStackTrace: false })
|
|
334
372
|
)
|
|
335
373
|
}) as any
|
|
336
374
|
|
|
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
|
-
|
|
375
|
+
const validateSample = Effect.fn("Repository.validateSample", { attributes: { "app.entity": name } })(
|
|
376
|
+
function*(options?: {
|
|
377
|
+
percentage?: number
|
|
378
|
+
maxItems?: number
|
|
379
|
+
}) {
|
|
380
|
+
const percentage = options?.percentage ?? 0.1 // default 10%
|
|
381
|
+
const maxItems = options?.maxItems
|
|
382
|
+
|
|
383
|
+
// 1. get all IDs with projection (bypasses main schema decode)
|
|
384
|
+
const allIds = yield* store
|
|
385
|
+
.filter({
|
|
386
|
+
t: null as unknown as Encoded,
|
|
387
|
+
select: [idKey as keyof Encoded]
|
|
388
|
+
})
|
|
389
|
+
.pipe(Effect.withSpan("Repository.filter", {
|
|
390
|
+
kind: "client",
|
|
391
|
+
attributes: { "app.entity": name }
|
|
392
|
+
}, { captureStackTrace: false }))
|
|
393
|
+
|
|
394
|
+
// 2. random subset
|
|
395
|
+
const shuffled = [...allIds].sort(() => Math.random() - 0.5)
|
|
396
|
+
const sampleSize = Math.min(
|
|
397
|
+
maxItems ?? Infinity,
|
|
398
|
+
Math.ceil(allIds.length * percentage)
|
|
399
|
+
)
|
|
400
|
+
const sample = shuffled.slice(0, sampleSize)
|
|
401
|
+
|
|
402
|
+
// 3. validate each item
|
|
403
|
+
const errors: ValidationError[] = []
|
|
404
|
+
|
|
405
|
+
for (const item of sample) {
|
|
406
|
+
const id = item[idKey]
|
|
407
|
+
const rawResult = yield* store.find(id).pipe(
|
|
408
|
+
Effect.withSpan("Repository.find", {
|
|
409
|
+
kind: "client",
|
|
410
|
+
attributes: { "app.entity": name, "app.entity.id": id }
|
|
411
|
+
}, { captureStackTrace: false })
|
|
412
|
+
)
|
|
366
413
|
|
|
367
|
-
|
|
368
|
-
const jitMResult = mapFrom(rawData) // apply jitM
|
|
414
|
+
if (Option.isNone(rawResult)) continue
|
|
369
415
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
provideRctx
|
|
373
|
-
)
|
|
416
|
+
const rawData = rawResult.value as Encoded
|
|
417
|
+
const jitMResult = mapFrom(rawData) // apply jitM
|
|
374
418
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
id,
|
|
379
|
-
rawData,
|
|
380
|
-
jitMResult,
|
|
381
|
-
error: decodeResult.failure
|
|
382
|
-
})
|
|
419
|
+
const decodeResult = yield* S.decodeEffectConcurrently(schema)(jitMResult).pipe(
|
|
420
|
+
Effect.result,
|
|
421
|
+
provideRctx
|
|
383
422
|
)
|
|
423
|
+
|
|
424
|
+
if (Result.isFailure(decodeResult)) {
|
|
425
|
+
errors.push(
|
|
426
|
+
ValidationError.make({
|
|
427
|
+
id,
|
|
428
|
+
rawData,
|
|
429
|
+
jitMResult,
|
|
430
|
+
error: decodeResult.failure
|
|
431
|
+
})
|
|
432
|
+
)
|
|
433
|
+
}
|
|
384
434
|
}
|
|
385
|
-
}
|
|
386
435
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
436
|
+
return ValidationResult.make({
|
|
437
|
+
total: NonNegativeInt(allIds.length),
|
|
438
|
+
sampled: NonNegativeInt(sample.length),
|
|
439
|
+
valid: NonNegativeInt(sample.length - errors.length),
|
|
440
|
+
errors
|
|
441
|
+
})
|
|
442
|
+
}
|
|
443
|
+
)
|
|
394
444
|
|
|
395
445
|
const r = {
|
|
396
446
|
changeFeed,
|
|
@@ -401,10 +451,17 @@ export function makeRepoInternal<
|
|
|
401
451
|
saveAndPublish,
|
|
402
452
|
removeAndPublish,
|
|
403
453
|
removeById,
|
|
454
|
+
seedNamespace: (namespace: string) => store.seedNamespace(namespace),
|
|
404
455
|
validateSample,
|
|
405
456
|
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(
|
|
457
|
+
const dec = S.decodeEffectConcurrently(S.Array(schema))
|
|
458
|
+
return store.queryRaw(q).pipe(
|
|
459
|
+
Effect.flatMap(dec),
|
|
460
|
+
Effect.withSpan("Repository.queryRaw", {
|
|
461
|
+
kind: "client",
|
|
462
|
+
attributes: { "app.entity": name }
|
|
463
|
+
}, { captureStackTrace: false })
|
|
464
|
+
)
|
|
408
465
|
},
|
|
409
466
|
query(q: any) {
|
|
410
467
|
// eslint-disable-next-line prefer-rest-params
|
|
@@ -414,15 +471,23 @@ export function makeRepoInternal<
|
|
|
414
471
|
* @internal
|
|
415
472
|
*/
|
|
416
473
|
mapped: <A, R>(schema: S.Codec<A, any, R>) => {
|
|
417
|
-
const dec = S.
|
|
474
|
+
const dec = S.decodeEffectConcurrently(schema)
|
|
418
475
|
const encMany = S.encodeEffect(S.Array(schema))
|
|
419
|
-
const decMany = S.
|
|
476
|
+
const decMany = S.decodeEffectConcurrently(S.Array(schema))
|
|
477
|
+
const spanAttrs = { kind: "client" as const, attributes: { "app.entity": name } }
|
|
420
478
|
return {
|
|
421
479
|
all: allE.pipe(
|
|
422
480
|
Effect.flatMap(decMany),
|
|
423
|
-
Effect.map((_) => _ as any[])
|
|
481
|
+
Effect.map((_) => _ as any[]),
|
|
482
|
+
Effect.withSpan("Repository.mapped.all", spanAttrs, { captureStackTrace: false })
|
|
424
483
|
),
|
|
425
|
-
find: (id: T[IdKey]) =>
|
|
484
|
+
find: (id: T[IdKey]) =>
|
|
485
|
+
flatMapOption(findE(id), dec).pipe(
|
|
486
|
+
Effect.withSpan("Repository.mapped.find", {
|
|
487
|
+
...spanAttrs,
|
|
488
|
+
attributes: { ...spanAttrs.attributes, "app.entity.id": id }
|
|
489
|
+
}, { captureStackTrace: false })
|
|
490
|
+
),
|
|
426
491
|
// query: (q: any) => {
|
|
427
492
|
// const a = Q.toFilter(q)
|
|
428
493
|
|
|
@@ -441,12 +506,12 @@ export function makeRepoInternal<
|
|
|
441
506
|
// },
|
|
442
507
|
save: (...xes: any[]) =>
|
|
443
508
|
Effect.flatMap(encMany(xes), (_) => saveAllE(_)).pipe(
|
|
444
|
-
Effect.withSpan("mapped.save",
|
|
509
|
+
Effect.withSpan("Repository.mapped.save", spanAttrs, { captureStackTrace: false })
|
|
445
510
|
)
|
|
446
511
|
}
|
|
447
512
|
}
|
|
448
513
|
}
|
|
449
|
-
return r as Repository<T, Encoded, Evt, ItemType, IdKey, Exclude<R, RCtx>, RPublish>
|
|
514
|
+
return r as Repository<T, Encoded, Evt, ItemType, IdKey, Exclude<R, RCtx>, RPublish, RCtx>
|
|
450
515
|
})
|
|
451
516
|
.pipe(Effect
|
|
452
517
|
// .withSpan("Repository.make [effect-app/infra]", { attributes: { "repository.model_name": name } })
|
|
@@ -513,7 +578,7 @@ export function makeStore<Encoded extends FieldValues>() {
|
|
|
513
578
|
.pipe(
|
|
514
579
|
Effect.flatMap(Effect.forEach(encodeToEncoded())),
|
|
515
580
|
setupRequestContextFromCurrent("Repository.makeInitial [effect-app/infra]", {
|
|
516
|
-
attributes: { "
|
|
581
|
+
attributes: { "app.entity": name }
|
|
517
582
|
})
|
|
518
583
|
)
|
|
519
584
|
: 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
|
})
|