{
  "version": 3,
  "sources": ["../../src/lib/throttle.ts"],
  "sourcesContent": ["const isTest = () =>\n\ttypeof process !== 'undefined' &&\n\tprocess.env.NODE_ENV === 'test' &&\n\t// @ts-expect-error\n\t!globalThis.__FORCE_RAF_IN_TESTS__\n\nconst fpsQueue: Array<() => void> = []\nconst targetFps = 60\nconst targetTimePerFrame = Math.ceil(1000 / targetFps)\nlet frame: number | undefined\nlet time = 0\nlet last = 0\n\nconst flush = () => {\n\tconst queue = fpsQueue.splice(0, fpsQueue.length)\n\tfor (const fn of queue) {\n\t\tfn()\n\t}\n}\n\nfunction tick() {\n\tif (frame) {\n\t\treturn\n\t}\n\tconst now = Date.now()\n\tconst elapsed = now - last\n\n\tif (time + elapsed < targetTimePerFrame) {\n\t\t// It's up to the consumer of debounce to call `cancel`\n\t\t// eslint-disable-next-line no-restricted-globals\n\t\tframe = requestAnimationFrame(() => {\n\t\t\tframe = undefined\n\t\t\ttick()\n\t\t})\n\t\treturn\n\t}\n\t// It's up to the consumer of debounce to call `cancel`\n\t// eslint-disable-next-line no-restricted-globals\n\tframe = requestAnimationFrame(() => {\n\t\tframe = undefined\n\t\tlast = now\n\t\t// If we fall behind more than 10 frames, we'll just reset the time so we don't try to update a number of times\n\t\t// This can happen if we don't interact with the page for a while\n\t\ttime = Math.min(time + elapsed - targetTimePerFrame, targetTimePerFrame * 10)\n\t\tflush()\n\t})\n}\n\nlet started = false\n\n/**\n * Returns a throttled version of the function that will only be called max once per frame.\n * The target frame rate is 60fps.\n * @param fn - the fun to return a throttled version of\n * @returns\n * @internal\n */\nexport function fpsThrottle(fn: { (): void; cancel?(): void }): {\n\t(): void\n\tcancel?(): void\n} {\n\tif (isTest()) {\n\t\tfn.cancel = () => frame && cancelAnimationFrame(frame)\n\t\treturn fn\n\t}\n\n\tconst throttledFn = () => {\n\t\tif (fpsQueue.includes(fn)) {\n\t\t\treturn\n\t\t}\n\t\tfpsQueue.push(fn)\n\t\tif (!started) {\n\t\t\tstarted = true\n\t\t\t// We set last to Date.now() - targetTimePerFrame - 1 so that the first run will happen immediately\n\t\t\tlast = Date.now() - targetTimePerFrame - 1\n\t\t}\n\t\ttick()\n\t}\n\tthrottledFn.cancel = () => {\n\t\tconst index = fpsQueue.indexOf(fn)\n\t\tif (index > -1) {\n\t\t\tfpsQueue.splice(index, 1)\n\t\t}\n\t}\n\treturn throttledFn\n}\n\n/**\n * Calls the function on the next frame. The target frame rate is 60fps.\n * If the same fn is passed again before the next frame, it will still be called only once.\n * @param fn - the fun to call on the next frame\n * @returns a function that will cancel the call if called before the next frame\n * @internal\n */\nexport function throttleToNextFrame(fn: () => void): () => void {\n\tif (isTest()) {\n\t\tfn()\n\t\treturn () => {\n\t\t\t// noop\n\t\t}\n\t}\n\n\tif (!fpsQueue.includes(fn)) {\n\t\tfpsQueue.push(fn)\n\t\tif (!started) {\n\t\t\tstarted = true\n\t\t\t// We set last to Date.now() - targetTimePerFrame - 1 so that the first run will happen immediately\n\t\t\tlast = Date.now() - targetTimePerFrame - 1\n\t\t}\n\t\ttick()\n\t}\n\n\treturn () => {\n\t\tconst index = fpsQueue.indexOf(fn)\n\t\tif (index > -1) {\n\t\t\tfpsQueue.splice(index, 1)\n\t\t}\n\t}\n}\n"],
  "mappings": "AAAA,MAAM,SAAS,MACd,OAAO,YAAY,eACnB,QAAQ,IAAI,aAAa;AAEzB,CAAC,WAAW;AAEb,MAAM,WAA8B,CAAC;AACrC,MAAM,YAAY;AAClB,MAAM,qBAAqB,KAAK,KAAK,MAAO,SAAS;AACrD,IAAI;AACJ,IAAI,OAAO;AACX,IAAI,OAAO;AAEX,MAAM,QAAQ,MAAM;AACnB,QAAM,QAAQ,SAAS,OAAO,GAAG,SAAS,MAAM;AAChD,aAAW,MAAM,OAAO;AACvB,OAAG;AAAA,EACJ;AACD;AAEA,SAAS,OAAO;AACf,MAAI,OAAO;AACV;AAAA,EACD;AACA,QAAM,MAAM,KAAK,IAAI;AACrB,QAAM,UAAU,MAAM;AAEtB,MAAI,OAAO,UAAU,oBAAoB;AAGxC,YAAQ,sBAAsB,MAAM;AACnC,cAAQ;AACR,WAAK;AAAA,IACN,CAAC;AACD;AAAA,EACD;AAGA,UAAQ,sBAAsB,MAAM;AACnC,YAAQ;AACR,WAAO;AAGP,WAAO,KAAK,IAAI,OAAO,UAAU,oBAAoB,qBAAqB,EAAE;AAC5E,UAAM;AAAA,EACP,CAAC;AACF;AAEA,IAAI,UAAU;AASP,SAAS,YAAY,IAG1B;AACD,MAAI,OAAO,GAAG;AACb,OAAG,SAAS,MAAM,SAAS,qBAAqB,KAAK;AACrD,WAAO;AAAA,EACR;AAEA,QAAM,cAAc,MAAM;AACzB,QAAI,SAAS,SAAS,EAAE,GAAG;AAC1B;AAAA,IACD;AACA,aAAS,KAAK,EAAE;AAChB,QAAI,CAAC,SAAS;AACb,gBAAU;AAEV,aAAO,KAAK,IAAI,IAAI,qBAAqB;AAAA,IAC1C;AACA,SAAK;AAAA,EACN;AACA,cAAY,SAAS,MAAM;AAC1B,UAAM,QAAQ,SAAS,QAAQ,EAAE;AACjC,QAAI,QAAQ,IAAI;AACf,eAAS,OAAO,OAAO,CAAC;AAAA,IACzB;AAAA,EACD;AACA,SAAO;AACR;AASO,SAAS,oBAAoB,IAA4B;AAC/D,MAAI,OAAO,GAAG;AACb,OAAG;AACH,WAAO,MAAM;AAAA,IAEb;AAAA,EACD;AAEA,MAAI,CAAC,SAAS,SAAS,EAAE,GAAG;AAC3B,aAAS,KAAK,EAAE;AAChB,QAAI,CAAC,SAAS;AACb,gBAAU;AAEV,aAAO,KAAK,IAAI,IAAI,qBAAqB;AAAA,IAC1C;AACA,SAAK;AAAA,EACN;AAEA,SAAO,MAAM;AACZ,UAAM,QAAQ,SAAS,QAAQ,EAAE;AACjC,QAAI,QAAQ,IAAI;AACf,eAAS,OAAO,OAAO,CAAC;AAAA,IACzB;AAAA,EACD;AACD;",
  "names": []
}
