{"version":3,"file":"writable-async-write.mjs","sources":["../../src/utils/writable-async-write.ts"],"sourcesContent":["import { once } from 'node:events';\nimport { finished } from 'node:stream/promises';\nimport type { Writable } from 'stream';\n\n/**\n * Async helper for application code that `await`s sequential writes to a `Writable`.\n *\n * 1. Waits until `writable.write` invokes its callback (chunk accepted / `_write` finished).\n * 2. If `write()` returned `false` **and** `writable.writableNeedDrain` is still true after the\n *    callback, waits for `'drain'`.\n *\n * We check both: the return value tells us backpressure was signaled; `writableNeedDrain` avoids\n * awaiting `'drain'` when it already fired before we subscribed (would otherwise hang forever).\n *\n * While waiting for `'drain'`, we also race {@link finished} so destroying the writable (e.g. abort)\n * cannot leave this promise pending forever.\n */\nexport async function write(writable: Writable, chunk: unknown): Promise<void> {\n  let flushed = true;\n\n  await new Promise<void>((resolve, reject) => {\n    let settled = false;\n    const finish = (fn: () => void) => {\n      if (settled) {\n        return;\n      }\n      settled = true;\n      writable.off('error', onError);\n      fn();\n    };\n    const onError = (err: Error) => {\n      finish(() => reject(err));\n    };\n    writable.once('error', onError);\n    flushed = writable.write(chunk, (err) => {\n      if (err) {\n        // Do not reject or remove `error` here: Node may emit `error` after this callback, and\n        // clearing the listener first would leave that emission unhandled.\n        setImmediate(() => {\n          if (!settled) {\n            finish(() => reject(err));\n          }\n        });\n        return;\n      }\n      finish(() => resolve());\n    });\n  });\n\n  if (!flushed && writable.writableNeedDrain) {\n    // Without `finished`, awaiting only `drain` can hang forever if the writable is destroyed first.\n    await Promise.race([\n      once(writable, 'drain'),\n      finished(writable, { readable: false, writable: true }),\n    ]);\n  }\n}\n"],"names":["write","writable","chunk","flushed","Promise","resolve","reject","settled","finish","fn","off","onError","err","once","setImmediate","writableNeedDrain","race","finished","readable"],"mappings":";;;AAIA;;;;;;;;;;;;AAYC,IACM,eAAeA,KAAAA,CAAMC,QAAkB,EAAEC,KAAc,EAAA;AAC5D,IAAA,IAAIC,OAAAA,GAAU,IAAA;IAEd,MAAM,IAAIC,OAAAA,CAAc,CAACC,OAAAA,EAASC,MAAAA,GAAAA;AAChC,QAAA,IAAIC,OAAAA,GAAU,KAAA;AACd,QAAA,MAAMC,SAAS,CAACC,EAAAA,GAAAA;AACd,YAAA,IAAIF,OAAAA,EAAS;AACX,gBAAA;AACF,YAAA;YACAA,OAAAA,GAAU,IAAA;YACVN,QAAAA,CAASS,GAAG,CAAC,OAAA,EAASC,OAAAA,CAAAA;AACtBF,YAAAA,EAAAA,EAAAA;AACF,QAAA,CAAA;AACA,QAAA,MAAME,UAAU,CAACC,GAAAA,GAAAA;AACfJ,YAAAA,MAAAA,CAAO,IAAMF,MAAAA,CAAOM,GAAAA,CAAAA,CAAAA;AACtB,QAAA,CAAA;QACAX,QAAAA,CAASY,IAAI,CAAC,OAAA,EAASF,OAAAA,CAAAA;AACvBR,QAAAA,OAAAA,GAAUF,QAAAA,CAASD,KAAK,CAACE,KAAAA,EAAO,CAACU,GAAAA,GAAAA;AAC/B,YAAA,IAAIA,GAAAA,EAAK;;;gBAGPE,YAAAA,CAAa,IAAA;AACX,oBAAA,IAAI,CAACP,OAAAA,EAAS;AACZC,wBAAAA,MAAAA,CAAO,IAAMF,MAAAA,CAAOM,GAAAA,CAAAA,CAAAA;AACtB,oBAAA;AACF,gBAAA,CAAA,CAAA;AACA,gBAAA;AACF,YAAA;AACAJ,YAAAA,MAAAA,CAAO,IAAMH,OAAAA,EAAAA,CAAAA;AACf,QAAA,CAAA,CAAA;AACF,IAAA,CAAA,CAAA;AAEA,IAAA,IAAI,CAACF,OAAAA,IAAWF,QAAAA,CAASc,iBAAiB,EAAE;;QAE1C,MAAMX,OAAAA,CAAQY,IAAI,CAAC;AACjBH,YAAAA,IAAAA,CAAKZ,QAAAA,EAAU,OAAA,CAAA;AACfgB,YAAAA,QAAAA,CAAShB,QAAAA,EAAU;gBAAEiB,QAAAA,EAAU,KAAA;gBAAOjB,QAAAA,EAAU;AAAK,aAAA;AACtD,SAAA,CAAA;AACH,IAAA;AACF;;;;"}