foldkit 0.156.0 → 0.157.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 -3
- package/dist/asyncData/asyncData.d.ts +7 -7
- package/dist/asyncData/asyncData.d.ts.map +1 -1
- package/dist/asyncData/asyncData.js +12 -12
- package/dist/calendar/calendarDate.d.ts +15 -15
- package/dist/calendar/calendarDate.d.ts.map +1 -1
- package/dist/calendar/calendarDate.js +14 -14
- package/dist/calendar/comparison.d.ts +2 -2
- package/dist/calendar/comparison.d.ts.map +1 -1
- package/dist/calendar/comparison.js +5 -5
- package/dist/calendar/info.d.ts +2 -2
- package/dist/calendar/info.d.ts.map +1 -1
- package/dist/calendar/info.js +2 -2
- package/dist/calendar/locale.d.ts +7 -7
- package/dist/calendar/locale.d.ts.map +1 -1
- package/dist/calendar/locale.js +23 -23
- package/dist/canvas/shape.d.ts +89 -89
- package/dist/canvas/shape.d.ts.map +1 -1
- package/dist/canvas/shape.js +65 -53
- package/dist/command/index.d.ts +3 -3
- package/dist/customElement/index.d.ts +2 -2
- package/dist/customElement/index.js +2 -2
- package/dist/devTools/protocol.d.ts +278 -278
- package/dist/devTools/protocol.d.ts.map +1 -1
- package/dist/devTools/protocol.js +98 -92
- package/dist/devTools/schemaSummarize.d.ts.map +1 -1
- package/dist/devTools/schemaSummarize.js +24 -24
- package/dist/devTools/serialize.d.ts +1 -1
- package/dist/devTools/serialize.d.ts.map +1 -1
- package/dist/devTools/serialize.js +10 -10
- package/dist/devTools/store.d.ts.map +1 -1
- package/dist/devTools/store.js +52 -28
- package/dist/devTools/submodelPath.d.ts.map +1 -1
- package/dist/devTools/submodelPath.js +3 -3
- package/dist/devTools/summarize.d.ts +6 -6
- package/dist/devTools/summarize.d.ts.map +1 -1
- package/dist/devTools/summarize.js +13 -13
- package/dist/devTools/webSocketBridge.d.ts +3 -3
- package/dist/devTools/webSocketBridge.d.ts.map +1 -1
- package/dist/devTools/webSocketBridge.js +8 -8
- package/dist/dom/dom.d.ts +2 -0
- package/dist/dom/dom.d.ts.map +1 -1
- package/dist/dom/dom.js +47 -13
- package/dist/experimental/machine/machine.d.ts +29 -6
- package/dist/experimental/machine/machine.d.ts.map +1 -1
- package/dist/experimental/machine/machine.js +9 -8
- package/dist/experimental/server/entry.js +2 -2
- package/dist/experimental/server/serialize.js +2 -2
- package/dist/experimental/server/server.js +4 -4
- package/dist/fieldValidation/fieldValidation.d.ts +12 -12
- package/dist/fieldValidation/fieldValidation.d.ts.map +1 -1
- package/dist/fieldValidation/fieldValidation.js +9 -9
- package/dist/fieldValidation/rule.d.ts +2 -2
- package/dist/fieldValidation/rule.d.ts.map +1 -1
- package/dist/fieldValidation/rule.js +6 -6
- package/dist/file/file.d.ts +3 -3
- package/dist/file/file.d.ts.map +1 -1
- package/dist/file/file.js +3 -3
- package/dist/html/boundary.d.ts +93 -36
- package/dist/html/boundary.d.ts.map +1 -1
- package/dist/html/boundary.js +242 -75
- package/dist/html/childAttribute.d.ts +6 -4
- package/dist/html/childAttribute.d.ts.map +1 -1
- package/dist/html/childAttribute.js +7 -1
- package/dist/html/index.d.ts +31 -16
- package/dist/html/index.d.ts.map +1 -1
- package/dist/html/index.js +97 -40
- package/dist/html/lazy.d.ts +6 -6
- package/dist/html/lazy.d.ts.map +1 -1
- package/dist/html/lazy.js +37 -15
- package/dist/html/public.d.ts +1 -1
- package/dist/html/public.d.ts.map +1 -1
- package/dist/html/runtimeSingleton.d.ts +27 -6
- package/dist/html/runtimeSingleton.d.ts.map +1 -1
- package/dist/html/runtimeSingleton.js +46 -29
- package/dist/html/submodel.d.ts.map +1 -1
- package/dist/html/submodel.js +28 -39
- package/dist/http/http.d.ts +1 -1
- package/dist/http/http.js +1 -1
- package/dist/managedResource/managedResource.d.ts +5 -5
- package/dist/managedResource/managedResource.js +3 -3
- package/dist/mount/index.d.ts +92 -39
- package/dist/mount/index.d.ts.map +1 -1
- package/dist/mount/index.js +28 -8
- package/dist/mount/public.d.ts +1 -1
- package/dist/mount/public.d.ts.map +1 -1
- package/dist/mount/public.js +1 -1
- package/dist/navigation/urlRequest.d.ts +9 -9
- package/dist/navigation/urlRequest.d.ts.map +1 -1
- package/dist/navigation/urlRequest.js +2 -2
- package/dist/onUnmountModule.d.ts +19 -0
- package/dist/onUnmountModule.d.ts.map +1 -0
- package/dist/onUnmountModule.js +80 -0
- package/dist/port/port.d.ts +5 -5
- package/dist/port/port.js +5 -5
- package/dist/route/parser.d.ts +2 -2
- package/dist/route/parser.js +2 -2
- package/dist/runtime/hmrProtocol.d.ts +10 -10
- package/dist/runtime/hmrProtocol.d.ts.map +1 -1
- package/dist/runtime/hmrProtocol.js +10 -10
- package/dist/runtime/runtime.d.ts +4 -4
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +168 -51
- package/dist/schema/index.d.ts +41 -29
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +9 -9
- package/dist/snabbdom/init.d.ts +1 -1
- package/dist/snabbdom/init.d.ts.map +1 -1
- package/dist/snabbdom/init.js +5 -1
- package/dist/snabbdom/vnode.d.ts +1 -0
- package/dist/snabbdom/vnode.d.ts.map +1 -1
- package/dist/snabbdom/vnode.js +1 -0
- package/dist/subscription/animationFrame.d.ts +3 -3
- package/dist/subscription/animationFrame.d.ts.map +1 -1
- package/dist/subscription/animationFrame.js +2 -2
- package/dist/subscription/fromEvent.d.ts +2 -2
- package/dist/subscription/fromEvent.js +2 -2
- package/dist/subscription/subscription.d.ts +3 -3
- package/dist/subscription/subscription.js +1 -1
- package/dist/test/apps/bubbling.d.ts +6 -6
- package/dist/test/apps/bubbling.d.ts.map +1 -1
- package/dist/test/apps/bubbling.js +6 -6
- package/dist/test/apps/colorPicker.d.ts +7 -7
- package/dist/test/apps/colorPicker.d.ts.map +1 -1
- package/dist/test/apps/colorPicker.js +5 -5
- package/dist/test/apps/contextMenu.d.ts +5 -5
- package/dist/test/apps/contextMenu.d.ts.map +1 -1
- package/dist/test/apps/contextMenu.js +4 -4
- package/dist/test/apps/counter.d.ts +8 -8
- package/dist/test/apps/counter.d.ts.map +1 -1
- package/dist/test/apps/counter.js +8 -8
- package/dist/test/apps/crashOnRender.d.ts +18 -18
- package/dist/test/apps/crashOnRender.d.ts.map +1 -1
- package/dist/test/apps/crashOnRender.js +11 -11
- package/dist/test/apps/drafts.d.ts +9 -9
- package/dist/test/apps/drafts.d.ts.map +1 -1
- package/dist/test/apps/drafts.js +6 -6
- package/dist/test/apps/feedSocket.d.ts +6 -6
- package/dist/test/apps/feedSocket.d.ts.map +1 -1
- package/dist/test/apps/feedSocket.js +8 -8
- package/dist/test/apps/fileUpload.d.ts +2 -2
- package/dist/test/apps/fileUpload.d.ts.map +1 -1
- package/dist/test/apps/fileUpload.js +2 -2
- package/dist/test/apps/focusBoundary.d.ts +3 -3
- package/dist/test/apps/focusBoundary.d.ts.map +1 -1
- package/dist/test/apps/focusBoundary.js +3 -3
- package/dist/test/apps/formChild.d.ts +11 -11
- package/dist/test/apps/formChild.d.ts.map +1 -1
- package/dist/test/apps/formChild.js +13 -12
- package/dist/test/apps/interactions.d.ts +8 -8
- package/dist/test/apps/interactions.d.ts.map +1 -1
- package/dist/test/apps/interactions.js +8 -8
- package/dist/test/apps/keypress.d.ts +6 -6
- package/dist/test/apps/keypress.d.ts.map +1 -1
- package/dist/test/apps/keypress.js +6 -6
- package/dist/test/apps/login.d.ts +11 -11
- package/dist/test/apps/login.d.ts.map +1 -1
- package/dist/test/apps/login.js +15 -15
- package/dist/test/apps/logoutButton.d.ts +3 -3
- package/dist/test/apps/logoutButton.d.ts.map +1 -1
- package/dist/test/apps/logoutButton.js +2 -2
- package/dist/test/apps/mountPanel.d.ts +9 -9
- package/dist/test/apps/mountPanel.d.ts.map +1 -1
- package/dist/test/apps/mountPanel.js +9 -9
- package/dist/test/apps/multiRole.d.ts +3 -3
- package/dist/test/apps/multiRole.d.ts.map +1 -1
- package/dist/test/apps/multiRole.js +2 -2
- package/dist/test/apps/pointer.d.ts +7 -7
- package/dist/test/apps/pointer.d.ts.map +1 -1
- package/dist/test/apps/pointer.js +7 -7
- package/dist/test/apps/resumeUpload.d.ts +8 -8
- package/dist/test/apps/resumeUpload.d.ts.map +1 -1
- package/dist/test/apps/resumeUpload.js +7 -7
- package/dist/test/apps/scorePanel.d.ts +3 -3
- package/dist/test/apps/scorePanel.d.ts.map +1 -1
- package/dist/test/apps/scorePanel.js +2 -2
- package/dist/test/apps/selectiveKeys.d.ts +3 -3
- package/dist/test/apps/selectiveKeys.d.ts.map +1 -1
- package/dist/test/apps/selectiveKeys.js +3 -3
- package/dist/test/apps/uploads.d.ts +18 -18
- package/dist/test/apps/uploads.d.ts.map +1 -1
- package/dist/test/apps/uploads.js +13 -13
- package/dist/test/matchers.d.ts.map +1 -1
- package/dist/test/matchers.js +4 -4
- package/dist/test/query.d.ts.map +1 -1
- package/dist/test/query.js +28 -28
- package/dist/test/scene.d.ts +37 -8
- package/dist/test/scene.d.ts.map +1 -1
- package/dist/test/scene.js +58 -15
- package/dist/test/story.d.ts +35 -8
- package/dist/test/story.d.ts.map +1 -1
- package/dist/test/story.js +44 -22
- package/dist/update/update.d.ts +17 -20
- package/dist/update/update.d.ts.map +1 -1
- package/dist/url/index.d.ts +8 -8
- package/dist/url/index.d.ts.map +1 -1
- package/dist/url/index.js +19 -19
- package/dist/vdom.d.ts +3 -2
- package/dist/vdom.d.ts.map +1 -1
- package/dist/vdom.js +16 -6
- package/package.json +1 -1
package/dist/html/lazy.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { type VNode } from '../vdom.js';
|
|
2
2
|
/** Creates a memoization slot for a view function. On each render, if the
|
|
3
|
-
* function reference,
|
|
4
|
-
*
|
|
3
|
+
* function reference, dispatchers, Mount render owner, and all arguments are
|
|
4
|
+
* equal to the previous call, the cached VNode is returned without
|
|
5
5
|
* re-running the view function. Snabbdom's `patchVnode` short-circuits when
|
|
6
6
|
* it sees the same VNode reference, so both VNode construction and subtree
|
|
7
7
|
* diffing are skipped.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* Dispatchers and Mount render ownership are part of the cache key because
|
|
10
|
+
* event handlers and Mounts in the cached VNode close over the frame active
|
|
11
|
+
* when the VNode was built. Returning a VNode built under a different frame
|
|
12
|
+
* would silently misroute events or retain the wrong Mount lifecycle owner.
|
|
13
13
|
*
|
|
14
14
|
* The cached VNode must be rendered at a single position in the tree.
|
|
15
15
|
* Snabbdom tracks the real DOM through each VNode's mutable `.elm` field
|
package/dist/html/lazy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lazy.d.ts","sourceRoot":"","sources":["../../src/html/lazy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,KAAK,EAAwC,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"lazy.d.ts","sourceRoot":"","sources":["../../src/html/lazy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,KAAK,EAAwC,MAAM,YAAY,CAAA;AAyG7E;;;;;;;;;;;;;;;;;oCAiBoC;AACpC,eAAO,MAAM,UAAU,QAAO,CAAC,CAAC,IAAI,SAAS,aAAa,CAAC,OAAO,CAAC,EACjE,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,KAAK,GAAG,IAAI,EACnC,IAAI,EAAE,IAAI,KACP,KAAK,GAAG,IAAI,CAUhB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;iDAsBiD;AACjD,eAAO,MAAM,eAAe,QAAO,CAAC,CAAC,IAAI,SAAS,aAAa,CAAC,OAAO,CAAC,EACtE,GAAG,EAAE,WAAW,EAChB,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,KAAK,GAAG,IAAI,EACnC,IAAI,EAAE,IAAI,KACP,KAAK,GAAG,IAAI,CAehB,CAAA"}
|
package/dist/html/lazy.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Predicate } from 'effect';
|
|
2
2
|
import { dedupeMemoizedResult, memoizedVNodes } from '../vdom.js';
|
|
3
|
-
import { beginLazyTracking, endLazyTracking,
|
|
4
|
-
import { requireBoundary, requireDispatch, } from './runtimeSingleton.js';
|
|
3
|
+
import { beginLazyTracking, endLazyTracking, registerBoundaryWrapTransactionRollback, restoreBoundaryWrapsForLazyHit, } from './boundary.js';
|
|
4
|
+
import { requireBoundary, requireDispatch, requireMountDispatch, requireMountRenderOwner, } from './runtimeSingleton.js';
|
|
5
5
|
const argsEqual = (previous, current) => {
|
|
6
6
|
if (previous.length !== current.length) {
|
|
7
7
|
return false;
|
|
@@ -15,16 +15,24 @@ const argsEqual = (previous, current) => {
|
|
|
15
15
|
};
|
|
16
16
|
const resolveOrCache = (previousEntry, fn, args, onCache) => {
|
|
17
17
|
const dispatch = requireDispatch();
|
|
18
|
+
const mountDispatch = requireMountDispatch();
|
|
19
|
+
const mountRenderOwner = requireMountRenderOwner();
|
|
18
20
|
const { registry } = requireBoundary();
|
|
19
|
-
// NOTE:
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
21
|
+
// NOTE: dispatcher identities and Mount render ownership belong in the
|
|
22
|
+
// cache key because the cached VNode closes over them. Current frame
|
|
23
|
+
// construction makes the Mount dispatcher identity derivable from the
|
|
24
|
+
// ordinary dispatcher's owner and boundary, so the second identity cannot
|
|
25
|
+
// change a cache decision today. Keeping both roles explicit prevents a
|
|
26
|
+
// future renderer that separates them from retaining stale handler or Mount
|
|
27
|
+
// lifecycle closures. Custom renderers can also use one dispatcher for both
|
|
28
|
+
// owners, so the owner remains a separate key member.
|
|
23
29
|
if (Predicate.isNotUndefined(previousEntry) &&
|
|
24
30
|
previousEntry.fn === fn &&
|
|
25
31
|
previousEntry.dispatch === dispatch &&
|
|
32
|
+
previousEntry.mountDispatch === mountDispatch &&
|
|
33
|
+
previousEntry.mountRenderOwner === mountRenderOwner &&
|
|
26
34
|
argsEqual(previousEntry.args, args)) {
|
|
27
|
-
|
|
35
|
+
restoreBoundaryWrapsForLazyHit(registry, previousEntry.trackedBoundaries);
|
|
28
36
|
return previousEntry.vnode;
|
|
29
37
|
}
|
|
30
38
|
const trackedBoundaries = beginLazyTracking(registry);
|
|
@@ -45,20 +53,29 @@ const resolveOrCache = (previousEntry, fn, args, onCache) => {
|
|
|
45
53
|
if (Predicate.isNotNull(deduped)) {
|
|
46
54
|
memoizedVNodes.add(deduped);
|
|
47
55
|
}
|
|
48
|
-
onCache({
|
|
56
|
+
onCache({
|
|
57
|
+
fn,
|
|
58
|
+
args,
|
|
59
|
+
dispatch,
|
|
60
|
+
mountDispatch,
|
|
61
|
+
mountRenderOwner,
|
|
62
|
+
vnode: deduped,
|
|
63
|
+
trackedBoundaries,
|
|
64
|
+
});
|
|
65
|
+
registerBoundaryWrapTransactionRollback(registry, previousEntry, onCache);
|
|
49
66
|
return deduped;
|
|
50
67
|
};
|
|
51
68
|
/** Creates a memoization slot for a view function. On each render, if the
|
|
52
|
-
* function reference,
|
|
53
|
-
*
|
|
69
|
+
* function reference, dispatchers, Mount render owner, and all arguments are
|
|
70
|
+
* equal to the previous call, the cached VNode is returned without
|
|
54
71
|
* re-running the view function. Snabbdom's `patchVnode` short-circuits when
|
|
55
72
|
* it sees the same VNode reference, so both VNode construction and subtree
|
|
56
73
|
* diffing are skipped.
|
|
57
74
|
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
75
|
+
* Dispatchers and Mount render ownership are part of the cache key because
|
|
76
|
+
* event handlers and Mounts in the cached VNode close over the frame active
|
|
77
|
+
* when the VNode was built. Returning a VNode built under a different frame
|
|
78
|
+
* would silently misroute events or retain the wrong Mount lifecycle owner.
|
|
62
79
|
*
|
|
63
80
|
* The cached VNode must be rendered at a single position in the tree.
|
|
64
81
|
* Snabbdom tracks the real DOM through each VNode's mutable `.elm` field
|
|
@@ -98,6 +115,11 @@ export const createLazy = () => {
|
|
|
98
115
|
export const createKeyedLazy = () => {
|
|
99
116
|
const cache = new Map();
|
|
100
117
|
return (key, fn, args) => resolveOrCache(cache.get(key), fn, args, entry => {
|
|
101
|
-
|
|
118
|
+
if (entry === undefined) {
|
|
119
|
+
cache.delete(key);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
cache.set(key, entry);
|
|
123
|
+
}
|
|
102
124
|
});
|
|
103
125
|
};
|
package/dist/html/public.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { childAttributes, ClickOptions, createKeyedLazy, createLazy, DefaultAction, EventPropagation, inertHtml, TextDirection, } from './index.js';
|
|
2
|
-
export type { Attribute, ChildAttribute, Document, Html, HtmlBuilder, KeyboardModifiers, TagName, } from './index.js';
|
|
2
|
+
export type { Attribute, ChildAttribute, Document, Html, HtmlBuilder, KeyboardModifiers, TagName, TextareaAttribute, } from './index.js';
|
|
3
3
|
//# sourceMappingURL=public.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/html/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,YAAY,EACZ,eAAe,EACf,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,SAAS,EACT,aAAa,GACd,MAAM,YAAY,CAAA;AAEnB,YAAY,EACV,SAAS,EACT,cAAc,EACd,QAAQ,EACR,IAAI,EACJ,WAAW,EACX,iBAAiB,EACjB,OAAO,
|
|
1
|
+
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/html/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,YAAY,EACZ,eAAe,EACf,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,SAAS,EACT,aAAa,GACd,MAAM,YAAY,CAAA;AAEnB,YAAY,EACV,SAAS,EACT,cAAc,EACd,QAAQ,EACR,IAAI,EACJ,WAAW,EACX,iBAAiB,EACjB,OAAO,EACP,iBAAiB,GAClB,MAAM,YAAY,CAAA"}
|
|
@@ -2,8 +2,17 @@ import type { Context } from 'effect';
|
|
|
2
2
|
import { type BoundaryId, type BoundaryRegistry } from './boundary.js';
|
|
3
3
|
/** Synchronous message dispatcher provided to view-time element constructors. */
|
|
4
4
|
export type DispatchSync = (message: unknown) => void;
|
|
5
|
+
/** Identifies which kind of render acquired a Mount. */
|
|
6
|
+
export type MountRenderOwner = 'Live' | 'Replay';
|
|
7
|
+
/** Resolves the render-owned dispatcher for a Mount at insertion time. */
|
|
8
|
+
export type MountDispatchResolver = Readonly<{
|
|
9
|
+
owner: MountRenderOwner;
|
|
10
|
+
resolve: () => DispatchSync;
|
|
11
|
+
}>;
|
|
5
12
|
export type Frame = Readonly<{
|
|
6
13
|
outerDispatch: DispatchSync;
|
|
14
|
+
mountOuterDispatch: DispatchSync;
|
|
15
|
+
mountRenderOwner: MountRenderOwner;
|
|
7
16
|
runtimeContext: Context.Context<never>;
|
|
8
17
|
boundaryRegistry: BoundaryRegistry;
|
|
9
18
|
boundaryId: BoundaryId;
|
|
@@ -19,7 +28,7 @@ export type Frame = Readonly<{
|
|
|
19
28
|
* omitted (e.g. crash views, test helpers that don't use Submodels), a
|
|
20
29
|
* fresh empty registry is created. The frame starts in the root
|
|
21
30
|
* boundary. */
|
|
22
|
-
export declare const setRuntime: (dispatch: DispatchSync, runtimeContext: Context.Context<never>, boundaryRegistry?: BoundaryRegistry) => void;
|
|
31
|
+
export declare const setRuntime: (dispatch: DispatchSync, runtimeContext: Context.Context<never>, boundaryRegistry?: BoundaryRegistry, mountRenderOwner?: MountRenderOwner) => void;
|
|
23
32
|
/** Pushes a new frame that inherits the current frame's dispatch, context,
|
|
24
33
|
* and registry, but uses a different boundary. Used by `h.submodel` to
|
|
25
34
|
* enter a child Submodel's wrapping context. Must be paired with
|
|
@@ -52,6 +61,12 @@ export declare const clearRuntime: () => void;
|
|
|
52
61
|
* is a cached per-boundary dispatcher that applies the wrapping chain at
|
|
53
62
|
* event-fire time. Throws when called outside of a runtime frame. */
|
|
54
63
|
export declare const requireDispatch: () => DispatchSync;
|
|
64
|
+
/** Returns the render-owned root dispatcher for Mount results. A live render
|
|
65
|
+
* supplies live dispatch, while a historical render supplies no-op dispatch
|
|
66
|
+
* for acquisitions owned by that replay. */
|
|
67
|
+
export declare const requireMountDispatch: () => DispatchSync;
|
|
68
|
+
/** Returns whether the current frame is rendering the live or replayed view. */
|
|
69
|
+
export declare const requireMountRenderOwner: () => MountRenderOwner;
|
|
55
70
|
/** A function that, given a message, resolves it through the current
|
|
56
71
|
* boundary's wrapping chain immediately and returns a thunk that dispatches
|
|
57
72
|
* the fully wrapped root message. */
|
|
@@ -62,12 +77,18 @@ export type UnmountResolver = (message: unknown) => () => void;
|
|
|
62
77
|
* patch. Throws when called outside of a runtime frame. */
|
|
63
78
|
export declare const requireUnmountResolver: () => UnmountResolver;
|
|
64
79
|
/** Returns the current frame's Submodel wrapping chain (innermost first), or an
|
|
65
|
-
* empty array at the root boundary. `OnMount`
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
80
|
+
* empty array at the root boundary. `OnMount` records this build-time snapshot
|
|
81
|
+
* for the Scene test harness, which replays the chain when the Mount is
|
|
82
|
+
* resolved. Production Mount dispatch uses the ownership-aware resolver below.
|
|
83
|
+
* Returns `[]` when there is no active frame, mirroring the lazy tolerance of
|
|
84
|
+
* handler-free Html built outside a render. */
|
|
70
85
|
export declare const requireBoundaryMappers: () => ReadonlyArray<(message: unknown) => unknown>;
|
|
86
|
+
/** Returns a resolver bound to the current frame's render owner and Submodel
|
|
87
|
+
* boundary. Mounts invoke it from their insert hook, so a cached VNode uses
|
|
88
|
+
* the dispatcher for the render that acquires it. That dispatcher follows
|
|
89
|
+
* later wrapper registrations from the same owner without crossing between
|
|
90
|
+
* live and replay renders. */
|
|
91
|
+
export declare const requireMountDispatchResolver: () => MountDispatchResolver;
|
|
71
92
|
/** Returns the current runtime Effect Context, used by Mount integrations
|
|
72
93
|
* that fork message-producing Effects against the live runtime services. */
|
|
73
94
|
export declare const requireRuntimeContext: () => Context.Context<never>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtimeSingleton.d.ts","sourceRoot":"","sources":["../../src/html/runtimeSingleton.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AAErC,OAAO,EACL,KAAK,UAAU,EACf,KAAK,gBAAgB,
|
|
1
|
+
{"version":3,"file":"runtimeSingleton.d.ts","sourceRoot":"","sources":["../../src/html/runtimeSingleton.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AAErC,OAAO,EACL,KAAK,UAAU,EACf,KAAK,gBAAgB,EAOtB,MAAM,eAAe,CAAA;AAEtB,iFAAiF;AACjF,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;AAErD,wDAAwD;AACxD,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,QAAQ,CAAA;AAEhD,0EAA0E;AAC1E,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C,KAAK,EAAE,gBAAgB,CAAA;IACvB,OAAO,EAAE,MAAM,YAAY,CAAA;CAC5B,CAAC,CAAA;AAEF,MAAM,MAAM,KAAK,GAAG,QAAQ,CAAC;IAC3B,aAAa,EAAE,YAAY,CAAA;IAC3B,kBAAkB,EAAE,YAAY,CAAA;IAChC,gBAAgB,EAAE,gBAAgB,CAAA;IAClC,cAAc,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IACtC,gBAAgB,EAAE,gBAAgB,CAAA;IAClC,UAAU,EAAE,UAAU,CAAA;CACvB,CAAC,CAAA;AAiBF;;;;;;;;;;gBAUgB;AAChB,eAAO,MAAM,UAAU,aACX,YAAY,kBACN,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,qBACpB,gBAAgB,qBAChB,gBAAgB,KACjC,IASF,CAAA;AAED;;;4BAG4B;AAC5B,eAAO,MAAM,YAAY,eAAgB,UAAU,KAAG,IAerD,CAAA;AAED;;;;;;;;;;;0DAW0D;AAC1D,eAAO,MAAM,SAAS,UAAW,KAAK,KAAG,IAExC,CAAA;AAED;;;;;;;6BAO6B;AAC7B,eAAO,MAAM,YAAY,QAAO,IAU/B,CAAA;AAED;;;sEAGsE;AACtE,eAAO,MAAM,eAAe,QAAO,YAOlC,CAAA;AAED;;6CAE6C;AAC7C,eAAO,MAAM,oBAAoB,QAAO,YAEvC,CAAA;AAED,gFAAgF;AAChF,eAAO,MAAM,uBAAuB,QAAO,gBAE1C,CAAA;AAED;;sCAEsC;AACtC,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,IAAI,CAAA;AAE9D;;;4DAG4D;AAC5D,eAAO,MAAM,sBAAsB,QAAO,eASzC,CAAA;AAED;;;;;gDAKgD;AAChD,eAAO,MAAM,sBAAsB,QAAO,aAAa,CACrD,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAO9B,CAAA;AAED;;;;+BAI+B;AAC/B,eAAO,MAAM,4BAA4B,QAAO,qBAW/C,CAAA;AAED;6EAC6E;AAC7E,eAAO,MAAM,qBAAqB,QAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAE7D,CAAA;AAED;;mEAEmE;AACnE,eAAO,MAAM,eAAe,QAAO,QAAQ,CAAC;IAC1C,QAAQ,EAAE,gBAAgB,CAAA;IAC1B,UAAU,EAAE,UAAU,CAAA;CACvB,CAQA,CAAA;AAED;;;;;8CAK8C;AAC9C,eAAO,MAAM,eAAe,QAAO,KAQlC,CAAA"}
|
|
@@ -1,5 +1,15 @@
|
|
|
1
|
-
import { ROOT_BOUNDARY, boundaryMappers, createBoundaryRegistry, getOrCreateBoundaryDispatch, resolveBoundaryDispatchThunk, } from './boundary.js';
|
|
1
|
+
import { ROOT_BOUNDARY, boundaryMappers, createBoundaryRegistry, getOrCreateBoundaryDispatch, resolveBoundaryDispatchThunk, resolveMountBoundaryDispatch, } from './boundary.js';
|
|
2
2
|
const stack = [];
|
|
3
|
+
const requireFrame = () => {
|
|
4
|
+
const frame = stack[stack.length - 1];
|
|
5
|
+
if (frame === undefined) {
|
|
6
|
+
throw new Error('Foldkit: html element constructors must be called inside a runtime-driven ' +
|
|
7
|
+
'render. The element was built outside a view, or foldkit was loaded as ' +
|
|
8
|
+
'more than one instance (a bundler split foldkit and @foldkit/ui into ' +
|
|
9
|
+
'separate copies).');
|
|
10
|
+
}
|
|
11
|
+
return frame;
|
|
12
|
+
};
|
|
3
13
|
/** Pushes a new dispatch and runtime context onto the singleton stack. The
|
|
4
14
|
* runtime calls this before invoking a user `view`, and any test or
|
|
5
15
|
* framework helper that builds VNodes outside of a normal render uses the
|
|
@@ -11,9 +21,11 @@ const stack = [];
|
|
|
11
21
|
* omitted (e.g. crash views, test helpers that don't use Submodels), a
|
|
12
22
|
* fresh empty registry is created. The frame starts in the root
|
|
13
23
|
* boundary. */
|
|
14
|
-
export const setRuntime = (dispatch, runtimeContext, boundaryRegistry = createBoundaryRegistry()) => {
|
|
24
|
+
export const setRuntime = (dispatch, runtimeContext, boundaryRegistry = createBoundaryRegistry(), mountRenderOwner = 'Live') => {
|
|
15
25
|
stack.push({
|
|
16
26
|
outerDispatch: dispatch,
|
|
27
|
+
mountOuterDispatch: dispatch,
|
|
28
|
+
mountRenderOwner,
|
|
17
29
|
runtimeContext,
|
|
18
30
|
boundaryRegistry,
|
|
19
31
|
boundaryId: ROOT_BOUNDARY,
|
|
@@ -30,6 +42,8 @@ export const pushBoundary = (boundaryId) => {
|
|
|
30
42
|
}
|
|
31
43
|
stack.push({
|
|
32
44
|
outerDispatch: parent.outerDispatch,
|
|
45
|
+
mountOuterDispatch: parent.mountOuterDispatch,
|
|
46
|
+
mountRenderOwner: parent.mountRenderOwner,
|
|
33
47
|
runtimeContext: parent.runtimeContext,
|
|
34
48
|
boundaryRegistry: parent.boundaryRegistry,
|
|
35
49
|
boundaryId,
|
|
@@ -72,35 +86,33 @@ export const clearRuntime = () => {
|
|
|
72
86
|
* is a cached per-boundary dispatcher that applies the wrapping chain at
|
|
73
87
|
* event-fire time. Throws when called outside of a runtime frame. */
|
|
74
88
|
export const requireDispatch = () => {
|
|
75
|
-
const frame =
|
|
76
|
-
if (frame === undefined) {
|
|
77
|
-
throw new Error('Foldkit: html element constructors must be called inside a runtime-driven ' +
|
|
78
|
-
'render. The element was built outside a view, or foldkit was loaded as ' +
|
|
79
|
-
'more than one instance (a bundler split foldkit and @foldkit/ui into ' +
|
|
80
|
-
'separate copies).');
|
|
81
|
-
}
|
|
89
|
+
const frame = requireFrame();
|
|
82
90
|
return getOrCreateBoundaryDispatch(frame.boundaryRegistry, frame.outerDispatch, frame.boundaryId);
|
|
83
91
|
};
|
|
92
|
+
/** Returns the render-owned root dispatcher for Mount results. A live render
|
|
93
|
+
* supplies live dispatch, while a historical render supplies no-op dispatch
|
|
94
|
+
* for acquisitions owned by that replay. */
|
|
95
|
+
export const requireMountDispatch = () => {
|
|
96
|
+
return requireFrame().mountOuterDispatch;
|
|
97
|
+
};
|
|
98
|
+
/** Returns whether the current frame is rendering the live or replayed view. */
|
|
99
|
+
export const requireMountRenderOwner = () => {
|
|
100
|
+
return requireFrame().mountRenderOwner;
|
|
101
|
+
};
|
|
84
102
|
/** Returns an {@link UnmountResolver} bound to the current frame's boundary.
|
|
85
103
|
* `OnUnmount` calls the resolver at build time (boundary alive) to capture a
|
|
86
104
|
* dispatch thunk that survives the boundary being torn down during the same
|
|
87
105
|
* patch. Throws when called outside of a runtime frame. */
|
|
88
106
|
export const requireUnmountResolver = () => {
|
|
89
|
-
const frame =
|
|
90
|
-
if (frame === undefined) {
|
|
91
|
-
throw new Error('Foldkit: html element constructors must be called inside a runtime-driven ' +
|
|
92
|
-
'render. The element was built outside a view, or foldkit was loaded as ' +
|
|
93
|
-
'more than one instance (a bundler split foldkit and @foldkit/ui into ' +
|
|
94
|
-
'separate copies).');
|
|
95
|
-
}
|
|
107
|
+
const frame = requireFrame();
|
|
96
108
|
return message => resolveBoundaryDispatchThunk(frame.boundaryRegistry, frame.outerDispatch, frame.boundaryId, message);
|
|
97
109
|
};
|
|
98
110
|
/** Returns the current frame's Submodel wrapping chain (innermost first), or an
|
|
99
|
-
* empty array at the root boundary. `OnMount`
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
111
|
+
* empty array at the root boundary. `OnMount` records this build-time snapshot
|
|
112
|
+
* for the Scene test harness, which replays the chain when the Mount is
|
|
113
|
+
* resolved. Production Mount dispatch uses the ownership-aware resolver below.
|
|
114
|
+
* Returns `[]` when there is no active frame, mirroring the lazy tolerance of
|
|
115
|
+
* handler-free Html built outside a render. */
|
|
104
116
|
export const requireBoundaryMappers = () => {
|
|
105
117
|
const frame = stack[stack.length - 1];
|
|
106
118
|
if (frame === undefined) {
|
|
@@ -108,17 +120,22 @@ export const requireBoundaryMappers = () => {
|
|
|
108
120
|
}
|
|
109
121
|
return boundaryMappers(frame.boundaryRegistry, frame.boundaryId);
|
|
110
122
|
};
|
|
123
|
+
/** Returns a resolver bound to the current frame's render owner and Submodel
|
|
124
|
+
* boundary. Mounts invoke it from their insert hook, so a cached VNode uses
|
|
125
|
+
* the dispatcher for the render that acquires it. That dispatcher follows
|
|
126
|
+
* later wrapper registrations from the same owner without crossing between
|
|
127
|
+
* live and replay renders. */
|
|
128
|
+
export const requireMountDispatchResolver = () => {
|
|
129
|
+
const frame = requireFrame();
|
|
130
|
+
return {
|
|
131
|
+
owner: frame.mountRenderOwner,
|
|
132
|
+
resolve: () => resolveMountBoundaryDispatch(frame.boundaryRegistry, frame.mountOuterDispatch, frame.boundaryId),
|
|
133
|
+
};
|
|
134
|
+
};
|
|
111
135
|
/** Returns the current runtime Effect Context, used by Mount integrations
|
|
112
136
|
* that fork message-producing Effects against the live runtime services. */
|
|
113
137
|
export const requireRuntimeContext = () => {
|
|
114
|
-
|
|
115
|
-
if (frame === undefined) {
|
|
116
|
-
throw new Error('Foldkit: html element constructors must be called inside a runtime-driven ' +
|
|
117
|
-
'render. The element was built outside a view, or foldkit was loaded as ' +
|
|
118
|
-
'more than one instance (a bundler split foldkit and @foldkit/ui into ' +
|
|
119
|
-
'separate copies).');
|
|
120
|
-
}
|
|
121
|
-
return frame.runtimeContext;
|
|
138
|
+
return requireFrame().runtimeContext;
|
|
122
139
|
};
|
|
123
140
|
/** Returns the current frame's boundary registry and boundary id. Used by
|
|
124
141
|
* `h.submodel` to register wrapping descriptors and compute child
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"submodel.d.ts","sourceRoot":"","sources":["../../src/html/submodel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAkB,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"submodel.d.ts","sourceRoot":"","sources":["../../src/html/submodel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAkB,MAAM,YAAY,CAAA;AAYvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAa7C,QAAA,MAAM,sBAAsB,sBAAsB,CAAA;AAElD;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCA4BgC;AAChC,MAAM,MAAM,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI,IAAI,CAAC;IAC7D,UAAU;CACX,SAAS,CAAC,IAAI,CAAC,GACZ,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,KAAK,GAAG,IAAI,GACvD,CACE,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,UAAU,EACtB,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,KACpB,KAAK,GAAG,IAAI,CAAC,GAAG;IACvB,QAAQ,CAAC,CAAC,sBAAsB,CAAC,EAAE,OAAO,CAAA;CAC3C,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;mDAsBmD;AACnD,eAAO,MAAM,UAAU,GAAI,KAAK,EAAE,OAAO,GAAG,KAAK,EAAE,UAAU,GAAG,IAAI,MAC9D,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,GAC3B,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,KAAK,GAAG,IAAI,GACvD,CACE,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,UAAU,EACtB,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,KACpB,KAAK,GAAG,IAAI,KACpB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,CAOM,CAAA;AAEhD;;;;kBAIkB;AAClB,MAAM,MAAM,eAAe,GAAG,CAAC,CAC7B,GAAG,IAAI,EAAE,aAAa,CAAC,GAAG,CAAC,KACxB,KAAK,GAAG,IAAI,CAAC,GAAG;IACnB,QAAQ,CAAC,CAAC,sBAAsB,CAAC,EAAE,OAAO,CAAA;CAC3C,CAAA;AAED,KAAK,WAAW,CAAC,IAAI,SAAS,eAAe,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;AAEpE,KAAK,YAAY,CAAC,IAAI,SAAS,eAAe,IAC5C,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,UAAU,EAAE,OAAO,CAAC,GACzD,UAAU,GACV,IAAI,CAAA;AAEV,KAAK,aAAa,CAAC,IAAI,SAAS,eAAe,IAAI,IAAI,SAAS;IAC9D,QAAQ,CAAC,CAAC,sBAAsB,CAAC,EAAE,MAAM,OAAO,CAAA;CACjD,GACG,OAAO,GACP,KAAK,CAAA;AAET;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBA2CgB;AAChB,MAAM,MAAM,cAAc,CACxB,IAAI,SAAS,eAAe,EAC5B,aAAa,IACX,QAAQ,CAAC;IACX,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,WAAW,CAAC,IAAI,CAAC,CAAA;IACxB,IAAI,EAAE,IAAI,CAAA;IACV,eAAe,EAAE,CAAC,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,KAAK,aAAa,CAAA;CACjE,CAAC,GAKA,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,GAChC,QAAQ,CAAC;IAAE,UAAU,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC,GAChC,QAAQ,CAAC;IAAE,UAAU,EAAE,YAAY,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CAAC,CAAA;AAqJnD;;;;;gEAKgE;AAChE,eAAO,MAAM,QAAQ,GAAI,IAAI,SAAS,eAAe,UAC3C,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,wBACf,WAAW,CAAC,OAAO,CAAC,KACzC,KAAK,GAAG,IA8EV,CAAA"}
|
package/dist/html/submodel.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { memoizedVNodes } from '../vdom.js';
|
|
2
|
-
import { composeBoundary, deregisterBoundaryWrap, registerBoundaryWrap, } from './boundary.js';
|
|
2
|
+
import { beginBoundaryWrapTransaction, commitBoundaryWrapTransaction, composeBoundary, deregisterBoundaryWrap, registerBoundaryWrap, rollbackBoundaryWrapTransaction, } from './boundary.js';
|
|
3
3
|
import { isChildAttribute } from './childAttribute.js';
|
|
4
4
|
import { clearRuntime, getCurrentFrame, pushBoundary, pushFrame, } from './runtimeSingleton.js';
|
|
5
5
|
// NOTE: string key (not Symbol) so SubmodelView types from different
|
|
@@ -136,23 +136,12 @@ const wrapViewInputsForOuterBoundary = (viewInputs, outerFrame) => {
|
|
|
136
136
|
*
|
|
137
137
|
* See `submodel.test.ts` for the cache-hit-survival and
|
|
138
138
|
* destroy-deregisters-wrap assertions. */
|
|
139
|
-
const withBoundaryCleanup = (vnode, registry, boundaryId) => {
|
|
139
|
+
const withBoundaryCleanup = (vnode, registry, boundaryId, descriptor, mountOuterDispatch) => {
|
|
140
140
|
const data = vnode.data ?? {};
|
|
141
141
|
const hook = data.hook ?? {};
|
|
142
142
|
const previousDestroy = hook.destroy;
|
|
143
143
|
const compositeDestroy = (removed) => {
|
|
144
|
-
|
|
145
|
-
// renders (e.g. a keyed root whose key changed) re-registers its
|
|
146
|
-
// boundary in the new view phase, then snabbdom destroys the OLD root
|
|
147
|
-
// vnode in the following patch phase. That destroy must not evict the
|
|
148
|
-
// freshly re-registered wrap. `seenThisRender` is cleared in
|
|
149
|
-
// `beginRender`, so during patch it still reflects the just-completed
|
|
150
|
-
// view phase: the boundary's presence there means it is live this cycle
|
|
151
|
-
// (a remount), not a true unmount. Deleting it here would surface later
|
|
152
|
-
// as `dispatchAcrossBoundary missing wrap`.
|
|
153
|
-
if (!registry.seenThisRender.has(boundaryId)) {
|
|
154
|
-
deregisterBoundaryWrap(registry, boundaryId);
|
|
155
|
-
}
|
|
144
|
+
deregisterBoundaryWrap(registry, boundaryId, descriptor, mountOuterDispatch);
|
|
156
145
|
if (previousDestroy !== undefined) {
|
|
157
146
|
previousDestroy(removed);
|
|
158
147
|
}
|
|
@@ -184,21 +173,23 @@ export const submodel = (config, htmlBuilderSingleton) => {
|
|
|
184
173
|
const parentFrame = getCurrentFrame();
|
|
185
174
|
const registry = parentFrame.boundaryRegistry;
|
|
186
175
|
const childBoundaryId = composeBoundary(parentFrame.boundaryId, config.slotId);
|
|
187
|
-
|
|
176
|
+
const descriptor = {
|
|
188
177
|
toParentMessage:
|
|
189
178
|
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
|
|
190
179
|
config.toParentMessage,
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// singleton retyped to the child's Message. The value carries no
|
|
194
|
-
// Message state (dispatch resolves from the frame pushed below), so
|
|
195
|
-
// the cast is the entire mechanism, exactly like the brand cast in
|
|
196
|
-
// `defineView`.
|
|
197
|
-
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
|
|
198
|
-
const childBuilder = htmlBuilderSingleton;
|
|
199
|
-
let vnode;
|
|
200
|
-
pushBoundary(childBoundaryId);
|
|
180
|
+
};
|
|
181
|
+
const transaction = beginBoundaryWrapTransaction(registry);
|
|
201
182
|
try {
|
|
183
|
+
registerBoundaryWrap(registry, childBoundaryId, descriptor, parentFrame.mountOuterDispatch);
|
|
184
|
+
// NOTE: the builder handed to the child view is the process-wide
|
|
185
|
+
// singleton retyped to the child's Message. The value carries no
|
|
186
|
+
// Message state (dispatch resolves from the frame pushed below), so
|
|
187
|
+
// the cast is the entire mechanism, exactly like the brand cast in
|
|
188
|
+
// `defineView`.
|
|
189
|
+
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
|
|
190
|
+
const childBuilder = htmlBuilderSingleton;
|
|
191
|
+
let vnode;
|
|
192
|
+
pushBoundary(childBoundaryId);
|
|
202
193
|
try {
|
|
203
194
|
if (!Object.hasOwn(config, 'viewInputs')) {
|
|
204
195
|
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
|
|
@@ -214,21 +205,19 @@ export const submodel = (config, htmlBuilderSingleton) => {
|
|
|
214
205
|
vnode = view(config.model, wrappedViewInputs, childBuilder);
|
|
215
206
|
}
|
|
216
207
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
// no destroy hook ever firing. Drop it before propagating.
|
|
220
|
-
deregisterBoundaryWrap(registry, childBoundaryId);
|
|
221
|
-
throw error;
|
|
208
|
+
finally {
|
|
209
|
+
clearRuntime();
|
|
222
210
|
}
|
|
211
|
+
if (vnode === null) {
|
|
212
|
+
rollbackBoundaryWrapTransaction(registry, transaction);
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
const vnodeWithCleanup = withBoundaryCleanup(vnode, registry, childBoundaryId, descriptor, parentFrame.mountOuterDispatch);
|
|
216
|
+
commitBoundaryWrapTransaction(registry, transaction);
|
|
217
|
+
return vnodeWithCleanup;
|
|
223
218
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
if (vnode === null) {
|
|
228
|
-
// No vnode means no destroy hook will ever fire; deregister now so
|
|
229
|
-
// the wrap doesn't leak.
|
|
230
|
-
deregisterBoundaryWrap(registry, childBoundaryId);
|
|
231
|
-
return null;
|
|
219
|
+
catch (error) {
|
|
220
|
+
rollbackBoundaryWrapTransaction(registry, transaction);
|
|
221
|
+
throw error;
|
|
232
222
|
}
|
|
233
|
-
return withBoundaryCleanup(vnode, registry, childBoundaryId);
|
|
234
223
|
};
|
package/dist/http/http.d.ts
CHANGED
|
@@ -29,7 +29,7 @@ import { HttpClient } from 'effect/unstable/http';
|
|
|
29
29
|
* execute: Effect.gen(function* () {
|
|
30
30
|
* const client = yield* HttpClient.HttpClient
|
|
31
31
|
* const response = yield* client.get('/api/count')
|
|
32
|
-
* const { count } = yield*
|
|
32
|
+
* const { count } = yield* Schema.decodeUnknownEffect(CountResponse)(
|
|
33
33
|
* yield* response.json,
|
|
34
34
|
* )
|
|
35
35
|
* return SucceededFetchCount({ count })
|
package/dist/http/http.js
CHANGED
|
@@ -29,7 +29,7 @@ import { FetchHttpClient, HttpClient } from 'effect/unstable/http';
|
|
|
29
29
|
* execute: Effect.gen(function* () {
|
|
30
30
|
* const client = yield* HttpClient.HttpClient
|
|
31
31
|
* const response = yield* client.get('/api/count')
|
|
32
|
-
* const { count } = yield*
|
|
32
|
+
* const { count } = yield* Schema.decodeUnknownEffect(CountResponse)(
|
|
33
33
|
* yield* response.json,
|
|
34
34
|
* )
|
|
35
35
|
* return SucceededFetchCount({ count })
|
|
@@ -54,7 +54,7 @@ type EntryBrand<Model, Message> = {
|
|
|
54
54
|
};
|
|
55
55
|
/**
|
|
56
56
|
* The requirements value the runtime hands to `acquire`. When the requirements
|
|
57
|
-
* schema is wrapped in `
|
|
57
|
+
* schema is wrapped in `Schema.Option`, the runtime unwraps the `Some` before
|
|
58
58
|
* calling `acquire`, so the parameter is the inner type.
|
|
59
59
|
*/
|
|
60
60
|
type AcquireParams<Requirements> = Requirements extends Option.Option<infer Params> ? Params : Requirements;
|
|
@@ -99,7 +99,7 @@ export type ServicesOf<Resources> = {
|
|
|
99
99
|
* on the config literal) lets TypeScript fully resolve the requirements type
|
|
100
100
|
* before contextually typing `modelToMaybeRequirements` and `acquire`, so
|
|
101
101
|
* destructuring patterns are inferred correctly even when the schema uses
|
|
102
|
-
* transforms like `
|
|
102
|
+
* transforms like `Schema.Option`.
|
|
103
103
|
*
|
|
104
104
|
* The `onAcquired` field is typed as `OnAcquired` intersected with the
|
|
105
105
|
* concrete `(value: Value) => Message` signature: the concrete member keeps
|
|
@@ -153,7 +153,7 @@ export type EntryBuilder<Model, Message> = <RequirementsSchema extends Schema.Sc
|
|
|
153
153
|
* - `modelToMaybeRequirements` — Extracts requirements from the model.
|
|
154
154
|
* `Option.none()` means "release", `Option.some(params)` means
|
|
155
155
|
* "acquire/re-acquire if params changed". For resources with no
|
|
156
|
-
* parameters, use `
|
|
156
|
+
* parameters, use `Schema.Option(Schema.Null)` and return `Option.some(null)`.
|
|
157
157
|
* - `acquire` — Creates the resource from the unwrapped params. The returned
|
|
158
158
|
* Effect should fail when acquisition fails: errors in the error channel
|
|
159
159
|
* flow to `onAcquireError` as a message instead of crashing the runtime.
|
|
@@ -179,7 +179,7 @@ export type EntryBuilder<Model, Message> = <RequirementsSchema extends Schema.Sc
|
|
|
179
179
|
* const CameraStream = ManagedResource.tag<MediaStream>()('CameraStream')
|
|
180
180
|
*
|
|
181
181
|
* const managedResources = ManagedResource.make<Model, Message>()(entry => ({
|
|
182
|
-
* camera: entry(
|
|
182
|
+
* camera: entry(Schema.Option(Schema.Struct({ facingMode: Schema.String })), {
|
|
183
183
|
* resource: CameraStream,
|
|
184
184
|
* modelToMaybeRequirements: model =>
|
|
185
185
|
* pipe(
|
|
@@ -218,7 +218,7 @@ type ChildMessageOf<Resources> = Resources[keyof Resources] extends Entry<any, i
|
|
|
218
218
|
* `Option.none()` to release), and a child Submodel that owns a managed
|
|
219
219
|
* resource is itself something that mounts and unmounts. A missing child is
|
|
220
220
|
* just another `None` and flows through the same acquire/release channel, so
|
|
221
|
-
* each lifted entry's requirements must be `
|
|
221
|
+
* each lifted entry's requirements must be `Schema.Option`-wrapped.
|
|
222
222
|
*/
|
|
223
223
|
export declare const lift: <Resources extends Record<string, Entry<any, any, Option.Option<any>, any, any>>>(resources: Resources) => <ParentModel, ParentMessage>(config: {
|
|
224
224
|
readonly toChildModel: (parentModel: ParentModel) => Option.Option<ChildModelOf<Resources>>;
|
|
@@ -55,7 +55,7 @@ export const tag = () => (key) => {
|
|
|
55
55
|
* - `modelToMaybeRequirements` — Extracts requirements from the model.
|
|
56
56
|
* `Option.none()` means "release", `Option.some(params)` means
|
|
57
57
|
* "acquire/re-acquire if params changed". For resources with no
|
|
58
|
-
* parameters, use `
|
|
58
|
+
* parameters, use `Schema.Option(Schema.Null)` and return `Option.some(null)`.
|
|
59
59
|
* - `acquire` — Creates the resource from the unwrapped params. The returned
|
|
60
60
|
* Effect should fail when acquisition fails: errors in the error channel
|
|
61
61
|
* flow to `onAcquireError` as a message instead of crashing the runtime.
|
|
@@ -81,7 +81,7 @@ export const tag = () => (key) => {
|
|
|
81
81
|
* const CameraStream = ManagedResource.tag<MediaStream>()('CameraStream')
|
|
82
82
|
*
|
|
83
83
|
* const managedResources = ManagedResource.make<Model, Message>()(entry => ({
|
|
84
|
-
* camera: entry(
|
|
84
|
+
* camera: entry(Schema.Option(Schema.Struct({ facingMode: Schema.String })), {
|
|
85
85
|
* resource: CameraStream,
|
|
86
86
|
* modelToMaybeRequirements: model =>
|
|
87
87
|
* pipe(
|
|
@@ -130,7 +130,7 @@ export const make = () =>
|
|
|
130
130
|
* `Option.none()` to release), and a child Submodel that owns a managed
|
|
131
131
|
* resource is itself something that mounts and unmounts. A missing child is
|
|
132
132
|
* just another `None` and flows through the same acquire/release channel, so
|
|
133
|
-
* each lifted entry's requirements must be `
|
|
133
|
+
* each lifted entry's requirements must be `Schema.Option`-wrapped.
|
|
134
134
|
*/
|
|
135
135
|
export const lift = (resources) => (config) =>
|
|
136
136
|
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
|