@effect-app/infra 0.170.5 → 0.171.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/_cjs/api/routing/base.cjs.map +1 -1
- package/_cjs/api/routing/makeRequestHandler.cjs.map +1 -1
- package/_cjs/services/QueueMaker/errors.cjs.map +1 -1
- package/_cjs/services/Repository/dsl.cjs +70 -0
- package/_cjs/services/Repository/dsl.cjs.map +1 -0
- package/_cjs/services/Repository/ext.cjs +202 -0
- package/_cjs/services/Repository/ext.cjs.map +1 -0
- package/_cjs/services/Repository/service.cjs +6 -0
- package/_cjs/services/Repository/service.cjs.map +1 -0
- package/_cjs/services/Repository.cjs +32 -252
- package/_cjs/services/Repository.cjs.map +1 -1
- package/_cjs/services/RepositoryBase.cjs +173 -48
- package/_cjs/services/RepositoryBase.cjs.map +1 -1
- package/_cjs/services/RequestContextContainer.cjs +6 -7
- package/_cjs/services/RequestContextContainer.cjs.map +1 -1
- package/_cjs/services/Store/ContextMapContainer.cjs +6 -7
- package/_cjs/services/Store/ContextMapContainer.cjs.map +1 -1
- package/_cjs/services/Store/Memory.cjs.map +1 -1
- package/_cjs/services/Store/utils.cjs.map +1 -1
- package/_src/api/routing/base.ts +5 -3
- package/_src/api/routing/makeRequestHandler.ts +20 -12
- package/_src/rateLimit.ts +2 -2
- package/_src/services/Emailer/Sendgrid.ts +2 -2
- package/_src/services/QueueMaker/errors.ts +6 -3
- package/_src/services/QueueMaker/memQueue.ts +2 -2
- package/_src/services/QueueMaker/sbqueue.ts +2 -2
- package/_src/services/Repository/dsl.ts +137 -0
- package/_src/services/Repository/ext.ts +669 -0
- package/_src/services/Repository/service.ts +12 -0
- package/_src/services/Repository.ts +3 -791
- package/_src/services/RepositoryBase.ts +640 -13
- package/_src/services/RequestContextContainer.ts +14 -16
- package/_src/services/Store/ContextMapContainer.ts +6 -9
- package/_src/services/Store/Cosmos.ts +2 -2
- package/_src/services/Store/Disk.ts +2 -2
- package/_src/services/Store/Memory.ts +2 -1
- package/_src/services/Store/Redis.ts +2 -2
- package/_src/services/Store/utils.ts +4 -5
- package/_src/services/simpledb/cosmosdb.ts +1 -1
- package/_src/services/simpledb/diskdb.ts +1 -1
- package/_src/services/simpledb/memdb.ts +1 -1
- package/_src/services/simpledb/mongodb.ts +1 -1
- package/_src/services/simpledb/redisdb.ts +2 -2
- package/dist/api/routing/base.d.ts +1 -2
- package/dist/api/routing/base.d.ts.map +1 -1
- package/dist/api/routing/base.js +1 -1
- package/dist/api/routing/makeRequestHandler.d.ts.map +1 -1
- package/dist/api/routing/makeRequestHandler.js +15 -11
- package/dist/rateLimit.js +1 -1
- package/dist/services/Emailer/Sendgrid.js +1 -1
- package/dist/services/QueueMaker/errors.d.ts.map +1 -1
- package/dist/services/QueueMaker/errors.js +5 -2
- package/dist/services/QueueMaker/memQueue.js +1 -1
- package/dist/services/QueueMaker/sbqueue.js +1 -1
- package/dist/services/QueueMaker/service.d.ts +2 -2
- package/dist/services/Repository/dsl.d.ts +51 -0
- package/dist/services/Repository/dsl.d.ts.map +1 -0
- package/dist/services/Repository/dsl.js +55 -0
- package/dist/services/Repository/ext.d.ts +310 -0
- package/dist/services/Repository/ext.d.ts.map +1 -0
- package/dist/services/Repository/ext.js +166 -0
- package/dist/services/Repository/service.d.ts +10 -0
- package/dist/services/Repository/service.d.ts.map +1 -0
- package/dist/services/Repository/service.js +2 -0
- package/dist/services/Repository.d.ts +3 -363
- package/dist/services/Repository.d.ts.map +1 -1
- package/dist/services/Repository.js +4 -217
- package/dist/services/RepositoryBase.d.ts +241 -6
- package/dist/services/RepositoryBase.d.ts.map +1 -1
- package/dist/services/RepositoryBase.js +176 -52
- package/dist/services/RequestContextContainer.d.ts +3 -5
- package/dist/services/RequestContextContainer.d.ts.map +1 -1
- package/dist/services/RequestContextContainer.js +17 -16
- package/dist/services/Store/ContextMapContainer.d.ts +2 -5
- package/dist/services/Store/ContextMapContainer.d.ts.map +1 -1
- package/dist/services/Store/ContextMapContainer.js +7 -8
- package/dist/services/Store/Cosmos.js +1 -1
- package/dist/services/Store/Disk.js +1 -1
- package/dist/services/Store/Memory.d.ts.map +1 -1
- package/dist/services/Store/Memory.js +1 -1
- package/dist/services/Store/Redis.js +1 -1
- package/dist/services/Store/utils.d.ts.map +1 -1
- package/dist/services/Store/utils.js +1 -1
- package/dist/services/simpledb/cosmosdb.js +1 -1
- package/dist/services/simpledb/diskdb.js +1 -1
- package/dist/services/simpledb/memdb.js +1 -1
- package/dist/services/simpledb/mongodb.js +1 -1
- package/dist/services/simpledb/redisdb.js +1 -1
- package/package.json +37 -7
|
@@ -1,791 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import type { FixEnv, PureLogT } from "@effect-app/prelude/Pure"
|
|
5
|
-
import { Pure } from "@effect-app/prelude/Pure"
|
|
6
|
-
import type { InvalidStateError, OptimisticConcurrencyException } from "../errors.js"
|
|
7
|
-
import { NotFoundError } from "../errors.js"
|
|
8
|
-
import type { Filter, PersistenceModelType } from "../services/Store.js"
|
|
9
|
-
import type { RepositoryBaseC } from "./RepositoryBase.js"
|
|
10
|
-
import type { QueryBuilder } from "./Store/filterApi/query.js"
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* @tsplus type Repository
|
|
14
|
-
*/
|
|
15
|
-
export interface Repository<
|
|
16
|
-
T extends { id: unknown },
|
|
17
|
-
PM extends PersistenceModelType<string>,
|
|
18
|
-
Evt,
|
|
19
|
-
ItemType extends string
|
|
20
|
-
> extends RepositoryBaseC<T, PM, Evt, ItemType> {}
|
|
21
|
-
|
|
22
|
-
export interface PureDSL<S, S2, W> {
|
|
23
|
-
get: ReturnType<typeof Pure.get<S>>
|
|
24
|
-
set: typeof Pure.set<S2>
|
|
25
|
-
log: (...w: W[]) => PureLogT<W>
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export const AnyPureDSL: PureDSL<any, any, any> = {
|
|
29
|
-
get: Pure.get(),
|
|
30
|
-
set: Pure.set,
|
|
31
|
-
log: (...evt: any[]) => Pure.logMany(evt)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* @tsplus fluent Repository get
|
|
36
|
-
*/
|
|
37
|
-
export function get<
|
|
38
|
-
T extends { id: unknown },
|
|
39
|
-
PM extends PersistenceModelType<string>,
|
|
40
|
-
Evt,
|
|
41
|
-
ItemType extends string
|
|
42
|
-
>(
|
|
43
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>,
|
|
44
|
-
id: T["id"]
|
|
45
|
-
) {
|
|
46
|
-
return self
|
|
47
|
-
.find(id)
|
|
48
|
-
.flatMap((_) => _.encaseInEffect(() => new NotFoundError<ItemType>({ type: self.itemType, id })))
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* @tsplus getter Repository log
|
|
53
|
-
*/
|
|
54
|
-
export function log<
|
|
55
|
-
T extends { id: unknown },
|
|
56
|
-
PM extends PersistenceModelType<string>,
|
|
57
|
-
Evt,
|
|
58
|
-
ItemType extends string
|
|
59
|
-
>(_: RepositoryBaseC<T, PM, Evt, ItemType>) {
|
|
60
|
-
return (evt: Evt) => AnyPureDSL.log(evt)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* TODO: project inside the db.
|
|
65
|
-
* @tsplus fluent Repository projectEffect
|
|
66
|
-
*/
|
|
67
|
-
export function projectEffect<
|
|
68
|
-
T extends { id: unknown },
|
|
69
|
-
PM extends PersistenceModelType<string>,
|
|
70
|
-
Evt,
|
|
71
|
-
ItemType extends string,
|
|
72
|
-
R,
|
|
73
|
-
E,
|
|
74
|
-
S = PM
|
|
75
|
-
>(
|
|
76
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>,
|
|
77
|
-
map: Effect<{
|
|
78
|
-
filter?: Filter<PM> | undefined
|
|
79
|
-
collect?: ((t: PM) => Option<S>) | undefined
|
|
80
|
-
limit?: number | undefined
|
|
81
|
-
skip?: number | undefined
|
|
82
|
-
}, E, R>
|
|
83
|
-
): Effect<S[], E, R>
|
|
84
|
-
export function projectEffect<
|
|
85
|
-
T extends { id: unknown },
|
|
86
|
-
PM extends PersistenceModelType<string>,
|
|
87
|
-
Evt,
|
|
88
|
-
ItemType extends string,
|
|
89
|
-
R,
|
|
90
|
-
E,
|
|
91
|
-
U extends keyof PM,
|
|
92
|
-
S = PM
|
|
93
|
-
>(
|
|
94
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>,
|
|
95
|
-
map: Effect<{
|
|
96
|
-
filter?: QueryBuilder<PM> | undefined
|
|
97
|
-
collect?: ((t: PM) => Option<S>) | undefined
|
|
98
|
-
limit?: number | undefined
|
|
99
|
-
skip?: number | undefined
|
|
100
|
-
}, E, R>
|
|
101
|
-
): Effect<Pick<PM, U>[], E, R>
|
|
102
|
-
export function projectEffect<
|
|
103
|
-
T extends { id: unknown },
|
|
104
|
-
PM extends PersistenceModelType<string>,
|
|
105
|
-
Evt,
|
|
106
|
-
ItemType extends string,
|
|
107
|
-
R,
|
|
108
|
-
E,
|
|
109
|
-
U extends keyof PM,
|
|
110
|
-
S = Pick<PM, U>
|
|
111
|
-
>(
|
|
112
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>,
|
|
113
|
-
map: Effect<{
|
|
114
|
-
filter?: Filter<PM> | undefined
|
|
115
|
-
select?: NonEmptyReadonlyArray<U> | undefined
|
|
116
|
-
collect?: ((t: PM) => Option<S>) | undefined
|
|
117
|
-
limit?: number | undefined
|
|
118
|
-
skip?: number | undefined
|
|
119
|
-
}, E, R>
|
|
120
|
-
): Effect<S[], E, R> {
|
|
121
|
-
// TODO: a projection that gets sent to the db instead.
|
|
122
|
-
return map.flatMap((f) =>
|
|
123
|
-
self
|
|
124
|
-
.utils
|
|
125
|
-
.filter(f)
|
|
126
|
-
.map((_) => f.collect ? _.filterMap(f.collect) : _ as unknown as S[])
|
|
127
|
-
)
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* TODO: project inside the db.
|
|
132
|
-
* @tsplus fluent Repository project
|
|
133
|
-
*/
|
|
134
|
-
export function project<
|
|
135
|
-
T extends { id: unknown },
|
|
136
|
-
PM extends PersistenceModelType<string>,
|
|
137
|
-
Evt,
|
|
138
|
-
ItemType extends string,
|
|
139
|
-
S = PM
|
|
140
|
-
>(
|
|
141
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>,
|
|
142
|
-
map: {
|
|
143
|
-
filter?: Filter<PM>
|
|
144
|
-
collect?: (t: PM) => Option<S>
|
|
145
|
-
limit?: number
|
|
146
|
-
skip?: number
|
|
147
|
-
}
|
|
148
|
-
): Effect<S[]>
|
|
149
|
-
export function project<
|
|
150
|
-
T extends { id: unknown },
|
|
151
|
-
PM extends PersistenceModelType<string>,
|
|
152
|
-
Evt,
|
|
153
|
-
ItemType extends string,
|
|
154
|
-
U extends keyof PM
|
|
155
|
-
>(
|
|
156
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>,
|
|
157
|
-
map: {
|
|
158
|
-
filter?: QueryBuilder<PM>
|
|
159
|
-
select: NonEmptyReadonlyArray<U>
|
|
160
|
-
limit?: number
|
|
161
|
-
skip?: number
|
|
162
|
-
}
|
|
163
|
-
): Effect<Pick<PM, U>[]>
|
|
164
|
-
export function project<
|
|
165
|
-
T extends { id: unknown },
|
|
166
|
-
PM extends PersistenceModelType<string>,
|
|
167
|
-
Evt,
|
|
168
|
-
ItemType extends string,
|
|
169
|
-
U extends keyof PM,
|
|
170
|
-
S = Pick<PM, U>
|
|
171
|
-
>(
|
|
172
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>,
|
|
173
|
-
map: {
|
|
174
|
-
filter?: Filter<PM>
|
|
175
|
-
select?: NonEmptyReadonlyArray<U>
|
|
176
|
-
collect?: (t: Pick<PM, U>) => Option<S>
|
|
177
|
-
limit?: number
|
|
178
|
-
skip?: number
|
|
179
|
-
}
|
|
180
|
-
): Effect<S[]> {
|
|
181
|
-
return self.projectEffect(Effect.sync(() => map))
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* TODO: count inside the db.
|
|
186
|
-
* @tsplus fluent Repository project
|
|
187
|
-
*/
|
|
188
|
-
export function count<
|
|
189
|
-
T extends { id: unknown },
|
|
190
|
-
PM extends PersistenceModelType<string>,
|
|
191
|
-
Evt,
|
|
192
|
-
ItemType extends string
|
|
193
|
-
>(
|
|
194
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>,
|
|
195
|
-
filter?: Filter<PM>
|
|
196
|
-
) {
|
|
197
|
-
return self
|
|
198
|
-
.projectEffect(Effect.sync(() => ({ filter })))
|
|
199
|
-
.map((_) => NonNegativeInt(_.length))
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* @tsplus fluent Repository queryEffect
|
|
204
|
-
*/
|
|
205
|
-
export function queryEffect<
|
|
206
|
-
T extends { id: unknown },
|
|
207
|
-
PM extends PersistenceModelType<string>,
|
|
208
|
-
Evt,
|
|
209
|
-
ItemType extends string,
|
|
210
|
-
R,
|
|
211
|
-
E,
|
|
212
|
-
S = T
|
|
213
|
-
>(
|
|
214
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>,
|
|
215
|
-
// TODO: think about collectPM, collectE, and collect(Parsed)
|
|
216
|
-
map: Effect<{ filter?: Filter<PM>; collect?: (t: T) => Option<S>; limit?: number; skip?: number }, E, R>
|
|
217
|
-
) {
|
|
218
|
-
return map.flatMap((f) =>
|
|
219
|
-
(f.filter ? self.utils.filter(f) : self.utils.all)
|
|
220
|
-
.flatMap((_) => self.utils.parseMany(_))
|
|
221
|
-
.map((_) => f.collect ? _.filterMap(f.collect) : _ as any as S[])
|
|
222
|
-
)
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* @tsplus fluent Repository queryOneEffect
|
|
227
|
-
*/
|
|
228
|
-
export function queryOneEffect<
|
|
229
|
-
T extends { id: unknown },
|
|
230
|
-
PM extends PersistenceModelType<string>,
|
|
231
|
-
Evt,
|
|
232
|
-
ItemType extends string,
|
|
233
|
-
R,
|
|
234
|
-
E
|
|
235
|
-
>(
|
|
236
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>,
|
|
237
|
-
// TODO: think about collectPM, collectE, and collect(Parsed)
|
|
238
|
-
map: Effect<{ filter?: Filter<PM> }, E, R>
|
|
239
|
-
): Effect<T, E | NotFoundError<ItemType>, R>
|
|
240
|
-
export function queryOneEffect<
|
|
241
|
-
T extends { id: unknown },
|
|
242
|
-
PM extends PersistenceModelType<string>,
|
|
243
|
-
Evt,
|
|
244
|
-
ItemType extends string,
|
|
245
|
-
R,
|
|
246
|
-
E,
|
|
247
|
-
S = T
|
|
248
|
-
>(
|
|
249
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>,
|
|
250
|
-
// TODO: think about collectPM, collectE, and collect(Parsed)
|
|
251
|
-
map: Effect<{ filter?: Filter<PM>; collect: (t: T) => Option<S> }, E, R>
|
|
252
|
-
): Effect<S, E | NotFoundError<ItemType>, R>
|
|
253
|
-
export function queryOneEffect<
|
|
254
|
-
T extends { id: unknown },
|
|
255
|
-
PM extends PersistenceModelType<string>,
|
|
256
|
-
Evt,
|
|
257
|
-
ItemType extends string,
|
|
258
|
-
R,
|
|
259
|
-
E,
|
|
260
|
-
S = T
|
|
261
|
-
>(
|
|
262
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>,
|
|
263
|
-
// TODO: think about collectPM, collectE, and collect(Parsed)
|
|
264
|
-
map: Effect<{ filter?: Filter<PM>; collect?: (t: T) => Option<S> }, E, R>
|
|
265
|
-
): Effect<S, E | NotFoundError<ItemType>, R> {
|
|
266
|
-
return map.flatMap((f) =>
|
|
267
|
-
(f.filter ? self.utils.filter({ filter: f.filter, limit: 1 }) : self.utils.all)
|
|
268
|
-
.flatMap((_) => self.utils.parseMany(_))
|
|
269
|
-
.flatMap((_) =>
|
|
270
|
-
(f.collect ? _.filterMap(f.collect) : _ as any as S[])
|
|
271
|
-
.toNonEmpty
|
|
272
|
-
.encaseInEffect(() => new NotFoundError<ItemType>({ type: self.itemType, id: f.filter }))
|
|
273
|
-
.map((_) => _[0])
|
|
274
|
-
)
|
|
275
|
-
)
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
/**
|
|
279
|
-
* @tsplus fluent Repository query
|
|
280
|
-
*/
|
|
281
|
-
export function query<
|
|
282
|
-
T extends { id: unknown },
|
|
283
|
-
PM extends PersistenceModelType<string>,
|
|
284
|
-
Evt,
|
|
285
|
-
ItemType extends string,
|
|
286
|
-
S = T
|
|
287
|
-
>(
|
|
288
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>,
|
|
289
|
-
// TODO: think about collectPM, collectE, and collect(Parsed)
|
|
290
|
-
map: { filter?: Filter<PM>; collect?: (t: T) => Option<S>; limit?: number; skip?: number }
|
|
291
|
-
) {
|
|
292
|
-
return self.queryEffect(Effect.sync(() => map))
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* @tsplus fluent Repository queryOne
|
|
297
|
-
*/
|
|
298
|
-
export function queryOne<
|
|
299
|
-
T extends { id: unknown },
|
|
300
|
-
PM extends PersistenceModelType<string>,
|
|
301
|
-
Evt,
|
|
302
|
-
ItemType extends string,
|
|
303
|
-
S = T
|
|
304
|
-
>(
|
|
305
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>,
|
|
306
|
-
map: { filter?: Filter<PM>; collect: (t: T) => Option<S> }
|
|
307
|
-
): Effect<S, NotFoundError<ItemType>>
|
|
308
|
-
export function queryOne<
|
|
309
|
-
T extends { id: unknown },
|
|
310
|
-
PM extends PersistenceModelType<string>,
|
|
311
|
-
Evt,
|
|
312
|
-
ItemType extends string
|
|
313
|
-
>(
|
|
314
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>,
|
|
315
|
-
map: { filter?: Filter<PM> }
|
|
316
|
-
): Effect<T, NotFoundError<ItemType>>
|
|
317
|
-
export function queryOne<
|
|
318
|
-
T extends { id: unknown },
|
|
319
|
-
PM extends PersistenceModelType<string>,
|
|
320
|
-
Evt,
|
|
321
|
-
ItemType extends string,
|
|
322
|
-
S = T
|
|
323
|
-
>(
|
|
324
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>,
|
|
325
|
-
map: { filter?: Filter<PM>; collect?: (t: T) => Option<S> }
|
|
326
|
-
) {
|
|
327
|
-
return self.queryOneEffect(Effect.sync(() => map))
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
/**
|
|
331
|
-
* @tsplus fluent Repository queryAndSaveOnePureEffect
|
|
332
|
-
*/
|
|
333
|
-
export function queryAndSaveOnePureEffect<
|
|
334
|
-
T extends { id: unknown },
|
|
335
|
-
PM extends PersistenceModelType<string>,
|
|
336
|
-
Evt,
|
|
337
|
-
ItemType extends string,
|
|
338
|
-
R,
|
|
339
|
-
E,
|
|
340
|
-
S extends T = T
|
|
341
|
-
>(
|
|
342
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>,
|
|
343
|
-
map: Effect<{ filter: Filter<PM>; collect: (t: T) => Option<S>; limit?: number; skip?: number }, E, R>
|
|
344
|
-
): <R2, A, E2, S2 extends T>(pure: Effect<A, E2, FixEnv<R2, Evt, S, S2>>) => Effect<A, InvalidStateError | OptimisticConcurrencyException | E | E2 | NotFoundError<ItemType>, | R
|
|
345
|
-
| Exclude<R2, {
|
|
346
|
-
env: PureEnv<Evt, S, S2>
|
|
347
|
-
}>>
|
|
348
|
-
export function queryAndSaveOnePureEffect<
|
|
349
|
-
T extends { id: unknown },
|
|
350
|
-
PM extends PersistenceModelType<string>,
|
|
351
|
-
Evt,
|
|
352
|
-
ItemType extends string,
|
|
353
|
-
R,
|
|
354
|
-
E
|
|
355
|
-
>(
|
|
356
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>,
|
|
357
|
-
map: Effect<{ filter: Filter<PM> }, E, R>
|
|
358
|
-
): <R2, A, E2, T2 extends T>(pure: Effect<A, E2, FixEnv<R2, Evt, T, T2>>) => Effect<A, InvalidStateError | OptimisticConcurrencyException | E | E2 | NotFoundError<ItemType>, | R
|
|
359
|
-
| Exclude<R2, {
|
|
360
|
-
env: PureEnv<Evt, T, T2>
|
|
361
|
-
}>>
|
|
362
|
-
export function queryAndSaveOnePureEffect(
|
|
363
|
-
self: any,
|
|
364
|
-
map: any
|
|
365
|
-
) {
|
|
366
|
-
return (pure: any) =>
|
|
367
|
-
queryOneEffect(self, map)
|
|
368
|
-
.flatMap((_) => saveWithPure_(self, _, pure))
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
/**
|
|
372
|
-
* @tsplus fluent Repository queryAndSaveOnePure
|
|
373
|
-
*/
|
|
374
|
-
export function queryAndSaveOnePure<
|
|
375
|
-
T extends { id: unknown },
|
|
376
|
-
PM extends PersistenceModelType<string>,
|
|
377
|
-
Evt,
|
|
378
|
-
ItemType extends string,
|
|
379
|
-
S extends T = T
|
|
380
|
-
>(
|
|
381
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>,
|
|
382
|
-
map: { filter: Filter<PM>; collect: (t: T) => Option<S>; limit?: number; skip?: number }
|
|
383
|
-
): <R2, A, E2, S2>(pure: Effect<A, E2, FixEnv<R2, Evt, S, S2>>) => Effect<
|
|
384
|
-
A,
|
|
385
|
-
InvalidStateError | OptimisticConcurrencyException | E2 | NotFoundError<ItemType>,
|
|
386
|
-
Exclude<R2, {
|
|
387
|
-
env: PureEnv<Evt, S, S2>
|
|
388
|
-
}>
|
|
389
|
-
>
|
|
390
|
-
export function queryAndSaveOnePure<
|
|
391
|
-
T extends { id: unknown },
|
|
392
|
-
PM extends PersistenceModelType<string>,
|
|
393
|
-
Evt,
|
|
394
|
-
ItemType extends string
|
|
395
|
-
>(
|
|
396
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>,
|
|
397
|
-
map: { filter: Filter<PM> }
|
|
398
|
-
): <R2, A, E2, T2>(pure: Effect<A, E2, FixEnv<R2, Evt, T, T2>>) => Effect<
|
|
399
|
-
A,
|
|
400
|
-
InvalidStateError | OptimisticConcurrencyException | E2 | NotFoundError<ItemType>,
|
|
401
|
-
Exclude<R2, {
|
|
402
|
-
env: PureEnv<Evt, T, T2>
|
|
403
|
-
}>
|
|
404
|
-
>
|
|
405
|
-
export function queryAndSaveOnePure(
|
|
406
|
-
self: any,
|
|
407
|
-
map: { filter: Filter<any>; collect?: any }
|
|
408
|
-
) {
|
|
409
|
-
return queryAndSaveOnePureEffect(self, Effect.sync(() => map))
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
/**
|
|
413
|
-
* @tsplus fluent Repository queryAndSavePureEffect
|
|
414
|
-
*/
|
|
415
|
-
export function queryAndSavePureEffect<
|
|
416
|
-
T extends { id: unknown },
|
|
417
|
-
PM extends PersistenceModelType<string>,
|
|
418
|
-
Evt,
|
|
419
|
-
ItemType extends string,
|
|
420
|
-
R,
|
|
421
|
-
E,
|
|
422
|
-
S extends T = T
|
|
423
|
-
>(
|
|
424
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>,
|
|
425
|
-
map: Effect<{ filter: Filter<PM>; collect?: (t: T) => Option<S>; limit?: number; skip?: number }, E, R>
|
|
426
|
-
) {
|
|
427
|
-
return <R2, A, E2, S2 extends T>(pure: Effect<A, E2, FixEnv<R2, Evt, S[], S2[]>>) =>
|
|
428
|
-
queryEffect(self, map)
|
|
429
|
-
.flatMap((_) => self.saveManyWithPure_(_, pure));
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
/**
|
|
433
|
-
* @tsplus fluent Repository queryAndSavePure
|
|
434
|
-
*/
|
|
435
|
-
export function queryAndSavePure<
|
|
436
|
-
T extends { id: unknown },
|
|
437
|
-
PM extends PersistenceModelType<string>,
|
|
438
|
-
Evt,
|
|
439
|
-
ItemType extends string,
|
|
440
|
-
S extends T = T
|
|
441
|
-
>(
|
|
442
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>,
|
|
443
|
-
map: { filter: Filter<PM>; collect?: (t: T) => Option<S>; limit?: number; skip?: number }
|
|
444
|
-
) {
|
|
445
|
-
return self.queryAndSavePureEffect(Effect.sync(() => map))
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
/**
|
|
449
|
-
* @tsplus getter Repository saveManyWithPure
|
|
450
|
-
*/
|
|
451
|
-
export function saveManyWithPure<
|
|
452
|
-
T extends { id: unknown },
|
|
453
|
-
PM extends PersistenceModelType<string>,
|
|
454
|
-
Evt,
|
|
455
|
-
ItemType extends string
|
|
456
|
-
>(self: RepositoryBaseC<T, PM, Evt, ItemType>) {
|
|
457
|
-
return <R, A, E, S1 extends T, S2 extends T>(pure: Effect<A, E, FixEnv<R, Evt, S1[], S2[]>>) =>
|
|
458
|
-
(items: Iterable<S1>) => saveManyWithPure_(self, items, pure);
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
/**
|
|
462
|
-
* @tsplus fluent Repository byIdAndSaveWithPure
|
|
463
|
-
*/
|
|
464
|
-
export function byIdAndSaveWithPure<
|
|
465
|
-
T extends { id: unknown },
|
|
466
|
-
PM extends PersistenceModelType<string>,
|
|
467
|
-
Evt,
|
|
468
|
-
ItemType extends string
|
|
469
|
-
>(self: RepositoryBaseC<T, PM, Evt, ItemType>, id: T["id"]) {
|
|
470
|
-
return <R, A, E, S2 extends T>(pure: Effect<A, E, FixEnv<R, Evt, T, S2>>) =>
|
|
471
|
-
get(self, id).flatMap((item) => saveWithPure_(self, item, pure));
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
/**
|
|
475
|
-
* NOTE: it's not as composable, only useful when the request is simple, and only this part needs request args.
|
|
476
|
-
* @tsplus getter Repository handleByIdAndSaveWithPure
|
|
477
|
-
*/
|
|
478
|
-
export function handleByIdAndSaveWithPure<
|
|
479
|
-
T extends { id: unknown },
|
|
480
|
-
PM extends PersistenceModelType<string>,
|
|
481
|
-
Evt,
|
|
482
|
-
ItemType extends string
|
|
483
|
-
>(self: RepositoryBaseC<T, PM, Evt, ItemType>) {
|
|
484
|
-
return <Req extends { id: T["id"] }, Context, R, A, E, S2 extends T>(
|
|
485
|
-
pure: (req: Req, ctx: Context) => Effect<A, E, FixEnv<R, Evt, T, S2>>
|
|
486
|
-
) =>
|
|
487
|
-
(req: Req, ctx: Context) => byIdAndSaveWithPure(self, req.id)(pure(req, ctx));
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
/**
|
|
491
|
-
* @tsplus fluent Repository saveManyWithPure_
|
|
492
|
-
*/
|
|
493
|
-
export function saveManyWithPure_<
|
|
494
|
-
R,
|
|
495
|
-
T extends { id: unknown },
|
|
496
|
-
PM extends PersistenceModelType<string>,
|
|
497
|
-
A,
|
|
498
|
-
E,
|
|
499
|
-
Evt,
|
|
500
|
-
S1 extends T,
|
|
501
|
-
S2 extends T,
|
|
502
|
-
ItemType extends string
|
|
503
|
-
>(
|
|
504
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>,
|
|
505
|
-
items: Iterable<S1>,
|
|
506
|
-
pure: Effect<A, E, FixEnv<R, Evt, S1[], S2[]>>
|
|
507
|
-
) {
|
|
508
|
-
return saveAllWithEffectInt(
|
|
509
|
-
self,
|
|
510
|
-
pure.runTerm([...items])
|
|
511
|
-
)
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
/**
|
|
515
|
-
* @tsplus fluent Repository saveWithPure_
|
|
516
|
-
*/
|
|
517
|
-
export function saveWithPure_<
|
|
518
|
-
R,
|
|
519
|
-
T extends { id: unknown },
|
|
520
|
-
PM extends PersistenceModelType<string>,
|
|
521
|
-
A,
|
|
522
|
-
E,
|
|
523
|
-
Evt,
|
|
524
|
-
S1 extends T,
|
|
525
|
-
S2 extends T,
|
|
526
|
-
ItemType extends string
|
|
527
|
-
>(
|
|
528
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>,
|
|
529
|
-
item: S1,
|
|
530
|
-
pure: Effect<A, E, FixEnv<R, Evt, S1, S2>>
|
|
531
|
-
) {
|
|
532
|
-
return saveAllWithEffectInt(
|
|
533
|
-
self,
|
|
534
|
-
pure
|
|
535
|
-
.runTerm(item)
|
|
536
|
-
.map(([item, events, a]) => [[item], events, a])
|
|
537
|
-
)
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
export function saveAllWithEffectInt<
|
|
541
|
-
T extends { id: unknown },
|
|
542
|
-
PM extends PersistenceModelType<string>,
|
|
543
|
-
P extends T,
|
|
544
|
-
Evt,
|
|
545
|
-
ItemType extends string,
|
|
546
|
-
R,
|
|
547
|
-
E,
|
|
548
|
-
A
|
|
549
|
-
>(
|
|
550
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>,
|
|
551
|
-
gen: Effect<readonly [Iterable<P>, Iterable<Evt>, A], E, R>
|
|
552
|
-
) {
|
|
553
|
-
return gen
|
|
554
|
-
.flatMap(
|
|
555
|
-
([items, events, a]) => self.saveAndPublish(items, events).map(() => a)
|
|
556
|
-
)
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
/**
|
|
560
|
-
* @tsplus fluent Repository queryAndSavePureEffectBatched
|
|
561
|
-
*/
|
|
562
|
-
export function queryAndSavePureEffectBatched<
|
|
563
|
-
T extends { id: unknown },
|
|
564
|
-
PM extends PersistenceModelType<string>,
|
|
565
|
-
Evt,
|
|
566
|
-
ItemType extends string,
|
|
567
|
-
R,
|
|
568
|
-
E,
|
|
569
|
-
S extends T = T
|
|
570
|
-
>(
|
|
571
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>,
|
|
572
|
-
// TODO: think about collectPM, collectE, and collect(Parsed)
|
|
573
|
-
map: Effect<{ filter: Filter<PM>; collect?: (t: T) => Option<S>; limit?: number; skip?: number }, E, R>,
|
|
574
|
-
batchSize = 100
|
|
575
|
-
) {
|
|
576
|
-
return <R2, A, E2, S2 extends T>(pure: Effect<A, E2, FixEnv<R2, Evt, S[], S2[]>>) =>
|
|
577
|
-
queryEffect(self, map)
|
|
578
|
-
.flatMap((_) => self.saveManyWithPureBatched_(_, pure, batchSize));
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
/**
|
|
582
|
-
* @tsplus fluent Repository queryAndSavePureBatched
|
|
583
|
-
*/
|
|
584
|
-
export function queryAndSavePureBatched<
|
|
585
|
-
T extends { id: unknown },
|
|
586
|
-
PM extends PersistenceModelType<string>,
|
|
587
|
-
Evt,
|
|
588
|
-
ItemType extends string,
|
|
589
|
-
S extends T = T
|
|
590
|
-
>(
|
|
591
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>,
|
|
592
|
-
// TODO: think about collectPM, collectE, and collect(Parsed)
|
|
593
|
-
map: { filter: Filter<PM>; collect?: (t: T) => Option<S>; limit?: number; skip?: number },
|
|
594
|
-
batchSize = 100
|
|
595
|
-
) {
|
|
596
|
-
return self.queryAndSavePureEffectBatched(Effect.sync(() => map), batchSize)
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
/**
|
|
600
|
-
* @tsplus fluent Repository saveManyWithPureBatched
|
|
601
|
-
*/
|
|
602
|
-
export function saveManyWithPureBatched<
|
|
603
|
-
T extends { id: unknown },
|
|
604
|
-
PM extends PersistenceModelType<string>,
|
|
605
|
-
Evt,
|
|
606
|
-
ItemType extends string
|
|
607
|
-
>(self: RepositoryBaseC<T, PM, Evt, ItemType>, batchSize = 100) {
|
|
608
|
-
return <R, A, E, S1 extends T, S2 extends T>(pure: Effect<A, E, FixEnv<R, Evt, S1[], S2[]>>) =>
|
|
609
|
-
(items: Iterable<S1>) => saveManyWithPureBatched_(self, items, pure, batchSize);
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
/**
|
|
613
|
-
* @tsplus fluent Repository saveManyWithPureBatched_
|
|
614
|
-
*/
|
|
615
|
-
export function saveManyWithPureBatched_<
|
|
616
|
-
R,
|
|
617
|
-
T extends { id: unknown },
|
|
618
|
-
PM extends PersistenceModelType<string>,
|
|
619
|
-
A,
|
|
620
|
-
E,
|
|
621
|
-
Evt,
|
|
622
|
-
S1 extends T,
|
|
623
|
-
S2 extends T,
|
|
624
|
-
ItemType extends string
|
|
625
|
-
>(
|
|
626
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>,
|
|
627
|
-
items: Iterable<S1>,
|
|
628
|
-
pure: Effect<A, E, FixEnv<R, Evt, S1[], S2[]>>,
|
|
629
|
-
batchSize = 100
|
|
630
|
-
) {
|
|
631
|
-
return items
|
|
632
|
-
.chunk(batchSize)
|
|
633
|
-
.forEachEffect((batch) =>
|
|
634
|
-
saveAllWithEffectInt(
|
|
635
|
-
self,
|
|
636
|
-
pure.runTerm(batch)
|
|
637
|
-
)
|
|
638
|
-
)
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
const anyDSL = makeDSL<any, any, any>()
|
|
642
|
-
|
|
643
|
-
export type AllDSL<T, Evt> =
|
|
644
|
-
& (<R, A, E, S1 extends T, S2 extends T>(
|
|
645
|
-
pure: (dsl: PureDSL<S1[], S2[], Evt>) => Effect<A, E, R>
|
|
646
|
-
) => Effect<A, E, FixEnv<R, Evt, S1[], S2[]>>)
|
|
647
|
-
& AllDSLExt<T, Evt>
|
|
648
|
-
|
|
649
|
-
/**
|
|
650
|
-
* @tsplus type DSLExt
|
|
651
|
-
*/
|
|
652
|
-
export interface AllDSLExt<T, Evt> {
|
|
653
|
-
modify: <R, E, A, S1 extends T, S2 extends T>(
|
|
654
|
-
pure: (items: S1[], dsl: PureDSL<S1[], S2[], Evt>) => Effect<A, E, R>
|
|
655
|
-
) => Effect<A, E, FixEnv<R, Evt, S1[], S2[]>>
|
|
656
|
-
update: <R, E, S1 extends T, S2 extends T>(
|
|
657
|
-
pure: (items: S1[], log: (...evt: Evt[]) => PureLogT<Evt>) => Effect<S2[], E, R>
|
|
658
|
-
) => Effect<S2[], E, FixEnv<R, Evt, S1[], S2[]>>
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
export function makeAllDSL<T, Evt>() {
|
|
662
|
-
const dsl: AllDSL<T, Evt> = anyDSL
|
|
663
|
-
return dsl
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
export type OneDSL<T, Evt> =
|
|
667
|
-
& (<R, A, E, S1 extends T, S2 extends T>(
|
|
668
|
-
pure: (dsl: PureDSL<S1, S2, Evt>) => Effect<A, E, FixEnv<R, Evt, S1, S2>>
|
|
669
|
-
) => Effect<A, E, FixEnv<R, Evt, S1, S2>>)
|
|
670
|
-
& OneDSLExt<T, Evt>
|
|
671
|
-
|
|
672
|
-
/**
|
|
673
|
-
* @tsplus type DSLExt
|
|
674
|
-
*/
|
|
675
|
-
export interface OneDSLExt<T, Evt> {
|
|
676
|
-
modify: <R, E, A, S1 extends T, S2 extends T>(
|
|
677
|
-
pure: (items: S1, dsl: PureDSL<S1, S2, Evt>) => Effect<A, E, FixEnv<R, Evt, S1, S2>>
|
|
678
|
-
) => Effect<A, E, FixEnv<R, Evt, S1, S2> | PureEnvEnv<Evt, S1, S1>>
|
|
679
|
-
update: <R, E, S1 extends T, S2 extends T>(
|
|
680
|
-
pure: (items: S1, log: (...evt: Evt[]) => PureLogT<Evt>) => Effect<S2, E, FixEnv<R, Evt, S1, S2>>
|
|
681
|
-
) => Effect<S2, E, FixEnv<R, Evt, S1, S2>>
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
/**
|
|
685
|
-
* @tsplus fluent DSLExt updateWith
|
|
686
|
-
*/
|
|
687
|
-
export function updateWithOne<T, Evt, S1 extends T, S2 extends T>(self: OneDSL<T, Evt>, upd: (item: S1) => S2) {
|
|
688
|
-
return self.update((_: S1) => Effect.sync(() => upd(_)))
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
/**
|
|
692
|
-
* @tsplus fluent DSLExt updateWith
|
|
693
|
-
*/
|
|
694
|
-
export function updateWith<T, Evt, S1 extends T, S2 extends T>(
|
|
695
|
-
self: AllDSL<T, Evt>,
|
|
696
|
-
upd: (item: S1[]) => S2[]
|
|
697
|
-
) {
|
|
698
|
-
return self.update((_: S1[]) => Effect.sync(() => upd(_)))
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
export function makeOneDSL<T, Evt>(): OneDSL<T, Evt> {
|
|
702
|
-
return anyDSL
|
|
703
|
-
}
|
|
704
|
-
|
|
705
|
-
export function makeDSL<S1, S2, Evt>() {
|
|
706
|
-
const dsl: PureDSL<S1, S2, Evt> = AnyPureDSL
|
|
707
|
-
|
|
708
|
-
function modify<
|
|
709
|
-
R,
|
|
710
|
-
E,
|
|
711
|
-
A
|
|
712
|
-
>(
|
|
713
|
-
pure: (
|
|
714
|
-
items: S1,
|
|
715
|
-
dsl: PureDSL<S1, S2, Evt>
|
|
716
|
-
) => Effect<A, E, R>
|
|
717
|
-
): Effect<A, E, FixEnv<R, Evt, S1, S2>> {
|
|
718
|
-
return dsl.get.flatMap((items) => pure(items, dsl)) as any
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
function update<
|
|
722
|
-
R,
|
|
723
|
-
E
|
|
724
|
-
>(
|
|
725
|
-
pure: (
|
|
726
|
-
items: S1,
|
|
727
|
-
log: (...evt: Evt[]) => PureLogT<Evt>
|
|
728
|
-
) => Effect<S2, E, R>
|
|
729
|
-
): Effect<S2, E, FixEnv<R, Evt, S1, S2>> {
|
|
730
|
-
return dsl.get.flatMap((items) => pure(items, dsl.log).tap(dsl.set)) as any
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
function withDSL<
|
|
734
|
-
R,
|
|
735
|
-
A,
|
|
736
|
-
E
|
|
737
|
-
>(
|
|
738
|
-
pure: (dsl: PureDSL<S1, S2, Evt>) => Effect<A, E, R>
|
|
739
|
-
): Effect<A, E, FixEnv<R, Evt, S1, S2>> {
|
|
740
|
-
return pure(AnyPureDSL) as any
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
return Object.assign(
|
|
744
|
-
withDSL,
|
|
745
|
-
{
|
|
746
|
-
modify,
|
|
747
|
-
update
|
|
748
|
-
}
|
|
749
|
-
)
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
export interface DSLExt<S1, S2, Evt> extends ReturnType<typeof makeDSL<S1, S2, Evt>> {}
|
|
753
|
-
|
|
754
|
-
export function ifAny<T, R, E, A>(fn: (items: NonEmptyReadonlyArray<T>) => Effect<A, E, R>) {
|
|
755
|
-
return (items: Iterable<T>) => Effect.sync(() => items.toNonEmptyArray).flatMapOpt(fn)
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
/**
|
|
759
|
-
* @tsplus fluent Iterable ifAny
|
|
760
|
-
*/
|
|
761
|
-
export function ifAny_<T, R, E, A>(items: Iterable<T>, fn: (items: NonEmptyReadonlyArray<T>) => Effect<A, E, R>) {
|
|
762
|
-
return Effect.sync(() => items.toNonEmptyArray).flatMapOpt(fn)
|
|
763
|
-
}
|
|
764
|
-
|
|
765
|
-
/**
|
|
766
|
-
* @tsplus getter Repository save
|
|
767
|
-
*/
|
|
768
|
-
export function save<
|
|
769
|
-
T extends { id: unknown },
|
|
770
|
-
PM extends PersistenceModelType<string>,
|
|
771
|
-
Evt,
|
|
772
|
-
ItemType extends string
|
|
773
|
-
>(
|
|
774
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>
|
|
775
|
-
) {
|
|
776
|
-
return (...items: NonEmptyArray<T>) => self.saveAndPublish(items)
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
/**
|
|
780
|
-
* @tsplus getter Repository saveWithEvents
|
|
781
|
-
*/
|
|
782
|
-
export function saveWithEvents<
|
|
783
|
-
T extends { id: unknown },
|
|
784
|
-
PM extends PersistenceModelType<string>,
|
|
785
|
-
Evt,
|
|
786
|
-
ItemType extends string
|
|
787
|
-
>(
|
|
788
|
-
self: RepositoryBaseC<T, PM, Evt, ItemType>
|
|
789
|
-
) {
|
|
790
|
-
return (events: Iterable<Evt>) => (...items: NonEmptyArray<T>) => self.saveAndPublish(items, events)
|
|
791
|
-
}
|
|
1
|
+
export * from "./Repository/dsl.js"
|
|
2
|
+
export * from "./Repository/ext.js"
|
|
3
|
+
export * from "./Repository/service.js"
|