@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.
@@ -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, Encoded extends { id: string }, R> {
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: Encoded["id"]) => Effect<Option<A>, ParseResult.ParseError, R>
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, Encoded, R>
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, Encoded, R>, never, Repo>
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 extends { id: unknown },
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["id"]) => Effect<Option<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 extends { id: unknown },
124
+ T,
124
125
  Encoded extends { id: string },
125
126
  Evt,
126
- ItemType extends string
127
- > extends RepositoryBaseC<T, Encoded, Evt, ItemType> {
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 extends { id: unknown },
138
+ T,
137
139
  Encoded extends { id: string },
138
140
  Evt,
139
141
  ItemType extends string,
140
- Ext
141
- > extends RepositoryBaseC1<T, Encoded, Evt, ItemType> {
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 extends { id: unknown },
169
+ T,
167
170
  Encoded extends { id: string },
168
171
  Evt,
169
172
  ItemType extends string,
170
- Ext
171
- > extends RepositoryBaseC2<T, Encoded, Evt, ItemType, Ext> {
172
- get(id: T["id"]) {
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["id"]) {
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["id"] }, Context, R, A, E, S2 extends 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["id"],
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 extends { id: unknown }
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("id"))
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("id"))
437
+ .pick(idKey as any))
432
438
  : _
433
439
  .pipe(S
434
- .pick("id"))
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["id"]) {
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((_) => _.id),
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["id"]) {
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: Encoded["id"]) => flatMapOption(findE(id), dec),
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 extends { id: unknown }
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 extends { id: unknown },
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 extends { id: unknown }, Encoded extends { id: string }, Evt, ItemType, Service> {
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["id"]) => Effect<Option<T>, never, Service>
787
- removeById: (id: T["id"]) => Effect<void, NotFoundError<ItemType>, Service>
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["id"]) => Effect<T, NotFoundError<ItemType>, Service>
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["id"],
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 { id: unknown }>(
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
- return <ItemType extends string, R, Encoded extends { id: string }, T extends { id: unknown }>(
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
- & (abstract new(
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
- return <
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 extends { id: unknown },
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
- & (abstract new(
1097
- impl: Repository<T, Encoded, Evt, ItemType> & Ext
1098
- ) => RepositoryBaseC3<T, Encoded, Evt, ItemType, Ext>)
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
- & RepoFunctions<T, Encoded, Evt, ItemType, Service> =>
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 extends { id: unknown },
1352
+ T,
1173
1353
  Encoded extends { id: string } & FieldValues,
1174
1354
  Evt,
1175
- Service
1176
- >(repo: Context.Tag<Service, Service> & RepoFunctions<T, Encoded, Evt, ItemType, Service>) => {
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["id"] }
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, (_) => _.id === r.id)
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["id"]) => Effect.request(_request({ id }), requestResolver)
1391
+ return (id: T[IdKey]) => Effect.request(_request({ id }), requestResolver)
1211
1392
  }