gps-plus-slam-app-framework 1.0.6 → 1.1.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 (198) hide show
  1. package/LICENSE +4 -4
  2. package/README.md +310 -115
  3. package/dist/accuracy-circles-DEKr0Hoh.d.ts +43 -0
  4. package/dist/{app-selectors-CHt7DLuq.d.ts → app-selectors-CR9OWodf.d.ts} +8 -10
  5. package/dist/ar/camera-blit-capture.d.ts +1 -1
  6. package/dist/ar/capability-checker.d.ts +2 -0
  7. package/dist/ar/capability-checker.js +25 -0
  8. package/dist/ar/capture-failure-tracker.d.ts +1 -1
  9. package/dist/ar/chromium-camera-access-workaround.d.ts +2 -2
  10. package/dist/ar/chromium-camera-access-workaround.js +197 -8
  11. package/dist/ar/depth-sampler.d.ts +2 -2
  12. package/dist/ar/enable-gps-ar.d.ts +2 -0
  13. package/dist/ar/enable-gps-ar.js +137 -0
  14. package/dist/ar/frame-loop.d.ts +2 -0
  15. package/dist/ar/frame-loop.js +63 -0
  16. package/dist/ar/image-capture.d.ts +1 -1
  17. package/dist/ar/image-capture.js +1 -1
  18. package/dist/ar/index.d.ts +16 -12
  19. package/dist/ar/index.js +8 -4
  20. package/dist/ar/replay-scene.d.ts +1 -1
  21. package/dist/ar/scene-node-names.d.ts +1 -1
  22. package/dist/ar/webxr-session.d.ts +4 -4
  23. package/dist/ar/webxr-session.js +173 -93
  24. package/dist/ar/xr-camera-texture.d.ts +1 -1
  25. package/dist/ar/xr-error-handler.d.ts +1 -1
  26. package/dist/ar/xr-frame-loop.d.ts +2 -0
  27. package/dist/ar/xr-frame-loop.js +69 -0
  28. package/dist/ar-world-group-alignment-Dn4rQk_c.d.ts +43 -0
  29. package/dist/capability-checker-BTCmZRL4.d.ts +43 -0
  30. package/dist/chromium-camera-access-workaround-MifIwK9x.d.ts +137 -0
  31. package/dist/core/index.d.ts +2 -2
  32. package/dist/core/index.js +2 -2
  33. package/dist/create-slam-app-store-B76AGaI0.d.ts +371 -0
  34. package/dist/{depth-sampler-BNCtnEoP.d.ts → depth-sampler-CqrkRr2N.d.ts} +1 -1
  35. package/dist/enable-gps-ar-DNbO0zbg.d.ts +95 -0
  36. package/dist/{file-system-DD5TczSO.d.ts → file-system-TIsDfamK.d.ts} +32 -2
  37. package/dist/frame-conversions-D2EYjeNa.d.ts +54 -0
  38. package/dist/frame-loop-BTeRpDm4.d.ts +47 -0
  39. package/dist/frustum-visibility-DGnJqls0.d.ts +58 -0
  40. package/dist/{fused-path-DtqCSqJh.d.ts → fused-path-BdVHmDW9.d.ts} +1 -1
  41. package/dist/geo/h3-proximity.d.ts +1 -1
  42. package/dist/geo/index.d.ts +1 -1
  43. package/dist/{geo-types-Xx-LVcnw.d.ts → geo-types-clgzl8b5.d.ts} +16 -1
  44. package/dist/{gps-GKc6_Cly.d.ts → gps-B7AlMPz5.d.ts} +1 -1
  45. package/dist/gps-anchor-CISLPQIb.d.ts +59 -0
  46. package/dist/{gps-ar-pose-sampler-D_Zso40V.d.ts → gps-ar-pose-sampler-BypXZUqC.d.ts} +1 -1
  47. package/dist/{gps-event-coordinator-fwvmVfku.d.ts → gps-event-coordinator-BKVZbS1M.d.ts} +3 -3
  48. package/dist/gps-event-markers-BlHq3jYV.d.ts +103 -0
  49. package/dist/hit-test-reticle-BGXOxrUh.d.ts +45 -0
  50. package/dist/{image-capture-2pKjYUS6.d.ts → image-capture-BXZUmj7j.d.ts} +1 -1
  51. package/dist/index--ldLph4V.d.ts +2 -0
  52. package/dist/index-22v8MXJX.d.ts +23 -0
  53. package/dist/index-BB2KEWbN2.d.ts +37 -0
  54. package/dist/index.d.ts +64 -52
  55. package/dist/index.js +21 -8
  56. package/dist/{leaflet-map-overlay-CQZcnxbc.d.ts → leaflet-map-overlay-jNt-kcUr.d.ts} +22 -11
  57. package/dist/{logger-B81iwxx0.d.ts → logger-BZ44Dhd3.d.ts} +7 -1
  58. package/dist/map-data-BGIBM5rv.d.ts +49 -0
  59. package/dist/map-overlay-draw-DcGs9UV3.d.ts +42 -0
  60. package/dist/{null-storage-backend-C0TiwwzQ.d.ts → null-storage-backend-BPQJSaMw.d.ts} +2 -2
  61. package/dist/{opfs-storage-backend-Gt3rd76D.d.ts → opfs-storage-backend-u4QKvgvP.d.ts} +2 -2
  62. package/dist/{permission-checker-Cu3nbH1S.d.ts → permission-checker-CfV7INCa.d.ts} +41 -1
  63. package/dist/persistence-middleware-xB5sTllJ.d.ts +55 -0
  64. package/dist/{recording-options-BYUFX8iU.d.ts → recording-options-BSFpBSZH.d.ts} +10 -4
  65. package/dist/{recording-replayer-BFhFs7Mc.d.ts → recording-replayer-CTL2cUE0.d.ts} +2 -2
  66. package/dist/{recording-slice-BiktUIWF.d.ts → recording-slice-Cb888P6d.d.ts} +2 -2
  67. package/dist/{replay-engine-B88Va62x.d.ts → replay-engine-B-5GIZtc.d.ts} +1 -1
  68. package/dist/{replay-scene-DtUm6bsr.d.ts → replay-scene-DkNfldPh.d.ts} +3 -3
  69. package/dist/sensors/gps-error-handler.d.ts +1 -1
  70. package/dist/sensors/gps.d.ts +1 -1
  71. package/dist/sensors/gps.js +2 -2
  72. package/dist/sensors/index.d.ts +3 -3
  73. package/dist/sensors/index.js +1 -1
  74. package/dist/sensors/permission-checker.d.ts +2 -2
  75. package/dist/sensors/permission-checker.js +79 -1
  76. package/dist/session-disposers-M-oashRH.js +57 -0
  77. package/dist/state/app-selectors.d.ts +2 -2
  78. package/dist/state/app-selectors.js +33 -3
  79. package/dist/state/combined-root-state.d.ts +2 -0
  80. package/dist/state/combined-root-state.js +1 -0
  81. package/dist/state/create-slam-app-store.d.ts +1 -1
  82. package/dist/state/create-slam-app-store.js +27 -13
  83. package/dist/state/gps-ar-pose-sampler.d.ts +3 -3
  84. package/dist/state/gps-event-coordinator.d.ts +1 -1
  85. package/dist/state/index.d.ts +17 -16
  86. package/dist/state/index.js +6 -4
  87. package/dist/state/persistence-middleware.d.ts +2 -2
  88. package/dist/state/persistence-middleware.js +43 -9
  89. package/dist/state/recording-options.d.ts +1 -1
  90. package/dist/state/recording-replayer.d.ts +2 -2
  91. package/dist/state/recording-slice.d.ts +1 -1
  92. package/dist/state/replay-engine.d.ts +1 -1
  93. package/dist/state/store-subscribers.d.ts +2 -2
  94. package/dist/state/store-subscribers.js +38 -12
  95. package/dist/state/subscribe-to-selector.d.ts +1 -1
  96. package/dist/state/tracking-quality.d.ts +2 -0
  97. package/dist/state/tracking-quality.js +723 -0
  98. package/dist/state/tracking-slice.d.ts +2 -0
  99. package/dist/state/tracking-slice.js +147 -0
  100. package/dist/state-BkIfpiyA.js +87 -0
  101. package/dist/storage/file-system-utils.d.ts +1 -1
  102. package/dist/storage/file-system.d.ts +2 -2
  103. package/dist/storage/file-system.js +52 -1
  104. package/dist/storage/index.d.ts +8 -8
  105. package/dist/storage/null-storage-backend.d.ts +1 -1
  106. package/dist/storage/opfs-storage-backend.d.ts +1 -1
  107. package/dist/storage/opfs-storage.d.ts +1 -1
  108. package/dist/storage/storage-backend.d.ts +1 -1
  109. package/dist/storage/zip-export.d.ts +1 -1
  110. package/dist/storage/zip-reader.d.ts +1 -1
  111. package/dist/storage/zip-reader.js +8 -4
  112. package/dist/{storage-backend-yVnuWGTr.d.ts → storage-backend-yDSKafAQ.d.ts} +1 -1
  113. package/dist/{store-subscribers-DKKHld49.d.ts → store-subscribers-swlbtg_z.d.ts} +31 -6
  114. package/dist/{subscribe-to-selector-ghDKYtap.d.ts → subscribe-to-selector--KQpgLXG.d.ts} +1 -1
  115. package/dist/test-utils/browser-mocks.d.ts +1 -1
  116. package/dist/test-utils/zip-round-trip-helpers.d.ts +7 -1
  117. package/dist/test-utils/zip-round-trip-helpers.js +2 -1
  118. package/dist/tracking-slice-CDREeoZ_.d.ts +86 -0
  119. package/dist/types/ar-types.d.ts +1 -1
  120. package/dist/types/geo-types.d.ts +2 -2
  121. package/dist/types/index.d.ts +3 -3
  122. package/dist/utils/concurrency.d.ts +1 -1
  123. package/dist/utils/failure-tracker.d.ts +1 -1
  124. package/dist/utils/format-file-size.d.ts +1 -1
  125. package/dist/utils/fused-path.d.ts +1 -1
  126. package/dist/utils/index.d.ts +6 -6
  127. package/dist/utils/list-formatter.d.ts +1 -1
  128. package/dist/utils/logger.d.ts +1 -1
  129. package/dist/utils/logger.js +68 -8
  130. package/dist/visualization/accuracy-circles.d.ts +2 -0
  131. package/dist/visualization/accuracy-circles.js +57 -0
  132. package/dist/visualization/alignment-lerper.d.ts +1 -1
  133. package/dist/visualization/ar-world-group-alignment.d.ts +2 -0
  134. package/dist/visualization/ar-world-group-alignment.js +51 -0
  135. package/dist/visualization/camera-follower.d.ts +1 -1
  136. package/dist/visualization/css3d-renderer-manager.d.ts +1 -1
  137. package/dist/visualization/frame-conversions.d.ts +2 -0
  138. package/dist/visualization/frame-conversions.js +88 -0
  139. package/dist/visualization/frustum-visibility.d.ts +2 -0
  140. package/dist/visualization/frustum-visibility.js +139 -0
  141. package/dist/visualization/gps-anchor.d.ts +2 -0
  142. package/dist/visualization/gps-anchor.js +217 -0
  143. package/dist/visualization/gps-compass-cubes.d.ts +1 -1
  144. package/dist/visualization/gps-event-markers.d.ts +2 -2
  145. package/dist/visualization/gps-event-markers.js +69 -2
  146. package/dist/visualization/hit-test-reticle.d.ts +2 -0
  147. package/dist/visualization/hit-test-reticle.js +81 -0
  148. package/dist/visualization/index.d.ts +19 -12
  149. package/dist/visualization/index.js +9 -2
  150. package/dist/visualization/leaflet-map-overlay.d.ts +1 -1
  151. package/dist/visualization/leaflet-map-overlay.js +33 -79
  152. package/dist/visualization/lerp-utils.d.ts +1 -1
  153. package/dist/visualization/map-data.d.ts +2 -0
  154. package/dist/visualization/map-data.js +33 -0
  155. package/dist/visualization/map-overlay-draw.d.ts +2 -0
  156. package/dist/visualization/map-overlay-draw.js +107 -0
  157. package/dist/visualization/map-overlay.d.ts +1 -1
  158. package/dist/visualization/three-dispose.d.ts +1 -1
  159. package/dist/visualization/vis-colors.d.ts +1 -1
  160. package/dist/webxr-nue-basis-BbdqhqY6.js +54 -0
  161. package/dist/{webxr-session-COlSrXdL.d.ts → webxr-session-BnArFCew.d.ts} +76 -14
  162. package/dist/xr-frame-loop-BKckC7xC.d.ts +70 -0
  163. package/dist/{zip-reader-KgJEXbca.d.ts → zip-reader-B2lzN8F5.d.ts} +5 -0
  164. package/package.json +16 -16
  165. package/dist/ar/tracking-state.d.ts +0 -2
  166. package/dist/ar/tracking-state.js +0 -164
  167. package/dist/chromium-camera-access-workaround-CU5zSKNr.d.ts +0 -61
  168. package/dist/combined-root-state-B3SvPNjU.d.ts +0 -6
  169. package/dist/create-slam-app-store-DBm7g2Zd.d.ts +0 -85
  170. package/dist/gps-anchored-mesh-manager-CovAFK4g.d.ts +0 -56
  171. package/dist/gps-event-markers-sVyO9utS.d.ts +0 -67
  172. package/dist/persistence-middleware-z-75iisb.d.ts +0 -31
  173. package/dist/tracking-state-B9QfuZCg.d.ts +0 -101
  174. package/dist/visualization/gps-anchored-mesh-manager.d.ts +0 -2
  175. package/dist/visualization/gps-anchored-mesh-manager.js +0 -128
  176. /package/dist/{alignment-lerper-D9BeDwZX.d.ts → alignment-lerper-CCZJf-Xb.d.ts} +0 -0
  177. /package/dist/{ar-types-B-ORgk6Z.d.ts → ar-types-isPsQptb.d.ts} +0 -0
  178. /package/dist/{camera-blit-capture-DHuyrrxr.d.ts → camera-blit-capture-75WWa9Xb.d.ts} +0 -0
  179. /package/dist/{camera-follower-BMqPddxx.d.ts → camera-follower-B-nS1sr6.d.ts} +0 -0
  180. /package/dist/{capture-failure-tracker-2Q6oI2uQ.d.ts → capture-failure-tracker-D4HYJNOj.d.ts} +0 -0
  181. /package/dist/{concurrency-p6gB30fT.d.ts → concurrency-Bsmv53qw.d.ts} +0 -0
  182. /package/dist/{css3d-renderer-manager-rgLMVAvd.d.ts → css3d-renderer-manager-EDED3nvg.d.ts} +0 -0
  183. /package/dist/{failure-tracker-1sQ_Cgyw.d.ts → failure-tracker-D7ELffm0.d.ts} +0 -0
  184. /package/dist/{file-system-utils-BH8FdyIu.d.ts → file-system-utils-BH6uIs2i.d.ts} +0 -0
  185. /package/dist/{format-file-size-onGq0k1Q.d.ts → format-file-size-B7gJb3Md.d.ts} +0 -0
  186. /package/dist/{gps-compass-cubes-jRIJMOuh.d.ts → gps-compass-cubes-Ys6Hf1nc.d.ts} +0 -0
  187. /package/dist/{gps-error-handler-CH1S528z.d.ts → gps-error-handler-BLDhUlw5.d.ts} +0 -0
  188. /package/dist/{h3-proximity-GwesPTFT.d.ts → h3-proximity-DJnghtir.d.ts} +0 -0
  189. /package/dist/{lerp-utils-CZgQlrmu.d.ts → lerp-utils-DNcSmKVX.d.ts} +0 -0
  190. /package/dist/{list-formatter-DKQQVLcl.d.ts → list-formatter-CsqcU4v5.d.ts} +0 -0
  191. /package/dist/{map-overlay-C9ifl_4-.d.ts → map-overlay-yrFsUtGv.d.ts} +0 -0
  192. /package/dist/{opfs-storage-Dlq1I_Gb.d.ts → opfs-storage-LsLY6VZV.d.ts} +0 -0
  193. /package/dist/{scene-node-names-DPsaE2z3.d.ts → scene-node-names-IHW7HR4S.d.ts} +0 -0
  194. /package/dist/{three-dispose-qt_r5wR1.d.ts → three-dispose-WTBAfaWU.d.ts} +0 -0
  195. /package/dist/{vis-colors-BKkdTIKb.d.ts → vis-colors-Djnyg_UH.d.ts} +0 -0
  196. /package/dist/{xr-camera-texture-BbukNE79.d.ts → xr-camera-texture-BU5YvKAM.d.ts} +0 -0
  197. /package/dist/{xr-error-handler-DTHfmvrl.d.ts → xr-error-handler-DcUFshNF.d.ts} +0 -0
  198. /package/dist/{zip-export-BjrQPv0X.d.ts → zip-export-C0_ErAqT.d.ts} +0 -0
@@ -0,0 +1,137 @@
1
+ //#region ../src/ar/chromium-camera-access-workaround.d.ts
2
+ /**
3
+ * Chromium WebXR camera-access tab-crash workaround.
4
+ *
5
+ * Background:
6
+ * Requesting `camera-access` as an optional WebXR feature on Android Chrome
7
+ * 147+ causes a fatal renderer-process crash (`CrRendererMain`) 1–2 seconds
8
+ * after entering AR. The crash reproduces in the upstream three.js
9
+ * `webxr_ar_hittest.html` example with `optionalFeatures: ['camera-access']`
10
+ * added — i.e. it is not specific to this app's session setup. See:
11
+ *
12
+ * - GpsPlusSlamJs_Docs/docs/2026-04-22-camera-access-reproducer-plan.md
13
+ * - GpsPlusSlamJs_Docs/docs/2026-06-04-camera-access-crash-regression-chrome-148.md
14
+ * - https://github.com/mrdoob/three.js/issues/33404
15
+ * - https://issues.chromium.org/issues/507508099 (root-cause, marked Fixed)
16
+ *
17
+ * There is NOT a single crash here — the Chromium tracker notes the crash on
18
+ * Chrome 147 is different from the crash on 148+, and the simple workaround
19
+ * below only helped on a subset of versions. The empirically-verified
20
+ * (on-device) timeline is:
21
+ *
22
+ * - 147 : deleting `createProjectionLayer` / `layers` forces three.js onto
23
+ * `XRWebGLLayer` and sidesteps the crash (deletes-only is sufficient).
24
+ * - 148.0.7778.12 .. 149.0.7821 : the delete-only trick is NOT sufficient on
25
+ * its own. An ADDITIONAL patch is needed: persist the `baseLayer`
26
+ * reference across `XRSession.prototype.updateRenderState` so three.js's
27
+ * later `depthNear`/`depthFar` update does not drop the active
28
+ * `glBaseLayer`. (Confirmed on-device on `148.0.7778.215`: BOTH the
29
+ * deletes and the baseLayer patch are required for the page not to
30
+ * crash. Earlier 148 builds (`< .7778.12`) are below the window per the
31
+ * tracker, which reported delete-only worked there.)
32
+ * - > 149.0.7821 (incl. Chrome 150) : the delete-only path is STILL required
33
+ * (confirmed on-device: Chrome 150 only stops crashing when the deletes
34
+ * are applied), but the extra baseLayer-persistence patch is NOT needed.
35
+ * The earlier assumption that Chromium fully fixed this on patched
36
+ * builds did not hold on real devices, so we no longer skip the
37
+ * workaround on "patched" Chrome.
38
+ *
39
+ * Resulting policy (see {@link applyChromiumProjectionLayerWorkaround}):
40
+ * - ALWAYS apply the deletes (every Chrome build, and unknown/non-Chromium
41
+ * environments — restoring the original always-on behavior).
42
+ * - Apply the baseLayer-persistence patch ONLY when a detected Chrome build
43
+ * falls inside the affected window
44
+ * [{@link BASELAYER_WINDOW_MIN} .. {@link BASELAYER_WINDOW_MAX}].
45
+ *
46
+ * Caveats:
47
+ * - This is a Chromium-specific hack and the upstream comment explicitly
48
+ * warns it "might break webxr on other devices" — keep it opt-in.
49
+ * - Must run BEFORE any WebXR session setup. Three.js reads these prototype
50
+ * members lazily when the first session starts, so calling this at app
51
+ * bootstrap (before `initAR()`) is sufficient.
52
+ * - Idempotent: safe to call repeatedly. Safe on environments where the
53
+ * prototypes do not exist (e.g. desktop browsers, jsdom).
54
+ */
55
+ /**
56
+ * Parsed Chrome version as `[major, minor, build, patch]`.
57
+ */
58
+ type ChromeVersion = [number, number, number, number];
59
+ /**
60
+ * Inclusive lower bound of the Chrome window that additionally needs the
61
+ * `baseLayer`-persistence patch (on top of the deletes).
62
+ *
63
+ * Set to `148.0.7778.12`, the issue tracker's figure for when the delete-only
64
+ * trick stopped being sufficient. On-device confirmation: `148.0.7778.215`
65
+ * (well inside this window) crashes with deletes-only and needs BOTH patches.
66
+ * Earlier 148 builds (`< .7778.12`) and all of Chrome 147 stay below this
67
+ * bound (deletes-only) per the documented timeline — we have no on-device
68
+ * evidence that they need the baseLayer patch, so we do not apply it there.
69
+ */
70
+ declare const BASELAYER_WINDOW_MIN: ChromeVersion;
71
+ /**
72
+ * Inclusive upper bound of the Chrome window that additionally needs the
73
+ * `baseLayer`-persistence patch. The crash is fixed after `149.0.7819.0` and
74
+ * the camera image is correctly populated after `149.0.7821.0`; above this
75
+ * build the extra patch is no longer required (the deletes still are — see
76
+ * the module header and the on-device matrix for Chrome 150).
77
+ *
78
+ * @see https://github.com/mrdoob/three.js/issues/33404
79
+ */
80
+ declare const BASELAYER_WINDOW_MAX: ChromeVersion;
81
+ /**
82
+ * Result of {@link applyChromiumProjectionLayerWorkaround}.
83
+ * Useful for logging and tests.
84
+ */
85
+ interface ChromiumProjectionLayerWorkaroundResult {
86
+ /** True if `XRWebGLBinding.prototype.createProjectionLayer` was deleted on this call. */
87
+ deletedCreateProjectionLayer: boolean;
88
+ /** True if `XRRenderState.prototype.layers` was deleted on this call. */
89
+ deletedRenderStateLayers: boolean;
90
+ /** True if `XRSession.prototype.updateRenderState` was wrapped on this call. */
91
+ patchedUpdateRenderState: boolean;
92
+ /** The detected Chrome version (`"major.minor.build.patch"`), or null. */
93
+ detectedChromeVersion: string | null;
94
+ }
95
+ /**
96
+ * Parse a Chrome/Chromium version from a user-agent string.
97
+ *
98
+ * Matches the `Chrome/<major>.<minor>.<build>.<patch>` token (and the iOS
99
+ * `CriOS/...` variant). Returns null for non-Chromium user agents.
100
+ */
101
+ declare function parseChromeVersion(userAgent: string): ChromeVersion | null;
102
+ /**
103
+ * True when the detected Chrome build falls inside the affected window
104
+ * [{@link BASELAYER_WINDOW_MIN} .. {@link BASELAYER_WINDOW_MAX}] (inclusive)
105
+ * and therefore additionally needs the `baseLayer`-persistence patch. Outside
106
+ * the window (including non-Chromium user agents) returns false — only the
107
+ * deletes are needed there.
108
+ */
109
+ declare function needsBaseLayerPersistence(userAgent: string): boolean;
110
+ /**
111
+ * Apply the Chromium camera-access tab-crash workaround.
112
+ *
113
+ * Policy (derived from on-device testing — see the module header):
114
+ *
115
+ * - ALWAYS removes `XRWebGLBinding.prototype.createProjectionLayer`
116
+ * (three.js r184) and `XRRenderState.prototype.layers` (three.js r158) so
117
+ * three.js falls back to `XRWebGLLayer`. This is required on every affected
118
+ * Chrome build observed so far, including Chrome 150, and is also applied
119
+ * on unknown/non-Chromium environments (restoring the original always-on
120
+ * behavior).
121
+ * - ADDITIONALLY persists the `baseLayer` across
122
+ * `XRSession.prototype.updateRenderState`, but ONLY when a detected Chrome
123
+ * build falls inside the affected window
124
+ * [{@link BASELAYER_WINDOW_MIN} .. {@link BASELAYER_WINDOW_MAX}]. Outside
125
+ * that window the extra patch is unnecessary (and is skipped on unknown
126
+ * environments to avoid touching projection-layer devices like Quest).
127
+ *
128
+ * Call once during bootstrap, before any `requestSession()` call.
129
+ *
130
+ * @param options.userAgent override the detected user agent (for testing).
131
+ * @returns which prototype members were actually changed on this call.
132
+ */
133
+ declare function applyChromiumProjectionLayerWorkaround(options?: {
134
+ userAgent?: string;
135
+ }): ChromiumProjectionLayerWorkaroundResult;
136
+ //#endregion
137
+ export { applyChromiumProjectionLayerWorkaround as a, ChromiumProjectionLayerWorkaroundResult as i, BASELAYER_WINDOW_MIN as n, needsBaseLayerPersistence as o, ChromeVersion as r, parseChromeVersion as s, BASELAYER_WINDOW_MAX as t };
@@ -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--ldLph4V.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 };
@@ -0,0 +1,371 @@
1
+ import { t as ARPose } from "./ar-types-isPsQptb.js";
2
+ import { a as TrackingSliceState, t as DeviceOrientation } from "./tracking-slice-CDREeoZ_.js";
3
+ import { t as RecordingState } from "./recording-slice-Cb888P6d.js";
4
+ import { n as SessionMetadata } from "./opfs-storage-LsLY6VZV.js";
5
+ import { n as StorageBackend } from "./storage-backend-yDSKafAQ.js";
6
+ import { GpsPoint, LatLong, Matrix4, RootState, Vector3 } from "gps-plus-slam-js";
7
+ import * as _$_reduxjs_toolkit0 from "@reduxjs/toolkit";
8
+ import { Middleware, Reducer, ReducersMapObject, configureStore } from "@reduxjs/toolkit";
9
+
10
+ //#region ../src/state/combined-root-state.d.ts
11
+ type CombinedRootState = SlamAppCombinedState;
12
+ //#endregion
13
+ //#region ../src/state/tracking-quality.d.ts
14
+ type TrackingQualityState = 'warming-up' | 'ar-lost' | 'degraded' | 'ok';
15
+ interface TrackingQualityReport {
16
+ state: TrackingQualityState;
17
+ /** 0..1, monotonically combined from {@link subScores}. */
18
+ confidence: number;
19
+ subScores: {
20
+ convergence: number;
21
+ residualConsensus: number; /** `null` when the device cannot supply an absolute compass heading. */
22
+ compassAgreement: number | null;
23
+ gpsAccuracy: number;
24
+ coverage: number;
25
+ };
26
+ diagnostics: {
27
+ /**
28
+ * §4.1 (Finding 6): **sum of |Δrotation|** across the last
29
+ * `matrixHistorySize - 1` consecutive snapshot pairs in the ring
30
+ * buffer, in degrees. Replaced the per-pair `recentMaxRotationDeltaDeg`
31
+ * on 2026-05-23 — see
32
+ * `GpsPlusSlamJs_Docs/docs/2026-05-23-tracking-quality-hud-user-feedback.md`
33
+ * (Finding 6). Surfaced in the recorder HUD as `ΣΔrot:`.
34
+ */
35
+ recentSumRotationDeltaDeg: number; /** §4.1 (Finding 6): sum of |Δtranslation| across the same window, in metres. Surfaced as `ΣΔpos:`. */
36
+ recentSumTranslationDeltaM: number;
37
+ medianResidualM: number;
38
+ medianRecentGpsAccuracyM: number;
39
+ walkedDistanceM: number;
40
+ directionSpreadDeg: number; /** `null` when §4.3 is unavailable (no absolute compass). */
41
+ headingDeltaDeg: number | null;
42
+ compassDriftDetected: boolean;
43
+ observationsSeen: number; /** §4.6 — diagnostic only, never feeds the aggregate. */
44
+ gpsVsFusedMaxDivergenceM: number;
45
+ };
46
+ }
47
+ interface TrackingQualityOptions {
48
+ /** §4.1 ring-buffer length. Seed default; corpus-tuned in §6.1. */
49
+ matrixHistorySize?: number;
50
+ /** §4.2 GPS-window length. Seed default; corpus-tuned in §6.1. */
51
+ residualWindowSize?: number;
52
+ /** Confidence threshold below which `state` reports `'degraded'`. */
53
+ degradedThreshold?: number;
54
+ /** §4.4 window length for GPS-accuracy budget. */
55
+ gpsAccuracyWindowSize?: number;
56
+ /** §4.5 walked-distance threshold for coverage = 1.0. */
57
+ coverageWalkedDistanceM?: number;
58
+ /** §4.5 direction-spread threshold for coverage = 1.0. */
59
+ coverageDirectionSpreadDeg?: number;
60
+ /** §4.1 ΣΔrotation (deg) at/below which convergence scores 1.0. Fail ramp ends at 4×. */
61
+ convergenceRotationWarnDeg?: number;
62
+ /** §4.1 ΣΔtranslation (m) at/below which convergence scores 1.0. Fail ramp ends at 4×. */
63
+ convergenceTranslationWarnM?: number;
64
+ /** §4.3 EMA threshold (deg) below which compass scores 1.0. */
65
+ compassWarnDeg?: number;
66
+ /** §4.3 EMA threshold (deg) above which compass scores 0.0. */
67
+ compassFailDeg?: number;
68
+ /** Minimum GPS observations before leaving `warming-up`. */
69
+ warmupMinObservations?: number;
70
+ /** Minimum coverage score before leaving `warming-up`. */
71
+ warmupMinCoverage?: number;
72
+ /** §4.2 residual saturation target (m). */
73
+ residualConfidenceTargetM?: number;
74
+ /** §4.4 GPS-accuracy floor used to normalise residuals (m). */
75
+ gpsAccuracyFloorM?: number;
76
+ /** §4.3 consecutive compass-agreeing observations for first agreement. */
77
+ firstAgreementMinStreak?: number;
78
+ /** §4.8 consecutive sub-threshold observations before ok → degraded. */
79
+ degradedHoldoff?: number;
80
+ /**
81
+ * §4.8b (Finding 4) — EMA blend factor applied to `subScores.convergence`.
82
+ * `1.0` disables smoothing (raw value). `0 < α < 1` blends as
83
+ * `smoothed = prevSmoothed + α * (raw - prevSmoothed)`. First observation
84
+ * (no prior smoothed value) is seeded to the raw value.
85
+ */
86
+ convergenceEmaAlpha?: number;
87
+ }
88
+ declare const DEFAULT_TRACKING_QUALITY_OPTIONS: Required<TrackingQualityOptions>;
89
+ /**
90
+ * Single buffered alignment matrix snapshot. `matrix` is stored as a
91
+ * plain `number[]` (length 16, row-major) so it stays serializable for
92
+ * RTK's `SerializableStateInvariantMiddleware` and for action logs.
93
+ */
94
+ interface AlignmentSnapshot {
95
+ observationIndex: number;
96
+ matrix: number[];
97
+ }
98
+ interface TrackingQualitySliceState {
99
+ recentAlignments: AlignmentSnapshot[];
100
+ firstAgreementObservationIndex: number | null;
101
+ report: TrackingQualityReport | null;
102
+ /** §4.8 — consecutive observations with raw confidence < degradedThreshold. */
103
+ degradedConsecutiveCount: number;
104
+ /**
105
+ * §4.8b (Finding 4) — last EMA-smoothed convergence sub-score. `null`
106
+ * means "no prior observation" and the next aggregator run will seed
107
+ * the value with the raw convergence score. Reset on
108
+ * `resetTrackingQuality`.
109
+ */
110
+ smoothedConvergence: number | null;
111
+ }
112
+ interface ConvergenceResult {
113
+ score: number;
114
+ /** §4.1 (Finding 6): sum of |Δrotation| across the last N-1 pairs. */
115
+ recentSumRotationDeltaDeg: number;
116
+ /** §4.1 (Finding 6): sum of |Δtranslation| across the last N-1 pairs. */
117
+ recentSumTranslationDeltaM: number;
118
+ /** Pair count used (≥ 2 snapshots ⇒ ≥ 1 pair, else 0). */
119
+ pairCount: number;
120
+ }
121
+ /**
122
+ * §4.1 matrix-history convergence over the buffered snapshots.
123
+ *
124
+ * Reuses the same kernel idea as `computeStabilityDelta` from the
125
+ * Investigation helpers (rotation + translation delta between two 4×4
126
+ * matrices). With 0 or 1 snapshot we return score 0 — convergence is
127
+ * undefined until at least one consecutive pair exists.
128
+ *
129
+ * Finding 6 (2026-05-23 field test): the per-pair `max` aggregation was
130
+ * replaced with a **sum** across the window. `max` is a burst detector
131
+ * — dominated by one bad pair, blind to slow drift; `sum` answers
132
+ * "how much alignment motion accumulated over the window?" and exposes
133
+ * slow creeping drift in user-readable units (°, m). The HUD now shows
134
+ * the raw sums (`ΣΔrot:`, `ΣΔpos:`) alongside the EMA-smoothed `Conv:`
135
+ * sub-score (Finding 4) so the user can debug an unstable reading.
136
+ */
137
+ declare function computeConvergence(snapshots: readonly AlignmentSnapshot[], options?: {
138
+ rotationWarnDeg?: number;
139
+ translationWarnM?: number;
140
+ }): ConvergenceResult;
141
+ /**
142
+ * Rotation and translation delta between two 4×4 alignment matrices in
143
+ * the column-major layout that gl-matrix and the framework use.
144
+ *
145
+ * Rotation: extract the orientation quaternion with `mat4.getRotation`
146
+ * and compute the relative angle via `quat.getAngle` (degrees).
147
+ * Translation: extract the origin column with `mat4.getTranslation` and
148
+ * compute the Euclidean distance.
149
+ *
150
+ * This is the **single shared kernel** for the AppFramework reporter and
151
+ * the Investigation harness (see §11 (a) of the tracking-quality plan).
152
+ * `GpsPlusSlamJs_Investigation/src/investigation-helpers.ts` re-exports
153
+ * `computeStabilityDelta` as a thin wrapper around this function so the
154
+ * §6.1 corpus sweep and the runtime convergence score share one numeric
155
+ * definition.
156
+ */
157
+ declare function matrixDelta(prev: readonly number[], curr: readonly number[]): {
158
+ rotationDeltaDeg: number;
159
+ translationDeltaM: number;
160
+ };
161
+ interface ResidualConsensusResult {
162
+ score: number;
163
+ medianResidualM: number;
164
+ count: number;
165
+ }
166
+ /**
167
+ * §4.2 — Median residual between the last `K` GPS observations and the
168
+ * positions you would have predicted by transforming the matching
169
+ * odometry positions through the current alignment matrix.
170
+ *
171
+ * Returns `score = 0`, `medianResidualM = 0` when we have fewer than
172
+ * 2 paired observations or when the alignment matrix / zero ref is
173
+ * not yet set.
174
+ */
175
+ declare function computeResidualConsensus(alignmentMatrix: Matrix4 | null, gpsPositions: readonly GpsPoint[], odometryPositions: readonly Vector3[], zeroRef: LatLong | null, options?: Pick<Required<TrackingQualityOptions>, 'residualWindowSize' | 'residualConfidenceTargetM' | 'gpsAccuracyFloorM'>): ResidualConsensusResult;
176
+ interface GpsAccuracyResult {
177
+ score: number;
178
+ medianM: number;
179
+ countAccurate: number;
180
+ countTotal: number;
181
+ }
182
+ /**
183
+ * §4.4 — Median `latLongAccuracy` of the last `K` GPS points, with
184
+ * an "accurate-fix count" diagnostic. Cheap, always available.
185
+ *
186
+ * `score` ramps from 1.0 at median ≤ 3 m to 0.0 at median ≥ 25 m
187
+ * (linear), matching the plan's "≤ 5 m is good" heuristic with a
188
+ * generous fail tail.
189
+ */
190
+ declare function computeGpsAccuracy(gpsPositions: readonly GpsPoint[], options?: {
191
+ windowSize?: number;
192
+ goodMedianM?: number;
193
+ badMedianM?: number;
194
+ }): GpsAccuracyResult;
195
+ interface CoverageResult {
196
+ score: number;
197
+ walkedDistanceM: number;
198
+ directionSpreadDeg: number;
199
+ }
200
+ /**
201
+ * §4.5 — Coverage = how far the user has walked AND how diverse the
202
+ * walking direction has been. Both required: a long but unidirectional
203
+ * walk leaves the rotation about the walking axis under-determined.
204
+ */
205
+ declare function computeCoverage(odometryPositions: readonly Vector3[], options?: {
206
+ walkedDistanceM?: number;
207
+ directionSpreadDeg?: number;
208
+ }): CoverageResult;
209
+ interface CompassAgreementResult {
210
+ /** `null` when `absolute !== true` on the sensor orientation. */
211
+ score: number | null;
212
+ headingDeltaDeg: number | null;
213
+ }
214
+ /**
215
+ * §4.3 — Compare the alignment matrix's mapping of AR-forward to ENU
216
+ * against the device compass heading. Returns `score = null` whenever
217
+ * the sensor's `absolute !== true` so the aggregate excludes the
218
+ * sub-score (per Q2 in the plan).
219
+ *
220
+ * AR-forward in our `ARPose` convention is `(0, 0, -1)` (right-handed,
221
+ * Y-up). We rotate that by the alignment's 3×3 rotation, take its
222
+ * North/East components, and compare against the compass alpha.
223
+ */
224
+ declare function computeCompassAgreement(alignmentMatrix: Matrix4 | null, sensorOrientation: DeviceOrientation | null, arPose: ARPose | null, options?: {
225
+ warnDeg?: number;
226
+ failDeg?: number;
227
+ }): CompassAgreementResult;
228
+ /**
229
+ * §4.6 — Maximum lateral distance between raw GPS positions and the
230
+ * positions you would predict by transforming the matching odometry
231
+ * positions through the current alignment. Diagnostic only — never
232
+ * feeds the aggregate confidence per the plan.
233
+ */
234
+ declare function computeGpsVsFusedDivergence(alignmentMatrix: Matrix4 | null, gpsPositions: readonly GpsPoint[], odometryPositions: readonly Vector3[], zeroRef: LatLong | null, windowSize?: number): number;
235
+ declare const snapshotPushed: _$_reduxjs_toolkit0.ActionCreatorWithPayload<AlignmentSnapshot, "trackingQuality/snapshotPushed">, snapshotsTrimmed: _$_reduxjs_toolkit0.ActionCreatorWithPayload<{
236
+ size: number;
237
+ }, "trackingQuality/snapshotsTrimmed">, reportUpdated: _$_reduxjs_toolkit0.ActionCreatorWithPayload<TrackingQualityReport | null, "trackingQuality/reportUpdated">, firstAgreementReached: _$_reduxjs_toolkit0.ActionCreatorWithPayload<number, "trackingQuality/firstAgreementReached">, degradedCountUpdated: _$_reduxjs_toolkit0.ActionCreatorWithPayload<number, "trackingQuality/degradedCountUpdated">, resetTrackingQuality: _$_reduxjs_toolkit0.ActionCreatorWithoutPayload<"trackingQuality/resetTrackingQuality">;
238
+ declare const trackingQualityReducer: _$_reduxjs_toolkit0.Reducer<TrackingQualitySliceState>;
239
+ interface RootWithTrackingQuality {
240
+ trackingQuality?: TrackingQualitySliceState;
241
+ }
242
+ declare function selectTrackingQuality(state: RootWithTrackingQuality): TrackingQualityReport | null;
243
+ declare function selectRecentAlignments(state: RootWithTrackingQuality): readonly AlignmentSnapshot[];
244
+ declare function selectFirstAgreementObservationIndex(state: RootWithTrackingQuality): number | null;
245
+ /**
246
+ * Pure function — produces a {@link TrackingQualityReport} from a root
247
+ * state and options. The Investigation harness imports this directly to
248
+ * sweep `(N, K)` without going through the Redux listener middleware.
249
+ *
250
+ * The report's `state` enum follows §5 of the plan:
251
+ * - `ar-lost` whenever `tracking.phase !== 'tracking'`
252
+ * - `warming-up` until `coverage ≥ warmupMinCoverage` AND
253
+ * `observationsSeen ≥ warmupMinObservations`
254
+ * - then `ok` / `degraded` from `min(subScores)` vs.
255
+ * `degradedThreshold`.
256
+ */
257
+ declare function computeTrackingQualityReport(rootState: CombinedRootState, options?: TrackingQualityOptions): TrackingQualityReport;
258
+ /**
259
+ * Build the listener middleware that drives the `trackingQuality`
260
+ * slice. Register the returned middleware in `createSlamAppStore`.
261
+ *
262
+ * Behaviour:
263
+ * - On `gpsData/recordGpsEvent` and `gpsData/setZeroPos`: if the
264
+ * alignment matrix changed, dispatch `snapshotPushed` +
265
+ * `snapshotsTrimmed`. Then recompute the report and dispatch
266
+ * `reportUpdated` if it changed.
267
+ * - On `recording/startSession` and `tracking/resetTracking`:
268
+ * dispatch `resetTrackingQuality` and recompute the report.
269
+ * - On `tracking/poseReceived` and `tracking/poseLost`: only
270
+ * recompute the report (no buffer change).
271
+ * - All dispatches are idempotency-gated so quiet motion does not
272
+ * churn the store.
273
+ */
274
+ declare function createTrackingQualityListenerMiddleware(options?: TrackingQualityOptions): Middleware;
275
+ //#endregion
276
+ //#region ../src/state/create-slam-app-store.d.ts
277
+ /**
278
+ * Base shape produced by `createSlamAppStore` with no `extraReducers`.
279
+ *
280
+ * Library state (`gpsData` / `gpsElements` / `arElements`) plus the
281
+ * framework recording slice (`recording`).
282
+ */
283
+ interface SlamAppRootState extends RootState {
284
+ recording: RecordingState;
285
+ tracking: TrackingSliceState;
286
+ trackingQuality: TrackingQualitySliceState;
287
+ }
288
+ /** A bare-minimum middleware signature compatible with RTK's middleware list. */
289
+ type SlamAppMiddleware = Middleware<any, any, any>;
290
+ /**
291
+ * Options for {@link createSlamAppStore}.
292
+ */
293
+ interface SlamAppStoreOptions<ExtraReducers extends ReducersMapObject = Record<string, never>> {
294
+ /**
295
+ * Persistence backend used to bridge Redux actions to durable storage.
296
+ * Tests / replay paths should pass `NullStorageBackend`.
297
+ */
298
+ storageBackend: StorageBackend;
299
+ /**
300
+ * Caller-supplied reducers added alongside the framework's built-ins.
301
+ * Use this seam to plug recorder slices (routing, refPoints, scenario)
302
+ * or any app-specific state without forking the factory.
303
+ */
304
+ extraReducers?: ExtraReducers;
305
+ /**
306
+ * Caller-supplied middlewares appended after RTK defaults and the
307
+ * persistence middleware.
308
+ */
309
+ extraMiddleware?: ReadonlyArray<SlamAppMiddleware>;
310
+ /**
311
+ * Additional slice prefixes to persist beyond the framework built-ins
312
+ * (`gpsData`, `recording`). Pass caller-owned slice names derived from
313
+ * the slice itself — e.g. `slicePrefixOf(addRefPointEntry.type)` or
314
+ * `refPointsSlice.name` — never a hand-typed literal, so a rename can
315
+ * never silently drop the slice's actions from recordings.
316
+ */
317
+ persistedExtraPrefixes?: readonly string[];
318
+ /**
319
+ * Invoked when the persistence middleware fails to durably write an action.
320
+ */
321
+ onWriteFailure?: (error: Error) => void;
322
+ /**
323
+ * Disables RTK's expensive dev-only middleware (Serializable / Immutable
324
+ * checks). Default `true`; set `false` for high-throughput replay scenarios.
325
+ */
326
+ enableDevChecks?: boolean;
327
+ /**
328
+ * License key for the core library. Defaults to the bundled community key.
329
+ * Apps with a paid license override here. Validation always runs and throws
330
+ * on invalid / expired / empty keys.
331
+ *
332
+ * @see EULA.md §3 — License Key
333
+ */
334
+ licenseKey?: string;
335
+ /**
336
+ * Optional overrides for the tracking-quality reporter
337
+ * (matrix-history size, residual window, thresholds, etc.).
338
+ *
339
+ * @see docs/2026-05-16-tracking-quality-metrics-plan.md
340
+ */
341
+ trackingQualityOptions?: Partial<TrackingQualityOptions>;
342
+ }
343
+ /**
344
+ * Combined root state: the framework's base state plus any caller-supplied
345
+ * extras. Generic so consumers get exact typing for the slices they add.
346
+ */
347
+ type SlamAppCombinedState<ExtraReducers extends ReducersMapObject = Record<never, never>> = SlamAppRootState & { [K in keyof ExtraReducers]: ExtraReducers[K] extends Reducer<infer S> ? S : never };
348
+ /**
349
+ * The store object returned by {@link createSlamAppStore}.
350
+ *
351
+ * Wraps RTK's store and adds storage-delegation helpers so consumers can
352
+ * issue frame / metadata writes without holding a separate handle to the
353
+ * `StorageBackend`.
354
+ */
355
+ interface SlamAppStore<ExtraReducers extends ReducersMapObject = Record<string, never>> {
356
+ getState: () => SlamAppCombinedState<ExtraReducers>;
357
+ dispatch: ReturnType<typeof configureStore>['dispatch'];
358
+ subscribe: (listener: () => void) => () => void;
359
+ /** Persist a captured camera frame via the configured backend. */
360
+ writeFrame: (blob: Blob, index: number) => Promise<void>;
361
+ /** Persist session metadata (`session.json`) via the configured backend. */
362
+ writeSessionMetadata: (metadata: SessionMetadata) => Promise<void>;
363
+ }
364
+ /**
365
+ * Build a Redux store wired with library + recording slices, persistence
366
+ * middleware, and any caller-supplied extras. See module docstring for the
367
+ * design rationale.
368
+ */
369
+ declare function createSlamAppStore<ExtraReducers extends ReducersMapObject = Record<string, never>>(options: SlamAppStoreOptions<ExtraReducers>): SlamAppStore<ExtraReducers>;
370
+ //#endregion
371
+ export { resetTrackingQuality as A, computeResidualConsensus as C, firstAgreementReached as D, degradedCountUpdated as E, snapshotsTrimmed as F, trackingQualityReducer as I, CombinedRootState as L, selectRecentAlignments as M, selectTrackingQuality as N, matrixDelta as O, snapshotPushed as P, computeGpsVsFusedDivergence as S, createTrackingQualityListenerMiddleware as T, TrackingQualityState as _, SlamAppStoreOptions as a, computeCoverage as b, CompassAgreementResult as c, DEFAULT_TRACKING_QUALITY_OPTIONS as d, GpsAccuracyResult as f, TrackingQualitySliceState as g, TrackingQualityReport as h, SlamAppStore as i, selectFirstAgreementObservationIndex as j, reportUpdated as k, ConvergenceResult as l, TrackingQualityOptions as m, SlamAppMiddleware as n, createSlamAppStore as o, ResidualConsensusResult as p, SlamAppRootState as r, AlignmentSnapshot as s, SlamAppCombinedState as t, CoverageResult as u, computeCompassAgreement as v, computeTrackingQualityReport as w, computeGpsAccuracy as x, computeConvergence as y };
@@ -1,4 +1,4 @@
1
- import { i as DepthSample, t as ARPose } from "./ar-types-B-ORgk6Z.js";
1
+ import { i as DepthSample, t as ARPose } from "./ar-types-isPsQptb.js";
2
2
 
3
3
  //#region ../src/ar/depth-sampler.d.ts
4
4
  /**
@@ -0,0 +1,95 @@
1
+ import { t as ArCrashIsolationOptions } from "./recording-options-BSFpBSZH.js";
2
+ import { n as RawDeviceOrientation, t as GpsPosition } from "./gps-B7AlMPz5.js";
3
+ import { n as PermissionStatus } from "./permission-checker-CfV7INCa.js";
4
+ import { t as SessionFeatureOptions } from "./webxr-session-BnArFCew.js";
5
+
6
+ //#region ../src/ar/enable-gps-ar.d.ts
7
+ /**
8
+ * Lifecycle status of the controller. The app maps these onto its button:
9
+ * - `checking` — support probe in flight (initial / after `refreshSupport`)
10
+ * - `unsupported`— WebXR immersive-ar is unavailable; button stays disabled
11
+ * - `ready` — supported and idle; button is the live "Enable GPS AR" CTA
12
+ * - `starting` — in-gesture orchestration in flight (button shows progress)
13
+ * - `running` — AR session started; button reflects the durable end state
14
+ * - `stopping` — teardown in flight (watches stopping, session ending)
15
+ * - `error` — orchestration failed; button reverts to a retryable CTA
16
+ */
17
+ type EnableGpsArStatus = 'checking' | 'unsupported' | 'ready' | 'starting' | 'running' | 'stopping' | 'error';
18
+ /** Observable controller state. */
19
+ interface EnableGpsArState {
20
+ readonly status: EnableGpsArStatus;
21
+ /** Human-readable failure reason when `status === 'error'`. */
22
+ readonly error?: string;
23
+ }
24
+ /** Per-`enable()` configuration. */
25
+ interface EnableGpsArConfig {
26
+ /** DOM element hosting the AR canvas / dom-overlay (passed to `initAR`). */
27
+ container: HTMLElement;
28
+ /**
29
+ * Opt-in to the depth ("3D map") permission probe. Default `false` — the
30
+ * minimal default set is WebXR + geolocation + orientation only.
31
+ */
32
+ requestDepth?: boolean;
33
+ /**
34
+ * Forward `requestHitTest` to `initAR` so the session requests the WebXR
35
+ * `hit-test` feature (the minimal AR example needs this for its reticle).
36
+ */
37
+ requestHitTest?: boolean;
38
+ /** Crash-isolation diagnostic flags forwarded verbatim to `initAR`. */
39
+ isolationOptions?: Partial<ArCrashIsolationOptions>;
40
+ /** Receives every GPS fix from the started watch. */
41
+ onGpsPosition?: (position: GpsPosition) => void;
42
+ /** Receives every device-orientation sample from the started watch. */
43
+ onOrientation?: (orientation: RawDeviceOrientation) => void;
44
+ }
45
+ /** Result of a single `enable()` attempt. */
46
+ interface EnableGpsArResult {
47
+ readonly ok: boolean;
48
+ /** Failure reason when `ok === false`. */
49
+ readonly error?: string;
50
+ }
51
+ /** Injectable collaborators (default to the real framework functions). */
52
+ interface EnableGpsArDeps {
53
+ isWebXRSupported: () => Promise<boolean>;
54
+ requestGeolocationPermission: () => Promise<PermissionStatus>;
55
+ requestOrientationPermission: () => Promise<PermissionStatus>;
56
+ requestWebXRWithDepthPermission: () => Promise<PermissionStatus>;
57
+ startGpsWatch: (onPosition: (position: GpsPosition) => void, onError?: (error: GeolocationPositionError) => void) => void;
58
+ startOrientationWatch: (onOrientation: (orientation: RawDeviceOrientation) => void) => void;
59
+ initAR: (container: HTMLElement, isolationOptions?: Partial<ArCrashIsolationOptions>, sessionFeatures?: SessionFeatureOptions) => Promise<void>;
60
+ stopGpsWatch: () => void;
61
+ stopOrientationWatch: () => void;
62
+ endARSession: () => Promise<void>;
63
+ }
64
+ /** Public controller surface the app drives from its button. */
65
+ interface EnableGpsArController {
66
+ /** Current observable state (button derives its label/disabled from this). */
67
+ getState: () => EnableGpsArState;
68
+ /** Subscribe to state changes; returns an unsubscribe function. */
69
+ subscribe: (listener: (state: EnableGpsArState) => void) => () => void;
70
+ /**
71
+ * Probe WebXR support and move `checking → ready | unsupported`. Call once on
72
+ * boot (and optionally on resume). No-op effect on permissions.
73
+ */
74
+ refreshSupport: () => Promise<void>;
75
+ /**
76
+ * In-gesture orchestration: request the configured permissions, start the
77
+ * sensor watches and `initAR`. Must be called synchronously from a user
78
+ * gesture so the permission prompts are allowed. Idempotent while
79
+ * `starting`/`running`/`stopping`.
80
+ */
81
+ enable: (config: EnableGpsArConfig) => Promise<EnableGpsArResult>;
82
+ /**
83
+ * Tear down the running AR session: stop sensor watches, end the WebXR
84
+ * session, and transition `running → stopping → ready` so the user can
85
+ * re-enter AR. No-op when not `running`.
86
+ */
87
+ disable: () => Promise<void>;
88
+ }
89
+ /**
90
+ * Create an "Enable GPS AR" controller. Pass partial `deps` in tests to inject
91
+ * fakes; production callers use the defaults.
92
+ */
93
+ declare function createEnableGpsArController(deps?: Partial<EnableGpsArDeps>): EnableGpsArController;
94
+ //#endregion
95
+ export { EnableGpsArState as a, EnableGpsArResult as i, EnableGpsArController as n, EnableGpsArStatus as o, EnableGpsArDeps as r, createEnableGpsArController as s, EnableGpsArConfig as t };
@@ -1,4 +1,4 @@
1
- import { n as SessionMetadata } from "./opfs-storage-Dlq1I_Gb.js";
1
+ import { n as SessionMetadata } from "./opfs-storage-LsLY6VZV.js";
2
2
 
3
3
  //#region ../src/storage/file-system.d.ts
4
4
  /**
@@ -80,5 +80,35 @@ declare function setCurrentScenario(scenarioName: string): Promise<FileSystemDir
80
80
  * Legacy: used during OPFS recovery.
81
81
  */
82
82
  declare function ensureScenarioDirectory(scenarioName: string): Promise<FileSystemDirectoryHandle | null>;
83
+ /**
84
+ * Result of clearing the reference-point cache across all scenarios.
85
+ */
86
+ interface ClearRefPointsCacheResult {
87
+ /** Number of scenarios whose `refPoints/` directory was deleted. */
88
+ readonly scenariosCleared: number;
89
+ /** Total number of scenarios scanned (including ones with no cache). */
90
+ readonly scenariosScanned: number;
91
+ /** Names of scenarios that failed to clear, with reason. */
92
+ readonly errors: {
93
+ scenarioName: string;
94
+ reason: string;
95
+ }[];
96
+ }
97
+ /**
98
+ * Clear the cached `refPoints/` directory for every scenario in OPFS.
99
+ *
100
+ * Used by the "Clear Reference Point Cache" maintenance action so that the
101
+ * next scenario load re-imports ref points from the read folder's `*.zip`
102
+ * recordings (see ref-point-recovery in the recorder app).
103
+ *
104
+ * Failures for individual scenarios are collected in `errors` rather than
105
+ * aborting the whole operation — partial progress is still useful.
106
+ *
107
+ * @throws Error if OPFS storage is unavailable (e.g. `initStorage()` not yet
108
+ * called, or browser does not support OPFS). Surfacing this loudly avoids
109
+ * reporting a silent "0 scenarios cleared" success that would mask the
110
+ * real failure to the user.
111
+ */
112
+ declare function clearRefPointsCacheForAllScenarios(): Promise<ClearRefPointsCacheResult>;
83
113
  //#endregion
84
- export { listSessions as a, setCurrentScenario as c, writeAction as d, writeFrame as f, initStorage as i, startSession as l, ensureScenarioDirectory as n, resetForNewSession as o, writeSessionMetadata as p, getCurrentScenarioHandle as r, resetStorageState as s, WriteAccessResult as t, verifyWriteAccess as u };
114
+ export { getCurrentScenarioHandle as a, resetForNewSession as c, startSession as d, verifyWriteAccess as f, writeSessionMetadata as h, ensureScenarioDirectory as i, resetStorageState as l, writeFrame as m, WriteAccessResult as n, initStorage as o, writeAction as p, clearRefPointsCacheForAllScenarios as r, listSessions as s, ClearRefPointsCacheResult as t, setCurrentScenario as u };