gps-plus-slam-app-framework 1.0.0 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +4 -4
- package/README.md +249 -108
- package/dist/accuracy-circles-CsxE_7x1.d.ts +43 -0
- package/dist/{app-selectors-DyMzxCEC.d.ts → app-selectors-BeU0_ab8.d.ts} +14 -15
- package/dist/ar/camera-blit-capture.d.ts +1 -1
- package/dist/ar/capture-failure-tracker.d.ts +1 -1
- package/dist/ar/chromium-camera-access-workaround.d.ts +1 -1
- package/dist/ar/depth-sampler.d.ts +2 -2
- package/dist/ar/depth-sampler.js +1 -1
- package/dist/ar/frame-loop.d.ts +2 -0
- package/dist/ar/frame-loop.js +40 -0
- package/dist/ar/image-capture.d.ts +1 -1
- package/dist/ar/image-capture.js +1 -1
- package/dist/ar/index.d.ts +12 -12
- package/dist/ar/index.js +3 -3
- package/dist/ar/replay-scene.d.ts +1 -1
- package/dist/ar/scene-node-names.d.ts +1 -1
- package/dist/ar/webxr-session.d.ts +4 -4
- package/dist/ar/webxr-session.js +151 -56
- package/dist/ar/xr-camera-texture.d.ts +1 -1
- package/dist/ar/xr-error-handler.d.ts +1 -1
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.js +2 -0
- package/dist/create-slam-app-store-CNsZ3rcX.d.ts +371 -0
- package/dist/{depth-sampler-BNCtnEoP.d.ts → depth-sampler-xg8vna6c.d.ts} +1 -1
- package/dist/file-system-DTApEv_Q.d.ts +114 -0
- package/dist/frame-loop-QJIxLin0.d.ts +42 -0
- package/dist/frustum-visibility-BHnFrSKQ.d.ts +58 -0
- package/dist/{fused-path-DtqCSqJh.d.ts → fused-path-CB4DwWOG.d.ts} +1 -1
- package/dist/geo/h3-proximity.d.ts +2 -0
- package/dist/{ref-points/h3-ref-point.js → geo/h3-proximity.js} +16 -12
- package/dist/geo/index.d.ts +2 -0
- package/dist/geo/index.js +2 -0
- package/dist/{geo-types-Xx-LVcnw.d.ts → geo-types-CTuF23gG.d.ts} +16 -1
- package/dist/{gps-Ddzr2KlX.d.ts → gps-DXoQb9Kf.d.ts} +1 -1
- package/dist/gps-anchor-CnWY61XK.d.ts +48 -0
- package/dist/gps-anchor-DjC_3MoT.js +257 -0
- package/dist/gps-ar-pose-sampler-DsM1Kb2N.d.ts +43 -0
- package/dist/{recording-coordinator-DzflP07_.d.ts → gps-event-coordinator-DBx9I1YX.d.ts} +7 -6
- package/dist/gps-event-markers-BGr-iLvi.d.ts +103 -0
- package/dist/{h3-ref-point-CFhayNSZ.d.ts → h3-proximity-BhfgNbdW.d.ts} +16 -12
- package/dist/{image-capture-2pKjYUS6.d.ts → image-capture-DZLxHDN9.d.ts} +1 -1
- package/dist/index-gzWJMVpo.d.ts +2 -0
- package/dist/index-pOjUCKEP.d.ts +24 -0
- package/dist/index.d.ts +59 -56
- package/dist/index.js +22 -21
- package/dist/{leaflet-map-overlay-CvfQXTye.d.ts → leaflet-map-overlay-Cew7XAoO.d.ts} +32 -17
- package/dist/licensing/index.d.ts +1 -1
- package/dist/licensing/index.js +1 -1
- package/dist/{logger-B81iwxx0.d.ts → logger-C9vugiQb.d.ts} +7 -1
- package/dist/map-data-sih4g64v.d.ts +49 -0
- package/dist/map-overlay-draw-B3R1c9Xp.d.ts +42 -0
- package/dist/{null-storage-backend-CsWvQwN8.d.ts → null-storage-backend-BKOS7JpL.d.ts} +4 -2
- package/dist/{opfs-storage-ChOzF_Wp.d.ts → opfs-storage-DOPkzgeT.d.ts} +54 -51
- package/dist/opfs-storage-backend-Cj_7PWoq.d.ts +13 -0
- package/dist/{permission-checker-jO2ziCWC.d.ts → permission-checker-DPJl_RU6.d.ts} +41 -1
- package/dist/persistence-middleware-BkHIqvaA.d.ts +55 -0
- package/dist/{recording-replayer-oOzPITrd.d.ts → recording-replayer-CmCIIZ02.d.ts} +2 -2
- package/dist/recording-slice-d6OtCrza.d.ts +28 -0
- package/dist/{replay-engine-DuX316ae.d.ts → replay-engine-BGBRQyXs.d.ts} +4 -1
- package/dist/{replay-scene-DtUm6bsr.d.ts → replay-scene-DpAGcAKY.d.ts} +3 -3
- package/dist/sensors/gps-error-handler.d.ts +1 -1
- package/dist/sensors/gps.d.ts +1 -1
- package/dist/sensors/gps.js +2 -2
- package/dist/sensors/index.d.ts +3 -3
- package/dist/sensors/index.js +1 -1
- package/dist/sensors/permission-checker.d.ts +2 -2
- package/dist/sensors/permission-checker.js +79 -1
- package/dist/state/app-selectors.d.ts +2 -2
- package/dist/state/app-selectors.js +33 -3
- package/dist/state/combined-root-state.d.ts +2 -0
- package/dist/state/combined-root-state.js +1 -0
- package/dist/state/create-slam-app-store.d.ts +2 -0
- package/dist/state/create-slam-app-store.js +75 -0
- package/dist/state/gps-ar-pose-sampler.d.ts +4 -0
- package/dist/state/gps-ar-pose-sampler.js +19 -0
- package/dist/state/{recording-coordinator.d.ts → gps-event-coordinator.d.ts} +1 -1
- package/dist/state/{recording-coordinator.js → gps-event-coordinator.js} +3 -4
- package/dist/state/index.d.ts +17 -17
- package/dist/state/index.js +10 -8
- package/dist/state/persistence-middleware.d.ts +2 -2
- package/dist/state/persistence-middleware.js +39 -11
- package/dist/state/recording-options.d.ts +1 -1
- package/dist/state/recording-replayer.d.ts +3 -2
- package/dist/state/recording-replayer.js +2 -2
- package/dist/state/recording-slice.d.ts +2 -0
- package/dist/state/{recorder-slice.js → recording-slice.js} +7 -15
- package/dist/state/replay-engine.d.ts +1 -1
- package/dist/state/replay-engine.js +3 -3
- package/dist/state/store-subscribers.d.ts +2 -2
- package/dist/state/store-subscribers.js +38 -20
- package/dist/state/subscribe-to-selector.d.ts +1 -1
- package/dist/state/tracking-quality.d.ts +2 -0
- package/dist/state/tracking-quality.js +723 -0
- package/dist/state/tracking-slice.d.ts +2 -0
- package/dist/state/tracking-slice.js +147 -0
- package/dist/storage/file-system-utils.d.ts +1 -1
- package/dist/storage/file-system.d.ts +2 -2
- package/dist/storage/file-system.js +154 -94
- package/dist/storage/index.d.ts +9 -11
- package/dist/storage/index.js +5 -7
- package/dist/storage/null-storage-backend.d.ts +1 -1
- package/dist/storage/null-storage-backend.js +7 -0
- package/dist/storage/opfs-storage-backend.d.ts +1 -1
- package/dist/storage/opfs-storage-backend.js +7 -1
- package/dist/storage/opfs-storage.d.ts +2 -2
- package/dist/storage/opfs-storage.js +69 -85
- package/dist/storage/storage-backend.d.ts +2 -2
- package/dist/storage/zip-export.d.ts +2 -2
- package/dist/storage/zip-export.js +55 -62
- package/dist/storage/zip-reader.d.ts +2 -2
- package/dist/storage/zip-reader.js +32 -5
- package/dist/storage-backend-CT0Il_AB.d.ts +28 -0
- package/dist/{store-subscribers-CuoIzB5T.d.ts → store-subscribers-Dce_CoJF.d.ts} +31 -7
- package/dist/{subscribe-to-selector-UTZ0KkAc.d.ts → subscribe-to-selector-DIHm3BRZ.d.ts} +1 -1
- package/dist/test-utils/browser-mocks.d.ts +1 -1
- package/dist/test-utils/zip-round-trip-helpers.d.ts +7 -1
- package/dist/test-utils/zip-round-trip-helpers.js +6 -5
- package/dist/tracking-slice-utCNND8t.d.ts +86 -0
- package/dist/types/ar-types.d.ts +1 -1
- package/dist/types/geo-types.d.ts +2 -2
- package/dist/types/index.d.ts +3 -3
- package/dist/utils/concurrency.d.ts +1 -1
- package/dist/utils/failure-tracker.d.ts +1 -1
- package/dist/utils/format-file-size.d.ts +1 -1
- package/dist/utils/fused-path.d.ts +1 -1
- package/dist/utils/index.d.ts +6 -6
- package/dist/utils/list-formatter.d.ts +1 -1
- package/dist/utils/logger.d.ts +1 -1
- package/dist/utils/logger.js +68 -8
- package/dist/visualization/accuracy-circles.d.ts +2 -0
- package/dist/visualization/accuracy-circles.js +57 -0
- package/dist/visualization/alignment-lerper.d.ts +1 -1
- package/dist/visualization/camera-follower.d.ts +1 -1
- package/dist/visualization/css3d-renderer-manager.d.ts +1 -1
- package/dist/visualization/frustum-visibility.d.ts +2 -0
- package/dist/visualization/frustum-visibility.js +139 -0
- package/dist/visualization/gps-anchor.d.ts +2 -0
- package/dist/visualization/gps-anchor.js +2 -0
- package/dist/visualization/gps-compass-cubes.d.ts +1 -1
- package/dist/visualization/gps-event-markers.d.ts +2 -2
- package/dist/visualization/gps-event-markers.js +69 -2
- package/dist/visualization/index.d.ts +17 -12
- package/dist/visualization/index.js +6 -2
- package/dist/visualization/leaflet-map-overlay.d.ts +1 -1
- package/dist/visualization/leaflet-map-overlay.js +56 -98
- package/dist/visualization/lerp-utils.d.ts +1 -1
- package/dist/visualization/map-data.d.ts +2 -0
- package/dist/visualization/map-data.js +33 -0
- package/dist/visualization/map-overlay-draw.d.ts +2 -0
- package/dist/visualization/map-overlay-draw.js +107 -0
- package/dist/visualization/map-overlay.d.ts +1 -1
- package/dist/visualization/three-dispose.d.ts +1 -1
- package/dist/visualization/vis-colors.d.ts +1 -1
- package/dist/{webxr-session-COlSrXdL.d.ts → webxr-session-DB5cIZnN.d.ts} +53 -12
- package/dist/{zip-export-Rtpi75JJ.d.ts → zip-export-QO4iLIi7.d.ts} +58 -7
- package/dist/{zip-reader-D7pkpX8K.d.ts → zip-reader-D1105idz.d.ts} +38 -1
- package/package.json +29 -18
- package/dist/ar/tracking-state.d.ts +0 -2
- package/dist/ar/tracking-state.js +0 -164
- package/dist/community-license-key-ChZLCJyO.d.ts +0 -21
- package/dist/file-system-BsQgYCU3.d.ts +0 -128
- package/dist/gps-event-markers-DpEy2qRd.d.ts +0 -67
- package/dist/licensing/community-license-key.d.ts +0 -2
- package/dist/licensing/community-license-key.js +0 -21
- package/dist/opfs-storage-backend-CVcmfJHN.d.ts +0 -11
- package/dist/persistence-middleware-DrptY02i.d.ts +0 -31
- package/dist/recorder-slice-fcwAXrsh.d.ts +0 -35
- package/dist/ref-point-importer-B_wn5ABk.d.ts +0 -62
- package/dist/ref-point-loader-Pt1smgHS.d.ts +0 -117
- package/dist/ref-points/h3-ref-point.d.ts +0 -2
- package/dist/ref-points/index.d.ts +0 -2
- package/dist/ref-points/index.js +0 -2
- package/dist/ref-points-slice-tC-Wd6XJ.d.ts +0 -48
- package/dist/reference-points-CFWy8_wj.d.ts +0 -68
- package/dist/routing-slice-BlHTM8eh.d.ts +0 -23
- package/dist/state/recorder-slice.d.ts +0 -2
- package/dist/state/ref-points-slice.d.ts +0 -2
- package/dist/state/ref-points-slice.js +0 -44
- package/dist/state/routing-slice.d.ts +0 -2
- package/dist/state/routing-slice.js +0 -13
- package/dist/state/store.d.ts +0 -9
- package/dist/state/store.js +0 -71
- package/dist/storage/ref-point-importer.d.ts +0 -2
- package/dist/storage/ref-point-importer.js +0 -163
- package/dist/storage/ref-point-loader.d.ts +0 -2
- package/dist/storage/ref-point-loader.js +0 -248
- package/dist/storage/ref-point-recovery.d.ts +0 -28
- package/dist/storage/ref-point-recovery.js +0 -159
- package/dist/storage-backend-BcEItnFr.d.ts +0 -20
- package/dist/store-C7PKOj8S.d.ts +0 -96
- package/dist/tracking-state-B9QfuZCg.d.ts +0 -101
- package/dist/visualization/reference-points.d.ts +0 -2
- package/dist/visualization/reference-points.js +0 -160
- /package/dist/{alignment-lerper-D9BeDwZX.d.ts → alignment-lerper-L1RbWHQ4.d.ts} +0 -0
- /package/dist/{ar-types-B-ORgk6Z.d.ts → ar-types-Ck8LEq8k.d.ts} +0 -0
- /package/dist/{camera-blit-capture-DHuyrrxr.d.ts → camera-blit-capture-C1V9I1Z6.d.ts} +0 -0
- /package/dist/{camera-follower-BMqPddxx.d.ts → camera-follower-1k8mnw5J.d.ts} +0 -0
- /package/dist/{capture-failure-tracker-2Q6oI2uQ.d.ts → capture-failure-tracker-JKb1ST8E.d.ts} +0 -0
- /package/dist/{chromium-camera-access-workaround-CU5zSKNr.d.ts → chromium-camera-access-workaround-NvChXsi8.d.ts} +0 -0
- /package/dist/{concurrency-p6gB30fT.d.ts → concurrency-CMw8pSaG.d.ts} +0 -0
- /package/dist/{css3d-renderer-manager-rgLMVAvd.d.ts → css3d-renderer-manager-CkjCb2HW.d.ts} +0 -0
- /package/dist/{failure-tracker-1sQ_Cgyw.d.ts → failure-tracker-DnHXOIRa.d.ts} +0 -0
- /package/dist/{file-system-utils-5cWO8Xyv.d.ts → file-system-utils-CtKiiw27.d.ts} +0 -0
- /package/dist/{format-file-size-onGq0k1Q.d.ts → format-file-size-BTS5H62-.d.ts} +0 -0
- /package/dist/{gps-compass-cubes-C-6JEnpR.d.ts → gps-compass-cubes-CsLtFv4B.d.ts} +0 -0
- /package/dist/{gps-error-handler-VPuNOuf8.d.ts → gps-error-handler-Dg3ziRVY.d.ts} +0 -0
- /package/dist/{lerp-utils-87NWjUOD.d.ts → lerp-utils-B8MM8zCR.d.ts} +0 -0
- /package/dist/{list-formatter-DKQQVLcl.d.ts → list-formatter-CNqi-E2j.d.ts} +0 -0
- /package/dist/{map-overlay-DuiZuCTx.d.ts → map-overlay-DAmreyA3.d.ts} +0 -0
- /package/dist/{recording-options-BYUFX8iU.d.ts → recording-options-Dq6IsKAv.d.ts} +0 -0
- /package/dist/{scene-node-names-DPsaE2z3.d.ts → scene-node-names-6LBjPmwz.d.ts} +0 -0
- /package/dist/{three-dispose-CCBHjE_a.d.ts → three-dispose-C2drkp6f.d.ts} +0 -0
- /package/dist/{vis-colors-Qi2vlRGt.d.ts → vis-colors-CHQhjal3.d.ts} +0 -0
- /package/dist/{xr-camera-texture-BbukNE79.d.ts → xr-camera-texture-BU5YvKAM.d.ts} +0 -0
- /package/dist/{xr-error-handler-DTHfmvrl.d.ts → xr-error-handler-CDY5QxGb.d.ts} +0 -0
|
@@ -6,20 +6,21 @@
|
|
|
6
6
|
* OPFS works consistently on Desktop Chrome, Android Chrome, and iOS Safari,
|
|
7
7
|
* unlike showDirectoryPicker which has write restrictions on Android.
|
|
8
8
|
*
|
|
9
|
-
* Directory structure:
|
|
10
|
-
* /gps-
|
|
11
|
-
* └──
|
|
12
|
-
* ├──
|
|
13
|
-
* │ ├──
|
|
14
|
-
* │
|
|
15
|
-
* │ │ ├──
|
|
16
|
-
* │ │
|
|
17
|
-
* │
|
|
18
|
-
* │
|
|
19
|
-
* │
|
|
20
|
-
* │ │ └── ...
|
|
21
|
-
* │ └── ...
|
|
9
|
+
* Directory structure (flat sessions — no scenario hierarchy):
|
|
10
|
+
* /gps-plus-slam/
|
|
11
|
+
* └── sessions/
|
|
12
|
+
* ├── recording-YYYY-MM-DD_HH-MM-SSutc/
|
|
13
|
+
* │ ├── session.json
|
|
14
|
+
* │ ├── actions/
|
|
15
|
+
* │ │ ├── 000001.json
|
|
16
|
+
* │ │ └── ...
|
|
17
|
+
* │ └── frames/
|
|
18
|
+
* │ ├── frame-000001.jpg
|
|
19
|
+
* │ └── ...
|
|
22
20
|
* └── ...
|
|
21
|
+
*
|
|
22
|
+
* Scenario grouping (scenarios/{name}/recording-…) is a recorder-only concern,
|
|
23
|
+
* handled by ScenarioWrappingStorageBackend in the recorder app.
|
|
23
24
|
*/
|
|
24
25
|
/**
|
|
25
26
|
* Session metadata stored in session.json.
|
|
@@ -46,8 +47,12 @@ interface SessionMetadata {
|
|
|
46
47
|
startedAt: string;
|
|
47
48
|
/** ISO 8601 timestamp when recording ended */
|
|
48
49
|
endedAt: string;
|
|
49
|
-
/**
|
|
50
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Opaque tag the framework does not interpret. Consumers (e.g. the recorder)
|
|
52
|
+
* use it to carry application-specific grouping info such as a scenario name.
|
|
53
|
+
* Replaces the former required `scenarioName` field.
|
|
54
|
+
*/
|
|
55
|
+
contextTag?: string;
|
|
51
56
|
/** Total number of actions recorded */
|
|
52
57
|
actionCount: number;
|
|
53
58
|
/** Total number of frames captured */
|
|
@@ -69,7 +74,6 @@ interface SessionMetadata {
|
|
|
69
74
|
* Result from createSession.
|
|
70
75
|
*/
|
|
71
76
|
interface CreateSessionResult {
|
|
72
|
-
scenarioName: string;
|
|
73
77
|
sessionName: string;
|
|
74
78
|
}
|
|
75
79
|
/**
|
|
@@ -80,19 +84,17 @@ declare function resetOpfsStorage(): void;
|
|
|
80
84
|
/**
|
|
81
85
|
* Reset session-level handles only.
|
|
82
86
|
*
|
|
83
|
-
* Preserves opfsRoot/
|
|
84
|
-
* but clears current
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
* Used during soft reset for new recordings (Issue 4, 2026-02-06 user feedback).
|
|
87
|
+
* Preserves opfsRoot/gpsPlusSlamDir/sessionsDir (OPFS stays initialized)
|
|
88
|
+
* but clears current session/actions/frames handles so a new session can
|
|
89
|
+
* be started fresh.
|
|
88
90
|
*/
|
|
89
91
|
declare function resetSessionHandles(): void;
|
|
90
92
|
/**
|
|
91
93
|
* Initialize OPFS storage by creating the required directory structure.
|
|
92
94
|
*
|
|
93
95
|
* Creates:
|
|
94
|
-
* - /gps-
|
|
95
|
-
* - /gps-
|
|
96
|
+
* - /gps-plus-slam/
|
|
97
|
+
* - /gps-plus-slam/sessions/
|
|
96
98
|
*
|
|
97
99
|
* This is idempotent - calling multiple times is safe.
|
|
98
100
|
*
|
|
@@ -100,34 +102,46 @@ declare function resetSessionHandles(): void;
|
|
|
100
102
|
*/
|
|
101
103
|
declare function initOpfsStorage(): Promise<void>;
|
|
102
104
|
/**
|
|
103
|
-
*
|
|
105
|
+
* Get the sessions root directory handle.
|
|
106
|
+
* Used by consumers that need direct OPFS access (e.g. ZIP export).
|
|
107
|
+
*/
|
|
108
|
+
declare function getSessionsRootHandle(): FileSystemDirectoryHandle | null;
|
|
109
|
+
/**
|
|
110
|
+
* Get the app root directory handle (gps-plus-slam/).
|
|
111
|
+
* Used by consumers that need to create additional directories alongside sessions/.
|
|
112
|
+
*/
|
|
113
|
+
declare function getAppRootHandle(): FileSystemDirectoryHandle | null;
|
|
114
|
+
/**
|
|
115
|
+
* Create a new recording session.
|
|
104
116
|
*
|
|
105
117
|
* Creates the directory structure:
|
|
106
|
-
* - /gps-
|
|
107
|
-
* - /gps-
|
|
108
|
-
* - /gps-
|
|
118
|
+
* - /gps-plus-slam/sessions/recording-{timestamp}/
|
|
119
|
+
* - /gps-plus-slam/sessions/recording-{timestamp}/actions/
|
|
120
|
+
* - /gps-plus-slam/sessions/recording-{timestamp}/frames/
|
|
109
121
|
*
|
|
110
|
-
* @param scenarioName - Name of the scenario (creates if doesn't exist)
|
|
111
122
|
* @param timestamp - Session start time (used for folder naming)
|
|
123
|
+
* @param _contextTag - Opaque tag; not used by the flat layout but accepted
|
|
124
|
+
* for interface compatibility with wrapping backends
|
|
112
125
|
* @returns Session information
|
|
113
126
|
* @throws Error if storage not initialized
|
|
114
127
|
*/
|
|
115
|
-
declare function createSession(
|
|
128
|
+
declare function createSession(timestamp: Date, _contextTag?: string): Promise<CreateSessionResult>;
|
|
116
129
|
/**
|
|
117
130
|
* Get the current session directory handle.
|
|
118
|
-
* Useful for test assertions.
|
|
119
131
|
* @internal
|
|
120
132
|
*/
|
|
121
133
|
declare function getSessionHandle(): FileSystemDirectoryHandle | null;
|
|
122
134
|
/**
|
|
123
|
-
*
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
*
|
|
128
|
-
*
|
|
135
|
+
* Set the active session handles externally.
|
|
136
|
+
*
|
|
137
|
+
* Used by file-system.ts's scenario-based path to reuse opfs-storage's
|
|
138
|
+
* write infrastructure for sessions created outside the flat layout.
|
|
139
|
+
* This is a temporary bridge until the recorder migrates to
|
|
140
|
+
* ScenarioWrappingStorageBackend.
|
|
141
|
+
*
|
|
142
|
+
* @internal
|
|
129
143
|
*/
|
|
130
|
-
declare function
|
|
144
|
+
declare function setSessionHandles(session: FileSystemDirectoryHandle, actions: FileSystemDirectoryHandle, frames: FileSystemDirectoryHandle): void;
|
|
131
145
|
/**
|
|
132
146
|
* Write a Redux action to the current session's actions directory.
|
|
133
147
|
*
|
|
@@ -152,25 +166,14 @@ declare function writeFrame(blob: Blob, index: number): Promise<void>;
|
|
|
152
166
|
*/
|
|
153
167
|
declare function writeSessionMetadata(metadata: SessionMetadata): Promise<void>;
|
|
154
168
|
/**
|
|
155
|
-
* List all
|
|
169
|
+
* List all session names in OPFS storage.
|
|
156
170
|
*
|
|
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
171
|
* @returns Array of session folder names
|
|
165
172
|
*/
|
|
166
|
-
declare function listSessions(
|
|
173
|
+
declare function listSessions(): Promise<string[]>;
|
|
167
174
|
/**
|
|
168
175
|
* Check storage quota.
|
|
169
176
|
*
|
|
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
177
|
* @returns Available and used storage in bytes
|
|
175
178
|
*/
|
|
176
179
|
declare function checkStorageQuota(): Promise<{
|
|
@@ -178,4 +181,4 @@ declare function checkStorageQuota(): Promise<{
|
|
|
178
181
|
used: number;
|
|
179
182
|
}>;
|
|
180
183
|
//#endregion
|
|
181
|
-
export {
|
|
184
|
+
export { getAppRootHandle as a, initOpfsStorage as c, resetSessionHandles as d, setSessionHandles as f, writeSessionMetadata as h, createSession as i, listSessions as l, writeFrame as m, SessionMetadata as n, getSessionHandle as o, writeAction as p, checkStorageQuota as r, getSessionsRootHandle as s, CreateSessionResult as t, resetOpfsStorage as u };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { n as SessionMetadata } from "./opfs-storage-DOPkzgeT.js";
|
|
2
|
+
import { n as StorageBackend, t as CreateSessionResult } from "./storage-backend-CT0Il_AB.js";
|
|
3
|
+
|
|
4
|
+
//#region ../src/storage/opfs-storage-backend.d.ts
|
|
5
|
+
declare class OpfsStorageBackend implements StorageBackend {
|
|
6
|
+
createSession(_timestamp: Date, _contextTag?: string): Promise<CreateSessionResult>;
|
|
7
|
+
listSessions(): Promise<string[]>;
|
|
8
|
+
writeAction(action: unknown, index: number): Promise<void>;
|
|
9
|
+
writeFrame(blob: Blob, index: number): Promise<void>;
|
|
10
|
+
writeSessionMetadata(metadata: SessionMetadata): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { OpfsStorageBackend as t };
|
|
@@ -117,6 +117,46 @@ declare function requestOrientationPermission(): Promise<PermissionStatus>;
|
|
|
117
117
|
* Returns current known state of each permission.
|
|
118
118
|
*/
|
|
119
119
|
declare function checkAllPermissions(): Promise<PermissionCheckResult>;
|
|
120
|
+
/**
|
|
121
|
+
* Subscription handle returned by {@link subscribePermissionChanges}.
|
|
122
|
+
* Calling `unsubscribe()` detaches every listener wired by the subscription.
|
|
123
|
+
*/
|
|
124
|
+
interface PermissionSubscription {
|
|
125
|
+
unsubscribe(): void;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Subscribe to out-of-band permission changes.
|
|
129
|
+
*
|
|
130
|
+
* Today the recorder app only re-runs `checkAllPermissions()` at startup
|
|
131
|
+
* and after the user clicks "Grant Permissions" — so a permission flipped
|
|
132
|
+
* via browser settings (e.g. user denies location, then enables it under
|
|
133
|
+
* "site settings") is only detected after a full page reload.
|
|
134
|
+
*
|
|
135
|
+
* This subscription wires three signals:
|
|
136
|
+
* 1. `navigator.permissions.query(...)` returns a live `PermissionStatus`
|
|
137
|
+
* for `'geolocation'` and `'camera'`; we keep those references and
|
|
138
|
+
* attach a `'change'` listener via `addEventListener` so we react
|
|
139
|
+
* immediately when the browser updates the underlying state.
|
|
140
|
+
* 2. `document.visibilitychange` (only when `visibilityState === 'visible'`)
|
|
141
|
+
* covers the "user tabbed out to settings, toggled, tabbed back" case
|
|
142
|
+
* on browsers where the `'change'` event does not fire reliably.
|
|
143
|
+
* 3. `window.focus` covers the same scenario for browsers/standalone
|
|
144
|
+
* windows where `visibilitychange` is not dispatched on focus return.
|
|
145
|
+
*
|
|
146
|
+
* Each signal triggers a fresh {@link checkAllPermissions} call; the
|
|
147
|
+
* resulting {@link PermissionCheckResult} is passed to `callback`.
|
|
148
|
+
*
|
|
149
|
+
* No periodic polling is performed — the trio above is the complete
|
|
150
|
+
* fallback chain. If a browser supports none of these signals for a given
|
|
151
|
+
* permission, the user can still re-check by clicking the (now permanently
|
|
152
|
+
* visible) "Grant Permissions" button.
|
|
153
|
+
*
|
|
154
|
+
* @param callback - Invoked with the latest {@link PermissionCheckResult}
|
|
155
|
+
* each time one of the signals fires. The initial state is **not**
|
|
156
|
+
* delivered; callers are expected to have already rendered it.
|
|
157
|
+
* @returns A handle whose `unsubscribe()` removes every wired listener.
|
|
158
|
+
*/
|
|
159
|
+
declare function subscribePermissionChanges(callback: (result: PermissionCheckResult) => void): PermissionSubscription;
|
|
120
160
|
/**
|
|
121
161
|
* Request all mandatory permissions that haven't been granted yet.
|
|
122
162
|
* Shows browser prompts for each permission that needs requesting.
|
|
@@ -143,4 +183,4 @@ declare function requestAllPermissions(): Promise<PermissionCheckResult>;
|
|
|
143
183
|
*/
|
|
144
184
|
declare function requestWebXRWithDepthPermission(): Promise<PermissionStatus>;
|
|
145
185
|
//#endregion
|
|
146
|
-
export {
|
|
186
|
+
export { subscribePermissionChanges as _, checkCameraPermission as a, checkOrientationPermission as c, requestCameraPermission as d, requestGeolocationPermission as f, setFileSystemState as g, resetFileSystemState as h, checkAllPermissions as i, checkWebXRSupport as l, requestWebXRWithDepthPermission as m, PermissionStatus as n, checkFileSystemPermission as o, requestOrientationPermission as p, PermissionSubscription as r, checkGeolocationPermission as s, PermissionCheckResult as t, requestAllPermissions as u };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { n as StorageBackend } from "./storage-backend-CT0Il_AB.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
|
+
* Slice names whose actions are persisted to the recording stream
|
|
12
|
+
* (e.g. `['gpsData', 'recording', 'refPoints']`).
|
|
13
|
+
*
|
|
14
|
+
* Callers MUST derive these from the actual slices — pass
|
|
15
|
+
* `slicePrefixOf(someActionCreator.type)` or a `slice.name`, never a
|
|
16
|
+
* hand-typed literal. A slice rename then propagates here automatically
|
|
17
|
+
* instead of silently dropping the renamed slice's actions from every
|
|
18
|
+
* recording (the 2026-05-28 `refPointsV2/` → `refPoints/` regression).
|
|
19
|
+
*
|
|
20
|
+
* `recording/recordWriteFailure` is always excluded regardless of this
|
|
21
|
+
* list, to prevent recursive persistence.
|
|
22
|
+
*/
|
|
23
|
+
persistedPrefixes: readonly string[];
|
|
24
|
+
/**
|
|
25
|
+
* Callback invoked when a write operation fails during persistence.
|
|
26
|
+
* User Feedback Issue #1 Part B: Used to show toast notifications.
|
|
27
|
+
*/
|
|
28
|
+
onWriteFailure?: (error: Error) => void;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Extract the slice prefix from a namespaced Redux action type.
|
|
32
|
+
*
|
|
33
|
+
* `'gpsData/setZeroPos'` → `'gpsData'`. Returns the whole string when there
|
|
34
|
+
* is no slash (e.g. `'@@INIT'`). This is the single point that turns a
|
|
35
|
+
* slice-owned action type into the value the persistence whitelist matches
|
|
36
|
+
* on, so call sites can derive prefixes from real action creators instead of
|
|
37
|
+
* re-typing literals.
|
|
38
|
+
*/
|
|
39
|
+
declare function slicePrefixOf(actionType: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* Create a Redux middleware that persists qualifying actions to storage
|
|
42
|
+
* during active recording sessions.
|
|
43
|
+
*
|
|
44
|
+
* Persistence rules:
|
|
45
|
+
* - Only persists when `state.recording.isRecording` is true (checked AFTER
|
|
46
|
+
* the action is reduced, so `startSession` itself is included).
|
|
47
|
+
* - Persists actions whose slice prefix is listed in `persistedPrefixes`.
|
|
48
|
+
* - Excludes `recording/recordWriteFailure` to prevent recursive persistence.
|
|
49
|
+
* - Excludes `routing/*` and any other non-whitelisted actions.
|
|
50
|
+
* - Uses 1-based indexing for action files (000001.json, 000002.json, …).
|
|
51
|
+
* - Each middleware instance maintains its own action index (Bug 10 fix).
|
|
52
|
+
*/
|
|
53
|
+
declare function createPersistenceMiddleware(options: PersistenceMiddlewareOptions): Middleware;
|
|
54
|
+
//#endregion
|
|
55
|
+
export { createPersistenceMiddleware as n, slicePrefixOf as r, PersistenceMiddlewareOptions as t };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { i as RecordedAction } from "./zip-reader-
|
|
1
|
+
import { L as CombinedRootState } from "./create-slam-app-store-CNsZ3rcX.js";
|
|
2
|
+
import { i as RecordedAction } from "./zip-reader-D1105idz.js";
|
|
3
3
|
|
|
4
4
|
//#region ../src/state/recording-replayer.d.ts
|
|
5
5
|
/**
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { i as DepthSample } from "./ar-types-Ck8LEq8k.js";
|
|
2
|
+
import { s as RecordingOptions } from "./recording-options-Dq6IsKAv.js";
|
|
3
|
+
import * as _$_reduxjs_toolkit0 from "@reduxjs/toolkit";
|
|
4
|
+
|
|
5
|
+
//#region ../src/state/recording-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 RecordingState {
|
|
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
|
+
declare const startSession: _$_reduxjs_toolkit0.ActionCreatorWithPayload<SessionMetadata, "recording/startSession">, endSession: _$_reduxjs_toolkit0.ActionCreatorWithoutPayload<"recording/endSession">, recordDepthSample: _$_reduxjs_toolkit0.ActionCreatorWithPayload<DepthSample, "recording/recordDepthSample">, recordWriteFailure: _$_reduxjs_toolkit0.ActionCreatorWithPayload<string, "recording/recordWriteFailure">;
|
|
26
|
+
declare const recordingReducer: _$_reduxjs_toolkit0.Reducer<RecordingState>;
|
|
27
|
+
//#endregion
|
|
28
|
+
export { recordWriteFailure as a, recordDepthSample as i, SessionMetadata as n, recordingReducer as o, endSession as r, startSession as s, RecordingState as t };
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { i as SlamAppStore } from "./create-slam-app-store-CNsZ3rcX.js";
|
|
2
|
+
import { ReducersMapObject } from "@reduxjs/toolkit";
|
|
2
3
|
|
|
3
4
|
//#region ../src/state/replay-engine.d.ts
|
|
5
|
+
/** Minimal store contract used by the replay engine: dispatches plain actions. */
|
|
6
|
+
type RecorderStore = SlamAppStore<ReducersMapObject>;
|
|
4
7
|
/** Default maximum delay between actions in ms (30 seconds real-time) */
|
|
5
8
|
declare const DEFAULT_MAX_DELAY_MS = 30000;
|
|
6
9
|
type ReplayState = 'idle' | 'playing' | 'paused' | 'completed';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { t as CameraFollower } from "./camera-follower-
|
|
2
|
-
import { t as AlignmentLerper } from "./alignment-lerper-
|
|
3
|
-
import { t as Css3dRendererManager } from "./css3d-renderer-manager-
|
|
1
|
+
import { t as CameraFollower } from "./camera-follower-1k8mnw5J.js";
|
|
2
|
+
import { t as AlignmentLerper } from "./alignment-lerper-L1RbWHQ4.js";
|
|
3
|
+
import { t as Css3dRendererManager } from "./css3d-renderer-manager-CkjCb2HW.js";
|
|
4
4
|
import * as THREE from "three";
|
|
5
5
|
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
|
|
6
6
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
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-
|
|
1
|
+
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-Dg3ziRVY.js";
|
|
2
2
|
export { GPS_ERROR_CODES, GPS_ERROR_MESSAGES, GPS_ERROR_MESSAGE_UNKNOWN, createGpsErrorHandler, getGpsErrorMessage };
|
package/dist/sensors/gps.d.ts
CHANGED
|
@@ -1,2 +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-
|
|
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-DXoQb9Kf.js";
|
|
2
2
|
export { GpsPosition, RawDeviceOrientation, requestOrientationPermission, startGpsWatch, startOrientationWatch, stopGpsWatch, stopOrientationWatch };
|
package/dist/sensors/gps.js
CHANGED
package/dist/sensors/index.d.ts
CHANGED
|
@@ -1,4 +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-
|
|
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-
|
|
3
|
-
import { a as
|
|
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-DXoQb9Kf.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-Dg3ziRVY.js";
|
|
3
|
+
import { a as checkCameraPermission, c as checkOrientationPermission, d as requestCameraPermission, f as requestGeolocationPermission, g as setFileSystemState, h as resetFileSystemState, i as checkAllPermissions, l as checkWebXRSupport, m as requestWebXRWithDepthPermission, n as PermissionStatus, o as checkFileSystemPermission, p as requestOrientationPermission$1, s as checkGeolocationPermission, t as PermissionCheckResult, u as requestAllPermissions } from "../permission-checker-DPJl_RU6.js";
|
|
4
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 };
|
package/dist/sensors/index.js
CHANGED
|
@@ -1,4 +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
1
|
import { requestOrientationPermission, startGpsWatch, startOrientationWatch, stopGpsWatch, stopOrientationWatch } from "./gps.js";
|
|
3
2
|
import { GPS_ERROR_CODES, GPS_ERROR_MESSAGES, GPS_ERROR_MESSAGE_UNKNOWN, createGpsErrorHandler, getGpsErrorMessage } from "./gps-error-handler.js";
|
|
3
|
+
import { checkAllPermissions, checkCameraPermission, checkFileSystemPermission, checkGeolocationPermission, checkOrientationPermission, checkWebXRSupport, requestAllPermissions, requestCameraPermission, requestGeolocationPermission, requestOrientationPermission as requestOrientationPermission$1, requestWebXRWithDepthPermission, resetFileSystemState, setFileSystemState } from "./permission-checker.js";
|
|
4
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 };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
export { PermissionCheckResult, PermissionStatus, checkAllPermissions, checkCameraPermission, checkFileSystemPermission, checkGeolocationPermission, checkOrientationPermission, checkWebXRSupport, requestAllPermissions, requestCameraPermission, requestGeolocationPermission, requestOrientationPermission, requestWebXRWithDepthPermission, resetFileSystemState, setFileSystemState };
|
|
1
|
+
import { _ as subscribePermissionChanges, a as checkCameraPermission, c as checkOrientationPermission, d as requestCameraPermission, f as requestGeolocationPermission, g as setFileSystemState, h as resetFileSystemState, i as checkAllPermissions, l as checkWebXRSupport, m as requestWebXRWithDepthPermission, n as PermissionStatus, o as checkFileSystemPermission, p as requestOrientationPermission, r as PermissionSubscription, s as checkGeolocationPermission, t as PermissionCheckResult, u as requestAllPermissions } from "../permission-checker-DPJl_RU6.js";
|
|
2
|
+
export { PermissionCheckResult, PermissionStatus, PermissionSubscription, checkAllPermissions, checkCameraPermission, checkFileSystemPermission, checkGeolocationPermission, checkOrientationPermission, checkWebXRSupport, requestAllPermissions, requestCameraPermission, requestGeolocationPermission, requestOrientationPermission, requestWebXRWithDepthPermission, resetFileSystemState, setFileSystemState, subscribePermissionChanges };
|
|
@@ -321,6 +321,84 @@ async function checkAllPermissions() {
|
|
|
321
321
|
};
|
|
322
322
|
}
|
|
323
323
|
/**
|
|
324
|
+
* Subscribe to out-of-band permission changes.
|
|
325
|
+
*
|
|
326
|
+
* Today the recorder app only re-runs `checkAllPermissions()` at startup
|
|
327
|
+
* and after the user clicks "Grant Permissions" — so a permission flipped
|
|
328
|
+
* via browser settings (e.g. user denies location, then enables it under
|
|
329
|
+
* "site settings") is only detected after a full page reload.
|
|
330
|
+
*
|
|
331
|
+
* This subscription wires three signals:
|
|
332
|
+
* 1. `navigator.permissions.query(...)` returns a live `PermissionStatus`
|
|
333
|
+
* for `'geolocation'` and `'camera'`; we keep those references and
|
|
334
|
+
* attach a `'change'` listener via `addEventListener` so we react
|
|
335
|
+
* immediately when the browser updates the underlying state.
|
|
336
|
+
* 2. `document.visibilitychange` (only when `visibilityState === 'visible'`)
|
|
337
|
+
* covers the "user tabbed out to settings, toggled, tabbed back" case
|
|
338
|
+
* on browsers where the `'change'` event does not fire reliably.
|
|
339
|
+
* 3. `window.focus` covers the same scenario for browsers/standalone
|
|
340
|
+
* windows where `visibilitychange` is not dispatched on focus return.
|
|
341
|
+
*
|
|
342
|
+
* Each signal triggers a fresh {@link checkAllPermissions} call; the
|
|
343
|
+
* resulting {@link PermissionCheckResult} is passed to `callback`.
|
|
344
|
+
*
|
|
345
|
+
* No periodic polling is performed — the trio above is the complete
|
|
346
|
+
* fallback chain. If a browser supports none of these signals for a given
|
|
347
|
+
* permission, the user can still re-check by clicking the (now permanently
|
|
348
|
+
* visible) "Grant Permissions" button.
|
|
349
|
+
*
|
|
350
|
+
* @param callback - Invoked with the latest {@link PermissionCheckResult}
|
|
351
|
+
* each time one of the signals fires. The initial state is **not**
|
|
352
|
+
* delivered; callers are expected to have already rendered it.
|
|
353
|
+
* @returns A handle whose `unsubscribe()` removes every wired listener.
|
|
354
|
+
*/
|
|
355
|
+
function subscribePermissionChanges(callback) {
|
|
356
|
+
let disposed = false;
|
|
357
|
+
const cleanups = [];
|
|
358
|
+
const notify = () => {
|
|
359
|
+
if (disposed) return;
|
|
360
|
+
checkAllPermissions().then((result) => {
|
|
361
|
+
if (!disposed) callback(result);
|
|
362
|
+
}).catch((err) => {
|
|
363
|
+
log.warn("subscribePermissionChanges: re-check failed", err);
|
|
364
|
+
});
|
|
365
|
+
};
|
|
366
|
+
if (typeof navigator !== "undefined" && navigator.permissions && typeof navigator.permissions.query === "function") {
|
|
367
|
+
const wireStatus = (name) => {
|
|
368
|
+
try {
|
|
369
|
+
navigator.permissions.query({ name }).then((status) => {
|
|
370
|
+
if (disposed) return;
|
|
371
|
+
const handler = () => notify();
|
|
372
|
+
status.addEventListener("change", handler);
|
|
373
|
+
cleanups.push(() => status.removeEventListener("change", handler));
|
|
374
|
+
}, () => {});
|
|
375
|
+
} catch {}
|
|
376
|
+
};
|
|
377
|
+
wireStatus("geolocation");
|
|
378
|
+
wireStatus("camera");
|
|
379
|
+
}
|
|
380
|
+
if (typeof document !== "undefined") {
|
|
381
|
+
const onVisibility = () => {
|
|
382
|
+
if (document.visibilityState === "visible") notify();
|
|
383
|
+
};
|
|
384
|
+
document.addEventListener("visibilitychange", onVisibility);
|
|
385
|
+
cleanups.push(() => document.removeEventListener("visibilitychange", onVisibility));
|
|
386
|
+
}
|
|
387
|
+
if (typeof window !== "undefined") {
|
|
388
|
+
const onFocus = () => notify();
|
|
389
|
+
window.addEventListener("focus", onFocus);
|
|
390
|
+
cleanups.push(() => window.removeEventListener("focus", onFocus));
|
|
391
|
+
}
|
|
392
|
+
return { unsubscribe() {
|
|
393
|
+
disposed = true;
|
|
394
|
+
for (const c of cleanups.splice(0)) try {
|
|
395
|
+
c();
|
|
396
|
+
} catch (err) {
|
|
397
|
+
log.warn("subscribePermissionChanges: cleanup failed", err);
|
|
398
|
+
}
|
|
399
|
+
} };
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
324
402
|
* Request all mandatory permissions that haven't been granted yet.
|
|
325
403
|
* Shows browser prompts for each permission that needs requesting.
|
|
326
404
|
*
|
|
@@ -394,4 +472,4 @@ async function requestWebXRWithDepthPermission() {
|
|
|
394
472
|
}
|
|
395
473
|
}
|
|
396
474
|
//#endregion
|
|
397
|
-
export { checkAllPermissions, checkCameraPermission, checkFileSystemPermission, checkGeolocationPermission, checkOrientationPermission, checkWebXRSupport, requestAllPermissions, requestCameraPermission, requestGeolocationPermission, requestOrientationPermission, requestWebXRWithDepthPermission, resetFileSystemState, setFileSystemState };
|
|
475
|
+
export { checkAllPermissions, checkCameraPermission, checkFileSystemPermission, checkGeolocationPermission, checkOrientationPermission, checkWebXRSupport, requestAllPermissions, requestCameraPermission, requestGeolocationPermission, requestOrientationPermission, requestWebXRWithDepthPermission, resetFileSystemState, setFileSystemState, subscribePermissionChanges };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
export { selectAlignmentMatrix, selectGpsPositions, selectOdometryPositions, selectOdometryRotations,
|
|
1
|
+
import { a as selectOdometryRotations, i as selectOdometryPositions, n as selectFrameTilesInWebXR, o as selectZeroReference, r as selectGpsPositions, t as selectAlignmentMatrix } from "../app-selectors-BeU0_ab8.js";
|
|
2
|
+
export { selectAlignmentMatrix, selectFrameTilesInWebXR, selectGpsPositions, selectOdometryPositions, selectOdometryRotations, selectZeroReference };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { nueQuaternionToWebXR, nueToWebXR } from "gps-plus-slam-js";
|
|
1
2
|
import { createSelector } from "@reduxjs/toolkit";
|
|
2
3
|
//#region ../src/state/app-selectors.ts
|
|
3
4
|
/**
|
|
@@ -17,7 +18,7 @@ import { createSelector } from "@reduxjs/toolkit";
|
|
|
17
18
|
const EMPTY_GPS_POSITIONS = [];
|
|
18
19
|
const EMPTY_ODOM_POSITIONS = [];
|
|
19
20
|
const EMPTY_ODOM_ROTATIONS = [];
|
|
20
|
-
const
|
|
21
|
+
const EMPTY_FRAME_TILES = [];
|
|
21
22
|
const selectGpsData = (state) => state.gpsData;
|
|
22
23
|
/** Alignment matrix (4×4), or null if not yet computed. */
|
|
23
24
|
const selectAlignmentMatrix = createSelector([selectGpsData], (gpsData) => gpsData?.gpsEvents?.alignmentMatrix ?? null);
|
|
@@ -30,6 +31,35 @@ const selectOdometryRotations = createSelector([selectGpsData], (gpsData) => gps
|
|
|
30
31
|
/** GPS zero reference (origin for coordinate conversion), or null. */
|
|
31
32
|
const selectZeroReference = createSelector([selectGpsData], (gpsData) => gpsData?.zero ?? null);
|
|
32
33
|
/** User-defined reference points for ground truth validation. */
|
|
33
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Captured AR image frames in WebXR coordinate space.
|
|
36
|
+
*
|
|
37
|
+
* Reads `state.gpsData.odometryPath.points` (which the library reducer
|
|
38
|
+
* stores in NUE convention — see `gpsDataSlice.ts` `add2dImage`) and
|
|
39
|
+
* converts each entry back to WebXR so the live AR scene visualizer can
|
|
40
|
+
* apply the pose directly. This is the source of truth for the
|
|
41
|
+
* frame-tile visualizer; the legacy `framesInScene` slice is a dead
|
|
42
|
+
* mirror scheduled for removal (Step 5 of the 2026-05-27
|
|
43
|
+
* slice-collapse plan).
|
|
44
|
+
*
|
|
45
|
+
* Memoized via createSelector keyed on `odometryPath.points` (NOT the whole
|
|
46
|
+
* `gpsData`). The library reducer uses Immer, so unrelated updates (GPS
|
|
47
|
+
* observations, VIO offsets) produce a new `gpsData` reference while
|
|
48
|
+
* `odometryPath.points` keeps its reference via structural sharing. Keying on
|
|
49
|
+
* the points array therefore preserves referential stability of the output
|
|
50
|
+
* across those dispatches — subscribers like `wireFrameTileSubscribers` only
|
|
51
|
+
* re-run when frames actually change.
|
|
52
|
+
*/
|
|
53
|
+
const selectOdometryPathPoints = (state) => state.gpsData?.odometryPath?.points;
|
|
54
|
+
const selectFrameTilesInWebXR = createSelector([selectOdometryPathPoints], (points) => {
|
|
55
|
+
if (!points || points.length === 0) return EMPTY_FRAME_TILES;
|
|
56
|
+
return points.map((p) => ({
|
|
57
|
+
imageFile: p.imageFile,
|
|
58
|
+
position: nueToWebXR(p.position),
|
|
59
|
+
rotation: nueQuaternionToWebXR(p.rotation),
|
|
60
|
+
screenRotation: p.screenRotation,
|
|
61
|
+
capturedAt: p.capturedAt
|
|
62
|
+
}));
|
|
63
|
+
});
|
|
34
64
|
//#endregion
|
|
35
|
-
export { selectAlignmentMatrix, selectGpsPositions, selectOdometryPositions, selectOdometryRotations,
|
|
65
|
+
export { selectAlignmentMatrix, selectFrameTilesInWebXR, selectGpsPositions, selectOdometryPositions, selectOdometryRotations, selectZeroReference };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as SlamAppStoreOptions, i as SlamAppStore, n as SlamAppMiddleware, o as createSlamAppStore, r as SlamAppRootState, t as SlamAppCombinedState } from "../create-slam-app-store-CNsZ3rcX.js";
|
|
2
|
+
export { SlamAppCombinedState, SlamAppMiddleware, SlamAppRootState, SlamAppStore, SlamAppStoreOptions, createSlamAppStore };
|