@parcel/workers 2.0.0-nightly.144 → 2.0.0-nightly.1441

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. package/index.d.ts +23 -0
  2. package/lib/Handle.js +16 -58
  3. package/lib/Worker.js +95 -57
  4. package/lib/WorkerFarm.js +272 -192
  5. package/lib/backend.js +4 -6
  6. package/lib/bus.js +10 -11
  7. package/lib/child.js +140 -116
  8. package/lib/childState.js +1 -2
  9. package/lib/core-worker.browser.js +4 -0
  10. package/lib/core-worker.js +4 -0
  11. package/lib/cpuCount.js +36 -25
  12. package/lib/index.js +34 -30
  13. package/lib/process/ProcessChild.js +18 -24
  14. package/lib/process/ProcessWorker.js +27 -38
  15. package/lib/threads/ThreadsChild.js +26 -28
  16. package/lib/threads/ThreadsWorker.js +25 -31
  17. package/lib/web/WebChild.js +44 -0
  18. package/lib/web/WebWorker.js +85 -0
  19. package/package.json +19 -8
  20. package/src/Handle.js +10 -39
  21. package/src/Worker.js +92 -22
  22. package/src/WorkerFarm.js +267 -62
  23. package/src/backend.js +5 -0
  24. package/src/bus.js +3 -2
  25. package/src/child.js +95 -26
  26. package/src/core-worker.browser.js +3 -0
  27. package/src/core-worker.js +2 -0
  28. package/src/cpuCount.js +23 -10
  29. package/src/index.js +8 -2
  30. package/src/process/ProcessChild.js +2 -1
  31. package/src/process/ProcessWorker.js +1 -1
  32. package/src/threads/ThreadsWorker.js +2 -2
  33. package/src/types.js +1 -1
  34. package/src/web/WebChild.js +50 -0
  35. package/src/web/WebWorker.js +85 -0
  36. package/test/cpuCount.test.js +1 -1
  37. package/test/integration/workerfarm/console.js +1 -1
  38. package/test/integration/workerfarm/logging.js +1 -1
  39. package/test/integration/workerfarm/reverse-handle.js +2 -2
  40. package/test/workerfarm.js +5 -5
  41. package/lib/Profiler.js +0 -70
  42. package/lib/Trace.js +0 -126
  43. package/src/Profiler.js +0 -93
  44. package/src/Trace.js +0 -121
package/lib/backend.js CHANGED
@@ -5,31 +5,29 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.detectBackend = detectBackend;
7
7
  exports.getWorkerBackend = getWorkerBackend;
8
-
9
8
  function detectBackend() {
9
+ // $FlowFixMe
10
+ if (process.browser) return 'web';
10
11
  switch (process.env.PARCEL_WORKER_BACKEND) {
11
12
  case 'threads':
12
13
  case 'process':
13
14
  return process.env.PARCEL_WORKER_BACKEND;
14
15
  }
15
-
16
16
  try {
17
17
  require('worker_threads');
18
-
19
18
  return 'threads';
20
19
  } catch (err) {
21
20
  return 'process';
22
21
  }
23
22
  }
24
-
25
23
  function getWorkerBackend(backend) {
26
24
  switch (backend) {
27
25
  case 'threads':
28
26
  return require('./threads/ThreadsWorker').default;
29
-
30
27
  case 'process':
31
28
  return require('./process/ProcessWorker').default;
32
-
29
+ case 'web':
30
+ return require('./web/WebWorker').default;
33
31
  default:
34
32
  throw new Error(`Invalid backend: ${backend}`);
35
33
  }
package/lib/bus.js CHANGED
@@ -4,30 +4,29 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
-
8
- var _events = _interopRequireDefault(require("events"));
9
-
7
+ function _events() {
8
+ const data = _interopRequireDefault(require("events"));
9
+ _events = function () {
10
+ return data;
11
+ };
12
+ return data;
13
+ }
10
14
  var _childState = require("./childState");
11
-
12
15
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
-
14
- class Bus extends _events.default {
16
+ class Bus extends _events().default {
15
17
  emit(event, ...args) {
16
18
  if (_childState.child) {
17
19
  _childState.child.workerApi.callMaster({
18
- location: __filename,
20
+ // $FlowFixMe
21
+ location: process.browser ? '@parcel/workers/src/bus.js' : __filename,
19
22
  method: 'emit',
20
23
  args: [event, ...args]
21
24
  }, false);
22
-
23
25
  return true;
24
26
  } else {
25
27
  return super.emit(event, ...args);
26
28
  }
27
29
  }
28
-
29
30
  }
30
-
31
31
  var _default = new Bus();
32
-
33
32
  exports.default = _default;
package/lib/child.js CHANGED
@@ -4,76 +4,89 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.Child = void 0;
7
-
8
- var _assert = _interopRequireDefault(require("assert"));
9
-
10
- var _nullthrows = _interopRequireDefault(require("nullthrows"));
11
-
12
- var _logger = _interopRequireWildcard(require("@parcel/logger"));
13
-
14
- var _diagnostic = _interopRequireWildcard(require("@parcel/diagnostic"));
15
-
7
+ var coreWorker = _interopRequireWildcard(require("./core-worker"));
8
+ function _assert() {
9
+ const data = _interopRequireDefault(require("assert"));
10
+ _assert = function () {
11
+ return data;
12
+ };
13
+ return data;
14
+ }
15
+ function _nullthrows() {
16
+ const data = _interopRequireDefault(require("nullthrows"));
17
+ _nullthrows = function () {
18
+ return data;
19
+ };
20
+ return data;
21
+ }
22
+ function _logger() {
23
+ const data = _interopRequireWildcard(require("@parcel/logger"));
24
+ _logger = function () {
25
+ return data;
26
+ };
27
+ return data;
28
+ }
29
+ function _diagnostic() {
30
+ const data = _interopRequireWildcard(require("@parcel/diagnostic"));
31
+ _diagnostic = function () {
32
+ return data;
33
+ };
34
+ return data;
35
+ }
36
+ function _core() {
37
+ const data = require("@parcel/core");
38
+ _core = function () {
39
+ return data;
40
+ };
41
+ return data;
42
+ }
16
43
  var _bus = _interopRequireDefault(require("./bus"));
17
-
18
- var _Profiler = _interopRequireDefault(require("./Profiler"));
19
-
20
- var _Handle = _interopRequireDefault(require("./Handle"));
21
-
22
- function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
23
-
24
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
25
-
44
+ function _profiler() {
45
+ const data = require("@parcel/profiler");
46
+ _profiler = function () {
47
+ return data;
48
+ };
49
+ return data;
50
+ }
51
+ var _Handle2 = _interopRequireDefault(require("./Handle"));
26
52
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
27
-
28
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
29
-
30
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
31
-
32
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
33
-
53
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
54
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
55
+ // The import of './Handle' should really be imported eagerly (with @babel/plugin-transform-modules-commonjs's lazy mode).
56
+ const Handle = _Handle2.default;
34
57
  class Child {
58
+ callQueue = [];
59
+ maxConcurrentCalls = 10;
60
+ responseId = 0;
61
+ responseQueue = new Map();
62
+ handles = new Map();
63
+ sharedReferences = new Map();
64
+ sharedReferencesByValue = new Map();
35
65
  constructor(ChildBackend) {
36
- _defineProperty(this, "callQueue", []);
66
+ this.child = new ChildBackend(m => {
67
+ this.messageListener(m);
68
+ }, () => this.handleEnd());
37
69
 
38
- _defineProperty(this, "childId", void 0);
39
-
40
- _defineProperty(this, "maxConcurrentCalls", 10);
41
-
42
- _defineProperty(this, "module", void 0);
43
-
44
- _defineProperty(this, "responseId", 0);
45
-
46
- _defineProperty(this, "responseQueue", new Map());
47
-
48
- _defineProperty(this, "loggerDisposable", void 0);
49
-
50
- _defineProperty(this, "child", void 0);
51
-
52
- _defineProperty(this, "profiler", void 0);
53
-
54
- _defineProperty(this, "workerApi", void 0);
55
-
56
- _defineProperty(this, "handles", new Map());
57
-
58
- _defineProperty(this, "sharedReferences", new Map());
59
-
60
- _defineProperty(this, "sharedReferencesByValue", new Map());
61
-
62
- _defineProperty(this, "workerApi", {
63
- callMaster: (request, awaitResponse = true) => this.addCall(request, awaitResponse),
64
- createReverseHandle: fn => this.createReverseHandle(fn),
65
- getSharedReference: ref => this.sharedReferences.get(ref),
66
- resolveSharedReference: value => this.sharedReferencesByValue.get(value)
67
- });
68
-
69
- this.child = new ChildBackend(this.messageListener.bind(this), this.handleEnd.bind(this)); // Monitior all logging events inside this child process and forward to
70
+ // Monitior all logging events inside this child process and forward to
70
71
  // the main process via the bus.
71
-
72
- this.loggerDisposable = _logger.default.onLog(event => {
72
+ this.loggerDisposable = _logger().default.onLog(event => {
73
73
  _bus.default.emit('logEvent', event);
74
74
  });
75
+ // .. and do the same for trace events
76
+ this.tracerDisposable = _profiler().tracer.onTrace(event => {
77
+ _bus.default.emit('traceEvent', event);
78
+ });
75
79
  }
76
-
80
+ workerApi = {
81
+ callMaster: (request, awaitResponse = true) => this.addCall(request, awaitResponse),
82
+ createReverseHandle: fn => this.createReverseHandle(fn),
83
+ runHandle: (handle, args) => this.workerApi.callMaster({
84
+ handle: handle.id,
85
+ args
86
+ }, true),
87
+ getSharedReference: ref => this.sharedReferences.get(ref),
88
+ resolveSharedReference: value => this.sharedReferencesByValue.get(value)
89
+ };
77
90
  messageListener(message) {
78
91
  if (message.type === 'response') {
79
92
  return this.handleResponse(message);
@@ -81,17 +94,26 @@ class Child {
81
94
  return this.handleRequest(message);
82
95
  }
83
96
  }
84
-
85
97
  send(data) {
86
98
  this.child.send(data);
87
99
  }
88
-
89
- childInit(module, childId) {
90
- // $FlowFixMe this must be dynamic
91
- this.module = require(module);
100
+ async childInit(module, childId) {
101
+ // $FlowFixMe
102
+ if (process.browser) {
103
+ if (module === '@parcel/core/src/worker.js') {
104
+ this.module = coreWorker;
105
+ } else {
106
+ throw new Error('No dynamic require possible: ' + module);
107
+ }
108
+ } else {
109
+ // $FlowFixMe this must be dynamic
110
+ this.module = require(module);
111
+ }
92
112
  this.childId = childId;
113
+ if (this.module.childInit != null) {
114
+ await this.module.childInit();
115
+ }
93
116
  }
94
-
95
117
  async handleRequest(data) {
96
118
  let {
97
119
  idx,
@@ -99,8 +121,7 @@ class Child {
99
121
  args,
100
122
  handle: handleId
101
123
  } = data;
102
- let child = (0, _nullthrows.default)(data.child);
103
-
124
+ let child = (0, _nullthrows().default)(data.child);
104
125
  const responseFromContent = content => ({
105
126
  idx,
106
127
  child,
@@ -108,20 +129,18 @@ class Child {
108
129
  contentType: 'data',
109
130
  content
110
131
  });
111
-
112
132
  const errorResponseFromError = e => ({
113
133
  idx,
114
134
  child,
115
135
  type: 'response',
116
136
  contentType: 'error',
117
- content: (0, _diagnostic.anyToDiagnostic)(e)
137
+ content: (0, _diagnostic().anyToDiagnostic)(e)
118
138
  });
119
-
120
139
  let result;
121
-
122
140
  if (handleId != null) {
123
141
  try {
124
- let fn = (0, _nullthrows.default)(this.handles.get(handleId)).fn;
142
+ var _this$handles$get;
143
+ let fn = (0, _nullthrows().default)((_this$handles$get = this.handles.get(handleId)) === null || _this$handles$get === void 0 ? void 0 : _this$handles$get.fn);
125
144
  result = responseFromContent(fn(...args));
126
145
  } catch (e) {
127
146
  result = errorResponseFromError(e);
@@ -129,22 +148,22 @@ class Child {
129
148
  } else if (method === 'childInit') {
130
149
  try {
131
150
  let [moduleName, childOptions] = args;
132
-
133
- if (childOptions.patchConsole) {
134
- (0, _logger.patchConsole)();
151
+ if (childOptions.shouldPatchConsole) {
152
+ (0, _logger().patchConsole)();
135
153
  } else {
136
- (0, _logger.unpatchConsole)();
154
+ (0, _logger().unpatchConsole)();
137
155
  }
138
-
139
- result = responseFromContent(this.childInit(moduleName, child));
156
+ if (childOptions.shouldTrace) {
157
+ _profiler().tracer.enable();
158
+ }
159
+ result = responseFromContent(await this.childInit(moduleName, child));
140
160
  } catch (e) {
141
161
  result = errorResponseFromError(e);
142
162
  }
143
163
  } else if (method === 'startProfile') {
144
- this.profiler = new _Profiler.default();
145
-
164
+ this.profiler = new (_profiler().SamplingProfiler)();
146
165
  try {
147
- result = responseFromContent((await this.profiler.startProfiling()));
166
+ result = responseFromContent(await this.profiler.startProfiling());
148
167
  } catch (e) {
149
168
  result = errorResponseFromError(e);
150
169
  }
@@ -155,81 +174,92 @@ class Child {
155
174
  } catch (e) {
156
175
  result = errorResponseFromError(e);
157
176
  }
177
+ } else if (method === 'takeHeapSnapshot') {
178
+ try {
179
+ let v8 = require('v8');
180
+ result = responseFromContent(v8.writeHeapSnapshot('heap-' + args[0] + '-' + (this.childId ? 'worker' + this.childId : 'main') + '.heapsnapshot'));
181
+ } catch (e) {
182
+ result = errorResponseFromError(e);
183
+ }
158
184
  } else if (method === 'createSharedReference') {
159
- let [ref, value] = args;
185
+ let [ref, _value] = args;
186
+ let value = _value instanceof ArrayBuffer ?
187
+ // In the case the value is pre-serialized as a buffer,
188
+ // deserialize it.
189
+ (0, _core().deserialize)(Buffer.from(_value)) : _value;
160
190
  this.sharedReferences.set(ref, value);
161
191
  this.sharedReferencesByValue.set(value, ref);
162
192
  result = responseFromContent(null);
163
193
  } else if (method === 'deleteSharedReference') {
164
- this.sharedReferences.delete(args[0]);
194
+ let ref = args[0];
195
+ let value = this.sharedReferences.get(ref);
196
+ this.sharedReferencesByValue.delete(value);
197
+ this.sharedReferences.delete(ref);
165
198
  result = responseFromContent(null);
166
199
  } else {
167
200
  try {
168
- result = responseFromContent(( // $FlowFixMe
169
- await this.module[method](this.workerApi, ...args)));
201
+ result = responseFromContent(
202
+ // $FlowFixMe
203
+ await this.module[method](this.workerApi, ...args));
170
204
  } catch (e) {
171
205
  result = errorResponseFromError(e);
172
206
  }
173
207
  }
174
-
175
- this.send(result);
208
+ try {
209
+ this.send(result);
210
+ } catch (e) {
211
+ result = this.send(errorResponseFromError(e));
212
+ }
176
213
  }
177
-
178
214
  handleResponse(data) {
179
- let idx = (0, _nullthrows.default)(data.idx);
215
+ let idx = (0, _nullthrows().default)(data.idx);
180
216
  let contentType = data.contentType;
181
217
  let content = data.content;
182
- let call = (0, _nullthrows.default)(this.responseQueue.get(idx));
183
-
218
+ let call = (0, _nullthrows().default)(this.responseQueue.get(idx));
184
219
  if (contentType === 'error') {
185
- (0, _assert.default)(typeof content !== 'string');
186
- call.reject(new _diagnostic.default({
220
+ (0, _assert().default)(typeof content !== 'string');
221
+ call.reject(new (_diagnostic().default)({
187
222
  diagnostic: content
188
223
  }));
189
224
  } else {
190
225
  call.resolve(content);
191
226
  }
227
+ this.responseQueue.delete(idx);
192
228
 
193
- this.responseQueue.delete(idx); // Process the next call
194
-
229
+ // Process the next call
195
230
  this.processQueue();
196
- } // Keep in mind to make sure responses to these calls are JSON.Stringify safe
197
-
231
+ }
198
232
 
233
+ // Keep in mind to make sure responses to these calls are JSON.Stringify safe
199
234
  addCall(request, awaitResponse = true) {
200
235
  var _promise;
201
-
202
236
  // $FlowFixMe
203
- let call = _objectSpread({}, request, {
237
+ let call = {
238
+ ...request,
204
239
  type: 'request',
205
240
  child: this.childId,
241
+ // $FlowFixMe Added in Flow 0.121.0 upgrade in #4381
206
242
  awaitResponse,
207
243
  resolve: () => {},
208
244
  reject: () => {}
209
- });
210
-
245
+ };
211
246
  let promise;
212
-
213
247
  if (awaitResponse) {
214
248
  promise = new Promise((resolve, reject) => {
215
249
  call.resolve = resolve;
216
250
  call.reject = reject;
217
251
  });
218
252
  }
219
-
220
253
  this.callQueue.push(call);
221
254
  this.processQueue();
222
255
  return (_promise = promise) !== null && _promise !== void 0 ? _promise : Promise.resolve();
223
256
  }
224
-
225
257
  sendRequest(call) {
226
258
  let idx;
227
-
228
259
  if (call.awaitResponse) {
229
260
  idx = this.responseId++;
230
261
  this.responseQueue.set(idx, call);
231
262
  }
232
-
233
263
  this.send({
234
264
  idx,
235
265
  child: call.child,
@@ -241,31 +271,25 @@ class Child {
241
271
  awaitResponse: call.awaitResponse
242
272
  });
243
273
  }
244
-
245
274
  processQueue() {
246
275
  if (!this.callQueue.length) {
247
276
  return;
248
277
  }
249
-
250
278
  if (this.responseQueue.size < this.maxConcurrentCalls) {
251
279
  this.sendRequest(this.callQueue.shift());
252
280
  }
253
281
  }
254
-
255
282
  handleEnd() {
256
283
  this.loggerDisposable.dispose();
284
+ this.tracerDisposable.dispose();
257
285
  }
258
-
259
286
  createReverseHandle(fn) {
260
- let handle = new _Handle.default({
287
+ let handle = new Handle({
261
288
  fn,
262
- workerApi: this.workerApi,
263
289
  childId: this.childId
264
290
  });
265
291
  this.handles.set(handle.id, handle);
266
292
  return handle;
267
293
  }
268
-
269
294
  }
270
-
271
295
  exports.Child = Child;
package/lib/childState.js CHANGED
@@ -3,14 +3,13 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.setChild = setChild;
7
6
  exports.child = void 0;
7
+ exports.setChild = setChild;
8
8
  // This file is imported by both the WorkerFarm and child implementation.
9
9
  // When a worker is inited, it sets the state in this file.
10
10
  // This way, WorkerFarm can access the state without directly importing the child code.
11
11
  let child = null;
12
12
  exports.child = child;
13
-
14
13
  function setChild(c) {
15
14
  exports.child = child = c;
16
15
  }
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+
3
+ // eslint-disable-next-line monorepo/no-internal-import
4
+ module.exports = require('@parcel/core/src/worker.js');
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+
3
+ // This is used only in browser builds
4
+ module.exports = {};
package/lib/cpuCount.js CHANGED
@@ -3,18 +3,26 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.detectRealCores = detectRealCores;
7
6
  exports.default = getCores;
8
-
9
- var _os = _interopRequireDefault(require("os"));
10
-
11
- var _child_process = require("child_process");
12
-
7
+ exports.detectRealCores = detectRealCores;
8
+ function _os() {
9
+ const data = _interopRequireDefault(require("os"));
10
+ _os = function () {
11
+ return data;
12
+ };
13
+ return data;
14
+ }
15
+ function _child_process() {
16
+ const data = require("child_process");
17
+ _child_process = function () {
18
+ return data;
19
+ };
20
+ return data;
21
+ }
13
22
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14
-
15
23
  const exec = command => {
16
24
  try {
17
- let stdout = (0, _child_process.execSync)(command, {
25
+ let stdout = (0, _child_process().execSync)(command, {
18
26
  encoding: 'utf8',
19
27
  // This prevents the command from outputting to the console
20
28
  stdio: [null, null, null]
@@ -24,45 +32,48 @@ const exec = command => {
24
32
  return '';
25
33
  }
26
34
  };
27
-
28
35
  function detectRealCores() {
29
- let platform = _os.default.platform();
30
-
36
+ let platform = _os().default.platform();
31
37
  let amount = 0;
32
-
33
38
  if (platform === 'linux') {
34
39
  amount = parseInt(exec('lscpu -p | egrep -v "^#" | sort -u -t, -k 2,4 | wc -l'), 10);
35
40
  } else if (platform === 'darwin') {
36
41
  amount = parseInt(exec('sysctl -n hw.physicalcpu_max'), 10);
42
+ } else if (platform === 'win32') {
43
+ const str = exec('wmic cpu get NumberOfCores').match(/\d+/g);
44
+ if (str !== null) {
45
+ amount = parseInt(str.filter(n => n !== '')[0], 10);
46
+ }
37
47
  }
38
-
39
48
  if (!amount || amount <= 0) {
40
49
  throw new Error('Could not detect cpu count!');
41
50
  }
42
-
43
51
  return amount;
44
52
  }
45
-
46
53
  let cores;
47
-
48
54
  function getCores(bypassCache = false) {
49
55
  // Do not re-run commands if we already have the count...
50
- // $FlowFixMe
51
56
  if (cores && !bypassCache) {
52
57
  return cores;
53
58
  }
54
59
 
55
- try {
56
- cores = detectRealCores();
57
- } catch (e) {
58
- // Guess the amount of real cores
59
- cores = _os.default.cpus().filter((cpu, index) => !cpu.model.includes('Intel') || index % 2 === 1).length;
60
- } // Another fallback
61
-
60
+ // $FlowFixMe
61
+ if (process.browser) {
62
+ // eslint-disable-next-line no-undef
63
+ cores = navigator.hardwareConcurrency / 2;
64
+ }
65
+ if (!cores) {
66
+ try {
67
+ cores = detectRealCores();
68
+ } catch (e) {
69
+ // Guess the amount of real cores
70
+ cores = _os().default.cpus().filter((cpu, index) => !cpu.model.includes('Intel') || index % 2 === 1).length;
71
+ }
72
+ }
62
73
 
74
+ // Another fallback
63
75
  if (!cores) {
64
76
  cores = 1;
65
77
  }
66
-
67
78
  return cores;
68
79
  }