@volley/vwr-loader 1.5.0 → 1.7.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/dist/cli.js +84 -24
- package/dist/cli.js.map +1 -1
- package/dist/{datadog.d.ts → vwr/src/datadog.d.ts} +7 -3
- package/dist/vwr/src/datadog.d.ts.map +1 -0
- package/dist/{datadog.js → vwr/src/datadog.js} +6 -5
- package/dist/vwr/src/datadog.js.map +1 -0
- package/dist/{envDefaults.d.ts → vwr/src/envDefaults.d.ts} +1 -0
- package/dist/vwr/src/envDefaults.d.ts.map +1 -0
- package/dist/vwr/src/envDefaults.js +67 -0
- package/dist/vwr/src/envDefaults.js.map +1 -0
- package/dist/vwr/src/iframe.d.ts +25 -0
- package/dist/vwr/src/iframe.d.ts.map +1 -0
- package/dist/vwr/src/iframe.js +82 -0
- package/dist/vwr/src/iframe.js.map +1 -0
- package/dist/vwr/src/logger.d.ts +15 -0
- package/dist/vwr/src/logger.d.ts.map +1 -0
- package/dist/{logger.js → vwr/src/logger.js} +30 -46
- package/dist/vwr/src/logger.js.map +1 -0
- package/dist/vwr/src/native/app-lifecycle/factory.d.ts +7 -0
- package/dist/vwr/src/native/app-lifecycle/factory.d.ts.map +1 -0
- package/dist/vwr/src/native/app-lifecycle/factory.js +68 -0
- package/dist/vwr/src/native/app-lifecycle/factory.js.map +1 -0
- package/dist/vwr/src/native/app-lifecycle/rpc.d.ts +15 -0
- package/dist/vwr/src/native/app-lifecycle/rpc.d.ts.map +1 -0
- package/dist/vwr/src/native/app-lifecycle/rpc.js +46 -0
- package/dist/vwr/src/native/app-lifecycle/rpc.js.map +1 -0
- package/dist/vwr/src/native/capacitor-bridge/rpc.d.ts +33 -0
- package/dist/vwr/src/native/capacitor-bridge/rpc.d.ts.map +1 -0
- package/dist/vwr/src/native/capacitor-bridge/rpc.js +129 -0
- package/dist/vwr/src/native/capacitor-bridge/rpc.js.map +1 -0
- package/dist/vwr/src/native/device-info/factory.d.ts +9 -0
- package/dist/vwr/src/native/device-info/factory.d.ts.map +1 -0
- package/dist/vwr/src/native/device-info/factory.js +28 -0
- package/dist/vwr/src/native/device-info/factory.js.map +1 -0
- package/dist/vwr/src/native/device-info/firetvCollector.d.ts +9 -0
- package/dist/vwr/src/native/device-info/firetvCollector.d.ts.map +1 -0
- package/dist/vwr/src/native/device-info/firetvCollector.js +180 -0
- package/dist/vwr/src/native/device-info/firetvCollector.js.map +1 -0
- package/dist/vwr/src/native/device-info/getDeviceId.d.ts +13 -0
- package/dist/vwr/src/native/device-info/getDeviceId.d.ts.map +1 -0
- package/dist/vwr/src/native/device-info/getDeviceId.js +137 -0
- package/dist/vwr/src/native/device-info/getDeviceId.js.map +1 -0
- package/dist/vwr/src/native/device-info/lgCollector.d.ts +8 -0
- package/dist/vwr/src/native/device-info/lgCollector.d.ts.map +1 -0
- package/dist/vwr/src/native/device-info/lgCollector.js +136 -0
- package/dist/vwr/src/native/device-info/lgCollector.js.map +1 -0
- package/dist/vwr/src/native/device-info/mobileCollector.d.ts +9 -0
- package/dist/vwr/src/native/device-info/mobileCollector.d.ts.map +1 -0
- package/dist/vwr/src/native/device-info/mobileCollector.js +47 -0
- package/dist/vwr/src/native/device-info/mobileCollector.js.map +1 -0
- package/dist/vwr/src/native/device-info/rpc.d.ts +51 -0
- package/dist/vwr/src/native/device-info/rpc.d.ts.map +1 -0
- package/dist/vwr/src/native/device-info/rpc.js +46 -0
- package/dist/vwr/src/native/device-info/rpc.js.map +1 -0
- package/dist/vwr/src/native/device-info/samsungCollector.d.ts +9 -0
- package/dist/vwr/src/native/device-info/samsungCollector.d.ts.map +1 -0
- package/dist/vwr/src/native/device-info/samsungCollector.js +86 -0
- package/dist/vwr/src/native/device-info/samsungCollector.js.map +1 -0
- package/dist/vwr/src/native/device-info/webCollector.d.ts +4 -0
- package/dist/vwr/src/native/device-info/webCollector.d.ts.map +1 -0
- package/dist/vwr/src/native/device-info/webCollector.js +56 -0
- package/dist/vwr/src/native/device-info/webCollector.js.map +1 -0
- package/dist/vwr/src/native/native-bridge/rpc.d.ts +33 -0
- package/dist/vwr/src/native/native-bridge/rpc.d.ts.map +1 -0
- package/dist/vwr/src/native/native-bridge/rpc.js +114 -0
- package/dist/vwr/src/native/native-bridge/rpc.js.map +1 -0
- package/dist/vwr/src/native/screensaver-prevention/LGLunaService.d.ts +14 -0
- package/dist/vwr/src/native/screensaver-prevention/LGLunaService.d.ts.map +1 -0
- package/dist/vwr/src/native/screensaver-prevention/LGLunaService.js +187 -0
- package/dist/vwr/src/native/screensaver-prevention/LGLunaService.js.map +1 -0
- package/dist/vwr/src/native/screensaver-prevention/rpc.d.ts +27 -0
- package/dist/vwr/src/native/screensaver-prevention/rpc.d.ts.map +1 -0
- package/dist/vwr/src/native/screensaver-prevention/rpc.js +71 -0
- package/dist/vwr/src/native/screensaver-prevention/rpc.js.map +1 -0
- package/dist/vwr/src/observability.d.ts +35 -0
- package/dist/vwr/src/observability.d.ts.map +1 -0
- package/dist/vwr/src/observability.js +68 -0
- package/dist/vwr/src/observability.js.map +1 -0
- package/dist/vwr/src/shellEnvDefaults.d.ts +15 -0
- package/dist/vwr/src/shellEnvDefaults.d.ts.map +1 -0
- package/dist/vwr/src/shellEnvDefaults.js +34 -0
- package/dist/vwr/src/shellEnvDefaults.js.map +1 -0
- package/dist/vwr/src/types.d.ts +56 -0
- package/dist/vwr/src/types.d.ts.map +1 -0
- package/dist/vwr/src/types.js +27 -0
- package/dist/vwr/src/types.js.map +1 -0
- package/dist/vwr/src/urlUtils.d.ts +17 -0
- package/dist/vwr/src/urlUtils.d.ts.map +1 -0
- package/dist/vwr/src/urlUtils.js +42 -0
- package/dist/vwr/src/urlUtils.js.map +1 -0
- package/dist/vwr/src/vwrBootstrap.d.ts +26 -0
- package/dist/vwr/src/vwrBootstrap.d.ts.map +1 -0
- package/dist/vwr/src/vwrBootstrap.js +176 -0
- package/dist/vwr/src/vwrBootstrap.js.map +1 -0
- package/dist/{vwrConfig.d.ts → vwr/src/vwrConfig.d.ts} +5 -0
- package/dist/vwr/src/vwrConfig.d.ts.map +1 -0
- package/dist/{vwrConfig.js → vwr/src/vwrConfig.js} +24 -7
- package/dist/vwr/src/vwrConfig.js.map +1 -0
- package/{src → dist/vwr-loader}/index.html +1 -1
- package/dist/vwr-loader/src/__mocks__/@datadog/browser-logs.d.ts.map +1 -0
- package/dist/vwr-loader/src/__mocks__/@datadog/browser-logs.js.map +1 -0
- package/dist/vwr-loader/src/__mocks__/@datadog/browser-rum.d.ts.map +1 -0
- package/dist/vwr-loader/src/__mocks__/@datadog/browser-rum.js.map +1 -0
- package/dist/vwr-loader/src/__mocks__/invalidVwrModule.d.ts +2 -0
- package/dist/vwr-loader/src/__mocks__/invalidVwrModule.d.ts.map +1 -0
- package/dist/vwr-loader/src/__mocks__/invalidVwrModule.js +2 -0
- package/dist/vwr-loader/src/__mocks__/invalidVwrModule.js.map +1 -0
- package/dist/vwr-loader/src/__mocks__/vwrModule.d.ts.map +1 -0
- package/dist/vwr-loader/src/__mocks__/vwrModule.js.map +1 -0
- package/dist/vwr-loader/src/amplitudeFlagFetcher.d.ts.map +1 -0
- package/dist/vwr-loader/src/amplitudeFlagFetcher.js.map +1 -0
- package/dist/vwr-loader/src/errors/InitializationError.d.ts.map +1 -0
- package/dist/vwr-loader/src/errors/InitializationError.js.map +1 -0
- package/dist/vwr-loader/src/errors/ensureError.d.ts.map +1 -0
- package/dist/vwr-loader/src/errors/ensureError.js.map +1 -0
- package/dist/vwr-loader/src/errors/index.d.ts.map +1 -0
- package/dist/vwr-loader/src/errors/index.js.map +1 -0
- package/dist/vwr-loader/src/exitHandler.d.ts.map +1 -0
- package/dist/{exitHandler.js → vwr-loader/src/exitHandler.js} +2 -3
- package/dist/vwr-loader/src/exitHandler.js.map +1 -0
- package/dist/vwr-loader/src/getEnvironment.d.ts.map +1 -0
- package/dist/vwr-loader/src/getEnvironment.js.map +1 -0
- package/dist/vwr-loader/src/getShellVersion.d.ts.map +1 -0
- package/dist/vwr-loader/src/getShellVersion.js.map +1 -0
- package/dist/vwr-loader/src/index.d.ts +8 -0
- package/dist/vwr-loader/src/index.d.ts.map +1 -0
- package/dist/vwr-loader/src/index.js +6 -0
- package/dist/vwr-loader/src/index.js.map +1 -0
- package/dist/vwr-loader/src/loadVwr.d.ts.map +1 -0
- package/dist/{loadVwr.js → vwr-loader/src/loadVwr.js} +36 -27
- package/dist/vwr-loader/src/loadVwr.js.map +1 -0
- package/dist/vwr-loader/src/logger.d.ts +4 -0
- package/dist/vwr-loader/src/logger.d.ts.map +1 -0
- package/dist/vwr-loader/src/logger.js +10 -0
- package/dist/vwr-loader/src/logger.js.map +1 -0
- package/dist/vwr-loader/src/main.d.ts +2 -0
- package/dist/vwr-loader/src/main.d.ts.map +1 -0
- package/dist/vwr-loader/src/main.js +96 -0
- package/dist/vwr-loader/src/main.js.map +1 -0
- package/dist/vwr-loader/src/polyfills.d.ts.map +1 -0
- package/dist/vwr-loader/src/polyfills.js.map +1 -0
- package/dist/{test-setup.d.ts.map → vwr-loader/src/test-setup.d.ts.map} +1 -1
- package/dist/vwr-loader/src/test-setup.js.map +1 -0
- package/package.json +13 -12
- package/dist/__mocks__/@datadog/browser-logs.d.ts.map +0 -1
- package/dist/__mocks__/@datadog/browser-logs.js.map +0 -1
- package/dist/__mocks__/@datadog/browser-rum.d.ts.map +0 -1
- package/dist/__mocks__/@datadog/browser-rum.js.map +0 -1
- package/dist/__mocks__/vwrModule.d.ts.map +0 -1
- package/dist/__mocks__/vwrModule.js.map +0 -1
- package/dist/amplitudeFlagFetcher.d.ts.map +0 -1
- package/dist/amplitudeFlagFetcher.js.map +0 -1
- package/dist/assets/profiler-BRmTNL9s.js +0 -2
- package/dist/assets/profiler-BRmTNL9s.js.map +0 -1
- package/dist/assets/startRecording-CuFdVhxx.js +0 -3
- package/dist/assets/startRecording-CuFdVhxx.js.map +0 -1
- package/dist/datadog.d.ts.map +0 -1
- package/dist/datadog.js.map +0 -1
- package/dist/envDefaults.d.ts.map +0 -1
- package/dist/envDefaults.js +0 -74
- package/dist/envDefaults.js.map +0 -1
- package/dist/errors/InitializationError.d.ts.map +0 -1
- package/dist/errors/InitializationError.js.map +0 -1
- package/dist/errors/ensureError.d.ts.map +0 -1
- package/dist/errors/ensureError.js.map +0 -1
- package/dist/errors/index.d.ts.map +0 -1
- package/dist/errors/index.js.map +0 -1
- package/dist/exitHandler.d.ts.map +0 -1
- package/dist/exitHandler.js.map +0 -1
- package/dist/getDeviceId.d.ts +0 -26
- package/dist/getDeviceId.d.ts.map +0 -1
- package/dist/getDeviceId.js +0 -209
- package/dist/getDeviceId.js.map +0 -1
- package/dist/getEnvironment.d.ts.map +0 -1
- package/dist/getEnvironment.js.map +0 -1
- package/dist/getShellVersion.d.ts.map +0 -1
- package/dist/getShellVersion.js.map +0 -1
- package/dist/index.d.ts +0 -8
- package/dist/index.d.ts.map +0 -1
- package/dist/index.html +0 -25
- package/dist/index.js +0 -6
- package/dist/index.js.map +0 -1
- package/dist/loadVwr.d.ts.map +0 -1
- package/dist/loadVwr.js.map +0 -1
- package/dist/logger.d.ts +0 -12
- package/dist/logger.d.ts.map +0 -1
- package/dist/logger.js.map +0 -1
- package/dist/main.js +0 -12
- package/dist/main.js.map +0 -1
- package/dist/polyfills.d.ts.map +0 -1
- package/dist/polyfills.js.map +0 -1
- package/dist/test-setup.js.map +0 -1
- package/dist/types.d.ts +0 -103
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -5
- package/dist/types.js.map +0 -1
- package/dist/vwrConfig.d.ts.map +0 -1
- package/dist/vwrConfig.js.map +0 -1
- package/src/__mocks__/@datadog/browser-logs.ts +0 -35
- package/src/__mocks__/@datadog/browser-rum.ts +0 -27
- package/src/__mocks__/vwrModule.ts +0 -3
- package/src/amplitudeFlagFetcher.test.ts +0 -175
- package/src/amplitudeFlagFetcher.ts +0 -105
- package/src/datadog.ts +0 -55
- package/src/envDefaults.ts +0 -94
- package/src/errors/InitializationError.ts +0 -105
- package/src/errors/ensureError.ts +0 -6
- package/src/errors/index.ts +0 -16
- package/src/exitHandler.test.ts +0 -373
- package/src/exitHandler.ts +0 -232
- package/src/getDeviceId.test.ts +0 -298
- package/src/getDeviceId.ts +0 -224
- package/src/getEnvironment.test.ts +0 -417
- package/src/getEnvironment.ts +0 -144
- package/src/getShellVersion.test.ts +0 -403
- package/src/getShellVersion.ts +0 -132
- package/src/index.ts +0 -7
- package/src/loadVwr.test.ts +0 -549
- package/src/loadVwr.ts +0 -357
- package/src/logger.ts +0 -121
- package/src/main.test.ts +0 -157
- package/src/main.ts +0 -127
- package/src/polyfills.ts +0 -32
- package/src/test-setup.ts +0 -5
- package/src/types.ts +0 -105
- package/src/vite-env.d.ts +0 -32
- package/src/vwrConfig.test.ts +0 -386
- package/src/vwrConfig.ts +0 -374
- /package/dist/{__mocks__ → vwr-loader/src/__mocks__}/@datadog/browser-logs.d.ts +0 -0
- /package/dist/{__mocks__ → vwr-loader/src/__mocks__}/@datadog/browser-logs.js +0 -0
- /package/dist/{__mocks__ → vwr-loader/src/__mocks__}/@datadog/browser-rum.d.ts +0 -0
- /package/dist/{__mocks__ → vwr-loader/src/__mocks__}/@datadog/browser-rum.js +0 -0
- /package/dist/{__mocks__ → vwr-loader/src/__mocks__}/vwrModule.d.ts +0 -0
- /package/dist/{__mocks__ → vwr-loader/src/__mocks__}/vwrModule.js +0 -0
- /package/dist/{amplitudeFlagFetcher.d.ts → vwr-loader/src/amplitudeFlagFetcher.d.ts} +0 -0
- /package/dist/{amplitudeFlagFetcher.js → vwr-loader/src/amplitudeFlagFetcher.js} +0 -0
- /package/dist/{errors → vwr-loader/src/errors}/InitializationError.d.ts +0 -0
- /package/dist/{errors → vwr-loader/src/errors}/InitializationError.js +0 -0
- /package/dist/{errors → vwr-loader/src/errors}/ensureError.d.ts +0 -0
- /package/dist/{errors → vwr-loader/src/errors}/ensureError.js +0 -0
- /package/dist/{errors → vwr-loader/src/errors}/index.d.ts +0 -0
- /package/dist/{errors → vwr-loader/src/errors}/index.js +0 -0
- /package/dist/{exitHandler.d.ts → vwr-loader/src/exitHandler.d.ts} +0 -0
- /package/dist/{getEnvironment.d.ts → vwr-loader/src/getEnvironment.d.ts} +0 -0
- /package/dist/{getEnvironment.js → vwr-loader/src/getEnvironment.js} +0 -0
- /package/dist/{getShellVersion.d.ts → vwr-loader/src/getShellVersion.d.ts} +0 -0
- /package/dist/{getShellVersion.js → vwr-loader/src/getShellVersion.js} +0 -0
- /package/dist/{loadVwr.d.ts → vwr-loader/src/loadVwr.d.ts} +0 -0
- /package/dist/{polyfills.d.ts → vwr-loader/src/polyfills.d.ts} +0 -0
- /package/dist/{polyfills.js → vwr-loader/src/polyfills.js} +0 -0
- /package/dist/{test-setup.d.ts → vwr-loader/src/test-setup.d.ts} +0 -0
- /package/dist/{test-setup.js → vwr-loader/src/test-setup.js} +0 -0
package/src/loadVwr.ts
DELETED
|
@@ -1,357 +0,0 @@
|
|
|
1
|
-
import type { DatadogRum } from "@datadog/browser-rum"
|
|
2
|
-
import type * as VWR from "@volley/vwr"
|
|
3
|
-
|
|
4
|
-
import { fetchAmplitudeFlags, FlagFetchError } from "./amplitudeFlagFetcher"
|
|
5
|
-
import { ENV_DEFAULTS } from "./envDefaults"
|
|
6
|
-
import {
|
|
7
|
-
InitializationError,
|
|
8
|
-
InitializationErrorReason,
|
|
9
|
-
isVWRInitializationError,
|
|
10
|
-
} from "./errors"
|
|
11
|
-
import { getDeviceId } from "./getDeviceId"
|
|
12
|
-
import { getEnvironment } from "./getEnvironment"
|
|
13
|
-
import { getShellVersion } from "./getShellVersion"
|
|
14
|
-
import { logger, setLogger } from "./logger"
|
|
15
|
-
import type {
|
|
16
|
-
ConfigFetchAttempt,
|
|
17
|
-
VWRConfig,
|
|
18
|
-
VWRConfigRequest,
|
|
19
|
-
VWRConfigResult,
|
|
20
|
-
} from "./vwrConfig"
|
|
21
|
-
import { getVWRConfig, validateConfig } from "./vwrConfig"
|
|
22
|
-
|
|
23
|
-
// Vite injects these at build time
|
|
24
|
-
// VITE_ENVIRONMENT is optional for platforms that support native env reading (Fire TV)
|
|
25
|
-
const BUILD_TIME_ENVIRONMENT = import.meta.env.VITE_ENVIRONMENT as
|
|
26
|
-
| string
|
|
27
|
-
| undefined
|
|
28
|
-
const PLATFORM = import.meta.env.VITE_PLATFORM
|
|
29
|
-
const CONFIG_URL = import.meta.env.VITE_CONFIG_URL
|
|
30
|
-
const CONFIG_FILE = import.meta.env.VITE_CONFIG_FILE
|
|
31
|
-
|
|
32
|
-
// AMPLITUDE_KEY can be optionally injected at build time (via build.ts script)
|
|
33
|
-
// Falls back to envDefaults if not injected (e.g., vite.config.dev.ts)
|
|
34
|
-
const AMPLITUDE_KEY = import.meta.env.VITE_AMPLITUDE_DEPLOYMENT_KEY
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Load VWR runtime.
|
|
38
|
-
*
|
|
39
|
-
* Optimized flow: checks vwr-enabled flag FIRST using baked-in Amplitude key,
|
|
40
|
-
* before doing any config fetches. For flag-OFF users (100% at initial launch),
|
|
41
|
-
* this reduces startup latency from ~2-4s to ~500ms by skipping config fetches.
|
|
42
|
-
*
|
|
43
|
-
* Flow:
|
|
44
|
-
* 1. Get deviceId, shellVersion, environment (fast, local/native)
|
|
45
|
-
* 2. Check vwr-enabled flag (single request, ~500ms)
|
|
46
|
-
* 3. If OFF → throw immediately (no config fetches)
|
|
47
|
-
* 4. If ON → fetch config, load VWR module, initialize
|
|
48
|
-
*
|
|
49
|
-
* Environment resolution:
|
|
50
|
-
* - Fire TV: reads from native BuildConfig.ENVIRONMENT (prevents env mismatch)
|
|
51
|
-
* - Other platforms: uses build-time injected VITE_ENVIRONMENT
|
|
52
|
-
* - Fallback: "dev"
|
|
53
|
-
*
|
|
54
|
-
* @param logger - Optional legacy logger, defaults to console
|
|
55
|
-
* @param observability - Optional observability config with @volley/logger and RUM client
|
|
56
|
-
*/
|
|
57
|
-
export const loadVwr = async (rum?: DatadogRum) => {
|
|
58
|
-
const totalStartTime = performance.now()
|
|
59
|
-
|
|
60
|
-
try {
|
|
61
|
-
await initializeVwr(rum)
|
|
62
|
-
|
|
63
|
-
// Track successful VWR initialization
|
|
64
|
-
rum?.addAction("vwr:init:complete", {
|
|
65
|
-
outcome: "success",
|
|
66
|
-
duration_ms: performance.now() - totalStartTime,
|
|
67
|
-
})
|
|
68
|
-
} catch (error) {
|
|
69
|
-
// Track failed VWR initialization
|
|
70
|
-
rum?.addAction("vwr:init:complete", {
|
|
71
|
-
outcome: "failure",
|
|
72
|
-
duration_ms: performance.now() - totalStartTime,
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
// Track fallback with structured reason
|
|
76
|
-
let reason = "UNKNOWN_ERROR"
|
|
77
|
-
if (error instanceof InitializationError) {
|
|
78
|
-
reason = error.reason
|
|
79
|
-
} else if (isVWRInitializationError(error)) {
|
|
80
|
-
reason = error.reason
|
|
81
|
-
}
|
|
82
|
-
rum?.addAction("vwr:fallback", {
|
|
83
|
-
reason,
|
|
84
|
-
error_type: error instanceof Error ? error.name : "UnknownError",
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
throw error
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
async function initializeVwr(rum: DatadogRum | undefined) {
|
|
92
|
-
if (!PLATFORM || !CONFIG_URL || !CONFIG_FILE) {
|
|
93
|
-
throw new InitializationError(
|
|
94
|
-
InitializationErrorReason.ENV_VARS_MISSING,
|
|
95
|
-
"[Shell] Required environment variables not injected (PLATFORM, CONFIG_URL, or CONFIG_FILE)",
|
|
96
|
-
{
|
|
97
|
-
configUrl: CONFIG_URL,
|
|
98
|
-
configFile: CONFIG_FILE,
|
|
99
|
-
}
|
|
100
|
-
)
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
logger.info({ platform: PLATFORM }, "Starting VWR load")
|
|
104
|
-
rum?.setGlobalContextProperty("platform", PLATFORM)
|
|
105
|
-
|
|
106
|
-
const deviceId = await getDeviceId(PLATFORM)
|
|
107
|
-
if (!deviceId) {
|
|
108
|
-
throw new InitializationError(
|
|
109
|
-
InitializationErrorReason.DEVICE_ID_FAILED,
|
|
110
|
-
`[Shell] Failed to retrieve device ID for platform: ${PLATFORM}`
|
|
111
|
-
)
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Set logger with deviceId context
|
|
115
|
-
setLogger(logger.child({ deviceId }))
|
|
116
|
-
|
|
117
|
-
const shellVersion = await getShellVersion(PLATFORM)
|
|
118
|
-
|
|
119
|
-
if (!shellVersion) {
|
|
120
|
-
throw new InitializationError(
|
|
121
|
-
InitializationErrorReason.SHELL_VERSION_FAILED,
|
|
122
|
-
`[Shell] Failed to retrieve shell version for platform: ${PLATFORM}`
|
|
123
|
-
)
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// Set logger with shellVersion context
|
|
127
|
-
setLogger(logger.child({ shellVersion }))
|
|
128
|
-
|
|
129
|
-
// Get environment from native (Fire TV) or build-time injection
|
|
130
|
-
// This ensures prod APKs cannot accidentally run dev VWR
|
|
131
|
-
const { environment: ENVIRONMENT } = await getEnvironment(
|
|
132
|
-
PLATFORM,
|
|
133
|
-
BUILD_TIME_ENVIRONMENT
|
|
134
|
-
)
|
|
135
|
-
|
|
136
|
-
// Get amplitude key: injected at build time OR from envDefaults
|
|
137
|
-
// Precedence: build-time injection > envDefaults
|
|
138
|
-
let amplitudeKey = AMPLITUDE_KEY
|
|
139
|
-
if (!amplitudeKey) {
|
|
140
|
-
const envDefaults = ENV_DEFAULTS[ENVIRONMENT]
|
|
141
|
-
if (!envDefaults) {
|
|
142
|
-
throw new InitializationError(
|
|
143
|
-
InitializationErrorReason.ENV_UNKNOWN,
|
|
144
|
-
`[Shell] Unknown environment: ${ENVIRONMENT}`
|
|
145
|
-
)
|
|
146
|
-
}
|
|
147
|
-
amplitudeKey = envDefaults.amplitudeKey
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// FAST PATH: Check flag first using amplitude key
|
|
151
|
-
// This avoids config fetches for flag-OFF users (majority at launch)
|
|
152
|
-
let flags
|
|
153
|
-
try {
|
|
154
|
-
flags = await fetchAmplitudeFlags(
|
|
155
|
-
deviceId,
|
|
156
|
-
PLATFORM,
|
|
157
|
-
{
|
|
158
|
-
apiKey: amplitudeKey,
|
|
159
|
-
timeout: 2000,
|
|
160
|
-
},
|
|
161
|
-
shellVersion
|
|
162
|
-
)
|
|
163
|
-
} catch (error) {
|
|
164
|
-
if (error instanceof FlagFetchError) {
|
|
165
|
-
throw new InitializationError(
|
|
166
|
-
InitializationErrorReason.FLAG_FETCH_FAILED,
|
|
167
|
-
`[Shell] ${error.message}`,
|
|
168
|
-
{
|
|
169
|
-
cause: error.cause,
|
|
170
|
-
}
|
|
171
|
-
)
|
|
172
|
-
}
|
|
173
|
-
throw error
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
logger.debug({ flags }, "Flags fetched")
|
|
177
|
-
|
|
178
|
-
// Set RUM context for flag result (enables filtering by flag outcome)
|
|
179
|
-
rum?.setGlobalContextProperty(
|
|
180
|
-
"flag_result",
|
|
181
|
-
flags["vwr-enabled"] ? "enabled" : "disabled"
|
|
182
|
-
)
|
|
183
|
-
|
|
184
|
-
if (!flags["vwr-enabled"]) {
|
|
185
|
-
// Flag OFF: skip all config fetches, fail fast
|
|
186
|
-
throw new InitializationError(
|
|
187
|
-
InitializationErrorReason.FLAG_DISABLED,
|
|
188
|
-
"[Shell] VWR not enabled via Amplitude flags"
|
|
189
|
-
)
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// Flag ON: proceed with full config loading
|
|
193
|
-
logger.debug("VWR flag enabled, fetching config")
|
|
194
|
-
|
|
195
|
-
const vwrConfigRequest: VWRConfigRequest = {
|
|
196
|
-
configUrl: CONFIG_URL,
|
|
197
|
-
configFile: CONFIG_FILE,
|
|
198
|
-
platform: PLATFORM,
|
|
199
|
-
deviceId: deviceId,
|
|
200
|
-
environment: ENVIRONMENT,
|
|
201
|
-
shellVersion: shellVersion,
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
let vwrConfig: VWRConfig
|
|
205
|
-
let configSource: VWRConfigResult["source"]
|
|
206
|
-
let configAttempts: ConfigFetchAttempt[]
|
|
207
|
-
let configTotalDurationMs: number
|
|
208
|
-
try {
|
|
209
|
-
const result = await getVWRConfig(vwrConfigRequest, logger)
|
|
210
|
-
vwrConfig = result.config
|
|
211
|
-
configSource = result.source
|
|
212
|
-
configAttempts = result.attempts
|
|
213
|
-
configTotalDurationMs = result.total_duration_ms
|
|
214
|
-
|
|
215
|
-
// Set RUM context for config source (enables tracking config fallback rate)
|
|
216
|
-
rum?.setGlobalContextProperty("config_source", configSource)
|
|
217
|
-
|
|
218
|
-
// Track per-source fetch attempts for detailed analysis
|
|
219
|
-
for (const attempt of configAttempts) {
|
|
220
|
-
rum?.addAction("vwr:config:fetch_attempt", {
|
|
221
|
-
source: attempt.source,
|
|
222
|
-
success: attempt.success,
|
|
223
|
-
duration_ms: attempt.duration_ms,
|
|
224
|
-
})
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
// Track total config resolution (all sources fetched in parallel)
|
|
228
|
-
rum?.addAction("vwr:config:resolved", {
|
|
229
|
-
source: configSource,
|
|
230
|
-
total_duration_ms: configTotalDurationMs,
|
|
231
|
-
})
|
|
232
|
-
|
|
233
|
-
logger.debug(
|
|
234
|
-
{
|
|
235
|
-
source: configSource,
|
|
236
|
-
total_duration_ms: configTotalDurationMs,
|
|
237
|
-
attempts: configAttempts,
|
|
238
|
-
},
|
|
239
|
-
"Config fetched"
|
|
240
|
-
)
|
|
241
|
-
} catch (configError) {
|
|
242
|
-
throw new InitializationError(
|
|
243
|
-
InitializationErrorReason.CONFIG_FETCH_FAILED,
|
|
244
|
-
configError instanceof Error
|
|
245
|
-
? configError.message
|
|
246
|
-
: "Config fetch failed",
|
|
247
|
-
{
|
|
248
|
-
cause: configError instanceof Error ? configError : undefined,
|
|
249
|
-
configUrl: CONFIG_URL,
|
|
250
|
-
}
|
|
251
|
-
)
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
if (!validateConfig(vwrConfig)) {
|
|
255
|
-
throw new InitializationError(
|
|
256
|
-
InitializationErrorReason.CONFIG_INVALID,
|
|
257
|
-
"[Shell] Invalid config (missing vwrUrl, hubUrl, or trustedDomains)",
|
|
258
|
-
{
|
|
259
|
-
config: JSON.stringify(vwrConfig),
|
|
260
|
-
}
|
|
261
|
-
)
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
logger.debug({ vwrUrl: vwrConfig.vwrUrl }, "Loading VWR module")
|
|
265
|
-
|
|
266
|
-
let vwr: typeof VWR
|
|
267
|
-
try {
|
|
268
|
-
vwr = (await import(/* @vite-ignore */ vwrConfig.vwrUrl)) as typeof VWR
|
|
269
|
-
|
|
270
|
-
logger.debug("VWR module loaded successfully")
|
|
271
|
-
} catch (fetchError) {
|
|
272
|
-
const err =
|
|
273
|
-
fetchError instanceof Error
|
|
274
|
-
? fetchError
|
|
275
|
-
: new Error(String(fetchError))
|
|
276
|
-
|
|
277
|
-
throw new InitializationError(
|
|
278
|
-
InitializationErrorReason.MODULE_FETCH_FAILED,
|
|
279
|
-
`[Shell] Failed to fetch VWR module: ${err.message}`,
|
|
280
|
-
{
|
|
281
|
-
cause: err,
|
|
282
|
-
vwrUrl: vwrConfig.vwrUrl,
|
|
283
|
-
}
|
|
284
|
-
)
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
if (typeof vwr.init !== "function") {
|
|
288
|
-
throw new InitializationError(
|
|
289
|
-
InitializationErrorReason.MODULE_INVALID,
|
|
290
|
-
"[Shell] VWR module missing init() function",
|
|
291
|
-
{
|
|
292
|
-
vwrUrl: vwrConfig.vwrUrl,
|
|
293
|
-
}
|
|
294
|
-
)
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// Build config source display string for VWR mode indicator
|
|
298
|
-
let configSourceDisplay: string
|
|
299
|
-
switch (configSource) {
|
|
300
|
-
case "device":
|
|
301
|
-
configSourceDisplay = `device (${deviceId})`
|
|
302
|
-
break
|
|
303
|
-
case "environment":
|
|
304
|
-
configSourceDisplay = `environment (${ENVIRONMENT})`
|
|
305
|
-
break
|
|
306
|
-
case "shellVersion":
|
|
307
|
-
configSourceDisplay = `shell-version (${ENVIRONMENT}/${PLATFORM}/${shellVersion})`
|
|
308
|
-
break
|
|
309
|
-
case "local":
|
|
310
|
-
configSourceDisplay = "local"
|
|
311
|
-
break
|
|
312
|
-
default:
|
|
313
|
-
configSourceDisplay = "defaults"
|
|
314
|
-
break
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
try {
|
|
318
|
-
await vwr.init(
|
|
319
|
-
{
|
|
320
|
-
hubUrl: vwrConfig.hubUrl,
|
|
321
|
-
launchUrl: vwrConfig.launchUrl,
|
|
322
|
-
platform: PLATFORM,
|
|
323
|
-
stage: ENVIRONMENT,
|
|
324
|
-
appVersion: shellVersion,
|
|
325
|
-
platformApiUrl: vwrConfig.platformApiUrl,
|
|
326
|
-
platformAuthApiUrl: vwrConfig.platformAuthApiUrl,
|
|
327
|
-
trustedOrigins: new Set(vwrConfig.trustedDomains),
|
|
328
|
-
nativeShellVersion: shellVersion,
|
|
329
|
-
configSource: configSourceDisplay,
|
|
330
|
-
},
|
|
331
|
-
logger,
|
|
332
|
-
rum
|
|
333
|
-
)
|
|
334
|
-
} catch (vwrError) {
|
|
335
|
-
// Re-throw InitializationErrors as-is (e.g., MODULE_INVALID)
|
|
336
|
-
if (vwrError instanceof InitializationError) {
|
|
337
|
-
throw vwrError
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
// Re-throw VWR errors directly - they already have structured info
|
|
341
|
-
if (isVWRInitializationError(vwrError)) {
|
|
342
|
-
throw vwrError
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
// Wrap other unknown errors as INIT_FAILED
|
|
346
|
-
const errorMessage =
|
|
347
|
-
vwrError instanceof Error ? vwrError.message : String(vwrError)
|
|
348
|
-
|
|
349
|
-
throw new InitializationError(
|
|
350
|
-
InitializationErrorReason.INIT_FAILED,
|
|
351
|
-
`[Shell] VWR initialization failed: ${errorMessage}`,
|
|
352
|
-
{
|
|
353
|
-
cause: vwrError instanceof Error ? vwrError : undefined,
|
|
354
|
-
}
|
|
355
|
-
)
|
|
356
|
-
}
|
|
357
|
-
}
|
package/src/logger.ts
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
import { datadogLogs } from "@datadog/browser-logs"
|
|
2
|
-
import type { ILogger } from "@volley/logger"
|
|
3
|
-
import { createLogger } from "@volley/logger"
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Context type specifically for error logs.
|
|
7
|
-
* Use this when calling logger.error() to include the Error object
|
|
8
|
-
* for RUM Error Tracking (source maps, stack traces).
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* ```typescript
|
|
12
|
-
* const context: ErrorLogContext = {
|
|
13
|
-
* error: someError,
|
|
14
|
-
* error_type: someError.name,
|
|
15
|
-
* // ... other context
|
|
16
|
-
* }
|
|
17
|
-
* logger.error(context, "Something went wrong")
|
|
18
|
-
* ```
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
// Initialize Datadog Logs - forwardErrorsToLogs disabled since we handle errors manually
|
|
22
|
-
datadogLogs.init({
|
|
23
|
-
clientToken: import.meta.env.VITE_DATADOG_CLIENT_TOKEN,
|
|
24
|
-
site: "datadoghq.com",
|
|
25
|
-
service: "vwr-loader",
|
|
26
|
-
env: import.meta.env.VITE_ENVIRONMENT,
|
|
27
|
-
version: import.meta.env.VITE_SHELL_VERSION,
|
|
28
|
-
forwardErrorsToLogs: true, // RUM picks up console errors automatically
|
|
29
|
-
sessionSampleRate: 100,
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Extract message and context from pino log object.
|
|
34
|
-
* Removes internal pino fields (msg, level, time) and extracts error if present.
|
|
35
|
-
*/
|
|
36
|
-
function parseLogObject(logObject: object) {
|
|
37
|
-
const obj = logObject as Record<string, unknown>
|
|
38
|
-
const msg = (obj.msg as string) || ""
|
|
39
|
-
const errorObj = obj.error instanceof Error ? obj.error : undefined
|
|
40
|
-
|
|
41
|
-
// Build context (exclude internal pino fields)
|
|
42
|
-
const {
|
|
43
|
-
msg: _msg,
|
|
44
|
-
level: _level,
|
|
45
|
-
time: _time,
|
|
46
|
-
error: _error,
|
|
47
|
-
...context
|
|
48
|
-
} = obj
|
|
49
|
-
|
|
50
|
-
return { msg, context, errorObj }
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Write handler for non-error logs (trace, debug, info, warn).
|
|
55
|
-
* Sends to console and Datadog Logs.
|
|
56
|
-
*/
|
|
57
|
-
function writeLog(
|
|
58
|
-
logObject: object,
|
|
59
|
-
consoleMethod: "debug" | "info" | "warn",
|
|
60
|
-
datadogLevel: "debug" | "info" | "warn"
|
|
61
|
-
) {
|
|
62
|
-
const { msg, context } = parseLogObject(logObject)
|
|
63
|
-
|
|
64
|
-
// Write to console for dev visibility
|
|
65
|
-
console[consoleMethod](msg, context)
|
|
66
|
-
|
|
67
|
-
// Send to Datadog Logs
|
|
68
|
-
datadogLogs.logger[datadogLevel](msg, context)
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Write handler for error logs (error, fatal).
|
|
73
|
-
* Sends to console and Datadog Logs with Error object.
|
|
74
|
-
*
|
|
75
|
-
* NOTE: This is commented out because forwardErrorsToLogs: true in datadogLogs.init()
|
|
76
|
-
* automatically forwards console.error calls to Datadog Logs. If forwardErrorsToLogs
|
|
77
|
-
* were disabled, we would use this handler to manually send errors to Datadog.
|
|
78
|
-
*/
|
|
79
|
-
// function writeError(logObject: object) {
|
|
80
|
-
// const { msg, context, errorObj } = parseLogObject(logObject)
|
|
81
|
-
|
|
82
|
-
// // Write to console for dev visibility (include error for stack trace)
|
|
83
|
-
// if (errorObj) {
|
|
84
|
-
// console.error(msg, context, errorObj)
|
|
85
|
-
// } else {
|
|
86
|
-
// console.error(msg, context)
|
|
87
|
-
// }
|
|
88
|
-
|
|
89
|
-
// // Send to Datadog Logs with Error object as 3rd arg
|
|
90
|
-
// datadogLogs.logger.error(msg, context, errorObj)
|
|
91
|
-
// }
|
|
92
|
-
|
|
93
|
-
export let logger: ILogger = createLogger({
|
|
94
|
-
type: "browser",
|
|
95
|
-
browser: {
|
|
96
|
-
asObject: true,
|
|
97
|
-
formatters: {
|
|
98
|
-
level(label: string) {
|
|
99
|
-
return { level: label }
|
|
100
|
-
},
|
|
101
|
-
},
|
|
102
|
-
// Separate write handlers per level for clarity
|
|
103
|
-
write: {
|
|
104
|
-
trace: (o: object) => writeLog(o, "debug", "debug"),
|
|
105
|
-
debug: (o: object) => writeLog(o, "debug", "debug"),
|
|
106
|
-
info: (o: object) => writeLog(o, "info", "info"),
|
|
107
|
-
warn: (o: object) => writeLog(o, "warn", "warn"),
|
|
108
|
-
// error and fatal logs are automatically forwarded to Datadog via forwardErrorsToLogs
|
|
109
|
-
// error: writeError,
|
|
110
|
-
// fatal: writeError,
|
|
111
|
-
},
|
|
112
|
-
},
|
|
113
|
-
}).child({
|
|
114
|
-
service: "vwr-loader",
|
|
115
|
-
env: import.meta.env.VITE_ENVIRONMENT,
|
|
116
|
-
platform: import.meta.env.VITE_PLATFORM,
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
export function setLogger(_logger: ILogger) {
|
|
120
|
-
logger = _logger
|
|
121
|
-
}
|
package/src/main.test.ts
DELETED
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it, vi } from "vitest"
|
|
2
|
-
|
|
3
|
-
// Mock all dependencies before importing main
|
|
4
|
-
vi.mock("./datadog", () => ({
|
|
5
|
-
initRumGlobal: vi.fn(() => ({
|
|
6
|
-
addAction: vi.fn(),
|
|
7
|
-
setGlobalContextProperty: vi.fn(),
|
|
8
|
-
})),
|
|
9
|
-
}))
|
|
10
|
-
|
|
11
|
-
vi.mock("./loadVwr", () => ({
|
|
12
|
-
loadVwr: vi.fn(),
|
|
13
|
-
}))
|
|
14
|
-
|
|
15
|
-
vi.mock("./logger", () => ({
|
|
16
|
-
logger: {
|
|
17
|
-
info: vi.fn(),
|
|
18
|
-
warn: vi.fn(),
|
|
19
|
-
error: vi.fn(),
|
|
20
|
-
},
|
|
21
|
-
}))
|
|
22
|
-
|
|
23
|
-
// Mock window.location
|
|
24
|
-
const mockLocationHref = vi.fn()
|
|
25
|
-
delete (window as any).location
|
|
26
|
-
;(window as any).location = {
|
|
27
|
-
_href: "",
|
|
28
|
-
search: "",
|
|
29
|
-
set href(value: string) {
|
|
30
|
-
this._href = value
|
|
31
|
-
mockLocationHref(value)
|
|
32
|
-
},
|
|
33
|
-
get href() {
|
|
34
|
-
return this._href
|
|
35
|
-
},
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
import { InitializationError } from "./errors"
|
|
39
|
-
import { loadVwr } from "./loadVwr"
|
|
40
|
-
import { logger } from "./logger"
|
|
41
|
-
|
|
42
|
-
const mockLoadVwr = vi.mocked(loadVwr)
|
|
43
|
-
|
|
44
|
-
describe("main.ts fallback behavior", () => {
|
|
45
|
-
beforeEach(() => {
|
|
46
|
-
vi.resetAllMocks()
|
|
47
|
-
vi.resetModules()
|
|
48
|
-
mockLocationHref.mockClear()
|
|
49
|
-
;(window.location as any)._href = ""
|
|
50
|
-
;(window.location as any).search = ""
|
|
51
|
-
|
|
52
|
-
// Stub environment variables
|
|
53
|
-
vi.stubEnv("VITE_PLATFORM", "FIRE_TV")
|
|
54
|
-
vi.stubEnv("VITE_HUB_URL", "https://hub.example.com")
|
|
55
|
-
vi.stubEnv("VITE_ENVIRONMENT", "dev")
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
describe("when VWR initialization fails", () => {
|
|
59
|
-
it("falls back to Hub URL when no gameControllerUrl present", async () => {
|
|
60
|
-
mockLoadVwr.mockRejectedValue(
|
|
61
|
-
new InitializationError("FLAG_DISABLED", "VWR not enabled", {})
|
|
62
|
-
)
|
|
63
|
-
|
|
64
|
-
// Import and run main
|
|
65
|
-
await import("./main")
|
|
66
|
-
|
|
67
|
-
// Wait for async init to complete
|
|
68
|
-
await vi.waitFor(() => {
|
|
69
|
-
expect(mockLocationHref).toHaveBeenCalled()
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
expect(mockLocationHref).toHaveBeenCalledWith(
|
|
73
|
-
"https://hub.example.com/?volley_platform=FIRE_TV&version=unknown"
|
|
74
|
-
)
|
|
75
|
-
expect(logger.info).toHaveBeenCalledWith(
|
|
76
|
-
expect.objectContaining({
|
|
77
|
-
PLATFORM: "FIRE_TV",
|
|
78
|
-
}),
|
|
79
|
-
"[Shell] No gameControllerUrl, redirecting to Hub"
|
|
80
|
-
)
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
it("falls back to gameControllerUrl when present", async () => {
|
|
84
|
-
mockLoadVwr.mockRejectedValue(
|
|
85
|
-
new InitializationError("FLAG_DISABLED", "VWR not enabled", {})
|
|
86
|
-
)
|
|
87
|
-
;(window.location as any).search =
|
|
88
|
-
"?gameControllerUrl=https://vly.gg/game123"
|
|
89
|
-
|
|
90
|
-
await import("./main")
|
|
91
|
-
|
|
92
|
-
await vi.waitFor(() => {
|
|
93
|
-
expect(mockLocationHref).toHaveBeenCalled()
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
expect(mockLocationHref).toHaveBeenCalledWith(
|
|
97
|
-
"https://vly.gg/game123"
|
|
98
|
-
)
|
|
99
|
-
expect(logger.info).toHaveBeenCalledWith(
|
|
100
|
-
expect.objectContaining({
|
|
101
|
-
gameControllerUrl: "https://vly.gg/game123",
|
|
102
|
-
}),
|
|
103
|
-
"[Shell] Using gameControllerUrl as fallback"
|
|
104
|
-
)
|
|
105
|
-
})
|
|
106
|
-
|
|
107
|
-
it("falls back to Hub URL when gameControllerUrl is empty", async () => {
|
|
108
|
-
mockLoadVwr.mockRejectedValue(
|
|
109
|
-
new InitializationError("FLAG_DISABLED", "VWR not enabled", {})
|
|
110
|
-
)
|
|
111
|
-
;(window.location as any).search = "?gameControllerUrl="
|
|
112
|
-
|
|
113
|
-
await import("./main")
|
|
114
|
-
|
|
115
|
-
await vi.waitFor(() => {
|
|
116
|
-
expect(mockLocationHref).toHaveBeenCalled()
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
expect(mockLocationHref).toHaveBeenCalledWith(
|
|
120
|
-
"https://hub.example.com/?volley_platform=FIRE_TV&version=unknown"
|
|
121
|
-
)
|
|
122
|
-
})
|
|
123
|
-
|
|
124
|
-
it("falls back to Hub URL when gameControllerUrl is whitespace only", async () => {
|
|
125
|
-
mockLoadVwr.mockRejectedValue(
|
|
126
|
-
new InitializationError("FLAG_DISABLED", "VWR not enabled", {})
|
|
127
|
-
)
|
|
128
|
-
;(window.location as any).search = "?gameControllerUrl=%20%20"
|
|
129
|
-
|
|
130
|
-
await import("./main")
|
|
131
|
-
|
|
132
|
-
await vi.waitFor(() => {
|
|
133
|
-
expect(mockLocationHref).toHaveBeenCalled()
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
expect(mockLocationHref).toHaveBeenCalledWith(
|
|
137
|
-
"https://hub.example.com/?volley_platform=FIRE_TV&version=unknown"
|
|
138
|
-
)
|
|
139
|
-
})
|
|
140
|
-
|
|
141
|
-
it("logs errors before fallback", async () => {
|
|
142
|
-
mockLoadVwr.mockRejectedValue(new Error("Init error"))
|
|
143
|
-
|
|
144
|
-
await import("./main")
|
|
145
|
-
|
|
146
|
-
await vi.waitFor(() => {
|
|
147
|
-
expect(logger.error).toHaveBeenCalled()
|
|
148
|
-
})
|
|
149
|
-
|
|
150
|
-
// Verify error was logged (exact format depends on error type)
|
|
151
|
-
expect(logger.error).toHaveBeenCalled()
|
|
152
|
-
expect(mockLocationHref).toHaveBeenCalledWith(
|
|
153
|
-
"https://hub.example.com/?volley_platform=FIRE_TV&version=unknown"
|
|
154
|
-
)
|
|
155
|
-
})
|
|
156
|
-
})
|
|
157
|
-
})
|