@rebask/core 0.1.5 → 0.2.1
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/entry.rsc.d.ts +1 -0
- package/dist/entry.rsc.d.ts.map +1 -1
- package/dist/entry.rsc.js +1 -0
- package/dist/handlers/markdown.d.ts +16 -0
- package/dist/handlers/markdown.d.ts.map +1 -0
- package/dist/handlers/markdown.js +161 -0
- package/dist/handlers/rsc/cache-lookup.d.ts.map +1 -1
- package/dist/handlers/rsc/cache-lookup.js +10 -4
- package/dist/handlers/rsc/index.js +1 -1
- package/dist/handlers/rsc/render-to-response.js +6 -2
- package/dist/handlers/rsc/segment-shell.d.ts +1 -1
- package/dist/handlers/rsc/segment-shell.d.ts.map +1 -1
- package/dist/handlers/rsc/segment-shell.js +5 -9
- package/dist/handlers/rsc/state.d.ts +1 -0
- package/dist/handlers/rsc/state.d.ts.map +1 -1
- package/dist/handlers/rsc/state.js +4 -0
- package/dist/lib/app-manifest.d.ts +12 -4
- package/dist/lib/app-manifest.d.ts.map +1 -1
- package/dist/lib/app-manifest.js +5 -0
- package/dist/lib/cache-key-tags.d.ts +2 -0
- package/dist/lib/cache-key-tags.d.ts.map +1 -1
- package/dist/lib/cache-key-tags.js +2 -0
- package/dist/lib/cache-storage.d.ts +7 -2
- package/dist/lib/cache-storage.d.ts.map +1 -1
- package/dist/lib/cache-storage.js +1 -0
- package/dist/lib/config.d.ts +2 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +8 -3
- package/dist/lib/dev-page-exports.d.ts +5 -0
- package/dist/lib/dev-page-exports.d.ts.map +1 -0
- package/dist/lib/dev-page-exports.js +14 -0
- package/dist/lib/lru-cache.d.ts.map +1 -1
- package/dist/lib/lru-cache.js +2 -0
- package/dist/lib/markdown.d.ts +5 -0
- package/dist/lib/markdown.d.ts.map +1 -0
- package/dist/lib/markdown.js +53 -0
- package/dist/lib/page-exports.d.ts +9 -0
- package/dist/lib/page-exports.d.ts.map +1 -0
- package/dist/lib/page-exports.js +47 -0
- package/dist/lib/ppr/cache-status.d.ts +3 -0
- package/dist/lib/ppr/cache-status.d.ts.map +1 -0
- package/dist/lib/ppr/cache-status.js +5 -0
- package/dist/lib/ppr/headers.d.ts +1 -1
- package/dist/lib/ppr/headers.d.ts.map +1 -1
- package/dist/lib/ppr/headers.js +1 -1
- package/dist/lib/prerender-params.d.ts +1 -1
- package/dist/lib/prerender-params.d.ts.map +1 -1
- package/dist/lib/prerender-params.js +17 -2
- package/dist/lib/project-files.d.ts +2 -1
- package/dist/lib/project-files.d.ts.map +1 -1
- package/dist/lib/project-files.js +16 -6
- package/dist/lib/route-builder.d.ts +4 -3
- package/dist/lib/route-builder.d.ts.map +1 -1
- package/dist/lib/route-builder.js +61 -13
- package/dist/lib/route-matcher.d.ts +4 -0
- package/dist/lib/route-matcher.d.ts.map +1 -1
- package/dist/lib/router-cache.d.ts +4 -0
- package/dist/lib/router-cache.d.ts.map +1 -1
- package/dist/lib/rsc-request.d.ts.map +1 -1
- package/dist/lib/rsc-request.js +3 -3
- package/dist/lib/server-router/get-router.d.ts.map +1 -1
- package/dist/lib/server-router/get-router.js +71 -16
- package/dist/lib/server-router/types.d.ts +4 -1
- package/dist/lib/server-router/types.d.ts.map +1 -1
- package/dist/lib/write-behind-cache.d.ts.map +1 -1
- package/dist/lib/write-behind-cache.js +5 -3
- package/dist/plugins/devtools.d.ts.map +1 -1
- package/dist/plugins/devtools.js +2 -2
- package/dist/plugins/ppr.d.ts +5 -0
- package/dist/plugins/ppr.d.ts.map +1 -1
- package/dist/plugins/prerender.d.ts.map +1 -1
- package/dist/plugins/prerender.js +114 -70
- package/dist/plugins/router/wint-router.d.ts.map +1 -1
- package/dist/plugins/router/wint-router.js +4 -2
- package/dist/router.d.ts +1 -1
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +16 -6
- package/dist/server-router.d.ts +1 -1
- package/dist/server-router.d.ts.map +1 -1
- package/dist/vite.d.ts +20 -1
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js +17 -4
- package/package.json +1 -5
- package/dist/components/prefetch-links.d.ts +0 -5
- package/dist/components/prefetch-links.d.ts.map +0 -1
- package/dist/components/prefetch-links.js +0 -174
|
@@ -5,12 +5,14 @@ import { proxyRouter } from "virtual:rebask/proxy-router";
|
|
|
5
5
|
import { createMatcher } from "virtual:rebask/server-router";
|
|
6
6
|
import { applyCookies, getSetCookieValues } from "../../cookies.js";
|
|
7
7
|
import { handleImageRequest } from "../../handlers/image.js";
|
|
8
|
+
import { handleMarkdownRoute, markdownNotFound } from "../../handlers/markdown.js";
|
|
8
9
|
import { handleRouteHandler } from "../../handlers/route-handler.js";
|
|
9
10
|
import { buildDefaultNotFoundRoute } from "../../handlers/rsc/errors.js";
|
|
10
11
|
import { handlePageRoute } from "../../handlers/rsc/index.js";
|
|
11
12
|
import { handleLayoutRouteRequest } from "../../handlers/segment.js";
|
|
12
13
|
import { getDevServer } from "../dev-server.js";
|
|
13
14
|
import { reinjectFlightHeaders, sanitizeForProxy } from "../flight-headers.js";
|
|
15
|
+
import { getMarkdownPathname, prefersMarkdown } from "../markdown.js";
|
|
14
16
|
import { buildProxy } from "../proxy/build-proxy.js";
|
|
15
17
|
import { proxyExternal } from "../proxy/proxy-external.js";
|
|
16
18
|
import { REWRITE_HEADER, rewriteHeaders } from "../proxy/rewrite.js";
|
|
@@ -20,35 +22,64 @@ import { RouteType } from "./types.js";
|
|
|
20
22
|
function buildEntries(pageRoutes, routeHandlerRoutes, layoutRoutes) {
|
|
21
23
|
const appEntries = [];
|
|
22
24
|
const layoutEntries = [];
|
|
25
|
+
const markdownEntries = [];
|
|
26
|
+
const hasMarkdownRoutes = pageRoutes.some((route) => route.markdownFilePath);
|
|
23
27
|
// Image optimization route
|
|
24
28
|
if (imageConfig !== null && loadImageHandler !== undefined) {
|
|
25
|
-
|
|
29
|
+
const imageEntry = {
|
|
26
30
|
type: RouteType.IMAGE,
|
|
27
31
|
methods: ["GET"],
|
|
28
32
|
pattern: imageConfig.path,
|
|
29
33
|
handler: handleImageRequest,
|
|
30
|
-
}
|
|
34
|
+
};
|
|
35
|
+
appEntries.push(imageEntry);
|
|
36
|
+
if (hasMarkdownRoutes)
|
|
37
|
+
markdownEntries.push(imageEntry);
|
|
31
38
|
}
|
|
32
39
|
// Page routes — registered for GET and POST:
|
|
33
40
|
// - GET: page loads, RSC requests, segment requests
|
|
34
41
|
// - POST: server functions, form submissions, PPR resume
|
|
35
42
|
for (const route of pageRoutes) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
43
|
+
if (route.hasPage !== false) {
|
|
44
|
+
appEntries.push({
|
|
45
|
+
type: RouteType.APP,
|
|
46
|
+
methods: ["GET", "POST"],
|
|
47
|
+
route,
|
|
48
|
+
handler: (req, params) => handlePageRoute(req, route, params),
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
if (!hasMarkdownRoutes)
|
|
52
|
+
continue;
|
|
53
|
+
if (route.markdownFilePath) {
|
|
54
|
+
markdownEntries.push({
|
|
55
|
+
type: RouteType.APP,
|
|
56
|
+
methods: ["GET", "HEAD"],
|
|
57
|
+
route,
|
|
58
|
+
handler: (req, params) => handleMarkdownRoute(req, route, params),
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
else if (route.hasPage !== false) {
|
|
62
|
+
// A specific page without Markdown still wins negotiation over a Markdown catch-all.
|
|
63
|
+
markdownEntries.push({
|
|
64
|
+
type: RouteType.APP,
|
|
65
|
+
methods: ["GET"],
|
|
66
|
+
route,
|
|
67
|
+
handler: (req, params) => handlePageRoute(req, route, params),
|
|
68
|
+
});
|
|
69
|
+
}
|
|
42
70
|
}
|
|
43
71
|
// Route handlers — registered for all methods so they can return 405 when the path exists but a
|
|
44
72
|
// specific method is not implemented.
|
|
45
73
|
for (const route of routeHandlerRoutes) {
|
|
46
|
-
|
|
74
|
+
const entry = {
|
|
47
75
|
type: RouteType.APP,
|
|
48
76
|
methods: [...HTTP_METHODS],
|
|
49
77
|
route,
|
|
50
78
|
handler: (req, params) => handleRouteHandler(req, route, params),
|
|
51
|
-
}
|
|
79
|
+
};
|
|
80
|
+
appEntries.push(entry);
|
|
81
|
+
if (hasMarkdownRoutes)
|
|
82
|
+
markdownEntries.push(entry);
|
|
52
83
|
}
|
|
53
84
|
// Layout routes — registered under /_rebask/1/{path}
|
|
54
85
|
for (const route of layoutRoutes) {
|
|
@@ -64,14 +95,34 @@ function buildEntries(pageRoutes, routeHandlerRoutes, layoutRoutes) {
|
|
|
64
95
|
handler: (req, params) => handleLayoutRouteRequest(req, route, params),
|
|
65
96
|
});
|
|
66
97
|
}
|
|
67
|
-
return { appEntries, layoutEntries };
|
|
98
|
+
return { appEntries, layoutEntries, markdownEntries };
|
|
68
99
|
}
|
|
69
100
|
function createRouter(pageRoutes, routeHandlerRoutes, layoutRoutes, resolvedProxyRouter = proxyRouter) {
|
|
70
|
-
const { appEntries, layoutEntries } = buildEntries(pageRoutes, routeHandlerRoutes, layoutRoutes);
|
|
101
|
+
const { appEntries, layoutEntries, markdownEntries } = buildEntries(pageRoutes, routeHandlerRoutes, layoutRoutes);
|
|
71
102
|
const appMatcher = createMatcher(appEntries);
|
|
103
|
+
const markdownMatcher = markdownEntries.length > 0 ? createMatcher(markdownEntries) : null;
|
|
72
104
|
const layoutMatcher = layoutEntries.length > 0 ? createMatcher(layoutEntries) : null;
|
|
73
105
|
const app = async (request) => {
|
|
74
|
-
const
|
|
106
|
+
const method = request.method;
|
|
107
|
+
const accept = request.headers.get("accept");
|
|
108
|
+
const isRscRequest = accept?.startsWith("text/x-component");
|
|
109
|
+
const isMarkdownMethod = method === "GET" || method === "HEAD";
|
|
110
|
+
if (!isRscRequest && isMarkdownMethod && markdownMatcher) {
|
|
111
|
+
const url = new URL(request.url);
|
|
112
|
+
const markdownPathname = __REBASK_MARKDOWN_URLS ? getMarkdownPathname(url.pathname) : null;
|
|
113
|
+
if (markdownPathname !== null) {
|
|
114
|
+
url.pathname = markdownPathname;
|
|
115
|
+
const markdownHandler = markdownMatcher.find(method, url.href);
|
|
116
|
+
if (markdownHandler?.route?.type === "page" && markdownHandler.route.markdownFilePath) {
|
|
117
|
+
return (await markdownHandler(request));
|
|
118
|
+
}
|
|
119
|
+
return markdownNotFound(request);
|
|
120
|
+
}
|
|
121
|
+
if (prefersMarkdown(accept)) {
|
|
122
|
+
const handler = markdownMatcher.find(method, request.url);
|
|
123
|
+
return handler ? handler(request) : markdownNotFound(request);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
75
126
|
const layoutHandler = isRscRequest
|
|
76
127
|
? layoutMatcher?.find(request.method, request.url)
|
|
77
128
|
: undefined;
|
|
@@ -161,11 +212,15 @@ export async function getRouter() {
|
|
|
161
212
|
if (router)
|
|
162
213
|
return router;
|
|
163
214
|
// Development: build routes from module manifest
|
|
164
|
-
const { layoutModules, pageModules, proxyModules, routeHandlerModules } = await loadAppManifest();
|
|
215
|
+
const { layoutModules, pageModules, proxyModules, routeHandlerModules, markdownHandlerModules, markdownSourceModules, } = await loadAppManifest();
|
|
165
216
|
const layouts = Object.keys(layoutModules);
|
|
166
217
|
const pages = Object.keys(pageModules);
|
|
167
|
-
|
|
168
|
-
|
|
218
|
+
const markdownFiles = [
|
|
219
|
+
...Object.keys(markdownSourceModules),
|
|
220
|
+
...Object.keys(markdownHandlerModules),
|
|
221
|
+
];
|
|
222
|
+
assertNoPageRouteHandlerConflicts(pages, Object.keys(routeHandlerModules), markdownFiles);
|
|
223
|
+
const routes = buildRoutes(layouts, pages, markdownFiles);
|
|
169
224
|
const routeHandlerRoutes = buildRouteHandlerRoutes(Object.keys(routeHandlerModules));
|
|
170
225
|
const layoutRoutes = buildLayoutRoutes(layouts);
|
|
171
226
|
const proxyModule = await Object.values(proxyModules)[0]?.();
|
|
@@ -29,9 +29,12 @@ type ImageEntry = {
|
|
|
29
29
|
};
|
|
30
30
|
export type RouteEntry = PageRouteEntry | RouteHandlerEntry | LayoutRSCEntry | ProxyEntry | ImageEntry;
|
|
31
31
|
type FindHandler<E extends RouteEntry> = ProxyEntry extends E ? (request: Request) => ReturnType<ProxyHandler> : (request: Request) => Promise<Response>;
|
|
32
|
+
export type MatchedHandler<E extends RouteEntry = RouteEntry> = FindHandler<E> & {
|
|
33
|
+
route?: Route | RouteHandlerRoute | LayoutRoute;
|
|
34
|
+
};
|
|
32
35
|
/** A compiled route matcher that finds the best matching route for a given method + URL. */
|
|
33
36
|
export interface RouteMatcher<E extends RouteEntry = RouteEntry> {
|
|
34
|
-
find(method: string, url: string):
|
|
37
|
+
find(method: string, url: string): MatchedHandler<E> | null;
|
|
35
38
|
}
|
|
36
39
|
/**
|
|
37
40
|
* A router plugin provides an implementation of this function via the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/server-router/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,KAAK,EACX,UAAU,EACV,WAAW,EACX,KAAK,EACL,iBAAiB,EACjB,WAAW,EACX,MAAM,qBAAqB,CAAA;AAE5B,oBAAY,SAAS;IACpB,GAAG,IAAA;IACH,KAAK,IAAA;IACL,KAAK,IAAA;CACL;AAED,KAAK,OAAO,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAE3E,KAAK,QAAQ,CAAC,CAAC,IAAI;IAClB,OAAO,EAAE,UAAU,EAAE,CAAA;IACrB,IAAI,EAAE,SAAS,CAAC,GAAG,CAAA;IACnB,KAAK,EAAE,CAAC,CAAA;IACR,OAAO,EAAE,OAAO,CAAA;CAChB,CAAA;AAED,KAAK,cAAc,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;AACrC,KAAK,iBAAiB,GAAG,QAAQ,CAAC,iBAAiB,CAAC,CAAA;AACpD,KAAK,cAAc,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAA;AAE3C,MAAM,MAAM,UAAU,GAAG;IACxB,IAAI,EAAE,SAAS,CAAC,KAAK,CAAA;IACrB,OAAO,EAAE,UAAU,EAAE,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,YAAY,CAAA;CACrB,CAAA;AAED,KAAK,UAAU,GAAG;IACjB,IAAI,EAAE,SAAS,CAAC,KAAK,CAAA;IACrB,OAAO,EAAE,UAAU,EAAE,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,OAAO,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,UAAU,GACnB,cAAc,GACd,iBAAiB,GACjB,cAAc,GACd,UAAU,GACV,UAAU,CAAA;AAEb,KAAK,WAAW,CAAC,CAAC,SAAS,UAAU,IAAI,UAAU,SAAS,CAAC,GAC1D,CAAC,OAAO,EAAE,OAAO,KAAK,UAAU,CAAC,YAAY,CAAC,GAC9C,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAE1C,4FAA4F;AAC5F,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU;IAC9D,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/server-router/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,KAAK,EACX,UAAU,EACV,WAAW,EACX,KAAK,EACL,iBAAiB,EACjB,WAAW,EACX,MAAM,qBAAqB,CAAA;AAE5B,oBAAY,SAAS;IACpB,GAAG,IAAA;IACH,KAAK,IAAA;IACL,KAAK,IAAA;CACL;AAED,KAAK,OAAO,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAE3E,KAAK,QAAQ,CAAC,CAAC,IAAI;IAClB,OAAO,EAAE,UAAU,EAAE,CAAA;IACrB,IAAI,EAAE,SAAS,CAAC,GAAG,CAAA;IACnB,KAAK,EAAE,CAAC,CAAA;IACR,OAAO,EAAE,OAAO,CAAA;CAChB,CAAA;AAED,KAAK,cAAc,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;AACrC,KAAK,iBAAiB,GAAG,QAAQ,CAAC,iBAAiB,CAAC,CAAA;AACpD,KAAK,cAAc,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAA;AAE3C,MAAM,MAAM,UAAU,GAAG;IACxB,IAAI,EAAE,SAAS,CAAC,KAAK,CAAA;IACrB,OAAO,EAAE,UAAU,EAAE,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,YAAY,CAAA;CACrB,CAAA;AAED,KAAK,UAAU,GAAG;IACjB,IAAI,EAAE,SAAS,CAAC,KAAK,CAAA;IACrB,OAAO,EAAE,UAAU,EAAE,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,OAAO,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,UAAU,GACnB,cAAc,GACd,iBAAiB,GACjB,cAAc,GACd,UAAU,GACV,UAAU,CAAA;AAEb,KAAK,WAAW,CAAC,CAAC,SAAS,UAAU,IAAI,UAAU,SAAS,CAAC,GAC1D,CAAC,OAAO,EAAE,OAAO,KAAK,UAAU,CAAC,YAAY,CAAC,GAC9C,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAE1C,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU,IAAI,WAAW,CAAC,CAAC,CAAC,GAAG;IAChF,KAAK,CAAC,EAAE,KAAK,GAAG,iBAAiB,GAAG,WAAW,CAAA;CAC/C,CAAA;AAED,4FAA4F;AAC5F,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU;IAC9D,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;CAC3D;AAED;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,SAAS,UAAU,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,YAAY,CAAC,CAAC,CAAC,CAAA;AAErF,MAAM,WAAW,YAAY;IAC5B,sFAAsF;IACtF,MAAM,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC/C,uEAAuE;IACvE,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC5C,qFAAqF;IACrF,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAA;CACrD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write-behind-cache.d.ts","sourceRoot":"","sources":["../../src/lib/write-behind-cache.ts"],"names":[],"mappings":"AACA,OAAO,EAIN,KAAK,YAAY,EACjB,MAAM,oBAAoB,CAAA;AAE3B,UAAU,kBAAkB;IAC3B;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;CACpB;AAID;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC9B,OAAO,EAAE,YAAY,EACrB,OAAO,GAAE,kBAAuB,GAC9B,YAAY,
|
|
1
|
+
{"version":3,"file":"write-behind-cache.d.ts","sourceRoot":"","sources":["../../src/lib/write-behind-cache.ts"],"names":[],"mappings":"AACA,OAAO,EAIN,KAAK,YAAY,EACjB,MAAM,oBAAoB,CAAA;AAE3B,UAAU,kBAAkB;IAC3B;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;CACpB;AAID;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC9B,OAAO,EAAE,YAAY,EACrB,OAAO,GAAE,kBAAuB,GAC9B,YAAY,CAyHd"}
|
|
@@ -62,9 +62,11 @@ export function withWriteBehind(storage, options = {}) {
|
|
|
62
62
|
return storage.set(key, entry, setOptions);
|
|
63
63
|
const bytes = entry.type === CacheEntryType.HTML
|
|
64
64
|
? entry.html.length + (entry.postponed?.length ?? 0)
|
|
65
|
-
: entry.type === CacheEntryType.
|
|
66
|
-
? entry.
|
|
67
|
-
: entry.
|
|
65
|
+
: entry.type === CacheEntryType.MARKDOWN
|
|
66
|
+
? entry.markdown.length
|
|
67
|
+
: entry.type === CacheEntryType.DURABLE_CACHE
|
|
68
|
+
? entry.data.length
|
|
69
|
+
: entry.rsc.length;
|
|
68
70
|
const queued = pending.get(key);
|
|
69
71
|
if (queued) {
|
|
70
72
|
pendingBytes += bytes - queued.bytes;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"devtools.d.ts","sourceRoot":"","sources":["../../src/plugins/devtools.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,MAAM,EAAmD,MAAM,MAAM,CAAA;AACnF,OAAO,KAAK,EACX,qBAAqB,EAIrB,MAAM,gBAAgB,CAAA;AAQvB,wBAAgB,cAAc,CAAC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,qBAAqB,EAAE,CAAC,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"devtools.d.ts","sourceRoot":"","sources":["../../src/plugins/devtools.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,MAAM,EAAmD,MAAM,MAAM,CAAA;AACnF,OAAO,KAAK,EACX,qBAAqB,EAIrB,MAAM,gBAAgB,CAAA;AAQvB,wBAAgB,cAAc,CAAC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,qBAAqB,EAAE,CAAC,GAAG,MAAM,CA0G3F"}
|
package/dist/plugins/devtools.js
CHANGED
|
@@ -61,11 +61,11 @@ export function devtoolsPlugin(cacheFunctions) {
|
|
|
61
61
|
await devtoolsModule.setupRebaskDevtools(devtools, {
|
|
62
62
|
root: projectRoot,
|
|
63
63
|
async getRoutes() {
|
|
64
|
-
const { pages, layouts, routeHandlers } = await scanAppDirectory(join(projectRoot, "app"));
|
|
64
|
+
const { pages, layouts, routeHandlers, markdownFiles } = await scanAppDirectory(join(projectRoot, "app"));
|
|
65
65
|
const proxyPath = await findProjectFile(projectRoot, "proxy");
|
|
66
66
|
const proxyModule = proxyPath && runner && (await runner.import(proxyPath));
|
|
67
67
|
return {
|
|
68
|
-
pages: buildRoutes(layouts, pages).filter((route) => route.type === "page"),
|
|
68
|
+
pages: buildRoutes(layouts, pages, markdownFiles).filter((route) => route.type === "page"),
|
|
69
69
|
routeHandlers: buildRouteHandlerRoutes(routeHandlers),
|
|
70
70
|
proxyPatterns: proxyModule ? Object.keys(proxyModule.default ?? proxyModule) : [],
|
|
71
71
|
};
|
package/dist/plugins/ppr.d.ts
CHANGED
|
@@ -2,6 +2,11 @@ import type { Plugin } from "vite";
|
|
|
2
2
|
/** The `name` of the Vite plugin. */
|
|
3
3
|
export declare const REBASK_PPR_PLUGIN_NAME = "rebask:ppr";
|
|
4
4
|
export interface PprConfig {
|
|
5
|
+
/**
|
|
6
|
+
* Whether page responses include `x-rebask-cache`. Platforms that own page cache set this to
|
|
7
|
+
* `false`.
|
|
8
|
+
*/
|
|
9
|
+
emitCacheStatus?: boolean;
|
|
5
10
|
/**
|
|
6
11
|
* Rebask only enters the resume path when this header matches `"1"`. Adapters must validate
|
|
7
12
|
* their own transport credential and set this header before the Rebask handler executes.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ppr.d.ts","sourceRoot":"","sources":["../../src/plugins/ppr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAElC,qCAAqC;AACrC,eAAO,MAAM,sBAAsB,eAAe,CAAA;AAElD,MAAM,WAAW,SAAS;IACzB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,2FAA2F;IAC3F,UAAU,EAAE,MAAM,CAAA;IAClB;;;;;;;OAOG;IACH,oBAAoB,EAAE,MAAM,CAAA;IAC5B,qEAAqE;IACrE,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,kBAAkB;IAClC,4EAA4E;IAC5E,SAAS,EAAE,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,CAAA;CAC7C;AAKD;;;GAGG;AACH,wBAAgB,SAAS,IAAI,MAAM,CA8BlC"}
|
|
1
|
+
{"version":3,"file":"ppr.d.ts","sourceRoot":"","sources":["../../src/plugins/ppr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAElC,qCAAqC;AACrC,eAAO,MAAM,sBAAsB,eAAe,CAAA;AAElD,MAAM,WAAW,SAAS;IACzB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,2FAA2F;IAC3F,UAAU,EAAE,MAAM,CAAA;IAClB;;;;;;;OAOG;IACH,oBAAoB,EAAE,MAAM,CAAA;IAC5B,qEAAqE;IACrE,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,kBAAkB;IAClC,4EAA4E;IAC5E,SAAS,EAAE,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,CAAA;CAC7C;AAKD;;;GAGG;AACH,wBAAgB,SAAS,IAAI,MAAM,CA8BlC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prerender.d.ts","sourceRoot":"","sources":["../../src/plugins/prerender.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"prerender.d.ts","sourceRoot":"","sources":["../../src/plugins/prerender.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAQlC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AASlE,OAAO,EAA0B,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAA;AACtF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAOjD,KAAK,YAAY,GAAG,WAAW,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC,CAAA;AAEhE,KAAK,sBAAsB,GAAG;IAC7B;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,mEAAmE;IACnE,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC,CAAA;IAC/D,2DAA2D;IAC3D,EAAE,CAAC,EAAE,MAAM,EAAE,CAAA;CACb,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC/B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAA;IAC9C,yEAAyE;IACzE,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAA;IAClG;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAC,CAAA;IAC3E,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IAC/C,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;CAChD,CAAA;AA2CD,UAAU,sBAAsB;IAC/B,aAAa,CAAC,EAAE,OAAO,CAAA;CACvB;AAED,wBAAgB,eAAe,CAC9B,GAAG,EAAE,eAAe,EACpB,OAAO,GAAE,sBAA2B,GAClC,MAAM,CA2ZR"}
|
|
@@ -63,7 +63,10 @@ export function prerenderPlugin(api, options = {}) {
|
|
|
63
63
|
const prerenderOptions = { isBuildPrerender: true };
|
|
64
64
|
await withFetchCache(() => Promise.all(pageRoutes.map(async (route) => {
|
|
65
65
|
const isDynamic = route.segments.some(isDynamicSegment);
|
|
66
|
-
|
|
66
|
+
// Static page + Markdown routes load params only to catch conflicting prerenderParams.
|
|
67
|
+
const paramsResult = isDynamic || (route.hasPage !== false && route.markdownFilePath)
|
|
68
|
+
? await entryModule.getPrerenderParams(route)
|
|
69
|
+
: null;
|
|
67
70
|
const resolvedParams = paramsResult && paramsResult.params.length > 0 ? paramsResult.params : null;
|
|
68
71
|
const allowExtraParams = isDynamic ? (paramsResult?.allowExtraParams ?? true) : true;
|
|
69
72
|
const { filePath, shellParams } = route;
|
|
@@ -96,90 +99,131 @@ export function prerenderPlugin(api, options = {}) {
|
|
|
96
99
|
if (allowExtraParams !== false) {
|
|
97
100
|
requests.push({ pathname: getRoutePathname(route), params: {} });
|
|
98
101
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
return { pathname, isSharedShell, response, prerenderMeta };
|
|
118
|
-
}));
|
|
119
|
-
for (const result of requestResults) {
|
|
120
|
-
const { pathname, isSharedShell, response, prerenderMeta } = result;
|
|
121
|
-
const { hasShell, cacheLife, postponedState, hasPrerenderRequestIO } = prerenderMeta;
|
|
122
|
-
if (hasPrerenderRequestIO && !isSharedShell) {
|
|
123
|
-
const ioPaths = (prerenderRequestIOPaths[filePath] ??= []);
|
|
124
|
-
ioPaths.push(pathname);
|
|
125
|
-
}
|
|
126
|
-
if (cacheLife) {
|
|
127
|
-
// Shared shell pathname is only a static prefix (not a real URL).
|
|
128
|
-
if (!isSharedShell) {
|
|
129
|
-
cacheControlByPath[pathname] = mergeCacheControl(cacheControlByPath[pathname], cacheLife);
|
|
102
|
+
if (route.hasPage !== false) {
|
|
103
|
+
const requestResults = await Promise.all(requests.map(async ({ pathname, params }) => {
|
|
104
|
+
let prerenderMeta;
|
|
105
|
+
const isSharedShell = isDynamic && Object.keys(params).length === 0;
|
|
106
|
+
const request = new Request(`http://localhost${pathname}`, {
|
|
107
|
+
headers: { accept: "text/html" },
|
|
108
|
+
});
|
|
109
|
+
const response = await entryModule.handlePageRoute(request, route, params, {
|
|
110
|
+
...prerenderOptions,
|
|
111
|
+
// The build URL is only a static prefix. Force unresolved params and skip any
|
|
112
|
+
// HTML cached at that URL.
|
|
113
|
+
...(isSharedShell && { resolvedParams: new Set() }),
|
|
114
|
+
onBuildPrerenderMeta(meta) {
|
|
115
|
+
prerenderMeta = meta;
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
if (!prerenderMeta) {
|
|
119
|
+
throw new Error(`Missing build prerender metadata for "${route.filePath}" at "${pathname}"`);
|
|
130
120
|
}
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
121
|
+
return { pathname, params, isSharedShell, response, prerenderMeta };
|
|
122
|
+
}));
|
|
123
|
+
for (const result of requestResults) {
|
|
124
|
+
const { pathname, params, isSharedShell, response, prerenderMeta } = result;
|
|
125
|
+
const { hasShell, cacheLife, postponedState, hasPrerenderRequestIO } = prerenderMeta;
|
|
126
|
+
if (hasPrerenderRequestIO && !isSharedShell) {
|
|
127
|
+
const ioPaths = (prerenderRequestIOPaths[filePath] ??= []);
|
|
128
|
+
ioPaths.push(pathname);
|
|
136
129
|
}
|
|
137
|
-
if (
|
|
138
|
-
|
|
139
|
-
if (
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
130
|
+
if (cacheLife) {
|
|
131
|
+
// Shared shell pathname is only a static prefix (not a real URL).
|
|
132
|
+
if (!isSharedShell) {
|
|
133
|
+
cacheControlByPath[pathname] = mergeCacheControl(cacheControlByPath[pathname], cacheLife);
|
|
134
|
+
}
|
|
135
|
+
cacheControlByFilePath[filePath] = mergeCacheControl(cacheControlByFilePath[filePath], cacheLife);
|
|
143
136
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
137
|
+
if (!hasShell) {
|
|
138
|
+
if (isSharedShell) {
|
|
139
|
+
noShellRoutes.add(filePath);
|
|
140
|
+
}
|
|
141
|
+
if (allowExtraParams !== false) {
|
|
142
|
+
const warning = noPrerenderWarning(pathname);
|
|
143
|
+
if (failOnDynamic)
|
|
144
|
+
throw new Error(warning);
|
|
145
|
+
else
|
|
146
|
+
console.warn(warning);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (hasShell && postponedState) {
|
|
150
|
+
const html = await response.text();
|
|
151
|
+
if (isSharedShell) {
|
|
152
|
+
await api.notifyShellPrerender({
|
|
153
|
+
kind: "shared",
|
|
154
|
+
filePath,
|
|
155
|
+
postponedState,
|
|
156
|
+
html,
|
|
157
|
+
notFound: prerenderMeta.notFound,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
await api.notifyShellPrerender({
|
|
162
|
+
kind: "static",
|
|
163
|
+
filePath,
|
|
164
|
+
pathname,
|
|
165
|
+
postponedState,
|
|
166
|
+
html,
|
|
167
|
+
notFound: prerenderMeta.notFound,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
else if (hasShell &&
|
|
172
|
+
cacheLife?.revalidate !== 0 &&
|
|
173
|
+
(!isDynamic || allowExtraParams === false)) {
|
|
174
|
+
const html = await response.text();
|
|
175
|
+
// Capture the RSC payload so adapters can ship it as a STATIC entry.
|
|
176
|
+
// Otherwise every cold RSC request uses the empty pass-through PPR
|
|
177
|
+
// entry and chains through the function.
|
|
178
|
+
const rscPayload = !hasPrerenderRequestIO && !prerenderMeta.notFound
|
|
179
|
+
? await entryModule
|
|
180
|
+
.handlePageRoute(new Request(`http://localhost${pathname}`, {
|
|
181
|
+
headers: { accept: "text/x-component" },
|
|
182
|
+
}), route, params, prerenderOptions)
|
|
183
|
+
.then((rscResponse) => rscResponse.text())
|
|
184
|
+
: undefined;
|
|
148
185
|
await api.notifyShellPrerender({
|
|
149
|
-
kind: "
|
|
186
|
+
kind: "static-html",
|
|
150
187
|
filePath,
|
|
151
|
-
|
|
188
|
+
pathname,
|
|
152
189
|
html,
|
|
190
|
+
...(rscPayload !== undefined && { rscPayload }),
|
|
153
191
|
notFound: prerenderMeta.notFound,
|
|
154
192
|
});
|
|
155
193
|
}
|
|
156
194
|
else {
|
|
195
|
+
// HTML is already cached inside handlePageRoute; drop the unused body.
|
|
196
|
+
response.body?.cancel().catch(() => { });
|
|
197
|
+
}
|
|
198
|
+
console.log(`[rebask] ${hasShell ? "✓" : "✗"} ${pathname}`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (route.markdownFilePath) {
|
|
202
|
+
for (const { pathname, params } of requests) {
|
|
203
|
+
// A dynamic route's empty-params request is only a shared shell, not a real URL.
|
|
204
|
+
if (isDynamic && Object.keys(params).length === 0)
|
|
205
|
+
continue;
|
|
206
|
+
const request = new Request(`http://localhost${pathname}`, {
|
|
207
|
+
headers: { accept: "text/markdown" },
|
|
208
|
+
});
|
|
209
|
+
let markdownMeta;
|
|
210
|
+
const response = await entryModule.handleMarkdownRoute(request, route, params, {
|
|
211
|
+
isBuildPrerender: true,
|
|
212
|
+
onBuildPrerenderMeta(meta) {
|
|
213
|
+
markdownMeta = meta;
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
const markdown = await response.text();
|
|
217
|
+
if (markdownMeta?.static) {
|
|
157
218
|
await api.notifyShellPrerender({
|
|
158
|
-
kind: "
|
|
159
|
-
filePath,
|
|
219
|
+
kind: "markdown",
|
|
160
220
|
pathname,
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
notFound: prerenderMeta.notFound,
|
|
221
|
+
markdown,
|
|
222
|
+
cacheLife: markdownMeta.cacheLife,
|
|
164
223
|
});
|
|
224
|
+
console.log(`[rebask] ✓ ${pathname}.md`);
|
|
165
225
|
}
|
|
166
226
|
}
|
|
167
|
-
else if (hasShell &&
|
|
168
|
-
cacheLife?.revalidate !== 0 &&
|
|
169
|
-
(!isDynamic || allowExtraParams === false)) {
|
|
170
|
-
await api.notifyShellPrerender({
|
|
171
|
-
kind: "static-html",
|
|
172
|
-
filePath,
|
|
173
|
-
pathname,
|
|
174
|
-
html: await response.text(),
|
|
175
|
-
notFound: prerenderMeta.notFound,
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
else {
|
|
179
|
-
// HTML is already cached inside handlePageRoute; drop the unused body.
|
|
180
|
-
response.body?.cancel().catch(() => { });
|
|
181
|
-
}
|
|
182
|
-
console.log(`[rebask] ${hasShell ? "✓" : "✗"} ${pathname}`);
|
|
183
227
|
}
|
|
184
228
|
// Prerender intermediate shells from layout `prerenderParams` (closest/richest first).
|
|
185
229
|
if (shellParams && allowExtraParams !== false) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wint-router.d.ts","sourceRoot":"","sources":["../../../src/plugins/router/wint-router.ts"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"wint-router.d.ts","sourceRoot":"","sources":["../../../src/plugins/router/wint-router.ts"],"names":[],"mappings":"AAEA,OAAO,EAGN,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,MAAM,kCAAkC,CAAA;AAsEzC;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,YAAY,CA4DjE"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Wint from "wint-js/turbo";
|
|
2
|
-
import { RouteType } from "../../lib/server-router/types.js";
|
|
2
|
+
import { RouteType, } from "../../lib/server-router/types.js";
|
|
3
3
|
/**
|
|
4
4
|
* Convert a route's segments to Wint-compatible pattern
|
|
5
5
|
* Examples:
|
|
@@ -110,7 +110,9 @@ export function createMatcher(entries) {
|
|
|
110
110
|
}
|
|
111
111
|
return (req) => entry.handler(req, params);
|
|
112
112
|
}
|
|
113
|
-
|
|
113
|
+
const handler = (req) => entry.handler(req, extractParams(entry.route.segments, ctx.params ?? {}));
|
|
114
|
+
handler.route = entry.route;
|
|
115
|
+
return handler;
|
|
114
116
|
},
|
|
115
117
|
};
|
|
116
118
|
}
|
package/dist/router.d.ts
CHANGED
|
@@ -115,7 +115,7 @@ declare class Router {
|
|
|
115
115
|
* Refetch any stale (or missing) segments for a URL whose route tree is
|
|
116
116
|
* already known, without ever fetching the route tree itself.
|
|
117
117
|
*
|
|
118
|
-
* Designed for hover / focus signals like `<Link
|
|
118
|
+
* Designed for hover / focus signals like `<Link>`. If the route tree
|
|
119
119
|
* hasn't been cached yet this is a no-op, and it's safe to call repeatedly because in-flight
|
|
120
120
|
* fetches dedupe and fully fresh trees do zero work.
|
|
121
121
|
*/
|
package/dist/router.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AAcrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAczD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,EAGN,KAAK,iBAAiB,EACtB,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAmB,KAAK,WAAW,EAAqB,MAAM,uBAAuB,CAAA;AAC5F,OAAO,KAAK,EAAoB,OAAO,EAA+B,MAAM,uBAAuB,CAAA;AAyCnG,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAA;AAC7D,YAAY,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAEpD,MAAM,MAAM,iBAAiB,GAAG;IAC/B;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC7B,qEAAqE;IACrE,MAAM,CAAC,EAAE,OAAO,CAAA;CAChB,CAAA;AASD,eAAO,MAAM,iBAAiB,mDAAoD,CAAA;AAElF,gEAAgE;AAChE,KAAK,iBAAiB,GAAG;IAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAA;AAsL5D,wEAAwE;AACxE,cAAM,MAAM;IAEV,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,OAAO;IAFhB,YACS,KAAK,EAAE,WAAW,EAClB,OAAO,GAAE,OAAO,GAAG,IAAW,EACnC;IAEJ,yCAAyC;IACzC,IAAI,QAAS,MAAM,GAAG,GAAG,YAAY,eAAe,KAAG,IAAI,CAU1D;IAED;;;OAGG;IACH,aAAa,UAAW,kBAAkB,KAAG,IAAI,CAGhD;IAED,yBAAyB,YAAa,OAAO,KAAG,IAAI,CAMnD;IAED;;OAEG;IACH,OAAO,QAAS,MAAM,GAAG,GAAG,YAAY,eAAe,KAAG,IAAI,CAU7D;IAED;;;;;;OAMG;YACW,cAAc;IAwC5B,4FAA4F;IAC5F,OAAO,CAAC,eAAe;IAIvB;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IASxB,0FAA0F;IAC1F,OAAO,CAAC,YAAY;IAmBpB;;;;;;;OAOG;YACW,eAAe;
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.tsx"],"names":[],"mappings":"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"}
|
package/dist/router.js
CHANGED
|
@@ -320,7 +320,9 @@ class Router {
|
|
|
320
320
|
const search = segmentLocation.search ?? "";
|
|
321
321
|
const fetchKey = `${segmentPath}?${search}`;
|
|
322
322
|
const { shellable, shellKey } = this.segmentShell(segmentLocation);
|
|
323
|
-
const cachedShell = import.meta.env.PROD && shellable && !skipShell
|
|
323
|
+
const cachedShell = import.meta.env.PROD && shellable && !skipShell
|
|
324
|
+
? (this.cache.getShell(segmentPath) ?? this.cache.getShell(shellKey))
|
|
325
|
+
: undefined;
|
|
324
326
|
const reusePolicy = this.cache.getSegmentReusePolicy(segmentLocation, cachedShell);
|
|
325
327
|
const { completeShell, inBackground } = reusePolicy;
|
|
326
328
|
let shell = reusePolicy.showShell ? cachedShell : undefined;
|
|
@@ -475,8 +477,11 @@ class Router {
|
|
|
475
477
|
// constantly, so no stable shell survives to match. Serve the full segment instead.
|
|
476
478
|
if (import.meta.env.DEV)
|
|
477
479
|
return null;
|
|
478
|
-
const
|
|
479
|
-
|
|
480
|
+
const usable = (shell) => shell && !shell.stale && (!shell.staticOnly || shell.path === segmentLocation.path);
|
|
481
|
+
const concrete = this.cache.getShell(segmentLocation.path);
|
|
482
|
+
const shared = this.cache.getShell(key);
|
|
483
|
+
const cached = usable(concrete) ? concrete : usable(shared) ? shared : undefined;
|
|
484
|
+
if (cached)
|
|
480
485
|
return cached;
|
|
481
486
|
let inFlight = inflightShellCache.get(key);
|
|
482
487
|
if (!inFlight || !inFlight.isCurrent()) {
|
|
@@ -499,6 +504,10 @@ class Router {
|
|
|
499
504
|
inflightShellCache.delete(key);
|
|
500
505
|
if (!shell)
|
|
501
506
|
return null;
|
|
507
|
+
// Another path answered the shared key with a static page. It cannot serve this one.
|
|
508
|
+
if (shell.staticOnly && shell.path !== segmentLocation.path) {
|
|
509
|
+
return this.ensureShell(segmentLocation, key, expectedRoutePrediction);
|
|
510
|
+
}
|
|
502
511
|
const payload = await shell.payload;
|
|
503
512
|
if (!inFlight.isCurrent())
|
|
504
513
|
return null;
|
|
@@ -511,7 +520,7 @@ class Router {
|
|
|
511
520
|
this.cache.markSegmentStale(segmentLocation);
|
|
512
521
|
throw new RoutePredictionMismatch();
|
|
513
522
|
}
|
|
514
|
-
this.cache.cacheShell(key, shell);
|
|
523
|
+
this.cache.cacheShell(shell.staticOnly ? segmentLocation.path : key, shell);
|
|
515
524
|
return shell;
|
|
516
525
|
}
|
|
517
526
|
async fetchSegmentShell(segmentLocation) {
|
|
@@ -536,7 +545,8 @@ class Router {
|
|
|
536
545
|
}));
|
|
537
546
|
const resolvedPayload = await payload;
|
|
538
547
|
const segmentHints = id === null ? await extractSegmentHints(resolvedPayload.seedData.content) : undefined;
|
|
539
|
-
|
|
548
|
+
const staticOnly = "routePrediction" in resolvedPayload && resolvedPayload.routePrediction?.[3] === true;
|
|
549
|
+
return { bytes, path: segmentLocation.path, staticOnly, id, payload, cachedAt, ...segmentHints };
|
|
540
550
|
}
|
|
541
551
|
/**
|
|
542
552
|
* Prefetch all missing segments for a route tree and cache them.
|
|
@@ -720,7 +730,7 @@ class Router {
|
|
|
720
730
|
* Refetch any stale (or missing) segments for a URL whose route tree is
|
|
721
731
|
* already known, without ever fetching the route tree itself.
|
|
722
732
|
*
|
|
723
|
-
* Designed for hover / focus signals like `<Link
|
|
733
|
+
* Designed for hover / focus signals like `<Link>`. If the route tree
|
|
724
734
|
* hasn't been cached yet this is a no-op, and it's safe to call repeatedly because in-flight
|
|
725
735
|
* fetches dedupe and fully fresh trees do zero work.
|
|
726
736
|
*/
|
package/dist/server-router.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { RouteType } from "./lib/server-router/types.js";
|
|
2
|
-
export type { CreateMatcherFn, RouteEntry, RouteMatcher } from "./lib/server-router/types.js";
|
|
2
|
+
export type { CreateMatcherFn, MatchedHandler, RouteEntry, RouteMatcher, } from "./lib/server-router/types.js";
|
|
3
3
|
export type { LayoutRoute, NotFoundRoute, Route, RouteSegment, RouteHandlerRoute, } from "./lib/route-matcher.js";
|
|
4
4
|
export { createRouterPlugin, rebaskRouter, type RouterPluginOptions, } from "./plugins/router/router-plugin.js";
|
|
5
5
|
//# sourceMappingURL=server-router.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-router.d.ts","sourceRoot":"","sources":["../src/server-router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AACxD,YAAY,
|
|
1
|
+
{"version":3,"file":"server-router.d.ts","sourceRoot":"","sources":["../src/server-router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AACxD,YAAY,EACX,eAAe,EACf,cAAc,EACd,UAAU,EACV,YAAY,GACZ,MAAM,8BAA8B,CAAA;AACrC,YAAY,EACX,WAAW,EACX,aAAa,EACb,KAAK,EACL,YAAY,EACZ,iBAAiB,GACjB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EACN,kBAAkB,EAClB,YAAY,EACZ,KAAK,mBAAmB,GACxB,MAAM,mCAAmC,CAAA"}
|