@exodus/atoms 7.6.1 → 8.1.0
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 +21 -0
- package/README.md +2 -14
- package/lib/enhancers/compute.d.ts +1 -1
- package/lib/enhancers/compute.js +2 -2
- package/lib/enhancers/difference.d.ts +2 -2
- package/lib/enhancers/with-storage-cache.js +21 -4
- package/lib/factories/storage.d.ts +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/package.json +2 -3
- package/lib/factories/remote-config.d.ts +0 -13
- package/lib/factories/remote-config.js +0 -35
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,27 @@
|
|
|
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
|
+
## [8.1.0](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/atoms@8.0.0...@exodus/atoms@8.1.0) (2024-08-10)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- **atoms:** warn when using cache enhancer on atom with no setter ([#8147](https://github.com/ExodusMovement/exodus-hydra/issues/8147)) ([1511a55](https://github.com/ExodusMovement/exodus-hydra/commit/1511a5528cce33d82795b4eb06385de370e7a847))
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
- **atoms:** invalidate cache on failed writes, adjust user id analytics atom API ([#8303](https://github.com/ExodusMovement/exodus-hydra/issues/8303)) ([17537a8](https://github.com/ExodusMovement/exodus-hydra/commit/17537a8b18aff90d5e7e1b12dd7964032af7b44b))
|
|
15
|
+
|
|
16
|
+
## [8.0.0](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/atoms@7.6.1...@exodus/atoms@8.0.0) (2024-07-17)
|
|
17
|
+
|
|
18
|
+
### ⚠ BREAKING CHANGES
|
|
19
|
+
|
|
20
|
+
- extract remote config atoms (#7817)
|
|
21
|
+
|
|
22
|
+
### Features
|
|
23
|
+
|
|
24
|
+
- **enhancers:** add compute asynchronous selector support ([#7873](https://github.com/ExodusMovement/exodus-hydra/issues/7873)) ([e62576e](https://github.com/ExodusMovement/exodus-hydra/commit/e62576e5a257f012a184e75a505c2381cc42e07c))
|
|
25
|
+
- extract remote config atoms ([#7817](https://github.com/ExodusMovement/exodus-hydra/issues/7817)) ([7c67be4](https://github.com/ExodusMovement/exodus-hydra/commit/7c67be43e1cdd8376cbf211a64e3fec9b049b90b))
|
|
26
|
+
|
|
6
27
|
## [7.6.1](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/atoms@7.6.0...@exodus/atoms@7.6.1) (2024-07-09)
|
|
7
28
|
|
|
8
29
|
**Note:** Version bump only for package @exodus/atoms
|
package/README.md
CHANGED
|
@@ -13,6 +13,7 @@ An atom is a data source wrapper that exposes a single piece of data through 3 d
|
|
|
13
13
|
- **get()**: read data
|
|
14
14
|
- **set(newValue)**: write data
|
|
15
15
|
- **observe(async (data) => {})**: observes data changes. Will be called initially with current data value. Observers are awaited in series.
|
|
16
|
+
- **reset()**: clear the stored value. The next `get()` call will return the default value\* and observers will be called with the default value.
|
|
16
17
|
|
|
17
18
|
## Data sources
|
|
18
19
|
|
|
@@ -33,12 +34,7 @@ This library provides helpers for creating atoms from multiple data sources we u
|
|
|
33
34
|
## Usage
|
|
34
35
|
|
|
35
36
|
```js
|
|
36
|
-
import {
|
|
37
|
-
createInMemoryAtom,
|
|
38
|
-
createStorageAtomFactory,
|
|
39
|
-
createRemoteConfigAtomFactory,
|
|
40
|
-
fromEventEmitter,
|
|
41
|
-
} from '@exodus/atoms'
|
|
37
|
+
import { createInMemoryAtom, createStorageAtomFactory, fromEventEmitter } from '@exodus/atoms'
|
|
42
38
|
|
|
43
39
|
// In memory atoms
|
|
44
40
|
const availableAssetNamesAtom = createInMemoryAtom({
|
|
@@ -54,14 +50,6 @@ const acceptedTermsAtom = storageAtomFactory({
|
|
|
54
50
|
isSoleWriter: true,
|
|
55
51
|
})
|
|
56
52
|
|
|
57
|
-
// Remote config atoms
|
|
58
|
-
const createRemoteConfigAtom = createRemoteConfigAtomFactory({ remoteConfig })
|
|
59
|
-
|
|
60
|
-
const fiatOnrampConfigAtom = createRemoteConfigAtom({
|
|
61
|
-
path: `dapps.fiatOnramp`,
|
|
62
|
-
defaultValue: {},
|
|
63
|
-
})
|
|
64
|
-
|
|
65
53
|
// Event emitter
|
|
66
54
|
const geolocationAtom = fromEventEmitter({
|
|
67
55
|
emitter: geolocation,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Atom, ReadonlyAtom } from '../utils/types.js';
|
|
2
2
|
type Params<T, V> = {
|
|
3
3
|
atom: Atom<T> | ReadonlyAtom<T>;
|
|
4
|
-
selector: (value: T) => V
|
|
4
|
+
selector: (value: T) => V | Promise<V>;
|
|
5
5
|
};
|
|
6
6
|
declare const compute: <T, V>({ atom, selector }: Params<T, V>) => ReadonlyAtom<V>;
|
|
7
7
|
export default compute;
|
package/lib/enhancers/compute.js
CHANGED
|
@@ -9,8 +9,8 @@ const compute = ({ atom, selector }) => {
|
|
|
9
9
|
const observe = (callback) => {
|
|
10
10
|
let prev;
|
|
11
11
|
let called;
|
|
12
|
-
return atom.observe((values) => {
|
|
13
|
-
const selected = selector(values);
|
|
12
|
+
return atom.observe(async (values) => {
|
|
13
|
+
const selected = await selector(values);
|
|
14
14
|
if (called && prev === selected)
|
|
15
15
|
return;
|
|
16
16
|
called = true;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Atom
|
|
1
|
+
import { Atom } from '../utils/types.js';
|
|
2
2
|
type Diff<T> = {
|
|
3
3
|
previous?: T;
|
|
4
4
|
current: T;
|
|
5
5
|
};
|
|
6
6
|
declare const difference: <T>(atom: Atom<T>) => Omit<Atom<T>, "observe"> & {
|
|
7
|
-
observe:
|
|
7
|
+
observe: Atom<Diff<T>>["observe"];
|
|
8
8
|
};
|
|
9
9
|
export default difference;
|
|
@@ -6,6 +6,9 @@ const getCacheAtom = ({ storage, key }) => {
|
|
|
6
6
|
const enhanceAtom = (params) => {
|
|
7
7
|
const { atom, logger } = params;
|
|
8
8
|
const cacheAtom = getCacheAtom(params);
|
|
9
|
+
if (!atom.hasOwnProperty('set')) {
|
|
10
|
+
logger.warn('Atom does not have a "set" method, cache will last only until the app is restarted');
|
|
11
|
+
}
|
|
9
12
|
let hasCache = false;
|
|
10
13
|
const setCache = async (fresh) => {
|
|
11
14
|
try {
|
|
@@ -31,15 +34,29 @@ const enhanceAtom = (params) => {
|
|
|
31
34
|
return fresh;
|
|
32
35
|
};
|
|
33
36
|
const set = async (value) => {
|
|
34
|
-
|
|
35
|
-
|
|
37
|
+
try {
|
|
38
|
+
await atom.set(value);
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
logger.warn('Failed to write to atom, is it a readonly atom? Clearing cache...', error);
|
|
42
|
+
}
|
|
43
|
+
finally {
|
|
44
|
+
hasCache = false;
|
|
45
|
+
}
|
|
36
46
|
};
|
|
37
47
|
const get = async () => {
|
|
38
48
|
return hasCache ? readCache() : readFresh();
|
|
39
49
|
};
|
|
40
50
|
const reset = async () => {
|
|
41
|
-
|
|
42
|
-
|
|
51
|
+
try {
|
|
52
|
+
await atom.reset();
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
logger.warn('Failed to write to atom, is it a readonly atom? Clearing cache...', error);
|
|
56
|
+
}
|
|
57
|
+
finally {
|
|
58
|
+
hasCache = false;
|
|
59
|
+
}
|
|
43
60
|
};
|
|
44
61
|
return { ...atom, get, set, reset };
|
|
45
62
|
};
|
|
@@ -9,7 +9,7 @@ type Params<D> = {
|
|
|
9
9
|
isSoleWriter?: boolean;
|
|
10
10
|
};
|
|
11
11
|
declare const createStorageAtomFactory: <T>({ storage }: FactoryParams<T>) => {
|
|
12
|
-
(opts: Omit<Params<unknown>,
|
|
12
|
+
(opts: Omit<Params<unknown>, "defaultValue">): Atom<T | undefined>;
|
|
13
13
|
<D extends T>(opts: Params<D>): Atom<T | D>;
|
|
14
14
|
};
|
|
15
15
|
export default createStorageAtomFactory;
|
package/lib/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export { default as createAtomMock } from './factories/memory.js';
|
|
2
2
|
export { default as createInMemoryAtom } from './factories/memory.js';
|
|
3
3
|
export { default as createStorageAtomFactory } from './factories/storage.js';
|
|
4
|
-
export { default as createRemoteConfigAtomFactory } from './factories/remote-config.js';
|
|
5
4
|
export { default as createKeystoreAtom } from './factories/keystore.js';
|
|
6
5
|
export { default as createSequencedKeystoreAtom } from './factories/sequenced-keystore.js';
|
|
7
6
|
export { default as createAtomObserver } from './factories/observer.js';
|
|
7
|
+
export { default as createSimpleObserver } from './simple-observer.js';
|
|
8
8
|
export { default as compute } from './enhancers/compute.js';
|
|
9
9
|
export { default as blockUntil } from './enhancers/block-until.js';
|
|
10
10
|
export { default as filter } from './enhancers/filter.js';
|
package/lib/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export { default as createAtomMock } from './factories/memory.js';
|
|
2
2
|
export { default as createInMemoryAtom } from './factories/memory.js';
|
|
3
3
|
export { default as createStorageAtomFactory } from './factories/storage.js';
|
|
4
|
-
export { default as createRemoteConfigAtomFactory } from './factories/remote-config.js';
|
|
5
4
|
export { default as createKeystoreAtom } from './factories/keystore.js';
|
|
6
5
|
export { default as createSequencedKeystoreAtom } from './factories/sequenced-keystore.js';
|
|
7
6
|
export { default as createAtomObserver } from './factories/observer.js';
|
|
7
|
+
export { default as createSimpleObserver } from './simple-observer.js';
|
|
8
8
|
export { default as compute } from './enhancers/compute.js';
|
|
9
9
|
export { default as blockUntil } from './enhancers/block-until.js';
|
|
10
10
|
export { default as filter } from './enhancers/filter.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/atoms",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.1.0",
|
|
4
4
|
"description": "Abstraction for encapsulating a piece of data behind a simple unified interface: get, set, observe",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -41,7 +41,6 @@
|
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@exodus/atom-tests": "^1.0.0",
|
|
44
|
-
"@exodus/remote-config": "^2.4.0",
|
|
45
44
|
"@exodus/storage-memory": "^2.1.1",
|
|
46
45
|
"@types/jest": "^29.5.11",
|
|
47
46
|
"@types/json-stringify-safe": "^5.0.3",
|
|
@@ -49,5 +48,5 @@
|
|
|
49
48
|
"@types/minimalistic-assert": "^1.0.2",
|
|
50
49
|
"events": "^3.3.0"
|
|
51
50
|
},
|
|
52
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "b1c2b04c40dfc00630a26f3f5f9a9fab1a9dce91"
|
|
53
52
|
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { RemoteConfigType } from '@exodus/remote-config';
|
|
2
|
-
type FactoryParams = {
|
|
3
|
-
remoteConfig: RemoteConfigType;
|
|
4
|
-
};
|
|
5
|
-
type Params<T> = {
|
|
6
|
-
defaultValue?: T;
|
|
7
|
-
} & ({
|
|
8
|
-
path: string;
|
|
9
|
-
} | {
|
|
10
|
-
selector: (config: object) => T;
|
|
11
|
-
});
|
|
12
|
-
declare const createRemoteConfigAtomFactory: ({ remoteConfig }: FactoryParams) => <T>({ defaultValue, ...params }: Params<T>) => import("../utils/types.js").Atom<T>;
|
|
13
|
-
export default createRemoteConfigAtomFactory;
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import lodash from 'lodash';
|
|
2
|
-
import createSimpleObserver from '../simple-observer.js';
|
|
3
|
-
import enforceObservableRules from '../enforce-rules.js';
|
|
4
|
-
const { get: getValueAtPath, isEqual } = lodash;
|
|
5
|
-
const createRemoteConfigAtomFactory = ({ remoteConfig }) => ({ defaultValue, ...params }) => {
|
|
6
|
-
if ('path' in params && 'selector' in params) {
|
|
7
|
-
throw new Error('Provide either a path or a selector to get data from remote config - not both.');
|
|
8
|
-
}
|
|
9
|
-
const getValue = (value) => 'path' in params ? getValueAtPath(value, params.path) : params.selector(value);
|
|
10
|
-
const { notify, observe } = createSimpleObserver();
|
|
11
|
-
const get = async () => {
|
|
12
|
-
const data = await remoteConfig.getAll();
|
|
13
|
-
return getValue(data);
|
|
14
|
-
};
|
|
15
|
-
const set = async () => {
|
|
16
|
-
throw new Error('remoteConfig is read-only');
|
|
17
|
-
};
|
|
18
|
-
remoteConfig.on('sync', async ({ current }) => {
|
|
19
|
-
const data = getValue(current);
|
|
20
|
-
return notify(data);
|
|
21
|
-
});
|
|
22
|
-
const observeDistinct = (callback) => observe(function (value) {
|
|
23
|
-
if (isEqual(this.lastValue, value))
|
|
24
|
-
return;
|
|
25
|
-
this.lastValue = value;
|
|
26
|
-
callback(value);
|
|
27
|
-
}.bind({}));
|
|
28
|
-
return enforceObservableRules({
|
|
29
|
-
get,
|
|
30
|
-
set,
|
|
31
|
-
observe: observeDistinct,
|
|
32
|
-
defaultValue,
|
|
33
|
-
});
|
|
34
|
-
};
|
|
35
|
-
export default createRemoteConfigAtomFactory;
|