@effect-app/infra 2.3.5 → 2.4.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 +6 -0
- package/_cjs/services/OperationsRepo.cjs +10 -1
- package/_cjs/services/OperationsRepo.cjs.map +1 -1
- package/_cjs/services/Repository/dsl.cjs.map +1 -1
- package/_cjs/services/Repository/ext.cjs +58 -104
- package/_cjs/services/Repository/ext.cjs.map +1 -1
- package/_cjs/services/Repository/legacy.cjs +108 -0
- package/_cjs/services/Repository/legacy.cjs.map +1 -0
- package/_cjs/services/Repository.cjs +11 -0
- package/_cjs/services/Repository.cjs.map +1 -1
- package/_cjs/services/RepositoryBase.cjs +4 -222
- package/_cjs/services/RepositoryBase.cjs.map +1 -1
- package/dist/services/Operations.d.ts +3 -3
- package/dist/services/OperationsRepo.d.ts +4 -1
- package/dist/services/OperationsRepo.d.ts.map +1 -1
- package/dist/services/OperationsRepo.js +12 -3
- package/dist/services/QueueMaker/errors.d.ts +1 -1
- package/dist/services/QueueMaker/errors.d.ts.map +1 -1
- package/dist/services/Repository/dsl.d.ts.map +1 -1
- package/dist/services/Repository/dsl.js +1 -1
- package/dist/services/Repository/ext.d.ts +43 -104
- package/dist/services/Repository/ext.d.ts.map +1 -1
- package/dist/services/Repository/ext.js +59 -93
- package/dist/services/Repository/legacy.d.ts +139 -0
- package/dist/services/Repository/legacy.d.ts.map +1 -0
- package/dist/services/Repository/legacy.js +99 -0
- package/dist/services/Repository/service.d.ts +21 -2
- package/dist/services/Repository/service.d.ts.map +1 -1
- package/dist/services/Repository.d.ts +1 -0
- package/dist/services/Repository.d.ts.map +1 -1
- package/dist/services/Repository.js +2 -1
- package/dist/services/RepositoryBase.d.ts +7 -237
- package/dist/services/RepositoryBase.d.ts.map +1 -1
- package/dist/services/RepositoryBase.js +5 -200
- package/dist/services/query/new-kid-interpreter.d.ts +1 -1
- package/examples/query.ts +3 -2
- package/package.json +11 -1
- package/src/services/OperationsRepo.ts +13 -4
- package/src/services/Repository/dsl.ts +1 -0
- package/src/services/Repository/ext.ts +269 -250
- package/src/services/Repository/legacy.ts +351 -0
- package/src/services/Repository/service.ts +44 -2
- package/src/services/Repository.ts +1 -0
- package/src/services/RepositoryBase.ts +12 -931
- package/test/query.test.ts +10 -8
|
@@ -1,272 +1,291 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import { Array, Effect } from "effect-app"
|
|
5
|
-
import type {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
3
|
+
import type { NonEmptyArray, NonEmptyReadonlyArray } from "effect-app"
|
|
4
|
+
import { Array, Effect, Exit, Option, Request, RequestResolver } from "effect-app"
|
|
5
|
+
import type { InvalidStateError, OptimisticConcurrencyException } from "effect-app/client"
|
|
6
|
+
import { NotFoundError } from "effect-app/client"
|
|
7
|
+
import type { FixEnv, PureEnv } from "effect-app/Pure"
|
|
8
|
+
import { runTerm } from "effect-app/Pure"
|
|
9
|
+
import type { Query, QueryEnd, QueryWhere } from "../query.js"
|
|
10
|
+
import * as Q from "../query.js"
|
|
9
11
|
import { AnyPureDSL } from "./dsl.js"
|
|
10
12
|
import type { Repository } from "./service.js"
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
14
|
+
export const extendRepo = <T, Encoded extends { id: string }, Evt, ItemType extends string, IdKey extends keyof T>(
|
|
15
|
+
repo: Repository<T, Encoded, Evt, ItemType, IdKey>
|
|
16
|
+
) => {
|
|
17
|
+
const get = (id: T[IdKey]) =>
|
|
18
|
+
Effect.flatMap(
|
|
19
|
+
repo.find(id),
|
|
20
|
+
(_) => Effect.mapError(_, () => new NotFoundError<ItemType>({ type: repo.itemType, id }))
|
|
21
|
+
)
|
|
22
|
+
function saveManyWithPure_<
|
|
23
|
+
R,
|
|
24
|
+
T,
|
|
25
|
+
Encoded extends { id: string },
|
|
26
|
+
A,
|
|
27
|
+
E,
|
|
28
|
+
Evt,
|
|
29
|
+
S1 extends T,
|
|
30
|
+
S2 extends T,
|
|
31
|
+
ItemType extends string,
|
|
32
|
+
IdKey extends keyof T
|
|
33
|
+
>(
|
|
34
|
+
self: Repository<T, Encoded, Evt, ItemType, IdKey>,
|
|
35
|
+
items: Iterable<S1>,
|
|
36
|
+
pure: Effect<A, E, FixEnv<R, Evt, readonly S1[], readonly S2[]>>
|
|
37
|
+
) {
|
|
38
|
+
return saveAllWithEffectInt(
|
|
39
|
+
self,
|
|
40
|
+
runTerm(pure, [...items])
|
|
41
|
+
)
|
|
42
|
+
}
|
|
29
43
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
44
|
+
function saveWithPure_<
|
|
45
|
+
R,
|
|
46
|
+
T,
|
|
47
|
+
Encoded extends { id: string },
|
|
48
|
+
A,
|
|
49
|
+
E,
|
|
50
|
+
Evt,
|
|
51
|
+
S1 extends T,
|
|
52
|
+
S2 extends T,
|
|
53
|
+
ItemType extends string,
|
|
54
|
+
IdKey extends keyof T
|
|
55
|
+
>(
|
|
56
|
+
self: Repository<T, Encoded, Evt, ItemType, IdKey>,
|
|
57
|
+
item: S1,
|
|
58
|
+
pure: Effect<A, E, FixEnv<R, Evt, S1, S2>>
|
|
59
|
+
) {
|
|
60
|
+
return saveAllWithEffectInt(
|
|
61
|
+
self,
|
|
62
|
+
runTerm(pure, item)
|
|
63
|
+
.pipe(Effect
|
|
64
|
+
.map(([item, events, a]) => [[item], events, a]))
|
|
65
|
+
)
|
|
66
|
+
}
|
|
42
67
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
68
|
+
function saveAllWithEffectInt<
|
|
69
|
+
T,
|
|
70
|
+
Encoded extends { id: string },
|
|
71
|
+
P extends T,
|
|
72
|
+
Evt,
|
|
73
|
+
ItemType extends string,
|
|
74
|
+
IdKey extends keyof T,
|
|
75
|
+
R,
|
|
76
|
+
E,
|
|
77
|
+
A
|
|
78
|
+
>(
|
|
79
|
+
self: Repository<T, Encoded, Evt, ItemType, IdKey>,
|
|
80
|
+
gen: Effect<readonly [Iterable<P>, Iterable<Evt>, A], E, R>
|
|
81
|
+
) {
|
|
82
|
+
return Effect.flatMap(gen, ([items, events, a]) => self.saveAndPublish(items, events).pipe(Effect.map(() => a)))
|
|
83
|
+
}
|
|
56
84
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
85
|
+
function saveManyWithPureBatched_<
|
|
86
|
+
R,
|
|
87
|
+
T,
|
|
88
|
+
Encoded extends { id: string },
|
|
89
|
+
A,
|
|
90
|
+
E,
|
|
91
|
+
Evt,
|
|
92
|
+
S1 extends T,
|
|
93
|
+
S2 extends T,
|
|
94
|
+
ItemType extends string,
|
|
95
|
+
IdKey extends keyof T
|
|
96
|
+
>(
|
|
97
|
+
self: Repository<T, Encoded, Evt, ItemType, IdKey>,
|
|
98
|
+
items: Iterable<S1>,
|
|
99
|
+
pure: Effect<A, E, FixEnv<R, Evt, readonly S1[], readonly S2[]>>,
|
|
100
|
+
batchSize = 100
|
|
101
|
+
) {
|
|
102
|
+
return Effect.forEach(
|
|
103
|
+
Array.chunk_(items, batchSize),
|
|
104
|
+
(batch) =>
|
|
105
|
+
saveAllWithEffectInt(
|
|
106
|
+
self,
|
|
107
|
+
runTerm(pure, batch)
|
|
108
|
+
)
|
|
109
|
+
)
|
|
110
|
+
}
|
|
73
111
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
112
|
+
const queryAndSavePure: {
|
|
113
|
+
<A, E2, R2, T2 extends T>(
|
|
114
|
+
q: (
|
|
115
|
+
q: Query<Encoded>
|
|
116
|
+
) => QueryEnd<Encoded, "one">,
|
|
117
|
+
pure: Effect<A, E2, FixEnv<R2, Evt, T, T2>>
|
|
118
|
+
): Effect.Effect<
|
|
119
|
+
A,
|
|
120
|
+
InvalidStateError | OptimisticConcurrencyException | NotFoundError<ItemType> | E2,
|
|
121
|
+
Exclude<R2, {
|
|
122
|
+
env: PureEnv<Evt, T, T2>
|
|
123
|
+
}>
|
|
124
|
+
>
|
|
125
|
+
<A, E2, R2, T2 extends T>(
|
|
126
|
+
q: (
|
|
127
|
+
q: Query<Encoded>
|
|
128
|
+
) =>
|
|
129
|
+
| Query<Encoded>
|
|
130
|
+
| QueryWhere<Encoded>
|
|
131
|
+
| QueryEnd<Encoded, "many">,
|
|
132
|
+
pure: Effect<A, E2, FixEnv<R2, Evt, readonly T[], readonly T2[]>>
|
|
133
|
+
): Effect.Effect<
|
|
134
|
+
A,
|
|
135
|
+
InvalidStateError | OptimisticConcurrencyException | E2,
|
|
136
|
+
Exclude<R2, {
|
|
137
|
+
env: PureEnv<Evt, readonly T[], readonly T2[]>
|
|
138
|
+
}>
|
|
139
|
+
>
|
|
140
|
+
<A, E2, R2, T2 extends T>(
|
|
141
|
+
q: (
|
|
142
|
+
q: Query<Encoded>
|
|
143
|
+
) =>
|
|
144
|
+
| Query<Encoded>
|
|
145
|
+
| QueryWhere<Encoded>
|
|
146
|
+
| QueryEnd<Encoded, "many">,
|
|
147
|
+
pure: Effect<A, E2, FixEnv<R2, Evt, readonly T[], readonly T2[]>>,
|
|
148
|
+
batch: "batched" | number
|
|
149
|
+
): Effect.Effect<
|
|
150
|
+
A[],
|
|
151
|
+
InvalidStateError | OptimisticConcurrencyException | E2,
|
|
152
|
+
Exclude<R2, {
|
|
153
|
+
env: PureEnv<Evt, readonly T[], readonly T2[]>
|
|
154
|
+
}>
|
|
155
|
+
>
|
|
156
|
+
} = (q, pure, batch?: "batched" | number) =>
|
|
157
|
+
repo.query(q).pipe(
|
|
158
|
+
Effect.andThen((_) =>
|
|
159
|
+
Array.isArray(_)
|
|
160
|
+
? batch === undefined
|
|
161
|
+
? saveManyWithPure_(repo, _ as any, pure as any)
|
|
162
|
+
: saveManyWithPureBatched_(repo, _ as any, pure as any, batch === "batched" ? 100 : batch)
|
|
163
|
+
: saveWithPure_(repo, _ as any, pure as any)
|
|
164
|
+
)
|
|
165
|
+
) as any
|
|
98
166
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
167
|
+
const saveManyWithPure: {
|
|
168
|
+
<R, A, E, S1 extends T, S2 extends T>(
|
|
169
|
+
items: Iterable<S1>,
|
|
170
|
+
pure: Effect<A, E, FixEnv<R, Evt, readonly S1[], readonly S2[]>>
|
|
171
|
+
): Effect.Effect<
|
|
172
|
+
A,
|
|
173
|
+
InvalidStateError | OptimisticConcurrencyException | E,
|
|
174
|
+
Exclude<R, {
|
|
175
|
+
env: PureEnv<Evt, readonly S1[], readonly S2[]>
|
|
176
|
+
}>
|
|
177
|
+
>
|
|
178
|
+
<R, A, E, S1 extends T, S2 extends T>(
|
|
179
|
+
items: Iterable<S1>,
|
|
180
|
+
pure: Effect<A, E, FixEnv<R, Evt, readonly S1[], readonly S2[]>>,
|
|
181
|
+
batch: "batched" | number
|
|
182
|
+
): Effect.Effect<
|
|
183
|
+
A[],
|
|
184
|
+
InvalidStateError | OptimisticConcurrencyException | E,
|
|
185
|
+
Exclude<R, {
|
|
186
|
+
env: PureEnv<Evt, readonly S1[], readonly S2[]>
|
|
187
|
+
}>
|
|
188
|
+
>
|
|
189
|
+
} = (items, pure, batch?: "batched" | number) =>
|
|
190
|
+
batch
|
|
191
|
+
? Effect.forEach(
|
|
192
|
+
Array.chunk_(items, batch === "batched" ? 100 : batch),
|
|
193
|
+
(batch) =>
|
|
194
|
+
saveAllWithEffectInt(
|
|
195
|
+
repo,
|
|
196
|
+
runTerm(pure, batch)
|
|
197
|
+
)
|
|
198
|
+
)
|
|
199
|
+
: saveAllWithEffectInt(
|
|
200
|
+
repo,
|
|
201
|
+
runTerm(pure, [...items])
|
|
202
|
+
)
|
|
125
203
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
>
|
|
137
|
-
|
|
138
|
-
gen: Effect<readonly [Iterable<P>, Iterable<Evt>, A], E, R>
|
|
139
|
-
) {
|
|
140
|
-
return Effect.flatMap(gen, ([items, events, a]) => self.saveAndPublish(items, events).pipe(Effect.map(() => a)))
|
|
141
|
-
}
|
|
204
|
+
const byIdAndSaveWithPure: {
|
|
205
|
+
<R, A, E, S2 extends T>(
|
|
206
|
+
id: T[IdKey],
|
|
207
|
+
pure: Effect<A, E, FixEnv<R, Evt, T, S2>>
|
|
208
|
+
): Effect<
|
|
209
|
+
A,
|
|
210
|
+
InvalidStateError | OptimisticConcurrencyException | NotFoundError<ItemType> | E,
|
|
211
|
+
Exclude<R, {
|
|
212
|
+
env: PureEnv<Evt, T, S2>
|
|
213
|
+
}>
|
|
214
|
+
>
|
|
215
|
+
} = (id, pure): any => get(id).pipe(Effect.flatMap((item) => saveWithPure_(repo, item, pure)))
|
|
142
216
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
T,
|
|
148
|
-
Encoded extends { id: string },
|
|
149
|
-
Evt,
|
|
150
|
-
ItemType extends string,
|
|
151
|
-
IdKey extends keyof T
|
|
152
|
-
>(self: RepositoryBaseC<T, Encoded, Evt, ItemType, IdKey>, batchSize = 100) {
|
|
153
|
-
return <R, A, E, S1 extends T, S2 extends T>(pure: Effect<A, E, FixEnv<R, Evt, readonly S1[], readonly S2[]>>) =>
|
|
154
|
-
(items: Iterable<S1>) => saveManyWithPureBatched_(self, items, pure, batchSize)
|
|
155
|
-
}
|
|
217
|
+
type Req =
|
|
218
|
+
& Request.Request<T, NotFoundError<ItemType>>
|
|
219
|
+
& { _tag: `Get${ItemType}`; id: T[IdKey] }
|
|
220
|
+
const _request = Request.tagged<Req>(`Get${repo.itemType}`)
|
|
156
221
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
222
|
+
const requestResolver = RequestResolver
|
|
223
|
+
.makeBatched((
|
|
224
|
+
requests: NonEmptyReadonlyArray<Req>
|
|
225
|
+
) =>
|
|
226
|
+
(repo.query(Q.where("id", "in", requests.map((_) => _.id)) as any) as Effect<readonly T[], never>)
|
|
227
|
+
// TODO
|
|
228
|
+
.pipe(
|
|
229
|
+
Effect.andThen((items) =>
|
|
230
|
+
Effect.forEach(requests, (r) =>
|
|
231
|
+
Request.complete(
|
|
232
|
+
r,
|
|
233
|
+
Array
|
|
234
|
+
.findFirst(items, (_) => _[repo.idKey] === r.id)
|
|
235
|
+
.pipe(Option.match({
|
|
236
|
+
onNone: () => Exit.fail(new NotFoundError({ type: repo.itemType, id: r.id })),
|
|
237
|
+
onSome: Exit.succeed
|
|
238
|
+
}))
|
|
239
|
+
), { discard: true })
|
|
240
|
+
),
|
|
241
|
+
Effect
|
|
242
|
+
.catchAllCause((cause) =>
|
|
243
|
+
Effect.forEach(requests, Request.complete(Exit.failCause(cause)), { discard: true })
|
|
244
|
+
)
|
|
245
|
+
)
|
|
246
|
+
)
|
|
247
|
+
.pipe(
|
|
248
|
+
RequestResolver.batchN(20)
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
const exts = {
|
|
252
|
+
request: (id: T[IdKey]) => Effect.request(_request({ id }), requestResolver),
|
|
253
|
+
get,
|
|
254
|
+
log: (evt: Evt) => AnyPureDSL.log(evt),
|
|
255
|
+
removeById: (id: T[IdKey]) => Effect.andThen(get(id), (_) => repo.removeAndPublish([_])),
|
|
256
|
+
save: (...items: NonEmptyArray<T>) => repo.saveAndPublish(items),
|
|
257
|
+
saveWithEvents: (events: Iterable<Evt>) => (...items: NonEmptyArray<T>) => repo.saveAndPublish(items, events),
|
|
258
|
+
queryAndSavePure,
|
|
259
|
+
saveManyWithPure,
|
|
260
|
+
byIdAndSaveWithPure,
|
|
261
|
+
saveWithPure: <
|
|
262
|
+
R,
|
|
263
|
+
A,
|
|
264
|
+
E,
|
|
265
|
+
S1 extends T,
|
|
266
|
+
S2 extends T
|
|
267
|
+
>(
|
|
268
|
+
item: S1,
|
|
269
|
+
pure: Effect<A, E, FixEnv<R, Evt, S1, S2>>
|
|
270
|
+
) =>
|
|
180
271
|
saveAllWithEffectInt(
|
|
181
|
-
|
|
182
|
-
runTerm(pure,
|
|
272
|
+
repo,
|
|
273
|
+
runTerm(pure, item)
|
|
274
|
+
.pipe(Effect.map(([item, events, a]) => [[item], events, a]))
|
|
183
275
|
)
|
|
184
|
-
|
|
185
|
-
}
|
|
276
|
+
}
|
|
186
277
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
T,
|
|
192
|
-
Encoded extends { id: string },
|
|
193
|
-
Evt,
|
|
194
|
-
ItemType extends string,
|
|
195
|
-
IdKey extends keyof T
|
|
196
|
-
>(
|
|
197
|
-
self: RepositoryBaseC<T, Encoded, Evt, ItemType, IdKey>
|
|
198
|
-
) {
|
|
199
|
-
return (...items: NonEmptyArray<T>) => self.saveAndPublish(items)
|
|
278
|
+
return {
|
|
279
|
+
...repo,
|
|
280
|
+
...exts
|
|
281
|
+
} as Repository<T, Encoded, Evt, ItemType, IdKey> & typeof exts
|
|
200
282
|
}
|
|
201
283
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
*/
|
|
205
|
-
export function saveWithEvents<
|
|
284
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
285
|
+
export interface ExtendedRepository<
|
|
206
286
|
T,
|
|
207
287
|
Encoded extends { id: string },
|
|
208
288
|
Evt,
|
|
209
289
|
ItemType extends string,
|
|
210
290
|
IdKey extends keyof T
|
|
211
|
-
>
|
|
212
|
-
self: RepositoryBaseC<T, Encoded, Evt, ItemType, IdKey>
|
|
213
|
-
) {
|
|
214
|
-
return (events: Iterable<Evt>) => (...items: NonEmptyArray<T>) => self.saveAndPublish(items, events)
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* @tsplus fluent Repository updateWithEffect
|
|
219
|
-
*/
|
|
220
|
-
export function itemUpdateWithEffect<
|
|
221
|
-
R,
|
|
222
|
-
E,
|
|
223
|
-
T extends { id: string },
|
|
224
|
-
Encoded extends { id: string },
|
|
225
|
-
Evt,
|
|
226
|
-
ItemType extends string,
|
|
227
|
-
IdKey extends keyof T
|
|
228
|
-
>(
|
|
229
|
-
repo: RepositoryBaseC<T, Encoded, Evt, ItemType, IdKey>,
|
|
230
|
-
id: T[IdKey],
|
|
231
|
-
mod: (item: T) => Effect<T, E, R>
|
|
232
|
-
) {
|
|
233
|
-
return get(repo, id).pipe(Effect.andThen(mod), Effect.andThen(save(repo)))
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* @tsplus fluent Repository update
|
|
238
|
-
*/
|
|
239
|
-
export function itemUpdate<
|
|
240
|
-
T extends { id: string },
|
|
241
|
-
Encoded extends { id: string },
|
|
242
|
-
Evt,
|
|
243
|
-
ItemType extends string,
|
|
244
|
-
IdKey extends keyof T
|
|
245
|
-
>(
|
|
246
|
-
repo: RepositoryBaseC<T, Encoded, Evt, ItemType, IdKey>,
|
|
247
|
-
id: T[IdKey],
|
|
248
|
-
mod: (item: T) => T
|
|
249
|
-
) {
|
|
250
|
-
return itemUpdateWithEffect(
|
|
251
|
-
repo,
|
|
252
|
-
id,
|
|
253
|
-
(item) => Effect.sync(() => mod(item))
|
|
254
|
-
)
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* only use this as a shortcut if you don't have the item already
|
|
259
|
-
* @tsplus fluent Repository removeById
|
|
260
|
-
*/
|
|
261
|
-
export function removeById<
|
|
262
|
-
T,
|
|
263
|
-
Encoded extends { id: string },
|
|
264
|
-
Evt,
|
|
265
|
-
ItemType extends string,
|
|
266
|
-
IdKey extends keyof T
|
|
267
|
-
>(
|
|
268
|
-
self: Repository<T, Encoded, Evt, ItemType, IdKey>,
|
|
269
|
-
id: T[IdKey]
|
|
270
|
-
) {
|
|
271
|
-
return get(self, id).pipe(Effect.flatMap((_) => self.removeAndPublish([_])))
|
|
272
|
-
}
|
|
291
|
+
> extends ReturnType<typeof extendRepo<T, Encoded, Evt, ItemType, IdKey>> {}
|