@farm.js/plugin 0.1.0-beta.7 → 0.1.0-beta.71
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/dev-static.d.ts +8 -0
- package/dist/dev-static.d.ts.map +1 -0
- package/dist/dev-static.js +37 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/middleware/index.d.ts.map +1 -1
- package/dist/middleware/index.js +9 -53
- package/dist/middleware/matching.d.ts +29 -0
- package/dist/middleware/matching.d.ts.map +1 -0
- package/dist/middleware/matching.js +79 -0
- package/dist/rsc/automatic-optimized-boundary.d.ts +11 -0
- package/dist/rsc/automatic-optimized-boundary.d.ts.map +1 -0
- package/dist/rsc/automatic-optimized-boundary.js +162 -0
- package/dist/rsc/entries/client.d.ts +1 -0
- package/dist/rsc/entries/client.d.ts.map +1 -1
- package/dist/rsc/entries/client.js +33 -3
- package/dist/rsc/entries/rsc.d.ts.map +1 -1
- package/dist/rsc/entries/rsc.js +17 -9
- package/dist/rsc/index.d.ts +3 -2
- package/dist/rsc/index.d.ts.map +1 -1
- package/dist/rsc/index.js +49 -6
- package/dist/rsc/nitro-build.d.ts.map +1 -1
- package/dist/rsc/nitro-build.js +9 -1
- package/dist/rsc/optimized-boundary.d.ts +9 -1
- package/dist/rsc/optimized-boundary.d.ts.map +1 -1
- package/dist/rsc/optimized-boundary.js +229 -1
- package/dist/rsc/route-action-transform.d.ts +11 -0
- package/dist/rsc/route-action-transform.d.ts.map +1 -0
- package/dist/rsc/route-action-transform.js +369 -0
- package/package.json +4 -4
package/dist/rsc/index.js
CHANGED
|
@@ -26,12 +26,15 @@ import { init as initModuleLexer, parse as parseModuleImports } from "es-module-
|
|
|
26
26
|
import { farmEnvironmentFunctionsPlugin } from "@farm.js/core/environment/vite";
|
|
27
27
|
import { generateRscEntry } from "./entries/rsc.js";
|
|
28
28
|
import { generateSsrEntry } from "./entries/ssr.js";
|
|
29
|
-
import { generateClientEntry } from "./entries/client.js";
|
|
29
|
+
import { generateClientEntry, serverFnTransportErrorClientRuntime } from "./entries/client.js";
|
|
30
|
+
import { transformFarmRouteActionClients } from "./route-action-transform.js";
|
|
30
31
|
import { transformFarmServerFns } from "./server-fn-transform.js";
|
|
32
|
+
import { transformAutomaticOptimizedBoundaries } from "./automatic-optimized-boundary.js";
|
|
31
33
|
import { resolveRscBuildOutputPath } from "./build-paths.js";
|
|
32
34
|
import { assertRscPackageCompatibility } from "./compatibility.js";
|
|
33
35
|
import fs from "fs/promises";
|
|
34
36
|
import path from "path";
|
|
37
|
+
import { devServableFileExists } from "../dev-static.js";
|
|
35
38
|
import { pathToFileURL } from "node:url";
|
|
36
39
|
import { createRequire } from "node:module";
|
|
37
40
|
// Use API and middleware plugins from @farm.js/core (require so CJS build resolves when ESM .mjs is missing)
|
|
@@ -40,6 +43,7 @@ const { farmApiPlugin, farmMiddlewarePlugin } = require_("@farm.js/core");
|
|
|
40
43
|
const { resolveServerActionsConfig } = require_("@farm.js/core/server-action-security");
|
|
41
44
|
const { normalizeFarmDeploymentId } = require_("@farm.js/core/deployment");
|
|
42
45
|
const { getFarmLayerAliases, getFarmSourceRoots, resolveFarmLayers } = require_("@farm.js/core/server");
|
|
46
|
+
const { searchParamsToObject } = require_("@farm.js/core/internal/production-runtime");
|
|
43
47
|
export { buildRscNitro, waitForRscManifest, waitForRscOutputs } from "./nitro-build.js";
|
|
44
48
|
import { registerRscNitroRuntimePackage } from "./nitro-build.js";
|
|
45
49
|
export { default as nitro } from "./vite-plugin-nitro.js";
|
|
@@ -710,6 +714,42 @@ export default function farmRsc(options = {}) {
|
|
|
710
714
|
return null;
|
|
711
715
|
},
|
|
712
716
|
},
|
|
717
|
+
{
|
|
718
|
+
name: "@farm.js/plugin/rsc:automatic-optimized-boundary",
|
|
719
|
+
enforce: "post",
|
|
720
|
+
transform(code, id) {
|
|
721
|
+
if (!rscEnabled || !optimizedBoundaryEnabled)
|
|
722
|
+
return null;
|
|
723
|
+
const environmentName = this.environment?.name;
|
|
724
|
+
if (environmentName !== "rsc")
|
|
725
|
+
return null;
|
|
726
|
+
const result = transformAutomaticOptimizedBoundaries(code, id);
|
|
727
|
+
if (!result)
|
|
728
|
+
return null;
|
|
729
|
+
if (debug) {
|
|
730
|
+
console.log(`[Farm.js] Added ${result.boundaryCount} automatic optimized-boundary candidate${result.boundaryCount === 1 ? "" : "s"} in ${id}`);
|
|
731
|
+
}
|
|
732
|
+
return { code: result.code, map: null };
|
|
733
|
+
},
|
|
734
|
+
},
|
|
735
|
+
{
|
|
736
|
+
name: "@farm.js/plugin/rsc:route-action-clients",
|
|
737
|
+
enforce: "pre",
|
|
738
|
+
transform(code, id) {
|
|
739
|
+
if (!rscEnabled || !actionsEnabled)
|
|
740
|
+
return null;
|
|
741
|
+
const environmentName = this.environment?.name;
|
|
742
|
+
if (environmentName !== "client")
|
|
743
|
+
return null;
|
|
744
|
+
const result = transformFarmRouteActionClients(code, id);
|
|
745
|
+
if (!result)
|
|
746
|
+
return null;
|
|
747
|
+
return {
|
|
748
|
+
code: result.code,
|
|
749
|
+
map: null,
|
|
750
|
+
};
|
|
751
|
+
},
|
|
752
|
+
},
|
|
713
753
|
{
|
|
714
754
|
name: "@farm.js/plugin/rsc:server-fn-actions",
|
|
715
755
|
enforce: "pre",
|
|
@@ -829,6 +869,7 @@ import {
|
|
|
829
869
|
createFarmDeploymentRequestHeaders,
|
|
830
870
|
isFarmDeploymentMismatchResponse,
|
|
831
871
|
} from '@farm.js/core/deployment';
|
|
872
|
+
${serverFnTransportErrorClientRuntime}
|
|
832
873
|
const farmDeploymentId = ${JSON.stringify(entryContext.deploymentId)};
|
|
833
874
|
setServerCallback(async (id, args) => {
|
|
834
875
|
const refs = createTemporaryReferenceSet();
|
|
@@ -855,9 +896,7 @@ setServerCallback(async (id, args) => {
|
|
|
855
896
|
if (!res.ok) throw new Error('Server action failed: ' + res.status);
|
|
856
897
|
const p = await createFromReadableStream(res.body, { temporaryReferences: refs });
|
|
857
898
|
if (p?.returnValue?.ok) return p.returnValue.data;
|
|
858
|
-
|
|
859
|
-
error.name = 'ServerActionError';
|
|
860
|
-
throw error;
|
|
899
|
+
throw createFarmServerFnTransportError(p?.returnValue?.data);
|
|
861
900
|
});
|
|
862
901
|
`
|
|
863
902
|
: "";
|
|
@@ -925,12 +964,16 @@ if (document.readyState === 'loading') {
|
|
|
925
964
|
const url = req.url || "/";
|
|
926
965
|
const pathname = url.split("?")[0];
|
|
927
966
|
const method = req.method || "GET";
|
|
967
|
+
// Dotted paths only skip RSC rendering when they map to a real
|
|
968
|
+
// file on disk — route segments may legitimately contain dots.
|
|
928
969
|
if (pathname.startsWith("/@") ||
|
|
929
970
|
pathname.startsWith("/__") ||
|
|
930
971
|
pathname.startsWith("/node_modules") ||
|
|
931
972
|
pathname.startsWith("/src/") ||
|
|
932
973
|
pathname.startsWith("/api/") ||
|
|
933
|
-
(pathname.includes(".") &&
|
|
974
|
+
(pathname.includes(".") &&
|
|
975
|
+
!pathname.endsWith("/") &&
|
|
976
|
+
devServableFileExists(pathname, [server.config.publicDir, server.config.root]))) {
|
|
934
977
|
return next();
|
|
935
978
|
}
|
|
936
979
|
const startTime = Date.now();
|
|
@@ -1112,7 +1155,7 @@ if (document.readyState === 'loading') {
|
|
|
1112
1155
|
const Layout = layoutModule?.default;
|
|
1113
1156
|
// Parse URL params (basic dynamic route support)
|
|
1114
1157
|
const params = {};
|
|
1115
|
-
const searchParams =
|
|
1158
|
+
const searchParams = searchParamsToObject(new URL(url, `http://${req.headers.host || "localhost:3000"}`).searchParams);
|
|
1116
1159
|
// Render the page with middleware data
|
|
1117
1160
|
const pageProps = {
|
|
1118
1161
|
params,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nitro-build.d.ts","sourceRoot":"","sources":["../../src/rsc/nitro-build.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAwBH;;;GAGG;AACH,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,IAAI,CAKN;AAwFD;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GACxD,OAAO,CAAC,IAAI,CAAC,CA0Bf;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GACxD,OAAO,CAAC,IAAI,CAAC,CAgCf;AA+DD,MAAM,MAAM,oBAAoB,GAAG;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,wBAAsB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"nitro-build.d.ts","sourceRoot":"","sources":["../../src/rsc/nitro-build.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAwBH;;;GAGG;AACH,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,IAAI,CAKN;AAwFD;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GACxD,OAAO,CAAC,IAAI,CAAC,CA0Bf;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GACxD,OAAO,CAAC,IAAI,CAAC,CAgCf;AA+DD,MAAM,MAAM,oBAAoB,GAAG;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,wBAAsB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CA8MhF"}
|
package/dist/rsc/nitro-build.js
CHANGED
|
@@ -271,7 +271,15 @@ export async function buildRscNitro(options) {
|
|
|
271
271
|
},
|
|
272
272
|
// Externalize rsc/ssr so we don't bundle (they reference Vite-generated manifest). We copy dist into server output after build.
|
|
273
273
|
rollupConfig: {
|
|
274
|
-
external: (id) =>
|
|
274
|
+
external: (id) => {
|
|
275
|
+
// Ids reach this predicate in both separator forms on Windows, and matching
|
|
276
|
+
// only the POSIX one makes the same module external in one pass and not in
|
|
277
|
+
// the next, which Rollup rejects.
|
|
278
|
+
const normalized = id.split("\\").join("/");
|
|
279
|
+
return (normalized.includes("../dist/") ||
|
|
280
|
+
normalized.includes("dist/rsc") ||
|
|
281
|
+
normalized.includes("dist/ssr"));
|
|
282
|
+
},
|
|
275
283
|
},
|
|
276
284
|
compatibilityDate: "2024-12-01",
|
|
277
285
|
minify: true,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type RenderOptions, type StrataDocument } from "@farming-labs/strata";
|
|
2
2
|
import { type StaticFragmentBoundary, type StaticFragmentProps } from "@farming-labs/strata/react-server";
|
|
3
|
-
import type
|
|
3
|
+
import { type ReactElement } from "react";
|
|
4
4
|
export type { RenderOptions, StrataDocument, StrataElement, StrataNode, StrataTag, StrataText, } from "@farming-labs/strata";
|
|
5
5
|
export interface OptimizedBoundaryProps extends Omit<StaticFragmentProps, "content"> {
|
|
6
6
|
/**
|
|
@@ -10,6 +10,14 @@ export interface OptimizedBoundaryProps extends Omit<StaticFragmentProps, "conte
|
|
|
10
10
|
document: StrataDocument;
|
|
11
11
|
renderOptions?: RenderOptions;
|
|
12
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* Internal compiler target for automatic optimized boundaries. This helper is
|
|
15
|
+
* deliberately fail-open: any unsupported or unsafe tree returns the original
|
|
16
|
+
* React element unchanged.
|
|
17
|
+
*
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
export declare function _optimizeBoundary(element: ReactElement): ReactElement;
|
|
13
21
|
/**
|
|
14
22
|
* Render a typed host-only document with the optimized native runtime and
|
|
15
23
|
* place it inside an opaque React-owned boundary.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"optimized-boundary.d.ts","sourceRoot":"","sources":["../../src/rsc/optimized-boundary.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"optimized-boundary.d.ts","sourceRoot":"","sources":["../../src/rsc/optimized-boundary.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,cAAc,EAIpB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAEL,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACzB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAA2C,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AAEnF,YAAY,EACV,aAAa,EACb,cAAc,EACd,aAAa,EACb,UAAU,EACV,SAAS,EACT,UAAU,GACX,MAAM,sBAAsB,CAAC;AAE9B,MAAM,WAAW,sBAAuB,SAAQ,IAAI,CAAC,mBAAmB,EAAE,SAAS,CAAC;IAClF;;;OAGG;IACH,QAAQ,EAAE,cAAc,CAAC;IACzB,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAiND;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,YAAY,GAAG,YAAY,CAsBrE;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,EACR,aAAa,EACb,GAAG,KAAK,EACT,EAAE,sBAAsB,GAAG,YAAY,CAMvC;AAED,MAAM,MAAM,oBAAoB,GAAG,sBAAsB,CAAC"}
|
|
@@ -1,5 +1,233 @@
|
|
|
1
|
-
import { render } from "@farming-labs/strata";
|
|
1
|
+
import { render, } from "@farming-labs/strata";
|
|
2
2
|
import { StaticFragment, } from "@farming-labs/strata/react-server";
|
|
3
|
+
import { createElement, Fragment, isValidElement } from "react";
|
|
4
|
+
const AUTOMATIC_MIN_NODES = 8;
|
|
5
|
+
const AUTOMATIC_MIN_BYTES = 256;
|
|
6
|
+
const AUTOMATIC_BOUNDARIES = new Set([
|
|
7
|
+
"article",
|
|
8
|
+
"aside",
|
|
9
|
+
"div",
|
|
10
|
+
"footer",
|
|
11
|
+
"header",
|
|
12
|
+
"main",
|
|
13
|
+
"nav",
|
|
14
|
+
"section",
|
|
15
|
+
"span",
|
|
16
|
+
]);
|
|
17
|
+
const STRATA_TAGS = new Set([
|
|
18
|
+
"a",
|
|
19
|
+
"abbr",
|
|
20
|
+
"address",
|
|
21
|
+
"article",
|
|
22
|
+
"aside",
|
|
23
|
+
"b",
|
|
24
|
+
"blockquote",
|
|
25
|
+
"br",
|
|
26
|
+
"caption",
|
|
27
|
+
"cite",
|
|
28
|
+
"code",
|
|
29
|
+
"col",
|
|
30
|
+
"colgroup",
|
|
31
|
+
"dd",
|
|
32
|
+
"del",
|
|
33
|
+
"details",
|
|
34
|
+
"dfn",
|
|
35
|
+
"div",
|
|
36
|
+
"dl",
|
|
37
|
+
"dt",
|
|
38
|
+
"em",
|
|
39
|
+
"figcaption",
|
|
40
|
+
"figure",
|
|
41
|
+
"footer",
|
|
42
|
+
"h1",
|
|
43
|
+
"h2",
|
|
44
|
+
"h3",
|
|
45
|
+
"h4",
|
|
46
|
+
"h5",
|
|
47
|
+
"h6",
|
|
48
|
+
"header",
|
|
49
|
+
"hr",
|
|
50
|
+
"i",
|
|
51
|
+
"img",
|
|
52
|
+
"ins",
|
|
53
|
+
"kbd",
|
|
54
|
+
"li",
|
|
55
|
+
"main",
|
|
56
|
+
"mark",
|
|
57
|
+
"nav",
|
|
58
|
+
"ol",
|
|
59
|
+
"p",
|
|
60
|
+
"pre",
|
|
61
|
+
"q",
|
|
62
|
+
"s",
|
|
63
|
+
"samp",
|
|
64
|
+
"section",
|
|
65
|
+
"small",
|
|
66
|
+
"span",
|
|
67
|
+
"strong",
|
|
68
|
+
"sub",
|
|
69
|
+
"summary",
|
|
70
|
+
"sup",
|
|
71
|
+
"table",
|
|
72
|
+
"tbody",
|
|
73
|
+
"td",
|
|
74
|
+
"tfoot",
|
|
75
|
+
"th",
|
|
76
|
+
"thead",
|
|
77
|
+
"time",
|
|
78
|
+
"tr",
|
|
79
|
+
"u",
|
|
80
|
+
"ul",
|
|
81
|
+
"var",
|
|
82
|
+
"wbr",
|
|
83
|
+
]);
|
|
84
|
+
const BOOLEAN_ATTRIBUTES = new Set(["hidden", "reversed"]);
|
|
85
|
+
const ATTRIBUTE_NAMES = {
|
|
86
|
+
className: "class",
|
|
87
|
+
colSpan: "colspan",
|
|
88
|
+
dateTime: "datetime",
|
|
89
|
+
rowSpan: "rowspan",
|
|
90
|
+
};
|
|
91
|
+
function AutomaticOptimizedBoundary({ document, fallback, ...props }) {
|
|
92
|
+
let content;
|
|
93
|
+
try {
|
|
94
|
+
content = render(document);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return fallback;
|
|
98
|
+
}
|
|
99
|
+
if (content.nodeCount < AUTOMATIC_MIN_NODES && content.bytes < AUTOMATIC_MIN_BYTES) {
|
|
100
|
+
return fallback;
|
|
101
|
+
}
|
|
102
|
+
return StaticFragment({ ...props, content });
|
|
103
|
+
}
|
|
104
|
+
function attributeValue(name, value) {
|
|
105
|
+
if (value === null || value === undefined)
|
|
106
|
+
return undefined;
|
|
107
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "bigint") {
|
|
108
|
+
return String(value);
|
|
109
|
+
}
|
|
110
|
+
if (typeof value !== "boolean")
|
|
111
|
+
return null;
|
|
112
|
+
if (name.startsWith("aria-") || name.startsWith("data-"))
|
|
113
|
+
return String(value);
|
|
114
|
+
if (BOOLEAN_ATTRIBUTES.has(name))
|
|
115
|
+
return value ? "" : undefined;
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
function convertAttributes(tag, props) {
|
|
119
|
+
const attributes = {};
|
|
120
|
+
for (const [reactName, rawValue] of Object.entries(props)) {
|
|
121
|
+
if (reactName === "children")
|
|
122
|
+
continue;
|
|
123
|
+
if (reactName === "dangerouslySetInnerHTML" ||
|
|
124
|
+
reactName === "ref" ||
|
|
125
|
+
reactName === "style" ||
|
|
126
|
+
reactName === "suppressHydrationWarning" ||
|
|
127
|
+
/^on[A-Z]/.test(reactName)) {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
const name = ATTRIBUTE_NAMES[reactName] || reactName;
|
|
131
|
+
const value = attributeValue(name, rawValue);
|
|
132
|
+
if (value === null)
|
|
133
|
+
return null;
|
|
134
|
+
if (value !== undefined)
|
|
135
|
+
attributes[name] = value;
|
|
136
|
+
}
|
|
137
|
+
return Object.keys(attributes).length > 0 ? attributes : {};
|
|
138
|
+
}
|
|
139
|
+
function automaticDocumentFromElement(element) {
|
|
140
|
+
const rootProps = element.props;
|
|
141
|
+
const children = [];
|
|
142
|
+
if (!appendStrataNodes(rootProps.children, children))
|
|
143
|
+
return null;
|
|
144
|
+
return { type: "document", ...(children.length > 0 ? { children } : {}) };
|
|
145
|
+
}
|
|
146
|
+
function appendStrataNodes(value, output) {
|
|
147
|
+
if (value === null || value === undefined || typeof value === "boolean")
|
|
148
|
+
return true;
|
|
149
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "bigint") {
|
|
150
|
+
output.push({ type: "text", value: String(value) });
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
if (Array.isArray(value)) {
|
|
154
|
+
for (const child of value) {
|
|
155
|
+
if (!appendStrataNodes(child, output))
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
if (!isValidElement(value))
|
|
161
|
+
return false;
|
|
162
|
+
const element = value;
|
|
163
|
+
const props = element.props;
|
|
164
|
+
if (element.type === Fragment)
|
|
165
|
+
return appendStrataNodes(props.children, output);
|
|
166
|
+
if (element.type === OptimizedBoundary || element.type === AutomaticOptimizedBoundary) {
|
|
167
|
+
const boundary = props.as ?? "div";
|
|
168
|
+
if (typeof boundary !== "string" || !STRATA_TAGS.has(boundary))
|
|
169
|
+
return false;
|
|
170
|
+
const { as: _as, document: _document, fallback: _fallback, ...boundaryProps } = props;
|
|
171
|
+
const attributes = convertAttributes(boundary, boundaryProps);
|
|
172
|
+
if (!attributes)
|
|
173
|
+
return false;
|
|
174
|
+
const document = props.document;
|
|
175
|
+
if (!document || document.type !== "document")
|
|
176
|
+
return false;
|
|
177
|
+
output.push({
|
|
178
|
+
type: "element",
|
|
179
|
+
tag: boundary,
|
|
180
|
+
...(Object.keys(attributes).length > 0 ? { attributes } : {}),
|
|
181
|
+
...(document.children?.length ? { children: document.children } : {}),
|
|
182
|
+
});
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
if (typeof element.type !== "string" || !STRATA_TAGS.has(element.type)) {
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
const tag = element.type;
|
|
189
|
+
const attributes = convertAttributes(tag, props);
|
|
190
|
+
if (!attributes)
|
|
191
|
+
return false;
|
|
192
|
+
const children = [];
|
|
193
|
+
if (!appendStrataNodes(props.children, children))
|
|
194
|
+
return false;
|
|
195
|
+
output.push({
|
|
196
|
+
type: "element",
|
|
197
|
+
tag,
|
|
198
|
+
...(Object.keys(attributes).length > 0 ? { attributes } : {}),
|
|
199
|
+
...(children.length > 0 ? { children } : {}),
|
|
200
|
+
});
|
|
201
|
+
return true;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Internal compiler target for automatic optimized boundaries. This helper is
|
|
205
|
+
* deliberately fail-open: any unsupported or unsafe tree returns the original
|
|
206
|
+
* React element unchanged.
|
|
207
|
+
*
|
|
208
|
+
* @internal
|
|
209
|
+
*/
|
|
210
|
+
export function _optimizeBoundary(element) {
|
|
211
|
+
if (!isValidElement(element) ||
|
|
212
|
+
typeof element.type !== "string" ||
|
|
213
|
+
!AUTOMATIC_BOUNDARIES.has(element.type)) {
|
|
214
|
+
return element;
|
|
215
|
+
}
|
|
216
|
+
const props = element.props;
|
|
217
|
+
if (props.dangerouslySetInnerHTML !== undefined || props.ref !== undefined)
|
|
218
|
+
return element;
|
|
219
|
+
const document = automaticDocumentFromElement(element);
|
|
220
|
+
if (!document)
|
|
221
|
+
return element;
|
|
222
|
+
const { children: _children, ...boundaryProps } = props;
|
|
223
|
+
return createElement(AutomaticOptimizedBoundary, {
|
|
224
|
+
...boundaryProps,
|
|
225
|
+
...(element.key !== null ? { key: element.key } : {}),
|
|
226
|
+
as: element.type,
|
|
227
|
+
document,
|
|
228
|
+
fallback: element,
|
|
229
|
+
});
|
|
230
|
+
}
|
|
3
231
|
/**
|
|
4
232
|
* Render a typed host-only document with the optimized native runtime and
|
|
5
233
|
* place it inside an opaque React-owned boundary.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type FarmRouteActionClientTransformResult = {
|
|
2
|
+
code: string;
|
|
3
|
+
routes: string[];
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Replace a programmatic route imported by the browser with a small action-only
|
|
7
|
+
* proxy. Route loaders, components, database imports, and other server code do
|
|
8
|
+
* not enter the client graph.
|
|
9
|
+
*/
|
|
10
|
+
export declare function transformFarmRouteActionClients(code: string, id: string): FarmRouteActionClientTransformResult | null;
|
|
11
|
+
//# sourceMappingURL=route-action-transform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-action-transform.d.ts","sourceRoot":"","sources":["../../src/rsc/route-action-transform.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,oCAAoC,GAAG;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAcF;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,GACT,oCAAoC,GAAG,IAAI,CAqC7C"}
|