Commit 1fc9d0b
Changed files (5)
src/core.ts
@@ -47,8 +47,8 @@ import {
log,
isString,
isStringLiteral,
- bufToString,
getLast,
+ getLines,
noop,
once,
parseBool,
@@ -601,26 +601,19 @@ export class ProcessPromise extends Promise<ProcessOutput> {
// Async iterator API
async *[Symbol.asyncIterator](): AsyncIterator<string> {
- let last: string | undefined
- const getLines = (chunk: Buffer | string) => {
- const lines = ((last || '') + bufToString(chunk)).split('\n')
- last = lines.pop()
- return lines
- }
+ const memo: (string | undefined)[] = []
for (const chunk of this._zurk!.store.stdout) {
- const lines = getLines(chunk)
- for (const line of lines) yield line
+ yield* getLines(chunk, memo)
}
for await (const chunk of this.stdout[Symbol.asyncIterator]
? this.stdout
: VoidStream.from(this.stdout)) {
- const lines = getLines(chunk)
- for (const line of lines) yield line
+ yield* getLines(chunk, memo)
}
- if (last) yield last
+ if (memo[0]) yield memo[0]
if ((await this.exitCode) !== 0) throw this._output
}
@@ -758,13 +751,23 @@ export class ProcessOutput extends Error {
}
lines(): string[] {
- return this.valueOf().split(/\r?\n/)
+ return [...this]
}
valueOf(): string {
return this.stdall.trim()
}
+ *[Symbol.iterator](): Iterator<string> {
+ const memo: (string | undefined)[] = []
+
+ for (const chunk of this._dto.store.stdall) {
+ yield* getLines(chunk, memo)
+ }
+
+ if (memo[0]) yield memo[0]
+ }
+
static getExitMessage = formatExitMessage
static getErrorMessage = formatErrorMessage;
src/util.ts
@@ -383,3 +383,12 @@ export const toCamelCase = (str: string) =>
export const parseBool = (v: string): boolean | string =>
({ true: true, false: false })[v] ?? v
+
+export const getLines = (
+ chunk: Buffer | string,
+ next: (string | undefined)[]
+) => {
+ const lines = ((next.pop() || '') + bufToString(chunk)).split(/\r?\n/)
+ next.push(lines.pop())
+ return lines
+}
test/smoke/node.test.mjs
@@ -19,6 +19,7 @@ import 'zx/globals'
{
const p = await $`echo foo`
assert.match(p.stdout, /foo/)
+ assert.deepEqual(p.lines(), ['foo'])
}
// captures err stack
test/core.test.js
@@ -1162,6 +1162,21 @@ describe('core', () => {
globalThis.Blob = Blob
})
+ test('[Symbol.Iterator]', () => {
+ const o = new ProcessOutput({
+ store: {
+ stdall: ['foo\nba', 'r\nbaz'],
+ },
+ })
+ const lines = []
+ const expected = ['foo', 'bar', 'baz']
+ for (const line of o) {
+ lines.push(line)
+ }
+ assert.deepEqual(lines, expected)
+ assert.deepEqual(o.lines(), expected)
+ })
+
describe('static', () => {
test('getExitMessage()', () => {
assert.match(
.size-limit.json
@@ -2,7 +2,7 @@
{
"name": "zx/core",
"path": ["build/core.cjs", "build/util.cjs", "build/vendor-core.cjs"],
- "limit": "77 kB",
+ "limit": "77.5 kB",
"brotli": false,
"gzip": false
},
@@ -30,7 +30,7 @@
{
"name": "all",
"path": "build/*",
- "limit": "849 kB",
+ "limit": "850 kB",
"brotli": false,
"gzip": false
}