Skip to content

Commit

Permalink
add node support, cancellable tasks and modules support #3
Browse files Browse the repository at this point in the history
  • Loading branch information
tbela99 committed Jun 27, 2023
1 parent 2ee11dc commit f064315
Show file tree
Hide file tree
Showing 31 changed files with 3,188 additions and 1,115 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
197 changes: 127 additions & 70 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +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 @@ -19,48 +19,66 @@ import {
dispose
} from "@tbela99/workerize";

const Rectangle = workerize(class {
// do node stuff
```

construct(width, height) {
## Web browser browser usage

this.width = width;
this.height = height;
}
```javascript

getWidth() {
return this.width;
}
import {
workerize,
dispose
} from "@tbela99/workerize/web";

getHeight() {
return this.height;
}
// do browser stuff
```

getSurface() {
Alternatively, you can use the 'browser.js' script which uses the UMD module format.

return this.width * this.height;
}
});
```html

<script src="dist/browser.js"></script>
<script>
const func = workerize.workerize(function () {
// do something
})
</script>
```

const rectangle = new Rectangle(20, 12);

const width = await rectangle.getWidth();
## Using a function

The function is turned into an async proxy.

### Web example
```javascript

console.log({width});
import {
workerize,
dispose
} from "@tbela99/workerize/web";

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

console.log({surface});
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

The function is turned into an async proxy
All class methods are turned into async proxies.

### Node example

```javascript

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

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

return [].slice.apply(arguments);
});
type;
name;
age;

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

console.log({
response: response.join(' ')
});
this.type = type;
this.age = age;
this.name = name;

const func2 = workerize(async function () {
if (name === '') {

return [].slice.apply(arguments);
});
let number = Math.floor(3 + 3 * Math.random());

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

const func3 = workerize(async (...args) => ['func3'].concat(args));
this.name += String.fromCharCode([65, 97][Math.floor(2 * Math.random())] + Math.floor(26 * Math.random()))
}
}
}

response = await func3('async', 'function', 'running', 'from', 'worker');
say() {

console.log({
response: response.join(' - ')
return `${this.name} says: I am a ${this.age} year(s) old ${this.type}`;
}
});

const func4 = workerize((...args) => ['func4'].concat(args));
// create an instance
const dog = new Class('Dog', 2, 'Marvin');

response = await func4('arrow', 'function', 'running', 'from', 'worker');

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,31 +137,69 @@ import {
dispose
} from "@tbela99/workerize";

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

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

return cat.say();
}, ['./js/animal.js']);
const result = await func(5, 43, 10);

const message = await animal('Cat', 2, 'Charlie');
console.log(result); // 58

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']);
## Injecting modules

```javascript

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

const sum = await compute(15, -5, 1);
const func = workerize(function (...args) {

console.log(sum); // 11
// 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);

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

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

console.log(result); // 58

dispose(func);

dispose(animal, compute);
```

## 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
Expand All @@ -156,3 +209,7 @@ 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 f064315

Please sign in to comment.