@exodus/atoms 5.7.3 → 6.0.1
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 +20 -0
- package/lib/countdown-lock.d.ts +5 -0
- package/lib/countdown-lock.js +24 -0
- package/lib/effects/wait-until.d.ts +11 -0
- package/lib/effects/wait-until.js +28 -0
- package/lib/enforce-rules.d.ts +8 -0
- package/lib/enforce-rules.js +59 -0
- package/lib/enhancers/block-until.d.ts +12 -0
- package/lib/enhancers/block-until.js +20 -0
- package/lib/enhancers/combine.d.ts +8 -0
- package/lib/enhancers/combine.js +47 -0
- package/lib/enhancers/compute.d.ts +7 -0
- package/lib/enhancers/compute.js +28 -0
- package/lib/enhancers/dedupe.d.ts +3 -0
- package/lib/enhancers/dedupe.js +29 -0
- package/lib/enhancers/difference.d.ts +9 -0
- package/lib/enhancers/difference.js +16 -0
- package/lib/enhancers/optimistic-notifier.d.ts +3 -0
- package/lib/enhancers/optimistic-notifier.js +48 -0
- package/lib/enhancers/read-only.d.ts +3 -0
- package/lib/enhancers/read-only.js +10 -0
- package/lib/enhancers/swallow-observer-errors.d.ts +12 -0
- package/lib/enhancers/swallow-observer-errors.js +18 -0
- package/lib/enhancers/timeout-observers.d.ts +7 -0
- package/lib/enhancers/timeout-observers.js +20 -0
- package/lib/enhancers/warn-on-same-value-set.d.ts +8 -0
- package/lib/enhancers/warn-on-same-value-set.js +30 -0
- package/lib/enhancers/with-serialization.d.ts +8 -0
- package/lib/enhancers/with-serialization.js +19 -0
- package/lib/event-emitter.d.ts +11 -0
- package/lib/event-emitter.js +15 -0
- package/lib/factories/keystore.d.ts +14 -0
- package/lib/factories/keystore.js +23 -0
- package/lib/factories/memory.d.ts +6 -0
- package/lib/factories/memory.js +35 -0
- package/lib/factories/observer.d.ts +13 -0
- package/lib/factories/observer.js +28 -0
- package/lib/factories/remote-config.d.ts +13 -0
- package/lib/factories/remote-config.js +34 -0
- package/lib/factories/sequenced-keystore.d.ts +15 -0
- package/lib/factories/sequenced-keystore.js +71 -0
- package/lib/factories/storage.d.ts +12 -0
- package/lib/factories/storage.js +46 -0
- package/lib/index.d.ts +22 -0
- package/{src → lib}/index.js +21 -24
- package/lib/simple-observer.d.ts +8 -0
- package/lib/simple-observer.js +18 -0
- package/lib/utils/guards.d.ts +2 -0
- package/lib/utils/guards.js +3 -0
- package/lib/utils/types.d.ts +24 -0
- package/lib/utils/types.js +1 -0
- package/package.json +10 -4
- package/src/countdown-lock.js +0 -29
- package/src/effects/wait-until.js +0 -29
- package/src/enforce-rules.js +0 -74
- package/src/enhancers/block-until.js +0 -23
- package/src/enhancers/combine.js +0 -59
- package/src/enhancers/compute.js +0 -31
- package/src/enhancers/dedupe.js +0 -31
- package/src/enhancers/difference.js +0 -20
- package/src/enhancers/optimistic-notifier.js +0 -60
- package/src/enhancers/read-only.js +0 -12
- package/src/enhancers/swallow-observer-errors.js +0 -22
- package/src/enhancers/timeout-observers.js +0 -27
- package/src/enhancers/warn-on-same-value-set.js +0 -49
- package/src/enhancers/with-serialization.js +0 -23
- package/src/event-emitter.js +0 -19
- package/src/factories/keystore.js +0 -40
- package/src/factories/memory.js +0 -46
- package/src/factories/observer.js +0 -33
- package/src/factories/remote-config.js +0 -50
- package/src/factories/sequenced-keystore.js +0 -108
- package/src/factories/storage.js +0 -60
- package/src/simple-observer.js +0 -23
package/src/enhancers/combine.js
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import createCountdownLock from '../countdown-lock'
|
|
2
|
-
import createSimpleObserver from '../simple-observer'
|
|
3
|
-
import enforceObservableRules from '../enforce-rules'
|
|
4
|
-
|
|
5
|
-
const combine = (atoms) => {
|
|
6
|
-
const { notify, observe: observeSimpleObserver } = createSimpleObserver()
|
|
7
|
-
const countdownLock = createCountdownLock(Object.keys(atoms))
|
|
8
|
-
|
|
9
|
-
let values = {}
|
|
10
|
-
let subscriptions = []
|
|
11
|
-
let subscribers = 0
|
|
12
|
-
|
|
13
|
-
const maybeUnsubscribeSourceObservables = () => {
|
|
14
|
-
subscribers -= 1
|
|
15
|
-
if (subscribers > 0) return
|
|
16
|
-
subscriptions.forEach((unsubscribe) => unsubscribe())
|
|
17
|
-
subscriptions = []
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const observe = (callback) => {
|
|
21
|
-
subscribers += 1
|
|
22
|
-
|
|
23
|
-
if (subscribers === 1) {
|
|
24
|
-
subscriptions = Object.entries(atoms).map(([name, atom]) =>
|
|
25
|
-
atom.observe(async (value) => {
|
|
26
|
-
values = {
|
|
27
|
-
...values,
|
|
28
|
-
[name]: value,
|
|
29
|
-
}
|
|
30
|
-
if (countdownLock.unlock(name)) await notify(values)
|
|
31
|
-
})
|
|
32
|
-
)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const unsubscribe = observeSimpleObserver(callback)
|
|
36
|
-
return () => {
|
|
37
|
-
unsubscribe()
|
|
38
|
-
maybeUnsubscribeSourceObservables()
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const get = async () => {
|
|
43
|
-
return Object.fromEntries(
|
|
44
|
-
await Promise.all(Object.entries(atoms).map(async ([name, atom]) => [name, await atom.get()]))
|
|
45
|
-
)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const set = async () => {
|
|
49
|
-
throw new Error('combine does not support method: set')
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return enforceObservableRules({
|
|
53
|
-
get,
|
|
54
|
-
set,
|
|
55
|
-
observe,
|
|
56
|
-
})
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export default combine
|
package/src/enhancers/compute.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
const compute = ({ atom, selector }) => {
|
|
2
|
-
const get = async () => {
|
|
3
|
-
const values = await atom.get()
|
|
4
|
-
return selector(values)
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
const set = async () => {
|
|
8
|
-
throw new Error('selected atom does not support set')
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const observe = (callback) => {
|
|
12
|
-
let prev
|
|
13
|
-
let called
|
|
14
|
-
return atom.observe((values) => {
|
|
15
|
-
const selected = selector(values)
|
|
16
|
-
if (called && prev === selected) return
|
|
17
|
-
called = true
|
|
18
|
-
prev = selected
|
|
19
|
-
return callback(selected)
|
|
20
|
-
})
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return {
|
|
24
|
-
...atom,
|
|
25
|
-
get,
|
|
26
|
-
set,
|
|
27
|
-
observe,
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export default compute
|
package/src/enhancers/dedupe.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { isEqual } from 'lodash'
|
|
2
|
-
|
|
3
|
-
const dedupe = (atom) => {
|
|
4
|
-
const set = (value) => {
|
|
5
|
-
// avoid triggering a get() when we're resetting the atom
|
|
6
|
-
// TODO: add atom.unset and stop using atom.set(undefined)
|
|
7
|
-
if (value === undefined) return atom.set(value)
|
|
8
|
-
|
|
9
|
-
return atom.set((previous) => (isEqual(previous, value) ? previous : value))
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const observe = (callback) => {
|
|
13
|
-
let called
|
|
14
|
-
let previous
|
|
15
|
-
return atom.observe(async (value) => {
|
|
16
|
-
if (called && isEqual(previous, value)) return
|
|
17
|
-
|
|
18
|
-
called = true
|
|
19
|
-
previous = value
|
|
20
|
-
return callback(value)
|
|
21
|
-
})
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
return {
|
|
25
|
-
...atom,
|
|
26
|
-
set,
|
|
27
|
-
observe,
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export default dedupe
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
const difference = (atom) => {
|
|
2
|
-
const observe = (callback) => {
|
|
3
|
-
let prev
|
|
4
|
-
|
|
5
|
-
const selector = (value) => {
|
|
6
|
-
const p = prev
|
|
7
|
-
prev = value
|
|
8
|
-
return { previous: p, current: value }
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
return atom.observe((value) => callback(selector(value)))
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
return {
|
|
15
|
-
...atom,
|
|
16
|
-
observe,
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export default difference
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import makeConcurrent from 'make-concurrent'
|
|
2
|
-
import createInMemoryAtom from '../factories/memory'
|
|
3
|
-
|
|
4
|
-
const optimisticNotifier = (atom) => {
|
|
5
|
-
const memoryAtom = createInMemoryAtom()
|
|
6
|
-
|
|
7
|
-
const set = makeConcurrent(async (newValue) => {
|
|
8
|
-
let previous
|
|
9
|
-
await memoryAtom.set((previousValue) => {
|
|
10
|
-
previous = previousValue
|
|
11
|
-
return newValue
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
atom
|
|
15
|
-
.set(newValue)
|
|
16
|
-
// only revert in case the value hasn't changed in the meanwhile
|
|
17
|
-
.catch(() => memoryAtom.set((value) => (value === newValue ? previous : value)))
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
let unsubscribeSource
|
|
21
|
-
let subscribers = 0
|
|
22
|
-
|
|
23
|
-
const maybeUnsubscribeSource = () => {
|
|
24
|
-
subscribers -= 1
|
|
25
|
-
if (subscribers > 0) return
|
|
26
|
-
unsubscribeSource()
|
|
27
|
-
unsubscribeSource = undefined
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const observe = (callback) => {
|
|
31
|
-
if (subscribers === 0) {
|
|
32
|
-
unsubscribeSource = atom.observe(set)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
subscribers += 1
|
|
36
|
-
const unsubscribe = memoryAtom.observe(callback)
|
|
37
|
-
|
|
38
|
-
return () => {
|
|
39
|
-
unsubscribe()
|
|
40
|
-
maybeUnsubscribeSource()
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const get = async () => {
|
|
45
|
-
if (subscribers === 0) {
|
|
46
|
-
return atom.get()
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return memoryAtom.get()
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return {
|
|
53
|
-
...memoryAtom,
|
|
54
|
-
set,
|
|
55
|
-
get,
|
|
56
|
-
observe,
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export default optimisticNotifier
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import assert from 'minimalistic-assert'
|
|
2
|
-
|
|
3
|
-
const swallowObserverErrors = ({ atom, logger }) => {
|
|
4
|
-
assert(atom, 'expected "atom')
|
|
5
|
-
assert(typeof logger?.error === 'function', 'expected logger with ".error" function')
|
|
6
|
-
|
|
7
|
-
const observe = (observer) =>
|
|
8
|
-
atom.observe(async (...args) => {
|
|
9
|
-
try {
|
|
10
|
-
await observer(...args)
|
|
11
|
-
} catch (err) {
|
|
12
|
-
logger.error('Observer threw error', err)
|
|
13
|
-
}
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
return {
|
|
17
|
-
...atom,
|
|
18
|
-
observe,
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export default swallowObserverErrors
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import delay from 'delay'
|
|
2
|
-
import assert from 'minimalistic-assert'
|
|
3
|
-
|
|
4
|
-
const timeoutObservers = ({ atom, timeout }) => {
|
|
5
|
-
assert(atom, 'expected "atom')
|
|
6
|
-
assert(typeof timeout === 'number', 'expected number "timeout"')
|
|
7
|
-
|
|
8
|
-
const observe = (observer) =>
|
|
9
|
-
atom.observe(async (...args) => {
|
|
10
|
-
const timeoutPromise = delay.reject(timeout, {
|
|
11
|
-
value: new Error('Observer timed out!'),
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
await Promise.race([
|
|
15
|
-
//
|
|
16
|
-
observer(...args),
|
|
17
|
-
timeoutPromise,
|
|
18
|
-
]).then(() => timeoutPromise.clear())
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
return {
|
|
22
|
-
...atom,
|
|
23
|
-
observe,
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export default timeoutObservers
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import assert from 'minimalistic-assert'
|
|
2
|
-
import { isEqual as deepEqual } from 'lodash'
|
|
3
|
-
|
|
4
|
-
const STRINGIFY_LIMIT = 1000
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Serialize an object to a JSON string with a limit on the number of properties shown
|
|
8
|
-
* @param {Object} obj - The object to be serialized
|
|
9
|
-
* @param {number} limit - The maximum number of properties to include in the output
|
|
10
|
-
* @returns {string} - The JSON string representation of the object
|
|
11
|
-
*/
|
|
12
|
-
const limitedStringify = (obj, limit = STRINGIFY_LIMIT) => {
|
|
13
|
-
let count = 0
|
|
14
|
-
|
|
15
|
-
return JSON.stringify(obj, (_, value) => {
|
|
16
|
-
if (count > limit) {
|
|
17
|
-
return
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
if (count === limit) {
|
|
21
|
-
count++
|
|
22
|
-
return '...more properties not shown'
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
count++
|
|
26
|
-
return value
|
|
27
|
-
})
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const warnOnSameValueSet = ({ atom, isEqual = deepEqual, logger }) => {
|
|
31
|
-
assert(atom, 'expected "atom')
|
|
32
|
-
assert(typeof logger?.warn === 'function', 'expected logger with ".warn" function')
|
|
33
|
-
|
|
34
|
-
let previousValue
|
|
35
|
-
atom.observe((value) => {
|
|
36
|
-
if (value !== undefined && isEqual(value, previousValue)) {
|
|
37
|
-
// limit value shown to avoid a CPU spike that can lead to Android freezing
|
|
38
|
-
logger.warn(
|
|
39
|
-
`Atom was called with the same value it currently holds: ${limitedStringify(value)}`
|
|
40
|
-
)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
previousValue = value
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
return atom
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export default warnOnSameValueSet
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
const withSerialization = ({ atom, serialize, deserialize }) => {
|
|
2
|
-
const get = async () => {
|
|
3
|
-
const serialized = await atom.get()
|
|
4
|
-
return deserialize(serialized)
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
const set = async (value) => {
|
|
8
|
-
if (typeof value === 'function') {
|
|
9
|
-
return atom.set((previousValue) => serialize(value(deserialize(previousValue))))
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const serialized = serialize(value)
|
|
13
|
-
return atom.set(serialized)
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const observe = (callback) => {
|
|
17
|
-
return atom.observe((value) => callback(deserialize(value), value))
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return { ...atom, get, set, observe }
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export default withSerialization
|
package/src/event-emitter.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import enforceObservableRules from './enforce-rules'
|
|
2
|
-
|
|
3
|
-
const fromEventEmitter = ({ emitter, event, get, set, defaultValue, logger, getInitialized }) => {
|
|
4
|
-
const observe = (listener) => {
|
|
5
|
-
emitter.on(event, listener)
|
|
6
|
-
return () => emitter.removeListener(event, listener)
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
return enforceObservableRules({
|
|
10
|
-
getInitialized,
|
|
11
|
-
get,
|
|
12
|
-
set,
|
|
13
|
-
observe,
|
|
14
|
-
defaultValue,
|
|
15
|
-
logger,
|
|
16
|
-
})
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export default fromEventEmitter
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import enforceObservableRules from '../enforce-rules'
|
|
2
|
-
import createSimpleObserver from '../simple-observer'
|
|
3
|
-
|
|
4
|
-
const createKeystoreAtom = ({
|
|
5
|
-
keystore,
|
|
6
|
-
logger,
|
|
7
|
-
config: {
|
|
8
|
-
//
|
|
9
|
-
key,
|
|
10
|
-
defaultValue,
|
|
11
|
-
isSoleWriter,
|
|
12
|
-
getOpts,
|
|
13
|
-
setOpts,
|
|
14
|
-
deleteOpts,
|
|
15
|
-
},
|
|
16
|
-
}) => {
|
|
17
|
-
const { notify, observe } = createSimpleObserver({ enable: isSoleWriter })
|
|
18
|
-
|
|
19
|
-
const set = async (value) => {
|
|
20
|
-
if (value == null) {
|
|
21
|
-
await keystore.deleteSecret(key, deleteOpts)
|
|
22
|
-
} else {
|
|
23
|
-
await keystore.setSecret(key, value, setOpts)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (isSoleWriter) await notify(value)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const get = () => keystore.getSecret(key, getOpts)
|
|
30
|
-
|
|
31
|
-
return enforceObservableRules({
|
|
32
|
-
get,
|
|
33
|
-
set,
|
|
34
|
-
observe,
|
|
35
|
-
defaultValue,
|
|
36
|
-
logger,
|
|
37
|
-
})
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export default createKeystoreAtom
|
package/src/factories/memory.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import EventEmitter from 'events/'
|
|
2
|
-
|
|
3
|
-
import fromEventEmitter from '../event-emitter'
|
|
4
|
-
import pDefer from 'p-defer'
|
|
5
|
-
|
|
6
|
-
const createAtomMock = (options = {}) => {
|
|
7
|
-
const { defaultValue } = options
|
|
8
|
-
|
|
9
|
-
let latestValue = defaultValue
|
|
10
|
-
|
|
11
|
-
const emitter = new EventEmitter()
|
|
12
|
-
emitter.setMaxListeners(Number.POSITIVE_INFINITY)
|
|
13
|
-
|
|
14
|
-
const initialized = pDefer()
|
|
15
|
-
|
|
16
|
-
const get = async () => {
|
|
17
|
-
if (!('defaultValue' in options)) {
|
|
18
|
-
await initialized.promise
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
return latestValue
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const set = (data) => {
|
|
25
|
-
latestValue = data
|
|
26
|
-
if (data !== undefined) {
|
|
27
|
-
initialized.resolve()
|
|
28
|
-
initialized.resolved = true
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
if (initialized.resolved) {
|
|
32
|
-
emitter.emit('data', data)
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return fromEventEmitter({
|
|
37
|
-
...options,
|
|
38
|
-
getInitialized: () => initialized.resolved,
|
|
39
|
-
emitter,
|
|
40
|
-
event: 'data',
|
|
41
|
-
get,
|
|
42
|
-
set,
|
|
43
|
-
})
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export default createAtomMock
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
const createAtomObserver = ({ port, atom, event, immediateRegister = true }) => {
|
|
2
|
-
let emitting = false
|
|
3
|
-
let unobserve
|
|
4
|
-
|
|
5
|
-
const register = () => {
|
|
6
|
-
if (unobserve) return
|
|
7
|
-
|
|
8
|
-
unobserve = atom.observe((value) => {
|
|
9
|
-
if (emitting) port.emit(event, value)
|
|
10
|
-
})
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const unregister = () => {
|
|
14
|
-
unobserve?.()
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const start = async () => {
|
|
18
|
-
emitting = true
|
|
19
|
-
port.emit(event, await atom.get())
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (immediateRegister) {
|
|
23
|
-
register()
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return {
|
|
27
|
-
register,
|
|
28
|
-
unregister,
|
|
29
|
-
start,
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export default createAtomObserver
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { get as getValueAtPath, isEqual } from 'lodash'
|
|
2
|
-
|
|
3
|
-
import createSimpleObserver from '../simple-observer'
|
|
4
|
-
import enforceObservableRules from '../enforce-rules'
|
|
5
|
-
|
|
6
|
-
const createRemoteConfigAtomFactory =
|
|
7
|
-
({ remoteConfig }) =>
|
|
8
|
-
({ path, selector, defaultValue }) => {
|
|
9
|
-
if (path && selector) {
|
|
10
|
-
throw new Error(
|
|
11
|
-
'Provide either a path or a selector to get data from remote config - not both.'
|
|
12
|
-
)
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const getValue = (value) => (selector ? selector(value) : getValueAtPath(value, path))
|
|
16
|
-
|
|
17
|
-
const { notify, observe } = createSimpleObserver()
|
|
18
|
-
|
|
19
|
-
const get = async () => {
|
|
20
|
-
const data = await remoteConfig.getAll()
|
|
21
|
-
return getValue(data)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const set = async () => {
|
|
25
|
-
throw new Error('remoteConfig is read-only')
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
remoteConfig.on('sync', async ({ current }) => {
|
|
29
|
-
const data = getValue(current)
|
|
30
|
-
return notify(data)
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
const observeDistinct = (callback) =>
|
|
34
|
-
observe(
|
|
35
|
-
function (value) {
|
|
36
|
-
if (isEqual(this.lastValue, value)) return
|
|
37
|
-
this.lastValue = value
|
|
38
|
-
callback(value)
|
|
39
|
-
}.bind({})
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
return enforceObservableRules({
|
|
43
|
-
get,
|
|
44
|
-
set,
|
|
45
|
-
observe: observeDistinct,
|
|
46
|
-
defaultValue,
|
|
47
|
-
})
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export default createRemoteConfigAtomFactory
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import assert from 'minimalistic-assert'
|
|
2
|
-
|
|
3
|
-
import enforceObservableRules from '../enforce-rules'
|
|
4
|
-
import createSimpleObserver from '../simple-observer'
|
|
5
|
-
|
|
6
|
-
const getRange = (offset, length) => Array.from({ length }, (_, i) => i + offset)
|
|
7
|
-
|
|
8
|
-
const createSequencedKeystoreAtom = ({
|
|
9
|
-
keystore,
|
|
10
|
-
config: {
|
|
11
|
-
//
|
|
12
|
-
key,
|
|
13
|
-
separator = '.',
|
|
14
|
-
defaultValue = [],
|
|
15
|
-
isSoleWriter,
|
|
16
|
-
getOpts,
|
|
17
|
-
setOpts,
|
|
18
|
-
deleteOpts,
|
|
19
|
-
},
|
|
20
|
-
}) => {
|
|
21
|
-
assert(key, 'sequence keystore atom: key missing')
|
|
22
|
-
|
|
23
|
-
assert(typeof key === 'string', 'sequence keystore atom: key must be a string')
|
|
24
|
-
|
|
25
|
-
assert(Array.isArray(defaultValue), 'sequence keystore atom: default value must be an array')
|
|
26
|
-
|
|
27
|
-
const { notify, observe } = createSimpleObserver({ enable: isSoleWriter })
|
|
28
|
-
|
|
29
|
-
let cache
|
|
30
|
-
|
|
31
|
-
const getKey = (index) =>
|
|
32
|
-
key.endsWith(separator) ? `${key}${index}` : `${key}${separator}${index}`
|
|
33
|
-
|
|
34
|
-
const getByIndex = async (index) => {
|
|
35
|
-
const key = getKey(index)
|
|
36
|
-
const value = await keystore.getSecret(key, getOpts)
|
|
37
|
-
if (value) return { key, value }
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const list = async () => {
|
|
41
|
-
let result = []
|
|
42
|
-
let batch = []
|
|
43
|
-
let offset = 0
|
|
44
|
-
const batchSize = 5
|
|
45
|
-
|
|
46
|
-
// paginate until we're out of items
|
|
47
|
-
do {
|
|
48
|
-
const range = getRange(offset, batchSize)
|
|
49
|
-
batch = await Promise.all(range.map(getByIndex))
|
|
50
|
-
batch = batch.filter(Boolean)
|
|
51
|
-
result = [...result, ...batch]
|
|
52
|
-
offset += batchSize
|
|
53
|
-
} while (batch.length > 0)
|
|
54
|
-
|
|
55
|
-
return result
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const clear = async () => {
|
|
59
|
-
const items = await list()
|
|
60
|
-
await Promise.all(items.map((item) => keystore.deleteSecret(item.key, deleteOpts)))
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const _set = async (value) => {
|
|
64
|
-
assert(Array.isArray(value), 'sequence keystore atom: set value must be an array')
|
|
65
|
-
|
|
66
|
-
await Promise.all(
|
|
67
|
-
value.map((value, index) => {
|
|
68
|
-
return keystore.setSecret(getKey(index), value, setOpts)
|
|
69
|
-
})
|
|
70
|
-
)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const set = async (value) => {
|
|
74
|
-
await clear()
|
|
75
|
-
|
|
76
|
-
if (value !== undefined) {
|
|
77
|
-
await _set(value)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
if (isSoleWriter) {
|
|
81
|
-
cache = value
|
|
82
|
-
await notify(value)
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const get = async () => {
|
|
87
|
-
if (cache) return cache
|
|
88
|
-
|
|
89
|
-
const items = await list()
|
|
90
|
-
const value = items.map((item) => item.value)
|
|
91
|
-
|
|
92
|
-
if (isSoleWriter) {
|
|
93
|
-
cache = value
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// let default value be used
|
|
97
|
-
return items.length === 0 ? undefined : value
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return enforceObservableRules({
|
|
101
|
-
get,
|
|
102
|
-
set,
|
|
103
|
-
observe,
|
|
104
|
-
defaultValue,
|
|
105
|
-
})
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export default createSequencedKeystoreAtom
|
package/src/factories/storage.js
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import createSimpleObserver from '../simple-observer'
|
|
2
|
-
import enforceObservableRules from '../enforce-rules'
|
|
3
|
-
import pDefer from 'p-defer'
|
|
4
|
-
|
|
5
|
-
const createStorageAtomFactory =
|
|
6
|
-
({ storage, logger }) =>
|
|
7
|
-
({ key, defaultValue, isSoleWriter }) => {
|
|
8
|
-
const { notify, observe } = createSimpleObserver({ enable: isSoleWriter })
|
|
9
|
-
|
|
10
|
-
let cached
|
|
11
|
-
let writePromiseDefer
|
|
12
|
-
const set = async (value) => {
|
|
13
|
-
if (value === undefined) {
|
|
14
|
-
writePromiseDefer = pDefer()
|
|
15
|
-
await storage.delete(key)
|
|
16
|
-
} else {
|
|
17
|
-
writePromiseDefer = pDefer()
|
|
18
|
-
await storage.set(key, value)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
writePromiseDefer.resolve()
|
|
22
|
-
|
|
23
|
-
if (isSoleWriter) {
|
|
24
|
-
cached = value
|
|
25
|
-
await notify(value)
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const get = async () => {
|
|
30
|
-
if (cached) {
|
|
31
|
-
return cached
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (writePromiseDefer) {
|
|
35
|
-
await writePromiseDefer.promise
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (cached) {
|
|
39
|
-
return cached
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const value = await storage.get(key)
|
|
43
|
-
|
|
44
|
-
if (isSoleWriter) {
|
|
45
|
-
cached = value
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return value
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return enforceObservableRules({
|
|
52
|
-
get,
|
|
53
|
-
set,
|
|
54
|
-
observe,
|
|
55
|
-
defaultValue,
|
|
56
|
-
logger,
|
|
57
|
-
})
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export default createStorageAtomFactory
|