mobx 6.13.0 → 6.13.2
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 +12 -0
- package/README.md +2 -2
- package/dist/core/atom.d.ts +10 -3
- package/dist/core/computedvalue.d.ts +3 -1
- package/dist/core/observable.d.ts +1 -1
- package/dist/core/reaction.d.ts +16 -6
- package/dist/mobx.cjs.development.js +133 -53
- 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 +133 -53
- package/dist/mobx.esm.development.js.map +1 -1
- package/dist/mobx.esm.js +133 -53
- 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 +133 -53
- 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/utils/utils.d.ts +14 -3
- package/package.json +1 -1
- package/src/api/autorun.ts +4 -4
- package/src/api/when.ts +1 -1
- package/src/core/atom.ts +29 -3
- package/src/core/computedvalue.ts +19 -18
- package/src/core/derivation.ts +6 -6
- package/src/core/observable.ts +1 -1
- package/src/core/reaction.ts +59 -23
- package/src/types/observableset.ts +4 -4
- package/src/utils/utils.ts +25 -3
package/dist/utils/utils.d.ts
CHANGED
|
@@ -30,9 +30,18 @@ export declare function isGenerator(obj: any): boolean;
|
|
|
30
30
|
export declare function addHiddenProp(object: any, propName: PropertyKey, value: any): void;
|
|
31
31
|
export declare function addHiddenFinalProp(object: any, propName: PropertyKey, value: any): void;
|
|
32
32
|
export declare function createInstanceofPredicate<T>(name: string, theClass: new (...args: any[]) => T): (x: any) => x is T;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Yields true for both native and observable Map, even across different windows.
|
|
35
|
+
*/
|
|
36
|
+
export declare function isES6Map(thing: unknown): thing is Map<any, any>;
|
|
37
|
+
/**
|
|
38
|
+
* Makes sure a Map is an instance of non-inherited native or observable Map.
|
|
39
|
+
*/
|
|
40
|
+
export declare function isPlainES6Map(thing: Map<unknown, unknown>): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Yields true for both native and observable Set, even across different windows.
|
|
43
|
+
*/
|
|
44
|
+
export declare function isES6Set(thing: unknown): thing is Set<any>;
|
|
36
45
|
/**
|
|
37
46
|
* Returns the following: own enumerable keys and symbols.
|
|
38
47
|
*/
|
|
@@ -44,3 +53,5 @@ export declare function hasProp(target: Object, prop: PropertyKey): boolean;
|
|
|
44
53
|
export declare const getOwnPropertyDescriptors: <T>(o: T) => { [P in keyof T]: TypedPropertyDescriptor<T[P]>; } & {
|
|
45
54
|
[x: string]: PropertyDescriptor;
|
|
46
55
|
};
|
|
56
|
+
export declare function getFlag(flags: number, mask: number): boolean;
|
|
57
|
+
export declare function setFlag(flags: number, mask: number, newValue: boolean): number;
|
package/package.json
CHANGED
package/src/api/autorun.ts
CHANGED
|
@@ -75,7 +75,7 @@ export function autorun(
|
|
|
75
75
|
isScheduled = true
|
|
76
76
|
scheduler(() => {
|
|
77
77
|
isScheduled = false
|
|
78
|
-
if (!reaction.
|
|
78
|
+
if (!reaction.isDisposed) {
|
|
79
79
|
reaction.track(reactionRunner)
|
|
80
80
|
}
|
|
81
81
|
})
|
|
@@ -90,7 +90,7 @@ export function autorun(
|
|
|
90
90
|
view(reaction)
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
if(!opts?.signal?.aborted) {
|
|
93
|
+
if (!opts?.signal?.aborted) {
|
|
94
94
|
reaction.schedule_()
|
|
95
95
|
}
|
|
96
96
|
return reaction.getDisposer_(opts?.signal)
|
|
@@ -160,7 +160,7 @@ export function reaction<T, FireImmediately extends boolean = false>(
|
|
|
160
160
|
|
|
161
161
|
function reactionRunner() {
|
|
162
162
|
isScheduled = false
|
|
163
|
-
if (r.
|
|
163
|
+
if (r.isDisposed) {
|
|
164
164
|
return
|
|
165
165
|
}
|
|
166
166
|
let changed: boolean = false
|
|
@@ -181,7 +181,7 @@ export function reaction<T, FireImmediately extends boolean = false>(
|
|
|
181
181
|
firstTime = false
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
if(!opts?.signal?.aborted) {
|
|
184
|
+
if (!opts?.signal?.aborted) {
|
|
185
185
|
r.schedule_()
|
|
186
186
|
}
|
|
187
187
|
return r.getDisposer_(opts?.signal)
|
package/src/api/when.ts
CHANGED
|
@@ -38,7 +38,7 @@ function _when(predicate: () => boolean, effect: Lambda, opts: IWhenOptions): IR
|
|
|
38
38
|
if (typeof opts.timeout === "number") {
|
|
39
39
|
const error = new Error("WHEN_TIMEOUT")
|
|
40
40
|
timeoutHandle = setTimeout(() => {
|
|
41
|
-
if (!disposer[$mobx].
|
|
41
|
+
if (!disposer[$mobx].isDisposed) {
|
|
42
42
|
disposer()
|
|
43
43
|
if (opts.onError) {
|
|
44
44
|
opts.onError(error)
|
package/src/core/atom.ts
CHANGED
|
@@ -14,6 +14,8 @@ import {
|
|
|
14
14
|
Lambda
|
|
15
15
|
} from "../internal"
|
|
16
16
|
|
|
17
|
+
import { getFlag, setFlag } from "../utils/utils"
|
|
18
|
+
|
|
17
19
|
export const $mobx = Symbol("mobx administration")
|
|
18
20
|
|
|
19
21
|
export interface IAtom extends IObservable {
|
|
@@ -22,11 +24,13 @@ export interface IAtom extends IObservable {
|
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
export class Atom implements IAtom {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
private static readonly isBeingObservedMask_ = 0b001
|
|
28
|
+
private static readonly isPendingUnobservationMask_ = 0b010
|
|
29
|
+
private static readonly diffValueMask_ = 0b100
|
|
30
|
+
private flags_ = 0b000
|
|
31
|
+
|
|
27
32
|
observers_ = new Set<IDerivation>()
|
|
28
33
|
|
|
29
|
-
diffValue_ = 0
|
|
30
34
|
lastAccessedBy_ = 0
|
|
31
35
|
lowestObserverState_ = IDerivationState_.NOT_TRACKING_
|
|
32
36
|
/**
|
|
@@ -35,6 +39,28 @@ export class Atom implements IAtom {
|
|
|
35
39
|
*/
|
|
36
40
|
constructor(public name_ = __DEV__ ? "Atom@" + getNextId() : "Atom") {}
|
|
37
41
|
|
|
42
|
+
// for effective unobserving. BaseAtom has true, for extra optimization, so its onBecomeUnobserved never gets called, because it's not needed
|
|
43
|
+
get isBeingObserved(): boolean {
|
|
44
|
+
return getFlag(this.flags_, Atom.isBeingObservedMask_)
|
|
45
|
+
}
|
|
46
|
+
set isBeingObserved(newValue: boolean) {
|
|
47
|
+
this.flags_ = setFlag(this.flags_, Atom.isBeingObservedMask_, newValue)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
get isPendingUnobservation(): boolean {
|
|
51
|
+
return getFlag(this.flags_, Atom.isPendingUnobservationMask_)
|
|
52
|
+
}
|
|
53
|
+
set isPendingUnobservation(newValue: boolean) {
|
|
54
|
+
this.flags_ = setFlag(this.flags_, Atom.isPendingUnobservationMask_, newValue)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
get diffValue(): 0 | 1 {
|
|
58
|
+
return getFlag(this.flags_, Atom.diffValueMask_) ? 1 : 0
|
|
59
|
+
}
|
|
60
|
+
set diffValue(newValue: 0 | 1) {
|
|
61
|
+
this.flags_ = setFlag(this.flags_, Atom.diffValueMask_, newValue === 1 ? true : false)
|
|
62
|
+
}
|
|
63
|
+
|
|
38
64
|
// onBecomeObservedListeners
|
|
39
65
|
public onBOL: Set<Lambda> | undefined
|
|
40
66
|
// onBecomeUnobservedListeners
|
|
@@ -32,6 +32,8 @@ import {
|
|
|
32
32
|
allowStateChangesEnd
|
|
33
33
|
} from "../internal"
|
|
34
34
|
|
|
35
|
+
import { getFlag, setFlag } from "../utils/utils"
|
|
36
|
+
|
|
35
37
|
export interface IComputedValue<T> {
|
|
36
38
|
get(): T
|
|
37
39
|
set(value: T): void
|
|
@@ -56,18 +58,6 @@ export type IComputedDidChange<T = any> = {
|
|
|
56
58
|
oldValue: T | undefined
|
|
57
59
|
}
|
|
58
60
|
|
|
59
|
-
function getFlag(flags: number, mask: number) {
|
|
60
|
-
return !!(flags & mask)
|
|
61
|
-
}
|
|
62
|
-
function setFlag(flags: number, mask: number, newValue: boolean): number {
|
|
63
|
-
if (newValue) {
|
|
64
|
-
flags |= mask
|
|
65
|
-
} else {
|
|
66
|
-
flags &= ~mask
|
|
67
|
-
}
|
|
68
|
-
return flags
|
|
69
|
-
}
|
|
70
|
-
|
|
71
61
|
/**
|
|
72
62
|
* A node in the state dependency root that observes other nodes, and can be observed itself.
|
|
73
63
|
*
|
|
@@ -92,7 +82,6 @@ export class ComputedValue<T> implements IObservable, IComputedValue<T>, IDeriva
|
|
|
92
82
|
observing_: IObservable[] = [] // nodes we are looking at. Our value depends on these nodes
|
|
93
83
|
newObserving_ = null // during tracking it's an array with new observed observers
|
|
94
84
|
observers_ = new Set<IDerivation>()
|
|
95
|
-
diffValue_ = 0
|
|
96
85
|
runId_ = 0
|
|
97
86
|
lastAccessedBy_ = 0
|
|
98
87
|
lowestObserverState_ = IDerivationState_.UP_TO_DATE_
|
|
@@ -101,11 +90,12 @@ export class ComputedValue<T> implements IObservable, IComputedValue<T>, IDeriva
|
|
|
101
90
|
name_: string
|
|
102
91
|
triggeredBy_?: string
|
|
103
92
|
|
|
104
|
-
private static readonly isComputingMask_ =
|
|
105
|
-
private static readonly isRunningSetterMask_ =
|
|
106
|
-
private static readonly isBeingObservedMask_ =
|
|
107
|
-
private static readonly isPendingUnobservationMask_ =
|
|
108
|
-
private
|
|
93
|
+
private static readonly isComputingMask_ = 0b00001
|
|
94
|
+
private static readonly isRunningSetterMask_ = 0b00010
|
|
95
|
+
private static readonly isBeingObservedMask_ = 0b00100
|
|
96
|
+
private static readonly isPendingUnobservationMask_ = 0b01000
|
|
97
|
+
private static readonly diffValueMask_ = 0b10000
|
|
98
|
+
private flags_ = 0b00000
|
|
109
99
|
|
|
110
100
|
derivation: () => T // N.B: unminified as it is used by MST
|
|
111
101
|
setter_?: (value: T) => void
|
|
@@ -197,6 +187,17 @@ export class ComputedValue<T> implements IObservable, IComputedValue<T>, IDeriva
|
|
|
197
187
|
this.flags_ = setFlag(this.flags_, ComputedValue.isPendingUnobservationMask_, newValue)
|
|
198
188
|
}
|
|
199
189
|
|
|
190
|
+
get diffValue(): 0 | 1 {
|
|
191
|
+
return getFlag(this.flags_, ComputedValue.diffValueMask_) ? 1 : 0
|
|
192
|
+
}
|
|
193
|
+
set diffValue(newValue: 0 | 1) {
|
|
194
|
+
this.flags_ = setFlag(
|
|
195
|
+
this.flags_,
|
|
196
|
+
ComputedValue.diffValueMask_,
|
|
197
|
+
newValue === 1 ? true : false
|
|
198
|
+
)
|
|
199
|
+
}
|
|
200
|
+
|
|
200
201
|
/**
|
|
201
202
|
* Returns the current value of this computed value.
|
|
202
203
|
* Will evaluate its computation first if needed.
|
package/src/core/derivation.ts
CHANGED
|
@@ -235,8 +235,8 @@ function bindDependencies(derivation: IDerivation) {
|
|
|
235
235
|
l = derivation.unboundDepsCount_
|
|
236
236
|
for (let i = 0; i < l; i++) {
|
|
237
237
|
const dep = observing[i]
|
|
238
|
-
if (dep.
|
|
239
|
-
dep.
|
|
238
|
+
if (dep.diffValue === 0) {
|
|
239
|
+
dep.diffValue = 1
|
|
240
240
|
if (i0 !== i) {
|
|
241
241
|
observing[i0] = dep
|
|
242
242
|
}
|
|
@@ -259,10 +259,10 @@ function bindDependencies(derivation: IDerivation) {
|
|
|
259
259
|
l = prevObserving.length
|
|
260
260
|
while (l--) {
|
|
261
261
|
const dep = prevObserving[l]
|
|
262
|
-
if (dep.
|
|
262
|
+
if (dep.diffValue === 0) {
|
|
263
263
|
removeObserver(dep, derivation)
|
|
264
264
|
}
|
|
265
|
-
dep.
|
|
265
|
+
dep.diffValue = 0
|
|
266
266
|
}
|
|
267
267
|
|
|
268
268
|
// Go through all new observables and check diffValue: (now it should be unique)
|
|
@@ -270,8 +270,8 @@ function bindDependencies(derivation: IDerivation) {
|
|
|
270
270
|
// 1: it wasn't observed, let's observe it. set back to 0
|
|
271
271
|
while (i0--) {
|
|
272
272
|
const dep = observing[i0]
|
|
273
|
-
if (dep.
|
|
274
|
-
dep.
|
|
273
|
+
if (dep.diffValue === 1) {
|
|
274
|
+
dep.diffValue = 0
|
|
275
275
|
addObserver(dep, derivation)
|
|
276
276
|
}
|
|
277
277
|
}
|
package/src/core/observable.ts
CHANGED
|
@@ -17,7 +17,7 @@ export interface IDepTreeNode {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export interface IObservable extends IDepTreeNode {
|
|
20
|
-
|
|
20
|
+
diffValue: number
|
|
21
21
|
/**
|
|
22
22
|
* Id of the derivation *run* that last accessed this observable.
|
|
23
23
|
* If this id equals the *run* id of the current derivation,
|
package/src/core/reaction.ts
CHANGED
|
@@ -22,6 +22,8 @@ import {
|
|
|
22
22
|
GenericAbortSignal
|
|
23
23
|
} from "../internal"
|
|
24
24
|
|
|
25
|
+
import { getFlag, setFlag } from "../utils/utils"
|
|
26
|
+
|
|
25
27
|
/**
|
|
26
28
|
* Reactions are a special kind of derivations. Several things distinguishes them from normal reactive computations
|
|
27
29
|
*
|
|
@@ -55,13 +57,16 @@ export class Reaction implements IDerivation, IReactionPublic {
|
|
|
55
57
|
observing_: IObservable[] = [] // nodes we are looking at. Our value depends on these nodes
|
|
56
58
|
newObserving_: IObservable[] = []
|
|
57
59
|
dependenciesState_ = IDerivationState_.NOT_TRACKING_
|
|
58
|
-
diffValue_ = 0
|
|
59
60
|
runId_ = 0
|
|
60
61
|
unboundDepsCount_ = 0
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
|
|
63
|
+
private static readonly isDisposedMask_ = 0b00001
|
|
64
|
+
private static readonly isScheduledMask_ = 0b00010
|
|
65
|
+
private static readonly isTrackPendingMask_ = 0b00100
|
|
66
|
+
private static readonly isRunningMask_ = 0b01000
|
|
67
|
+
private static readonly diffValueMask_ = 0b10000
|
|
68
|
+
private flags_ = 0b00000
|
|
69
|
+
|
|
65
70
|
isTracing_: TraceMode = TraceMode.NONE
|
|
66
71
|
|
|
67
72
|
constructor(
|
|
@@ -71,37 +76,68 @@ export class Reaction implements IDerivation, IReactionPublic {
|
|
|
71
76
|
public requiresObservable_?
|
|
72
77
|
) {}
|
|
73
78
|
|
|
79
|
+
get isDisposed() {
|
|
80
|
+
return getFlag(this.flags_, Reaction.isDisposedMask_)
|
|
81
|
+
}
|
|
82
|
+
set isDisposed(newValue: boolean) {
|
|
83
|
+
this.flags_ = setFlag(this.flags_, Reaction.isDisposedMask_, newValue)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
get isScheduled() {
|
|
87
|
+
return getFlag(this.flags_, Reaction.isScheduledMask_)
|
|
88
|
+
}
|
|
89
|
+
set isScheduled(newValue: boolean) {
|
|
90
|
+
this.flags_ = setFlag(this.flags_, Reaction.isScheduledMask_, newValue)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
get isTrackPending() {
|
|
94
|
+
return getFlag(this.flags_, Reaction.isTrackPendingMask_)
|
|
95
|
+
}
|
|
96
|
+
set isTrackPending(newValue: boolean) {
|
|
97
|
+
this.flags_ = setFlag(this.flags_, Reaction.isTrackPendingMask_, newValue)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
get isRunning() {
|
|
101
|
+
return getFlag(this.flags_, Reaction.isRunningMask_)
|
|
102
|
+
}
|
|
103
|
+
set isRunning(newValue: boolean) {
|
|
104
|
+
this.flags_ = setFlag(this.flags_, Reaction.isRunningMask_, newValue)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
get diffValue(): 0 | 1 {
|
|
108
|
+
return getFlag(this.flags_, Reaction.diffValueMask_) ? 1 : 0
|
|
109
|
+
}
|
|
110
|
+
set diffValue(newValue: 0 | 1) {
|
|
111
|
+
this.flags_ = setFlag(this.flags_, Reaction.diffValueMask_, newValue === 1 ? true : false)
|
|
112
|
+
}
|
|
113
|
+
|
|
74
114
|
onBecomeStale_() {
|
|
75
115
|
this.schedule_()
|
|
76
116
|
}
|
|
77
117
|
|
|
78
118
|
schedule_() {
|
|
79
|
-
if (!this.
|
|
80
|
-
this.
|
|
119
|
+
if (!this.isScheduled) {
|
|
120
|
+
this.isScheduled = true
|
|
81
121
|
globalState.pendingReactions.push(this)
|
|
82
122
|
runReactions()
|
|
83
123
|
}
|
|
84
124
|
}
|
|
85
125
|
|
|
86
|
-
isScheduled() {
|
|
87
|
-
return this.isScheduled_
|
|
88
|
-
}
|
|
89
|
-
|
|
90
126
|
/**
|
|
91
127
|
* internal, use schedule() if you intend to kick off a reaction
|
|
92
128
|
*/
|
|
93
129
|
runReaction_() {
|
|
94
|
-
if (!this.
|
|
130
|
+
if (!this.isDisposed) {
|
|
95
131
|
startBatch()
|
|
96
|
-
this.
|
|
132
|
+
this.isScheduled = false
|
|
97
133
|
const prev = globalState.trackingContext
|
|
98
134
|
globalState.trackingContext = this
|
|
99
135
|
if (shouldCompute(this)) {
|
|
100
|
-
this.
|
|
136
|
+
this.isTrackPending = true
|
|
101
137
|
|
|
102
138
|
try {
|
|
103
139
|
this.onInvalidate_()
|
|
104
|
-
if (__DEV__ && this.
|
|
140
|
+
if (__DEV__ && this.isTrackPending && isSpyEnabled()) {
|
|
105
141
|
// onInvalidate didn't trigger track right away..
|
|
106
142
|
spyReport({
|
|
107
143
|
name: this.name_,
|
|
@@ -118,7 +154,7 @@ export class Reaction implements IDerivation, IReactionPublic {
|
|
|
118
154
|
}
|
|
119
155
|
|
|
120
156
|
track(fn: () => void) {
|
|
121
|
-
if (this.
|
|
157
|
+
if (this.isDisposed) {
|
|
122
158
|
return
|
|
123
159
|
// console.warn("Reaction already disposed") // Note: Not a warning / error in mobx 4 either
|
|
124
160
|
}
|
|
@@ -132,14 +168,14 @@ export class Reaction implements IDerivation, IReactionPublic {
|
|
|
132
168
|
type: "reaction"
|
|
133
169
|
})
|
|
134
170
|
}
|
|
135
|
-
this.
|
|
171
|
+
this.isRunning = true
|
|
136
172
|
const prevReaction = globalState.trackingContext // reactions could create reactions...
|
|
137
173
|
globalState.trackingContext = this
|
|
138
174
|
const result = trackDerivedFunction(this, fn, undefined)
|
|
139
175
|
globalState.trackingContext = prevReaction
|
|
140
|
-
this.
|
|
141
|
-
this.
|
|
142
|
-
if (this.
|
|
176
|
+
this.isRunning = false
|
|
177
|
+
this.isTrackPending = false
|
|
178
|
+
if (this.isDisposed) {
|
|
143
179
|
// disposed during last run. Clean up everything that was bound after the dispose call.
|
|
144
180
|
clearObserving(this)
|
|
145
181
|
}
|
|
@@ -185,9 +221,9 @@ export class Reaction implements IDerivation, IReactionPublic {
|
|
|
185
221
|
}
|
|
186
222
|
|
|
187
223
|
dispose() {
|
|
188
|
-
if (!this.
|
|
189
|
-
this.
|
|
190
|
-
if (!this.
|
|
224
|
+
if (!this.isDisposed) {
|
|
225
|
+
this.isDisposed = true
|
|
226
|
+
if (!this.isRunning) {
|
|
191
227
|
// if disposed while running, clean up later. Maybe not optimal, but rare case
|
|
192
228
|
startBatch()
|
|
193
229
|
clearObserving(this)
|
|
@@ -244,7 +244,7 @@ export class ObservableSet<T = any> implements Set<T>, IInterceptable<ISetWillCh
|
|
|
244
244
|
}
|
|
245
245
|
|
|
246
246
|
intersection<U>(otherSet: ReadonlySetLike<U> | Set<U>): Set<T & U> {
|
|
247
|
-
if (isES6Set(otherSet)) {
|
|
247
|
+
if (isES6Set(otherSet) && !isObservableSet(otherSet)) {
|
|
248
248
|
return otherSet.intersection(this)
|
|
249
249
|
} else {
|
|
250
250
|
const dehancedSet = new Set(this)
|
|
@@ -253,7 +253,7 @@ export class ObservableSet<T = any> implements Set<T>, IInterceptable<ISetWillCh
|
|
|
253
253
|
}
|
|
254
254
|
|
|
255
255
|
union<U>(otherSet: ReadonlySetLike<U> | Set<U>): Set<T | U> {
|
|
256
|
-
if (isES6Set(otherSet)) {
|
|
256
|
+
if (isES6Set(otherSet) && !isObservableSet(otherSet)) {
|
|
257
257
|
return otherSet.union(this)
|
|
258
258
|
} else {
|
|
259
259
|
const dehancedSet = new Set(this)
|
|
@@ -266,7 +266,7 @@ export class ObservableSet<T = any> implements Set<T>, IInterceptable<ISetWillCh
|
|
|
266
266
|
}
|
|
267
267
|
|
|
268
268
|
symmetricDifference<U>(otherSet: ReadonlySetLike<U> | Set<U>): Set<T | U> {
|
|
269
|
-
if (isES6Set(otherSet)) {
|
|
269
|
+
if (isES6Set(otherSet) && !isObservableSet(otherSet)) {
|
|
270
270
|
return otherSet.symmetricDifference(this)
|
|
271
271
|
} else {
|
|
272
272
|
const dehancedSet = new Set(this)
|
|
@@ -283,7 +283,7 @@ export class ObservableSet<T = any> implements Set<T>, IInterceptable<ISetWillCh
|
|
|
283
283
|
}
|
|
284
284
|
|
|
285
285
|
isDisjointFrom(otherSet: ReadonlySetLike<unknown> | Set<unknown>): boolean {
|
|
286
|
-
if (isES6Set(otherSet)) {
|
|
286
|
+
if (isES6Set(otherSet) && !isObservableSet(otherSet)) {
|
|
287
287
|
return otherSet.isDisjointFrom(this)
|
|
288
288
|
} else {
|
|
289
289
|
const dehancedSet = new Set(this)
|
package/src/utils/utils.ts
CHANGED
|
@@ -140,18 +140,27 @@ export function createInstanceofPredicate<T>(
|
|
|
140
140
|
} as any
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
-
|
|
143
|
+
/**
|
|
144
|
+
* Yields true for both native and observable Map, even across different windows.
|
|
145
|
+
*/
|
|
146
|
+
export function isES6Map(thing: unknown): thing is Map<any, any> {
|
|
144
147
|
return thing != null && Object.prototype.toString.call(thing) === "[object Map]"
|
|
145
148
|
}
|
|
146
149
|
|
|
147
|
-
|
|
150
|
+
/**
|
|
151
|
+
* Makes sure a Map is an instance of non-inherited native or observable Map.
|
|
152
|
+
*/
|
|
153
|
+
export function isPlainES6Map(thing: Map<unknown, unknown>): boolean {
|
|
148
154
|
const mapProto = Object.getPrototypeOf(thing)
|
|
149
155
|
const objectProto = Object.getPrototypeOf(mapProto)
|
|
150
156
|
const nullProto = Object.getPrototypeOf(objectProto)
|
|
151
157
|
return nullProto === null
|
|
152
158
|
}
|
|
153
159
|
|
|
154
|
-
|
|
160
|
+
/**
|
|
161
|
+
* Yields true for both native and observable Set, even across different windows.
|
|
162
|
+
*/
|
|
163
|
+
export function isES6Set(thing: unknown): thing is Set<any> {
|
|
155
164
|
return thing != null && Object.prototype.toString.call(thing) === "[object Set]"
|
|
156
165
|
}
|
|
157
166
|
|
|
@@ -212,3 +221,16 @@ export const getOwnPropertyDescriptors =
|
|
|
212
221
|
})
|
|
213
222
|
return res
|
|
214
223
|
}
|
|
224
|
+
|
|
225
|
+
export function getFlag(flags: number, mask: number) {
|
|
226
|
+
return !!(flags & mask)
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export function setFlag(flags: number, mask: number, newValue: boolean): number {
|
|
230
|
+
if (newValue) {
|
|
231
|
+
flags |= mask
|
|
232
|
+
} else {
|
|
233
|
+
flags &= ~mask
|
|
234
|
+
}
|
|
235
|
+
return flags
|
|
236
|
+
}
|