effect-app 4.0.0-beta.281 → 4.0.0-beta.283
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 +32 -0
- package/dist/DataDependencies.d.ts +159 -0
- package/dist/DataDependencies.d.ts.map +1 -0
- package/dist/DataDependencies.js +44 -0
- package/dist/Model/Repository/internal/internal.d.ts.map +1 -1
- package/dist/Model/Repository/internal/internal.js +16 -8
- package/dist/Model/query/new-kid-interpreter.js +2 -2
- package/dist/QueueMaker.d.ts +8 -10
- package/dist/QueueMaker.d.ts.map +1 -1
- package/dist/QueueMaker.js +9 -2
- package/dist/Schema/Class.d.ts +1 -1
- package/dist/Schema/Class.d.ts.map +1 -1
- package/dist/Schema/Class.js +2 -2
- package/dist/Schema/ext.d.ts +1 -1
- package/dist/Schema/ext.d.ts.map +1 -1
- package/dist/Schema/moreStrings.d.ts +1 -1
- package/dist/Schema/moreStrings.d.ts.map +1 -1
- package/dist/Schema/numbers.d.ts +1 -1
- package/dist/Schema/numbers.d.ts.map +1 -1
- package/dist/Schema/schema.d.ts +1 -1
- package/dist/Schema/schema.d.ts.map +1 -1
- package/dist/Schema/schema.js +2 -2
- package/dist/Schema/strings.d.ts +1 -1
- package/dist/Schema/strings.d.ts.map +1 -1
- package/dist/Schema.d.ts +14 -1
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +3 -2
- package/dist/SchemaAST.d.ts +23 -0
- package/dist/SchemaAST.d.ts.map +1 -0
- package/dist/SchemaAST.js +25 -0
- package/dist/client/apiClientFactory.d.ts.map +1 -1
- package/dist/client/apiClientFactory.js +44 -7
- package/dist/client/makeClient.d.ts +19 -23
- package/dist/client/makeClient.d.ts.map +1 -1
- package/dist/client/makeClient.js +3 -10
- package/dist/client.d.ts +1 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +2 -1
- package/dist/rpc/Invalidation.d.ts +994 -2
- package/dist/rpc/Invalidation.d.ts.map +1 -1
- package/dist/rpc/Invalidation.js +10 -3
- package/package.json +2 -2
- package/src/DataDependencies.ts +78 -0
- package/src/Model/Repository/internal/internal.ts +15 -1
- package/src/Model/query/new-kid-interpreter.ts +1 -1
- package/src/QueueMaker.ts +8 -16
- package/src/Schema/Class.ts +1 -1
- package/src/Schema/ext.ts +1 -1
- package/src/Schema/moreStrings.ts +1 -1
- package/src/Schema/numbers.ts +1 -1
- package/src/Schema/schema.ts +1 -1
- package/src/Schema/strings.ts +1 -1
- package/src/Schema.ts +14 -1
- package/src/SchemaAST.ts +29 -0
- package/src/client/apiClientFactory.ts +64 -16
- package/src/client/makeClient.ts +12 -22
- package/src/client.ts +1 -0
- package/src/rpc/Invalidation.ts +16 -2
- package/test/dist/rpc.test.d.ts.map +1 -1
- package/test/rpc.test.ts +7 -8
|
@@ -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,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/dist/rpc/Invalidation.js
CHANGED
|
@@ -2,6 +2,7 @@ import * as Ref from "effect/Ref";
|
|
|
2
2
|
import { Rpc } from "effect/unstable/rpc";
|
|
3
3
|
import { makeQueryKey } from "../client/clientFor.js";
|
|
4
4
|
import * as Context from "../Context.js";
|
|
5
|
+
import * as DataDependencies from "../DataDependencies.js";
|
|
5
6
|
import * as Effect from "../Effect.js";
|
|
6
7
|
import * as S from "../Schema.js";
|
|
7
8
|
const normalizeKey = (input) => {
|
|
@@ -12,7 +13,7 @@ const normalizeKey = (input) => {
|
|
|
12
13
|
};
|
|
13
14
|
// Disambiguates `add` overloads: a `string[]` means a single key; an array
|
|
14
15
|
// containing arrays-or-objects means a batch of inputs.
|
|
15
|
-
const isBatch = (input) => Array.isArray(input) && input
|
|
16
|
+
const isBatch = (input) => Array.isArray(input) && input[0] !== undefined && typeof input[0] !== "string";
|
|
16
17
|
const normalizeInputs = (input) => isBatch(input) ? input.map(normalizeKey) : [normalizeKey(input)];
|
|
17
18
|
/**
|
|
18
19
|
* A single segment within an `InvalidationKey` array.
|
|
@@ -25,7 +26,13 @@ export const InvalidationKey = S.Array(InvalidationKeySegment);
|
|
|
25
26
|
/** Schema for the full set of invalidation keys – an array of `InvalidationKey`. */
|
|
26
27
|
export const InvalidationKeys = S.Array(InvalidationKey);
|
|
27
28
|
/** Metadata included in every command response for server-driven cache invalidation. */
|
|
28
|
-
export const CommandMetaData = S.Struct({
|
|
29
|
+
export const CommandMetaData = S.Struct({
|
|
30
|
+
invalidateQueries: InvalidationKeys,
|
|
31
|
+
dataDependencies: DataDependencies.DataDependencySet
|
|
32
|
+
});
|
|
33
|
+
export const emptyDataDependencies = { reads: [], writes: [] };
|
|
34
|
+
export const makeMetaData = (invalidateQueries, dataDependencies = emptyDataDependencies) => ({ invalidateQueries, dataDependencies });
|
|
35
|
+
export const QueryResponseWithMetaData = (success) => S.Struct({ payload: success, metadata: S.Struct({ dataDependencies: DataDependencies.DataDependencySet }) });
|
|
29
36
|
/**
|
|
30
37
|
* Wraps a command's success schema so that the wire format carries both the `payload`
|
|
31
38
|
* (the handler's actual return value) and `metadata` (server-driven cache invalidation keys).
|
|
@@ -165,4 +172,4 @@ export const makeStreamRpc = Rpc.custom(({ defect, error, success }) => ({
|
|
|
165
172
|
error: StreamFailureChunk(error),
|
|
166
173
|
defect
|
|
167
174
|
}));
|
|
168
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
175
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSW52YWxpZGF0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3JwYy9JbnZhbGlkYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEdBQUcsTUFBTSxZQUFZLENBQUE7QUFDakMsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLHFCQUFxQixDQUFBO0FBQ3pDLE9BQU8sRUFBeUIsWUFBWSxFQUFFLE1BQU0sd0JBQXdCLENBQUE7QUFDNUUsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUE7QUFDeEMsT0FBTyxLQUFLLGdCQUFnQixNQUFNLHdCQUF3QixDQUFBO0FBQzFELE9BQU8sS0FBSyxNQUFNLE1BQU0sY0FBYyxDQUFBO0FBQ3RDLE9BQU8sS0FBSyxDQUFDLE1BQU0sY0FBYyxDQUFBO0FBU2pDLE1BQU0sWUFBWSxHQUFHLENBQUMsS0FBMkIsRUFBbUIsRUFBRTtJQUNwRSxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUE7SUFDdEMsTUFBTSxPQUFPLEdBQUcsS0FBbUQsQ0FBQTtJQUNuRSxPQUFPLFlBQVksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxPQUFPLENBQUMsRUFBRSxFQUFFLE9BQU8sRUFBRSxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLE9BQU8sQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFBO0FBQzFHLENBQUMsQ0FBQTtBQUVELDJFQUEyRTtBQUMzRSx3REFBd0Q7QUFDeEQsTUFBTSxPQUFPLEdBQUcsQ0FDZCxLQUFpRSxFQUNuQixFQUFFLENBQ2hELEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLFNBQVMsSUFBSSxPQUFPLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxRQUFRLENB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
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "effect-app",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.283",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"dependencies": {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"vitest": "^4.1.7"
|
|
22
22
|
},
|
|
23
23
|
"peerDependencies": {
|
|
24
|
-
"effect": "^4.0.0-beta.
|
|
24
|
+
"effect": "^4.0.0-beta.88"
|
|
25
25
|
},
|
|
26
26
|
"typesVersions": {
|
|
27
27
|
"*": {
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import * as Ref from "effect/Ref"
|
|
2
|
+
import * as Context from "./Context.ts"
|
|
3
|
+
import * as Effect from "./Effect.ts"
|
|
4
|
+
import * as S from "./Schema.ts"
|
|
5
|
+
|
|
6
|
+
export const DataDependency = S.Struct({
|
|
7
|
+
type: S.Literals(["repo", "signal"]),
|
|
8
|
+
name: S.String
|
|
9
|
+
})
|
|
10
|
+
export type DataDependency = S.Schema.Type<typeof DataDependency>
|
|
11
|
+
|
|
12
|
+
export const DataDependencies = S.Array(DataDependency)
|
|
13
|
+
export type DataDependencies = S.Schema.Type<typeof DataDependencies>
|
|
14
|
+
|
|
15
|
+
export const DataDependencySet = S.Struct({
|
|
16
|
+
reads: DataDependencies,
|
|
17
|
+
writes: DataDependencies
|
|
18
|
+
})
|
|
19
|
+
export type DataDependencySet = S.Schema.Type<typeof DataDependencySet>
|
|
20
|
+
|
|
21
|
+
export interface DataDependencyRecorderService {
|
|
22
|
+
readonly read: (dependency: DataDependency) => Effect.Effect<void>
|
|
23
|
+
readonly write: (dependency: DataDependency) => Effect.Effect<void>
|
|
24
|
+
readonly get: Effect.Effect<DataDependencySet>
|
|
25
|
+
readonly drain: Effect.Effect<DataDependencySet>
|
|
26
|
+
readonly drainWrites: Effect.Effect<DataDependencies>
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const containsDependency = (dependencies: ReadonlyArray<DataDependency>, dependency: DataDependency) =>
|
|
30
|
+
dependencies.some((_) => _.type === dependency.type && _.name === dependency.name)
|
|
31
|
+
|
|
32
|
+
const appendDependency = (dependency: DataDependency) => (dependencies: DataDependencies): DataDependencies =>
|
|
33
|
+
containsDependency(dependencies, dependency) ? dependencies : [...dependencies, dependency]
|
|
34
|
+
|
|
35
|
+
export const DataDependencyRecorder = Context.Reference<DataDependencyRecorderService>(
|
|
36
|
+
"effect-app/DataDependencyRecorder",
|
|
37
|
+
{
|
|
38
|
+
defaultValue: () => ({
|
|
39
|
+
read: (_dependency) => Effect.void,
|
|
40
|
+
write: (_dependency) => Effect.void,
|
|
41
|
+
get: Effect.succeed({ reads: [], writes: [] }),
|
|
42
|
+
drain: Effect.succeed({ reads: [], writes: [] }),
|
|
43
|
+
drainWrites: Effect.succeed([])
|
|
44
|
+
})
|
|
45
|
+
}
|
|
46
|
+
)
|
|
47
|
+
export type DataDependencyRecorder = typeof DataDependencyRecorder
|
|
48
|
+
|
|
49
|
+
export const makeDataDependencyRecorder = (
|
|
50
|
+
readsRef: Ref.Ref<DataDependencies>,
|
|
51
|
+
writesRef: Ref.Ref<DataDependencies>
|
|
52
|
+
): DataDependencyRecorderService => ({
|
|
53
|
+
read: (dependency) => Ref.update(readsRef, appendDependency(dependency)),
|
|
54
|
+
write: (dependency) => Ref.update(writesRef, appendDependency(dependency)),
|
|
55
|
+
get: Effect.all({
|
|
56
|
+
reads: Ref.get(readsRef),
|
|
57
|
+
writes: Ref.get(writesRef)
|
|
58
|
+
}),
|
|
59
|
+
drain: Effect.all({
|
|
60
|
+
reads: Ref.getAndSet(readsRef, []),
|
|
61
|
+
writes: Ref.getAndSet(writesRef, [])
|
|
62
|
+
}),
|
|
63
|
+
drainWrites: Ref.getAndSet(writesRef, [])
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
export const repo = (name: string): DataDependency => ({ type: "repo", name })
|
|
67
|
+
export const signal = (name: string): DataDependency => ({ type: "signal", name })
|
|
68
|
+
|
|
69
|
+
export const QueryReadDependenciesMetaKey = "effect-app.query.readDependencies"
|
|
70
|
+
|
|
71
|
+
export const read = (dependency: DataDependency) => DataDependencyRecorder.use((_) => _.read(dependency))
|
|
72
|
+
|
|
73
|
+
export const write = (dependency: DataDependency) => DataDependencyRecorder.use((_) => _.write(dependency))
|
|
74
|
+
|
|
75
|
+
export const intersects = (
|
|
76
|
+
a: ReadonlyArray<DataDependency>,
|
|
77
|
+
b: ReadonlyArray<DataDependency>
|
|
78
|
+
) => a.some((dependency) => containsDependency(b, dependency))
|
|
@@ -7,7 +7,7 @@ import * as HashSet from "effect/HashSet"
|
|
|
7
7
|
import * as Pipeable from "effect/Pipeable"
|
|
8
8
|
import * as Ref from "effect/Ref"
|
|
9
9
|
import * as Result from "effect/Result"
|
|
10
|
-
import * as SchemaAST from "
|
|
10
|
+
import * as SchemaAST from "../../../SchemaAST.ts"
|
|
11
11
|
import type * as Scope from "effect/Scope"
|
|
12
12
|
import * as Unify from "effect/Unify"
|
|
13
13
|
import * as Array from "../../../Array.ts"
|
|
@@ -16,6 +16,7 @@ import { toNonEmptyArray } from "../../../Array.ts"
|
|
|
16
16
|
import * as Chunk from "../../../Chunk.ts"
|
|
17
17
|
import { NotFoundError } from "../../../client/errors.ts"
|
|
18
18
|
import * as Context from "../../../Context.ts"
|
|
19
|
+
import * as DataDependencies from "../../../DataDependencies.ts"
|
|
19
20
|
import * as Effect from "../../../Effect.ts"
|
|
20
21
|
import { flatMapOption } from "../../../Effect.ts"
|
|
21
22
|
import * as Option from "../../../Option.ts"
|
|
@@ -100,6 +101,9 @@ export function makeRepoInternal<
|
|
|
100
101
|
)
|
|
101
102
|
|
|
102
103
|
const store = yield* mkStore(args.makeInitial, args.config)
|
|
104
|
+
const repoDependency = DataDependencies.repo(name)
|
|
105
|
+
const recordRead = DataDependencies.read(repoDependency)
|
|
106
|
+
const recordWrite = DataDependencies.write(repoDependency)
|
|
103
107
|
const cms = Effect.map(getContextMap.pipe(Effect.orDie), (_) => ({
|
|
104
108
|
get: (id: string) => _.get(`${name}.${id}`),
|
|
105
109
|
set: (id: string, etag: string | undefined) => _.set(`${name}.${id}`, etag)
|
|
@@ -162,6 +166,7 @@ export function makeRepoInternal<
|
|
|
162
166
|
(_) => decodeMany(_).pipe(Effect.orDie)
|
|
163
167
|
)
|
|
164
168
|
.pipe(
|
|
169
|
+
Effect.tap(() => recordRead),
|
|
165
170
|
Effect.map((_) => _ as T[]),
|
|
166
171
|
Effect.withSpan("Repository.all", {
|
|
167
172
|
kind: "client",
|
|
@@ -231,6 +236,7 @@ export function makeRepoInternal<
|
|
|
231
236
|
kind: "client",
|
|
232
237
|
attributes: { "app.entity": name }
|
|
233
238
|
})(function*(id: T[IdKey]) {
|
|
239
|
+
yield* recordRead
|
|
234
240
|
yield* Effect.annotateCurrentSpan({ "app.entity.id": id })
|
|
235
241
|
return yield* flatMapOption(findE(id), (_) => Effect.orDie(decode(_)))
|
|
236
242
|
})
|
|
@@ -258,6 +264,7 @@ export function makeRepoInternal<
|
|
|
258
264
|
|
|
259
265
|
const saveAndPublish = Effect.fn("Repository.saveAndPublish", { attributes: { "app.entity": name } })(
|
|
260
266
|
function*(items: Iterable<T>, events: Iterable<Evt> = []) {
|
|
267
|
+
yield* recordWrite
|
|
261
268
|
const it = Chunk.fromIterable(items)
|
|
262
269
|
const evts = [...events]
|
|
263
270
|
yield* Effect.annotateCurrentSpan({
|
|
@@ -277,6 +284,7 @@ export function makeRepoInternal<
|
|
|
277
284
|
|
|
278
285
|
const removeAndPublish = Effect.fn("Repository.removeAndPublish", { attributes: { "app.entity": name } })(
|
|
279
286
|
function*(a: Iterable<T>, events: Iterable<Evt> = []) {
|
|
287
|
+
yield* recordWrite
|
|
280
288
|
const { set } = yield* cms
|
|
281
289
|
const it = [...a]
|
|
282
290
|
const evts = [...events]
|
|
@@ -305,6 +313,7 @@ export function makeRepoInternal<
|
|
|
305
313
|
|
|
306
314
|
const removeById = Effect.fn("Repository.removeById", { attributes: { "app.entity": name } })(
|
|
307
315
|
function*(idOrIds: T[IdKey] | ReadonlyArray<T[IdKey]>) {
|
|
316
|
+
yield* recordWrite
|
|
308
317
|
const ids = globalThis.Array.isArray(idOrIds)
|
|
309
318
|
? idOrIds as readonly T[IdKey][]
|
|
310
319
|
: [idOrIds as T[IdKey]]
|
|
@@ -460,6 +469,7 @@ export function makeRepoInternal<
|
|
|
460
469
|
"db.response.returned_rows": Array.isArray(r) ? r.length : 1
|
|
461
470
|
})
|
|
462
471
|
),
|
|
472
|
+
Effect.tap(() => recordRead),
|
|
463
473
|
Effect.withSpan("Repository.query", {
|
|
464
474
|
kind: "client",
|
|
465
475
|
attributes: { "app.entity": name }
|
|
@@ -552,6 +562,7 @@ export function makeRepoInternal<
|
|
|
552
562
|
const dec = S.decodeEffectConcurrently(S.Array(schema))
|
|
553
563
|
return store.queryRaw(q).pipe(
|
|
554
564
|
Effect.flatMap(dec),
|
|
565
|
+
Effect.tap(() => recordRead),
|
|
555
566
|
Effect.withSpan("Repository.queryRaw", {
|
|
556
567
|
kind: "client",
|
|
557
568
|
attributes: { "app.entity": name }
|
|
@@ -573,11 +584,13 @@ export function makeRepoInternal<
|
|
|
573
584
|
return {
|
|
574
585
|
all: allE.pipe(
|
|
575
586
|
Effect.flatMap(decMany),
|
|
587
|
+
Effect.tap(() => recordRead),
|
|
576
588
|
Effect.map((_) => _ as any[]),
|
|
577
589
|
Effect.withSpan("Repository.mapped.all", spanAttrs, { captureStackTrace: false })
|
|
578
590
|
),
|
|
579
591
|
find: (id: T[IdKey]) =>
|
|
580
592
|
flatMapOption(findE(id), dec).pipe(
|
|
593
|
+
Effect.tap(() => recordRead),
|
|
581
594
|
Effect.withSpan("Repository.mapped.find", {
|
|
582
595
|
...spanAttrs,
|
|
583
596
|
attributes: { ...spanAttrs.attributes, "app.entity.id": id }
|
|
@@ -601,6 +614,7 @@ export function makeRepoInternal<
|
|
|
601
614
|
// },
|
|
602
615
|
save: (...xes: any[]) =>
|
|
603
616
|
Effect.flatMap(encMany(xes), (_) => saveAllE(_)).pipe(
|
|
617
|
+
Effect.tap(() => recordWrite),
|
|
604
618
|
Effect.withSpan("Repository.mapped.save", spanAttrs, { captureStackTrace: false })
|
|
605
619
|
)
|
|
606
620
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
3
3
|
import { identity, pipe } from "effect/Function"
|
|
4
4
|
import * as Match from "effect/Match"
|
|
5
|
-
import * as SchemaAST from "
|
|
5
|
+
import * as SchemaAST from "../../SchemaAST.ts"
|
|
6
6
|
import * as Array from "../../Array.ts"
|
|
7
7
|
import { toNonEmptyArray } from "../../Array.ts"
|
|
8
8
|
import * as Option from "../../Option.ts"
|
package/src/QueueMaker.ts
CHANGED
|
@@ -1,19 +1,11 @@
|
|
|
1
|
-
import type * as Scope from "effect/Scope"
|
|
2
|
-
import type { NonEmptyReadonlyArray } from "./Array.ts"
|
|
3
|
-
import type * as Effect from "./Effect.ts"
|
|
4
1
|
import { RequestContext } from "./RequestContext.ts"
|
|
5
2
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface QueueMakerOps {}
|
|
17
|
-
export const QueueMaker: QueueMakerOps = {}
|
|
18
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Per-message context envelope (tenant/store id, request metadata) carried
|
|
5
|
+
* alongside message-schema payloads. Alias of {@link RequestContext}.
|
|
6
|
+
*
|
|
7
|
+
* All that remains of the former queue machinery (SB/SQLite/mem `QueueMaker`
|
|
8
|
+
* implementations and the `QueueBase` interface) after the move to cluster
|
|
9
|
+
* entities — the message schemas that embed it still reference this envelope.
|
|
10
|
+
*/
|
|
19
11
|
export const QueueMeta = RequestContext
|
package/src/Schema/Class.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type * as Cause from "effect/Cause"
|
|
|
3
3
|
import * as Effect from "effect/Effect"
|
|
4
4
|
import * as Option from "effect/Option"
|
|
5
5
|
import * as S from "effect/Schema"
|
|
6
|
-
import * as SchemaAST from "
|
|
6
|
+
import * as SchemaAST from "../SchemaAST.ts"
|
|
7
7
|
import * as SchemaGetter from "effect/SchemaGetter"
|
|
8
8
|
import * as SchemaIssue from "effect/SchemaIssue"
|
|
9
9
|
import * as SchemaTransformation from "effect/SchemaTransformation"
|
package/src/Schema/ext.ts
CHANGED
|
@@ -37,7 +37,7 @@ import * as Function from "effect/Function"
|
|
|
37
37
|
import * as Option from "effect/Option"
|
|
38
38
|
import * as S from "effect/Schema"
|
|
39
39
|
import { isDateValid } from "effect/Schema"
|
|
40
|
-
import type * as SchemaAST from "
|
|
40
|
+
import type * as SchemaAST from "../SchemaAST.ts"
|
|
41
41
|
import * as SchemaIssue from "effect/SchemaIssue"
|
|
42
42
|
import * as SchemaTransformation from "effect/SchemaTransformation"
|
|
43
43
|
import { type NonEmptyReadonlyArray } from "../Array.ts"
|
|
@@ -14,7 +14,7 @@ import type * as B from "effect/Brand"
|
|
|
14
14
|
import * as Effect from "effect/Effect"
|
|
15
15
|
import { pipe } from "effect/Function"
|
|
16
16
|
import * as S from "effect/Schema"
|
|
17
|
-
import type * as SchemaAST from "
|
|
17
|
+
import type * as SchemaAST from "../SchemaAST.ts"
|
|
18
18
|
import type { Simplify } from "effect/Types"
|
|
19
19
|
import { customRandom, nanoid, urlAlphabet } from "nanoid"
|
|
20
20
|
import validator from "validator"
|
package/src/Schema/numbers.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
import { extendM } from "effect-app/utils"
|
|
12
12
|
import * as Effect from "effect/Effect"
|
|
13
13
|
import * as S from "effect/Schema"
|
|
14
|
-
import type * as SchemaAST from "
|
|
14
|
+
import type * as SchemaAST from "../SchemaAST.ts"
|
|
15
15
|
import type { Simplify } from "effect/Types"
|
|
16
16
|
import { type BrandedSchema, fromBrand, nominal } from "./brand.ts"
|
|
17
17
|
import { withDefaultMake } from "./ext.ts"
|
package/src/Schema/schema.ts
CHANGED
package/src/Schema/strings.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type * as B from "effect/Brand"
|
|
2
2
|
import * as S from "effect/Schema"
|
|
3
|
-
import type * as SchemaAST from "
|
|
3
|
+
import type * as SchemaAST from "../SchemaAST.ts"
|
|
4
4
|
import type { Simplify } from "effect/Types"
|
|
5
5
|
import { type BrandedSchema, fromBrand, nominal } from "./brand.ts"
|
|
6
6
|
import { withDefaultMake } from "./ext.ts"
|
package/src/Schema.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as S from "effect/Schema"
|
|
2
|
-
import * as SchemaAST from "
|
|
2
|
+
import * as SchemaAST from "./SchemaAST.ts"
|
|
3
3
|
import { type Simplify } from "effect/Struct"
|
|
4
4
|
import type * as Tracer from "effect/Tracer"
|
|
5
5
|
import type { RequiredKeys } from "effect/Types"
|
|
@@ -137,6 +137,19 @@ export * as SchemaParser from "./Schema/SchemaParser.ts"
|
|
|
137
137
|
|
|
138
138
|
export { Void as Void_ } from "effect/Schema"
|
|
139
139
|
|
|
140
|
+
/**
|
|
141
|
+
* Schema for a TypeScript `void` return value — the single canonical `Void`
|
|
142
|
+
* used across the app, including RPC success schemas.
|
|
143
|
+
*
|
|
144
|
+
* Built from our overridden {@link SchemaAST.Void} AST node: accepts **any
|
|
145
|
+
* present value** at runtime and discards it to `undefined`, while keeping the
|
|
146
|
+
* decoded/encoded type as `void` (effect-smol PR #2475). Use {@link Void_}
|
|
147
|
+
* (effect's original) or `S.Undefined` when the input must be exactly
|
|
148
|
+
* `undefined`.
|
|
149
|
+
*/
|
|
150
|
+
export interface Void extends S.Void {}
|
|
151
|
+
export const Void: Void = S.make<S.Void>(new SchemaAST.Void())
|
|
152
|
+
|
|
140
153
|
// ---------------------------------------------------------------------------
|
|
141
154
|
// Struct / NonEmptyArray / Record
|
|
142
155
|
// ---------------------------------------------------------------------------
|
package/src/SchemaAST.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect"
|
|
2
|
+
import type * as Option from "effect/Option"
|
|
3
|
+
import { Void as BaseVoid } from "effect/SchemaAST"
|
|
4
|
+
|
|
5
|
+
export * from "effect/SchemaAST"
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* AST node for a TypeScript `void` return value — overrides effect's
|
|
9
|
+
* `SchemaAST.Void` parser with TypeScript `void` semantics (the effect-smol
|
|
10
|
+
* PR #2475 / `b7d46ab` implementation).
|
|
11
|
+
*
|
|
12
|
+
* Runtime parsing accepts **any present value** and discards it, producing
|
|
13
|
+
* `undefined` — matching a `void` return whose result callers never observe.
|
|
14
|
+
* The decoded/encoded TypeScript representation stays `void`.
|
|
15
|
+
*
|
|
16
|
+
* @see {@link void_} for the singleton instance.
|
|
17
|
+
*/
|
|
18
|
+
export class Void extends BaseVoid {
|
|
19
|
+
/** @internal — mirrors the PR's `fromAnyToConst(undefined)`. */
|
|
20
|
+
getParser() {
|
|
21
|
+
const succeed = Effect.succeedSome(undefined)
|
|
22
|
+
return (oinput: Option.Option<unknown>) => oinput._tag === "None" ? Effect.succeedNone : succeed
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const voidNode: Void = new Void()
|
|
27
|
+
|
|
28
|
+
/** Singleton {@link Void} AST node — overrides effect's `void` singleton. */
|
|
29
|
+
export { voidNode as void }
|
|
@@ -10,6 +10,7 @@ import * as Struct from "effect/Struct"
|
|
|
10
10
|
import { Rpc, RpcClient, RpcGroup, RpcSerialization } from "effect/unstable/rpc"
|
|
11
11
|
import * as Config from "../Config.ts"
|
|
12
12
|
import * as Context from "../Context.ts"
|
|
13
|
+
import * as DataDependencies from "../DataDependencies.ts"
|
|
13
14
|
import * as Effect from "../Effect.ts"
|
|
14
15
|
import { HttpClient, HttpClientRequest } from "../http.ts"
|
|
15
16
|
import { Invalidation } from "../rpc.ts"
|
|
@@ -142,7 +143,12 @@ export const makeRpcGroupFromRequestsAndModuleName = <M extends RequestsAny, con
|
|
|
142
143
|
stream: true as const
|
|
143
144
|
})
|
|
144
145
|
: Invalidation.makeCommandRpc(r._tag, { payload: r, success: r.success, error: r.error })
|
|
145
|
-
: Rpc.make(r._tag, {
|
|
146
|
+
: Rpc.make(r._tag, {
|
|
147
|
+
payload: r,
|
|
148
|
+
success: isStream ? r.success : Invalidation.QueryResponseWithMetaData(r.success),
|
|
149
|
+
error: r.error,
|
|
150
|
+
stream: isStream
|
|
151
|
+
})) as any
|
|
146
152
|
})
|
|
147
153
|
)
|
|
148
154
|
.prefix(`${moduleName}.`)
|
|
@@ -211,6 +217,20 @@ const makeApiClientFactory = Effect
|
|
|
211
217
|
// `InvalidationKeysFromServer` and yield the raw payload / re-fail with the raw
|
|
212
218
|
// error. Middleware-thrown failures arrive raw on the Cause already (no wrap to
|
|
213
219
|
// strip) — the `else` branch passes them through.
|
|
220
|
+
const forwardDependencies = (
|
|
221
|
+
dependencies: DataDependencies.DataDependencySet | undefined,
|
|
222
|
+
options?: { readonly reads?: boolean }
|
|
223
|
+
) =>
|
|
224
|
+
dependencies === undefined
|
|
225
|
+
? Effect.void
|
|
226
|
+
: Effect.gen(function*() {
|
|
227
|
+
const dependencyRecorder = yield* DataDependencies.DataDependencyRecorder
|
|
228
|
+
if (options?.reads) {
|
|
229
|
+
yield* Effect.forEach(dependencies.reads, dependencyRecorder.read, { discard: true })
|
|
230
|
+
}
|
|
231
|
+
yield* Effect.forEach(dependencies.writes, dependencyRecorder.write, { discard: true })
|
|
232
|
+
})
|
|
233
|
+
|
|
214
234
|
const unwrapCommand = (eff: Effect.Effect<any, any, any>): Effect.Effect<any, any, any> =>
|
|
215
235
|
eff.pipe(
|
|
216
236
|
Effect.flatMap((result: any) =>
|
|
@@ -218,6 +238,7 @@ const makeApiClientFactory = Effect
|
|
|
218
238
|
const keys: ReadonlyArray<Invalidation.InvalidationKey> = result?.metadata?.invalidateQueries ?? []
|
|
219
239
|
const invalidationKeys = yield* InvalidationKeysFromServer
|
|
220
240
|
yield* Effect.forEach(keys, (key) => invalidationKeys.add(key), { discard: true })
|
|
241
|
+
yield* forwardDependencies(result?.metadata?.dataDependencies)
|
|
221
242
|
return result.payload
|
|
222
243
|
})
|
|
223
244
|
),
|
|
@@ -227,12 +248,23 @@ const makeApiClientFactory = Effect
|
|
|
227
248
|
const keys: ReadonlyArray<Invalidation.InvalidationKey> = result.metadata?.invalidateQueries ?? []
|
|
228
249
|
const invalidationKeys = yield* InvalidationKeysFromServer
|
|
229
250
|
yield* Effect.forEach(keys, (key) => invalidationKeys.add(key), { discard: true })
|
|
251
|
+
yield* forwardDependencies(result.metadata?.dataDependencies)
|
|
230
252
|
return yield* Effect.fail(result.error)
|
|
231
253
|
})
|
|
232
254
|
: Effect.fail(result)
|
|
233
255
|
)
|
|
234
256
|
)
|
|
235
257
|
|
|
258
|
+
const unwrapQuery = (eff: Effect.Effect<any, any, any>): Effect.Effect<any, any, any> =>
|
|
259
|
+
eff.pipe(
|
|
260
|
+
Effect.flatMap((result: any) =>
|
|
261
|
+
Effect.gen(function*() {
|
|
262
|
+
yield* forwardDependencies(result?.metadata?.dataDependencies, { reads: true })
|
|
263
|
+
return result.payload
|
|
264
|
+
})
|
|
265
|
+
)
|
|
266
|
+
)
|
|
267
|
+
|
|
236
268
|
return {
|
|
237
269
|
mr,
|
|
238
270
|
client: typedKeysOf(filtered)
|
|
@@ -275,7 +307,7 @@ const makeApiClientFactory = Effect
|
|
|
275
307
|
Effect.provide(layers, { local: true }),
|
|
276
308
|
Effect.provide(svcs)
|
|
277
309
|
)
|
|
278
|
-
return isCommand ? unwrapCommand(rpcEffect) : rpcEffect
|
|
310
|
+
return isCommand ? unwrapCommand(rpcEffect) : isStream ? rpcEffect : unwrapQuery(rpcEffect)
|
|
279
311
|
})
|
|
280
312
|
)
|
|
281
313
|
|
|
@@ -292,13 +324,24 @@ const makeApiClientFactory = Effect
|
|
|
292
324
|
// Collect server invalidation keys from the "done" chunk, then discard it.
|
|
293
325
|
Stream.tap((item: any) =>
|
|
294
326
|
item._tag === "done" || item._tag === "metadata"
|
|
295
|
-
?
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
327
|
+
? Effect.gen(function*() {
|
|
328
|
+
const metadata = item.metadata as Invalidation.CommandMetaData
|
|
329
|
+
const invalidationKeys = yield* InvalidationKeysFromServer
|
|
330
|
+
yield* Effect.forEach(metadata.invalidateQueries, invalidationKeys.add, {
|
|
331
|
+
discard: true
|
|
332
|
+
})
|
|
333
|
+
const dependencyRecorder = yield* DataDependencies.DataDependencyRecorder
|
|
334
|
+
yield* Effect.forEach(
|
|
335
|
+
metadata.dataDependencies.reads,
|
|
336
|
+
dependencyRecorder.read,
|
|
299
337
|
{ discard: true }
|
|
300
338
|
)
|
|
301
|
-
|
|
339
|
+
yield* Effect.forEach(
|
|
340
|
+
metadata.dataDependencies.writes,
|
|
341
|
+
dependencyRecorder.write,
|
|
342
|
+
{ discard: true }
|
|
343
|
+
)
|
|
344
|
+
})
|
|
302
345
|
: Effect.void
|
|
303
346
|
),
|
|
304
347
|
Stream.filter((item: any) => item._tag === "value"),
|
|
@@ -309,15 +352,20 @@ const makeApiClientFactory = Effect
|
|
|
309
352
|
Stream.catch((err: any) =>
|
|
310
353
|
err?._tag === "error" && err?.metadata
|
|
311
354
|
? Stream.fromEffect(
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
355
|
+
Effect.gen(function*() {
|
|
356
|
+
const metadata = err.metadata as Invalidation.CommandMetaData
|
|
357
|
+
const invalidationKeys = yield* InvalidationKeysFromServer
|
|
358
|
+
yield* Effect.forEach(metadata.invalidateQueries, invalidationKeys.add, {
|
|
359
|
+
discard: true
|
|
360
|
+
})
|
|
361
|
+
const dependencyRecorder = yield* DataDependencies.DataDependencyRecorder
|
|
362
|
+
yield* Effect.forEach(
|
|
363
|
+
metadata.dataDependencies.writes,
|
|
364
|
+
dependencyRecorder.write,
|
|
365
|
+
{ discard: true }
|
|
366
|
+
)
|
|
367
|
+
return yield* Effect.fail(err.error)
|
|
368
|
+
})
|
|
321
369
|
)
|
|
322
370
|
: Stream.fail(err)
|
|
323
371
|
),
|