@webtypen/webframez-react 0.0.31 → 0.0.33

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
@@ -111,6 +111,7 @@ function sendRSC(res, model, options = {}) {
111
111
  } = options;
112
112
  res.statusCode = statusCode;
113
113
  res.setHeader("Content-Type", contentType);
114
+ res.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate");
114
115
  const stream = renderToPipeableStream(model, moduleMap, { onError });
115
116
  stream.pipe(res);
116
117
  return stream;
@@ -148,6 +149,7 @@ function createRSCHandler(options) {
148
149
  import fs from "node:fs";
149
150
  import Module from "node:module";
150
151
  import path2 from "node:path";
152
+ import { RouteChildrenSlot } from "@webtypen/webframez-react/route-slot";
151
153
 
152
154
  // src/head.ts
153
155
  var ABSOLUTE_ASSET_URL_PATTERN = /^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;
@@ -237,6 +239,16 @@ function isRouteChildrenType(type) {
237
239
  return false;
238
240
  }
239
241
  }
242
+ function isReactElementLike(node) {
243
+ if (!node || typeof node !== "object") {
244
+ return false;
245
+ }
246
+ try {
247
+ return "type" in node && "props" in node;
248
+ } catch {
249
+ return false;
250
+ }
251
+ }
240
252
  function injectRouteChildren(node, routeChildren) {
241
253
  if (node === null || node === void 0 || typeof node === "boolean") {
242
254
  return node;
@@ -252,13 +264,17 @@ function injectRouteChildren(node, routeChildren) {
252
264
  });
253
265
  return changed ? next : node;
254
266
  }
255
- if (!React.isValidElement(node)) {
267
+ if (isReactElementLike(node) && isRouteChildrenType(node.type)) {
268
+ return routeChildren;
269
+ }
270
+ const isValidElement = React.isValidElement(node);
271
+ if (!isValidElement && !isReactElementLike(node)) {
256
272
  return node;
257
273
  }
258
- if (isRouteChildrenType(node.type)) {
274
+ if (isValidElement && isRouteChildrenType(node.type)) {
259
275
  return routeChildren;
260
276
  }
261
- const props = node.props;
277
+ const props = node.props ?? {};
262
278
  if (!("children" in props)) {
263
279
  return node;
264
280
  }
@@ -266,10 +282,19 @@ function injectRouteChildren(node, routeChildren) {
266
282
  if (nextChildren === props.children) {
267
283
  return node;
268
284
  }
269
- if (Array.isArray(nextChildren)) {
270
- return React.cloneElement(node, void 0, ...nextChildren);
285
+ if (isValidElement) {
286
+ if (Array.isArray(nextChildren)) {
287
+ return React.cloneElement(node, void 0, ...nextChildren);
288
+ }
289
+ return React.cloneElement(node, void 0, nextChildren);
271
290
  }
272
- return React.cloneElement(node, void 0, nextChildren);
291
+ const elementLike = node;
292
+ const nextProps = {
293
+ ...elementLike.props ?? {},
294
+ children: nextChildren,
295
+ ...elementLike.key !== void 0 && elementLike.key !== null ? { key: elementLike.key } : {}
296
+ };
297
+ return React.createElement(elementLike.type, nextProps);
273
298
  }
274
299
 
275
300
  // src/file-router.tsx
@@ -434,15 +459,22 @@ function mergeHead(...configs) {
434
459
  if (!config) {
435
460
  continue;
436
461
  }
462
+ const hasOwn = (key) => Object.prototype.hasOwnProperty.call(config, key);
437
463
  if (config.title) {
438
464
  merged.title = config.title;
439
465
  }
440
466
  if (config.description) {
441
467
  merged.description = config.description;
442
468
  }
443
- if (config.basename) {
469
+ if (hasOwn("basename")) {
444
470
  merged.basename = config.basename;
445
471
  }
472
+ if (hasOwn("routeBasePath")) {
473
+ merged.routeBasePath = config.routeBasePath;
474
+ }
475
+ if (hasOwn("transportBasePath")) {
476
+ merged.transportBasePath = config.transportBasePath;
477
+ }
446
478
  if (config.favicon) {
447
479
  merged.favicon = config.favicon;
448
480
  }
@@ -603,9 +635,12 @@ function createFileRouter(options) {
603
635
  const errorHead = await resolveHead(errorModule, errorProps);
604
636
  const layoutNode = layoutModule ? await layoutModule.default(context) : null;
605
637
  const model = layoutNode ? injectRouteChildren(layoutNode, errorNode) : errorNode;
638
+ const contextModel = layoutNode ? injectRouteChildren(layoutNode, /* @__PURE__ */ jsx(RouteChildrenSlot, {})) : void 0;
606
639
  return {
607
640
  statusCode,
608
641
  model,
642
+ contextModel,
643
+ pageModel: errorNode,
609
644
  head: mergeHead(layoutHead, errorHead)
610
645
  };
611
646
  }
@@ -725,9 +760,12 @@ function createFileRouter(options) {
725
760
  const pageHead = await resolveHead(pageModule, pageContext);
726
761
  const layoutNode = layoutModule ? await layoutModule.default(pageContext) : null;
727
762
  const model = layoutNode ? injectRouteChildren(layoutNode, pageNode) : pageNode;
763
+ const contextModel = layoutNode ? injectRouteChildren(layoutNode, /* @__PURE__ */ jsx(RouteChildrenSlot, {})) : void 0;
728
764
  return {
729
765
  statusCode: 200,
730
766
  model,
767
+ contextModel,
768
+ pageModel: pageNode,
731
769
  head: mergeHead(layoutHead, pageHead)
732
770
  };
733
771
  } catch (error) {
@@ -886,7 +924,7 @@ async function decodeFlightPayloadFromString(flightData, moduleMap) {
886
924
 
887
925
  if (typeof reactServerDomClientNode.createFromNodeStream === "function") {
888
926
  return await reactServerDomClientNode.createFromNodeStream(
889
- Readable.from([flightData]),
927
+ Readable.from([Buffer.from(flightData)]),
890
928
  serverConsumerManifest
891
929
  );
892
930
  }
@@ -911,7 +949,21 @@ async function renderHtmlFromFlightData(flightData, moduleMap) {
911
949
  ? payload.model
912
950
  : payload;
913
951
 
914
- return renderHtml(model);
952
+ const basename =
953
+ payload &&
954
+ typeof payload === "object" &&
955
+ payload.head &&
956
+ typeof payload.head.basename === "string"
957
+ ? payload.head.basename
958
+ : "";
959
+
960
+ const previousBasename = globalThis.__RSC_BASENAME;
961
+ globalThis.__RSC_BASENAME = basename;
962
+ try {
963
+ return await renderHtml(model);
964
+ } finally {
965
+ globalThis.__RSC_BASENAME = previousBasename;
966
+ }
915
967
  }
916
968
 
917
969
  process.on("message", async (message) => {
@@ -1378,6 +1430,8 @@ function createNodeRequestHandler(options) {
1378
1430
  );
1379
1431
  const payload = {
1380
1432
  model: resolved2.model,
1433
+ contextModel: resolved2.contextModel,
1434
+ pageModel: resolved2.pageModel,
1381
1435
  head: resolved2.head
1382
1436
  };
1383
1437
  sendRSC(res, payload, {
@@ -1400,6 +1454,7 @@ function createNodeRequestHandler(options) {
1400
1454
  } else if (ext === ".json") {
1401
1455
  res.setHeader("Content-Type", "application/json; charset=utf-8");
1402
1456
  }
1457
+ res.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate");
1403
1458
  const stream = fs2.createReadStream(filePath);
1404
1459
  stream.on("error", () => {
1405
1460
  res.statusCode = 404;
@@ -1423,6 +1478,8 @@ function createNodeRequestHandler(options) {
1423
1478
  );
1424
1479
  const initialPayload = {
1425
1480
  model: resolved.model,
1481
+ contextModel: resolved.contextModel,
1482
+ pageModel: resolved.pageModel,
1426
1483
  head: resolved.head
1427
1484
  };
1428
1485
  const initialFlightData = await renderRSCToString(initialPayload, {
@@ -0,0 +1,53 @@
1
+ "use client";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/route-slot.tsx
31
+ var route_slot_exports = {};
32
+ __export(route_slot_exports, {
33
+ RouteChildrenSlot: () => RouteChildrenSlot,
34
+ RouteChildrenSlotProvider: () => RouteChildrenSlotProvider
35
+ });
36
+ module.exports = __toCommonJS(route_slot_exports);
37
+ var import_react = __toESM(require("react"), 1);
38
+ var import_jsx_runtime = require("react/jsx-runtime");
39
+ var RouteChildrenSlotContext = import_react.default.createContext(null);
40
+ function RouteChildrenSlotProvider({
41
+ children,
42
+ page
43
+ }) {
44
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RouteChildrenSlotContext.Provider, { value: page, children });
45
+ }
46
+ function RouteChildrenSlot() {
47
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: import_react.default.useContext(RouteChildrenSlotContext) });
48
+ }
49
+ // Annotate the CommonJS export names for ESM import in node:
50
+ 0 && (module.exports = {
51
+ RouteChildrenSlot,
52
+ RouteChildrenSlotProvider
53
+ });
@@ -0,0 +1,7 @@
1
+ import type { ReactNode } from "react";
2
+
3
+ export function RouteChildrenSlotProvider(props: {
4
+ children: ReactNode;
5
+ page: ReactNode;
6
+ }): ReactNode;
7
+ export function RouteChildrenSlot(): ReactNode;
@@ -0,0 +1,19 @@
1
+ "use client";
2
+
3
+ // src/route-slot.tsx
4
+ import React from "react";
5
+ import { Fragment, jsx } from "react/jsx-runtime";
6
+ var RouteChildrenSlotContext = React.createContext(null);
7
+ function RouteChildrenSlotProvider({
8
+ children,
9
+ page
10
+ }) {
11
+ return /* @__PURE__ */ jsx(RouteChildrenSlotContext.Provider, { value: page, children });
12
+ }
13
+ function RouteChildrenSlot() {
14
+ return /* @__PURE__ */ jsx(Fragment, { children: React.useContext(RouteChildrenSlotContext) });
15
+ }
16
+ export {
17
+ RouteChildrenSlot,
18
+ RouteChildrenSlotProvider
19
+ };
package/dist/router.cjs CHANGED
@@ -40,6 +40,7 @@ module.exports = __toCommonJS(router_exports);
40
40
  var import_node_fs = __toESM(require("node:fs"), 1);
41
41
  var import_node_module = __toESM(require("node:module"), 1);
42
42
  var import_node_path = __toESM(require("node:path"), 1);
43
+ var import_route_slot = require("@webtypen/webframez-react/route-slot");
43
44
 
44
45
  // src/head.ts
45
46
  var ABSOLUTE_ASSET_URL_PATTERN = /^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;
@@ -129,6 +130,16 @@ function isRouteChildrenType(type) {
129
130
  return false;
130
131
  }
131
132
  }
133
+ function isReactElementLike(node) {
134
+ if (!node || typeof node !== "object") {
135
+ return false;
136
+ }
137
+ try {
138
+ return "type" in node && "props" in node;
139
+ } catch {
140
+ return false;
141
+ }
142
+ }
132
143
  function injectRouteChildren(node, routeChildren) {
133
144
  if (node === null || node === void 0 || typeof node === "boolean") {
134
145
  return node;
@@ -144,13 +155,17 @@ function injectRouteChildren(node, routeChildren) {
144
155
  });
145
156
  return changed ? next : node;
146
157
  }
147
- if (!import_react.default.isValidElement(node)) {
158
+ if (isReactElementLike(node) && isRouteChildrenType(node.type)) {
159
+ return routeChildren;
160
+ }
161
+ const isValidElement = import_react.default.isValidElement(node);
162
+ if (!isValidElement && !isReactElementLike(node)) {
148
163
  return node;
149
164
  }
150
- if (isRouteChildrenType(node.type)) {
165
+ if (isValidElement && isRouteChildrenType(node.type)) {
151
166
  return routeChildren;
152
167
  }
153
- const props = node.props;
168
+ const props = node.props ?? {};
154
169
  if (!("children" in props)) {
155
170
  return node;
156
171
  }
@@ -158,10 +173,19 @@ function injectRouteChildren(node, routeChildren) {
158
173
  if (nextChildren === props.children) {
159
174
  return node;
160
175
  }
161
- if (Array.isArray(nextChildren)) {
162
- return import_react.default.cloneElement(node, void 0, ...nextChildren);
176
+ if (isValidElement) {
177
+ if (Array.isArray(nextChildren)) {
178
+ return import_react.default.cloneElement(node, void 0, ...nextChildren);
179
+ }
180
+ return import_react.default.cloneElement(node, void 0, nextChildren);
163
181
  }
164
- return import_react.default.cloneElement(node, void 0, nextChildren);
182
+ const elementLike = node;
183
+ const nextProps = {
184
+ ...elementLike.props ?? {},
185
+ children: nextChildren,
186
+ ...elementLike.key !== void 0 && elementLike.key !== null ? { key: elementLike.key } : {}
187
+ };
188
+ return import_react.default.createElement(elementLike.type, nextProps);
165
189
  }
166
190
 
167
191
  // src/file-router.tsx
@@ -326,15 +350,22 @@ function mergeHead(...configs) {
326
350
  if (!config) {
327
351
  continue;
328
352
  }
353
+ const hasOwn = (key) => Object.prototype.hasOwnProperty.call(config, key);
329
354
  if (config.title) {
330
355
  merged.title = config.title;
331
356
  }
332
357
  if (config.description) {
333
358
  merged.description = config.description;
334
359
  }
335
- if (config.basename) {
360
+ if (hasOwn("basename")) {
336
361
  merged.basename = config.basename;
337
362
  }
363
+ if (hasOwn("routeBasePath")) {
364
+ merged.routeBasePath = config.routeBasePath;
365
+ }
366
+ if (hasOwn("transportBasePath")) {
367
+ merged.transportBasePath = config.transportBasePath;
368
+ }
338
369
  if (config.favicon) {
339
370
  merged.favicon = config.favicon;
340
371
  }
@@ -495,9 +526,12 @@ function createFileRouter(options) {
495
526
  const errorHead = await resolveHead(errorModule, errorProps);
496
527
  const layoutNode = layoutModule ? await layoutModule.default(context) : null;
497
528
  const model = layoutNode ? injectRouteChildren(layoutNode, errorNode) : errorNode;
529
+ const contextModel = layoutNode ? injectRouteChildren(layoutNode, /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_route_slot.RouteChildrenSlot, {})) : void 0;
498
530
  return {
499
531
  statusCode,
500
532
  model,
533
+ contextModel,
534
+ pageModel: errorNode,
501
535
  head: mergeHead(layoutHead, errorHead)
502
536
  };
503
537
  }
@@ -617,9 +651,12 @@ function createFileRouter(options) {
617
651
  const pageHead = await resolveHead(pageModule, pageContext);
618
652
  const layoutNode = layoutModule ? await layoutModule.default(pageContext) : null;
619
653
  const model = layoutNode ? injectRouteChildren(layoutNode, pageNode) : pageNode;
654
+ const contextModel = layoutNode ? injectRouteChildren(layoutNode, /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_route_slot.RouteChildrenSlot, {})) : void 0;
620
655
  return {
621
656
  statusCode: 200,
622
657
  model,
658
+ contextModel,
659
+ pageModel: pageNode,
623
660
  head: mergeHead(layoutHead, pageHead)
624
661
  };
625
662
  } catch (error) {
package/dist/router.d.ts CHANGED
@@ -5,6 +5,8 @@ export type ResolvedRoute = {
5
5
  statusCode: number;
6
6
  model: ReactNode;
7
7
  head: HeadConfig;
8
+ contextModel?: ReactNode;
9
+ pageModel?: ReactNode;
8
10
  };
9
11
 
10
12
  export function createFileRouter(options: { pagesDir: string }): {
package/dist/router.js CHANGED
@@ -10,6 +10,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
10
10
  import fs from "node:fs";
11
11
  import Module from "node:module";
12
12
  import path from "node:path";
13
+ import { RouteChildrenSlot } from "@webtypen/webframez-react/route-slot";
13
14
 
14
15
  // src/head.ts
15
16
  var ABSOLUTE_ASSET_URL_PATTERN = /^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;
@@ -99,6 +100,16 @@ function isRouteChildrenType(type) {
99
100
  return false;
100
101
  }
101
102
  }
103
+ function isReactElementLike(node) {
104
+ if (!node || typeof node !== "object") {
105
+ return false;
106
+ }
107
+ try {
108
+ return "type" in node && "props" in node;
109
+ } catch {
110
+ return false;
111
+ }
112
+ }
102
113
  function injectRouteChildren(node, routeChildren) {
103
114
  if (node === null || node === void 0 || typeof node === "boolean") {
104
115
  return node;
@@ -114,13 +125,17 @@ function injectRouteChildren(node, routeChildren) {
114
125
  });
115
126
  return changed ? next : node;
116
127
  }
117
- if (!React.isValidElement(node)) {
128
+ if (isReactElementLike(node) && isRouteChildrenType(node.type)) {
129
+ return routeChildren;
130
+ }
131
+ const isValidElement = React.isValidElement(node);
132
+ if (!isValidElement && !isReactElementLike(node)) {
118
133
  return node;
119
134
  }
120
- if (isRouteChildrenType(node.type)) {
135
+ if (isValidElement && isRouteChildrenType(node.type)) {
121
136
  return routeChildren;
122
137
  }
123
- const props = node.props;
138
+ const props = node.props ?? {};
124
139
  if (!("children" in props)) {
125
140
  return node;
126
141
  }
@@ -128,10 +143,19 @@ function injectRouteChildren(node, routeChildren) {
128
143
  if (nextChildren === props.children) {
129
144
  return node;
130
145
  }
131
- if (Array.isArray(nextChildren)) {
132
- return React.cloneElement(node, void 0, ...nextChildren);
146
+ if (isValidElement) {
147
+ if (Array.isArray(nextChildren)) {
148
+ return React.cloneElement(node, void 0, ...nextChildren);
149
+ }
150
+ return React.cloneElement(node, void 0, nextChildren);
133
151
  }
134
- return React.cloneElement(node, void 0, nextChildren);
152
+ const elementLike = node;
153
+ const nextProps = {
154
+ ...elementLike.props ?? {},
155
+ children: nextChildren,
156
+ ...elementLike.key !== void 0 && elementLike.key !== null ? { key: elementLike.key } : {}
157
+ };
158
+ return React.createElement(elementLike.type, nextProps);
135
159
  }
136
160
 
137
161
  // src/file-router.tsx
@@ -296,15 +320,22 @@ function mergeHead(...configs) {
296
320
  if (!config) {
297
321
  continue;
298
322
  }
323
+ const hasOwn = (key) => Object.prototype.hasOwnProperty.call(config, key);
299
324
  if (config.title) {
300
325
  merged.title = config.title;
301
326
  }
302
327
  if (config.description) {
303
328
  merged.description = config.description;
304
329
  }
305
- if (config.basename) {
330
+ if (hasOwn("basename")) {
306
331
  merged.basename = config.basename;
307
332
  }
333
+ if (hasOwn("routeBasePath")) {
334
+ merged.routeBasePath = config.routeBasePath;
335
+ }
336
+ if (hasOwn("transportBasePath")) {
337
+ merged.transportBasePath = config.transportBasePath;
338
+ }
308
339
  if (config.favicon) {
309
340
  merged.favicon = config.favicon;
310
341
  }
@@ -465,9 +496,12 @@ function createFileRouter(options) {
465
496
  const errorHead = await resolveHead(errorModule, errorProps);
466
497
  const layoutNode = layoutModule ? await layoutModule.default(context) : null;
467
498
  const model = layoutNode ? injectRouteChildren(layoutNode, errorNode) : errorNode;
499
+ const contextModel = layoutNode ? injectRouteChildren(layoutNode, /* @__PURE__ */ jsx(RouteChildrenSlot, {})) : void 0;
468
500
  return {
469
501
  statusCode,
470
502
  model,
503
+ contextModel,
504
+ pageModel: errorNode,
471
505
  head: mergeHead(layoutHead, errorHead)
472
506
  };
473
507
  }
@@ -587,9 +621,12 @@ function createFileRouter(options) {
587
621
  const pageHead = await resolveHead(pageModule, pageContext);
588
622
  const layoutNode = layoutModule ? await layoutModule.default(pageContext) : null;
589
623
  const model = layoutNode ? injectRouteChildren(layoutNode, pageNode) : pageNode;
624
+ const contextModel = layoutNode ? injectRouteChildren(layoutNode, /* @__PURE__ */ jsx(RouteChildrenSlot, {})) : void 0;
590
625
  return {
591
626
  statusCode: 200,
592
627
  model,
628
+ contextModel,
629
+ pageModel: pageNode,
593
630
  head: mergeHead(layoutHead, pageHead)
594
631
  };
595
632
  } catch (error) {
package/dist/types.d.ts CHANGED
@@ -61,6 +61,8 @@ export type HeadConfig = {
61
61
  title?: string;
62
62
  description?: string;
63
63
  basename?: string;
64
+ routeBasePath?: string;
65
+ transportBasePath?: string;
64
66
  favicon?: string;
65
67
  meta?: HeadMetaTag[];
66
68
  links?: HeadLinkTag[];
@@ -69,6 +71,8 @@ export type HeadConfig = {
69
71
  export type ClientNavigationPayload = {
70
72
  model: ReactNode;
71
73
  head: HeadConfig;
74
+ contextModel?: ReactNode;
75
+ pageModel?: ReactNode;
72
76
  };
73
77
 
74
78
  export type HeadResolver<TContext = RouteContext> = (
@@ -112,6 +116,7 @@ export type CreateHtmlShellOptions = {
112
116
  initialFlightData?: string;
113
117
  clientRenderMode?: "hydrate" | "mount";
114
118
  basename?: string;
119
+ routeBasePath?: string;
115
120
  liveReloadPath?: string;
116
121
  liveReloadServerId?: string;
117
122
  };