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,181 @@
1
+ //#region ../src/storage/opfs-storage.d.ts
2
+ /**
3
+ * OPFS Storage Module
4
+ *
5
+ * Uses the Origin Private File System (OPFS) API to persist recording data.
6
+ * OPFS works consistently on Desktop Chrome, Android Chrome, and iOS Safari,
7
+ * unlike showDirectoryPicker which has write restrictions on Android.
8
+ *
9
+ * Directory structure:
10
+ * /gps-recorder/
11
+ * └── scenarios/
12
+ * ├── {scenario-name}/
13
+ * │ ├── recording-YYYY-MM-DD_HH-MM-SSutc/
14
+ * │ │ ├── session.json
15
+ * │ │ ├── actions/
16
+ * │ │ │ ├── 000001.json
17
+ * │ │ │ └── ...
18
+ * │ │ └── frames/
19
+ * │ │ ├── frame-000001.jpg
20
+ * │ │ └── ...
21
+ * │ └── ...
22
+ * └── ...
23
+ */
24
+ /**
25
+ * Session metadata stored in session.json.
26
+ */
27
+ interface SessionMetadata {
28
+ /** Schema version for forward compatibility */
29
+ version: 1;
30
+ /**
31
+ * Odometry coordinate convention version.
32
+ * - Absent (era 1, old recordings): odomPosition in raw WebXR frame [xrX, xrY, xrZ],
33
+ * GPS payload uses `gpsPoint` with ENU coordinates and derived fields.
34
+ * - 2 (era 2): odomPosition in NUE frame [-xrZ, xrY, xrX],
35
+ * GPS payload uses `gpsPoint` with NUE coordinates and derived fields.
36
+ * - 3 (era 3): odomPosition in raw WebXR [xrX, xrY, xrZ],
37
+ * GPS payload uses `gpsPoint` with NUE coordinates and derived fields.
38
+ * - 4 (era 4): odomPosition in raw WebXR [xrX, xrY, xrZ],
39
+ * GPS payload uses `rawGpsPoint` (raw sensor fields only, no derived fields).
40
+ * - 5 (era 5, current): Same action format as era 4. State-side change only:
41
+ * reducer now also converts quaternion rotations from WebXR to NUE.
42
+ * Used during replay to determine whether migration is needed.
43
+ */
44
+ odomCoordVersion?: 2 | 3 | 4 | 5;
45
+ /** ISO 8601 timestamp when recording started */
46
+ startedAt: string;
47
+ /** ISO 8601 timestamp when recording ended */
48
+ endedAt: string;
49
+ /** Name of the scenario this session belongs to */
50
+ scenarioName: string;
51
+ /** Total number of actions recorded */
52
+ actionCount: number;
53
+ /** Total number of frames captured */
54
+ frameCount: number;
55
+ /** Browser user agent string */
56
+ userAgent: string;
57
+ /** Build/environment info for debugging. Optional for backwards compat. */
58
+ build?: {
59
+ /** Git commit hash (short, e.g. "a1b2c3d"), or "dev" during local dev without git */commitHash: string; /** App version from package.json (e.g. "0.1.0") */
60
+ appVersion: string; /** Library version from gps-plus-slam-js package.json */
61
+ libraryVersion: string; /** Framework version from gps-plus-slam-app-framework package.json */
62
+ frameworkVersion: string; /** ISO 8601 timestamp of when this build was produced */
63
+ buildTime: string;
64
+ };
65
+ /** The page URL the recording was made from (origin + pathname only). Optional for backwards compat. */
66
+ pageUrl?: string;
67
+ }
68
+ /**
69
+ * Result from createSession.
70
+ */
71
+ interface CreateSessionResult {
72
+ scenarioName: string;
73
+ sessionName: string;
74
+ }
75
+ /**
76
+ * Reset module state - exported for testing only.
77
+ * @internal
78
+ */
79
+ declare function resetOpfsStorage(): void;
80
+ /**
81
+ * Reset session-level handles only.
82
+ *
83
+ * Preserves opfsRoot/gpsRecorderDir/scenariosDir (OPFS stays initialized)
84
+ * but clears current scenario/session/actions/frames handles so a new
85
+ * session can be started fresh.
86
+ *
87
+ * Used during soft reset for new recordings (Issue 4, 2026-02-06 user feedback).
88
+ */
89
+ declare function resetSessionHandles(): void;
90
+ /**
91
+ * Initialize OPFS storage by creating the required directory structure.
92
+ *
93
+ * Creates:
94
+ * - /gps-recorder/
95
+ * - /gps-recorder/scenarios/
96
+ *
97
+ * This is idempotent - calling multiple times is safe.
98
+ *
99
+ * @throws Error if OPFS is not supported
100
+ */
101
+ declare function initOpfsStorage(): Promise<void>;
102
+ /**
103
+ * Create a new recording session within a scenario.
104
+ *
105
+ * Creates the directory structure:
106
+ * - /gps-recorder/scenarios/{scenarioName}/recording-{timestamp}/
107
+ * - /gps-recorder/scenarios/{scenarioName}/recording-{timestamp}/actions/
108
+ * - /gps-recorder/scenarios/{scenarioName}/recording-{timestamp}/frames/
109
+ *
110
+ * @param scenarioName - Name of the scenario (creates if doesn't exist)
111
+ * @param timestamp - Session start time (used for folder naming)
112
+ * @returns Session information
113
+ * @throws Error if storage not initialized
114
+ */
115
+ declare function createSession(scenarioName: string, timestamp: Date): Promise<CreateSessionResult>;
116
+ /**
117
+ * Get the current session directory handle.
118
+ * Useful for test assertions.
119
+ * @internal
120
+ */
121
+ declare function getSessionHandle(): FileSystemDirectoryHandle | null;
122
+ /**
123
+ * Get the current scenario directory handle.
124
+ */
125
+ declare function getScenarioHandle(): FileSystemDirectoryHandle | null;
126
+ /**
127
+ * Get the scenarios root directory handle.
128
+ * Used for loading reference points across scenarios.
129
+ */
130
+ declare function getScenariosRootHandle(): FileSystemDirectoryHandle | null;
131
+ /**
132
+ * Write a Redux action to the current session's actions directory.
133
+ *
134
+ * @param action - The action object to write
135
+ * @param index - Sequential action index (1-based)
136
+ * @throws Error if no active session
137
+ */
138
+ declare function writeAction(action: unknown, index: number): Promise<void>;
139
+ /**
140
+ * Write a frame blob to the current session's frames directory.
141
+ *
142
+ * @param blob - Image blob to write
143
+ * @param index - Sequential frame index (1-based)
144
+ * @throws Error if no active session
145
+ */
146
+ declare function writeFrame(blob: Blob, index: number): Promise<void>;
147
+ /**
148
+ * Write session metadata to session.json in the current session directory.
149
+ *
150
+ * @param metadata - Session metadata object
151
+ * @throws Error if no active session
152
+ */
153
+ declare function writeSessionMetadata(metadata: SessionMetadata): Promise<void>;
154
+ /**
155
+ * List all scenario names in OPFS storage.
156
+ *
157
+ * @returns Array of scenario folder names
158
+ */
159
+ declare function listScenarios(): Promise<string[]>;
160
+ /**
161
+ * List all session names within a scenario.
162
+ *
163
+ * @param scenarioName - Name of the scenario
164
+ * @returns Array of session folder names
165
+ */
166
+ declare function listSessions(scenarioName: string): Promise<string[]>;
167
+ /**
168
+ * Check storage quota.
169
+ *
170
+ * Note: Prefer calling `initOpfsStorage()` before this function to ensure
171
+ * the Storage API is available. If the Storage Manager API is not supported,
172
+ * returns a safe default of `{ available: 0, used: 0 }`.
173
+ *
174
+ * @returns Available and used storage in bytes
175
+ */
176
+ declare function checkStorageQuota(): Promise<{
177
+ available: number;
178
+ used: number;
179
+ }>;
180
+ //#endregion
181
+ export { getScenarioHandle as a, initOpfsStorage as c, resetOpfsStorage as d, resetSessionHandles as f, writeSessionMetadata as h, createSession as i, listScenarios as l, writeFrame as m, SessionMetadata as n, getScenariosRootHandle as o, writeAction as p, checkStorageQuota as r, getSessionHandle as s, CreateSessionResult as t, listSessions as u };
@@ -0,0 +1,11 @@
1
+ import { n as SessionMetadata } from "./opfs-storage-ChOzF_Wp.js";
2
+ import { t as StorageBackend } from "./storage-backend-BcEItnFr.js";
3
+
4
+ //#region ../src/storage/opfs-storage-backend.d.ts
5
+ declare class OpfsStorageBackend implements StorageBackend {
6
+ writeAction(action: unknown, index: number): Promise<void>;
7
+ writeFrame(blob: Blob, index: number): Promise<void>;
8
+ writeSessionMetadata(metadata: SessionMetadata): Promise<void>;
9
+ }
10
+ //#endregion
11
+ export { OpfsStorageBackend as t };
@@ -0,0 +1,146 @@
1
+ //#region ../src/sensors/permission-checker.d.ts
2
+ /**
3
+ * Permission Checker Module
4
+ *
5
+ * Provides utilities to check and verify mandatory device permissions
6
+ * required for AR+GPS tracking: WebXR (immersive-ar), Camera, and Geolocation.
7
+ *
8
+ * This module is used by the setup modal to verify permissions BEFORE
9
+ * the user enters AR mode, providing clear feedback on what's missing.
10
+ */
11
+ /**
12
+ * Individual permission status for a single capability.
13
+ */
14
+ interface PermissionStatus {
15
+ /** Whether the permission/feature is supported by the browser/device */
16
+ supported: boolean;
17
+ /** Whether permission has been granted (null if not yet requested) */
18
+ granted: boolean | null;
19
+ /** Human-readable error message if not supported or denied */
20
+ error?: string;
21
+ }
22
+ /**
23
+ * Aggregated status of all mandatory permissions.
24
+ */
25
+ interface PermissionCheckResult {
26
+ /** WebXR immersive-ar session support */
27
+ webxr: PermissionStatus;
28
+ /** Geolocation API access */
29
+ geolocation: PermissionStatus;
30
+ /** Camera access (via getUserMedia) */
31
+ camera: PermissionStatus;
32
+ /** Device orientation (compass) - optional but recommended */
33
+ orientation: PermissionStatus;
34
+ /** File system access for saving recordings */
35
+ fileSystem: PermissionStatus;
36
+ /** Whether all mandatory permissions are ready */
37
+ allMandatoryReady: boolean;
38
+ }
39
+ /**
40
+ * Internal state for file system permission tracking.
41
+ * This tracks whether a folder has been selected and write access verified.
42
+ */
43
+ interface FileSystemState {
44
+ folderSelected: boolean;
45
+ writeVerified: boolean;
46
+ writeError?: string;
47
+ }
48
+ /**
49
+ * Reset file system permission state.
50
+ * Exported for testing purposes.
51
+ * @internal
52
+ */
53
+ declare function resetFileSystemState(): void;
54
+ /**
55
+ * Set file system permission state.
56
+ * Used by the storage module after folder selection and write verification.
57
+ * @internal
58
+ */
59
+ declare function setFileSystemState(state: Partial<FileSystemState>): void;
60
+ /**
61
+ * Check file system access permission status.
62
+ *
63
+ * User Feedback Issue #1: File system access is critical for recording.
64
+ * This function checks:
65
+ * 1. If OPFS (Origin Private File System) is available
66
+ * 2. If storage has been initialized
67
+ * 3. If write access has been verified
68
+ *
69
+ * Note: We now use OPFS instead of showDirectoryPicker because it works
70
+ * consistently on Android Chrome, iOS Safari, and Desktop browsers.
71
+ *
72
+ * @returns Permission status for file system access
73
+ */
74
+ declare function checkFileSystemPermission(): PermissionStatus;
75
+ /**
76
+ * Check if WebXR immersive-ar mode is supported.
77
+ * Does not request a session, only checks support.
78
+ */
79
+ declare function checkWebXRSupport(): Promise<PermissionStatus>;
80
+ /**
81
+ * Check geolocation permission status without triggering a prompt.
82
+ * Uses the Permissions API if available, otherwise returns unknown state.
83
+ */
84
+ declare function checkGeolocationPermission(): Promise<PermissionStatus>;
85
+ /**
86
+ * Request geolocation permission by triggering a position request.
87
+ * This will show the browser's permission prompt if not already granted.
88
+ *
89
+ * @param timeoutMs - Maximum time to wait for position (default 10s)
90
+ * @returns Updated permission status after request
91
+ */
92
+ declare function requestGeolocationPermission(timeoutMs?: number): Promise<PermissionStatus>;
93
+ /**
94
+ * Check camera permission status without triggering a prompt.
95
+ * Uses the Permissions API if available.
96
+ */
97
+ declare function checkCameraPermission(): Promise<PermissionStatus>;
98
+ /**
99
+ * Request camera permission by triggering getUserMedia.
100
+ * This will show the browser's permission prompt if not already granted.
101
+ *
102
+ * @returns Updated permission status after request
103
+ */
104
+ declare function requestCameraPermission(): Promise<PermissionStatus>;
105
+ /**
106
+ * Check device orientation permission status.
107
+ * On iOS 13+, this requires explicit permission request.
108
+ */
109
+ declare function checkOrientationPermission(): Promise<PermissionStatus>;
110
+ /**
111
+ * Request device orientation permission (iOS 13+).
112
+ * On other platforms, this is a no-op that returns granted.
113
+ */
114
+ declare function requestOrientationPermission(): Promise<PermissionStatus>;
115
+ /**
116
+ * Check all permissions without triggering any prompts.
117
+ * Returns current known state of each permission.
118
+ */
119
+ declare function checkAllPermissions(): Promise<PermissionCheckResult>;
120
+ /**
121
+ * Request all mandatory permissions that haven't been granted yet.
122
+ * Shows browser prompts for each permission that needs requesting.
123
+ *
124
+ * This now includes the WebXR+Depth probe to trigger the "3D map" permission
125
+ * upfront, rather than surprising users with a second prompt after "Enter AR".
126
+ *
127
+ * @returns Updated permission check result after requests
128
+ */
129
+ declare function requestAllPermissions(): Promise<PermissionCheckResult>;
130
+ /**
131
+ * Request WebXR permission with depth-sensing by starting a probe session.
132
+ *
133
+ * The depth-sensing permission (ARCore's "3D map of surroundings") is only
134
+ * triggered when an XR session is actually started with depth-sensing options.
135
+ * This function starts a minimal probe session to trigger the permission prompt,
136
+ * then immediately ends it.
137
+ *
138
+ * This allows the app to request all AR permissions upfront during the
139
+ * setup flow, rather than surprising users with a second prompt when
140
+ * they click "Enter AR".
141
+ *
142
+ * @returns Permission status indicating if AR+depth access was granted
143
+ */
144
+ declare function requestWebXRWithDepthPermission(): Promise<PermissionStatus>;
145
+ //#endregion
146
+ export { checkFileSystemPermission as a, checkWebXRSupport as c, requestGeolocationPermission as d, requestOrientationPermission as f, setFileSystemState as h, checkCameraPermission as i, requestAllPermissions as l, resetFileSystemState as m, PermissionStatus as n, checkGeolocationPermission as o, requestWebXRWithDepthPermission as p, checkAllPermissions as r, checkOrientationPermission as s, PermissionCheckResult as t, requestCameraPermission as u };
@@ -0,0 +1,31 @@
1
+ import { t as StorageBackend } from "./storage-backend-BcEItnFr.js";
2
+ import { Middleware } from "@reduxjs/toolkit";
3
+
4
+ //#region ../src/state/persistence-middleware.d.ts
5
+ interface PersistenceMiddlewareOptions {
6
+ /**
7
+ * StorageBackend to use for action persistence.
8
+ */
9
+ storageBackend: StorageBackend;
10
+ /**
11
+ * Callback invoked when a write operation fails during persistence.
12
+ * User Feedback Issue #1 Part B: Used to show toast notifications.
13
+ */
14
+ onWriteFailure?: (error: Error) => void;
15
+ }
16
+ /**
17
+ * Create a Redux middleware that persists qualifying actions to storage
18
+ * during active recording sessions.
19
+ *
20
+ * Persistence rules:
21
+ * - Only persists when `state.recorder.isRecording` is true (checked AFTER
22
+ * the action is reduced, so `startSession` itself is included).
23
+ * - Persists `gpsData/*` and `recorder/*` actions.
24
+ * - Excludes `recorder/recordWriteFailure` to prevent recursive persistence.
25
+ * - Excludes `routing/*`, `refPoints/*`, and any other non-recording actions.
26
+ * - Uses 1-based indexing for action files (000001.json, 000002.json, …).
27
+ * - Each middleware instance maintains its own action index (Bug 10 fix).
28
+ */
29
+ declare function createPersistenceMiddleware(options: PersistenceMiddlewareOptions): Middleware;
30
+ //#endregion
31
+ export { createPersistenceMiddleware as n, PersistenceMiddlewareOptions as t };
@@ -0,0 +1,35 @@
1
+ import { i as DepthSample } from "./ar-types-B-ORgk6Z.js";
2
+ import { s as RecordingOptions } from "./recording-options-BYUFX8iU.js";
3
+ import * as _$_reduxjs_toolkit0 from "@reduxjs/toolkit";
4
+
5
+ //#region ../src/state/recorder-slice.d.ts
6
+ interface SessionMetadata {
7
+ scenarioName: string;
8
+ sessionName: string;
9
+ startTime: number;
10
+ deviceInfo?: string;
11
+ notes?: string;
12
+ /** Recording options used for this session (for replay context) */
13
+ recordingOptions?: RecordingOptions;
14
+ }
15
+ interface RecorderState {
16
+ isRecording: boolean;
17
+ sessionMetadata: SessionMetadata | null;
18
+ actionCount: number;
19
+ /**
20
+ * Count of failed file write operations during this session.
21
+ * User Feedback Issue #1 Part B: Track write failures for visibility.
22
+ */
23
+ failedWriteCount: number;
24
+ /**
25
+ * Currently selected scenario name.
26
+ * Replaces the closure variable in folder-manager.ts so any module
27
+ * can read it via store.getState().recorder.currentScenarioName.
28
+ * @see docs/2026-03-26-state-management-audit.md §9.4 Priority 2
29
+ */
30
+ currentScenarioName: string;
31
+ }
32
+ declare const startSession: _$_reduxjs_toolkit0.ActionCreatorWithPayload<SessionMetadata, "recorder/startSession">, endSession: _$_reduxjs_toolkit0.ActionCreatorWithoutPayload<"recorder/endSession">, recordDepthSample: _$_reduxjs_toolkit0.ActionCreatorWithPayload<DepthSample, "recorder/recordDepthSample">, recordWriteFailure: _$_reduxjs_toolkit0.ActionCreatorWithPayload<string, "recorder/recordWriteFailure">, setCurrentScenarioName: _$_reduxjs_toolkit0.ActionCreatorWithPayload<string, "recorder/setCurrentScenarioName">;
33
+ declare const recorderReducer: _$_reduxjs_toolkit0.Reducer<RecorderState>;
34
+ //#endregion
35
+ export { recordWriteFailure as a, startSession as c, recordDepthSample as i, SessionMetadata as n, recorderReducer as o, endSession as r, setCurrentScenarioName as s, RecorderState as t };
@@ -0,0 +1,81 @@
1
+ import { t as ARPose } from "./ar-types-B-ORgk6Z.js";
2
+ import { n as RawDeviceOrientation, t as GpsPosition } from "./gps-Ddzr2KlX.js";
3
+ import { c as RecordGpsEventPayload, l as RecorderStore } from "./store-C7PKOj8S.js";
4
+ import { Quaternion, RawGpsPoint, Vector3, eulerToQuaternion } from "gps-plus-slam-js";
5
+
6
+ //#region ../src/state/recording-coordinator.d.ts
7
+ /**
8
+ * Configuration for the recording coordinator
9
+ */
10
+ interface RecordingCoordinatorConfig {
11
+ /** Redux store to dispatch actions to */
12
+ store: RecorderStore;
13
+ /** Function to get current AR pose (from WebXR module) */
14
+ getArPose: () => ARPose | null;
15
+ }
16
+ /**
17
+ * Update the cached device orientation.
18
+ * Called by orientation watch, used when GPS event arrives.
19
+ */
20
+ declare function updateDeviceOrientation(orientation: RawDeviceOrientation): void;
21
+ /**
22
+ * Get the current cached device orientation.
23
+ */
24
+ declare function getLastDeviceOrientation(): RawDeviceOrientation | null;
25
+ /**
26
+ * Clear cached state (for testing or session reset)
27
+ */
28
+ declare function resetCoordinatorState(): void;
29
+ /**
30
+ * Extract raw odometry position tuple from ARPose.
31
+ *
32
+ * Returns the raw WebXR position without coordinate conversion.
33
+ * The reducer applies the WebXR→NUE transform when storing into state
34
+ * (raw-storage pattern, see docs/2026-04-09-raw-storage-convert-on-read.md).
35
+ *
36
+ * WebXR local-floor frame: X=East, Y=Up, Z=South (toward viewer / backward).
37
+ */
38
+ declare function extractOdomPosition(arPose: ARPose): Vector3;
39
+ /**
40
+ * Extract odometry rotation tuple from ARPose.
41
+ */
42
+ declare function extractOdomRotation(arPose: ARPose): Quaternion;
43
+ /**
44
+ * Build a RawGpsPoint from GPS position data.
45
+ * Returns only raw sensor fields — no derived fields (coordinates, weight,
46
+ * zeroRef, deviceRotation). Derived fields are computed by the library
47
+ * reducer when the action is dispatched (raw-storage pattern).
48
+ *
49
+ * @param gpsPosition - GPS position from Geolocation API
50
+ * @param deviceOrientation - Optional device orientation from sensors
51
+ * @returns RawGpsPoint ready for the action payload
52
+ */
53
+ declare function buildRawGpsPoint(gpsPosition: GpsPosition, deviceOrientation: RawDeviceOrientation | null): RawGpsPoint;
54
+ /**
55
+ * Build a RecordGpsEventPayload from GPS position and AR pose.
56
+ * This is a pure function for testability.
57
+ *
58
+ * Stores only raw sensor data in the payload. The library reducer
59
+ * computes derived fields (coordinates, weight, deviceRotation)
60
+ * when the action is processed (raw-storage pattern).
61
+ *
62
+ * @param gpsPosition - GPS position from Geolocation API
63
+ * @param arPose - AR pose from WebXR
64
+ * @param deviceOrientation - Optional device orientation from sensors
65
+ * @returns RecordGpsEventPayload ready for dispatch
66
+ */
67
+ declare function buildRecordGpsEventPayload(gpsPosition: GpsPosition, arPose: ARPose, deviceOrientation: RawDeviceOrientation | null): RecordGpsEventPayload;
68
+ /**
69
+ * Create a GPS position handler that dispatches combined GPS+AR events.
70
+ *
71
+ * This is the CRITICAL function that implements the correct architecture:
72
+ * - Called when GPS arrives
73
+ * - Reads current AR pose
74
+ * - Dispatches single combined action
75
+ *
76
+ * @param config - Configuration with store and getArPose function
77
+ * @returns Callback function for GPS watch
78
+ */
79
+ declare function createGpsPositionHandler(config: RecordingCoordinatorConfig): (position: GpsPosition) => void;
80
+ //#endregion
81
+ export { eulerToQuaternion as a, getLastDeviceOrientation as c, createGpsPositionHandler as i, resetCoordinatorState as l, buildRawGpsPoint as n, extractOdomPosition as o, buildRecordGpsEventPayload as r, extractOdomRotation as s, RecordingCoordinatorConfig as t, updateDeviceOrientation as u };
@@ -0,0 +1,166 @@
1
+ //#region ../src/state/recording-options.d.ts
2
+ /**
3
+ * Recording Options - User-configurable settings for data capture.
4
+ *
5
+ * Allows users to disable/configure high-frequency data streams
6
+ * (depth sampling, image capture) to improve performance on lower-end devices.
7
+ *
8
+ * Options persist in localStorage across sessions.
9
+ */
10
+ /**
11
+ * Input type for validateRecordingOptions allowing partial nested objects.
12
+ * This allows passing incomplete objects that will be merged with defaults.
13
+ */
14
+ interface RecordingOptionsInput {
15
+ depth?: Partial<DepthCaptureOptions>;
16
+ images?: Partial<ImageCaptureOptions>;
17
+ arCrashIsolation?: Partial<ArCrashIsolationOptions>;
18
+ }
19
+ /**
20
+ * Diagnostic flags for isolating pre-recording AR startup crashes.
21
+ * These gates affect XR session negotiation and frame-loop behavior,
22
+ * independently of recording-time image/depth capture.
23
+ */
24
+ interface ArCrashIsolationOptions {
25
+ enableDomOverlay: boolean;
26
+ enableCameraAccess: boolean;
27
+ enableDepthSensingFeature: boolean;
28
+ enableCss3dRenderer: boolean;
29
+ enableCameraTextureAcquisition: boolean;
30
+ /**
31
+ * Apply the Chromium WebXR camera-access tab-crash workaround at app
32
+ * bootstrap (deletes `XRWebGLBinding.prototype.createProjectionLayer` and
33
+ * `XRRenderState.prototype.layers` so three.js falls back to
34
+ * `XRWebGLLayer`). Opt-in because the upstream issue thread warns it may
35
+ * break WebXR on unaffected devices.
36
+ *
37
+ * @see GpsPlusSlamJs_AppFramework/src/ar/chromium-camera-access-workaround.ts
38
+ * @see https://github.com/mrdoob/three.js/issues/33404
39
+ */
40
+ applyChromiumProjectionLayerWorkaround: boolean;
41
+ }
42
+ /**
43
+ * Configuration for depth sampling during recording.
44
+ */
45
+ interface DepthCaptureOptions {
46
+ /** Whether to capture depth samples. Default: true */
47
+ enabled: boolean;
48
+ /** Interval between samples in milliseconds. Default: 1000 */
49
+ intervalMs: number;
50
+ /** Grid size (N×N points per sample). Default: 3 */
51
+ gridSize: number;
52
+ }
53
+ /**
54
+ * Configuration for image capture during recording.
55
+ */
56
+ interface ImageCaptureOptions {
57
+ /** Whether to capture images. Default: true */
58
+ enabled: boolean;
59
+ /** Interval between captures in milliseconds. Default: 2000 */
60
+ intervalMs: number;
61
+ /** JPEG quality (0.0 - 1.0). Default: 0.7 */
62
+ quality: number;
63
+ /** Resolution divisor: 1 = full native resolution, 2 = half, 4 = quarter. Default: 1 */
64
+ resolutionDivisor: number;
65
+ }
66
+ /**
67
+ * User-configurable recording options.
68
+ * Persisted to localStorage for cross-session consistency.
69
+ */
70
+ interface RecordingOptions {
71
+ /** Depth sampling configuration */
72
+ depth: DepthCaptureOptions;
73
+ /** Image capture configuration */
74
+ images: ImageCaptureOptions;
75
+ /** Diagnostic flags for pre-recording AR crash isolation */
76
+ arCrashIsolation: ArCrashIsolationOptions;
77
+ }
78
+ /**
79
+ * localStorage key for persisted options.
80
+ *
81
+ * **Multi-tab caveat:** All tabs/instances sharing the same origin will
82
+ * read and write this key. In multi-tab or embedded scenarios, concurrent
83
+ * saves can silently overwrite each other. Use a custom `storageKey`
84
+ * parameter in `loadRecordingOptions` / `saveRecordingOptions` to isolate
85
+ * instances when needed.
86
+ */
87
+ declare const STORAGE_KEY = "gps-plus-slam-recorder-options";
88
+ /** Default recording options (all streams enabled) */
89
+ declare const DEFAULT_RECORDING_OPTIONS: RecordingOptions;
90
+ /** Validation constraints for depth options */
91
+ declare const DEPTH_CONSTRAINTS: {
92
+ readonly intervalMs: {
93
+ readonly min: 500;
94
+ readonly max: 5000;
95
+ readonly step: 100;
96
+ };
97
+ readonly gridSize: {
98
+ readonly min: 2;
99
+ readonly max: 10;
100
+ readonly step: 1;
101
+ };
102
+ };
103
+ /** Validation constraints for image options */
104
+ declare const IMAGE_CONSTRAINTS: {
105
+ readonly intervalMs: {
106
+ readonly min: 1000;
107
+ readonly max: 10000;
108
+ readonly step: 500;
109
+ };
110
+ readonly quality: {
111
+ readonly min: 0.3;
112
+ readonly max: 1;
113
+ readonly step: 0.1;
114
+ };
115
+ readonly resolutionDivisor: {
116
+ readonly min: 1;
117
+ readonly max: 8;
118
+ readonly step: 1;
119
+ };
120
+ };
121
+ /**
122
+ * Validate and normalize AR crash isolation flags.
123
+ * Missing or invalid values fall back to defaults.
124
+ */
125
+ declare function validateArCrashIsolationOptions(options: Partial<ArCrashIsolationOptions>): ArCrashIsolationOptions;
126
+ /**
127
+ * Validate and normalize depth options.
128
+ * Invalid values are clamped to valid ranges.
129
+ */
130
+ declare function validateDepthOptions(options: Partial<DepthCaptureOptions>): DepthCaptureOptions;
131
+ /**
132
+ * Validate and normalize image options.
133
+ * Invalid values are clamped to valid ranges.
134
+ */
135
+ declare function validateImageOptions(options: Partial<ImageCaptureOptions>): ImageCaptureOptions;
136
+ /**
137
+ * Validate and normalize a full RecordingOptions object.
138
+ * Merges with defaults and clamps invalid values.
139
+ */
140
+ declare function validateRecordingOptions(options: RecordingOptionsInput): RecordingOptions;
141
+ /**
142
+ * Load recording options from localStorage.
143
+ * Returns defaults if no saved options exist or parsing fails.
144
+ * Validates and merges with defaults to handle schema evolution.
145
+ * @param storageKey - Optional custom localStorage key (defaults to STORAGE_KEY).
146
+ */
147
+ declare function loadRecordingOptions(storageKey?: string): RecordingOptions;
148
+ /**
149
+ * Save recording options to localStorage.
150
+ * Options are validated before saving.
151
+ * @param storageKey - Optional custom localStorage key (defaults to STORAGE_KEY).
152
+ */
153
+ declare function saveRecordingOptions(options: RecordingOptions, storageKey?: string): void;
154
+ /**
155
+ * Reset recording options to defaults.
156
+ * Clears localStorage and returns default options.
157
+ * @param storageKey - Optional custom localStorage key (defaults to STORAGE_KEY).
158
+ */
159
+ declare function resetRecordingOptions(storageKey?: string): RecordingOptions;
160
+ /**
161
+ * Create a deep copy of recording options.
162
+ * Useful for creating mutable copies of the frozen defaults.
163
+ */
164
+ declare function cloneRecordingOptions(options: RecordingOptions): RecordingOptions;
165
+ //#endregion
166
+ export { validateRecordingOptions as _, IMAGE_CONSTRAINTS as a, RecordingOptionsInput as c, loadRecordingOptions as d, resetRecordingOptions as f, validateImageOptions as g, validateDepthOptions as h, DepthCaptureOptions as i, STORAGE_KEY as l, validateArCrashIsolationOptions as m, DEFAULT_RECORDING_OPTIONS as n, ImageCaptureOptions as o, saveRecordingOptions as p, DEPTH_CONSTRAINTS as r, RecordingOptions as s, ArCrashIsolationOptions as t, cloneRecordingOptions as u };
@@ -0,0 +1,32 @@
1
+ import { n as CombinedRootState } from "./store-C7PKOj8S.js";
2
+ import { i as RecordedAction } from "./zip-reader-D7pkpX8K.js";
3
+
4
+ //#region ../src/state/recording-replayer.d.ts
5
+ /**
6
+ * Options for replaying a recording.
7
+ */
8
+ interface ReplayRecordingOptions {
9
+ /**
10
+ * Optional migration function to transform raw actions from the ZIP before
11
+ * dispatching. Use this to handle older recording formats (e.g., era 1–3
12
+ * recordings that use `gpsPoint` instead of `rawGpsPoint`).
13
+ *
14
+ * When not provided, actions are dispatched as-is from the ZIP.
15
+ */
16
+ readonly migrateActions?: (actions: RecordedAction[]) => RecordedAction[];
17
+ }
18
+ /**
19
+ * Replay a recording session from zip data, returning the final state.
20
+ *
21
+ * Loads all actions from the zip, creates a store with no persistence,
22
+ * optionally migrates old-format actions, dispatches in order, and returns
23
+ * the resulting state.
24
+ *
25
+ * @param zipData - The zip file content as a Uint8Array
26
+ * @param options - Optional replay configuration (e.g., action migration)
27
+ * @returns The fully-replayed combined state (library + recorder)
28
+ * @throws If the zip cannot be parsed or contains invalid data
29
+ */
30
+ declare function replayRecording(zipData: Uint8Array, options?: ReplayRecordingOptions): Promise<CombinedRootState>;
31
+ //#endregion
32
+ export { replayRecording as n, ReplayRecordingOptions as t };