@effect-app/infra 1.44.6 → 1.45.1
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.map +1 -1
- package/_cjs/services/RepositoryBase.cjs +17 -12
- package/_cjs/services/RepositoryBase.cjs.map +1 -1
- package/dist/RequestContext.d.ts.map +1 -1
- package/dist/api/internal/RequestContextMiddleware.d.ts +1 -1
- package/dist/services/OperationsRepo.d.ts +1 -1
- package/dist/services/QueueMaker/sbqueue.d.ts +1 -1
- package/dist/services/Repository/ext.d.ts +27 -51
- package/dist/services/Repository/ext.d.ts.map +1 -1
- package/dist/services/Repository/ext.js +1 -1
- package/dist/services/Repository/service.d.ts +2 -4
- package/dist/services/Repository/service.d.ts.map +1 -1
- package/dist/services/RepositoryBase.d.ts +107 -93
- package/dist/services/RepositoryBase.d.ts.map +1 -1
- package/dist/services/RepositoryBase.js +19 -14
- package/dist/services/RequestContextContainer.d.ts +1 -1
- package/dist/services/Store/service.d.ts +1 -1
- package/examples/query.ts +4 -3
- package/package.json +3 -3
- package/src/services/Repository/ext.ts +58 -44
- package/src/services/Repository/service.ts +4 -3
- package/src/services/RepositoryBase.ts +292 -111
- package/test/query.test.ts +4 -3
|
@@ -50,10 +50,10 @@ import type { QAll, Query, QueryEnd, QueryProjection, QueryWhere } from "./query
|
|
|
50
50
|
import * as Q from "./query.js"
|
|
51
51
|
import { ContextMapContainer } from "./Store/ContextMapContainer.js"
|
|
52
52
|
|
|
53
|
-
export interface Mapped1<A,
|
|
53
|
+
export interface Mapped1<A, IdKey extends keyof A, R> {
|
|
54
54
|
all: Effect<A[], ParseResult.ParseError, R>
|
|
55
55
|
save: (...xes: readonly A[]) => Effect<void, OptimisticConcurrencyException | ParseResult.ParseError, R>
|
|
56
|
-
find: (id:
|
|
56
|
+
find: (id: A[IdKey]) => Effect<Option<A>, ParseResult.ParseError, R>
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
// TODO: auto use project, and select fields from the From side of schema only
|
|
@@ -62,13 +62,13 @@ export interface Mapped2<A, R> {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
export interface Mapped<Encoded extends { id: string }> {
|
|
65
|
-
<A, R>(schema: S.Schema<A, Encoded, R>): Mapped1<A,
|
|
65
|
+
<A, R, IdKey extends keyof A>(schema: S.Schema<A, Encoded, R>): Mapped1<A, IdKey, R>
|
|
66
66
|
// TODO: constrain on Encoded2 having to contain only fields that fit Encoded
|
|
67
67
|
<A, Encoded2, R>(schema: S.Schema<A, Encoded2, R>): Mapped2<A, R>
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
export interface MM<Repo, Encoded extends { id: string }> {
|
|
71
|
-
<A, R>(schema: S.Schema<A, Encoded, R>): Effect<Mapped1<A,
|
|
71
|
+
<A, R, IdKey extends keyof A>(schema: S.Schema<A, Encoded, R>): Effect<Mapped1<A, IdKey, R>, never, Repo>
|
|
72
72
|
// TODO: constrain on Encoded2 having to contain only fields that fit Encoded
|
|
73
73
|
<A, Encoded2, R>(schema: S.Schema<A, Encoded2, R>): Effect<Mapped2<A, R>, never, Repo>
|
|
74
74
|
}
|
|
@@ -77,13 +77,14 @@ export interface MM<Repo, Encoded extends { id: string }> {
|
|
|
77
77
|
* @tsplus type Repository
|
|
78
78
|
*/
|
|
79
79
|
export abstract class RepositoryBaseC<
|
|
80
|
-
T
|
|
80
|
+
T,
|
|
81
81
|
Encoded extends { id: string },
|
|
82
82
|
Evt,
|
|
83
|
-
ItemType extends string
|
|
83
|
+
ItemType extends string,
|
|
84
|
+
IdKey extends keyof T
|
|
84
85
|
> {
|
|
85
86
|
abstract readonly itemType: ItemType
|
|
86
|
-
abstract readonly find: (id: T[
|
|
87
|
+
abstract readonly find: (id: T[IdKey]) => Effect<Option<T>>
|
|
87
88
|
abstract readonly all: Effect<T[]>
|
|
88
89
|
abstract readonly saveAndPublish: (
|
|
89
90
|
items: Iterable<T>,
|
|
@@ -120,11 +121,12 @@ export abstract class RepositoryBaseC<
|
|
|
120
121
|
}
|
|
121
122
|
|
|
122
123
|
export abstract class RepositoryBaseC1<
|
|
123
|
-
T
|
|
124
|
+
T,
|
|
124
125
|
Encoded extends { id: string },
|
|
125
126
|
Evt,
|
|
126
|
-
ItemType extends string
|
|
127
|
-
|
|
127
|
+
ItemType extends string,
|
|
128
|
+
IdKey extends keyof T
|
|
129
|
+
> extends RepositoryBaseC<T, Encoded, Evt, ItemType, IdKey> {
|
|
128
130
|
constructor(
|
|
129
131
|
public readonly itemType: ItemType
|
|
130
132
|
) {
|
|
@@ -133,15 +135,16 @@ export abstract class RepositoryBaseC1<
|
|
|
133
135
|
}
|
|
134
136
|
|
|
135
137
|
export class RepositoryBaseC2<
|
|
136
|
-
T
|
|
138
|
+
T,
|
|
137
139
|
Encoded extends { id: string },
|
|
138
140
|
Evt,
|
|
139
141
|
ItemType extends string,
|
|
140
|
-
Ext
|
|
141
|
-
|
|
142
|
+
Ext,
|
|
143
|
+
IdKey extends keyof T
|
|
144
|
+
> extends RepositoryBaseC1<T, Encoded, Evt, ItemType, IdKey> {
|
|
142
145
|
constructor(
|
|
143
146
|
itemType: ItemType,
|
|
144
|
-
protected readonly impl: Repository<T, Encoded, Evt, ItemType> & Ext
|
|
147
|
+
protected readonly impl: Repository<T, Encoded, Evt, ItemType, IdKey> & Ext
|
|
145
148
|
) {
|
|
146
149
|
super(itemType)
|
|
147
150
|
this.saveAndPublish = this.impl.saveAndPublish
|
|
@@ -163,13 +166,14 @@ export class RepositoryBaseC2<
|
|
|
163
166
|
}
|
|
164
167
|
|
|
165
168
|
export class RepositoryBaseC3<
|
|
166
|
-
T
|
|
169
|
+
T,
|
|
167
170
|
Encoded extends { id: string },
|
|
168
171
|
Evt,
|
|
169
172
|
ItemType extends string,
|
|
170
|
-
Ext
|
|
171
|
-
|
|
172
|
-
|
|
173
|
+
Ext,
|
|
174
|
+
IdKey extends keyof T
|
|
175
|
+
> extends RepositoryBaseC2<T, Encoded, Evt, ItemType, Ext, IdKey> {
|
|
176
|
+
get(id: T[IdKey]) {
|
|
173
177
|
return Effect.andThen(
|
|
174
178
|
this
|
|
175
179
|
.find(id),
|
|
@@ -179,7 +183,7 @@ export class RepositoryBaseC3<
|
|
|
179
183
|
|
|
180
184
|
readonly log = (evt: Evt) => AnyPureDSL.log(evt)
|
|
181
185
|
|
|
182
|
-
removeById(id: T[
|
|
186
|
+
removeById(id: T[IdKey]) {
|
|
183
187
|
return Effect.andThen(this.get(id), (_) => this.removeAndPublish([_]))
|
|
184
188
|
}
|
|
185
189
|
|
|
@@ -237,8 +241,8 @@ export class RepositoryBaseC3<
|
|
|
237
241
|
Effect.andThen((_) =>
|
|
238
242
|
Array.isArray(_)
|
|
239
243
|
? batch === undefined
|
|
240
|
-
? saveManyWithPure_(this, _, pure as any)
|
|
241
|
-
: saveManyWithPureBatched_(this, _, pure as any, batch === "batched" ? 100 : batch)
|
|
244
|
+
? saveManyWithPure_(this, _ as any, pure as any)
|
|
245
|
+
: saveManyWithPureBatched_(this, _ as any, pure as any, batch === "batched" ? 100 : batch)
|
|
242
246
|
: saveWithPure_(this, _ as any, pure as any)
|
|
243
247
|
)
|
|
244
248
|
) as any
|
|
@@ -246,7 +250,7 @@ export class RepositoryBaseC3<
|
|
|
246
250
|
/**
|
|
247
251
|
* NOTE: it's not as composable, only useful when the request is simple, and only this part needs request args.
|
|
248
252
|
*/
|
|
249
|
-
readonly handleByIdAndSaveWithPure = <Req extends { id: T[
|
|
253
|
+
readonly handleByIdAndSaveWithPure = <Req extends { id: T[IdKey] }, Context, R, A, E, S2 extends T>(
|
|
250
254
|
pure: (req: Req, ctx: Context) => Effect<A, E, FixEnv<R, Evt, T, S2>>
|
|
251
255
|
) =>
|
|
252
256
|
(req: Req, ctx: Context) => byIdAndSaveWithPure(this, req.id)(pure(req, ctx))
|
|
@@ -290,7 +294,7 @@ export class RepositoryBaseC3<
|
|
|
290
294
|
|
|
291
295
|
byIdAndSaveWithPure: {
|
|
292
296
|
<R, A, E, S2 extends T>(
|
|
293
|
-
id: T[
|
|
297
|
+
id: T[IdKey],
|
|
294
298
|
pure: Effect<A, E, FixEnv<R, Evt, T, S2>>
|
|
295
299
|
): Effect<
|
|
296
300
|
A,
|
|
@@ -331,12 +335,14 @@ export function makeRepo<
|
|
|
331
335
|
ItemType extends string,
|
|
332
336
|
R,
|
|
333
337
|
Encoded extends { id: string },
|
|
334
|
-
T
|
|
338
|
+
T,
|
|
339
|
+
IdKey extends keyof T
|
|
335
340
|
>(
|
|
336
341
|
name: ItemType,
|
|
337
342
|
schema: S.Schema<T, Encoded, R>,
|
|
338
343
|
mapFrom: (pm: Encoded) => Encoded,
|
|
339
|
-
mapTo: (e: Encoded, etag: string | undefined) => PersistenceModelType<Encoded
|
|
344
|
+
mapTo: (e: Encoded, etag: string | undefined) => PersistenceModelType<Encoded>,
|
|
345
|
+
idKey: IdKey
|
|
340
346
|
) => {
|
|
341
347
|
type PM = PersistenceModelType<Encoded>
|
|
342
348
|
function mapToPersistenceModel(
|
|
@@ -416,7 +422,7 @@ export function makeRepo<
|
|
|
416
422
|
// we need to get the TypeLiteral, incase of class it's behind a transform...
|
|
417
423
|
? S.Union(..._.ast.types.map((_) =>
|
|
418
424
|
(S.make(_._tag === "Transformation" ? _.from : _) as unknown as Schema<T, Encoded>)
|
|
419
|
-
.pipe(S.pick(
|
|
425
|
+
.pipe(S.pick(idKey as any))
|
|
420
426
|
))
|
|
421
427
|
: _
|
|
422
428
|
.ast
|
|
@@ -428,10 +434,10 @@ export function makeRepo<
|
|
|
428
434
|
.from
|
|
429
435
|
) as unknown as Schema<T, Encoded>)
|
|
430
436
|
.pipe(S
|
|
431
|
-
.pick(
|
|
437
|
+
.pick(idKey as any))
|
|
432
438
|
: _
|
|
433
439
|
.pipe(S
|
|
434
|
-
.pick(
|
|
440
|
+
.pick(idKey as any))
|
|
435
441
|
)
|
|
436
442
|
const encodeId = flow(S.encode(i), Effect.provide(rctx))
|
|
437
443
|
function findEId(id: Encoded["id"]) {
|
|
@@ -444,16 +450,16 @@ export function makeRepo<
|
|
|
444
450
|
})
|
|
445
451
|
)
|
|
446
452
|
}
|
|
447
|
-
function findE(id: T[
|
|
453
|
+
function findE(id: T[IdKey]) {
|
|
448
454
|
return pipe(
|
|
449
|
-
encodeId({ id }),
|
|
455
|
+
encodeId({ [idKey]: id } as any),
|
|
450
456
|
Effect.orDie,
|
|
451
|
-
Effect.map((_) => _
|
|
457
|
+
Effect.map((_) => (_ as any)[idKey]), // we will have idKey because the transform is undone again by the encode schema mumbo jumbo above
|
|
452
458
|
Effect.flatMap(findEId)
|
|
453
459
|
)
|
|
454
460
|
}
|
|
455
461
|
|
|
456
|
-
function find(id: T[
|
|
462
|
+
function find(id: T[IdKey]) {
|
|
457
463
|
return Effect.flatMapOption(findE(id), (_) => Effect.orDie(decode(_)))
|
|
458
464
|
}
|
|
459
465
|
|
|
@@ -605,7 +611,7 @@ export function makeRepo<
|
|
|
605
611
|
)
|
|
606
612
|
}) as any
|
|
607
613
|
|
|
608
|
-
const r: Repository<T, Encoded, Evt, ItemType> = {
|
|
614
|
+
const r: Repository<T, Encoded, Evt, ItemType, IdKey> = {
|
|
609
615
|
changeFeed,
|
|
610
616
|
itemType: name,
|
|
611
617
|
find,
|
|
@@ -626,7 +632,7 @@ export function makeRepo<
|
|
|
626
632
|
Effect.flatMap(decMany),
|
|
627
633
|
Effect.map((_) => _ as any[])
|
|
628
634
|
),
|
|
629
|
-
find: (id:
|
|
635
|
+
find: (id: T[IdKey]) => flatMapOption(findE(id), dec),
|
|
630
636
|
// query: (q: any) => {
|
|
631
637
|
// const a = Q.toFilter(q)
|
|
632
638
|
|
|
@@ -678,7 +684,7 @@ export function makeStore<
|
|
|
678
684
|
ItemType extends string,
|
|
679
685
|
R,
|
|
680
686
|
E extends { id: string },
|
|
681
|
-
T
|
|
687
|
+
T
|
|
682
688
|
>(
|
|
683
689
|
name: ItemType,
|
|
684
690
|
schema: S.Schema<T, E, R>,
|
|
@@ -736,11 +742,12 @@ export function makeStore<
|
|
|
736
742
|
}
|
|
737
743
|
|
|
738
744
|
export interface Repos<
|
|
739
|
-
T
|
|
745
|
+
T,
|
|
740
746
|
Encoded extends { id: string },
|
|
741
747
|
R,
|
|
742
748
|
Evt,
|
|
743
|
-
ItemType extends string
|
|
749
|
+
ItemType extends string,
|
|
750
|
+
IdKey extends keyof T
|
|
744
751
|
> {
|
|
745
752
|
make<RInitial = never, E = never, R2 = never>(
|
|
746
753
|
args: [Evt] extends [never] ? {
|
|
@@ -756,7 +763,7 @@ export interface Repos<
|
|
|
756
763
|
partitionValue?: (a: Encoded) => string
|
|
757
764
|
}
|
|
758
765
|
}
|
|
759
|
-
): Effect<Repository<T, Encoded, Evt, ItemType>, E, StoreMaker | ContextMapContainer | R | RInitial | R2>
|
|
766
|
+
): Effect<Repository<T, Encoded, Evt, ItemType, IdKey>, E, StoreMaker | ContextMapContainer | R | RInitial | R2>
|
|
760
767
|
makeWith<Out, RInitial = never, E = never, R2 = never>(
|
|
761
768
|
args: [Evt] extends [never] ? {
|
|
762
769
|
makeInitial?: Effect<readonly T[], E, RInitial>
|
|
@@ -771,20 +778,20 @@ export interface Repos<
|
|
|
771
778
|
partitionValue?: (a: Encoded) => string
|
|
772
779
|
}
|
|
773
780
|
},
|
|
774
|
-
f: (r: Repository<T, Encoded, Evt, ItemType>) => Out
|
|
781
|
+
f: (r: Repository<T, Encoded, Evt, ItemType, IdKey>) => Out
|
|
775
782
|
): Effect<Out, E, StoreMaker | ContextMapContainer | R | RInitial | R2>
|
|
776
783
|
readonly Q: ReturnType<typeof Q.make<Encoded>>
|
|
777
|
-
readonly type: Repository<T, Encoded, Evt, ItemType>
|
|
784
|
+
readonly type: Repository<T, Encoded, Evt, ItemType, IdKey>
|
|
778
785
|
}
|
|
779
786
|
|
|
780
787
|
export type GetRepoType<T> = T extends { type: infer R } ? R : never
|
|
781
788
|
|
|
782
|
-
export interface RepoFunctions<T
|
|
789
|
+
export interface RepoFunctions<T, Encoded extends { id: string }, Evt, ItemType, IdKey extends keyof T, Service> {
|
|
783
790
|
itemType: ItemType
|
|
784
791
|
T: T
|
|
785
792
|
all: Effect<readonly T[], never, Service>
|
|
786
|
-
find: (id: T[
|
|
787
|
-
removeById: (id: T[
|
|
793
|
+
find: (id: T[IdKey]) => Effect<Option<T>, never, Service>
|
|
794
|
+
removeById: (id: T[IdKey]) => Effect<void, NotFoundError<ItemType>, Service>
|
|
788
795
|
saveAndPublish: (
|
|
789
796
|
items: Iterable<T>,
|
|
790
797
|
events?: Iterable<Evt>
|
|
@@ -794,7 +801,7 @@ export interface RepoFunctions<T extends { id: unknown }, Encoded extends { id:
|
|
|
794
801
|
events?: Iterable<Evt>
|
|
795
802
|
) => Effect<void, never, Service>
|
|
796
803
|
save: (...items: T[]) => Effect<void, InvalidStateError | OptimisticConcurrencyException, Service>
|
|
797
|
-
get: (id: T[
|
|
804
|
+
get: (id: T[IdKey]) => Effect<T, NotFoundError<ItemType>, Service>
|
|
798
805
|
|
|
799
806
|
queryAndSavePure: {
|
|
800
807
|
<A, E2, R2, T2 extends T>(
|
|
@@ -871,7 +878,7 @@ export interface RepoFunctions<T extends { id: unknown }, Encoded extends { id:
|
|
|
871
878
|
|
|
872
879
|
byIdAndSaveWithPure: {
|
|
873
880
|
<R, A, E, S2 extends T>(
|
|
874
|
-
id: T[
|
|
881
|
+
id: T[IdKey],
|
|
875
882
|
pure: Effect<A, E, FixEnv<R, Evt, T, S2>>
|
|
876
883
|
): Effect<
|
|
877
884
|
A,
|
|
@@ -954,29 +961,32 @@ export const RepositoryBaseImpl = <Service>() => {
|
|
|
954
961
|
return <
|
|
955
962
|
Evt = never
|
|
956
963
|
>() =>
|
|
957
|
-
<ItemType extends string, R, Encoded extends { id: string }, T extends
|
|
964
|
+
<ItemType extends string, R, Encoded extends { id: string }, T, IdKey extends keyof T>(
|
|
958
965
|
itemType: ItemType,
|
|
959
966
|
schema: S.Schema<T, Encoded, R>,
|
|
967
|
+
idKey: IdKey,
|
|
960
968
|
jitM?: (pm: Encoded) => Encoded
|
|
961
969
|
):
|
|
962
|
-
& (abstract new() => RepositoryBaseC1<T, Encoded, Evt, ItemType>)
|
|
970
|
+
& (abstract new() => RepositoryBaseC1<T, Encoded, Evt, ItemType, IdKey>)
|
|
963
971
|
& Context.Tag<Service, Service>
|
|
964
972
|
& Repos<
|
|
965
973
|
T,
|
|
966
974
|
Encoded,
|
|
967
975
|
R,
|
|
968
976
|
Evt,
|
|
969
|
-
ItemType
|
|
977
|
+
ItemType,
|
|
978
|
+
IdKey
|
|
970
979
|
>
|
|
971
|
-
& RepoFunctions<T, Encoded, Evt, ItemType, Service> =>
|
|
980
|
+
& RepoFunctions<T, Encoded, Evt, ItemType, IdKey, Service> =>
|
|
972
981
|
{
|
|
973
982
|
const mkRepo = makeRepo<Evt>()(
|
|
974
983
|
itemType,
|
|
975
984
|
schema,
|
|
976
985
|
jitM ? (pm) => jitM(pm as unknown as Encoded) : (pm) => pm as any,
|
|
977
|
-
(e, _etag) => ({ ...e, _etag })
|
|
986
|
+
(e, _etag) => ({ ...e, _etag }),
|
|
987
|
+
idKey
|
|
978
988
|
)
|
|
979
|
-
abstract class Cls extends RepositoryBaseC1<T, Encoded, Evt, ItemType> {
|
|
989
|
+
abstract class Cls extends RepositoryBaseC1<T, Encoded, Evt, ItemType, IdKey> {
|
|
980
990
|
constructor() {
|
|
981
991
|
super(itemType)
|
|
982
992
|
}
|
|
@@ -984,7 +994,7 @@ export const RepositoryBaseImpl = <Service>() => {
|
|
|
984
994
|
static readonly makeWith = ((a: any, b: any) => Effect.map(mkRepo.make(a), b)) as any
|
|
985
995
|
|
|
986
996
|
static readonly Q = Q.make<Encoded>()
|
|
987
|
-
static readonly type: Repository<T, Encoded, Evt, ItemType> = undefined as any
|
|
997
|
+
static readonly type: Repository<T, Encoded, Evt, ItemType, IdKey> = undefined as any
|
|
988
998
|
}
|
|
989
999
|
const limit = Error.stackTraceLimit
|
|
990
1000
|
Error.stackTraceLimit = 2
|
|
@@ -997,33 +1007,61 @@ export const RepositoryBaseImpl = <Service>() => {
|
|
|
997
1007
|
}
|
|
998
1008
|
|
|
999
1009
|
export const RepositoryDefaultImpl = <Service, Evt = never>() => {
|
|
1000
|
-
|
|
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>(
|
|
1001
1049
|
itemType: ItemType,
|
|
1002
1050
|
schema: S.Schema<T, Encoded, R>,
|
|
1051
|
+
idKeyOrJitM?: IdKey | ((pm: Encoded) => Encoded),
|
|
1003
1052
|
jitM?: (pm: Encoded) => Encoded
|
|
1004
|
-
)
|
|
1005
|
-
|
|
1006
|
-
impl: Repository<T, Encoded, Evt, ItemType>
|
|
1007
|
-
) => RepositoryBaseC3<T, Encoded, Evt, ItemType, {}>)
|
|
1008
|
-
& Context.Tag<Service, Service>
|
|
1009
|
-
& Repos<
|
|
1010
|
-
T,
|
|
1011
|
-
Encoded,
|
|
1012
|
-
R,
|
|
1013
|
-
Evt,
|
|
1014
|
-
ItemType
|
|
1015
|
-
>
|
|
1016
|
-
& RepoFunctions<T, Encoded, Evt, ItemType, Service> =>
|
|
1017
|
-
{
|
|
1053
|
+
) => {
|
|
1054
|
+
if (!jitM && idKeyOrJitM !== undefined && typeof idKeyOrJitM === "function") jitM = idKeyOrJitM
|
|
1018
1055
|
const mkRepo = makeRepo<Evt>()(
|
|
1019
1056
|
itemType,
|
|
1020
1057
|
schema,
|
|
1021
1058
|
jitM ? (pm) => jitM(pm) : (pm) => pm,
|
|
1022
|
-
(e, _etag) => ({ ...e, _etag })
|
|
1059
|
+
(e, _etag) => ({ ...e, _etag }),
|
|
1060
|
+
idKeyOrJitM ?? "id" as any
|
|
1023
1061
|
)
|
|
1024
|
-
abstract class Cls extends RepositoryBaseC3<T, Encoded, Evt, ItemType, {}> {
|
|
1062
|
+
abstract class Cls extends RepositoryBaseC3<T, Encoded, Evt, ItemType, {}, IdKey> {
|
|
1025
1063
|
constructor(
|
|
1026
|
-
impl: Repository<T, Encoded, Evt, ItemType>
|
|
1064
|
+
impl: Repository<T, Encoded, Evt, ItemType, IdKey>
|
|
1027
1065
|
) {
|
|
1028
1066
|
super(itemType, impl)
|
|
1029
1067
|
}
|
|
@@ -1032,7 +1070,7 @@ export const RepositoryDefaultImpl = <Service, Evt = never>() => {
|
|
|
1032
1070
|
|
|
1033
1071
|
static readonly Q = Q.make<Encoded>()
|
|
1034
1072
|
|
|
1035
|
-
static readonly type: Repository<T, Encoded, Evt, ItemType> = undefined as any
|
|
1073
|
+
static readonly type: Repository<T, Encoded, Evt, ItemType, IdKey> = undefined as any
|
|
1036
1074
|
}
|
|
1037
1075
|
const limit = Error.stackTraceLimit
|
|
1038
1076
|
Error.stackTraceLimit = 2
|
|
@@ -1042,14 +1080,172 @@ export const RepositoryDefaultImpl = <Service, Evt = never>() => {
|
|
|
1042
1080
|
Object.assign(Cls, makeRepoFunctions(Cls, itemType))
|
|
1043
1081
|
) as any // impl is missing, but its marked protected
|
|
1044
1082
|
}
|
|
1083
|
+
return f
|
|
1045
1084
|
}
|
|
1046
1085
|
|
|
1047
1086
|
export const RepositoryDefaultImpl2 = <Service, Evt = never>() => {
|
|
1048
|
-
|
|
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 | ContextMapContainer,
|
|
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 | ContextMapContainer
|
|
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 | ContextMapContainer,
|
|
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 | ContextMapContainer
|
|
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
|
+
} = <
|
|
1049
1244
|
ItemType extends string,
|
|
1050
1245
|
R,
|
|
1051
1246
|
Encoded extends { id: string },
|
|
1052
|
-
T
|
|
1247
|
+
T,
|
|
1248
|
+
IdKey extends keyof T,
|
|
1053
1249
|
E = never,
|
|
1054
1250
|
RInitial = never,
|
|
1055
1251
|
R2 = never,
|
|
@@ -1063,6 +1259,7 @@ export const RepositoryDefaultImpl2 = <Service, Evt = never>() => {
|
|
|
1063
1259
|
schema: S.Schema<T, Encoded, R>,
|
|
1064
1260
|
options: [Evt] extends [never] ? {
|
|
1065
1261
|
dependencies?: Layers
|
|
1262
|
+
idKey?: IdKey
|
|
1066
1263
|
config?: Omit<StoreConfig<Encoded>, "partitionValue"> & {
|
|
1067
1264
|
partitionValue?: (a: Encoded) => string
|
|
1068
1265
|
}
|
|
@@ -1078,6 +1275,7 @@ export const RepositoryDefaultImpl2 = <Service, Evt = never>() => {
|
|
|
1078
1275
|
}
|
|
1079
1276
|
: {
|
|
1080
1277
|
dependencies?: Layers
|
|
1278
|
+
idKey?: IdKey
|
|
1081
1279
|
jitM?: (pm: Encoded) => Encoded
|
|
1082
1280
|
config?: Omit<StoreConfig<Encoded>, "partitionValue"> & {
|
|
1083
1281
|
partitionValue?: (a: Encoded) => string
|
|
@@ -1092,40 +1290,19 @@ export const RepositoryDefaultImpl2 = <Service, Evt = never>() => {
|
|
|
1092
1290
|
R1
|
|
1093
1291
|
>
|
|
1094
1292
|
}
|
|
1095
|
-
)
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
& Context.Tag<Service, Service>
|
|
1100
|
-
& {
|
|
1101
|
-
Default: Layer.Layer<
|
|
1102
|
-
Service,
|
|
1103
|
-
E1 | Layer.Layer.Error<Layers[number]>,
|
|
1104
|
-
Exclude<
|
|
1105
|
-
R1 | R | StoreMaker | ContextMapContainer,
|
|
1106
|
-
{ [k in keyof Layers]: Layer.Layer.Success<Layers[k]> }[number]
|
|
1107
|
-
>
|
|
1108
|
-
>
|
|
1109
|
-
DefaultWithoutDependencies: Layer.Layer<
|
|
1110
|
-
Service,
|
|
1111
|
-
E1,
|
|
1112
|
-
R1 | R | StoreMaker | ContextMapContainer
|
|
1113
|
-
>
|
|
1114
|
-
}
|
|
1115
|
-
& Repos<
|
|
1293
|
+
) => {
|
|
1294
|
+
let layerCache = undefined
|
|
1295
|
+
let layerCache2 = undefined
|
|
1296
|
+
abstract class Cls extends RepositoryBaseC3<
|
|
1116
1297
|
T,
|
|
1117
1298
|
Encoded,
|
|
1118
|
-
R,
|
|
1119
1299
|
Evt,
|
|
1120
|
-
ItemType
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
let layerCache = undefined
|
|
1125
|
-
let layerCache2 = undefined
|
|
1126
|
-
abstract class Cls extends RepositoryBaseC3<T, Encoded, Evt, ItemType, Ext> {
|
|
1300
|
+
ItemType,
|
|
1301
|
+
Ext,
|
|
1302
|
+
IdKey
|
|
1303
|
+
> {
|
|
1127
1304
|
constructor(
|
|
1128
|
-
impl: Repository<T, Encoded, Evt, ItemType> & Ext
|
|
1305
|
+
impl: Repository<T, Encoded, Evt, ItemType, IdKey> & Ext
|
|
1129
1306
|
) {
|
|
1130
1307
|
super(itemType, impl)
|
|
1131
1308
|
}
|
|
@@ -1139,7 +1316,8 @@ export const RepositoryDefaultImpl2 = <Service, Evt = never>() => {
|
|
|
1139
1316
|
itemType,
|
|
1140
1317
|
schema,
|
|
1141
1318
|
options?.jitM ? (pm) => options.jitM!(pm) : (pm) => pm,
|
|
1142
|
-
(e, _etag) => ({ ...e, _etag })
|
|
1319
|
+
(e, _etag) => ({ ...e, _etag }),
|
|
1320
|
+
options.idKey ?? "id" as any
|
|
1143
1321
|
)
|
|
1144
1322
|
const r = yield* mkRepo.make({ ...options, ...opts } as any)
|
|
1145
1323
|
return Layer.succeed(self, new self(Object.assign(r, "ext" in opts ? opts.ext : {})))
|
|
@@ -1154,7 +1332,7 @@ export const RepositoryDefaultImpl2 = <Service, Evt = never>() => {
|
|
|
1154
1332
|
.pipe(Layer.provide(options.dependencies as any))
|
|
1155
1333
|
: self.DefaultWithoutDependencies
|
|
1156
1334
|
}
|
|
1157
|
-
static readonly type: Repository<T, Encoded, Evt, ItemType> = undefined as any
|
|
1335
|
+
static readonly type: Repository<T, Encoded, Evt, ItemType, IdKey> = undefined as any
|
|
1158
1336
|
}
|
|
1159
1337
|
const limit = Error.stackTraceLimit
|
|
1160
1338
|
Error.stackTraceLimit = 2
|
|
@@ -1164,19 +1342,22 @@ export const RepositoryDefaultImpl2 = <Service, Evt = never>() => {
|
|
|
1164
1342
|
Object.assign(Cls, makeRepoFunctions(Cls, itemType))
|
|
1165
1343
|
) as any // impl is missing, but its marked protected
|
|
1166
1344
|
}
|
|
1345
|
+
|
|
1346
|
+
return f
|
|
1167
1347
|
}
|
|
1168
1348
|
|
|
1169
1349
|
// TODO: integrate with repo
|
|
1170
1350
|
export const makeRequest = <
|
|
1171
1351
|
ItemType extends string,
|
|
1172
|
-
T
|
|
1352
|
+
T,
|
|
1173
1353
|
Encoded extends { id: string } & FieldValues,
|
|
1174
1354
|
Evt,
|
|
1175
|
-
Service
|
|
1176
|
-
|
|
1355
|
+
Service,
|
|
1356
|
+
IdKey extends keyof T
|
|
1357
|
+
>(repo: Context.Tag<Service, Service> & RepoFunctions<T, Encoded, Evt, ItemType, IdKey, Service>, idKey: IdKey) => {
|
|
1177
1358
|
type Req =
|
|
1178
1359
|
& Request.Request<T, NotFoundError<ItemType>>
|
|
1179
|
-
& { _tag: `Get${ItemType}`; id: T[
|
|
1360
|
+
& { _tag: `Get${ItemType}`; id: T[IdKey] }
|
|
1180
1361
|
const _request = Request.tagged<Req>(`Get${repo.itemType}`)
|
|
1181
1362
|
|
|
1182
1363
|
const requestResolver = RequestResolver
|
|
@@ -1189,7 +1370,7 @@ export const makeRequest = <
|
|
|
1189
1370
|
Request.complete(
|
|
1190
1371
|
r,
|
|
1191
1372
|
Array
|
|
1192
|
-
.findFirst(items, (_) => _
|
|
1373
|
+
.findFirst(items, (_) => _[idKey] === r.id)
|
|
1193
1374
|
.pipe(Option.match({
|
|
1194
1375
|
onNone: () => Exit.fail(new NotFoundError({ type: repo.itemType, id: r.id })),
|
|
1195
1376
|
onSome: Exit.succeed
|
|
@@ -1207,5 +1388,5 @@ export const makeRequest = <
|
|
|
1207
1388
|
RequestResolver.contextFromServices(repo)
|
|
1208
1389
|
)
|
|
1209
1390
|
|
|
1210
|
-
return (id: T[
|
|
1391
|
+
return (id: T[IdKey]) => Effect.request(_request({ id }), requestResolver)
|
|
1211
1392
|
}
|