diff --git a/lib/parse.js b/lib/parse.js index 4b85915c..213c8132 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -60,7 +60,14 @@ const DONE = Symbol('onDone') const SAW_VALID_ENTRY = Symbol('sawValidEntry') const SAW_NULL_BLOCK = Symbol('sawNullBlock') const SAW_EOF = Symbol('sawEOF') -const CLOSESTREAM = Symbol('closeStream') +const CLOSESTREAMTICK = Symbol('closeStreamTick') +const CLOSESTREAMMICRO = Symbol('closeStreamMicro') +const CLOSESTREAMPROMISE = Symbol('closeStreamPromise') +const CLOSESTREAM = process.env.TAR_CLOSE === 'tick' + ? CLOSESTREAMTICK + : process.env.TAR_CLOSE === 'micro' ? CLOSESTREAMMICRO + : process.env.TAR_CLOSE === 'promise' ? CLOSESTREAMPROMISE + : null const noop = _ => true @@ -222,7 +229,13 @@ module.exports = warner(class Parser extends EE { } [CLOSESTREAM] () { - nextTick(() => this.emit('close')) + if (CLOSESTREAM === CLOSESTREAMTICK) { + nextTick(() => this.emit('close')) + } else if (CLOSESTREAM === CLOSESTREAMMICRO) { + queueMicrotask(() => this.emit('close')) + } else if (CLOSESTREAM === CLOSESTREAMPROMISE) { + Promise.resolve().then(() => this.emit('close')) + } } [PROCESSENTRY] (entry) { diff --git a/test/extract.js b/test/extract.js index 5bbffeec..fbeec1e4 100644 --- a/test/extract.js +++ b/test/extract.js @@ -11,7 +11,6 @@ const { promisify } = require('util') const rimraf = promisify(require('rimraf')) const mutateFS = require('mutate-fs') const pipeline = promisify(require('stream').pipeline) -const https = require('https') t.teardown(_ => rimraf(extractdir)) @@ -57,6 +56,7 @@ t.test('basic extracting', t => { }) t.test('ensure an open stream is not prematuraly closed', t => { + t.plan(1) const dir = path.resolve(extractdir, 'basic-with-stream') t.beforeEach(async () => { @@ -65,18 +65,19 @@ t.test('ensure an open stream is not prematuraly closed', t => { }) const check = async t => { - fs.lstatSync(dir + '/node-tar-main/LICENSE') + t.ok(fs.lstatSync(dir + '/long-path')) await rimraf(dir) t.end() } t.test('async promisey', t => { - https.get('https://codeload.github.com/npm/node-tar/tar.gz/main', (stream) => { - return pipeline( - stream, - x({ cwd: dir }, ['node-tar-main/LICENSE']) - ).then(_ => check(t)) + const stream = fs.createReadStream(path.resolve(tars, 'long-paths.tar'), { + highWaterMark: 1, }) + pipeline( + stream, + x({ cwd: dir }) + ).then(_ => check(t)) }) t.end()