@thi.ng/rstream
Version:
Reactive streams & subscription primitives for constructing dataflow graphs / pipelines
64 lines (63 loc) • 1.63 kB
JavaScript
import { State } from "./api.js";
import { __nextID } from "./idgen.js";
import { LOGGER } from "./logger.js";
import { Subscription } from "./subscription.js";
import { defWorker } from "./defworker.js";
const tunnel = (opts) => new Tunnel(opts);
class Tunnel extends Subscription {
workers;
src;
transferables;
terminate;
interrupt;
index;
constructor(opts) {
super(void 0, { id: opts.id || `tunnel-${__nextID()}` });
this.src = opts.src;
this.workers = new Array(opts.maxWorkers || 1);
this.transferables = opts.transferables;
this.terminate = opts.terminate || 1e3;
this.interrupt = opts.interrupt || false;
this.index = 0;
}
next(x) {
if (this.state < State.DONE) {
let tx;
if (this.transferables) {
tx = this.transferables(x);
}
let worker = this.workers[this.index];
if (this.interrupt && worker) {
worker.terminate();
worker = null;
}
if (!worker) {
this.workers[this.index++] = worker = defWorker(this.src);
this.index %= this.workers.length;
worker.addEventListener(
"message",
(e) => this.dispatch(e.data)
);
worker.addEventListener(
"error",
(e) => this.error(e)
);
}
worker.postMessage(x, tx || []);
}
}
done() {
super.done();
if (this.terminate > 0) {
setTimeout(() => {
LOGGER.info("terminating workers...");
this.workers.forEach((worker) => worker?.terminate());
delete this.workers;
}, this.terminate);
}
}
}
export {
Tunnel,
tunnel
};