@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.
@@ -145,6 +145,7 @@ function sendRSC(res, model, options = {}) {
145
145
  } = options;
146
146
  res.statusCode = statusCode;
147
147
  res.setHeader("Content-Type", contentType);
148
+ res.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate");
148
149
  const stream = (0, import_server.renderToPipeableStream)(model, moduleMap, { onError });
149
150
  stream.pipe(res);
150
151
  return stream;
@@ -154,6 +155,7 @@ function sendRSC(res, model, options = {}) {
154
155
  var import_node_fs = __toESM(require("node:fs"), 1);
155
156
  var import_node_module2 = __toESM(require("node:module"), 1);
156
157
  var import_node_path2 = __toESM(require("node:path"), 1);
158
+ var import_route_slot = require("@webtypen/webframez-react/route-slot");
157
159
 
158
160
  // src/head.ts
159
161
  var ABSOLUTE_ASSET_URL_PATTERN = /^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;
@@ -243,6 +245,16 @@ function isRouteChildrenType(type) {
243
245
  return false;
244
246
  }
245
247
  }
248
+ function isReactElementLike(node) {
249
+ if (!node || typeof node !== "object") {
250
+ return false;
251
+ }
252
+ try {
253
+ return "type" in node && "props" in node;
254
+ } catch {
255
+ return false;
256
+ }
257
+ }
246
258
  function injectRouteChildren(node, routeChildren) {
247
259
  if (node === null || node === void 0 || typeof node === "boolean") {
248
260
  return node;
@@ -258,13 +270,17 @@ function injectRouteChildren(node, routeChildren) {
258
270
  });
259
271
  return changed ? next : node;
260
272
  }
261
- if (!import_react.default.isValidElement(node)) {
273
+ if (isReactElementLike(node) && isRouteChildrenType(node.type)) {
274
+ return routeChildren;
275
+ }
276
+ const isValidElement = import_react.default.isValidElement(node);
277
+ if (!isValidElement && !isReactElementLike(node)) {
262
278
  return node;
263
279
  }
264
- if (isRouteChildrenType(node.type)) {
280
+ if (isValidElement && isRouteChildrenType(node.type)) {
265
281
  return routeChildren;
266
282
  }
267
- const props = node.props;
283
+ const props = node.props ?? {};
268
284
  if (!("children" in props)) {
269
285
  return node;
270
286
  }
@@ -272,10 +288,19 @@ function injectRouteChildren(node, routeChildren) {
272
288
  if (nextChildren === props.children) {
273
289
  return node;
274
290
  }
275
- if (Array.isArray(nextChildren)) {
276
- return import_react.default.cloneElement(node, void 0, ...nextChildren);
291
+ if (isValidElement) {
292
+ if (Array.isArray(nextChildren)) {
293
+ return import_react.default.cloneElement(node, void 0, ...nextChildren);
294
+ }
295
+ return import_react.default.cloneElement(node, void 0, nextChildren);
277
296
  }
278
- return import_react.default.cloneElement(node, void 0, nextChildren);
297
+ const elementLike = node;
298
+ const nextProps = {
299
+ ...elementLike.props ?? {},
300
+ children: nextChildren,
301
+ ...elementLike.key !== void 0 && elementLike.key !== null ? { key: elementLike.key } : {}
302
+ };
303
+ return import_react.default.createElement(elementLike.type, nextProps);
279
304
  }
280
305
 
281
306
  // src/file-router.tsx
@@ -440,15 +465,22 @@ function mergeHead(...configs) {
440
465
  if (!config) {
441
466
  continue;
442
467
  }
468
+ const hasOwn = (key) => Object.prototype.hasOwnProperty.call(config, key);
443
469
  if (config.title) {
444
470
  merged.title = config.title;
445
471
  }
446
472
  if (config.description) {
447
473
  merged.description = config.description;
448
474
  }
449
- if (config.basename) {
475
+ if (hasOwn("basename")) {
450
476
  merged.basename = config.basename;
451
477
  }
478
+ if (hasOwn("routeBasePath")) {
479
+ merged.routeBasePath = config.routeBasePath;
480
+ }
481
+ if (hasOwn("transportBasePath")) {
482
+ merged.transportBasePath = config.transportBasePath;
483
+ }
452
484
  if (config.favicon) {
453
485
  merged.favicon = config.favicon;
454
486
  }
@@ -609,9 +641,12 @@ function createFileRouter(options) {
609
641
  const errorHead = await resolveHead(errorModule, errorProps);
610
642
  const layoutNode = layoutModule ? await layoutModule.default(context) : null;
611
643
  const model = layoutNode ? injectRouteChildren(layoutNode, errorNode) : errorNode;
644
+ const contextModel = layoutNode ? injectRouteChildren(layoutNode, /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_route_slot.RouteChildrenSlot, {})) : void 0;
612
645
  return {
613
646
  statusCode,
614
647
  model,
648
+ contextModel,
649
+ pageModel: errorNode,
615
650
  head: mergeHead(layoutHead, errorHead)
616
651
  };
617
652
  }
@@ -731,9 +766,12 @@ function createFileRouter(options) {
731
766
  const pageHead = await resolveHead(pageModule, pageContext);
732
767
  const layoutNode = layoutModule ? await layoutModule.default(pageContext) : null;
733
768
  const model = layoutNode ? injectRouteChildren(layoutNode, pageNode) : pageNode;
769
+ const contextModel = layoutNode ? injectRouteChildren(layoutNode, /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_route_slot.RouteChildrenSlot, {})) : void 0;
734
770
  return {
735
771
  statusCode: 200,
736
772
  model,
773
+ contextModel,
774
+ pageModel: pageNode,
737
775
  head: mergeHead(layoutHead, pageHead)
738
776
  };
739
777
  } catch (error) {
@@ -888,7 +926,7 @@ async function decodeFlightPayloadFromString(flightData, moduleMap) {
888
926
 
889
927
  if (typeof reactServerDomClientNode.createFromNodeStream === "function") {
890
928
  return await reactServerDomClientNode.createFromNodeStream(
891
- Readable.from([flightData]),
929
+ Readable.from([Buffer.from(flightData)]),
892
930
  serverConsumerManifest
893
931
  );
894
932
  }
@@ -913,7 +951,21 @@ async function renderHtmlFromFlightData(flightData, moduleMap) {
913
951
  ? payload.model
914
952
  : payload;
915
953
 
916
- return renderHtml(model);
954
+ const basename =
955
+ payload &&
956
+ typeof payload === "object" &&
957
+ payload.head &&
958
+ typeof payload.head.basename === "string"
959
+ ? payload.head.basename
960
+ : "";
961
+
962
+ const previousBasename = globalThis.__RSC_BASENAME;
963
+ globalThis.__RSC_BASENAME = basename;
964
+ try {
965
+ return await renderHtml(model);
966
+ } finally {
967
+ globalThis.__RSC_BASENAME = previousBasename;
968
+ }
917
969
  }
918
970
 
919
971
  process.on("message", async (message) => {
@@ -1380,6 +1432,8 @@ function createNodeRequestHandler(options) {
1380
1432
  );
1381
1433
  const payload = {
1382
1434
  model: resolved2.model,
1435
+ contextModel: resolved2.contextModel,
1436
+ pageModel: resolved2.pageModel,
1383
1437
  head: resolved2.head
1384
1438
  };
1385
1439
  sendRSC(res, payload, {
@@ -1402,6 +1456,7 @@ function createNodeRequestHandler(options) {
1402
1456
  } else if (ext === ".json") {
1403
1457
  res.setHeader("Content-Type", "application/json; charset=utf-8");
1404
1458
  }
1459
+ res.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate");
1405
1460
  const stream = import_node_fs2.default.createReadStream(filePath);
1406
1461
  stream.on("error", () => {
1407
1462
  res.statusCode = 404;
@@ -1425,6 +1480,8 @@ function createNodeRequestHandler(options) {
1425
1480
  );
1426
1481
  const initialPayload = {
1427
1482
  model: resolved.model,
1483
+ contextModel: resolved.contextModel,
1484
+ pageModel: resolved.pageModel,
1428
1485
  head: resolved.head
1429
1486
  };
1430
1487
  const initialFlightData = await renderRSCToString(initialPayload, {
@@ -117,6 +117,7 @@ function sendRSC(res, model, options = {}) {
117
117
  } = options;
118
118
  res.statusCode = statusCode;
119
119
  res.setHeader("Content-Type", contentType);
120
+ res.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate");
120
121
  const stream = renderToPipeableStream(model, moduleMap, { onError });
121
122
  stream.pipe(res);
122
123
  return stream;
@@ -126,6 +127,7 @@ function sendRSC(res, model, options = {}) {
126
127
  import fs from "node:fs";
127
128
  import Module from "node:module";
128
129
  import path2 from "node:path";
130
+ import { RouteChildrenSlot } from "@webtypen/webframez-react/route-slot";
129
131
 
130
132
  // src/head.ts
131
133
  var ABSOLUTE_ASSET_URL_PATTERN = /^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;
@@ -215,6 +217,16 @@ function isRouteChildrenType(type) {
215
217
  return false;
216
218
  }
217
219
  }
220
+ function isReactElementLike(node) {
221
+ if (!node || typeof node !== "object") {
222
+ return false;
223
+ }
224
+ try {
225
+ return "type" in node && "props" in node;
226
+ } catch {
227
+ return false;
228
+ }
229
+ }
218
230
  function injectRouteChildren(node, routeChildren) {
219
231
  if (node === null || node === void 0 || typeof node === "boolean") {
220
232
  return node;
@@ -230,13 +242,17 @@ function injectRouteChildren(node, routeChildren) {
230
242
  });
231
243
  return changed ? next : node;
232
244
  }
233
- if (!React.isValidElement(node)) {
245
+ if (isReactElementLike(node) && isRouteChildrenType(node.type)) {
246
+ return routeChildren;
247
+ }
248
+ const isValidElement = React.isValidElement(node);
249
+ if (!isValidElement && !isReactElementLike(node)) {
234
250
  return node;
235
251
  }
236
- if (isRouteChildrenType(node.type)) {
252
+ if (isValidElement && isRouteChildrenType(node.type)) {
237
253
  return routeChildren;
238
254
  }
239
- const props = node.props;
255
+ const props = node.props ?? {};
240
256
  if (!("children" in props)) {
241
257
  return node;
242
258
  }
@@ -244,10 +260,19 @@ function injectRouteChildren(node, routeChildren) {
244
260
  if (nextChildren === props.children) {
245
261
  return node;
246
262
  }
247
- if (Array.isArray(nextChildren)) {
248
- return React.cloneElement(node, void 0, ...nextChildren);
263
+ if (isValidElement) {
264
+ if (Array.isArray(nextChildren)) {
265
+ return React.cloneElement(node, void 0, ...nextChildren);
266
+ }
267
+ return React.cloneElement(node, void 0, nextChildren);
249
268
  }
250
- return React.cloneElement(node, void 0, nextChildren);
269
+ const elementLike = node;
270
+ const nextProps = {
271
+ ...elementLike.props ?? {},
272
+ children: nextChildren,
273
+ ...elementLike.key !== void 0 && elementLike.key !== null ? { key: elementLike.key } : {}
274
+ };
275
+ return React.createElement(elementLike.type, nextProps);
251
276
  }
252
277
 
253
278
  // src/file-router.tsx
@@ -412,15 +437,22 @@ function mergeHead(...configs) {
412
437
  if (!config) {
413
438
  continue;
414
439
  }
440
+ const hasOwn = (key) => Object.prototype.hasOwnProperty.call(config, key);
415
441
  if (config.title) {
416
442
  merged.title = config.title;
417
443
  }
418
444
  if (config.description) {
419
445
  merged.description = config.description;
420
446
  }
421
- if (config.basename) {
447
+ if (hasOwn("basename")) {
422
448
  merged.basename = config.basename;
423
449
  }
450
+ if (hasOwn("routeBasePath")) {
451
+ merged.routeBasePath = config.routeBasePath;
452
+ }
453
+ if (hasOwn("transportBasePath")) {
454
+ merged.transportBasePath = config.transportBasePath;
455
+ }
424
456
  if (config.favicon) {
425
457
  merged.favicon = config.favicon;
426
458
  }
@@ -581,9 +613,12 @@ function createFileRouter(options) {
581
613
  const errorHead = await resolveHead(errorModule, errorProps);
582
614
  const layoutNode = layoutModule ? await layoutModule.default(context) : null;
583
615
  const model = layoutNode ? injectRouteChildren(layoutNode, errorNode) : errorNode;
616
+ const contextModel = layoutNode ? injectRouteChildren(layoutNode, /* @__PURE__ */ jsx(RouteChildrenSlot, {})) : void 0;
584
617
  return {
585
618
  statusCode,
586
619
  model,
620
+ contextModel,
621
+ pageModel: errorNode,
587
622
  head: mergeHead(layoutHead, errorHead)
588
623
  };
589
624
  }
@@ -703,9 +738,12 @@ function createFileRouter(options) {
703
738
  const pageHead = await resolveHead(pageModule, pageContext);
704
739
  const layoutNode = layoutModule ? await layoutModule.default(pageContext) : null;
705
740
  const model = layoutNode ? injectRouteChildren(layoutNode, pageNode) : pageNode;
741
+ const contextModel = layoutNode ? injectRouteChildren(layoutNode, /* @__PURE__ */ jsx(RouteChildrenSlot, {})) : void 0;
706
742
  return {
707
743
  statusCode: 200,
708
744
  model,
745
+ contextModel,
746
+ pageModel: pageNode,
709
747
  head: mergeHead(layoutHead, pageHead)
710
748
  };
711
749
  } catch (error) {
@@ -860,7 +898,7 @@ async function decodeFlightPayloadFromString(flightData, moduleMap) {
860
898
 
861
899
  if (typeof reactServerDomClientNode.createFromNodeStream === "function") {
862
900
  return await reactServerDomClientNode.createFromNodeStream(
863
- Readable.from([flightData]),
901
+ Readable.from([Buffer.from(flightData)]),
864
902
  serverConsumerManifest
865
903
  );
866
904
  }
@@ -885,7 +923,21 @@ async function renderHtmlFromFlightData(flightData, moduleMap) {
885
923
  ? payload.model
886
924
  : payload;
887
925
 
888
- return renderHtml(model);
926
+ const basename =
927
+ payload &&
928
+ typeof payload === "object" &&
929
+ payload.head &&
930
+ typeof payload.head.basename === "string"
931
+ ? payload.head.basename
932
+ : "";
933
+
934
+ const previousBasename = globalThis.__RSC_BASENAME;
935
+ globalThis.__RSC_BASENAME = basename;
936
+ try {
937
+ return await renderHtml(model);
938
+ } finally {
939
+ globalThis.__RSC_BASENAME = previousBasename;
940
+ }
889
941
  }
890
942
 
891
943
  process.on("message", async (message) => {
@@ -1352,6 +1404,8 @@ function createNodeRequestHandler(options) {
1352
1404
  );
1353
1405
  const payload = {
1354
1406
  model: resolved2.model,
1407
+ contextModel: resolved2.contextModel,
1408
+ pageModel: resolved2.pageModel,
1355
1409
  head: resolved2.head
1356
1410
  };
1357
1411
  sendRSC(res, payload, {
@@ -1374,6 +1428,7 @@ function createNodeRequestHandler(options) {
1374
1428
  } else if (ext === ".json") {
1375
1429
  res.setHeader("Content-Type", "application/json; charset=utf-8");
1376
1430
  }
1431
+ res.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate");
1377
1432
  const stream = fs2.createReadStream(filePath);
1378
1433
  stream.on("error", () => {
1379
1434
  res.statusCode = 404;
@@ -1397,6 +1452,8 @@ function createNodeRequestHandler(options) {
1397
1452
  );
1398
1453
  const initialPayload = {
1399
1454
  model: resolved.model,
1455
+ contextModel: resolved.contextModel,
1456
+ pageModel: resolved.pageModel,
1400
1457
  head: resolved.head
1401
1458
  };
1402
1459
  const initialFlightData = await renderRSCToString(initialPayload, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webtypen/webframez-react",
3
- "version": "0.0.31",
3
+ "version": "0.0.33",
4
4
  "description": "TypeScript React RSC addition for @webtypen/webframez-core",
5
5
  "homepage": "https://webtypen.de/",
6
6
  "author": {
@@ -43,6 +43,11 @@
43
43
  "import": "./dist/navigation.js",
44
44
  "require": "./dist/navigation.cjs"
45
45
  },
46
+ "./route-slot": {
47
+ "types": "./dist/route-slot.d.ts",
48
+ "import": "./dist/route-slot.js",
49
+ "require": "./dist/route-slot.cjs"
50
+ },
46
51
  "./types": {
47
52
  "types": "./dist/types.d.ts",
48
53
  "import": "./dist/types.js",