Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/joshlong145/span
Web Worker Abstraction For Deno Runtime
https://github.com/joshlong145/span
async-await deno javascript jsr postmessage typescript webassembly webworkers
Last synced: about 5 hours ago
JSON representation
Web Worker Abstraction For Deno Runtime
- Host: GitHub
- URL: https://github.com/joshlong145/span
- Owner: joshLong145
- License: mit
- Created: 2022-07-11T02:50:59.000Z (over 2 years ago)
- Default Branch: master
- Last Pushed: 2024-11-17T22:25:32.000Z (3 months ago)
- Last Synced: 2024-11-17T23:25:34.522Z (3 months ago)
- Topics: async-await, deno, javascript, jsr, postmessage, typescript, webassembly, webworkers
- Language: TypeScript
- Homepage:
- Size: 4.28 MB
- Stars: 3
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Span: Worker Pooling abstraction
[![Deno module](https://shield.deno.dev/x/span)](https://deno.land/x/span)
[![JSR](https://jsr.io/badges/@joshlong145/span)](https://jsr.io/@joshlong145/span)
[![Unit Test CI](https://github.com/joshLong145/Span/actions/workflows/test.yml/badge.svg)](https://github.com/joshLong145/Span/actions/workflows/test.yml)
`Span` provides a simplified way to use Web Workers in Deno and other JavaScript
runtimes. Abstracting the complexities of Web Workers of WebWorkers through a
pooling abstraction. Allowing you to define methods within a class that are
automatically translated into functions executed in a Web Worker. This module
helps manage execution state and shared memory using `SharedArrayBuffer`.## Features
- **Class-based Definition**: Define methods in a class extending
`WorkerDefinition`, which are then converted into functions that run in a Web
Worker.
- **Shared Memory**: Utilize `SharedArrayBuffer` to cache and manage execution
state.
- **Pooling**: Support for parallelization through an internal `Worker Pool` to
allow for true parallel task execution.
- **WebAssembly (WASM) Support**: Integrate and interact with WASM modules
compiled from languages such as GoLang and Rust.**note** when compiling rust through `wasm bidgen` only `--target web` is known
to be supported.## Installation
Install via Deno:
```bash
deno install -A -f https://deno.land/x/span/mod.ts
```Install via JSR (for use with Deno)
```bash
deno add @joshlong145/span
```## Example JS
```javascript
class Example extends WorkerDefinition {
public constructor() {
super();
}addOne = (
buffer: SharedArrayBuffer,
args: Record,
): SharedArrayBuffer => {
console.log("param name value: ", args.name);
const arr = new Int8Array(buffer);
arr[0] += 1;
return buffer;
}fib = (
buffer: SharedArrayBuffer,
module: Record,
): SharedArrayBuffer => {
let i;
const arr = new Uint8Array(buffer);
arr[0] = 0;
arr[1] = 1;for (i = 2; i <= module.count; i++) {
arr[i] = arr[i - 2] + arr[i - 1];
console.log(arr[i]);
}
return buffer;
}
}const example: Example = new Example();
const wrapper: InstanceWrapper = new InstanceWrapper(
example,
{} as InstanceConfiguration,
);wrapper.start();
await example.execute("addOne", {name: 'foo'}).promise.then((buf: SharedArrayBuffer) => {
console.log("add one result: ", new Int32Array(buf));
});
await example.execute("addOne", { name: "foo" }).promise.then(
(buf: SharedArrayBuffer) => {
console.log("add one result ", new Int32Array(buf)[0]);
},
);await example.execute("fib", {count: 10}).promise.then((buffer: SharedArrayBuffer) => {
console.log('fib result ', new Uint8Array(buffer));
console.log('last fib number', new Uint8Array(buffer)[10]);
});
```Usage of generated code
```javascript
class Example extends WorkerDefinition {
public constructor() {
super();
}addOne = (
buffer: SharedArrayBuffer,
args: Record,
): SharedArrayBuffer => {
console.log("param name value: ", args.name);
const arr = new Int8Array(buffer);
arr[0] += 1;
return buffer;
}fib = (
buffer: SharedArrayBuffer,
module: Record,
): SharedArrayBuffer => {
let i;
const arr = new Uint8Array(buffer);
arr[0] = 0;
arr[1] = 1;for (i = 2; i <= module.count; i++) {
arr[i] = arr[i - 2] + arr[i - 1];
console.log(arr[i]);
}
return buffer;
}
}
const example: Example = new Example();const wrapper: InstanceWrapper = new InstanceWrapper(
example,
{
outputPath: "/path/to/gen/output"
} as InstanceConfiguration,
);wrapper.create();
import { foo } from "";
await foo().then(() => {
console.log("bar");
});
```## Usage in process (uses example from above)
```javascript
const example: WorkerDefinition = new Example();const wrapper: InstanceWrapper = new InstanceWrapper(example, {
outputPath: 'output'
});wrapper.start();
await example.execute('fib' {count: 10}).promise.then((buffer: SharedArrayBuffer) => {
console.log("final fib number", new Uint8Array(buffer)[10]);
});example.terminateWorker();
```# Example JS With WASM
The below example uses a WASM module compiled from `Golang` using `tiny-go`.
Below we provide the go WASM runtime as an `addon` and give a callback for
loading the module at the given file path.```javascript
class Example extends WorkerDefinition {public constructor() {
super();
}addOne = (buffer: SharedArrayBuffer, module: any) => {
let arr = new Int8Array(buffer);
arr[0] += 1
//@ts-ignore
self.primeGenerator()
return arr.buffer
}
}const example: Example = new Example();
const wrapper: InstanceWrapper = new InstanceWrapper(example, {
addons: [
"./lib/wasm_exec_tiny.js",
],
modulePath: "./examples/wasm/primes-2.wasm",
addonLoader: (path: string) => {
return Deno.readTextFileSync(path);
},
moduleLoader: (path: string) => {
const fd = Deno.openSync(path);
//import { readAllSync } from 'https://deno.land/std/io/read_all.ts';
return readAllSync(fd);
},
});wrapper.start();
await example.execute("addOne").promise.then((buf: SharedArrayBuffer) => {
console.log("buffer returned ", new Int32Array(buf))
});example.terminateWorker();
```