effect-app 4.0.0-beta.303 → 4.0.0-beta.304
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/dist/DataDependencies.d.ts +173 -310
- package/dist/DataDependencies.d.ts.map +1 -1
- package/dist/DataDependencies.js +51 -8
- package/dist/Model/Repository/internal/internal.d.ts +2 -0
- package/dist/Model/Repository/internal/internal.d.ts.map +1 -1
- package/dist/Model/Repository/internal/internal.js +27 -10
- package/dist/Model/Repository/makeRepo.d.ts +2 -0
- package/dist/Model/Repository/makeRepo.d.ts.map +1 -1
- package/dist/Model/Repository/makeRepo.js +1 -1
- package/dist/rpc/Invalidation.d.ts +1506 -2586
- package/dist/rpc/Invalidation.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/DataDependencies.ts +57 -8
- package/src/Model/Repository/internal/internal.ts +32 -9
- package/src/Model/Repository/makeRepo.ts +3 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Invalidation.d.ts","sourceRoot":"","sources":["../../src/rpc/Invalidation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,YAAY,CAAA;AACjC,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAA;AACzC,OAAO,EAAE,KAAK,gBAAgB,EAAgB,MAAM,wBAAwB,CAAA;AAC5E,OAAO,KAAK,OAAO,MAAM,eAAe,CAAA;AACxC,OAAO,KAAK,gBAAgB,MAAM,wBAAwB,CAAA;AAC1D,OAAO,KAAK,MAAM,MAAM,cAAc,CAAA;AACtC,OAAO,KAAK,CAAC,MAAM,cAAc,CAAA;AAEjC;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG,eAAe,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,gBAAgB,CAAA;CAAE,CAAA;AAmBjH;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,uCAAS,CAAA;AAC5C,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,sBAAsB,CAAC,CAAA;AAEjF,6GAA6G;AAC7G,eAAO,MAAM,eAAe;;;CAAkC,CAAA;AAC9D,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,eAAe,CAAC,CAAA;AAEnE,oFAAoF;AACpF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;CAA2B,CAAA;AACxD,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAErE,wFAAwF;AACxF,eAAO,MAAM,eAAe
|
|
1
|
+
{"version":3,"file":"Invalidation.d.ts","sourceRoot":"","sources":["../../src/rpc/Invalidation.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/DataDependencies.ts
CHANGED
|
@@ -1,13 +1,22 @@
|
|
|
1
|
+
import type { NonEmptyReadonlyArray } from "effect/Array"
|
|
1
2
|
import * as Ref from "effect/Ref"
|
|
2
3
|
import * as Stream from "effect/Stream"
|
|
4
|
+
import * as Context from "./Context.ts"
|
|
3
5
|
import * as Effect from "./Effect.ts"
|
|
4
6
|
import * as RequestScopedDependencies from "./RequestScopedDependencies.ts"
|
|
5
7
|
import * as S from "./Schema.ts"
|
|
6
8
|
|
|
7
|
-
export const DataDependency = S.
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
export const DataDependency = S.Union([
|
|
10
|
+
S.Struct({
|
|
11
|
+
type: S.Literal("repo"),
|
|
12
|
+
name: S.String,
|
|
13
|
+
ids: S.optional(S.NonEmptyArray(S.String))
|
|
14
|
+
}),
|
|
15
|
+
S.Struct({
|
|
16
|
+
type: S.Literal("signal"),
|
|
17
|
+
name: S.String
|
|
18
|
+
})
|
|
19
|
+
])
|
|
11
20
|
export type DataDependency = S.Schema.Type<typeof DataDependency>
|
|
12
21
|
|
|
13
22
|
export const DataDependencies = S.ReadonlySet(DataDependency)
|
|
@@ -29,15 +38,39 @@ export interface DataDependencyRecorderService {
|
|
|
29
38
|
readonly drainWrites: Effect.Effect<DataDependencies>
|
|
30
39
|
}
|
|
31
40
|
|
|
41
|
+
const sameDomain = (a: DataDependency, b: DataDependency) => a.type === b.type && a.name === b.name
|
|
42
|
+
|
|
43
|
+
const dependenciesOverlap = (a: DataDependency, b: DataDependency) => {
|
|
44
|
+
if (!sameDomain(a, b)) return false
|
|
45
|
+
if (a.type === "signal" || b.type === "signal") return true
|
|
46
|
+
if (a.ids === undefined || b.ids === undefined) return true
|
|
47
|
+
return a.ids.some((id) => b.ids?.includes(id))
|
|
48
|
+
}
|
|
49
|
+
|
|
32
50
|
const containsDependency = (dependencies: ReadonlySet<DataDependency>, dependency: DataDependency) => {
|
|
33
51
|
for (const _ of dependencies) {
|
|
34
|
-
if (_
|
|
52
|
+
if (dependenciesOverlap(_, dependency)) return true
|
|
35
53
|
}
|
|
36
54
|
return false
|
|
37
55
|
}
|
|
38
56
|
|
|
39
|
-
const appendDependency = (dependency: DataDependency) => (dependencies: DataDependencies): DataDependencies =>
|
|
40
|
-
|
|
57
|
+
const appendDependency = (dependency: DataDependency) => (dependencies: DataDependencies): DataDependencies => {
|
|
58
|
+
const existing = [...dependencies].find((_) => sameDomain(_, dependency))
|
|
59
|
+
if (existing === undefined) return new Set([...dependencies, dependency])
|
|
60
|
+
if (existing.type === "signal" || dependency.type === "signal") return dependencies
|
|
61
|
+
if (existing.ids === undefined) return dependencies
|
|
62
|
+
if (dependency.ids === undefined) {
|
|
63
|
+
return new Set([...dependencies].filter((_) => _ !== existing).concat(dependency))
|
|
64
|
+
}
|
|
65
|
+
const first = existing.ids[0]
|
|
66
|
+
const ids: NonEmptyReadonlyArray<string> = [
|
|
67
|
+
first,
|
|
68
|
+
...new Set([...existing.ids.slice(1), ...dependency.ids].filter((id) => id !== first))
|
|
69
|
+
]
|
|
70
|
+
if (ids.length === existing.ids.length) return dependencies
|
|
71
|
+
const merged = repo(existing.name, ids)
|
|
72
|
+
return new Set([...dependencies].filter((_) => _ !== existing).concat(merged))
|
|
73
|
+
}
|
|
41
74
|
|
|
42
75
|
export const DataDependencyRecorder = RequestScopedDependencies.make(
|
|
43
76
|
"effect-app/DataDependencyRecorder",
|
|
@@ -90,9 +123,25 @@ export const makeDataDependencyRecorder = (
|
|
|
90
123
|
drainWrites: Ref.getAndSet(writesRef, empty())
|
|
91
124
|
})
|
|
92
125
|
|
|
93
|
-
export const repo = (name: string): DataDependency =>
|
|
126
|
+
export const repo = (name: string, ids?: NonEmptyReadonlyArray<string>): DataDependency =>
|
|
127
|
+
ids === undefined ? { type: "repo", name } : { type: "repo", name, ids }
|
|
94
128
|
export const signal = (name: string): DataDependency => ({ type: "signal", name })
|
|
95
129
|
|
|
130
|
+
const RepoReadScope = Context.Reference<DataDependency | undefined>("effect-app/DataDependencies/RepoReadScope", {
|
|
131
|
+
defaultValue: () => undefined
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
export const readRepo = (name: string) =>
|
|
135
|
+
Effect.flatMap(
|
|
136
|
+
RepoReadScope,
|
|
137
|
+
(scope) => read(scope?.type === "repo" && scope.name === name ? scope : repo(name))
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
export const withRepoReadScope =
|
|
141
|
+
(name: string, ids: NonEmptyReadonlyArray<string>) =>
|
|
142
|
+
<A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>
|
|
143
|
+
Effect.provideService(self, RepoReadScope, repo(name, ids))
|
|
144
|
+
|
|
96
145
|
export const QueryReadDependenciesMetaKey = "effect-app.query.readDependencies"
|
|
97
146
|
|
|
98
147
|
export const read = (dependency: DataDependency) =>
|
|
@@ -114,6 +114,7 @@ export function makeRepoInternal<
|
|
|
114
114
|
args: [Evt] extends [never] ? {
|
|
115
115
|
schemaContext?: Context.Context<RCtx>
|
|
116
116
|
makeInitial?: Effect.Effect<readonly T[], E, RInitial> | undefined
|
|
117
|
+
dependencyIds?: (item: T) => NonEmptyReadonlyArray<string>
|
|
117
118
|
config?: Omit<StoreConfig<Encoded>, "partitionValue"> & {
|
|
118
119
|
partitionValue?: (e?: Encoded) => string
|
|
119
120
|
}
|
|
@@ -122,6 +123,7 @@ export function makeRepoInternal<
|
|
|
122
123
|
schemaContext?: Context.Context<RCtx>
|
|
123
124
|
publishEvents: (evt: NonEmptyReadonlyArray<Evt>) => Effect.Effect<void, never, RPublish>
|
|
124
125
|
makeInitial?: Effect.Effect<readonly T[], E, RInitial> | undefined
|
|
126
|
+
dependencyIds?: (item: T) => NonEmptyReadonlyArray<string>
|
|
125
127
|
config?: Omit<StoreConfig<Encoded>, "partitionValue"> & {
|
|
126
128
|
partitionValue?: (e?: Encoded) => string
|
|
127
129
|
}
|
|
@@ -143,9 +145,21 @@ export function makeRepoInternal<
|
|
|
143
145
|
)
|
|
144
146
|
|
|
145
147
|
const store = yield* mkStore(args.makeInitial, args.config)
|
|
146
|
-
const
|
|
147
|
-
const
|
|
148
|
-
|
|
148
|
+
const recordRead = DataDependencies.readRepo(name)
|
|
149
|
+
const entityDependency = (ids: NonEmptyReadonlyArray<T[IdKey]>) =>
|
|
150
|
+
DataDependencies.repo(name, [String(ids[0]), ...ids.slice(1).map(String)])
|
|
151
|
+
const itemDependency = (items: NonEmptyReadonlyArray<T>) => {
|
|
152
|
+
const firstIds = args.dependencyIds?.(items[0]) ?? [String(items[0][idKey])]
|
|
153
|
+
return DataDependencies.repo(name, [
|
|
154
|
+
firstIds[0],
|
|
155
|
+
...firstIds.slice(1),
|
|
156
|
+
...items.slice(1).flatMap((item) => args.dependencyIds?.(item) ?? [String(item[idKey])])
|
|
157
|
+
])
|
|
158
|
+
}
|
|
159
|
+
const recordEntityRead = (id: T[IdKey]) => DataDependencies.read(entityDependency([id]))
|
|
160
|
+
const recordEntityWrite = (ids: NonEmptyReadonlyArray<T[IdKey]>) =>
|
|
161
|
+
DataDependencies.write(entityDependency(ids))
|
|
162
|
+
const recordItemWrite = (items: NonEmptyReadonlyArray<T>) => DataDependencies.write(itemDependency(items))
|
|
149
163
|
const cms = Effect.map(getContextMap.pipe(Effect.orDie), (_) => ({
|
|
150
164
|
get: (id: string) => _.get(`${name}.${id}`),
|
|
151
165
|
set: (id: string, etag: string | undefined) => _.set(`${name}.${id}`, etag)
|
|
@@ -282,7 +296,7 @@ export function makeRepoInternal<
|
|
|
282
296
|
kind: "client",
|
|
283
297
|
attributes: { "app.entity": name }
|
|
284
298
|
})(function*(id: T[IdKey]) {
|
|
285
|
-
yield*
|
|
299
|
+
yield* recordEntityRead(id)
|
|
286
300
|
yield* Effect.annotateCurrentSpan({ "app.entity.id": id })
|
|
287
301
|
return yield* flatMapOption(findE(id), (_) => Effect.orDie(decode(_)))
|
|
288
302
|
})
|
|
@@ -310,8 +324,11 @@ export function makeRepoInternal<
|
|
|
310
324
|
|
|
311
325
|
const saveAndPublish = Effect.fn("Repository.saveAndPublish", { attributes: { "app.entity": name } })(
|
|
312
326
|
function*(items: Iterable<T>, events: Iterable<Evt> = []) {
|
|
313
|
-
yield* recordWrite
|
|
314
327
|
const it = Chunk.fromIterable(items)
|
|
328
|
+
if (Chunk.isNonEmpty(it)) {
|
|
329
|
+
const values = Chunk.toReadonlyArray(it)
|
|
330
|
+
yield* recordItemWrite([values[0], ...values.slice(1)])
|
|
331
|
+
}
|
|
315
332
|
const evts = [...events]
|
|
316
333
|
yield* Effect.annotateCurrentSpan({
|
|
317
334
|
"app.entity.ids": Chunk.map(it, (_) => _[idKey]),
|
|
@@ -330,9 +347,11 @@ export function makeRepoInternal<
|
|
|
330
347
|
|
|
331
348
|
const removeAndPublish = Effect.fn("Repository.removeAndPublish", { attributes: { "app.entity": name } })(
|
|
332
349
|
function*(a: Iterable<T>, events: Iterable<Evt> = []) {
|
|
333
|
-
yield* recordWrite
|
|
334
350
|
const { set } = yield* cms
|
|
335
351
|
const it = [...a]
|
|
352
|
+
if (Array.isReadonlyArrayNonEmpty(it)) {
|
|
353
|
+
yield* recordItemWrite(it)
|
|
354
|
+
}
|
|
336
355
|
const evts = [...events]
|
|
337
356
|
yield* Effect.annotateCurrentSpan({
|
|
338
357
|
"app.entity.ids": it.map((_) => _[idKey]),
|
|
@@ -359,13 +378,13 @@ export function makeRepoInternal<
|
|
|
359
378
|
|
|
360
379
|
const removeById = Effect.fn("Repository.removeById", { attributes: { "app.entity": name } })(
|
|
361
380
|
function*(idOrIds: T[IdKey] | ReadonlyArray<T[IdKey]>) {
|
|
362
|
-
yield* recordWrite
|
|
363
381
|
const ids = globalThis.Array.isArray(idOrIds)
|
|
364
382
|
? idOrIds as readonly T[IdKey][]
|
|
365
383
|
: [idOrIds as T[IdKey]]
|
|
366
384
|
if (!Array.isReadonlyArrayNonEmpty(ids)) {
|
|
367
385
|
return
|
|
368
386
|
}
|
|
387
|
+
yield* recordEntityWrite(ids)
|
|
369
388
|
const { set } = yield* cms
|
|
370
389
|
const eids = yield* Effect.forEach(ids, (_) => encodeIdOnly(_ as any)).pipe(Effect.orDie)
|
|
371
390
|
yield* Effect.annotateCurrentSpan({ "app.entity.ids": eids })
|
|
@@ -640,7 +659,7 @@ export function makeRepoInternal<
|
|
|
640
659
|
),
|
|
641
660
|
find: (id: T[IdKey]) =>
|
|
642
661
|
flatMapOption(findE(id), dec).pipe(
|
|
643
|
-
Effect.tap(() =>
|
|
662
|
+
Effect.tap(() => recordEntityRead(id)),
|
|
644
663
|
Effect.withSpan("Repository.mapped.find", {
|
|
645
664
|
...spanAttrs,
|
|
646
665
|
attributes: { ...spanAttrs.attributes, "app.entity.id": id }
|
|
@@ -669,7 +688,11 @@ export function makeRepoInternal<
|
|
|
669
688
|
(_) => saveAllE(_)
|
|
670
689
|
)
|
|
671
690
|
.pipe(
|
|
672
|
-
Effect.tap(() =>
|
|
691
|
+
Effect.tap(() =>
|
|
692
|
+
Array.isReadonlyArrayNonEmpty(xes)
|
|
693
|
+
? recordEntityWrite([xes[0][idKey], ...xes.slice(1).map((_) => _[idKey])])
|
|
694
|
+
: Effect.void
|
|
695
|
+
),
|
|
673
696
|
Effect.withSpan("Repository.mapped.save", spanAttrs, { captureStackTrace: false })
|
|
674
697
|
)
|
|
675
698
|
}
|
|
@@ -58,6 +58,9 @@ export interface RepositoryOptions<
|
|
|
58
58
|
*/
|
|
59
59
|
schemaContext?: Context.Context<RCtx>
|
|
60
60
|
|
|
61
|
+
/** IDs, including aliases, that identify an entity for dependency invalidation. */
|
|
62
|
+
dependencyIds?: (item: T) => NonEmptyReadonlyArray<string>
|
|
63
|
+
|
|
61
64
|
overrides?: (
|
|
62
65
|
repo: Repository<T, Encoded, Evt, ItemType, IdKey, Exclude<RSchema, RCtx>, RPublish, RCtx>
|
|
63
66
|
) => Repository<T, Encoded, Evt, ItemType, IdKey, Exclude<RSchema, RCtx>, RPublish, RCtx>
|