@typecad/cuttlefish 0.1.0-alpha.1

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 (377) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +79 -0
  3. package/dist/api/board-types.d.ts +1 -0
  4. package/dist/api/board-types.js +4 -0
  5. package/dist/api/capabilities.d.ts +12 -0
  6. package/dist/api/capabilities.js +1 -0
  7. package/dist/api/config.d.ts +120 -0
  8. package/dist/api/config.js +7 -0
  9. package/dist/api/index.d.ts +5 -0
  10. package/dist/api/index.js +2 -0
  11. package/dist/api/schema/builder.d.ts +14 -0
  12. package/dist/api/schema/builder.js +15 -0
  13. package/dist/api/schema/index.d.ts +2 -0
  14. package/dist/api/schema/index.js +1 -0
  15. package/dist/api/schema/types.d.ts +257 -0
  16. package/dist/api/schema/types.js +4 -0
  17. package/dist/api/shared/async-runtime-static.d.ts +8 -0
  18. package/dist/api/shared/async-runtime-static.js +201 -0
  19. package/dist/api/shared/async-types.d.ts +42 -0
  20. package/dist/api/shared/async-types.js +8 -0
  21. package/dist/api/shared/board-resolver.d.ts +12 -0
  22. package/dist/api/shared/board-resolver.js +7 -0
  23. package/dist/api/shared/cpp-type-ir.d.ts +229 -0
  24. package/dist/api/shared/cpp-type-ir.js +672 -0
  25. package/dist/api/shared/display-adapter.d.ts +12 -0
  26. package/dist/api/shared/display-adapter.js +145 -0
  27. package/dist/api/shared/display-adapters/eink-mono.d.ts +2 -0
  28. package/dist/api/shared/display-adapters/eink-mono.js +53 -0
  29. package/dist/api/shared/display-adapters/sdl.d.ts +2 -0
  30. package/dist/api/shared/display-adapters/sdl.js +452 -0
  31. package/dist/api/shared/display-adapters/ssd1309.d.ts +2 -0
  32. package/dist/api/shared/display-adapters/ssd1309.js +136 -0
  33. package/dist/api/shared/display-adapters/st7796.d.ts +2 -0
  34. package/dist/api/shared/display-adapters/st7796.js +132 -0
  35. package/dist/api/shared/display-capabilities.d.ts +45 -0
  36. package/dist/api/shared/display-capabilities.js +54 -0
  37. package/dist/api/shared/display-op-ir.d.ts +62 -0
  38. package/dist/api/shared/display-op-ir.js +19 -0
  39. package/dist/api/shared/display-profile.d.ts +265 -0
  40. package/dist/api/shared/display-profile.js +338 -0
  41. package/dist/api/shared/graphics-strategy.d.ts +29 -0
  42. package/dist/api/shared/graphics-strategy.js +11 -0
  43. package/dist/api/shared/hal-op-ir.d.ts +393 -0
  44. package/dist/api/shared/hal-op-ir.js +18 -0
  45. package/dist/api/shared/index.d.ts +26 -0
  46. package/dist/api/shared/index.js +21 -0
  47. package/dist/api/shared/ir-core.d.ts +363 -0
  48. package/dist/api/shared/ir-core.js +8 -0
  49. package/dist/api/shared/ir-declarations.d.ts +201 -0
  50. package/dist/api/shared/ir-declarations.js +26 -0
  51. package/dist/api/shared/ir.d.ts +85 -0
  52. package/dist/api/shared/ir.js +13 -0
  53. package/dist/api/shared/platform-strategy.d.ts +402 -0
  54. package/dist/api/shared/platform-strategy.js +14 -0
  55. package/dist/api/shared/polyfill-helper-registry.d.ts +11 -0
  56. package/dist/api/shared/polyfill-helper-registry.js +86 -0
  57. package/dist/api/shared/polyfill-types.d.ts +33 -0
  58. package/dist/api/shared/polyfill-types.js +76 -0
  59. package/dist/api/shared/promise-runtime.d.ts +10 -0
  60. package/dist/api/shared/promise-runtime.js +244 -0
  61. package/dist/api/shared/snprintf-types.d.ts +29 -0
  62. package/dist/api/shared/snprintf-types.js +8 -0
  63. package/dist/api/shared/string-method-registry.d.ts +53 -0
  64. package/dist/api/shared/string-method-registry.js +168 -0
  65. package/dist/api/shared/toolchain-types.d.ts +63 -0
  66. package/dist/api/shared/toolchain-types.js +71 -0
  67. package/dist/api/shared/types.d.ts +50 -0
  68. package/dist/api/shared/types.js +6 -0
  69. package/dist/ast/parse.d.ts +2 -0
  70. package/dist/ast/parse.js +4 -0
  71. package/dist/cache.d.ts +26 -0
  72. package/dist/cache.js +95 -0
  73. package/dist/cli-utils.d.ts +37 -0
  74. package/dist/cli-utils.js +250 -0
  75. package/dist/cli.d.ts +2 -0
  76. package/dist/cli.js +635 -0
  77. package/dist/config-loader.d.ts +78 -0
  78. package/dist/config-loader.js +508 -0
  79. package/dist/config-schema.d.ts +233 -0
  80. package/dist/config-schema.js +83 -0
  81. package/dist/create/board-checklist.d.ts +2 -0
  82. package/dist/create/board-checklist.js +52 -0
  83. package/dist/create/board-codegen.d.ts +9 -0
  84. package/dist/create/board-codegen.js +238 -0
  85. package/dist/create/board-generators.d.ts +12 -0
  86. package/dist/create/board-generators.js +652 -0
  87. package/dist/create/board-spec.d.ts +640 -0
  88. package/dist/create/board-spec.js +215 -0
  89. package/dist/create/eslint-rules-template.d.ts +2 -0
  90. package/dist/create/eslint-rules-template.js +672 -0
  91. package/dist/create/index.d.ts +11 -0
  92. package/dist/create/index.js +8 -0
  93. package/dist/create/init-scaffold.d.ts +27 -0
  94. package/dist/create/init-scaffold.js +150 -0
  95. package/dist/create/init-templates.d.ts +24 -0
  96. package/dist/create/init-templates.js +379 -0
  97. package/dist/create/init-wizard.d.ts +8 -0
  98. package/dist/create/init-wizard.js +168 -0
  99. package/dist/debug/breakpoint-loader.d.ts +24 -0
  100. package/dist/debug/breakpoint-loader.js +137 -0
  101. package/dist/debug/index.d.ts +3 -0
  102. package/dist/debug/index.js +7 -0
  103. package/dist/debug/preprocessor.d.ts +9 -0
  104. package/dist/debug/preprocessor.js +214 -0
  105. package/dist/debug/types.d.ts +32 -0
  106. package/dist/debug/types.js +6 -0
  107. package/dist/diagnostics/diagnostics-report.d.ts +51 -0
  108. package/dist/diagnostics/diagnostics-report.js +333 -0
  109. package/dist/diagnostics/json-schema.d.ts +138 -0
  110. package/dist/diagnostics/json-schema.js +27 -0
  111. package/dist/diagnostics/md-writer.d.ts +10 -0
  112. package/dist/diagnostics/md-writer.js +336 -0
  113. package/dist/diagnostics/mermaid-builder.d.ts +65 -0
  114. package/dist/diagnostics/mermaid-builder.js +681 -0
  115. package/dist/emit/cpp-emitter.d.ts +6 -0
  116. package/dist/emit/cpp-emitter.js +48 -0
  117. package/dist/emit/emitters/class-emitter.d.ts +2 -0
  118. package/dist/emit/emitters/class-emitter.js +523 -0
  119. package/dist/emit/emitters/emitter-context.d.ts +174 -0
  120. package/dist/emit/emitters/emitter-context.js +1 -0
  121. package/dist/emit/emitters/entrypoint-synthesizer.d.ts +2 -0
  122. package/dist/emit/emitters/entrypoint-synthesizer.js +175 -0
  123. package/dist/emit/emitters/function-emitter-impl.d.ts +19 -0
  124. package/dist/emit/emitters/function-emitter-impl.js +428 -0
  125. package/dist/emit/emitters/line-appender.d.ts +15 -0
  126. package/dist/emit/emitters/line-appender.js +344 -0
  127. package/dist/emit/emitters/namespace-emitter.d.ts +2 -0
  128. package/dist/emit/emitters/namespace-emitter.js +324 -0
  129. package/dist/emit/emitters/output-finalizer.d.ts +4 -0
  130. package/dist/emit/emitters/output-finalizer.js +267 -0
  131. package/dist/emit/emitters/setup.d.ts +3 -0
  132. package/dist/emit/emitters/setup.js +851 -0
  133. package/dist/emit/emitters/top-level-prep.d.ts +2 -0
  134. package/dist/emit/emitters/top-level-prep.js +706 -0
  135. package/dist/emit/emitters/type-decl-emitter.d.ts +2 -0
  136. package/dist/emit/emitters/type-decl-emitter.js +251 -0
  137. package/dist/emit/emitters/ui-emitter.d.ts +21 -0
  138. package/dist/emit/emitters/ui-emitter.js +564 -0
  139. package/dist/emit/enum-emitter.d.ts +1 -0
  140. package/dist/emit/enum-emitter.js +1 -0
  141. package/dist/emit/expression-renderer.d.ts +283 -0
  142. package/dist/emit/expression-renderer.js +1477 -0
  143. package/dist/emit/native-helpers-emitter.d.ts +11 -0
  144. package/dist/emit/native-helpers-emitter.js +34 -0
  145. package/dist/emit/route-hal-op.d.ts +5 -0
  146. package/dist/emit/route-hal-op.js +13 -0
  147. package/dist/emit/snprintf-helpers.d.ts +17 -0
  148. package/dist/emit/snprintf-helpers.js +462 -0
  149. package/dist/emit/statement-renderer.d.ts +189 -0
  150. package/dist/emit/statement-renderer.js +948 -0
  151. package/dist/emit/utils/async-state-machine.d.ts +42 -0
  152. package/dist/emit/utils/async-state-machine.js +343 -0
  153. package/dist/emit/utils/comment-helpers.d.ts +20 -0
  154. package/dist/emit/utils/comment-helpers.js +31 -0
  155. package/dist/emit/utils/cpp-helpers.d.ts +47 -0
  156. package/dist/emit/utils/cpp-helpers.js +85 -0
  157. package/dist/emit/utils/include-resolver.d.ts +58 -0
  158. package/dist/emit/utils/include-resolver.js +155 -0
  159. package/dist/emit/utils/index.d.ts +8 -0
  160. package/dist/emit/utils/index.js +12 -0
  161. package/dist/emit/utils/type-inference.d.ts +159 -0
  162. package/dist/emit/utils/type-inference.js +559 -0
  163. package/dist/eslint-check.d.ts +10 -0
  164. package/dist/eslint-check.js +102 -0
  165. package/dist/framework-package.d.ts +10 -0
  166. package/dist/framework-package.js +58 -0
  167. package/dist/framework-registry.d.ts +39 -0
  168. package/dist/framework-registry.js +30 -0
  169. package/dist/incremental-cache.d.ts +116 -0
  170. package/dist/incremental-cache.js +335 -0
  171. package/dist/ir/adc-range-validation.d.ts +11 -0
  172. package/dist/ir/adc-range-validation.js +250 -0
  173. package/dist/ir/ast-node-utils.d.ts +8 -0
  174. package/dist/ir/ast-node-utils.js +32 -0
  175. package/dist/ir/board-pin-utils.d.ts +13 -0
  176. package/dist/ir/board-pin-utils.js +65 -0
  177. package/dist/ir/board-resolver.d.ts +36 -0
  178. package/dist/ir/board-resolver.js +437 -0
  179. package/dist/ir/build-ir-state.d.ts +167 -0
  180. package/dist/ir/build-ir-state.js +306 -0
  181. package/dist/ir/build-ir.d.ts +2 -0
  182. package/dist/ir/build-ir.js +808 -0
  183. package/dist/ir/call-graph.d.ts +35 -0
  184. package/dist/ir/call-graph.js +194 -0
  185. package/dist/ir/compile-time-only.d.ts +2 -0
  186. package/dist/ir/compile-time-only.js +16 -0
  187. package/dist/ir/declaration-builders.d.ts +9 -0
  188. package/dist/ir/declaration-builders.js +608 -0
  189. package/dist/ir/entry-points.d.ts +30 -0
  190. package/dist/ir/entry-points.js +191 -0
  191. package/dist/ir/expression-to-ir.d.ts +5 -0
  192. package/dist/ir/expression-to-ir.js +2249 -0
  193. package/dist/ir/extract-property-chain.d.ts +10 -0
  194. package/dist/ir/extract-property-chain.js +30 -0
  195. package/dist/ir/feature-prescan.d.ts +3 -0
  196. package/dist/ir/feature-prescan.js +43 -0
  197. package/dist/ir/feature-registry.d.ts +30 -0
  198. package/dist/ir/feature-registry.js +816 -0
  199. package/dist/ir/filter.d.ts +7 -0
  200. package/dist/ir/filter.js +85 -0
  201. package/dist/ir/function-builder.d.ts +19 -0
  202. package/dist/ir/function-builder.js +670 -0
  203. package/dist/ir/hal/hal-emitter.d.ts +62 -0
  204. package/dist/ir/hal/hal-emitter.js +735 -0
  205. package/dist/ir/hal/hal-parser.d.ts +61 -0
  206. package/dist/ir/hal/hal-parser.js +473 -0
  207. package/dist/ir/hal/hal-plugins.d.ts +34 -0
  208. package/dist/ir/hal/hal-plugins.js +706 -0
  209. package/dist/ir/hal-resolver.d.ts +5 -0
  210. package/dist/ir/hal-resolver.js +5 -0
  211. package/dist/ir/heap-analysis.d.ts +8 -0
  212. package/dist/ir/heap-analysis.js +350 -0
  213. package/dist/ir/heap-array-validation.d.ts +24 -0
  214. package/dist/ir/heap-array-validation.js +29 -0
  215. package/dist/ir/identifier-collector.d.ts +18 -0
  216. package/dist/ir/identifier-collector.js +439 -0
  217. package/dist/ir/interrupt-analysis.d.ts +39 -0
  218. package/dist/ir/interrupt-analysis.js +467 -0
  219. package/dist/ir/memory-budget-validation.d.ts +10 -0
  220. package/dist/ir/memory-budget-validation.js +86 -0
  221. package/dist/ir/namespace-builder.d.ts +7 -0
  222. package/dist/ir/namespace-builder.js +152 -0
  223. package/dist/ir/ownership-analysis.d.ts +9 -0
  224. package/dist/ir/ownership-analysis.js +1207 -0
  225. package/dist/ir/peripheral-ownership.d.ts +3 -0
  226. package/dist/ir/peripheral-ownership.js +152 -0
  227. package/dist/ir/peripheral-symbols.d.ts +7 -0
  228. package/dist/ir/peripheral-symbols.js +57 -0
  229. package/dist/ir/peripheral-usage.d.ts +54 -0
  230. package/dist/ir/peripheral-usage.js +691 -0
  231. package/dist/ir/peripheral-validation.d.ts +8 -0
  232. package/dist/ir/peripheral-validation.js +77 -0
  233. package/dist/ir/pin-alias-conflict.d.ts +4 -0
  234. package/dist/ir/pin-alias-conflict.js +34 -0
  235. package/dist/ir/pin-capability-validation.d.ts +6 -0
  236. package/dist/ir/pin-capability-validation.js +413 -0
  237. package/dist/ir/pin-mode-validation.d.ts +10 -0
  238. package/dist/ir/pin-mode-validation.js +301 -0
  239. package/dist/ir/pin-safety.d.ts +11 -0
  240. package/dist/ir/pin-safety.js +58 -0
  241. package/dist/ir/program-analysis.d.ts +44 -0
  242. package/dist/ir/program-analysis.js +589 -0
  243. package/dist/ir/pulldown-validation.d.ts +7 -0
  244. package/dist/ir/pulldown-validation.js +49 -0
  245. package/dist/ir/pwm-timer-sharing.d.ts +4 -0
  246. package/dist/ir/pwm-timer-sharing.js +93 -0
  247. package/dist/ir/reachability.d.ts +68 -0
  248. package/dist/ir/reachability.js +224 -0
  249. package/dist/ir/register-decorators.d.ts +6 -0
  250. package/dist/ir/register-decorators.js +49 -0
  251. package/dist/ir/render-expr.d.ts +4 -0
  252. package/dist/ir/render-expr.js +127 -0
  253. package/dist/ir/resource-analysis.d.ts +19 -0
  254. package/dist/ir/resource-analysis.js +153 -0
  255. package/dist/ir/statement-to-ir.d.ts +23 -0
  256. package/dist/ir/statement-to-ir.js +349 -0
  257. package/dist/ir/symbol-table.d.ts +68 -0
  258. package/dist/ir/symbol-table.js +179 -0
  259. package/dist/ir/symbol-types.d.ts +56 -0
  260. package/dist/ir/symbol-types.js +107 -0
  261. package/dist/ir/timer0-pwm-timing-conflict.d.ts +4 -0
  262. package/dist/ir/timer0-pwm-timing-conflict.js +71 -0
  263. package/dist/ir/timing-validation.d.ts +7 -0
  264. package/dist/ir/timing-validation.js +95 -0
  265. package/dist/ir/transformers/array-methods.d.ts +8 -0
  266. package/dist/ir/transformers/array-methods.js +493 -0
  267. package/dist/ir/transformers/call-statement.d.ts +5 -0
  268. package/dist/ir/transformers/call-statement.js +758 -0
  269. package/dist/ir/transformers/callback-context-registry.d.ts +20 -0
  270. package/dist/ir/transformers/callback-context-registry.js +55 -0
  271. package/dist/ir/transformers/canvas-lowering.d.ts +42 -0
  272. package/dist/ir/transformers/canvas-lowering.js +249 -0
  273. package/dist/ir/transformers/control-flow.d.ts +8 -0
  274. package/dist/ir/transformers/control-flow.js +508 -0
  275. package/dist/ir/transformers/expressions.d.ts +7 -0
  276. package/dist/ir/transformers/expressions.js +406 -0
  277. package/dist/ir/transformers/hal-call-resolver.d.ts +29 -0
  278. package/dist/ir/transformers/hal-call-resolver.js +274 -0
  279. package/dist/ir/transformers/hal-emit-helpers.d.ts +14 -0
  280. package/dist/ir/transformers/hal-emit-helpers.js +63 -0
  281. package/dist/ir/transformers/namespace-methods.d.ts +20 -0
  282. package/dist/ir/transformers/namespace-methods.js +110 -0
  283. package/dist/ir/transformers/register-assignment.d.ts +5 -0
  284. package/dist/ir/transformers/register-assignment.js +56 -0
  285. package/dist/ir/transformers/ui-call-resolver.d.ts +149 -0
  286. package/dist/ir/transformers/ui-call-resolver.js +1136 -0
  287. package/dist/ir/transformers/ui-callback-lowering.d.ts +62 -0
  288. package/dist/ir/transformers/ui-callback-lowering.js +623 -0
  289. package/dist/ir/transformers/ui-mount.d.ts +20 -0
  290. package/dist/ir/transformers/ui-mount.js +35 -0
  291. package/dist/ir/transformers/ui-reactive.d.ts +68 -0
  292. package/dist/ir/transformers/ui-reactive.js +129 -0
  293. package/dist/ir/transformers/variables.d.ts +14 -0
  294. package/dist/ir/transformers/variables.js +1045 -0
  295. package/dist/ir/try-catch-validation.d.ts +26 -0
  296. package/dist/ir/try-catch-validation.js +128 -0
  297. package/dist/ir/type-resolution.d.ts +31 -0
  298. package/dist/ir/type-resolution.js +977 -0
  299. package/dist/ir/ui-element-auto-wire.d.ts +50 -0
  300. package/dist/ir/ui-element-auto-wire.js +218 -0
  301. package/dist/ir/unit-suspicion-validation.d.ts +12 -0
  302. package/dist/ir/unit-suspicion-validation.js +296 -0
  303. package/dist/ir/utils/walk-ir.d.ts +6 -0
  304. package/dist/ir/utils/walk-ir.js +162 -0
  305. package/dist/ir/validation-orchestrator.d.ts +4 -0
  306. package/dist/ir/validation-orchestrator.js +45 -0
  307. package/dist/libdef/base-class-resolver.d.ts +23 -0
  308. package/dist/libdef/base-class-resolver.js +50 -0
  309. package/dist/libdef/cpp-to-decl.d.ts +34 -0
  310. package/dist/libdef/cpp-to-decl.js +584 -0
  311. package/dist/libdef/header-parser.d.ts +53 -0
  312. package/dist/libdef/header-parser.js +269 -0
  313. package/dist/libdef/registry.d.ts +10 -0
  314. package/dist/libdef/registry.js +142 -0
  315. package/dist/mapping/peripheral-names.d.ts +23 -0
  316. package/dist/mapping/peripheral-names.js +63 -0
  317. package/dist/mapping/source-map.d.ts +46 -0
  318. package/dist/mapping/source-map.js +207 -0
  319. package/dist/orchestrator/dts-generator.d.ts +17 -0
  320. package/dist/orchestrator/dts-generator.js +83 -0
  321. package/dist/orchestrator/graph-builder.d.ts +18 -0
  322. package/dist/orchestrator/graph-builder.js +218 -0
  323. package/dist/orchestrator/semantic-facts-verifier.d.ts +38 -0
  324. package/dist/orchestrator/semantic-facts-verifier.js +121 -0
  325. package/dist/orchestrator/semantic-facts.d.ts +141 -0
  326. package/dist/orchestrator/semantic-facts.js +652 -0
  327. package/dist/orchestrator/type-checker.d.ts +39 -0
  328. package/dist/orchestrator/type-checker.js +760 -0
  329. package/dist/platform/async-runtime.d.ts +8 -0
  330. package/dist/platform/async-runtime.js +26 -0
  331. package/dist/platform/generic-strategy.d.ts +101 -0
  332. package/dist/platform/generic-strategy.js +289 -0
  333. package/dist/platform/index.d.ts +4 -0
  334. package/dist/platform/index.js +9 -0
  335. package/dist/platform/registry.d.ts +21 -0
  336. package/dist/platform/registry.js +42 -0
  337. package/dist/platform/toolchain.d.ts +4 -0
  338. package/dist/platform/toolchain.js +43 -0
  339. package/dist/preview/client.d.ts +1 -0
  340. package/dist/preview/client.js +137 -0
  341. package/dist/preview/server.d.ts +5 -0
  342. package/dist/preview/server.js +199 -0
  343. package/dist/profiler/index.d.ts +28 -0
  344. package/dist/profiler/index.js +28 -0
  345. package/dist/profiler/profiler.d.ts +95 -0
  346. package/dist/profiler/profiler.js +338 -0
  347. package/dist/profiler/types.d.ts +87 -0
  348. package/dist/profiler/types.js +12 -0
  349. package/dist/stores/display-profile-store.d.ts +16 -0
  350. package/dist/stores/display-profile-store.js +48 -0
  351. package/dist/stores/theme-store.d.ts +13 -0
  352. package/dist/stores/theme-store.js +30 -0
  353. package/dist/testing.d.ts +45 -0
  354. package/dist/testing.js +47 -0
  355. package/dist/transpile/resolution.d.ts +29 -0
  356. package/dist/transpile/resolution.js +282 -0
  357. package/dist/transpile.d.ts +3 -0
  358. package/dist/transpile.js +722 -0
  359. package/dist/types.d.ts +217 -0
  360. package/dist/types.js +1 -0
  361. package/dist/ui/ui-bridge.d.ts +4 -0
  362. package/dist/ui/ui-bridge.js +34 -0
  363. package/dist/ui-hook.d.ts +84 -0
  364. package/dist/ui-hook.js +45 -0
  365. package/dist/utils/cli.d.ts +3 -0
  366. package/dist/utils/cli.js +463 -0
  367. package/dist/utils/fs.d.ts +4 -0
  368. package/dist/utils/fs.js +23 -0
  369. package/dist/utils/logger.d.ts +2 -0
  370. package/dist/utils/logger.js +8 -0
  371. package/dist/utils/strings.d.ts +35 -0
  372. package/dist/utils/strings.js +142 -0
  373. package/dist/utils/ui.d.ts +66 -0
  374. package/dist/utils/ui.js +149 -0
  375. package/dist/watch.d.ts +35 -0
  376. package/dist/watch.js +111 -0
  377. package/package.json +127 -0
@@ -0,0 +1,137 @@
1
+ // PreviewUIRuntime is loaded dynamically (see the import in the snapshot
2
+ // handler). Typed as any to avoid a static dependency on @typecad/ui.
3
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
4
+ let runtime;
5
+ let imageData;
6
+ let pendingPointerMove;
7
+ let pendingPointerFrame = 0;
8
+ function byId(id) {
9
+ const el = document.getElementById(id);
10
+ if (!el)
11
+ throw new Error(`Missing preview element #${id}`);
12
+ return el;
13
+ }
14
+ function renderDiagnostics(snapshot, extra = []) {
15
+ const diagnostics = byId("diagnostics");
16
+ const messages = [
17
+ ...snapshot.diagnostics.map((d) => `${d.severity}: ${d.message}`),
18
+ ...extra,
19
+ ];
20
+ diagnostics.replaceChildren(...messages.map((message) => {
21
+ const div = document.createElement("div");
22
+ div.textContent = message;
23
+ return div;
24
+ }));
25
+ }
26
+ function canvasPoint(canvas, event, width, height) {
27
+ const rect = canvas.getBoundingClientRect();
28
+ return {
29
+ x: Math.floor(((event.clientX - rect.left) / rect.width) * width),
30
+ y: Math.floor(((event.clientY - rect.top) / rect.height) * height),
31
+ };
32
+ }
33
+ function renderPinControls(controls) {
34
+ const panel = byId("pins");
35
+ panel.replaceChildren();
36
+ if (controls.length === 0) {
37
+ const empty = document.createElement("div");
38
+ empty.className = "empty";
39
+ empty.textContent = "No GPIO controls";
40
+ panel.append(empty);
41
+ return;
42
+ }
43
+ for (const control of controls) {
44
+ const button = document.createElement("button");
45
+ button.type = "button";
46
+ button.textContent = control.label;
47
+ button.addEventListener("click", () => runtime?.triggerPin(control));
48
+ panel.append(button);
49
+ }
50
+ }
51
+ function flushPointerMove() {
52
+ pendingPointerFrame = 0;
53
+ if (!runtime || !pendingPointerMove)
54
+ return;
55
+ const point = pendingPointerMove;
56
+ pendingPointerMove = undefined;
57
+ runtime.pointerMove(point.x, point.y);
58
+ }
59
+ async function loadSnapshot() {
60
+ const res = await fetch("/snapshot.json", { cache: "no-store" });
61
+ if (!res.ok)
62
+ throw new Error(await res.text());
63
+ return await res.json();
64
+ }
65
+ async function start() {
66
+ const snapshot = await loadSnapshot();
67
+ runtime?.stop();
68
+ runtime = undefined;
69
+ const canvas = byId("display");
70
+ canvas.width = snapshot.program.width;
71
+ canvas.height = snapshot.program.height;
72
+ imageData = new ImageData(snapshot.program.width, snapshot.program.height);
73
+ const ctx = canvas.getContext("2d");
74
+ if (!ctx)
75
+ throw new Error("2D canvas context unavailable");
76
+ ctx.imageSmoothingEnabled = false;
77
+ // Set the canvas CSS aspect-ratio to match the display (e.g. 128:64 for
78
+ // OLED, 320:240 for TFT) so the browser scales it proportionally.
79
+ document.documentElement.style.setProperty("--display-aspect", `${snapshot.program.width} / ${snapshot.program.height}`);
80
+ const status = byId("status");
81
+ status.textContent = `${snapshot.profileName ?? snapshot.program.display?.driver ?? "display"} ${snapshot.program.width}x${snapshot.program.height} ${snapshot.program.colorFormat}`;
82
+ const extraDiagnostics = [];
83
+ // Routed through a variable (not a string literal) so tsc types this as
84
+ // `any` and never resolves @typecad/ui's declaration files — see the
85
+ // comment in ui/ui-bridge.ts for why a literal specifier here causes
86
+ // TS5055 on rebuilds where dist/ already exists.
87
+ const hostRuntimePath = "@typecad/ui/preview/host-ui-runtime";
88
+ const { PreviewUIRuntime } = await import(hostRuntimePath);
89
+ runtime = new PreviewUIRuntime(snapshot, {
90
+ onFrame: (rgba) => {
91
+ if (!imageData)
92
+ return;
93
+ imageData.data.set(rgba);
94
+ ctx.putImageData(imageData, 0, 0);
95
+ },
96
+ onDiagnostics: (message) => {
97
+ extraDiagnostics.push(message);
98
+ renderDiagnostics(snapshot, extraDiagnostics);
99
+ },
100
+ });
101
+ canvas.onpointerdown = (event) => {
102
+ if (!runtime)
103
+ return;
104
+ canvas.setPointerCapture(event.pointerId);
105
+ const p = canvasPoint(canvas, event, snapshot.program.width, snapshot.program.height);
106
+ runtime.pointerDown(p.x, p.y);
107
+ };
108
+ canvas.onpointermove = (event) => {
109
+ if (!runtime)
110
+ return;
111
+ pendingPointerMove = canvasPoint(canvas, event, snapshot.program.width, snapshot.program.height);
112
+ if (!pendingPointerFrame)
113
+ pendingPointerFrame = requestAnimationFrame(flushPointerMove);
114
+ };
115
+ const pointerUp = () => {
116
+ if (pendingPointerFrame) {
117
+ cancelAnimationFrame(pendingPointerFrame);
118
+ flushPointerMove();
119
+ }
120
+ runtime?.pointerUp();
121
+ };
122
+ canvas.onpointerup = pointerUp;
123
+ canvas.onpointercancel = pointerUp;
124
+ renderPinControls(snapshot.pinControls);
125
+ renderDiagnostics(snapshot);
126
+ runtime.start();
127
+ }
128
+ void start().catch((error) => {
129
+ byId("diagnostics").textContent = error instanceof Error ? error.message : String(error);
130
+ });
131
+ const events = new EventSource("/events");
132
+ events.addEventListener("reload", () => {
133
+ void start().catch((error) => {
134
+ byId("diagnostics").textContent = error instanceof Error ? error.message : String(error);
135
+ });
136
+ });
137
+ export {};
@@ -0,0 +1,5 @@
1
+ export interface PreviewServerOptions {
2
+ configPath?: string;
3
+ port?: number;
4
+ }
5
+ export declare function runPreviewServer(options?: PreviewServerOptions): Promise<void>;
@@ -0,0 +1,199 @@
1
+ import fs from "node:fs";
2
+ import http from "node:http";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import chalk from "chalk";
6
+ import { findConfigFile, parseConfigFile } from "../config-loader.js";
7
+ import { requireUIHook } from "../ui-hook.js";
8
+ const HTML = `<!doctype html>
9
+ <html lang="en">
10
+ <head>
11
+ <meta charset="utf-8">
12
+ <meta name="viewport" content="width=device-width, initial-scale=1">
13
+ <title>Cuttlefish Preview</title>
14
+ <style>
15
+ :root { color-scheme: dark; font-family: ui-sans-serif, system-ui, sans-serif; background: #111315; color: #e8ecef; }
16
+ body { margin: 0; height: 100vh; overflow: hidden; display: grid; grid-template-columns: minmax(360px, 1fr) 280px; }
17
+ main { display: grid; place-items: center; padding: 24px; background: #191d20; }
18
+ canvas { image-rendering: pixelated; width: min(92vw, 960px); max-height: calc(100vh - 48px); aspect-ratio: var(--display-aspect, 4 / 3); background: #000; box-shadow: 0 12px 36px rgba(0,0,0,.35); }
19
+ aside { border-left: 1px solid #2d3338; padding: 18px; display: flex; flex-direction: column; gap: 18px; min-height: 0; }
20
+ aside > section:first-child, aside > section:nth-child(2) { flex-shrink: 0; } /* Display + GPIO stay visible */
21
+ aside > section:last-child { min-height: 0; display: flex; flex-direction: column; }
22
+ #diagnostics { overflow-y: auto; min-height: 0; }
23
+ h1 { font-size: 15px; margin: 0 0 8px; font-weight: 650; }
24
+ #status, #diagnostics, .empty { color: #aab3ba; font-size: 12px; line-height: 1.4; }
25
+ #pins { display: grid; gap: 8px; }
26
+ button { appearance: none; border: 1px solid #44505a; background: #252b30; color: #f3f6f8; border-radius: 6px; padding: 9px 10px; text-align: left; font: inherit; cursor: pointer; }
27
+ button:hover { background: #303841; }
28
+ @media (max-width: 760px) {
29
+ body { height: auto; min-height: 100vh; overflow: auto; grid-template-rows: auto 1fr; grid-template-columns: 1fr; }
30
+ aside { border-left: 0; border-top: 1px solid #2d3338; }
31
+ canvas { width: min(94vw, 640px); }
32
+ }
33
+ </style>
34
+ </head>
35
+ <body>
36
+ <main><canvas id="display" width="320" height="240"></canvas></main>
37
+ <aside>
38
+ <section>
39
+ <h1>Display</h1>
40
+ <div id="status"></div>
41
+ </section>
42
+ <section>
43
+ <h1>GPIO</h1>
44
+ <div id="pins"></div>
45
+ </section>
46
+ <section>
47
+ <h1>Diagnostics</h1>
48
+ <div id="diagnostics"></div>
49
+ </section>
50
+ </aside>
51
+ <script type="module" src="/__cuttlefish/preview/client.js"></script>
52
+ </body>
53
+ </html>`;
54
+ function contentType(filePath) {
55
+ if (filePath.endsWith(".js"))
56
+ return "text/javascript; charset=utf-8";
57
+ if (filePath.endsWith(".json"))
58
+ return "application/json; charset=utf-8";
59
+ if (filePath.endsWith(".map"))
60
+ return "application/json; charset=utf-8";
61
+ return "text/plain; charset=utf-8";
62
+ }
63
+ function writeText(res, status, text, type = "text/plain; charset=utf-8") {
64
+ res.writeHead(status, { "content-type": type });
65
+ res.end(text);
66
+ }
67
+ function resolveConfigPath(configPath) {
68
+ if (configPath) {
69
+ const abs = path.resolve(process.cwd(), configPath);
70
+ if (!fs.existsSync(abs))
71
+ throw new Error(`Config file not found: ${abs}`);
72
+ return abs;
73
+ }
74
+ const found = findConfigFile(process.cwd());
75
+ if (!found)
76
+ throw new Error("No cuttlefish.config.ts found for preview.");
77
+ return found;
78
+ }
79
+ function watchPreviewFiles(projectRoot, configPath, notify) {
80
+ const watchers = [];
81
+ let timer;
82
+ const debounced = () => {
83
+ if (timer)
84
+ clearTimeout(timer);
85
+ timer = setTimeout(notify, 80);
86
+ };
87
+ const addWatch = (target, recursive = false) => {
88
+ if (!fs.existsSync(target))
89
+ return;
90
+ try {
91
+ watchers.push(fs.watch(target, { recursive }, (_event, filename) => {
92
+ const name = String(filename ?? "");
93
+ if (!name || /\.(ts|css|html)$/.test(name) || name === path.basename(configPath))
94
+ debounced();
95
+ }));
96
+ }
97
+ catch {
98
+ if (recursive)
99
+ addWatch(target, false);
100
+ }
101
+ };
102
+ addWatch(path.join(projectRoot, "src"), true);
103
+ addWatch(configPath);
104
+ return watchers;
105
+ }
106
+ async function listen(server, preferredPort) {
107
+ for (let port = preferredPort; port < preferredPort + 20; port++) {
108
+ const result = await new Promise((resolve, reject) => {
109
+ const onError = (error) => {
110
+ server.off("listening", onListening);
111
+ if (error.code === "EADDRINUSE")
112
+ resolve("busy");
113
+ else
114
+ reject(error);
115
+ };
116
+ const onListening = () => {
117
+ server.off("error", onError);
118
+ resolve("ok");
119
+ };
120
+ server.once("error", onError);
121
+ server.once("listening", onListening);
122
+ server.listen(port, "127.0.0.1");
123
+ });
124
+ if (result === "ok")
125
+ return port;
126
+ }
127
+ throw new Error(`No available preview port found starting at ${preferredPort}.`);
128
+ }
129
+ export async function runPreviewServer(options = {}) {
130
+ const configPath = resolveConfigPath(options.configPath);
131
+ const config = parseConfigFile(configPath);
132
+ if (!config)
133
+ throw new Error(`Could not parse ${configPath}`);
134
+ const projectRoot = path.dirname(configPath);
135
+ requireUIHook().generateProjectUITypeDeclarations(projectRoot);
136
+ const distRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
137
+ const clients = new Set();
138
+ const server = http.createServer(async (req, res) => {
139
+ const url = new URL(req.url ?? "/", "http://127.0.0.1");
140
+ try {
141
+ if (url.pathname === "/") {
142
+ writeText(res, 200, HTML, "text/html; charset=utf-8");
143
+ return;
144
+ }
145
+ if (url.pathname === "/snapshot.json") {
146
+ requireUIHook().generateProjectUITypeDeclarations(projectRoot);
147
+ // Routed through a variable (not a string literal) so tsc types this
148
+ // as `any` and never resolves @typecad/ui's declaration files — see
149
+ // the comment in ui/ui-bridge.ts for why a literal specifier here
150
+ // causes TS5055 on rebuilds where dist/ already exists.
151
+ const buildProgramPath = "@typecad/ui/preview/build-program";
152
+ const { buildPreviewSnapshot } = await import(buildProgramPath);
153
+ const snapshot = await buildPreviewSnapshot({ config, projectRoot });
154
+ writeText(res, 200, JSON.stringify(snapshot), "application/json; charset=utf-8");
155
+ return;
156
+ }
157
+ if (url.pathname === "/events") {
158
+ res.writeHead(200, {
159
+ "content-type": "text/event-stream",
160
+ "cache-control": "no-cache",
161
+ "connection": "keep-alive",
162
+ });
163
+ res.write("\n");
164
+ clients.add(res);
165
+ req.on("close", () => clients.delete(res));
166
+ return;
167
+ }
168
+ if (url.pathname.startsWith("/__cuttlefish/")) {
169
+ const rel = decodeURIComponent(url.pathname.slice("/__cuttlefish/".length));
170
+ const filePath = path.resolve(distRoot, rel);
171
+ if (!filePath.startsWith(distRoot) || !fs.existsSync(filePath) || !fs.statSync(filePath).isFile()) {
172
+ writeText(res, 404, "Not found");
173
+ return;
174
+ }
175
+ res.writeHead(200, { "content-type": contentType(filePath) });
176
+ fs.createReadStream(filePath).pipe(res);
177
+ return;
178
+ }
179
+ writeText(res, 404, "Not found");
180
+ }
181
+ catch (error) {
182
+ writeText(res, 500, error instanceof Error ? error.message : String(error));
183
+ }
184
+ });
185
+ const notify = () => {
186
+ for (const client of clients) {
187
+ client.write("event: reload\n");
188
+ client.write(`data: ${Date.now()}\n\n`);
189
+ }
190
+ };
191
+ const watchers = watchPreviewFiles(projectRoot, configPath, notify);
192
+ server.on("close", () => watchers.forEach((watcher) => watcher.close()));
193
+ const port = await listen(server, options.port ?? 5174);
194
+ console.log(chalk.cyan("Cuttlefish preview") + chalk.gray(` ${path.relative(process.cwd(), configPath)}`));
195
+ console.log(` http://127.0.0.1:${port}/`);
196
+ await new Promise((resolve) => {
197
+ server.on("close", resolve);
198
+ });
199
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Performance profiler for transpilation.
3
+ *
4
+ * @example
5
+ * ```typescript
6
+ * import { initProfiler, formatConsoleReport } from './profiler.js';
7
+ *
8
+ * const profiler = initProfiler({ enabled: true });
9
+ * profiler.startSession();
10
+ *
11
+ * // Time synchronous operations
12
+ * profiler.timeSync('phase:name', () => {
13
+ * // do work
14
+ * });
15
+ *
16
+ * // Time async operations
17
+ * await profiler.timeAsync('phase:async', async () => {
18
+ * // do async work
19
+ * });
20
+ *
21
+ * // Generate report
22
+ * const session = profiler.endSession();
23
+ * const report = profiler.generateReport(session);
24
+ * console.log(formatConsoleReport(report));
25
+ * ```
26
+ */
27
+ export { Profiler, getProfiler, initProfiler } from "./profiler.js";
28
+ export { TimingEntry, MemorySnapshot, PhaseStatistics, ProfilerSession, ProfilerOptions, ProfilerReport, DEFAULT_PROFILER_OPTIONS, } from "./types.js";
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Performance profiler for transpilation.
3
+ *
4
+ * @example
5
+ * ```typescript
6
+ * import { initProfiler, formatConsoleReport } from './profiler.js';
7
+ *
8
+ * const profiler = initProfiler({ enabled: true });
9
+ * profiler.startSession();
10
+ *
11
+ * // Time synchronous operations
12
+ * profiler.timeSync('phase:name', () => {
13
+ * // do work
14
+ * });
15
+ *
16
+ * // Time async operations
17
+ * await profiler.timeAsync('phase:async', async () => {
18
+ * // do async work
19
+ * });
20
+ *
21
+ * // Generate report
22
+ * const session = profiler.endSession();
23
+ * const report = profiler.generateReport(session);
24
+ * console.log(formatConsoleReport(report));
25
+ * ```
26
+ */
27
+ export { Profiler, getProfiler, initProfiler } from "./profiler.js";
28
+ export { DEFAULT_PROFILER_OPTIONS, } from "./types.js";
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Performance profiler for the transpilation pipeline.
3
+ *
4
+ * Usage:
5
+ * const profiler = initProfiler({ enabled: true });
6
+ * profiler.startSession();
7
+ * profiler.timeSync('phase:name', () => { ... });
8
+ * await profiler.timeAsync('phase:async', async () => { ... });
9
+ * const report = profiler.endSession();
10
+ */
11
+ import { ProfilerOptions, ProfilerSession, ProfilerReport } from "./types.js";
12
+ export declare class Profiler {
13
+ private enabled;
14
+ private trackMemory;
15
+ private threshold;
16
+ private timings;
17
+ private activeTimers;
18
+ private memorySnapshots;
19
+ private sessionStart;
20
+ private parentStack;
21
+ private timerCounter;
22
+ constructor(options?: Partial<ProfilerOptions>);
23
+ /**
24
+ * Check if profiling is enabled
25
+ */
26
+ isEnabled(): boolean;
27
+ /**
28
+ * Start a timing measurement
29
+ */
30
+ startTimer(name: string, metadata?: Record<string, unknown>): void;
31
+ /**
32
+ * End a timing measurement
33
+ */
34
+ endTimer(name: string): number;
35
+ /**
36
+ * Time a synchronous function
37
+ */
38
+ timeSync<T>(name: string, fn: () => T, metadata?: Record<string, unknown>): T;
39
+ /**
40
+ * Time an asynchronous function
41
+ */
42
+ timeAsync<T>(name: string, fn: () => Promise<T>, metadata?: Record<string, unknown>): Promise<T>;
43
+ /**
44
+ * Capture a memory snapshot
45
+ */
46
+ captureMemorySnapshot(name: string): void;
47
+ /**
48
+ * Start a profiling session
49
+ */
50
+ startSession(): void;
51
+ /**
52
+ * End a profiling session and return the session data
53
+ */
54
+ endSession(): ProfilerSession;
55
+ /**
56
+ * Compute aggregated statistics by phase
57
+ */
58
+ private computePhaseStatistics;
59
+ /**
60
+ * Extract the base phase name from a timer name
61
+ */
62
+ private extractBasePhase;
63
+ /**
64
+ * Generate a profiler report from a session
65
+ */
66
+ generateReport(session: ProfilerSession): ProfilerReport;
67
+ /**
68
+ * Identify phases that are bottlenecks (>10% of total time)
69
+ */
70
+ private identifyBottlenecks;
71
+ /**
72
+ * Generate optimization recommendations based on profiling data
73
+ */
74
+ private generateRecommendations;
75
+ /**
76
+ * Generate a human-readable summary
77
+ */
78
+ private generateSummary;
79
+ /**
80
+ * Get all timing durations as a flat record (for diagnostics integration).
81
+ */
82
+ getTimings(): Record<string, number>;
83
+ /**
84
+ * Clear all profiling data
85
+ */
86
+ clear(): void;
87
+ }
88
+ /**
89
+ * Get the global profiler instance (creates one if not exists)
90
+ */
91
+ export declare function getProfiler(): Profiler;
92
+ /**
93
+ * Initialize the global profiler with options
94
+ */
95
+ export declare function initProfiler(options?: Partial<ProfilerOptions>): Profiler;