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.
Files changed (216) hide show
  1. package/LICENSE +4 -4
  2. package/README.md +249 -108
  3. package/dist/accuracy-circles-CsxE_7x1.d.ts +43 -0
  4. package/dist/{app-selectors-DyMzxCEC.d.ts → app-selectors-BeU0_ab8.d.ts} +14 -15
  5. package/dist/ar/camera-blit-capture.d.ts +1 -1
  6. package/dist/ar/capture-failure-tracker.d.ts +1 -1
  7. package/dist/ar/chromium-camera-access-workaround.d.ts +1 -1
  8. package/dist/ar/depth-sampler.d.ts +2 -2
  9. package/dist/ar/depth-sampler.js +1 -1
  10. package/dist/ar/frame-loop.d.ts +2 -0
  11. package/dist/ar/frame-loop.js +40 -0
  12. package/dist/ar/image-capture.d.ts +1 -1
  13. package/dist/ar/image-capture.js +1 -1
  14. package/dist/ar/index.d.ts +12 -12
  15. package/dist/ar/index.js +3 -3
  16. package/dist/ar/replay-scene.d.ts +1 -1
  17. package/dist/ar/scene-node-names.d.ts +1 -1
  18. package/dist/ar/webxr-session.d.ts +4 -4
  19. package/dist/ar/webxr-session.js +151 -56
  20. package/dist/ar/xr-camera-texture.d.ts +1 -1
  21. package/dist/ar/xr-error-handler.d.ts +1 -1
  22. package/dist/core/index.d.ts +2 -0
  23. package/dist/core/index.js +2 -0
  24. package/dist/create-slam-app-store-CNsZ3rcX.d.ts +371 -0
  25. package/dist/{depth-sampler-BNCtnEoP.d.ts → depth-sampler-xg8vna6c.d.ts} +1 -1
  26. package/dist/file-system-DTApEv_Q.d.ts +114 -0
  27. package/dist/frame-loop-QJIxLin0.d.ts +42 -0
  28. package/dist/frustum-visibility-BHnFrSKQ.d.ts +58 -0
  29. package/dist/{fused-path-DtqCSqJh.d.ts → fused-path-CB4DwWOG.d.ts} +1 -1
  30. package/dist/geo/h3-proximity.d.ts +2 -0
  31. package/dist/{ref-points/h3-ref-point.js → geo/h3-proximity.js} +16 -12
  32. package/dist/geo/index.d.ts +2 -0
  33. package/dist/geo/index.js +2 -0
  34. package/dist/{geo-types-Xx-LVcnw.d.ts → geo-types-CTuF23gG.d.ts} +16 -1
  35. package/dist/{gps-Ddzr2KlX.d.ts → gps-DXoQb9Kf.d.ts} +1 -1
  36. package/dist/gps-anchor-CnWY61XK.d.ts +48 -0
  37. package/dist/gps-anchor-DjC_3MoT.js +257 -0
  38. package/dist/gps-ar-pose-sampler-DsM1Kb2N.d.ts +43 -0
  39. package/dist/{recording-coordinator-DzflP07_.d.ts → gps-event-coordinator-DBx9I1YX.d.ts} +7 -6
  40. package/dist/gps-event-markers-BGr-iLvi.d.ts +103 -0
  41. package/dist/{h3-ref-point-CFhayNSZ.d.ts → h3-proximity-BhfgNbdW.d.ts} +16 -12
  42. package/dist/{image-capture-2pKjYUS6.d.ts → image-capture-DZLxHDN9.d.ts} +1 -1
  43. package/dist/index-gzWJMVpo.d.ts +2 -0
  44. package/dist/index-pOjUCKEP.d.ts +24 -0
  45. package/dist/index.d.ts +59 -56
  46. package/dist/index.js +22 -21
  47. package/dist/{leaflet-map-overlay-CvfQXTye.d.ts → leaflet-map-overlay-Cew7XAoO.d.ts} +32 -17
  48. package/dist/licensing/index.d.ts +1 -1
  49. package/dist/licensing/index.js +1 -1
  50. package/dist/{logger-B81iwxx0.d.ts → logger-C9vugiQb.d.ts} +7 -1
  51. package/dist/map-data-sih4g64v.d.ts +49 -0
  52. package/dist/map-overlay-draw-B3R1c9Xp.d.ts +42 -0
  53. package/dist/{null-storage-backend-CsWvQwN8.d.ts → null-storage-backend-BKOS7JpL.d.ts} +4 -2
  54. package/dist/{opfs-storage-ChOzF_Wp.d.ts → opfs-storage-DOPkzgeT.d.ts} +54 -51
  55. package/dist/opfs-storage-backend-Cj_7PWoq.d.ts +13 -0
  56. package/dist/{permission-checker-jO2ziCWC.d.ts → permission-checker-DPJl_RU6.d.ts} +41 -1
  57. package/dist/persistence-middleware-BkHIqvaA.d.ts +55 -0
  58. package/dist/{recording-replayer-oOzPITrd.d.ts → recording-replayer-CmCIIZ02.d.ts} +2 -2
  59. package/dist/recording-slice-d6OtCrza.d.ts +28 -0
  60. package/dist/{replay-engine-DuX316ae.d.ts → replay-engine-BGBRQyXs.d.ts} +4 -1
  61. package/dist/{replay-scene-DtUm6bsr.d.ts → replay-scene-DpAGcAKY.d.ts} +3 -3
  62. package/dist/sensors/gps-error-handler.d.ts +1 -1
  63. package/dist/sensors/gps.d.ts +1 -1
  64. package/dist/sensors/gps.js +2 -2
  65. package/dist/sensors/index.d.ts +3 -3
  66. package/dist/sensors/index.js +1 -1
  67. package/dist/sensors/permission-checker.d.ts +2 -2
  68. package/dist/sensors/permission-checker.js +79 -1
  69. package/dist/state/app-selectors.d.ts +2 -2
  70. package/dist/state/app-selectors.js +33 -3
  71. package/dist/state/combined-root-state.d.ts +2 -0
  72. package/dist/state/combined-root-state.js +1 -0
  73. package/dist/state/create-slam-app-store.d.ts +2 -0
  74. package/dist/state/create-slam-app-store.js +75 -0
  75. package/dist/state/gps-ar-pose-sampler.d.ts +4 -0
  76. package/dist/state/gps-ar-pose-sampler.js +19 -0
  77. package/dist/state/{recording-coordinator.d.ts → gps-event-coordinator.d.ts} +1 -1
  78. package/dist/state/{recording-coordinator.js → gps-event-coordinator.js} +3 -4
  79. package/dist/state/index.d.ts +17 -17
  80. package/dist/state/index.js +10 -8
  81. package/dist/state/persistence-middleware.d.ts +2 -2
  82. package/dist/state/persistence-middleware.js +39 -11
  83. package/dist/state/recording-options.d.ts +1 -1
  84. package/dist/state/recording-replayer.d.ts +3 -2
  85. package/dist/state/recording-replayer.js +2 -2
  86. package/dist/state/recording-slice.d.ts +2 -0
  87. package/dist/state/{recorder-slice.js → recording-slice.js} +7 -15
  88. package/dist/state/replay-engine.d.ts +1 -1
  89. package/dist/state/replay-engine.js +3 -3
  90. package/dist/state/store-subscribers.d.ts +2 -2
  91. package/dist/state/store-subscribers.js +38 -20
  92. package/dist/state/subscribe-to-selector.d.ts +1 -1
  93. package/dist/state/tracking-quality.d.ts +2 -0
  94. package/dist/state/tracking-quality.js +723 -0
  95. package/dist/state/tracking-slice.d.ts +2 -0
  96. package/dist/state/tracking-slice.js +147 -0
  97. package/dist/storage/file-system-utils.d.ts +1 -1
  98. package/dist/storage/file-system.d.ts +2 -2
  99. package/dist/storage/file-system.js +154 -94
  100. package/dist/storage/index.d.ts +9 -11
  101. package/dist/storage/index.js +5 -7
  102. package/dist/storage/null-storage-backend.d.ts +1 -1
  103. package/dist/storage/null-storage-backend.js +7 -0
  104. package/dist/storage/opfs-storage-backend.d.ts +1 -1
  105. package/dist/storage/opfs-storage-backend.js +7 -1
  106. package/dist/storage/opfs-storage.d.ts +2 -2
  107. package/dist/storage/opfs-storage.js +69 -85
  108. package/dist/storage/storage-backend.d.ts +2 -2
  109. package/dist/storage/zip-export.d.ts +2 -2
  110. package/dist/storage/zip-export.js +55 -62
  111. package/dist/storage/zip-reader.d.ts +2 -2
  112. package/dist/storage/zip-reader.js +32 -5
  113. package/dist/storage-backend-CT0Il_AB.d.ts +28 -0
  114. package/dist/{store-subscribers-CuoIzB5T.d.ts → store-subscribers-Dce_CoJF.d.ts} +31 -7
  115. package/dist/{subscribe-to-selector-UTZ0KkAc.d.ts → subscribe-to-selector-DIHm3BRZ.d.ts} +1 -1
  116. package/dist/test-utils/browser-mocks.d.ts +1 -1
  117. package/dist/test-utils/zip-round-trip-helpers.d.ts +7 -1
  118. package/dist/test-utils/zip-round-trip-helpers.js +6 -5
  119. package/dist/tracking-slice-utCNND8t.d.ts +86 -0
  120. package/dist/types/ar-types.d.ts +1 -1
  121. package/dist/types/geo-types.d.ts +2 -2
  122. package/dist/types/index.d.ts +3 -3
  123. package/dist/utils/concurrency.d.ts +1 -1
  124. package/dist/utils/failure-tracker.d.ts +1 -1
  125. package/dist/utils/format-file-size.d.ts +1 -1
  126. package/dist/utils/fused-path.d.ts +1 -1
  127. package/dist/utils/index.d.ts +6 -6
  128. package/dist/utils/list-formatter.d.ts +1 -1
  129. package/dist/utils/logger.d.ts +1 -1
  130. package/dist/utils/logger.js +68 -8
  131. package/dist/visualization/accuracy-circles.d.ts +2 -0
  132. package/dist/visualization/accuracy-circles.js +57 -0
  133. package/dist/visualization/alignment-lerper.d.ts +1 -1
  134. package/dist/visualization/camera-follower.d.ts +1 -1
  135. package/dist/visualization/css3d-renderer-manager.d.ts +1 -1
  136. package/dist/visualization/frustum-visibility.d.ts +2 -0
  137. package/dist/visualization/frustum-visibility.js +139 -0
  138. package/dist/visualization/gps-anchor.d.ts +2 -0
  139. package/dist/visualization/gps-anchor.js +2 -0
  140. package/dist/visualization/gps-compass-cubes.d.ts +1 -1
  141. package/dist/visualization/gps-event-markers.d.ts +2 -2
  142. package/dist/visualization/gps-event-markers.js +69 -2
  143. package/dist/visualization/index.d.ts +17 -12
  144. package/dist/visualization/index.js +6 -2
  145. package/dist/visualization/leaflet-map-overlay.d.ts +1 -1
  146. package/dist/visualization/leaflet-map-overlay.js +56 -98
  147. package/dist/visualization/lerp-utils.d.ts +1 -1
  148. package/dist/visualization/map-data.d.ts +2 -0
  149. package/dist/visualization/map-data.js +33 -0
  150. package/dist/visualization/map-overlay-draw.d.ts +2 -0
  151. package/dist/visualization/map-overlay-draw.js +107 -0
  152. package/dist/visualization/map-overlay.d.ts +1 -1
  153. package/dist/visualization/three-dispose.d.ts +1 -1
  154. package/dist/visualization/vis-colors.d.ts +1 -1
  155. package/dist/{webxr-session-COlSrXdL.d.ts → webxr-session-DB5cIZnN.d.ts} +53 -12
  156. package/dist/{zip-export-Rtpi75JJ.d.ts → zip-export-QO4iLIi7.d.ts} +58 -7
  157. package/dist/{zip-reader-D7pkpX8K.d.ts → zip-reader-D1105idz.d.ts} +38 -1
  158. package/package.json +29 -18
  159. package/dist/ar/tracking-state.d.ts +0 -2
  160. package/dist/ar/tracking-state.js +0 -164
  161. package/dist/community-license-key-ChZLCJyO.d.ts +0 -21
  162. package/dist/file-system-BsQgYCU3.d.ts +0 -128
  163. package/dist/gps-event-markers-DpEy2qRd.d.ts +0 -67
  164. package/dist/licensing/community-license-key.d.ts +0 -2
  165. package/dist/licensing/community-license-key.js +0 -21
  166. package/dist/opfs-storage-backend-CVcmfJHN.d.ts +0 -11
  167. package/dist/persistence-middleware-DrptY02i.d.ts +0 -31
  168. package/dist/recorder-slice-fcwAXrsh.d.ts +0 -35
  169. package/dist/ref-point-importer-B_wn5ABk.d.ts +0 -62
  170. package/dist/ref-point-loader-Pt1smgHS.d.ts +0 -117
  171. package/dist/ref-points/h3-ref-point.d.ts +0 -2
  172. package/dist/ref-points/index.d.ts +0 -2
  173. package/dist/ref-points/index.js +0 -2
  174. package/dist/ref-points-slice-tC-Wd6XJ.d.ts +0 -48
  175. package/dist/reference-points-CFWy8_wj.d.ts +0 -68
  176. package/dist/routing-slice-BlHTM8eh.d.ts +0 -23
  177. package/dist/state/recorder-slice.d.ts +0 -2
  178. package/dist/state/ref-points-slice.d.ts +0 -2
  179. package/dist/state/ref-points-slice.js +0 -44
  180. package/dist/state/routing-slice.d.ts +0 -2
  181. package/dist/state/routing-slice.js +0 -13
  182. package/dist/state/store.d.ts +0 -9
  183. package/dist/state/store.js +0 -71
  184. package/dist/storage/ref-point-importer.d.ts +0 -2
  185. package/dist/storage/ref-point-importer.js +0 -163
  186. package/dist/storage/ref-point-loader.d.ts +0 -2
  187. package/dist/storage/ref-point-loader.js +0 -248
  188. package/dist/storage/ref-point-recovery.d.ts +0 -28
  189. package/dist/storage/ref-point-recovery.js +0 -159
  190. package/dist/storage-backend-BcEItnFr.d.ts +0 -20
  191. package/dist/store-C7PKOj8S.d.ts +0 -96
  192. package/dist/tracking-state-B9QfuZCg.d.ts +0 -101
  193. package/dist/visualization/reference-points.d.ts +0 -2
  194. package/dist/visualization/reference-points.js +0 -160
  195. /package/dist/{alignment-lerper-D9BeDwZX.d.ts → alignment-lerper-L1RbWHQ4.d.ts} +0 -0
  196. /package/dist/{ar-types-B-ORgk6Z.d.ts → ar-types-Ck8LEq8k.d.ts} +0 -0
  197. /package/dist/{camera-blit-capture-DHuyrrxr.d.ts → camera-blit-capture-C1V9I1Z6.d.ts} +0 -0
  198. /package/dist/{camera-follower-BMqPddxx.d.ts → camera-follower-1k8mnw5J.d.ts} +0 -0
  199. /package/dist/{capture-failure-tracker-2Q6oI2uQ.d.ts → capture-failure-tracker-JKb1ST8E.d.ts} +0 -0
  200. /package/dist/{chromium-camera-access-workaround-CU5zSKNr.d.ts → chromium-camera-access-workaround-NvChXsi8.d.ts} +0 -0
  201. /package/dist/{concurrency-p6gB30fT.d.ts → concurrency-CMw8pSaG.d.ts} +0 -0
  202. /package/dist/{css3d-renderer-manager-rgLMVAvd.d.ts → css3d-renderer-manager-CkjCb2HW.d.ts} +0 -0
  203. /package/dist/{failure-tracker-1sQ_Cgyw.d.ts → failure-tracker-DnHXOIRa.d.ts} +0 -0
  204. /package/dist/{file-system-utils-5cWO8Xyv.d.ts → file-system-utils-CtKiiw27.d.ts} +0 -0
  205. /package/dist/{format-file-size-onGq0k1Q.d.ts → format-file-size-BTS5H62-.d.ts} +0 -0
  206. /package/dist/{gps-compass-cubes-C-6JEnpR.d.ts → gps-compass-cubes-CsLtFv4B.d.ts} +0 -0
  207. /package/dist/{gps-error-handler-VPuNOuf8.d.ts → gps-error-handler-Dg3ziRVY.d.ts} +0 -0
  208. /package/dist/{lerp-utils-87NWjUOD.d.ts → lerp-utils-B8MM8zCR.d.ts} +0 -0
  209. /package/dist/{list-formatter-DKQQVLcl.d.ts → list-formatter-CNqi-E2j.d.ts} +0 -0
  210. /package/dist/{map-overlay-DuiZuCTx.d.ts → map-overlay-DAmreyA3.d.ts} +0 -0
  211. /package/dist/{recording-options-BYUFX8iU.d.ts → recording-options-Dq6IsKAv.d.ts} +0 -0
  212. /package/dist/{scene-node-names-DPsaE2z3.d.ts → scene-node-names-6LBjPmwz.d.ts} +0 -0
  213. /package/dist/{three-dispose-CCBHjE_a.d.ts → three-dispose-C2drkp6f.d.ts} +0 -0
  214. /package/dist/{vis-colors-Qi2vlRGt.d.ts → vis-colors-CHQhjal3.d.ts} +0 -0
  215. /package/dist/{xr-camera-texture-BbukNE79.d.ts → xr-camera-texture-BU5YvKAM.d.ts} +0 -0
  216. /package/dist/{xr-error-handler-DTHfmvrl.d.ts → xr-error-handler-CDY5QxGb.d.ts} +0 -0
@@ -77,6 +77,11 @@ declare function loadSessionMetadataFromBlob(blob: Blob, maxFileSize?: number):
77
77
  interface GpsPathCoord {
78
78
  readonly lat: number;
79
79
  readonly lng: number;
80
+ /**
81
+ * Horizontal accuracy in meters (1σ), if the source GPS event included it.
82
+ * Used by 2D-map previews to draw a per-event accuracy circle.
83
+ */
84
+ readonly accuracy?: number;
80
85
  }
81
86
  /**
82
87
  * Extract GPS coordinates from a recording zip provided as a Blob.
@@ -93,5 +98,37 @@ interface GpsPathCoord {
93
98
  * @returns Array of GPS coordinates in chronological order
94
99
  */
95
100
  declare function loadGpsPathFromBlob(blob: Blob, maxFileSize?: number): Promise<GpsPathCoord[]>;
101
+ /**
102
+ * A single file pulled out of a contributor-owned subdirectory inside a
103
+ * recording zip. Returned by {@link loadEntriesFromSubdir}.
104
+ *
105
+ * `getText()` is lazy: callers pay the decompression cost only for files they
106
+ * actually open, so iterating an entire `refPoints/` subdir to harvest a few
107
+ * entries stays cheap.
108
+ */
109
+ interface ZipSubdirEntry {
110
+ /** Filename relative to the subdir (e.g. `'42.json'`, not `'refPoints/42.json'`). */
111
+ readonly relativePath: string;
112
+ /** Original full filename inside the ZIP (`'refPoints/42.json'`). */
113
+ readonly fullPath: string;
114
+ /** Uncompressed size in bytes. */
115
+ readonly uncompressedSize: number;
116
+ /** Lazily decode the entry as UTF-8 text. */
117
+ getText(): Promise<string>;
118
+ }
119
+ /**
120
+ * Enumerate every file under a single top-level subdirectory of a recording
121
+ * zip. Mirrors the writer-side {@link ZipExportContributor} seam so consumers
122
+ * (typically the recorder) can read back what they wrote without
123
+ * re-implementing zip enumeration.
124
+ *
125
+ * Skips directory entries and files outside `subdir`. Sorts entries by
126
+ * `relativePath` for deterministic iteration. Returns an empty array when
127
+ * the subdir is absent (graceful degradation for older zips).
128
+ *
129
+ * @param data - The zip file content as a Uint8Array
130
+ * @param subdir - Top-level subdir to scan (no leading or trailing `/`)
131
+ */
132
+ declare function loadEntriesFromSubdir(data: Uint8Array, subdir: string): Promise<ZipSubdirEntry[]>;
96
133
  //#endregion
97
- export { ZipActionEntry as a, loadSessionMetadata as c, RecordedAction as i, loadSessionMetadataFromBlob as l, GpsPathCoord as n, loadActionsFromZip as o, MAX_ACTION_FILE_SIZE as r, loadGpsPathFromBlob as s, Entry$1 as t, readZipEntries as u };
134
+ export { ZipActionEntry as a, loadEntriesFromSubdir as c, loadSessionMetadataFromBlob as d, readZipEntries as f, RecordedAction as i, loadGpsPathFromBlob as l, GpsPathCoord as n, ZipSubdirEntry as o, MAX_ACTION_FILE_SIZE as r, loadActionsFromZip as s, Entry$1 as t, loadSessionMetadata as u };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gps-plus-slam-app-framework",
3
- "version": "1.0.0",
3
+ "version": "1.0.7",
4
4
  "description": "Reusable AR+GPS app framework layer — WebXR session management, Three.js visualization, GPS sensors, storage abstractions, replay engine, and store wiring for gps-plus-slam-js.",
5
5
  "type": "module",
6
6
  "files": [
@@ -10,14 +10,15 @@
10
10
  ".": "./dist/index.js",
11
11
  "./ar": "./dist/ar/index.js",
12
12
  "./ar/*": "./dist/ar/*.js",
13
+ "./core": "./dist/core/index.js",
13
14
  "./sensors": "./dist/sensors/index.js",
14
15
  "./sensors/*": "./dist/sensors/*.js",
15
16
  "./state": "./dist/state/index.js",
16
17
  "./state/*": "./dist/state/*.js",
17
18
  "./storage": "./dist/storage/index.js",
18
19
  "./storage/*": "./dist/storage/*.js",
19
- "./ref-points": "./dist/ref-points/index.js",
20
- "./ref-points/*": "./dist/ref-points/*.js",
20
+ "./geo": "./dist/geo/index.js",
21
+ "./geo/*": "./dist/geo/*.js",
21
22
  "./visualization": "./dist/visualization/index.js",
22
23
  "./visualization/*": "./dist/visualization/*.js",
23
24
  "./utils": "./dist/utils/index.js",
@@ -35,7 +36,7 @@
35
36
  "dependencies": {
36
37
  "@reduxjs/toolkit": "^2.11.2",
37
38
  "gl-matrix": "3.4.4",
38
- "gps-plus-slam-js": "^1.0.0"
39
+ "gps-plus-slam-js": "^1.0.7"
39
40
  },
40
41
  "peerDependencies": {
41
42
  "@sentry/browser": ">=10.0.0",
@@ -54,27 +55,27 @@
54
55
  },
55
56
  "devDependencies": {
56
57
  "@eslint/js": "^10.0.1",
57
- "@sentry/browser": "^10.49.0",
58
+ "@sentry/browser": "^10.53.1",
58
59
  "@types/leaflet": "^1.9.21",
59
- "@types/node": "^25.6.0",
60
- "@types/three": "^0.184.0",
61
- "@vitest/coverage-v8": "^4.1.5",
62
- "@vitest/eslint-plugin": "^1.6.16",
60
+ "@types/node": "^25.7.0",
61
+ "@types/three": "^0.184.1",
62
+ "@vitest/coverage-v8": "^4.1.6",
63
+ "@vitest/eslint-plugin": "^1.6.17",
63
64
  "@zip.js/zip.js": "^2.8.26",
64
- "dpdm": "^4.0.1",
65
- "eslint": "^10.2.1",
65
+ "dpdm": "^4.2.0",
66
+ "eslint": "^10.3.0",
66
67
  "eslint-config-prettier": "^10.1.8",
67
- "fast-check": "^4.7.0",
68
- "globals": "^17.5.0",
68
+ "fast-check": "^4.8.0",
69
+ "globals": "^17.6.0",
69
70
  "h3-js": "^4.4.0",
70
- "jsdom": "^29.0.2",
71
+ "jsdom": "^29.1.1",
71
72
  "leaflet": "^1.9.4",
72
73
  "prettier": "^3.8.3",
73
74
  "three": "^0.184.0",
74
- "tsdown": "^0.21.9",
75
+ "tsdown": "^0.22.0",
75
76
  "typescript": "^6.0.3",
76
- "typescript-eslint": "^8.59.0",
77
- "vitest": "^4.1.5"
77
+ "typescript-eslint": "^8.59.3",
78
+ "vitest": "^4.1.6"
78
79
  },
79
80
  "keywords": [
80
81
  "ar",
@@ -86,6 +87,15 @@
86
87
  ],
87
88
  "author": "cs-util-com",
88
89
  "license": "Apache-2.0",
90
+ "repository": {
91
+ "type": "git",
92
+ "url": "https://github.com/cs-util-com/location-based-webxr.git",
93
+ "directory": "GpsPlusSlamJs_AppFramework"
94
+ },
95
+ "homepage": "https://github.com/cs-util-com/location-based-webxr#readme",
96
+ "bugs": {
97
+ "url": "https://github.com/cs-util-com/location-based-webxr/issues"
98
+ },
89
99
  "scripts": {
90
100
  "test": "pnpm run test:core",
91
101
  "test:core": "pnpm run format && pnpm run lint && pnpm run typecheck && pnpm run typecheck:tests && pnpm run test:unit",
@@ -93,8 +103,9 @@
93
103
  "format:check": "prettier --check --ignore-unknown .",
94
104
  "build": "tsdown --config config/tsdown.config.ts",
95
105
  "verify:pack": "pnpm pack --dry-run",
106
+ "verify:community-key-lifetime": "node scripts/verify-community-key-lifetime.mjs",
96
107
  "test:unit": "vitest run --coverage --config config/vitest.config.ts",
97
- "typecheck": "tsc -p tsconfig.json --noEmit",
108
+ "typecheck": "tsc -p tsconfig.app.json --noEmit",
98
109
  "typecheck:tests": "tsc -p tsconfig.vitest.json --noEmit",
99
110
  "lint": "eslint . --config config/eslint.config.mjs",
100
111
  "test:watch": "vitest --config config/vitest.config.ts",
@@ -1,2 +0,0 @@
1
- import { a as TrackingStateManager, i as TrackingStateCallbacks, n as ResetTransformData, r as TrackingState, t as DeviceOrientation } from "../tracking-state-B9QfuZCg.js";
2
- export { DeviceOrientation, ResetTransformData, TrackingState, TrackingStateCallbacks, TrackingStateManager };
@@ -1,164 +0,0 @@
1
- import { createLogger } from "../utils/logger.js";
2
- import { extractOdomPosition } from "../state/recording-coordinator.js";
3
- //#region ../src/ar/tracking-state.ts
4
- /**
5
- * Tracking State Manager
6
- *
7
- * Detects AR tracking loss and restart events, maintaining state
8
- * about the last valid odometry pose for alignment correction.
9
- *
10
- * ARCHITECTURE NOTE: See docs/architecture-ar-gps-pose-separation.md
11
- *
12
- * When WebXR tracking is lost and restarted, the odometry frame resets
13
- * to a new origin. To maintain GPS+AR alignment, we need to:
14
- * 1. Store the last valid pose before tracking was lost
15
- * 2. Detect when tracking resumes with a new pose
16
- * 3. Dispatch odometryTrackingRestarted with both poses for offset calculation
17
- */
18
- const log = createLogger("TrackingState");
19
- /**
20
- * Possible tracking states
21
- */
22
- let TrackingState = /* @__PURE__ */ function(TrackingState) {
23
- /** AR session started but no pose received yet */
24
- TrackingState["INITIALIZING"] = "initializing";
25
- /** Actively receiving valid poses */
26
- TrackingState["TRACKING"] = "tracking";
27
- /** Pose became unavailable (tracking lost) */
28
- TrackingState["LOST"] = "lost";
29
- return TrackingState;
30
- }({});
31
- /**
32
- * Manages AR tracking state and detects loss/restart events.
33
- */
34
- var TrackingStateManager = class {
35
- state = "initializing";
36
- lastValidPose = null;
37
- lastSensorOrientation = null;
38
- lostFrameCount = 0;
39
- originResetDuringLoss = false;
40
- resetTransform = void 0;
41
- callbacks;
42
- constructor(callbacks) {
43
- this.callbacks = callbacks;
44
- }
45
- /**
46
- * Get current tracking state.
47
- */
48
- getState() {
49
- return this.state;
50
- }
51
- /**
52
- * Get the last valid AR pose (before tracking was lost).
53
- */
54
- getLastValidPose() {
55
- return this.lastValidPose;
56
- }
57
- /**
58
- * Get count of consecutive frames without pose (during LOST state).
59
- */
60
- getLostFrameCount() {
61
- return this.lostFrameCount;
62
- }
63
- /**
64
- * Flag that an XRReferenceSpace reset event occurred during tracking loss.
65
- * Only meaningful while in LOST state — ignored otherwise.
66
- *
67
- * @param transform — Serialized XRReferenceSpaceEvent.transform (post-reset
68
- * origin in pre-reset coordinates). Pass `null` when the event's
69
- * transform property is null (runtime can't determine delta).
70
- * Omit entirely for backwards-compat with callers that don't have it.
71
- */
72
- markOriginReset(transform) {
73
- if (this.state === "lost") {
74
- this.originResetDuringLoss = true;
75
- this.resetTransform = transform;
76
- }
77
- }
78
- /**
79
- * Called when a valid pose is received from WebXR.
80
- */
81
- onPoseReceived(pose) {
82
- if (this.state === "lost") this.handleTrackingRestarted(pose);
83
- this.state = "tracking";
84
- this.lastValidPose = pose;
85
- this.lastSensorOrientation = this.callbacks.getDeviceOrientation();
86
- this.lostFrameCount = 0;
87
- }
88
- /**
89
- * Called when pose is null/unavailable from WebXR.
90
- */
91
- onPoseLost() {
92
- this.lostFrameCount++;
93
- if (this.state === "tracking") {
94
- this.state = "lost";
95
- this.callbacks.onTrackingLost();
96
- log.warn("AR tracking lost");
97
- }
98
- }
99
- /**
100
- * Reset the manager to initial state.
101
- * Call this when starting a new session.
102
- */
103
- reset() {
104
- this.state = "initializing";
105
- this.lastValidPose = null;
106
- this.lastSensorOrientation = null;
107
- this.lostFrameCount = 0;
108
- this.originResetDuringLoss = false;
109
- this.resetTransform = void 0;
110
- }
111
- /**
112
- * Handle the transition from LOST to TRACKING (restart detected).
113
- */
114
- handleTrackingRestarted(newPose) {
115
- const hadReset = this.originResetDuringLoss;
116
- const savedResetTransform = this.resetTransform;
117
- this.originResetDuringLoss = false;
118
- this.resetTransform = void 0;
119
- if (!hadReset) {
120
- log.info("AR tracking recovered (same coordinate frame)");
121
- this.callbacks.onTrackingRecovered?.();
122
- return;
123
- }
124
- if (!this.lastValidPose) {
125
- log.warn("Tracking restarted but no previous pose available");
126
- return;
127
- }
128
- const currentSensorOrientation = this.callbacks.getDeviceOrientation();
129
- const lastOrientation = this.lastSensorOrientation ?? currentSensorOrientation;
130
- const payload = {
131
- lastValidOdomPos: extractOdomPosition(this.lastValidPose),
132
- lastValidOdomRot: [
133
- this.lastValidPose.orientation.x,
134
- this.lastValidPose.orientation.y,
135
- this.lastValidPose.orientation.z,
136
- this.lastValidPose.orientation.w
137
- ],
138
- lastSensorOrientation: {
139
- alpha: lastOrientation.alpha,
140
- beta: lastOrientation.beta,
141
- gamma: lastOrientation.gamma,
142
- absolute: lastOrientation.absolute
143
- },
144
- newOdomRot: [
145
- newPose.orientation.x,
146
- newPose.orientation.y,
147
- newPose.orientation.z,
148
- newPose.orientation.w
149
- ],
150
- newSensorOrientation: {
151
- alpha: currentSensorOrientation.alpha,
152
- beta: currentSensorOrientation.beta,
153
- gamma: currentSensorOrientation.gamma,
154
- absolute: currentSensorOrientation.absolute
155
- },
156
- newOdomPos: extractOdomPosition(newPose),
157
- resetTransform: savedResetTransform
158
- };
159
- log.info("AR tracking restarted (origin reset), dispatching alignment correction");
160
- this.callbacks.onTrackingRestarted(payload);
161
- }
162
- };
163
- //#endregion
164
- export { TrackingState, TrackingStateManager };
@@ -1,21 +0,0 @@
1
- //#region ../src/licensing/community-license-key.d.ts
2
- /**
3
- * Community license key for the gps-plus-slam-js core library.
4
- *
5
- * Generated by the core library maintainers and bundled with the open-source
6
- * `gps-plus-slam-app-framework` package so that every example app (and any
7
- * downstream app built on the framework) automatically uses a valid license
8
- * without per-developer registration.
9
- *
10
- * The key has a rolling expiration of 12 months. Each release of the
11
- * open-source packages renews it. Active users who regularly update their
12
- * dependencies will never be affected by the expiration.
13
- *
14
- * For licenses with extended validity beyond the community key's scope,
15
- * contact support@csutil.com.
16
- *
17
- * @see GpsPlusSlamJs/EULA.md §3 — License Key
18
- */
19
- declare const COMMUNITY_LICENSE_KEY = "eyJ0eXBlIjoiY29tbXVuaXR5IiwiZXhwIjoxODA4NzcyNDI3fQ.YYNf0IdqniZdMzRXCuvewxsQQ01XNywrKsfL5IpiJotfFJfqtrGg4u9z0QFhXeszPtUhnvgC8_oOnbOkbXPuAw";
20
- //#endregion
21
- export { COMMUNITY_LICENSE_KEY as t };
@@ -1,128 +0,0 @@
1
- import { n as ArPoseTuples } from "./ar-types-B-ORgk6Z.js";
2
- import { n as SessionMetadata } from "./opfs-storage-ChOzF_Wp.js";
3
- import { LatLongAlt } from "gps-plus-slam-js";
4
-
5
- //#region ../src/storage/file-system.d.ts
6
- /**
7
- * Reset module state - exported for testing only
8
- * @internal
9
- */
10
- declare function resetStorageState(): void;
11
- /**
12
- * Reset session-level state for a new recording.
13
- *
14
- * Clears scenario/session names and OPFS session handles, but preserves
15
- * `storageInitialized` and the OPFS root so `initStorage()` doesn't need
16
- * to be called again.
17
- *
18
- * Used during soft reset for new recordings (Issue 4, 2026-02-06 user feedback).
19
- */
20
- declare function resetForNewSession(): void;
21
- /**
22
- * Result of write access verification.
23
- */
24
- interface WriteAccessResult {
25
- /** Whether write access was successfully verified */
26
- success: boolean;
27
- /** Error message if write verification failed */
28
- error?: string;
29
- }
30
- /**
31
- * Verify that we have actual write access to a directory.
32
- *
33
- * This probes the directory by creating a test file, writing content,
34
- * and cleaning up. This catches cases where showDirectoryPicker grants
35
- * a handle but the underlying file system is read-only.
36
- *
37
- * User Feedback Issue #1: Even with mode: 'readwrite', Android can
38
- * return a handle where getFileHandle({create: true}) succeeds but
39
- * createWritable() fails with NoModificationAllowedError.
40
- *
41
- * @param dirHandle - Directory handle to verify
42
- * @returns Success status and optional error message
43
- */
44
- declare function verifyWriteAccess(dirHandle: FileSystemDirectoryHandle): Promise<WriteAccessResult>;
45
- /**
46
- * Initialize storage using OPFS.
47
- *
48
- * This replaces the old showDirectoryPicker approach which failed on Android Chrome.
49
- * OPFS is automatically available and doesn't require user folder selection.
50
- *
51
- * @returns List of existing scenario folder names
52
- * @throws Error if OPFS is not supported
53
- */
54
- declare function initStorage(): Promise<string[]>;
55
- /**
56
- * Create or open a scenario folder, then create a new session folder.
57
- *
58
- * Now uses OPFS backend instead of showDirectoryPicker.
59
- *
60
- * @param scenarioName - Name of the scenario
61
- */
62
- declare function startSession(scenarioName: string): Promise<{
63
- scenarioPath: string;
64
- sessionPath: string;
65
- }>;
66
- /**
67
- * Write a Redux action to OPFS as a JSON file.
68
- */
69
- declare function writeAction(action: unknown, index: number): Promise<void>;
70
- /**
71
- * Write a captured frame image to OPFS.
72
- */
73
- declare function writeFrame(blob: Blob, index: number): Promise<void>;
74
- /**
75
- * Write session metadata (session.json) to OPFS.
76
- * Contains timing, counts, and user agent for the recording session.
77
- */
78
- declare function writeSessionMetadata(metadata: SessionMetadata): Promise<void>;
79
- /**
80
- * Shape of a parsed action file for type safety
81
- */
82
- interface ParsedRefPointAction {
83
- type: string;
84
- payload: {
85
- id: string;
86
- gpsPosition?: LatLongAlt;
87
- arPose?: ArPoseTuples;
88
- };
89
- }
90
- /**
91
- * Type guard for reference point actions
92
- * Exported for testing
93
- */
94
- declare function isRefPointAction(action: unknown): action is ParsedRefPointAction;
95
- /**
96
- * Load existing reference points from a scenario (across all sessions).
97
- * Now uses OPFS storage backend.
98
- */
99
- declare function loadScenarioRefPoints(scenarioName: string): Promise<RefPointRecord[]>;
100
- /**
101
- * Get the current scenario handle (for loading prior sessions).
102
- * Now delegates to OPFS storage backend.
103
- */
104
- declare function getCurrentScenarioHandle(): FileSystemDirectoryHandle | null;
105
- /**
106
- * Set the current scenario handle (when user selects a scenario).
107
- * With OPFS, we just store the name - the actual handle is retrieved when needed.
108
- */
109
- declare function setCurrentScenario(scenarioName: string): Promise<FileSystemDirectoryHandle | null>;
110
- /**
111
- * Ensure a scenario directory exists in OPFS, creating it if necessary.
112
- * Used during OPFS recovery when the scenario directory was lost but ZIP
113
- * data is available for restoration.
114
- *
115
- * Unlike setCurrentScenario() which only reads, this creates on demand.
116
- */
117
- declare function ensureScenarioDirectory(scenarioName: string): Promise<FileSystemDirectoryHandle | null>;
118
- /**
119
- * Reference point record from prior sessions
120
- */
121
- interface RefPointRecord {
122
- id: string;
123
- sessionName: string;
124
- gpsPosition?: LatLongAlt;
125
- arPose?: ArPoseTuples;
126
- }
127
- //#endregion
128
- export { initStorage as a, resetForNewSession as c, startSession as d, verifyWriteAccess as f, writeSessionMetadata as h, getCurrentScenarioHandle as i, resetStorageState as l, writeFrame as m, WriteAccessResult as n, isRefPointAction as o, writeAction as p, ensureScenarioDirectory as r, loadScenarioRefPoints as s, RefPointRecord as t, setCurrentScenario as u };
@@ -1,67 +0,0 @@
1
- import { LatLong, Vector3 } from "gps-plus-slam-js";
2
-
3
- //#region ../src/visualization/gps-event-markers.d.ts
4
- /**
5
- * Manager for GPS event visualization
6
- */
7
- declare class GpsEventVisualizer {
8
- private rawGpsMarkers;
9
- private fusedMarkers;
10
- private snapshotMarkers;
11
- private zeroRef;
12
- private eventCounter;
13
- private snapshotCounter;
14
- /**
15
- * Set the GPS zero reference (origin for coordinate conversion).
16
- * Must be called before adding GPS events.
17
- *
18
- * @param zero - GPS coordinates of the origin
19
- */
20
- setZeroRef(zero: LatLong): void;
21
- /**
22
- * Get the current zero reference
23
- */
24
- getZeroRef(): LatLong | null;
25
- /**
26
- * Add a GPS event to the visualization.
27
- * Creates both a raw GPS marker and a fused alignment marker.
28
- *
29
- * @param gpsCoords - GPS position as [x, y, z] meters from zero reference
30
- * @param odomPosition - AR odometry position at the time of GPS reading
31
- */
32
- addGpsEvent(gpsCoords: Vector3, odomPosition: Vector3): void;
33
- /**
34
- * Add an alignment snapshot marker at the given NUE position.
35
- * Snapshots represent the system's best GPS estimate at each alignment update.
36
- * Added to scene root (GPS world space), not arWorldGroup.
37
- */
38
- addAlignmentSnapshot(nuePosition: Vector3): void;
39
- /**
40
- * Get the NUE positions of all alignment snapshot markers.
41
- * Used at session end to convert to GPS coordinates for the summary map.
42
- */
43
- getAlignmentSnapshotPositions(): Vector3[];
44
- /**
45
- * Create a sphere marker mesh with the given color and name.
46
- */
47
- private createMarkerMesh;
48
- /**
49
- * Clear all markers from the scene and reset state.
50
- */
51
- clearAll(): void;
52
- /**
53
- * Get count of visible markers.
54
- */
55
- getCounts(): {
56
- raw: number;
57
- fused: number;
58
- snapshots: number;
59
- };
60
- }
61
- /**
62
- * Singleton instance for global use.
63
- * Import this to visualize GPS events.
64
- */
65
- declare const gpsEventVisualizer: GpsEventVisualizer;
66
- //#endregion
67
- export { gpsEventVisualizer as n, GpsEventVisualizer as t };
@@ -1,2 +0,0 @@
1
- import { t as COMMUNITY_LICENSE_KEY } from "../community-license-key-ChZLCJyO.js";
2
- export { COMMUNITY_LICENSE_KEY };
@@ -1,21 +0,0 @@
1
- //#region ../src/licensing/community-license-key.ts
2
- /**
3
- * Community license key for the gps-plus-slam-js core library.
4
- *
5
- * Generated by the core library maintainers and bundled with the open-source
6
- * `gps-plus-slam-app-framework` package so that every example app (and any
7
- * downstream app built on the framework) automatically uses a valid license
8
- * without per-developer registration.
9
- *
10
- * The key has a rolling expiration of 12 months. Each release of the
11
- * open-source packages renews it. Active users who regularly update their
12
- * dependencies will never be affected by the expiration.
13
- *
14
- * For licenses with extended validity beyond the community key's scope,
15
- * contact support@csutil.com.
16
- *
17
- * @see GpsPlusSlamJs/EULA.md §3 — License Key
18
- */
19
- const COMMUNITY_LICENSE_KEY = "eyJ0eXBlIjoiY29tbXVuaXR5IiwiZXhwIjoxODA4NzcyNDI3fQ.YYNf0IdqniZdMzRXCuvewxsQQ01XNywrKsfL5IpiJotfFJfqtrGg4u9z0QFhXeszPtUhnvgC8_oOnbOkbXPuAw";
20
- //#endregion
21
- export { COMMUNITY_LICENSE_KEY };
@@ -1,11 +0,0 @@
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 };
@@ -1,31 +0,0 @@
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 };
@@ -1,35 +0,0 @@
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 };