feat(metro+utils): init lazyfication
This commit is contained in:
parent
1ffe8e5189
commit
ee6669f514
2 changed files with 51 additions and 0 deletions
40
src/lib/utils/lazy.ts
Normal file
40
src/lib/utils/lazy.ts
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
const factorySymbol = Symbol.for("bunny.lazyFactory");
|
||||
const cacheSymbol = Symbol("bunny.lazyCache");
|
||||
const dummySymbol = Symbol("bunny.lazyDummy");
|
||||
|
||||
const unconfigurable = ["arguments", "caller", "prototype"];
|
||||
const isUnconfigurable = (key: PropertyKey) => typeof key === "string" && unconfigurable.includes(key);
|
||||
|
||||
const lazyHandler: ProxyHandler<any> = {
|
||||
...Object.fromEntries(Object.getOwnPropertyNames(Reflect).map(fnName => {
|
||||
return [fnName, (target: any, ...args: any[]) => {
|
||||
// @ts-ignore
|
||||
const func = s => Reflect[fnName](s, ...args);
|
||||
return func(target[factorySymbol]()) ?? func(target[dummySymbol]);
|
||||
}];
|
||||
})),
|
||||
ownKeys: target => {
|
||||
const cacheKeys = Reflect.ownKeys(target[factorySymbol]() ?? target[dummySymbol]);
|
||||
unconfigurable.forEach(key => isUnconfigurable(key) && cacheKeys.push(key));
|
||||
return cacheKeys;
|
||||
},
|
||||
getOwnPropertyDescriptor: (target, p) => {
|
||||
if (isUnconfigurable(p)) return Reflect.getOwnPropertyDescriptor(target, p);
|
||||
|
||||
const descriptor = Reflect.getOwnPropertyDescriptor(target[factorySymbol]() ?? target[dummySymbol], p);
|
||||
if (descriptor) Object.defineProperty(target, p, descriptor);
|
||||
return descriptor;
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Lazy proxy that will only call the factory function when needed (when a property is accessed)
|
||||
* @param factory Factory function to create the object
|
||||
* @returns A proxy that will call the factory function only when needed
|
||||
*/
|
||||
export function proxyLazy<T>(factory: () => T, dummy: any = () => void 0): T {
|
||||
dummy[factorySymbol] = () => dummy[cacheSymbol] ??= factory();
|
||||
dummy[dummySymbol] = dummy;
|
||||
|
||||
return new Proxy(dummy, lazyHandler) as any;
|
||||
}
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
import { proxyLazy } from "@lib/utils/lazy";
|
||||
|
||||
import { byDisplayName, byFilePath, byName, byProps, byStoreName, byTypeName } from "./filters";
|
||||
import { findAllExports, findExports } from "./finders";
|
||||
import { FilterCheckDef, FilterDefinition, ModuleExports } from "./types";
|
||||
|
|
@ -41,16 +43,25 @@ export function createSimpleFilter(
|
|||
}
|
||||
|
||||
export const findByProps = (...props: string[]) => findExports(byProps(...props));
|
||||
export const findByPropsLazy = (...props: string[]) => proxyLazy(() => findByProps(...props));
|
||||
export const findByPropsAll = (...props: string[]) => findAllExports(byProps(...props));
|
||||
|
||||
export const findByName = (name: string, expDefault = true) => findExports(expDefault ? byName(name) : byName.byDefault(name));
|
||||
export const findByNameLazy = (name: string, expDefault = true) => proxyLazy(() => findByName(name, expDefault));
|
||||
export const findByNameAll = (name: string, expDefault = true) => findAllExports(expDefault ? byName(name) : byName.byDefault(name));
|
||||
|
||||
export const findByDisplayName = (name: string, expDefault = true) => findExports(expDefault ? byDisplayName(name) : byDisplayName.byDefault(name));
|
||||
export const findByDisplayNameLazy = (name: string, expDefault = true) => proxyLazy(() => findByDisplayName(name, expDefault));
|
||||
export const findByDisplayNameAll = (name: string, expDefault = true) => findAllExports(expDefault ? byDisplayName(name) : byDisplayName.byDefault(name));
|
||||
|
||||
export const findByTypeName = (name: string, expDefault = true) => findExports(expDefault ? byTypeName(name) : byTypeName.byDefault(name));
|
||||
export const findByTypeNameLazy = (name: string, expDefault = true) => proxyLazy(() => findByTypeName(name, expDefault));
|
||||
export const findByTypeNameAll = (name: string, expDefault = true) => findAllExports(expDefault ? byTypeName(name) : byTypeName.byDefault(name));
|
||||
|
||||
export const findByStoreName = (name: string) => findExports(byStoreName(name));
|
||||
export const findByStoreNameLazy = (name: string) => proxyLazy(() => findByStoreName(name));
|
||||
|
||||
export const findByFilePath = (path: string) => findExports(byFilePath(path));
|
||||
export const findByFilePathLazy = (path: string) => proxyLazy(() => findByFilePath(path));
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue