@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,3 +1,4 @@
1
+ import { nodeRegistry } from '../registry';
1
2
  import { AnyNode } from '../schema/types';
2
3
  import { healSceneNodes } from '../utils/heal-scene-graph';
3
4
  const KNOWN_TYPES = new Set(AnyNode.options.map((o) => o.shape.type.parse(undefined)));
@@ -34,7 +35,13 @@ export function validateBuildJson(input) {
34
35
  const errors = [];
35
36
  const warnings = [];
36
37
  const schemaIssues = [];
37
- const stats = { total: 0, byType: {}, unknownTypes: {}, floorAreaM2: 0 };
38
+ const stats = {
39
+ total: 0,
40
+ byType: {},
41
+ pluginTypes: {},
42
+ unknownTypes: {},
43
+ floorAreaM2: 0,
44
+ };
38
45
  if (!isPlainObject(input)) {
39
46
  errors.push({
40
47
  severity: 'error',
@@ -109,6 +116,33 @@ export function validateBuildJson(input) {
109
116
  message: '"rootNodeIds" is empty — no entry point into the scene.',
110
117
  });
111
118
  }
119
+ // Ids of nodes whose type falls outside the static schema union — plugin
120
+ // kinds (`trees:tree`) or genuinely unknown types. The scene store accepts
121
+ // them on load (they already round-trip through the DB fine) and they're
122
+ // surfaced by the unknown-types warning, but a parent's strict `children`
123
+ // id union would hard-fail over them: validate parents against a copy with
124
+ // those ids filtered out. The imported data itself keeps them.
125
+ const nonSchemaNodeIds = new Set();
126
+ for (const [key, value] of Object.entries(nodes)) {
127
+ if (!isPlainObject(value))
128
+ continue;
129
+ const type = typeof value.type === 'string' ? value.type : null;
130
+ if (type && KNOWN_TYPES.has(type))
131
+ continue;
132
+ nonSchemaNodeIds.add(typeof value.id === 'string' ? value.id : key);
133
+ }
134
+ const withoutNonSchemaChildren = (value) => {
135
+ const children = value.children;
136
+ if (!Array.isArray(children))
137
+ return value;
138
+ if (!children.some((child) => typeof child === 'string' && nonSchemaNodeIds.has(child))) {
139
+ return value;
140
+ }
141
+ return {
142
+ ...value,
143
+ children: children.filter((child) => !(typeof child === 'string' && nonSchemaNodeIds.has(child))),
144
+ };
145
+ };
112
146
  let validRootCount = 0;
113
147
  let mismatchedKeyCount = 0;
114
148
  let schemaFailureCount = 0;
@@ -141,7 +175,7 @@ export function validateBuildJson(input) {
141
175
  if (KNOWN_TYPES.has(type)) {
142
176
  const t = type;
143
177
  stats.byType[t] = (stats.byType[t] ?? 0) + 1;
144
- const parseResult = AnyNode.safeParse(value);
178
+ const parseResult = AnyNode.safeParse(withoutNonSchemaChildren(value));
145
179
  if (!parseResult.success) {
146
180
  schemaFailureCount += 1;
147
181
  const issue = parseResult.error.issues[0];
@@ -168,7 +202,29 @@ export function validateBuildJson(input) {
168
202
  }
169
203
  }
170
204
  else {
171
- stats.unknownTypes[type] = (stats.unknownTypes[type] ?? 0) + 1;
205
+ const registered = nodeRegistry.get(type);
206
+ if (registered) {
207
+ // A runtime-registered plugin kind (e.g. `trees:tree`) is a
208
+ // first-class citizen: validate it with its own registered schema
209
+ // instead of flagging it unknown. Files from projects whose plugin
210
+ // is NOT loaded here still fall through to the unknown-types
211
+ // warning below.
212
+ stats.pluginTypes[type] = (stats.pluginTypes[type] ?? 0) + 1;
213
+ const parseResult = registered.schema.safeParse(value);
214
+ if (!parseResult.success) {
215
+ schemaFailureCount += 1;
216
+ const issue = parseResult.error.issues[0];
217
+ schemaIssues.push({
218
+ nodeId: key,
219
+ nodeType: type,
220
+ path: issue ? issue.path.join('.') : '',
221
+ message: issue ? issue.message : 'schema mismatch',
222
+ });
223
+ }
224
+ }
225
+ else {
226
+ stats.unknownTypes[type] = (stats.unknownTypes[type] ?? 0) + 1;
227
+ }
172
228
  }
173
229
  if (parentId && !(parentId in nodes)) {
174
230
  warnings.push({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pascal-app/core",
3
- "version": "0.9.2",
3
+ "version": "1.0.0-beta.1",
4
4
  "description": "Core library for Pascal 3D building editor",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -59,7 +59,7 @@
59
59
  "scripts": {
60
60
  "build": "tsc --build",
61
61
  "dev": "tsgo --build --watch",
62
- "test": "bun test",
62
+ "test": "bun test src",
63
63
  "bench:registry": "bun run src/registry/__bench__/relations-resolver.bench.ts",
64
64
  "prepublishOnly": "npm run build"
65
65
  },
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=scene-registry.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scene-registry.test.d.ts","sourceRoot":"","sources":["../../../src/hooks/scene-registry/scene-registry.test.ts"],"names":[],"mappings":""}
@@ -1,26 +0,0 @@
1
- import { describe, expect, test } from 'bun:test';
2
- import { Group } from 'three';
3
- import { sceneRegistry } from './scene-registry';
4
- describe('sceneRegistry revision', () => {
5
- test('changes only when registered object membership changes', () => {
6
- sceneRegistry.clear();
7
- const initial = sceneRegistry.revision;
8
- const object = new Group();
9
- sceneRegistry.nodes.set('wall_a', object);
10
- expect(sceneRegistry.revision).toBe(initial + 1);
11
- sceneRegistry.nodes.set('wall_a', object);
12
- expect(sceneRegistry.revision).toBe(initial + 1);
13
- sceneRegistry.nodes.delete('missing');
14
- expect(sceneRegistry.revision).toBe(initial + 1);
15
- sceneRegistry.nodes.delete('wall_a');
16
- expect(sceneRegistry.revision).toBe(initial + 2);
17
- });
18
- test('clear invalidates a populated registry once', () => {
19
- sceneRegistry.clear();
20
- sceneRegistry.nodes.set('wall_a', new Group());
21
- sceneRegistry.nodes.set('wall_b', new Group());
22
- const beforeClear = sceneRegistry.revision;
23
- sceneRegistry.clear();
24
- expect(sceneRegistry.revision).toBe(beforeClear + 1);
25
- });
26
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=floor-placed-elevation.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"floor-placed-elevation.test.d.ts","sourceRoot":"","sources":["../../../src/hooks/spatial-grid/floor-placed-elevation.test.ts"],"names":[],"mappings":""}
@@ -1,366 +0,0 @@
1
- import { beforeEach, describe, expect, test } from 'bun:test';
2
- import { z } from 'zod';
3
- import { nodeRegistry, registerNode } from '../../registry';
4
- import useScene from '../../store/use-scene';
5
- import { getFloorPlacedElevation, getFloorStackedPosition } from './floor-placed-elevation';
6
- import { spatialGridManager } from './spatial-grid-manager';
7
- const LEVEL_ID = 'level_test';
8
- function makeDefinition(kind, capabilities = {}) {
9
- return {
10
- kind,
11
- schemaVersion: 1,
12
- schema: z.object({ type: z.literal(kind) }),
13
- category: 'utility',
14
- defaults: () => ({}),
15
- capabilities,
16
- };
17
- }
18
- function makeLevel() {
19
- return {
20
- id: LEVEL_ID,
21
- type: 'level',
22
- object: 'node',
23
- parentId: null,
24
- visible: true,
25
- metadata: {},
26
- children: [],
27
- level: 0,
28
- };
29
- }
30
- function makeFloorNode(overrides = {}) {
31
- return {
32
- id: 'item_test',
33
- type: 'item',
34
- object: 'node',
35
- parentId: LEVEL_ID,
36
- visible: true,
37
- metadata: {},
38
- children: [],
39
- position: [0, 0, 0],
40
- rotation: [0, 0, 0],
41
- scale: [1, 1, 1],
42
- asset: {
43
- id: 'asset_test',
44
- category: 'test',
45
- name: 'Test',
46
- thumbnail: '',
47
- src: 'asset:test',
48
- dimensions: [1, 1, 1],
49
- source: 'library',
50
- },
51
- ...overrides,
52
- };
53
- }
54
- function addSlab(polygon, elevation, id = `slab_${elevation}`) {
55
- const slab = {
56
- id,
57
- type: 'slab',
58
- object: 'node',
59
- parentId: LEVEL_ID,
60
- visible: true,
61
- metadata: {},
62
- children: [],
63
- polygon,
64
- holes: [],
65
- holeMetadata: [],
66
- elevation,
67
- autoFromWalls: false,
68
- };
69
- spatialGridManager.handleNodeCreated(slab, LEVEL_ID);
70
- }
71
- function nodesFor(...nodes) {
72
- return Object.fromEntries(nodes.map((node) => [node.id, node]));
73
- }
74
- describe('floor-placed elevation resolver', () => {
75
- beforeEach(() => {
76
- nodeRegistry._reset();
77
- spatialGridManager.clear();
78
- useScene.setState({ nodes: {} });
79
- });
80
- test('returns 0 without a floorPlaced capability', () => {
81
- registerNode(makeDefinition('item'));
82
- addSlab([
83
- [-1, -1],
84
- [1, -1],
85
- [1, 1],
86
- [-1, 1],
87
- ], 0.4);
88
- const level = makeLevel();
89
- const node = makeFloorNode();
90
- expect(getFloorPlacedElevation({
91
- node,
92
- nodes: nodesFor(level, node),
93
- position: [0, 0, 0],
94
- rotation: [0, 0, 0],
95
- })).toBe(0);
96
- });
97
- test('canPlaceOnFloorFootprints accepts an L-shaped draft in the open corner gap', () => {
98
- const baseAsset = makeFloorNode().asset;
99
- registerNode(makeDefinition('item', {
100
- floorPlaced: {
101
- footprint: (node) => ({
102
- dimensions: node.asset
103
- .dimensions,
104
- rotation: [0, node.rotation[1] ?? 0, 0],
105
- }),
106
- collides: true,
107
- },
108
- }));
109
- const level = makeLevel();
110
- const blocker = makeFloorNode({
111
- id: 'item_blocker',
112
- position: [0.85, 0, 0.85],
113
- asset: {
114
- ...baseAsset,
115
- id: 'asset_blocker',
116
- name: 'Blocker',
117
- src: 'asset:blocker',
118
- dimensions: [0.3, 1, 0.3],
119
- },
120
- });
121
- useScene.setState({ nodes: nodesFor(level, blocker) });
122
- const coarse = spatialGridManager.canPlaceOnFloor(LEVEL_ID, [0.5, 0, 0.5], [1, 1, 1], [0, 0, 0]);
123
- const precise = spatialGridManager.canPlaceOnFloorFootprints(LEVEL_ID, [
124
- { position: [0.2, 0, 0.5], dimensions: [0.4, 1, 1], rotation: [0, 0, 0] },
125
- { position: [0.8, 0, 0.2], dimensions: [0.4, 1, 0.4], rotation: [0, 0, 0] },
126
- ]);
127
- expect(coarse.valid).toBe(false);
128
- expect(coarse.conflictIds).toEqual(['item_blocker']);
129
- expect(precise.valid).toBe(true);
130
- expect(precise.conflictIds).toEqual([]);
131
- });
132
- test('canPlaceOnFloorFootprints rejects overlapping draft footprints', () => {
133
- useScene.setState({ nodes: nodesFor(makeLevel()) });
134
- const result = spatialGridManager.canPlaceOnFloorFootprints(LEVEL_ID, [
135
- { position: [0, 0, 0], dimensions: [1, 1, 1], rotation: [0, 0, 0] },
136
- { position: [0.25, 0, 0], dimensions: [1, 1, 1], rotation: [0, 0, 0] },
137
- ]);
138
- expect(result.valid).toBe(false);
139
- expect(result.conflictIds).toEqual([]);
140
- });
141
- test('canPlaceOnFloorFootprints ignores descendants of an ignored composite node', () => {
142
- registerNode(makeDefinition('cabinet', {
143
- floorPlaced: {
144
- footprint: () => ({
145
- dimensions: [1, 1, 1],
146
- rotation: [0, 0, 0],
147
- }),
148
- collides: true,
149
- },
150
- }));
151
- registerNode(makeDefinition('cabinet-module', {
152
- floorPlaced: {
153
- footprint: () => ({
154
- dimensions: [1, 1, 1],
155
- rotation: [0, 0, 0],
156
- }),
157
- collides: true,
158
- },
159
- }));
160
- const level = makeLevel();
161
- const run = {
162
- id: 'cabinet_run',
163
- type: 'cabinet',
164
- object: 'node',
165
- parentId: LEVEL_ID,
166
- visible: true,
167
- metadata: {},
168
- children: ['cabinet-module_child'],
169
- position: [0, 0, 0],
170
- rotation: 0,
171
- };
172
- const module = {
173
- id: 'cabinet-module_child',
174
- type: 'cabinet-module',
175
- object: 'node',
176
- parentId: run.id,
177
- visible: true,
178
- metadata: {},
179
- children: [],
180
- position: [0, 0, 0],
181
- rotation: 0,
182
- };
183
- useScene.setState({ nodes: nodesFor(level, run, module) });
184
- const result = spatialGridManager.canPlaceOnFloorFootprints(LEVEL_ID, [{ position: [0, 0, 0], dimensions: [1, 1, 1], rotation: [0, 0, 0] }], [run.id]);
185
- expect(result.valid).toBe(true);
186
- expect(result.conflictIds).toEqual([]);
187
- });
188
- test('returns 0 when applies returns false', () => {
189
- registerNode(makeDefinition('item', {
190
- floorPlaced: {
191
- footprint: () => ({ dimensions: [1, 1, 1], rotation: [0, 0, 0] }),
192
- applies: () => false,
193
- },
194
- }));
195
- addSlab([
196
- [-1, -1],
197
- [1, -1],
198
- [1, 1],
199
- [-1, 1],
200
- ], 0.4);
201
- const level = makeLevel();
202
- const node = makeFloorNode();
203
- expect(getFloorPlacedElevation({
204
- node,
205
- nodes: nodesFor(level, node),
206
- position: [0, 0, 0],
207
- rotation: [0, 0, 0],
208
- })).toBe(0);
209
- });
210
- test('clamps non-finite slab elevation to 0', () => {
211
- registerNode(makeDefinition('item', {
212
- floorPlaced: {
213
- footprint: () => ({ dimensions: [1, 1, 1], rotation: [0, 0, 0] }),
214
- },
215
- }));
216
- const original = spatialGridManager.getSlabElevationForItem;
217
- spatialGridManager.getSlabElevationForItem = (() => Number.NaN);
218
- try {
219
- const level = makeLevel();
220
- const node = makeFloorNode();
221
- expect(getFloorPlacedElevation({
222
- node,
223
- nodes: nodesFor(level, node),
224
- position: [0, 0, 0],
225
- rotation: [0, 0, 0],
226
- })).toBe(0);
227
- }
228
- finally {
229
- spatialGridManager.getSlabElevationForItem = original;
230
- }
231
- });
232
- test('returns 0 for a non-level direct parent', () => {
233
- registerNode(makeDefinition('item', {
234
- floorPlaced: {
235
- footprint: () => ({ dimensions: [1, 1, 1], rotation: [0, 0, 0] }),
236
- },
237
- }));
238
- addSlab([
239
- [-1, -1],
240
- [1, -1],
241
- [1, 1],
242
- [-1, 1],
243
- ], 0.4);
244
- const level = makeLevel();
245
- const shelf = {
246
- id: 'shelf_test',
247
- type: 'shelf',
248
- parentId: LEVEL_ID,
249
- };
250
- const node = makeFloorNode({ parentId: shelf.id });
251
- expect(getFloorPlacedElevation({
252
- node,
253
- nodes: nodesFor(level, shelf, node),
254
- position: [0, 0, 0],
255
- rotation: [0, 0, 0],
256
- })).toBe(0);
257
- });
258
- test('returns 0 when the declared parent is missing', () => {
259
- registerNode(makeDefinition('item', {
260
- floorPlaced: {
261
- footprint: () => ({ dimensions: [1, 1, 1], rotation: [0, 0, 0] }),
262
- },
263
- }));
264
- addSlab([
265
- [-1, -1],
266
- [1, -1],
267
- [1, 1],
268
- [-1, 1],
269
- ], 0.4);
270
- const node = makeFloorNode({ parentId: 'missing_level' });
271
- expect(getFloorPlacedElevation({
272
- node,
273
- nodes: nodesFor(node),
274
- position: [0, 0, 0],
275
- rotation: [0, 0, 0],
276
- levelId: LEVEL_ID,
277
- })).toBe(0);
278
- });
279
- test('uses the pending rotated footprint', () => {
280
- registerNode(makeDefinition('item', {
281
- floorPlaced: {
282
- footprint: (node) => ({
283
- dimensions: [4, 1, 1],
284
- rotation: node.rotation,
285
- }),
286
- },
287
- }));
288
- addSlab([
289
- [-0.2, 1.2],
290
- [0.2, 1.2],
291
- [0.2, 1.8],
292
- [-0.2, 1.8],
293
- ], 0.45);
294
- const level = makeLevel();
295
- const node = makeFloorNode();
296
- expect(getFloorPlacedElevation({
297
- node,
298
- nodes: nodesFor(level, node),
299
- position: [0, 0, 0],
300
- rotation: [0, Math.PI / 2, 0],
301
- })).toBeCloseTo(0.45);
302
- });
303
- test('returns slab overlap elevation and stacks Y onto canonical position', () => {
304
- registerNode(makeDefinition('item', {
305
- floorPlaced: {
306
- footprint: (node) => ({
307
- dimensions: [1, 1, 1],
308
- rotation: node.rotation,
309
- }),
310
- },
311
- }));
312
- addSlab([
313
- [-1, -1],
314
- [1, -1],
315
- [1, 1],
316
- [-1, 1],
317
- ], 0.35);
318
- const level = makeLevel();
319
- const node = makeFloorNode();
320
- expect(getFloorPlacedElevation({
321
- node,
322
- nodes: nodesFor(level, node),
323
- position: [0, 0.1, 0],
324
- rotation: [0, 0, 0],
325
- })).toBeCloseTo(0.35);
326
- const stacked = getFloorStackedPosition({
327
- node,
328
- nodes: nodesFor(level, node),
329
- position: [0, 0.1, 0],
330
- rotation: [0, 0, 0],
331
- });
332
- expect(stacked[0]).toBe(0);
333
- expect(stacked[1]).toBeCloseTo(0.45);
334
- expect(stacked[2]).toBe(0);
335
- });
336
- test('takes the max elevation across composite footprints', () => {
337
- registerNode(makeDefinition('item', {
338
- floorPlaced: {
339
- footprints: () => [
340
- { position: [0, 0, 0], dimensions: [1, 1, 1], rotation: [0, 0, 0] },
341
- { position: [3, 0, 0], dimensions: [1, 1, 1], rotation: [0, 0, 0] },
342
- ],
343
- },
344
- }));
345
- addSlab([
346
- [-1, -1],
347
- [1, -1],
348
- [1, 1],
349
- [-1, 1],
350
- ], 0.2, 'slab_low');
351
- addSlab([
352
- [2.5, -0.5],
353
- [3.5, -0.5],
354
- [3.5, 0.5],
355
- [2.5, 0.5],
356
- ], 0.8, 'slab_high');
357
- const level = makeLevel();
358
- const node = makeFloorNode();
359
- expect(getFloorPlacedElevation({
360
- node,
361
- nodes: nodesFor(level, node),
362
- position: [0, 0, 0],
363
- rotation: [0, 0, 0],
364
- })).toBeCloseTo(0.8);
365
- });
366
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=wall-slab-overlap.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"wall-slab-overlap.test.d.ts","sourceRoot":"","sources":["../../../src/hooks/spatial-grid/wall-slab-overlap.test.ts"],"names":[],"mappings":""}