@webtypen/webframez-react 0.0.14 → 0.0.16

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/index.js CHANGED
@@ -166,6 +166,7 @@ function createRSCHandler(options) {
166
166
 
167
167
  // src/file-router.tsx
168
168
  import fs from "node:fs";
169
+ import Module from "node:module";
169
170
  import path2 from "node:path";
170
171
 
171
172
  // src/router-runtime.tsx
@@ -228,6 +229,26 @@ function injectRouteChildren(node, routeChildren) {
228
229
 
229
230
  // src/file-router.tsx
230
231
  import { jsx, jsxs } from "react/jsx-runtime";
232
+ var ROOT_RUNTIME_REQUIRE = Module.createRequire(
233
+ path2.join(process.cwd(), "__webframez_react_runtime__.js")
234
+ );
235
+ var FORCED_PACKAGE_REQUESTS = [
236
+ "@webtypen/webframez-core",
237
+ "@webtypen/webframez-react",
238
+ "react",
239
+ "react/jsx-runtime",
240
+ "react/jsx-dev-runtime",
241
+ "react-dom",
242
+ "react-dom/client",
243
+ "react-dom/server",
244
+ "react-dom/server.node",
245
+ "react-server-dom-webpack",
246
+ "react-server-dom-webpack/server",
247
+ "react-server-dom-webpack/client",
248
+ "react-server-dom-webpack/client.node",
249
+ "scheduler"
250
+ ];
251
+ var forcedPackageResolutionInstalled = false;
231
252
  function normalizePathname(pathname) {
232
253
  const trimmed = pathname.replace(/\/+$/, "") || "/";
233
254
  return trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
@@ -276,6 +297,28 @@ var MANAGED_HEAD_ATTR = "data-webframez-head";
276
297
  function createManagedAttributes() {
277
298
  return `${MANAGED_HEAD_ATTR}="true"`;
278
299
  }
300
+ function shouldForcePackageResolution(request) {
301
+ return FORCED_PACKAGE_REQUESTS.some(
302
+ (candidate) => request === candidate || request.startsWith(`${candidate}/`)
303
+ );
304
+ }
305
+ function installForcedPackageResolution() {
306
+ if (forcedPackageResolutionInstalled) {
307
+ return;
308
+ }
309
+ const moduleWithPrivateResolver = Module;
310
+ const originalResolveFilename = moduleWithPrivateResolver._resolveFilename;
311
+ moduleWithPrivateResolver._resolveFilename = function patchedResolveFilename(request, parent, isMain, options) {
312
+ if (typeof request === "string" && shouldForcePackageResolution(request)) {
313
+ try {
314
+ return ROOT_RUNTIME_REQUIRE.resolve(request);
315
+ } catch {
316
+ }
317
+ }
318
+ return originalResolveFilename.call(this, request, parent, isMain, options);
319
+ };
320
+ forcedPackageResolutionInstalled = true;
321
+ }
279
322
  function toRouteEntry(pagesDir, filePath) {
280
323
  const normalized = filePath.replace(/\\/g, "/");
281
324
  if (!normalized.endsWith("/index.js")) {
@@ -423,9 +466,11 @@ function isRouteAbort(value) {
423
466
  }
424
467
  }
425
468
  function createFileRouter(options) {
469
+ installForcedPackageResolution();
426
470
  const pagesDir = options.pagesDir;
427
471
  const layoutPath = path2.join(pagesDir, "layout.js");
428
472
  const errorPath = path2.join(pagesDir, "errors.js");
473
+ const middlewaresPath = path2.join(pagesDir, "middlewares.js");
429
474
  function buildRouteEntries() {
430
475
  const files = walkFiles(pagesDir);
431
476
  return files.map((filePath) => toRouteEntry(pagesDir, filePath)).filter((entry) => entry !== null).sort((a, b) => {
@@ -468,6 +513,75 @@ function createFileRouter(options) {
468
513
  head: mergeHead(layoutHead, errorHead)
469
514
  };
470
515
  }
516
+ function normalizeMiddlewareNames(config) {
517
+ if (!config) {
518
+ return [];
519
+ }
520
+ return Array.isArray(config) ? config : [config];
521
+ }
522
+ function isPlainObject(value) {
523
+ if (!value || typeof value !== "object") {
524
+ return false;
525
+ }
526
+ const prototype = Object.getPrototypeOf(value);
527
+ return prototype === Object.prototype || prototype === null;
528
+ }
529
+ function mergeRouteData(currentData, nextData) {
530
+ if (typeof nextData === "undefined") {
531
+ return currentData;
532
+ }
533
+ if (isPlainObject(currentData) && isPlainObject(nextData)) {
534
+ return {
535
+ ...currentData,
536
+ ...nextData
537
+ };
538
+ }
539
+ return nextData;
540
+ }
541
+ async function resolveMiddlewares(config, context) {
542
+ const middlewareNames = normalizeMiddlewareNames(config);
543
+ const requiresNamedMiddleware = middlewareNames.length > 0;
544
+ if (!fs.existsSync(middlewaresPath)) {
545
+ if (!requiresNamedMiddleware) {
546
+ return context;
547
+ }
548
+ throw createAbort({
549
+ status: 500,
550
+ message: `Invalid middleware '${middlewareNames[0]}'`
551
+ });
552
+ }
553
+ const middlewareModule = resolveModule(middlewaresPath);
554
+ const registry = middlewareModule.middlewares;
555
+ if (!registry) {
556
+ if (!requiresNamedMiddleware) {
557
+ return context;
558
+ }
559
+ throw createAbort({
560
+ status: 500,
561
+ message: `Invalid middleware '${middlewareNames[0]}'`
562
+ });
563
+ }
564
+ const orderedMiddlewareNames = typeof registry["*"] === "function" ? ["*", ...middlewareNames] : middlewareNames;
565
+ if (orderedMiddlewareNames.length === 0) {
566
+ return context;
567
+ }
568
+ let nextContext = context;
569
+ for (const middlewareName of orderedMiddlewareNames) {
570
+ const middleware = registry[middlewareName];
571
+ if (typeof middleware !== "function") {
572
+ throw createAbort({
573
+ status: 500,
574
+ message: `Invalid middleware '${middlewareName}'`
575
+ });
576
+ }
577
+ const middlewareData = await middleware(nextContext);
578
+ nextContext = {
579
+ ...nextContext,
580
+ data: mergeRouteData(nextContext.data, middlewareData)
581
+ };
582
+ }
583
+ return nextContext;
584
+ }
471
585
  async function resolve(input) {
472
586
  const pathname = normalizePathname(input.pathname);
473
587
  const contextBase = {
@@ -493,10 +607,12 @@ function createFileRouter(options) {
493
607
  activeContext = context;
494
608
  const pageModule = resolveModule(match.entry.filePath);
495
609
  const layoutModule = fs.existsSync(layoutPath) ? resolveModule(layoutPath) : null;
496
- const pageData = await resolvePageData(pageModule, context);
610
+ const middlewareContext = await resolveMiddlewares(pageModule.middlewares, context);
611
+ activeContext = middlewareContext;
612
+ const pageData = await resolvePageData(pageModule, middlewareContext);
497
613
  const pageContext = {
498
- ...context,
499
- data: pageData
614
+ ...middlewareContext,
615
+ data: mergeRouteData(middlewareContext.data, pageData)
500
616
  };
501
617
  activeContext = pageContext;
502
618
  const pageNode = await pageModule.default(pageContext);
@@ -544,19 +660,34 @@ if (!pagesDir) {
544
660
  throw new Error("Missing WEBFRAMEZ_REACT_PAGES_DIR");
545
661
  }
546
662
 
547
- const appRequire = Module.createRequire(path.join(pagesDir, "__webframez_react_worker__.js"));
663
+ const rootRequire = Module.createRequire(path.join(process.cwd(), "__webframez_react_worker__.js"));
548
664
  const originalResolveFilename = Module._resolveFilename;
549
665
  const forcedResolutions = new Map([
550
- ["react", appRequire.resolve("react")],
551
- ["react/jsx-runtime", appRequire.resolve("react/jsx-runtime")],
552
- ["react/jsx-dev-runtime", appRequire.resolve("react/jsx-dev-runtime")],
553
- ["react-dom/client", appRequire.resolve("react-dom/client")]
666
+ ["@webtypen/webframez-core", rootRequire.resolve("@webtypen/webframez-core")],
667
+ ["@webtypen/webframez-react", rootRequire.resolve("@webtypen/webframez-react")],
668
+ ["react", rootRequire.resolve("react")],
669
+ ["react/jsx-runtime", rootRequire.resolve("react/jsx-runtime")],
670
+ ["react/jsx-dev-runtime", rootRequire.resolve("react/jsx-dev-runtime")],
671
+ ["react-dom", rootRequire.resolve("react-dom")],
672
+ ["react-dom/client", rootRequire.resolve("react-dom/client")],
673
+ ["react-dom/server", rootRequire.resolve("react-dom/server")],
674
+ ["react-dom/server.node", rootRequire.resolve("react-dom/server.node")],
675
+ ["react-server-dom-webpack", rootRequire.resolve("react-server-dom-webpack")],
676
+ ["react-server-dom-webpack/server", rootRequire.resolve("react-server-dom-webpack/server")],
677
+ ["react-server-dom-webpack/client", rootRequire.resolve("react-server-dom-webpack/client")],
678
+ ["react-server-dom-webpack/client.node", rootRequire.resolve("react-server-dom-webpack/client.node")],
679
+ ["scheduler", rootRequire.resolve("scheduler")]
554
680
  ]);
555
681
 
556
682
  Module._resolveFilename = function(request, parent, isMain, options) {
557
683
  if (forcedResolutions.has(request)) {
558
684
  return forcedResolutions.get(request);
559
685
  }
686
+ for (const forcedRequest of forcedResolutions.keys()) {
687
+ if (request.startsWith(forcedRequest + "/")) {
688
+ return rootRequire.resolve(request);
689
+ }
690
+ }
560
691
  return originalResolveFilename.call(this, request, parent, isMain, options);
561
692
  };
562
693
 
package/dist/router.cjs CHANGED
@@ -38,6 +38,7 @@ module.exports = __toCommonJS(router_exports);
38
38
 
39
39
  // src/file-router.tsx
40
40
  var import_node_fs = __toESM(require("node:fs"), 1);
41
+ var import_node_module = __toESM(require("node:module"), 1);
41
42
  var import_node_path = __toESM(require("node:path"), 1);
42
43
 
43
44
  // src/router-runtime.tsx
@@ -100,6 +101,26 @@ function injectRouteChildren(node, routeChildren) {
100
101
 
101
102
  // src/file-router.tsx
102
103
  var import_jsx_runtime = require("react/jsx-runtime");
104
+ var ROOT_RUNTIME_REQUIRE = import_node_module.default.createRequire(
105
+ import_node_path.default.join(process.cwd(), "__webframez_react_runtime__.js")
106
+ );
107
+ var FORCED_PACKAGE_REQUESTS = [
108
+ "@webtypen/webframez-core",
109
+ "@webtypen/webframez-react",
110
+ "react",
111
+ "react/jsx-runtime",
112
+ "react/jsx-dev-runtime",
113
+ "react-dom",
114
+ "react-dom/client",
115
+ "react-dom/server",
116
+ "react-dom/server.node",
117
+ "react-server-dom-webpack",
118
+ "react-server-dom-webpack/server",
119
+ "react-server-dom-webpack/client",
120
+ "react-server-dom-webpack/client.node",
121
+ "scheduler"
122
+ ];
123
+ var forcedPackageResolutionInstalled = false;
103
124
  function normalizePathname(pathname) {
104
125
  const trimmed = pathname.replace(/\/+$/, "") || "/";
105
126
  return trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
@@ -148,6 +169,28 @@ var MANAGED_HEAD_ATTR = "data-webframez-head";
148
169
  function createManagedAttributes() {
149
170
  return `${MANAGED_HEAD_ATTR}="true"`;
150
171
  }
172
+ function shouldForcePackageResolution(request) {
173
+ return FORCED_PACKAGE_REQUESTS.some(
174
+ (candidate) => request === candidate || request.startsWith(`${candidate}/`)
175
+ );
176
+ }
177
+ function installForcedPackageResolution() {
178
+ if (forcedPackageResolutionInstalled) {
179
+ return;
180
+ }
181
+ const moduleWithPrivateResolver = import_node_module.default;
182
+ const originalResolveFilename = moduleWithPrivateResolver._resolveFilename;
183
+ moduleWithPrivateResolver._resolveFilename = function patchedResolveFilename(request, parent, isMain, options) {
184
+ if (typeof request === "string" && shouldForcePackageResolution(request)) {
185
+ try {
186
+ return ROOT_RUNTIME_REQUIRE.resolve(request);
187
+ } catch {
188
+ }
189
+ }
190
+ return originalResolveFilename.call(this, request, parent, isMain, options);
191
+ };
192
+ forcedPackageResolutionInstalled = true;
193
+ }
151
194
  function toRouteEntry(pagesDir, filePath) {
152
195
  const normalized = filePath.replace(/\\/g, "/");
153
196
  if (!normalized.endsWith("/index.js")) {
@@ -295,9 +338,11 @@ function isRouteAbort(value) {
295
338
  }
296
339
  }
297
340
  function createFileRouter(options) {
341
+ installForcedPackageResolution();
298
342
  const pagesDir = options.pagesDir;
299
343
  const layoutPath = import_node_path.default.join(pagesDir, "layout.js");
300
344
  const errorPath = import_node_path.default.join(pagesDir, "errors.js");
345
+ const middlewaresPath = import_node_path.default.join(pagesDir, "middlewares.js");
301
346
  function buildRouteEntries() {
302
347
  const files = walkFiles(pagesDir);
303
348
  return files.map((filePath) => toRouteEntry(pagesDir, filePath)).filter((entry) => entry !== null).sort((a, b) => {
@@ -340,6 +385,75 @@ function createFileRouter(options) {
340
385
  head: mergeHead(layoutHead, errorHead)
341
386
  };
342
387
  }
388
+ function normalizeMiddlewareNames(config) {
389
+ if (!config) {
390
+ return [];
391
+ }
392
+ return Array.isArray(config) ? config : [config];
393
+ }
394
+ function isPlainObject(value) {
395
+ if (!value || typeof value !== "object") {
396
+ return false;
397
+ }
398
+ const prototype = Object.getPrototypeOf(value);
399
+ return prototype === Object.prototype || prototype === null;
400
+ }
401
+ function mergeRouteData(currentData, nextData) {
402
+ if (typeof nextData === "undefined") {
403
+ return currentData;
404
+ }
405
+ if (isPlainObject(currentData) && isPlainObject(nextData)) {
406
+ return {
407
+ ...currentData,
408
+ ...nextData
409
+ };
410
+ }
411
+ return nextData;
412
+ }
413
+ async function resolveMiddlewares(config, context) {
414
+ const middlewareNames = normalizeMiddlewareNames(config);
415
+ const requiresNamedMiddleware = middlewareNames.length > 0;
416
+ if (!import_node_fs.default.existsSync(middlewaresPath)) {
417
+ if (!requiresNamedMiddleware) {
418
+ return context;
419
+ }
420
+ throw createAbort({
421
+ status: 500,
422
+ message: `Invalid middleware '${middlewareNames[0]}'`
423
+ });
424
+ }
425
+ const middlewareModule = resolveModule(middlewaresPath);
426
+ const registry = middlewareModule.middlewares;
427
+ if (!registry) {
428
+ if (!requiresNamedMiddleware) {
429
+ return context;
430
+ }
431
+ throw createAbort({
432
+ status: 500,
433
+ message: `Invalid middleware '${middlewareNames[0]}'`
434
+ });
435
+ }
436
+ const orderedMiddlewareNames = typeof registry["*"] === "function" ? ["*", ...middlewareNames] : middlewareNames;
437
+ if (orderedMiddlewareNames.length === 0) {
438
+ return context;
439
+ }
440
+ let nextContext = context;
441
+ for (const middlewareName of orderedMiddlewareNames) {
442
+ const middleware = registry[middlewareName];
443
+ if (typeof middleware !== "function") {
444
+ throw createAbort({
445
+ status: 500,
446
+ message: `Invalid middleware '${middlewareName}'`
447
+ });
448
+ }
449
+ const middlewareData = await middleware(nextContext);
450
+ nextContext = {
451
+ ...nextContext,
452
+ data: mergeRouteData(nextContext.data, middlewareData)
453
+ };
454
+ }
455
+ return nextContext;
456
+ }
343
457
  async function resolve(input) {
344
458
  const pathname = normalizePathname(input.pathname);
345
459
  const contextBase = {
@@ -365,10 +479,12 @@ function createFileRouter(options) {
365
479
  activeContext = context;
366
480
  const pageModule = resolveModule(match.entry.filePath);
367
481
  const layoutModule = import_node_fs.default.existsSync(layoutPath) ? resolveModule(layoutPath) : null;
368
- const pageData = await resolvePageData(pageModule, context);
482
+ const middlewareContext = await resolveMiddlewares(pageModule.middlewares, context);
483
+ activeContext = middlewareContext;
484
+ const pageData = await resolvePageData(pageModule, middlewareContext);
369
485
  const pageContext = {
370
- ...context,
371
- data: pageData
486
+ ...middlewareContext,
487
+ data: mergeRouteData(middlewareContext.data, pageData)
372
488
  };
373
489
  activeContext = pageContext;
374
490
  const pageNode = await pageModule.default(pageContext);
package/dist/router.js CHANGED
@@ -8,6 +8,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
8
8
 
9
9
  // src/file-router.tsx
10
10
  import fs from "node:fs";
11
+ import Module from "node:module";
11
12
  import path from "node:path";
12
13
 
13
14
  // src/router-runtime.tsx
@@ -70,6 +71,26 @@ function injectRouteChildren(node, routeChildren) {
70
71
 
71
72
  // src/file-router.tsx
72
73
  import { jsx, jsxs } from "react/jsx-runtime";
74
+ var ROOT_RUNTIME_REQUIRE = Module.createRequire(
75
+ path.join(process.cwd(), "__webframez_react_runtime__.js")
76
+ );
77
+ var FORCED_PACKAGE_REQUESTS = [
78
+ "@webtypen/webframez-core",
79
+ "@webtypen/webframez-react",
80
+ "react",
81
+ "react/jsx-runtime",
82
+ "react/jsx-dev-runtime",
83
+ "react-dom",
84
+ "react-dom/client",
85
+ "react-dom/server",
86
+ "react-dom/server.node",
87
+ "react-server-dom-webpack",
88
+ "react-server-dom-webpack/server",
89
+ "react-server-dom-webpack/client",
90
+ "react-server-dom-webpack/client.node",
91
+ "scheduler"
92
+ ];
93
+ var forcedPackageResolutionInstalled = false;
73
94
  function normalizePathname(pathname) {
74
95
  const trimmed = pathname.replace(/\/+$/, "") || "/";
75
96
  return trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
@@ -118,6 +139,28 @@ var MANAGED_HEAD_ATTR = "data-webframez-head";
118
139
  function createManagedAttributes() {
119
140
  return `${MANAGED_HEAD_ATTR}="true"`;
120
141
  }
142
+ function shouldForcePackageResolution(request) {
143
+ return FORCED_PACKAGE_REQUESTS.some(
144
+ (candidate) => request === candidate || request.startsWith(`${candidate}/`)
145
+ );
146
+ }
147
+ function installForcedPackageResolution() {
148
+ if (forcedPackageResolutionInstalled) {
149
+ return;
150
+ }
151
+ const moduleWithPrivateResolver = Module;
152
+ const originalResolveFilename = moduleWithPrivateResolver._resolveFilename;
153
+ moduleWithPrivateResolver._resolveFilename = function patchedResolveFilename(request, parent, isMain, options) {
154
+ if (typeof request === "string" && shouldForcePackageResolution(request)) {
155
+ try {
156
+ return ROOT_RUNTIME_REQUIRE.resolve(request);
157
+ } catch {
158
+ }
159
+ }
160
+ return originalResolveFilename.call(this, request, parent, isMain, options);
161
+ };
162
+ forcedPackageResolutionInstalled = true;
163
+ }
121
164
  function toRouteEntry(pagesDir, filePath) {
122
165
  const normalized = filePath.replace(/\\/g, "/");
123
166
  if (!normalized.endsWith("/index.js")) {
@@ -265,9 +308,11 @@ function isRouteAbort(value) {
265
308
  }
266
309
  }
267
310
  function createFileRouter(options) {
311
+ installForcedPackageResolution();
268
312
  const pagesDir = options.pagesDir;
269
313
  const layoutPath = path.join(pagesDir, "layout.js");
270
314
  const errorPath = path.join(pagesDir, "errors.js");
315
+ const middlewaresPath = path.join(pagesDir, "middlewares.js");
271
316
  function buildRouteEntries() {
272
317
  const files = walkFiles(pagesDir);
273
318
  return files.map((filePath) => toRouteEntry(pagesDir, filePath)).filter((entry) => entry !== null).sort((a, b) => {
@@ -310,6 +355,75 @@ function createFileRouter(options) {
310
355
  head: mergeHead(layoutHead, errorHead)
311
356
  };
312
357
  }
358
+ function normalizeMiddlewareNames(config) {
359
+ if (!config) {
360
+ return [];
361
+ }
362
+ return Array.isArray(config) ? config : [config];
363
+ }
364
+ function isPlainObject(value) {
365
+ if (!value || typeof value !== "object") {
366
+ return false;
367
+ }
368
+ const prototype = Object.getPrototypeOf(value);
369
+ return prototype === Object.prototype || prototype === null;
370
+ }
371
+ function mergeRouteData(currentData, nextData) {
372
+ if (typeof nextData === "undefined") {
373
+ return currentData;
374
+ }
375
+ if (isPlainObject(currentData) && isPlainObject(nextData)) {
376
+ return {
377
+ ...currentData,
378
+ ...nextData
379
+ };
380
+ }
381
+ return nextData;
382
+ }
383
+ async function resolveMiddlewares(config, context) {
384
+ const middlewareNames = normalizeMiddlewareNames(config);
385
+ const requiresNamedMiddleware = middlewareNames.length > 0;
386
+ if (!fs.existsSync(middlewaresPath)) {
387
+ if (!requiresNamedMiddleware) {
388
+ return context;
389
+ }
390
+ throw createAbort({
391
+ status: 500,
392
+ message: `Invalid middleware '${middlewareNames[0]}'`
393
+ });
394
+ }
395
+ const middlewareModule = resolveModule(middlewaresPath);
396
+ const registry = middlewareModule.middlewares;
397
+ if (!registry) {
398
+ if (!requiresNamedMiddleware) {
399
+ return context;
400
+ }
401
+ throw createAbort({
402
+ status: 500,
403
+ message: `Invalid middleware '${middlewareNames[0]}'`
404
+ });
405
+ }
406
+ const orderedMiddlewareNames = typeof registry["*"] === "function" ? ["*", ...middlewareNames] : middlewareNames;
407
+ if (orderedMiddlewareNames.length === 0) {
408
+ return context;
409
+ }
410
+ let nextContext = context;
411
+ for (const middlewareName of orderedMiddlewareNames) {
412
+ const middleware = registry[middlewareName];
413
+ if (typeof middleware !== "function") {
414
+ throw createAbort({
415
+ status: 500,
416
+ message: `Invalid middleware '${middlewareName}'`
417
+ });
418
+ }
419
+ const middlewareData = await middleware(nextContext);
420
+ nextContext = {
421
+ ...nextContext,
422
+ data: mergeRouteData(nextContext.data, middlewareData)
423
+ };
424
+ }
425
+ return nextContext;
426
+ }
313
427
  async function resolve(input) {
314
428
  const pathname = normalizePathname(input.pathname);
315
429
  const contextBase = {
@@ -335,10 +449,12 @@ function createFileRouter(options) {
335
449
  activeContext = context;
336
450
  const pageModule = resolveModule(match.entry.filePath);
337
451
  const layoutModule = fs.existsSync(layoutPath) ? resolveModule(layoutPath) : null;
338
- const pageData = await resolvePageData(pageModule, context);
452
+ const middlewareContext = await resolveMiddlewares(pageModule.middlewares, context);
453
+ activeContext = middlewareContext;
454
+ const pageData = await resolvePageData(pageModule, middlewareContext);
339
455
  const pageContext = {
340
- ...context,
341
- data: pageData
456
+ ...middlewareContext,
457
+ data: mergeRouteData(middlewareContext.data, pageData)
342
458
  };
343
459
  activeContext = pageContext;
344
460
  const pageNode = await pageModule.default(pageContext);
package/dist/types.d.ts CHANGED
@@ -69,10 +69,18 @@ export type PageDataResolver<TData = unknown> = (
69
69
  context: RouteContext
70
70
  ) => TData | Promise<TData>;
71
71
 
72
+ export type RouteMiddlewareResult = Record<string, unknown> | undefined | void;
73
+ export type RouteMiddlewareResolver<TData = unknown> = (
74
+ context: RouteContext<TData>
75
+ ) => RouteMiddlewareResult | Promise<RouteMiddlewareResult>;
76
+ export type RouteMiddlewareRegistry = Record<string, RouteMiddlewareResolver<any>>;
77
+ export type RouteMiddlewareConfig = string | string[];
78
+
72
79
  export type PageModule<TData = unknown> = {
73
80
  default: (props: PageProps<TData>) => ReactNode | Promise<ReactNode>;
74
81
  Head?: HeadResolver<PageProps<TData>>;
75
82
  Data?: PageDataResolver<TData>;
83
+ middlewares?: RouteMiddlewareConfig;
76
84
  };
77
85
 
78
86
  export type LayoutModule = {
@@ -91,6 +99,8 @@ export type CreateHtmlShellOptions = {
91
99
  clientScriptUrl?: string;
92
100
  headTags?: string;
93
101
  rootHtml?: string;
102
+ initialFlightData?: string;
103
+ clientRenderMode?: "hydrate" | "mount";
94
104
  basename?: string;
95
105
  liveReloadPath?: string;
96
106
  liveReloadServerId?: string;