@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
|
@@ -12,7 +12,9 @@ export async function resumeContainerEvent(input: {
|
|
|
12
12
|
const routeWakeModule = loadRouteWakeModule ? await loadRouteWakeModule() : undefined;
|
|
13
13
|
const resume = (routeWakeModule as RouteWakeModule | undefined)?.resumeContainerEvent;
|
|
14
14
|
if (typeof resume !== 'function') {
|
|
15
|
-
throw new Error(
|
|
15
|
+
throw new Error(
|
|
16
|
+
`Markless Router could not wake prerendered route module: ${file ?? '<unknown>'}`,
|
|
17
|
+
);
|
|
16
18
|
}
|
|
17
19
|
await resume(input);
|
|
18
20
|
}
|
|
@@ -1,21 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const tsrxResumeModuleLoaders = import.meta.glob('/pages/**/*.tsrx', {
|
|
5
|
-
query: '?markless-resume',
|
|
6
|
-
});
|
|
7
|
-
const routeResumeModules = new WeakMap<() => Promise<unknown>, Promise<unknown>>();
|
|
1
|
+
import { mdxResumeModules, tsrxResumeModules } from 'virtual:markless-router/dev-resume-modules';
|
|
2
|
+
|
|
3
|
+
const routeResumeModules = new Map<unknown, Promise<unknown>>();
|
|
8
4
|
|
|
9
5
|
export async function resumeContainerEvent(input: {
|
|
10
6
|
readonly root: ParentNode;
|
|
11
7
|
readonly [key: string]: unknown;
|
|
12
8
|
}) {
|
|
13
|
-
const
|
|
9
|
+
const route = routeFromRoot(input.root);
|
|
10
|
+
const file = route?.file;
|
|
11
|
+
// The page this event belongs to: a navigation that keeps the container starts a new one while the route module loads.
|
|
12
|
+
const life = (input.root as { readonly __mL?: object }).__mL;
|
|
14
13
|
try {
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
? await loadRouteModuleOnce(loadRouteResumeModule)
|
|
18
|
-
: undefined;
|
|
14
|
+
const routeResumeModule = route ? await loadRouteResumeModule(route) : undefined;
|
|
15
|
+
if ((input.root as { readonly __mL?: object }).__mL !== life) return;
|
|
19
16
|
const resume = (routeResumeModule as RouteResumeModule | undefined)?.resumeContainerEvent;
|
|
20
17
|
if (typeof resume !== 'function') {
|
|
21
18
|
throw new Error(
|
|
@@ -43,24 +40,40 @@ interface RouteResumeModule {
|
|
|
43
40
|
readonly resumeContainerEvent?: (input: unknown) => unknown;
|
|
44
41
|
}
|
|
45
42
|
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
interface RouteScript {
|
|
44
|
+
readonly file?: string;
|
|
45
|
+
// The built chunk holding the route's resume module, then the export evaluating it inside a pack and the one holding it.
|
|
46
|
+
readonly resume?: readonly [url: string, evaluate?: string, read?: string];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function loadRouteResumeModule(route: RouteScript): Promise<unknown> | undefined {
|
|
50
|
+
const [url, evaluate, read] = route.resume ?? [];
|
|
51
|
+
const key = url ?? (route.file && devResumeModuleLoader(route.file));
|
|
52
|
+
if (!key) return undefined;
|
|
53
|
+
let pending = routeResumeModules.get(key);
|
|
48
54
|
if (!pending) {
|
|
49
|
-
pending =
|
|
50
|
-
|
|
55
|
+
pending = (
|
|
56
|
+
typeof key === 'string'
|
|
57
|
+
? import(/* @vite-ignore */ key).then((module: Record<string, () => unknown>) => {
|
|
58
|
+
const evaluated = evaluate ? module[evaluate]!() : module;
|
|
59
|
+
return read ? module[read] : evaluated;
|
|
60
|
+
})
|
|
61
|
+
: key()
|
|
62
|
+
).catch((error: unknown) => {
|
|
63
|
+
routeResumeModules.delete(key);
|
|
51
64
|
throw error;
|
|
52
65
|
});
|
|
53
|
-
routeResumeModules.set(
|
|
66
|
+
routeResumeModules.set(key, pending);
|
|
54
67
|
}
|
|
55
68
|
return pending;
|
|
56
69
|
}
|
|
57
70
|
|
|
58
|
-
function
|
|
59
|
-
const loaders = file.endsWith('.mdx') ?
|
|
60
|
-
return loaders[file] ?? loaders[`/${file}`];
|
|
71
|
+
function devResumeModuleLoader(file: string): (() => Promise<unknown>) | undefined {
|
|
72
|
+
const loaders = file.endsWith('.mdx') ? mdxResumeModules : tsrxResumeModules;
|
|
73
|
+
return loaders?.[file] ?? loaders?.[`/${file}`];
|
|
61
74
|
}
|
|
62
75
|
|
|
63
|
-
function
|
|
76
|
+
function routeFromRoot(root: ParentNode): RouteScript | undefined {
|
|
64
77
|
const script = root.querySelector?.('script[type="@markless/core/route"]');
|
|
65
78
|
const text = script?.textContent;
|
|
66
79
|
if (!text) {
|
|
@@ -68,8 +81,8 @@ function routeFileFromRoot(root: ParentNode): string | undefined {
|
|
|
68
81
|
}
|
|
69
82
|
|
|
70
83
|
try {
|
|
71
|
-
const route = JSON.parse(text) as
|
|
72
|
-
return typeof route.file === 'string' ? route
|
|
84
|
+
const route = JSON.parse(text) as RouteScript;
|
|
85
|
+
return typeof route.file === 'string' ? route : undefined;
|
|
73
86
|
} catch {
|
|
74
87
|
return undefined;
|
|
75
88
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Every route's resume module: a build entry no page loads, so each module gets its chunk; dev resumes through it.
|
|
2
|
+
export const mdxResumeModules = import.meta.glob('/pages/**/*.mdx', {
|
|
3
|
+
query: '?markless-resume',
|
|
4
|
+
});
|
|
5
|
+
export const tsrxResumeModules = import.meta.glob('/pages/**/*.tsrx', {
|
|
6
|
+
query: '?markless-resume',
|
|
7
|
+
});
|