UNPKG

@strapi/data-transfer

Version:

Data transfer capabilities for Strapi

1 lines 3.54 kB
{"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;;;;"}