@farm.js/react 0.1.0-beta.0 → 0.1.0-beta.10

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/index.cjs CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  // src/index.ts
4
4
  var DEFAULT_COMPILER_DIRECTIVE = "use compiler";
5
+ var DEFAULT_COMPILER_REPORT_FILE = ".farm/react-compiler.json";
6
+ function normalizeCompilerReportFile(value) {
7
+ if (value === void 0) return DEFAULT_COMPILER_REPORT_FILE;
8
+ if (typeof value !== "string" || !value.trim()) {
9
+ throw new TypeError("The React compiler report file must be a non-empty relative path.");
10
+ }
11
+ const normalized = value.trim().replace(/\\/g, "/");
12
+ if (normalized.startsWith("/") || /^[A-Za-z]:\//.test(normalized) || normalized.split("/").includes("..")) {
13
+ throw new TypeError("The React compiler report file must stay inside the project root.");
14
+ }
15
+ return normalized;
16
+ }
5
17
  function normalizeReactCompilerOptions(value) {
6
18
  const options = value === true ? {} : value;
7
19
  const mode = options.mode || "infer";
@@ -16,7 +28,21 @@ function normalizeReactCompilerOptions(value) {
16
28
  if (!["fallback", "warn", "error"].includes(onUnsupported)) {
17
29
  throw new TypeError(`Unknown unsupported-component behavior: ${String(onUnsupported)}`);
18
30
  }
19
- return { mode, directive, onUnsupported };
31
+ const reactivity = options.reactivity || "hybrid";
32
+ if (reactivity !== "static" && reactivity !== "hybrid") {
33
+ throw new TypeError(`Unknown React compiler reactivity mode: ${String(reactivity)}`);
34
+ }
35
+ if (options.report !== void 0 && typeof options.report !== "boolean") {
36
+ throw new TypeError("The React compiler report option must be a boolean.");
37
+ }
38
+ if (options.report === false && options.reportFile !== void 0) {
39
+ throw new TypeError(
40
+ "A React compiler report file cannot be configured when reporting is false."
41
+ );
42
+ }
43
+ const reportFile = normalizeCompilerReportFile(options.reportFile);
44
+ const report = options.report === true || options.reportFile !== void 0;
45
+ return { mode, directive, onUnsupported, reactivity, report, reportFile };
20
46
  }
21
47
  var REACT_RENDERER = Object.freeze({
22
48
  name: "react",
@@ -54,6 +80,7 @@ function react(options = {}) {
54
80
  }
55
81
 
56
82
  exports.DEFAULT_COMPILER_DIRECTIVE = DEFAULT_COMPILER_DIRECTIVE;
83
+ exports.DEFAULT_COMPILER_REPORT_FILE = DEFAULT_COMPILER_REPORT_FILE;
57
84
  exports.REACT_RENDERER = REACT_RENDERER;
58
85
  exports.normalizeReactCompilerOptions = normalizeReactCompilerOptions;
59
86
  exports.react = react;
@@ -1 +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"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["import type { FarmRenderer } from \"@farm.js/core/renderer\";\n\nexport type ReactCompilerMode = \"infer\" | \"annotation\";\nexport type ReactCompilerReactivity = \"static\" | \"hybrid\";\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 * How compiled bindings subscribe to state. `hybrid` keeps compiler-proven\n * dependencies and narrows short-circuited reads at runtime.\n */\n reactivity?: ReactCompilerReactivity;\n /** Write a machine-readable compiler coverage report after a production build. */\n report?: boolean;\n /** Project-relative report location. Providing it also enables reporting. */\n reportFile?: string;\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 reactivity: ReactCompilerReactivity;\n report: boolean;\n reportFile: string;\n}\n\nexport const DEFAULT_COMPILER_DIRECTIVE = \"use compiler\";\nexport const DEFAULT_COMPILER_REPORT_FILE = \".farm/react-compiler.json\";\n\nfunction normalizeCompilerReportFile(value: unknown): string {\n if (value === undefined) return DEFAULT_COMPILER_REPORT_FILE;\n if (typeof value !== \"string\" || !value.trim()) {\n throw new TypeError(\"The React compiler report file must be a non-empty relative path.\");\n }\n const normalized = value.trim().replace(/\\\\/g, \"/\");\n if (\n normalized.startsWith(\"/\") ||\n /^[A-Za-z]:\\//.test(normalized) ||\n normalized.split(\"/\").includes(\"..\")\n ) {\n throw new TypeError(\"The React compiler report file must stay inside the project root.\");\n }\n return normalized;\n}\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 const reactivity = options.reactivity || \"hybrid\";\n if (reactivity !== \"static\" && reactivity !== \"hybrid\") {\n throw new TypeError(`Unknown React compiler reactivity mode: ${String(reactivity)}`);\n }\n\n if (options.report !== undefined && typeof options.report !== \"boolean\") {\n throw new TypeError(\"The React compiler report option must be a boolean.\");\n }\n if (options.report === false && options.reportFile !== undefined) {\n throw new TypeError(\n \"A React compiler report file cannot be configured when reporting is false.\",\n );\n }\n const reportFile = normalizeCompilerReportFile(options.reportFile);\n const report = options.report === true || options.reportFile !== undefined;\n\n return { mode, directive, onUnsupported, reactivity, report, reportFile };\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 CHANGED
@@ -2,6 +2,7 @@ import { FarmRenderer } from '@farm.js/core/renderer';
2
2
  export { FarmRenderer } from '@farm.js/core/renderer';
3
3
 
4
4
  type ReactCompilerMode = "infer" | "annotation";
5
+ type ReactCompilerReactivity = "static" | "hybrid";
5
6
  type UnsupportedCompilerBehavior = "fallback" | "warn" | "error";
6
7
  interface ReactCompilerOptions {
7
8
  /** Compile every component that the safe subset can prove eligible. */
@@ -10,6 +11,15 @@ interface ReactCompilerOptions {
10
11
  directive?: string;
11
12
  /** What to do when a selected component is outside the safe subset. */
12
13
  onUnsupported?: UnsupportedCompilerBehavior;
14
+ /**
15
+ * How compiled bindings subscribe to state. `hybrid` keeps compiler-proven
16
+ * dependencies and narrows short-circuited reads at runtime.
17
+ */
18
+ reactivity?: ReactCompilerReactivity;
19
+ /** Write a machine-readable compiler coverage report after a production build. */
20
+ report?: boolean;
21
+ /** Project-relative report location. Providing it also enables reporting. */
22
+ reportFile?: string;
13
23
  }
14
24
  interface ReactRendererOptions {
15
25
  experimental?: {
@@ -21,11 +31,15 @@ interface NormalizedReactCompilerOptions {
21
31
  mode: ReactCompilerMode;
22
32
  directive: string;
23
33
  onUnsupported: UnsupportedCompilerBehavior;
34
+ reactivity: ReactCompilerReactivity;
35
+ report: boolean;
36
+ reportFile: string;
24
37
  }
25
38
  declare const DEFAULT_COMPILER_DIRECTIVE = "use compiler";
39
+ declare const DEFAULT_COMPILER_REPORT_FILE = ".farm/react-compiler.json";
26
40
  declare function normalizeReactCompilerOptions(value: true | ReactCompilerOptions): NormalizedReactCompilerOptions;
27
41
  declare const REACT_RENDERER: Readonly<FarmRenderer>;
28
42
  /** Select React and optionally enable Farm's experimental AOT compiler. */
29
43
  declare function react(options?: ReactRendererOptions): FarmRenderer;
30
44
 
31
- export { DEFAULT_COMPILER_DIRECTIVE, type NormalizedReactCompilerOptions, REACT_RENDERER, type ReactCompilerMode, type ReactCompilerOptions, type ReactRendererOptions, type UnsupportedCompilerBehavior, normalizeReactCompilerOptions, react };
45
+ export { DEFAULT_COMPILER_DIRECTIVE, DEFAULT_COMPILER_REPORT_FILE, type NormalizedReactCompilerOptions, REACT_RENDERER, type ReactCompilerMode, type ReactCompilerOptions, type ReactCompilerReactivity, type ReactRendererOptions, type UnsupportedCompilerBehavior, normalizeReactCompilerOptions, react };
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ import { FarmRenderer } from '@farm.js/core/renderer';
2
2
  export { FarmRenderer } from '@farm.js/core/renderer';
3
3
 
4
4
  type ReactCompilerMode = "infer" | "annotation";
5
+ type ReactCompilerReactivity = "static" | "hybrid";
5
6
  type UnsupportedCompilerBehavior = "fallback" | "warn" | "error";
6
7
  interface ReactCompilerOptions {
7
8
  /** Compile every component that the safe subset can prove eligible. */
@@ -10,6 +11,15 @@ interface ReactCompilerOptions {
10
11
  directive?: string;
11
12
  /** What to do when a selected component is outside the safe subset. */
12
13
  onUnsupported?: UnsupportedCompilerBehavior;
14
+ /**
15
+ * How compiled bindings subscribe to state. `hybrid` keeps compiler-proven
16
+ * dependencies and narrows short-circuited reads at runtime.
17
+ */
18
+ reactivity?: ReactCompilerReactivity;
19
+ /** Write a machine-readable compiler coverage report after a production build. */
20
+ report?: boolean;
21
+ /** Project-relative report location. Providing it also enables reporting. */
22
+ reportFile?: string;
13
23
  }
14
24
  interface ReactRendererOptions {
15
25
  experimental?: {
@@ -21,11 +31,15 @@ interface NormalizedReactCompilerOptions {
21
31
  mode: ReactCompilerMode;
22
32
  directive: string;
23
33
  onUnsupported: UnsupportedCompilerBehavior;
34
+ reactivity: ReactCompilerReactivity;
35
+ report: boolean;
36
+ reportFile: string;
24
37
  }
25
38
  declare const DEFAULT_COMPILER_DIRECTIVE = "use compiler";
39
+ declare const DEFAULT_COMPILER_REPORT_FILE = ".farm/react-compiler.json";
26
40
  declare function normalizeReactCompilerOptions(value: true | ReactCompilerOptions): NormalizedReactCompilerOptions;
27
41
  declare const REACT_RENDERER: Readonly<FarmRenderer>;
28
42
  /** Select React and optionally enable Farm's experimental AOT compiler. */
29
43
  declare function react(options?: ReactRendererOptions): FarmRenderer;
30
44
 
31
- export { DEFAULT_COMPILER_DIRECTIVE, type NormalizedReactCompilerOptions, REACT_RENDERER, type ReactCompilerMode, type ReactCompilerOptions, type ReactRendererOptions, type UnsupportedCompilerBehavior, normalizeReactCompilerOptions, react };
45
+ export { DEFAULT_COMPILER_DIRECTIVE, DEFAULT_COMPILER_REPORT_FILE, type NormalizedReactCompilerOptions, REACT_RENDERER, type ReactCompilerMode, type ReactCompilerOptions, type ReactCompilerReactivity, type ReactRendererOptions, type UnsupportedCompilerBehavior, normalizeReactCompilerOptions, react };
package/dist/index.mjs CHANGED
@@ -1,5 +1,17 @@
1
1
  // src/index.ts
2
2
  var DEFAULT_COMPILER_DIRECTIVE = "use compiler";
3
+ var DEFAULT_COMPILER_REPORT_FILE = ".farm/react-compiler.json";
4
+ function normalizeCompilerReportFile(value) {
5
+ if (value === void 0) return DEFAULT_COMPILER_REPORT_FILE;
6
+ if (typeof value !== "string" || !value.trim()) {
7
+ throw new TypeError("The React compiler report file must be a non-empty relative path.");
8
+ }
9
+ const normalized = value.trim().replace(/\\/g, "/");
10
+ if (normalized.startsWith("/") || /^[A-Za-z]:\//.test(normalized) || normalized.split("/").includes("..")) {
11
+ throw new TypeError("The React compiler report file must stay inside the project root.");
12
+ }
13
+ return normalized;
14
+ }
3
15
  function normalizeReactCompilerOptions(value) {
4
16
  const options = value === true ? {} : value;
5
17
  const mode = options.mode || "infer";
@@ -14,7 +26,21 @@ function normalizeReactCompilerOptions(value) {
14
26
  if (!["fallback", "warn", "error"].includes(onUnsupported)) {
15
27
  throw new TypeError(`Unknown unsupported-component behavior: ${String(onUnsupported)}`);
16
28
  }
17
- return { mode, directive, onUnsupported };
29
+ const reactivity = options.reactivity || "hybrid";
30
+ if (reactivity !== "static" && reactivity !== "hybrid") {
31
+ throw new TypeError(`Unknown React compiler reactivity mode: ${String(reactivity)}`);
32
+ }
33
+ if (options.report !== void 0 && typeof options.report !== "boolean") {
34
+ throw new TypeError("The React compiler report option must be a boolean.");
35
+ }
36
+ if (options.report === false && options.reportFile !== void 0) {
37
+ throw new TypeError(
38
+ "A React compiler report file cannot be configured when reporting is false."
39
+ );
40
+ }
41
+ const reportFile = normalizeCompilerReportFile(options.reportFile);
42
+ const report = options.report === true || options.reportFile !== void 0;
43
+ return { mode, directive, onUnsupported, reactivity, report, reportFile };
18
44
  }
19
45
  var REACT_RENDERER = Object.freeze({
20
46
  name: "react",
@@ -51,6 +77,6 @@ function react(options = {}) {
51
77
  };
52
78
  }
53
79
 
54
- export { DEFAULT_COMPILER_DIRECTIVE, REACT_RENDERER, normalizeReactCompilerOptions, react };
80
+ export { DEFAULT_COMPILER_DIRECTIVE, DEFAULT_COMPILER_REPORT_FILE, REACT_RENDERER, normalizeReactCompilerOptions, react };
55
81
  //# sourceMappingURL=index.mjs.map
56
82
  //# sourceMappingURL=index.mjs.map
@@ -1 +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.mjs","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"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import type { FarmRenderer } from \"@farm.js/core/renderer\";\n\nexport type ReactCompilerMode = \"infer\" | \"annotation\";\nexport type ReactCompilerReactivity = \"static\" | \"hybrid\";\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 * How compiled bindings subscribe to state. `hybrid` keeps compiler-proven\n * dependencies and narrows short-circuited reads at runtime.\n */\n reactivity?: ReactCompilerReactivity;\n /** Write a machine-readable compiler coverage report after a production build. */\n report?: boolean;\n /** Project-relative report location. Providing it also enables reporting. */\n reportFile?: string;\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 reactivity: ReactCompilerReactivity;\n report: boolean;\n reportFile: string;\n}\n\nexport const DEFAULT_COMPILER_DIRECTIVE = \"use compiler\";\nexport const DEFAULT_COMPILER_REPORT_FILE = \".farm/react-compiler.json\";\n\nfunction normalizeCompilerReportFile(value: unknown): string {\n if (value === undefined) return DEFAULT_COMPILER_REPORT_FILE;\n if (typeof value !== \"string\" || !value.trim()) {\n throw new TypeError(\"The React compiler report file must be a non-empty relative path.\");\n }\n const normalized = value.trim().replace(/\\\\/g, \"/\");\n if (\n normalized.startsWith(\"/\") ||\n /^[A-Za-z]:\\//.test(normalized) ||\n normalized.split(\"/\").includes(\"..\")\n ) {\n throw new TypeError(\"The React compiler report file must stay inside the project root.\");\n }\n return normalized;\n}\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 const reactivity = options.reactivity || \"hybrid\";\n if (reactivity !== \"static\" && reactivity !== \"hybrid\") {\n throw new TypeError(`Unknown React compiler reactivity mode: ${String(reactivity)}`);\n }\n\n if (options.report !== undefined && typeof options.report !== \"boolean\") {\n throw new TypeError(\"The React compiler report option must be a boolean.\");\n }\n if (options.report === false && options.reportFile !== undefined) {\n throw new TypeError(\n \"A React compiler report file cannot be configured when reporting is false.\",\n );\n }\n const reportFile = normalizeCompilerReportFile(options.reportFile);\n const report = options.report === true || options.reportFile !== undefined;\n\n return { mode, directive, onUnsupported, reactivity, report, reportFile };\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/list.cjs ADDED
@@ -0,0 +1,44 @@
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/list.tsx
10
+
11
+ // src/iterable.ts
12
+ var oneShotSnapshots = /* @__PURE__ */ new WeakMap();
13
+ function materializeIterable(source) {
14
+ if (source == null) return [];
15
+ const iterator = source[Symbol.iterator]();
16
+ const oneShot = iterator === source && (typeof source === "object" || typeof source === "function");
17
+ if (oneShot) {
18
+ const cached = oneShotSnapshots.get(source);
19
+ if (cached) return cached;
20
+ }
21
+ const items = Array.from({ [Symbol.iterator]: () => iterator });
22
+ if (oneShot) oneShotSnapshots.set(source, items);
23
+ return items;
24
+ }
25
+
26
+ // src/list.tsx
27
+ function List({ each, by, children }) {
28
+ const rows = materializeIterable(each);
29
+ return React__default.default.createElement(
30
+ React__default.default.Fragment,
31
+ null,
32
+ ...rows.map((item, index) => {
33
+ const row = children(item, index);
34
+ if (!React__default.default.isValidElement(row)) {
35
+ throw new TypeError("@farm.js/react List children must return one React element.");
36
+ }
37
+ return React__default.default.cloneElement(row, { key: by(item, index) });
38
+ })
39
+ );
40
+ }
41
+
42
+ exports.List = List;
43
+ //# sourceMappingURL=list.cjs.map
44
+ //# sourceMappingURL=list.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/iterable.ts","../src/list.tsx"],"names":["React"],"mappings":";;;;;;;;;;;AAAA,IAAM,gBAAA,uBAAuB,OAAA,EAAoC;AAG1D,SAAS,oBAA0B,MAAA,EAAmD;AAC3F,EAAA,IAAI,MAAA,IAAU,IAAA,EAAM,OAAO,EAAC;AAE5B,EAAA,MAAM,QAAA,GAAW,MAAA,CAAO,MAAA,CAAO,QAAQ,CAAA,EAAE;AACzC,EAAA,MAAM,UACJ,QAAA,KAAc,MAAA,KACb,OAAO,MAAA,KAAW,QAAA,IAAY,OAAO,MAAA,KAAW,UAAA,CAAA;AACnD,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,MAAM,MAAA,GAAS,gBAAA,CAAiB,GAAA,CAAI,MAAgB,CAAA;AACpD,IAAA,IAAI,QAAQ,OAAO,MAAA;AAAA,EACrB;AAEA,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,IAAA,CAAK,EAAE,CAAC,OAAO,QAAQ,GAAG,MAAM,QAAA,EAAU,CAAA;AAC9D,EAAA,IAAI,OAAA,EAAS,gBAAA,CAAiB,GAAA,CAAI,MAAA,EAAkB,KAAK,CAAA;AACzD,EAAA,OAAO,KAAA;AACT;;;ACCO,SAAS,IAAA,CAAW,EAAE,IAAA,EAAM,EAAA,EAAI,UAAS,EAAwC;AACtF,EAAA,MAAM,IAAA,GAAO,oBAAoB,IAAI,CAAA;AACrC,EAAA,OAAOA,sBAAA,CAAM,aAAA;AAAA,IACXA,sBAAA,CAAM,QAAA;AAAA,IACN,IAAA;AAAA,IACA,GAAG,IAAA,CAAK,GAAA,CAAI,CAAC,MAAM,KAAA,KAAU;AAC3B,MAAA,MAAM,GAAA,GAAM,QAAA,CAAS,IAAA,EAAM,KAAK,CAAA;AAChC,MAAA,IAAI,CAACA,sBAAA,CAAM,cAAA,CAAe,GAAG,CAAA,EAAG;AAC9B,QAAA,MAAM,IAAI,UAAU,6DAA6D,CAAA;AAAA,MACnF;AACA,MAAA,OAAOA,sBAAA,CAAM,aAAa,GAAA,EAAK,EAAE,KAAK,EAAA,CAAG,IAAA,EAAM,KAAK,CAAA,EAAuB,CAAA;AAAA,IAC7E,CAAC;AAAA,GACH;AACF","file":"list.cjs","sourcesContent":["const oneShotSnapshots = new WeakMap<object, readonly unknown[]>();\n\n/** Materialize an iterable without consuming a one-shot iterator more than once. */\nexport function materializeIterable<Item>(source: Iterable<Item> | null | undefined): Item[] {\n if (source == null) return [];\n\n const iterator = source[Symbol.iterator]();\n const oneShot =\n iterator === (source as unknown) &&\n (typeof source === \"object\" || typeof source === \"function\");\n if (oneShot) {\n const cached = oneShotSnapshots.get(source as object);\n if (cached) return cached as Item[];\n }\n\n const items = Array.from({ [Symbol.iterator]: () => iterator });\n if (oneShot) oneShotSnapshots.set(source as object, items);\n return items;\n}\n","import React from \"react\";\nimport { materializeIterable } from \"./iterable\";\n\nexport interface ListProps<Item> {\n /** Items to render. Nullish collections are treated as empty. */\n each: Iterable<Item> | null | undefined;\n /** Returns the stable React key for one item. */\n by(item: Item, index: number): React.Key;\n /** Renders one keyed row. */\n children(item: Item, index: number): React.ReactElement;\n}\n\n/**\n * An explicit keyed collection boundary for advanced list expressions.\n *\n * It behaves like ordinary React when the compiler is disabled. With the\n * experimental compiler enabled, eligible usages are isolated so local list\n * updates do not execute the surrounding user component.\n */\nexport function List<Item>({ each, by, children }: ListProps<Item>): React.ReactElement {\n const rows = materializeIterable(each);\n return React.createElement(\n React.Fragment,\n null,\n ...rows.map((item, index) => {\n const row = children(item, index);\n if (!React.isValidElement(row)) {\n throw new TypeError(\"@farm.js/react List children must return one React element.\");\n }\n return React.cloneElement(row, { key: by(item, index) } as React.Attributes);\n }),\n );\n}\n"]}
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+
3
+ interface ListProps<Item> {
4
+ /** Items to render. Nullish collections are treated as empty. */
5
+ each: Iterable<Item> | null | undefined;
6
+ /** Returns the stable React key for one item. */
7
+ by(item: Item, index: number): React.Key;
8
+ /** Renders one keyed row. */
9
+ children(item: Item, index: number): React.ReactElement;
10
+ }
11
+ /**
12
+ * An explicit keyed collection boundary for advanced list expressions.
13
+ *
14
+ * It behaves like ordinary React when the compiler is disabled. With the
15
+ * experimental compiler enabled, eligible usages are isolated so local list
16
+ * updates do not execute the surrounding user component.
17
+ */
18
+ declare function List<Item>({ each, by, children }: ListProps<Item>): React.ReactElement;
19
+
20
+ export { List, type ListProps };
package/dist/list.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+
3
+ interface ListProps<Item> {
4
+ /** Items to render. Nullish collections are treated as empty. */
5
+ each: Iterable<Item> | null | undefined;
6
+ /** Returns the stable React key for one item. */
7
+ by(item: Item, index: number): React.Key;
8
+ /** Renders one keyed row. */
9
+ children(item: Item, index: number): React.ReactElement;
10
+ }
11
+ /**
12
+ * An explicit keyed collection boundary for advanced list expressions.
13
+ *
14
+ * It behaves like ordinary React when the compiler is disabled. With the
15
+ * experimental compiler enabled, eligible usages are isolated so local list
16
+ * updates do not execute the surrounding user component.
17
+ */
18
+ declare function List<Item>({ each, by, children }: ListProps<Item>): React.ReactElement;
19
+
20
+ export { List, type ListProps };
package/dist/list.mjs ADDED
@@ -0,0 +1,38 @@
1
+ import React from 'react';
2
+
3
+ // src/list.tsx
4
+
5
+ // src/iterable.ts
6
+ var oneShotSnapshots = /* @__PURE__ */ new WeakMap();
7
+ function materializeIterable(source) {
8
+ if (source == null) return [];
9
+ const iterator = source[Symbol.iterator]();
10
+ const oneShot = iterator === source && (typeof source === "object" || typeof source === "function");
11
+ if (oneShot) {
12
+ const cached = oneShotSnapshots.get(source);
13
+ if (cached) return cached;
14
+ }
15
+ const items = Array.from({ [Symbol.iterator]: () => iterator });
16
+ if (oneShot) oneShotSnapshots.set(source, items);
17
+ return items;
18
+ }
19
+
20
+ // src/list.tsx
21
+ function List({ each, by, children }) {
22
+ const rows = materializeIterable(each);
23
+ return React.createElement(
24
+ React.Fragment,
25
+ null,
26
+ ...rows.map((item, index) => {
27
+ const row = children(item, index);
28
+ if (!React.isValidElement(row)) {
29
+ throw new TypeError("@farm.js/react List children must return one React element.");
30
+ }
31
+ return React.cloneElement(row, { key: by(item, index) });
32
+ })
33
+ );
34
+ }
35
+
36
+ export { List };
37
+ //# sourceMappingURL=list.mjs.map
38
+ //# sourceMappingURL=list.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/iterable.ts","../src/list.tsx"],"names":[],"mappings":";;;;;AAAA,IAAM,gBAAA,uBAAuB,OAAA,EAAoC;AAG1D,SAAS,oBAA0B,MAAA,EAAmD;AAC3F,EAAA,IAAI,MAAA,IAAU,IAAA,EAAM,OAAO,EAAC;AAE5B,EAAA,MAAM,QAAA,GAAW,MAAA,CAAO,MAAA,CAAO,QAAQ,CAAA,EAAE;AACzC,EAAA,MAAM,UACJ,QAAA,KAAc,MAAA,KACb,OAAO,MAAA,KAAW,QAAA,IAAY,OAAO,MAAA,KAAW,UAAA,CAAA;AACnD,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,MAAM,MAAA,GAAS,gBAAA,CAAiB,GAAA,CAAI,MAAgB,CAAA;AACpD,IAAA,IAAI,QAAQ,OAAO,MAAA;AAAA,EACrB;AAEA,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,IAAA,CAAK,EAAE,CAAC,OAAO,QAAQ,GAAG,MAAM,QAAA,EAAU,CAAA;AAC9D,EAAA,IAAI,OAAA,EAAS,gBAAA,CAAiB,GAAA,CAAI,MAAA,EAAkB,KAAK,CAAA;AACzD,EAAA,OAAO,KAAA;AACT;;;ACCO,SAAS,IAAA,CAAW,EAAE,IAAA,EAAM,EAAA,EAAI,UAAS,EAAwC;AACtF,EAAA,MAAM,IAAA,GAAO,oBAAoB,IAAI,CAAA;AACrC,EAAA,OAAO,KAAA,CAAM,aAAA;AAAA,IACX,KAAA,CAAM,QAAA;AAAA,IACN,IAAA;AAAA,IACA,GAAG,IAAA,CAAK,GAAA,CAAI,CAAC,MAAM,KAAA,KAAU;AAC3B,MAAA,MAAM,GAAA,GAAM,QAAA,CAAS,IAAA,EAAM,KAAK,CAAA;AAChC,MAAA,IAAI,CAAC,KAAA,CAAM,cAAA,CAAe,GAAG,CAAA,EAAG;AAC9B,QAAA,MAAM,IAAI,UAAU,6DAA6D,CAAA;AAAA,MACnF;AACA,MAAA,OAAO,KAAA,CAAM,aAAa,GAAA,EAAK,EAAE,KAAK,EAAA,CAAG,IAAA,EAAM,KAAK,CAAA,EAAuB,CAAA;AAAA,IAC7E,CAAC;AAAA,GACH;AACF","file":"list.mjs","sourcesContent":["const oneShotSnapshots = new WeakMap<object, readonly unknown[]>();\n\n/** Materialize an iterable without consuming a one-shot iterator more than once. */\nexport function materializeIterable<Item>(source: Iterable<Item> | null | undefined): Item[] {\n if (source == null) return [];\n\n const iterator = source[Symbol.iterator]();\n const oneShot =\n iterator === (source as unknown) &&\n (typeof source === \"object\" || typeof source === \"function\");\n if (oneShot) {\n const cached = oneShotSnapshots.get(source as object);\n if (cached) return cached as Item[];\n }\n\n const items = Array.from({ [Symbol.iterator]: () => iterator });\n if (oneShot) oneShotSnapshots.set(source as object, items);\n return items;\n}\n","import React from \"react\";\nimport { materializeIterable } from \"./iterable\";\n\nexport interface ListProps<Item> {\n /** Items to render. Nullish collections are treated as empty. */\n each: Iterable<Item> | null | undefined;\n /** Returns the stable React key for one item. */\n by(item: Item, index: number): React.Key;\n /** Renders one keyed row. */\n children(item: Item, index: number): React.ReactElement;\n}\n\n/**\n * An explicit keyed collection boundary for advanced list expressions.\n *\n * It behaves like ordinary React when the compiler is disabled. With the\n * experimental compiler enabled, eligible usages are isolated so local list\n * updates do not execute the surrounding user component.\n */\nexport function List<Item>({ each, by, children }: ListProps<Item>): React.ReactElement {\n const rows = materializeIterable(each);\n return React.createElement(\n React.Fragment,\n null,\n ...rows.map((item, index) => {\n const row = children(item, index);\n if (!React.isValidElement(row)) {\n throw new TypeError(\"@farm.js/react List children must return one React element.\");\n }\n return React.cloneElement(row, { key: by(item, index) } as React.Attributes);\n }),\n );\n}\n"]}