@farm.js/core 0.1.0-beta.33 → 0.1.0-beta.34

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.
Files changed (59) hide show
  1. package/dist/{chunk-GKEYR7EK.mjs → chunk-4EHFJHPN.mjs} +2 -2
  2. package/dist/{chunk-GKEYR7EK.mjs.map → chunk-4EHFJHPN.mjs.map} +1 -1
  3. package/dist/{chunk-EL644GWT.mjs → chunk-7JLDC7IO.mjs} +17 -4
  4. package/dist/chunk-7JLDC7IO.mjs.map +1 -0
  5. package/dist/{chunk-QGRLI3KV.mjs → chunk-AVP2HHCL.mjs} +2 -2
  6. package/dist/{chunk-5PDVNNUQ.mjs → chunk-BNTDKO7T.mjs} +8 -4
  7. package/dist/chunk-BNTDKO7T.mjs.map +1 -0
  8. package/dist/{chunk-DV5ZT2JO.mjs → chunk-DGEPZFH3.mjs} +4 -4
  9. package/dist/{chunk-NETDSCXV.mjs → chunk-IU42657J.mjs} +2 -2
  10. package/dist/{chunk-4TI6B4AY.mjs → chunk-UMGOTX4G.mjs} +220 -154
  11. package/dist/chunk-UMGOTX4G.mjs.map +1 -0
  12. package/dist/client/lifecycle.mjs +2 -2
  13. package/dist/client-plugins.cjs +1 -1
  14. package/dist/client-plugins.cjs.map +1 -1
  15. package/dist/client-plugins.mjs +2 -2
  16. package/dist/client.cjs +1 -1
  17. package/dist/client.cjs.map +1 -1
  18. package/dist/client.mjs +2 -2
  19. package/dist/{devtools-BF6URGGF.mjs → devtools-G4S3JRIH.mjs} +3 -3
  20. package/dist/docs.cjs +13 -1
  21. package/dist/docs.cjs.map +1 -1
  22. package/dist/docs.mjs +3 -3
  23. package/dist/index.cjs +437 -352
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.mjs +7 -7
  26. package/dist/internal/build-runtime.cjs +414 -329
  27. package/dist/internal/build-runtime.cjs.map +1 -1
  28. package/dist/internal/build-runtime.mjs +6 -6
  29. package/dist/internal/client-runtime.cjs +1 -1
  30. package/dist/internal/client-runtime.cjs.map +1 -1
  31. package/dist/internal/client-runtime.mjs +2 -2
  32. package/dist/internal/config-runtime.cjs +17 -3
  33. package/dist/internal/config-runtime.cjs.map +1 -1
  34. package/dist/internal/config-runtime.mjs +2 -2
  35. package/dist/plugin.cjs +16 -3
  36. package/dist/plugin.cjs.map +1 -1
  37. package/dist/plugin.mjs +3 -3
  38. package/dist/renderer.cjs +7 -3
  39. package/dist/renderer.cjs.map +1 -1
  40. package/dist/renderer.d.mts +9 -0
  41. package/dist/renderer.d.ts +9 -0
  42. package/dist/renderer.mjs +1 -1
  43. package/dist/server.cjs +23 -6
  44. package/dist/server.cjs.map +1 -1
  45. package/dist/server.mjs +4 -4
  46. package/dist/version.cjs +1 -1
  47. package/dist/version.cjs.map +1 -1
  48. package/dist/version.mjs +1 -1
  49. package/dist/vite.cjs +21 -5
  50. package/dist/vite.cjs.map +1 -1
  51. package/dist/vite.mjs +3 -3
  52. package/package.json +3 -3
  53. package/dist/chunk-4TI6B4AY.mjs.map +0 -1
  54. package/dist/chunk-5PDVNNUQ.mjs.map +0 -1
  55. package/dist/chunk-EL644GWT.mjs.map +0 -1
  56. /package/dist/{chunk-QGRLI3KV.mjs.map → chunk-AVP2HHCL.mjs.map} +0 -0
  57. /package/dist/{chunk-DV5ZT2JO.mjs.map → chunk-DGEPZFH3.mjs.map} +0 -0
  58. /package/dist/{chunk-NETDSCXV.mjs.map → chunk-IU42657J.mjs.map} +0 -0
  59. /package/dist/{devtools-BF6URGGF.mjs.map → devtools-G4S3JRIH.mjs.map} +0 -0
package/dist/plugin.mjs CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  import "./chunk-RQ633A5I.mjs";
7
7
  import {
8
8
  farmPlugin
9
- } from "./chunk-DV5ZT2JO.mjs";
9
+ } from "./chunk-DGEPZFH3.mjs";
10
10
  import "./chunk-XJTDE4L4.mjs";
11
11
  import "./chunk-FEXCU2DR.mjs";
12
12
  import "./chunk-AMZZCRQ7.mjs";
@@ -19,7 +19,7 @@ import "./chunk-USLFXFFH.mjs";
19
19
  import "./chunk-E257KFBU.mjs";
20
20
  import "./chunk-7MABZJIM.mjs";
21
21
  import "./chunk-YW7OBE6Q.mjs";
22
- import "./chunk-5PDVNNUQ.mjs";
22
+ import "./chunk-BNTDKO7T.mjs";
23
23
  import "./chunk-74YTBPTY.mjs";
24
24
  import "./chunk-7ZVN3YZI.mjs";
25
25
  import "./chunk-GY2STC2S.mjs";
@@ -62,7 +62,7 @@ import "./chunk-RBRLLZL5.mjs";
62
62
  import "./chunk-WZ5QFROO.mjs";
63
63
  import "./chunk-7ZMKVETU.mjs";
64
64
  import "./chunk-PCDBGY4A.mjs";
65
- import "./chunk-GKEYR7EK.mjs";
65
+ import "./chunk-4EHFJHPN.mjs";
66
66
  import "./chunk-CGILA3WO.mjs";
67
67
  export {
68
68
  FarmRuntimeShutdownError,
package/dist/renderer.cjs CHANGED
@@ -111,7 +111,8 @@ function resolveFarmRenderer(renderer) {
111
111
  dedupe: [...resolved.dedupe || []],
112
112
  optimizeDeps: [...resolved.optimizeDeps || []],
113
113
  buildConcurrency: resolved.buildConcurrency || "parallel",
114
- capabilities: getFarmRendererCapabilities(resolved)
114
+ capabilities: getFarmRendererCapabilities(resolved),
115
+ options: resolved.options ? { ...resolved.options } : void 0
115
116
  };
116
117
  }
117
118
  __name(resolveFarmRenderer, "resolveFarmRenderer");
@@ -137,7 +138,7 @@ function resolveFarmRendererModule(root, specifier) {
137
138
  }
138
139
  __name(resolveFarmRendererModule, "resolveFarmRendererModule");
139
140
  async function loadFarmRendererVitePlugins(renderer, root, options = {}) {
140
- if (isReactRenderer(renderer)) return [];
141
+ if (renderer.vite === REACT_RENDERER.vite) return [];
141
142
  const modulePath = resolveFarmRendererModule(root, renderer.vite);
142
143
  const rendererModule = await import((0, import_node_url.pathToFileURL)(modulePath).href);
143
144
  if (typeof rendererModule.createFarmRendererPlugin !== "function") {
@@ -145,7 +146,10 @@ async function loadFarmRendererVitePlugins(renderer, root, options = {}) {
145
146
  `Renderer \`${renderer.name}\` module ${renderer.vite} must export createFarmRendererPlugin().`
146
147
  );
147
148
  }
148
- const created = await rendererModule.createFarmRendererPlugin(options);
149
+ const created = await rendererModule.createFarmRendererPlugin({
150
+ ...options,
151
+ rendererOptions: renderer.options
152
+ });
149
153
  if (!created) return [];
150
154
  return Array.isArray(created) ? [...created] : [created];
151
155
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/renderer.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\n/**\n * A rendering-library integration used by Farm's compiler, server renderer,\n * and browser hydration runtime.\n *\n * Renderer descriptors intentionally contain module identifiers instead of\n * implementation functions. This keeps farm.config.ts serializable and lets\n * every module resolve from the application that selected the renderer.\n */\nexport interface FarmRenderer {\n /** Stable public identifier used in diagnostics and generated manifests. */\n name: string;\n /** Module exporting the renderer's Vite plugin factory. */\n vite: string;\n /** Module exporting Farm's server-renderer compatibility contract. */\n server: string;\n /** Module exporting Farm's browser-renderer compatibility contract. */\n client: string;\n /** JSX import source written to generated TypeScript configuration. */\n jsxImportSource?: string;\n /** Additional file extensions used for renderer-owned route components. */\n componentExtensions?: readonly string[];\n /** Packages that must share one module instance in a Farm application. */\n dedupe?: readonly string[];\n /** Renderer packages seeded into Vite's dependency optimizer. */\n optimizeDeps?: readonly string[];\n /**\n * Scheduling policy for the production client and SSR graphs.\n *\n * Most renderer plugins are safe to run in parallel. Renderers whose\n * compiler plugins keep process-global mutable state can opt into serial\n * builds so one graph cannot invalidate the other's transforms.\n */\n buildConcurrency?: \"parallel\" | \"serial\";\n /** Runtime features this renderer intentionally supports. */\n capabilities?: FarmRendererCapabilitiesInput;\n}\n\nexport interface FarmRendererStreamingCapabilities {\n /** Supports Node.js writable streams through renderToPipeableStream(). */\n node: boolean;\n /** Supports WHATWG ReadableStream output through renderToReadableStream(). */\n web: boolean;\n}\n\nexport interface FarmRendererCapabilities {\n streaming: FarmRendererStreamingCapabilities;\n}\n\nexport interface FarmRendererCapabilitiesInput {\n streaming?: Partial<FarmRendererStreamingCapabilities>;\n}\n\nconst DEFAULT_RENDERER_CAPABILITIES: Readonly<FarmRendererCapabilities> = Object.freeze({\n streaming: Object.freeze({ node: false, web: false }),\n});\n\nexport function getFarmRendererCapabilities(\n renderer?: Pick<FarmRenderer, \"capabilities\">,\n): FarmRendererCapabilities {\n return {\n streaming: {\n node: renderer?.capabilities?.streaming?.node ?? DEFAULT_RENDERER_CAPABILITIES.streaming.node,\n web: renderer?.capabilities?.streaming?.web ?? DEFAULT_RENDERER_CAPABILITIES.streaming.web,\n },\n };\n}\n\nexport const FARM_COMPONENT_EXTENSIONS = [\".ts\", \".tsx\", \".js\", \".jsx\"] as const;\n\nexport function resolveFarmComponentExtensions(extensions: readonly string[] = []): string[] {\n return Array.from(\n new Set(\n [...FARM_COMPONENT_EXTENSIONS, ...extensions].map((extension) => {\n const normalized = extension.trim().toLowerCase();\n return normalized.startsWith(\".\") ? normalized : `.${normalized}`;\n }),\n ),\n ).filter((extension) => extension.length > 1);\n}\n\nexport function getFarmRendererComponentExtensions(\n renderer?: Pick<FarmRenderer, \"componentExtensions\">,\n): string[] {\n return resolveFarmComponentExtensions(renderer?.componentExtensions);\n}\n\nexport interface FarmRendererViteModule {\n createFarmRendererPlugin(options?: {\n ssr?: boolean;\n }): unknown | readonly unknown[] | Promise<unknown | readonly unknown[]>;\n}\n\nexport interface FarmServerRendererRuntime {\n readonly name: string;\n readonly Fragment: unknown;\n readonly Suspense: unknown;\n createElement(type: unknown, props?: unknown, ...children: unknown[]): unknown;\n isValidElement(value: unknown): boolean;\n renderToString(element: unknown): string | Promise<string>;\n /** Optional runtime copy of the descriptor capabilities for diagnostics. */\n readonly capabilities?: FarmRendererCapabilities;\n /** Optional bootstrap required before this renderer hydrates server markup. */\n generateHydrationScript?: () => string;\n /** Optional component used to render route-level failures. */\n ErrorBoundary?: unknown;\n /** Optional streaming primitive. Renderers without one use buffered SSR. */\n renderToPipeableStream?: (\n element: unknown,\n callbacks: {\n onShellReady(): void;\n onShellError(error: unknown): void;\n onError(error: unknown): void;\n },\n ) => { pipe(destination: NodeJS.WritableStream): void };\n /** WHATWG streaming primitive used by Web-stream-capable renderers. */\n renderToReadableStream?: (\n element: unknown,\n ) => ReadableStream<Uint8Array | string> | Promise<ReadableStream<Uint8Array | string>>;\n}\n\nexport const REACT_RENDERER: Readonly<FarmRenderer> = Object.freeze({\n name: \"react\",\n vite: \"@farm.js/core/renderer/react/vite\",\n server: \"@farm.js/core/renderer/react/server\",\n client: \"@farm.js/core/renderer/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 ],\n capabilities: {\n streaming: { node: true, web: false },\n },\n});\n\nexport function defineRenderer<const TRenderer extends FarmRenderer>(\n renderer: TRenderer,\n): TRenderer {\n return renderer;\n}\n\nexport function resolveFarmRenderer(renderer?: FarmRenderer): FarmRenderer {\n const resolved = renderer || REACT_RENDERER;\n const fields = [\"name\", \"vite\", \"server\", \"client\"] as const;\n\n for (const field of fields) {\n if (typeof resolved[field] !== \"string\" || resolved[field].trim().length === 0) {\n throw new TypeError(`Farm renderer \\`${field}\\` must be a non-empty string.`);\n }\n }\n\n return {\n ...resolved,\n componentExtensions: [...(resolved.componentExtensions || [])],\n dedupe: [...(resolved.dedupe || [])],\n optimizeDeps: [...(resolved.optimizeDeps || [])],\n buildConcurrency: resolved.buildConcurrency || \"parallel\",\n capabilities: getFarmRendererCapabilities(resolved),\n };\n}\n\nexport async function readFarmRendererWebStream(\n stream: ReadableStream<Uint8Array | string>,\n): Promise<string> {\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n let html = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n html += typeof value === \"string\" ? value : decoder.decode(value, { stream: true });\n }\n\n return html + decoder.decode();\n}\n\nexport function isReactRenderer(renderer: Pick<FarmRenderer, \"name\"> | undefined): boolean {\n return !renderer || renderer.name === \"react\";\n}\n\n/** Resolve an optional renderer module from the application's dependency graph. */\nexport function resolveFarmRendererModule(root: string, specifier: string): string {\n const requireFromApp = createRequire(path.join(path.resolve(root), \"package.json\"));\n return requireFromApp.resolve(specifier);\n}\n\nexport async function loadFarmRendererVitePlugins(\n renderer: FarmRenderer,\n root: string,\n options: { ssr?: boolean } = {},\n): Promise<unknown[]> {\n // React uses Vite's default automatic JSX transform today. Keep the legacy\n // path dependency-free and avoid resolving Farm's own built package while\n // running directly from source in the monorepo.\n if (isReactRenderer(renderer)) return [];\n\n const modulePath = resolveFarmRendererModule(root, renderer.vite);\n const rendererModule = (await import(pathToFileURL(modulePath).href)) as FarmRendererViteModule;\n\n if (typeof rendererModule.createFarmRendererPlugin !== \"function\") {\n throw new Error(\n `Renderer \\`${renderer.name}\\` module ${renderer.vite} must export createFarmRendererPlugin().`,\n );\n }\n\n const created = await rendererModule.createFarmRendererPlugin(options);\n if (!created) return [];\n return Array.isArray(created) ? [...created] : [created];\n}\n"],"mappings":"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","names":["path"]}
1
+ {"version":3,"sources":["../src/renderer.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\n/**\n * A rendering-library integration used by Farm's compiler, server renderer,\n * and browser hydration runtime.\n *\n * Renderer descriptors intentionally contain module identifiers instead of\n * implementation functions. This keeps farm.config.ts serializable and lets\n * every module resolve from the application that selected the renderer.\n */\nexport interface FarmRenderer {\n /** Stable public identifier used in diagnostics and generated manifests. */\n name: string;\n /** Module exporting the renderer's Vite plugin factory. */\n vite: string;\n /** Module exporting Farm's server-renderer compatibility contract. */\n server: string;\n /** Module exporting Farm's browser-renderer compatibility contract. */\n client: string;\n /** JSX import source written to generated TypeScript configuration. */\n jsxImportSource?: string;\n /** Additional file extensions used for renderer-owned route components. */\n componentExtensions?: readonly string[];\n /** Packages that must share one module instance in a Farm application. */\n dedupe?: readonly string[];\n /** Renderer packages seeded into Vite's dependency optimizer. */\n optimizeDeps?: readonly string[];\n /**\n * Scheduling policy for the production client and SSR graphs.\n *\n * Most renderer plugins are safe to run in parallel. Renderers whose\n * compiler plugins keep process-global mutable state can opt into serial\n * builds so one graph cannot invalidate the other's transforms.\n */\n buildConcurrency?: \"parallel\" | \"serial\";\n /** Runtime features this renderer intentionally supports. */\n capabilities?: FarmRendererCapabilitiesInput;\n /**\n * Serializable options consumed by the renderer's Vite integration.\n *\n * Keeping renderer-owned configuration on the descriptor lets one rendering\n * library expose multiple compiler modes without teaching Farm's core about\n * each option.\n */\n options?: Readonly<Record<string, unknown>>;\n}\n\nexport interface FarmRendererStreamingCapabilities {\n /** Supports Node.js writable streams through renderToPipeableStream(). */\n node: boolean;\n /** Supports WHATWG ReadableStream output through renderToReadableStream(). */\n web: boolean;\n}\n\nexport interface FarmRendererCapabilities {\n streaming: FarmRendererStreamingCapabilities;\n}\n\nexport interface FarmRendererCapabilitiesInput {\n streaming?: Partial<FarmRendererStreamingCapabilities>;\n}\n\nconst DEFAULT_RENDERER_CAPABILITIES: Readonly<FarmRendererCapabilities> = Object.freeze({\n streaming: Object.freeze({ node: false, web: false }),\n});\n\nexport function getFarmRendererCapabilities(\n renderer?: Pick<FarmRenderer, \"capabilities\">,\n): FarmRendererCapabilities {\n return {\n streaming: {\n node: renderer?.capabilities?.streaming?.node ?? DEFAULT_RENDERER_CAPABILITIES.streaming.node,\n web: renderer?.capabilities?.streaming?.web ?? DEFAULT_RENDERER_CAPABILITIES.streaming.web,\n },\n };\n}\n\nexport const FARM_COMPONENT_EXTENSIONS = [\".ts\", \".tsx\", \".js\", \".jsx\"] as const;\n\nexport function resolveFarmComponentExtensions(extensions: readonly string[] = []): string[] {\n return Array.from(\n new Set(\n [...FARM_COMPONENT_EXTENSIONS, ...extensions].map((extension) => {\n const normalized = extension.trim().toLowerCase();\n return normalized.startsWith(\".\") ? normalized : `.${normalized}`;\n }),\n ),\n ).filter((extension) => extension.length > 1);\n}\n\nexport function getFarmRendererComponentExtensions(\n renderer?: Pick<FarmRenderer, \"componentExtensions\">,\n): string[] {\n return resolveFarmComponentExtensions(renderer?.componentExtensions);\n}\n\nexport interface FarmRendererViteModule {\n createFarmRendererPlugin(options?: {\n ssr?: boolean;\n rendererOptions?: Readonly<Record<string, unknown>>;\n }): unknown | readonly unknown[] | Promise<unknown | readonly unknown[]>;\n}\n\nexport interface FarmServerRendererRuntime {\n readonly name: string;\n readonly Fragment: unknown;\n readonly Suspense: unknown;\n createElement(type: unknown, props?: unknown, ...children: unknown[]): unknown;\n isValidElement(value: unknown): boolean;\n renderToString(element: unknown): string | Promise<string>;\n /** Optional runtime copy of the descriptor capabilities for diagnostics. */\n readonly capabilities?: FarmRendererCapabilities;\n /** Optional bootstrap required before this renderer hydrates server markup. */\n generateHydrationScript?: () => string;\n /** Optional component used to render route-level failures. */\n ErrorBoundary?: unknown;\n /** Optional streaming primitive. Renderers without one use buffered SSR. */\n renderToPipeableStream?: (\n element: unknown,\n callbacks: {\n onShellReady(): void;\n onShellError(error: unknown): void;\n onError(error: unknown): void;\n },\n ) => { pipe(destination: NodeJS.WritableStream): void };\n /** WHATWG streaming primitive used by Web-stream-capable renderers. */\n renderToReadableStream?: (\n element: unknown,\n ) => ReadableStream<Uint8Array | string> | Promise<ReadableStream<Uint8Array | string>>;\n}\n\nexport const REACT_RENDERER: Readonly<FarmRenderer> = Object.freeze({\n name: \"react\",\n vite: \"@farm.js/core/renderer/react/vite\",\n server: \"@farm.js/core/renderer/react/server\",\n client: \"@farm.js/core/renderer/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 ],\n capabilities: {\n streaming: { node: true, web: false },\n },\n});\n\nexport function defineRenderer<const TRenderer extends FarmRenderer>(\n renderer: TRenderer,\n): TRenderer {\n return renderer;\n}\n\nexport function resolveFarmRenderer(renderer?: FarmRenderer): FarmRenderer {\n const resolved = renderer || REACT_RENDERER;\n const fields = [\"name\", \"vite\", \"server\", \"client\"] as const;\n\n for (const field of fields) {\n if (typeof resolved[field] !== \"string\" || resolved[field].trim().length === 0) {\n throw new TypeError(`Farm renderer \\`${field}\\` must be a non-empty string.`);\n }\n }\n\n return {\n ...resolved,\n componentExtensions: [...(resolved.componentExtensions || [])],\n dedupe: [...(resolved.dedupe || [])],\n optimizeDeps: [...(resolved.optimizeDeps || [])],\n buildConcurrency: resolved.buildConcurrency || \"parallel\",\n capabilities: getFarmRendererCapabilities(resolved),\n options: resolved.options ? { ...resolved.options } : undefined,\n };\n}\n\nexport async function readFarmRendererWebStream(\n stream: ReadableStream<Uint8Array | string>,\n): Promise<string> {\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n let html = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n html += typeof value === \"string\" ? value : decoder.decode(value, { stream: true });\n }\n\n return html + decoder.decode();\n}\n\nexport function isReactRenderer(renderer: Pick<FarmRenderer, \"name\"> | undefined): boolean {\n return !renderer || renderer.name === \"react\";\n}\n\n/** Resolve an optional renderer module from the application's dependency graph. */\nexport function resolveFarmRendererModule(root: string, specifier: string): string {\n const requireFromApp = createRequire(path.join(path.resolve(root), \"package.json\"));\n return requireFromApp.resolve(specifier);\n}\n\nexport async function loadFarmRendererVitePlugins(\n renderer: FarmRenderer,\n root: string,\n options: { ssr?: boolean } = {},\n): Promise<unknown[]> {\n // React uses Vite's default automatic JSX transform today. Keep the legacy\n // path dependency-free and avoid resolving Farm's own built package while\n // running directly from source in the monorepo.\n if (renderer.vite === REACT_RENDERER.vite) return [];\n\n const modulePath = resolveFarmRendererModule(root, renderer.vite);\n const rendererModule = (await import(pathToFileURL(modulePath).href)) as FarmRendererViteModule;\n\n if (typeof rendererModule.createFarmRendererPlugin !== \"function\") {\n throw new Error(\n `Renderer \\`${renderer.name}\\` module ${renderer.vite} must export createFarmRendererPlugin().`,\n );\n }\n\n const created = await rendererModule.createFarmRendererPlugin({\n ...options,\n rendererOptions: renderer.options,\n });\n if (!created) return [];\n return Array.isArray(created) ? [...created] : [created];\n}\n"],"mappings":"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","names":["path"]}
@@ -33,6 +33,14 @@ interface FarmRenderer {
33
33
  buildConcurrency?: "parallel" | "serial";
34
34
  /** Runtime features this renderer intentionally supports. */
35
35
  capabilities?: FarmRendererCapabilitiesInput;
36
+ /**
37
+ * Serializable options consumed by the renderer's Vite integration.
38
+ *
39
+ * Keeping renderer-owned configuration on the descriptor lets one rendering
40
+ * library expose multiple compiler modes without teaching Farm's core about
41
+ * each option.
42
+ */
43
+ options?: Readonly<Record<string, unknown>>;
36
44
  }
37
45
  interface FarmRendererStreamingCapabilities {
38
46
  /** Supports Node.js writable streams through renderToPipeableStream(). */
@@ -53,6 +61,7 @@ declare function getFarmRendererComponentExtensions(renderer?: Pick<FarmRenderer
53
61
  interface FarmRendererViteModule {
54
62
  createFarmRendererPlugin(options?: {
55
63
  ssr?: boolean;
64
+ rendererOptions?: Readonly<Record<string, unknown>>;
56
65
  }): unknown | readonly unknown[] | Promise<unknown | readonly unknown[]>;
57
66
  }
58
67
  interface FarmServerRendererRuntime {
@@ -33,6 +33,14 @@ interface FarmRenderer {
33
33
  buildConcurrency?: "parallel" | "serial";
34
34
  /** Runtime features this renderer intentionally supports. */
35
35
  capabilities?: FarmRendererCapabilitiesInput;
36
+ /**
37
+ * Serializable options consumed by the renderer's Vite integration.
38
+ *
39
+ * Keeping renderer-owned configuration on the descriptor lets one rendering
40
+ * library expose multiple compiler modes without teaching Farm's core about
41
+ * each option.
42
+ */
43
+ options?: Readonly<Record<string, unknown>>;
36
44
  }
37
45
  interface FarmRendererStreamingCapabilities {
38
46
  /** Supports Node.js writable streams through renderToPipeableStream(). */
@@ -53,6 +61,7 @@ declare function getFarmRendererComponentExtensions(renderer?: Pick<FarmRenderer
53
61
  interface FarmRendererViteModule {
54
62
  createFarmRendererPlugin(options?: {
55
63
  ssr?: boolean;
64
+ rendererOptions?: Readonly<Record<string, unknown>>;
56
65
  }): unknown | readonly unknown[] | Promise<unknown | readonly unknown[]>;
57
66
  }
58
67
  interface FarmServerRendererRuntime {
package/dist/renderer.mjs CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  resolveFarmComponentExtensions,
11
11
  resolveFarmRenderer,
12
12
  resolveFarmRendererModule
13
- } from "./chunk-5PDVNNUQ.mjs";
13
+ } from "./chunk-BNTDKO7T.mjs";
14
14
  import "./chunk-CGILA3WO.mjs";
15
15
  export {
16
16
  FARM_COMPONENT_EXTENSIONS,
package/dist/server.cjs CHANGED
@@ -5204,7 +5204,8 @@ function resolveFarmRenderer(renderer) {
5204
5204
  dedupe: [...resolved.dedupe || []],
5205
5205
  optimizeDeps: [...resolved.optimizeDeps || []],
5206
5206
  buildConcurrency: resolved.buildConcurrency || "parallel",
5207
- capabilities: getFarmRendererCapabilities(resolved)
5207
+ capabilities: getFarmRendererCapabilities(resolved),
5208
+ options: resolved.options ? { ...resolved.options } : void 0
5208
5209
  };
5209
5210
  }
5210
5211
  async function readFarmRendererWebStream(stream) {
@@ -5226,7 +5227,7 @@ function resolveFarmRendererModule(root, specifier) {
5226
5227
  return requireFromApp.resolve(specifier);
5227
5228
  }
5228
5229
  async function loadFarmRendererVitePlugins(renderer, root, options = {}) {
5229
- if (isReactRenderer(renderer)) return [];
5230
+ if (renderer.vite === REACT_RENDERER.vite) return [];
5230
5231
  const modulePath = resolveFarmRendererModule(root, renderer.vite);
5231
5232
  const rendererModule = await import((0, import_node_url2.pathToFileURL)(modulePath).href);
5232
5233
  if (typeof rendererModule.createFarmRendererPlugin !== "function") {
@@ -5234,7 +5235,10 @@ async function loadFarmRendererVitePlugins(renderer, root, options = {}) {
5234
5235
  `Renderer \`${renderer.name}\` module ${renderer.vite} must export createFarmRendererPlugin().`
5235
5236
  );
5236
5237
  }
5237
- const created = await rendererModule.createFarmRendererPlugin(options);
5238
+ const created = await rendererModule.createFarmRendererPlugin({
5239
+ ...options,
5240
+ rendererOptions: renderer.options
5241
+ });
5238
5242
  if (!created) return [];
5239
5243
  return Array.isArray(created) ? [...created] : [created];
5240
5244
  }
@@ -11176,7 +11180,8 @@ function getDefaultDeployOutputDir(target, preset, distDir) {
11176
11180
  function resolveDeployConfig(config, overrides = {}) {
11177
11181
  const deploy = config.deploy || {};
11178
11182
  const distDir = config.distDir || ".farm";
11179
- const target = normalizeDeployTarget(overrides.target || deploy.target);
11183
+ const overrideTarget = normalizeDeployTarget(overrides.target);
11184
+ const target = overrideTarget ? overrideTarget : overrides.preset ? getDeployTargetForPreset(overrides.preset) : normalizeDeployTarget(deploy.target);
11180
11185
  const preset = overrides.preset || deploy.preset || config.preset || getPresetForDeployTarget(target) || "node-server";
11181
11186
  const resolvedTarget = target || getDeployTargetForPreset(preset);
11182
11187
  const platformOutput = resolvedTarget === "vercel" ? deploy.vercel?.outputDirectory : resolvedTarget === "cloudflare" ? deploy.cloudflare?.outputDir : resolvedTarget === "netlify" ? deploy.netlify?.outputDir : void 0;
@@ -11208,6 +11213,14 @@ function normalizeDocsContentDir(value) {
11208
11213
  const normalized = value.replace(/\\/g, "/").replace(/^\/+/, "").replace(/\/+$/, "");
11209
11214
  return normalized || void 0;
11210
11215
  }
11216
+ async function inferDocsContentDir(root, srcDir, entry) {
11217
+ const { existsSync: existsSync18 } = await import("fs");
11218
+ const contentDir = import_path9.default.resolve(root, srcDir, "app", entry);
11219
+ if (!existsSync18(contentDir)) return void 0;
11220
+ const relativeContentDir = import_path9.default.relative(root, contentDir);
11221
+ if (relativeContentDir.startsWith("..") || import_path9.default.isAbsolute(relativeContentDir)) return void 0;
11222
+ return normalizeDocsContentDir(relativeContentDir);
11223
+ }
11211
11224
  function isRecord3(value) {
11212
11225
  return !!value && typeof value === "object" && !Array.isArray(value);
11213
11226
  }
@@ -11359,7 +11372,10 @@ async function resolveDocsConfig(userDocs, options = {}) {
11359
11372
  configuredDocsPath || explicitRoute || (configuredEntry ? `/${configuredEntry}` : void 0)
11360
11373
  );
11361
11374
  const docsEntry = explicitRoute && explicitRoute.startsWith("/") ? docsRouteToEntry(explicitRoute) : docsRouteToEntry(configuredEntry || entryRoute);
11362
- const contentDir = normalizeDocsContentDir(docsOptions.contentDir || mergedDocsConfig.contentDir);
11375
+ const configuredContentDir = normalizeDocsContentDir(
11376
+ docsOptions.contentDir || mergedDocsConfig.contentDir
11377
+ );
11378
+ const contentDir = configuredContentDir || await inferDocsContentDir(root, options.srcDir || "src", docsEntry);
11363
11379
  return {
11364
11380
  enabled: true,
11365
11381
  entry: entryRoute,
@@ -11580,6 +11596,7 @@ var init_config4 = __esm({
11580
11596
  __name(normalizeDocsRoute, "normalizeDocsRoute");
11581
11597
  __name(docsRouteToEntry, "docsRouteToEntry");
11582
11598
  __name(normalizeDocsContentDir, "normalizeDocsContentDir");
11599
+ __name(inferDocsContentDir, "inferDocsContentDir");
11583
11600
  __name(isRecord3, "isRecord");
11584
11601
  __name(cloneSerializable, "cloneSerializable");
11585
11602
  __name(sanitizeDocsConfig, "sanitizeDocsConfig");
@@ -20895,7 +20912,7 @@ _setFarmThemeServerSnapshotResolver(() => {
20895
20912
  });
20896
20913
 
20897
20914
  // package.json
20898
- var version = "0.1.0-beta.33";
20915
+ var version = "0.1.0-beta.34";
20899
20916
 
20900
20917
  // src/version.ts
20901
20918
  var FARM_VERSION = version;