cline 1.0.0-nightly.19 → 1.0.0-nightly.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cline +0 -0
- package/bin/cline-darwin-amd64 +0 -0
- package/bin/cline-darwin-arm64 +0 -0
- package/bin/cline-host +0 -0
- package/bin/cline-host-darwin-amd64 +0 -0
- package/bin/cline-host-darwin-arm64 +0 -0
- package/bin/cline-host-linux-amd64 +0 -0
- package/bin/cline-host-linux-arm64 +0 -0
- package/bin/cline-linux-amd64 +0 -0
- package/bin/cline-linux-arm64 +0 -0
- package/cline-core.js +24841 -16621
- package/extension/package.json +12 -4
- package/node_modules/b4a/LICENSE +201 -0
- package/node_modules/b4a/README.md +153 -0
- package/node_modules/b4a/browser.js +563 -0
- package/node_modules/b4a/index.js +188 -0
- package/node_modules/b4a/lib/ascii.js +31 -0
- package/node_modules/b4a/lib/base64.js +65 -0
- package/node_modules/b4a/lib/hex.js +51 -0
- package/node_modules/b4a/lib/utf16le.js +40 -0
- package/node_modules/b4a/lib/utf8.js +141 -0
- package/node_modules/b4a/package.json +49 -0
- package/node_modules/b4a/react-native.js +5 -0
- package/node_modules/bare-events/LICENSE +201 -0
- package/node_modules/bare-events/README.md +25 -0
- package/node_modules/bare-events/global.d.ts +15 -0
- package/node_modules/bare-events/global.js +5 -0
- package/node_modules/bare-events/index.d.ts +94 -0
- package/node_modules/bare-events/index.js +355 -0
- package/node_modules/bare-events/lib/errors.js +32 -0
- package/node_modules/bare-events/package.json +61 -0
- package/node_modules/bare-events/web.d.ts +79 -0
- package/node_modules/bare-events/web.js +347 -0
- package/node_modules/bare-fs/CMakeLists.txt +13 -0
- package/node_modules/bare-fs/LICENSE +201 -0
- package/node_modules/bare-fs/README.md +29 -0
- package/node_modules/bare-fs/binding.c +2238 -0
- package/node_modules/bare-fs/binding.js +1 -0
- package/node_modules/bare-fs/index.d.ts +1115 -0
- package/node_modules/bare-fs/index.js +2330 -0
- package/node_modules/bare-fs/lib/constants.d.ts +49 -0
- package/node_modules/bare-fs/lib/constants.js +49 -0
- package/node_modules/bare-fs/lib/errors.d.ts +11 -0
- package/node_modules/bare-fs/lib/errors.js +55 -0
- package/node_modules/bare-fs/package.json +71 -0
- package/node_modules/bare-fs/prebuilds/android-arm/bare-fs.bare +0 -0
- package/node_modules/bare-fs/prebuilds/android-arm64/bare-fs.bare +0 -0
- package/node_modules/bare-fs/prebuilds/android-ia32/bare-fs.bare +0 -0
- package/node_modules/bare-fs/prebuilds/android-x64/bare-fs.bare +0 -0
- package/node_modules/bare-fs/prebuilds/darwin-arm64/bare-fs.bare +0 -0
- package/node_modules/bare-fs/prebuilds/darwin-x64/bare-fs.bare +0 -0
- package/node_modules/bare-fs/prebuilds/ios-arm64/bare-fs.bare +0 -0
- package/node_modules/bare-fs/prebuilds/ios-arm64-simulator/bare-fs.bare +0 -0
- package/node_modules/bare-fs/prebuilds/ios-x64-simulator/bare-fs.bare +0 -0
- package/node_modules/bare-fs/prebuilds/linux-arm64/bare-fs.bare +0 -0
- package/node_modules/bare-fs/prebuilds/linux-x64/bare-fs.bare +0 -0
- package/node_modules/bare-fs/prebuilds/win32-arm64/bare-fs.bare +0 -0
- package/node_modules/bare-fs/prebuilds/win32-x64/bare-fs.bare +0 -0
- package/node_modules/bare-fs/promises.d.ts +282 -0
- package/node_modules/bare-fs/promises.js +90 -0
- package/node_modules/bare-os/CMakeLists.txt +13 -0
- package/node_modules/bare-os/LICENSE +201 -0
- package/node_modules/bare-os/README.md +11 -0
- package/node_modules/bare-os/binding.c +1119 -0
- package/node_modules/bare-os/binding.js +1 -0
- package/node_modules/bare-os/index.d.ts +109 -0
- package/node_modules/bare-os/index.js +99 -0
- package/node_modules/bare-os/lib/constants.js +6 -0
- package/node_modules/bare-os/lib/errors.js +22 -0
- package/node_modules/bare-os/package.json +46 -0
- package/node_modules/bare-os/prebuilds/android-arm/bare-os.bare +0 -0
- package/node_modules/bare-os/prebuilds/android-arm64/bare-os.bare +0 -0
- package/node_modules/bare-os/prebuilds/android-ia32/bare-os.bare +0 -0
- package/node_modules/bare-os/prebuilds/android-x64/bare-os.bare +0 -0
- package/node_modules/bare-os/prebuilds/darwin-arm64/bare-os.bare +0 -0
- package/node_modules/bare-os/prebuilds/darwin-x64/bare-os.bare +0 -0
- package/node_modules/bare-os/prebuilds/ios-arm64/bare-os.bare +0 -0
- package/node_modules/bare-os/prebuilds/ios-arm64-simulator/bare-os.bare +0 -0
- package/node_modules/bare-os/prebuilds/ios-x64-simulator/bare-os.bare +0 -0
- package/node_modules/bare-os/prebuilds/linux-arm64/bare-os.bare +0 -0
- package/node_modules/bare-os/prebuilds/linux-x64/bare-os.bare +0 -0
- package/node_modules/bare-os/prebuilds/win32-arm64/bare-os.bare +0 -0
- package/node_modules/bare-os/prebuilds/win32-x64/bare-os.bare +0 -0
- package/node_modules/bare-path/LICENSE +201 -0
- package/node_modules/bare-path/NOTICE +28 -0
- package/node_modules/bare-path/README.md +19 -0
- package/node_modules/bare-path/index.js +11 -0
- package/node_modules/bare-path/lib/constants.js +11 -0
- package/node_modules/bare-path/lib/posix.js +242 -0
- package/node_modules/bare-path/lib/shared.js +67 -0
- package/node_modules/bare-path/lib/win32.js +513 -0
- package/node_modules/bare-path/package.json +36 -0
- package/node_modules/bare-stream/LICENSE +201 -0
- package/node_modules/bare-stream/README.md +15 -0
- package/node_modules/bare-stream/global.js +8 -0
- package/node_modules/bare-stream/index.d.ts +237 -0
- package/node_modules/bare-stream/index.js +355 -0
- package/node_modules/bare-stream/package.json +61 -0
- package/node_modules/bare-stream/promises.js +3 -0
- package/node_modules/bare-stream/web.d.ts +73 -0
- package/node_modules/bare-stream/web.js +229 -0
- package/node_modules/bare-url/CMakeLists.txt +27 -0
- package/node_modules/bare-url/LICENSE +201 -0
- package/node_modules/bare-url/README.md +19 -0
- package/node_modules/bare-url/binding.c +188 -0
- package/node_modules/bare-url/binding.js +1 -0
- package/node_modules/bare-url/global.d.ts +12 -0
- package/node_modules/bare-url/global.js +2 -0
- package/node_modules/bare-url/index.d.ts +39 -0
- package/node_modules/bare-url/index.js +450 -0
- package/node_modules/bare-url/lib/errors.d.ts +8 -0
- package/node_modules/bare-url/lib/errors.js +38 -0
- package/node_modules/bare-url/lib/url-search-params.d.ts +21 -0
- package/node_modules/bare-url/lib/url-search-params.js +176 -0
- package/node_modules/bare-url/package.json +51 -0
- package/node_modules/bare-url/prebuilds/android-arm/bare-url.bare +0 -0
- package/node_modules/bare-url/prebuilds/android-arm64/bare-url.bare +0 -0
- package/node_modules/bare-url/prebuilds/android-ia32/bare-url.bare +0 -0
- package/node_modules/bare-url/prebuilds/android-x64/bare-url.bare +0 -0
- package/node_modules/bare-url/prebuilds/darwin-arm64/bare-url.bare +0 -0
- package/node_modules/bare-url/prebuilds/darwin-x64/bare-url.bare +0 -0
- package/node_modules/bare-url/prebuilds/ios-arm64/bare-url.bare +0 -0
- package/node_modules/bare-url/prebuilds/ios-arm64-simulator/bare-url.bare +0 -0
- package/node_modules/bare-url/prebuilds/ios-x64-simulator/bare-url.bare +0 -0
- package/node_modules/bare-url/prebuilds/linux-arm64/bare-url.bare +0 -0
- package/node_modules/bare-url/prebuilds/linux-x64/bare-url.bare +0 -0
- package/node_modules/bare-url/prebuilds/win32-arm64/bare-url.bare +0 -0
- package/node_modules/bare-url/prebuilds/win32-x64/bare-url.bare +0 -0
- package/node_modules/better-sqlite3/deps/download.sh +1 -1
- package/node_modules/better-sqlite3/deps/sqlite3/sqlite3.c +122 -81
- package/node_modules/better-sqlite3/deps/sqlite3/sqlite3.h +45 -45
- package/node_modules/better-sqlite3/lib/database.js +1 -1
- package/node_modules/better-sqlite3/package.json +4 -7
- package/node_modules/better-sqlite3/src/addon.cpp +47 -0
- package/node_modules/better-sqlite3/src/better_sqlite3.cpp +44 -2164
- package/node_modules/better-sqlite3/src/objects/backup.cpp +120 -0
- package/node_modules/better-sqlite3/src/objects/backup.hpp +36 -0
- package/node_modules/better-sqlite3/src/objects/database.cpp +417 -0
- package/node_modules/better-sqlite3/src/objects/database.hpp +103 -0
- package/node_modules/better-sqlite3/src/objects/statement-iterator.cpp +113 -0
- package/node_modules/better-sqlite3/src/objects/statement-iterator.hpp +50 -0
- package/node_modules/better-sqlite3/src/objects/statement.cpp +383 -0
- package/node_modules/better-sqlite3/src/objects/statement.hpp +58 -0
- package/node_modules/better-sqlite3/src/util/bind-map.cpp +73 -0
- package/node_modules/better-sqlite3/src/util/binder.cpp +193 -0
- package/node_modules/better-sqlite3/src/util/constants.cpp +172 -0
- package/node_modules/better-sqlite3/src/util/custom-aggregate.cpp +121 -0
- package/node_modules/better-sqlite3/src/util/custom-function.cpp +59 -0
- package/node_modules/better-sqlite3/src/util/custom-table.cpp +409 -0
- package/node_modules/better-sqlite3/src/util/data-converter.cpp +17 -0
- package/node_modules/better-sqlite3/src/util/data.cpp +194 -0
- package/node_modules/better-sqlite3/src/util/helpers.cpp +109 -0
- package/node_modules/better-sqlite3/src/util/macros.cpp +63 -0
- package/node_modules/better-sqlite3/src/util/query-macros.cpp +71 -0
- package/node_modules/better-sqlite3/src/util/row-builder.cpp +49 -0
- package/node_modules/events-universal/LICENSE +201 -0
- package/node_modules/events-universal/README.md +17 -0
- package/node_modules/events-universal/bare.js +1 -0
- package/node_modules/events-universal/default.js +1 -0
- package/node_modules/events-universal/index.js +1 -0
- package/node_modules/events-universal/package.json +39 -0
- package/node_modules/events-universal/react-native.js +1 -0
- package/node_modules/{fs-constants → fast-fifo}/LICENSE +1 -1
- package/node_modules/fast-fifo/README.md +78 -0
- package/node_modules/fast-fifo/fixed-size.js +39 -0
- package/node_modules/fast-fifo/index.js +48 -0
- package/node_modules/fast-fifo/package.json +28 -0
- package/node_modules/{base64-js → streamx}/LICENSE +1 -1
- package/node_modules/streamx/README.md +489 -0
- package/node_modules/streamx/index.js +1184 -0
- package/node_modules/streamx/package.json +34 -0
- package/node_modules/tar-fs/README.md +23 -34
- package/node_modules/tar-fs/index.js +211 -184
- package/node_modules/tar-fs/package.json +27 -7
- package/node_modules/tar-stream/README.md +34 -19
- package/node_modules/tar-stream/constants.js +14 -0
- package/node_modules/tar-stream/extract.js +341 -192
- package/node_modules/tar-stream/headers.js +201 -175
- package/node_modules/tar-stream/pack.js +226 -194
- package/node_modules/tar-stream/package.json +23 -46
- package/node_modules/text-decoder/LICENSE +201 -0
- package/node_modules/text-decoder/README.md +36 -0
- package/node_modules/text-decoder/index.js +64 -0
- package/node_modules/text-decoder/lib/browser-decoder.js +17 -0
- package/node_modules/text-decoder/lib/pass-through-decoder.js +19 -0
- package/node_modules/text-decoder/lib/utf8-decoder.js +104 -0
- package/node_modules/text-decoder/package.json +38 -0
- package/package.json +2 -2
- package/proto/cline/account.proto +10 -8
- package/proto/cline/browser.proto +3 -1
- package/proto/cline/checkpoints.proto +5 -3
- package/proto/cline/commands.proto +4 -2
- package/proto/cline/common.proto +5 -7
- package/proto/cline/dictation.proto +3 -1
- package/proto/cline/file.proto +36 -34
- package/proto/cline/hooks.proto +3 -2
- package/proto/cline/mcp.proto +6 -4
- package/proto/cline/models.proto +189 -19
- package/proto/cline/oca_account.proto +6 -7
- package/proto/cline/slash.proto +3 -1
- package/proto/cline/state.proto +147 -292
- package/proto/cline/task.proto +4 -2
- package/proto/cline/ui.proto +25 -24
- package/proto/cline/web.proto +3 -1
- package/proto/descriptor_set.pb +0 -0
- package/proto/host/diff.proto +5 -4
- package/proto/host/env.proto +8 -7
- package/proto/host/testing.proto +3 -3
- package/proto/host/window.proto +2 -2
- package/proto/host/workspace.proto +24 -11
- package/node_modules/base64-js/README.md +0 -34
- package/node_modules/base64-js/base64js.min.js +0 -1
- package/node_modules/base64-js/index.d.ts +0 -3
- package/node_modules/base64-js/index.js +0 -150
- package/node_modules/base64-js/package.json +0 -47
- package/node_modules/better-sqlite3/src/better_sqlite3.hpp +0 -1036
- package/node_modules/bl/.travis.yml +0 -17
- package/node_modules/bl/BufferList.js +0 -396
- package/node_modules/bl/LICENSE.md +0 -13
- package/node_modules/bl/README.md +0 -247
- package/node_modules/bl/bl.js +0 -84
- package/node_modules/bl/package.json +0 -37
- package/node_modules/bl/test/convert.js +0 -21
- package/node_modules/bl/test/indexOf.js +0 -492
- package/node_modules/bl/test/isBufferList.js +0 -32
- package/node_modules/bl/test/test.js +0 -869
- package/node_modules/buffer/AUTHORS.md +0 -70
- package/node_modules/buffer/LICENSE +0 -21
- package/node_modules/buffer/README.md +0 -410
- package/node_modules/buffer/index.d.ts +0 -186
- package/node_modules/buffer/index.js +0 -1817
- package/node_modules/buffer/package.json +0 -96
- package/node_modules/chownr/LICENSE +0 -15
- package/node_modules/chownr/README.md +0 -3
- package/node_modules/chownr/chownr.js +0 -167
- package/node_modules/chownr/package.json +0 -29
- package/node_modules/fs-constants/README.md +0 -26
- package/node_modules/fs-constants/browser.js +0 -1
- package/node_modules/fs-constants/index.js +0 -1
- package/node_modules/fs-constants/package.json +0 -19
- package/node_modules/ieee754/LICENSE +0 -11
- package/node_modules/ieee754/README.md +0 -51
- package/node_modules/ieee754/index.d.ts +0 -10
- package/node_modules/ieee754/index.js +0 -85
- package/node_modules/ieee754/package.json +0 -52
- package/node_modules/inherits/LICENSE +0 -16
- package/node_modules/inherits/README.md +0 -42
- package/node_modules/inherits/inherits.js +0 -9
- package/node_modules/inherits/inherits_browser.js +0 -27
- package/node_modules/inherits/package.json +0 -29
- package/node_modules/readable-stream/CONTRIBUTING.md +0 -38
- package/node_modules/readable-stream/GOVERNANCE.md +0 -136
- package/node_modules/readable-stream/LICENSE +0 -47
- package/node_modules/readable-stream/README.md +0 -106
- package/node_modules/readable-stream/errors-browser.js +0 -127
- package/node_modules/readable-stream/errors.js +0 -116
- package/node_modules/readable-stream/experimentalWarning.js +0 -17
- package/node_modules/readable-stream/lib/_stream_duplex.js +0 -126
- package/node_modules/readable-stream/lib/_stream_passthrough.js +0 -37
- package/node_modules/readable-stream/lib/_stream_readable.js +0 -1027
- package/node_modules/readable-stream/lib/_stream_transform.js +0 -190
- package/node_modules/readable-stream/lib/_stream_writable.js +0 -641
- package/node_modules/readable-stream/lib/internal/streams/async_iterator.js +0 -180
- package/node_modules/readable-stream/lib/internal/streams/buffer_list.js +0 -183
- package/node_modules/readable-stream/lib/internal/streams/destroy.js +0 -96
- package/node_modules/readable-stream/lib/internal/streams/end-of-stream.js +0 -86
- package/node_modules/readable-stream/lib/internal/streams/from-browser.js +0 -3
- package/node_modules/readable-stream/lib/internal/streams/from.js +0 -52
- package/node_modules/readable-stream/lib/internal/streams/pipeline.js +0 -86
- package/node_modules/readable-stream/lib/internal/streams/state.js +0 -22
- package/node_modules/readable-stream/lib/internal/streams/stream-browser.js +0 -1
- package/node_modules/readable-stream/lib/internal/streams/stream.js +0 -1
- package/node_modules/readable-stream/package.json +0 -68
- package/node_modules/readable-stream/readable-browser.js +0 -9
- package/node_modules/readable-stream/readable.js +0 -16
- package/node_modules/string_decoder/LICENSE +0 -48
- package/node_modules/string_decoder/README.md +0 -47
- package/node_modules/string_decoder/lib/string_decoder.js +0 -296
- package/node_modules/string_decoder/package.json +0 -34
- package/node_modules/tar-fs/.travis.yml +0 -6
- package/node_modules/tar-fs/test/fixtures/a/hello.txt +0 -1
- package/node_modules/tar-fs/test/fixtures/b/a/test.txt +0 -1
- package/node_modules/tar-fs/test/fixtures/d/file1 +0 -0
- package/node_modules/tar-fs/test/fixtures/d/file2 +0 -0
- package/node_modules/tar-fs/test/fixtures/d/sub-dir/file5 +0 -0
- package/node_modules/tar-fs/test/fixtures/d/sub-files/file3 +0 -0
- package/node_modules/tar-fs/test/fixtures/d/sub-files/file4 +0 -0
- package/node_modules/tar-fs/test/fixtures/e/directory/.ignore +0 -0
- package/node_modules/tar-fs/test/fixtures/e/file +0 -0
- package/node_modules/tar-fs/test/fixtures/invalid.tar +0 -0
- package/node_modules/tar-fs/test/index.js +0 -346
- package/node_modules/tar-stream/sandbox.js +0 -11
- package/node_modules/util-deprecate/History.md +0 -16
- package/node_modules/util-deprecate/LICENSE +0 -24
- package/node_modules/util-deprecate/README.md +0 -53
- package/node_modules/util-deprecate/browser.js +0 -67
- package/node_modules/util-deprecate/node.js +0 -6
- package/node_modules/util-deprecate/package.json +0 -27
- package/test-startup.sh +0 -14
|
@@ -0,0 +1,1184 @@
|
|
|
1
|
+
const { EventEmitter } = require('events-universal')
|
|
2
|
+
const STREAM_DESTROYED = new Error('Stream was destroyed')
|
|
3
|
+
const PREMATURE_CLOSE = new Error('Premature close')
|
|
4
|
+
|
|
5
|
+
const FIFO = require('fast-fifo')
|
|
6
|
+
const TextDecoder = require('text-decoder')
|
|
7
|
+
|
|
8
|
+
// if we do a future major, expect queue microtask to be there always, for now a bit defensive
|
|
9
|
+
const qmt = typeof queueMicrotask === 'undefined' ? fn => global.process.nextTick(fn) : queueMicrotask
|
|
10
|
+
|
|
11
|
+
/* eslint-disable no-multi-spaces */
|
|
12
|
+
|
|
13
|
+
// 29 bits used total (4 from shared, 14 from read, and 11 from write)
|
|
14
|
+
const MAX = ((1 << 29) - 1)
|
|
15
|
+
|
|
16
|
+
// Shared state
|
|
17
|
+
const OPENING = 0b0001
|
|
18
|
+
const PREDESTROYING = 0b0010
|
|
19
|
+
const DESTROYING = 0b0100
|
|
20
|
+
const DESTROYED = 0b1000
|
|
21
|
+
|
|
22
|
+
const NOT_OPENING = MAX ^ OPENING
|
|
23
|
+
const NOT_PREDESTROYING = MAX ^ PREDESTROYING
|
|
24
|
+
|
|
25
|
+
// Read state (4 bit offset from shared state)
|
|
26
|
+
const READ_ACTIVE = 0b00000000000001 << 4
|
|
27
|
+
const READ_UPDATING = 0b00000000000010 << 4
|
|
28
|
+
const READ_PRIMARY = 0b00000000000100 << 4
|
|
29
|
+
const READ_QUEUED = 0b00000000001000 << 4
|
|
30
|
+
const READ_RESUMED = 0b00000000010000 << 4
|
|
31
|
+
const READ_PIPE_DRAINED = 0b00000000100000 << 4
|
|
32
|
+
const READ_ENDING = 0b00000001000000 << 4
|
|
33
|
+
const READ_EMIT_DATA = 0b00000010000000 << 4
|
|
34
|
+
const READ_EMIT_READABLE = 0b00000100000000 << 4
|
|
35
|
+
const READ_EMITTED_READABLE = 0b00001000000000 << 4
|
|
36
|
+
const READ_DONE = 0b00010000000000 << 4
|
|
37
|
+
const READ_NEXT_TICK = 0b00100000000000 << 4
|
|
38
|
+
const READ_NEEDS_PUSH = 0b01000000000000 << 4
|
|
39
|
+
const READ_READ_AHEAD = 0b10000000000000 << 4
|
|
40
|
+
|
|
41
|
+
// Combined read state
|
|
42
|
+
const READ_FLOWING = READ_RESUMED | READ_PIPE_DRAINED
|
|
43
|
+
const READ_ACTIVE_AND_NEEDS_PUSH = READ_ACTIVE | READ_NEEDS_PUSH
|
|
44
|
+
const READ_PRIMARY_AND_ACTIVE = READ_PRIMARY | READ_ACTIVE
|
|
45
|
+
const READ_EMIT_READABLE_AND_QUEUED = READ_EMIT_READABLE | READ_QUEUED
|
|
46
|
+
const READ_RESUMED_READ_AHEAD = READ_RESUMED | READ_READ_AHEAD
|
|
47
|
+
|
|
48
|
+
const READ_NOT_ACTIVE = MAX ^ READ_ACTIVE
|
|
49
|
+
const READ_NON_PRIMARY = MAX ^ READ_PRIMARY
|
|
50
|
+
const READ_NON_PRIMARY_AND_PUSHED = MAX ^ (READ_PRIMARY | READ_NEEDS_PUSH)
|
|
51
|
+
const READ_PUSHED = MAX ^ READ_NEEDS_PUSH
|
|
52
|
+
const READ_PAUSED = MAX ^ READ_RESUMED
|
|
53
|
+
const READ_NOT_QUEUED = MAX ^ (READ_QUEUED | READ_EMITTED_READABLE)
|
|
54
|
+
const READ_NOT_ENDING = MAX ^ READ_ENDING
|
|
55
|
+
const READ_PIPE_NOT_DRAINED = MAX ^ READ_FLOWING
|
|
56
|
+
const READ_NOT_NEXT_TICK = MAX ^ READ_NEXT_TICK
|
|
57
|
+
const READ_NOT_UPDATING = MAX ^ READ_UPDATING
|
|
58
|
+
const READ_NO_READ_AHEAD = MAX ^ READ_READ_AHEAD
|
|
59
|
+
const READ_PAUSED_NO_READ_AHEAD = MAX ^ READ_RESUMED_READ_AHEAD
|
|
60
|
+
|
|
61
|
+
// Write state (18 bit offset, 4 bit offset from shared state and 14 from read state)
|
|
62
|
+
const WRITE_ACTIVE = 0b00000000001 << 18
|
|
63
|
+
const WRITE_UPDATING = 0b00000000010 << 18
|
|
64
|
+
const WRITE_PRIMARY = 0b00000000100 << 18
|
|
65
|
+
const WRITE_QUEUED = 0b00000001000 << 18
|
|
66
|
+
const WRITE_UNDRAINED = 0b00000010000 << 18
|
|
67
|
+
const WRITE_DONE = 0b00000100000 << 18
|
|
68
|
+
const WRITE_EMIT_DRAIN = 0b00001000000 << 18
|
|
69
|
+
const WRITE_NEXT_TICK = 0b00010000000 << 18
|
|
70
|
+
const WRITE_WRITING = 0b00100000000 << 18
|
|
71
|
+
const WRITE_FINISHING = 0b01000000000 << 18
|
|
72
|
+
const WRITE_CORKED = 0b10000000000 << 18
|
|
73
|
+
|
|
74
|
+
const WRITE_NOT_ACTIVE = MAX ^ (WRITE_ACTIVE | WRITE_WRITING)
|
|
75
|
+
const WRITE_NON_PRIMARY = MAX ^ WRITE_PRIMARY
|
|
76
|
+
const WRITE_NOT_FINISHING = MAX ^ (WRITE_ACTIVE | WRITE_FINISHING)
|
|
77
|
+
const WRITE_DRAINED = MAX ^ WRITE_UNDRAINED
|
|
78
|
+
const WRITE_NOT_QUEUED = MAX ^ WRITE_QUEUED
|
|
79
|
+
const WRITE_NOT_NEXT_TICK = MAX ^ WRITE_NEXT_TICK
|
|
80
|
+
const WRITE_NOT_UPDATING = MAX ^ WRITE_UPDATING
|
|
81
|
+
const WRITE_NOT_CORKED = MAX ^ WRITE_CORKED
|
|
82
|
+
|
|
83
|
+
// Combined shared state
|
|
84
|
+
const ACTIVE = READ_ACTIVE | WRITE_ACTIVE
|
|
85
|
+
const NOT_ACTIVE = MAX ^ ACTIVE
|
|
86
|
+
const DONE = READ_DONE | WRITE_DONE
|
|
87
|
+
const DESTROY_STATUS = DESTROYING | DESTROYED | PREDESTROYING
|
|
88
|
+
const OPEN_STATUS = DESTROY_STATUS | OPENING
|
|
89
|
+
const AUTO_DESTROY = DESTROY_STATUS | DONE
|
|
90
|
+
const NON_PRIMARY = WRITE_NON_PRIMARY & READ_NON_PRIMARY
|
|
91
|
+
const ACTIVE_OR_TICKING = WRITE_NEXT_TICK | READ_NEXT_TICK
|
|
92
|
+
const TICKING = ACTIVE_OR_TICKING & NOT_ACTIVE
|
|
93
|
+
const IS_OPENING = OPEN_STATUS | TICKING
|
|
94
|
+
|
|
95
|
+
// Combined shared state and read state
|
|
96
|
+
const READ_PRIMARY_STATUS = OPEN_STATUS | READ_ENDING | READ_DONE
|
|
97
|
+
const READ_STATUS = OPEN_STATUS | READ_DONE | READ_QUEUED
|
|
98
|
+
const READ_ENDING_STATUS = OPEN_STATUS | READ_ENDING | READ_QUEUED
|
|
99
|
+
const READ_READABLE_STATUS = OPEN_STATUS | READ_EMIT_READABLE | READ_QUEUED | READ_EMITTED_READABLE
|
|
100
|
+
const SHOULD_NOT_READ = OPEN_STATUS | READ_ACTIVE | READ_ENDING | READ_DONE | READ_NEEDS_PUSH | READ_READ_AHEAD
|
|
101
|
+
const READ_BACKPRESSURE_STATUS = DESTROY_STATUS | READ_ENDING | READ_DONE
|
|
102
|
+
const READ_UPDATE_SYNC_STATUS = READ_UPDATING | OPEN_STATUS | READ_NEXT_TICK | READ_PRIMARY
|
|
103
|
+
const READ_NEXT_TICK_OR_OPENING = READ_NEXT_TICK | OPENING
|
|
104
|
+
|
|
105
|
+
// Combined write state
|
|
106
|
+
const WRITE_PRIMARY_STATUS = OPEN_STATUS | WRITE_FINISHING | WRITE_DONE
|
|
107
|
+
const WRITE_QUEUED_AND_UNDRAINED = WRITE_QUEUED | WRITE_UNDRAINED
|
|
108
|
+
const WRITE_QUEUED_AND_ACTIVE = WRITE_QUEUED | WRITE_ACTIVE
|
|
109
|
+
const WRITE_DRAIN_STATUS = WRITE_QUEUED | WRITE_UNDRAINED | OPEN_STATUS | WRITE_ACTIVE
|
|
110
|
+
const WRITE_STATUS = OPEN_STATUS | WRITE_ACTIVE | WRITE_QUEUED | WRITE_CORKED
|
|
111
|
+
const WRITE_PRIMARY_AND_ACTIVE = WRITE_PRIMARY | WRITE_ACTIVE
|
|
112
|
+
const WRITE_ACTIVE_AND_WRITING = WRITE_ACTIVE | WRITE_WRITING
|
|
113
|
+
const WRITE_FINISHING_STATUS = OPEN_STATUS | WRITE_FINISHING | WRITE_QUEUED_AND_ACTIVE | WRITE_DONE
|
|
114
|
+
const WRITE_BACKPRESSURE_STATUS = WRITE_UNDRAINED | DESTROY_STATUS | WRITE_FINISHING | WRITE_DONE
|
|
115
|
+
const WRITE_UPDATE_SYNC_STATUS = WRITE_UPDATING | OPEN_STATUS | WRITE_NEXT_TICK | WRITE_PRIMARY
|
|
116
|
+
const WRITE_DROP_DATA = WRITE_FINISHING | WRITE_DONE | DESTROY_STATUS
|
|
117
|
+
|
|
118
|
+
const asyncIterator = Symbol.asyncIterator || Symbol('asyncIterator')
|
|
119
|
+
|
|
120
|
+
class WritableState {
|
|
121
|
+
constructor (stream, { highWaterMark = 16384, map = null, mapWritable, byteLength, byteLengthWritable } = {}) {
|
|
122
|
+
this.stream = stream
|
|
123
|
+
this.queue = new FIFO()
|
|
124
|
+
this.highWaterMark = highWaterMark
|
|
125
|
+
this.buffered = 0
|
|
126
|
+
this.error = null
|
|
127
|
+
this.pipeline = null
|
|
128
|
+
this.drains = null // if we add more seldomly used helpers we might them into a subobject so its a single ptr
|
|
129
|
+
this.byteLength = byteLengthWritable || byteLength || defaultByteLength
|
|
130
|
+
this.map = mapWritable || map
|
|
131
|
+
this.afterWrite = afterWrite.bind(this)
|
|
132
|
+
this.afterUpdateNextTick = updateWriteNT.bind(this)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
get ended () {
|
|
136
|
+
return (this.stream._duplexState & WRITE_DONE) !== 0
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
push (data) {
|
|
140
|
+
if ((this.stream._duplexState & WRITE_DROP_DATA) !== 0) return false
|
|
141
|
+
if (this.map !== null) data = this.map(data)
|
|
142
|
+
|
|
143
|
+
this.buffered += this.byteLength(data)
|
|
144
|
+
this.queue.push(data)
|
|
145
|
+
|
|
146
|
+
if (this.buffered < this.highWaterMark) {
|
|
147
|
+
this.stream._duplexState |= WRITE_QUEUED
|
|
148
|
+
return true
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
this.stream._duplexState |= WRITE_QUEUED_AND_UNDRAINED
|
|
152
|
+
return false
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
shift () {
|
|
156
|
+
const data = this.queue.shift()
|
|
157
|
+
|
|
158
|
+
this.buffered -= this.byteLength(data)
|
|
159
|
+
if (this.buffered === 0) this.stream._duplexState &= WRITE_NOT_QUEUED
|
|
160
|
+
|
|
161
|
+
return data
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
end (data) {
|
|
165
|
+
if (typeof data === 'function') this.stream.once('finish', data)
|
|
166
|
+
else if (data !== undefined && data !== null) this.push(data)
|
|
167
|
+
this.stream._duplexState = (this.stream._duplexState | WRITE_FINISHING) & WRITE_NON_PRIMARY
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
autoBatch (data, cb) {
|
|
171
|
+
const buffer = []
|
|
172
|
+
const stream = this.stream
|
|
173
|
+
|
|
174
|
+
buffer.push(data)
|
|
175
|
+
while ((stream._duplexState & WRITE_STATUS) === WRITE_QUEUED_AND_ACTIVE) {
|
|
176
|
+
buffer.push(stream._writableState.shift())
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if ((stream._duplexState & OPEN_STATUS) !== 0) return cb(null)
|
|
180
|
+
stream._writev(buffer, cb)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
update () {
|
|
184
|
+
const stream = this.stream
|
|
185
|
+
|
|
186
|
+
stream._duplexState |= WRITE_UPDATING
|
|
187
|
+
|
|
188
|
+
do {
|
|
189
|
+
while ((stream._duplexState & WRITE_STATUS) === WRITE_QUEUED) {
|
|
190
|
+
const data = this.shift()
|
|
191
|
+
stream._duplexState |= WRITE_ACTIVE_AND_WRITING
|
|
192
|
+
stream._write(data, this.afterWrite)
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if ((stream._duplexState & WRITE_PRIMARY_AND_ACTIVE) === 0) this.updateNonPrimary()
|
|
196
|
+
} while (this.continueUpdate() === true)
|
|
197
|
+
|
|
198
|
+
stream._duplexState &= WRITE_NOT_UPDATING
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
updateNonPrimary () {
|
|
202
|
+
const stream = this.stream
|
|
203
|
+
|
|
204
|
+
if ((stream._duplexState & WRITE_FINISHING_STATUS) === WRITE_FINISHING) {
|
|
205
|
+
stream._duplexState = stream._duplexState | WRITE_ACTIVE
|
|
206
|
+
stream._final(afterFinal.bind(this))
|
|
207
|
+
return
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if ((stream._duplexState & DESTROY_STATUS) === DESTROYING) {
|
|
211
|
+
if ((stream._duplexState & ACTIVE_OR_TICKING) === 0) {
|
|
212
|
+
stream._duplexState |= ACTIVE
|
|
213
|
+
stream._destroy(afterDestroy.bind(this))
|
|
214
|
+
}
|
|
215
|
+
return
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if ((stream._duplexState & IS_OPENING) === OPENING) {
|
|
219
|
+
stream._duplexState = (stream._duplexState | ACTIVE) & NOT_OPENING
|
|
220
|
+
stream._open(afterOpen.bind(this))
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
continueUpdate () {
|
|
225
|
+
if ((this.stream._duplexState & WRITE_NEXT_TICK) === 0) return false
|
|
226
|
+
this.stream._duplexState &= WRITE_NOT_NEXT_TICK
|
|
227
|
+
return true
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
updateCallback () {
|
|
231
|
+
if ((this.stream._duplexState & WRITE_UPDATE_SYNC_STATUS) === WRITE_PRIMARY) this.update()
|
|
232
|
+
else this.updateNextTick()
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
updateNextTick () {
|
|
236
|
+
if ((this.stream._duplexState & WRITE_NEXT_TICK) !== 0) return
|
|
237
|
+
this.stream._duplexState |= WRITE_NEXT_TICK
|
|
238
|
+
if ((this.stream._duplexState & WRITE_UPDATING) === 0) qmt(this.afterUpdateNextTick)
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
class ReadableState {
|
|
243
|
+
constructor (stream, { highWaterMark = 16384, map = null, mapReadable, byteLength, byteLengthReadable } = {}) {
|
|
244
|
+
this.stream = stream
|
|
245
|
+
this.queue = new FIFO()
|
|
246
|
+
this.highWaterMark = highWaterMark === 0 ? 1 : highWaterMark
|
|
247
|
+
this.buffered = 0
|
|
248
|
+
this.readAhead = highWaterMark > 0
|
|
249
|
+
this.error = null
|
|
250
|
+
this.pipeline = null
|
|
251
|
+
this.byteLength = byteLengthReadable || byteLength || defaultByteLength
|
|
252
|
+
this.map = mapReadable || map
|
|
253
|
+
this.pipeTo = null
|
|
254
|
+
this.afterRead = afterRead.bind(this)
|
|
255
|
+
this.afterUpdateNextTick = updateReadNT.bind(this)
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
get ended () {
|
|
259
|
+
return (this.stream._duplexState & READ_DONE) !== 0
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
pipe (pipeTo, cb) {
|
|
263
|
+
if (this.pipeTo !== null) throw new Error('Can only pipe to one destination')
|
|
264
|
+
if (typeof cb !== 'function') cb = null
|
|
265
|
+
|
|
266
|
+
this.stream._duplexState |= READ_PIPE_DRAINED
|
|
267
|
+
this.pipeTo = pipeTo
|
|
268
|
+
this.pipeline = new Pipeline(this.stream, pipeTo, cb)
|
|
269
|
+
|
|
270
|
+
if (cb) this.stream.on('error', noop) // We already error handle this so supress crashes
|
|
271
|
+
|
|
272
|
+
if (isStreamx(pipeTo)) {
|
|
273
|
+
pipeTo._writableState.pipeline = this.pipeline
|
|
274
|
+
if (cb) pipeTo.on('error', noop) // We already error handle this so supress crashes
|
|
275
|
+
pipeTo.on('finish', this.pipeline.finished.bind(this.pipeline)) // TODO: just call finished from pipeTo itself
|
|
276
|
+
} else {
|
|
277
|
+
const onerror = this.pipeline.done.bind(this.pipeline, pipeTo)
|
|
278
|
+
const onclose = this.pipeline.done.bind(this.pipeline, pipeTo, null) // onclose has a weird bool arg
|
|
279
|
+
pipeTo.on('error', onerror)
|
|
280
|
+
pipeTo.on('close', onclose)
|
|
281
|
+
pipeTo.on('finish', this.pipeline.finished.bind(this.pipeline))
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
pipeTo.on('drain', afterDrain.bind(this))
|
|
285
|
+
this.stream.emit('piping', pipeTo)
|
|
286
|
+
pipeTo.emit('pipe', this.stream)
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
push (data) {
|
|
290
|
+
const stream = this.stream
|
|
291
|
+
|
|
292
|
+
if (data === null) {
|
|
293
|
+
this.highWaterMark = 0
|
|
294
|
+
stream._duplexState = (stream._duplexState | READ_ENDING) & READ_NON_PRIMARY_AND_PUSHED
|
|
295
|
+
return false
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (this.map !== null) {
|
|
299
|
+
data = this.map(data)
|
|
300
|
+
if (data === null) {
|
|
301
|
+
stream._duplexState &= READ_PUSHED
|
|
302
|
+
return this.buffered < this.highWaterMark
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
this.buffered += this.byteLength(data)
|
|
307
|
+
this.queue.push(data)
|
|
308
|
+
|
|
309
|
+
stream._duplexState = (stream._duplexState | READ_QUEUED) & READ_PUSHED
|
|
310
|
+
|
|
311
|
+
return this.buffered < this.highWaterMark
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
shift () {
|
|
315
|
+
const data = this.queue.shift()
|
|
316
|
+
|
|
317
|
+
this.buffered -= this.byteLength(data)
|
|
318
|
+
if (this.buffered === 0) this.stream._duplexState &= READ_NOT_QUEUED
|
|
319
|
+
return data
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
unshift (data) {
|
|
323
|
+
const pending = [this.map !== null ? this.map(data) : data]
|
|
324
|
+
while (this.buffered > 0) pending.push(this.shift())
|
|
325
|
+
|
|
326
|
+
for (let i = 0; i < pending.length - 1; i++) {
|
|
327
|
+
const data = pending[i]
|
|
328
|
+
this.buffered += this.byteLength(data)
|
|
329
|
+
this.queue.push(data)
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
this.push(pending[pending.length - 1])
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
read () {
|
|
336
|
+
const stream = this.stream
|
|
337
|
+
|
|
338
|
+
if ((stream._duplexState & READ_STATUS) === READ_QUEUED) {
|
|
339
|
+
const data = this.shift()
|
|
340
|
+
if (this.pipeTo !== null && this.pipeTo.write(data) === false) stream._duplexState &= READ_PIPE_NOT_DRAINED
|
|
341
|
+
if ((stream._duplexState & READ_EMIT_DATA) !== 0) stream.emit('data', data)
|
|
342
|
+
return data
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
if (this.readAhead === false) {
|
|
346
|
+
stream._duplexState |= READ_READ_AHEAD
|
|
347
|
+
this.updateNextTick()
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
return null
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
drain () {
|
|
354
|
+
const stream = this.stream
|
|
355
|
+
|
|
356
|
+
while ((stream._duplexState & READ_STATUS) === READ_QUEUED && (stream._duplexState & READ_FLOWING) !== 0) {
|
|
357
|
+
const data = this.shift()
|
|
358
|
+
if (this.pipeTo !== null && this.pipeTo.write(data) === false) stream._duplexState &= READ_PIPE_NOT_DRAINED
|
|
359
|
+
if ((stream._duplexState & READ_EMIT_DATA) !== 0) stream.emit('data', data)
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
update () {
|
|
364
|
+
const stream = this.stream
|
|
365
|
+
|
|
366
|
+
stream._duplexState |= READ_UPDATING
|
|
367
|
+
|
|
368
|
+
do {
|
|
369
|
+
this.drain()
|
|
370
|
+
|
|
371
|
+
while (this.buffered < this.highWaterMark && (stream._duplexState & SHOULD_NOT_READ) === READ_READ_AHEAD) {
|
|
372
|
+
stream._duplexState |= READ_ACTIVE_AND_NEEDS_PUSH
|
|
373
|
+
stream._read(this.afterRead)
|
|
374
|
+
this.drain()
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
if ((stream._duplexState & READ_READABLE_STATUS) === READ_EMIT_READABLE_AND_QUEUED) {
|
|
378
|
+
stream._duplexState |= READ_EMITTED_READABLE
|
|
379
|
+
stream.emit('readable')
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
if ((stream._duplexState & READ_PRIMARY_AND_ACTIVE) === 0) this.updateNonPrimary()
|
|
383
|
+
} while (this.continueUpdate() === true)
|
|
384
|
+
|
|
385
|
+
stream._duplexState &= READ_NOT_UPDATING
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
updateNonPrimary () {
|
|
389
|
+
const stream = this.stream
|
|
390
|
+
|
|
391
|
+
if ((stream._duplexState & READ_ENDING_STATUS) === READ_ENDING) {
|
|
392
|
+
stream._duplexState = (stream._duplexState | READ_DONE) & READ_NOT_ENDING
|
|
393
|
+
stream.emit('end')
|
|
394
|
+
if ((stream._duplexState & AUTO_DESTROY) === DONE) stream._duplexState |= DESTROYING
|
|
395
|
+
if (this.pipeTo !== null) this.pipeTo.end()
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
if ((stream._duplexState & DESTROY_STATUS) === DESTROYING) {
|
|
399
|
+
if ((stream._duplexState & ACTIVE_OR_TICKING) === 0) {
|
|
400
|
+
stream._duplexState |= ACTIVE
|
|
401
|
+
stream._destroy(afterDestroy.bind(this))
|
|
402
|
+
}
|
|
403
|
+
return
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
if ((stream._duplexState & IS_OPENING) === OPENING) {
|
|
407
|
+
stream._duplexState = (stream._duplexState | ACTIVE) & NOT_OPENING
|
|
408
|
+
stream._open(afterOpen.bind(this))
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
continueUpdate () {
|
|
413
|
+
if ((this.stream._duplexState & READ_NEXT_TICK) === 0) return false
|
|
414
|
+
this.stream._duplexState &= READ_NOT_NEXT_TICK
|
|
415
|
+
return true
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
updateCallback () {
|
|
419
|
+
if ((this.stream._duplexState & READ_UPDATE_SYNC_STATUS) === READ_PRIMARY) this.update()
|
|
420
|
+
else this.updateNextTick()
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
updateNextTickIfOpen () {
|
|
424
|
+
if ((this.stream._duplexState & READ_NEXT_TICK_OR_OPENING) !== 0) return
|
|
425
|
+
this.stream._duplexState |= READ_NEXT_TICK
|
|
426
|
+
if ((this.stream._duplexState & READ_UPDATING) === 0) qmt(this.afterUpdateNextTick)
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
updateNextTick () {
|
|
430
|
+
if ((this.stream._duplexState & READ_NEXT_TICK) !== 0) return
|
|
431
|
+
this.stream._duplexState |= READ_NEXT_TICK
|
|
432
|
+
if ((this.stream._duplexState & READ_UPDATING) === 0) qmt(this.afterUpdateNextTick)
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
class TransformState {
|
|
437
|
+
constructor (stream) {
|
|
438
|
+
this.data = null
|
|
439
|
+
this.afterTransform = afterTransform.bind(stream)
|
|
440
|
+
this.afterFinal = null
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
class Pipeline {
|
|
445
|
+
constructor (src, dst, cb) {
|
|
446
|
+
this.from = src
|
|
447
|
+
this.to = dst
|
|
448
|
+
this.afterPipe = cb
|
|
449
|
+
this.error = null
|
|
450
|
+
this.pipeToFinished = false
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
finished () {
|
|
454
|
+
this.pipeToFinished = true
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
done (stream, err) {
|
|
458
|
+
if (err) this.error = err
|
|
459
|
+
|
|
460
|
+
if (stream === this.to) {
|
|
461
|
+
this.to = null
|
|
462
|
+
|
|
463
|
+
if (this.from !== null) {
|
|
464
|
+
if ((this.from._duplexState & READ_DONE) === 0 || !this.pipeToFinished) {
|
|
465
|
+
this.from.destroy(this.error || new Error('Writable stream closed prematurely'))
|
|
466
|
+
}
|
|
467
|
+
return
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
if (stream === this.from) {
|
|
472
|
+
this.from = null
|
|
473
|
+
|
|
474
|
+
if (this.to !== null) {
|
|
475
|
+
if ((stream._duplexState & READ_DONE) === 0) {
|
|
476
|
+
this.to.destroy(this.error || new Error('Readable stream closed before ending'))
|
|
477
|
+
}
|
|
478
|
+
return
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
if (this.afterPipe !== null) this.afterPipe(this.error)
|
|
483
|
+
this.to = this.from = this.afterPipe = null
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
function afterDrain () {
|
|
488
|
+
this.stream._duplexState |= READ_PIPE_DRAINED
|
|
489
|
+
this.updateCallback()
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
function afterFinal (err) {
|
|
493
|
+
const stream = this.stream
|
|
494
|
+
if (err) stream.destroy(err)
|
|
495
|
+
if ((stream._duplexState & DESTROY_STATUS) === 0) {
|
|
496
|
+
stream._duplexState |= WRITE_DONE
|
|
497
|
+
stream.emit('finish')
|
|
498
|
+
}
|
|
499
|
+
if ((stream._duplexState & AUTO_DESTROY) === DONE) {
|
|
500
|
+
stream._duplexState |= DESTROYING
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
stream._duplexState &= WRITE_NOT_FINISHING
|
|
504
|
+
|
|
505
|
+
// no need to wait the extra tick here, so we short circuit that
|
|
506
|
+
if ((stream._duplexState & WRITE_UPDATING) === 0) this.update()
|
|
507
|
+
else this.updateNextTick()
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
function afterDestroy (err) {
|
|
511
|
+
const stream = this.stream
|
|
512
|
+
|
|
513
|
+
if (!err && this.error !== STREAM_DESTROYED) err = this.error
|
|
514
|
+
if (err) stream.emit('error', err)
|
|
515
|
+
stream._duplexState |= DESTROYED
|
|
516
|
+
stream.emit('close')
|
|
517
|
+
|
|
518
|
+
const rs = stream._readableState
|
|
519
|
+
const ws = stream._writableState
|
|
520
|
+
|
|
521
|
+
if (rs !== null && rs.pipeline !== null) rs.pipeline.done(stream, err)
|
|
522
|
+
|
|
523
|
+
if (ws !== null) {
|
|
524
|
+
while (ws.drains !== null && ws.drains.length > 0) ws.drains.shift().resolve(false)
|
|
525
|
+
if (ws.pipeline !== null) ws.pipeline.done(stream, err)
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
function afterWrite (err) {
|
|
530
|
+
const stream = this.stream
|
|
531
|
+
|
|
532
|
+
if (err) stream.destroy(err)
|
|
533
|
+
stream._duplexState &= WRITE_NOT_ACTIVE
|
|
534
|
+
|
|
535
|
+
if (this.drains !== null) tickDrains(this.drains)
|
|
536
|
+
|
|
537
|
+
if ((stream._duplexState & WRITE_DRAIN_STATUS) === WRITE_UNDRAINED) {
|
|
538
|
+
stream._duplexState &= WRITE_DRAINED
|
|
539
|
+
if ((stream._duplexState & WRITE_EMIT_DRAIN) === WRITE_EMIT_DRAIN) {
|
|
540
|
+
stream.emit('drain')
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
this.updateCallback()
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
function afterRead (err) {
|
|
548
|
+
if (err) this.stream.destroy(err)
|
|
549
|
+
this.stream._duplexState &= READ_NOT_ACTIVE
|
|
550
|
+
if (this.readAhead === false && (this.stream._duplexState & READ_RESUMED) === 0) this.stream._duplexState &= READ_NO_READ_AHEAD
|
|
551
|
+
this.updateCallback()
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
function updateReadNT () {
|
|
555
|
+
if ((this.stream._duplexState & READ_UPDATING) === 0) {
|
|
556
|
+
this.stream._duplexState &= READ_NOT_NEXT_TICK
|
|
557
|
+
this.update()
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
function updateWriteNT () {
|
|
562
|
+
if ((this.stream._duplexState & WRITE_UPDATING) === 0) {
|
|
563
|
+
this.stream._duplexState &= WRITE_NOT_NEXT_TICK
|
|
564
|
+
this.update()
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
function tickDrains (drains) {
|
|
569
|
+
for (let i = 0; i < drains.length; i++) {
|
|
570
|
+
// drains.writes are monotonic, so if one is 0 its always the first one
|
|
571
|
+
if (--drains[i].writes === 0) {
|
|
572
|
+
drains.shift().resolve(true)
|
|
573
|
+
i--
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
function afterOpen (err) {
|
|
579
|
+
const stream = this.stream
|
|
580
|
+
|
|
581
|
+
if (err) stream.destroy(err)
|
|
582
|
+
|
|
583
|
+
if ((stream._duplexState & DESTROYING) === 0) {
|
|
584
|
+
if ((stream._duplexState & READ_PRIMARY_STATUS) === 0) stream._duplexState |= READ_PRIMARY
|
|
585
|
+
if ((stream._duplexState & WRITE_PRIMARY_STATUS) === 0) stream._duplexState |= WRITE_PRIMARY
|
|
586
|
+
stream.emit('open')
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
stream._duplexState &= NOT_ACTIVE
|
|
590
|
+
|
|
591
|
+
if (stream._writableState !== null) {
|
|
592
|
+
stream._writableState.updateCallback()
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
if (stream._readableState !== null) {
|
|
596
|
+
stream._readableState.updateCallback()
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
function afterTransform (err, data) {
|
|
601
|
+
if (data !== undefined && data !== null) this.push(data)
|
|
602
|
+
this._writableState.afterWrite(err)
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
function newListener (name) {
|
|
606
|
+
if (this._readableState !== null) {
|
|
607
|
+
if (name === 'data') {
|
|
608
|
+
this._duplexState |= (READ_EMIT_DATA | READ_RESUMED_READ_AHEAD)
|
|
609
|
+
this._readableState.updateNextTick()
|
|
610
|
+
}
|
|
611
|
+
if (name === 'readable') {
|
|
612
|
+
this._duplexState |= READ_EMIT_READABLE
|
|
613
|
+
this._readableState.updateNextTick()
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
if (this._writableState !== null) {
|
|
618
|
+
if (name === 'drain') {
|
|
619
|
+
this._duplexState |= WRITE_EMIT_DRAIN
|
|
620
|
+
this._writableState.updateNextTick()
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
class Stream extends EventEmitter {
|
|
626
|
+
constructor (opts) {
|
|
627
|
+
super()
|
|
628
|
+
|
|
629
|
+
this._duplexState = 0
|
|
630
|
+
this._readableState = null
|
|
631
|
+
this._writableState = null
|
|
632
|
+
|
|
633
|
+
if (opts) {
|
|
634
|
+
if (opts.open) this._open = opts.open
|
|
635
|
+
if (opts.destroy) this._destroy = opts.destroy
|
|
636
|
+
if (opts.predestroy) this._predestroy = opts.predestroy
|
|
637
|
+
if (opts.signal) {
|
|
638
|
+
opts.signal.addEventListener('abort', abort.bind(this))
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
this.on('newListener', newListener)
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
_open (cb) {
|
|
646
|
+
cb(null)
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
_destroy (cb) {
|
|
650
|
+
cb(null)
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
_predestroy () {
|
|
654
|
+
// does nothing
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
get readable () {
|
|
658
|
+
return this._readableState !== null ? true : undefined
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
get writable () {
|
|
662
|
+
return this._writableState !== null ? true : undefined
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
get destroyed () {
|
|
666
|
+
return (this._duplexState & DESTROYED) !== 0
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
get destroying () {
|
|
670
|
+
return (this._duplexState & DESTROY_STATUS) !== 0
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
destroy (err) {
|
|
674
|
+
if ((this._duplexState & DESTROY_STATUS) === 0) {
|
|
675
|
+
if (!err) err = STREAM_DESTROYED
|
|
676
|
+
this._duplexState = (this._duplexState | DESTROYING) & NON_PRIMARY
|
|
677
|
+
|
|
678
|
+
if (this._readableState !== null) {
|
|
679
|
+
this._readableState.highWaterMark = 0
|
|
680
|
+
this._readableState.error = err
|
|
681
|
+
}
|
|
682
|
+
if (this._writableState !== null) {
|
|
683
|
+
this._writableState.highWaterMark = 0
|
|
684
|
+
this._writableState.error = err
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
this._duplexState |= PREDESTROYING
|
|
688
|
+
this._predestroy()
|
|
689
|
+
this._duplexState &= NOT_PREDESTROYING
|
|
690
|
+
|
|
691
|
+
if (this._readableState !== null) this._readableState.updateNextTick()
|
|
692
|
+
if (this._writableState !== null) this._writableState.updateNextTick()
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
class Readable extends Stream {
|
|
698
|
+
constructor (opts) {
|
|
699
|
+
super(opts)
|
|
700
|
+
|
|
701
|
+
this._duplexState |= OPENING | WRITE_DONE | READ_READ_AHEAD
|
|
702
|
+
this._readableState = new ReadableState(this, opts)
|
|
703
|
+
|
|
704
|
+
if (opts) {
|
|
705
|
+
if (this._readableState.readAhead === false) this._duplexState &= READ_NO_READ_AHEAD
|
|
706
|
+
if (opts.read) this._read = opts.read
|
|
707
|
+
if (opts.eagerOpen) this._readableState.updateNextTick()
|
|
708
|
+
if (opts.encoding) this.setEncoding(opts.encoding)
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
setEncoding (encoding) {
|
|
713
|
+
const dec = new TextDecoder(encoding)
|
|
714
|
+
const map = this._readableState.map || echo
|
|
715
|
+
this._readableState.map = mapOrSkip
|
|
716
|
+
return this
|
|
717
|
+
|
|
718
|
+
function mapOrSkip (data) {
|
|
719
|
+
const next = dec.push(data)
|
|
720
|
+
return next === '' && (data.byteLength !== 0 || dec.remaining > 0) ? null : map(next)
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
_read (cb) {
|
|
725
|
+
cb(null)
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
pipe (dest, cb) {
|
|
729
|
+
this._readableState.updateNextTick()
|
|
730
|
+
this._readableState.pipe(dest, cb)
|
|
731
|
+
return dest
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
read () {
|
|
735
|
+
this._readableState.updateNextTick()
|
|
736
|
+
return this._readableState.read()
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
push (data) {
|
|
740
|
+
this._readableState.updateNextTickIfOpen()
|
|
741
|
+
return this._readableState.push(data)
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
unshift (data) {
|
|
745
|
+
this._readableState.updateNextTickIfOpen()
|
|
746
|
+
return this._readableState.unshift(data)
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
resume () {
|
|
750
|
+
this._duplexState |= READ_RESUMED_READ_AHEAD
|
|
751
|
+
this._readableState.updateNextTick()
|
|
752
|
+
return this
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
pause () {
|
|
756
|
+
this._duplexState &= (this._readableState.readAhead === false ? READ_PAUSED_NO_READ_AHEAD : READ_PAUSED)
|
|
757
|
+
return this
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
static _fromAsyncIterator (ite, opts) {
|
|
761
|
+
let destroy
|
|
762
|
+
|
|
763
|
+
const rs = new Readable({
|
|
764
|
+
...opts,
|
|
765
|
+
read (cb) {
|
|
766
|
+
ite.next().then(push).then(cb.bind(null, null)).catch(cb)
|
|
767
|
+
},
|
|
768
|
+
predestroy () {
|
|
769
|
+
destroy = ite.return()
|
|
770
|
+
},
|
|
771
|
+
destroy (cb) {
|
|
772
|
+
if (!destroy) return cb(null)
|
|
773
|
+
destroy.then(cb.bind(null, null)).catch(cb)
|
|
774
|
+
}
|
|
775
|
+
})
|
|
776
|
+
|
|
777
|
+
return rs
|
|
778
|
+
|
|
779
|
+
function push (data) {
|
|
780
|
+
if (data.done) rs.push(null)
|
|
781
|
+
else rs.push(data.value)
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
static from (data, opts) {
|
|
786
|
+
if (isReadStreamx(data)) return data
|
|
787
|
+
if (data[asyncIterator]) return this._fromAsyncIterator(data[asyncIterator](), opts)
|
|
788
|
+
if (!Array.isArray(data)) data = data === undefined ? [] : [data]
|
|
789
|
+
|
|
790
|
+
let i = 0
|
|
791
|
+
return new Readable({
|
|
792
|
+
...opts,
|
|
793
|
+
read (cb) {
|
|
794
|
+
this.push(i === data.length ? null : data[i++])
|
|
795
|
+
cb(null)
|
|
796
|
+
}
|
|
797
|
+
})
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
static isBackpressured (rs) {
|
|
801
|
+
return (rs._duplexState & READ_BACKPRESSURE_STATUS) !== 0 || rs._readableState.buffered >= rs._readableState.highWaterMark
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
static isPaused (rs) {
|
|
805
|
+
return (rs._duplexState & READ_RESUMED) === 0
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
[asyncIterator] () {
|
|
809
|
+
const stream = this
|
|
810
|
+
|
|
811
|
+
let error = null
|
|
812
|
+
let promiseResolve = null
|
|
813
|
+
let promiseReject = null
|
|
814
|
+
|
|
815
|
+
this.on('error', (err) => { error = err })
|
|
816
|
+
this.on('readable', onreadable)
|
|
817
|
+
this.on('close', onclose)
|
|
818
|
+
|
|
819
|
+
return {
|
|
820
|
+
[asyncIterator] () {
|
|
821
|
+
return this
|
|
822
|
+
},
|
|
823
|
+
next () {
|
|
824
|
+
return new Promise(function (resolve, reject) {
|
|
825
|
+
promiseResolve = resolve
|
|
826
|
+
promiseReject = reject
|
|
827
|
+
const data = stream.read()
|
|
828
|
+
if (data !== null) ondata(data)
|
|
829
|
+
else if ((stream._duplexState & DESTROYED) !== 0) ondata(null)
|
|
830
|
+
})
|
|
831
|
+
},
|
|
832
|
+
return () {
|
|
833
|
+
return destroy(null)
|
|
834
|
+
},
|
|
835
|
+
throw (err) {
|
|
836
|
+
return destroy(err)
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
function onreadable () {
|
|
841
|
+
if (promiseResolve !== null) ondata(stream.read())
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
function onclose () {
|
|
845
|
+
if (promiseResolve !== null) ondata(null)
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
function ondata (data) {
|
|
849
|
+
if (promiseReject === null) return
|
|
850
|
+
if (error) promiseReject(error)
|
|
851
|
+
else if (data === null && (stream._duplexState & READ_DONE) === 0) promiseReject(STREAM_DESTROYED)
|
|
852
|
+
else promiseResolve({ value: data, done: data === null })
|
|
853
|
+
promiseReject = promiseResolve = null
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
function destroy (err) {
|
|
857
|
+
stream.destroy(err)
|
|
858
|
+
return new Promise((resolve, reject) => {
|
|
859
|
+
if (stream._duplexState & DESTROYED) return resolve({ value: undefined, done: true })
|
|
860
|
+
stream.once('close', function () {
|
|
861
|
+
if (err) reject(err)
|
|
862
|
+
else resolve({ value: undefined, done: true })
|
|
863
|
+
})
|
|
864
|
+
})
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
class Writable extends Stream {
|
|
870
|
+
constructor (opts) {
|
|
871
|
+
super(opts)
|
|
872
|
+
|
|
873
|
+
this._duplexState |= OPENING | READ_DONE
|
|
874
|
+
this._writableState = new WritableState(this, opts)
|
|
875
|
+
|
|
876
|
+
if (opts) {
|
|
877
|
+
if (opts.writev) this._writev = opts.writev
|
|
878
|
+
if (opts.write) this._write = opts.write
|
|
879
|
+
if (opts.final) this._final = opts.final
|
|
880
|
+
if (opts.eagerOpen) this._writableState.updateNextTick()
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
cork () {
|
|
885
|
+
this._duplexState |= WRITE_CORKED
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
uncork () {
|
|
889
|
+
this._duplexState &= WRITE_NOT_CORKED
|
|
890
|
+
this._writableState.updateNextTick()
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
_writev (batch, cb) {
|
|
894
|
+
cb(null)
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
_write (data, cb) {
|
|
898
|
+
this._writableState.autoBatch(data, cb)
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
_final (cb) {
|
|
902
|
+
cb(null)
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
static isBackpressured (ws) {
|
|
906
|
+
return (ws._duplexState & WRITE_BACKPRESSURE_STATUS) !== 0
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
static drained (ws) {
|
|
910
|
+
if (ws.destroyed) return Promise.resolve(false)
|
|
911
|
+
const state = ws._writableState
|
|
912
|
+
const pending = (isWritev(ws) ? Math.min(1, state.queue.length) : state.queue.length)
|
|
913
|
+
const writes = pending + ((ws._duplexState & WRITE_WRITING) ? 1 : 0)
|
|
914
|
+
if (writes === 0) return Promise.resolve(true)
|
|
915
|
+
if (state.drains === null) state.drains = []
|
|
916
|
+
return new Promise((resolve) => {
|
|
917
|
+
state.drains.push({ writes, resolve })
|
|
918
|
+
})
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
write (data) {
|
|
922
|
+
this._writableState.updateNextTick()
|
|
923
|
+
return this._writableState.push(data)
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
end (data) {
|
|
927
|
+
this._writableState.updateNextTick()
|
|
928
|
+
this._writableState.end(data)
|
|
929
|
+
return this
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
class Duplex extends Readable { // and Writable
|
|
934
|
+
constructor (opts) {
|
|
935
|
+
super(opts)
|
|
936
|
+
|
|
937
|
+
this._duplexState = OPENING | (this._duplexState & READ_READ_AHEAD)
|
|
938
|
+
this._writableState = new WritableState(this, opts)
|
|
939
|
+
|
|
940
|
+
if (opts) {
|
|
941
|
+
if (opts.writev) this._writev = opts.writev
|
|
942
|
+
if (opts.write) this._write = opts.write
|
|
943
|
+
if (opts.final) this._final = opts.final
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
cork () {
|
|
948
|
+
this._duplexState |= WRITE_CORKED
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
uncork () {
|
|
952
|
+
this._duplexState &= WRITE_NOT_CORKED
|
|
953
|
+
this._writableState.updateNextTick()
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
_writev (batch, cb) {
|
|
957
|
+
cb(null)
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
_write (data, cb) {
|
|
961
|
+
this._writableState.autoBatch(data, cb)
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
_final (cb) {
|
|
965
|
+
cb(null)
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
write (data) {
|
|
969
|
+
this._writableState.updateNextTick()
|
|
970
|
+
return this._writableState.push(data)
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
end (data) {
|
|
974
|
+
this._writableState.updateNextTick()
|
|
975
|
+
this._writableState.end(data)
|
|
976
|
+
return this
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
class Transform extends Duplex {
|
|
981
|
+
constructor (opts) {
|
|
982
|
+
super(opts)
|
|
983
|
+
this._transformState = new TransformState(this)
|
|
984
|
+
|
|
985
|
+
if (opts) {
|
|
986
|
+
if (opts.transform) this._transform = opts.transform
|
|
987
|
+
if (opts.flush) this._flush = opts.flush
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
_write (data, cb) {
|
|
992
|
+
if (this._readableState.buffered >= this._readableState.highWaterMark) {
|
|
993
|
+
this._transformState.data = data
|
|
994
|
+
} else {
|
|
995
|
+
this._transform(data, this._transformState.afterTransform)
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
_read (cb) {
|
|
1000
|
+
if (this._transformState.data !== null) {
|
|
1001
|
+
const data = this._transformState.data
|
|
1002
|
+
this._transformState.data = null
|
|
1003
|
+
cb(null)
|
|
1004
|
+
this._transform(data, this._transformState.afterTransform)
|
|
1005
|
+
} else {
|
|
1006
|
+
cb(null)
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
destroy (err) {
|
|
1011
|
+
super.destroy(err)
|
|
1012
|
+
if (this._transformState.data !== null) {
|
|
1013
|
+
this._transformState.data = null
|
|
1014
|
+
this._transformState.afterTransform()
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
_transform (data, cb) {
|
|
1019
|
+
cb(null, data)
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
_flush (cb) {
|
|
1023
|
+
cb(null)
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
_final (cb) {
|
|
1027
|
+
this._transformState.afterFinal = cb
|
|
1028
|
+
this._flush(transformAfterFlush.bind(this))
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
class PassThrough extends Transform {}
|
|
1033
|
+
|
|
1034
|
+
function transformAfterFlush (err, data) {
|
|
1035
|
+
const cb = this._transformState.afterFinal
|
|
1036
|
+
if (err) return cb(err)
|
|
1037
|
+
if (data !== null && data !== undefined) this.push(data)
|
|
1038
|
+
this.push(null)
|
|
1039
|
+
cb(null)
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
function pipelinePromise (...streams) {
|
|
1043
|
+
return new Promise((resolve, reject) => {
|
|
1044
|
+
return pipeline(...streams, (err) => {
|
|
1045
|
+
if (err) return reject(err)
|
|
1046
|
+
resolve()
|
|
1047
|
+
})
|
|
1048
|
+
})
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
function pipeline (stream, ...streams) {
|
|
1052
|
+
const all = Array.isArray(stream) ? [...stream, ...streams] : [stream, ...streams]
|
|
1053
|
+
const done = (all.length && typeof all[all.length - 1] === 'function') ? all.pop() : null
|
|
1054
|
+
|
|
1055
|
+
if (all.length < 2) throw new Error('Pipeline requires at least 2 streams')
|
|
1056
|
+
|
|
1057
|
+
let src = all[0]
|
|
1058
|
+
let dest = null
|
|
1059
|
+
let error = null
|
|
1060
|
+
|
|
1061
|
+
for (let i = 1; i < all.length; i++) {
|
|
1062
|
+
dest = all[i]
|
|
1063
|
+
|
|
1064
|
+
if (isStreamx(src)) {
|
|
1065
|
+
src.pipe(dest, onerror)
|
|
1066
|
+
} else {
|
|
1067
|
+
errorHandle(src, true, i > 1, onerror)
|
|
1068
|
+
src.pipe(dest)
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
src = dest
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
if (done) {
|
|
1075
|
+
let fin = false
|
|
1076
|
+
|
|
1077
|
+
const autoDestroy = isStreamx(dest) || !!(dest._writableState && dest._writableState.autoDestroy)
|
|
1078
|
+
|
|
1079
|
+
dest.on('error', (err) => {
|
|
1080
|
+
if (error === null) error = err
|
|
1081
|
+
})
|
|
1082
|
+
|
|
1083
|
+
dest.on('finish', () => {
|
|
1084
|
+
fin = true
|
|
1085
|
+
if (!autoDestroy) done(error)
|
|
1086
|
+
})
|
|
1087
|
+
|
|
1088
|
+
if (autoDestroy) {
|
|
1089
|
+
dest.on('close', () => done(error || (fin ? null : PREMATURE_CLOSE)))
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
return dest
|
|
1094
|
+
|
|
1095
|
+
function errorHandle (s, rd, wr, onerror) {
|
|
1096
|
+
s.on('error', onerror)
|
|
1097
|
+
s.on('close', onclose)
|
|
1098
|
+
|
|
1099
|
+
function onclose () {
|
|
1100
|
+
if (rd && s._readableState && !s._readableState.ended) return onerror(PREMATURE_CLOSE)
|
|
1101
|
+
if (wr && s._writableState && !s._writableState.ended) return onerror(PREMATURE_CLOSE)
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
function onerror (err) {
|
|
1106
|
+
if (!err || error) return
|
|
1107
|
+
error = err
|
|
1108
|
+
|
|
1109
|
+
for (const s of all) {
|
|
1110
|
+
s.destroy(err)
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
function echo (s) {
|
|
1116
|
+
return s
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
function isStream (stream) {
|
|
1120
|
+
return !!stream._readableState || !!stream._writableState
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
function isStreamx (stream) {
|
|
1124
|
+
return typeof stream._duplexState === 'number' && isStream(stream)
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
function isEnded (stream) {
|
|
1128
|
+
return !!stream._readableState && stream._readableState.ended
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
function isFinished (stream) {
|
|
1132
|
+
return !!stream._writableState && stream._writableState.ended
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
function getStreamError (stream, opts = {}) {
|
|
1136
|
+
const err = (stream._readableState && stream._readableState.error) || (stream._writableState && stream._writableState.error)
|
|
1137
|
+
|
|
1138
|
+
// avoid implicit errors by default
|
|
1139
|
+
return (!opts.all && err === STREAM_DESTROYED) ? null : err
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
function isReadStreamx (stream) {
|
|
1143
|
+
return isStreamx(stream) && stream.readable
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
function isDisturbed (stream) {
|
|
1147
|
+
return (stream._duplexState & OPENING) !== OPENING || (stream._duplexState & ACTIVE_OR_TICKING) !== 0
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
function isTypedArray (data) {
|
|
1151
|
+
return typeof data === 'object' && data !== null && typeof data.byteLength === 'number'
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
function defaultByteLength (data) {
|
|
1155
|
+
return isTypedArray(data) ? data.byteLength : 1024
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
function noop () {}
|
|
1159
|
+
|
|
1160
|
+
function abort () {
|
|
1161
|
+
this.destroy(new Error('Stream aborted.'))
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
function isWritev (s) {
|
|
1165
|
+
return s._writev !== Writable.prototype._writev && s._writev !== Duplex.prototype._writev
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
module.exports = {
|
|
1169
|
+
pipeline,
|
|
1170
|
+
pipelinePromise,
|
|
1171
|
+
isStream,
|
|
1172
|
+
isStreamx,
|
|
1173
|
+
isEnded,
|
|
1174
|
+
isFinished,
|
|
1175
|
+
isDisturbed,
|
|
1176
|
+
getStreamError,
|
|
1177
|
+
Stream,
|
|
1178
|
+
Writable,
|
|
1179
|
+
Readable,
|
|
1180
|
+
Duplex,
|
|
1181
|
+
Transform,
|
|
1182
|
+
// Export PassThrough for compatibility with Node.js core's stream module
|
|
1183
|
+
PassThrough
|
|
1184
|
+
}
|