npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

arbeiter

v0.0.9

Published

A worker-helper for in-browser.</br> Allows for dynamically creating workers with manageable state.

Downloads

2

Readme

Arbeiter

A worker-helper for in-browser. Allows for dynamically creating workers with manageable state.

How to use

  • simple example
import Arbeiter from "arbeiter";

// The arbeiters' types have to be explicitly typed inside Arbeiter's generic.
const arbeiter = new Arbeiter<{ 
  counter: number; 
  increment: () => number 
}>();

const { methods, terminate } = arbeiter.construct(() => ({
  counter: 0,
  increment: function () {
    // only state accessed with `this` can be manipulated
    return this.counter++;
  },
}));

// All functions are converted into async functions
// and are accessible in `methods`
methods.increment().then(
  value => value // 1
);
  • transfer OffscreenCanvas
import Factory from "arbeiter";

const arbeiter = new Arbeiter<{
  canvas?: OffscreenCanvas,
  context?:
  transfer: (canvas: OffscreenCanvas) => void
  fill: (color: string) => void
}>();

const { methods, terminate } = arbeiter.construct(() => ({
  canvas: undefined,
  transfer: function (canvas) {
    this.canvas = canvas;
    this.context = this.canvas.getContext('2d');
  },
  fill: function(color) {
    if (!this.context) return;
    this.context.fillStyle = color;
    this.context.fillRect(0, 0, 100, 100);
  }
}));

const canvas = document.createElement('canvas');

// Transferable objects are automagically transferred
methods.transfer(canvas.transferControlToOffscreen()).then(
  () => methods.fill("red")
)
  • function-parameters
import Arbeiter from "arbeiter";

const arbeiter = new Arbeiter<{
  func: (callback: (number: number) => void) => void;
}>();

const { methods, terminate } = arbeiter.construct(() => ({
  func: function (callback) {
    callback(Math.random());
  },
}));

// All functions passed as arguments have to be serializable 
// Variables available on `this` can be accessed and manipulated
methods.func(number => 
  console.log("random number", number)
); // worker will log `random number 0.1522...`
methods.func(number => 
  console.log("number random", number)
); // worker will log `number random 0.1522...`

// Functions can normally not be serialized with workers
// To be able to pass and execute the function
// Arbeiter uses `.toString` and `eval` under the hood 

// `eval` has performance and security implications, so be careful.
  • options-config
// You can disable passing around and `eval`ing functions 
// with an optional secondary parameter
arbeiter.construct(
  () => ({
    func: function (callback) {
      // will give type-error, since callback will be a string
      callback(Math.random());
    },
  }),
  {
    eval: false,
  }
);

// if options.methods[methodName].eval is defined, 
// it will overwrite the global config
arbeiter.construct(
  () => ({
    func: function (callback) {
      // will give type-error, since callback will be a string
      callback(Math.random());
    },
  }),
  {
    eval: true,
    methods: {
      func: {
        eval: false,
      },
    },
  }
);
// If you want to remove the overhead of the arbeiter 
// responding back after each execution
// You can disable this functionality inside 
// the config with the `async`-parameter

// The methods affected will not be cast to a sync function
// but the async functions will never resolve

const { methods } = arbeiter.construct(
  () => ({
    func: function (callback) {
      return "resolved";
    },
  }),
  {
    async: false,
  }
);

methods.func().then(message => 
  console.log(message)
); // console.log() will never be called

// Just as with `eval`, `async` can be configured for individual methods too
const { methods, terminate } = factory.construct(
  () => ({
    func: function (callback) {
      return "resolved";
    },
  }),
  {
    async: false,
    methods: {
      func: {
        async: true,
      },
    },
  }
);

methods.func().then(message => 
  console.log(message)
); // console.log() will be called
  • terminate workers
import Factory from "arbeiter";

const arbeiter = new Arbeiter<{}>();

const { methods, terminate } = arbeiter.construct(() => ({}));

// Individual workers can be terminated with terminate()
terminate()

// To terminate all workers constructed with the arbeiter
arbeiter.terminate()

Acknowledgements

I took the idea of making workers dynamically with .toString from worktank. worktank's focus is pooling, pure functions (in dynamic mode) and isomorphic code. arbeiter does not have any pooling-functionality currently, allows for state to be initialized/managed, and is currently only available in-browser.