@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.
- package/android/src/main/java/com/aguacerowx/reactnative/SatelliteLayerView.java +11 -3
- package/android/src/main/java/com/aguacerowx/reactnative/WeatherFrameProcessorModule.java +315 -275
- package/ios/SatelliteLayerView.swift +11 -4
- package/ios/WeatherFrameProcessorModule.swift +222 -188
- package/lib/commonjs/WeatherLayerManager.js +112 -48
- package/lib/commonjs/WeatherLayerManager.js.map +1 -1
- package/lib/commonjs/aguaceroCoreDebugHooks.js +144 -0
- package/lib/commonjs/aguaceroCoreDebugHooks.js.map +1 -0
- package/lib/commonjs/aguaceroRnDebug.js +358 -0
- package/lib/commonjs/aguaceroRnDebug.js.map +1 -0
- package/lib/commonjs/gridCdnAuth.js +64 -0
- package/lib/commonjs/gridCdnAuth.js.map +1 -0
- package/lib/commonjs/index.js +50 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/nexrad/nexradAndroidController.js +38 -25
- package/lib/commonjs/nexrad/nexradAndroidController.js.map +1 -1
- package/lib/commonjs/nexrad/nexradDiag.js +31 -25
- package/lib/commonjs/nexrad/nexradDiag.js.map +1 -1
- package/lib/commonjs/satellite/satelliteAndroidController.js +24 -15
- package/lib/commonjs/satellite/satelliteAndroidController.js.map +1 -1
- package/lib/module/WeatherLayerManager.js +112 -48
- package/lib/module/WeatherLayerManager.js.map +1 -1
- package/lib/module/aguaceroCoreDebugHooks.js +136 -0
- package/lib/module/aguaceroCoreDebugHooks.js.map +1 -0
- package/lib/module/aguaceroRnDebug.js +341 -0
- package/lib/module/aguaceroRnDebug.js.map +1 -0
- package/lib/module/gridCdnAuth.js +56 -0
- package/lib/module/gridCdnAuth.js.map +1 -0
- package/lib/module/index.js +2 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/nexrad/nexradAndroidController.js +38 -25
- package/lib/module/nexrad/nexradAndroidController.js.map +1 -1
- package/lib/module/nexrad/nexradDiag.js +31 -25
- package/lib/module/nexrad/nexradDiag.js.map +1 -1
- package/lib/module/satellite/satelliteAndroidController.js +24 -15
- package/lib/module/satellite/satelliteAndroidController.js.map +1 -1
- package/lib/typescript/WeatherLayerManager.d.ts.map +1 -1
- package/lib/typescript/aguaceroCoreDebugHooks.d.ts +10 -0
- package/lib/typescript/aguaceroCoreDebugHooks.d.ts.map +1 -0
- package/lib/typescript/aguaceroRnDebug.d.ts +97 -0
- package/lib/typescript/aguaceroRnDebug.d.ts.map +1 -0
- package/lib/typescript/gridCdnAuth.d.ts +24 -0
- package/lib/typescript/gridCdnAuth.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +2 -0
- package/lib/typescript/nexrad/nexradAndroidController.d.ts.map +1 -1
- package/lib/typescript/nexrad/nexradDiag.d.ts.map +1 -1
- package/lib/typescript/satellite/satelliteAndroidController.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/WeatherLayerManager.js +2024 -1947
- package/src/aguaceroCoreDebugHooks.js +142 -0
- package/src/aguaceroRnDebug.js +335 -0
- package/src/gridCdnAuth.js +56 -0
- package/src/index.js +19 -7
- package/src/nexrad/nexradAndroidController.js +1078 -1068
- package/src/nexrad/nexradDiag.js +150 -144
- package/src/satellite/satelliteAndroidController.js +245 -236
|
@@ -14,6 +14,9 @@ import { SatelliteAndroidController } from './satellite/satelliteAndroidControll
|
|
|
14
14
|
import NwsAlertsOverlay from './nws/NwsAlertsOverlay';
|
|
15
15
|
import { mapRegistry } from './MapRegistry';
|
|
16
16
|
import { satBridgeWarn } from './satelliteBridgeDiag';
|
|
17
|
+
import { augmentProcessFrameOptionsForDebug, aguaceroDebugWarn, configureAguaceroRnDebug, getAguaceroAuthDiagnosticSnapshot, isAguaceroRnDebugEnabled } from './aguaceroRnDebug';
|
|
18
|
+
import { installAguaceroCoreDebugHooks, logProcessFrameAuthMismatch } from './aguaceroCoreDebugHooks';
|
|
19
|
+
import { resolveGridRequestSiteOrigin } from './gridCdnAuth';
|
|
17
20
|
const NEXRAD_NATIVE = Platform.OS === 'android' || Platform.OS === 'ios';
|
|
18
21
|
const SATELLITE_NATIVE = Platform.OS === 'android' || Platform.OS === 'ios';
|
|
19
22
|
satBridgeWarn('SDK fingerprint', {
|
|
@@ -22,9 +25,9 @@ satBridgeWarn('SDK fingerprint', {
|
|
|
22
25
|
note: 'If you never see sat-bridge logs, the app bundle is not loading this WeatherLayerManager build.'
|
|
23
26
|
});
|
|
24
27
|
|
|
25
|
-
/**
|
|
26
|
-
* Same filtering as {@link AguaceroCore#_getFilteredMrmsTimestampsForVariable} for older cores
|
|
27
|
-
* where that helper (or {@code setMRMSDurationValue}) is missing from the prototype chain.
|
|
28
|
+
/**
|
|
29
|
+
* Same filtering as {@link AguaceroCore#_getFilteredMrmsTimestampsForVariable} for older cores
|
|
30
|
+
* where that helper (or {@code setMRMSDurationValue}) is missing from the prototype chain.
|
|
28
31
|
*/
|
|
29
32
|
function getFilteredMrmsTimestampsCompat(core, variable) {
|
|
30
33
|
const raw = core.mrmsStatus?.[variable];
|
|
@@ -39,9 +42,9 @@ function getFilteredMrmsTimestampsCompat(core, variable) {
|
|
|
39
42
|
return list;
|
|
40
43
|
}
|
|
41
44
|
|
|
42
|
-
/**
|
|
43
|
-
* Older npm installs may resolve an {@link AguaceroCore} without {@code setMRMSDurationValue} /
|
|
44
|
-
* {@code setNexradDurationValue}; mirror those methods here using the same logic as the SDK.
|
|
45
|
+
/**
|
|
46
|
+
* Older npm installs may resolve an {@link AguaceroCore} without {@code setMRMSDurationValue} /
|
|
47
|
+
* {@code setNexradDurationValue}; mirror those methods here using the same logic as the SDK.
|
|
45
48
|
*/
|
|
46
49
|
async function applyMrmsDurationValue(core, value) {
|
|
47
50
|
if (typeof core.setMRMSDurationValue === 'function') {
|
|
@@ -106,12 +109,12 @@ const {
|
|
|
106
109
|
InspectorModule
|
|
107
110
|
} = NativeModules;
|
|
108
111
|
|
|
109
|
-
/**
|
|
110
|
-
* `state:change` payloads can briefly have {@code isNexrad} before {@code nexradSite} / {@code nexradTimestamp}
|
|
111
|
-
* are populated; {@code core.state} is updated first. Merge so readouts match the active radar.
|
|
112
|
-
*
|
|
113
|
-
* @param {object | null} emitted
|
|
114
|
-
* @param {object | null} coreState
|
|
112
|
+
/**
|
|
113
|
+
* `state:change` payloads can briefly have {@code isNexrad} before {@code nexradSite} / {@code nexradTimestamp}
|
|
114
|
+
* are populated; {@code core.state} is updated first. Merge so readouts match the active radar.
|
|
115
|
+
*
|
|
116
|
+
* @param {object | null} emitted
|
|
117
|
+
* @param {object | null} coreState
|
|
115
118
|
*/
|
|
116
119
|
function mergeNexradEmittedWithCore(emitted, coreState) {
|
|
117
120
|
if (!emitted || !coreState) return null;
|
|
@@ -126,10 +129,10 @@ function mergeNexradEmittedWithCore(emitted, coreState) {
|
|
|
126
129
|
};
|
|
127
130
|
}
|
|
128
131
|
|
|
129
|
-
/**
|
|
130
|
-
* Compact timeline identity for deduping {@code state:change}: extending the NEXRAD/satellite window
|
|
131
|
-
* often keeps the same selected unix — without this, {@link WeatherLayerManager} short-circuits and
|
|
132
|
-
* never calls native {@code sync} / preload with the expanded frame list.
|
|
132
|
+
/**
|
|
133
|
+
* Compact timeline identity for deduping {@code state:change}: extending the NEXRAD/satellite window
|
|
134
|
+
* often keeps the same selected unix — without this, {@link WeatherLayerManager} short-circuits and
|
|
135
|
+
* never calls native {@code sync} / preload with the expanded frame list.
|
|
133
136
|
*/
|
|
134
137
|
function nexradObsTimelineSig(state) {
|
|
135
138
|
const arr = [...(state?.availableNexradTimestamps || [])].map(Number).filter(t => Number.isFinite(t)).sort((a, b) => a - b);
|
|
@@ -142,8 +145,9 @@ function satelliteObsTimelineSig(state) {
|
|
|
142
145
|
return `${keys.length}:${keys[0]}:${keys[keys.length - 1]}`;
|
|
143
146
|
}
|
|
144
147
|
|
|
145
|
-
/** True
|
|
148
|
+
/** True when {@link WeatherLayerManager} `debug` / {@link configureAguaceroRnDebug}, or legacy `__AGUACERO_WX_GRID_DEBUG__`. */
|
|
146
149
|
function wxGridDebugEnabled() {
|
|
150
|
+
if (isAguaceroRnDebugEnabled()) return true;
|
|
147
151
|
try {
|
|
148
152
|
if (typeof __DEV__ !== 'undefined' && __DEV__) return true;
|
|
149
153
|
return Boolean(typeof globalThis !== 'undefined' && globalThis.__AGUACERO_WX_GRID_DEBUG__);
|
|
@@ -169,37 +173,34 @@ function wxGridWarn(tag, detail) {
|
|
|
169
173
|
}
|
|
170
174
|
}
|
|
171
175
|
|
|
172
|
-
/**
|
|
173
|
-
* Native {@code processFrame} must mirror browser/AguaceroCore grid auth: encoded {@code apiKey}
|
|
174
|
-
* in the query string and optional {@code Origin} / {@code Referer} (many CloudFront setups require them).
|
|
175
|
-
*
|
|
176
|
-
* @param {string} baseGridUrl
|
|
177
|
-
* @param {string} resourcePath
|
|
178
|
-
* @param {string} apiKey
|
|
179
|
-
* @param {string | null | undefined} bundleId
|
|
180
|
-
* @param {string | undefined} gridRequestSiteOrigin -
|
|
176
|
+
/**
|
|
177
|
+
* Native {@code processFrame} must mirror browser/AguaceroCore grid auth: encoded {@code apiKey}
|
|
178
|
+
* in the query string and optional {@code Origin} / {@code Referer} (many CloudFront setups require them).
|
|
179
|
+
*
|
|
180
|
+
* @param {string} baseGridUrl
|
|
181
|
+
* @param {string} resourcePath
|
|
182
|
+
* @param {string} apiKey
|
|
183
|
+
* @param {string | null | undefined} bundleId
|
|
184
|
+
* @param {string | undefined} gridRequestSiteOrigin - prop or core origin (see {@link resolveGridRequestSiteOrigin})
|
|
185
|
+
* @param {import('@aguacerowx/javascript-sdk').AguaceroCore | null | undefined} core
|
|
181
186
|
*/
|
|
182
|
-
function buildGridFrameProcessOptions(baseGridUrl, resourcePath, apiKey, bundleId, gridRequestSiteOrigin) {
|
|
183
|
-
const
|
|
187
|
+
function buildGridFrameProcessOptions(baseGridUrl, resourcePath, apiKey, bundleId, gridRequestSiteOrigin, core) {
|
|
188
|
+
const trimmedKey = typeof apiKey === 'string' ? apiKey.trim() : apiKey;
|
|
189
|
+
const url = `${baseGridUrl}${resourcePath}?apiKey=${encodeURIComponent(trimmedKey || '')}`;
|
|
184
190
|
const options = {
|
|
185
191
|
url,
|
|
186
|
-
apiKey,
|
|
192
|
+
apiKey: trimmedKey,
|
|
187
193
|
bundleId
|
|
188
194
|
};
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
origin = origin.slice(0, -1);
|
|
193
|
-
}
|
|
194
|
-
if (origin.length > 0) {
|
|
195
|
-
options.gridRequestSiteOrigin = origin;
|
|
196
|
-
}
|
|
195
|
+
const origin = resolveGridRequestSiteOrigin(gridRequestSiteOrigin, core);
|
|
196
|
+
if (origin) {
|
|
197
|
+
options.gridRequestSiteOrigin = origin;
|
|
197
198
|
}
|
|
198
199
|
return options;
|
|
199
200
|
}
|
|
200
201
|
|
|
201
|
-
/**
|
|
202
|
-
* A helper function to generate the raw RGBA byte buffer for the colormap texture.
|
|
202
|
+
/**
|
|
203
|
+
* A helper function to generate the raw RGBA byte buffer for the colormap texture.
|
|
203
204
|
*/
|
|
204
205
|
const _generateColormapBytes = colormap => {
|
|
205
206
|
const width = 256;
|
|
@@ -261,8 +262,15 @@ export const WeatherLayerManager = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
261
262
|
onNwsAlertClick,
|
|
262
263
|
/** Same semantics as mapsgl / AguaceroCore: Origin + Referer for grid CDN (required by many CloudFront rules). */
|
|
263
264
|
gridRequestSiteOrigin,
|
|
265
|
+
/** When true, logs auth/HTTP diagnostics under `[AguaceroRN][debug]` (Metro / Logcat / Xcode). */
|
|
266
|
+
debug = false,
|
|
264
267
|
...restProps
|
|
265
268
|
} = props;
|
|
269
|
+
useEffect(() => {
|
|
270
|
+
configureAguaceroRnDebug({
|
|
271
|
+
enabled: Boolean(debug)
|
|
272
|
+
});
|
|
273
|
+
}, [debug]);
|
|
266
274
|
const context = useContext(AguaceroContext);
|
|
267
275
|
|
|
268
276
|
// Create the core here instead of getting it from context
|
|
@@ -277,6 +285,24 @@ export const WeatherLayerManager = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
277
285
|
},
|
|
278
286
|
autoRefresh: false // <-- add this
|
|
279
287
|
}), [apiKey, gridRequestSiteOrigin]);
|
|
288
|
+
useEffect(() => {
|
|
289
|
+
if (!core) return;
|
|
290
|
+
installAguaceroCoreDebugHooks(core, {
|
|
291
|
+
gridRequestSiteOriginProp: gridRequestSiteOrigin ?? null,
|
|
292
|
+
debugProp: Boolean(debug)
|
|
293
|
+
});
|
|
294
|
+
if (isAguaceroRnDebugEnabled() && !apiKey) {
|
|
295
|
+
aguaceroDebugWarn('WeatherLayerManager.missingApiKey', {
|
|
296
|
+
hint: 'apiKey prop is empty — all CDN requests will fail or return 403'
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
if (isAguaceroRnDebugEnabled() && apiKey && !gridRequestSiteOrigin) {
|
|
300
|
+
aguaceroDebugWarn('WeatherLayerManager.missingGridOrigin', {
|
|
301
|
+
hint: 'gridRequestSiteOrigin is not set — CloudFront often returns 403 without Origin/Referer on React Native',
|
|
302
|
+
snapshot: getAguaceroAuthDiagnosticSnapshot(core)
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
}, [core, debug, gridRequestSiteOrigin, apiKey]);
|
|
280
306
|
const [watchesWarningsOptions, setWatchesWarningsOptions] = useState(() => ({
|
|
281
307
|
alertInteractionEnabled: true,
|
|
282
308
|
...(watchesWarningsProp ?? {})
|
|
@@ -380,6 +406,8 @@ export const WeatherLayerManager = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
380
406
|
// Track if we've done the initial load
|
|
381
407
|
const hasInitialLoad = useRef(false);
|
|
382
408
|
const hasPreloadedRef = useRef(false);
|
|
409
|
+
/** Bumped on {@code cancelAllFrames} / full reload so stale {@code processFrame} results are ignored. */
|
|
410
|
+
const preloadGenerationRef = useRef(0);
|
|
383
411
|
|
|
384
412
|
// Track the last state we processed to avoid redundant updates
|
|
385
413
|
const lastProcessedState = useRef(null);
|
|
@@ -460,9 +488,9 @@ export const WeatherLayerManager = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
460
488
|
refreshData: () => {
|
|
461
489
|
_checkForUpdates();
|
|
462
490
|
},
|
|
463
|
-
/**
|
|
464
|
-
* NWS watches/warnings (native map, iOS + Android): same options as mapsgl {@link WeatherLayerManager#configureWatchesWarnings}.
|
|
465
|
-
* @param {object} partial
|
|
491
|
+
/**
|
|
492
|
+
* NWS watches/warnings (native map, iOS + Android): same options as mapsgl {@link WeatherLayerManager#configureWatchesWarnings}.
|
|
493
|
+
* @param {object} partial
|
|
466
494
|
*/
|
|
467
495
|
configureWatchesWarnings: partial => {
|
|
468
496
|
setWatchesWarningsOptions(prev => ({
|
|
@@ -526,6 +554,8 @@ export const WeatherLayerManager = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
526
554
|
|
|
527
555
|
// Only mark as "has preloaded" after validation passes
|
|
528
556
|
hasPreloadedRef.current = true;
|
|
557
|
+
const generation = preloadGenerationRef.current;
|
|
558
|
+
const isStaleGeneration = () => generation !== preloadGenerationRef.current;
|
|
529
559
|
wxGridVerbose('preloadStart', {
|
|
530
560
|
isMRMS,
|
|
531
561
|
model,
|
|
@@ -642,7 +672,11 @@ export const WeatherLayerManager = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
642
672
|
} else {
|
|
643
673
|
resourcePath = `/grids/${model}/${date}/${run}/${currentFrame}/${variable}/0`;
|
|
644
674
|
}
|
|
645
|
-
const options = buildGridFrameProcessOptions(core.baseGridUrl, resourcePath, core.apiKey, core.bundleId, gridRequestSiteOrigin);
|
|
675
|
+
const options = augmentProcessFrameOptionsForDebug(buildGridFrameProcessOptions(core.baseGridUrl, resourcePath, core.apiKey, core.bundleId, gridRequestSiteOrigin, core), core);
|
|
676
|
+
logProcessFrameAuthMismatch(core, options, {
|
|
677
|
+
phase: 'preloadCurrent',
|
|
678
|
+
currentCacheKey
|
|
679
|
+
});
|
|
646
680
|
try {
|
|
647
681
|
wxGridVerbose('processFrameRequest', {
|
|
648
682
|
currentCacheKey,
|
|
@@ -650,6 +684,13 @@ export const WeatherLayerManager = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
650
684
|
frame: currentFrame
|
|
651
685
|
});
|
|
652
686
|
const result = await WeatherFrameProcessorModule.processFrame(options);
|
|
687
|
+
if (isStaleGeneration()) {
|
|
688
|
+
wxGridVerbose('preloadCurrentFrameStale', {
|
|
689
|
+
currentCacheKey,
|
|
690
|
+
generation
|
|
691
|
+
});
|
|
692
|
+
return;
|
|
693
|
+
}
|
|
653
694
|
if (!result || !result.filePath) {
|
|
654
695
|
hasPreloadedRef.current = false;
|
|
655
696
|
wxGridWarn('preloadAbort', {
|
|
@@ -747,12 +788,20 @@ export const WeatherLayerManager = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
747
788
|
const cancelled = e && (e.code === 'E_CANCELLED' || e?.userInfo?.code === 'E_CANCELLED' || typeof e?.message === 'string' && e.message.includes('superseded'));
|
|
748
789
|
if (!cancelled) {
|
|
749
790
|
hasPreloadedRef.current = false;
|
|
750
|
-
|
|
791
|
+
const errDetail = {
|
|
751
792
|
currentCacheKey,
|
|
752
793
|
code: e?.code,
|
|
753
794
|
message: e?.message,
|
|
754
795
|
userInfo: e?.userInfo
|
|
755
|
-
}
|
|
796
|
+
};
|
|
797
|
+
wxGridWarn('preloadProcessFrameError', errDetail);
|
|
798
|
+
if (isAguaceroRnDebugEnabled()) {
|
|
799
|
+
aguaceroDebugWarn('preloadProcessFrameError', {
|
|
800
|
+
...errDetail,
|
|
801
|
+
auth: getAguaceroAuthDiagnosticSnapshot(core),
|
|
802
|
+
is403: e?.code === 'HTTP_ERROR' && typeof e?.message === 'string' && e.message.includes('403')
|
|
803
|
+
});
|
|
804
|
+
}
|
|
756
805
|
} else {
|
|
757
806
|
wxGridVerbose('preloadProcessFrameCancelled', {
|
|
758
807
|
currentCacheKey
|
|
@@ -777,8 +826,15 @@ export const WeatherLayerManager = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
777
826
|
} else {
|
|
778
827
|
resourcePath = `/grids/${model}/${date}/${run}/${frame}/${variable}/0`;
|
|
779
828
|
}
|
|
780
|
-
const options = buildGridFrameProcessOptions(core.baseGridUrl, resourcePath, core.apiKey, core.bundleId, gridRequestSiteOrigin);
|
|
829
|
+
const options = augmentProcessFrameOptionsForDebug(buildGridFrameProcessOptions(core.baseGridUrl, resourcePath, core.apiKey, core.bundleId, gridRequestSiteOrigin, core), core);
|
|
830
|
+
logProcessFrameAuthMismatch(core, options, {
|
|
831
|
+
phase: 'preloadBackground',
|
|
832
|
+
cacheKey
|
|
833
|
+
});
|
|
781
834
|
WeatherFrameProcessorModule.processFrame(options).then(result => {
|
|
835
|
+
if (isStaleGeneration()) {
|
|
836
|
+
return;
|
|
837
|
+
}
|
|
782
838
|
if (!result || !result.filePath) {
|
|
783
839
|
return;
|
|
784
840
|
}
|
|
@@ -1166,7 +1222,11 @@ export const WeatherLayerManager = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
1166
1222
|
m = (frameDate.getUTCMonth() + 1).toString().padStart(2, '0'),
|
|
1167
1223
|
d = frameDate.getUTCDate().toString().padStart(2, '0');
|
|
1168
1224
|
const resourcePath = `/grids/mrms/${y}${m}${d}/${frame}/0/${currentVariable}/0`;
|
|
1169
|
-
const options = buildGridFrameProcessOptions(core.baseGridUrl, resourcePath, core.apiKey, core.bundleId, gridRequestSiteOrigin);
|
|
1225
|
+
const options = augmentProcessFrameOptionsForDebug(buildGridFrameProcessOptions(core.baseGridUrl, resourcePath, core.apiKey, core.bundleId, gridRequestSiteOrigin, core), core);
|
|
1226
|
+
logProcessFrameAuthMismatch(core, options, {
|
|
1227
|
+
phase: 'mrmsRefresh',
|
|
1228
|
+
cacheKey
|
|
1229
|
+
});
|
|
1170
1230
|
WeatherFrameProcessorModule.processFrame(options).then(result => {
|
|
1171
1231
|
if (!result || !result.filePath) return;
|
|
1172
1232
|
const frameData = {
|
|
@@ -1431,6 +1491,7 @@ export const WeatherLayerManager = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
1431
1491
|
}
|
|
1432
1492
|
}
|
|
1433
1493
|
hasPreloadedRef.current = false;
|
|
1494
|
+
preloadGenerationRef.current += 1;
|
|
1434
1495
|
preloadedDataCache.current.clear();
|
|
1435
1496
|
cachedGeometry.current = null;
|
|
1436
1497
|
cachedColormap.current = null;
|
|
@@ -1438,7 +1499,8 @@ export const WeatherLayerManager = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
1438
1499
|
WeatherFrameProcessorModule.cancelAllFrames();
|
|
1439
1500
|
wxGridVerbose('cancelAllFrames', {
|
|
1440
1501
|
reason: 'needsFullLoad',
|
|
1441
|
-
variable: newState.variable
|
|
1502
|
+
variable: newState.variable,
|
|
1503
|
+
generation: preloadGenerationRef.current
|
|
1442
1504
|
});
|
|
1443
1505
|
if (!newState.variable) {
|
|
1444
1506
|
previousStateRef.current = newState;
|
|
@@ -1460,6 +1522,8 @@ export const WeatherLayerManager = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
1460
1522
|
mrmsTimestamp: newState.mrmsTimestamp,
|
|
1461
1523
|
forecastHour: newState.forecastHour
|
|
1462
1524
|
});
|
|
1525
|
+
hasPreloadedRef.current = false;
|
|
1526
|
+
void preloadAllFramesToDisk(newState);
|
|
1463
1527
|
}
|
|
1464
1528
|
if (success && newState.opacity !== renderProps.opacity) {
|
|
1465
1529
|
setRenderProps(prev => ({
|