@pascal-app/core 1.0.0-beta.5 → 1.0.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 (417) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +23 -0
  3. package/dist/capture/index.d.ts +3 -0
  4. package/dist/capture/index.d.ts.map +1 -0
  5. package/dist/capture/index.js +2 -0
  6. package/dist/capture/schema.d.ts +417 -0
  7. package/dist/capture/schema.d.ts.map +1 -0
  8. package/dist/capture/schema.js +350 -0
  9. package/dist/capture/source.d.ts +60 -0
  10. package/dist/capture/source.d.ts.map +1 -0
  11. package/dist/capture/source.js +254 -0
  12. package/dist/events/bus.d.ts +58 -7
  13. package/dist/events/bus.d.ts.map +1 -1
  14. package/dist/events/hidden-wall-pointer-hold.d.ts +28 -0
  15. package/dist/events/hidden-wall-pointer-hold.d.ts.map +1 -0
  16. package/dist/events/hidden-wall-pointer-hold.js +37 -0
  17. package/dist/hooks/spatial-grid/floor-placed-elevation.d.ts +4 -4
  18. package/dist/hooks/spatial-grid/floor-placed-elevation.d.ts.map +1 -1
  19. package/dist/hooks/spatial-grid/floor-placed-elevation.js +7 -12
  20. package/dist/hooks/spatial-grid/floor-placed-footprints.d.ts +4 -0
  21. package/dist/hooks/spatial-grid/floor-placed-footprints.d.ts.map +1 -0
  22. package/dist/hooks/spatial-grid/floor-placed-footprints.js +7 -0
  23. package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts +5 -8
  24. package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts.map +1 -1
  25. package/dist/hooks/spatial-grid/spatial-grid-manager.js +23 -106
  26. package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts +2931 -2
  27. package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts.map +1 -1
  28. package/dist/hooks/spatial-grid/spatial-grid-sync.js +207 -30
  29. package/dist/hooks/spatial-grid/support-host-patch.d.ts +45 -1
  30. package/dist/hooks/spatial-grid/support-host-patch.d.ts.map +1 -1
  31. package/dist/hooks/spatial-grid/support-host-patch.js +174 -9
  32. package/dist/hooks/spatial-grid/use-spatial-query.d.ts +1 -1
  33. package/dist/hooks/spatial-grid/use-spatial-query.js +1 -1
  34. package/dist/index.d.ts +74 -64
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +74 -61
  37. package/dist/lib/asset-storage.d.ts.map +1 -1
  38. package/dist/lib/asset-storage.js +4 -1
  39. package/dist/lib/door-operation.d.ts +1 -1
  40. package/dist/lib/item-polygon-overlap.d.ts +6 -0
  41. package/dist/lib/item-polygon-overlap.d.ts.map +1 -0
  42. package/dist/lib/item-polygon-overlap.js +67 -0
  43. package/dist/lib/level-name.d.ts +1 -1
  44. package/dist/lib/measurement-geometry.d.ts +4 -4
  45. package/dist/lib/plan-footprint.d.ts +41 -0
  46. package/dist/lib/plan-footprint.d.ts.map +1 -0
  47. package/dist/lib/plan-footprint.js +58 -0
  48. package/dist/lib/polygon-union.d.ts +4 -0
  49. package/dist/lib/polygon-union.d.ts.map +1 -0
  50. package/dist/lib/polygon-union.js +306 -0
  51. package/dist/lib/roof-overlap.d.ts +32 -0
  52. package/dist/lib/roof-overlap.d.ts.map +1 -0
  53. package/dist/lib/roof-overlap.js +72 -0
  54. package/dist/lib/room-topology-index.d.ts +1 -1
  55. package/dist/lib/room-topology-index.js +1 -1
  56. package/dist/lib/selection-proxy.d.ts +1 -1
  57. package/dist/lib/slab-polygon.d.ts +36 -3
  58. package/dist/lib/slab-polygon.d.ts.map +1 -1
  59. package/dist/lib/slab-polygon.js +135 -29
  60. package/dist/lib/space-detection.d.ts +12 -1
  61. package/dist/lib/space-detection.d.ts.map +1 -1
  62. package/dist/lib/space-detection.js +58 -25
  63. package/dist/lib/terrain-brush.d.ts +1 -1
  64. package/dist/lib/terrain-brush.js +1 -1
  65. package/dist/lib/terrain-codec.d.ts +2 -2
  66. package/dist/lib/terrain-codec.js +1 -1
  67. package/dist/lib/terrain-raycast.d.ts +1 -1
  68. package/dist/lib/terrain-raycast.js +1 -1
  69. package/dist/lib/terrain-source.d.ts +3 -3
  70. package/dist/lib/terrain-source.js +3 -3
  71. package/dist/lib/terrain-support.d.ts +1 -1
  72. package/dist/lib/terrain-support.js +3 -3
  73. package/dist/lib/unit-containment.d.ts +19 -0
  74. package/dist/lib/unit-containment.d.ts.map +1 -0
  75. package/dist/lib/unit-containment.js +158 -0
  76. package/dist/lib/unit-report.d.ts +19 -0
  77. package/dist/lib/unit-report.d.ts.map +1 -0
  78. package/dist/lib/unit-report.js +36 -0
  79. package/dist/lib/wall-distance.d.ts +2 -2
  80. package/dist/lib/wall-distance.js +1 -1
  81. package/dist/lib/zone-quantities.d.ts +1 -1
  82. package/dist/lib/zone-quantities.js +7 -7
  83. package/dist/material-library.d.ts +1 -1
  84. package/dist/material-library.js +1 -1
  85. package/dist/procedural-items/fixtures.d.ts +261 -0
  86. package/dist/procedural-items/fixtures.d.ts.map +1 -0
  87. package/dist/procedural-items/fixtures.js +349 -0
  88. package/dist/procedural-items/index.d.ts +10 -0
  89. package/dist/procedural-items/index.d.ts.map +1 -0
  90. package/dist/procedural-items/index.js +9 -0
  91. package/dist/procedural-items/integration.d.ts +92 -0
  92. package/dist/procedural-items/integration.d.ts.map +1 -0
  93. package/dist/procedural-items/integration.js +19 -0
  94. package/dist/procedural-items/library-colors.d.ts +56 -0
  95. package/dist/procedural-items/library-colors.d.ts.map +1 -0
  96. package/dist/procedural-items/library-colors.js +84 -0
  97. package/dist/procedural-items/materials.d.ts +5 -0
  98. package/dist/procedural-items/materials.d.ts.map +1 -0
  99. package/dist/procedural-items/materials.js +47 -0
  100. package/dist/procedural-items/node.d.ts +280 -0
  101. package/dist/procedural-items/node.d.ts.map +1 -0
  102. package/dist/procedural-items/node.js +71 -0
  103. package/dist/procedural-items/placement.d.ts +7 -0
  104. package/dist/procedural-items/placement.d.ts.map +1 -0
  105. package/dist/procedural-items/placement.js +48 -0
  106. package/dist/procedural-items/query.d.ts +50 -0
  107. package/dist/procedural-items/query.d.ts.map +1 -0
  108. package/dist/procedural-items/query.js +298 -0
  109. package/dist/procedural-items/recipe.d.ts +144 -0
  110. package/dist/procedural-items/recipe.d.ts.map +1 -0
  111. package/dist/procedural-items/recipe.js +372 -0
  112. package/dist/procedural-items/spatial.d.ts +19 -0
  113. package/dist/procedural-items/spatial.d.ts.map +1 -0
  114. package/dist/procedural-items/spatial.js +39 -0
  115. package/dist/registry/__bench__/relations-resolver.bench.js +2 -2
  116. package/dist/registry/handles.d.ts +36 -7
  117. package/dist/registry/handles.d.ts.map +1 -1
  118. package/dist/registry/index.d.ts +6 -7
  119. package/dist/registry/index.d.ts.map +1 -1
  120. package/dist/registry/index.js +4 -5
  121. package/dist/registry/registry.d.ts +13 -6
  122. package/dist/registry/registry.d.ts.map +1 -1
  123. package/dist/registry/registry.js +37 -4
  124. package/dist/registry/relations-resolver.d.ts +2 -2
  125. package/dist/registry/relations-resolver.js +1 -1
  126. package/dist/registry/scene-api.d.ts +18 -2
  127. package/dist/registry/scene-api.d.ts.map +1 -1
  128. package/dist/registry/scene-api.js +50 -2
  129. package/dist/registry/subtree.d.ts +1 -1
  130. package/dist/registry/subtree.js +2 -2
  131. package/dist/registry/types.d.ts +246 -21
  132. package/dist/registry/types.d.ts.map +1 -1
  133. package/dist/registry/use-registry-version.js +1 -1
  134. package/dist/registry/validate-relations.d.ts +4 -0
  135. package/dist/registry/validate-relations.d.ts.map +1 -0
  136. package/dist/registry/validate-relations.js +22 -0
  137. package/dist/schema/__bench__/node-parsers.bench.d.ts +24 -0
  138. package/dist/schema/__bench__/node-parsers.bench.d.ts.map +1 -0
  139. package/dist/schema/__bench__/node-parsers.bench.js +314 -0
  140. package/dist/schema/__fixtures__/node-fixtures.d.ts +28 -0
  141. package/dist/schema/__fixtures__/node-fixtures.d.ts.map +1 -0
  142. package/dist/schema/__fixtures__/node-fixtures.js +127 -0
  143. package/dist/schema/base.d.ts +1 -1
  144. package/dist/schema/base.d.ts.map +1 -1
  145. package/dist/schema/base.js +9 -2
  146. package/dist/schema/collections.d.ts +1 -1
  147. package/dist/schema/collections.js +1 -1
  148. package/dist/schema/compiled-node-parsers.d.ts +40 -0
  149. package/dist/schema/compiled-node-parsers.d.ts.map +1 -0
  150. package/dist/schema/compiled-node-parsers.js +95 -0
  151. package/dist/schema/index.d.ts +73 -66
  152. package/dist/schema/index.d.ts.map +1 -1
  153. package/dist/schema/index.js +65 -57
  154. package/dist/schema/material.d.ts +1 -0
  155. package/dist/schema/material.d.ts.map +1 -1
  156. package/dist/schema/material.js +2 -1
  157. package/dist/schema/nodes/automatic-downspout.d.ts +17 -0
  158. package/dist/schema/nodes/automatic-downspout.d.ts.map +1 -0
  159. package/dist/schema/nodes/automatic-downspout.js +237 -0
  160. package/dist/schema/nodes/block.d.ts +107 -0
  161. package/dist/schema/nodes/block.d.ts.map +1 -0
  162. package/dist/schema/nodes/block.js +206 -0
  163. package/dist/schema/nodes/box-vent.d.ts +8 -2
  164. package/dist/schema/nodes/box-vent.d.ts.map +1 -1
  165. package/dist/schema/nodes/box-vent.js +4 -2
  166. package/dist/schema/nodes/building.d.ts +2 -2
  167. package/dist/schema/nodes/building.d.ts.map +1 -1
  168. package/dist/schema/nodes/building.js +8 -5
  169. package/dist/schema/nodes/cabinet.d.ts +26 -4
  170. package/dist/schema/nodes/cabinet.d.ts.map +1 -1
  171. package/dist/schema/nodes/cabinet.js +29 -8
  172. package/dist/schema/nodes/ceiling.d.ts +2 -2
  173. package/dist/schema/nodes/ceiling.js +5 -5
  174. package/dist/schema/nodes/chimney.d.ts +2 -2
  175. package/dist/schema/nodes/chimney.js +2 -2
  176. package/dist/schema/nodes/column.d.ts +7 -6
  177. package/dist/schema/nodes/column.d.ts.map +1 -1
  178. package/dist/schema/nodes/column.js +3 -2
  179. package/dist/schema/nodes/construction-dimension.d.ts +1 -1
  180. package/dist/schema/nodes/construction-dimension.js +2 -2
  181. package/dist/schema/nodes/cupola.d.ts +9 -1
  182. package/dist/schema/nodes/cupola.d.ts.map +1 -1
  183. package/dist/schema/nodes/cupola.js +4 -2
  184. package/dist/schema/nodes/door.d.ts +1 -1
  185. package/dist/schema/nodes/door.js +2 -2
  186. package/dist/schema/nodes/dormer.d.ts +45 -2
  187. package/dist/schema/nodes/dormer.d.ts.map +1 -1
  188. package/dist/schema/nodes/dormer.js +133 -9
  189. package/dist/schema/nodes/downspout.d.ts +11 -1
  190. package/dist/schema/nodes/downspout.d.ts.map +1 -1
  191. package/dist/schema/nodes/downspout.js +26 -2
  192. package/dist/schema/nodes/duct-fitting.d.ts +18 -1
  193. package/dist/schema/nodes/duct-fitting.d.ts.map +1 -1
  194. package/dist/schema/nodes/duct-fitting.js +26 -5
  195. package/dist/schema/nodes/duct-segment.d.ts +23 -1
  196. package/dist/schema/nodes/duct-segment.d.ts.map +1 -1
  197. package/dist/schema/nodes/duct-segment.js +21 -1
  198. package/dist/schema/nodes/duct-terminal.d.ts +1 -1
  199. package/dist/schema/nodes/duct-terminal.js +1 -1
  200. package/dist/schema/nodes/elevator.d.ts +1 -1
  201. package/dist/schema/nodes/elevator.js +2 -2
  202. package/dist/schema/nodes/eyebrow-vent.d.ts +8 -2
  203. package/dist/schema/nodes/eyebrow-vent.d.ts.map +1 -1
  204. package/dist/schema/nodes/eyebrow-vent.js +4 -2
  205. package/dist/schema/nodes/fence.d.ts +1 -1
  206. package/dist/schema/nodes/fence.js +2 -2
  207. package/dist/schema/nodes/guide.d.ts +1 -1
  208. package/dist/schema/nodes/guide.js +2 -2
  209. package/dist/schema/nodes/gutter.d.ts +36 -2
  210. package/dist/schema/nodes/gutter.d.ts.map +1 -1
  211. package/dist/schema/nodes/gutter.js +310 -3
  212. package/dist/schema/nodes/hanger-overrides.d.ts +7 -0
  213. package/dist/schema/nodes/hanger-overrides.d.ts.map +1 -0
  214. package/dist/schema/nodes/hanger-overrides.js +6 -0
  215. package/dist/schema/nodes/hvac-equipment.d.ts +1 -1
  216. package/dist/schema/nodes/hvac-equipment.js +1 -1
  217. package/dist/schema/nodes/imported-mesh.d.ts +40 -0
  218. package/dist/schema/nodes/imported-mesh.d.ts.map +1 -0
  219. package/dist/schema/nodes/imported-mesh.js +27 -0
  220. package/dist/schema/nodes/item.d.ts +3 -2
  221. package/dist/schema/nodes/item.d.ts.map +1 -1
  222. package/dist/schema/nodes/item.js +8 -3
  223. package/dist/schema/nodes/lean-to-extension.d.ts +212 -0
  224. package/dist/schema/nodes/lean-to-extension.d.ts.map +1 -0
  225. package/dist/schema/nodes/lean-to-extension.js +114 -0
  226. package/dist/schema/nodes/level.d.ts +2 -2
  227. package/dist/schema/nodes/level.d.ts.map +1 -1
  228. package/dist/schema/nodes/level.js +1 -1
  229. package/dist/schema/nodes/lineset.d.ts +1 -1
  230. package/dist/schema/nodes/lineset.js +1 -1
  231. package/dist/schema/nodes/liquid-line.d.ts +1 -1
  232. package/dist/schema/nodes/liquid-line.js +1 -1
  233. package/dist/schema/nodes/measurement.d.ts +1 -1
  234. package/dist/schema/nodes/measurement.js +2 -2
  235. package/dist/schema/nodes/pipe-fitting.d.ts +10 -2
  236. package/dist/schema/nodes/pipe-fitting.d.ts.map +1 -1
  237. package/dist/schema/nodes/pipe-fitting.js +7 -3
  238. package/dist/schema/nodes/pipe-segment.d.ts +24 -2
  239. package/dist/schema/nodes/pipe-segment.d.ts.map +1 -1
  240. package/dist/schema/nodes/pipe-segment.js +21 -1
  241. package/dist/schema/nodes/pipe-trap.d.ts +2 -2
  242. package/dist/schema/nodes/pipe-trap.js +1 -1
  243. package/dist/schema/nodes/ridge-vent.d.ts +2 -2
  244. package/dist/schema/nodes/ridge-vent.d.ts.map +1 -1
  245. package/dist/schema/nodes/ridge-vent.js +7 -4
  246. package/dist/schema/nodes/roof-segment-shape.d.ts +5 -1
  247. package/dist/schema/nodes/roof-segment-shape.d.ts.map +1 -1
  248. package/dist/schema/nodes/roof-segment-shape.js +65 -2
  249. package/dist/schema/nodes/roof-segment-walls.d.ts +4 -2
  250. package/dist/schema/nodes/roof-segment-walls.d.ts.map +1 -1
  251. package/dist/schema/nodes/roof-segment-walls.js +2 -2
  252. package/dist/schema/nodes/roof-segment.d.ts +42 -2
  253. package/dist/schema/nodes/roof-segment.d.ts.map +1 -1
  254. package/dist/schema/nodes/roof-segment.js +81 -4
  255. package/dist/schema/nodes/roof.d.ts +23 -2
  256. package/dist/schema/nodes/roof.d.ts.map +1 -1
  257. package/dist/schema/nodes/roof.js +17 -3
  258. package/dist/schema/nodes/scan.d.ts +19 -2
  259. package/dist/schema/nodes/scan.d.ts.map +1 -1
  260. package/dist/schema/nodes/scan.js +13 -3
  261. package/dist/schema/nodes/shelf.d.ts +3 -3
  262. package/dist/schema/nodes/shelf.d.ts.map +1 -1
  263. package/dist/schema/nodes/shelf.js +3 -4
  264. package/dist/schema/nodes/site.d.ts +1 -1
  265. package/dist/schema/nodes/site.js +2 -2
  266. package/dist/schema/nodes/skylight.d.ts +5 -5
  267. package/dist/schema/nodes/skylight.js +2 -2
  268. package/dist/schema/nodes/slab.d.ts +1 -1
  269. package/dist/schema/nodes/slab.js +3 -3
  270. package/dist/schema/nodes/solar-panel.d.ts +1 -1
  271. package/dist/schema/nodes/solar-panel.js +3 -3
  272. package/dist/schema/nodes/spawn.d.ts +1 -1
  273. package/dist/schema/nodes/spawn.js +1 -1
  274. package/dist/schema/nodes/stair-segment.d.ts +1 -1
  275. package/dist/schema/nodes/stair-segment.js +2 -2
  276. package/dist/schema/nodes/stair.d.ts +2 -2
  277. package/dist/schema/nodes/stair.js +3 -3
  278. package/dist/schema/nodes/structural-grid.d.ts +1 -1
  279. package/dist/schema/nodes/structural-grid.js +1 -1
  280. package/dist/schema/nodes/turbine-vent.d.ts +8 -2
  281. package/dist/schema/nodes/turbine-vent.d.ts.map +1 -1
  282. package/dist/schema/nodes/turbine-vent.js +4 -2
  283. package/dist/schema/nodes/unit.d.ts +33 -0
  284. package/dist/schema/nodes/unit.d.ts.map +1 -0
  285. package/dist/schema/nodes/unit.js +13 -0
  286. package/dist/schema/nodes/wall.d.ts +5 -5
  287. package/dist/schema/nodes/wall.d.ts.map +1 -1
  288. package/dist/schema/nodes/wall.js +13 -6
  289. package/dist/schema/nodes/window.d.ts +10 -3
  290. package/dist/schema/nodes/window.d.ts.map +1 -1
  291. package/dist/schema/nodes/window.js +6 -2
  292. package/dist/schema/nodes/zone.d.ts +2 -2
  293. package/dist/schema/nodes/zone.js +2 -2
  294. package/dist/schema/scene-material.js +2 -2
  295. package/dist/schema/types.d.ts +815 -118
  296. package/dist/schema/types.d.ts.map +1 -1
  297. package/dist/schema/types.js +79 -46
  298. package/dist/services/alignment-anchors.d.ts +6 -11
  299. package/dist/services/alignment-anchors.d.ts.map +1 -1
  300. package/dist/services/alignment-anchors.js +7 -34
  301. package/dist/services/drag-session.d.ts +4 -4
  302. package/dist/services/drag-session.js +1 -1
  303. package/dist/services/hosting.d.ts +4 -10
  304. package/dist/services/hosting.d.ts.map +1 -1
  305. package/dist/services/hosting.js +6 -16
  306. package/dist/services/index.d.ts +16 -13
  307. package/dist/services/index.d.ts.map +1 -1
  308. package/dist/services/index.js +16 -13
  309. package/dist/services/level-height.d.ts +2 -2
  310. package/dist/services/level-height.js +3 -3
  311. package/dist/services/movement.d.ts +3 -3
  312. package/dist/services/movement.js +2 -2
  313. package/dist/services/port-connectivity.d.ts +1 -1
  314. package/dist/services/port-connectivity.js +1 -1
  315. package/dist/services/riser-diagram.d.ts +1 -1
  316. package/dist/services/shelf-board.d.ts +5 -0
  317. package/dist/services/shelf-board.d.ts.map +1 -0
  318. package/dist/services/shelf-board.js +15 -0
  319. package/dist/services/storey.d.ts +2 -2
  320. package/dist/services/storey.js +2 -2
  321. package/dist/services/surface-hosting-procedural-parity.fixtures.d.ts +13 -0
  322. package/dist/services/surface-hosting-procedural-parity.fixtures.d.ts.map +1 -0
  323. package/dist/services/surface-hosting-procedural-parity.fixtures.js +4691 -0
  324. package/dist/services/surface-hosting-shelf-parity.fixtures.d.ts +1060 -0
  325. package/dist/services/surface-hosting-shelf-parity.fixtures.d.ts.map +1 -0
  326. package/dist/services/surface-hosting-shelf-parity.fixtures.js +3127 -0
  327. package/dist/services/surface-hosting.d.ts +88 -0
  328. package/dist/services/surface-hosting.d.ts.map +1 -0
  329. package/dist/services/surface-hosting.js +268 -0
  330. package/dist/services/surface-region.d.ts +8 -0
  331. package/dist/services/surface-region.d.ts.map +1 -0
  332. package/dist/services/surface-region.js +44 -0
  333. package/dist/services/system-graph.d.ts +12 -1
  334. package/dist/services/system-graph.d.ts.map +1 -1
  335. package/dist/services/system-graph.js +36 -6
  336. package/dist/services/validate-dwv.d.ts +1 -1
  337. package/dist/services/validate-dwv.js +1 -1
  338. package/dist/store/actions/node-actions.d.ts +9 -2
  339. package/dist/store/actions/node-actions.d.ts.map +1 -1
  340. package/dist/store/actions/node-actions.js +475 -24
  341. package/dist/store/history-control.d.ts +3 -3
  342. package/dist/store/history-invalidation.d.ts +3 -0
  343. package/dist/store/history-invalidation.d.ts.map +1 -0
  344. package/dist/store/history-invalidation.js +72 -0
  345. package/dist/store/scene-hydration.d.ts +5 -0
  346. package/dist/store/scene-hydration.d.ts.map +1 -0
  347. package/dist/store/scene-hydration.js +57 -0
  348. package/dist/store/use-interactive.d.ts +2 -2
  349. package/dist/store/use-live-terrain.d.ts +1 -1
  350. package/dist/store/use-scene.d.ts +7 -4
  351. package/dist/store/use-scene.d.ts.map +1 -1
  352. package/dist/store/use-scene.js +361 -87
  353. package/dist/systems/elevator/elevator-dispatch.d.ts +2 -2
  354. package/dist/systems/elevator/elevator-dispatch.js +1 -1
  355. package/dist/systems/elevator/elevator-geometry.d.ts +1 -1
  356. package/dist/systems/elevator/elevator-opening-sync.d.ts +1 -1
  357. package/dist/systems/elevator/elevator-opening-sync.js +2 -2
  358. package/dist/systems/elevator/elevator-opening-system.js +3 -3
  359. package/dist/systems/elevator/elevator-runtime.d.ts +3 -3
  360. package/dist/systems/elevator/elevator-runtime.js +3 -3
  361. package/dist/systems/elevator/elevator-service.d.ts +1 -1
  362. package/dist/systems/elevator/elevator-service.js +1 -1
  363. package/dist/systems/fence/fence-centerline.d.ts +2 -2
  364. package/dist/systems/fence/fence-centerline.js +2 -2
  365. package/dist/systems/fence/fence-spline.d.ts +2 -2
  366. package/dist/systems/roof/roof-elevation-system.d.ts +3 -0
  367. package/dist/systems/roof/roof-elevation-system.d.ts.map +1 -0
  368. package/dist/systems/roof/roof-elevation-system.js +94 -0
  369. package/dist/systems/roof/roof-elevation.d.ts +4 -0
  370. package/dist/systems/roof/roof-elevation.d.ts.map +1 -0
  371. package/dist/systems/roof/roof-elevation.js +95 -0
  372. package/dist/systems/roof/roof-footprint.d.ts +17 -0
  373. package/dist/systems/roof/roof-footprint.d.ts.map +1 -0
  374. package/dist/systems/roof/roof-footprint.js +83 -0
  375. package/dist/systems/slab/slab-placement.d.ts +1 -1
  376. package/dist/systems/slab/slab-support.d.ts +1 -1
  377. package/dist/systems/slab/slab-support.js +4 -4
  378. package/dist/systems/stair/stair-flight.d.ts +17 -0
  379. package/dist/systems/stair/stair-flight.d.ts.map +1 -0
  380. package/dist/systems/stair/stair-flight.js +27 -0
  381. package/dist/systems/stair/stair-footprint.d.ts +1 -1
  382. package/dist/systems/stair/stair-opening-preview.d.ts +1621 -1267
  383. package/dist/systems/stair/stair-opening-preview.d.ts.map +1 -1
  384. package/dist/systems/stair/stair-opening-preview.js +2 -2
  385. package/dist/systems/stair/stair-opening-sync.d.ts +1 -1
  386. package/dist/systems/stair/stair-opening-sync.js +6 -6
  387. package/dist/systems/stair/stair-opening-system.d.ts +1 -0
  388. package/dist/systems/stair/stair-opening-system.d.ts.map +1 -1
  389. package/dist/systems/stair/stair-opening-system.js +100 -103
  390. package/dist/systems/stair/stair-rise.d.ts +1 -1
  391. package/dist/systems/stair/stair-rise.d.ts.map +1 -1
  392. package/dist/systems/stair/stair-rise.js +23 -24
  393. package/dist/systems/wall/wall-curve.d.ts +3 -2
  394. package/dist/systems/wall/wall-curve.d.ts.map +1 -1
  395. package/dist/systems/wall/wall-curve.js +73 -0
  396. package/dist/systems/wall/wall-footprint.d.ts +3 -2
  397. package/dist/systems/wall/wall-footprint.d.ts.map +1 -1
  398. package/dist/systems/wall/wall-footprint.js +3 -2
  399. package/dist/systems/wall/wall-mitering.d.ts +1 -1
  400. package/dist/systems/wall/wall-mitering.js +1 -1
  401. package/dist/systems/wall/wall-move.d.ts +1 -1
  402. package/dist/systems/wall/wall-top.d.ts +1 -1
  403. package/dist/systems/wall/wall-topology.d.ts +2 -2
  404. package/dist/systems/wall/wall-topology.js +4 -4
  405. package/dist/utils/clone-scene-graph.d.ts +3 -3
  406. package/dist/utils/clone-scene-graph.d.ts.map +1 -1
  407. package/dist/utils/clone-scene-graph.js +35 -3
  408. package/dist/utils/scene-migrations.d.ts +3 -3
  409. package/dist/utils/scene-migrations.js +3 -3
  410. package/dist/utils/vertical-scene-migration.js +5 -5
  411. package/dist/validation/validate-build-json.d.ts +7 -1
  412. package/dist/validation/validate-build-json.d.ts.map +1 -1
  413. package/dist/validation/validate-build-json.js +92 -4
  414. package/package.json +23 -5
  415. package/dist/systems/elevator/elevator-runtime-system.d.ts +0 -2
  416. package/dist/systems/elevator/elevator-runtime-system.d.ts.map +0 -1
  417. package/dist/systems/elevator/elevator-runtime-system.js +0 -8
@@ -0,0 +1,350 @@
1
+ import { z } from 'zod';
2
+ const MetadataSchema = z.record(z.string(), z.unknown());
3
+ export const CaptureSessionLocatorSchema = z.object({
4
+ sessionId: z.string().min(1),
5
+ manifestUrl: z.string().min(1).optional(),
6
+ schemaVersion: z.number().int().positive().optional(),
7
+ revisionId: z.string().min(1).optional(),
8
+ });
9
+ export const DeviceMotionSampleSchema = z.object({
10
+ segment: z.number().int().nonnegative(),
11
+ timestamp: z.number().nonnegative(),
12
+ transform: z.array(z.number()).length(16),
13
+ });
14
+ export const DeviceMotionTrajectorySchema = z.object({
15
+ coordinateSystem: z.string().min(1),
16
+ samples: z.array(DeviceMotionSampleSchema).min(2),
17
+ });
18
+ export const ArkitDeviceMotionTrajectorySchema = DeviceMotionTrajectorySchema.extend({
19
+ coordinateSystem: z.literal('arkit-world'),
20
+ });
21
+ export const PointCloudPayloadSchema = z
22
+ .object({
23
+ coordinateSystem: z.string().min(1),
24
+ positions: z.array(z.number().finite()).min(3),
25
+ colors: z.array(z.number().finite()).optional(),
26
+ })
27
+ .superRefine((payload, context) => {
28
+ if (payload.positions.length % 3 !== 0) {
29
+ context.addIssue({
30
+ code: 'custom',
31
+ message: 'Point-cloud positions must contain XYZ triples.',
32
+ path: ['positions'],
33
+ });
34
+ }
35
+ if (payload.colors && payload.colors.length !== payload.positions.length) {
36
+ context.addIssue({
37
+ code: 'custom',
38
+ message: 'Point-cloud colors must match the positions array length.',
39
+ path: ['colors'],
40
+ });
41
+ }
42
+ });
43
+ export const ArkitPointCloudPayloadSchema = PointCloudPayloadSchema.safeExtend({
44
+ coordinateSystem: z.literal('arkit-world'),
45
+ });
46
+ const MAX_SURFACE_MESH_VERTICES = 65_535;
47
+ const MAX_SURFACE_MESH_FACES = 20_000;
48
+ export const SurfaceMeshPayloadSchema = z
49
+ .object({
50
+ version: z.literal(1),
51
+ coordinateSystem: z.string().min(1),
52
+ representation: z.literal('quantized-indexed-triangle-mesh'),
53
+ appearance: z.literal('camera-vertex-color'),
54
+ vertexCount: z.number().int().positive().max(MAX_SURFACE_MESH_VERTICES),
55
+ faceCount: z.number().int().positive().max(MAX_SURFACE_MESH_FACES),
56
+ boundsMin: z.array(z.number().finite()).length(3),
57
+ boundsMax: z.array(z.number().finite()).length(3),
58
+ positionEncoding: z.literal('uint16x3-base64-little-endian'),
59
+ colorEncoding: z.literal('uint8x3-base64-srgb'),
60
+ indexEncoding: z.literal('uint16x3-base64-little-endian'),
61
+ positions: z.string().min(1).max(524_280),
62
+ colors: z.string().min(1).max(262_140),
63
+ indices: z
64
+ .string()
65
+ .min(1)
66
+ .max(MAX_SURFACE_MESH_FACES * 8),
67
+ })
68
+ .superRefine((payload, context) => {
69
+ if (payload.vertexCount > payload.faceCount * 3) {
70
+ context.addIssue({
71
+ code: 'custom',
72
+ message: 'Surface meshes cannot contain more than three vertices per face.',
73
+ path: ['vertexCount'],
74
+ });
75
+ }
76
+ for (let axis = 0; axis < 3; axis += 1) {
77
+ if ((payload.boundsMax[axis] ?? 0) < (payload.boundsMin[axis] ?? 0)) {
78
+ context.addIssue({
79
+ code: 'custom',
80
+ message: 'Surface-mesh maximum bounds must not be below minimum bounds.',
81
+ path: ['boundsMax', axis],
82
+ });
83
+ }
84
+ }
85
+ const positionBytes = decodeBase64(payload.positions);
86
+ const colorBytes = decodeBase64(payload.colors);
87
+ const indexBytes = decodeBase64(payload.indices);
88
+ validateSurfaceMeshByteLength(positionBytes, payload.vertexCount * 3 * 2, 'positions', context);
89
+ validateSurfaceMeshByteLength(colorBytes, payload.vertexCount * 3, 'colors', context);
90
+ validateSurfaceMeshByteLength(indexBytes, payload.faceCount * 3 * 2, 'indices', context);
91
+ if (indexBytes?.byteLength === payload.faceCount * 3 * 2) {
92
+ const indices = new DataView(indexBytes.buffer, indexBytes.byteOffset, indexBytes.byteLength);
93
+ for (let offset = 0; offset < indexBytes.byteLength; offset += 2) {
94
+ if (indices.getUint16(offset, true) >= payload.vertexCount) {
95
+ context.addIssue({
96
+ code: 'custom',
97
+ message: 'Surface-mesh indices must reference an existing vertex.',
98
+ path: ['indices'],
99
+ });
100
+ break;
101
+ }
102
+ }
103
+ }
104
+ });
105
+ export const ArkitSurfaceMeshPayloadSchema = SurfaceMeshPayloadSchema.safeExtend({
106
+ coordinateSystem: z.literal('arkit-world'),
107
+ });
108
+ export const CaptureTimeRangeSchema = z
109
+ .object({
110
+ start: z.number().nonnegative(),
111
+ end: z.number().nonnegative(),
112
+ })
113
+ .refine((range) => range.end >= range.start, {
114
+ message: 'Capture time ranges must end at or after they start.',
115
+ path: ['end'],
116
+ });
117
+ export const CaptureArtifactReferenceSchema = z.object({
118
+ id: z.string().min(1),
119
+ uri: z.string().min(1).optional(),
120
+ mediaType: z.string().min(1),
121
+ byteLength: z.number().int().nonnegative().optional(),
122
+ sha256: z.string().min(1).optional(),
123
+ frameId: z.string().min(1).optional(),
124
+ timeRange: CaptureTimeRangeSchema.optional(),
125
+ metadata: MetadataSchema.optional(),
126
+ });
127
+ export const CaptureStreamDescriptorSchema = z.object({
128
+ id: z.string().min(1),
129
+ kind: z.string().min(1),
130
+ role: z.string().min(1).optional(),
131
+ availability: z.enum(['pending', 'live', 'ready', 'failed']).default('ready'),
132
+ frameId: z.string().min(1).optional(),
133
+ clockId: z.string().min(1).optional(),
134
+ artifact: CaptureArtifactReferenceSchema.optional(),
135
+ inline: z.unknown().optional(),
136
+ metadata: MetadataSchema.optional(),
137
+ });
138
+ export const CaptureClockSchema = z.object({
139
+ id: z.string().min(1),
140
+ timebase: z.enum(['seconds', 'milliseconds', 'microseconds', 'nanoseconds']),
141
+ epoch: z.string().min(1).optional(),
142
+ });
143
+ export const CaptureCoordinateFrameSchema = z.object({
144
+ id: z.string().min(1),
145
+ parentId: z.string().min(1).optional(),
146
+ convention: z.string().min(1),
147
+ transform: z.array(z.number()).length(16).optional(),
148
+ });
149
+ export const CaptureSessionManifestV1Schema = z.object({
150
+ schemaVersion: z.literal(1),
151
+ sessionId: z.string().min(1),
152
+ projectId: z.string().min(1),
153
+ streams: z.object({
154
+ roomModel: z
155
+ .object({
156
+ kind: z.literal('room-model'),
157
+ mediaType: z.literal('model/vnd.usdz+zip'),
158
+ url: z.string().min(1),
159
+ })
160
+ .optional(),
161
+ deviceMotion: z
162
+ .object({
163
+ kind: z.literal('device-motion'),
164
+ trajectory: ArkitDeviceMotionTrajectorySchema,
165
+ })
166
+ .optional(),
167
+ pointCloud: z
168
+ .object({
169
+ kind: z.literal('point-cloud'),
170
+ points: ArkitPointCloudPayloadSchema,
171
+ })
172
+ .optional(),
173
+ surfaceMesh: z
174
+ .object({
175
+ kind: z.literal('surface-mesh'),
176
+ mesh: ArkitSurfaceMeshPayloadSchema,
177
+ })
178
+ .optional(),
179
+ }),
180
+ });
181
+ export const CaptureSessionManifestV2Schema = z
182
+ .object({
183
+ schemaVersion: z.literal(2),
184
+ sessionId: z.string().min(1),
185
+ projectId: z.string().min(1).optional(),
186
+ revisionId: z.string().min(1).optional(),
187
+ state: z.enum(['live', 'finalizing', 'ready', 'failed']).default('ready'),
188
+ clocks: z.array(CaptureClockSchema).default([]),
189
+ coordinateFrames: z.array(CaptureCoordinateFrameSchema).default([]),
190
+ streams: z.array(CaptureStreamDescriptorSchema),
191
+ metadata: MetadataSchema.optional(),
192
+ })
193
+ .superRefine(validateUniqueSessionIds);
194
+ export const CaptureSessionManifestSchema = z.union([
195
+ CaptureSessionManifestV1Schema,
196
+ CaptureSessionManifestV2Schema,
197
+ ]);
198
+ export const CaptureSessionDescriptorSchema = z
199
+ .object({
200
+ schemaVersion: z.number().int().positive(),
201
+ sessionId: z.string().min(1),
202
+ projectId: z.string().min(1).optional(),
203
+ revisionId: z.string().min(1).optional(),
204
+ state: z.enum(['live', 'finalizing', 'ready', 'failed']),
205
+ clocks: z.array(CaptureClockSchema),
206
+ coordinateFrames: z.array(CaptureCoordinateFrameSchema),
207
+ streams: z.array(CaptureStreamDescriptorSchema),
208
+ metadata: MetadataSchema.optional(),
209
+ })
210
+ .superRefine(validateUniqueSessionIds);
211
+ export function normalizeCaptureSessionManifest(value) {
212
+ const manifest = CaptureSessionManifestSchema.parse(value);
213
+ if (manifest.schemaVersion === 2)
214
+ return CaptureSessionDescriptorSchema.parse(manifest);
215
+ const streams = [];
216
+ if (manifest.streams.roomModel) {
217
+ streams.push({
218
+ id: 'room-model',
219
+ kind: manifest.streams.roomModel.kind,
220
+ role: 'model',
221
+ availability: 'ready',
222
+ artifact: {
223
+ id: `${manifest.sessionId}:room-model`,
224
+ mediaType: manifest.streams.roomModel.mediaType,
225
+ uri: manifest.streams.roomModel.url,
226
+ },
227
+ });
228
+ }
229
+ if (manifest.streams.deviceMotion) {
230
+ streams.push({
231
+ id: 'device-motion',
232
+ kind: manifest.streams.deviceMotion.kind,
233
+ role: 'deviceMotion',
234
+ availability: 'ready',
235
+ inline: manifest.streams.deviceMotion.trajectory,
236
+ });
237
+ }
238
+ if (manifest.streams.pointCloud) {
239
+ streams.push({
240
+ id: 'point-cloud',
241
+ kind: manifest.streams.pointCloud.kind,
242
+ role: 'pointCloud',
243
+ availability: 'ready',
244
+ inline: manifest.streams.pointCloud.points,
245
+ });
246
+ }
247
+ if (manifest.streams.surfaceMesh) {
248
+ streams.push({
249
+ id: 'surface-mesh',
250
+ kind: manifest.streams.surfaceMesh.kind,
251
+ role: 'surfaceMesh',
252
+ availability: 'ready',
253
+ inline: manifest.streams.surfaceMesh.mesh,
254
+ });
255
+ }
256
+ return CaptureSessionDescriptorSchema.parse({
257
+ schemaVersion: manifest.schemaVersion,
258
+ sessionId: manifest.sessionId,
259
+ projectId: manifest.projectId,
260
+ state: 'ready',
261
+ clocks: [],
262
+ coordinateFrames: [],
263
+ streams,
264
+ });
265
+ }
266
+ export function captureLayerKey(stream) {
267
+ if (stream.role)
268
+ return stream.role;
269
+ if (stream.kind === 'room-model')
270
+ return 'model';
271
+ if (stream.kind === 'device-motion')
272
+ return 'deviceMotion';
273
+ if (stream.kind === 'point-cloud')
274
+ return 'pointCloud';
275
+ if (stream.kind === 'surface-mesh')
276
+ return 'surfaceMesh';
277
+ if (stream.kind === 'gaussian-splat')
278
+ return 'splat';
279
+ if (stream.kind === 'spaceform-scene')
280
+ return 'spaceformScene';
281
+ return stream.kind;
282
+ }
283
+ export function captureStreamLabel(stream) {
284
+ const key = captureLayerKey(stream);
285
+ if (key === 'model')
286
+ return '3D model';
287
+ if (key === 'deviceMotion')
288
+ return 'Device motion';
289
+ if (key === 'pointCloud')
290
+ return 'Point cloud';
291
+ if (key === 'surfaceMesh')
292
+ return 'Surface mesh';
293
+ if (key === 'splat')
294
+ return 'Gaussian splat';
295
+ return key
296
+ .replace(/([a-z])([A-Z])/g, '$1 $2')
297
+ .replace(/[-_]+/g, ' ')
298
+ .replace(/^./, (value) => value.toUpperCase());
299
+ }
300
+ function validateSurfaceMeshByteLength(bytes, expectedLength, path, context) {
301
+ if (bytes?.byteLength === expectedLength)
302
+ return;
303
+ context.addIssue({
304
+ code: 'custom',
305
+ message: `Surface-mesh ${path} must contain exactly ${expectedLength} decoded bytes.`,
306
+ path: [path],
307
+ });
308
+ }
309
+ function decodeBase64(value) {
310
+ if (value.length % 4 !== 0 ||
311
+ !/^(?:[A-Za-z\d+/]{4})*(?:[A-Za-z\d+/]{2}==|[A-Za-z\d+/]{3}=)?$/.test(value)) {
312
+ return null;
313
+ }
314
+ const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
315
+ const padding = value.endsWith('==') ? 2 : value.endsWith('=') ? 1 : 0;
316
+ const output = new Uint8Array((value.length / 4) * 3 - padding);
317
+ let outputIndex = 0;
318
+ for (let index = 0; index < value.length; index += 4) {
319
+ const a = alphabet.indexOf(value[index] ?? '');
320
+ const b = alphabet.indexOf(value[index + 1] ?? '');
321
+ const c = value[index + 2] === '=' ? 0 : alphabet.indexOf(value[index + 2] ?? '');
322
+ const d = value[index + 3] === '=' ? 0 : alphabet.indexOf(value[index + 3] ?? '');
323
+ const bits = a * 262_144 + b * 4096 + c * 64 + d;
324
+ if (outputIndex < output.length)
325
+ output[outputIndex++] = Math.floor(bits / 65_536) % 256;
326
+ if (outputIndex < output.length)
327
+ output[outputIndex++] = Math.floor(bits / 256) % 256;
328
+ if (outputIndex < output.length)
329
+ output[outputIndex++] = bits % 256;
330
+ }
331
+ return output;
332
+ }
333
+ function validateUniqueSessionIds(value, context) {
334
+ validateUniqueIds(value.streams, 'streams', context);
335
+ validateUniqueIds(value.clocks, 'clocks', context);
336
+ validateUniqueIds(value.coordinateFrames, 'coordinateFrames', context);
337
+ }
338
+ function validateUniqueIds(values, path, context) {
339
+ const seen = new Set();
340
+ values.forEach((value, index) => {
341
+ if (seen.has(value.id)) {
342
+ context.addIssue({
343
+ code: 'custom',
344
+ message: `Duplicate capture ${path} id: ${value.id}`,
345
+ path: [path, index, 'id'],
346
+ });
347
+ }
348
+ seen.add(value.id);
349
+ });
350
+ }
@@ -0,0 +1,60 @@
1
+ import { z } from 'zod';
2
+ import { type CaptureArtifactReference, type CaptureSessionDescriptor, type CaptureSessionLocator } from './schema.js';
3
+ export declare const CaptureStreamPacketSchema: z.ZodObject<{
4
+ protocolVersion: z.ZodLiteral<1>;
5
+ sessionId: z.ZodString;
6
+ streamId: z.ZodString;
7
+ generation: z.ZodNumber;
8
+ sequence: z.ZodNumber;
9
+ timestamp: z.ZodNumber;
10
+ frameId: z.ZodOptional<z.ZodString>;
11
+ keyframe: z.ZodOptional<z.ZodBoolean>;
12
+ bounds: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber, z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
13
+ payload: z.ZodUnknown;
14
+ }, z.core.$strip>;
15
+ export type CaptureStreamPacket = z.infer<typeof CaptureStreamPacketSchema>;
16
+ export type CaptureSourceEvent = {
17
+ type: 'descriptor';
18
+ descriptor: CaptureSessionDescriptor;
19
+ } | {
20
+ type: 'packet';
21
+ packet: CaptureStreamPacket;
22
+ } | {
23
+ type: 'closed';
24
+ };
25
+ export type CaptureArtifactResolution = {
26
+ url: string;
27
+ dispose?: () => void;
28
+ };
29
+ export type CaptureSubscriptionOptions = {
30
+ signal?: AbortSignal;
31
+ streamIds?: readonly string[];
32
+ };
33
+ export interface CaptureSource {
34
+ describe(signal?: AbortSignal): Promise<CaptureSessionDescriptor>;
35
+ resolveArtifact?(artifact: CaptureArtifactReference, signal?: AbortSignal): Promise<CaptureArtifactResolution>;
36
+ subscribe?(options?: CaptureSubscriptionOptions): AsyncIterable<CaptureSourceEvent>;
37
+ }
38
+ export type CaptureSourceResolver = (locator: CaptureSessionLocator) => CaptureSource | Promise<CaptureSource>;
39
+ export type HttpCaptureSourceOptions = {
40
+ credentials?: RequestCredentials;
41
+ fetch?: typeof globalThis.fetch;
42
+ headers?: HeadersInit;
43
+ manifestUrl?: (locator: CaptureSessionLocator) => string;
44
+ resolveArtifact?: (artifact: CaptureArtifactReference, signal?: AbortSignal) => Promise<CaptureArtifactResolution>;
45
+ };
46
+ export type PushCaptureSourceOptions = {
47
+ maxQueuedEventsPerSubscriber?: number;
48
+ };
49
+ export declare function createHttpCaptureSource(locatorInput: CaptureSessionLocator, options?: HttpCaptureSourceOptions): CaptureSource;
50
+ export declare class PushCaptureSource implements CaptureSource {
51
+ #private;
52
+ constructor(descriptor: CaptureSessionDescriptor, options?: PushCaptureSourceOptions);
53
+ describe(): Promise<CaptureSessionDescriptor>;
54
+ resolveArtifact(artifact: CaptureArtifactReference): Promise<CaptureArtifactResolution>;
55
+ subscribe(options?: CaptureSubscriptionOptions): AsyncIterable<CaptureSourceEvent>;
56
+ updateDescriptor(descriptor: CaptureSessionDescriptor): void;
57
+ publishPacket(packetInput: CaptureStreamPacket): void;
58
+ close(): void;
59
+ }
60
+ //# sourceMappingURL=source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../src/capture/source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,wBAAwB,EAE7B,KAAK,qBAAqB,EAG3B,MAAM,UAAU,CAAA;AAEjB,eAAO,MAAM,yBAAyB;;;;;;;;;;;iBAapC,CAAA;AAEF,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAA;AAE3E,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,UAAU,EAAE,wBAAwB,CAAA;CAAE,GAC5D;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAA;AAEtB,MAAM,MAAM,yBAAyB,GAAG;IACtC,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,0BAA0B,GAAG;IACvC,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAC9B,CAAA;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAA;IACjE,eAAe,CAAC,CACd,QAAQ,EAAE,wBAAwB,EAClC,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,yBAAyB,CAAC,CAAA;IACrC,SAAS,CAAC,CAAC,OAAO,CAAC,EAAE,0BAA0B,GAAG,aAAa,CAAC,kBAAkB,CAAC,CAAA;CACpF;AAED,MAAM,MAAM,qBAAqB,GAAG,CAClC,OAAO,EAAE,qBAAqB,KAC3B,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAA;AAE3C,MAAM,MAAM,wBAAwB,GAAG;IACrC,WAAW,CAAC,EAAE,kBAAkB,CAAA;IAChC,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;IAC/B,OAAO,CAAC,EAAE,WAAW,CAAA;IACrB,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,qBAAqB,KAAK,MAAM,CAAA;IACxD,eAAe,CAAC,EAAE,CAChB,QAAQ,EAAE,wBAAwB,EAClC,MAAM,CAAC,EAAE,WAAW,KACjB,OAAO,CAAC,yBAAyB,CAAC,CAAA;CACxC,CAAA;AAED,MAAM,MAAM,wBAAwB,GAAG;IACrC,4BAA4B,CAAC,EAAE,MAAM,CAAA;CACtC,CAAA;AAED,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,qBAAqB,EACnC,OAAO,GAAE,wBAA6B,GACrC,aAAa,CAwCf;AAmCD,qBAAa,iBAAkB,YAAW,aAAa;;gBAMzC,UAAU,EAAE,wBAAwB,EAAE,OAAO,GAAE,wBAA6B;IAKlF,QAAQ,IAAI,OAAO,CAAC,wBAAwB,CAAC;IAI7C,eAAe,CAAC,QAAQ,EAAE,wBAAwB,GAAG,OAAO,CAAC,yBAAyB,CAAC;IAK7F,SAAS,CAAC,OAAO,GAAE,0BAA+B,GAAG,aAAa,CAAC,kBAAkB,CAAC;IAyBtF,gBAAgB,CAAC,UAAU,EAAE,wBAAwB,GAAG,IAAI;IAU5D,aAAa,CAAC,WAAW,EAAE,mBAAmB,GAAG,IAAI;IAYrD,KAAK,IAAI,IAAI;CAqBd"}
@@ -0,0 +1,254 @@
1
+ import { z } from 'zod';
2
+ import { CaptureSessionDescriptorSchema, CaptureSessionLocatorSchema, normalizeCaptureSessionManifest, } from './schema.js';
3
+ export const CaptureStreamPacketSchema = z.object({
4
+ protocolVersion: z.literal(1),
5
+ sessionId: z.string().min(1),
6
+ streamId: z.string().min(1),
7
+ generation: z.number().int().nonnegative(),
8
+ sequence: z.number().int().nonnegative(),
9
+ timestamp: z.number().nonnegative(),
10
+ frameId: z.string().min(1).optional(),
11
+ keyframe: z.boolean().optional(),
12
+ bounds: z
13
+ .tuple([z.number(), z.number(), z.number(), z.number(), z.number(), z.number()])
14
+ .optional(),
15
+ payload: z.unknown(),
16
+ });
17
+ export function createHttpCaptureSource(locatorInput, options = {}) {
18
+ const locator = CaptureSessionLocatorSchema.parse(locatorInput);
19
+ const manifestUrl = locator.manifestUrl ?? options.manifestUrl?.(locator);
20
+ if (!manifestUrl)
21
+ throw new Error(`Capture session ${locator.sessionId} has no manifest URL.`);
22
+ let descriptorPromise = null;
23
+ const loadDescriptor = async () => {
24
+ const fetcher = options.fetch ?? globalThis.fetch;
25
+ const response = await fetcher(manifestUrl, {
26
+ credentials: options.credentials,
27
+ headers: options.headers,
28
+ });
29
+ if (!response.ok)
30
+ throw new Error(`Capture session ${locator.sessionId} is unavailable.`);
31
+ const descriptor = normalizeCaptureSessionManifest(await response.json());
32
+ if (descriptor.sessionId !== locator.sessionId) {
33
+ throw new Error(`Capture manifest session does not match ${locator.sessionId}.`);
34
+ }
35
+ if (locator.schemaVersion && descriptor.schemaVersion !== locator.schemaVersion) {
36
+ throw new Error(`Capture manifest schema does not match version ${locator.schemaVersion}.`);
37
+ }
38
+ if (locator.revisionId && descriptor.revisionId !== locator.revisionId) {
39
+ throw new Error(`Capture manifest revision does not match ${locator.revisionId}.`);
40
+ }
41
+ return descriptor;
42
+ };
43
+ return {
44
+ describe(signal) {
45
+ descriptorPromise ??= loadDescriptor().catch((cause) => {
46
+ descriptorPromise = null;
47
+ throw cause;
48
+ });
49
+ return waitForPromise(descriptorPromise, signal).then(cloneCaptureDescriptor);
50
+ },
51
+ async resolveArtifact(artifact, signal) {
52
+ if (options.resolveArtifact)
53
+ return options.resolveArtifact(artifact, signal);
54
+ if (!artifact.uri)
55
+ throw new Error(`Capture artifact ${artifact.id} has no URI.`);
56
+ return { url: resolveArtifactUri(artifact.uri, manifestUrl) };
57
+ },
58
+ };
59
+ }
60
+ function waitForPromise(promise, signal) {
61
+ if (!signal)
62
+ return promise;
63
+ if (signal.aborted)
64
+ return Promise.reject(abortError());
65
+ return new Promise((resolve, reject) => {
66
+ const onAbort = () => reject(abortError());
67
+ signal.addEventListener('abort', onAbort, { once: true });
68
+ void promise.then(resolve, reject).finally(() => signal.removeEventListener('abort', onAbort));
69
+ });
70
+ }
71
+ function abortError() {
72
+ const error = new Error('The capture request was aborted.');
73
+ error.name = 'AbortError';
74
+ return error;
75
+ }
76
+ function resolveArtifactUri(uri, manifestUrl) {
77
+ try {
78
+ const base = typeof globalThis.location === 'undefined'
79
+ ? new URL(manifestUrl)
80
+ : new URL(manifestUrl, globalThis.location.href);
81
+ return new URL(uri, base).toString();
82
+ }
83
+ catch {
84
+ return uri;
85
+ }
86
+ }
87
+ export class PushCaptureSource {
88
+ #closed = false;
89
+ #descriptor;
90
+ #maxQueuedEventsPerSubscriber;
91
+ #subscribers = new Set();
92
+ constructor(descriptor, options = {}) {
93
+ this.#descriptor = cloneCaptureDescriptor(descriptor);
94
+ this.#maxQueuedEventsPerSubscriber = Math.max(1, options.maxQueuedEventsPerSubscriber ?? 32);
95
+ }
96
+ async describe() {
97
+ return cloneCaptureDescriptor(this.#descriptor);
98
+ }
99
+ async resolveArtifact(artifact) {
100
+ if (!artifact.uri)
101
+ throw new Error(`Capture artifact ${artifact.id} has no URI.`);
102
+ return { url: artifact.uri };
103
+ }
104
+ subscribe(options = {}) {
105
+ let cleanupAbort = () => { };
106
+ let subscriber;
107
+ const iterator = new EventIterator(() => {
108
+ cleanupAbort();
109
+ this.#subscribers.delete(subscriber);
110
+ }, this.#maxQueuedEventsPerSubscriber);
111
+ subscriber = {
112
+ iterator,
113
+ streamIds: options.streamIds ? new Set(options.streamIds) : null,
114
+ };
115
+ this.#subscribers.add(subscriber);
116
+ if (this.#closed) {
117
+ iterator.close({ type: 'closed' });
118
+ }
119
+ else if (options.signal) {
120
+ if (options.signal.aborted)
121
+ iterator.finish();
122
+ else {
123
+ const onAbort = () => iterator.finish();
124
+ options.signal.addEventListener('abort', onAbort, { once: true });
125
+ cleanupAbort = () => options.signal?.removeEventListener('abort', onAbort);
126
+ }
127
+ }
128
+ return iterator;
129
+ }
130
+ updateDescriptor(descriptor) {
131
+ if (this.#closed)
132
+ return;
133
+ const nextDescriptor = cloneCaptureDescriptor(descriptor);
134
+ if (nextDescriptor.sessionId !== this.#descriptor.sessionId) {
135
+ throw new Error('A capture source cannot change session identity.');
136
+ }
137
+ this.#descriptor = nextDescriptor;
138
+ this.#publish({ type: 'descriptor', descriptor: cloneCaptureDescriptor(nextDescriptor) });
139
+ }
140
+ publishPacket(packetInput) {
141
+ if (this.#closed)
142
+ return;
143
+ const packet = CaptureStreamPacketSchema.parse(packetInput);
144
+ if (packet.sessionId !== this.#descriptor.sessionId) {
145
+ throw new Error(`Capture packet does not belong to ${this.#descriptor.sessionId}.`);
146
+ }
147
+ if (!this.#descriptor.streams.some((stream) => stream.id === packet.streamId)) {
148
+ throw new Error(`Capture packet references unknown stream ${packet.streamId}.`);
149
+ }
150
+ this.#publish({ type: 'packet', packet });
151
+ }
152
+ close() {
153
+ if (this.#closed)
154
+ return;
155
+ this.#closed = true;
156
+ for (const subscriber of this.#subscribers) {
157
+ subscriber.iterator.close({ type: 'closed' });
158
+ }
159
+ this.#subscribers.clear();
160
+ }
161
+ #publish(event) {
162
+ for (const subscriber of this.#subscribers) {
163
+ if (event.type === 'packet' &&
164
+ subscriber.streamIds &&
165
+ !subscriber.streamIds.has(event.packet.streamId)) {
166
+ continue;
167
+ }
168
+ subscriber.iterator.push(cloneCaptureSourceEvent(event));
169
+ }
170
+ }
171
+ }
172
+ class EventIterator {
173
+ #done = false;
174
+ #maxQueuedEvents;
175
+ #onFinish;
176
+ #queue = [];
177
+ #waiters = [];
178
+ constructor(onFinish, maxQueuedEvents) {
179
+ this.#onFinish = onFinish;
180
+ this.#maxQueuedEvents = maxQueuedEvents;
181
+ }
182
+ [Symbol.asyncIterator]() {
183
+ return this;
184
+ }
185
+ next() {
186
+ const event = this.#queue.shift();
187
+ if (event)
188
+ return Promise.resolve({ done: false, value: event });
189
+ if (this.#done)
190
+ return Promise.resolve({ done: true, value: undefined });
191
+ return new Promise((resolve) => this.#waiters.push(resolve));
192
+ }
193
+ return() {
194
+ this.finish();
195
+ return Promise.resolve({ done: true, value: undefined });
196
+ }
197
+ push(event) {
198
+ if (this.#done)
199
+ return;
200
+ const waiter = this.#waiters.shift();
201
+ if (waiter)
202
+ waiter({ done: false, value: event });
203
+ else {
204
+ this.#queue.push(event);
205
+ this.#trimQueue();
206
+ }
207
+ }
208
+ close(event) {
209
+ if (this.#done)
210
+ return;
211
+ this.#done = true;
212
+ this.#queue = [];
213
+ const waiter = this.#waiters.shift();
214
+ if (waiter)
215
+ waiter({ done: false, value: event });
216
+ else
217
+ this.#queue.push(event);
218
+ for (const pending of this.#waiters.splice(0))
219
+ pending({ done: true, value: undefined });
220
+ this.#onFinish();
221
+ }
222
+ finish() {
223
+ if (this.#done) {
224
+ this.#queue = [];
225
+ return;
226
+ }
227
+ this.#done = true;
228
+ this.#queue = [];
229
+ this.#onFinish();
230
+ for (const waiter of this.#waiters.splice(0))
231
+ waiter({ done: true, value: undefined });
232
+ }
233
+ #trimQueue() {
234
+ while (this.#queue.length > this.#maxQueuedEvents) {
235
+ const packetIndex = this.#queue.findIndex((event) => event.type === 'packet');
236
+ this.#queue.splice(packetIndex >= 0 ? packetIndex : 0, 1);
237
+ }
238
+ }
239
+ }
240
+ function cloneCaptureDescriptor(descriptor) {
241
+ return CaptureSessionDescriptorSchema.parse(structuredClone(descriptor));
242
+ }
243
+ function cloneCaptureSourceEvent(event) {
244
+ if (event.type === 'descriptor') {
245
+ return { type: 'descriptor', descriptor: cloneCaptureDescriptor(event.descriptor) };
246
+ }
247
+ if (event.type === 'packet') {
248
+ return {
249
+ type: 'packet',
250
+ packet: CaptureStreamPacketSchema.parse(structuredClone(event.packet)),
251
+ };
252
+ }
253
+ return { type: 'closed' };
254
+ }