@effect-app/infra 0.221.0 → 0.223.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 +21 -0
- package/_cjs/services/Operations.cjs +3 -2
- package/_cjs/services/Operations.cjs.map +1 -1
- package/_cjs/services/Repository/ext.cjs.map +1 -1
- package/_cjs/services/RepositoryBase.cjs +6 -4
- package/_cjs/services/RepositoryBase.cjs.map +1 -1
- package/_cjs/services/Store/Cosmos.cjs.map +1 -1
- package/_cjs/services/Store/Disk.cjs.map +1 -1
- package/_cjs/services/Store/Memory.cjs +1 -0
- package/_cjs/services/Store/Memory.cjs.map +1 -1
- package/_cjs/services/Store/service.cjs.map +1 -1
- package/_cjs/services/Store/utils.cjs.map +1 -1
- package/dist/services/Operations.d.ts +1 -0
- package/dist/services/Operations.d.ts.map +1 -1
- package/dist/services/Operations.js +4 -3
- package/dist/services/Repository/ext.d.ts +42 -15
- package/dist/services/Repository/ext.d.ts.map +1 -1
- package/dist/services/Repository/ext.js +1 -1
- package/dist/services/Repository/service.d.ts +3 -2
- package/dist/services/Repository/service.d.ts.map +1 -1
- package/dist/services/RepositoryBase.d.ts +81 -86
- package/dist/services/RepositoryBase.d.ts.map +1 -1
- package/dist/services/RepositoryBase.js +11 -7
- package/dist/services/Store/Cosmos.d.ts.map +1 -1
- package/dist/services/Store/Cosmos.js +1 -1
- package/dist/services/Store/Disk.d.ts +3 -1
- package/dist/services/Store/Disk.d.ts.map +1 -1
- package/dist/services/Store/Disk.js +1 -1
- package/dist/services/Store/Memory.d.ts +9 -3
- package/dist/services/Store/Memory.d.ts.map +1 -1
- package/dist/services/Store/Memory.js +2 -2
- package/dist/services/Store/service.d.ts +37 -18
- package/dist/services/Store/service.d.ts.map +1 -1
- package/dist/services/Store/service.js +1 -1
- package/dist/services/Store/utils.d.ts +6 -2
- package/dist/services/Store/utils.d.ts.map +1 -1
- package/dist/services/Store/utils.js +1 -1
- package/dist/services/query/new-kid-interpreter.d.ts +1 -1
- package/package.json +10 -10
- package/src/services/Operations.ts +4 -2
- package/src/services/Repository/ext.ts +28 -29
- package/src/services/Repository/service.ts +2 -3
- package/src/services/RepositoryBase.ts +177 -169
- package/src/services/Store/Cosmos.ts +13 -12
- package/src/services/Store/Disk.ts +12 -11
- package/src/services/Store/Memory.ts +13 -12
- package/src/services/Store/index.test.ts.bak +3 -3
- package/src/services/Store/service.ts +22 -19
- package/src/services/Store/utils.ts +2 -2
- package/test/query.test.ts +1 -1
|
@@ -18,12 +18,13 @@ function makeCosmosStore({ prefix }: StorageConfig) {
|
|
|
18
18
|
return Effect.gen(function*($) {
|
|
19
19
|
const { db } = yield* $(CosmosClient)
|
|
20
20
|
return {
|
|
21
|
-
make: <Id extends string,
|
|
21
|
+
make: <Id extends string, Encoded extends { id: Id }, R = never, E = never>(
|
|
22
22
|
name: string,
|
|
23
|
-
seed?: Effect<Iterable<
|
|
24
|
-
config?: StoreConfig<
|
|
23
|
+
seed?: Effect<Iterable<Encoded>, E, R>,
|
|
24
|
+
config?: StoreConfig<Encoded>
|
|
25
25
|
) =>
|
|
26
26
|
Effect.gen(function*($) {
|
|
27
|
+
type PM = PersistenceModelType<Encoded>
|
|
27
28
|
const containerId = `${prefix}${name}`
|
|
28
29
|
yield* $(
|
|
29
30
|
Effect.promise(() =>
|
|
@@ -121,7 +122,7 @@ function makeCosmosStore({ prefix }: StorageConfig) {
|
|
|
121
122
|
)
|
|
122
123
|
)
|
|
123
124
|
)
|
|
124
|
-
return batchResult.flat() as unknown as NonEmptyReadonlyArray<
|
|
125
|
+
return batchResult.flat() as unknown as NonEmptyReadonlyArray<Encoded>
|
|
125
126
|
})
|
|
126
127
|
.pipe(Effect.withSpan("Cosmos.bulkSet [effect-app/infra/Store]", {
|
|
127
128
|
attributes: { "repository.container_id": containerId, "repository.model_name": name }
|
|
@@ -183,7 +184,7 @@ function makeCosmosStore({ prefix }: StorageConfig) {
|
|
|
183
184
|
return batch.map(([e], i) => ({
|
|
184
185
|
...e,
|
|
185
186
|
_etag: result[i]?.eTag
|
|
186
|
-
})) as unknown as NonEmptyReadonlyArray<
|
|
187
|
+
})) as unknown as NonEmptyReadonlyArray<Encoded>
|
|
187
188
|
})
|
|
188
189
|
))
|
|
189
190
|
})
|
|
@@ -193,7 +194,7 @@ function makeCosmosStore({ prefix }: StorageConfig) {
|
|
|
193
194
|
}))
|
|
194
195
|
}
|
|
195
196
|
|
|
196
|
-
const s: Store<
|
|
197
|
+
const s: Store<Encoded, Id> = {
|
|
197
198
|
all: Effect
|
|
198
199
|
.sync(() => ({
|
|
199
200
|
query: `SELECT * FROM ${name} f WHERE f.id != @id`,
|
|
@@ -218,13 +219,13 @@ function makeCosmosStore({ prefix }: StorageConfig) {
|
|
|
218
219
|
/**
|
|
219
220
|
* May return duplicate results for "join_find", when matching more than once.
|
|
220
221
|
*/
|
|
221
|
-
filter: <U extends keyof
|
|
222
|
-
f: FilterArgs<
|
|
222
|
+
filter: <U extends keyof Encoded = never>(
|
|
223
|
+
f: FilterArgs<Encoded, U>
|
|
223
224
|
) => {
|
|
224
225
|
const skip = f?.skip
|
|
225
226
|
const limit = f?.limit
|
|
226
227
|
const filter = f.filter ?? { type: "new-kid", build: () => [] }
|
|
227
|
-
type M = U extends undefined ?
|
|
228
|
+
type M = U extends undefined ? Encoded : Pick<Encoded, U>
|
|
228
229
|
return Effect
|
|
229
230
|
.sync(() =>
|
|
230
231
|
buildWhereCosmosQuery3(
|
|
@@ -267,8 +268,8 @@ function makeCosmosStore({ prefix }: StorageConfig) {
|
|
|
267
268
|
Effect
|
|
268
269
|
.promise(() =>
|
|
269
270
|
container
|
|
270
|
-
.item(id, config?.partitionValue({ id } as
|
|
271
|
-
.read<
|
|
271
|
+
.item(id, config?.partitionValue({ id } as Encoded))
|
|
272
|
+
.read<Encoded>()
|
|
272
273
|
.then(({ resource }) =>
|
|
273
274
|
Option.fromNullable(resource).pipe(Option.map((_) => ({ ...defaultValues, ..._ })))
|
|
274
275
|
)
|
|
@@ -329,7 +330,7 @@ function makeCosmosStore({ prefix }: StorageConfig) {
|
|
|
329
330
|
),
|
|
330
331
|
batchSet,
|
|
331
332
|
bulkSet,
|
|
332
|
-
remove: (e:
|
|
333
|
+
remove: (e: Encoded) =>
|
|
333
334
|
Effect
|
|
334
335
|
.promise(() => container.item(e.id, config?.partitionValue(e)).delete())
|
|
335
336
|
.pipe(Effect
|
|
@@ -8,14 +8,15 @@ import { makeMemoryStoreInt, storeId } from "./Memory.js"
|
|
|
8
8
|
import type { PersistenceModelType, StorageConfig, Store, StoreConfig } from "./service.js"
|
|
9
9
|
import { StoreMaker } from "./service.js"
|
|
10
10
|
|
|
11
|
-
function makeDiskStoreInt<Id extends string,
|
|
11
|
+
function makeDiskStoreInt<Id extends string, Encoded extends { id: Id }, R, E>(
|
|
12
12
|
prefix: string,
|
|
13
13
|
namespace: string,
|
|
14
14
|
dir: string,
|
|
15
15
|
name: string,
|
|
16
|
-
seed?: Effect<Iterable<
|
|
17
|
-
defaultValues?: Partial<
|
|
16
|
+
seed?: Effect<Iterable<Encoded>, E, R>,
|
|
17
|
+
defaultValues?: Partial<Encoded>
|
|
18
18
|
) {
|
|
19
|
+
type PM = PersistenceModelType<Encoded>
|
|
19
20
|
return Effect.gen(function*($) {
|
|
20
21
|
if (namespace !== "primary") {
|
|
21
22
|
dir = dir + "/" + namespace
|
|
@@ -58,7 +59,7 @@ function makeDiskStoreInt<Id extends string, PM extends PersistenceModelType<Id>
|
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
const store = yield* $(
|
|
61
|
-
makeMemoryStoreInt<Id,
|
|
62
|
+
makeMemoryStoreInt<Id, Encoded, R, E>(
|
|
62
63
|
name,
|
|
63
64
|
namespace,
|
|
64
65
|
!fs.existsSync(file)
|
|
@@ -98,7 +99,7 @@ function makeDiskStoreInt<Id extends string, PM extends PersistenceModelType<Id>
|
|
|
98
99
|
store.remove,
|
|
99
100
|
Effect.tap(flushToDiskInBackground)
|
|
100
101
|
)
|
|
101
|
-
} satisfies Store<
|
|
102
|
+
} satisfies Store<Encoded, Id>
|
|
102
103
|
})
|
|
103
104
|
}
|
|
104
105
|
|
|
@@ -112,15 +113,15 @@ export function makeDiskStore({ prefix }: StorageConfig, dir: string) {
|
|
|
112
113
|
fs.mkdirSync(dir)
|
|
113
114
|
}
|
|
114
115
|
return {
|
|
115
|
-
make: <Id extends string,
|
|
116
|
+
make: <Id extends string, Encoded extends { id: Id }, R, E>(
|
|
116
117
|
name: string,
|
|
117
|
-
seed?: Effect<Iterable<
|
|
118
|
-
config?: StoreConfig<
|
|
118
|
+
seed?: Effect<Iterable<Encoded>, E, R>,
|
|
119
|
+
config?: StoreConfig<Encoded>
|
|
119
120
|
) =>
|
|
120
121
|
Effect.gen(function*($) {
|
|
121
122
|
const storesSem = Effect.unsafeMakeSemaphore(1)
|
|
122
123
|
const primary = yield* $(makeDiskStoreInt(prefix, "primary", dir, name, seed, config?.defaultValues))
|
|
123
|
-
const stores = new Map<string, Store<
|
|
124
|
+
const stores = new Map<string, Store<Encoded, Id>>([["primary", primary]])
|
|
124
125
|
const ctx = yield* $(Effect.context<R>())
|
|
125
126
|
const getStore = !config?.allowNamespace
|
|
126
127
|
? Effect.succeed(primary)
|
|
@@ -136,7 +137,7 @@ export function makeDiskStore({ prefix }: StorageConfig, dir: string) {
|
|
|
136
137
|
Effect.suspend(() => {
|
|
137
138
|
const existing = stores.get(namespace)
|
|
138
139
|
if (existing) return Effect.sync(() => existing)
|
|
139
|
-
return makeDiskStoreInt<Id,
|
|
140
|
+
return makeDiskStoreInt<Id, Encoded, R, E>(prefix, namespace, dir, name, seed, config?.defaultValues)
|
|
140
141
|
.pipe(
|
|
141
142
|
Effect.orDie,
|
|
142
143
|
Effect.provide(ctx),
|
|
@@ -146,7 +147,7 @@ export function makeDiskStore({ prefix }: StorageConfig, dir: string) {
|
|
|
146
147
|
)
|
|
147
148
|
}))
|
|
148
149
|
|
|
149
|
-
const s: Store<
|
|
150
|
+
const s: Store<Encoded, Id> = {
|
|
150
151
|
all: Effect.flatMap(getStore, (_) => _.all),
|
|
151
152
|
find: (...args) => Effect.flatMap(getStore, (_) => _.find(...args)),
|
|
152
153
|
filter: (...args) => Effect.flatMap(getStore, (_) => _.filter(...args)),
|
|
@@ -8,7 +8,7 @@ import type { FilterArgs, PersistenceModelType, Store, StoreConfig } from "./ser
|
|
|
8
8
|
import { StoreMaker } from "./service.js"
|
|
9
9
|
import { codeFilter, makeUpdateETag } from "./utils.js"
|
|
10
10
|
|
|
11
|
-
export function memFilter<T extends
|
|
11
|
+
export function memFilter<T extends { id: string }, U extends keyof T = never>(f: FilterArgs<T, U>) {
|
|
12
12
|
type M = U extends undefined ? T : Pick<T, U>
|
|
13
13
|
return ((c: T[]): M[] => {
|
|
14
14
|
const select = (r: T[]): M[] => (f.select ? r.map((_) => pick(_, f.select!)) : r) as any
|
|
@@ -78,18 +78,19 @@ function logQuery(f: FilterArgs<any, any>, defaultValues?: any) {
|
|
|
78
78
|
}))
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
export function makeMemoryStoreInt<Id extends string,
|
|
81
|
+
export function makeMemoryStoreInt<Id extends string, Encoded extends { id: Id }, R = never, E = never>(
|
|
82
82
|
modelName: string,
|
|
83
83
|
namespace: string,
|
|
84
|
-
seed?: Effect<Iterable<
|
|
85
|
-
_defaultValues?: Partial<
|
|
84
|
+
seed?: Effect<Iterable<Encoded>, E, R>,
|
|
85
|
+
_defaultValues?: Partial<Encoded>
|
|
86
86
|
) {
|
|
87
|
+
type PM = PersistenceModelType<Encoded>
|
|
87
88
|
return Effect.gen(function*($) {
|
|
88
89
|
const updateETag = makeUpdateETag(modelName)
|
|
89
90
|
const items_ = yield* $(seed ?? Effect.sync(() => []))
|
|
90
91
|
const defaultValues = _defaultValues ?? {}
|
|
91
92
|
|
|
92
|
-
const items = new Map([...items_].map((_) => [_.id, { ...defaultValues, ..._ }] as const))
|
|
93
|
+
const items = new Map([...items_].map((_) => [_.id, { _etag: undefined, ...defaultValues, ..._ }] as const))
|
|
93
94
|
const store = Ref.unsafeMake<ReadonlyMap<Id, PM>>(items)
|
|
94
95
|
const sem = Effect.unsafeMakeSemaphore(1)
|
|
95
96
|
const withPermit = sem.withPermits(1)
|
|
@@ -120,7 +121,7 @@ export function makeMemoryStoreInt<Id extends string, PM extends PersistenceMode
|
|
|
120
121
|
.map((_) => _ as NonEmptyArray<PM>),
|
|
121
122
|
withPermit
|
|
122
123
|
)
|
|
123
|
-
const s: Store<
|
|
124
|
+
const s: Store<Encoded, Id> = {
|
|
124
125
|
all: all.pipe(Effect.withSpan("Memory.all [effect-app/infra/Store]", {
|
|
125
126
|
attributes: {
|
|
126
127
|
modelName,
|
|
@@ -189,7 +190,7 @@ export function makeMemoryStoreInt<Id extends string, PM extends PersistenceMode
|
|
|
189
190
|
attributes: { "repository.model_name": modelName, "repository.namespace": namespace }
|
|
190
191
|
}))
|
|
191
192
|
),
|
|
192
|
-
remove: (e:
|
|
193
|
+
remove: (e: Encoded) =>
|
|
193
194
|
Ref
|
|
194
195
|
.get(store)
|
|
195
196
|
.pipe(
|
|
@@ -206,14 +207,14 @@ export function makeMemoryStoreInt<Id extends string, PM extends PersistenceMode
|
|
|
206
207
|
}
|
|
207
208
|
|
|
208
209
|
export const makeMemoryStore = () => ({
|
|
209
|
-
make: <Id extends string,
|
|
210
|
+
make: <Id extends string, Encoded extends { id: Id }, R = never, E = never>(
|
|
210
211
|
modelName: string,
|
|
211
|
-
seed?: Effect<Iterable<
|
|
212
|
-
config?: StoreConfig<
|
|
212
|
+
seed?: Effect<Iterable<Encoded>, E, R>,
|
|
213
|
+
config?: StoreConfig<Encoded>
|
|
213
214
|
) =>
|
|
214
215
|
Effect.gen(function*($) {
|
|
215
216
|
const storesSem = Effect.unsafeMakeSemaphore(1)
|
|
216
|
-
const primary = yield* $(makeMemoryStoreInt<Id,
|
|
217
|
+
const primary = yield* $(makeMemoryStoreInt<Id, Encoded, R, E>(modelName, "primary", seed, config?.defaultValues))
|
|
217
218
|
const ctx = yield* $(Effect.context<R>())
|
|
218
219
|
const stores = new Map([["primary", primary]])
|
|
219
220
|
const getStore = !config?.allowNamespace
|
|
@@ -239,7 +240,7 @@ export const makeMemoryStore = () => ({
|
|
|
239
240
|
)
|
|
240
241
|
}))
|
|
241
242
|
}))
|
|
242
|
-
const s: Store<
|
|
243
|
+
const s: Store<Encoded, Id> = {
|
|
243
244
|
all: Effect.flatMap(getStore, (_) => _.all),
|
|
244
245
|
find: (...args) => Effect.flatMap(getStore, (_) => _.find(...args)),
|
|
245
246
|
filter: (...args) => Effect.flatMap(getStore, (_) => _.filter(...args)),
|
|
@@ -14,7 +14,7 @@ describe("Optimistic Concurrency", () => {
|
|
|
14
14
|
Effect.gen(function*($) {
|
|
15
15
|
const existing = new Map<
|
|
16
16
|
string,
|
|
17
|
-
{ _etag
|
|
17
|
+
{ _etag?: string | undefined; id: string; a: string }
|
|
18
18
|
>()
|
|
19
19
|
const { make } = makeMemoryStore()
|
|
20
20
|
const store = yield* $(make("test", Effect.sync(() => existing)))
|
|
@@ -48,7 +48,7 @@ describe("Optimistic Concurrency", () => {
|
|
|
48
48
|
Effect.gen(function*($) {
|
|
49
49
|
const existing = new Map<
|
|
50
50
|
string,
|
|
51
|
-
{ _etag
|
|
51
|
+
{ _etag?: string | undefined; id: string; a: string }
|
|
52
52
|
>()
|
|
53
53
|
const { make } = makeMemoryStore()
|
|
54
54
|
const store = yield* $(make("test", Effect.sync(() => existing)))
|
|
@@ -86,7 +86,7 @@ describe("Optimistic Concurrency", () => {
|
|
|
86
86
|
Effect.gen(function*($) {
|
|
87
87
|
const existing = new Map<
|
|
88
88
|
string,
|
|
89
|
-
{ _etag
|
|
89
|
+
{ _etag?: string | undefined; id: string; a: string }
|
|
90
90
|
>()
|
|
91
91
|
const { make } = makeMemoryStore()
|
|
92
92
|
const store = yield* $(make("test", Effect.sync(() => existing)))
|
|
@@ -36,26 +36,30 @@ export type Where =
|
|
|
36
36
|
|
|
37
37
|
export type Filter<E extends FieldValues> = QueryBuilder<E>
|
|
38
38
|
|
|
39
|
-
export interface O<
|
|
40
|
-
key: keyof
|
|
39
|
+
export interface O<Encoded extends { id: string }> {
|
|
40
|
+
key: keyof Encoded
|
|
41
41
|
direction: "ASC" | "DESC"
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
export interface FilterArgs<
|
|
45
|
-
filter?: Filter<
|
|
44
|
+
export interface FilterArgs<Encoded extends { id: string }, U extends keyof Encoded = never> {
|
|
45
|
+
filter?: Filter<Encoded> | undefined
|
|
46
46
|
select?: NonEmptyReadonlyArray<U> | undefined
|
|
47
|
-
order?: NonEmptyReadonlyArray<O<
|
|
47
|
+
order?: NonEmptyReadonlyArray<O<Encoded>>
|
|
48
48
|
limit?: number | undefined
|
|
49
49
|
skip?: number | undefined
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
export type FilterFunc<
|
|
53
|
-
args: FilterArgs<
|
|
54
|
-
) => Effect<(U extends undefined ?
|
|
52
|
+
export type FilterFunc<Encoded extends { id: string }> = <U extends keyof Encoded = never>(
|
|
53
|
+
args: FilterArgs<Encoded, U>
|
|
54
|
+
) => Effect<(U extends undefined ? Encoded : Pick<Encoded, U>)[]>
|
|
55
55
|
|
|
56
|
-
export interface Store<
|
|
56
|
+
export interface Store<
|
|
57
|
+
Encoded extends { id: Id },
|
|
58
|
+
Id extends string,
|
|
59
|
+
PM extends PersistenceModelType<Encoded> = PersistenceModelType<Encoded>
|
|
60
|
+
> {
|
|
57
61
|
all: Effect<PM[]>
|
|
58
|
-
filter: FilterFunc<
|
|
62
|
+
filter: FilterFunc<Encoded>
|
|
59
63
|
find: (id: Id) => Effect<Option<PM>>
|
|
60
64
|
set: (e: PM) => Effect<PM, OptimisticConcurrencyException>
|
|
61
65
|
batchSet: (
|
|
@@ -65,9 +69,9 @@ export interface Store<PM extends PersistenceModelType<Id>, Id> {
|
|
|
65
69
|
items: NonEmptyReadonlyArray<PM>
|
|
66
70
|
) => Effect<NonEmptyReadonlyArray<PM>, OptimisticConcurrencyException>
|
|
67
71
|
/**
|
|
68
|
-
* Requires the
|
|
72
|
+
* Requires the Encoded type, not Id, because various stores may need to calculate e.g partition keys.
|
|
69
73
|
*/
|
|
70
|
-
remove: (e:
|
|
74
|
+
remove: (e: Encoded) => Effect<void>
|
|
71
75
|
}
|
|
72
76
|
|
|
73
77
|
/**
|
|
@@ -75,11 +79,11 @@ export interface Store<PM extends PersistenceModelType<Id>, Id> {
|
|
|
75
79
|
* @tsplus companion StoreMaker.Ops
|
|
76
80
|
*/
|
|
77
81
|
export class StoreMaker extends TagClassId("effect-app/StoreMaker")<StoreMaker, {
|
|
78
|
-
make: <
|
|
82
|
+
make: <Encoded extends { id: Id }, Id extends string, R = never, E = never>(
|
|
79
83
|
name: string,
|
|
80
|
-
seed?: Effect<Iterable<
|
|
81
|
-
config?: StoreConfig<
|
|
82
|
-
) => Effect<Store<
|
|
84
|
+
seed?: Effect<Iterable<Encoded>, E, R>,
|
|
85
|
+
config?: StoreConfig<Encoded>
|
|
86
|
+
) => Effect<Store<Encoded, Id>, E, R>
|
|
83
87
|
}>() {
|
|
84
88
|
}
|
|
85
89
|
|
|
@@ -157,9 +161,8 @@ const makeMap = Effect.sync(() => makeContextMap())
|
|
|
157
161
|
export class ContextMap extends TagClassMakeId("effect-app/ContextMap", makeMap)<ContextMap>() {
|
|
158
162
|
}
|
|
159
163
|
|
|
160
|
-
export
|
|
161
|
-
|
|
162
|
-
_etag: string | undefined
|
|
164
|
+
export type PersistenceModelType<Encoded> = Encoded & {
|
|
165
|
+
_etag?: string | undefined
|
|
163
166
|
}
|
|
164
167
|
|
|
165
168
|
export interface StorageConfig {
|
|
@@ -4,14 +4,14 @@ import { OptimisticConcurrencyException } from "../../errors.js"
|
|
|
4
4
|
import { codeFilter3_ } from "./codeFilter.js"
|
|
5
5
|
import type { Filter, PersistenceModelType, SupportedValues2 } from "./service.js"
|
|
6
6
|
|
|
7
|
-
export const makeETag = <E extends PersistenceModelType<
|
|
7
|
+
export const makeETag = <E extends PersistenceModelType<{}>>(
|
|
8
8
|
{ _etag, ...e }: E
|
|
9
9
|
): E => (({
|
|
10
10
|
...e,
|
|
11
11
|
_etag: objectHash(e)
|
|
12
12
|
}) as any)
|
|
13
13
|
export const makeUpdateETag =
|
|
14
|
-
(type: string) => <E extends PersistenceModelType<
|
|
14
|
+
(type: string) => <E extends PersistenceModelType<{ id: string }>>(e: E, current: Option<E>) =>
|
|
15
15
|
Effect.gen(function*($) {
|
|
16
16
|
if (e._etag) {
|
|
17
17
|
yield* $(
|
package/test/query.test.ts
CHANGED
|
@@ -67,7 +67,7 @@ it("works", () => {
|
|
|
67
67
|
expect(processed).toEqual(items.slice(0, 2).toReversed().map((_) => pick(_, "id", "displayName")))
|
|
68
68
|
})
|
|
69
69
|
|
|
70
|
-
class TestRepo extends RepositoryDefaultImpl<TestRepo>()
|
|
70
|
+
class TestRepo extends RepositoryDefaultImpl<TestRepo>()(
|
|
71
71
|
"test",
|
|
72
72
|
s
|
|
73
73
|
) {
|