foldkit 0.100.1 → 0.102.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 +3 -2
- package/dist/canvas/view.d.ts +1 -1
- package/dist/canvas/view.d.ts.map +1 -1
- package/dist/canvas/view.js +5 -5
- package/dist/command/index.d.ts +71 -0
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +34 -1
- package/dist/command/public.d.ts +1 -1
- package/dist/command/public.d.ts.map +1 -1
- package/dist/command/public.js +1 -1
- package/dist/devTools/overlay.d.ts.map +1 -1
- package/dist/devTools/overlay.js +156 -149
- package/dist/dom/dom.d.ts +8 -11
- package/dist/dom/dom.d.ts.map +1 -1
- package/dist/dom/dom.js +8 -11
- package/dist/dom/elementMovement.d.ts +1 -3
- package/dist/dom/elementMovement.d.ts.map +1 -1
- package/dist/dom/elementMovement.js +1 -3
- package/dist/dom/inert.d.ts +2 -4
- package/dist/dom/inert.d.ts.map +1 -1
- package/dist/dom/inert.js +2 -4
- package/dist/dom/scrollLock.d.ts +2 -2
- package/dist/dom/scrollLock.js +2 -2
- package/dist/dom/waitForAnimation.d.ts +1 -1
- package/dist/dom/waitForAnimation.js +1 -1
- package/dist/html/boundary.d.ts +98 -0
- package/dist/html/boundary.d.ts.map +1 -0
- package/dist/html/boundary.js +176 -0
- package/dist/html/childAttribute.d.ts +44 -0
- package/dist/html/childAttribute.d.ts.map +1 -0
- package/dist/html/childAttribute.js +34 -0
- package/dist/html/index.d.ts +70 -23
- package/dist/html/index.d.ts.map +1 -1
- package/dist/html/index.js +639 -575
- package/dist/html/lazy.d.ts +12 -7
- package/dist/html/lazy.d.ts.map +1 -1
- package/dist/html/lazy.js +30 -11
- package/dist/html/public.d.ts +2 -2
- package/dist/html/public.d.ts.map +1 -1
- package/dist/html/public.js +1 -1
- package/dist/html/runtimeSingleton.d.ts +72 -0
- package/dist/html/runtimeSingleton.d.ts.map +1 -0
- package/dist/html/runtimeSingleton.js +112 -0
- package/dist/html/submodel.d.ts +98 -0
- package/dist/html/submodel.d.ts.map +1 -0
- package/dist/html/submodel.js +190 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/render/render.d.ts +1 -1
- package/dist/render/render.js +1 -1
- package/dist/runtime/messagePriority.d.ts +5 -1
- package/dist/runtime/messagePriority.d.ts.map +1 -1
- package/dist/runtime/messagePriority.js +25 -4
- package/dist/runtime/runtime.d.ts +11 -11
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +118 -63
- package/dist/runtime/subscription.d.ts +139 -19
- package/dist/runtime/subscription.d.ts.map +1 -1
- package/dist/runtime/subscription.js +90 -9
- package/dist/submodel/public.d.ts +4 -0
- package/dist/submodel/public.d.ts.map +1 -0
- package/dist/submodel/public.js +1 -0
- package/dist/submodel/submodel.d.ts +32 -0
- package/dist/submodel/submodel.d.ts.map +1 -0
- package/dist/submodel/submodel.js +1 -0
- package/dist/subscription/animationFrame.d.ts +23 -26
- package/dist/subscription/animationFrame.d.ts.map +1 -1
- package/dist/subscription/animationFrame.js +17 -18
- package/dist/subscription/public.d.ts +2 -2
- package/dist/subscription/public.d.ts.map +1 -1
- package/dist/subscription/public.js +1 -1
- package/dist/test/apps/disabledButton.d.ts +4 -5
- package/dist/test/apps/disabledButton.d.ts.map +1 -1
- package/dist/test/apps/disabledButton.js +16 -16
- package/dist/test/scene.d.ts +8 -8
- package/dist/test/scene.d.ts.map +1 -1
- package/dist/test/scene.js +25 -13
- package/dist/test/story.d.ts +15 -8
- package/dist/test/story.d.ts.map +1 -1
- package/dist/test/story.js +21 -9
- package/dist/ui/animation/index.d.ts +30 -14
- package/dist/ui/animation/index.d.ts.map +1 -1
- package/dist/ui/animation/index.js +9 -19
- package/dist/ui/animation/public.d.ts +2 -2
- package/dist/ui/animation/public.d.ts.map +1 -1
- package/dist/ui/animation/public.js +1 -1
- package/dist/ui/calendar/index.d.ts +199 -84
- package/dist/ui/calendar/index.d.ts.map +1 -1
- package/dist/ui/calendar/index.js +129 -140
- package/dist/ui/calendar/public.d.ts +2 -2
- package/dist/ui/calendar/public.d.ts.map +1 -1
- package/dist/ui/calendar/public.js +1 -1
- package/dist/ui/checkbox/index.d.ts +93 -21
- package/dist/ui/checkbox/index.d.ts.map +1 -1
- package/dist/ui/checkbox/index.js +62 -33
- package/dist/ui/checkbox/public.d.ts +2 -2
- package/dist/ui/checkbox/public.d.ts.map +1 -1
- package/dist/ui/checkbox/public.js +1 -1
- package/dist/ui/combobox/multi.d.ts +35 -91
- package/dist/ui/combobox/multi.d.ts.map +1 -1
- package/dist/ui/combobox/multi.js +34 -17
- package/dist/ui/combobox/multiPublic.d.ts +2 -2
- package/dist/ui/combobox/multiPublic.d.ts.map +1 -1
- package/dist/ui/combobox/multiPublic.js +1 -1
- package/dist/ui/combobox/public.d.ts +3 -3
- package/dist/ui/combobox/public.d.ts.map +1 -1
- package/dist/ui/combobox/public.js +2 -2
- package/dist/ui/combobox/shared.d.ts +56 -31
- package/dist/ui/combobox/shared.d.ts.map +1 -1
- package/dist/ui/combobox/shared.js +333 -322
- package/dist/ui/combobox/single.d.ts +46 -93
- package/dist/ui/combobox/single.d.ts.map +1 -1
- package/dist/ui/combobox/single.js +44 -17
- package/dist/ui/datePicker/index.d.ts +256 -48
- package/dist/ui/datePicker/index.d.ts.map +1 -1
- package/dist/ui/datePicker/index.js +149 -104
- package/dist/ui/datePicker/public.d.ts +2 -2
- package/dist/ui/datePicker/public.d.ts.map +1 -1
- package/dist/ui/datePicker/public.js +1 -1
- package/dist/ui/dialog/index.d.ts +95 -39
- package/dist/ui/dialog/index.d.ts.map +1 -1
- package/dist/ui/dialog/index.js +71 -62
- package/dist/ui/dialog/public.d.ts +2 -2
- package/dist/ui/dialog/public.d.ts.map +1 -1
- package/dist/ui/dialog/public.js +1 -1
- package/dist/ui/disclosure/index.d.ts +71 -31
- package/dist/ui/disclosure/index.d.ts.map +1 -1
- package/dist/ui/disclosure/index.js +57 -62
- package/dist/ui/disclosure/public.d.ts +2 -2
- package/dist/ui/disclosure/public.d.ts.map +1 -1
- package/dist/ui/disclosure/public.js +1 -1
- package/dist/ui/dragAndDrop/index.d.ts +385 -103
- package/dist/ui/dragAndDrop/index.d.ts.map +1 -1
- package/dist/ui/dragAndDrop/index.js +26 -31
- package/dist/ui/dragAndDrop/public.d.ts +1 -1
- package/dist/ui/dragAndDrop/public.d.ts.map +1 -1
- package/dist/ui/dragAndDrop/public.js +1 -1
- package/dist/ui/fileDrop/index.d.ts +42 -46
- package/dist/ui/fileDrop/index.d.ts.map +1 -1
- package/dist/ui/fileDrop/index.js +30 -46
- package/dist/ui/fileDrop/public.d.ts +2 -2
- package/dist/ui/fileDrop/public.d.ts.map +1 -1
- package/dist/ui/fileDrop/public.js +1 -1
- package/dist/ui/listbox/multi.d.ts +39 -84
- package/dist/ui/listbox/multi.d.ts.map +1 -1
- package/dist/ui/listbox/multi.js +38 -20
- package/dist/ui/listbox/multiPublic.d.ts +2 -2
- package/dist/ui/listbox/multiPublic.d.ts.map +1 -1
- package/dist/ui/listbox/multiPublic.js +1 -1
- package/dist/ui/listbox/public.d.ts +3 -3
- package/dist/ui/listbox/public.d.ts.map +1 -1
- package/dist/ui/listbox/public.js +2 -2
- package/dist/ui/listbox/shared.d.ts +71 -30
- package/dist/ui/listbox/shared.d.ts.map +1 -1
- package/dist/ui/listbox/shared.js +319 -296
- package/dist/ui/listbox/single.d.ts +57 -85
- package/dist/ui/listbox/single.d.ts.map +1 -1
- package/dist/ui/listbox/single.js +48 -24
- package/dist/ui/menu/index.d.ts +80 -36
- package/dist/ui/menu/index.d.ts.map +1 -1
- package/dist/ui/menu/index.js +117 -86
- package/dist/ui/menu/public.d.ts +2 -2
- package/dist/ui/menu/public.d.ts.map +1 -1
- package/dist/ui/menu/public.js +1 -1
- package/dist/ui/popover/index.d.ts +117 -44
- package/dist/ui/popover/index.d.ts.map +1 -1
- package/dist/ui/popover/index.js +88 -101
- package/dist/ui/popover/public.d.ts +2 -2
- package/dist/ui/popover/public.d.ts.map +1 -1
- package/dist/ui/popover/public.js +1 -1
- package/dist/ui/radioGroup/index.d.ts +122 -45
- package/dist/ui/radioGroup/index.d.ts.map +1 -1
- package/dist/ui/radioGroup/index.js +111 -72
- package/dist/ui/radioGroup/public.d.ts +2 -2
- package/dist/ui/radioGroup/public.d.ts.map +1 -1
- package/dist/ui/radioGroup/public.js +1 -1
- package/dist/ui/slider/index.d.ts +247 -103
- package/dist/ui/slider/index.d.ts.map +1 -1
- package/dist/ui/slider/index.js +52 -68
- package/dist/ui/slider/public.d.ts +2 -2
- package/dist/ui/slider/public.d.ts.map +1 -1
- package/dist/ui/slider/public.js +1 -1
- package/dist/ui/switch/index.d.ts +74 -21
- package/dist/ui/switch/index.d.ts.map +1 -1
- package/dist/ui/switch/index.js +62 -33
- package/dist/ui/switch/public.d.ts +2 -2
- package/dist/ui/switch/public.d.ts.map +1 -1
- package/dist/ui/switch/public.js +1 -1
- package/dist/ui/tabs/index.d.ts +107 -45
- package/dist/ui/tabs/index.d.ts.map +1 -1
- package/dist/ui/tabs/index.js +99 -81
- package/dist/ui/tabs/public.d.ts +2 -2
- package/dist/ui/tabs/public.d.ts.map +1 -1
- package/dist/ui/tabs/public.js +1 -1
- package/dist/ui/toast/index.d.ts +93 -109
- package/dist/ui/toast/index.d.ts.map +1 -1
- package/dist/ui/toast/index.js +16 -29
- package/dist/ui/toast/schema.d.ts +15 -4
- package/dist/ui/toast/schema.d.ts.map +1 -1
- package/dist/ui/toast/schema.js +11 -4
- package/dist/ui/toast/update.d.ts +36 -18
- package/dist/ui/toast/update.d.ts.map +1 -1
- package/dist/ui/toast/update.js +33 -14
- package/dist/ui/tooltip/index.d.ts +94 -42
- package/dist/ui/tooltip/index.d.ts.map +1 -1
- package/dist/ui/tooltip/index.js +64 -73
- package/dist/ui/tooltip/public.d.ts +2 -2
- package/dist/ui/tooltip/public.d.ts.map +1 -1
- package/dist/ui/tooltip/public.js +1 -1
- package/dist/ui/virtualList/index.d.ts +63 -80
- package/dist/ui/virtualList/index.d.ts.map +1 -1
- package/dist/ui/virtualList/index.js +22 -49
- package/dist/ui/virtualList/public.d.ts +2 -2
- package/dist/ui/virtualList/public.d.ts.map +1 -1
- package/dist/ui/virtualList/public.js +1 -1
- package/package.json +1 -1
package/dist/render/render.js
CHANGED
|
@@ -8,6 +8,10 @@ export type EnvelopedMessage<Message> = Readonly<{
|
|
|
8
8
|
* class. The runtime calls this on each `Queue.takeAll` batch so user input
|
|
9
9
|
* (view dispatch, navigation, subscription events, managed-resource events,
|
|
10
10
|
* external dispatchers) lands ahead of chain-derived work (Command results)
|
|
11
|
-
* whenever both share a frame.
|
|
11
|
+
* whenever both share a frame.
|
|
12
|
+
*
|
|
13
|
+
* Single-pass partition: walks the batch once and pushes each unwrapped
|
|
14
|
+
* message into either `highs` or `normals`, then concatenates. Avoids the
|
|
15
|
+
* four allocations of the previous filter/filter/appendAll/map chain. */
|
|
12
16
|
export declare const orderByPriority: <Message>(batch: ReadonlyArray<EnvelopedMessage<Message>>) => ReadonlyArray<Message>;
|
|
13
17
|
//# sourceMappingURL=messagePriority.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messagePriority.d.ts","sourceRoot":"","sources":["../../src/runtime/messagePriority.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAA;AAExC,MAAM,MAAM,gBAAgB,CAAC,OAAO,IAAI,QAAQ,CAAC;IAC/C,QAAQ,EAAE,QAAQ,CAAA;IAClB,OAAO,EAAE,OAAO,CAAA;CACjB,CAAC,CAAA;AAEF
|
|
1
|
+
{"version":3,"file":"messagePriority.d.ts","sourceRoot":"","sources":["../../src/runtime/messagePriority.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAA;AAExC,MAAM,MAAM,gBAAgB,CAAC,OAAO,IAAI,QAAQ,CAAC;IAC/C,QAAQ,EAAE,QAAQ,CAAA;IAClB,OAAO,EAAE,OAAO,CAAA;CACjB,CAAC,CAAA;AAEF;;;;;;;;;0EAS0E;AAC1E,eAAO,MAAM,eAAe,GAAI,OAAO,EACrC,OAAO,aAAa,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,KAC9C,aAAa,CAAC,OAAO,CAoBvB,CAAA"}
|
|
@@ -4,9 +4,30 @@ import { Array } from 'effect';
|
|
|
4
4
|
* class. The runtime calls this on each `Queue.takeAll` batch so user input
|
|
5
5
|
* (view dispatch, navigation, subscription events, managed-resource events,
|
|
6
6
|
* external dispatchers) lands ahead of chain-derived work (Command results)
|
|
7
|
-
* whenever both share a frame.
|
|
7
|
+
* whenever both share a frame.
|
|
8
|
+
*
|
|
9
|
+
* Single-pass partition: walks the batch once and pushes each unwrapped
|
|
10
|
+
* message into either `highs` or `normals`, then concatenates. Avoids the
|
|
11
|
+
* four allocations of the previous filter/filter/appendAll/map chain. */
|
|
8
12
|
export const orderByPriority = (batch) => {
|
|
9
|
-
const highs =
|
|
10
|
-
const normals =
|
|
11
|
-
|
|
13
|
+
const highs = [];
|
|
14
|
+
const normals = [];
|
|
15
|
+
for (const envelope of batch) {
|
|
16
|
+
if (envelope.priority === 'High') {
|
|
17
|
+
highs.push(envelope.message);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
normals.push(envelope.message);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (Array.isReadonlyArrayEmpty(normals)) {
|
|
24
|
+
return highs;
|
|
25
|
+
}
|
|
26
|
+
if (Array.isReadonlyArrayEmpty(highs)) {
|
|
27
|
+
return normals;
|
|
28
|
+
}
|
|
29
|
+
for (const message of normals) {
|
|
30
|
+
highs.push(message);
|
|
31
|
+
}
|
|
32
|
+
return highs;
|
|
12
33
|
};
|
|
@@ -94,19 +94,19 @@ export type CrashContext<Model, Message> = Readonly<{
|
|
|
94
94
|
model: Model;
|
|
95
95
|
message: Message;
|
|
96
96
|
}>;
|
|
97
|
-
/** Configuration for crash handling
|
|
97
|
+
/** Configuration for crash handling, with custom crash UI and/or crash reporting. */
|
|
98
98
|
export type CrashConfig<Model, Message> = Readonly<{
|
|
99
99
|
view?: (context: CrashContext<Model, Message>) => Document;
|
|
100
100
|
report?: (context: CrashContext<Model, Message>) => void;
|
|
101
101
|
}>;
|
|
102
|
-
type BaseProgramConfig<Model, Message,
|
|
102
|
+
type BaseProgramConfig<Model, Message, Resources = never, ManagedResourceServices = never> = Readonly<{
|
|
103
103
|
Model: Schema.Codec<Model, any, unknown, unknown>;
|
|
104
104
|
update: (model: Model, message: Message) => readonly [
|
|
105
105
|
Model,
|
|
106
106
|
ReadonlyArray<Command<Message, never, Resources | ManagedResourceServices>>
|
|
107
107
|
];
|
|
108
108
|
view: (model: Model) => Document;
|
|
109
|
-
subscriptions?: Subscriptions<Model, Message,
|
|
109
|
+
subscriptions?: Subscriptions<Model, Message, Resources | ManagedResourceServices>;
|
|
110
110
|
container: HTMLElement | null;
|
|
111
111
|
crash?: CrashConfig<Model, Message>;
|
|
112
112
|
slowView?: SlowViewConfig<Model, Message>;
|
|
@@ -116,7 +116,7 @@ type BaseProgramConfig<Model, Message, StreamDepsMap extends Schema.Struct<Schem
|
|
|
116
116
|
devTools?: DevToolsConfig;
|
|
117
117
|
}>;
|
|
118
118
|
/** Configuration for `makeProgram` with flags and URL routing. */
|
|
119
|
-
export type RoutingProgramConfigWithFlags<Model, Message,
|
|
119
|
+
export type RoutingProgramConfigWithFlags<Model, Message, Flags, Resources = never, ManagedResourceServices = never> = BaseProgramConfig<Model, Message, Resources, ManagedResourceServices> & Readonly<{
|
|
120
120
|
Flags: Schema.Codec<Flags, any, unknown, unknown>;
|
|
121
121
|
flags: Effect.Effect<Flags>;
|
|
122
122
|
routing: RoutingConfig<Message>;
|
|
@@ -126,7 +126,7 @@ export type RoutingProgramConfigWithFlags<Model, Message, StreamDepsMap extends
|
|
|
126
126
|
];
|
|
127
127
|
}>;
|
|
128
128
|
/** Configuration for `makeProgram` with URL routing but no flags. */
|
|
129
|
-
export type RoutingProgramConfig<Model, Message,
|
|
129
|
+
export type RoutingProgramConfig<Model, Message, Resources = never, ManagedResourceServices = never> = BaseProgramConfig<Model, Message, Resources, ManagedResourceServices> & Readonly<{
|
|
130
130
|
routing: RoutingConfig<Message>;
|
|
131
131
|
init: (url: Url) => readonly [
|
|
132
132
|
Model,
|
|
@@ -134,7 +134,7 @@ export type RoutingProgramConfig<Model, Message, StreamDepsMap extends Schema.St
|
|
|
134
134
|
];
|
|
135
135
|
}>;
|
|
136
136
|
/** Configuration for `makeProgram` with flags but no URL routing. */
|
|
137
|
-
export type ProgramConfigWithFlags<Model, Message,
|
|
137
|
+
export type ProgramConfigWithFlags<Model, Message, Flags, Resources = never, ManagedResourceServices = never> = BaseProgramConfig<Model, Message, Resources, ManagedResourceServices> & Readonly<{
|
|
138
138
|
Flags: Schema.Codec<Flags, any, unknown, unknown>;
|
|
139
139
|
flags: Effect.Effect<Flags>;
|
|
140
140
|
init: (flags: Flags) => readonly [
|
|
@@ -143,7 +143,7 @@ export type ProgramConfigWithFlags<Model, Message, StreamDepsMap extends Schema.
|
|
|
143
143
|
];
|
|
144
144
|
}>;
|
|
145
145
|
/** Configuration for `makeProgram` without flags or URL routing. */
|
|
146
|
-
export type ProgramConfig<Model, Message,
|
|
146
|
+
export type ProgramConfig<Model, Message, Resources = never, ManagedResourceServices = never> = BaseProgramConfig<Model, Message, Resources, ManagedResourceServices> & Readonly<{
|
|
147
147
|
init: () => readonly [
|
|
148
148
|
Model,
|
|
149
149
|
ReadonlyArray<Command<Message, never, Resources | ManagedResourceServices>>
|
|
@@ -173,16 +173,16 @@ export type MakeRuntimeReturn = Readonly<{
|
|
|
173
173
|
/** Creates a Foldkit program and returns a runtime that can be passed to `run`. Add a `routing` config for URL routing. */
|
|
174
174
|
export declare function makeProgram<Model, Message extends {
|
|
175
175
|
_tag: string;
|
|
176
|
-
},
|
|
176
|
+
}, Flags, Resources = never, ManagedResourceServices = never>(config: RoutingProgramConfigWithFlags<Model, Message, Flags, Resources, ManagedResourceServices>): MakeRuntimeReturn;
|
|
177
177
|
export declare function makeProgram<Model, Message extends {
|
|
178
178
|
_tag: string;
|
|
179
|
-
},
|
|
179
|
+
}, Resources = never, ManagedResourceServices = never>(config: RoutingProgramConfig<Model, Message, Resources, ManagedResourceServices>): MakeRuntimeReturn;
|
|
180
180
|
export declare function makeProgram<Model, Message extends {
|
|
181
181
|
_tag: string;
|
|
182
|
-
},
|
|
182
|
+
}, Flags, Resources = never, ManagedResourceServices = never>(config: ProgramConfigWithFlags<Model, Message, Flags, Resources, ManagedResourceServices>): MakeRuntimeReturn;
|
|
183
183
|
export declare function makeProgram<Model, Message extends {
|
|
184
184
|
_tag: string;
|
|
185
|
-
},
|
|
185
|
+
}, Resources = never, ManagedResourceServices = never>(config: ProgramConfig<Model, Message, Resources, ManagedResourceServices>): MakeRuntimeReturn;
|
|
186
186
|
/** Starts a Foldkit runtime, with HMR support for development. */
|
|
187
187
|
export declare const run: (program: MakeRuntimeReturn) => void;
|
|
188
188
|
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/runtime.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,OAAO,EAEP,MAAM,EAGN,KAAK,EAEL,MAAM,EAON,MAAM,EAIP,MAAM,QAAQ,CAAA;AAGf,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AASlD,OAAO,
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/runtime.ts"],"names":[],"mappings":"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"}
|
package/dist/runtime/runtime.js
CHANGED
|
@@ -4,6 +4,7 @@ import { h } from 'snabbdom';
|
|
|
4
4
|
import { createOverlay } from '../devTools/overlay.js';
|
|
5
5
|
import { createDevToolsStore, } from '../devTools/store.js';
|
|
6
6
|
import { startWebSocketBridge } from '../devTools/webSocketBridge.js';
|
|
7
|
+
import { __beginRender as beginHtmlRender, __clearRuntime as clearHtmlRuntime, __createBoundaryRegistry as createHtmlBoundaryRegistry, __setRuntime as setHtmlRuntime, } from '../html/index.js';
|
|
7
8
|
import { MountTracker } from '../mount/index.js';
|
|
8
9
|
import { fromString as urlFromString } from '../url/index.js';
|
|
9
10
|
import { patch, toVNode } from '../vdom.js';
|
|
@@ -66,12 +67,6 @@ const makeRuntime = ({ Model, flags: resolveFlags, init, update, view, subscript
|
|
|
66
67
|
// current burst exceeds FRAME_BUDGET_MS so the browser gets a frame.
|
|
67
68
|
// setTimeout(0) is clamped to 4ms+; MessageChannel delivers in ~0.5ms.
|
|
68
69
|
const FRAME_BUDGET_MS = 5;
|
|
69
|
-
const yieldToBrowser = Effect.callback(resume => {
|
|
70
|
-
const channel = new MessageChannel();
|
|
71
|
-
channel.port2.onmessage = () => resume(Effect.void);
|
|
72
|
-
channel.port1.postMessage(null);
|
|
73
|
-
return Effect.sync(() => channel.port2.close());
|
|
74
|
-
});
|
|
75
70
|
// NOTE: render coalescing relies on this firing once per frame. Multiple
|
|
76
71
|
// Messages dispatched between frames all flag the renderLoop dirty; the
|
|
77
72
|
// next rAF tick reads the latest model and renders once. Without this,
|
|
@@ -87,7 +82,39 @@ const makeRuntime = ({ Model, flags: resolveFlags, init, update, view, subscript
|
|
|
87
82
|
return yield* Effect.die(new Error('[foldkit] Runtime container must have an `id` for HMR model preservation. ' +
|
|
88
83
|
'Set `container.id = "app"` (or any unique string) before passing it to makeProgram.'));
|
|
89
84
|
}
|
|
85
|
+
// NOTE: one persistent MessageChannel for the runtime lifetime,
|
|
86
|
+
// shared by every burst-budget yield. The queue-drain fiber is the
|
|
87
|
+
// sole consumer, so a single `pendingYieldResume` slot is sufficient.
|
|
88
|
+
const yieldChannel = yield* Effect.acquireRelease(Effect.sync(() => new MessageChannel()), channel => Effect.sync(() => {
|
|
89
|
+
channel.port1.close();
|
|
90
|
+
channel.port2.close();
|
|
91
|
+
}));
|
|
92
|
+
let pendingYieldResume = null;
|
|
93
|
+
yieldChannel.port2.onmessage = () => {
|
|
94
|
+
const resume = pendingYieldResume;
|
|
95
|
+
pendingYieldResume = null;
|
|
96
|
+
if (resume !== null) {
|
|
97
|
+
resume(Effect.void);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
const yieldToBrowser = Effect.callback(resume => {
|
|
101
|
+
pendingYieldResume = resume;
|
|
102
|
+
yieldChannel.port1.postMessage(null);
|
|
103
|
+
return Effect.sync(() => {
|
|
104
|
+
if (pendingYieldResume === resume) {
|
|
105
|
+
pendingYieldResume = null;
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
});
|
|
90
109
|
const maybeResourceLayer = Option.fromNullishOr(resources);
|
|
110
|
+
// NOTE: One boundary registry per runtime instance, shared
|
|
111
|
+
// across renders so Submodel wrap descriptors registered by
|
|
112
|
+
// h.submodel persist between renders. The render function calls
|
|
113
|
+
// `beginHtmlRender` at the start of each pass; wraps for
|
|
114
|
+
// unmounted Submodels (e.g. an entry removed from a list) are
|
|
115
|
+
// dropped from the registry via snabbdom destroy hooks attached
|
|
116
|
+
// by `h.submodel` to each child vnode.
|
|
117
|
+
const boundaryRegistry = createHtmlBoundaryRegistry();
|
|
91
118
|
const managedResourceEntries = managedResources
|
|
92
119
|
? /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
|
|
93
120
|
Record.toEntries(managedResources)
|
|
@@ -181,8 +208,19 @@ const makeRuntime = ({ Model, flags: resolveFlags, init, update, view, subscript
|
|
|
181
208
|
}
|
|
182
209
|
const modelRef = yield* Ref.make(initModel);
|
|
183
210
|
const maybeCurrentVNodeRef = yield* Ref.make(Option.none());
|
|
184
|
-
|
|
185
|
-
|
|
211
|
+
// NOTE: queue-drain-fiber-local state. Kept as plain closure
|
|
212
|
+
// variables instead of `Ref`s because nothing else reads or writes
|
|
213
|
+
// them concurrently, and JS's single-threaded model already orders
|
|
214
|
+
// writes against subsequent reads. `currentMessage` is read by the
|
|
215
|
+
// crash handler, which runs inside the same `forever` fiber via
|
|
216
|
+
// `Effect.catchCause`.
|
|
217
|
+
let currentMessage = Option.none();
|
|
218
|
+
let burstStartedAt = 0;
|
|
219
|
+
// NOTE: the DevTools store is installed at most once during boot and
|
|
220
|
+
// never replaced. Caching it in a closure variable avoids a
|
|
221
|
+
// `Ref.get` on every message and on every render-loop tick (the
|
|
222
|
+
// store powers `isPausedEffect`).
|
|
223
|
+
let maybeDevToolsStore = Option.none();
|
|
186
224
|
const dispatchSync = (message) => {
|
|
187
225
|
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
|
|
188
226
|
enqueueHighUnsafe(message);
|
|
@@ -193,13 +231,10 @@ const makeRuntime = ({ Model, flags: resolveFlags, init, update, view, subscript
|
|
|
193
231
|
const dispatch = { dispatchAsync, dispatchSync };
|
|
194
232
|
const isRenderPendingRef = yield* SubscriptionRef.make(false);
|
|
195
233
|
const lastDirtyMessageRef = yield* Ref.make(Option.none());
|
|
196
|
-
const isPausedEffect = Effect.
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
onSome: ({ stateRef }) => SubscriptionRef.get(stateRef).pipe(Effect.map(({ isPaused }) => isPaused)),
|
|
201
|
-
});
|
|
202
|
-
});
|
|
234
|
+
const isPausedEffect = Effect.suspend(() => Option.match(maybeDevToolsStore, {
|
|
235
|
+
onNone: () => Effect.succeed(false),
|
|
236
|
+
onSome: ({ stateRef }) => SubscriptionRef.get(stateRef).pipe(Effect.map(({ isPaused }) => isPaused)),
|
|
237
|
+
}));
|
|
203
238
|
const mountStartBuffer = [];
|
|
204
239
|
const mountEndBuffer = [];
|
|
205
240
|
const mountTracker = {
|
|
@@ -228,32 +263,30 @@ const makeRuntime = ({ Model, flags: resolveFlags, init, update, view, subscript
|
|
|
228
263
|
PubSub.publishUnsafe(modelPubSub, nextModel);
|
|
229
264
|
yield* schedulePreserveModel(nextModel);
|
|
230
265
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
266
|
+
if (!Array.isReadonlyArrayEmpty(commands)) {
|
|
267
|
+
yield* Effect.forEach(
|
|
268
|
+
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
|
|
269
|
+
commands, command => Effect.forkDetach(command.effect.pipe(Effect.withSpan(command.name, {
|
|
270
|
+
attributes: command.args ?? {},
|
|
271
|
+
}), provideAllResources, Effect.flatMap(enqueueNormal))));
|
|
272
|
+
}
|
|
237
273
|
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
|
|
238
274
|
const messageTag = message._tag;
|
|
239
275
|
const isModelChanged = currentModel !== nextModel;
|
|
240
276
|
const isExcludedFromHistory = excludeFromHistoryTags.has(messageTag);
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
return Effect.void;
|
|
255
|
-
},
|
|
256
|
-
});
|
|
277
|
+
if (Option.isSome(maybeDevToolsStore)) {
|
|
278
|
+
const store = maybeDevToolsStore.value;
|
|
279
|
+
if (!isExcludedFromHistory) {
|
|
280
|
+
yield* store.recordMessage(
|
|
281
|
+
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
|
|
282
|
+
message, currentModel, nextModel, Array.map(
|
|
283
|
+
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
|
|
284
|
+
commands, toCommandRecord), isModelChanged);
|
|
285
|
+
}
|
|
286
|
+
else if (isModelChanged) {
|
|
287
|
+
yield* store.updateLatestModel(nextModel);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
257
290
|
});
|
|
258
291
|
// NOTE: `dispatchService` defaults to the live dispatch but is
|
|
259
292
|
// overridable so the DevTools jumpTo render path can pass
|
|
@@ -264,9 +297,18 @@ const makeRuntime = ({ Model, flags: resolveFlags, init, update, view, subscript
|
|
|
264
297
|
// This prevents mount-derived Messages from polluting history when
|
|
265
298
|
// the user is just inspecting past state.
|
|
266
299
|
const render = (model, message, dispatchService = dispatch) => Effect.gen(function* () {
|
|
300
|
+
const runtimeContext = yield* Effect.context();
|
|
267
301
|
const viewStart = performance.now();
|
|
268
|
-
|
|
269
|
-
|
|
302
|
+
beginHtmlRender(boundaryRegistry);
|
|
303
|
+
setHtmlRuntime(dispatchService.dispatchSync, runtimeContext, boundaryRegistry);
|
|
304
|
+
let nextDocument;
|
|
305
|
+
try {
|
|
306
|
+
nextDocument = view(model);
|
|
307
|
+
}
|
|
308
|
+
finally {
|
|
309
|
+
clearHtmlRuntime();
|
|
310
|
+
}
|
|
311
|
+
const nextVNode = nextDocument.body;
|
|
270
312
|
const viewDuration = performance.now() - viewStart;
|
|
271
313
|
Option.match(resolvedSlowView, {
|
|
272
314
|
onNone: Function.constVoid,
|
|
@@ -282,7 +324,7 @@ const makeRuntime = ({ Model, flags: resolveFlags, init, update, view, subscript
|
|
|
282
324
|
},
|
|
283
325
|
});
|
|
284
326
|
const maybeCurrentVNode = yield* Ref.get(maybeCurrentVNodeRef);
|
|
285
|
-
const patchedVNode = yield* Effect.sync(() => patchVNode(maybeCurrentVNode,
|
|
327
|
+
const patchedVNode = yield* Effect.sync(() => patchVNode(maybeCurrentVNode, nextVNode, container));
|
|
286
328
|
yield* Ref.set(maybeCurrentVNodeRef, Option.some(patchedVNode));
|
|
287
329
|
yield* Effect.sync(() => applyDocumentMetadata(nextDocument, patchedVNode.elm));
|
|
288
330
|
}).pipe(Effect.provideService(Dispatch, dispatchService), Effect.provideService(MountTracker, mountTracker));
|
|
@@ -296,7 +338,7 @@ const makeRuntime = ({ Model, flags: resolveFlags, init, update, view, subscript
|
|
|
296
338
|
const { position, mode, maybeBanner } = resolvedDevTools.value;
|
|
297
339
|
// NOTE: when excludeFromHistory is active, the runtime drops
|
|
298
340
|
// excluded Messages from the recorded history. Replay walks the
|
|
299
|
-
// recorded entries forward from the nearest keyframe
|
|
341
|
+
// recorded entries forward from the nearest keyframe. With
|
|
300
342
|
// exclusion, the dropped Messages aren't in that walk, so any
|
|
301
343
|
// cumulative state they would have produced is missing from the
|
|
302
344
|
// replayed model. Setting keyframeInterval to 1 stores a full
|
|
@@ -337,7 +379,7 @@ const makeRuntime = ({ Model, flags: resolveFlags, init, update, view, subscript
|
|
|
337
379
|
maxEntries: devToolsMaxEntries,
|
|
338
380
|
}),
|
|
339
381
|
});
|
|
340
|
-
|
|
382
|
+
maybeDevToolsStore = Option.some(devToolsStore);
|
|
341
383
|
// The init render runs below; capture the events it produces. We
|
|
342
384
|
// record init AFTER that render so the buffer reflects the mounts
|
|
343
385
|
// that fired on the first paint.
|
|
@@ -355,8 +397,7 @@ const makeRuntime = ({ Model, flags: resolveFlags, init, update, view, subscript
|
|
|
355
397
|
}
|
|
356
398
|
yield* render(initModel, Option.none());
|
|
357
399
|
const initMountEvents = drainMountEvents();
|
|
358
|
-
|
|
359
|
-
yield* Option.match(maybeStoreForInit, {
|
|
400
|
+
yield* Option.match(maybeDevToolsStore, {
|
|
360
401
|
onNone: () => Effect.void,
|
|
361
402
|
onSome: store => store.recordInit(initModel, Array.map(initCommands, toCommandRecord), initMountEvents.starts),
|
|
362
403
|
});
|
|
@@ -375,8 +416,7 @@ const makeRuntime = ({ Model, flags: resolveFlags, init, update, view, subscript
|
|
|
375
416
|
const maybeMessage = yield* Ref.get(lastDirtyMessageRef);
|
|
376
417
|
yield* render(model, maybeMessage);
|
|
377
418
|
const mountEvents = drainMountEvents();
|
|
378
|
-
|
|
379
|
-
yield* Option.match(maybeStore, {
|
|
419
|
+
yield* Option.match(maybeDevToolsStore, {
|
|
380
420
|
onNone: () => Effect.void,
|
|
381
421
|
onSome: store => store.attachRenderedMounts(mountEvents.starts, mountEvents.ends),
|
|
382
422
|
});
|
|
@@ -385,9 +425,10 @@ const makeRuntime = ({ Model, flags: resolveFlags, init, update, view, subscript
|
|
|
385
425
|
yield* Effect.forkDetach(renderLoop);
|
|
386
426
|
addBfcacheRestoreListener();
|
|
387
427
|
if (subscriptions) {
|
|
388
|
-
yield* pipe(subscriptions, Record.toEntries, Effect.forEach(([_key, {
|
|
428
|
+
yield* pipe(subscriptions, Record.toEntries, Effect.forEach(([_key, { dependenciesSchema, modelToDependencies, keepAliveEquivalence, dependenciesToStream, },]) => Effect.gen(function* () {
|
|
389
429
|
const latestDependenciesRef = yield* Ref.make(modelToDependencies(initModel));
|
|
390
|
-
const equivalence =
|
|
430
|
+
const equivalence = keepAliveEquivalence ??
|
|
431
|
+
Schema.toEquivalence(dependenciesSchema);
|
|
391
432
|
const modelStream = Stream.concat(Stream.make(initModel), Stream.fromPubSub(modelPubSub));
|
|
392
433
|
yield* Effect.forkDetach(modelStream.pipe(
|
|
393
434
|
// NOTE: Ref.set runs upstream of Stream.changesWith on
|
|
@@ -438,16 +479,14 @@ const makeRuntime = ({ Model, flags: resolveFlags, init, update, view, subscript
|
|
|
438
479
|
concurrency: 'unbounded',
|
|
439
480
|
discard: true,
|
|
440
481
|
});
|
|
441
|
-
const burstStartedAtRef = yield* Ref.make(0);
|
|
442
482
|
const processWithBudget = (message) => Effect.gen(function* () {
|
|
443
|
-
|
|
483
|
+
currentMessage = Option.some(message);
|
|
444
484
|
yield* processMessage(message);
|
|
445
|
-
const burstStartedAt = yield* Ref.get(burstStartedAtRef);
|
|
446
485
|
if (performance.now() - burstStartedAt < FRAME_BUDGET_MS) {
|
|
447
486
|
return;
|
|
448
487
|
}
|
|
449
488
|
yield* yieldToBrowser;
|
|
450
|
-
|
|
489
|
+
burstStartedAt = performance.now();
|
|
451
490
|
});
|
|
452
491
|
const processBatch = (batch) => Effect.forEach(orderByPriority(batch), processWithBudget, {
|
|
453
492
|
discard: true,
|
|
@@ -487,7 +526,7 @@ const makeRuntime = ({ Model, flags: resolveFlags, init, update, view, subscript
|
|
|
487
526
|
const first = yield* Option.match(maybeFirst, {
|
|
488
527
|
onNone: () => Effect.gen(function* () {
|
|
489
528
|
const message = yield* Queue.take(messageQueue);
|
|
490
|
-
|
|
529
|
+
burstStartedAt = performance.now();
|
|
491
530
|
return message;
|
|
492
531
|
}),
|
|
493
532
|
onSome: Effect.succeed,
|
|
@@ -501,7 +540,7 @@ const makeRuntime = ({ Model, flags: resolveFlags, init, update, view, subscript
|
|
|
501
540
|
? squashed
|
|
502
541
|
: new Error(String(squashed));
|
|
503
542
|
const model = Effect.runSync(Ref.get(modelRef));
|
|
504
|
-
const message =
|
|
543
|
+
const message = Option.getOrThrow(currentMessage);
|
|
505
544
|
renderCrashView({ error: appError, model, message }, crash, container, maybeCurrentVNodeRef);
|
|
506
545
|
})));
|
|
507
546
|
}));
|
|
@@ -555,22 +594,38 @@ const renderCrashView = (context, crash, container, maybeCurrentVNodeRef) => {
|
|
|
555
594
|
console.error('[foldkit] crash.report failed:', reportError);
|
|
556
595
|
}
|
|
557
596
|
}
|
|
597
|
+
const crashContext = Context.make(Dispatch, noOpDispatch).pipe(Context.add(MountTracker, {
|
|
598
|
+
started: () => { },
|
|
599
|
+
ended: () => { },
|
|
600
|
+
}));
|
|
558
601
|
try {
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
602
|
+
setHtmlRuntime(noOpDispatch.dispatchSync, crashContext);
|
|
603
|
+
let crashDocument;
|
|
604
|
+
try {
|
|
605
|
+
crashDocument = crash?.view
|
|
606
|
+
? crash.view(context)
|
|
607
|
+
: defaultCrashView(context);
|
|
608
|
+
}
|
|
609
|
+
finally {
|
|
610
|
+
clearHtmlRuntime();
|
|
611
|
+
}
|
|
562
612
|
const maybeCurrentVNode = Effect.runSync(Ref.get(maybeCurrentVNodeRef));
|
|
563
|
-
const
|
|
564
|
-
const patchedVNode = patchVNode(maybeCurrentVNode, vnode, container);
|
|
613
|
+
const patchedVNode = patchVNode(maybeCurrentVNode, crashDocument.body, container);
|
|
565
614
|
applyDocumentMetadata(crashDocument, patchedVNode.elm);
|
|
566
615
|
}
|
|
567
616
|
catch (viewError) {
|
|
568
617
|
console.error('[foldkit] crash.view failed:', viewError);
|
|
569
|
-
const maybeCurrentVNode = Effect.runSync(Ref.get(maybeCurrentVNodeRef));
|
|
570
618
|
const fallbackViewError = viewError instanceof Error ? viewError : new Error(String(viewError));
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
619
|
+
setHtmlRuntime(noOpDispatch.dispatchSync, crashContext);
|
|
620
|
+
let fallbackDocument;
|
|
621
|
+
try {
|
|
622
|
+
fallbackDocument = defaultCrashView(context, fallbackViewError);
|
|
623
|
+
}
|
|
624
|
+
finally {
|
|
625
|
+
clearHtmlRuntime();
|
|
626
|
+
}
|
|
627
|
+
const maybeCurrentVNode = Effect.runSync(Ref.get(maybeCurrentVNodeRef));
|
|
628
|
+
const patchedVNode = patchVNode(maybeCurrentVNode, fallbackDocument.body, container);
|
|
574
629
|
applyDocumentMetadata(fallbackDocument, patchedVNode.elm);
|
|
575
630
|
}
|
|
576
631
|
};
|