@aguacerowx/javascript-sdk 0.0.4 → 0.0.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aguacerowx/javascript-sdk",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -7,7 +7,6 @@ import { getUnitConversionFunction } from './unitConversions.js';
7
7
  import { DICTIONARIES, MODEL_CONFIGS } from './dictionaries.js';
8
8
  import { DEFAULT_COLORMAPS } from './default-colormaps.js';
9
9
  import proj4 from 'proj4';
10
- import { decompress } from 'fzstd';
11
10
  import { getBundleId } from './getBundleId';
12
11
 
13
12
  // --- Non-UI Helper Functions ---
@@ -161,6 +160,7 @@ export class AguaceroCore extends EventEmitter {
161
160
 
162
161
  play() {
163
162
  if (this.isPlaying) return;
163
+ console.log('▶️ [Core] Play called');
164
164
  this.isPlaying = true;
165
165
  clearInterval(this.playIntervalId);
166
166
  this.playIntervalId = setInterval(() => { this.step(1); }, this.playbackSpeed);
@@ -170,6 +170,7 @@ export class AguaceroCore extends EventEmitter {
170
170
 
171
171
  pause() {
172
172
  if (!this.isPlaying) return;
173
+ console.log('⏸️ [Core] Pause called');
173
174
  this.isPlaying = false;
174
175
  clearInterval(this.playIntervalId);
175
176
  this.playIntervalId = null;
@@ -177,19 +178,65 @@ export class AguaceroCore extends EventEmitter {
177
178
  this._emitStateChange(); // Notify UI that isPlaying is now false
178
179
  }
179
180
 
180
- togglePlay() { this.isPlaying ? this.pause() : this.play(); }
181
+ togglePlay() {
182
+ console.log('⏯️ [Core] Toggle Play called');
183
+ this.isPlaying ? this.pause() : this.play();
184
+ }
181
185
 
182
186
  step(direction = 1) {
183
- const { model, date, run, forecastHour } = this.state;
184
- const forecastHours = this.modelStatus?.[model]?.[date]?.[run];
185
- if (!forecastHours || forecastHours.length === 0) return;
186
- const currentIndex = forecastHours.indexOf(forecastHour);
187
- if (currentIndex === -1) return;
188
- const maxIndex = forecastHours.length - 1;
189
- let nextIndex = currentIndex + direction;
190
- if (nextIndex > maxIndex) nextIndex = 0;
191
- if (nextIndex < 0) nextIndex = maxIndex;
192
- this.setState({ forecastHour: forecastHours[nextIndex] });
187
+ console.log(`[Core.step] Stepping... Direction: ${direction}, Mode: ${this.state.isMRMS ? 'MRMS' : 'Model'}`);
188
+
189
+ // --- THIS IS THE CORRECTED MRMS LOGIC ---
190
+ if (this.state.isMRMS) {
191
+ const { variable, mrmsTimestamp } = this.state;
192
+ if (!this.mrmsStatus || !this.mrmsStatus[variable]) {
193
+ console.warn('[Core.step] MRMS status or variable not available.');
194
+ return;
195
+ }
196
+
197
+ // CRITICAL FIX: The UI and state emissions use a REVERSED array (newest first).
198
+ // The step logic MUST use the same reversed array for indexes to match.
199
+ const availableTimestamps = [...(this.mrmsStatus[variable] || [])].reverse();
200
+ if (availableTimestamps.length === 0) return;
201
+
202
+ const currentIndex = availableTimestamps.indexOf(mrmsTimestamp);
203
+ console.log(`[Core.step] MRMS Current Timestamp: ${mrmsTimestamp}, Index: ${currentIndex}`);
204
+
205
+ if (currentIndex === -1) {
206
+ // If not found, reset to the first (newest) frame
207
+ this.setState({ mrmsTimestamp: availableTimestamps[0] });
208
+ return;
209
+ }
210
+
211
+ const maxIndex = availableTimestamps.length - 1;
212
+ let nextIndex = currentIndex + direction;
213
+
214
+ // Loop animation
215
+ if (nextIndex > maxIndex) nextIndex = 0;
216
+ if (nextIndex < 0) nextIndex = maxIndex;
217
+
218
+ const newTimestamp = availableTimestamps[nextIndex];
219
+ console.log(`[Core.step] MRMS New Index: ${nextIndex}, New Timestamp: ${newTimestamp}`);
220
+ this.setState({ mrmsTimestamp: newTimestamp });
221
+
222
+ } else {
223
+ const { model, date, run, forecastHour } = this.state;
224
+ const forecastHours = this.modelStatus?.[model]?.[date]?.[run];
225
+ if (!forecastHours || forecastHours.length === 0) return;
226
+
227
+ const currentIndex = forecastHours.indexOf(forecastHour);
228
+ console.log(`[Core.step] Model Current Hour: ${forecastHour}, Index: ${currentIndex}`);
229
+ if (currentIndex === -1) return;
230
+
231
+ const maxIndex = forecastHours.length - 1;
232
+ let nextIndex = currentIndex + direction;
233
+ if (nextIndex > maxIndex) nextIndex = 0;
234
+ if (nextIndex < 0) nextIndex = maxIndex;
235
+
236
+ const newHour = forecastHours[nextIndex];
237
+ console.log(`[Core.step] Model New Index: ${nextIndex}, New Hour: ${newHour}`);
238
+ this.setState({ forecastHour: newHour });
239
+ }
193
240
  }
194
241
 
195
242
  setPlaybackSpeed(speed) {
@@ -364,7 +411,7 @@ export class AguaceroCore extends EventEmitter {
364
411
  const baseUrl = `${this.baseGridUrl}${resourcePath}`;
365
412
  const urlWithApiKeyParam = `${baseUrl}?apiKey=${this.apiKey}`;
366
413
  const headers = { 'x-api-key': this.apiKey };
367
- if (this.bundleId) {
414
+ if (this.bundleId && this.isReactNative) {
368
415
  headers['x-app-identifier'] = this.bundleId;
369
416
  }
370
417
 
@@ -455,12 +502,33 @@ export class AguaceroCore extends EventEmitter {
455
502
  const index1D = j * nx + i;
456
503
  const byteValue = gridData.data[index1D];
457
504
  const signedQuantizedValue = byteValue - 128;
458
- const { scale, offset, missing_quantized } = gridData.encoding;
505
+
506
+ // --- START OF FIX ---
507
+ // You were missing 'scale_type' in this destructuring assignment.
508
+ const { scale, offset, missing_quantized, scale_type } = gridData.encoding;
509
+ // --- END OF FIX ---
459
510
 
460
511
  if (signedQuantizedValue === missing_quantized) return null;
461
512
 
462
- const nativeValue = signedQuantizedValue * scale + offset;
463
- const { baseUnit } = this._getColormapForVariable(variable);
513
+ const intermediateValue = signedQuantizedValue * scale + offset;
514
+
515
+ // Step 2: Apply non-linear scaling if specified
516
+ let nativeValue = intermediateValue;
517
+ if (scale_type === 'sqrt') {
518
+ // Square the value while preserving its sign
519
+ nativeValue = intermediateValue < 0 ? -(intermediateValue * intermediateValue) : (intermediateValue * intermediateValue);
520
+ }
521
+ const { colormap, baseUnit } = this._getColormapForVariable(variable);
522
+
523
+ // If the value is outside the colormap's bounds, return null.
524
+ if (colormap && colormap.length >= 2) {
525
+ const minBound = colormap[0];
526
+ const maxBound = colormap[colormap.length - 2];
527
+ if (nativeValue < minBound || nativeValue > maxBound) {
528
+ return null;
529
+ }
530
+ }
531
+
464
532
  let dataNativeUnit = baseUnit || (DICTIONARIES.fld[variable] || {}).defaultUnit || 'none';
465
533
 
466
534
  const displayUnit = this._getTargetUnit(dataNativeUnit, units);
@@ -278,7 +278,7 @@ export const MODEL_CONFIGS = {
278
278
  },
279
279
  'gfs': {
280
280
  max_zoom: 3,
281
- vars: ['2r_2', '2t_2', 'refd_1000', 'vis_0', 'gust_runmax', "gh_tendency_500", 'bulk_shear_speedmb_500', 'bulk_shear_speedmb_700', 'bulk_shear_speedmb_850', 'bulk_shear_speedmb_925','2t_2iso0', 'crain_total', 'crain_3', 'crain_6', 'crain_12', 'crain_24', 'crain_48', 'cicep_total', 'cicep_3', 'cicep_6', 'cicep_12', 'cicep_24', 'cicep_48', 'cfrzr_total', 'cfrzr_3', 'cfrzr_6', 'cfrzr_12', 'cfrzr_24', 'cfrzr_48', 'csnow_total', 'csnow_3', 'csnow_6', 'csnow_12', 'csnow_24', 'csnow_48', 'tp_0_total', 'tp_3', 'tp_6', 'tp_12', 'tp_24', 'tp_48', 'cin_0', 'wind_speed_700', 'wind_speed_200', 'divergence_200', 'd_925', 'tadv_300', 'w_850', 'rainRefl', 'icepRefl', 'snowRefl', 'frzrRefl', 'lftx_0', 'refc_0', 'fgen_850', 'hcc_0', 'r_700', 't_850', 't_850iso0', 'r_850', 'tcc_0', 'hlcy_3000', 'thickness', 'vo_850', 'wind_direction_2000', 'r_500', 'gh_500', 'wind_speed_500', '2d_2', 'cape_25500', 'mcc_0', 'w_500', 'pwat_0', 'divergence_850', 't_500', 'wind_speed_850', 'lcl', 'cape_0', 'tadv_850', 'tadv_700', 'theta2PVU', 'wind_speed_2000', 'lapse_rates_500700', 'vo_500', 'irsat', 't_700', 't_700iso0', 'cin_25500', 'ehi_3000', 'lcc_0', 'gh_850', 'wind_speed_925', 'gh_200', 'wind_speed_300', 'fgen_700', 'vo_700', 'd_850', 'thetaE', 'pres2PVU', 'd_700', 'crain', 'csnow', 'cicep', 'cfrzr', 'w_700', 'gust_0', 'ivt', 'atemp', 'cape_9000', 'r_925', 'mslma_0', 'w_925', 'cin_9000', 'mean700300mbRH', 'wind_speed_10', 't_925', 't_925iso0', 'gh_925', 'gh_700', 'gh_300'],
281
+ vars: ['tp_0_total', '2r_2', '2t_2', 'refd_1000', 'vis_0', 'gust_runmax', "gh_tendency_500", 'bulk_shear_speedmb_500', 'bulk_shear_speedmb_700', 'bulk_shear_speedmb_850', 'bulk_shear_speedmb_925','2t_2iso0', 'crain_total', 'crain_3', 'crain_6', 'crain_12', 'crain_24', 'crain_48', 'cicep_total', 'cicep_3', 'cicep_6', 'cicep_12', 'cicep_24', 'cicep_48', 'cfrzr_total', 'cfrzr_3', 'cfrzr_6', 'cfrzr_12', 'cfrzr_24', 'cfrzr_48', 'csnow_total', 'csnow_3', 'csnow_6', 'csnow_12', 'csnow_24', 'csnow_48', 'tp_3', 'tp_6', 'tp_12', 'tp_24', 'tp_48', 'cin_0', 'wind_speed_700', 'wind_speed_200', 'divergence_200', 'd_925', 'tadv_300', 'w_850', 'rainRefl', 'icepRefl', 'snowRefl', 'frzrRefl', 'lftx_0', 'refc_0', 'fgen_850', 'hcc_0', 'r_700', 't_850', 't_850iso0', 'r_850', 'tcc_0', 'hlcy_3000', 'thickness', 'vo_850', 'wind_direction_2000', 'r_500', 'gh_500', 'wind_speed_500', '2d_2', 'cape_25500', 'mcc_0', 'w_500', 'pwat_0', 'divergence_850', 't_500', 'wind_speed_850', 'lcl', 'cape_0', 'tadv_850', 'tadv_700', 'theta2PVU', 'wind_speed_2000', 'lapse_rates_500700', 'vo_500', 'irsat', 't_700', 't_700iso0', 'cin_25500', 'ehi_3000', 'lcc_0', 'gh_850', 'wind_speed_925', 'gh_200', 'wind_speed_300', 'fgen_700', 'vo_700', 'd_850', 'thetaE', 'pres2PVU', 'd_700', 'crain', 'csnow', 'cicep', 'cfrzr', 'w_700', 'gust_0', 'ivt', 'atemp', 'cape_9000', 'r_925', 'mslma_0', 'w_925', 'cin_9000', 'mean700300mbRH', 'wind_speed_10', 't_925', 't_925iso0', 'gh_925', 'gh_700', 'gh_300'],
282
282
  category: 'Global',
283
283
  name: 'GFS',
284
284
  bounds: [-180, -90, 180, 90],