foldkit 0.150.0 → 0.151.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -13
- package/dist/asyncData/asyncData.d.ts +3 -4
- package/dist/asyncData/asyncData.d.ts.map +1 -1
- package/dist/asyncData/asyncData.js +3 -4
- package/dist/command/index.d.ts +14 -13
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +13 -12
- package/dist/experimental/machine/machine.d.ts +9 -2
- package/dist/experimental/machine/machine.d.ts.map +1 -1
- package/dist/experimental/machine/machine.js +3 -3
- package/dist/experimental/server/server.d.ts +6 -5
- package/dist/experimental/server/server.d.ts.map +1 -1
- package/dist/experimental/server/server.js +1 -2
- package/dist/html/submodel.d.ts +4 -4
- package/dist/html/submodel.d.ts.map +1 -1
- package/dist/runtime/runtime.d.ts +11 -47
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +9 -5
- package/dist/test/apps/attributes.d.ts +11 -4
- package/dist/test/apps/attributes.d.ts.map +1 -1
- package/dist/test/apps/attributes.js +1 -1
- package/dist/test/apps/bubbling.d.ts +13 -4
- package/dist/test/apps/bubbling.d.ts.map +1 -1
- package/dist/test/apps/bubbling.js +8 -6
- package/dist/test/apps/colorPicker.d.ts +11 -3
- package/dist/test/apps/colorPicker.d.ts.map +1 -1
- package/dist/test/apps/colorPicker.js +3 -1
- package/dist/test/apps/contextMenu.d.ts +16 -8
- package/dist/test/apps/contextMenu.d.ts.map +1 -1
- package/dist/test/apps/contextMenu.js +3 -4
- package/dist/test/apps/counter.d.ts +10 -10
- package/dist/test/apps/counter.d.ts.map +1 -1
- package/dist/test/apps/counter.js +26 -20
- package/dist/test/apps/crashOnRender.d.ts +12 -12
- package/dist/test/apps/crashOnRender.d.ts.map +1 -1
- package/dist/test/apps/crashOnRender.js +6 -7
- package/dist/test/apps/drafts.d.ts +10 -10
- package/dist/test/apps/drafts.d.ts.map +1 -1
- package/dist/test/apps/drafts.js +7 -5
- package/dist/test/apps/feedSocket.d.ts +19 -4
- package/dist/test/apps/feedSocket.d.ts.map +1 -1
- package/dist/test/apps/feedSocket.js +12 -7
- package/dist/test/apps/fileUpload.d.ts +11 -3
- package/dist/test/apps/fileUpload.d.ts.map +1 -1
- package/dist/test/apps/fileUpload.js +3 -1
- package/dist/test/apps/formChild.d.ts +48 -3
- package/dist/test/apps/formChild.d.ts.map +1 -1
- package/dist/test/apps/formChild.js +33 -38
- package/dist/test/apps/interactions.d.ts +25 -7
- package/dist/test/apps/interactions.d.ts.map +1 -1
- package/dist/test/apps/interactions.js +20 -10
- package/dist/test/apps/keypress.d.ts +15 -4
- package/dist/test/apps/keypress.d.ts.map +1 -1
- package/dist/test/apps/keypress.js +13 -5
- package/dist/test/apps/login.d.ts +13 -13
- package/dist/test/apps/login.d.ts.map +1 -1
- package/dist/test/apps/login.js +28 -18
- package/dist/test/apps/logoutButton.d.ts +15 -6
- package/dist/test/apps/logoutButton.d.ts.map +1 -1
- package/dist/test/apps/logoutButton.js +6 -3
- package/dist/test/apps/mountPanel.d.ts +25 -5
- package/dist/test/apps/mountPanel.d.ts.map +1 -1
- package/dist/test/apps/mountPanel.js +14 -10
- package/dist/test/apps/multiRole.d.ts +10 -3
- package/dist/test/apps/multiRole.d.ts.map +1 -1
- package/dist/test/apps/multiRole.js +5 -2
- package/dist/test/apps/pointer.d.ts +16 -5
- package/dist/test/apps/pointer.d.ts.map +1 -1
- package/dist/test/apps/pointer.js +6 -8
- package/dist/test/apps/resumeUpload.d.ts +25 -4
- package/dist/test/apps/resumeUpload.d.ts.map +1 -1
- package/dist/test/apps/resumeUpload.js +16 -15
- package/dist/test/apps/scorePanel.d.ts +10 -3
- package/dist/test/apps/scorePanel.d.ts.map +1 -1
- package/dist/test/apps/scorePanel.js +3 -1
- package/dist/test/apps/selectiveKeys.d.ts +14 -3
- package/dist/test/apps/selectiveKeys.d.ts.map +1 -1
- package/dist/test/apps/selectiveKeys.js +7 -3
- package/dist/test/apps/uploads.d.ts +13 -13
- package/dist/test/apps/uploads.d.ts.map +1 -1
- package/dist/test/apps/uploads.js +23 -24
- package/dist/test/internal.d.ts +18 -3
- package/dist/test/internal.d.ts.map +1 -1
- package/dist/test/internal.js +8 -16
- package/dist/test/scene.d.ts +16 -19
- package/dist/test/scene.d.ts.map +1 -1
- package/dist/test/scene.js +11 -27
- package/dist/test/story.d.ts +16 -8
- package/dist/test/story.d.ts.map +1 -1
- package/dist/test/story.js +12 -17
- package/dist/update/public.d.ts +2 -2
- package/dist/update/public.d.ts.map +1 -1
- package/dist/update/public.js +1 -1
- package/dist/update/update.d.ts +143 -69
- package/dist/update/update.d.ts.map +1 -1
- package/dist/update/update.js +72 -42
- package/package.json +1 -1
package/dist/update/update.d.ts
CHANGED
|
@@ -1,40 +1,79 @@
|
|
|
1
1
|
import { Option } from 'effect';
|
|
2
2
|
import { type AsyncData } from '../asyncData/index.js';
|
|
3
3
|
import { type Command } from '../command/index.js';
|
|
4
|
-
/** The Commands
|
|
5
|
-
* the
|
|
6
|
-
*
|
|
4
|
+
/** The Commands collection an update return may include. The collection keeps
|
|
5
|
+
* the order in which the update returned them, but the runtime forks the
|
|
6
|
+
* Commands independently. `R` is the services the Commands need and defaults
|
|
7
|
+
* to `never` for applications without resources.
|
|
7
8
|
*
|
|
8
|
-
*
|
|
9
|
-
* throughout; the root update and every Submodel define their own:
|
|
9
|
+
* Name an alias when a module reuses the same Message and service types:
|
|
10
10
|
*
|
|
11
11
|
* ```ts
|
|
12
12
|
* export type Commands = Update.Commands<Message, AppServices>
|
|
13
13
|
* ``` */
|
|
14
14
|
export type Commands<Message, R = never> = ReadonlyArray<Command<Message, never, R>>;
|
|
15
|
-
/** The
|
|
16
|
-
* Commands to run.
|
|
15
|
+
/** The record an update returns when it cannot emit an OutMessage: the next
|
|
16
|
+
* Model and any Commands to run.
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
* result, the root update and every Submodel alike:
|
|
18
|
+
* Inline the type when a matcher is its only use:
|
|
20
19
|
*
|
|
21
20
|
* ```ts
|
|
22
|
-
* export
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
|
|
34
|
-
|
|
21
|
+
* export const update = (model: Model, message: Message) =>
|
|
22
|
+
* Message.match<Update.Return<Model, Message>>(message, {
|
|
23
|
+
* ClickedSave: () => ({ model, commands: [Save()] }),
|
|
24
|
+
* SucceededSave: ({ note }) => ({
|
|
25
|
+
* model: evo(model, { note: () => note }),
|
|
26
|
+
* }),
|
|
27
|
+
* })
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* Give it a local `UpdateReturn` alias when another matcher or helper in the
|
|
31
|
+
* module needs the same type. */
|
|
32
|
+
export type Return<Model, Message, R = never> = Readonly<{
|
|
33
|
+
model: Model;
|
|
34
|
+
commands?: Commands<Message, R>;
|
|
35
|
+
/** Marks this as a result that cannot emit an OutMessage. TypeScript rejects
|
|
36
|
+
* assigning an OutMessage-producing result to this type, so a caller cannot
|
|
37
|
+
* accidentally accept the Model and Commands while losing the OutMessage. */
|
|
38
|
+
outMessage?: never;
|
|
39
|
+
}>;
|
|
40
|
+
/** The return shape of an update that can also surface an OutMessage to its
|
|
41
|
+
* parent. Omit `commands` when the update statically creates none. Return a
|
|
42
|
+
* computed Commands collection directly, even when it may be empty. Omit
|
|
43
|
+
* `outMessage` when the update emitted nothing. A Submodel that cannot emit
|
|
44
|
+
* an OutMessage returns {@link Return} instead. */
|
|
45
|
+
export type ReturnWithOutMessage<Model, Message, OutMessage, R = never> = Readonly<{
|
|
46
|
+
model: Model;
|
|
47
|
+
commands?: Commands<Message, R>;
|
|
48
|
+
outMessage?: OutMessage;
|
|
49
|
+
}>;
|
|
50
|
+
/** Adds a known or optional OutMessage to a plain update return while
|
|
51
|
+
* preserving its Model and Commands. Use this helper when attaching to an
|
|
52
|
+
* existing return or when the value has the type `OutMessage | undefined`.
|
|
53
|
+
* `undefined` means that the operation emitted no OutMessage, so the returned
|
|
54
|
+
* record omits the property.
|
|
55
|
+
*
|
|
56
|
+
* The input must be a {@link Return}, so this helper cannot replace an
|
|
57
|
+
* OutMessage that an update already emitted.
|
|
58
|
+
*
|
|
59
|
+
* ```ts
|
|
60
|
+
* const editorSave = Update.combine(model, [writeDraft, clearErrors])
|
|
61
|
+
*
|
|
62
|
+
* return pipe(editorSave, Update.withOutMessage(outMessage))
|
|
63
|
+
* ```
|
|
64
|
+
*
|
|
65
|
+
* When the OutMessage is already known while constructing a new result,
|
|
66
|
+
* include it directly: `{ model, commands, outMessage }`. If the OutMessage
|
|
67
|
+
* may be `undefined`, pass the new result first:
|
|
68
|
+
* `Update.withOutMessage({ model, commands }, outMessage)`. */
|
|
69
|
+
export declare const withOutMessage: {
|
|
70
|
+
<OutMessage>(outMessage: OutMessage | undefined): <Model, Message, R = never>(updateReturn: Return<Model, Message, R>) => ReturnWithOutMessage<Model, Message, OutMessage, R>;
|
|
71
|
+
<Model, Message, OutMessage, R = never>(updateReturn: Return<Model, Message, R>, outMessage: OutMessage | undefined): ReturnWithOutMessage<Model, Message, OutMessage, R>;
|
|
72
|
+
};
|
|
35
73
|
/** One self-contained edit to the Model paired with the Commands to run:
|
|
36
74
|
* the unit {@link combine} composes. A step that needs arguments is a
|
|
37
|
-
* function returning a Step
|
|
75
|
+
* function returning a Step
|
|
76
|
+
* (`(noteId: NoteId) => Update.Step<Model, Message>`). */
|
|
38
77
|
export type Step<Model, Message, R = never> = (model: Model) => Return<Model, Message, R>;
|
|
39
78
|
/** Composes a list of update steps into one. Each step runs against the
|
|
40
79
|
* Model the previous step produced, and every step's Commands are
|
|
@@ -48,7 +87,7 @@ export type Step<Model, Message, R = never> = (model: Model) => Return<Model, Me
|
|
|
48
87
|
* Steps only ever accumulate Commands; a step cannot cancel or replace
|
|
49
88
|
* another step's Commands, and no Command runs during the fold. The
|
|
50
89
|
* runtime runs the batch after update returns. `combine([])` returns
|
|
51
|
-
* `
|
|
90
|
+
* `{ model }`.
|
|
52
91
|
*
|
|
53
92
|
* ```ts
|
|
54
93
|
* SucceededUpdateNote: ({ note }) =>
|
|
@@ -86,9 +125,9 @@ export type Refreshable<Model, Message, A, E, R = never> = Readonly<{
|
|
|
86
125
|
* cache: read the entry, ask `revalidate` whether it should transition,
|
|
87
126
|
* and only when it says yes write the transitioned state and emit the
|
|
88
127
|
* load Command. When `revalidate` returns `None` (a missing entry, or a
|
|
89
|
-
* state with nothing to revalidate) the step returns `
|
|
90
|
-
* Model, no Command.
|
|
91
|
-
*
|
|
128
|
+
* state with nothing to revalidate) the step returns `{ model }`: same
|
|
129
|
+
* Model, no Command. A handler can list every affected cache, and only the
|
|
130
|
+
* caches that currently hold data reload.
|
|
92
131
|
*
|
|
93
132
|
* ```ts
|
|
94
133
|
* const refreshAllNotes = refresh({
|
|
@@ -100,7 +139,7 @@ export type Refreshable<Model, Message, A, E, R = never> = Readonly<{
|
|
|
100
139
|
* ``` */
|
|
101
140
|
export declare const refresh: <Model, Message, A, E, R = never>(refreshable: Refreshable<Model, Message, A, E, R>) => Step<Model, Message, R>;
|
|
102
141
|
/** The four capabilities that fold one child Submodel's update into the
|
|
103
|
-
* parent, for a child
|
|
142
|
+
* parent, for a child whose update cannot emit an OutMessage.
|
|
104
143
|
*
|
|
105
144
|
* - `update`: the child update function to run.
|
|
106
145
|
* - `read`: the getter half of the lens onto the child: reads the child
|
|
@@ -122,12 +161,11 @@ export type ChildFold<ParentModel, ParentMessage, ChildModel, Input, ChildMessag
|
|
|
122
161
|
/** The lifters a `foldOutMessage` receives as its second parameter,
|
|
123
162
|
* already bound to the fold config's `toParentMessage`.
|
|
124
163
|
*
|
|
125
|
-
* The fold lifts the Commands the child's `update
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
* child's
|
|
129
|
-
*
|
|
130
|
-
* fulfills it, built with context only the parent holds.
|
|
164
|
+
* The fold already lifts the Commands returned by the child's `update`.
|
|
165
|
+
* Use these lifters for a Command returned by the parent's OutMessage Step
|
|
166
|
+
* when that Command still produces the child's Message. For example, the
|
|
167
|
+
* parent may handle a child's `Requested*` fact by returning a child Command
|
|
168
|
+
* built with routing context only the parent holds.
|
|
131
169
|
*
|
|
132
170
|
* The lifters apply the same lift the fold gives the child's own
|
|
133
171
|
* Commands, so the Step writes no `Command.mapMessage` call and keeps
|
|
@@ -138,20 +176,25 @@ export type ChildFold<ParentModel, ParentMessage, ChildModel, Input, ChildMessag
|
|
|
138
176
|
* OutMessage value directly:
|
|
139
177
|
*
|
|
140
178
|
* ```ts
|
|
141
|
-
* const foldLoginOutMessage
|
|
179
|
+
* const foldLoginOutMessage = (
|
|
142
180
|
* outMessage: Login.OutMessage,
|
|
143
|
-
*
|
|
144
|
-
* ) =>
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
*
|
|
181
|
+
* { liftCommand }: Update.FoldContext<Login.Message, Message>,
|
|
182
|
+
* ) =>
|
|
183
|
+
* M.value(outMessage).pipe(
|
|
184
|
+
* M.withReturnType<Update.Step<Model, Message>>(),
|
|
185
|
+
* M.tagsExhaustive({
|
|
186
|
+
* RequestedMagicLink:
|
|
187
|
+
* ({ email }) =>
|
|
188
|
+
* model => ({
|
|
189
|
+
* model,
|
|
190
|
+
* commands: [
|
|
191
|
+
* liftCommand(
|
|
192
|
+
* Login.SendMagicLink({ email, redirectRoute: model.route }),
|
|
193
|
+
* ),
|
|
194
|
+
* ],
|
|
195
|
+
* }),
|
|
196
|
+
* }),
|
|
197
|
+
* )
|
|
155
198
|
* ``` */
|
|
156
199
|
export type FoldContext<ChildMessage, ParentMessage> = Readonly<{
|
|
157
200
|
liftCommand: <E = never, R = never>(command: Command<ChildMessage, E, R>) => Command<ParentMessage, E, R>;
|
|
@@ -176,24 +219,28 @@ export type ChildFoldWithOutMessage<ParentModel, ParentMessage, ChildModel, Inpu
|
|
|
176
219
|
foldOutMessage: (outMessage: ChildOutMessage, context: FoldContext<ChildMessage, ParentMessage>) => Step<ParentModel, ParentMessage, R>;
|
|
177
220
|
}>;
|
|
178
221
|
/** {@link ChildFoldWithOutMessage} for a parent that is itself a
|
|
179
|
-
* Submodel, so the fold
|
|
180
|
-
* channel as a third tuple element. Adds:
|
|
222
|
+
* Submodel, so the fold can return the parent's own OutMessage. Adds:
|
|
181
223
|
*
|
|
182
224
|
* - `toParentOutMessage`: lifts the child's OutMessage into the
|
|
183
|
-
* parent's own OutMessage
|
|
184
|
-
* child returns no OutMessage the fold
|
|
225
|
+
* parent's own OutMessage. Return `undefined` for a named child variant
|
|
226
|
+
* that stops at this parent. When the child returns no OutMessage, the fold
|
|
227
|
+
* omits `outMessage`.
|
|
185
228
|
* - `foldOutMessage` stays available for a parent that also updates
|
|
186
229
|
* its own state from the child's OutMessage, and is optional here.
|
|
187
230
|
*
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
*
|
|
231
|
+
* Use this shape only when `toParentOutMessage` forwards at least one child
|
|
232
|
+
* OutMessage from the current Submodel to its parent. If no child OutMessage
|
|
233
|
+
* is forwarded, use {@link ChildFoldWithOutMessage}. Its plain result is
|
|
234
|
+
* valid wherever the parent accepts {@link ReturnWithOutMessage}, because
|
|
235
|
+
* emitting no OutMessage is valid. Local handling through `foldOutMessage`
|
|
236
|
+
* is independent, so a forwarded child OutMessage may also update the
|
|
237
|
+
* current parent. */
|
|
191
238
|
export type ChildFoldWithParentOutMessage<ParentModel, ParentMessage, ChildModel, Input, ChildMessage, ChildOutMessage, ParentOutMessage, R = never> = Readonly<{
|
|
192
239
|
update: (childModel: ChildModel, input: Input) => ReturnWithOutMessage<ChildModel, ChildMessage, ChildOutMessage, R>;
|
|
193
240
|
read: (model: ParentModel) => Option.Option<ChildModel>;
|
|
194
241
|
write: (model: ParentModel, nextChildModel: ChildModel) => ParentModel;
|
|
195
242
|
toParentMessage: (message: ChildMessage) => ParentMessage;
|
|
196
|
-
toParentOutMessage: (outMessage: ChildOutMessage) =>
|
|
243
|
+
toParentOutMessage: (outMessage: ChildOutMessage) => ParentOutMessage | undefined;
|
|
197
244
|
foldOutMessage?: (outMessage: ChildOutMessage, context: FoldContext<ChildMessage, ParentMessage>) => Step<ParentModel, ParentMessage, R>;
|
|
198
245
|
}>;
|
|
199
246
|
/** {@link Step} for an update that also surfaces an OutMessage to its
|
|
@@ -237,7 +284,7 @@ export type FoldWithOutMessage<ParentModel, ParentMessage, Input, ParentOutMessa
|
|
|
237
284
|
* The fold runs `update` against the child Model `read` returns, writes
|
|
238
285
|
* the child back, and lifts the child's Commands through
|
|
239
286
|
* `toParentMessage`. When `read` returns `None` the fold returns
|
|
240
|
-
* `
|
|
287
|
+
* `{ model }`: a Message for an unmounted child is a no-op. When the
|
|
241
288
|
* child's update returns an OutMessage, `foldOutMessage` runs against
|
|
242
289
|
* the Model with the child already written back, and its Commands
|
|
243
290
|
* follow the child's in the returned batch.
|
|
@@ -250,8 +297,10 @@ export type FoldWithOutMessage<ParentModel, ParentMessage, Input, ParentOutMessa
|
|
|
250
297
|
*
|
|
251
298
|
* A parent that is itself a Submodel passes a
|
|
252
299
|
* {@link ChildFoldWithParentOutMessage} and receives a
|
|
253
|
-
* {@link FoldWithOutMessage}, whose results
|
|
254
|
-
* OutMessage
|
|
300
|
+
* {@link FoldWithOutMessage}, whose results may include the parent's own
|
|
301
|
+
* OutMessage. Add `toParentOutMessage` only when it forwards at least one
|
|
302
|
+
* child OutMessage from the current Submodel to its parent. Omit
|
|
303
|
+
* `toParentOutMessage` when the local `foldOutMessage` handles every variant.
|
|
255
304
|
*
|
|
256
305
|
* An entry point that takes nothing but the child Model, such as
|
|
257
306
|
* `Dialog.close`, has no input to pass: fold it with
|
|
@@ -264,7 +313,7 @@ export type FoldWithOutMessage<ParentModel, ParentMessage, Input, ParentOutMessa
|
|
|
264
313
|
* ```ts
|
|
265
314
|
* const enterJoinedRoom = (roomId: string, player: Player): UpdateStep =>
|
|
266
315
|
* Update.combine([
|
|
267
|
-
* model =>
|
|
316
|
+
* model => ({ model, commands: [NavigateToRoom({ roomId })] }),
|
|
268
317
|
* Update.foldChild({
|
|
269
318
|
* update: (room: Room.Model, joinedPlayer: Player) =>
|
|
270
319
|
* Room.informJoined(room, joinedPlayer, { roomId }),
|
|
@@ -290,10 +339,11 @@ export type ChildStepFold<ParentModel, ParentMessage, ChildModel, ChildMessage,
|
|
|
290
339
|
write: (model: ParentModel, nextChildModel: ChildModel) => ParentModel;
|
|
291
340
|
toParentMessage: (message: ChildMessage) => ParentMessage;
|
|
292
341
|
}>;
|
|
293
|
-
/** {@link ChildStepFold} for an entry point
|
|
294
|
-
* OutMessage
|
|
295
|
-
* in {@link ChildFoldWithOutMessage},
|
|
296
|
-
* a {@link FoldContext} of lifters bound to
|
|
342
|
+
/** {@link ChildStepFold} for an entry point that can emit the child's
|
|
343
|
+
* OutMessage, adding `foldOutMessage`. The function has the same contract as
|
|
344
|
+
* `foldOutMessage` in {@link ChildFoldWithOutMessage}, including the optional
|
|
345
|
+
* second parameter: a {@link FoldContext} of lifters bound to
|
|
346
|
+
* `toParentMessage`. */
|
|
297
347
|
export type ChildStepFoldWithOutMessage<ParentModel, ParentMessage, ChildModel, ChildMessage, ChildOutMessage, R = never> = Readonly<{
|
|
298
348
|
update: (childModel: ChildModel) => ReturnWithOutMessage<ChildModel, ChildMessage, ChildOutMessage, R>;
|
|
299
349
|
read: (model: ParentModel) => Option.Option<ChildModel>;
|
|
@@ -301,6 +351,25 @@ export type ChildStepFoldWithOutMessage<ParentModel, ParentMessage, ChildModel,
|
|
|
301
351
|
toParentMessage: (message: ChildMessage) => ParentMessage;
|
|
302
352
|
foldOutMessage: (outMessage: ChildOutMessage, context: FoldContext<ChildMessage, ParentMessage>) => Step<ParentModel, ParentMessage, R>;
|
|
303
353
|
}>;
|
|
354
|
+
/** {@link ChildStepFoldWithOutMessage} for a parent that is itself a
|
|
355
|
+
* Submodel. `toParentOutMessage` turns the child's OutMessage into the
|
|
356
|
+
* parent's OutMessage. Return `undefined` for a named child variant that
|
|
357
|
+
* stops at this parent. `foldOutMessage` remains available when the parent
|
|
358
|
+
* also updates its own state from the child's OutMessage.
|
|
359
|
+
*
|
|
360
|
+
* Use this shape only when `toParentOutMessage` forwards at least one child
|
|
361
|
+
* OutMessage from the current Submodel to its parent. If no child OutMessage
|
|
362
|
+
* is forwarded, use {@link ChildStepFoldWithOutMessage}. Local handling
|
|
363
|
+
* through `foldOutMessage` is independent, so a forwarded child OutMessage
|
|
364
|
+
* may also update the current parent. */
|
|
365
|
+
export type ChildStepFoldWithParentOutMessage<ParentModel, ParentMessage, ChildModel, ChildMessage, ChildOutMessage, ParentOutMessage, R = never> = Readonly<{
|
|
366
|
+
update: (childModel: ChildModel) => ReturnWithOutMessage<ChildModel, ChildMessage, ChildOutMessage, R>;
|
|
367
|
+
read: (model: ParentModel) => Option.Option<ChildModel>;
|
|
368
|
+
write: (model: ParentModel, nextChildModel: ChildModel) => ParentModel;
|
|
369
|
+
toParentMessage: (message: ChildMessage) => ParentMessage;
|
|
370
|
+
toParentOutMessage: (outMessage: ChildOutMessage) => ParentOutMessage | undefined;
|
|
371
|
+
foldOutMessage?: (outMessage: ChildOutMessage, context: FoldContext<ChildMessage, ParentMessage>) => Step<ParentModel, ParentMessage, R>;
|
|
372
|
+
}>;
|
|
304
373
|
/** Folds a child entry point that takes nothing but the child Model, and
|
|
305
374
|
* returns the {@link Step} directly. Everything else matches
|
|
306
375
|
* {@link foldChild}: the child is read, updated, and written back, its
|
|
@@ -325,14 +394,19 @@ export type ChildStepFoldWithOutMessage<ParentModel, ParentMessage, ChildModel,
|
|
|
325
394
|
* Update.combine(model, [writeRouteFields, foldMobileMenuDialogClose])
|
|
326
395
|
* ```
|
|
327
396
|
*
|
|
328
|
-
* `foldOutMessage` takes the same optional second parameter
|
|
329
|
-
*
|
|
330
|
-
* to this config's `toParentMessage`, for a Command the
|
|
331
|
-
* result is the child's Message.
|
|
397
|
+
* `foldOutMessage` takes the same optional second parameter as
|
|
398
|
+
* {@link foldChild}: a {@link FoldContext} carrying `liftCommand` and
|
|
399
|
+
* `liftCommands` bound to this config's `toParentMessage`, for a Command the
|
|
400
|
+
* Step returns whose result is the child's Message.
|
|
332
401
|
*
|
|
333
|
-
* A parent that is itself a Submodel
|
|
334
|
-
*
|
|
402
|
+
* A parent that is itself a Submodel adds `toParentOutMessage` when it
|
|
403
|
+
* forwards at least one child OutMessage to its own parent and receives a
|
|
404
|
+
* {@link StepWithOutMessage}, just as the input-taking {@link foldChild}
|
|
405
|
+
* returns a {@link FoldWithOutMessage}. When no child OutMessage is
|
|
406
|
+
* forwarded, omit the lift and use the plain Step directly. Local handling
|
|
407
|
+
* through `foldOutMessage` is independent of forwarding. */
|
|
335
408
|
export declare const foldChildStep: {
|
|
409
|
+
<ParentModel, ParentMessage, ChildModel, ChildMessage, ChildOutMessage, ParentOutMessage, R = never>(childFold: ChildStepFoldWithParentOutMessage<ParentModel, ParentMessage, ChildModel, ChildMessage, ChildOutMessage, ParentOutMessage, R>): StepWithOutMessage<ParentModel, ParentMessage, ParentOutMessage, R>;
|
|
336
410
|
<ParentModel, ParentMessage, ChildModel, ChildMessage, ChildOutMessage, R = never>(childFold: ChildStepFoldWithOutMessage<ParentModel, ParentMessage, ChildModel, ChildMessage, ChildOutMessage, R>): Step<ParentModel, ParentMessage, R>;
|
|
337
411
|
<ParentModel, ParentMessage, ChildModel, ChildMessage, R = never>(childFold: ChildStepFold<ParentModel, ParentMessage, ChildModel, ChildMessage, R>): Step<ParentModel, ParentMessage, R>;
|
|
338
412
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/update/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,MAAM,EAAQ,MAAM,QAAQ,CAAA;AAEtD,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,KAAK,OAAO,EAA2B,MAAM,qBAAqB,CAAA;AAE3E;;;;;;;;;UASU;AACV,MAAM,MAAM,QAAQ,CAAC,OAAO,EAAE,CAAC,GAAG,KAAK,IAAI,aAAa,CACtD,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAC3B,CAAA;AAED
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/update/update.ts"],"names":[],"mappings":"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"}
|
package/dist/update/update.js
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
import { Array, Function, Option, pipe } from 'effect';
|
|
2
2
|
import { mapMessage, mapMessages } from '../command/index.js';
|
|
3
|
+
/** Adds a known or optional OutMessage to a plain update return while
|
|
4
|
+
* preserving its Model and Commands. Use this helper when attaching to an
|
|
5
|
+
* existing return or when the value has the type `OutMessage | undefined`.
|
|
6
|
+
* `undefined` means that the operation emitted no OutMessage, so the returned
|
|
7
|
+
* record omits the property.
|
|
8
|
+
*
|
|
9
|
+
* The input must be a {@link Return}, so this helper cannot replace an
|
|
10
|
+
* OutMessage that an update already emitted.
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* const editorSave = Update.combine(model, [writeDraft, clearErrors])
|
|
14
|
+
*
|
|
15
|
+
* return pipe(editorSave, Update.withOutMessage(outMessage))
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* When the OutMessage is already known while constructing a new result,
|
|
19
|
+
* include it directly: `{ model, commands, outMessage }`. If the OutMessage
|
|
20
|
+
* may be `undefined`, pass the new result first:
|
|
21
|
+
* `Update.withOutMessage({ model, commands }, outMessage)`. */
|
|
22
|
+
export const withOutMessage = Function.dual(2, (updateReturn, outMessage) => outMessage === undefined ? updateReturn : { ...updateReturn, outMessage });
|
|
3
23
|
/** Composes a list of update steps into one. Each step runs against the
|
|
4
24
|
* Model the previous step produced, and every step's Commands are
|
|
5
25
|
* concatenated into a single batch, in step order.
|
|
@@ -12,7 +32,7 @@ import { mapMessage, mapMessages } from '../command/index.js';
|
|
|
12
32
|
* Steps only ever accumulate Commands; a step cannot cancel or replace
|
|
13
33
|
* another step's Commands, and no Command runs during the fold. The
|
|
14
34
|
* runtime runs the batch after update returns. `combine([])` returns
|
|
15
|
-
* `
|
|
35
|
+
* `{ model }`.
|
|
16
36
|
*
|
|
17
37
|
* ```ts
|
|
18
38
|
* SucceededUpdateNote: ({ note }) =>
|
|
@@ -26,19 +46,20 @@ import { mapMessage, mapMessages } from '../command/index.js';
|
|
|
26
46
|
* ])
|
|
27
47
|
* ``` */
|
|
28
48
|
export const combine = Function.dual(2, (model, steps) => {
|
|
29
|
-
const seed =
|
|
30
|
-
return Array.reduce(steps, seed, (
|
|
31
|
-
const
|
|
32
|
-
|
|
49
|
+
const seed = { model };
|
|
50
|
+
return Array.reduce(steps, seed, (current, step) => {
|
|
51
|
+
const next = step(current.model);
|
|
52
|
+
const commands = [...(current.commands ?? []), ...(next.commands ?? [])];
|
|
53
|
+
return { model: next.model, commands };
|
|
33
54
|
});
|
|
34
55
|
});
|
|
35
56
|
/** Turns a {@link Refreshable} into an update step that revalidates one
|
|
36
57
|
* cache: read the entry, ask `revalidate` whether it should transition,
|
|
37
58
|
* and only when it says yes write the transitioned state and emit the
|
|
38
59
|
* load Command. When `revalidate` returns `None` (a missing entry, or a
|
|
39
|
-
* state with nothing to revalidate) the step returns `
|
|
40
|
-
* Model, no Command.
|
|
41
|
-
*
|
|
60
|
+
* state with nothing to revalidate) the step returns `{ model }`: same
|
|
61
|
+
* Model, no Command. A handler can list every affected cache, and only the
|
|
62
|
+
* caches that currently hold data reload.
|
|
42
63
|
*
|
|
43
64
|
* ```ts
|
|
44
65
|
* const refreshAllNotes = refresh({
|
|
@@ -49,8 +70,11 @@ export const combine = Function.dual(2, (model, steps) => {
|
|
|
49
70
|
* })
|
|
50
71
|
* ``` */
|
|
51
72
|
export const refresh = (refreshable) => model => pipe(refreshable.read(model), Option.flatMap(refreshable.revalidate), Option.match({
|
|
52
|
-
onNone: () =>
|
|
53
|
-
onSome: next =>
|
|
73
|
+
onNone: () => ({ model }),
|
|
74
|
+
onSome: next => ({
|
|
75
|
+
model: refreshable.write(model, next),
|
|
76
|
+
commands: [refreshable.load],
|
|
77
|
+
}),
|
|
54
78
|
}));
|
|
55
79
|
/** Folds a child Submodel's update into the parent: the update half of
|
|
56
80
|
* embedding a child, complementing `h.submodel` on the view half. Give
|
|
@@ -73,7 +97,7 @@ export const refresh = (refreshable) => model => pipe(refreshable.read(model), O
|
|
|
73
97
|
* The fold runs `update` against the child Model `read` returns, writes
|
|
74
98
|
* the child back, and lifts the child's Commands through
|
|
75
99
|
* `toParentMessage`. When `read` returns `None` the fold returns
|
|
76
|
-
* `
|
|
100
|
+
* `{ model }`: a Message for an unmounted child is a no-op. When the
|
|
77
101
|
* child's update returns an OutMessage, `foldOutMessage` runs against
|
|
78
102
|
* the Model with the child already written back, and its Commands
|
|
79
103
|
* follow the child's in the returned batch.
|
|
@@ -86,8 +110,10 @@ export const refresh = (refreshable) => model => pipe(refreshable.read(model), O
|
|
|
86
110
|
*
|
|
87
111
|
* A parent that is itself a Submodel passes a
|
|
88
112
|
* {@link ChildFoldWithParentOutMessage} and receives a
|
|
89
|
-
* {@link FoldWithOutMessage}, whose results
|
|
90
|
-
* OutMessage
|
|
113
|
+
* {@link FoldWithOutMessage}, whose results may include the parent's own
|
|
114
|
+
* OutMessage. Add `toParentOutMessage` only when it forwards at least one
|
|
115
|
+
* child OutMessage from the current Submodel to its parent. Omit
|
|
116
|
+
* `toParentOutMessage` when the local `foldOutMessage` handles every variant.
|
|
91
117
|
*
|
|
92
118
|
* An entry point that takes nothing but the child Model, such as
|
|
93
119
|
* `Dialog.close`, has no input to pass: fold it with
|
|
@@ -100,7 +126,7 @@ export const refresh = (refreshable) => model => pipe(refreshable.read(model), O
|
|
|
100
126
|
* ```ts
|
|
101
127
|
* const enterJoinedRoom = (roomId: string, player: Player): UpdateStep =>
|
|
102
128
|
* Update.combine([
|
|
103
|
-
* model =>
|
|
129
|
+
* model => ({ model, commands: [NavigateToRoom({ roomId })] }),
|
|
104
130
|
* Update.foldChild({
|
|
105
131
|
* update: (room: Room.Model, joinedPlayer: Player) =>
|
|
106
132
|
* Room.informJoined(room, joinedPlayer, { roomId }),
|
|
@@ -119,25 +145,29 @@ const makeFoldContext = (toParentMessage) => ({
|
|
|
119
145
|
liftCommands: commands => mapMessages(commands, toParentMessage),
|
|
120
146
|
});
|
|
121
147
|
const runChildFold = (childFold, context, model, input) => pipe(model, childFold.read, Option.match({
|
|
122
|
-
onNone: () =>
|
|
123
|
-
? [model, []]
|
|
124
|
-
: [model, [], Option.none()],
|
|
148
|
+
onNone: () => ({ model }),
|
|
125
149
|
onSome: childModel => {
|
|
126
|
-
const
|
|
127
|
-
const modelWithChild = childFold.write(model,
|
|
128
|
-
const mappedCommands = mapMessages(
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
150
|
+
const childUpdate = childFold.update(childModel, input);
|
|
151
|
+
const modelWithChild = childFold.write(model, childUpdate.model);
|
|
152
|
+
const mappedCommands = mapMessages(childUpdate.commands, childFold.toParentMessage);
|
|
153
|
+
const update = childFold.foldOutMessage === undefined ||
|
|
154
|
+
childUpdate.outMessage === undefined
|
|
155
|
+
? { model: modelWithChild, commands: mappedCommands }
|
|
156
|
+
: combine(modelWithChild, [
|
|
157
|
+
stepModel => ({
|
|
158
|
+
model: stepModel,
|
|
159
|
+
commands: mappedCommands,
|
|
160
|
+
}),
|
|
161
|
+
childFold.foldOutMessage(childUpdate.outMessage, context),
|
|
162
|
+
]);
|
|
134
163
|
if (childFold.toParentOutMessage === undefined) {
|
|
135
|
-
return
|
|
164
|
+
return update;
|
|
165
|
+
}
|
|
166
|
+
if (childUpdate.outMessage === undefined) {
|
|
167
|
+
return update;
|
|
136
168
|
}
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
: Option.flatMap(maybeOutMessage, childFold.toParentOutMessage);
|
|
140
|
-
return [nextModel, commands, maybeParentOutMessage];
|
|
169
|
+
const parentOutMessage = childFold.toParentOutMessage(childUpdate.outMessage);
|
|
170
|
+
return withOutMessage(update, parentOutMessage);
|
|
141
171
|
},
|
|
142
172
|
}));
|
|
143
173
|
/** Folds a child entry point that takes nothing but the child Model, and
|
|
@@ -164,18 +194,18 @@ const runChildFold = (childFold, context, model, input) => pipe(model, childFold
|
|
|
164
194
|
* Update.combine(model, [writeRouteFields, foldMobileMenuDialogClose])
|
|
165
195
|
* ```
|
|
166
196
|
*
|
|
167
|
-
* `foldOutMessage` takes the same optional second parameter
|
|
168
|
-
*
|
|
169
|
-
* to this config's `toParentMessage`, for a Command the
|
|
170
|
-
* result is the child's Message.
|
|
171
|
-
*
|
|
172
|
-
* A parent that is itself a Submodel
|
|
173
|
-
*
|
|
197
|
+
* `foldOutMessage` takes the same optional second parameter as
|
|
198
|
+
* {@link foldChild}: a {@link FoldContext} carrying `liftCommand` and
|
|
199
|
+
* `liftCommands` bound to this config's `toParentMessage`, for a Command the
|
|
200
|
+
* Step returns whose result is the child's Message.
|
|
201
|
+
*
|
|
202
|
+
* A parent that is itself a Submodel adds `toParentOutMessage` when it
|
|
203
|
+
* forwards at least one child OutMessage to its own parent and receives a
|
|
204
|
+
* {@link StepWithOutMessage}, just as the input-taking {@link foldChild}
|
|
205
|
+
* returns a {@link FoldWithOutMessage}. When no child OutMessage is
|
|
206
|
+
* forwarded, omit the lift and use the plain Step directly. Local handling
|
|
207
|
+
* through `foldOutMessage` is independent of forwarding. */
|
|
174
208
|
export const foldChildStep = (childFold) => {
|
|
175
209
|
const context = makeFoldContext(childFold.toParentMessage);
|
|
176
|
-
return model => runChildFold(childFold, context, model, undefined);
|
|
177
|
-
};
|
|
178
|
-
const appendOutMessageStep = (foldOutMessage, outMessage, context, modelWithChild, mappedCommands) => {
|
|
179
|
-
const [nextModel, outCommands] = foldOutMessage(outMessage, context)(modelWithChild);
|
|
180
|
-
return [nextModel, [...mappedCommands, ...outCommands]];
|
|
210
|
+
return (model) => runChildFold(childFold, context, model, undefined);
|
|
181
211
|
};
|