mobx 6.1.8 → 6.9.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 +224 -7
- package/README.md +54 -52
- package/dist/api/annotation.d.ts +6 -12
- package/dist/api/autorun.d.ts +4 -4
- package/dist/api/flow.d.ts +1 -0
- package/dist/api/intercept.d.ts +5 -5
- package/dist/api/object-api.d.ts +2 -0
- package/dist/api/observable.d.ts +5 -1
- package/dist/api/observe.d.ts +4 -4
- package/dist/api/tojs.d.ts +4 -1
- package/dist/api/when.d.ts +8 -0
- package/dist/core/atom.d.ts +1 -1
- package/dist/core/computedvalue.d.ts +0 -1
- package/dist/core/globalstate.d.ts +4 -0
- package/dist/core/reaction.d.ts +2 -2
- package/dist/errors.d.ts +4 -2
- package/dist/internal.d.ts +1 -0
- package/dist/mobx.cjs.development.js +1477 -1719
- package/dist/mobx.cjs.development.js.map +1 -1
- package/dist/mobx.cjs.production.min.js +1 -1
- package/dist/mobx.cjs.production.min.js.map +1 -1
- package/dist/mobx.d.ts +1 -1
- package/dist/mobx.esm.development.js +1475 -1720
- package/dist/mobx.esm.development.js.map +1 -1
- package/dist/mobx.esm.js +1492 -1726
- package/dist/mobx.esm.js.map +1 -1
- package/dist/mobx.esm.production.min.js +1 -1
- package/dist/mobx.esm.production.min.js.map +1 -1
- package/dist/mobx.umd.development.js +1477 -1719
- package/dist/mobx.umd.development.js.map +1 -1
- package/dist/mobx.umd.production.min.js +1 -1
- package/dist/mobx.umd.production.min.js.map +1 -1
- package/dist/types/actionannotation.d.ts +7 -1
- package/dist/types/autoannotation.d.ts +3 -0
- package/dist/types/observablemap.d.ts +5 -4
- package/dist/types/observableobject.d.ts +6 -9
- package/dist/types/observableset.d.ts +4 -4
- package/dist/types/observablevalue.d.ts +3 -5
- package/dist/utils/utils.d.ts +4 -4
- package/package.json +1 -1
- package/src/api/action.ts +8 -3
- package/src/api/annotation.ts +14 -44
- package/src/api/autorun.ts +38 -17
- package/src/api/computed.ts +5 -2
- package/src/api/configure.ts +6 -2
- package/src/api/decorators.ts +1 -1
- package/src/api/extendobservable.ts +12 -6
- package/src/api/extras.ts +4 -2
- package/src/api/flow.ts +17 -5
- package/src/api/intercept-read.ts +4 -2
- package/src/api/intercept.ts +10 -7
- package/src/api/iscomputed.ts +14 -8
- package/src/api/isobservable.ts +10 -4
- package/src/api/makeObservable.ts +35 -36
- package/src/api/object-api.ts +42 -14
- package/src/api/observable.ts +39 -25
- package/src/api/observe.ts +9 -6
- package/src/api/tojs.ts +20 -10
- package/src/api/trace.ts +6 -2
- package/src/api/when.ts +34 -9
- package/src/core/action.ts +11 -5
- package/src/core/atom.ts +9 -2
- package/src/core/computedvalue.ts +48 -27
- package/src/core/derivation.ts +34 -12
- package/src/core/globalstate.ts +25 -7
- package/src/core/observable.ts +23 -13
- package/src/core/reaction.ts +16 -7
- package/src/core/spy.ts +20 -7
- package/src/errors.ts +16 -3
- package/src/internal.ts +1 -0
- package/src/mobx.ts +6 -2
- package/src/types/actionannotation.ts +30 -52
- package/src/types/autoannotation.ts +107 -0
- package/src/types/computedannotation.ts +7 -37
- package/src/types/dynamicobject.ts +12 -6
- package/src/types/flowannotation.ts +40 -41
- package/src/types/intercept-utils.ts +9 -3
- package/src/types/legacyobservablearray.ts +26 -3
- package/src/types/listen-utils.ts +6 -2
- package/src/types/modifiers.ts +52 -16
- package/src/types/observableannotation.ts +7 -34
- package/src/types/observablearray.ts +106 -45
- package/src/types/observablemap.ts +71 -35
- package/src/types/observableobject.ts +88 -82
- package/src/types/observableset.ts +32 -13
- package/src/types/observablevalue.ts +16 -10
- package/src/types/overrideannotation.ts +4 -2
- package/src/types/type-utils.ts +34 -12
- package/src/utils/comparer.ts +5 -1
- package/src/utils/eq.ts +45 -15
- package/src/utils/utils.ts +39 -16
package/src/mobx.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* (c) Michel Weststrate 2015 - 2020
|
|
3
3
|
* MIT Licensed
|
|
4
4
|
*
|
|
5
|
-
* Welcome to the mobx sources! To get
|
|
5
|
+
* Welcome to the mobx sources! To get a global overview of how MobX internally works,
|
|
6
6
|
* this is a good place to start:
|
|
7
7
|
* https://medium.com/@mweststrate/becoming-fully-reactive-an-in-depth-explanation-of-mobservable-55995262a254#.xvbh6qd74
|
|
8
8
|
*
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import { die } from "./errors"
|
|
19
19
|
import { getGlobal } from "./utils/global"
|
|
20
|
-
;["Symbol", "Map", "Set"
|
|
20
|
+
;["Symbol", "Map", "Set"].forEach(m => {
|
|
21
21
|
let g = getGlobal()
|
|
22
22
|
if (typeof g[m] === "undefined") {
|
|
23
23
|
die(`MobX requires global '${m}' to be available or polyfilled`)
|
|
@@ -75,6 +75,7 @@ export {
|
|
|
75
75
|
IObservableFactory,
|
|
76
76
|
CreateObservableOptions,
|
|
77
77
|
computed,
|
|
78
|
+
IComputedFactory,
|
|
78
79
|
isObservable,
|
|
79
80
|
isObservableProp,
|
|
80
81
|
isComputed,
|
|
@@ -99,10 +100,13 @@ export {
|
|
|
99
100
|
remove,
|
|
100
101
|
has,
|
|
101
102
|
get,
|
|
103
|
+
apiOwnKeys as ownKeys,
|
|
104
|
+
apiDefineProperty as defineProperty,
|
|
102
105
|
configure,
|
|
103
106
|
onBecomeObserved,
|
|
104
107
|
onBecomeUnobserved,
|
|
105
108
|
flow,
|
|
109
|
+
isFlow,
|
|
106
110
|
flowResult,
|
|
107
111
|
FlowCancellationError,
|
|
108
112
|
isFlowCancellationError,
|
|
@@ -3,14 +3,11 @@ import {
|
|
|
3
3
|
createAction,
|
|
4
4
|
isAction,
|
|
5
5
|
defineProperty,
|
|
6
|
-
getDescriptor,
|
|
7
|
-
objectPrototype,
|
|
8
6
|
die,
|
|
9
7
|
isFunction,
|
|
10
8
|
Annotation,
|
|
11
|
-
recordAnnotationApplied,
|
|
12
9
|
globalState,
|
|
13
|
-
|
|
10
|
+
MakeResult
|
|
14
11
|
} from "../internal"
|
|
15
12
|
|
|
16
13
|
export function createActionAnnotation(name: string, options?: object): Annotation {
|
|
@@ -22,54 +19,33 @@ export function createActionAnnotation(name: string, options?: object): Annotati
|
|
|
22
19
|
}
|
|
23
20
|
}
|
|
24
21
|
|
|
25
|
-
function make_(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
annotated = true
|
|
43
|
-
// Don't annotate protos if bound
|
|
44
|
-
if (bound) {
|
|
45
|
-
break
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
// Prototype
|
|
49
|
-
if (source !== adm.target_) {
|
|
50
|
-
if (isAction(descriptor.value)) {
|
|
51
|
-
// A prototype could have been annotated already by other constructor,
|
|
52
|
-
// rest of the proto chain must be annotated already
|
|
53
|
-
annotated = true
|
|
54
|
-
break
|
|
55
|
-
}
|
|
56
|
-
const actionDescriptor = createActionDescriptor(adm, this, key, descriptor, false)
|
|
57
|
-
defineProperty(source, key, actionDescriptor)
|
|
58
|
-
annotated = true
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
source = Object.getPrototypeOf(source)
|
|
22
|
+
function make_(
|
|
23
|
+
adm: ObservableObjectAdministration,
|
|
24
|
+
key: PropertyKey,
|
|
25
|
+
descriptor: PropertyDescriptor,
|
|
26
|
+
source: object
|
|
27
|
+
): MakeResult {
|
|
28
|
+
// bound
|
|
29
|
+
if (this.options_?.bound) {
|
|
30
|
+
return this.extend_(adm, key, descriptor, false) === null
|
|
31
|
+
? MakeResult.Cancel
|
|
32
|
+
: MakeResult.Break
|
|
33
|
+
}
|
|
34
|
+
// own
|
|
35
|
+
if (source === adm.target_) {
|
|
36
|
+
return this.extend_(adm, key, descriptor, false) === null
|
|
37
|
+
? MakeResult.Cancel
|
|
38
|
+
: MakeResult.Continue
|
|
62
39
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
//
|
|
67
|
-
|
|
68
|
-
// When called from super() some props may not exist yet.
|
|
69
|
-
// However we don't have to worry about missing prop,
|
|
70
|
-
// because the decorator must have been applied to something.
|
|
71
|
-
die(1, this.annotationType_, `${adm.name_}.${key.toString()}`)
|
|
40
|
+
// prototype
|
|
41
|
+
if (isAction(descriptor.value)) {
|
|
42
|
+
// A prototype could have been annotated already by other constructor,
|
|
43
|
+
// rest of the proto chain must be annotated already
|
|
44
|
+
return MakeResult.Break
|
|
72
45
|
}
|
|
46
|
+
const actionDescriptor = createActionDescriptor(adm, this, key, descriptor, false)
|
|
47
|
+
defineProperty(source, key, actionDescriptor)
|
|
48
|
+
return MakeResult.Continue
|
|
73
49
|
}
|
|
74
50
|
|
|
75
51
|
function extend_(
|
|
@@ -96,7 +72,7 @@ function assertActionDescriptor(
|
|
|
96
72
|
}
|
|
97
73
|
}
|
|
98
74
|
|
|
99
|
-
function createActionDescriptor(
|
|
75
|
+
export function createActionDescriptor(
|
|
100
76
|
adm: ObservableObjectAdministration,
|
|
101
77
|
annotation: Annotation,
|
|
102
78
|
key: PropertyKey,
|
|
@@ -113,7 +89,9 @@ function createActionDescriptor(
|
|
|
113
89
|
value: createAction(
|
|
114
90
|
annotation.options_?.name ?? key.toString(),
|
|
115
91
|
value,
|
|
116
|
-
annotation.options_?.autoAction ?? false
|
|
92
|
+
annotation.options_?.autoAction ?? false,
|
|
93
|
+
// https://github.com/mobxjs/mobx/discussions/3140
|
|
94
|
+
annotation.options_?.bound ? adm.proxy_ ?? adm.target_ : undefined
|
|
117
95
|
),
|
|
118
96
|
// Non-configurable for classes
|
|
119
97
|
// prevents accidental field redefinition in subclass
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ObservableObjectAdministration,
|
|
3
|
+
observable,
|
|
4
|
+
Annotation,
|
|
5
|
+
defineProperty,
|
|
6
|
+
createAction,
|
|
7
|
+
globalState,
|
|
8
|
+
flow,
|
|
9
|
+
computed,
|
|
10
|
+
autoAction,
|
|
11
|
+
isGenerator,
|
|
12
|
+
MakeResult
|
|
13
|
+
} from "../internal"
|
|
14
|
+
|
|
15
|
+
const AUTO = "true"
|
|
16
|
+
|
|
17
|
+
export const autoAnnotation: Annotation = createAutoAnnotation()
|
|
18
|
+
|
|
19
|
+
export function createAutoAnnotation(options?: object): Annotation {
|
|
20
|
+
return {
|
|
21
|
+
annotationType_: AUTO,
|
|
22
|
+
options_: options,
|
|
23
|
+
make_,
|
|
24
|
+
extend_
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function make_(
|
|
29
|
+
adm: ObservableObjectAdministration,
|
|
30
|
+
key: PropertyKey,
|
|
31
|
+
descriptor: PropertyDescriptor,
|
|
32
|
+
source: object
|
|
33
|
+
): MakeResult {
|
|
34
|
+
// getter -> computed
|
|
35
|
+
if (descriptor.get) {
|
|
36
|
+
return computed.make_(adm, key, descriptor, source)
|
|
37
|
+
}
|
|
38
|
+
// lone setter -> action setter
|
|
39
|
+
if (descriptor.set) {
|
|
40
|
+
// TODO make action applicable to setter and delegate to action.make_
|
|
41
|
+
const set = createAction(key.toString(), descriptor.set) as (v: any) => void
|
|
42
|
+
// own
|
|
43
|
+
if (source === adm.target_) {
|
|
44
|
+
return adm.defineProperty_(key, {
|
|
45
|
+
configurable: globalState.safeDescriptors ? adm.isPlainObject_ : true,
|
|
46
|
+
set
|
|
47
|
+
}) === null
|
|
48
|
+
? MakeResult.Cancel
|
|
49
|
+
: MakeResult.Continue
|
|
50
|
+
}
|
|
51
|
+
// proto
|
|
52
|
+
defineProperty(source, key, {
|
|
53
|
+
configurable: true,
|
|
54
|
+
set
|
|
55
|
+
})
|
|
56
|
+
return MakeResult.Continue
|
|
57
|
+
}
|
|
58
|
+
// function on proto -> autoAction/flow
|
|
59
|
+
if (source !== adm.target_ && typeof descriptor.value === "function") {
|
|
60
|
+
if (isGenerator(descriptor.value)) {
|
|
61
|
+
const flowAnnotation = this.options_?.autoBind ? flow.bound : flow
|
|
62
|
+
return flowAnnotation.make_(adm, key, descriptor, source)
|
|
63
|
+
}
|
|
64
|
+
const actionAnnotation = this.options_?.autoBind ? autoAction.bound : autoAction
|
|
65
|
+
return actionAnnotation.make_(adm, key, descriptor, source)
|
|
66
|
+
}
|
|
67
|
+
// other -> observable
|
|
68
|
+
// Copy props from proto as well, see test:
|
|
69
|
+
// "decorate should work with Object.create"
|
|
70
|
+
let observableAnnotation = this.options_?.deep === false ? observable.ref : observable
|
|
71
|
+
// if function respect autoBind option
|
|
72
|
+
if (typeof descriptor.value === "function" && this.options_?.autoBind) {
|
|
73
|
+
descriptor.value = descriptor.value.bind(adm.proxy_ ?? adm.target_)
|
|
74
|
+
}
|
|
75
|
+
return observableAnnotation.make_(adm, key, descriptor, source)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function extend_(
|
|
79
|
+
adm: ObservableObjectAdministration,
|
|
80
|
+
key: PropertyKey,
|
|
81
|
+
descriptor: PropertyDescriptor,
|
|
82
|
+
proxyTrap: boolean
|
|
83
|
+
): boolean | null {
|
|
84
|
+
// getter -> computed
|
|
85
|
+
if (descriptor.get) {
|
|
86
|
+
return computed.extend_(adm, key, descriptor, proxyTrap)
|
|
87
|
+
}
|
|
88
|
+
// lone setter -> action setter
|
|
89
|
+
if (descriptor.set) {
|
|
90
|
+
// TODO make action applicable to setter and delegate to action.extend_
|
|
91
|
+
return adm.defineProperty_(
|
|
92
|
+
key,
|
|
93
|
+
{
|
|
94
|
+
configurable: globalState.safeDescriptors ? adm.isPlainObject_ : true,
|
|
95
|
+
set: createAction(key.toString(), descriptor.set) as (v: any) => void
|
|
96
|
+
},
|
|
97
|
+
proxyTrap
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
// other -> observable
|
|
101
|
+
// if function respect autoBind option
|
|
102
|
+
if (typeof descriptor.value === "function" && this.options_?.autoBind) {
|
|
103
|
+
descriptor.value = descriptor.value.bind(adm.proxy_ ?? adm.target_)
|
|
104
|
+
}
|
|
105
|
+
let observableAnnotation = this.options_?.deep === false ? observable.ref : observable
|
|
106
|
+
return observableAnnotation.extend_(adm, key, descriptor, proxyTrap)
|
|
107
|
+
}
|
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ObservableObjectAdministration,
|
|
3
|
-
getDescriptor,
|
|
4
|
-
objectPrototype,
|
|
5
|
-
die,
|
|
6
|
-
Annotation,
|
|
7
|
-
recordAnnotationApplied,
|
|
8
|
-
storedAnnotationsSymbol
|
|
9
|
-
} from "../internal"
|
|
1
|
+
import { ObservableObjectAdministration, die, Annotation, MakeResult } from "../internal"
|
|
10
2
|
|
|
11
3
|
export function createComputedAnnotation(name: string, options?: object): Annotation {
|
|
12
4
|
return {
|
|
@@ -17,34 +9,12 @@ export function createComputedAnnotation(name: string, options?: object): Annota
|
|
|
17
9
|
}
|
|
18
10
|
}
|
|
19
11
|
|
|
20
|
-
function make_(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const definePropertyOutcome = adm.defineComputedProperty_(key, {
|
|
27
|
-
...this.options_,
|
|
28
|
-
get: descriptor.get,
|
|
29
|
-
set: descriptor.set
|
|
30
|
-
})
|
|
31
|
-
if (!definePropertyOutcome) {
|
|
32
|
-
// Intercepted
|
|
33
|
-
return
|
|
34
|
-
}
|
|
35
|
-
recordAnnotationApplied(adm, this, key)
|
|
36
|
-
return
|
|
37
|
-
}
|
|
38
|
-
source = Object.getPrototypeOf(source)
|
|
39
|
-
}
|
|
40
|
-
if (!adm.target_[storedAnnotationsSymbol]?.[key]) {
|
|
41
|
-
// Throw on missing key, except for decorators:
|
|
42
|
-
// Decorator annotations are collected from whole prototype chain.
|
|
43
|
-
// When called from super() some props may not exist yet.
|
|
44
|
-
// However we don't have to worry about missing prop,
|
|
45
|
-
// because the decorator must have been applied to something.
|
|
46
|
-
die(1, this.annotationType_, `${adm.name_}.${key.toString()}`)
|
|
47
|
-
}
|
|
12
|
+
function make_(
|
|
13
|
+
adm: ObservableObjectAdministration,
|
|
14
|
+
key: PropertyKey,
|
|
15
|
+
descriptor: PropertyDescriptor
|
|
16
|
+
): MakeResult {
|
|
17
|
+
return this.extend_(adm, key, descriptor, false) === null ? MakeResult.Cancel : MakeResult.Break
|
|
48
18
|
}
|
|
49
19
|
|
|
50
20
|
function extend_(
|
|
@@ -19,17 +19,20 @@ function getAdm(target): ObservableObjectAdministration {
|
|
|
19
19
|
// and skip either the internal values map, or the base object with its property descriptors!
|
|
20
20
|
const objectProxyTraps: ProxyHandler<any> = {
|
|
21
21
|
has(target: IIsObservableObject, name: PropertyKey): boolean {
|
|
22
|
-
if (__DEV__ && globalState.trackingDerivation)
|
|
22
|
+
if (__DEV__ && globalState.trackingDerivation) {
|
|
23
23
|
warnAboutProxyRequirement(
|
|
24
24
|
"detect new properties using the 'in' operator. Use 'has' from 'mobx' instead."
|
|
25
25
|
)
|
|
26
|
+
}
|
|
26
27
|
return getAdm(target).has_(name)
|
|
27
28
|
},
|
|
28
29
|
get(target: IIsObservableObject, name: PropertyKey): any {
|
|
29
30
|
return getAdm(target).get_(name)
|
|
30
31
|
},
|
|
31
32
|
set(target: IIsObservableObject, name: PropertyKey, value: any): boolean {
|
|
32
|
-
if (!isStringish(name))
|
|
33
|
+
if (!isStringish(name)) {
|
|
34
|
+
return false
|
|
35
|
+
}
|
|
33
36
|
if (__DEV__ && !getAdm(target).values_.has(name)) {
|
|
34
37
|
warnAboutProxyRequirement(
|
|
35
38
|
"add a new observable property through direct assignment. Use 'set' from 'mobx' instead."
|
|
@@ -44,7 +47,9 @@ const objectProxyTraps: ProxyHandler<any> = {
|
|
|
44
47
|
"delete properties from an observable object. Use 'remove' from 'mobx' instead."
|
|
45
48
|
)
|
|
46
49
|
}
|
|
47
|
-
if (!isStringish(name))
|
|
50
|
+
if (!isStringish(name)) {
|
|
51
|
+
return false
|
|
52
|
+
}
|
|
48
53
|
// null (intercepted) -> true (success)
|
|
49
54
|
return getAdm(target).delete_(name, true) ?? true
|
|
50
55
|
},
|
|
@@ -61,11 +66,12 @@ const objectProxyTraps: ProxyHandler<any> = {
|
|
|
61
66
|
// null (intercepted) -> true (success)
|
|
62
67
|
return getAdm(target).defineProperty_(name, descriptor) ?? true
|
|
63
68
|
},
|
|
64
|
-
ownKeys(target: IIsObservableObject):
|
|
65
|
-
if (__DEV__ && globalState.trackingDerivation)
|
|
69
|
+
ownKeys(target: IIsObservableObject): ArrayLike<string | symbol> {
|
|
70
|
+
if (__DEV__ && globalState.trackingDerivation) {
|
|
66
71
|
warnAboutProxyRequirement(
|
|
67
|
-
"iterate keys to detect added / removed properties. Use
|
|
72
|
+
"iterate keys to detect added / removed properties. Use 'keys' from 'mobx' instead."
|
|
68
73
|
)
|
|
74
|
+
}
|
|
69
75
|
return getAdm(target).ownKeys_()
|
|
70
76
|
},
|
|
71
77
|
preventExtensions(target) {
|
|
@@ -2,15 +2,13 @@ import {
|
|
|
2
2
|
ObservableObjectAdministration,
|
|
3
3
|
Annotation,
|
|
4
4
|
defineProperty,
|
|
5
|
-
getDescriptor,
|
|
6
|
-
objectPrototype,
|
|
7
5
|
die,
|
|
8
6
|
flow,
|
|
9
7
|
isFlow,
|
|
10
|
-
recordAnnotationApplied,
|
|
11
8
|
isFunction,
|
|
12
9
|
globalState,
|
|
13
|
-
|
|
10
|
+
MakeResult,
|
|
11
|
+
hasProp
|
|
14
12
|
} from "../internal"
|
|
15
13
|
|
|
16
14
|
export function createFlowAnnotation(name: string, options?: object): Annotation {
|
|
@@ -22,44 +20,33 @@ export function createFlowAnnotation(name: string, options?: object): Annotation
|
|
|
22
20
|
}
|
|
23
21
|
}
|
|
24
22
|
|
|
25
|
-
function make_(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const flowDescriptor = createFlowDescriptor(adm, this, key, descriptor)
|
|
43
|
-
const definePropertyOutcome = adm.defineProperty_(key, flowDescriptor)
|
|
44
|
-
if (!definePropertyOutcome) {
|
|
45
|
-
// Intercepted
|
|
46
|
-
return
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
annotated = true
|
|
23
|
+
function make_(
|
|
24
|
+
adm: ObservableObjectAdministration,
|
|
25
|
+
key: PropertyKey,
|
|
26
|
+
descriptor: PropertyDescriptor,
|
|
27
|
+
source: object
|
|
28
|
+
): MakeResult {
|
|
29
|
+
// own
|
|
30
|
+
if (source === adm.target_) {
|
|
31
|
+
return this.extend_(adm, key, descriptor, false) === null
|
|
32
|
+
? MakeResult.Cancel
|
|
33
|
+
: MakeResult.Continue
|
|
34
|
+
}
|
|
35
|
+
// prototype
|
|
36
|
+
// bound - must annotate protos to support super.flow()
|
|
37
|
+
if (this.options_?.bound && (!hasProp(adm.target_, key) || !isFlow(adm.target_[key]))) {
|
|
38
|
+
if (this.extend_(adm, key, descriptor, false) === null) {
|
|
39
|
+
return MakeResult.Cancel
|
|
50
40
|
}
|
|
51
|
-
source = Object.getPrototypeOf(source)
|
|
52
41
|
}
|
|
53
|
-
if (
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
// Decorator annotations are collected from whole prototype chain.
|
|
58
|
-
// When called from super() some props may not exist yet.
|
|
59
|
-
// However we don't have to worry about missing prop,
|
|
60
|
-
// because the decorator must have been applied to something.
|
|
61
|
-
die(1, this.annotationType_, `${adm.name_}.${key.toString()}`)
|
|
42
|
+
if (isFlow(descriptor.value)) {
|
|
43
|
+
// A prototype could have been annotated already by other constructor,
|
|
44
|
+
// rest of the proto chain must be annotated already
|
|
45
|
+
return MakeResult.Break
|
|
62
46
|
}
|
|
47
|
+
const flowDescriptor = createFlowDescriptor(adm, this, key, descriptor, false, false)
|
|
48
|
+
defineProperty(source, key, flowDescriptor)
|
|
49
|
+
return MakeResult.Continue
|
|
63
50
|
}
|
|
64
51
|
|
|
65
52
|
function extend_(
|
|
@@ -68,7 +55,7 @@ function extend_(
|
|
|
68
55
|
descriptor: PropertyDescriptor,
|
|
69
56
|
proxyTrap: boolean
|
|
70
57
|
): boolean | null {
|
|
71
|
-
const flowDescriptor = createFlowDescriptor(adm, this, key, descriptor)
|
|
58
|
+
const flowDescriptor = createFlowDescriptor(adm, this, key, descriptor, this.options_?.bound)
|
|
72
59
|
return adm.defineProperty_(key, flowDescriptor, proxyTrap)
|
|
73
60
|
}
|
|
74
61
|
|
|
@@ -91,12 +78,24 @@ function createFlowDescriptor(
|
|
|
91
78
|
annotation: Annotation,
|
|
92
79
|
key: PropertyKey,
|
|
93
80
|
descriptor: PropertyDescriptor,
|
|
81
|
+
bound: boolean,
|
|
94
82
|
// provides ability to disable safeDescriptors for prototypes
|
|
95
83
|
safeDescriptors: boolean = globalState.safeDescriptors
|
|
96
84
|
): PropertyDescriptor {
|
|
97
85
|
assertFlowDescriptor(adm, annotation, key, descriptor)
|
|
86
|
+
let { value } = descriptor
|
|
87
|
+
// In case of flow.bound, the descriptor can be from already annotated prototype
|
|
88
|
+
if (!isFlow(value)) {
|
|
89
|
+
value = flow(value)
|
|
90
|
+
}
|
|
91
|
+
if (bound) {
|
|
92
|
+
// We do not keep original function around, so we bind the existing flow
|
|
93
|
+
value = value.bind(adm.proxy_ ?? adm.target_)
|
|
94
|
+
// This is normally set by `flow`, but `bind` returns new function...
|
|
95
|
+
value.isMobXFlow = true
|
|
96
|
+
}
|
|
98
97
|
return {
|
|
99
|
-
value
|
|
98
|
+
value,
|
|
100
99
|
// Non-configurable for classes
|
|
101
100
|
// prevents accidental field redefinition in subclass
|
|
102
101
|
configurable: safeDescriptors ? adm.isPlainObject_ : true,
|
|
@@ -18,7 +18,9 @@ export function registerInterceptor<T>(
|
|
|
18
18
|
interceptors.push(handler)
|
|
19
19
|
return once(() => {
|
|
20
20
|
const idx = interceptors.indexOf(handler)
|
|
21
|
-
if (idx !== -1)
|
|
21
|
+
if (idx !== -1) {
|
|
22
|
+
interceptors.splice(idx, 1)
|
|
23
|
+
}
|
|
22
24
|
})
|
|
23
25
|
}
|
|
24
26
|
|
|
@@ -32,8 +34,12 @@ export function interceptChange<T>(
|
|
|
32
34
|
const interceptors = [...(interceptable.interceptors_ || [])]
|
|
33
35
|
for (let i = 0, l = interceptors.length; i < l; i++) {
|
|
34
36
|
change = interceptors[i](change)
|
|
35
|
-
if (change && !(change as any).type)
|
|
36
|
-
|
|
37
|
+
if (change && !(change as any).type) {
|
|
38
|
+
die(14)
|
|
39
|
+
}
|
|
40
|
+
if (!change) {
|
|
41
|
+
break
|
|
42
|
+
}
|
|
37
43
|
}
|
|
38
44
|
return change
|
|
39
45
|
} finally {
|
|
@@ -14,6 +14,21 @@ import {
|
|
|
14
14
|
defineProperty
|
|
15
15
|
} from "../internal"
|
|
16
16
|
|
|
17
|
+
// Bug in safari 9.* (or iOS 9 safari mobile). See #364
|
|
18
|
+
const ENTRY_0 = createArrayEntryDescriptor(0)
|
|
19
|
+
|
|
20
|
+
const safariPrototypeSetterInheritanceBug = (() => {
|
|
21
|
+
let v = false
|
|
22
|
+
const p = {}
|
|
23
|
+
Object.defineProperty(p, "0", {
|
|
24
|
+
set: () => {
|
|
25
|
+
v = true
|
|
26
|
+
}
|
|
27
|
+
})
|
|
28
|
+
Object.create(p)["0"] = 1
|
|
29
|
+
return v === false
|
|
30
|
+
})()
|
|
31
|
+
|
|
17
32
|
/**
|
|
18
33
|
* This array buffer contains two lists of properties, so that all arrays
|
|
19
34
|
* can recycle their property definitions, which significantly improves performance of creating
|
|
@@ -57,6 +72,12 @@ class LegacyObservableArray<T> extends StubArray {
|
|
|
57
72
|
this.spliceWithArray(0, 0, initialValues)
|
|
58
73
|
allowStateChangesEnd(prev)
|
|
59
74
|
}
|
|
75
|
+
|
|
76
|
+
if (safariPrototypeSetterInheritanceBug) {
|
|
77
|
+
// Seems that Safari won't use numeric prototype setter untill any * numeric property is
|
|
78
|
+
// defined on the instance. After that it works fine, even if this property is deleted.
|
|
79
|
+
Object.defineProperty(this, "0", ENTRY_0)
|
|
80
|
+
}
|
|
60
81
|
}
|
|
61
82
|
|
|
62
83
|
concat(...arrays: T[][]): T[] {
|
|
@@ -85,7 +106,6 @@ class LegacyObservableArray<T> extends StubArray {
|
|
|
85
106
|
let nextIndex = 0
|
|
86
107
|
return makeIterable({
|
|
87
108
|
next() {
|
|
88
|
-
// @ts-ignore
|
|
89
109
|
return nextIndex < self.length
|
|
90
110
|
? { value: self[nextIndex++], done: false }
|
|
91
111
|
: { done: true, value: undefined }
|
|
@@ -95,7 +115,9 @@ class LegacyObservableArray<T> extends StubArray {
|
|
|
95
115
|
}
|
|
96
116
|
|
|
97
117
|
Object.entries(arrayExtensions).forEach(([prop, fn]) => {
|
|
98
|
-
if (prop !== "concat")
|
|
118
|
+
if (prop !== "concat") {
|
|
119
|
+
addHiddenProp(LegacyObservableArray.prototype, prop, fn)
|
|
120
|
+
}
|
|
99
121
|
})
|
|
100
122
|
|
|
101
123
|
function createArrayEntryDescriptor(index: number) {
|
|
@@ -117,8 +139,9 @@ function createArrayBufferItem(index: number) {
|
|
|
117
139
|
|
|
118
140
|
export function reserveArrayBuffer(max: number) {
|
|
119
141
|
if (max > OBSERVABLE_ARRAY_BUFFER_SIZE) {
|
|
120
|
-
for (let index = OBSERVABLE_ARRAY_BUFFER_SIZE; index < max + 100; index++)
|
|
142
|
+
for (let index = OBSERVABLE_ARRAY_BUFFER_SIZE; index < max + 100; index++) {
|
|
121
143
|
createArrayBufferItem(index)
|
|
144
|
+
}
|
|
122
145
|
OBSERVABLE_ARRAY_BUFFER_SIZE = max
|
|
123
146
|
}
|
|
124
147
|
}
|
|
@@ -13,14 +13,18 @@ export function registerListener(listenable: IListenable, handler: Function): La
|
|
|
13
13
|
listeners.push(handler)
|
|
14
14
|
return once(() => {
|
|
15
15
|
const idx = listeners.indexOf(handler)
|
|
16
|
-
if (idx !== -1)
|
|
16
|
+
if (idx !== -1) {
|
|
17
|
+
listeners.splice(idx, 1)
|
|
18
|
+
}
|
|
17
19
|
})
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
export function notifyListeners<T>(listenable: IListenable, change: T) {
|
|
21
23
|
const prevU = untrackedStart()
|
|
22
24
|
let listeners = listenable.changeListeners_
|
|
23
|
-
if (!listeners)
|
|
25
|
+
if (!listeners) {
|
|
26
|
+
return
|
|
27
|
+
}
|
|
24
28
|
listeners = listeners.slice()
|
|
25
29
|
for (let i = 0, l = listeners.length; i < l; i++) {
|
|
26
30
|
listeners[i](change)
|