@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 +6 -0
- package/atoms/index.js +3 -3
- package/atoms/syncable.js +6 -34
- package/package.json +2 -2
- package/plugin/index.js +39 -3
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
|
|
1
|
+
import createSyncableRemoteAtom from './syncable.js'
|
|
2
2
|
import createLocalUiConfigAtom from './local.js'
|
|
3
3
|
|
|
4
4
|
const createUiConfigAtomDefinitions = ({ configValues }) => {
|
|
5
|
-
return configValues.
|
|
5
|
+
return configValues.flatMap((configValue) =>
|
|
6
6
|
configValue.syncable
|
|
7
|
-
?
|
|
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
|
|
11
|
-
const factory = ({ fusion
|
|
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'
|
|
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
|
|
19
|
+
export default createSyncableAtom
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/ui-config",
|
|
3
|
-
"version": "3.13.
|
|
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": "
|
|
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: () =>
|
|
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: () =>
|
|
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
|
}
|