@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/client.cjs +1 -1
- package/dist/client.d.ts +1 -0
- package/dist/client.js +1 -1
- package/dist/http.cjs +66 -9
- package/dist/http.js +66 -9
- package/dist/index.cjs +66 -9
- package/dist/index.js +66 -9
- package/dist/route-slot.cjs +53 -0
- package/dist/route-slot.d.ts +7 -0
- package/dist/route-slot.js +19 -0
- package/dist/router.cjs +44 -7
- package/dist/router.d.ts +2 -0
- package/dist/router.js +44 -7
- package/dist/types.d.ts +5 -0
- package/dist/webframez-core.cjs +66 -9
- package/dist/webframez-core.js +66 -9
- package/package.json +6 -1
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 (
|
|
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 (
|
|
270
|
-
|
|
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
|
-
|
|
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 (
|
|
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
|
-
|
|
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,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 (
|
|
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 (
|
|
162
|
-
|
|
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
|
-
|
|
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 (
|
|
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
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 (
|
|
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 (
|
|
132
|
-
|
|
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
|
-
|
|
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 (
|
|
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
|
};
|