@v4fire/client
Version:
V4Fire client core library
63 lines (50 loc) • 1.45 kB
text/typescript
/*!
* V4Fire Client Core
* https://github.com/V4Fire/Client
*
* Released under the MIT license
* https://github.com/V4Fire/Client/blob/master/LICENSE
*/
import { fakeCopyLabel } from 'core/component/watch';
const
toNonFakeObject = Symbol('Link to a non fake object');
/**
* Returns a "fake" copy of the specified (weak)map/(weak)set object
* @param obj
*/
export function fakeMapSetCopy<
T extends Map<unknown, unknown> | WeakMap<object, unknown> | Set<unknown> | WeakSet<object>
>(obj: T): T {
obj = obj[toNonFakeObject] ?? obj;
const
Constructor = obj.constructor,
proto = Constructor.prototype;
// @ts-ignore (constructor)
const wrap = new Constructor();
for (let keys = Object.getOwnPropertyNames(proto), i = 0; i < keys.length; i++) {
const
key = keys[i],
desc = Object.getOwnPropertyDescriptor(proto, key);
if (!desc) {
continue;
}
if (Object.isFunction(desc.value)) {
Object.defineProperty(wrap, key, {
...desc,
value: obj[key].bind(obj)
});
// eslint-disable-next-line @typescript-eslint/unbound-method
} else if (Object.isFunction(desc.get)) {
Object.defineProperty(wrap, key, {
...desc,
get: () => obj[key],
set: desc.set && ((v) => obj[key] = v)
});
}
}
wrap[Symbol.iterator] = obj[Symbol.iterator]?.bind(obj);
wrap[Symbol.asyncIterator] = obj[Symbol.asyncIterator]?.bind(obj);
wrap[toNonFakeObject] = obj;
wrap[fakeCopyLabel] = true;
return wrap;
}