@effect-app/infra 0.211.1 → 0.211.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effect-app/infra",
3
- "version": "0.211.1",
3
+ "version": "0.211.2",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "dependencies": {
@@ -19,10 +19,10 @@
19
19
  "pure-rand": "6.0.4",
20
20
  "redlock": "^4.2.0",
21
21
  "@effect-app/core": "0.150.5",
22
- "@effect-app/schema": "0.203.4",
23
- "@effect-app/infra-adapters": "0.137.19",
22
+ "effect-app": "0.181.8",
24
23
  "@effect-app/fluent-extensions": "0.143.4",
25
- "effect-app": "0.181.8"
24
+ "@effect-app/infra-adapters": "0.137.19",
25
+ "@effect-app/schema": "0.203.4"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@babel/cli": "^7.23.9",
@@ -1,17 +1,14 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
  // Update = Must return updated items
3
3
  // Modify = Must `set` updated items, and can return anything.
4
- import { toNonEmptyArray } from "@effect-app/core/Array"
5
- import { NonNegativeInt } from "@effect-app/schema"
6
4
  import { Effect, ReadonlyArray } from "effect-app"
7
- import type { NonEmptyArray, NonEmptyReadonlyArray, Option } from "effect-app"
8
- import { type FixEnv, type PureEnv, runTerm } from "effect-app/Pure"
9
- import type { InvalidStateError, OptimisticConcurrencyException } from "../../errors.js"
5
+ import type { NonEmptyArray } from "effect-app"
6
+ import { type FixEnv, runTerm } from "effect-app/Pure"
10
7
  import { NotFoundError } from "../../errors.js"
11
- import type { Filter, PersistenceModelType } from "../../services/Store.js"
8
+ import type { PersistenceModelType } from "../../services/Store.js"
12
9
  import type { RepositoryBaseC } from "../RepositoryBase.js"
13
- import type { QueryBuilder } from "../Store/filterApi/query.js"
14
10
  import { AnyPureDSL } from "./dsl.js"
11
+ import type { Repository } from "./service.js"
15
12
 
16
13
  /**
17
14
  * @tsplus fluent Repository get
@@ -42,435 +39,6 @@ export function log<
42
39
  return (evt: Evt) => AnyPureDSL.log(evt)
43
40
  }
44
41
 
45
- /**
46
- * TODO: project inside the db.
47
- * @tsplus fluent Repository projectEffect
48
- */
49
- export function projectEffect<
50
- T extends { id: unknown },
51
- PM extends PersistenceModelType<string>,
52
- Evt,
53
- ItemType extends string,
54
- R,
55
- E,
56
- S = PM
57
- >(
58
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
59
- map: Effect<
60
- {
61
- filter?: Filter<PM> | undefined
62
- collect?: ((t: PM) => Option<S>) | undefined
63
- limit?: number | undefined
64
- skip?: number | undefined
65
- },
66
- E,
67
- R
68
- >
69
- ): Effect<S[], E, R>
70
- export function projectEffect<
71
- T extends { id: unknown },
72
- PM extends PersistenceModelType<string>,
73
- Evt,
74
- ItemType extends string,
75
- R,
76
- E,
77
- U extends keyof PM,
78
- S = PM
79
- >(
80
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
81
- map: Effect<
82
- {
83
- filter?: QueryBuilder<PM> | undefined
84
- collect?: ((t: PM) => Option<S>) | undefined
85
- limit?: number | undefined
86
- skip?: number | undefined
87
- },
88
- E,
89
- R
90
- >
91
- ): Effect<Pick<PM, U>[], E, R>
92
- export function projectEffect<
93
- T extends { id: unknown },
94
- PM extends PersistenceModelType<string>,
95
- Evt,
96
- ItemType extends string,
97
- R,
98
- E,
99
- U extends keyof PM,
100
- S = Pick<PM, U>
101
- >(
102
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
103
- map: Effect<
104
- {
105
- filter?: Filter<PM> | undefined
106
- select?: NonEmptyReadonlyArray<U> | undefined
107
- collect?: ((t: PM) => Option<S>) | undefined
108
- limit?: number | undefined
109
- skip?: number | undefined
110
- },
111
- E,
112
- R
113
- >
114
- ): Effect<S[], E, R> {
115
- // TODO: a projection that gets sent to the db instead.
116
- return Effect.flatMap(map, (f) =>
117
- self
118
- .utils
119
- .filter(f)
120
- .pipe(Effect.map((_) => f.collect ? ReadonlyArray.filterMap(_, f.collect) : _ as unknown as S[])))
121
- }
122
-
123
- /**
124
- * TODO: project inside the db.
125
- * @tsplus fluent Repository project
126
- */
127
- export function project<
128
- T extends { id: unknown },
129
- PM extends PersistenceModelType<string>,
130
- Evt,
131
- ItemType extends string,
132
- S = PM
133
- >(
134
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
135
- map: {
136
- filter?: Filter<PM>
137
- collect?: (t: PM) => Option<S>
138
- limit?: number
139
- skip?: number
140
- }
141
- ): Effect<S[]>
142
- export function project<
143
- T extends { id: unknown },
144
- PM extends PersistenceModelType<string>,
145
- Evt,
146
- ItemType extends string,
147
- U extends keyof PM
148
- >(
149
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
150
- map: {
151
- filter?: QueryBuilder<PM>
152
- select: NonEmptyReadonlyArray<U>
153
- limit?: number
154
- skip?: number
155
- }
156
- ): Effect<Pick<PM, U>[]>
157
- export function project<
158
- T extends { id: unknown },
159
- PM extends PersistenceModelType<string>,
160
- Evt,
161
- ItemType extends string,
162
- U extends keyof PM,
163
- S = Pick<PM, U>
164
- >(
165
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
166
- map: {
167
- filter?: Filter<PM>
168
- select?: NonEmptyReadonlyArray<U>
169
- collect?: (t: Pick<PM, U>) => Option<S>
170
- limit?: number
171
- skip?: number
172
- }
173
- ): Effect<S[]> {
174
- return projectEffect(self, Effect.sync(() => map))
175
- }
176
-
177
- /**
178
- * TODO: count inside the db.
179
- * @tsplus fluent Repository project
180
- */
181
- export function count<
182
- T extends { id: unknown },
183
- PM extends PersistenceModelType<string>,
184
- Evt,
185
- ItemType extends string
186
- >(
187
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
188
- filter?: Filter<PM>
189
- ) {
190
- return projectEffect(self, Effect.sync(() => ({ filter })))
191
- .pipe(Effect.map((_) => NonNegativeInt(_.length)))
192
- }
193
-
194
- /**
195
- * @tsplus fluent Repository queryEffect
196
- */
197
- export function queryEffect<
198
- T extends { id: unknown },
199
- PM extends PersistenceModelType<string>,
200
- Evt,
201
- ItemType extends string,
202
- R,
203
- E,
204
- S = T
205
- >(
206
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
207
- // TODO: think about collectPM, collectE, and collect(Parsed)
208
- map: Effect<{ filter?: Filter<PM>; collect?: (t: T) => Option<S>; limit?: number; skip?: number }, E, R>
209
- ) {
210
- return Effect.flatMap(map, (f) =>
211
- (f.filter ? self.utils.filter(f) : self.utils.all)
212
- .pipe(
213
- Effect.flatMap((_) => self.utils.parseMany(_)),
214
- Effect.map((_) => f.collect ? ReadonlyArray.filterMap(_, f.collect) : _ as unknown[] as S[])
215
- ))
216
- }
217
-
218
- /**
219
- * @tsplus fluent Repository queryOneEffect
220
- */
221
- export function queryOneEffect<
222
- T extends { id: unknown },
223
- PM extends PersistenceModelType<string>,
224
- Evt,
225
- ItemType extends string,
226
- R,
227
- E
228
- >(
229
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
230
- // TODO: think about collectPM, collectE, and collect(Parsed)
231
- map: Effect<{ filter?: Filter<PM> }, E, R>
232
- ): Effect<T, E | NotFoundError<ItemType>, R>
233
- export function queryOneEffect<
234
- T extends { id: unknown },
235
- PM extends PersistenceModelType<string>,
236
- Evt,
237
- ItemType extends string,
238
- R,
239
- E,
240
- S = T
241
- >(
242
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
243
- // TODO: think about collectPM, collectE, and collect(Parsed)
244
- map: Effect<{ filter?: Filter<PM>; collect: (t: T) => Option<S> }, E, R>
245
- ): Effect<S, E | NotFoundError<ItemType>, R>
246
- export function queryOneEffect<
247
- T extends { id: unknown },
248
- PM extends PersistenceModelType<string>,
249
- Evt,
250
- ItemType extends string,
251
- R,
252
- E,
253
- S = T
254
- >(
255
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
256
- // TODO: think about collectPM, collectE, and collect(Parsed)
257
- map: Effect<{ filter?: Filter<PM>; collect?: (t: T) => Option<S> }, E, R>
258
- ): Effect<S, E | NotFoundError<ItemType>, R> {
259
- return Effect.flatMap(map, (f) =>
260
- (f.filter ? self.utils.filter({ filter: f.filter, limit: 1 }) : self.utils.all)
261
- .pipe(
262
- Effect.flatMap((_) => self.utils.parseMany(_)),
263
- Effect
264
- .flatMap((_) =>
265
- toNonEmptyArray(
266
- f.collect
267
- ? ReadonlyArray.filterMap(_, f.collect)
268
- : _ as unknown[] as S[]
269
- )
270
- .pipe(
271
- Effect.mapError(() => new NotFoundError<ItemType>({ type: self.itemType, id: f.filter })),
272
- Effect
273
- .map((_) => _[0])
274
- )
275
- )
276
- ))
277
- }
278
-
279
- /**
280
- * @tsplus fluent Repository query
281
- */
282
- export function query<
283
- T extends { id: unknown },
284
- PM extends PersistenceModelType<string>,
285
- Evt,
286
- ItemType extends string,
287
- S = T
288
- >(
289
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
290
- // TODO: think about collectPM, collectE, and collect(Parsed)
291
- map: { filter?: Filter<PM>; collect?: (t: T) => Option<S>; limit?: number; skip?: number }
292
- ) {
293
- return queryEffect(self, Effect.sync(() => map))
294
- }
295
-
296
- /**
297
- * @tsplus fluent Repository queryOne
298
- */
299
- export function queryOne<
300
- T extends { id: unknown },
301
- PM extends PersistenceModelType<string>,
302
- Evt,
303
- ItemType extends string,
304
- S = T
305
- >(
306
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
307
- map: { filter?: Filter<PM>; collect: (t: T) => Option<S> }
308
- ): Effect<S, NotFoundError<ItemType>>
309
- export function queryOne<
310
- T extends { id: unknown },
311
- PM extends PersistenceModelType<string>,
312
- Evt,
313
- ItemType extends string
314
- >(
315
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
316
- map: { filter?: Filter<PM> }
317
- ): Effect<T, NotFoundError<ItemType>>
318
- export function queryOne<
319
- T extends { id: unknown },
320
- PM extends PersistenceModelType<string>,
321
- Evt,
322
- ItemType extends string,
323
- S = T
324
- >(
325
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
326
- map: { filter?: Filter<PM>; collect?: (t: T) => Option<S> }
327
- ) {
328
- return queryOneEffect(self, Effect.sync(() => map))
329
- }
330
-
331
- /**
332
- * @tsplus fluent Repository queryAndSaveOnePureEffect
333
- */
334
- export function queryAndSaveOnePureEffect<
335
- T extends { id: unknown },
336
- PM extends PersistenceModelType<string>,
337
- Evt,
338
- ItemType extends string,
339
- R,
340
- E,
341
- S extends T = T
342
- >(
343
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
344
- map: Effect<{ filter: Filter<PM>; collect: (t: T) => Option<S>; limit?: number; skip?: number }, E, R>
345
- ): <R2, A, E2, S2 extends T>(
346
- pure: Effect<A, E2, FixEnv<R2, Evt, S, S2>>
347
- ) => Effect<
348
- A,
349
- InvalidStateError | OptimisticConcurrencyException | E | E2 | NotFoundError<ItemType>,
350
- | R
351
- | Exclude<R2, {
352
- env: PureEnv<Evt, S, S2>
353
- }>
354
- >
355
- export function queryAndSaveOnePureEffect<
356
- T extends { id: unknown },
357
- PM extends PersistenceModelType<string>,
358
- Evt,
359
- ItemType extends string,
360
- R,
361
- E
362
- >(
363
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
364
- map: Effect<{ filter: Filter<PM> }, E, R>
365
- ): <R2, A, E2, T2 extends T>(
366
- pure: Effect<A, E2, FixEnv<R2, Evt, T, T2>>
367
- ) => Effect<
368
- A,
369
- InvalidStateError | OptimisticConcurrencyException | E | E2 | NotFoundError<ItemType>,
370
- | R
371
- | Exclude<R2, {
372
- env: PureEnv<Evt, T, T2>
373
- }>
374
- >
375
- export function queryAndSaveOnePureEffect(
376
- self: any,
377
- map: any
378
- ) {
379
- return (pure: any) =>
380
- queryOneEffect(self, map)
381
- .pipe(Effect.flatMap((_) => saveWithPure_(self, _, pure)))
382
- }
383
-
384
- /**
385
- * @tsplus fluent Repository queryAndSaveOnePure
386
- */
387
- export function queryAndSaveOnePure<
388
- T extends { id: unknown },
389
- PM extends PersistenceModelType<string>,
390
- Evt,
391
- ItemType extends string,
392
- S extends T = T
393
- >(
394
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
395
- map: { filter: Filter<PM>; collect: (t: T) => Option<S>; limit?: number; skip?: number }
396
- ): <R2, A, E2, S2>(pure: Effect<A, E2, FixEnv<R2, Evt, S, S2>>) => Effect<
397
- A,
398
- InvalidStateError | OptimisticConcurrencyException | E2 | NotFoundError<ItemType>,
399
- Exclude<R2, {
400
- env: PureEnv<Evt, S, S2>
401
- }>
402
- >
403
- export function queryAndSaveOnePure<
404
- T extends { id: unknown },
405
- PM extends PersistenceModelType<string>,
406
- Evt,
407
- ItemType extends string
408
- >(
409
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
410
- map: { filter: Filter<PM> }
411
- ): <R2, A, E2, T2>(pure: Effect<A, E2, FixEnv<R2, Evt, T, T2>>) => Effect<
412
- A,
413
- InvalidStateError | OptimisticConcurrencyException | E2 | NotFoundError<ItemType>,
414
- Exclude<R2, {
415
- env: PureEnv<Evt, T, T2>
416
- }>
417
- >
418
- export function queryAndSaveOnePure(
419
- self: any,
420
- map: { filter: Filter<any>; collect?: any }
421
- ) {
422
- return queryAndSaveOnePureEffect(self, Effect.sync(() => map))
423
- }
424
-
425
- /**
426
- * @tsplus fluent Repository queryAndSavePureEffect
427
- */
428
- export function queryAndSavePureEffect<
429
- T extends { id: unknown },
430
- PM extends PersistenceModelType<string>,
431
- Evt,
432
- ItemType extends string,
433
- R,
434
- E,
435
- S extends T = T
436
- >(
437
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
438
- map: Effect<{ filter: Filter<PM>; collect?: (t: T) => Option<S>; limit?: number; skip?: number }, E, R>
439
- ) {
440
- return <R2, A, E2, S2 extends T>(pure: Effect<A, E2, FixEnv<R2, Evt, readonly S[], readonly S2[]>>) =>
441
- queryEffect(self, map)
442
- .pipe(Effect.flatMap((_) => saveManyWithPure_(self, _, pure)))
443
- }
444
-
445
- /**
446
- * @tsplus fluent Repository queryAndSavePure
447
- */
448
- export function queryAndSavePure<
449
- T extends { id: unknown },
450
- PM extends PersistenceModelType<string>,
451
- Evt,
452
- ItemType extends string,
453
- S extends T = T
454
- >(
455
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
456
- map: { filter: Filter<PM>; collect?: (t: T) => Option<S>; limit?: number; skip?: number }
457
- ) {
458
- return queryAndSavePureEffect(self, Effect.sync(() => map))
459
- }
460
-
461
- /**
462
- * @tsplus getter Repository saveManyWithPure
463
- */
464
- export function saveManyWithPure<
465
- T extends { id: unknown },
466
- PM extends PersistenceModelType<string>,
467
- Evt,
468
- ItemType extends string
469
- >(self: RepositoryBaseC<T, PM, Evt, ItemType>) {
470
- return <R, A, E, S1 extends T, S2 extends T>(pure: Effect<A, E, FixEnv<R, Evt, readonly S1[], readonly S2[]>>) =>
471
- (items: Iterable<S1>) => saveManyWithPure_(self, items, pure)
472
- }
473
-
474
42
  /**
475
43
  * @tsplus fluent Repository byIdAndSaveWithPure
476
44
  */
@@ -566,46 +134,6 @@ export function saveAllWithEffectInt<
566
134
  return Effect.flatMap(gen, ([items, events, a]) => self.saveAndPublish(items, events).pipe(Effect.map(() => a)))
567
135
  }
568
136
 
569
- /**
570
- * @tsplus fluent Repository queryAndSavePureEffectBatched
571
- */
572
- export function queryAndSavePureEffectBatched<
573
- T extends { id: unknown },
574
- PM extends PersistenceModelType<string>,
575
- Evt,
576
- ItemType extends string,
577
- R,
578
- E,
579
- S extends T = T
580
- >(
581
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
582
- // TODO: think about collectPM, collectE, and collect(Parsed)
583
- map: Effect<{ filter: Filter<PM>; collect?: (t: T) => Option<S>; limit?: number; skip?: number }, E, R>,
584
- batchSize = 100
585
- ) {
586
- return <R2, A, E2, S2 extends T>(pure: Effect<A, E2, FixEnv<R2, Evt, readonly S[], readonly S2[]>>) =>
587
- queryEffect(self, map)
588
- .pipe(Effect.flatMap((_) => saveManyWithPureBatched_(self, _, pure, batchSize)))
589
- }
590
-
591
- /**
592
- * @tsplus fluent Repository queryAndSavePureBatched
593
- */
594
- export function queryAndSavePureBatched<
595
- T extends { id: unknown },
596
- PM extends PersistenceModelType<string>,
597
- Evt,
598
- ItemType extends string,
599
- S extends T = T
600
- >(
601
- self: RepositoryBaseC<T, PM, Evt, ItemType>,
602
- // TODO: think about collectPM, collectE, and collect(Parsed)
603
- map: { filter: Filter<PM>; collect?: (t: T) => Option<S>; limit?: number; skip?: number },
604
- batchSize = 100
605
- ) {
606
- return queryAndSavePureEffectBatched(self, Effect.sync(() => map), batchSize)
607
- }
608
-
609
137
  /**
610
138
  * @tsplus fluent Repository saveManyWithPureBatched
611
139
  */
@@ -713,3 +241,19 @@ export function itemUpdate<
713
241
  (item) => Effect.sync(() => mod(item))
714
242
  )
715
243
  }
244
+
245
+ /**
246
+ * only use this as a shortcut if you don't have the item already
247
+ * @tsplus fluent Repository removeById
248
+ */
249
+ export function removeById<
250
+ T extends { id: unknown },
251
+ PM extends PersistenceModelType<string>,
252
+ Evt,
253
+ ItemType extends string
254
+ >(
255
+ self: Repository<T, PM, Evt, ItemType>,
256
+ id: T["id"]
257
+ ) {
258
+ return get(self, id).pipe(Effect.flatMap((_) => self.removeAndPublish([_])))
259
+ }