@aguacerowx/react-native 0.0.53 → 0.0.54

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 (261) hide show
  1. package/LICENSE +21 -0
  2. package/android/src/main/java/com/aguacerowx/reactnative/NexradRadarLayerView.java +14 -2
  3. package/android/src/main/java/com/aguacerowx/reactnative/WeatherFrameProcessorModule.java +77 -0
  4. package/index.js +1 -1
  5. package/ios/WeatherFrameProcessorModule.m +19 -15
  6. package/ios/WeatherFrameProcessorModule.swift +65 -0
  7. package/lib/commonjs/AguaceroContext.js +0 -4
  8. package/lib/commonjs/AguaceroContext.js.map +1 -1
  9. package/lib/commonjs/GridRenderLayer.js +62 -76
  10. package/lib/commonjs/GridRenderLayer.js.map +1 -1
  11. package/lib/commonjs/MapManager.js +110 -224
  12. package/lib/commonjs/MapManager.js.map +1 -1
  13. package/lib/commonjs/MapRegistry.js +21 -33
  14. package/lib/commonjs/MapRegistry.js.map +1 -1
  15. package/lib/commonjs/NexradRadarLayer.android.js +28 -100
  16. package/lib/commonjs/NexradRadarLayer.android.js.map +1 -1
  17. package/lib/commonjs/NexradRadarLayer.ios.js +26 -97
  18. package/lib/commonjs/NexradRadarLayer.ios.js.map +1 -1
  19. package/lib/commonjs/NexradSitesMapLayer.js +41 -61
  20. package/lib/commonjs/NexradSitesMapLayer.js.map +1 -1
  21. package/lib/commonjs/SatelliteLayer.android.js +26 -38
  22. package/lib/commonjs/SatelliteLayer.android.js.map +1 -1
  23. package/lib/commonjs/SatelliteLayer.ios.js +30 -42
  24. package/lib/commonjs/SatelliteLayer.ios.js.map +1 -1
  25. package/lib/commonjs/StyleApplicator.js +129 -175
  26. package/lib/commonjs/StyleApplicator.js.map +1 -1
  27. package/lib/commonjs/WeatherLayerManager.js +995 -1646
  28. package/lib/commonjs/WeatherLayerManager.js.map +1 -1
  29. package/lib/commonjs/aguaceroCoreDebugHooks.js +58 -130
  30. package/lib/commonjs/aguaceroCoreDebugHooks.js.map +1 -1
  31. package/lib/commonjs/aguaceroRnDebug.js +147 -288
  32. package/lib/commonjs/aguaceroRnDebug.js.map +1 -1
  33. package/lib/commonjs/cdnAuthenticatedFetch.js +104 -0
  34. package/lib/commonjs/cdnAuthenticatedFetch.js.map +1 -0
  35. package/lib/commonjs/dispatchViewManagerCommandCompat.js +51 -88
  36. package/lib/commonjs/dispatchViewManagerCommandCompat.js.map +1 -1
  37. package/lib/commonjs/gridCdnAuth.js +41 -50
  38. package/lib/commonjs/gridCdnAuth.js.map +1 -1
  39. package/lib/commonjs/index.js +14 -0
  40. package/lib/commonjs/index.js.map +1 -1
  41. package/lib/commonjs/nexrad/nexradAndroidController.js +851 -863
  42. package/lib/commonjs/nexrad/nexradAndroidController.js.map +1 -1
  43. package/lib/commonjs/nexrad/nexradCrossSectionSampleAtLatLon.bundled.js +62 -85
  44. package/lib/commonjs/nexrad/nexradCrossSectionSampleAtLatLon.bundled.js.map +1 -1
  45. package/lib/commonjs/nexrad/nexradDiag.js +32 -148
  46. package/lib/commonjs/nexrad/nexradDiag.js.map +1 -1
  47. package/lib/commonjs/nexrad/nexradLevel2Keys.js +261 -0
  48. package/lib/commonjs/nexrad/nexradLevel2Keys.js.map +1 -0
  49. package/lib/commonjs/nexrad/nexradLutBuild.js +64 -111
  50. package/lib/commonjs/nexrad/nexradLutBuild.js.map +1 -1
  51. package/lib/commonjs/nexrad/nexradMapboxFrameOpts.bundled.js +136 -164
  52. package/lib/commonjs/nexrad/nexradMapboxFrameOpts.bundled.js.map +1 -1
  53. package/lib/commonjs/nexrad/nexradSdkImports.js +51 -0
  54. package/lib/commonjs/nexrad/nexradSdkImports.js.map +1 -0
  55. package/lib/commonjs/nexrad/radarArchiveCore.bundled.js +2848 -4455
  56. package/lib/commonjs/nexrad/radarArchiveCore.bundled.js.map +1 -1
  57. package/lib/commonjs/nexrad/radarDecode.worker.bundled.js +445 -648
  58. package/lib/commonjs/nexrad/radarDecode.worker.bundled.js.map +1 -1
  59. package/lib/commonjs/nexrad/radarFrameGpuMatch.bundled.js +52 -68
  60. package/lib/commonjs/nexrad/radarFrameGpuMatch.bundled.js.map +1 -1
  61. package/lib/commonjs/nexradNativeCommandIds.js +24 -0
  62. package/lib/commonjs/nexradNativeCommandIds.js.map +1 -0
  63. package/lib/commonjs/nws/NwsAlertsOverlay.android.js.map +1 -1
  64. package/lib/commonjs/nws/NwsAlertsOverlay.ios.js.map +1 -1
  65. package/lib/commonjs/nws/NwsAlertsOverlay.js +3 -3
  66. package/lib/commonjs/nws/NwsAlertsOverlay.js.map +1 -1
  67. package/lib/commonjs/nws/NwsAlertsOverlay.native.js +235 -361
  68. package/lib/commonjs/nws/NwsAlertsOverlay.native.js.map +1 -1
  69. package/lib/commonjs/nws/eventSourceRnPolyfill.js +92 -146
  70. package/lib/commonjs/nws/eventSourceRnPolyfill.js.map +1 -1
  71. package/lib/commonjs/nws/nwsAndroidConstants.js +2 -8
  72. package/lib/commonjs/nws/nwsAndroidConstants.js.map +1 -1
  73. package/lib/commonjs/satellite/satelliteAndroidController.js +117 -202
  74. package/lib/commonjs/satellite/satelliteAndroidController.js.map +1 -1
  75. package/lib/commonjs/satelliteBridgeDiag.js +3 -13
  76. package/lib/commonjs/satelliteBridgeDiag.js.map +1 -1
  77. package/lib/commonjs/satelliteRnDebug.js +117 -218
  78. package/lib/commonjs/satelliteRnDebug.js.map +1 -1
  79. package/lib/module/AguaceroContext.js +2 -7
  80. package/lib/module/AguaceroContext.js.map +1 -1
  81. package/lib/module/GridRenderLayer.js +66 -80
  82. package/lib/module/GridRenderLayer.js.map +1 -1
  83. package/lib/module/MapManager.js +125 -239
  84. package/lib/module/MapManager.js.map +1 -1
  85. package/lib/module/MapRegistry.js +21 -33
  86. package/lib/module/MapRegistry.js.map +1 -1
  87. package/lib/module/NexradRadarLayer.android.js +32 -104
  88. package/lib/module/NexradRadarLayer.android.js.map +1 -1
  89. package/lib/module/NexradRadarLayer.ios.js +30 -101
  90. package/lib/module/NexradRadarLayer.ios.js.map +1 -1
  91. package/lib/module/NexradSitesMapLayer.js +44 -63
  92. package/lib/module/NexradSitesMapLayer.js.map +1 -1
  93. package/lib/module/SatelliteLayer.android.js +32 -44
  94. package/lib/module/SatelliteLayer.android.js.map +1 -1
  95. package/lib/module/SatelliteLayer.ios.js +36 -48
  96. package/lib/module/SatelliteLayer.ios.js.map +1 -1
  97. package/lib/module/StyleApplicator.js +144 -191
  98. package/lib/module/StyleApplicator.js.map +1 -1
  99. package/lib/module/WeatherLayerManager.js +1024 -1675
  100. package/lib/module/WeatherLayerManager.js.map +1 -1
  101. package/lib/module/aguaceroCoreDebugHooks.js +59 -130
  102. package/lib/module/aguaceroCoreDebugHooks.js.map +1 -1
  103. package/lib/module/aguaceroRnDebug.js +151 -292
  104. package/lib/module/aguaceroRnDebug.js.map +1 -1
  105. package/lib/module/cdnAuthenticatedFetch.js +97 -0
  106. package/lib/module/cdnAuthenticatedFetch.js.map +1 -0
  107. package/lib/module/dispatchViewManagerCommandCompat.js +52 -90
  108. package/lib/module/dispatchViewManagerCommandCompat.js.map +1 -1
  109. package/lib/module/gridCdnAuth.js +38 -50
  110. package/lib/module/gridCdnAuth.js.map +1 -1
  111. package/lib/module/index.js +9 -7
  112. package/lib/module/index.js.map +1 -1
  113. package/lib/module/nexrad/nexradAndroidController.js +865 -876
  114. package/lib/module/nexrad/nexradAndroidController.js.map +1 -1
  115. package/lib/module/nexrad/nexradCrossSectionSampleAtLatLon.bundled.js +62 -85
  116. package/lib/module/nexrad/nexradCrossSectionSampleAtLatLon.bundled.js.map +1 -1
  117. package/lib/module/nexrad/nexradDiag.js +31 -145
  118. package/lib/module/nexrad/nexradDiag.js.map +1 -1
  119. package/lib/module/nexrad/nexradLevel2Keys.js +245 -0
  120. package/lib/module/nexrad/nexradLevel2Keys.js.map +1 -0
  121. package/lib/module/nexrad/nexradLutBuild.js +64 -110
  122. package/lib/module/nexrad/nexradLutBuild.js.map +1 -1
  123. package/lib/module/nexrad/nexradMapboxFrameOpts.bundled.js +136 -163
  124. package/lib/module/nexrad/nexradMapboxFrameOpts.bundled.js.map +1 -1
  125. package/lib/module/nexrad/nexradSdkImports.js +4 -0
  126. package/lib/module/nexrad/nexradSdkImports.js.map +1 -0
  127. package/lib/module/nexrad/radarArchiveCore.bundled.js +2839 -4448
  128. package/lib/module/nexrad/radarArchiveCore.bundled.js.map +1 -1
  129. package/lib/module/nexrad/radarDecode.worker.bundled.js +445 -648
  130. package/lib/module/nexrad/radarDecode.worker.bundled.js.map +1 -1
  131. package/lib/module/nexrad/radarFrameGpuMatch.bundled.js +50 -66
  132. package/lib/module/nexrad/radarFrameGpuMatch.bundled.js.map +1 -1
  133. package/lib/module/nexradNativeCommandIds.js +18 -0
  134. package/lib/module/nexradNativeCommandIds.js.map +1 -0
  135. package/lib/module/nws/NwsAlertsOverlay.android.js +1 -1
  136. package/lib/module/nws/NwsAlertsOverlay.android.js.map +1 -1
  137. package/lib/module/nws/NwsAlertsOverlay.ios.js +1 -1
  138. package/lib/module/nws/NwsAlertsOverlay.ios.js.map +1 -1
  139. package/lib/module/nws/NwsAlertsOverlay.js +5 -5
  140. package/lib/module/nws/NwsAlertsOverlay.js.map +1 -1
  141. package/lib/module/nws/NwsAlertsOverlay.native.js +248 -373
  142. package/lib/module/nws/NwsAlertsOverlay.native.js.map +1 -1
  143. package/lib/module/nws/eventSourceRnPolyfill.js +92 -146
  144. package/lib/module/nws/eventSourceRnPolyfill.js.map +1 -1
  145. package/lib/module/nws/nwsAndroidConstants.js +2 -8
  146. package/lib/module/nws/nwsAndroidConstants.js.map +1 -1
  147. package/lib/module/satellite/satelliteAndroidController.js +123 -208
  148. package/lib/module/satellite/satelliteAndroidController.js.map +1 -1
  149. package/lib/module/satelliteBridgeDiag.js +3 -13
  150. package/lib/module/satelliteBridgeDiag.js.map +1 -1
  151. package/lib/module/satelliteRnDebug.js +123 -223
  152. package/lib/module/satelliteRnDebug.js.map +1 -1
  153. package/lib/typescript/AguaceroContext.d.ts +0 -4
  154. package/lib/typescript/AguaceroContext.d.ts.map +1 -1
  155. package/lib/typescript/GridRenderLayer.d.ts.map +1 -1
  156. package/lib/typescript/MapManager.d.ts +0 -12
  157. package/lib/typescript/MapManager.d.ts.map +1 -1
  158. package/lib/typescript/MapRegistry.d.ts +10 -12
  159. package/lib/typescript/MapRegistry.d.ts.map +1 -1
  160. package/lib/typescript/NexradRadarLayer.android.d.ts.map +1 -1
  161. package/lib/typescript/NexradRadarLayer.ios.d.ts.map +1 -1
  162. package/lib/typescript/NexradSitesMapLayer.d.ts +4 -10
  163. package/lib/typescript/NexradSitesMapLayer.d.ts.map +1 -1
  164. package/lib/typescript/SatelliteLayer.android.d.ts.map +1 -1
  165. package/lib/typescript/SatelliteLayer.ios.d.ts.map +1 -1
  166. package/lib/typescript/StyleApplicator.d.ts +1 -1
  167. package/lib/typescript/StyleApplicator.d.ts.map +1 -1
  168. package/lib/typescript/WeatherLayerManager.d.ts.map +1 -1
  169. package/lib/typescript/aguaceroCoreDebugHooks.d.ts +2 -9
  170. package/lib/typescript/aguaceroCoreDebugHooks.d.ts.map +1 -1
  171. package/lib/typescript/aguaceroRnDebug.d.ts +47 -66
  172. package/lib/typescript/aguaceroRnDebug.d.ts.map +1 -1
  173. package/lib/typescript/cdnAuthenticatedFetch.d.ts +10 -0
  174. package/lib/typescript/cdnAuthenticatedFetch.d.ts.map +1 -0
  175. package/lib/typescript/dispatchViewManagerCommandCompat.d.ts +1 -17
  176. package/lib/typescript/dispatchViewManagerCommandCompat.d.ts.map +1 -1
  177. package/lib/typescript/gridCdnAuth.d.ts +16 -21
  178. package/lib/typescript/gridCdnAuth.d.ts.map +1 -1
  179. package/lib/typescript/index.d.ts +1 -0
  180. package/lib/typescript/nexrad/nexradAndroidController.d.ts +39 -89
  181. package/lib/typescript/nexrad/nexradAndroidController.d.ts.map +1 -1
  182. package/lib/typescript/nexrad/nexradCrossSectionSampleAtLatLon.bundled.d.ts +2 -1
  183. package/lib/typescript/nexrad/nexradCrossSectionSampleAtLatLon.bundled.d.ts.map +1 -1
  184. package/lib/typescript/nexrad/nexradDiag.d.ts +13 -101
  185. package/lib/typescript/nexrad/nexradDiag.d.ts.map +1 -1
  186. package/lib/typescript/nexrad/nexradLevel2Keys.d.ts +36 -0
  187. package/lib/typescript/nexrad/nexradLevel2Keys.d.ts.map +1 -0
  188. package/lib/typescript/nexrad/nexradLutBuild.d.ts +3 -10
  189. package/lib/typescript/nexrad/nexradLutBuild.d.ts.map +1 -1
  190. package/lib/typescript/nexrad/nexradMapboxFrameOpts.bundled.d.ts +4 -3
  191. package/lib/typescript/nexrad/nexradMapboxFrameOpts.bundled.d.ts.map +1 -1
  192. package/lib/typescript/nexrad/nexradSdkImports.d.ts +2 -0
  193. package/lib/typescript/nexrad/nexradSdkImports.d.ts.map +1 -0
  194. package/lib/typescript/nexrad/radarArchiveCore.bundled.d.ts +12 -7
  195. package/lib/typescript/nexrad/radarArchiveCore.bundled.d.ts.map +1 -1
  196. package/lib/typescript/nexrad/radarDecode.worker.bundled.d.ts +20 -20
  197. package/lib/typescript/nexrad/radarDecode.worker.bundled.d.ts.map +1 -1
  198. package/lib/typescript/nexrad/radarFrameGpuMatch.bundled.d.ts +4 -3
  199. package/lib/typescript/nexrad/radarFrameGpuMatch.bundled.d.ts.map +1 -1
  200. package/lib/typescript/nexradNativeCommandIds.d.ts +2 -0
  201. package/lib/typescript/nexradNativeCommandIds.d.ts.map +1 -0
  202. package/lib/typescript/nws/NwsAlertsOverlay.native.d.ts +6 -17
  203. package/lib/typescript/nws/NwsAlertsOverlay.native.d.ts.map +1 -1
  204. package/lib/typescript/nws/eventSourceRnPolyfill.d.ts +0 -3
  205. package/lib/typescript/nws/eventSourceRnPolyfill.d.ts.map +1 -1
  206. package/lib/typescript/nws/nwsAndroidConstants.d.ts +0 -5
  207. package/lib/typescript/nws/nwsAndroidConstants.d.ts.map +1 -1
  208. package/lib/typescript/satellite/satelliteAndroidController.d.ts +9 -47
  209. package/lib/typescript/satellite/satelliteAndroidController.d.ts.map +1 -1
  210. package/lib/typescript/satelliteBridgeDiag.d.ts +1 -5
  211. package/lib/typescript/satelliteBridgeDiag.d.ts.map +1 -1
  212. package/lib/typescript/satelliteRnDebug.d.ts +24 -30
  213. package/lib/typescript/satelliteRnDebug.d.ts.map +1 -1
  214. package/package.json +75 -74
  215. package/src/AguaceroContext.js +1 -7
  216. package/src/GridRenderLayer.js +1 -128
  217. package/src/MapManager.js +1 -277
  218. package/src/MapRegistry.js +1 -56
  219. package/src/NexradRadarLayer.android.js +1 -121
  220. package/src/NexradRadarLayer.ios.js +1 -115
  221. package/src/NexradSitesMapLayer.js +1 -75
  222. package/src/SatelliteLayer.android.js +1 -63
  223. package/src/SatelliteLayer.ios.js +1 -70
  224. package/src/StyleApplicator.js +1 -241
  225. package/src/WeatherLayerManager.js +1 -2045
  226. package/src/aguaceroCoreDebugHooks.js +1 -142
  227. package/src/aguaceroRnDebug.js +1 -336
  228. package/src/cdnAuthenticatedFetch.js +1 -0
  229. package/src/dispatchViewManagerCommandCompat.js +1 -100
  230. package/src/gridCdnAuth.js +1 -56
  231. package/src/index.js +1 -27
  232. package/src/nexrad/nexradAndroidController.js +1 -1078
  233. package/src/nexrad/nexradCrossSectionSampleAtLatLon.bundled.js +1 -91
  234. package/src/nexrad/nexradDiag.js +1 -150
  235. package/src/nexrad/nexradLevel2Keys.js +1 -0
  236. package/src/nexrad/nexradLutBuild.js +1 -126
  237. package/src/nexrad/nexradMapboxFrameOpts.bundled.js +1 -245
  238. package/src/nexrad/nexradSdkImports.js +1 -0
  239. package/src/nexrad/radarArchiveCore.bundled.js +1 -7085
  240. package/src/nexrad/radarDecode.worker.bundled.js +1 -813
  241. package/src/nexrad/radarFrameGpuMatch.bundled.js +1 -79
  242. package/src/nexradNativeCommandIds.js +1 -0
  243. package/src/nws/NwsAlertsOverlay.android.js +1 -1
  244. package/src/nws/NwsAlertsOverlay.ios.js +1 -1
  245. package/src/nws/NwsAlertsOverlay.js +1 -7
  246. package/src/nws/NwsAlertsOverlay.native.js +1 -463
  247. package/src/nws/eventSourceRnPolyfill.js +7 -193
  248. package/src/nws/nwsAndroidConstants.js +1 -8
  249. package/src/satellite/satelliteAndroidController.js +1 -257
  250. package/src/satelliteBridgeDiag.js +1 -15
  251. package/src/satelliteRnDebug.js +1 -269
  252. package/lib/commonjs/nexrad/nexradNativeCommandIds.js +0 -51
  253. package/lib/commonjs/nexrad/nexradNativeCommandIds.js.map +0 -1
  254. package/lib/module/nexrad/nexradNativeCommandIds.js +0 -44
  255. package/lib/module/nexrad/nexradNativeCommandIds.js.map +0 -1
  256. package/lib/typescript/nexrad/nexradNativeCommandIds.d.ts +0 -9
  257. package/lib/typescript/nexrad/nexradNativeCommandIds.d.ts.map +0 -1
  258. package/src/nexrad/nexradNativeCommandIds.js +0 -44
  259. /package/lib/commonjs/{nexrad/nexradSitesUs.json → nexradSitesUs.json} +0 -0
  260. /package/lib/module/{nexrad/nexradSitesUs.json → nexradSitesUs.json} +0 -0
  261. /package/src/{nexrad/nexradSitesUs.json → nexradSitesUs.json} +0 -0
@@ -1,142 +1 @@
1
- /**
2
- * Per-core hooks for {@link AguaceroCore} when RN debug is enabled.
3
- */
4
- import {
5
- aguaceroDebug,
6
- aguaceroDebugWarn,
7
- getAguaceroAuthDiagnosticSnapshot,
8
- isAguaceroRnDebugEnabled,
9
- redactApiKeyFromUrl,
10
- } from './aguaceroRnDebug';
11
-
12
- const HOOK_FLAG = '__aguaceroRnDebugHooksInstalled';
13
-
14
- /**
15
- * @param {import('@aguacerowx/javascript-sdk').AguaceroCore} core
16
- * @param {Record<string, unknown>} [extra]
17
- */
18
- export function installAguaceroCoreDebugHooks(core, extra = {}) {
19
- if (!core || !isAguaceroRnDebugEnabled() || core[HOOK_FLAG]) {
20
- return;
21
- }
22
- core[HOOK_FLAG] = true;
23
-
24
- aguaceroDebug('core.created', getAguaceroAuthDiagnosticSnapshot(core, extra));
25
-
26
- if (typeof core.initialize === 'function' && !core.__aguaceroOrigInitialize) {
27
- core.__aguaceroOrigInitialize = core.initialize.bind(core);
28
- core.initialize = async function aguaceroDebugInitialize(options) {
29
- aguaceroDebug('core.initialize.start', {
30
- stateMode: {
31
- isMRMS: core.state?.isMRMS,
32
- isSatellite: core.state?.isSatellite,
33
- isNexrad: core.state?.isNexrad,
34
- model: core.state?.model,
35
- variable: core.state?.variable,
36
- },
37
- });
38
- try {
39
- await core.__aguaceroOrigInitialize(options);
40
- aguaceroDebug('core.initialize.done', {
41
- hasModelStatus: Boolean(core.modelStatus),
42
- hasMrmsStatus: Boolean(core.mrmsStatus),
43
- hasSatelliteListing: Boolean(core.satelliteListing),
44
- mrmsVariableCount: core.mrmsStatus ? Object.keys(core.mrmsStatus).length : 0,
45
- });
46
- } catch (err) {
47
- aguaceroDebugWarn('core.initialize.error', { message: err?.message || String(err) });
48
- throw err;
49
- }
50
- };
51
- }
52
-
53
- if (typeof core._loadGridData === 'function' && !core.__aguaceroOrigLoadGridData) {
54
- core.__aguaceroOrigLoadGridData = core._loadGridData.bind(core);
55
- core._loadGridData = async function aguaceroDebugLoadGridData(state) {
56
- const tag = 'core._loadGridData';
57
- aguaceroDebug(`${tag}.start`, {
58
- isMRMS: state?.isMRMS,
59
- model: state?.model,
60
- variable: state?.variable,
61
- mrmsTimestamp: state?.mrmsTimestamp,
62
- forecastHour: state?.forecastHour,
63
- auth: getAguaceroAuthDiagnosticSnapshot(core),
64
- });
65
- const result = await core.__aguaceroOrigLoadGridData(state);
66
- if (result == null) {
67
- aguaceroDebugWarn(`${tag}.null`, {
68
- hint: 'Grid load returned null — often failed fetch (check fetch.httpError above) or missing apiKey',
69
- });
70
- } else {
71
- aguaceroDebug(`${tag}.ok`, {
72
- hasData: Boolean(result?.data),
73
- encodingKeys: result?.encoding ? Object.keys(result.encoding) : [],
74
- });
75
- }
76
- return result;
77
- };
78
- }
79
-
80
- if (typeof core.refreshNexradTimes === 'function' && !core.__aguaceroOrigRefreshNexradTimes) {
81
- core.__aguaceroOrigRefreshNexradTimes = core.refreshNexradTimes.bind(core);
82
- core.refreshNexradTimes = async function aguaceroDebugRefreshNexradTimes() {
83
- aguaceroDebug('core.refreshNexradTimes.start', {
84
- site: core.state?.nexradSite,
85
- product: core.state?.nexradProduct,
86
- dataSource: core.state?.nexradDataSource,
87
- });
88
- try {
89
- const out = await core.__aguaceroOrigRefreshNexradTimes();
90
- aguaceroDebug('core.refreshNexradTimes.done', {
91
- timesCount: out?.unixTimes?.length ?? 0,
92
- });
93
- return out;
94
- } catch (err) {
95
- aguaceroDebugWarn('core.refreshNexradTimes.error', { message: err?.message || String(err) });
96
- throw err;
97
- }
98
- };
99
- }
100
-
101
- if (typeof core.setState === 'function' && !core.__aguaceroOrigSetState) {
102
- core.__aguaceroOrigSetState = core.setState.bind(core);
103
- core.setState = async function aguaceroDebugSetState(patch) {
104
- const modeChange =
105
- patch &&
106
- ('isMRMS' in patch || 'isSatellite' in patch || 'isNexrad' in patch || 'variable' in patch);
107
- if (modeChange) {
108
- aguaceroDebug('core.setState.modePatch', {
109
- keys: Object.keys(patch || {}),
110
- patch: { ...patch, apiKey: undefined },
111
- });
112
- }
113
- return core.__aguaceroOrigSetState(patch);
114
- };
115
- }
116
- }
117
-
118
- /**
119
- * @param {import('@aguacerowx/javascript-sdk').AguaceroCore} core
120
- */
121
- export function logProcessFrameAuthMismatch(core, options, context = {}) {
122
- if (!isAguaceroRnDebugEnabled() || !core || !options) return;
123
- const mismatches = [];
124
- if (options.apiKey && core.apiKey && options.apiKey !== core.apiKey) {
125
- mismatches.push('processFrame.apiKey !== core.apiKey');
126
- }
127
- if (options.bundleId !== undefined && options.bundleId !== core.bundleId) {
128
- mismatches.push('processFrame.bundleId !== core.bundleId');
129
- }
130
- const optOrigin = options.gridRequestSiteOrigin || '';
131
- const coreOrigin = core.gridRequestSiteOrigin || '';
132
- if (String(optOrigin) !== String(coreOrigin)) {
133
- mismatches.push('processFrame.gridRequestSiteOrigin !== core.gridRequestSiteOrigin');
134
- }
135
- if (mismatches.length > 0) {
136
- aguaceroDebugWarn('auth.mismatch', {
137
- mismatches,
138
- processFrameUrl: redactApiKeyFromUrl(options.url),
139
- ...context,
140
- });
141
- }
142
- }
1
+ import{aguaceroDebug as s,aguaceroDebugWarn as o,getAguaceroAuthDiagnosticSnapshot as n,isAguaceroRnDebugEnabled as c,redactApiKeyFromUrl as d}from"./aguaceroRnDebug";const u="__aguaceroRnDebugHooksInstalled";export function installAguaceroCoreDebugHooks(a,e={}){!a||!c()||a[u]||(a[u]=!0,s("core.created",n(a,e)),typeof a.initialize=="function"&&!a.__aguaceroOrigInitialize&&(a.__aguaceroOrigInitialize=a.initialize.bind(a),a.initialize=async function(i){s("core.initialize.start",{stateMode:{isMRMS:a.state?.isMRMS,isSatellite:a.state?.isSatellite,isNexrad:a.state?.isNexrad,model:a.state?.model,variable:a.state?.variable}});try{await a.__aguaceroOrigInitialize(i),s("core.initialize.done",{hasModelStatus:!!a.modelStatus,hasMrmsStatus:!!a.mrmsStatus,hasSatelliteListing:!!a.satelliteListing,mrmsVariableCount:a.mrmsStatus?Object.keys(a.mrmsStatus).length:0})}catch(t){throw o("core.initialize.error",{message:t?.message||String(t)}),t}}),typeof a._loadGridData=="function"&&!a.__aguaceroOrigLoadGridData&&(a.__aguaceroOrigLoadGridData=a._loadGridData.bind(a),a._loadGridData=async function(i){const t="core._loadGridData";s(`${t}.start`,{isMRMS:i?.isMRMS,model:i?.model,variable:i?.variable,mrmsTimestamp:i?.mrmsTimestamp,forecastHour:i?.forecastHour,auth:n(a)});const r=await a.__aguaceroOrigLoadGridData(i);return r==null?o(`${t}.null`,{hint:"Grid load returned null \u2014 often failed fetch (check fetch.httpError above) or missing apiKey"}):s(`${t}.ok`,{hasData:!!r?.data,encodingKeys:r?.encoding?Object.keys(r.encoding):[]}),r}),typeof a.setState=="function"&&!a.__aguaceroOrigSetState&&(a.__aguaceroOrigSetState=a.setState.bind(a),a.setState=async function(i){return i&&("isMRMS"in i||"isSatellite"in i||"isNexrad"in i||"variable"in i)&&s("core.setState.modePatch",{keys:Object.keys(i||{}),patch:{...i,apiKey:void 0}}),a.__aguaceroOrigSetState(i)}))}export function logProcessFrameAuthMismatch(a,e,i={}){if(!c()||!a||!e)return;const t=[];e.apiKey&&a.apiKey&&e.apiKey!==a.apiKey&&t.push("processFrame.apiKey !== core.apiKey"),e.bundleId!==void 0&&e.bundleId!==a.bundleId&&t.push("processFrame.bundleId !== core.bundleId");const r=e.gridRequestSiteOrigin||"",l=a.gridRequestSiteOrigin||"";String(r)!==String(l)&&t.push("processFrame.gridRequestSiteOrigin !== core.gridRequestSiteOrigin"),t.length>0&&o("auth.mismatch",{mismatches:t,processFrameUrl:d(e.url),...i})}
@@ -1,336 +1 @@
1
- /**
2
- * React Native SDK auth / HTTP diagnostics.
3
- *
4
- * Enable in your app (pick one):
5
- *
6
- * 1. **Recommended** — pass `debug={true}` on {@link WeatherLayerManager}:
7
- * ```jsx
8
- * <WeatherLayerManager apiKey={key} debug gridRequestSiteOrigin="https://your-allowed-origin.com" />
9
- * ```
10
- *
11
- * 2. **Global** — before rendering weather (works in release builds):
12
- * ```js
13
- * import { configureAguaceroRnDebug } from '@aguacerowx/react-native';
14
- * configureAguaceroRnDebug({ enabled: true });
15
- * ```
16
- * or: `globalThis.__AGUACERO_DEBUG__ = true` in your entry file.
17
- *
18
- * Logs use the prefix `[AguaceroRN][debug]` (Metro, Xcode, Logcat).
19
- * Satellite imagery: also filter `[AguaceroRN][satellite]` and native `AguaceroSatelliteDiagnostic` events.
20
- * API keys are never printed in full — only length, fingerprint, and whitespace hints.
21
- */
22
-
23
- import { Platform } from 'react-native';
24
- import { resolveGridRequestSiteOrigin } from './gridCdnAuth';
25
-
26
- const LOG_PREFIX = '[AguaceroRN][debug]';
27
-
28
- /** @type {boolean | null} */
29
- let _explicitEnabled = null;
30
-
31
- let _fetchLoggerInstalled = false;
32
- let _fetchSeq = 0;
33
-
34
- const AGUACERO_URL_MARKERS = [
35
- 'cloudfront.net',
36
- 'lambda-url.us-east-2.on.aws',
37
- 'amazonaws.com',
38
- 'noaa.gov',
39
- ];
40
-
41
- /**
42
- * @param {boolean} enabled
43
- */
44
- export function setAguaceroRnDebugEnabled(enabled) {
45
- configureAguaceroRnDebug({ enabled: Boolean(enabled) });
46
- }
47
-
48
- /**
49
- * @param {{ enabled?: boolean }} opts
50
- */
51
- export function configureAguaceroRnDebug(opts = {}) {
52
- if (opts && typeof opts.enabled === 'boolean') {
53
- _explicitEnabled = opts.enabled;
54
- }
55
- const on = isAguaceroRnDebugEnabled();
56
- try {
57
- if (typeof globalThis !== 'undefined') {
58
- globalThis.__AGUACERO_DEBUG__ = on;
59
- globalThis.__AGUACERO_WX_GRID_DEBUG__ = on;
60
- globalThis.__AGUACERO_NEXRAD_DEBUG__ = on;
61
- }
62
- } catch {
63
- /* ignore */
64
- }
65
- if (on) {
66
- installGlobalFetchLogger();
67
- aguaceroDebug('debug.enabled', {
68
- platform: Platform.OS,
69
- explicitFlag: _explicitEnabled,
70
- globalFlag: safeGlobalDebugFlag(),
71
- });
72
- }
73
- }
74
-
75
- /**
76
- * True when `debug={true}`, {@link configureAguaceroRnDebug}, or `globalThis.__AGUACERO_DEBUG__ === true`.
77
- * @returns {boolean}
78
- */
79
- export function isAguaceroRnDebugEnabled() {
80
- if (_explicitEnabled === true) return true;
81
- if (_explicitEnabled === false) {
82
- try {
83
- return typeof globalThis !== 'undefined' && globalThis.__AGUACERO_DEBUG__ === true;
84
- } catch {
85
- return false;
86
- }
87
- }
88
- try {
89
- if (typeof __DEV__ !== 'undefined' && __DEV__) return false;
90
- } catch {
91
- /* ignore */
92
- }
93
- try {
94
- return typeof globalThis !== 'undefined' && globalThis.__AGUACERO_DEBUG__ === true;
95
- } catch {
96
- return false;
97
- }
98
- }
99
-
100
- function safeGlobalDebugFlag() {
101
- try {
102
- return typeof globalThis !== 'undefined' ? globalThis.__AGUACERO_DEBUG__ === true : false;
103
- } catch {
104
- return false;
105
- }
106
- }
107
-
108
- /**
109
- * @param {string | null | undefined} secret
110
- * @returns {Record<string, unknown>}
111
- */
112
- export function describeSecret(secret) {
113
- if (secret == null || secret === '') {
114
- return { present: false, length: 0 };
115
- }
116
- const s = String(secret);
117
- const trimmed = s.trim();
118
- return {
119
- present: true,
120
- length: s.length,
121
- trimmedLength: trimmed.length,
122
- hasLeadingWhitespace: s.length > 0 && s !== trimmed && /^\s/.test(s),
123
- hasTrailingWhitespace: s.length > 0 && s !== trimmed && /\s$/.test(s),
124
- hasInternalWhitespace: /\s/.test(trimmed) && trimmed.indexOf(' ') >= 0,
125
- fingerprint: fingerprintSecret(trimmed || s),
126
- looksLikePlaceholder: /^(your[-_]?)?api[-_]?key|xxx+|test+$/i.test(trimmed),
127
- };
128
- }
129
-
130
- /**
131
- * @param {string} s
132
- * @returns {string}
133
- */
134
- export function fingerprintSecret(s) {
135
- if (!s) return '(empty)';
136
- if (s.length <= 8) return `len${s.length}`;
137
- return `${s.slice(0, 4)}…${s.slice(-4)} (len=${s.length})`;
138
- }
139
-
140
- /**
141
- * @param {string} u
142
- * @returns {string}
143
- */
144
- export function redactApiKeyFromUrl(u) {
145
- if (!u || typeof u !== 'string') return String(u);
146
- return u.replace(/([?&])apiKey=[^&]*/gi, '$1apiKey=(redacted)');
147
- }
148
-
149
- /**
150
- * @param {string} url
151
- * @returns {boolean}
152
- */
153
- export function shouldLogAguaceroUrl(url) {
154
- if (!url || typeof url !== 'string') return false;
155
- const lower = url.toLowerCase();
156
- return AGUACERO_URL_MARKERS.some((m) => lower.includes(m));
157
- }
158
-
159
- /**
160
- * @param {string} tag
161
- * @param {Record<string, unknown> | undefined} detail
162
- */
163
- export function aguaceroDebug(tag, detail) {
164
- if (!isAguaceroRnDebugEnabled()) return;
165
- if (detail !== undefined) {
166
- console.warn(`${LOG_PREFIX}[${tag}]`, detail);
167
- } else {
168
- console.warn(`${LOG_PREFIX}[${tag}]`);
169
- }
170
- }
171
-
172
- /**
173
- * Auth / HTTP failures: logged when debug is on (same prefix).
174
- * @param {string} tag
175
- * @param {Record<string, unknown> | undefined} detail
176
- */
177
- export function aguaceroDebugWarn(tag, detail) {
178
- if (!isAguaceroRnDebugEnabled()) return;
179
- if (detail !== undefined) {
180
- console.warn(`${LOG_PREFIX}[WARN][${tag}]`, detail);
181
- } else {
182
- console.warn(`${LOG_PREFIX}[WARN][${tag}]`);
183
- }
184
- }
185
-
186
- /**
187
- * @param {import('@aguacerowx/javascript-sdk').AguaceroCore | { apiKey?: string; bundleId?: string | null; gridRequestSiteOrigin?: string | null; baseGridUrl?: string; isReactNative?: boolean }} core
188
- * @param {Record<string, unknown>} [extra]
189
- */
190
- export function getAguaceroAuthDiagnosticSnapshot(core, extra = {}) {
191
- const apiKey = core?.apiKey;
192
- const bundleId = core?.bundleId;
193
- const origin = core?.gridRequestSiteOrigin;
194
- return {
195
- platform: Platform.OS,
196
- isReactNative: Boolean(core?.isReactNative),
197
- baseGridUrl: core?.baseGridUrl ?? null,
198
- apiKey: describeSecret(apiKey),
199
- bundleId: bundleId
200
- ? { present: true, value: String(bundleId), length: String(bundleId).length }
201
- : { present: false, hint: 'Install react-native-device-info for x-app-identifier on CDN requests' },
202
- gridRequestSiteOrigin: origin
203
- ? { present: true, value: String(origin), length: String(origin).length }
204
- : {
205
- present: false,
206
- hint: 'Pass gridRequestSiteOrigin on WeatherLayerManager (RN falls back to https://localhost if omitted)',
207
- },
208
- willSendAppIdentifier: Boolean(bundleId && core?.isReactNative),
209
- willSendOriginHeaders: Boolean(origin && String(origin).trim()),
210
- ...extra,
211
- };
212
- }
213
-
214
- /**
215
- * @param {Record<string, unknown>} options - {@link buildGridFrameProcessOptions} output
216
- * @param {import('@aguacerowx/javascript-sdk').AguaceroCore} [core]
217
- * @returns {Record<string, unknown>}
218
- */
219
- export function augmentProcessFrameOptionsForDebug(options, core) {
220
- const out = { ...options };
221
- if (!out.gridRequestSiteOrigin && core) {
222
- const origin = resolveGridRequestSiteOrigin(undefined, core);
223
- if (origin) {
224
- out.gridRequestSiteOrigin = origin;
225
- }
226
- }
227
- if (!isAguaceroRnDebugEnabled()) {
228
- return out;
229
- }
230
- out.debug = true;
231
- aguaceroDebug('processFrame.options', {
232
- url: redactApiKeyFromUrl(out.url),
233
- hasApiKeyInQuery: typeof out.url === 'string' && /[?&]apiKey=/i.test(out.url),
234
- apiKey: describeSecret(out.apiKey),
235
- bundleId: out.bundleId ? { present: true, value: String(out.bundleId) } : { present: false },
236
- gridRequestSiteOrigin: out.gridRequestSiteOrigin ?? null,
237
- coreSnapshot: core ? getAguaceroAuthDiagnosticSnapshot(core) : undefined,
238
- });
239
- return out;
240
- }
241
-
242
- /**
243
- * @param {string | Request} input
244
- * @param {RequestInit | undefined} init
245
- */
246
- function summarizeFetchRequest(input, init) {
247
- const url = typeof input === 'string' ? input : input?.url;
248
- const headers = new Headers(
249
- (typeof input !== 'string' && input?.headers) || init?.headers || undefined,
250
- );
251
- const headerRecord = {};
252
- headers.forEach((v, k) => {
253
- const lk = k.toLowerCase();
254
- if (lk === 'x-api-key' || lk === 'authorization') {
255
- headerRecord[k] = describeSecret(v);
256
- } else {
257
- headerRecord[k] = v;
258
- }
259
- });
260
- return {
261
- url: redactApiKeyFromUrl(url || ''),
262
- method: init?.method || (typeof input !== 'string' ? input?.method : undefined) || 'GET',
263
- headers: headerRecord,
264
- hasApiKeyQuery: typeof url === 'string' && /[?&]apiKey=/i.test(url),
265
- };
266
- }
267
-
268
- /**
269
- * Patches `global.fetch` once to log Aguacero CDN / API traffic when debug is enabled.
270
- */
271
- export function installGlobalFetchLogger() {
272
- if (_fetchLoggerInstalled || !isAguaceroRnDebugEnabled()) return;
273
- if (typeof globalThis === 'undefined' || typeof globalThis.fetch !== 'function') return;
274
-
275
- const originalFetch = globalThis.fetch.bind(globalThis);
276
- _fetchLoggerInstalled = true;
277
-
278
- globalThis.fetch = async function aguaceroInstrumentedFetch(input, init) {
279
- const url = typeof input === 'string' ? input : input?.url;
280
- const shouldLog = shouldLogAguaceroUrl(url || '');
281
- const reqId = shouldLog ? `f${++_fetchSeq}` : null;
282
- const started = Date.now();
283
-
284
- if (shouldLog) {
285
- aguaceroDebug('fetch.start', { reqId, ...summarizeFetchRequest(input, init) });
286
- }
287
-
288
- try {
289
- const response = await originalFetch(input, init);
290
- if (shouldLog) {
291
- const elapsedMs = Date.now() - started;
292
- const base = {
293
- reqId,
294
- status: response.status,
295
- statusText: response.statusText,
296
- ok: response.ok,
297
- elapsedMs,
298
- url: redactApiKeyFromUrl(url || ''),
299
- };
300
- if (!response.ok) {
301
- let bodySnippet = null;
302
- try {
303
- const clone = response.clone();
304
- const text = await clone.text();
305
- bodySnippet = text.length > 600 ? `${text.slice(0, 600)}…` : text;
306
- } catch {
307
- bodySnippet = '(could not read body)';
308
- }
309
- aguaceroDebugWarn('fetch.httpError', {
310
- ...base,
311
- bodySnippet,
312
- hint403:
313
- response.status === 403
314
- ? '403 usually means: invalid/disabled API key, bundleId not allowlisted (x-app-identifier), or missing/wrong gridRequestSiteOrigin (Origin/Referer). Compare snapshot at core.created / processFrame.options.'
315
- : undefined,
316
- });
317
- } else {
318
- aguaceroDebug('fetch.ok', base);
319
- }
320
- }
321
- return response;
322
- } catch (err) {
323
- if (shouldLog) {
324
- aguaceroDebugWarn('fetch.throw', {
325
- reqId,
326
- message: err?.message || String(err),
327
- elapsedMs: Date.now() - started,
328
- url: redactApiKeyFromUrl(url || ''),
329
- });
330
- }
331
- throw err;
332
- }
333
- };
334
-
335
- aguaceroDebug('fetch.hookInstalled', { platform: Platform.OS });
336
- }
1
+ import{Platform as p}from"react-native";import{resolveGridRequestSiteOrigin as b}from"./gridCdnAuth";const l="[AguaceroRN][debug]";let u=null,h=!1,_=0;const y=["cloudfront.net","lambda-url.us-east-2.on.aws","amazonaws.com","noaa.gov"];export function setAguaceroRnDebugEnabled(e){configureAguaceroRnDebug({enabled:!!e})}export function configureAguaceroRnDebug(e={}){e&&typeof e.enabled=="boolean"&&(u=e.enabled);const t=isAguaceroRnDebugEnabled();try{typeof globalThis<"u"&&(globalThis.__AGUACERO_DEBUG__=t,globalThis.__AGUACERO_WX_GRID_DEBUG__=t,globalThis.__AGUACERO_NEXRAD_DEBUG__=t,globalThis.__AGUACERO_NEXRAD_PIPELINE__=t)}catch{}t&&(installGlobalFetchLogger(),aguaceroDebug("debug.enabled",{platform:p.OS,explicitFlag:u,globalFlag:m()}))}export function isAguaceroRnDebugEnabled(){if(u===!0)return!0;if(u===!1)try{return typeof globalThis<"u"&&globalThis.__AGUACERO_DEBUG__===!0}catch{return!1}try{if(typeof __DEV__<"u"&&__DEV__)return!1}catch{}try{return typeof globalThis<"u"&&globalThis.__AGUACERO_DEBUG__===!0}catch{return!1}}function m(){try{return typeof globalThis<"u"?globalThis.__AGUACERO_DEBUG__===!0:!1}catch{return!1}}export function describeSecret(e){if(e==null||e==="")return{present:!1,length:0};const t=String(e),n=t.trim();return{present:!0,length:t.length,trimmedLength:n.length,hasLeadingWhitespace:t.length>0&&t!==n&&/^\s/.test(t),hasTrailingWhitespace:t.length>0&&t!==n&&/\s$/.test(t),hasInternalWhitespace:/\s/.test(n)&&n.indexOf(" ")>=0,fingerprint:fingerprintSecret(n||t),looksLikePlaceholder:/^(your[-_]?)?api[-_]?key|xxx+|test+$/i.test(n)}}export function fingerprintSecret(e){return e?e.length<=8?`len${e.length}`:`${e.slice(0,4)}\u2026${e.slice(-4)} (len=${e.length})`:"(empty)"}export function redactApiKeyFromUrl(e){return!e||typeof e!="string"?String(e):e.replace(/([?&])apiKey=[^&]*/gi,"$1apiKey=(redacted)")}export function shouldLogAguaceroUrl(e){if(!e||typeof e!="string")return!1;const t=e.toLowerCase();return y.some(n=>t.includes(n))}export function aguaceroDebug(e,t){isAguaceroRnDebugEnabled()&&(t!==void 0?console.warn(`${l}[${e}]`,t):console.warn(`${l}[${e}]`))}export function aguaceroDebugWarn(e,t){isAguaceroRnDebugEnabled()&&(t!==void 0?console.warn(`${l}[WARN][${e}]`,t):console.warn(`${l}[WARN][${e}]`))}export function getAguaceroAuthDiagnosticSnapshot(e,t={}){const n=e?.apiKey,o=e?.bundleId,r=e?.gridRequestSiteOrigin;return{platform:p.OS,isReactNative:!!e?.isReactNative,baseGridUrl:e?.baseGridUrl??null,apiKey:describeSecret(n),bundleId:o?{present:!0,value:String(o),length:String(o).length}:{present:!1,hint:"Install react-native-device-info for x-app-identifier on CDN requests"},gridRequestSiteOrigin:r?{present:!0,value:String(r),length:String(r).length}:{present:!1,hint:"Pass gridRequestSiteOrigin on WeatherLayerManager (RN falls back to https://localhost if omitted)"},willSendAppIdentifier:!!(o&&e?.isReactNative),willSendOriginHeaders:!!(r&&String(r).trim()),...t}}export function augmentProcessFrameOptionsForDebug(e,t){const n={...e};if(!n.gridRequestSiteOrigin&&t){const o=b(void 0,t);o&&(n.gridRequestSiteOrigin=o)}return isAguaceroRnDebugEnabled()&&(n.debug=!0,aguaceroDebug("processFrame.options",{url:redactApiKeyFromUrl(n.url),hasApiKeyInQuery:typeof n.url=="string"&&/[?&]apiKey=/i.test(n.url),apiKey:describeSecret(n.apiKey),bundleId:n.bundleId?{present:!0,value:String(n.bundleId)}:{present:!1},gridRequestSiteOrigin:n.gridRequestSiteOrigin??null,coreSnapshot:t?getAguaceroAuthDiagnosticSnapshot(t):void 0})),n}function A(e,t){const n=typeof e=="string"?e:e?.url,o=new Headers(typeof e!="string"&&e?.headers||t?.headers||void 0),r={};return o.forEach((a,s)=>{const i=s.toLowerCase();i==="x-api-key"||i==="authorization"?r[s]=describeSecret(a):r[s]=a}),{url:redactApiKeyFromUrl(n||""),method:t?.method||(typeof e!="string"?e?.method:void 0)||"GET",headers:r,hasApiKeyQuery:typeof n=="string"&&/[?&]apiKey=/i.test(n)}}export function installGlobalFetchLogger(){if(h||!isAguaceroRnDebugEnabled()||typeof globalThis>"u"||typeof globalThis.fetch!="function")return;const e=globalThis.fetch.bind(globalThis);h=!0,globalThis.fetch=async function(t,n){const o=typeof t=="string"?t:t?.url,r=shouldLogAguaceroUrl(o||""),a=r?`f${++_}`:null,s=Date.now();r&&aguaceroDebug("fetch.start",{reqId:a,...A(t,n)});try{const i=await e(t,n);if(r){const f=Date.now()-s,d={reqId:a,status:i.status,statusText:i.statusText,ok:i.ok,elapsedMs:f,url:redactApiKeyFromUrl(o||"")};if(i.ok)aguaceroDebug("fetch.ok",d);else{let g=null;try{const c=await i.clone().text();g=c.length>600?`${c.slice(0,600)}\u2026`:c}catch{g="(could not read body)"}aguaceroDebugWarn("fetch.httpError",{...d,bodySnippet:g,hint403:i.status===403?"403 usually means: invalid/disabled API key, bundleId not allowlisted (x-app-identifier), or missing/wrong gridRequestSiteOrigin (Origin/Referer). Compare snapshot at core.created / processFrame.options.":void 0})}}return i}catch(i){throw r&&aguaceroDebugWarn("fetch.throw",{reqId:a,message:i?.message||String(i),elapsedMs:Date.now()-s,url:redactApiKeyFromUrl(o||"")}),i}},aguaceroDebug("fetch.hookInstalled",{platform:p.OS})}
@@ -0,0 +1 @@
1
+ import{NativeModules as O,Platform as h}from"react-native";import{toByteArray as R}from"base64-js";import{buildNativeCloudFrontFetchOptions as q,RN_DEFAULT_GRID_REQUEST_SITE_ORIGIN as F}from"./gridCdnAuth";import{aguaceroDebug as w,isAguaceroRnDebugEnabled as v,redactApiKeyFromUrl as K}from"./aguaceroRnDebug";const s="[Aguacero][NEXRAD][fetch]";function I(e){if(!e)return{};if(typeof Headers<"u"&&e instanceof Headers){const r={};return e.forEach((d,c)=>{r[c]=d}),r}return{...e}}function A(e){const r=R(e||"");return r.buffer.slice(r.byteOffset,r.byteOffset+r.byteLength)}export function nexradNativeCloudFrontFetchUnavailableReason(){if(h.OS!=="android"&&h.OS!=="ios")return`platform=${h.OS}`;const e=O.WeatherFrameProcessorModule;return e?typeof e.fetchCloudFront!="function"?"fetchCloudFront not on native module \u2014 rebuild native app after SDK update":null:"WeatherFrameProcessorModule missing \u2014 rebuild native app"}export function createNexradCloudFrontFetch(e){const r=nexradNativeCloudFrontFetchUnavailableReason();if(r)return console.warn(`${s} native unavailable: ${r}`),null;const d=O.WeatherFrameProcessorModule;return console.warn(`${s} using native OkHttp/URLSession for level-2 CloudFront`),async function(c,L={}){const b=I(L.headers),g=b.Range||b.range||null,p=e()||{},t=q({url:c,apiKey:p.apiKey,bundleId:p.bundleId,gridRequestSiteOrigin:p.gridRequestSiteOrigin,range:g||void 0});v()&&w("nexrad.fetchCloudFront.request",{url:K(t.url),range:g||"(none)",apiKeyLen:t.apiKey.length,bundleId:t.bundleId||"(none)",gridRequestSiteOrigin:t.gridRequestSiteOrigin,hint:"Same native auth as processFrame / satellite: x-api-key + ?apiKey= + Origin; x-app-identifier only if bundleId set"}),t.apiKey||console.warn(`${s} apiKey is empty \u2014 CloudFront will 403. Pass apiKey on WeatherLayerManager (same as models/satellite).`);const i=await d.fetchCloudFront({...t,debug:v()}),a=Number(i?.status)||0;if(console.warn(`${s} response`,{status:a,range:g||"(none)",transport:"native",bodyBytes:i?.bodyBase64?Math.floor(i.bodyBase64.length*3/4):0}),a===403){let n="";try{const u=R(i?.bodyBase64||"");let l="";for(let y=0;y<u.length;y++)l+=String.fromCharCode(u[y]);n=l.length>200?`${l.slice(0,200)}\u2026`:l}catch(u){n=`(unreadable: ${u.message})`}const m=typeof n=="string"&&n.includes("<Code>AccessDenied</Code>")&&n.includes("Access Denied"),S=typeof n=="string"&&(n.includes("Access Denied:")||n.includes("Missing API Key"));let o;m?o="CloudFront Lambda auth succeeded; S3 origin denied /level-2-new (fix OAC + bucket policy for that prefix, or object missing). Grids use other paths \u2014 they can work while level-2 fails.":S?o=t.gridRequestSiteOrigin===F?"Lambda rejected request \u2014 pass gridRequestSiteOrigin on WeatherLayerManager.":"Lambda rejected request \u2014 verify apiKey, bundleId allowlist, and gridRequestSiteOrigin.":t.gridRequestSiteOrigin===F?o="Origin is https://localhost \u2014 pass gridRequestSiteOrigin on WeatherLayerManager (same origin as MapsGL / App2).":o="Verify apiKey, bundleId allowlist (com.reactnativeapp), and gridRequestSiteOrigin match CloudFront.",console.warn(`${s} 403`,{hint:o,denialLayer:m?"s3-origin":S?"lambda-edge":"unknown",apiKeyLen:t.apiKey.length,bundleId:t.bundleId||"(none)",gridRequestSiteOrigin:t.gridRequestSiteOrigin,bodySnippet:n})}const f=new Map;i?.contentRange&&f.set("content-range",String(i.contentRange)),i?.contentLength!=null&&i.contentLength!==""&&f.set("content-length",String(i.contentLength));const C=A(i?.bodyBase64||"");return{ok:a>=200&&a<300||a===206,status:a,headers:{get(n){return f.get(String(n).toLowerCase())??null}},arrayBuffer:async()=>C}}}
@@ -1,100 +1 @@
1
- import { satBridgeWarn } from './satelliteBridgeDiag';
2
-
3
- /**
4
- * Dispatches native view-manager commands on both the New Architecture (Fabric `HostInstance`)
5
- * and the legacy Paper renderer (`reactTag` from {@code findNodeHandle}).
6
- *
7
- * Codegen views that only used {@code UIManager.dispatchViewManagerCommand(findNodeHandle(...))}
8
- * silently no-op on Fabric when {@code findNodeHandle} returns null — satellite/NEXRAD/grid
9
- * commands never reach native.
10
- *
11
- * @param {React.RefObject | { current: unknown }} nativeRef
12
- * @param {string} viewManagerName e.g. `'SatelliteLayer'`
13
- * @param {string} commandName e.g. `'syncSatellite'` (must match native Commands export)
14
- * @param {Array<unknown>} args
15
- * @returns {boolean} true if a dispatch path ran
16
- */
17
- export function dispatchViewManagerCommandCompat(nativeRef, viewManagerName, commandName, args) {
18
- const node = nativeRef?.current;
19
- const nodeDesc =
20
- node == null
21
- ? 'null'
22
- : `${typeof node}${node?.constructor?.name ? ':' + node.constructor.name : ''}`;
23
- if (node == null) {
24
- satBridgeWarn(`dispatch:${commandName}:abort`, {
25
- reason: 'nativeRef.current is null — SatelliteLayer native view never mounted or ref not attached',
26
- viewManagerName,
27
- });
28
- return false;
29
- }
30
-
31
- const { UIManager, findNodeHandle } = require('react-native');
32
- let cmdId;
33
- let commandsKeys = [];
34
- try {
35
- const cfg = UIManager.getViewManagerConfig(viewManagerName);
36
- commandsKeys = cfg?.Commands ? Object.keys(cfg.Commands) : [];
37
- cmdId = cfg?.Commands?.[commandName];
38
- } catch (e) {
39
- cmdId = null;
40
- satBridgeWarn(`dispatch:${commandName}:uimanager-error`, { viewManagerName, message: String(e) });
41
- }
42
-
43
- satBridgeWarn(`dispatch:${commandName}:try-paper`, {
44
- viewManagerName,
45
- nodeDesc,
46
- cmdId: cmdId ?? 'MISSING',
47
- commandsKeys,
48
- argsSummary:
49
- commandName === 'syncSatellite' && args?.[0]
50
- ? `jsonLen=${String(args[0]).length}`
51
- : `argsLen=${args?.length ?? 0}`,
52
- });
53
-
54
- // Prefer legacy Paper dispatch when we have a react tag — matches Grid/NEXRAD paths that still work on bridge mode.
55
- if (cmdId != null) {
56
- const tag = findNodeHandle(node);
57
- if (tag != null) {
58
- try {
59
- UIManager.dispatchViewManagerCommand(tag, cmdId, args);
60
- satBridgeWarn(`dispatch:${commandName}:ok-paper`, { reactTag: tag, cmdId });
61
- return true;
62
- } catch (e) {
63
- satBridgeWarn(`dispatch:${commandName}:paper-threw`, { message: String(e), reactTag: tag });
64
- }
65
- } else {
66
- satBridgeWarn(`dispatch:${commandName}:paper-skip`, {
67
- reason: 'findNodeHandle(node) is null (typical on Fabric — will try RendererProxy.dispatchCommand)',
68
- });
69
- }
70
- } else {
71
- satBridgeWarn(`dispatch:${commandName}:no-cmdId`, {
72
- reason: 'UIManager has no Commands entry — view manager name mismatch or pod not linked',
73
- viewManagerName,
74
- });
75
- }
76
-
77
- // Fabric / bridgeless: HostInstance + command name (string). Required when findNodeHandle is null.
78
- try {
79
- const RendererProxy = require('react-native/Libraries/ReactNative/RendererProxy');
80
- if (typeof RendererProxy.dispatchCommand === 'function') {
81
- RendererProxy.dispatchCommand(node, commandName, args);
82
- satBridgeWarn(`dispatch:${commandName}:ok-fabric`, {
83
- note: 'dispatched via RendererProxy.dispatchCommand(string name)',
84
- });
85
- return true;
86
- }
87
- satBridgeWarn(`dispatch:${commandName}:no-rendererProxy`, {
88
- reason: 'RendererProxy.dispatchCommand missing',
89
- });
90
- } catch (e) {
91
- satBridgeWarn(`dispatch:${commandName}:fabric-threw`, { message: String(e) });
92
- }
93
-
94
- satBridgeWarn(`dispatch:${commandName}:FAILED`, {
95
- viewManagerName,
96
- nodeDesc,
97
- hadCmdId: cmdId != null,
98
- });
99
- return false;
100
- }
1
+ import{satBridgeWarn as n}from"./satelliteBridgeDiag";export function dispatchViewManagerCommandCompat(m,i,a,s){const r=m?.current,o=r==null?"null":`${typeof r}${r?.constructor?.name?":"+r.constructor.name:""}`;if(r==null)return n(`dispatch:${a}:abort`,{reason:"nativeRef.current is null \u2014 SatelliteLayer native view never mounted or ref not attached",viewManagerName:i}),!1;const{UIManager:c,findNodeHandle:p}=require("react-native");let t,d=[];try{const e=c.getViewManagerConfig(i);d=e?.Commands?Object.keys(e.Commands):[],t=e?.Commands?.[a]}catch(e){t=null,n(`dispatch:${a}:uimanager-error`,{viewManagerName:i,message:String(e)})}if(n(`dispatch:${a}:try-paper`,{viewManagerName:i,nodeDesc:o,cmdId:t??"MISSING",commandsKeys:d,argsSummary:a==="syncSatellite"&&s?.[0]?`jsonLen=${String(s[0]).length}`:`argsLen=${s?.length??0}`}),t!=null){const e=p(r);if(e!=null)try{return c.dispatchViewManagerCommand(e,t,s),n(`dispatch:${a}:ok-paper`,{reactTag:e,cmdId:t}),!0}catch(l){n(`dispatch:${a}:paper-threw`,{message:String(l),reactTag:e})}else n(`dispatch:${a}:paper-skip`,{reason:"findNodeHandle(node) is null (typical on Fabric \u2014 will try RendererProxy.dispatchCommand)"})}else n(`dispatch:${a}:no-cmdId`,{reason:"UIManager has no Commands entry \u2014 view manager name mismatch or pod not linked",viewManagerName:i});try{const e=require("react-native/Libraries/ReactNative/RendererProxy");if(typeof e.dispatchCommand=="function")return e.dispatchCommand(r,a,s),n(`dispatch:${a}:ok-fabric`,{note:"dispatched via RendererProxy.dispatchCommand(string name)"}),!0;n(`dispatch:${a}:no-rendererProxy`,{reason:"RendererProxy.dispatchCommand missing"})}catch(e){n(`dispatch:${a}:fabric-threw`,{message:String(e)})}return n(`dispatch:${a}:FAILED`,{viewManagerName:i,nodeDesc:o,hadCmdId:t!=null}),!1}
@@ -1,56 +1 @@
1
- /**
2
- * CloudFront grid CDN auth helpers for React Native.
3
- *
4
- * The CDN returns HTTP 403 when {@code Origin} is missing (even if {@code x-api-key} and
5
- * {@code apiKey} query are valid). Browsers set Origin automatically; RN native HTTP does not.
6
- */
7
-
8
- /** Fallback when no prop/core/global origin is configured (any origin satisfies the CDN). */
9
- export const RN_DEFAULT_GRID_REQUEST_SITE_ORIGIN = 'https://localhost';
10
-
11
- /**
12
- * @returns {string}
13
- */
14
- export function readGlobalGridRequestSiteOrigin() {
15
- try {
16
- const g = globalThis.__AGUACERO_GRID_REQUEST_SITE_ORIGIN__;
17
- if (typeof g === 'string' && g.trim()) {
18
- return g.trim().replace(/\/+$/, '');
19
- }
20
- } catch {
21
- /* ignore */
22
- }
23
- return '';
24
- }
25
-
26
- /**
27
- * Resolve the site origin used for {@code Origin} / {@code Referer} on grid CDN requests.
28
- *
29
- * @param {string | undefined | null} propOrigin - {@link WeatherLayerManager} `gridRequestSiteOrigin` prop
30
- * @param {{ gridRequestSiteOrigin?: string | null; isReactNative?: boolean } | null | undefined} core
31
- * @returns {string | null} Normalized origin without trailing slash, or null on web when unset
32
- */
33
- export function resolveGridRequestSiteOrigin(propOrigin, core) {
34
- const normalize = (s) => {
35
- let o = String(s).trim();
36
- while (o.endsWith('/')) {
37
- o = o.slice(0, -1);
38
- }
39
- return o;
40
- };
41
-
42
- if (typeof propOrigin === 'string' && propOrigin.trim()) {
43
- return normalize(propOrigin);
44
- }
45
- if (typeof core?.gridRequestSiteOrigin === 'string' && core.gridRequestSiteOrigin.trim()) {
46
- return normalize(core.gridRequestSiteOrigin);
47
- }
48
- const fromGlobal = readGlobalGridRequestSiteOrigin();
49
- if (fromGlobal) {
50
- return fromGlobal;
51
- }
52
- if (core?.isReactNative) {
53
- return RN_DEFAULT_GRID_REQUEST_SITE_ORIGIN;
54
- }
55
- return null;
56
- }
1
+ export const RN_DEFAULT_GRID_REQUEST_SITE_ORIGIN="https://localhost";export function readGlobalGridRequestSiteOrigin(){try{const t=globalThis.__AGUACERO_GRID_REQUEST_SITE_ORIGIN__;if(typeof t=="string"&&t.trim())return t.trim().replace(/\/+$/,"")}catch{}return""}export function resolveGridRequestSiteOrigin(t,e){const i=n=>{let r=String(n).trim();for(;r.endsWith("/");)r=r.slice(0,-1);return r};return typeof t=="string"&&t.trim()?i(t):typeof e?.gridRequestSiteOrigin=="string"&&e.gridRequestSiteOrigin.trim()?i(e.gridRequestSiteOrigin):readGlobalGridRequestSiteOrigin()||(e?.isReactNative?RN_DEFAULT_GRID_REQUEST_SITE_ORIGIN:null)}export function normalizeCdnApiKey(t){return typeof t=="string"?t.trim():""}export function ensureApiKeyInUrl(t,e){const i=normalizeCdnApiKey(e);if(!i||/[?&]apiKey=/i.test(t))return t;const n=t.includes("?")?"&":"?";return`${t}${n}apiKey=${encodeURIComponent(i)}`}export function buildNativeCloudFrontFetchOptions({url:t,apiKey:e,bundleId:i,gridRequestSiteOrigin:n,core:r,range:o}){const u=normalizeCdnApiKey(e),c=resolveGridRequestSiteOrigin(n,r)||RN_DEFAULT_GRID_REQUEST_SITE_ORIGIN,s={url:ensureApiKeyInUrl(t,u),apiKey:u,bundleId:i?String(i):"",gridRequestSiteOrigin:c};return o&&(s.range=o),s}