@dynamic-labs/react-native-extension 4.83.2-alpha.0 → 4.84.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/index.cjs +402 -184
- package/index.js +403 -185
- package/package.json +6 -6
- package/src/components/WebView/EmbeddedWebView/embeddedWebViewPhaseTimers/embeddedWebViewPhaseTimers.d.ts +37 -23
- package/src/components/WebView/successLog/emitSuccessLog.d.ts +35 -0
- package/src/components/WebView/successLog/index.d.ts +3 -0
- package/src/components/WebView/successLog/successLogCooldown.d.ts +39 -0
- package/src/components/WebView/useWebViewPhaseTimers/useWebViewPhaseTimers.d.ts +20 -19
- package/src/components/WebView/useWebViewSuccessLog/index.d.ts +1 -0
- package/src/components/WebView/useWebViewSuccessLog/useWebViewSuccessLog.d.ts +28 -0
- package/src/components/WebView/webViewPhaseTimerCore/index.d.ts +2 -0
- package/src/components/WebView/webViewPhaseTimerCore/webViewPhaseTimerCore.d.ts +123 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamic-labs/react-native-extension",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.84.0",
|
|
4
4
|
"main": "./index.cjs",
|
|
5
5
|
"module": "./index.js",
|
|
6
6
|
"types": "./src/index.d.ts",
|
|
@@ -18,11 +18,11 @@
|
|
|
18
18
|
"@turnkey/react-native-passkey-stamper": "1.2.7",
|
|
19
19
|
"@react-native-documents/picker": "^11.0.0",
|
|
20
20
|
"react-native-fs": ">=2.20.0",
|
|
21
|
-
"@dynamic-labs/assert-package-version": "4.
|
|
22
|
-
"@dynamic-labs/client": "4.
|
|
23
|
-
"@dynamic-labs/logger": "4.
|
|
24
|
-
"@dynamic-labs/message-transport": "4.
|
|
25
|
-
"@dynamic-labs/webview-messages": "4.
|
|
21
|
+
"@dynamic-labs/assert-package-version": "4.84.0",
|
|
22
|
+
"@dynamic-labs/client": "4.84.0",
|
|
23
|
+
"@dynamic-labs/logger": "4.84.0",
|
|
24
|
+
"@dynamic-labs/message-transport": "4.84.0",
|
|
25
|
+
"@dynamic-labs/webview-messages": "4.84.0"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
28
|
"react": ">=18.0.0 <20.0.0",
|
|
@@ -1,24 +1,31 @@
|
|
|
1
1
|
import { Core } from '@dynamic-labs/client';
|
|
2
2
|
import { WebViewFailedToLoadErrorMeta, WebViewFailedToLoadErrorPhase } from '../../../../errors/WebViewFailedToLoadError';
|
|
3
|
+
import { WebViewLoadSuccessMeta, WebViewPhaseEvent } from '../../webViewPhaseTimerCore';
|
|
3
4
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* `os_kill` increment cumulative counters that persist across reloads.
|
|
5
|
+
* Path-agnostic success-log meta. Re-exported here for callsite
|
|
6
|
+
* ergonomics so `setupEmbeddedWebView` doesn't need to reach into
|
|
7
|
+
* `webViewPhaseTimerCore` directly.
|
|
8
8
|
*/
|
|
9
|
-
export type
|
|
9
|
+
export type EmbeddedWebViewLoadSuccessMeta = WebViewLoadSuccessMeta;
|
|
10
|
+
/**
|
|
11
|
+
* Re-exported for callsite ergonomics: lets `setupEmbeddedWebView` import
|
|
12
|
+
* a single `EmbeddedWebViewPhaseEvent` type rather than reach into
|
|
13
|
+
* `webViewPhaseTimerCore` directly.
|
|
14
|
+
*/
|
|
15
|
+
export type EmbeddedWebViewPhaseEvent = WebViewPhaseEvent;
|
|
10
16
|
type EmbeddedWebViewPhaseTimersProps = {
|
|
11
17
|
core: Core;
|
|
12
|
-
webViewUrl: URL;
|
|
13
18
|
loadingTimeoutMs: number;
|
|
14
19
|
recoveryTimeoutMs: number;
|
|
20
|
+
webViewUrl: URL;
|
|
15
21
|
};
|
|
16
22
|
export type EmbeddedWebViewPhaseTimers = {
|
|
17
23
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
24
|
+
* Detach from the message transport. Call this on teardown so the
|
|
25
|
+
* embedded webview controller can be re-created without leaking
|
|
26
|
+
* subscriptions.
|
|
20
27
|
*/
|
|
21
|
-
|
|
28
|
+
dispose: () => void;
|
|
22
29
|
/**
|
|
23
30
|
* Build the structured meta to attach to
|
|
24
31
|
* {@link WebViewFailedToLoadError}. The `phase` argument reflects the
|
|
@@ -29,24 +36,31 @@ export type EmbeddedWebViewPhaseTimers = {
|
|
|
29
36
|
phase: WebViewFailedToLoadErrorPhase;
|
|
30
37
|
}) => WebViewFailedToLoadErrorMeta;
|
|
31
38
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
39
|
+
* Build the structured meta to attach to the `webview.load_succeeded`
|
|
40
|
+
* instrumentation log. Same timing fields as {@link getMeta} but without
|
|
41
|
+
* the failure-specific `phase` discriminator.
|
|
35
42
|
*/
|
|
36
|
-
|
|
43
|
+
getSuccessMeta: () => EmbeddedWebViewLoadSuccessMeta;
|
|
44
|
+
/**
|
|
45
|
+
* Record a per-attempt lifecycle event. See {@link WebViewPhaseEvent}
|
|
46
|
+
* for the semantics of each event.
|
|
47
|
+
*/
|
|
48
|
+
recordEvent: (event: EmbeddedWebViewPhaseEvent) => void;
|
|
37
49
|
};
|
|
38
50
|
/**
|
|
39
51
|
* Non-React equivalent of `useWebViewPhaseTimers` for the embedded native
|
|
40
|
-
* webview path. The embedded path is a singleton wired by
|
|
41
|
-
* (not a React component), so we expose the same
|
|
42
|
-
* plain factory.
|
|
52
|
+
* webview path. The embedded path is a singleton wired by
|
|
53
|
+
* `setupEmbeddedWebView` (not a React component), so we expose the same
|
|
54
|
+
* phase-timing surface as a plain factory.
|
|
55
|
+
*
|
|
56
|
+
* Both this factory and the hook delegate the actual state machine to
|
|
57
|
+
* {@link createWebViewPhaseTimerCore}; the only path-specific bits are:
|
|
43
58
|
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* is small enough that keeping them separate stays cleaner.
|
|
59
|
+
* - `hadClearState` is always `false` (embedded path has no clear-state
|
|
60
|
+
* recovery model — that's exclusive to the React `<WebView>` path's
|
|
61
|
+
* loading-timeout recovery flow)
|
|
62
|
+
* - `retryCount` is always `0` (embedded path has no retry counter URL
|
|
63
|
+
* query param either)
|
|
50
64
|
*/
|
|
51
|
-
export declare const createEmbeddedWebViewPhaseTimers: ({ core,
|
|
65
|
+
export declare const createEmbeddedWebViewPhaseTimers: ({ core, loadingTimeoutMs, recoveryTimeoutMs, webViewUrl, }: EmbeddedWebViewPhaseTimersProps) => EmbeddedWebViewPhaseTimers;
|
|
52
66
|
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Core } from '@dynamic-labs/client';
|
|
2
|
+
import { SuccessLogCooldown } from './successLogCooldown';
|
|
3
|
+
export declare const SUCCESS_LOG_KEY = "webview.load_succeeded";
|
|
4
|
+
type SuccessLogMeta = Record<string, unknown>;
|
|
5
|
+
type EmitSuccessLogArgs<Meta extends SuccessLogMeta> = {
|
|
6
|
+
/**
|
|
7
|
+
* Device-local cooldown gate. If `shouldEmit` returns false the log
|
|
8
|
+
* is suppressed; on emit, the cooldown is recorded immediately so a
|
|
9
|
+
* crash between emit and `recordEmitted` doesn't replay the log.
|
|
10
|
+
*/
|
|
11
|
+
cooldown: SuccessLogCooldown;
|
|
12
|
+
core: Core;
|
|
13
|
+
/**
|
|
14
|
+
* Late-bound meta builder. We call this only after the cooldown
|
|
15
|
+
* passes so paths that maintain expensive snapshots don't pay the
|
|
16
|
+
* cost when they're going to be suppressed.
|
|
17
|
+
*/
|
|
18
|
+
getMeta: () => Meta;
|
|
19
|
+
/**
|
|
20
|
+
* Short identifier describing the path. Appears in the log message
|
|
21
|
+
* (`<name> loaded successfully`) so the two streams are
|
|
22
|
+
* distinguishable in Datadog without a per-path `key` field.
|
|
23
|
+
*/
|
|
24
|
+
name: string;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Shared emission pattern for the `webview.load_succeeded`
|
|
28
|
+
* instrumentation log. Both the RN `<WebView>` and the embedded
|
|
29
|
+
* WebView fire the same event with the same payload shape after
|
|
30
|
+
* checking the same cooldown gate — this helper centralises that
|
|
31
|
+
* sequence so the two call sites stay aligned and any future field we
|
|
32
|
+
* add to the success log lands in both places automatically.
|
|
33
|
+
*/
|
|
34
|
+
export declare const emitSuccessLog: <Meta extends SuccessLogMeta>({ cooldown, core, getMeta, name, }: EmitSuccessLogArgs<Meta>) => Promise<void>;
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export declare const SUCCESS_LOG_COOLDOWN_MS: number;
|
|
2
|
+
export type SuccessLogCooldown = {
|
|
3
|
+
recordEmitted: (now?: number) => Promise<void>;
|
|
4
|
+
shouldEmit: (now?: number) => Promise<boolean>;
|
|
5
|
+
};
|
|
6
|
+
type CreateSuccessLogCooldownArgs = {
|
|
7
|
+
/**
|
|
8
|
+
* Short identifier used only in warning log messages so storage
|
|
9
|
+
* failures are distinguishable in Datadog (e.g. `'webview'` vs
|
|
10
|
+
* `'embedded webview'`).
|
|
11
|
+
*/
|
|
12
|
+
name: string;
|
|
13
|
+
/**
|
|
14
|
+
* Dedicated `expo-secure-store` key under which the timestamp of the
|
|
15
|
+
* last successful emit is persisted. Each call site MUST use a
|
|
16
|
+
* distinct key so the two log streams cooldown independently.
|
|
17
|
+
*/
|
|
18
|
+
storageKey: string;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Create a device-local cooldown gate for a `webview.load_succeeded`
|
|
22
|
+
* instrumentation log.
|
|
23
|
+
*
|
|
24
|
+
* Both `<WebView>` (RN bridge) and `<EmbeddedWebView>` (native bridge)
|
|
25
|
+
* emit the same success log; each instantiates its own cooldown with a
|
|
26
|
+
* dedicated storage key so emitting one log doesn't starve the other
|
|
27
|
+
* for an app that mounts both.
|
|
28
|
+
*
|
|
29
|
+
* - `shouldEmit` returns `true` when the cooldown has elapsed (or no
|
|
30
|
+
* timestamp has ever been stored) and `false` while inside the
|
|
31
|
+
* window. If secure-store throws on read we default to emitting —
|
|
32
|
+
* losing a diagnostic log is worse than the rare duplicate.
|
|
33
|
+
* - `recordEmitted` persists the current timestamp so subsequent calls
|
|
34
|
+
* within the window are suppressed. Write failures are swallowed
|
|
35
|
+
* (logged as a warning) so they don't break the host wrapper —
|
|
36
|
+
* worst case the next emit also goes through.
|
|
37
|
+
*/
|
|
38
|
+
export declare const createSuccessLogCooldown: ({ name, storageKey, }: CreateSuccessLogCooldownArgs) => SuccessLogCooldown;
|
|
39
|
+
export {};
|
|
@@ -1,28 +1,14 @@
|
|
|
1
1
|
import { Core } from '@dynamic-labs/client';
|
|
2
2
|
import { WebViewFailedToLoadErrorMeta, WebViewFailedToLoadErrorPhase } from '../../../errors/WebViewFailedToLoadError';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
*
|
|
6
|
-
* `requestChannel.request('manifest')` sends a `MessageTransportData` whose
|
|
7
|
-
* `type` is the literal request name. The host replies with `manifest__ack`,
|
|
8
|
-
* which we ignore: receiving the request is sufficient evidence that the
|
|
9
|
-
* webview JS bundle is alive and the message bridge works.
|
|
10
|
-
*/
|
|
11
|
-
type WebViewPhaseEvent = 'load_start' | 'load' | 'load_end' | 'native_error' | 'os_kill';
|
|
3
|
+
import { WebViewLoadSuccessMeta, WebViewPhaseEvent } from '../webViewPhaseTimerCore';
|
|
4
|
+
export type { WebViewLoadSuccessMeta };
|
|
12
5
|
type UseWebViewPhaseTimersProps = {
|
|
13
6
|
core: Core;
|
|
14
|
-
webViewUrl: URL;
|
|
15
7
|
loadingTimeout: number;
|
|
16
8
|
recoveryTimeout: number;
|
|
9
|
+
webViewUrl: URL;
|
|
17
10
|
};
|
|
18
11
|
export type WebViewPhaseTimers = {
|
|
19
|
-
/**
|
|
20
|
-
* Record a per-attempt lifecycle event. `load_start` resets the
|
|
21
|
-
* per-attempt state (so the timings reflect the current reload), while
|
|
22
|
-
* `native_error` and `os_kill` increment cumulative counters that
|
|
23
|
-
* persist across reloads.
|
|
24
|
-
*/
|
|
25
|
-
recordEvent: (event: WebViewPhaseEvent) => void;
|
|
26
12
|
/**
|
|
27
13
|
* Build the structured meta to attach to {@link WebViewFailedToLoadError}.
|
|
28
14
|
* Pass `phase` explicitly from the callsite (the phase reflects the
|
|
@@ -31,6 +17,17 @@ export type WebViewPhaseTimers = {
|
|
|
31
17
|
getMeta: (args: {
|
|
32
18
|
phase: WebViewFailedToLoadErrorPhase;
|
|
33
19
|
}) => WebViewFailedToLoadErrorMeta;
|
|
20
|
+
/**
|
|
21
|
+
* Build the structured meta to attach to the `webview.load_succeeded`
|
|
22
|
+
* instrumentation log. Same timing fields as {@link getMeta} but without
|
|
23
|
+
* the failure-specific `phase` discriminator.
|
|
24
|
+
*/
|
|
25
|
+
getSuccessMeta: () => WebViewLoadSuccessMeta;
|
|
26
|
+
/**
|
|
27
|
+
* Record a per-attempt lifecycle event. See {@link WebViewPhaseEvent}
|
|
28
|
+
* for the semantics of each event.
|
|
29
|
+
*/
|
|
30
|
+
recordEvent: (event: WebViewPhaseEvent) => void;
|
|
34
31
|
};
|
|
35
32
|
/**
|
|
36
33
|
* Tracks how long each step of the WebView load took, so when we raise
|
|
@@ -40,6 +37,10 @@ export type WebViewPhaseTimers = {
|
|
|
40
37
|
* timings (`webview.time_to_load_manifest`, `webview.time_to_sdk_ready`)
|
|
41
38
|
* still come from the webview itself once it boots, but those don't help
|
|
42
39
|
* when the webview never boots in the first place.
|
|
40
|
+
*
|
|
41
|
+
* The actual state machine lives in {@link createWebViewPhaseTimerCore},
|
|
42
|
+
* which is also reused by the embedded native WebView path. This hook
|
|
43
|
+
* only layers the React-specific bits (ref-based core lifetime tied to
|
|
44
|
+
* `useEffect`, URL-derived `hadClearState` / `retryCount`).
|
|
43
45
|
*/
|
|
44
|
-
export declare const useWebViewPhaseTimers: ({ core,
|
|
45
|
-
export {};
|
|
46
|
+
export declare const useWebViewPhaseTimers: ({ core, loadingTimeout, recoveryTimeout, webViewUrl, }: UseWebViewPhaseTimersProps) => WebViewPhaseTimers;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useWebViewSuccessLog } from './useWebViewSuccessLog';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Core } from '@dynamic-labs/client';
|
|
2
|
+
import { WebViewLoadSuccessMeta } from '../useWebViewPhaseTimers/useWebViewPhaseTimers';
|
|
3
|
+
type UseWebViewSuccessLogProps = {
|
|
4
|
+
core: Core;
|
|
5
|
+
getSuccessMeta: () => WebViewLoadSuccessMeta;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Emit a `webview.load_succeeded` instrumentation log the first time
|
|
9
|
+
* the SDK signals it's ready, gated by a device-local 1h cooldown so a
|
|
10
|
+
* customer with many WebView mounts (or many app launches) doesn't spam
|
|
11
|
+
* the logs pipeline.
|
|
12
|
+
*
|
|
13
|
+
* The error path is unaffected: failures keep going through
|
|
14
|
+
* `logger.error(WebViewFailedToLoadError, meta)` with no cooldown.
|
|
15
|
+
*
|
|
16
|
+
* The hook intentionally fires only once per mount (`hasEmittedRef`):
|
|
17
|
+
* after a successful boot we don't expect another `sdkHasLoaded` for
|
|
18
|
+
* the same WebView lifetime, and emitting twice for the same load would
|
|
19
|
+
* be misleading.
|
|
20
|
+
*
|
|
21
|
+
* Cooldown gating + log emission are delegated to the shared
|
|
22
|
+
* `successLog` helpers so this hook and the embedded native WebView
|
|
23
|
+
* path stay in lockstep on payload shape and storage semantics; the
|
|
24
|
+
* dedicated storage key here keeps the RN-path cooldown independent
|
|
25
|
+
* from the embedded path's.
|
|
26
|
+
*/
|
|
27
|
+
export declare const useWebViewSuccessLog: ({ core, getSuccessMeta, }: UseWebViewSuccessLogProps) => void;
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { buildSuccessMeta, computePhaseDurations, createWebViewPhaseTimerCore, } from './webViewPhaseTimerCore';
|
|
2
|
+
export type { CumulativeCounters, PerAttemptTimings, PhaseDurations, WebViewLoadSuccessMeta, WebViewPhaseEvent, WebViewPhaseTimerCore, } from './webViewPhaseTimerCore';
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { Core } from '@dynamic-labs/client';
|
|
2
|
+
/**
|
|
3
|
+
* Per-attempt lifecycle event recorded by the phase-timer core.
|
|
4
|
+
*
|
|
5
|
+
* - `load_start` — native bridge fired `onLoadStart` (resets per-attempt
|
|
6
|
+
* state so timings reflect the current attempt)
|
|
7
|
+
* - `load` — native bridge fired `onLoad` (HTML byte stream received)
|
|
8
|
+
* - `load_end` — native bridge fired `onLoadEnd` (page finished
|
|
9
|
+
* rendering)
|
|
10
|
+
* - `native_error` — native bridge raised an `onLoadError`; increments a
|
|
11
|
+
* counter that persists across reloads
|
|
12
|
+
* - `os_kill` — host detected an OS-level WebView kill (e.g. backgrounded
|
|
13
|
+
* for too long); also a cumulative counter
|
|
14
|
+
*/
|
|
15
|
+
export type WebViewPhaseEvent = 'load' | 'load_end' | 'load_start' | 'native_error' | 'os_kill';
|
|
16
|
+
export type PerAttemptTimings = {
|
|
17
|
+
htmlLoadStartedAt: number | null;
|
|
18
|
+
htmlLoadedAt: number | null;
|
|
19
|
+
manifestReceivedAt: number | null;
|
|
20
|
+
onLoadEndAt: number | null;
|
|
21
|
+
sdkReadyAt: number | null;
|
|
22
|
+
};
|
|
23
|
+
export type CumulativeCounters = {
|
|
24
|
+
nativeErrorCount: number;
|
|
25
|
+
osKillCount: number;
|
|
26
|
+
};
|
|
27
|
+
export type PhaseDurations = {
|
|
28
|
+
htmlLoadMs: number | null;
|
|
29
|
+
manifestReceivedMs: number | null;
|
|
30
|
+
onLoadToOnLoadEndMs: number | null;
|
|
31
|
+
sdkReadyMs: number | null;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Derive cross-phase durations from raw timestamps. The four durations
|
|
35
|
+
* are what end up in the failure / success log meta:
|
|
36
|
+
*
|
|
37
|
+
* - `htmlLoadMs` — `onLoadStart` to `onLoad`; native HTML fetch
|
|
38
|
+
* - `onLoadToOnLoadEndMs` — `onLoad` to `onLoadEnd`; native render/parse
|
|
39
|
+
* - `manifestReceivedMs` — `onLoadEnd` to first `manifest` request from
|
|
40
|
+
* the webview JS; "JS bundle is alive" signal
|
|
41
|
+
* - `sdkReadyMs` — `onLoadEnd` to first `sdkHasLoaded` event from the
|
|
42
|
+
* webview JS; "SDK fully bootstrapped" signal
|
|
43
|
+
*/
|
|
44
|
+
export declare const computePhaseDurations: (timings: PerAttemptTimings) => PhaseDurations;
|
|
45
|
+
export type WebViewPhaseTimerCore = {
|
|
46
|
+
/** Detach the message-transport subscription. */
|
|
47
|
+
dispose: () => void;
|
|
48
|
+
getCounters: () => CumulativeCounters;
|
|
49
|
+
getTimings: () => PerAttemptTimings;
|
|
50
|
+
recordEvent: (event: WebViewPhaseEvent) => void;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Path-agnostic shape of the `webview.load_succeeded` instrumentation
|
|
54
|
+
* log meta. Both the React `<WebView>` and the embedded native WebView
|
|
55
|
+
* paths emit this exact surface so the two log streams can be queried
|
|
56
|
+
* together in Datadog without per-path field translation.
|
|
57
|
+
*
|
|
58
|
+
* The failure meta (`WebViewFailedToLoadErrorMeta`) is this shape plus
|
|
59
|
+
* a `phase` discriminator — see `buildSuccessMeta` callers.
|
|
60
|
+
*/
|
|
61
|
+
export type WebViewLoadSuccessMeta = {
|
|
62
|
+
hadClearState: boolean;
|
|
63
|
+
htmlLoadMs: number | null;
|
|
64
|
+
loadingTimeoutMs: number;
|
|
65
|
+
manifestReceivedMs: number | null;
|
|
66
|
+
nativeErrorCount: number;
|
|
67
|
+
onLoadToOnLoadEndMs: number | null;
|
|
68
|
+
osKillCount: number;
|
|
69
|
+
recoveryTimeoutMs: number;
|
|
70
|
+
retryCount: number;
|
|
71
|
+
sdkReadyMs: number | null;
|
|
72
|
+
webviewUrl: string;
|
|
73
|
+
};
|
|
74
|
+
type BuildSuccessMetaArgs = {
|
|
75
|
+
/**
|
|
76
|
+
* Snapshot source for raw timings + cumulative counters. Typically a
|
|
77
|
+
* live {@link WebViewPhaseTimerCore} instance, but the type only
|
|
78
|
+
* requires `getTimings` / `getCounters` so callers can fall back to
|
|
79
|
+
* empty values if the core hasn't been created yet.
|
|
80
|
+
*/
|
|
81
|
+
core: Pick<WebViewPhaseTimerCore, 'getCounters' | 'getTimings'>;
|
|
82
|
+
/**
|
|
83
|
+
* Whether the current attempt was kicked off by the React
|
|
84
|
+
* `<WebView>`'s clear-state recovery flow. Embedded path is always
|
|
85
|
+
* `false`.
|
|
86
|
+
*/
|
|
87
|
+
hadClearState: boolean;
|
|
88
|
+
loadingTimeoutMs: number;
|
|
89
|
+
recoveryTimeoutMs: number;
|
|
90
|
+
/**
|
|
91
|
+
* Number of times the React `<WebView>` re-mounted via the `?retry=`
|
|
92
|
+
* URL query param. Embedded path is always `0`.
|
|
93
|
+
*/
|
|
94
|
+
retryCount: number;
|
|
95
|
+
webviewUrl: string;
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Build the success-shape meta from a {@link WebViewPhaseTimerCore}
|
|
99
|
+
* snapshot plus the path-specific fields. Both call sites call this
|
|
100
|
+
* with their own context (RN reads `hadClearState` / `retryCount` from
|
|
101
|
+
* the URL; embedded passes constants) so the success-log payload stays
|
|
102
|
+
* identical across the two paths.
|
|
103
|
+
*/
|
|
104
|
+
export declare const buildSuccessMeta: ({ core, hadClearState, loadingTimeoutMs, recoveryTimeoutMs, retryCount, webviewUrl, }: BuildSuccessMetaArgs) => WebViewLoadSuccessMeta;
|
|
105
|
+
/**
|
|
106
|
+
* Shared state machine driving WebView load-phase instrumentation.
|
|
107
|
+
*
|
|
108
|
+
* Both the React `<WebView>` (RN bridge) and the native embedded WebView
|
|
109
|
+
* (native bridge) feed lifecycle events into this core and produce
|
|
110
|
+
* matching meta from the same timings + counters. Each path layers its
|
|
111
|
+
* own path-specific fields (`hadClearState`, `retryCount`, etc.) on top
|
|
112
|
+
* of the raw state this core exposes via `getTimings()` / `getCounters()`.
|
|
113
|
+
*
|
|
114
|
+
* The core owns the `core.messageTransport` subscription that captures
|
|
115
|
+
* the two webview-originated signals bracketing SDK bootstrap
|
|
116
|
+
* (`manifest` once the JS bundle is alive; `sdkHasLoadedEventName`
|
|
117
|
+
* once the SDK is fully ready). Native bridge lifecycle events come in
|
|
118
|
+
* via `recordEvent` instead.
|
|
119
|
+
*/
|
|
120
|
+
export declare const createWebViewPhaseTimerCore: ({ core, }: {
|
|
121
|
+
core: Core;
|
|
122
|
+
}) => WebViewPhaseTimerCore;
|
|
123
|
+
export {};
|