{"version":3,"file":"utils.cjs","sources":["../../src/utils.ts"],"sourcesContent":["export type NoInfer<A extends any> = [A][A extends any ? 0 : never]\n\nexport type PartialKeys<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>\n\nexport function memo<TDeps extends ReadonlyArray<any>, TResult>(\n  getDeps: () => [...TDeps],\n  fn: (...args: NoInfer<[...TDeps]>) => TResult,\n  opts: {\n    key: false | string\n    debug?: () => boolean\n    onChange?: (result: TResult) => void\n    initialDeps?: TDeps\n    skipInitialOnChange?: boolean\n  },\n) {\n  let deps = opts.initialDeps ?? []\n  let result: TResult | undefined\n  let isInitial = true\n\n  function memoizedFunction(): TResult {\n    // Debug-only timing. In production builds, `process.env.NODE_ENV !==\n    // 'production'` is constant-folded to `false` by downstream minifiers\n    // (Terser/esbuild/swc with `define`), which DCEs the entire block.\n    const debugEnabled =\n      process.env.NODE_ENV !== 'production' && !!opts.key && !!opts.debug?.()\n    let depTime = 0\n    if (debugEnabled) depTime = Date.now()\n\n    const newDeps = getDeps()\n\n    const depsChanged =\n      newDeps.length !== deps.length ||\n      newDeps.some((dep: any, index: number) => deps[index] !== dep)\n\n    if (!depsChanged) {\n      return result!\n    }\n\n    deps = newDeps\n\n    let resultTime = 0\n    if (debugEnabled) resultTime = Date.now()\n\n    result = fn(...newDeps)\n\n    if (debugEnabled) {\n      const depEndTime = Math.round((Date.now() - depTime) * 100) / 100\n      const resultEndTime = Math.round((Date.now() - resultTime) * 100) / 100\n      const resultFpsPercentage = resultEndTime / 16\n\n      const pad = (str: number | string, num: number) => {\n        str = String(str)\n        while (str.length < num) {\n          str = ' ' + str\n        }\n        return str\n      }\n\n      console.info(\n        `%c⏱ ${pad(resultEndTime, 5)} /${pad(depEndTime, 5)} ms`,\n        `\n            font-size: .6rem;\n            font-weight: bold;\n            color: hsl(${Math.max(\n              0,\n              Math.min(120 - 120 * resultFpsPercentage, 120),\n            )}deg 100% 31%);`,\n        opts?.key,\n      )\n    }\n\n    if (opts?.onChange && !(isInitial && opts.skipInitialOnChange)) {\n      opts.onChange(result)\n    }\n\n    isInitial = false\n\n    return result\n  }\n\n  // Attach updateDeps to the function itself\n  memoizedFunction.updateDeps = (newDeps: [...TDeps]) => {\n    deps = newDeps\n  }\n\n  return memoizedFunction\n}\n\nexport function notUndefined<T>(value: T | undefined, msg?: string): T {\n  if (value === undefined) {\n    throw new Error(`Unexpected undefined${msg ? `: ${msg}` : ''}`)\n  } else {\n    return value\n  }\n}\n\nexport const approxEqual = (a: number, b: number) => Math.abs(a - b) < 1.01\n\nexport const debounce = (\n  targetWindow: Window & typeof globalThis,\n  fn: Function,\n  ms: number,\n) => {\n  let timeoutId: number\n  return function (this: any, ...args: Array<any>) {\n    targetWindow.clearTimeout(timeoutId)\n    timeoutId = targetWindow.setTimeout(() => fn.apply(this, args), ms)\n  }\n}\n"],"names":[],"mappings":";;AAIO,SAAS,KACd,SACA,IACA,MAOA;AACA,MAAI,OAAO,KAAK,eAAe,CAAA;AAC/B,MAAI;AACJ,MAAI,YAAY;AAEhB,WAAS,mBAA4B;;AAInC,UAAM,eACJ,QAAQ,IAAI,aAAa,gBAAgB,CAAC,CAAC,KAAK,OAAO,CAAC,GAAC,UAAK,UAAL;AAC3D,QAAI,UAAU;AACd,QAAI,aAAc,WAAU,KAAK,IAAA;AAEjC,UAAM,UAAU,QAAA;AAEhB,UAAM,cACJ,QAAQ,WAAW,KAAK,UACxB,QAAQ,KAAK,CAAC,KAAU,UAAkB,KAAK,KAAK,MAAM,GAAG;AAE/D,QAAI,CAAC,aAAa;AAChB,aAAO;AAAA,IACT;AAEA,WAAO;AAEP,QAAI,aAAa;AACjB,QAAI,aAAc,cAAa,KAAK,IAAA;AAEpC,aAAS,GAAG,GAAG,OAAO;AAEtB,QAAI,cAAc;AAChB,YAAM,aAAa,KAAK,OAAO,KAAK,QAAQ,WAAW,GAAG,IAAI;AAC9D,YAAM,gBAAgB,KAAK,OAAO,KAAK,QAAQ,cAAc,GAAG,IAAI;AACpE,YAAM,sBAAsB,gBAAgB;AAE5C,YAAM,MAAM,CAAC,KAAsB,QAAgB;AACjD,cAAM,OAAO,GAAG;AAChB,eAAO,IAAI,SAAS,KAAK;AACvB,gBAAM,MAAM;AAAA,QACd;AACA,eAAO;AAAA,MACT;AAEA,cAAQ;AAAA,QACN,OAAO,IAAI,eAAe,CAAC,CAAC,KAAK,IAAI,YAAY,CAAC,CAAC;AAAA,QACnD;AAAA;AAAA;AAAA,yBAGiB,KAAK;AAAA,UAChB;AAAA,UACA,KAAK,IAAI,MAAM,MAAM,qBAAqB,GAAG;AAAA,QAAA,CAC9C;AAAA,QACL,6BAAM;AAAA,MAAA;AAAA,IAEV;AAEA,SAAI,6BAAM,aAAY,EAAE,aAAa,KAAK,sBAAsB;AAC9D,WAAK,SAAS,MAAM;AAAA,IACtB;AAEA,gBAAY;AAEZ,WAAO;AAAA,EACT;AAGA,mBAAiB,aAAa,CAAC,YAAwB;AACrD,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEO,SAAS,aAAgB,OAAsB,KAAiB;AACrE,MAAI,UAAU,QAAW;AACvB,UAAM,IAAI,MAAM,uBAAuB,MAAM,KAAK,GAAG,KAAK,EAAE,EAAE;AAAA,EAChE,OAAO;AACL,WAAO;AAAA,EACT;AACF;AAEO,MAAM,cAAc,CAAC,GAAW,MAAc,KAAK,IAAI,IAAI,CAAC,IAAI;AAEhE,MAAM,WAAW,CACtB,cACA,IACA,OACG;AACH,MAAI;AACJ,SAAO,YAAwB,MAAkB;AAC/C,iBAAa,aAAa,SAAS;AACnC,gBAAY,aAAa,WAAW,MAAM,GAAG,MAAM,MAAM,IAAI,GAAG,EAAE;AAAA,EACpE;AACF;;;;;"}