@effect-app/vue 4.0.0-beta.176 → 4.0.0-beta.178
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/dist/makeClient.d.ts +11 -3
- package/dist/makeClient.d.ts.map +1 -1
- package/dist/makeClient.js +71 -30
- package/dist/mutate.d.ts +25 -2
- package/dist/mutate.d.ts.map +1 -1
- package/dist/mutate.js +91 -7
- package/examples/streamMutation.ts +83 -0
- package/package.json +2 -2
- package/src/makeClient.ts +87 -4
- package/src/mutate.ts +145 -7
- package/test/dist/stubs.d.ts +868 -118
- package/test/dist/stubs.d.ts.map +1 -1
- package/tsconfig.examples.json +20 -0
- package/tsconfig.json.bak +3 -0
package/dist/mutate.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
import { matchQuery } from "@tanstack/query-core";
|
|
3
3
|
import { useQueryClient } from "@tanstack/vue-query";
|
|
4
|
-
import { Effect, Option } from "effect-app";
|
|
4
|
+
import { Effect, Exit, Option } from "effect-app";
|
|
5
5
|
import { InvalidationKeysFromServer, makeInvalidationKeysService, makeQueryKey } from "effect-app/client";
|
|
6
6
|
import { tuple } from "effect-app/Function";
|
|
7
7
|
import * as Ref from "effect/Ref";
|
|
8
|
+
import * as Stream from "effect/Stream";
|
|
8
9
|
import * as AsyncResult from "effect/unstable/reactivity/AsyncResult";
|
|
9
10
|
import { computed, shallowRef } from "vue";
|
|
10
11
|
export const getQueryKey = (h) => {
|
|
@@ -63,12 +64,44 @@ export const asResult = (handler) => {
|
|
|
63
64
|
.pipe(Effect.andThen(Effect.suspend(() => handler(...args).pipe(Effect.exit, Effect.tap((exit) => Effect.sync(() => (state.value = AsyncResult.fromExit(exit))))))));
|
|
64
65
|
return tuple(computed(() => state.value), act);
|
|
65
66
|
};
|
|
66
|
-
|
|
67
|
-
|
|
67
|
+
/**
|
|
68
|
+
* Like `asResult`, but for streams. The ref is updated with each emitted value
|
|
69
|
+
* (keeping `waiting: true`) and is finalised (with `waiting: false`) once the
|
|
70
|
+
* stream terminates successfully. Errors are surfaced as `AsyncResult.failure`.
|
|
71
|
+
*/
|
|
72
|
+
export const asStreamResult = (handler) => {
|
|
73
|
+
const state = shallowRef(AsyncResult.initial());
|
|
74
|
+
const runStream = (stream) => Effect
|
|
75
|
+
.sync(() => {
|
|
76
|
+
state.value = AsyncResult.initial(true);
|
|
77
|
+
})
|
|
78
|
+
.pipe(Effect.andThen(stream.pipe(Stream.runForEach((value) => Effect.sync(() => {
|
|
79
|
+
state.value = AsyncResult.success(value, { waiting: true });
|
|
80
|
+
})), Effect.exit, Effect.flatMap((exit) => Effect.sync(() => {
|
|
81
|
+
if (exit._tag === "Success") {
|
|
82
|
+
const current = state.value;
|
|
83
|
+
if (AsyncResult.isSuccess(current)) {
|
|
84
|
+
state.value = AsyncResult.success(current.value, { waiting: false });
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
state.value = AsyncResult.initial(false);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
state.value = AsyncResult.failure(exit.cause);
|
|
92
|
+
}
|
|
93
|
+
})))));
|
|
94
|
+
const act = Stream.isStream(handler)
|
|
95
|
+
? runStream(handler)
|
|
96
|
+
: (...args) => runStream(handler(...args));
|
|
97
|
+
return tuple(computed(() => state.value), act);
|
|
98
|
+
};
|
|
99
|
+
const buildInvalidateCache = (queryClient, self, queryInvalidation) => {
|
|
100
|
+
const invalidateQueriesFn = (filters, options) => Effect.currentSpan.pipe(Effect.orElseSucceed(() => null), Effect.flatMap((span) => Effect.promise(() => queryClient.invalidateQueries(filters, { ...options, updateMeta: { span } }))));
|
|
68
101
|
const getClientInvalidationTargets = (input, output) => {
|
|
69
102
|
const queryKey = getQueryKey(self);
|
|
70
|
-
if (
|
|
71
|
-
return
|
|
103
|
+
if (queryInvalidation) {
|
|
104
|
+
return queryInvalidation(queryKey, self.id, input, output).map((_) => ({
|
|
72
105
|
filters: _.filters,
|
|
73
106
|
options: _.options
|
|
74
107
|
}));
|
|
@@ -99,7 +132,7 @@ export const invalidateQueries = (queryClient, self, options) => {
|
|
|
99
132
|
}
|
|
100
133
|
}
|
|
101
134
|
return Effect
|
|
102
|
-
.andThen(Effect.annotateCurrentSpan({ clientTargets, serverKeys }), Effect.forEach(groups.values(), ({ options, refetchType, targets }) =>
|
|
135
|
+
.andThen(Effect.annotateCurrentSpan({ clientTargets, serverKeys }), Effect.forEach(groups.values(), ({ options, refetchType, targets }) => invalidateQueriesFn({
|
|
103
136
|
...(refetchType !== undefined ? { refetchType } : {}),
|
|
104
137
|
predicate: (query) => targets.some((t) => t.filters ? matchQuery(t.filters, query) : true)
|
|
105
138
|
}, options), { discard: true, concurrency: "inherit" }))
|
|
@@ -108,6 +141,10 @@ export const invalidateQueries = (queryClient, self, options) => {
|
|
|
108
141
|
// TODO: should we do this in general on any mutation, regardless of invalidation?
|
|
109
142
|
Effect.sleep(0)), Effect.withSpan("client.query.invalidation", {}, { captureStackTrace: false }));
|
|
110
143
|
});
|
|
144
|
+
return invalidateCache;
|
|
145
|
+
};
|
|
146
|
+
export const invalidateQueries = (queryClient, self, options) => {
|
|
147
|
+
const invalidateCache = buildInvalidateCache(queryClient, self, options?.queryInvalidation);
|
|
111
148
|
const select = options?.select;
|
|
112
149
|
const handle = (eff, input) => Effect.gen(function* () {
|
|
113
150
|
const keysRef = yield* Ref.make([]);
|
|
@@ -148,4 +185,51 @@ export const useMakeMutation = () => {
|
|
|
148
185
|
};
|
|
149
186
|
return useMutation;
|
|
150
187
|
};
|
|
151
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXV0YXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL211dGF0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx1REFBdUQ7QUFDdkQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFBO0FBQ2pELE9BQU8sRUFBeUUsY0FBYyxFQUFFLE1BQU0scUJBQXFCLENBQUE7QUFDM0gsT0FBTyxFQUFjLE1BQU0sRUFBYSxNQUFNLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFDbEUsT0FBTyxFQUF3QiwwQkFBMEIsRUFBRSwyQkFBMkIsRUFBRSxZQUFZLEVBQVksTUFBTSxtQkFBbUIsQ0FBQTtBQUV6SSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0scUJBQXFCLENBQUE7QUFDM0MsT0FBTyxLQUFLLEdBQUcsTUFBTSxZQUFZLENBQUE7QUFDakMsT0FBTyxLQUFLLFdBQVcsTUFBTSx3Q0FBd0MsQ0FBQTtBQUNyRSxPQUFPLEVBQUUsUUFBUSxFQUFvQixVQUFVLEVBQUUsTUFBTSxLQUFLLENBQUE7QUFFNUQsTUFBTSxDQUFDLE1BQU0sV0FBVyxHQUFHLENBQUMsQ0FBNkMsRUFBRSxFQUFFO0lBQzNFLE1BQU0sR0FBRyxHQUFHLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUMzQixNQUFNLEVBQUUsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUE7SUFDL0MsNkZBQTZGO0lBQzdGLG9GQUFvRjtJQUNwRixNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMs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
|
|
188
|
+
/**
|
|
189
|
+
* Like `makeMutation`, but for stream-type request handlers.
|
|
190
|
+
* Returns a `[ref, execute]` tuple where `ref` is a reactive `AsyncResult` updated per
|
|
191
|
+
* stream element. Queries are invalidated once when the stream finishes, regardless of
|
|
192
|
+
* success or failure.
|
|
193
|
+
*
|
|
194
|
+
* Must be called inside a Vue setup context (uses `useQueryClient` internally).
|
|
195
|
+
*/
|
|
196
|
+
export const makeStreamMutation = () => {
|
|
197
|
+
const queryClient = useQueryClient();
|
|
198
|
+
return (self, mergedInvalidation) => {
|
|
199
|
+
const state = shallowRef(AsyncResult.initial());
|
|
200
|
+
const runStream = (stream, input) => {
|
|
201
|
+
const invCache = buildInvalidateCache(queryClient, self, mergedInvalidation);
|
|
202
|
+
return Effect
|
|
203
|
+
.sync(() => {
|
|
204
|
+
state.value = AsyncResult.initial(true);
|
|
205
|
+
})
|
|
206
|
+
.pipe(Effect.andThen(stream.pipe(Stream.runForEach((value) => Effect.sync(() => {
|
|
207
|
+
state.value = AsyncResult.success(value, { waiting: true });
|
|
208
|
+
})), Effect.exit, Effect.tap((exit) => Effect.sync(() => {
|
|
209
|
+
if (exit._tag === "Success") {
|
|
210
|
+
const current = state.value;
|
|
211
|
+
if (AsyncResult.isSuccess(current)) {
|
|
212
|
+
state.value = AsyncResult.success(current.value, { waiting: false });
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
state.value = AsyncResult.initial(false);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
state.value = AsyncResult.failure(exit.cause);
|
|
220
|
+
}
|
|
221
|
+
})), Effect.tap((exit) => {
|
|
222
|
+
const current = state.value;
|
|
223
|
+
const lastValue = AsyncResult.isSuccess(current) ? current.value : undefined;
|
|
224
|
+
const invExit = exit._tag === "Success" ? Exit.succeed(lastValue) : exit;
|
|
225
|
+
return invCache(input, invExit, []);
|
|
226
|
+
}), Effect.asVoid)));
|
|
227
|
+
};
|
|
228
|
+
const handler = self.handler;
|
|
229
|
+
const act = Stream.isStream(handler)
|
|
230
|
+
? runStream(handler)
|
|
231
|
+
: (i) => runStream(handler(i), i);
|
|
232
|
+
return tuple(computed(() => state.value), act);
|
|
233
|
+
};
|
|
234
|
+
};
|
|
235
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXV0YXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL211dGF0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx1REFBdUQ7QUFDdkQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFBO0FBQ2pELE9BQU8sRUFBeUUsY0FBYyxFQUFFLE1BQU0scUJBQXFCLENBQUE7QUFDM0gsT0FBTyxFQUFjLE1BQU0sRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sWUFBWSxDQUFBO0FBQzdELE9BQU8sRUFBd0IsMEJBQTBCLEVBQUUsMkJBQTJCLEVBQUUsWUFBWSxFQUFZLE1BQU0sbUJBQW1CLENBQUE7QUFFekksT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLHFCQUFxQixDQUFBO0FBQzNDLE9BQU8sS0FBSyxHQUFHLE1BQU0sWUFBWSxDQUFBO0FBQ2pDLE9BQU8sS0FBSyxNQUFNLE1BQU0sZUFBZSxDQUFBO0FBQ3ZDLE9BQU8sS0FBSyxXQUFXLE1BQU0sd0NBQXdDLENBQUE7QUFDckUsT0FBTyxFQUFFLFFBQVEsRUFBb0IsVUFBVSxFQUFFLE1BQU0sS0FBSyxDQUFBO0FBRTVELE1BQU0sQ0FBQyxNQUFNLFdBQVcsR0FBRyxDQUFDLENBQTZDLEVBQUUsRUFBRTtJQUMzRSxNQUFNLEdBQUcsR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUE7SUFDM0IsTUFBTSxFQUFFLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO0lBQy9DLDZGQUE2RjtJQUM3RixvRkFBb0Y7SUFDcEYsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxNQUFN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
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example: stream-based mutation for a long-running operation.
|
|
3
|
+
*
|
|
4
|
+
* The server streams a tagged union of progress updates and a final result.
|
|
5
|
+
* The Vue ref is updated for every emitted value; `AsyncResult` stays in the
|
|
6
|
+
* `waiting` state until the stream ends.
|
|
7
|
+
*
|
|
8
|
+
* When using `makeClient` / `clientFor`, stream-type requests are exposed as
|
|
9
|
+
* `mutateStream` on the client object (and as `XxxStream` in `.helpers`).
|
|
10
|
+
* The example below shows both the low-level `asStreamResult` API and how the
|
|
11
|
+
* same functionality appears on the generated client.
|
|
12
|
+
*/
|
|
13
|
+
import { Effect, S, Stream } from "effect-app"
|
|
14
|
+
import { asStreamResult } from "../src/mutate.js"
|
|
15
|
+
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Domain model
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
/** Intermediate progress report, e.g. "5 of 400 items processed". */
|
|
21
|
+
export class OperationProgress extends S.TaggedClass<OperationProgress>()("OperationProgress", {
|
|
22
|
+
completed: S.NonNegativeInt,
|
|
23
|
+
total: S.NonNegativeInt
|
|
24
|
+
}) {}
|
|
25
|
+
|
|
26
|
+
/** The final result produced once the operation is complete. */
|
|
27
|
+
export class ExportComplete extends S.TaggedClass<ExportComplete>()("ExportComplete", {
|
|
28
|
+
fileUrl: S.NonEmptyString
|
|
29
|
+
}) {}
|
|
30
|
+
|
|
31
|
+
/** Tagged union emitted by the stream. */
|
|
32
|
+
export type ExportEvent = OperationProgress | ExportComplete
|
|
33
|
+
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
// Simulated stream (replace with a real RPC / SSE stream in production)
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Produces `total` progress updates followed by a single `ExportComplete`.
|
|
40
|
+
* Each step is separated by a 50 ms delay to simulate real async work.
|
|
41
|
+
*/
|
|
42
|
+
const makeExportStream = (total: S.NonNegativeInt): Stream.Stream<ExportEvent> =>
|
|
43
|
+
Stream.concat(
|
|
44
|
+
Stream.range(1, total).pipe(
|
|
45
|
+
Stream.map((completed) => new OperationProgress({ completed: S.NonNegativeInt(completed), total })),
|
|
46
|
+
Stream.tap(() => Effect.sleep("50 millis"))
|
|
47
|
+
),
|
|
48
|
+
Stream.make(new ExportComplete({ fileUrl: S.NonEmptyString("https://example.com/export.csv") }))
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
// Option A: low-level `asStreamResult` (call inside a `setup()` function)
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
|
|
55
|
+
export const useExportMutation = () => {
|
|
56
|
+
/**
|
|
57
|
+
* `result` - reactive ref, always reflects the latest stream event.
|
|
58
|
+
* `AsyncResult` tag:
|
|
59
|
+
* - Initial (waiting=true) - operation in progress
|
|
60
|
+
* - Success (waiting=true) - progress update received, still running
|
|
61
|
+
* - Success (waiting=false) - final result, operation complete
|
|
62
|
+
* - Failure - operation failed
|
|
63
|
+
*
|
|
64
|
+
* `execute` - call with the desired `total` to kick off the stream.
|
|
65
|
+
*/
|
|
66
|
+
const [result, execute] = asStreamResult((total: S.NonNegativeInt) => makeExportStream(total))
|
|
67
|
+
|
|
68
|
+
return { result, execute }
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
// Option B: via `makeClient` / `clientFor` (stream requests -> `mutateStream`)
|
|
73
|
+
//
|
|
74
|
+
// When a request schema has `type: "stream"`, `clientFor` exposes:
|
|
75
|
+
//
|
|
76
|
+
// client.exportData.mutateStream
|
|
77
|
+
// // -> [ComputedRef<AsyncResult<ExportEvent, E>>, (input: I) => Effect<void, never, R>]
|
|
78
|
+
//
|
|
79
|
+
// which is equivalent to calling `asStreamResult(client.exportData.handler)`.
|
|
80
|
+
//
|
|
81
|
+
// The `.helpers` object also includes `exportDataStream` (the camelCase key
|
|
82
|
+
// plus "Stream" suffix) with the same [ref, execute] tuple.
|
|
83
|
+
// ---------------------------------------------------------------------------
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effect-app/vue",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.178",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"homepage": "https://github.com/effect-ts-app/libs/tree/main/packages/vue",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"@vueuse/core": "^14.2.1",
|
|
12
12
|
"change-case": "^5.4.4",
|
|
13
13
|
"query-string": "^9.3.1",
|
|
14
|
-
"effect-app": "4.0.0-beta.
|
|
14
|
+
"effect-app": "4.0.0-beta.178"
|
|
15
15
|
},
|
|
16
16
|
"peerDependencies": {
|
|
17
17
|
"@effect/atom-vue": "^4.0.0-beta.59",
|
package/src/makeClient.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { type InvalidateOptions, type InvalidateQueryFilters, isCancelledError,
|
|
|
3
3
|
import { camelCase } from "change-case"
|
|
4
4
|
import { type Context, Effect, Exit, Hash, type Layer, type ManagedRuntime, S, Struct } from "effect-app"
|
|
5
5
|
import { type ApiClientFactory, type Req } from "effect-app/client"
|
|
6
|
-
import type { ExtractModuleName, RequestHandler, RequestHandlers, RequestHandlerWithInput, RequestInputFromMake, RequestsAny } from "effect-app/client/clientFor"
|
|
6
|
+
import type { ExtractModuleName, RequestHandler, RequestHandlers, RequestHandlerWithInput, RequestInputFromMake, RequestsAny, RequestStreamHandler, RequestStreamHandlerWithInput } from "effect-app/client/clientFor"
|
|
7
7
|
import type { InvalidationCallback } from "effect-app/client/makeClient"
|
|
8
8
|
import type * as ExitResult from "effect/Exit"
|
|
9
9
|
import { type Fiber } from "effect/Fiber"
|
|
@@ -12,7 +12,7 @@ import { type ComputedRef, onBeforeUnmount, ref, type WatchSource } from "vue"
|
|
|
12
12
|
import { type Commander, CommanderStatic } from "./commander.js"
|
|
13
13
|
import { type I18n } from "./intl.js"
|
|
14
14
|
import { type CommanderResolved, makeUseCommand } from "./makeUseCommand.js"
|
|
15
|
-
import { makeMutation, type MutationOptionsBase, useMakeMutation } from "./mutate.js"
|
|
15
|
+
import { makeMutation, makeStreamMutation, type MutationOptionsBase, useMakeMutation } from "./mutate.js"
|
|
16
16
|
import { type CustomUndefinedInitialQueryOptions, makeQuery } from "./query.js"
|
|
17
17
|
import { makeRunPromise } from "./runtime.js"
|
|
18
18
|
import { type Toast } from "./toast.js"
|
|
@@ -125,6 +125,13 @@ type CommandHandler<Req> = Req extends
|
|
|
125
125
|
? Request["type"] extends "command" ? RequestHandler<A, E, R, Request, Id> : never
|
|
126
126
|
: never
|
|
127
127
|
|
|
128
|
+
type StreamHandler<Req> = Req extends
|
|
129
|
+
RequestStreamHandlerWithInput<infer I, infer A, infer E, infer R, infer Request, infer Id>
|
|
130
|
+
? Request["type"] extends "stream" ? RequestStreamHandlerWithInput<I, A, E, R, Request, Id> : never
|
|
131
|
+
: Req extends RequestStreamHandler<infer A, infer E, infer R, infer Request, infer Id>
|
|
132
|
+
? Request["type"] extends "stream" ? RequestStreamHandler<A, E, R, Request, Id> : never
|
|
133
|
+
: never
|
|
134
|
+
|
|
128
135
|
export interface MutationExtensions<RT, Id extends string, I, A, E, R> {
|
|
129
136
|
/** Defines a Command based on this mutation, taking the `id` of the mutation as the `id` of the Command.
|
|
130
137
|
* The Mutation function will be taken as the first member of the Command, the Command required input will be the Mutation input.
|
|
@@ -217,6 +224,17 @@ export type MutationWithExtensions<RT, Req> = Req extends
|
|
|
217
224
|
? MutationExt<RT, Id, A, E, R, S.Codec.Encoded<Request["success"]>>
|
|
218
225
|
: never
|
|
219
226
|
|
|
227
|
+
/**
|
|
228
|
+
* The `mutateStream` tuple for a stream-type request handler:
|
|
229
|
+
* `[resultRef, execute]` where `execute` updates the ref live with each emitted value.
|
|
230
|
+
*/
|
|
231
|
+
export type StreamMutationWithExtensions<Req> = Req extends
|
|
232
|
+
RequestStreamHandlerWithInput<infer I, infer A, infer E, infer R, infer _Request, infer _Id>
|
|
233
|
+
? readonly [ComputedRef<AsyncResult.AsyncResult<A, E>>, (input: I) => Effect.Effect<void, never, R>]
|
|
234
|
+
: Req extends RequestStreamHandler<infer A, infer E, infer R, infer _Request, infer _Id>
|
|
235
|
+
? readonly [ComputedRef<AsyncResult.AsyncResult<A, E>>, Effect.Effect<void, never, R>]
|
|
236
|
+
: never
|
|
237
|
+
|
|
220
238
|
// we don't really care about the RT, as we are in charge of ensuring runtime safety anyway
|
|
221
239
|
// eslint-disable-next-line unused-imports/no-unused-vars
|
|
222
240
|
declare const useQuery_: QueryImpl<any>["useQuery"]
|
|
@@ -571,6 +589,9 @@ export const makeClient = <RT_, RTHooks>(
|
|
|
571
589
|
let m: ReturnType<typeof useMutationInt>
|
|
572
590
|
const useMutation = () => m ??= useMutationInt()
|
|
573
591
|
|
|
592
|
+
let sm: ReturnType<typeof makeStreamMutation>
|
|
593
|
+
const useStreamMutation = () => sm ??= makeStreamMutation()
|
|
594
|
+
|
|
574
595
|
const query = new QueryImpl(getBaseRt)
|
|
575
596
|
const useQuery = query.useQuery
|
|
576
597
|
const useSuspenseQuery = query.useSuspenseQuery
|
|
@@ -697,7 +718,7 @@ export const makeClient = <RT_, RTHooks>(
|
|
|
697
718
|
if (client[key].Request.type !== "command") {
|
|
698
719
|
return acc
|
|
699
720
|
}
|
|
700
|
-
const fromRequestConfig = client[key].Request.config?.invalidatesQueries as
|
|
721
|
+
const fromRequestConfig = client[key].Request.config?.["invalidatesQueries"] as
|
|
701
722
|
| InvalidationCallback<InvalidationResourcesFor<M>>
|
|
702
723
|
| undefined
|
|
703
724
|
const fromRequest = fromRequestConfig
|
|
@@ -739,6 +760,43 @@ export const makeClient = <RT_, RTHooks>(
|
|
|
739
760
|
return mutations
|
|
740
761
|
}
|
|
741
762
|
|
|
763
|
+
const mapStreamMutation = <M extends RequestsAny>(
|
|
764
|
+
client: ClientFrom<M>,
|
|
765
|
+
queryInvalidation?: (client: ClientFrom<M>) => QueryInvalidation<M>,
|
|
766
|
+
invalidationResources?: InvalidationResourcesFor<M>
|
|
767
|
+
) => {
|
|
768
|
+
const streamMutation = useStreamMutation()
|
|
769
|
+
const invalidation = queryInvalidation?.(client)
|
|
770
|
+
const queryResources = makeQueryResources(invalidationResources)
|
|
771
|
+
const streams = Struct.keys(client).reduce(
|
|
772
|
+
(acc, key) => {
|
|
773
|
+
if (client[key].Request.type !== "stream") {
|
|
774
|
+
return acc
|
|
775
|
+
}
|
|
776
|
+
const fromRequestConfig = client[key].Request.config?.["invalidatesQueries"] as
|
|
777
|
+
| InvalidationCallback<InvalidationResourcesFor<M>>
|
|
778
|
+
| undefined
|
|
779
|
+
const fromRequest = fromRequestConfig
|
|
780
|
+
? ((defaultKey: string[], _name: string, input?: unknown, output?: unknown) =>
|
|
781
|
+
fromRequestConfig(defaultKey, queryResources as never, input as never, output as never).map((entry) => ({
|
|
782
|
+
filters: entry.filters,
|
|
783
|
+
options: entry.options
|
|
784
|
+
})))
|
|
785
|
+
: undefined
|
|
786
|
+
const mergedInvalidation = mergeInvalidation(fromRequest, invalidation?.[key])
|
|
787
|
+
;(acc as any)[camelCase(key) + "Stream"] = streamMutation(client[key] as any, mergedInvalidation)
|
|
788
|
+
return acc
|
|
789
|
+
},
|
|
790
|
+
{} as {
|
|
791
|
+
[
|
|
792
|
+
Key in keyof typeof client as StreamHandler<typeof client[Key]> extends never ? never
|
|
793
|
+
: `${ToCamel<string & Key>}Stream`
|
|
794
|
+
]: StreamMutationWithExtensions<StreamHandler<typeof client[Key]>>
|
|
795
|
+
}
|
|
796
|
+
)
|
|
797
|
+
return streams
|
|
798
|
+
}
|
|
799
|
+
|
|
742
800
|
// make available .query, .suspense and .mutate for each operation
|
|
743
801
|
// and a .helpers with all mutations and queries
|
|
744
802
|
const mapClient = <M extends RequestsAny>(
|
|
@@ -750,6 +808,7 @@ export const makeClient = <RT_, RTHooks>(
|
|
|
750
808
|
) => {
|
|
751
809
|
const Command = useCommand()
|
|
752
810
|
const mutation = useMutation()
|
|
811
|
+
const streamMutation = useStreamMutation()
|
|
753
812
|
const invalidation = queryInvalidation?.(client)
|
|
754
813
|
const queryResources = makeQueryResources(invalidationResources)
|
|
755
814
|
const extended = Struct.keys(client).reduce(
|
|
@@ -786,9 +845,30 @@ export const makeClient = <RT_, RTHooks>(
|
|
|
786
845
|
}
|
|
787
846
|
}
|
|
788
847
|
}
|
|
848
|
+
: requestType === "stream"
|
|
849
|
+
? (() => {
|
|
850
|
+
const fromRequestConfig = client[key].Request.config?.["invalidatesQueries"] as
|
|
851
|
+
| InvalidationCallback<InvalidationResourcesFor<M>>
|
|
852
|
+
| undefined
|
|
853
|
+
const fromRequest = fromRequestConfig
|
|
854
|
+
? ((defaultKey: string[], _name: string, input?: unknown, output?: unknown) =>
|
|
855
|
+
fromRequestConfig(defaultKey, queryResources as never, input as never, output as never).map((
|
|
856
|
+
entry
|
|
857
|
+
) => ({
|
|
858
|
+
filters: entry.filters,
|
|
859
|
+
options: entry.options
|
|
860
|
+
})))
|
|
861
|
+
: undefined
|
|
862
|
+
const mergedInvalidation = mergeInvalidation(fromRequest, invalidation?.[key])
|
|
863
|
+
return {
|
|
864
|
+
...client[key],
|
|
865
|
+
request: h_,
|
|
866
|
+
mutateStream: streamMutation(client[key] as any, mergedInvalidation)
|
|
867
|
+
}
|
|
868
|
+
})()
|
|
789
869
|
: {
|
|
790
870
|
mutate: ((handler: any) => {
|
|
791
|
-
const fromRequestConfig = client[key].Request.config?.invalidatesQueries as
|
|
871
|
+
const fromRequestConfig = client[key].Request.config?.["invalidatesQueries"] as
|
|
792
872
|
| InvalidationCallback<InvalidationResourcesFor<M>>
|
|
793
873
|
| undefined
|
|
794
874
|
const fromRequest = fromRequestConfig
|
|
@@ -844,6 +924,8 @@ export const makeClient = <RT_, RTHooks>(
|
|
|
844
924
|
: CommandRequestWithExtensions<RT | RTHooks, CommandHandler<typeof client[Key]>>)
|
|
845
925
|
& (CommandHandler<typeof client[Key]> extends never ? {}
|
|
846
926
|
: { mutate: MutationWithExtensions<RT | RTHooks, CommandHandler<typeof client[Key]>> })
|
|
927
|
+
& (StreamHandler<typeof client[Key]> extends never ? {}
|
|
928
|
+
: { mutateStream: StreamMutationWithExtensions<StreamHandler<typeof client[Key]>> })
|
|
847
929
|
& { Input: typeof client[Key] extends RequestHandlerWithInput<infer I, any, any, any, any, any> ? I : never }
|
|
848
930
|
}
|
|
849
931
|
)
|
|
@@ -851,6 +933,7 @@ export const makeClient = <RT_, RTHooks>(
|
|
|
851
933
|
helpers: {
|
|
852
934
|
...mapRequest(client),
|
|
853
935
|
...mapMutation(client, queryInvalidation, invalidationResources),
|
|
936
|
+
...mapStreamMutation(client, queryInvalidation, invalidationResources),
|
|
854
937
|
...mapQuery(client)
|
|
855
938
|
}
|
|
856
939
|
})
|
package/src/mutate.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
import { matchQuery } from "@tanstack/query-core"
|
|
3
3
|
import { type InvalidateOptions, type InvalidateQueryFilters, type QueryClient, useQueryClient } from "@tanstack/vue-query"
|
|
4
|
-
import { type Cause, Effect,
|
|
4
|
+
import { type Cause, Effect, Exit, Option } from "effect-app"
|
|
5
5
|
import { type InvalidationKey, InvalidationKeysFromServer, makeInvalidationKeysService, makeQueryKey, type Req } from "effect-app/client"
|
|
6
6
|
import type { ClientForOptions, RequestHandler, RequestHandlerWithInput } from "effect-app/client/clientFor"
|
|
7
7
|
import { tuple } from "effect-app/Function"
|
|
8
8
|
import * as Ref from "effect/Ref"
|
|
9
|
+
import * as Stream from "effect/Stream"
|
|
9
10
|
import * as AsyncResult from "effect/unstable/reactivity/AsyncResult"
|
|
10
11
|
import { computed, type ComputedRef, shallowRef } from "vue"
|
|
11
12
|
|
|
@@ -137,17 +138,73 @@ export const asResult: {
|
|
|
137
138
|
return tuple(computed(() => state.value), act) as any
|
|
138
139
|
}
|
|
139
140
|
|
|
140
|
-
|
|
141
|
+
/**
|
|
142
|
+
* Like `asResult`, but for streams. The ref is updated with each emitted value
|
|
143
|
+
* (keeping `waiting: true`) and is finalised (with `waiting: false`) once the
|
|
144
|
+
* stream terminates successfully. Errors are surfaced as `AsyncResult.failure`.
|
|
145
|
+
*/
|
|
146
|
+
export const asStreamResult: {
|
|
147
|
+
<A, E, R>(
|
|
148
|
+
handler: Stream.Stream<A, E, R>
|
|
149
|
+
): readonly [ComputedRef<AsyncResult.AsyncResult<A, E>>, Effect.Effect<void, never, R>]
|
|
150
|
+
<Args extends readonly any[], A, E, R>(
|
|
151
|
+
handler: (...args: Args) => Stream.Stream<A, E, R>
|
|
152
|
+
): readonly [ComputedRef<AsyncResult.AsyncResult<A, E>>, (...args: Args) => Effect.Effect<void, never, R>]
|
|
153
|
+
} = <Args extends readonly any[], A, E, R>(
|
|
154
|
+
handler: Stream.Stream<A, E, R> | ((...args: Args) => Stream.Stream<A, E, R>)
|
|
155
|
+
) => {
|
|
156
|
+
const state = shallowRef<AsyncResult.AsyncResult<A, E>>(AsyncResult.initial())
|
|
157
|
+
|
|
158
|
+
const runStream = (stream: Stream.Stream<A, E, R>): Effect.Effect<void, never, R> =>
|
|
159
|
+
Effect
|
|
160
|
+
.sync(() => {
|
|
161
|
+
state.value = AsyncResult.initial(true)
|
|
162
|
+
})
|
|
163
|
+
.pipe(
|
|
164
|
+
Effect.andThen(
|
|
165
|
+
stream.pipe(
|
|
166
|
+
Stream.runForEach((value) =>
|
|
167
|
+
Effect.sync(() => {
|
|
168
|
+
state.value = AsyncResult.success(value, { waiting: true })
|
|
169
|
+
})
|
|
170
|
+
),
|
|
171
|
+
Effect.exit,
|
|
172
|
+
Effect.flatMap((exit) =>
|
|
173
|
+
Effect.sync(() => {
|
|
174
|
+
if (exit._tag === "Success") {
|
|
175
|
+
const current = state.value
|
|
176
|
+
if (AsyncResult.isSuccess(current)) {
|
|
177
|
+
state.value = AsyncResult.success(current.value, { waiting: false })
|
|
178
|
+
} else {
|
|
179
|
+
state.value = AsyncResult.initial(false)
|
|
180
|
+
}
|
|
181
|
+
} else {
|
|
182
|
+
state.value = AsyncResult.failure(exit.cause)
|
|
183
|
+
}
|
|
184
|
+
})
|
|
185
|
+
)
|
|
186
|
+
)
|
|
187
|
+
)
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
const act = Stream.isStream(handler)
|
|
191
|
+
? runStream(handler)
|
|
192
|
+
: (...args: Args) => runStream(handler(...args))
|
|
193
|
+
|
|
194
|
+
return tuple(computed(() => state.value), act) as any
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const buildInvalidateCache = (
|
|
141
198
|
queryClient: QueryClient,
|
|
142
199
|
self: { id: string; options?: ClientForOptions },
|
|
143
|
-
|
|
200
|
+
queryInvalidation?: MutationOptionsBase["queryInvalidation"]
|
|
144
201
|
) => {
|
|
145
202
|
type InvalidationTarget = {
|
|
146
203
|
readonly filters: InvalidateQueryFilters | undefined
|
|
147
204
|
readonly options: InvalidateOptions | undefined
|
|
148
205
|
}
|
|
149
206
|
|
|
150
|
-
const
|
|
207
|
+
const invalidateQueriesFn = (
|
|
151
208
|
filters?: InvalidateQueryFilters,
|
|
152
209
|
options?: InvalidateOptions
|
|
153
210
|
) =>
|
|
@@ -164,8 +221,8 @@ export const invalidateQueries = (
|
|
|
164
221
|
): ReadonlyArray<InvalidationTarget> => {
|
|
165
222
|
const queryKey = getQueryKey(self)
|
|
166
223
|
|
|
167
|
-
if (
|
|
168
|
-
return
|
|
224
|
+
if (queryInvalidation) {
|
|
225
|
+
return queryInvalidation(queryKey, self.id, input, output).map((_) => ({
|
|
169
226
|
filters: _.filters,
|
|
170
227
|
options: _.options
|
|
171
228
|
}))
|
|
@@ -219,7 +276,7 @@ export const invalidateQueries = (
|
|
|
219
276
|
Effect.forEach(
|
|
220
277
|
groups.values(),
|
|
221
278
|
({ options, refetchType, targets }) =>
|
|
222
|
-
|
|
279
|
+
invalidateQueriesFn(
|
|
223
280
|
{
|
|
224
281
|
...(refetchType !== undefined ? { refetchType } : {}),
|
|
225
282
|
predicate: (query) => targets.some((t) => t.filters ? matchQuery(t.filters, query) : true)
|
|
@@ -239,6 +296,16 @@ export const invalidateQueries = (
|
|
|
239
296
|
)
|
|
240
297
|
})
|
|
241
298
|
|
|
299
|
+
return invalidateCache
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
export const invalidateQueries = (
|
|
303
|
+
queryClient: QueryClient,
|
|
304
|
+
self: { id: string; options?: ClientForOptions },
|
|
305
|
+
options?: MutationOptionsBase
|
|
306
|
+
) => {
|
|
307
|
+
const invalidateCache = buildInvalidateCache(queryClient, self, options?.queryInvalidation)
|
|
308
|
+
|
|
242
309
|
const select = options?.select
|
|
243
310
|
|
|
244
311
|
const handle = <A, E, R>(eff: Effect.Effect<A, E, R>, input?: unknown) =>
|
|
@@ -345,3 +412,74 @@ export const useMakeMutation = () => {
|
|
|
345
412
|
}
|
|
346
413
|
return useMutation
|
|
347
414
|
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Like `makeMutation`, but for stream-type request handlers.
|
|
418
|
+
* Returns a `[ref, execute]` tuple where `ref` is a reactive `AsyncResult` updated per
|
|
419
|
+
* stream element. Queries are invalidated once when the stream finishes, regardless of
|
|
420
|
+
* success or failure.
|
|
421
|
+
*
|
|
422
|
+
* Must be called inside a Vue setup context (uses `useQueryClient` internally).
|
|
423
|
+
*/
|
|
424
|
+
export const makeStreamMutation = () => {
|
|
425
|
+
const queryClient = useQueryClient()
|
|
426
|
+
|
|
427
|
+
return (
|
|
428
|
+
self: {
|
|
429
|
+
id: string
|
|
430
|
+
options?: ClientForOptions
|
|
431
|
+
handler: Stream.Stream<any, any, any> | ((i: any) => Stream.Stream<any, any, any>)
|
|
432
|
+
},
|
|
433
|
+
mergedInvalidation?: MutationOptionsBase["queryInvalidation"]
|
|
434
|
+
) => {
|
|
435
|
+
const state = shallowRef<AsyncResult.AsyncResult<any, any>>(AsyncResult.initial())
|
|
436
|
+
|
|
437
|
+
const runStream = (stream: Stream.Stream<any, any, any>, input?: unknown): Effect.Effect<void, never, any> => {
|
|
438
|
+
const invCache = buildInvalidateCache(queryClient, self, mergedInvalidation)
|
|
439
|
+
return Effect
|
|
440
|
+
.sync(() => {
|
|
441
|
+
state.value = AsyncResult.initial(true)
|
|
442
|
+
})
|
|
443
|
+
.pipe(
|
|
444
|
+
Effect.andThen(
|
|
445
|
+
stream.pipe(
|
|
446
|
+
Stream.runForEach((value) =>
|
|
447
|
+
Effect.sync(() => {
|
|
448
|
+
state.value = AsyncResult.success(value, { waiting: true })
|
|
449
|
+
})
|
|
450
|
+
),
|
|
451
|
+
Effect.exit,
|
|
452
|
+
Effect.tap((exit) =>
|
|
453
|
+
Effect.sync(() => {
|
|
454
|
+
if (exit._tag === "Success") {
|
|
455
|
+
const current = state.value
|
|
456
|
+
if (AsyncResult.isSuccess(current)) {
|
|
457
|
+
state.value = AsyncResult.success(current.value, { waiting: false })
|
|
458
|
+
} else {
|
|
459
|
+
state.value = AsyncResult.initial(false)
|
|
460
|
+
}
|
|
461
|
+
} else {
|
|
462
|
+
state.value = AsyncResult.failure(exit.cause)
|
|
463
|
+
}
|
|
464
|
+
})
|
|
465
|
+
),
|
|
466
|
+
Effect.tap((exit) => {
|
|
467
|
+
const current = state.value
|
|
468
|
+
const lastValue = AsyncResult.isSuccess(current) ? current.value : undefined
|
|
469
|
+
const invExit = exit._tag === "Success" ? Exit.succeed(lastValue) : exit
|
|
470
|
+
return invCache(input, invExit, [])
|
|
471
|
+
}),
|
|
472
|
+
Effect.asVoid
|
|
473
|
+
)
|
|
474
|
+
)
|
|
475
|
+
)
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
const handler = self.handler
|
|
479
|
+
const act = Stream.isStream(handler)
|
|
480
|
+
? runStream(handler)
|
|
481
|
+
: (i: any) => runStream((handler as (i: any) => Stream.Stream<any, any, any>)(i), i)
|
|
482
|
+
|
|
483
|
+
return tuple(computed(() => state.value), act)
|
|
484
|
+
}
|
|
485
|
+
}
|