@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.
Files changed (252) hide show
  1. package/dist/cli.js +84 -24
  2. package/dist/cli.js.map +1 -1
  3. package/dist/{datadog.d.ts → vwr/src/datadog.d.ts} +7 -3
  4. package/dist/vwr/src/datadog.d.ts.map +1 -0
  5. package/dist/{datadog.js → vwr/src/datadog.js} +6 -5
  6. package/dist/vwr/src/datadog.js.map +1 -0
  7. package/dist/{envDefaults.d.ts → vwr/src/envDefaults.d.ts} +1 -0
  8. package/dist/vwr/src/envDefaults.d.ts.map +1 -0
  9. package/dist/vwr/src/envDefaults.js +67 -0
  10. package/dist/vwr/src/envDefaults.js.map +1 -0
  11. package/dist/vwr/src/iframe.d.ts +25 -0
  12. package/dist/vwr/src/iframe.d.ts.map +1 -0
  13. package/dist/vwr/src/iframe.js +82 -0
  14. package/dist/vwr/src/iframe.js.map +1 -0
  15. package/dist/vwr/src/logger.d.ts +15 -0
  16. package/dist/vwr/src/logger.d.ts.map +1 -0
  17. package/dist/{logger.js → vwr/src/logger.js} +30 -46
  18. package/dist/vwr/src/logger.js.map +1 -0
  19. package/dist/vwr/src/native/app-lifecycle/factory.d.ts +7 -0
  20. package/dist/vwr/src/native/app-lifecycle/factory.d.ts.map +1 -0
  21. package/dist/vwr/src/native/app-lifecycle/factory.js +68 -0
  22. package/dist/vwr/src/native/app-lifecycle/factory.js.map +1 -0
  23. package/dist/vwr/src/native/app-lifecycle/rpc.d.ts +15 -0
  24. package/dist/vwr/src/native/app-lifecycle/rpc.d.ts.map +1 -0
  25. package/dist/vwr/src/native/app-lifecycle/rpc.js +46 -0
  26. package/dist/vwr/src/native/app-lifecycle/rpc.js.map +1 -0
  27. package/dist/vwr/src/native/capacitor-bridge/rpc.d.ts +33 -0
  28. package/dist/vwr/src/native/capacitor-bridge/rpc.d.ts.map +1 -0
  29. package/dist/vwr/src/native/capacitor-bridge/rpc.js +129 -0
  30. package/dist/vwr/src/native/capacitor-bridge/rpc.js.map +1 -0
  31. package/dist/vwr/src/native/device-info/factory.d.ts +9 -0
  32. package/dist/vwr/src/native/device-info/factory.d.ts.map +1 -0
  33. package/dist/vwr/src/native/device-info/factory.js +28 -0
  34. package/dist/vwr/src/native/device-info/factory.js.map +1 -0
  35. package/dist/vwr/src/native/device-info/firetvCollector.d.ts +9 -0
  36. package/dist/vwr/src/native/device-info/firetvCollector.d.ts.map +1 -0
  37. package/dist/vwr/src/native/device-info/firetvCollector.js +180 -0
  38. package/dist/vwr/src/native/device-info/firetvCollector.js.map +1 -0
  39. package/dist/vwr/src/native/device-info/getDeviceId.d.ts +13 -0
  40. package/dist/vwr/src/native/device-info/getDeviceId.d.ts.map +1 -0
  41. package/dist/vwr/src/native/device-info/getDeviceId.js +137 -0
  42. package/dist/vwr/src/native/device-info/getDeviceId.js.map +1 -0
  43. package/dist/vwr/src/native/device-info/lgCollector.d.ts +8 -0
  44. package/dist/vwr/src/native/device-info/lgCollector.d.ts.map +1 -0
  45. package/dist/vwr/src/native/device-info/lgCollector.js +136 -0
  46. package/dist/vwr/src/native/device-info/lgCollector.js.map +1 -0
  47. package/dist/vwr/src/native/device-info/mobileCollector.d.ts +9 -0
  48. package/dist/vwr/src/native/device-info/mobileCollector.d.ts.map +1 -0
  49. package/dist/vwr/src/native/device-info/mobileCollector.js +47 -0
  50. package/dist/vwr/src/native/device-info/mobileCollector.js.map +1 -0
  51. package/dist/vwr/src/native/device-info/rpc.d.ts +51 -0
  52. package/dist/vwr/src/native/device-info/rpc.d.ts.map +1 -0
  53. package/dist/vwr/src/native/device-info/rpc.js +46 -0
  54. package/dist/vwr/src/native/device-info/rpc.js.map +1 -0
  55. package/dist/vwr/src/native/device-info/samsungCollector.d.ts +9 -0
  56. package/dist/vwr/src/native/device-info/samsungCollector.d.ts.map +1 -0
  57. package/dist/vwr/src/native/device-info/samsungCollector.js +86 -0
  58. package/dist/vwr/src/native/device-info/samsungCollector.js.map +1 -0
  59. package/dist/vwr/src/native/device-info/webCollector.d.ts +4 -0
  60. package/dist/vwr/src/native/device-info/webCollector.d.ts.map +1 -0
  61. package/dist/vwr/src/native/device-info/webCollector.js +56 -0
  62. package/dist/vwr/src/native/device-info/webCollector.js.map +1 -0
  63. package/dist/vwr/src/native/native-bridge/rpc.d.ts +33 -0
  64. package/dist/vwr/src/native/native-bridge/rpc.d.ts.map +1 -0
  65. package/dist/vwr/src/native/native-bridge/rpc.js +114 -0
  66. package/dist/vwr/src/native/native-bridge/rpc.js.map +1 -0
  67. package/dist/vwr/src/native/screensaver-prevention/LGLunaService.d.ts +14 -0
  68. package/dist/vwr/src/native/screensaver-prevention/LGLunaService.d.ts.map +1 -0
  69. package/dist/vwr/src/native/screensaver-prevention/LGLunaService.js +187 -0
  70. package/dist/vwr/src/native/screensaver-prevention/LGLunaService.js.map +1 -0
  71. package/dist/vwr/src/native/screensaver-prevention/rpc.d.ts +27 -0
  72. package/dist/vwr/src/native/screensaver-prevention/rpc.d.ts.map +1 -0
  73. package/dist/vwr/src/native/screensaver-prevention/rpc.js +71 -0
  74. package/dist/vwr/src/native/screensaver-prevention/rpc.js.map +1 -0
  75. package/dist/vwr/src/observability.d.ts +35 -0
  76. package/dist/vwr/src/observability.d.ts.map +1 -0
  77. package/dist/vwr/src/observability.js +68 -0
  78. package/dist/vwr/src/observability.js.map +1 -0
  79. package/dist/vwr/src/shellEnvDefaults.d.ts +15 -0
  80. package/dist/vwr/src/shellEnvDefaults.d.ts.map +1 -0
  81. package/dist/vwr/src/shellEnvDefaults.js +34 -0
  82. package/dist/vwr/src/shellEnvDefaults.js.map +1 -0
  83. package/dist/vwr/src/types.d.ts +56 -0
  84. package/dist/vwr/src/types.d.ts.map +1 -0
  85. package/dist/vwr/src/types.js +27 -0
  86. package/dist/vwr/src/types.js.map +1 -0
  87. package/dist/vwr/src/urlUtils.d.ts +17 -0
  88. package/dist/vwr/src/urlUtils.d.ts.map +1 -0
  89. package/dist/vwr/src/urlUtils.js +42 -0
  90. package/dist/vwr/src/urlUtils.js.map +1 -0
  91. package/dist/vwr/src/vwrBootstrap.d.ts +26 -0
  92. package/dist/vwr/src/vwrBootstrap.d.ts.map +1 -0
  93. package/dist/vwr/src/vwrBootstrap.js +176 -0
  94. package/dist/vwr/src/vwrBootstrap.js.map +1 -0
  95. package/dist/{vwrConfig.d.ts → vwr/src/vwrConfig.d.ts} +5 -0
  96. package/dist/vwr/src/vwrConfig.d.ts.map +1 -0
  97. package/dist/{vwrConfig.js → vwr/src/vwrConfig.js} +24 -7
  98. package/dist/vwr/src/vwrConfig.js.map +1 -0
  99. package/{src → dist/vwr-loader}/index.html +1 -1
  100. package/dist/vwr-loader/src/__mocks__/@datadog/browser-logs.d.ts.map +1 -0
  101. package/dist/vwr-loader/src/__mocks__/@datadog/browser-logs.js.map +1 -0
  102. package/dist/vwr-loader/src/__mocks__/@datadog/browser-rum.d.ts.map +1 -0
  103. package/dist/vwr-loader/src/__mocks__/@datadog/browser-rum.js.map +1 -0
  104. package/dist/vwr-loader/src/__mocks__/invalidVwrModule.d.ts +2 -0
  105. package/dist/vwr-loader/src/__mocks__/invalidVwrModule.d.ts.map +1 -0
  106. package/dist/vwr-loader/src/__mocks__/invalidVwrModule.js +2 -0
  107. package/dist/vwr-loader/src/__mocks__/invalidVwrModule.js.map +1 -0
  108. package/dist/vwr-loader/src/__mocks__/vwrModule.d.ts.map +1 -0
  109. package/dist/vwr-loader/src/__mocks__/vwrModule.js.map +1 -0
  110. package/dist/vwr-loader/src/amplitudeFlagFetcher.d.ts.map +1 -0
  111. package/dist/vwr-loader/src/amplitudeFlagFetcher.js.map +1 -0
  112. package/dist/vwr-loader/src/errors/InitializationError.d.ts.map +1 -0
  113. package/dist/vwr-loader/src/errors/InitializationError.js.map +1 -0
  114. package/dist/vwr-loader/src/errors/ensureError.d.ts.map +1 -0
  115. package/dist/vwr-loader/src/errors/ensureError.js.map +1 -0
  116. package/dist/vwr-loader/src/errors/index.d.ts.map +1 -0
  117. package/dist/vwr-loader/src/errors/index.js.map +1 -0
  118. package/dist/vwr-loader/src/exitHandler.d.ts.map +1 -0
  119. package/dist/{exitHandler.js → vwr-loader/src/exitHandler.js} +2 -3
  120. package/dist/vwr-loader/src/exitHandler.js.map +1 -0
  121. package/dist/vwr-loader/src/getEnvironment.d.ts.map +1 -0
  122. package/dist/vwr-loader/src/getEnvironment.js.map +1 -0
  123. package/dist/vwr-loader/src/getShellVersion.d.ts.map +1 -0
  124. package/dist/vwr-loader/src/getShellVersion.js.map +1 -0
  125. package/dist/vwr-loader/src/index.d.ts +8 -0
  126. package/dist/vwr-loader/src/index.d.ts.map +1 -0
  127. package/dist/vwr-loader/src/index.js +6 -0
  128. package/dist/vwr-loader/src/index.js.map +1 -0
  129. package/dist/vwr-loader/src/loadVwr.d.ts.map +1 -0
  130. package/dist/{loadVwr.js → vwr-loader/src/loadVwr.js} +36 -27
  131. package/dist/vwr-loader/src/loadVwr.js.map +1 -0
  132. package/dist/vwr-loader/src/logger.d.ts +4 -0
  133. package/dist/vwr-loader/src/logger.d.ts.map +1 -0
  134. package/dist/vwr-loader/src/logger.js +10 -0
  135. package/dist/vwr-loader/src/logger.js.map +1 -0
  136. package/dist/vwr-loader/src/main.d.ts +2 -0
  137. package/dist/vwr-loader/src/main.d.ts.map +1 -0
  138. package/dist/vwr-loader/src/main.js +96 -0
  139. package/dist/vwr-loader/src/main.js.map +1 -0
  140. package/dist/vwr-loader/src/polyfills.d.ts.map +1 -0
  141. package/dist/vwr-loader/src/polyfills.js.map +1 -0
  142. package/dist/{test-setup.d.ts.map → vwr-loader/src/test-setup.d.ts.map} +1 -1
  143. package/dist/vwr-loader/src/test-setup.js.map +1 -0
  144. package/package.json +13 -12
  145. package/dist/__mocks__/@datadog/browser-logs.d.ts.map +0 -1
  146. package/dist/__mocks__/@datadog/browser-logs.js.map +0 -1
  147. package/dist/__mocks__/@datadog/browser-rum.d.ts.map +0 -1
  148. package/dist/__mocks__/@datadog/browser-rum.js.map +0 -1
  149. package/dist/__mocks__/vwrModule.d.ts.map +0 -1
  150. package/dist/__mocks__/vwrModule.js.map +0 -1
  151. package/dist/amplitudeFlagFetcher.d.ts.map +0 -1
  152. package/dist/amplitudeFlagFetcher.js.map +0 -1
  153. package/dist/assets/profiler-BRmTNL9s.js +0 -2
  154. package/dist/assets/profiler-BRmTNL9s.js.map +0 -1
  155. package/dist/assets/startRecording-CuFdVhxx.js +0 -3
  156. package/dist/assets/startRecording-CuFdVhxx.js.map +0 -1
  157. package/dist/datadog.d.ts.map +0 -1
  158. package/dist/datadog.js.map +0 -1
  159. package/dist/envDefaults.d.ts.map +0 -1
  160. package/dist/envDefaults.js +0 -74
  161. package/dist/envDefaults.js.map +0 -1
  162. package/dist/errors/InitializationError.d.ts.map +0 -1
  163. package/dist/errors/InitializationError.js.map +0 -1
  164. package/dist/errors/ensureError.d.ts.map +0 -1
  165. package/dist/errors/ensureError.js.map +0 -1
  166. package/dist/errors/index.d.ts.map +0 -1
  167. package/dist/errors/index.js.map +0 -1
  168. package/dist/exitHandler.d.ts.map +0 -1
  169. package/dist/exitHandler.js.map +0 -1
  170. package/dist/getDeviceId.d.ts +0 -26
  171. package/dist/getDeviceId.d.ts.map +0 -1
  172. package/dist/getDeviceId.js +0 -209
  173. package/dist/getDeviceId.js.map +0 -1
  174. package/dist/getEnvironment.d.ts.map +0 -1
  175. package/dist/getEnvironment.js.map +0 -1
  176. package/dist/getShellVersion.d.ts.map +0 -1
  177. package/dist/getShellVersion.js.map +0 -1
  178. package/dist/index.d.ts +0 -8
  179. package/dist/index.d.ts.map +0 -1
  180. package/dist/index.html +0 -25
  181. package/dist/index.js +0 -6
  182. package/dist/index.js.map +0 -1
  183. package/dist/loadVwr.d.ts.map +0 -1
  184. package/dist/loadVwr.js.map +0 -1
  185. package/dist/logger.d.ts +0 -12
  186. package/dist/logger.d.ts.map +0 -1
  187. package/dist/logger.js.map +0 -1
  188. package/dist/main.js +0 -12
  189. package/dist/main.js.map +0 -1
  190. package/dist/polyfills.d.ts.map +0 -1
  191. package/dist/polyfills.js.map +0 -1
  192. package/dist/test-setup.js.map +0 -1
  193. package/dist/types.d.ts +0 -103
  194. package/dist/types.d.ts.map +0 -1
  195. package/dist/types.js +0 -5
  196. package/dist/types.js.map +0 -1
  197. package/dist/vwrConfig.d.ts.map +0 -1
  198. package/dist/vwrConfig.js.map +0 -1
  199. package/src/__mocks__/@datadog/browser-logs.ts +0 -35
  200. package/src/__mocks__/@datadog/browser-rum.ts +0 -27
  201. package/src/__mocks__/vwrModule.ts +0 -3
  202. package/src/amplitudeFlagFetcher.test.ts +0 -175
  203. package/src/amplitudeFlagFetcher.ts +0 -105
  204. package/src/datadog.ts +0 -55
  205. package/src/envDefaults.ts +0 -94
  206. package/src/errors/InitializationError.ts +0 -105
  207. package/src/errors/ensureError.ts +0 -6
  208. package/src/errors/index.ts +0 -16
  209. package/src/exitHandler.test.ts +0 -373
  210. package/src/exitHandler.ts +0 -232
  211. package/src/getDeviceId.test.ts +0 -298
  212. package/src/getDeviceId.ts +0 -224
  213. package/src/getEnvironment.test.ts +0 -417
  214. package/src/getEnvironment.ts +0 -144
  215. package/src/getShellVersion.test.ts +0 -403
  216. package/src/getShellVersion.ts +0 -132
  217. package/src/index.ts +0 -7
  218. package/src/loadVwr.test.ts +0 -549
  219. package/src/loadVwr.ts +0 -357
  220. package/src/logger.ts +0 -121
  221. package/src/main.test.ts +0 -157
  222. package/src/main.ts +0 -127
  223. package/src/polyfills.ts +0 -32
  224. package/src/test-setup.ts +0 -5
  225. package/src/types.ts +0 -105
  226. package/src/vite-env.d.ts +0 -32
  227. package/src/vwrConfig.test.ts +0 -386
  228. package/src/vwrConfig.ts +0 -374
  229. /package/dist/{__mocks__ → vwr-loader/src/__mocks__}/@datadog/browser-logs.d.ts +0 -0
  230. /package/dist/{__mocks__ → vwr-loader/src/__mocks__}/@datadog/browser-logs.js +0 -0
  231. /package/dist/{__mocks__ → vwr-loader/src/__mocks__}/@datadog/browser-rum.d.ts +0 -0
  232. /package/dist/{__mocks__ → vwr-loader/src/__mocks__}/@datadog/browser-rum.js +0 -0
  233. /package/dist/{__mocks__ → vwr-loader/src/__mocks__}/vwrModule.d.ts +0 -0
  234. /package/dist/{__mocks__ → vwr-loader/src/__mocks__}/vwrModule.js +0 -0
  235. /package/dist/{amplitudeFlagFetcher.d.ts → vwr-loader/src/amplitudeFlagFetcher.d.ts} +0 -0
  236. /package/dist/{amplitudeFlagFetcher.js → vwr-loader/src/amplitudeFlagFetcher.js} +0 -0
  237. /package/dist/{errors → vwr-loader/src/errors}/InitializationError.d.ts +0 -0
  238. /package/dist/{errors → vwr-loader/src/errors}/InitializationError.js +0 -0
  239. /package/dist/{errors → vwr-loader/src/errors}/ensureError.d.ts +0 -0
  240. /package/dist/{errors → vwr-loader/src/errors}/ensureError.js +0 -0
  241. /package/dist/{errors → vwr-loader/src/errors}/index.d.ts +0 -0
  242. /package/dist/{errors → vwr-loader/src/errors}/index.js +0 -0
  243. /package/dist/{exitHandler.d.ts → vwr-loader/src/exitHandler.d.ts} +0 -0
  244. /package/dist/{getEnvironment.d.ts → vwr-loader/src/getEnvironment.d.ts} +0 -0
  245. /package/dist/{getEnvironment.js → vwr-loader/src/getEnvironment.js} +0 -0
  246. /package/dist/{getShellVersion.d.ts → vwr-loader/src/getShellVersion.d.ts} +0 -0
  247. /package/dist/{getShellVersion.js → vwr-loader/src/getShellVersion.js} +0 -0
  248. /package/dist/{loadVwr.d.ts → vwr-loader/src/loadVwr.d.ts} +0 -0
  249. /package/dist/{polyfills.d.ts → vwr-loader/src/polyfills.d.ts} +0 -0
  250. /package/dist/{polyfills.js → vwr-loader/src/polyfills.js} +0 -0
  251. /package/dist/{test-setup.d.ts → vwr-loader/src/test-setup.d.ts} +0 -0
  252. /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
- })