@effect-app/infra 2.3.5 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/_cjs/services/OperationsRepo.cjs +10 -1
- package/_cjs/services/OperationsRepo.cjs.map +1 -1
- package/_cjs/services/Repository/dsl.cjs.map +1 -1
- package/_cjs/services/Repository/ext.cjs +58 -104
- package/_cjs/services/Repository/ext.cjs.map +1 -1
- package/_cjs/services/Repository/legacy.cjs +108 -0
- package/_cjs/services/Repository/legacy.cjs.map +1 -0
- package/_cjs/services/Repository.cjs +11 -0
- package/_cjs/services/Repository.cjs.map +1 -1
- package/_cjs/services/RepositoryBase.cjs +4 -222
- package/_cjs/services/RepositoryBase.cjs.map +1 -1
- package/dist/services/Operations.d.ts +3 -3
- package/dist/services/OperationsRepo.d.ts +4 -1
- package/dist/services/OperationsRepo.d.ts.map +1 -1
- package/dist/services/OperationsRepo.js +12 -3
- package/dist/services/QueueMaker/errors.d.ts +1 -1
- package/dist/services/QueueMaker/errors.d.ts.map +1 -1
- package/dist/services/Repository/dsl.d.ts.map +1 -1
- package/dist/services/Repository/dsl.js +1 -1
- package/dist/services/Repository/ext.d.ts +43 -104
- package/dist/services/Repository/ext.d.ts.map +1 -1
- package/dist/services/Repository/ext.js +59 -93
- package/dist/services/Repository/legacy.d.ts +139 -0
- package/dist/services/Repository/legacy.d.ts.map +1 -0
- package/dist/services/Repository/legacy.js +99 -0
- package/dist/services/Repository/service.d.ts +21 -2
- package/dist/services/Repository/service.d.ts.map +1 -1
- package/dist/services/Repository.d.ts +1 -0
- package/dist/services/Repository.d.ts.map +1 -1
- package/dist/services/Repository.js +2 -1
- package/dist/services/RepositoryBase.d.ts +7 -237
- package/dist/services/RepositoryBase.d.ts.map +1 -1
- package/dist/services/RepositoryBase.js +5 -200
- package/dist/services/query/new-kid-interpreter.d.ts +1 -1
- package/examples/query.ts +3 -2
- package/package.json +11 -1
- package/src/services/OperationsRepo.ts +13 -4
- package/src/services/Repository/dsl.ts +1 -0
- package/src/services/Repository/ext.ts +269 -250
- package/src/services/Repository/legacy.ts +351 -0
- package/src/services/Repository/service.ts +44 -2
- package/src/services/Repository.ts +1 -0
- package/src/services/RepositoryBase.ts +12 -931
- package/test/query.test.ts +10 -8
|
@@ -5,325 +5,27 @@
|
|
|
5
5
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
6
6
|
|
|
7
7
|
// import type { ParserEnv } from "effect-app/Schema/custom/Parser"
|
|
8
|
-
import {
|
|
9
|
-
AnyPureDSL,
|
|
10
|
-
byIdAndSaveWithPure,
|
|
11
|
-
get,
|
|
12
|
-
type Repository,
|
|
13
|
-
saveAllWithEffectInt,
|
|
14
|
-
saveManyWithPure_,
|
|
15
|
-
saveManyWithPureBatched_,
|
|
16
|
-
saveWithPure_
|
|
17
|
-
} from "./Repository.js"
|
|
8
|
+
import { type Repository } from "./Repository.js"
|
|
18
9
|
import { StoreMaker } from "./Store.js"
|
|
19
10
|
import type { FilterArgs, PersistenceModelType, StoreConfig } from "./Store.js"
|
|
20
11
|
import type {} from "effect/Equal"
|
|
21
12
|
import type {} from "effect/Hash"
|
|
22
|
-
import type {
|
|
23
|
-
import {
|
|
24
|
-
Array,
|
|
25
|
-
Chunk,
|
|
26
|
-
Context,
|
|
27
|
-
Effect,
|
|
28
|
-
Equivalence,
|
|
29
|
-
Exit,
|
|
30
|
-
flow,
|
|
31
|
-
Layer,
|
|
32
|
-
Option,
|
|
33
|
-
pipe,
|
|
34
|
-
PubSub,
|
|
35
|
-
Request,
|
|
36
|
-
RequestResolver,
|
|
37
|
-
S,
|
|
38
|
-
Unify
|
|
39
|
-
} from "effect-app"
|
|
13
|
+
import type { NonEmptyReadonlyArray } from "effect-app"
|
|
14
|
+
import { Array, Chunk, Effect, Equivalence, flow, Option, pipe, PubSub, S, Unify } from "effect-app"
|
|
40
15
|
import { toNonEmptyArray } from "effect-app/Array"
|
|
41
16
|
import { flatMapOption } from "effect-app/Effect"
|
|
42
|
-
import {
|
|
43
|
-
import type { FixEnv, PureEnv } from "effect-app/Pure"
|
|
44
|
-
import type { ParseResult, Schema } from "effect-app/Schema"
|
|
17
|
+
import type { Schema } from "effect-app/Schema"
|
|
45
18
|
import { NonNegativeInt } from "effect-app/Schema"
|
|
46
19
|
import { setupRequestContextFromCurrent } from "../api/setupRequest.js"
|
|
47
|
-
import {
|
|
20
|
+
import { NotFoundError } from "../errors.js"
|
|
48
21
|
import type { FieldValues } from "../filter/types.js"
|
|
49
22
|
import { make as makeQuery } from "./query.js"
|
|
50
|
-
import type { QAll,
|
|
23
|
+
import type { QAll, QueryProjection } from "./query.js"
|
|
51
24
|
import * as Q from "./query.js"
|
|
25
|
+
import { extendRepo } from "./Repository/ext.js"
|
|
26
|
+
import type { ExtendedRepository } from "./Repository/ext.js"
|
|
52
27
|
import { getContextMap } from "./Store/ContextMapContainer.js"
|
|
53
28
|
|
|
54
|
-
export interface Mapped1<A, IdKey extends keyof A, R> {
|
|
55
|
-
all: Effect<A[], ParseResult.ParseError, R>
|
|
56
|
-
save: (...xes: readonly A[]) => Effect<void, OptimisticConcurrencyException | ParseResult.ParseError, R>
|
|
57
|
-
find: (id: A[IdKey]) => Effect<Option<A>, ParseResult.ParseError, R>
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// TODO: auto use project, and select fields from the From side of schema only
|
|
61
|
-
export interface Mapped2<A, R> {
|
|
62
|
-
all: Effect<A[], ParseResult.ParseError, R>
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export interface Mapped<Encoded extends { id: string }> {
|
|
66
|
-
<A, R, IdKey extends keyof A>(schema: S.Schema<A, Encoded, R>): Mapped1<A, IdKey, R>
|
|
67
|
-
// TODO: constrain on Encoded2 having to contain only fields that fit Encoded
|
|
68
|
-
<A, Encoded2, R>(schema: S.Schema<A, Encoded2, R>): Mapped2<A, R>
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export interface MM<Repo, Encoded extends { id: string }> {
|
|
72
|
-
<A, R, IdKey extends keyof A>(schema: S.Schema<A, Encoded, R>): Effect<Mapped1<A, IdKey, R>, never, Repo>
|
|
73
|
-
// TODO: constrain on Encoded2 having to contain only fields that fit Encoded
|
|
74
|
-
<A, Encoded2, R>(schema: S.Schema<A, Encoded2, R>): Effect<Mapped2<A, R>, never, Repo>
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* @tsplus type Repository
|
|
79
|
-
*/
|
|
80
|
-
export abstract class RepositoryBaseC<
|
|
81
|
-
T,
|
|
82
|
-
Encoded extends { id: string },
|
|
83
|
-
Evt,
|
|
84
|
-
ItemType extends string,
|
|
85
|
-
IdKey extends keyof T
|
|
86
|
-
> {
|
|
87
|
-
abstract readonly itemType: ItemType
|
|
88
|
-
abstract readonly find: (id: T[IdKey]) => Effect<Option<T>>
|
|
89
|
-
abstract readonly all: Effect<T[]>
|
|
90
|
-
abstract readonly saveAndPublish: (
|
|
91
|
-
items: Iterable<T>,
|
|
92
|
-
events?: Iterable<Evt>
|
|
93
|
-
) => Effect<void, InvalidStateError | OptimisticConcurrencyException>
|
|
94
|
-
abstract readonly changeFeed: PubSub.PubSub<[T[], "save" | "remove"]>
|
|
95
|
-
abstract readonly removeAndPublish: (
|
|
96
|
-
items: Iterable<T>,
|
|
97
|
-
events?: Iterable<Evt>
|
|
98
|
-
) => Effect<void>
|
|
99
|
-
|
|
100
|
-
abstract readonly query: {
|
|
101
|
-
<A, R, Encoded2 extends FieldValues, TType extends "one" | "many" | "count" = "many">(
|
|
102
|
-
q: (
|
|
103
|
-
initial: Query<Encoded>
|
|
104
|
-
) => QueryProjection<Encoded extends Encoded2 ? Encoded2 : never, A, R, TType>
|
|
105
|
-
): Effect.Effect<
|
|
106
|
-
TType extends "many" ? readonly A[] : TType extends "count" ? NonNegativeInt : A,
|
|
107
|
-
| (TType extends "many" ? never : NotFoundError<ItemType>)
|
|
108
|
-
| (TType extends "count" ? never : S.ParseResult.ParseError),
|
|
109
|
-
R
|
|
110
|
-
>
|
|
111
|
-
<R = never, TType extends "one" | "many" = "many">(
|
|
112
|
-
q: (initial: Query<Encoded>) => QAll<Encoded, T, R, TType>
|
|
113
|
-
): Effect.Effect<TType extends "many" ? readonly T[] : T, TType extends "many" ? never : NotFoundError<ItemType>, R>
|
|
114
|
-
// <R = never>(q: QAll<Encoded, T, R>): Effect.Effect<readonly T[], never, R>
|
|
115
|
-
// <A, R, Encoded2 extends FieldValues>(
|
|
116
|
-
// q: QueryProjection<Encoded extends Encoded2 ? Encoded2 : never, A, R>
|
|
117
|
-
// ): Effect.Effect<readonly A[], S.ParseResult.ParseError, R>
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/** @deprecated use query */
|
|
121
|
-
abstract readonly mapped: Mapped<Encoded>
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
export abstract class RepositoryBaseC1<
|
|
125
|
-
T,
|
|
126
|
-
Encoded extends { id: string },
|
|
127
|
-
Evt,
|
|
128
|
-
ItemType extends string,
|
|
129
|
-
IdKey extends keyof T
|
|
130
|
-
> extends RepositoryBaseC<T, Encoded, Evt, ItemType, IdKey> {
|
|
131
|
-
constructor(
|
|
132
|
-
public readonly itemType: ItemType
|
|
133
|
-
) {
|
|
134
|
-
super()
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
export class RepositoryBaseC2<
|
|
139
|
-
T,
|
|
140
|
-
Encoded extends { id: string },
|
|
141
|
-
Evt,
|
|
142
|
-
ItemType extends string,
|
|
143
|
-
Ext,
|
|
144
|
-
IdKey extends keyof T
|
|
145
|
-
> extends RepositoryBaseC1<T, Encoded, Evt, ItemType, IdKey> {
|
|
146
|
-
constructor(
|
|
147
|
-
itemType: ItemType,
|
|
148
|
-
protected readonly impl: Repository<T, Encoded, Evt, ItemType, IdKey> & Ext
|
|
149
|
-
) {
|
|
150
|
-
super(itemType)
|
|
151
|
-
this.saveAndPublish = this.impl.saveAndPublish
|
|
152
|
-
this.removeAndPublish = this.impl.removeAndPublish
|
|
153
|
-
this.find = this.impl.find
|
|
154
|
-
this.all = this.impl.all
|
|
155
|
-
this.changeFeed = this.impl.changeFeed
|
|
156
|
-
this.mapped = this.impl.mapped
|
|
157
|
-
this.query = this.impl.query
|
|
158
|
-
}
|
|
159
|
-
// makes super calls a compiler error, as it should
|
|
160
|
-
override saveAndPublish
|
|
161
|
-
override removeAndPublish
|
|
162
|
-
override find
|
|
163
|
-
override all
|
|
164
|
-
override changeFeed
|
|
165
|
-
override mapped
|
|
166
|
-
override query
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
export class RepositoryBaseC3<
|
|
170
|
-
T,
|
|
171
|
-
Encoded extends { id: string },
|
|
172
|
-
Evt,
|
|
173
|
-
ItemType extends string,
|
|
174
|
-
Ext,
|
|
175
|
-
IdKey extends keyof T
|
|
176
|
-
> extends RepositoryBaseC2<T, Encoded, Evt, ItemType, Ext, IdKey> {
|
|
177
|
-
get(id: T[IdKey]) {
|
|
178
|
-
return Effect.andThen(
|
|
179
|
-
this
|
|
180
|
-
.find(id),
|
|
181
|
-
(_) => Effect.mapError(_, () => new NotFoundError<ItemType>({ type: this.itemType, id }))
|
|
182
|
-
)
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
readonly log = (evt: Evt) => AnyPureDSL.log(evt)
|
|
186
|
-
|
|
187
|
-
removeById(id: T[IdKey]) {
|
|
188
|
-
return Effect.andThen(this.get(id), (_) => this.removeAndPublish([_]))
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
readonly save = (...items: NonEmptyArray<T>) => this.saveAndPublish(items)
|
|
192
|
-
|
|
193
|
-
readonly saveWithEvents = (events: Iterable<Evt>) => (...items: NonEmptyArray<T>) =>
|
|
194
|
-
this.saveAndPublish(items, events)
|
|
195
|
-
|
|
196
|
-
readonly queryAndSavePure: {
|
|
197
|
-
<A, E2, R2, T2 extends T>(
|
|
198
|
-
q: (
|
|
199
|
-
q: Query<Encoded>
|
|
200
|
-
) => QueryEnd<Encoded, "one">,
|
|
201
|
-
pure: Effect<A, E2, FixEnv<R2, Evt, T, T2>>
|
|
202
|
-
): Effect.Effect<
|
|
203
|
-
A,
|
|
204
|
-
InvalidStateError | OptimisticConcurrencyException | NotFoundError<ItemType> | E2,
|
|
205
|
-
Exclude<R2, {
|
|
206
|
-
env: PureEnv<Evt, T, T2>
|
|
207
|
-
}>
|
|
208
|
-
>
|
|
209
|
-
<A, E2, R2, T2 extends T>(
|
|
210
|
-
q: (
|
|
211
|
-
q: Query<Encoded>
|
|
212
|
-
) =>
|
|
213
|
-
| Query<Encoded>
|
|
214
|
-
| QueryWhere<Encoded>
|
|
215
|
-
| QueryEnd<Encoded, "many">,
|
|
216
|
-
pure: Effect<A, E2, FixEnv<R2, Evt, readonly T[], readonly T2[]>>
|
|
217
|
-
): Effect.Effect<
|
|
218
|
-
A,
|
|
219
|
-
InvalidStateError | OptimisticConcurrencyException | E2,
|
|
220
|
-
Exclude<R2, {
|
|
221
|
-
env: PureEnv<Evt, readonly T[], readonly T2[]>
|
|
222
|
-
}>
|
|
223
|
-
>
|
|
224
|
-
<A, E2, R2, T2 extends T>(
|
|
225
|
-
q: (
|
|
226
|
-
q: Query<Encoded>
|
|
227
|
-
) =>
|
|
228
|
-
| Query<Encoded>
|
|
229
|
-
| QueryWhere<Encoded>
|
|
230
|
-
| QueryEnd<Encoded, "many">,
|
|
231
|
-
pure: Effect<A, E2, FixEnv<R2, Evt, readonly T[], readonly T2[]>>,
|
|
232
|
-
batch: "batched" | number
|
|
233
|
-
): Effect.Effect<
|
|
234
|
-
A[],
|
|
235
|
-
InvalidStateError | OptimisticConcurrencyException | E2,
|
|
236
|
-
Exclude<R2, {
|
|
237
|
-
env: PureEnv<Evt, readonly T[], readonly T2[]>
|
|
238
|
-
}>
|
|
239
|
-
>
|
|
240
|
-
} = (q, pure, batch?: "batched" | number) =>
|
|
241
|
-
this.query(q).pipe(
|
|
242
|
-
Effect.andThen((_) =>
|
|
243
|
-
Array.isArray(_)
|
|
244
|
-
? batch === undefined
|
|
245
|
-
? saveManyWithPure_(this, _ as any, pure as any)
|
|
246
|
-
: saveManyWithPureBatched_(this, _ as any, pure as any, batch === "batched" ? 100 : batch)
|
|
247
|
-
: saveWithPure_(this, _ as any, pure as any)
|
|
248
|
-
)
|
|
249
|
-
) as any
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* NOTE: it's not as composable, only useful when the request is simple, and only this part needs request args.
|
|
253
|
-
*/
|
|
254
|
-
readonly handleByIdAndSaveWithPure = <Req extends { id: T[IdKey] }, Context, R, A, E, S2 extends T>(
|
|
255
|
-
pure: (req: Req, ctx: Context) => Effect<A, E, FixEnv<R, Evt, T, S2>>
|
|
256
|
-
) =>
|
|
257
|
-
(req: Req, ctx: Context) => byIdAndSaveWithPure(this, req.id)(pure(req, ctx))
|
|
258
|
-
|
|
259
|
-
saveManyWithPure: {
|
|
260
|
-
<R, A, E, S1 extends T, S2 extends T>(
|
|
261
|
-
items: Iterable<S1>,
|
|
262
|
-
pure: Effect<A, E, FixEnv<R, Evt, readonly S1[], readonly S2[]>>
|
|
263
|
-
): Effect.Effect<
|
|
264
|
-
A,
|
|
265
|
-
InvalidStateError | OptimisticConcurrencyException | E,
|
|
266
|
-
Exclude<R, {
|
|
267
|
-
env: PureEnv<Evt, readonly S1[], readonly S2[]>
|
|
268
|
-
}>
|
|
269
|
-
>
|
|
270
|
-
<R, A, E, S1 extends T, S2 extends T>(
|
|
271
|
-
items: Iterable<S1>,
|
|
272
|
-
pure: Effect<A, E, FixEnv<R, Evt, readonly S1[], readonly S2[]>>,
|
|
273
|
-
batch: "batched" | number
|
|
274
|
-
): Effect.Effect<
|
|
275
|
-
A[],
|
|
276
|
-
InvalidStateError | OptimisticConcurrencyException | E,
|
|
277
|
-
Exclude<R, {
|
|
278
|
-
env: PureEnv<Evt, readonly S1[], readonly S2[]>
|
|
279
|
-
}>
|
|
280
|
-
>
|
|
281
|
-
} = (items, pure, batch?: "batched" | number) =>
|
|
282
|
-
batch
|
|
283
|
-
? Effect.forEach(
|
|
284
|
-
Array.chunk_(items, batch === "batched" ? 100 : batch),
|
|
285
|
-
(batch) =>
|
|
286
|
-
saveAllWithEffectInt(
|
|
287
|
-
this,
|
|
288
|
-
runTerm(pure, batch)
|
|
289
|
-
)
|
|
290
|
-
)
|
|
291
|
-
: saveAllWithEffectInt(
|
|
292
|
-
this,
|
|
293
|
-
runTerm(pure, [...items])
|
|
294
|
-
)
|
|
295
|
-
|
|
296
|
-
byIdAndSaveWithPure: {
|
|
297
|
-
<R, A, E, S2 extends T>(
|
|
298
|
-
id: T[IdKey],
|
|
299
|
-
pure: Effect<A, E, FixEnv<R, Evt, T, S2>>
|
|
300
|
-
): Effect<
|
|
301
|
-
A,
|
|
302
|
-
InvalidStateError | OptimisticConcurrencyException | NotFoundError<ItemType> | E,
|
|
303
|
-
Exclude<R, {
|
|
304
|
-
env: PureEnv<Evt, T, S2>
|
|
305
|
-
}>
|
|
306
|
-
>
|
|
307
|
-
} = (id, pure): any => get(this, id).pipe(Effect.flatMap((item) => saveWithPure_(this, item, pure)))
|
|
308
|
-
|
|
309
|
-
saveWithPure<
|
|
310
|
-
R,
|
|
311
|
-
A,
|
|
312
|
-
E,
|
|
313
|
-
S1 extends T,
|
|
314
|
-
S2 extends T
|
|
315
|
-
>(
|
|
316
|
-
item: S1,
|
|
317
|
-
pure: Effect<A, E, FixEnv<R, Evt, S1, S2>>
|
|
318
|
-
) {
|
|
319
|
-
return saveAllWithEffectInt(
|
|
320
|
-
this,
|
|
321
|
-
runTerm(pure, item)
|
|
322
|
-
.pipe(Effect.map(([item, events, a]) => [[item], events, a]))
|
|
323
|
-
)
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
|
|
327
29
|
const dedupe = Array.dedupeWith(Equivalence.string)
|
|
328
30
|
|
|
329
31
|
/**
|
|
@@ -614,12 +316,12 @@ export function makeRepoInternal<
|
|
|
614
316
|
const r: Repository<T, Encoded, Evt, ItemType, IdKey> = {
|
|
615
317
|
changeFeed,
|
|
616
318
|
itemType: name,
|
|
319
|
+
idKey,
|
|
617
320
|
find,
|
|
618
321
|
all,
|
|
619
322
|
saveAndPublish,
|
|
620
323
|
removeAndPublish,
|
|
621
324
|
query: (q: any) => query(typeof q === "function" ? q(makeQuery()) : q) as any,
|
|
622
|
-
|
|
623
325
|
/**
|
|
624
326
|
* @internal
|
|
625
327
|
*/
|
|
@@ -786,568 +488,6 @@ export interface Repos<
|
|
|
786
488
|
|
|
787
489
|
export type GetRepoType<T> = T extends { type: infer R } ? R : never
|
|
788
490
|
|
|
789
|
-
export interface RepoFunctions<T, Encoded extends { id: string }, Evt, ItemType, IdKey extends keyof T, Service> {
|
|
790
|
-
itemType: ItemType
|
|
791
|
-
T: T
|
|
792
|
-
all: Effect<readonly T[], never, Service>
|
|
793
|
-
find: (id: T[IdKey]) => Effect<Option<T>, never, Service>
|
|
794
|
-
removeById: (id: T[IdKey]) => Effect<void, NotFoundError<ItemType>, Service>
|
|
795
|
-
saveAndPublish: (
|
|
796
|
-
items: Iterable<T>,
|
|
797
|
-
events?: Iterable<Evt>
|
|
798
|
-
) => Effect<void, InvalidStateError | OptimisticConcurrencyException, Service>
|
|
799
|
-
removeAndPublish: (
|
|
800
|
-
items: Iterable<T>,
|
|
801
|
-
events?: Iterable<Evt>
|
|
802
|
-
) => Effect<void, never, Service>
|
|
803
|
-
save: (...items: T[]) => Effect<void, InvalidStateError | OptimisticConcurrencyException, Service>
|
|
804
|
-
get: (id: T[IdKey]) => Effect<T, NotFoundError<ItemType>, Service>
|
|
805
|
-
|
|
806
|
-
queryAndSavePure: {
|
|
807
|
-
<A, E2, R2, T2 extends T>(
|
|
808
|
-
q: (
|
|
809
|
-
q: Query<Encoded>
|
|
810
|
-
) => QueryEnd<Encoded, "one">,
|
|
811
|
-
pure: Effect<A, E2, FixEnv<R2, Evt, T, T2>>
|
|
812
|
-
): Effect.Effect<
|
|
813
|
-
A,
|
|
814
|
-
InvalidStateError | OptimisticConcurrencyException | NotFoundError<ItemType> | E2,
|
|
815
|
-
| Service
|
|
816
|
-
| Exclude<R2, {
|
|
817
|
-
env: PureEnv<Evt, T, T2>
|
|
818
|
-
}>
|
|
819
|
-
>
|
|
820
|
-
<A, E2, R2, T2 extends T>(
|
|
821
|
-
q: (
|
|
822
|
-
q: Query<Encoded>
|
|
823
|
-
) =>
|
|
824
|
-
| Query<Encoded>
|
|
825
|
-
| QueryWhere<Encoded>
|
|
826
|
-
| QueryEnd<Encoded, "many">,
|
|
827
|
-
pure: Effect<A, E2, FixEnv<R2, Evt, readonly T[], readonly T2[]>>
|
|
828
|
-
): Effect.Effect<
|
|
829
|
-
A,
|
|
830
|
-
InvalidStateError | OptimisticConcurrencyException | E2,
|
|
831
|
-
| Service
|
|
832
|
-
| Exclude<R2, {
|
|
833
|
-
env: PureEnv<Evt, readonly T[], readonly T2[]>
|
|
834
|
-
}>
|
|
835
|
-
>
|
|
836
|
-
<A, E2, R2, T2 extends T>(
|
|
837
|
-
q: (
|
|
838
|
-
q: Query<Encoded>
|
|
839
|
-
) =>
|
|
840
|
-
| Query<Encoded>
|
|
841
|
-
| QueryWhere<Encoded>
|
|
842
|
-
| QueryEnd<Encoded, "many">,
|
|
843
|
-
pure: Effect<A, E2, FixEnv<R2, Evt, readonly T[], readonly T2[]>>,
|
|
844
|
-
batch: "batched" | number
|
|
845
|
-
): Effect.Effect<
|
|
846
|
-
A[],
|
|
847
|
-
InvalidStateError | OptimisticConcurrencyException | E2,
|
|
848
|
-
| Service
|
|
849
|
-
| Exclude<R2, {
|
|
850
|
-
env: PureEnv<Evt, readonly T[], readonly T2[]>
|
|
851
|
-
}>
|
|
852
|
-
>
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
readonly query: {
|
|
856
|
-
<A, R, From extends FieldValues, TType extends "one" | "many" | "count" = "many">(
|
|
857
|
-
q: (
|
|
858
|
-
initial: Query<Encoded>
|
|
859
|
-
) => QueryProjection<Encoded extends From ? From : never, A, R, TType>
|
|
860
|
-
): Effect.Effect<
|
|
861
|
-
TType extends "many" ? readonly A[] : TType extends "count" ? NonNegativeInt : A,
|
|
862
|
-
| (TType extends "many" ? never : NotFoundError<ItemType>)
|
|
863
|
-
| (TType extends "count" ? never : S.ParseResult.ParseError),
|
|
864
|
-
Service | R
|
|
865
|
-
>
|
|
866
|
-
<R = never, TType extends "one" | "many" = "many">(
|
|
867
|
-
q: (initial: Query<Encoded>) => QAll<Encoded, T, R, TType>
|
|
868
|
-
): Effect.Effect<
|
|
869
|
-
TType extends "many" ? readonly T[] : T,
|
|
870
|
-
TType extends "many" ? never : NotFoundError<ItemType>,
|
|
871
|
-
Service | R
|
|
872
|
-
>
|
|
873
|
-
// <R = never>(q: QAll<Encoded, T, R>): Effect.Effect<readonly T[], never, Service | R>
|
|
874
|
-
// <A, R, From extends FieldValues>(
|
|
875
|
-
// q: QueryProjection<Encoded extends From ? From : never, A, R>
|
|
876
|
-
// ): Effect.Effect<readonly A[], S.ParseResult.ParseError, Service | R>
|
|
877
|
-
}
|
|
878
|
-
|
|
879
|
-
byIdAndSaveWithPure: {
|
|
880
|
-
<R, A, E, S2 extends T>(
|
|
881
|
-
id: T[IdKey],
|
|
882
|
-
pure: Effect<A, E, FixEnv<R, Evt, T, S2>>
|
|
883
|
-
): Effect<
|
|
884
|
-
A,
|
|
885
|
-
InvalidStateError | OptimisticConcurrencyException | E | NotFoundError<ItemType>,
|
|
886
|
-
| Service
|
|
887
|
-
| Exclude<R, {
|
|
888
|
-
env: PureEnv<Evt, T, S2>
|
|
889
|
-
}>
|
|
890
|
-
>
|
|
891
|
-
}
|
|
892
|
-
|
|
893
|
-
saveManyWithPure: {
|
|
894
|
-
<R, A, E, S1 extends T, S2 extends T>(
|
|
895
|
-
items: Iterable<S1>,
|
|
896
|
-
pure: Effect<A, E, FixEnv<R, Evt, readonly S1[], readonly S2[]>>
|
|
897
|
-
): Effect.Effect<
|
|
898
|
-
A,
|
|
899
|
-
InvalidStateError | OptimisticConcurrencyException | E,
|
|
900
|
-
Exclude<R, {
|
|
901
|
-
env: PureEnv<Evt, readonly S1[], readonly S2[]>
|
|
902
|
-
}>
|
|
903
|
-
>
|
|
904
|
-
<R, A, E, S1 extends T, S2 extends T>(
|
|
905
|
-
items: Iterable<S1>,
|
|
906
|
-
pure: Effect<A, E, FixEnv<R, Evt, readonly S1[], readonly S2[]>>,
|
|
907
|
-
batch: "batched" | number
|
|
908
|
-
): Effect.Effect<
|
|
909
|
-
A[],
|
|
910
|
-
InvalidStateError | OptimisticConcurrencyException | E,
|
|
911
|
-
Exclude<R, {
|
|
912
|
-
env: PureEnv<Evt, readonly S1[], readonly S2[]>
|
|
913
|
-
}>
|
|
914
|
-
>
|
|
915
|
-
}
|
|
916
|
-
|
|
917
|
-
/** @experimental */
|
|
918
|
-
mapped: MM<Service, Encoded>
|
|
919
|
-
|
|
920
|
-
use: <X>(
|
|
921
|
-
body: (_: Service) => X
|
|
922
|
-
) => X extends Effect<infer A, infer E, infer R> ? Effect<A, E, R | Service> : Effect<X, never, Service>
|
|
923
|
-
}
|
|
924
|
-
|
|
925
|
-
const makeRepoFunctions = (tag: any, itemType: any) => {
|
|
926
|
-
const { all } = Effect.serviceConstants(tag) as any
|
|
927
|
-
const {
|
|
928
|
-
byIdAndSaveWithPure,
|
|
929
|
-
find,
|
|
930
|
-
get,
|
|
931
|
-
query,
|
|
932
|
-
queryAndSavePure,
|
|
933
|
-
removeAndPublish,
|
|
934
|
-
removeById,
|
|
935
|
-
save,
|
|
936
|
-
saveAndPublish,
|
|
937
|
-
saveManyWithPure
|
|
938
|
-
} = Effect.serviceFunctions(tag) as any
|
|
939
|
-
|
|
940
|
-
const mapped = (s: any) => Effect.map(tag, (_: any) => _.mapped(s))
|
|
941
|
-
|
|
942
|
-
return {
|
|
943
|
-
itemType,
|
|
944
|
-
all,
|
|
945
|
-
byIdAndSaveWithPure,
|
|
946
|
-
find,
|
|
947
|
-
removeById,
|
|
948
|
-
saveAndPublish,
|
|
949
|
-
removeAndPublish,
|
|
950
|
-
save,
|
|
951
|
-
get,
|
|
952
|
-
query,
|
|
953
|
-
mapped,
|
|
954
|
-
queryAndSavePure,
|
|
955
|
-
saveManyWithPure,
|
|
956
|
-
use: (body: any) => Effect.andThen(tag, body)
|
|
957
|
-
}
|
|
958
|
-
}
|
|
959
|
-
|
|
960
|
-
export const RepositoryBaseImpl = <Service>() => {
|
|
961
|
-
return <
|
|
962
|
-
Evt = never
|
|
963
|
-
>() =>
|
|
964
|
-
<ItemType extends string, R, Encoded extends { id: string }, T, IdKey extends keyof T>(
|
|
965
|
-
itemType: ItemType,
|
|
966
|
-
schema: S.Schema<T, Encoded, R>,
|
|
967
|
-
idKey: IdKey,
|
|
968
|
-
jitM?: (pm: Encoded) => Encoded
|
|
969
|
-
):
|
|
970
|
-
& (abstract new() => RepositoryBaseC1<T, Encoded, Evt, ItemType, IdKey>)
|
|
971
|
-
& Context.Tag<Service, Service>
|
|
972
|
-
& Repos<
|
|
973
|
-
T,
|
|
974
|
-
Encoded,
|
|
975
|
-
R,
|
|
976
|
-
Evt,
|
|
977
|
-
ItemType,
|
|
978
|
-
IdKey
|
|
979
|
-
>
|
|
980
|
-
& RepoFunctions<T, Encoded, Evt, ItemType, IdKey, Service> =>
|
|
981
|
-
{
|
|
982
|
-
const mkRepo = makeRepoInternal<Evt>()(
|
|
983
|
-
itemType,
|
|
984
|
-
schema,
|
|
985
|
-
jitM ? (pm) => jitM(pm as unknown as Encoded) : (pm) => pm as any,
|
|
986
|
-
(e, _etag) => ({ ...e, _etag }),
|
|
987
|
-
idKey
|
|
988
|
-
)
|
|
989
|
-
abstract class Cls extends RepositoryBaseC1<T, Encoded, Evt, ItemType, IdKey> {
|
|
990
|
-
constructor() {
|
|
991
|
-
super(itemType)
|
|
992
|
-
}
|
|
993
|
-
static readonly make = mkRepo.make
|
|
994
|
-
static readonly makeWith = ((a: any, b: any) => Effect.map(mkRepo.make(a), b)) as any
|
|
995
|
-
|
|
996
|
-
static readonly Q = Q.make<Encoded>()
|
|
997
|
-
static readonly type: Repository<T, Encoded, Evt, ItemType, IdKey> = undefined as any
|
|
998
|
-
}
|
|
999
|
-
const limit = Error.stackTraceLimit
|
|
1000
|
-
Error.stackTraceLimit = 2
|
|
1001
|
-
const creationError = new Error()
|
|
1002
|
-
Error.stackTraceLimit = limit
|
|
1003
|
-
return Context.assignTag<Service>(undefined, creationError)(
|
|
1004
|
-
Object.assign(Cls, makeRepoFunctions(Cls, itemType))
|
|
1005
|
-
) as any
|
|
1006
|
-
}
|
|
1007
|
-
}
|
|
1008
|
-
|
|
1009
|
-
export const RepositoryDefaultImpl = <Service, Evt = never>() => {
|
|
1010
|
-
const f: {
|
|
1011
|
-
<ItemType extends string, R, Encoded extends { id: string }, T, const IdKey extends keyof T>(
|
|
1012
|
-
itemType: ItemType,
|
|
1013
|
-
schema: S.Schema<T, Encoded, R>,
|
|
1014
|
-
idKey: IdKey,
|
|
1015
|
-
jitM?: (pm: Encoded) => Encoded
|
|
1016
|
-
):
|
|
1017
|
-
& (abstract new(
|
|
1018
|
-
impl: Repository<T, Encoded, Evt, ItemType, IdKey>
|
|
1019
|
-
) => RepositoryBaseC3<T, Encoded, Evt, ItemType, {}, IdKey>)
|
|
1020
|
-
& Context.Tag<Service, Service>
|
|
1021
|
-
& Repos<
|
|
1022
|
-
T,
|
|
1023
|
-
Encoded,
|
|
1024
|
-
R,
|
|
1025
|
-
Evt,
|
|
1026
|
-
ItemType,
|
|
1027
|
-
IdKey
|
|
1028
|
-
>
|
|
1029
|
-
& RepoFunctions<T, Encoded, Evt, ItemType, IdKey, Service>
|
|
1030
|
-
<ItemType extends string, R, Encoded extends { id: string }, T extends { id: unknown }>(
|
|
1031
|
-
itemType: ItemType,
|
|
1032
|
-
schema: S.Schema<T, Encoded, R>,
|
|
1033
|
-
jitM?: (pm: Encoded) => Encoded
|
|
1034
|
-
):
|
|
1035
|
-
& (abstract new(
|
|
1036
|
-
impl: Repository<T, Encoded, Evt, ItemType, "id">
|
|
1037
|
-
) => RepositoryBaseC3<T, Encoded, Evt, ItemType, {}, "id">)
|
|
1038
|
-
& Context.Tag<Service, Service>
|
|
1039
|
-
& Repos<
|
|
1040
|
-
T,
|
|
1041
|
-
Encoded,
|
|
1042
|
-
R,
|
|
1043
|
-
Evt,
|
|
1044
|
-
ItemType,
|
|
1045
|
-
"id"
|
|
1046
|
-
>
|
|
1047
|
-
& RepoFunctions<T, Encoded, Evt, ItemType, "id", Service>
|
|
1048
|
-
} = <ItemType extends string, R, Encoded extends { id: string }, T, const IdKey extends keyof T>(
|
|
1049
|
-
itemType: ItemType,
|
|
1050
|
-
schema: S.Schema<T, Encoded, R>,
|
|
1051
|
-
idKeyOrJitM?: IdKey | ((pm: Encoded) => Encoded),
|
|
1052
|
-
jitM?: (pm: Encoded) => Encoded
|
|
1053
|
-
) => {
|
|
1054
|
-
if (!jitM && idKeyOrJitM !== undefined && typeof idKeyOrJitM === "function") jitM = idKeyOrJitM
|
|
1055
|
-
const mkRepo = makeRepoInternal<Evt>()(
|
|
1056
|
-
itemType,
|
|
1057
|
-
schema,
|
|
1058
|
-
jitM ? (pm) => jitM(pm) : (pm) => pm,
|
|
1059
|
-
(e, _etag) => ({ ...e, _etag }),
|
|
1060
|
-
idKeyOrJitM ?? "id" as any
|
|
1061
|
-
)
|
|
1062
|
-
abstract class Cls extends RepositoryBaseC3<T, Encoded, Evt, ItemType, {}, IdKey> {
|
|
1063
|
-
constructor(
|
|
1064
|
-
impl: Repository<T, Encoded, Evt, ItemType, IdKey>
|
|
1065
|
-
) {
|
|
1066
|
-
super(itemType, impl)
|
|
1067
|
-
}
|
|
1068
|
-
static readonly make = mkRepo.make
|
|
1069
|
-
static readonly makeWith = ((a: any, b: any) => Effect.map(mkRepo.make(a), b)) as any
|
|
1070
|
-
|
|
1071
|
-
static readonly Q = Q.make<Encoded>()
|
|
1072
|
-
|
|
1073
|
-
static readonly type: Repository<T, Encoded, Evt, ItemType, IdKey> = undefined as any
|
|
1074
|
-
}
|
|
1075
|
-
const limit = Error.stackTraceLimit
|
|
1076
|
-
Error.stackTraceLimit = 2
|
|
1077
|
-
const creationError = new Error()
|
|
1078
|
-
Error.stackTraceLimit = limit
|
|
1079
|
-
return Context.assignTag<Service>(undefined, creationError)(
|
|
1080
|
-
Object.assign(Cls, makeRepoFunctions(Cls, itemType))
|
|
1081
|
-
) as any // impl is missing, but its marked protected
|
|
1082
|
-
}
|
|
1083
|
-
return f
|
|
1084
|
-
}
|
|
1085
|
-
|
|
1086
|
-
export const RepositoryDefaultImpl2 = <Service, Evt = never>() => {
|
|
1087
|
-
const f: {
|
|
1088
|
-
<
|
|
1089
|
-
ItemType extends string,
|
|
1090
|
-
R,
|
|
1091
|
-
Encoded extends { id: string },
|
|
1092
|
-
T,
|
|
1093
|
-
IdKey extends keyof T,
|
|
1094
|
-
E = never,
|
|
1095
|
-
RInitial = never,
|
|
1096
|
-
R2 = never,
|
|
1097
|
-
Layers extends [Layer.Layer.Any, ...Layer.Layer.Any[]] = [Layer.Layer<never>],
|
|
1098
|
-
E1 = never,
|
|
1099
|
-
R1 = never,
|
|
1100
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
1101
|
-
Ext = {}
|
|
1102
|
-
>(
|
|
1103
|
-
itemType: ItemType,
|
|
1104
|
-
schema: S.Schema<T, Encoded, R>,
|
|
1105
|
-
options: [Evt] extends [never] ? {
|
|
1106
|
-
dependencies?: Layers
|
|
1107
|
-
idKey: IdKey
|
|
1108
|
-
config?: Omit<StoreConfig<Encoded>, "partitionValue"> & {
|
|
1109
|
-
partitionValue?: (a: Encoded) => string
|
|
1110
|
-
}
|
|
1111
|
-
jitM?: (pm: Encoded) => Encoded
|
|
1112
|
-
options?: Effect<
|
|
1113
|
-
{
|
|
1114
|
-
makeInitial?: Effect<readonly T[], E, RInitial>
|
|
1115
|
-
ext?: Ext
|
|
1116
|
-
},
|
|
1117
|
-
E1,
|
|
1118
|
-
R1
|
|
1119
|
-
>
|
|
1120
|
-
}
|
|
1121
|
-
: {
|
|
1122
|
-
dependencies?: Layers
|
|
1123
|
-
idKey: IdKey
|
|
1124
|
-
jitM?: (pm: Encoded) => Encoded
|
|
1125
|
-
config?: Omit<StoreConfig<Encoded>, "partitionValue"> & {
|
|
1126
|
-
partitionValue?: (a: Encoded) => string
|
|
1127
|
-
}
|
|
1128
|
-
options?: Effect<
|
|
1129
|
-
{
|
|
1130
|
-
publishEvents: (evt: NonEmptyReadonlyArray<Evt>) => Effect<void, never, R2>
|
|
1131
|
-
makeInitial?: Effect<readonly T[], E, RInitial>
|
|
1132
|
-
ext?: Ext
|
|
1133
|
-
},
|
|
1134
|
-
E1,
|
|
1135
|
-
R1
|
|
1136
|
-
>
|
|
1137
|
-
}
|
|
1138
|
-
):
|
|
1139
|
-
& (abstract new(
|
|
1140
|
-
impl: Repository<T, Encoded, Evt, ItemType, IdKey> & Ext
|
|
1141
|
-
) => RepositoryBaseC3<T, Encoded, Evt, ItemType, Ext, IdKey>)
|
|
1142
|
-
& Context.Tag<Service, Service>
|
|
1143
|
-
& {
|
|
1144
|
-
Default: Layer.Layer<
|
|
1145
|
-
Service,
|
|
1146
|
-
E1 | Layer.Layer.Error<Layers[number]>,
|
|
1147
|
-
Exclude<
|
|
1148
|
-
R1 | R | StoreMaker,
|
|
1149
|
-
{ [k in keyof Layers]: Layer.Layer.Success<Layers[k]> }[number]
|
|
1150
|
-
>
|
|
1151
|
-
>
|
|
1152
|
-
DefaultWithoutDependencies: Layer.Layer<
|
|
1153
|
-
Service,
|
|
1154
|
-
E1,
|
|
1155
|
-
R1 | R | StoreMaker
|
|
1156
|
-
>
|
|
1157
|
-
}
|
|
1158
|
-
& Repos<
|
|
1159
|
-
T,
|
|
1160
|
-
Encoded,
|
|
1161
|
-
R,
|
|
1162
|
-
Evt,
|
|
1163
|
-
ItemType,
|
|
1164
|
-
IdKey
|
|
1165
|
-
>
|
|
1166
|
-
& RepoFunctions<T, Encoded, Evt, ItemType, IdKey, Service>
|
|
1167
|
-
<
|
|
1168
|
-
ItemType extends string,
|
|
1169
|
-
R,
|
|
1170
|
-
Encoded extends { id: string },
|
|
1171
|
-
T extends { id: unknown },
|
|
1172
|
-
E = never,
|
|
1173
|
-
RInitial = never,
|
|
1174
|
-
R2 = never,
|
|
1175
|
-
Layers extends [Layer.Layer.Any, ...Layer.Layer.Any[]] = [Layer.Layer<never>],
|
|
1176
|
-
E1 = never,
|
|
1177
|
-
R1 = never,
|
|
1178
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
1179
|
-
Ext = {}
|
|
1180
|
-
>(
|
|
1181
|
-
itemType: ItemType,
|
|
1182
|
-
schema: S.Schema<T, Encoded, R>,
|
|
1183
|
-
options: [Evt] extends [never] ? {
|
|
1184
|
-
dependencies?: Layers
|
|
1185
|
-
config?: Omit<StoreConfig<Encoded>, "partitionValue"> & {
|
|
1186
|
-
partitionValue?: (a: Encoded) => string
|
|
1187
|
-
}
|
|
1188
|
-
jitM?: (pm: Encoded) => Encoded
|
|
1189
|
-
options?: Effect<
|
|
1190
|
-
{
|
|
1191
|
-
makeInitial?: Effect<readonly T[], E, RInitial>
|
|
1192
|
-
ext?: Ext
|
|
1193
|
-
},
|
|
1194
|
-
E1,
|
|
1195
|
-
R1
|
|
1196
|
-
>
|
|
1197
|
-
}
|
|
1198
|
-
: {
|
|
1199
|
-
dependencies?: Layers
|
|
1200
|
-
jitM?: (pm: Encoded) => Encoded
|
|
1201
|
-
config?: Omit<StoreConfig<Encoded>, "partitionValue"> & {
|
|
1202
|
-
partitionValue?: (a: Encoded) => string
|
|
1203
|
-
}
|
|
1204
|
-
options?: Effect<
|
|
1205
|
-
{
|
|
1206
|
-
publishEvents: (evt: NonEmptyReadonlyArray<Evt>) => Effect<void, never, R2>
|
|
1207
|
-
makeInitial?: Effect<readonly T[], E, RInitial>
|
|
1208
|
-
ext?: Ext
|
|
1209
|
-
},
|
|
1210
|
-
E1,
|
|
1211
|
-
R1
|
|
1212
|
-
>
|
|
1213
|
-
}
|
|
1214
|
-
):
|
|
1215
|
-
& (abstract new(
|
|
1216
|
-
impl: Repository<T, Encoded, Evt, ItemType, "id"> & Ext
|
|
1217
|
-
) => RepositoryBaseC3<T, Encoded, Evt, ItemType, Ext, "id">)
|
|
1218
|
-
& Context.Tag<Service, Service>
|
|
1219
|
-
& {
|
|
1220
|
-
Default: Layer.Layer<
|
|
1221
|
-
Service,
|
|
1222
|
-
E1 | Layer.Layer.Error<Layers[number]>,
|
|
1223
|
-
Exclude<
|
|
1224
|
-
R1 | R | StoreMaker,
|
|
1225
|
-
{ [k in keyof Layers]: Layer.Layer.Success<Layers[k]> }[number]
|
|
1226
|
-
>
|
|
1227
|
-
>
|
|
1228
|
-
DefaultWithoutDependencies: Layer.Layer<
|
|
1229
|
-
Service,
|
|
1230
|
-
E1,
|
|
1231
|
-
R1 | R | StoreMaker
|
|
1232
|
-
>
|
|
1233
|
-
}
|
|
1234
|
-
& Repos<
|
|
1235
|
-
T,
|
|
1236
|
-
Encoded,
|
|
1237
|
-
R,
|
|
1238
|
-
Evt,
|
|
1239
|
-
ItemType,
|
|
1240
|
-
"id"
|
|
1241
|
-
>
|
|
1242
|
-
& RepoFunctions<T, Encoded, Evt, ItemType, "id", Service>
|
|
1243
|
-
} = <
|
|
1244
|
-
ItemType extends string,
|
|
1245
|
-
R,
|
|
1246
|
-
Encoded extends { id: string },
|
|
1247
|
-
T,
|
|
1248
|
-
IdKey extends keyof T,
|
|
1249
|
-
E = never,
|
|
1250
|
-
RInitial = never,
|
|
1251
|
-
R2 = never,
|
|
1252
|
-
Layers extends [Layer.Layer.Any, ...Layer.Layer.Any[]] = [Layer.Layer<never>],
|
|
1253
|
-
E1 = never,
|
|
1254
|
-
R1 = never,
|
|
1255
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
1256
|
-
Ext = {}
|
|
1257
|
-
>(
|
|
1258
|
-
itemType: ItemType,
|
|
1259
|
-
schema: S.Schema<T, Encoded, R>,
|
|
1260
|
-
options: [Evt] extends [never] ? {
|
|
1261
|
-
dependencies?: Layers
|
|
1262
|
-
idKey?: IdKey
|
|
1263
|
-
config?: Omit<StoreConfig<Encoded>, "partitionValue"> & {
|
|
1264
|
-
partitionValue?: (a: Encoded) => string
|
|
1265
|
-
}
|
|
1266
|
-
jitM?: (pm: Encoded) => Encoded
|
|
1267
|
-
options?: Effect<
|
|
1268
|
-
{
|
|
1269
|
-
makeInitial?: Effect<readonly T[], E, RInitial>
|
|
1270
|
-
ext?: Ext
|
|
1271
|
-
},
|
|
1272
|
-
E1,
|
|
1273
|
-
R1
|
|
1274
|
-
>
|
|
1275
|
-
}
|
|
1276
|
-
: {
|
|
1277
|
-
dependencies?: Layers
|
|
1278
|
-
idKey?: IdKey
|
|
1279
|
-
jitM?: (pm: Encoded) => Encoded
|
|
1280
|
-
config?: Omit<StoreConfig<Encoded>, "partitionValue"> & {
|
|
1281
|
-
partitionValue?: (a: Encoded) => string
|
|
1282
|
-
}
|
|
1283
|
-
options?: Effect<
|
|
1284
|
-
{
|
|
1285
|
-
publishEvents: (evt: NonEmptyReadonlyArray<Evt>) => Effect<void, never, R2>
|
|
1286
|
-
makeInitial?: Effect<readonly T[], E, RInitial>
|
|
1287
|
-
ext?: Ext
|
|
1288
|
-
},
|
|
1289
|
-
E1,
|
|
1290
|
-
R1
|
|
1291
|
-
>
|
|
1292
|
-
}
|
|
1293
|
-
) => {
|
|
1294
|
-
let layerCache = undefined
|
|
1295
|
-
let layerCache2 = undefined
|
|
1296
|
-
abstract class Cls extends RepositoryBaseC3<
|
|
1297
|
-
T,
|
|
1298
|
-
Encoded,
|
|
1299
|
-
Evt,
|
|
1300
|
-
ItemType,
|
|
1301
|
-
Ext,
|
|
1302
|
-
IdKey
|
|
1303
|
-
> {
|
|
1304
|
-
constructor(
|
|
1305
|
-
impl: Repository<T, Encoded, Evt, ItemType, IdKey> & Ext
|
|
1306
|
-
) {
|
|
1307
|
-
super(itemType, impl)
|
|
1308
|
-
}
|
|
1309
|
-
static readonly Q = Q.make<Encoded>()
|
|
1310
|
-
static get DefaultWithoutDependencies() {
|
|
1311
|
-
const self = this as any
|
|
1312
|
-
return layerCache ??= Effect
|
|
1313
|
-
.gen(function*() {
|
|
1314
|
-
const opts = yield* options.options ?? Effect.succeed({})
|
|
1315
|
-
const mkRepo = makeRepoInternal<Evt>()(
|
|
1316
|
-
itemType,
|
|
1317
|
-
schema,
|
|
1318
|
-
options?.jitM ? (pm) => options.jitM!(pm) : (pm) => pm,
|
|
1319
|
-
(e, _etag) => ({ ...e, _etag }),
|
|
1320
|
-
options.idKey ?? "id" as any
|
|
1321
|
-
)
|
|
1322
|
-
const r = yield* mkRepo.make({ ...options, ...opts } as any)
|
|
1323
|
-
const repo = new self(Object.assign(r, "ext" in opts ? opts.ext : {}))
|
|
1324
|
-
return Layer.succeed(self, repo)
|
|
1325
|
-
})
|
|
1326
|
-
.pipe(Layer.unwrapEffect)
|
|
1327
|
-
}
|
|
1328
|
-
static get Default() {
|
|
1329
|
-
const self = this as any
|
|
1330
|
-
return layerCache2 ??= options.dependencies
|
|
1331
|
-
? self
|
|
1332
|
-
.DefaultWithoutDependencies
|
|
1333
|
-
.pipe(Layer.provide(options.dependencies as any))
|
|
1334
|
-
: self.DefaultWithoutDependencies
|
|
1335
|
-
}
|
|
1336
|
-
static readonly type: Repository<T, Encoded, Evt, ItemType, IdKey> = undefined as any
|
|
1337
|
-
}
|
|
1338
|
-
const limit = Error.stackTraceLimit
|
|
1339
|
-
Error.stackTraceLimit = 2
|
|
1340
|
-
const creationError = new Error()
|
|
1341
|
-
Error.stackTraceLimit = limit
|
|
1342
|
-
// TODO: actual class name or expect a string identifier - careful with overlapping between modules
|
|
1343
|
-
return Context.assignTag<Service>(registerName(itemType + "Repo"), creationError)(
|
|
1344
|
-
Object.assign(Cls, makeRepoFunctions(Cls, itemType))
|
|
1345
|
-
) as any // impl is missing, but its marked protected
|
|
1346
|
-
}
|
|
1347
|
-
|
|
1348
|
-
return f
|
|
1349
|
-
}
|
|
1350
|
-
|
|
1351
491
|
export const makeRepo: {
|
|
1352
492
|
<
|
|
1353
493
|
ItemType extends string,
|
|
@@ -1371,8 +511,7 @@ export const makeRepo: {
|
|
|
1371
511
|
publishEvents?: (evt: NonEmptyReadonlyArray<Evt>) => Effect<void, never, R2>
|
|
1372
512
|
makeInitial?: Effect<readonly T[], E, RInitial>
|
|
1373
513
|
}
|
|
1374
|
-
):
|
|
1375
|
-
Effect.Effect<RepositoryBaseC3<T, Encoded, Evt, ItemType, {}, IdKey>, E, R | RInitial | R2 | StoreMaker>
|
|
514
|
+
): Effect.Effect<ExtendedRepository<T, Encoded, Evt, ItemType, IdKey>, E, R | RInitial | R2 | StoreMaker>
|
|
1376
515
|
<
|
|
1377
516
|
ItemType extends string,
|
|
1378
517
|
R,
|
|
@@ -1393,7 +532,7 @@ export const makeRepo: {
|
|
|
1393
532
|
publishEvents?: (evt: NonEmptyReadonlyArray<Evt>) => Effect<void, never, R2>
|
|
1394
533
|
makeInitial?: Effect<readonly T[], E, RInitial>
|
|
1395
534
|
}
|
|
1396
|
-
): Effect.Effect<
|
|
535
|
+
): Effect.Effect<ExtendedRepository<T, Encoded, Evt, ItemType, "id">, E, R | RInitial | R2 | StoreMaker>
|
|
1397
536
|
} = <
|
|
1398
537
|
ItemType extends string,
|
|
1399
538
|
R,
|
|
@@ -1426,64 +565,6 @@ export const makeRepo: {
|
|
|
1426
565
|
options.idKey ?? "id" as any
|
|
1427
566
|
)
|
|
1428
567
|
const r = yield* mkRepo.make(options as any)
|
|
1429
|
-
const repo =
|
|
568
|
+
const repo = extendRepo(r)
|
|
1430
569
|
return repo
|
|
1431
570
|
})
|
|
1432
|
-
|
|
1433
|
-
const names = new Map<string, number>()
|
|
1434
|
-
const registerName = (name: string) => {
|
|
1435
|
-
const existing = names.get(name)
|
|
1436
|
-
if (existing === undefined) {
|
|
1437
|
-
names.set(name, 1)
|
|
1438
|
-
return name
|
|
1439
|
-
} else {
|
|
1440
|
-
const n = existing + 1
|
|
1441
|
-
names.set(name, n)
|
|
1442
|
-
return name + "-" + existing
|
|
1443
|
-
}
|
|
1444
|
-
}
|
|
1445
|
-
|
|
1446
|
-
// TODO: integrate with repo
|
|
1447
|
-
export const makeRequest = <
|
|
1448
|
-
ItemType extends string,
|
|
1449
|
-
T,
|
|
1450
|
-
Encoded extends { id: string } & FieldValues,
|
|
1451
|
-
Evt,
|
|
1452
|
-
Service,
|
|
1453
|
-
IdKey extends keyof T
|
|
1454
|
-
>(repo: Context.Tag<Service, Service> & RepoFunctions<T, Encoded, Evt, ItemType, IdKey, Service>, idKey: IdKey) => {
|
|
1455
|
-
type Req =
|
|
1456
|
-
& Request.Request<T, NotFoundError<ItemType>>
|
|
1457
|
-
& { _tag: `Get${ItemType}`; id: T[IdKey] }
|
|
1458
|
-
const _request = Request.tagged<Req>(`Get${repo.itemType}`)
|
|
1459
|
-
|
|
1460
|
-
const requestResolver = RequestResolver
|
|
1461
|
-
.makeBatched((requests: NonEmptyReadonlyArray<Req>) =>
|
|
1462
|
-
(repo
|
|
1463
|
-
.query(Q.where("id", "in", requests.map((_) => _.id)) as any) as Effect<readonly T[], never, Service>) // TODO
|
|
1464
|
-
.pipe(
|
|
1465
|
-
Effect.andThen((items) =>
|
|
1466
|
-
Effect.forEach(requests, (r) =>
|
|
1467
|
-
Request.complete(
|
|
1468
|
-
r,
|
|
1469
|
-
Array
|
|
1470
|
-
.findFirst(items, (_) => _[idKey] === r.id)
|
|
1471
|
-
.pipe(Option.match({
|
|
1472
|
-
onNone: () => Exit.fail(new NotFoundError({ type: repo.itemType, id: r.id })),
|
|
1473
|
-
onSome: Exit.succeed
|
|
1474
|
-
}))
|
|
1475
|
-
), { discard: true })
|
|
1476
|
-
),
|
|
1477
|
-
Effect
|
|
1478
|
-
.catchAllCause((cause) =>
|
|
1479
|
-
Effect.forEach(requests, Request.complete(Exit.failCause(cause)), { discard: true })
|
|
1480
|
-
)
|
|
1481
|
-
)
|
|
1482
|
-
)
|
|
1483
|
-
.pipe(
|
|
1484
|
-
RequestResolver.batchN(20),
|
|
1485
|
-
RequestResolver.contextFromServices(repo)
|
|
1486
|
-
)
|
|
1487
|
-
|
|
1488
|
-
return (id: T[IdKey]) => Effect.request(_request({ id }), requestResolver)
|
|
1489
|
-
}
|