@markless/router 0.9.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-CVhSjR45.js → create-server-entry-BnaEfDHl.js} +288 -68
- package/dist/index.js +2 -2
- package/dist/{request-locals-BPfJaoM_.js → navigation-timing-CzH6VaBR.js} +2 -1
- 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 +188 -6
- package/dist/vite/runtime/mdx-route.js +124 -12
- package/dist/vite.js +384 -62
- package/package.json +5 -5
- package/src/vite/entries/fragment-entry.ts +433 -254
- 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";
|
|
@@ -92,4 +93,4 @@ function takeMiddlewareHeaders(request) {
|
|
|
92
93
|
return record.taken;
|
|
93
94
|
}
|
|
94
95
|
//#endregion
|
|
95
|
-
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;
|
|
@@ -133,6 +218,7 @@ type ProtocolStatePayload = {
|
|
|
133
218
|
readonly graphNodeId: string;
|
|
134
219
|
readonly key: string;
|
|
135
220
|
}>;
|
|
221
|
+
readonly sharedRecords?: ReadonlyArray<SerializedRecord>;
|
|
136
222
|
};
|
|
137
223
|
type ProtocolBranchContentRead = {
|
|
138
224
|
readonly graphNodeId: string;
|
|
@@ -198,6 +284,8 @@ type ProtocolArmRecordSet = {
|
|
|
198
284
|
readonly elementHandles: ProtocolViewPayload['elementHandles'];
|
|
199
285
|
readonly keyedRepeats?: ProtocolViewPayload['keyedRepeats'];
|
|
200
286
|
readonly branches?: ReadonlyArray<ProtocolArmBranchRecord>;
|
|
287
|
+
/** Served beside `events` sent as templates: the names the stream boot listens for. */
|
|
288
|
+
readonly eventNames?: ReadonlyArray<string>;
|
|
201
289
|
};
|
|
202
290
|
/**
|
|
203
291
|
* Where one row-template slot's value comes from: the repeated item, a graph
|
|
@@ -225,6 +313,23 @@ type ProtocolRowTemplateSlotValue = {
|
|
|
225
313
|
readonly path: ReadonlyArray<string>;
|
|
226
314
|
}>;
|
|
227
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;
|
|
228
333
|
type ProtocolViewPayload = {
|
|
229
334
|
readonly version: typeof ASYNC_PROTOCOL_VERSION;
|
|
230
335
|
readonly asyncRunners?: Readonly<Record<string, string>>;
|
|
@@ -341,7 +446,7 @@ type ProtocolViewPayload = {
|
|
|
341
446
|
*/
|
|
342
447
|
readonly enclosingRow?: {
|
|
343
448
|
readonly repeatId: string;
|
|
344
|
-
readonly parentHostPath:
|
|
449
|
+
readonly parentHostPath: ProtocolElementAddress;
|
|
345
450
|
readonly itemPath?: ReadonlyArray<string>;
|
|
346
451
|
};
|
|
347
452
|
readonly collectionGraphNodeId?: string;
|
|
@@ -364,6 +469,11 @@ type ProtocolViewPayload = {
|
|
|
364
469
|
readonly arm: number;
|
|
365
470
|
};
|
|
366
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;
|
|
367
477
|
readonly rowElementCount: number;
|
|
368
478
|
/**
|
|
369
479
|
* Element children of the parent that stand before the rows. Rows occupy
|
|
@@ -442,6 +552,18 @@ type ProtocolViewPayload = {
|
|
|
442
552
|
readonly path: ReadonlyArray<number>;
|
|
443
553
|
readonly name: string;
|
|
444
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>;
|
|
445
567
|
};
|
|
446
568
|
/**
|
|
447
569
|
* The parent graph node each prop a `rowTemplate` source slot reads follows,
|
|
@@ -494,16 +616,25 @@ type ProtocolViewPayload = {
|
|
|
494
616
|
readonly rowChunkId?: string;
|
|
495
617
|
};
|
|
496
618
|
readonly rowElementHandles?: ReadonlyArray<{
|
|
497
|
-
readonly hostPath:
|
|
619
|
+
readonly hostPath: ProtocolElementAddress;
|
|
498
620
|
readonly handleId: string;
|
|
499
621
|
readonly name: string;
|
|
500
622
|
readonly plural?: boolean;
|
|
501
623
|
}>;
|
|
502
624
|
readonly rowEvents: ReadonlyArray<{
|
|
503
|
-
readonly hostPath:
|
|
625
|
+
readonly hostPath: ProtocolElementAddress;
|
|
504
626
|
readonly eventName: string;
|
|
505
627
|
readonly symbolIds: ReadonlyArray<string>;
|
|
506
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
|
+
};
|
|
507
638
|
}>;
|
|
508
639
|
}>;
|
|
509
640
|
readonly branches?: ReadonlyArray<{
|
|
@@ -520,7 +651,7 @@ type ProtocolViewPayload = {
|
|
|
520
651
|
readonly armTests?: ReadonlyArray<unknown>;
|
|
521
652
|
readonly armRecords?: ReadonlyArray<{
|
|
522
653
|
readonly events: ReadonlyArray<{
|
|
523
|
-
readonly hostPath:
|
|
654
|
+
readonly hostPath: ProtocolElementAddress;
|
|
524
655
|
readonly eventName: string;
|
|
525
656
|
readonly symbolIds: ReadonlyArray<string>;
|
|
526
657
|
readonly syncPolicy?: ProtocolSyncPolicy;
|
|
@@ -603,6 +734,9 @@ type ProtocolViewPayload = {
|
|
|
603
734
|
readonly path: ReadonlyArray<string>;
|
|
604
735
|
readonly runnerSymbolId?: string;
|
|
605
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>;
|
|
606
740
|
}>;
|
|
607
741
|
};
|
|
608
742
|
//#endregion
|
|
@@ -689,7 +823,27 @@ type RuntimeDemandMapClosurePlan = {
|
|
|
689
823
|
}>;
|
|
690
824
|
};
|
|
691
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
|
|
692
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
|
+
};
|
|
693
847
|
type RuntimeGraphAsyncSnapshot = {
|
|
694
848
|
readonly status: 'idle';
|
|
695
849
|
readonly version: 0;
|
|
@@ -709,6 +863,19 @@ type RuntimeGraphAsyncSnapshot = {
|
|
|
709
863
|
readonly key: unknown;
|
|
710
864
|
readonly error: unknown;
|
|
711
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
|
+
};
|
|
712
879
|
type DomJournalEntry = {
|
|
713
880
|
readonly type: 'setText';
|
|
714
881
|
readonly locator: string;
|
|
@@ -778,6 +945,8 @@ type RuntimeGraphSubscription = {
|
|
|
778
945
|
readonly graphNodeId: string;
|
|
779
946
|
readonly path?: ReadonlyArray<string>;
|
|
780
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;
|
|
781
950
|
};
|
|
782
951
|
/**
|
|
783
952
|
* Told about a write the moment it lands, before the flush that write schedules.
|
|
@@ -820,11 +989,14 @@ type RuntimeGraph = {
|
|
|
820
989
|
readonly listSharedDefinitions: () => NonNullable<ProtocolStatePayload['sharedDefinitions']>;
|
|
821
990
|
readonly takeSharedPatches: () => RuntimeGraphSharedPatch[];
|
|
822
991
|
readonly applySharedPatch: (patch: RuntimeGraphSharedPatch) => boolean;
|
|
823
|
-
|
|
992
|
+
/** Answers the value written, as the assignment it lowers from does. */
|
|
993
|
+
readonly write: (write: RuntimeGraphWrite) => unknown;
|
|
824
994
|
readonly update: (update: RuntimeGraphUpdate) => unknown;
|
|
825
995
|
readonly call: (call: RuntimeGraphCall) => unknown;
|
|
826
996
|
readonly delete: (deletion: RuntimeGraphDelete) => boolean;
|
|
827
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;
|
|
828
1000
|
/**
|
|
829
1001
|
* Optional so a facade over a subset of this contract stays a `RuntimeGraph`;
|
|
830
1002
|
* a caller without it gets the flush-time answer it always had.
|
|
@@ -879,6 +1051,7 @@ type ResumeDomElement = ResumeDomNode & {
|
|
|
879
1051
|
__marklessReleaseDispatch?: () => void;
|
|
880
1052
|
__marklessEventOnlyGraph?: Map<string, unknown>;
|
|
881
1053
|
__marklessCensus?: ResumeDomElement[];
|
|
1054
|
+
__marklessComments?: ResumeDomComment[];
|
|
882
1055
|
__marklessBranchArms?: Map<string, ResumeBranchArmEntry>;
|
|
883
1056
|
readonly ownerDocument?: ResumeDomOwnerDocument;
|
|
884
1057
|
};
|
|
@@ -917,7 +1090,7 @@ type ResumeDomEvent = {
|
|
|
917
1090
|
readonly preventDefault?: () => void;
|
|
918
1091
|
readonly stopPropagation?: () => void;
|
|
919
1092
|
readonly composedPath?: () => ReadonlyArray<ResumeDomElement>;
|
|
920
|
-
|
|
1093
|
+
__marklessPressPath?: ReadonlyArray<ResumeDomElement>;
|
|
921
1094
|
};
|
|
922
1095
|
type ResumeSharedPatchEvent = {
|
|
923
1096
|
readonly type: 'async:shared-patch';
|
|
@@ -937,6 +1110,8 @@ type ResumeAsyncBoundaryRecord = {
|
|
|
937
1110
|
readonly endAnchor: ResumeDomComment;
|
|
938
1111
|
readonly asyncReads: ProtocolViewPayload['asyncBoundaries'][number]['asyncReads'];
|
|
939
1112
|
readonly armRecords?: ResumeArmRecordSet | ReadonlyArray<unknown>;
|
|
1113
|
+
readonly composedInstancePath?: string;
|
|
1114
|
+
readonly composedGraphProps?: ProtocolViewPayload['asyncBoundaries'][number]['composedGraphProps'];
|
|
940
1115
|
};
|
|
941
1116
|
type ResumeBranchArmRecordSet = NonNullable<NonNullable<ProtocolViewPayload['branches']>[number]['armRecords']>[number];
|
|
942
1117
|
type ResumeBranchRecord = {
|
|
@@ -1007,6 +1182,13 @@ type ResumeArmRecordSet = {
|
|
|
1007
1182
|
readonly elementHandles: ProtocolViewPayload['elementHandles'];
|
|
1008
1183
|
readonly keyedRepeats?: NonNullable<ProtocolViewPayload['keyedRepeats']>;
|
|
1009
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>;
|
|
1010
1192
|
};
|
|
1011
1193
|
type ResumeSymbolContext = {
|
|
1012
1194
|
readonly graph?: RuntimeGraph;
|
|
@@ -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
|
}
|