@effect-app/infra 0.12.5 → 0.13.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 +14 -0
- package/_cjs/api/defaultErrorHandler.cjs +8 -8
- package/_cjs/api/defaultErrorHandler.cjs.map +1 -1
- package/_cjs/api/routing.cjs +7 -7
- package/_cjs/api/routing.cjs.map +1 -1
- package/_cjs/filter.cjs.map +1 -1
- package/_cjs/services/Repository.cjs +39 -24
- package/_cjs/services/Repository.cjs.map +1 -1
- package/_cjs/services/Store/Cosmos.cjs +3 -7
- package/_cjs/services/Store/Cosmos.cjs.map +1 -1
- package/_cjs/services/Store/codeFilter.test.cjs.map +1 -1
- package/_cjs/services/Store/utils.cjs +2 -2
- package/_cjs/services/Store/utils.cjs.map +1 -1
- package/_cjs/services/simpledb/simpledb.cjs +9 -9
- package/_cjs/services/simpledb/simpledb.cjs.map +1 -1
- package/_src/api/defaultErrorHandler.ts +3 -5
- package/_src/api/routing.ts +12 -13
- package/_src/filter/types/path/common.ts +9 -9
- package/_src/filter/types/path/eager.ts +12 -12
- package/_src/filter/types/utils.ts +1 -1
- package/_src/filter.ts +7 -11
- package/_src/services/Repository.ts +111 -50
- package/_src/services/Store/Cosmos.ts +14 -14
- package/_src/services/Store/codeFilter.test.ts +37 -30
- package/_src/services/Store/utils.ts +34 -34
- package/_src/services/simpledb/simpledb.ts +5 -6
- package/dist/api/defaultErrorHandler.d.ts.map +1 -1
- package/dist/api/defaultErrorHandler.js +11 -11
- package/dist/api/routing.d.ts.map +1 -1
- package/dist/api/routing.js +9 -9
- package/dist/filter/types/path/common.d.ts.map +1 -1
- package/dist/filter/types/path/eager.d.ts.map +1 -1
- package/dist/filter/types/utils.d.ts.map +1 -1
- package/dist/filter.d.ts.map +1 -1
- package/dist/filter.js +2 -2
- package/dist/services/Repository.d.ts +23 -5
- package/dist/services/Repository.d.ts.map +1 -1
- package/dist/services/Repository.js +41 -25
- package/dist/services/Store/Cosmos.js +8 -10
- package/dist/services/Store/codeFilter.test.d.ts.map +1 -1
- package/dist/services/Store/utils.d.ts.map +1 -1
- package/dist/services/Store/utils.js +30 -30
- package/dist/services/simpledb/simpledb.d.ts.map +1 -1
- package/dist/services/simpledb/simpledb.js +9 -9
- package/package.json +4 -4
- package/.jest-cache/haste-map-369fa5ca2164cc35b19159bd76147276-e7a7ff05756c055cb63be97ba8537525-314902b6271c341511f7398a50469024 +0 -0
- package/.jest-cache/haste-map-369fa5ca2164cc35b19159bd76147276-e7a7ff05756c055cb63be97ba8537525-3f072cc7afa09b6adaead0527ab9df83 +0 -0
- package/.jest-cache/haste-map-369fa5ca2164cc35b19159bd76147276-e7a7ff05756c055cb63be97ba8537525-74c3c295c110fc861b6a4c673afc3e24 +0 -0
- package/.jest-cache/haste-map-369fa5ca2164cc35b19159bd76147276-e7a7ff05756c055cb63be97ba8537525-bf6dae8cb9ea9740ceb39aefaf12716c +0 -0
- package/.jest-cache/haste-map-369fa5ca2164cc35b19159bd76147276-e7a7ff05756c055cb63be97ba8537525-cf9d1486029526079a5f68f2041dea02 +0 -0
- package/.jest-cache/haste-map-4ca41cc04e60c616a19cbb483cbf487b-e2f1f4b6d87214e3c49442fed31f310c-b4710ed9fb3d0757c4bf23045c585670 +0 -0
- package/.jest-cache/haste-map-4ca41cc04e60c616a19cbb483cbf487b-e2f1f4b6d87214e3c49442fed31f310c-ee17e5395bb1b7b36a4e2e22a6ae1449 +0 -0
- package/.jest-cache/haste-map-7dc16d7fae8c072843ed1c69eae73100-a8a4225b317477b49bca31f54559afb3-c16136699bb7f463be85273162b447c3 +0 -0
- package/.jest-cache/haste-map-9aa1e395a82e108eb49698982c574272-e2f1f4b6d87214e3c49442fed31f310c-f7435f46fc41ac5a13d06a49cae9a650 +0 -0
- package/.jest-cache/haste-map-9d206b45d610536c9ec65eec263c6964-a8a4225b317477b49bca31f54559afb3-3510506a330b44f1ae629033aac8fbb3 +0 -0
- package/.jest-cache/haste-map-a00ab30d0d656f9d3990958a54b9ccfd-87603b0fc921b26b622a5859b4c92bed-17b550b450b18840c25861aa6e835f0c +0 -0
- package/.jest-cache/haste-map-a00ab30d0d656f9d3990958a54b9ccfd-87603b0fc921b26b622a5859b4c92bed-4dc31290b1efc98335eb4c89167d75c3 +0 -0
- package/.jest-cache/haste-map-ab843cb0ffbadfd0deea4adb182c7ecd-87603b0fc921b26b622a5859b4c92bed-997106edf4bbc31567a378146180e45e +0 -0
- package/.jest-cache/haste-map-ab843cb0ffbadfd0deea4adb182c7ecd-87603b0fc921b26b622a5859b4c92bed-f0cd25414f9ed16c446940ca3aa23c1b +0 -0
- package/.jest-cache/haste-map-cf17f2edf0e949eebfdfca561816457c-e7a7ff05756c055cb63be97ba8537525-2cac07d09e6384e2d37c49714edad0ba +0 -0
- package/.jest-cache/haste-map-cf17f2edf0e949eebfdfca561816457c-e7a7ff05756c055cb63be97ba8537525-d7967c2976c5feac7161c964f0aa442f +0 -0
- package/.jest-cache/haste-map-fb1a173276d25bbff02f815600059283-938122bdc1c8836874b6585d7acb2e99-f705929cca05ce95ceaa6d520b560ce8 +0 -0
|
@@ -1,22 +1,28 @@
|
|
|
1
1
|
// Update = Must return updated items
|
|
2
2
|
// Modify = Must `set` updated items, and can return anything.
|
|
3
|
+
import type { FixEnv, PureLogT } from "@effect-app/prelude/_ext/Pure"
|
|
4
|
+
import { Pure } from "@effect-app/prelude/_ext/Pure"
|
|
5
|
+
import type { ParserEnv } from "@effect-app/schema/custom/Parser"
|
|
3
6
|
import type { InvalidStateError, OptimisticConcurrencyException } from "../errors.js"
|
|
4
7
|
import { NotFoundError } from "../errors.js"
|
|
5
8
|
import type { RequestContext } from "../RequestContext.js"
|
|
6
|
-
import { ContextMap} from "../services/Store.js"
|
|
9
|
+
import { ContextMap } from "../services/Store.js"
|
|
7
10
|
import type { Filter } from "../services/Store.js"
|
|
8
|
-
import type { FixEnv, PureLogT} from "@effect-app/prelude/_ext/Pure";
|
|
9
|
-
import { Pure } from "@effect-app/prelude/_ext/Pure"
|
|
10
|
-
import type { ParserEnv } from "@effect-app/schema/custom/Parser"
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* @tsplus type Repository
|
|
14
14
|
*/
|
|
15
|
-
export interface Repository<
|
|
15
|
+
export interface Repository<
|
|
16
|
+
T extends { id: Id },
|
|
17
|
+
PM extends { id: string },
|
|
18
|
+
Evt,
|
|
19
|
+
Id extends string,
|
|
20
|
+
ItemType extends string
|
|
21
|
+
> {
|
|
16
22
|
itemType: ItemType
|
|
17
23
|
find: (id: Id) => Effect<ContextMap | RequestContext, never, Opt<T>>
|
|
18
24
|
all: Effect<ContextMap, never, Chunk<T>>
|
|
19
|
-
|
|
25
|
+
saveAndPublish: (
|
|
20
26
|
items: Iterable<T>,
|
|
21
27
|
events?: Iterable<Evt>
|
|
22
28
|
) => Effect<ContextMap | RequestContext, InvalidStateError | OptimisticConcurrencyException, void>
|
|
@@ -24,18 +30,24 @@ export interface Repository<T extends { id: Id }, PM extends { id: string }, Evt
|
|
|
24
30
|
mapReverse: (
|
|
25
31
|
pm: PM,
|
|
26
32
|
setEtag: (id: string, eTag: string | undefined) => void
|
|
27
|
-
) => unknown
|
|
28
|
-
parse: (a: unknown, env?: ParserEnv | undefined) => T
|
|
29
|
-
all: Effect<never, never, Chunk<PM
|
|
30
|
-
filter: (filter: Filter<PM>, cursor?: { limit?: number
|
|
33
|
+
) => unknown // TODO
|
|
34
|
+
parse: (a: unknown, env?: ParserEnv | undefined) => T
|
|
35
|
+
all: Effect<never, never, Chunk<PM>>
|
|
36
|
+
filter: (filter: Filter<PM>, cursor?: { limit?: number; skip?: number }) => Effect<never, never, Chunk<PM>>
|
|
31
37
|
}
|
|
32
38
|
}
|
|
33
39
|
|
|
34
40
|
export interface PureDSL<S, S2, W> {
|
|
35
|
-
get: ReturnType<typeof Pure.get<S
|
|
41
|
+
get: ReturnType<typeof Pure.get<S>>
|
|
42
|
+
set: typeof Pure.set<S2>
|
|
43
|
+
log: (...w: W[]) => PureLogT<W>
|
|
36
44
|
}
|
|
37
45
|
|
|
38
|
-
export const AnyPureDSL: PureDSL<any, any, any> = {
|
|
46
|
+
export const AnyPureDSL: PureDSL<any, any, any> = {
|
|
47
|
+
get: Pure.get(),
|
|
48
|
+
set: Pure.set,
|
|
49
|
+
log: (...evt: any[]) => Pure.logMany(evt)
|
|
50
|
+
}
|
|
39
51
|
|
|
40
52
|
/**
|
|
41
53
|
* @tsplus fluent Repository get
|
|
@@ -61,7 +73,7 @@ export function filter<
|
|
|
61
73
|
T extends { id: Id },
|
|
62
74
|
PM extends { id: string },
|
|
63
75
|
Evt,
|
|
64
|
-
ItemType extends string
|
|
76
|
+
ItemType extends string
|
|
65
77
|
>(self: Repository<T, PM, Evt, Id, ItemType>, filter: Predicate<T>) {
|
|
66
78
|
return self.all.map(_ => _.filter(filter))
|
|
67
79
|
}
|
|
@@ -75,12 +87,11 @@ export function filterAll<
|
|
|
75
87
|
PM extends { id: string },
|
|
76
88
|
Evt,
|
|
77
89
|
ItemType extends string,
|
|
78
|
-
S extends T
|
|
90
|
+
S extends T
|
|
79
91
|
>(self: Repository<T, PM, Evt, Id, ItemType>, map: (items: Chunk<T>) => Chunk<S>) {
|
|
80
92
|
return self.all.map(map)
|
|
81
93
|
}
|
|
82
94
|
|
|
83
|
-
|
|
84
95
|
/**
|
|
85
96
|
* @tsplus fluent Repository collect
|
|
86
97
|
*/
|
|
@@ -90,7 +101,7 @@ export function collect<
|
|
|
90
101
|
PM extends { id: string },
|
|
91
102
|
Evt,
|
|
92
103
|
ItemType extends string,
|
|
93
|
-
S extends T
|
|
104
|
+
S extends T
|
|
94
105
|
>(self: Repository<T, PM, Evt, Id, ItemType>, collect: (item: T) => Opt<S>) {
|
|
95
106
|
return self.all.map(_ => _.filterMap(collect))
|
|
96
107
|
}
|
|
@@ -127,7 +138,7 @@ export function projectEffect<
|
|
|
127
138
|
) {
|
|
128
139
|
// TODO: a projection that gets sent to the db instead.
|
|
129
140
|
return map.flatMap(f =>
|
|
130
|
-
(f.filter ? self.utils.filter(f.filter, { limit: f.limit, skip: f.skip}) : self.utils.all)
|
|
141
|
+
(f.filter ? self.utils.filter(f.filter, { limit: f.limit, skip: f.skip }) : self.utils.all)
|
|
131
142
|
.map(_ => _.filterMap(f.collect))
|
|
132
143
|
)
|
|
133
144
|
}
|
|
@@ -142,7 +153,7 @@ export function project<
|
|
|
142
153
|
PM extends { id: string },
|
|
143
154
|
Evt,
|
|
144
155
|
ItemType extends string,
|
|
145
|
-
S
|
|
156
|
+
S
|
|
146
157
|
>(
|
|
147
158
|
self: Repository<T, PM, Evt, Id, ItemType>,
|
|
148
159
|
map: { filter?: Filter<PM>; collect: (t: PM) => Opt<S>; limit?: number; skip?: number }
|
|
@@ -150,7 +161,6 @@ export function project<
|
|
|
150
161
|
return self.projectEffect(Effect(map))
|
|
151
162
|
}
|
|
152
163
|
|
|
153
|
-
|
|
154
164
|
/**
|
|
155
165
|
* @tsplus fluent Repository queryEffect
|
|
156
166
|
*/
|
|
@@ -162,14 +172,14 @@ export function queryEffect<
|
|
|
162
172
|
ItemType extends string,
|
|
163
173
|
R,
|
|
164
174
|
E,
|
|
165
|
-
S
|
|
175
|
+
S
|
|
166
176
|
>(
|
|
167
177
|
self: Repository<T, PM, Evt, Id, ItemType>,
|
|
168
178
|
// TODO: think about collectPM, collectE, and collect(Parsed)
|
|
169
179
|
map: Effect<R, E, { filter?: Filter<PM>; collect: (t: T) => Opt<S>; limit?: number; skip?: number }>
|
|
170
180
|
) {
|
|
171
181
|
return map.flatMap(f =>
|
|
172
|
-
(f.filter ? self.utils.filter(f.filter, { limit: f.limit, skip: f.skip}) : self.utils.all)
|
|
182
|
+
(f.filter ? self.utils.filter(f.filter, { limit: f.limit, skip: f.skip }) : self.utils.all)
|
|
173
183
|
.flatMap(items =>
|
|
174
184
|
Do($ => {
|
|
175
185
|
const { set } = $(Effect.service(ContextMap))
|
|
@@ -192,7 +202,7 @@ export function queryOneEffect<
|
|
|
192
202
|
ItemType extends string,
|
|
193
203
|
R,
|
|
194
204
|
E,
|
|
195
|
-
S
|
|
205
|
+
S
|
|
196
206
|
>(
|
|
197
207
|
self: Repository<T, PM, Evt, Id, ItemType>,
|
|
198
208
|
// TODO: think about collectPM, collectE, and collect(Parsed)
|
|
@@ -207,7 +217,11 @@ export function queryOneEffect<
|
|
|
207
217
|
})
|
|
208
218
|
)
|
|
209
219
|
.map(_ => _.map(_ => self.utils.parse(_)))
|
|
210
|
-
.flatMap(_ =>
|
|
220
|
+
.flatMap(_ =>
|
|
221
|
+
_.filterMap(f.collect).toNonEmptyArray.encaseInEffect(() =>
|
|
222
|
+
new NotFoundError(self.itemType, JSON.stringify(f.filter))
|
|
223
|
+
).map(_ => _[0])
|
|
224
|
+
)
|
|
211
225
|
)
|
|
212
226
|
}
|
|
213
227
|
|
|
@@ -220,7 +234,7 @@ export function query<
|
|
|
220
234
|
PM extends { id: string },
|
|
221
235
|
Evt,
|
|
222
236
|
ItemType extends string,
|
|
223
|
-
S
|
|
237
|
+
S
|
|
224
238
|
>(
|
|
225
239
|
self: Repository<T, PM, Evt, Id, ItemType>,
|
|
226
240
|
// TODO: think about collectPM, collectE, and collect(Parsed)
|
|
@@ -238,7 +252,7 @@ export function queryOne<
|
|
|
238
252
|
PM extends { id: string },
|
|
239
253
|
Evt,
|
|
240
254
|
ItemType extends string,
|
|
241
|
-
S
|
|
255
|
+
S
|
|
242
256
|
>(
|
|
243
257
|
self: Repository<T, PM, Evt, Id, ItemType>,
|
|
244
258
|
// TODO: think about collectPM, collectE, and collect(Parsed)
|
|
@@ -258,7 +272,7 @@ export function queryAndSavePureEffect<
|
|
|
258
272
|
ItemType extends string,
|
|
259
273
|
R,
|
|
260
274
|
E,
|
|
261
|
-
S extends T = T
|
|
275
|
+
S extends T = T
|
|
262
276
|
>(
|
|
263
277
|
self: Repository<T, PM, Evt, Id, ItemType>,
|
|
264
278
|
// TODO: think about collectPM, collectE, and collect(Parsed)
|
|
@@ -278,7 +292,7 @@ export function queryAndSavePure<
|
|
|
278
292
|
PM extends { id: string },
|
|
279
293
|
Evt,
|
|
280
294
|
ItemType extends string,
|
|
281
|
-
S extends T = T
|
|
295
|
+
S extends T = T
|
|
282
296
|
>(
|
|
283
297
|
self: Repository<T, PM, Evt, Id, ItemType>,
|
|
284
298
|
// TODO: think about collectPM, collectE, and collect(Parsed)
|
|
@@ -298,7 +312,7 @@ export function saveManyWithPure<
|
|
|
298
312
|
ItemType extends string
|
|
299
313
|
>(self: Repository<T, PM, Evt, Id, ItemType>) {
|
|
300
314
|
return <R, A, E, S1 extends T, S2 extends T>(pure: Effect<FixEnv<R, Evt, Chunk<S1>, Iterable<S2>>, E, A>) =>
|
|
301
|
-
|
|
315
|
+
(items: Iterable<S1>) => saveManyWithPure_(self, items, pure)
|
|
302
316
|
}
|
|
303
317
|
|
|
304
318
|
/**
|
|
@@ -311,7 +325,8 @@ export function byIdAndSaveWithPure<
|
|
|
311
325
|
Evt,
|
|
312
326
|
ItemType extends string
|
|
313
327
|
>(self: Repository<T, PM, Evt, Id, ItemType>, id: Id) {
|
|
314
|
-
return <R, A, E, S2 extends T>(pure: Effect<FixEnv<R, Evt, T, S2>, E, A>) =>
|
|
328
|
+
return <R, A, E, S2 extends T>(pure: Effect<FixEnv<R, Evt, T, S2>, E, A>) =>
|
|
329
|
+
get(self, id).flatMap(item => saveWithPure_(self, item, pure))
|
|
315
330
|
}
|
|
316
331
|
|
|
317
332
|
/**
|
|
@@ -323,9 +338,12 @@ export function handleByIdAndSaveWithPure<
|
|
|
323
338
|
T extends { id: Id },
|
|
324
339
|
PM extends { id: string },
|
|
325
340
|
Evt,
|
|
326
|
-
ItemType extends string
|
|
341
|
+
ItemType extends string
|
|
327
342
|
>(self: Repository<T, PM, Evt, Id, ItemType>) {
|
|
328
|
-
return <Req extends { id: Id }, Context, R, A, E, S2 extends T>(
|
|
343
|
+
return <Req extends { id: Id }, Context, R, A, E, S2 extends T>(
|
|
344
|
+
pure: (req: Req, ctx: Context) => Effect<FixEnv<R, Evt, T, S2>, E, A>
|
|
345
|
+
) =>
|
|
346
|
+
(req: Req, ctx: Context) => byIdAndSaveWithPure(self, req.id)(pure(req, ctx))
|
|
329
347
|
}
|
|
330
348
|
|
|
331
349
|
/**
|
|
@@ -375,7 +393,7 @@ export function saveWithPure_<
|
|
|
375
393
|
return saveAllWithEffectInt(
|
|
376
394
|
self,
|
|
377
395
|
pure.runTerm(item)
|
|
378
|
-
|
|
396
|
+
.map(([item, events, a]) => [[item], events, a])
|
|
379
397
|
)
|
|
380
398
|
}
|
|
381
399
|
|
|
@@ -396,7 +414,7 @@ function saveAllWithEffectInt<
|
|
|
396
414
|
return gen
|
|
397
415
|
.flatMap(
|
|
398
416
|
([items, events, a]) =>
|
|
399
|
-
self.
|
|
417
|
+
self.saveAndPublish(items, events)
|
|
400
418
|
.map(() => a)
|
|
401
419
|
)
|
|
402
420
|
}
|
|
@@ -404,16 +422,21 @@ function saveAllWithEffectInt<
|
|
|
404
422
|
const anyDSL = makeDSL<any, any, any>()
|
|
405
423
|
|
|
406
424
|
export type AllDSL<T, Evt> =
|
|
407
|
-
(<R, A, E, S1 extends T, S2 extends T>(
|
|
408
|
-
|
|
425
|
+
& (<R, A, E, S1 extends T, S2 extends T>(
|
|
426
|
+
pure: (dsl: PureDSL<Chunk<S1>, Iterable<S2>, Evt>) => Effect<R, E, A>
|
|
427
|
+
) => Effect<FixEnv<R, Evt, Chunk<S1>, Iterable<S2>>, E, A>)
|
|
428
|
+
& AllDSLExt<T, Evt>
|
|
409
429
|
|
|
410
|
-
|
|
411
430
|
/**
|
|
412
431
|
* @tsplus type DSLExt
|
|
413
432
|
*/
|
|
414
|
-
export interface AllDSLExt<T, Evt>
|
|
415
|
-
modify: <R, E, A, S1 extends T, S2 extends T>(
|
|
416
|
-
|
|
433
|
+
export interface AllDSLExt<T, Evt> {
|
|
434
|
+
modify: <R, E, A, S1 extends T, S2 extends T>(
|
|
435
|
+
pure: (items: Chunk<S1>, dsl: PureDSL<Chunk<S1>, Iterable<S2>, Evt>) => Effect<R, E, A>
|
|
436
|
+
) => Effect<FixEnv<R, Evt, Chunk<S1>, Iterable<S2>>, E, A>
|
|
437
|
+
update: <R, E, S1 extends T, S2 extends T>(
|
|
438
|
+
pure: (items: Chunk<S1>, log: (...evt: Evt[]) => PureLogT<Evt>) => Effect<R, E, Iterable<S2>>
|
|
439
|
+
) => Effect<FixEnv<R, Evt, Chunk<S1>, Iterable<S2>>, E, Iterable<S2>>
|
|
417
440
|
}
|
|
418
441
|
|
|
419
442
|
export function makeAllDSL<T, Evt>() {
|
|
@@ -422,16 +445,21 @@ export function makeAllDSL<T, Evt>() {
|
|
|
422
445
|
}
|
|
423
446
|
|
|
424
447
|
export type OneDSL<T, Evt> =
|
|
425
|
-
(<R, A, E, S1 extends T, S2 extends T>(
|
|
426
|
-
|
|
427
|
-
|
|
448
|
+
& (<R, A, E, S1 extends T, S2 extends T>(
|
|
449
|
+
pure: (dsl: PureDSL<S1, S2, Evt>) => Effect<FixEnv<R, Evt, S1, S2>, E, A>
|
|
450
|
+
) => Effect<FixEnv<R, Evt, S1, S2>, E, A>)
|
|
451
|
+
& OneDSLExt<T, Evt>
|
|
428
452
|
|
|
429
453
|
/**
|
|
430
454
|
* @tsplus type DSLExt
|
|
431
455
|
*/
|
|
432
456
|
export interface OneDSLExt<T, Evt> {
|
|
433
|
-
modify: <R, E, A, S1 extends T, S2 extends T>(
|
|
434
|
-
|
|
457
|
+
modify: <R, E, A, S1 extends T, S2 extends T>(
|
|
458
|
+
pure: (items: S1, dsl: PureDSL<S1, S2, Evt>) => Effect<FixEnv<R, Evt, S1, S2>, E, A>
|
|
459
|
+
) => Effect<FixEnv<R, Evt, S1, S2> | PureEnvEnv<Evt, S1, S1>, E, A>
|
|
460
|
+
update: <R, E, S1 extends T, S2 extends T>(
|
|
461
|
+
pure: (items: S1, log: (...evt: Evt[]) => PureLogT<Evt>) => Effect<FixEnv<R, Evt, S1, S2>, E, S2>
|
|
462
|
+
) => Effect<FixEnv<R, Evt, S1, S2>, E, S2>
|
|
435
463
|
}
|
|
436
464
|
|
|
437
465
|
/**
|
|
@@ -444,11 +472,14 @@ export function updateWithOne<T, Evt, S1 extends T, S2 extends T>(self: OneDSL<T
|
|
|
444
472
|
/**
|
|
445
473
|
* @tsplus fluent DSLExt updateWith
|
|
446
474
|
*/
|
|
447
|
-
export function updateWith<T, Evt, S1 extends T, S2 extends T>(
|
|
475
|
+
export function updateWith<T, Evt, S1 extends T, S2 extends T>(
|
|
476
|
+
self: AllDSL<T, Evt>,
|
|
477
|
+
upd: (item: Chunk<S1>) => Iterable<S2>
|
|
478
|
+
) {
|
|
448
479
|
return self.update((_: Chunk<S1>) => Effect(upd(_)))
|
|
449
480
|
}
|
|
450
481
|
|
|
451
|
-
export function makeOneDSL<T, Evt>(): OneDSL<T, Evt>
|
|
482
|
+
export function makeOneDSL<T, Evt>(): OneDSL<T, Evt> {
|
|
452
483
|
return anyDSL
|
|
453
484
|
}
|
|
454
485
|
|
|
@@ -491,15 +522,15 @@ export function makeDSL<S1, S2, Evt>() {
|
|
|
491
522
|
}
|
|
492
523
|
|
|
493
524
|
return Object.assign(
|
|
494
|
-
withDSL,
|
|
525
|
+
withDSL,
|
|
526
|
+
{
|
|
495
527
|
modify,
|
|
496
|
-
update
|
|
528
|
+
update
|
|
497
529
|
}
|
|
498
530
|
)
|
|
499
531
|
}
|
|
500
532
|
|
|
501
|
-
export interface DSLExt<S1, S2, Evt> extends ReturnType<typeof makeDSL<S1, S2, Evt>> {
|
|
502
|
-
|
|
533
|
+
export interface DSLExt<S1, S2, Evt> extends ReturnType<typeof makeDSL<S1, S2, Evt>> {}
|
|
503
534
|
|
|
504
535
|
export function ifAny<T, R, E, A>(fn: (items: NonEmptyReadonlyArray<T>) => Effect<R, E, A>) {
|
|
505
536
|
return (items: Iterable<T>) => Effect(items.toNonEmptyArray).flatMapOpt(fn)
|
|
@@ -511,3 +542,33 @@ export function ifAny<T, R, E, A>(fn: (items: NonEmptyReadonlyArray<T>) => Effec
|
|
|
511
542
|
export function ifAny_<T, R, E, A>(items: Iterable<T>, fn: (items: NonEmptyReadonlyArray<T>) => Effect<R, E, A>) {
|
|
512
543
|
return Effect(items.toNonEmptyArray).flatMapOpt(fn)
|
|
513
544
|
}
|
|
545
|
+
|
|
546
|
+
/**
|
|
547
|
+
* @tsplus getter Repository save
|
|
548
|
+
*/
|
|
549
|
+
export function save<
|
|
550
|
+
Id extends string,
|
|
551
|
+
T extends { id: Id },
|
|
552
|
+
PM extends { id: string },
|
|
553
|
+
Evt,
|
|
554
|
+
ItemType extends string
|
|
555
|
+
>(
|
|
556
|
+
self: Repository<T, PM, Evt, Id, ItemType>
|
|
557
|
+
) {
|
|
558
|
+
return (...items: NonEmptyArray<T>) => self.saveAndPublish(items)
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/**
|
|
562
|
+
* @tsplus getter Repository saveWithEvents
|
|
563
|
+
*/
|
|
564
|
+
export function saveWithEvents<
|
|
565
|
+
Id extends string,
|
|
566
|
+
T extends { id: Id },
|
|
567
|
+
PM extends { id: string },
|
|
568
|
+
Evt,
|
|
569
|
+
ItemType extends string
|
|
570
|
+
>(
|
|
571
|
+
self: Repository<T, PM, Evt, Id, ItemType>
|
|
572
|
+
) {
|
|
573
|
+
return (events: Iterable<Evt>) => (...items: NonEmptyArray<T>) => self.saveAndPublish(items, events)
|
|
574
|
+
}
|
|
@@ -237,23 +237,23 @@ export function makeCosmosStore({ prefix }: StorageConfig) {
|
|
|
237
237
|
const skip = cursor?.skip
|
|
238
238
|
const limit = cursor?.limit
|
|
239
239
|
return (filter.type === "join_find"
|
|
240
|
-
|
|
240
|
+
// This is a problem if one of the multiple joined arrays can be empty!
|
|
241
241
|
// https://stackoverflow.com/questions/60320780/azure-cosmosdb-sql-join-not-returning-results-when-the-child-contains-empty-arra
|
|
242
242
|
// so we use multiple queries instead.
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
)
|
|
243
|
+
? filter.keys
|
|
244
|
+
.forEachEffect(k =>
|
|
245
|
+
Effect(() => buildFindJoinCosmosQuery(filter, k, name, skip, limit))
|
|
246
|
+
.tap(q => logQuery(q))
|
|
247
|
+
.flatMap(q =>
|
|
248
|
+
Effect.promise(() =>
|
|
249
|
+
container.items
|
|
250
|
+
.query<PM>(q)
|
|
251
|
+
.fetchAll()
|
|
252
|
+
.then(({ resources }) => resources.toChunk)
|
|
254
253
|
)
|
|
255
|
-
|
|
256
|
-
|
|
254
|
+
)
|
|
255
|
+
)
|
|
256
|
+
.map(_ => _.flatMap(_ => _))
|
|
257
257
|
: Effect(() => buildCosmosQuery(filter, name, importedMarkerId, skip, limit))
|
|
258
258
|
.tap(q => logQuery(q))
|
|
259
259
|
.flatMap(q =>
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import { expect, test } from "vitest"
|
|
2
1
|
import type { StoreWhereFilter, Where } from "@effect-app/infra/services/Store"
|
|
2
|
+
import { expect, test } from "vitest"
|
|
3
3
|
import { makeFilters } from "../../filter.js"
|
|
4
4
|
import { codeFilter } from "./utils.js"
|
|
5
5
|
|
|
6
|
-
|
|
7
6
|
const somethings = [
|
|
8
|
-
{a: 1, b: "b", c: ["c"], d: [{a: "a2", b: 1}, {a: "a", b: 1}], id: "1"},
|
|
9
|
-
{a: 2, b: "b2", c: ["c2"], d: [{a: "a4", b: 2}, {a: "a5", b: 2}], id: "2"}
|
|
7
|
+
{ a: 1, b: "b", c: ["c"], d: [{ a: "a2", b: 1 }, { a: "a", b: 1 }], id: "1" },
|
|
8
|
+
{ a: 2, b: "b2", c: ["c2"], d: [{ a: "a4", b: 2 }, { a: "a5", b: 2 }], id: "2" }
|
|
10
9
|
] satisfies readonly Something[]
|
|
11
10
|
|
|
12
11
|
const f_ = makeFilters<Something>()
|
|
@@ -31,44 +30,52 @@ export function somethingsWhere(
|
|
|
31
30
|
})
|
|
32
31
|
}
|
|
33
32
|
|
|
34
|
-
|
|
35
33
|
type SomethingElse = {
|
|
36
|
-
a: string
|
|
34
|
+
a: string
|
|
37
35
|
b: number
|
|
38
36
|
}
|
|
39
37
|
|
|
40
38
|
type Something = {
|
|
41
|
-
a: number
|
|
42
|
-
id: string
|
|
43
|
-
b: string
|
|
39
|
+
a: number
|
|
40
|
+
id: string
|
|
41
|
+
b: string
|
|
44
42
|
c: readonly string[]
|
|
45
43
|
d: readonly SomethingElse[]
|
|
46
44
|
}
|
|
47
45
|
|
|
48
46
|
test("works", () => {
|
|
49
|
-
expect(
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
somethingsWhere(_ => _("b", _ => "b"))
|
|
56
|
-
)).toArray)
|
|
57
|
-
.toEqual([somethings[0]])
|
|
47
|
+
expect(
|
|
48
|
+
somethings.filterMap(codeFilter(
|
|
49
|
+
somethingsWhere(_ => _("b", _ => "b2"))
|
|
50
|
+
)).toArray
|
|
51
|
+
)
|
|
52
|
+
.toEqual([somethings[1]])
|
|
58
53
|
|
|
54
|
+
expect(
|
|
55
|
+
somethings.filterMap(codeFilter(
|
|
56
|
+
somethingsWhere(_ => _("b", _ => "b"))
|
|
57
|
+
)).toArray
|
|
58
|
+
)
|
|
59
|
+
.toEqual([somethings[0]])
|
|
59
60
|
|
|
60
|
-
expect(
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
expect(
|
|
62
|
+
somethings.filterMap(codeFilter(
|
|
63
|
+
somethingsWhere(_ => _("d.-1.a", _ => "a5"))
|
|
64
|
+
)).toArray
|
|
65
|
+
)
|
|
66
|
+
.toEqual([somethings[1]])
|
|
64
67
|
|
|
65
|
-
expect(
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
68
|
+
expect(
|
|
69
|
+
somethings.filterMap(codeFilter(
|
|
70
|
+
somethingsWhere(_ => _("d.-1.a", _ => "a"))
|
|
71
|
+
)).toArray
|
|
72
|
+
)
|
|
73
|
+
.toEqual([somethings[0]])
|
|
69
74
|
|
|
70
|
-
expect(
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
75
|
+
expect(
|
|
76
|
+
somethings.filterMap(codeFilter(
|
|
77
|
+
somethingsWhere(_ => _("d.-1.a", _ => _.$isnt("a")))
|
|
78
|
+
)).toArray
|
|
79
|
+
)
|
|
80
|
+
.toEqual([somethings[1]])
|
|
74
81
|
})
|
|
@@ -13,8 +13,8 @@ export const makeETag = <E extends PersistenceModelType<Id>, Id extends string>(
|
|
|
13
13
|
...e,
|
|
14
14
|
_etag: objectHash(e)
|
|
15
15
|
}) as any
|
|
16
|
-
export const makeUpdateETag =
|
|
17
|
-
<E extends PersistenceModelType<Id>, Id extends string>(e: E, current: Opt<E>) =>
|
|
16
|
+
export const makeUpdateETag =
|
|
17
|
+
(name: string) => <E extends PersistenceModelType<Id>, Id extends string>(e: E, current: Opt<E>) =>
|
|
18
18
|
Effect.gen(function*($) {
|
|
19
19
|
if (current.isSome() && current.value._etag !== e._etag) {
|
|
20
20
|
return yield* $(
|
|
@@ -54,40 +54,40 @@ export function codeFilter<E extends { id: string }, NE extends E>(filter: Filte
|
|
|
54
54
|
})
|
|
55
55
|
? Opt(x as unknown as NE)
|
|
56
56
|
: Opt.none
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
? Opt(x as unknown as NE)
|
|
70
|
-
: Opt.none
|
|
71
|
-
: filter.where
|
|
72
|
-
.every(p =>
|
|
73
|
-
p.t === "in"
|
|
74
|
-
? p.value.includes(get(x, p.key))
|
|
75
|
-
: p.t === "not-in"
|
|
76
|
-
? !p.value.includes(get(x, p.key))
|
|
77
|
-
: p.t === "not-eq"
|
|
78
|
-
? p.key.includes(".-1.")
|
|
79
|
-
? (get(x, p.key.split(".-1.")[0]) as any[])
|
|
80
|
-
// TODO: or vs and
|
|
81
|
-
.every(_ => !compareCaseInsensitive(get(_, p.key.split(".-1.")[1]!), p.value))
|
|
82
|
-
: !compareCaseInsensitive(get(x, p.key), p.value)
|
|
83
|
-
: p.key.includes(".-1.")
|
|
84
|
-
? (get(x, p.key.split(".-1.")[0]) as any[])
|
|
85
|
-
// TODO: or vs and
|
|
86
|
-
.some(_ => compareCaseInsensitive(get(_, p.key.split(".-1.")[1]!), p.value))
|
|
87
|
-
: compareCaseInsensitive(get(x, p.key), p.value)
|
|
88
|
-
)
|
|
57
|
+
// TODO: support mixed or/and
|
|
58
|
+
: filter.mode === "or"
|
|
59
|
+
? filter.where
|
|
60
|
+
.some(p =>
|
|
61
|
+
p.t === "in"
|
|
62
|
+
? p.value.includes(get(x, p.key))
|
|
63
|
+
: p.t === "not-in"
|
|
64
|
+
? !p.value.includes(get(x, p.key))
|
|
65
|
+
: p.t === "not-eq"
|
|
66
|
+
? !compareCaseInsensitive(get(x, p.key), p.value)
|
|
67
|
+
: compareCaseInsensitive(get(x, p.key), p.value)
|
|
68
|
+
)
|
|
89
69
|
? Opt(x as unknown as NE)
|
|
90
70
|
: Opt.none
|
|
71
|
+
: filter.where
|
|
72
|
+
.every(p =>
|
|
73
|
+
p.t === "in"
|
|
74
|
+
? p.value.includes(get(x, p.key))
|
|
75
|
+
: p.t === "not-in"
|
|
76
|
+
? !p.value.includes(get(x, p.key))
|
|
77
|
+
: p.t === "not-eq"
|
|
78
|
+
? p.key.includes(".-1.")
|
|
79
|
+
? (get(x, p.key.split(".-1.")[0]) as any[])
|
|
80
|
+
// TODO: or vs and
|
|
81
|
+
.every(_ => !compareCaseInsensitive(get(_, p.key.split(".-1.")[1]!), p.value))
|
|
82
|
+
: !compareCaseInsensitive(get(x, p.key), p.value)
|
|
83
|
+
: p.key.includes(".-1.")
|
|
84
|
+
? (get(x, p.key.split(".-1.")[0]) as any[])
|
|
85
|
+
// TODO: or vs and
|
|
86
|
+
.some(_ => compareCaseInsensitive(get(_, p.key.split(".-1.")[1]!), p.value))
|
|
87
|
+
: compareCaseInsensitive(get(x, p.key), p.value)
|
|
88
|
+
)
|
|
89
|
+
? Opt(x as unknown as NE)
|
|
90
|
+
: Opt.none
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
export function codeFilterJoinSelect<E extends { id: string }, NE>(
|
|
@@ -30,12 +30,11 @@ export const RecordCache = Tag<RecordCache>()
|
|
|
30
30
|
|
|
31
31
|
export const LiveRecordCache = Effect(makeLiveRecordCache()).toLayer(RecordCache)
|
|
32
32
|
|
|
33
|
-
const getM = <T>(type: string) =>
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
})
|
|
33
|
+
const getM = <T>(type: string) => <R, E, A>(eff: (m: EffectMap<string, CachedRecord<T>>) => Effect<R, E, A>) =>
|
|
34
|
+
Effect.gen(function*($) {
|
|
35
|
+
const { get } = yield* $(RecordCache.access)
|
|
36
|
+
return yield* $(get<T>(type).flatMap(eff))
|
|
37
|
+
})
|
|
39
38
|
|
|
40
39
|
export function find<R, RDecode, EDecode, E, EA, A>(
|
|
41
40
|
tryRead: (id: string) => Effect<R, E, Opt<CachedRecord<EA>>>,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaultErrorHandler.d.ts","sourceRoot":"","sources":["../../_src/api/defaultErrorHandler.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAA;AAClC,OAAO,KAAK,EACV,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,8BAA8B,EAC9B,iBAAiB,EACjB,eAAe,EAChB,MAAM,cAAc,CAAA;AACrB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAG1D,wBAAgB,wBAAwB,CAAC,CAAC,EACxC,IAAI,EAAE,OAAO,CAAC,OAAO,EACrB,GAAG,EAAE,OAAO,CAAC,QAAQ,EACrB,eAAe,EAAE,cAAc,EAC/B,EAAE,EAAE,MAAM,CAAC,CAAC,EAAE,eAAe,EAAE,IAAI,CAAC,uEAgBrC;AAKD,wBAAgB,mBAAmB,CAAC,CAAC,EACnC,GAAG,EAAE,OAAO,CAAC,OAAO,EACpB,GAAG,EAAE,OAAO,CAAC,QAAQ,EACrB,CAAC,EAAE,cAAc,EACjB,EAAE,EAAE,MAAM,CAAC,CAAC,EAAE,eAAe,EAAE,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"defaultErrorHandler.d.ts","sourceRoot":"","sources":["../../_src/api/defaultErrorHandler.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAA;AAClC,OAAO,KAAK,EACV,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,8BAA8B,EAC9B,iBAAiB,EACjB,eAAe,EAChB,MAAM,cAAc,CAAA;AACrB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAG1D,wBAAgB,wBAAwB,CAAC,CAAC,EACxC,IAAI,EAAE,OAAO,CAAC,OAAO,EACrB,GAAG,EAAE,OAAO,CAAC,QAAQ,EACrB,eAAe,EAAE,cAAc,EAC/B,EAAE,EAAE,MAAM,CAAC,CAAC,EAAE,eAAe,EAAE,IAAI,CAAC,uEAgBrC;AAKD,wBAAgB,mBAAmB,CAAC,CAAC,EACnC,GAAG,EAAE,OAAO,CAAC,OAAO,EACpB,GAAG,EAAE,OAAO,CAAC,QAAQ,EACrB,CAAC,EAAE,cAAc,EACjB,EAAE,EAAE,MAAM,CAAC,CAAC,EAAE,eAAe,EAAE,IAAI,CAAC,uEAwCrC;AAED,MAAM,MAAM,eAAe,GACvB,eAAe,GACf,aAAa,GACb,gBAAgB,GAChB,iBAAiB,GACjB,iBAAiB,GACjB,8BAA8B,CAAA"}
|