|
@@ -22,13 +22,15 @@ const toReactive = <T extends unknown>(value: T): T =>
|
|
|
const toReadonly = <T extends unknown>(value: T): T =>
|
|
const toReadonly = <T extends unknown>(value: T): T =>
|
|
|
isObject(value) ? readonly(value) : value
|
|
isObject(value) ? readonly(value) : value
|
|
|
|
|
|
|
|
|
|
+const toShallow = <T extends unknown>(value: T): T => value
|
|
|
|
|
+
|
|
|
const getProto = <T extends CollectionTypes>(v: T): any =>
|
|
const getProto = <T extends CollectionTypes>(v: T): any =>
|
|
|
Reflect.getPrototypeOf(v)
|
|
Reflect.getPrototypeOf(v)
|
|
|
|
|
|
|
|
function get(
|
|
function get(
|
|
|
target: MapTypes,
|
|
target: MapTypes,
|
|
|
key: unknown,
|
|
key: unknown,
|
|
|
- wrap: typeof toReactive | typeof toReadonly
|
|
|
|
|
|
|
+ wrap: typeof toReactive | typeof toReadonly | typeof toShallow
|
|
|
) {
|
|
) {
|
|
|
target = toRaw(target)
|
|
target = toRaw(target)
|
|
|
const rawKey = toRaw(key)
|
|
const rawKey = toRaw(key)
|
|
@@ -132,7 +134,7 @@ function clear(this: IterableCollections) {
|
|
|
return result
|
|
return result
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-function createForEach(isReadonly: boolean) {
|
|
|
|
|
|
|
+function createForEach(isReadonly: boolean, shallow: boolean) {
|
|
|
return function forEach(
|
|
return function forEach(
|
|
|
this: IterableCollections,
|
|
this: IterableCollections,
|
|
|
callback: Function,
|
|
callback: Function,
|
|
@@ -140,7 +142,7 @@ function createForEach(isReadonly: boolean) {
|
|
|
) {
|
|
) {
|
|
|
const observed = this
|
|
const observed = this
|
|
|
const target = toRaw(observed)
|
|
const target = toRaw(observed)
|
|
|
- const wrap = isReadonly ? toReadonly : toReactive
|
|
|
|
|
|
|
+ const wrap = isReadonly ? toReadonly : shallow ? toShallow : toReactive
|
|
|
!isReadonly && track(target, TrackOpTypes.ITERATE, ITERATE_KEY)
|
|
!isReadonly && track(target, TrackOpTypes.ITERATE, ITERATE_KEY)
|
|
|
// important: create sure the callback is
|
|
// important: create sure the callback is
|
|
|
// 1. invoked with the reactive map as `this` and 3rd arg
|
|
// 1. invoked with the reactive map as `this` and 3rd arg
|
|
@@ -152,14 +154,18 @@ function createForEach(isReadonly: boolean) {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-function createIterableMethod(method: string | symbol, isReadonly: boolean) {
|
|
|
|
|
|
|
+function createIterableMethod(
|
|
|
|
|
+ method: string | symbol,
|
|
|
|
|
+ isReadonly: boolean,
|
|
|
|
|
+ shallow: boolean
|
|
|
|
|
+) {
|
|
|
return function(this: IterableCollections, ...args: unknown[]) {
|
|
return function(this: IterableCollections, ...args: unknown[]) {
|
|
|
const target = toRaw(this)
|
|
const target = toRaw(this)
|
|
|
const isMap = target instanceof Map
|
|
const isMap = target instanceof Map
|
|
|
const isPair = method === 'entries' || (method === Symbol.iterator && isMap)
|
|
const isPair = method === 'entries' || (method === Symbol.iterator && isMap)
|
|
|
const isKeyOnly = method === 'keys' && isMap
|
|
const isKeyOnly = method === 'keys' && isMap
|
|
|
const innerIterator = getProto(target)[method].apply(target, args)
|
|
const innerIterator = getProto(target)[method].apply(target, args)
|
|
|
- const wrap = isReadonly ? toReadonly : toReactive
|
|
|
|
|
|
|
+ const wrap = isReadonly ? toReadonly : shallow ? toShallow : toReactive
|
|
|
!isReadonly &&
|
|
!isReadonly &&
|
|
|
track(
|
|
track(
|
|
|
target,
|
|
target,
|
|
@@ -212,7 +218,22 @@ const mutableInstrumentations: Record<string, Function> = {
|
|
|
set,
|
|
set,
|
|
|
delete: deleteEntry,
|
|
delete: deleteEntry,
|
|
|
clear,
|
|
clear,
|
|
|
- forEach: createForEach(false)
|
|
|
|
|
|
|
+ forEach: createForEach(false, false)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const shallowInstrumentations: Record<string, Function> = {
|
|
|
|
|
+ get(this: MapTypes, key: unknown) {
|
|
|
|
|
+ return get(this, key, toShallow)
|
|
|
|
|
+ },
|
|
|
|
|
+ get size() {
|
|
|
|
|
+ return size((this as unknown) as IterableCollections)
|
|
|
|
|
+ },
|
|
|
|
|
+ has,
|
|
|
|
|
+ add,
|
|
|
|
|
+ set,
|
|
|
|
|
+ delete: deleteEntry,
|
|
|
|
|
+ clear,
|
|
|
|
|
+ forEach: createForEach(false, true)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const readonlyInstrumentations: Record<string, Function> = {
|
|
const readonlyInstrumentations: Record<string, Function> = {
|
|
@@ -227,25 +248,34 @@ const readonlyInstrumentations: Record<string, Function> = {
|
|
|
set: createReadonlyMethod(TriggerOpTypes.SET),
|
|
set: createReadonlyMethod(TriggerOpTypes.SET),
|
|
|
delete: createReadonlyMethod(TriggerOpTypes.DELETE),
|
|
delete: createReadonlyMethod(TriggerOpTypes.DELETE),
|
|
|
clear: createReadonlyMethod(TriggerOpTypes.CLEAR),
|
|
clear: createReadonlyMethod(TriggerOpTypes.CLEAR),
|
|
|
- forEach: createForEach(true)
|
|
|
|
|
|
|
+ forEach: createForEach(true, false)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator]
|
|
const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator]
|
|
|
iteratorMethods.forEach(method => {
|
|
iteratorMethods.forEach(method => {
|
|
|
mutableInstrumentations[method as string] = createIterableMethod(
|
|
mutableInstrumentations[method as string] = createIterableMethod(
|
|
|
method,
|
|
method,
|
|
|
|
|
+ false,
|
|
|
false
|
|
false
|
|
|
)
|
|
)
|
|
|
readonlyInstrumentations[method as string] = createIterableMethod(
|
|
readonlyInstrumentations[method as string] = createIterableMethod(
|
|
|
method,
|
|
method,
|
|
|
|
|
+ true,
|
|
|
|
|
+ false
|
|
|
|
|
+ )
|
|
|
|
|
+ shallowInstrumentations[method as string] = createIterableMethod(
|
|
|
|
|
+ method,
|
|
|
|
|
+ true,
|
|
|
true
|
|
true
|
|
|
)
|
|
)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
-function createInstrumentationGetter(isReadonly: boolean) {
|
|
|
|
|
- const instrumentations = isReadonly
|
|
|
|
|
- ? readonlyInstrumentations
|
|
|
|
|
- : mutableInstrumentations
|
|
|
|
|
|
|
+function createInstrumentationGetter(isReadonly: boolean, shallow: boolean) {
|
|
|
|
|
+ const instrumentations = shallow
|
|
|
|
|
+ ? shallowInstrumentations
|
|
|
|
|
+ : isReadonly
|
|
|
|
|
+ ? readonlyInstrumentations
|
|
|
|
|
+ : mutableInstrumentations
|
|
|
|
|
|
|
|
return (
|
|
return (
|
|
|
target: CollectionTypes,
|
|
target: CollectionTypes,
|
|
@@ -271,11 +301,15 @@ function createInstrumentationGetter(isReadonly: boolean) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
export const mutableCollectionHandlers: ProxyHandler<CollectionTypes> = {
|
|
export const mutableCollectionHandlers: ProxyHandler<CollectionTypes> = {
|
|
|
- get: createInstrumentationGetter(false)
|
|
|
|
|
|
|
+ get: createInstrumentationGetter(false, false)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export const shallowCollectionHandlers: ProxyHandler<CollectionTypes> = {
|
|
|
|
|
+ get: createInstrumentationGetter(false, true)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
export const readonlyCollectionHandlers: ProxyHandler<CollectionTypes> = {
|
|
export const readonlyCollectionHandlers: ProxyHandler<CollectionTypes> = {
|
|
|
- get: createInstrumentationGetter(true)
|
|
|
|
|
|
|
+ get: createInstrumentationGetter(true, false)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function checkIdentityKeys(
|
|
function checkIdentityKeys(
|