Skip to content

Commit

Permalink
Merge pull request #2 from tbela99/v2
Browse files Browse the repository at this point in the history
- implement module support
- implement node worker 
- implement cancellable tasks
  • Loading branch information
tbela99 authored Jun 27, 2023
2 parents 9af779c + f064315 commit c91f20a
Show file tree
Hide file tree
Showing 31 changed files with 3,236 additions and 1,129 deletions.
30 changes: 30 additions & 0 deletions .github/workflows/node.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs

name: Node.js CI

on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]

jobs:
build:

runs-on: ubuntu-latest

strategy:
matrix:
node-version: [16.x, 18.x, 20.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/

steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- run: npm install
# - run: npm run build
- run: npm test
213 changes: 134 additions & 79 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
# Workerize
Export functions or class into a service worker context.

Export functions or class into a worker context in nodejs and web browser. Tasks are cancellable.

## Installation

```shell
$ npm i @tbela99/workerize
```

## Using a class
the

All class methods are turned into async proxies
## Node usage

```javascript

Expand All @@ -18,47 +19,66 @@ import {
dispose
} from "@tbela99/workerize";

(async function () {
// do node stuff
```

const Rectangle = workerize(class {
## Web browser browser usage

construct (width, height) {
```javascript

this.width = width;
this.height = height;
}
import {
workerize,
dispose
} from "@tbela99/workerize/web";

getWidth() { return this.width; }
// do browser stuff
```

getHeight() { return this.height; }
Alternatively, you can use the 'browser.js' script which uses the UMD module format.

getSurface () {
```html

return this.width * this.height;
}
});
<script src="dist/browser.js"></script>
<script>
const rectangle = new Rectangle(20, 12);
const func = workerize.workerize(function () {
// do something
})
</script>
```

const width = await rectangle.getWidth();

console.log({width});

const surface = await rectangle.getSurface();

console.log({surface});
## Using a function

// ...
The function is turned into an async proxy.

### Web example
```javascript

import {
workerize,
dispose
} from "@tbela99/workerize/web";

// async and arrow functions can be passed as well
const func = workerize(function (...args) {

return args.reduce((acc, curr) => acc + curr, 0);
});

response = await func(1, 2, 70); // 74

// terminate the service worker
dispose(func);

// later terminate the worker
dispose(rectangle);
})();
```

## Using a function
## Using a class

All class methods are turned into async proxies.

The function is turned into an async proxy
### Node example

```javascript

Expand All @@ -67,53 +87,48 @@ import {
dispose
} from "@tbela99/workerize";

(async function () {
// pass a class definition
const Class = workerize(class {

const func = workerize(function () {
type;
name;
age;

return [].slice.apply(arguments);
});
constructor(type, age, name = '') {

response = await func('function', 'running', 'from', 'worker');
this.type = type;
this.age = age;
this.name = name;

console.log({
response: response.join(' ')
});
if (name === '') {

const func2 = workerize(async function () {
let number = Math.floor(3 + 3 * Math.random());

return [].slice.apply(arguments);
});
while (number--) {

response = await func2('async', 'function', 'running', 'from', 'worker');
console.log({
response: response.join(' ')
});

const func3 = workerize(async (...args) => ['func3'].concat(args));

response = await func3('async', 'function', 'running', 'from', 'worker');
this.name += String.fromCharCode([65, 97][Math.floor(2 * Math.random())] + Math.floor(26 * Math.random()))
}
}
}

console.log({
response: response.join(' - ')
});
say() {

const func4 = workerize((...args) => ['func4'].concat(args));
return `${this.name} says: I am a ${this.age} year(s) old ${this.type}`;
}
});

response = await func4('arrow', 'function', 'running', 'from', 'worker');
// create an instance
const dog = new Class('Dog', 2, 'Marvin');

console.log({
response: response.join(' - ')
});
console.log(await dog.say()); // 'Marin says: I am a 2 years(s) old Dog'

// terminate the service workers
dispose(instance, func, func2, func3, func4);
})();
// terminate the service worker
dispose(dog);

```
## Injecting dependencies

you can inject javascript libraries into the worker context
You can inject javascript libraries into the worker context.

```javascript

Expand All @@ -122,39 +137,79 @@ import {
dispose
} from "@tbela99/workerize";

(async function () {
const func = workerize(function (...args) {

const animal = workerize(function (...args) {
// sum function is defined in ./js/sum.js
return sum(...args);
}, {dependencies: ['./js/sum.js']});

// Animal is defined in './js/animal.js'
const cat = new Animal(...args)
const result = await func(5, 43, 10);

return cat.say();
}, ['./js/animal.js']);
console.log(result); // 58

const message = await animal('Cat', 2, 'Charlie');

console.log(message); // "Charlie says: I am a 2 year(s) old Cat"
dispose(func);

const compute = workerize(function (...args: number[]) {
```

// sum is defined in './js/sum.js'
return sum(...args);
}, ['./js/sum.js']);

const sum = await compute(15, -5, 1);

console.log(sum); // 11
## Injecting modules

```javascript

import {
workerize,
dispose
} from "@tbela99/workerize";

const func = workerize(function (...args) {

// an array called 'modules' containing the declared modules is injected in the scope
// modules are in the same order they are declared
// add is exported by the module ./js/add.js
return modules[0].add(...args);

dispose(animal, compute);
})();
}, {dependencies: ['./js/add.js'], module: true});

const result = await func(5, 43, 10);

console.log(result); // 58

dispose(func);

```

## Documentation

### Workerize

parameters:
- _task_: function or class to execute in the worker context.
- _options_: optional, worker options.

worker options:
- _dependencies_: array. an array of javascript files to inject as module or dependencies
- _module_: boolean. If true, dependencies are injected as modules. A variable of type array called 'modules' will be injected in the scope. it contains the injected modules in the same order as they were injected.
- _signal_: optional. AbortSignal instance used to abort the worker execution and delete it

### Dispose

Delete the worker instance.

#### Usage

```javascript

dispose(worker1 [, worker2, ..., workern]);
```
## A note about the proxies parameters

All parameters you pass to the proxy must be [transferable](https://developer.mozilla.org/en-US/docs/Web/API/Transferable). Objects will be serialized and deserialized as JSON data. All methods, property settter and getter are removed.
All parameters you pass to the proxy must
be [transferable](https://developer.mozilla.org/en-US/docs/Web/API/Transferable). Objects will be serialized and
deserialized as JSON data. All methods, property settter and getter are removed.

## License

MIT OR LGPL-3.0

---

Thanks to [Jetbrains](https://jetbrains.com) for providing a free WebStorm license
Loading

0 comments on commit c91f20a

Please sign in to comment.