JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 1
  • Score
    100M100P100Q20597F
  • License MIT

Utilities to deal with child_process native Node.js package.

Package Exports

    This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (child-process-utilities) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

    Readme

    child-process-utilities

    Memory-efficient utilities to deal with child_process native Node.js package.

    Installation

    npm i child-process-utilities

    Usage

    Iterate over the output streams of a process using async iterators

    This method does not use any sort of buffering. Which means that we do not cache the entire output into memory.

    stdout/stderr

    The values returned by stdout and stderr can be iterated directly by default.

    import { spawn } from "child-process-utilities";
    
    const childProcess = spawn(/* ... */, /* ... */, /* ... */);
    
    for await (const chunk of childProcess.output().stdout()) {
      //             ^ Uint8Array
      console.log("Chunk: %s", chunk);
    }

    split

    In the example below, the output is streamed line by line, since we're using the \n character, but any other character can be passed to split.

    import { spawn } from "child-process-utilities";
    
    const lines = spawn
      .pipe(bin.curl, ["-L", project.license.url])
      .output()
      .stdout()
      .split("\n"); // Returns an AsyncIterableIterator<string>
    for await (const line of lines) {
      console.log("This is a line: %s", line);
    }
    
    // Or
    const chunks = spawn
      .pipe(bin.curl, ["-L", project.license.url])
      .output()
      .stdout(); // `IReadableHelper` is an async iterator by itself
    for await (const chunk of chunks) {
      //             ^ Uint8Array
      console.log("Chunk: %s", line);
    }

    Please note that for performance reasons any decisive output functions can only be called once.

    const childProcess = spawn(/* ... */, /* ... */, /* ... */);
    
    childProcess.output().stderr().raw() // Do
    childProcess.output().stderr().raw() // Don't
    //             stderr ^^^^^^
    
    // stdout
    childProcess.output().stdout().raw() // Do
    childProcess.output().stdout().raw() // Don't
    //             stdout ^^^^^^

    Wait for a process to finish

    import { spawn } from "child-process-utilities";
    
    export default async function () {
      await spawn("npx", ["ts-node", "src"]).wait();
    }

    Wait for a process to finish without consuming stdout

    import { spawn } from "child-process-utilities";
    
    export default async function () {
      await spawn.pipe("npx", ["ts-node", "src"]).wait();
    }

    Get the output of a process

    String

    import { spawn } from "child-process-utilities";
    
    export default async function () {
      const { stdout, stderr } = await spawn("npx", ["ts-node", "src"]).output();
      console.log(await stdout().decode("UTF-8")); // Returns a string
      console.error(await stderr().decode("UTF-8")); // Returns a string
    }

    Uint8Array

    import { spawn } from "child-process-utilities";
    
    export default async function () {
      const { stdout, stderr } = await spawn("npx", ["ts-node", "src"]).output();
      console.log(await stdout().raw()); // Returns an Uint8Array
      console.error(await stderr().raw()); // Returns an Uint8Array
    }

    JSON

    import { spawn } from "child-process-utilities";
    
    export default async function () {
      const { stdout, stderr } = await spawn("npx", ["ts-node", "src"]).output();
      console.log(await stdout().json()); // Parses the stdout as JSON
      console.error(await stderr().json()); // Parses the stderr as JSON
    }
    JSON property type inference

    You can pass a type to the spawn function to infer the return type of the output method. Currently, we only support defining a type for the json output property.

    // (method) IReadableHelper<{ json: number; }>.json<number>(): Promise<number>
    spawn</* Using TypeScript inline types */ { json: number }>("x")
      .output()
      .stdout()
      .json(); // Promise<number>
    
    interface IVideoMetadata {
      duration: number;
      fileName: string;
    }
    
    interface IGetVideoMetadataTypes {
      json: IVideoMetadata;
    }
    
    // (method) IReadableHelper<IVideoMetadata>.json<IVideoMetadata>(): Promise<IVideoMetadata>
    spawn<IGetVideoMetadataTypes>("/home/user/get-video-metadata.sh", [
      "video.mp4" /* ... */,
    ])
      .output()
      .stdout()
      .json(); // Promise<IVideoMetadata>
    
    // (method) IReadableHelper<{ json: unknown; }>.json<unknown>(): Promise<unknown>
    spawn("x").output().stdout().json(); // Promise<unknown>

    Advantages on this approach is that you can define a spawn method that returns a predefined type:

    import { spawn } from "child-process-utilities";
    
    export interface IVideoMetadata {
      duration: number;
      fileName: string;
    }
    
    export interface IGetVideoMetadataTypes {
      json: IVideoMetadata;
    }
    
    const getVideoMetadata = (url: string) =>
      spawn<IGetVideoMetadataTypes>("/home/user/get-video-metadata.sh", [url]);
    
    export default getVideoMetadata;
    import getVideoMetadata from "./getVideoMetadata";
    
    export default async function askForVideoMetadata() {
      const pendingVideoMetadata = getVideoMetadata("video.mp4");
      const error = await pendingVideoMetadata.output().stderr().raw();
    
      try {
        const videoMetadata = await pendingVideoMetadata.output().stdout().json();
      } catch (error) {
        process.stderr.write(error);
      }
    }