@incodetech/core 2.3.0-rc.1 → 2.3.0-rc.10
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/dist/{BrowserDiagnosticsCryptoProvider-CU6kBvqv.esm.js → BrowserDiagnosticsCryptoProvider-BuzqvbhN.esm.js} +6 -24
- package/dist/{FaceDetectionProvider-BfhWkK90.esm.js → FaceDetectionProvider-BZYHujqz.esm.js} +8 -8
- package/dist/{MotionSensorProvider-BgTYwg9L.esm.js → MotionSensorProvider-DyhbM4Si.esm.js} +1 -1
- package/dist/ae-signature.esm.js +1 -1
- package/dist/{apiError-Budb6m6w.esm.js → apiError-iTFZ5fiI.esm.js} +1 -1
- package/dist/authentication.d.ts +2 -2
- package/dist/authentication.esm.js +2 -2
- package/dist/{authenticationManager-CjXBjC-c.d.ts → authenticationManager-B23V74p7.d.ts} +1 -1
- package/dist/{authenticationManager-cMXhG70r.esm.js → authenticationManager-D22ju23T.esm.js} +4 -4
- package/dist/{authenticationStateMachine-MOYz4HCf.esm.js → authenticationStateMachine-TyFaCegB.esm.js} +3 -3
- package/dist/{backCameraStream-BOtyQowf.esm.js → backCameraStream-B0-YgP_y.esm.js} +1 -0
- package/dist/camera.esm.js +1 -1
- package/dist/consent.d.ts +1 -1
- package/dist/{consentManager-BhYFeKiG.d.ts → consentManager-uhDPdU6i.d.ts} +8 -8
- package/dist/{createCameraCycleOwnership-CX3hJGKc.esm.js → createCameraCycleOwnership-DnwTl1ad.esm.js} +6 -1
- package/dist/{deepsightLoader-DDv3vhXU.esm.js → deepsightLoader-DamOBrBJ.esm.js} +6 -6
- package/dist/document-capture.d.ts +1 -1
- package/dist/document-capture.esm.js +2 -2
- package/dist/{documentCaptureManager-CwAiM9WY.esm.js → documentCaptureManager-BRPxqYD2.esm.js} +1 -1
- package/dist/{documentCaptureManager-DensIj5F.d.ts → documentCaptureManager-lEtCM320.d.ts} +14 -0
- package/dist/{documentCaptureStateMachine-DfGOBapD.esm.js → documentCaptureStateMachine-D312sSIu.esm.js} +13 -8
- package/dist/dynamic-forms.esm.js +2 -2
- package/dist/{dynamicFormsManager-BbS-XMFc.esm.js → dynamicFormsManager-DKgiusbF.esm.js} +1 -1
- package/dist/{dynamicFormsStateMachine-D8zHBCh4.esm.js → dynamicFormsStateMachine-BV8yR5iN.esm.js} +1 -1
- package/dist/ekyb.esm.js +3 -3
- package/dist/{ekybManager-5aiac8wL.esm.js → ekybManager-8VUBu8VW.esm.js} +1 -1
- package/dist/{ekybStateMachine-Bn2IE9rx.esm.js → ekybStateMachine-Bnsefu9M.esm.js} +1 -1
- package/dist/electronic-signature.esm.js +1 -1
- package/dist/{electronicSignatureManager-BJJH0Tvi.esm.js → electronicSignatureManager--YFXVldr.esm.js} +1 -1
- package/dist/extensibility.d.ts +7 -7
- package/dist/extensibility.esm.js +13 -13
- package/dist/{faceCaptureManagerFactory-B7Ms6pSs.esm.js → faceCaptureManagerFactory-Bk6pVs6E.esm.js} +3 -3
- package/dist/{faceCaptureManagerFactory-BeUl8fl1.d.ts → faceCaptureManagerFactory-DMLstvui.d.ts} +80 -40
- package/dist/{faceCaptureSetup-bkAlr5d8.esm.js → faceCaptureSetup-CGQDK97m.esm.js} +267 -45
- package/dist/{feature-management-E0mq0pMs.esm.js → feature-management-C8OAO_CZ.esm.js} +1 -1
- package/dist/feature-management.esm.js +1 -1
- package/dist/fiscal-qr.esm.js +1 -1
- package/dist/{fiscalQrManager-BunLVFbd.esm.js → fiscalQrManager-DbCVMIBx.esm.js} +1 -1
- package/dist/flow.esm.js +3 -3
- package/dist/{flowCompletionService-DJp1odGN.esm.js → flowCompletionService-C0zcPnqK.esm.js} +1 -1
- package/dist/{flowServices-DjPFGs_D.esm.js → flowServices-G1FDrkLd.esm.js} +5 -5
- package/dist/geolocation.esm.js +2 -2
- package/dist/{geolocationManager-D5906YXx.esm.js → geolocationManager-DNixQOgf.esm.js} +1 -1
- package/dist/{geolocationStateMachine-BVOduc3y.esm.js → geolocationStateMachine-D1aZJ6eR.esm.js} +1 -1
- package/dist/id-selfie-flow.esm.js +9 -9
- package/dist/id.d.ts +2 -2
- package/dist/id.esm.js +4 -4
- package/dist/idCaptureDefaults-sJahGQgV.esm.js +282 -0
- package/dist/{idCaptureManager-rfV9dIXy.esm.js → idCaptureManager-B8lo-ksK.esm.js} +5 -5
- package/dist/{idCaptureManager-DKESug0R.d.ts → idCaptureManager-BaHEyQyr.d.ts} +23 -5
- package/dist/{idCaptureServices-i1KxugN7.esm.js → idCaptureServices-DLqls7Xv.esm.js} +60 -13
- package/dist/{idCaptureStateMachine-Ne_PXth_.esm.js → idCaptureStateMachine-CCPGFPRF.esm.js} +221 -76
- package/dist/index.d.ts +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/mandatory-consent.d.ts +1 -1
- package/dist/{mandatoryConsentManager-vhv1co_n.d.ts → mandatoryConsentManager-CJSyhTpi.d.ts} +4 -4
- package/dist/{multipartRecordingService-OEgIRvqC.esm.js → multipartRecordingService-YKu0Bd7S.esm.js} +490 -8
- package/dist/{permissionGuards-uYZYFu4J.esm.js → permissionGuards-D6TfVop2.esm.js} +1 -1
- package/dist/{permissionServices-Bj_fyWtv.esm.js → permissionServices-EY3_Vx6c.esm.js} +2 -2
- package/dist/qe-signature.esm.js +1 -1
- package/dist/{runChildModule-CI1gGWN1.esm.js → runChildModule-B3Z4iJnG.esm.js} +1 -1
- package/dist/{safeStorage-B-trhxg6.esm.js → safeStorage-BdU9_m2E.esm.js} +1 -1
- package/dist/{sdkVersion-BZh6dj53.esm.js → sdkVersion-CD9fJC2Y.esm.js} +1 -1
- package/dist/selfie.d.ts +2 -2
- package/dist/selfie.esm.js +7 -7
- package/dist/{selfieManager-4RRLi21P.d.ts → selfieManager-CDCTOrcg.d.ts} +1 -1
- package/dist/{selfieManager-B-2c1n_x.esm.js → selfieManager-DzOPNipB.esm.js} +4 -4
- package/dist/{selfieStateMachine-Bzx41R8d.esm.js → selfieStateMachine-CidiobBW.esm.js} +3 -3
- package/dist/{session-3LmvAU4S.esm.js → session-BABCfUhC.esm.js} +3 -3
- package/dist/session.esm.js +4 -4
- package/dist/{sessionInitializer-BFk33E67.esm.js → sessionInitializer-BK5NjMe0.esm.js} +4 -4
- package/dist/{setup-Cv-JM9QC.d.ts → setup-Cyko6cAn.d.ts} +6 -18
- package/dist/{setup-BWG-hivt.esm.js → setup-D4YCSH31.esm.js} +12 -200
- package/dist/{tri-4RsGrIt6.esm.js → tri-xzRLIIMN.esm.js} +0 -10
- package/dist/tri.esm.js +1 -1
- package/dist/{trueSightService-BN-Hzw82.esm.js → trueSightService-D8yZwF3G.esm.js} +189 -570
- package/dist/video-selfie.esm.js +5 -6
- package/dist/{videoSelfieCameraWarmer-B8PcYqmz.esm.js → videoSelfieCameraWarmer-C80ZPDZ8.esm.js} +6 -6
- package/dist/{warmup-CUUnwYxe.esm.js → warmup-ChDwHSel.esm.js} +5 -0
- package/dist/wasm.d.ts +1 -1
- package/dist/wasm.esm.js +3 -2
- package/dist/{wasmDsFlagSync-B2e8p268.esm.js → wasmDsFlagSync-DYrLUEII.esm.js} +1 -1
- package/dist/workflow.esm.js +15 -15
- package/package.json +1 -6
- package/dist/FaceDetectionProvider-LdZ47bWy.d.ts +0 -36
- package/dist/StreamCanvasProcessingSession-CBnbTnOr.esm.js +0 -42
- package/dist/idCaptureDefaults-CbPA-Auz.esm.js +0 -727
- package/dist/personhood.d.ts +0 -538
- package/dist/personhood.esm.js +0 -1574
- package/dist/types-BT_Oalip.d.ts +0 -1
|
@@ -1,9 +1,148 @@
|
|
|
1
|
-
import { a as setWebApiHttpTransport, i as initializeWasmWebClient, o as setupWasmConnection, r as executeWasmRequest, t as WasmWebClientError } from "./wasmWebClient-B7baE-Wf.esm.js";
|
|
1
|
+
import { a as setWebApiHttpTransport, f as deriveSiblingJsPath, i as initializeWasmWebClient, o as setupWasmConnection, p as WASM_MODEL_FILES, r as executeWasmRequest, t as WasmWebClientError, v as buildModelVariantSources } from "./wasmWebClient-B7baE-Wf.esm.js";
|
|
2
2
|
import { t as getTimestamp } from "./IBrowserEnvironmentCapability-DEaRRk-R.esm.js";
|
|
3
3
|
import { i as isApiConfigured, n as getApi, o as setClient, r as getToken, t as api } from "./api-Bx3gKW_y.esm.js";
|
|
4
|
-
import {
|
|
5
|
-
import { t as SDK_VERSION } from "./sdkVersion-
|
|
4
|
+
import { n as eventModuleNames } from "./events-ijlbX_Wx.esm.js";
|
|
5
|
+
import { t as SDK_VERSION } from "./sdkVersion-CD9fJC2Y.esm.js";
|
|
6
6
|
import { t as endpoints } from "./endpoints-B-3Q-LUw.esm.js";
|
|
7
|
+
//#region ../infra/src/wasm/wasmDefaults.ts
|
|
8
|
+
const WASM_CDN_BASE_URL = "https://cdn.incodesmile.com/ml-wasm-kit-release";
|
|
9
|
+
/** The WASM version bundled and tested with this SDK release. */
|
|
10
|
+
const DEFAULT_WASM_VERSION = "v2.14.50-post1";
|
|
11
|
+
const PATH_KEYS = [
|
|
12
|
+
"wasmPath",
|
|
13
|
+
"wasmSimdPath",
|
|
14
|
+
"glueCodePath",
|
|
15
|
+
"glueCodeSimdPath",
|
|
16
|
+
"modelsBasePath"
|
|
17
|
+
];
|
|
18
|
+
function isBlank(value) {
|
|
19
|
+
return value.trim() === "";
|
|
20
|
+
}
|
|
21
|
+
function hasDisallowedControlChars(value) {
|
|
22
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
23
|
+
const code = value.charCodeAt(i);
|
|
24
|
+
if (code < 32 || code === 127) return true;
|
|
25
|
+
}
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
function isMalformedPath(value) {
|
|
29
|
+
const trimmed = value.trim();
|
|
30
|
+
if (trimmed === "") return false;
|
|
31
|
+
if (hasDisallowedControlChars(trimmed)) return true;
|
|
32
|
+
if (/^https?:\/\//i.test(trimmed)) try {
|
|
33
|
+
new URL(trimmed);
|
|
34
|
+
return false;
|
|
35
|
+
} catch {
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
function warnInvalidWasmPath(field, reason) {
|
|
41
|
+
if (reason === "empty") {
|
|
42
|
+
console.warn(`[Incode SDK] wasm.${field} is empty. Falling back to CDN default.`);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
console.warn(`[Incode SDK] wasm.${field} appears malformed. Falling back to CDN default.`);
|
|
46
|
+
}
|
|
47
|
+
function warnMalformedWasmPath(field) {
|
|
48
|
+
console.warn(`[Incode SDK] wasm.${field} appears malformed. Check the URL or path.`);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Validates merged WASM path strings. When overrides contained blank path
|
|
52
|
+
* values, callers should have already fallen back to defaults before this runs.
|
|
53
|
+
*/
|
|
54
|
+
function validateWasmPaths(config) {
|
|
55
|
+
for (const key of PATH_KEYS) {
|
|
56
|
+
const value = config[key];
|
|
57
|
+
if (typeof value === "string" && isMalformedPath(value)) warnMalformedWasmPath(key);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function pickPath(key, overrides, defaultValue) {
|
|
61
|
+
if (!overrides || !(key in overrides)) return defaultValue;
|
|
62
|
+
const raw = overrides[key];
|
|
63
|
+
if (raw === void 0) return defaultValue;
|
|
64
|
+
if (typeof raw !== "string") return defaultValue;
|
|
65
|
+
if (isBlank(raw)) {
|
|
66
|
+
warnInvalidWasmPath(key, "empty");
|
|
67
|
+
return defaultValue;
|
|
68
|
+
}
|
|
69
|
+
if (isMalformedPath(raw)) {
|
|
70
|
+
warnInvalidWasmPath(key, "malformed");
|
|
71
|
+
return defaultValue;
|
|
72
|
+
}
|
|
73
|
+
return raw.trim();
|
|
74
|
+
}
|
|
75
|
+
function pickSource(key, overrides, defaultValue) {
|
|
76
|
+
if (!(key in overrides) || overrides[key] === void 0) return defaultValue;
|
|
77
|
+
const source = overrides[key];
|
|
78
|
+
if (typeof source !== "string") return source;
|
|
79
|
+
return pickPath(key, overrides, String(defaultValue));
|
|
80
|
+
}
|
|
81
|
+
function resolveBasePath(overrides) {
|
|
82
|
+
const defaultValue = `${WASM_CDN_BASE_URL}/${DEFAULT_WASM_VERSION}`;
|
|
83
|
+
if (!("basePath" in overrides) || overrides.basePath === void 0) return defaultValue;
|
|
84
|
+
const basePath = overrides.basePath;
|
|
85
|
+
if (typeof basePath !== "string" || isBlank(basePath) || isMalformedPath(basePath)) throw new Error("[Incode SDK] wasm.basePath is invalid.");
|
|
86
|
+
return basePath.trim();
|
|
87
|
+
}
|
|
88
|
+
/** Builds a WarmupConfig from a directory that mirrors the ml-wasm-kit CDN layout. */
|
|
89
|
+
function buildWasmConfigFromBasePath(basePath) {
|
|
90
|
+
const base = basePath.endsWith("/") ? basePath.slice(0, -1) : basePath;
|
|
91
|
+
return {
|
|
92
|
+
wasmPath: `${base}/webLib.wasm`,
|
|
93
|
+
wasmSimdPath: `${base}/webLibSimd.wasm`,
|
|
94
|
+
glueCodePath: `${base}/webLib.js`,
|
|
95
|
+
glueCodeSimdPath: `${base}/webLibSimd.js`,
|
|
96
|
+
modelsBasePath: `${base}/models`
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/** Builds the standard WarmupConfig from the Incode CDN. */
|
|
100
|
+
function buildDefaultWasmConfig() {
|
|
101
|
+
return buildWasmConfigFromBasePath(`${WASM_CDN_BASE_URL}/${DEFAULT_WASM_VERSION}`);
|
|
102
|
+
}
|
|
103
|
+
const BARCODE_ENHANCE_MODEL_FILE = WASM_MODEL_FILES.barcode;
|
|
104
|
+
/**
|
|
105
|
+
* URL of the lazily-loaded PDF417 barcode enhancement model (US Smart Capture).
|
|
106
|
+
* Derived from the resolved `modelsBasePath` so self-hosted / air-gapped
|
|
107
|
+
* deployments resolve it correctly, falling back to the CDN default. Loaded on
|
|
108
|
+
* demand via `IIdCaptureCapability.setBarcodeEnhancementModel` — deliberately
|
|
109
|
+
* NOT part of any warmup model bundle.
|
|
110
|
+
*/
|
|
111
|
+
function getBarcodeEnhanceModelUrl(modelsBasePath, variant = "current") {
|
|
112
|
+
const source = buildModelVariantSources(modelsBasePath ?? `${WASM_CDN_BASE_URL}/v2.14.50-post1/models`, BARCODE_ENHANCE_MODEL_FILE);
|
|
113
|
+
return typeof source === "string" ? source : source[variant];
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Merges optional WASM path overrides with CDN defaults. Explicit non-blank
|
|
117
|
+
* paths take precedence. Blank override strings log a warning and fall back to defaults.
|
|
118
|
+
*/
|
|
119
|
+
function resolveWasmConfig(overrides) {
|
|
120
|
+
if (!overrides) return buildDefaultWasmConfig();
|
|
121
|
+
const defaults = buildWasmConfigFromBasePath(resolveBasePath(overrides));
|
|
122
|
+
const resolvedWasmPath = pickSource("wasmPath", overrides, defaults.wasmPath);
|
|
123
|
+
const simdDefault = overrides.selfHosted ? resolvedWasmPath : defaults.wasmSimdPath;
|
|
124
|
+
const modelsDefault = defaults.modelsBasePath;
|
|
125
|
+
const resolvedWasmSimdPath = pickSource("wasmSimdPath", overrides, simdDefault);
|
|
126
|
+
const glueCodeSimdDefault = typeof resolvedWasmSimdPath === "string" ? deriveSiblingJsPath(resolvedWasmSimdPath) : defaults.glueCodeSimdPath;
|
|
127
|
+
const merged = {
|
|
128
|
+
wasmPath: resolvedWasmPath,
|
|
129
|
+
wasmSimdPath: resolvedWasmSimdPath,
|
|
130
|
+
glueCodePath: pickPath("glueCodePath", overrides, defaults.glueCodePath),
|
|
131
|
+
glueCodeSimdPath: pickPath("glueCodeSimdPath", overrides, glueCodeSimdDefault),
|
|
132
|
+
modelsBasePath: pickPath("modelsBasePath", overrides, modelsDefault),
|
|
133
|
+
useSimd: overrides.useSimd,
|
|
134
|
+
pipelines: overrides.pipelines,
|
|
135
|
+
pipelineModels: overrides.pipelineModels,
|
|
136
|
+
modelUrls: overrides.modelUrls,
|
|
137
|
+
legacyModelUrls: overrides.legacyModelUrls,
|
|
138
|
+
loadGlue: overrides.loadGlue,
|
|
139
|
+
loadGlueSimd: overrides.loadGlueSimd,
|
|
140
|
+
selfHosted: overrides.selfHosted
|
|
141
|
+
};
|
|
142
|
+
validateWasmPaths(merged);
|
|
143
|
+
return merged;
|
|
144
|
+
}
|
|
145
|
+
//#endregion
|
|
7
146
|
//#region ../infra/src/http/createApi.ts
|
|
8
147
|
var FetchHttpError = class extends Error {
|
|
9
148
|
constructor(status, statusText, url, method, headers, data) {
|
|
@@ -336,7 +475,7 @@ const createWasmApi = async (config) => {
|
|
|
336
475
|
const upperMethod = normalizeMethod(method);
|
|
337
476
|
const requestParams = params ?? query;
|
|
338
477
|
const fullUrl = buildUrl(defaults.baseURL, url, requestParams);
|
|
339
|
-
const needsSchemeHeader =
|
|
478
|
+
const needsSchemeHeader = useSha256 && isEncryptionEnabled();
|
|
340
479
|
const mergedHeaders = {
|
|
341
480
|
...defaults.headers,
|
|
342
481
|
...needsSchemeHeader ? { "X-RSA-Encryption-Scheme": RSA_OAEP_SHA256_SCHEME } : {},
|
|
@@ -423,10 +562,18 @@ const createWasmApi = async (config) => {
|
|
|
423
562
|
* `httpClient.request()` pipeline as every other endpoint — header
|
|
424
563
|
* injection, encryption-state handling, default headers, timeout — instead
|
|
425
564
|
* of bypassing it via `executeWasmRequest` directly.
|
|
565
|
+
*
|
|
566
|
+
* Protected captures arrive with `ie === true`: the C++ `WebApi` already
|
|
567
|
+
* encrypted the body inline, and only the WASM `WebClient` can unwrap it. A
|
|
568
|
+
* plain fetch client would post the ciphertext as JSON and the backend
|
|
569
|
+
* answers 406. If the plain client is still installed at that point (the
|
|
570
|
+
* host called `setup()` without `wasm` and warmed WASM separately), swap to
|
|
571
|
+
* the WASM client first. The module is already loaded — the payload came
|
|
572
|
+
* out of it — so the swap only creates the `WebClient`.
|
|
426
573
|
*/
|
|
427
574
|
function bindWebApiTransport(client) {
|
|
428
575
|
return async (url, body, config) => {
|
|
429
|
-
const response = await client.request({
|
|
576
|
+
const response = await (config.ie === true && storedHttpConfig && !storedHttpConfig.isWasm ? await ensureWasmHttpClient() : client).request({
|
|
430
577
|
method: "POST",
|
|
431
578
|
url,
|
|
432
579
|
body,
|
|
@@ -445,7 +592,12 @@ function installClient(client) {
|
|
|
445
592
|
setClient(client);
|
|
446
593
|
setWebApiHttpTransport(bindWebApiTransport(client));
|
|
447
594
|
}
|
|
595
|
+
async function ensureWasmHttpClient() {
|
|
596
|
+
await upgradeToWasmHttpClient(resolveWasmConfig());
|
|
597
|
+
return getApi();
|
|
598
|
+
}
|
|
448
599
|
let storedHttpConfig;
|
|
600
|
+
let pendingUpgrade;
|
|
449
601
|
/** Reads the current HTTP-client config (or `undefined` if none installed). */
|
|
450
602
|
function getStoredHttpConfig() {
|
|
451
603
|
return storedHttpConfig;
|
|
@@ -502,19 +654,24 @@ async function installFreshHttpClient(apiURL, options, effectiveWasm, encryption
|
|
|
502
654
|
async function upgradeToWasmHttpClient(resolved) {
|
|
503
655
|
const stored = storedHttpConfig;
|
|
504
656
|
if (!stored || stored.isWasm) return;
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
657
|
+
pendingUpgrade ??= (async () => {
|
|
658
|
+
installClient(await createWasmApi({
|
|
659
|
+
apiURL: stored.apiURL,
|
|
660
|
+
customHeaders: stored.customHeaders,
|
|
661
|
+
timeout: stored.timeout,
|
|
662
|
+
wasm: resolved,
|
|
663
|
+
encryptionEnabled: stored.encryption.enabled,
|
|
664
|
+
mgf1: stored.encryption.mgf1,
|
|
665
|
+
isEncryptionEnabled: isHttpEncrypted
|
|
666
|
+
}));
|
|
667
|
+
storedHttpConfig = {
|
|
668
|
+
...stored,
|
|
669
|
+
isWasm: true
|
|
670
|
+
};
|
|
671
|
+
})().finally(() => {
|
|
672
|
+
pendingUpgrade = void 0;
|
|
673
|
+
});
|
|
674
|
+
return pendingUpgrade;
|
|
518
675
|
}
|
|
519
676
|
/**
|
|
520
677
|
* When `wantsEncryption` is true, wraps a call that triggers the in-binary
|
|
@@ -531,8 +688,6 @@ async function withHandshakeFailureContext(wantsEncryption, fn) {
|
|
|
531
688
|
throw error;
|
|
532
689
|
}
|
|
533
690
|
}
|
|
534
|
-
/** Dirty-timer half of the interrupted-snapshot rebuild debounce (module boundaries + timer). */
|
|
535
|
-
const SNAPSHOT_DIRTY_INTERVAL_MS = 15e3;
|
|
536
691
|
/** Hard cap per log message, UTF-8 bytes (contract). */
|
|
537
692
|
const MESSAGE_MAX_BYTES = 8 * 1024;
|
|
538
693
|
const TRUESIGHT_SDK_ID = "IncdOnboarding";
|
|
@@ -613,92 +768,6 @@ function truncateUtf8(value, maxBytes) {
|
|
|
613
768
|
}
|
|
614
769
|
return result + TRUNCATION_SUFFIX;
|
|
615
770
|
}
|
|
616
|
-
const EVICTION_ORDER = [
|
|
617
|
-
"verbose",
|
|
618
|
-
"debug",
|
|
619
|
-
"info"
|
|
620
|
-
];
|
|
621
|
-
function createLogBuffer(options = {}) {
|
|
622
|
-
const flushThresholdBytes = options.flushThresholdBytes ?? 6e5;
|
|
623
|
-
const maxEntries = options.maxEntries ?? 5e3;
|
|
624
|
-
const { onOverflow } = options;
|
|
625
|
-
const entries = [];
|
|
626
|
-
let mode = onOverflow ? "flush" : "evict";
|
|
627
|
-
let nextIndex = 0;
|
|
628
|
-
let bytes = 0;
|
|
629
|
-
let dropped = 0;
|
|
630
|
-
let overflowPending = false;
|
|
631
|
-
function entryCost(entry) {
|
|
632
|
-
return utf8ByteLength(entry.message) + utf8ByteLength(entry.subsystem) + 120;
|
|
633
|
-
}
|
|
634
|
-
function removeAt(position) {
|
|
635
|
-
const [removed] = entries.splice(position, 1);
|
|
636
|
-
bytes -= entryCost(removed);
|
|
637
|
-
dropped += 1;
|
|
638
|
-
}
|
|
639
|
-
/** Lowest level first (oldest within it); warning+ only as the last resort. */
|
|
640
|
-
function evictOne() {
|
|
641
|
-
for (const level of EVICTION_ORDER) {
|
|
642
|
-
const position = entries.findIndex((entry) => entry.level === level);
|
|
643
|
-
if (position !== -1) {
|
|
644
|
-
removeAt(position);
|
|
645
|
-
return;
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
removeAt(0);
|
|
649
|
-
}
|
|
650
|
-
function copyOf(entry) {
|
|
651
|
-
return { ...entry };
|
|
652
|
-
}
|
|
653
|
-
return {
|
|
654
|
-
append(level, subsystem, category, message) {
|
|
655
|
-
const entry = {
|
|
656
|
-
index: nextIndex,
|
|
657
|
-
timestampMs: getTimestamp(),
|
|
658
|
-
level,
|
|
659
|
-
subsystem,
|
|
660
|
-
category,
|
|
661
|
-
message: sanitizeMessage(message)
|
|
662
|
-
};
|
|
663
|
-
nextIndex += 1;
|
|
664
|
-
entries.push(entry);
|
|
665
|
-
bytes += entryCost(entry);
|
|
666
|
-
if (mode === "flush" && onOverflow) {
|
|
667
|
-
if (!overflowPending && bytes >= flushThresholdBytes) {
|
|
668
|
-
overflowPending = true;
|
|
669
|
-
onOverflow(entries.map(copyOf));
|
|
670
|
-
}
|
|
671
|
-
} else while (bytes > flushThresholdBytes && entries.length > 1) evictOne();
|
|
672
|
-
while (entries.length > maxEntries) evictOne();
|
|
673
|
-
},
|
|
674
|
-
snapshot() {
|
|
675
|
-
return entries.map(copyOf);
|
|
676
|
-
},
|
|
677
|
-
sliceSince(index) {
|
|
678
|
-
return entries.filter((entry) => entry.index > index).map(copyOf);
|
|
679
|
-
},
|
|
680
|
-
markFlushed(uptoIndex) {
|
|
681
|
-
let removedBytes = 0;
|
|
682
|
-
let keepFrom = 0;
|
|
683
|
-
while (keepFrom < entries.length && entries[keepFrom].index <= uptoIndex) {
|
|
684
|
-
removedBytes += entryCost(entries[keepFrom]);
|
|
685
|
-
keepFrom += 1;
|
|
686
|
-
}
|
|
687
|
-
entries.splice(0, keepFrom);
|
|
688
|
-
bytes -= removedBytes;
|
|
689
|
-
overflowPending = false;
|
|
690
|
-
},
|
|
691
|
-
setOverflowMode(next) {
|
|
692
|
-
mode = next;
|
|
693
|
-
},
|
|
694
|
-
get droppedCount() {
|
|
695
|
-
return dropped;
|
|
696
|
-
},
|
|
697
|
-
get byteEstimate() {
|
|
698
|
-
return bytes;
|
|
699
|
-
}
|
|
700
|
-
};
|
|
701
|
-
}
|
|
702
771
|
//#endregion
|
|
703
772
|
//#region ../infra/src/crypto/randomUUID.ts
|
|
704
773
|
/**
|
|
@@ -815,14 +884,6 @@ function toContractEntry(entry) {
|
|
|
815
884
|
category: entry.category
|
|
816
885
|
};
|
|
817
886
|
}
|
|
818
|
-
//#endregion
|
|
819
|
-
//#region src/internal/trueSight/sessionMetadata.ts
|
|
820
|
-
/**
|
|
821
|
-
* Hosts that match this pattern are non-prod by heuristic. Known failure modes
|
|
822
|
-
* (customer CNAMEs, devMode left on in prod) are documented for the planned
|
|
823
|
-
* P1 team review — see plan §Operating decisions (B6).
|
|
824
|
-
*/
|
|
825
|
-
const NON_PROD_HOST_PATTERN = /stage|demo|saas-dev|localhost/i;
|
|
826
887
|
function createInitialState() {
|
|
827
888
|
return {
|
|
828
889
|
sessionId: null,
|
|
@@ -846,67 +907,16 @@ function createInitialState() {
|
|
|
846
907
|
}
|
|
847
908
|
let state = createInitialState();
|
|
848
909
|
let sources = {};
|
|
849
|
-
function stampStartedAtOnce() {
|
|
850
|
-
if (state.startedAtMs === null) state.startedAtMs = getTimestamp();
|
|
851
|
-
}
|
|
852
910
|
/** Tap for `createSession` — sessionId comes from the returned `interviewId`. */
|
|
853
|
-
function noteSessionCreated(session, options = {}) {
|
|
854
|
-
|
|
855
|
-
stampStartedAtOnce();
|
|
856
|
-
state.sdkLanguage = options.language ?? state.sdkLanguage;
|
|
857
|
-
state.hasConfigurationId = state.hasConfigurationId || options.configurationId !== void 0;
|
|
858
|
-
state.hasExternalCustomerId = state.hasExternalCustomerId || options.externalCustomerId !== void 0;
|
|
859
|
-
state.hasProvidedSessionId = state.hasProvidedSessionId || options.interviewId !== void 0;
|
|
860
|
-
}
|
|
861
|
-
/**
|
|
862
|
-
* Fallback sessionId for host-minted-token integrations that never called
|
|
863
|
-
* `createSession`: `Features.sessionIdentifier` — used only when no
|
|
864
|
-
* `interviewId` was observed.
|
|
865
|
-
*/
|
|
866
|
-
function noteFeatureConfig(features) {
|
|
867
|
-
if (!state.sessionId && features.sessionIdentifier) {
|
|
868
|
-
state.sessionId = features.sessionIdentifier;
|
|
869
|
-
stampStartedAtOnce();
|
|
870
|
-
}
|
|
871
|
-
}
|
|
872
|
-
/**
|
|
873
|
-
* Entry-surface discriminator. `startOnboardingSection` is the default (weakest
|
|
874
|
-
* signal — standalone module managers); richer surfaces upgrade it and are never
|
|
875
|
-
* downgraded back.
|
|
876
|
-
*/
|
|
877
|
-
function noteIntegrationSurface(integrationType) {
|
|
878
|
-
if (integrationType === "startOnboardingSection") return;
|
|
879
|
-
state.integrationType = integrationType;
|
|
880
|
-
}
|
|
881
|
-
function noteEnvironment(environment) {
|
|
882
|
-
state.browser = environment.browser ?? state.browser;
|
|
883
|
-
state.osVersion = environment.osVersion ?? state.osVersion;
|
|
884
|
-
state.osLanguage = environment.osLanguage ?? state.osLanguage;
|
|
885
|
-
}
|
|
886
|
-
/**
|
|
887
|
-
* WRITE-ONCE orchestrator identity (determinism guarantee for debugging):
|
|
888
|
-
* a session is a flow or a workflow from its first orchestrator observation
|
|
889
|
-
* and can never flip mid-session — a record labeled `flow` must always point
|
|
890
|
-
* at a real flow. First non-null value wins for each of flowType/flowId/
|
|
891
|
-
* workflowId; later calls are ignored (the service logs a self-health line
|
|
892
|
-
* when a CONFLICTING orchestrator kind shows up).
|
|
893
|
-
*/
|
|
894
|
-
function noteFlowContext(context) {
|
|
895
|
-
state.flowType = state.flowType ?? context.flowType;
|
|
896
|
-
state.flowId = state.flowId ?? context.flowId ?? null;
|
|
897
|
-
state.workflowId = state.workflowId ?? context.workflowId ?? null;
|
|
898
|
-
}
|
|
911
|
+
function noteSessionCreated(session, options = {}) {}
|
|
912
|
+
function noteEnvironment(environment) {}
|
|
899
913
|
/**
|
|
900
914
|
* `testing` heuristic: devMode OR non-prod API host pattern. Always a boolean —
|
|
901
915
|
* the contract requires the field present on every record. Signals MERGE across
|
|
902
916
|
* calls (a later apiUrl-only call must not erase an earlier devMode signal);
|
|
903
917
|
* `testing` is recomputed from the merged pair.
|
|
904
918
|
*/
|
|
905
|
-
function noteTestingSignals(signals) {
|
|
906
|
-
state.devModeSignal = signals.devMode ?? state.devModeSignal;
|
|
907
|
-
state.apiUrlSignal = signals.apiUrl ?? state.apiUrlSignal;
|
|
908
|
-
state.testing = state.devModeSignal === true || state.apiUrlSignal !== void 0 && NON_PROD_HOST_PATTERN.test(state.apiUrlSignal);
|
|
909
|
-
}
|
|
919
|
+
function noteTestingSignals(signals) {}
|
|
910
920
|
/**
|
|
911
921
|
* Live read of the merged testing signal (devMode OR non-prod host). Used to
|
|
912
922
|
* gate host-console self-health noise so production host pages stay quiet while
|
|
@@ -917,25 +927,12 @@ function isTrueSightTesting() {
|
|
|
917
927
|
return state.testing;
|
|
918
928
|
}
|
|
919
929
|
/**
|
|
920
|
-
* Tap for `initializeSession({ token })` with a host-minted token — records
|
|
921
|
-
* only the presence fact ("this token came from outside the SDK"), never the
|
|
922
|
-
* token itself.
|
|
923
|
-
*/
|
|
924
|
-
function noteExternalTokenProvided() {
|
|
925
|
-
state.hasExternalToken = true;
|
|
926
|
-
}
|
|
927
|
-
/**
|
|
928
930
|
* Wiring tap for every `initializeSession({ token })`: a token activated
|
|
929
931
|
* before any `createSession` was observed on this page is host-minted, i.e.
|
|
930
932
|
* external. (The exact `token`/`externalToken` web-semantics are a pending
|
|
931
933
|
* Phase 0 contract ask — this inference is the interim mapping.)
|
|
932
934
|
*/
|
|
933
|
-
function noteTokenActivated() {
|
|
934
|
-
if (state.sessionId === null) noteExternalTokenProvided();
|
|
935
|
-
}
|
|
936
|
-
function configureTrueSightMetadataSources(next) {
|
|
937
|
-
sources = next;
|
|
938
|
-
}
|
|
935
|
+
function noteTokenActivated() {}
|
|
939
936
|
/** Explicit literal — the metadata half handed to the record builder. */
|
|
940
937
|
function buildSessionMetadata() {
|
|
941
938
|
return {
|
|
@@ -1110,100 +1107,10 @@ async function fetchFeatureConfig(signal) {
|
|
|
1110
1107
|
function resetFeatureConfigCache() {
|
|
1111
1108
|
cachedFeatures = null;
|
|
1112
1109
|
}
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
* lowercase dotted string per SDK area. The raw `eventModuleNames` wire
|
|
1118
|
-
* values are inconsistent (`SELFIE`, `datasharingconsent`, `AdSign`…), four
|
|
1119
|
-
* keys collapse into `ID`, and `workflow` doubles as a module name — this
|
|
1120
|
-
* table is the single normalization point, snapshot-frozen in tests so the
|
|
1121
|
-
* dashboard facet stays bounded (~70 strings) forever.
|
|
1122
|
-
*/
|
|
1123
|
-
const MODULE_SUBSYSTEMS = {
|
|
1124
|
-
[eventModuleNames.selfie]: "module.selfie",
|
|
1125
|
-
[eventModuleNames.faceCapture]: "module.face-capture",
|
|
1126
|
-
[eventModuleNames.authentication]: "module.authentication",
|
|
1127
|
-
[eventModuleNames.authFace]: "module.auth-face",
|
|
1128
|
-
[eventModuleNames.mlConsent]: "module.ml-consent",
|
|
1129
|
-
[eventModuleNames.combinedConsent]: "module.combined-consent",
|
|
1130
|
-
[eventModuleNames.curpValidation]: "module.curp",
|
|
1131
|
-
[eventModuleNames.faceMatch]: "module.face-match",
|
|
1132
|
-
[eventModuleNames.qr]: "module.qr",
|
|
1133
|
-
[eventModuleNames.videoSelfie]: "module.video-selfie",
|
|
1134
|
-
[eventModuleNames.id]: "module.id",
|
|
1135
|
-
[eventModuleNames.idCapture]: "module.id-capture",
|
|
1136
|
-
[eventModuleNames.idVerification]: "module.id-verification",
|
|
1137
|
-
[eventModuleNames.idOcr]: "module.id-ocr",
|
|
1138
|
-
[eventModuleNames.document]: "module.document-capture",
|
|
1139
|
-
[eventModuleNames.creditCard]: "module.credit-card-front",
|
|
1140
|
-
[eventModuleNames.creditCardBack]: "module.credit-card-back",
|
|
1141
|
-
[eventModuleNames.conference]: "module.conference",
|
|
1142
|
-
[eventModuleNames.otp]: "module.otp",
|
|
1143
|
-
[eventModuleNames.signature]: "module.e-sign",
|
|
1144
|
-
[eventModuleNames.ekyc]: "module.e-kyc",
|
|
1145
|
-
[eventModuleNames.watchlist]: "module.watchlist",
|
|
1146
|
-
[eventModuleNames.globalWatchList]: "module.global-watchlist",
|
|
1147
|
-
[eventModuleNames.customWatchList]: "module.custom-watchlist",
|
|
1148
|
-
[eventModuleNames.email]: "module.email",
|
|
1149
|
-
[eventModuleNames.phone]: "module.phone-number",
|
|
1150
|
-
[eventModuleNames.instantVerifyEmail]: "module.instant-verify-email",
|
|
1151
|
-
[eventModuleNames.instantVerifyConsent]: "module.instant-verify-consent",
|
|
1152
|
-
[eventModuleNames.forms]: "module.forms",
|
|
1153
|
-
[eventModuleNames.customModule]: "module.custom-module",
|
|
1154
|
-
[eventModuleNames.geolocation]: "module.geolocation",
|
|
1155
|
-
[eventModuleNames.ekyb]: "module.e-kyb",
|
|
1156
|
-
[eventModuleNames.identityReuse]: "module.identity-reuse",
|
|
1157
|
-
[eventModuleNames.antifraud]: "module.antifraud",
|
|
1158
|
-
[eventModuleNames.aeSignature]: "module.ae-signature",
|
|
1159
|
-
[eventModuleNames.qeSignature]: "module.qe-signature",
|
|
1160
|
-
[eventModuleNames.crossDocumentDataMatch]: "module.cross-document-data-match",
|
|
1161
|
-
[eventModuleNames.customFields]: "module.custom-fields",
|
|
1162
|
-
[eventModuleNames.fieldComparison]: "module.field-comparison",
|
|
1163
|
-
[eventModuleNames.personhood]: "module.personhood",
|
|
1164
|
-
[eventModuleNames.watchlistForBusiness]: "module.watchlist-for-business",
|
|
1165
|
-
[eventModuleNames.trustGraph]: "module.trust-graph",
|
|
1166
|
-
[eventModuleNames.certificateIssuance]: "module.certificate-issuance",
|
|
1167
|
-
[eventModuleNames.governmentValidation]: "module.government-validation",
|
|
1168
|
-
[eventModuleNames.documentUpload]: "module.document-upload",
|
|
1169
|
-
[eventModuleNames.home]: "module.home",
|
|
1170
|
-
[eventModuleNames.workflow]: "module.workflow",
|
|
1171
|
-
[eventModuleNames.fiscalQr]: "module.fiscal-qr"
|
|
1172
|
-
};
|
|
1173
|
-
const CUSTOM_SUBSYSTEM_MAX_CHARS = 40;
|
|
1174
|
-
/**
|
|
1175
|
-
* Canonical `module.<kebab>` for a raw wire module name. Unknown/integrator-
|
|
1176
|
-
* custom names get a sanitized lowercase fallback (capped) — custom SDK 2
|
|
1177
|
-
* integrations get real per-module detail, not a lumped `other`.
|
|
1178
|
-
*/
|
|
1179
|
-
function normalizeSubsystem(rawModule) {
|
|
1180
|
-
if (rawModule === void 0) return "module.unknown";
|
|
1181
|
-
const canonical = MODULE_SUBSYSTEMS[rawModule];
|
|
1182
|
-
if (canonical !== void 0) return canonical;
|
|
1183
|
-
const sanitized = rawModule.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, CUSTOM_SUBSYSTEM_MAX_CHARS).replace(/-+$/g, "");
|
|
1184
|
-
return `module.${sanitized === "" ? "unknown" : sanitized}`;
|
|
1185
|
-
}
|
|
1186
|
-
const ID_SCAN_MODULES = /* @__PURE__ */ new Set([
|
|
1187
|
-
eventModuleNames.id,
|
|
1188
|
-
eventModuleNames.idCapture,
|
|
1189
|
-
eventModuleNames.idVerification,
|
|
1190
|
-
eventModuleNames.idOcr,
|
|
1191
|
-
eventModuleNames.document,
|
|
1192
|
-
eventModuleNames.documentUpload,
|
|
1193
|
-
eventModuleNames.creditCard,
|
|
1194
|
-
eventModuleNames.creditCardBack,
|
|
1195
|
-
eventModuleNames.curpValidation
|
|
1196
|
-
]);
|
|
1197
|
-
const FACE_SCAN_MODULES = /* @__PURE__ */ new Set([
|
|
1198
|
-
eventModuleNames.selfie,
|
|
1199
|
-
eventModuleNames.faceCapture,
|
|
1200
|
-
eventModuleNames.authentication,
|
|
1201
|
-
eventModuleNames.authFace,
|
|
1202
|
-
eventModuleNames.faceMatch,
|
|
1203
|
-
eventModuleNames.videoSelfie,
|
|
1204
|
-
eventModuleNames.personhood
|
|
1205
|
-
]);
|
|
1206
|
-
const ORCHESTRATION_MODULES = /* @__PURE__ */ new Set([eventModuleNames.home, eventModuleNames.workflow]);
|
|
1110
|
+
eventModuleNames.selfie, eventModuleNames.faceCapture, eventModuleNames.authentication, eventModuleNames.authFace, eventModuleNames.mlConsent, eventModuleNames.combinedConsent, eventModuleNames.curpValidation, eventModuleNames.faceMatch, eventModuleNames.qr, eventModuleNames.videoSelfie, eventModuleNames.id, eventModuleNames.idCapture, eventModuleNames.idVerification, eventModuleNames.idOcr, eventModuleNames.document, eventModuleNames.creditCard, eventModuleNames.creditCardBack, eventModuleNames.conference, eventModuleNames.otp, eventModuleNames.signature, eventModuleNames.ekyc, eventModuleNames.watchlist, eventModuleNames.globalWatchList, eventModuleNames.customWatchList, eventModuleNames.email, eventModuleNames.phone, eventModuleNames.instantVerifyEmail, eventModuleNames.instantVerifyConsent, eventModuleNames.forms, eventModuleNames.customModule, eventModuleNames.geolocation, eventModuleNames.ekyb, eventModuleNames.identityReuse, eventModuleNames.antifraud, eventModuleNames.aeSignature, eventModuleNames.qeSignature, eventModuleNames.crossDocumentDataMatch, eventModuleNames.customFields, eventModuleNames.fieldComparison, eventModuleNames.personhood, eventModuleNames.watchlistForBusiness, eventModuleNames.trustGraph, eventModuleNames.certificateIssuance, eventModuleNames.governmentValidation, eventModuleNames.documentUpload, eventModuleNames.home, eventModuleNames.workflow, eventModuleNames.fiscalQr;
|
|
1111
|
+
eventModuleNames.id, eventModuleNames.idCapture, eventModuleNames.idVerification, eventModuleNames.idOcr, eventModuleNames.document, eventModuleNames.documentUpload, eventModuleNames.creditCard, eventModuleNames.creditCardBack, eventModuleNames.curpValidation;
|
|
1112
|
+
eventModuleNames.selfie, eventModuleNames.faceCapture, eventModuleNames.authentication, eventModuleNames.authFace, eventModuleNames.faceMatch, eventModuleNames.videoSelfie, eventModuleNames.personhood;
|
|
1113
|
+
eventModuleNames.home, eventModuleNames.workflow;
|
|
1207
1114
|
/**
|
|
1208
1115
|
* Coarse category for HTTP-failure entries, from the endpoint path (event
|
|
1209
1116
|
* map row 23: "by endpoint"). A conservative token heuristic — the category
|
|
@@ -1216,101 +1123,6 @@ function categoryForEndpoint(endpoint) {
|
|
|
1216
1123
|
if (/start|flow|workflow|feature-config|onboarding|finish-status/.test(endpoint)) return "orchestration";
|
|
1217
1124
|
return "other";
|
|
1218
1125
|
}
|
|
1219
|
-
/** Coarse contract category from the RAW `event.module` value (plan rule). */
|
|
1220
|
-
function categoryForModule(rawModule) {
|
|
1221
|
-
if (rawModule === void 0) return "other";
|
|
1222
|
-
if (ID_SCAN_MODULES.has(rawModule)) return "idScan";
|
|
1223
|
-
if (FACE_SCAN_MODULES.has(rawModule)) return "faceScan";
|
|
1224
|
-
if (ORCHESTRATION_MODULES.has(rawModule)) return "orchestration";
|
|
1225
|
-
return "other";
|
|
1226
|
-
}
|
|
1227
|
-
/** `verb key=value` line: undefined values drop their pair entirely. */
|
|
1228
|
-
function formatLine(verb, pairs = []) {
|
|
1229
|
-
const parts = [verb];
|
|
1230
|
-
for (const [key, value] of pairs) if (value !== void 0 && value !== null && value !== "") parts.push(`${key}=${String(value)}`);
|
|
1231
|
-
return parts.join(" ");
|
|
1232
|
-
}
|
|
1233
|
-
/**
|
|
1234
|
-
* Analytics event → contract log tuple, or `null` for codes the taxonomy
|
|
1235
|
-
* does not cover (deny-by-default: nothing rides into the record unreviewed).
|
|
1236
|
-
* Levels/subsystems/categories per the plan's event map rows 5–6 and 16–20.
|
|
1237
|
-
*/
|
|
1238
|
-
function mapAnalyticsEventToLog(event) {
|
|
1239
|
-
const payload = event.payload ?? {};
|
|
1240
|
-
const subsystem = normalizeSubsystem(event.module);
|
|
1241
|
-
const category = categoryForModule(event.module);
|
|
1242
|
-
switch (event.code) {
|
|
1243
|
-
case "moduleOpened":
|
|
1244
|
-
case "moduleClosed": return {
|
|
1245
|
-
level: "info",
|
|
1246
|
-
subsystem,
|
|
1247
|
-
category,
|
|
1248
|
-
message: formatLine(event.code === "moduleOpened" ? "module opened" : "module closed", [["screen", event.screen]])
|
|
1249
|
-
};
|
|
1250
|
-
case "screenOpened":
|
|
1251
|
-
case "screenClosed": return {
|
|
1252
|
-
level: "debug",
|
|
1253
|
-
subsystem,
|
|
1254
|
-
category,
|
|
1255
|
-
message: formatLine(event.code === "screenOpened" ? "screen opened" : "screen closed", [["screen", event.screen]])
|
|
1256
|
-
};
|
|
1257
|
-
case "errorTriggered": return {
|
|
1258
|
-
level: "error",
|
|
1259
|
-
subsystem,
|
|
1260
|
-
category,
|
|
1261
|
-
message: formatLine("errorTriggered", [
|
|
1262
|
-
["errorName", stringOrUndefined(payload.errorName) ?? "unknown"],
|
|
1263
|
-
["errorCode", stringOrUndefined(payload.errorCode)],
|
|
1264
|
-
["reason", stringOrUndefined(payload.reason)]
|
|
1265
|
-
])
|
|
1266
|
-
};
|
|
1267
|
-
case "captureAttemptFinished": return {
|
|
1268
|
-
level: "debug",
|
|
1269
|
-
subsystem,
|
|
1270
|
-
category,
|
|
1271
|
-
message: formatLine("capture attempt finished", [["logs", stringOrUndefined(payload.logs)]])
|
|
1272
|
-
};
|
|
1273
|
-
case "background":
|
|
1274
|
-
case "foreground": return {
|
|
1275
|
-
level: "debug",
|
|
1276
|
-
subsystem,
|
|
1277
|
-
category,
|
|
1278
|
-
message: `visibility ${event.code}`
|
|
1279
|
-
};
|
|
1280
|
-
case "elementClicked": return {
|
|
1281
|
-
level: "debug",
|
|
1282
|
-
subsystem,
|
|
1283
|
-
category,
|
|
1284
|
-
message: formatLine("element clicked", [["element", stringOrUndefined(payload.element)], ["action", stringOrUndefined(payload.action)]])
|
|
1285
|
-
};
|
|
1286
|
-
case "browser": {
|
|
1287
|
-
const browser = nameVersion(payload.browser);
|
|
1288
|
-
const os = nameVersion(payload.os);
|
|
1289
|
-
const device = typeof payload.device === "object" && payload.device !== null ? stringOrUndefined(payload.device.type) : void 0;
|
|
1290
|
-
return {
|
|
1291
|
-
level: "info",
|
|
1292
|
-
subsystem: "session",
|
|
1293
|
-
category: "other",
|
|
1294
|
-
message: formatLine("browser info", [
|
|
1295
|
-
["browser", browser],
|
|
1296
|
-
["os", os],
|
|
1297
|
-
["device", device],
|
|
1298
|
-
["webrtc", typeof payload.isWebRtcSupported === "boolean" ? payload.isWebRtcSupported : void 0]
|
|
1299
|
-
])
|
|
1300
|
-
};
|
|
1301
|
-
}
|
|
1302
|
-
default: return null;
|
|
1303
|
-
}
|
|
1304
|
-
}
|
|
1305
|
-
function stringOrUndefined(value) {
|
|
1306
|
-
return typeof value === "string" ? value : void 0;
|
|
1307
|
-
}
|
|
1308
|
-
function nameVersion(value) {
|
|
1309
|
-
if (typeof value !== "object" || value === null) return;
|
|
1310
|
-
const { name, version } = value;
|
|
1311
|
-
const joined = [name, version].filter((part) => typeof part === "string" && part !== "").join(" ");
|
|
1312
|
-
return joined === "" ? void 0 : joined;
|
|
1313
|
-
}
|
|
1314
1126
|
//#endregion
|
|
1315
1127
|
//#region src/internal/trueSight/uploader.ts
|
|
1316
1128
|
let cryptoProviderPromise = null;
|
|
@@ -1320,7 +1132,7 @@ let cryptoProviderPromise = null;
|
|
|
1320
1132
|
* the service's prewarm).
|
|
1321
1133
|
*/
|
|
1322
1134
|
function loadDiagnosticsCryptoProvider() {
|
|
1323
|
-
cryptoProviderPromise ??= import("./BrowserDiagnosticsCryptoProvider-
|
|
1135
|
+
cryptoProviderPromise ??= import("./BrowserDiagnosticsCryptoProvider-BuzqvbhN.esm.js").then((module) => new module.BrowserDiagnosticsCryptoProvider());
|
|
1324
1136
|
return cryptoProviderPromise;
|
|
1325
1137
|
}
|
|
1326
1138
|
/**
|
|
@@ -1329,35 +1141,7 @@ function loadDiagnosticsCryptoProvider() {
|
|
|
1329
1141
|
* rebuild ONCE with the oldest half of the logs dropped; still over → drop
|
|
1330
1142
|
* the upload entirely rather than send an invalid envelope.
|
|
1331
1143
|
*/
|
|
1332
|
-
async function uploadDiagnostics(record, options) {
|
|
1333
|
-
const warn = options.warn ?? defaultWarn;
|
|
1334
|
-
try {
|
|
1335
|
-
const sealer = await (options.loadCrypto ?? loadDiagnosticsCryptoProvider)();
|
|
1336
|
-
let envelope = await sealer.seal(JSON.stringify(record));
|
|
1337
|
-
let envelopeBytes = utf8ByteLength(JSON.stringify(envelope));
|
|
1338
|
-
if (envelopeBytes > 1e6) {
|
|
1339
|
-
const trimmed = {
|
|
1340
|
-
...record,
|
|
1341
|
-
logs: record.logs.slice(Math.floor(record.logs.length / 2))
|
|
1342
|
-
};
|
|
1343
|
-
warn(`[TrueSight] envelope ${envelopeBytes}B over the 1MB cap — rebuilt with the oldest ${record.logs.length - trimmed.logs.length} logs dropped`);
|
|
1344
|
-
envelope = await sealer.seal(JSON.stringify(trimmed));
|
|
1345
|
-
envelopeBytes = utf8ByteLength(JSON.stringify(envelope));
|
|
1346
|
-
if (envelopeBytes > 1e6) {
|
|
1347
|
-
warn("[TrueSight] envelope still over the cap after trim — upload dropped");
|
|
1348
|
-
return;
|
|
1349
|
-
}
|
|
1350
|
-
} else if (envelopeBytes > 9e5) warn(`[TrueSight] envelope ${envelopeBytes}B is approaching the 1MB cap`);
|
|
1351
|
-
const keepalive = options.keepalive === true && envelopeBytes <= 6e4;
|
|
1352
|
-
if (isForwardedFalse((await options.post(endpoints.diagnosticsData, envelope, keepalive ? { keepalive: true } : {})).data)) warn("[TrueSight] proxy accepted the record but did not forward it (forwarded:false)");
|
|
1353
|
-
} catch (error) {
|
|
1354
|
-
warn(`[TrueSight] diagnostics upload failed (no retry): ${String(error)}`);
|
|
1355
|
-
}
|
|
1356
|
-
}
|
|
1357
|
-
function isForwardedFalse(data) {
|
|
1358
|
-
return typeof data === "object" && data !== null && "forwarded" in data && data.forwarded === false;
|
|
1359
|
-
}
|
|
1360
|
-
function defaultWarn() {}
|
|
1144
|
+
async function uploadDiagnostics(record, options) {}
|
|
1361
1145
|
//#endregion
|
|
1362
1146
|
//#region src/internal/trueSight/trueSightService.ts
|
|
1363
1147
|
let active = false;
|
|
@@ -1374,21 +1158,15 @@ let options = defaultOptions();
|
|
|
1374
1158
|
let observedManagerKind = null;
|
|
1375
1159
|
let orchestratorConflictLogged = false;
|
|
1376
1160
|
let snapshotRecordId = null;
|
|
1377
|
-
let cachedPendingEnvelope = null;
|
|
1378
1161
|
let snapshotDirty = false;
|
|
1379
1162
|
let captureActive = false;
|
|
1380
1163
|
let rebuildInFlight = false;
|
|
1381
1164
|
let sealFailureLogged = false;
|
|
1382
1165
|
let pendingSlotRegistered = false;
|
|
1383
1166
|
let recoveryStarted = false;
|
|
1384
|
-
let bridgeFailureCount = 0;
|
|
1385
|
-
let envSnapshotLogged = false;
|
|
1386
1167
|
let hintTransitionCount = 0;
|
|
1387
1168
|
let hintSuppressedCount = 0;
|
|
1388
1169
|
let lastHintStatus = null;
|
|
1389
|
-
let overflowBatchCount = 0;
|
|
1390
|
-
let lastFlushRecordId = null;
|
|
1391
|
-
let overflowDormant = false;
|
|
1392
1170
|
let overflowFlushInFlightUpTo = null;
|
|
1393
1171
|
let dirtyTimerHandle = null;
|
|
1394
1172
|
let unsubscribePageHide = null;
|
|
@@ -1406,25 +1184,7 @@ function defaultOptions() {
|
|
|
1406
1184
|
* encryption lock); `reset()` → `resetTrueSight()` starts a new one.
|
|
1407
1185
|
* `enabled:false` is a no-op by design: zero subscriptions, zero state.
|
|
1408
1186
|
*/
|
|
1409
|
-
function initializeTrueSightDiagnostics(serviceOptions) {
|
|
1410
|
-
if (!serviceOptions.enabled || active) return;
|
|
1411
|
-
active = true;
|
|
1412
|
-
options = {
|
|
1413
|
-
...defaultOptions(),
|
|
1414
|
-
...pickDefined(serviceOptions)
|
|
1415
|
-
};
|
|
1416
|
-
buffer = createLogBuffer({ onOverflow: handleBufferOverflow });
|
|
1417
|
-
configureTrueSightMetadataSources({
|
|
1418
|
-
getHasToken: () => getToken() !== null,
|
|
1419
|
-
getE2eEncryptionEnabled: isHttpEncrypted
|
|
1420
|
-
});
|
|
1421
|
-
unsubscribeEvents = subscribeEvent(handleAnalyticsEvent);
|
|
1422
|
-
trueSightLog("debug", "diagnostics", "other", "diagnostics initialized");
|
|
1423
|
-
if (options.pageLifecycle && options.storage) unsubscribePageHide = options.pageLifecycle.onPageHide(handlePageHide);
|
|
1424
|
-
if (options.timer && options.storage) dirtyTimerHandle = options.timer.setInterval(() => {
|
|
1425
|
-
maybeRebuildSnapshot();
|
|
1426
|
-
}, SNAPSHOT_DIRTY_INTERVAL_MS);
|
|
1427
|
-
}
|
|
1187
|
+
function initializeTrueSightDiagnostics(serviceOptions) {}
|
|
1428
1188
|
/**
|
|
1429
1189
|
* Session-time entry, called from `initializeSession` once feature config is
|
|
1430
1190
|
* known. Collection is already running by then (buffering starts at
|
|
@@ -1439,7 +1199,6 @@ function startTrueSightCollection(features) {
|
|
|
1439
1199
|
prewarmCrypto();
|
|
1440
1200
|
}
|
|
1441
1201
|
if (features) {
|
|
1442
|
-
noteFeatureConfig(features);
|
|
1443
1202
|
if (!flagResolutionStarted) {
|
|
1444
1203
|
flagResolutionStarted = true;
|
|
1445
1204
|
applyFeatureResolution(features, false);
|
|
@@ -1447,7 +1206,6 @@ function startTrueSightCollection(features) {
|
|
|
1447
1206
|
} else if (!flagResolutionStarted) {
|
|
1448
1207
|
flagResolutionStarted = true;
|
|
1449
1208
|
options.fetchFeatures().then((fetched) => {
|
|
1450
|
-
noteFeatureConfig(fetched);
|
|
1451
1209
|
applyFeatureResolution(fetched, false);
|
|
1452
1210
|
}, () => {
|
|
1453
1211
|
applyFeatureResolution(null, true);
|
|
@@ -1460,10 +1218,7 @@ function startTrueSightCollection(features) {
|
|
|
1460
1218
|
* snapshot rebuilds are suppressed — the collector must never compete with
|
|
1461
1219
|
* 30 fps capture. Deactivation flushes the deferred rebuild.
|
|
1462
1220
|
*/
|
|
1463
|
-
function noteTrueSightCaptureActivity(activityActive) {
|
|
1464
|
-
captureActive = activityActive;
|
|
1465
|
-
if (!activityActive) maybeRebuildSnapshot();
|
|
1466
|
-
}
|
|
1221
|
+
function noteTrueSightCaptureActivity(activityActive) {}
|
|
1467
1222
|
/**
|
|
1468
1223
|
* Seals and uploads the one final record per session. The upload-relevant
|
|
1469
1224
|
* state — transport, metadata (live token/E2EE getters read NOW), buffered
|
|
@@ -1481,7 +1236,6 @@ function finalizeTrueSight(outcome, failureReason) {
|
|
|
1481
1236
|
if (transport === null || cryptoUnsupported) return Promise.resolve();
|
|
1482
1237
|
const record = buildDiagnosticsRecord(metadata, logs, outcome, failureReason);
|
|
1483
1238
|
if (record === null) return Promise.resolve();
|
|
1484
|
-
cachedPendingEnvelope = null;
|
|
1485
1239
|
if (options.storage && metadata.sessionId) clearPending(metadata.sessionId, { storage: options.storage });
|
|
1486
1240
|
return options.upload(record, {
|
|
1487
1241
|
post: transport,
|
|
@@ -1513,12 +1267,6 @@ function trueSightHintTransition(subsystem, category, status) {
|
|
|
1513
1267
|
}
|
|
1514
1268
|
trueSightLog("debug", subsystem, category, `hint changed status=${status}`);
|
|
1515
1269
|
}
|
|
1516
|
-
function resetHintBudget() {
|
|
1517
|
-
if (hintSuppressedCount > 0) trueSightLog("debug", "diagnostics", "other", `hint transitions suppressed count=${hintSuppressedCount}`);
|
|
1518
|
-
hintTransitionCount = 0;
|
|
1519
|
-
hintSuppressedCount = 0;
|
|
1520
|
-
lastHintStatus = null;
|
|
1521
|
-
}
|
|
1522
1270
|
/** Buffer tap for wiring points and self-health lines. No-op when inactive. */
|
|
1523
1271
|
function trueSightLog(level, subsystem, category, message) {
|
|
1524
1272
|
if (buffer === null) return;
|
|
@@ -1541,11 +1289,7 @@ function notifyTrueSightFlowEvent(event, managerKind) {
|
|
|
1541
1289
|
trueSightLog("info", managerKind, "orchestration", "flow.started");
|
|
1542
1290
|
break;
|
|
1543
1291
|
case "flow.ready":
|
|
1544
|
-
if (identityAccepted)
|
|
1545
|
-
flowType: managerKind,
|
|
1546
|
-
flowId: managerKind === "flow" ? event.flowId ?? null : null,
|
|
1547
|
-
workflowId: managerKind === "workflow" ? event.flowId ?? null : null
|
|
1548
|
-
});
|
|
1292
|
+
if (identityAccepted) managerKind === "flow" && event.flowId, managerKind === "workflow" && event.flowId;
|
|
1549
1293
|
trueSightLog("info", managerKind, "orchestration", `flow.ready ${managerKind === "workflow" ? "workflowId" : "flowId"}=${event.flowId ?? "unknown"}`);
|
|
1550
1294
|
break;
|
|
1551
1295
|
case "flow.module.started":
|
|
@@ -1603,8 +1347,6 @@ function stampOrchestratorIdentity(managerKind) {
|
|
|
1603
1347
|
}
|
|
1604
1348
|
return false;
|
|
1605
1349
|
}
|
|
1606
|
-
noteIntegrationSurface(managerKind === "workflow" ? "startWorkflow" : "startFlow");
|
|
1607
|
-
noteFlowContext({ flowType: managerKind });
|
|
1608
1350
|
return true;
|
|
1609
1351
|
}
|
|
1610
1352
|
/** Full teardown, called from `reset()` AFTER finalize captured its snapshot. */
|
|
@@ -1628,51 +1370,19 @@ function resetTrueSight() {
|
|
|
1628
1370
|
observedManagerKind = null;
|
|
1629
1371
|
orchestratorConflictLogged = false;
|
|
1630
1372
|
snapshotRecordId = null;
|
|
1631
|
-
cachedPendingEnvelope = null;
|
|
1632
1373
|
snapshotDirty = false;
|
|
1633
1374
|
captureActive = false;
|
|
1634
1375
|
rebuildInFlight = false;
|
|
1635
1376
|
sealFailureLogged = false;
|
|
1636
1377
|
pendingSlotRegistered = false;
|
|
1637
1378
|
recoveryStarted = false;
|
|
1638
|
-
bridgeFailureCount = 0;
|
|
1639
|
-
envSnapshotLogged = false;
|
|
1640
1379
|
hintTransitionCount = 0;
|
|
1641
1380
|
hintSuppressedCount = 0;
|
|
1642
1381
|
lastHintStatus = null;
|
|
1643
|
-
overflowBatchCount = 0;
|
|
1644
|
-
lastFlushRecordId = null;
|
|
1645
|
-
overflowDormant = false;
|
|
1646
1382
|
overflowFlushInFlightUpTo = null;
|
|
1647
1383
|
options = defaultOptions();
|
|
1648
1384
|
resetTrueSightMetadata();
|
|
1649
1385
|
}
|
|
1650
|
-
function handleAnalyticsEvent(event) {
|
|
1651
|
-
if (finalized) return;
|
|
1652
|
-
try {
|
|
1653
|
-
const mapped = mapAnalyticsEventToLog(event);
|
|
1654
|
-
if (mapped === null) return;
|
|
1655
|
-
trueSightLog(mapped.level, mapped.subsystem, mapped.category, mapped.message);
|
|
1656
|
-
if (mapped.level === "error" || mapped.level === "severe") logEnvironmentSnapshotOnce();
|
|
1657
|
-
if (event.code === "captureAttemptFinished") resetHintBudget();
|
|
1658
|
-
} catch {
|
|
1659
|
-
bridgeFailureCount += 1;
|
|
1660
|
-
if (bridgeFailureCount === 1) trueSightLog("warning", "diagnostics", "other", "bridge mapping failed");
|
|
1661
|
-
}
|
|
1662
|
-
}
|
|
1663
|
-
/**
|
|
1664
|
-
* Environment-snapshot-on-first-error (event map 19d): the "conditions at
|
|
1665
|
-
* the moment of failure" line — logged once per session, right after the
|
|
1666
|
-
* first error-level entry. The snapshot closure is injected (navigator
|
|
1667
|
-
* facts live behind the L0 environment provider).
|
|
1668
|
-
*/
|
|
1669
|
-
function logEnvironmentSnapshotOnce() {
|
|
1670
|
-
if (envSnapshotLogged || options.getEnvironmentSnapshot === void 0) return;
|
|
1671
|
-
envSnapshotLogged = true;
|
|
1672
|
-
try {
|
|
1673
|
-
trueSightLog("info", "session", "other", `environment at first error ${options.getEnvironmentSnapshot()}`);
|
|
1674
|
-
} catch {}
|
|
1675
|
-
}
|
|
1676
1386
|
function applyFeatureResolution(features, unresolvable) {
|
|
1677
1387
|
if (!active || remoteKilled || finalized) return;
|
|
1678
1388
|
const entry = features?.features?.find((candidate) => candidate.feature === "TRUESIGHT_DIAGNOSTICS");
|
|
@@ -1689,67 +1399,6 @@ function remoteKill() {
|
|
|
1689
1399
|
unsubscribeEvents = null;
|
|
1690
1400
|
}
|
|
1691
1401
|
/**
|
|
1692
|
-
* Size-limit overflow flush (plan §1.3, event map 10b): the buffer crossed
|
|
1693
|
-
* ~600 KB mid-session — ship the slice as its OWN contract-valid record
|
|
1694
|
-
* (fresh id, same sessionId, index continuity ties the records together)
|
|
1695
|
-
* and keep logging. **STAGING-ONLY until BE ships `inProgress`/`flushReason`
|
|
1696
|
-
* (hard gate B2)**: outside staging (`testing !== true`) the machinery goes
|
|
1697
|
-
* dormant and the buffer falls back to eviction. Interim outcome marker is
|
|
1698
|
-
* the sanctioned `failure/interrupted` pair; the terminal record supersedes.
|
|
1699
|
-
*/
|
|
1700
|
-
function handleBufferOverflow(slice) {
|
|
1701
|
-
dispatchOverflowSlice(slice);
|
|
1702
|
-
}
|
|
1703
|
-
async function dispatchOverflowSlice(slice) {
|
|
1704
|
-
if (!active || remoteKilled || finalized || overflowDormant || slice.length === 0) return;
|
|
1705
|
-
const metadata = buildSessionMetadata();
|
|
1706
|
-
if (metadata.testing !== true) {
|
|
1707
|
-
goOverflowDormant("overflowFlush dormant reason=prod");
|
|
1708
|
-
return;
|
|
1709
|
-
}
|
|
1710
|
-
if (cryptoUnsupported) {
|
|
1711
|
-
goOverflowDormant("overflowFlush dormant reason=cryptoUnsupported");
|
|
1712
|
-
return;
|
|
1713
|
-
}
|
|
1714
|
-
const transport = safeCaptureTransport();
|
|
1715
|
-
if (transport === null) {
|
|
1716
|
-
goOverflowDormant("overflowFlush dormant reason=noTransport");
|
|
1717
|
-
return;
|
|
1718
|
-
}
|
|
1719
|
-
overflowBatchCount += 1;
|
|
1720
|
-
const record = buildDiagnosticsRecord(metadata, [{
|
|
1721
|
-
index: slice[0].index,
|
|
1722
|
-
timestampMs: getTimestamp(),
|
|
1723
|
-
level: "info",
|
|
1724
|
-
subsystem: "diagnostics",
|
|
1725
|
-
category: "other",
|
|
1726
|
-
message: `sizeLimitFlush batch=${overflowBatchCount} prevRecordId=${lastFlushRecordId ?? "none"}`
|
|
1727
|
-
}, ...slice], "failure", "interrupted");
|
|
1728
|
-
if (record === null) {
|
|
1729
|
-
goOverflowDormant("overflowFlush dormant reason=unbuildable");
|
|
1730
|
-
return;
|
|
1731
|
-
}
|
|
1732
|
-
lastFlushRecordId = record.id;
|
|
1733
|
-
const upToIndex = slice[slice.length - 1].index;
|
|
1734
|
-
overflowFlushInFlightUpTo = upToIndex;
|
|
1735
|
-
await options.upload(record, {
|
|
1736
|
-
post: transport,
|
|
1737
|
-
loadCrypto: options.loadCrypto,
|
|
1738
|
-
warn: selfHealthWarn
|
|
1739
|
-
});
|
|
1740
|
-
buffer?.markFlushed(upToIndex);
|
|
1741
|
-
overflowFlushInFlightUpTo = null;
|
|
1742
|
-
snapshotDirty = true;
|
|
1743
|
-
trueSightLog("info", "diagnostics", "other", `sizeLimitFlush dispatched batch=${overflowBatchCount} recordId=${record.id} entries=${slice.length}`);
|
|
1744
|
-
}
|
|
1745
|
-
/** B2 fallback: machinery dormant, eviction takes over — logged exactly once. */
|
|
1746
|
-
function goOverflowDormant(message) {
|
|
1747
|
-
if (overflowDormant) return;
|
|
1748
|
-
overflowDormant = true;
|
|
1749
|
-
trueSightLog("warning", "diagnostics", "other", message);
|
|
1750
|
-
buffer?.setOverflowMode("evict");
|
|
1751
|
-
}
|
|
1752
|
-
/**
|
|
1753
1402
|
* Debounced interrupted-snapshot rebuild (plan §1.8): triggered by module
|
|
1754
1403
|
* boundaries and the dirty-interval tick, suppressed while a capture loop is
|
|
1755
1404
|
* active (C7). Seals the CURRENT state as a `failure/interrupted` record
|
|
@@ -1768,7 +1417,6 @@ function maybeRebuildSnapshot() {
|
|
|
1768
1417
|
snapshotDirty = false;
|
|
1769
1418
|
rebuildInFlight = true;
|
|
1770
1419
|
options.loadCrypto().then((sealer) => sealer.seal(JSON.stringify(record))).then(async (envelope) => {
|
|
1771
|
-
cachedPendingEnvelope = envelope;
|
|
1772
1420
|
if (!pendingSlotRegistered) {
|
|
1773
1421
|
pendingSlotRegistered = true;
|
|
1774
1422
|
await registerPendingSlot(sessionId, { storage });
|
|
@@ -1789,22 +1437,6 @@ function maybeRebuildSnapshot() {
|
|
|
1789
1437
|
});
|
|
1790
1438
|
}
|
|
1791
1439
|
/**
|
|
1792
|
-
* Page-hide = persist only, NEVER send (locked decision): one synchronous-
|
|
1793
|
-
* effective write of the freshest pre-sealed snapshot. Building or posting
|
|
1794
|
-
* here is forbidden — a hidden tab is frequently a user who returns.
|
|
1795
|
-
*/
|
|
1796
|
-
function handlePageHide() {
|
|
1797
|
-
if (!active || remoteKilled || finalized || cachedPendingEnvelope === null || options.storage === void 0) return;
|
|
1798
|
-
const sessionId = buildSessionMetadata().sessionId;
|
|
1799
|
-
if (!sessionId) return;
|
|
1800
|
-
writePendingEnvelope(sessionId, {
|
|
1801
|
-
v: 1,
|
|
1802
|
-
persistedAt: getTimestamp(),
|
|
1803
|
-
envelope: cachedPendingEnvelope
|
|
1804
|
-
}, { storage: options.storage });
|
|
1805
|
-
trueSightLog("debug", "diagnostics", "other", "snapshot persisted on pagehide");
|
|
1806
|
-
}
|
|
1807
|
-
/**
|
|
1808
1440
|
* Next-load recovery off the first-token-observed hook (A1) — runs once per
|
|
1809
1441
|
* lifecycle, fire-and-forget, and reports the A5 loss counters as a
|
|
1810
1442
|
* self-health line when there was anything to report.
|
|
@@ -1869,19 +1501,6 @@ function selfHealthWarn(message) {
|
|
|
1869
1501
|
if (isTrueSightTesting()) console.warn(message);
|
|
1870
1502
|
trueSightLog("warning", "diagnostics", "other", message);
|
|
1871
1503
|
}
|
|
1872
|
-
/** Spread-safe subset: injected seams only, `undefined` values dropped. */
|
|
1873
|
-
function pickDefined(serviceOptions) {
|
|
1874
|
-
const picked = {};
|
|
1875
|
-
if (serviceOptions.fetchFeatures) picked.fetchFeatures = serviceOptions.fetchFeatures;
|
|
1876
|
-
if (serviceOptions.captureTransport) picked.captureTransport = serviceOptions.captureTransport;
|
|
1877
|
-
if (serviceOptions.upload) picked.upload = serviceOptions.upload;
|
|
1878
|
-
if (serviceOptions.loadCrypto) picked.loadCrypto = serviceOptions.loadCrypto;
|
|
1879
|
-
if (serviceOptions.pageLifecycle) picked.pageLifecycle = serviceOptions.pageLifecycle;
|
|
1880
|
-
if (serviceOptions.timer) picked.timer = serviceOptions.timer;
|
|
1881
|
-
if (serviceOptions.storage) picked.storage = serviceOptions.storage;
|
|
1882
|
-
if (serviceOptions.getEnvironmentSnapshot) picked.getEnvironmentSnapshot = serviceOptions.getEnvironmentSnapshot;
|
|
1883
|
-
return picked;
|
|
1884
|
-
}
|
|
1885
1504
|
/** ` index=i total=n` suffix when the flow event carries module positioning. */
|
|
1886
1505
|
function modulePosition(payload) {
|
|
1887
1506
|
if (typeof payload !== "object" || payload === null) return "";
|
|
@@ -1889,4 +1508,4 @@ function modulePosition(payload) {
|
|
|
1889
1508
|
return `${typeof moduleIndex === "number" ? ` index=${moduleIndex}` : ""}${typeof totalModules === "number" ? ` total=${totalModules}` : ""}`;
|
|
1890
1509
|
}
|
|
1891
1510
|
//#endregion
|
|
1892
|
-
export {
|
|
1511
|
+
export { DEFAULT_WASM_VERSION as C, resolveWasmConfig as D, getBarcodeEnhanceModelUrl as E, upgradeToWasmHttpClient as S, buildWasmConfigFromBasePath as T, noteTestingSignals as _, notifyTrueSightManagerStopped as a, installFreshHttpClient as b, trueSightHintTransition as c, fetchFeatureConfig as d, isFeatureEnabled as f, noteSessionCreated as g, noteEnvironment as h, notifyTrueSightFlowEvent as i, trueSightLog as l, isTrueSightTesting as m, initializeTrueSightDiagnostics as n, resetTrueSight as o, resetFeatureConfigCache as p, noteTrueSightCaptureActivity as r, startTrueSightCollection as s, finalizeTrueSight as t, categoryForEndpoint as u, noteTokenActivated as v, buildDefaultWasmConfig as w, resetHttpClientState as x, getStoredHttpConfig as y };
|