@farm.js/react 0.1.0-beta.0
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/LICENSE +22 -0
- package/README.md +75 -0
- package/dist/client.cjs +24 -0
- package/dist/client.cjs.map +1 -0
- package/dist/client.d.mts +2 -0
- package/dist/client.d.ts +2 -0
- package/dist/client.mjs +4 -0
- package/dist/client.mjs.map +1 -0
- package/dist/compiler-runtime.cjs +140 -0
- package/dist/compiler-runtime.cjs.map +1 -0
- package/dist/compiler-runtime.d.mts +36 -0
- package/dist/compiler-runtime.d.ts +36 -0
- package/dist/compiler-runtime.mjs +134 -0
- package/dist/compiler-runtime.mjs.map +1 -0
- package/dist/index.cjs +61 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.mts +31 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.mjs +56 -0
- package/dist/index.mjs.map +1 -0
- package/dist/server.cjs +24 -0
- package/dist/server.cjs.map +1 -0
- package/dist/server.d.mts +3 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.mjs +4 -0
- package/dist/server.mjs.map +1 -0
- package/dist/vite.cjs +573 -0
- package/dist/vite.cjs.map +1 -0
- package/dist/vite.d.mts +9 -0
- package/dist/vite.d.ts +9 -0
- package/dist/vite.mjs +571 -0
- package/dist/vite.mjs.map +1 -0
- package/package.json +85 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Farm.js Team
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# @farm.js/react
|
|
2
|
+
|
|
3
|
+
React renderer integration for FARMJS, including the experimental Group 1 AOT compiler.
|
|
4
|
+
|
|
5
|
+
React remains the default renderer and needs no package or configuration. Install this package only
|
|
6
|
+
when opting into the compiler experiment:
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
pnpm add @farm.js/react
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import { defineConfig } from "@farm.js/core";
|
|
14
|
+
import { react } from "@farm.js/react";
|
|
15
|
+
|
|
16
|
+
export default defineConfig({
|
|
17
|
+
renderer: react({
|
|
18
|
+
experimental: {
|
|
19
|
+
compiler: true,
|
|
20
|
+
},
|
|
21
|
+
}),
|
|
22
|
+
});
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`compiler: true` uses inference: every application TSX/JSX component is considered, eligible
|
|
26
|
+
components are compiled, and everything else keeps the normal React path.
|
|
27
|
+
|
|
28
|
+
For selective adoption, use annotation mode:
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
renderer: react({
|
|
32
|
+
experimental: {
|
|
33
|
+
compiler: {
|
|
34
|
+
mode: "annotation",
|
|
35
|
+
directive: "use compiler",
|
|
36
|
+
onUnsupported: "warn",
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
}),
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
export function Counter() {
|
|
44
|
+
"use compiler";
|
|
45
|
+
const [count, setCount] = useState(0);
|
|
46
|
+
return <button onClick={() => setCount((value) => value + 1)}>Count: {count}</button>;
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The directive is configurable and only has meaning in annotation mode.
|
|
51
|
+
|
|
52
|
+
## Group 1 contract
|
|
53
|
+
|
|
54
|
+
The first compiler group handles components that the compiler can prove have:
|
|
55
|
+
|
|
56
|
+
- one host-element root and a static host-element tree;
|
|
57
|
+
- top-level `useState` declarations;
|
|
58
|
+
- state-driven text and basic attribute/property bindings;
|
|
59
|
+
- React-managed event handlers; and
|
|
60
|
+
- no refs, effects, custom child components, keyed lists, or conditional child structure.
|
|
61
|
+
|
|
62
|
+
The generated component preserves React ownership of placement, props, events, SSR, and hydration.
|
|
63
|
+
Local state cells batch updates into a microtask and patch only compiler-known DOM paths. A local
|
|
64
|
+
state update therefore does not schedule a React render or reconciliation pass.
|
|
65
|
+
|
|
66
|
+
Unsupported components fall back to React by default. Use `onUnsupported: "warn"` for diagnostics
|
|
67
|
+
or `onUnsupported: "error"` while tightening an annotated migration.
|
|
68
|
+
|
|
69
|
+
The runtime test compares the same counter interaction on both paths: ordinary React performs a
|
|
70
|
+
second component render and commit, while the compiled component remains at one render and one
|
|
71
|
+
commit and updates its two bindings directly. This is a deterministic structural performance
|
|
72
|
+
assertion; it is not presented as a cross-machine timing benchmark.
|
|
73
|
+
|
|
74
|
+
Keyed list lowering, structural conditionals, effects, and more advanced hook support belong to
|
|
75
|
+
later compiler groups and intentionally stay on React in this release.
|
package/dist/client.cjs
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var client = require('@farm.js/core/renderer/react/client');
|
|
6
|
+
|
|
7
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
+
|
|
9
|
+
var client__default = /*#__PURE__*/_interopDefault(client);
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
Object.defineProperty(exports, "default", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function () { return client__default.default; }
|
|
16
|
+
});
|
|
17
|
+
Object.keys(client).forEach(function (k) {
|
|
18
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () { return client[k]; }
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
//# sourceMappingURL=client.cjs.map
|
|
24
|
+
//# sourceMappingURL=client.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"client.cjs","sourcesContent":[]}
|
package/dist/client.d.ts
ADDED
package/dist/client.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"client.mjs","sourcesContent":[]}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
|
|
5
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
6
|
+
|
|
7
|
+
var React__default = /*#__PURE__*/_interopDefault(React);
|
|
8
|
+
|
|
9
|
+
// src/compiler-runtime.tsx
|
|
10
|
+
function renderTextValue(value) {
|
|
11
|
+
if (Array.isArray(value)) return value.map(renderTextValue).join("");
|
|
12
|
+
if (value === null || value === void 0 || typeof value === "boolean") return "";
|
|
13
|
+
return String(value);
|
|
14
|
+
}
|
|
15
|
+
function findBindingTarget(root, path) {
|
|
16
|
+
let current = root;
|
|
17
|
+
for (const index of path) {
|
|
18
|
+
current = current?.children.item(index) || null;
|
|
19
|
+
}
|
|
20
|
+
return current;
|
|
21
|
+
}
|
|
22
|
+
function updateAttribute(element, name, value) {
|
|
23
|
+
const attributeName = name === "className" ? "class" : name === "htmlFor" ? "for" : name;
|
|
24
|
+
const stringifiesBoolean = attributeName.startsWith("data-") || attributeName.startsWith("aria-");
|
|
25
|
+
if (name === "value" && element instanceof HTMLInputElement) {
|
|
26
|
+
element.value = value === null || value === void 0 ? "" : String(value);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (name === "checked" && element instanceof HTMLInputElement) {
|
|
30
|
+
element.checked = Boolean(value);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if (name === "selected" && element instanceof HTMLOptionElement) {
|
|
34
|
+
element.selected = Boolean(value);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (name === "disabled" && "disabled" in element) {
|
|
38
|
+
element.disabled = Boolean(value);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (value === null || value === void 0 || value === false && !stringifiesBoolean) {
|
|
42
|
+
element.removeAttribute(attributeName);
|
|
43
|
+
} else if (value === true && !stringifiesBoolean) {
|
|
44
|
+
element.setAttribute(attributeName, "");
|
|
45
|
+
} else {
|
|
46
|
+
element.setAttribute(attributeName, String(value));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function createCompiledComponent(definition) {
|
|
50
|
+
class FarmCompiledComponent extends React__default.default.Component {
|
|
51
|
+
constructor(props) {
|
|
52
|
+
super(props);
|
|
53
|
+
this.root = null;
|
|
54
|
+
this.mounted = false;
|
|
55
|
+
this.flushQueued = false;
|
|
56
|
+
this.dirtyState = /* @__PURE__ */ new Set();
|
|
57
|
+
this.captureRoot = (root) => {
|
|
58
|
+
this.root = root;
|
|
59
|
+
};
|
|
60
|
+
this.cells = definition.initialize(props).map((initialValue, index) => {
|
|
61
|
+
let value = initialValue;
|
|
62
|
+
const pending = [];
|
|
63
|
+
return {
|
|
64
|
+
get: () => value,
|
|
65
|
+
set: (next) => {
|
|
66
|
+
pending.push(next);
|
|
67
|
+
this.scheduleBindingFlush(index);
|
|
68
|
+
},
|
|
69
|
+
flush: () => {
|
|
70
|
+
if (pending.length === 0) return false;
|
|
71
|
+
const previous = value;
|
|
72
|
+
for (const next of pending.splice(0)) {
|
|
73
|
+
value = typeof next === "function" ? next(value) : next;
|
|
74
|
+
}
|
|
75
|
+
return !Object.is(previous, value);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
scheduleBindingFlush(index) {
|
|
81
|
+
this.dirtyState.add(index);
|
|
82
|
+
if (!this.mounted || this.flushQueued) return;
|
|
83
|
+
this.flushQueued = true;
|
|
84
|
+
queueMicrotask(() => {
|
|
85
|
+
this.flushQueued = false;
|
|
86
|
+
if (!this.mounted) return;
|
|
87
|
+
const dirty = /* @__PURE__ */ new Set();
|
|
88
|
+
for (const index2 of this.dirtyState) {
|
|
89
|
+
if (this.cells[index2]?.flush()) dirty.add(index2);
|
|
90
|
+
}
|
|
91
|
+
this.dirtyState.clear();
|
|
92
|
+
if (dirty.size === 0) return;
|
|
93
|
+
for (const binding of definition.bindings) {
|
|
94
|
+
if (binding.dependencies.some((dependency) => dirty.has(dependency))) {
|
|
95
|
+
this.applyBinding(binding);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
applyBinding(binding) {
|
|
101
|
+
if (!this.root) return;
|
|
102
|
+
const target = findBindingTarget(this.root, binding.path);
|
|
103
|
+
if (!target) return;
|
|
104
|
+
const value = binding.read(this.props, this.cells);
|
|
105
|
+
if (binding.kind === "text") {
|
|
106
|
+
target.textContent = renderTextValue(value);
|
|
107
|
+
} else {
|
|
108
|
+
updateAttribute(target, binding.name, value);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
componentDidMount() {
|
|
112
|
+
this.mounted = true;
|
|
113
|
+
}
|
|
114
|
+
componentDidUpdate() {
|
|
115
|
+
for (const binding of definition.bindings) this.applyBinding(binding);
|
|
116
|
+
}
|
|
117
|
+
componentWillUnmount() {
|
|
118
|
+
this.mounted = false;
|
|
119
|
+
this.root = null;
|
|
120
|
+
this.dirtyState.clear();
|
|
121
|
+
}
|
|
122
|
+
render() {
|
|
123
|
+
const element = definition.render(this.props, this.cells);
|
|
124
|
+
if (!React__default.default.isValidElement(element) || typeof element.type !== "string") {
|
|
125
|
+
throw new TypeError(
|
|
126
|
+
`Compiled component ${definition.displayName} must return one host element.`
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
return React__default.default.cloneElement(element, {
|
|
130
|
+
ref: this.captureRoot
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
FarmCompiledComponent.displayName = `FarmCompiled(${definition.displayName})`;
|
|
135
|
+
return FarmCompiledComponent;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
exports.createCompiledComponent = createCompiledComponent;
|
|
139
|
+
//# sourceMappingURL=compiler-runtime.cjs.map
|
|
140
|
+
//# sourceMappingURL=compiler-runtime.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/compiler-runtime.tsx"],"names":["React","index"],"mappings":"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","file":"compiler-runtime.cjs","sourcesContent":["import React from \"react\";\n\nexport type CompilerStateUpdater = unknown | ((previous: unknown) => unknown);\n\nexport interface CompilerCell {\n get(): unknown;\n set(next: CompilerStateUpdater): void;\n}\n\ninterface RuntimeCell extends CompilerCell {\n flush(): boolean;\n}\n\nexport interface CompilerTextBinding<Props> {\n kind: \"text\";\n path: readonly number[];\n dependencies: readonly number[];\n read(props: Props, state: readonly CompilerCell[]): unknown;\n}\n\nexport interface CompilerAttributeBinding<Props> {\n kind: \"attribute\";\n path: readonly number[];\n dependencies: readonly number[];\n name: string;\n read(props: Props, state: readonly CompilerCell[]): unknown;\n}\n\nexport type CompilerBinding<Props> = CompilerTextBinding<Props> | CompilerAttributeBinding<Props>;\n\nexport interface CompiledComponentDefinition<Props> {\n displayName: string;\n initialize(props: Props): readonly unknown[];\n render(props: Props, state: readonly CompilerCell[]): React.ReactElement;\n bindings: readonly CompilerBinding<Props>[];\n}\n\nfunction renderTextValue(value: unknown): string {\n if (Array.isArray(value)) return value.map(renderTextValue).join(\"\");\n if (value === null || value === undefined || typeof value === \"boolean\") return \"\";\n return String(value);\n}\n\nfunction findBindingTarget(root: Element, path: readonly number[]): Element | null {\n let current: Element | null = root;\n for (const index of path) {\n current = current?.children.item(index) || null;\n }\n return current;\n}\n\nfunction updateAttribute(element: Element, name: string, value: unknown): void {\n const attributeName = name === \"className\" ? \"class\" : name === \"htmlFor\" ? \"for\" : name;\n const stringifiesBoolean = attributeName.startsWith(\"data-\") || attributeName.startsWith(\"aria-\");\n\n if (name === \"value\" && element instanceof HTMLInputElement) {\n element.value = value === null || value === undefined ? \"\" : String(value);\n return;\n }\n\n if (name === \"checked\" && element instanceof HTMLInputElement) {\n element.checked = Boolean(value);\n return;\n }\n\n if (name === \"selected\" && element instanceof HTMLOptionElement) {\n element.selected = Boolean(value);\n return;\n }\n\n if (name === \"disabled\" && \"disabled\" in element) {\n (element as HTMLButtonElement).disabled = Boolean(value);\n return;\n }\n\n if (value === null || value === undefined || (value === false && !stringifiesBoolean)) {\n element.removeAttribute(attributeName);\n } else if (value === true && !stringifiesBoolean) {\n element.setAttribute(attributeName, \"\");\n } else {\n element.setAttribute(attributeName, String(value));\n }\n}\n\n/**\n * Runtime target emitted by the AOT transform.\n *\n * React owns component placement, SSR, hydration, props, and event semantics.\n * Compiler cells own local state updates and patch only precomputed DOM paths.\n */\nexport function createCompiledComponent<Props>(\n definition: CompiledComponentDefinition<Props>,\n): React.ComponentType<Props> {\n class FarmCompiledComponent extends React.Component<Props> {\n private root: Element | null = null;\n private mounted = false;\n private flushQueued = false;\n private readonly dirtyState = new Set<number>();\n private readonly cells: RuntimeCell[];\n\n constructor(props: Props) {\n super(props);\n this.cells = definition.initialize(props).map((initialValue, index) => {\n let value = initialValue;\n const pending: CompilerStateUpdater[] = [];\n return {\n get: () => value,\n set: (next) => {\n pending.push(next);\n this.scheduleBindingFlush(index);\n },\n flush: () => {\n if (pending.length === 0) return false;\n const previous = value;\n for (const next of pending.splice(0)) {\n value = typeof next === \"function\" ? next(value) : next;\n }\n return !Object.is(previous, value);\n },\n };\n });\n }\n\n private captureRoot = (root: Element | null) => {\n this.root = root;\n };\n\n private scheduleBindingFlush(index: number): void {\n this.dirtyState.add(index);\n if (!this.mounted || this.flushQueued) return;\n this.flushQueued = true;\n queueMicrotask(() => {\n this.flushQueued = false;\n if (!this.mounted) return;\n const dirty = new Set<number>();\n for (const index of this.dirtyState) {\n if (this.cells[index]?.flush()) dirty.add(index);\n }\n this.dirtyState.clear();\n if (dirty.size === 0) return;\n for (const binding of definition.bindings) {\n if (binding.dependencies.some((dependency) => dirty.has(dependency))) {\n this.applyBinding(binding);\n }\n }\n });\n }\n\n private applyBinding(binding: CompilerBinding<Props>): void {\n if (!this.root) return;\n const target = findBindingTarget(this.root, binding.path);\n if (!target) return;\n const value = binding.read(this.props, this.cells);\n if (binding.kind === \"text\") {\n target.textContent = renderTextValue(value);\n } else {\n updateAttribute(target, binding.name, value);\n }\n }\n\n componentDidMount(): void {\n this.mounted = true;\n }\n\n componentDidUpdate(): void {\n // React has reconciled a parent-driven prop update. Reapply compiled\n // bindings from the current cells so React and the imperative state stay\n // coherent even when both change in the same turn.\n for (const binding of definition.bindings) this.applyBinding(binding);\n }\n\n componentWillUnmount(): void {\n this.mounted = false;\n this.root = null;\n this.dirtyState.clear();\n }\n\n render(): React.ReactNode {\n const element = definition.render(this.props, this.cells);\n if (!React.isValidElement(element) || typeof element.type !== \"string\") {\n throw new TypeError(\n `Compiled component ${definition.displayName} must return one host element.`,\n );\n }\n return React.cloneElement(element, {\n ref: this.captureRoot,\n } as React.Attributes);\n }\n }\n\n (FarmCompiledComponent as React.ComponentType<Props>).displayName =\n `FarmCompiled(${definition.displayName})`;\n return FarmCompiledComponent;\n}\n"]}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
type CompilerStateUpdater = unknown | ((previous: unknown) => unknown);
|
|
4
|
+
interface CompilerCell {
|
|
5
|
+
get(): unknown;
|
|
6
|
+
set(next: CompilerStateUpdater): void;
|
|
7
|
+
}
|
|
8
|
+
interface CompilerTextBinding<Props> {
|
|
9
|
+
kind: "text";
|
|
10
|
+
path: readonly number[];
|
|
11
|
+
dependencies: readonly number[];
|
|
12
|
+
read(props: Props, state: readonly CompilerCell[]): unknown;
|
|
13
|
+
}
|
|
14
|
+
interface CompilerAttributeBinding<Props> {
|
|
15
|
+
kind: "attribute";
|
|
16
|
+
path: readonly number[];
|
|
17
|
+
dependencies: readonly number[];
|
|
18
|
+
name: string;
|
|
19
|
+
read(props: Props, state: readonly CompilerCell[]): unknown;
|
|
20
|
+
}
|
|
21
|
+
type CompilerBinding<Props> = CompilerTextBinding<Props> | CompilerAttributeBinding<Props>;
|
|
22
|
+
interface CompiledComponentDefinition<Props> {
|
|
23
|
+
displayName: string;
|
|
24
|
+
initialize(props: Props): readonly unknown[];
|
|
25
|
+
render(props: Props, state: readonly CompilerCell[]): React.ReactElement;
|
|
26
|
+
bindings: readonly CompilerBinding<Props>[];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Runtime target emitted by the AOT transform.
|
|
30
|
+
*
|
|
31
|
+
* React owns component placement, SSR, hydration, props, and event semantics.
|
|
32
|
+
* Compiler cells own local state updates and patch only precomputed DOM paths.
|
|
33
|
+
*/
|
|
34
|
+
declare function createCompiledComponent<Props>(definition: CompiledComponentDefinition<Props>): React.ComponentType<Props>;
|
|
35
|
+
|
|
36
|
+
export { type CompiledComponentDefinition, type CompilerAttributeBinding, type CompilerBinding, type CompilerCell, type CompilerStateUpdater, type CompilerTextBinding, createCompiledComponent };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
type CompilerStateUpdater = unknown | ((previous: unknown) => unknown);
|
|
4
|
+
interface CompilerCell {
|
|
5
|
+
get(): unknown;
|
|
6
|
+
set(next: CompilerStateUpdater): void;
|
|
7
|
+
}
|
|
8
|
+
interface CompilerTextBinding<Props> {
|
|
9
|
+
kind: "text";
|
|
10
|
+
path: readonly number[];
|
|
11
|
+
dependencies: readonly number[];
|
|
12
|
+
read(props: Props, state: readonly CompilerCell[]): unknown;
|
|
13
|
+
}
|
|
14
|
+
interface CompilerAttributeBinding<Props> {
|
|
15
|
+
kind: "attribute";
|
|
16
|
+
path: readonly number[];
|
|
17
|
+
dependencies: readonly number[];
|
|
18
|
+
name: string;
|
|
19
|
+
read(props: Props, state: readonly CompilerCell[]): unknown;
|
|
20
|
+
}
|
|
21
|
+
type CompilerBinding<Props> = CompilerTextBinding<Props> | CompilerAttributeBinding<Props>;
|
|
22
|
+
interface CompiledComponentDefinition<Props> {
|
|
23
|
+
displayName: string;
|
|
24
|
+
initialize(props: Props): readonly unknown[];
|
|
25
|
+
render(props: Props, state: readonly CompilerCell[]): React.ReactElement;
|
|
26
|
+
bindings: readonly CompilerBinding<Props>[];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Runtime target emitted by the AOT transform.
|
|
30
|
+
*
|
|
31
|
+
* React owns component placement, SSR, hydration, props, and event semantics.
|
|
32
|
+
* Compiler cells own local state updates and patch only precomputed DOM paths.
|
|
33
|
+
*/
|
|
34
|
+
declare function createCompiledComponent<Props>(definition: CompiledComponentDefinition<Props>): React.ComponentType<Props>;
|
|
35
|
+
|
|
36
|
+
export { type CompiledComponentDefinition, type CompilerAttributeBinding, type CompilerBinding, type CompilerCell, type CompilerStateUpdater, type CompilerTextBinding, createCompiledComponent };
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
// src/compiler-runtime.tsx
|
|
4
|
+
function renderTextValue(value) {
|
|
5
|
+
if (Array.isArray(value)) return value.map(renderTextValue).join("");
|
|
6
|
+
if (value === null || value === void 0 || typeof value === "boolean") return "";
|
|
7
|
+
return String(value);
|
|
8
|
+
}
|
|
9
|
+
function findBindingTarget(root, path) {
|
|
10
|
+
let current = root;
|
|
11
|
+
for (const index of path) {
|
|
12
|
+
current = current?.children.item(index) || null;
|
|
13
|
+
}
|
|
14
|
+
return current;
|
|
15
|
+
}
|
|
16
|
+
function updateAttribute(element, name, value) {
|
|
17
|
+
const attributeName = name === "className" ? "class" : name === "htmlFor" ? "for" : name;
|
|
18
|
+
const stringifiesBoolean = attributeName.startsWith("data-") || attributeName.startsWith("aria-");
|
|
19
|
+
if (name === "value" && element instanceof HTMLInputElement) {
|
|
20
|
+
element.value = value === null || value === void 0 ? "" : String(value);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (name === "checked" && element instanceof HTMLInputElement) {
|
|
24
|
+
element.checked = Boolean(value);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (name === "selected" && element instanceof HTMLOptionElement) {
|
|
28
|
+
element.selected = Boolean(value);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (name === "disabled" && "disabled" in element) {
|
|
32
|
+
element.disabled = Boolean(value);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (value === null || value === void 0 || value === false && !stringifiesBoolean) {
|
|
36
|
+
element.removeAttribute(attributeName);
|
|
37
|
+
} else if (value === true && !stringifiesBoolean) {
|
|
38
|
+
element.setAttribute(attributeName, "");
|
|
39
|
+
} else {
|
|
40
|
+
element.setAttribute(attributeName, String(value));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function createCompiledComponent(definition) {
|
|
44
|
+
class FarmCompiledComponent extends React.Component {
|
|
45
|
+
constructor(props) {
|
|
46
|
+
super(props);
|
|
47
|
+
this.root = null;
|
|
48
|
+
this.mounted = false;
|
|
49
|
+
this.flushQueued = false;
|
|
50
|
+
this.dirtyState = /* @__PURE__ */ new Set();
|
|
51
|
+
this.captureRoot = (root) => {
|
|
52
|
+
this.root = root;
|
|
53
|
+
};
|
|
54
|
+
this.cells = definition.initialize(props).map((initialValue, index) => {
|
|
55
|
+
let value = initialValue;
|
|
56
|
+
const pending = [];
|
|
57
|
+
return {
|
|
58
|
+
get: () => value,
|
|
59
|
+
set: (next) => {
|
|
60
|
+
pending.push(next);
|
|
61
|
+
this.scheduleBindingFlush(index);
|
|
62
|
+
},
|
|
63
|
+
flush: () => {
|
|
64
|
+
if (pending.length === 0) return false;
|
|
65
|
+
const previous = value;
|
|
66
|
+
for (const next of pending.splice(0)) {
|
|
67
|
+
value = typeof next === "function" ? next(value) : next;
|
|
68
|
+
}
|
|
69
|
+
return !Object.is(previous, value);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
scheduleBindingFlush(index) {
|
|
75
|
+
this.dirtyState.add(index);
|
|
76
|
+
if (!this.mounted || this.flushQueued) return;
|
|
77
|
+
this.flushQueued = true;
|
|
78
|
+
queueMicrotask(() => {
|
|
79
|
+
this.flushQueued = false;
|
|
80
|
+
if (!this.mounted) return;
|
|
81
|
+
const dirty = /* @__PURE__ */ new Set();
|
|
82
|
+
for (const index2 of this.dirtyState) {
|
|
83
|
+
if (this.cells[index2]?.flush()) dirty.add(index2);
|
|
84
|
+
}
|
|
85
|
+
this.dirtyState.clear();
|
|
86
|
+
if (dirty.size === 0) return;
|
|
87
|
+
for (const binding of definition.bindings) {
|
|
88
|
+
if (binding.dependencies.some((dependency) => dirty.has(dependency))) {
|
|
89
|
+
this.applyBinding(binding);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
applyBinding(binding) {
|
|
95
|
+
if (!this.root) return;
|
|
96
|
+
const target = findBindingTarget(this.root, binding.path);
|
|
97
|
+
if (!target) return;
|
|
98
|
+
const value = binding.read(this.props, this.cells);
|
|
99
|
+
if (binding.kind === "text") {
|
|
100
|
+
target.textContent = renderTextValue(value);
|
|
101
|
+
} else {
|
|
102
|
+
updateAttribute(target, binding.name, value);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
componentDidMount() {
|
|
106
|
+
this.mounted = true;
|
|
107
|
+
}
|
|
108
|
+
componentDidUpdate() {
|
|
109
|
+
for (const binding of definition.bindings) this.applyBinding(binding);
|
|
110
|
+
}
|
|
111
|
+
componentWillUnmount() {
|
|
112
|
+
this.mounted = false;
|
|
113
|
+
this.root = null;
|
|
114
|
+
this.dirtyState.clear();
|
|
115
|
+
}
|
|
116
|
+
render() {
|
|
117
|
+
const element = definition.render(this.props, this.cells);
|
|
118
|
+
if (!React.isValidElement(element) || typeof element.type !== "string") {
|
|
119
|
+
throw new TypeError(
|
|
120
|
+
`Compiled component ${definition.displayName} must return one host element.`
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
return React.cloneElement(element, {
|
|
124
|
+
ref: this.captureRoot
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
FarmCompiledComponent.displayName = `FarmCompiled(${definition.displayName})`;
|
|
129
|
+
return FarmCompiledComponent;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export { createCompiledComponent };
|
|
133
|
+
//# sourceMappingURL=compiler-runtime.mjs.map
|
|
134
|
+
//# sourceMappingURL=compiler-runtime.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/compiler-runtime.tsx"],"names":["index"],"mappings":"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","file":"compiler-runtime.mjs","sourcesContent":["import React from \"react\";\n\nexport type CompilerStateUpdater = unknown | ((previous: unknown) => unknown);\n\nexport interface CompilerCell {\n get(): unknown;\n set(next: CompilerStateUpdater): void;\n}\n\ninterface RuntimeCell extends CompilerCell {\n flush(): boolean;\n}\n\nexport interface CompilerTextBinding<Props> {\n kind: \"text\";\n path: readonly number[];\n dependencies: readonly number[];\n read(props: Props, state: readonly CompilerCell[]): unknown;\n}\n\nexport interface CompilerAttributeBinding<Props> {\n kind: \"attribute\";\n path: readonly number[];\n dependencies: readonly number[];\n name: string;\n read(props: Props, state: readonly CompilerCell[]): unknown;\n}\n\nexport type CompilerBinding<Props> = CompilerTextBinding<Props> | CompilerAttributeBinding<Props>;\n\nexport interface CompiledComponentDefinition<Props> {\n displayName: string;\n initialize(props: Props): readonly unknown[];\n render(props: Props, state: readonly CompilerCell[]): React.ReactElement;\n bindings: readonly CompilerBinding<Props>[];\n}\n\nfunction renderTextValue(value: unknown): string {\n if (Array.isArray(value)) return value.map(renderTextValue).join(\"\");\n if (value === null || value === undefined || typeof value === \"boolean\") return \"\";\n return String(value);\n}\n\nfunction findBindingTarget(root: Element, path: readonly number[]): Element | null {\n let current: Element | null = root;\n for (const index of path) {\n current = current?.children.item(index) || null;\n }\n return current;\n}\n\nfunction updateAttribute(element: Element, name: string, value: unknown): void {\n const attributeName = name === \"className\" ? \"class\" : name === \"htmlFor\" ? \"for\" : name;\n const stringifiesBoolean = attributeName.startsWith(\"data-\") || attributeName.startsWith(\"aria-\");\n\n if (name === \"value\" && element instanceof HTMLInputElement) {\n element.value = value === null || value === undefined ? \"\" : String(value);\n return;\n }\n\n if (name === \"checked\" && element instanceof HTMLInputElement) {\n element.checked = Boolean(value);\n return;\n }\n\n if (name === \"selected\" && element instanceof HTMLOptionElement) {\n element.selected = Boolean(value);\n return;\n }\n\n if (name === \"disabled\" && \"disabled\" in element) {\n (element as HTMLButtonElement).disabled = Boolean(value);\n return;\n }\n\n if (value === null || value === undefined || (value === false && !stringifiesBoolean)) {\n element.removeAttribute(attributeName);\n } else if (value === true && !stringifiesBoolean) {\n element.setAttribute(attributeName, \"\");\n } else {\n element.setAttribute(attributeName, String(value));\n }\n}\n\n/**\n * Runtime target emitted by the AOT transform.\n *\n * React owns component placement, SSR, hydration, props, and event semantics.\n * Compiler cells own local state updates and patch only precomputed DOM paths.\n */\nexport function createCompiledComponent<Props>(\n definition: CompiledComponentDefinition<Props>,\n): React.ComponentType<Props> {\n class FarmCompiledComponent extends React.Component<Props> {\n private root: Element | null = null;\n private mounted = false;\n private flushQueued = false;\n private readonly dirtyState = new Set<number>();\n private readonly cells: RuntimeCell[];\n\n constructor(props: Props) {\n super(props);\n this.cells = definition.initialize(props).map((initialValue, index) => {\n let value = initialValue;\n const pending: CompilerStateUpdater[] = [];\n return {\n get: () => value,\n set: (next) => {\n pending.push(next);\n this.scheduleBindingFlush(index);\n },\n flush: () => {\n if (pending.length === 0) return false;\n const previous = value;\n for (const next of pending.splice(0)) {\n value = typeof next === \"function\" ? next(value) : next;\n }\n return !Object.is(previous, value);\n },\n };\n });\n }\n\n private captureRoot = (root: Element | null) => {\n this.root = root;\n };\n\n private scheduleBindingFlush(index: number): void {\n this.dirtyState.add(index);\n if (!this.mounted || this.flushQueued) return;\n this.flushQueued = true;\n queueMicrotask(() => {\n this.flushQueued = false;\n if (!this.mounted) return;\n const dirty = new Set<number>();\n for (const index of this.dirtyState) {\n if (this.cells[index]?.flush()) dirty.add(index);\n }\n this.dirtyState.clear();\n if (dirty.size === 0) return;\n for (const binding of definition.bindings) {\n if (binding.dependencies.some((dependency) => dirty.has(dependency))) {\n this.applyBinding(binding);\n }\n }\n });\n }\n\n private applyBinding(binding: CompilerBinding<Props>): void {\n if (!this.root) return;\n const target = findBindingTarget(this.root, binding.path);\n if (!target) return;\n const value = binding.read(this.props, this.cells);\n if (binding.kind === \"text\") {\n target.textContent = renderTextValue(value);\n } else {\n updateAttribute(target, binding.name, value);\n }\n }\n\n componentDidMount(): void {\n this.mounted = true;\n }\n\n componentDidUpdate(): void {\n // React has reconciled a parent-driven prop update. Reapply compiled\n // bindings from the current cells so React and the imperative state stay\n // coherent even when both change in the same turn.\n for (const binding of definition.bindings) this.applyBinding(binding);\n }\n\n componentWillUnmount(): void {\n this.mounted = false;\n this.root = null;\n this.dirtyState.clear();\n }\n\n render(): React.ReactNode {\n const element = definition.render(this.props, this.cells);\n if (!React.isValidElement(element) || typeof element.type !== \"string\") {\n throw new TypeError(\n `Compiled component ${definition.displayName} must return one host element.`,\n );\n }\n return React.cloneElement(element, {\n ref: this.captureRoot,\n } as React.Attributes);\n }\n }\n\n (FarmCompiledComponent as React.ComponentType<Props>).displayName =\n `FarmCompiled(${definition.displayName})`;\n return FarmCompiledComponent;\n}\n"]}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/index.ts
|
|
4
|
+
var DEFAULT_COMPILER_DIRECTIVE = "use compiler";
|
|
5
|
+
function normalizeReactCompilerOptions(value) {
|
|
6
|
+
const options = value === true ? {} : value;
|
|
7
|
+
const mode = options.mode || "infer";
|
|
8
|
+
if (mode !== "infer" && mode !== "annotation") {
|
|
9
|
+
throw new TypeError(`Unknown React compiler mode: ${String(mode)}`);
|
|
10
|
+
}
|
|
11
|
+
if (options.directive !== void 0 && mode !== "annotation") {
|
|
12
|
+
throw new TypeError("The React compiler directive can only be configured in annotation mode.");
|
|
13
|
+
}
|
|
14
|
+
const directive = options.directive?.trim() || DEFAULT_COMPILER_DIRECTIVE;
|
|
15
|
+
const onUnsupported = options.onUnsupported || "fallback";
|
|
16
|
+
if (!["fallback", "warn", "error"].includes(onUnsupported)) {
|
|
17
|
+
throw new TypeError(`Unknown unsupported-component behavior: ${String(onUnsupported)}`);
|
|
18
|
+
}
|
|
19
|
+
return { mode, directive, onUnsupported };
|
|
20
|
+
}
|
|
21
|
+
var REACT_RENDERER = Object.freeze({
|
|
22
|
+
name: "react",
|
|
23
|
+
vite: "@farm.js/react/vite",
|
|
24
|
+
server: "@farm.js/react/server",
|
|
25
|
+
client: "@farm.js/react/client",
|
|
26
|
+
jsxImportSource: "react",
|
|
27
|
+
dedupe: ["react", "react-dom", "react/jsx-runtime", "react/jsx-dev-runtime"],
|
|
28
|
+
optimizeDeps: [
|
|
29
|
+
"react",
|
|
30
|
+
"react-dom",
|
|
31
|
+
"react-dom/client",
|
|
32
|
+
"react/jsx-runtime",
|
|
33
|
+
"react/jsx-dev-runtime",
|
|
34
|
+
"@farm.js/react/compiler-runtime"
|
|
35
|
+
],
|
|
36
|
+
capabilities: {
|
|
37
|
+
streaming: { node: true, web: false }
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
function react(options = {}) {
|
|
41
|
+
const compiler = options.experimental?.compiler;
|
|
42
|
+
const normalizedCompiler = compiler ? normalizeReactCompilerOptions(compiler) : false;
|
|
43
|
+
return {
|
|
44
|
+
...REACT_RENDERER,
|
|
45
|
+
dedupe: [...REACT_RENDERER.dedupe || []],
|
|
46
|
+
optimizeDeps: [...REACT_RENDERER.optimizeDeps || []],
|
|
47
|
+
capabilities: {
|
|
48
|
+
streaming: { ...REACT_RENDERER.capabilities?.streaming }
|
|
49
|
+
},
|
|
50
|
+
options: {
|
|
51
|
+
experimental: { compiler: normalizedCompiler }
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
exports.DEFAULT_COMPILER_DIRECTIVE = DEFAULT_COMPILER_DIRECTIVE;
|
|
57
|
+
exports.REACT_RENDERER = REACT_RENDERER;
|
|
58
|
+
exports.normalizeReactCompilerOptions = normalizeReactCompilerOptions;
|
|
59
|
+
exports.react = react;
|
|
60
|
+
//# sourceMappingURL=index.cjs.map
|
|
61
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;AA2BO,IAAM,0BAAA,GAA6B;AAEnC,SAAS,8BACd,KAAA,EACgC;AAChC,EAAA,MAAM,OAAA,GAAU,KAAA,KAAU,IAAA,GAAO,EAAC,GAAI,KAAA;AACtC,EAAA,MAAM,IAAA,GAAO,QAAQ,IAAA,IAAQ,OAAA;AAE7B,EAAA,IAAI,IAAA,KAAS,OAAA,IAAW,IAAA,KAAS,YAAA,EAAc;AAC7C,IAAA,MAAM,IAAI,SAAA,CAAU,CAAA,6BAAA,EAAgC,MAAA,CAAO,IAAI,CAAC,CAAA,CAAE,CAAA;AAAA,EACpE;AAEA,EAAA,IAAI,OAAA,CAAQ,SAAA,KAAc,MAAA,IAAa,IAAA,KAAS,YAAA,EAAc;AAC5D,IAAA,MAAM,IAAI,UAAU,yEAAyE,CAAA;AAAA,EAC/F;AAEA,EAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,SAAA,EAAW,IAAA,EAAK,IAAK,0BAAA;AAC/C,EAAA,MAAM,aAAA,GAAgB,QAAQ,aAAA,IAAiB,UAAA;AAC/C,EAAA,IAAI,CAAE,CAAC,UAAA,EAAY,MAAA,EAAQ,OAAO,CAAA,CAAY,QAAA,CAAS,aAAa,CAAA,EAAG;AACrE,IAAA,MAAM,IAAI,SAAA,CAAU,CAAA,wCAAA,EAA2C,MAAA,CAAO,aAAa,CAAC,CAAA,CAAE,CAAA;AAAA,EACxF;AAEA,EAAA,OAAO,EAAE,IAAA,EAAM,SAAA,EAAW,aAAA,EAAc;AAC1C;AAEA,IAAM,cAAA,GAAyC,OAAO,MAAA,CAAO;AAAA,EAC3D,IAAA,EAAM,OAAA;AAAA,EACN,IAAA,EAAM,qBAAA;AAAA,EACN,MAAA,EAAQ,uBAAA;AAAA,EACR,MAAA,EAAQ,uBAAA;AAAA,EACR,eAAA,EAAiB,OAAA;AAAA,EACjB,MAAA,EAAQ,CAAC,OAAA,EAAS,WAAA,EAAa,qBAAqB,uBAAuB,CAAA;AAAA,EAC3E,YAAA,EAAc;AAAA,IACZ,OAAA;AAAA,IACA,WAAA;AAAA,IACA,kBAAA;AAAA,IACA,mBAAA;AAAA,IACA,uBAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA,YAAA,EAAc;AAAA,IACZ,SAAA,EAAW,EAAE,IAAA,EAAM,IAAA,EAAM,KAAK,KAAA;AAAM;AAExC,CAAC;AAGM,SAAS,KAAA,CAAM,OAAA,GAAgC,EAAC,EAAiB;AACtE,EAAA,MAAM,QAAA,GAAW,QAAQ,YAAA,EAAc,QAAA;AACvC,EAAA,MAAM,kBAAA,GAAqB,QAAA,GAAW,6BAAA,CAA8B,QAAQ,CAAA,GAAI,KAAA;AAEhF,EAAA,OAAO;AAAA,IACL,GAAG,cAAA;AAAA,IACH,QAAQ,CAAC,GAAI,cAAA,CAAe,MAAA,IAAU,EAAG,CAAA;AAAA,IACzC,cAAc,CAAC,GAAI,cAAA,CAAe,YAAA,IAAgB,EAAG,CAAA;AAAA,IACrD,YAAA,EAAc;AAAA,MACZ,SAAA,EAAW,EAAE,GAAG,cAAA,CAAe,cAAc,SAAA;AAAU,KACzD;AAAA,IACA,OAAA,EAAS;AAAA,MACP,YAAA,EAAc,EAAE,QAAA,EAAU,kBAAA;AAAmB;AAC/C,GACF;AACF","file":"index.cjs","sourcesContent":["import type { FarmRenderer } from \"@farm.js/core/renderer\";\n\nexport type ReactCompilerMode = \"infer\" | \"annotation\";\nexport type UnsupportedCompilerBehavior = \"fallback\" | \"warn\" | \"error\";\n\nexport interface ReactCompilerOptions {\n /** Compile every component that the safe subset can prove eligible. */\n mode?: ReactCompilerMode;\n /** Function or module directive used only by annotation mode. */\n directive?: string;\n /** What to do when a selected component is outside the safe subset. */\n onUnsupported?: UnsupportedCompilerBehavior;\n}\n\nexport interface ReactRendererOptions {\n experimental?: {\n /** `true` enables automatic inference; an object customizes selection. */\n compiler?: boolean | ReactCompilerOptions;\n };\n}\n\nexport interface NormalizedReactCompilerOptions {\n mode: ReactCompilerMode;\n directive: string;\n onUnsupported: UnsupportedCompilerBehavior;\n}\n\nexport const DEFAULT_COMPILER_DIRECTIVE = \"use compiler\";\n\nexport function normalizeReactCompilerOptions(\n value: true | ReactCompilerOptions,\n): NormalizedReactCompilerOptions {\n const options = value === true ? {} : value;\n const mode = options.mode || \"infer\";\n\n if (mode !== \"infer\" && mode !== \"annotation\") {\n throw new TypeError(`Unknown React compiler mode: ${String(mode)}`);\n }\n\n if (options.directive !== undefined && mode !== \"annotation\") {\n throw new TypeError(\"The React compiler directive can only be configured in annotation mode.\");\n }\n\n const directive = options.directive?.trim() || DEFAULT_COMPILER_DIRECTIVE;\n const onUnsupported = options.onUnsupported || \"fallback\";\n if (!([\"fallback\", \"warn\", \"error\"] as const).includes(onUnsupported)) {\n throw new TypeError(`Unknown unsupported-component behavior: ${String(onUnsupported)}`);\n }\n\n return { mode, directive, onUnsupported };\n}\n\nconst REACT_RENDERER: Readonly<FarmRenderer> = Object.freeze({\n name: \"react\",\n vite: \"@farm.js/react/vite\",\n server: \"@farm.js/react/server\",\n client: \"@farm.js/react/client\",\n jsxImportSource: \"react\",\n dedupe: [\"react\", \"react-dom\", \"react/jsx-runtime\", \"react/jsx-dev-runtime\"],\n optimizeDeps: [\n \"react\",\n \"react-dom\",\n \"react-dom/client\",\n \"react/jsx-runtime\",\n \"react/jsx-dev-runtime\",\n \"@farm.js/react/compiler-runtime\",\n ],\n capabilities: {\n streaming: { node: true, web: false },\n },\n});\n\n/** Select React and optionally enable Farm's experimental AOT compiler. */\nexport function react(options: ReactRendererOptions = {}): FarmRenderer {\n const compiler = options.experimental?.compiler;\n const normalizedCompiler = compiler ? normalizeReactCompilerOptions(compiler) : false;\n\n return {\n ...REACT_RENDERER,\n dedupe: [...(REACT_RENDERER.dedupe || [])],\n optimizeDeps: [...(REACT_RENDERER.optimizeDeps || [])],\n capabilities: {\n streaming: { ...REACT_RENDERER.capabilities?.streaming },\n },\n options: {\n experimental: { compiler: normalizedCompiler },\n },\n };\n}\n\nexport { REACT_RENDERER };\nexport type { FarmRenderer } from \"@farm.js/core/renderer\";\n"]}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { FarmRenderer } from '@farm.js/core/renderer';
|
|
2
|
+
export { FarmRenderer } from '@farm.js/core/renderer';
|
|
3
|
+
|
|
4
|
+
type ReactCompilerMode = "infer" | "annotation";
|
|
5
|
+
type UnsupportedCompilerBehavior = "fallback" | "warn" | "error";
|
|
6
|
+
interface ReactCompilerOptions {
|
|
7
|
+
/** Compile every component that the safe subset can prove eligible. */
|
|
8
|
+
mode?: ReactCompilerMode;
|
|
9
|
+
/** Function or module directive used only by annotation mode. */
|
|
10
|
+
directive?: string;
|
|
11
|
+
/** What to do when a selected component is outside the safe subset. */
|
|
12
|
+
onUnsupported?: UnsupportedCompilerBehavior;
|
|
13
|
+
}
|
|
14
|
+
interface ReactRendererOptions {
|
|
15
|
+
experimental?: {
|
|
16
|
+
/** `true` enables automatic inference; an object customizes selection. */
|
|
17
|
+
compiler?: boolean | ReactCompilerOptions;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
interface NormalizedReactCompilerOptions {
|
|
21
|
+
mode: ReactCompilerMode;
|
|
22
|
+
directive: string;
|
|
23
|
+
onUnsupported: UnsupportedCompilerBehavior;
|
|
24
|
+
}
|
|
25
|
+
declare const DEFAULT_COMPILER_DIRECTIVE = "use compiler";
|
|
26
|
+
declare function normalizeReactCompilerOptions(value: true | ReactCompilerOptions): NormalizedReactCompilerOptions;
|
|
27
|
+
declare const REACT_RENDERER: Readonly<FarmRenderer>;
|
|
28
|
+
/** Select React and optionally enable Farm's experimental AOT compiler. */
|
|
29
|
+
declare function react(options?: ReactRendererOptions): FarmRenderer;
|
|
30
|
+
|
|
31
|
+
export { DEFAULT_COMPILER_DIRECTIVE, type NormalizedReactCompilerOptions, REACT_RENDERER, type ReactCompilerMode, type ReactCompilerOptions, type ReactRendererOptions, type UnsupportedCompilerBehavior, normalizeReactCompilerOptions, react };
|