gps-plus-slam-app-framework 1.0.6 → 1.0.7

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 (174) hide show
  1. package/LICENSE +4 -4
  2. package/README.md +249 -108
  3. package/dist/accuracy-circles-CsxE_7x1.d.ts +43 -0
  4. package/dist/{app-selectors-CHt7DLuq.d.ts → app-selectors-BeU0_ab8.d.ts} +8 -10
  5. package/dist/ar/camera-blit-capture.d.ts +1 -1
  6. package/dist/ar/capture-failure-tracker.d.ts +1 -1
  7. package/dist/ar/chromium-camera-access-workaround.d.ts +1 -1
  8. package/dist/ar/depth-sampler.d.ts +2 -2
  9. package/dist/ar/frame-loop.d.ts +2 -0
  10. package/dist/ar/frame-loop.js +40 -0
  11. package/dist/ar/image-capture.d.ts +1 -1
  12. package/dist/ar/image-capture.js +1 -1
  13. package/dist/ar/index.d.ts +12 -12
  14. package/dist/ar/index.js +3 -3
  15. package/dist/ar/replay-scene.d.ts +1 -1
  16. package/dist/ar/scene-node-names.d.ts +1 -1
  17. package/dist/ar/webxr-session.d.ts +4 -4
  18. package/dist/ar/webxr-session.js +150 -55
  19. package/dist/ar/xr-camera-texture.d.ts +1 -1
  20. package/dist/ar/xr-error-handler.d.ts +1 -1
  21. package/dist/core/index.d.ts +2 -2
  22. package/dist/core/index.js +2 -2
  23. package/dist/create-slam-app-store-CNsZ3rcX.d.ts +371 -0
  24. package/dist/{depth-sampler-BNCtnEoP.d.ts → depth-sampler-xg8vna6c.d.ts} +1 -1
  25. package/dist/{file-system-DD5TczSO.d.ts → file-system-DTApEv_Q.d.ts} +32 -2
  26. package/dist/frame-loop-QJIxLin0.d.ts +42 -0
  27. package/dist/frustum-visibility-BHnFrSKQ.d.ts +58 -0
  28. package/dist/{fused-path-DtqCSqJh.d.ts → fused-path-CB4DwWOG.d.ts} +1 -1
  29. package/dist/geo/h3-proximity.d.ts +1 -1
  30. package/dist/geo/index.d.ts +1 -1
  31. package/dist/{geo-types-Xx-LVcnw.d.ts → geo-types-CTuF23gG.d.ts} +16 -1
  32. package/dist/{gps-GKc6_Cly.d.ts → gps-DXoQb9Kf.d.ts} +1 -1
  33. package/dist/gps-anchor-CnWY61XK.d.ts +48 -0
  34. package/dist/gps-anchor-DjC_3MoT.js +257 -0
  35. package/dist/{gps-ar-pose-sampler-D_Zso40V.d.ts → gps-ar-pose-sampler-DsM1Kb2N.d.ts} +1 -1
  36. package/dist/{gps-event-coordinator-fwvmVfku.d.ts → gps-event-coordinator-DBx9I1YX.d.ts} +3 -3
  37. package/dist/gps-event-markers-BGr-iLvi.d.ts +103 -0
  38. package/dist/{image-capture-2pKjYUS6.d.ts → image-capture-DZLxHDN9.d.ts} +1 -1
  39. package/dist/index-gzWJMVpo.d.ts +2 -0
  40. package/dist/index-pOjUCKEP.d.ts +24 -0
  41. package/dist/index.d.ts +58 -52
  42. package/dist/index.js +11 -5
  43. package/dist/{leaflet-map-overlay-CQZcnxbc.d.ts → leaflet-map-overlay-Cew7XAoO.d.ts} +22 -11
  44. package/dist/{logger-B81iwxx0.d.ts → logger-C9vugiQb.d.ts} +7 -1
  45. package/dist/map-data-sih4g64v.d.ts +49 -0
  46. package/dist/map-overlay-draw-B3R1c9Xp.d.ts +42 -0
  47. package/dist/{null-storage-backend-C0TiwwzQ.d.ts → null-storage-backend-BKOS7JpL.d.ts} +2 -2
  48. package/dist/{opfs-storage-backend-Gt3rd76D.d.ts → opfs-storage-backend-Cj_7PWoq.d.ts} +2 -2
  49. package/dist/{permission-checker-Cu3nbH1S.d.ts → permission-checker-DPJl_RU6.d.ts} +41 -1
  50. package/dist/persistence-middleware-BkHIqvaA.d.ts +55 -0
  51. package/dist/{recording-replayer-BFhFs7Mc.d.ts → recording-replayer-CmCIIZ02.d.ts} +2 -2
  52. package/dist/{recording-slice-BiktUIWF.d.ts → recording-slice-d6OtCrza.d.ts} +2 -2
  53. package/dist/{replay-engine-B88Va62x.d.ts → replay-engine-BGBRQyXs.d.ts} +1 -1
  54. package/dist/{replay-scene-DtUm6bsr.d.ts → replay-scene-DpAGcAKY.d.ts} +3 -3
  55. package/dist/sensors/gps-error-handler.d.ts +1 -1
  56. package/dist/sensors/gps.d.ts +1 -1
  57. package/dist/sensors/gps.js +2 -2
  58. package/dist/sensors/index.d.ts +3 -3
  59. package/dist/sensors/permission-checker.d.ts +2 -2
  60. package/dist/sensors/permission-checker.js +79 -1
  61. package/dist/state/app-selectors.d.ts +2 -2
  62. package/dist/state/app-selectors.js +33 -3
  63. package/dist/state/combined-root-state.d.ts +2 -0
  64. package/dist/state/combined-root-state.js +1 -0
  65. package/dist/state/create-slam-app-store.d.ts +1 -1
  66. package/dist/state/create-slam-app-store.js +27 -13
  67. package/dist/state/gps-ar-pose-sampler.d.ts +3 -3
  68. package/dist/state/gps-event-coordinator.d.ts +1 -1
  69. package/dist/state/index.d.ts +17 -16
  70. package/dist/state/index.js +6 -4
  71. package/dist/state/persistence-middleware.d.ts +2 -2
  72. package/dist/state/persistence-middleware.js +35 -7
  73. package/dist/state/recording-options.d.ts +1 -1
  74. package/dist/state/recording-replayer.d.ts +2 -2
  75. package/dist/state/recording-slice.d.ts +1 -1
  76. package/dist/state/replay-engine.d.ts +1 -1
  77. package/dist/state/store-subscribers.d.ts +2 -2
  78. package/dist/state/store-subscribers.js +38 -12
  79. package/dist/state/subscribe-to-selector.d.ts +1 -1
  80. package/dist/state/tracking-quality.d.ts +2 -0
  81. package/dist/state/tracking-quality.js +723 -0
  82. package/dist/state/tracking-slice.d.ts +2 -0
  83. package/dist/state/tracking-slice.js +147 -0
  84. package/dist/storage/file-system-utils.d.ts +1 -1
  85. package/dist/storage/file-system.d.ts +2 -2
  86. package/dist/storage/file-system.js +52 -1
  87. package/dist/storage/index.d.ts +8 -8
  88. package/dist/storage/null-storage-backend.d.ts +1 -1
  89. package/dist/storage/opfs-storage-backend.d.ts +1 -1
  90. package/dist/storage/opfs-storage.d.ts +1 -1
  91. package/dist/storage/storage-backend.d.ts +1 -1
  92. package/dist/storage/zip-export.d.ts +1 -1
  93. package/dist/storage/zip-reader.d.ts +1 -1
  94. package/dist/storage/zip-reader.js +8 -4
  95. package/dist/{storage-backend-yVnuWGTr.d.ts → storage-backend-CT0Il_AB.d.ts} +1 -1
  96. package/dist/{store-subscribers-DKKHld49.d.ts → store-subscribers-Dce_CoJF.d.ts} +31 -6
  97. package/dist/{subscribe-to-selector-ghDKYtap.d.ts → subscribe-to-selector-DIHm3BRZ.d.ts} +1 -1
  98. package/dist/test-utils/browser-mocks.d.ts +1 -1
  99. package/dist/test-utils/zip-round-trip-helpers.d.ts +7 -1
  100. package/dist/test-utils/zip-round-trip-helpers.js +2 -1
  101. package/dist/tracking-slice-utCNND8t.d.ts +86 -0
  102. package/dist/types/ar-types.d.ts +1 -1
  103. package/dist/types/geo-types.d.ts +2 -2
  104. package/dist/types/index.d.ts +3 -3
  105. package/dist/utils/concurrency.d.ts +1 -1
  106. package/dist/utils/failure-tracker.d.ts +1 -1
  107. package/dist/utils/format-file-size.d.ts +1 -1
  108. package/dist/utils/fused-path.d.ts +1 -1
  109. package/dist/utils/index.d.ts +6 -6
  110. package/dist/utils/list-formatter.d.ts +1 -1
  111. package/dist/utils/logger.d.ts +1 -1
  112. package/dist/utils/logger.js +68 -8
  113. package/dist/visualization/accuracy-circles.d.ts +2 -0
  114. package/dist/visualization/accuracy-circles.js +57 -0
  115. package/dist/visualization/alignment-lerper.d.ts +1 -1
  116. package/dist/visualization/camera-follower.d.ts +1 -1
  117. package/dist/visualization/css3d-renderer-manager.d.ts +1 -1
  118. package/dist/visualization/frustum-visibility.d.ts +2 -0
  119. package/dist/visualization/frustum-visibility.js +139 -0
  120. package/dist/visualization/gps-anchor.d.ts +2 -0
  121. package/dist/visualization/gps-anchor.js +2 -0
  122. package/dist/visualization/gps-compass-cubes.d.ts +1 -1
  123. package/dist/visualization/gps-event-markers.d.ts +2 -2
  124. package/dist/visualization/gps-event-markers.js +69 -2
  125. package/dist/visualization/index.d.ts +17 -12
  126. package/dist/visualization/index.js +6 -2
  127. package/dist/visualization/leaflet-map-overlay.d.ts +1 -1
  128. package/dist/visualization/leaflet-map-overlay.js +33 -79
  129. package/dist/visualization/lerp-utils.d.ts +1 -1
  130. package/dist/visualization/map-data.d.ts +2 -0
  131. package/dist/visualization/map-data.js +33 -0
  132. package/dist/visualization/map-overlay-draw.d.ts +2 -0
  133. package/dist/visualization/map-overlay-draw.js +107 -0
  134. package/dist/visualization/map-overlay.d.ts +1 -1
  135. package/dist/visualization/three-dispose.d.ts +1 -1
  136. package/dist/visualization/vis-colors.d.ts +1 -1
  137. package/dist/{webxr-session-COlSrXdL.d.ts → webxr-session-DB5cIZnN.d.ts} +53 -12
  138. package/dist/{zip-reader-KgJEXbca.d.ts → zip-reader-D1105idz.d.ts} +5 -0
  139. package/package.json +16 -16
  140. package/dist/ar/tracking-state.d.ts +0 -2
  141. package/dist/ar/tracking-state.js +0 -164
  142. package/dist/combined-root-state-B3SvPNjU.d.ts +0 -6
  143. package/dist/create-slam-app-store-DBm7g2Zd.d.ts +0 -85
  144. package/dist/gps-anchored-mesh-manager-CovAFK4g.d.ts +0 -56
  145. package/dist/gps-event-markers-sVyO9utS.d.ts +0 -67
  146. package/dist/persistence-middleware-z-75iisb.d.ts +0 -31
  147. package/dist/tracking-state-B9QfuZCg.d.ts +0 -101
  148. package/dist/visualization/gps-anchored-mesh-manager.d.ts +0 -2
  149. package/dist/visualization/gps-anchored-mesh-manager.js +0 -128
  150. /package/dist/{alignment-lerper-D9BeDwZX.d.ts → alignment-lerper-L1RbWHQ4.d.ts} +0 -0
  151. /package/dist/{ar-types-B-ORgk6Z.d.ts → ar-types-Ck8LEq8k.d.ts} +0 -0
  152. /package/dist/{camera-blit-capture-DHuyrrxr.d.ts → camera-blit-capture-C1V9I1Z6.d.ts} +0 -0
  153. /package/dist/{camera-follower-BMqPddxx.d.ts → camera-follower-1k8mnw5J.d.ts} +0 -0
  154. /package/dist/{capture-failure-tracker-2Q6oI2uQ.d.ts → capture-failure-tracker-JKb1ST8E.d.ts} +0 -0
  155. /package/dist/{chromium-camera-access-workaround-CU5zSKNr.d.ts → chromium-camera-access-workaround-NvChXsi8.d.ts} +0 -0
  156. /package/dist/{concurrency-p6gB30fT.d.ts → concurrency-CMw8pSaG.d.ts} +0 -0
  157. /package/dist/{css3d-renderer-manager-rgLMVAvd.d.ts → css3d-renderer-manager-CkjCb2HW.d.ts} +0 -0
  158. /package/dist/{failure-tracker-1sQ_Cgyw.d.ts → failure-tracker-DnHXOIRa.d.ts} +0 -0
  159. /package/dist/{file-system-utils-BH8FdyIu.d.ts → file-system-utils-CtKiiw27.d.ts} +0 -0
  160. /package/dist/{format-file-size-onGq0k1Q.d.ts → format-file-size-BTS5H62-.d.ts} +0 -0
  161. /package/dist/{gps-compass-cubes-jRIJMOuh.d.ts → gps-compass-cubes-CsLtFv4B.d.ts} +0 -0
  162. /package/dist/{gps-error-handler-CH1S528z.d.ts → gps-error-handler-Dg3ziRVY.d.ts} +0 -0
  163. /package/dist/{h3-proximity-GwesPTFT.d.ts → h3-proximity-BhfgNbdW.d.ts} +0 -0
  164. /package/dist/{lerp-utils-CZgQlrmu.d.ts → lerp-utils-B8MM8zCR.d.ts} +0 -0
  165. /package/dist/{list-formatter-DKQQVLcl.d.ts → list-formatter-CNqi-E2j.d.ts} +0 -0
  166. /package/dist/{map-overlay-C9ifl_4-.d.ts → map-overlay-DAmreyA3.d.ts} +0 -0
  167. /package/dist/{opfs-storage-Dlq1I_Gb.d.ts → opfs-storage-DOPkzgeT.d.ts} +0 -0
  168. /package/dist/{recording-options-BYUFX8iU.d.ts → recording-options-Dq6IsKAv.d.ts} +0 -0
  169. /package/dist/{scene-node-names-DPsaE2z3.d.ts → scene-node-names-6LBjPmwz.d.ts} +0 -0
  170. /package/dist/{three-dispose-qt_r5wR1.d.ts → three-dispose-C2drkp6f.d.ts} +0 -0
  171. /package/dist/{vis-colors-BKkdTIKb.d.ts → vis-colors-CHQhjal3.d.ts} +0 -0
  172. /package/dist/{xr-camera-texture-BbukNE79.d.ts → xr-camera-texture-BU5YvKAM.d.ts} +0 -0
  173. /package/dist/{xr-error-handler-DTHfmvrl.d.ts → xr-error-handler-CDY5QxGb.d.ts} +0 -0
  174. /package/dist/{zip-export-BjrQPv0X.d.ts → zip-export-QO4iLIi7.d.ts} +0 -0
@@ -0,0 +1,40 @@
1
+ //#region ../src/ar/frame-loop.ts
2
+ const updates = /* @__PURE__ */ new Set();
3
+ /**
4
+ * Register a per-frame callback. Returns an unregister function.
5
+ *
6
+ * Registration is idempotent — calling with the same `fn` twice is a no-op
7
+ * (it remains a single entry in the underlying `Set`).
8
+ */
9
+ function registerFrameUpdate(fn) {
10
+ updates.add(fn);
11
+ return () => {
12
+ updates.delete(fn);
13
+ };
14
+ }
15
+ /**
16
+ * Invoke all registered callbacks. Called by the WebXR session's
17
+ * `onXRFrame` once per frame with the XR-derived `dt` (seconds since the
18
+ * previous frame; 0 on the first frame after a reset) and `elapsed`
19
+ * (seconds since the session started).
20
+ *
21
+ * The set is snapshotted before iterating so that
22
+ * `registerFrameUpdate` / unregister calls made by a handler during the
23
+ * same frame are deferred to the next tick. Iterating the live `Set`
24
+ * would otherwise skip a not-yet-visited entry that an earlier handler
25
+ * unregistered — a hard-to-debug source of non-determinism.
26
+ */
27
+ function runFrameUpdates(dt, elapsed) {
28
+ const snapshot = Array.from(updates);
29
+ for (const fn of snapshot) fn(dt, elapsed);
30
+ }
31
+ /**
32
+ * Clear all registrations. Called from `resetWebXRState()` so a fresh
33
+ * session starts with an empty registry (any callbacks from the previous
34
+ * session are dropped along with their owning components).
35
+ */
36
+ function clearFrameUpdates() {
37
+ updates.clear();
38
+ }
39
+ //#endregion
40
+ export { clearFrameUpdates, registerFrameUpdate, runFrameUpdates };
@@ -1,2 +1,2 @@
1
- import { a as ImageCaptureManager, i as ImageCaptureConfig, n as DEFAULT_CAPTURE_CONFIG, o as MIN_VALID_IMAGE_BYTES, r as ImageCaptureCallbacks, t as CapturedImage } from "../image-capture-2pKjYUS6.js";
1
+ import { a as ImageCaptureManager, i as ImageCaptureConfig, n as DEFAULT_CAPTURE_CONFIG, o as MIN_VALID_IMAGE_BYTES, r as ImageCaptureCallbacks, t as CapturedImage } from "../image-capture-DZLxHDN9.js";
2
2
  export { CapturedImage, DEFAULT_CAPTURE_CONFIG, ImageCaptureCallbacks, ImageCaptureConfig, ImageCaptureManager, MIN_VALID_IMAGE_BYTES };
@@ -92,7 +92,7 @@ var ImageCaptureManager = class {
92
92
  if (!pose) return;
93
93
  this.captureInProgress = true;
94
94
  this.lastCaptureTime = time;
95
- const timestamp = Date.now();
95
+ const timestamp = performance.timeOrigin + time;
96
96
  const screenRotation = this.callbacks.getScreenRotation();
97
97
  const frameIndex = ++this.frameCount;
98
98
  this.captureTimeoutId = setTimeout(() => {
@@ -1,12 +1,12 @@
1
- import { i as computeCaptureSize, n as CameraBlitCaptureConfig, r as DEFAULT_BLIT_CONFIG, t as CameraBlitCapture } from "../camera-blit-capture-DHuyrrxr.js";
2
- import { a as createCaptureFailureTracker, i as DEFAULT_CAPTURE_TRACKER_CONFIG, n as CaptureFailureTracker, r as CaptureFailureTrackerConfig, t as CAPTURE_FAILURE_WARNING } from "../capture-failure-tracker-2Q6oI2uQ.js";
3
- import { n as applyChromiumProjectionLayerWorkaround, t as ChromiumProjectionLayerWorkaroundResult } from "../chromium-camera-access-workaround-CU5zSKNr.js";
4
- import { i as DepthSamplerConfig, n as DepthSampler, r as DepthSamplerCallbacks, t as DepthInfo } from "../depth-sampler-BNCtnEoP.js";
5
- import { a as ImageCaptureManager, i as ImageCaptureConfig, n as DEFAULT_CAPTURE_CONFIG, o as MIN_VALID_IMAGE_BYTES, r as ImageCaptureCallbacks, t as CapturedImage } from "../image-capture-2pKjYUS6.js";
6
- import { a as getCameraFollower, c as getReplayState, d as updateOrbitTarget, i as getAlignmentLerper, l as initReplayScene, n as ReplaySceneState, o as getCameraMode, r as disposeReplayScene, t as CameraMode, u as toggleCameraMode } from "../replay-scene-DtUm6bsr.js";
7
- import { t as SCENE_NODE } from "../scene-node-names-DPsaE2z3.js";
8
- import { a as TrackingStateManager, i as TrackingStateCallbacks, r as TrackingState, t as DeviceOrientation } from "../tracking-state-B9QfuZCg.js";
9
- import { i as acquireCameraTexture, n as RendererLike, r as XRCameraLike, t as CameraTextureResult } from "../xr-camera-texture-BbukNE79.js";
10
- import { A as setTrackingLostCallback, D as setImageCaptureCallback, E as setFrameCallback, F as stopDepthCapture, I as stopImageCapture, N as startDepthCapture, P as startImageCapture, T as setDepthCaptureCallback, d as getDepthSampleCount, f as getImageCaptureFrameCount, g as initAR, i as endARSession, k as setTrackingCallbacks, p as getLiveCss3dManager } from "../webxr-session-COlSrXdL.js";
11
- import { n as XR_ERROR_MESSAGE_UNKNOWN, r as getXrErrorMessage, t as XR_ERROR_MESSAGES } from "../xr-error-handler-DTHfmvrl.js";
12
- export { CAPTURE_FAILURE_WARNING, CameraBlitCapture, type CameraBlitCaptureConfig, type CameraMode, type CameraTextureResult, type CaptureFailureTracker, type CaptureFailureTrackerConfig, type CapturedImage, type ChromiumProjectionLayerWorkaroundResult, DEFAULT_BLIT_CONFIG, DEFAULT_CAPTURE_CONFIG, DEFAULT_CAPTURE_TRACKER_CONFIG, type DepthInfo, DepthSampler, type DepthSamplerCallbacks, type DepthSamplerConfig, type DeviceOrientation, type ImageCaptureCallbacks, type ImageCaptureConfig, ImageCaptureManager, MIN_VALID_IMAGE_BYTES, type RendererLike, type ReplaySceneState, SCENE_NODE, TrackingState, type TrackingStateCallbacks, TrackingStateManager, type XRCameraLike, XR_ERROR_MESSAGES, XR_ERROR_MESSAGE_UNKNOWN, acquireCameraTexture, applyChromiumProjectionLayerWorkaround, computeCaptureSize, createCaptureFailureTracker, disposeReplayScene, endARSession, getAlignmentLerper, getCameraFollower, getCameraMode, getDepthSampleCount, getImageCaptureFrameCount, getLiveCss3dManager, getReplayState, getXrErrorMessage, initAR, initReplayScene, setDepthCaptureCallback, setFrameCallback, setImageCaptureCallback, setTrackingCallbacks, setTrackingLostCallback, startDepthCapture, startImageCapture, stopDepthCapture, stopImageCapture, toggleCameraMode, updateOrbitTarget };
1
+ import { i as computeCaptureSize, n as CameraBlitCaptureConfig, r as DEFAULT_BLIT_CONFIG, t as CameraBlitCapture } from "../camera-blit-capture-C1V9I1Z6.js";
2
+ import { a as createCaptureFailureTracker, i as DEFAULT_CAPTURE_TRACKER_CONFIG, n as CaptureFailureTracker, r as CaptureFailureTrackerConfig, t as CAPTURE_FAILURE_WARNING } from "../capture-failure-tracker-JKb1ST8E.js";
3
+ import { n as applyChromiumProjectionLayerWorkaround, t as ChromiumProjectionLayerWorkaroundResult } from "../chromium-camera-access-workaround-NvChXsi8.js";
4
+ import { i as DepthSamplerConfig, n as DepthSampler, r as DepthSamplerCallbacks, t as DepthInfo } from "../depth-sampler-xg8vna6c.js";
5
+ import { r as registerFrameUpdate, t as FrameUpdate } from "../frame-loop-QJIxLin0.js";
6
+ import { a as ImageCaptureManager, i as ImageCaptureConfig, n as DEFAULT_CAPTURE_CONFIG, o as MIN_VALID_IMAGE_BYTES, r as ImageCaptureCallbacks, t as CapturedImage } from "../image-capture-DZLxHDN9.js";
7
+ import { a as getCameraFollower, c as getReplayState, d as updateOrbitTarget, i as getAlignmentLerper, l as initReplayScene, n as ReplaySceneState, o as getCameraMode, r as disposeReplayScene, t as CameraMode, u as toggleCameraMode } from "../replay-scene-DpAGcAKY.js";
8
+ import { t as SCENE_NODE } from "../scene-node-names-6LBjPmwz.js";
9
+ import { i as acquireCameraTexture, n as RendererLike, r as XRCameraLike, t as CameraTextureResult } from "../xr-camera-texture-BU5YvKAM.js";
10
+ import { A as setTrackingCallbacks, D as setFrameCallback, E as setDepthCaptureCallback, F as startDepthCapture, I as startImageCapture, L as stopDepthCapture, N as setTrackingStore, O as setImageCaptureCallback, R as stopImageCapture, _ as initAR, a as endARSession, f as getDepthSampleCount, j as setTrackingLostCallback, m as getLiveCss3dManager, p as getImageCaptureFrameCount } from "../webxr-session-DB5cIZnN.js";
11
+ import { n as XR_ERROR_MESSAGE_UNKNOWN, r as getXrErrorMessage, t as XR_ERROR_MESSAGES } from "../xr-error-handler-CDY5QxGb.js";
12
+ export { CAPTURE_FAILURE_WARNING, CameraBlitCapture, type CameraBlitCaptureConfig, type CameraMode, type CameraTextureResult, type CaptureFailureTracker, type CaptureFailureTrackerConfig, type CapturedImage, type ChromiumProjectionLayerWorkaroundResult, DEFAULT_BLIT_CONFIG, DEFAULT_CAPTURE_CONFIG, DEFAULT_CAPTURE_TRACKER_CONFIG, type DepthInfo, DepthSampler, type DepthSamplerCallbacks, type DepthSamplerConfig, type FrameUpdate, type ImageCaptureCallbacks, type ImageCaptureConfig, ImageCaptureManager, MIN_VALID_IMAGE_BYTES, type RendererLike, type ReplaySceneState, SCENE_NODE, type XRCameraLike, XR_ERROR_MESSAGES, XR_ERROR_MESSAGE_UNKNOWN, acquireCameraTexture, applyChromiumProjectionLayerWorkaround, computeCaptureSize, createCaptureFailureTracker, disposeReplayScene, endARSession, getAlignmentLerper, getCameraFollower, getCameraMode, getDepthSampleCount, getImageCaptureFrameCount, getLiveCss3dManager, getReplayState, getXrErrorMessage, initAR, initReplayScene, registerFrameUpdate, setDepthCaptureCallback, setFrameCallback, setImageCaptureCallback, setTrackingCallbacks, setTrackingLostCallback, setTrackingStore, startDepthCapture, startImageCapture, stopDepthCapture, stopImageCapture, toggleCameraMode, updateOrbitTarget };
package/dist/ar/index.js CHANGED
@@ -2,11 +2,11 @@ import { CameraBlitCapture, DEFAULT_BLIT_CONFIG, computeCaptureSize } from "./ca
2
2
  import { applyChromiumProjectionLayerWorkaround } from "./chromium-camera-access-workaround.js";
3
3
  import { CAPTURE_FAILURE_WARNING, DEFAULT_CAPTURE_TRACKER_CONFIG, createCaptureFailureTracker } from "./capture-failure-tracker.js";
4
4
  import { DepthSampler } from "./depth-sampler.js";
5
+ import { registerFrameUpdate } from "./frame-loop.js";
5
6
  import { DEFAULT_CAPTURE_CONFIG, ImageCaptureManager, MIN_VALID_IMAGE_BYTES } from "./image-capture.js";
6
- import { TrackingState, TrackingStateManager } from "./tracking-state.js";
7
7
  import { acquireCameraTexture } from "./xr-camera-texture.js";
8
8
  import { SCENE_NODE } from "./scene-node-names.js";
9
- import { endARSession, getDepthSampleCount, getImageCaptureFrameCount, getLiveCss3dManager, initAR, setDepthCaptureCallback, setFrameCallback, setImageCaptureCallback, setTrackingCallbacks, setTrackingLostCallback, startDepthCapture, startImageCapture, stopDepthCapture, stopImageCapture } from "./webxr-session.js";
9
+ import { endARSession, getDepthSampleCount, getImageCaptureFrameCount, getLiveCss3dManager, initAR, setDepthCaptureCallback, setFrameCallback, setImageCaptureCallback, setTrackingCallbacks, setTrackingLostCallback, setTrackingStore, startDepthCapture, startImageCapture, stopDepthCapture, stopImageCapture } from "./webxr-session.js";
10
10
  import { disposeReplayScene, getAlignmentLerper, getCameraFollower, getCameraMode, getReplayState, initReplayScene, toggleCameraMode, updateOrbitTarget } from "./replay-scene.js";
11
11
  import { XR_ERROR_MESSAGES, XR_ERROR_MESSAGE_UNKNOWN, getXrErrorMessage } from "./xr-error-handler.js";
12
- export { CAPTURE_FAILURE_WARNING, CameraBlitCapture, DEFAULT_BLIT_CONFIG, DEFAULT_CAPTURE_CONFIG, DEFAULT_CAPTURE_TRACKER_CONFIG, DepthSampler, ImageCaptureManager, MIN_VALID_IMAGE_BYTES, SCENE_NODE, TrackingState, TrackingStateManager, XR_ERROR_MESSAGES, XR_ERROR_MESSAGE_UNKNOWN, acquireCameraTexture, applyChromiumProjectionLayerWorkaround, computeCaptureSize, createCaptureFailureTracker, disposeReplayScene, endARSession, getAlignmentLerper, getCameraFollower, getCameraMode, getDepthSampleCount, getImageCaptureFrameCount, getLiveCss3dManager, getReplayState, getXrErrorMessage, initAR, initReplayScene, setDepthCaptureCallback, setFrameCallback, setImageCaptureCallback, setTrackingCallbacks, setTrackingLostCallback, startDepthCapture, startImageCapture, stopDepthCapture, stopImageCapture, toggleCameraMode, updateOrbitTarget };
12
+ export { CAPTURE_FAILURE_WARNING, CameraBlitCapture, DEFAULT_BLIT_CONFIG, DEFAULT_CAPTURE_CONFIG, DEFAULT_CAPTURE_TRACKER_CONFIG, DepthSampler, ImageCaptureManager, MIN_VALID_IMAGE_BYTES, SCENE_NODE, XR_ERROR_MESSAGES, XR_ERROR_MESSAGE_UNKNOWN, acquireCameraTexture, applyChromiumProjectionLayerWorkaround, computeCaptureSize, createCaptureFailureTracker, disposeReplayScene, endARSession, getAlignmentLerper, getCameraFollower, getCameraMode, getDepthSampleCount, getImageCaptureFrameCount, getLiveCss3dManager, getReplayState, getXrErrorMessage, initAR, initReplayScene, registerFrameUpdate, setDepthCaptureCallback, setFrameCallback, setImageCaptureCallback, setTrackingCallbacks, setTrackingLostCallback, setTrackingStore, startDepthCapture, startImageCapture, stopDepthCapture, stopImageCapture, toggleCameraMode, updateOrbitTarget };
@@ -1,2 +1,2 @@
1
- import { a as getCameraFollower, c as getReplayState, d as updateOrbitTarget, i as getAlignmentLerper, l as initReplayScene, n as ReplaySceneState, o as getCameraMode, r as disposeReplayScene, s as getCss3dManager, t as CameraMode, u as toggleCameraMode } from "../replay-scene-DtUm6bsr.js";
1
+ import { a as getCameraFollower, c as getReplayState, d as updateOrbitTarget, i as getAlignmentLerper, l as initReplayScene, n as ReplaySceneState, o as getCameraMode, r as disposeReplayScene, s as getCss3dManager, t as CameraMode, u as toggleCameraMode } from "../replay-scene-DpAGcAKY.js";
2
2
  export { CameraMode, ReplaySceneState, disposeReplayScene, getAlignmentLerper, getCameraFollower, getCameraMode, getCss3dManager, getReplayState, initReplayScene, toggleCameraMode, updateOrbitTarget };
@@ -1,2 +1,2 @@
1
- import { t as SCENE_NODE } from "../scene-node-names-DPsaE2z3.js";
1
+ import { t as SCENE_NODE } from "../scene-node-names-6LBjPmwz.js";
2
2
  export { SCENE_NODE };
@@ -1,4 +1,4 @@
1
- import { i as DepthSample, t as ARPose } from "../ar-types-B-ORgk6Z.js";
2
- import { t as CapturedImage } from "../image-capture-2pKjYUS6.js";
3
- import { A as setTrackingLostCallback, C as setArWorldGroup, D as setImageCaptureCallback, E as setFrameCallback, F as stopDepthCapture, I as stopImageCapture, M as shouldLogCameraAccessDiagnostic, N as startDepthCapture, O as setScene, P as startImageCapture, S as setArPose, T as setDepthCaptureCallback, _ as isWebXRSupported, a as extractPoseFromViewer, b as nueQuaternionToWebXR, c as getArWorldGroup, d as getDepthSampleCount, f as getImageCaptureFrameCount, g as initAR, h as getXrCameraFromPose, i as endARSession, j as setTrackingRecoveredCallback, k as setTrackingCallbacks, l as getCamera, m as getScene, n as buildSessionOptions, o as extractResetTransformData, p as getLiveCss3dManager, r as createSceneHierarchy, s as getArPose, t as applyAlignmentMatrix, u as getCurrentArPose, v as isXRCameraLike, w as setCamera, x as resetWebXRState, y as nuePositionToWebXR } from "../webxr-session-COlSrXdL.js";
4
- export { ARPose, CapturedImage, DepthSample, applyAlignmentMatrix, buildSessionOptions, createSceneHierarchy, endARSession, extractPoseFromViewer, extractResetTransformData, getArPose, getArWorldGroup, getCamera, getCurrentArPose, getDepthSampleCount, getImageCaptureFrameCount, getLiveCss3dManager, getScene, getXrCameraFromPose, initAR, isWebXRSupported, isXRCameraLike, nuePositionToWebXR, nueQuaternionToWebXR, resetWebXRState, setArPose, setArWorldGroup, setCamera, setDepthCaptureCallback, setFrameCallback, setImageCaptureCallback, setScene, setTrackingCallbacks, setTrackingLostCallback, setTrackingRecoveredCallback, shouldLogCameraAccessDiagnostic, startDepthCapture, startImageCapture, stopDepthCapture, stopImageCapture };
1
+ import { i as DepthSample, t as ARPose } from "../ar-types-Ck8LEq8k.js";
2
+ import { t as CapturedImage } from "../image-capture-DZLxHDN9.js";
3
+ import { A as setTrackingCallbacks, C as setArPose, D as setFrameCallback, E as setDepthCaptureCallback, F as startDepthCapture, I as startImageCapture, L as stopDepthCapture, M as setTrackingRecoveredCallback, N as setTrackingStore, O as setImageCaptureCallback, P as shouldLogCameraAccessDiagnostic, R as stopImageCapture, S as resetWebXRState, T as setCamera, _ as initAR, a as endARSession, b as nuePositionToWebXR, c as getArPose, d as getCurrentArPose, f as getDepthSampleCount, g as getXrCameraFromPose, h as getScene, i as createSceneHierarchy, j as setTrackingLostCallback, k as setScene, l as getArWorldGroup, m as getLiveCss3dManager, n as applyAlignmentMatrix, o as extractPoseFromViewer, p as getImageCaptureFrameCount, r as buildSessionOptions, s as extractResetTransformData, t as TrackingSubscribableStore, u as getCamera, v as isWebXRSupported, w as setArWorldGroup, x as nueQuaternionToWebXR, y as isXRCameraLike } from "../webxr-session-DB5cIZnN.js";
4
+ export { ARPose, CapturedImage, DepthSample, TrackingSubscribableStore, applyAlignmentMatrix, buildSessionOptions, createSceneHierarchy, endARSession, extractPoseFromViewer, extractResetTransformData, getArPose, getArWorldGroup, getCamera, getCurrentArPose, getDepthSampleCount, getImageCaptureFrameCount, getLiveCss3dManager, getScene, getXrCameraFromPose, initAR, isWebXRSupported, isXRCameraLike, nuePositionToWebXR, nueQuaternionToWebXR, resetWebXRState, setArPose, setArWorldGroup, setCamera, setDepthCaptureCallback, setFrameCallback, setImageCaptureCallback, setScene, setTrackingCallbacks, setTrackingLostCallback, setTrackingRecoveredCallback, setTrackingStore, shouldLogCameraAccessDiagnostic, startDepthCapture, startImageCapture, stopDepthCapture, stopImageCapture };
@@ -2,8 +2,9 @@ import { createLogger } from "../utils/logger.js";
2
2
  import { CameraBlitCapture, computeCaptureSize } from "./camera-blit-capture.js";
3
3
  import { getLastDeviceOrientation } from "../state/gps-event-coordinator.js";
4
4
  import { DepthSampler } from "./depth-sampler.js";
5
+ import { clearFrameUpdates, runFrameUpdates } from "./frame-loop.js";
5
6
  import { DEFAULT_CAPTURE_CONFIG, ImageCaptureManager } from "./image-capture.js";
6
- import { TrackingStateManager } from "./tracking-state.js";
7
+ import { clearLastRestartedPayload, originReset, poseLost, poseReceived, resetTracking, selectLastRestartedPayload, selectTrackingPhase } from "../state/tracking-slice.js";
7
8
  import { acquireCameraTexture } from "./xr-camera-texture.js";
8
9
  import { DEFAULT_RECORDING_OPTIONS, validateArCrashIsolationOptions } from "../state/recording-options.js";
9
10
  import { SCENE_NODE } from "./scene-node-names.js";
@@ -84,6 +85,13 @@ let scene = null;
84
85
  let camera = null;
85
86
  let xrSession = null;
86
87
  /**
88
+ * Monotonic time of the previous XR frame, in milliseconds (XR `time`
89
+ * argument). Reset to 0 by `resetWebXRState()` so the first frame of a
90
+ * new session sees `dt = 0` rather than a stale delta from the prior
91
+ * session.
92
+ */
93
+ let lastFrameTime = 0;
94
+ /**
87
95
  * Reset WebXR module state - exported for testing only.
88
96
  * @internal
89
97
  */
@@ -100,12 +108,18 @@ function resetWebXRState() {
100
108
  arWorldGroup = null;
101
109
  arPoseNode = null;
102
110
  latestArPose = null;
111
+ lastFrameTime = 0;
112
+ clearFrameUpdates();
103
113
  imageCaptureManager = null;
104
114
  onImageCaptured = null;
105
115
  getScreenRotation = null;
106
116
  onCaptureFailed = null;
107
117
  onSuspiciousImage = null;
108
- trackingStateManager = null;
118
+ if (trackingPhaseUnsubscribe) {
119
+ trackingPhaseUnsubscribe();
120
+ trackingPhaseUnsubscribe = null;
121
+ }
122
+ trackingStore = null;
109
123
  onTrackingRestarted = null;
110
124
  onTrackingLost = null;
111
125
  onTrackingRecovered = null;
@@ -163,9 +177,22 @@ let onSuspiciousImage = null;
163
177
  */
164
178
  let getScreenRotation = null;
165
179
  /**
166
- * Tracking state manager (created when AR session starts with tracking callbacks)
180
+ * Redux store injected by the host (`setTrackingStore`). When present
181
+ * together with `onTrackingRestarted`, `onXRFrame` dispatches
182
+ * `poseReceived`/`poseLost`, the XR reference-space reset listener
183
+ * dispatches `originReset`, and a `subscribeToSelector` translation
184
+ * surface translates phase transitions back into the existing
185
+ * `onTrackingLost` / `onTrackingRestarted` / `onTrackingRecovered`
186
+ * callbacks. When the store is absent the tracking pipeline simply
187
+ * no-ops.
167
188
  */
168
- let trackingStateManager = null;
189
+ let trackingStore = null;
190
+ /**
191
+ * Unsubscribe handle returned by the phase subscription set up in
192
+ * `initAR`. Cleared in `resetWebXRState` and on session-end so we never
193
+ * leave dangling listeners on a stale store.
194
+ */
195
+ let trackingPhaseUnsubscribe = null;
169
196
  /**
170
197
  * Callback for when tracking restarts (set via setTrackingCallbacks)
171
198
  */
@@ -373,8 +400,18 @@ async function isWebXRSupported() {
373
400
  * basisChangeNode is a static scene-graph node that holds the WEBXR_TO_NUE
374
401
  * basis-change matrix permanently (matrixAutoUpdate=false). Moving it here
375
402
  * instead of composing it in applyAlignmentMatrix() keeps arWorldGroup's
376
- * local space as NUE: objects added directly to arWorldGroup can be placed
377
- * at [1,0,0]=North, [0,0,1]=East without any WebXR↔NUE conversion.
403
+ * local space in the **NUE axis convention** (X=North, Y=Up, Z=East), so no
404
+ * WebXR↔NUE swizzle is needed for children.
405
+ *
406
+ * CAUTION — two NUE frames: arWorldGroup's local space is the *AR-odometry*
407
+ * NUE frame, i.e. the **domain** of the alignment matrix, NOT the GPS-world
408
+ * NUE frame of the scene root. Only content authored in AR-odometry
409
+ * coordinates (e.g. the camera subtree) may be placed with raw local values.
410
+ * GPS-world content (a lat/lon → NUE point) is expressed in the scene-root
411
+ * frame and must be pre-multiplied by alignment⁻¹ before being used as a
412
+ * local position under arWorldGroup — see createGpsAnchor and the
413
+ * alignment-frame bug doc
414
+ * (GpsPlusSlamJs_Docs/docs/2026-05-31-gps-anchor-alignment-frame-bug.md).
378
415
  *
379
416
  * - Recording: arpose stays at identity; WebXRManager writes to camera.
380
417
  * - Replay: arpose receives recorded odomPosition/odomRotation;
@@ -415,6 +452,7 @@ function createSceneHierarchy() {
415
452
  */
416
453
  async function initAR(container, isolationOptions = {}) {
417
454
  if (!navigator.xr) throw new Error("WebXR not available");
455
+ if (renderer || xrSession) throw new Error("AR session already initialized — call endARSession() before initAR() again");
418
456
  currentArCrashIsolationOptions = validateArCrashIsolationOptions(isolationOptions);
419
457
  renderer = new THREE.WebGLRenderer({
420
458
  antialias: true,
@@ -434,40 +472,19 @@ async function initAR(container, isolationOptions = {}) {
434
472
  xrSession = await navigator.xr.requestSession("immersive-ar", sessionOptions);
435
473
  xrSession.addEventListener("end", () => {
436
474
  log.info("Session ended");
437
- if (trackingStateManager) trackingStateManager.reset();
475
+ if (trackingStore) trackingStore.dispatch(resetTracking());
438
476
  xrSession = null;
439
477
  latestArPose = null;
440
478
  });
441
479
  await renderer.xr.setSession(xrSession);
442
- if (onTrackingRestarted) {
443
- trackingStateManager = new TrackingStateManager({
444
- onTrackingLost: () => {
445
- log.warn("Tracking lost");
446
- latestArPose = null;
447
- onTrackingLost?.();
448
- },
449
- onTrackingRestarted: (payload) => {
450
- log.info("Tracking restarted (origin reset)");
451
- onTrackingRestarted?.(payload);
452
- },
453
- onTrackingRecovered: () => {
454
- log.info("Tracking recovered (same coordinate frame)");
455
- onTrackingRecovered?.();
456
- },
457
- getDeviceOrientation: () => {
458
- const orientation = getLastDeviceOrientation();
459
- return {
460
- alpha: orientation?.alpha ?? 0,
461
- beta: orientation?.beta ?? 0,
462
- gamma: orientation?.gamma ?? 0,
463
- absolute: orientation?.absolute ?? false
464
- };
465
- }
466
- });
480
+ if (onTrackingRestarted && trackingStore) {
481
+ const store = trackingStore;
482
+ store.dispatch(resetTracking());
483
+ trackingPhaseUnsubscribe = subscribeToTrackingPhase(store);
467
484
  const referenceSpace = renderer.xr.getReferenceSpace();
468
485
  if (referenceSpace) referenceSpace.addEventListener("reset", (event) => {
469
486
  const transformData = extractResetTransformData(event);
470
- trackingStateManager?.markOriginReset(transformData);
487
+ store.dispatch(originReset(transformData));
471
488
  log.warn("XR reference space reset detected", transformData ? "(transform available)" : "(no transform)");
472
489
  });
473
490
  }
@@ -480,12 +497,72 @@ async function initAR(container, isolationOptions = {}) {
480
497
  log.info("AR session started");
481
498
  }
482
499
  /**
483
- * Update tracking state manager with current pose state.
500
+ * Snapshot the current `DeviceOrientation` (with documented fallback
501
+ * defaults) for inclusion in `poseReceived` payloads.
502
+ */
503
+ function snapshotDeviceOrientation() {
504
+ const orientation = getLastDeviceOrientation();
505
+ return {
506
+ alpha: orientation?.alpha ?? 0,
507
+ beta: orientation?.beta ?? 0,
508
+ gamma: orientation?.gamma ?? 0,
509
+ absolute: orientation?.absolute ?? false
510
+ };
511
+ }
512
+ /**
513
+ * Wire the tracking-slice → host-callbacks translation. The subscriber
514
+ * runs synchronously inside each `dispatch`, so the host callbacks fire
515
+ * in the same order as a direct invocation would.
516
+ *
517
+ * Translation rules (locked in by tracking-slice tests):
518
+ * - `tracking → lost`: clear `latestArPose` (drops in-flight GPS events)
519
+ * and call `onTrackingLost?.()`.
520
+ * - `lost → tracking` with `lastRestartedPayload !== null` (Case 2):
521
+ * call `onTrackingRestarted?.(payload)` then dispatch
522
+ * `clearLastRestartedPayload` so a subsequent loss cycle starts clean.
523
+ * - `lost → tracking` with payload null (Case 1: seamless recovery):
524
+ * call `onTrackingRecovered?.()`.
525
+ * - `initializing → tracking`: no callback (initial acquisition is not
526
+ * a restart — same behaviour as the manager).
527
+ */
528
+ function subscribeToTrackingPhase(store) {
529
+ let prev = "initializing";
530
+ return store.subscribe(() => {
531
+ const next = selectTrackingPhase(store.getState());
532
+ if (next === prev) return;
533
+ const previous = prev;
534
+ prev = next;
535
+ if (previous === "tracking" && next === "lost") {
536
+ log.warn("Tracking lost");
537
+ latestArPose = null;
538
+ onTrackingLost?.();
539
+ return;
540
+ }
541
+ if (previous === "lost" && next === "tracking") {
542
+ const payload = selectLastRestartedPayload(store.getState());
543
+ if (payload !== null) {
544
+ log.info("Tracking restarted (origin reset)");
545
+ onTrackingRestarted?.(payload);
546
+ store.dispatch(clearLastRestartedPayload());
547
+ } else {
548
+ log.info("Tracking recovered (same coordinate frame)");
549
+ onTrackingRecovered?.();
550
+ }
551
+ }
552
+ });
553
+ }
554
+ /**
555
+ * Dispatch the per-frame `poseReceived` / `poseLost` action into the
556
+ * tracking slice. No-op when no store is bound or when tracking wiring
557
+ * was not requested.
484
558
  */
485
559
  function updateTrackingState(arPose) {
486
- if (!trackingStateManager) return;
487
- if (arPose) trackingStateManager.onPoseReceived(arPose);
488
- else trackingStateManager.onPoseLost();
560
+ if (!trackingStore || !onTrackingRestarted) return;
561
+ if (arPose) trackingStore.dispatch(poseReceived({
562
+ pose: arPose,
563
+ sensorOrientation: snapshotDeviceOrientation()
564
+ }));
565
+ else trackingStore.dispatch(poseLost());
489
566
  }
490
567
  /**
491
568
  * Called each XR frame
@@ -497,6 +574,10 @@ function onXRFrame(time, frame) {
497
574
  const pose = frame.getViewerPose(referenceSpace);
498
575
  const arPose = extractPoseFromViewer(pose);
499
576
  updateTrackingState(arPose);
577
+ const dt = lastFrameTime === 0 ? 0 : (time - lastFrameTime) / 1e3;
578
+ const elapsed = time / 1e3;
579
+ lastFrameTime = time;
580
+ runFrameUpdates(dt, elapsed);
500
581
  if (arPose) latestArPose = arPose;
501
582
  latestCameraTexture = null;
502
583
  if (currentArCrashIsolationOptions.enableCameraTextureAcquisition) {
@@ -703,27 +784,20 @@ function nueQuaternionToWebXR(nue) {
703
784
  /**
704
785
  * End the current XR session and clean up all resources.
705
786
  *
706
- * Stops the animation loop, disposes the WebGL renderer, removes the
707
- * canvas from the DOM, and tears down the CSS3D overlay. This is the
708
- * production cleanup path call it when the AR experience is finished.
787
+ * Stops the animation loop, ends the XR session, then delegates the full
788
+ * teardown to {@link resetWebXRState} so every module-level reference is
789
+ * cleared (renderer/scene/camera, image-capture, depth, the tracking-phase
790
+ * subscription, the frame-update registry, diagnostics, blit resources).
791
+ * This is the production cleanup path — call it when the AR experience is
792
+ * finished.
709
793
  */
710
794
  async function endARSession() {
711
795
  if (renderer) renderer.setAnimationLoop(null);
712
- if (xrSession) {
713
- await xrSession.end();
714
- xrSession = null;
715
- }
716
- latestArPose = null;
717
- if (css3dManager) {
718
- css3dManager.dispose();
719
- css3dManager = null;
720
- }
721
- if (renderer) {
722
- if (renderer.domElement.parentElement) renderer.domElement.parentElement.removeChild(renderer.domElement);
723
- renderer.dispose();
724
- renderer = null;
796
+ try {
797
+ if (xrSession) await xrSession.end();
798
+ } finally {
799
+ resetWebXRState();
725
800
  }
726
- cleanupBlitResources();
727
801
  }
728
802
  /**
729
803
  * Set up image capture callbacks.
@@ -755,6 +829,10 @@ function startImageCapture(config, resolutionDivisor = 1) {
755
829
  log.warn("Cannot start image capture - callbacks not set");
756
830
  return;
757
831
  }
832
+ if (imageCaptureManager || blitCapture) {
833
+ log.warn("Image capture already running - stopping previous session");
834
+ stopImageCapture();
835
+ }
758
836
  const callbacks = {
759
837
  getCurrentPose: getCurrentArPose,
760
838
  getScreenRotation,
@@ -802,6 +880,23 @@ function getImageCaptureFrameCount() {
802
880
  return imageCaptureManager?.getFrameCount() ?? 0;
803
881
  }
804
882
  /**
883
+ * Inject the Redux store used by the tracking-state slice pipeline.
884
+ *
885
+ * MUST be called before `initAR()` whenever the host also wires tracking
886
+ * callbacks via `setTrackingCallbacks`. Without a store the tracking
887
+ * pipeline silently no-ops.
888
+ *
889
+ * @param store — any store satisfying {@link TrackingSubscribableStore}.
890
+ * `null` clears the binding (useful for teardown in tests).
891
+ */
892
+ function setTrackingStore(store) {
893
+ if (trackingPhaseUnsubscribe) {
894
+ trackingPhaseUnsubscribe();
895
+ trackingPhaseUnsubscribe = null;
896
+ }
897
+ trackingStore = store;
898
+ }
899
+ /**
805
900
  * Set up tracking state callbacks.
806
901
  * Call this BEFORE initAR() to enable tracking restart detection.
807
902
  *
@@ -887,4 +982,4 @@ function getLiveCss3dManager() {
887
982
  return css3dManager;
888
983
  }
889
984
  //#endregion
890
- export { applyAlignmentMatrix, buildSessionOptions, createSceneHierarchy, endARSession, extractPoseFromViewer, extractResetTransformData, getArPose, getArWorldGroup, getCamera, getCurrentArPose, getDepthSampleCount, getImageCaptureFrameCount, getLiveCss3dManager, getScene, getXrCameraFromPose, initAR, isWebXRSupported, isXRCameraLike, nuePositionToWebXR, nueQuaternionToWebXR, resetWebXRState, setArPose, setArWorldGroup, setCamera, setDepthCaptureCallback, setFrameCallback, setImageCaptureCallback, setScene, setTrackingCallbacks, setTrackingLostCallback, setTrackingRecoveredCallback, shouldLogCameraAccessDiagnostic, startDepthCapture, startImageCapture, stopDepthCapture, stopImageCapture };
985
+ export { applyAlignmentMatrix, buildSessionOptions, createSceneHierarchy, endARSession, extractPoseFromViewer, extractResetTransformData, getArPose, getArWorldGroup, getCamera, getCurrentArPose, getDepthSampleCount, getImageCaptureFrameCount, getLiveCss3dManager, getScene, getXrCameraFromPose, initAR, isWebXRSupported, isXRCameraLike, nuePositionToWebXR, nueQuaternionToWebXR, resetWebXRState, setArPose, setArWorldGroup, setCamera, setDepthCaptureCallback, setFrameCallback, setImageCaptureCallback, setScene, setTrackingCallbacks, setTrackingLostCallback, setTrackingRecoveredCallback, setTrackingStore, shouldLogCameraAccessDiagnostic, startDepthCapture, startImageCapture, stopDepthCapture, stopImageCapture };
@@ -1,2 +1,2 @@
1
- import { i as acquireCameraTexture, n as RendererLike, r as XRCameraLike, t as CameraTextureResult } from "../xr-camera-texture-BbukNE79.js";
1
+ import { i as acquireCameraTexture, n as RendererLike, r as XRCameraLike, t as CameraTextureResult } from "../xr-camera-texture-BU5YvKAM.js";
2
2
  export { CameraTextureResult, RendererLike, XRCameraLike, acquireCameraTexture };
@@ -1,2 +1,2 @@
1
- import { n as XR_ERROR_MESSAGE_UNKNOWN, r as getXrErrorMessage, t as XR_ERROR_MESSAGES } from "../xr-error-handler-DTHfmvrl.js";
1
+ import { n as XR_ERROR_MESSAGE_UNKNOWN, r as getXrErrorMessage, t as XR_ERROR_MESSAGES } from "../xr-error-handler-CDY5QxGb.js";
2
2
  export { XR_ERROR_MESSAGES, XR_ERROR_MESSAGE_UNKNOWN, getXrErrorMessage };
@@ -1,2 +1,2 @@
1
- import { GpsPoint, LatLong, LatLongAlt, Matrix4, Quaternion, RootState, RootState as LibraryRootState, Vector3, calcGpsCoords, createGpsSlamStore, isIdentityMatrix4, odometryTrackingRestarted, validateLicenseKey, webxrToNUE } from "gps-plus-slam-js";
2
- export { type GpsPoint, type LatLong, type LatLongAlt, type LibraryRootState, type Matrix4, type Quaternion, type RootState, type Vector3, calcGpsCoords, createGpsSlamStore, isIdentityMatrix4, odometryTrackingRestarted, validateLicenseKey, webxrToNUE };
1
+ import { a as LibraryRootState, c as RootState, d as calcRelativeCoordsInMeters, f as createGpsSlamStore, g as webxrToNUE, h as validateLicenseKey, i as LatLongAlt, l as Vector3, m as odometryTrackingRestarted, n as GpsPoint, o as Matrix4, p as isIdentityMatrix4, r as LatLong, s as Quaternion, t as ArImageCapture, u as calcGpsCoords } from "../index-gzWJMVpo.js";
2
+ export { ArImageCapture, GpsPoint, LatLong, LatLongAlt, LibraryRootState, Matrix4, Quaternion, RootState, Vector3, calcGpsCoords, calcRelativeCoordsInMeters, createGpsSlamStore, isIdentityMatrix4, odometryTrackingRestarted, validateLicenseKey, webxrToNUE };
@@ -1,2 +1,2 @@
1
- import { calcGpsCoords, createGpsSlamStore, isIdentityMatrix4, odometryTrackingRestarted, validateLicenseKey, webxrToNUE } from "gps-plus-slam-js";
2
- export { calcGpsCoords, createGpsSlamStore, isIdentityMatrix4, odometryTrackingRestarted, validateLicenseKey, webxrToNUE };
1
+ import { calcGpsCoords, calcRelativeCoordsInMeters, createGpsSlamStore, isIdentityMatrix4, odometryTrackingRestarted, validateLicenseKey, webxrToNUE } from "gps-plus-slam-js";
2
+ export { calcGpsCoords, calcRelativeCoordsInMeters, createGpsSlamStore, isIdentityMatrix4, odometryTrackingRestarted, validateLicenseKey, webxrToNUE };