@bldrs-ai/conway 1.389.1221 → 1.394.1504

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 (382) hide show
  1. package/README.md +36 -22
  2. package/compiled/Dist/ConwayGeomWasmNode.js +0 -0
  3. package/compiled/Dist/ConwayGeomWasmNodeMT.js +0 -0
  4. package/compiled/Dist/ConwayGeomWasmWeb.js +0 -0
  5. package/compiled/Dist/ConwayGeomWasmWebMT.js +1 -1
  6. package/compiled/Dist/ConwayGeomWasmWebMT.wasm +0 -0
  7. package/compiled/dependencies/conway-geom/Dist/ConwayGeomWasmNode.js +0 -0
  8. package/compiled/dependencies/conway-geom/Dist/ConwayGeomWasmNodeMT.js +0 -0
  9. package/compiled/dependencies/conway-geom/Dist/ConwayGeomWasmWeb.js +0 -0
  10. package/compiled/dependencies/conway-geom/Dist/ConwayGeomWasmWebMT.js +1 -1
  11. package/compiled/dependencies/conway-geom/Dist/ConwayGeomWasmWebMT.wasm +0 -0
  12. package/compiled/dependencies/conway-geom/interface/conway_geometry.d.ts +19 -0
  13. package/compiled/dependencies/conway-geom/interface/conway_geometry.d.ts.map +1 -1
  14. package/compiled/dependencies/conway-geom/interface/conway_geometry.js +17 -0
  15. package/compiled/dependencies/conway-geom/interface/parameters/surface_object.d.ts +6 -0
  16. package/compiled/dependencies/conway-geom/interface/parameters/surface_object.d.ts.map +1 -1
  17. package/compiled/examples/browser-bundled.cjs +1569 -51
  18. package/compiled/examples/cli-bundled.cjs +2790 -436
  19. package/compiled/examples/cli-step-bundled.cjs +1904 -229
  20. package/compiled/examples/validator-bundled.cjs +1569 -51
  21. package/compiled/src/AP214E3_2010/AP214E3_2010_gen/b_spline_curve.gen.d.ts +2 -2
  22. package/compiled/src/AP214E3_2010/AP214E3_2010_gen/b_spline_curve.gen.d.ts.map +1 -1
  23. package/compiled/src/AP214E3_2010/AP214E3_2010_gen/b_spline_curve.gen.js +2 -2
  24. package/compiled/src/AP214E3_2010/AP214E3_2010_gen/b_spline_surface.gen.d.ts +3 -3
  25. package/compiled/src/AP214E3_2010/AP214E3_2010_gen/b_spline_surface.gen.d.ts.map +1 -1
  26. package/compiled/src/AP214E3_2010/AP214E3_2010_gen/b_spline_surface.gen.js +3 -3
  27. package/compiled/src/AP214E3_2010/AP214E3_2010_gen/composite_curve.gen.d.ts +1 -1
  28. package/compiled/src/AP214E3_2010/AP214E3_2010_gen/composite_curve.gen.d.ts.map +1 -1
  29. package/compiled/src/AP214E3_2010/AP214E3_2010_gen/composite_curve.gen.js +1 -1
  30. package/compiled/src/AP214E3_2010/AP214E3_2010_gen/offset_curve_2d.gen.d.ts +1 -1
  31. package/compiled/src/AP214E3_2010/AP214E3_2010_gen/offset_curve_2d.gen.d.ts.map +1 -1
  32. package/compiled/src/AP214E3_2010/AP214E3_2010_gen/offset_curve_2d.gen.js +1 -1
  33. package/compiled/src/AP214E3_2010/AP214E3_2010_gen/offset_curve_3d.gen.d.ts +1 -1
  34. package/compiled/src/AP214E3_2010/AP214E3_2010_gen/offset_curve_3d.gen.d.ts.map +1 -1
  35. package/compiled/src/AP214E3_2010/AP214E3_2010_gen/offset_curve_3d.gen.js +1 -1
  36. package/compiled/src/AP214E3_2010/AP214E3_2010_gen/offset_surface.gen.d.ts +1 -1
  37. package/compiled/src/AP214E3_2010/AP214E3_2010_gen/offset_surface.gen.d.ts.map +1 -1
  38. package/compiled/src/AP214E3_2010/AP214E3_2010_gen/offset_surface.gen.js +1 -1
  39. package/compiled/src/AP214E3_2010/AP214E3_2010_gen/presentation_style_assignment.gen.d.ts.map +1 -1
  40. package/compiled/src/AP214E3_2010/AP214E3_2010_gen/presentation_style_assignment.gen.js +2 -2
  41. package/compiled/src/AP214E3_2010/AP214E3_2010_gen/schema_ap214.gen.js +11 -11
  42. package/compiled/src/AP214E3_2010/AP214E3_2010_gen/shape_aspect.gen.d.ts +1 -1
  43. package/compiled/src/AP214E3_2010/AP214E3_2010_gen/shape_aspect.gen.d.ts.map +1 -1
  44. package/compiled/src/AP214E3_2010/AP214E3_2010_gen/shape_aspect.gen.js +1 -1
  45. package/compiled/src/AP214E3_2010/ap214_command_line_main.js +7 -3
  46. package/compiled/src/AP214E3_2010/ap214_geometry_extraction.d.ts +181 -7
  47. package/compiled/src/AP214E3_2010/ap214_geometry_extraction.d.ts.map +1 -1
  48. package/compiled/src/AP214E3_2010/ap214_geometry_extraction.js +906 -137
  49. package/compiled/src/AP214E3_2010/ap214_geometry_extraction.test.js +10 -2
  50. package/compiled/src/AP214E3_2010/ap214_logical_attribute.test.d.ts +2 -0
  51. package/compiled/src/AP214E3_2010/ap214_logical_attribute.test.d.ts.map +1 -0
  52. package/compiled/src/AP214E3_2010/ap214_logical_attribute.test.js +114 -0
  53. package/compiled/src/AP214E3_2010/ap214_model_geometry.d.ts +6 -0
  54. package/compiled/src/AP214E3_2010/ap214_model_geometry.d.ts.map +1 -1
  55. package/compiled/src/AP214E3_2010/ap214_model_geometry.js +9 -0
  56. package/compiled/src/AP214E3_2010/ap214_pcurve_basis_surfaces.test.d.ts +2 -0
  57. package/compiled/src/AP214E3_2010/ap214_pcurve_basis_surfaces.test.d.ts.map +1 -0
  58. package/compiled/src/AP214E3_2010/ap214_pcurve_basis_surfaces.test.js +233 -0
  59. package/compiled/src/AP214E3_2010/ap214_sphere_vertex_loop.test.d.ts +2 -0
  60. package/compiled/src/AP214E3_2010/ap214_sphere_vertex_loop.test.d.ts.map +1 -0
  61. package/compiled/src/AP214E3_2010/ap214_sphere_vertex_loop.test.js +147 -0
  62. package/compiled/src/AP214E3_2010/ap214_step_model.d.ts +2 -1
  63. package/compiled/src/AP214E3_2010/ap214_step_model.d.ts.map +1 -1
  64. package/compiled/src/AP214E3_2010/ap214_step_model.js +1 -1
  65. package/compiled/src/AP214E3_2010/ap214_typed_select_enum.test.d.ts +2 -0
  66. package/compiled/src/AP214E3_2010/ap214_typed_select_enum.test.d.ts.map +1 -0
  67. package/compiled/src/AP214E3_2010/ap214_typed_select_enum.test.js +65 -0
  68. package/compiled/src/AP214E3_2010/ap214_unit_scale.test.d.ts +2 -0
  69. package/compiled/src/AP214E3_2010/ap214_unit_scale.test.d.ts.map +1 -0
  70. package/compiled/src/AP214E3_2010/ap214_unit_scale.test.js +111 -0
  71. package/compiled/src/compat/web-ifc/ap214_streamed_open.test.d.ts +2 -0
  72. package/compiled/src/compat/web-ifc/ap214_streamed_open.test.d.ts.map +1 -0
  73. package/compiled/src/compat/web-ifc/ap214_streamed_open.test.js +190 -0
  74. package/compiled/src/compat/web-ifc/coordination_export_order.test.d.ts +2 -0
  75. package/compiled/src/compat/web-ifc/coordination_export_order.test.d.ts.map +1 -0
  76. package/compiled/src/compat/web-ifc/coordination_export_order.test.js +110 -0
  77. package/compiled/src/compat/web-ifc/coordination_f64.d.ts +165 -0
  78. package/compiled/src/compat/web-ifc/coordination_f64.d.ts.map +1 -0
  79. package/compiled/src/compat/web-ifc/coordination_f64.js +286 -0
  80. package/compiled/src/compat/web-ifc/coordination_f64.test.d.ts +2 -0
  81. package/compiled/src/compat/web-ifc/coordination_f64.test.d.ts.map +1 -0
  82. package/compiled/src/compat/web-ifc/coordination_f64.test.js +225 -0
  83. package/compiled/src/compat/web-ifc/ifc_api.d.ts +154 -0
  84. package/compiled/src/compat/web-ifc/ifc_api.d.ts.map +1 -1
  85. package/compiled/src/compat/web-ifc/ifc_api.js +211 -3
  86. package/compiled/src/compat/web-ifc/ifc_api_deferred_open.test.d.ts +2 -0
  87. package/compiled/src/compat/web-ifc/ifc_api_deferred_open.test.d.ts.map +1 -0
  88. package/compiled/src/compat/web-ifc/ifc_api_deferred_open.test.js +288 -0
  89. package/compiled/src/compat/web-ifc/ifc_api_model_passthrough.d.ts +39 -0
  90. package/compiled/src/compat/web-ifc/ifc_api_model_passthrough.d.ts.map +1 -1
  91. package/compiled/src/compat/web-ifc/ifc_api_model_passthrough_factory.d.ts +30 -0
  92. package/compiled/src/compat/web-ifc/ifc_api_model_passthrough_factory.d.ts.map +1 -1
  93. package/compiled/src/compat/web-ifc/ifc_api_model_passthrough_factory.js +83 -0
  94. package/compiled/src/compat/web-ifc/ifc_api_preview_channel.test.d.ts +2 -0
  95. package/compiled/src/compat/web-ifc/ifc_api_preview_channel.test.d.ts.map +1 -0
  96. package/compiled/src/compat/web-ifc/ifc_api_preview_channel.test.js +383 -0
  97. package/compiled/src/compat/web-ifc/ifc_api_preview_coordination.test.d.ts +2 -0
  98. package/compiled/src/compat/web-ifc/ifc_api_preview_coordination.test.d.ts.map +1 -0
  99. package/compiled/src/compat/web-ifc/ifc_api_preview_coordination.test.js +124 -0
  100. package/compiled/src/compat/web-ifc/ifc_api_proxy_ap214.d.ts +132 -0
  101. package/compiled/src/compat/web-ifc/ifc_api_proxy_ap214.d.ts.map +1 -1
  102. package/compiled/src/compat/web-ifc/ifc_api_proxy_ap214.js +488 -92
  103. package/compiled/src/compat/web-ifc/ifc_api_proxy_ifc.d.ts +268 -0
  104. package/compiled/src/compat/web-ifc/ifc_api_proxy_ifc.d.ts.map +1 -1
  105. package/compiled/src/compat/web-ifc/ifc_api_proxy_ifc.js +996 -149
  106. package/compiled/src/compat/web-ifc/ifc_api_streamed_open.test.d.ts +2 -0
  107. package/compiled/src/compat/web-ifc/ifc_api_streamed_open.test.d.ts.map +1 -0
  108. package/compiled/src/compat/web-ifc/ifc_api_streamed_open.test.js +129 -0
  109. package/compiled/src/compat/web-ifc/spatial_imposter.d.ts +134 -0
  110. package/compiled/src/compat/web-ifc/spatial_imposter.d.ts.map +1 -0
  111. package/compiled/src/compat/web-ifc/spatial_imposter.js +933 -0
  112. package/compiled/src/compat/web-ifc/spatial_imposter.test.d.ts +2 -0
  113. package/compiled/src/compat/web-ifc/spatial_imposter.test.d.ts.map +1 -0
  114. package/compiled/src/compat/web-ifc/spatial_imposter.test.js +467 -0
  115. package/compiled/src/compat/web-ifc/store_preview_channel.d.ts +187 -0
  116. package/compiled/src/compat/web-ifc/store_preview_channel.d.ts.map +1 -0
  117. package/compiled/src/compat/web-ifc/store_preview_channel.js +524 -0
  118. package/compiled/src/compat/web-ifc/store_preview_channel.test.d.ts +2 -0
  119. package/compiled/src/compat/web-ifc/store_preview_channel.test.d.ts.map +1 -0
  120. package/compiled/src/compat/web-ifc/store_preview_channel.test.js +234 -0
  121. package/compiled/src/compat/web-ifc/streamed_preview_channel.d.ts +306 -0
  122. package/compiled/src/compat/web-ifc/streamed_preview_channel.d.ts.map +1 -0
  123. package/compiled/src/compat/web-ifc/streamed_preview_channel.js +580 -0
  124. package/compiled/src/compat/web-ifc/web_wasm_directory.test.d.ts +2 -0
  125. package/compiled/src/compat/web-ifc/web_wasm_directory.test.d.ts.map +1 -0
  126. package/compiled/src/compat/web-ifc/web_wasm_directory.test.js +22 -0
  127. package/compiled/src/core/composed_model_skeleton.d.ts +63 -0
  128. package/compiled/src/core/composed_model_skeleton.d.ts.map +1 -0
  129. package/compiled/src/core/composed_model_skeleton.js +66 -0
  130. package/compiled/src/core/composed_model_skeleton.test.d.ts +2 -0
  131. package/compiled/src/core/composed_model_skeleton.test.d.ts.map +1 -0
  132. package/compiled/src/core/composed_model_skeleton.test.js +69 -0
  133. package/compiled/src/core/demand_geometry_queue.d.ts +147 -0
  134. package/compiled/src/core/demand_geometry_queue.d.ts.map +1 -0
  135. package/compiled/src/core/demand_geometry_queue.js +223 -0
  136. package/compiled/src/core/demand_geometry_queue.test.d.ts +2 -0
  137. package/compiled/src/core/demand_geometry_queue.test.d.ts.map +1 -0
  138. package/compiled/src/core/demand_geometry_queue.test.js +133 -0
  139. package/compiled/src/core/demand_residency_pump.d.ts +93 -0
  140. package/compiled/src/core/demand_residency_pump.d.ts.map +1 -0
  141. package/compiled/src/core/demand_residency_pump.js +120 -0
  142. package/compiled/src/core/demand_residency_pump.test.d.ts +2 -0
  143. package/compiled/src/core/demand_residency_pump.test.d.ts.map +1 -0
  144. package/compiled/src/core/demand_residency_pump.test.js +148 -0
  145. package/compiled/src/core/geometry_tile_bindings.d.ts +110 -0
  146. package/compiled/src/core/geometry_tile_bindings.d.ts.map +1 -0
  147. package/compiled/src/core/geometry_tile_bindings.js +76 -0
  148. package/compiled/src/core/geometry_tile_bindings.test.d.ts +2 -0
  149. package/compiled/src/core/geometry_tile_bindings.test.d.ts.map +1 -0
  150. package/compiled/src/core/geometry_tile_bindings.test.js +211 -0
  151. package/compiled/src/core/geometry_tile_pool.d.ts +99 -0
  152. package/compiled/src/core/geometry_tile_pool.d.ts.map +1 -0
  153. package/compiled/src/core/geometry_tile_pool.js +104 -0
  154. package/compiled/src/core/geometry_tile_pool.test.d.ts +2 -0
  155. package/compiled/src/core/geometry_tile_pool.test.d.ts.map +1 -0
  156. package/compiled/src/core/geometry_tile_pool.test.js +180 -0
  157. package/compiled/src/core/mem/chunked_pool.d.ts +116 -0
  158. package/compiled/src/core/mem/chunked_pool.d.ts.map +1 -0
  159. package/compiled/src/core/mem/chunked_pool.js +149 -0
  160. package/compiled/src/core/mem/chunked_pool.test.d.ts +2 -0
  161. package/compiled/src/core/mem/chunked_pool.test.d.ts.map +1 -0
  162. package/compiled/src/core/mem/chunked_pool.test.js +63 -0
  163. package/compiled/src/core/mem/shared_asset_pool.d.ts +82 -0
  164. package/compiled/src/core/mem/shared_asset_pool.d.ts.map +1 -0
  165. package/compiled/src/core/mem/shared_asset_pool.js +113 -0
  166. package/compiled/src/core/mem/shared_asset_pool.test.d.ts +2 -0
  167. package/compiled/src/core/mem/shared_asset_pool.test.d.ts.map +1 -0
  168. package/compiled/src/core/mem/shared_asset_pool.test.js +49 -0
  169. package/compiled/src/core/model_registry.d.ts +87 -0
  170. package/compiled/src/core/model_registry.d.ts.map +1 -0
  171. package/compiled/src/core/model_registry.js +101 -0
  172. package/compiled/src/core/model_registry.test.d.ts +2 -0
  173. package/compiled/src/core/model_registry.test.d.ts.map +1 -0
  174. package/compiled/src/core/model_registry.test.js +60 -0
  175. package/compiled/src/core/model_uri.d.ts +57 -0
  176. package/compiled/src/core/model_uri.d.ts.map +1 -0
  177. package/compiled/src/core/model_uri.js +101 -0
  178. package/compiled/src/core/model_uri.test.d.ts +2 -0
  179. package/compiled/src/core/model_uri.test.d.ts.map +1 -0
  180. package/compiled/src/core/model_uri.test.js +49 -0
  181. package/compiled/src/core/progress.d.ts +16 -2
  182. package/compiled/src/core/progress.d.ts.map +1 -1
  183. package/compiled/src/core/progress.js +31 -5
  184. package/compiled/src/core/progress.test.js +11 -2
  185. package/compiled/src/core/progress_log.d.ts +1 -0
  186. package/compiled/src/core/progress_log.d.ts.map +1 -1
  187. package/compiled/src/core/progress_log.js +7 -2
  188. package/compiled/src/core/progress_log.test.js +21 -0
  189. package/compiled/src/core/shared_byte_budget.d.ts +60 -0
  190. package/compiled/src/core/shared_byte_budget.d.ts.map +1 -0
  191. package/compiled/src/core/shared_byte_budget.js +85 -0
  192. package/compiled/src/core/shared_byte_budget.test.d.ts +2 -0
  193. package/compiled/src/core/shared_byte_budget.test.d.ts.map +1 -0
  194. package/compiled/src/core/shared_byte_budget.test.js +55 -0
  195. package/compiled/src/core/wasm_heap.d.ts +208 -0
  196. package/compiled/src/core/wasm_heap.d.ts.map +1 -0
  197. package/compiled/src/core/wasm_heap.js +417 -0
  198. package/compiled/src/core/wasm_heap.test.d.ts +2 -0
  199. package/compiled/src/core/wasm_heap.test.d.ts.map +1 -0
  200. package/compiled/src/core/wasm_heap.test.js +546 -0
  201. package/compiled/src/demand/index.d.ts +23 -0
  202. package/compiled/src/demand/index.d.ts.map +1 -0
  203. package/compiled/src/demand/index.js +22 -0
  204. package/compiled/src/ifc/ifc4_gen/IfcLogical.gen.d.ts +1 -1
  205. package/compiled/src/ifc/ifc4_gen/IfcLogical.gen.d.ts.map +1 -1
  206. package/compiled/src/ifc/ifc4_gen/IfcLogical.gen.js +1 -1
  207. package/compiled/src/ifc/ifc4_gen/IfcPresentationStyleAssignment.gen.d.ts.map +1 -1
  208. package/compiled/src/ifc/ifc4_gen/IfcPresentationStyleAssignment.gen.js +2 -2
  209. package/compiled/src/ifc/ifc4_gen/IfcRelInterferesElements.gen.d.ts +1 -1
  210. package/compiled/src/ifc/ifc4_gen/IfcRelInterferesElements.gen.d.ts.map +1 -1
  211. package/compiled/src/ifc/ifc4_gen/IfcRelInterferesElements.gen.js +1 -1
  212. package/compiled/src/ifc/ifc4_gen/schema_ifc.gen.js +2 -2
  213. package/compiled/src/ifc/ifc_demand_extraction.test.d.ts +2 -0
  214. package/compiled/src/ifc/ifc_demand_extraction.test.d.ts.map +1 -0
  215. package/compiled/src/ifc/ifc_demand_extraction.test.js +251 -0
  216. package/compiled/src/ifc/ifc_geometry_extraction.d.ts +367 -6
  217. package/compiled/src/ifc/ifc_geometry_extraction.d.ts.map +1 -1
  218. package/compiled/src/ifc/ifc_geometry_extraction.js +1322 -389
  219. package/compiled/src/ifc/ifc_grid_placement.test.d.ts +2 -0
  220. package/compiled/src/ifc/ifc_grid_placement.test.d.ts.map +1 -0
  221. package/compiled/src/ifc/ifc_grid_placement.test.js +261 -0
  222. package/compiled/src/ifc/ifc_model_geometry.d.ts +12 -0
  223. package/compiled/src/ifc/ifc_model_geometry.d.ts.map +1 -1
  224. package/compiled/src/ifc/ifc_model_geometry.js +15 -0
  225. package/compiled/src/ifc/ifc_regression_batch_main.js +210 -12
  226. package/compiled/src/ifc/ifc_spatial_skeleton.d.ts +145 -0
  227. package/compiled/src/ifc/ifc_spatial_skeleton.d.ts.map +1 -0
  228. package/compiled/src/ifc/ifc_spatial_skeleton.js +266 -0
  229. package/compiled/src/ifc/ifc_spatial_skeleton.test.d.ts +2 -0
  230. package/compiled/src/ifc/ifc_spatial_skeleton.test.d.ts.map +1 -0
  231. package/compiled/src/ifc/ifc_spatial_skeleton.test.js +199 -0
  232. package/compiled/src/ifc/ifc_step_model.d.ts +6 -2
  233. package/compiled/src/ifc/ifc_step_model.d.ts.map +1 -1
  234. package/compiled/src/ifc/ifc_step_model.js +6 -4
  235. package/compiled/src/ifc/ifc_step_parser.d.ts +58 -0
  236. package/compiled/src/ifc/ifc_step_parser.d.ts.map +1 -1
  237. package/compiled/src/ifc/ifc_step_parser.js +64 -0
  238. package/compiled/src/ifc/ifc_stream_model.test.d.ts +2 -0
  239. package/compiled/src/ifc/ifc_stream_model.test.d.ts.map +1 -0
  240. package/compiled/src/ifc/ifc_stream_model.test.js +70 -0
  241. package/compiled/src/ifc/ifc_stream_open.d.ts +131 -0
  242. package/compiled/src/ifc/ifc_stream_open.d.ts.map +1 -0
  243. package/compiled/src/ifc/ifc_stream_open.js +116 -0
  244. package/compiled/src/ifc/ifc_stream_open.test.d.ts +2 -0
  245. package/compiled/src/ifc/ifc_stream_open.test.d.ts.map +1 -0
  246. package/compiled/src/ifc/ifc_stream_open.test.js +230 -0
  247. package/compiled/src/ifc/ifc_tile_extractor.d.ts +84 -0
  248. package/compiled/src/ifc/ifc_tile_extractor.d.ts.map +1 -0
  249. package/compiled/src/ifc/ifc_tile_extractor.js +134 -0
  250. package/compiled/src/ifc/ifc_tile_extractor.test.d.ts +2 -0
  251. package/compiled/src/ifc/ifc_tile_extractor.test.d.ts.map +1 -0
  252. package/compiled/src/ifc/ifc_tile_extractor.test.js +118 -0
  253. package/compiled/src/ifc/ifc_typed_select_enum.test.d.ts +2 -0
  254. package/compiled/src/ifc/ifc_typed_select_enum.test.d.ts.map +1 -0
  255. package/compiled/src/ifc/ifc_typed_select_enum.test.js +60 -0
  256. package/compiled/src/index.d.ts +21 -1
  257. package/compiled/src/index.d.ts.map +1 -1
  258. package/compiled/src/index.js +28 -1
  259. package/compiled/src/logging/logger.d.ts +16 -2
  260. package/compiled/src/logging/logger.d.ts.map +1 -1
  261. package/compiled/src/logging/logger.js +34 -7
  262. package/compiled/src/logging/logger.test.js +30 -0
  263. package/compiled/src/mem/index.d.ts +17 -0
  264. package/compiled/src/mem/index.d.ts.map +1 -0
  265. package/compiled/src/mem/index.js +16 -0
  266. package/compiled/src/namespace_surface.test.d.ts +2 -0
  267. package/compiled/src/namespace_surface.test.d.ts.map +1 -0
  268. package/compiled/src/namespace_surface.test.js +43 -0
  269. package/compiled/src/parsing/parsing_buffer.d.ts +23 -0
  270. package/compiled/src/parsing/parsing_buffer.d.ts.map +1 -1
  271. package/compiled/src/parsing/parsing_buffer.js +31 -0
  272. package/compiled/src/scripts/model_report_displacement.test.d.ts +2 -0
  273. package/compiled/src/scripts/model_report_displacement.test.d.ts.map +1 -0
  274. package/compiled/src/scripts/model_report_displacement.test.js +104 -0
  275. package/compiled/src/scripts/render_glb_paths.test.d.ts +2 -0
  276. package/compiled/src/scripts/render_glb_paths.test.d.ts.map +1 -0
  277. package/compiled/src/scripts/render_glb_paths.test.js +115 -0
  278. package/compiled/src/step/indexing/step_type_indexer.d.ts +20 -0
  279. package/compiled/src/step/indexing/step_type_indexer.d.ts.map +1 -1
  280. package/compiled/src/step/indexing/step_type_indexer.js +67 -0
  281. package/compiled/src/step/parsing/byte_source.d.ts +153 -0
  282. package/compiled/src/step/parsing/byte_source.d.ts.map +1 -0
  283. package/compiled/src/step/parsing/byte_source.js +106 -0
  284. package/compiled/src/step/parsing/byte_source.test.d.ts +2 -0
  285. package/compiled/src/step/parsing/byte_source.test.d.ts.map +1 -0
  286. package/compiled/src/step/parsing/byte_source.test.js +47 -0
  287. package/compiled/src/step/parsing/byte_source_node.d.ts +41 -0
  288. package/compiled/src/step/parsing/byte_source_node.d.ts.map +1 -0
  289. package/compiled/src/step/parsing/byte_source_node.js +54 -0
  290. package/compiled/src/step/parsing/columnar_index.d.ts +103 -0
  291. package/compiled/src/step/parsing/columnar_index.d.ts.map +1 -0
  292. package/compiled/src/step/parsing/columnar_index.js +224 -0
  293. package/compiled/src/step/parsing/columnar_index.test.d.ts +2 -0
  294. package/compiled/src/step/parsing/columnar_index.test.d.ts.map +1 -0
  295. package/compiled/src/step/parsing/columnar_index.test.js +155 -0
  296. package/compiled/src/step/parsing/cross_reference_registry.d.ts +95 -0
  297. package/compiled/src/step/parsing/cross_reference_registry.d.ts.map +1 -0
  298. package/compiled/src/step/parsing/cross_reference_registry.js +91 -0
  299. package/compiled/src/step/parsing/cross_reference_registry.test.d.ts +2 -0
  300. package/compiled/src/step/parsing/cross_reference_registry.test.d.ts.map +1 -0
  301. package/compiled/src/step/parsing/cross_reference_registry.test.js +66 -0
  302. package/compiled/src/step/parsing/decode_utf8.d.ts +15 -0
  303. package/compiled/src/step/parsing/decode_utf8.d.ts.map +1 -1
  304. package/compiled/src/step/parsing/decode_utf8.js +28 -0
  305. package/compiled/src/step/parsing/express_ref_scan.d.ts +20 -0
  306. package/compiled/src/step/parsing/express_ref_scan.d.ts.map +1 -0
  307. package/compiled/src/step/parsing/express_ref_scan.js +91 -0
  308. package/compiled/src/step/parsing/express_ref_scan.test.d.ts +2 -0
  309. package/compiled/src/step/parsing/express_ref_scan.test.d.ts.map +1 -0
  310. package/compiled/src/step/parsing/express_ref_scan.test.js +28 -0
  311. package/compiled/src/step/parsing/index_sidecar.d.ts +81 -0
  312. package/compiled/src/step/parsing/index_sidecar.d.ts.map +1 -0
  313. package/compiled/src/step/parsing/index_sidecar.js +283 -0
  314. package/compiled/src/step/parsing/index_sidecar.test.d.ts +2 -0
  315. package/compiled/src/step/parsing/index_sidecar.test.d.ts.map +1 -0
  316. package/compiled/src/step/parsing/index_sidecar.test.js +122 -0
  317. package/compiled/src/step/parsing/inf_recovery_index.test.d.ts +2 -0
  318. package/compiled/src/step/parsing/inf_recovery_index.test.d.ts.map +1 -0
  319. package/compiled/src/step/parsing/inf_recovery_index.test.js +108 -0
  320. package/compiled/src/step/parsing/prefix_type_index.d.ts +124 -0
  321. package/compiled/src/step/parsing/prefix_type_index.d.ts.map +1 -0
  322. package/compiled/src/step/parsing/prefix_type_index.js +207 -0
  323. package/compiled/src/step/parsing/prefix_type_index.test.d.ts +2 -0
  324. package/compiled/src/step/parsing/prefix_type_index.test.d.ts.map +1 -0
  325. package/compiled/src/step/parsing/prefix_type_index.test.js +298 -0
  326. package/compiled/src/step/parsing/range_byte_source.d.ts +69 -0
  327. package/compiled/src/step/parsing/range_byte_source.d.ts.map +1 -0
  328. package/compiled/src/step/parsing/range_byte_source.js +78 -0
  329. package/compiled/src/step/parsing/range_byte_source.test.d.ts +2 -0
  330. package/compiled/src/step/parsing/range_byte_source.test.d.ts.map +1 -0
  331. package/compiled/src/step/parsing/range_byte_source.test.js +70 -0
  332. package/compiled/src/step/parsing/record_event.d.ts +23 -0
  333. package/compiled/src/step/parsing/record_event.d.ts.map +1 -0
  334. package/compiled/src/step/parsing/record_event.js +1 -0
  335. package/compiled/src/step/parsing/record_field_cursor.d.ts +94 -0
  336. package/compiled/src/step/parsing/record_field_cursor.d.ts.map +1 -0
  337. package/compiled/src/step/parsing/record_field_cursor.js +189 -0
  338. package/compiled/src/step/parsing/step_deserialization_functions.d.ts +29 -0
  339. package/compiled/src/step/parsing/step_deserialization_functions.d.ts.map +1 -1
  340. package/compiled/src/step/parsing/step_deserialization_functions.js +45 -0
  341. package/compiled/src/step/parsing/step_deserialization_functions.test.js +59 -1
  342. package/compiled/src/step/parsing/step_parser.d.ts +66 -1
  343. package/compiled/src/step/parsing/step_parser.d.ts.map +1 -1
  344. package/compiled/src/step/parsing/step_parser.js +164 -10
  345. package/compiled/src/step/parsing/step_string_parser.js +8 -8
  346. package/compiled/src/step/parsing/streaming_index_builder.d.ts +141 -0
  347. package/compiled/src/step/parsing/streaming_index_builder.d.ts.map +1 -0
  348. package/compiled/src/step/parsing/streaming_index_builder.js +280 -0
  349. package/compiled/src/step/parsing/streaming_index_builder.test.d.ts +2 -0
  350. package/compiled/src/step/parsing/streaming_index_builder.test.d.ts.map +1 -0
  351. package/compiled/src/step/parsing/streaming_index_builder.test.js +107 -0
  352. package/compiled/src/step/parsing/streaming_index_builder_async.test.d.ts +2 -0
  353. package/compiled/src/step/parsing/streaming_index_builder_async.test.d.ts.map +1 -0
  354. package/compiled/src/step/parsing/streaming_index_builder_async.test.js +109 -0
  355. package/compiled/src/step/parsing/streaming_record_dispatcher.d.ts +71 -0
  356. package/compiled/src/step/parsing/streaming_record_dispatcher.d.ts.map +1 -0
  357. package/compiled/src/step/parsing/streaming_record_dispatcher.js +88 -0
  358. package/compiled/src/step/parsing/streaming_record_dispatcher.test.d.ts +2 -0
  359. package/compiled/src/step/parsing/streaming_record_dispatcher.test.d.ts.map +1 -0
  360. package/compiled/src/step/parsing/streaming_record_dispatcher.test.js +66 -0
  361. package/compiled/src/step/parsing/uint32_sink.d.ts +72 -0
  362. package/compiled/src/step/parsing/uint32_sink.d.ts.map +1 -0
  363. package/compiled/src/step/parsing/uint32_sink.js +180 -0
  364. package/compiled/src/step/parsing/uint32_sink.test.d.ts +2 -0
  365. package/compiled/src/step/parsing/uint32_sink.test.d.ts.map +1 -0
  366. package/compiled/src/step/parsing/uint32_sink.test.js +199 -0
  367. package/compiled/src/step/step_buffer_provider.d.ts +48 -3
  368. package/compiled/src/step/step_buffer_provider.d.ts.map +1 -1
  369. package/compiled/src/step/step_buffer_provider.js +60 -11
  370. package/compiled/src/step/step_buffer_provider.test.js +14 -0
  371. package/compiled/src/step/step_entity_base.d.ts +65 -3
  372. package/compiled/src/step/step_entity_base.d.ts.map +1 -1
  373. package/compiled/src/step/step_entity_base.js +135 -3
  374. package/compiled/src/step/step_model_base.d.ts +221 -8
  375. package/compiled/src/step/step_model_base.d.ts.map +1 -1
  376. package/compiled/src/step/step_model_base.js +542 -7
  377. package/compiled/src/stream/index.d.ts +34 -0
  378. package/compiled/src/stream/index.d.ts.map +1 -0
  379. package/compiled/src/stream/index.js +32 -0
  380. package/compiled/src/version/version.js +1 -1
  381. package/compiled/tsconfig.tsbuildinfo +1 -1
  382. package/package.json +16 -1
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Routes the streaming parse's per-record events (M2) to consumers that
3
+ * subscribe by **type set**. A subscription's type set is the subtype closure
4
+ * of the entity constructors it names — the same `query` closure the type
5
+ * index and `expressIDsOfTypes` use (conway #383) — so `on([IfcRoot], …)`
6
+ * matches every product, relationship, property set and quantity, and any
7
+ * future IfcRoot subtype, with no whitelist to maintain.
8
+ *
9
+ * Feed `dispatcher.onRecordIndexed` to `buildIndexStreaming` /
10
+ * `parseDataBlockStreamed`. Handlers run synchronously in the parse path, so
11
+ * they must be cheap (copy ids into a compact structure); anything expensive
12
+ * belongs on a demand queue, not here.
13
+ *
14
+ * Because subscriptions match on the raw parse `typeID`, external-mapping /
15
+ * complex records (typeID 0) are only delivered via `onAnyRecord`. Resolving
16
+ * their concrete types is not this class's job and never was: the columns
17
+ * carry the multi-mapping, so
18
+ * {@link import('./prefix_type_index').PrefixTypeIndex} attributes them
19
+ * correctly without the event stream. For the overwhelming majority of records
20
+ * (simple, one type each) type-set delivery is exact.
21
+ */
22
+ export class StreamingRecordDispatcher {
23
+ constructor() {
24
+ /**
25
+ * Concrete type → the handlers subscribed to it, unioned across
26
+ * subscriptions. Dispatch is one lookup per record no matter how many
27
+ * consumers are attached: the per-record cost of a subscription is the only
28
+ * cost this class has at 9.4 M records, so it must not scale with the
29
+ * subscriber count (issue #393).
30
+ */
31
+ this.byType = new Map();
32
+ this.any = [];
33
+ /**
34
+ * The per-record callback to hand to the streaming parse. Dispatches each
35
+ * record to the matching subscribers. Bound so it can be passed directly.
36
+ *
37
+ * @param localID The record's dense local ID.
38
+ * @param expressID The record's express ID.
39
+ * @param typeID The record's type ID (0 for external-mapping records).
40
+ * @param buffer The live parse window holding the record's bytes.
41
+ * @param byteOffset Offset of the record's first byte within `buffer`.
42
+ * @param byteLength Length of the record in bytes.
43
+ */
44
+ this.onRecordIndexed = (localID, expressID, typeID, buffer, byteOffset, byteLength) => {
45
+ for (const handler of this.any) {
46
+ handler(localID, expressID, typeID, buffer, byteOffset, byteLength);
47
+ }
48
+ if (typeID !== void 0) {
49
+ const handlers = this.byType.get(typeID);
50
+ if (handlers !== void 0) {
51
+ for (const handler of handlers) {
52
+ handler(localID, expressID, typeID, buffer, byteOffset, byteLength);
53
+ }
54
+ }
55
+ }
56
+ };
57
+ }
58
+ /**
59
+ * Subscribe to records of the given entity types (including their
60
+ * subtypes).
61
+ *
62
+ * @param types The entity constructors whose subtype closures to match.
63
+ * @param handler Called for each matching record.
64
+ */
65
+ on(types, handler) {
66
+ // Closures overlap between subscriptions (IfcRoot ⊃ IfcProduct, …), so a
67
+ // type may already have handlers; dedupe within one subscription so a
68
+ // constructor named twice doesn't deliver twice.
69
+ for (const typeID of new Set(types.flatMap((type) => type.query))) {
70
+ const handlers = this.byType.get(typeID);
71
+ if (handlers === void 0) {
72
+ this.byType.set(typeID, [handler]);
73
+ }
74
+ else {
75
+ handlers.push(handler);
76
+ }
77
+ }
78
+ }
79
+ /**
80
+ * Subscribe to every record regardless of type (the firehose — including
81
+ * external-mapping records).
82
+ *
83
+ * @param handler Called for every record.
84
+ */
85
+ onAnyRecord(handler) {
86
+ this.any.push(handler);
87
+ }
88
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=streaming_record_dispatcher.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming_record_dispatcher.test.d.ts","sourceRoot":"","sources":["../../../../src/step/parsing/streaming_record_dispatcher.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,66 @@
1
+ /* eslint-disable no-magic-numbers */
2
+ // M2 core: record events emitted live from the streaming parse, routed by a
3
+ // type-set subscription, let a consumer build a semantic structure
4
+ // incrementally — and it must match what the finished model's type index
5
+ // yields. Here: a roots registry collected from the event stream equals
6
+ // `expressIDsOfTypes(IfcRoot)` on the resident model.
7
+ import * as fs from "fs";
8
+ import { beforeAll, describe, expect, test } from "@jest/globals";
9
+ import ParsingBuffer from "../../parsing/parsing_buffer.js";
10
+ import IfcStepParser from "../../ifc/ifc_step_parser.js";
11
+ import { BufferByteSource } from "./byte_source.js";
12
+ import { buildIndexStreaming } from "./streaming_index_builder.js";
13
+ import { StreamingRecordDispatcher } from "./streaming_record_dispatcher.js";
14
+ import { ParseResult } from "./step_parser.js";
15
+ import { IfcRoot, IfcProduct } from "../../ifc/ifc4_gen/index.js";
16
+ let bytes;
17
+ let residentRoots;
18
+ let residentProducts;
19
+ beforeAll(() => {
20
+ bytes = new Uint8Array(fs.readFileSync("data/index.ifc"));
21
+ const input = new ParsingBuffer(bytes);
22
+ IfcStepParser.Instance.parseHeader(input);
23
+ const [, model] = IfcStepParser.Instance.parseDataToModel(input);
24
+ residentRoots = new Set(model.expressIDsOfTypes(IfcRoot));
25
+ residentProducts = new Set(model.expressIDsOfTypes(IfcProduct));
26
+ });
27
+ describe("StreamingRecordDispatcher", () => {
28
+ test("a roots registry built live from the event stream matches the type index", () => {
29
+ const roots = [];
30
+ const products = new Set();
31
+ const dispatcher = new StreamingRecordDispatcher();
32
+ dispatcher.on([IfcRoot], (_localID, expressID) => roots.push(expressID));
33
+ dispatcher.on([IfcProduct], (_localID, expressID) => products.add(expressID));
34
+ const result = buildIndexStreaming(new BufferByteSource(bytes), IfcStepParser.Instance, 4 * 1024, // tiny pool → the parse slides; events still fire per record
35
+ dispatcher.onRecordIndexed);
36
+ expect(result.result).toBe(ParseResult.COMPLETE);
37
+ // index.ifc has no external-mapping records, so raw-typeID delivery is
38
+ // exact vs. the type index.
39
+ expect(new Set(roots)).toEqual(residentRoots);
40
+ expect(products).toEqual(residentProducts);
41
+ // Products are a strict subset of roots (IfcProduct ⊂ IfcRoot).
42
+ expect(residentProducts.size).toBeLessThan(residentRoots.size);
43
+ for (const p of products) {
44
+ expect(residentRoots.has(p)).toBe(true);
45
+ }
46
+ });
47
+ test("localIDs arrive dense and in ascending parse order", () => {
48
+ const localIDs = [];
49
+ const dispatcher = new StreamingRecordDispatcher();
50
+ dispatcher.onAnyRecord((localID) => localIDs.push(localID));
51
+ buildIndexStreaming(new BufferByteSource(bytes), IfcStepParser.Instance, 128 * 1024, dispatcher.onRecordIndexed);
52
+ expect(localIDs.length).toBeGreaterThan(10);
53
+ // 0,1,2,…,n-1 in order.
54
+ expect(localIDs).toEqual(localIDs.map((_v, i) => i));
55
+ });
56
+ test("onAnyRecord sees every record; a type filter sees a subset", () => {
57
+ let all = 0;
58
+ let rootsCount = 0;
59
+ const dispatcher = new StreamingRecordDispatcher();
60
+ dispatcher.onAnyRecord(() => ++all);
61
+ dispatcher.on([IfcRoot], () => ++rootsCount);
62
+ buildIndexStreaming(new BufferByteSource(bytes), IfcStepParser.Instance, 128 * 1024, dispatcher.onRecordIndexed);
63
+ expect(all).toBeGreaterThan(rootsCount);
64
+ expect(rootsCount).toBe(residentRoots.size);
65
+ });
66
+ });
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Growable Uint32Array append sink.
3
+ *
4
+ * Exists so hot extraction loops can parse integer list fields straight
5
+ * out of the STEP buffer into one reusable typed array, instead of
6
+ * allocating (and caching) a boxed `Array< number >` per record. On
7
+ * tessellated IFC4 models that difference is structural: a large
8
+ * polygonal-faceset model carries millions of IfcIndexedPolygonalFace
9
+ * records, and a per-record array for each is the dominant source of
10
+ * both GC time and retained heap during geometry extraction.
11
+ */
12
+ export declare class Uint32Sink {
13
+ private data_;
14
+ private length_;
15
+ /**
16
+ * @param initialCapacity Initial element capacity.
17
+ */
18
+ constructor(initialCapacity?: number);
19
+ /** @return {number} Element count appended since the last reset. */
20
+ get length(): number;
21
+ /**
22
+ * A view of exactly the appended elements. Only valid until the next
23
+ * append (which may reallocate) — copy it if it must outlive that.
24
+ *
25
+ * @return {Uint32Array} View over [0, length).
26
+ */
27
+ get view(): Uint32Array;
28
+ /** Drop all appended elements, keeping the allocated capacity. */
29
+ reset(): void;
30
+ /**
31
+ * Keep the first `length` elements. Used to unwind a failed fast path.
32
+ *
33
+ * @param length New length, ≤ current length.
34
+ */
35
+ truncate(length: number): void;
36
+ /**
37
+ * Append one value, growing geometrically when full.
38
+ *
39
+ * @param value The value to append.
40
+ */
41
+ push(value: number): void;
42
+ }
43
+ /**
44
+ * Parse a STEP integer list at `cursor` into `sink`, appending in order.
45
+ *
46
+ * The single implementation shared by the entity-level and
47
+ * reference-level fast paths, so they cannot drift from each other or
48
+ * from the generated array getters they stand in for (same optional
49
+ * handling, same element extraction, same "incorrectly typed" error).
50
+ *
51
+ * @param buffer The record's buffer window.
52
+ * @param cursor Start of the field.
53
+ * @param endCursor End bound for extraction.
54
+ * @param sink Receives the appended values.
55
+ * @return {number} How many values were appended (0 when unset/optional-null).
56
+ */
57
+ export declare function extractIntegerArrayAt(buffer: Uint8Array, cursor: number, endCursor: number, sink: Uint32Sink): number;
58
+ /**
59
+ * Fast path for `(1,2,3,4)` / `(1, 2, 3, 4)` — the CoordIndex shape.
60
+ * Digits only, no comments, no reals. Returns undefined when the field
61
+ * is not that shape so the caller can use the general parser. A failed
62
+ * parse does not leave partial values in `sink`.
63
+ *
64
+ * @param buffer Record window.
65
+ * @param cursor Start of the field.
66
+ * @param endCursor End bound.
67
+ * @param sink Receives values.
68
+ * @return {number | undefined} Count appended, or undefined if this
69
+ * is not an unsigned-integer list.
70
+ */
71
+ export declare function extractUnsignedIntegerListAt(buffer: Uint8Array, cursor: number, endCursor: number, sink: Uint32Sink): number | undefined;
72
+ //# sourceMappingURL=uint32_sink.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uint32_sink.d.ts","sourceRoot":"","sources":["../../../../src/step/parsing/uint32_sink.ts"],"names":[],"mappings":"AAgBA;;;;;;;;;;GAUG;AACH,qBAAa,UAAU;IAErB,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,OAAO,CAAY;IAE3B;;OAEG;gBACU,eAAe,GAAE,MAAa;IAI3C,oEAAoE;IACpE,IAAW,MAAM,IAAI,MAAM,CAE1B;IAED;;;;;OAKG;IACH,IAAW,IAAI,IAAI,WAAW,CAE7B;IAED,kEAAkE;IAC3D,KAAK,IAAI,IAAI;IAIpB;;;;OAIG;IACI,QAAQ,CAAE,MAAM,EAAE,MAAM,GAAI,IAAI;IAIvC;;;;OAIG;IACI,IAAI,CAAE,KAAK,EAAE,MAAM,GAAI,IAAI;CAanC;AAGD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CACjC,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,UAAU,GAAI,MAAM,CAqC7B;AAGD;;;;;;;;;;;;GAYG;AACH,wBAAgB,4BAA4B,CACxC,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,UAAU,GAAI,MAAM,GAAG,SAAS,CAsFzC"}
@@ -0,0 +1,180 @@
1
+ import { skipValue, stepExtractArrayBegin, stepExtractArrayToken, stepExtractNumber, stepExtractOptional, } from "./step_deserialization_functions.js";
2
+ import ParsingConstants from "../../parsing/parsing_constants.js";
3
+ const OPEN_PAREN = ParsingConstants.OPEN_PAREN;
4
+ const CLOSE_PAREN = ParsingConstants.CLOSE_PAREN;
5
+ const COMMA = ParsingConstants.COMMA;
6
+ const ZERO = ParsingConstants.ZERO;
7
+ const WHITESPACE = ParsingConstants.WHITE_SPACE_SET;
8
+ /**
9
+ * Growable Uint32Array append sink.
10
+ *
11
+ * Exists so hot extraction loops can parse integer list fields straight
12
+ * out of the STEP buffer into one reusable typed array, instead of
13
+ * allocating (and caching) a boxed `Array< number >` per record. On
14
+ * tessellated IFC4 models that difference is structural: a large
15
+ * polygonal-faceset model carries millions of IfcIndexedPolygonalFace
16
+ * records, and a per-record array for each is the dominant source of
17
+ * both GC time and retained heap during geometry extraction.
18
+ */
19
+ export class Uint32Sink {
20
+ /**
21
+ * @param initialCapacity Initial element capacity.
22
+ */
23
+ constructor(initialCapacity = 1024) {
24
+ this.length_ = 0;
25
+ this.data_ = new Uint32Array(Math.max(1, initialCapacity));
26
+ }
27
+ /** @return {number} Element count appended since the last reset. */
28
+ get length() {
29
+ return this.length_;
30
+ }
31
+ /**
32
+ * A view of exactly the appended elements. Only valid until the next
33
+ * append (which may reallocate) — copy it if it must outlive that.
34
+ *
35
+ * @return {Uint32Array} View over [0, length).
36
+ */
37
+ get view() {
38
+ return this.data_.subarray(0, this.length_);
39
+ }
40
+ /** Drop all appended elements, keeping the allocated capacity. */
41
+ reset() {
42
+ this.length_ = 0;
43
+ }
44
+ /**
45
+ * Keep the first `length` elements. Used to unwind a failed fast path.
46
+ *
47
+ * @param length New length, ≤ current length.
48
+ */
49
+ truncate(length) {
50
+ this.length_ = length;
51
+ }
52
+ /**
53
+ * Append one value, growing geometrically when full.
54
+ *
55
+ * @param value The value to append.
56
+ */
57
+ push(value) {
58
+ if (this.length_ === this.data_.length) {
59
+ const grown = new Uint32Array(this.data_.length * 2);
60
+ grown.set(this.data_);
61
+ this.data_ = grown;
62
+ }
63
+ this.data_[this.length_++] = value;
64
+ }
65
+ }
66
+ /**
67
+ * Parse a STEP integer list at `cursor` into `sink`, appending in order.
68
+ *
69
+ * The single implementation shared by the entity-level and
70
+ * reference-level fast paths, so they cannot drift from each other or
71
+ * from the generated array getters they stand in for (same optional
72
+ * handling, same element extraction, same "incorrectly typed" error).
73
+ *
74
+ * @param buffer The record's buffer window.
75
+ * @param cursor Start of the field.
76
+ * @param endCursor End bound for extraction.
77
+ * @param sink Receives the appended values.
78
+ * @return {number} How many values were appended (0 when unset/optional-null).
79
+ */
80
+ export function extractIntegerArrayAt(buffer, cursor, endCursor, sink) {
81
+ const marked = sink.length;
82
+ const fast = extractUnsignedIntegerListAt(buffer, cursor, endCursor, sink);
83
+ if (fast !== void 0) {
84
+ return fast;
85
+ }
86
+ sink.truncate(marked);
87
+ if (stepExtractOptional(buffer, cursor, endCursor) === null) {
88
+ return 0;
89
+ }
90
+ let count = 0;
91
+ let signedCursor0 = stepExtractArrayBegin(buffer, cursor, endCursor);
92
+ let readCursor = Math.abs(signedCursor0);
93
+ while (signedCursor0 >= 0) {
94
+ const value = stepExtractNumber(buffer, readCursor, endCursor);
95
+ if (value === void 0) {
96
+ throw new Error("Value in STEP was incorrectly typed");
97
+ }
98
+ readCursor = skipValue(buffer, readCursor, endCursor);
99
+ sink.push(value);
100
+ ++count;
101
+ signedCursor0 = stepExtractArrayToken(buffer, readCursor, endCursor);
102
+ readCursor = Math.abs(signedCursor0);
103
+ }
104
+ return count;
105
+ }
106
+ /**
107
+ * Fast path for `(1,2,3,4)` / `(1, 2, 3, 4)` — the CoordIndex shape.
108
+ * Digits only, no comments, no reals. Returns undefined when the field
109
+ * is not that shape so the caller can use the general parser. A failed
110
+ * parse does not leave partial values in `sink`.
111
+ *
112
+ * @param buffer Record window.
113
+ * @param cursor Start of the field.
114
+ * @param endCursor End bound.
115
+ * @param sink Receives values.
116
+ * @return {number | undefined} Count appended, or undefined if this
117
+ * is not an unsigned-integer list.
118
+ */
119
+ export function extractUnsignedIntegerListAt(buffer, cursor, endCursor, sink) {
120
+ const marked = sink.length;
121
+ while (cursor < endCursor && WHITESPACE.has(buffer[cursor])) {
122
+ ++cursor;
123
+ }
124
+ if (cursor >= endCursor) {
125
+ return void 0;
126
+ }
127
+ if (buffer[cursor] === ParsingConstants.DOLLAR) {
128
+ return 0;
129
+ }
130
+ if (buffer[cursor] !== OPEN_PAREN) {
131
+ return void 0;
132
+ }
133
+ ++cursor;
134
+ let count = 0;
135
+ while (cursor < endCursor) {
136
+ while (cursor < endCursor && WHITESPACE.has(buffer[cursor])) {
137
+ ++cursor;
138
+ }
139
+ if (cursor >= endCursor) {
140
+ sink.truncate(marked);
141
+ return void 0;
142
+ }
143
+ if (buffer[cursor] === CLOSE_PAREN) {
144
+ return count;
145
+ }
146
+ if (count > 0) {
147
+ if (buffer[cursor] !== COMMA) {
148
+ sink.truncate(marked);
149
+ return void 0;
150
+ }
151
+ ++cursor;
152
+ while (cursor < endCursor && WHITESPACE.has(buffer[cursor])) {
153
+ ++cursor;
154
+ }
155
+ if (cursor >= endCursor) {
156
+ sink.truncate(marked);
157
+ return void 0;
158
+ }
159
+ }
160
+ const digit = buffer[cursor] - ZERO;
161
+ if (digit < 0 || digit > 9) {
162
+ sink.truncate(marked);
163
+ return void 0;
164
+ }
165
+ let value = digit;
166
+ ++cursor;
167
+ while (cursor < endCursor) {
168
+ const next = buffer[cursor] - ZERO;
169
+ if (next < 0 || next > 9) {
170
+ break;
171
+ }
172
+ value = value * 10 + next;
173
+ ++cursor;
174
+ }
175
+ sink.push(value);
176
+ ++count;
177
+ }
178
+ sink.truncate(marked);
179
+ return void 0;
180
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=uint32_sink.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uint32_sink.test.d.ts","sourceRoot":"","sources":["../../../../src/step/parsing/uint32_sink.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,199 @@
1
+ /* eslint-disable no-magic-numbers */
2
+ // Uint32Sink backs the polygonal-faceset extraction fast path, and
3
+ // extractIntegerArrayInto must stay exactly equivalent to the generated
4
+ // array getters it replaces there — including for a real model's faces.
5
+ import * as fs from "fs";
6
+ import { beforeAll, describe, expect, test } from "@jest/globals";
7
+ import { IfcAPI } from "../../compat/web-ifc/ifc_api.js";
8
+ import EntityTypesIfc from "../../ifc/ifc4_gen/entity_types_ifc.gen.js";
9
+ import { IfcIndexedPolygonalFace, IfcIndexedPolygonalFaceWithVoids, IfcPolygonalFaceSet, } from "../../ifc/ifc4_gen/index.js";
10
+ import { Uint32Sink, extractUnsignedIntegerListAt } from "./uint32_sink.js";
11
+ describe("Uint32Sink", () => {
12
+ test("appends, grows past its initial capacity, and views exactly its length", () => {
13
+ const sink = new Uint32Sink(2);
14
+ expect(sink.length).toBe(0);
15
+ expect(Array.from(sink.view)).toEqual([]);
16
+ for (let where = 0; where < 10; ++where) {
17
+ sink.push(where * 3);
18
+ }
19
+ expect(sink.length).toBe(10);
20
+ expect(Array.from(sink.view)).toEqual([0, 3, 6, 9, 12, 15, 18, 21, 24, 27]);
21
+ });
22
+ test("extractUnsignedIntegerListAt parses a plain CoordIndex list", () => {
23
+ const sink = new Uint32Sink(4);
24
+ const bytes = new TextEncoder().encode("(1,2,3,4)");
25
+ expect(extractUnsignedIntegerListAt(bytes, 0, bytes.length, sink)).toBe(4);
26
+ expect(Array.from(sink.view)).toEqual([1, 2, 3, 4]);
27
+ });
28
+ test("extractUnsignedIntegerListAt refuses a real and leaves the sink clean", () => {
29
+ const sink = new Uint32Sink(4);
30
+ const bytes = new TextEncoder().encode("(1,2.5,3)");
31
+ sink.push(9);
32
+ expect(extractUnsignedIntegerListAt(bytes, 0, bytes.length, sink))
33
+ .toBeUndefined();
34
+ expect(Array.from(sink.view)).toEqual([9]);
35
+ });
36
+ test("reset drops elements but keeps capacity for reuse", () => {
37
+ const sink = new Uint32Sink(4);
38
+ sink.push(11);
39
+ sink.push(22);
40
+ sink.reset();
41
+ expect(sink.length).toBe(0);
42
+ expect(Array.from(sink.view)).toEqual([]);
43
+ sink.push(33);
44
+ expect(Array.from(sink.view)).toEqual([33]);
45
+ });
46
+ });
47
+ describe("extractIntegerArrayInto", () => {
48
+ let api;
49
+ let modelID;
50
+ /**
51
+ * The faces the extraction fast path actually covers: voided faces
52
+ * keep the getter path in production, so exclude them here too.
53
+ *
54
+ * @return {IfcIndexedPolygonalFace[]} Non-voided faces of the fixture.
55
+ */
56
+ function plainFaces() {
57
+ // The passthrough holds the proxy tuple; the StepModel is its head.
58
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
59
+ const model = api.models.get(modelID).model[0];
60
+ return Array.from(model.types(IfcIndexedPolygonalFace))
61
+ .filter((face) => !(face instanceof IfcIndexedPolygonalFaceWithVoids));
62
+ }
63
+ beforeAll(async () => {
64
+ api = new IfcAPI();
65
+ await api.Init();
66
+ modelID = api.OpenModel(new Uint8Array(fs.readFileSync("data/index.ifc")), { COORDINATE_TO_ORIGIN: true, USE_FAST_BOOLS: true });
67
+ }, 120000);
68
+ test("matches the generated CoordIndex getter on every face of a real model", () => {
69
+ const faces = plainFaces();
70
+ expect(faces.length).toBeGreaterThan(0);
71
+ const sink = new Uint32Sink(4);
72
+ for (const face of faces) {
73
+ // The getter caches, so read it first and compare the in-place
74
+ // parse against it — the fast path must be a drop-in.
75
+ const expected = face.CoordIndex;
76
+ sink.reset();
77
+ const count = face.extractIntegerArrayInto(0, 0, 3, sink);
78
+ expect(count).toBe(expected.length);
79
+ expect(Array.from(sink.view)).toEqual(expected);
80
+ }
81
+ }, 120000);
82
+ test("appends consecutively across records into one sink", () => {
83
+ const faces = plainFaces();
84
+ const sink = new Uint32Sink(4);
85
+ const expected = [];
86
+ for (const face of faces) {
87
+ face.extractIntegerArrayInto(0, 0, 3, sink);
88
+ expected.push(...face.CoordIndex);
89
+ }
90
+ expect(Array.from(sink.view)).toEqual(expected);
91
+ }, 120000);
92
+ });
93
+ // The reference-level path the faceset extraction uses to avoid
94
+ // constructing an entity per face. It must agree with the generated
95
+ // getters exactly, and must report failure (rather than guess) whenever
96
+ // its preconditions don't hold, because the caller's fallback depends on
97
+ // that signal.
98
+ describe("reference-level faceset fast path", () => {
99
+ const FACES_OFFSET = 2;
100
+ const FACES_BASE_OFFSET = 1;
101
+ const FACES_DEPTH = 4;
102
+ const COORD_INDEX_OFFSET = 0;
103
+ let api;
104
+ let modelID;
105
+ /**
106
+ * @return {object} The StepModel behind the passthrough tuple.
107
+ */
108
+ function stepModel() {
109
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
110
+ return api.models.get(modelID).model[0];
111
+ }
112
+ /**
113
+ * @return {IfcPolygonalFaceSet[]} The fixture's facesets.
114
+ */
115
+ function faceSets() {
116
+ return Array.from(stepModel().types(IfcPolygonalFaceSet));
117
+ }
118
+ beforeAll(async () => {
119
+ api = new IfcAPI();
120
+ await api.Init();
121
+ modelID = api.OpenModel(new Uint8Array(fs.readFileSync("data/index.ifc")), { COORDINATE_TO_ORIGIN: true, USE_FAST_BOOLS: true });
122
+ }, 120000);
123
+ test("forEachReferenceInField yields exactly the express IDs the Faces getter resolves", () => {
124
+ const sets = faceSets();
125
+ expect(sets.length).toBeGreaterThan(0);
126
+ for (const faceSet of sets) {
127
+ const walked = [];
128
+ const completed = faceSet.forEachReferenceInField(FACES_OFFSET, FACES_BASE_OFFSET, FACES_DEPTH, (expressID) => {
129
+ walked.push(expressID);
130
+ return true;
131
+ });
132
+ expect(completed).toBe(true);
133
+ expect(walked).toEqual(faceSet.Faces.map((face) => face.expressID));
134
+ }
135
+ }, 120000);
136
+ test("forEachReferenceInField stops when the callback returns false", () => {
137
+ const faceSet = faceSets()[0];
138
+ const walked = [];
139
+ const completed = faceSet.forEachReferenceInField(FACES_OFFSET, FACES_BASE_OFFSET, FACES_DEPTH, (expressID) => {
140
+ walked.push(expressID);
141
+ return false;
142
+ });
143
+ expect(completed).toBe(false);
144
+ expect(walked.length).toBe(1);
145
+ }, 120000);
146
+ test("extractIntegerArrayByExpressIDInto matches the generated CoordIndex getter", () => {
147
+ const model = stepModel();
148
+ const sink = new Uint32Sink(4);
149
+ for (const faceSet of faceSets()) {
150
+ for (const face of faceSet.Faces) {
151
+ if (face instanceof IfcIndexedPolygonalFaceWithVoids) {
152
+ continue;
153
+ }
154
+ sink.reset();
155
+ const count = model.extractIntegerArrayByExpressIDInto(face.expressID, COORD_INDEX_OFFSET, EntityTypesIfc.IFCINDEXEDPOLYGONALFACE, sink);
156
+ expect(count).toBe(face.CoordIndex.length);
157
+ expect(Array.from(sink.view)).toEqual(face.CoordIndex);
158
+ }
159
+ }
160
+ }, 120000);
161
+ test("column path matches CoordIndex without materialising the face first", () => {
162
+ const model = stepModel();
163
+ const sink = new Uint32Sink(4);
164
+ for (const faceSet of faceSets()) {
165
+ const expressIDs = [];
166
+ faceSet.forEachReferenceInField(FACES_OFFSET, FACES_BASE_OFFSET, FACES_DEPTH, (expressID) => {
167
+ if (expressID !== void 0) {
168
+ expressIDs.push(expressID);
169
+ }
170
+ return true;
171
+ });
172
+ const fromColumns = [];
173
+ for (const expressID of expressIDs) {
174
+ sink.reset();
175
+ const count = model.extractIntegerArrayByExpressIDInto(expressID, COORD_INDEX_OFFSET, EntityTypesIfc.IFCINDEXEDPOLYGONALFACE, sink);
176
+ if (count === void 0) {
177
+ continue;
178
+ }
179
+ fromColumns.push(Array.from(sink.view));
180
+ }
181
+ const fromGetter = faceSet.Faces
182
+ .filter((face) => !(face instanceof IfcIndexedPolygonalFaceWithVoids))
183
+ .map((face) => face.CoordIndex);
184
+ expect(fromColumns).toEqual(fromGetter);
185
+ }
186
+ }, 120000);
187
+ test("reports failure for an unknown express ID and for a type mismatch", () => {
188
+ const model = stepModel();
189
+ const sink = new Uint32Sink(4);
190
+ const face = faceSets()[0].Faces[0];
191
+ // Unknown record: the caller must fall back, not read something else.
192
+ expect(model.extractIntegerArrayByExpressIDInto(268435455, COORD_INDEX_OFFSET, EntityTypesIfc.IFCINDEXEDPOLYGONALFACE, sink))
193
+ .toBeUndefined();
194
+ // Right record, wrong expected type: field offsets would not be
195
+ // comparable, so this must refuse rather than misread the record.
196
+ expect(model.extractIntegerArrayByExpressIDInto(face.expressID, COORD_INDEX_OFFSET, EntityTypesIfc.IFCPOLYGONALFACESET, sink))
197
+ .toBeUndefined();
198
+ }, 120000);
199
+ });