@faicad/faijs 0.33.1 → 0.35.2

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 (392) hide show
  1. package/dist/api/api-namespace.d.ts +14 -14
  2. package/dist/api/api-namespace.d.ts.map +1 -1
  3. package/dist/api/api-namespace.js +40 -14
  4. package/dist/api/api-namespace.js.map +1 -1
  5. package/dist/api/appearance.d.ts +47 -6
  6. package/dist/api/appearance.d.ts.map +1 -1
  7. package/dist/api/appearance.js.map +1 -1
  8. package/dist/api/assembly/solve-tree.d.ts +1 -0
  9. package/dist/api/assembly/solve-tree.d.ts.map +1 -1
  10. package/dist/api/assembly/solve-tree.js +42 -17
  11. package/dist/api/assembly/solve-tree.js.map +1 -1
  12. package/dist/api/assembly/solve.d.ts +1 -0
  13. package/dist/api/assembly/solve.d.ts.map +1 -1
  14. package/dist/api/assembly/solve.js.map +1 -1
  15. package/dist/api/assembly/solvers/global-solver.d.ts.map +1 -1
  16. package/dist/api/assembly/solvers/global-solver.js +130 -23
  17. package/dist/api/assembly/solvers/global-solver.js.map +1 -1
  18. package/dist/api/assembly/solvers/pose-from-delta.d.ts +9 -0
  19. package/dist/api/assembly/solvers/pose-from-delta.d.ts.map +1 -1
  20. package/dist/api/assembly/solvers/pose-from-delta.js +23 -0
  21. package/dist/api/assembly/solvers/pose-from-delta.js.map +1 -1
  22. package/dist/api/assembly/solvers/types.d.ts +20 -2
  23. package/dist/api/assembly/solvers/types.d.ts.map +1 -1
  24. package/dist/api/assembly/solvers/types.js.map +1 -1
  25. package/dist/api/chamfer.d.ts +7 -4
  26. package/dist/api/chamfer.d.ts.map +1 -1
  27. package/dist/api/chamfer.js +57 -13
  28. package/dist/api/chamfer.js.map +1 -1
  29. package/dist/api/draft.d.ts +7 -4
  30. package/dist/api/draft.d.ts.map +1 -1
  31. package/dist/api/draft.js +11 -6
  32. package/dist/api/draft.js.map +1 -1
  33. package/dist/api/edge-ref.d.ts +4 -4
  34. package/dist/api/edge-ref.js +4 -4
  35. package/dist/api/edge-ref.js.map +1 -1
  36. package/dist/api/extrude.d.ts +10 -6
  37. package/dist/api/extrude.d.ts.map +1 -1
  38. package/dist/api/extrude.js +50 -25
  39. package/dist/api/extrude.js.map +1 -1
  40. package/dist/api/face-ref.d.ts +4 -4
  41. package/dist/api/face-ref.js +4 -4
  42. package/dist/api/face-ref.js.map +1 -1
  43. package/dist/api/feature-repair.d.ts +6 -3
  44. package/dist/api/feature-repair.d.ts.map +1 -1
  45. package/dist/api/feature-repair.js +12 -7
  46. package/dist/api/feature-repair.js.map +1 -1
  47. package/dist/api/fillet-variable.d.ts +6 -2
  48. package/dist/api/fillet-variable.d.ts.map +1 -1
  49. package/dist/api/fillet-variable.js +24 -6
  50. package/dist/api/fillet-variable.js.map +1 -1
  51. package/dist/api/fillet.d.ts +7 -4
  52. package/dist/api/fillet.d.ts.map +1 -1
  53. package/dist/api/fillet.js +45 -12
  54. package/dist/api/fillet.js.map +1 -1
  55. package/dist/api/helix.d.ts +13 -13
  56. package/dist/api/helix.d.ts.map +1 -1
  57. package/dist/api/helix.js +19 -24
  58. package/dist/api/helix.js.map +1 -1
  59. package/dist/api/import-brep.d.ts +10 -18
  60. package/dist/api/import-brep.d.ts.map +1 -1
  61. package/dist/api/import-brep.js +17 -25
  62. package/dist/api/import-brep.js.map +1 -1
  63. package/dist/api/import-step.d.ts +10 -15
  64. package/dist/api/import-step.d.ts.map +1 -1
  65. package/dist/api/import-step.js +24 -29
  66. package/dist/api/import-step.js.map +1 -1
  67. package/dist/api/index.js +2 -2
  68. package/dist/api/index.js.map +1 -1
  69. package/dist/api/internal/export-members.js.map +1 -1
  70. package/dist/api/loft-advanced.d.ts +4 -0
  71. package/dist/api/loft-advanced.d.ts.map +1 -1
  72. package/dist/api/loft-advanced.js +4 -0
  73. package/dist/api/loft-advanced.js.map +1 -1
  74. package/dist/api/loft.d.ts +5 -3
  75. package/dist/api/loft.d.ts.map +1 -1
  76. package/dist/api/loft.js +5 -3
  77. package/dist/api/loft.js.map +1 -1
  78. package/dist/api/meta.d.ts +42 -6
  79. package/dist/api/meta.d.ts.map +1 -1
  80. package/dist/api/meta.js.map +1 -1
  81. package/dist/api/punch-hole.d.ts +5 -2
  82. package/dist/api/punch-hole.d.ts.map +1 -1
  83. package/dist/api/punch-hole.js +4 -1
  84. package/dist/api/punch-hole.js.map +1 -1
  85. package/dist/api/replicate.d.ts +4 -5
  86. package/dist/api/replicate.d.ts.map +1 -1
  87. package/dist/api/replicate.js +4 -5
  88. package/dist/api/replicate.js.map +1 -1
  89. package/dist/api/selectors-to-refs.d.ts +83 -0
  90. package/dist/api/selectors-to-refs.d.ts.map +1 -0
  91. package/dist/api/selectors-to-refs.js +211 -0
  92. package/dist/api/selectors-to-refs.js.map +1 -0
  93. package/dist/api/shell.d.ts +17 -8
  94. package/dist/api/shell.d.ts.map +1 -1
  95. package/dist/api/shell.js +45 -15
  96. package/dist/api/shell.js.map +1 -1
  97. package/dist/api/sketch-on-face.d.ts +12 -6
  98. package/dist/api/sketch-on-face.d.ts.map +1 -1
  99. package/dist/api/sketch-on-face.js +31 -4
  100. package/dist/api/sketch-on-face.js.map +1 -1
  101. package/dist/api/sketch-on-plane.d.ts +3 -0
  102. package/dist/api/sketch-on-plane.d.ts.map +1 -1
  103. package/dist/api/sketch-on-plane.js +3 -0
  104. package/dist/api/sketch-on-plane.js.map +1 -1
  105. package/dist/api/sketch-on-surface.d.ts +4 -1
  106. package/dist/api/sketch-on-surface.d.ts.map +1 -1
  107. package/dist/api/sketch-on-surface.js +4 -1
  108. package/dist/api/sketch-on-surface.js.map +1 -1
  109. package/dist/api/view/view-projection.d.ts.map +1 -1
  110. package/dist/api/view/view-projection.js +9 -2
  111. package/dist/api/view/view-projection.js.map +1 -1
  112. package/dist/brep/brep-chain.js +2 -2
  113. package/dist/brep/brep-chain.js.map +1 -1
  114. package/dist/brep/brep-ops.d.ts +1 -1
  115. package/dist/brep/brep-ops.js +1 -1
  116. package/dist/brep/brep-ops.js.map +1 -1
  117. package/dist/brep/engine/adapters/brep-mock.d.ts.map +1 -1
  118. package/dist/brep/engine/adapters/brep-mock.js +45 -0
  119. package/dist/brep/engine/adapters/brep-mock.js.map +1 -1
  120. package/dist/brep/engine/primitives.d.ts +87 -3
  121. package/dist/brep/engine/primitives.d.ts.map +1 -1
  122. package/dist/brep/engine/primitives.js +1 -1
  123. package/dist/brep/engine/primitives.js.map +1 -1
  124. package/dist/brep/engine/registry.d.ts +33 -7
  125. package/dist/brep/engine/registry.d.ts.map +1 -1
  126. package/dist/brep/engine/registry.js +47 -16
  127. package/dist/brep/engine/registry.js.map +1 -1
  128. package/dist/brep/handle-bridge.d.ts +14 -15
  129. package/dist/brep/handle-bridge.d.ts.map +1 -1
  130. package/dist/brep/handle-bridge.js +35 -15
  131. package/dist/brep/handle-bridge.js.map +1 -1
  132. package/dist/brep/primitives-brep.js +2 -2
  133. package/dist/brep/primitives-brep.js.map +1 -1
  134. package/dist/brep/text/text-to-solid.d.ts +40 -3
  135. package/dist/brep/text/text-to-solid.d.ts.map +1 -1
  136. package/dist/brep/text/text-to-solid.js +104 -24
  137. package/dist/brep/text/text-to-solid.js.map +1 -1
  138. package/dist/brepkit-kernel/brepkitKernel.d.ts +2 -2
  139. package/dist/brepkit-kernel/brepkitKernel.d.ts.map +1 -1
  140. package/dist/brepkit-kernel/brepkitKernel.js +315 -36
  141. package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
  142. package/dist/brepkit-kernel/brepkitWasm.js +7 -7
  143. package/dist/brepkit-kernel/brepkitWasm.js.map +1 -1
  144. package/dist/brepkit-kernel/multi-version-test.d.ts +2 -2
  145. package/dist/brepkit-kernel/multi-version-test.d.ts.map +1 -1
  146. package/dist/brepkit-kernel/multi-version-test.js +6 -6
  147. package/dist/brepkit-kernel/multi-version-test.js.map +1 -1
  148. package/dist/browser.d.ts +2 -3
  149. package/dist/browser.d.ts.map +1 -1
  150. package/dist/browser.js +1 -2
  151. package/dist/browser.js.map +1 -1
  152. package/dist/cad-runtime/admit-compat-lib.d.ts +9 -1
  153. package/dist/cad-runtime/admit-compat-lib.d.ts.map +1 -1
  154. package/dist/cad-runtime/admit-compat-lib.js +11 -1
  155. package/dist/cad-runtime/admit-compat-lib.js.map +1 -1
  156. package/dist/cad-runtime/browser-lib-loader.d.ts +16 -11
  157. package/dist/cad-runtime/browser-lib-loader.d.ts.map +1 -1
  158. package/dist/cad-runtime/browser-lib-loader.js +16 -8
  159. package/dist/cad-runtime/browser-lib-loader.js.map +1 -1
  160. package/dist/cad-runtime/direct-executor.d.ts +62 -5
  161. package/dist/cad-runtime/direct-executor.d.ts.map +1 -1
  162. package/dist/cad-runtime/direct-executor.js +617 -42
  163. package/dist/cad-runtime/direct-executor.js.map +1 -1
  164. package/dist/cad-runtime/interp/closure.d.ts +3 -2
  165. package/dist/cad-runtime/interp/closure.d.ts.map +1 -1
  166. package/dist/cad-runtime/interp/closure.js.map +1 -1
  167. package/dist/cad-runtime/interp/env.d.ts +9 -6
  168. package/dist/cad-runtime/interp/env.d.ts.map +1 -1
  169. package/dist/cad-runtime/interp/env.js +4 -2
  170. package/dist/cad-runtime/interp/env.js.map +1 -1
  171. package/dist/cad-runtime/lib-decl.d.ts +121 -0
  172. package/dist/cad-runtime/lib-decl.d.ts.map +1 -0
  173. package/dist/cad-runtime/lib-decl.js +100 -0
  174. package/dist/cad-runtime/lib-decl.js.map +1 -0
  175. package/dist/cad-runtime/ports.d.ts +12 -0
  176. package/dist/cad-runtime/ports.d.ts.map +1 -1
  177. package/dist/cad-runtime/ports.js.map +1 -1
  178. package/dist/cad-runtime/runtime.d.ts +59 -5
  179. package/dist/cad-runtime/runtime.d.ts.map +1 -1
  180. package/dist/cad-runtime/runtime.js +237 -18
  181. package/dist/cad-runtime/runtime.js.map +1 -1
  182. package/dist/extra/browser.d.ts +9 -0
  183. package/dist/extra/browser.d.ts.map +1 -0
  184. package/dist/extra/browser.js +9 -0
  185. package/dist/extra/browser.js.map +1 -0
  186. package/dist/extra/editor-ops.d.ts +22 -0
  187. package/dist/extra/editor-ops.d.ts.map +1 -0
  188. package/dist/extra/editor-ops.js +21 -0
  189. package/dist/extra/editor-ops.js.map +1 -0
  190. package/dist/extra/extras/svg-extrude.d.ts +45 -0
  191. package/dist/extra/extras/svg-extrude.d.ts.map +1 -0
  192. package/dist/extra/extras/svg-extrude.js +110 -0
  193. package/dist/extra/extras/svg-extrude.js.map +1 -0
  194. package/dist/extra/extras/text-cjk.d.ts +36 -0
  195. package/dist/extra/extras/text-cjk.d.ts.map +1 -0
  196. package/dist/extra/extras/text-cjk.js +86 -0
  197. package/dist/extra/extras/text-cjk.js.map +1 -0
  198. package/dist/extra/extras/text-geometry.d.ts +69 -0
  199. package/dist/extra/extras/text-geometry.d.ts.map +1 -0
  200. package/dist/extra/extras/text-geometry.js +188 -0
  201. package/dist/extra/extras/text-geometry.js.map +1 -0
  202. package/dist/extra/index.d.ts +40 -0
  203. package/dist/extra/index.d.ts.map +1 -0
  204. package/dist/extra/index.js +40 -0
  205. package/dist/extra/index.js.map +1 -0
  206. package/dist/extra/mesh/drill-hole/DrillHoleCore.d.ts +94 -0
  207. package/dist/extra/mesh/drill-hole/DrillHoleCore.d.ts.map +1 -0
  208. package/dist/extra/mesh/drill-hole/DrillHoleCore.js +282 -0
  209. package/dist/extra/mesh/drill-hole/DrillHoleCore.js.map +1 -0
  210. package/dist/extra/mesh/drill-hole/drill-types.d.ts +34 -0
  211. package/dist/extra/mesh/drill-hole/drill-types.d.ts.map +1 -0
  212. package/dist/extra/mesh/drill-hole/drill-types.js +7 -0
  213. package/dist/extra/mesh/drill-hole/drill-types.js.map +1 -0
  214. package/dist/extra/mesh/engrave-decoration.d.ts +42 -0
  215. package/dist/extra/mesh/engrave-decoration.d.ts.map +1 -0
  216. package/dist/extra/mesh/engrave-decoration.js +39 -0
  217. package/dist/extra/mesh/engrave-decoration.js.map +1 -0
  218. package/dist/extra/mesh/fai_drill.d.ts +21 -0
  219. package/dist/extra/mesh/fai_drill.d.ts.map +1 -0
  220. package/dist/extra/mesh/fai_drill.js +89 -0
  221. package/dist/extra/mesh/fai_drill.js.map +1 -0
  222. package/dist/extra/mesh/fai_extrude.d.ts +24 -0
  223. package/dist/extra/mesh/fai_extrude.d.ts.map +1 -0
  224. package/dist/extra/mesh/fai_extrude.js +42 -0
  225. package/dist/extra/mesh/fai_extrude.js.map +1 -0
  226. package/dist/extra/mesh/fai_split.d.ts +164 -0
  227. package/dist/extra/mesh/fai_split.d.ts.map +1 -0
  228. package/dist/extra/mesh/fai_split.js +269 -0
  229. package/dist/extra/mesh/fai_split.js.map +1 -0
  230. package/dist/extra/mesh/primitives.d.ts +29 -0
  231. package/dist/extra/mesh/primitives.d.ts.map +1 -0
  232. package/dist/extra/mesh/primitives.js +41 -0
  233. package/dist/extra/mesh/primitives.js.map +1 -0
  234. package/dist/extra/op-names.d.ts +37 -0
  235. package/dist/extra/op-names.d.ts.map +1 -0
  236. package/dist/extra/op-names.js +46 -0
  237. package/dist/extra/op-names.js.map +1 -0
  238. package/dist/extra/ops/compound.d.ts +140 -0
  239. package/dist/extra/ops/compound.d.ts.map +1 -0
  240. package/dist/extra/ops/compound.js +167 -0
  241. package/dist/extra/ops/compound.js.map +1 -0
  242. package/dist/extra/ops/copy.d.ts +40 -0
  243. package/dist/extra/ops/copy.d.ts.map +1 -0
  244. package/dist/extra/ops/copy.js +83 -0
  245. package/dist/extra/ops/copy.js.map +1 -0
  246. package/dist/extra/ops/fai_drill.d.ts +51 -0
  247. package/dist/extra/ops/fai_drill.d.ts.map +1 -0
  248. package/dist/extra/ops/fai_drill.js +233 -0
  249. package/dist/extra/ops/fai_drill.js.map +1 -0
  250. package/dist/extra/ops/fai_extrude.d.ts +36 -0
  251. package/dist/extra/ops/fai_extrude.d.ts.map +1 -0
  252. package/dist/extra/ops/fai_extrude.js +84 -0
  253. package/dist/extra/ops/fai_extrude.js.map +1 -0
  254. package/dist/extra/ops/fai_split.d.ts +46 -0
  255. package/dist/extra/ops/fai_split.d.ts.map +1 -0
  256. package/dist/extra/ops/fai_split.js +235 -0
  257. package/dist/extra/ops/fai_split.js.map +1 -0
  258. package/dist/extra/ops/load.d.ts +49 -0
  259. package/dist/extra/ops/load.d.ts.map +1 -0
  260. package/dist/extra/ops/load.js +385 -0
  261. package/dist/extra/ops/load.js.map +1 -0
  262. package/dist/extra/ops/svg-extrude.d.ts +32 -0
  263. package/dist/extra/ops/svg-extrude.d.ts.map +1 -0
  264. package/dist/extra/ops/svg-extrude.js +74 -0
  265. package/dist/extra/ops/svg-extrude.js.map +1 -0
  266. package/dist/extra/ops/text.d.ts +34 -0
  267. package/dist/extra/ops/text.d.ts.map +1 -0
  268. package/dist/extra/ops/text.js +100 -0
  269. package/dist/extra/ops/text.js.map +1 -0
  270. package/dist/geometry2d/bridge/lift-on-plane.d.ts +8 -5
  271. package/dist/geometry2d/bridge/lift-on-plane.d.ts.map +1 -1
  272. package/dist/geometry2d/bridge/lift-on-plane.js +8 -5
  273. package/dist/geometry2d/bridge/lift-on-plane.js.map +1 -1
  274. package/dist/index.d.ts +6 -2
  275. package/dist/index.d.ts.map +1 -1
  276. package/dist/index.js +8 -2
  277. package/dist/index.js.map +1 -1
  278. package/dist/lang/symbol-table.d.ts +3 -3
  279. package/dist/lang/symbol-table.generated.d.ts +10 -0
  280. package/dist/lang/symbol-table.generated.d.ts.map +1 -1
  281. package/dist/lang/symbol-table.generated.js +10 -0
  282. package/dist/lang/symbol-table.generated.js.map +1 -1
  283. package/dist/lang/symbol-table.js +3 -3
  284. package/dist/lang/symbol-table.js.map +1 -1
  285. package/dist/math3d/index.d.ts +1 -1
  286. package/dist/math3d/index.js +1 -1
  287. package/dist/math3d/index.js.map +1 -1
  288. package/dist/mesh/engrave.d.ts +2 -3
  289. package/dist/mesh/engrave.d.ts.map +1 -1
  290. package/dist/mesh/engrave.js +4 -11
  291. package/dist/mesh/engrave.js.map +1 -1
  292. package/dist/mesh/index.d.ts +0 -2
  293. package/dist/mesh/index.d.ts.map +1 -1
  294. package/dist/mesh/index.js +0 -2
  295. package/dist/mesh/index.js.map +1 -1
  296. package/dist/mesh/primitives.d.ts +1 -1
  297. package/dist/mesh/primitives.js +1 -1
  298. package/dist/mesh/primitives.js.map +1 -1
  299. package/dist/node-host/cli.d.ts +20 -4
  300. package/dist/node-host/cli.d.ts.map +1 -1
  301. package/dist/node-host/cli.js +84 -35
  302. package/dist/node-host/cli.js.map +1 -1
  303. package/dist/node-host/execute-script.d.ts.map +1 -1
  304. package/dist/node-host/execute-script.js +3 -4
  305. package/dist/node-host/execute-script.js.map +1 -1
  306. package/dist/node-host/lib-package-json.d.ts +36 -0
  307. package/dist/node-host/lib-package-json.d.ts.map +1 -0
  308. package/dist/node-host/lib-package-json.js +73 -0
  309. package/dist/node-host/lib-package-json.js.map +1 -0
  310. package/dist/occt-kernel/occt-primitives.d.ts.map +1 -1
  311. package/dist/occt-kernel/occt-primitives.js +41 -0
  312. package/dist/occt-kernel/occt-primitives.js.map +1 -1
  313. package/dist/occt-kernel/occtKernel.d.ts +1 -1
  314. package/dist/occt-kernel/occtKernel.js +1 -1
  315. package/dist/occt-kernel/occtKernel.js.map +1 -1
  316. package/dist/runtime-state.d.ts +28 -1
  317. package/dist/runtime-state.d.ts.map +1 -1
  318. package/dist/runtime-state.js +14 -1
  319. package/dist/runtime-state.js.map +1 -1
  320. package/dist/sdk.d.ts +2 -2
  321. package/dist/sdk.d.ts.map +1 -1
  322. package/dist/sdk.js +11 -2
  323. package/dist/sdk.js.map +1 -1
  324. package/dist/sketch/bspline.d.ts +58 -0
  325. package/dist/sketch/bspline.d.ts.map +1 -0
  326. package/dist/sketch/bspline.js +104 -0
  327. package/dist/sketch/bspline.js.map +1 -0
  328. package/dist/sketch/canonical.d.ts +239 -0
  329. package/dist/sketch/canonical.d.ts.map +1 -0
  330. package/dist/sketch/canonical.js +17 -0
  331. package/dist/sketch/canonical.js.map +1 -0
  332. package/dist/sketch/contour.d.ts +43 -0
  333. package/dist/sketch/contour.d.ts.map +1 -0
  334. package/dist/sketch/contour.js +202 -0
  335. package/dist/sketch/contour.js.map +1 -0
  336. package/dist/sketch/dim-spec.d.ts +32 -0
  337. package/dist/sketch/dim-spec.d.ts.map +1 -0
  338. package/dist/sketch/dim-spec.js +112 -0
  339. package/dist/sketch/dim-spec.js.map +1 -0
  340. package/dist/sketch/faces.d.ts +45 -0
  341. package/dist/sketch/faces.d.ts.map +1 -0
  342. package/dist/sketch/faces.js +108 -0
  343. package/dist/sketch/faces.js.map +1 -0
  344. package/dist/sketch/fcstd-types.d.ts +194 -0
  345. package/dist/sketch/fcstd-types.d.ts.map +1 -0
  346. package/dist/sketch/fcstd-types.js +67 -0
  347. package/dist/sketch/fcstd-types.js.map +1 -0
  348. package/dist/sketch/index.d.ts +46 -0
  349. package/dist/sketch/index.d.ts.map +1 -0
  350. package/dist/sketch/index.js +39 -0
  351. package/dist/sketch/index.js.map +1 -0
  352. package/dist/sketch/node.d.ts +14 -0
  353. package/dist/sketch/node.d.ts.map +1 -0
  354. package/dist/sketch/node.js +43 -0
  355. package/dist/sketch/node.js.map +1 -0
  356. package/dist/sketch/op.d.ts +111 -0
  357. package/dist/sketch/op.d.ts.map +1 -0
  358. package/dist/sketch/op.js +185 -0
  359. package/dist/sketch/op.js.map +1 -0
  360. package/dist/sketch/planegcs-backend.d.ts +69 -0
  361. package/dist/sketch/planegcs-backend.d.ts.map +1 -0
  362. package/dist/sketch/planegcs-backend.js +812 -0
  363. package/dist/sketch/planegcs-backend.js.map +1 -0
  364. package/dist/sketch/project.d.ts +176 -0
  365. package/dist/sketch/project.d.ts.map +1 -0
  366. package/dist/sketch/project.js +656 -0
  367. package/dist/sketch/project.js.map +1 -0
  368. package/dist/sketch/shapes.d.ts +370 -0
  369. package/dist/sketch/shapes.d.ts.map +1 -0
  370. package/dist/sketch/shapes.js +959 -0
  371. package/dist/sketch/shapes.js.map +1 -0
  372. package/dist/sketch/solve.d.ts +21 -0
  373. package/dist/sketch/solve.d.ts.map +1 -0
  374. package/dist/sketch/solve.js +144 -0
  375. package/dist/sketch/solve.js.map +1 -0
  376. package/dist/sketch/solver-loader.d.ts +47 -0
  377. package/dist/sketch/solver-loader.d.ts.map +1 -0
  378. package/dist/sketch/solver-loader.js +77 -0
  379. package/dist/sketch/solver-loader.js.map +1 -0
  380. package/dist/sketch/solver.d.ts +63 -0
  381. package/dist/sketch/solver.d.ts.map +1 -0
  382. package/dist/sketch/solver.js +28 -0
  383. package/dist/sketch/solver.js.map +1 -0
  384. package/dist/sketch/verify.d.ts +53 -0
  385. package/dist/sketch/verify.d.ts.map +1 -0
  386. package/dist/sketch/verify.js +71 -0
  387. package/dist/sketch/verify.js.map +1 -0
  388. package/dist/weapp.d.ts +1 -1
  389. package/dist/weapp.d.ts.map +1 -1
  390. package/dist/weapp.js +1 -1
  391. package/dist/weapp.js.map +1 -1
  392. package/package.json +43 -11
@@ -4,8 +4,9 @@
4
4
  * Corresponds to the vm backend's `__ctx.<name> = async function <name>(...)`
5
5
  * hoisting: every user function becomes an async callable stored in ctx.
6
6
  * Visible bindings inside the body = params + namespace bindings + S4 safe
7
- * globals (D2) — never top-level ctx variables. Nested closures additionally
8
- * see the enclosing function's locals (D3 lexical capture).
7
+ * globals + top-level ctx variables/functions (constraint 1: call-time reads;
8
+ * writes stay local per env.assign) + enclosing function locals for nested
9
+ * closures (D3 lexical capture).
9
10
  *
10
11
  * Module-graph note: this file must NOT import eval-expr/exec-stmt (they
11
12
  * import this file); body execution goes through the lazily wired
@@ -1 +1 @@
1
- {"version":3,"file":"closure.d.ts","sourceRoot":"","sources":["../../../src/cad-runtime/interp/closure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,OAAO,CAAA;AAGnD;;;;GAIG;AACH,qBAAa,aAAa;IAEtB,8EAA8E;IAC9E,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,4EAA4E;IAC5E,OAAO,CAAC,QAAQ,CAAC,MAAM;;IAHvB,8EAA8E;IAC7D,IAAI,EAAE,OAAO;IAC9B,4EAA4E;IAC3D,MAAM,EAAE,SAAS;IAGpC;;;;;OAKG;IACG,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;CA4ClE"}
1
+ {"version":3,"file":"closure.d.ts","sourceRoot":"","sources":["../../../src/cad-runtime/interp/closure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,OAAO,CAAA;AAGnD;;;;GAIG;AACH,qBAAa,aAAa;IAEtB,8EAA8E;IAC9E,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,4EAA4E;IAC5E,OAAO,CAAC,QAAQ,CAAC,MAAM;;IAHvB,8EAA8E;IAC7D,IAAI,EAAE,OAAO;IAC9B,4EAA4E;IAC3D,MAAM,EAAE,SAAS;IAGpC;;;;;OAKG;IACG,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;CA4ClE"}
@@ -1 +1 @@
1
- {"version":3,"file":"closure.js","sourceRoot":"","sources":["../../../src/cad-runtime/interp/closure.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,SAAS,EAAoB,MAAM,OAAO,CAAA;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAExC;;;;GAIG;AACH,MAAM,OAAO,aAAa;IAGL;IAEA;IAJnB;IACE,8EAA8E;IAC7D,IAAa;IAC9B,4EAA4E;IAC3D,MAAiB;QAFjB,SAAI,GAAJ,IAAI,CAAS;QAEb,WAAM,GAAN,MAAM,CAAW;IACjC,CAAC;IAEJ;;;;;OAKG;IACH,KAAK,CAAC,IAAI,CAAC,IAAe,EAAE,KAAkB;QAC5C,IAAI,EAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;YACnC,KAAK,CAAC,KAAK,EAAE,CAAA;YACb,MAAM,IAAI,KAAK,CAAC,mDAAmD,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAA;QACvF,CAAC;QACD,IAAI,CAAC;YACH,qEAAqE;YACrE,8DAA8D;YAC9D,MAAM,GAAG,GAAG,IAAI,SAAS,CACvB,UAAU,EACV,KAAK,CAAC,IAAI,CAAC,GAAG,EACd,KAAK,CAAC,IAAI,CAAC,UAAU,EACrB,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CACtD,CAAA;YACD,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAU,EAAE,EAAE,CACzD,CAAC,EAAE,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CACzC,CAAA;YACD,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;gBACvB,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;oBACf,MAAM,IAAI,KAAK,CAAC,4EAA4E,CAAC,CAAA;gBAC/F,CAAC;YACH,CAAC;YACD,MAAM,CAAC,OAAO,CAAC,CAAC,CAAS,EAAE,CAAS,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YAClE,qEAAqE;YACrE,wEAAwE;YACxE,mEAAmE;YACnE,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC;gBACvB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;YACvC,CAAC;YACD,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,KAAK,gBAAgB,EAAE,CAAC;gBAC9C,IAAI,CAAC;oBACH,MAAM,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,EAAE,GAAG,CAAC,CAAA;gBACtD,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,IAAI,CAAC,YAAY,YAAY;wBAAE,OAAO,CAAC,CAAC,KAAK,CAAA;oBAC7C,MAAM,CAAC,CAAA;gBACT,CAAC;gBACD,OAAO,SAAS,CAAA;YAClB,CAAC;YACD,6BAA6B;YAC7B,OAAO,MAAM,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QAClD,CAAC;gBAAS,CAAC;YACT,KAAK,CAAC,KAAK,EAAE,CAAA;QACf,CAAC;IACH,CAAC;CACF","sourcesContent":["/**\n * closure — InterpClosure, the interpreter's function object.\n *\n * Corresponds to the vm backend's `__ctx.<name> = async function <name>(...)`\n * hoisting: every user function becomes an async callable stored in ctx.\n * Visible bindings inside the body = params + namespace bindings + S4 safe\n * globals (D2) — never top-level ctx variables. Nested closures additionally\n * see the enclosing function's locals (D3 lexical capture).\n *\n * Module-graph note: this file must NOT import eval-expr/exec-stmt (they\n * import this file); body execution goes through the lazily wired\n * state.evalExpr / state.execBody.\n */\nimport type { ASTNode } from '../exec-backend'\nimport { InterpEnv, type InterpState } from './env'\nimport { ReturnSignal } from './signals'\n\n/**\n * An interpreter-created user function value (FunctionDeclaration /\n * FunctionExpression / ArrowFunctionExpression). Corresponds to the vm\n * backend's `__ctx.<name> = async function <name>(...)` hoisted closure.\n */\nexport class InterpClosure {\n constructor(\n /** FunctionDeclaration / FunctionExpression / ArrowFunctionExpression node */\n private readonly node: ASTNode,\n /** defining env (lexical parent for nested closures; root env → dropped) */\n private readonly defEnv: InterpEnv,\n ) {}\n\n /**\n * Invoke the closure with positional args.\n * @param args - evaluated call arguments (positional; params ABI §3.4).\n * @param state - shared interpreter state (recursion guard, wired evaluators).\n * @returns the returned value (undefined for a plain body end).\n */\n async call(args: unknown[], state: InterpState): Promise<unknown> {\n if (++state.depth > state.maxDepth) {\n state.depth--\n throw new Error(`E_EXEC_LIMIT: closure recursion depth exceeded (${state.maxDepth})`)\n }\n try {\n // ctx/ns come from the CALL-time host (registerLib hot-update safe);\n // the parent chain carries only lexical function locals (D3).\n const env = new InterpEnv(\n 'function',\n state.host.ctx,\n state.host.namespaces,\n this.defEnv.kind === 'root' ? undefined : this.defEnv,\n )\n const params = (this.node.params ?? []).map((p: ASTNode) =>\n p?.type === 'Identifier' ? p.name : null,\n )\n for (const p of params) {\n if (p === null) {\n throw new Error('E_UNSUPPORTED_SYNTAX: non-identifier function parameters are not supported')\n }\n }\n params.forEach((p: string, i: number) => env.vars.set(p, args[i]))\n // Named function expression self-binding (matches the vm path, where\n // transformFunction emits `__ctx.<name> = async function <name>(...)` —\n // the function name inside the body binds to the function itself).\n if (this.node.id?.name) {\n env.vars.set(this.node.id.name, this)\n }\n if (this.node.body?.type === 'BlockStatement') {\n try {\n await state.execBody(this.node.body.body ?? [], env)\n } catch (e) {\n if (e instanceof ReturnSignal) return e.value\n throw e\n }\n return undefined\n }\n // arrow with expression body\n return await state.evalExpr(this.node.body, env)\n } finally {\n state.depth--\n }\n }\n}\n"]}
1
+ {"version":3,"file":"closure.js","sourceRoot":"","sources":["../../../src/cad-runtime/interp/closure.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,SAAS,EAAoB,MAAM,OAAO,CAAA;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAExC;;;;GAIG;AACH,MAAM,OAAO,aAAa;IAGL;IAEA;IAJnB;IACE,8EAA8E;IAC7D,IAAa;IAC9B,4EAA4E;IAC3D,MAAiB;QAFjB,SAAI,GAAJ,IAAI,CAAS;QAEb,WAAM,GAAN,MAAM,CAAW;IACjC,CAAC;IAEJ;;;;;OAKG;IACH,KAAK,CAAC,IAAI,CAAC,IAAe,EAAE,KAAkB;QAC5C,IAAI,EAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;YACnC,KAAK,CAAC,KAAK,EAAE,CAAA;YACb,MAAM,IAAI,KAAK,CAAC,mDAAmD,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAA;QACvF,CAAC;QACD,IAAI,CAAC;YACH,qEAAqE;YACrE,8DAA8D;YAC9D,MAAM,GAAG,GAAG,IAAI,SAAS,CACvB,UAAU,EACV,KAAK,CAAC,IAAI,CAAC,GAAG,EACd,KAAK,CAAC,IAAI,CAAC,UAAU,EACrB,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CACtD,CAAA;YACD,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAU,EAAE,EAAE,CACzD,CAAC,EAAE,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CACzC,CAAA;YACD,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;gBACvB,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;oBACf,MAAM,IAAI,KAAK,CAAC,4EAA4E,CAAC,CAAA;gBAC/F,CAAC;YACH,CAAC;YACD,MAAM,CAAC,OAAO,CAAC,CAAC,CAAS,EAAE,CAAS,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YAClE,qEAAqE;YACrE,wEAAwE;YACxE,mEAAmE;YACnE,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC;gBACvB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;YACvC,CAAC;YACD,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,KAAK,gBAAgB,EAAE,CAAC;gBAC9C,IAAI,CAAC;oBACH,MAAM,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,EAAE,GAAG,CAAC,CAAA;gBACtD,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,IAAI,CAAC,YAAY,YAAY;wBAAE,OAAO,CAAC,CAAC,KAAK,CAAA;oBAC7C,MAAM,CAAC,CAAA;gBACT,CAAC;gBACD,OAAO,SAAS,CAAA;YAClB,CAAC;YACD,6BAA6B;YAC7B,OAAO,MAAM,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QAClD,CAAC;gBAAS,CAAC;YACT,KAAK,CAAC,KAAK,EAAE,CAAA;QACf,CAAC;IACH,CAAC;CACF","sourcesContent":["/**\n * closure — InterpClosure, the interpreter's function object.\n *\n * Corresponds to the vm backend's `__ctx.<name> = async function <name>(...)`\n * hoisting: every user function becomes an async callable stored in ctx.\n * Visible bindings inside the body = params + namespace bindings + S4 safe\n * globals + top-level ctx variables/functions (constraint 1: call-time reads;\n * writes stay local per env.assign) + enclosing function locals for nested\n * closures (D3 lexical capture).\n *\n * Module-graph note: this file must NOT import eval-expr/exec-stmt (they\n * import this file); body execution goes through the lazily wired\n * state.evalExpr / state.execBody.\n */\nimport type { ASTNode } from '../exec-backend'\nimport { InterpEnv, type InterpState } from './env'\nimport { ReturnSignal } from './signals'\n\n/**\n * An interpreter-created user function value (FunctionDeclaration /\n * FunctionExpression / ArrowFunctionExpression). Corresponds to the vm\n * backend's `__ctx.<name> = async function <name>(...)` hoisted closure.\n */\nexport class InterpClosure {\n constructor(\n /** FunctionDeclaration / FunctionExpression / ArrowFunctionExpression node */\n private readonly node: ASTNode,\n /** defining env (lexical parent for nested closures; root env → dropped) */\n private readonly defEnv: InterpEnv,\n ) {}\n\n /**\n * Invoke the closure with positional args.\n * @param args - evaluated call arguments (positional; params ABI §3.4).\n * @param state - shared interpreter state (recursion guard, wired evaluators).\n * @returns the returned value (undefined for a plain body end).\n */\n async call(args: unknown[], state: InterpState): Promise<unknown> {\n if (++state.depth > state.maxDepth) {\n state.depth--\n throw new Error(`E_EXEC_LIMIT: closure recursion depth exceeded (${state.maxDepth})`)\n }\n try {\n // ctx/ns come from the CALL-time host (registerLib hot-update safe);\n // the parent chain carries only lexical function locals (D3).\n const env = new InterpEnv(\n 'function',\n state.host.ctx,\n state.host.namespaces,\n this.defEnv.kind === 'root' ? undefined : this.defEnv,\n )\n const params = (this.node.params ?? []).map((p: ASTNode) =>\n p?.type === 'Identifier' ? p.name : null,\n )\n for (const p of params) {\n if (p === null) {\n throw new Error('E_UNSUPPORTED_SYNTAX: non-identifier function parameters are not supported')\n }\n }\n params.forEach((p: string, i: number) => env.vars.set(p, args[i]))\n // Named function expression self-binding (matches the vm path, where\n // transformFunction emits `__ctx.<name> = async function <name>(...)` —\n // the function name inside the body binds to the function itself).\n if (this.node.id?.name) {\n env.vars.set(this.node.id.name, this)\n }\n if (this.node.body?.type === 'BlockStatement') {\n try {\n await state.execBody(this.node.body.body ?? [], env)\n } catch (e) {\n if (e instanceof ReturnSignal) return e.value\n throw e\n }\n return undefined\n }\n // arrow with expression body\n return await state.evalExpr(this.node.body, env)\n } finally {\n state.depth--\n }\n }\n}\n"]}
@@ -4,10 +4,10 @@
4
4
  * Env kinds (design D1/D2):
5
5
  * - root: the persistent ctx IS the variable container — reads resolve ctx,
6
6
  * writes go to ctx (block-level const/let included, R-5 semantics per D1).
7
- * - function: params + function-local let/const only; a function body CANNOT
8
- * see top-level ctx variables (D2 — matches the vm backend, where the
9
- * function body is embedded verbatim inside `new Function`, so ctx
10
- * identifiers are free identifiers there and ReferenceError).
7
+ * - function: params + function-local let/const, plus call-time READ access to
8
+ * top-level ctx variables/functions (constraint 1 contract — matches the vm
9
+ * backend's injected `let { ... } = __ctx` destructuring). Writes stay
10
+ * local (assign): function bodies never modify top-level variables.
11
11
  * - overlay: catch-clause scope — local vars, reads fall through to parent,
12
12
  * writes stay local (matches the vm path where the catch param is a plain
13
13
  * function-scope binding, not hoisted to ctx).
@@ -15,7 +15,8 @@
15
15
  * Root identifier resolution order (matches hoistText: declared/ctx names are
16
16
  * rewritten to `__ctx.<name>`, so ctx wins over ns): overlay vars → ctx →
17
17
  * namespace bindings → S4 safe globals → ReferenceError.
18
- * Function env: vars → parent function vars → ns → globals (never ctx, D2).
18
+ * Function env: vars → parent function vars → ctx → ns → globals (ctx reads
19
+ * are call-time; ctx writes from function bodies land in local vars).
19
20
  */
20
21
  import type { ExecHost, ASTNode } from '../exec-backend.js';
21
22
  /** Where a resolved identifier binding lives. */
@@ -63,7 +64,9 @@ export declare class InterpEnv {
63
64
  */
64
65
  hasNs(name: string): boolean;
65
66
  /**
66
- * Resolve an identifier through vars → ctx → ns → S4 globals.
67
+ * Resolve an identifier through vars → parent vars → ctx → ns → S4 globals.
68
+ * Function envs read top-level ctx bindings at call time (constraint 1);
69
+ * writes from function envs never reach ctx (see assign).
67
70
  * @param name - identifier to resolve.
68
71
  * @returns the binding, or undefined when unresolvable (caller throws ReferenceError).
69
72
  */
@@ -1 +1 @@
1
- {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../../src/cad-runtime/interp/env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAGxD,iDAAiD;AACjD,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAA;AAE5D,2EAA2E;AAC3E,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,YAAY,CAAA;IACnB,KAAK,EAAE,OAAO,CAAA;CACf;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,CAAA;IACd,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAA;IACb,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,CAAA;IAChB,kDAAkD;IAClD,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IAC7D,qDAAqD;IACrD,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,SAAS,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CAChE;AAED;;;GAGG;AACH,qBAAa,SAAS;IAKlB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,iFAAiF;IACjF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAR1B,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,uBAA6B;gBAG/B,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,EAC7B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC5C,iFAAiF;IAChE,MAAM,CAAC,EAAE,SAAS,YAAA;IAGrC;;;;OAIG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI5B;;;;OAIG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAmBjD;;;;;OAKG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;CAe3C"}
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../../src/cad-runtime/interp/env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAGxD,iDAAiD;AACjD,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAA;AAE5D,2EAA2E;AAC3E,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,YAAY,CAAA;IACnB,KAAK,EAAE,OAAO,CAAA;CACf;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,CAAA;IACd,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAA;IACb,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,CAAA;IAChB,kDAAkD;IAClD,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IAC7D,qDAAqD;IACrD,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,SAAS,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CAChE;AAED;;;GAGG;AACH,qBAAa,SAAS;IAKlB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,iFAAiF;IACjF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAR1B,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,uBAA6B;gBAG/B,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,EAC7B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC5C,iFAAiF;IAChE,MAAM,CAAC,EAAE,SAAS,YAAA;IAGrC;;;;OAIG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI5B;;;;;;OAMG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAmBjD;;;;;OAKG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;CAe3C"}
@@ -27,7 +27,9 @@ export class InterpEnv {
27
27
  return Object.prototype.hasOwnProperty.call(this.ns, name);
28
28
  }
29
29
  /**
30
- * Resolve an identifier through vars → ctx → ns → S4 globals.
30
+ * Resolve an identifier through vars → parent vars → ctx → ns → S4 globals.
31
+ * Function envs read top-level ctx bindings at call time (constraint 1);
32
+ * writes from function envs never reach ctx (see assign).
31
33
  * @param name - identifier to resolve.
32
34
  * @returns the binding, or undefined when unresolvable (caller throws ReferenceError).
33
35
  */
@@ -40,7 +42,7 @@ export class InterpEnv {
40
42
  return { where: 'local', value: p.vars.get(name) };
41
43
  p = p.parent;
42
44
  }
43
- if (this.kind !== 'function' && Object.prototype.hasOwnProperty.call(this.ctx, name)) {
45
+ if (Object.prototype.hasOwnProperty.call(this.ctx, name)) {
44
46
  return { where: 'ctx', value: this.ctx[name] };
45
47
  }
46
48
  if (this.hasNs(name)) {
@@ -1 +1 @@
1
- {"version":3,"file":"env.js","sourceRoot":"","sources":["../../../src/cad-runtime/interp/env.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * env — scope/binding resolution for the AST interpreter.\n *\n * Env kinds (design D1/D2):\n * - root: the persistent ctx IS the variable container — reads resolve ctx,\n * writes go to ctx (block-level const/let included, R-5 semantics per D1).\n * - function: params + function-local let/const only; a function body CANNOT\n * see top-level ctx variables (D2 — matches the vm backend, where the\n * function body is embedded verbatim inside `new Function`, so ctx\n * identifiers are free identifiers there and ReferenceError).\n * - overlay: catch-clause scope — local vars, reads fall through to parent,\n * writes stay local (matches the vm path where the catch param is a plain\n * function-scope binding, not hoisted to ctx).\n *\n * Root identifier resolution order (matches hoistText: declared/ctx names are\n * rewritten to `__ctx.<name>`, so ctx wins over ns): overlay vars → ctx →\n * namespace bindings → S4 safe globals → ReferenceError.\n * Function env: vars → parent function vars → ns → globals (never ctx, D2).\n */\nimport type { ExecHost, ASTNode } from '../exec-backend'\nimport { S4_SAFE_GLOBALS } from '../../lang/security-scanner'\n\n/** Where a resolved identifier binding lives. */\nexport type BindingWhere = 'ns' | 'ctx' | 'global' | 'local'\n\n/** Result of resolving an identifier: its scope kind and current value. */\nexport interface ResolvedBinding {\n where: BindingWhere\n value: unknown\n}\n\n/**\n * Interpreter-wide state shared by all eval/exec calls within one unit run.\n * `evalExpr`/`execBody` are wired by the backend (lazily, to keep the module\n * graph acyclic: eval-expr → closure, exec-stmt → eval-expr, closure → state).\n */\nexport interface InterpState {\n host: ExecHost\n /** current closure recursion depth (guard against stack blowout) */\n depth: number\n /** maximum closure recursion depth before E_EXEC_LIMIT */\n maxDepth: number\n /** expression evaluator (wired by the backend) */\n evalExpr: (node: ASTNode, env: InterpEnv) => Promise<unknown>\n /** statement-list executor (wired by the backend) */\n execBody: (body: ASTNode[], env: InterpEnv) => Promise<unknown>\n}\n\n/**\n * Lexical environment for one scope level of the AST interpreter.\n * See module doc for the root/function/overlay semantics (D1/D2).\n */\nexport class InterpEnv {\n /** local bindings (function params/locals, catch params, for-in/of vars) */\n readonly vars = new Map<string, unknown>()\n\n constructor(\n readonly kind: 'root' | 'function' | 'overlay',\n private readonly ctx: Record<string, unknown>,\n private readonly ns: Record<string, unknown>,\n /** enclosing function env (closures only; never crosses into a root env — D2) */\n private readonly parent?: InterpEnv,\n ) {}\n\n /**\n * True when `name` is a namespace binding.\n * @param name - identifier to test.\n * @returns true when the namespaces record owns `name`.\n */\n hasNs(name: string): boolean {\n return Object.prototype.hasOwnProperty.call(this.ns, name)\n }\n\n /**\n * Resolve an identifier through vars → ctx → ns → S4 globals.\n * @param name - identifier to resolve.\n * @returns the binding, or undefined when unresolvable (caller throws ReferenceError).\n */\n lookup(name: string): ResolvedBinding | undefined {\n if (this.vars.has(name)) return { where: 'local', value: this.vars.get(name) }\n let p = this.parent\n while (p) {\n if (p.vars.has(name)) return { where: 'local', value: p.vars.get(name) }\n p = p.parent\n }\n if (this.kind !== 'function' && Object.prototype.hasOwnProperty.call(this.ctx, name)) {\n return { where: 'ctx', value: this.ctx[name] }\n }\n if (this.hasNs(name)) {\n return { where: 'ns', value: (this.ns as Record<string, unknown>)[name] }\n }\n if (S4_SAFE_GLOBALS.has(name)) {\n return { where: 'global', value: (globalThis as Record<string, unknown>)[name] }\n }\n return undefined\n }\n\n /**\n * Write a variable: function/overlay envs stay local; the root env writes\n * through to the persistent ctx (D1). Namespace bindings are read-only.\n * @param name - identifier to write.\n * @param value - value to store.\n */\n assign(name: string, value: unknown): void {\n if (this.kind === 'function' || this.kind === 'overlay' || this.vars.has(name)) {\n // function bodies never write ctx (D2); overlay writes stay local\n if (this.hasNs(name) && !this.vars.has(name)) {\n throw new Error(`E_NS_ASSIGN: cannot assign to namespace binding \"${name}\"`)\n }\n this.vars.set(name, value)\n return\n }\n if (this.hasNs(name)) {\n throw new Error(`E_NS_ASSIGN: cannot assign to namespace binding \"${name}\"`)\n }\n // root env: writes go to the persistent ctx (D1)\n this.ctx[name] = value\n }\n}\n"]}
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../../src/cad-runtime/interp/env.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AA4B7D;;;GAGG;AACH,MAAM,OAAO,SAAS;IAKT;IACQ;IACA;IAEA;IARnB,4EAA4E;IACnE,IAAI,GAAG,IAAI,GAAG,EAAmB,CAAA;IAE1C,YACW,IAAqC,EAC7B,GAA4B,EAC5B,EAA2B;IAC5C,iFAAiF;IAChE,MAAkB;QAJ1B,SAAI,GAAJ,IAAI,CAAiC;QAC7B,QAAG,GAAH,GAAG,CAAyB;QAC5B,OAAE,GAAF,EAAE,CAAyB;QAE3B,WAAM,GAAN,MAAM,CAAY;IAClC,CAAC;IAEJ;;;;OAIG;IACH,KAAK,CAAC,IAAY;QAChB,OAAO,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAA;IAC5D,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,IAAY;QACjB,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAA;QAC9E,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAA;QACnB,OAAO,CAAC,EAAE,CAAC;YACT,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAA;YACxE,CAAC,GAAG,CAAC,CAAC,MAAM,CAAA;QACd,CAAC;QACD,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC;YACzD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAA;QAChD,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAG,IAAI,CAAC,EAA8B,CAAC,IAAI,CAAC,EAAE,CAAA;QAC3E,CAAC;QACD,IAAI,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAG,UAAsC,CAAC,IAAI,CAAC,EAAE,CAAA;QAClF,CAAC;QACD,OAAO,SAAS,CAAA;IAClB,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,IAAY,EAAE,KAAc;QACjC,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/E,kEAAkE;YAClE,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7C,MAAM,IAAI,KAAK,CAAC,oDAAoD,IAAI,GAAG,CAAC,CAAA;YAC9E,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;YAC1B,OAAM;QACR,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,oDAAoD,IAAI,GAAG,CAAC,CAAA;QAC9E,CAAC;QACD,iDAAiD;QACjD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAA;IACxB,CAAC;CACF","sourcesContent":["/**\n * env — scope/binding resolution for the AST interpreter.\n *\n * Env kinds (design D1/D2):\n * - root: the persistent ctx IS the variable container — reads resolve ctx,\n * writes go to ctx (block-level const/let included, R-5 semantics per D1).\n * - function: params + function-local let/const, plus call-time READ access to\n * top-level ctx variables/functions (constraint 1 contract — matches the vm\n * backend's injected `let { ... } = __ctx` destructuring). Writes stay\n * local (assign): function bodies never modify top-level variables.\n * - overlay: catch-clause scope — local vars, reads fall through to parent,\n * writes stay local (matches the vm path where the catch param is a plain\n * function-scope binding, not hoisted to ctx).\n *\n * Root identifier resolution order (matches hoistText: declared/ctx names are\n * rewritten to `__ctx.<name>`, so ctx wins over ns): overlay vars → ctx →\n * namespace bindings → S4 safe globals → ReferenceError.\n * Function env: vars → parent function vars → ctx → ns → globals (ctx reads\n * are call-time; ctx writes from function bodies land in local vars).\n */\nimport type { ExecHost, ASTNode } from '../exec-backend'\nimport { S4_SAFE_GLOBALS } from '../../lang/security-scanner'\n\n/** Where a resolved identifier binding lives. */\nexport type BindingWhere = 'ns' | 'ctx' | 'global' | 'local'\n\n/** Result of resolving an identifier: its scope kind and current value. */\nexport interface ResolvedBinding {\n where: BindingWhere\n value: unknown\n}\n\n/**\n * Interpreter-wide state shared by all eval/exec calls within one unit run.\n * `evalExpr`/`execBody` are wired by the backend (lazily, to keep the module\n * graph acyclic: eval-expr → closure, exec-stmt → eval-expr, closure → state).\n */\nexport interface InterpState {\n host: ExecHost\n /** current closure recursion depth (guard against stack blowout) */\n depth: number\n /** maximum closure recursion depth before E_EXEC_LIMIT */\n maxDepth: number\n /** expression evaluator (wired by the backend) */\n evalExpr: (node: ASTNode, env: InterpEnv) => Promise<unknown>\n /** statement-list executor (wired by the backend) */\n execBody: (body: ASTNode[], env: InterpEnv) => Promise<unknown>\n}\n\n/**\n * Lexical environment for one scope level of the AST interpreter.\n * See module doc for the root/function/overlay semantics (D1/D2).\n */\nexport class InterpEnv {\n /** local bindings (function params/locals, catch params, for-in/of vars) */\n readonly vars = new Map<string, unknown>()\n\n constructor(\n readonly kind: 'root' | 'function' | 'overlay',\n private readonly ctx: Record<string, unknown>,\n private readonly ns: Record<string, unknown>,\n /** enclosing function env (closures only; never crosses into a root env — D2) */\n private readonly parent?: InterpEnv,\n ) {}\n\n /**\n * True when `name` is a namespace binding.\n * @param name - identifier to test.\n * @returns true when the namespaces record owns `name`.\n */\n hasNs(name: string): boolean {\n return Object.prototype.hasOwnProperty.call(this.ns, name)\n }\n\n /**\n * Resolve an identifier through vars → parent vars → ctx → ns → S4 globals.\n * Function envs read top-level ctx bindings at call time (constraint 1);\n * writes from function envs never reach ctx (see assign).\n * @param name - identifier to resolve.\n * @returns the binding, or undefined when unresolvable (caller throws ReferenceError).\n */\n lookup(name: string): ResolvedBinding | undefined {\n if (this.vars.has(name)) return { where: 'local', value: this.vars.get(name) }\n let p = this.parent\n while (p) {\n if (p.vars.has(name)) return { where: 'local', value: p.vars.get(name) }\n p = p.parent\n }\n if (Object.prototype.hasOwnProperty.call(this.ctx, name)) {\n return { where: 'ctx', value: this.ctx[name] }\n }\n if (this.hasNs(name)) {\n return { where: 'ns', value: (this.ns as Record<string, unknown>)[name] }\n }\n if (S4_SAFE_GLOBALS.has(name)) {\n return { where: 'global', value: (globalThis as Record<string, unknown>)[name] }\n }\n return undefined\n }\n\n /**\n * Write a variable: function/overlay envs stay local; the root env writes\n * through to the persistent ctx (D1). Namespace bindings are read-only.\n * @param name - identifier to write.\n * @param value - value to store.\n */\n assign(name: string, value: unknown): void {\n if (this.kind === 'function' || this.kind === 'overlay' || this.vars.has(name)) {\n // function bodies never write ctx (D2); overlay writes stay local\n if (this.hasNs(name) && !this.vars.has(name)) {\n throw new Error(`E_NS_ASSIGN: cannot assign to namespace binding \"${name}\"`)\n }\n this.vars.set(name, value)\n return\n }\n if (this.hasNs(name)) {\n throw new Error(`E_NS_ASSIGN: cannot assign to namespace binding \"${name}\"`)\n }\n // root env: writes go to the persistent ctx (D1)\n this.ctx[name] = value\n }\n}\n"]}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * lib-decl — 库级定位声明(`package.json` 的 `faijs.lib`)的契约与装配期校验。
3
+ *
4
+ * 两级声明(2026-10-14 内核取用面收敛 §3.3)是**两个不同维度**,不是粗细两层:
5
+ *
6
+ * - **库级 = 定位属性**:「这个库能不能在某个内核上成立」。判据不是它的函数调了
7
+ * 哪些方法,而是它的语义基准(`conformsTo`)依赖什么——`faijs-freecad` 的几何
8
+ * 结果必须与 FreeCAD 一致,而 FreeCAD 的几何由 occt 定义,所以它只能跑 occt。
9
+ * 这条约束**任何 `fn.engines` 都写不出来**。
10
+ * - **函数级 = 实现事实**(`fn.engines`):「这个函数的实现调了哪个内核的东西」。
11
+ *
12
+ * 有效引擎的判定链:`fn.engines ?? lib.platform ?? 中立`(缺省 = 中立 = 今日行为)。
13
+ * 该链在**装配期一次解析完**(`admit-compat-lib.ts`),所以分派侧
14
+ * (`backend-dispatch.ts`)只读 op 元数据,不需要认识库级声明。
15
+ *
16
+ * 装配期校验两条:
17
+ * 1. `platform` 的取值必须是合法引擎 id(`BREP_ENGINE_IDS`);
18
+ * 2. **单向** peer 约束:`platform` 含 `occt` ⟹ 该库必须有 `occt-wasm` 的
19
+ * `peerDependencies`。反向不成立——`faijs-fasteners` 有 `occt-wasm` peer,库级
20
+ * `platform` 却是中立的(只有两条支路用到 occt)。所以 peer **不能**反推 `platform`。
21
+ */
22
+ import { type BrepEngineId } from '../brep/engine/types.js';
23
+ /** 库在系统中的角色(§3.3 第 1 项)。缺省按最严处理:`library`。 */
24
+ export declare const LIB_ROLES: readonly ["library", "host", "declaration", "adapter"];
25
+ /** 见 {@link LIB_ROLES}。 */
26
+ export type LibRole = (typeof LIB_ROLES)[number];
27
+ /**
28
+ * 库级定位声明(库自身 `package.json` 的 `faijs.lib` 字段)。
29
+ */
30
+ export interface LibDecl {
31
+ /** 库在系统中的角色;缺省 `'library'`(门禁取最严策略)。 */
32
+ role?: LibRole;
33
+ /** **语义基准**:本库的几何语义以谁为准(`'faijs'` / `'cadquery'` / `'freecad'` / `'openscad'` / …)。 */
34
+ conformsTo?: string;
35
+ /** 由基准推导出的引擎约束(显式写出,供门禁静态读);`[]` = 中立。 */
36
+ platform?: readonly BrepEngineId[];
37
+ }
38
+ /**
39
+ * 一个库的装配元数据(`package.json` 的 `faijs` 字段 + 其 peer 声明)。
40
+ *
41
+ * 这是 **`package.json` 的原始投影**,不是校验后的形态:`lib` 故意留成 `unknown`
42
+ * (来源是不可信的磁盘 / 网络 JSON),由装配期 `assertLibDecl` 校验后才成为
43
+ * {@link LibDecl}。`LibLoader.libMetaFor` / `registerLib({ lib })` 都用这个形状。
44
+ *
45
+ * `peers` 只用于装配期单向校验(§3.3 第 1 项),不参与运行期判定。
46
+ */
47
+ export interface LibMeta {
48
+ /** 逐库 autoLift 覆盖(D3-autoLift,既有字段)。 */
49
+ autoLift?: boolean;
50
+ /** `package.json` 的 `faijs.lib` 原始值(未校验)。 */
51
+ lib?: unknown;
52
+ /**
53
+ * 库自身 `peerDependencies`(键 = 包名,值 = range)。
54
+ *
55
+ * `undefined` 与 `{}` **语义不同**:`undefined` = 该来源没提供 peer 事实(跳过单向
56
+ * 校验);`{}` = 查过了、确实没有 peer(照常校验,`platform` 含 occt 即被拒)。
57
+ * 读盘来源(CLI / 浏览器 meta / `lib-meta.json`)一律给 `{}`,所以磁盘上的缺位会被
58
+ * 判红而不是被放过。
59
+ */
60
+ peers?: Readonly<Record<string, string>>;
61
+ }
62
+ /**
63
+ * 校验并归一化库级声明。缺失 = 未声明(返回 `undefined`,按中立处理)。
64
+ *
65
+ * @param lib - 库 `package.json` 的 `faijs.lib`,或 host 手动注册时给的等价对象。
66
+ * @param peers - 库 `peerDependencies`。`undefined` = 事实未提供(跳过 peer 单向校验);
67
+ * `{}` = 确实没有 peer(照常校验)。读盘来源一律给 `{}`,见 {@link LibMeta.peers}。
68
+ * @param where - 报错定位串(库名 / binding),仅用于消息。
69
+ * @returns 归一化后的声明,或 `undefined`(未声明)。
70
+ * @throws 声明形态非法 / 引擎 id 非法 / `platform` 含 occt 而无 `occt-wasm` peer。
71
+ */
72
+ export declare function assertLibDecl(lib: unknown, peers?: Readonly<Record<string, string>>, where?: string): LibDecl | undefined;
73
+ /**
74
+ * 有效引擎判定链:`fn.engines ?? lib.platform ?? 中立`(§3.3 第 2 项)。
75
+ *
76
+ * @param fnEngines - 函数自身的 `fn.engines` 声明(可选)。
77
+ * @param libPlatform - 库级 `platform` 声明(可选)。
78
+ * @returns 有效引擎集合;`undefined` = 中立(所有引擎)。
79
+ */
80
+ export declare function resolveFunctionEngines(fnEngines: readonly BrepEngineId[] | undefined, libPlatform: readonly BrepEngineId[] | undefined): readonly BrepEngineId[] | undefined;
81
+ /** {@link CadRuntime.describeLib} 的逐函数视图。 */
82
+ export interface LibFunctionView {
83
+ /** 脚本面函数名。 */
84
+ name: string;
85
+ /** 有效引擎(已解析 `fn.engines ?? lib.platform`);`undefined` = 中立。 */
86
+ engines?: readonly BrepEngineId[];
87
+ /** 产物名清单(`fn.outputs`)。 */
88
+ outputs?: string[];
89
+ }
90
+ /** {@link CadRuntime.describeLib} 的返回值:一个库的定位 + 逐函数清单。 */
91
+ export interface LibDescription {
92
+ /** 注册时使用的 binding 名(语句面 `binding.fn(...)`)。 */
93
+ binding: string;
94
+ /** 库的 npm 包名(注册时声明;缺省 undefined)。 */
95
+ packageName?: string;
96
+ /** 库级角色(未声明 = `library`)。 */
97
+ role: LibRole;
98
+ /** 语义基准(未声明 = undefined)。 */
99
+ conformsTo?: string;
100
+ /** 库级引擎约束(未声明 = 中立)。 */
101
+ platform: readonly BrepEngineId[];
102
+ /** 逐函数视图。 */
103
+ functions: LibFunctionView[];
104
+ }
105
+ /** {@link CadRuntime.libsUnder} 的可调用项。 */
106
+ export interface LibCallableView {
107
+ binding: string;
108
+ name: string;
109
+ }
110
+ /** {@link CadRuntime.libsUnder} 的静态拒绝项。 */
111
+ export interface LibRejectedView extends LibCallableView {
112
+ /** 拒绝原因(含声明的引擎集合,用于人工排查)。 */
113
+ reason: string;
114
+ }
115
+ /** {@link CadRuntime.libsUnder} 的返回值:给定引擎下的可调用 / 静态拒绝两分。 */
116
+ export interface LibsUnderEngine {
117
+ engineId: string;
118
+ callable: LibCallableView[];
119
+ rejected: LibRejectedView[];
120
+ }
121
+ //# sourceMappingURL=lib-decl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lib-decl.d.ts","sourceRoot":"","sources":["../../src/cad-runtime/lib-decl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAEzE,8CAA8C;AAC9C,eAAO,MAAM,SAAS,wDAAyD,CAAA;AAE/E,2BAA2B;AAC3B,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAA;AAEhD;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,wCAAwC;IACxC,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,uFAAuF;IACvF,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,SAAS,YAAY,EAAE,CAAA;CACnC;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,OAAO;IACtB,wCAAwC;IACxC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,6CAA6C;IAC7C,GAAG,CAAC,EAAE,OAAO,CAAA;IACb;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CACzC;AAID;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,OAAO,EACZ,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EACxC,KAAK,SAAc,GAClB,OAAO,GAAG,SAAS,CA8DrB;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,EAC9C,WAAW,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,GAC/C,SAAS,YAAY,EAAE,GAAG,SAAS,CAIrC;AAED,6CAA6C;AAC7C,MAAM,WAAW,eAAe;IAC9B,cAAc;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,+DAA+D;IAC/D,OAAO,CAAC,EAAE,SAAS,YAAY,EAAE,CAAA;IACjC,2BAA2B;IAC3B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,0DAA0D;AAC1D,MAAM,WAAW,cAAc;IAC7B,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAA;IACf,qCAAqC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,6BAA6B;IAC7B,IAAI,EAAE,OAAO,CAAA;IACb,6BAA6B;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,wBAAwB;IACxB,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAA;IACjC,aAAa;IACb,SAAS,EAAE,eAAe,EAAE,CAAA;CAC7B;AAED,0CAA0C;AAC1C,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;CACb;AAED,2CAA2C;AAC3C,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAA;CACf;AAED,4DAA4D;AAC5D,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,eAAe,EAAE,CAAA;IAC3B,QAAQ,EAAE,eAAe,EAAE,CAAA;CAC5B"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * lib-decl — 库级定位声明(`package.json` 的 `faijs.lib`)的契约与装配期校验。
3
+ *
4
+ * 两级声明(2026-10-14 内核取用面收敛 §3.3)是**两个不同维度**,不是粗细两层:
5
+ *
6
+ * - **库级 = 定位属性**:「这个库能不能在某个内核上成立」。判据不是它的函数调了
7
+ * 哪些方法,而是它的语义基准(`conformsTo`)依赖什么——`faijs-freecad` 的几何
8
+ * 结果必须与 FreeCAD 一致,而 FreeCAD 的几何由 occt 定义,所以它只能跑 occt。
9
+ * 这条约束**任何 `fn.engines` 都写不出来**。
10
+ * - **函数级 = 实现事实**(`fn.engines`):「这个函数的实现调了哪个内核的东西」。
11
+ *
12
+ * 有效引擎的判定链:`fn.engines ?? lib.platform ?? 中立`(缺省 = 中立 = 今日行为)。
13
+ * 该链在**装配期一次解析完**(`admit-compat-lib.ts`),所以分派侧
14
+ * (`backend-dispatch.ts`)只读 op 元数据,不需要认识库级声明。
15
+ *
16
+ * 装配期校验两条:
17
+ * 1. `platform` 的取值必须是合法引擎 id(`BREP_ENGINE_IDS`);
18
+ * 2. **单向** peer 约束:`platform` 含 `occt` ⟹ 该库必须有 `occt-wasm` 的
19
+ * `peerDependencies`。反向不成立——`faijs-fasteners` 有 `occt-wasm` peer,库级
20
+ * `platform` 却是中立的(只有两条支路用到 occt)。所以 peer **不能**反推 `platform`。
21
+ */
22
+ import { BREP_ENGINE_IDS } from '../brep/engine/types.js';
23
+ /** 库在系统中的角色(§3.3 第 1 项)。缺省按最严处理:`library`。 */
24
+ export const LIB_ROLES = ['library', 'host', 'declaration', 'adapter'];
25
+ const DECL_KEYS = new Set(['role', 'conformsTo', 'platform']);
26
+ /**
27
+ * 校验并归一化库级声明。缺失 = 未声明(返回 `undefined`,按中立处理)。
28
+ *
29
+ * @param lib - 库 `package.json` 的 `faijs.lib`,或 host 手动注册时给的等价对象。
30
+ * @param peers - 库 `peerDependencies`。`undefined` = 事实未提供(跳过 peer 单向校验);
31
+ * `{}` = 确实没有 peer(照常校验)。读盘来源一律给 `{}`,见 {@link LibMeta.peers}。
32
+ * @param where - 报错定位串(库名 / binding),仅用于消息。
33
+ * @returns 归一化后的声明,或 `undefined`(未声明)。
34
+ * @throws 声明形态非法 / 引擎 id 非法 / `platform` 含 occt 而无 `occt-wasm` peer。
35
+ */
36
+ export function assertLibDecl(lib, peers, where = '<unknown>') {
37
+ if (lib === undefined || lib === null)
38
+ return undefined;
39
+ if (typeof lib !== 'object' || Array.isArray(lib)) {
40
+ throw new Error(`[faijs] lib '${where}': faijs.lib must be an object, got ${Array.isArray(lib) ? 'array' : typeof lib}`);
41
+ }
42
+ const raw = lib;
43
+ for (const key of Object.keys(raw)) {
44
+ if (!DECL_KEYS.has(key)) {
45
+ throw new Error(`[faijs] lib '${where}': unknown faijs.lib field '${key}' (expected one of ${[...DECL_KEYS].join('/')})`);
46
+ }
47
+ }
48
+ const out = {};
49
+ if (raw.role !== undefined) {
50
+ if (typeof raw.role !== 'string' || !LIB_ROLES.includes(raw.role)) {
51
+ throw new Error(`[faijs] lib '${where}': faijs.lib.role must be one of ${LIB_ROLES.join('/')}, got ${JSON.stringify(raw.role)}`);
52
+ }
53
+ out.role = raw.role;
54
+ }
55
+ if (raw.conformsTo !== undefined) {
56
+ if (typeof raw.conformsTo !== 'string' || raw.conformsTo.trim() === '') {
57
+ throw new Error(`[faijs] lib '${where}': faijs.lib.conformsTo must be a non-empty string`);
58
+ }
59
+ out.conformsTo = raw.conformsTo;
60
+ }
61
+ if (raw.platform !== undefined) {
62
+ if (!Array.isArray(raw.platform)) {
63
+ throw new Error(`[faijs] lib '${where}': faijs.lib.platform must be an array of engine ids`);
64
+ }
65
+ const seen = new Set();
66
+ for (const id of raw.platform) {
67
+ if (typeof id !== 'string' || !BREP_ENGINE_IDS.includes(id)) {
68
+ throw new Error(`[faijs] lib '${where}': faijs.lib.platform contains unknown engine id ${JSON.stringify(id)} ` +
69
+ `(expected one of ${BREP_ENGINE_IDS.join('/')})`);
70
+ }
71
+ if (seen.has(id)) {
72
+ throw new Error(`[faijs] lib '${where}': faijs.lib.platform has duplicate engine id '${id}'`);
73
+ }
74
+ seen.add(id);
75
+ }
76
+ out.platform = raw.platform;
77
+ }
78
+ // 单向 peer 约束(§3.3 第 1 项):platform 含 occt ⟹ 库必须有 occt-wasm peer。
79
+ // 反向不成立(fasteners 是活反例),所以 peer 不能用来反推 platform。
80
+ if (out.platform?.includes('occt') && peers !== undefined && peers['occt-wasm'] === undefined) {
81
+ throw new Error(`[faijs] lib '${where}': faijs.lib.platform declares 'occt' but the package has no ` +
82
+ `'occt-wasm' peerDependency — a library that needs the OCCT platform must declare that dependency`);
83
+ }
84
+ return out;
85
+ }
86
+ /**
87
+ * 有效引擎判定链:`fn.engines ?? lib.platform ?? 中立`(§3.3 第 2 项)。
88
+ *
89
+ * @param fnEngines - 函数自身的 `fn.engines` 声明(可选)。
90
+ * @param libPlatform - 库级 `platform` 声明(可选)。
91
+ * @returns 有效引擎集合;`undefined` = 中立(所有引擎)。
92
+ */
93
+ export function resolveFunctionEngines(fnEngines, libPlatform) {
94
+ if (fnEngines !== undefined && fnEngines.length > 0)
95
+ return fnEngines;
96
+ if (libPlatform !== undefined && libPlatform.length > 0)
97
+ return libPlatform;
98
+ return undefined;
99
+ }
100
+ //# sourceMappingURL=lib-decl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lib-decl.js","sourceRoot":"","sources":["../../src/cad-runtime/lib-decl.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * lib-decl — 库级定位声明(`package.json` 的 `faijs.lib`)的契约与装配期校验。\n *\n * 两级声明(2026-10-14 内核取用面收敛 §3.3)是**两个不同维度**,不是粗细两层:\n *\n * - **库级 = 定位属性**:「这个库能不能在某个内核上成立」。判据不是它的函数调了\n * 哪些方法,而是它的语义基准(`conformsTo`)依赖什么——`faijs-freecad` 的几何\n * 结果必须与 FreeCAD 一致,而 FreeCAD 的几何由 occt 定义,所以它只能跑 occt。\n * 这条约束**任何 `fn.engines` 都写不出来**。\n * - **函数级 = 实现事实**(`fn.engines`):「这个函数的实现调了哪个内核的东西」。\n *\n * 有效引擎的判定链:`fn.engines ?? lib.platform ?? 中立`(缺省 = 中立 = 今日行为)。\n * 该链在**装配期一次解析完**(`admit-compat-lib.ts`),所以分派侧\n * (`backend-dispatch.ts`)只读 op 元数据,不需要认识库级声明。\n *\n * 装配期校验两条:\n * 1. `platform` 的取值必须是合法引擎 id(`BREP_ENGINE_IDS`);\n * 2. **单向** peer 约束:`platform` 含 `occt` ⟹ 该库必须有 `occt-wasm` 的\n * `peerDependencies`。反向不成立——`faijs-fasteners` 有 `occt-wasm` peer,库级\n * `platform` 却是中立的(只有两条支路用到 occt)。所以 peer **不能**反推 `platform`。\n */\n\nimport { BREP_ENGINE_IDS, type BrepEngineId } from '../brep/engine/types'\n\n/** 库在系统中的角色(§3.3 第 1 项)。缺省按最严处理:`library`。 */\nexport const LIB_ROLES = ['library', 'host', 'declaration', 'adapter'] as const\n\n/** 见 {@link LIB_ROLES}。 */\nexport type LibRole = (typeof LIB_ROLES)[number]\n\n/**\n * 库级定位声明(库自身 `package.json` 的 `faijs.lib` 字段)。\n */\nexport interface LibDecl {\n /** 库在系统中的角色;缺省 `'library'`(门禁取最严策略)。 */\n role?: LibRole\n /** **语义基准**:本库的几何语义以谁为准(`'faijs'` / `'cadquery'` / `'freecad'` / `'openscad'` / …)。 */\n conformsTo?: string\n /** 由基准推导出的引擎约束(显式写出,供门禁静态读);`[]` = 中立。 */\n platform?: readonly BrepEngineId[]\n}\n\n/**\n * 一个库的装配元数据(`package.json` 的 `faijs` 字段 + 其 peer 声明)。\n *\n * 这是 **`package.json` 的原始投影**,不是校验后的形态:`lib` 故意留成 `unknown`\n * (来源是不可信的磁盘 / 网络 JSON),由装配期 `assertLibDecl` 校验后才成为\n * {@link LibDecl}。`LibLoader.libMetaFor` / `registerLib({ lib })` 都用这个形状。\n *\n * `peers` 只用于装配期单向校验(§3.3 第 1 项),不参与运行期判定。\n */\nexport interface LibMeta {\n /** 逐库 autoLift 覆盖(D3-autoLift,既有字段)。 */\n autoLift?: boolean\n /** `package.json` 的 `faijs.lib` 原始值(未校验)。 */\n lib?: unknown\n /**\n * 库自身 `peerDependencies`(键 = 包名,值 = range)。\n *\n * `undefined` 与 `{}` **语义不同**:`undefined` = 该来源没提供 peer 事实(跳过单向\n * 校验);`{}` = 查过了、确实没有 peer(照常校验,`platform` 含 occt 即被拒)。\n * 读盘来源(CLI / 浏览器 meta / `lib-meta.json`)一律给 `{}`,所以磁盘上的缺位会被\n * 判红而不是被放过。\n */\n peers?: Readonly<Record<string, string>>\n}\n\nconst DECL_KEYS = new Set(['role', 'conformsTo', 'platform'])\n\n/**\n * 校验并归一化库级声明。缺失 = 未声明(返回 `undefined`,按中立处理)。\n *\n * @param lib - 库 `package.json` 的 `faijs.lib`,或 host 手动注册时给的等价对象。\n * @param peers - 库 `peerDependencies`。`undefined` = 事实未提供(跳过 peer 单向校验);\n * `{}` = 确实没有 peer(照常校验)。读盘来源一律给 `{}`,见 {@link LibMeta.peers}。\n * @param where - 报错定位串(库名 / binding),仅用于消息。\n * @returns 归一化后的声明,或 `undefined`(未声明)。\n * @throws 声明形态非法 / 引擎 id 非法 / `platform` 含 occt 而无 `occt-wasm` peer。\n */\nexport function assertLibDecl(\n lib: unknown,\n peers?: Readonly<Record<string, string>>,\n where = '<unknown>',\n): LibDecl | undefined {\n if (lib === undefined || lib === null) return undefined\n if (typeof lib !== 'object' || Array.isArray(lib)) {\n throw new Error(`[faijs] lib '${where}': faijs.lib must be an object, got ${Array.isArray(lib) ? 'array' : typeof lib}`)\n }\n const raw = lib as Record<string, unknown>\n for (const key of Object.keys(raw)) {\n if (!DECL_KEYS.has(key)) {\n throw new Error(\n `[faijs] lib '${where}': unknown faijs.lib field '${key}' (expected one of ${[...DECL_KEYS].join('/')})`,\n )\n }\n }\n\n const out: LibDecl = {}\n\n if (raw.role !== undefined) {\n if (typeof raw.role !== 'string' || !(LIB_ROLES as readonly string[]).includes(raw.role)) {\n throw new Error(\n `[faijs] lib '${where}': faijs.lib.role must be one of ${LIB_ROLES.join('/')}, got ${JSON.stringify(raw.role)}`,\n )\n }\n out.role = raw.role as LibRole\n }\n\n if (raw.conformsTo !== undefined) {\n if (typeof raw.conformsTo !== 'string' || raw.conformsTo.trim() === '') {\n throw new Error(`[faijs] lib '${where}': faijs.lib.conformsTo must be a non-empty string`)\n }\n out.conformsTo = raw.conformsTo\n }\n\n if (raw.platform !== undefined) {\n if (!Array.isArray(raw.platform)) {\n throw new Error(`[faijs] lib '${where}': faijs.lib.platform must be an array of engine ids`)\n }\n const seen = new Set<string>()\n for (const id of raw.platform) {\n if (typeof id !== 'string' || !(BREP_ENGINE_IDS as readonly string[]).includes(id)) {\n throw new Error(\n `[faijs] lib '${where}': faijs.lib.platform contains unknown engine id ${JSON.stringify(id)} ` +\n `(expected one of ${BREP_ENGINE_IDS.join('/')})`,\n )\n }\n if (seen.has(id)) {\n throw new Error(`[faijs] lib '${where}': faijs.lib.platform has duplicate engine id '${id}'`)\n }\n seen.add(id)\n }\n out.platform = raw.platform as readonly BrepEngineId[]\n }\n\n // 单向 peer 约束(§3.3 第 1 项):platform 含 occt ⟹ 库必须有 occt-wasm peer。\n // 反向不成立(fasteners 是活反例),所以 peer 不能用来反推 platform。\n if (out.platform?.includes('occt') && peers !== undefined && peers['occt-wasm'] === undefined) {\n throw new Error(\n `[faijs] lib '${where}': faijs.lib.platform declares 'occt' but the package has no ` +\n `'occt-wasm' peerDependency — a library that needs the OCCT platform must declare that dependency`,\n )\n }\n\n return out\n}\n\n/**\n * 有效引擎判定链:`fn.engines ?? lib.platform ?? 中立`(§3.3 第 2 项)。\n *\n * @param fnEngines - 函数自身的 `fn.engines` 声明(可选)。\n * @param libPlatform - 库级 `platform` 声明(可选)。\n * @returns 有效引擎集合;`undefined` = 中立(所有引擎)。\n */\nexport function resolveFunctionEngines(\n fnEngines: readonly BrepEngineId[] | undefined,\n libPlatform: readonly BrepEngineId[] | undefined,\n): readonly BrepEngineId[] | undefined {\n if (fnEngines !== undefined && fnEngines.length > 0) return fnEngines\n if (libPlatform !== undefined && libPlatform.length > 0) return libPlatform\n return undefined\n}\n\n/** {@link CadRuntime.describeLib} 的逐函数视图。 */\nexport interface LibFunctionView {\n /** 脚本面函数名。 */\n name: string\n /** 有效引擎(已解析 `fn.engines ?? lib.platform`);`undefined` = 中立。 */\n engines?: readonly BrepEngineId[]\n /** 产物名清单(`fn.outputs`)。 */\n outputs?: string[]\n}\n\n/** {@link CadRuntime.describeLib} 的返回值:一个库的定位 + 逐函数清单。 */\nexport interface LibDescription {\n /** 注册时使用的 binding 名(语句面 `binding.fn(...)`)。 */\n binding: string\n /** 库的 npm 包名(注册时声明;缺省 undefined)。 */\n packageName?: string\n /** 库级角色(未声明 = `library`)。 */\n role: LibRole\n /** 语义基准(未声明 = undefined)。 */\n conformsTo?: string\n /** 库级引擎约束(未声明 = 中立)。 */\n platform: readonly BrepEngineId[]\n /** 逐函数视图。 */\n functions: LibFunctionView[]\n}\n\n/** {@link CadRuntime.libsUnder} 的可调用项。 */\nexport interface LibCallableView {\n binding: string\n name: string\n}\n\n/** {@link CadRuntime.libsUnder} 的静态拒绝项。 */\nexport interface LibRejectedView extends LibCallableView {\n /** 拒绝原因(含声明的引擎集合,用于人工排查)。 */\n reason: string\n}\n\n/** {@link CadRuntime.libsUnder} 的返回值:给定引擎下的可调用 / 静态拒绝两分。 */\nexport interface LibsUnderEngine {\n engineId: string\n callable: LibCallableView[]\n rejected: LibRejectedView[]\n}\n"]}
@@ -11,6 +11,7 @@
11
11
  */
12
12
  import type { PartName } from '../identity.js';
13
13
  import type { LibNamespace } from '../runtime-state.js';
14
+ import type { LibMeta } from './lib-decl.js';
14
15
  /** 网格数据(与 csg.ts ManifoldMeshData 同构) */
15
16
  export interface MeshData {
16
17
  positions: Float32Array;
@@ -157,6 +158,17 @@ export interface LibLoader {
157
158
  */
158
159
  autoLiftFor?: (packageName: string) => boolean | undefined;
159
160
  };
161
+ /**
162
+ * 按 packageName 取库自身的**装配元数据**(`package.json` 的 `faijs.lib` 定位声明
163
+ * + `peerDependencies`)。逐库自动装载时由 runtime 读一次,喂给
164
+ * `registerLib({ lib, peers })` 的装配期校验(§3.3 第 1 项)。
165
+ *
166
+ * 与 `options.autoLiftFor` 同源(都出自库的 `package.json`),但**必须同步**——
167
+ * `autoLoadLibsFromImports` 在装载后立即调用,没有 await 的余地。
168
+ *
169
+ * 缺省 / 返回 `undefined` = 该来源不提供库声明事实 → 按中立处理(今日行为)。
170
+ */
171
+ libMetaFor?(packageName: string): LibMeta | undefined;
160
172
  /**
161
173
  * 可选源码扫描钩子(§6.2 ②):宿主返回库源码时走同一 SecurityScanner(A4,固定 strict);
162
174
  * 不提供或返回 undefined 则跳过。不改 loadLib 返回值——返回 LibNamespace,
@@ -1 +1 @@
1
- {"version":3,"file":"ports.d.ts","sourceRoot":"","sources":["../../src/cad-runtime/ports.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ports.d.ts","sourceRoot":"","sources":["../../src/cad-runtime/ports.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ports.js","sourceRoot":"","sources":["../../src/cad-runtime/ports.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG","sourcesContent":["/**\n * Ports 接口定义 — Host 注入的环境能力\n *\n *\n * L2 CadRuntime 通过这些接口获取所有环境能力(CSG 计算、SDF 求值、字体、纹理、资产、事件)。\n * 不直接 import 任何 ?worker、window、document、zustand store——这些由 Host 实现。\n *\n * 两个宿主各自实现:\n * - browser host: WorkerCsgBackend / WorkerSdfBackend / BrowserFontProvider / ...\n * - node host (P3): InlineCsgBackend / InlineSdfBackend / NodeFontProvider / ...\n */\n\nimport type { PartName } from '../identity'\nimport type { LibNamespace } from '../runtime-state'\n\n// ── 共享类型 ──\n\n/** 网格数据(与 csg.ts ManifoldMeshData 同构) */\nexport interface MeshData {\n positions: Float32Array\n indices: Uint32Array\n}\n\n/** 平面参数 */\nexport interface PlaneParams {\n normal: [number, number, number]\n offset: number\n}\n\n// Re-export joinery param types from boolean/geo-convert to ensure\n// structural identity across CsgBackend interface and implementations.\nexport type {\n DovetailGrooveParams,\n DowelSplitParams,\n StraightTenonSplitParams,\n} from '../boolean/geo-convert'\nimport type {\n DovetailGrooveParams,\n DowelSplitParams,\n StraightTenonSplitParams,\n} from '../boolean/geo-convert'\n\n/** 分割结果 */\nexport interface SplitResult {\n front: MeshData\n back: MeshData\n wedge: MeshData | null\n}\n\n// ── CsgBackend ──\n\n/**\n * CSG 后端接口 — mesh 路径的布尔/分割操作。\n *\n * browser 实现:WorkerCsgBackend(经 csg-worker postMessage)\n * node 实现 (P3):InlineCsgBackend(主线程直跑 manifold-3d)\n */\nexport interface CsgBackend {\n boolean(op: 'union' | 'subtract' | 'intersect', meshes: MeshData[]): Promise<MeshData>\n splitPlane(mesh: MeshData, plane: PlaneParams): Promise<{ front: MeshData; back: MeshData }>\n splitDovetail(\n mesh: MeshData,\n params: {\n planeNormal: [number, number, number]\n planeDistance: number\n planeCenter: [number, number, number]\n widthDir: [number, number, number]\n bboxWidthOnWidthDir: number\n groove: DovetailGrooveParams\n },\n ): Promise<SplitResult>\n splitDowel(\n mesh: MeshData,\n params: {\n planeNormal: [number, number, number]\n planeDistance: number\n planeCenter: [number, number, number]\n widthDir: [number, number, number]\n dowel: DowelSplitParams\n selectedSections?: number[] | null\n },\n ): Promise<SplitResult>\n splitStraightTenon(\n mesh: MeshData,\n params: {\n planeNormal: [number, number, number]\n planeDistance: number\n planeCenter: [number, number, number]\n widthDir: [number, number, number]\n tenon: StraightTenonSplitParams\n selectedSections?: number[] | null\n },\n ): Promise<SplitResult>\n}\n\n// ── SdfBackend ──\n\n/**\n * SDF 后端接口 — SDF 求值。\n *\n * browser 实现:WorkerSdfBackend(经 sdf-worker postMessage)\n * node 实现 (P3):InlineSdfBackend(主线程直跑)\n */\nexport interface SdfBackend {\n runSdf(\n code: string,\n params: Record<string, number>,\n bounds: [number, number, number, number, number, number],\n edgeLength: number,\n level?: number,\n tolerance?: number,\n ): Promise<MeshData>\n}\n\n// ── FontProvider ──\n\n/**\n * 字体提供者接口。\n *\n * browser 实现:BrowserFontProvider(?url + fetch + fontRegistry DI)\n * node 实现 (P3):NodeFontProvider(fs 字体加载)\n */\nexport interface FontProvider {\n /** 加载字体字节(按 key/path),返回 ArrayBuffer */\n loadFont(key: string): Promise<ArrayBuffer>\n /** 列出可用字体 key(node 端为资产目录,browser 端为注册表) */\n listFonts(): string[]\n}\n\n// ── TextureSampler ──\n\n/**\n * 纹理采样接口 — knurl 纹理。\n *\n * browser 实现:CanvasTextureSampler(Image + canvas)\n * node 实现 (P3):纯数据解码\n */\nexport interface TextureSampler {\n /** 采样纹理在 (u, v) 处的值 [0,1] */\n sample(u: number, v: number): number\n /** 纹理尺寸 */\n readonly width: number\n readonly height: number\n}\n\n// ── AssetResolver ──\n\n/**\n * 资产解析接口 — load* 操作的字节来源。\n *\n * browser 实现:FaicadAssetResolver(faicad 会话缓存)\n * node 实现 (P3):FsAssetResolver(--assets 目录/manifest)\n */\nexport interface AssetResolver {\n /** loadByKey 的 headless 等价物 */\n resolveByKey(key: string): Promise<{ bytes: ArrayBuffer; format?: string }>\n /** 本地文件路径(browser 下抛错) */\n resolveFile(path: string): Promise<ArrayBuffer>\n /** 网络 URL(两环境通用) */\n resolveUrl(url: string): Promise<ArrayBuffer>\n}\n\n// ── EventSink ──\n\n/**\n * 事件通知接口 — BREP 丢失等事件。\n *\n * browser 实现:BrowserEventSink(window.dispatchEvent → toast)\n * node 实现 (P3):CliEventSink(写入 stderr + 收集到 events 数组)\n */\nexport interface EventSink {\n emit(event: 'part-brep-lost', detail: { partName: PartName; callee: string; reason: string }): void\n}\n\n// ── LibLoader ──\n\n/**\n * 库加载器接口 — 按 packageName 自动装载未注册的第三方库。\n *\n * 宿主实现:\n * - node CLI(createNodePorts):白名单 + Node 原生 `import(name)`(monorepo\n * workspace symlink 直接把裸包解析到包源码)。\n * - browser / demo:静态 `LIB_MODULES` 映射表(value 必须是静态字面量\n * specifier,Vite/Rollup 才能静态分析打包;禁止变量传参的 import(name))。\n * - vitest:复用浏览器映射表写法 + `await import('@faicad/…')`(alias 落位活源码)。\n */\nexport interface LibLoader {\n /** 按 packageName 加载库模块,返回其导出命名空间对象(与 registerLib 的 ns 同形)。 */\n loadLib(packageName: string): Promise<LibNamespace>\n /** 列出当前可加载的 packageName(check 阶段同步校验 import specifier 用)。 */\n listLibs(): string[]\n /** 自动装载的注册选项;缺省由推断式决定(有 dual-op 的库不提升,全裸函数库自动提升,与手动注入一致)。 */\n options?: {\n autoLift?: boolean\n /**\n * 按 packageName 的逐库 `autoLift` 覆盖(优先于 `options.autoLift`)。\n * 返回 `undefined` 时回落到全局选项 / 推断式。用于别名库:如 cq-compat 在\n * 浏览器 host 被全局 autoLift 提升后,compat 边界会改变实参形态,破坏其\n * 内部「以 Shape 受众」的借面逻辑(原 CLI 即按 autoLift=false 运行)。\n * 逐库关掉提升恢复 CLI 等价行为。\n */\n autoLiftFor?: (packageName: string) => boolean | undefined\n }\n /**\n * 可选源码扫描钩子(§6.2 ②):宿主返回库源码时走同一 SecurityScanner(A4,固定 strict);\n * 不提供或返回 undefined 则跳过。不改 loadLib 返回值——返回 LibNamespace,\n * 往里挂 source 会被 admitCompatLib 当成导出值并污染命名空间。\n * @param packageName - the npm package name.\n * @returns the library source text if available, otherwise undefined.\n */\n loadSource?(packageName: string): Promise<string | undefined>\n}\n\n// ── ProjectLoader ──\n\n/**\n * 项目文件加载器(多文件,§4.5)——按 moduleKey 读取/枚举项目内 .fai.js 模块源码。\n *\n * moduleKey 约定:host 决定字符串形态(项目根相对路径等);引擎只做最小归一\n * (POSIX 斜杠、去掉 `./`/`../`/前导 `/` 前缀),随后按 `listModules()` 精确匹配。\n *\n * host 实现:\n * - 3d_editor / browser:项目文件表 + session 内缓存;\n * - node / vitest:内存映射表或 fs 读取(fixture 目录)。\n */\nexport interface ProjectLoader {\n /** 列出当前可加载的 moduleKey(装载前预检 / 错误提示用)。 */\n listModules(): string[]\n /** 按 moduleKey 读取模块源码(.fai.js 文本)。 */\n readSource(moduleKey: string): Promise<string>\n /** 模块内容指纹(增量缓存用;不提供则每次全量重读重执行)。 */\n fingerprint?(moduleKey: string): Promise<string>\n}\n\n// ── 宿主环境 ──\n\n/**\n * 宿主环境——脚本面导出命令的可用性判据。\n *\n * - `'node'`:Node.js 进程(CLI、进程内嵌)。落盘发生在用户自己的机器上,\n * 不构成跨域外泄,因此开放;\n * - `'browser'`:web 页面 / web worker。页面内脚本发起下载正是 CSP、\n * 用户手势要求与 drive-by download 防护所针对的模式;\n * - `'weapp'`:小程序 worker。落盘同样属于宿主能力的范畴。\n *\n * 只有 `'node'` 宿主开放脚本面导出命令(`cad.exportStl` / `cad.exportBrep`),\n * 其余值(含未声明)执行即报 `E_HOST_UNSUPPORTED`。理由:`.fai.js` 是可由 AI\n * 生成任意代码的文本、属不受信输入(`lang/security-scanner.ts` 的静态门禁自认\n * 不是沙箱),而导出把「往哪写、写几份、写什么」的决定权交给脚本文本。浏览器 /\n * 小程序里要导出模型,必须由宿主提供的入口触发——用户点的按钮,或宿主自己调用的\n * 库面字节通道(`exportModel(Sync)` / `exportStepFromSolids*` 等)。\n *\n * 宿主在端口装配期声明一次;运行期不探测环境(`typeof process` 那类判断只留在\n * 内核装载器里选 wasm 装载通道)。未声明按非 node 处理(fail-closed,不兜底)。\n */\nexport type HostEnv = 'node' | 'browser' | 'weapp'\n\n// ── HostPorts 汇总 ──\n\n/**\n * Host 在 createRuntime 时注入的全部环境能力。\n *\n * 所有字段可选——node 测试环境可只提供 occt kernel(不注入 csg/sdf),\n * BREP-path ops 不依赖这些 Port。\n */\nexport interface HostPorts {\n csg?: CsgBackend\n sdf?: SdfBackend\n fonts?: FontProvider\n texture?: TextureSampler\n assets?: AssetResolver\n events: EventSink // events 必填——断链通知是基础能力\n /**\n * 宿主环境(装配期声明一次;未声明 → 脚本面导出命令一律拒绝)。\n *\n * 保持可选而不设为必填:`HostPorts` 是公开类型,设必填会把与本次能力无关的\n * 机械改动压到仓内近百处只给 `events` 的装配点上;读取端 fail-closed(漏声明 =\n * 非 node)效果等价于必填。见 {@link HostEnv}。\n */\n hostEnv?: HostEnv\n /** 库加载器(execute 自动装载未注册库;check 用它做 specifier 预检)。可选——无则仅手工 registerLib。 */\n libLoader?: LibLoader\n /** 项目文件加载器(相对 specifier 的多文件模块,§4.5)。可选——不提供则单文件行为不变。 */\n projectLoader?: ProjectLoader\n}\n\n// ── 执行模式 ──\n\n/**\n * 执行模式(设计文档 §4.4)。\n *\n * - `auto`(默认):优先 BREP,断链后自动切 mesh + EventSink 通知\n * - `brep`:强制 BREP,断链即报错 E_BREP_UNSUPPORTED,不自动切换\n * - `mesh`:全部走 mesh 路径\n */\nexport type ExecutionMode = 'auto' | 'brep' | 'mesh'\n"]}
1
+ {"version":3,"file":"ports.js","sourceRoot":"","sources":["../../src/cad-runtime/ports.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG","sourcesContent":["/**\n * Ports 接口定义 — Host 注入的环境能力\n *\n *\n * L2 CadRuntime 通过这些接口获取所有环境能力(CSG 计算、SDF 求值、字体、纹理、资产、事件)。\n * 不直接 import 任何 ?worker、window、document、zustand store——这些由 Host 实现。\n *\n * 两个宿主各自实现:\n * - browser host: WorkerCsgBackend / WorkerSdfBackend / BrowserFontProvider / ...\n * - node host (P3): InlineCsgBackend / InlineSdfBackend / NodeFontProvider / ...\n */\n\nimport type { PartName } from '../identity'\nimport type { LibNamespace } from '../runtime-state'\nimport type { LibMeta } from './lib-decl'\n\n// ── 共享类型 ──\n\n/** 网格数据(与 csg.ts ManifoldMeshData 同构) */\nexport interface MeshData {\n positions: Float32Array\n indices: Uint32Array\n}\n\n/** 平面参数 */\nexport interface PlaneParams {\n normal: [number, number, number]\n offset: number\n}\n\n// Re-export joinery param types from boolean/geo-convert to ensure\n// structural identity across CsgBackend interface and implementations.\nexport type {\n DovetailGrooveParams,\n DowelSplitParams,\n StraightTenonSplitParams,\n} from '../boolean/geo-convert'\nimport type {\n DovetailGrooveParams,\n DowelSplitParams,\n StraightTenonSplitParams,\n} from '../boolean/geo-convert'\n\n/** 分割结果 */\nexport interface SplitResult {\n front: MeshData\n back: MeshData\n wedge: MeshData | null\n}\n\n// ── CsgBackend ──\n\n/**\n * CSG 后端接口 — mesh 路径的布尔/分割操作。\n *\n * browser 实现:WorkerCsgBackend(经 csg-worker postMessage)\n * node 实现 (P3):InlineCsgBackend(主线程直跑 manifold-3d)\n */\nexport interface CsgBackend {\n boolean(op: 'union' | 'subtract' | 'intersect', meshes: MeshData[]): Promise<MeshData>\n splitPlane(mesh: MeshData, plane: PlaneParams): Promise<{ front: MeshData; back: MeshData }>\n splitDovetail(\n mesh: MeshData,\n params: {\n planeNormal: [number, number, number]\n planeDistance: number\n planeCenter: [number, number, number]\n widthDir: [number, number, number]\n bboxWidthOnWidthDir: number\n groove: DovetailGrooveParams\n },\n ): Promise<SplitResult>\n splitDowel(\n mesh: MeshData,\n params: {\n planeNormal: [number, number, number]\n planeDistance: number\n planeCenter: [number, number, number]\n widthDir: [number, number, number]\n dowel: DowelSplitParams\n selectedSections?: number[] | null\n },\n ): Promise<SplitResult>\n splitStraightTenon(\n mesh: MeshData,\n params: {\n planeNormal: [number, number, number]\n planeDistance: number\n planeCenter: [number, number, number]\n widthDir: [number, number, number]\n tenon: StraightTenonSplitParams\n selectedSections?: number[] | null\n },\n ): Promise<SplitResult>\n}\n\n// ── SdfBackend ──\n\n/**\n * SDF 后端接口 — SDF 求值。\n *\n * browser 实现:WorkerSdfBackend(经 sdf-worker postMessage)\n * node 实现 (P3):InlineSdfBackend(主线程直跑)\n */\nexport interface SdfBackend {\n runSdf(\n code: string,\n params: Record<string, number>,\n bounds: [number, number, number, number, number, number],\n edgeLength: number,\n level?: number,\n tolerance?: number,\n ): Promise<MeshData>\n}\n\n// ── FontProvider ──\n\n/**\n * 字体提供者接口。\n *\n * browser 实现:BrowserFontProvider(?url + fetch + fontRegistry DI)\n * node 实现 (P3):NodeFontProvider(fs 字体加载)\n */\nexport interface FontProvider {\n /** 加载字体字节(按 key/path),返回 ArrayBuffer */\n loadFont(key: string): Promise<ArrayBuffer>\n /** 列出可用字体 key(node 端为资产目录,browser 端为注册表) */\n listFonts(): string[]\n}\n\n// ── TextureSampler ──\n\n/**\n * 纹理采样接口 — knurl 纹理。\n *\n * browser 实现:CanvasTextureSampler(Image + canvas)\n * node 实现 (P3):纯数据解码\n */\nexport interface TextureSampler {\n /** 采样纹理在 (u, v) 处的值 [0,1] */\n sample(u: number, v: number): number\n /** 纹理尺寸 */\n readonly width: number\n readonly height: number\n}\n\n// ── AssetResolver ──\n\n/**\n * 资产解析接口 — load* 操作的字节来源。\n *\n * browser 实现:FaicadAssetResolver(faicad 会话缓存)\n * node 实现 (P3):FsAssetResolver(--assets 目录/manifest)\n */\nexport interface AssetResolver {\n /** loadByKey 的 headless 等价物 */\n resolveByKey(key: string): Promise<{ bytes: ArrayBuffer; format?: string }>\n /** 本地文件路径(browser 下抛错) */\n resolveFile(path: string): Promise<ArrayBuffer>\n /** 网络 URL(两环境通用) */\n resolveUrl(url: string): Promise<ArrayBuffer>\n}\n\n// ── EventSink ──\n\n/**\n * 事件通知接口 — BREP 丢失等事件。\n *\n * browser 实现:BrowserEventSink(window.dispatchEvent → toast)\n * node 实现 (P3):CliEventSink(写入 stderr + 收集到 events 数组)\n */\nexport interface EventSink {\n emit(event: 'part-brep-lost', detail: { partName: PartName; callee: string; reason: string }): void\n}\n\n// ── LibLoader ──\n\n/**\n * 库加载器接口 — 按 packageName 自动装载未注册的第三方库。\n *\n * 宿主实现:\n * - node CLI(createNodePorts):白名单 + Node 原生 `import(name)`(monorepo\n * workspace symlink 直接把裸包解析到包源码)。\n * - browser / demo:静态 `LIB_MODULES` 映射表(value 必须是静态字面量\n * specifier,Vite/Rollup 才能静态分析打包;禁止变量传参的 import(name))。\n * - vitest:复用浏览器映射表写法 + `await import('@faicad/…')`(alias 落位活源码)。\n */\nexport interface LibLoader {\n /** 按 packageName 加载库模块,返回其导出命名空间对象(与 registerLib 的 ns 同形)。 */\n loadLib(packageName: string): Promise<LibNamespace>\n /** 列出当前可加载的 packageName(check 阶段同步校验 import specifier 用)。 */\n listLibs(): string[]\n /** 自动装载的注册选项;缺省由推断式决定(有 dual-op 的库不提升,全裸函数库自动提升,与手动注入一致)。 */\n options?: {\n autoLift?: boolean\n /**\n * 按 packageName 的逐库 `autoLift` 覆盖(优先于 `options.autoLift`)。\n * 返回 `undefined` 时回落到全局选项 / 推断式。用于别名库:如 cq-compat 在\n * 浏览器 host 被全局 autoLift 提升后,compat 边界会改变实参形态,破坏其\n * 内部「以 Shape 受众」的借面逻辑(原 CLI 即按 autoLift=false 运行)。\n * 逐库关掉提升恢复 CLI 等价行为。\n */\n autoLiftFor?: (packageName: string) => boolean | undefined\n }\n /**\n * 按 packageName 取库自身的**装配元数据**(`package.json` 的 `faijs.lib` 定位声明\n * + `peerDependencies`)。逐库自动装载时由 runtime 读一次,喂给\n * `registerLib({ lib, peers })` 的装配期校验(§3.3 第 1 项)。\n *\n * 与 `options.autoLiftFor` 同源(都出自库的 `package.json`),但**必须同步**——\n * `autoLoadLibsFromImports` 在装载后立即调用,没有 await 的余地。\n *\n * 缺省 / 返回 `undefined` = 该来源不提供库声明事实 → 按中立处理(今日行为)。\n */\n libMetaFor?(packageName: string): LibMeta | undefined\n /**\n * 可选源码扫描钩子(§6.2 ②):宿主返回库源码时走同一 SecurityScanner(A4,固定 strict);\n * 不提供或返回 undefined 则跳过。不改 loadLib 返回值——返回 LibNamespace,\n * 往里挂 source 会被 admitCompatLib 当成导出值并污染命名空间。\n * @param packageName - the npm package name.\n * @returns the library source text if available, otherwise undefined.\n */\n loadSource?(packageName: string): Promise<string | undefined>\n}\n\n// ── ProjectLoader ──\n\n/**\n * 项目文件加载器(多文件,§4.5)——按 moduleKey 读取/枚举项目内 .fai.js 模块源码。\n *\n * moduleKey 约定:host 决定字符串形态(项目根相对路径等);引擎只做最小归一\n * (POSIX 斜杠、去掉 `./`/`../`/前导 `/` 前缀),随后按 `listModules()` 精确匹配。\n *\n * host 实现:\n * - 3d_editor / browser:项目文件表 + session 内缓存;\n * - node / vitest:内存映射表或 fs 读取(fixture 目录)。\n */\nexport interface ProjectLoader {\n /** 列出当前可加载的 moduleKey(装载前预检 / 错误提示用)。 */\n listModules(): string[]\n /** 按 moduleKey 读取模块源码(.fai.js 文本)。 */\n readSource(moduleKey: string): Promise<string>\n /** 模块内容指纹(增量缓存用;不提供则每次全量重读重执行)。 */\n fingerprint?(moduleKey: string): Promise<string>\n}\n\n// ── 宿主环境 ──\n\n/**\n * 宿主环境——脚本面导出命令的可用性判据。\n *\n * - `'node'`:Node.js 进程(CLI、进程内嵌)。落盘发生在用户自己的机器上,\n * 不构成跨域外泄,因此开放;\n * - `'browser'`:web 页面 / web worker。页面内脚本发起下载正是 CSP、\n * 用户手势要求与 drive-by download 防护所针对的模式;\n * - `'weapp'`:小程序 worker。落盘同样属于宿主能力的范畴。\n *\n * 只有 `'node'` 宿主开放脚本面导出命令(`cad.exportStl` / `cad.exportBrep`),\n * 其余值(含未声明)执行即报 `E_HOST_UNSUPPORTED`。理由:`.fai.js` 是可由 AI\n * 生成任意代码的文本、属不受信输入(`lang/security-scanner.ts` 的静态门禁自认\n * 不是沙箱),而导出把「往哪写、写几份、写什么」的决定权交给脚本文本。浏览器 /\n * 小程序里要导出模型,必须由宿主提供的入口触发——用户点的按钮,或宿主自己调用的\n * 库面字节通道(`exportModel(Sync)` / `exportStepFromSolids*` 等)。\n *\n * 宿主在端口装配期声明一次;运行期不探测环境(`typeof process` 那类判断只留在\n * 内核装载器里选 wasm 装载通道)。未声明按非 node 处理(fail-closed,不兜底)。\n */\nexport type HostEnv = 'node' | 'browser' | 'weapp'\n\n// ── HostPorts 汇总 ──\n\n/**\n * Host 在 createRuntime 时注入的全部环境能力。\n *\n * 所有字段可选——node 测试环境可只提供 occt kernel(不注入 csg/sdf),\n * BREP-path ops 不依赖这些 Port。\n */\nexport interface HostPorts {\n csg?: CsgBackend\n sdf?: SdfBackend\n fonts?: FontProvider\n texture?: TextureSampler\n assets?: AssetResolver\n events: EventSink // events 必填——断链通知是基础能力\n /**\n * 宿主环境(装配期声明一次;未声明 → 脚本面导出命令一律拒绝)。\n *\n * 保持可选而不设为必填:`HostPorts` 是公开类型,设必填会把与本次能力无关的\n * 机械改动压到仓内近百处只给 `events` 的装配点上;读取端 fail-closed(漏声明 =\n * 非 node)效果等价于必填。见 {@link HostEnv}。\n */\n hostEnv?: HostEnv\n /** 库加载器(execute 自动装载未注册库;check 用它做 specifier 预检)。可选——无则仅手工 registerLib。 */\n libLoader?: LibLoader\n /** 项目文件加载器(相对 specifier 的多文件模块,§4.5)。可选——不提供则单文件行为不变。 */\n projectLoader?: ProjectLoader\n}\n\n// ── 执行模式 ──\n\n/**\n * 执行模式(设计文档 §4.4)。\n *\n * - `auto`(默认):优先 BREP,断链后自动切 mesh + EventSink 通知\n * - `brep`:强制 BREP,断链即报错 E_BREP_UNSUPPORTED,不自动切换\n * - `mesh`:全部走 mesh 路径\n */\nexport type ExecutionMode = 'auto' | 'brep' | 'mesh'\n"]}