@parcel/workers 2.0.0-nightly.149 → 2.0.0-nightly.1490

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 (44) hide show
  1. package/index.d.ts +23 -0
  2. package/lib/Handle.js +16 -58
  3. package/lib/Worker.js +103 -62
  4. package/lib/WorkerFarm.js +272 -192
  5. package/lib/backend.js +4 -6
  6. package/lib/bus.js +11 -13
  7. package/lib/child.js +140 -116
  8. package/lib/childState.js +2 -4
  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 +35 -32
  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 +95 -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,28 @@ 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
- var _default = new Bus();
32
-
33
- exports.default = _default;
31
+ var _default = exports.default = new Bus();
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(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
54
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
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,12 @@
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
- let child = null;
12
- exports.child = child;
13
-
11
+ let child = exports.child = null;
14
12
  function setChild(c) {
15
13
  exports.child = child = c;
16
14
  }
@@ -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
  }