{"version":3,"file":"create-batch-handler.mjs","sourceRoot":"","sources":["../../src/utils/create-batch-handler.ts"],"names":[],"mappings":";;AAOA;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,oBAAoB,CAClC,YAAsC,EACtC,WAAmB,EACnB,OAA+C;IAE/C,IAAI,WAAW,GAAW,EAAE,CAAC;IAC7B,IAAI,eAAe,GAAqB,EAAE,CAAC;IAE3C,MAAM,KAAK,GAAG,KAAK,IAAmB,EAAE;QACtC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,OAAO;QACT,CAAC;QACD,MAAM,MAAM,GAAG,WAAW,CAAC;QAC3B,MAAM,QAAQ,GAAG,eAAe,CAAC;QACjC,WAAW,GAAG,EAAE,CAAC;QACjB,eAAe,GAAG,EAAE,CAAC;QAErB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;YACpC,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;YACtB,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QACnD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACvD,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,cAAc,GAAG,QAAQ,CAAC,KAAK,EAAE,WAAW,EAAE;QAClD,OAAO,EAAE,KAAK;QACd,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,CAAC,GAAS,EAAiB,EAAE;QAC3C,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC3C,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACtB,eAAe,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YAC1C,yIAAyI;YACzI,cAAc,EAAE,CAAC;QACnB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,OAAO,OAAO,CAAC;AACjB,CAAC","sourcesContent":["import { debounce } from 'lodash';\n\ntype PendingSettler = {\n  resolve: () => void;\n  reject: (reason: unknown) => void;\n};\n\n/**\n * Batched handler: buffers arguments, debounces flush, then runs an aggregator\n * on the buffer and invokes onFlush with the result. Used to coalesce rapid\n * updateBalances calls without dropping params.\n *\n * Each call to the returned function returns a Promise that resolves when the\n * flush that includes that call completes, or rejects if onFlush throws, so\n * callers can await or use .catch() for error handling.\n *\n * @param aggregatorFn - Reduces the buffered items into one.\n * @param timeframeMs - Debounce wait before flushing.\n * @param onFlush - Called with the aggregated result when flush runs.\n * @returns Function that accepts an item, schedules a batched flush, and returns a Promise that settles when that batch completes.\n */\nexport function createBatchedHandler<Item>(\n  aggregatorFn: (buffer: Item[]) => Item,\n  timeframeMs: number,\n  onFlush: (merged: Item) => void | Promise<void>,\n): (arg: Item) => Promise<void> {\n  let eventBuffer: Item[] = [];\n  let pendingSettlers: PendingSettler[] = [];\n\n  const flush = async (): Promise<void> => {\n    if (eventBuffer.length === 0) {\n      return;\n    }\n    const buffer = eventBuffer;\n    const settlers = pendingSettlers;\n    eventBuffer = [];\n    pendingSettlers = [];\n\n    try {\n      const merged = aggregatorFn(buffer);\n      await onFlush(merged);\n      settlers.forEach((settler) => settler.resolve());\n    } catch (error) {\n      settlers.forEach((settler) => settler.reject(error));\n    }\n  };\n\n  const debouncedFlush = debounce(flush, timeframeMs, {\n    leading: false,\n    trailing: true,\n  });\n\n  const capture = (arg: Item): Promise<void> => {\n    return new Promise<void>((resolve, reject) => {\n      eventBuffer.push(arg);\n      pendingSettlers.push({ resolve, reject });\n      // eslint-disable-next-line @typescript-eslint/no-floating-promises -- Rejections are forwarded to capture() callers via pendingSettlers.\n      debouncedFlush();\n    });\n  };\n\n  return capture;\n}\n"]}