accessible-worker v0.0.1-dev-11
Accessible Worker (experimental )
accessible-worker aim to make web worker more accessible in TypeScipt and meet oop(Object Oriented Programing) style
What it does?
- Use TypeScript decorator & acorn compile class into web worker source code.
Accessible Worker Define | Compiled Web Worker Souce Codes |
---|---|
Demo
- A demo is provided, accessible-worker-demo / online with codesandbox
Getting Started
Install,
npm install accessible-worker -s
oryarn add accessible-worker
Update
tsconfig.json
, for useaccessible-worker
in your project, you shold add"experimentalDecorators":true
option incompilerOptions
, look like this:{ ... "compilerOptions":{ ... "experimentalDecorators":true ... } ... }
Channel Worker
Channel Worker is designed as Sever-Client style based on event communication
Define Server I/O events like this:
// events for server to listen on type InputEvents = { COMBINE_MESSAGE: (name: { name: string }) => void, BEGIN_COUNT: () => void } // events for server to emit type OutputEvents = { COMBINED_MESSAGE: (message: string) => void, SEND_COUNT: (count: number) => void }
Implement your own Channel Worker extends
ChannelWorkerDefinition
like this:// Define Accessible Worker Description Class @AccessibleWorker() class MyAccessibleWorker extends ChannelWorkerDefinition<InputEvents, OutputEvents> { constructor() { super() this.prefix = 'Hi' } @GlobalVariable<string>() prefix: string = 'Hello' @GlobalVariable<number>() count = 0 @GlobalVariable<any>() timer: any @SubscribeMessage<InputEvents>('COMBINE_MESSAGE') async combineMessage(data: InferParams<InputEvents, 'COMBINE_MESSAGE'>) { console.log(MyOwnModule.a + MyOwnModule.b) this.emit('COMBINED_MESSAGE', `${this.prefix} ${data.name}`) } @SubscribeMessage<InputEvents>('BEGIN_COUNT') async onCount() { clearInterval(this.timer) this.count = 0 this.timer = setInterval(() => { this.count++ this.emit('SEND_COUNT', this.count) }, 1000) } }
Register your own Channel Worker with
AccessibleWorkerFactory
:// register Channel Worker const channelWorkerClient = await AccessibleWorkerFactory.registerChannelWorker<InputEvents, OutputEvents>(MyAccessibleWorker)
Now, you can use your own Channel Worker:
channelWorkerClient.on('COMBINED_MESSAGE', (msg: string) => { console.log(msg) // output // hi, okay6 }) channelWorkerClient.on('SEND_COUNT', count => { console.log(count) // output // 1 // 2 // 3 // 4 // ... }) client.emit('COMBINE_MESSAGE', {name: 'okay6'}) client.emit('BEGIN_COUNT'))
Functional Worker
Functional Worker will make a function run in web worker by proxy
Define you own function set:
const functionSet = { add: (a: number, b: number): number => { return a + b }, sub: (a: number, b: number): Promise<number> => Promise.resolve(a - b) }
Register your own function set with
AccessibleWorkerFactory
:// register Functional Worker const functionalWorker = await AccessibleWorkerFactory.registerFunctionSet(functionSet)
Now, you can your own function worker:
functionalWorker.sub(3, 1).then(res => { console.log(res) // output // 2 }) functionalWorker.add(1, 3).then(res => { console.log(res) // output // 4 })
Use third library
Cause accessible-worker is inline-worker (Javascript codes is dynamicilly created inner Blob), Same origin policy will block some request like
import {module} from 'lib'
andimportscripts
, so if we wanna use third library, we have to merge library code into web worker.accessible-worker provides a schema for integrate third library into yourt own web worker.(Now,only tested on webpack5)
First, define a module which export all you need in one constant like this:
// worker_module.ts import {v4 as uuidv4} from 'uuid' import _ from "lodash"; export const MyOwnModule = { uuid: uuidv4, endWith: _.endsWith }
Then, define your own Channel Worker or Function Worker:
import { AccessibleWorker, AccessibleWorkerFactory, ChannelWorkerDefinition, GlobalVariable, InferParams, SubscribeMessage } from "accessible-worker"; import {MyOwnModule} from "./worker_module"; type InputEvents = { IS_END_WITH: (param: {str:string, suffix:string}) => void } type OutputEvents = { END_WITH_RES: (res: boolean) => void } @AccessibleWorker({ module: { name: 'MyOwnModule', relativePath: 'accessible_worker_module' } }) class MyAccessibleWorker extends ChannelWorkerDefinition<InputEvents, OutputEvents> { @SubscribeMessage<InputEvents>('IS_END_WITH') async combineMessage(data: InferParams<InputEvents, 'IS_END_WITH'>) { this.emit('END_WITH_RES', MyOwnModule.endWith(data.str,data.suffix)) } } const functionSet = { uuid: (): string => MyOwnModule.uuid(), }
Register your own channel worker or function worker:
// register Channel Worker const channelWorkerClient = await AccessibleWorkerFactory.registerChannelWorker<InputEvents, OutputEvents>(MyAccessibleWorker) // register Functional Worker const functionalWorker = await AccessibleWorkerFactory.registerFunctionSet(functionSet,{ module: { name: 'MyOwnModule', relativePath: 'accessible_worker_module' } })
You should compile
worker_module.ts
into single js file for load, in webpack5, we can do it like this, add a new webpack config:const TerserPlugin = require("terser-webpack-plugin"); module.exports = { entry: { "accessible_worker_module": "./project/worker_module.ts", }, experiments: { outputModule: true, }, optimization: { minimize: true, minimizer: [ new TerserPlugin({ extractComments: false }), ], }, output: { publicPath: './dist/', filename: '[name].js', chunkFilename: '[name].[chunkhash].js', library: { type: "module" } }, resolve: { extensions: [".ts", ".js"], }, module: { rules: [ { test: /\.tsx?$/, use: "ts-loader", exclude: "/node-modules/" }, ] }, mode: "production" }
Add build script in
package.json
:{ ... "scripts": { ... "awm": "webpack --config webpack.aw.config.js", ... } ... }
For compile worker_module.ts once code updated, we can use webpack hook plugin
hook-shell-script-webpack-plugin
inwebpack.config.js
:module.exports = { ... plugins: [ ... new HookShellScriptPlugin({ afterEmit: ['npm run awm'] }) ... ], ... }
!!! So far, accessible-worker is experimental and only tested on webpack5
Todo
- Complete codes comments
- Complete API docs
- Support expection catch in web web worker
ChangeLog
License
Copyright (c) 2023-present, HongXiang Li
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago