@switchlabs/verify-ai-react-native 2.4.22 → 2.4.23
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/lib/components/VerifyAIScanner.js +15 -2
- package/lib/telemetry/TelemetryReporter.d.ts +6 -0
- package/lib/telemetry/TelemetryReporter.js +30 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +1 -1
- package/src/components/VerifyAIScanner.tsx +18 -2
- package/src/telemetry/TelemetryReporter.ts +34 -1
- package/src/version.ts +1 -1
|
@@ -4,6 +4,7 @@ import { View, Text, TouchableOpacity, StyleSheet, ActivityIndicator, AppState,
|
|
|
4
4
|
import { CameraView, useCameraPermissions, } from 'expo-camera';
|
|
5
5
|
import { VerifyAIRequestError } from '../client';
|
|
6
6
|
import { useTelemetry } from '../telemetry/TelemetryContext';
|
|
7
|
+
import { SDK_VERSION } from '../version';
|
|
7
8
|
import { BikeOverlay } from './BikeOverlay';
|
|
8
9
|
import { ScooterOverlay } from './ScooterOverlay';
|
|
9
10
|
import { ANDROID_ACCELEROMETER_AXIS_DOMINANCE_THRESHOLD, classifyAndroidAccelerometerOrientation, getOverlayRotationDeg, } from './scannerOrientation';
|
|
@@ -326,11 +327,23 @@ export function VerifyAIScanner({ onCapture, policy, onResult, onError, onClose,
|
|
|
326
327
|
telemetryRef.current = telemetry;
|
|
327
328
|
buildScannerTelemetryMetadataRef.current = buildScannerTelemetryMetadata;
|
|
328
329
|
useEffect(() => {
|
|
329
|
-
telemetryRef.current
|
|
330
|
+
const reporter = telemetryRef.current;
|
|
331
|
+
if (reporter) {
|
|
332
|
+
console.log(`VerifyAI[${SDK_VERSION}]: scanner telemetry attached ` +
|
|
333
|
+
`baseUrl=${reporter.getBaseUrl()} apiKeyPrefix=${reporter.getApiKeyPrefix()}…`);
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
console.warn(`VerifyAI[${SDK_VERSION}]: scanner telemetry is not attached; field ` +
|
|
337
|
+
'diagnostics will only appear in local device logs. Pass a ' +
|
|
338
|
+
'`TelemetryReporter` into `<VerifyAIScanner telemetry={…} />` or ' +
|
|
339
|
+
'wrap the tree in `<TelemetryContext.Provider value={reporter}>` ' +
|
|
340
|
+
'to enable server-side diagnostics.');
|
|
341
|
+
}
|
|
342
|
+
reporter?.track('camera_scanner_mounted', {
|
|
330
343
|
component: 'scanner',
|
|
331
344
|
error: 'scanner_mounted',
|
|
332
345
|
metadata: buildScannerTelemetryMetadataRef.current?.({
|
|
333
|
-
scanner_telemetry_attached:
|
|
346
|
+
scanner_telemetry_attached: reporter ? 1 : 0,
|
|
334
347
|
}),
|
|
335
348
|
});
|
|
336
349
|
return () => {
|
|
@@ -9,6 +9,12 @@ export declare class TelemetryReporter {
|
|
|
9
9
|
private loadedPersisted;
|
|
10
10
|
private loadPersistedPromise;
|
|
11
11
|
constructor(apiKey: string, baseUrl: string);
|
|
12
|
+
/** Telemetry POST destination — exposed so the scanner can log an init banner
|
|
13
|
+
* that helps field debugging confirm where events are being sent. */
|
|
14
|
+
getBaseUrl(): string;
|
|
15
|
+
/** First 6 characters of the API key, for log banners. Never returns the full key. */
|
|
16
|
+
getApiKeyPrefix(): string;
|
|
17
|
+
private logDeliveryFailure;
|
|
12
18
|
/** Track an error event. Fire-and-forget — never throws. */
|
|
13
19
|
track(eventType: string, opts?: {
|
|
14
20
|
component?: string;
|
|
@@ -40,6 +40,20 @@ export class TelemetryReporter {
|
|
|
40
40
|
// Load any persisted events left behind by a previous session
|
|
41
41
|
this.loadPersistedBuffer();
|
|
42
42
|
}
|
|
43
|
+
/** Telemetry POST destination — exposed so the scanner can log an init banner
|
|
44
|
+
* that helps field debugging confirm where events are being sent. */
|
|
45
|
+
getBaseUrl() {
|
|
46
|
+
return this.baseUrl;
|
|
47
|
+
}
|
|
48
|
+
/** First 6 characters of the API key, for log banners. Never returns the full key. */
|
|
49
|
+
getApiKeyPrefix() {
|
|
50
|
+
return this.apiKey.length >= 6 ? this.apiKey.slice(0, 6) : this.apiKey;
|
|
51
|
+
}
|
|
52
|
+
logDeliveryFailure(kind, detail, eventCount) {
|
|
53
|
+
const trimmed = detail.length > 200 ? detail.slice(0, 200) : detail;
|
|
54
|
+
console.warn(`VerifyAI[${SDK_VERSION}]: telemetry POST failed kind=${kind} ` +
|
|
55
|
+
`events=${eventCount} url=${this.baseUrl}/telemetry detail=${trimmed}`);
|
|
56
|
+
}
|
|
43
57
|
/** Track an error event. Fire-and-forget — never throws. */
|
|
44
58
|
track(eventType, opts = {}) {
|
|
45
59
|
if (this.disposed)
|
|
@@ -113,6 +127,7 @@ export class TelemetryReporter {
|
|
|
113
127
|
this.clearFlushTimer();
|
|
114
128
|
const controller = new AbortController();
|
|
115
129
|
const timeout = setTimeout(() => controller.abort(), 10000);
|
|
130
|
+
let loggedDeliveryFailure = false;
|
|
116
131
|
try {
|
|
117
132
|
const response = await fetch(`${this.baseUrl}/telemetry`, {
|
|
118
133
|
method: 'POST',
|
|
@@ -124,12 +139,26 @@ export class TelemetryReporter {
|
|
|
124
139
|
signal: controller.signal,
|
|
125
140
|
});
|
|
126
141
|
if (!response.ok) {
|
|
142
|
+
let body = '';
|
|
143
|
+
try {
|
|
144
|
+
body = await response.text();
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
// ignore
|
|
148
|
+
}
|
|
149
|
+
this.logDeliveryFailure(`http_${response.status}`, body, events.length);
|
|
150
|
+
loggedDeliveryFailure = true;
|
|
127
151
|
throw new Error(`Telemetry request failed with status ${response.status}`);
|
|
128
152
|
}
|
|
129
153
|
// Success — clear persisted buffer since events are now server-side
|
|
130
154
|
this.persistBuffer(); // buffer is empty at this point, so this clears the key
|
|
131
155
|
}
|
|
132
|
-
catch {
|
|
156
|
+
catch (error) {
|
|
157
|
+
if (!loggedDeliveryFailure) {
|
|
158
|
+
const kind = error instanceof Error ? error.name : typeof error;
|
|
159
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
160
|
+
this.logDeliveryFailure(kind, detail, events.length);
|
|
161
|
+
}
|
|
133
162
|
for (const [dedupKey, event] of bufferedEntries) {
|
|
134
163
|
const existing = this.buffer.get(dedupKey);
|
|
135
164
|
if (existing) {
|
package/lib/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "2.4.
|
|
1
|
+
export declare const SDK_VERSION = "2.4.23";
|
package/lib/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const SDK_VERSION = '2.4.
|
|
1
|
+
export const SDK_VERSION = '2.4.23';
|
package/package.json
CHANGED
|
@@ -23,6 +23,7 @@ import type {
|
|
|
23
23
|
import { VerifyAIRequestError } from '../client';
|
|
24
24
|
import { useTelemetry } from '../telemetry/TelemetryContext';
|
|
25
25
|
import type { TelemetryReporter } from '../telemetry/TelemetryReporter';
|
|
26
|
+
import { SDK_VERSION } from '../version';
|
|
26
27
|
import { BikeOverlay } from './BikeOverlay';
|
|
27
28
|
import { ScooterOverlay } from './ScooterOverlay';
|
|
28
29
|
import {
|
|
@@ -439,11 +440,26 @@ export function VerifyAIScanner({
|
|
|
439
440
|
buildScannerTelemetryMetadataRef.current = buildScannerTelemetryMetadata;
|
|
440
441
|
|
|
441
442
|
useEffect(() => {
|
|
442
|
-
telemetryRef.current
|
|
443
|
+
const reporter = telemetryRef.current;
|
|
444
|
+
if (reporter) {
|
|
445
|
+
console.log(
|
|
446
|
+
`VerifyAI[${SDK_VERSION}]: scanner telemetry attached ` +
|
|
447
|
+
`baseUrl=${reporter.getBaseUrl()} apiKeyPrefix=${reporter.getApiKeyPrefix()}…`,
|
|
448
|
+
);
|
|
449
|
+
} else {
|
|
450
|
+
console.warn(
|
|
451
|
+
`VerifyAI[${SDK_VERSION}]: scanner telemetry is not attached; field ` +
|
|
452
|
+
'diagnostics will only appear in local device logs. Pass a ' +
|
|
453
|
+
'`TelemetryReporter` into `<VerifyAIScanner telemetry={…} />` or ' +
|
|
454
|
+
'wrap the tree in `<TelemetryContext.Provider value={reporter}>` ' +
|
|
455
|
+
'to enable server-side diagnostics.',
|
|
456
|
+
);
|
|
457
|
+
}
|
|
458
|
+
reporter?.track('camera_scanner_mounted', {
|
|
443
459
|
component: 'scanner',
|
|
444
460
|
error: 'scanner_mounted',
|
|
445
461
|
metadata: buildScannerTelemetryMetadataRef.current?.({
|
|
446
|
-
scanner_telemetry_attached:
|
|
462
|
+
scanner_telemetry_attached: reporter ? 1 : 0,
|
|
447
463
|
}),
|
|
448
464
|
});
|
|
449
465
|
|
|
@@ -71,6 +71,25 @@ export class TelemetryReporter {
|
|
|
71
71
|
this.loadPersistedBuffer();
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
/** Telemetry POST destination — exposed so the scanner can log an init banner
|
|
75
|
+
* that helps field debugging confirm where events are being sent. */
|
|
76
|
+
getBaseUrl(): string {
|
|
77
|
+
return this.baseUrl;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** First 6 characters of the API key, for log banners. Never returns the full key. */
|
|
81
|
+
getApiKeyPrefix(): string {
|
|
82
|
+
return this.apiKey.length >= 6 ? this.apiKey.slice(0, 6) : this.apiKey;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private logDeliveryFailure(kind: string, detail: string, eventCount: number): void {
|
|
86
|
+
const trimmed = detail.length > 200 ? detail.slice(0, 200) : detail;
|
|
87
|
+
console.warn(
|
|
88
|
+
`VerifyAI[${SDK_VERSION}]: telemetry POST failed kind=${kind} ` +
|
|
89
|
+
`events=${eventCount} url=${this.baseUrl}/telemetry detail=${trimmed}`,
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
74
93
|
/** Track an error event. Fire-and-forget — never throws. */
|
|
75
94
|
track(
|
|
76
95
|
eventType: string,
|
|
@@ -158,6 +177,7 @@ export class TelemetryReporter {
|
|
|
158
177
|
const controller = new AbortController();
|
|
159
178
|
const timeout = setTimeout(() => controller.abort(), 10000);
|
|
160
179
|
|
|
180
|
+
let loggedDeliveryFailure = false;
|
|
161
181
|
try {
|
|
162
182
|
const response = await fetch(`${this.baseUrl}/telemetry`, {
|
|
163
183
|
method: 'POST',
|
|
@@ -170,12 +190,25 @@ export class TelemetryReporter {
|
|
|
170
190
|
});
|
|
171
191
|
|
|
172
192
|
if (!response.ok) {
|
|
193
|
+
let body = '';
|
|
194
|
+
try {
|
|
195
|
+
body = await response.text();
|
|
196
|
+
} catch {
|
|
197
|
+
// ignore
|
|
198
|
+
}
|
|
199
|
+
this.logDeliveryFailure(`http_${response.status}`, body, events.length);
|
|
200
|
+
loggedDeliveryFailure = true;
|
|
173
201
|
throw new Error(`Telemetry request failed with status ${response.status}`);
|
|
174
202
|
}
|
|
175
203
|
|
|
176
204
|
// Success — clear persisted buffer since events are now server-side
|
|
177
205
|
this.persistBuffer(); // buffer is empty at this point, so this clears the key
|
|
178
|
-
} catch {
|
|
206
|
+
} catch (error) {
|
|
207
|
+
if (!loggedDeliveryFailure) {
|
|
208
|
+
const kind = error instanceof Error ? error.name : typeof error;
|
|
209
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
210
|
+
this.logDeliveryFailure(kind, detail, events.length);
|
|
211
|
+
}
|
|
179
212
|
for (const [dedupKey, event] of bufferedEntries) {
|
|
180
213
|
const existing = this.buffer.get(dedupKey);
|
|
181
214
|
if (existing) {
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const SDK_VERSION = '2.4.
|
|
1
|
+
export const SDK_VERSION = '2.4.23';
|