refactor: Improve identifiers in pointer.ts + use Map over object (#134)
Co-authored-by: Elliot <key.draw@gmail.com>
This commit is contained in:
parent
d6353aeb0b
commit
909ffccafb
1 changed files with 25 additions and 19 deletions
|
@ -7,6 +7,9 @@ type PointerMeta = {
|
||||||
path: (string | number)[]
|
path: (string | number)[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** We are using an empty object as a WeakMap key for storing pointer meta data */
|
||||||
|
type WeakPointerKey = {}
|
||||||
|
|
||||||
export type UnindexableTypesForPointer =
|
export type UnindexableTypesForPointer =
|
||||||
| number
|
| number
|
||||||
| string
|
| string
|
||||||
|
@ -20,7 +23,11 @@ export type UnindexablePointer = {
|
||||||
[K in $IntentionalAny]: Pointer<undefined>
|
[K in $IntentionalAny]: Pointer<undefined>
|
||||||
}
|
}
|
||||||
|
|
||||||
const pointerMetaWeakMap = new WeakMap<{}, PointerMeta>()
|
const pointerMetaWeakMap = new WeakMap<WeakPointerKey, PointerMeta>()
|
||||||
|
const cachedSubPathPointersWeakMap = new WeakMap<
|
||||||
|
WeakPointerKey,
|
||||||
|
Map<string | number, Pointer<unknown>>
|
||||||
|
>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A wrapper type for the type a `Pointer` points to.
|
* A wrapper type for the type a `Pointer` points to.
|
||||||
|
@ -64,27 +71,26 @@ export type Pointer<O> = PointerType<O> &
|
||||||
|
|
||||||
const pointerMetaSymbol = Symbol('pointerMeta')
|
const pointerMetaSymbol = Symbol('pointerMeta')
|
||||||
|
|
||||||
const cachedSubPointersWeakMap = new WeakMap<
|
const proxyHandler = {
|
||||||
{},
|
get(
|
||||||
Record<string | number, Pointer<unknown>>
|
pointerKey: WeakPointerKey,
|
||||||
>()
|
prop: string | typeof pointerMetaSymbol,
|
||||||
|
): $IntentionalAny {
|
||||||
|
if (prop === pointerMetaSymbol) return pointerMetaWeakMap.get(pointerKey)!
|
||||||
|
|
||||||
const handler = {
|
let subPathPointers = cachedSubPathPointersWeakMap.get(pointerKey)
|
||||||
get(obj: {}, prop: string | typeof pointerMetaSymbol): $IntentionalAny {
|
if (!subPathPointers) {
|
||||||
if (prop === pointerMetaSymbol) return pointerMetaWeakMap.get(obj)!
|
subPathPointers = new Map()
|
||||||
|
cachedSubPathPointersWeakMap.set(pointerKey, subPathPointers)
|
||||||
let subs = cachedSubPointersWeakMap.get(obj)
|
|
||||||
if (!subs) {
|
|
||||||
subs = {}
|
|
||||||
cachedSubPointersWeakMap.set(obj, subs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subs[prop]) return subs[prop]
|
const existing = subPathPointers.get(prop)
|
||||||
|
if (existing !== undefined) return existing
|
||||||
|
|
||||||
const meta = pointerMetaWeakMap.get(obj)!
|
const meta = pointerMetaWeakMap.get(pointerKey)!
|
||||||
|
|
||||||
const subPointer = pointer({root: meta.root, path: [...meta.path, prop]})
|
const subPointer = pointer({root: meta.root, path: [...meta.path, prop]})
|
||||||
subs[prop] = subPointer
|
subPathPointers.set(prop, subPointer)
|
||||||
return subPointer
|
return subPointer
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -158,9 +164,9 @@ function pointer<O>(args: {root: {}; path?: Array<string | number>}) {
|
||||||
root: args.root as $IntentionalAny,
|
root: args.root as $IntentionalAny,
|
||||||
path: args.path ?? [],
|
path: args.path ?? [],
|
||||||
}
|
}
|
||||||
const hiddenObj = {}
|
const pointerKey: WeakPointerKey = {}
|
||||||
pointerMetaWeakMap.set(hiddenObj, meta)
|
pointerMetaWeakMap.set(pointerKey, meta)
|
||||||
return new Proxy(hiddenObj, handler) as Pointer<O>
|
return new Proxy(pointerKey, proxyHandler) as Pointer<O>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default pointer
|
export default pointer
|
||||||
|
|
Loading…
Reference in a new issue