Skip to content

Commit c91bfe3

Browse files
authored
Merge pull request #27 from dottostack/feat/atomic
feat: deep computed operator
2 parents bba9474 + 40348cf commit c91bfe3

File tree

21 files changed

+478
-148
lines changed

21 files changed

+478
-148
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const DEEP_HANDLER = Symbol.for('deep')

packages/dotto.x/computed/container.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,30 @@ import { onOff } from '../lifecycle'
33
import { context } from './context'
44
import { decorate } from '../utils/decorate'
55
import { get_or_create } from '../utils/get_or_create'
6+
import { DEEP_HANDLER } from './constants'
67

78
export const createContainer = (cb, emit, invalidate) => {
89
let listeners = new Map()
9-
let storeOffHandlers = new Map()
10+
let destroys = new Map()
1011

1112
return {
13+
listeners,
14+
destroys,
15+
emit,
16+
invalidate,
1217
unbind() {
13-
listeners.forEach(sub => run_all(Object.values(sub)))
18+
listeners.forEach(sub => {
19+
run_all([...Object.values(sub), sub[DEEP_HANDLER] || (() => {})])
20+
})
1421
listeners.clear()
15-
storeOffHandlers.forEach(sub => run_all(Object.values(sub)))
16-
storeOffHandlers.clear()
22+
destroys.forEach(sub => run_all(Object.values(sub)))
23+
destroys.clear()
1724
},
1825
add(store, query) {
1926
let listenerBox = get_or_create(listeners, store, () => ({}))
27+
if (listenerBox[DEEP_HANDLER]) return
2028
// TODO
21-
get_or_create(storeOffHandlers, store, () => {
29+
get_or_create(destroys, store, () => {
2230
let unbind = onOff(store, () => {
2331
listeners.delete(store)
2432
invalidate(!listeners.size)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import type { DotXStore } from '../create-store'
2+
import type { ResolveType } from '../utils/get'
3+
import type { DotXAtom } from '../create-atom'
4+
import type { ReadableStore } from './computed'
5+
6+
export function deep<Sub extends ReadableStore>(
7+
dep: Sub
8+
): ReturnType<Sub['get']>
9+
10+
export function deep<Data>(dep: DotXAtom<Data>): Data
11+
12+
export function deep<Data>(dep: DotXStore<Data>): Data
13+
14+
export function deep<Data, Query extends string>(
15+
dep: DotXStore<Data>,
16+
query: Query
17+
): ResolveType<Data, Query>

packages/dotto.x/computed/deep.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { onOff, onChange } from '../lifecycle'
2+
import { run_all } from '../utils/run_all'
3+
import { DEEP_HANDLER } from './constants'
4+
import { target } from './context'
5+
6+
const change = (store, cb) => {
7+
let unsubs = [store.listen(() => {}), onChange(store, cb)]
8+
return () => run_all(unsubs)
9+
}
10+
11+
export const deep = (store, query) => {
12+
if (store._run) return store.get(true)
13+
14+
let container = target()
15+
if (!container || container.silent) return store.get(query)
16+
17+
let { listeners, destroys, invalidate, emit } = container
18+
19+
let listenerBox = listeners.get(store)
20+
if (listenerBox && listenerBox[DEEP_HANDLER]) return store.get(query)
21+
listeners.set(store, { [DEEP_HANDLER]: change(store, emit) })
22+
if (listenerBox) run_all(Object.values(listenerBox))
23+
if (!destroys.has(store)) {
24+
destroys.set(
25+
store,
26+
onOff(store, () => invalidate(true))
27+
)
28+
}
29+
30+
return store.get(query)
31+
}

0 commit comments

Comments
 (0)