-
Notifications
You must be signed in to change notification settings - Fork 82
/
store.js
61 lines (51 loc) · 1.84 KB
/
store.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
const connectionStore = new WeakMap()
const ITERATION_KEY = Symbol('iteration key')
export function storeObservable (obj) {
// this will be used to save (obj.key -> reaction) connections later
connectionStore.set(obj, new Map())
}
export function registerReactionForOperation (reaction, { target, key, type }) {
if (type === 'iterate') {
key = ITERATION_KEY
}
const reactionsForObj = connectionStore.get(target)
let reactionsForKey = reactionsForObj.get(key)
if (!reactionsForKey) {
reactionsForKey = new Set()
reactionsForObj.set(key, reactionsForKey)
}
// save the fact that the key is used by the reaction during its current run
if (!reactionsForKey.has(reaction)) {
reactionsForKey.add(reaction)
reaction.cleaners.push(reactionsForKey)
}
}
export function getReactionsForOperation ({ target, key, type }) {
const reactionsForTarget = connectionStore.get(target)
const reactionsForKey = new Set()
if (type === 'clear') {
reactionsForTarget.forEach((_, key) => {
addReactionsForKey(reactionsForKey, reactionsForTarget, key)
})
} else {
addReactionsForKey(reactionsForKey, reactionsForTarget, key)
}
if (type === 'add' || type === 'delete' || type === 'clear') {
const iterationKey = Array.isArray(target) ? 'length' : ITERATION_KEY
addReactionsForKey(reactionsForKey, reactionsForTarget, iterationKey)
}
return reactionsForKey
}
function addReactionsForKey (reactionsForKey, reactionsForTarget, key) {
const reactions = reactionsForTarget.get(key)
reactions && reactions.forEach(reactionsForKey.add, reactionsForKey)
}
export function releaseReaction (reaction) {
if (reaction.cleaners) {
reaction.cleaners.forEach(releaseReactionKeyConnection, reaction)
}
reaction.cleaners = []
}
function releaseReactionKeyConnection (reactionsForKey) {
reactionsForKey.delete(this)
}