@rebask/core 0.1.5 → 0.2.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.
Files changed (83) hide show
  1. package/dist/entry.rsc.d.ts +1 -0
  2. package/dist/entry.rsc.d.ts.map +1 -1
  3. package/dist/entry.rsc.js +1 -0
  4. package/dist/handlers/markdown.d.ts +16 -0
  5. package/dist/handlers/markdown.d.ts.map +1 -0
  6. package/dist/handlers/markdown.js +161 -0
  7. package/dist/handlers/rsc/cache-lookup.d.ts.map +1 -1
  8. package/dist/handlers/rsc/cache-lookup.js +10 -4
  9. package/dist/handlers/rsc/index.js +1 -1
  10. package/dist/handlers/rsc/render-to-response.js +6 -2
  11. package/dist/handlers/rsc/segment-shell.d.ts +1 -1
  12. package/dist/handlers/rsc/segment-shell.d.ts.map +1 -1
  13. package/dist/handlers/rsc/segment-shell.js +5 -9
  14. package/dist/handlers/rsc/state.d.ts +1 -0
  15. package/dist/handlers/rsc/state.d.ts.map +1 -1
  16. package/dist/handlers/rsc/state.js +4 -0
  17. package/dist/lib/app-manifest.d.ts +12 -4
  18. package/dist/lib/app-manifest.d.ts.map +1 -1
  19. package/dist/lib/app-manifest.js +5 -0
  20. package/dist/lib/cache-key-tags.d.ts +2 -0
  21. package/dist/lib/cache-key-tags.d.ts.map +1 -1
  22. package/dist/lib/cache-key-tags.js +2 -0
  23. package/dist/lib/cache-storage.d.ts +7 -2
  24. package/dist/lib/cache-storage.d.ts.map +1 -1
  25. package/dist/lib/cache-storage.js +1 -0
  26. package/dist/lib/config.d.ts +2 -0
  27. package/dist/lib/config.d.ts.map +1 -1
  28. package/dist/lib/config.js +8 -3
  29. package/dist/lib/dev-page-exports.d.ts +5 -0
  30. package/dist/lib/dev-page-exports.d.ts.map +1 -0
  31. package/dist/lib/dev-page-exports.js +14 -0
  32. package/dist/lib/lru-cache.d.ts.map +1 -1
  33. package/dist/lib/lru-cache.js +2 -0
  34. package/dist/lib/markdown.d.ts +5 -0
  35. package/dist/lib/markdown.d.ts.map +1 -0
  36. package/dist/lib/markdown.js +53 -0
  37. package/dist/lib/page-exports.d.ts +9 -0
  38. package/dist/lib/page-exports.d.ts.map +1 -0
  39. package/dist/lib/page-exports.js +47 -0
  40. package/dist/lib/ppr/cache-status.d.ts +3 -0
  41. package/dist/lib/ppr/cache-status.d.ts.map +1 -0
  42. package/dist/lib/ppr/cache-status.js +5 -0
  43. package/dist/lib/ppr/headers.d.ts +1 -1
  44. package/dist/lib/ppr/headers.d.ts.map +1 -1
  45. package/dist/lib/ppr/headers.js +1 -1
  46. package/dist/lib/prerender-params.d.ts +1 -1
  47. package/dist/lib/prerender-params.d.ts.map +1 -1
  48. package/dist/lib/prerender-params.js +17 -2
  49. package/dist/lib/project-files.d.ts +2 -1
  50. package/dist/lib/project-files.d.ts.map +1 -1
  51. package/dist/lib/project-files.js +16 -6
  52. package/dist/lib/route-builder.d.ts +4 -3
  53. package/dist/lib/route-builder.d.ts.map +1 -1
  54. package/dist/lib/route-builder.js +61 -13
  55. package/dist/lib/route-matcher.d.ts +4 -0
  56. package/dist/lib/route-matcher.d.ts.map +1 -1
  57. package/dist/lib/rsc-request.d.ts.map +1 -1
  58. package/dist/lib/rsc-request.js +3 -3
  59. package/dist/lib/server-router/get-router.d.ts.map +1 -1
  60. package/dist/lib/server-router/get-router.js +71 -16
  61. package/dist/lib/server-router/types.d.ts +4 -1
  62. package/dist/lib/server-router/types.d.ts.map +1 -1
  63. package/dist/lib/write-behind-cache.d.ts.map +1 -1
  64. package/dist/lib/write-behind-cache.js +5 -3
  65. package/dist/plugins/devtools.d.ts.map +1 -1
  66. package/dist/plugins/devtools.js +2 -2
  67. package/dist/plugins/ppr.d.ts +5 -0
  68. package/dist/plugins/ppr.d.ts.map +1 -1
  69. package/dist/plugins/prerender.d.ts.map +1 -1
  70. package/dist/plugins/prerender.js +114 -70
  71. package/dist/plugins/router/wint-router.d.ts.map +1 -1
  72. package/dist/plugins/router/wint-router.js +4 -2
  73. package/dist/router.d.ts +1 -1
  74. package/dist/router.js +1 -1
  75. package/dist/server-router.d.ts +1 -1
  76. package/dist/server-router.d.ts.map +1 -1
  77. package/dist/vite.d.ts +20 -1
  78. package/dist/vite.d.ts.map +1 -1
  79. package/dist/vite.js +17 -4
  80. package/package.json +1 -5
  81. package/dist/components/prefetch-links.d.ts +0 -5
  82. package/dist/components/prefetch-links.d.ts.map +0 -1
  83. 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
- appEntries.push({
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
- appEntries.push({
37
- type: RouteType.APP,
38
- methods: ["GET", "POST"],
39
- route,
40
- handler: (req, params) => handlePageRoute(req, route, params),
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
- appEntries.push({
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 isRscRequest = request.headers.get("accept")?.startsWith("text/x-component");
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
- assertNoPageRouteHandlerConflicts(pages, Object.keys(routeHandlerModules));
168
- const routes = buildRoutes(layouts, pages);
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): FindHandler<E> | null;
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,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;CACxD;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
+ {"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,CAuHd"}
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.DURABLE_CACHE
66
- ? entry.data.length
67
- : entry.rsc.length;
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,CAwG3F"}
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"}
@@ -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
  };
@@ -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;AAOlC,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,CA6VR"}
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
- const paramsResult = isDynamic ? await entryModule.getPrerenderParams(route) : null;
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
- const requestResults = await Promise.all(requests.map(async ({ pathname, params }) => {
100
- let prerenderMeta;
101
- const isSharedShell = isDynamic && Object.keys(params).length === 0;
102
- const request = new Request(`http://localhost${pathname}`, {
103
- headers: { accept: "text/html" },
104
- });
105
- const response = await entryModule.handlePageRoute(request, route, params, {
106
- ...prerenderOptions,
107
- // The build URL is only a static prefix. Force unresolved params and skip any
108
- // HTML cached at that URL.
109
- ...(isSharedShell && { resolvedParams: new Set() }),
110
- onBuildPrerenderMeta(meta) {
111
- prerenderMeta = meta;
112
- },
113
- });
114
- if (!prerenderMeta) {
115
- throw new Error(`Missing build prerender metadata for "${route.filePath}" at "${pathname}"`);
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
- cacheControlByFilePath[filePath] = mergeCacheControl(cacheControlByFilePath[filePath], cacheLife);
132
- }
133
- if (!hasShell) {
134
- if (isSharedShell) {
135
- noShellRoutes.add(filePath);
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 (allowExtraParams !== false) {
138
- const warning = noPrerenderWarning(pathname);
139
- if (failOnDynamic)
140
- throw new Error(warning);
141
- else
142
- console.warn(warning);
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
- if (hasShell && postponedState) {
146
- const html = await response.text();
147
- if (isSharedShell) {
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: "shared",
186
+ kind: "static-html",
150
187
  filePath,
151
- postponedState,
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: "static",
159
- filePath,
219
+ kind: "markdown",
160
220
  pathname,
161
- postponedState,
162
- html,
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,EAAa,KAAK,UAAU,EAAE,KAAK,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAsEhG;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,YAAY,CAwDjE"}
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
- return (req) => entry.handler(req, extractParams(entry.route.segments, ctx.params ?? {}));
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>` and `<PrefetchLinks>`. If the route tree
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.js CHANGED
@@ -720,7 +720,7 @@ class Router {
720
720
  * Refetch any stale (or missing) segments for a URL whose route tree is
721
721
  * already known, without ever fetching the route tree itself.
722
722
  *
723
- * Designed for hover / focus signals like `<Link>` and `<PrefetchLinks>`. If the route tree
723
+ * Designed for hover / focus signals like `<Link>`. If the route tree
724
724
  * hasn't been cached yet this is a no-op, and it's safe to call repeatedly because in-flight
725
725
  * fetches dedupe and fully fresh trees do zero work.
726
726
  */
@@ -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,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAC7F,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"}
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"}
package/dist/vite.d.ts CHANGED
@@ -21,9 +21,20 @@ type StaticHtmlPrerender = {
21
21
  filePath: string;
22
22
  pathname: string;
23
23
  html: string;
24
+ rscPayload?: string;
24
25
  /** The page answers 404. */
25
26
  notFound: boolean;
26
27
  };
28
+ type MarkdownPrerender = {
29
+ kind: "markdown";
30
+ pathname: string;
31
+ markdown: string;
32
+ cacheLife: {
33
+ revalidate: number;
34
+ expire: number;
35
+ tags?: string[];
36
+ };
37
+ };
27
38
  type IntermediateShellPrerender = {
28
39
  kind: "intermediate";
29
40
  /** Baked param names in route order. */
@@ -34,7 +45,7 @@ type IntermediateShellPrerender = {
34
45
  params: Record<string, string | string[] | undefined>;
35
46
  } & ShellPrerenderBase;
36
47
  /** Prerendered HTML from a successful build (for platform adapters). */
37
- export type ShellPrerenderResult = SharedShellPrerender | StaticShellPrerender | StaticHtmlPrerender | IntermediateShellPrerender;
48
+ export type ShellPrerenderResult = SharedShellPrerender | StaticShellPrerender | StaticHtmlPrerender | IntermediateShellPrerender | MarkdownPrerender;
38
49
  export interface RebaskPluginApi {
39
50
  /** Get all routes (available after RSC build) */
40
51
  getRoutes: () => Route[];
@@ -47,6 +58,8 @@ export interface RebaskPluginApi {
47
58
  getLayoutRoutes: () => LayoutRoute[];
48
59
  /** Get route handler routes (available after RSC build) */
49
60
  getRouteHandlerRoutes: () => RouteHandlerRoute[];
61
+ /** Whether routes with a Markdown representation are also served at `.md` URLs. */
62
+ hasMarkdownUrls: () => boolean;
50
63
  /** Get the built RSC entry, which a platform can move out of `dist` (available after config resolution) */
51
64
  getRscEntry: () => string;
52
65
  /** Override the deployment id used for skew protection. */
@@ -96,6 +109,12 @@ export interface RebaskPluginOptions {
96
109
  * @default false
97
110
  */
98
111
  fullHtmlForBots?: boolean;
112
+ /**
113
+ * Serve routes with a `markdown.md` or `markdown.ts` file at their `.md` URL as well as through
114
+ * `Accept`.
115
+ * @default true
116
+ */
117
+ markdownUrls?: boolean;
99
118
  /**
100
119
  * Propagation keys (e.g. `["traceparent"]`) to expose to the browser, so client-side navigation,
101
120
  * prefetch, and server function requests join the same trace.
@@ -1 +1 @@
1
- {"version":3,"file":"vite.d.ts","sourceRoot":"","sources":["../src/vite.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"vite.d.ts","sourceRoot":"","sources":["../src/vite.ts"],"names":[],"mappings":"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"}