mobx 7.0.4 → 7.0.5
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 +6 -0
- package/dist/mobx.cjs.development.js +60 -30
- 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.esm.development.js +60 -30
- package/dist/mobx.esm.development.js.map +1 -1
- package/dist/mobx.esm.js +60 -30
- 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.mjs +60 -30
- package/dist/mobx.mjs.map +1 -1
- package/dist/mobx.umd.development.js +60 -30
- 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/autoannotation.d.ts +2 -1
- package/package.json +1 -1
- package/src/api/observable.ts +2 -2
- package/src/core/observable.ts +33 -25
- package/src/types/autoannotation.ts +13 -1
- package/src/types/intercept-utils.ts +7 -2
- package/src/types/listen-utils.ts +7 -2
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import { Annotation } from "../internal";
|
|
1
|
+
import { Annotation, CreateObservableOptions } from "../internal";
|
|
2
2
|
export declare const autoAnnotation: Annotation;
|
|
3
3
|
export declare function createAutoAnnotation(options?: object): Annotation;
|
|
4
|
+
export declare function getAutoAnnotation(options: CreateObservableOptions): Annotation;
|
package/package.json
CHANGED
package/src/api/observable.ts
CHANGED
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
AnnotationsMap,
|
|
27
27
|
assign,
|
|
28
28
|
createObservableAnnotation,
|
|
29
|
-
|
|
29
|
+
getAutoAnnotation,
|
|
30
30
|
initObservable,
|
|
31
31
|
decorateObservable20223_
|
|
32
32
|
} from "../internal"
|
|
@@ -87,7 +87,7 @@ export function getEnhancerFromOptions(options: CreateObservableOptions): IEnhan
|
|
|
87
87
|
export function getAnnotationFromOptions(
|
|
88
88
|
options?: CreateObservableOptions
|
|
89
89
|
): Annotation | undefined {
|
|
90
|
-
return options ? options.defaultDecorator ??
|
|
90
|
+
return options ? options.defaultDecorator ?? getAutoAnnotation(options) : undefined
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
export function getEnhancerFromAnnotation(annotation?: Annotation): IEnhancer<any> {
|
package/src/core/observable.ts
CHANGED
|
@@ -117,34 +117,42 @@ export function endBatch() {
|
|
|
117
117
|
// the nested call instead of recursing; the outer loop re-reads list.length on
|
|
118
118
|
// every iteration, so it picks up anything the nested dispose() pushes onto the
|
|
119
119
|
// same pendingUnobservations array.
|
|
120
|
-
if (!globalState.isRunningUnobservations) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
120
|
+
if (!globalState.isRunningUnobservations && globalState.pendingUnobservations.length > 0) {
|
|
121
|
+
runPendingUnobservations()
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Only called when there is something to unobserve, so the common endBatch() skips the
|
|
127
|
+
// try/finally and the pendingUnobservations reallocation entirely
|
|
128
|
+
function runPendingUnobservations() {
|
|
129
|
+
globalState.isRunningUnobservations = true
|
|
130
|
+
try {
|
|
131
|
+
const list = globalState.pendingUnobservations
|
|
132
|
+
for (let i = 0; i < list.length; i++) {
|
|
133
|
+
const observable = list[i]
|
|
134
|
+
observable.isPendingUnobservation = false
|
|
135
|
+
if (!observable.observers_ || observable.observers_.size === 0) {
|
|
136
|
+
// release the empty Set so unobserved atoms don't keep paying for it
|
|
137
|
+
observable.observers_ = null
|
|
138
|
+
if (observable.isBeingObserved) {
|
|
139
|
+
// if this observable had reactive observers, trigger the hooks
|
|
140
|
+
observable.isBeingObserved = false
|
|
141
|
+
observable.onBUO()
|
|
142
|
+
}
|
|
143
|
+
if (observable instanceof ComputedValue) {
|
|
144
|
+
// computed values are automatically teared down when the last observer leaves
|
|
145
|
+
// this process happens recursively, this computed might be the last observabe of another, etc..
|
|
146
|
+
observable.suspend_()
|
|
139
147
|
}
|
|
140
|
-
globalState.pendingUnobservations = []
|
|
141
|
-
} finally {
|
|
142
|
-
// Always release the guard, even if an onBUO handler (user code) threw,
|
|
143
|
-
// otherwise every future endBatch() would see isRunningUnobservations
|
|
144
|
-
// stuck true and silently stop draining pendingUnobservations forever.
|
|
145
|
-
globalState.isRunningUnobservations = false
|
|
146
148
|
}
|
|
147
149
|
}
|
|
150
|
+
globalState.pendingUnobservations = []
|
|
151
|
+
} finally {
|
|
152
|
+
// Always release the guard, even if an onBUO handler (user code) threw,
|
|
153
|
+
// otherwise every future endBatch() would see isRunningUnobservations
|
|
154
|
+
// stuck true and silently stop draining pendingUnobservations forever.
|
|
155
|
+
globalState.isRunningUnobservations = false
|
|
148
156
|
}
|
|
149
157
|
}
|
|
150
158
|
|
|
@@ -13,7 +13,8 @@ import {
|
|
|
13
13
|
autoActionBound,
|
|
14
14
|
isGenerator,
|
|
15
15
|
MakeResult,
|
|
16
|
-
isAction
|
|
16
|
+
isAction,
|
|
17
|
+
CreateObservableOptions
|
|
17
18
|
} from "../internal"
|
|
18
19
|
|
|
19
20
|
const AUTO = "true"
|
|
@@ -29,6 +30,17 @@ export function createAutoAnnotation(options?: object): Annotation {
|
|
|
29
30
|
}
|
|
30
31
|
}
|
|
31
32
|
|
|
33
|
+
// The auto annotation only depends on `deep` and `autoBind`, so share one instance per combination
|
|
34
|
+
// instead of allocating one for every object created with options
|
|
35
|
+
const autoAnnotations: Annotation[] = [autoAnnotation]
|
|
36
|
+
|
|
37
|
+
export function getAutoAnnotation(options: CreateObservableOptions): Annotation {
|
|
38
|
+
const deep = options.deep !== false
|
|
39
|
+
const autoBind = !!options.autoBind
|
|
40
|
+
const idx = (deep ? 0 : 1) | (autoBind ? 2 : 0)
|
|
41
|
+
return (autoAnnotations[idx] ??= createAutoAnnotation({ deep, autoBind }))
|
|
42
|
+
}
|
|
43
|
+
|
|
32
44
|
function make_(
|
|
33
45
|
adm: ObservableObjectAdministration,
|
|
34
46
|
key: PropertyKey,
|
|
@@ -14,8 +14,13 @@ export function registerInterceptor<T>(
|
|
|
14
14
|
interceptable: IInterceptable<T>,
|
|
15
15
|
handler: IInterceptor<T>
|
|
16
16
|
): Lambda {
|
|
17
|
-
|
|
18
|
-
interceptors
|
|
17
|
+
let interceptors = interceptable.interceptors_
|
|
18
|
+
if (interceptors) {
|
|
19
|
+
interceptors.push(handler)
|
|
20
|
+
} else {
|
|
21
|
+
// Allocate at the exact size: pushing onto an empty array over-allocates its backing store
|
|
22
|
+
interceptors = interceptable.interceptors_ = [handler]
|
|
23
|
+
}
|
|
19
24
|
return once(() => {
|
|
20
25
|
const idx = interceptors.indexOf(handler)
|
|
21
26
|
if (idx !== -1) {
|
|
@@ -9,8 +9,13 @@ export function hasListeners(listenable: IListenable) {
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export function registerListener(listenable: IListenable, handler: Function): Lambda {
|
|
12
|
-
|
|
13
|
-
listeners
|
|
12
|
+
let listeners = listenable.changeListeners_
|
|
13
|
+
if (listeners) {
|
|
14
|
+
listeners.push(handler)
|
|
15
|
+
} else {
|
|
16
|
+
// Allocate at the exact size: pushing onto an empty array over-allocates its backing store
|
|
17
|
+
listeners = listenable.changeListeners_ = [handler]
|
|
18
|
+
}
|
|
14
19
|
return once(() => {
|
|
15
20
|
const idx = listeners.indexOf(handler)
|
|
16
21
|
if (idx !== -1) {
|