worker-lib 1.0.1 → 1.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,21 +1,21 @@
1
- declare type WorkerType = {
2
- [key: string]: (...args: any) => any;
3
- };
4
- /**
5
- * createWorker
6
- *
7
- * @template T
8
- * @param {() => Worker} builder
9
- * @param {number} [limit=0]
10
- * @return {*}
11
- */
12
- export declare const createWorker: <T extends WorkerType>(builder: () => Worker, limit?: number) => <K extends keyof T>(name: K, ...value: Parameters<T[K]>) => Promise<ReturnType<T[K]>>;
13
- /**
14
- *
15
- *
16
- * @template T
17
- * @param {T} WorkerProc
18
- * @return {*}
19
- */
20
- export declare const initWorker: <T extends WorkerType>(WorkerProc: T) => T;
21
- export {};
1
+ type WorkerType = {
2
+ [key: string]: (...args: any) => any;
3
+ };
4
+ /**
5
+ * createWorker
6
+ *
7
+ * @template T
8
+ * @param {() => Worker} builder
9
+ * @param {number} [limit=0]
10
+ * @return {*}
11
+ */
12
+ export declare const createWorker: <T extends WorkerType>(builder: () => Worker, limit?: number) => <K extends keyof T>(name: K, ...value: Parameters<T[K]>) => Promise<ReturnType<T[K]>>;
13
+ /**
14
+ *
15
+ *
16
+ * @template T
17
+ * @param {T} WorkerProc
18
+ * @return {*}
19
+ */
20
+ export declare const initWorker: <T extends WorkerType>(WorkerProc: T) => T;
21
+ export {};
@@ -1,134 +1,125 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.initWorker = exports.createWorker = void 0;
13
- const init = (worker) => {
14
- return new Promise((resolve) => {
15
- worker.addEventListener("message", () => {
16
- resolve(worker);
17
- }, { once: true });
18
- });
19
- };
20
- const exec = (worker, name, ...value) => {
21
- return new Promise((resolve, reject) => {
22
- const p = (result) => __awaiter(void 0, void 0, void 0, function* () {
23
- const { data } = result;
24
- switch (data.type) {
25
- case "callback":
26
- const r = value[data.payload.index](data.payload.value);
27
- worker.postMessage({
28
- type: "callback_result",
29
- payload: { id: data.payload.id, result: yield r },
30
- });
31
- break;
32
- case "result":
33
- worker.removeEventListener("message", p);
34
- resolve(data.payload);
35
- break;
36
- case "error":
37
- worker.removeEventListener("message", p);
38
- reject(data.payload);
39
- break;
40
- }
41
- });
42
- worker.addEventListener("message", p);
43
- worker.postMessage({
44
- type: "function",
45
- payload: {
46
- name,
47
- value: value.map((v) => !(typeof v === "function") && v),
48
- callback: value.map((v) => typeof v === "function"),
49
- },
50
- });
51
- });
52
- };
53
- /**
54
- * createWorker
55
- *
56
- * @template T
57
- * @param {() => Worker} builder
58
- * @param {number} [limit=0]
59
- * @return {*}
60
- */
61
- const createWorker = (builder, limit = 0) => {
62
- let workers = 0;
63
- const unuses = [];
64
- const jobs = [];
65
- return (name, ...value) => {
66
- return new Promise((resolve, reject) => __awaiter(void 0, void 0, void 0, function* () {
67
- jobs.push({ resolve, reject, name, value });
68
- let worker = unuses.pop();
69
- if (limit === 0 || workers < limit) {
70
- worker = yield init(builder());
71
- workers++;
72
- }
73
- if (worker) {
74
- while (jobs.length) {
75
- const { resolve, reject, name, value } = jobs.shift();
76
- yield exec(worker, name, ...value)
77
- .then((v) => resolve(v))
78
- .catch((e) => reject(e));
79
- }
80
- unuses.push(worker);
81
- }
82
- }));
83
- };
84
- };
85
- exports.createWorker = createWorker;
86
- /**
87
- *
88
- *
89
- * @template T
90
- * @param {T} WorkerProc
91
- * @return {*}
92
- */
93
- const initWorker = (WorkerProc) => {
94
- const worker = self;
95
- worker.addEventListener("message", (e) => __awaiter(void 0, void 0, void 0, function* () {
96
- const data = e.data;
97
- if (data.type === "function") {
98
- const { name, value, callback, } = data.payload;
99
- const proc = WorkerProc[name];
100
- if (proc) {
101
- try {
102
- const params = value.map((v, index) => callback[index] ? (...params) => callbackProc(worker, index, params) : v);
103
- worker.postMessage({
104
- type: "result",
105
- payload: yield proc(...params),
106
- });
107
- }
108
- catch (e) {
109
- worker.postMessage({ type: "error", payload: String(e) });
110
- }
111
- }
112
- }
113
- }));
114
- worker.postMessage(undefined);
115
- return WorkerProc;
116
- };
117
- exports.initWorker = initWorker;
118
- const callbackProc = (worker, index, params) => {
119
- const id = WorkerValue.id++;
120
- return new Promise((resolve) => {
121
- worker.addEventListener("message", (e) => {
122
- const data = e.data;
123
- if (data.type === "callback_result" && data.payload.id === id) {
124
- resolve(data.payload.result);
125
- }
126
- }, { once: true });
127
- worker.postMessage({
128
- type: "callback",
129
- payload: { id, index, value: params },
130
- });
131
- });
132
- };
133
- const WorkerValue = { id: 0, promises: {} };
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.initWorker = exports.createWorker = void 0;
4
+ const init = (worker) => {
5
+ return new Promise((resolve) => {
6
+ worker.addEventListener("message", () => {
7
+ resolve(worker);
8
+ }, { once: true });
9
+ });
10
+ };
11
+ const exec = (worker, name, ...value) => {
12
+ return new Promise((resolve, reject) => {
13
+ const p = async (result) => {
14
+ const { data } = result;
15
+ switch (data.type) {
16
+ case "callback":
17
+ const r = value[data.payload.index](data.payload.value);
18
+ worker.postMessage({
19
+ type: "callback_result",
20
+ payload: { id: data.payload.id, result: await r },
21
+ });
22
+ break;
23
+ case "result":
24
+ worker.removeEventListener("message", p);
25
+ resolve(data.payload);
26
+ break;
27
+ case "error":
28
+ worker.removeEventListener("message", p);
29
+ reject(data.payload);
30
+ break;
31
+ }
32
+ };
33
+ worker.addEventListener("message", p);
34
+ worker.postMessage({
35
+ type: "function",
36
+ payload: {
37
+ name,
38
+ value: value.map((v) => !(typeof v === "function") && v),
39
+ callback: value.map((v) => typeof v === "function"),
40
+ },
41
+ });
42
+ });
43
+ };
44
+ /**
45
+ * createWorker
46
+ *
47
+ * @template T
48
+ * @param {() => Worker} builder
49
+ * @param {number} [limit=0]
50
+ * @return {*}
51
+ */
52
+ const createWorker = (builder, limit = 0) => {
53
+ let workers = 0;
54
+ const unuses = [];
55
+ const jobs = [];
56
+ return (name, ...value) => {
57
+ return new Promise(async (resolve, reject) => {
58
+ jobs.push({ resolve, reject, name, value });
59
+ let worker = unuses.pop();
60
+ if (limit === 0 || workers < limit) {
61
+ worker = await init(builder());
62
+ workers++;
63
+ }
64
+ if (worker) {
65
+ while (jobs.length) {
66
+ const { resolve, reject, name, value } = jobs.shift();
67
+ await exec(worker, name, ...value)
68
+ .then((v) => resolve(v))
69
+ .catch((e) => reject(e));
70
+ }
71
+ unuses.push(worker);
72
+ }
73
+ });
74
+ };
75
+ };
76
+ exports.createWorker = createWorker;
77
+ /**
78
+ *
79
+ *
80
+ * @template T
81
+ * @param {T} WorkerProc
82
+ * @return {*}
83
+ */
84
+ const initWorker = (WorkerProc) => {
85
+ const worker = self;
86
+ worker.addEventListener("message", async (e) => {
87
+ const data = e.data;
88
+ if (data.type === "function") {
89
+ const { name, value, callback, } = data.payload;
90
+ const proc = WorkerProc[name];
91
+ if (proc) {
92
+ try {
93
+ const params = value.map((v, index) => callback[index] ? (...params) => callbackProc(worker, index, params) : v);
94
+ worker.postMessage({
95
+ type: "result",
96
+ payload: await proc(...params),
97
+ });
98
+ }
99
+ catch (e) {
100
+ worker.postMessage({ type: "error", payload: String(e) });
101
+ }
102
+ }
103
+ }
104
+ });
105
+ worker.postMessage(undefined);
106
+ return WorkerProc;
107
+ };
108
+ exports.initWorker = initWorker;
109
+ const callbackProc = (worker, index, params) => {
110
+ const id = WorkerValue.id++;
111
+ return new Promise((resolve) => {
112
+ worker.addEventListener("message", (e) => {
113
+ const data = e.data;
114
+ if (data.type === "callback_result" && data.payload.id === id) {
115
+ resolve(data.payload.result);
116
+ }
117
+ }, { once: true });
118
+ worker.postMessage({
119
+ type: "callback",
120
+ payload: { id, index, value: params },
121
+ });
122
+ });
123
+ };
124
+ const WorkerValue = { id: 0, promises: {} };
134
125
  //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["type WorkerType = { [key: string]: (...args: any) => any };\ntype WorkerRecvEvent<T> =\n | {\n type: \"function\";\n payload: { name: keyof T; callback: boolean[]; value: unknown[] };\n }\n | { type: \"callback_result\"; payload: { id: number; result: unknown } };\ntype WorkerSendEvent<T extends WorkerType> =\n | {\n type: \"callback\";\n payload: { id: number; result: unknown; index: number; value: T };\n }\n | {\n type: \"result\";\n payload: ReturnType<T[keyof T]>;\n }\n | {\n type: \"error\";\n payload: unknown;\n };\n\nconst init = (worker: Worker): Promise<Worker> => {\n return new Promise((resolve) => {\n worker.addEventListener(\n \"message\",\n () => {\n resolve(worker);\n },\n { once: true }\n );\n });\n};\nconst exec = <T extends WorkerType>(\n worker: Worker,\n name: keyof T,\n ...value: Parameters<T[keyof T]>\n): Promise<ReturnType<T[keyof T]>> => {\n return new Promise((resolve, reject) => {\n const p = async (result: MessageEvent<WorkerSendEvent<T>>) => {\n const { data } = result;\n switch (data.type) {\n case \"callback\":\n const r = value[data.payload.index](data.payload.value);\n worker.postMessage({\n type: \"callback_result\",\n payload: { id: data.payload.id, result: await r },\n });\n break;\n case \"result\":\n worker.removeEventListener(\"message\", p);\n resolve(data.payload);\n break;\n case \"error\":\n worker.removeEventListener(\"message\", p);\n reject(data.payload);\n break;\n }\n };\n worker.addEventListener(\"message\", p);\n worker.postMessage({\n type: \"function\",\n payload: {\n name,\n value: value.map((v: unknown) => !(typeof v === \"function\") && v),\n callback: value.map((v: unknown) => typeof v === \"function\"),\n },\n } as WorkerRecvEvent<T>);\n });\n};\n\n/**\n * createWorker\n *\n * @template T\n * @param {() => Worker} builder\n * @param {number} [limit=0]\n * @return {*}\n */\nexport const createWorker = <T extends WorkerType>(builder: () => Worker, limit = 0) => {\n let workers = 0;\n const unuses: Worker[] = [];\n const jobs: any = [];\n return <K extends keyof T>(name: K, ...value: Parameters<T[K]>): Promise<ReturnType<T[K]>> => {\n return new Promise(async (resolve, reject) => {\n jobs.push({ resolve, reject, name, value });\n let worker = unuses.pop();\n if (limit === 0 || workers < limit) {\n worker = await init(builder());\n workers++;\n }\n if (worker) {\n while (jobs.length) {\n const { resolve, reject, name, value } = jobs.shift();\n await exec(worker, name, ...value)\n .then((v) => resolve(v))\n .catch((e) => reject(e));\n }\n unuses.push(worker);\n }\n });\n };\n};\n/**\n *\n *\n * @template T\n * @param {T} WorkerProc\n * @return {*}\n */\nexport const initWorker = <T extends WorkerType>(WorkerProc: T) => {\n const worker = self as unknown as Worker;\n worker.addEventListener(\"message\", async (e: MessageEvent) => {\n const data = e.data as WorkerRecvEvent<T>;\n if (data.type === \"function\") {\n const {\n name,\n value,\n callback,\n }: {\n name: keyof T;\n value: unknown[];\n callback: boolean[];\n } = data.payload;\n const proc = WorkerProc[name];\n if (proc) {\n try {\n const params = value.map((v, index) =>\n callback[index] ? (...params: unknown[]) => callbackProc<T>(worker, index, params) : v\n );\n worker.postMessage({\n type: \"result\",\n payload: await proc(...params),\n });\n } catch (e) {\n worker.postMessage({ type: \"error\", payload: String(e) });\n }\n }\n }\n });\n worker.postMessage(undefined);\n return WorkerProc;\n};\n\nconst callbackProc = <T>(worker: Worker, index: number, params: unknown[]) => {\n const id = WorkerValue.id++;\n return new Promise((resolve) => {\n worker.addEventListener(\n \"message\",\n (e: MessageEvent) => {\n const data = e.data as WorkerRecvEvent<T>;\n if (data.type === \"callback_result\" && data.payload.id === id) {\n resolve(data.payload.result);\n }\n },\n { once: true }\n );\n worker.postMessage({\n type: \"callback\",\n payload: { id, index, value: params },\n });\n });\n};\n\nconst WorkerValue = { id: 0, promises: {} } as {\n id: number;\n promises: { [key: number]: Promise<unknown> };\n};\n"]}
@@ -0,0 +1,26 @@
1
+ import type { Worker } from "node:worker_threads";
2
+ type WorkerType = {
3
+ [key: string]: (...args: any) => any;
4
+ };
5
+ /**
6
+ * createWorker
7
+ *
8
+ * @template T
9
+ * @param {() => Worker} builder
10
+ * @param {number} [limit=0]
11
+ * @return {*}
12
+ */
13
+ export declare const createWorker: <T extends WorkerType>(builder: () => Worker, limit?: number) => {
14
+ execute: <K extends keyof T>(name: K, ...value: Parameters<T[K]>) => Promise<Awaited<ReturnType<T[K]>>>;
15
+ waitAll: () => Promise<void>;
16
+ close: () => void;
17
+ };
18
+ /**
19
+ *
20
+ *
21
+ * @template T
22
+ * @param {T} WorkerProc
23
+ * @return {*}
24
+ */
25
+ export declare const initWorker: <T extends WorkerType>(WorkerProc: T) => T;
26
+ export {};
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.initWorker = exports.createWorker = void 0;
4
+ const node_worker_threads_1 = require("node:worker_threads");
5
+ const init = (worker) => {
6
+ return new Promise((resolve) => {
7
+ worker.once("message", () => {
8
+ resolve(worker);
9
+ });
10
+ });
11
+ };
12
+ const exec = (worker, name, ...value) => {
13
+ return new Promise((resolve, reject) => {
14
+ const p = async (data) => {
15
+ switch (data.type) {
16
+ case "callback":
17
+ const r = value[data.payload.index](data.payload.value);
18
+ worker.postMessage({
19
+ type: "callback_result",
20
+ payload: { id: data.payload.id, result: await r },
21
+ });
22
+ break;
23
+ case "result":
24
+ worker.removeListener("message", p);
25
+ resolve(data.payload);
26
+ break;
27
+ case "error":
28
+ worker.removeListener("message", p);
29
+ reject(data.payload);
30
+ break;
31
+ }
32
+ };
33
+ worker.addListener("message", p);
34
+ worker.postMessage({
35
+ type: "function",
36
+ payload: {
37
+ name,
38
+ value: value.map((v) => !(typeof v === "function") && v),
39
+ callback: value.map((v) => typeof v === "function"),
40
+ },
41
+ });
42
+ });
43
+ };
44
+ /**
45
+ * createWorker
46
+ *
47
+ * @template T
48
+ * @param {() => Worker} builder
49
+ * @param {number} [limit=0]
50
+ * @return {*}
51
+ */
52
+ const createWorker = (builder, limit = 4) => {
53
+ const workers = Array(limit)
54
+ .fill(undefined)
55
+ .map(() => ({}));
56
+ const getResolver = async () => {
57
+ while (true) {
58
+ const target = workers.find(({ resultResolver }) => !resultResolver);
59
+ if (target) {
60
+ target.resultResolver = Promise.withResolvers();
61
+ if (!target.worker)
62
+ target.worker = await init(builder());
63
+ return target;
64
+ }
65
+ await Promise.race(workers.map(({ resultResolver }) => resultResolver?.promise));
66
+ }
67
+ };
68
+ const execute = async (name, ...value) => {
69
+ const target = await getResolver();
70
+ const { resultResolver } = target;
71
+ if (!resultResolver)
72
+ throw new Error("Unexpected error");
73
+ exec(target.worker, name, ...value)
74
+ .then(resultResolver.resolve)
75
+ .catch(resultResolver.reject)
76
+ .finally(() => {
77
+ target.resultResolver = undefined;
78
+ });
79
+ return resultResolver.promise;
80
+ };
81
+ const waitAll = async () => {
82
+ while (workers.find(({ resultResolver }) => resultResolver)) {
83
+ await Promise.all(workers.flatMap(({ resultResolver }) => resultResolver ? [resultResolver.promise] : []));
84
+ }
85
+ };
86
+ const close = () => {
87
+ for (const { worker } of workers) {
88
+ worker?.terminate();
89
+ }
90
+ };
91
+ return { execute, waitAll, close };
92
+ };
93
+ exports.createWorker = createWorker;
94
+ /**
95
+ *
96
+ *
97
+ * @template T
98
+ * @param {T} WorkerProc
99
+ * @return {*}
100
+ */
101
+ const initWorker = (WorkerProc) => {
102
+ const worker = node_worker_threads_1.parentPort;
103
+ if (!worker) {
104
+ throw new Error("This is not a worker thread");
105
+ }
106
+ worker.addListener("message", async (data) => {
107
+ if (data.type === "function") {
108
+ const { name, value, callback, } = data.payload;
109
+ const proc = WorkerProc[name];
110
+ if (proc) {
111
+ try {
112
+ const params = value.map((v, index) => callback[index]
113
+ ? (...params) => callbackProc(worker, index, params)
114
+ : v);
115
+ worker.postMessage({
116
+ type: "result",
117
+ payload: await proc(...params),
118
+ });
119
+ }
120
+ catch (e) {
121
+ worker.postMessage({ type: "error", payload: String(e) });
122
+ }
123
+ }
124
+ }
125
+ });
126
+ worker.postMessage(undefined);
127
+ return WorkerProc;
128
+ };
129
+ exports.initWorker = initWorker;
130
+ const callbackProc = (worker, index, params) => {
131
+ const id = WorkerValue.id++;
132
+ return new Promise((resolve) => {
133
+ worker.once("message", (data) => {
134
+ if (data.type === "callback_result" && data.payload.id === id) {
135
+ resolve(data.payload.result);
136
+ }
137
+ });
138
+ worker.postMessage({
139
+ type: "callback",
140
+ payload: { id, index, value: params },
141
+ });
142
+ });
143
+ };
144
+ const WorkerValue = { id: 0, promises: {} };
145
+ //# sourceMappingURL=node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/node.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Worker } from \"node:worker_threads\";\nimport { parentPort } from \"node:worker_threads\";\ntype WorkerType = { [key: string]: (...args: any) => any };\ntype WorkerRecvEvent<T> =\n | {\n type: \"function\";\n payload: { name: keyof T; callback: boolean[]; value: unknown[] };\n }\n | { type: \"callback_result\"; payload: { id: number; result: unknown } };\ntype WorkerSendEvent<T extends WorkerType> =\n | {\n type: \"callback\";\n payload: { id: number; result: unknown; index: number; value: T };\n }\n | {\n type: \"result\";\n payload: ReturnType<T[keyof T]>;\n }\n | {\n type: \"error\";\n payload: unknown;\n };\n\nconst init = (worker: Worker): Promise<Worker> => {\n return new Promise((resolve) => {\n worker.once(\"message\", () => {\n resolve(worker);\n });\n });\n};\nconst exec = <T extends WorkerType>(\n worker: Worker,\n name: keyof T,\n ...value: Parameters<T[keyof T]>\n): Promise<ReturnType<T[keyof T]>> => {\n return new Promise((resolve, reject) => {\n const p = async (data: WorkerSendEvent<T>) => {\n switch (data.type) {\n case \"callback\":\n const r = value[data.payload.index](data.payload.value);\n worker.postMessage({\n type: \"callback_result\",\n payload: { id: data.payload.id, result: await r },\n });\n break;\n case \"result\":\n worker.removeListener(\"message\", p);\n resolve(data.payload);\n break;\n case \"error\":\n worker.removeListener(\"message\", p);\n reject(data.payload);\n break;\n }\n };\n worker.addListener(\"message\", p);\n worker.postMessage({\n type: \"function\",\n payload: {\n name,\n value: value.map((v: unknown) => !(typeof v === \"function\") && v),\n callback: value.map((v: unknown) => typeof v === \"function\"),\n },\n } as WorkerRecvEvent<T>);\n });\n};\n\n/**\n * createWorker\n *\n * @template T\n * @param {() => Worker} builder\n * @param {number} [limit=0]\n * @return {*}\n */\nexport const createWorker = <T extends WorkerType>(\n builder: () => Worker,\n limit = 4\n) => {\n const workers: {\n worker?: Worker;\n resultResolver?: PromiseWithResolvers<unknown>;\n }[] = Array(limit)\n .fill(undefined)\n .map(() => ({}));\n const getResolver = async () => {\n while (true) {\n const target = workers.find(({ resultResolver }) => !resultResolver);\n if (target) {\n target.resultResolver = Promise.withResolvers<unknown>();\n if (!target.worker) target.worker = await init(builder());\n return target;\n }\n await Promise.race(\n workers.map(({ resultResolver }) => resultResolver?.promise)\n );\n }\n };\n\n const execute = async <K extends keyof T>(\n name: K,\n ...value: Parameters<T[K]>\n ): Promise<Awaited<ReturnType<T[K]>>> => {\n const target = await getResolver();\n const { resultResolver } = target;\n if (!resultResolver) throw new Error(\"Unexpected error\");\n exec(target.worker!, name as string, ...value)\n .then(resultResolver.resolve)\n .catch(resultResolver.reject)\n .finally(() => {\n target.resultResolver = undefined;\n });\n return resultResolver.promise as Promise<Awaited<ReturnType<T[K]>>>;\n };\n const waitAll = async () => {\n while (workers.find(({ resultResolver }) => resultResolver)) {\n await Promise.all(\n workers.flatMap(({ resultResolver }) =>\n resultResolver ? [resultResolver.promise] : []\n )\n );\n }\n };\n const close = () => {\n for (const { worker } of workers) {\n worker?.terminate();\n }\n };\n return { execute, waitAll, close };\n};\n/**\n *\n *\n * @template T\n * @param {T} WorkerProc\n * @return {*}\n */\nexport const initWorker = <T extends WorkerType>(WorkerProc: T) => {\n const worker = parentPort;\n if (!worker) {\n throw new Error(\"This is not a worker thread\");\n }\n worker.addListener(\"message\", async (data: WorkerRecvEvent<T>) => {\n if (data.type === \"function\") {\n const {\n name,\n value,\n callback,\n }: {\n name: keyof T;\n value: unknown[];\n callback: boolean[];\n } = data.payload;\n const proc = WorkerProc[name];\n if (proc) {\n try {\n const params = value.map((v, index) =>\n callback[index]\n ? (...params: unknown[]) =>\n callbackProc<T>(worker as never, index, params)\n : v\n );\n worker.postMessage({\n type: \"result\",\n payload: await proc(...params),\n });\n } catch (e) {\n worker.postMessage({ type: \"error\", payload: String(e) });\n }\n }\n }\n });\n worker.postMessage(undefined);\n return WorkerProc;\n};\n\nconst callbackProc = <T>(worker: Worker, index: number, params: unknown[]) => {\n const id = WorkerValue.id++;\n return new Promise((resolve) => {\n worker.once(\"message\", (data: WorkerRecvEvent<T>) => {\n if (data.type === \"callback_result\" && data.payload.id === id) {\n resolve(data.payload.result);\n }\n });\n worker.postMessage({\n type: \"callback\",\n payload: { id, index, value: params },\n });\n });\n};\n\nconst WorkerValue = { id: 0, promises: {} } as {\n id: number;\n promises: { [key: number]: Promise<unknown> };\n};\n"]}
@@ -0,0 +1,21 @@
1
+ type WorkerType = {
2
+ [key: string]: (...args: any) => any;
3
+ };
4
+ /**
5
+ * createWorker
6
+ *
7
+ * @template T
8
+ * @param {() => Worker} builder
9
+ * @param {number} [limit=0]
10
+ * @return {*}
11
+ */
12
+ export declare const createWorker: <T extends WorkerType>(builder: () => Worker, limit?: number) => <K extends keyof T>(name: K, ...value: Parameters<T[K]>) => Promise<ReturnType<T[K]>>;
13
+ /**
14
+ *
15
+ *
16
+ * @template T
17
+ * @param {T} WorkerProc
18
+ * @return {*}
19
+ */
20
+ export declare const initWorker: <T extends WorkerType>(WorkerProc: T) => T;
21
+ export {};
@@ -0,0 +1,120 @@
1
+ const init = (worker) => {
2
+ return new Promise((resolve) => {
3
+ worker.addEventListener("message", () => {
4
+ resolve(worker);
5
+ }, { once: true });
6
+ });
7
+ };
8
+ const exec = (worker, name, ...value) => {
9
+ return new Promise((resolve, reject) => {
10
+ const p = async (result) => {
11
+ const { data } = result;
12
+ switch (data.type) {
13
+ case "callback":
14
+ const r = value[data.payload.index](data.payload.value);
15
+ worker.postMessage({
16
+ type: "callback_result",
17
+ payload: { id: data.payload.id, result: await r },
18
+ });
19
+ break;
20
+ case "result":
21
+ worker.removeEventListener("message", p);
22
+ resolve(data.payload);
23
+ break;
24
+ case "error":
25
+ worker.removeEventListener("message", p);
26
+ reject(data.payload);
27
+ break;
28
+ }
29
+ };
30
+ worker.addEventListener("message", p);
31
+ worker.postMessage({
32
+ type: "function",
33
+ payload: {
34
+ name,
35
+ value: value.map((v) => !(typeof v === "function") && v),
36
+ callback: value.map((v) => typeof v === "function"),
37
+ },
38
+ });
39
+ });
40
+ };
41
+ /**
42
+ * createWorker
43
+ *
44
+ * @template T
45
+ * @param {() => Worker} builder
46
+ * @param {number} [limit=0]
47
+ * @return {*}
48
+ */
49
+ export const createWorker = (builder, limit = 0) => {
50
+ let workers = 0;
51
+ const unuses = [];
52
+ const jobs = [];
53
+ return (name, ...value) => {
54
+ return new Promise(async (resolve, reject) => {
55
+ jobs.push({ resolve, reject, name, value });
56
+ let worker = unuses.pop();
57
+ if (limit === 0 || workers < limit) {
58
+ worker = await init(builder());
59
+ workers++;
60
+ }
61
+ if (worker) {
62
+ while (jobs.length) {
63
+ const { resolve, reject, name, value } = jobs.shift();
64
+ await exec(worker, name, ...value)
65
+ .then((v) => resolve(v))
66
+ .catch((e) => reject(e));
67
+ }
68
+ unuses.push(worker);
69
+ }
70
+ });
71
+ };
72
+ };
73
+ /**
74
+ *
75
+ *
76
+ * @template T
77
+ * @param {T} WorkerProc
78
+ * @return {*}
79
+ */
80
+ export const initWorker = (WorkerProc) => {
81
+ const worker = self;
82
+ worker.addEventListener("message", async (e) => {
83
+ const data = e.data;
84
+ if (data.type === "function") {
85
+ const { name, value, callback, } = data.payload;
86
+ const proc = WorkerProc[name];
87
+ if (proc) {
88
+ try {
89
+ const params = value.map((v, index) => callback[index] ? (...params) => callbackProc(worker, index, params) : v);
90
+ worker.postMessage({
91
+ type: "result",
92
+ payload: await proc(...params),
93
+ });
94
+ }
95
+ catch (e) {
96
+ worker.postMessage({ type: "error", payload: String(e) });
97
+ }
98
+ }
99
+ }
100
+ });
101
+ worker.postMessage(undefined);
102
+ return WorkerProc;
103
+ };
104
+ const callbackProc = (worker, index, params) => {
105
+ const id = WorkerValue.id++;
106
+ return new Promise((resolve) => {
107
+ worker.addEventListener("message", (e) => {
108
+ const data = e.data;
109
+ if (data.type === "callback_result" && data.payload.id === id) {
110
+ resolve(data.payload.result);
111
+ }
112
+ }, { once: true });
113
+ worker.postMessage({
114
+ type: "callback",
115
+ payload: { id, index, value: params },
116
+ });
117
+ });
118
+ };
119
+ const WorkerValue = { id: 0, promises: {} };
120
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["type WorkerType = { [key: string]: (...args: any) => any };\ntype WorkerRecvEvent<T> =\n | {\n type: \"function\";\n payload: { name: keyof T; callback: boolean[]; value: unknown[] };\n }\n | { type: \"callback_result\"; payload: { id: number; result: unknown } };\ntype WorkerSendEvent<T extends WorkerType> =\n | {\n type: \"callback\";\n payload: { id: number; result: unknown; index: number; value: T };\n }\n | {\n type: \"result\";\n payload: ReturnType<T[keyof T]>;\n }\n | {\n type: \"error\";\n payload: unknown;\n };\n\nconst init = (worker: Worker): Promise<Worker> => {\n return new Promise((resolve) => {\n worker.addEventListener(\n \"message\",\n () => {\n resolve(worker);\n },\n { once: true }\n );\n });\n};\nconst exec = <T extends WorkerType>(\n worker: Worker,\n name: keyof T,\n ...value: Parameters<T[keyof T]>\n): Promise<ReturnType<T[keyof T]>> => {\n return new Promise((resolve, reject) => {\n const p = async (result: MessageEvent<WorkerSendEvent<T>>) => {\n const { data } = result;\n switch (data.type) {\n case \"callback\":\n const r = value[data.payload.index](data.payload.value);\n worker.postMessage({\n type: \"callback_result\",\n payload: { id: data.payload.id, result: await r },\n });\n break;\n case \"result\":\n worker.removeEventListener(\"message\", p);\n resolve(data.payload);\n break;\n case \"error\":\n worker.removeEventListener(\"message\", p);\n reject(data.payload);\n break;\n }\n };\n worker.addEventListener(\"message\", p);\n worker.postMessage({\n type: \"function\",\n payload: {\n name,\n value: value.map((v: unknown) => !(typeof v === \"function\") && v),\n callback: value.map((v: unknown) => typeof v === \"function\"),\n },\n } as WorkerRecvEvent<T>);\n });\n};\n\n/**\n * createWorker\n *\n * @template T\n * @param {() => Worker} builder\n * @param {number} [limit=0]\n * @return {*}\n */\nexport const createWorker = <T extends WorkerType>(builder: () => Worker, limit = 0) => {\n let workers = 0;\n const unuses: Worker[] = [];\n const jobs: any = [];\n return <K extends keyof T>(name: K, ...value: Parameters<T[K]>): Promise<ReturnType<T[K]>> => {\n return new Promise(async (resolve, reject) => {\n jobs.push({ resolve, reject, name, value });\n let worker = unuses.pop();\n if (limit === 0 || workers < limit) {\n worker = await init(builder());\n workers++;\n }\n if (worker) {\n while (jobs.length) {\n const { resolve, reject, name, value } = jobs.shift();\n await exec(worker, name, ...value)\n .then((v) => resolve(v))\n .catch((e) => reject(e));\n }\n unuses.push(worker);\n }\n });\n };\n};\n/**\n *\n *\n * @template T\n * @param {T} WorkerProc\n * @return {*}\n */\nexport const initWorker = <T extends WorkerType>(WorkerProc: T) => {\n const worker = self as unknown as Worker;\n worker.addEventListener(\"message\", async (e: MessageEvent) => {\n const data = e.data as WorkerRecvEvent<T>;\n if (data.type === \"function\") {\n const {\n name,\n value,\n callback,\n }: {\n name: keyof T;\n value: unknown[];\n callback: boolean[];\n } = data.payload;\n const proc = WorkerProc[name];\n if (proc) {\n try {\n const params = value.map((v, index) =>\n callback[index] ? (...params: unknown[]) => callbackProc<T>(worker, index, params) : v\n );\n worker.postMessage({\n type: \"result\",\n payload: await proc(...params),\n });\n } catch (e) {\n worker.postMessage({ type: \"error\", payload: String(e) });\n }\n }\n }\n });\n worker.postMessage(undefined);\n return WorkerProc;\n};\n\nconst callbackProc = <T>(worker: Worker, index: number, params: unknown[]) => {\n const id = WorkerValue.id++;\n return new Promise((resolve) => {\n worker.addEventListener(\n \"message\",\n (e: MessageEvent) => {\n const data = e.data as WorkerRecvEvent<T>;\n if (data.type === \"callback_result\" && data.payload.id === id) {\n resolve(data.payload.result);\n }\n },\n { once: true }\n );\n worker.postMessage({\n type: \"callback\",\n payload: { id, index, value: params },\n });\n });\n};\n\nconst WorkerValue = { id: 0, promises: {} } as {\n id: number;\n promises: { [key: number]: Promise<unknown> };\n};\n"]}
@@ -0,0 +1,26 @@
1
+ import type { Worker } from "node:worker_threads";
2
+ type WorkerType = {
3
+ [key: string]: (...args: any) => any;
4
+ };
5
+ /**
6
+ * createWorker
7
+ *
8
+ * @template T
9
+ * @param {() => Worker} builder
10
+ * @param {number} [limit=0]
11
+ * @return {*}
12
+ */
13
+ export declare const createWorker: <T extends WorkerType>(builder: () => Worker, limit?: number) => {
14
+ execute: <K extends keyof T>(name: K, ...value: Parameters<T[K]>) => Promise<Awaited<ReturnType<T[K]>>>;
15
+ waitAll: () => Promise<void>;
16
+ close: () => void;
17
+ };
18
+ /**
19
+ *
20
+ *
21
+ * @template T
22
+ * @param {T} WorkerProc
23
+ * @return {*}
24
+ */
25
+ export declare const initWorker: <T extends WorkerType>(WorkerProc: T) => T;
26
+ export {};
@@ -0,0 +1,140 @@
1
+ import { parentPort } from "node:worker_threads";
2
+ const init = (worker) => {
3
+ return new Promise((resolve) => {
4
+ worker.once("message", () => {
5
+ resolve(worker);
6
+ });
7
+ });
8
+ };
9
+ const exec = (worker, name, ...value) => {
10
+ return new Promise((resolve, reject) => {
11
+ const p = async (data) => {
12
+ switch (data.type) {
13
+ case "callback":
14
+ const r = value[data.payload.index](data.payload.value);
15
+ worker.postMessage({
16
+ type: "callback_result",
17
+ payload: { id: data.payload.id, result: await r },
18
+ });
19
+ break;
20
+ case "result":
21
+ worker.removeListener("message", p);
22
+ resolve(data.payload);
23
+ break;
24
+ case "error":
25
+ worker.removeListener("message", p);
26
+ reject(data.payload);
27
+ break;
28
+ }
29
+ };
30
+ worker.addListener("message", p);
31
+ worker.postMessage({
32
+ type: "function",
33
+ payload: {
34
+ name,
35
+ value: value.map((v) => !(typeof v === "function") && v),
36
+ callback: value.map((v) => typeof v === "function"),
37
+ },
38
+ });
39
+ });
40
+ };
41
+ /**
42
+ * createWorker
43
+ *
44
+ * @template T
45
+ * @param {() => Worker} builder
46
+ * @param {number} [limit=0]
47
+ * @return {*}
48
+ */
49
+ export const createWorker = (builder, limit = 4) => {
50
+ const workers = Array(limit)
51
+ .fill(undefined)
52
+ .map(() => ({}));
53
+ const getResolver = async () => {
54
+ while (true) {
55
+ const target = workers.find(({ resultResolver }) => !resultResolver);
56
+ if (target) {
57
+ target.resultResolver = Promise.withResolvers();
58
+ if (!target.worker)
59
+ target.worker = await init(builder());
60
+ return target;
61
+ }
62
+ await Promise.race(workers.map(({ resultResolver }) => resultResolver?.promise));
63
+ }
64
+ };
65
+ const execute = async (name, ...value) => {
66
+ const target = await getResolver();
67
+ const { resultResolver } = target;
68
+ if (!resultResolver)
69
+ throw new Error("Unexpected error");
70
+ exec(target.worker, name, ...value)
71
+ .then(resultResolver.resolve)
72
+ .catch(resultResolver.reject)
73
+ .finally(() => {
74
+ target.resultResolver = undefined;
75
+ });
76
+ return resultResolver.promise;
77
+ };
78
+ const waitAll = async () => {
79
+ while (workers.find(({ resultResolver }) => resultResolver)) {
80
+ await Promise.all(workers.flatMap(({ resultResolver }) => resultResolver ? [resultResolver.promise] : []));
81
+ }
82
+ };
83
+ const close = () => {
84
+ for (const { worker } of workers) {
85
+ worker?.terminate();
86
+ }
87
+ };
88
+ return { execute, waitAll, close };
89
+ };
90
+ /**
91
+ *
92
+ *
93
+ * @template T
94
+ * @param {T} WorkerProc
95
+ * @return {*}
96
+ */
97
+ export const initWorker = (WorkerProc) => {
98
+ const worker = parentPort;
99
+ if (!worker) {
100
+ throw new Error("This is not a worker thread");
101
+ }
102
+ worker.addListener("message", async (data) => {
103
+ if (data.type === "function") {
104
+ const { name, value, callback, } = data.payload;
105
+ const proc = WorkerProc[name];
106
+ if (proc) {
107
+ try {
108
+ const params = value.map((v, index) => callback[index]
109
+ ? (...params) => callbackProc(worker, index, params)
110
+ : v);
111
+ worker.postMessage({
112
+ type: "result",
113
+ payload: await proc(...params),
114
+ });
115
+ }
116
+ catch (e) {
117
+ worker.postMessage({ type: "error", payload: String(e) });
118
+ }
119
+ }
120
+ }
121
+ });
122
+ worker.postMessage(undefined);
123
+ return WorkerProc;
124
+ };
125
+ const callbackProc = (worker, index, params) => {
126
+ const id = WorkerValue.id++;
127
+ return new Promise((resolve) => {
128
+ worker.once("message", (data) => {
129
+ if (data.type === "callback_result" && data.payload.id === id) {
130
+ resolve(data.payload.result);
131
+ }
132
+ });
133
+ worker.postMessage({
134
+ type: "callback",
135
+ payload: { id, index, value: params },
136
+ });
137
+ });
138
+ };
139
+ const WorkerValue = { id: 0, promises: {} };
140
+ //# sourceMappingURL=node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/node.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Worker } from \"node:worker_threads\";\nimport { parentPort } from \"node:worker_threads\";\ntype WorkerType = { [key: string]: (...args: any) => any };\ntype WorkerRecvEvent<T> =\n | {\n type: \"function\";\n payload: { name: keyof T; callback: boolean[]; value: unknown[] };\n }\n | { type: \"callback_result\"; payload: { id: number; result: unknown } };\ntype WorkerSendEvent<T extends WorkerType> =\n | {\n type: \"callback\";\n payload: { id: number; result: unknown; index: number; value: T };\n }\n | {\n type: \"result\";\n payload: ReturnType<T[keyof T]>;\n }\n | {\n type: \"error\";\n payload: unknown;\n };\n\nconst init = (worker: Worker): Promise<Worker> => {\n return new Promise((resolve) => {\n worker.once(\"message\", () => {\n resolve(worker);\n });\n });\n};\nconst exec = <T extends WorkerType>(\n worker: Worker,\n name: keyof T,\n ...value: Parameters<T[keyof T]>\n): Promise<ReturnType<T[keyof T]>> => {\n return new Promise((resolve, reject) => {\n const p = async (data: WorkerSendEvent<T>) => {\n switch (data.type) {\n case \"callback\":\n const r = value[data.payload.index](data.payload.value);\n worker.postMessage({\n type: \"callback_result\",\n payload: { id: data.payload.id, result: await r },\n });\n break;\n case \"result\":\n worker.removeListener(\"message\", p);\n resolve(data.payload);\n break;\n case \"error\":\n worker.removeListener(\"message\", p);\n reject(data.payload);\n break;\n }\n };\n worker.addListener(\"message\", p);\n worker.postMessage({\n type: \"function\",\n payload: {\n name,\n value: value.map((v: unknown) => !(typeof v === \"function\") && v),\n callback: value.map((v: unknown) => typeof v === \"function\"),\n },\n } as WorkerRecvEvent<T>);\n });\n};\n\n/**\n * createWorker\n *\n * @template T\n * @param {() => Worker} builder\n * @param {number} [limit=0]\n * @return {*}\n */\nexport const createWorker = <T extends WorkerType>(\n builder: () => Worker,\n limit = 4\n) => {\n const workers: {\n worker?: Worker;\n resultResolver?: PromiseWithResolvers<unknown>;\n }[] = Array(limit)\n .fill(undefined)\n .map(() => ({}));\n const getResolver = async () => {\n while (true) {\n const target = workers.find(({ resultResolver }) => !resultResolver);\n if (target) {\n target.resultResolver = Promise.withResolvers<unknown>();\n if (!target.worker) target.worker = await init(builder());\n return target;\n }\n await Promise.race(\n workers.map(({ resultResolver }) => resultResolver?.promise)\n );\n }\n };\n\n const execute = async <K extends keyof T>(\n name: K,\n ...value: Parameters<T[K]>\n ): Promise<Awaited<ReturnType<T[K]>>> => {\n const target = await getResolver();\n const { resultResolver } = target;\n if (!resultResolver) throw new Error(\"Unexpected error\");\n exec(target.worker!, name as string, ...value)\n .then(resultResolver.resolve)\n .catch(resultResolver.reject)\n .finally(() => {\n target.resultResolver = undefined;\n });\n return resultResolver.promise as Promise<Awaited<ReturnType<T[K]>>>;\n };\n const waitAll = async () => {\n while (workers.find(({ resultResolver }) => resultResolver)) {\n await Promise.all(\n workers.flatMap(({ resultResolver }) =>\n resultResolver ? [resultResolver.promise] : []\n )\n );\n }\n };\n const close = () => {\n for (const { worker } of workers) {\n worker?.terminate();\n }\n };\n return { execute, waitAll, close };\n};\n/**\n *\n *\n * @template T\n * @param {T} WorkerProc\n * @return {*}\n */\nexport const initWorker = <T extends WorkerType>(WorkerProc: T) => {\n const worker = parentPort;\n if (!worker) {\n throw new Error(\"This is not a worker thread\");\n }\n worker.addListener(\"message\", async (data: WorkerRecvEvent<T>) => {\n if (data.type === \"function\") {\n const {\n name,\n value,\n callback,\n }: {\n name: keyof T;\n value: unknown[];\n callback: boolean[];\n } = data.payload;\n const proc = WorkerProc[name];\n if (proc) {\n try {\n const params = value.map((v, index) =>\n callback[index]\n ? (...params: unknown[]) =>\n callbackProc<T>(worker as never, index, params)\n : v\n );\n worker.postMessage({\n type: \"result\",\n payload: await proc(...params),\n });\n } catch (e) {\n worker.postMessage({ type: \"error\", payload: String(e) });\n }\n }\n }\n });\n worker.postMessage(undefined);\n return WorkerProc;\n};\n\nconst callbackProc = <T>(worker: Worker, index: number, params: unknown[]) => {\n const id = WorkerValue.id++;\n return new Promise((resolve) => {\n worker.once(\"message\", (data: WorkerRecvEvent<T>) => {\n if (data.type === \"callback_result\" && data.payload.id === id) {\n resolve(data.payload.result);\n }\n });\n worker.postMessage({\n type: \"callback\",\n payload: { id, index, value: params },\n });\n });\n};\n\nconst WorkerValue = { id: 0, promises: {} } as {\n id: number;\n promises: { [key: number]: Promise<unknown> };\n};\n"]}
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
package/package.json CHANGED
@@ -1,20 +1,49 @@
1
1
  {
2
2
  "name": "worker-lib",
3
- "version": "1.0.1",
4
- "main": "dist/index.js",
3
+ "version": "1.0.3",
4
+ "main": "./dist/cjs/index.js",
5
+ "types": "./dist/cjs/index.d.ts",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/cjs/index.d.ts",
9
+ "require": "./dist/cjs/index.js",
10
+ "import": "./dist/esm/index.js"
11
+ },
12
+ "./node": {
13
+ "type": "./dist/cjs/node.d.ts",
14
+ "default": "./dist/cjs/node.js"
15
+ }
16
+ },
17
+ "typesVersions": {
18
+ "*": {
19
+ "*": [
20
+ "./dist/cjs/index.d.ts"
21
+ ],
22
+ "node": [
23
+ "./dist/cjs/node.d.ts"
24
+ ]
25
+ }
26
+ },
5
27
  "license": "MIT",
6
28
  "scripts": {
7
- "build": "tsc -b"
29
+ "build": "tsc && tsc --project ./tsconfig.esm.json && cpy esm dist"
8
30
  },
9
31
  "devDependencies": {
10
- "typescript": "^4.4.2"
32
+ "@types/node": "22.13.5",
33
+ "cpy-cli": "5.0.0",
34
+ "typescript": "^5.7.3"
11
35
  },
12
36
  "description": "Library for easy use of web-worker",
13
37
  "repository": {
14
38
  "type": "git",
15
39
  "url": "git+https://github.com/SoraKumo001/worker-lib.git"
16
40
  },
17
- "keywords": ["Next.js","react","TypeScript","web-worker"],
41
+ "keywords": [
42
+ "Next.js",
43
+ "react",
44
+ "TypeScript",
45
+ "web-worker"
46
+ ],
18
47
  "author": "SoraKumo",
19
48
  "bugs": {
20
49
  "url": "https://github.com/SoraKumo001/worker-lib/issues"
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAqBA,MAAM,IAAI,GAAG,CAAC,MAAc,EAAmB,EAAE;IAC/C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,CAAC,gBAAgB,CACrB,SAAS,EACT,GAAG,EAAE;YACH,OAAO,CAAC,MAAM,CAAC,CAAC;QAClB,CAAC,EACD,EAAE,IAAI,EAAE,IAAI,EAAE,CACf,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AACF,MAAM,IAAI,GAAG,CACX,MAAc,EACd,IAAa,EACb,GAAG,KAA6B,EACC,EAAE;IACnC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,CAAC,GAAG,CAAO,MAAwC,EAAE,EAAE;YAC3D,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC;YACxB,QAAQ,IAAI,CAAC,IAAI,EAAE;gBACjB,KAAK,UAAU;oBACb,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;oBACxD,MAAM,CAAC,WAAW,CAAC;wBACjB,IAAI,EAAE,iBAAiB;wBACvB,OAAO,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE;qBAClD,CAAC,CAAC;oBACH,MAAM;gBACR,KAAK,QAAQ;oBACX,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;oBACzC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBACtB,MAAM;gBACR,KAAK,OAAO;oBACV,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;oBACzC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBACrB,MAAM;aACT;QACH,CAAC,CAAA,CAAC;QACF,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QACtC,MAAM,CAAC,WAAW,CAAC;YACjB,IAAI,EAAE,UAAU;YAChB,OAAO,EAAE;gBACP,IAAI;gBACJ,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,UAAU,CAAC,IAAI,CAAC,CAAC;gBACjE,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAU,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,UAAU,CAAC;aAC7D;SACoB,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF;;;;;;;GAOG;AACI,MAAM,YAAY,GAAG,CAAuB,OAAqB,EAAE,KAAK,GAAG,CAAC,EAAE,EAAE;IACrF,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,IAAI,GAAQ,EAAE,CAAC;IACrB,OAAO,CAAoB,IAAO,EAAE,GAAG,KAAuB,EAA6B,EAAE;QAC3F,OAAO,IAAI,OAAO,CAAC,CAAO,OAAO,EAAE,MAAM,EAAE,EAAE;YAC3C,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YAC5C,IAAI,MAAM,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC;YAC1B,IAAI,KAAK,KAAK,CAAC,IAAI,OAAO,GAAG,KAAK,EAAE;gBAClC,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC/B,OAAO,EAAE,CAAC;aACX;YACD,IAAI,MAAM,EAAE;gBACV,OAAO,IAAI,CAAC,MAAM,EAAE;oBAClB,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;oBACtD,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;yBAC/B,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;yBACvB,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;iBAC5B;gBACD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;aACrB;QACH,CAAC,CAAA,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC,CAAC;AAvBW,QAAA,YAAY,gBAuBvB;AACF;;;;;;GAMG;AACI,MAAM,UAAU,GAAG,CAAuB,UAAa,EAAE,EAAE;IAChE,MAAM,MAAM,GAAG,IAAyB,CAAC;IACzC,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAO,CAAe,EAAE,EAAE;QAC3D,MAAM,IAAI,GAAG,CAAC,CAAC,IAA0B,CAAC;QAC1C,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,EAAE;YAC5B,MAAM,EACJ,IAAI,EACJ,KAAK,EACL,QAAQ,GACT,GAIG,IAAI,CAAC,OAAO,CAAC;YACjB,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;YAC9B,IAAI,IAAI,EAAE;gBACR,IAAI;oBACF,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CACpC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAiB,EAAE,EAAE,CAAC,YAAY,CAAI,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CACvF,CAAC;oBACF,MAAM,CAAC,WAAW,CAAC;wBACjB,IAAI,EAAE,QAAQ;wBACd,OAAO,EAAE,MAAM,IAAI,CAAC,GAAG,MAAM,CAAC;qBAC/B,CAAC,CAAC;iBACJ;gBAAC,OAAO,CAAC,EAAE;oBACV,MAAM,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;iBAC3D;aACF;SACF;IACH,CAAC,CAAA,CAAC,CAAC;IACH,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;IAC9B,OAAO,UAAU,CAAC;AACpB,CAAC,CAAC;AAhCW,QAAA,UAAU,cAgCrB;AAEF,MAAM,YAAY,GAAG,CAAI,MAAc,EAAE,KAAa,EAAE,MAAiB,EAAE,EAAE;IAC3E,MAAM,EAAE,GAAG,WAAW,CAAC,EAAE,EAAE,CAAC;IAC5B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,CAAC,gBAAgB,CACrB,SAAS,EACT,CAAC,CAAe,EAAE,EAAE;YAClB,MAAM,IAAI,GAAG,CAAC,CAAC,IAA0B,CAAC;YAC1C,IAAI,IAAI,CAAC,IAAI,KAAK,iBAAiB,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE;gBAC7D,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;aAC9B;QACH,CAAC,EACD,EAAE,IAAI,EAAE,IAAI,EAAE,CACf,CAAC;QACF,MAAM,CAAC,WAAW,CAAC;YACjB,IAAI,EAAE,UAAU;YAChB,OAAO,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE;SACtC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,WAAW,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAGxC,CAAC","sourcesContent":["type WorkerType = { [key: string]: (...args: any) => any };\ntype WorkerRecvEvent<T> =\n | {\n type: \"function\";\n payload: { name: keyof T; callback: boolean[]; value: unknown[] };\n }\n | { type: \"callback_result\"; payload: { id: number; result: unknown } };\ntype WorkerSendEvent<T extends WorkerType> =\n | {\n type: \"callback\";\n payload: { id: number; result: unknown; index: number; value: T };\n }\n | {\n type: \"result\";\n payload: ReturnType<T[keyof T]>;\n }\n | {\n type: \"error\";\n payload: unknown;\n };\n\nconst init = (worker: Worker): Promise<Worker> => {\n return new Promise((resolve) => {\n worker.addEventListener(\n \"message\",\n () => {\n resolve(worker);\n },\n { once: true }\n );\n });\n};\nconst exec = <T extends WorkerType>(\n worker: Worker,\n name: keyof T,\n ...value: Parameters<T[keyof T]>\n): Promise<ReturnType<T[keyof T]>> => {\n return new Promise((resolve, reject) => {\n const p = async (result: MessageEvent<WorkerSendEvent<T>>) => {\n const { data } = result;\n switch (data.type) {\n case \"callback\":\n const r = value[data.payload.index](data.payload.value);\n worker.postMessage({\n type: \"callback_result\",\n payload: { id: data.payload.id, result: await r },\n });\n break;\n case \"result\":\n worker.removeEventListener(\"message\", p);\n resolve(data.payload);\n break;\n case \"error\":\n worker.removeEventListener(\"message\", p);\n reject(data.payload);\n break;\n }\n };\n worker.addEventListener(\"message\", p);\n worker.postMessage({\n type: \"function\",\n payload: {\n name,\n value: value.map((v: unknown) => !(typeof v === \"function\") && v),\n callback: value.map((v: unknown) => typeof v === \"function\"),\n },\n } as WorkerRecvEvent<T>);\n });\n};\n\n/**\n * createWorker\n *\n * @template T\n * @param {() => Worker} builder\n * @param {number} [limit=0]\n * @return {*}\n */\nexport const createWorker = <T extends WorkerType>(builder: () => Worker, limit = 0) => {\n let workers = 0;\n const unuses: Worker[] = [];\n const jobs: any = [];\n return <K extends keyof T>(name: K, ...value: Parameters<T[K]>): Promise<ReturnType<T[K]>> => {\n return new Promise(async (resolve, reject) => {\n jobs.push({ resolve, reject, name, value });\n let worker = unuses.pop();\n if (limit === 0 || workers < limit) {\n worker = await init(builder());\n workers++;\n }\n if (worker) {\n while (jobs.length) {\n const { resolve, reject, name, value } = jobs.shift();\n await exec(worker, name, ...value)\n .then((v) => resolve(v))\n .catch((e) => reject(e));\n }\n unuses.push(worker);\n }\n });\n };\n};\n/**\n *\n *\n * @template T\n * @param {T} WorkerProc\n * @return {*}\n */\nexport const initWorker = <T extends WorkerType>(WorkerProc: T) => {\n const worker = self as unknown as Worker;\n worker.addEventListener(\"message\", async (e: MessageEvent) => {\n const data = e.data as WorkerRecvEvent<T>;\n if (data.type === \"function\") {\n const {\n name,\n value,\n callback,\n }: {\n name: keyof T;\n value: unknown[];\n callback: boolean[];\n } = data.payload;\n const proc = WorkerProc[name];\n if (proc) {\n try {\n const params = value.map((v, index) =>\n callback[index] ? (...params: unknown[]) => callbackProc<T>(worker, index, params) : v\n );\n worker.postMessage({\n type: \"result\",\n payload: await proc(...params),\n });\n } catch (e) {\n worker.postMessage({ type: \"error\", payload: String(e) });\n }\n }\n }\n });\n worker.postMessage(undefined);\n return WorkerProc;\n};\n\nconst callbackProc = <T>(worker: Worker, index: number, params: unknown[]) => {\n const id = WorkerValue.id++;\n return new Promise((resolve) => {\n worker.addEventListener(\n \"message\",\n (e: MessageEvent) => {\n const data = e.data as WorkerRecvEvent<T>;\n if (data.type === \"callback_result\" && data.payload.id === id) {\n resolve(data.payload.result);\n }\n },\n { once: true }\n );\n worker.postMessage({\n type: \"callback\",\n payload: { id, index, value: params },\n });\n });\n};\n\nconst WorkerValue = { id: 0, promises: {} } as {\n id: number;\n promises: { [key: number]: Promise<unknown> };\n};\n"]}