@exodus/market-history 10.2.0 → 10.2.2

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/CHANGELOG.md CHANGED
@@ -3,6 +3,18 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [10.2.2](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/market-history@10.2.1...@exodus/market-history@10.2.2) (2025-05-26)
7
+
8
+ ### Bug Fixes
9
+
10
+ - fix: potential race condition (#12678)
11
+
12
+ ## [10.2.1](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/market-history@10.2.0...@exodus/market-history@10.2.1) (2025-05-18)
13
+
14
+ ### Bug Fixes
15
+
16
+ - fix: market-history stop (#12548)
17
+
6
18
  ## [10.2.0](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/market-history@10.1.3...@exodus/market-history@10.2.0) (2025-05-08)
7
19
 
8
20
  ### Features
package/module/index.js CHANGED
@@ -62,7 +62,8 @@ const filterMapAssetDataFromServer = (data) =>
62
62
  .filter((piece) => piece.close !== 0)
63
63
  .map((piece) => [piece.time * 1000, { close: piece.close }])
64
64
 
65
- const delayWithJitter = (ms, jitter = 0) => delay(Math.floor(ms + Math.random() * jitter))
65
+ const delayWithJitter = (ms, jitter = 0, signal) =>
66
+ delay(Math.floor(ms + Math.random() * jitter), { signal })
66
67
 
67
68
  const setupPriceFetchInterval = async ({
68
69
  func,
@@ -75,7 +76,13 @@ const setupPriceFetchInterval = async ({
75
76
  while (abortController ? !abortController.signal.aborted : true) {
76
77
  const now = getCurrentTime()
77
78
  const untilEndOfPeriod = dayjs.utc(now).endOf(granularity).valueOf() - now
78
- await delayWithJitter(untilEndOfPeriod + delay, getJitter())
79
+
80
+ try {
81
+ await delayWithJitter(untilEndOfPeriod + delay, getJitter(), abortController?.signal)
82
+ } catch {
83
+ // aborted
84
+ break
85
+ }
79
86
 
80
87
  try {
81
88
  await func()
@@ -141,7 +148,7 @@ class MarketHistoryMonitor {
141
148
  this.#synchronizedTime = synchronizedTime
142
149
  }
143
150
 
144
- #started = false
151
+ #isActive = false
145
152
 
146
153
  #setCache = async ({ currency, granularity, pricesByAssetName }) => {
147
154
  let hasChanges = false
@@ -265,7 +272,7 @@ class MarketHistoryMonitor {
265
272
  }
266
273
 
267
274
  updateAll = async () => {
268
- if (!this.#started) {
275
+ if (!this.#isActive) {
269
276
  const e = new Error('market-history updateAll cannot be called before module started')
270
277
  this.#errorTracking.track({
271
278
  error: e,
@@ -320,6 +327,10 @@ class MarketHistoryMonitor {
320
327
  }
321
328
 
322
329
  #updateAssets = async (assetNames, granularities) => {
330
+ if (!this.#isActive) {
331
+ return
332
+ }
333
+
323
334
  const currency = this.#currency
324
335
  const promises = granularities.map((granularity) =>
325
336
  this.#fetchPricesByGranularity({ granularity, assetNames, currency })
@@ -327,6 +338,10 @@ class MarketHistoryMonitor {
327
338
 
328
339
  const results = await Promise.all(promises)
329
340
 
341
+ if (!this.#isActive) {
342
+ return
343
+ }
344
+
330
345
  await this.#marketHistoryAtom.set((current) => {
331
346
  const detectHasChanges = (result, parsedGranularity) => {
332
347
  if (!current || !current.data) return true
@@ -392,6 +407,11 @@ class MarketHistoryMonitor {
392
407
  difference(this.#remoteConfigClearCacheAtom).observe(({ current, previous }) => {
393
408
  const clear = async () => {
394
409
  await this.#invalidateStorage({ remoteConfigClearCacheVersion: current })
410
+
411
+ if (!this.#isActive) {
412
+ return
413
+ }
414
+
395
415
  await this.updateAll()
396
416
  }
397
417
 
@@ -452,6 +472,10 @@ class MarketHistoryMonitor {
452
472
  },
453
473
  }
454
474
  })
475
+ if (!this.#isActive) {
476
+ return
477
+ }
478
+
455
479
  this.updateAll()
456
480
  }
457
481
  })
@@ -490,39 +514,55 @@ class MarketHistoryMonitor {
490
514
 
491
515
  start = makeConcurrent(
492
516
  async () => {
493
- if (this.#started) return
517
+ if (this.#isActive) return
494
518
  this.#logger.info('market history start')
495
- this.#started = true
519
+ this.#isActive = true
496
520
  this.#abortController = new AbortController()
497
521
 
498
522
  const remoteConfigClearCacheVersion = await this.#remoteConfigClearCacheAtom.get()
499
523
  await this.#invalidateStorage({ remoteConfigClearCacheVersion })
500
524
 
525
+ if (!this.#isActive) {
526
+ return
527
+ }
528
+
501
529
  this.#currency = await this.#currencyAtom.get()
502
530
  this.#previouslyEnabledAssets = await this.#enabledAssetsAtom.get()
503
531
 
532
+ if (!this.#isActive) {
533
+ return
534
+ }
535
+
504
536
  // Initialize atom if necessary
505
537
  await this.#initMarketHistoryAtom()
506
538
 
539
+ if (!this.#isActive) {
540
+ return
541
+ }
542
+
507
543
  this.#setupTimers()
508
544
  this.#listenRemoteConfigClearCacheVersionChanges()
509
545
  this.#listenCurrencyChanges()
510
546
  this.#listenEnabledAssetsChanges()
511
547
 
548
+ if (!this.#isActive) {
549
+ return
550
+ }
551
+
512
552
  await this.updateAll()
513
553
  },
514
554
  { concurrency: 1 }
515
555
  )
516
556
 
517
557
  stop = () => {
518
- if (!this.#started) {
558
+ if (!this.#isActive) {
519
559
  return
520
560
  }
521
561
 
522
562
  this.#logger.info('market history stops')
523
563
  this.#atomListeners.forEach((unsubscribe) => unsubscribe())
524
564
  this.#atomListeners = []
525
- this.#started = false
565
+ this.#isActive = false
526
566
  this.#abortController.abort()
527
567
  }
528
568
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exodus/market-history",
3
- "version": "10.2.0",
3
+ "version": "10.2.2",
4
4
  "description": "Fetches historical prices for assets",
5
5
  "author": "Exodus Movement, Inc.",
6
6
  "license": "MIT",
@@ -29,7 +29,7 @@
29
29
  "@exodus/dayjs": "^1.0.2",
30
30
  "@exodus/price-api": "^4.1.1",
31
31
  "@exodus/remote-config-atoms": "^1.1.0",
32
- "delay": "^1.3.1",
32
+ "delay": "^5.0.0",
33
33
  "make-concurrent": "^5.4.0",
34
34
  "ms": "^0.7.1",
35
35
  "reselect": "^3.0.1"
@@ -37,12 +37,12 @@
37
37
  "devDependencies": {
38
38
  "@exodus/assets": "^11.0.0",
39
39
  "@exodus/assets-base": "^10.0.0",
40
- "@exodus/assets-feature": "^7.4.0",
40
+ "@exodus/assets-feature": "^8.1.1",
41
41
  "@exodus/bitcoin-meta": "^2.0.0",
42
42
  "@exodus/ethereum-meta": "^2.4.1",
43
43
  "@exodus/locale": "^2.5.0",
44
44
  "@exodus/logger": "^1.2.3",
45
- "@exodus/rates-monitor": "^4.14.0",
45
+ "@exodus/rates-monitor": "^4.14.2",
46
46
  "@exodus/redux-dependency-injection": "^4.1.1",
47
47
  "@exodus/storage-memory": "^2.2.2",
48
48
  "events": "^3.3.0",
@@ -59,5 +59,5 @@
59
59
  "publishConfig": {
60
60
  "access": "public"
61
61
  },
62
- "gitHead": "f74c439e4584cdfffe88e19fc3acfafc918a29dc"
62
+ "gitHead": "c46def8fc6822d459f0a7c4cb00ac66fb5a2580c"
63
63
  }
package/plugin/index.js CHANGED
@@ -54,6 +54,7 @@ const createMarketHistoryLifecyclePlugin = ({
54
54
  const onStop = () => {
55
55
  observer.unregister()
56
56
  unobserve?.()
57
+ marketHistoryMonitor.stop()
57
58
  }
58
59
 
59
60
  return { onUnlock, onLoad, onStop }