-
-
Notifications
You must be signed in to change notification settings - Fork 150
/
worker.ts
59 lines (57 loc) · 1.82 KB
/
worker.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import type { WithErrorHandlerOpts, WorkerSource } from "./api.js";
import { defWorker } from "./defworker.js";
import { __optsWithID } from "./idgen.js";
import { LOGGER } from "./logger.js";
import { stream } from "./stream.js";
export interface FromWorkerOpts extends WithErrorHandlerOpts {
/**
* If true, the worker will be terminated when the stream
* is being closed.
*
* @defaultValue true
*/
terminate: boolean;
}
/**
* Returns a {@link Stream} which adds `message` and `error` event
* listeners to given `worker` and then emits received values.
*
* @remarks
* If `terminate` is true (default), the worker will be terminated when
* the stream is being closed (either directly or indirectly, i.e. if
* the user called {@link ISubscriber.done} on the stream or the last
* child subscription has unsubscribed, depending on
* {@link CommonOpts | config options}).
*
* As with {@link postWorker}, the `worker` can be an existing `Worker`
* instance, a JS source code `Blob` or an URL string. In the latter two
* cases, a worker is created automatically.
*
* @param worker -
* @param opts -
*/
export const fromWorker = <T>(
worker: WorkerSource,
opts?: Partial<FromWorkerOpts>
) => {
const _worker = defWorker(worker);
opts = __optsWithID("worker", opts);
return stream<T>((stream) => {
const msgListener = (e: MessageEvent) => {
stream.next(e.data);
};
const errListener = (e: MessageEvent) => {
stream.error(e.data);
};
_worker.addEventListener("message", msgListener);
_worker.addEventListener("error", <EventListener>errListener);
return () => {
_worker.removeEventListener("message", msgListener);
_worker.removeEventListener("error", <EventListener>errListener);
if (opts!.terminate !== false) {
LOGGER.info("terminating worker", _worker);
_worker.terminate();
}
};
}, opts);
};