@effect-app/infra 0.170.6 → 0.172.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.
Files changed (67) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/_cjs/services/Operations/live.cjs +8 -9
  3. package/_cjs/services/Operations/live.cjs.map +1 -1
  4. package/_cjs/services/Repository/dsl.cjs +70 -0
  5. package/_cjs/services/Repository/dsl.cjs.map +1 -0
  6. package/_cjs/services/Repository/ext.cjs +217 -0
  7. package/_cjs/services/Repository/ext.cjs.map +1 -0
  8. package/_cjs/services/Repository/service.cjs +6 -0
  9. package/_cjs/services/Repository/service.cjs.map +1 -0
  10. package/_cjs/services/Repository.cjs +32 -252
  11. package/_cjs/services/Repository.cjs.map +1 -1
  12. package/_cjs/services/RepositoryBase.cjs +173 -48
  13. package/_cjs/services/RepositoryBase.cjs.map +1 -1
  14. package/_cjs/services/RequestContextContainer.cjs +13 -14
  15. package/_cjs/services/RequestContextContainer.cjs.map +1 -1
  16. package/_cjs/services/Store/ContextMapContainer.cjs +9 -10
  17. package/_cjs/services/Store/ContextMapContainer.cjs.map +1 -1
  18. package/_cjs/services/Store/codeFilter.cjs +2 -2
  19. package/_cjs/services/Store/utils.cjs +8 -9
  20. package/_cjs/services/Store/utils.cjs.map +1 -1
  21. package/_cjs/services/simpledb/diskdb.cjs +1 -2
  22. package/_cjs/services/simpledb/diskdb.cjs.map +1 -1
  23. package/_cjs/services/simpledb/simpledb.cjs +5 -6
  24. package/_cjs/services/simpledb/simpledb.cjs.map +1 -1
  25. package/_src/api/express/schema/routing.ts +6 -6
  26. package/_src/services/Operations/live.ts +1 -1
  27. package/_src/services/Repository/dsl.ts +137 -0
  28. package/_src/services/Repository/ext.ts +707 -0
  29. package/_src/services/Repository/service.ts +12 -0
  30. package/_src/services/Repository.ts +3 -815
  31. package/_src/services/RepositoryBase.ts +621 -4
  32. package/_src/services/RequestContextContainer.ts +1 -1
  33. package/_src/services/Store/ContextMapContainer.ts +1 -1
  34. package/_src/services/Store/codeFilter.ts +2 -2
  35. package/_src/services/Store/utils.ts +9 -9
  36. package/_src/services/simpledb/diskdb.ts +1 -1
  37. package/_src/services/simpledb/simpledb.ts +1 -1
  38. package/dist/services/Operations/live.js +9 -10
  39. package/dist/services/QueueMaker/service.d.ts +2 -2
  40. package/dist/services/Repository/dsl.d.ts +51 -0
  41. package/dist/services/Repository/dsl.d.ts.map +1 -0
  42. package/dist/services/Repository/dsl.js +55 -0
  43. package/dist/services/Repository/ext.d.ts +324 -0
  44. package/dist/services/Repository/ext.d.ts.map +1 -0
  45. package/dist/services/Repository/ext.js +180 -0
  46. package/dist/services/Repository/service.d.ts +10 -0
  47. package/dist/services/Repository/service.d.ts.map +1 -0
  48. package/dist/services/Repository/service.js +2 -0
  49. package/dist/services/Repository.d.ts +3 -363
  50. package/dist/services/Repository.d.ts.map +1 -1
  51. package/dist/services/Repository.js +4 -217
  52. package/dist/services/RepositoryBase.d.ts +241 -6
  53. package/dist/services/RepositoryBase.d.ts.map +1 -1
  54. package/dist/services/RepositoryBase.js +164 -48
  55. package/dist/services/RequestContextContainer.js +14 -15
  56. package/dist/services/Store/ContextMapContainer.js +10 -11
  57. package/dist/services/Store/codeFilter.js +3 -3
  58. package/dist/services/Store/utils.js +10 -11
  59. package/dist/services/simpledb/cosmosdb.d.ts +2 -2
  60. package/dist/services/simpledb/diskdb.d.ts +1 -1
  61. package/dist/services/simpledb/diskdb.js +2 -3
  62. package/dist/services/simpledb/memdb.d.ts +1 -1
  63. package/dist/services/simpledb/redisdb.d.ts +5 -5
  64. package/dist/services/simpledb/shared.d.ts +5 -5
  65. package/dist/services/simpledb/simpledb.d.ts +2 -2
  66. package/dist/services/simpledb/simpledb.js +5 -6
  67. package/package.json +37 -7
@@ -1,815 +1,3 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
- // Update = Must return updated items
3
- // Modify = Must `set` updated items, and can return anything.
4
- import type { FixEnv, PureLogT } from "@effect-app/prelude/Pure"
5
- import { Pure } from "@effect-app/prelude/Pure"
6
- import type { InvalidStateError, OptimisticConcurrencyException } from "../errors.js"
7
- import { NotFoundError } from "../errors.js"
8
- import type { Filter, PersistenceModelType } from "../services/Store.js"
9
- import type { RepositoryBaseC } from "./RepositoryBase.js"
10
- import type { QueryBuilder } from "./Store/filterApi/query.js"
11
-
12
- /**
13
- * @tsplus type Repository
14
- */
15
- export interface Repository<
16
- T extends { id: unknown },
17
- PM extends PersistenceModelType<string>,
18
- Evt,
19
- ItemType extends string
20
- > extends RepositoryBaseC<T, PM, Evt, ItemType> {}
21
-
22
- export interface PureDSL<S, S2, W> {
23
- get: ReturnType<typeof Pure.get<S>>
24
- set: typeof Pure.set<S2>
25
- log: (...w: W[]) => PureLogT<W>
26
- }
27
-
28
- export const AnyPureDSL: PureDSL<any, any, any> = {
29
- get: Pure.get(),
30
- set: Pure.set,
31
- log: (...evt: any[]) => Pure.logMany(evt)
32
- }
33
-
34
- /**
35
- * @tsplus fluent Repository get
36
- */
37
- export function get<
38
- T extends { id: unknown },
39
- PM extends PersistenceModelType<string>,
40
- Evt,
41
- ItemType extends string
42
- >(
43
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
44
- id: T["id"]
45
- ) {
46
- return self
47
- .find(id)
48
- .flatMap((_) => _.encaseInEffect(() => new NotFoundError<ItemType>({ type: self.itemType, id })))
49
- }
50
-
51
- /**
52
- * @tsplus getter Repository log
53
- */
54
- export function log<
55
- T extends { id: unknown },
56
- PM extends PersistenceModelType<string>,
57
- Evt,
58
- ItemType extends string
59
- >(_: RepositoryBaseC<T, PM, Evt, ItemType>) {
60
- return (evt: Evt) => AnyPureDSL.log(evt)
61
- }
62
-
63
- /**
64
- * TODO: project inside the db.
65
- * @tsplus fluent Repository projectEffect
66
- */
67
- export function projectEffect<
68
- T extends { id: unknown },
69
- PM extends PersistenceModelType<string>,
70
- Evt,
71
- ItemType extends string,
72
- R,
73
- E,
74
- S = PM
75
- >(
76
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
77
- map: Effect<
78
- {
79
- filter?: Filter<PM> | undefined
80
- collect?: ((t: PM) => Option<S>) | undefined
81
- limit?: number | undefined
82
- skip?: number | undefined
83
- },
84
- E,
85
- R
86
- >
87
- ): Effect<S[], E, R>
88
- export function projectEffect<
89
- T extends { id: unknown },
90
- PM extends PersistenceModelType<string>,
91
- Evt,
92
- ItemType extends string,
93
- R,
94
- E,
95
- U extends keyof PM,
96
- S = PM
97
- >(
98
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
99
- map: Effect<
100
- {
101
- filter?: QueryBuilder<PM> | undefined
102
- collect?: ((t: PM) => Option<S>) | undefined
103
- limit?: number | undefined
104
- skip?: number | undefined
105
- },
106
- E,
107
- R
108
- >
109
- ): Effect<Pick<PM, U>[], E, R>
110
- export function projectEffect<
111
- T extends { id: unknown },
112
- PM extends PersistenceModelType<string>,
113
- Evt,
114
- ItemType extends string,
115
- R,
116
- E,
117
- U extends keyof PM,
118
- S = Pick<PM, U>
119
- >(
120
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
121
- map: Effect<
122
- {
123
- filter?: Filter<PM> | undefined
124
- select?: NonEmptyReadonlyArray<U> | undefined
125
- collect?: ((t: PM) => Option<S>) | undefined
126
- limit?: number | undefined
127
- skip?: number | undefined
128
- },
129
- E,
130
- R
131
- >
132
- ): Effect<S[], E, R> {
133
- // TODO: a projection that gets sent to the db instead.
134
- return map.flatMap((f) =>
135
- self
136
- .utils
137
- .filter(f)
138
- .map((_) => f.collect ? _.filterMap(f.collect) : _ as unknown as S[])
139
- )
140
- }
141
-
142
- /**
143
- * TODO: project inside the db.
144
- * @tsplus fluent Repository project
145
- */
146
- export function project<
147
- T extends { id: unknown },
148
- PM extends PersistenceModelType<string>,
149
- Evt,
150
- ItemType extends string,
151
- S = PM
152
- >(
153
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
154
- map: {
155
- filter?: Filter<PM>
156
- collect?: (t: PM) => Option<S>
157
- limit?: number
158
- skip?: number
159
- }
160
- ): Effect<S[]>
161
- export function project<
162
- T extends { id: unknown },
163
- PM extends PersistenceModelType<string>,
164
- Evt,
165
- ItemType extends string,
166
- U extends keyof PM
167
- >(
168
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
169
- map: {
170
- filter?: QueryBuilder<PM>
171
- select: NonEmptyReadonlyArray<U>
172
- limit?: number
173
- skip?: number
174
- }
175
- ): Effect<Pick<PM, U>[]>
176
- export function project<
177
- T extends { id: unknown },
178
- PM extends PersistenceModelType<string>,
179
- Evt,
180
- ItemType extends string,
181
- U extends keyof PM,
182
- S = Pick<PM, U>
183
- >(
184
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
185
- map: {
186
- filter?: Filter<PM>
187
- select?: NonEmptyReadonlyArray<U>
188
- collect?: (t: Pick<PM, U>) => Option<S>
189
- limit?: number
190
- skip?: number
191
- }
192
- ): Effect<S[]> {
193
- return self.projectEffect(Effect.sync(() => map))
194
- }
195
-
196
- /**
197
- * TODO: count inside the db.
198
- * @tsplus fluent Repository project
199
- */
200
- export function count<
201
- T extends { id: unknown },
202
- PM extends PersistenceModelType<string>,
203
- Evt,
204
- ItemType extends string
205
- >(
206
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
207
- filter?: Filter<PM>
208
- ) {
209
- return self
210
- .projectEffect(Effect.sync(() => ({ filter })))
211
- .map((_) => NonNegativeInt(_.length))
212
- }
213
-
214
- /**
215
- * @tsplus fluent Repository queryEffect
216
- */
217
- export function queryEffect<
218
- T extends { id: unknown },
219
- PM extends PersistenceModelType<string>,
220
- Evt,
221
- ItemType extends string,
222
- R,
223
- E,
224
- S = T
225
- >(
226
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
227
- // TODO: think about collectPM, collectE, and collect(Parsed)
228
- map: Effect<{ filter?: Filter<PM>; collect?: (t: T) => Option<S>; limit?: number; skip?: number }, E, R>
229
- ) {
230
- return map.flatMap((f) =>
231
- (f.filter ? self.utils.filter(f) : self.utils.all)
232
- .flatMap((_) => self.utils.parseMany(_))
233
- .map((_) => f.collect ? _.filterMap(f.collect) : _ as any as S[])
234
- )
235
- }
236
-
237
- /**
238
- * @tsplus fluent Repository queryOneEffect
239
- */
240
- export function queryOneEffect<
241
- T extends { id: unknown },
242
- PM extends PersistenceModelType<string>,
243
- Evt,
244
- ItemType extends string,
245
- R,
246
- E
247
- >(
248
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
249
- // TODO: think about collectPM, collectE, and collect(Parsed)
250
- map: Effect<{ filter?: Filter<PM> }, E, R>
251
- ): Effect<T, E | NotFoundError<ItemType>, R>
252
- export function queryOneEffect<
253
- T extends { id: unknown },
254
- PM extends PersistenceModelType<string>,
255
- Evt,
256
- ItemType extends string,
257
- R,
258
- E,
259
- S = T
260
- >(
261
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
262
- // TODO: think about collectPM, collectE, and collect(Parsed)
263
- map: Effect<{ filter?: Filter<PM>; collect: (t: T) => Option<S> }, E, R>
264
- ): Effect<S, E | NotFoundError<ItemType>, R>
265
- export function queryOneEffect<
266
- T extends { id: unknown },
267
- PM extends PersistenceModelType<string>,
268
- Evt,
269
- ItemType extends string,
270
- R,
271
- E,
272
- S = T
273
- >(
274
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
275
- // TODO: think about collectPM, collectE, and collect(Parsed)
276
- map: Effect<{ filter?: Filter<PM>; collect?: (t: T) => Option<S> }, E, R>
277
- ): Effect<S, E | NotFoundError<ItemType>, R> {
278
- return map.flatMap((f) =>
279
- (f.filter ? self.utils.filter({ filter: f.filter, limit: 1 }) : self.utils.all)
280
- .flatMap((_) => self.utils.parseMany(_))
281
- .flatMap((_) =>
282
- (f.collect ? _.filterMap(f.collect) : _ as any as S[])
283
- .toNonEmpty
284
- .encaseInEffect(() => new NotFoundError<ItemType>({ type: self.itemType, id: f.filter }))
285
- .map((_) => _[0])
286
- )
287
- )
288
- }
289
-
290
- /**
291
- * @tsplus fluent Repository query
292
- */
293
- export function query<
294
- T extends { id: unknown },
295
- PM extends PersistenceModelType<string>,
296
- Evt,
297
- ItemType extends string,
298
- S = T
299
- >(
300
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
301
- // TODO: think about collectPM, collectE, and collect(Parsed)
302
- map: { filter?: Filter<PM>; collect?: (t: T) => Option<S>; limit?: number; skip?: number }
303
- ) {
304
- return self.queryEffect(Effect.sync(() => map))
305
- }
306
-
307
- /**
308
- * @tsplus fluent Repository queryOne
309
- */
310
- export function queryOne<
311
- T extends { id: unknown },
312
- PM extends PersistenceModelType<string>,
313
- Evt,
314
- ItemType extends string,
315
- S = T
316
- >(
317
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
318
- map: { filter?: Filter<PM>; collect: (t: T) => Option<S> }
319
- ): Effect<S, NotFoundError<ItemType>>
320
- export function queryOne<
321
- T extends { id: unknown },
322
- PM extends PersistenceModelType<string>,
323
- Evt,
324
- ItemType extends string
325
- >(
326
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
327
- map: { filter?: Filter<PM> }
328
- ): Effect<T, NotFoundError<ItemType>>
329
- export function queryOne<
330
- T extends { id: unknown },
331
- PM extends PersistenceModelType<string>,
332
- Evt,
333
- ItemType extends string,
334
- S = T
335
- >(
336
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
337
- map: { filter?: Filter<PM>; collect?: (t: T) => Option<S> }
338
- ) {
339
- return self.queryOneEffect(Effect.sync(() => map))
340
- }
341
-
342
- /**
343
- * @tsplus fluent Repository queryAndSaveOnePureEffect
344
- */
345
- export function queryAndSaveOnePureEffect<
346
- T extends { id: unknown },
347
- PM extends PersistenceModelType<string>,
348
- Evt,
349
- ItemType extends string,
350
- R,
351
- E,
352
- S extends T = T
353
- >(
354
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
355
- map: Effect<{ filter: Filter<PM>; collect: (t: T) => Option<S>; limit?: number; skip?: number }, E, R>
356
- ): <R2, A, E2, S2 extends T>(
357
- pure: Effect<A, E2, FixEnv<R2, Evt, S, S2>>
358
- ) => Effect<
359
- A,
360
- InvalidStateError | OptimisticConcurrencyException | E | E2 | NotFoundError<ItemType>,
361
- | R
362
- | Exclude<R2, {
363
- env: PureEnv<Evt, S, S2>
364
- }>
365
- >
366
- export function queryAndSaveOnePureEffect<
367
- T extends { id: unknown },
368
- PM extends PersistenceModelType<string>,
369
- Evt,
370
- ItemType extends string,
371
- R,
372
- E
373
- >(
374
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
375
- map: Effect<{ filter: Filter<PM> }, E, R>
376
- ): <R2, A, E2, T2 extends T>(
377
- pure: Effect<A, E2, FixEnv<R2, Evt, T, T2>>
378
- ) => Effect<
379
- A,
380
- InvalidStateError | OptimisticConcurrencyException | E | E2 | NotFoundError<ItemType>,
381
- | R
382
- | Exclude<R2, {
383
- env: PureEnv<Evt, T, T2>
384
- }>
385
- >
386
- export function queryAndSaveOnePureEffect(
387
- self: any,
388
- map: any
389
- ) {
390
- return (pure: any) =>
391
- queryOneEffect(self, map)
392
- .flatMap((_) => saveWithPure_(self, _, pure))
393
- }
394
-
395
- /**
396
- * @tsplus fluent Repository queryAndSaveOnePure
397
- */
398
- export function queryAndSaveOnePure<
399
- T extends { id: unknown },
400
- PM extends PersistenceModelType<string>,
401
- Evt,
402
- ItemType extends string,
403
- S extends T = T
404
- >(
405
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
406
- map: { filter: Filter<PM>; collect: (t: T) => Option<S>; limit?: number; skip?: number }
407
- ): <R2, A, E2, S2>(pure: Effect<A, E2, FixEnv<R2, Evt, S, S2>>) => Effect<
408
- A,
409
- InvalidStateError | OptimisticConcurrencyException | E2 | NotFoundError<ItemType>,
410
- Exclude<R2, {
411
- env: PureEnv<Evt, S, S2>
412
- }>
413
- >
414
- export function queryAndSaveOnePure<
415
- T extends { id: unknown },
416
- PM extends PersistenceModelType<string>,
417
- Evt,
418
- ItemType extends string
419
- >(
420
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
421
- map: { filter: Filter<PM> }
422
- ): <R2, A, E2, T2>(pure: Effect<A, E2, FixEnv<R2, Evt, T, T2>>) => Effect<
423
- A,
424
- InvalidStateError | OptimisticConcurrencyException | E2 | NotFoundError<ItemType>,
425
- Exclude<R2, {
426
- env: PureEnv<Evt, T, T2>
427
- }>
428
- >
429
- export function queryAndSaveOnePure(
430
- self: any,
431
- map: { filter: Filter<any>; collect?: any }
432
- ) {
433
- return queryAndSaveOnePureEffect(self, Effect.sync(() => map))
434
- }
435
-
436
- /**
437
- * @tsplus fluent Repository queryAndSavePureEffect
438
- */
439
- export function queryAndSavePureEffect<
440
- T extends { id: unknown },
441
- PM extends PersistenceModelType<string>,
442
- Evt,
443
- ItemType extends string,
444
- R,
445
- E,
446
- S extends T = T
447
- >(
448
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
449
- map: Effect<{ filter: Filter<PM>; collect?: (t: T) => Option<S>; limit?: number; skip?: number }, E, R>
450
- ) {
451
- return <R2, A, E2, S2 extends T>(pure: Effect<A, E2, FixEnv<R2, Evt, S[], S2[]>>) =>
452
- queryEffect(self, map)
453
- .flatMap((_) => self.saveManyWithPure_(_, pure))
454
- }
455
-
456
- /**
457
- * @tsplus fluent Repository queryAndSavePure
458
- */
459
- export function queryAndSavePure<
460
- T extends { id: unknown },
461
- PM extends PersistenceModelType<string>,
462
- Evt,
463
- ItemType extends string,
464
- S extends T = T
465
- >(
466
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
467
- map: { filter: Filter<PM>; collect?: (t: T) => Option<S>; limit?: number; skip?: number }
468
- ) {
469
- return self.queryAndSavePureEffect(Effect.sync(() => map))
470
- }
471
-
472
- /**
473
- * @tsplus getter Repository saveManyWithPure
474
- */
475
- export function saveManyWithPure<
476
- T extends { id: unknown },
477
- PM extends PersistenceModelType<string>,
478
- Evt,
479
- ItemType extends string
480
- >(self: RepositoryBaseC<T, PM, Evt, ItemType>) {
481
- return <R, A, E, S1 extends T, S2 extends T>(pure: Effect<A, E, FixEnv<R, Evt, S1[], S2[]>>) =>
482
- (items: Iterable<S1>) => saveManyWithPure_(self, items, pure)
483
- }
484
-
485
- /**
486
- * @tsplus fluent Repository byIdAndSaveWithPure
487
- */
488
- export function byIdAndSaveWithPure<
489
- T extends { id: unknown },
490
- PM extends PersistenceModelType<string>,
491
- Evt,
492
- ItemType extends string
493
- >(self: RepositoryBaseC<T, PM, Evt, ItemType>, id: T["id"]) {
494
- return <R, A, E, S2 extends T>(pure: Effect<A, E, FixEnv<R, Evt, T, S2>>) =>
495
- get(self, id).flatMap((item) => saveWithPure_(self, item, pure))
496
- }
497
-
498
- /**
499
- * NOTE: it's not as composable, only useful when the request is simple, and only this part needs request args.
500
- * @tsplus getter Repository handleByIdAndSaveWithPure
501
- */
502
- export function handleByIdAndSaveWithPure<
503
- T extends { id: unknown },
504
- PM extends PersistenceModelType<string>,
505
- Evt,
506
- ItemType extends string
507
- >(self: RepositoryBaseC<T, PM, Evt, ItemType>) {
508
- return <Req extends { id: T["id"] }, Context, R, A, E, S2 extends T>(
509
- pure: (req: Req, ctx: Context) => Effect<A, E, FixEnv<R, Evt, T, S2>>
510
- ) =>
511
- (req: Req, ctx: Context) => byIdAndSaveWithPure(self, req.id)(pure(req, ctx))
512
- }
513
-
514
- /**
515
- * @tsplus fluent Repository saveManyWithPure_
516
- */
517
- export function saveManyWithPure_<
518
- R,
519
- T extends { id: unknown },
520
- PM extends PersistenceModelType<string>,
521
- A,
522
- E,
523
- Evt,
524
- S1 extends T,
525
- S2 extends T,
526
- ItemType extends string
527
- >(
528
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
529
- items: Iterable<S1>,
530
- pure: Effect<A, E, FixEnv<R, Evt, S1[], S2[]>>
531
- ) {
532
- return saveAllWithEffectInt(
533
- self,
534
- pure.runTerm([...items])
535
- )
536
- }
537
-
538
- /**
539
- * @tsplus fluent Repository saveWithPure_
540
- */
541
- export function saveWithPure_<
542
- R,
543
- T extends { id: unknown },
544
- PM extends PersistenceModelType<string>,
545
- A,
546
- E,
547
- Evt,
548
- S1 extends T,
549
- S2 extends T,
550
- ItemType extends string
551
- >(
552
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
553
- item: S1,
554
- pure: Effect<A, E, FixEnv<R, Evt, S1, S2>>
555
- ) {
556
- return saveAllWithEffectInt(
557
- self,
558
- pure
559
- .runTerm(item)
560
- .map(([item, events, a]) => [[item], events, a])
561
- )
562
- }
563
-
564
- export function saveAllWithEffectInt<
565
- T extends { id: unknown },
566
- PM extends PersistenceModelType<string>,
567
- P extends T,
568
- Evt,
569
- ItemType extends string,
570
- R,
571
- E,
572
- A
573
- >(
574
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
575
- gen: Effect<readonly [Iterable<P>, Iterable<Evt>, A], E, R>
576
- ) {
577
- return gen
578
- .flatMap(
579
- ([items, events, a]) => self.saveAndPublish(items, events).map(() => a)
580
- )
581
- }
582
-
583
- /**
584
- * @tsplus fluent Repository queryAndSavePureEffectBatched
585
- */
586
- export function queryAndSavePureEffectBatched<
587
- T extends { id: unknown },
588
- PM extends PersistenceModelType<string>,
589
- Evt,
590
- ItemType extends string,
591
- R,
592
- E,
593
- S extends T = T
594
- >(
595
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
596
- // TODO: think about collectPM, collectE, and collect(Parsed)
597
- map: Effect<{ filter: Filter<PM>; collect?: (t: T) => Option<S>; limit?: number; skip?: number }, E, R>,
598
- batchSize = 100
599
- ) {
600
- return <R2, A, E2, S2 extends T>(pure: Effect<A, E2, FixEnv<R2, Evt, S[], S2[]>>) =>
601
- queryEffect(self, map)
602
- .flatMap((_) => self.saveManyWithPureBatched_(_, pure, batchSize))
603
- }
604
-
605
- /**
606
- * @tsplus fluent Repository queryAndSavePureBatched
607
- */
608
- export function queryAndSavePureBatched<
609
- T extends { id: unknown },
610
- PM extends PersistenceModelType<string>,
611
- Evt,
612
- ItemType extends string,
613
- S extends T = T
614
- >(
615
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
616
- // TODO: think about collectPM, collectE, and collect(Parsed)
617
- map: { filter: Filter<PM>; collect?: (t: T) => Option<S>; limit?: number; skip?: number },
618
- batchSize = 100
619
- ) {
620
- return self.queryAndSavePureEffectBatched(Effect.sync(() => map), batchSize)
621
- }
622
-
623
- /**
624
- * @tsplus fluent Repository saveManyWithPureBatched
625
- */
626
- export function saveManyWithPureBatched<
627
- T extends { id: unknown },
628
- PM extends PersistenceModelType<string>,
629
- Evt,
630
- ItemType extends string
631
- >(self: RepositoryBaseC<T, PM, Evt, ItemType>, batchSize = 100) {
632
- return <R, A, E, S1 extends T, S2 extends T>(pure: Effect<A, E, FixEnv<R, Evt, S1[], S2[]>>) =>
633
- (items: Iterable<S1>) => saveManyWithPureBatched_(self, items, pure, batchSize)
634
- }
635
-
636
- /**
637
- * @tsplus fluent Repository saveManyWithPureBatched_
638
- */
639
- export function saveManyWithPureBatched_<
640
- R,
641
- T extends { id: unknown },
642
- PM extends PersistenceModelType<string>,
643
- A,
644
- E,
645
- Evt,
646
- S1 extends T,
647
- S2 extends T,
648
- ItemType extends string
649
- >(
650
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
651
- items: Iterable<S1>,
652
- pure: Effect<A, E, FixEnv<R, Evt, S1[], S2[]>>,
653
- batchSize = 100
654
- ) {
655
- return items
656
- .chunk(batchSize)
657
- .forEachEffect((batch) =>
658
- saveAllWithEffectInt(
659
- self,
660
- pure.runTerm(batch)
661
- )
662
- )
663
- }
664
-
665
- const anyDSL = makeDSL<any, any, any>()
666
-
667
- export type AllDSL<T, Evt> =
668
- & (<R, A, E, S1 extends T, S2 extends T>(
669
- pure: (dsl: PureDSL<S1[], S2[], Evt>) => Effect<A, E, R>
670
- ) => Effect<A, E, FixEnv<R, Evt, S1[], S2[]>>)
671
- & AllDSLExt<T, Evt>
672
-
673
- /**
674
- * @tsplus type DSLExt
675
- */
676
- export interface AllDSLExt<T, Evt> {
677
- modify: <R, E, A, S1 extends T, S2 extends T>(
678
- pure: (items: S1[], dsl: PureDSL<S1[], S2[], Evt>) => Effect<A, E, R>
679
- ) => Effect<A, E, FixEnv<R, Evt, S1[], S2[]>>
680
- update: <R, E, S1 extends T, S2 extends T>(
681
- pure: (items: S1[], log: (...evt: Evt[]) => PureLogT<Evt>) => Effect<S2[], E, R>
682
- ) => Effect<S2[], E, FixEnv<R, Evt, S1[], S2[]>>
683
- }
684
-
685
- export function makeAllDSL<T, Evt>() {
686
- const dsl: AllDSL<T, Evt> = anyDSL
687
- return dsl
688
- }
689
-
690
- export type OneDSL<T, Evt> =
691
- & (<R, A, E, S1 extends T, S2 extends T>(
692
- pure: (dsl: PureDSL<S1, S2, Evt>) => Effect<A, E, FixEnv<R, Evt, S1, S2>>
693
- ) => Effect<A, E, FixEnv<R, Evt, S1, S2>>)
694
- & OneDSLExt<T, Evt>
695
-
696
- /**
697
- * @tsplus type DSLExt
698
- */
699
- export interface OneDSLExt<T, Evt> {
700
- modify: <R, E, A, S1 extends T, S2 extends T>(
701
- pure: (items: S1, dsl: PureDSL<S1, S2, Evt>) => Effect<A, E, FixEnv<R, Evt, S1, S2>>
702
- ) => Effect<A, E, FixEnv<R, Evt, S1, S2> | PureEnvEnv<Evt, S1, S1>>
703
- update: <R, E, S1 extends T, S2 extends T>(
704
- pure: (items: S1, log: (...evt: Evt[]) => PureLogT<Evt>) => Effect<S2, E, FixEnv<R, Evt, S1, S2>>
705
- ) => Effect<S2, E, FixEnv<R, Evt, S1, S2>>
706
- }
707
-
708
- /**
709
- * @tsplus fluent DSLExt updateWith
710
- */
711
- export function updateWithOne<T, Evt, S1 extends T, S2 extends T>(self: OneDSL<T, Evt>, upd: (item: S1) => S2) {
712
- return self.update((_: S1) => Effect.sync(() => upd(_)))
713
- }
714
-
715
- /**
716
- * @tsplus fluent DSLExt updateWith
717
- */
718
- export function updateWith<T, Evt, S1 extends T, S2 extends T>(
719
- self: AllDSL<T, Evt>,
720
- upd: (item: S1[]) => S2[]
721
- ) {
722
- return self.update((_: S1[]) => Effect.sync(() => upd(_)))
723
- }
724
-
725
- export function makeOneDSL<T, Evt>(): OneDSL<T, Evt> {
726
- return anyDSL
727
- }
728
-
729
- export function makeDSL<S1, S2, Evt>() {
730
- const dsl: PureDSL<S1, S2, Evt> = AnyPureDSL
731
-
732
- function modify<
733
- R,
734
- E,
735
- A
736
- >(
737
- pure: (
738
- items: S1,
739
- dsl: PureDSL<S1, S2, Evt>
740
- ) => Effect<A, E, R>
741
- ): Effect<A, E, FixEnv<R, Evt, S1, S2>> {
742
- return dsl.get.flatMap((items) => pure(items, dsl)) as any
743
- }
744
-
745
- function update<
746
- R,
747
- E
748
- >(
749
- pure: (
750
- items: S1,
751
- log: (...evt: Evt[]) => PureLogT<Evt>
752
- ) => Effect<S2, E, R>
753
- ): Effect<S2, E, FixEnv<R, Evt, S1, S2>> {
754
- return dsl.get.flatMap((items) => pure(items, dsl.log).tap(dsl.set)) as any
755
- }
756
-
757
- function withDSL<
758
- R,
759
- A,
760
- E
761
- >(
762
- pure: (dsl: PureDSL<S1, S2, Evt>) => Effect<A, E, R>
763
- ): Effect<A, E, FixEnv<R, Evt, S1, S2>> {
764
- return pure(AnyPureDSL) as any
765
- }
766
-
767
- return Object.assign(
768
- withDSL,
769
- {
770
- modify,
771
- update
772
- }
773
- )
774
- }
775
-
776
- export interface DSLExt<S1, S2, Evt> extends ReturnType<typeof makeDSL<S1, S2, Evt>> {}
777
-
778
- export function ifAny<T, R, E, A>(fn: (items: NonEmptyReadonlyArray<T>) => Effect<A, E, R>) {
779
- return (items: Iterable<T>) => Effect.sync(() => items.toNonEmptyArray).flatMapOpt(fn)
780
- }
781
-
782
- /**
783
- * @tsplus fluent Iterable ifAny
784
- */
785
- export function ifAny_<T, R, E, A>(items: Iterable<T>, fn: (items: NonEmptyReadonlyArray<T>) => Effect<A, E, R>) {
786
- return Effect.sync(() => items.toNonEmptyArray).flatMapOpt(fn)
787
- }
788
-
789
- /**
790
- * @tsplus getter Repository save
791
- */
792
- export function save<
793
- T extends { id: unknown },
794
- PM extends PersistenceModelType<string>,
795
- Evt,
796
- ItemType extends string
797
- >(
798
- self: RepositoryBaseC<T, PM, Evt, ItemType>
799
- ) {
800
- return (...items: NonEmptyArray<T>) => self.saveAndPublish(items)
801
- }
802
-
803
- /**
804
- * @tsplus getter Repository saveWithEvents
805
- */
806
- export function saveWithEvents<
807
- T extends { id: unknown },
808
- PM extends PersistenceModelType<string>,
809
- Evt,
810
- ItemType extends string
811
- >(
812
- self: RepositoryBaseC<T, PM, Evt, ItemType>
813
- ) {
814
- return (events: Iterable<Evt>) => (...items: NonEmptyArray<T>) => self.saveAndPublish(items, events)
815
- }
1
+ export * from "./Repository/dsl.js"
2
+ export * from "./Repository/ext.js"
3
+ export * from "./Repository/service.js"