@farm.js/plugin 0.1.0-beta.1 → 0.1.0-beta.100
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/api/index.d.ts +2 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +25 -95
- 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 +28 -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/compatibility.d.ts +8 -0
- package/dist/rsc/compatibility.d.ts.map +1 -0
- package/dist/rsc/compatibility.js +46 -0
- package/dist/rsc/dev-response.d.ts +3 -0
- package/dist/rsc/dev-response.d.ts.map +1 -0
- package/dist/rsc/dev-response.js +10 -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 +42 -5
- package/dist/rsc/entries/error-fallback.d.ts +3 -0
- package/dist/rsc/entries/error-fallback.d.ts.map +1 -0
- package/dist/rsc/entries/error-fallback.js +12 -0
- package/dist/rsc/entries/rsc.d.ts.map +1 -1
- package/dist/rsc/entries/rsc.js +187 -189
- package/dist/rsc/entries/ssr.d.ts.map +1 -1
- package/dist/rsc/entries/ssr.js +44 -74
- package/dist/rsc/index.d.ts +15 -2
- package/dist/rsc/index.d.ts.map +1 -1
- package/dist/rsc/index.js +167 -69
- package/dist/rsc/nitro-build.d.ts.map +1 -1
- package/dist/rsc/nitro-build.js +28 -8
- package/dist/rsc/optimized-boundary.d.ts +10 -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/dist/rsc/server-fn-transform.js +1 -1
- package/dist/rsc/test-fixture-dependencies.d.ts +2 -0
- package/dist/rsc/test-fixture-dependencies.d.ts.map +1 -0
- package/dist/rsc/test-fixture-dependencies.js +23 -0
- package/dist/rsc/types.d.ts +9 -0
- package/dist/rsc/types.d.ts.map +1 -1
- package/dist/rsc/vite-plugin-nitro.d.ts +20 -7
- package/dist/rsc/vite-plugin-nitro.d.ts.map +1 -1
- package/dist/rsc/vite-plugin-nitro.js +51 -66
- package/package.json +15 -8
package/dist/rsc/nitro-build.js
CHANGED
|
@@ -219,9 +219,20 @@ function createRscRequest(event) {
|
|
|
219
219
|
return new Request(event.req, { signal: controller.signal });
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
-
export default defineEventHandler((event) =>
|
|
223
|
-
|
|
224
|
-
|
|
222
|
+
export default defineEventHandler(async (event) => {
|
|
223
|
+
const response = await handler(createRscRequest(event), {
|
|
224
|
+
waitUntil: (promise) => event.waitUntil(promise),
|
|
225
|
+
});
|
|
226
|
+
// H3's prepared headers override Response headers. Keep both the runtime's
|
|
227
|
+
// fields (e.g. Accept-Encoding from static middleware) and the app's fields.
|
|
228
|
+
const vary = [event.res.headers.get('vary'), response.headers.get('vary')]
|
|
229
|
+
.filter(Boolean).join(',').split(',').map(value => value.trim()).filter(Boolean);
|
|
230
|
+
if (vary.length) {
|
|
231
|
+
const fields = new Map(vary.map(value => [value.toLowerCase(), value]));
|
|
232
|
+
event.res.headers.set('vary', fields.has('*') ? '*' : [...fields.values()].join(', '));
|
|
233
|
+
}
|
|
234
|
+
return response;
|
|
235
|
+
});
|
|
225
236
|
`.trim();
|
|
226
237
|
const entryPath = path.join(buildDir, "rsc-entry.mjs");
|
|
227
238
|
mkdirSync(buildDir, { recursive: true });
|
|
@@ -271,7 +282,15 @@ export async function buildRscNitro(options) {
|
|
|
271
282
|
},
|
|
272
283
|
// Externalize rsc/ssr so we don't bundle (they reference Vite-generated manifest). We copy dist into server output after build.
|
|
273
284
|
rollupConfig: {
|
|
274
|
-
external: (id) =>
|
|
285
|
+
external: (id) => {
|
|
286
|
+
// Ids reach this predicate in both separator forms on Windows, and matching
|
|
287
|
+
// only the POSIX one makes the same module external in one pass and not in
|
|
288
|
+
// the next, which Rollup rejects.
|
|
289
|
+
const normalized = id.split("\\").join("/");
|
|
290
|
+
return (normalized.includes("../dist/") ||
|
|
291
|
+
normalized.includes("dist/rsc") ||
|
|
292
|
+
normalized.includes("dist/ssr"));
|
|
293
|
+
},
|
|
275
294
|
},
|
|
276
295
|
compatibilityDate: "2024-12-01",
|
|
277
296
|
minify: true,
|
|
@@ -366,13 +385,14 @@ export async function buildRscNitro(options) {
|
|
|
366
385
|
}
|
|
367
386
|
}
|
|
368
387
|
if (existsSync(ssrIndexPath)) {
|
|
369
|
-
const
|
|
388
|
+
const assetsDirName = assetsDir ?? "assets";
|
|
389
|
+
const assetsRoot = path.join(publicDir, assetsDirName);
|
|
370
390
|
let clientCssHref = "";
|
|
371
|
-
if (existsSync(
|
|
372
|
-
const files = readdirSync(
|
|
391
|
+
if (existsSync(assetsRoot)) {
|
|
392
|
+
const files = readdirSync(assetsRoot);
|
|
373
393
|
const cssFile = files.find((f) => f.endsWith(".css"));
|
|
374
394
|
if (cssFile)
|
|
375
|
-
clientCssHref =
|
|
395
|
+
clientCssHref = `/${assetsDirName}/${cssFile}`;
|
|
376
396
|
}
|
|
377
397
|
try {
|
|
378
398
|
let ssrCode = readFileSync(ssrIndexPath, "utf-8");
|
|
@@ -1,5 +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 ReactElement } from "react";
|
|
3
4
|
export type { RenderOptions, StrataDocument, StrataElement, StrataNode, StrataTag, StrataText, } from "@farming-labs/strata";
|
|
4
5
|
export interface OptimizedBoundaryProps extends Omit<StaticFragmentProps, "content"> {
|
|
5
6
|
/**
|
|
@@ -9,12 +10,20 @@ export interface OptimizedBoundaryProps extends Omit<StaticFragmentProps, "conte
|
|
|
9
10
|
document: StrataDocument;
|
|
10
11
|
renderOptions?: RenderOptions;
|
|
11
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;
|
|
12
21
|
/**
|
|
13
22
|
* Render a typed host-only document with the optimized native runtime and
|
|
14
23
|
* place it inside an opaque React-owned boundary.
|
|
15
24
|
*
|
|
16
25
|
* Enable `experimental.optimizedBoundary` before importing this component.
|
|
17
26
|
*/
|
|
18
|
-
export declare function OptimizedBoundary({ document, renderOptions, ...props }: OptimizedBoundaryProps):
|
|
27
|
+
export declare function OptimizedBoundary({ document, renderOptions, ...props }: OptimizedBoundaryProps): ReactElement;
|
|
19
28
|
export type OptimizedBoundaryTag = StaticFragmentBoundary;
|
|
20
29
|
//# sourceMappingURL=optimized-boundary.d.ts.map
|
|
@@ -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"}
|