@faicad/faijs 0.18.3 → 0.22.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 (241) hide show
  1. package/dist/api/api-namespace.d.ts.map +1 -1
  2. package/dist/api/api-namespace.js +4 -1
  3. package/dist/api/api-namespace.js.map +1 -1
  4. package/dist/api/brep-mirror/joinery-brep.d.ts +1 -1
  5. package/dist/api/brep-mirror/joinery-brep.d.ts.map +1 -1
  6. package/dist/api/brep-mirror/joinery-brep.js +22 -20
  7. package/dist/api/brep-mirror/joinery-brep.js.map +1 -1
  8. package/dist/api/generated/script-face-manifest.d.ts +4 -0
  9. package/dist/api/generated/script-face-manifest.d.ts.map +1 -1
  10. package/dist/api/generated/script-face-manifest.js.map +1 -1
  11. package/dist/api/index.d.ts +4 -0
  12. package/dist/api/index.d.ts.map +1 -1
  13. package/dist/api/index.js +3 -0
  14. package/dist/api/index.js.map +1 -1
  15. package/dist/api/knurl.d.ts.map +1 -1
  16. package/dist/api/knurl.js +1 -0
  17. package/dist/api/knurl.js.map +1 -1
  18. package/dist/api/primitives.d.ts +4 -3
  19. package/dist/api/primitives.d.ts.map +1 -1
  20. package/dist/api/primitives.js +9 -3
  21. package/dist/api/primitives.js.map +1 -1
  22. package/dist/api/profile.d.ts +34 -5
  23. package/dist/api/profile.d.ts.map +1 -1
  24. package/dist/api/profile.js +168 -186
  25. package/dist/api/profile.js.map +1 -1
  26. package/dist/api/punch-hole.d.ts +77 -0
  27. package/dist/api/punch-hole.d.ts.map +1 -0
  28. package/dist/api/punch-hole.js +207 -0
  29. package/dist/api/punch-hole.js.map +1 -0
  30. package/dist/api/sketch-on-face.d.ts +85 -0
  31. package/dist/api/sketch-on-face.d.ts.map +1 -0
  32. package/dist/api/sketch-on-face.js +136 -0
  33. package/dist/api/sketch-on-face.js.map +1 -0
  34. package/dist/api/sketch-on-plane.d.ts +87 -0
  35. package/dist/api/sketch-on-plane.d.ts.map +1 -0
  36. package/dist/api/sketch-on-plane.js +106 -0
  37. package/dist/api/sketch-on-plane.js.map +1 -0
  38. package/dist/api/surface/arg-spec.d.ts +8 -0
  39. package/dist/api/surface/arg-spec.d.ts.map +1 -1
  40. package/dist/api/surface/arg-spec.js.map +1 -1
  41. package/dist/api/transform.d.ts +5 -5
  42. package/dist/api/transform.d.ts.map +1 -1
  43. package/dist/api/transform.js +12 -10
  44. package/dist/api/transform.js.map +1 -1
  45. package/dist/api/xml-dom.d.ts +27 -0
  46. package/dist/api/xml-dom.d.ts.map +1 -0
  47. package/dist/api/xml-dom.js +45 -0
  48. package/dist/api/xml-dom.js.map +1 -0
  49. package/dist/boolean/csg-backend.d.ts +6 -6
  50. package/dist/boolean/csg-backend.d.ts.map +1 -1
  51. package/dist/boolean/csg-backend.js +9 -9
  52. package/dist/boolean/csg-backend.js.map +1 -1
  53. package/dist/boolean/csg-core.d.ts +10 -10
  54. package/dist/boolean/csg-core.d.ts.map +1 -1
  55. package/dist/boolean/csg-core.js +24 -24
  56. package/dist/boolean/csg-core.js.map +1 -1
  57. package/dist/boolean/extrude-helpers.d.ts +8 -8
  58. package/dist/boolean/extrude-helpers.d.ts.map +1 -1
  59. package/dist/boolean/extrude-helpers.js +13 -13
  60. package/dist/boolean/extrude-helpers.js.map +1 -1
  61. package/dist/brep/brep-ops.d.ts +24 -10
  62. package/dist/brep/brep-ops.d.ts.map +1 -1
  63. package/dist/brep/brep-ops.js +46 -18
  64. package/dist/brep/brep-ops.js.map +1 -1
  65. package/dist/brep/brep-topology.d.ts.map +1 -1
  66. package/dist/brep/brep-topology.js +3 -1
  67. package/dist/brep/brep-topology.js.map +1 -1
  68. package/dist/brep/export/export-model.d.ts +79 -0
  69. package/dist/brep/export/export-model.d.ts.map +1 -0
  70. package/dist/brep/export/export-model.js +335 -0
  71. package/dist/brep/export/export-model.js.map +1 -0
  72. package/dist/brep/primitives-brep.d.ts.map +1 -1
  73. package/dist/brep/primitives-brep.js +3 -1
  74. package/dist/brep/primitives-brep.js.map +1 -1
  75. package/dist/brepkit-kernel/brepkitKernel.d.ts.map +1 -1
  76. package/dist/brepkit-kernel/brepkitKernel.js +4 -2
  77. package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
  78. package/dist/browser-host/csg-worker-protocol.d.ts +3 -3
  79. package/dist/browser-host/csg-worker-protocol.d.ts.map +1 -1
  80. package/dist/browser-host/csg-worker-protocol.js.map +1 -1
  81. package/dist/browser-host/csg-worker.js +3 -3
  82. package/dist/browser-host/csg-worker.js.map +1 -1
  83. package/dist/browser-host/inline-csg-backend.d.ts +3 -3
  84. package/dist/browser-host/inline-csg-backend.d.ts.map +1 -1
  85. package/dist/browser-host/inline-csg-backend.js +3 -3
  86. package/dist/browser-host/inline-csg-backend.js.map +1 -1
  87. package/dist/browser-host/worker-csg-backend.d.ts +3 -3
  88. package/dist/browser-host/worker-csg-backend.d.ts.map +1 -1
  89. package/dist/browser-host/worker-csg-backend.js.map +1 -1
  90. package/dist/cad-runtime/direct-executor.d.ts +4 -0
  91. package/dist/cad-runtime/direct-executor.d.ts.map +1 -1
  92. package/dist/cad-runtime/direct-executor.js +17 -1
  93. package/dist/cad-runtime/direct-executor.js.map +1 -1
  94. package/dist/cad-runtime/ports.d.ts +3 -3
  95. package/dist/cad-runtime/ports.d.ts.map +1 -1
  96. package/dist/cad-runtime/ports.js.map +1 -1
  97. package/dist/cad-runtime/runtime.d.ts +24 -1
  98. package/dist/cad-runtime/runtime.d.ts.map +1 -1
  99. package/dist/cad-runtime/runtime.js +53 -3
  100. package/dist/cad-runtime/runtime.js.map +1 -1
  101. package/dist/define-op.d.ts +22 -0
  102. package/dist/define-op.d.ts.map +1 -1
  103. package/dist/define-op.js +15 -0
  104. package/dist/define-op.js.map +1 -1
  105. package/dist/env-agnostic.d.ts +7 -7
  106. package/dist/env-agnostic.d.ts.map +1 -1
  107. package/dist/env-agnostic.js +3 -3
  108. package/dist/env-agnostic.js.map +1 -1
  109. package/dist/geometry2d/adapt.d.ts +46 -0
  110. package/dist/geometry2d/adapt.d.ts.map +1 -0
  111. package/dist/geometry2d/adapt.js +41 -0
  112. package/dist/geometry2d/adapt.js.map +1 -0
  113. package/dist/geometry2d/bbox2d.d.ts +82 -0
  114. package/dist/geometry2d/bbox2d.d.ts.map +1 -0
  115. package/dist/geometry2d/bbox2d.js +123 -0
  116. package/dist/geometry2d/bbox2d.js.map +1 -0
  117. package/dist/geometry2d/blueprint-sketcher.d.ts +27 -0
  118. package/dist/geometry2d/blueprint-sketcher.d.ts.map +1 -0
  119. package/dist/geometry2d/blueprint-sketcher.js +29 -0
  120. package/dist/geometry2d/blueprint-sketcher.js.map +1 -0
  121. package/dist/geometry2d/blueprint.d.ts +102 -0
  122. package/dist/geometry2d/blueprint.d.ts.map +1 -0
  123. package/dist/geometry2d/blueprint.js +225 -0
  124. package/dist/geometry2d/blueprint.js.map +1 -0
  125. package/dist/geometry2d/blueprints.d.ts +58 -0
  126. package/dist/geometry2d/blueprints.d.ts.map +1 -0
  127. package/dist/geometry2d/blueprints.js +72 -0
  128. package/dist/geometry2d/blueprints.js.map +1 -0
  129. package/dist/geometry2d/bridge/lift-on-plane.d.ts +50 -0
  130. package/dist/geometry2d/bridge/lift-on-plane.d.ts.map +1 -0
  131. package/dist/geometry2d/bridge/lift-on-plane.js +78 -0
  132. package/dist/geometry2d/bridge/lift-on-plane.js.map +1 -0
  133. package/dist/geometry2d/bridge/on-surface.d.ts +98 -0
  134. package/dist/geometry2d/bridge/on-surface.d.ts.map +1 -0
  135. package/dist/geometry2d/bridge/on-surface.js +94 -0
  136. package/dist/geometry2d/bridge/on-surface.js.map +1 -0
  137. package/dist/geometry2d/bridge/plane.d.ts +69 -0
  138. package/dist/geometry2d/bridge/plane.d.ts.map +1 -0
  139. package/dist/geometry2d/bridge/plane.js +96 -0
  140. package/dist/geometry2d/bridge/plane.js.map +1 -0
  141. package/dist/geometry2d/canned-blueprints.d.ts +44 -0
  142. package/dist/geometry2d/canned-blueprints.d.ts.map +1 -0
  143. package/dist/geometry2d/canned-blueprints.js +94 -0
  144. package/dist/geometry2d/canned-blueprints.js.map +1 -0
  145. package/dist/geometry2d/compound-blueprint.d.ts +72 -0
  146. package/dist/geometry2d/compound-blueprint.d.ts.map +1 -0
  147. package/dist/geometry2d/compound-blueprint.js +95 -0
  148. package/dist/geometry2d/compound-blueprint.js.map +1 -0
  149. package/dist/geometry2d/curve2d.d.ts +298 -0
  150. package/dist/geometry2d/curve2d.d.ts.map +1 -0
  151. package/dist/geometry2d/curve2d.js +1110 -0
  152. package/dist/geometry2d/curve2d.js.map +1 -0
  153. package/dist/geometry2d/index.d.ts +22 -0
  154. package/dist/geometry2d/index.d.ts.map +1 -0
  155. package/dist/geometry2d/index.js +21 -0
  156. package/dist/geometry2d/index.js.map +1 -0
  157. package/dist/geometry2d/organise.d.ts +28 -0
  158. package/dist/geometry2d/organise.d.ts.map +1 -0
  159. package/dist/geometry2d/organise.js +108 -0
  160. package/dist/geometry2d/organise.js.map +1 -0
  161. package/dist/geometry2d/pen-sketcher.d.ts +365 -0
  162. package/dist/geometry2d/pen-sketcher.d.ts.map +1 -0
  163. package/dist/geometry2d/pen-sketcher.js +520 -0
  164. package/dist/geometry2d/pen-sketcher.js.map +1 -0
  165. package/dist/geometry2d/point.d.ts +44 -0
  166. package/dist/geometry2d/point.d.ts.map +1 -0
  167. package/dist/geometry2d/point.js +57 -0
  168. package/dist/geometry2d/point.js.map +1 -0
  169. package/dist/geometry2d/svg-ellipse.d.ts +74 -0
  170. package/dist/geometry2d/svg-ellipse.d.ts.map +1 -0
  171. package/dist/geometry2d/svg-ellipse.js +163 -0
  172. package/dist/geometry2d/svg-ellipse.js.map +1 -0
  173. package/dist/lang/code-to-args.d.ts +29 -3
  174. package/dist/lang/code-to-args.d.ts.map +1 -1
  175. package/dist/lang/code-to-args.js +41 -2
  176. package/dist/lang/code-to-args.js.map +1 -1
  177. package/dist/lang/codegen.d.ts +45 -1
  178. package/dist/lang/codegen.d.ts.map +1 -1
  179. package/dist/lang/codegen.js +135 -6
  180. package/dist/lang/codegen.js.map +1 -1
  181. package/dist/lang/host-arg.d.ts +6 -0
  182. package/dist/lang/host-arg.d.ts.map +1 -1
  183. package/dist/lang/host-arg.js.map +1 -1
  184. package/dist/lang/metadata-extractor.d.ts +25 -0
  185. package/dist/lang/metadata-extractor.d.ts.map +1 -1
  186. package/dist/lang/metadata-extractor.js +289 -25
  187. package/dist/lang/metadata-extractor.js.map +1 -1
  188. package/dist/lang/parse-error.d.ts +7 -1
  189. package/dist/lang/parse-error.d.ts.map +1 -1
  190. package/dist/lang/parse-error.js.map +1 -1
  191. package/dist/lang/security-scanner.d.ts +9 -1
  192. package/dist/lang/security-scanner.d.ts.map +1 -1
  193. package/dist/lang/security-scanner.js +38 -1
  194. package/dist/lang/security-scanner.js.map +1 -1
  195. package/dist/lang/symbol-table.generated.d.ts +3 -0
  196. package/dist/lang/symbol-table.generated.d.ts.map +1 -1
  197. package/dist/lang/symbol-table.generated.js +3 -0
  198. package/dist/lang/symbol-table.generated.js.map +1 -1
  199. package/dist/mesh/io.d.ts +62 -9
  200. package/dist/mesh/io.d.ts.map +1 -1
  201. package/dist/mesh/io.js +124 -17
  202. package/dist/mesh/io.js.map +1 -1
  203. package/dist/mesh/threemf-loader.d.ts +15 -0
  204. package/dist/mesh/threemf-loader.d.ts.map +1 -0
  205. package/dist/mesh/threemf-loader.js +163 -0
  206. package/dist/mesh/threemf-loader.js.map +1 -0
  207. package/dist/mesh/transform.d.ts +2 -2
  208. package/dist/mesh/transform.d.ts.map +1 -1
  209. package/dist/mesh/transform.js +3 -3
  210. package/dist/mesh/transform.js.map +1 -1
  211. package/dist/mesh/types.d.ts +2 -2
  212. package/dist/mesh/types.d.ts.map +1 -1
  213. package/dist/mesh/types.js.map +1 -1
  214. package/dist/node-host/cli.d.ts.map +1 -1
  215. package/dist/node-host/cli.js +53 -26
  216. package/dist/node-host/cli.js.map +1 -1
  217. package/dist/occt-kernel/occtKernel.d.ts.map +1 -1
  218. package/dist/occt-kernel/occtKernel.js +4 -2
  219. package/dist/occt-kernel/occtKernel.js.map +1 -1
  220. package/dist/occt-kernel/topologyExt.d.ts.map +1 -1
  221. package/dist/occt-kernel/topologyExt.js +4 -1
  222. package/dist/occt-kernel/topologyExt.js.map +1 -1
  223. package/dist/runtime-state.d.ts +18 -0
  224. package/dist/runtime-state.d.ts.map +1 -1
  225. package/dist/runtime-state.js +23 -0
  226. package/dist/runtime-state.js.map +1 -1
  227. package/dist/sdk.d.ts +1 -1
  228. package/dist/sdk.d.ts.map +1 -1
  229. package/dist/sdk.js +1 -1
  230. package/dist/sdk.js.map +1 -1
  231. package/dist/tolerance.d.ts +38 -0
  232. package/dist/tolerance.d.ts.map +1 -0
  233. package/dist/tolerance.js +40 -0
  234. package/dist/tolerance.js.map +1 -0
  235. package/dist/topology/naming/score.js +3 -3
  236. package/dist/topology/naming/score.js.map +1 -1
  237. package/dist/units.d.ts +248 -0
  238. package/dist/units.d.ts.map +1 -0
  239. package/dist/units.js +397 -0
  240. package/dist/units.js.map +1 -0
  241. package/package.json +19 -2
@@ -30,6 +30,7 @@ import { type SlotMap } from './api/internal/dual-form-args.js';
30
30
  import { type ResultLike } from './api/internal/result-unwrap.js';
31
31
  import type { Shape } from './mesh/types.js';
32
32
  import { type BrepEngineId, type BrepHandle } from './brep/engine/types.js';
33
+ import type { DimName } from './units.js';
33
34
  import { type Provenance } from './topology/naming/lineage.js';
34
35
  /** Raw mesh data (structurally identical to Shape; mesh impls return it). */
35
36
  export type MeshData = {
@@ -111,6 +112,14 @@ export interface DualOpOptions {
111
112
  * missing naming = compile-time error (G4: no undeclared ops).
112
113
  */
113
114
  naming: Provenance;
115
+ /**
116
+ * Script-side dimension declaration (unit-system D8): per-parameter dim for
117
+ * the static `dimension` check stage. Params absent here are treated as
118
+ * dimensionless and exempt from the check. `DimName` is a pure type import.
119
+ */
120
+ paramDims?: Record<string, DimName>;
121
+ /** Return dimension declaration (D8): the value produced carries this dim. */
122
+ retDim?: DimName;
114
123
  }
115
124
  /** Implementation set (at least one of mesh/brep is required, D1/D1b); options are siblings of the implementations. */
116
125
  export type DualOpImpls<A extends unknown[]> = (DualOpOptions & {
@@ -136,6 +145,10 @@ export interface DualOpMeta {
136
145
  slotMap?: SlotMap;
137
146
  /** Topology identity provenance (Phase 2.3, mirrors DualOpOptions.naming). */
138
147
  naming: Provenance;
148
+ /** Script-side dimension declaration (D8, mirrors DualOpOptions.paramDims). */
149
+ paramDims?: Record<string, DimName>;
150
+ /** Return dimension declaration (D8). */
151
+ retDim?: DimName;
139
152
  }
140
153
  /** Property key carrying DualOpMeta on wrapped functions. */
141
154
  export declare const DUAL_OP_META = "__faijs__dualOp";
@@ -189,6 +202,15 @@ export declare function defineOp<A extends unknown[]>(decl: DualOpImpls<A>): ((.
189
202
  * @returns `true` if at least one exported value is a dual-op function.
190
203
  */
191
204
  export declare function hasDualOp(ns: Record<string, unknown>): boolean;
205
+ /**
206
+ * Read the dual-op metadata of a wrapped function (unit-system D8 declaration
207
+ * surface). Returns `undefined` when the function carries no dual-op metadata,
208
+ * so callers never probe the private key directly.
209
+ *
210
+ * @param fn - a function that may have been produced by `defineOp`/`compatOp`.
211
+ * @returns the op's metadata, or `undefined`.
212
+ */
213
+ export declare function dualOpMetaOf(fn: unknown): DualOpMeta | undefined;
192
214
  /**
193
215
  * Assert that a library conforms to the dual-op contract: if it exports any
194
216
  * dual-op function, it must also export `contractVersion` matching the engine's.
@@ -1 +1 @@
1
- {"version":3,"file":"define-op.d.ts","sourceRoot":"","sources":["../src/define-op.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"define-op.d.ts","sourceRoot":"","sources":["../src/define-op.ts"],"names":[],"mappings":"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"}
package/dist/define-op.js CHANGED
@@ -163,6 +163,8 @@ export function defineOp(decl) {
163
163
  schema: decl.schema,
164
164
  slotMap: decl.slotMap,
165
165
  naming: decl.naming,
166
+ paramDims: decl.paramDims,
167
+ retDim: decl.retDim,
166
168
  };
167
169
  // Async wrapper: implementations may be sync or async (stdlib mesh paths are
168
170
  // often async, e.g. drill/engrave/boolean). The compiled .fai.js product always
@@ -281,6 +283,19 @@ export function hasDualOp(ns) {
281
283
  const values = Object.values(ns);
282
284
  return values.some((v) => typeof v === 'function' && v[DUAL_OP_META]);
283
285
  }
286
+ /**
287
+ * Read the dual-op metadata of a wrapped function (unit-system D8 declaration
288
+ * surface). Returns `undefined` when the function carries no dual-op metadata,
289
+ * so callers never probe the private key directly.
290
+ *
291
+ * @param fn - a function that may have been produced by `defineOp`/`compatOp`.
292
+ * @returns the op's metadata, or `undefined`.
293
+ */
294
+ export function dualOpMetaOf(fn) {
295
+ if (typeof fn !== 'function')
296
+ return undefined;
297
+ return fn[DUAL_OP_META];
298
+ }
284
299
  /**
285
300
  * Assert that a library conforms to the dual-op contract: if it exports any
286
301
  * dual-op function, it must also export `contractVersion` matching the engine's.
@@ -1 +1 @@
1
- {"version":3,"file":"define-op.js","sourceRoot":"","sources":["../src/define-op.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * define-op — dual-path implementation decorator for geometry functions\n * (D-face contract: mesh mandatory as the default path, BREP optional).\n *\n *\n * `defineOp({ mesh?, brep?, ... })` declares the implementation set of a\n * geometry function (a function whose signature returns `SolidShape`). The\n * wrapper:\n * - auto-collects geometry inputs via `args.filter(isGeometryInput)` — a shape\n * that is identity-registered (`isShape`) or a structural mesh shape\n * (`isMeshShape`, positions + indices — e.g. bare ManifoldMeshData handed in\n * by a host via `geoToManifoldMesh`). The old per-function form passed the\n * actual geometry args (`dispatchPath([input], ...)`), so a bare mesh input\n * dispatched to the mesh path (`hasBrep=false`); the re-collection must keep\n * that compatibility. No `inputs` field — decided at runtime by the args\n * themselves, not the author.\n * - calls the engine's `dispatchPath` to select brep/mesh by mode (static,\n * no runtime fallback);\n * - wraps raw products: mesh path → `solid()`, brep path → `fromHandle()` /\n * `fromBrep()` (D3/D4: products must come from constructors, brep products\n * must carry a BREP slot).\n *\n * Zero heavy runtime dependencies: imports only runtime-state / shape /\n * handle-bridge / backend-dispatch / mesh/types (a zero-import module holding\n * the Shape type and the structural `isMeshShape` guard) — the dist/sdk.js\n * static-import guard keeps passing.\n */\n\nimport { dispatchPath, firstMissingCapability, type BrepCapabilityName } from './cad-runtime/backend-dispatch'\nimport {\n CONTRACT_VERSION,\n BrepUnsupportedError,\n MeshUnsupportedError,\n getCurrentStmt,\n getRuntimeState,\n nameOf,\n} from './runtime-state'\nimport { asStmtId, type PartName } from './identity'\nimport { isShape, solid, fromBrep, getSlot } from './shape'\nimport { isMeshShape } from './mesh/types'\nimport { fromHandle, meshHandle, isOcctHandle } from './brep/handle-bridge'\nimport { positionalToObject, type SlotMap } from './api/internal/dual-form-args'\nimport { toOpFailure, unwrapResult, OpError, type ResultLike } from './api/internal/result-unwrap'\nimport type { Shape } from './mesh/types'\nimport { BREP_ENGINE_IDS, type BrepEngineId, type BrepHandle } from './brep/engine/types'\nimport { type Provenance, runtimeLineage } from './topology/naming/lineage'\n\n/** 合法引擎 id 集合(assertLibConforms 的 engines 校验用,D11-1)。 */\nconst BREP_ENGINE_ID_SET = new Set<string>(BREP_ENGINE_IDS)\n\n/** Raw mesh data (structurally identical to Shape; mesh impls return it). */\nexport type MeshData = { positions: Float32Array; indices: Uint32Array }\n\n/**\n * Geometry-input recognition for dispatch auto-collection.\n *\n * Compat rule: the old per-function form passed the *actual* geometry args to\n * `dispatchPath` (`[input]` / `shapes`), so a bare ManifoldMeshData object\n * (e.g. `geoToManifoldMesh` output passed straight by a host) had no BREP slot\n * → `hasBrep=false` → mesh path. defineOp must keep that: an input counts as\n * geometry when it is identity-registered (`isShape`, constructor product) OR\n * structurally a mesh shape (`positions` + `indices`). Params objects and other\n * scalar args are not geometry inputs.\n *\n * @param v - the candidate argument.\n * @returns true when the argument is a geometry input (registered shape or bare mesh data).\n */\nexport function isGeometryInput(v: unknown): v is Shape {\n return isShape(v) || isMeshShape(v)\n}\n\n/**\n * §1.4 registration guard: the StmtId whose top-level `wrapped` is currently\n * registering a lineage node. Nested op calls (an impl invoking another op /\n * itself) share the same `getCurrentStmt()` anchor and are skipped so they\n * don't trip N3 (E_TOPO_DUPLICATE_STMT) with identical content. C1 (single\n * live runtime) means at most one statement registers at a time.\n *\n * The marker lives on the runtime state and is reset at statement boundaries\n * (runtime-state.setCurrentStmt: anchor change / end-of-statement), NOT at op\n * granularity — a TS library function (cq-compat Workplane op, etc.) may call\n * several defineOps within one statement, and only the first one must register.\n */\n\n/** Product of a mesh implementation: raw mesh data, a wrapped Shape, or (with `outputs`) a record of named products. */\nexport type MeshProduct = MeshData | Shape | Record<string, MeshData | Shape>\n\n/** Mesh implementation: sync or async (stdlib mesh paths are often async); returns a mesh product. */\nexport type MeshImpl<A extends unknown[]> = (...args: A) => MeshProduct | Promise<MeshProduct>\n\n/** BREP implementation result: a raw handle, or a handle plus face evolution. */\nexport interface BrepResult {\n solid: BrepHandle\n faceEvolution?: Map<number, number[]>\n}\n\n/** Product of a BREP implementation: a raw handle, { solid, faceEvolution }, a wrapped Shape, or (with `outputs`) a record of named products. */\nexport type BrepProduct =\n | BrepHandle\n | BrepResult\n | Shape\n | Record<string, BrepHandle | BrepResult | Shape>\n | ResultLike\n\n/** BREP implementation: sync or async; returns a brep product. */\nexport type BrepImpl<A extends unknown[]> = (...args: A) => BrepProduct | Promise<BrepProduct>\n\n/** Optional declaration: capabilities (D5) and named multi-products (split, scheme C). */\nexport interface DualOpOptions {\n /** Op name (error messages); falls back to an anonymous prefix when absent. */\n name?: string\n capabilities?: BrepCapabilityName[]\n /**\n * 平台身份声明(D11,narrowing plan 2026-09-24):本 op 实现可运行在哪些\n * BREP 引擎上——一个**引擎白名单**。缺省 = 全平台(中立 op——实现只用 L1 核心面)。\n *\n * 平台 op(实现 import 了 `occt-kernel/*` / `brepkit-kernel/*`,调用该平台\n * 原生方法)**必须**声明 `engines` 自证身份。\n *\n * 与 `capabilities` **可以并存**(2026-09-24 撤销 D11-7 互斥):两者是正交的两轴——\n * `engines` 收窄「在哪些引擎上跑」,`capabilities` 声明「需要哪些内核能力」。判定\n * 次序 `engines` 在先(D11-2),能力门随后对同一引擎继续求交,故同时声明等于\n * 「只在这些引擎上,且要求这些能力」——不会静默放行\"目标引擎缺该能力\"的组合。\n */\n engines?: readonly BrepEngineId[]\n outputs?: string[]\n /** L3 schema per named parameter (G1 codegen + UI panel, plain string form). */\n schema?: Record<string, string>\n /**\n * D11 slot-map declaration (§4.2): the positional→object boxing table\n * (SlotMap) mapping a brepjs-style positional call onto this op's native\n * object form. Ops without it accept only the form their implementation\n * natively takes.\n */\n slotMap?: SlotMap\n /**\n * Topology identity provenance (plan §4.4 / Phase 2.3, **required**).\n * Declares the op's face-mapping category + new-face vocabulary.\n * The lineage registrar (§4.3) reads this to build the blood-line graph;\n * missing naming = compile-time error (G4: no undeclared ops).\n */\n naming: Provenance\n}\n\n/** Implementation set (at least one of mesh/brep is required, D1/D1b); options are siblings of the implementations. */\nexport type DualOpImpls<A extends unknown[]> =\n | (DualOpOptions & { mesh: MeshImpl<A>; brep?: BrepImpl<A> })\n | (DualOpOptions & { mesh?: never; brep: BrepImpl<A> })\n\n/** Metadata hung on the wrapped function object (K5: function info is data). */\nexport interface DualOpMeta {\n kind: 'dual-op'\n mesh?: unknown\n brep?: unknown\n /** Op name (error messages). */\n name?: string\n capabilities?: BrepCapabilityName[]\n /** 平台身份声明(D11,镜像 DualOpOptions.engines)。 */\n engines?: readonly BrepEngineId[]\n outputs?: string[]\n schema?: Record<string, string>\n /** D11 slot-map declaration (positional → object boxing table, §9 naming). */\n slotMap?: SlotMap\n /** Topology identity provenance (Phase 2.3, mirrors DualOpOptions.naming). */\n naming: Provenance\n}\n\n/** Property key carrying DualOpMeta on wrapped functions. */\nexport const DUAL_OP_META = '__faijs__dualOp'\n\ntype MetaCarrier = { [DUAL_OP_META]?: DualOpMeta }\n\nfunction wrapMeshOne(v: unknown): Shape {\n if (isShape(v)) return v\n return solid(v as MeshData)\n}\n\nfunction wrapBrepOne(v: unknown): Shape {\n if (isShape(v)) return v\n if (v !== null && typeof v === 'object' && 'faceEvolution' in v) {\n const res = v as BrepResult\n return fromBrep(meshHandle(res.solid), res)\n }\n // A plain object that is not a Shape and not an OCCT handle is a data\n // product (e.g. a compat fn returning a sheetmetal-style record), not a\n // geometry handle — pass it through so it lands in the engine's value\n // store instead of being tessellated as if it were a bare handle. Native\n // OCCT handles from an implementation are hand-computed shape numbers\n // (from a branded number return) or objects; only the number path reaches\n // fromHandle. The handle/data distinction must go through the shared\n // isOcctHandle leaf (handle-bridge) — never a hardcoded '__occtWasm' in v.\n if (v !== null && typeof v === 'object' && !isOcctHandle(v)) {\n return v as unknown as Shape\n }\n return fromHandle(v)\n}\n\nfunction wrapByKeys(r: unknown, keys: string[], wrapOne: (v: unknown) => Shape): Record<string, Shape> {\n const src = (r ?? {}) as Record<string, unknown>\n const out: Record<string, Shape> = {}\n for (const k of keys) {\n const v = src[k]\n // An output may be an array (e.g. the compat adapter adopts each element of\n // an array-valued `outputs` field); wrap element-wise so arrays stay arrays.\n out[k] = Array.isArray(v) ? (v.map(wrapOne) as unknown as Shape) : wrapOne(v)\n }\n // Pass through non-shape data keys (e.g. autoHeal's `report`): declared\n // outputs are the geometry that gets Shape-wrapped, but sibling data products\n // of the same op result must survive the statement boundary (§5.4 selfhost).\n for (const k of Object.keys(src)) {\n if (!keys.includes(k)) out[k] = src[k] as unknown as Shape\n }\n return out\n}\n\n/** Human-readable op label for error messages (falls back when unnamed). */\nfunction opLabel(meta: DualOpMeta): string {\n return meta.name ?? '<anon>'\n}\n\n/**\n * Run one implementation through the unified Result boundary (§5.2, D1).\n *\n * Transition contract: an implementation may\n * ① return a `Result` → unwrapped here (`err` becomes a throw);\n * ② throw → normalized into an op-labelled error;\n * ③ return a plain product → passed through untouched.\n *\n * The two engine-level routing errors keep their class: `runtime.ts` matches\n * `BrepUnsupportedError` / `MeshUnsupportedError` by `instanceof` to turn them\n * into `ExecutionResult.failedAt`, so they must not be re-wrapped.\n *\n * @param meta - the op's metadata (name).\n * @param impl - the implementation to run.\n * @param args - the normalized argument list.\n * @returns the (unwrapped) implementation product.\n */\nasync function runImpl(\n meta: DualOpMeta,\n impl: ((...a: unknown[]) => unknown) | undefined,\n args: unknown[],\n): Promise<unknown> {\n const label = opLabel(meta)\n let product: unknown\n try {\n product = await (impl as (...a: unknown[]) => unknown)(...args)\n } catch (e) {\n if (e instanceof BrepUnsupportedError || e instanceof MeshUnsupportedError) throw e\n // An OpError is already the engine-recognizable statement failure (thrown\n // by the compat adapter's Result unwrap, or by impls returning a Result);\n // re-wrapping it into a plain Error would make CadRuntime treat it as an\n // uncaught bug instead of a statement failure.\n if (e instanceof OpError) throw e\n throw toOpFailure(label, e)\n }\n return unwrapResult(product, label)\n}\n\n/**\n * Declare a geometry function's dual-path implementation set.\n *\n * At least one implementation (mesh or brep) is required — enforced at\n * compile time by the union type and at construction time by a runtime check.\n * Geometry inputs are auto-collected by identity-or-structure\n * (`args.filter(isGeometryInput)` = `isShape` ∨ `isMeshShape`); raw mesh\n * products are wrapped by `solid()`, raw brep products by\n * `fromHandle()` / `fromBrep()`. `mode` selects the engine path via the\n * engine's static `dispatchPath` — the author never writes an `if (path)`\n * branch.\n *\n * @param decl - the declaration object: implementations `{ mesh }` (mesh-only),\n * `{ brep }` (brep-only, D1b), or `{ mesh, brep }` (dual-path), plus optional\n * `capabilities` (D5: missing capability degrades in auto, errors in brep mode)\n * and `outputs` (named multi-products, e.g. split) as siblings.\n * @returns the wrapped geometry function with dual-op metadata attached.\n */\nexport function defineOp<A extends unknown[]>(\n decl: DualOpImpls<A> & { outputs: string[] },\n): ((...args: A) => Promise<Record<string, Shape>>) & MetaCarrier\n/**\n * Overload without `outputs`: single-product functions resolve to a `Promise<Shape>`.\n * @param decl - the declaration object: implementations `{ mesh }`, `{ brep }`, or `{ mesh, brep }`.\n * @returns the wrapped geometry function with dual-op metadata attached.\n */\nexport function defineOp<A extends unknown[]>(\n decl: DualOpImpls<A>,\n): ((...args: A) => Promise<Shape>) & MetaCarrier\n/** Implementation signature (not visible to callers); matches the union of both overloads. */\nexport function defineOp<A extends unknown[]>(\n decl: DualOpImpls<A>,\n): ((...args: A) => Promise<Shape | Record<string, Shape>>) & MetaCarrier {\n // Construction-time check (②): implementations must be functions, then at\n // least one implementation must be present.\n if (decl.mesh !== undefined && typeof decl.mesh !== 'function') {\n throw new Error('[faijs/defineOp] mesh must be a function')\n }\n if (decl.brep !== undefined && typeof decl.brep !== 'function') {\n throw new Error('[faijs/defineOp] brep must be a function')\n }\n if (typeof decl.mesh !== 'function' && typeof decl.brep !== 'function') {\n throw new Error('[faijs/defineOp] at least one implementation (mesh or brep) is required')\n }\n\n const meta: DualOpMeta = {\n kind: 'dual-op',\n mesh: decl.mesh,\n brep: decl.brep,\n name: decl.name,\n capabilities: decl.capabilities,\n engines: decl.engines,\n outputs: decl.outputs,\n schema: decl.schema,\n slotMap: decl.slotMap,\n naming: decl.naming,\n }\n\n // Async wrapper: implementations may be sync or async (stdlib mesh paths are\n // often async, e.g. drill/engrave/boolean). The compiled .fai.js product always\n // awaits the call, so returning a Promise is transparent.\n const wrapped = async (...args: A): Promise<Shape | Record<string, Shape>> => {\n // D11 (§4.2): faijs-native ops declare an object-form implementation, so a\n // brepjs-style positional call is boxed into the object form here — before\n // dispatch, so geometry inputs are collected from the normalized arg list.\n const callArgs = (\n meta.slotMap ? positionalToObject(args as unknown[], meta.slotMap, opLabel(meta)) : args\n ) as A\n // Geometry inputs: identity-or-structure auto collection (execution-time\n // read, same nature as hasBrep — decided before the implementation runs).\n // Compat: bare ManifoldMeshData args (host geoToManifoldMesh output) are\n // geometry inputs too — old form passed [input] so they reached the mesh path.\n const inputs = (callArgs as unknown[]).filter(isGeometryInput) as Shape[]\n // §1.4 lineage registration (plan §4.3): every top-level dual-op execution\n // records a blood-line node via `runtimeLineage.register`, which enforces\n // N1 (untracked input → throw, never default to chain-root) / N2\n // (stmt↔anchor mismatch) / N3 (conflicting re-register). The graph is\n // cleared per program execution (direct-executor runCode) and C1 guarantees\n // a single live runtime, so the anchor is authoritative inside a statement.\n // Skip when no anchor is set (the op was invoked outside a statement\n // context — there is no lineage to record, and N2 must not fire on a context\n // that legitimately has none).\n //\n // Guard: a statement executes exactly one *top-level* op; an op's\n // implementation may invoke other ops (or itself) internally, and those\n // nested calls share the same `getCurrentStmt()` anchor. They are\n // implementation details, not statements, so they must NOT register a second\n // node under the same StmtId — that would trip N3 (E_TOPO_DUPLICATE_STMT)\n // on identical content. Only the outermost `wrapped` for the current\n // statement registers; the flag below stays set for the *entire* statement\n // execution (including the awaited impl), so nested calls see it and skip.\n const anchor = getCurrentStmt()\n const st = getRuntimeState()\n const isOuter = anchor != null && st.registeredStmtId !== anchor.id\n if (isOuter) st.registeredStmtId = asStmtId(anchor.id)\n try {\n if (isOuter && anchor) {\n runtimeLineage.register(\n {\n stmt: asStmtId(anchor.id),\n op: opLabel(meta),\n inputs,\n outputs: anchor.outputs as [PartName, ...PartName[]],\n provenance: meta.naming,\n },\n {\n nameOf,\n currentStmt: () => {\n const a = getCurrentStmt()\n return a ? { id: a.id } : undefined\n },\n },\n )\n }\n // D5 capability routing: feed the first missing capability to dispatchPath\n // (auto degrades to mesh, brep mode errors). Matched as a concrete name\n // against the engine's declaration set (family booleans + its `evolution`\n // list of *WithHistory kernel function names) — see firstMissingCapability.\n const missing = firstMissingCapability(meta.capabilities)\n const path = dispatchPath(inputs, meta, missing, meta.engines)\n if (path === 'brep') {\n const r = await runImpl(meta, decl.brep as unknown as ((...a: unknown[]) => unknown) | undefined, callArgs)\n const out = meta.outputs ? wrapByKeys(r, meta.outputs, wrapBrepOne) : wrapBrepOne(r)\n // 1.10 前置①:执行期把 hash 演化挂到血缘节点(kernel 类回走推进的数据源)。\n // 演化在几何算完那一刻可得(fromBrep → slot.faceEvolution),事后补挂不参与\n // N3 的内容比较(lineage.ts 设计如此)。无演化(identity/construct 等无历史\n // 输出)时跳过——identity 类推进不依赖演化,construct 词汇在节点 provenance 里。\n const outShape = (typeof out === 'object' && out !== null ? Object.values(out)[0] : out) as Shape | undefined\n const evolution = outShape ? getSlot(outShape)?.faceEvolution : undefined\n if (outShape && evolution) {\n runtimeLineage.attachEvolution(asStmtId(anchor!.id), evolution)\n }\n // 1.10 前置③:part 键的 roleTable 旁挂在这里记录(不是 fromBrep)——\n // impl 返回后 anchor.outputs 名字已定,而 fromBrep 时刻 shape 还未被\n // executor 命名(nameOf 为 undefined)。op 实现读输入表(inputRoleTable)\n // 与解析读表(tableOfPart)都走这份 part 键权威表。\n if (outShape && anchor && anchor.outputs.length > 0) {\n const stmtId = asStmtId(anchor.id)\n const table = runtimeLineage.outputTableOf(stmtId)\n const solid = runtimeLineage.outputHandleOf(stmtId)\n if (table) runtimeLineage.recordOutput(stmtId, table, solid, anchor.outputs[0] as PartName)\n }\n return out\n }\n const m = await runImpl(meta, decl.mesh as unknown as ((...a: unknown[]) => unknown) | undefined, callArgs)\n return meta.outputs ? wrapByKeys(m, meta.outputs, wrapMeshOne) : wrapMeshOne(m)\n } finally {\n // 同语句去重标记不在 op 粒度清理——语句边界由 runtime-state.setCurrentStmt\n // 在锚点变化时重置;TS 库函数体内连续 op 调用共享锚点,嵌套调用正确跳过。\n }\n }\n\n Object.defineProperty(wrapped, DUAL_OP_META, { value: meta, enumerable: false })\n return wrapped as ((...args: A) => Promise<Shape | Record<string, Shape>>) & MetaCarrier\n}\n\n/**\n * Assembly-time validation (③, strict mode, D-4): a library that exports any\n * dual-op function must carry a matching `contractVersion`, and every exported\n * dual-op must be structurally valid (mesh a function, brep a function or\n * undefined, capabilities/outputs well-formed). Called by `registerLib`.\n *\n * Functions without dual-op metadata are left untouched (declarative\n * enforcement boundary — K5 forbids name-based classification).\n *\n * @param lib - the library namespace object being registered.\n */\n/**\n * Detect whether a library namespace exports any dual-op function (carries\n * `DUAL_OP_META`). Used by `registerLib`'s inferred `autoLift` default: a\n * library that already declares dual-ops does not need bare-function lifting.\n *\n * @param ns - the library namespace object.\n * @returns `true` if at least one exported value is a dual-op function.\n */\nexport function hasDualOp(ns: Record<string, unknown>): boolean {\n const values = Object.values(ns)\n return values.some((v) => typeof v === 'function' && (v as MetaCarrier)[DUAL_OP_META])\n}\n\n/**\n * Assert that a library conforms to the dual-op contract: if it exports any\n * dual-op function, it must also export `contractVersion` matching the engine's.\n *\n * @param lib - the library namespace object being registered.\n * @throws {Error} when dual-op functions are present without a matching contract version.\n */\nexport function assertLibConforms(lib: Record<string, unknown>): void {\n if (hasDualOp(lib) && lib.contractVersion !== CONTRACT_VERSION) {\n throw new Error(\n `[faijs] library with dual-op functions must export contractVersion = ${CONTRACT_VERSION} (got ${String(lib.contractVersion)})`,\n )\n }\n\n for (const [name, value] of Object.entries(lib)) {\n if (typeof value !== 'function') continue\n const meta = (value as MetaCarrier)[DUAL_OP_META]\n if (!meta || meta.kind !== 'dual-op') continue\n if (typeof meta.mesh !== 'function' && typeof meta.brep !== 'function') {\n throw new Error(`[faijs] lib function '${name}' declares dual-op without any implementation`)\n }\n if (meta.mesh !== undefined && typeof meta.mesh !== 'function') {\n throw new Error(`[faijs] lib function '${name}' declares dual-op with a non-function mesh implementation`)\n }\n if (meta.brep !== undefined && typeof meta.brep !== 'function') {\n throw new Error(`[faijs] lib function '${name}' declares dual-op with a non-function brep implementation`)\n }\n if (meta.capabilities !== undefined && !Array.isArray(meta.capabilities)) {\n throw new Error(`[faijs] lib function '${name}' declares invalid capabilities (expected string[])`)\n }\n // D11-7 互斥**已撤销**(2026-09-24 用户裁决):engines 与 capabilities 是两条正交的\n // 声明轴——前者是引擎身份白名单(在哪些引擎上跑),后者是实现所需内核能力清单\n // (要用哪些方法)。两者并存是合法且更诚实的写法:engines 收窄候选集,能力门随后\n // 对同一引擎继续求交(dispatchPath 的求值次序本就是 engines 在先,D11-2)。\n // 曾经的理由「能力名空间只收 L1 中立名」与事实不符——BrepCapabilityName 含\n // BrepMethodKind 逐核真名(isNull / dispose / chamfer / shell / ...,见\n // brep/engine/types.ts),本就是内核名空间;平台 op 声明能力名并不越界。\n // 故此处不再校验两者是否同时出现。\n if (meta.engines !== undefined) {\n if (!Array.isArray(meta.engines) || meta.engines.length === 0) {\n throw new Error(`[faijs] lib function '${name}' declares invalid engines (expected non-empty BrepEngineId[])`)\n }\n const bad = meta.engines.find((e) => !BREP_ENGINE_ID_SET.has(e))\n if (bad !== undefined) {\n throw new Error(\n `[faijs] lib function '${name}' declares unknown engine '${String(bad)}' — expected one of ${BREP_ENGINE_IDS.join(', ')}`,\n )\n }\n }\n if (\n meta.outputs !== undefined\n && (!Array.isArray(meta.outputs) || meta.outputs.some((k) => typeof k !== 'string'))\n ) {\n throw new Error(`[faijs] lib function '${name}' declares invalid outputs (expected string[])`)\n }\n if (meta.schema !== undefined && !isValidSchema(meta.schema)) {\n throw new Error(`[faijs] lib function '${name}' declares invalid schema (expected Record<string, string>)`)\n }\n if (meta.name !== undefined && typeof meta.name !== 'string') {\n throw new Error(`[faijs] lib function '${name}' declares invalid name (expected string)`)\n }\n if (meta.slotMap !== undefined && !isValidSlotMap(meta.slotMap)) {\n throw new Error(\n `[faijs] lib function '${name}' declares invalid slotMap (expected { keys: string[]; vec3Keys?: string[]; shapeArity?: number })`,\n )\n }\n }\n}\n\n/** True when the D11 slot-map declaration has a non-empty string `keys` list. */\nfunction isValidSlotMap(form: unknown): form is SlotMap {\n if (form === null || typeof form !== 'object') return false\n const keys = (form as { keys?: unknown }).keys\n if (!Array.isArray(keys) || keys.some((k) => typeof k !== 'string')) return false\n const vec3 = (form as { vec3Keys?: unknown }).vec3Keys\n if (vec3 !== undefined && (!Array.isArray(vec3) || vec3.some((k) => typeof k !== 'string'))) return false\n const arity = (form as { shapeArity?: unknown }).shapeArity\n if (arity !== undefined && (typeof arity !== 'number' || !Number.isInteger(arity) || arity < 0)) return false\n return true\n}\n\n/** True when every schema value is a non-empty string. */\nfunction isValidSchema(schema: unknown): schema is Record<string, string> {\n if (schema === null || typeof schema !== 'object' || Array.isArray(schema)) return false\n return Object.values(schema).every((v) => typeof v === 'string' && v.length > 0)\n}\n"]}
1
+ {"version":3,"file":"define-op.js","sourceRoot":"","sources":["../src/define-op.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * define-op — dual-path implementation decorator for geometry functions\n * (D-face contract: mesh mandatory as the default path, BREP optional).\n *\n *\n * `defineOp({ mesh?, brep?, ... })` declares the implementation set of a\n * geometry function (a function whose signature returns `SolidShape`). The\n * wrapper:\n * - auto-collects geometry inputs via `args.filter(isGeometryInput)` — a shape\n * that is identity-registered (`isShape`) or a structural mesh shape\n * (`isMeshShape`, positions + indices — e.g. bare ManifoldMeshData handed in\n * by a host via `geoToManifoldMesh`). The old per-function form passed the\n * actual geometry args (`dispatchPath([input], ...)`), so a bare mesh input\n * dispatched to the mesh path (`hasBrep=false`); the re-collection must keep\n * that compatibility. No `inputs` field — decided at runtime by the args\n * themselves, not the author.\n * - calls the engine's `dispatchPath` to select brep/mesh by mode (static,\n * no runtime fallback);\n * - wraps raw products: mesh path → `solid()`, brep path → `fromHandle()` /\n * `fromBrep()` (D3/D4: products must come from constructors, brep products\n * must carry a BREP slot).\n *\n * Zero heavy runtime dependencies: imports only runtime-state / shape /\n * handle-bridge / backend-dispatch / mesh/types (a zero-import module holding\n * the Shape type and the structural `isMeshShape` guard) — the dist/sdk.js\n * static-import guard keeps passing.\n */\n\nimport { dispatchPath, firstMissingCapability, type BrepCapabilityName } from './cad-runtime/backend-dispatch'\nimport {\n CONTRACT_VERSION,\n BrepUnsupportedError,\n MeshUnsupportedError,\n getCurrentStmt,\n getRuntimeState,\n nameOf,\n} from './runtime-state'\nimport { asStmtId, type PartName } from './identity'\nimport { isShape, solid, fromBrep, getSlot } from './shape'\nimport { isMeshShape } from './mesh/types'\nimport { fromHandle, meshHandle, isOcctHandle } from './brep/handle-bridge'\nimport { positionalToObject, type SlotMap } from './api/internal/dual-form-args'\nimport { toOpFailure, unwrapResult, OpError, type ResultLike } from './api/internal/result-unwrap'\nimport type { Shape } from './mesh/types'\nimport { BREP_ENGINE_IDS, type BrepEngineId, type BrepHandle } from './brep/engine/types'\nimport type { DimName } from './units'\nimport { type Provenance, runtimeLineage } from './topology/naming/lineage'\n\n/** 合法引擎 id 集合(assertLibConforms 的 engines 校验用,D11-1)。 */\nconst BREP_ENGINE_ID_SET = new Set<string>(BREP_ENGINE_IDS)\n\n/** Raw mesh data (structurally identical to Shape; mesh impls return it). */\nexport type MeshData = { positions: Float32Array; indices: Uint32Array }\n\n/**\n * Geometry-input recognition for dispatch auto-collection.\n *\n * Compat rule: the old per-function form passed the *actual* geometry args to\n * `dispatchPath` (`[input]` / `shapes`), so a bare ManifoldMeshData object\n * (e.g. `geoToManifoldMesh` output passed straight by a host) had no BREP slot\n * → `hasBrep=false` → mesh path. defineOp must keep that: an input counts as\n * geometry when it is identity-registered (`isShape`, constructor product) OR\n * structurally a mesh shape (`positions` + `indices`). Params objects and other\n * scalar args are not geometry inputs.\n *\n * @param v - the candidate argument.\n * @returns true when the argument is a geometry input (registered shape or bare mesh data).\n */\nexport function isGeometryInput(v: unknown): v is Shape {\n return isShape(v) || isMeshShape(v)\n}\n\n/**\n * §1.4 registration guard: the StmtId whose top-level `wrapped` is currently\n * registering a lineage node. Nested op calls (an impl invoking another op /\n * itself) share the same `getCurrentStmt()` anchor and are skipped so they\n * don't trip N3 (E_TOPO_DUPLICATE_STMT) with identical content. C1 (single\n * live runtime) means at most one statement registers at a time.\n *\n * The marker lives on the runtime state and is reset at statement boundaries\n * (runtime-state.setCurrentStmt: anchor change / end-of-statement), NOT at op\n * granularity — a TS library function (cq-compat Workplane op, etc.) may call\n * several defineOps within one statement, and only the first one must register.\n */\n\n/** Product of a mesh implementation: raw mesh data, a wrapped Shape, or (with `outputs`) a record of named products. */\nexport type MeshProduct = MeshData | Shape | Record<string, MeshData | Shape>\n\n/** Mesh implementation: sync or async (stdlib mesh paths are often async); returns a mesh product. */\nexport type MeshImpl<A extends unknown[]> = (...args: A) => MeshProduct | Promise<MeshProduct>\n\n/** BREP implementation result: a raw handle, or a handle plus face evolution. */\nexport interface BrepResult {\n solid: BrepHandle\n faceEvolution?: Map<number, number[]>\n}\n\n/** Product of a BREP implementation: a raw handle, { solid, faceEvolution }, a wrapped Shape, or (with `outputs`) a record of named products. */\nexport type BrepProduct =\n | BrepHandle\n | BrepResult\n | Shape\n | Record<string, BrepHandle | BrepResult | Shape>\n | ResultLike\n\n/** BREP implementation: sync or async; returns a brep product. */\nexport type BrepImpl<A extends unknown[]> = (...args: A) => BrepProduct | Promise<BrepProduct>\n\n/** Optional declaration: capabilities (D5) and named multi-products (split, scheme C). */\nexport interface DualOpOptions {\n /** Op name (error messages); falls back to an anonymous prefix when absent. */\n name?: string\n capabilities?: BrepCapabilityName[]\n /**\n * 平台身份声明(D11,narrowing plan 2026-09-24):本 op 实现可运行在哪些\n * BREP 引擎上——一个**引擎白名单**。缺省 = 全平台(中立 op——实现只用 L1 核心面)。\n *\n * 平台 op(实现 import 了 `occt-kernel/*` / `brepkit-kernel/*`,调用该平台\n * 原生方法)**必须**声明 `engines` 自证身份。\n *\n * 与 `capabilities` **可以并存**(2026-09-24 撤销 D11-7 互斥):两者是正交的两轴——\n * `engines` 收窄「在哪些引擎上跑」,`capabilities` 声明「需要哪些内核能力」。判定\n * 次序 `engines` 在先(D11-2),能力门随后对同一引擎继续求交,故同时声明等于\n * 「只在这些引擎上,且要求这些能力」——不会静默放行\"目标引擎缺该能力\"的组合。\n */\n engines?: readonly BrepEngineId[]\n outputs?: string[]\n /** L3 schema per named parameter (G1 codegen + UI panel, plain string form). */\n schema?: Record<string, string>\n /**\n * D11 slot-map declaration (§4.2): the positional→object boxing table\n * (SlotMap) mapping a brepjs-style positional call onto this op's native\n * object form. Ops without it accept only the form their implementation\n * natively takes.\n */\n slotMap?: SlotMap\n /**\n * Topology identity provenance (plan §4.4 / Phase 2.3, **required**).\n * Declares the op's face-mapping category + new-face vocabulary.\n * The lineage registrar (§4.3) reads this to build the blood-line graph;\n * missing naming = compile-time error (G4: no undeclared ops).\n */\n naming: Provenance\n /**\n * Script-side dimension declaration (unit-system D8): per-parameter dim for\n * the static `dimension` check stage. Params absent here are treated as\n * dimensionless and exempt from the check. `DimName` is a pure type import.\n */\n paramDims?: Record<string, DimName>\n /** Return dimension declaration (D8): the value produced carries this dim. */\n retDim?: DimName\n}\n\n/** Implementation set (at least one of mesh/brep is required, D1/D1b); options are siblings of the implementations. */\nexport type DualOpImpls<A extends unknown[]> =\n | (DualOpOptions & { mesh: MeshImpl<A>; brep?: BrepImpl<A> })\n | (DualOpOptions & { mesh?: never; brep: BrepImpl<A> })\n\n/** Metadata hung on the wrapped function object (K5: function info is data). */\nexport interface DualOpMeta {\n kind: 'dual-op'\n mesh?: unknown\n brep?: unknown\n /** Op name (error messages). */\n name?: string\n capabilities?: BrepCapabilityName[]\n /** 平台身份声明(D11,镜像 DualOpOptions.engines)。 */\n engines?: readonly BrepEngineId[]\n outputs?: string[]\n schema?: Record<string, string>\n /** D11 slot-map declaration (positional → object boxing table, §9 naming). */\n slotMap?: SlotMap\n /** Topology identity provenance (Phase 2.3, mirrors DualOpOptions.naming). */\n naming: Provenance\n /** Script-side dimension declaration (D8, mirrors DualOpOptions.paramDims). */\n paramDims?: Record<string, DimName>\n /** Return dimension declaration (D8). */\n retDim?: DimName\n}\n\n/** Property key carrying DualOpMeta on wrapped functions. */\nexport const DUAL_OP_META = '__faijs__dualOp'\n\ntype MetaCarrier = { [DUAL_OP_META]?: DualOpMeta }\n\nfunction wrapMeshOne(v: unknown): Shape {\n if (isShape(v)) return v\n return solid(v as MeshData)\n}\n\nfunction wrapBrepOne(v: unknown): Shape {\n if (isShape(v)) return v\n if (v !== null && typeof v === 'object' && 'faceEvolution' in v) {\n const res = v as BrepResult\n return fromBrep(meshHandle(res.solid), res)\n }\n // A plain object that is not a Shape and not an OCCT handle is a data\n // product (e.g. a compat fn returning a sheetmetal-style record), not a\n // geometry handle — pass it through so it lands in the engine's value\n // store instead of being tessellated as if it were a bare handle. Native\n // OCCT handles from an implementation are hand-computed shape numbers\n // (from a branded number return) or objects; only the number path reaches\n // fromHandle. The handle/data distinction must go through the shared\n // isOcctHandle leaf (handle-bridge) — never a hardcoded '__occtWasm' in v.\n if (v !== null && typeof v === 'object' && !isOcctHandle(v)) {\n return v as unknown as Shape\n }\n return fromHandle(v)\n}\n\nfunction wrapByKeys(r: unknown, keys: string[], wrapOne: (v: unknown) => Shape): Record<string, Shape> {\n const src = (r ?? {}) as Record<string, unknown>\n const out: Record<string, Shape> = {}\n for (const k of keys) {\n const v = src[k]\n // An output may be an array (e.g. the compat adapter adopts each element of\n // an array-valued `outputs` field); wrap element-wise so arrays stay arrays.\n out[k] = Array.isArray(v) ? (v.map(wrapOne) as unknown as Shape) : wrapOne(v)\n }\n // Pass through non-shape data keys (e.g. autoHeal's `report`): declared\n // outputs are the geometry that gets Shape-wrapped, but sibling data products\n // of the same op result must survive the statement boundary (§5.4 selfhost).\n for (const k of Object.keys(src)) {\n if (!keys.includes(k)) out[k] = src[k] as unknown as Shape\n }\n return out\n}\n\n/** Human-readable op label for error messages (falls back when unnamed). */\nfunction opLabel(meta: DualOpMeta): string {\n return meta.name ?? '<anon>'\n}\n\n/**\n * Run one implementation through the unified Result boundary (§5.2, D1).\n *\n * Transition contract: an implementation may\n * ① return a `Result` → unwrapped here (`err` becomes a throw);\n * ② throw → normalized into an op-labelled error;\n * ③ return a plain product → passed through untouched.\n *\n * The two engine-level routing errors keep their class: `runtime.ts` matches\n * `BrepUnsupportedError` / `MeshUnsupportedError` by `instanceof` to turn them\n * into `ExecutionResult.failedAt`, so they must not be re-wrapped.\n *\n * @param meta - the op's metadata (name).\n * @param impl - the implementation to run.\n * @param args - the normalized argument list.\n * @returns the (unwrapped) implementation product.\n */\nasync function runImpl(\n meta: DualOpMeta,\n impl: ((...a: unknown[]) => unknown) | undefined,\n args: unknown[],\n): Promise<unknown> {\n const label = opLabel(meta)\n let product: unknown\n try {\n product = await (impl as (...a: unknown[]) => unknown)(...args)\n } catch (e) {\n if (e instanceof BrepUnsupportedError || e instanceof MeshUnsupportedError) throw e\n // An OpError is already the engine-recognizable statement failure (thrown\n // by the compat adapter's Result unwrap, or by impls returning a Result);\n // re-wrapping it into a plain Error would make CadRuntime treat it as an\n // uncaught bug instead of a statement failure.\n if (e instanceof OpError) throw e\n throw toOpFailure(label, e)\n }\n return unwrapResult(product, label)\n}\n\n/**\n * Declare a geometry function's dual-path implementation set.\n *\n * At least one implementation (mesh or brep) is required — enforced at\n * compile time by the union type and at construction time by a runtime check.\n * Geometry inputs are auto-collected by identity-or-structure\n * (`args.filter(isGeometryInput)` = `isShape` ∨ `isMeshShape`); raw mesh\n * products are wrapped by `solid()`, raw brep products by\n * `fromHandle()` / `fromBrep()`. `mode` selects the engine path via the\n * engine's static `dispatchPath` — the author never writes an `if (path)`\n * branch.\n *\n * @param decl - the declaration object: implementations `{ mesh }` (mesh-only),\n * `{ brep }` (brep-only, D1b), or `{ mesh, brep }` (dual-path), plus optional\n * `capabilities` (D5: missing capability degrades in auto, errors in brep mode)\n * and `outputs` (named multi-products, e.g. split) as siblings.\n * @returns the wrapped geometry function with dual-op metadata attached.\n */\nexport function defineOp<A extends unknown[]>(\n decl: DualOpImpls<A> & { outputs: string[] },\n): ((...args: A) => Promise<Record<string, Shape>>) & MetaCarrier\n/**\n * Overload without `outputs`: single-product functions resolve to a `Promise<Shape>`.\n * @param decl - the declaration object: implementations `{ mesh }`, `{ brep }`, or `{ mesh, brep }`.\n * @returns the wrapped geometry function with dual-op metadata attached.\n */\nexport function defineOp<A extends unknown[]>(\n decl: DualOpImpls<A>,\n): ((...args: A) => Promise<Shape>) & MetaCarrier\n/** Implementation signature (not visible to callers); matches the union of both overloads. */\nexport function defineOp<A extends unknown[]>(\n decl: DualOpImpls<A>,\n): ((...args: A) => Promise<Shape | Record<string, Shape>>) & MetaCarrier {\n // Construction-time check (②): implementations must be functions, then at\n // least one implementation must be present.\n if (decl.mesh !== undefined && typeof decl.mesh !== 'function') {\n throw new Error('[faijs/defineOp] mesh must be a function')\n }\n if (decl.brep !== undefined && typeof decl.brep !== 'function') {\n throw new Error('[faijs/defineOp] brep must be a function')\n }\n if (typeof decl.mesh !== 'function' && typeof decl.brep !== 'function') {\n throw new Error('[faijs/defineOp] at least one implementation (mesh or brep) is required')\n }\n\n const meta: DualOpMeta = {\n kind: 'dual-op',\n mesh: decl.mesh,\n brep: decl.brep,\n name: decl.name,\n capabilities: decl.capabilities,\n engines: decl.engines,\n outputs: decl.outputs,\n schema: decl.schema,\n slotMap: decl.slotMap,\n naming: decl.naming,\n paramDims: decl.paramDims,\n retDim: decl.retDim,\n }\n\n // Async wrapper: implementations may be sync or async (stdlib mesh paths are\n // often async, e.g. drill/engrave/boolean). The compiled .fai.js product always\n // awaits the call, so returning a Promise is transparent.\n const wrapped = async (...args: A): Promise<Shape | Record<string, Shape>> => {\n // D11 (§4.2): faijs-native ops declare an object-form implementation, so a\n // brepjs-style positional call is boxed into the object form here — before\n // dispatch, so geometry inputs are collected from the normalized arg list.\n const callArgs = (\n meta.slotMap ? positionalToObject(args as unknown[], meta.slotMap, opLabel(meta)) : args\n ) as A\n // Geometry inputs: identity-or-structure auto collection (execution-time\n // read, same nature as hasBrep — decided before the implementation runs).\n // Compat: bare ManifoldMeshData args (host geoToManifoldMesh output) are\n // geometry inputs too — old form passed [input] so they reached the mesh path.\n const inputs = (callArgs as unknown[]).filter(isGeometryInput) as Shape[]\n // §1.4 lineage registration (plan §4.3): every top-level dual-op execution\n // records a blood-line node via `runtimeLineage.register`, which enforces\n // N1 (untracked input → throw, never default to chain-root) / N2\n // (stmt↔anchor mismatch) / N3 (conflicting re-register). The graph is\n // cleared per program execution (direct-executor runCode) and C1 guarantees\n // a single live runtime, so the anchor is authoritative inside a statement.\n // Skip when no anchor is set (the op was invoked outside a statement\n // context — there is no lineage to record, and N2 must not fire on a context\n // that legitimately has none).\n //\n // Guard: a statement executes exactly one *top-level* op; an op's\n // implementation may invoke other ops (or itself) internally, and those\n // nested calls share the same `getCurrentStmt()` anchor. They are\n // implementation details, not statements, so they must NOT register a second\n // node under the same StmtId — that would trip N3 (E_TOPO_DUPLICATE_STMT)\n // on identical content. Only the outermost `wrapped` for the current\n // statement registers; the flag below stays set for the *entire* statement\n // execution (including the awaited impl), so nested calls see it and skip.\n const anchor = getCurrentStmt()\n const st = getRuntimeState()\n const isOuter = anchor != null && st.registeredStmtId !== anchor.id\n if (isOuter) st.registeredStmtId = asStmtId(anchor.id)\n try {\n if (isOuter && anchor) {\n runtimeLineage.register(\n {\n stmt: asStmtId(anchor.id),\n op: opLabel(meta),\n inputs,\n outputs: anchor.outputs as [PartName, ...PartName[]],\n provenance: meta.naming,\n },\n {\n nameOf,\n currentStmt: () => {\n const a = getCurrentStmt()\n return a ? { id: a.id } : undefined\n },\n },\n )\n }\n // D5 capability routing: feed the first missing capability to dispatchPath\n // (auto degrades to mesh, brep mode errors). Matched as a concrete name\n // against the engine's declaration set (family booleans + its `evolution`\n // list of *WithHistory kernel function names) — see firstMissingCapability.\n const missing = firstMissingCapability(meta.capabilities)\n const path = dispatchPath(inputs, meta, missing, meta.engines)\n if (path === 'brep') {\n const r = await runImpl(meta, decl.brep as unknown as ((...a: unknown[]) => unknown) | undefined, callArgs)\n const out = meta.outputs ? wrapByKeys(r, meta.outputs, wrapBrepOne) : wrapBrepOne(r)\n // 1.10 前置①:执行期把 hash 演化挂到血缘节点(kernel 类回走推进的数据源)。\n // 演化在几何算完那一刻可得(fromBrep → slot.faceEvolution),事后补挂不参与\n // N3 的内容比较(lineage.ts 设计如此)。无演化(identity/construct 等无历史\n // 输出)时跳过——identity 类推进不依赖演化,construct 词汇在节点 provenance 里。\n const outShape = (typeof out === 'object' && out !== null ? Object.values(out)[0] : out) as Shape | undefined\n const evolution = outShape ? getSlot(outShape)?.faceEvolution : undefined\n if (outShape && evolution) {\n runtimeLineage.attachEvolution(asStmtId(anchor!.id), evolution)\n }\n // 1.10 前置③:part 键的 roleTable 旁挂在这里记录(不是 fromBrep)——\n // impl 返回后 anchor.outputs 名字已定,而 fromBrep 时刻 shape 还未被\n // executor 命名(nameOf 为 undefined)。op 实现读输入表(inputRoleTable)\n // 与解析读表(tableOfPart)都走这份 part 键权威表。\n if (outShape && anchor && anchor.outputs.length > 0) {\n const stmtId = asStmtId(anchor.id)\n const table = runtimeLineage.outputTableOf(stmtId)\n const solid = runtimeLineage.outputHandleOf(stmtId)\n if (table) runtimeLineage.recordOutput(stmtId, table, solid, anchor.outputs[0] as PartName)\n }\n return out\n }\n const m = await runImpl(meta, decl.mesh as unknown as ((...a: unknown[]) => unknown) | undefined, callArgs)\n return meta.outputs ? wrapByKeys(m, meta.outputs, wrapMeshOne) : wrapMeshOne(m)\n } finally {\n // 同语句去重标记不在 op 粒度清理——语句边界由 runtime-state.setCurrentStmt\n // 在锚点变化时重置;TS 库函数体内连续 op 调用共享锚点,嵌套调用正确跳过。\n }\n }\n\n Object.defineProperty(wrapped, DUAL_OP_META, { value: meta, enumerable: false })\n return wrapped as ((...args: A) => Promise<Shape | Record<string, Shape>>) & MetaCarrier\n}\n\n/**\n * Assembly-time validation (③, strict mode, D-4): a library that exports any\n * dual-op function must carry a matching `contractVersion`, and every exported\n * dual-op must be structurally valid (mesh a function, brep a function or\n * undefined, capabilities/outputs well-formed). Called by `registerLib`.\n *\n * Functions without dual-op metadata are left untouched (declarative\n * enforcement boundary — K5 forbids name-based classification).\n *\n * @param lib - the library namespace object being registered.\n */\n/**\n * Detect whether a library namespace exports any dual-op function (carries\n * `DUAL_OP_META`). Used by `registerLib`'s inferred `autoLift` default: a\n * library that already declares dual-ops does not need bare-function lifting.\n *\n * @param ns - the library namespace object.\n * @returns `true` if at least one exported value is a dual-op function.\n */\nexport function hasDualOp(ns: Record<string, unknown>): boolean {\n const values = Object.values(ns)\n return values.some((v) => typeof v === 'function' && (v as MetaCarrier)[DUAL_OP_META])\n}\n\n/**\n * Read the dual-op metadata of a wrapped function (unit-system D8 declaration\n * surface). Returns `undefined` when the function carries no dual-op metadata,\n * so callers never probe the private key directly.\n *\n * @param fn - a function that may have been produced by `defineOp`/`compatOp`.\n * @returns the op's metadata, or `undefined`.\n */\nexport function dualOpMetaOf(fn: unknown): DualOpMeta | undefined {\n if (typeof fn !== 'function') return undefined\n return (fn as MetaCarrier)[DUAL_OP_META]\n}\n\n/**\n * Assert that a library conforms to the dual-op contract: if it exports any\n * dual-op function, it must also export `contractVersion` matching the engine's.\n *\n * @param lib - the library namespace object being registered.\n * @throws {Error} when dual-op functions are present without a matching contract version.\n */\nexport function assertLibConforms(lib: Record<string, unknown>): void {\n if (hasDualOp(lib) && lib.contractVersion !== CONTRACT_VERSION) {\n throw new Error(\n `[faijs] library with dual-op functions must export contractVersion = ${CONTRACT_VERSION} (got ${String(lib.contractVersion)})`,\n )\n }\n\n for (const [name, value] of Object.entries(lib)) {\n if (typeof value !== 'function') continue\n const meta = (value as MetaCarrier)[DUAL_OP_META]\n if (!meta || meta.kind !== 'dual-op') continue\n if (typeof meta.mesh !== 'function' && typeof meta.brep !== 'function') {\n throw new Error(`[faijs] lib function '${name}' declares dual-op without any implementation`)\n }\n if (meta.mesh !== undefined && typeof meta.mesh !== 'function') {\n throw new Error(`[faijs] lib function '${name}' declares dual-op with a non-function mesh implementation`)\n }\n if (meta.brep !== undefined && typeof meta.brep !== 'function') {\n throw new Error(`[faijs] lib function '${name}' declares dual-op with a non-function brep implementation`)\n }\n if (meta.capabilities !== undefined && !Array.isArray(meta.capabilities)) {\n throw new Error(`[faijs] lib function '${name}' declares invalid capabilities (expected string[])`)\n }\n // D11-7 互斥**已撤销**(2026-09-24 用户裁决):engines 与 capabilities 是两条正交的\n // 声明轴——前者是引擎身份白名单(在哪些引擎上跑),后者是实现所需内核能力清单\n // (要用哪些方法)。两者并存是合法且更诚实的写法:engines 收窄候选集,能力门随后\n // 对同一引擎继续求交(dispatchPath 的求值次序本就是 engines 在先,D11-2)。\n // 曾经的理由「能力名空间只收 L1 中立名」与事实不符——BrepCapabilityName 含\n // BrepMethodKind 逐核真名(isNull / dispose / chamfer / shell / ...,见\n // brep/engine/types.ts),本就是内核名空间;平台 op 声明能力名并不越界。\n // 故此处不再校验两者是否同时出现。\n if (meta.engines !== undefined) {\n if (!Array.isArray(meta.engines) || meta.engines.length === 0) {\n throw new Error(`[faijs] lib function '${name}' declares invalid engines (expected non-empty BrepEngineId[])`)\n }\n const bad = meta.engines.find((e) => !BREP_ENGINE_ID_SET.has(e))\n if (bad !== undefined) {\n throw new Error(\n `[faijs] lib function '${name}' declares unknown engine '${String(bad)}' — expected one of ${BREP_ENGINE_IDS.join(', ')}`,\n )\n }\n }\n if (\n meta.outputs !== undefined\n && (!Array.isArray(meta.outputs) || meta.outputs.some((k) => typeof k !== 'string'))\n ) {\n throw new Error(`[faijs] lib function '${name}' declares invalid outputs (expected string[])`)\n }\n if (meta.schema !== undefined && !isValidSchema(meta.schema)) {\n throw new Error(`[faijs] lib function '${name}' declares invalid schema (expected Record<string, string>)`)\n }\n if (meta.name !== undefined && typeof meta.name !== 'string') {\n throw new Error(`[faijs] lib function '${name}' declares invalid name (expected string)`)\n }\n if (meta.slotMap !== undefined && !isValidSlotMap(meta.slotMap)) {\n throw new Error(\n `[faijs] lib function '${name}' declares invalid slotMap (expected { keys: string[]; vec3Keys?: string[]; shapeArity?: number })`,\n )\n }\n }\n}\n\n/** True when the D11 slot-map declaration has a non-empty string `keys` list. */\nfunction isValidSlotMap(form: unknown): form is SlotMap {\n if (form === null || typeof form !== 'object') return false\n const keys = (form as { keys?: unknown }).keys\n if (!Array.isArray(keys) || keys.some((k) => typeof k !== 'string')) return false\n const vec3 = (form as { vec3Keys?: unknown }).vec3Keys\n if (vec3 !== undefined && (!Array.isArray(vec3) || vec3.some((k) => typeof k !== 'string'))) return false\n const arity = (form as { shapeArity?: unknown }).shapeArity\n if (arity !== undefined && (typeof arity !== 'number' || !Number.isInteger(arity) || arity < 0)) return false\n return true\n}\n\n/** True when every schema value is a non-empty string. */\nfunction isValidSchema(schema: unknown): schema is Record<string, string> {\n if (schema === null || typeof schema !== 'object' || Array.isArray(schema)) return false\n return Object.values(schema).every((v) => typeof v === 'string' && v.length > 0)\n}\n"]}
@@ -13,20 +13,20 @@
13
13
  */
14
14
  export type { FileId, InnerId, ScopedId, StmtId, PartName, GroupName, RefId, ReferenceId, SelectorKey, OccurrenceId, ShapeId, FaceId, EdgeId, NodeId, StatementId, FaceSelector, } from './identity.js';
15
15
  export { asFileId, asInnerId, asScopedId, asStmtId, asPartName, asGroupName, asRefId, asReferenceId, asSelectorKey, asOccurrenceId, asShapeId, asFaceId, asEdgeId, asNodeId, toScopedId, splitScopedId, isScopedId, toInnerId, } from './identity.js';
16
- export { configureBackends, getBackends, setCurrentStmt, getCurrentStmt, keep, keepHidden, getRuntimeState, nameOf, setName, setKeepSink, setPendingAssemblyTransforms, takePendingAssemblyTransforms, assertContractVersion, CONTRACT_VERSION, } from './runtime-state.js';
17
- export type { Backends, FaijsRuntimeState, ShapeSlot, KeepSink, RuntimeExecutionMode, AssemblyTransform, StdlibFn, StdlibNamespace, ExecutionAnchor, } from './runtime-state.js';
16
+ export { configureBackends, getBackends, setCurrentStmt, getCurrentStmt, keep, keepHidden, getRuntimeState, nameOf, setName, setKeepSink, setPendingAssemblyTransforms, takePendingAssemblyTransforms, assertContractVersion, setPendingDetectedUnit, takePendingDetectedUnits, CONTRACT_VERSION, } from './runtime-state.js';
17
+ export type { Backends, FaijsRuntimeState, ShapeSlot, KeepSink, RuntimeExecutionMode, AssemblyTransform, StdlibFn, StdlibNamespace, ExecutionAnchor, DetectedUnits, } from './runtime-state.js';
18
18
  export type { Vec3, JsonValue, TerminalShape, ParamDef, } from './lang/types.js';
19
19
  export type { Provenance, NewFaceRule } from './topology/naming/lineage.js';
20
20
  export { derivePartName, getMaxModelNum, } from './lang/allocate-id.js';
21
21
  export type { DerivePartNameInput, DerivePartNameResult } from './lang/allocate-id.js';
22
- export { fmtNum, formatCodeLine } from './lang/codegen.js';
23
- export type { FormatCodeLineInput } from './lang/codegen.js';
22
+ export { fmtNum, formatCodeLine, fmtUnitNum, formatUnitLiteral } from './lang/codegen.js';
23
+ export type { FormatCodeLineInput, UnitSerializeOptions } from './lang/codegen.js';
24
24
  export { analyzeCode } from './lang/statement-summary.js';
25
25
  export type { StatementSummary } from './lang/statement-summary.js';
26
- export { codeToArgs } from './lang/code-to-args.js';
27
- export type { CodeToArgsResult } from './lang/code-to-args.js';
26
+ export { codeToArgs, parseUnitLiteral } from './lang/code-to-args.js';
27
+ export type { CodeToArgsResult, CodeToArgsOptions } from './lang/code-to-args.js';
28
28
  export { extractMetadata } from './lang/metadata-extractor.js';
29
- export type { UiMetadata, ArgSource, ParamEntry, ImportEntry, FunctionEntry, BlockEntry, KeepEntry, ExtractMetadataOptions, } from './lang/metadata-extractor.js';
29
+ export type { UiMetadata, ArgSource, ParamEntry, ImportEntry, FunctionEntry, BlockEntry, KeepEntry, ExtractMetadataOptions, OpDimMap, OpDimDecl, } from './lang/metadata-extractor.js';
30
30
  export { scanSource, scanAst, assertSecure } from './lang/security-scanner.js';
31
31
  export type { SecurityPolicy, SecurityRuleId, SecurityViolation, SecurityScanOptions, SecurityScanResult, } from './lang/security-scanner.js';
32
32
  export { validateExpression } from './lang/expr-validate.js';
@@ -1 +1 @@
1
- {"version":3,"file":"env-agnostic.d.ts","sourceRoot":"","sources":["../src/env-agnostic.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"env-agnostic.d.ts","sourceRoot":"","sources":["../src/env-agnostic.ts"],"names":[],"mappings":"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"}
@@ -13,11 +13,11 @@
13
13
  */
14
14
  export { asFileId, asInnerId, asScopedId, asStmtId, asPartName, asGroupName, asRefId, asReferenceId, asSelectorKey, asOccurrenceId, asShapeId, asFaceId, asEdgeId, asNodeId, toScopedId, splitScopedId, isScopedId, toInnerId, } from './identity.js';
15
15
  // ── runtime-state:运行时状态锚点(零依赖层;引擎与库共享)──
16
- export { configureBackends, getBackends, setCurrentStmt, getCurrentStmt, keep, keepHidden, getRuntimeState, nameOf, setName, setKeepSink, setPendingAssemblyTransforms, takePendingAssemblyTransforms, assertContractVersion, CONTRACT_VERSION, } from './runtime-state.js';
16
+ export { configureBackends, getBackends, setCurrentStmt, getCurrentStmt, keep, keepHidden, getRuntimeState, nameOf, setName, setKeepSink, setPendingAssemblyTransforms, takePendingAssemblyTransforms, assertContractVersion, setPendingDetectedUnit, takePendingDetectedUnits, CONTRACT_VERSION, } from './runtime-state.js';
17
17
  export { derivePartName, getMaxModelNum, } from './lang/allocate-id.js';
18
- export { fmtNum, formatCodeLine } from './lang/codegen.js';
18
+ export { fmtNum, formatCodeLine, fmtUnitNum, formatUnitLiteral } from './lang/codegen.js';
19
19
  export { analyzeCode } from './lang/statement-summary.js';
20
- export { codeToArgs } from './lang/code-to-args.js';
20
+ export { codeToArgs, parseUnitLiteral } from './lang/code-to-args.js';
21
21
  // MetadataExtractor — 无 IR 元数据提取器(UI 通道语义源;UiMetadata 全量)
22
22
  export { extractMetadata } from './lang/metadata-extractor.js';
23
23
  // SecurityScanner — 静态安全门禁(纵深防御第一层)
@@ -1 +1 @@
1
- {"version":3,"file":"env-agnostic.js","sourceRoot":"","sources":["../src/env-agnostic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH,OAAO,EACL,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAClE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,SAAS,EAChE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAC5B,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,GACjD,MAAM,YAAY,CAAA;AAEnB,0CAA0C;AAC1C,OAAO,EACL,iBAAiB,EAAE,WAAW,EAAE,cAAc,EAAE,cAAc,EAC9D,IAAI,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAC/D,4BAA4B,EAAE,6BAA6B,EAAE,qBAAqB,EAClF,gBAAgB,GACjB,MAAM,iBAAiB,CAAA;AAaxB,OAAO,EACL,cAAc,EAAE,cAAc,GAC/B,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEvD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAEtD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAEhD,0DAA0D;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAK3D,oCAAoC;AACpC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAK3E,qCAAqC;AACrC,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAEzD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAMlD,OAAO,EACL,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,SAAS,EACrE,gBAAgB,EAAE,gBAAgB,EAAE,cAAc,GACnD,MAAM,iBAAiB,CAAA;AAExB,+BAA+B;AAC/B,gEAAgE;AAChE,mEAAmE;AACnE,+DAA+D;AAC/D,0EAA0E;AAC1E,qDAAqD;AACrD,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAA","sourcesContent":["/**\n * env-agnostic.ts — environment-agnostic shared surface (weapp plan §9.1)\n *\n * One home for the exports that every host entry (index / browser / weapp)\n * must share: identity + runtime-state + lang/* text-layer tools. Umbrella\n * entries re-export this module instead of hand-listing the same symbols three\n * times — hand lists are how drift (and entry leaks) happened before.\n *\n * Constraint: NOTHING in this module's dependency graph may be\n * platform-specific. No node:*, no DOM, no three (the weapp main thread holds\n * its own three copy — a second copy via this entry is a hard failure), no\n * brepkit, no wasm loaders. Guarded by entry-boundary.test.ts.\n */\n\n// ── identity:品牌类型 + 信任点(f0,零依赖)──\nexport type {\n FileId, InnerId, ScopedId, StmtId, PartName, GroupName,\n RefId, ReferenceId, SelectorKey, OccurrenceId, ShapeId,\n FaceId, EdgeId, NodeId, StatementId, FaceSelector,\n} from './identity'\nexport {\n asFileId, asInnerId, asScopedId, asStmtId, asPartName, asGroupName,\n asRefId, asReferenceId, asSelectorKey, asOccurrenceId, asShapeId,\n asFaceId, asEdgeId, asNodeId,\n toScopedId, splitScopedId, isScopedId, toInnerId,\n} from './identity'\n\n// ── runtime-state:运行时状态锚点(零依赖层;引擎与库共享)──\nexport {\n configureBackends, getBackends, setCurrentStmt, getCurrentStmt,\n keep, keepHidden, getRuntimeState, nameOf, setName, setKeepSink,\n setPendingAssemblyTransforms, takePendingAssemblyTransforms, assertContractVersion,\n CONTRACT_VERSION,\n} from './runtime-state'\nexport type {\n Backends, FaijsRuntimeState, ShapeSlot, KeepSink, RuntimeExecutionMode,\n AssemblyTransform, StdlibFn, StdlibNamespace, ExecutionAnchor,\n} from './runtime-state'\n\n// ── L0 lang/ 文本面(IR 是引擎内部实现细节,不导出;公开面只有代码文本工具与结果类型)──\nexport type {\n Vec3, JsonValue,\n TerminalShape, ParamDef,\n} from './lang/types'\n// 拓扑身份 provenance 类型(op 级命名 / 拓扑身份系统公开面)。\nexport type { Provenance, NewFaceRule } from './topology/naming/lineage'\nexport {\n derivePartName, getMaxModelNum,\n} from './lang/allocate-id'\nexport type { DerivePartNameInput, DerivePartNameResult } from './lang/allocate-id'\nexport { fmtNum, formatCodeLine } from './lang/codegen'\nexport type { FormatCodeLineInput } from './lang/codegen'\nexport { analyzeCode } from './lang/statement-summary'\nexport type { StatementSummary } from './lang/statement-summary'\nexport { codeToArgs } from './lang/code-to-args'\nexport type { CodeToArgsResult } from './lang/code-to-args'\n// MetadataExtractor — 无 IR 元数据提取器(UI 通道语义源;UiMetadata 全量)\nexport { extractMetadata } from './lang/metadata-extractor'\nexport type {\n UiMetadata, ArgSource, ParamEntry, ImportEntry, FunctionEntry, BlockEntry, KeepEntry,\n ExtractMetadataOptions,\n} from './lang/metadata-extractor'\n// SecurityScanner — 静态安全门禁(纵深防御第一层)\nexport { scanSource, scanAst, assertSecure } from './lang/security-scanner'\nexport type {\n SecurityPolicy, SecurityRuleId, SecurityViolation,\n SecurityScanOptions, SecurityScanResult,\n} from './lang/security-scanner'\n// 参数表达式编辑(P0-C/P0-D):实时校验层 + 编辑面板纯函数\nexport { validateExpression } from './lang/expr-validate'\nexport type { ExprValidateInput, ExprValidateResult } from './lang/expr-validate'\nexport { editArgSource } from './lang/source-edit'\nexport type { EditSourceError } from './lang/source-edit'\n// HostArg — 宿主友好位置参数类型(IR 屏蔽层)\nexport type {\n HostArg, HostRef, HostVarRef, HostParamRef, HostCallRef, HostExprRef, HostRefKind,\n} from './lang/host-arg'\nexport {\n isHostVarRef, isHostParamRef, isHostCallRef, isHostExprRef, isHostRef,\n hostArgToDisplay, hostArgToLiteral, HOST_REF_KINDS,\n} from './lang/host-arg'\n\n// ── mesh 工具面(环境无关):折边法线数据版 ──\n// weapp 方案 §9.1 第 4 项:GeometryBinding 下沉 scene-kernel 后,共享层需要的是\n// 「positions / indices 进、法线 Float32Array 出」的版本,且模块链不得 import three\n// (端侧只能有一份 0.162)。算法在 boolean/creased-normals.ts(零依赖移植 three 的\n// toCreasedNormals);three 版 deriveNormals(boolean/deriveNormals.ts)只是本数据版\n// 的 BufferGeometry 薄适配,留在 browser/index 面供 web 场景使用。\nexport { deriveCreasedNormalsData } from './boolean/creased-normals'\nexport type { CreasedNormalsInput, CreasedNormalsResult } from './boolean/creased-normals'\n\n// ── primitives 纯类型(零运行时依赖;primitive-emission 共享层消费)──\nexport type {\n PrimitiveType, PrimitiveParamsRecord, PrimitiveArgsRecord, PrimitiveMeta,\n} from './primitives/types'\n"]}
1
+ {"version":3,"file":"env-agnostic.js","sourceRoot":"","sources":["../src/env-agnostic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH,OAAO,EACL,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAClE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,SAAS,EAChE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAC5B,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,GACjD,MAAM,YAAY,CAAA;AAEnB,0CAA0C;AAC1C,OAAO,EACL,iBAAiB,EAAE,WAAW,EAAE,cAAc,EAAE,cAAc,EAC9D,IAAI,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAC/D,4BAA4B,EAAE,6BAA6B,EAAE,qBAAqB,EAClF,sBAAsB,EAAE,wBAAwB,EAChD,gBAAgB,GACjB,MAAM,iBAAiB,CAAA;AAaxB,OAAO,EACL,cAAc,EAAE,cAAc,GAC/B,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAEtF,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAEtD,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAElE,0DAA0D;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAK3D,oCAAoC;AACpC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAK3E,qCAAqC;AACrC,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAEzD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAMlD,OAAO,EACL,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,SAAS,EACrE,gBAAgB,EAAE,gBAAgB,EAAE,cAAc,GACnD,MAAM,iBAAiB,CAAA;AAExB,+BAA+B;AAC/B,gEAAgE;AAChE,mEAAmE;AACnE,+DAA+D;AAC/D,0EAA0E;AAC1E,qDAAqD;AACrD,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAA","sourcesContent":["/**\n * env-agnostic.ts — environment-agnostic shared surface (weapp plan §9.1)\n *\n * One home for the exports that every host entry (index / browser / weapp)\n * must share: identity + runtime-state + lang/* text-layer tools. Umbrella\n * entries re-export this module instead of hand-listing the same symbols three\n * times — hand lists are how drift (and entry leaks) happened before.\n *\n * Constraint: NOTHING in this module's dependency graph may be\n * platform-specific. No node:*, no DOM, no three (the weapp main thread holds\n * its own three copy — a second copy via this entry is a hard failure), no\n * brepkit, no wasm loaders. Guarded by entry-boundary.test.ts.\n */\n\n// ── identity:品牌类型 + 信任点(f0,零依赖)──\nexport type {\n FileId, InnerId, ScopedId, StmtId, PartName, GroupName,\n RefId, ReferenceId, SelectorKey, OccurrenceId, ShapeId,\n FaceId, EdgeId, NodeId, StatementId, FaceSelector,\n} from './identity'\nexport {\n asFileId, asInnerId, asScopedId, asStmtId, asPartName, asGroupName,\n asRefId, asReferenceId, asSelectorKey, asOccurrenceId, asShapeId,\n asFaceId, asEdgeId, asNodeId,\n toScopedId, splitScopedId, isScopedId, toInnerId,\n} from './identity'\n\n// ── runtime-state:运行时状态锚点(零依赖层;引擎与库共享)──\nexport {\n configureBackends, getBackends, setCurrentStmt, getCurrentStmt,\n keep, keepHidden, getRuntimeState, nameOf, setName, setKeepSink,\n setPendingAssemblyTransforms, takePendingAssemblyTransforms, assertContractVersion,\n setPendingDetectedUnit, takePendingDetectedUnits,\n CONTRACT_VERSION,\n} from './runtime-state'\nexport type {\n Backends, FaijsRuntimeState, ShapeSlot, KeepSink, RuntimeExecutionMode,\n AssemblyTransform, StdlibFn, StdlibNamespace, ExecutionAnchor, DetectedUnits,\n} from './runtime-state'\n\n// ── L0 lang/ 文本面(IR 是引擎内部实现细节,不导出;公开面只有代码文本工具与结果类型)──\nexport type {\n Vec3, JsonValue,\n TerminalShape, ParamDef,\n} from './lang/types'\n// 拓扑身份 provenance 类型(op 级命名 / 拓扑身份系统公开面)。\nexport type { Provenance, NewFaceRule } from './topology/naming/lineage'\nexport {\n derivePartName, getMaxModelNum,\n} from './lang/allocate-id'\nexport type { DerivePartNameInput, DerivePartNameResult } from './lang/allocate-id'\nexport { fmtNum, formatCodeLine, fmtUnitNum, formatUnitLiteral } from './lang/codegen'\nexport type { FormatCodeLineInput, UnitSerializeOptions } from './lang/codegen'\nexport { analyzeCode } from './lang/statement-summary'\nexport type { StatementSummary } from './lang/statement-summary'\nexport { codeToArgs, parseUnitLiteral } from './lang/code-to-args'\nexport type { CodeToArgsResult, CodeToArgsOptions } from './lang/code-to-args'\n// MetadataExtractor — 无 IR 元数据提取器(UI 通道语义源;UiMetadata 全量)\nexport { extractMetadata } from './lang/metadata-extractor'\nexport type {\n UiMetadata, ArgSource, ParamEntry, ImportEntry, FunctionEntry, BlockEntry, KeepEntry,\n ExtractMetadataOptions, OpDimMap, OpDimDecl,\n} from './lang/metadata-extractor'\n// SecurityScanner — 静态安全门禁(纵深防御第一层)\nexport { scanSource, scanAst, assertSecure } from './lang/security-scanner'\nexport type {\n SecurityPolicy, SecurityRuleId, SecurityViolation,\n SecurityScanOptions, SecurityScanResult,\n} from './lang/security-scanner'\n// 参数表达式编辑(P0-C/P0-D):实时校验层 + 编辑面板纯函数\nexport { validateExpression } from './lang/expr-validate'\nexport type { ExprValidateInput, ExprValidateResult } from './lang/expr-validate'\nexport { editArgSource } from './lang/source-edit'\nexport type { EditSourceError } from './lang/source-edit'\n// HostArg — 宿主友好位置参数类型(IR 屏蔽层)\nexport type {\n HostArg, HostRef, HostVarRef, HostParamRef, HostCallRef, HostExprRef, HostRefKind,\n} from './lang/host-arg'\nexport {\n isHostVarRef, isHostParamRef, isHostCallRef, isHostExprRef, isHostRef,\n hostArgToDisplay, hostArgToLiteral, HOST_REF_KINDS,\n} from './lang/host-arg'\n\n// ── mesh 工具面(环境无关):折边法线数据版 ──\n// weapp 方案 §9.1 第 4 项:GeometryBinding 下沉 scene-kernel 后,共享层需要的是\n// 「positions / indices 进、法线 Float32Array 出」的版本,且模块链不得 import three\n// (端侧只能有一份 0.162)。算法在 boolean/creased-normals.ts(零依赖移植 three 的\n// toCreasedNormals);three 版 deriveNormals(boolean/deriveNormals.ts)只是本数据版\n// 的 BufferGeometry 薄适配,留在 browser/index 面供 web 场景使用。\nexport { deriveCreasedNormalsData } from './boolean/creased-normals'\nexport type { CreasedNormalsInput, CreasedNormalsResult } from './boolean/creased-normals'\n\n// ── primitives 纯类型(零运行时依赖;primitive-emission 共享层消费)──\nexport type {\n PrimitiveType, PrimitiveParamsRecord, PrimitiveArgsRecord, PrimitiveMeta,\n} from './primitives/types'\n"]}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Adaptors from legacy profile-segment shapes to `Curve2dObj` (pure-data).
3
+ *
4
+ * faijs `cad.profile` historically fed its own `ProfileLineSeg`/`ProfileArcSeg`
5
+ * segment model directly into OCCT edge construction. To unify every 2D input on
6
+ * the pure-2D `Geometry2dObj` base (plan F2), this module converts those segment
7
+ * shapes into `Curve2dObj` without importing `api/` (the input types are declared
8
+ * structurally here; `api/profile.ts`'s `ProfileSeg` is structurally compatible).
9
+ *
10
+ * @module
11
+ */
12
+ import type { Curve2dObj } from './curve2d.js';
13
+ /** Line segment in profile form (2D, z=0). */
14
+ export interface ProfileLineSegLike {
15
+ kind: 'line';
16
+ x1: number;
17
+ y1: number;
18
+ x2: number;
19
+ y2: number;
20
+ }
21
+ /** Arc segment in profile form (2D, z=0). `x1/y1/x2/y2` are the sampled arc
22
+ * endpoints, but many inputs omit them (e.g. FCBL corpus), so endpoints are
23
+ * always re-derived from `(cx, cy, radius, startAngle, endAngle)` — matching
24
+ * the original kernel construction. */
25
+ export interface ProfileArcSegLike {
26
+ kind: 'arc';
27
+ cx: number;
28
+ cy: number;
29
+ radius: number;
30
+ startAngle: number;
31
+ endAngle: number;
32
+ ccw: boolean;
33
+ x1?: number;
34
+ y1?: number;
35
+ x2?: number;
36
+ y2?: number;
37
+ }
38
+ /** A profile segment: either a profile line or a profile arc. */
39
+ export type ProfileSegLike = ProfileLineSegLike | ProfileArcSegLike;
40
+ /**
41
+ * Convert a single profile segment to the equivalent 2D curve.
42
+ * @param seg - the profile line or arc segment.
43
+ * @returns the equivalent `Curve2dObj` (line, trimmed arc, or full circle).
44
+ */
45
+ export declare function profileSegToCurve(seg: ProfileSegLike): Curve2dObj;
46
+ //# sourceMappingURL=adapt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapt.d.ts","sourceRoot":"","sources":["../../src/geometry2d/adapt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAG3C,8CAA8C;AAC9C,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;CACX;AAED;;;uCAGuC;AACvC,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,KAAK,CAAA;IACX,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,EAAE,OAAO,CAAA;IACZ,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,EAAE,CAAC,EAAE,MAAM,CAAA;CACZ;AAED,iEAAiE;AACjE,MAAM,MAAM,cAAc,GAAG,kBAAkB,GAAG,iBAAiB,CAAA;AAEnE;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,cAAc,GAAG,UAAU,CA4BjE"}
@@ -0,0 +1,41 @@
1
+ import { makeLine2d, makeArc2dThreePoints, makeCircle2d } from './curve2d.js';
2
+ /**
3
+ * Convert a single profile segment to the equivalent 2D curve.
4
+ * @param seg - the profile line or arc segment.
5
+ * @returns the equivalent `Curve2dObj` (line, trimmed arc, or full circle).
6
+ */
7
+ export function profileSegToCurve(seg) {
8
+ if (seg.kind === 'line')
9
+ return makeLine2d(seg.x1, seg.y1, seg.x2, seg.y2);
10
+ // GOTCHA(2026-09-25, A3 FCBL_tree_entourage):`ccw` 决定几何方向,非元数据。
11
+ // CW 弧的正向扫角是 startAngle→endAngle **递减**:不能沿用 `endAngle−startAngle`
12
+ // 再归一化到 (0,2π],那样会把短 CW 弧(如 65°)算成 CCW 的补角长弧
13
+ // (294°),使 makeArcEdge 收到穿过旋转轴的补角弧 → revolve 退化 → BRepMesh 挂死
14
+ // (进程无声死亡,正被 sketch-arc-ccw-gotcha.test.ts 护栏锁定)。
15
+ // 归一化沿用 brepjs/旧 `arcToHandles`:`while` 平移而非 `%`(`%` 会把
16
+ // 恰为 2π 的整圆扫角消成 0——fp 上 `x % x === 0`——把整圆误判成退化线段)。
17
+ let sweep = seg.ccw ? seg.endAngle - seg.startAngle : seg.startAngle - seg.endAngle;
18
+ while (sweep <= 0)
19
+ sweep += 2 * Math.PI;
20
+ while (sweep > 2 * Math.PI)
21
+ sweep -= 2 * Math.PI;
22
+ // 极小扫角(退化弧)→ 退化为线段。
23
+ if (sweep < 1e-9)
24
+ return makeLine2d(seg.cx + seg.radius * Math.cos(seg.startAngle), seg.cy + seg.radius * Math.sin(seg.startAngle), seg.cx + seg.radius * Math.cos(seg.endAngle), seg.cy + seg.radius * Math.sin(seg.endAngle));
25
+ // 整圆(扫 ≈ 2π,起点≈终点)须保留为真圆:三点构造过奇异点退化(→line)。
26
+ if (sweep >= 2 * Math.PI - 1e-9)
27
+ return makeCircle2d(seg.cx, seg.cy, seg.radius, seg.ccw);
28
+ // 端点/中点一律由 (cx, cy, radius, angle) 解析(缺失 x1/y1/x2/y2 时仍精确),
29
+ // 与旧 `arcToHandles` 一致:这样相邻线段的接缝点完全重合,wire 闭合。
30
+ const sx = seg.cx + seg.radius * Math.cos(seg.startAngle);
31
+ const sy = seg.cy + seg.radius * Math.sin(seg.startAngle);
32
+ const ex = seg.cx + seg.radius * Math.cos(seg.endAngle);
33
+ const ey = seg.cy + seg.radius * Math.sin(seg.endAngle);
34
+ // 几何中点:CCW 从 startAngle 顺向 +sweep/2;CW 从 startAngle 反向 −sweep/2;
35
+ // 三点(起点/中点/终点)定唯一弧。
36
+ const midAngle = seg.ccw ? seg.startAngle + sweep / 2 : seg.startAngle - sweep / 2;
37
+ const mx = seg.cx + seg.radius * Math.cos(midAngle);
38
+ const my = seg.cy + seg.radius * Math.sin(midAngle);
39
+ return makeArc2dThreePoints(sx, sy, mx, my, ex, ey);
40
+ }
41
+ //# sourceMappingURL=adapt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapt.js","sourceRoot":"","sources":["../../src/geometry2d/adapt.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Adaptors from legacy profile-segment shapes to `Curve2dObj` (pure-data).\n *\n * faijs `cad.profile` historically fed its own `ProfileLineSeg`/`ProfileArcSeg`\n * segment model directly into OCCT edge construction. To unify every 2D input on\n * the pure-2D `Geometry2dObj` base (plan F2), this module converts those segment\n * shapes into `Curve2dObj` without importing `api/` (the input types are declared\n * structurally here; `api/profile.ts`'s `ProfileSeg` is structurally compatible).\n *\n * @module\n */\nimport type { Curve2dObj } from './curve2d'\nimport { makeLine2d, makeArc2dThreePoints, makeCircle2d } from './curve2d'\n\n/** Line segment in profile form (2D, z=0). */\nexport interface ProfileLineSegLike {\n kind: 'line'\n x1: number\n y1: number\n x2: number\n y2: number\n}\n\n/** Arc segment in profile form (2D, z=0). `x1/y1/x2/y2` are the sampled arc\n * endpoints, but many inputs omit them (e.g. FCBL corpus), so endpoints are\n * always re-derived from `(cx, cy, radius, startAngle, endAngle)` — matching\n * the original kernel construction. */\nexport interface ProfileArcSegLike {\n kind: 'arc'\n cx: number\n cy: number\n radius: number\n startAngle: number\n endAngle: number\n ccw: boolean\n x1?: number\n y1?: number\n x2?: number\n y2?: number\n}\n\n/** A profile segment: either a profile line or a profile arc. */\nexport type ProfileSegLike = ProfileLineSegLike | ProfileArcSegLike\n\n/**\n * Convert a single profile segment to the equivalent 2D curve.\n * @param seg - the profile line or arc segment.\n * @returns the equivalent `Curve2dObj` (line, trimmed arc, or full circle).\n */\nexport function profileSegToCurve(seg: ProfileSegLike): Curve2dObj {\n if (seg.kind === 'line') return makeLine2d(seg.x1, seg.y1, seg.x2, seg.y2)\n // GOTCHA(2026-09-25, A3 FCBL_tree_entourage):`ccw` 决定几何方向,非元数据。\n // CW 弧的正向扫角是 startAngle→endAngle **递减**:不能沿用 `endAngle−startAngle`\n // 再归一化到 (0,2π],那样会把短 CW 弧(如 65°)算成 CCW 的补角长弧\n // (294°),使 makeArcEdge 收到穿过旋转轴的补角弧 → revolve 退化 → BRepMesh 挂死\n // (进程无声死亡,正被 sketch-arc-ccw-gotcha.test.ts 护栏锁定)。\n // 归一化沿用 brepjs/旧 `arcToHandles`:`while` 平移而非 `%`(`%` 会把\n // 恰为 2π 的整圆扫角消成 0——fp 上 `x % x === 0`——把整圆误判成退化线段)。\n let sweep = seg.ccw ? seg.endAngle - seg.startAngle : seg.startAngle - seg.endAngle\n while (sweep <= 0) sweep += 2 * Math.PI\n while (sweep > 2 * Math.PI) sweep -= 2 * Math.PI\n // 极小扫角(退化弧)→ 退化为线段。\n if (sweep < 1e-9) return makeLine2d(seg.cx + seg.radius * Math.cos(seg.startAngle), seg.cy + seg.radius * Math.sin(seg.startAngle), seg.cx + seg.radius * Math.cos(seg.endAngle), seg.cy + seg.radius * Math.sin(seg.endAngle))\n // 整圆(扫 ≈ 2π,起点≈终点)须保留为真圆:三点构造过奇异点退化(→line)。\n if (sweep >= 2 * Math.PI - 1e-9) return makeCircle2d(seg.cx, seg.cy, seg.radius, seg.ccw)\n // 端点/中点一律由 (cx, cy, radius, angle) 解析(缺失 x1/y1/x2/y2 时仍精确),\n // 与旧 `arcToHandles` 一致:这样相邻线段的接缝点完全重合,wire 闭合。\n const sx = seg.cx + seg.radius * Math.cos(seg.startAngle)\n const sy = seg.cy + seg.radius * Math.sin(seg.startAngle)\n const ex = seg.cx + seg.radius * Math.cos(seg.endAngle)\n const ey = seg.cy + seg.radius * Math.sin(seg.endAngle)\n // 几何中点:CCW 从 startAngle 顺向 +sweep/2;CW 从 startAngle 反向 −sweep/2;\n // 三点(起点/中点/终点)定唯一弧。\n const midAngle = seg.ccw ? seg.startAngle + sweep / 2 : seg.startAngle - sweep / 2\n const mx = seg.cx + seg.radius * Math.cos(midAngle)\n const my = seg.cy + seg.radius * Math.sin(midAngle)\n return makeArc2dThreePoints(sx, sy, mx, my, ex, ey)\n}"]}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Axis-aligned 2D bounding box (pure-data; faijs port of brepjs `BoundingBox2d`).
3
+ * brepjs backs this with a kernel `Bnd_Box2d`; here it's plain numbers.
4
+ *
5
+ * License: adapted from brepjs (Apache-2.0).
6
+ * @module
7
+ */
8
+ export interface BBox2d {
9
+ xMin: number;
10
+ yMin: number;
11
+ xMax: number;
12
+ yMax: number;
13
+ }
14
+ /**
15
+ * Create an empty (inverted) bounding box.
16
+ * @returns a fresh BBox2d whose mins are +Infinity and maxes are -Infinity.
17
+ */
18
+ export declare function createBBox2d(): BBox2d;
19
+ /**
20
+ * True when the box holds no finite extent yet.
21
+ * @param bb - the bounding box to test.
22
+ * @returns true when any corner is non-finite or the box is inverted.
23
+ */
24
+ export declare function isEmpty(bb: BBox2d): boolean;
25
+ /**
26
+ * Expand `bb` to include the given corner points.
27
+ * @param bb - the bounding box to expand in place.
28
+ * @param pts - the corner points to include.
29
+ */
30
+ export declare function addPoints(bb: BBox2d, pts: ReadonlyArray<readonly [number, number]>): void;
31
+ /**
32
+ * Expand `bb` to include all points of `other`.
33
+ * @param bb - the box to expand in place.
34
+ * @param other - the box whose extent is folded into `bb`.
35
+ */
36
+ export declare function mergeBBox(bb: BBox2d, other: BBox2d): void;
37
+ /**
38
+ * Return `[min, max]` corner points.
39
+ * @param bb - the bounding box to read from.
40
+ * @returns the lower-left and upper-right corners as `[[xMin,yMin],[xMax,yMax]]`.
41
+ */
42
+ export declare function boundsOf(bb: BBox2d): [[number, number], [number, number]];
43
+ /**
44
+ * Compute the center point of the box.
45
+ * @param bb - the bounding box to read from.
46
+ * @returns the midpoint `[x, y]` between the min and max corners.
47
+ */
48
+ export declare function centerOf(bb: BBox2d): [number, number];
49
+ /**
50
+ * Compute the width of the box.
51
+ * @param bb - the bounding box to read from.
52
+ * @returns the absolute horizontal extent.
53
+ */
54
+ export declare function widthOf(bb: BBox2d): number;
55
+ /**
56
+ * Compute the height of the box.
57
+ * @param bb - the bounding box to read from.
58
+ * @returns the absolute vertical extent.
59
+ */
60
+ export declare function heightOf(bb: BBox2d): number;
61
+ /**
62
+ * Point guaranteed outside (to the upper-right of) the box.
63
+ * @param bb - the bounding box to read from.
64
+ * @param paddingPercent - the padding as a percent of the box extent (default 1).
65
+ * @returns a point offset to the upper-right of `bb`.
66
+ */
67
+ export declare function outsidePointOf(bb: BBox2d, paddingPercent?: number): [number, number];
68
+ /**
69
+ * True if `bb` and `other` are completely disjoint.
70
+ * @param bb - the first bounding box.
71
+ * @param other - the second bounding box.
72
+ * @returns true when the two boxes do not overlap (empty boxes count as disjoint).
73
+ */
74
+ export declare function isBBoxOut(bb: BBox2d, other: BBox2d): boolean;
75
+ /**
76
+ * True if the point lies inside (or on the boundary of) the box.
77
+ * @param bb - the bounding box to test against.
78
+ * @param pt - the 2D point to test, `[x, y]`.
79
+ * @returns true when `pt` is within (or on) the box.
80
+ */
81
+ export declare function containsPoint(bb: BBox2d, pt: readonly [number, number]): boolean;
82
+ //# sourceMappingURL=bbox2d.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bbox2d.d.ts","sourceRoot":"","sources":["../../src/geometry2d/bbox2d.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAK3C;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAOzF;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAKzD;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAKzE;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAErD;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE1C;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,SAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAI/E;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAI5D;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAIhF"}