@confect/foldkit 10.0.0-next.19
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 +61 -0
- package/LICENSE +7 -0
- package/README.md +11 -0
- package/dist/Client.d.ts +69 -0
- package/dist/Client.d.ts.map +1 -0
- package/dist/Client.js +44 -0
- package/dist/Client.js.map +1 -0
- package/dist/Command.d.ts +158 -0
- package/dist/Command.d.ts.map +1 -0
- package/dist/Command.js +111 -0
- package/dist/Command.js.map +1 -0
- package/dist/PaginatedQuery.d.ts +227 -0
- package/dist/PaginatedQuery.d.ts.map +1 -0
- package/dist/PaginatedQuery.js +351 -0
- package/dist/PaginatedQuery.js.map +1 -0
- package/dist/Subscription.d.ts +132 -0
- package/dist/Subscription.d.ts.map +1 -0
- package/dist/Subscription.js +119 -0
- package/dist/Subscription.js.map +1 -0
- package/dist/WebSocketClient.d.ts +16 -0
- package/dist/WebSocketClient.d.ts.map +1 -0
- package/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/package.json +71 -0
- package/src/Client.ts +53 -0
- package/src/Command.ts +452 -0
- package/src/PaginatedQuery.ts +1001 -0
- package/src/Subscription.ts +338 -0
- package/src/index.ts +4 -0
package/src/Command.ts
ADDED
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
import type * as Ref from "@confect/core/Ref";
|
|
2
|
+
import * as Effect from "effect/Effect";
|
|
3
|
+
import * as Match from "effect/Match";
|
|
4
|
+
import type * as Schema from "effect/Schema";
|
|
5
|
+
import * as FoldkitCommand from "foldkit/command";
|
|
6
|
+
import * as Client from "./Client";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Everything a Command against `Ref_` can fail with before it is folded into
|
|
10
|
+
* an `onError` Message: the ref's typed error (if it declares an `error`
|
|
11
|
+
* schema), a transport-level `WebSocketClientError`, or a `SchemaError` from
|
|
12
|
+
* encoding args or decoding returns.
|
|
13
|
+
*/
|
|
14
|
+
export type Error<Ref_ extends Ref.AnyConfect> =
|
|
15
|
+
| Ref.Error<Ref_>
|
|
16
|
+
| Client.WebSocketClientError
|
|
17
|
+
| Schema.SchemaError;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Maps a Confect function's outcome into the app's Messages. Every failure —
|
|
21
|
+
* the ref's typed error, a transport error, or a codec error — arrives via
|
|
22
|
+
* `onError`, so the resulting Command's error channel is `never`, as Foldkit
|
|
23
|
+
* requires. Follow Foldkit's naming convention: past-tense facts like
|
|
24
|
+
* `SucceededSaveNote` / `FailedSaveNote`.
|
|
25
|
+
*/
|
|
26
|
+
export interface Handlers<
|
|
27
|
+
Ref_ extends Ref.AnyConfect,
|
|
28
|
+
SuccessMessage,
|
|
29
|
+
ErrorMessage,
|
|
30
|
+
> {
|
|
31
|
+
readonly onSuccess: (returns: Ref.Returns<Ref_>) => SuccessMessage;
|
|
32
|
+
readonly onError: (error: Error<Ref_>) => ErrorMessage;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The Command instance a definition call constructs.
|
|
37
|
+
*/
|
|
38
|
+
type Instance<
|
|
39
|
+
Name extends string,
|
|
40
|
+
Ref_ extends Ref.AnyConfect,
|
|
41
|
+
Message,
|
|
42
|
+
> = Readonly<{
|
|
43
|
+
name: Name;
|
|
44
|
+
args: Ref.Args<Ref_>;
|
|
45
|
+
effect: Effect.Effect<Message, never, Client.Client>;
|
|
46
|
+
}>;
|
|
47
|
+
|
|
48
|
+
type SchemaArgs<Ref_ extends Ref.AnyConfect> = Schema.Schema.Type<
|
|
49
|
+
Schema.Struct<Ref.ArgsSchema<Ref_>["fields"]>
|
|
50
|
+
>;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* A Foldkit Command definition whose args are the ref's args: our
|
|
54
|
+
* ref-derived call signature (args optional when the ref declares none)
|
|
55
|
+
* intersected with Foldkit's own `CommandDefinitionWithArgs`, which supplies
|
|
56
|
+
* the `CommandDefinitionTypeId` brand and makes the definition assignable
|
|
57
|
+
* wherever Foldkit accepts one — including Story/Scene `Command.resolve`
|
|
58
|
+
* and `expectExact` matchers. Call it from `update` to construct a Command
|
|
59
|
+
* instance; nothing runs until the Foldkit runtime executes it.
|
|
60
|
+
*/
|
|
61
|
+
export type Definition<
|
|
62
|
+
Name extends string,
|
|
63
|
+
Ref_ extends Ref.AnyConfect,
|
|
64
|
+
Message,
|
|
65
|
+
> = ((...args: Ref.OptionalArgs<Ref_>) => Instance<Name, Ref_, Message>) &
|
|
66
|
+
FoldkitCommand.CommandDefinitionWithArgs<
|
|
67
|
+
Name,
|
|
68
|
+
Ref.ArgsSchema<Ref_>["fields"],
|
|
69
|
+
Effect.Effect<Message, never, Client.Client>
|
|
70
|
+
>;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Makes a factory-built Command interruptible — Foldkit's `InterruptOption`
|
|
74
|
+
* applied to the ref's args. `true` keys every invocation by the Command
|
|
75
|
+
* name — right when at most one invocation is meaningfully in flight; a
|
|
76
|
+
* `KeyedInterrupt` derives the key part from the ref's args, so concurrent
|
|
77
|
+
* invocations can be targeted independently.
|
|
78
|
+
*
|
|
79
|
+
* Interrupting stops the client-side Effect and guarantees the invocation's
|
|
80
|
+
* result Messages never dispatch — it does not cancel the Convex function on
|
|
81
|
+
* the server, which runs to completion once the call is on the wire.
|
|
82
|
+
*/
|
|
83
|
+
export type InterruptOption<
|
|
84
|
+
Ref_ extends Ref.AnyConfect,
|
|
85
|
+
KeyField extends keyof SchemaArgs<Ref_> & string = keyof SchemaArgs<Ref_> &
|
|
86
|
+
string,
|
|
87
|
+
> = FoldkitCommand.InterruptOption<SchemaArgs<Ref_>, KeyField>;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* The keyed arm of `InterruptOption`: `keyFields` declares the args the
|
|
91
|
+
* `Interrupt` constructor requires; `toKey` derives the key part from them.
|
|
92
|
+
*/
|
|
93
|
+
export type KeyedInterrupt<
|
|
94
|
+
Ref_ extends Ref.AnyConfect,
|
|
95
|
+
KeyField extends keyof SchemaArgs<Ref_> & string,
|
|
96
|
+
> = Exclude<InterruptOption<Ref_, KeyField>, true>;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* An interruptible Command definition whose key is the Command name — the
|
|
100
|
+
* ref-derived call signature intersected with Foldkit's
|
|
101
|
+
* `Interruptible.DefinitionWithArgsNameKeyed`, which supplies the brand and
|
|
102
|
+
* the `Interrupt` constructor.
|
|
103
|
+
*/
|
|
104
|
+
export type InterruptibleDefinition<
|
|
105
|
+
Name extends string,
|
|
106
|
+
Ref_ extends Ref.AnyConfect,
|
|
107
|
+
Message,
|
|
108
|
+
> = ((
|
|
109
|
+
...args: Ref.OptionalArgs<Ref_>
|
|
110
|
+
) => Instance<Name, Ref_, Message> & Readonly<{ key: string }>) &
|
|
111
|
+
FoldkitCommand.Interruptible.DefinitionWithArgsNameKeyed<
|
|
112
|
+
Name,
|
|
113
|
+
Ref.ArgsSchema<Ref_>["fields"],
|
|
114
|
+
Effect.Effect<Message, never, Client.Client>
|
|
115
|
+
>;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* An interruptible Command definition whose key is derived from the ref's
|
|
119
|
+
* args — the ref-derived call signature intersected with Foldkit's
|
|
120
|
+
* `Interruptible.DefinitionWithArgs`, which supplies the brand and the
|
|
121
|
+
* key-args-taking `Interrupt` constructor.
|
|
122
|
+
*/
|
|
123
|
+
export type KeyedInterruptibleDefinition<
|
|
124
|
+
Name extends string,
|
|
125
|
+
Ref_ extends Ref.AnyConfect,
|
|
126
|
+
KeyField extends keyof SchemaArgs<Ref_> & string,
|
|
127
|
+
Message,
|
|
128
|
+
> = ((
|
|
129
|
+
...args: Ref.OptionalArgs<Ref_>
|
|
130
|
+
) => Instance<Name, Ref_, Message> & Readonly<{ key: string }>) &
|
|
131
|
+
FoldkitCommand.Interruptible.DefinitionWithArgs<
|
|
132
|
+
Name,
|
|
133
|
+
Ref.ArgsSchema<Ref_>["fields"],
|
|
134
|
+
Pick<SchemaArgs<Ref_>, KeyField>,
|
|
135
|
+
Effect.Effect<Message, never, Client.Client>
|
|
136
|
+
>;
|
|
137
|
+
|
|
138
|
+
const run = <Ref_ extends Ref.AnyConfect, SuccessMessage, ErrorMessage>(
|
|
139
|
+
handlers: Handlers<Ref_, SuccessMessage, ErrorMessage>,
|
|
140
|
+
invoke: (
|
|
141
|
+
client: Client.Client,
|
|
142
|
+
) => Effect.Effect<Ref.Returns<Ref_>, Error<Ref_>>,
|
|
143
|
+
): Effect.Effect<SuccessMessage | ErrorMessage, never, Client.Client> =>
|
|
144
|
+
Effect.flatMap(Client.Client, invoke).pipe(
|
|
145
|
+
Effect.match({
|
|
146
|
+
onSuccess: handlers.onSuccess,
|
|
147
|
+
onFailure: handlers.onError,
|
|
148
|
+
}),
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* An execute body for a hand-written `Command.define` — every failure already
|
|
153
|
+
* folded into a Message. Reach for these when the factory below doesn't fit:
|
|
154
|
+
* a custom args schema, `interrupt`, or a Command that makes several calls.
|
|
155
|
+
*/
|
|
156
|
+
export const queryEffect =
|
|
157
|
+
<Query extends Ref.AnyConfectPublicQuery, SuccessMessage, ErrorMessage>(
|
|
158
|
+
ref: Query,
|
|
159
|
+
handlers: Handlers<Query, SuccessMessage, ErrorMessage>,
|
|
160
|
+
) =>
|
|
161
|
+
(
|
|
162
|
+
...args: Ref.OptionalArgs<Query>
|
|
163
|
+
): Effect.Effect<SuccessMessage | ErrorMessage, never, Client.Client> =>
|
|
164
|
+
run(handlers, (client) => client.query(ref, ...args));
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* An execute body for a hand-written `Command.define` — every failure already
|
|
168
|
+
* folded into a Message. See `queryEffect`.
|
|
169
|
+
*/
|
|
170
|
+
export const mutationEffect =
|
|
171
|
+
<Mutation extends Ref.AnyConfectPublicMutation, SuccessMessage, ErrorMessage>(
|
|
172
|
+
ref: Mutation,
|
|
173
|
+
handlers: Handlers<Mutation, SuccessMessage, ErrorMessage>,
|
|
174
|
+
) =>
|
|
175
|
+
(
|
|
176
|
+
...args: Ref.OptionalArgs<Mutation>
|
|
177
|
+
): Effect.Effect<SuccessMessage | ErrorMessage, never, Client.Client> =>
|
|
178
|
+
run(handlers, (client) => client.mutation(ref, ...args));
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* An execute body for a hand-written `Command.define` — every failure already
|
|
182
|
+
* folded into a Message. See `queryEffect`.
|
|
183
|
+
*/
|
|
184
|
+
export const actionEffect =
|
|
185
|
+
<Action extends Ref.AnyConfectPublicAction, SuccessMessage, ErrorMessage>(
|
|
186
|
+
ref: Action,
|
|
187
|
+
handlers: Handlers<Action, SuccessMessage, ErrorMessage>,
|
|
188
|
+
) =>
|
|
189
|
+
(
|
|
190
|
+
...args: Ref.OptionalArgs<Action>
|
|
191
|
+
): Effect.Effect<SuccessMessage | ErrorMessage, never, Client.Client> =>
|
|
192
|
+
run(handlers, (client) => client.action(ref, ...args));
|
|
193
|
+
|
|
194
|
+
type RunWithArgs<Ref_ extends Ref.AnyConfect, Message> = (
|
|
195
|
+
...args: Ref.OptionalArgs<Ref_>
|
|
196
|
+
) => Effect.Effect<Message, never, Client.Client>;
|
|
197
|
+
|
|
198
|
+
function makeDefinition<
|
|
199
|
+
Name extends string,
|
|
200
|
+
Ref_ extends Ref.AnyConfect,
|
|
201
|
+
SuccessMessage,
|
|
202
|
+
ErrorMessage,
|
|
203
|
+
KeyField extends keyof SchemaArgs<Ref_> & string = keyof SchemaArgs<Ref_> &
|
|
204
|
+
string,
|
|
205
|
+
>(
|
|
206
|
+
name: Name,
|
|
207
|
+
ref: Ref_,
|
|
208
|
+
messages: ReadonlyArray<Schema.Top>,
|
|
209
|
+
runWithArgs: RunWithArgs<Ref_, SuccessMessage | ErrorMessage>,
|
|
210
|
+
interrupt?: InterruptOption<Ref_, KeyField>,
|
|
211
|
+
): Definition<Name, Ref_, SuccessMessage | ErrorMessage> {
|
|
212
|
+
type Fields = Ref.ArgsSchema<Ref_>["fields"];
|
|
213
|
+
type FoldkitArgs = SchemaArgs<Ref_>;
|
|
214
|
+
|
|
215
|
+
const fields: Fields = ref.args.fields;
|
|
216
|
+
const execute = (args: FoldkitArgs | undefined) =>
|
|
217
|
+
runWithArgs(
|
|
218
|
+
...((args === undefined ? [] : [args]) as Ref.OptionalArgs<Ref_>),
|
|
219
|
+
);
|
|
220
|
+
|
|
221
|
+
return Match.value(interrupt).pipe(
|
|
222
|
+
Match.withReturnType<
|
|
223
|
+
Definition<Name, Ref_, SuccessMessage | ErrorMessage>
|
|
224
|
+
>(),
|
|
225
|
+
Match.when(
|
|
226
|
+
undefined,
|
|
227
|
+
() =>
|
|
228
|
+
FoldkitCommand.define(name, {
|
|
229
|
+
args: fields,
|
|
230
|
+
messages,
|
|
231
|
+
execute,
|
|
232
|
+
}) as Definition<Name, Ref_, SuccessMessage | ErrorMessage>,
|
|
233
|
+
),
|
|
234
|
+
Match.when(
|
|
235
|
+
true,
|
|
236
|
+
(nameKeyedInterrupt) =>
|
|
237
|
+
FoldkitCommand.define(name, {
|
|
238
|
+
args: fields,
|
|
239
|
+
messages,
|
|
240
|
+
interrupt: nameKeyedInterrupt,
|
|
241
|
+
execute,
|
|
242
|
+
}) as InterruptibleDefinition<
|
|
243
|
+
Name,
|
|
244
|
+
Ref_,
|
|
245
|
+
SuccessMessage | ErrorMessage
|
|
246
|
+
>,
|
|
247
|
+
),
|
|
248
|
+
Match.when(Match.defined, (keyedInterrupt) => {
|
|
249
|
+
const definition: FoldkitCommand.CommandDefinitionWithArgs<
|
|
250
|
+
Name,
|
|
251
|
+
Fields,
|
|
252
|
+
ReturnType<typeof execute>
|
|
253
|
+
> = FoldkitCommand.define(name, {
|
|
254
|
+
args: fields,
|
|
255
|
+
messages,
|
|
256
|
+
interrupt: keyedInterrupt,
|
|
257
|
+
execute,
|
|
258
|
+
});
|
|
259
|
+
return definition as Definition<
|
|
260
|
+
Name,
|
|
261
|
+
Ref_,
|
|
262
|
+
SuccessMessage | ErrorMessage
|
|
263
|
+
>;
|
|
264
|
+
}),
|
|
265
|
+
Match.exhaustive,
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
type FactoryConfig<
|
|
270
|
+
Ref_ extends Ref.AnyConfect,
|
|
271
|
+
Messages extends ReadonlyArray<Schema.Top>,
|
|
272
|
+
SuccessMessage,
|
|
273
|
+
ErrorMessage,
|
|
274
|
+
> = Handlers<Ref_, SuccessMessage, ErrorMessage> & {
|
|
275
|
+
readonly messages: Messages;
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
type KeyedFactoryConfig<
|
|
279
|
+
Ref_ extends Ref.AnyConfect,
|
|
280
|
+
Messages extends ReadonlyArray<Schema.Top>,
|
|
281
|
+
SuccessMessage,
|
|
282
|
+
ErrorMessage,
|
|
283
|
+
KeyField extends keyof SchemaArgs<Ref_> & string,
|
|
284
|
+
> = FactoryConfig<Ref_, Messages, SuccessMessage, ErrorMessage> & {
|
|
285
|
+
readonly interrupt: KeyedInterrupt<Ref_, KeyField>;
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
type NameKeyedFactoryConfig<
|
|
289
|
+
Ref_ extends Ref.AnyConfect,
|
|
290
|
+
Messages extends ReadonlyArray<Schema.Top>,
|
|
291
|
+
SuccessMessage,
|
|
292
|
+
ErrorMessage,
|
|
293
|
+
> = FactoryConfig<Ref_, Messages, SuccessMessage, ErrorMessage> & {
|
|
294
|
+
readonly interrupt: true;
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
type StandardFactoryConfig<
|
|
298
|
+
Ref_ extends Ref.AnyConfect,
|
|
299
|
+
Messages extends ReadonlyArray<Schema.Top>,
|
|
300
|
+
SuccessMessage,
|
|
301
|
+
ErrorMessage,
|
|
302
|
+
> = FactoryConfig<Ref_, Messages, SuccessMessage, ErrorMessage> & {
|
|
303
|
+
readonly interrupt?: never;
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Builds the overload set for one ref kind. Each arm preserves whether
|
|
308
|
+
* `interrupt` is absent, `true`, or args-keyed all the way to
|
|
309
|
+
* `makeDefinition`.
|
|
310
|
+
*/
|
|
311
|
+
const makeFactory = <BoundRef extends Ref.AnyConfect>(
|
|
312
|
+
effectHelper: <Ref_ extends BoundRef, SuccessMessage, ErrorMessage>(
|
|
313
|
+
ref: Ref_,
|
|
314
|
+
handlers: Handlers<Ref_, SuccessMessage, ErrorMessage>,
|
|
315
|
+
) => RunWithArgs<Ref_, SuccessMessage | ErrorMessage>,
|
|
316
|
+
) => {
|
|
317
|
+
function factory<
|
|
318
|
+
const Name extends string,
|
|
319
|
+
Ref_ extends BoundRef,
|
|
320
|
+
const Messages extends ReadonlyArray<Schema.Top>,
|
|
321
|
+
SuccessMessage extends Schema.Schema.Type<Messages[number]>,
|
|
322
|
+
ErrorMessage extends Schema.Schema.Type<Messages[number]>,
|
|
323
|
+
KeyField extends keyof SchemaArgs<Ref_> & string,
|
|
324
|
+
>(
|
|
325
|
+
name: Name,
|
|
326
|
+
ref: Ref_,
|
|
327
|
+
config: KeyedFactoryConfig<
|
|
328
|
+
Ref_,
|
|
329
|
+
Messages,
|
|
330
|
+
SuccessMessage,
|
|
331
|
+
ErrorMessage,
|
|
332
|
+
KeyField
|
|
333
|
+
>,
|
|
334
|
+
): KeyedInterruptibleDefinition<
|
|
335
|
+
Name,
|
|
336
|
+
Ref_,
|
|
337
|
+
KeyField,
|
|
338
|
+
SuccessMessage | ErrorMessage
|
|
339
|
+
>;
|
|
340
|
+
function factory<
|
|
341
|
+
const Name extends string,
|
|
342
|
+
Ref_ extends BoundRef,
|
|
343
|
+
const Messages extends ReadonlyArray<Schema.Top>,
|
|
344
|
+
SuccessMessage extends Schema.Schema.Type<Messages[number]>,
|
|
345
|
+
ErrorMessage extends Schema.Schema.Type<Messages[number]>,
|
|
346
|
+
>(
|
|
347
|
+
name: Name,
|
|
348
|
+
ref: Ref_,
|
|
349
|
+
config: NameKeyedFactoryConfig<
|
|
350
|
+
Ref_,
|
|
351
|
+
Messages,
|
|
352
|
+
SuccessMessage,
|
|
353
|
+
ErrorMessage
|
|
354
|
+
>,
|
|
355
|
+
): InterruptibleDefinition<Name, Ref_, SuccessMessage | ErrorMessage>;
|
|
356
|
+
function factory<
|
|
357
|
+
const Name extends string,
|
|
358
|
+
Ref_ extends BoundRef,
|
|
359
|
+
const Messages extends ReadonlyArray<Schema.Top>,
|
|
360
|
+
SuccessMessage extends Schema.Schema.Type<Messages[number]>,
|
|
361
|
+
ErrorMessage extends Schema.Schema.Type<Messages[number]>,
|
|
362
|
+
>(
|
|
363
|
+
name: Name,
|
|
364
|
+
ref: Ref_,
|
|
365
|
+
config: StandardFactoryConfig<Ref_, Messages, SuccessMessage, ErrorMessage>,
|
|
366
|
+
): Definition<Name, Ref_, SuccessMessage | ErrorMessage>;
|
|
367
|
+
function factory<
|
|
368
|
+
const Name extends string,
|
|
369
|
+
Ref_ extends BoundRef,
|
|
370
|
+
SuccessMessage,
|
|
371
|
+
ErrorMessage,
|
|
372
|
+
KeyField extends keyof SchemaArgs<Ref_> & string,
|
|
373
|
+
>(
|
|
374
|
+
name: Name,
|
|
375
|
+
ref: Ref_,
|
|
376
|
+
config: FactoryConfig<
|
|
377
|
+
Ref_,
|
|
378
|
+
ReadonlyArray<Schema.Top>,
|
|
379
|
+
SuccessMessage,
|
|
380
|
+
ErrorMessage
|
|
381
|
+
> & {
|
|
382
|
+
readonly interrupt?: InterruptOption<Ref_, KeyField>;
|
|
383
|
+
},
|
|
384
|
+
): Definition<Name, Ref_, SuccessMessage | ErrorMessage> {
|
|
385
|
+
const runWithArgs = effectHelper(ref, config);
|
|
386
|
+
return Match.value(config.interrupt).pipe(
|
|
387
|
+
Match.withReturnType<
|
|
388
|
+
Definition<Name, Ref_, SuccessMessage | ErrorMessage>
|
|
389
|
+
>(),
|
|
390
|
+
Match.when(undefined, () =>
|
|
391
|
+
makeDefinition(name, ref, config.messages, runWithArgs),
|
|
392
|
+
),
|
|
393
|
+
Match.when(true, (interrupt) =>
|
|
394
|
+
makeDefinition(name, ref, config.messages, runWithArgs, interrupt),
|
|
395
|
+
),
|
|
396
|
+
Match.when(Match.defined, (interrupt) =>
|
|
397
|
+
makeDefinition(name, ref, config.messages, runWithArgs, interrupt),
|
|
398
|
+
),
|
|
399
|
+
Match.exhaustive,
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
return factory;
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* A Foldkit Command definition for a Confect query whose Command args are the
|
|
408
|
+
* ref's args:
|
|
409
|
+
*
|
|
410
|
+
* ```ts
|
|
411
|
+
* const FetchNote = Command.query("FetchNote", refs.public.notes.get, {
|
|
412
|
+
* messages: [SucceededGetNote, FailedGetNote],
|
|
413
|
+
* onSuccess: (note) => SucceededGetNote({ note }),
|
|
414
|
+
* onError: (error) => FailedGetNote({ message: String(error) }),
|
|
415
|
+
* })
|
|
416
|
+
* // In update:
|
|
417
|
+
* // [model, [FetchNote({ noteId })]]
|
|
418
|
+
* ```
|
|
419
|
+
*
|
|
420
|
+
* Pass `interrupt` to make invocations interruptible via the returned
|
|
421
|
+
* definition's `Interrupt` constructor — `true` keys them by the Command
|
|
422
|
+
* name, `{ keyFields, toKey }` by a part derived from the ref's args:
|
|
423
|
+
*
|
|
424
|
+
* ```ts
|
|
425
|
+
* const SaveDraft = Command.mutation("SaveDraft", refs.public.notes.insert, {
|
|
426
|
+
* messages: [SucceededSaveDraft, FailedSaveDraft],
|
|
427
|
+
* onSuccess: (noteId) => SucceededSaveDraft({ noteId }),
|
|
428
|
+
* onError: (error) => FailedSaveDraft({ message: String(error) }),
|
|
429
|
+
* interrupt: true,
|
|
430
|
+
* })
|
|
431
|
+
* // In update:
|
|
432
|
+
* // [model, [SaveDraft.Interrupt((outcome) => CompletedCancelSaveDraft({ outcome }))]]
|
|
433
|
+
* ```
|
|
434
|
+
*/
|
|
435
|
+
export const query: ReturnType<typeof makeFactory<Ref.AnyConfectPublicQuery>> =
|
|
436
|
+
makeFactory(queryEffect);
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* A Foldkit Command definition for a Confect mutation whose Command args are
|
|
440
|
+
* the ref's args. See `query`.
|
|
441
|
+
*/
|
|
442
|
+
export const mutation: ReturnType<
|
|
443
|
+
typeof makeFactory<Ref.AnyConfectPublicMutation>
|
|
444
|
+
> = makeFactory(mutationEffect);
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* A Foldkit Command definition for a Confect action whose Command args are
|
|
448
|
+
* the ref's args. See `query`.
|
|
449
|
+
*/
|
|
450
|
+
export const action: ReturnType<
|
|
451
|
+
typeof makeFactory<Ref.AnyConfectPublicAction>
|
|
452
|
+
> = makeFactory(actionEffect);
|