@exodus/ui-config 3.13.1 → 3.13.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,12 @@
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
+ ## [3.13.2](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/ui-config@3.13.1...@exodus/ui-config@3.13.2) (2026-01-13)
7
+
8
+ ### Bug Fixes
9
+
10
+ - fix(ui-config): sync atoms in plugin instead of in atom definition (#14908)
11
+
6
12
  ## [3.13.1](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/ui-config@3.13.0...@exodus/ui-config@3.13.1) (2025-12-24)
7
13
 
8
14
  ### Bug Fixes
package/atoms/index.js CHANGED
@@ -1,10 +1,10 @@
1
- import createSyncableUiConfigAtom from './syncable.js'
1
+ import createSyncableRemoteAtom from './syncable.js'
2
2
  import createLocalUiConfigAtom from './local.js'
3
3
 
4
4
  const createUiConfigAtomDefinitions = ({ configValues }) => {
5
- return configValues.map((configValue) =>
5
+ return configValues.flatMap((configValue) =>
6
6
  configValue.syncable
7
- ? createSyncableUiConfigAtom(configValue)
7
+ ? [createLocalUiConfigAtom(configValue), createSyncableRemoteAtom(configValue)]
8
8
  : createLocalUiConfigAtom(configValue)
9
9
  )
10
10
  }
package/atoms/syncable.js CHANGED
@@ -1,47 +1,19 @@
1
- /* eslint-disable @exodus/hydra/no-eternal-subscription */
2
-
3
- // eslint-disable-next-line no-restricted-imports -- TODO: Fix this the next time the file is edited.
4
- import lodash from 'lodash'
5
1
  import { createFusionAtom } from '@exodus/fusion-atoms'
6
- import { createStorageAtomFactory } from '@exodus/atoms'
7
-
8
- const { isEqual } = lodash
9
2
 
10
- const createSyncableUiConfigAtom = ({ id, atomId, encrypted, defaultValue }) => {
11
- const factory = ({ fusion, storage }) => {
3
+ const createSyncableAtom = ({ id, atomId, encrypted }) => {
4
+ const factory = ({ fusion }) => {
12
5
  const path = encrypted ? `private.${id}` : id
13
-
14
- const localAtom = createStorageAtomFactory({ storage })({ key: id, isSoleWriter: true })
15
- const fusionAtom = createFusionAtom({ fusion, path })
16
-
17
- // Sync value up to fusion
18
- localAtom.observe((value) => {
19
- if (value === undefined) return // Avoid syncing down missing fusion values
20
- fusionAtom.set((prevValue) => (isEqual(value, prevValue) ? prevValue : value))
21
- })
22
-
23
- // Sync value down from fusion
24
- fusionAtom.observe((value) => {
25
- if (value === undefined) return // Avoid syncing down missing fusion values
26
- localAtom.set((prevValue) => (isEqual(value, prevValue) ? prevValue : value))
27
- })
28
-
29
- return localAtom
6
+ return createFusionAtom({ fusion, path })
30
7
  }
31
8
 
32
9
  return {
33
10
  definition: {
34
- id: atomId,
11
+ id: `syncable${atomId}`,
35
12
  type: 'atom',
36
13
  factory,
37
- dependencies: ['fusion', 'storage'],
38
- public: true,
14
+ dependencies: ['fusion'],
39
15
  },
40
- storage: { namespace: 'uiConfig' },
41
- aliases: [
42
- { implementationId: encrypted ? 'storage' : 'unsafeStorage', interfaceId: 'storage' },
43
- ],
44
16
  }
45
17
  }
46
18
 
47
- export default createSyncableUiConfigAtom
19
+ export default createSyncableAtom
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exodus/ui-config",
3
- "version": "3.13.1",
3
+ "version": "3.13.2",
4
4
  "description": "Helper for storing various UI-specific settings/config.",
5
5
  "author": "Exodus Movement, Inc.",
6
6
  "license": "MIT",
@@ -45,5 +45,5 @@
45
45
  "access": "public",
46
46
  "provenance": false
47
47
  },
48
- "gitHead": "1306676a6484452bf215467d94d680d9311210bc"
48
+ "gitHead": "f23ac1572edd03edec89b37fae62cdb777f3f369"
49
49
  }
package/plugin/index.js CHANGED
@@ -1,7 +1,12 @@
1
+ // eslint-disable-next-line no-restricted-imports
2
+ import lodash from 'lodash'
1
3
  import { createAtomObserver } from '@exodus/atoms'
2
4
 
5
+ const { isEqual } = lodash
6
+
3
7
  const createUiConfigPluginDefinition = ({ configValues }) => {
4
8
  const atomIds = configValues.map((v) => v.atomId)
9
+ const syncableAtomIds = configValues.filter((v) => v.syncable).map((v) => `syncable${v.atomId}`)
5
10
 
6
11
  const factory = ({ port, ...atoms }) => {
7
12
  const items = configValues.map(({ id, atomId, ...config }) => ({
@@ -10,12 +15,43 @@ const createUiConfigPluginDefinition = ({ configValues }) => {
10
15
  config,
11
16
  }))
12
17
 
18
+ const syncAtoms = () => {
19
+ const subscriptions = configValues
20
+ .filter((config) => config.syncable)
21
+ .flatMap((config) => {
22
+ const localAtom = atoms[config.atomId]
23
+ const remoteAtom = atoms[`syncable${config.atomId}`]
24
+ return [
25
+ localAtom.observe((value) => {
26
+ if (value === undefined) return
27
+ remoteAtom.set((prevValue) => (isEqual(value, prevValue) ? prevValue : value))
28
+ }),
29
+
30
+ remoteAtom.observe((value) => {
31
+ if (value === undefined) return
32
+ localAtom.set((prevValue) => (isEqual(value, prevValue) ? prevValue : value))
33
+ }),
34
+ ]
35
+ })
36
+
37
+ return () => {
38
+ subscriptions.forEach((unsubscribe) => unsubscribe())
39
+ }
40
+ }
41
+
42
+ let unsubscribeSyncAtoms = () => {}
13
43
  return {
14
44
  onLoad: () => items.forEach(({ observer }) => observer.start()),
15
- onStart: () => items.forEach(({ observer }) => observer.start()),
45
+ onStart: () => {
46
+ items.forEach(({ observer }) => observer.start())
47
+ unsubscribeSyncAtoms = syncAtoms()
48
+ },
16
49
  onClear: () =>
17
50
  Promise.all(items.map(({ atom, config }) => (config.persist ? null : atom.set(undefined)))),
18
- onStop: () => items.forEach(({ observer }) => observer.unregister()),
51
+ onStop: () => {
52
+ items.forEach(({ observer }) => observer.unregister())
53
+ unsubscribeSyncAtoms()
54
+ },
19
55
  }
20
56
  }
21
57
 
@@ -24,7 +60,7 @@ const createUiConfigPluginDefinition = ({ configValues }) => {
24
60
  type: 'plugin',
25
61
  id: 'uiConfigPlugin',
26
62
  factory,
27
- dependencies: ['port', ...atomIds],
63
+ dependencies: ['port', ...atomIds, ...syncableAtomIds],
28
64
  public: true,
29
65
  },
30
66
  }