@noego/wood 0.4.6 → 0.4.7

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 (241) hide show
  1. package/bin/wood.js +6 -1
  2. package/dist/client/app_env.cjs +39 -0
  3. package/dist/client/app_env.cjs.map +1 -0
  4. package/dist/client/app_env.d.cts +7 -0
  5. package/dist/client/app_env.d.ts +7 -0
  6. package/dist/client/app_env.js +14 -0
  7. package/dist/client/app_env.js.map +1 -0
  8. package/dist/client/index.cjs +33 -9
  9. package/dist/client/index.cjs.map +1 -1
  10. package/dist/client/index.d.cts +5 -1
  11. package/dist/client/index.d.ts +5 -1
  12. package/dist/client/index.js +32 -9
  13. package/dist/client/index.js.map +1 -1
  14. package/dist/codegen/channel_map_generator.cjs +102 -0
  15. package/dist/codegen/channel_map_generator.cjs.map +1 -0
  16. package/dist/codegen/channel_map_generator.d.cts +6 -0
  17. package/dist/codegen/channel_map_generator.d.ts +6 -0
  18. package/dist/codegen/channel_map_generator.js +78 -0
  19. package/dist/codegen/channel_map_generator.js.map +1 -0
  20. package/dist/codegen/controller_registration_generator.cjs +6 -1
  21. package/dist/codegen/controller_registration_generator.cjs.map +1 -1
  22. package/dist/codegen/controller_registration_generator.js +6 -1
  23. package/dist/codegen/controller_registration_generator.js.map +1 -1
  24. package/dist/codegen/generated_file_notice.cjs +40 -0
  25. package/dist/codegen/generated_file_notice.cjs.map +1 -0
  26. package/dist/codegen/generated_file_notice.d.cts +3 -0
  27. package/dist/codegen/generated_file_notice.d.ts +3 -0
  28. package/dist/codegen/generated_file_notice.js +16 -0
  29. package/dist/codegen/generated_file_notice.js.map +1 -0
  30. package/dist/codegen/index.cjs +3 -0
  31. package/dist/codegen/index.cjs.map +1 -1
  32. package/dist/codegen/index.d.cts +1 -0
  33. package/dist/codegen/index.d.ts +1 -0
  34. package/dist/codegen/index.js +2 -0
  35. package/dist/codegen/index.js.map +1 -1
  36. package/dist/codegen/preload_generator.cjs +97 -1
  37. package/dist/codegen/preload_generator.cjs.map +1 -1
  38. package/dist/codegen/preload_generator.js +97 -1
  39. package/dist/codegen/preload_generator.js.map +1 -1
  40. package/dist/codegen/renderer_app_generator.cjs +6 -1
  41. package/dist/codegen/renderer_app_generator.cjs.map +1 -1
  42. package/dist/codegen/renderer_app_generator.js +6 -1
  43. package/dist/codegen/renderer_app_generator.js.map +1 -1
  44. package/dist/codegen/renderer_controller_registration_generator.cjs +6 -1
  45. package/dist/codegen/renderer_controller_registration_generator.cjs.map +1 -1
  46. package/dist/codegen/renderer_controller_registration_generator.js +6 -1
  47. package/dist/codegen/renderer_controller_registration_generator.js.map +1 -1
  48. package/dist/codegen/renderer_view_manifest_generator.cjs +6 -1
  49. package/dist/codegen/renderer_view_manifest_generator.cjs.map +1 -1
  50. package/dist/codegen/renderer_view_manifest_generator.js +6 -1
  51. package/dist/codegen/renderer_view_manifest_generator.js.map +1 -1
  52. package/dist/codegen/runtime_generator.cjs +6 -1
  53. package/dist/codegen/runtime_generator.cjs.map +1 -1
  54. package/dist/codegen/runtime_generator.js +6 -1
  55. package/dist/codegen/runtime_generator.js.map +1 -1
  56. package/dist/codegen/test_mock_generator.cjs +5 -1
  57. package/dist/codegen/test_mock_generator.cjs.map +1 -1
  58. package/dist/codegen/test_mock_generator.js +5 -1
  59. package/dist/codegen/test_mock_generator.js.map +1 -1
  60. package/dist/codegen/type_generator.cjs +6 -1
  61. package/dist/codegen/type_generator.cjs.map +1 -1
  62. package/dist/codegen/type_generator.js +6 -1
  63. package/dist/codegen/type_generator.js.map +1 -1
  64. package/dist/index.cjs +19 -6
  65. package/dist/index.cjs.map +1 -1
  66. package/dist/index.d.cts +7 -1
  67. package/dist/index.d.ts +7 -1
  68. package/dist/index.js +13 -1
  69. package/dist/index.js.map +1 -1
  70. package/dist/main/index.cjs +133 -55
  71. package/dist/main/index.cjs.map +1 -1
  72. package/dist/main/index.d.cts +30 -2
  73. package/dist/main/index.d.ts +30 -2
  74. package/dist/main/index.js +134 -55
  75. package/dist/main/index.js.map +1 -1
  76. package/dist/main/renderer_trace_drain_coordinator.cjs +127 -0
  77. package/dist/main/renderer_trace_drain_coordinator.cjs.map +1 -0
  78. package/dist/main/renderer_trace_drain_coordinator.d.cts +46 -0
  79. package/dist/main/renderer_trace_drain_coordinator.d.ts +46 -0
  80. package/dist/main/renderer_trace_drain_coordinator.js +101 -0
  81. package/dist/main/renderer_trace_drain_coordinator.js.map +1 -0
  82. package/dist/router/wood_router.cjs +9 -1
  83. package/dist/router/wood_router.cjs.map +1 -1
  84. package/dist/router/wood_router.d.cts +1 -1
  85. package/dist/router/wood_router.d.ts +1 -1
  86. package/dist/router/wood_router.js +9 -1
  87. package/dist/router/wood_router.js.map +1 -1
  88. package/dist/runtime/app_env.cjs +52 -0
  89. package/dist/runtime/app_env.cjs.map +1 -0
  90. package/dist/runtime/app_env.d.cts +10 -0
  91. package/dist/runtime/app_env.d.ts +10 -0
  92. package/dist/runtime/app_env.js +18 -0
  93. package/dist/runtime/app_env.js.map +1 -0
  94. package/dist/runtime/index.cjs +9 -2
  95. package/dist/runtime/index.cjs.map +1 -1
  96. package/dist/runtime/index.d.cts +5 -1
  97. package/dist/runtime/index.d.ts +5 -1
  98. package/dist/runtime/index.js +9 -1
  99. package/dist/runtime/index.js.map +1 -1
  100. package/dist/runtime/renderer_log_dispatcher.cjs.map +1 -1
  101. package/dist/runtime/renderer_log_dispatcher.d.cts +1 -1
  102. package/dist/runtime/renderer_log_dispatcher.d.ts +1 -1
  103. package/dist/runtime/renderer_log_dispatcher.js.map +1 -1
  104. package/dist/runtime/renderer_trace_batch_receiver_registry.cjs +50 -0
  105. package/dist/runtime/renderer_trace_batch_receiver_registry.cjs.map +1 -0
  106. package/dist/runtime/renderer_trace_batch_receiver_registry.d.cts +10 -0
  107. package/dist/runtime/renderer_trace_batch_receiver_registry.d.ts +10 -0
  108. package/dist/runtime/renderer_trace_batch_receiver_registry.js +24 -0
  109. package/dist/runtime/renderer_trace_batch_receiver_registry.js.map +1 -0
  110. package/dist/runtime/runtime.cjs +75 -57
  111. package/dist/runtime/runtime.cjs.map +1 -1
  112. package/dist/runtime/runtime.d.cts +8 -1
  113. package/dist/runtime/runtime.d.ts +8 -1
  114. package/dist/runtime/runtime.js +80 -58
  115. package/dist/runtime/runtime.js.map +1 -1
  116. package/dist/testing/browser.cjs +540 -11
  117. package/dist/testing/browser.cjs.map +1 -1
  118. package/dist/testing/browser.d.cts +219 -3
  119. package/dist/testing/browser.d.ts +219 -3
  120. package/dist/testing/browser.js +540 -11
  121. package/dist/testing/browser.js.map +1 -1
  122. package/dist/testing/create_controller_harness.d.cts +1 -1
  123. package/dist/testing/create_controller_harness.d.ts +1 -1
  124. package/dist/testing/index.cjs +13 -0
  125. package/dist/testing/index.cjs.map +1 -1
  126. package/dist/testing/index.d.cts +7 -2
  127. package/dist/testing/index.d.ts +7 -2
  128. package/dist/testing/index.js +14 -0
  129. package/dist/testing/index.js.map +1 -1
  130. package/dist/trace-testing/index.d.cts +1 -1
  131. package/dist/trace-testing/index.d.ts +1 -1
  132. package/dist/trace-testing/trace_recorder.d.cts +1 -1
  133. package/dist/trace-testing/trace_recorder.d.ts +1 -1
  134. package/dist/trace-transport/index.cjs +32 -0
  135. package/dist/trace-transport/index.cjs.map +1 -0
  136. package/dist/trace-transport/index.d.cts +6 -0
  137. package/dist/trace-transport/index.d.ts +6 -0
  138. package/dist/trace-transport/index.js +7 -0
  139. package/dist/trace-transport/index.js.map +1 -0
  140. package/dist/trace_hub-Cob54qRx.d.cts +56 -0
  141. package/dist/trace_hub-Cob54qRx.d.ts +56 -0
  142. package/dist/tracing/index.cjs +14 -0
  143. package/dist/tracing/index.cjs.map +1 -1
  144. package/dist/tracing/index.d.cts +7 -1
  145. package/dist/tracing/index.d.ts +7 -1
  146. package/dist/tracing/index.js +12 -0
  147. package/dist/tracing/index.js.map +1 -1
  148. package/dist/tracing/renderer_trace_batch_host.cjs +80 -0
  149. package/dist/tracing/renderer_trace_batch_host.cjs.map +1 -0
  150. package/dist/tracing/renderer_trace_batch_host.d.cts +16 -0
  151. package/dist/tracing/renderer_trace_batch_host.d.ts +16 -0
  152. package/dist/tracing/renderer_trace_batch_host.js +56 -0
  153. package/dist/tracing/renderer_trace_batch_host.js.map +1 -0
  154. package/dist/tracing/renderer_trace_batch_transport.cjs +313 -0
  155. package/dist/tracing/renderer_trace_batch_transport.cjs.map +1 -0
  156. package/dist/tracing/renderer_trace_batch_transport.d.cts +53 -0
  157. package/dist/tracing/renderer_trace_batch_transport.d.ts +53 -0
  158. package/dist/tracing/renderer_trace_batch_transport.js +292 -0
  159. package/dist/tracing/renderer_trace_batch_transport.js.map +1 -0
  160. package/dist/tracing/trace_commit_writer.cjs +159 -0
  161. package/dist/tracing/trace_commit_writer.cjs.map +1 -0
  162. package/dist/tracing/trace_commit_writer.d.cts +97 -0
  163. package/dist/tracing/trace_commit_writer.d.ts +97 -0
  164. package/dist/tracing/trace_commit_writer.js +135 -0
  165. package/dist/tracing/trace_commit_writer.js.map +1 -0
  166. package/dist/tracing/trace_hub.cjs +58 -3
  167. package/dist/tracing/trace_hub.cjs.map +1 -1
  168. package/dist/tracing/trace_hub.d.cts +2 -46
  169. package/dist/tracing/trace_hub.d.ts +2 -46
  170. package/dist/tracing/trace_hub.js +56 -3
  171. package/dist/tracing/trace_hub.js.map +1 -1
  172. package/dist/tracing/trace_provider.cjs +42 -12
  173. package/dist/tracing/trace_provider.cjs.map +1 -1
  174. package/dist/tracing/trace_provider.d.cts +15 -1
  175. package/dist/tracing/trace_provider.d.ts +15 -1
  176. package/dist/tracing/trace_provider.js +43 -12
  177. package/dist/tracing/trace_provider.js.map +1 -1
  178. package/dist/tracing/types/wood_trace_batch.types.cjs +17 -0
  179. package/dist/tracing/types/wood_trace_batch.types.cjs.map +1 -0
  180. package/dist/tracing/types/wood_trace_batch.types.d.cts +124 -0
  181. package/dist/tracing/types/wood_trace_batch.types.d.ts +124 -0
  182. package/dist/tracing/types/wood_trace_batch.types.js +1 -0
  183. package/dist/tracing/types/wood_trace_batch.types.js.map +1 -0
  184. package/dist/tracing/types/wood_trace_sink.types.cjs +17 -0
  185. package/dist/tracing/types/wood_trace_sink.types.cjs.map +1 -0
  186. package/dist/tracing/types/wood_trace_sink.types.d.cts +2 -0
  187. package/dist/tracing/types/wood_trace_sink.types.d.ts +2 -0
  188. package/dist/tracing/types/wood_trace_sink.types.js +1 -0
  189. package/dist/tracing/types/wood_trace_sink.types.js.map +1 -0
  190. package/dist/tracing/wood_trace_batch_contract.cjs +229 -0
  191. package/dist/tracing/wood_trace_batch_contract.cjs.map +1 -0
  192. package/dist/tracing/wood_trace_batch_contract.d.cts +23 -0
  193. package/dist/tracing/wood_trace_batch_contract.d.ts +23 -0
  194. package/dist/tracing/wood_trace_batch_contract.js +205 -0
  195. package/dist/tracing/wood_trace_batch_contract.js.map +1 -0
  196. package/dist/transport/build_transport_bridge.cjs +62 -0
  197. package/dist/transport/build_transport_bridge.cjs.map +1 -0
  198. package/dist/transport/build_transport_bridge.d.cts +29 -0
  199. package/dist/transport/build_transport_bridge.d.ts +29 -0
  200. package/dist/transport/build_transport_bridge.js +38 -0
  201. package/dist/transport/build_transport_bridge.js.map +1 -0
  202. package/dist/transport/in_process_router_transport.cjs +41 -0
  203. package/dist/transport/in_process_router_transport.cjs.map +1 -0
  204. package/dist/transport/in_process_router_transport.d.cts +31 -0
  205. package/dist/transport/in_process_router_transport.d.ts +31 -0
  206. package/dist/transport/in_process_router_transport.js +17 -0
  207. package/dist/transport/in_process_router_transport.js.map +1 -0
  208. package/dist/transport/index.cjs +42 -0
  209. package/dist/transport/index.cjs.map +1 -0
  210. package/dist/transport/index.d.cts +8 -0
  211. package/dist/transport/index.d.ts +8 -0
  212. package/dist/transport/index.js +19 -0
  213. package/dist/transport/index.js.map +1 -0
  214. package/dist/transport/loopback_remote_transport.cjs +270 -0
  215. package/dist/transport/loopback_remote_transport.cjs.map +1 -0
  216. package/dist/transport/loopback_remote_transport.d.cts +49 -0
  217. package/dist/transport/loopback_remote_transport.d.ts +49 -0
  218. package/dist/transport/loopback_remote_transport.js +237 -0
  219. package/dist/transport/loopback_remote_transport.js.map +1 -0
  220. package/dist/transport/loopback_serialization.cjs +116 -0
  221. package/dist/transport/loopback_serialization.cjs.map +1 -0
  222. package/dist/transport/loopback_serialization.d.cts +28 -0
  223. package/dist/transport/loopback_serialization.d.ts +28 -0
  224. package/dist/transport/loopback_serialization.js +91 -0
  225. package/dist/transport/loopback_serialization.js.map +1 -0
  226. package/dist/transport/transport_contract_suite.cjs +110 -0
  227. package/dist/transport/transport_contract_suite.cjs.map +1 -0
  228. package/dist/transport/transport_contract_suite.d.cts +23 -0
  229. package/dist/transport/transport_contract_suite.d.ts +23 -0
  230. package/dist/transport/transport_contract_suite.js +85 -0
  231. package/dist/transport/transport_contract_suite.js.map +1 -0
  232. package/dist/transport/wood_rpc_transport.cjs +17 -0
  233. package/dist/transport/wood_rpc_transport.cjs.map +1 -0
  234. package/dist/transport/wood_rpc_transport.d.cts +44 -0
  235. package/dist/transport/wood_rpc_transport.d.ts +44 -0
  236. package/dist/transport/wood_rpc_transport.js +1 -0
  237. package/dist/transport/wood_rpc_transport.js.map +1 -0
  238. package/docs/browser-testing.md +139 -1
  239. package/package.json +22 -3
  240. package/src/components/NavigationShell.browser.test.ts +236 -0
  241. package/src/components/NavigationShell.svelte +162 -49
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/codegen/renderer_view_manifest_generator.ts"],"sourcesContent":["import path from 'path';\nimport type { ViewDef } from '../types/index.cjs';\n\nexport interface RendererViewManifestGeneratorOptions {\n /** Absolute path to renderer component root (e.g. /app/ui) */\n componentDir: string;\n /** Absolute output directory where generated file will be written */\n outDir: string;\n}\n\nfunction computeImportPath(fromDir: string, toFile: string): string {\n let rel = path.relative(fromDir, toFile);\n\n if (!rel.startsWith('.')) {\n rel = './' + rel;\n }\n\n return rel.replace(/\\\\/g, '/');\n}\n\nfunction toIdentifier(prefix: string, value: string): string {\n const core = value\n .replace(/[^a-zA-Z0-9]+/g, ' ')\n .trim()\n .split(/\\s+/)\n .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))\n .join('');\n\n return `${prefix}${core || 'Component'}`;\n}\n\nfunction viewKey(view: ViewDef): string {\n return `${view.windowName}.${view.pageName}`;\n}\n\nexport function generateRendererViewManifest(\n views: ViewDef[],\n options: RendererViewManifestGeneratorOptions,\n): string {\n const sortedViews = [...views].sort((a, b) => viewKey(a).localeCompare(viewKey(b)));\n\n const importLines: string[] = [];\n const viewIdentifiers = new Map<string, string>();\n const layoutIdentifiers = new Map<string, string>();\n const usedNames = new Set<string>();\n\n const allocateName = (prefix: string, filePath: string): string => {\n const base = toIdentifier(prefix, filePath);\n let name = base;\n let suffix = 2;\n while (usedNames.has(name)) {\n name = `${base}${suffix}`;\n suffix += 1;\n }\n usedNames.add(name);\n return name;\n };\n\n for (const view of sortedViews) {\n if (!viewIdentifiers.has(view.viewPath)) {\n const identifier = allocateName('View', view.viewPath);\n viewIdentifiers.set(view.viewPath, identifier);\n const abs = path.resolve(options.componentDir, view.viewPath);\n const importPath = computeImportPath(options.outDir, abs);\n importLines.push(`import ${identifier} from '${importPath}';`);\n }\n\n for (const layoutPath of view.layouts) {\n if (layoutIdentifiers.has(layoutPath)) continue;\n const identifier = allocateName('Layout', layoutPath);\n layoutIdentifiers.set(layoutPath, identifier);\n const abs = path.resolve(options.componentDir, layoutPath);\n const importPath = computeImportPath(options.outDir, abs);\n importLines.push(`import ${identifier} from '${importPath}';`);\n }\n }\n\n const manifestEntries = sortedViews.map((view) => {\n const key = viewKey(view);\n const viewIdentifier = viewIdentifiers.get(view.viewPath)!;\n const layoutList = view.layouts.map((layoutPath) => layoutIdentifiers.get(layoutPath)!);\n const controllerValue = view.controller ? `'${view.controller.replace(/'/g, \"\\\\'\")}'` : 'undefined';\n\n return ` '${key}': {\n key: '${key}',\n windowName: '${view.windowName}',\n pageName: '${view.pageName}',\n viewPath: '${view.viewPath}',\n layoutPaths: ${JSON.stringify(view.layouts)},\n controller: ${controllerValue},\n view: ${viewIdentifier},\n layouts: [${layoutList.join(', ')}],\n },`;\n });\n\n return `// AUTO-GENERATED by @noego/wood -- do not edit\n${importLines.join('\\n')}\n\nexport interface GeneratedViewManifestEntry {\n key: string;\n windowName: string;\n pageName: string;\n viewPath: string;\n layoutPaths: string[];\n controller?: string;\n view: any;\n layouts: any[];\n}\n\nexport const VIEW_MANIFEST: Record<string, GeneratedViewManifestEntry> = {\n${manifestEntries.join('\\n')}\n};\n\nexport function getViewManifestEntry(viewKey: string): GeneratedViewManifestEntry | null {\n return VIEW_MANIFEST[viewKey] ?? null;\n}\n`;\n}\n"],"mappings":"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","names":["path"]}
1
+ {"version":3,"sources":["../../src/codegen/renderer_view_manifest_generator.ts"],"sourcesContent":["import path from 'path';\nimport type { ViewDef } from '../types/index.cjs';\nimport { generatedFileNotice } from './generated_file_notice.cjs';\n\nconst RENDERER_VIEW_SOURCE_INSTRUCTIONS = [\n 'To change routes, page components, or layouts, edit the views YAML configured by',\n 'wood.config.yml renderer.openapi and the matching UI source files.',\n] as const;\n\nexport interface RendererViewManifestGeneratorOptions {\n /** Absolute path to renderer component root (e.g. /app/ui) */\n componentDir: string;\n /** Absolute output directory where generated file will be written */\n outDir: string;\n}\n\nfunction computeImportPath(fromDir: string, toFile: string): string {\n let rel = path.relative(fromDir, toFile);\n\n if (!rel.startsWith('.')) {\n rel = './' + rel;\n }\n\n return rel.replace(/\\\\/g, '/');\n}\n\nfunction toIdentifier(prefix: string, value: string): string {\n const core = value\n .replace(/[^a-zA-Z0-9]+/g, ' ')\n .trim()\n .split(/\\s+/)\n .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))\n .join('');\n\n return `${prefix}${core || 'Component'}`;\n}\n\nfunction viewKey(view: ViewDef): string {\n return `${view.windowName}.${view.pageName}`;\n}\n\nexport function generateRendererViewManifest(\n views: ViewDef[],\n options: RendererViewManifestGeneratorOptions,\n): string {\n const sortedViews = [...views].sort((a, b) => viewKey(a).localeCompare(viewKey(b)));\n\n const importLines: string[] = [];\n const viewIdentifiers = new Map<string, string>();\n const layoutIdentifiers = new Map<string, string>();\n const usedNames = new Set<string>();\n\n const allocateName = (prefix: string, filePath: string): string => {\n const base = toIdentifier(prefix, filePath);\n let name = base;\n let suffix = 2;\n while (usedNames.has(name)) {\n name = `${base}${suffix}`;\n suffix += 1;\n }\n usedNames.add(name);\n return name;\n };\n\n for (const view of sortedViews) {\n if (!viewIdentifiers.has(view.viewPath)) {\n const identifier = allocateName('View', view.viewPath);\n viewIdentifiers.set(view.viewPath, identifier);\n const abs = path.resolve(options.componentDir, view.viewPath);\n const importPath = computeImportPath(options.outDir, abs);\n importLines.push(`import ${identifier} from '${importPath}';`);\n }\n\n for (const layoutPath of view.layouts) {\n if (layoutIdentifiers.has(layoutPath)) continue;\n const identifier = allocateName('Layout', layoutPath);\n layoutIdentifiers.set(layoutPath, identifier);\n const abs = path.resolve(options.componentDir, layoutPath);\n const importPath = computeImportPath(options.outDir, abs);\n importLines.push(`import ${identifier} from '${importPath}';`);\n }\n }\n\n const manifestEntries = sortedViews.map((view) => {\n const key = viewKey(view);\n const viewIdentifier = viewIdentifiers.get(view.viewPath)!;\n const layoutList = view.layouts.map((layoutPath) => layoutIdentifiers.get(layoutPath)!);\n const controllerValue = view.controller ? `'${view.controller.replace(/'/g, \"\\\\'\")}'` : 'undefined';\n\n return ` '${key}': {\n key: '${key}',\n windowName: '${view.windowName}',\n pageName: '${view.pageName}',\n viewPath: '${view.viewPath}',\n layoutPaths: ${JSON.stringify(view.layouts)},\n controller: ${controllerValue},\n view: ${viewIdentifier},\n layouts: [${layoutList.join(', ')}],\n },`;\n });\n\n return `${generatedFileNotice(RENDERER_VIEW_SOURCE_INSTRUCTIONS)}\n${importLines.join('\\n')}\n\nexport interface GeneratedViewManifestEntry {\n key: string;\n windowName: string;\n pageName: string;\n viewPath: string;\n layoutPaths: string[];\n controller?: string;\n view: any;\n layouts: any[];\n}\n\nexport const VIEW_MANIFEST: Record<string, GeneratedViewManifestEntry> = {\n${manifestEntries.join('\\n')}\n};\n\nexport function getViewManifestEntry(viewKey: string): GeneratedViewManifestEntry | null {\n return VIEW_MANIFEST[viewKey] ?? null;\n}\n`;\n}\n"],"mappings":"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","names":["path"]}
@@ -1,4 +1,9 @@
1
1
  import path from "path";
2
+ import { generatedFileNotice } from "./generated_file_notice.js";
3
+ const RENDERER_VIEW_SOURCE_INSTRUCTIONS = [
4
+ "To change routes, page components, or layouts, edit the views YAML configured by",
5
+ "wood.config.yml renderer.openapi and the matching UI source files."
6
+ ];
2
7
  function computeImportPath(fromDir, toFile) {
3
8
  let rel = path.relative(fromDir, toFile);
4
9
  if (!rel.startsWith(".")) {
@@ -63,7 +68,7 @@ function generateRendererViewManifest(views, options) {
63
68
  layouts: [${layoutList.join(", ")}],
64
69
  },`;
65
70
  });
66
- return `// AUTO-GENERATED by @noego/wood -- do not edit
71
+ return `${generatedFileNotice(RENDERER_VIEW_SOURCE_INSTRUCTIONS)}
67
72
  ${importLines.join("\n")}
68
73
 
69
74
  export interface GeneratedViewManifestEntry {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/codegen/renderer_view_manifest_generator.ts"],"sourcesContent":["import path from 'path';\nimport type { ViewDef } from '../types/index.js';\n\nexport interface RendererViewManifestGeneratorOptions {\n /** Absolute path to renderer component root (e.g. /app/ui) */\n componentDir: string;\n /** Absolute output directory where generated file will be written */\n outDir: string;\n}\n\nfunction computeImportPath(fromDir: string, toFile: string): string {\n let rel = path.relative(fromDir, toFile);\n\n if (!rel.startsWith('.')) {\n rel = './' + rel;\n }\n\n return rel.replace(/\\\\/g, '/');\n}\n\nfunction toIdentifier(prefix: string, value: string): string {\n const core = value\n .replace(/[^a-zA-Z0-9]+/g, ' ')\n .trim()\n .split(/\\s+/)\n .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))\n .join('');\n\n return `${prefix}${core || 'Component'}`;\n}\n\nfunction viewKey(view: ViewDef): string {\n return `${view.windowName}.${view.pageName}`;\n}\n\nexport function generateRendererViewManifest(\n views: ViewDef[],\n options: RendererViewManifestGeneratorOptions,\n): string {\n const sortedViews = [...views].sort((a, b) => viewKey(a).localeCompare(viewKey(b)));\n\n const importLines: string[] = [];\n const viewIdentifiers = new Map<string, string>();\n const layoutIdentifiers = new Map<string, string>();\n const usedNames = new Set<string>();\n\n const allocateName = (prefix: string, filePath: string): string => {\n const base = toIdentifier(prefix, filePath);\n let name = base;\n let suffix = 2;\n while (usedNames.has(name)) {\n name = `${base}${suffix}`;\n suffix += 1;\n }\n usedNames.add(name);\n return name;\n };\n\n for (const view of sortedViews) {\n if (!viewIdentifiers.has(view.viewPath)) {\n const identifier = allocateName('View', view.viewPath);\n viewIdentifiers.set(view.viewPath, identifier);\n const abs = path.resolve(options.componentDir, view.viewPath);\n const importPath = computeImportPath(options.outDir, abs);\n importLines.push(`import ${identifier} from '${importPath}';`);\n }\n\n for (const layoutPath of view.layouts) {\n if (layoutIdentifiers.has(layoutPath)) continue;\n const identifier = allocateName('Layout', layoutPath);\n layoutIdentifiers.set(layoutPath, identifier);\n const abs = path.resolve(options.componentDir, layoutPath);\n const importPath = computeImportPath(options.outDir, abs);\n importLines.push(`import ${identifier} from '${importPath}';`);\n }\n }\n\n const manifestEntries = sortedViews.map((view) => {\n const key = viewKey(view);\n const viewIdentifier = viewIdentifiers.get(view.viewPath)!;\n const layoutList = view.layouts.map((layoutPath) => layoutIdentifiers.get(layoutPath)!);\n const controllerValue = view.controller ? `'${view.controller.replace(/'/g, \"\\\\'\")}'` : 'undefined';\n\n return ` '${key}': {\n key: '${key}',\n windowName: '${view.windowName}',\n pageName: '${view.pageName}',\n viewPath: '${view.viewPath}',\n layoutPaths: ${JSON.stringify(view.layouts)},\n controller: ${controllerValue},\n view: ${viewIdentifier},\n layouts: [${layoutList.join(', ')}],\n },`;\n });\n\n return `// AUTO-GENERATED by @noego/wood -- do not edit\n${importLines.join('\\n')}\n\nexport interface GeneratedViewManifestEntry {\n key: string;\n windowName: string;\n pageName: string;\n viewPath: string;\n layoutPaths: string[];\n controller?: string;\n view: any;\n layouts: any[];\n}\n\nexport const VIEW_MANIFEST: Record<string, GeneratedViewManifestEntry> = {\n${manifestEntries.join('\\n')}\n};\n\nexport function getViewManifestEntry(viewKey: string): GeneratedViewManifestEntry | null {\n return VIEW_MANIFEST[viewKey] ?? null;\n}\n`;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/codegen/renderer_view_manifest_generator.ts"],"sourcesContent":["import path from 'path';\nimport type { ViewDef } from '../types/index.js';\nimport { generatedFileNotice } from './generated_file_notice.js';\n\nconst RENDERER_VIEW_SOURCE_INSTRUCTIONS = [\n 'To change routes, page components, or layouts, edit the views YAML configured by',\n 'wood.config.yml renderer.openapi and the matching UI source files.',\n] as const;\n\nexport interface RendererViewManifestGeneratorOptions {\n /** Absolute path to renderer component root (e.g. /app/ui) */\n componentDir: string;\n /** Absolute output directory where generated file will be written */\n outDir: string;\n}\n\nfunction computeImportPath(fromDir: string, toFile: string): string {\n let rel = path.relative(fromDir, toFile);\n\n if (!rel.startsWith('.')) {\n rel = './' + rel;\n }\n\n return rel.replace(/\\\\/g, '/');\n}\n\nfunction toIdentifier(prefix: string, value: string): string {\n const core = value\n .replace(/[^a-zA-Z0-9]+/g, ' ')\n .trim()\n .split(/\\s+/)\n .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))\n .join('');\n\n return `${prefix}${core || 'Component'}`;\n}\n\nfunction viewKey(view: ViewDef): string {\n return `${view.windowName}.${view.pageName}`;\n}\n\nexport function generateRendererViewManifest(\n views: ViewDef[],\n options: RendererViewManifestGeneratorOptions,\n): string {\n const sortedViews = [...views].sort((a, b) => viewKey(a).localeCompare(viewKey(b)));\n\n const importLines: string[] = [];\n const viewIdentifiers = new Map<string, string>();\n const layoutIdentifiers = new Map<string, string>();\n const usedNames = new Set<string>();\n\n const allocateName = (prefix: string, filePath: string): string => {\n const base = toIdentifier(prefix, filePath);\n let name = base;\n let suffix = 2;\n while (usedNames.has(name)) {\n name = `${base}${suffix}`;\n suffix += 1;\n }\n usedNames.add(name);\n return name;\n };\n\n for (const view of sortedViews) {\n if (!viewIdentifiers.has(view.viewPath)) {\n const identifier = allocateName('View', view.viewPath);\n viewIdentifiers.set(view.viewPath, identifier);\n const abs = path.resolve(options.componentDir, view.viewPath);\n const importPath = computeImportPath(options.outDir, abs);\n importLines.push(`import ${identifier} from '${importPath}';`);\n }\n\n for (const layoutPath of view.layouts) {\n if (layoutIdentifiers.has(layoutPath)) continue;\n const identifier = allocateName('Layout', layoutPath);\n layoutIdentifiers.set(layoutPath, identifier);\n const abs = path.resolve(options.componentDir, layoutPath);\n const importPath = computeImportPath(options.outDir, abs);\n importLines.push(`import ${identifier} from '${importPath}';`);\n }\n }\n\n const manifestEntries = sortedViews.map((view) => {\n const key = viewKey(view);\n const viewIdentifier = viewIdentifiers.get(view.viewPath)!;\n const layoutList = view.layouts.map((layoutPath) => layoutIdentifiers.get(layoutPath)!);\n const controllerValue = view.controller ? `'${view.controller.replace(/'/g, \"\\\\'\")}'` : 'undefined';\n\n return ` '${key}': {\n key: '${key}',\n windowName: '${view.windowName}',\n pageName: '${view.pageName}',\n viewPath: '${view.viewPath}',\n layoutPaths: ${JSON.stringify(view.layouts)},\n controller: ${controllerValue},\n view: ${viewIdentifier},\n layouts: [${layoutList.join(', ')}],\n },`;\n });\n\n return `${generatedFileNotice(RENDERER_VIEW_SOURCE_INSTRUCTIONS)}\n${importLines.join('\\n')}\n\nexport interface GeneratedViewManifestEntry {\n key: string;\n windowName: string;\n pageName: string;\n viewPath: string;\n layoutPaths: string[];\n controller?: string;\n view: any;\n layouts: any[];\n}\n\nexport const VIEW_MANIFEST: Record<string, GeneratedViewManifestEntry> = {\n${manifestEntries.join('\\n')}\n};\n\nexport function getViewManifestEntry(viewKey: string): GeneratedViewManifestEntry | null {\n return VIEW_MANIFEST[viewKey] ?? null;\n}\n`;\n}\n"],"mappings":"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","names":[]}
@@ -33,6 +33,11 @@ __export(runtime_generator_exports, {
33
33
  module.exports = __toCommonJS(runtime_generator_exports);
34
34
  var import_fs = require("fs");
35
35
  var import_path = __toESM(require("path"), 1);
36
+ var import_generated_file_notice = require("./generated_file_notice.cjs");
37
+ const RUNTIME_SOURCE_INSTRUCTIONS = [
38
+ "To change IPC routing, validation schemas, or bundled controller registration,",
39
+ "edit the operations YAML configured by wood.config.yml main.openapi and the matching controller files."
40
+ ];
36
41
  const CANDIDATE_SUFFIXES = [
37
42
  ".ts",
38
43
  ".controller.ts",
@@ -116,7 +121,7 @@ Ensure each controller file exists with one of these suffixes: .ts, .controller.
116
121
  }
117
122
  const operationEntries = Array.from(operations.entries()).sort(([a], [b]) => a.localeCompare(b)).map(([channel, op]) => ` ['${channel}', ${serializeOperation(op)}],`);
118
123
  const lines = [
119
- "// AUTO-GENERATED by @noego/wood -- do not edit",
124
+ (0, import_generated_file_notice.generatedFileNotice)(RUNTIME_SOURCE_INSTRUCTIONS),
120
125
  "//",
121
126
  "// Static imports ensure all controllers are bundled and available at startup.",
122
127
  "// Operations are pre-parsed at build time to avoid runtime YAML I/O in Electron bundles.",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/codegen/runtime_generator.ts"],"sourcesContent":["import { existsSync } from 'fs';\nimport path from 'path';\nimport type { OperationDef } from '../types/index.cjs';\n\nconst CANDIDATE_SUFFIXES = [\n '.ts',\n '.controller.ts',\n '.js',\n '.controller.js',\n] as const;\n\nconst INDEX_CANDIDATES = [\n 'index.ts',\n 'index.js',\n] as const;\n\nfunction resolveControllerFile(controllerName: string, controllersDir: string): string | undefined {\n const basePath = path.resolve(controllersDir, controllerName);\n\n for (const suffix of CANDIDATE_SUFFIXES) {\n const candidate = basePath + suffix;\n if (existsSync(candidate)) return candidate;\n }\n\n for (const indexFile of INDEX_CANDIDATES) {\n const candidate = path.resolve(controllersDir, controllerName, indexFile);\n if (existsSync(candidate)) return candidate;\n }\n\n return undefined;\n}\n\nfunction computeImportPath(fromDir: string, toFile: string): string {\n let rel = path.relative(fromDir, toFile);\n\n if (!rel.startsWith('.')) {\n rel = './' + rel;\n }\n\n if (rel.endsWith('.ts')) {\n rel = rel.slice(0, -3);\n }\n\n return rel.replace(/\\\\/g, '/');\n}\n\nfunction toControllerClassName(controllerName: string): string {\n const pascal = controllerName\n .split(/[_\\-.]/)\n .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))\n .join('');\n\n return pascal + 'Controller';\n}\n\nfunction extractControllerNames(operations: Map<string, OperationDef>): string[] {\n const names = new Set<string>();\n operations.forEach((op) => names.add(op.controller));\n return Array.from(names).sort();\n}\n\nexport interface RuntimeGeneratorOptions {\n controllersDir: string;\n outDir: string;\n allowUnresolved?: boolean;\n}\n\nfunction serializeOperation(op: OperationDef): string {\n const payload: Record<string, unknown> = {\n channel: op.channel,\n controller: op.controller,\n action: op.action,\n middleware: op.middleware,\n };\n\n if (op.inputSchema !== undefined) {\n payload.inputSchema = op.inputSchema;\n }\n if (op.outputSchema !== undefined) {\n payload.outputSchema = op.outputSchema;\n }\n\n return JSON.stringify(payload);\n}\n\n/**\n * Generate a single runtime registration file that registers controllers and\n * pre-parsed operations with a WoodRouter-compatible target.\n */\nexport function generateRuntime(\n operations: Map<string, OperationDef>,\n options: RuntimeGeneratorOptions,\n): string {\n const controllerNames = extractControllerNames(operations);\n const outDirResolved = path.resolve(options.outDir);\n\n const imports: string[] = [];\n const registrations: string[] = [];\n const unresolved: string[] = [];\n\n for (const name of controllerNames) {\n const filePath = resolveControllerFile(name, options.controllersDir);\n if (!filePath) {\n unresolved.push(name);\n continue;\n }\n\n const importPath = computeImportPath(outDirResolved, filePath);\n const className = toControllerClassName(name);\n\n imports.push(`import ${className} from '${importPath}';`);\n registrations.push(` router.registerController('${name}', ${className});`);\n }\n\n if (unresolved.length > 0 && !options.allowUnresolved) {\n throw new Error(\n `Runtime codegen failed: ${unresolved.length} controller(s) not found on disk:\\n` +\n unresolved.map(name => ` - \"${name}\" (searched in ${options.controllersDir})`).join('\\n') +\n `\\n\\nEnsure each controller file exists with one of these suffixes: .ts, .controller.ts, .js, .controller.js`\n );\n }\n\n const operationEntries = Array.from(operations.entries())\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([channel, op]) => ` ['${channel}', ${serializeOperation(op)}],`);\n\n const lines: string[] = [\n '// AUTO-GENERATED by @noego/wood -- do not edit',\n '//',\n '// Static imports ensure all controllers are bundled and available at startup.',\n '// Operations are pre-parsed at build time to avoid runtime YAML I/O in Electron bundles.',\n '',\n ];\n\n lines.push(...imports);\n\n if (imports.length > 0) {\n lines.push('');\n }\n\n if (unresolved.length > 0) {\n lines.push(\n '// WARNING: The following controllers could not be resolved on disk:',\n ...unresolved.map((name) => `// - ${name}`),\n '',\n );\n }\n\n lines.push(\n 'const OPERATIONS = new Map<string, any>([',\n ...operationEntries,\n ']);',\n '',\n 'export function registerRuntime(router: {',\n ' registerController(name: string, cls: any): void;',\n ' loadOperations(operations: Map<string, any>): void;',\n '}): void {',\n ...registrations,\n ' router.loadOperations(OPERATIONS);',\n '}',\n '',\n );\n\n return lines.join('\\n');\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAA2B;AAC3B,kBAAiB;AAGjB,MAAM,qBAAqB;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,MAAM,mBAAmB;AAAA,EACvB;AAAA,EACA;AACF;AAEA,SAAS,sBAAsB,gBAAwB,gBAA4C;AACjG,QAAM,WAAW,YAAAA,QAAK,QAAQ,gBAAgB,cAAc;AAE5D,aAAW,UAAU,oBAAoB;AACvC,UAAM,YAAY,WAAW;AAC7B,YAAI,sBAAW,SAAS,EAAG,QAAO;AAAA,EACpC;AAEA,aAAW,aAAa,kBAAkB;AACxC,UAAM,YAAY,YAAAA,QAAK,QAAQ,gBAAgB,gBAAgB,SAAS;AACxE,YAAI,sBAAW,SAAS,EAAG,QAAO;AAAA,EACpC;AAEA,SAAO;AACT;AAEA,SAAS,kBAAkB,SAAiB,QAAwB;AAClE,MAAI,MAAM,YAAAA,QAAK,SAAS,SAAS,MAAM;AAEvC,MAAI,CAAC,IAAI,WAAW,GAAG,GAAG;AACxB,UAAM,OAAO;AAAA,EACf;AAEA,MAAI,IAAI,SAAS,KAAK,GAAG;AACvB,UAAM,IAAI,MAAM,GAAG,EAAE;AAAA,EACvB;AAEA,SAAO,IAAI,QAAQ,OAAO,GAAG;AAC/B;AAEA,SAAS,sBAAsB,gBAAgC;AAC7D,QAAM,SAAS,eACZ,MAAM,QAAQ,EACd,IAAI,CAAC,YAAY,QAAQ,OAAO,CAAC,EAAE,YAAY,IAAI,QAAQ,MAAM,CAAC,CAAC,EACnE,KAAK,EAAE;AAEV,SAAO,SAAS;AAClB;AAEA,SAAS,uBAAuB,YAAiD;AAC/E,QAAM,QAAQ,oBAAI,IAAY;AAC9B,aAAW,QAAQ,CAAC,OAAO,MAAM,IAAI,GAAG,UAAU,CAAC;AACnD,SAAO,MAAM,KAAK,KAAK,EAAE,KAAK;AAChC;AAQA,SAAS,mBAAmB,IAA0B;AACpD,QAAM,UAAmC;AAAA,IACvC,SAAS,GAAG;AAAA,IACZ,YAAY,GAAG;AAAA,IACf,QAAQ,GAAG;AAAA,IACX,YAAY,GAAG;AAAA,EACjB;AAEA,MAAI,GAAG,gBAAgB,QAAW;AAChC,YAAQ,cAAc,GAAG;AAAA,EAC3B;AACA,MAAI,GAAG,iBAAiB,QAAW;AACjC,YAAQ,eAAe,GAAG;AAAA,EAC5B;AAEA,SAAO,KAAK,UAAU,OAAO;AAC/B;AAMO,SAAS,gBACd,YACA,SACQ;AACR,QAAM,kBAAkB,uBAAuB,UAAU;AACzD,QAAM,iBAAiB,YAAAA,QAAK,QAAQ,QAAQ,MAAM;AAElD,QAAM,UAAoB,CAAC;AAC3B,QAAM,gBAA0B,CAAC;AACjC,QAAM,aAAuB,CAAC;AAE9B,aAAW,QAAQ,iBAAiB;AAClC,UAAM,WAAW,sBAAsB,MAAM,QAAQ,cAAc;AACnE,QAAI,CAAC,UAAU;AACb,iBAAW,KAAK,IAAI;AACpB;AAAA,IACF;AAEA,UAAM,aAAa,kBAAkB,gBAAgB,QAAQ;AAC7D,UAAM,YAAY,sBAAsB,IAAI;AAE5C,YAAQ,KAAK,UAAU,SAAS,UAAU,UAAU,IAAI;AACxD,kBAAc,KAAK,gCAAgC,IAAI,MAAM,SAAS,IAAI;AAAA,EAC5E;AAEA,MAAI,WAAW,SAAS,KAAK,CAAC,QAAQ,iBAAiB;AACrD,UAAM,IAAI;AAAA,MACR,2BAA2B,WAAW,MAAM;AAAA,IAC5C,WAAW,IAAI,UAAQ,QAAQ,IAAI,kBAAkB,QAAQ,cAAc,GAAG,EAAE,KAAK,IAAI,IACzF;AAAA;AAAA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,mBAAmB,MAAM,KAAK,WAAW,QAAQ,CAAC,EACrD,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,EACrC,IAAI,CAAC,CAAC,SAAS,EAAE,MAAM,OAAO,OAAO,MAAM,mBAAmB,EAAE,CAAC,IAAI;AAExE,QAAM,QAAkB;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,KAAK,GAAG,OAAO;AAErB,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,WAAW,SAAS,GAAG;AACzB,UAAM;AAAA,MACJ;AAAA,MACA,GAAG,WAAW,IAAI,CAAC,SAAS,UAAU,IAAI,EAAE;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AAEA,QAAM;AAAA,IACJ;AAAA,IACA,GAAG;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;","names":["path"]}
1
+ {"version":3,"sources":["../../src/codegen/runtime_generator.ts"],"sourcesContent":["import { existsSync } from 'fs';\nimport path from 'path';\nimport type { OperationDef } from '../types/index.cjs';\nimport { generatedFileNotice } from './generated_file_notice.cjs';\n\nconst RUNTIME_SOURCE_INSTRUCTIONS = [\n 'To change IPC routing, validation schemas, or bundled controller registration,',\n 'edit the operations YAML configured by wood.config.yml main.openapi and the matching controller files.',\n] as const;\n\nconst CANDIDATE_SUFFIXES = [\n '.ts',\n '.controller.ts',\n '.js',\n '.controller.js',\n] as const;\n\nconst INDEX_CANDIDATES = [\n 'index.ts',\n 'index.js',\n] as const;\n\nfunction resolveControllerFile(controllerName: string, controllersDir: string): string | undefined {\n const basePath = path.resolve(controllersDir, controllerName);\n\n for (const suffix of CANDIDATE_SUFFIXES) {\n const candidate = basePath + suffix;\n if (existsSync(candidate)) return candidate;\n }\n\n for (const indexFile of INDEX_CANDIDATES) {\n const candidate = path.resolve(controllersDir, controllerName, indexFile);\n if (existsSync(candidate)) return candidate;\n }\n\n return undefined;\n}\n\nfunction computeImportPath(fromDir: string, toFile: string): string {\n let rel = path.relative(fromDir, toFile);\n\n if (!rel.startsWith('.')) {\n rel = './' + rel;\n }\n\n if (rel.endsWith('.ts')) {\n rel = rel.slice(0, -3);\n }\n\n return rel.replace(/\\\\/g, '/');\n}\n\nfunction toControllerClassName(controllerName: string): string {\n const pascal = controllerName\n .split(/[_\\-.]/)\n .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))\n .join('');\n\n return pascal + 'Controller';\n}\n\nfunction extractControllerNames(operations: Map<string, OperationDef>): string[] {\n const names = new Set<string>();\n operations.forEach((op) => names.add(op.controller));\n return Array.from(names).sort();\n}\n\nexport interface RuntimeGeneratorOptions {\n controllersDir: string;\n outDir: string;\n allowUnresolved?: boolean;\n}\n\nfunction serializeOperation(op: OperationDef): string {\n const payload: Record<string, unknown> = {\n channel: op.channel,\n controller: op.controller,\n action: op.action,\n middleware: op.middleware,\n };\n\n if (op.inputSchema !== undefined) {\n payload.inputSchema = op.inputSchema;\n }\n if (op.outputSchema !== undefined) {\n payload.outputSchema = op.outputSchema;\n }\n\n return JSON.stringify(payload);\n}\n\n/**\n * Generate a single runtime registration file that registers controllers and\n * pre-parsed operations with a WoodRouter-compatible target.\n */\nexport function generateRuntime(\n operations: Map<string, OperationDef>,\n options: RuntimeGeneratorOptions,\n): string {\n const controllerNames = extractControllerNames(operations);\n const outDirResolved = path.resolve(options.outDir);\n\n const imports: string[] = [];\n const registrations: string[] = [];\n const unresolved: string[] = [];\n\n for (const name of controllerNames) {\n const filePath = resolveControllerFile(name, options.controllersDir);\n if (!filePath) {\n unresolved.push(name);\n continue;\n }\n\n const importPath = computeImportPath(outDirResolved, filePath);\n const className = toControllerClassName(name);\n\n imports.push(`import ${className} from '${importPath}';`);\n registrations.push(` router.registerController('${name}', ${className});`);\n }\n\n if (unresolved.length > 0 && !options.allowUnresolved) {\n throw new Error(\n `Runtime codegen failed: ${unresolved.length} controller(s) not found on disk:\\n` +\n unresolved.map(name => ` - \"${name}\" (searched in ${options.controllersDir})`).join('\\n') +\n `\\n\\nEnsure each controller file exists with one of these suffixes: .ts, .controller.ts, .js, .controller.js`\n );\n }\n\n const operationEntries = Array.from(operations.entries())\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([channel, op]) => ` ['${channel}', ${serializeOperation(op)}],`);\n\n const lines: string[] = [\n generatedFileNotice(RUNTIME_SOURCE_INSTRUCTIONS),\n '//',\n '// Static imports ensure all controllers are bundled and available at startup.',\n '// Operations are pre-parsed at build time to avoid runtime YAML I/O in Electron bundles.',\n '',\n ];\n\n lines.push(...imports);\n\n if (imports.length > 0) {\n lines.push('');\n }\n\n if (unresolved.length > 0) {\n lines.push(\n '// WARNING: The following controllers could not be resolved on disk:',\n ...unresolved.map((name) => `// - ${name}`),\n '',\n );\n }\n\n lines.push(\n 'const OPERATIONS = new Map<string, any>([',\n ...operationEntries,\n ']);',\n '',\n 'export function registerRuntime(router: {',\n ' registerController(name: string, cls: any): void;',\n ' loadOperations(operations: Map<string, any>): void;',\n '}): void {',\n ...registrations,\n ' router.loadOperations(OPERATIONS);',\n '}',\n '',\n );\n\n return lines.join('\\n');\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAA2B;AAC3B,kBAAiB;AAEjB,mCAAoC;AAEpC,MAAM,8BAA8B;AAAA,EAClC;AAAA,EACA;AACF;AAEA,MAAM,qBAAqB;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,MAAM,mBAAmB;AAAA,EACvB;AAAA,EACA;AACF;AAEA,SAAS,sBAAsB,gBAAwB,gBAA4C;AACjG,QAAM,WAAW,YAAAA,QAAK,QAAQ,gBAAgB,cAAc;AAE5D,aAAW,UAAU,oBAAoB;AACvC,UAAM,YAAY,WAAW;AAC7B,YAAI,sBAAW,SAAS,EAAG,QAAO;AAAA,EACpC;AAEA,aAAW,aAAa,kBAAkB;AACxC,UAAM,YAAY,YAAAA,QAAK,QAAQ,gBAAgB,gBAAgB,SAAS;AACxE,YAAI,sBAAW,SAAS,EAAG,QAAO;AAAA,EACpC;AAEA,SAAO;AACT;AAEA,SAAS,kBAAkB,SAAiB,QAAwB;AAClE,MAAI,MAAM,YAAAA,QAAK,SAAS,SAAS,MAAM;AAEvC,MAAI,CAAC,IAAI,WAAW,GAAG,GAAG;AACxB,UAAM,OAAO;AAAA,EACf;AAEA,MAAI,IAAI,SAAS,KAAK,GAAG;AACvB,UAAM,IAAI,MAAM,GAAG,EAAE;AAAA,EACvB;AAEA,SAAO,IAAI,QAAQ,OAAO,GAAG;AAC/B;AAEA,SAAS,sBAAsB,gBAAgC;AAC7D,QAAM,SAAS,eACZ,MAAM,QAAQ,EACd,IAAI,CAAC,YAAY,QAAQ,OAAO,CAAC,EAAE,YAAY,IAAI,QAAQ,MAAM,CAAC,CAAC,EACnE,KAAK,EAAE;AAEV,SAAO,SAAS;AAClB;AAEA,SAAS,uBAAuB,YAAiD;AAC/E,QAAM,QAAQ,oBAAI,IAAY;AAC9B,aAAW,QAAQ,CAAC,OAAO,MAAM,IAAI,GAAG,UAAU,CAAC;AACnD,SAAO,MAAM,KAAK,KAAK,EAAE,KAAK;AAChC;AAQA,SAAS,mBAAmB,IAA0B;AACpD,QAAM,UAAmC;AAAA,IACvC,SAAS,GAAG;AAAA,IACZ,YAAY,GAAG;AAAA,IACf,QAAQ,GAAG;AAAA,IACX,YAAY,GAAG;AAAA,EACjB;AAEA,MAAI,GAAG,gBAAgB,QAAW;AAChC,YAAQ,cAAc,GAAG;AAAA,EAC3B;AACA,MAAI,GAAG,iBAAiB,QAAW;AACjC,YAAQ,eAAe,GAAG;AAAA,EAC5B;AAEA,SAAO,KAAK,UAAU,OAAO;AAC/B;AAMO,SAAS,gBACd,YACA,SACQ;AACR,QAAM,kBAAkB,uBAAuB,UAAU;AACzD,QAAM,iBAAiB,YAAAA,QAAK,QAAQ,QAAQ,MAAM;AAElD,QAAM,UAAoB,CAAC;AAC3B,QAAM,gBAA0B,CAAC;AACjC,QAAM,aAAuB,CAAC;AAE9B,aAAW,QAAQ,iBAAiB;AAClC,UAAM,WAAW,sBAAsB,MAAM,QAAQ,cAAc;AACnE,QAAI,CAAC,UAAU;AACb,iBAAW,KAAK,IAAI;AACpB;AAAA,IACF;AAEA,UAAM,aAAa,kBAAkB,gBAAgB,QAAQ;AAC7D,UAAM,YAAY,sBAAsB,IAAI;AAE5C,YAAQ,KAAK,UAAU,SAAS,UAAU,UAAU,IAAI;AACxD,kBAAc,KAAK,gCAAgC,IAAI,MAAM,SAAS,IAAI;AAAA,EAC5E;AAEA,MAAI,WAAW,SAAS,KAAK,CAAC,QAAQ,iBAAiB;AACrD,UAAM,IAAI;AAAA,MACR,2BAA2B,WAAW,MAAM;AAAA,IAC5C,WAAW,IAAI,UAAQ,QAAQ,IAAI,kBAAkB,QAAQ,cAAc,GAAG,EAAE,KAAK,IAAI,IACzF;AAAA;AAAA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,mBAAmB,MAAM,KAAK,WAAW,QAAQ,CAAC,EACrD,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,EACrC,IAAI,CAAC,CAAC,SAAS,EAAE,MAAM,OAAO,OAAO,MAAM,mBAAmB,EAAE,CAAC,IAAI;AAExE,QAAM,QAAkB;AAAA,QACtB,kDAAoB,2BAA2B;AAAA,IAC/C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,KAAK,GAAG,OAAO;AAErB,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,WAAW,SAAS,GAAG;AACzB,UAAM;AAAA,MACJ;AAAA,MACA,GAAG,WAAW,IAAI,CAAC,SAAS,UAAU,IAAI,EAAE;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AAEA,QAAM;AAAA,IACJ;AAAA,IACA,GAAG;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;","names":["path"]}
@@ -1,5 +1,10 @@
1
1
  import { existsSync } from "fs";
2
2
  import path from "path";
3
+ import { generatedFileNotice } from "./generated_file_notice.js";
4
+ const RUNTIME_SOURCE_INSTRUCTIONS = [
5
+ "To change IPC routing, validation schemas, or bundled controller registration,",
6
+ "edit the operations YAML configured by wood.config.yml main.openapi and the matching controller files."
7
+ ];
3
8
  const CANDIDATE_SUFFIXES = [
4
9
  ".ts",
5
10
  ".controller.ts",
@@ -83,7 +88,7 @@ Ensure each controller file exists with one of these suffixes: .ts, .controller.
83
88
  }
84
89
  const operationEntries = Array.from(operations.entries()).sort(([a], [b]) => a.localeCompare(b)).map(([channel, op]) => ` ['${channel}', ${serializeOperation(op)}],`);
85
90
  const lines = [
86
- "// AUTO-GENERATED by @noego/wood -- do not edit",
91
+ generatedFileNotice(RUNTIME_SOURCE_INSTRUCTIONS),
87
92
  "//",
88
93
  "// Static imports ensure all controllers are bundled and available at startup.",
89
94
  "// Operations are pre-parsed at build time to avoid runtime YAML I/O in Electron bundles.",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/codegen/runtime_generator.ts"],"sourcesContent":["import { existsSync } from 'fs';\nimport path from 'path';\nimport type { OperationDef } from '../types/index.js';\n\nconst CANDIDATE_SUFFIXES = [\n '.ts',\n '.controller.ts',\n '.js',\n '.controller.js',\n] as const;\n\nconst INDEX_CANDIDATES = [\n 'index.ts',\n 'index.js',\n] as const;\n\nfunction resolveControllerFile(controllerName: string, controllersDir: string): string | undefined {\n const basePath = path.resolve(controllersDir, controllerName);\n\n for (const suffix of CANDIDATE_SUFFIXES) {\n const candidate = basePath + suffix;\n if (existsSync(candidate)) return candidate;\n }\n\n for (const indexFile of INDEX_CANDIDATES) {\n const candidate = path.resolve(controllersDir, controllerName, indexFile);\n if (existsSync(candidate)) return candidate;\n }\n\n return undefined;\n}\n\nfunction computeImportPath(fromDir: string, toFile: string): string {\n let rel = path.relative(fromDir, toFile);\n\n if (!rel.startsWith('.')) {\n rel = './' + rel;\n }\n\n if (rel.endsWith('.ts')) {\n rel = rel.slice(0, -3);\n }\n\n return rel.replace(/\\\\/g, '/');\n}\n\nfunction toControllerClassName(controllerName: string): string {\n const pascal = controllerName\n .split(/[_\\-.]/)\n .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))\n .join('');\n\n return pascal + 'Controller';\n}\n\nfunction extractControllerNames(operations: Map<string, OperationDef>): string[] {\n const names = new Set<string>();\n operations.forEach((op) => names.add(op.controller));\n return Array.from(names).sort();\n}\n\nexport interface RuntimeGeneratorOptions {\n controllersDir: string;\n outDir: string;\n allowUnresolved?: boolean;\n}\n\nfunction serializeOperation(op: OperationDef): string {\n const payload: Record<string, unknown> = {\n channel: op.channel,\n controller: op.controller,\n action: op.action,\n middleware: op.middleware,\n };\n\n if (op.inputSchema !== undefined) {\n payload.inputSchema = op.inputSchema;\n }\n if (op.outputSchema !== undefined) {\n payload.outputSchema = op.outputSchema;\n }\n\n return JSON.stringify(payload);\n}\n\n/**\n * Generate a single runtime registration file that registers controllers and\n * pre-parsed operations with a WoodRouter-compatible target.\n */\nexport function generateRuntime(\n operations: Map<string, OperationDef>,\n options: RuntimeGeneratorOptions,\n): string {\n const controllerNames = extractControllerNames(operations);\n const outDirResolved = path.resolve(options.outDir);\n\n const imports: string[] = [];\n const registrations: string[] = [];\n const unresolved: string[] = [];\n\n for (const name of controllerNames) {\n const filePath = resolveControllerFile(name, options.controllersDir);\n if (!filePath) {\n unresolved.push(name);\n continue;\n }\n\n const importPath = computeImportPath(outDirResolved, filePath);\n const className = toControllerClassName(name);\n\n imports.push(`import ${className} from '${importPath}';`);\n registrations.push(` router.registerController('${name}', ${className});`);\n }\n\n if (unresolved.length > 0 && !options.allowUnresolved) {\n throw new Error(\n `Runtime codegen failed: ${unresolved.length} controller(s) not found on disk:\\n` +\n unresolved.map(name => ` - \"${name}\" (searched in ${options.controllersDir})`).join('\\n') +\n `\\n\\nEnsure each controller file exists with one of these suffixes: .ts, .controller.ts, .js, .controller.js`\n );\n }\n\n const operationEntries = Array.from(operations.entries())\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([channel, op]) => ` ['${channel}', ${serializeOperation(op)}],`);\n\n const lines: string[] = [\n '// AUTO-GENERATED by @noego/wood -- do not edit',\n '//',\n '// Static imports ensure all controllers are bundled and available at startup.',\n '// Operations are pre-parsed at build time to avoid runtime YAML I/O in Electron bundles.',\n '',\n ];\n\n lines.push(...imports);\n\n if (imports.length > 0) {\n lines.push('');\n }\n\n if (unresolved.length > 0) {\n lines.push(\n '// WARNING: The following controllers could not be resolved on disk:',\n ...unresolved.map((name) => `// - ${name}`),\n '',\n );\n }\n\n lines.push(\n 'const OPERATIONS = new Map<string, any>([',\n ...operationEntries,\n ']);',\n '',\n 'export function registerRuntime(router: {',\n ' registerController(name: string, cls: any): void;',\n ' loadOperations(operations: Map<string, any>): void;',\n '}): void {',\n ...registrations,\n ' router.loadOperations(OPERATIONS);',\n '}',\n '',\n );\n\n return lines.join('\\n');\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/codegen/runtime_generator.ts"],"sourcesContent":["import { existsSync } from 'fs';\nimport path from 'path';\nimport type { OperationDef } from '../types/index.js';\nimport { generatedFileNotice } from './generated_file_notice.js';\n\nconst RUNTIME_SOURCE_INSTRUCTIONS = [\n 'To change IPC routing, validation schemas, or bundled controller registration,',\n 'edit the operations YAML configured by wood.config.yml main.openapi and the matching controller files.',\n] as const;\n\nconst CANDIDATE_SUFFIXES = [\n '.ts',\n '.controller.ts',\n '.js',\n '.controller.js',\n] as const;\n\nconst INDEX_CANDIDATES = [\n 'index.ts',\n 'index.js',\n] as const;\n\nfunction resolveControllerFile(controllerName: string, controllersDir: string): string | undefined {\n const basePath = path.resolve(controllersDir, controllerName);\n\n for (const suffix of CANDIDATE_SUFFIXES) {\n const candidate = basePath + suffix;\n if (existsSync(candidate)) return candidate;\n }\n\n for (const indexFile of INDEX_CANDIDATES) {\n const candidate = path.resolve(controllersDir, controllerName, indexFile);\n if (existsSync(candidate)) return candidate;\n }\n\n return undefined;\n}\n\nfunction computeImportPath(fromDir: string, toFile: string): string {\n let rel = path.relative(fromDir, toFile);\n\n if (!rel.startsWith('.')) {\n rel = './' + rel;\n }\n\n if (rel.endsWith('.ts')) {\n rel = rel.slice(0, -3);\n }\n\n return rel.replace(/\\\\/g, '/');\n}\n\nfunction toControllerClassName(controllerName: string): string {\n const pascal = controllerName\n .split(/[_\\-.]/)\n .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))\n .join('');\n\n return pascal + 'Controller';\n}\n\nfunction extractControllerNames(operations: Map<string, OperationDef>): string[] {\n const names = new Set<string>();\n operations.forEach((op) => names.add(op.controller));\n return Array.from(names).sort();\n}\n\nexport interface RuntimeGeneratorOptions {\n controllersDir: string;\n outDir: string;\n allowUnresolved?: boolean;\n}\n\nfunction serializeOperation(op: OperationDef): string {\n const payload: Record<string, unknown> = {\n channel: op.channel,\n controller: op.controller,\n action: op.action,\n middleware: op.middleware,\n };\n\n if (op.inputSchema !== undefined) {\n payload.inputSchema = op.inputSchema;\n }\n if (op.outputSchema !== undefined) {\n payload.outputSchema = op.outputSchema;\n }\n\n return JSON.stringify(payload);\n}\n\n/**\n * Generate a single runtime registration file that registers controllers and\n * pre-parsed operations with a WoodRouter-compatible target.\n */\nexport function generateRuntime(\n operations: Map<string, OperationDef>,\n options: RuntimeGeneratorOptions,\n): string {\n const controllerNames = extractControllerNames(operations);\n const outDirResolved = path.resolve(options.outDir);\n\n const imports: string[] = [];\n const registrations: string[] = [];\n const unresolved: string[] = [];\n\n for (const name of controllerNames) {\n const filePath = resolveControllerFile(name, options.controllersDir);\n if (!filePath) {\n unresolved.push(name);\n continue;\n }\n\n const importPath = computeImportPath(outDirResolved, filePath);\n const className = toControllerClassName(name);\n\n imports.push(`import ${className} from '${importPath}';`);\n registrations.push(` router.registerController('${name}', ${className});`);\n }\n\n if (unresolved.length > 0 && !options.allowUnresolved) {\n throw new Error(\n `Runtime codegen failed: ${unresolved.length} controller(s) not found on disk:\\n` +\n unresolved.map(name => ` - \"${name}\" (searched in ${options.controllersDir})`).join('\\n') +\n `\\n\\nEnsure each controller file exists with one of these suffixes: .ts, .controller.ts, .js, .controller.js`\n );\n }\n\n const operationEntries = Array.from(operations.entries())\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([channel, op]) => ` ['${channel}', ${serializeOperation(op)}],`);\n\n const lines: string[] = [\n generatedFileNotice(RUNTIME_SOURCE_INSTRUCTIONS),\n '//',\n '// Static imports ensure all controllers are bundled and available at startup.',\n '// Operations are pre-parsed at build time to avoid runtime YAML I/O in Electron bundles.',\n '',\n ];\n\n lines.push(...imports);\n\n if (imports.length > 0) {\n lines.push('');\n }\n\n if (unresolved.length > 0) {\n lines.push(\n '// WARNING: The following controllers could not be resolved on disk:',\n ...unresolved.map((name) => `// - ${name}`),\n '',\n );\n }\n\n lines.push(\n 'const OPERATIONS = new Map<string, any>([',\n ...operationEntries,\n ']);',\n '',\n 'export function registerRuntime(router: {',\n ' registerController(name: string, cls: any): void;',\n ' loadOperations(operations: Map<string, any>): void;',\n '}): void {',\n ...registrations,\n ' router.loadOperations(OPERATIONS);',\n '}',\n '',\n );\n\n return lines.join('\\n');\n}\n"],"mappings":"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","names":[]}
@@ -21,6 +21,10 @@ __export(test_mock_generator_exports, {
21
21
  generateTestMock: () => generateTestMock
22
22
  });
23
23
  module.exports = __toCommonJS(test_mock_generator_exports);
24
+ var import_generated_file_notice = require("./generated_file_notice.cjs");
25
+ const TEST_MOCK_SOURCE_INSTRUCTIONS = [
26
+ "To change mocked IPC shape, edit the operations YAML configured by wood.config.yml main.openapi."
27
+ ];
24
28
  function buildNestedMockTree(operations) {
25
29
  const tree = {};
26
30
  for (const [channel, op] of operations) {
@@ -51,7 +55,7 @@ function generateMockTree(node, indent = " ") {
51
55
  function generateTestMock(operations) {
52
56
  const tree = buildNestedMockTree(operations);
53
57
  const mockCode = generateMockTree(tree);
54
- return `// AUTO-GENERATED by @noego/wood -- do not edit
58
+ return `${(0, import_generated_file_notice.generatedFileNotice)(TEST_MOCK_SOURCE_INSTRUCTIONS)}
55
59
  // Regenerated by noego dev and noego build when YAML changes
56
60
  import { vi } from 'vitest';
57
61
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/codegen/test_mock_generator.ts"],"sourcesContent":["import type { OperationDef } from '../types/index.cjs';\n\nfunction buildNestedMockTree(operations: Map<string, OperationDef>): Record<string, unknown> {\n const tree: Record<string, unknown> = {};\n for (const [channel, op] of operations) {\n const parts = channel.split('.');\n let current: Record<string, unknown> = tree;\n for (let i = 0; i < parts.length - 1; i++) {\n if (!current[parts[i]]) current[parts[i]] = {};\n current = current[parts[i]] as Record<string, unknown>;\n }\n current[parts[parts.length - 1]] = { __operation: op };\n }\n return tree;\n}\n\nfunction generateMockTree(node: Record<string, unknown>, indent: string = ' '): string {\n const lines: string[] = [];\n for (const [key, value] of Object.entries(node)) {\n const entry = value as Record<string, unknown>;\n if (entry.__operation) {\n lines.push(`${indent}${key}: vi.fn().mockResolvedValue({}),`);\n } else {\n lines.push(`${indent}${key}: {`);\n lines.push(generateMockTree(entry, indent + ' '));\n lines.push(`${indent}},`);\n }\n }\n return lines.join('\\n');\n}\n\nexport function generateTestMock(operations: Map<string, OperationDef>): string {\n const tree = buildNestedMockTree(operations);\n const mockCode = generateMockTree(tree);\n\n return `// AUTO-GENERATED by @noego/wood -- do not edit\n// Regenerated by noego dev and noego build when YAML changes\nimport { vi } from 'vitest';\n\nconst __WOOD_INTERNAL_BRIDGE_KEY = '__NOEGO_WOOD_BRIDGE__';\n\nconst mockWood = {\n${mockCode}\n __load: vi.fn(),\n __navigate: vi.fn(),\n __window: {\n open: vi.fn(),\n close: vi.fn(),\n focus: vi.fn(),\n minimize: vi.fn(),\n maximize: vi.fn(),\n },\n __debug: {\n current: vi.fn().mockResolvedValue({\n ok: true,\n enabled: false,\n mode: 'production',\n windows: [],\n }),\n },\n __contextMenu: {\n show: vi.fn(),\n },\n on: vi.fn(() => vi.fn()),\n __log: vi.fn().mockResolvedValue({\n ok: true,\n forwarded: false,\n configured: false,\n reason: 'unconfigured',\n }),\n};\n\nObject.defineProperty(window, __WOOD_INTERNAL_BRIDGE_KEY, { value: mockWood, writable: true });\n`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,SAAS,oBAAoB,YAAgE;AAC3F,QAAM,OAAgC,CAAC;AACvC,aAAW,CAAC,SAAS,EAAE,KAAK,YAAY;AACtC,UAAM,QAAQ,QAAQ,MAAM,GAAG;AAC/B,QAAI,UAAmC;AACvC,aAAS,IAAI,GAAG,IAAI,MAAM,SAAS,GAAG,KAAK;AACzC,UAAI,CAAC,QAAQ,MAAM,CAAC,CAAC,EAAG,SAAQ,MAAM,CAAC,CAAC,IAAI,CAAC;AAC7C,gBAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,IAC5B;AACA,YAAQ,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,EAAE,aAAa,GAAG;AAAA,EACvD;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,MAA+B,SAAiB,MAAc;AACtF,QAAM,QAAkB,CAAC;AACzB,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,UAAM,QAAQ;AACd,QAAI,MAAM,aAAa;AACrB,YAAM,KAAK,GAAG,MAAM,GAAG,GAAG,kCAAkC;AAAA,IAC9D,OAAO;AACL,YAAM,KAAK,GAAG,MAAM,GAAG,GAAG,KAAK;AAC/B,YAAM,KAAK,iBAAiB,OAAO,SAAS,IAAI,CAAC;AACjD,YAAM,KAAK,GAAG,MAAM,IAAI;AAAA,IAC1B;AAAA,EACF;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,SAAS,iBAAiB,YAA+C;AAC9E,QAAM,OAAO,oBAAoB,UAAU;AAC3C,QAAM,WAAW,iBAAiB,IAAI;AAEtC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOP,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgCV;","names":[]}
1
+ {"version":3,"sources":["../../src/codegen/test_mock_generator.ts"],"sourcesContent":["import type { OperationDef } from '../types/index.cjs';\nimport { generatedFileNotice } from './generated_file_notice.cjs';\n\nconst TEST_MOCK_SOURCE_INSTRUCTIONS = [\n 'To change mocked IPC shape, edit the operations YAML configured by wood.config.yml main.openapi.',\n] as const;\n\nfunction buildNestedMockTree(operations: Map<string, OperationDef>): Record<string, unknown> {\n const tree: Record<string, unknown> = {};\n for (const [channel, op] of operations) {\n const parts = channel.split('.');\n let current: Record<string, unknown> = tree;\n for (let i = 0; i < parts.length - 1; i++) {\n if (!current[parts[i]]) current[parts[i]] = {};\n current = current[parts[i]] as Record<string, unknown>;\n }\n current[parts[parts.length - 1]] = { __operation: op };\n }\n return tree;\n}\n\nfunction generateMockTree(node: Record<string, unknown>, indent: string = ' '): string {\n const lines: string[] = [];\n for (const [key, value] of Object.entries(node)) {\n const entry = value as Record<string, unknown>;\n if (entry.__operation) {\n lines.push(`${indent}${key}: vi.fn().mockResolvedValue({}),`);\n } else {\n lines.push(`${indent}${key}: {`);\n lines.push(generateMockTree(entry, indent + ' '));\n lines.push(`${indent}},`);\n }\n }\n return lines.join('\\n');\n}\n\nexport function generateTestMock(operations: Map<string, OperationDef>): string {\n const tree = buildNestedMockTree(operations);\n const mockCode = generateMockTree(tree);\n\n return `${generatedFileNotice(TEST_MOCK_SOURCE_INSTRUCTIONS)}\n// Regenerated by noego dev and noego build when YAML changes\nimport { vi } from 'vitest';\n\nconst __WOOD_INTERNAL_BRIDGE_KEY = '__NOEGO_WOOD_BRIDGE__';\n\nconst mockWood = {\n${mockCode}\n __load: vi.fn(),\n __navigate: vi.fn(),\n __window: {\n open: vi.fn(),\n close: vi.fn(),\n focus: vi.fn(),\n minimize: vi.fn(),\n maximize: vi.fn(),\n },\n __debug: {\n current: vi.fn().mockResolvedValue({\n ok: true,\n enabled: false,\n mode: 'production',\n windows: [],\n }),\n },\n __contextMenu: {\n show: vi.fn(),\n },\n on: vi.fn(() => vi.fn()),\n __log: vi.fn().mockResolvedValue({\n ok: true,\n forwarded: false,\n configured: false,\n reason: 'unconfigured',\n }),\n};\n\nObject.defineProperty(window, __WOOD_INTERNAL_BRIDGE_KEY, { value: mockWood, writable: true });\n`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mCAAoC;AAEpC,MAAM,gCAAgC;AAAA,EACpC;AACF;AAEA,SAAS,oBAAoB,YAAgE;AAC3F,QAAM,OAAgC,CAAC;AACvC,aAAW,CAAC,SAAS,EAAE,KAAK,YAAY;AACtC,UAAM,QAAQ,QAAQ,MAAM,GAAG;AAC/B,QAAI,UAAmC;AACvC,aAAS,IAAI,GAAG,IAAI,MAAM,SAAS,GAAG,KAAK;AACzC,UAAI,CAAC,QAAQ,MAAM,CAAC,CAAC,EAAG,SAAQ,MAAM,CAAC,CAAC,IAAI,CAAC;AAC7C,gBAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,IAC5B;AACA,YAAQ,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,EAAE,aAAa,GAAG;AAAA,EACvD;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,MAA+B,SAAiB,MAAc;AACtF,QAAM,QAAkB,CAAC;AACzB,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,UAAM,QAAQ;AACd,QAAI,MAAM,aAAa;AACrB,YAAM,KAAK,GAAG,MAAM,GAAG,GAAG,kCAAkC;AAAA,IAC9D,OAAO;AACL,YAAM,KAAK,GAAG,MAAM,GAAG,GAAG,KAAK;AAC/B,YAAM,KAAK,iBAAiB,OAAO,SAAS,IAAI,CAAC;AACjD,YAAM,KAAK,GAAG,MAAM,IAAI;AAAA,IAC1B;AAAA,EACF;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,SAAS,iBAAiB,YAA+C;AAC9E,QAAM,OAAO,oBAAoB,UAAU;AAC3C,QAAM,WAAW,iBAAiB,IAAI;AAEtC,SAAO,OAAG,kDAAoB,6BAA6B,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO5D,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgCV;","names":[]}
@@ -1,3 +1,7 @@
1
+ import { generatedFileNotice } from "./generated_file_notice.js";
2
+ const TEST_MOCK_SOURCE_INSTRUCTIONS = [
3
+ "To change mocked IPC shape, edit the operations YAML configured by wood.config.yml main.openapi."
4
+ ];
1
5
  function buildNestedMockTree(operations) {
2
6
  const tree = {};
3
7
  for (const [channel, op] of operations) {
@@ -28,7 +32,7 @@ function generateMockTree(node, indent = " ") {
28
32
  function generateTestMock(operations) {
29
33
  const tree = buildNestedMockTree(operations);
30
34
  const mockCode = generateMockTree(tree);
31
- return `// AUTO-GENERATED by @noego/wood -- do not edit
35
+ return `${generatedFileNotice(TEST_MOCK_SOURCE_INSTRUCTIONS)}
32
36
  // Regenerated by noego dev and noego build when YAML changes
33
37
  import { vi } from 'vitest';
34
38
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/codegen/test_mock_generator.ts"],"sourcesContent":["import type { OperationDef } from '../types/index.js';\n\nfunction buildNestedMockTree(operations: Map<string, OperationDef>): Record<string, unknown> {\n const tree: Record<string, unknown> = {};\n for (const [channel, op] of operations) {\n const parts = channel.split('.');\n let current: Record<string, unknown> = tree;\n for (let i = 0; i < parts.length - 1; i++) {\n if (!current[parts[i]]) current[parts[i]] = {};\n current = current[parts[i]] as Record<string, unknown>;\n }\n current[parts[parts.length - 1]] = { __operation: op };\n }\n return tree;\n}\n\nfunction generateMockTree(node: Record<string, unknown>, indent: string = ' '): string {\n const lines: string[] = [];\n for (const [key, value] of Object.entries(node)) {\n const entry = value as Record<string, unknown>;\n if (entry.__operation) {\n lines.push(`${indent}${key}: vi.fn().mockResolvedValue({}),`);\n } else {\n lines.push(`${indent}${key}: {`);\n lines.push(generateMockTree(entry, indent + ' '));\n lines.push(`${indent}},`);\n }\n }\n return lines.join('\\n');\n}\n\nexport function generateTestMock(operations: Map<string, OperationDef>): string {\n const tree = buildNestedMockTree(operations);\n const mockCode = generateMockTree(tree);\n\n return `// AUTO-GENERATED by @noego/wood -- do not edit\n// Regenerated by noego dev and noego build when YAML changes\nimport { vi } from 'vitest';\n\nconst __WOOD_INTERNAL_BRIDGE_KEY = '__NOEGO_WOOD_BRIDGE__';\n\nconst mockWood = {\n${mockCode}\n __load: vi.fn(),\n __navigate: vi.fn(),\n __window: {\n open: vi.fn(),\n close: vi.fn(),\n focus: vi.fn(),\n minimize: vi.fn(),\n maximize: vi.fn(),\n },\n __debug: {\n current: vi.fn().mockResolvedValue({\n ok: true,\n enabled: false,\n mode: 'production',\n windows: [],\n }),\n },\n __contextMenu: {\n show: vi.fn(),\n },\n on: vi.fn(() => vi.fn()),\n __log: vi.fn().mockResolvedValue({\n ok: true,\n forwarded: false,\n configured: false,\n reason: 'unconfigured',\n }),\n};\n\nObject.defineProperty(window, __WOOD_INTERNAL_BRIDGE_KEY, { value: mockWood, writable: true });\n`;\n}\n"],"mappings":"AAEA,SAAS,oBAAoB,YAAgE;AAC3F,QAAM,OAAgC,CAAC;AACvC,aAAW,CAAC,SAAS,EAAE,KAAK,YAAY;AACtC,UAAM,QAAQ,QAAQ,MAAM,GAAG;AAC/B,QAAI,UAAmC;AACvC,aAAS,IAAI,GAAG,IAAI,MAAM,SAAS,GAAG,KAAK;AACzC,UAAI,CAAC,QAAQ,MAAM,CAAC,CAAC,EAAG,SAAQ,MAAM,CAAC,CAAC,IAAI,CAAC;AAC7C,gBAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,IAC5B;AACA,YAAQ,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,EAAE,aAAa,GAAG;AAAA,EACvD;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,MAA+B,SAAiB,MAAc;AACtF,QAAM,QAAkB,CAAC;AACzB,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,UAAM,QAAQ;AACd,QAAI,MAAM,aAAa;AACrB,YAAM,KAAK,GAAG,MAAM,GAAG,GAAG,kCAAkC;AAAA,IAC9D,OAAO;AACL,YAAM,KAAK,GAAG,MAAM,GAAG,GAAG,KAAK;AAC/B,YAAM,KAAK,iBAAiB,OAAO,SAAS,IAAI,CAAC;AACjD,YAAM,KAAK,GAAG,MAAM,IAAI;AAAA,IAC1B;AAAA,EACF;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,SAAS,iBAAiB,YAA+C;AAC9E,QAAM,OAAO,oBAAoB,UAAU;AAC3C,QAAM,WAAW,iBAAiB,IAAI;AAEtC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOP,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgCV;","names":[]}
1
+ {"version":3,"sources":["../../src/codegen/test_mock_generator.ts"],"sourcesContent":["import type { OperationDef } from '../types/index.js';\nimport { generatedFileNotice } from './generated_file_notice.js';\n\nconst TEST_MOCK_SOURCE_INSTRUCTIONS = [\n 'To change mocked IPC shape, edit the operations YAML configured by wood.config.yml main.openapi.',\n] as const;\n\nfunction buildNestedMockTree(operations: Map<string, OperationDef>): Record<string, unknown> {\n const tree: Record<string, unknown> = {};\n for (const [channel, op] of operations) {\n const parts = channel.split('.');\n let current: Record<string, unknown> = tree;\n for (let i = 0; i < parts.length - 1; i++) {\n if (!current[parts[i]]) current[parts[i]] = {};\n current = current[parts[i]] as Record<string, unknown>;\n }\n current[parts[parts.length - 1]] = { __operation: op };\n }\n return tree;\n}\n\nfunction generateMockTree(node: Record<string, unknown>, indent: string = ' '): string {\n const lines: string[] = [];\n for (const [key, value] of Object.entries(node)) {\n const entry = value as Record<string, unknown>;\n if (entry.__operation) {\n lines.push(`${indent}${key}: vi.fn().mockResolvedValue({}),`);\n } else {\n lines.push(`${indent}${key}: {`);\n lines.push(generateMockTree(entry, indent + ' '));\n lines.push(`${indent}},`);\n }\n }\n return lines.join('\\n');\n}\n\nexport function generateTestMock(operations: Map<string, OperationDef>): string {\n const tree = buildNestedMockTree(operations);\n const mockCode = generateMockTree(tree);\n\n return `${generatedFileNotice(TEST_MOCK_SOURCE_INSTRUCTIONS)}\n// Regenerated by noego dev and noego build when YAML changes\nimport { vi } from 'vitest';\n\nconst __WOOD_INTERNAL_BRIDGE_KEY = '__NOEGO_WOOD_BRIDGE__';\n\nconst mockWood = {\n${mockCode}\n __load: vi.fn(),\n __navigate: vi.fn(),\n __window: {\n open: vi.fn(),\n close: vi.fn(),\n focus: vi.fn(),\n minimize: vi.fn(),\n maximize: vi.fn(),\n },\n __debug: {\n current: vi.fn().mockResolvedValue({\n ok: true,\n enabled: false,\n mode: 'production',\n windows: [],\n }),\n },\n __contextMenu: {\n show: vi.fn(),\n },\n on: vi.fn(() => vi.fn()),\n __log: vi.fn().mockResolvedValue({\n ok: true,\n forwarded: false,\n configured: false,\n reason: 'unconfigured',\n }),\n};\n\nObject.defineProperty(window, __WOOD_INTERNAL_BRIDGE_KEY, { value: mockWood, writable: true });\n`;\n}\n"],"mappings":"AACA,SAAS,2BAA2B;AAEpC,MAAM,gCAAgC;AAAA,EACpC;AACF;AAEA,SAAS,oBAAoB,YAAgE;AAC3F,QAAM,OAAgC,CAAC;AACvC,aAAW,CAAC,SAAS,EAAE,KAAK,YAAY;AACtC,UAAM,QAAQ,QAAQ,MAAM,GAAG;AAC/B,QAAI,UAAmC;AACvC,aAAS,IAAI,GAAG,IAAI,MAAM,SAAS,GAAG,KAAK;AACzC,UAAI,CAAC,QAAQ,MAAM,CAAC,CAAC,EAAG,SAAQ,MAAM,CAAC,CAAC,IAAI,CAAC;AAC7C,gBAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,IAC5B;AACA,YAAQ,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,EAAE,aAAa,GAAG;AAAA,EACvD;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,MAA+B,SAAiB,MAAc;AACtF,QAAM,QAAkB,CAAC;AACzB,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,UAAM,QAAQ;AACd,QAAI,MAAM,aAAa;AACrB,YAAM,KAAK,GAAG,MAAM,GAAG,GAAG,kCAAkC;AAAA,IAC9D,OAAO;AACL,YAAM,KAAK,GAAG,MAAM,GAAG,GAAG,KAAK;AAC/B,YAAM,KAAK,iBAAiB,OAAO,SAAS,IAAI,CAAC;AACjD,YAAM,KAAK,GAAG,MAAM,IAAI;AAAA,IAC1B;AAAA,EACF;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,SAAS,iBAAiB,YAA+C;AAC9E,QAAM,OAAO,oBAAoB,UAAU;AAC3C,QAAM,WAAW,iBAAiB,IAAI;AAEtC,SAAO,GAAG,oBAAoB,6BAA6B,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO5D,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgCV;","names":[]}
@@ -21,6 +21,11 @@ __export(type_generator_exports, {
21
21
  generateTypes: () => generateTypes
22
22
  });
23
23
  module.exports = __toCommonJS(type_generator_exports);
24
+ var import_generated_file_notice = require("./generated_file_notice.cjs");
25
+ const TYPE_SOURCE_INSTRUCTIONS = [
26
+ "To change IPC channels, input schemas, controller/action names, or renderer bridge types,",
27
+ "edit the operations YAML configured by wood.config.yml main.openapi and the matching controller methods."
28
+ ];
24
29
  function formatPropertyKey(key) {
25
30
  if (/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key)) {
26
31
  return key;
@@ -144,7 +149,7 @@ function generateTypes(operations) {
144
149
  const tree = buildNestedTypeTree(operations);
145
150
  const typesCode = generateTypeTree(tree);
146
151
  const rpcTypeCode = generateRpcTypeTree(operations);
147
- return `// AUTO-GENERATED by @noego/wood -- do not edit
152
+ return `${(0, import_generated_file_notice.generatedFileNotice)(TYPE_SOURCE_INSTRUCTIONS)}
148
153
  export interface WoodRpcManifestEntry {
149
154
  channel: string;
150
155
  controller: string;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/codegen/type_generator.ts"],"sourcesContent":["import type { OperationDef } from '../types/index.cjs';\n\nfunction formatPropertyKey(key: string): string {\n if (/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key)) {\n return key;\n }\n\n return JSON.stringify(key);\n}\n\nfunction operationHasInput(op: OperationDef): boolean {\n return Boolean(\n op.inputSchema &&\n (op.inputSchema as Record<string, unknown>).type === 'object' &&\n Object.keys((op.inputSchema as Record<string, Record<string, unknown>>).properties ?? {}).length > 0,\n );\n}\n\nfunction jsonSchemaToTS(schema: Record<string, unknown> | undefined, indent: string = ''): string {\n if (!schema) return 'unknown';\n\n const type = schema.type as string | undefined;\n\n if (type === 'string') {\n if (schema.enum) {\n return (schema.enum as string[]).map((v) => `'${v}'`).join(' | ');\n }\n return 'string';\n }\n if (type === 'number' || type === 'integer') return 'number';\n if (type === 'boolean') return 'boolean';\n if (type === 'array') {\n const itemType = jsonSchemaToTS(schema.items as Record<string, unknown>, indent);\n return `Array<${itemType}>`;\n }\n if (type === 'object') {\n const props = (schema.properties ?? {}) as Record<string, Record<string, unknown>>;\n const required = new Set((schema.required as string[]) ?? []);\n const entries = Object.entries(props);\n if (entries.length === 0) return 'Record<string, unknown>';\n\n const lines = entries.map(([key, val]) => {\n const optional = required.has(key) ? '' : '?';\n const valType = jsonSchemaToTS(val, indent + ' ');\n return `${indent} ${formatPropertyKey(key)}${optional}: ${valType};`;\n });\n return `{\\n${lines.join('\\n')}\\n${indent}}`;\n }\n\n return 'unknown';\n}\n\nfunction buildNestedTypeTree(operations: Map<string, OperationDef>): Record<string, unknown> {\n const tree: Record<string, unknown> = {};\n for (const [channel, op] of operations) {\n const parts = channel.split('.');\n let current: Record<string, unknown> = tree;\n for (let i = 0; i < parts.length - 1; i++) {\n if (!current[parts[i]]) current[parts[i]] = {};\n current = current[parts[i]] as Record<string, unknown>;\n }\n current[parts[parts.length - 1]] = { __operation: op };\n }\n return tree;\n}\n\nfunction generateTypeTree(node: Record<string, unknown>, indent: string = ' '): string {\n const lines: string[] = [];\n for (const [key, value] of Object.entries(node)) {\n const entry = value as Record<string, unknown>;\n if (entry.__operation) {\n const op = entry.__operation as OperationDef;\n const inputType = jsonSchemaToTS(op.inputSchema as Record<string, unknown>, indent + ' ');\n const outputType = jsonSchemaToTS(op.outputSchema as Record<string, unknown>, indent + ' ');\n const hasInput = operationHasInput(op);\n\n if (hasInput) {\n lines.push(`${indent}${formatPropertyKey(key)}(data: ${inputType}): Promise<${outputType}>;`);\n } else {\n lines.push(`${indent}${formatPropertyKey(key)}(): Promise<${outputType}>;`);\n }\n } else {\n lines.push(`${indent}${formatPropertyKey(key)}: {`);\n lines.push(generateTypeTree(entry, indent + ' '));\n lines.push(`${indent}};`);\n }\n }\n return lines.join('\\n');\n}\n\ntype RpcActionTypeEntry = {\n channel: string;\n inputType: string;\n outputType: string;\n hasInput: boolean;\n};\n\nfunction buildRpcControllerTree(\n operations: Map<string, OperationDef>,\n): Record<string, Record<string, RpcActionTypeEntry>> {\n const tree: Record<string, Record<string, RpcActionTypeEntry>> = {};\n\n for (const operation of operations.values()) {\n const controller = operation.controller;\n const action = operation.action;\n\n if (!tree[controller]) {\n tree[controller] = {};\n }\n\n if (tree[controller][action]) {\n throw new Error(\n `Type codegen failed: duplicate RPC action \"${controller}.${action}\" found in channel \"${operation.channel}\".`,\n );\n }\n\n tree[controller][action] = {\n channel: operation.channel,\n inputType: jsonSchemaToTS(operation.inputSchema as Record<string, unknown>, ' '),\n outputType: jsonSchemaToTS(operation.outputSchema as Record<string, unknown>, ' '),\n hasInput: operationHasInput(operation),\n };\n }\n\n return tree;\n}\n\nfunction generateRpcTypeTree(operations: Map<string, OperationDef>): string {\n const controllerTree = buildRpcControllerTree(operations);\n const controllerNames = Object.keys(controllerTree).sort((a, b) => a.localeCompare(b));\n const lines: string[] = [];\n\n for (const controllerName of controllerNames) {\n lines.push(` ${formatPropertyKey(controllerName)}: {`);\n const actions = controllerTree[controllerName];\n const actionNames = Object.keys(actions).sort((a, b) => a.localeCompare(b));\n for (const actionName of actionNames) {\n const action = actions[actionName];\n if (action.hasInput) {\n lines.push(` ${formatPropertyKey(actionName)}(data: ${action.inputType}): Promise<${action.outputType}>;`);\n } else {\n lines.push(` ${formatPropertyKey(actionName)}(): Promise<${action.outputType}>;`);\n }\n }\n lines.push(' };');\n }\n\n return lines.join('\\n');\n}\n\nexport function generateTypes(operations: Map<string, OperationDef>): string {\n const tree = buildNestedTypeTree(operations);\n const typesCode = generateTypeTree(tree);\n const rpcTypeCode = generateRpcTypeTree(operations);\n\n return `// AUTO-GENERATED by @noego/wood -- do not edit\nexport interface WoodRpcManifestEntry {\n channel: string;\n controller: string;\n action: string;\n path: string[];\n hasInput: boolean;\n}\n\n/**\n * Project-specific renderer App facade contract.\n *\n * This matches @noego/wood/client getApp() and injected App instances:\n * controller name -> controller action.\n */\nexport interface GeneratedApp {\n${rpcTypeCode}\n}\n\n/** Backward-compatible name for the generated client App facade contract. */\nexport interface WoodRpcApi extends GeneratedApp {}\n\n/**\n * Project-specific raw preload bridge contract.\n *\n * This matches the channel path exposed by preload.generated.ts:\n * operation channel segments -> invoke function.\n */\nexport interface GeneratedWoodBridge {\n${typesCode}\n}\n\nexport interface WoodApi extends GeneratedWoodBridge {\n __rpcManifest: WoodRpcManifestEntry[];\n __load(route: string, params: Record<string, string>): Promise<unknown>;\n __navigate(windowId: string, route: string): Promise<void>;\n __window: {\n current(): Promise<{ ok: boolean; windowId?: string; defaultRoute?: string }>;\n open(windowId: string, options?: Record<string, unknown>): Promise<void>;\n close(windowId?: string): Promise<void>;\n focus(windowId: string): Promise<void>;\n minimize(windowId?: string): Promise<void>;\n maximize(windowId?: string): Promise<void>;\n };\n __debug: {\n current(): Promise<{\n ok: boolean;\n enabled: boolean;\n mode: 'development' | 'production';\n port?: number;\n windows: Array<{\n windowId: string;\n title: string;\n webContentsId: number;\n url: string;\n focused: boolean;\n rendererHealth?: 'ready' | 'loading' | 'unresponsive' | 'gone' | 'destroyed';\n }>;\n }>;\n };\n __contextMenu: {\n show(data: {\n items: Array<{ label?: string; action?: string; data?: string; _callbackId?: string; disabled?: boolean; type?: 'separator' }>;\n position: { x: number; y: number };\n }): Promise<void>;\n };\n on(channel: string, callback: (...args: unknown[]) => void): () => void;\n __log(level: string, logger: string, message: string, context?: unknown): Promise<{\n ok: boolean;\n forwarded: boolean;\n configured: boolean;\n reason?: 'unconfigured' | 'callback-error';\n errorMessage?: string;\n }>;\n}\n`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,SAAS,kBAAkB,KAAqB;AAC9C,MAAI,6BAA6B,KAAK,GAAG,GAAG;AAC1C,WAAO;AAAA,EACT;AAEA,SAAO,KAAK,UAAU,GAAG;AAC3B;AAEA,SAAS,kBAAkB,IAA2B;AACpD,SAAO;AAAA,IACL,GAAG,eACA,GAAG,YAAwC,SAAS,YACrD,OAAO,KAAM,GAAG,YAAwD,cAAc,CAAC,CAAC,EAAE,SAAS;AAAA,EACvG;AACF;AAEA,SAAS,eAAe,QAA6C,SAAiB,IAAY;AAChG,MAAI,CAAC,OAAQ,QAAO;AAEpB,QAAM,OAAO,OAAO;AAEpB,MAAI,SAAS,UAAU;AACrB,QAAI,OAAO,MAAM;AACf,aAAQ,OAAO,KAAkB,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,KAAK,KAAK;AAAA,IAClE;AACA,WAAO;AAAA,EACT;AACA,MAAI,SAAS,YAAY,SAAS,UAAW,QAAO;AACpD,MAAI,SAAS,UAAW,QAAO;AAC/B,MAAI,SAAS,SAAS;AACpB,UAAM,WAAW,eAAe,OAAO,OAAkC,MAAM;AAC/E,WAAO,SAAS,QAAQ;AAAA,EAC1B;AACA,MAAI,SAAS,UAAU;AACrB,UAAM,QAAS,OAAO,cAAc,CAAC;AACrC,UAAM,WAAW,IAAI,IAAK,OAAO,YAAyB,CAAC,CAAC;AAC5D,UAAM,UAAU,OAAO,QAAQ,KAAK;AACpC,QAAI,QAAQ,WAAW,EAAG,QAAO;AAEjC,UAAM,QAAQ,QAAQ,IAAI,CAAC,CAAC,KAAK,GAAG,MAAM;AACxC,YAAM,WAAW,SAAS,IAAI,GAAG,IAAI,KAAK;AAC1C,YAAM,UAAU,eAAe,KAAK,SAAS,IAAI;AACjD,aAAO,GAAG,MAAM,KAAK,kBAAkB,GAAG,CAAC,GAAG,QAAQ,KAAK,OAAO;AAAA,IACpE,CAAC;AACD,WAAO;AAAA,EAAM,MAAM,KAAK,IAAI,CAAC;AAAA,EAAK,MAAM;AAAA,EAC1C;AAEA,SAAO;AACT;AAEA,SAAS,oBAAoB,YAAgE;AAC3F,QAAM,OAAgC,CAAC;AACvC,aAAW,CAAC,SAAS,EAAE,KAAK,YAAY;AACtC,UAAM,QAAQ,QAAQ,MAAM,GAAG;AAC/B,QAAI,UAAmC;AACvC,aAAS,IAAI,GAAG,IAAI,MAAM,SAAS,GAAG,KAAK;AACzC,UAAI,CAAC,QAAQ,MAAM,CAAC,CAAC,EAAG,SAAQ,MAAM,CAAC,CAAC,IAAI,CAAC;AAC7C,gBAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,IAC5B;AACA,YAAQ,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,EAAE,aAAa,GAAG;AAAA,EACvD;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,MAA+B,SAAiB,MAAc;AACtF,QAAM,QAAkB,CAAC;AACzB,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,UAAM,QAAQ;AACd,QAAI,MAAM,aAAa;AACrB,YAAM,KAAK,MAAM;AACjB,YAAM,YAAY,eAAe,GAAG,aAAwC,SAAS,IAAI;AACzF,YAAM,aAAa,eAAe,GAAG,cAAyC,SAAS,IAAI;AAC3F,YAAM,WAAW,kBAAkB,EAAE;AAErC,UAAI,UAAU;AACZ,cAAM,KAAK,GAAG,MAAM,GAAG,kBAAkB,GAAG,CAAC,UAAU,SAAS,cAAc,UAAU,IAAI;AAAA,MAC9F,OAAO;AACL,cAAM,KAAK,GAAG,MAAM,GAAG,kBAAkB,GAAG,CAAC,eAAe,UAAU,IAAI;AAAA,MAC5E;AAAA,IACF,OAAO;AACL,YAAM,KAAK,GAAG,MAAM,GAAG,kBAAkB,GAAG,CAAC,KAAK;AAClD,YAAM,KAAK,iBAAiB,OAAO,SAAS,IAAI,CAAC;AACjD,YAAM,KAAK,GAAG,MAAM,IAAI;AAAA,IAC1B;AAAA,EACF;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AASA,SAAS,uBACP,YACoD;AACpD,QAAM,OAA2D,CAAC;AAElE,aAAW,aAAa,WAAW,OAAO,GAAG;AAC3C,UAAM,aAAa,UAAU;AAC7B,UAAM,SAAS,UAAU;AAEzB,QAAI,CAAC,KAAK,UAAU,GAAG;AACrB,WAAK,UAAU,IAAI,CAAC;AAAA,IACtB;AAEA,QAAI,KAAK,UAAU,EAAE,MAAM,GAAG;AAC5B,YAAM,IAAI;AAAA,QACR,8CAA8C,UAAU,IAAI,MAAM,uBAAuB,UAAU,OAAO;AAAA,MAC5G;AAAA,IACF;AAEA,SAAK,UAAU,EAAE,MAAM,IAAI;AAAA,MACzB,SAAS,UAAU;AAAA,MACnB,WAAW,eAAe,UAAU,aAAwC,MAAM;AAAA,MAClF,YAAY,eAAe,UAAU,cAAyC,MAAM;AAAA,MACpF,UAAU,kBAAkB,SAAS;AAAA,IACvC;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,oBAAoB,YAA+C;AAC1E,QAAM,iBAAiB,uBAAuB,UAAU;AACxD,QAAM,kBAAkB,OAAO,KAAK,cAAc,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,cAAc,CAAC,CAAC;AACrF,QAAM,QAAkB,CAAC;AAEzB,aAAW,kBAAkB,iBAAiB;AAC5C,UAAM,KAAK,KAAK,kBAAkB,cAAc,CAAC,KAAK;AACtD,UAAM,UAAU,eAAe,cAAc;AAC7C,UAAM,cAAc,OAAO,KAAK,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,cAAc,CAAC,CAAC;AAC1E,eAAW,cAAc,aAAa;AACpC,YAAM,SAAS,QAAQ,UAAU;AACjC,UAAI,OAAO,UAAU;AACnB,cAAM,KAAK,OAAO,kBAAkB,UAAU,CAAC,UAAU,OAAO,SAAS,cAAc,OAAO,UAAU,IAAI;AAAA,MAC9G,OAAO;AACL,cAAM,KAAK,OAAO,kBAAkB,UAAU,CAAC,eAAe,OAAO,UAAU,IAAI;AAAA,MACrF;AAAA,IACF;AACA,UAAM,KAAK,MAAM;AAAA,EACnB;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,SAAS,cAAc,YAA+C;AAC3E,QAAM,OAAO,oBAAoB,UAAU;AAC3C,QAAM,YAAY,iBAAiB,IAAI;AACvC,QAAM,cAAc,oBAAoB,UAAU;AAElD,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBP,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaX,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA+CX;","names":[]}
1
+ {"version":3,"sources":["../../src/codegen/type_generator.ts"],"sourcesContent":["import type { OperationDef } from '../types/index.cjs';\nimport { generatedFileNotice } from './generated_file_notice.cjs';\n\nconst TYPE_SOURCE_INSTRUCTIONS = [\n 'To change IPC channels, input schemas, controller/action names, or renderer bridge types,',\n 'edit the operations YAML configured by wood.config.yml main.openapi and the matching controller methods.',\n] as const;\n\nfunction formatPropertyKey(key: string): string {\n if (/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key)) {\n return key;\n }\n\n return JSON.stringify(key);\n}\n\nfunction operationHasInput(op: OperationDef): boolean {\n return Boolean(\n op.inputSchema &&\n (op.inputSchema as Record<string, unknown>).type === 'object' &&\n Object.keys((op.inputSchema as Record<string, Record<string, unknown>>).properties ?? {}).length > 0,\n );\n}\n\nfunction jsonSchemaToTS(schema: Record<string, unknown> | undefined, indent: string = ''): string {\n if (!schema) return 'unknown';\n\n const type = schema.type as string | undefined;\n\n if (type === 'string') {\n if (schema.enum) {\n return (schema.enum as string[]).map((v) => `'${v}'`).join(' | ');\n }\n return 'string';\n }\n if (type === 'number' || type === 'integer') return 'number';\n if (type === 'boolean') return 'boolean';\n if (type === 'array') {\n const itemType = jsonSchemaToTS(schema.items as Record<string, unknown>, indent);\n return `Array<${itemType}>`;\n }\n if (type === 'object') {\n const props = (schema.properties ?? {}) as Record<string, Record<string, unknown>>;\n const required = new Set((schema.required as string[]) ?? []);\n const entries = Object.entries(props);\n if (entries.length === 0) return 'Record<string, unknown>';\n\n const lines = entries.map(([key, val]) => {\n const optional = required.has(key) ? '' : '?';\n const valType = jsonSchemaToTS(val, indent + ' ');\n return `${indent} ${formatPropertyKey(key)}${optional}: ${valType};`;\n });\n return `{\\n${lines.join('\\n')}\\n${indent}}`;\n }\n\n return 'unknown';\n}\n\nfunction buildNestedTypeTree(operations: Map<string, OperationDef>): Record<string, unknown> {\n const tree: Record<string, unknown> = {};\n for (const [channel, op] of operations) {\n const parts = channel.split('.');\n let current: Record<string, unknown> = tree;\n for (let i = 0; i < parts.length - 1; i++) {\n if (!current[parts[i]]) current[parts[i]] = {};\n current = current[parts[i]] as Record<string, unknown>;\n }\n current[parts[parts.length - 1]] = { __operation: op };\n }\n return tree;\n}\n\nfunction generateTypeTree(node: Record<string, unknown>, indent: string = ' '): string {\n const lines: string[] = [];\n for (const [key, value] of Object.entries(node)) {\n const entry = value as Record<string, unknown>;\n if (entry.__operation) {\n const op = entry.__operation as OperationDef;\n const inputType = jsonSchemaToTS(op.inputSchema as Record<string, unknown>, indent + ' ');\n const outputType = jsonSchemaToTS(op.outputSchema as Record<string, unknown>, indent + ' ');\n const hasInput = operationHasInput(op);\n\n if (hasInput) {\n lines.push(`${indent}${formatPropertyKey(key)}(data: ${inputType}): Promise<${outputType}>;`);\n } else {\n lines.push(`${indent}${formatPropertyKey(key)}(): Promise<${outputType}>;`);\n }\n } else {\n lines.push(`${indent}${formatPropertyKey(key)}: {`);\n lines.push(generateTypeTree(entry, indent + ' '));\n lines.push(`${indent}};`);\n }\n }\n return lines.join('\\n');\n}\n\ntype RpcActionTypeEntry = {\n channel: string;\n inputType: string;\n outputType: string;\n hasInput: boolean;\n};\n\nfunction buildRpcControllerTree(\n operations: Map<string, OperationDef>,\n): Record<string, Record<string, RpcActionTypeEntry>> {\n const tree: Record<string, Record<string, RpcActionTypeEntry>> = {};\n\n for (const operation of operations.values()) {\n const controller = operation.controller;\n const action = operation.action;\n\n if (!tree[controller]) {\n tree[controller] = {};\n }\n\n if (tree[controller][action]) {\n throw new Error(\n `Type codegen failed: duplicate RPC action \"${controller}.${action}\" found in channel \"${operation.channel}\".`,\n );\n }\n\n tree[controller][action] = {\n channel: operation.channel,\n inputType: jsonSchemaToTS(operation.inputSchema as Record<string, unknown>, ' '),\n outputType: jsonSchemaToTS(operation.outputSchema as Record<string, unknown>, ' '),\n hasInput: operationHasInput(operation),\n };\n }\n\n return tree;\n}\n\nfunction generateRpcTypeTree(operations: Map<string, OperationDef>): string {\n const controllerTree = buildRpcControllerTree(operations);\n const controllerNames = Object.keys(controllerTree).sort((a, b) => a.localeCompare(b));\n const lines: string[] = [];\n\n for (const controllerName of controllerNames) {\n lines.push(` ${formatPropertyKey(controllerName)}: {`);\n const actions = controllerTree[controllerName];\n const actionNames = Object.keys(actions).sort((a, b) => a.localeCompare(b));\n for (const actionName of actionNames) {\n const action = actions[actionName];\n if (action.hasInput) {\n lines.push(` ${formatPropertyKey(actionName)}(data: ${action.inputType}): Promise<${action.outputType}>;`);\n } else {\n lines.push(` ${formatPropertyKey(actionName)}(): Promise<${action.outputType}>;`);\n }\n }\n lines.push(' };');\n }\n\n return lines.join('\\n');\n}\n\nexport function generateTypes(operations: Map<string, OperationDef>): string {\n const tree = buildNestedTypeTree(operations);\n const typesCode = generateTypeTree(tree);\n const rpcTypeCode = generateRpcTypeTree(operations);\n\n return `${generatedFileNotice(TYPE_SOURCE_INSTRUCTIONS)}\nexport interface WoodRpcManifestEntry {\n channel: string;\n controller: string;\n action: string;\n path: string[];\n hasInput: boolean;\n}\n\n/**\n * Project-specific renderer App facade contract.\n *\n * This matches @noego/wood/client getApp() and injected App instances:\n * controller name -> controller action.\n */\nexport interface GeneratedApp {\n${rpcTypeCode}\n}\n\n/** Backward-compatible name for the generated client App facade contract. */\nexport interface WoodRpcApi extends GeneratedApp {}\n\n/**\n * Project-specific raw preload bridge contract.\n *\n * This matches the channel path exposed by preload.generated.ts:\n * operation channel segments -> invoke function.\n */\nexport interface GeneratedWoodBridge {\n${typesCode}\n}\n\nexport interface WoodApi extends GeneratedWoodBridge {\n __rpcManifest: WoodRpcManifestEntry[];\n __load(route: string, params: Record<string, string>): Promise<unknown>;\n __navigate(windowId: string, route: string): Promise<void>;\n __window: {\n current(): Promise<{ ok: boolean; windowId?: string; defaultRoute?: string }>;\n open(windowId: string, options?: Record<string, unknown>): Promise<void>;\n close(windowId?: string): Promise<void>;\n focus(windowId: string): Promise<void>;\n minimize(windowId?: string): Promise<void>;\n maximize(windowId?: string): Promise<void>;\n };\n __debug: {\n current(): Promise<{\n ok: boolean;\n enabled: boolean;\n mode: 'development' | 'production';\n port?: number;\n windows: Array<{\n windowId: string;\n title: string;\n webContentsId: number;\n url: string;\n focused: boolean;\n rendererHealth?: 'ready' | 'loading' | 'unresponsive' | 'gone' | 'destroyed';\n }>;\n }>;\n };\n __contextMenu: {\n show(data: {\n items: Array<{ label?: string; action?: string; data?: string; _callbackId?: string; disabled?: boolean; type?: 'separator' }>;\n position: { x: number; y: number };\n }): Promise<void>;\n };\n on(channel: string, callback: (...args: unknown[]) => void): () => void;\n __log(level: string, logger: string, message: string, context?: unknown): Promise<{\n ok: boolean;\n forwarded: boolean;\n configured: boolean;\n reason?: 'unconfigured' | 'callback-error';\n errorMessage?: string;\n }>;\n}\n`;\n}\n"],"mappings":"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","names":[]}
@@ -1,3 +1,8 @@
1
+ import { generatedFileNotice } from "./generated_file_notice.js";
2
+ const TYPE_SOURCE_INSTRUCTIONS = [
3
+ "To change IPC channels, input schemas, controller/action names, or renderer bridge types,",
4
+ "edit the operations YAML configured by wood.config.yml main.openapi and the matching controller methods."
5
+ ];
1
6
  function formatPropertyKey(key) {
2
7
  if (/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key)) {
3
8
  return key;
@@ -121,7 +126,7 @@ function generateTypes(operations) {
121
126
  const tree = buildNestedTypeTree(operations);
122
127
  const typesCode = generateTypeTree(tree);
123
128
  const rpcTypeCode = generateRpcTypeTree(operations);
124
- return `// AUTO-GENERATED by @noego/wood -- do not edit
129
+ return `${generatedFileNotice(TYPE_SOURCE_INSTRUCTIONS)}
125
130
  export interface WoodRpcManifestEntry {
126
131
  channel: string;
127
132
  controller: string;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/codegen/type_generator.ts"],"sourcesContent":["import type { OperationDef } from '../types/index.js';\n\nfunction formatPropertyKey(key: string): string {\n if (/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key)) {\n return key;\n }\n\n return JSON.stringify(key);\n}\n\nfunction operationHasInput(op: OperationDef): boolean {\n return Boolean(\n op.inputSchema &&\n (op.inputSchema as Record<string, unknown>).type === 'object' &&\n Object.keys((op.inputSchema as Record<string, Record<string, unknown>>).properties ?? {}).length > 0,\n );\n}\n\nfunction jsonSchemaToTS(schema: Record<string, unknown> | undefined, indent: string = ''): string {\n if (!schema) return 'unknown';\n\n const type = schema.type as string | undefined;\n\n if (type === 'string') {\n if (schema.enum) {\n return (schema.enum as string[]).map((v) => `'${v}'`).join(' | ');\n }\n return 'string';\n }\n if (type === 'number' || type === 'integer') return 'number';\n if (type === 'boolean') return 'boolean';\n if (type === 'array') {\n const itemType = jsonSchemaToTS(schema.items as Record<string, unknown>, indent);\n return `Array<${itemType}>`;\n }\n if (type === 'object') {\n const props = (schema.properties ?? {}) as Record<string, Record<string, unknown>>;\n const required = new Set((schema.required as string[]) ?? []);\n const entries = Object.entries(props);\n if (entries.length === 0) return 'Record<string, unknown>';\n\n const lines = entries.map(([key, val]) => {\n const optional = required.has(key) ? '' : '?';\n const valType = jsonSchemaToTS(val, indent + ' ');\n return `${indent} ${formatPropertyKey(key)}${optional}: ${valType};`;\n });\n return `{\\n${lines.join('\\n')}\\n${indent}}`;\n }\n\n return 'unknown';\n}\n\nfunction buildNestedTypeTree(operations: Map<string, OperationDef>): Record<string, unknown> {\n const tree: Record<string, unknown> = {};\n for (const [channel, op] of operations) {\n const parts = channel.split('.');\n let current: Record<string, unknown> = tree;\n for (let i = 0; i < parts.length - 1; i++) {\n if (!current[parts[i]]) current[parts[i]] = {};\n current = current[parts[i]] as Record<string, unknown>;\n }\n current[parts[parts.length - 1]] = { __operation: op };\n }\n return tree;\n}\n\nfunction generateTypeTree(node: Record<string, unknown>, indent: string = ' '): string {\n const lines: string[] = [];\n for (const [key, value] of Object.entries(node)) {\n const entry = value as Record<string, unknown>;\n if (entry.__operation) {\n const op = entry.__operation as OperationDef;\n const inputType = jsonSchemaToTS(op.inputSchema as Record<string, unknown>, indent + ' ');\n const outputType = jsonSchemaToTS(op.outputSchema as Record<string, unknown>, indent + ' ');\n const hasInput = operationHasInput(op);\n\n if (hasInput) {\n lines.push(`${indent}${formatPropertyKey(key)}(data: ${inputType}): Promise<${outputType}>;`);\n } else {\n lines.push(`${indent}${formatPropertyKey(key)}(): Promise<${outputType}>;`);\n }\n } else {\n lines.push(`${indent}${formatPropertyKey(key)}: {`);\n lines.push(generateTypeTree(entry, indent + ' '));\n lines.push(`${indent}};`);\n }\n }\n return lines.join('\\n');\n}\n\ntype RpcActionTypeEntry = {\n channel: string;\n inputType: string;\n outputType: string;\n hasInput: boolean;\n};\n\nfunction buildRpcControllerTree(\n operations: Map<string, OperationDef>,\n): Record<string, Record<string, RpcActionTypeEntry>> {\n const tree: Record<string, Record<string, RpcActionTypeEntry>> = {};\n\n for (const operation of operations.values()) {\n const controller = operation.controller;\n const action = operation.action;\n\n if (!tree[controller]) {\n tree[controller] = {};\n }\n\n if (tree[controller][action]) {\n throw new Error(\n `Type codegen failed: duplicate RPC action \"${controller}.${action}\" found in channel \"${operation.channel}\".`,\n );\n }\n\n tree[controller][action] = {\n channel: operation.channel,\n inputType: jsonSchemaToTS(operation.inputSchema as Record<string, unknown>, ' '),\n outputType: jsonSchemaToTS(operation.outputSchema as Record<string, unknown>, ' '),\n hasInput: operationHasInput(operation),\n };\n }\n\n return tree;\n}\n\nfunction generateRpcTypeTree(operations: Map<string, OperationDef>): string {\n const controllerTree = buildRpcControllerTree(operations);\n const controllerNames = Object.keys(controllerTree).sort((a, b) => a.localeCompare(b));\n const lines: string[] = [];\n\n for (const controllerName of controllerNames) {\n lines.push(` ${formatPropertyKey(controllerName)}: {`);\n const actions = controllerTree[controllerName];\n const actionNames = Object.keys(actions).sort((a, b) => a.localeCompare(b));\n for (const actionName of actionNames) {\n const action = actions[actionName];\n if (action.hasInput) {\n lines.push(` ${formatPropertyKey(actionName)}(data: ${action.inputType}): Promise<${action.outputType}>;`);\n } else {\n lines.push(` ${formatPropertyKey(actionName)}(): Promise<${action.outputType}>;`);\n }\n }\n lines.push(' };');\n }\n\n return lines.join('\\n');\n}\n\nexport function generateTypes(operations: Map<string, OperationDef>): string {\n const tree = buildNestedTypeTree(operations);\n const typesCode = generateTypeTree(tree);\n const rpcTypeCode = generateRpcTypeTree(operations);\n\n return `// AUTO-GENERATED by @noego/wood -- do not edit\nexport interface WoodRpcManifestEntry {\n channel: string;\n controller: string;\n action: string;\n path: string[];\n hasInput: boolean;\n}\n\n/**\n * Project-specific renderer App facade contract.\n *\n * This matches @noego/wood/client getApp() and injected App instances:\n * controller name -> controller action.\n */\nexport interface GeneratedApp {\n${rpcTypeCode}\n}\n\n/** Backward-compatible name for the generated client App facade contract. */\nexport interface WoodRpcApi extends GeneratedApp {}\n\n/**\n * Project-specific raw preload bridge contract.\n *\n * This matches the channel path exposed by preload.generated.ts:\n * operation channel segments -> invoke function.\n */\nexport interface GeneratedWoodBridge {\n${typesCode}\n}\n\nexport interface WoodApi extends GeneratedWoodBridge {\n __rpcManifest: WoodRpcManifestEntry[];\n __load(route: string, params: Record<string, string>): Promise<unknown>;\n __navigate(windowId: string, route: string): Promise<void>;\n __window: {\n current(): Promise<{ ok: boolean; windowId?: string; defaultRoute?: string }>;\n open(windowId: string, options?: Record<string, unknown>): Promise<void>;\n close(windowId?: string): Promise<void>;\n focus(windowId: string): Promise<void>;\n minimize(windowId?: string): Promise<void>;\n maximize(windowId?: string): Promise<void>;\n };\n __debug: {\n current(): Promise<{\n ok: boolean;\n enabled: boolean;\n mode: 'development' | 'production';\n port?: number;\n windows: Array<{\n windowId: string;\n title: string;\n webContentsId: number;\n url: string;\n focused: boolean;\n rendererHealth?: 'ready' | 'loading' | 'unresponsive' | 'gone' | 'destroyed';\n }>;\n }>;\n };\n __contextMenu: {\n show(data: {\n items: Array<{ label?: string; action?: string; data?: string; _callbackId?: string; disabled?: boolean; type?: 'separator' }>;\n position: { x: number; y: number };\n }): Promise<void>;\n };\n on(channel: string, callback: (...args: unknown[]) => void): () => void;\n __log(level: string, logger: string, message: string, context?: unknown): Promise<{\n ok: boolean;\n forwarded: boolean;\n configured: boolean;\n reason?: 'unconfigured' | 'callback-error';\n errorMessage?: string;\n }>;\n}\n`;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/codegen/type_generator.ts"],"sourcesContent":["import type { OperationDef } from '../types/index.js';\nimport { generatedFileNotice } from './generated_file_notice.js';\n\nconst TYPE_SOURCE_INSTRUCTIONS = [\n 'To change IPC channels, input schemas, controller/action names, or renderer bridge types,',\n 'edit the operations YAML configured by wood.config.yml main.openapi and the matching controller methods.',\n] as const;\n\nfunction formatPropertyKey(key: string): string {\n if (/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key)) {\n return key;\n }\n\n return JSON.stringify(key);\n}\n\nfunction operationHasInput(op: OperationDef): boolean {\n return Boolean(\n op.inputSchema &&\n (op.inputSchema as Record<string, unknown>).type === 'object' &&\n Object.keys((op.inputSchema as Record<string, Record<string, unknown>>).properties ?? {}).length > 0,\n );\n}\n\nfunction jsonSchemaToTS(schema: Record<string, unknown> | undefined, indent: string = ''): string {\n if (!schema) return 'unknown';\n\n const type = schema.type as string | undefined;\n\n if (type === 'string') {\n if (schema.enum) {\n return (schema.enum as string[]).map((v) => `'${v}'`).join(' | ');\n }\n return 'string';\n }\n if (type === 'number' || type === 'integer') return 'number';\n if (type === 'boolean') return 'boolean';\n if (type === 'array') {\n const itemType = jsonSchemaToTS(schema.items as Record<string, unknown>, indent);\n return `Array<${itemType}>`;\n }\n if (type === 'object') {\n const props = (schema.properties ?? {}) as Record<string, Record<string, unknown>>;\n const required = new Set((schema.required as string[]) ?? []);\n const entries = Object.entries(props);\n if (entries.length === 0) return 'Record<string, unknown>';\n\n const lines = entries.map(([key, val]) => {\n const optional = required.has(key) ? '' : '?';\n const valType = jsonSchemaToTS(val, indent + ' ');\n return `${indent} ${formatPropertyKey(key)}${optional}: ${valType};`;\n });\n return `{\\n${lines.join('\\n')}\\n${indent}}`;\n }\n\n return 'unknown';\n}\n\nfunction buildNestedTypeTree(operations: Map<string, OperationDef>): Record<string, unknown> {\n const tree: Record<string, unknown> = {};\n for (const [channel, op] of operations) {\n const parts = channel.split('.');\n let current: Record<string, unknown> = tree;\n for (let i = 0; i < parts.length - 1; i++) {\n if (!current[parts[i]]) current[parts[i]] = {};\n current = current[parts[i]] as Record<string, unknown>;\n }\n current[parts[parts.length - 1]] = { __operation: op };\n }\n return tree;\n}\n\nfunction generateTypeTree(node: Record<string, unknown>, indent: string = ' '): string {\n const lines: string[] = [];\n for (const [key, value] of Object.entries(node)) {\n const entry = value as Record<string, unknown>;\n if (entry.__operation) {\n const op = entry.__operation as OperationDef;\n const inputType = jsonSchemaToTS(op.inputSchema as Record<string, unknown>, indent + ' ');\n const outputType = jsonSchemaToTS(op.outputSchema as Record<string, unknown>, indent + ' ');\n const hasInput = operationHasInput(op);\n\n if (hasInput) {\n lines.push(`${indent}${formatPropertyKey(key)}(data: ${inputType}): Promise<${outputType}>;`);\n } else {\n lines.push(`${indent}${formatPropertyKey(key)}(): Promise<${outputType}>;`);\n }\n } else {\n lines.push(`${indent}${formatPropertyKey(key)}: {`);\n lines.push(generateTypeTree(entry, indent + ' '));\n lines.push(`${indent}};`);\n }\n }\n return lines.join('\\n');\n}\n\ntype RpcActionTypeEntry = {\n channel: string;\n inputType: string;\n outputType: string;\n hasInput: boolean;\n};\n\nfunction buildRpcControllerTree(\n operations: Map<string, OperationDef>,\n): Record<string, Record<string, RpcActionTypeEntry>> {\n const tree: Record<string, Record<string, RpcActionTypeEntry>> = {};\n\n for (const operation of operations.values()) {\n const controller = operation.controller;\n const action = operation.action;\n\n if (!tree[controller]) {\n tree[controller] = {};\n }\n\n if (tree[controller][action]) {\n throw new Error(\n `Type codegen failed: duplicate RPC action \"${controller}.${action}\" found in channel \"${operation.channel}\".`,\n );\n }\n\n tree[controller][action] = {\n channel: operation.channel,\n inputType: jsonSchemaToTS(operation.inputSchema as Record<string, unknown>, ' '),\n outputType: jsonSchemaToTS(operation.outputSchema as Record<string, unknown>, ' '),\n hasInput: operationHasInput(operation),\n };\n }\n\n return tree;\n}\n\nfunction generateRpcTypeTree(operations: Map<string, OperationDef>): string {\n const controllerTree = buildRpcControllerTree(operations);\n const controllerNames = Object.keys(controllerTree).sort((a, b) => a.localeCompare(b));\n const lines: string[] = [];\n\n for (const controllerName of controllerNames) {\n lines.push(` ${formatPropertyKey(controllerName)}: {`);\n const actions = controllerTree[controllerName];\n const actionNames = Object.keys(actions).sort((a, b) => a.localeCompare(b));\n for (const actionName of actionNames) {\n const action = actions[actionName];\n if (action.hasInput) {\n lines.push(` ${formatPropertyKey(actionName)}(data: ${action.inputType}): Promise<${action.outputType}>;`);\n } else {\n lines.push(` ${formatPropertyKey(actionName)}(): Promise<${action.outputType}>;`);\n }\n }\n lines.push(' };');\n }\n\n return lines.join('\\n');\n}\n\nexport function generateTypes(operations: Map<string, OperationDef>): string {\n const tree = buildNestedTypeTree(operations);\n const typesCode = generateTypeTree(tree);\n const rpcTypeCode = generateRpcTypeTree(operations);\n\n return `${generatedFileNotice(TYPE_SOURCE_INSTRUCTIONS)}\nexport interface WoodRpcManifestEntry {\n channel: string;\n controller: string;\n action: string;\n path: string[];\n hasInput: boolean;\n}\n\n/**\n * Project-specific renderer App facade contract.\n *\n * This matches @noego/wood/client getApp() and injected App instances:\n * controller name -> controller action.\n */\nexport interface GeneratedApp {\n${rpcTypeCode}\n}\n\n/** Backward-compatible name for the generated client App facade contract. */\nexport interface WoodRpcApi extends GeneratedApp {}\n\n/**\n * Project-specific raw preload bridge contract.\n *\n * This matches the channel path exposed by preload.generated.ts:\n * operation channel segments -> invoke function.\n */\nexport interface GeneratedWoodBridge {\n${typesCode}\n}\n\nexport interface WoodApi extends GeneratedWoodBridge {\n __rpcManifest: WoodRpcManifestEntry[];\n __load(route: string, params: Record<string, string>): Promise<unknown>;\n __navigate(windowId: string, route: string): Promise<void>;\n __window: {\n current(): Promise<{ ok: boolean; windowId?: string; defaultRoute?: string }>;\n open(windowId: string, options?: Record<string, unknown>): Promise<void>;\n close(windowId?: string): Promise<void>;\n focus(windowId: string): Promise<void>;\n minimize(windowId?: string): Promise<void>;\n maximize(windowId?: string): Promise<void>;\n };\n __debug: {\n current(): Promise<{\n ok: boolean;\n enabled: boolean;\n mode: 'development' | 'production';\n port?: number;\n windows: Array<{\n windowId: string;\n title: string;\n webContentsId: number;\n url: string;\n focused: boolean;\n rendererHealth?: 'ready' | 'loading' | 'unresponsive' | 'gone' | 'destroyed';\n }>;\n }>;\n };\n __contextMenu: {\n show(data: {\n items: Array<{ label?: string; action?: string; data?: string; _callbackId?: string; disabled?: boolean; type?: 'separator' }>;\n position: { x: number; y: number };\n }): Promise<void>;\n };\n on(channel: string, callback: (...args: unknown[]) => void): () => void;\n __log(level: string, logger: string, message: string, context?: unknown): Promise<{\n ok: boolean;\n forwarded: boolean;\n configured: boolean;\n reason?: 'unconfigured' | 'callback-error';\n errorMessage?: string;\n }>;\n}\n`;\n}\n"],"mappings":"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","names":[]}
package/dist/index.cjs CHANGED
@@ -31,6 +31,7 @@ __export(index_exports, {
31
31
  RendererTracer: () => import_tracing.RendererTracer,
32
32
  SchemaValidator: () => import_validation.SchemaValidator,
33
33
  TestTracer: () => import_tracing.TestTracer,
34
+ TraceCommitWriter: () => import_tracing.TraceCommitWriter,
34
35
  TraceProvider: () => import_tracing.TraceProvider,
35
36
  TraceProviderConfiguration: () => import_tracing.TraceProviderConfiguration,
36
37
  WOOD_DEV_DIRECTORY: () => import_dev_metadata.WOOD_DEV_DIRECTORY,
@@ -44,21 +45,24 @@ __export(index_exports, {
44
45
  buildMiddlewareContext: () => import_middleware.buildMiddlewareContext,
45
46
  clearApplicationRootForTests: () => import_runtime.clearApplicationRootForTests,
46
47
  clearContainerRegistryForTests: () => import_runtime.clearContainerRegistryForTests,
48
+ clearRendererTraceBatchReceiverForTests: () => import_runtime.clearRendererTraceBatchReceiverForTests,
47
49
  clearTraceHubForTests: () => import_tracing.clearTraceHubForTests,
48
50
  disposeControllerLifecycle: () => import_controller.disposeControllerLifecycle,
49
51
  executeMiddleware: () => import_middleware.executeMiddleware,
50
- generateControllerRegistration: () => import_codegen4.generateControllerRegistration,
52
+ generateChannelMap: () => import_codegen3.generateChannelMap,
53
+ generateControllerRegistration: () => import_codegen5.generateControllerRegistration,
51
54
  generatePreload: () => import_codegen.generatePreload,
52
- generateRendererApp: () => import_codegen8.generateRendererApp,
53
- generateRendererControllerRegistration: () => import_codegen7.generateRendererControllerRegistration,
54
- generateRendererViewManifest: () => import_codegen6.generateRendererViewManifest,
55
- generateRuntime: () => import_codegen5.generateRuntime,
56
- generateTestMock: () => import_codegen3.generateTestMock,
55
+ generateRendererApp: () => import_codegen9.generateRendererApp,
56
+ generateRendererControllerRegistration: () => import_codegen8.generateRendererControllerRegistration,
57
+ generateRendererViewManifest: () => import_codegen7.generateRendererViewManifest,
58
+ generateRuntime: () => import_codegen6.generateRuntime,
59
+ generateTestMock: () => import_codegen4.generateTestMock,
57
60
  generateTypes: () => import_codegen2.generateTypes,
58
61
  getApplicationRoot: () => import_runtime.getApplicationRoot,
59
62
  getContainer: () => import_runtime.getContainer,
60
63
  getIpc: () => import_ipc.getIpc,
61
64
  getNavigation: () => import_navigation.getNavigation,
65
+ getRendererTraceBatchReceiver: () => import_runtime.getRendererTraceBatchReceiver,
62
66
  getTraceEvents$: () => import_tracing.getTraceEvents$,
63
67
  go: () => import_navigation.go,
64
68
  goback: () => import_navigation.goback,
@@ -70,12 +74,14 @@ __export(index_exports, {
70
74
  parseViewsFile: () => import_parser2.parseViewsFile,
71
75
  pushEvent: () => import_bridge.pushEvent,
72
76
  readWoodDevMetadata: () => import_dev_metadata.readWoodDevMetadata,
77
+ registerTraceSink: () => import_tracing.registerTraceSink,
73
78
  removeWoodDevMetadata: () => import_dev_metadata.removeWoodDevMetadata,
74
79
  resolveWoodDevDirectory: () => import_dev_metadata.resolveWoodDevDirectory,
75
80
  resolveWoodDevMetadataPath: () => import_dev_metadata.resolveWoodDevMetadataPath,
76
81
  resolveWoodRemoteDebuggingPort: () => import_dev_metadata.resolveWoodRemoteDebuggingPort,
77
82
  runtime: () => import_runtime.runtime,
78
83
  setApplicationRoot: () => import_runtime.setApplicationRoot,
84
+ setRendererTraceBatchReceiver: () => import_runtime.setRendererTraceBatchReceiver,
79
85
  setRendererTraceEnabled: () => import_tracing.setRendererTraceEnabled,
80
86
  setRendererTraceTransport: () => import_tracing.setRendererTraceTransport,
81
87
  startBackendLoop: () => import_bridge.startBackendLoop,
@@ -98,6 +104,7 @@ var import_codegen5 = require("./codegen/index.cjs");
98
104
  var import_codegen6 = require("./codegen/index.cjs");
99
105
  var import_codegen7 = require("./codegen/index.cjs");
100
106
  var import_codegen8 = require("./codegen/index.cjs");
107
+ var import_codegen9 = require("./codegen/index.cjs");
101
108
  var import_window = require("./window/index.cjs");
102
109
  var import_loader = require("./loader/index.cjs");
103
110
  var import_bridge = require("./bridge/index.cjs");
@@ -121,6 +128,7 @@ var import_tracing = require("./tracing/index.js");
121
128
  RendererTracer,
122
129
  SchemaValidator,
123
130
  TestTracer,
131
+ TraceCommitWriter,
124
132
  TraceProvider,
125
133
  TraceProviderConfiguration,
126
134
  WOOD_DEV_DIRECTORY,
@@ -134,9 +142,11 @@ var import_tracing = require("./tracing/index.js");
134
142
  buildMiddlewareContext,
135
143
  clearApplicationRootForTests,
136
144
  clearContainerRegistryForTests,
145
+ clearRendererTraceBatchReceiverForTests,
137
146
  clearTraceHubForTests,
138
147
  disposeControllerLifecycle,
139
148
  executeMiddleware,
149
+ generateChannelMap,
140
150
  generateControllerRegistration,
141
151
  generatePreload,
142
152
  generateRendererApp,
@@ -149,6 +159,7 @@ var import_tracing = require("./tracing/index.js");
149
159
  getContainer,
150
160
  getIpc,
151
161
  getNavigation,
162
+ getRendererTraceBatchReceiver,
152
163
  getTraceEvents$,
153
164
  go,
154
165
  goback,
@@ -160,12 +171,14 @@ var import_tracing = require("./tracing/index.js");
160
171
  parseViewsFile,
161
172
  pushEvent,
162
173
  readWoodDevMetadata,
174
+ registerTraceSink,
163
175
  removeWoodDevMetadata,
164
176
  resolveWoodDevDirectory,
165
177
  resolveWoodDevMetadataPath,
166
178
  resolveWoodRemoteDebuggingPort,
167
179
  runtime,
168
180
  setApplicationRoot,
181
+ setRendererTraceBatchReceiver,
169
182
  setRendererTraceEnabled,
170
183
  setRendererTraceTransport,
171
184
  startBackendLoop,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// @noego/wood — Declarative Electron desktop apps using the noego ecosystem\n\n// Types\nexport type {\n WoodConfig,\n WindowDef,\n DevConfig,\n ElectronBuilderConfig,\n OperationDef,\n RawOperationsDocument,\n RawModuleDef,\n RawOperationEntry,\n RawModuleOperationEntry,\n ViewDef,\n RawViewsDocument,\n RawViewEntry,\n ParameterDef,\n IpcContext,\n WoodMiddlewareContext,\n WoodMiddlewareFn,\n RequestData,\n ControllerArgs,\n LoaderResult,\n BridgeMessage,\n BridgeRequest,\n BridgeResponse,\n BridgeReady,\n BridgePush,\n BridgeElectronApi,\n SerializedError,\n ContextMenuContext,\n ContextMenuItem,\n ContextMenuEvent,\n} from './types';\n\n// Errors\nexport { WoodAuthError, WoodValidationError, BackendRestartingError } from './types/index.cjs';\n\n// Config\nexport { parseConfig } from './config/index.cjs';\n\n// Parsers\nexport { parseOperations, parseOperationsFile } from './parser/index.cjs';\nexport { parseViews, parseViewsFile } from './parser/index.cjs';\n\n// Router\nexport { WoodRouter } from './router/index.cjs';\n\n// Validation\nexport { SchemaValidator } from './validation/index.cjs';\n\n// Middleware\nexport { MiddlewareResolver, buildMiddlewareContext, executeMiddleware } from './middleware/index.cjs';\n\n// Controller\nexport { ControllerResolver, buildControllerArgs, disposeControllerLifecycle } from './controller/index.cjs';\nexport type { ControllerLifecycle } from './controller/index.cjs';\n\n// Codegen\nexport { generatePreload } from './codegen/index.cjs';\nexport { generateTypes } from './codegen/index.cjs';\nexport { generateTestMock } from './codegen/index.cjs';\nexport { generateControllerRegistration } from './codegen/index.cjs';\nexport type { ControllerRegistrationOptions } from './codegen/index.cjs';\nexport { generateRuntime } from './codegen/index.cjs';\nexport type { RuntimeGeneratorOptions } from './codegen/index.cjs';\nexport { generateRendererViewManifest } from './codegen/index.cjs';\nexport type { RendererViewManifestGeneratorOptions } from './codegen/index.cjs';\nexport { generateRendererControllerRegistration } from './codegen/index.cjs';\nexport type { RendererControllerRegistrationOptions } from './codegen/index.cjs';\nexport { generateRendererApp } from './codegen/index.cjs';\nexport type { RendererAppGeneratorOptions } from './codegen/index.cjs';\n\n// Window\nexport { WindowManager, WindowStateStore } from './window/index.cjs';\nexport type { ScreenLike, WindowBounds } from './window/index.cjs';\n\n// Loader\nexport { LoaderRunner } from './loader/index.cjs';\n\n// Bridge\nexport { BackendBridge, startBackendLoop, pushEvent } from './bridge/index.cjs';\n\n// Dev metadata (lightweight; safe at runtime)\n// Heavy dev tooling (WoodDevServer, BackendWatcher, YamlWatcher,\n// EsbuildBackend) is available via the '@noego/wood/dev' subpath only,\n// so production consumers never load esbuild/chokidar.\nexport {\n DEFAULT_WOOD_REMOTE_DEBUGGING_PORT,\n WOOD_DEV_DIRECTORY,\n WOOD_DEV_METADATA_BASENAME,\n resolveWoodRemoteDebuggingPort,\n resolveWoodDevDirectory,\n resolveWoodDevMetadataPath,\n writeWoodDevMetadata,\n readWoodDevMetadata,\n removeWoodDevMetadata,\n} from './dev/dev_metadata.js';\nexport type { WoodDevMetadata } from './dev/dev_metadata.js';\n\n// Runtime\nexport {\n getContainer,\n clearContainerRegistryForTests,\n getApplicationRoot,\n setApplicationRoot,\n clearApplicationRootForTests,\n runtime,\n} from './runtime/index.js';\nexport type {\n GetContainerOptions,\n RuntimeOptions,\n RuntimeResult,\n RegisterRuntimeRouter,\n} from './runtime';\n\n// Navigation\nexport { Navigation, getNavigation, go, goto, goback } from './navigation/index.cjs';\nexport type { NavigationEntry, NavigationOptions } from './navigation/index.cjs';\n\n// Isomorphic IPC API\nexport { Ipc, getIpc } from './ipc/index.cjs';\nexport type { IpcPushOptions } from './ipc/index.cjs';\n\n// Tracing\nexport {\n FrameworkTracer,\n MainTracer,\n RendererTracer,\n TestTracer,\n TraceProvider,\n TraceProviderConfiguration,\n clearTraceHubForTests,\n getTraceEvents$,\n setRendererTraceEnabled,\n setRendererTraceTransport,\n} from './tracing/index.js';\nexport type {\n TraceDispatchResult,\n TraceEvent,\n TraceInput,\n TraceLevel,\n TraceProcess,\n TraceProviderMode,\n TraceRuntimeContext,\n TraceRuntime,\n TraceWaitOptions,\n} from './tracing/index.js';\n\n// Testing — available via '@noego/wood/testing' subpath export.\n// Not re-exported here to avoid pulling vitest into production builds.\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoCA,mBAA2E;AAG3E,oBAA4B;AAG5B,oBAAqD;AACrD,IAAAA,iBAA2C;AAG3C,oBAA2B;AAG3B,wBAAgC;AAGhC,wBAA8E;AAG9E,wBAAoF;AAIpF,qBAAgC;AAChC,IAAAC,kBAA8B;AAC9B,IAAAA,kBAAiC;AACjC,IAAAA,kBAA+C;AAE/C,IAAAA,kBAAgC;AAEhC,IAAAA,kBAA6C;AAE7C,IAAAA,kBAAuD;AAEvD,IAAAA,kBAAoC;AAIpC,oBAAgD;AAIhD,oBAA6B;AAG7B,oBAA2D;AAM3D,0BAUO;AAIP,qBAOO;AASP,wBAA4D;AAI5D,iBAA4B;AAI5B,qBAWO;","names":["import_parser","import_codegen"]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// @noego/wood — Declarative Electron desktop apps using the noego ecosystem\n\n// Types\nexport type {\n WoodConfig,\n WindowDef,\n DevConfig,\n ElectronBuilderConfig,\n OperationDef,\n RawOperationsDocument,\n RawModuleDef,\n RawOperationEntry,\n RawModuleOperationEntry,\n ViewDef,\n RawViewsDocument,\n RawViewEntry,\n ParameterDef,\n IpcContext,\n WoodMiddlewareContext,\n WoodMiddlewareFn,\n RequestData,\n ControllerArgs,\n LoaderResult,\n BridgeMessage,\n BridgeRequest,\n BridgeResponse,\n BridgeReady,\n BridgePush,\n BridgeElectronApi,\n SerializedError,\n ContextMenuContext,\n ContextMenuItem,\n ContextMenuEvent,\n} from './types';\n\n// Errors\nexport { WoodAuthError, WoodValidationError, BackendRestartingError } from './types/index.cjs';\n\n// Config\nexport { parseConfig } from './config/index.cjs';\n\n// Parsers\nexport { parseOperations, parseOperationsFile } from './parser/index.cjs';\nexport { parseViews, parseViewsFile } from './parser/index.cjs';\n\n// Router\nexport { WoodRouter } from './router/index.cjs';\n\n// Validation\nexport { SchemaValidator } from './validation/index.cjs';\n\n// Middleware\nexport { MiddlewareResolver, buildMiddlewareContext, executeMiddleware } from './middleware/index.cjs';\n\n// Controller\nexport { ControllerResolver, buildControllerArgs, disposeControllerLifecycle } from './controller/index.cjs';\nexport type { ControllerLifecycle } from './controller/index.cjs';\n\n// Codegen\nexport { generatePreload } from './codegen/index.cjs';\nexport { generateTypes } from './codegen/index.cjs';\nexport { generateChannelMap } from './codegen/index.cjs';\nexport { generateTestMock } from './codegen/index.cjs';\nexport { generateControllerRegistration } from './codegen/index.cjs';\nexport type { ControllerRegistrationOptions } from './codegen/index.cjs';\nexport { generateRuntime } from './codegen/index.cjs';\nexport type { RuntimeGeneratorOptions } from './codegen/index.cjs';\nexport { generateRendererViewManifest } from './codegen/index.cjs';\nexport type { RendererViewManifestGeneratorOptions } from './codegen/index.cjs';\nexport { generateRendererControllerRegistration } from './codegen/index.cjs';\nexport type { RendererControllerRegistrationOptions } from './codegen/index.cjs';\nexport { generateRendererApp } from './codegen/index.cjs';\nexport type { RendererAppGeneratorOptions } from './codegen/index.cjs';\n\n// Window\nexport { WindowManager, WindowStateStore } from './window/index.cjs';\nexport type { ScreenLike, WindowBounds } from './window/index.cjs';\n\n// Loader\nexport { LoaderRunner } from './loader/index.cjs';\n\n// Bridge\nexport { BackendBridge, startBackendLoop, pushEvent } from './bridge/index.cjs';\n\n// Dev metadata (lightweight; safe at runtime)\n// Heavy dev tooling (WoodDevServer, BackendWatcher, YamlWatcher,\n// EsbuildBackend) is available via the '@noego/wood/dev' subpath only,\n// so production consumers never load esbuild/chokidar.\nexport {\n DEFAULT_WOOD_REMOTE_DEBUGGING_PORT,\n WOOD_DEV_DIRECTORY,\n WOOD_DEV_METADATA_BASENAME,\n resolveWoodRemoteDebuggingPort,\n resolveWoodDevDirectory,\n resolveWoodDevMetadataPath,\n writeWoodDevMetadata,\n readWoodDevMetadata,\n removeWoodDevMetadata,\n} from './dev/dev_metadata.js';\nexport type { WoodDevMetadata } from './dev/dev_metadata.js';\n\n// Runtime\nexport {\n getContainer,\n clearContainerRegistryForTests,\n getApplicationRoot,\n setApplicationRoot,\n clearApplicationRootForTests,\n clearRendererTraceBatchReceiverForTests,\n getRendererTraceBatchReceiver,\n runtime,\n setRendererTraceBatchReceiver,\n} from './runtime/index.js';\nexport type {\n GetContainerOptions,\n RuntimeOptions,\n RuntimeResult,\n RegisterRuntimeRouter,\n} from './runtime';\n\n// Navigation\nexport { Navigation, getNavigation, go, goto, goback } from './navigation/index.cjs';\nexport type { NavigationEntry, NavigationOptions } from './navigation/index.cjs';\n\n// Isomorphic IPC API\nexport { Ipc, getIpc } from './ipc/index.cjs';\nexport type { IpcPushOptions } from './ipc/index.cjs';\n\n// Tracing\nexport {\n FrameworkTracer,\n MainTracer,\n RendererTracer,\n TestTracer,\n TraceProvider,\n TraceProviderConfiguration,\n TraceCommitWriter,\n clearTraceHubForTests,\n getTraceEvents$,\n registerTraceSink,\n setRendererTraceEnabled,\n setRendererTraceTransport,\n} from './tracing/index.js';\nexport type {\n TraceCommitRow,\n TraceCommitWriterOptions,\n TraceFlushOptions,\n TraceFlushResult,\n WoodTracePersistencePort,\n TraceDispatchResult,\n TraceEvent,\n TraceInput,\n TraceLevel,\n TraceProcess,\n TraceProviderMode,\n TraceRuntimeContext,\n TraceRuntime,\n TraceWaitOptions,\n WoodRendererTraceEvent,\n WoodRendererTraceInput,\n WoodTraceBatch,\n WoodTraceBatchAcknowledgement,\n WoodTraceBatchReceiver,\n WoodTraceBatchRuntimeContext,\n WoodTraceEventSink,\n WoodTraceEventSnapshot,\n WoodTraceSinkDisposer,\n} from './tracing/index.js';\n\n// Testing — available via '@noego/wood/testing' subpath export.\n// Not re-exported here to avoid pulling vitest into production builds.\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoCA,mBAA2E;AAG3E,oBAA4B;AAG5B,oBAAqD;AACrD,IAAAA,iBAA2C;AAG3C,oBAA2B;AAG3B,wBAAgC;AAGhC,wBAA8E;AAG9E,wBAAoF;AAIpF,qBAAgC;AAChC,IAAAC,kBAA8B;AAC9B,IAAAA,kBAAmC;AACnC,IAAAA,kBAAiC;AACjC,IAAAA,kBAA+C;AAE/C,IAAAA,kBAAgC;AAEhC,IAAAA,kBAA6C;AAE7C,IAAAA,kBAAuD;AAEvD,IAAAA,kBAAoC;AAIpC,oBAAgD;AAIhD,oBAA6B;AAG7B,oBAA2D;AAM3D,0BAUO;AAIP,qBAUO;AASP,wBAA4D;AAI5D,iBAA4B;AAI5B,qBAaO;","names":["import_parser","import_codegen"]}