@effect-app/infra 2.9.5 → 2.11.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 (42) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/_cjs/Emailer/Sendgrid.cjs +1 -1
  3. package/_cjs/Emailer/Sendgrid.cjs.map +1 -1
  4. package/_cjs/Emailer/service.cjs.map +1 -1
  5. package/_cjs/Model/Repository/internal/internal.cjs +247 -0
  6. package/_cjs/Model/Repository/internal/internal.cjs.map +1 -0
  7. package/_cjs/Model/Repository/legacy.cjs +0 -139
  8. package/_cjs/Model/Repository/legacy.cjs.map +1 -1
  9. package/_cjs/Model/Repository/makeRepo.cjs +2 -241
  10. package/_cjs/Model/Repository/makeRepo.cjs.map +1 -1
  11. package/_cjs/Store/Cosmos.cjs +1 -1
  12. package/_cjs/Store/Cosmos.cjs.map +1 -1
  13. package/_cjs/Store/index.cjs +1 -1
  14. package/_cjs/Store/index.cjs.map +1 -1
  15. package/dist/Emailer/Sendgrid.js +3 -3
  16. package/dist/Emailer/service.d.ts +3 -2
  17. package/dist/Emailer/service.d.ts.map +1 -1
  18. package/dist/Emailer/service.js +1 -1
  19. package/dist/Model/Repository/internal/internal.d.ts +66 -0
  20. package/dist/Model/Repository/internal/internal.d.ts.map +1 -0
  21. package/dist/Model/Repository/internal/internal.js +247 -0
  22. package/dist/Model/Repository/legacy.d.ts +2 -186
  23. package/dist/Model/Repository/legacy.d.ts.map +1 -1
  24. package/dist/Model/Repository/legacy.js +2 -123
  25. package/dist/Model/Repository/makeRepo.d.ts +3 -68
  26. package/dist/Model/Repository/makeRepo.d.ts.map +1 -1
  27. package/dist/Model/Repository/makeRepo.js +3 -247
  28. package/dist/Operations.d.ts +3 -3
  29. package/dist/Store/Cosmos.d.ts.map +1 -1
  30. package/dist/Store/Cosmos.js +3 -3
  31. package/dist/Store/index.js +3 -3
  32. package/dist/Store/service.d.ts +2 -2
  33. package/dist/Store/service.d.ts.map +1 -1
  34. package/package.json +10 -10
  35. package/src/Emailer/Sendgrid.ts +2 -2
  36. package/src/Emailer/service.ts +3 -2
  37. package/src/Model/Repository/internal/internal.ts +481 -0
  38. package/src/Model/Repository/legacy.ts +2 -536
  39. package/src/Model/Repository/makeRepo.ts +4 -481
  40. package/src/Store/Cosmos.ts +2 -2
  41. package/src/Store/index.ts +2 -2
  42. package/src/Store/service.ts +2 -2
@@ -1,541 +1,7 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
  /* eslint-disable @typescript-eslint/no-unsafe-assignment */
3
- import type { NonEmptyReadonlyArray, Option, ParseResult, S } from "effect-app"
4
- import { Context, Effect, Layer } from "effect-app"
5
- import type { InvalidStateError, NotFoundError, OptimisticConcurrencyException } from "effect-app/client"
6
- import type { FixEnv, PureEnv } from "effect-app/Pure"
7
- import type { NonNegativeInt } from "effect-app/Schema"
8
- import type { StoreConfig, StoreMaker } from "../../Store.js"
9
- import type { FieldValues } from "../filter/types.js"
10
- import * as Q from "../query.js"
11
- import type { ExtendedRepository } from "./ext.js"
12
- import { extendRepo } from "./ext.js"
13
- import type { Repos } from "./makeRepo.js"
14
- import { makeRepoInternal } from "./makeRepo.js"
15
- import type { RefineTHelper, Repository } from "./service.js"
16
-
17
- const names = new Map<string, number>()
18
- const registerName = (name: string) => {
19
- const existing = names.get(name)
20
- if (existing === undefined) {
21
- names.set(name, 1)
22
- return name
23
- } else {
24
- const n = existing + 1
25
- names.set(name, n)
26
- return name + "-" + existing
27
- }
28
- }
29
-
30
- /**
31
- * @deprecated
32
- */
33
- export interface RepoFunctions<
34
- T,
35
- Encoded extends { id: string },
36
- Evt,
37
- ItemType,
38
- IdKey extends keyof T,
39
- RSchema,
40
- RPublish,
41
- Service
42
- > {
43
- itemType: ItemType
44
- T: T
45
- all: Effect<readonly T[], never, RSchema | Service>
46
- find: (id: T[IdKey]) => Effect<Option<T>, never, RSchema | Service>
47
- removeById: (id: T[IdKey]) => Effect<void, NotFoundError<ItemType>, RSchema | Service>
48
- saveAndPublish: (
49
- items: Iterable<T>,
50
- events?: Iterable<Evt>
51
- ) => Effect<void, InvalidStateError | OptimisticConcurrencyException, RSchema | RPublish | Service>
52
- removeAndPublish: (
53
- items: Iterable<T>,
54
- events?: Iterable<Evt>
55
- ) => Effect<void, never, RSchema | Service>
56
- save: (...items: T[]) => Effect<void, InvalidStateError | OptimisticConcurrencyException, RSchema | Service>
57
- get: (id: T[IdKey]) => Effect<T, NotFoundError<ItemType>, RSchema | RPublish | Service>
58
- queryAndSavePure: {
59
- <A, E2, R2, T2 extends T>(
60
- q: (
61
- q: Q.Query<Encoded>
62
- ) => Q.QueryEnd<Encoded, "one">,
63
- pure: Effect<A, E2, FixEnv<R2, Evt, T, T2>>
64
- ): Effect.Effect<
65
- A,
66
- InvalidStateError | OptimisticConcurrencyException | NotFoundError<ItemType> | E2,
67
- | RSchema
68
- | RPublish
69
- | Service
70
- | Exclude<R2, {
71
- env: PureEnv<Evt, T, T2>
72
- }>
73
- >
74
- <A, E2, R2, T2 extends T>(
75
- q: (
76
- q: Q.Query<Encoded>
77
- ) =>
78
- | Q.Query<Encoded>
79
- | Q.QueryWhere<Encoded>
80
- | Q.QueryEnd<Encoded, "many">,
81
- pure: Effect<A, E2, FixEnv<R2, Evt, readonly T[], readonly T2[]>>
82
- ): Effect.Effect<
83
- A,
84
- InvalidStateError | OptimisticConcurrencyException | E2,
85
- | RSchema
86
- | RPublish
87
- | Service
88
- | Exclude<R2, {
89
- env: PureEnv<Evt, readonly T[], readonly T2[]>
90
- }>
91
- >
92
- <A, E2, R2, T2 extends T>(
93
- q: (
94
- q: Q.Query<Encoded>
95
- ) =>
96
- | Q.Query<Encoded>
97
- | Q.QueryWhere<Encoded>
98
- | Q.QueryEnd<Encoded, "many">,
99
- pure: Effect<A, E2, FixEnv<R2, Evt, readonly T[], readonly T2[]>>,
100
- batch: "batched" | number
101
- ): Effect.Effect<
102
- A[],
103
- InvalidStateError | OptimisticConcurrencyException | E2,
104
- | RSchema
105
- | RPublish
106
- | Service
107
- | Exclude<R2, {
108
- env: PureEnv<Evt, readonly T[], readonly T2[]>
109
- }>
110
- >
111
- }
112
- readonly query: {
113
- <A, R, From extends FieldValues, TType extends "one" | "many" | "count" = "many">(
114
- q: (
115
- initial: Q.Query<Encoded>
116
- ) => Q.QueryProjection<Encoded extends From ? From : never, A, R, TType>
117
- ): Effect.Effect<
118
- TType extends "many" ? readonly A[] : TType extends "count" ? NonNegativeInt : A,
119
- | (TType extends "many" ? never : NotFoundError<ItemType>)
120
- | (TType extends "count" ? never : S.ParseResult.ParseError),
121
- R | RSchema | Service
122
- >
123
- <
124
- R = never,
125
- TType extends "one" | "many" = "many",
126
- EncodedRefined extends Encoded = Encoded
127
- >(
128
- q: (
129
- initial: Q.Query<Encoded>
130
- ) => Q.QAll<Encoded, EncodedRefined, RefineTHelper<T, EncodedRefined>, R, TType>
131
- ): Effect.Effect<
132
- TType extends "many" ? readonly RefineTHelper<T, EncodedRefined>[] : RefineTHelper<T, EncodedRefined>,
133
- TType extends "many" ? never : NotFoundError<ItemType>,
134
- R | RSchema | Service
135
- >
136
- }
137
- byIdAndSaveWithPure: {
138
- <R, A, E, S2 extends T>(
139
- id: T[IdKey],
140
- pure: Effect<A, E, FixEnv<R, Evt, T, S2>>
141
- ): Effect<
142
- A,
143
- InvalidStateError | OptimisticConcurrencyException | E | NotFoundError<ItemType>,
144
- | RSchema
145
- | RPublish
146
- | Service
147
- | Exclude<R, {
148
- env: PureEnv<Evt, T, S2>
149
- }>
150
- >
151
- }
152
- saveManyWithPure: {
153
- <R, A, E, S1 extends T, S2 extends T>(
154
- items: Iterable<S1>,
155
- pure: Effect<A, E, FixEnv<R, Evt, readonly S1[], readonly S2[]>>
156
- ): Effect.Effect<
157
- A,
158
- InvalidStateError | OptimisticConcurrencyException | E,
159
- | RSchema
160
- | RPublish
161
- | Service
162
- | Exclude<R, {
163
- env: PureEnv<Evt, readonly S1[], readonly S2[]>
164
- }>
165
- >
166
- <R, A, E, S1 extends T, S2 extends T>(
167
- items: Iterable<S1>,
168
- pure: Effect<A, E, FixEnv<R, Evt, readonly S1[], readonly S2[]>>,
169
- batch: "batched" | number
170
- ): Effect.Effect<
171
- A[],
172
- InvalidStateError | OptimisticConcurrencyException | E,
173
- | RSchema
174
- | RPublish
175
- | Service
176
- | Exclude<R, {
177
- env: PureEnv<Evt, readonly S1[], readonly S2[]>
178
- }>
179
- >
180
- }
181
- /** @experimental */
182
- mapped: MM<Service, Encoded>
183
- use: <X>(
184
- body: (_: Service) => X
185
- ) => X extends Effect<infer A, infer E, infer R> ? Effect<A, E, R | Service> : Effect<X, never, Service>
186
- }
187
-
188
- /**
189
- * @deprecated
190
- */
191
- const makeRepoFunctions = (tag: any, itemType: any) => {
192
- const { all } = Effect.serviceConstants(tag) as any
193
- const {
194
- byIdAndSaveWithPure,
195
- find,
196
- get,
197
- query,
198
- queryAndSavePure,
199
- removeAndPublish,
200
- removeById,
201
- save,
202
- saveAndPublish,
203
- saveManyWithPure
204
- } = Effect.serviceFunctions(tag) as any
205
- const mapped = (s: any) => Effect.map(tag, (_: any) => _.mapped(s))
206
- return {
207
- itemType,
208
- all,
209
- byIdAndSaveWithPure,
210
- find,
211
- removeById,
212
- saveAndPublish,
213
- removeAndPublish,
214
- save,
215
- get,
216
- query,
217
- mapped,
218
- queryAndSavePure,
219
- saveManyWithPure,
220
- use: (body: any) => Effect.andThen(tag, body)
221
- }
222
- }
223
-
224
- /** @deprecated use makeRepo/extendRepo */
225
- export class RepositoryBase<
226
- T,
227
- Encoded extends { id: string },
228
- Evt,
229
- ItemType extends string,
230
- Ext,
231
- IdKey extends keyof T,
232
- RSchema,
233
- RPublish
234
- > implements ExtendedRepository<T, Encoded, Evt, ItemType, IdKey, RSchema, RPublish> {
235
- constructor(protected readonly impl: ExtendedRepository<T, Encoded, Evt, ItemType, IdKey, RSchema, RPublish> & Ext) {
236
- this.saveAndPublish = this.impl.saveAndPublish
237
- this.removeAndPublish = this.impl.removeAndPublish
238
- this.find = this.impl.find
239
- this.all = this.impl.all
240
- this.changeFeed = this.impl.changeFeed
241
- this.mapped = this.impl.mapped
242
- this.query = this.impl.query
243
- this.get = this.impl.get
244
- this.itemType = this.impl.itemType
245
- this.idKey = this.impl.idKey
246
- this.log = this.impl.log
247
- this.removeById = this.impl.removeById
248
- this.save = this.impl.save
249
- this.saveWithEvents = this.impl.saveWithEvents
250
- this.queryAndSavePure = this.impl.queryAndSavePure
251
- this.saveManyWithPure = this.impl.saveManyWithPure
252
- this.byIdAndSaveWithPure = this.impl.byIdAndSaveWithPure
253
- this.saveWithPure = this.impl.saveWithPure
254
- this.request = this.impl.request
255
- }
256
- get: (id: T[IdKey]) => Effect<T, NotFoundError<ItemType>, RSchema>
257
- idKey
258
- request
259
- itemType
260
- saveAndPublish
261
- removeAndPublish
262
- find
263
- all
264
- changeFeed
265
- mapped
266
- query
267
- log
268
- removeById
269
- save
270
- saveWithEvents
271
- queryAndSavePure
272
- saveManyWithPure
273
- byIdAndSaveWithPure
274
- saveWithPure
275
- }
276
-
277
- export const RepositoryDefaultImpl2 = <Service, Evt = never>() => {
278
- const f: {
279
- <
280
- ItemType extends string,
281
- RSchema,
282
- Encoded extends { id: string },
283
- T,
284
- IdKey extends keyof T,
285
- E = never,
286
- RInitial = never,
287
- RPublish = never,
288
- Layers extends [Layer.Layer.Any, ...Layer.Layer.Any[]] = [Layer.Layer<never>],
289
- E1 = never,
290
- R1 = never,
291
- // eslint-disable-next-line @typescript-eslint/no-empty-object-type
292
- Ext = {}
293
- >(
294
- itemType: ItemType,
295
- schema: S.Schema<T, Encoded, RSchema>,
296
- options: [Evt] extends [never] ? {
297
- dependencies?: Layers
298
- idKey: IdKey
299
- config?: Omit<StoreConfig<Encoded>, "partitionValue"> & {
300
- partitionValue?: (a: Encoded) => string
301
- }
302
- jitM?: (pm: Encoded) => Encoded
303
- options?: Effect<
304
- {
305
- makeInitial?: Effect<readonly T[], E, RInitial>
306
- ext?: Ext
307
- },
308
- E1,
309
- R1
310
- >
311
- }
312
- : {
313
- dependencies?: Layers
314
- idKey: IdKey
315
- jitM?: (pm: Encoded) => Encoded
316
- config?: Omit<StoreConfig<Encoded>, "partitionValue"> & {
317
- partitionValue?: (a: Encoded) => string
318
- }
319
- options?: Effect<
320
- {
321
- publishEvents: (evt: NonEmptyReadonlyArray<Evt>) => Effect<void, never, RPublish>
322
- makeInitial?: Effect<readonly T[], E, RInitial>
323
- ext?: Ext
324
- },
325
- E1,
326
- R1
327
- >
328
- }
329
- ):
330
- & (abstract new(
331
- impl: Repository<T, Encoded, Evt, ItemType, IdKey, RSchema, RPublish> & Ext
332
- ) => RepositoryBase<T, Encoded, Evt, ItemType, Ext, IdKey, RSchema, RPublish>)
333
- & Context.Tag<Service, Service>
334
- & RepoFunctions<T, Encoded, Evt, ItemType, IdKey, RSchema, RPublish, Service>
335
- & {
336
- Default: Layer.Layer<
337
- Service,
338
- E | E1 | Layer.Layer.Error<Layers[number]>,
339
- Exclude<
340
- R1 | StoreMaker,
341
- { [k in keyof Layers]: Layer.Layer.Success<Layers[k]> }[number]
342
- >
343
- >
344
- DefaultWithoutDependencies: Layer.Layer<
345
- Service,
346
- E1,
347
- R1 | StoreMaker
348
- >
349
- }
350
- & Repos<
351
- T,
352
- Encoded,
353
- RSchema,
354
- Evt,
355
- ItemType,
356
- IdKey,
357
- RPublish
358
- >
359
- <
360
- ItemType extends string,
361
- RSchema,
362
- Encoded extends { id: string },
363
- T extends { id: unknown },
364
- E = never,
365
- RInitial = never,
366
- RPublish = never,
367
- Layers extends [Layer.Layer.Any, ...Layer.Layer.Any[]] = [Layer.Layer<never>],
368
- E1 = never,
369
- R1 = never,
370
- // eslint-disable-next-line @typescript-eslint/no-empty-object-type
371
- Ext = {}
372
- >(
373
- itemType: ItemType,
374
- schema: S.Schema<T, Encoded, RSchema>,
375
- options: [Evt] extends [never] ? {
376
- dependencies?: Layers
377
- config?: Omit<StoreConfig<Encoded>, "partitionValue"> & {
378
- partitionValue?: (a: Encoded) => string
379
- }
380
- jitM?: (pm: Encoded) => Encoded
381
- options?: Effect<
382
- {
383
- makeInitial?: Effect<readonly T[], E, RInitial>
384
- ext?: Ext
385
- },
386
- E1,
387
- R1
388
- >
389
- }
390
- : {
391
- dependencies?: Layers
392
- jitM?: (pm: Encoded) => Encoded
393
- config?: Omit<StoreConfig<Encoded>, "partitionValue"> & {
394
- partitionValue?: (a: Encoded) => string
395
- }
396
- options?: Effect<
397
- {
398
- publishEvents: (evt: NonEmptyReadonlyArray<Evt>) => Effect<void, never, RPublish>
399
- makeInitial?: Effect<readonly T[], E, RInitial>
400
- ext?: Ext
401
- },
402
- E1,
403
- R1
404
- >
405
- }
406
- ):
407
- & (abstract new(
408
- impl: Repository<T, Encoded, Evt, ItemType, "id", RSchema, RPublish> & Ext
409
- ) => RepositoryBase<T, Encoded, Evt, ItemType, Ext, "id", RSchema, RPublish>)
410
- & Context.Tag<Service, Service>
411
- & RepoFunctions<T, Encoded, Evt, ItemType, "id", RSchema, RPublish, Service>
412
- & {
413
- Default: Layer.Layer<
414
- Service,
415
- E | E1 | Layer.Layer.Error<Layers[number]>,
416
- Exclude<
417
- R1 | StoreMaker,
418
- { [k in keyof Layers]: Layer.Layer.Success<Layers[k]> }[number]
419
- >
420
- >
421
- DefaultWithoutDependencies: Layer.Layer<
422
- Service,
423
- E1,
424
- R1 | StoreMaker
425
- >
426
- }
427
- & Repos<
428
- T,
429
- Encoded,
430
- RSchema,
431
- Evt,
432
- ItemType,
433
- "id",
434
- RPublish
435
- >
436
- } = <
437
- ItemType extends string,
438
- RSchema,
439
- Encoded extends { id: string },
440
- T,
441
- IdKey extends keyof T,
442
- E = never,
443
- RInitial = never,
444
- RPublish = never,
445
- Layers extends [Layer.Layer.Any, ...Layer.Layer.Any[]] = [Layer.Layer<never>],
446
- E1 = never,
447
- R1 = never,
448
- // eslint-disable-next-line @typescript-eslint/no-empty-object-type
449
- Ext = {}
450
- >(
451
- itemType: ItemType,
452
- schema: S.Schema<T, Encoded, RSchema>,
453
- options: [Evt] extends [never] ? {
454
- dependencies?: Layers
455
- idKey?: IdKey
456
- config?: Omit<StoreConfig<Encoded>, "partitionValue"> & {
457
- partitionValue?: (a: Encoded) => string
458
- }
459
- jitM?: (pm: Encoded) => Encoded
460
- options?: Effect<
461
- {
462
- makeInitial?: Effect<readonly T[], E, RInitial>
463
- ext?: Ext
464
- },
465
- E1,
466
- R1
467
- >
468
- }
469
- : {
470
- dependencies?: Layers
471
- idKey?: IdKey
472
- jitM?: (pm: Encoded) => Encoded
473
- config?: Omit<StoreConfig<Encoded>, "partitionValue"> & {
474
- partitionValue?: (a: Encoded) => string
475
- }
476
- options?: Effect<
477
- {
478
- publishEvents: (evt: NonEmptyReadonlyArray<Evt>) => Effect<void, never, RPublish>
479
- makeInitial?: Effect<readonly T[], E, RInitial>
480
- ext?: Ext
481
- },
482
- E1,
483
- R1
484
- >
485
- }
486
- ) => {
487
- let layerCache = undefined
488
- let layerCache2 = undefined
489
- abstract class Cls extends RepositoryBase<
490
- T,
491
- Encoded,
492
- Evt,
493
- ItemType,
494
- Ext,
495
- IdKey,
496
- RSchema,
497
- RPublish
498
- > {
499
- static readonly Q = Q.make<Encoded>()
500
- static get DefaultWithoutDependencies() {
501
- const self = this as any
502
- return layerCache ??= Effect
503
- .gen(function*() {
504
- const opts = yield* options.options ?? Effect.succeed({})
505
- const mkRepo = makeRepoInternal<Evt>()(
506
- itemType,
507
- schema,
508
- options?.jitM ? (pm) => options.jitM!(pm) : (pm) => pm,
509
- (e, _etag) => ({ ...e, _etag }),
510
- options.idKey ?? "id" as any
511
- )
512
- const r = yield* mkRepo.make({ ...options, ...opts } as any)
513
- const repo = new self(Object.assign(extendRepo(r), "ext" in opts ? opts.ext : {}))
514
- return Layer.succeed(self, repo)
515
- })
516
- .pipe(Layer.unwrapEffect)
517
- }
518
- static get Default() {
519
- const self = this as any
520
- return layerCache2 ??= options.dependencies
521
- ? self
522
- .DefaultWithoutDependencies
523
- .pipe(Layer.provide(options.dependencies as any))
524
- : self.DefaultWithoutDependencies
525
- }
526
- }
527
- const limit = Error.stackTraceLimit
528
- Error.stackTraceLimit = 2
529
- const creationError = new Error()
530
- Error.stackTraceLimit = limit
531
- // TODO: actual class name or expect a string identifier - careful with overlapping between modules
532
- return Context.assignTag<Service>(registerName(itemType + "Repo"), creationError)(
533
- Object.assign(Cls, makeRepoFunctions(Cls, itemType))
534
- ) as any // impl is missing, but its marked protected
535
- }
536
-
537
- return f
538
- }
3
+ import type { Effect, Option, ParseResult, S } from "effect-app"
4
+ import type { OptimisticConcurrencyException } from "effect-app/client"
539
5
 
540
6
  export interface Mapped1<A, IdKey extends keyof A, R> {
541
7
  all: Effect<A[], ParseResult.ParseError, R>