@aguacerowx/react-native 0.0.50 → 0.0.52

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 (56) hide show
  1. package/android/src/main/java/com/aguacerowx/reactnative/SatelliteLayerView.java +11 -3
  2. package/android/src/main/java/com/aguacerowx/reactnative/WeatherFrameProcessorModule.java +315 -275
  3. package/ios/SatelliteLayerView.swift +11 -4
  4. package/ios/WeatherFrameProcessorModule.swift +222 -188
  5. package/lib/commonjs/WeatherLayerManager.js +112 -48
  6. package/lib/commonjs/WeatherLayerManager.js.map +1 -1
  7. package/lib/commonjs/aguaceroCoreDebugHooks.js +144 -0
  8. package/lib/commonjs/aguaceroCoreDebugHooks.js.map +1 -0
  9. package/lib/commonjs/aguaceroRnDebug.js +358 -0
  10. package/lib/commonjs/aguaceroRnDebug.js.map +1 -0
  11. package/lib/commonjs/gridCdnAuth.js +64 -0
  12. package/lib/commonjs/gridCdnAuth.js.map +1 -0
  13. package/lib/commonjs/index.js +50 -0
  14. package/lib/commonjs/index.js.map +1 -1
  15. package/lib/commonjs/nexrad/nexradAndroidController.js +38 -25
  16. package/lib/commonjs/nexrad/nexradAndroidController.js.map +1 -1
  17. package/lib/commonjs/nexrad/nexradDiag.js +31 -25
  18. package/lib/commonjs/nexrad/nexradDiag.js.map +1 -1
  19. package/lib/commonjs/satellite/satelliteAndroidController.js +24 -15
  20. package/lib/commonjs/satellite/satelliteAndroidController.js.map +1 -1
  21. package/lib/module/WeatherLayerManager.js +112 -48
  22. package/lib/module/WeatherLayerManager.js.map +1 -1
  23. package/lib/module/aguaceroCoreDebugHooks.js +136 -0
  24. package/lib/module/aguaceroCoreDebugHooks.js.map +1 -0
  25. package/lib/module/aguaceroRnDebug.js +341 -0
  26. package/lib/module/aguaceroRnDebug.js.map +1 -0
  27. package/lib/module/gridCdnAuth.js +56 -0
  28. package/lib/module/gridCdnAuth.js.map +1 -0
  29. package/lib/module/index.js +2 -0
  30. package/lib/module/index.js.map +1 -1
  31. package/lib/module/nexrad/nexradAndroidController.js +38 -25
  32. package/lib/module/nexrad/nexradAndroidController.js.map +1 -1
  33. package/lib/module/nexrad/nexradDiag.js +31 -25
  34. package/lib/module/nexrad/nexradDiag.js.map +1 -1
  35. package/lib/module/satellite/satelliteAndroidController.js +24 -15
  36. package/lib/module/satellite/satelliteAndroidController.js.map +1 -1
  37. package/lib/typescript/WeatherLayerManager.d.ts.map +1 -1
  38. package/lib/typescript/aguaceroCoreDebugHooks.d.ts +10 -0
  39. package/lib/typescript/aguaceroCoreDebugHooks.d.ts.map +1 -0
  40. package/lib/typescript/aguaceroRnDebug.d.ts +97 -0
  41. package/lib/typescript/aguaceroRnDebug.d.ts.map +1 -0
  42. package/lib/typescript/gridCdnAuth.d.ts +24 -0
  43. package/lib/typescript/gridCdnAuth.d.ts.map +1 -0
  44. package/lib/typescript/index.d.ts +2 -0
  45. package/lib/typescript/nexrad/nexradAndroidController.d.ts.map +1 -1
  46. package/lib/typescript/nexrad/nexradDiag.d.ts.map +1 -1
  47. package/lib/typescript/satellite/satelliteAndroidController.d.ts.map +1 -1
  48. package/package.json +1 -1
  49. package/src/WeatherLayerManager.js +2024 -1947
  50. package/src/aguaceroCoreDebugHooks.js +142 -0
  51. package/src/aguaceroRnDebug.js +335 -0
  52. package/src/gridCdnAuth.js +56 -0
  53. package/src/index.js +19 -7
  54. package/src/nexrad/nexradAndroidController.js +1078 -1068
  55. package/src/nexrad/nexradDiag.js +150 -144
  56. package/src/satellite/satelliteAndroidController.js +245 -236
@@ -0,0 +1,341 @@
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
+ * API keys are never printed in full — only length, fingerprint, and whitespace hints.
20
+ */
21
+
22
+ import { Platform } from 'react-native';
23
+ import { resolveGridRequestSiteOrigin } from './gridCdnAuth';
24
+ const LOG_PREFIX = '[AguaceroRN][debug]';
25
+
26
+ /** @type {boolean | null} */
27
+ let _explicitEnabled = null;
28
+ let _fetchLoggerInstalled = false;
29
+ let _fetchSeq = 0;
30
+ const AGUACERO_URL_MARKERS = ['cloudfront.net', 'lambda-url.us-east-2.on.aws', 'amazonaws.com', 'noaa.gov'];
31
+
32
+ /**
33
+ * @param {boolean} enabled
34
+ */
35
+ export function setAguaceroRnDebugEnabled(enabled) {
36
+ configureAguaceroRnDebug({
37
+ enabled: Boolean(enabled)
38
+ });
39
+ }
40
+
41
+ /**
42
+ * @param {{ enabled?: boolean }} opts
43
+ */
44
+ export function configureAguaceroRnDebug(opts = {}) {
45
+ if (opts && typeof opts.enabled === 'boolean') {
46
+ _explicitEnabled = opts.enabled;
47
+ }
48
+ const on = isAguaceroRnDebugEnabled();
49
+ try {
50
+ if (typeof globalThis !== 'undefined') {
51
+ globalThis.__AGUACERO_DEBUG__ = on;
52
+ globalThis.__AGUACERO_WX_GRID_DEBUG__ = on;
53
+ globalThis.__AGUACERO_NEXRAD_DEBUG__ = on;
54
+ }
55
+ } catch {
56
+ /* ignore */
57
+ }
58
+ if (on) {
59
+ installGlobalFetchLogger();
60
+ aguaceroDebug('debug.enabled', {
61
+ platform: Platform.OS,
62
+ explicitFlag: _explicitEnabled,
63
+ globalFlag: safeGlobalDebugFlag()
64
+ });
65
+ }
66
+ }
67
+
68
+ /**
69
+ * True when `debug={true}`, {@link configureAguaceroRnDebug}, or `globalThis.__AGUACERO_DEBUG__ === true`.
70
+ * @returns {boolean}
71
+ */
72
+ export function isAguaceroRnDebugEnabled() {
73
+ if (_explicitEnabled === true) return true;
74
+ if (_explicitEnabled === false) {
75
+ try {
76
+ return typeof globalThis !== 'undefined' && globalThis.__AGUACERO_DEBUG__ === true;
77
+ } catch {
78
+ return false;
79
+ }
80
+ }
81
+ try {
82
+ if (typeof __DEV__ !== 'undefined' && __DEV__) return false;
83
+ } catch {
84
+ /* ignore */
85
+ }
86
+ try {
87
+ return typeof globalThis !== 'undefined' && globalThis.__AGUACERO_DEBUG__ === true;
88
+ } catch {
89
+ return false;
90
+ }
91
+ }
92
+ function safeGlobalDebugFlag() {
93
+ try {
94
+ return typeof globalThis !== 'undefined' ? globalThis.__AGUACERO_DEBUG__ === true : false;
95
+ } catch {
96
+ return false;
97
+ }
98
+ }
99
+
100
+ /**
101
+ * @param {string | null | undefined} secret
102
+ * @returns {Record<string, unknown>}
103
+ */
104
+ export function describeSecret(secret) {
105
+ if (secret == null || secret === '') {
106
+ return {
107
+ present: false,
108
+ length: 0
109
+ };
110
+ }
111
+ const s = String(secret);
112
+ const trimmed = s.trim();
113
+ return {
114
+ present: true,
115
+ length: s.length,
116
+ trimmedLength: trimmed.length,
117
+ hasLeadingWhitespace: s.length > 0 && s !== trimmed && /^\s/.test(s),
118
+ hasTrailingWhitespace: s.length > 0 && s !== trimmed && /\s$/.test(s),
119
+ hasInternalWhitespace: /\s/.test(trimmed) && trimmed.indexOf(' ') >= 0,
120
+ fingerprint: fingerprintSecret(trimmed || s),
121
+ looksLikePlaceholder: /^(your[-_]?)?api[-_]?key|xxx+|test+$/i.test(trimmed)
122
+ };
123
+ }
124
+
125
+ /**
126
+ * @param {string} s
127
+ * @returns {string}
128
+ */
129
+ export function fingerprintSecret(s) {
130
+ if (!s) return '(empty)';
131
+ if (s.length <= 8) return `len${s.length}`;
132
+ return `${s.slice(0, 4)}…${s.slice(-4)} (len=${s.length})`;
133
+ }
134
+
135
+ /**
136
+ * @param {string} u
137
+ * @returns {string}
138
+ */
139
+ export function redactApiKeyFromUrl(u) {
140
+ if (!u || typeof u !== 'string') return String(u);
141
+ return u.replace(/([?&])apiKey=[^&]*/gi, '$1apiKey=(redacted)');
142
+ }
143
+
144
+ /**
145
+ * @param {string} url
146
+ * @returns {boolean}
147
+ */
148
+ export function shouldLogAguaceroUrl(url) {
149
+ if (!url || typeof url !== 'string') return false;
150
+ const lower = url.toLowerCase();
151
+ return AGUACERO_URL_MARKERS.some(m => lower.includes(m));
152
+ }
153
+
154
+ /**
155
+ * @param {string} tag
156
+ * @param {Record<string, unknown> | undefined} detail
157
+ */
158
+ export function aguaceroDebug(tag, detail) {
159
+ if (!isAguaceroRnDebugEnabled()) return;
160
+ if (detail !== undefined) {
161
+ console.warn(`${LOG_PREFIX}[${tag}]`, detail);
162
+ } else {
163
+ console.warn(`${LOG_PREFIX}[${tag}]`);
164
+ }
165
+ }
166
+
167
+ /**
168
+ * Auth / HTTP failures: logged when debug is on (same prefix).
169
+ * @param {string} tag
170
+ * @param {Record<string, unknown> | undefined} detail
171
+ */
172
+ export function aguaceroDebugWarn(tag, detail) {
173
+ if (!isAguaceroRnDebugEnabled()) return;
174
+ if (detail !== undefined) {
175
+ console.warn(`${LOG_PREFIX}[WARN][${tag}]`, detail);
176
+ } else {
177
+ console.warn(`${LOG_PREFIX}[WARN][${tag}]`);
178
+ }
179
+ }
180
+
181
+ /**
182
+ * @param {import('@aguacerowx/javascript-sdk').AguaceroCore | { apiKey?: string; bundleId?: string | null; gridRequestSiteOrigin?: string | null; baseGridUrl?: string; isReactNative?: boolean }} core
183
+ * @param {Record<string, unknown>} [extra]
184
+ */
185
+ export function getAguaceroAuthDiagnosticSnapshot(core, extra = {}) {
186
+ const apiKey = core?.apiKey;
187
+ const bundleId = core?.bundleId;
188
+ const origin = core?.gridRequestSiteOrigin;
189
+ return {
190
+ platform: Platform.OS,
191
+ isReactNative: Boolean(core?.isReactNative),
192
+ baseGridUrl: core?.baseGridUrl ?? null,
193
+ apiKey: describeSecret(apiKey),
194
+ bundleId: bundleId ? {
195
+ present: true,
196
+ value: String(bundleId),
197
+ length: String(bundleId).length
198
+ } : {
199
+ present: false,
200
+ hint: 'Install react-native-device-info for x-app-identifier on CDN requests'
201
+ },
202
+ gridRequestSiteOrigin: origin ? {
203
+ present: true,
204
+ value: String(origin),
205
+ length: String(origin).length
206
+ } : {
207
+ present: false,
208
+ hint: 'Pass gridRequestSiteOrigin on WeatherLayerManager (RN falls back to https://localhost if omitted)'
209
+ },
210
+ willSendAppIdentifier: Boolean(bundleId && core?.isReactNative),
211
+ willSendOriginHeaders: Boolean(origin && String(origin).trim()),
212
+ ...extra
213
+ };
214
+ }
215
+
216
+ /**
217
+ * @param {Record<string, unknown>} options - {@link buildGridFrameProcessOptions} output
218
+ * @param {import('@aguacerowx/javascript-sdk').AguaceroCore} [core]
219
+ * @returns {Record<string, unknown>}
220
+ */
221
+ export function augmentProcessFrameOptionsForDebug(options, core) {
222
+ const out = {
223
+ ...options
224
+ };
225
+ if (!out.gridRequestSiteOrigin && core) {
226
+ const origin = resolveGridRequestSiteOrigin(undefined, core);
227
+ if (origin) {
228
+ out.gridRequestSiteOrigin = origin;
229
+ }
230
+ }
231
+ if (!isAguaceroRnDebugEnabled()) {
232
+ return out;
233
+ }
234
+ out.debug = true;
235
+ aguaceroDebug('processFrame.options', {
236
+ url: redactApiKeyFromUrl(out.url),
237
+ hasApiKeyInQuery: typeof out.url === 'string' && /[?&]apiKey=/i.test(out.url),
238
+ apiKey: describeSecret(out.apiKey),
239
+ bundleId: out.bundleId ? {
240
+ present: true,
241
+ value: String(out.bundleId)
242
+ } : {
243
+ present: false
244
+ },
245
+ gridRequestSiteOrigin: out.gridRequestSiteOrigin ?? null,
246
+ coreSnapshot: core ? getAguaceroAuthDiagnosticSnapshot(core) : undefined
247
+ });
248
+ return out;
249
+ }
250
+
251
+ /**
252
+ * @param {string | Request} input
253
+ * @param {RequestInit | undefined} init
254
+ */
255
+ function summarizeFetchRequest(input, init) {
256
+ const url = typeof input === 'string' ? input : input?.url;
257
+ const headers = new Headers(typeof input !== 'string' && input?.headers || init?.headers || undefined);
258
+ const headerRecord = {};
259
+ headers.forEach((v, k) => {
260
+ const lk = k.toLowerCase();
261
+ if (lk === 'x-api-key' || lk === 'authorization') {
262
+ headerRecord[k] = describeSecret(v);
263
+ } else {
264
+ headerRecord[k] = v;
265
+ }
266
+ });
267
+ return {
268
+ url: redactApiKeyFromUrl(url || ''),
269
+ method: init?.method || (typeof input !== 'string' ? input?.method : undefined) || 'GET',
270
+ headers: headerRecord,
271
+ hasApiKeyQuery: typeof url === 'string' && /[?&]apiKey=/i.test(url)
272
+ };
273
+ }
274
+
275
+ /**
276
+ * Patches `global.fetch` once to log Aguacero CDN / API traffic when debug is enabled.
277
+ */
278
+ export function installGlobalFetchLogger() {
279
+ if (_fetchLoggerInstalled || !isAguaceroRnDebugEnabled()) return;
280
+ if (typeof globalThis === 'undefined' || typeof globalThis.fetch !== 'function') return;
281
+ const originalFetch = globalThis.fetch.bind(globalThis);
282
+ _fetchLoggerInstalled = true;
283
+ globalThis.fetch = async function aguaceroInstrumentedFetch(input, init) {
284
+ const url = typeof input === 'string' ? input : input?.url;
285
+ const shouldLog = shouldLogAguaceroUrl(url || '');
286
+ const reqId = shouldLog ? `f${++_fetchSeq}` : null;
287
+ const started = Date.now();
288
+ if (shouldLog) {
289
+ aguaceroDebug('fetch.start', {
290
+ reqId,
291
+ ...summarizeFetchRequest(input, init)
292
+ });
293
+ }
294
+ try {
295
+ const response = await originalFetch(input, init);
296
+ if (shouldLog) {
297
+ const elapsedMs = Date.now() - started;
298
+ const base = {
299
+ reqId,
300
+ status: response.status,
301
+ statusText: response.statusText,
302
+ ok: response.ok,
303
+ elapsedMs,
304
+ url: redactApiKeyFromUrl(url || '')
305
+ };
306
+ if (!response.ok) {
307
+ let bodySnippet = null;
308
+ try {
309
+ const clone = response.clone();
310
+ const text = await clone.text();
311
+ bodySnippet = text.length > 600 ? `${text.slice(0, 600)}…` : text;
312
+ } catch {
313
+ bodySnippet = '(could not read body)';
314
+ }
315
+ aguaceroDebugWarn('fetch.httpError', {
316
+ ...base,
317
+ bodySnippet,
318
+ hint403: response.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.' : undefined
319
+ });
320
+ } else {
321
+ aguaceroDebug('fetch.ok', base);
322
+ }
323
+ }
324
+ return response;
325
+ } catch (err) {
326
+ if (shouldLog) {
327
+ aguaceroDebugWarn('fetch.throw', {
328
+ reqId,
329
+ message: err?.message || String(err),
330
+ elapsedMs: Date.now() - started,
331
+ url: redactApiKeyFromUrl(url || '')
332
+ });
333
+ }
334
+ throw err;
335
+ }
336
+ };
337
+ aguaceroDebug('fetch.hookInstalled', {
338
+ platform: Platform.OS
339
+ });
340
+ }
341
+ //# sourceMappingURL=aguaceroRnDebug.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["Platform","resolveGridRequestSiteOrigin","LOG_PREFIX","_explicitEnabled","_fetchLoggerInstalled","_fetchSeq","AGUACERO_URL_MARKERS","setAguaceroRnDebugEnabled","enabled","configureAguaceroRnDebug","Boolean","opts","on","isAguaceroRnDebugEnabled","globalThis","__AGUACERO_DEBUG__","__AGUACERO_WX_GRID_DEBUG__","__AGUACERO_NEXRAD_DEBUG__","installGlobalFetchLogger","aguaceroDebug","platform","OS","explicitFlag","globalFlag","safeGlobalDebugFlag","__DEV__","describeSecret","secret","present","length","s","String","trimmed","trim","trimmedLength","hasLeadingWhitespace","test","hasTrailingWhitespace","hasInternalWhitespace","indexOf","fingerprint","fingerprintSecret","looksLikePlaceholder","slice","redactApiKeyFromUrl","u","replace","shouldLogAguaceroUrl","url","lower","toLowerCase","some","m","includes","tag","detail","undefined","console","warn","aguaceroDebugWarn","getAguaceroAuthDiagnosticSnapshot","core","extra","apiKey","bundleId","origin","gridRequestSiteOrigin","isReactNative","baseGridUrl","value","hint","willSendAppIdentifier","willSendOriginHeaders","augmentProcessFrameOptionsForDebug","options","out","debug","hasApiKeyInQuery","coreSnapshot","summarizeFetchRequest","input","init","headers","Headers","headerRecord","forEach","v","k","lk","method","hasApiKeyQuery","fetch","originalFetch","bind","aguaceroInstrumentedFetch","shouldLog","reqId","started","Date","now","response","elapsedMs","base","status","statusText","ok","bodySnippet","clone","text","hint403","err","message"],"sourceRoot":"..\\..\\src","sources":["aguaceroRnDebug.js"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,56 @@
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
+ if (typeof propOrigin === 'string' && propOrigin.trim()) {
42
+ return normalize(propOrigin);
43
+ }
44
+ if (typeof core?.gridRequestSiteOrigin === 'string' && core.gridRequestSiteOrigin.trim()) {
45
+ return normalize(core.gridRequestSiteOrigin);
46
+ }
47
+ const fromGlobal = readGlobalGridRequestSiteOrigin();
48
+ if (fromGlobal) {
49
+ return fromGlobal;
50
+ }
51
+ if (core?.isReactNative) {
52
+ return RN_DEFAULT_GRID_REQUEST_SITE_ORIGIN;
53
+ }
54
+ return null;
55
+ }
56
+ //# sourceMappingURL=gridCdnAuth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["RN_DEFAULT_GRID_REQUEST_SITE_ORIGIN","readGlobalGridRequestSiteOrigin","g","globalThis","__AGUACERO_GRID_REQUEST_SITE_ORIGIN__","trim","replace","resolveGridRequestSiteOrigin","propOrigin","core","normalize","s","o","String","endsWith","slice","gridRequestSiteOrigin","fromGlobal","isReactNative"],"sourceRoot":"..\\..\\src","sources":["gridCdnAuth.js"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,OAAO,MAAMA,mCAAmC,GAAG,mBAAmB;;AAEtE;AACA;AACA;AACA,OAAO,SAASC,+BAA+BA,CAAA,EAAG;EAC9C,IAAI;IACA,MAAMC,CAAC,GAAGC,UAAU,CAACC,qCAAqC;IAC1D,IAAI,OAAOF,CAAC,KAAK,QAAQ,IAAIA,CAAC,CAACG,IAAI,CAAC,CAAC,EAAE;MACnC,OAAOH,CAAC,CAACG,IAAI,CAAC,CAAC,CAACC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;IACvC;EACJ,CAAC,CAAC,MAAM;IACJ;EAAA;EAEJ,OAAO,EAAE;AACb;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,4BAA4BA,CAACC,UAAU,EAAEC,IAAI,EAAE;EAC3D,MAAMC,SAAS,GAAIC,CAAC,IAAK;IACrB,IAAIC,CAAC,GAAGC,MAAM,CAACF,CAAC,CAAC,CAACN,IAAI,CAAC,CAAC;IACxB,OAAOO,CAAC,CAACE,QAAQ,CAAC,GAAG,CAAC,EAAE;MACpBF,CAAC,GAAGA,CAAC,CAACG,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACtB;IACA,OAAOH,CAAC;EACZ,CAAC;EAED,IAAI,OAAOJ,UAAU,KAAK,QAAQ,IAAIA,UAAU,CAACH,IAAI,CAAC,CAAC,EAAE;IACrD,OAAOK,SAAS,CAACF,UAAU,CAAC;EAChC;EACA,IAAI,OAAOC,IAAI,EAAEO,qBAAqB,KAAK,QAAQ,IAAIP,IAAI,CAACO,qBAAqB,CAACX,IAAI,CAAC,CAAC,EAAE;IACtF,OAAOK,SAAS,CAACD,IAAI,CAACO,qBAAqB,CAAC;EAChD;EACA,MAAMC,UAAU,GAAGhB,+BAA+B,CAAC,CAAC;EACpD,IAAIgB,UAAU,EAAE;IACZ,OAAOA,UAAU;EACrB;EACA,IAAIR,IAAI,EAAES,aAAa,EAAE;IACrB,OAAOlB,mCAAmC;EAC9C;EACA,OAAO,IAAI;AACf","ignoreList":[]}
@@ -1,5 +1,7 @@
1
1
  export { MapManager } from './MapManager';
2
2
  export { WeatherLayerManager } from './WeatherLayerManager';
3
+ export { configureAguaceroRnDebug, setAguaceroRnDebugEnabled, isAguaceroRnDebugEnabled, getAguaceroAuthDiagnosticSnapshot, aguaceroDebug, aguaceroDebugWarn } from './aguaceroRnDebug';
4
+ export { resolveGridRequestSiteOrigin, RN_DEFAULT_GRID_REQUEST_SITE_ORIGIN } from './gridCdnAuth';
3
5
  export { default as GridRenderLayer } from './GridRenderLayerNativeComponent';
4
6
  export { AGUACERO_NEXRAD_MAP_LAYER_ID, AGUACERO_SATELLITE_MAP_LAYER_ID } from './nws/nwsAndroidConstants';
5
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["MapManager","WeatherLayerManager","default","GridRenderLayer","AGUACERO_NEXRAD_MAP_LAYER_ID","AGUACERO_SATELLITE_MAP_LAYER_ID"],"sourceRoot":"..\\..\\src","sources":["index.js"],"mappings":"AAAA,SAASA,UAAU,QAAQ,cAAc;AACzC,SAASC,mBAAmB,QAAQ,uBAAuB;AAC3D,SAASC,OAAO,IAAIC,eAAe,QAAQ,kCAAkC;AAC7E,SACEC,4BAA4B,EAC5BC,+BAA+B,QAC1B,2BAA2B","ignoreList":[]}
1
+ {"version":3,"names":["MapManager","WeatherLayerManager","configureAguaceroRnDebug","setAguaceroRnDebugEnabled","isAguaceroRnDebugEnabled","getAguaceroAuthDiagnosticSnapshot","aguaceroDebug","aguaceroDebugWarn","resolveGridRequestSiteOrigin","RN_DEFAULT_GRID_REQUEST_SITE_ORIGIN","default","GridRenderLayer","AGUACERO_NEXRAD_MAP_LAYER_ID","AGUACERO_SATELLITE_MAP_LAYER_ID"],"sourceRoot":"..\\..\\src","sources":["index.js"],"mappings":"AAAA,SAASA,UAAU,QAAQ,cAAc;AACzC,SAASC,mBAAmB,QAAQ,uBAAuB;AAC3D,SACIC,wBAAwB,EACxBC,yBAAyB,EACzBC,wBAAwB,EACxBC,iCAAiC,EACjCC,aAAa,EACbC,iBAAiB,QACd,mBAAmB;AAC1B,SACIC,4BAA4B,EAC5BC,mCAAmC,QAChC,eAAe;AACtB,SAASC,OAAO,IAAIC,eAAe,QAAQ,kCAAkC;AAC7E,SACEC,4BAA4B,EAC5BC,+BAA+B,QAC1B,2BAA2B","ignoreList":[]}
@@ -1,5 +1,5 @@
1
- /**
2
- * AguaceroCore NEXRAD → Android native custom layer (parity with mapsgl {@link NexradWeatherController}).
1
+ /**
2
+ * AguaceroCore NEXRAD → Android native custom layer (parity with mapsgl {@link NexradWeatherController}).
3
3
  */
4
4
  import { getUnitConversionFunction, getDefaultRadarTilt, nexradBinGroupIdForKey, variableToNexradGroup } from '@aguacerowx/javascript-sdk';
5
5
  import { fromByteArray } from 'base64-js';
@@ -10,6 +10,7 @@ import { sampleNexradFrameAtLatLon } from './nexradCrossSectionSampleAtLatLon.bu
10
10
  import { buildNexradLutRgba } from './nexradLutBuild.js';
11
11
  import { Platform } from 'react-native';
12
12
  import { nexradDiagBootSnapshot, nexradDiagGateTextureSummary, nexradPerfSpan } from './nexradDiag.js';
13
+ import { aguaceroDebug, getAguaceroAuthDiagnosticSnapshot, isAguaceroRnDebugEnabled } from '../aguaceroRnDebug';
13
14
  nexradDiagBootSnapshot({
14
15
  archiveExports: {
15
16
  setNexradArchiveApiKey: typeof setNexradArchiveApiKey,
@@ -163,10 +164,10 @@ function rleCompressGateData(gateData) {
163
164
  return out.subarray(0, outIdx);
164
165
  }
165
166
  export class NexradAndroidController {
166
- /**
167
- * @param {*} core - AguaceroCore instance
168
- * @param {React.MutableRefObject<{ uploadNexradFrame?: (s: string) => void; uploadNexradStyleOnly?: (s: string) => void; clearNexrad?: () => void; activateNexradCachedFrame?: (k: string) => void } | null>} layerRef
169
- * @param {object} [options]
167
+ /**
168
+ * @param {*} core - AguaceroCore instance
169
+ * @param {React.MutableRefObject<{ uploadNexradFrame?: (s: string) => void; uploadNexradStyleOnly?: (s: string) => void; clearNexrad?: () => void; activateNexradCachedFrame?: (k: string) => void } | null>} layerRef
170
+ * @param {object} [options]
170
171
  */
171
172
  constructor(core, layerRef, options = {}) {
172
173
  this.core = core;
@@ -212,7 +213,12 @@ export class NexradAndroidController {
212
213
  setNexradSitesJsonUrl(`${base}/data/nexrad.json`);
213
214
  setNexradSitesFetchAuth(core.apiKey || '', core.bundleId || '');
214
215
  }
215
- setNexradArchiveSiteOrigin(core.gridRequestSiteOrigin || '');
216
+ setNexradArchiveSiteOrigin(core.gridRequestSiteOrigin || 'https://localhost');
217
+ if (isAguaceroRnDebugEnabled()) {
218
+ aguaceroDebug('nexrad.authConfigured', getAguaceroAuthDiagnosticSnapshot(core, {
219
+ phase: 'NexradAndroidController.constructor'
220
+ }));
221
+ }
216
222
  }
217
223
  _trimNativeGpuReadyKeys(max) {
218
224
  while (this._nativeGpuReadyKeys.size > max) {
@@ -296,10 +302,10 @@ export class NexradAndroidController {
296
302
  };
297
303
  }
298
304
 
299
- /**
300
- * LRU for full native JSON payloads (parity with mapsgl gate-texture reuse — avoids base64 + stringify on repeat scrubs).
301
- * @param {string} syncKey
302
- * @returns {{ json: string; valueScale: number; valueOffset: number } | null}
305
+ /**
306
+ * LRU for full native JSON payloads (parity with mapsgl gate-texture reuse — avoids base64 + stringify on repeat scrubs).
307
+ * @param {string} syncKey
308
+ * @returns {{ json: string; valueScale: number; valueOffset: number } | null}
303
309
  */
304
310
  _nativeUploadJsonLruTouch(syncKey) {
305
311
  const ent = this._nativeUploadJsonLru.get(syncKey);
@@ -320,18 +326,18 @@ export class NexradAndroidController {
320
326
  }
321
327
  }
322
328
 
323
- /**
324
- * Full-frame JSON includes LUT + opacity + shader toggles; keep LRU key aligned so scrubbing
325
- * cannot resurrect an outdated style after the user changes only presentation options.
329
+ /**
330
+ * Full-frame JSON includes LUT + opacity + shader toggles; keep LRU key aligned so scrubbing
331
+ * cannot resurrect an outdated style after the user changes only presentation options.
326
332
  */
327
333
  _nativeUploadLruKey(state, syncKey) {
328
334
  return `${syncKey}|o:${state.opacity ?? 1}|g:${this._gateSmoothing ? 1 : 0}|i:${this._interpolateColormap ? 1 : 0}`;
329
335
  }
330
336
 
331
- /**
332
- * After JS decoded a frame into `_frameCache`, optionally push it through the native bridge.
333
- * During timeline preload we **only** upload the **currently displayed** unix to Metal; other
334
- * volumes stay in the JS cache until {@link sync} needs them (avoids 40+ full decodes on load).
337
+ /**
338
+ * After JS decoded a frame into `_frameCache`, optionally push it through the native bridge.
339
+ * During timeline preload we **only** upload the **currently displayed** unix to Metal; other
340
+ * volumes stay in the JS cache until {@link sync} needs them (avoids 40+ full decodes on load).
335
341
  */
336
342
  _primeNativeGpuUploadIfNeeded(snapshot, unix, p, frame, abortSignal) {
337
343
  if (!frame || !p || abortSignal && abortSignal.aborted) return;
@@ -353,11 +359,11 @@ export class NexradAndroidController {
353
359
  }
354
360
  }
355
361
 
356
- /**
357
- * @param {*} state
358
- * @param {*} frame - decoded archive frame
359
- * @param {{ fetchKey: string }} p - from {@link _buildFetchParamsForUnix}
360
- * @param {number} unix
362
+ /**
363
+ * @param {*} state
364
+ * @param {*} frame - decoded archive frame
365
+ * @param {{ fetchKey: string }} p - from {@link _buildFetchParamsForUnix}
366
+ * @param {number} unix
361
367
  */
362
368
  _uploadFrameToNative(state, frame, p, unix) {
363
369
  const uploadTotal = nexradPerfSpan(`uploadFrame.total site=${state.nexradSite} unix=${unix} var=${p?.radarVar ?? state.nexradProduct}`);
@@ -674,8 +680,15 @@ export class NexradAndroidController {
674
680
 
675
681
  setNexradArchiveApiKey(this.core.apiKey || '');
676
682
  setNexradArchiveBundleId(this.core.bundleId || '');
677
- setNexradArchiveSiteOrigin(this.core.gridRequestSiteOrigin || '');
683
+ setNexradArchiveSiteOrigin(this.core.gridRequestSiteOrigin || 'https://localhost');
678
684
  setNexradSitesFetchAuth(this.core.apiKey || '', this.core.bundleId || '');
685
+ if (isAguaceroRnDebugEnabled()) {
686
+ aguaceroDebug('nexrad.authConfigured', getAguaceroAuthDiagnosticSnapshot(this.core, {
687
+ phase: 'NexradAndroidController.preload',
688
+ site: state.nexradSite,
689
+ product: state.nexradProduct
690
+ }));
691
+ }
679
692
  const snapshot = {
680
693
  ...state
681
694
  };
@@ -797,7 +810,7 @@ export class NexradAndroidController {
797
810
  const tAuth = nexradPerfSpan('sync.setArchiveAuth');
798
811
  setNexradArchiveApiKey(this.core.apiKey || '');
799
812
  setNexradArchiveBundleId(this.core.bundleId || '');
800
- setNexradArchiveSiteOrigin(this.core.gridRequestSiteOrigin || '');
813
+ setNexradArchiveSiteOrigin(this.core.gridRequestSiteOrigin || 'https://localhost');
801
814
  setNexradSitesFetchAuth(this.core.apiKey || '', this.core.bundleId || '');
802
815
  tAuth.end({});
803
816
  const unix = Number(state.nexradTimestamp);