@vesk/runtime 0.2.94 → 0.2.95
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/hydrate.d.ts +24 -3
- package/dist/hydrate.d.ts.map +1 -1
- package/dist/hydrate.js +146 -16
- package/dist/resource.d.ts +1 -1
- package/dist/resource.d.ts.map +1 -1
- package/dist/resource.js +32 -16
- package/dist/router.d.ts +1 -0
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +83 -5
- package/package.json +2 -2
package/dist/hydrate.d.ts
CHANGED
|
@@ -17,16 +17,30 @@ export interface ClaimByKeyOptions {
|
|
|
17
17
|
*/
|
|
18
18
|
skipK?: number;
|
|
19
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* Minimal compiler-generated shape descriptor for a structural claim. It never
|
|
22
|
+
* touches the DOM; the client program carries it. Only stable, source-authored
|
|
23
|
+
* static class tokens are validated — dynamic values are deliberately ignored
|
|
24
|
+
* because SSR text/attributes may legitimately differ at first paint.
|
|
25
|
+
*/
|
|
26
|
+
export interface HydrateClaimDescriptor {
|
|
27
|
+
class?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface StructuralRegionBranchDescriptor {
|
|
30
|
+
tag?: string;
|
|
31
|
+
descriptor?: HydrateClaimDescriptor | null;
|
|
32
|
+
count: number;
|
|
33
|
+
}
|
|
20
34
|
export interface HydrateWalker {
|
|
21
35
|
root: HTMLElement | null;
|
|
22
36
|
done(): boolean;
|
|
23
|
-
nextElement(tag?: string, skipK?: number): Element;
|
|
37
|
+
nextElement(tag?: string, skipK?: number, descriptor?: HydrateClaimDescriptor): Element;
|
|
24
38
|
/**
|
|
25
39
|
* Claim an element like `nextElement` but without stripping its direct text
|
|
26
40
|
* children. Used by static-component stubs whose SSR content is preserved
|
|
27
41
|
* as-is (no client-side re-creation of text nodes).
|
|
28
42
|
*/
|
|
29
|
-
claimOnly?(tag?: string): Element;
|
|
43
|
+
claimOnly?(tag?: string, skipK?: number, descriptor?: HydrateClaimDescriptor): Element;
|
|
30
44
|
/**
|
|
31
45
|
* Drop any remaining markers whose comment node is no longer attached to
|
|
32
46
|
* the document. Self-claiming runtime components (Link/NavLink/Md/Form/
|
|
@@ -85,6 +99,13 @@ export interface HydrateWalker {
|
|
|
85
99
|
*/
|
|
86
100
|
injectSkipK?(n: number): void;
|
|
87
101
|
takeSkipK?(): number;
|
|
102
|
+
/**
|
|
103
|
+
* Markerless structural branch reconciliation: identify the SSR branch
|
|
104
|
+
* sitting at the region's cursor slot by its static descriptor, and
|
|
105
|
+
* discard that branch's SSR residue when the client selected a different
|
|
106
|
+
* branch (or no branch). Returns true when a branch was discarded.
|
|
107
|
+
*/
|
|
108
|
+
discardStructuralRegion?(branches: StructuralRegionBranchDescriptor[], selected: number, skipK?: number): boolean;
|
|
88
109
|
}
|
|
89
110
|
interface HydrateIdleOptions {
|
|
90
111
|
chunkSize?: number;
|
|
@@ -105,7 +126,7 @@ interface HydrateCancel extends HydrateCancelBase {
|
|
|
105
126
|
*/
|
|
106
127
|
export declare function reactiveProps<T extends Record<string, unknown>>(props: T): T;
|
|
107
128
|
export declare function setHydrateDevMode(enabled: boolean): void;
|
|
108
|
-
export type HydrationIssueKind = 'tag-mismatch' | 'exhausted' | 'leftover-marker' | 'twin' | 'key-reorder' | 'marker-skew' | 'untyped-marker';
|
|
129
|
+
export type HydrationIssueKind = 'tag-mismatch' | 'descriptor-mismatch' | 'exhausted' | 'leftover-marker' | 'twin' | 'key-reorder' | 'marker-skew' | 'untyped-marker';
|
|
109
130
|
export interface HydrationIssue {
|
|
110
131
|
kind: HydrationIssueKind;
|
|
111
132
|
detail: string;
|
package/dist/hydrate.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hydrate.d.ts","sourceRoot":"","sources":["../src/hydrate.ts"],"names":[],"mappings":"AAyBA,MAAM,WAAW,YAAY;IAC5B,EAAE,EAAE,OAAO,CAAC;CACZ;AAED,MAAM,WAAW,iBAAiB;IACjC;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IACzB,IAAI,IAAI,OAAO,CAAC;IAChB,WAAW,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"hydrate.d.ts","sourceRoot":"","sources":["../src/hydrate.ts"],"names":[],"mappings":"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"}
|
package/dist/hydrate.js
CHANGED
|
@@ -874,16 +874,73 @@ class WalkerEngine {
|
|
|
874
874
|
// markerless design walks PLAIN server HTML: a per-parent stack of element
|
|
875
875
|
// lists, claimed positionally by `skipK` (the number of source siblings the
|
|
876
876
|
// caller already consumed — static residues it retrieved from `__vsk_ssrEls`)
|
|
877
|
-
//
|
|
878
|
-
// descriptor
|
|
879
|
-
//
|
|
880
|
-
//
|
|
881
|
-
// The SSR node is never
|
|
877
|
+
// by tag and, at component/region roots, an optional compiler-generated static
|
|
878
|
+
// class descriptor. The compiler emits `nextElement(tag, skipK, descriptor)`
|
|
879
|
+
// claims; divergence follows §2.2 step 4: a tag or descriptor mismatch consumes
|
|
880
|
+
// exactly one slot, reports, detaches the provably-owned direct-child ghost,
|
|
881
|
+
// and hands back a fresh element that the caller mounts. The SSR node is never
|
|
882
|
+
// bound.
|
|
882
883
|
//
|
|
883
884
|
// The same engine backs `createHydrateChildWalker`, so runtime components that
|
|
884
885
|
// claim offspring positionally (loading stubs, slot content) keep working with
|
|
885
886
|
// identical semantics.
|
|
886
887
|
// ---------------------------------------------------------------------------
|
|
888
|
+
/**
|
|
889
|
+
* Split a class attribute into tokens without a regex (runtime helpers follow
|
|
890
|
+
* the tokenizer style used by md.ts). Only used for the descriptor's static
|
|
891
|
+
* class fingerprint.
|
|
892
|
+
*/
|
|
893
|
+
function classTokens(value) {
|
|
894
|
+
const out = [];
|
|
895
|
+
let token = '';
|
|
896
|
+
for (let i = 0; i < value.length; i++) {
|
|
897
|
+
const ch = value[i];
|
|
898
|
+
if (ch === ' ' || ch === '\n' || ch === '\t' || ch === '\r' || ch === '\f') {
|
|
899
|
+
if (token) {
|
|
900
|
+
out.push(token);
|
|
901
|
+
token = '';
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
else {
|
|
905
|
+
token += ch;
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
if (token)
|
|
909
|
+
out.push(token);
|
|
910
|
+
return out;
|
|
911
|
+
}
|
|
912
|
+
function descriptorMatches(el, descriptor) {
|
|
913
|
+
if (!descriptor || !descriptor.class)
|
|
914
|
+
return true;
|
|
915
|
+
const wanted = classTokens(descriptor.class);
|
|
916
|
+
if (wanted.length === 0)
|
|
917
|
+
return true;
|
|
918
|
+
const actual = el.classList;
|
|
919
|
+
if (actual) {
|
|
920
|
+
for (const token of wanted) {
|
|
921
|
+
if (!actual.contains(token))
|
|
922
|
+
return false;
|
|
923
|
+
}
|
|
924
|
+
return true;
|
|
925
|
+
}
|
|
926
|
+
// Minimal DOM shims (tests, linkedom variants) may expose className or only
|
|
927
|
+
// the class attribute instead of a live classList.
|
|
928
|
+
const raw = el.getAttribute('class') ?? el.className ?? '';
|
|
929
|
+
const present = classTokens(String(raw));
|
|
930
|
+
for (const token of wanted) {
|
|
931
|
+
if (!present.includes(token))
|
|
932
|
+
return false;
|
|
933
|
+
}
|
|
934
|
+
return true;
|
|
935
|
+
}
|
|
936
|
+
function structuralBranchMatches(el, branch) {
|
|
937
|
+
const actualTag = el.tagName.toLowerCase();
|
|
938
|
+
if (branch.tag && actualTag !== branch.tag)
|
|
939
|
+
return false;
|
|
940
|
+
if (branch.descriptor)
|
|
941
|
+
return descriptorMatches(el, branch.descriptor);
|
|
942
|
+
return !!branch.tag;
|
|
943
|
+
}
|
|
887
944
|
class StructuralWalker {
|
|
888
945
|
root;
|
|
889
946
|
// Snapshot taken at construction, so fresh nodes mounted during the render
|
|
@@ -975,7 +1032,7 @@ class StructuralWalker {
|
|
|
975
1032
|
this.inheritOffset = 0;
|
|
976
1033
|
return n;
|
|
977
1034
|
}
|
|
978
|
-
claimAt(tag, skipK, raw) {
|
|
1035
|
+
claimAt(tag, skipK, raw, descriptor) {
|
|
979
1036
|
if (globalThis.__vesk_hydrate_debug) {
|
|
980
1037
|
// eslint-disable-next-line no-console
|
|
981
1038
|
console.error('[hyd-dbg] claimAt', tag, 'skip=', skipK, 'idx=', this.idx, 'els=', this.els.length);
|
|
@@ -995,17 +1052,21 @@ class StructuralWalker {
|
|
|
995
1052
|
target = this.idx;
|
|
996
1053
|
while (target < this.els.length) {
|
|
997
1054
|
const el = this.els[target];
|
|
998
|
-
|
|
1055
|
+
const actualTag = el.tagName.toLowerCase();
|
|
1056
|
+
const tagMismatch = !!tag && actualTag !== tag;
|
|
1057
|
+
const descriptorMismatch = !tagMismatch && !descriptorMatches(el, descriptor);
|
|
1058
|
+
if (tagMismatch || descriptorMismatch) {
|
|
999
1059
|
// §2.2 step 4: descriptor failed. Consume exactly ONE slot and
|
|
1000
1060
|
// hand back a fresh element. The direct-child SSR ghost is
|
|
1001
1061
|
// detached below; nested recovery remains owned by its child walker.
|
|
1002
1062
|
this.idx = this.advancePastSkippable(target + 1);
|
|
1063
|
+
const expectedTag = tag || 'div';
|
|
1003
1064
|
const ghost = {
|
|
1004
1065
|
state: 'ghost',
|
|
1005
1066
|
el,
|
|
1006
1067
|
owner: this.root,
|
|
1007
|
-
expectedTag
|
|
1008
|
-
actualTag
|
|
1068
|
+
expectedTag,
|
|
1069
|
+
actualTag,
|
|
1009
1070
|
detached: false,
|
|
1010
1071
|
};
|
|
1011
1072
|
recordClaim(this.root, ghost);
|
|
@@ -1021,16 +1082,20 @@ class StructuralWalker {
|
|
|
1021
1082
|
// The final sweep will report/repair a still-owned ghost.
|
|
1022
1083
|
}
|
|
1023
1084
|
}
|
|
1024
|
-
const fresh = document.createElement(
|
|
1085
|
+
const fresh = document.createElement(expectedTag);
|
|
1025
1086
|
recordClaim(this.root, {
|
|
1026
1087
|
state: 'fresh',
|
|
1027
1088
|
el: fresh,
|
|
1028
1089
|
owner: this.root,
|
|
1029
|
-
expectedTag
|
|
1090
|
+
expectedTag,
|
|
1030
1091
|
actualTag: fresh.tagName.toLowerCase(),
|
|
1031
1092
|
detached: false,
|
|
1032
1093
|
});
|
|
1033
|
-
|
|
1094
|
+
const actualClass = el.getAttribute('class') || '';
|
|
1095
|
+
const detail = descriptorMismatch
|
|
1096
|
+
? `descriptor wanted <${expectedTag} class="${descriptor?.class || ''}"> but the SSR slot holds <${actualTag} class="${actualClass}">; consumed one slot, detached the local ghost, and rendered fresh.`
|
|
1097
|
+
: `descriptor wanted <${tag}> but the SSR slot holds <${actualTag}>; consumed one slot, detached the local ghost, and rendered fresh.`;
|
|
1098
|
+
reportMiss(descriptorMismatch ? 'descriptor-mismatch' : 'tag-mismatch', detail, false);
|
|
1034
1099
|
return fresh;
|
|
1035
1100
|
}
|
|
1036
1101
|
if (this.adopted.has(el)) {
|
|
@@ -1064,11 +1129,76 @@ class StructuralWalker {
|
|
|
1064
1129
|
false);
|
|
1065
1130
|
return fresh;
|
|
1066
1131
|
}
|
|
1067
|
-
nextElement(tag, skipK = 0) {
|
|
1068
|
-
return this.claimAt(tag, skipK, false);
|
|
1132
|
+
nextElement(tag, skipK = 0, descriptor) {
|
|
1133
|
+
return this.claimAt(tag, skipK, false, descriptor);
|
|
1134
|
+
}
|
|
1135
|
+
claimOnly(tag, skipK = 0, descriptor) {
|
|
1136
|
+
return this.claimAt(tag, skipK, true, descriptor);
|
|
1069
1137
|
}
|
|
1070
|
-
|
|
1071
|
-
|
|
1138
|
+
discardStructuralRegion(branches, selected, skipK = 0) {
|
|
1139
|
+
if (!branches || branches.length === 0)
|
|
1140
|
+
return false;
|
|
1141
|
+
let offset = skipK || 0;
|
|
1142
|
+
if (!offset)
|
|
1143
|
+
offset = this.inheritOffset;
|
|
1144
|
+
let target = this.advancePastSkippable(this.idx + offset);
|
|
1145
|
+
if (target > this.els.length)
|
|
1146
|
+
target = this.idx;
|
|
1147
|
+
target = this.advancePastSkippable(target);
|
|
1148
|
+
while (target < this.els.length) {
|
|
1149
|
+
const el = this.els[target];
|
|
1150
|
+
if (this.adopted.has(el)) {
|
|
1151
|
+
target = this.advancePastSkippable(target + 1);
|
|
1152
|
+
continue;
|
|
1153
|
+
}
|
|
1154
|
+
let matchCount = 0;
|
|
1155
|
+
let matchIdx = -1;
|
|
1156
|
+
for (let i = 0; i < branches.length; i++) {
|
|
1157
|
+
if (structuralBranchMatches(el, branches[i])) {
|
|
1158
|
+
matchCount++;
|
|
1159
|
+
matchIdx = i;
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
if (matchCount !== 1 || matchIdx === selected)
|
|
1163
|
+
return false;
|
|
1164
|
+
const count = branches[matchIdx].count;
|
|
1165
|
+
if (!count || count < 1)
|
|
1166
|
+
return false;
|
|
1167
|
+
this.inheritOffset = 0;
|
|
1168
|
+
let p = target;
|
|
1169
|
+
let removed = 0;
|
|
1170
|
+
while (removed < count && p < this.els.length) {
|
|
1171
|
+
const candidate = this.els[p];
|
|
1172
|
+
if (this.adopted.has(candidate)) {
|
|
1173
|
+
p = this.advancePastSkippable(p + 1);
|
|
1174
|
+
continue;
|
|
1175
|
+
}
|
|
1176
|
+
const actualTag = candidate.tagName.toLowerCase();
|
|
1177
|
+
const ghost = {
|
|
1178
|
+
state: 'ghost',
|
|
1179
|
+
el: candidate,
|
|
1180
|
+
owner: this.root,
|
|
1181
|
+
expectedTag: branches[matchIdx].tag || actualTag,
|
|
1182
|
+
actualTag,
|
|
1183
|
+
detached: false,
|
|
1184
|
+
};
|
|
1185
|
+
recordClaim(this.root, ghost);
|
|
1186
|
+
if (this.root && candidate.parentNode === this.root) {
|
|
1187
|
+
try {
|
|
1188
|
+
candidate.remove();
|
|
1189
|
+
ghost.detached = true;
|
|
1190
|
+
}
|
|
1191
|
+
catch {
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
p = this.advancePastSkippable(p + 1);
|
|
1195
|
+
removed++;
|
|
1196
|
+
}
|
|
1197
|
+
this.idx = p;
|
|
1198
|
+
reportMiss('descriptor-mismatch', `structural region reconciliation removed SSR branch ${matchIdx}; the client selected branch ${selected}.`, false);
|
|
1199
|
+
return true;
|
|
1200
|
+
}
|
|
1201
|
+
return false;
|
|
1072
1202
|
}
|
|
1073
1203
|
subWalker(rootEl) {
|
|
1074
1204
|
if (globalThis.__vesk_hydrate_debug) {
|
package/dist/resource.d.ts
CHANGED
package/dist/resource.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAQhE,MAAM,WAAW,QAAQ,CAAC,CAAC,CAAE,SAAQ,
|
|
1
|
+
{"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"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"}
|
package/dist/resource.js
CHANGED
|
@@ -212,8 +212,11 @@ function resolveFetchUrl(url) {
|
|
|
212
212
|
if (/^[a-z][a-z0-9+.-]*:/i.test(url) || url.startsWith('//'))
|
|
213
213
|
return url;
|
|
214
214
|
const ctx = g().__vesk_request;
|
|
215
|
+
// Bind the resolver: on the server the request context is often a
|
|
216
|
+
// `VeskRequest`, whose `resolveUrl` is a prototype method that reads
|
|
217
|
+
// `this.origin`. Calling it unbound throws "reading 'origin' of undefined".
|
|
215
218
|
const resolver = ctx && typeof ctx.resolveUrl === 'function'
|
|
216
|
-
? ctx.resolveUrl
|
|
219
|
+
? ctx.resolveUrl.bind(ctx)
|
|
217
220
|
: null;
|
|
218
221
|
if (resolver)
|
|
219
222
|
return resolver(url);
|
|
@@ -559,20 +562,25 @@ export function mutate(key, data) {
|
|
|
559
562
|
registry.forEach(h => startRequest(h, true));
|
|
560
563
|
}
|
|
561
564
|
}
|
|
565
|
+
class ResourcePromise extends Promise {
|
|
566
|
+
read;
|
|
567
|
+
constructor(read) {
|
|
568
|
+
super(() => { });
|
|
569
|
+
this.read = read;
|
|
570
|
+
}
|
|
571
|
+
then(onfulfilled, onrejected) {
|
|
572
|
+
return this.read().then(onfulfilled, onrejected);
|
|
573
|
+
}
|
|
574
|
+
catch(onrejected) {
|
|
575
|
+
return this.read().catch(onrejected);
|
|
576
|
+
}
|
|
577
|
+
finally(onfinally) {
|
|
578
|
+
return this.read().finally(onfinally);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
562
581
|
function createResourceAccessor(handle) {
|
|
563
582
|
const state = handle.state;
|
|
564
|
-
const
|
|
565
|
-
Object.defineProperty(accessor, 'loading', {
|
|
566
|
-
get() { return get(state).loading; },
|
|
567
|
-
});
|
|
568
|
-
Object.defineProperty(accessor, 'error', {
|
|
569
|
-
get() { return get(state).error; },
|
|
570
|
-
});
|
|
571
|
-
Object.defineProperty(accessor, 'data', {
|
|
572
|
-
get() { return get(state).data; },
|
|
573
|
-
});
|
|
574
|
-
accessor._state = state;
|
|
575
|
-
const toData = async () => {
|
|
583
|
+
const read = async () => {
|
|
576
584
|
for (;;) {
|
|
577
585
|
const s = get(state);
|
|
578
586
|
if (!s.loading) {
|
|
@@ -583,9 +591,17 @@ function createResourceAccessor(handle) {
|
|
|
583
591
|
await handle.settled;
|
|
584
592
|
}
|
|
585
593
|
};
|
|
586
|
-
accessor
|
|
587
|
-
|
|
588
|
-
|
|
594
|
+
const accessor = new ResourcePromise(read);
|
|
595
|
+
Object.defineProperty(accessor, 'loading', {
|
|
596
|
+
get() { return get(state).loading; },
|
|
597
|
+
});
|
|
598
|
+
Object.defineProperty(accessor, 'error', {
|
|
599
|
+
get() { return get(state).error; },
|
|
600
|
+
});
|
|
601
|
+
Object.defineProperty(accessor, 'data', {
|
|
602
|
+
get() { return get(state).data; },
|
|
603
|
+
});
|
|
604
|
+
accessor._state = state;
|
|
589
605
|
accessor.refresh = () => revalidate(handle);
|
|
590
606
|
accessor.abort = () => {
|
|
591
607
|
if (!isServer())
|
package/dist/router.d.ts
CHANGED
|
@@ -82,6 +82,7 @@ type GuardFn = (to: string, from: string) => false | string | void | Promise<fal
|
|
|
82
82
|
export declare function createRouter(routes: RouteNode[] | Record<string, Function>, options?: RouterOptions): RouterInstance;
|
|
83
83
|
interface FileRouterOptions extends RouterOptions {
|
|
84
84
|
middleware?: Function | Function[];
|
|
85
|
+
serverMiddleware?: boolean;
|
|
85
86
|
render?: (router: RouterInstance, match: RouteMatch, container: HTMLElement) => void;
|
|
86
87
|
}
|
|
87
88
|
interface FileRouterInstance extends RouterInstance {
|
package/dist/router.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}
|
package/dist/router.js
CHANGED
|
@@ -1046,6 +1046,21 @@ async function renderErrorPage(router, match, container, error, navToken) {
|
|
|
1046
1046
|
container.innerHTML = dom;
|
|
1047
1047
|
}
|
|
1048
1048
|
}
|
|
1049
|
+
/**
|
|
1050
|
+
* Marks the initial-hydration lifecycle on `globalThis.__vesk_hydrated`.
|
|
1051
|
+
* `window.__vesk_router` is assigned before the layout/page hydration runs, and
|
|
1052
|
+
* claiming a large layout chain can take seconds on low-end devices — so tools
|
|
1053
|
+
* (e2e harnesses, boot scripts) that need "handlers are attached and the SSR
|
|
1054
|
+
* DOM is claimed" must wait for this flag, not the router. Set false while the
|
|
1055
|
+
* hydration promise is in flight, true once it settles (resolved or rejected —
|
|
1056
|
+
* the error path still renders an interactive error component).
|
|
1057
|
+
*/
|
|
1058
|
+
function trackHydration(promise) {
|
|
1059
|
+
const g = globalThis;
|
|
1060
|
+
g.__vesk_hydrated = false;
|
|
1061
|
+
promise.then(() => { g.__vesk_hydrated = true; }, () => { g.__vesk_hydrated = true; });
|
|
1062
|
+
return promise;
|
|
1063
|
+
}
|
|
1049
1064
|
async function hydrateInitial(router, match, container, strategy) {
|
|
1050
1065
|
// Token at hydration start (usually 0 — before any client navigation).
|
|
1051
1066
|
// Every container paint below passes it to its async renderer so a
|
|
@@ -1444,15 +1459,17 @@ export function createRouter(routes, options = {}) {
|
|
|
1444
1459
|
const match = matchRoute(this.routeTree, url.pathname);
|
|
1445
1460
|
if (match) {
|
|
1446
1461
|
match.pathname = url.pathname;
|
|
1447
|
-
hydrateInitial(this, match, container, hydrateStrategy);
|
|
1462
|
+
trackHydration(hydrateInitial(this, match, container, hydrateStrategy));
|
|
1448
1463
|
this._currentMatch = match;
|
|
1449
1464
|
}
|
|
1450
1465
|
else {
|
|
1451
1466
|
this.navigate(path, { replace: true });
|
|
1467
|
+
globalThis.__vesk_hydrated = true;
|
|
1452
1468
|
}
|
|
1453
1469
|
}
|
|
1454
1470
|
else {
|
|
1455
1471
|
this.navigate(path, { replace: true });
|
|
1472
|
+
globalThis.__vesk_hydrated = true;
|
|
1456
1473
|
}
|
|
1457
1474
|
return this;
|
|
1458
1475
|
},
|
|
@@ -1497,7 +1514,15 @@ export function createRouter(routes, options = {}) {
|
|
|
1497
1514
|
const updateUrl = () => {
|
|
1498
1515
|
const fullPath = url.pathname + url.search;
|
|
1499
1516
|
const target = mode ? (fullPath.startsWith('/') ? '#' + fullPath : '#' + fullPath) : fullPath;
|
|
1500
|
-
|
|
1517
|
+
// Re-check the live location here, not just at navigate()
|
|
1518
|
+
// entry: an async middleware/guard chain defers this push, so
|
|
1519
|
+
// a second navigation started before the first one lands
|
|
1520
|
+
// would otherwise push the same URL twice.
|
|
1521
|
+
const liveFull = window.location.pathname + window.location.search + window.location.hash;
|
|
1522
|
+
if (!opts.replace && target === liveFull) {
|
|
1523
|
+
// already current — do not duplicate the history entry
|
|
1524
|
+
}
|
|
1525
|
+
else if (!opts.replace) {
|
|
1501
1526
|
window.history.pushState({ path: url.pathname }, '', target);
|
|
1502
1527
|
}
|
|
1503
1528
|
else {
|
|
@@ -1710,6 +1735,46 @@ export function createFileRouter(routeTree, options = {}) {
|
|
|
1710
1735
|
const renderFn = options.render || renderMatch;
|
|
1711
1736
|
const hydrateStrategy = options.hydrate || 'full';
|
|
1712
1737
|
const hashMode = options.hash === true;
|
|
1738
|
+
const serverMiddlewareCache = new Map();
|
|
1739
|
+
let serverMiddlewareDisabled = false;
|
|
1740
|
+
const runServerMiddleware = async (ctx, next) => {
|
|
1741
|
+
if (options.serverMiddleware !== true || typeof window === 'undefined' || serverMiddlewareDisabled)
|
|
1742
|
+
return next();
|
|
1743
|
+
const path = String(ctx.url || '/');
|
|
1744
|
+
const cached = serverMiddlewareCache.get(path);
|
|
1745
|
+
if (cached && Date.now() - cached.at < 2500) {
|
|
1746
|
+
if (cached.body && typeof cached.body.redirect === 'string' && cached.body.redirect) {
|
|
1747
|
+
return { redirect: cached.body.redirect };
|
|
1748
|
+
}
|
|
1749
|
+
if (cached.body && typeof cached.body.rewrite === 'string' && cached.body.rewrite)
|
|
1750
|
+
return next(cached.body.rewrite);
|
|
1751
|
+
return next();
|
|
1752
|
+
}
|
|
1753
|
+
const endpoint = globalThis.__veskServerMiddlewareEndpoint ?? '/_vesk/middleware';
|
|
1754
|
+
try {
|
|
1755
|
+
const res = await fetch(`${endpoint}?path=${encodeURIComponent(path)}`, {
|
|
1756
|
+
credentials: 'include',
|
|
1757
|
+
headers: { Accept: 'application/json' },
|
|
1758
|
+
cache: 'no-store',
|
|
1759
|
+
});
|
|
1760
|
+
if (res.status === 404) {
|
|
1761
|
+
serverMiddlewareDisabled = true;
|
|
1762
|
+
return next();
|
|
1763
|
+
}
|
|
1764
|
+
const body = await res.json().catch(() => null);
|
|
1765
|
+
serverMiddlewareCache.set(path, { at: Date.now(), body });
|
|
1766
|
+
if (body && typeof body.redirect === 'string' && body.redirect) {
|
|
1767
|
+
// Returning this object is honored by the router's middleware chain.
|
|
1768
|
+
return { redirect: body.redirect };
|
|
1769
|
+
}
|
|
1770
|
+
if (body && typeof body.rewrite === 'string' && body.rewrite)
|
|
1771
|
+
return next(body.rewrite);
|
|
1772
|
+
return next();
|
|
1773
|
+
}
|
|
1774
|
+
catch {
|
|
1775
|
+
return next();
|
|
1776
|
+
}
|
|
1777
|
+
};
|
|
1713
1778
|
const router = {
|
|
1714
1779
|
_hydrateStrategy: hydrateStrategy,
|
|
1715
1780
|
routeTree,
|
|
@@ -1847,15 +1912,17 @@ export function createFileRouter(routeTree, options = {}) {
|
|
|
1847
1912
|
const match = matchRoute(routeTree, path);
|
|
1848
1913
|
if (match) {
|
|
1849
1914
|
match.pathname = path;
|
|
1850
|
-
hydrateInitial(router, match, container, hydrateStrategy);
|
|
1915
|
+
trackHydration(hydrateInitial(router, match, container, hydrateStrategy));
|
|
1851
1916
|
router._currentMatch = match;
|
|
1852
1917
|
}
|
|
1853
1918
|
else {
|
|
1854
1919
|
router.navigate(path, { replace: true });
|
|
1920
|
+
globalThis.__vesk_hydrated = true;
|
|
1855
1921
|
}
|
|
1856
1922
|
}
|
|
1857
1923
|
else {
|
|
1858
1924
|
router.navigate(path, { replace: true });
|
|
1925
|
+
globalThis.__vesk_hydrated = true;
|
|
1859
1926
|
}
|
|
1860
1927
|
return router;
|
|
1861
1928
|
},
|
|
@@ -1924,12 +1991,23 @@ export function createFileRouter(routeTree, options = {}) {
|
|
|
1924
1991
|
navDebug('navigate', url.pathname, 'token=' + router._navToken, 'pendingChunks', hasPendingChunks(match.matchChain));
|
|
1925
1992
|
const navToken = router._navToken;
|
|
1926
1993
|
loadingStart();
|
|
1927
|
-
const middlewareFns =
|
|
1994
|
+
const middlewareFns = [
|
|
1995
|
+
...(options.serverMiddleware === true ? [runServerMiddleware] : []),
|
|
1996
|
+
...(Array.isArray(middleware) ? middleware : (middleware ? [middleware] : [])),
|
|
1997
|
+
];
|
|
1928
1998
|
let firstRenderFailed = false;
|
|
1929
1999
|
const updateUrl = () => {
|
|
1930
2000
|
const fullUrl = url.pathname + url.search;
|
|
1931
2001
|
const target = mode ? (fullUrl.startsWith('/') ? '#' + fullUrl : '#' + fullUrl) : fullUrl;
|
|
1932
|
-
|
|
2002
|
+
// Re-check the live location here, not just at navigate()
|
|
2003
|
+
// entry: an async middleware/guard chain defers this push, so
|
|
2004
|
+
// a second navigation started before the first one lands
|
|
2005
|
+
// would otherwise push the same URL twice.
|
|
2006
|
+
const liveFull = window.location.pathname + window.location.search + window.location.hash;
|
|
2007
|
+
if (!opts.replace && target === liveFull) {
|
|
2008
|
+
// already current — do not duplicate the history entry
|
|
2009
|
+
}
|
|
2010
|
+
else if (!opts.replace) {
|
|
1933
2011
|
window.history.pushState({ path: fullUrl }, '', target);
|
|
1934
2012
|
}
|
|
1935
2013
|
else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vesk/runtime",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.95",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Vesk runtime — reactivity, blocks, DOM operations, hydration",
|
|
6
6
|
"main": "./dist/index-client.js",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
}
|
|
81
81
|
},
|
|
82
82
|
"dependencies": {
|
|
83
|
-
"@vesk/compiler": "^0.2.
|
|
83
|
+
"@vesk/compiler": "^0.2.95"
|
|
84
84
|
},
|
|
85
85
|
"scripts": {
|
|
86
86
|
"typecheck": "tsc --noEmit",
|