Giter VIP home page Giter VIP logo

async-worker-ts's Introduction

async-worker-ts

async-worker-ts is a lightweight TypeScript package designed to simplify the execution of asynchronous workers in TypeScript applications. It provides a simple and efficient way to manage asynchronous tasks in the background, allowing you to offload time-consuming operations without blocking the main thread.

Features

  • Asynchronous Workers: Easily create and run asynchronous workers in TypeScript.
  • True multithreading: Execute procedures in multiple threads simultaneously to improve performance.
  • Promise-based API: Simple and intuitive API based on Promises for easy integration.

Installation

Install the package using npm:

npm install async-worker-ts

or

pnpm add async-worker-ts
import createWorker, { task } from "async-worker-ts"

const worker = createWorker({
  calculatePi: (iterations: number) => {
    let pi = 0
    for (let i = 0; i < iterations; i++) {
      pi += Math.pow(-1, i) / (2 * i + 1)
    }
    return pi * 4
  },

  todos: {
    get: () => {
      // ...
    },
    add: () => {
      // ...
    },
    delete: () => {
      // ...
    },
  },
})

await worker.calculatePi(1_000_000).then(console.log) // 3.14159265258979
await worker.exit() // terminates the worker thread

Accessing procedures within procedures:

import useWorker from "async-worker-ts"

const worker = useWorker({
  /**
   * NB; the 'this' keyword is available in procedures declared as anything
   * but arrow functions and can be used to access other procedures.
   */
  addRandomNumbers: function () {
    const a = this.randomNumber()
    const b = this.randomNumber()
    return a + b
  },
  randomNumber: () => {
    return Math.random() * 42
  },
})

Emitting data via Tasks:

import useWorker, { task } from "async-worker-ts"

const worker = useWorker({
  calculatePi: task(function (iterations: number) {
    let pi = 0
    for (let i = 0; i < iterations; i++) {
      pi += Math.pow(-1, i) / (2 * i + 1)

      // the "this" keyword in the context of a task refers to the task itself.
      if (i % (iterations / 100) === 0) this.emit("progress", i / iterations)
    }
    return pi * 4
  }),
})

await worker
  .calculatePi(1_000_000)
  .on("progress", console.log) // 0.01, 0.02, ...
  .then(console.log) // 3.14159265258979

Concurrency and batching:

import useWorker from "async-worker-ts"

const worker = useWorker({
  calculatePi: (iterations: number) => {
    let pi = 0
    for (let i = 0; i < iterations; i++) {
      pi += Math.pow(-1, i) / (2 * i + 1)
    }
    return pi * 4
  },
})

/**
 * We can use the 'concurrently' method to run a task from the worker
 * client in a new auto-disposed worker thread.
 */
worker.concurrently((w) => w.calculatePi(1_000_000)) // 3.14159265258979

/** or: */
for (let i = 0; i < 4; i++) {
  worker.concurrently((w) => w.calculatePi(1_000_000))
}

Transferables:

import useWorker, { transfer } from "async-worker-ts"

const worker = useWorker({
  drawToCanvas: (OffscreenCanvas) => {
    // ... do things with the canvas here as if we were on the main thread
  },
})
const canvas = document.createElement("canvas")
const offscreenCvs = canvas.transferControlToOffscreen()

/**
 * By passing the argument through the 'transfer' function, we flag it as an
 * transferable. This is the equivalent of calling 'postMessage' with the
 * second argument being an array containing the argument.
 */
worker.drawToCanvas(transfer(offscreenCvs))

Dynamic imports and module resolution:

Importing modules requires a bundler for module resolution because procedures are serialized and executed in a different scope, rendering relative paths useless. I created awt-bundler as a simple bundler for using this package with Node.

someModule.ts:

export const someFunction = () => {
  // ...
}

myWorker.ts:

import useWorker, { AWTClientBuilder } from "async-worker-ts"

const worker = useWorker({
  doSomething: async () => {
    const { someFunction } = await import("./someModule.ts")
    return someFunction()
  },
})

// or:

const workerWithCachedImports = new AWTClientBuilder()
  .withImportCache(async () => {
    const { someFunction } = await import("./someModule.js")
    return { someFunction }
  })
  .build(function ({ someFunction }) {
    return {
      doSomething: () => {
        return someFunction()
      },
    }
  })

God help your CPU. ๐Ÿ™

Richard Ayoade using async-worker-ts

Contributing

We welcome contributions from the community. To contribute to async-worker-ts, please follow our contribution guidelines.

License

This package is licensed under the GNUV3 License - see the LICENSE file for details.

async-worker-ts's People

Contributors

lankymoose avatar statulr avatar

Stargazers

Daniele avatar L avatar  avatar Hatem Hosny avatar Marcis Bergmanis avatar Christopher Yovanovitch avatar Kainoa Kanter avatar Brandon avatar salah alhashmi avatar

Watchers

 avatar

Forkers

statulr

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.