@effect-app/infra 0.211.0 → 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/CHANGELOG.md +12 -0
- package/_cjs/services/Repository/ext.cjs +8 -102
- package/_cjs/services/Repository/ext.cjs.map +1 -1
- package/_cjs/services/RepositoryBase.cjs +20 -58
- package/_cjs/services/RepositoryBase.cjs.map +1 -1
- package/_cjs/services/Store/codeFilter.cjs +0 -43
- package/_cjs/services/Store/codeFilter.cjs.map +1 -1
- package/dist/services/Repository/ext.d.ts +27 -219
- package/dist/services/Repository/ext.d.ts.map +1 -1
- package/dist/services/Repository/ext.js +8 -95
- package/dist/services/RepositoryBase.d.ts +6 -51
- package/dist/services/RepositoryBase.d.ts.map +1 -1
- package/dist/services/RepositoryBase.js +33 -70
- package/dist/services/Store/codeFilter.d.ts.map +1 -1
- package/dist/services/Store/codeFilter.js +1 -44
- package/package.json +3 -3
- package/src/services/Repository/ext.ts +20 -476
- package/src/services/RepositoryBase.ts +51 -131
- package/src/services/Store/codeFilter.ts +0 -46
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
AnyPureDSL,
|
|
9
9
|
byIdAndSaveWithPure,
|
|
10
10
|
get,
|
|
11
|
-
queryEffect,
|
|
12
11
|
type Repository,
|
|
13
12
|
saveAllWithEffectInt,
|
|
14
13
|
saveManyWithPure_,
|
|
@@ -16,7 +15,7 @@ import {
|
|
|
16
15
|
saveWithPure_
|
|
17
16
|
} from "./Repository.js"
|
|
18
17
|
import { StoreMaker } from "./Store.js"
|
|
19
|
-
import type {
|
|
18
|
+
import type { FilterArgs, PersistenceModelType, StoreConfig } from "./Store.js"
|
|
20
19
|
import type {} from "effect/Equal"
|
|
21
20
|
import type {} from "effect/Hash"
|
|
22
21
|
import { toNonEmptyArray } from "@effect-app/core/Array"
|
|
@@ -35,7 +34,7 @@ import { make as makeQuery } from "./query.js"
|
|
|
35
34
|
import type { QAll, Query, QueryEnd, QueryProjection, QueryWhere } from "./query.js"
|
|
36
35
|
import * as Q from "./query.js"
|
|
37
36
|
import { ContextMapContainer } from "./Store/ContextMapContainer.js"
|
|
38
|
-
import * as QB from "./Store/filterApi/query.js"
|
|
37
|
+
import type * as QB from "./Store/filterApi/query.js"
|
|
39
38
|
|
|
40
39
|
export interface Mapped1<PM extends { id: string }, X, R> {
|
|
41
40
|
all: Effect<X[], ParseResult.ParseError, R>
|
|
@@ -82,24 +81,12 @@ export abstract class RepositoryBaseC<
|
|
|
82
81
|
items: Iterable<T>,
|
|
83
82
|
events?: Iterable<Evt>
|
|
84
83
|
) => Effect<void, InvalidStateError | OptimisticConcurrencyException>
|
|
85
|
-
abstract readonly utils: {
|
|
86
|
-
parseMany: (a: readonly PM[]) => Effect<readonly T[]>
|
|
87
|
-
parseMany2: <A, R>(
|
|
88
|
-
a: readonly PM[],
|
|
89
|
-
schema: S.Schema<A, Omit<PM, "_etag">, R>
|
|
90
|
-
) => Effect<readonly A[], S.ParseResult.ParseError, R>
|
|
91
|
-
all: Effect<PM[]>
|
|
92
|
-
filter: FilterFunc<PM>
|
|
93
|
-
// count: (filter?: Filter<PM>) => Effect<never, never, NonNegativeInt>
|
|
94
|
-
}
|
|
95
84
|
abstract readonly changeFeed: PubSub.PubSub<[T[], "save" | "remove"]>
|
|
96
85
|
abstract readonly removeAndPublish: (
|
|
97
86
|
items: Iterable<T>,
|
|
98
87
|
events?: Iterable<Evt>
|
|
99
88
|
) => Effect<void>
|
|
100
89
|
|
|
101
|
-
/** @deprecated use query */
|
|
102
|
-
abstract readonly mapped: Mapped<PM, Omit<PM, "_etag">>
|
|
103
90
|
abstract readonly query: {
|
|
104
91
|
<A, R, From extends FieldValues, TType extends "one" | "many" | "count" = "many">(
|
|
105
92
|
q: (
|
|
@@ -119,6 +106,9 @@ export abstract class RepositoryBaseC<
|
|
|
119
106
|
// q: QueryProjection<Omit<PM, "_etag"> extends From ? From : never, A, R>
|
|
120
107
|
// ): Effect.Effect<readonly A[], S.ParseResult.ParseError, R>
|
|
121
108
|
}
|
|
109
|
+
|
|
110
|
+
/** @deprecated use query */
|
|
111
|
+
abstract readonly mapped: Mapped<PM, Omit<PM, "_etag">>
|
|
122
112
|
}
|
|
123
113
|
|
|
124
114
|
export abstract class RepositoryBaseC1<
|
|
@@ -149,7 +139,6 @@ export class RepositoryBaseC2<
|
|
|
149
139
|
this.removeAndPublish = this.impl.removeAndPublish
|
|
150
140
|
this.find = this.impl.find
|
|
151
141
|
this.all = this.impl.all
|
|
152
|
-
this.utils = this.impl.utils
|
|
153
142
|
this.changeFeed = this.impl.changeFeed
|
|
154
143
|
this.mapped = this.impl.mapped
|
|
155
144
|
this.query = this.impl.query
|
|
@@ -159,7 +148,6 @@ export class RepositoryBaseC2<
|
|
|
159
148
|
override removeAndPublish
|
|
160
149
|
override find
|
|
161
150
|
override all
|
|
162
|
-
override utils
|
|
163
151
|
override changeFeed
|
|
164
152
|
override mapped
|
|
165
153
|
override query
|
|
@@ -313,31 +301,6 @@ export class RepositoryBaseC3<
|
|
|
313
301
|
.pipe(Effect.map(([item, events, a]) => [[item], events, a]))
|
|
314
302
|
)
|
|
315
303
|
}
|
|
316
|
-
|
|
317
|
-
/** @deprecated use query */
|
|
318
|
-
queryLegacy<S = T>(
|
|
319
|
-
// TODO: think about collectPM, collectE, and collect(Parsed)
|
|
320
|
-
_map: { filter?: Filter<PM>; collect?: (t: T) => Option<S>; limit?: number; skip?: number }
|
|
321
|
-
) {
|
|
322
|
-
return Effect.flatMap(Effect.sync(() => _map), (f) =>
|
|
323
|
-
(f.filter ? this.utils.filter(f) : this.utils.all)
|
|
324
|
-
.pipe(
|
|
325
|
-
Effect.flatMap((_) => this.utils.parseMany(_)),
|
|
326
|
-
Effect.map((_) => f.collect ? ReadonlyArray.filterMap(_, f.collect) : _ as unknown[] as S[])
|
|
327
|
-
))
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
/** @deprecated use query */
|
|
331
|
-
queryAndSavePureBatched<
|
|
332
|
-
S extends T = T
|
|
333
|
-
>(
|
|
334
|
-
// TODO: think about collectPM, collectE, and collect(Parsed)
|
|
335
|
-
map: { filter: Filter<PM>; collect?: (t: T) => Option<S>; limit?: number; skip?: number },
|
|
336
|
-
batchSize = 100
|
|
337
|
-
) {
|
|
338
|
-
return <R2, A, E2, S2 extends T>(pure: Effect<A, E2, FixEnv<R2, Evt, readonly S[], readonly S2[]>>) =>
|
|
339
|
-
Effect.flatMap(queryEffect(this, Effect.succeed(map)), (_) => this.saveManyWithPure(_, pure, batchSize))
|
|
340
|
-
}
|
|
341
304
|
}
|
|
342
305
|
|
|
343
306
|
type Exact<A, B> = [A] extends [B] ? [B] extends [A] ? true : false : false
|
|
@@ -415,12 +378,8 @@ export function makeRepo<
|
|
|
415
378
|
: () => Effect.unit
|
|
416
379
|
const changeFeed = yield* $(PubSub.unbounded<[T[], "save" | "remove"]>())
|
|
417
380
|
|
|
418
|
-
const allE =
|
|
419
|
-
Effect.
|
|
420
|
-
const { set } = yield* $(cms)
|
|
421
|
-
return items.map((_) => mapReverse(_, set))
|
|
422
|
-
})
|
|
423
|
-
))
|
|
381
|
+
const allE = cms
|
|
382
|
+
.pipe(Effect.flatMap((cm) => Effect.map(store.all, (_) => _.map((_) => mapReverse(_, cm.set)))))
|
|
424
383
|
|
|
425
384
|
const all = Effect
|
|
426
385
|
.flatMap(
|
|
@@ -531,33 +490,30 @@ export function makeRepo<
|
|
|
531
490
|
})
|
|
532
491
|
}
|
|
533
492
|
|
|
534
|
-
const
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
.
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
.
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
(items) => Effect.map(cms, ({ set }) => items.forEach((_) => set(_.id, _._etag)))
|
|
559
|
-
)
|
|
560
|
-
} satisfies Repository<T, PM, Evt, ItemType>["utils"]
|
|
493
|
+
const parseMany = (items: readonly PM[]) =>
|
|
494
|
+
Effect
|
|
495
|
+
.flatMap(cms, (cm) =>
|
|
496
|
+
decodeMany(items.map((_) => mapReverse(_, cm.set)))
|
|
497
|
+
.pipe(Effect.orDie, Effect.withSpan("parseMany")))
|
|
498
|
+
const parseMany2 = <A, R>(
|
|
499
|
+
items: readonly PM[],
|
|
500
|
+
schema: S.Schema<A, Omit<PM, "_etag">, R>
|
|
501
|
+
) =>
|
|
502
|
+
Effect
|
|
503
|
+
.flatMap(cms, (cm) =>
|
|
504
|
+
S
|
|
505
|
+
.decode(S.array(schema))(
|
|
506
|
+
items.map((_) => mapReverse(_, cm.set) as unknown as Omit<PM, "_etag">)
|
|
507
|
+
)
|
|
508
|
+
.pipe(Effect.orDie, Effect.withSpan("parseMany2")))
|
|
509
|
+
const filter = <U extends keyof PM = keyof PM>(args: FilterArgs<PM, U>) =>
|
|
510
|
+
store
|
|
511
|
+
.filter(args)
|
|
512
|
+
.pipe(Effect.tap((items) =>
|
|
513
|
+
args.select
|
|
514
|
+
? Effect.unit
|
|
515
|
+
: Effect.map(cms, ({ set }) => items.forEach((_) => set((_ as PM).id, (_ as PM)._etag)))
|
|
516
|
+
))
|
|
561
517
|
|
|
562
518
|
// TODO: For raw we should use S.from, and drop the R...
|
|
563
519
|
const query: {
|
|
@@ -580,22 +536,20 @@ export function makeRepo<
|
|
|
580
536
|
>(q: QAll<PM, A, R>) => {
|
|
581
537
|
const a = Q.toFilter(q)
|
|
582
538
|
const eff = a.mode === "raw"
|
|
583
|
-
?
|
|
584
|
-
.utils
|
|
585
|
-
.filter(a)
|
|
539
|
+
? filter(a)
|
|
586
540
|
// TODO: mapFrom but need to support per field and dependencies
|
|
587
541
|
.pipe(Effect.andThen(flow(S.decode(S.array(S.from(a.schema ?? schema))), Effect.provide(rctx))))
|
|
588
542
|
: Effect.flatMap(
|
|
589
|
-
|
|
543
|
+
filter(a),
|
|
590
544
|
(_) =>
|
|
591
545
|
Unify
|
|
592
546
|
.unify(
|
|
593
547
|
a.schema
|
|
594
|
-
?
|
|
548
|
+
? parseMany2(
|
|
595
549
|
_,
|
|
596
550
|
a.schema as any
|
|
597
551
|
)
|
|
598
|
-
:
|
|
552
|
+
: parseMany(_)
|
|
599
553
|
)
|
|
600
554
|
)
|
|
601
555
|
return pipe(
|
|
@@ -623,40 +577,36 @@ export function makeRepo<
|
|
|
623
577
|
}) as any
|
|
624
578
|
|
|
625
579
|
const r: Repository<T, PM, Evt, ItemType> = {
|
|
580
|
+
changeFeed,
|
|
581
|
+
itemType: name,
|
|
582
|
+
find,
|
|
583
|
+
all,
|
|
584
|
+
saveAndPublish,
|
|
585
|
+
removeAndPublish,
|
|
586
|
+
query: (q: any) => query(typeof q === "function" ? q(makeQuery()) : q) as any,
|
|
587
|
+
|
|
626
588
|
/**
|
|
627
589
|
* @internal
|
|
628
590
|
*/
|
|
629
|
-
utils,
|
|
630
591
|
mapped: <A, R>(schema: S.Schema<A, any, R>) => {
|
|
631
592
|
const dec = S.decode(schema)
|
|
632
593
|
const encMany = S.encode(S.array(schema))
|
|
633
594
|
const decMany = S.decode(S.array(schema))
|
|
634
595
|
return {
|
|
635
|
-
all:
|
|
636
|
-
.
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
Effect.map((_) => _ as any[])
|
|
640
|
-
),
|
|
596
|
+
all: allE.pipe(
|
|
597
|
+
Effect.flatMap(decMany),
|
|
598
|
+
Effect.map((_) => _ as any[])
|
|
599
|
+
),
|
|
641
600
|
find: (id: PM["id"]) => flatMapOption(findE(id), dec),
|
|
642
601
|
query: (b: any) =>
|
|
643
|
-
|
|
644
|
-
.utils
|
|
645
|
-
.filter({ filter: b })
|
|
602
|
+
filter({ filter: b })
|
|
646
603
|
.pipe(
|
|
647
604
|
Effect.flatMap(decMany),
|
|
648
605
|
Effect.map((_) => _ as any[])
|
|
649
606
|
),
|
|
650
607
|
save: (...xes: any[]) => Effect.flatMap(encMany(xes), (_) => saveAllE(_))
|
|
651
608
|
}
|
|
652
|
-
}
|
|
653
|
-
changeFeed,
|
|
654
|
-
itemType: name,
|
|
655
|
-
find,
|
|
656
|
-
all,
|
|
657
|
-
saveAndPublish,
|
|
658
|
-
removeAndPublish,
|
|
659
|
-
query: (q: any) => query(typeof q === "function" ? q(makeQuery()) : q) as any
|
|
609
|
+
}
|
|
660
610
|
}
|
|
661
611
|
return r
|
|
662
612
|
})
|
|
@@ -667,28 +617,11 @@ export function makeRepo<
|
|
|
667
617
|
|
|
668
618
|
return {
|
|
669
619
|
make,
|
|
670
|
-
Query: QB.QueryBuilder.make<PM>(),
|
|
671
620
|
Q: Q.make<Omit<PM, "_etag">>()
|
|
672
621
|
}
|
|
673
622
|
}
|
|
674
623
|
}
|
|
675
624
|
|
|
676
|
-
/**
|
|
677
|
-
* only use this as a shortcut if you don't have the item already
|
|
678
|
-
* @tsplus fluent Repository removeById
|
|
679
|
-
*/
|
|
680
|
-
export function removeById<
|
|
681
|
-
T extends { id: unknown },
|
|
682
|
-
PM extends PersistenceModelType<string>,
|
|
683
|
-
Evt,
|
|
684
|
-
ItemType extends string
|
|
685
|
-
>(
|
|
686
|
-
self: Repository<T, PM, Evt, ItemType>,
|
|
687
|
-
id: T["id"]
|
|
688
|
-
) {
|
|
689
|
-
return get(self, id).pipe(Effect.flatMap((_) => self.removeAndPublish([_])))
|
|
690
|
-
}
|
|
691
|
-
|
|
692
625
|
const pluralize = (s: string) =>
|
|
693
626
|
s.endsWith("s")
|
|
694
627
|
? s + "es"
|
|
@@ -799,8 +732,6 @@ export interface Repos<
|
|
|
799
732
|
},
|
|
800
733
|
f: (r: Repository<T, PM, Evt, ItemType>) => Out
|
|
801
734
|
): Effect<Out, E, StoreMaker | ContextMapContainer | R | RInitial | R2>
|
|
802
|
-
/** @deprecated use `Q` instead */
|
|
803
|
-
readonly Query: ReturnType<typeof QB.QueryBuilder.make<PM>>
|
|
804
735
|
readonly Q: ReturnType<typeof Q.make<PM>>
|
|
805
736
|
readonly type: Repository<T, PM, Evt, ItemType>
|
|
806
737
|
}
|
|
@@ -927,14 +858,6 @@ export interface RepoFunctions<T extends { id: unknown }, PM extends { id: strin
|
|
|
927
858
|
>
|
|
928
859
|
}
|
|
929
860
|
|
|
930
|
-
/** @deprecated use query */
|
|
931
|
-
queryLegacy: <S = T>(map: {
|
|
932
|
-
filter?: Filter<PM>
|
|
933
|
-
collect?: (t: T) => Option<S>
|
|
934
|
-
limit?: number
|
|
935
|
-
skip?: number
|
|
936
|
-
}) => Effect<S[], never, Service>
|
|
937
|
-
|
|
938
861
|
/** @experimental */
|
|
939
862
|
mapped: MM<Service, PM, Omit<PM, "_etag">>
|
|
940
863
|
|
|
@@ -951,7 +874,6 @@ const makeRepoFunctions = (tag: any) => {
|
|
|
951
874
|
get,
|
|
952
875
|
query,
|
|
953
876
|
queryAndSavePure,
|
|
954
|
-
queryLegacy,
|
|
955
877
|
removeAndPublish,
|
|
956
878
|
removeById,
|
|
957
879
|
save,
|
|
@@ -971,10 +893,10 @@ const makeRepoFunctions = (tag: any) => {
|
|
|
971
893
|
save,
|
|
972
894
|
get,
|
|
973
895
|
query,
|
|
974
|
-
queryLegacy,
|
|
975
896
|
mapped,
|
|
976
897
|
queryAndSavePure,
|
|
977
|
-
saveManyWithPure
|
|
898
|
+
saveManyWithPure,
|
|
899
|
+
use: (body: any) => Effect.andThen(tag, body)
|
|
978
900
|
}
|
|
979
901
|
}
|
|
980
902
|
|
|
@@ -1013,7 +935,6 @@ export const RepositoryBaseImpl = <Service>() => {
|
|
|
1013
935
|
static readonly make = mkRepo.make
|
|
1014
936
|
static readonly makeWith = ((a: any, b: any) => Effect.map(mkRepo.make(a), b)) as any
|
|
1015
937
|
|
|
1016
|
-
static readonly Query = QB.QueryBuilder.make<PM>()
|
|
1017
938
|
static readonly Q = Q.make<From>()
|
|
1018
939
|
static readonly type: Repository<T, PM, Evt, ItemType> = undefined as any
|
|
1019
940
|
}
|
|
@@ -1061,7 +982,6 @@ export const RepositoryDefaultImpl = <Service>() => {
|
|
|
1061
982
|
static readonly make = mkRepo.make
|
|
1062
983
|
static readonly makeWith = ((a: any, b: any) => Effect.map(mkRepo.make(a), b)) as any
|
|
1063
984
|
|
|
1064
|
-
static readonly Query = QB.QueryBuilder.make<PM>()
|
|
1065
985
|
static readonly Q = Q.make<From>()
|
|
1066
986
|
|
|
1067
987
|
static readonly type: Repository<T, PM, Evt, ItemType> = undefined as any
|
|
@@ -53,52 +53,6 @@ export const codeFilterStatement = <E>(p: FilterR, x: E) => {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
// const or = <E extends { id: string }, NE extends E>(filters: readonly FilterResult[], x: E): Option<NE> =>
|
|
57
|
-
// filters
|
|
58
|
-
// .some((p) => {
|
|
59
|
-
// if (p.t === "and-scope") {
|
|
60
|
-
// return and(p.result, x)
|
|
61
|
-
// }
|
|
62
|
-
// if (p.t === "or-scope") {
|
|
63
|
-
// return or(p.result, x)
|
|
64
|
-
// }
|
|
65
|
-
// if (p.t === "where-scope") {
|
|
66
|
-
// return codeFilter2(filters)(x)
|
|
67
|
-
// }
|
|
68
|
-
// return codeFilterStatement(p, x)
|
|
69
|
-
// })
|
|
70
|
-
// ? Option.some(x as unknown as NE)
|
|
71
|
-
// : Option.none()
|
|
72
|
-
|
|
73
|
-
// export const and = <E extends { id: string }, NE extends E>(filters: readonly FilterResult[], x: E): Option<NE> =>
|
|
74
|
-
// filters
|
|
75
|
-
// .every((p) => {
|
|
76
|
-
// if (p.t === "and-scope") {
|
|
77
|
-
// return and(p.result, x)
|
|
78
|
-
// }
|
|
79
|
-
// if (p.t === "or-scope") {
|
|
80
|
-
// return or(p.result, x)
|
|
81
|
-
// }
|
|
82
|
-
// if (p.t === "where-scope") {
|
|
83
|
-
// return codeFilter2(filters)(x)
|
|
84
|
-
// }
|
|
85
|
-
// return codeFilterStatement(p, x)
|
|
86
|
-
// })
|
|
87
|
-
// ? Option.some(x as unknown as NE)
|
|
88
|
-
// : Option.none()
|
|
89
|
-
|
|
90
|
-
// // TODO: how to handle and/or outside scopes.
|
|
91
|
-
// // TODO: the scopes are not about and every, or some.. they're about logical grouping. It's a logical group + and/or etc.
|
|
92
|
-
// // TODO: how to convert this to code? would we compile an actual function body instead?!
|
|
93
|
-
// export function codeFilter2<E extends { id: string }, NE extends E>(filters: readonly FilterResult[]) {
|
|
94
|
-
// // TODO: handle or, and, or-scope, and-scope, where-scope
|
|
95
|
-
// return (x: E) =>
|
|
96
|
-
// // AND
|
|
97
|
-
// and<E, NE>(filters, x)
|
|
98
|
-
// // OR
|
|
99
|
-
// // or<E, NE>(filters, x)
|
|
100
|
-
// }
|
|
101
|
-
|
|
102
56
|
export const codeFilter3 = <E>(state: readonly FilterResult[]) => (sut: E) => codeFilter3_(state, sut)
|
|
103
57
|
export const codeFilter3_ = <E>(state: readonly FilterResult[], sut: E, statements: any[] = []): boolean => {
|
|
104
58
|
let s = ""
|