gps-plus-slam-app-framework 1.4.0 → 1.8.0

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 (243) hide show
  1. package/dist/absolute-orientation-BAxc15J6.d.ts +54 -0
  2. package/dist/{accuracy-circles-Pi2YeCrM.d.ts → accuracy-circles-DkWBkF5g.d.ts} +16 -6
  3. package/dist/{app-selectors-CrOucL00.d.ts → app-selectors-JqydaUMN.d.ts} +1 -1
  4. package/dist/ar/bresenham3d.d.ts +1 -1
  5. package/dist/ar/camera-blit-capture.d.ts +1 -1
  6. package/dist/ar/capability-checker.d.ts +1 -1
  7. package/dist/ar/capture-failure-tracker.d.ts +1 -1
  8. package/dist/ar/chromium-camera-access-workaround.d.ts +1 -1
  9. package/dist/ar/depth-grid-lookup.d.ts +1 -1
  10. package/dist/ar/depth-occluder.d.ts +127 -0
  11. package/dist/ar/depth-occluder.js +299 -0
  12. package/dist/ar/depth-sampler.d.ts +2 -2
  13. package/dist/ar/depth-sampler.js +24 -4
  14. package/dist/ar/depth-unprojection.d.ts +1 -1
  15. package/dist/ar/depth-unprojection.js +52 -21
  16. package/dist/ar/enable-gps-ar.d.ts +1 -1
  17. package/dist/ar/enable-gps-ar.js +1 -1
  18. package/dist/ar/frame-loop.d.ts +1 -1
  19. package/dist/ar/frame-loop.js +12 -2
  20. package/dist/ar/image-capture.d.ts +2 -2
  21. package/dist/ar/image-capture.js +1 -154
  22. package/dist/ar/image-quality.d.ts +2 -0
  23. package/dist/ar/image-quality.js +169 -0
  24. package/dist/ar/index.d.ts +32 -30
  25. package/dist/ar/index.js +7 -5
  26. package/dist/ar/occlusion-mesh-worker.d.ts +58 -0
  27. package/dist/ar/occlusion-mesh-worker.js +129 -0
  28. package/dist/ar/occupancy-grid.d.ts +2 -2
  29. package/dist/ar/occupancy-grid.js +287 -31
  30. package/dist/ar/occupancy-mesher.d.ts +2 -0
  31. package/dist/ar/occupancy-mesher.js +638 -0
  32. package/dist/ar/planar-pnp.d.ts +1 -1
  33. package/dist/ar/qr-debug-view.d.ts +1 -1
  34. package/dist/ar/qr-derived-pose.d.ts +1 -1
  35. package/dist/ar/qr-detection-controller.d.ts +1 -1
  36. package/dist/ar/qr-frontend.d.ts +1 -1
  37. package/dist/ar/qr-pose.d.ts +1 -1
  38. package/dist/ar/qr-size-depth-context.d.ts +2 -2
  39. package/dist/ar/qr-size-measurer.d.ts +1 -1
  40. package/dist/ar/replay-scene.d.ts +1 -1
  41. package/dist/ar/replay-scene.js +1 -1
  42. package/dist/ar/scene-node-names.d.ts +1 -1
  43. package/dist/ar/webxr-nue-basis.d.ts +1 -1
  44. package/dist/ar/webxr-session.d.ts +4 -4
  45. package/dist/ar/webxr-session.js +2 -2
  46. package/dist/ar/xr-camera-texture.d.ts +1 -1
  47. package/dist/ar/xr-error-handler.d.ts +1 -1
  48. package/dist/ar/xr-frame-loop.d.ts +1 -1
  49. package/dist/ar/xr-frame-loop.js +12 -2
  50. package/dist/{ar-Dc72Ksiu.js → ar-BqCudtqE.js} +4 -3
  51. package/dist/{ar-world-group-alignment-DDLkgNf_.d.ts → ar-world-group-alignment-BlvGcIAk.d.ts} +1 -1
  52. package/dist/capture-motion-gate-BGoAMkmf.d.ts +24 -0
  53. package/dist/capture-motion-gate-_NdTSwKi.js +106 -0
  54. package/dist/cell-key-DIB4rOTV.js +51 -0
  55. package/dist/core/index.d.ts +2 -2
  56. package/dist/core/index.js +2 -2
  57. package/dist/{create-slam-app-store-Ce2FMKCp.d.ts → create-slam-app-store-D3nzh9Wb.d.ts} +50 -40
  58. package/dist/create-slam-app-store-DXiAnJwR.js +156 -0
  59. package/dist/{depth-grid-lookup-vMDrGTk_.d.ts → depth-grid-lookup-D5atpNZ3.d.ts} +1 -1
  60. package/dist/{depth-sampler-DwfPYzS7.d.ts → depth-sampler-CwObAwEA.d.ts} +33 -1
  61. package/dist/{depth-unprojection-CK3b9htH.d.ts → depth-unprojection-DRdBU90S.d.ts} +1 -1
  62. package/dist/{enable-gps-ar-CjZ1nEdu.d.ts → enable-gps-ar-DvGzBOrp.d.ts} +4 -4
  63. package/dist/{frame-conversions-D_Af8Dt3.d.ts → frame-conversions-C4bnNOEY.d.ts} +1 -1
  64. package/dist/{fused-path-C0FHe67t.d.ts → fused-path-C5pp0PJU.d.ts} +1 -1
  65. package/dist/geo/h3-proximity.d.ts +1 -1
  66. package/dist/geo/index.d.ts +1 -1
  67. package/dist/geodesic-angle-BTldfFgs.js +39 -0
  68. package/dist/{gps-anchor-C6I9NDHA.d.ts → gps-anchor-BjECcYnD.d.ts} +1 -1
  69. package/dist/{gps-ar-pose-sampler-DaHg2aPZ.d.ts → gps-ar-pose-sampler-DEGNk2CI.d.ts} +1 -1
  70. package/dist/{gps-event-coordinator-C7hwHyLA.d.ts → gps-event-coordinator-CHtIkhb7.d.ts} +21 -11
  71. package/dist/{image-capture-C2Feywet.d.ts → image-capture-Bp6Pd4Md.d.ts} +103 -3
  72. package/dist/image-capture-DVcuqMtX.js +374 -0
  73. package/dist/image-quality-BMx2ko9-.d.ts +158 -0
  74. package/dist/index-D4vrgV4b.d.ts +2 -0
  75. package/dist/index-D74JTX4I.d.ts +22 -0
  76. package/dist/{index-m_LneUSi.d.ts → index-DlsOo2IB.d.ts} +1 -1
  77. package/dist/{index-BvLo2poy.d.ts → index-cCQWuYqy.d.ts} +3 -3
  78. package/dist/index.d.ts +82 -77
  79. package/dist/index.js +15 -10
  80. package/dist/{leaflet-map-overlay-bnb2U1NQ.d.ts → leaflet-map-overlay-BOZFW5kT.d.ts} +64 -10
  81. package/dist/leaflet-map-overlay-CBWPvaX9.js +452 -0
  82. package/dist/lerp-utils-Qs8OhumS.d.ts +42 -0
  83. package/dist/map-data-D7rpMC6f.js +120 -0
  84. package/dist/{map-data-DdjPiSav.d.ts → map-data-PNfGKGWx.d.ts} +22 -2
  85. package/dist/{map-overlay-draw-CPVdAsFq.d.ts → map-overlay-draw-DiroaJed.d.ts} +1 -1
  86. package/dist/{null-storage-backend-CuSdYFsM.d.ts → null-storage-backend-B1-jlpin.d.ts} +2 -2
  87. package/dist/occlusion-mesh-b28lRJ6S.d.ts +194 -0
  88. package/dist/occupancy-grid-BV7RhB7I.d.ts +194 -0
  89. package/dist/occupancy-mesher-C2ecWhNp.d.ts +100 -0
  90. package/dist/{opfs-storage-DMtlt57S.d.ts → opfs-storage-CTkxvxN4.d.ts} +5 -0
  91. package/dist/{opfs-storage-backend-CeQAb0SD.d.ts → opfs-storage-backend-D6Z03fML.d.ts} +2 -2
  92. package/dist/{persistence-middleware-5eearhSV.d.ts → persistence-middleware-CG-t08X4.d.ts} +1 -1
  93. package/dist/{planar-pnp-cjthe7Be.d.ts → planar-pnp-D7bc_rLX.d.ts} +1 -1
  94. package/dist/{qr-debug-view-B8gTzjMm.d.ts → qr-debug-view-BJooqbiP.d.ts} +1 -1
  95. package/dist/{qr-derived-pose-DinKE600.d.ts → qr-derived-pose-BwNWn8oV.d.ts} +2 -2
  96. package/dist/{qr-detected-slice-Cpv-dg82.d.ts → qr-detected-slice-TzVb8bij.d.ts} +4 -4
  97. package/dist/{qr-detection-controller-Cd2Ih4cC.d.ts → qr-detection-controller-Bo4XfQTP.d.ts} +3 -3
  98. package/dist/{qr-frontend-DufZp2xS.d.ts → qr-frontend-BPURlh3S.d.ts} +1 -1
  99. package/dist/{qr-pose-aggregation-CFlmLm6w.d.ts → qr-pose-aggregation-CypnmjA-.d.ts} +1 -1
  100. package/dist/{qr-pose-aggregation-DXR9STHs.js → qr-pose-aggregation-DBiaLW0O.js} +1 -10
  101. package/dist/{qr-size-depth-context-onu36E9s.d.ts → qr-size-depth-context-apAOmbrZ.d.ts} +2 -2
  102. package/dist/{qr-size-measurer-D7739ZpB.d.ts → qr-size-measurer-DxiMqRUw.d.ts} +3 -3
  103. package/dist/recording-options-vASCFzc5.d.ts +667 -0
  104. package/dist/{recording-replayer-CUEK82tM.d.ts → recording-replayer-D0V9WkmY.d.ts} +2 -2
  105. package/dist/{recording-slice-B-uCgGoh.d.ts → recording-slice-DTUtSVgd.d.ts} +2 -2
  106. package/dist/{replay-engine-BSVd7Zzb.d.ts → replay-engine-xdrUgWJi.d.ts} +1 -1
  107. package/dist/{replay-scene-CPt56pps.d.ts → replay-scene-zJ8SFDjE.d.ts} +3 -3
  108. package/dist/sensors/absolute-orientation.d.ts +2 -0
  109. package/dist/sensors/absolute-orientation.js +162 -0
  110. package/dist/sensors/gps-error-handler.d.ts +1 -1
  111. package/dist/sensors/gps.d.ts +1 -1
  112. package/dist/sensors/index.d.ts +5 -4
  113. package/dist/sensors/index.js +2 -1
  114. package/dist/sensors/permission-checker.d.ts +1 -1
  115. package/dist/state/app-selectors.d.ts +1 -1
  116. package/dist/state/combined-root-state.d.ts +1 -1
  117. package/dist/state/create-slam-app-store.d.ts +1 -1
  118. package/dist/state/create-slam-app-store.js +1 -74
  119. package/dist/state/gps-ar-pose-sampler.d.ts +3 -3
  120. package/dist/state/gps-event-coordinator.d.ts +2 -2
  121. package/dist/state/gps-event-coordinator.js +27 -17
  122. package/dist/state/index.d.ts +20 -20
  123. package/dist/state/index.js +4 -4
  124. package/dist/state/persistence-middleware.d.ts +1 -1
  125. package/dist/state/persistence-middleware.js +30 -19
  126. package/dist/state/qr-detected-slice.d.ts +3 -3
  127. package/dist/state/qr-detected-slice.js +1 -1
  128. package/dist/state/recording-options.d.ts +2 -2
  129. package/dist/state/recording-options.js +286 -25
  130. package/dist/state/recording-replayer.d.ts +2 -2
  131. package/dist/state/recording-replayer.js +1 -1
  132. package/dist/state/recording-slice.d.ts +1 -1
  133. package/dist/state/replay-engine.d.ts +1 -1
  134. package/dist/state/store-subscribers.d.ts +2 -2
  135. package/dist/state/store-subscribers.js +2 -1
  136. package/dist/state/subscribe-to-selector.d.ts +1 -1
  137. package/dist/state/tracking-quality.d.ts +2 -2
  138. package/dist/state/tracking-quality.js +49 -128
  139. package/dist/state/tracking-slice.d.ts +1 -1
  140. package/dist/{state-IEw0ZsBu.js → state-BeKvn4B-.js} +1 -1
  141. package/dist/storage/file-system-utils.d.ts +1 -1
  142. package/dist/storage/index.d.ts +8 -8
  143. package/dist/storage/null-storage-backend.d.ts +1 -1
  144. package/dist/storage/opfs-storage-backend.d.ts +1 -1
  145. package/dist/storage/opfs-storage.d.ts +1 -1
  146. package/dist/storage/opfs-storage.js +25 -1
  147. package/dist/storage/storage-backend.d.ts +1 -1
  148. package/dist/storage/zip-coverage-embed.d.ts +1 -1
  149. package/dist/storage/zip-export.d.ts +1 -1
  150. package/dist/storage/zip-reader.d.ts +1 -1
  151. package/dist/{storage-backend-CTJHNdMp.d.ts → storage-backend-sEtmM4yW.d.ts} +1 -1
  152. package/dist/{store-subscribers-BZP81hjh.d.ts → store-subscribers-DScA7tdT.d.ts} +2 -2
  153. package/dist/{subscribe-to-selector-Bp3sLx8L.d.ts → subscribe-to-selector-B9ylM5Oh.d.ts} +1 -1
  154. package/dist/test-utils/browser-mocks.d.ts +1 -1
  155. package/dist/test-utils/zip-round-trip-helpers.d.ts +1 -1
  156. package/dist/{tracking-slice-DJZ9qeGg.d.ts → tracking-slice-DMkHlbny.d.ts} +1 -1
  157. package/dist/types/ar-types.d.ts +1 -1
  158. package/dist/types/geo-types.d.ts +1 -1
  159. package/dist/types/index.d.ts +2 -2
  160. package/dist/utils/concurrency.d.ts +1 -1
  161. package/dist/utils/failure-tracker.d.ts +1 -1
  162. package/dist/utils/format-file-size.d.ts +1 -1
  163. package/dist/utils/fused-path.d.ts +1 -1
  164. package/dist/utils/index.d.ts +8 -7
  165. package/dist/utils/index.js +2 -1
  166. package/dist/utils/list-formatter.d.ts +1 -1
  167. package/dist/utils/logger.d.ts +1 -1
  168. package/dist/visualization/accuracy-circles.d.ts +1 -1
  169. package/dist/visualization/accuracy-circles.js +17 -8
  170. package/dist/visualization/alignment-lerper.d.ts +1 -1
  171. package/dist/visualization/ar-world-group-alignment.d.ts +1 -1
  172. package/dist/visualization/ar-world-group-alignment.js +1 -1
  173. package/dist/visualization/camera-follower.d.ts +1 -1
  174. package/dist/visualization/css3d-renderer-manager.d.ts +1 -1
  175. package/dist/visualization/frame-conversions.d.ts +1 -1
  176. package/dist/visualization/frustum-visibility.d.ts +1 -1
  177. package/dist/visualization/gps-anchor.d.ts +1 -1
  178. package/dist/visualization/gps-compass-cubes.d.ts +1 -1
  179. package/dist/visualization/gps-event-markers.d.ts +1 -1
  180. package/dist/visualization/gps-event-markers.js +1 -1
  181. package/dist/visualization/hit-test-reticle.d.ts +1 -1
  182. package/dist/visualization/index.d.ts +20 -19
  183. package/dist/visualization/index.js +4 -3
  184. package/dist/visualization/leaflet-map-overlay.d.ts +1 -1
  185. package/dist/visualization/leaflet-map-overlay.js +1 -282
  186. package/dist/visualization/lerp-utils.d.ts +2 -2
  187. package/dist/visualization/lerp-utils.js +27 -3
  188. package/dist/visualization/map-data.d.ts +1 -1
  189. package/dist/visualization/map-data.js +1 -32
  190. package/dist/visualization/map-overlay-draw.d.ts +1 -1
  191. package/dist/visualization/map-overlay-draw.js +24 -2
  192. package/dist/visualization/map-overlay.d.ts +1 -1
  193. package/dist/visualization/occluder-mesh-driver.d.ts +130 -0
  194. package/dist/visualization/occluder-mesh-driver.js +219 -0
  195. package/dist/visualization/occlusion-mesh.d.ts +2 -0
  196. package/dist/visualization/occlusion-mesh.js +437 -0
  197. package/dist/visualization/three-dispose.d.ts +1 -1
  198. package/dist/visualization/vis-colors.d.ts +1 -1
  199. package/dist/{webxr-session-CJF9Nijp.js → webxr-session-BCP2XK7k.js} +110 -14
  200. package/dist/{webxr-session-COsOjJwn.d.ts → webxr-session-cRG2SYAQ.d.ts} +83 -10
  201. package/package.json +4 -4
  202. package/dist/index-eaI1Z1KR.d.ts +0 -2
  203. package/dist/lerp-utils-kLxMJ2Xj.d.ts +0 -20
  204. package/dist/occupancy-grid-Bvi2Gw1U.d.ts +0 -82
  205. package/dist/recording-options-D93kksJU.d.ts +0 -369
  206. /package/dist/{alignment-lerper-BUTsQ2yu.d.ts → alignment-lerper-gD70k7Fq.d.ts} +0 -0
  207. /package/dist/{ar-types-BckI1E-O.d.ts → ar-types-Cc5yvBwn.d.ts} +0 -0
  208. /package/dist/{bresenham3d-ByjcmEgM.d.ts → bresenham3d-DGc4nIb-.d.ts} +0 -0
  209. /package/dist/{camera-blit-capture-CqWe1G7s.d.ts → camera-blit-capture-BimSdyih.d.ts} +0 -0
  210. /package/dist/{camera-follower-BTb2Yp12.d.ts → camera-follower-DfBm2J5i.d.ts} +0 -0
  211. /package/dist/{capability-checker-CXqoJYtb.d.ts → capability-checker-BTTpygvZ.d.ts} +0 -0
  212. /package/dist/{capture-failure-tracker-BL5SoG2a.d.ts → capture-failure-tracker-_BVfhpxv.d.ts} +0 -0
  213. /package/dist/{chromium-camera-access-workaround-BNK189P0.d.ts → chromium-camera-access-workaround-C6yJLXz9.d.ts} +0 -0
  214. /package/dist/{concurrency-DqAlKX4j.d.ts → concurrency-DPeGBH0X.d.ts} +0 -0
  215. /package/dist/{css3d-renderer-manager-m-ab19vp.d.ts → css3d-renderer-manager-CPpVtvgs.d.ts} +0 -0
  216. /package/dist/{failure-tracker-Cnc_xWUw.d.ts → failure-tracker-CeKf5HIc.d.ts} +0 -0
  217. /package/dist/{file-system-utils-Bs7lpeVP.d.ts → file-system-utils-DueXHxo9.d.ts} +0 -0
  218. /package/dist/{format-file-size-BFUWvir1.d.ts → format-file-size-DxN-EBLc.d.ts} +0 -0
  219. /package/dist/{frame-loop-BEO9_q3k.d.ts → frame-loop-7GBMBu68.d.ts} +0 -0
  220. /package/dist/{frustum-visibility-D_RGmH98.d.ts → frustum-visibility-CokkgS_i.d.ts} +0 -0
  221. /package/dist/{geo-types-DqiBzPO9.d.ts → geo-types-DrGVu8nS.d.ts} +0 -0
  222. /package/dist/{gps-C5inWeNV.d.ts → gps-CDKDQokE.d.ts} +0 -0
  223. /package/dist/{gps-compass-cubes-BExxrWJ-.d.ts → gps-compass-cubes-1mooS3BS.d.ts} +0 -0
  224. /package/dist/{gps-error-handler-C2bS69oJ.d.ts → gps-error-handler-C34GQuTu.d.ts} +0 -0
  225. /package/dist/{gps-event-markers-Dd0G2bD0.d.ts → gps-event-markers-Di2nBzx-.d.ts} +0 -0
  226. /package/dist/{h3-proximity-B57C6rYL.d.ts → h3-proximity-D0GTHQmr.d.ts} +0 -0
  227. /package/dist/{hit-test-reticle-Dqak9hiR.d.ts → hit-test-reticle-CaQbrhbk.d.ts} +0 -0
  228. /package/dist/{list-formatter-ct8txwvR.d.ts → list-formatter-DLFDnS70.d.ts} +0 -0
  229. /package/dist/{logger-CzQrCe6C.d.ts → logger-CqTd5Kpk.d.ts} +0 -0
  230. /package/dist/{map-overlay-Dci4yvm3.d.ts → map-overlay-BCQgvIgU.d.ts} +0 -0
  231. /package/dist/{permission-checker-CtPtPQRq.d.ts → permission-checker-B-VtjnBA.d.ts} +0 -0
  232. /package/dist/{qr-pose-Bt2reSw7.d.ts → qr-pose-y3vaEd6x.d.ts} +0 -0
  233. /package/dist/{scene-node-names-CdNeQjOE.d.ts → scene-node-names-CGb-ylBd.d.ts} +0 -0
  234. /package/dist/{session-disposers-D8wnO-uW.js → session-disposers-BPrMplIC.js} +0 -0
  235. /package/dist/{three-dispose-BCZkSJp2.d.ts → three-dispose-BMOAmPhb.d.ts} +0 -0
  236. /package/dist/{vis-colors-BZsSLI4i.d.ts → vis-colors-C7HI0u9_.d.ts} +0 -0
  237. /package/dist/{webxr-nue-basis-CW1wsbm6.d.ts → webxr-nue-basis-CaCnYxuq.d.ts} +0 -0
  238. /package/dist/{xr-camera-texture-BmrP7iNZ.d.ts → xr-camera-texture-q0eIDSRg.d.ts} +0 -0
  239. /package/dist/{xr-error-handler-BEjRgZjt.d.ts → xr-error-handler-uVGDu9IX.d.ts} +0 -0
  240. /package/dist/{xr-frame-loop-K8ebdjLw.d.ts → xr-frame-loop-DX3JPpAU.d.ts} +0 -0
  241. /package/dist/{zip-coverage-embed-tFohI2J4.d.ts → zip-coverage-embed-ncVbaZAz.d.ts} +0 -0
  242. /package/dist/{zip-export-DDWXInTR.d.ts → zip-export-CtiUnAlJ.d.ts} +0 -0
  243. /package/dist/{zip-reader-Q2ue6zlC.d.ts → zip-reader-CvruaGvD.d.ts} +0 -0
@@ -0,0 +1,130 @@
1
+ import { t as GridCell } from "../bresenham3d-DGc4nIb-.js";
2
+ import { n as MeshMode } from "../occupancy-mesher-C2ecWhNp.js";
3
+ import { MeshWorkerRequest, MeshWorkerResponse } from "../ar/occlusion-mesh-worker.js";
4
+ import { Vector3 } from "gps-plus-slam-js";
5
+
6
+ //#region ../src/visualization/occluder-mesh-driver.d.ts
7
+ /** Called with the meshed geometry (typed arrays) when a job completes. */
8
+ type OnMesh = (positions: Float32Array, indices: Uint32Array) => void;
9
+ /**
10
+ * Timing/size stats for one completed mesh job — the freshness instrumentation
11
+ * for the Phase-2 gate (see the plan's §"Next step"): `durationMs` is the
12
+ * wall-clock time from posting the job (including packing already done by then)
13
+ * to receiving its geometry, i.e. the occluder's current refresh latency.
14
+ * Failed jobs report nothing (they surface via
15
+ * {@link OccluderMeshDriverOptions.onError}).
16
+ */
17
+ interface OccluderMeshStats {
18
+ /** Wall-clock ms from post to delivered geometry (inline time on the sync path). */
19
+ readonly durationMs: number;
20
+ /** Number of occupied cells the mesh was built from. */
21
+ readonly cellCount: number;
22
+ readonly mode: MeshMode;
23
+ /** True when meshed inline on the main thread (fallback), false when off-thread. */
24
+ readonly synchronous: boolean;
25
+ }
26
+ /**
27
+ * The minimal `Worker`-like surface the driver needs. A consumer adapts a real
28
+ * `Worker`: forwards `worker.onmessage` → `poster.onmessage` and
29
+ * `worker.onerror` / `worker.onmessageerror` → `poster.onerror` (so the driver
30
+ * can recover from a worker that never replies).
31
+ */
32
+ interface MeshWorkerPoster {
33
+ postMessage(message: MeshWorkerRequest, transfer: ArrayBufferLike[]): void;
34
+ onmessage: ((event: {
35
+ data: MeshWorkerResponse;
36
+ }) => void) | null;
37
+ /** Fired when the worker errors (uncaught throw or module load failure). */
38
+ onerror: ((error?: unknown) => void) | null;
39
+ }
40
+ /** Optional driver callbacks (logging + worker-teardown seams). */
41
+ interface OccluderMeshDriverOptions {
42
+ /**
43
+ * Called once when the driver gives up on the worker and switches to
44
+ * synchronous meshing (the worker errored before ever producing a mesh —
45
+ * almost always a module that failed to load). The consumer should terminate
46
+ * the now-dead worker.
47
+ */
48
+ onWorkerUnusable?: () => void;
49
+ /**
50
+ * Called with any error that aborts a job — a worker error event, or a throw
51
+ * from synchronous meshing — so the consumer can log it. Optional; if absent
52
+ * the error is swallowed (the frame is dropped, the driver stays healthy).
53
+ */
54
+ onError?: (error: unknown) => void;
55
+ /**
56
+ * Called with {@link OccluderMeshStats} each time a job completes (fires just
57
+ * before the job's geometry callback). Optional logging seam so the consumer
58
+ * can surface mesh duration + input size per refresh.
59
+ */
60
+ onMeshStats?: (stats: OccluderMeshStats) => void;
61
+ /**
62
+ * Injectable monotonic clock in ms for {@link OccluderMeshStats.durationMs}
63
+ * (tests); defaults to `performance.now()`.
64
+ */
65
+ now?: () => number;
66
+ }
67
+ declare class OccluderMeshDriver {
68
+ private readonly poster;
69
+ private readonly onWorkerUnusable?;
70
+ private readonly onError?;
71
+ private readonly onMeshStats?;
72
+ private readonly now;
73
+ private nextId;
74
+ private inFlightId;
75
+ private inFlightCallback;
76
+ /** Timing/size context of the in-flight job; cleared on completion/failure. */
77
+ private inFlightStats;
78
+ private pending;
79
+ private disposed;
80
+ /** True ⇒ mesh inline (no worker, or the worker was declared unusable). */
81
+ private syncMode;
82
+ /** Set once the worker returns a mesh — distinguishes a transient error from a load failure. */
83
+ private hasSucceeded;
84
+ /**
85
+ * @param poster a worker adapter, or `null` for synchronous main-thread meshing.
86
+ * @param options optional {@link OccluderMeshDriverOptions.onWorkerUnusable} /
87
+ * {@link OccluderMeshDriverOptions.onError} callbacks.
88
+ */
89
+ constructor(poster: MeshWorkerPoster | null, options?: OccluderMeshDriverOptions);
90
+ /** True while a mesh job is being computed (worker path only). */
91
+ get busy(): boolean;
92
+ /**
93
+ * Request a mesh of `cells` (tuple array, or a flat Int32Array snapshot —
94
+ * see `packMeshRequest`; a flat snapshot's buffer is transferred/detached,
95
+ * so pass a fresh array). If a job is already in flight, this becomes the
96
+ * (single) pending job — the newest request wins; intermediates are dropped.
97
+ * `getCellPoint` is invoked with a transient cell tuple that may be a reused
98
+ * scratch — it must not retain the tuple beyond the call (see
99
+ * `MeshOccupiedCellsOptions.getCellPoint`).
100
+ */
101
+ request(cells: readonly GridCell[] | Int32Array, cellSizeM: number, mode: MeshMode, getCellPoint: ((cell: GridCell) => Vector3 | null) | undefined, onMesh: OnMesh): void;
102
+ private post;
103
+ private handleResponse;
104
+ /**
105
+ * A worker error event. If a job is in flight, recover it (only one ever is).
106
+ * If none is — the realistic ordering for a **module-load failure**, which
107
+ * errors within a few ms of construction, before the first (throttled)
108
+ * `request` posts anything — the worker is dead: posting to it would be
109
+ * silently dropped (no second error) and wedge the in-flight slot forever. So
110
+ * a pre-first-post error on a worker that has **never** succeeded is treated as
111
+ * a load failure right here — declare it unusable and switch to synchronous
112
+ * meshing so the first `request` never touches the dead worker. A stray/late
113
+ * error on a worker that has already meshed once is transient — kept, ignored.
114
+ */
115
+ private handleWorkerError;
116
+ /**
117
+ * Clear a failed in-flight job so the driver never wedges. If the worker had
118
+ * never produced a mesh (almost always a module load failure) fall back to
119
+ * synchronous meshing — unless `workerAtFault` is false (a pack-time error in
120
+ * the caller's `getCellPoint`, which never reached the worker). Then re-post
121
+ * the pending snapshot if one is queued. We deliberately do NOT re-post the
122
+ * *failed* job: if it failed on deterministic bad data, re-posting would
123
+ * loop — the next refresh brings a fresh snapshot.
124
+ */
125
+ private failInFlight;
126
+ /** Stop delivering results (detaches the worker handlers; drops any pending). */
127
+ dispose(): void;
128
+ }
129
+ //#endregion
130
+ export { MeshWorkerPoster, OccluderMeshDriver, OccluderMeshDriverOptions, OccluderMeshStats, OnMesh };
@@ -0,0 +1,219 @@
1
+ import { packMeshRequest, runMeshRequest } from "../ar/occlusion-mesh-worker.js";
2
+ //#region ../src/visualization/occluder-mesh-driver.ts
3
+ /**
4
+ * Occluder mesh driver — main-thread orchestration for the Web Worker offload.
5
+ *
6
+ * Drives {@link packMeshRequest} / {@link runMeshRequest} (see
7
+ * `2026-07-01-occluder-worker-and-chunked-remesh-plan.md`): the occluder wiring
8
+ * calls {@link OccluderMeshDriver.request} on each refresh with the occupied-cell
9
+ * snapshot; the driver packs it, posts it to a worker, and invokes a callback
10
+ * with the meshed geometry when it returns — so the expensive mesh runs
11
+ * off-thread and never stalls the render.
12
+ *
13
+ * Policy (locked 2026-07-01):
14
+ * - **Coalesce to latest** — at most one job in flight; a request made while busy
15
+ * is remembered (newest wins) and posted when the current one returns, so work
16
+ * never queues up behind a growing grid.
17
+ * - **Synchronous fallback** — constructed with `poster = null` (no worker
18
+ * support), it meshes inline and calls back immediately (today's behaviour).
19
+ * - **Error recovery (2026-07-01 Phase 1 gap fix)** — a worker that never replies
20
+ * (an uncaught throw in `runMeshRequest`, or a module that fails to load) must
21
+ * not wedge the in-flight slot forever. On a worker error the driver clears the
22
+ * slot and re-posts the pending snapshot (or lets the next refresh post) so the
23
+ * occluder never silently freezes. If the worker errors **before ever producing
24
+ * a mesh** — almost always a load failure — the driver declares it unusable
25
+ * ({@link OccluderMeshDriverOptions.onWorkerUnusable}) and switches to
26
+ * synchronous main-thread meshing, since further posts would vanish into a dead
27
+ * worker.
28
+ *
29
+ * Framework-owned + THREE-free: a consumer supplies a {@link MeshWorkerPoster}
30
+ * adapting a real `Worker`, and applies the result (e.g. `OcclusionMesh.applyMeshData`).
31
+ */
32
+ /** Cell count of a snapshot in either representation. */
33
+ function cellCountOf(cells) {
34
+ return cells instanceof Int32Array ? cells.length / 3 : cells.length;
35
+ }
36
+ var OccluderMeshDriver = class {
37
+ poster;
38
+ onWorkerUnusable;
39
+ onError;
40
+ onMeshStats;
41
+ now;
42
+ nextId = 1;
43
+ inFlightId = null;
44
+ inFlightCallback = null;
45
+ /** Timing/size context of the in-flight job; cleared on completion/failure. */
46
+ inFlightStats = null;
47
+ pending = null;
48
+ disposed = false;
49
+ /** True ⇒ mesh inline (no worker, or the worker was declared unusable). */
50
+ syncMode;
51
+ /** Set once the worker returns a mesh — distinguishes a transient error from a load failure. */
52
+ hasSucceeded = false;
53
+ /**
54
+ * @param poster a worker adapter, or `null` for synchronous main-thread meshing.
55
+ * @param options optional {@link OccluderMeshDriverOptions.onWorkerUnusable} /
56
+ * {@link OccluderMeshDriverOptions.onError} callbacks.
57
+ */
58
+ constructor(poster, options = {}) {
59
+ this.poster = poster;
60
+ this.syncMode = poster === null;
61
+ this.onWorkerUnusable = options.onWorkerUnusable;
62
+ this.onError = options.onError;
63
+ this.onMeshStats = options.onMeshStats;
64
+ this.now = options.now ?? (() => performance.now());
65
+ if (poster) {
66
+ poster.onmessage = (event) => this.handleResponse(event.data);
67
+ poster.onerror = (error) => this.handleWorkerError(error);
68
+ }
69
+ }
70
+ /** True while a mesh job is being computed (worker path only). */
71
+ get busy() {
72
+ return this.inFlightId !== null;
73
+ }
74
+ /**
75
+ * Request a mesh of `cells` (tuple array, or a flat Int32Array snapshot —
76
+ * see `packMeshRequest`; a flat snapshot's buffer is transferred/detached,
77
+ * so pass a fresh array). If a job is already in flight, this becomes the
78
+ * (single) pending job — the newest request wins; intermediates are dropped.
79
+ * `getCellPoint` is invoked with a transient cell tuple that may be a reused
80
+ * scratch — it must not retain the tuple beyond the call (see
81
+ * `MeshOccupiedCellsOptions.getCellPoint`).
82
+ */
83
+ request(cells, cellSizeM, mode, getCellPoint, onMesh) {
84
+ if (this.disposed) return;
85
+ const job = {
86
+ cells,
87
+ cellSizeM,
88
+ mode,
89
+ getCellPoint,
90
+ onMesh
91
+ };
92
+ if (this.inFlightId !== null) {
93
+ this.pending = job;
94
+ return;
95
+ }
96
+ this.post(job);
97
+ }
98
+ post(job) {
99
+ const id = this.nextId++;
100
+ this.inFlightId = id;
101
+ this.inFlightCallback = job.onMesh;
102
+ this.inFlightStats = {
103
+ startedMs: this.now(),
104
+ cellCount: cellCountOf(job.cells),
105
+ mode: job.mode,
106
+ synchronous: this.syncMode || this.poster === null
107
+ };
108
+ let packed;
109
+ try {
110
+ packed = packMeshRequest(id, job.cells, job.cellSizeM, job.mode, job.getCellPoint);
111
+ } catch (error) {
112
+ this.failInFlight(id, error, { workerAtFault: false });
113
+ return;
114
+ }
115
+ const { request, transfer } = packed;
116
+ if (this.poster && !this.syncMode) try {
117
+ this.poster.postMessage(request, transfer);
118
+ } catch (error) {
119
+ this.failInFlight(id, error);
120
+ }
121
+ else try {
122
+ const { response } = runMeshRequest(request);
123
+ this.handleResponse(response);
124
+ } catch (error) {
125
+ if (this.inFlightId === id) this.failInFlight(id, error);
126
+ else this.onError?.(error);
127
+ }
128
+ }
129
+ handleResponse(response) {
130
+ if (this.disposed || response.id !== this.inFlightId) return;
131
+ this.hasSucceeded = true;
132
+ const callback = this.inFlightCallback;
133
+ const stats = this.inFlightStats;
134
+ try {
135
+ if (stats && this.onMeshStats) {
136
+ const { startedMs, ...rest } = stats;
137
+ this.onMeshStats({
138
+ ...rest,
139
+ durationMs: this.now() - startedMs
140
+ });
141
+ }
142
+ callback?.(response.positions, response.indices);
143
+ } finally {
144
+ this.inFlightId = null;
145
+ this.inFlightCallback = null;
146
+ this.inFlightStats = null;
147
+ if (!this.disposed && this.pending) {
148
+ const next = this.pending;
149
+ this.pending = null;
150
+ this.post(next);
151
+ }
152
+ }
153
+ }
154
+ /**
155
+ * A worker error event. If a job is in flight, recover it (only one ever is).
156
+ * If none is — the realistic ordering for a **module-load failure**, which
157
+ * errors within a few ms of construction, before the first (throttled)
158
+ * `request` posts anything — the worker is dead: posting to it would be
159
+ * silently dropped (no second error) and wedge the in-flight slot forever. So
160
+ * a pre-first-post error on a worker that has **never** succeeded is treated as
161
+ * a load failure right here — declare it unusable and switch to synchronous
162
+ * meshing so the first `request` never touches the dead worker. A stray/late
163
+ * error on a worker that has already meshed once is transient — kept, ignored.
164
+ */
165
+ handleWorkerError(error) {
166
+ if (this.disposed) return;
167
+ if (this.inFlightId !== null) {
168
+ this.failInFlight(this.inFlightId, error);
169
+ return;
170
+ }
171
+ if (!this.syncMode && !this.hasSucceeded) {
172
+ if (error !== void 0) this.onError?.(error);
173
+ this.syncMode = true;
174
+ this.onWorkerUnusable?.();
175
+ }
176
+ }
177
+ /**
178
+ * Clear a failed in-flight job so the driver never wedges. If the worker had
179
+ * never produced a mesh (almost always a module load failure) fall back to
180
+ * synchronous meshing — unless `workerAtFault` is false (a pack-time error in
181
+ * the caller's `getCellPoint`, which never reached the worker). Then re-post
182
+ * the pending snapshot if one is queued. We deliberately do NOT re-post the
183
+ * *failed* job: if it failed on deterministic bad data, re-posting would
184
+ * loop — the next refresh brings a fresh snapshot.
185
+ */
186
+ failInFlight(id, error, options = {}) {
187
+ if (this.disposed || id !== this.inFlightId) return;
188
+ try {
189
+ if (error !== void 0) this.onError?.(error);
190
+ } finally {
191
+ this.inFlightId = null;
192
+ this.inFlightCallback = null;
193
+ this.inFlightStats = null;
194
+ if ((options.workerAtFault ?? true) && !this.syncMode && !this.hasSucceeded) {
195
+ this.syncMode = true;
196
+ this.onWorkerUnusable?.();
197
+ }
198
+ if (this.pending) {
199
+ const next = this.pending;
200
+ this.pending = null;
201
+ this.post(next);
202
+ }
203
+ }
204
+ }
205
+ /** Stop delivering results (detaches the worker handlers; drops any pending). */
206
+ dispose() {
207
+ this.disposed = true;
208
+ this.pending = null;
209
+ this.inFlightCallback = null;
210
+ this.inFlightId = null;
211
+ this.inFlightStats = null;
212
+ if (this.poster) {
213
+ this.poster.onmessage = null;
214
+ this.poster.onerror = null;
215
+ }
216
+ }
217
+ };
218
+ //#endregion
219
+ export { OccluderMeshDriver };
@@ -0,0 +1,2 @@
1
+ import { a as occluderDepthFade, i as buildOccluderDepthShadeSnippet, n as OcclusionMesh, o as occluderFresnelRim, r as OcclusionMeshOptions, t as OCCLUDER_DEPTH_SHADE } from "../occlusion-mesh-b28lRJ6S.js";
2
+ export { OCCLUDER_DEPTH_SHADE, OcclusionMesh, OcclusionMeshOptions, buildOccluderDepthShadeSnippet, occluderDepthFade, occluderFresnelRim };