-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
/
tojs.ts
67 lines (63 loc) · 1.89 KB
/
tojs.ts
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
62
63
64
65
66
67
import {
keys,
isObservable,
isObservableArray,
isObservableValue,
isObservableMap,
isObservableSet,
getPlainObjectKeys,
die
} from "../internal"
function cache<K, V>(map: Map<any, any>, key: K, value: V): V {
map.set(key, value)
return value
}
function toJSHelper(source, __alreadySeen: Map<any, any>) {
if (
source == null ||
typeof source !== "object" ||
source instanceof Date ||
!isObservable(source)
)
return source
if (isObservableValue(source)) return toJSHelper(source.get(), __alreadySeen)
if (__alreadySeen.has(source)) {
return __alreadySeen.get(source)
}
if (isObservableArray(source)) {
const res = cache(__alreadySeen, source, new Array(source.length))
source.forEach((value, idx) => {
res[idx] = toJSHelper(value, __alreadySeen)
})
return res
}
if (isObservableSet(source)) {
const res = cache(__alreadySeen, source, new Set())
source.forEach(value => {
res.add(toJSHelper(value, __alreadySeen))
})
return res
}
if (isObservableMap(source)) {
const res = cache(__alreadySeen, source, new Map())
source.forEach((value, key) => {
res.set(key, toJSHelper(value, __alreadySeen))
})
return res
} else {
// must be observable object
keys(source) // make sure keys are observed
const res = cache(__alreadySeen, source, {})
getPlainObjectKeys(source).forEach((key: any) => {
res[key] = toJSHelper(source[key], __alreadySeen)
})
return res
}
}
/**
* Basically, a deep clone, so that no reactive property will exist anymore.
*/
export function toJS<T>(source: T, options?: any): T {
if (__DEV__ && options) die("toJS no longer supports options")
return toJSHelper(source, new Map())
}