@markless/router 0.8.0 → 0.10.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/dist/{create-server-entry-BsYTWdxi.js → create-server-entry-BnaEfDHl.js} +311 -66
- package/dist/index.js +2 -2
- package/dist/{request-locals-BDAhNpEa.js → navigation-timing-CzH6VaBR.js} +4 -2
- package/dist/vite/runtime/create-server-entry.d.ts +1 -0
- package/dist/vite/runtime/create-server-entry.js +1 -1
- package/dist/vite/runtime/mdx-route.d.ts +190 -7
- package/dist/vite/runtime/mdx-route.js +125 -13
- package/dist/vite.js +411 -62
- package/package.json +5 -5
- package/src/vite/entries/fragment-entry.ts +570 -238
- package/src/vite/entries/prerender-wake-entry.ts +3 -1
- package/src/vite/entries/resume-entry.ts +36 -23
- package/src/vite/entries/resume-modules.ts +7 -0
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { f as LINK_ATTRIBUTE, h as SCROLL_ATTRIBUTE, m as REPLACE_ATTRIBUTE, o as HTML_ATTRIBUTES_SLOT, p as PREFETCH_ATTRIBUTE, r as rememberRequestLocals, t as MARKLESS_NAV_PENDING_MIN_MS, u as routeMountTarget } from "./navigation-timing-CzH6VaBR.js";
|
|
2
2
|
import { a as normalizeRequestPathname, c as parseRequestFile, i as matchRouteManifest, l as transformRequestFileSource, n as buildRouteManifestFromFileIds, o as normalizeRouteFileId, s as normalizeRequestFileId } from "./route-manifest-DmoxXanW.js";
|
|
3
3
|
import { createExternalDelegateStructureTokens, createExternalDelegateView } from "@markless/web/fns/external-delegate";
|
|
4
4
|
import { render } from "@markless/web/render";
|
|
5
|
-
import {
|
|
5
|
+
import { settleOrPendingDeadline } from "@markless/web/fns/pending-timing";
|
|
6
6
|
//#region src/route-state.ts
|
|
7
7
|
const MARKLESS_ROUTER_ROUTE_EVENT = "marklessrouternavigate";
|
|
8
8
|
const MARKLESS_ROUTER_RENDERED_EVENT = "marklessrouterrendered";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CONTAINER_ATTRIBUTE, PROTOCOL_CONTAINER_END_COMMENT, PROTOCOL_CONTAINER_START_COMMENT, PROTOCOL_LOCATOR_PATHS_ATTRIBUTE } from "@markless/web/fns/container-region";
|
|
2
|
+
import { MARKLESS_PENDING_MIN_VISIBLE_MS as MARKLESS_NAV_PENDING_MIN_MS, MARKLESS_PENDING_SETTLE_DEADLINE_MS as MARKLESS_NAV_SETTLE_DEADLINE_MS } from "@markless/web/fns/pending-timing";
|
|
2
3
|
//#region src/link-attributes.ts
|
|
3
4
|
const LINK_ATTRIBUTE = "data-markless-router-link";
|
|
4
5
|
const REPLACE_ATTRIBUTE = "data-markless-router-replace";
|
|
@@ -9,8 +10,9 @@ const PREFETCH_ATTRIBUTE = "data-markless-router-prefetch";
|
|
|
9
10
|
const ROUTE_SCRIPT_TYPE = "@markless/core/route";
|
|
10
11
|
const HTML_ATTRIBUTES_SLOT = "__marklessRouterHtmlAttributes";
|
|
11
12
|
const SERVED_HTML_ATTRIBUTES_PROPERTY = "__marklessServedHtmlAttributes";
|
|
13
|
+
const SERVED_BODY_ATTRIBUTES_PROPERTY = "__marklessServedBodyAttributes";
|
|
12
14
|
function servedHtmlAttributesScript() {
|
|
13
|
-
return `<script>document.documentElement.${
|
|
15
|
+
return `<script>(()=>{const r=document.documentElement,p=(e)=>Array.from(e.attributes,(a)=>[a.name,a.value]),b=()=>!!document.body&&!!(r.${SERVED_BODY_ATTRIBUTES_PROPERTY}=p(document.body));r.${SERVED_HTML_ATTRIBUTES_PROPERTY}=p(r);b()||new MutationObserver((_,o)=>{b()&&o.disconnect()}).observe(r,{childList:true})})()<\/script>`;
|
|
14
16
|
}
|
|
15
17
|
function routeMountTarget(document, currentRoot) {
|
|
16
18
|
const root = currentRoot ?? document.querySelector(`script[type="@markless/core/route"]`)?.parentElement;
|
|
@@ -91,4 +93,4 @@ function takeMiddlewareHeaders(request) {
|
|
|
91
93
|
return record.taken;
|
|
92
94
|
}
|
|
93
95
|
//#endregion
|
|
94
|
-
export {
|
|
96
|
+
export { takeMiddlewareHeaders as a, SERVED_BODY_ATTRIBUTES_PROPERTY as c, servedHtmlAttributesScript as d, LINK_ATTRIBUTE as f, SCROLL_ATTRIBUTE as h, requestLocals as i, SERVED_HTML_ATTRIBUTES_PROPERTY as l, REPLACE_ATTRIBUTE as m, MARKLESS_NAV_SETTLE_DEADLINE_MS as n, HTML_ATTRIBUTES_SLOT as o, PREFETCH_ATTRIBUTE as p, rememberRequestLocals as r, ROUTE_SCRIPT_TYPE as s, MARKLESS_NAV_PENDING_MIN_MS as t, routeMountTarget as u };
|
|
@@ -10,6 +10,7 @@ export interface ServerEntryOptions {
|
|
|
10
10
|
readonly prerenderWakeEntryPath?: string;
|
|
11
11
|
readonly routeModulePreloads?: Record<string, readonly ModulePreloadInput[]>;
|
|
12
12
|
readonly routeSsrModulePreloads?: Record<string, readonly ModulePreloadInput[]>;
|
|
13
|
+
readonly routeResumeModules?: Readonly<Record<string, readonly string[]>>;
|
|
13
14
|
readonly routeStylesheets?: Record<string, readonly string[]>;
|
|
14
15
|
readonly documentStylesheets?: readonly string[];
|
|
15
16
|
readonly importMap?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as createServerEntry, n as routerLinkBridgeModules } from "../../create-server-entry-
|
|
1
|
+
export { t as createServerEntry, n as routerLinkBridgeModules } from "../../create-server-entry-BnaEfDHl.js";
|
|
@@ -5,6 +5,80 @@ declare const ASYNC_BOUNDARY_ARM: {
|
|
|
5
5
|
readonly catch: 2;
|
|
6
6
|
};
|
|
7
7
|
//#endregion
|
|
8
|
+
//#region ../serializer/src/value.d.ts
|
|
9
|
+
type SerializedPrimitive = null | string | number | boolean | {
|
|
10
|
+
readonly $type: 'undefined';
|
|
11
|
+
} | {
|
|
12
|
+
readonly $type: 'bigint';
|
|
13
|
+
readonly value: string;
|
|
14
|
+
} | {
|
|
15
|
+
readonly $type: 'number';
|
|
16
|
+
readonly value: NonFiniteNumberName;
|
|
17
|
+
};
|
|
18
|
+
/** JSON has no form for these, so a bare number slot would print as `null`. */
|
|
19
|
+
type NonFiniteNumberName = 'Infinity' | '-Infinity' | 'NaN';
|
|
20
|
+
type SerializedSlot = SerializedPrimitive | {
|
|
21
|
+
readonly $ref: number;
|
|
22
|
+
} | {
|
|
23
|
+
readonly $type: 'date';
|
|
24
|
+
readonly value: string;
|
|
25
|
+
} | {
|
|
26
|
+
readonly $type: 'regexp';
|
|
27
|
+
readonly source: string;
|
|
28
|
+
readonly flags: string;
|
|
29
|
+
} | {
|
|
30
|
+
readonly $type: 'url';
|
|
31
|
+
readonly value: string;
|
|
32
|
+
};
|
|
33
|
+
type SerializedRecord = {
|
|
34
|
+
readonly id: number;
|
|
35
|
+
readonly type: 'object';
|
|
36
|
+
readonly fields: ReadonlyArray<readonly [string, SerializedSlot]>;
|
|
37
|
+
} | {
|
|
38
|
+
readonly id: number;
|
|
39
|
+
readonly type: 'array';
|
|
40
|
+
readonly items: ReadonlyArray<SerializedSlot>;
|
|
41
|
+
} | {
|
|
42
|
+
readonly id: number;
|
|
43
|
+
readonly type: 'map';
|
|
44
|
+
readonly entries: ReadonlyArray<readonly [SerializedSlot, SerializedSlot]>;
|
|
45
|
+
} | {
|
|
46
|
+
readonly id: number;
|
|
47
|
+
readonly type: 'set';
|
|
48
|
+
readonly values: ReadonlyArray<SerializedSlot>;
|
|
49
|
+
} | {
|
|
50
|
+
readonly id: number;
|
|
51
|
+
readonly type: 'date';
|
|
52
|
+
readonly value: string;
|
|
53
|
+
} | {
|
|
54
|
+
readonly id: number;
|
|
55
|
+
readonly type: 'regexp';
|
|
56
|
+
readonly source: string;
|
|
57
|
+
readonly flags: string;
|
|
58
|
+
} | {
|
|
59
|
+
readonly id: number;
|
|
60
|
+
readonly type: 'url';
|
|
61
|
+
readonly value: string;
|
|
62
|
+
} | {
|
|
63
|
+
readonly id: number;
|
|
64
|
+
readonly type: 'array-buffer';
|
|
65
|
+
readonly bytes: ReadonlyArray<number>;
|
|
66
|
+
} | {
|
|
67
|
+
readonly id: number;
|
|
68
|
+
readonly type: 'typed-array';
|
|
69
|
+
readonly arrayType: TypedArrayName;
|
|
70
|
+
readonly buffer: SerializedSlot;
|
|
71
|
+
readonly byteOffset: number;
|
|
72
|
+
readonly length: number;
|
|
73
|
+
} | {
|
|
74
|
+
readonly id: number;
|
|
75
|
+
readonly type: 'data-view';
|
|
76
|
+
readonly buffer: SerializedSlot;
|
|
77
|
+
readonly byteOffset: number;
|
|
78
|
+
readonly byteLength: number;
|
|
79
|
+
};
|
|
80
|
+
type TypedArrayName = 'Int8Array' | 'Uint8Array' | 'Uint8ClampedArray' | 'Int16Array' | 'Uint16Array' | 'Int32Array' | 'Uint32Array' | 'Float32Array' | 'Float64Array' | 'BigInt64Array' | 'BigUint64Array';
|
|
81
|
+
//#endregion
|
|
8
82
|
//#region ../serializer/src/protocol-constants.d.ts
|
|
9
83
|
declare const ASYNC_PROTOCOL_VERSION = 1;
|
|
10
84
|
declare const STORAGE_PROTOCOL_VERSION = 2;
|
|
@@ -15,6 +89,15 @@ declare const PROTOCOL_EVENT_ACTION_KIND: {
|
|
|
15
89
|
//#endregion
|
|
16
90
|
//#region ../serializer/src/protocol.d.ts
|
|
17
91
|
type ProtocolAsyncBoundaryArm = (typeof ASYNC_BOUNDARY_ARM)[keyof typeof ASYNC_BOUNDARY_ARM];
|
|
92
|
+
/**
|
|
93
|
+
* Where an element sits below the node an address starts from, one step per
|
|
94
|
+
* level. A step counts the parent's element children, and each @if, @switch or
|
|
95
|
+
* @try block as one (its start comment, content and end comment together). Text
|
|
96
|
+
* never counts, since adjacent text merges and an empty value renders no node,
|
|
97
|
+
* so the server's HTML and a client-built tree read the same. A negative step
|
|
98
|
+
* counts back from the end: -1 is the last.
|
|
99
|
+
*/
|
|
100
|
+
type ProtocolElementAddress = ReadonlyArray<number>;
|
|
18
101
|
type ProtocolSyncPolicyCondition = {
|
|
19
102
|
readonly type: 'and';
|
|
20
103
|
readonly conditions: ReadonlyArray<ProtocolSyncPolicyCondition>;
|
|
@@ -28,6 +111,8 @@ type ProtocolSyncPolicyCondition = {
|
|
|
28
111
|
readonly type: 'graph-truthy';
|
|
29
112
|
readonly graphNodeId: string;
|
|
30
113
|
readonly path?: ReadonlyArray<string>;
|
|
114
|
+
/** When present, the read must equal this value rather than be truthy. */
|
|
115
|
+
readonly equals?: string | number | boolean | null;
|
|
31
116
|
} | {
|
|
32
117
|
readonly type: 'constant-truthy';
|
|
33
118
|
readonly value: unknown;
|
|
@@ -93,6 +178,7 @@ type ProtocolStatePayload = {
|
|
|
93
178
|
readonly key: unknown;
|
|
94
179
|
readonly error: unknown;
|
|
95
180
|
};
|
|
181
|
+
readonly hostScope?: string;
|
|
96
182
|
}>;
|
|
97
183
|
readonly sharedSeeds?: ReadonlyArray<{
|
|
98
184
|
readonly graphNodeId: string;
|
|
@@ -132,6 +218,7 @@ type ProtocolStatePayload = {
|
|
|
132
218
|
readonly graphNodeId: string;
|
|
133
219
|
readonly key: string;
|
|
134
220
|
}>;
|
|
221
|
+
readonly sharedRecords?: ReadonlyArray<SerializedRecord>;
|
|
135
222
|
};
|
|
136
223
|
type ProtocolBranchContentRead = {
|
|
137
224
|
readonly graphNodeId: string;
|
|
@@ -197,6 +284,8 @@ type ProtocolArmRecordSet = {
|
|
|
197
284
|
readonly elementHandles: ProtocolViewPayload['elementHandles'];
|
|
198
285
|
readonly keyedRepeats?: ProtocolViewPayload['keyedRepeats'];
|
|
199
286
|
readonly branches?: ReadonlyArray<ProtocolArmBranchRecord>;
|
|
287
|
+
/** Served beside `events` sent as templates: the names the stream boot listens for. */
|
|
288
|
+
readonly eventNames?: ReadonlyArray<string>;
|
|
200
289
|
};
|
|
201
290
|
/**
|
|
202
291
|
* Where one row-template slot's value comes from: the repeated item, a graph
|
|
@@ -224,6 +313,23 @@ type ProtocolRowTemplateSlotValue = {
|
|
|
224
313
|
readonly path: ReadonlyArray<string>;
|
|
225
314
|
}>;
|
|
226
315
|
};
|
|
316
|
+
/** One arm of a row's branch: its markup and slots, FRAGMENT-relative to the arm's first node. */
|
|
317
|
+
type ProtocolRowTemplateArm = {
|
|
318
|
+
readonly html: string;
|
|
319
|
+
readonly textSlots?: ReadonlyArray<{
|
|
320
|
+
readonly path: ReadonlyArray<number>;
|
|
321
|
+
} & ProtocolRowTemplateSlotValue>;
|
|
322
|
+
readonly attributeSlots?: ReadonlyArray<{
|
|
323
|
+
readonly path: ReadonlyArray<number>;
|
|
324
|
+
readonly name: string;
|
|
325
|
+
} & ProtocolRowTemplateSlotValue>;
|
|
326
|
+
};
|
|
327
|
+
type ProtocolRowTemplateBranchSlot = {
|
|
328
|
+
readonly path: ReadonlyArray<number>;
|
|
329
|
+
readonly branchId: string;
|
|
330
|
+
readonly armTests?: ReadonlyArray<unknown>;
|
|
331
|
+
readonly arms: ReadonlyArray<ProtocolRowTemplateArm>;
|
|
332
|
+
} & ProtocolRowTemplateSlotValue;
|
|
227
333
|
type ProtocolViewPayload = {
|
|
228
334
|
readonly version: typeof ASYNC_PROTOCOL_VERSION;
|
|
229
335
|
readonly asyncRunners?: Readonly<Record<string, string>>;
|
|
@@ -340,7 +446,7 @@ type ProtocolViewPayload = {
|
|
|
340
446
|
*/
|
|
341
447
|
readonly enclosingRow?: {
|
|
342
448
|
readonly repeatId: string;
|
|
343
|
-
readonly parentHostPath:
|
|
449
|
+
readonly parentHostPath: ProtocolElementAddress;
|
|
344
450
|
readonly itemPath?: ReadonlyArray<string>;
|
|
345
451
|
};
|
|
346
452
|
readonly collectionGraphNodeId?: string;
|
|
@@ -363,6 +469,11 @@ type ProtocolViewPayload = {
|
|
|
363
469
|
readonly arm: number;
|
|
364
470
|
};
|
|
365
471
|
readonly itemName: string;
|
|
472
|
+
/**
|
|
473
|
+
* The `index` name of the `@for`, which a row handler reading it is handed
|
|
474
|
+
* beside the item. Pay-per-use: present only when a row handler reads it.
|
|
475
|
+
*/
|
|
476
|
+
readonly indexName?: string;
|
|
366
477
|
readonly rowElementCount: number;
|
|
367
478
|
/**
|
|
368
479
|
* Element children of the parent that stand before the rows. Rows occupy
|
|
@@ -441,6 +552,18 @@ type ProtocolViewPayload = {
|
|
|
441
552
|
readonly path: ReadonlyArray<number>;
|
|
442
553
|
readonly name: string;
|
|
443
554
|
} & ProtocolRowTemplateSlotValue>;
|
|
555
|
+
/**
|
|
556
|
+
* An `@if`/`@switch` written in the row, flipped per row. The slot value is
|
|
557
|
+
* the test (the discriminant for a `@switch`, matched against `armTests`),
|
|
558
|
+
* and `path` names the marker in `html` the shown arm's anchors and nodes
|
|
559
|
+
* replace. A branch that IS the row (`@for { @if { <tr> } }`) has the marker
|
|
560
|
+
* as the whole html: its arm is the row root, so a flip rebuilds the row.
|
|
561
|
+
* `branchId` is the branch site as the anchor comments spell it, before
|
|
562
|
+
* composition's prefix, like `branchArm.branchId`.
|
|
563
|
+
*
|
|
564
|
+
* Pay-per-use: a row with no such branch omits the field.
|
|
565
|
+
*/
|
|
566
|
+
readonly branchSlots?: ReadonlyArray<ProtocolRowTemplateBranchSlot>;
|
|
444
567
|
};
|
|
445
568
|
/**
|
|
446
569
|
* The parent graph node each prop a `rowTemplate` source slot reads follows,
|
|
@@ -493,16 +616,25 @@ type ProtocolViewPayload = {
|
|
|
493
616
|
readonly rowChunkId?: string;
|
|
494
617
|
};
|
|
495
618
|
readonly rowElementHandles?: ReadonlyArray<{
|
|
496
|
-
readonly hostPath:
|
|
619
|
+
readonly hostPath: ProtocolElementAddress;
|
|
497
620
|
readonly handleId: string;
|
|
498
621
|
readonly name: string;
|
|
499
622
|
readonly plural?: boolean;
|
|
500
623
|
}>;
|
|
501
624
|
readonly rowEvents: ReadonlyArray<{
|
|
502
|
-
readonly hostPath:
|
|
625
|
+
readonly hostPath: ProtocolElementAddress;
|
|
503
626
|
readonly eventName: string;
|
|
504
627
|
readonly symbolIds: ReadonlyArray<string>;
|
|
505
628
|
readonly syncPolicy?: ProtocolSyncPolicy;
|
|
629
|
+
/**
|
|
630
|
+
* The event's host sits in arm `arm` of `rowTemplate.branchSlots[slot]`, so it
|
|
631
|
+
* exists only while that arm shows, and `hostPath` is ARM-relative: element
|
|
632
|
+
* index among the arm's nodes, then child-node indexes from there.
|
|
633
|
+
*/
|
|
634
|
+
readonly arm?: {
|
|
635
|
+
readonly slot: number;
|
|
636
|
+
readonly arm: number;
|
|
637
|
+
};
|
|
506
638
|
}>;
|
|
507
639
|
}>;
|
|
508
640
|
readonly branches?: ReadonlyArray<{
|
|
@@ -519,7 +651,7 @@ type ProtocolViewPayload = {
|
|
|
519
651
|
readonly armTests?: ReadonlyArray<unknown>;
|
|
520
652
|
readonly armRecords?: ReadonlyArray<{
|
|
521
653
|
readonly events: ReadonlyArray<{
|
|
522
|
-
readonly hostPath:
|
|
654
|
+
readonly hostPath: ProtocolElementAddress;
|
|
523
655
|
readonly eventName: string;
|
|
524
656
|
readonly symbolIds: ReadonlyArray<string>;
|
|
525
657
|
readonly syncPolicy?: ProtocolSyncPolicy;
|
|
@@ -602,6 +734,9 @@ type ProtocolViewPayload = {
|
|
|
602
734
|
readonly path: ReadonlyArray<string>;
|
|
603
735
|
readonly runnerSymbolId?: string;
|
|
604
736
|
}>;
|
|
737
|
+
/** As on a branch: the part instance that authored this boundary and where its live props now live, for the arm its own module re-renders on settle. */
|
|
738
|
+
readonly composedInstancePath?: string;
|
|
739
|
+
readonly composedGraphProps?: ReadonlyArray<ProtocolComposedGraphProp>;
|
|
605
740
|
}>;
|
|
606
741
|
};
|
|
607
742
|
//#endregion
|
|
@@ -688,7 +823,27 @@ type RuntimeDemandMapClosurePlan = {
|
|
|
688
823
|
}>;
|
|
689
824
|
};
|
|
690
825
|
//#endregion
|
|
826
|
+
//#region ../runtime/src/graph-reconcile.d.ts
|
|
827
|
+
/**
|
|
828
|
+
* One array inside a derived value that reconciles by key instead of by
|
|
829
|
+
* element identity. `path` names the array (`[]` is the derived value itself)
|
|
830
|
+
* and `keyPath` is read on each element to get its identity.
|
|
831
|
+
*/
|
|
832
|
+
type RuntimeGraphReconcileKey = {
|
|
833
|
+
readonly path: ReadonlyArray<string>;
|
|
834
|
+
readonly keyPath: ReadonlyArray<string>;
|
|
835
|
+
};
|
|
836
|
+
/** Reconcile options carried by a computed or async computed graph node. */
|
|
837
|
+
type RuntimeGraphReconcileOptions = {
|
|
838
|
+
readonly keyed?: ReadonlyArray<RuntimeGraphReconcileKey>;
|
|
839
|
+
};
|
|
840
|
+
//#endregion
|
|
691
841
|
//#region ../runtime/src/graph.d.ts
|
|
842
|
+
type RuntimeGraphRead = (graphNodeId: string, path?: ReadonlyArray<string>) => unknown;
|
|
843
|
+
type RuntimeGraphComputedDependency = {
|
|
844
|
+
readonly graphNodeId: string;
|
|
845
|
+
readonly path?: ReadonlyArray<string>;
|
|
846
|
+
};
|
|
692
847
|
type RuntimeGraphAsyncSnapshot = {
|
|
693
848
|
readonly status: 'idle';
|
|
694
849
|
readonly version: 0;
|
|
@@ -708,6 +863,19 @@ type RuntimeGraphAsyncSnapshot = {
|
|
|
708
863
|
readonly key: unknown;
|
|
709
864
|
readonly error: unknown;
|
|
710
865
|
};
|
|
866
|
+
type RuntimeGraphAsyncComputed = {
|
|
867
|
+
readonly graphNodeId: string;
|
|
868
|
+
readonly dependencies: ReadonlyArray<RuntimeGraphComputedDependency>;
|
|
869
|
+
readonly initialSnapshot?: RuntimeGraphAsyncSnapshot;
|
|
870
|
+
readonly key: (read: RuntimeGraphRead) => unknown;
|
|
871
|
+
/** How a fulfilled value reconciles against the previously published one. */
|
|
872
|
+
readonly reconcile?: RuntimeGraphReconcileOptions;
|
|
873
|
+
readonly run: (input: {
|
|
874
|
+
readonly key: unknown;
|
|
875
|
+
readonly signal: AbortSignal;
|
|
876
|
+
readonly read: RuntimeGraphRead;
|
|
877
|
+
}) => unknown | Promise<unknown>;
|
|
878
|
+
};
|
|
711
879
|
type DomJournalEntry = {
|
|
712
880
|
readonly type: 'setText';
|
|
713
881
|
readonly locator: string;
|
|
@@ -777,6 +945,8 @@ type RuntimeGraphSubscription = {
|
|
|
777
945
|
readonly graphNodeId: string;
|
|
778
946
|
readonly path?: ReadonlyArray<string>;
|
|
779
947
|
readonly run: (value: unknown) => DomJournalResult | RuntimeGraphCommit | void | Promise<DomJournalResult | RuntimeGraphCommit | void>;
|
|
948
|
+
/** False while `run` still has code to load; a write observer then leaves its DOM to the pass, so the task's writes land together. */
|
|
949
|
+
readonly ready?: () => boolean;
|
|
780
950
|
};
|
|
781
951
|
/**
|
|
782
952
|
* Told about a write the moment it lands, before the flush that write schedules.
|
|
@@ -819,11 +989,14 @@ type RuntimeGraph = {
|
|
|
819
989
|
readonly listSharedDefinitions: () => NonNullable<ProtocolStatePayload['sharedDefinitions']>;
|
|
820
990
|
readonly takeSharedPatches: () => RuntimeGraphSharedPatch[];
|
|
821
991
|
readonly applySharedPatch: (patch: RuntimeGraphSharedPatch) => boolean;
|
|
822
|
-
|
|
992
|
+
/** Answers the value written, as the assignment it lowers from does. */
|
|
993
|
+
readonly write: (write: RuntimeGraphWrite) => unknown;
|
|
823
994
|
readonly update: (update: RuntimeGraphUpdate) => unknown;
|
|
824
995
|
readonly call: (call: RuntimeGraphCall) => unknown;
|
|
825
996
|
readonly delete: (deletion: RuntimeGraphDelete) => boolean;
|
|
826
997
|
readonly subscribe: (subscription: RuntimeGraphSubscription) => () => void;
|
|
998
|
+
/** Adds an async computed a component rendered after the graph was built; false when the node already exists. */
|
|
999
|
+
readonly defineAsyncComputed?: (asyncComputed: RuntimeGraphAsyncComputed) => boolean;
|
|
827
1000
|
/**
|
|
828
1001
|
* Optional so a facade over a subset of this contract stays a `RuntimeGraph`;
|
|
829
1002
|
* a caller without it gets the flush-time answer it always had.
|
|
@@ -866,7 +1039,7 @@ type ResumeDomElement = ResumeDomNode & {
|
|
|
866
1039
|
readonly dispatchEvent?: (event: ResumeSharedPatchEvent) => boolean;
|
|
867
1040
|
readonly setAttribute?: (name: string, value: string) => void;
|
|
868
1041
|
readonly removeAttribute?: (name: string) => void;
|
|
869
|
-
__marklessDelegatedDispatch?: boolean;
|
|
1042
|
+
__marklessDelegatedDispatch?: boolean | string;
|
|
870
1043
|
__marklessListen?: (eventType: string) => void;
|
|
871
1044
|
__marklessDispatch?: (input: {
|
|
872
1045
|
readonly root: ResumeDomElement;
|
|
@@ -878,6 +1051,7 @@ type ResumeDomElement = ResumeDomNode & {
|
|
|
878
1051
|
__marklessReleaseDispatch?: () => void;
|
|
879
1052
|
__marklessEventOnlyGraph?: Map<string, unknown>;
|
|
880
1053
|
__marklessCensus?: ResumeDomElement[];
|
|
1054
|
+
__marklessComments?: ResumeDomComment[];
|
|
881
1055
|
__marklessBranchArms?: Map<string, ResumeBranchArmEntry>;
|
|
882
1056
|
readonly ownerDocument?: ResumeDomOwnerDocument;
|
|
883
1057
|
};
|
|
@@ -916,7 +1090,7 @@ type ResumeDomEvent = {
|
|
|
916
1090
|
readonly preventDefault?: () => void;
|
|
917
1091
|
readonly stopPropagation?: () => void;
|
|
918
1092
|
readonly composedPath?: () => ReadonlyArray<ResumeDomElement>;
|
|
919
|
-
|
|
1093
|
+
__marklessPressPath?: ReadonlyArray<ResumeDomElement>;
|
|
920
1094
|
};
|
|
921
1095
|
type ResumeSharedPatchEvent = {
|
|
922
1096
|
readonly type: 'async:shared-patch';
|
|
@@ -936,6 +1110,8 @@ type ResumeAsyncBoundaryRecord = {
|
|
|
936
1110
|
readonly endAnchor: ResumeDomComment;
|
|
937
1111
|
readonly asyncReads: ProtocolViewPayload['asyncBoundaries'][number]['asyncReads'];
|
|
938
1112
|
readonly armRecords?: ResumeArmRecordSet | ReadonlyArray<unknown>;
|
|
1113
|
+
readonly composedInstancePath?: string;
|
|
1114
|
+
readonly composedGraphProps?: ProtocolViewPayload['asyncBoundaries'][number]['composedGraphProps'];
|
|
939
1115
|
};
|
|
940
1116
|
type ResumeBranchArmRecordSet = NonNullable<NonNullable<ProtocolViewPayload['branches']>[number]['armRecords']>[number];
|
|
941
1117
|
type ResumeBranchRecord = {
|
|
@@ -1006,6 +1182,13 @@ type ResumeArmRecordSet = {
|
|
|
1006
1182
|
readonly elementHandles: ProtocolViewPayload['elementHandles'];
|
|
1007
1183
|
readonly keyedRepeats?: NonNullable<ProtocolViewPayload['keyedRepeats']>;
|
|
1008
1184
|
readonly branches?: ReadonlyArray<ResumeArmBranchRecord>;
|
|
1185
|
+
/** @try blocks the arm renders inside itself, anchor indexes counted from the arm start. */
|
|
1186
|
+
readonly asyncBoundaries?: ReadonlyArray<Omit<ResumeAsyncBoundaryPayload, 'armRecords'> & {
|
|
1187
|
+
readonly armRecords?: ResumeArmRecordSet;
|
|
1188
|
+
}>;
|
|
1189
|
+
};
|
|
1190
|
+
type ResumeAsyncBoundaryPayload = ProtocolViewPayload['asyncBoundaries'][number] & {
|
|
1191
|
+
readonly armRecords?: ResumeArmRecordSet | ReadonlyArray<unknown>;
|
|
1009
1192
|
};
|
|
1010
1193
|
type ResumeSymbolContext = {
|
|
1011
1194
|
readonly graph?: RuntimeGraph;
|
|
@@ -4,7 +4,7 @@ import { i as protocolStateVersion, n as protocolInstanceQualifies, t as protoco
|
|
|
4
4
|
/** The field names each templated record list may spell, in the order its templates index them. */
|
|
5
5
|
const PROTOCOL_RECORD_KEYS = {
|
|
6
6
|
"markless/state": {
|
|
7
|
-
computed: "graphNodeId name async deriveSymbolId value version root $type $ref source flags records id type fields items entries values bytes arrayType buffer byteOffset length byteLength directValue dependencies path snapshot status key error",
|
|
7
|
+
computed: "graphNodeId name async deriveSymbolId value version root $type $ref source flags records id type fields items entries values bytes arrayType buffer byteOffset length byteLength directValue dependencies path snapshot status key error hostScope",
|
|
8
8
|
sharedSeeds: "graphNodeId deriveSymbolId dependencies path reads",
|
|
9
9
|
sharedDefinitions: "id name exportedName scope version graphNodeIds projectionIds dependencies definitionId definitionName returnProperties kind graphNodeId path"
|
|
10
10
|
},
|
|
@@ -17,34 +17,114 @@ const PROTOCOL_RECORD_KEYS = {
|
|
|
17
17
|
//#endregion
|
|
18
18
|
//#region ../serializer/src/protocol-templated-lists.ts
|
|
19
19
|
/**
|
|
20
|
-
* The record lists a payload script may serve as record templates instead of a plain array.
|
|
21
|
-
*
|
|
20
|
+
* The record lists a payload script may serve as record templates instead of a plain array. A
|
|
21
|
+
* reader that parses a payload script without decoding it may read only the other lists.
|
|
22
22
|
*/
|
|
23
23
|
const PROTOCOL_TEMPLATED_LISTS = {
|
|
24
24
|
"markless/state": [
|
|
25
|
+
"cells",
|
|
25
26
|
"computed",
|
|
26
27
|
"sharedSeeds",
|
|
27
|
-
"sharedDefinitions"
|
|
28
|
+
"sharedDefinitions",
|
|
29
|
+
"sharedRecords"
|
|
28
30
|
],
|
|
29
31
|
"markless/view": [
|
|
32
|
+
"locators",
|
|
33
|
+
"events",
|
|
30
34
|
"domUpdates",
|
|
31
35
|
"behaviors",
|
|
32
|
-
"elementHandles"
|
|
36
|
+
"elementHandles",
|
|
37
|
+
"keyedRepeats"
|
|
33
38
|
]
|
|
34
39
|
};
|
|
35
40
|
//#endregion
|
|
41
|
+
//#region ../serializer/src/protocol-shared-records-decode.ts
|
|
42
|
+
const ref = (slot, copy) => typeof slot === "object" && slot !== null && "$ref" in slot ? { $ref: copy(slot.$ref) } : slot;
|
|
43
|
+
function renamed(record, copy) {
|
|
44
|
+
const map = (slot) => ref(slot, copy);
|
|
45
|
+
if (record.type === "object") return {
|
|
46
|
+
...record,
|
|
47
|
+
fields: record.fields.map(([key, slot]) => [key, map(slot)])
|
|
48
|
+
};
|
|
49
|
+
if (record.type === "array") return {
|
|
50
|
+
...record,
|
|
51
|
+
items: record.items.map(map)
|
|
52
|
+
};
|
|
53
|
+
if (record.type === "map") return {
|
|
54
|
+
...record,
|
|
55
|
+
entries: record.entries.map(([key, value]) => [map(key), map(value)])
|
|
56
|
+
};
|
|
57
|
+
if (record.type === "set") return {
|
|
58
|
+
...record,
|
|
59
|
+
values: record.values.map(map)
|
|
60
|
+
};
|
|
61
|
+
if (record.type === "typed-array" || record.type === "data-view") return {
|
|
62
|
+
...record,
|
|
63
|
+
buffer: map(record.buffer)
|
|
64
|
+
};
|
|
65
|
+
return record;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Gives every envelope of a freshly parsed state payload, in place, a copy of each shared subtree
|
|
69
|
+
* it references, under ids of its own: two references to one shared record are two objects.
|
|
70
|
+
*/
|
|
71
|
+
function expandSharedRecords(state) {
|
|
72
|
+
const payload = state;
|
|
73
|
+
const shared = payload?.sharedRecords;
|
|
74
|
+
if (!shared) return state;
|
|
75
|
+
const byId = new Map(shared.map((record) => [record.id, record]));
|
|
76
|
+
const expand = (envelope) => {
|
|
77
|
+
const records = envelope?.records;
|
|
78
|
+
if (!Array.isArray(records)) return;
|
|
79
|
+
let next = 0;
|
|
80
|
+
for (const record of records) next = Math.max(next, record.id + 1);
|
|
81
|
+
const copies = [];
|
|
82
|
+
const copy = (id) => {
|
|
83
|
+
const record = byId.get(id);
|
|
84
|
+
if (!record) return id;
|
|
85
|
+
const at = next++;
|
|
86
|
+
const slot = copies.push(record) - 1;
|
|
87
|
+
copies[slot] = {
|
|
88
|
+
...renamed(record, copy),
|
|
89
|
+
id: at
|
|
90
|
+
};
|
|
91
|
+
return at;
|
|
92
|
+
};
|
|
93
|
+
const own = records.map((record) => renamed(record, copy));
|
|
94
|
+
if (copies.length) envelope.records = [...own, ...copies];
|
|
95
|
+
};
|
|
96
|
+
for (const cell of payload.cells ?? []) expand(cell?.value);
|
|
97
|
+
for (const computed of payload.computed ?? []) {
|
|
98
|
+
expand(computed?.value);
|
|
99
|
+
const snapshot = computed?.snapshot;
|
|
100
|
+
expand(snapshot?.key);
|
|
101
|
+
expand(snapshot?.value);
|
|
102
|
+
expand(snapshot?.error);
|
|
103
|
+
}
|
|
104
|
+
delete payload.sharedRecords;
|
|
105
|
+
return state;
|
|
106
|
+
}
|
|
107
|
+
//#endregion
|
|
36
108
|
//#region ../serializer/src/protocol-record-templates.ts
|
|
37
|
-
function expandRecordTemplates(list, keys = "") {
|
|
109
|
+
function expandRecordTemplates(list, keys = "", instancePaths = []) {
|
|
38
110
|
if (Array.isArray(list)) return list;
|
|
39
111
|
const { t, r } = list;
|
|
40
112
|
const names = keys.split(" ");
|
|
41
|
-
const
|
|
113
|
+
const paths = [];
|
|
114
|
+
const path = (at) => {
|
|
115
|
+
const entry = instancePaths[at];
|
|
116
|
+
return paths[at] ??= typeof entry === "string" ? entry : path(entry[0]) + entry[1];
|
|
117
|
+
};
|
|
118
|
+
const parts = t.map((text) => text.replace(/~(\d+):/g, (_, at) => `"${names[+at]}":`).split(/([\^`])(\d+)/));
|
|
42
119
|
return r.map((ref) => {
|
|
43
120
|
if (typeof ref === "number") return JSON.parse(parts[ref][0]);
|
|
44
121
|
if (!Array.isArray(ref)) return ref;
|
|
45
122
|
const part = parts[ref[0]];
|
|
46
123
|
let text = part[0];
|
|
47
|
-
for (let at = 1; at < part.length; at +=
|
|
124
|
+
for (let at = 1; at < part.length; at += 3) {
|
|
125
|
+
const value = ref[+part[at + 1] + 1];
|
|
126
|
+
text += (part[at] === "`" ? path(value) : value) + part[at + 2];
|
|
127
|
+
}
|
|
48
128
|
return JSON.parse(text);
|
|
49
129
|
});
|
|
50
130
|
}
|
|
@@ -52,11 +132,20 @@ function expandRecordTemplates(list, keys = "") {
|
|
|
52
132
|
function decodeProtocolPayloadLists(type, payload) {
|
|
53
133
|
const record = payload;
|
|
54
134
|
const keys = PROTOCOL_RECORD_KEYS[type];
|
|
55
|
-
if (record)
|
|
56
|
-
const
|
|
57
|
-
|
|
135
|
+
if (record) {
|
|
136
|
+
const paths = record.instancePaths;
|
|
137
|
+
const inRows = record.inRows;
|
|
138
|
+
for (const key of PROTOCOL_TEMPLATED_LISTS[type]) {
|
|
139
|
+
const list = record[key];
|
|
140
|
+
if (list && !Array.isArray(list)) record[key] = expandRecordTemplates(list, keys[key], paths);
|
|
141
|
+
const rows = inRows?.[key] && expandRecordTemplates(inRows[key], keys[key], paths);
|
|
142
|
+
let at = 0;
|
|
143
|
+
if (rows) record[key] = list.map((item) => item ?? rows[at++]);
|
|
144
|
+
}
|
|
145
|
+
delete record.instancePaths;
|
|
146
|
+
delete record.inRows;
|
|
58
147
|
}
|
|
59
|
-
return payload;
|
|
148
|
+
return expandSharedRecords(payload);
|
|
60
149
|
}
|
|
61
150
|
//#endregion
|
|
62
151
|
//#region ../serializer/src/storage-cookie.ts
|
|
@@ -742,7 +831,7 @@ async function runScalar(root, event, prepared, symbol) {
|
|
|
742
831
|
},
|
|
743
832
|
write(write) {
|
|
744
833
|
check(write.graphNodeId, write.path);
|
|
745
|
-
value = write.value;
|
|
834
|
+
return value = write.value;
|
|
746
835
|
},
|
|
747
836
|
update(update) {
|
|
748
837
|
check(update.graphNodeId, update.path);
|
|
@@ -1330,6 +1419,9 @@ function islandScopedFamilyRecord(record, context) {
|
|
|
1330
1419
|
index: context.commentOffset + Number(anchor.index)
|
|
1331
1420
|
};
|
|
1332
1421
|
}
|
|
1422
|
+
if (isFamilyRecord(record.rowTemplate)) mapped.rowTemplate = islandScopedRowTemplate(record.rowTemplate, island);
|
|
1423
|
+
if ((record.rowTemplate || record.rowComponent) && record.instancePath === void 0 && island.segment) mapped.instancePath = island.segment;
|
|
1424
|
+
if (Array.isArray(record.propRoutes)) mapped.propRoutes = record.propRoutes.map((route) => isFamilyRecord(route) ? islandScopedGraphRecord(route, island) : route);
|
|
1333
1425
|
for (const key of MDX_NESTED_RECORD_KEYS) {
|
|
1334
1426
|
const nested = record[key];
|
|
1335
1427
|
if (Array.isArray(nested)) mapped[key] = nested.map((entry) => isFamilyRecord(entry) ? islandScopedFamilyRecord(entry, context) : entry);
|
|
@@ -1337,6 +1429,26 @@ function islandScopedFamilyRecord(record, context) {
|
|
|
1337
1429
|
}
|
|
1338
1430
|
return mapped;
|
|
1339
1431
|
}
|
|
1432
|
+
function islandScopedRowTemplate(template, island) {
|
|
1433
|
+
const slot = (value) => {
|
|
1434
|
+
if (!isFamilyRecord(value)) return value;
|
|
1435
|
+
const scoped = { ...islandScopedGraphRecord(value, island) };
|
|
1436
|
+
if (Array.isArray(value.reads)) scoped.reads = value.reads.map((read) => isFamilyRecord(read) ? islandScopedGraphRecord(read, island) : read);
|
|
1437
|
+
if (Array.isArray(value.arms)) scoped.arms = value.arms.map(slots);
|
|
1438
|
+
return scoped;
|
|
1439
|
+
};
|
|
1440
|
+
const slots = (owner) => {
|
|
1441
|
+
if (!isFamilyRecord(owner)) return owner;
|
|
1442
|
+
const scoped = { ...owner };
|
|
1443
|
+
for (const key of [
|
|
1444
|
+
"textSlots",
|
|
1445
|
+
"attributeSlots",
|
|
1446
|
+
"branchSlots"
|
|
1447
|
+
]) if (Array.isArray(owner[key])) scoped[key] = owner[key].map(slot);
|
|
1448
|
+
return scoped;
|
|
1449
|
+
};
|
|
1450
|
+
return slots(template);
|
|
1451
|
+
}
|
|
1340
1452
|
function isFamilyRecord(value) {
|
|
1341
1453
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1342
1454
|
}
|