@kirill.konshin/worker 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"workerUtils.js","sources":["../src/workerUtils.ts"],"sourcesContent":["const g = globalThis;\n\n// @see https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Transferable_objects\nconst transferrable = [\n g.ArrayBuffer,\n g.MessagePort,\n g.ReadableStream,\n g.WritableStream,\n g.TransformStream,\n // WebTransportReceiveStream, // ReferenceError: WebTransportReceiveStream is not defined\n // WebTransportSendStream, // ReferenceError: WebTransportReceiveStream is not defined\n // AudioData, // TS2304: Cannot find name AudioData\n g.ImageBitmap,\n g.VideoFrame,\n g.OffscreenCanvas,\n g.RTCDataChannel,\n g.MediaSourceHandle,\n // MIDIAccess, // ReferenceError: MIDIAccess is not defined\n].filter(Boolean);\n\nexport function isTransferable(obj: any): typeof obj | null {\n return transferrable.some((t) => obj instanceof t) ? obj : null;\n}\n\nexport function getTransferrable(data: any = {}): Transferable[] {\n if (!data) return [];\n return Object.values<any>(data)\n .reduce((r, v) => {\n return Array.isArray(v) ? [...r, ...v.map(isTransferable)] : [...r, isTransferable(v)];\n }, [])\n .filter(Boolean);\n}\n"],"names":[],"mappings":"AAAA,MAAM,IAAI;AAGV,MAAM,gBAAgB;AAAA,EAClB,EAAE;AAAA,EACF,EAAE;AAAA,EACF,EAAE;AAAA,EACF,EAAE;AAAA,EACF,EAAE;AAAA;AAAA;AAAA;AAAA,EAIF,EAAE;AAAA,EACF,EAAE;AAAA,EACF,EAAE;AAAA,EACF,EAAE;AAAA,EACF,EAAE;AAAA;AAEN,EAAE,OAAO,OAAO;AAET,SAAS,eAAe,KAA6B;AACxD,SAAO,cAAc,KAAK,CAAC,MAAM,eAAe,CAAC,IAAI,MAAM;AAC/D;AAEO,SAAS,iBAAiB,OAAY,IAAoB;AAC7D,MAAI,CAAC,KAAM,QAAO,CAAA;AAClB,SAAO,OAAO,OAAY,IAAI,EACzB,OAAO,CAAC,GAAG,MAAM;AACd,WAAO,MAAM,QAAQ,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,IAAI,cAAc,CAAC,IAAI,CAAC,GAAG,GAAG,eAAe,CAAC,CAAC;AAAA,EACzF,GAAG,CAAA,CAAE,EACJ,OAAO,OAAO;AACvB;"}
1
+ {"version":3,"file":"workerUtils.js","names":[],"sources":["../src/workerUtils.ts"],"sourcesContent":["const g = globalThis;\n\n// @see https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Transferable_objects\nconst transferrable = [\n g.ArrayBuffer,\n g.MessagePort,\n g.ReadableStream,\n g.WritableStream,\n g.TransformStream,\n // WebTransportReceiveStream, // ReferenceError: WebTransportReceiveStream is not defined\n // WebTransportSendStream, // ReferenceError: WebTransportReceiveStream is not defined\n // AudioData, // TS2304: Cannot find name AudioData\n g.ImageBitmap,\n g.VideoFrame,\n g.OffscreenCanvas,\n g.RTCDataChannel,\n g.MediaSourceHandle,\n // MIDIAccess, // ReferenceError: MIDIAccess is not defined\n].filter(Boolean);\n\nexport function isTransferable(obj: any): typeof obj | null {\n return transferrable.some((t) => obj instanceof t) ? obj : null;\n}\n\nexport function getTransferrable(data: any = {}): Transferable[] {\n if (!data) return [];\n return Object.values<any>(data)\n .reduce((r, v) => {\n return Array.isArray(v) ? [...r, ...v.map(isTransferable)] : [...r, isTransferable(v)];\n }, [])\n .filter(Boolean);\n}\n"],"mappings":";AAAA,IAAM,IAAI;AAGV,IAAM,gBAAgB;CAClB,EAAE;CACF,EAAE;CACF,EAAE;CACF,EAAE;CACF,EAAE;CAIF,EAAE;CACF,EAAE;CACF,EAAE;CACF,EAAE;CACF,EAAE;AAEN,CAAC,CAAC,OAAO,OAAO;AAEhB,SAAgB,eAAe,KAA6B;CACxD,OAAO,cAAc,MAAM,MAAM,eAAe,CAAC,IAAI,MAAM;AAC/D;AAEA,SAAgB,iBAAiB,OAAY,CAAC,GAAmB;CAC7D,IAAI,CAAC,MAAM,OAAO,CAAC;CACnB,OAAO,OAAO,OAAY,IAAI,CAAC,CAC1B,QAAQ,GAAG,MAAM;EACd,OAAO,MAAM,QAAQ,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,IAAI,cAAc,CAAC,IAAI,CAAC,GAAG,GAAG,eAAe,CAAC,CAAC;CACzF,GAAG,CAAC,CAAC,CAAC,CACL,OAAO,OAAO;AACvB"}
package/dist/wrpc.d.ts CHANGED
@@ -32,6 +32,7 @@ export declare enum LogLevel {
32
32
  }
33
33
  export declare function deriveController(signal?: AbortSignal): [AbortController, AbortSignal];
34
34
  export declare function rejectOnSignal(promise: Promise<any>, signal: AbortSignal): Promise<Event['data']>;
35
+ export declare const RESERVED_NAMES: string[];
35
36
  export declare function wrpc({ debug, name, }?: {
36
37
  debug?: LogLevel;
37
38
  name?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"wrpc.d.ts","sourceRoot":"","sources":["../src/wrpc.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,UAAU,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,SAAS,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAA;CAAE,CAAC;AAErH,MAAM,MAAM,OAAO,GAAG;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,KAAK,GAAG,YAAY,CAAC;IAAE,GAAG,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,GAAG,GAAG,KAAK,CAAA;CAAE,CAAC,CAAC;AAEzE,MAAM,MAAM,UAAU,GAAG;IACrB,WAAW,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IACzD,gBAAgB,EAAE,CACd,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,IAAI,EAC1B,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,KACjD,IAAI,CAAC;IACV,mBAAmB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,IAAI,KAAK,IAAI,CAAC;CAC5E,GAAG,GAAG,CAAC;AAER,oBAAY,QAAQ;IAChB,QAAQ,IAAI;IACZ,KAAK,IAAI;IACT,SAAS,IAAI;IACb,MAAM,IAAI;IACV,SAAS,IAAI;CAChB;AAID,wBAAgB,gBAAgB,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,CAAC,eAAe,EAAE,WAAW,CAAC,CAGrF;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAOjG;AAID,wBAAgB,IAAI,CAAC,EACjB,KAAyB,EACzB,IAAiE,GACpE,GAAE;IACC,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACZ,GAAG;IACL,eAAe,EAAE,CAAC,CAAC,SAAS,UAAU,EAClC,MAAM,EAAE,UAAU,EAClB,UAAU,EAAE,CAAC,KACZ;QACD,UAAU,EAAE,CAAC,CAAC;QACd,IAAI,EAAE,MAAM,IAAI,CAAC;KACpB,CAAC;IACF,YAAY,EAAE,CAAC,CAAC,SAAS,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC;CAChF,CAkTA"}
1
+ {"version":3,"file":"wrpc.d.ts","sourceRoot":"","sources":["../src/wrpc.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,UAAU,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,SAAS,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAA;CAAE,CAAC;AAErH,MAAM,MAAM,OAAO,GAAG;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,KAAK,GAAG,YAAY,CAAC;IAAE,GAAG,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,GAAG,GAAG,KAAK,CAAA;CAAE,CAAC,CAAC;AAEzE,MAAM,MAAM,UAAU,GAAG;IACrB,WAAW,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IACzD,gBAAgB,EAAE,CACd,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,IAAI,EAC1B,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,KACjD,IAAI,CAAC;IACV,mBAAmB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,IAAI,KAAK,IAAI,CAAC;CAC5E,GAAG,GAAG,CAAC;AAER,oBAAY,QAAQ;IAChB,QAAQ,IAAI;IACZ,KAAK,IAAI;IACT,SAAS,IAAI;IACb,MAAM,IAAI;IACV,SAAS,IAAI;CAChB;AAID,wBAAgB,gBAAgB,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,CAAC,eAAe,EAAE,WAAW,CAAC,CAGrF;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAajG;AAOD,eAAO,MAAM,cAAc,EAAE,MAAM,EAAsE,CAAC;AAU1G,wBAAgB,IAAI,CAAC,EACjB,KAAyB,EACzB,IAAiE,GACpE,GAAE;IACC,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACZ,GAAG;IACL,eAAe,EAAE,CAAC,CAAC,SAAS,UAAU,EAClC,MAAM,EAAE,UAAU,EAClB,UAAU,EAAE,CAAC,KACZ;QACD,UAAU,EAAE,CAAC,CAAC;QACd,IAAI,EAAE,MAAM,IAAI,CAAC;KACpB,CAAC;IACF,YAAY,EAAE,CAAC,CAAC,SAAS,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC;CAChF,CA6VA"}
@@ -1,26 +1,30 @@
1
+ declare const responders: {
2
+ test: ({ buf, signal }?: {
3
+ signal?: AbortSignal;
4
+ buf?: ArrayBuffer;
5
+ }) => Generator<{
6
+ progress: number;
7
+ aborted?: boolean;
8
+ }, string, unknown>;
9
+ returnYield: () => Generator<1 | 3 | 2, any, unknown>;
10
+ bidirectional: (prefix?: number) => Generator<string, string, number>;
11
+ error: () => AsyncGenerator<never, never, unknown>;
12
+ promise: () => Promise<{
13
+ test: string;
14
+ }>;
15
+ promiseError: () => Promise<never>;
16
+ setTimeout: ({ timeout }?: {
17
+ timeout?: number;
18
+ }) => Promise<unknown>;
19
+ setInterval: ({ timeout }?: {
20
+ timeout?: number;
21
+ }) => AsyncGenerator<unknown, never, unknown>;
22
+ cleanupGen: () => AsyncGenerator<number, void, unknown>;
23
+ wasCleaned: () => Promise<boolean>;
24
+ };
1
25
  export declare const responder: {
2
- responders: {
3
- test: ({ buf, signal }?: {
4
- signal?: AbortSignal;
5
- buf?: ArrayBuffer;
6
- }) => Generator<{
7
- progress: number;
8
- aborted?: boolean;
9
- }, string, unknown>;
10
- returnYield: () => Generator<1 | 3 | 2, any, unknown>;
11
- bidirectional: (prefix?: any) => Generator<string, string, number>;
12
- error: () => AsyncGenerator<never, never, unknown>;
13
- promise: () => Promise<{
14
- test: string;
15
- }>;
16
- promiseError: () => Promise<never>;
17
- setTimeout: ({ timeout }?: {
18
- timeout?: number;
19
- }) => Promise<unknown>;
20
- setInterval: ({ timeout }?: {
21
- timeout?: number;
22
- }) => AsyncGenerator<any, never, unknown>;
23
- };
26
+ responders: typeof responders;
24
27
  stop: () => void;
25
28
  };
29
+ export {};
26
30
  //# sourceMappingURL=wrpc.fixture.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"wrpc.fixture.d.ts","sourceRoot":"","sources":["../src/wrpc.fixture.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,SAAS,EAAE;IACpB,UAAU,EAAE;QAGR,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE;YAAE,MAAM,CAAC,EAAE,WAAW,CAAC;YAAC,GAAG,CAAC,EAAE,WAAW,CAAA;SAAE,KAAK,SAAS,CAC9E;YACI,QAAQ,EAAE,MAAM,CAAC;YACjB,OAAO,CAAC,EAAE,OAAO,CAAC;SACrB,EACD,MAAM,EACN,OAAO,CACV,CAAC;QAEF,WAAW,EAAE,MAAM,SAAS,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;QACtD,aAAa,EAAE,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAEnE,KAAK,EAAE,MAAM,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QACnD,OAAO,EAAE,MAAM,OAAO,CAAC;YACnB,IAAI,EAAE,MAAM,CAAC;SAChB,CAAC,CAAC;QACH,YAAY,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;QACnC,UAAU,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE;YAAE,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;QACrE,WAAW,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE;YAAE,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,KAAK,cAAc,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;KAC5F,CAAC;IACF,IAAI,EAAE,MAAM,IAAI,CAAC;CAkDnB,CAAC"}
1
+ {"version":3,"file":"wrpc.fixture.d.ts","sourceRoot":"","sources":["../src/wrpc.fixture.ts"],"names":[],"mappings":"AASA,QAAA,MAAM,UAAU;6BAEsB;QAAE,MAAM,CAAC,EAAE,WAAW,CAAC;QAAC,GAAG,CAAC,EAAE,WAAW,CAAA;KAAE,KAAQ,SAAS,CAC1F;QACI,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,OAAO,CAAC;KACrB,EACD,MAAM,EACN,OAAO,CACV;uBAO0B,SAAS,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC;wCAKtB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;iBAS7C,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC;mBAGpC,OAAO,CAAC;QAChC,IAAI,EAAE,MAAM,CAAC;KAChB,CAAC;wBAG+B,OAAO,CAAC,KAAK,CAAC;+BAGR;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,KAAQ,OAAO,CAAC,OAAO,CAAC;gCAGjC;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,KAAQ,cAAc,CACxF,OAAO,EACP,KAAK,EACL,OAAO,CACV;sBAM+B,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC;sBAW/C,OAAO,CAAC,OAAO,CAAC;CACzC,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE;IAAE,UAAU,EAAE,OAAO,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,IAAI,CAAA;CAA6C,CAAC"}
package/dist/wrpc.js CHANGED
@@ -1,241 +1,244 @@
1
1
  import { getTransferrable } from "./workerUtils.js";
2
- var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
3
- LogLevel2[LogLevel2["disabled"] = 0] = "disabled";
4
- LogLevel2[LogLevel2["error"] = 1] = "error";
5
- LogLevel2[LogLevel2["lifecycle"] = 2] = "lifecycle";
6
- LogLevel2[LogLevel2["detail"] = 3] = "detail";
7
- LogLevel2[LogLevel2["transport"] = 4] = "transport";
8
- return LogLevel2;
9
- })(LogLevel || {});
2
+ //#region src/wrpc.ts
3
+ var LogLevel = /* @__PURE__ */ function(LogLevel) {
4
+ LogLevel[LogLevel["disabled"] = 0] = "disabled";
5
+ LogLevel[LogLevel["error"] = 1] = "error";
6
+ LogLevel[LogLevel["lifecycle"] = 2] = "lifecycle";
7
+ LogLevel[LogLevel["detail"] = 3] = "detail";
8
+ LogLevel[LogLevel["transport"] = 4] = "transport";
9
+ return LogLevel;
10
+ }({});
10
11
  function deriveController(signal) {
11
- const controller = new AbortController();
12
- return [controller, AbortSignal.any([controller.signal, signal].filter(Boolean))];
12
+ const controller = new AbortController();
13
+ return [controller, AbortSignal.any([controller.signal, signal].filter(Boolean))];
13
14
  }
14
15
  function rejectOnSignal(promise, signal) {
15
- return Promise.race([
16
- promise,
17
- new Promise((resolve, reject) => {
18
- signal.addEventListener("abort", () => reject("RaceAborted:" + signal.reason), { once: true, signal });
19
- })
20
- ]);
16
+ if (signal.aborted) return Promise.reject("RaceAborted:" + signal.reason);
17
+ return Promise.race([promise, new Promise((resolve, reject) => {
18
+ signal.addEventListener("abort", () => reject("RaceAborted:" + signal.reason), { once: true });
19
+ })]);
21
20
  }
22
- function wrpc({
23
- debug = 0,
24
- name = globalThis.importScripts ? "RESPONDER" : "CALLER"
25
- } = {}) {
26
- function logger(type) {
27
- return (level, ctx, ...args) => {
28
- if (!debug || debug < level) return;
29
- const { id, message, ...restCtx } = ctx || {};
30
- console[type](name, message || "*", id || "*", ...args, restCtx);
31
- };
32
- }
33
- const log = logger("log");
34
- const logWarn = logger("warn");
35
- const logError = logger("error");
36
- function send(worker, ctx, payload) {
37
- log(4, ctx, "SEND", payload, typeof payload);
38
- worker.postMessage({ ctx, payload }, getTransferrable(payload));
39
- }
40
- function listen(worker, context, listener, signal, once = false) {
41
- signal.addEventListener(
42
- "abort",
43
- () => logWarn(3, context, "LISTEN SIGNAL ABORT", signal.reason),
44
- {
45
- signal,
46
- once: true
47
- }
48
- );
49
- worker.addEventListener(
50
- "message",
51
- ({ data }) => {
52
- log(4, context, "LISTEN EVENT", data);
53
- if (!context || data?.ctx?.message === context.message && data.ctx?.id === context.id) listener(data);
54
- },
55
- { signal, once }
56
- );
57
- }
58
- function waitFor(worker, ctx, condition = (data) => true, signal) {
59
- const [waitController, waitSignal] = deriveController(signal);
60
- return new Promise(
61
- (res) => listen(
62
- worker,
63
- ctx,
64
- (data) => {
65
- if (!condition(data)) return;
66
- waitController.abort("WaitFinished");
67
- res(data);
68
- },
69
- waitSignal
70
- )
71
- );
72
- }
73
- function createResponder(worker, responders) {
74
- const mainController = new AbortController();
75
- worker.addEventListener("messageerror", (e) => logError(1, null, "MESSAGE ERROR", e), {
76
- signal: mainController.signal
77
- });
78
- listen(
79
- worker,
80
- null,
81
- async ({ ctx, payload = {} }) => {
82
- if (!ctx || !ctx.message || !ctx.id || ctx.abort || ctx.ack) return;
83
- try {
84
- const responder = responders[ctx.message];
85
- if (!responder) throw new Error("Unknown responder", { cause: ctx });
86
- const [subController, subSignal] = deriveController(mainController.signal);
87
- if (ctx.signalName) payload[ctx.signalName] = subSignal;
88
- const iterator = responder(payload);
89
- log(2, ctx, "START", iterator);
90
- if (!iterator[Symbol.asyncIterator] && !iterator[Symbol.iterator]) {
91
- send(worker, { ...ctx, promise: true }, await rejectOnSignal(iterator, subSignal));
92
- log(3, ctx, "PROMISE RESOLVED");
93
- return;
94
- }
95
- try {
96
- listen(
97
- worker,
98
- ctx,
99
- (data) => {
100
- if (!data.ctx.abort) return;
101
- subController.abort(data.ctx.abort);
102
- logWarn(2, ctx, "GOT ABORT");
103
- },
104
- subSignal
105
- );
106
- let res;
107
- let nextPayload = payload;
108
- do {
109
- res = await rejectOnSignal(iterator.next(nextPayload), subSignal);
110
- send(worker, { ...ctx, done: res.done }, res.value);
111
- if (res.done) {
112
- subController.abort("Done");
113
- break;
114
- }
115
- const nextData = await rejectOnSignal(
116
- waitFor(worker, ctx, (data) => !!data.ctx.ack, subSignal),
117
- subSignal
118
- );
119
- nextPayload = nextData.payload;
120
- log(3, ctx, "LOOP ACK");
121
- } while (!res.done && !subSignal.aborted);
122
- } catch (e) {
123
- if (!subSignal.aborted && !e.message.includes("RaceAborted")) {
124
- logError(1, ctx, "LOOP ERROR", e);
125
- send(worker, { ...ctx, error: true, done: true }, e);
126
- }
127
- } finally {
128
- log(3, ctx, "LOOP DONE");
129
- }
130
- } catch (e) {
131
- logError(1, ctx, "ERROR", e);
132
- send(worker, { ...ctx, error: true, done: true }, e);
133
- } finally {
134
- log(3, ctx, "DONE");
135
- }
136
- },
137
- mainController.signal
138
- );
139
- function stop() {
140
- mainController.abort("Stop");
141
- }
142
- return { responders, stop };
143
- }
144
- function createCaller(worker, responders) {
145
- worker.addEventListener("messageerror", (e) => logError(1, null, "MESSAGE ERROR", e));
146
- return new Proxy(responders, {
147
- get(target, prop, receiver) {
148
- function gen(payload) {
149
- const ctx = { message: prop.toString(), id: crypto.randomUUID() };
150
- let signal = null;
151
- if (payload && Object.is(payload, Object(payload))) {
152
- for (const [key, value] of Object.entries(payload)) {
153
- if (value instanceof AbortSignal) {
154
- log(3, ctx, "FOUND SIGNAL", key);
155
- ctx.signalName = key;
156
- signal = value;
157
- payload[key] = null;
158
- }
159
- }
160
- }
161
- const [mainController, mainSignal] = deriveController(signal);
162
- const cancel = (notify, reason = "") => {
163
- if (mainController.signal.aborted) return;
164
- logWarn(2, ctx, "CANCEL", reason, notify);
165
- if (reason) mainController.abort(reason);
166
- if (notify) send(worker, { ...ctx, abort: reason });
167
- };
168
- const [promiseController, promiseSignal] = deriveController(mainSignal);
169
- const promise = waitFor(
170
- worker,
171
- ctx,
172
- (data) => !!data.ctx.promise || !!data.ctx.error,
173
- promiseSignal
174
- ).then(({ ctx: ctx2, payload: payload2 }) => {
175
- if (ctx2.error) {
176
- logError(1, ctx2, "PROMISE ERROR", payload2);
177
- throw payload2;
178
- }
179
- log(2, ctx2, "PROMISE RESOLVED", payload2);
180
- return payload2;
181
- });
182
- async function* generator() {
183
- let done = false;
184
- try {
185
- mainSignal.addEventListener("abort", () => cancel(true, mainSignal.reason), {
186
- once: true,
187
- signal: mainSignal
188
- });
189
- log(3, ctx, "GENERATOR START");
190
- promiseController.abort("GeneratorUsed");
191
- do {
192
- const data = await rejectOnSignal(
193
- waitFor(worker, ctx, void 0, mainSignal),
194
- mainSignal
195
- );
196
- const { ctx: ctxIn, payload: value } = data;
197
- log(2, ctx, "EVENT", mainSignal.aborted, ctxIn, value);
198
- if (ctxIn.promise) {
199
- logError(1, ctx, "ERROR", "Unexpected promise in generator", data);
200
- throw new Error("Unexpected promise in generator", { cause: data });
201
- }
202
- if (ctxIn.error) {
203
- logError(1, ctx, "ERROR", data);
204
- cancel(false, "Error");
205
- throw value;
206
- }
207
- if (ctxIn.done) {
208
- done = true;
209
- return value;
210
- } else {
211
- const nextPayload = yield value;
212
- if (!mainSignal.aborted) send(worker, { ...ctx, ack: true }, nextPayload);
213
- }
214
- } while (!mainSignal.aborted);
215
- } finally {
216
- log(3, ctx, "DONE");
217
- cancel(true, mainSignal.aborted ? mainSignal.reason : done ? "Done" : "Break");
218
- }
219
- }
220
- const iterator = generator();
221
- send(worker, ctx, payload);
222
- iterator["then"] = promise.then.bind(promise);
223
- iterator["catch"] = promise.catch.bind(promise);
224
- iterator["finally"] = promise.finally.bind(promise);
225
- return iterator;
226
- }
227
- Object.defineProperty(gen, "name", { value: prop.toString() });
228
- target[prop] = gen;
229
- return gen;
230
- }
231
- });
232
- }
233
- return { createResponder, createCaller };
21
+ var RESERVED_NAMES = [
22
+ "then",
23
+ "catch",
24
+ "finally",
25
+ "toJSON",
26
+ "toString",
27
+ "constructor"
28
+ ];
29
+ function validateResponders(responders) {
30
+ for (const key of Object.keys(responders)) if (RESERVED_NAMES.includes(key)) throw new Error(`Responder name "${key}" is reserved`);
234
31
  }
235
- export {
236
- LogLevel,
237
- deriveController,
238
- rejectOnSignal,
239
- wrpc
240
- };
241
- //# sourceMappingURL=wrpc.js.map
32
+ function wrpc({ debug = 0, name = globalThis.importScripts ? "RESPONDER" : "CALLER" } = {}) {
33
+ function logger(type) {
34
+ return (level, ctx, ...args) => {
35
+ if (!debug || debug < level) return;
36
+ const { id, message, ...restCtx } = ctx ?? {};
37
+ console[type](name, message ?? "*", id ?? "*", ...args, restCtx);
38
+ };
39
+ }
40
+ const log = logger("log");
41
+ const logWarn = logger("warn");
42
+ const logError = logger("error");
43
+ function send(worker, ctx, payload) {
44
+ log(4, ctx, "SEND", payload, typeof payload);
45
+ worker.postMessage({
46
+ ctx,
47
+ payload
48
+ }, getTransferrable(payload));
49
+ }
50
+ function listen(worker, context, listener, signal, once = false) {
51
+ signal.addEventListener("abort", () => logWarn(3, context, "LISTEN SIGNAL ABORT", signal.reason), { once: true });
52
+ worker.addEventListener("message", ({ data }) => {
53
+ log(4, context, "LISTEN EVENT", data);
54
+ if (!context || data?.ctx?.message === context.message && data.ctx?.id === context.id) listener(data);
55
+ }, {
56
+ signal,
57
+ once
58
+ });
59
+ }
60
+ function waitFor(worker, ctx, condition = (data) => true, signal) {
61
+ const [waitController, waitSignal] = deriveController(signal);
62
+ return new Promise((resolve) => listen(worker, ctx, (data) => {
63
+ if (!condition(data)) return;
64
+ waitController.abort("WaitFinished");
65
+ resolve(data);
66
+ }, waitSignal));
67
+ }
68
+ function createResponder(worker, responders) {
69
+ validateResponders(responders);
70
+ const mainController = new AbortController();
71
+ worker.addEventListener("messageerror", (e) => logError(1, null, "MESSAGE ERROR", e), { signal: mainController.signal });
72
+ listen(worker, null, async ({ ctx, payload = {} }) => {
73
+ if (!ctx?.message || !ctx.id || ctx.abort || ctx.ack) return;
74
+ try {
75
+ const responder = responders[ctx.message];
76
+ if (!responder) throw new Error("Unknown responder", { cause: ctx });
77
+ const [subController, subSignal] = deriveController(mainController.signal);
78
+ if (ctx.signalName) payload[ctx.signalName] = subSignal;
79
+ const iterator = responder.call(responders, payload);
80
+ log(2, ctx, "START", iterator);
81
+ if (!iterator[Symbol.asyncIterator] && !iterator[Symbol.iterator]) {
82
+ send(worker, {
83
+ ...ctx,
84
+ promise: true
85
+ }, await rejectOnSignal(iterator, subSignal));
86
+ log(3, ctx, "PROMISE RESOLVED");
87
+ return;
88
+ }
89
+ let res;
90
+ try {
91
+ listen(worker, ctx, (data) => {
92
+ if (!data.ctx.abort) return;
93
+ subController.abort(data.ctx.abort);
94
+ logWarn(2, ctx, "GOT ABORT");
95
+ }, subSignal);
96
+ let nextPayload = payload;
97
+ do {
98
+ res = await rejectOnSignal(iterator.next(nextPayload), subSignal);
99
+ send(worker, {
100
+ ...ctx,
101
+ done: res.done
102
+ }, res.value);
103
+ if (res.done) {
104
+ subController.abort("Done");
105
+ break;
106
+ }
107
+ nextPayload = (await rejectOnSignal(waitFor(worker, ctx, (data) => !!data.ctx.ack, subSignal), subSignal)).payload;
108
+ log(3, ctx, "LOOP ACK");
109
+ } while (!res.done && !subSignal.aborted);
110
+ } catch (e) {
111
+ if (!subSignal.aborted && !e.message.includes("RaceAborted")) {
112
+ logError(1, ctx, "LOOP ERROR", e);
113
+ send(worker, {
114
+ ...ctx,
115
+ error: true,
116
+ done: true
117
+ }, e);
118
+ }
119
+ } finally {
120
+ if (!res?.done) try {
121
+ Promise.resolve(iterator.return?.(void 0)).catch(() => {});
122
+ } catch {}
123
+ log(3, ctx, "LOOP DONE");
124
+ }
125
+ } catch (e) {
126
+ logError(1, ctx, "ERROR", e);
127
+ send(worker, {
128
+ ...ctx,
129
+ error: true,
130
+ done: true
131
+ }, e);
132
+ } finally {
133
+ log(3, ctx, "DONE");
134
+ }
135
+ }, mainController.signal);
136
+ function stop() {
137
+ mainController.abort("Stop");
138
+ }
139
+ return {
140
+ responders,
141
+ stop
142
+ };
143
+ }
144
+ function createCaller(worker, responders) {
145
+ validateResponders(responders);
146
+ worker.addEventListener("messageerror", (e) => logError(1, null, "MESSAGE ERROR", e));
147
+ return new Proxy(responders, { get(target, prop, receiver) {
148
+ if (typeof prop !== "string" || RESERVED_NAMES.includes(prop)) return Reflect.get(target, prop, receiver);
149
+ function gen(payload) {
150
+ const ctx = {
151
+ message: prop.toString(),
152
+ id: crypto.randomUUID()
153
+ };
154
+ let signal = null;
155
+ if (payload && Object.is(payload, Object(payload))) {
156
+ for (const [key, value] of Object.entries(payload)) if (value instanceof AbortSignal) {
157
+ log(3, ctx, "FOUND SIGNAL", key);
158
+ ctx.signalName = key;
159
+ signal = value;
160
+ payload[key] = null;
161
+ }
162
+ }
163
+ const [mainController, mainSignal] = deriveController(signal);
164
+ const cancel = (notify, reason = "") => {
165
+ if (mainController.signal.aborted) return;
166
+ logWarn(2, ctx, "CANCEL", reason, notify);
167
+ if (reason) mainController.abort(reason);
168
+ if (notify) send(worker, {
169
+ ...ctx,
170
+ abort: reason
171
+ });
172
+ };
173
+ const [promiseController, promiseSignal] = deriveController(mainSignal);
174
+ const promise = waitFor(worker, ctx, void 0, promiseSignal).then((data) => {
175
+ const { ctx: ctxIn, payload } = data;
176
+ if (ctxIn.error) {
177
+ logError(1, ctx, "PROMISE ERROR", payload);
178
+ throw payload;
179
+ }
180
+ if (ctxIn.promise) {
181
+ log(2, ctx, "PROMISE RESOLVED", payload);
182
+ return payload;
183
+ }
184
+ logError(1, ctx, "ERROR", "Cannot await a generator method", data);
185
+ cancel(true, "AwaitedGenerator");
186
+ throw new Error("Cannot await a generator method, use `for await ... of`", { cause: data });
187
+ });
188
+ promise.catch(() => {});
189
+ async function* generator() {
190
+ let done = false;
191
+ try {
192
+ mainSignal.addEventListener("abort", () => cancel(true, mainSignal.reason), { once: true });
193
+ log(3, ctx, "GENERATOR START");
194
+ promiseController.abort("GeneratorUsed");
195
+ do {
196
+ const data = await rejectOnSignal(waitFor(worker, ctx, void 0, mainSignal), mainSignal);
197
+ const { ctx: ctxIn, payload: value } = data;
198
+ log(2, ctx, "EVENT", mainSignal.aborted, ctxIn, value);
199
+ if (ctxIn.promise) {
200
+ logError(1, ctx, "ERROR", "Unexpected promise in generator", data);
201
+ throw new Error("Unexpected promise in generator", { cause: data });
202
+ }
203
+ if (ctxIn.error) {
204
+ logError(1, ctx, "ERROR", data);
205
+ cancel(false, "Error");
206
+ throw value;
207
+ }
208
+ if (ctxIn.done) {
209
+ done = true;
210
+ return value;
211
+ } else {
212
+ const nextPayload = yield value;
213
+ if (!mainSignal.aborted) send(worker, {
214
+ ...ctx,
215
+ ack: true
216
+ }, nextPayload);
217
+ }
218
+ } while (!mainSignal.aborted);
219
+ } finally {
220
+ log(3, ctx, "DONE");
221
+ cancel(true, mainSignal.aborted ? mainSignal.reason : done ? "Done" : "Break");
222
+ }
223
+ }
224
+ const iterator = generator();
225
+ send(worker, ctx, payload);
226
+ iterator["then"] = promise.then.bind(promise);
227
+ iterator["catch"] = promise.catch.bind(promise);
228
+ iterator["finally"] = promise.finally.bind(promise);
229
+ return iterator;
230
+ }
231
+ Object.defineProperty(gen, "name", { value: prop.toString() });
232
+ target[prop] = gen;
233
+ return gen;
234
+ } });
235
+ }
236
+ return {
237
+ createResponder,
238
+ createCaller
239
+ };
240
+ }
241
+ //#endregion
242
+ export { LogLevel, RESERVED_NAMES, deriveController, rejectOnSignal, wrpc };
243
+
244
+ //# sourceMappingURL=wrpc.js.map