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.
- package/LICENSE +201 -0
- package/README.md +222 -0
- package/dist/alignment-lerper-D9BeDwZX.d.ts +29 -0
- package/dist/app-selectors-DyMzxCEC.d.ts +140 -0
- package/dist/ar/camera-blit-capture.d.ts +2 -0
- package/dist/ar/camera-blit-capture.js +253 -0
- package/dist/ar/capture-failure-tracker.d.ts +2 -0
- package/dist/ar/capture-failure-tracker.js +45 -0
- package/dist/ar/chromium-camera-access-workaround.d.ts +2 -0
- package/dist/ar/chromium-camera-access-workaround.js +32 -0
- package/dist/ar/depth-sampler.d.ts +3 -0
- package/dist/ar/depth-sampler.js +147 -0
- package/dist/ar/image-capture.d.ts +2 -0
- package/dist/ar/image-capture.js +152 -0
- package/dist/ar/index.d.ts +12 -0
- package/dist/ar/index.js +12 -0
- package/dist/ar/replay-scene.d.ts +2 -0
- package/dist/ar/replay-scene.js +325 -0
- package/dist/ar/scene-node-names.d.ts +2 -0
- package/dist/ar/scene-node-names.js +16 -0
- package/dist/ar/tracking-state.d.ts +2 -0
- package/dist/ar/tracking-state.js +164 -0
- package/dist/ar/webxr-session.d.ts +4 -0
- package/dist/ar/webxr-session.js +890 -0
- package/dist/ar/xr-camera-texture.d.ts +2 -0
- package/dist/ar/xr-camera-texture.js +39 -0
- package/dist/ar/xr-error-handler.d.ts +2 -0
- package/dist/ar/xr-error-handler.js +37 -0
- package/dist/ar-types-B-ORgk6Z.d.ts +82 -0
- package/dist/camera-blit-capture-DHuyrrxr.d.ts +108 -0
- package/dist/camera-follower-BMqPddxx.d.ts +29 -0
- package/dist/capture-failure-tracker-2Q6oI2uQ.d.ts +52 -0
- package/dist/chromium-camera-access-workaround-CU5zSKNr.d.ts +61 -0
- package/dist/community-license-key-ChZLCJyO.d.ts +21 -0
- package/dist/concurrency-p6gB30fT.d.ts +24 -0
- package/dist/css3d-renderer-manager-rgLMVAvd.d.ts +23 -0
- package/dist/depth-sampler-BNCtnEoP.d.ts +108 -0
- package/dist/failure-tracker-1sQ_Cgyw.d.ts +49 -0
- package/dist/file-system-BsQgYCU3.d.ts +128 -0
- package/dist/file-system-utils-5cWO8Xyv.d.ts +24 -0
- package/dist/format-file-size-onGq0k1Q.d.ts +24 -0
- package/dist/fused-path-DtqCSqJh.d.ts +25 -0
- package/dist/geo-types-Xx-LVcnw.d.ts +29 -0
- package/dist/gps-Ddzr2KlX.d.ts +54 -0
- package/dist/gps-compass-cubes-C-6JEnpR.d.ts +22 -0
- package/dist/gps-error-handler-VPuNOuf8.d.ts +40 -0
- package/dist/gps-event-markers-DpEy2qRd.d.ts +67 -0
- package/dist/h3-ref-point-CFhayNSZ.d.ts +59 -0
- package/dist/image-capture-2pKjYUS6.d.ts +130 -0
- package/dist/index.d.ts +56 -0
- package/dist/index.js +61 -0
- package/dist/leaflet-map-overlay-CvfQXTye.d.ts +114 -0
- package/dist/lerp-utils-87NWjUOD.d.ts +20 -0
- package/dist/licensing/community-license-key.d.ts +2 -0
- package/dist/licensing/community-license-key.js +21 -0
- package/dist/licensing/index.d.ts +2 -0
- package/dist/licensing/index.js +2 -0
- package/dist/list-formatter-DKQQVLcl.d.ts +14 -0
- package/dist/logger-B81iwxx0.d.ts +74 -0
- package/dist/map-overlay-DuiZuCTx.d.ts +153 -0
- package/dist/null-storage-backend-CsWvQwN8.d.ts +11 -0
- package/dist/opfs-storage-ChOzF_Wp.d.ts +181 -0
- package/dist/opfs-storage-backend-CVcmfJHN.d.ts +11 -0
- package/dist/permission-checker-jO2ziCWC.d.ts +146 -0
- package/dist/persistence-middleware-DrptY02i.d.ts +31 -0
- package/dist/recorder-slice-fcwAXrsh.d.ts +35 -0
- package/dist/recording-coordinator-DzflP07_.d.ts +81 -0
- package/dist/recording-options-BYUFX8iU.d.ts +166 -0
- package/dist/recording-replayer-oOzPITrd.d.ts +32 -0
- package/dist/ref-point-importer-B_wn5ABk.d.ts +62 -0
- package/dist/ref-point-loader-Pt1smgHS.d.ts +117 -0
- package/dist/ref-points/h3-ref-point.d.ts +2 -0
- package/dist/ref-points/h3-ref-point.js +74 -0
- package/dist/ref-points/index.d.ts +2 -0
- package/dist/ref-points/index.js +2 -0
- package/dist/ref-points-slice-tC-Wd6XJ.d.ts +48 -0
- package/dist/reference-points-CFWy8_wj.d.ts +68 -0
- package/dist/replay-engine-DuX316ae.d.ts +103 -0
- package/dist/replay-scene-DtUm6bsr.d.ts +109 -0
- package/dist/routing-slice-BlHTM8eh.d.ts +23 -0
- package/dist/scene-node-names-DPsaE2z3.d.ts +14 -0
- package/dist/sensors/gps-error-handler.d.ts +2 -0
- package/dist/sensors/gps-error-handler.js +53 -0
- package/dist/sensors/gps.d.ts +2 -0
- package/dist/sensors/gps.js +93 -0
- package/dist/sensors/index.d.ts +4 -0
- package/dist/sensors/index.js +4 -0
- package/dist/sensors/permission-checker.d.ts +2 -0
- package/dist/sensors/permission-checker.js +397 -0
- package/dist/state/app-selectors.d.ts +2 -0
- package/dist/state/app-selectors.js +35 -0
- package/dist/state/index.d.ts +17 -0
- package/dist/state/index.js +13 -0
- package/dist/state/persistence-middleware.d.ts +2 -0
- package/dist/state/persistence-middleware.js +71 -0
- package/dist/state/recorder-slice.d.ts +2 -0
- package/dist/state/recorder-slice.js +47 -0
- package/dist/state/recording-coordinator.d.ts +2 -0
- package/dist/state/recording-coordinator.js +150 -0
- package/dist/state/recording-options.d.ts +2 -0
- package/dist/state/recording-options.js +192 -0
- package/dist/state/recording-replayer.d.ts +2 -0
- package/dist/state/recording-replayer.js +39 -0
- package/dist/state/ref-points-slice.d.ts +2 -0
- package/dist/state/ref-points-slice.js +44 -0
- package/dist/state/replay-engine.d.ts +2 -0
- package/dist/state/replay-engine.js +230 -0
- package/dist/state/routing-slice.d.ts +2 -0
- package/dist/state/routing-slice.js +13 -0
- package/dist/state/store-subscribers.d.ts +3 -0
- package/dist/state/store-subscribers.js +97 -0
- package/dist/state/store.d.ts +9 -0
- package/dist/state/store.js +71 -0
- package/dist/state/subscribe-to-selector.d.ts +2 -0
- package/dist/state/subscribe-to-selector.js +26 -0
- package/dist/storage/file-system-utils.d.ts +2 -0
- package/dist/storage/file-system-utils.js +31 -0
- package/dist/storage/file-system.d.ts +2 -0
- package/dist/storage/file-system.js +229 -0
- package/dist/storage/index.d.ts +11 -0
- package/dist/storage/index.js +10 -0
- package/dist/storage/null-storage-backend.d.ts +2 -0
- package/dist/storage/null-storage-backend.js +8 -0
- package/dist/storage/opfs-storage-backend.d.ts +2 -0
- package/dist/storage/opfs-storage-backend.js +15 -0
- package/dist/storage/opfs-storage.d.ts +2 -0
- package/dist/storage/opfs-storage.js +242 -0
- package/dist/storage/ref-point-importer.d.ts +2 -0
- package/dist/storage/ref-point-importer.js +163 -0
- package/dist/storage/ref-point-loader.d.ts +2 -0
- package/dist/storage/ref-point-loader.js +248 -0
- package/dist/storage/ref-point-recovery.d.ts +28 -0
- package/dist/storage/ref-point-recovery.js +159 -0
- package/dist/storage/storage-backend.d.ts +2 -0
- package/dist/storage/storage-backend.js +1 -0
- package/dist/storage/zip-export.d.ts +2 -0
- package/dist/storage/zip-export.js +214 -0
- package/dist/storage/zip-reader.d.ts +2 -0
- package/dist/storage/zip-reader.js +190 -0
- package/dist/storage-backend-BcEItnFr.d.ts +20 -0
- package/dist/store-C7PKOj8S.d.ts +96 -0
- package/dist/store-subscribers-CuoIzB5T.d.ts +77 -0
- package/dist/subscribe-to-selector-UTZ0KkAc.d.ts +26 -0
- package/dist/test-utils/browser-mocks.d.ts +294 -0
- package/dist/test-utils/browser-mocks.js +568 -0
- package/dist/test-utils/zip-round-trip-helpers.d.ts +60 -0
- package/dist/test-utils/zip-round-trip-helpers.js +207 -0
- package/dist/three-dispose-CCBHjE_a.d.ts +30 -0
- package/dist/tracking-state-B9QfuZCg.d.ts +101 -0
- package/dist/types/ar-types.d.ts +2 -0
- package/dist/types/ar-types.js +1 -0
- package/dist/types/geo-types.d.ts +2 -0
- package/dist/types/geo-types.js +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.js +1 -0
- package/dist/utils/concurrency.d.ts +2 -0
- package/dist/utils/concurrency.js +40 -0
- package/dist/utils/failure-tracker.d.ts +2 -0
- package/dist/utils/failure-tracker.js +48 -0
- package/dist/utils/format-file-size.d.ts +2 -0
- package/dist/utils/format-file-size.js +41 -0
- package/dist/utils/fused-path.d.ts +2 -0
- package/dist/utils/fused-path.js +44 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.js +7 -0
- package/dist/utils/list-formatter.d.ts +2 -0
- package/dist/utils/list-formatter.js +17 -0
- package/dist/utils/logger.d.ts +2 -0
- package/dist/utils/logger.js +226 -0
- package/dist/vis-colors-Qi2vlRGt.d.ts +63 -0
- package/dist/visualization/alignment-lerper.d.ts +2 -0
- package/dist/visualization/alignment-lerper.js +68 -0
- package/dist/visualization/camera-follower.d.ts +2 -0
- package/dist/visualization/camera-follower.js +51 -0
- package/dist/visualization/css3d-renderer-manager.d.ts +2 -0
- package/dist/visualization/css3d-renderer-manager.js +41 -0
- package/dist/visualization/gps-compass-cubes.d.ts +2 -0
- package/dist/visualization/gps-compass-cubes.js +129 -0
- package/dist/visualization/gps-event-markers.d.ts +2 -0
- package/dist/visualization/gps-event-markers.js +159 -0
- package/dist/visualization/index.d.ts +12 -0
- package/dist/visualization/index.js +12 -0
- package/dist/visualization/leaflet-map-overlay.d.ts +2 -0
- package/dist/visualization/leaflet-map-overlay.js +313 -0
- package/dist/visualization/lerp-utils.d.ts +2 -0
- package/dist/visualization/lerp-utils.js +22 -0
- package/dist/visualization/map-overlay.d.ts +2 -0
- package/dist/visualization/map-overlay.js +241 -0
- package/dist/visualization/reference-points.d.ts +2 -0
- package/dist/visualization/reference-points.js +160 -0
- package/dist/visualization/three-dispose.d.ts +2 -0
- package/dist/visualization/three-dispose.js +55 -0
- package/dist/visualization/vis-colors.d.ts +2 -0
- package/dist/visualization/vis-colors.js +74 -0
- package/dist/webxr-session-COlSrXdL.d.ts +316 -0
- package/dist/xr-camera-texture-BbukNE79.d.ts +53 -0
- package/dist/xr-error-handler-DTHfmvrl.d.ts +24 -0
- package/dist/zip-export-Rtpi75JJ.d.ts +87 -0
- package/dist/zip-reader-D7pkpX8K.d.ts +97 -0
- package/package.json +104 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { createLogger } from "../utils/logger.js";
|
|
2
|
+
//#region ../src/ar/xr-camera-texture.ts
|
|
3
|
+
const log = createLogger("XRCameraTexture");
|
|
4
|
+
/**
|
|
5
|
+
* Acquire the camera texture for the current XR frame using Three.js's
|
|
6
|
+
* built-in getCameraTexture() API, paired with native camera dimensions.
|
|
7
|
+
*
|
|
8
|
+
* Three.js internally:
|
|
9
|
+
* 1. Creates XRWebGLBinding (lazy, one per session)
|
|
10
|
+
* 2. Calls glBinding.getCameraImage(camera) each frame
|
|
11
|
+
* 3. Wraps in ExternalTexture (sourceTexture = native WebGLTexture)
|
|
12
|
+
* 4. Caches per xrCamera in cameraAccessTextures map
|
|
13
|
+
*
|
|
14
|
+
* This function adds the native camera dimensions (width/height) needed
|
|
15
|
+
* for dynamic render target sizing in the blit capture pipeline.
|
|
16
|
+
*
|
|
17
|
+
* Must be called within the XR animation frame callback.
|
|
18
|
+
*
|
|
19
|
+
* @param renderer - The Three.js WebGLRenderer
|
|
20
|
+
* @param xrCamera - The XRCamera from XRView.camera, or null if unavailable
|
|
21
|
+
* @returns CameraTextureResult, or null if acquisition fails
|
|
22
|
+
*/
|
|
23
|
+
function acquireCameraTexture(renderer, xrCamera) {
|
|
24
|
+
if (!xrCamera) return null;
|
|
25
|
+
try {
|
|
26
|
+
const texture = renderer.xr.getCameraTexture(xrCamera);
|
|
27
|
+
if (!texture) return null;
|
|
28
|
+
return {
|
|
29
|
+
texture,
|
|
30
|
+
width: xrCamera.width,
|
|
31
|
+
height: xrCamera.height
|
|
32
|
+
};
|
|
33
|
+
} catch (error) {
|
|
34
|
+
log.error("Failed to acquire camera texture:", error);
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
//#endregion
|
|
39
|
+
export { acquireCameraTexture };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//#region ../src/ar/xr-error-handler.ts
|
|
2
|
+
/**
|
|
3
|
+
* WebXR Error Handler
|
|
4
|
+
*
|
|
5
|
+
* Provides user-facing error messages for WebXR session failures.
|
|
6
|
+
* Separates error handling logic from AR module for testability.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Known WebXR error types and their user-friendly messages.
|
|
10
|
+
*/
|
|
11
|
+
const XR_ERROR_MESSAGES = {
|
|
12
|
+
NotSupportedError: "AR not supported on this device. Please ensure ARCore (Android) or ARKit (iOS) is installed.",
|
|
13
|
+
SecurityError: "Camera permission denied. Allow camera access to use AR features.",
|
|
14
|
+
InvalidStateError: "AR session already active. Please close other AR apps and try again.",
|
|
15
|
+
NotAllowedError: "AR access not allowed. Check browser permissions for this site."
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Default message for unknown error types.
|
|
19
|
+
*/
|
|
20
|
+
const XR_ERROR_MESSAGE_UNKNOWN = "Failed to start AR session. Check device compatibility and permissions.";
|
|
21
|
+
/**
|
|
22
|
+
* Get a user-friendly error message from a WebXR session error.
|
|
23
|
+
*
|
|
24
|
+
* @param error - The error thrown by navigator.xr.requestSession
|
|
25
|
+
* @returns A user-friendly error message
|
|
26
|
+
*/
|
|
27
|
+
function getXrErrorMessage(error) {
|
|
28
|
+
if (error instanceof DOMException) return XR_ERROR_MESSAGES[error.name] ?? "Failed to start AR session. Check device compatibility and permissions.";
|
|
29
|
+
if (error instanceof Error) {
|
|
30
|
+
const msg = error.message.toLowerCase();
|
|
31
|
+
if (msg.includes("not supported")) return XR_ERROR_MESSAGES["NotSupportedError"];
|
|
32
|
+
if (msg.includes("permission") || msg.includes("denied")) return XR_ERROR_MESSAGES["SecurityError"];
|
|
33
|
+
}
|
|
34
|
+
return XR_ERROR_MESSAGE_UNKNOWN;
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
export { XR_ERROR_MESSAGES, XR_ERROR_MESSAGE_UNKNOWN, getXrErrorMessage };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Quaternion, Vector3 } from "gps-plus-slam-js";
|
|
2
|
+
|
|
3
|
+
//#region ../src/types/ar-types.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Tuple-form AR pose for storage/serialization.
|
|
6
|
+
*
|
|
7
|
+
* The tuple equivalent of ARPose — uses the library's readonly Vector3/Quaternion
|
|
8
|
+
* tuples instead of object-form { x, y, z }. Used in storage interfaces where
|
|
9
|
+
* poses are persisted as plain number arrays in JSON.
|
|
10
|
+
*
|
|
11
|
+
* @see ARPose for the object-form variant used in live AR tracking
|
|
12
|
+
* @see 2026-03-03-code-review-inline-type-duplication.md Finding #6
|
|
13
|
+
*/
|
|
14
|
+
interface ArPoseTuples {
|
|
15
|
+
readonly position: Vector3;
|
|
16
|
+
readonly rotation: Quaternion;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* 3D position in object-form as returned by the WebXR API (XRViewerPose).
|
|
20
|
+
* Distinct from the library's tuple-form `Vector3` (`readonly [number, number, number]`).
|
|
21
|
+
*/
|
|
22
|
+
interface WebXRVec3 {
|
|
23
|
+
readonly x: number;
|
|
24
|
+
readonly y: number;
|
|
25
|
+
readonly z: number;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Quaternion orientation in object-form as returned by the WebXR API (XRViewerPose).
|
|
29
|
+
* Distinct from the library's tuple-form `Quaternion` (`readonly [number, number, number, number]`).
|
|
30
|
+
*/
|
|
31
|
+
interface WebXRQuaternion {
|
|
32
|
+
readonly x: number;
|
|
33
|
+
readonly y: number;
|
|
34
|
+
readonly z: number;
|
|
35
|
+
readonly w: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Device pose in AR space.
|
|
39
|
+
* Position and orientation are in the local-floor reference space.
|
|
40
|
+
* This is the RAW pose, NOT transformed by any alignment matrix.
|
|
41
|
+
*/
|
|
42
|
+
interface ARPose {
|
|
43
|
+
readonly position: WebXRVec3;
|
|
44
|
+
readonly orientation: WebXRQuaternion;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* A single depth point sample from WebXR Depth API.
|
|
48
|
+
* Used for 3D reconstruction and validating AR tracking accuracy.
|
|
49
|
+
*/
|
|
50
|
+
interface DepthPoint {
|
|
51
|
+
/** Normalized screen X coordinate (0-1) */
|
|
52
|
+
readonly screenX: number;
|
|
53
|
+
/** Normalized screen Y coordinate (0-1) */
|
|
54
|
+
readonly screenY: number;
|
|
55
|
+
/** Depth value in meters */
|
|
56
|
+
readonly depthM: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* A complete depth sample with camera pose and grid of depth points.
|
|
60
|
+
* Produced by the depth sampler at ~1 Hz, consumed by the store for
|
|
61
|
+
* persistence and replay. This is the single canonical type, re-exported
|
|
62
|
+
* by `store.ts` for dispatch convenience.
|
|
63
|
+
*/
|
|
64
|
+
interface DepthSample {
|
|
65
|
+
/** Timestamp in milliseconds */
|
|
66
|
+
readonly timestamp: number;
|
|
67
|
+
/**
|
|
68
|
+
* Camera position in **raw WebXR** convention [x=East, y=Up, z=South].
|
|
69
|
+
* NOT in NUE — the recordDepthSample reducer is a no-op, so no
|
|
70
|
+
* webxrToNUE conversion is applied. Consumers must convert if needed.
|
|
71
|
+
*/
|
|
72
|
+
readonly cameraPos: Vector3;
|
|
73
|
+
/**
|
|
74
|
+
* Camera rotation quaternion in **raw WebXR** convention [x, y, z, w].
|
|
75
|
+
* NOT in NUE — same reasoning as cameraPos.
|
|
76
|
+
*/
|
|
77
|
+
readonly cameraRot: Quaternion;
|
|
78
|
+
/** Grid of depth points */
|
|
79
|
+
readonly points: DepthPoint[];
|
|
80
|
+
}
|
|
81
|
+
//#endregion
|
|
82
|
+
export { WebXRQuaternion as a, DepthSample as i, ArPoseTuples as n, WebXRVec3 as o, DepthPoint as r, ARPose as t };
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import * as THREE from "three";
|
|
2
|
+
|
|
3
|
+
//#region ../src/ar/camera-blit-capture.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Configuration for the blit capture render target dimensions.
|
|
6
|
+
* Smaller = faster readPixels (less GPU stall), but lower resolution.
|
|
7
|
+
*/
|
|
8
|
+
interface CameraBlitCaptureConfig {
|
|
9
|
+
/** Width of the intermediate render target in pixels */
|
|
10
|
+
width: number;
|
|
11
|
+
/** Height of the intermediate render target in pixels */
|
|
12
|
+
height: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Default blit capture config.
|
|
16
|
+
* 512×512 is a good balance between quality and readPixels performance on mobile.
|
|
17
|
+
*/
|
|
18
|
+
declare const DEFAULT_BLIT_CONFIG: CameraBlitCaptureConfig;
|
|
19
|
+
/**
|
|
20
|
+
* Compute the capture dimensions from the native camera resolution
|
|
21
|
+
* and a user-configurable resolution divisor.
|
|
22
|
+
*
|
|
23
|
+
* @param cameraWidth - Native camera width in pixels (from XRCamera)
|
|
24
|
+
* @param cameraHeight - Native camera height in pixels (from XRCamera)
|
|
25
|
+
* @param divisor - Resolution divisor: 1 = full, 2 = half, 4 = quarter, etc.
|
|
26
|
+
* Values ≤ 0 are treated as 1. Fractional values < 1 are treated as 1.
|
|
27
|
+
* @returns Integer pixel dimensions, clamped to at least 1×1.
|
|
28
|
+
* Falls back to DEFAULT_BLIT_CONFIG when inputs are invalid (≤ 0).
|
|
29
|
+
*/
|
|
30
|
+
declare function computeCaptureSize(cameraWidth: number, cameraHeight: number, divisor: number): {
|
|
31
|
+
width: number;
|
|
32
|
+
height: number;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Captures readable pixel data from WebXR opaque camera textures
|
|
36
|
+
* using the intermediate render target "blit" technique.
|
|
37
|
+
*
|
|
38
|
+
* Usage:
|
|
39
|
+
* 1. Create once when AR session starts
|
|
40
|
+
* 2. Call captureToBlob() when a frame needs to be captured
|
|
41
|
+
* 3. Call dispose() when AR session ends
|
|
42
|
+
*/
|
|
43
|
+
declare class CameraBlitCapture {
|
|
44
|
+
private renderTarget;
|
|
45
|
+
private blitScene;
|
|
46
|
+
private blitCamera;
|
|
47
|
+
private blitMaterial;
|
|
48
|
+
private quad;
|
|
49
|
+
private pixelBuffer;
|
|
50
|
+
private width;
|
|
51
|
+
private height;
|
|
52
|
+
private disposed;
|
|
53
|
+
constructor(config?: CameraBlitCaptureConfig);
|
|
54
|
+
/**
|
|
55
|
+
* Capture the WebXR camera texture to a JPEG Blob via the blit technique.
|
|
56
|
+
*
|
|
57
|
+
* IMPORTANT: Must be called within the XR animation frame callback,
|
|
58
|
+
* while the camera texture is valid.
|
|
59
|
+
*
|
|
60
|
+
* @param renderer - The Three.js WebGL renderer
|
|
61
|
+
* @param cameraTexture - The opaque camera texture from renderer.xr.getCameraTexture()
|
|
62
|
+
* @param quality - JPEG quality 0.0-1.0
|
|
63
|
+
* @returns JPEG Blob, or null if capture fails
|
|
64
|
+
*/
|
|
65
|
+
captureToBlob(renderer: THREE.WebGLRenderer, cameraTexture: THREE.Texture, quality: number): Promise<Blob | null>;
|
|
66
|
+
/**
|
|
67
|
+
* Check if a pixel buffer is entirely black (all zeros).
|
|
68
|
+
* Uses sampling for performance (checks BLACK_CHECK_SAMPLE_COUNT evenly-spaced pixels).
|
|
69
|
+
*
|
|
70
|
+
* This is useful to detect if the blit technique failed to convert
|
|
71
|
+
* the opaque texture (different from a legitimately dark scene).
|
|
72
|
+
*
|
|
73
|
+
* @param pixels - RGBA pixel buffer
|
|
74
|
+
* @returns true if all sampled pixels are zero
|
|
75
|
+
*/
|
|
76
|
+
static isBlackFrame(pixels: Uint8Array): boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Convert the internal pixel buffer to a JPEG Blob using OffscreenCanvas
|
|
79
|
+
* (or fallback to regular Canvas).
|
|
80
|
+
*/
|
|
81
|
+
private pixelsToJpegBlob;
|
|
82
|
+
private getFlippedImageData;
|
|
83
|
+
private pixelsToJpegViaOffscreenCanvas;
|
|
84
|
+
private pixelsToJpegViaCanvas;
|
|
85
|
+
/**
|
|
86
|
+
* Flip ImageData vertically in-place.
|
|
87
|
+
* WebGL readPixels returns bottom-row-first; canvas expects top-row-first.
|
|
88
|
+
*/
|
|
89
|
+
private flipImageDataVertically;
|
|
90
|
+
/**
|
|
91
|
+
* Resize the render target and pixel buffer to match new dimensions.
|
|
92
|
+
* Call this when the camera resolution is first known or changes.
|
|
93
|
+
*
|
|
94
|
+
* No-op when dimensions already match (avoids per-frame reallocation).
|
|
95
|
+
* Returns false if disposed, dimensions unchanged, or dimensions invalid.
|
|
96
|
+
*
|
|
97
|
+
* @param newWidth - Desired capture width in pixels
|
|
98
|
+
* @param newHeight - Desired capture height in pixels
|
|
99
|
+
* @returns true if resources were actually resized
|
|
100
|
+
*/
|
|
101
|
+
resizeIfNeeded(newWidth: number, newHeight: number): boolean;
|
|
102
|
+
/**
|
|
103
|
+
* Dispose GPU resources. Call when AR session ends.
|
|
104
|
+
*/
|
|
105
|
+
dispose(): void;
|
|
106
|
+
}
|
|
107
|
+
//#endregion
|
|
108
|
+
export { computeCaptureSize as i, CameraBlitCaptureConfig as n, DEFAULT_BLIT_CONFIG as r, CameraBlitCapture as t };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as THREE from "three";
|
|
2
|
+
|
|
3
|
+
//#region ../src/visualization/camera-follower.d.ts
|
|
4
|
+
interface CameraFollower {
|
|
5
|
+
/** The underlying Object3D — add children (map, cubes) here. */
|
|
6
|
+
readonly object3D: THREE.Object3D;
|
|
7
|
+
/**
|
|
8
|
+
* Update the follower position. Call once per frame before render.
|
|
9
|
+
*
|
|
10
|
+
* @param camera The active camera (its world position is read).
|
|
11
|
+
* @param dt Delta time in seconds since last frame.
|
|
12
|
+
*/
|
|
13
|
+
update(camera: THREE.Camera, dt: number): void;
|
|
14
|
+
/** Remove the follower from the scene graph. */
|
|
15
|
+
dispose(): void;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Create a CameraFollower and attach it as a child of the given parent.
|
|
19
|
+
*
|
|
20
|
+
* The parent should be the scene root (not arWorldGroup) so that the
|
|
21
|
+
* follower's world rotation stays identity — ensuring compass directions
|
|
22
|
+
* align with the NUE GPS frame regardless of alignment matrix changes.
|
|
23
|
+
*
|
|
24
|
+
* @param parent Parent node — should be the scene root.
|
|
25
|
+
* @param lerpRate Lerp speed multiplier (default 8).
|
|
26
|
+
*/
|
|
27
|
+
declare function createCameraFollower(parent: THREE.Object3D, lerpRate?: number): CameraFollower;
|
|
28
|
+
//#endregion
|
|
29
|
+
export { createCameraFollower as n, CameraFollower as t };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
//#region ../src/ar/capture-failure-tracker.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Capture Failure Tracker
|
|
4
|
+
*
|
|
5
|
+
* Tracks consecutive image capture failures and notifies users when
|
|
6
|
+
* multiple frames fail to capture (e.g., low memory on mobile devices).
|
|
7
|
+
*
|
|
8
|
+
* Field Test Readiness Issue #11: Silent image capture failures
|
|
9
|
+
*
|
|
10
|
+
* Thin wrapper around the generic failure tracker factory.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Configuration for the capture failure tracker.
|
|
14
|
+
*/
|
|
15
|
+
interface CaptureFailureTrackerConfig {
|
|
16
|
+
/**
|
|
17
|
+
* Number of consecutive failures before warning the user.
|
|
18
|
+
* Default: 5 (higher than write failures since capture failures are less critical)
|
|
19
|
+
*/
|
|
20
|
+
failureThreshold: number;
|
|
21
|
+
/**
|
|
22
|
+
* Callback to show error to user.
|
|
23
|
+
*/
|
|
24
|
+
onWarning: (message: string) => void;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Default configuration values.
|
|
28
|
+
*/
|
|
29
|
+
declare const DEFAULT_CAPTURE_TRACKER_CONFIG: Omit<CaptureFailureTrackerConfig, 'onWarning'>;
|
|
30
|
+
/**
|
|
31
|
+
* User-facing warning message when threshold is exceeded.
|
|
32
|
+
*/
|
|
33
|
+
declare const CAPTURE_FAILURE_WARNING = "Multiple image captures failed. Device may be low on memory.";
|
|
34
|
+
/**
|
|
35
|
+
* Tracks consecutive capture failures and warns user when threshold is exceeded.
|
|
36
|
+
*/
|
|
37
|
+
interface CaptureFailureTracker {
|
|
38
|
+
recordSuccess(): void;
|
|
39
|
+
recordFailure(): void;
|
|
40
|
+
getFailureCount(): number;
|
|
41
|
+
hasWarned(): boolean;
|
|
42
|
+
reset(): void;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Create a new capture failure tracker.
|
|
46
|
+
*
|
|
47
|
+
* @param config - Configuration with warning callback and optional threshold
|
|
48
|
+
* @returns CaptureFailureTracker instance
|
|
49
|
+
*/
|
|
50
|
+
declare function createCaptureFailureTracker(config: Partial<CaptureFailureTrackerConfig> & Pick<CaptureFailureTrackerConfig, 'onWarning'>): CaptureFailureTracker;
|
|
51
|
+
//#endregion
|
|
52
|
+
export { createCaptureFailureTracker as a, DEFAULT_CAPTURE_TRACKER_CONFIG as i, CaptureFailureTracker as n, CaptureFailureTrackerConfig as r, CAPTURE_FAILURE_WARNING as t };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
//#region ../src/ar/chromium-camera-access-workaround.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Chromium WebXR camera-access tab-crash workaround.
|
|
4
|
+
*
|
|
5
|
+
* Background:
|
|
6
|
+
* Requesting `camera-access` as an optional WebXR feature on recent Android
|
|
7
|
+
* Chrome versions causes a fatal renderer-process crash (`CrRendererMain`)
|
|
8
|
+
* 1–2 seconds after entering AR. The crash reproduces in the upstream
|
|
9
|
+
* three.js `webxr_ar_hittest.html` example with `optionalFeatures:
|
|
10
|
+
* ['camera-access']` added — i.e. it is not specific to this app's session
|
|
11
|
+
* setup. See:
|
|
12
|
+
*
|
|
13
|
+
* - GpsPlusSlamJs_Docs/docs/2026-04-22-camera-access-reproducer-plan.md
|
|
14
|
+
* - GpsPlusSlamJs_Docs/docs/2026-04-23-webxr-camera-access-crash-bug-report.html
|
|
15
|
+
* - https://github.com/mrdoob/three.js/issues/33404
|
|
16
|
+
*
|
|
17
|
+
* Workaround (from the upstream issue thread):
|
|
18
|
+
* Three.js's `WebXRManager` chooses between the newer `XRProjectionLayer`
|
|
19
|
+
* and the older `XRWebGLLayer` based on whether
|
|
20
|
+
* `XRWebGLBinding.prototype.createProjectionLayer` is available. The crash
|
|
21
|
+
* appears to involve the projection-layer + camera-access combination, so
|
|
22
|
+
* removing the prototype method forces three.js to fall back to
|
|
23
|
+
* `XRWebGLLayer`, which sidesteps the bug.
|
|
24
|
+
*
|
|
25
|
+
* `XRRenderState.prototype.layers` is the equivalent capability check used
|
|
26
|
+
* by older three.js (r158-era) and is included for completeness.
|
|
27
|
+
*
|
|
28
|
+
* Caveats:
|
|
29
|
+
* - This is a Chromium-specific hack and the upstream comment explicitly
|
|
30
|
+
* warns it "might break webxr on other devices" — keep it opt-in.
|
|
31
|
+
* - Must run BEFORE any WebXR session setup. Three.js reads these prototype
|
|
32
|
+
* members lazily when the first session starts, so calling this at app
|
|
33
|
+
* bootstrap (before `initAR()`) is sufficient.
|
|
34
|
+
* - Idempotent: safe to call repeatedly. Safe on environments where the
|
|
35
|
+
* prototypes do not exist (e.g. desktop browsers, jsdom).
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* Result of {@link applyChromiumProjectionLayerWorkaround}.
|
|
39
|
+
* Useful for logging and tests.
|
|
40
|
+
*/
|
|
41
|
+
interface ChromiumProjectionLayerWorkaroundResult {
|
|
42
|
+
/** True if `XRWebGLBinding.prototype.createProjectionLayer` was deleted on this call. */
|
|
43
|
+
deletedCreateProjectionLayer: boolean;
|
|
44
|
+
/** True if `XRRenderState.prototype.layers` was deleted on this call. */
|
|
45
|
+
deletedRenderStateLayers: boolean;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Apply the Chromium camera-access tab-crash workaround.
|
|
49
|
+
*
|
|
50
|
+
* Removes `XRWebGLBinding.prototype.createProjectionLayer` (three.js r184)
|
|
51
|
+
* and `XRRenderState.prototype.layers` (three.js r158) so three.js falls
|
|
52
|
+
* back to `XRWebGLLayer`, which avoids the renderer-process crash that
|
|
53
|
+
* happens when both projection layers and `camera-access` are enabled.
|
|
54
|
+
*
|
|
55
|
+
* Call once during bootstrap, before any `requestSession()` call.
|
|
56
|
+
*
|
|
57
|
+
* @returns which prototype members were actually deleted on this call.
|
|
58
|
+
*/
|
|
59
|
+
declare function applyChromiumProjectionLayerWorkaround(): ChromiumProjectionLayerWorkaroundResult;
|
|
60
|
+
//#endregion
|
|
61
|
+
export { applyChromiumProjectionLayerWorkaround as n, ChromiumProjectionLayerWorkaroundResult as t };
|
|
@@ -0,0 +1,21 @@
|
|
|
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 };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
//#region ../src/utils/concurrency.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Concurrency Utilities
|
|
4
|
+
*
|
|
5
|
+
* Provides helpers for limiting the number of concurrent async operations.
|
|
6
|
+
* Used to prevent excessive memory consumption when scanning many files
|
|
7
|
+
* in parallel (e.g., reading zip metadata during scenario discovery).
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Map over an array with a concurrency limit on the async mapper function.
|
|
11
|
+
*
|
|
12
|
+
* Behaves like `Promise.all(items.map(fn))` but limits how many mapper
|
|
13
|
+
* invocations run simultaneously. Results are returned in the same order
|
|
14
|
+
* as the input items.
|
|
15
|
+
*
|
|
16
|
+
* @param items - Array of items to process
|
|
17
|
+
* @param limit - Maximum number of concurrent mapper invocations
|
|
18
|
+
* @param mapper - Async function to apply to each item
|
|
19
|
+
* @returns Array of results in the same order as input items
|
|
20
|
+
* @throws Re-throws the first error from any mapper invocation (fail-fast)
|
|
21
|
+
*/
|
|
22
|
+
declare function mapWithConcurrencyLimit<T, R>(items: T[], limit: number, mapper: (item: T, index: number) => Promise<R>): Promise<R[]>;
|
|
23
|
+
//#endregion
|
|
24
|
+
export { mapWithConcurrencyLimit as t };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as THREE from "three";
|
|
2
|
+
|
|
3
|
+
//#region ../src/visualization/css3d-renderer-manager.d.ts
|
|
4
|
+
interface Css3dRendererManager {
|
|
5
|
+
render(scene: THREE.Scene, camera: THREE.Camera): void;
|
|
6
|
+
setSize(width: number, height: number): void;
|
|
7
|
+
dispose(): void;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Create and configure a CSS3DRenderer overlay for the given container.
|
|
11
|
+
*
|
|
12
|
+
* The CSS3D layer is positioned absolutely over the container with
|
|
13
|
+
* `pointer-events: none` so it does not intercept clicks intended
|
|
14
|
+
* for the WebGL canvas underneath.
|
|
15
|
+
*
|
|
16
|
+
* **Requirement:** The `container` element must have `position: relative`,
|
|
17
|
+
* `absolute`, `fixed`, or `sticky`. If the container is `position: static`
|
|
18
|
+
* (the CSS default), the overlay will float to the nearest positioned
|
|
19
|
+
* ancestor instead of aligning with the container.
|
|
20
|
+
*/
|
|
21
|
+
declare function createCss3dRendererManager(container: HTMLElement, width: number, height: number): Css3dRendererManager;
|
|
22
|
+
//#endregion
|
|
23
|
+
export { createCss3dRendererManager as n, Css3dRendererManager as t };
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { i as DepthSample, t as ARPose } from "./ar-types-B-ORgk6Z.js";
|
|
2
|
+
|
|
3
|
+
//#region ../src/ar/depth-sampler.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Configuration for depth sampling behavior.
|
|
6
|
+
*/
|
|
7
|
+
interface DepthSamplerConfig {
|
|
8
|
+
/** Interval between samples in milliseconds. Default: 1000ms */
|
|
9
|
+
intervalMs: number;
|
|
10
|
+
/** Number of points per dimension (gridSize x gridSize). Default: 3 */
|
|
11
|
+
gridSize: number;
|
|
12
|
+
/** Time in ms to wait before declaring depth unavailable. Default: 5000ms */
|
|
13
|
+
unavailabilityThresholdMs: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Callbacks for depth sampler events.
|
|
17
|
+
*/
|
|
18
|
+
interface DepthSamplerCallbacks {
|
|
19
|
+
/** Called when a depth sample is captured */
|
|
20
|
+
onSampleCaptured: (sample: DepthSample) => void;
|
|
21
|
+
/** Returns the current AR pose, or null if not available */
|
|
22
|
+
getCurrentPose: () => ARPose | null;
|
|
23
|
+
/**
|
|
24
|
+
* Called once when depth is determined to be unavailable.
|
|
25
|
+
* Triggered after unavailabilityThresholdMs with no depth data.
|
|
26
|
+
* Field Test Readiness Issue #8.
|
|
27
|
+
*/
|
|
28
|
+
onDepthUnavailable?: () => void;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* WebXR depth info interface (subset of XRDepthInformation).
|
|
32
|
+
*/
|
|
33
|
+
interface DepthInfo {
|
|
34
|
+
width: number;
|
|
35
|
+
height: number;
|
|
36
|
+
getDepthInMeters: (x: number, y: number) => number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Samples sparse depth points from WebXR depth sensing.
|
|
40
|
+
*
|
|
41
|
+
* Usage:
|
|
42
|
+
* ```ts
|
|
43
|
+
* const sampler = new DepthSampler({
|
|
44
|
+
* onSampleCaptured: (sample) => saveSample(sample),
|
|
45
|
+
* getCurrentPose: () => arSession.getCurrentPose(),
|
|
46
|
+
* });
|
|
47
|
+
* sampler.start();
|
|
48
|
+
* // In frame loop:
|
|
49
|
+
* sampler.onFrame(timestamp, depthInfo);
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
declare class DepthSampler {
|
|
53
|
+
private readonly callbacks;
|
|
54
|
+
private readonly config;
|
|
55
|
+
private running;
|
|
56
|
+
private sampleCount;
|
|
57
|
+
private lastSampleTime;
|
|
58
|
+
/** Timestamp when sampling started (for unavailability detection) */
|
|
59
|
+
private startTime;
|
|
60
|
+
/** Whether we've ever received valid depth data */
|
|
61
|
+
private depthReceived;
|
|
62
|
+
/** Whether we've already fired the unavailable callback */
|
|
63
|
+
private unavailableCallbackFired;
|
|
64
|
+
constructor(callbacks: DepthSamplerCallbacks, config?: Partial<DepthSamplerConfig>);
|
|
65
|
+
/**
|
|
66
|
+
* Start depth sampling.
|
|
67
|
+
*/
|
|
68
|
+
start(): void;
|
|
69
|
+
/**
|
|
70
|
+
* Stop depth sampling.
|
|
71
|
+
*/
|
|
72
|
+
stop(): void;
|
|
73
|
+
/**
|
|
74
|
+
* Check if sampler is currently running.
|
|
75
|
+
*/
|
|
76
|
+
isRunning(): boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Get the number of samples captured since start.
|
|
79
|
+
*/
|
|
80
|
+
getSampleCount(): number;
|
|
81
|
+
/**
|
|
82
|
+
* Get the current configuration.
|
|
83
|
+
*/
|
|
84
|
+
getConfig(): DepthSamplerConfig;
|
|
85
|
+
/**
|
|
86
|
+
* Called each frame with depth information.
|
|
87
|
+
*
|
|
88
|
+
* @param timestamp - Current frame timestamp in milliseconds
|
|
89
|
+
* @param depthInfo - WebXR depth information, or null if unavailable
|
|
90
|
+
*/
|
|
91
|
+
onFrame(timestamp: number, depthInfo: DepthInfo | null): void;
|
|
92
|
+
/**
|
|
93
|
+
* Sample a grid of depth points from the depth buffer.
|
|
94
|
+
*/
|
|
95
|
+
private sampleGrid;
|
|
96
|
+
/**
|
|
97
|
+
* Check if depth has been unavailable for longer than the threshold.
|
|
98
|
+
* If so, fire the onDepthUnavailable callback (once).
|
|
99
|
+
*/
|
|
100
|
+
private checkDepthUnavailability;
|
|
101
|
+
/**
|
|
102
|
+
* Check if depth data has ever been received.
|
|
103
|
+
* Useful for testing and status display.
|
|
104
|
+
*/
|
|
105
|
+
hasReceivedDepth(): boolean;
|
|
106
|
+
}
|
|
107
|
+
//#endregion
|
|
108
|
+
export { DepthSamplerConfig as i, DepthSampler as n, DepthSamplerCallbacks as r, DepthInfo as t };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
//#region ../src/utils/failure-tracker.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Generic Failure Tracker Factory
|
|
4
|
+
*
|
|
5
|
+
* Shared pattern extracted from capture-failure-tracker and write-failure-tracker.
|
|
6
|
+
* Tracks consecutive failures, warns the user once when a threshold is exceeded,
|
|
7
|
+
* and supports session-level reset.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Configuration for creating a failure tracker.
|
|
11
|
+
*/
|
|
12
|
+
interface FailureTrackerConfig {
|
|
13
|
+
/** Human-readable label used for log messages (e.g., 'CaptureFailure'). */
|
|
14
|
+
label: string;
|
|
15
|
+
/** Message passed to `onWarning` when the threshold is reached. */
|
|
16
|
+
warningMessage: string;
|
|
17
|
+
/** Default threshold used when `failureThreshold` is not provided. */
|
|
18
|
+
defaultThreshold: number;
|
|
19
|
+
/** Callback invoked once when consecutive failures reach the threshold. */
|
|
20
|
+
onWarning: (message: string) => void;
|
|
21
|
+
/** Optional override for the failure threshold. */
|
|
22
|
+
failureThreshold?: number;
|
|
23
|
+
/** Log level for each failure: 'warn' (default) or 'error'. */
|
|
24
|
+
logLevel?: 'warn' | 'error';
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* A failure tracker instance returned by `createFailureTracker`.
|
|
28
|
+
*/
|
|
29
|
+
interface FailureTracker {
|
|
30
|
+
/** Record a success — resets the consecutive failure counter. */
|
|
31
|
+
recordSuccess(): void;
|
|
32
|
+
/** Record a failure (optionally with an error for logging). */
|
|
33
|
+
recordFailure(error?: unknown): void;
|
|
34
|
+
/** Current number of consecutive failures. */
|
|
35
|
+
getFailureCount(): number;
|
|
36
|
+
/** Whether the warning has already been shown this session. */
|
|
37
|
+
hasWarned(): boolean;
|
|
38
|
+
/** Reset all state (for new sessions). */
|
|
39
|
+
reset(): void;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Create a generic failure tracker.
|
|
43
|
+
*
|
|
44
|
+
* @param config - Tracker configuration
|
|
45
|
+
* @returns A FailureTracker instance
|
|
46
|
+
*/
|
|
47
|
+
declare function createFailureTracker(config: FailureTrackerConfig): FailureTracker;
|
|
48
|
+
//#endregion
|
|
49
|
+
export { FailureTrackerConfig as n, createFailureTracker as r, FailureTracker as t };
|