ತಂಗಿ [tangi] Kan. younger sister
ಅಕ್ಕ [akka] Kan. older sister
Lightweight actor library for Web Workers inspired by Akka.
Type-safe, production-ready and lightweight messaging layer for Web Workers.
For people to scale Web Workers beyond the simple patterns of communication.
Run npx http-server . and open index.html:
index.html
<scripttype="module">import{makeActorContext}from"https://esm.sh/@pricingmonkey/tangi";constworker=newWorker(newURL('./worker.js',import.meta.url),{type: 'module'});constworkerRemoteContext=makeActorContext(worker);constresponse=workerRemoteContext.ask(id=>({_tag: "PING", id }));switch(response._tag){case"Right": {console.log(response.right);break;}case"Left": {console.error(response.left);break;}}</script>worker.js
import{makeActorContext}from"https://esm.sh/@pricingmonkey/tangi";constworkerLocalContext=makeActorContext(self);workerLocalContext.receiveMessage(message=>{switch(message._tag){case"PING": {return{_tag: "Right",right: "PONG"};}}});yarn demo:web-workeryarn demo:shared-worker
Best served with:
Use workerRemoteContext.tell({ _tag: "FIRE" }). See example below:
messages.ts
typeFireMessage={_tag: "FIRE";}main.ts
import{makeActorContext}from"tangi";import{FireMessage}from"./messages";constworker=new(require("worker-loader!./worker"))();constworkerRemoteContext=makeActorContext<FireMessage,never>(worker);workerRemoteContext.tell({_tag: "FIRE"});worker.ts
import{makeActorContext}from"tangi";import{FireMessage}from"./messages";constworkerLocalContext=makeActorContext<never,FireMessage>(selfasany);workerLocalContext.receiveMessage(message=>{switch(message._tag){case"FIRE": {// trigger some logic in the WebWorker}}});Use workerRemoteContext.ask({ _tag: "PING" }) combined with workerLocalContext.receiveMessage({ _tag: "PING" }). See example below:
messages.ts
typePingMessage={_tag: "PING";}typePongMessage={_tag: "PONG";}main.ts
import{makeActorContext}from"tangi";import{PingMessage,PongMessage}from"./messages";constworker=new(require("worker-loader!./worker"))();constworkerRemoteContext=makeActorContext<PingMessage,never>(worker);constresponse=workerRemoteContext.ask<string,PongMessage>(id=>({_tag: "PING", id }));console.log(response)worker.ts
import{makeActorContext}from"tangi";import{PongMessage}from"./messages";constworkerLocalContext=makeActorContext<never,PongMessage>(selfasany);workerLocalContext.receiveMessage(message=>{switch(message._tag){case"PING": {return{_tag: "PONG"};}}});worker.ts
import{makeActorContext,makeCancellationOperator}from"tangi";typePingMessage={_tag: "PING";id: string;}typeCancelMessage={_tag: "CANCEL";id: string;}constmakeTask=(killSwitch)=>{returnasync()=>{for(leti=0;i<100000;i++){awaitfetch("http://example.org");if(killSwitch.isCancelled){return;}}}};constworkerLocalContext=makeActorContext<never,PongMessage>(selfasany);constcancellationOperator=makeCancellationOperator();workerLocalContext.receiveMessage(asyncmessage=>{switch(message._tag){case"PING": {constcancellableTask=cancellationOperator.register(message.id,message.id,makeTask);try{awaittask.promise();}finally{cancellationOperator.unregister(message.id,message.id);}return;}case"CANCEL": {cancellationOperator.cancel(message.id);return;}}});Use it to cancel multiple messages in a given group/context.
Similar to Cancellation (single message) and:
- types become:
typePingMessage={_tag: "PING";groupId: string;id: string;}typeCancelMessage={_tag: "CANCEL";groupId: string;id: string;}- cancellation operator calls change to:
cancellationOperator.register(message.contextId,message.id,task);cancellationOperator.unregister(message.contextId,message.id);cancellationOperator.cancel(message.contextId);