declare const CSSINJS_STATISTIC: any; const enableStatistic = process.env.NODE_ENV !== 'production' || typeof CSSINJS_STATISTIC !== 'undefined'; let recording = true; /** * This function will do as `Object.assign` in production. But will use Object.defineProperty:get to * pass all value access in development. To support statistic field usage with alias token. */ export function merge(...objs: Partial[]): T { /* istanbul ignore next */ if (!enableStatistic) { return Object.assign({}, ...objs); } recording = false; const ret = {} as T; objs.forEach((obj) => { const keys = Object.keys(obj); keys.forEach((key) => { Object.defineProperty(ret, key, { configurable: true, enumerable: true, get: () => (obj as any)[key], }); }); }); recording = true; return ret; } /** @internal Internal Usage. Not use in your production. */ export const statistic: Record< string, { global: string[]; component: Record } > = {}; /** @internal Internal Usage. Not use in your production. */ // eslint-disable-next-line camelcase export const _statistic_build_: typeof statistic = {}; /* istanbul ignore next */ function noop() {} /** Statistic token usage case. Should use `merge` function if you do not want spread record. */ export default function statisticToken(token: T) { let tokenKeys: Set | undefined; let proxy = token; let flush: (componentName: string, componentToken: Record) => void = noop; if (enableStatistic) { tokenKeys = new Set(); proxy = new Proxy(token, { get(obj: any, prop: any) { if (recording) { tokenKeys!.add(prop); } return obj[prop]; }, }); flush = (componentName, componentToken) => { statistic[componentName] = { global: Array.from(tokenKeys!), component: { ...statistic[componentName]?.component, ...componentToken, }, }; }; } return { token: proxy, keys: tokenKeys, flush }; }