@xylabs/threads 4.6.4 → 4.7.0

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.
Files changed (227) hide show
  1. package/dist/browser/master/implementation.browser.mjs +89 -0
  2. package/dist/browser/master/implementation.browser.mjs.map +1 -0
  3. package/dist/browser/worker/worker.browser.mjs +291 -0
  4. package/dist/browser/worker/worker.browser.mjs.map +1 -0
  5. package/dist/neutral/index.mjs +1022 -0
  6. package/dist/neutral/index.mjs.map +1 -0
  7. package/dist/neutral/master/implementation.mjs +264 -0
  8. package/dist/neutral/master/implementation.mjs.map +1 -0
  9. package/dist/neutral/master/index.mjs +988 -0
  10. package/dist/neutral/master/index.mjs.map +1 -0
  11. package/dist/neutral/master/pool.mjs +579 -0
  12. package/dist/neutral/master/pool.mjs.map +1 -0
  13. package/dist/neutral/master/register.mjs +272 -0
  14. package/dist/neutral/master/register.mjs.map +1 -0
  15. package/dist/neutral/master/spawn.mjs +412 -0
  16. package/dist/neutral/master/spawn.mjs.map +1 -0
  17. package/dist/neutral/master/thread.mjs +29 -0
  18. package/dist/neutral/master/thread.mjs.map +1 -0
  19. package/dist/neutral/observable-promise.mjs +132 -0
  20. package/dist/neutral/observable-promise.mjs.map +1 -0
  21. package/dist/neutral/observable.mjs +31 -0
  22. package/dist/neutral/observable.mjs.map +1 -0
  23. package/dist/node/master/implementation.node.mjs +154 -0
  24. package/dist/node/master/implementation.node.mjs.map +1 -0
  25. package/dist/node/worker/worker.node.mjs +304 -0
  26. package/dist/node/worker/worker.node.mjs.map +1 -0
  27. package/dist/{common.d.ts → types/common.d.ts} +5 -1
  28. package/dist/types/common.d.ts.map +1 -0
  29. package/dist/types/index.d.ts +9 -0
  30. package/dist/types/index.d.ts.map +1 -0
  31. package/dist/{master → types/master}/get-bundle-url.browser.d.ts +1 -0
  32. package/dist/types/master/get-bundle-url.browser.d.ts.map +1 -0
  33. package/dist/{master → types/master}/implementation.browser.d.ts +2 -1
  34. package/dist/types/master/implementation.browser.d.ts.map +1 -0
  35. package/dist/{master → types/master}/implementation.d.ts +4 -1
  36. package/dist/types/master/implementation.d.ts.map +1 -0
  37. package/dist/{master → types/master}/implementation.node.d.ts +2 -1
  38. package/dist/types/master/implementation.node.d.ts.map +1 -0
  39. package/dist/types/master/index.d.ts +13 -0
  40. package/dist/types/master/index.d.ts.map +1 -0
  41. package/dist/{master → types/master}/invocation-proxy.d.ts +2 -1
  42. package/dist/types/master/invocation-proxy.d.ts.map +1 -0
  43. package/dist/{master → types/master}/pool-types.d.ts +16 -1
  44. package/dist/types/master/pool-types.d.ts.map +1 -0
  45. package/dist/types/master/pool.d.ts +93 -0
  46. package/dist/types/master/pool.d.ts.map +1 -0
  47. package/dist/types/master/register.d.ts +2 -0
  48. package/dist/types/master/register.d.ts.map +1 -0
  49. package/dist/{master → types/master}/spawn.d.ts +12 -2
  50. package/dist/types/master/spawn.d.ts.map +1 -0
  51. package/dist/types/master/thread.d.ts +13 -0
  52. package/dist/types/master/thread.d.ts.map +1 -0
  53. package/dist/{observable-promise.d.ts → types/observable-promise.d.ts} +14 -0
  54. package/dist/types/observable-promise.d.ts.map +1 -0
  55. package/dist/types/observable.d.ts +21 -0
  56. package/dist/types/observable.d.ts.map +1 -0
  57. package/dist/{ponyfills.d.ts → types/ponyfills.d.ts} +1 -0
  58. package/dist/types/ponyfills.d.ts.map +1 -0
  59. package/dist/types/promise.d.ts +6 -0
  60. package/dist/types/promise.d.ts.map +1 -0
  61. package/dist/{serializers.d.ts → types/serializers.d.ts} +1 -0
  62. package/dist/types/serializers.d.ts.map +1 -0
  63. package/dist/{symbols.d.ts → types/symbols.d.ts} +1 -0
  64. package/dist/types/symbols.d.ts.map +1 -0
  65. package/dist/types/transferable.d.ts +43 -0
  66. package/dist/types/transferable.d.ts.map +1 -0
  67. package/dist/types/{master.d.ts → types/master.d.ts} +17 -3
  68. package/dist/types/types/master.d.ts.map +1 -0
  69. package/dist/types/{messages.d.ts → types/messages.d.ts} +1 -0
  70. package/dist/types/types/messages.d.ts.map +1 -0
  71. package/dist/types/{worker.d.ts → types/worker.d.ts} +1 -0
  72. package/dist/types/types/worker.d.ts.map +1 -0
  73. package/dist/types/worker/WorkerGlobalScope.d.ts +6 -0
  74. package/dist/types/worker/WorkerGlobalScope.d.ts.map +1 -0
  75. package/dist/types/worker/expose.d.ts +4 -0
  76. package/dist/types/worker/expose.d.ts.map +1 -0
  77. package/dist/types/worker/worker.browser.d.ts +14 -0
  78. package/dist/types/worker/worker.browser.d.ts.map +1 -0
  79. package/dist/types/worker/worker.node.d.ts +25 -0
  80. package/dist/types/worker/worker.node.d.ts.map +1 -0
  81. package/package.json +66 -77
  82. package/src/common.ts +10 -6
  83. package/src/index.ts +10 -9
  84. package/src/master/get-bundle-url.browser.ts +2 -1
  85. package/src/master/implementation.browser.ts +2 -2
  86. package/src/master/implementation.node.ts +19 -96
  87. package/src/master/implementation.ts +2 -2
  88. package/src/master/index.ts +7 -7
  89. package/src/master/invocation-proxy.ts +6 -6
  90. package/src/master/pool-types.ts +1 -1
  91. package/src/master/pool.ts +14 -13
  92. package/src/master/register.ts +2 -1
  93. package/src/master/spawn.ts +8 -8
  94. package/src/master/thread.ts +2 -2
  95. package/src/observable-promise.ts +3 -2
  96. package/src/serializers.ts +1 -1
  97. package/src/transferable.ts +2 -1
  98. package/src/types/master.ts +3 -3
  99. package/src/worker/WorkerGlobalScope.ts +5 -0
  100. package/src/worker/expose.ts +234 -0
  101. package/src/worker/is-observable.d.ts +7 -0
  102. package/src/worker/{implementation.browser.ts → worker.browser.ts} +26 -10
  103. package/src/worker/{implementation.worker_threads.ts → worker.node.ts} +30 -12
  104. package/types/is-observable.d.ts +1 -1
  105. package/xy.config.ts +24 -0
  106. package/dist/common.js +0 -16
  107. package/dist/esm/common.js +0 -16
  108. package/dist/esm/index.js +0 -26
  109. package/dist/esm/master/get-bundle-url.browser.js +0 -25
  110. package/dist/esm/master/implementation.browser.js +0 -65
  111. package/dist/esm/master/implementation.js +0 -43
  112. package/dist/esm/master/implementation.node.js +0 -205
  113. package/dist/esm/master/index.js +0 -14
  114. package/dist/esm/master/invocation-proxy.js +0 -121
  115. package/dist/esm/master/pool-types.js +0 -14
  116. package/dist/esm/master/pool.js +0 -262
  117. package/dist/esm/master/register.js +0 -11
  118. package/dist/esm/master/spawn.js +0 -114
  119. package/dist/esm/master/thread.js +0 -18
  120. package/dist/esm/observable-promise.js +0 -132
  121. package/dist/esm/observable.js +0 -33
  122. package/dist/esm/ponyfills.js +0 -20
  123. package/dist/esm/promise.js +0 -23
  124. package/dist/esm/serializers.js +0 -41
  125. package/dist/esm/symbols.js +0 -8
  126. package/dist/esm/transferable.js +0 -25
  127. package/dist/esm/types/master.js +0 -9
  128. package/dist/esm/types/messages.js +0 -16
  129. package/dist/esm/types/worker.js +0 -2
  130. package/dist/esm/worker/bundle-entry.js +0 -26
  131. package/dist/esm/worker/implementation.browser.js +0 -24
  132. package/dist/esm/worker/implementation.js +0 -19
  133. package/dist/esm/worker/implementation.tiny-worker.js +0 -37
  134. package/dist/esm/worker/implementation.worker_threads.js +0 -41
  135. package/dist/esm/worker/index.js +0 -174
  136. package/dist/esm/worker_threads.js +0 -13
  137. package/dist/index.d.ts +0 -7
  138. package/dist/index.js +0 -26
  139. package/dist/master/get-bundle-url.browser.js +0 -25
  140. package/dist/master/implementation.browser.js +0 -65
  141. package/dist/master/implementation.js +0 -43
  142. package/dist/master/implementation.node.js +0 -205
  143. package/dist/master/index.d.ts +0 -10
  144. package/dist/master/index.js +0 -14
  145. package/dist/master/invocation-proxy.js +0 -121
  146. package/dist/master/pool-types.js +0 -14
  147. package/dist/master/pool.d.ts +0 -50
  148. package/dist/master/pool.js +0 -262
  149. package/dist/master/register.d.ts +0 -1
  150. package/dist/master/register.js +0 -11
  151. package/dist/master/spawn.js +0 -114
  152. package/dist/master/thread.d.ts +0 -8
  153. package/dist/master/thread.js +0 -18
  154. package/dist/observable-promise.js +0 -132
  155. package/dist/observable.d.ts +0 -11
  156. package/dist/observable.js +0 -33
  157. package/dist/ponyfills.js +0 -20
  158. package/dist/promise.d.ts +0 -1
  159. package/dist/promise.js +0 -23
  160. package/dist/serializers.js +0 -41
  161. package/dist/symbols.js +0 -8
  162. package/dist/transferable.d.ts +0 -9
  163. package/dist/transferable.js +0 -25
  164. package/dist/types/master.js +0 -9
  165. package/dist/types/messages.js +0 -16
  166. package/dist/types/worker.js +0 -2
  167. package/dist/worker/bundle-entry.d.ts +0 -1
  168. package/dist/worker/bundle-entry.js +0 -26
  169. package/dist/worker/implementation.browser.d.ts +0 -6
  170. package/dist/worker/implementation.browser.js +0 -24
  171. package/dist/worker/implementation.d.ts +0 -3
  172. package/dist/worker/implementation.js +0 -19
  173. package/dist/worker/implementation.tiny-worker.d.ts +0 -6
  174. package/dist/worker/implementation.tiny-worker.js +0 -37
  175. package/dist/worker/implementation.worker_threads.d.ts +0 -8
  176. package/dist/worker/implementation.worker_threads.js +0 -41
  177. package/dist/worker/index.d.ts +0 -5
  178. package/dist/worker/index.js +0 -174
  179. package/dist/worker_threads.d.ts +0 -8
  180. package/dist/worker_threads.js +0 -13
  181. package/observable.d.ts +0 -2
  182. package/observable.js +0 -2
  183. package/observable.mjs +0 -4
  184. package/register.d.ts +0 -2
  185. package/register.js +0 -2
  186. package/register.mjs +0 -1
  187. package/rollup.config.js +0 -16
  188. package/src/worker/bundle-entry.ts +0 -10
  189. package/src/worker/implementation.tiny-worker.ts +0 -55
  190. package/src/worker/implementation.ts +0 -23
  191. package/src/worker/index.ts +0 -230
  192. package/src/worker_threads.ts +0 -27
  193. package/test/lib/index.ts +0 -1
  194. package/test/lib/serialization.ts +0 -38
  195. package/test/observable-promise.test.ts +0 -205
  196. package/test/observable.test.ts +0 -87
  197. package/test/pool.test.ts +0 -183
  198. package/test/serialization.test.ts +0 -23
  199. package/test/spawn.chromium.mocha.ts +0 -53
  200. package/test/spawn.test.ts +0 -87
  201. package/test/streaming.test.ts +0 -29
  202. package/test/transferables.test.ts +0 -71
  203. package/test/workers/arraybuffer-xor.ts +0 -10
  204. package/test/workers/count-to-five.ts +0 -12
  205. package/test/workers/counter.ts +0 -19
  206. package/test/workers/faulty-function.ts +0 -5
  207. package/test/workers/hello-world.ts +0 -5
  208. package/test/workers/increment.ts +0 -8
  209. package/test/workers/minmax.ts +0 -25
  210. package/test/workers/serialization.ts +0 -13
  211. package/test/workers/top-level-throw.ts +0 -1
  212. package/test-tooling/rollup/app.js +0 -21
  213. package/test-tooling/rollup/rollup.config.ts +0 -14
  214. package/test-tooling/rollup/worker.js +0 -7
  215. package/test-tooling/tsconfig/minimal.ts +0 -12
  216. package/test-tooling/webpack/addition-worker.ts +0 -9
  217. package/test-tooling/webpack/app-with-inlined-worker.ts +0 -28
  218. package/test-tooling/webpack/app.ts +0 -61
  219. package/test-tooling/webpack/pool-worker.ts +0 -5
  220. package/test-tooling/webpack/raw-loader.d.ts +0 -4
  221. package/test-tooling/webpack/webpack.chromium.mocha.ts +0 -21
  222. package/test-tooling/webpack/webpack.node.config.js +0 -29
  223. package/test-tooling/webpack/webpack.web.config.js +0 -28
  224. package/types/webworker.d.ts +0 -9
  225. package/worker.d.ts +0 -2
  226. package/worker.js +0 -2
  227. package/worker.mjs +0 -6
@@ -1,205 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.defaultPoolSize = void 0;
7
- exports.getWorkerImplementation = getWorkerImplementation;
8
- exports.isWorkerRuntime = isWorkerRuntime;
9
- const node_events_1 = require("node:events");
10
- const node_os_1 = require("node:os");
11
- const node_path_1 = __importDefault(require("node:path"));
12
- const node_url_1 = require("node:url");
13
- const callsites_3_1_0_1 = __importDefault(require("callsites-3-1-0"));
14
- let tsNodeAvailable;
15
- exports.defaultPoolSize = (0, node_os_1.cpus)().length;
16
- function detectTsNode() {
17
- if (typeof __non_webpack_require__ === 'function') {
18
- return false;
19
- }
20
- if (tsNodeAvailable) {
21
- return tsNodeAvailable;
22
- }
23
- try {
24
- eval('require').resolve('ts-node');
25
- tsNodeAvailable = true;
26
- }
27
- catch (error) {
28
- if (error && error.code === 'MODULE_NOT_FOUND') {
29
- tsNodeAvailable = false;
30
- }
31
- else {
32
- throw error;
33
- }
34
- }
35
- return tsNodeAvailable;
36
- }
37
- function createTsNodeModule(scriptPath) {
38
- return `
39
- require("ts-node/register/transpile-only");
40
- require(${JSON.stringify(scriptPath)});
41
- `;
42
- }
43
- function rebaseScriptPath(scriptPath, ignoreRegex) {
44
- const parentCallSite = (0, callsites_3_1_0_1.default)().find((callsite) => {
45
- const filename = callsite.getFileName();
46
- return Boolean(filename && !filename.match(ignoreRegex) && !/[/\\]master[/\\]implementation/.test(filename) && !/^internal\/process/.test(filename));
47
- });
48
- const rawCallerPath = parentCallSite ? parentCallSite.getFileName() : null;
49
- let callerPath = rawCallerPath ? rawCallerPath : null;
50
- if (callerPath && callerPath.startsWith('file:')) {
51
- callerPath = (0, node_url_1.fileURLToPath)(callerPath);
52
- }
53
- return callerPath ? node_path_1.default.join(node_path_1.default.dirname(callerPath), scriptPath) : scriptPath;
54
- }
55
- function resolveScriptPath(scriptPath, baseURL) {
56
- const makeRelative = (filePath) => {
57
- return node_path_1.default.isAbsolute(filePath) ? filePath : node_path_1.default.join(baseURL || eval('__dirname'), filePath);
58
- };
59
- return typeof __non_webpack_require__ === 'function'
60
- ? __non_webpack_require__.resolve(makeRelative(scriptPath))
61
- : eval('require').resolve(makeRelative(rebaseScriptPath(scriptPath, /[/\\]worker_threads[/\\]/)));
62
- }
63
- function initWorkerThreadsWorker() {
64
- const NativeWorker = typeof __non_webpack_require__ === 'function' ? __non_webpack_require__('worker_threads').Worker : eval('require')('worker_threads').Worker;
65
- let allWorkers = [];
66
- class Worker extends NativeWorker {
67
- mappedEventListeners;
68
- constructor(scriptPath, options) {
69
- const resolvedScriptPath = options && options.fromSource ? null : resolveScriptPath(scriptPath, (options || {})._baseURL);
70
- if (!resolvedScriptPath) {
71
- const sourceCode = scriptPath;
72
- super(sourceCode, { ...options, eval: true });
73
- }
74
- else if (/\.tsx?$/i.test(resolvedScriptPath) && detectTsNode()) {
75
- super(createTsNodeModule(resolvedScriptPath), { ...options, eval: true });
76
- }
77
- else if (/\.asar[/\\]/.test(resolvedScriptPath)) {
78
- super(resolvedScriptPath.replace(/\.asar([/\\])/, '.asar.unpacked$1'), options);
79
- }
80
- else {
81
- super(resolvedScriptPath, options);
82
- }
83
- this.mappedEventListeners = new WeakMap();
84
- allWorkers.push(this);
85
- }
86
- addEventListener(eventName, rawListener) {
87
- const listener = (message) => {
88
- rawListener({ data: message });
89
- };
90
- this.mappedEventListeners.set(rawListener, listener);
91
- this.on(eventName, listener);
92
- }
93
- removeEventListener(eventName, rawListener) {
94
- const listener = this.mappedEventListeners.get(rawListener) || rawListener;
95
- this.off(eventName, listener);
96
- }
97
- }
98
- const terminateWorkersAndMaster = () => {
99
- Promise.all(allWorkers.map(worker => worker.terminate())).then(() => process.exit(0), () => process.exit(1));
100
- allWorkers = [];
101
- };
102
- process.on('SIGINT', () => terminateWorkersAndMaster());
103
- process.on('SIGTERM', () => terminateWorkersAndMaster());
104
- class BlobWorker extends Worker {
105
- constructor(blob, options) {
106
- super(Buffer.from(blob).toString('utf-8'), { ...options, fromSource: true });
107
- }
108
- static fromText(source, options) {
109
- return new Worker(source, { ...options, fromSource: true });
110
- }
111
- }
112
- return {
113
- blob: BlobWorker,
114
- default: Worker,
115
- };
116
- }
117
- function initTinyWorker() {
118
- const TinyWorker = require('tiny-worker');
119
- let allWorkers = [];
120
- class Worker extends TinyWorker {
121
- emitter;
122
- constructor(scriptPath, options) {
123
- const resolvedScriptPath = options && options.fromSource
124
- ? null
125
- : process.platform === 'win32'
126
- ? `file:///${resolveScriptPath(scriptPath).replaceAll('\\', '/')}`
127
- : resolveScriptPath(scriptPath);
128
- if (!resolvedScriptPath) {
129
- const sourceCode = scriptPath;
130
- super(new Function(sourceCode), [], { esm: true });
131
- }
132
- else if (/\.tsx?$/i.test(resolvedScriptPath) && detectTsNode()) {
133
- super(new Function(createTsNodeModule(resolveScriptPath(scriptPath))), [], { esm: true });
134
- }
135
- else if (/\.asar[/\\]/.test(resolvedScriptPath)) {
136
- super(resolvedScriptPath.replace(/\.asar([/\\])/, '.asar.unpacked$1'), [], { esm: true });
137
- }
138
- else {
139
- super(resolvedScriptPath, [], { esm: true });
140
- }
141
- allWorkers.push(this);
142
- this.emitter = new node_events_1.EventEmitter();
143
- this.onerror = (error) => this.emitter.emit('error', error);
144
- this.onmessage = (message) => this.emitter.emit('message', message);
145
- }
146
- addEventListener(eventName, listener) {
147
- this.emitter.addListener(eventName, listener);
148
- }
149
- removeEventListener(eventName, listener) {
150
- this.emitter.removeListener(eventName, listener);
151
- }
152
- terminate() {
153
- allWorkers = allWorkers.filter(worker => worker !== this);
154
- return super.terminate();
155
- }
156
- }
157
- const terminateWorkersAndMaster = () => {
158
- Promise.all(allWorkers.map(worker => worker.terminate())).then(() => process.exit(0), () => process.exit(1));
159
- allWorkers = [];
160
- };
161
- process.on('SIGINT', () => terminateWorkersAndMaster());
162
- process.on('SIGTERM', () => terminateWorkersAndMaster());
163
- class BlobWorker extends Worker {
164
- constructor(blob, options) {
165
- super(Buffer.from(blob).toString('utf-8'), { ...options, fromSource: true });
166
- }
167
- static fromText(source, options) {
168
- return new Worker(source, { ...options, fromSource: true });
169
- }
170
- }
171
- return {
172
- blob: BlobWorker,
173
- default: Worker,
174
- };
175
- }
176
- let implementation;
177
- let isTinyWorker;
178
- function selectWorkerImplementation() {
179
- try {
180
- isTinyWorker = false;
181
- return initWorkerThreadsWorker();
182
- }
183
- catch {
184
- console.debug('Node worker_threads not available. Trying to fall back to tiny-worker polyfill...');
185
- isTinyWorker = true;
186
- return initTinyWorker();
187
- }
188
- }
189
- function getWorkerImplementation() {
190
- if (!implementation) {
191
- implementation = selectWorkerImplementation();
192
- }
193
- return implementation;
194
- }
195
- function isWorkerRuntime() {
196
- if (isTinyWorker) {
197
- return self !== undefined && self['postMessage'] ? true : false;
198
- }
199
- else {
200
- const isMainThread = typeof __non_webpack_require__ === 'function'
201
- ? __non_webpack_require__('worker_threads').isMainThread
202
- : eval('require')('worker_threads').isMainThread;
203
- return !isMainThread;
204
- }
205
- }
@@ -1,14 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isWorkerRuntime = exports.Worker = exports.BlobWorker = exports.Thread = exports.spawn = exports.Pool = void 0;
4
- const implementation_1 = require("./implementation");
5
- var pool_1 = require("./pool");
6
- Object.defineProperty(exports, "Pool", { enumerable: true, get: function () { return pool_1.Pool; } });
7
- var spawn_1 = require("./spawn");
8
- Object.defineProperty(exports, "spawn", { enumerable: true, get: function () { return spawn_1.spawn; } });
9
- var thread_1 = require("./thread");
10
- Object.defineProperty(exports, "Thread", { enumerable: true, get: function () { return thread_1.Thread; } });
11
- exports.BlobWorker = (0, implementation_1.getWorkerImplementation)().blob;
12
- exports.Worker = (0, implementation_1.getWorkerImplementation)().default;
13
- var implementation_2 = require("./implementation");
14
- Object.defineProperty(exports, "isWorkerRuntime", { enumerable: true, get: function () { return implementation_2.isWorkerRuntime; } });
@@ -1,121 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.createProxyFunction = createProxyFunction;
7
- exports.createProxyModule = createProxyModule;
8
- const debug_1 = __importDefault(require("debug"));
9
- const observable_fns_1 = require("observable-fns");
10
- const common_1 = require("../common");
11
- const observable_promise_1 = require("../observable-promise");
12
- const transferable_1 = require("../transferable");
13
- const messages_1 = require("../types/messages");
14
- const debugMessages = (0, debug_1.default)('threads:master:messages');
15
- let nextJobUID = 1;
16
- const dedupe = (array) => [...new Set(array)];
17
- const isJobErrorMessage = (data) => data && data.type === messages_1.WorkerMessageType.error;
18
- const isJobResultMessage = (data) => data && data.type === messages_1.WorkerMessageType.result;
19
- const isJobStartMessage = (data) => data && data.type === messages_1.WorkerMessageType.running;
20
- function createObservableForJob(worker, jobUID) {
21
- return new observable_fns_1.Observable((observer) => {
22
- let asyncType;
23
- const messageHandler = ((event) => {
24
- debugMessages('Message from worker:', event.data);
25
- if (!event.data || event.data.uid !== jobUID)
26
- return;
27
- if (isJobStartMessage(event.data)) {
28
- asyncType = event.data.resultType;
29
- }
30
- else if (isJobResultMessage(event.data)) {
31
- if (asyncType === 'promise') {
32
- if (event.data.payload !== undefined) {
33
- observer.next((0, common_1.deserialize)(event.data.payload));
34
- }
35
- observer.complete();
36
- worker.removeEventListener('message', messageHandler);
37
- }
38
- else {
39
- if (event.data.payload) {
40
- observer.next((0, common_1.deserialize)(event.data.payload));
41
- }
42
- if (event.data.complete) {
43
- observer.complete();
44
- worker.removeEventListener('message', messageHandler);
45
- }
46
- }
47
- }
48
- else if (isJobErrorMessage(event.data)) {
49
- const error = (0, common_1.deserialize)(event.data.error);
50
- if (asyncType === 'promise' || !asyncType) {
51
- observer.error(error);
52
- }
53
- else {
54
- observer.error(error);
55
- }
56
- worker.removeEventListener('message', messageHandler);
57
- }
58
- });
59
- worker.addEventListener('message', messageHandler);
60
- return () => {
61
- if (asyncType === 'observable' || !asyncType) {
62
- const cancelMessage = {
63
- type: messages_1.MasterMessageType.cancel,
64
- uid: jobUID,
65
- };
66
- worker.postMessage(cancelMessage);
67
- }
68
- worker.removeEventListener('message', messageHandler);
69
- };
70
- });
71
- }
72
- function prepareArguments(rawArgs) {
73
- if (rawArgs.length === 0) {
74
- return {
75
- args: [],
76
- transferables: [],
77
- };
78
- }
79
- const args = [];
80
- const transferables = [];
81
- for (const arg of rawArgs) {
82
- if ((0, transferable_1.isTransferDescriptor)(arg)) {
83
- args.push((0, common_1.serialize)(arg.send));
84
- transferables.push(...arg.transferables);
85
- }
86
- else {
87
- args.push((0, common_1.serialize)(arg));
88
- }
89
- }
90
- return {
91
- args,
92
- transferables: transferables.length === 0 ? transferables : dedupe(transferables),
93
- };
94
- }
95
- function createProxyFunction(worker, method) {
96
- return ((...rawArgs) => {
97
- const uid = nextJobUID++;
98
- const { args, transferables } = prepareArguments(rawArgs);
99
- const runMessage = {
100
- args,
101
- method,
102
- type: messages_1.MasterMessageType.run,
103
- uid,
104
- };
105
- debugMessages('Sending command to run function to worker:', runMessage);
106
- try {
107
- worker.postMessage(runMessage, transferables);
108
- }
109
- catch (error) {
110
- return observable_promise_1.ObservablePromise.from(Promise.reject(error));
111
- }
112
- return observable_promise_1.ObservablePromise.from((0, observable_fns_1.multicast)(createObservableForJob(worker, uid)));
113
- });
114
- }
115
- function createProxyModule(worker, methodNames) {
116
- const proxy = {};
117
- for (const methodName of methodNames) {
118
- proxy[methodName] = createProxyFunction(worker, methodName);
119
- }
120
- return proxy;
121
- }
@@ -1,14 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PoolEventType = void 0;
4
- var PoolEventType;
5
- (function (PoolEventType) {
6
- PoolEventType["initialized"] = "initialized";
7
- PoolEventType["taskCanceled"] = "taskCanceled";
8
- PoolEventType["taskCompleted"] = "taskCompleted";
9
- PoolEventType["taskFailed"] = "taskFailed";
10
- PoolEventType["taskQueued"] = "taskQueued";
11
- PoolEventType["taskQueueDrained"] = "taskQueueDrained";
12
- PoolEventType["taskStart"] = "taskStart";
13
- PoolEventType["terminated"] = "terminated";
14
- })(PoolEventType || (exports.PoolEventType = PoolEventType = {}));
@@ -1,262 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.Thread = exports.PoolEventType = exports.Pool = void 0;
7
- const debug_1 = __importDefault(require("debug"));
8
- const observable_fns_1 = require("observable-fns");
9
- const ponyfills_1 = require("../ponyfills");
10
- const implementation_1 = require("./implementation");
11
- const pool_types_1 = require("./pool-types");
12
- const thread_1 = require("./thread");
13
- let nextPoolID = 1;
14
- function createArray(size) {
15
- const array = [];
16
- for (let index = 0; index < size; index++) {
17
- array.push(index);
18
- }
19
- return array;
20
- }
21
- function delay(ms) {
22
- return new Promise(resolve => setTimeout(resolve, ms));
23
- }
24
- function flatMap(array, mapper) {
25
- return array.reduce((flattened, element) => [...flattened, ...mapper(element)], []);
26
- }
27
- function slugify(text) {
28
- return text.replaceAll(/\W/g, ' ').trim().replaceAll(/\s+/g, '-');
29
- }
30
- function spawnWorkers(spawnWorker, count) {
31
- return createArray(count).map(() => ({
32
- init: spawnWorker(),
33
- runningTasks: [],
34
- }));
35
- }
36
- class WorkerPool {
37
- static EventType = pool_types_1.PoolEventType;
38
- debug;
39
- eventObservable;
40
- options;
41
- workers;
42
- eventSubject = new observable_fns_1.Subject();
43
- initErrors = [];
44
- isClosing = false;
45
- nextTaskID = 1;
46
- taskQueue = [];
47
- constructor(spawnWorker, optionsOrSize) {
48
- const options = typeof optionsOrSize === 'number' ? { size: optionsOrSize } : optionsOrSize || {};
49
- const { size = implementation_1.defaultPoolSize } = options;
50
- this.debug = (0, debug_1.default)(`threads:pool:${slugify(options.name || String(nextPoolID++))}`);
51
- this.options = options;
52
- this.workers = spawnWorkers(spawnWorker, size);
53
- this.eventObservable = (0, observable_fns_1.multicast)(observable_fns_1.Observable.from(this.eventSubject));
54
- Promise.all(this.workers.map(worker => worker.init)).then(() => this.eventSubject.next({
55
- size: this.workers.length,
56
- type: pool_types_1.PoolEventType.initialized,
57
- }), (error) => {
58
- this.debug('Error while initializing pool worker:', error);
59
- this.eventSubject.error(error);
60
- this.initErrors.push(error);
61
- });
62
- }
63
- findIdlingWorker() {
64
- const { concurrency = 1 } = this.options;
65
- return this.workers.find(worker => worker.runningTasks.length < concurrency);
66
- }
67
- async runPoolTask(worker, task) {
68
- const workerID = this.workers.indexOf(worker) + 1;
69
- this.debug(`Running task #${task.id} on worker #${workerID}...`);
70
- this.eventSubject.next({
71
- taskID: task.id,
72
- type: pool_types_1.PoolEventType.taskStart,
73
- workerID,
74
- });
75
- try {
76
- const returnValue = await task.run(await worker.init);
77
- this.debug(`Task #${task.id} completed successfully`);
78
- this.eventSubject.next({
79
- returnValue,
80
- taskID: task.id,
81
- type: pool_types_1.PoolEventType.taskCompleted,
82
- workerID,
83
- });
84
- }
85
- catch (error) {
86
- this.debug(`Task #${task.id} failed`);
87
- this.eventSubject.next({
88
- error,
89
- taskID: task.id,
90
- type: pool_types_1.PoolEventType.taskFailed,
91
- workerID,
92
- });
93
- }
94
- }
95
- async run(worker, task) {
96
- const runPromise = (async () => {
97
- const removeTaskFromWorkersRunningTasks = () => {
98
- worker.runningTasks = worker.runningTasks.filter(someRunPromise => someRunPromise !== runPromise);
99
- };
100
- await delay(0);
101
- try {
102
- await this.runPoolTask(worker, task);
103
- }
104
- finally {
105
- removeTaskFromWorkersRunningTasks();
106
- if (!this.isClosing) {
107
- this.scheduleWork();
108
- }
109
- }
110
- })();
111
- worker.runningTasks.push(runPromise);
112
- }
113
- scheduleWork() {
114
- this.debug('Attempt de-queueing a task in order to run it...');
115
- const availableWorker = this.findIdlingWorker();
116
- if (!availableWorker)
117
- return;
118
- const nextTask = this.taskQueue.shift();
119
- if (!nextTask) {
120
- this.debug('Task queue is empty');
121
- this.eventSubject.next({ type: pool_types_1.PoolEventType.taskQueueDrained });
122
- return;
123
- }
124
- this.run(availableWorker, nextTask);
125
- }
126
- taskCompletion(taskID) {
127
- return new Promise((resolve, reject) => {
128
- const eventSubscription = this.events().subscribe((event) => {
129
- if (event.type === pool_types_1.PoolEventType.taskCompleted && event.taskID === taskID) {
130
- eventSubscription.unsubscribe();
131
- resolve(event.returnValue);
132
- }
133
- else if (event.type === pool_types_1.PoolEventType.taskFailed && event.taskID === taskID) {
134
- eventSubscription.unsubscribe();
135
- reject(event.error);
136
- }
137
- else if (event.type === pool_types_1.PoolEventType.terminated) {
138
- eventSubscription.unsubscribe();
139
- reject(new Error('Pool has been terminated before task was run.'));
140
- }
141
- });
142
- });
143
- }
144
- async settled(allowResolvingImmediately = false) {
145
- const getCurrentlyRunningTasks = () => flatMap(this.workers, worker => worker.runningTasks);
146
- const taskFailures = [];
147
- const failureSubscription = this.eventObservable.subscribe((event) => {
148
- if (event.type === pool_types_1.PoolEventType.taskFailed) {
149
- taskFailures.push(event.error);
150
- }
151
- });
152
- if (this.initErrors.length > 0) {
153
- throw this.initErrors[0];
154
- }
155
- if (allowResolvingImmediately && this.taskQueue.length === 0) {
156
- await (0, ponyfills_1.allSettled)(getCurrentlyRunningTasks());
157
- return taskFailures;
158
- }
159
- await new Promise((resolve, reject) => {
160
- const subscription = this.eventObservable.subscribe({
161
- error: reject,
162
- next(event) {
163
- if (event.type === pool_types_1.PoolEventType.taskQueueDrained) {
164
- subscription.unsubscribe();
165
- resolve(void 0);
166
- }
167
- },
168
- });
169
- });
170
- await (0, ponyfills_1.allSettled)(getCurrentlyRunningTasks());
171
- failureSubscription.unsubscribe();
172
- return taskFailures;
173
- }
174
- async completed(allowResolvingImmediately = false) {
175
- const settlementPromise = this.settled(allowResolvingImmediately);
176
- const earlyExitPromise = new Promise((resolve, reject) => {
177
- const subscription = this.eventObservable.subscribe({
178
- error: reject,
179
- next(event) {
180
- if (event.type === pool_types_1.PoolEventType.taskQueueDrained) {
181
- subscription.unsubscribe();
182
- resolve(settlementPromise);
183
- }
184
- else if (event.type === pool_types_1.PoolEventType.taskFailed) {
185
- subscription.unsubscribe();
186
- reject(event.error);
187
- }
188
- },
189
- });
190
- });
191
- const errors = await Promise.race([settlementPromise, earlyExitPromise]);
192
- if (errors.length > 0) {
193
- throw errors[0];
194
- }
195
- }
196
- events() {
197
- return this.eventObservable;
198
- }
199
- queue(taskFunction) {
200
- const { maxQueuedJobs = Number.POSITIVE_INFINITY } = this.options;
201
- if (this.isClosing) {
202
- throw new Error('Cannot schedule pool tasks after terminate() has been called.');
203
- }
204
- if (this.initErrors.length > 0) {
205
- throw this.initErrors[0];
206
- }
207
- const taskID = this.nextTaskID++;
208
- const taskCompletion = this.taskCompletion(taskID);
209
- taskCompletion.catch((error) => {
210
- this.debug(`Task #${taskID} errored:`, error);
211
- });
212
- const task = {
213
- cancel: () => {
214
- if (!this.taskQueue.includes(task))
215
- return;
216
- this.taskQueue = this.taskQueue.filter(someTask => someTask !== task);
217
- this.eventSubject.next({
218
- taskID: task.id,
219
- type: pool_types_1.PoolEventType.taskCanceled,
220
- });
221
- },
222
- id: taskID,
223
- run: taskFunction,
224
- then: taskCompletion.then.bind(taskCompletion),
225
- };
226
- if (this.taskQueue.length >= maxQueuedJobs) {
227
- throw new Error('Maximum number of pool tasks queued. Refusing to queue another one.\n'
228
- + 'This usually happens for one of two reasons: We are either at peak '
229
- + "workload right now or some tasks just won't finish, thus blocking the pool.");
230
- }
231
- this.debug(`Queueing task #${task.id}...`);
232
- this.taskQueue.push(task);
233
- this.eventSubject.next({
234
- taskID: task.id,
235
- type: pool_types_1.PoolEventType.taskQueued,
236
- });
237
- this.scheduleWork();
238
- return task;
239
- }
240
- async terminate(force) {
241
- this.isClosing = true;
242
- if (!force) {
243
- await this.completed(true);
244
- }
245
- this.eventSubject.next({
246
- remainingQueue: [...this.taskQueue],
247
- type: pool_types_1.PoolEventType.terminated,
248
- });
249
- this.eventSubject.complete();
250
- await Promise.all(this.workers.map(async (worker) => thread_1.Thread.terminate(await worker.init)));
251
- }
252
- }
253
- function PoolConstructor(spawnWorker, optionsOrSize) {
254
- return new WorkerPool(spawnWorker, optionsOrSize);
255
- }
256
- ;
257
- PoolConstructor.EventType = pool_types_1.PoolEventType;
258
- exports.Pool = PoolConstructor;
259
- var pool_types_2 = require("./pool-types");
260
- Object.defineProperty(exports, "PoolEventType", { enumerable: true, get: function () { return pool_types_2.PoolEventType; } });
261
- var thread_2 = require("./thread");
262
- Object.defineProperty(exports, "Thread", { enumerable: true, get: function () { return thread_2.Thread; } });
@@ -1,11 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const index_1 = require("./index");
4
- if (typeof globalThis !== 'undefined') {
5
- ;
6
- globalThis.Worker = index_1.Worker;
7
- }
8
- else if (window !== undefined) {
9
- ;
10
- window.Worker = index_1.Worker;
11
- }