@pascal-app/core 0.9.2 → 1.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (339) hide show
  1. package/README.md +17 -10
  2. package/dist/events/bus.d.ts +21 -2
  3. package/dist/events/bus.d.ts.map +1 -1
  4. package/dist/hooks/spatial-grid/floor-placed-elevation.d.ts +17 -1
  5. package/dist/hooks/spatial-grid/floor-placed-elevation.d.ts.map +1 -1
  6. package/dist/hooks/spatial-grid/floor-placed-elevation.js +61 -8
  7. package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts +116 -66
  8. package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts.map +1 -1
  9. package/dist/hooks/spatial-grid/spatial-grid-manager.js +316 -441
  10. package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts +46 -1
  11. package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts.map +1 -1
  12. package/dist/hooks/spatial-grid/spatial-grid-sync.js +193 -12
  13. package/dist/hooks/spatial-grid/support-host-id.d.ts +3 -0
  14. package/dist/hooks/spatial-grid/support-host-id.d.ts.map +1 -0
  15. package/dist/hooks/spatial-grid/support-host-id.js +2 -0
  16. package/dist/hooks/spatial-grid/support-host-patch.d.ts +51 -0
  17. package/dist/hooks/spatial-grid/support-host-patch.d.ts.map +1 -0
  18. package/dist/hooks/spatial-grid/support-host-patch.js +164 -0
  19. package/dist/index.d.ts +23 -11
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +22 -10
  22. package/dist/lib/measurement-geometry.d.ts +4 -0
  23. package/dist/lib/measurement-geometry.d.ts.map +1 -1
  24. package/dist/lib/measurement-geometry.js +27 -10
  25. package/dist/lib/slab-polygon.d.ts.map +1 -1
  26. package/dist/lib/slab-polygon.js +33 -1
  27. package/dist/lib/space-detection.d.ts +15 -4
  28. package/dist/lib/space-detection.d.ts.map +1 -1
  29. package/dist/lib/space-detection.js +174 -88
  30. package/dist/lib/terrain-brush.d.ts +163 -0
  31. package/dist/lib/terrain-brush.d.ts.map +1 -0
  32. package/dist/lib/terrain-brush.js +359 -0
  33. package/dist/lib/terrain-codec.d.ts +51 -0
  34. package/dist/lib/terrain-codec.d.ts.map +1 -0
  35. package/dist/lib/terrain-codec.js +167 -0
  36. package/dist/lib/terrain-field.d.ts +150 -0
  37. package/dist/lib/terrain-field.d.ts.map +1 -0
  38. package/dist/lib/terrain-field.js +248 -0
  39. package/dist/lib/terrain-raycast.d.ts +44 -0
  40. package/dist/lib/terrain-raycast.d.ts.map +1 -0
  41. package/dist/lib/terrain-raycast.js +188 -0
  42. package/dist/lib/terrain-source.d.ts +60 -0
  43. package/dist/lib/terrain-source.d.ts.map +1 -0
  44. package/dist/lib/terrain-source.js +90 -0
  45. package/dist/lib/terrain-support.d.ts +60 -0
  46. package/dist/lib/terrain-support.d.ts.map +1 -0
  47. package/dist/lib/terrain-support.js +150 -0
  48. package/dist/lib/zone-quantities.d.ts +1 -1
  49. package/dist/lib/zone-quantities.d.ts.map +1 -1
  50. package/dist/lib/zone-quantities.js +311 -66
  51. package/dist/material-library.d.ts +9 -1
  52. package/dist/material-library.d.ts.map +1 -1
  53. package/dist/material-library.js +56 -4
  54. package/dist/registry/handles.d.ts +16 -1
  55. package/dist/registry/handles.d.ts.map +1 -1
  56. package/dist/registry/index.d.ts +1 -1
  57. package/dist/registry/index.d.ts.map +1 -1
  58. package/dist/registry/subtree.d.ts.map +1 -1
  59. package/dist/registry/subtree.js +5 -2
  60. package/dist/registry/types.d.ts +64 -1
  61. package/dist/registry/types.d.ts.map +1 -1
  62. package/dist/schema/index.d.ts +6 -3
  63. package/dist/schema/index.d.ts.map +1 -1
  64. package/dist/schema/index.js +6 -3
  65. package/dist/schema/nodes/cabinet.d.ts +2 -0
  66. package/dist/schema/nodes/cabinet.d.ts.map +1 -1
  67. package/dist/schema/nodes/cabinet.js +4 -2
  68. package/dist/schema/nodes/ceiling.d.ts +1 -1
  69. package/dist/schema/nodes/ceiling.d.ts.map +1 -1
  70. package/dist/schema/nodes/ceiling.js +7 -1
  71. package/dist/schema/nodes/column.d.ts +1 -0
  72. package/dist/schema/nodes/column.d.ts.map +1 -1
  73. package/dist/schema/nodes/column.js +2 -0
  74. package/dist/schema/nodes/construction-dimension.d.ts +195 -0
  75. package/dist/schema/nodes/construction-dimension.d.ts.map +1 -0
  76. package/dist/schema/nodes/construction-dimension.js +151 -0
  77. package/dist/schema/nodes/door.d.ts +29 -0
  78. package/dist/schema/nodes/door.d.ts.map +1 -1
  79. package/dist/schema/nodes/door.js +20 -0
  80. package/dist/schema/nodes/duct-terminal.d.ts +1 -0
  81. package/dist/schema/nodes/duct-terminal.d.ts.map +1 -1
  82. package/dist/schema/nodes/duct-terminal.js +2 -0
  83. package/dist/schema/nodes/fence.d.ts +2 -0
  84. package/dist/schema/nodes/fence.d.ts.map +1 -1
  85. package/dist/schema/nodes/fence.js +8 -0
  86. package/dist/schema/nodes/hvac-equipment.d.ts +1 -0
  87. package/dist/schema/nodes/hvac-equipment.d.ts.map +1 -1
  88. package/dist/schema/nodes/hvac-equipment.js +2 -0
  89. package/dist/schema/nodes/item.d.ts +1 -0
  90. package/dist/schema/nodes/item.d.ts.map +1 -1
  91. package/dist/schema/nodes/item.js +13 -0
  92. package/dist/schema/nodes/level.d.ts +2 -1
  93. package/dist/schema/nodes/level.d.ts.map +1 -1
  94. package/dist/schema/nodes/level.js +12 -33
  95. package/dist/schema/nodes/shelf.d.ts +1 -0
  96. package/dist/schema/nodes/shelf.d.ts.map +1 -1
  97. package/dist/schema/nodes/shelf.js +2 -0
  98. package/dist/schema/nodes/site.d.ts +9 -0
  99. package/dist/schema/nodes/site.d.ts.map +1 -1
  100. package/dist/schema/nodes/site.js +8 -6
  101. package/dist/schema/nodes/slab.d.ts +5 -0
  102. package/dist/schema/nodes/slab.d.ts.map +1 -1
  103. package/dist/schema/nodes/slab.js +14 -2
  104. package/dist/schema/nodes/spawn.d.ts +1 -0
  105. package/dist/schema/nodes/spawn.d.ts.map +1 -1
  106. package/dist/schema/nodes/spawn.js +2 -0
  107. package/dist/schema/nodes/stair.d.ts +3 -1
  108. package/dist/schema/nodes/stair.d.ts.map +1 -1
  109. package/dist/schema/nodes/stair.js +8 -1
  110. package/dist/schema/nodes/structural-grid.d.ts +27 -0
  111. package/dist/schema/nodes/structural-grid.d.ts.map +1 -0
  112. package/dist/schema/nodes/structural-grid.js +17 -0
  113. package/dist/schema/nodes/wall.d.ts +5 -2
  114. package/dist/schema/nodes/wall.d.ts.map +1 -1
  115. package/dist/schema/nodes/wall.js +13 -4
  116. package/dist/schema/nodes/window.d.ts +29 -0
  117. package/dist/schema/nodes/window.d.ts.map +1 -1
  118. package/dist/schema/nodes/window.js +18 -0
  119. package/dist/schema/nodes/zone.d.ts +20 -0
  120. package/dist/schema/nodes/zone.d.ts.map +1 -1
  121. package/dist/schema/nodes/zone.js +15 -0
  122. package/dist/schema/terrain.d.ts +28 -0
  123. package/dist/schema/terrain.d.ts.map +1 -0
  124. package/dist/schema/terrain.js +30 -0
  125. package/dist/schema/types.d.ts +211 -3
  126. package/dist/schema/types.d.ts.map +1 -1
  127. package/dist/schema/types.js +4 -0
  128. package/dist/services/__fixtures__/wall-plane-top-boundary-repro.d.ts +80 -0
  129. package/dist/services/__fixtures__/wall-plane-top-boundary-repro.d.ts.map +1 -0
  130. package/dist/services/__fixtures__/wall-plane-top-boundary-repro.js +89 -0
  131. package/dist/services/index.d.ts +2 -1
  132. package/dist/services/index.d.ts.map +1 -1
  133. package/dist/services/index.js +2 -1
  134. package/dist/services/level-height.d.ts +8 -9
  135. package/dist/services/level-height.d.ts.map +1 -1
  136. package/dist/services/level-height.js +48 -16
  137. package/dist/services/storey.d.ts +103 -0
  138. package/dist/services/storey.d.ts.map +1 -0
  139. package/dist/services/storey.js +296 -0
  140. package/dist/store/actions/node-actions.d.ts.map +1 -1
  141. package/dist/store/actions/node-actions.js +47 -3
  142. package/dist/store/history-control.d.ts +20 -0
  143. package/dist/store/history-control.d.ts.map +1 -1
  144. package/dist/store/history-control.js +110 -13
  145. package/dist/store/use-live-terrain.d.ts +65 -0
  146. package/dist/store/use-live-terrain.d.ts.map +1 -0
  147. package/dist/store/use-live-terrain.js +31 -0
  148. package/dist/store/use-live-transforms.d.ts +8 -0
  149. package/dist/store/use-live-transforms.d.ts.map +1 -1
  150. package/dist/store/use-scene.d.ts +31 -2
  151. package/dist/store/use-scene.d.ts.map +1 -1
  152. package/dist/store/use-scene.js +638 -8
  153. package/dist/systems/elevator/elevator-opening-system.d.ts +1 -0
  154. package/dist/systems/elevator/elevator-opening-system.d.ts.map +1 -1
  155. package/dist/systems/elevator/elevator-opening-system.js +27 -21
  156. package/dist/systems/elevator/elevator-service.d.ts +0 -2
  157. package/dist/systems/elevator/elevator-service.d.ts.map +1 -1
  158. package/dist/systems/elevator/elevator-service.js +2 -24
  159. package/dist/systems/slab/slab-placement.d.ts +11 -0
  160. package/dist/systems/slab/slab-placement.d.ts.map +1 -0
  161. package/dist/systems/slab/slab-placement.js +14 -0
  162. package/dist/systems/slab/slab-support.d.ts +137 -0
  163. package/dist/systems/slab/slab-support.d.ts.map +1 -0
  164. package/dist/systems/slab/slab-support.js +557 -0
  165. package/dist/systems/stair/stair-opening-preview.d.ts +1060 -935
  166. package/dist/systems/stair/stair-opening-preview.d.ts.map +1 -1
  167. package/dist/systems/stair/stair-opening-sync.d.ts.map +1 -1
  168. package/dist/systems/stair/stair-opening-sync.js +18 -15
  169. package/dist/systems/stair/stair-opening-system.d.ts.map +1 -1
  170. package/dist/systems/stair/stair-opening-system.js +32 -4
  171. package/dist/systems/stair/stair-rise.d.ts +22 -0
  172. package/dist/systems/stair/stair-rise.d.ts.map +1 -0
  173. package/dist/systems/stair/stair-rise.js +79 -0
  174. package/dist/systems/wall/wall-curve.d.ts +10 -0
  175. package/dist/systems/wall/wall-curve.d.ts.map +1 -1
  176. package/dist/systems/wall/wall-curve.js +1 -1
  177. package/dist/systems/wall/wall-mitering.js +6 -6
  178. package/dist/systems/wall/wall-top.d.ts +40 -0
  179. package/dist/systems/wall/wall-top.d.ts.map +1 -0
  180. package/dist/systems/wall/wall-top.js +46 -0
  181. package/dist/utils/clone-scene-graph.d.ts.map +1 -1
  182. package/dist/utils/clone-scene-graph.js +34 -3
  183. package/dist/utils/heal-scene-graph.d.ts +1 -1
  184. package/dist/utils/heal-scene-graph.d.ts.map +1 -1
  185. package/dist/utils/heal-scene-graph.js +25 -9
  186. package/dist/validation/validate-build-json.d.ts +2 -0
  187. package/dist/validation/validate-build-json.d.ts.map +1 -1
  188. package/dist/validation/validate-build-json.js +59 -3
  189. package/package.json +2 -2
  190. package/dist/hooks/scene-registry/scene-registry.test.d.ts +0 -2
  191. package/dist/hooks/scene-registry/scene-registry.test.d.ts.map +0 -1
  192. package/dist/hooks/scene-registry/scene-registry.test.js +0 -26
  193. package/dist/hooks/spatial-grid/floor-placed-elevation.test.d.ts +0 -2
  194. package/dist/hooks/spatial-grid/floor-placed-elevation.test.d.ts.map +0 -1
  195. package/dist/hooks/spatial-grid/floor-placed-elevation.test.js +0 -366
  196. package/dist/hooks/spatial-grid/wall-slab-overlap.test.d.ts +0 -2
  197. package/dist/hooks/spatial-grid/wall-slab-overlap.test.d.ts.map +0 -1
  198. package/dist/hooks/spatial-grid/wall-slab-overlap.test.js +0 -363
  199. package/dist/lib/measurement-geometry.test.d.ts +0 -2
  200. package/dist/lib/measurement-geometry.test.d.ts.map +0 -1
  201. package/dist/lib/measurement-geometry.test.js +0 -102
  202. package/dist/lib/slab-polygon.test.d.ts +0 -2
  203. package/dist/lib/slab-polygon.test.d.ts.map +0 -1
  204. package/dist/lib/slab-polygon.test.js +0 -635
  205. package/dist/lib/space-detection-pause.test.d.ts +0 -2
  206. package/dist/lib/space-detection-pause.test.d.ts.map +0 -1
  207. package/dist/lib/space-detection-pause.test.js +0 -42
  208. package/dist/lib/space-detection.test.d.ts +0 -2
  209. package/dist/lib/space-detection.test.d.ts.map +0 -1
  210. package/dist/lib/space-detection.test.js +0 -376
  211. package/dist/lib/zone-quantities.test.d.ts +0 -2
  212. package/dist/lib/zone-quantities.test.d.ts.map +0 -1
  213. package/dist/lib/zone-quantities.test.js +0 -82
  214. package/dist/registry/registry.test.d.ts +0 -2
  215. package/dist/registry/registry.test.d.ts.map +0 -1
  216. package/dist/registry/registry.test.js +0 -196
  217. package/dist/registry/relations-resolver.test.d.ts +0 -2
  218. package/dist/registry/relations-resolver.test.d.ts.map +0 -1
  219. package/dist/registry/relations-resolver.test.js +0 -183
  220. package/dist/registry/scene-api.test.d.ts +0 -2
  221. package/dist/registry/scene-api.test.d.ts.map +0 -1
  222. package/dist/registry/scene-api.test.js +0 -183
  223. package/dist/registry/subtree.test.d.ts +0 -2
  224. package/dist/registry/subtree.test.d.ts.map +0 -1
  225. package/dist/registry/subtree.test.js +0 -163
  226. package/dist/schema/asset-url.test.d.ts +0 -2
  227. package/dist/schema/asset-url.test.d.ts.map +0 -1
  228. package/dist/schema/asset-url.test.js +0 -134
  229. package/dist/schema/material.test.d.ts +0 -2
  230. package/dist/schema/material.test.d.ts.map +0 -1
  231. package/dist/schema/material.test.js +0 -43
  232. package/dist/schema/nodes/measurement.test.d.ts +0 -2
  233. package/dist/schema/nodes/measurement.test.d.ts.map +0 -1
  234. package/dist/schema/nodes/measurement.test.js +0 -139
  235. package/dist/schema/nodes/ridge-vent-defaults.test.d.ts +0 -2
  236. package/dist/schema/nodes/ridge-vent-defaults.test.d.ts.map +0 -1
  237. package/dist/schema/nodes/ridge-vent-defaults.test.js +0 -205
  238. package/dist/schema/nodes/roof-segment-shape.test.d.ts +0 -2
  239. package/dist/schema/nodes/roof-segment-shape.test.d.ts.map +0 -1
  240. package/dist/schema/nodes/roof-segment-shape.test.js +0 -175
  241. package/dist/schema/nodes/roof-segment-surface.test.d.ts +0 -2
  242. package/dist/schema/nodes/roof-segment-surface.test.d.ts.map +0 -1
  243. package/dist/schema/nodes/roof-segment-surface.test.js +0 -48
  244. package/dist/schema/nodes/roof-segment-trim.test.d.ts +0 -2
  245. package/dist/schema/nodes/roof-segment-trim.test.d.ts.map +0 -1
  246. package/dist/schema/nodes/roof-segment-trim.test.js +0 -107
  247. package/dist/schema/nodes/roof-segment-walls.test.d.ts +0 -2
  248. package/dist/schema/nodes/roof-segment-walls.test.d.ts.map +0 -1
  249. package/dist/schema/nodes/roof-segment-walls.test.js +0 -92
  250. package/dist/schema/nodes/wall.test.d.ts +0 -2
  251. package/dist/schema/nodes/wall.test.d.ts.map +0 -1
  252. package/dist/schema/nodes/wall.test.js +0 -208
  253. package/dist/services/alignment-anchors.test.d.ts +0 -2
  254. package/dist/services/alignment-anchors.test.d.ts.map +0 -1
  255. package/dist/services/alignment-anchors.test.js +0 -383
  256. package/dist/services/alignment.test.d.ts +0 -2
  257. package/dist/services/alignment.test.d.ts.map +0 -1
  258. package/dist/services/alignment.test.js +0 -92
  259. package/dist/services/drag-session.test.d.ts +0 -2
  260. package/dist/services/drag-session.test.d.ts.map +0 -1
  261. package/dist/services/drag-session.test.js +0 -219
  262. package/dist/services/hosting.test.d.ts +0 -2
  263. package/dist/services/hosting.test.d.ts.map +0 -1
  264. package/dist/services/hosting.test.js +0 -230
  265. package/dist/services/movement.test.d.ts +0 -2
  266. package/dist/services/movement.test.d.ts.map +0 -1
  267. package/dist/services/movement.test.js +0 -133
  268. package/dist/services/opening-guides.test.d.ts +0 -2
  269. package/dist/services/opening-guides.test.d.ts.map +0 -1
  270. package/dist/services/opening-guides.test.js +0 -208
  271. package/dist/services/port-connectivity.test.d.ts +0 -2
  272. package/dist/services/port-connectivity.test.d.ts.map +0 -1
  273. package/dist/services/port-connectivity.test.js +0 -297
  274. package/dist/services/riser-diagram.test.d.ts +0 -2
  275. package/dist/services/riser-diagram.test.d.ts.map +0 -1
  276. package/dist/services/riser-diagram.test.js +0 -66
  277. package/dist/services/single-undo-dance.test.d.ts +0 -2
  278. package/dist/services/single-undo-dance.test.d.ts.map +0 -1
  279. package/dist/services/single-undo-dance.test.js +0 -210
  280. package/dist/services/snap.test.d.ts +0 -2
  281. package/dist/services/snap.test.d.ts.map +0 -1
  282. package/dist/services/snap.test.js +0 -137
  283. package/dist/services/system-graph.test.d.ts +0 -2
  284. package/dist/services/system-graph.test.d.ts.map +0 -1
  285. package/dist/services/system-graph.test.js +0 -138
  286. package/dist/services/validate-dwv.test.d.ts +0 -2
  287. package/dist/services/validate-dwv.test.d.ts.map +0 -1
  288. package/dist/services/validate-dwv.test.js +0 -109
  289. package/dist/store/actions/node-mutation-sanitize.test.d.ts +0 -2
  290. package/dist/store/actions/node-mutation-sanitize.test.d.ts.map +0 -1
  291. package/dist/store/actions/node-mutation-sanitize.test.js +0 -147
  292. package/dist/store/actions/reparent.test.d.ts +0 -2
  293. package/dist/store/actions/reparent.test.d.ts.map +0 -1
  294. package/dist/store/actions/reparent.test.js +0 -212
  295. package/dist/store/actions/ridge-vent-update.test.d.ts +0 -2
  296. package/dist/store/actions/ridge-vent-update.test.d.ts.map +0 -1
  297. package/dist/store/actions/ridge-vent-update.test.js +0 -264
  298. package/dist/store/use-scene-dirty-tracking.test.d.ts +0 -2
  299. package/dist/store/use-scene-dirty-tracking.test.d.ts.map +0 -1
  300. package/dist/store/use-scene-dirty-tracking.test.js +0 -68
  301. package/dist/store/use-scene-elevator-migration.test.d.ts +0 -2
  302. package/dist/store/use-scene-elevator-migration.test.d.ts.map +0 -1
  303. package/dist/store/use-scene-elevator-migration.test.js +0 -109
  304. package/dist/store/use-scene-measurement-roundtrip.test.d.ts +0 -2
  305. package/dist/store/use-scene-measurement-roundtrip.test.d.ts.map +0 -1
  306. package/dist/store/use-scene-measurement-roundtrip.test.js +0 -97
  307. package/dist/store/use-scene-plugins.test.d.ts +0 -2
  308. package/dist/store/use-scene-plugins.test.d.ts.map +0 -1
  309. package/dist/store/use-scene-plugins.test.js +0 -51
  310. package/dist/store/use-scene-wall-slot-migration.test.d.ts +0 -2
  311. package/dist/store/use-scene-wall-slot-migration.test.d.ts.map +0 -1
  312. package/dist/store/use-scene-wall-slot-migration.test.js +0 -210
  313. package/dist/store/use-scene-window-migration.test.d.ts +0 -2
  314. package/dist/store/use-scene-window-migration.test.d.ts.map +0 -1
  315. package/dist/store/use-scene-window-migration.test.js +0 -85
  316. package/dist/systems/elevator/elevator-opening-sync.test.d.ts +0 -2
  317. package/dist/systems/elevator/elevator-opening-sync.test.d.ts.map +0 -1
  318. package/dist/systems/elevator/elevator-opening-sync.test.js +0 -146
  319. package/dist/systems/elevator/elevator-runtime.test.d.ts +0 -2
  320. package/dist/systems/elevator/elevator-runtime.test.d.ts.map +0 -1
  321. package/dist/systems/elevator/elevator-runtime.test.js +0 -64
  322. package/dist/systems/fence/fence-spline.test.d.ts +0 -2
  323. package/dist/systems/fence/fence-spline.test.d.ts.map +0 -1
  324. package/dist/systems/fence/fence-spline.test.js +0 -136
  325. package/dist/systems/stair/stair-opening-preview.test.d.ts +0 -2
  326. package/dist/systems/stair/stair-opening-preview.test.d.ts.map +0 -1
  327. package/dist/systems/stair/stair-opening-preview.test.js +0 -80
  328. package/dist/systems/stair/stair-opening-sync.test.d.ts +0 -2
  329. package/dist/systems/stair/stair-opening-sync.test.d.ts.map +0 -1
  330. package/dist/systems/stair/stair-opening-sync.test.js +0 -485
  331. package/dist/systems/wall/wall-mitering.test.d.ts +0 -2
  332. package/dist/systems/wall/wall-mitering.test.d.ts.map +0 -1
  333. package/dist/systems/wall/wall-mitering.test.js +0 -63
  334. package/dist/utils/clone-scene-graph.test.d.ts +0 -2
  335. package/dist/utils/clone-scene-graph.test.d.ts.map +0 -1
  336. package/dist/utils/clone-scene-graph.test.js +0 -62
  337. package/dist/utils/heal-scene-graph.test.d.ts +0 -2
  338. package/dist/utils/heal-scene-graph.test.d.ts.map +0 -1
  339. package/dist/utils/heal-scene-graph.test.js +0 -88
@@ -1,208 +0,0 @@
1
- import { describe, expect, test } from 'bun:test';
2
- import { computeEdgeGaps, computeOpeningGuides, detectAlongWallAlignment, detectEqualSpacing, detectVerticalAlignment, } from './opening-guides';
3
- function span(id, centerS, width, centerY = 1, height = 1) {
4
- return { id, centerS, width, centerY, height };
5
- }
6
- const WALL = { length: 10, height: 2.5 };
7
- describe('detectEqualSpacing', () => {
8
- test('returns null for fewer than three openings', () => {
9
- const a = span('a', 0.5, 1);
10
- const b = span('b', 2.5, 1);
11
- expect(detectEqualSpacing([a, b], 'b', 0.03, 0.02)).toBeNull();
12
- });
13
- test('detects a run of equal gaps across three openings', () => {
14
- // width 1 each: a[0,1] b[2,3] c[4,5] → two gaps of 1m.
15
- const a = span('a', 0.5, 1);
16
- const b = span('b', 2.5, 1);
17
- const c = span('c', 4.5, 1);
18
- const run = detectEqualSpacing([a, b, c], 'b', 0.03, 0.02);
19
- expect(run).not.toBeNull();
20
- expect(run?.gap).toBeCloseTo(1);
21
- expect(run?.segments).toHaveLength(2);
22
- expect(run?.openingIds).toEqual(['a', 'b', 'c']);
23
- expect(run?.segments[0]).toEqual({ fromS: 1, toS: 2 });
24
- expect(run?.segments[1]).toEqual({ fromS: 3, toS: 4 });
25
- });
26
- test('extends a run across four openings (three gaps)', () => {
27
- const openings = [span('a', 0.5, 1), span('b', 2.5, 1), span('c', 4.5, 1), span('d', 6.5, 1)];
28
- const run = detectEqualSpacing(openings, 'c', 0.03, 0.02);
29
- expect(run?.segments).toHaveLength(3);
30
- expect(run?.openingIds).toEqual(['a', 'b', 'c', 'd']);
31
- });
32
- test('returns null when gaps differ beyond tolerance', () => {
33
- const a = span('a', 0.5, 1); // [0,1]
34
- const b = span('b', 2.5, 1); // [2,3] → gap 1
35
- const c = span('c', 5, 1); // [4.5,5.5] → gap 1.5
36
- expect(detectEqualSpacing([a, b, c], 'b', 0.03, 0.02)).toBeNull();
37
- });
38
- test('returns null when the moving opening is not part of the equal run', () => {
39
- const a = span('a', 0.5, 1);
40
- const b = span('b', 2.5, 1);
41
- const c = span('c', 4.5, 1); // a,b,c form equal gaps of 1
42
- const d = span('d', 10, 1); // far right, breaks the run
43
- expect(detectEqualSpacing([a, b, c, d], 'd', 0.03, 0.02)).toBeNull();
44
- });
45
- test('a near-zero (touching) gap breaks a run', () => {
46
- const a = span('a', 0.5, 1); // [0,1]
47
- const b = span('b', 1.505, 1); // [1.005,2.005] → gap 0.005 < minGap
48
- const c = span('c', 3.005, 1); // [2.505,3.505] → gap 0.5
49
- expect(detectEqualSpacing([a, b, c], 'b', 0.03, 0.02)).toBeNull();
50
- });
51
- test('honours the equal-spacing tolerance', () => {
52
- const a = span('a', 0.5, 1); // [0,1]
53
- const b = span('b', 2.5, 1); // [2,3] → gap 1.0
54
- const c = span('c', 4.52, 1); // [4.02,5.02] → gap 1.02
55
- expect(detectEqualSpacing([a, b, c], 'b', 0.03, 0.02)?.segments).toHaveLength(2);
56
- expect(detectEqualSpacing([a, b, c], 'b', 0.01, 0.02)).toBeNull();
57
- });
58
- });
59
- describe('computeEdgeGaps', () => {
60
- test('measures clearance to the nearest neighbour on each side', () => {
61
- const moving = span('m', 5, 1); // [4.5,5.5]
62
- const left = span('l', 2, 1); // [1.5,2.5]
63
- const right = span('r', 8, 1); // [7.5,8.5]
64
- const gaps = computeEdgeGaps(moving, [left, right], WALL, 0.02);
65
- const byside = Object.fromEntries(gaps.map((g) => [g.side, g]));
66
- expect(byside.left?.distance).toBeCloseTo(2);
67
- expect(byside.left?.target).toBe('opening');
68
- expect(byside.left?.targetId).toBe('l');
69
- expect(byside.right?.distance).toBeCloseTo(2);
70
- expect(byside.right?.targetId).toBe('r');
71
- });
72
- test('falls back to wall ends with no neighbour', () => {
73
- const moving = span('m', 5, 1); // [4.5,5.5]
74
- const gaps = computeEdgeGaps(moving, [], WALL, 0.02);
75
- const byside = Object.fromEntries(gaps.map((g) => [g.side, g]));
76
- expect(byside.left?.target).toBe('wall-start');
77
- expect(byside.left?.distance).toBeCloseTo(4.5);
78
- expect(byside.right?.target).toBe('wall-end');
79
- expect(byside.right?.distance).toBeCloseTo(4.5);
80
- });
81
- test('omits a side that is flush / overlapping (below minGap)', () => {
82
- const moving = span('m', 5, 1); // [4.5,5.5]
83
- const flush = span('l', 4, 1); // [3.5,4.5] right edge touches moving left
84
- const gaps = computeEdgeGaps(moving, [flush], WALL, 0.02);
85
- expect(gaps.find((g) => g.side === 'left')).toBeUndefined();
86
- expect(gaps.find((g) => g.side === 'right')?.target).toBe('wall-end');
87
- });
88
- });
89
- describe('detectAlongWallAlignment', () => {
90
- test('detects edge-to-edge alignment within tolerance', () => {
91
- const moving = span('m', 5, 2); // [4,6]
92
- const sib = span('s', 7.05, 2); // left edge 6.05
93
- const a = detectAlongWallAlignment(moving, [sib], 0.08);
94
- expect(a?.movingFeature).toBe('right');
95
- expect(a?.targetFeature).toBe('left');
96
- expect(a?.snap).toBeCloseTo(0.05);
97
- expect(a?.s).toBeCloseTo(6.05);
98
- });
99
- test('detects centre alignment', () => {
100
- const moving = span('m', 5, 2);
101
- const sib = span('s', 5.03, 0.5); // centre 5.03, edges far from moving edges
102
- const a = detectAlongWallAlignment(moving, [sib], 0.08);
103
- expect(a?.movingFeature).toBe('center');
104
- expect(a?.targetFeature).toBe('center');
105
- expect(a?.snap).toBeCloseTo(0.03);
106
- });
107
- test('returns null when nothing is within tolerance', () => {
108
- const moving = span('m', 5, 2);
109
- const sib = span('s', 9, 2);
110
- expect(detectAlongWallAlignment(moving, [sib], 0.08)).toBeNull();
111
- });
112
- });
113
- describe('detectVerticalAlignment', () => {
114
- test('detects a shared sill within tolerance', () => {
115
- const moving = span('m', 5, 1, 1.5, 1); // sill 1.0
116
- const sib = span('s', 8, 1, 2.04, 2); // sill 1.04
117
- const a = detectVerticalAlignment(moving, [sib], 0.08);
118
- expect(a?.movingFeature).toBe('sill');
119
- expect(a?.targetFeature).toBe('sill');
120
- expect(a?.snap).toBeCloseTo(0.04);
121
- expect(a?.y).toBeCloseTo(1.04);
122
- });
123
- test('returns null when sills/tops differ beyond tolerance', () => {
124
- const moving = span('m', 5, 1, 1.5, 1); // sill 1, top 2, centre 1.5
125
- const sib = span('s', 8, 1, 0.4, 0.4); // sill 0.2, top 0.6, centre 0.4
126
- expect(detectVerticalAlignment(moving, [sib], 0.08)).toBeNull();
127
- });
128
- });
129
- describe('computeOpeningGuides', () => {
130
- test('includes sill/head for windows', () => {
131
- const moving = span('m', 5, 1, 1.5, 1); // bottom 1, top 2
132
- const guides = computeOpeningGuides({
133
- moving,
134
- siblings: [],
135
- wall: WALL,
136
- includeVertical: true,
137
- });
138
- expect(guides.sillHead?.sill).toBeCloseTo(1);
139
- expect(guides.sillHead?.head).toBeCloseTo(0.5); // 2.5 - 2
140
- expect(guides.sillHead?.bottomY).toBeCloseTo(1);
141
- expect(guides.sillHead?.topY).toBeCloseTo(2);
142
- });
143
- test('omits vertical guides for doors (sit on the floor)', () => {
144
- const moving = span('m', 5, 1, 1, 2);
145
- const sib = span('s', 8, 1, 1, 2);
146
- const guides = computeOpeningGuides({
147
- moving,
148
- siblings: [sib],
149
- wall: WALL,
150
- includeVertical: false,
151
- });
152
- expect(guides.sillHead).toBeNull();
153
- expect(guides.vertical).toBeNull();
154
- // along-wall + proximity still computed for doors
155
- expect(guides.gaps.length).toBeGreaterThan(0);
156
- });
157
- test('combines proximity and equal-spacing in one pass', () => {
158
- const moving = span('b', 2.5, 1);
159
- const guides = computeOpeningGuides({
160
- moving,
161
- siblings: [span('a', 0.5, 1), span('c', 4.5, 1)],
162
- wall: WALL,
163
- includeVertical: true,
164
- });
165
- expect(guides.gaps).toHaveLength(2);
166
- expect(guides.equalSpacing?.gap).toBeCloseTo(1);
167
- expect(guides.equalSpacing?.openingIds).toEqual(['a', 'b', 'c']);
168
- });
169
- });
170
- describe('opening-guides — review regressions', () => {
171
- test('detectEqualSpacing finds a run that starts partway through a drifting sequence', () => {
172
- // gaps 1.00, 1.02, 1.04 — only [b,c,d] is equal within 0.03 and includes the
173
- // moving opening; a first-gap-anchored greedy scan used to drop it.
174
- const openings = [span('a', 0.5, 1), span('b', 2.5, 1), span('c', 4.52, 1), span('d', 6.56, 1)];
175
- const run = detectEqualSpacing(openings, 'd', 0.03, 0.02);
176
- expect(run?.openingIds).toEqual(['b', 'c', 'd']);
177
- expect(run?.gap).toBeCloseTo(1.03);
178
- expect(run?.segments).toHaveLength(2);
179
- });
180
- test('detectEqualSpacing prefers the leftmost run on a length tie', () => {
181
- // gaps 1,1,2,2 with the moving opening in the middle — two equal-length runs.
182
- const openings = [
183
- span('a', 0.5, 1),
184
- span('b', 2.5, 1),
185
- span('c', 4.5, 1),
186
- span('d', 7.5, 1),
187
- span('e', 10.5, 1),
188
- ];
189
- expect(detectEqualSpacing(openings, 'c', 0.03, 0.02)?.openingIds).toEqual(['a', 'b', 'c']);
190
- });
191
- test('computeEdgeGaps suppresses both sides when a sibling overlaps', () => {
192
- const moving = span('m', 5, 1); // [4.5,5.5]
193
- const containing = span('s', 5, 2); // [4,6] straddles both edges
194
- expect(computeEdgeGaps(moving, [containing], WALL, 0.02)).toEqual([]);
195
- });
196
- test('alignment detectors ignore the moving opening if present in siblings', () => {
197
- const moving = span('m', 5, 2, 1.5, 1);
198
- expect(detectAlongWallAlignment(moving, [moving], 0.08)).toBeNull();
199
- expect(detectVerticalAlignment(moving, [moving], 0.08)).toBeNull();
200
- });
201
- test('detectAlongWallAlignment reports a negative snap when the feature is past the target', () => {
202
- const moving = span('m', 5, 2); // centre 5
203
- const sib = span('s', 4.96, 0.5); // centre 4.96
204
- const a = detectAlongWallAlignment(moving, [sib], 0.08);
205
- expect(a?.movingFeature).toBe('center');
206
- expect(a?.snap).toBeCloseTo(-0.04);
207
- });
208
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=port-connectivity.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"port-connectivity.test.d.ts","sourceRoot":"","sources":["../../src/services/port-connectivity.test.ts"],"names":[],"mappings":""}
@@ -1,297 +0,0 @@
1
- import { describe, expect, test } from 'bun:test';
2
- import { registerNode } from '../registry';
3
- import { analyzePortConnectivity, resolveConnectivityUpdates } from './port-connectivity';
4
- // Stub registrations mirroring the real kinds' port + role conventions
5
- // without importing the nodes package (which pulls in CSG and can't load
6
- // under the test runner). A run exposes start/end at its path tips; the
7
- // fitting here is a simple two-collar elbow at ±X around its position.
8
- function stubDef(kind, distributionRole, ports) {
9
- registerNode({
10
- kind,
11
- schemaVersion: 1,
12
- schema: {},
13
- category: 'utility',
14
- distributionRole,
15
- defaults: () => ({}),
16
- capabilities: {},
17
- ports,
18
- });
19
- }
20
- stubDef('duct-segment', 'run', (node) => {
21
- const path = node.path;
22
- const system = node.system;
23
- return [
24
- { id: 'start', position: path[0], direction: [-1, 0, 0], diameter: 6, system },
25
- { id: 'end', position: path[path.length - 1], direction: [1, 0, 0], diameter: 6, system },
26
- ];
27
- });
28
- stubDef('duct-fitting', 'fitting', (node) => {
29
- const position = node.position;
30
- const system = node.system;
31
- return [
32
- {
33
- id: 'inlet',
34
- position: [position[0] - 0.2, position[1], position[2]],
35
- direction: [-1, 0, 0],
36
- diameter: 6,
37
- system,
38
- },
39
- {
40
- id: 'outlet',
41
- position: [position[0] + 0.2, position[1], position[2]],
42
- direction: [1, 0, 0],
43
- diameter: 6,
44
- system,
45
- },
46
- ];
47
- });
48
- stubDef('duct-tee', 'fitting', (node) => {
49
- const position = node.position;
50
- const system = node.system;
51
- return [
52
- {
53
- id: 'inlet',
54
- position: [position[0] - 0.2, position[1], position[2]],
55
- direction: [-1, 0, 0],
56
- diameter: 6,
57
- system,
58
- },
59
- {
60
- id: 'outlet',
61
- position: [position[0] + 0.2, position[1], position[2]],
62
- direction: [1, 0, 0],
63
- diameter: 6,
64
- system,
65
- },
66
- {
67
- id: 'branch',
68
- position: [position[0], position[1], position[2] + 0.2],
69
- direction: [0, 0, 1],
70
- diameter: 6,
71
- system,
72
- },
73
- ];
74
- });
75
- let nextId = 0;
76
- function makeNode(type, fields) {
77
- nextId += 1;
78
- return { id: `${type}_${nextId}`, type, object: 'node', parentId: null, ...fields };
79
- }
80
- function sceneOf(...nodes) {
81
- return Object.fromEntries(nodes.map((n) => [n.id, n]));
82
- }
83
- function expectPointClose(actual, expected) {
84
- expect(actual[0]).toBeCloseTo(expected[0], 6);
85
- expect(actual[1]).toBeCloseTo(expected[1], 6);
86
- expect(actual[2]).toBeCloseTo(expected[2], 6);
87
- }
88
- describe('port connectivity — joint follow (stretch vs translate)', () => {
89
- // Layout: duct A ends at the fitting's inlet (−0.2,0,0); duct B starts at the
90
- // fitting's outlet (+0.2,0,0). Both runs lie on the X axis. Dragging A's
91
- // mated endpoint carries the fitting and duct B; how B reacts depends on
92
- // whether the drag is along its axis (stretch) or across it (translate).
93
- function joint() {
94
- const fitting = makeNode('duct-fitting', { position: [0, 0, 0], system: 'supply' });
95
- const ductA = makeNode('duct-segment', {
96
- path: [
97
- [-3, 0, 0],
98
- [-0.2, 0, 0],
99
- ],
100
- system: 'supply',
101
- });
102
- const ductB = makeNode('duct-segment', {
103
- path: [
104
- [0.2, 0, 0],
105
- [3, 0, 0],
106
- ],
107
- system: 'supply',
108
- });
109
- return { fitting, ductA, ductB };
110
- }
111
- function movedA(end) {
112
- const { ductA } = joint();
113
- return { ...ductA, path: [[-3, 0, 0], end] };
114
- }
115
- test('the fitting and sibling run are picked up as carried connections', () => {
116
- const { fitting, ductA, ductB } = joint();
117
- const connectivity = analyzePortConnectivity(ductA, sceneOf(fitting, ductA, ductB));
118
- expect(connectivity.connections.find((c) => c.kind === 'rigid-node' && c.nodeId === fitting.id)).toBeDefined();
119
- expect(connectivity.connections.find((c) => c.kind === 'run' && c.nodeId === ductB.id)).toBeDefined();
120
- });
121
- test('perpendicular drag translates the WHOLE sibling run (no skew)', () => {
122
- const { fitting, ductA, ductB } = joint();
123
- const nodes = sceneOf(fitting, ductA, ductB);
124
- const connectivity = analyzePortConnectivity(ductA, nodes);
125
- // Move A's mated end +1 in Z — perpendicular to B's X axis.
126
- const updates = resolveConnectivityUpdates(connectivity, movedA([-0.2, 0, 1]));
127
- expect(updates.find((u) => u.id === fitting.id).data.position).toEqual([0, 0, 1]);
128
- const bPath = updates.find((u) => u.id === ductB.id).data.path;
129
- // Both ends ride +1 in Z: the run keeps its length and direction.
130
- expect(bPath[0]).toEqual([0.2, 0, 1]);
131
- expect(bPath[1]).toEqual([3, 0, 1]);
132
- });
133
- test('parallel drag stretches the sibling run (only the near end slides)', () => {
134
- const { fitting, ductA, ductB } = joint();
135
- const nodes = sceneOf(fitting, ductA, ductB);
136
- const connectivity = analyzePortConnectivity(ductA, nodes);
137
- // Move A's mated end +0.5 in X — along B's axis (the fitting slides toward B).
138
- const updates = resolveConnectivityUpdates(connectivity, movedA([0.3, 0, 0]));
139
- const bPath = updates.find((u) => u.id === ductB.id).data.path;
140
- // Near end slid +0.5 in X; far end stayed put → the run shortened.
141
- expect(bPath[0]).toEqual([0.7, 0, 0]);
142
- expect(bPath[1]).toEqual([3, 0, 0]);
143
- });
144
- test('perpendicular slide propagates through the sibling run to its far joint', () => {
145
- // Extend the chain: duct B's far end (3,0,0) meets a second elbow, and duct
146
- // C hangs off that elbow. A perpendicular drag should carry the whole chain.
147
- const { fitting, ductA, ductB } = joint();
148
- const elbow2 = makeNode('duct-fitting', { position: [3.2, 0, 0], system: 'supply' });
149
- // elbow ports are ±0.2 on X around its position → inlet at (3,0,0) meets B.
150
- const ductC = makeNode('duct-segment', {
151
- path: [
152
- [3.4, 0, 0],
153
- [6, 0, 0],
154
- ],
155
- system: 'supply',
156
- });
157
- const nodes = sceneOf(fitting, ductA, ductB, elbow2, ductC);
158
- const connectivity = analyzePortConnectivity(ductA, nodes);
159
- const updates = resolveConnectivityUpdates(connectivity, movedA([-0.2, 0, 1]));
160
- // Whole chain rode +1 in Z.
161
- const bPath = updates.find((u) => u.id === ductB.id).data.path;
162
- expect(bPath[1]).toEqual([3, 0, 1]);
163
- expect(updates.find((u) => u.id === elbow2.id).data.position).toEqual([3.2, 0, 1]);
164
- const cPath = updates.find((u) => u.id === ductC.id).data.path;
165
- expect(cPath[0]).toEqual([3.4, 0, 1]);
166
- expect(cPath[1]).toEqual([6, 0, 1]);
167
- });
168
- test('a run reached from both ends applies both endpoint deltas', () => {
169
- const moved = makeNode('duct-segment', {
170
- path: [
171
- [0, 0, 0],
172
- [3, 0, 0],
173
- ],
174
- system: 'supply',
175
- });
176
- const follower = makeNode('duct-segment', {
177
- path: [
178
- [0, 0, 0],
179
- [3, 0, 0],
180
- ],
181
- system: 'supply',
182
- });
183
- const nodes = sceneOf(moved, follower);
184
- const connectivity = analyzePortConnectivity(moved, nodes);
185
- const preview = {
186
- ...moved,
187
- path: [
188
- [0, 0, 1],
189
- [3, 0, 2],
190
- ],
191
- };
192
- const updates = resolveConnectivityUpdates(connectivity, preview);
193
- const path = updates.find((u) => u.id === follower.id).data.path;
194
- expect(path[0]).toEqual([0, 0, 1]);
195
- expect(path[1]).toEqual([3, 0, 2]);
196
- });
197
- test('a polyline run reached from both ends preserves interior bend shape', () => {
198
- const moved = makeNode('duct-segment', {
199
- path: [
200
- [0, 0, 0],
201
- [3, 0, 3],
202
- ],
203
- system: 'supply',
204
- });
205
- const follower = makeNode('duct-segment', {
206
- path: [
207
- [0, 0, 0],
208
- [1, 0, 0],
209
- [1, 0, 3],
210
- [3, 0, 3],
211
- ],
212
- system: 'supply',
213
- });
214
- const nodes = sceneOf(moved, follower);
215
- const connectivity = analyzePortConnectivity(moved, nodes);
216
- const preview = {
217
- ...moved,
218
- path: [
219
- [-0.5, 0, 0],
220
- [3.5, 0, 3],
221
- ],
222
- };
223
- const updates = resolveConnectivityUpdates(connectivity, preview);
224
- const path = updates.find((u) => u.id === follower.id).data.path;
225
- expect(path).toEqual([
226
- [-0.5, 0, 0],
227
- [1, 0, 0],
228
- [1, 0, 3],
229
- [3.5, 0, 3],
230
- ]);
231
- });
232
- test('a fitting reached from both collars rebroadcasts its final compatible rigid delta', () => {
233
- const moved = makeNode('duct-segment', {
234
- path: [
235
- [-0.2, 0, 0],
236
- [0.2, 0, 0],
237
- ],
238
- system: 'supply',
239
- });
240
- const fitting = makeNode('duct-tee', { position: [0, 0, 0], system: 'supply' });
241
- const downstream = makeNode('duct-segment', {
242
- path: [
243
- [0, 0, 0.2],
244
- [3, 0, 0.2],
245
- ],
246
- system: 'supply',
247
- });
248
- const nodes = sceneOf(moved, fitting, downstream);
249
- const connectivity = analyzePortConnectivity(moved, nodes);
250
- const preview = {
251
- ...moved,
252
- path: [
253
- [-0.2, 0, 1],
254
- [0.2, 0, 1.00005],
255
- ],
256
- };
257
- const updates = resolveConnectivityUpdates(connectivity, preview);
258
- expectPointClose(updates.find((u) => u.id === fitting.id).data.position, [0, 0, 1.000025]);
259
- const path = updates.find((u) => u.id === downstream.id).data.path;
260
- expectPointClose(path[0], [0, 0, 1.200025]);
261
- expectPointClose(path[1], [3, 0, 1.200025]);
262
- });
263
- test('a fitting reached from incompatible collars merges constraints deterministically', () => {
264
- const moved = makeNode('duct-segment', {
265
- path: [
266
- [-0.2, 0, 0],
267
- [0.2, 0, 0],
268
- ],
269
- system: 'supply',
270
- });
271
- const fitting = makeNode('duct-fitting', { position: [0, 0, 0], system: 'supply' });
272
- const nodes = sceneOf(moved, fitting);
273
- const connectivity = analyzePortConnectivity(moved, nodes);
274
- const preview = {
275
- ...moved,
276
- path: [
277
- [-0.2, 0, 1],
278
- [0.2, 0, -1],
279
- ],
280
- };
281
- const updates = resolveConnectivityUpdates(connectivity, preview);
282
- expectPointClose(updates.find((u) => u.id === fitting.id).data.position, [0, 0, 0]);
283
- });
284
- test('an unrelated run not on the fitting is left alone', () => {
285
- const { fitting, ductA, ductB } = joint();
286
- const distant = makeNode('duct-segment', {
287
- path: [
288
- [10, 0, 0],
289
- [13, 0, 0],
290
- ],
291
- system: 'supply',
292
- });
293
- const nodes = sceneOf(fitting, ductA, ductB, distant);
294
- const connectivity = analyzePortConnectivity(ductA, nodes);
295
- expect(connectivity.connections.find((c) => c.nodeId === distant.id)).toBeUndefined();
296
- });
297
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=riser-diagram.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"riser-diagram.test.d.ts","sourceRoot":"","sources":["../../src/services/riser-diagram.test.ts"],"names":[],"mappings":""}
@@ -1,66 +0,0 @@
1
- import { describe, expect, test } from 'bun:test';
2
- import { buildRiserDiagram, projectIso } from './riser-diagram';
3
- let nextId = 0;
4
- function makeNode(type, fields) {
5
- nextId += 1;
6
- return { id: `${type}_${nextId}`, type, object: 'node', parentId: null, ...fields };
7
- }
8
- function sceneOf(...nodes) {
9
- return Object.fromEntries(nodes.map((n) => [n.id, n]));
10
- }
11
- describe('projectIso', () => {
12
- test('higher elevation maps to smaller screen Y', () => {
13
- const [, lowY] = projectIso(0, 0, 0);
14
- const [, highY] = projectIso(0, 2, 0);
15
- expect(highY).toBeLessThan(lowY);
16
- });
17
- });
18
- describe('buildRiserDiagram', () => {
19
- test('null when no DWV nodes', () => {
20
- const wall = makeNode('wall', {});
21
- expect(buildRiserDiagram(sceneOf(wall))).toBeNull();
22
- });
23
- test('classifies a vertical stack vs a sloped horizontal drain', () => {
24
- const stack = makeNode('pipe-segment', {
25
- path: [
26
- [0, 0, 0],
27
- [0, 3, 0],
28
- ],
29
- diameter: 3,
30
- system: 'vent',
31
- });
32
- const drain = makeNode('pipe-segment', {
33
- path: [
34
- [0, 0, 0],
35
- [3, -0.06, 0],
36
- ],
37
- diameter: 2,
38
- system: 'waste',
39
- });
40
- const diagram = buildRiserDiagram(sceneOf(stack, drain));
41
- const stackLine = diagram.lines.find((l) => l.nodeId === stack.id);
42
- const drainLine = diagram.lines.find((l) => l.nodeId === drain.id);
43
- expect(stackLine.vertical).toBe(true);
44
- expect(drainLine.vertical).toBe(false);
45
- });
46
- test('emits a vent-termination marker for a vent run', () => {
47
- const vent = makeNode('pipe-segment', {
48
- path: [
49
- [0, 0, 0],
50
- [0, 3, 0],
51
- ],
52
- diameter: 2,
53
- system: 'vent',
54
- });
55
- const diagram = buildRiserDiagram(sceneOf(vent));
56
- expect(diagram.markers.some((m) => m.kind === 'vent-termination')).toBe(true);
57
- });
58
- test('labels traps', () => {
59
- const trap = makeNode('pipe-trap', {
60
- position: [1, 0, 0],
61
- diameter: 1.5,
62
- });
63
- const diagram = buildRiserDiagram(sceneOf(trap));
64
- expect(diagram.markers.some((m) => m.kind === 'trap')).toBe(true);
65
- });
66
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=single-undo-dance.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"single-undo-dance.test.d.ts","sourceRoot":"","sources":["../../src/services/single-undo-dance.test.ts"],"names":[],"mappings":""}