gps-plus-slam-app-framework 1.0.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 (200) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +222 -0
  3. package/dist/alignment-lerper-D9BeDwZX.d.ts +29 -0
  4. package/dist/app-selectors-DyMzxCEC.d.ts +140 -0
  5. package/dist/ar/camera-blit-capture.d.ts +2 -0
  6. package/dist/ar/camera-blit-capture.js +253 -0
  7. package/dist/ar/capture-failure-tracker.d.ts +2 -0
  8. package/dist/ar/capture-failure-tracker.js +45 -0
  9. package/dist/ar/chromium-camera-access-workaround.d.ts +2 -0
  10. package/dist/ar/chromium-camera-access-workaround.js +32 -0
  11. package/dist/ar/depth-sampler.d.ts +3 -0
  12. package/dist/ar/depth-sampler.js +147 -0
  13. package/dist/ar/image-capture.d.ts +2 -0
  14. package/dist/ar/image-capture.js +152 -0
  15. package/dist/ar/index.d.ts +12 -0
  16. package/dist/ar/index.js +12 -0
  17. package/dist/ar/replay-scene.d.ts +2 -0
  18. package/dist/ar/replay-scene.js +325 -0
  19. package/dist/ar/scene-node-names.d.ts +2 -0
  20. package/dist/ar/scene-node-names.js +16 -0
  21. package/dist/ar/tracking-state.d.ts +2 -0
  22. package/dist/ar/tracking-state.js +164 -0
  23. package/dist/ar/webxr-session.d.ts +4 -0
  24. package/dist/ar/webxr-session.js +890 -0
  25. package/dist/ar/xr-camera-texture.d.ts +2 -0
  26. package/dist/ar/xr-camera-texture.js +39 -0
  27. package/dist/ar/xr-error-handler.d.ts +2 -0
  28. package/dist/ar/xr-error-handler.js +37 -0
  29. package/dist/ar-types-B-ORgk6Z.d.ts +82 -0
  30. package/dist/camera-blit-capture-DHuyrrxr.d.ts +108 -0
  31. package/dist/camera-follower-BMqPddxx.d.ts +29 -0
  32. package/dist/capture-failure-tracker-2Q6oI2uQ.d.ts +52 -0
  33. package/dist/chromium-camera-access-workaround-CU5zSKNr.d.ts +61 -0
  34. package/dist/community-license-key-ChZLCJyO.d.ts +21 -0
  35. package/dist/concurrency-p6gB30fT.d.ts +24 -0
  36. package/dist/css3d-renderer-manager-rgLMVAvd.d.ts +23 -0
  37. package/dist/depth-sampler-BNCtnEoP.d.ts +108 -0
  38. package/dist/failure-tracker-1sQ_Cgyw.d.ts +49 -0
  39. package/dist/file-system-BsQgYCU3.d.ts +128 -0
  40. package/dist/file-system-utils-5cWO8Xyv.d.ts +24 -0
  41. package/dist/format-file-size-onGq0k1Q.d.ts +24 -0
  42. package/dist/fused-path-DtqCSqJh.d.ts +25 -0
  43. package/dist/geo-types-Xx-LVcnw.d.ts +29 -0
  44. package/dist/gps-Ddzr2KlX.d.ts +54 -0
  45. package/dist/gps-compass-cubes-C-6JEnpR.d.ts +22 -0
  46. package/dist/gps-error-handler-VPuNOuf8.d.ts +40 -0
  47. package/dist/gps-event-markers-DpEy2qRd.d.ts +67 -0
  48. package/dist/h3-ref-point-CFhayNSZ.d.ts +59 -0
  49. package/dist/image-capture-2pKjYUS6.d.ts +130 -0
  50. package/dist/index.d.ts +56 -0
  51. package/dist/index.js +61 -0
  52. package/dist/leaflet-map-overlay-CvfQXTye.d.ts +114 -0
  53. package/dist/lerp-utils-87NWjUOD.d.ts +20 -0
  54. package/dist/licensing/community-license-key.d.ts +2 -0
  55. package/dist/licensing/community-license-key.js +21 -0
  56. package/dist/licensing/index.d.ts +2 -0
  57. package/dist/licensing/index.js +2 -0
  58. package/dist/list-formatter-DKQQVLcl.d.ts +14 -0
  59. package/dist/logger-B81iwxx0.d.ts +74 -0
  60. package/dist/map-overlay-DuiZuCTx.d.ts +153 -0
  61. package/dist/null-storage-backend-CsWvQwN8.d.ts +11 -0
  62. package/dist/opfs-storage-ChOzF_Wp.d.ts +181 -0
  63. package/dist/opfs-storage-backend-CVcmfJHN.d.ts +11 -0
  64. package/dist/permission-checker-jO2ziCWC.d.ts +146 -0
  65. package/dist/persistence-middleware-DrptY02i.d.ts +31 -0
  66. package/dist/recorder-slice-fcwAXrsh.d.ts +35 -0
  67. package/dist/recording-coordinator-DzflP07_.d.ts +81 -0
  68. package/dist/recording-options-BYUFX8iU.d.ts +166 -0
  69. package/dist/recording-replayer-oOzPITrd.d.ts +32 -0
  70. package/dist/ref-point-importer-B_wn5ABk.d.ts +62 -0
  71. package/dist/ref-point-loader-Pt1smgHS.d.ts +117 -0
  72. package/dist/ref-points/h3-ref-point.d.ts +2 -0
  73. package/dist/ref-points/h3-ref-point.js +74 -0
  74. package/dist/ref-points/index.d.ts +2 -0
  75. package/dist/ref-points/index.js +2 -0
  76. package/dist/ref-points-slice-tC-Wd6XJ.d.ts +48 -0
  77. package/dist/reference-points-CFWy8_wj.d.ts +68 -0
  78. package/dist/replay-engine-DuX316ae.d.ts +103 -0
  79. package/dist/replay-scene-DtUm6bsr.d.ts +109 -0
  80. package/dist/routing-slice-BlHTM8eh.d.ts +23 -0
  81. package/dist/scene-node-names-DPsaE2z3.d.ts +14 -0
  82. package/dist/sensors/gps-error-handler.d.ts +2 -0
  83. package/dist/sensors/gps-error-handler.js +53 -0
  84. package/dist/sensors/gps.d.ts +2 -0
  85. package/dist/sensors/gps.js +93 -0
  86. package/dist/sensors/index.d.ts +4 -0
  87. package/dist/sensors/index.js +4 -0
  88. package/dist/sensors/permission-checker.d.ts +2 -0
  89. package/dist/sensors/permission-checker.js +397 -0
  90. package/dist/state/app-selectors.d.ts +2 -0
  91. package/dist/state/app-selectors.js +35 -0
  92. package/dist/state/index.d.ts +17 -0
  93. package/dist/state/index.js +13 -0
  94. package/dist/state/persistence-middleware.d.ts +2 -0
  95. package/dist/state/persistence-middleware.js +71 -0
  96. package/dist/state/recorder-slice.d.ts +2 -0
  97. package/dist/state/recorder-slice.js +47 -0
  98. package/dist/state/recording-coordinator.d.ts +2 -0
  99. package/dist/state/recording-coordinator.js +150 -0
  100. package/dist/state/recording-options.d.ts +2 -0
  101. package/dist/state/recording-options.js +192 -0
  102. package/dist/state/recording-replayer.d.ts +2 -0
  103. package/dist/state/recording-replayer.js +39 -0
  104. package/dist/state/ref-points-slice.d.ts +2 -0
  105. package/dist/state/ref-points-slice.js +44 -0
  106. package/dist/state/replay-engine.d.ts +2 -0
  107. package/dist/state/replay-engine.js +230 -0
  108. package/dist/state/routing-slice.d.ts +2 -0
  109. package/dist/state/routing-slice.js +13 -0
  110. package/dist/state/store-subscribers.d.ts +3 -0
  111. package/dist/state/store-subscribers.js +97 -0
  112. package/dist/state/store.d.ts +9 -0
  113. package/dist/state/store.js +71 -0
  114. package/dist/state/subscribe-to-selector.d.ts +2 -0
  115. package/dist/state/subscribe-to-selector.js +26 -0
  116. package/dist/storage/file-system-utils.d.ts +2 -0
  117. package/dist/storage/file-system-utils.js +31 -0
  118. package/dist/storage/file-system.d.ts +2 -0
  119. package/dist/storage/file-system.js +229 -0
  120. package/dist/storage/index.d.ts +11 -0
  121. package/dist/storage/index.js +10 -0
  122. package/dist/storage/null-storage-backend.d.ts +2 -0
  123. package/dist/storage/null-storage-backend.js +8 -0
  124. package/dist/storage/opfs-storage-backend.d.ts +2 -0
  125. package/dist/storage/opfs-storage-backend.js +15 -0
  126. package/dist/storage/opfs-storage.d.ts +2 -0
  127. package/dist/storage/opfs-storage.js +242 -0
  128. package/dist/storage/ref-point-importer.d.ts +2 -0
  129. package/dist/storage/ref-point-importer.js +163 -0
  130. package/dist/storage/ref-point-loader.d.ts +2 -0
  131. package/dist/storage/ref-point-loader.js +248 -0
  132. package/dist/storage/ref-point-recovery.d.ts +28 -0
  133. package/dist/storage/ref-point-recovery.js +159 -0
  134. package/dist/storage/storage-backend.d.ts +2 -0
  135. package/dist/storage/storage-backend.js +1 -0
  136. package/dist/storage/zip-export.d.ts +2 -0
  137. package/dist/storage/zip-export.js +214 -0
  138. package/dist/storage/zip-reader.d.ts +2 -0
  139. package/dist/storage/zip-reader.js +190 -0
  140. package/dist/storage-backend-BcEItnFr.d.ts +20 -0
  141. package/dist/store-C7PKOj8S.d.ts +96 -0
  142. package/dist/store-subscribers-CuoIzB5T.d.ts +77 -0
  143. package/dist/subscribe-to-selector-UTZ0KkAc.d.ts +26 -0
  144. package/dist/test-utils/browser-mocks.d.ts +294 -0
  145. package/dist/test-utils/browser-mocks.js +568 -0
  146. package/dist/test-utils/zip-round-trip-helpers.d.ts +60 -0
  147. package/dist/test-utils/zip-round-trip-helpers.js +207 -0
  148. package/dist/three-dispose-CCBHjE_a.d.ts +30 -0
  149. package/dist/tracking-state-B9QfuZCg.d.ts +101 -0
  150. package/dist/types/ar-types.d.ts +2 -0
  151. package/dist/types/ar-types.js +1 -0
  152. package/dist/types/geo-types.d.ts +2 -0
  153. package/dist/types/geo-types.js +1 -0
  154. package/dist/types/index.d.ts +3 -0
  155. package/dist/types/index.js +1 -0
  156. package/dist/utils/concurrency.d.ts +2 -0
  157. package/dist/utils/concurrency.js +40 -0
  158. package/dist/utils/failure-tracker.d.ts +2 -0
  159. package/dist/utils/failure-tracker.js +48 -0
  160. package/dist/utils/format-file-size.d.ts +2 -0
  161. package/dist/utils/format-file-size.js +41 -0
  162. package/dist/utils/fused-path.d.ts +2 -0
  163. package/dist/utils/fused-path.js +44 -0
  164. package/dist/utils/index.d.ts +7 -0
  165. package/dist/utils/index.js +7 -0
  166. package/dist/utils/list-formatter.d.ts +2 -0
  167. package/dist/utils/list-formatter.js +17 -0
  168. package/dist/utils/logger.d.ts +2 -0
  169. package/dist/utils/logger.js +226 -0
  170. package/dist/vis-colors-Qi2vlRGt.d.ts +63 -0
  171. package/dist/visualization/alignment-lerper.d.ts +2 -0
  172. package/dist/visualization/alignment-lerper.js +68 -0
  173. package/dist/visualization/camera-follower.d.ts +2 -0
  174. package/dist/visualization/camera-follower.js +51 -0
  175. package/dist/visualization/css3d-renderer-manager.d.ts +2 -0
  176. package/dist/visualization/css3d-renderer-manager.js +41 -0
  177. package/dist/visualization/gps-compass-cubes.d.ts +2 -0
  178. package/dist/visualization/gps-compass-cubes.js +129 -0
  179. package/dist/visualization/gps-event-markers.d.ts +2 -0
  180. package/dist/visualization/gps-event-markers.js +159 -0
  181. package/dist/visualization/index.d.ts +12 -0
  182. package/dist/visualization/index.js +12 -0
  183. package/dist/visualization/leaflet-map-overlay.d.ts +2 -0
  184. package/dist/visualization/leaflet-map-overlay.js +313 -0
  185. package/dist/visualization/lerp-utils.d.ts +2 -0
  186. package/dist/visualization/lerp-utils.js +22 -0
  187. package/dist/visualization/map-overlay.d.ts +2 -0
  188. package/dist/visualization/map-overlay.js +241 -0
  189. package/dist/visualization/reference-points.d.ts +2 -0
  190. package/dist/visualization/reference-points.js +160 -0
  191. package/dist/visualization/three-dispose.d.ts +2 -0
  192. package/dist/visualization/three-dispose.js +55 -0
  193. package/dist/visualization/vis-colors.d.ts +2 -0
  194. package/dist/visualization/vis-colors.js +74 -0
  195. package/dist/webxr-session-COlSrXdL.d.ts +316 -0
  196. package/dist/xr-camera-texture-BbukNE79.d.ts +53 -0
  197. package/dist/xr-error-handler-DTHfmvrl.d.ts +24 -0
  198. package/dist/zip-export-Rtpi75JJ.d.ts +87 -0
  199. package/dist/zip-reader-D7pkpX8K.d.ts +97 -0
  200. package/package.json +104 -0
@@ -0,0 +1,53 @@
1
+ import { createLogger } from "../utils/logger.js";
2
+ //#region ../src/sensors/gps-error-handler.ts
3
+ /**
4
+ * GPS Error Handler
5
+ *
6
+ * Provides user-facing error messages for GPS failures.
7
+ * Separates error handling logic from GPS module for testability.
8
+ */
9
+ const log = createLogger("GPSError");
10
+ /**
11
+ * GPS error codes from the Geolocation API.
12
+ * Duplicated here to avoid depending on browser types in tests.
13
+ */
14
+ const GPS_ERROR_CODES = {
15
+ PERMISSION_DENIED: 1,
16
+ POSITION_UNAVAILABLE: 2,
17
+ TIMEOUT: 3
18
+ };
19
+ /**
20
+ * User-friendly error messages for each GPS error type.
21
+ */
22
+ const GPS_ERROR_MESSAGES = {
23
+ [GPS_ERROR_CODES.PERMISSION_DENIED]: "GPS permission denied. Enable location access in your browser or device settings.",
24
+ [GPS_ERROR_CODES.POSITION_UNAVAILABLE]: "GPS position unavailable. Move outdoors for better signal.",
25
+ [GPS_ERROR_CODES.TIMEOUT]: "GPS timeout. Move outdoors or check that location services are enabled."
26
+ };
27
+ /**
28
+ * Default message for unknown error codes.
29
+ */
30
+ const GPS_ERROR_MESSAGE_UNKNOWN = "GPS error. Check your device settings.";
31
+ /**
32
+ * Get a user-friendly error message for a GPS error.
33
+ *
34
+ * @param error - The GeolocationPositionError from the browser API
35
+ * @returns A user-friendly error message
36
+ */
37
+ function getGpsErrorMessage(error) {
38
+ return GPS_ERROR_MESSAGES[error.code] ?? "GPS error. Check your device settings.";
39
+ }
40
+ /**
41
+ * Create a GPS error handler that logs and shows user-facing errors.
42
+ *
43
+ * @param showError - Function to display error to user (e.g., from hud.ts)
44
+ * @returns A function suitable for use as startGpsWatch's onError callback
45
+ */
46
+ function createGpsErrorHandler(showError) {
47
+ return (error) => {
48
+ log.error(`GPS error (code ${error.code}):`, error.message);
49
+ showError(getGpsErrorMessage(error));
50
+ };
51
+ }
52
+ //#endregion
53
+ export { GPS_ERROR_CODES, GPS_ERROR_MESSAGES, GPS_ERROR_MESSAGE_UNKNOWN, createGpsErrorHandler, getGpsErrorMessage };
@@ -0,0 +1,2 @@
1
+ import { a as startOrientationWatch, i as startGpsWatch, n as RawDeviceOrientation, o as stopGpsWatch, r as requestOrientationPermission, s as stopOrientationWatch, t as GpsPosition } from "../gps-Ddzr2KlX.js";
2
+ export { GpsPosition, RawDeviceOrientation, requestOrientationPermission, startGpsWatch, startOrientationWatch, stopGpsWatch, stopOrientationWatch };
@@ -0,0 +1,93 @@
1
+ import { createLogger } from "../utils/logger.js";
2
+ //#region ../src/sensors/gps.ts
3
+ /**
4
+ * GPS Module
5
+ *
6
+ * Handles Geolocation API access and device orientation/compass.
7
+ */
8
+ const log = createLogger("GPS");
9
+ let watchId = null;
10
+ let orientationHandler = null;
11
+ /**
12
+ * Start watching GPS position.
13
+ * Idempotent: clears any existing watch before starting a new one
14
+ * (Issue 4, 2026-02-27 user feedback — prevents watch leaks when
15
+ * transitioning from warm-up to recording watch).
16
+ */
17
+ function startGpsWatch(onPosition, onError) {
18
+ if (!navigator.geolocation) {
19
+ log.error("Geolocation API not available");
20
+ return;
21
+ }
22
+ stopGpsWatch();
23
+ watchId = navigator.geolocation.watchPosition((pos) => {
24
+ onPosition({
25
+ lat: pos.coords.latitude,
26
+ lon: pos.coords.longitude,
27
+ altitude: pos.coords.altitude,
28
+ accuracy: pos.coords.accuracy,
29
+ altitudeAccuracy: pos.coords.altitudeAccuracy,
30
+ heading: pos.coords.heading,
31
+ speed: pos.coords.speed,
32
+ timestamp: pos.timestamp
33
+ });
34
+ }, (err) => {
35
+ log.error("Error:", err.message);
36
+ onError?.(err);
37
+ }, {
38
+ enableHighAccuracy: true,
39
+ maximumAge: 0,
40
+ timeout: 1e4
41
+ });
42
+ log.info("Watch started");
43
+ }
44
+ /**
45
+ * Stop watching GPS position
46
+ */
47
+ function stopGpsWatch() {
48
+ if (watchId !== null) {
49
+ navigator.geolocation.clearWatch(watchId);
50
+ watchId = null;
51
+ log.info("Watch stopped");
52
+ }
53
+ }
54
+ /**
55
+ * Start listening for device orientation (compass)
56
+ */
57
+ function startOrientationWatch(onOrientation) {
58
+ stopOrientationWatch();
59
+ orientationHandler = (event) => {
60
+ onOrientation({
61
+ alpha: event.alpha,
62
+ beta: event.beta,
63
+ gamma: event.gamma,
64
+ absolute: event.absolute
65
+ });
66
+ };
67
+ window.addEventListener("deviceorientation", orientationHandler);
68
+ log.info("Orientation watch started");
69
+ }
70
+ /**
71
+ * Stop listening for device orientation
72
+ */
73
+ function stopOrientationWatch() {
74
+ if (orientationHandler) {
75
+ window.removeEventListener("deviceorientation", orientationHandler);
76
+ orientationHandler = null;
77
+ log.info("Orientation watch stopped");
78
+ }
79
+ }
80
+ /**
81
+ * Request permission for device orientation (required on iOS 13+)
82
+ */
83
+ async function requestOrientationPermission() {
84
+ const DeviceOrientationEventWithPermission = DeviceOrientationEvent;
85
+ if (typeof DeviceOrientationEventWithPermission.requestPermission === "function") try {
86
+ return await DeviceOrientationEventWithPermission.requestPermission() === "granted";
87
+ } catch {
88
+ return false;
89
+ }
90
+ return true;
91
+ }
92
+ //#endregion
93
+ export { requestOrientationPermission, startGpsWatch, startOrientationWatch, stopGpsWatch, stopOrientationWatch };
@@ -0,0 +1,4 @@
1
+ import { a as startOrientationWatch, i as startGpsWatch, n as RawDeviceOrientation, o as stopGpsWatch, r as requestOrientationPermission, s as stopOrientationWatch, t as GpsPosition } from "../gps-Ddzr2KlX.js";
2
+ import { a as getGpsErrorMessage, i as createGpsErrorHandler, n as GPS_ERROR_MESSAGES, r as GPS_ERROR_MESSAGE_UNKNOWN, t as GPS_ERROR_CODES } from "../gps-error-handler-VPuNOuf8.js";
3
+ import { a as checkFileSystemPermission, c as checkWebXRSupport, d as requestGeolocationPermission, f as requestOrientationPermission$1, h as setFileSystemState, i as checkCameraPermission, l as requestAllPermissions, m as resetFileSystemState, n as PermissionStatus, o as checkGeolocationPermission, p as requestWebXRWithDepthPermission, r as checkAllPermissions, s as checkOrientationPermission, t as PermissionCheckResult, u as requestCameraPermission } from "../permission-checker-jO2ziCWC.js";
4
+ export { GPS_ERROR_CODES, GPS_ERROR_MESSAGES, GPS_ERROR_MESSAGE_UNKNOWN, type GpsPosition, type PermissionCheckResult, type PermissionStatus, type RawDeviceOrientation, checkAllPermissions, checkCameraPermission, checkFileSystemPermission, checkGeolocationPermission, checkOrientationPermission, checkWebXRSupport, createGpsErrorHandler, getGpsErrorMessage, requestAllPermissions, requestCameraPermission, requestOrientationPermission as requestDeviceOrientationPermission, requestGeolocationPermission, requestOrientationPermission$1 as requestOrientationPermission, requestWebXRWithDepthPermission, resetFileSystemState, setFileSystemState, startGpsWatch, startOrientationWatch, stopGpsWatch, stopOrientationWatch };
@@ -0,0 +1,4 @@
1
+ import { checkAllPermissions, checkCameraPermission, checkFileSystemPermission, checkGeolocationPermission, checkOrientationPermission, checkWebXRSupport, requestAllPermissions, requestCameraPermission, requestGeolocationPermission, requestOrientationPermission as requestOrientationPermission$1, requestWebXRWithDepthPermission, resetFileSystemState, setFileSystemState } from "./permission-checker.js";
2
+ import { requestOrientationPermission, startGpsWatch, startOrientationWatch, stopGpsWatch, stopOrientationWatch } from "./gps.js";
3
+ import { GPS_ERROR_CODES, GPS_ERROR_MESSAGES, GPS_ERROR_MESSAGE_UNKNOWN, createGpsErrorHandler, getGpsErrorMessage } from "./gps-error-handler.js";
4
+ export { GPS_ERROR_CODES, GPS_ERROR_MESSAGES, GPS_ERROR_MESSAGE_UNKNOWN, checkAllPermissions, checkCameraPermission, checkFileSystemPermission, checkGeolocationPermission, checkOrientationPermission, checkWebXRSupport, createGpsErrorHandler, getGpsErrorMessage, requestAllPermissions, requestCameraPermission, requestOrientationPermission as requestDeviceOrientationPermission, requestGeolocationPermission, requestOrientationPermission$1 as requestOrientationPermission, requestWebXRWithDepthPermission, resetFileSystemState, setFileSystemState, startGpsWatch, startOrientationWatch, stopGpsWatch, stopOrientationWatch };
@@ -0,0 +1,2 @@
1
+ import { a as checkFileSystemPermission, c as checkWebXRSupport, d as requestGeolocationPermission, f as requestOrientationPermission, h as setFileSystemState, i as checkCameraPermission, l as requestAllPermissions, m as resetFileSystemState, n as PermissionStatus, o as checkGeolocationPermission, p as requestWebXRWithDepthPermission, r as checkAllPermissions, s as checkOrientationPermission, t as PermissionCheckResult, u as requestCameraPermission } from "../permission-checker-jO2ziCWC.js";
2
+ export { PermissionCheckResult, PermissionStatus, checkAllPermissions, checkCameraPermission, checkFileSystemPermission, checkGeolocationPermission, checkOrientationPermission, checkWebXRSupport, requestAllPermissions, requestCameraPermission, requestGeolocationPermission, requestOrientationPermission, requestWebXRWithDepthPermission, resetFileSystemState, setFileSystemState };
@@ -0,0 +1,397 @@
1
+ import { createLogger } from "../utils/logger.js";
2
+ //#region ../src/sensors/permission-checker.ts
3
+ /**
4
+ * Permission Checker Module
5
+ *
6
+ * Provides utilities to check and verify mandatory device permissions
7
+ * required for AR+GPS tracking: WebXR (immersive-ar), Camera, and Geolocation.
8
+ *
9
+ * This module is used by the setup modal to verify permissions BEFORE
10
+ * the user enters AR mode, providing clear feedback on what's missing.
11
+ */
12
+ const log = createLogger("PermissionChecker");
13
+ let fileSystemState = {
14
+ folderSelected: false,
15
+ writeVerified: false
16
+ };
17
+ /**
18
+ * Reset file system permission state.
19
+ * Exported for testing purposes.
20
+ * @internal
21
+ */
22
+ function resetFileSystemState() {
23
+ fileSystemState = {
24
+ folderSelected: false,
25
+ writeVerified: false
26
+ };
27
+ }
28
+ /**
29
+ * Set file system permission state.
30
+ * Used by the storage module after folder selection and write verification.
31
+ * @internal
32
+ */
33
+ function setFileSystemState(state) {
34
+ fileSystemState = {
35
+ ...fileSystemState,
36
+ ...state
37
+ };
38
+ }
39
+ /**
40
+ * Check file system access permission status.
41
+ *
42
+ * User Feedback Issue #1: File system access is critical for recording.
43
+ * This function checks:
44
+ * 1. If OPFS (Origin Private File System) is available
45
+ * 2. If storage has been initialized
46
+ * 3. If write access has been verified
47
+ *
48
+ * Note: We now use OPFS instead of showDirectoryPicker because it works
49
+ * consistently on Android Chrome, iOS Safari, and Desktop browsers.
50
+ *
51
+ * @returns Permission status for file system access
52
+ */
53
+ function checkFileSystemPermission() {
54
+ if (typeof navigator === "undefined" || !navigator.storage || typeof navigator.storage.getDirectory !== "function") return {
55
+ supported: false,
56
+ granted: null,
57
+ error: "Origin Private File System (OPFS) not supported. Use Chrome 86+, Safari 15.2+, or Firefox 111+."
58
+ };
59
+ if (!fileSystemState.folderSelected) return {
60
+ supported: true,
61
+ granted: null
62
+ };
63
+ if (!fileSystemState.writeVerified) return {
64
+ supported: true,
65
+ granted: false,
66
+ error: fileSystemState.writeError || "Storage write failed. Please try again."
67
+ };
68
+ return {
69
+ supported: true,
70
+ granted: true
71
+ };
72
+ }
73
+ /**
74
+ * Check if WebXR immersive-ar mode is supported.
75
+ * Does not request a session, only checks support.
76
+ */
77
+ async function checkWebXRSupport() {
78
+ if (!navigator.xr) return {
79
+ supported: false,
80
+ granted: null,
81
+ error: "WebXR API not available. Use a compatible browser like Chrome on Android."
82
+ };
83
+ try {
84
+ if (!await navigator.xr.isSessionSupported("immersive-ar")) return {
85
+ supported: false,
86
+ granted: null,
87
+ error: "AR mode not supported. Ensure you have ARCore/ARKit installed."
88
+ };
89
+ return {
90
+ supported: true,
91
+ granted: true
92
+ };
93
+ } catch (err) {
94
+ log.error("WebXR support check failed:", err);
95
+ return {
96
+ supported: false,
97
+ granted: null,
98
+ error: "Failed to check AR support. Please refresh and try again."
99
+ };
100
+ }
101
+ }
102
+ /**
103
+ * Check geolocation permission status without triggering a prompt.
104
+ * Uses the Permissions API if available, otherwise returns unknown state.
105
+ */
106
+ async function checkGeolocationPermission() {
107
+ if (!navigator.geolocation) return {
108
+ supported: false,
109
+ granted: null,
110
+ error: "Geolocation API not available in this browser."
111
+ };
112
+ if (navigator.permissions) try {
113
+ const result = await navigator.permissions.query({ name: "geolocation" });
114
+ if (result.state === "granted") return {
115
+ supported: true,
116
+ granted: true
117
+ };
118
+ else if (result.state === "denied") return {
119
+ supported: true,
120
+ granted: false,
121
+ error: "Location access denied. Please enable in browser settings."
122
+ };
123
+ return {
124
+ supported: true,
125
+ granted: null
126
+ };
127
+ } catch {}
128
+ return {
129
+ supported: true,
130
+ granted: null
131
+ };
132
+ }
133
+ /**
134
+ * Request geolocation permission by triggering a position request.
135
+ * This will show the browser's permission prompt if not already granted.
136
+ *
137
+ * @param timeoutMs - Maximum time to wait for position (default 10s)
138
+ * @returns Updated permission status after request
139
+ */
140
+ async function requestGeolocationPermission(timeoutMs = 1e4) {
141
+ if (!navigator.geolocation) return {
142
+ supported: false,
143
+ granted: null,
144
+ error: "Geolocation API not available in this browser."
145
+ };
146
+ return new Promise((resolve) => {
147
+ navigator.geolocation.getCurrentPosition(() => {
148
+ log.info("Geolocation permission granted");
149
+ resolve({
150
+ supported: true,
151
+ granted: true
152
+ });
153
+ }, (error) => {
154
+ log.warn("Geolocation error:", error.message);
155
+ if (error.code === error.PERMISSION_DENIED) resolve({
156
+ supported: true,
157
+ granted: false,
158
+ error: "Location access denied. Please enable in browser settings."
159
+ });
160
+ else if (error.code === error.POSITION_UNAVAILABLE) resolve({
161
+ supported: true,
162
+ granted: null,
163
+ error: "Location unavailable. Check GPS is enabled on your device."
164
+ });
165
+ else resolve({
166
+ supported: true,
167
+ granted: null,
168
+ error: "Location request timed out. Please try again."
169
+ });
170
+ }, {
171
+ enableHighAccuracy: true,
172
+ timeout: timeoutMs,
173
+ maximumAge: 0
174
+ });
175
+ });
176
+ }
177
+ /**
178
+ * Check camera permission status without triggering a prompt.
179
+ * Uses the Permissions API if available.
180
+ */
181
+ async function checkCameraPermission() {
182
+ if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) return {
183
+ supported: false,
184
+ granted: null,
185
+ error: "Camera API not available. Use HTTPS and a modern browser."
186
+ };
187
+ if (navigator.permissions) try {
188
+ const result = await navigator.permissions.query({ name: "camera" });
189
+ if (result.state === "granted") return {
190
+ supported: true,
191
+ granted: true
192
+ };
193
+ else if (result.state === "denied") return {
194
+ supported: true,
195
+ granted: false,
196
+ error: "Camera access denied. Please enable in browser settings."
197
+ };
198
+ return {
199
+ supported: true,
200
+ granted: null
201
+ };
202
+ } catch {}
203
+ return {
204
+ supported: true,
205
+ granted: null
206
+ };
207
+ }
208
+ /**
209
+ * Request camera permission by triggering getUserMedia.
210
+ * This will show the browser's permission prompt if not already granted.
211
+ *
212
+ * @returns Updated permission status after request
213
+ */
214
+ async function requestCameraPermission() {
215
+ if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) return {
216
+ supported: false,
217
+ granted: null,
218
+ error: "Camera API not available. Use HTTPS and a modern browser."
219
+ };
220
+ try {
221
+ const stream = await navigator.mediaDevices.getUserMedia({ video: true });
222
+ for (const track of stream.getTracks()) track.stop();
223
+ log.info("Camera permission granted");
224
+ return {
225
+ supported: true,
226
+ granted: true
227
+ };
228
+ } catch (err) {
229
+ log.warn("Camera permission error:", err);
230
+ const error = err;
231
+ if (error.name === "NotAllowedError") return {
232
+ supported: true,
233
+ granted: false,
234
+ error: "Camera access denied. Please enable in browser settings."
235
+ };
236
+ else if (error.name === "NotFoundError") return {
237
+ supported: false,
238
+ granted: null,
239
+ error: "No camera found on this device."
240
+ };
241
+ return {
242
+ supported: true,
243
+ granted: null,
244
+ error: "Camera access failed. Please try again."
245
+ };
246
+ }
247
+ }
248
+ /**
249
+ * Check device orientation permission status.
250
+ * On iOS 13+, this requires explicit permission request.
251
+ */
252
+ function checkOrientationPermission() {
253
+ if (typeof DeviceOrientationEvent === "undefined") return Promise.resolve({
254
+ supported: false,
255
+ granted: null,
256
+ error: "Device orientation not supported."
257
+ });
258
+ if (typeof DeviceOrientationEvent.requestPermission === "function") return Promise.resolve({
259
+ supported: true,
260
+ granted: null
261
+ });
262
+ return Promise.resolve({
263
+ supported: true,
264
+ granted: true
265
+ });
266
+ }
267
+ /**
268
+ * Request device orientation permission (iOS 13+).
269
+ * On other platforms, this is a no-op that returns granted.
270
+ */
271
+ async function requestOrientationPermission() {
272
+ if (typeof DeviceOrientationEvent === "undefined") return {
273
+ supported: false,
274
+ granted: null,
275
+ error: "Device orientation not supported."
276
+ };
277
+ const DeviceOrientationEventWithPermission = DeviceOrientationEvent;
278
+ if (typeof DeviceOrientationEventWithPermission.requestPermission === "function") try {
279
+ if (await DeviceOrientationEventWithPermission.requestPermission() === "granted") {
280
+ log.info("Orientation permission granted");
281
+ return {
282
+ supported: true,
283
+ granted: true
284
+ };
285
+ } else return {
286
+ supported: true,
287
+ granted: false,
288
+ error: "Motion & orientation access denied."
289
+ };
290
+ } catch {
291
+ return {
292
+ supported: true,
293
+ granted: null,
294
+ error: "Orientation permission request failed."
295
+ };
296
+ }
297
+ return {
298
+ supported: true,
299
+ granted: true
300
+ };
301
+ }
302
+ /**
303
+ * Check all permissions without triggering any prompts.
304
+ * Returns current known state of each permission.
305
+ */
306
+ async function checkAllPermissions() {
307
+ const [webxr, geolocation, camera, orientation] = await Promise.all([
308
+ checkWebXRSupport(),
309
+ checkGeolocationPermission(),
310
+ checkCameraPermission(),
311
+ checkOrientationPermission()
312
+ ]);
313
+ const fileSystem = checkFileSystemPermission();
314
+ return {
315
+ webxr,
316
+ geolocation,
317
+ camera,
318
+ orientation,
319
+ fileSystem,
320
+ allMandatoryReady: webxr.supported && webxr.granted === true && geolocation.supported && geolocation.granted === true && camera.supported && camera.granted === true && fileSystem.supported && fileSystem.granted === true
321
+ };
322
+ }
323
+ /**
324
+ * Request all mandatory permissions that haven't been granted yet.
325
+ * Shows browser prompts for each permission that needs requesting.
326
+ *
327
+ * This now includes the WebXR+Depth probe to trigger the "3D map" permission
328
+ * upfront, rather than surprising users with a second prompt after "Enter AR".
329
+ *
330
+ * @returns Updated permission check result after requests
331
+ */
332
+ async function requestAllPermissions() {
333
+ const result = await checkAllPermissions();
334
+ if (result.webxr.supported) result.webxr = await requestWebXRWithDepthPermission();
335
+ if (result.geolocation.supported && result.geolocation.granted !== true) result.geolocation = await requestGeolocationPermission();
336
+ if (result.camera.supported && result.camera.granted !== true) result.camera = await requestCameraPermission();
337
+ if (result.orientation.supported && result.orientation.granted !== true) result.orientation = await requestOrientationPermission();
338
+ result.fileSystem = checkFileSystemPermission();
339
+ result.allMandatoryReady = result.webxr.supported && result.webxr.granted === true && result.geolocation.supported && result.geolocation.granted === true && result.camera.supported && result.camera.granted === true && result.fileSystem.supported && result.fileSystem.granted === true;
340
+ return result;
341
+ }
342
+ /**
343
+ * Request WebXR permission with depth-sensing by starting a probe session.
344
+ *
345
+ * The depth-sensing permission (ARCore's "3D map of surroundings") is only
346
+ * triggered when an XR session is actually started with depth-sensing options.
347
+ * This function starts a minimal probe session to trigger the permission prompt,
348
+ * then immediately ends it.
349
+ *
350
+ * This allows the app to request all AR permissions upfront during the
351
+ * setup flow, rather than surprising users with a second prompt when
352
+ * they click "Enter AR".
353
+ *
354
+ * @returns Permission status indicating if AR+depth access was granted
355
+ */
356
+ async function requestWebXRWithDepthPermission() {
357
+ if (!navigator.xr) return {
358
+ supported: false,
359
+ granted: null,
360
+ error: "WebXR not available"
361
+ };
362
+ try {
363
+ const session = await navigator.xr.requestSession("immersive-ar", {
364
+ requiredFeatures: ["local-floor"],
365
+ optionalFeatures: ["depth-sensing"],
366
+ depthSensing: {
367
+ usagePreference: ["cpu-optimized"],
368
+ dataFormatPreference: ["luminance-alpha", "float32"]
369
+ }
370
+ });
371
+ try {
372
+ await session.end();
373
+ } catch (endError) {
374
+ log.warn("Probe session end failed (permission still granted):", endError);
375
+ }
376
+ log.info("WebXR with depth-sensing permission granted");
377
+ return {
378
+ supported: true,
379
+ granted: true
380
+ };
381
+ } catch (err) {
382
+ const error = err;
383
+ log.warn("WebXR depth probe failed:", error);
384
+ if (error.name === "NotAllowedError") return {
385
+ supported: true,
386
+ granted: false,
387
+ error: "AR access denied"
388
+ };
389
+ return {
390
+ supported: false,
391
+ granted: null,
392
+ error: error.message
393
+ };
394
+ }
395
+ }
396
+ //#endregion
397
+ export { checkAllPermissions, checkCameraPermission, checkFileSystemPermission, checkGeolocationPermission, checkOrientationPermission, checkWebXRSupport, requestAllPermissions, requestCameraPermission, requestGeolocationPermission, requestOrientationPermission, requestWebXRWithDepthPermission, resetFileSystemState, setFileSystemState };
@@ -0,0 +1,2 @@
1
+ import { a as selectReferencePoints, i as selectOdometryRotations, n as selectGpsPositions, o as selectZeroReference, r as selectOdometryPositions, t as selectAlignmentMatrix } from "../app-selectors-DyMzxCEC.js";
2
+ export { selectAlignmentMatrix, selectGpsPositions, selectOdometryPositions, selectOdometryRotations, selectReferencePoints, selectZeroReference };
@@ -0,0 +1,35 @@
1
+ import { createSelector } from "@reduxjs/toolkit";
2
+ //#region ../src/state/app-selectors.ts
3
+ /**
4
+ * App-level memoized selectors for CombinedRootState.
5
+ *
6
+ * Wraps library getter functions with createSelector (RTK/reselect) for
7
+ * standard memoization. The library getters already return stable references
8
+ * via immutable state, but createSelector adds:
9
+ * - Explicit memoization contract (input comparison → cached output)
10
+ * - Consistent select* naming convention matching selectCachedKnownRefPoints
11
+ * - Composition-ready building blocks for derived selectors
12
+ *
13
+ * Used by subscribeToSelector in store-subscribers.ts for change detection.
14
+ *
15
+ * @see docs/2026-04-07-architecture-observations-consolidated.md §1
16
+ */
17
+ const EMPTY_GPS_POSITIONS = [];
18
+ const EMPTY_ODOM_POSITIONS = [];
19
+ const EMPTY_ODOM_ROTATIONS = [];
20
+ const EMPTY_REF_POINTS = [];
21
+ const selectGpsData = (state) => state.gpsData;
22
+ /** Alignment matrix (4×4), or null if not yet computed. */
23
+ const selectAlignmentMatrix = createSelector([selectGpsData], (gpsData) => gpsData?.gpsEvents?.alignmentMatrix ?? null);
24
+ /** Recorded GPS positions with metadata. */
25
+ const selectGpsPositions = createSelector([selectGpsData], (gpsData) => gpsData?.gpsEvents?.gpsPositions ?? EMPTY_GPS_POSITIONS);
26
+ /** Recorded odometry positions (AR-local space). */
27
+ const selectOdometryPositions = createSelector([selectGpsData], (gpsData) => gpsData?.gpsEvents?.odometryPositions ?? EMPTY_ODOM_POSITIONS);
28
+ /** Recorded odometry rotations (AR-local space). */
29
+ const selectOdometryRotations = createSelector([selectGpsData], (gpsData) => gpsData?.gpsEvents?.odometryRotations ?? EMPTY_ODOM_ROTATIONS);
30
+ /** GPS zero reference (origin for coordinate conversion), or null. */
31
+ const selectZeroReference = createSelector([selectGpsData], (gpsData) => gpsData?.zero ?? null);
32
+ /** User-defined reference points for ground truth validation. */
33
+ const selectReferencePoints = createSelector([selectGpsData], (gpsData) => gpsData?.referencePoints ?? EMPTY_REF_POINTS);
34
+ //#endregion
35
+ export { selectAlignmentMatrix, selectGpsPositions, selectOdometryPositions, selectOdometryRotations, selectReferencePoints, selectZeroReference };
@@ -0,0 +1,17 @@
1
+ import { i as DepthSample, r as DepthPoint } from "../ar-types-B-ORgk6Z.js";
2
+ import { _ as validateRecordingOptions, a as IMAGE_CONSTRAINTS, c as RecordingOptionsInput, d as loadRecordingOptions, f as resetRecordingOptions, g as validateImageOptions, h as validateDepthOptions, i as DepthCaptureOptions, l as STORAGE_KEY, n as DEFAULT_RECORDING_OPTIONS, o as ImageCaptureOptions, p as saveRecordingOptions, r as DEPTH_CONSTRAINTS, s as RecordingOptions, u as cloneRecordingOptions } from "../recording-options-BYUFX8iU.js";
3
+ import { n as SessionMetadata } from "../opfs-storage-ChOzF_Wp.js";
4
+ import { t as StorageBackend } from "../storage-backend-BcEItnFr.js";
5
+ import { a as recordWriteFailure, c as startSession, i as recordDepthSample, n as SessionMetadata$1, o as recorderReducer, r as endSession, s as setCurrentScenarioName, t as RecorderState } from "../recorder-slice-fcwAXrsh.js";
6
+ import { a as resetRefPointsState, i as refPointsReducer, n as clearSessionRefPointUsage, o as selectCachedKnownRefPoints, r as incrementRefPointUsage, s as setImportedRefPoints, t as RefPointsState } from "../ref-points-slice-tC-Wd6XJ.js";
7
+ import { i as routingReducer, n as RoutingState, r as navigateTo, t as AppScreen } from "../routing-slice-BlHTM8eh.js";
8
+ import { n as RefPointMark } from "../ref-point-loader-Pt1smgHS.js";
9
+ import { _ as setZeroPos, a as MarkReferencePointPayload, c as RecordGpsEventPayload, d as RootState, f as add2dImage, g as recordGpsEvent, h as markReferencePoint, i as LatLong, l as RecorderStore, m as createRecorderStore, n as CombinedRootState, o as RawDeviceOrientation, p as calcRelativeCoordsInMeters, r as GpsPoint, s as RawGpsPoint, t as AppDispatch, u as RecorderStoreOptions } from "../store-C7PKOj8S.js";
10
+ import { a as eulerToQuaternion, c as getLastDeviceOrientation, i as createGpsPositionHandler, l as resetCoordinatorState, n as buildRawGpsPoint, o as extractOdomPosition, r as buildRecordGpsEventPayload, s as extractOdomRotation, t as RecordingCoordinatorConfig, u as updateDeviceOrientation } from "../recording-coordinator-DzflP07_.js";
11
+ import { n as replayRecording, t as ReplayRecordingOptions } from "../recording-replayer-oOzPITrd.js";
12
+ import { n as createPersistenceMiddleware, t as PersistenceMiddlewareOptions } from "../persistence-middleware-DrptY02i.js";
13
+ import { a as ReplayAction, c as computeInterActionDelay, i as ProgressCallback, l as extractActionTimestamp, n as DEFAULT_MAX_DELAY_MS, o as ReplayEngine, r as ErrorCallback, s as ReplayState, t as CompleteCallback } from "../replay-engine-DuX316ae.js";
14
+ import { n as subscribeToSelector, t as SubscribableStore } from "../subscribe-to-selector-UTZ0KkAc.js";
15
+ import { n as wireStoreSubscribers, t as StoreSubscriberDeps } from "../store-subscribers-CuoIzB5T.js";
16
+ import { a as selectReferencePoints, i as selectOdometryRotations, n as selectGpsPositions, o as selectZeroReference, r as selectOdometryPositions, t as selectAlignmentMatrix } from "../app-selectors-DyMzxCEC.js";
17
+ export { type AppDispatch, type AppScreen, type CombinedRootState, type CompleteCallback, DEFAULT_MAX_DELAY_MS, DEFAULT_RECORDING_OPTIONS, DEPTH_CONSTRAINTS, type DepthCaptureOptions, type DepthPoint, type DepthSample, type ErrorCallback, type GpsPoint, IMAGE_CONSTRAINTS, type ImageCaptureOptions, type LatLong, type MarkReferencePointPayload, type SessionMetadata as OpfsSessionMetadata, type PersistenceMiddlewareOptions, type ProgressCallback, type RawDeviceOrientation, type RawGpsPoint, type RecordGpsEventPayload, type RecorderState, type RecorderStore, type RecorderStoreOptions, type RecordingCoordinatorConfig, type RecordingOptions, type RecordingOptionsInput, type RefPointMark, type RefPointsState, type ReplayAction, ReplayEngine, type ReplayRecordingOptions, type ReplayState, type RootState, type RoutingState, STORAGE_KEY, type SessionMetadata$1 as SessionMetadata, type StorageBackend, type StoreSubscriberDeps, type SubscribableStore, add2dImage, buildRawGpsPoint, buildRecordGpsEventPayload, calcRelativeCoordsInMeters, clearSessionRefPointUsage, cloneRecordingOptions, computeInterActionDelay, createGpsPositionHandler, createPersistenceMiddleware, createRecorderStore, endSession, eulerToQuaternion, extractActionTimestamp, extractOdomPosition, extractOdomRotation, getLastDeviceOrientation, incrementRefPointUsage, loadRecordingOptions, markReferencePoint, navigateTo, recordDepthSample, recordGpsEvent, recordWriteFailure, recorderReducer, refPointsReducer, replayRecording, resetCoordinatorState, resetRecordingOptions, resetRefPointsState, routingReducer, saveRecordingOptions, selectAlignmentMatrix, selectCachedKnownRefPoints, selectGpsPositions, selectOdometryPositions, selectOdometryRotations, selectReferencePoints, selectZeroReference, setCurrentScenarioName, setImportedRefPoints, setZeroPos, startSession, subscribeToSelector, updateDeviceOrientation, validateDepthOptions, validateImageOptions, validateRecordingOptions, wireStoreSubscribers };
@@ -0,0 +1,13 @@
1
+ import { endSession, recordDepthSample, recordWriteFailure, recorderReducer, setCurrentScenarioName, startSession } from "./recorder-slice.js";
2
+ import { clearSessionRefPointUsage, incrementRefPointUsage, refPointsReducer, resetRefPointsState, selectCachedKnownRefPoints, setImportedRefPoints } from "./ref-points-slice.js";
3
+ import { navigateTo, routingReducer } from "./routing-slice.js";
4
+ import { createPersistenceMiddleware } from "./persistence-middleware.js";
5
+ import { add2dImage, calcRelativeCoordsInMeters, createRecorderStore, markReferencePoint, recordGpsEvent, setZeroPos } from "./store.js";
6
+ import { buildRawGpsPoint, buildRecordGpsEventPayload, createGpsPositionHandler, eulerToQuaternion, extractOdomPosition, extractOdomRotation, getLastDeviceOrientation, resetCoordinatorState, updateDeviceOrientation } from "./recording-coordinator.js";
7
+ import { DEFAULT_RECORDING_OPTIONS, DEPTH_CONSTRAINTS, IMAGE_CONSTRAINTS, STORAGE_KEY, cloneRecordingOptions, loadRecordingOptions, resetRecordingOptions, saveRecordingOptions, validateDepthOptions, validateImageOptions, validateRecordingOptions } from "./recording-options.js";
8
+ import { replayRecording } from "./recording-replayer.js";
9
+ import { DEFAULT_MAX_DELAY_MS, ReplayEngine, computeInterActionDelay, extractActionTimestamp } from "./replay-engine.js";
10
+ import { subscribeToSelector } from "./subscribe-to-selector.js";
11
+ import { selectAlignmentMatrix, selectGpsPositions, selectOdometryPositions, selectOdometryRotations, selectReferencePoints, selectZeroReference } from "./app-selectors.js";
12
+ import { wireStoreSubscribers } from "./store-subscribers.js";
13
+ export { DEFAULT_MAX_DELAY_MS, DEFAULT_RECORDING_OPTIONS, DEPTH_CONSTRAINTS, IMAGE_CONSTRAINTS, ReplayEngine, STORAGE_KEY, add2dImage, buildRawGpsPoint, buildRecordGpsEventPayload, calcRelativeCoordsInMeters, clearSessionRefPointUsage, cloneRecordingOptions, computeInterActionDelay, createGpsPositionHandler, createPersistenceMiddleware, createRecorderStore, endSession, eulerToQuaternion, extractActionTimestamp, extractOdomPosition, extractOdomRotation, getLastDeviceOrientation, incrementRefPointUsage, loadRecordingOptions, markReferencePoint, navigateTo, recordDepthSample, recordGpsEvent, recordWriteFailure, recorderReducer, refPointsReducer, replayRecording, resetCoordinatorState, resetRecordingOptions, resetRefPointsState, routingReducer, saveRecordingOptions, selectAlignmentMatrix, selectCachedKnownRefPoints, selectGpsPositions, selectOdometryPositions, selectOdometryRotations, selectReferencePoints, selectZeroReference, setCurrentScenarioName, setImportedRefPoints, setZeroPos, startSession, subscribeToSelector, updateDeviceOrientation, validateDepthOptions, validateImageOptions, validateRecordingOptions, wireStoreSubscribers };
@@ -0,0 +1,2 @@
1
+ import { n as createPersistenceMiddleware, t as PersistenceMiddlewareOptions } from "../persistence-middleware-DrptY02i.js";
2
+ export { PersistenceMiddlewareOptions, createPersistenceMiddleware };