diff --git a/dev/deps.ts b/dev/deps.ts index bfac5a5..378fb1a 100644 --- a/dev/deps.ts +++ b/dev/deps.ts @@ -1,2 +1,2 @@ export * as path from "../tests/deps/path.ts"; -export * as colors from "https://deno.land/std@0.207.0/fmt/colors.ts"; +export * as colors from "https://deno.land/std@0.208.0/fmt/colors.ts"; diff --git a/dev/lines/consume.ts b/dev/lines/consume.ts new file mode 100644 index 0000000..f0d5582 --- /dev/null +++ b/dev/lines/consume.ts @@ -0,0 +1,8 @@ +import { blue } from "https://deno.land/std@0.208.0/fmt/colors.ts"; +import { run } from "../../mod.ts"; + +const produce = import.meta.resolve("./produce.ts"); + +for await (const line of run("deno", "run", produce).lines) { + console.log(`${blue(new Date().toISOString())} ${line}`); +} diff --git a/dev/lines/produce.ts b/dev/lines/produce.ts new file mode 100644 index 0000000..a5ae71a --- /dev/null +++ b/dev/lines/produce.ts @@ -0,0 +1,19 @@ +import { sleep } from "../../mod.ts"; + +let count = 0; + +for (;;) { + console.log(`${new Date().toISOString()} ${count++}\nx\ny\nz`); + await sleep(1000 + Math.random() * 10000); +} + +// for (let j = 0; j < 10000000; j++) { +// const acc: string[] = []; +// for (let i = 0; i < 1000; i++) { +// acc.push( +// `${j}:${i} dsjkslfsjldjflskjflsdjfljslkdfjsdlkfjskjklsdjflksjdklsjldjfskdfsfdlsjfksl`, +// ); +// } +// console.log(acc.join("")); +// await sleep(10000); +// } diff --git a/legacy/deps-test.ts b/legacy/deps-test.ts index 13cebea..7d008a6 100644 --- a/legacy/deps-test.ts +++ b/legacy/deps-test.ts @@ -1,3 +1,3 @@ -export * from "https://deno.land/std@0.207.0/testing/asserts.ts"; +export * from "https://deno.land/std@0.208.0/testing/asserts.ts"; export * from "https://deno.land/x/asynciter@0.0.18/mod.ts"; -export * from "https://deno.land/std@0.207.0/fmt/colors.ts"; +export * from "https://deno.land/std@0.208.0/fmt/colors.ts"; diff --git a/legacy/deps.ts b/legacy/deps.ts index 17d59d0..fb7cc7a 100644 --- a/legacy/deps.ts +++ b/legacy/deps.ts @@ -1,2 +1,2 @@ -export * from "https://deno.land/std@0.207.0/async/mod.ts"; -export * from "https://deno.land/std@0.207.0/io/mod.ts"; +export * from "https://deno.land/std@0.208.0/async/mod.ts"; +export * from "https://deno.land/std@0.208.0/io/mod.ts"; diff --git a/legacy/examples/pushiterable/example-of-pushiterable.ts b/legacy/examples/pushiterable/example-of-pushiterable.ts index 83c7812..3f62cbb 100755 --- a/legacy/examples/pushiterable/example-of-pushiterable.ts +++ b/legacy/examples/pushiterable/example-of-pushiterable.ts @@ -4,7 +4,7 @@ import { Answer, Question } from "./common-json-defs.ts"; import * as proc from "../../mod.ts"; import { WritableIterable } from "../../../mod1.ts"; import { asynciter } from "https://deno.land/x/asynciter@0.0.18/mod.ts"; -import { blue, red } from "https://deno.land/std@0.207.0/fmt/colors.ts"; +import { blue, red } from "https://deno.land/std@0.208.0/fmt/colors.ts"; /** * This demonstrates sending objects to and receiving objects from a child process diff --git a/legacy/runners/constants.ts b/legacy/runners/constants.ts index 76867dd..ac7f4e9 100644 --- a/legacy/runners/constants.ts +++ b/legacy/runners/constants.ts @@ -1,4 +1,4 @@ -import { isWindows } from "https://deno.land/std@0.207.0/path/_os.ts"; +import { isWindows } from "https://deno.land/std@0.208.0/path/_os.ts"; export const LINESEP: string = (() => { if (isWindows) { diff --git a/legacy/runners/handlers/bytes.test.ts b/legacy/runners/handlers/bytes.test.ts index 18e7aec..8813c09 100644 --- a/legacy/runners/handlers/bytes.test.ts +++ b/legacy/runners/handlers/bytes.test.ts @@ -1,4 +1,4 @@ -import { assertEquals } from "https://deno.land/std@0.207.0/testing/asserts.ts"; +import { assertEquals } from "https://deno.land/std@0.208.0/testing/asserts.ts"; import * as proc from "../../mod.ts"; Deno.test({ diff --git a/legacy/runners/utility.ts b/legacy/runners/utility.ts index 6f4f59f..1542b2f 100644 --- a/legacy/runners/utility.ts +++ b/legacy/runners/utility.ts @@ -1,5 +1,5 @@ import { BufReader, BufWriter } from "../deps.ts"; -import * as path from "https://deno.land/std@0.207.0/path/mod.ts"; +import * as path from "https://deno.land/std@0.208.0/path/mod.ts"; export const DEFAULT_BUFFER_SIZE = 4096; diff --git a/legacy/tests/line-split.test.ts b/legacy/tests/line-split.test.ts index c1ae04a..6f0327c 100644 --- a/legacy/tests/line-split.test.ts +++ b/legacy/tests/line-split.test.ts @@ -1,4 +1,4 @@ -import { assertEquals } from "https://deno.land/std@0.207.0/testing/asserts.ts"; +import { assertEquals } from "https://deno.land/std@0.208.0/testing/asserts.ts"; import * as proc from "../mod.ts"; Deno.test({ diff --git a/legacy/tests/piped.test.ts b/legacy/tests/piped.test.ts index 80d6845..4458537 100644 --- a/legacy/tests/piped.test.ts +++ b/legacy/tests/piped.test.ts @@ -1,4 +1,4 @@ -import { assertEquals } from "https://deno.land/std@0.207.0/testing/asserts.ts"; +import { assertEquals } from "https://deno.land/std@0.208.0/testing/asserts.ts"; import * as proc from "../mod.ts"; Deno.test({ diff --git a/site/scripts/deps/path.ts b/site/scripts/deps/path.ts index f949bb6..416183c 100644 --- a/site/scripts/deps/path.ts +++ b/site/scripts/deps/path.ts @@ -1 +1 @@ -export * from "https://deno.land/std@0.207.0/path/posix.ts"; +export * from "https://deno.land/std@0.208.0/path/posix.ts"; diff --git a/site/scripts/process/output.ts b/site/scripts/process/output.ts index 3e6d3d9..120d267 100644 --- a/site/scripts/process/output.ts +++ b/site/scripts/process/output.ts @@ -1,4 +1,4 @@ -import { run } from "https://deno.land/x/proc@0.21.3/mod.ts"; +import { run } from "https://deno.land/x/proc@0.21.5/mod.ts"; await run("echo", "Hello, world.").forEach((it) => console.dir(it)); diff --git a/src/deps/colors.ts b/src/deps/colors.ts index 552e0b4..1af00ff 100644 --- a/src/deps/colors.ts +++ b/src/deps/colors.ts @@ -1 +1 @@ -export * from "https://deno.land/std@0.207.0/fmt/colors.ts"; +export * from "https://deno.land/std@0.208.0/fmt/colors.ts"; diff --git a/src/deps/path.ts b/src/deps/path.ts index 223fcc8..ba823f5 100644 --- a/src/deps/path.ts +++ b/src/deps/path.ts @@ -1 +1 @@ -export * from "https://deno.land/std@0.207.0/path/mod.ts"; +export * from "https://deno.land/std@0.208.0/path/mod.ts"; diff --git a/src/deps/retry.ts b/src/deps/retry.ts index 34d8270..f1c5b55 100644 --- a/src/deps/retry.ts +++ b/src/deps/retry.ts @@ -1 +1 @@ -export * from "https://deno.land/std@0.207.0/async/retry.ts"; +export * from "https://deno.land/std@0.208.0/async/retry.ts"; diff --git a/src/deps/streams.ts b/src/deps/streams.ts index aa56935..c2b0b0d 100644 --- a/src/deps/streams.ts +++ b/src/deps/streams.ts @@ -1 +1 @@ -export * from "https://deno.land/std@0.207.0/streams/mod.ts"; +export * from "https://deno.land/std@0.208.0/streams/mod.ts"; diff --git a/src/deps/tee.ts b/src/deps/tee.ts index 1945d01..32b8466 100644 --- a/src/deps/tee.ts +++ b/src/deps/tee.ts @@ -1 +1 @@ -export * from "https://deno.land/std@0.207.0/async/tee.ts"; +export * from "https://deno.land/std@0.208.0/async/tee.ts"; diff --git a/src/enumerable.ts b/src/enumerable.ts index 0dc9681..244b346 100644 --- a/src/enumerable.ts +++ b/src/enumerable.ts @@ -763,7 +763,7 @@ export class Enumerable implements AsyncIterable { * to improve performance with larger data. */ get lines(): Lines { - return enumerate(toLines(this as Enumerable)) as Lines; + return enumerate(toLines(this.iter as Enumerable)) as Lines; } /** diff --git a/src/process.ts b/src/process.ts index 0555935..b3389af 100644 --- a/src/process.ts +++ b/src/process.ts @@ -275,9 +275,7 @@ export class Process implements Deno.Closer { yield* process.stdout; } finally { status = await process.status; - if (ser != null) { - await ser; - } + await ser; } const cause = passError(); diff --git a/src/transformers.ts b/src/transformers.ts index ccbcfdd..5672288 100644 --- a/src/transformers.ts +++ b/src/transformers.ts @@ -46,6 +46,98 @@ export async function* toChunkedLines( } } +// /** +// * Convert an `AsyncIterable` into an `AsyncIterable` +// * (an array of lines chunked together based on buffer size) +// * split on `lf` and also suppressing trailing `cr`. `lf` and trailing `cr` +// * is removed from the returned lines. As this is line-oriented data, if the +// * last line is empty (the last byte was a line feed, splitting into one extra line), +// * it is suppressed. +// * +// * @param buffs The iterable bytes. +// */ +// export async function* toByteLines2( +// buffs: AsyncIterable, +// ): AsyncIterable { +// /* +// * Using subarray since that is just a view. No copy operation. Faster. +// * +// * Iterating and testing byte-wise rather than using `find()`, which requires a +// * call to a function for each byte. Should be pretty close to byte-at-a-time +// * C-style scanning. Not as fast as a SIMD operation, but that isn't an option +// * here. +// */ +// let currentLine: Uint8Array[] = []; +// let lastline: undefined | Uint8Array; + +// function bufferLine(): Uint8Array | undefined { +// function createLine(): Uint8Array { +// const line = concat(currentLine); + +// if (line.length > 0 && line[line.length - 1] === 13) { +// /* Strip the carriage return. */ +// return line.subarray(0, line.length - 1); +// } else { +// return line; +// } +// } + +// const temp = lastline; +// lastline = createLine(); +// return temp; +// } + +// try { +// for await (const buff of buffs) { +// const length = buff.length; + +// const chunk: Uint8Array[] = []; + +// let start = 0; +// for (let pos = 0; pos < length; pos++) { +// if (buff[pos] === 10) { +// if (pos) { +// currentLine.push(buff.subarray(start, pos)); +// } + +// const b = bufferLine(); +// if (b) { +// chunk.push(b); +// } + +// currentLine = []; +// start = pos + 1; +// } +// } + +// if (chunk.length > 0) { +// yield chunk; +// } + +// if (start < length) { +// currentLine.push(buff.subarray(start)); +// } +// } +// } finally { +// const chunk: Uint8Array[] = []; + +// if (currentLine.length > 0) { +// const b = bufferLine(); +// if (b) { +// chunk.push(b); +// } +// } + +// if (lastline?.length) { +// chunk.push(lastline); +// } + +// if (chunk.length > 0) { +// yield chunk; +// } +// } +// } + /** * Convert an `AsyncIterable` into an `AsyncIterable` * (an array of lines chunked together based on buffer size) @@ -59,83 +151,47 @@ export async function* toChunkedLines( export async function* toByteLines( buffs: AsyncIterable, ): AsyncIterable { - /* - * Using subarray since that is just a view. No copy operation. Faster. - * - * Iterating and testing byte-wise rather than using `find()`, which requires a - * call to a function for each byte. Should be pretty close to byte-at-a-time - * C-style scanning. Not as fast as a SIMD operation, but that isn't an option - * here. - */ - let currentLine: Uint8Array[] = []; - let lastline: undefined | Uint8Array; - - function bufferLine(): Uint8Array | undefined { - function createLine(): Uint8Array { - const line = concat(currentLine); - - if (line.length > 0 && line[line.length - 1] === 13) { - /* Strip the carriage return. */ - return line.subarray(0, line.length - 1); - } else { - return line; - } - } - - const temp = lastline; - lastline = createLine(); - return temp; - } - - try { - for await (const buff of buffs) { - const length = buff.length; - - const chunk: Uint8Array[] = []; - - let start = 0; - for (let pos = 0; pos < length; pos++) { - if (buff[pos] === 10) { - if (pos) { - currentLine.push(buff.subarray(start, pos)); - } - - const b = bufferLine(); - if (b) { - chunk.push(b); - } - - currentLine = []; - start = pos + 1; - } - } + const completeLines: Uint8Array[] = []; + const currentLine: Uint8Array[] = []; - if (chunk.length > 0) { - yield chunk; - } + function makeCurrentLineComplete() { + const line = concat(currentLine); + currentLine.length = 0; - if (start < length) { - currentLine.push(buff.subarray(start)); - } + const lineLen = line.length; + if (lineLen > 0 && line[lineLen - 1] === 13) { + completeLines.push(line.subarray(0, lineLen - 1)); + } else { + completeLines.push(line); } - } finally { - const chunk: Uint8Array[] = []; + } - if (currentLine.length > 0) { - const b = bufferLine(); - if (b) { - chunk.push(b); + for await (const buff of buffs) { + const buffLen = buff.length; + let lastPos = 0; + for (let pos = 0; pos < buffLen; pos++) { + if (buff[pos] === 10) { + currentLine.push(buff.subarray(lastPos, pos)); + makeCurrentLineComplete(); + lastPos = pos + 1; } } - - if (lastline?.length) { - chunk.push(lastline); + if (lastPos < buffLen) { + currentLine.push(buff.subarray(lastPos)); } - - if (chunk.length > 0) { - yield chunk; + if (completeLines.length > 0) { + yield completeLines; + completeLines.length = 0; } } + + if (currentLine.length > 0) { + makeCurrentLineComplete(); + } + + if (completeLines.length > 0) { + yield completeLines; + } } /** diff --git a/tests/deps/asserts.ts b/tests/deps/asserts.ts index 1177569..55cefed 100644 --- a/tests/deps/asserts.ts +++ b/tests/deps/asserts.ts @@ -1 +1 @@ -export * from "https://deno.land/std@0.207.0/assert/mod.ts"; +export * from "https://deno.land/std@0.208.0/assert/mod.ts"; diff --git a/tests/deps/colors.ts b/tests/deps/colors.ts index 552e0b4..1af00ff 100644 --- a/tests/deps/colors.ts +++ b/tests/deps/colors.ts @@ -1 +1 @@ -export * from "https://deno.land/std@0.207.0/fmt/colors.ts"; +export * from "https://deno.land/std@0.208.0/fmt/colors.ts"; diff --git a/tests/deps/path.ts b/tests/deps/path.ts index 223fcc8..ba823f5 100644 --- a/tests/deps/path.ts +++ b/tests/deps/path.ts @@ -1 +1 @@ -export * from "https://deno.land/std@0.207.0/path/mod.ts"; +export * from "https://deno.land/std@0.208.0/path/mod.ts"; diff --git a/tests/deps/streams.ts b/tests/deps/streams.ts index aa56935..c2b0b0d 100644 --- a/tests/deps/streams.ts +++ b/tests/deps/streams.ts @@ -1 +1 @@ -export * from "https://deno.land/std@0.207.0/streams/mod.ts"; +export * from "https://deno.land/std@0.208.0/streams/mod.ts"; diff --git a/tests/errors/example-errors.test.ts b/tests/errors/example-errors.test.ts index d7d48ba..62da30e 100644 --- a/tests/errors/example-errors.test.ts +++ b/tests/errors/example-errors.test.ts @@ -9,86 +9,92 @@ class BadNewsError extends Error { } } -Deno.test("error processing from stderr #1", async () => { - try { - const cmd: Cmd = [ - "bash", - "-c", - ` +Deno.test( + { name: "error processing from stderr #1", sanitizeResources: false }, + async () => { + try { + const cmd: Cmd = [ + "bash", + "-c", + ` echo "Hello," echo "world." echo "BAD-NEWS" >&2 exit 1 `, - ]; + ]; - await run({ - fnStderr: async (stderr) => { - let badResult = false; + await run({ + fnStderr: async (stderr) => { + let badResult = false; - for await (const line of stderr.lines) { - if (line.includes("BAD-NEWS")) { - badResult = true; + for await (const line of stderr.lines) { + if (line.includes("BAD-NEWS")) { + badResult = true; + } + console.error(yellow(line)); } - console.error(yellow(line)); - } - return badResult; - }, - fnError: (error?: Error, stderrData?: boolean) => { - if (stderrData === true) { - throw new BadNewsError("It's bad."); - } else if (error != null) { - throw error; - } - }, - }, ...cmd).toStdout(); + return badResult; + }, + fnError: (error?: Error, stderrData?: boolean) => { + if (stderrData === true) { + throw new BadNewsError("It's bad."); + } else if (error != null) { + throw error; + } + }, + }, ...cmd).toStdout(); - fail("expected BadNewsError but no error thrown"); - } catch (e) { - if (!(e instanceof BadNewsError)) { - fail(`expected BadNewsError error was ${e.name}`); + fail("expected BadNewsError but no error thrown"); + } catch (e) { + if (!(e instanceof BadNewsError)) { + fail(`expected BadNewsError error was ${e.name}`); + } } - } -}); + }, +); -Deno.test("error processing from stderr #2", async () => { - try { - const cmd: Cmd = [ - "bash", - "-c", - ` +Deno.test( + { name: "error processing from stderr #2", sanitizeResources: false }, + async () => { + try { + const cmd: Cmd = [ + "bash", + "-c", + ` echo "Hello," echo "world." echo "BAD-NEWS" >&2 exit 1 `, - ]; + ]; - await run({ - fnStderr: async (stderr) => { - let badResult = false; + await run({ + fnStderr: async (stderr) => { + let badResult = false; - for await (const line of stderr.lines) { - if (line.includes("BAD-NEWS")) { - badResult = true; + for await (const line of stderr.lines) { + if (line.includes("BAD-NEWS")) { + badResult = true; + } + console.error(yellow(line)); } - console.error(yellow(line)); - } - if (badResult) { - throw new BadNewsError("It's bad, but at least it is simple."); - } - }, - }, ...cmd).toStdout(); + if (badResult) { + throw new BadNewsError("It's bad, but at least it is simple."); + } + }, + }, ...cmd).toStdout(); - fail("expected BadNewsError but no error thrown"); - } catch (e) { - if (!(e instanceof BadNewsError)) { - fail(`expected BadNewsError error was ${e.name}`); + fail("expected BadNewsError but no error thrown"); + } catch (e) { + if (!(e instanceof BadNewsError)) { + fail(`expected BadNewsError error was ${e.name}`); + } } - } -}); + }, +); Deno.test("error suppression", async () => { const cmd: Cmd = [ diff --git a/tools/deps/colors.ts b/tools/deps/colors.ts index 552e0b4..1af00ff 100644 --- a/tools/deps/colors.ts +++ b/tools/deps/colors.ts @@ -1 +1 @@ -export * from "https://deno.land/std@0.207.0/fmt/colors.ts"; +export * from "https://deno.land/std@0.208.0/fmt/colors.ts"; diff --git a/tools/deps/crypto.ts b/tools/deps/crypto.ts index 8b6dee5..e7417fa 100644 --- a/tools/deps/crypto.ts +++ b/tools/deps/crypto.ts @@ -1 +1 @@ -export * from "https://deno.land/std@0.207.0/crypto/mod.ts"; +export * from "https://deno.land/std@0.208.0/crypto/mod.ts"; diff --git a/tools/deps/path.ts b/tools/deps/path.ts index 223fcc8..ba823f5 100644 --- a/tools/deps/path.ts +++ b/tools/deps/path.ts @@ -1 +1 @@ -export * from "https://deno.land/std@0.207.0/path/mod.ts"; +export * from "https://deno.land/std@0.208.0/path/mod.ts"; diff --git a/tools/deps/retry.ts b/tools/deps/retry.ts index 34d8270..f1c5b55 100644 --- a/tools/deps/retry.ts +++ b/tools/deps/retry.ts @@ -1 +1 @@ -export * from "https://deno.land/std@0.207.0/async/retry.ts"; +export * from "https://deno.land/std@0.208.0/async/retry.ts"; diff --git a/version.json b/version.json index 67d4e49..2d30bce 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version":"0.21.5"} +{"version":"0.21.6"}