@dynamic-labs/react-native-extension 4.92.3 → 4.93.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.
Files changed (40) hide show
  1. package/android/EmbeddedWebViewController.kt +19 -2
  2. package/android/dynamic/embeddedwebview/EmbeddedWebViewController.kt +19 -2
  3. package/android/embeddedwebview/EmbeddedWebViewController.kt +19 -2
  4. package/android/java/xyz/dynamic/embeddedwebview/EmbeddedWebViewController.kt +19 -2
  5. package/android/main/java/xyz/dynamic/embeddedwebview/EmbeddedWebViewController.kt +19 -2
  6. package/android/src/main/java/xyz/dynamic/embeddedwebview/EmbeddedWebViewController.kt +19 -2
  7. package/android/xyz/dynamic/embeddedwebview/EmbeddedWebViewController.kt +19 -2
  8. package/index.cjs +252 -796
  9. package/index.js +251 -797
  10. package/ios/EmbeddedWebViewController.swift +7 -6
  11. package/package.json +6 -6
  12. package/src/ReactNativeExtension/ReactNativeExtension.d.ts +11 -2
  13. package/src/components/WebView/EmbeddedWebView/EmbeddedWebView.d.ts +6 -19
  14. package/src/components/WebView/WebView.d.ts +17 -6
  15. package/src/errors/WebViewFailedToLoadError.d.ts +1 -86
  16. package/src/components/WebView/EmbeddedWebView/embeddedWebViewPhaseTimers/embeddedWebViewPhaseTimers.d.ts +0 -66
  17. package/src/components/WebView/EmbeddedWebView/embeddedWebViewPhaseTimers/index.d.ts +0 -1
  18. package/src/components/WebView/constants.d.ts +0 -3
  19. package/src/components/WebView/successLog/emitSuccessLog.d.ts +0 -35
  20. package/src/components/WebView/successLog/index.d.ts +0 -3
  21. package/src/components/WebView/useWebViewLoadingTimeout/index.d.ts +0 -1
  22. package/src/components/WebView/useWebViewLoadingTimeout/useWebViewLoadingTimeout.d.ts +0 -4
  23. package/src/components/WebView/useWebViewPhaseTimers/index.d.ts +0 -1
  24. package/src/components/WebView/useWebViewPhaseTimers/useWebViewPhaseTimers.d.ts +0 -46
  25. package/src/components/WebView/useWebViewRecoveryTimeout/index.d.ts +0 -1
  26. package/src/components/WebView/useWebViewRecoveryTimeout/useWebViewRecoveryTimeout.d.ts +0 -12
  27. package/src/components/WebView/useWebViewSuccessLog/index.d.ts +0 -1
  28. package/src/components/WebView/useWebViewSuccessLog/useWebViewSuccessLog.d.ts +0 -28
  29. package/src/components/WebView/utils/assignEnvironmentIdToUrl/assignEnvironmentIdToUrl.d.ts +0 -1
  30. package/src/components/WebView/utils/assignEnvironmentIdToUrl/index.d.ts +0 -1
  31. package/src/components/WebView/utils/assignStartTimeToUrl/assignStartTimeToUrl.d.ts +0 -1
  32. package/src/components/WebView/utils/assignStartTimeToUrl/index.d.ts +0 -1
  33. package/src/components/WebView/utils/hasClearStateInUrl/hasClearStateInUrl.d.ts +0 -1
  34. package/src/components/WebView/utils/hasClearStateInUrl/index.d.ts +0 -1
  35. package/src/components/WebView/utils/increaseRetryToUrl/increaseRetryToUrl.d.ts +0 -1
  36. package/src/components/WebView/utils/increaseRetryToUrl/index.d.ts +0 -1
  37. package/src/components/WebView/utils/setClearStateToUrl/index.d.ts +0 -1
  38. package/src/components/WebView/utils/setClearStateToUrl/setClearStateToUrl.d.ts +0 -1
  39. package/src/components/WebView/webViewPhaseTimerCore/index.d.ts +0 -2
  40. package/src/components/WebView/webViewPhaseTimerCore/webViewPhaseTimerCore.d.ts +0 -123
@@ -24,7 +24,6 @@ public final class EmbeddedWebViewController: NSObject {
24
24
  private var window: UIWindow?
25
25
  private var webView: WKWebView?
26
26
  private var debuggingEnabled = false
27
- private var hasLoaded = false
28
27
  private var pendingNavigationDecisions: [String: (WKNavigationActionPolicy) -> Void] = [:]
29
28
  private var navigationTimers: [String: Timer] = [:]
30
29
  private var emitterToken: UUID?
@@ -69,10 +68,9 @@ public final class EmbeddedWebViewController: NSObject {
69
68
  return
70
69
  }
71
70
  ensureWebView()
72
- hasLoaded = true
73
71
  // Pre-approve the origin so the first `decidePolicyFor` call can skip
74
72
  // the JS round-trip. On cold boot the JS thread may be too congested to
75
- // respond within the 2 s navigation-decision timeout, silently
73
+ // respond within the navigation-decision timeout, silently
76
74
  // cancelling the load.
77
75
  preApprovedOrigin = originString(for: parsed)
78
76
  webView?.load(URLRequest(url: parsed))
@@ -133,7 +131,6 @@ public final class EmbeddedWebViewController: NSObject {
133
131
  pendingNavigationDecisions.removeAll()
134
132
  navigationTimers.values.forEach { $0.invalidate() }
135
133
  navigationTimers.removeAll()
136
- hasLoaded = false
137
134
  preApprovedOrigin = nil
138
135
  }
139
136
 
@@ -349,7 +346,7 @@ extension EmbeddedWebViewController: WKNavigationDelegate {
349
346
  // Fast-path: if the URL's origin matches the pre-approved origin (set
350
347
  // by `setUrl`), allow immediately. This eliminates the cold-boot race
351
348
  // where the JS thread is too congested to respond to
352
- // `onShouldStartLoad` within the 2 s navigation-decision timeout.
349
+ // `onShouldStartLoad` within the navigation-decision timeout.
353
350
  if let approved = preApprovedOrigin,
354
351
  approved == originString(for: navigationAction.request.url) {
355
352
  preApprovedOrigin = nil
@@ -469,10 +466,14 @@ extension EmbeddedWebViewController: WKNavigationDelegate {
469
466
  "description": "WebContent process terminated",
470
467
  "isProvisional": false,
471
468
  ])
469
+ // The content process is dead — this WKWebView can never load anything
470
+ // again. Tear it down so the next `setUrl` recreates a fresh webview via
471
+ // the lazy `ensureWebView` path (mirrors Android's onRenderProcessGone).
472
+ destroy()
472
473
  }
473
474
 
474
475
  // Errors from cancelling our own navigation (e.g. when the JS allowlist
475
- // returns false or the 2 s decision timeout fires) are not real load
476
+ // returns false or the navigation-decision timeout fires) are not real load
476
477
  // failures and should not be instrumented as such.
477
478
  private func isCancellationError(_ error: NSError) -> Bool {
478
479
  if error.domain == NSURLErrorDomain && error.code == NSURLErrorCancelled {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dynamic-labs/react-native-extension",
3
- "version": "4.92.3",
3
+ "version": "4.93.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.92.3",
22
- "@dynamic-labs/client": "4.92.3",
23
- "@dynamic-labs/logger": "4.92.3",
24
- "@dynamic-labs/message-transport": "4.92.3",
25
- "@dynamic-labs/webview-messages": "4.92.3"
21
+ "@dynamic-labs/assert-package-version": "4.93.0",
22
+ "@dynamic-labs/client": "4.93.0",
23
+ "@dynamic-labs/logger": "4.93.0",
24
+ "@dynamic-labs/message-transport": "4.93.0",
25
+ "@dynamic-labs/webview-messages": "4.93.0"
26
26
  },
27
27
  "peerDependencies": {
28
28
  "react": ">=18.0.0 <20.0.0",
@@ -1,5 +1,5 @@
1
1
  import { FC } from 'react';
2
- import { Extension } from '@dynamic-labs/client';
2
+ import { Extension, WebViewLoadOptions } from '@dynamic-labs/client';
3
3
  import { WebViewProps } from '../components/WebView';
4
4
  export type ReactNativeExtensionProps = {
5
5
  /**
@@ -46,10 +46,19 @@ export type ReactNativeExtensionProps = {
46
46
  * Defaults to false.
47
47
  */
48
48
  embeddedWebView?: boolean;
49
+ /**
50
+ * Customer-tunable budgets of the webview load engine (how long each
51
+ * load attempt may take and how long the SDK inside the webview may take
52
+ * to become ready). Applies to both webview paths. When a budget is
53
+ * exhausted on the final attempt, the SDK raises
54
+ * `WebViewFailedToLoadError`. See `WebViewLoadOptions` for the per-field
55
+ * documentation and defaults. Only tune this for pathological networks.
56
+ */
57
+ webviewLoad?: WebViewLoadOptions;
49
58
  };
50
59
  export type IReactNativeExtension = {
51
60
  reactNative: {
52
61
  WebView: FC<WebViewProps> | (() => null);
53
62
  };
54
63
  };
55
- export declare const ReactNativeExtension: ({ webviewUrl, webviewDebuggingEnabled, appOrigin, embeddedWebView, }?: ReactNativeExtensionProps) => Extension<IReactNativeExtension>;
64
+ export declare const ReactNativeExtension: ({ webviewUrl, webviewDebuggingEnabled, appOrigin, embeddedWebView, webviewLoad, }?: ReactNativeExtensionProps) => Extension<IReactNativeExtension>;
@@ -1,26 +1,13 @@
1
- import { Core } from '@dynamic-labs/client';
1
+ import { Core, WebViewLoadOptions } from '@dynamic-labs/client';
2
2
  export type SetupEmbeddedWebViewArgs = {
3
3
  webviewUrl: string;
4
4
  core: Core;
5
5
  webviewDebuggingEnabled?: boolean;
6
6
  /**
7
- * Max time (ms) between the native webview reporting it has started a
8
- * navigation (`onLoadStart`) and reporting that the response committed
9
- * (`onLoad`). If this elapses, the SDK raises
10
- * {@link WebViewFailedToLoadError} with `phase: 'html_load'` so the page
11
- * can no longer hang silently waiting for bytes that never arrive.
12
- *
13
- * Defaults to 20s, matching the RN `<WebView>` path.
7
+ * Customer-tunable budgets of the webview load engine. Forwarded
8
+ * verbatim to `createWebViewLoadController`, which owns the defaults.
9
+ * See `WebViewLoadOptions` for the per-field documentation.
14
10
  */
15
- loadingTimeoutMs?: number;
16
- /**
17
- * Max time (ms) between the native webview reporting it has finished
18
- * loading (`onLoadEnd`) and the SDK signalling it has finished booting
19
- * (`sdkHasLoadedEventName`). If this elapses, the SDK raises
20
- * {@link WebViewFailedToLoadError} with `phase: 'sdk_bootstrap'`.
21
- *
22
- * Defaults to 20s, matching the RN `<WebView>` path.
23
- */
24
- recoveryTimeoutMs?: number;
11
+ webviewLoad?: WebViewLoadOptions;
25
12
  };
26
- export declare const setupEmbeddedWebView: ({ webviewUrl, core, webviewDebuggingEnabled, loadingTimeoutMs, recoveryTimeoutMs, }: SetupEmbeddedWebViewArgs) => (() => void);
13
+ export declare const setupEmbeddedWebView: ({ webviewUrl, core, webviewDebuggingEnabled, webviewLoad, }: SetupEmbeddedWebViewArgs) => (() => void);
@@ -1,18 +1,22 @@
1
1
  import { FC } from 'react';
2
- import { Core } from '@dynamic-labs/client';
2
+ import { Core, WebViewLoadOptions } from '@dynamic-labs/client';
3
3
  export type WebViewProps = {
4
4
  /**
5
- * Disable the webview recovery
5
+ * @deprecated No-op, accepted only for backwards compatibility. Webview
6
+ * load recovery is owned by the shared webview load controller (bounded
7
+ * retries with backoff) and is always on — it can no longer be disabled.
6
8
  */
7
9
  disableRecovery?: boolean;
8
10
  /**
9
- * The timeout between the page loaded event and the SDK
10
- * has loaded event
11
+ * @deprecated Configure `webviewLoad.sdkReadyTimeoutMs` on
12
+ * `ReactNativeExtension` instead. Still honored; an explicit value here
13
+ * overrides the extension setting.
11
14
  */
12
15
  recoveryTimeout?: number;
13
16
  /**
14
- * The timeout between the webview page load start event and the
15
- * page html and assets finishes loading
17
+ * @deprecated Configure `webviewLoad.pageLoadTimeoutMs` on
18
+ * `ReactNativeExtension` instead. Still honored; an explicit value here
19
+ * overrides the extension setting.
16
20
  */
17
21
  loadingTimeout?: number;
18
22
  };
@@ -20,6 +24,13 @@ type WebViewInternalProps = WebViewProps & {
20
24
  webviewUrl: string;
21
25
  core: Core;
22
26
  webviewDebuggingEnabled?: boolean;
27
+ /**
28
+ * Customer-tunable budgets of the webview load engine, as configured on
29
+ * `ReactNativeExtension`. Forwarded to `createWebViewLoadController`;
30
+ * the deprecated `loadingTimeout` / `recoveryTimeout` JSX props override
31
+ * the two timeout fields when set explicitly.
32
+ */
33
+ webviewLoad?: WebViewLoadOptions;
23
34
  };
24
35
  export declare const WebView: FC<WebViewInternalProps>;
25
36
  export declare const createWebView: (internalProps: WebViewInternalProps) => FC<WebViewProps>;
@@ -1,86 +1 @@
1
- /**
2
- * Categorical phase the WebView was in when the failure was raised.
3
- *
4
- * Use this for high-level grouping; the duration fields on
5
- * {@link WebViewFailedToLoadErrorMeta} give the granular timing data.
6
- */
7
- export type WebViewFailedToLoadErrorPhase = 'html_load' | 'sdk_bootstrap' | 'after_clear_state' | 'native_error' | 'embedded_native_error' | 'unknown';
8
- /**
9
- * Structured context attached to {@link WebViewFailedToLoadError} so the
10
- * resulting error log carries enough information to tell *which* step the
11
- * WebView was stuck in when the failure was raised, and how long each step
12
- * took.
13
- *
14
- * The setter on `InitializationModule.error` forwards this object directly
15
- * to `logger.error`, so every field below ends up as a structured field on
16
- * the same Datadog log as the error message.
17
- */
18
- export type WebViewFailedToLoadErrorMeta = {
19
- phase: WebViewFailedToLoadErrorPhase;
20
- /**
21
- * Milliseconds between RN's `onLoadStart` and `onLoad` callbacks (the
22
- * HTML + asset fetch). `null` if `onLoad` never fired.
23
- */
24
- htmlLoadMs: number | null;
25
- /**
26
- * Milliseconds between RN's `onLoad` and `onLoadEnd` callbacks. Usually
27
- * small; mostly there to flag pathological cases. `null` if `onLoadEnd`
28
- * never fired.
29
- */
30
- onLoadToOnLoadEndMs: number | null;
31
- /**
32
- * Milliseconds between `onLoadEnd` and the first `manifest` request
33
- * received from the webview-side SDK. Proxy for "the JS bundle is alive
34
- * and the message bridge works". `null` if the manifest request never
35
- * arrived.
36
- */
37
- manifestReceivedMs: number | null;
38
- /**
39
- * Milliseconds between `onLoadEnd` and the webview-side SDK signalling
40
- * it has finished initialising (via the `sdkHasLoadedEventName` store
41
- * change). `null` if the SDK never signalled it was ready.
42
- */
43
- sdkReadyMs: number | null;
44
- /**
45
- * Number of `retry` increments in the WebView URL at the time of failure
46
- * (covers OS-kill reloads, load_error reloads, and recovery reloads).
47
- */
48
- retryCount: number;
49
- /**
50
- * Whether the `clear-state` query parameter was present in the URL when
51
- * the failure was raised. `true` indicates we already retried with a
52
- * clean state and still couldn't finish loading.
53
- */
54
- hadClearState: boolean;
55
- /**
56
- * Number of times RN's `onError` fired across the lifetime of the
57
- * WebView component instance.
58
- */
59
- nativeErrorCount: number;
60
- /**
61
- * Number of times the OS killed the WebView process (via
62
- * `onContentProcessDidTerminate` on iOS or `onRenderProcessGone` on
63
- * Android) across the lifetime of the WebView component instance.
64
- */
65
- osKillCount: number;
66
- /** The configured value for `loadingTimeout` (ms). */
67
- loadingTimeoutMs: number;
68
- /** The configured value for `recoveryTimeout` (ms). */
69
- recoveryTimeoutMs: number;
70
- /** The URL the WebView was attempting to load when the failure occurred. */
71
- webviewUrl?: string;
72
- /**
73
- * Native error info, only populated when the failure originated from the
74
- * embedded native WebView path (iOS WKWebView / Android WebView), where
75
- * we get a single `onLoadError` event with these fields.
76
- */
77
- nativeErrorCode?: number;
78
- nativeErrorDescription?: string;
79
- nativeErrorDomain?: string;
80
- nativeErrorIsProvisional?: boolean;
81
- nativeErrorFailedUrl?: string;
82
- };
83
- export declare class WebViewFailedToLoadError extends Error {
84
- readonly meta?: WebViewFailedToLoadErrorMeta;
85
- constructor(meta?: WebViewFailedToLoadErrorMeta);
86
- }
1
+ export { WebViewFailedToLoadError, type WebViewFailedToLoadErrorMeta, type WebViewFailedToLoadErrorPhase, type WebViewLoadAttemptFailure, } from '@dynamic-labs/client';
@@ -1,66 +0,0 @@
1
- import { Core } from '@dynamic-labs/client';
2
- import { WebViewFailedToLoadErrorMeta, WebViewFailedToLoadErrorPhase } from '../../../../errors/WebViewFailedToLoadError';
3
- import { WebViewLoadSuccessMeta, WebViewPhaseEvent } from '../../webViewPhaseTimerCore';
4
- /**
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
- */
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;
16
- type EmbeddedWebViewPhaseTimersProps = {
17
- core: Core;
18
- loadingTimeoutMs: number;
19
- recoveryTimeoutMs: number;
20
- webViewUrl: URL;
21
- };
22
- export type EmbeddedWebViewPhaseTimers = {
23
- /**
24
- * Detach from the message transport. Call this on teardown so the
25
- * embedded webview controller can be re-created without leaking
26
- * subscriptions.
27
- */
28
- dispose: () => void;
29
- /**
30
- * Build the structured meta to attach to
31
- * {@link WebViewFailedToLoadError}. The `phase` argument reflects the
32
- * source of the failure; the duration fields come from the recorded
33
- * lifecycle events and observed message-transport activity.
34
- */
35
- getMeta: (args: {
36
- phase: WebViewFailedToLoadErrorPhase;
37
- }) => WebViewFailedToLoadErrorMeta;
38
- /**
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.
42
- */
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;
49
- };
50
- /**
51
- * Non-React equivalent of `useWebViewPhaseTimers` for the embedded native
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:
58
- *
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)
64
- */
65
- export declare const createEmbeddedWebViewPhaseTimers: ({ core, loadingTimeoutMs, recoveryTimeoutMs, webViewUrl, }: EmbeddedWebViewPhaseTimersProps) => EmbeddedWebViewPhaseTimers;
66
- export {};
@@ -1 +0,0 @@
1
- export { createEmbeddedWebViewPhaseTimers, type EmbeddedWebViewPhaseEvent, type EmbeddedWebViewPhaseTimers, } from './embeddedWebViewPhaseTimers';
@@ -1,3 +0,0 @@
1
- export declare const CLEAR_STATE_PARAM = "clear-state";
2
- export declare const ENVIRONMENT_ID_PARAM = "environmentId";
3
- export declare const WEBVIEW_START_TIME_PARAM = "webviewStartTime";
@@ -1,35 +0,0 @@
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 {};
@@ -1,3 +0,0 @@
1
- export { emitSuccessLog, SUCCESS_LOG_KEY } from './emitSuccessLog';
2
- export { createSuccessLogCooldown, SUCCESS_LOG_COOLDOWN_MS, } from './successLogCooldown';
3
- export type { SuccessLogCooldown } from './successLogCooldown';
@@ -1 +0,0 @@
1
- export { useWebViewLoadingTimeout } from './useWebViewLoadingTimeout';
@@ -1,4 +0,0 @@
1
- export declare const useWebViewLoadingTimeout: (timeout: number, onTimeout: () => void) => {
2
- onLoad: () => void;
3
- onLoadStart: () => void;
4
- };
@@ -1 +0,0 @@
1
- export { useWebViewPhaseTimers, type WebViewPhaseTimers, } from './useWebViewPhaseTimers';
@@ -1,46 +0,0 @@
1
- import { Core } from '@dynamic-labs/client';
2
- import { WebViewFailedToLoadErrorMeta, WebViewFailedToLoadErrorPhase } from '../../../errors/WebViewFailedToLoadError';
3
- import { WebViewLoadSuccessMeta, WebViewPhaseEvent } from '../webViewPhaseTimerCore';
4
- export type { WebViewLoadSuccessMeta };
5
- type UseWebViewPhaseTimersProps = {
6
- core: Core;
7
- loadingTimeout: number;
8
- recoveryTimeout: number;
9
- webViewUrl: URL;
10
- };
11
- export type WebViewPhaseTimers = {
12
- /**
13
- * Build the structured meta to attach to {@link WebViewFailedToLoadError}.
14
- * Pass `phase` explicitly from the callsite (the phase reflects the
15
- * source of the failure, not just the current timing state).
16
- */
17
- getMeta: (args: {
18
- phase: WebViewFailedToLoadErrorPhase;
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;
31
- };
32
- /**
33
- * Tracks how long each step of the WebView load took, so when we raise
34
- * `WebViewFailedToLoadError` we can attach the timings to the error log.
35
- *
36
- * The timings cover the host-side phases of the load — the webview-side
37
- * timings (`webview.time_to_load_manifest`, `webview.time_to_sdk_ready`)
38
- * still come from the webview itself once it boots, but those don't help
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`).
45
- */
46
- export declare const useWebViewPhaseTimers: ({ core, loadingTimeout, recoveryTimeout, webViewUrl, }: UseWebViewPhaseTimersProps) => WebViewPhaseTimers;
@@ -1 +0,0 @@
1
- export { useWebViewRecoveryTimeout } from './useWebViewRecoveryTimeout';
@@ -1,12 +0,0 @@
1
- import { Dispatch, SetStateAction } from 'react';
2
- import { Core } from '@dynamic-labs/client';
3
- type UseWebViewRecoveryTimeoutProps = {
4
- core: Core;
5
- webViewUrl: URL;
6
- disableRecovery: boolean;
7
- recoveryTimeout: number;
8
- setWebViewUrl: Dispatch<SetStateAction<URL>>;
9
- onFailedToLoadAfterClearState?: () => void;
10
- };
11
- export declare const useWebViewRecoveryTimeout: ({ core, webViewUrl, disableRecovery, recoveryTimeout, setWebViewUrl, onFailedToLoadAfterClearState, }: UseWebViewRecoveryTimeoutProps) => () => void;
12
- export {};
@@ -1 +0,0 @@
1
- export { useWebViewSuccessLog } from './useWebViewSuccessLog';
@@ -1,28 +0,0 @@
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 {};
@@ -1 +0,0 @@
1
- export declare const assignEnvironmentIdToUrl: (url: string, environmentId: string) => URL;
@@ -1 +0,0 @@
1
- export { assignEnvironmentIdToUrl } from './assignEnvironmentIdToUrl';
@@ -1 +0,0 @@
1
- export declare const assignStartTimeToUrl: (url: URL) => URL;
@@ -1 +0,0 @@
1
- export { assignStartTimeToUrl } from './assignStartTimeToUrl';
@@ -1 +0,0 @@
1
- export declare const hasClearStateInUrl: (webViewUrl: URL) => boolean;
@@ -1 +0,0 @@
1
- export { hasClearStateInUrl } from './hasClearStateInUrl';
@@ -1 +0,0 @@
1
- export declare const increaseRetryToUrl: (webViewUrl: URL) => URL;
@@ -1 +0,0 @@
1
- export { increaseRetryToUrl } from './increaseRetryToUrl';
@@ -1 +0,0 @@
1
- export { setClearStateToUrl } from './setClearStateToUrl';
@@ -1 +0,0 @@
1
- export declare const setClearStateToUrl: (webViewUrl: URL) => URL;
@@ -1,2 +0,0 @@
1
- export { buildSuccessMeta, computePhaseDurations, createWebViewPhaseTimerCore, } from './webViewPhaseTimerCore';
2
- export type { CumulativeCounters, PerAttemptTimings, PhaseDurations, WebViewLoadSuccessMeta, WebViewPhaseEvent, WebViewPhaseTimerCore, } from './webViewPhaseTimerCore';