@parcel/workers 2.0.0-nightly.142 → 2.0.0-nightly.1423

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.
package/src/child.js CHANGED
@@ -9,16 +9,20 @@ import type {
9
9
  WorkerResponse,
10
10
  ChildImpl,
11
11
  } from './types';
12
- import type {IDisposable} from '@parcel/types';
13
- import type {WorkerApi} from './WorkerFarm';
12
+ import type {Async, IDisposable} from '@parcel/types';
13
+ import type {SharedReference} from './WorkerFarm';
14
14
 
15
15
  import invariant from 'assert';
16
16
  import nullthrows from 'nullthrows';
17
17
  import Logger, {patchConsole, unpatchConsole} from '@parcel/logger';
18
18
  import ThrowableDiagnostic, {anyToDiagnostic} from '@parcel/diagnostic';
19
+ import {deserialize} from '@parcel/core';
19
20
  import bus from './bus';
20
- import Profiler from './Profiler';
21
- import Handle from './Handle';
21
+ import {SamplingProfiler, tracer} from '@parcel/profiler';
22
+ import _Handle from './Handle';
23
+
24
+ // The import of './Handle' should really be imported eagerly (with @babel/plugin-transform-modules-commonjs's lazy mode).
25
+ const Handle = _Handle;
22
26
 
23
27
  type ChildCall = WorkerRequest & {|
24
28
  resolve: (result: Promise<any> | any) => void,
@@ -30,20 +34,22 @@ export class Child {
30
34
  childId: ?number;
31
35
  maxConcurrentCalls: number = 10;
32
36
  module: ?any;
33
- responseId = 0;
37
+ responseId: number = 0;
34
38
  responseQueue: Map<number, ChildCall> = new Map();
35
39
  loggerDisposable: IDisposable;
40
+ tracerDisposable: IDisposable;
36
41
  child: ChildImpl;
37
- profiler: ?Profiler;
38
- workerApi: WorkerApi;
42
+ profiler: ?SamplingProfiler;
39
43
  handles: Map<number, Handle> = new Map();
40
- sharedReferences: Map<number, mixed> = new Map();
41
- sharedReferencesByValue: Map<mixed, number> = new Map();
44
+ sharedReferences: Map<SharedReference, mixed> = new Map();
45
+ sharedReferencesByValue: Map<mixed, SharedReference> = new Map();
42
46
 
43
47
  constructor(ChildBackend: Class<ChildImpl>) {
44
48
  this.child = new ChildBackend(
45
- this.messageListener.bind(this),
46
- this.handleEnd.bind(this),
49
+ m => {
50
+ this.messageListener(m);
51
+ },
52
+ () => this.handleEnd(),
47
53
  );
48
54
 
49
55
  // Monitior all logging events inside this child process and forward to
@@ -51,21 +57,37 @@ export class Child {
51
57
  this.loggerDisposable = Logger.onLog(event => {
52
58
  bus.emit('logEvent', event);
53
59
  });
60
+ // .. and do the same for trace events
61
+ this.tracerDisposable = tracer.onTrace(event => {
62
+ bus.emit('traceEvent', event);
63
+ });
54
64
  }
55
65
 
56
- workerApi = {
66
+ workerApi: {|
67
+ callMaster: (
68
+ request: CallRequest,
69
+ awaitResponse?: ?boolean,
70
+ ) => Promise<mixed>,
71
+ createReverseHandle: (fn: (...args: Array<any>) => mixed) => Handle,
72
+ getSharedReference: (ref: SharedReference) => mixed,
73
+ resolveSharedReference: (value: mixed) => void | SharedReference,
74
+ runHandle: (handle: Handle, args: Array<any>) => Promise<mixed>,
75
+ |} = {
57
76
  callMaster: (
58
77
  request: CallRequest,
59
78
  awaitResponse: ?boolean = true,
60
79
  ): Promise<mixed> => this.addCall(request, awaitResponse),
61
80
  createReverseHandle: (fn: (...args: Array<any>) => mixed): Handle =>
62
81
  this.createReverseHandle(fn),
63
- getSharedReference: (ref: number) => this.sharedReferences.get(ref),
82
+ runHandle: (handle: Handle, args: Array<any>): Promise<mixed> =>
83
+ this.workerApi.callMaster({handle: handle.id, args}, true),
84
+ getSharedReference: (ref: SharedReference) =>
85
+ this.sharedReferences.get(ref),
64
86
  resolveSharedReference: (value: mixed) =>
65
87
  this.sharedReferencesByValue.get(value),
66
88
  };
67
89
 
68
- messageListener(message: WorkerMessage): void | Promise<void> {
90
+ messageListener(message: WorkerMessage): Async<void> {
69
91
  if (message.type === 'response') {
70
92
  return this.handleResponse(message);
71
93
  } else if (message.type === 'request') {
@@ -77,10 +99,14 @@ export class Child {
77
99
  this.child.send(data);
78
100
  }
79
101
 
80
- childInit(module: string, childId: number): void {
102
+ async childInit(module: string, childId: number): Promise<void> {
81
103
  // $FlowFixMe this must be dynamic
82
104
  this.module = require(module);
83
105
  this.childId = childId;
106
+
107
+ if (this.module.childInit != null) {
108
+ await this.module.childInit();
109
+ }
84
110
  }
85
111
 
86
112
  async handleRequest(data: WorkerRequest): Promise<void> {
@@ -106,7 +132,7 @@ export class Child {
106
132
  let result;
107
133
  if (handleId != null) {
108
134
  try {
109
- let fn = nullthrows(this.handles.get(handleId)).fn;
135
+ let fn = nullthrows(this.handles.get(handleId)?.fn);
110
136
  result = responseFromContent(fn(...args));
111
137
  } catch (e) {
112
138
  result = errorResponseFromError(e);
@@ -114,18 +140,22 @@ export class Child {
114
140
  } else if (method === 'childInit') {
115
141
  try {
116
142
  let [moduleName, childOptions] = args;
117
- if (childOptions.patchConsole) {
143
+ if (childOptions.shouldPatchConsole) {
118
144
  patchConsole();
119
145
  } else {
120
146
  unpatchConsole();
121
147
  }
122
148
 
123
- result = responseFromContent(this.childInit(moduleName, child));
149
+ if (childOptions.shouldTrace) {
150
+ tracer.enable();
151
+ }
152
+
153
+ result = responseFromContent(await this.childInit(moduleName, child));
124
154
  } catch (e) {
125
155
  result = errorResponseFromError(e);
126
156
  }
127
157
  } else if (method === 'startProfile') {
128
- this.profiler = new Profiler();
158
+ this.profiler = new SamplingProfiler();
129
159
  try {
130
160
  result = responseFromContent(await this.profiler.startProfiling());
131
161
  } catch (e) {
@@ -138,13 +168,37 @@ export class Child {
138
168
  } catch (e) {
139
169
  result = errorResponseFromError(e);
140
170
  }
171
+ } else if (method === 'takeHeapSnapshot') {
172
+ try {
173
+ let v8 = require('v8');
174
+ result = responseFromContent(
175
+ v8.writeHeapSnapshot(
176
+ 'heap-' +
177
+ args[0] +
178
+ '-' +
179
+ (this.childId ? 'worker' + this.childId : 'main') +
180
+ '.heapsnapshot',
181
+ ),
182
+ );
183
+ } catch (e) {
184
+ result = errorResponseFromError(e);
185
+ }
141
186
  } else if (method === 'createSharedReference') {
142
- let [ref, value] = args;
187
+ let [ref, _value] = args;
188
+ let value =
189
+ _value instanceof ArrayBuffer
190
+ ? // In the case the value is pre-serialized as a buffer,
191
+ // deserialize it.
192
+ deserialize(Buffer.from(_value))
193
+ : _value;
143
194
  this.sharedReferences.set(ref, value);
144
195
  this.sharedReferencesByValue.set(value, ref);
145
196
  result = responseFromContent(null);
146
197
  } else if (method === 'deleteSharedReference') {
147
- this.sharedReferences.delete(args[0]);
198
+ let ref = args[0];
199
+ let value = this.sharedReferences.get(ref);
200
+ this.sharedReferencesByValue.delete(value);
201
+ this.sharedReferences.delete(ref);
148
202
  result = responseFromContent(null);
149
203
  } else {
150
204
  try {
@@ -157,7 +211,11 @@ export class Child {
157
211
  }
158
212
  }
159
213
 
160
- this.send(result);
214
+ try {
215
+ this.send(result);
216
+ } catch (e) {
217
+ result = this.send(errorResponseFromError(e));
218
+ }
161
219
  }
162
220
 
163
221
  handleResponse(data: WorkerResponse): void {
@@ -189,6 +247,7 @@ export class Child {
189
247
  ...request,
190
248
  type: 'request',
191
249
  child: this.childId,
250
+ // $FlowFixMe Added in Flow 0.121.0 upgrade in #4381
192
251
  awaitResponse,
193
252
  resolve: () => {},
194
253
  reject: () => {},
@@ -239,12 +298,12 @@ export class Child {
239
298
 
240
299
  handleEnd(): void {
241
300
  this.loggerDisposable.dispose();
301
+ this.tracerDisposable.dispose();
242
302
  }
243
303
 
244
- createReverseHandle(fn: (...args: Array<any>) => mixed) {
304
+ createReverseHandle(fn: (...args: Array<any>) => mixed): Handle {
245
305
  let handle = new Handle({
246
306
  fn,
247
- workerApi: this.workerApi,
248
307
  childId: this.childId,
249
308
  });
250
309
  this.handles.set(handle.id, handle);
package/src/cpuCount.js CHANGED
@@ -26,6 +26,11 @@ export function detectRealCores(): number {
26
26
  );
27
27
  } else if (platform === 'darwin') {
28
28
  amount = parseInt(exec('sysctl -n hw.physicalcpu_max'), 10);
29
+ } else if (platform === 'win32') {
30
+ const str = exec('wmic cpu get NumberOfCores').match(/\d+/g);
31
+ if (str !== null) {
32
+ amount = parseInt(str.filter(n => n !== '')[0], 10);
33
+ }
29
34
  }
30
35
 
31
36
  if (!amount || amount <= 0) {
@@ -36,9 +41,8 @@ export function detectRealCores(): number {
36
41
  }
37
42
 
38
43
  let cores;
39
- export default function getCores(bypassCache?: boolean = false) {
44
+ export default function getCores(bypassCache?: boolean = false): number {
40
45
  // Do not re-run commands if we already have the count...
41
- // $FlowFixMe
42
46
  if (cores && !bypassCache) {
43
47
  return cores;
44
48
  }
@@ -49,8 +53,9 @@ export default function getCores(bypassCache?: boolean = false) {
49
53
  // Guess the amount of real cores
50
54
  cores = os
51
55
  .cpus()
52
- .filter((cpu, index) => !cpu.model.includes('Intel') || index % 2 === 1)
53
- .length;
56
+ .filter(
57
+ (cpu, index) => !cpu.model.includes('Intel') || index % 2 === 1,
58
+ ).length;
54
59
  }
55
60
 
56
61
  // Another fallback
package/src/index.js CHANGED
@@ -1,9 +1,10 @@
1
1
  // @flow
2
- import type {LogEvent} from '@parcel/types';
2
+ import type {TraceEvent, LogEvent} from '@parcel/types';
3
3
  import invariant from 'assert';
4
4
  import WorkerFarm from './WorkerFarm';
5
5
  import Logger from '@parcel/logger';
6
6
  import bus from './bus';
7
+ import {tracer} from '@parcel/profiler';
7
8
 
8
9
  if (!WorkerFarm.isWorker()) {
9
10
  // Forward all logger events originating from workers into the main process
@@ -29,9 +30,14 @@ if (!WorkerFarm.isWorker()) {
29
30
  throw new Error('Unknown log level');
30
31
  }
31
32
  });
33
+
34
+ // Forward all trace events originating from workers into the main process
35
+ bus.on('traceEvent', (e: TraceEvent) => {
36
+ tracer.trace(e);
37
+ });
32
38
  }
33
39
 
34
40
  export default WorkerFarm;
35
41
  export {bus};
36
42
  export {Handle} from './WorkerFarm';
37
- export type {WorkerApi, FarmOptions} from './WorkerFarm';
43
+ export type {WorkerApi, FarmOptions, SharedReference} from './WorkerFarm';
@@ -25,7 +25,7 @@ export default class ProcessChild implements ChildImpl {
25
25
  process.on('message', data => this.handleMessage(data));
26
26
  }
27
27
 
28
- handleMessage(data: string) {
28
+ handleMessage(data: string): void {
29
29
  if (data === 'die') {
30
30
  return this.stop();
31
31
  }
@@ -37,6 +37,7 @@ export default class ProcessChild implements ChildImpl {
37
37
  let processSend = nullthrows(process.send).bind(process);
38
38
  processSend(serialize(data).toString('base64'), err => {
39
39
  if (err && err instanceof Error) {
40
+ // $FlowFixMe[prop-missing]
40
41
  if (err.code === 'ERR_IPC_CHANNEL_CLOSED') {
41
42
  // IPC connection closed
42
43
  // no need to keep the worker running if it can't send or receive data
@@ -34,7 +34,7 @@ export default class ProcessWorker implements WorkerImpl {
34
34
  this.onExit = onExit;
35
35
  }
36
36
 
37
- start() {
37
+ start(): Promise<void> {
38
38
  this.child = childProcess.fork(WORKER_PATH, process.argv, {
39
39
  execArgv: this.execArgv,
40
40
  env: process.env,
@@ -32,7 +32,7 @@ export default class ThreadsWorker implements WorkerImpl {
32
32
  this.onExit = onExit;
33
33
  }
34
34
 
35
- start() {
35
+ start(): Promise<void> {
36
36
  this.worker = new Worker(WORKER_PATH, {
37
37
  execArgv: this.execArgv,
38
38
  env: process.env,
@@ -47,7 +47,7 @@ export default class ThreadsWorker implements WorkerImpl {
47
47
  });
48
48
  }
49
49
 
50
- stop() {
50
+ stop(): Promise<void> {
51
51
  // In node 12, this returns a promise, but previously it accepted a callback
52
52
  // TODO: Pass a callback in earlier versions of Node
53
53
  return Promise.resolve(this.worker.terminate());
@@ -3,7 +3,7 @@ import os from 'os';
3
3
 
4
4
  import getCores, {detectRealCores} from '../src/cpuCount';
5
5
 
6
- describe('cpuCount', function() {
6
+ describe('cpuCount', function () {
7
7
  it('Should be able to detect real cpu count', () => {
8
8
  // Windows not supported as getting the cpu count takes a couple seconds...
9
9
  if (os.platform() === 'win32') return;
@@ -1,4 +1,4 @@
1
- const WorkerFarm = require('../../../').default;
1
+ const WorkerFarm = require('../../../src/WorkerFarm').default;
2
2
 
3
3
  function run() {
4
4
  if (WorkerFarm.isWorker()) {
@@ -1,4 +1,4 @@
1
- const WorkerFarm = require('../../../').default;
1
+ const WorkerFarm = require('../../../src/WorkerFarm').default;
2
2
  const Logger = require('@parcel/logger').default;
3
3
 
4
4
  function run() {
@@ -1,5 +1,5 @@
1
- function run(_, handle) {
2
- return handle();
1
+ function run(workerApi, handle) {
2
+ return workerApi.runHandle(handle, []);
3
3
  }
4
4
 
5
5
  exports.run = run;
@@ -1,8 +1,8 @@
1
1
  import Logger from '@parcel/logger';
2
2
  import assert from 'assert';
3
- import WorkerFarm from '../';
3
+ import WorkerFarm from '../src';
4
4
 
5
- describe('WorkerFarm', function() {
5
+ describe('WorkerFarm', function () {
6
6
  this.timeout(30000);
7
7
 
8
8
  it('Should start up workers', async () => {
@@ -132,7 +132,7 @@ describe('WorkerFarm', function() {
132
132
  await workerfarm.end();
133
133
  });
134
134
 
135
- it('Forwards stdio from the child process and levels event source if patchConsole is true', async () => {
135
+ it('Forwards stdio from the child process and levels event source if shouldPatchConsole is true', async () => {
136
136
  let events = [];
137
137
  let logDisposable = Logger.onLog(event => events.push(event));
138
138
 
@@ -140,7 +140,7 @@ describe('WorkerFarm', function() {
140
140
  warmWorkers: true,
141
141
  useLocalWorker: false,
142
142
  workerPath: require.resolve('./integration/workerfarm/console.js'),
143
- patchConsole: true,
143
+ shouldPatchConsole: true,
144
144
  });
145
145
 
146
146
  await workerfarm.run();
@@ -291,7 +291,7 @@ describe('WorkerFarm', function() {
291
291
  assert.equal(result, 'Shared reference does not exist');
292
292
  });
293
293
 
294
- it('should resolve shared references in workers', async () => {
294
+ it('Should resolve shared references in workers', async () => {
295
295
  let workerfarm = new WorkerFarm({
296
296
  warmWorkers: true,
297
297
  useLocalWorker: false,
package/lib/Profiler.js DELETED
@@ -1,70 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
-
8
- var _assert = _interopRequireDefault(require("assert"));
9
-
10
- var _diagnostic = _interopRequireDefault(require("@parcel/diagnostic"));
11
-
12
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
-
14
- 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; }
15
-
16
- class Profiler {
17
- constructor() {
18
- _defineProperty(this, "session", void 0);
19
- }
20
-
21
- startProfiling() {
22
- let inspector;
23
-
24
- try {
25
- inspector = require('inspector');
26
- } catch (err) {
27
- throw new _diagnostic.default({
28
- diagnostic: {
29
- message: `The inspector module isn't available`,
30
- origin: '@parcel/workers',
31
- hints: ['Disable build profiling']
32
- }
33
- });
34
- }
35
-
36
- this.session = new inspector.Session();
37
- this.session.connect();
38
- return Promise.all([this.sendCommand('Profiler.setSamplingInterval', {
39
- interval: 100
40
- }), this.sendCommand('Profiler.enable'), this.sendCommand('Profiler.start')]);
41
- }
42
-
43
- sendCommand(method, params) {
44
- (0, _assert.default)(this.session != null);
45
- return new Promise((resolve, reject) => {
46
- this.session.post(method, params, (err, params) => {
47
- if (err == null) {
48
- resolve(params);
49
- } else {
50
- reject(err);
51
- }
52
- });
53
- });
54
- }
55
-
56
- destroy() {
57
- if (this.session != null) {
58
- this.session.disconnect();
59
- }
60
- }
61
-
62
- async stopProfiling() {
63
- let res = await this.sendCommand('Profiler.stop');
64
- this.destroy();
65
- return res.profile;
66
- }
67
-
68
- }
69
-
70
- exports.default = Profiler;
package/lib/Trace.js DELETED
@@ -1,126 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
-
8
- var _chromeTraceEvent = require("chrome-trace-event");
9
-
10
- 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; }
11
-
12
- class Trace {
13
- constructor() {
14
- _defineProperty(this, "tracer", void 0);
15
-
16
- _defineProperty(this, "tid", void 0);
17
-
18
- _defineProperty(this, "eventId", void 0);
19
-
20
- this.tracer = new _chromeTraceEvent.Tracer();
21
- this.tid = 0;
22
- this.eventId = 0;
23
- this.init();
24
- }
25
-
26
- getEventId() {
27
- return this.eventId++;
28
- }
29
-
30
- init() {
31
- this.tracer.instantEvent({
32
- name: 'TracingStartedInPage',
33
- id: this.getEventId(),
34
- cat: ['disabled-by-default-devtools.timeline'],
35
- args: {
36
- data: {
37
- sessionId: '-1',
38
- page: '0xfff',
39
- frames: [{
40
- frame: '0xfff',
41
- url: 'parcel',
42
- name: ''
43
- }]
44
- }
45
- }
46
- });
47
- this.tracer.instantEvent({
48
- name: 'TracingStartedInBrowser',
49
- id: this.getEventId(),
50
- cat: ['disabled-by-default-devtools.timeline'],
51
- args: {
52
- data: {
53
- sessionId: '-1'
54
- }
55
- }
56
- });
57
- }
58
-
59
- addCPUProfile(name, profile) {
60
- const trace = this.tracer;
61
- const tid = this.tid;
62
- this.tid++;
63
- const cpuStartTime = profile.startTime;
64
- const cpuEndTime = profile.endTime;
65
- trace.instantEvent({
66
- tid,
67
- id: this.getEventId(),
68
- cat: ['toplevel'],
69
- name: 'TaskQueueManager::ProcessTaskFromWorkQueue',
70
- args: {
71
- src_file: '../../ipc/ipc_moji_bootstrap.cc',
72
- src_func: 'Accept'
73
- },
74
- ts: cpuStartTime
75
- });
76
- trace.completeEvent({
77
- tid,
78
- name: 'EvaluateScript',
79
- id: this.getEventId(),
80
- cat: ['devtools.timeline'],
81
- ts: cpuStartTime,
82
- dur: cpuEndTime - cpuStartTime,
83
- args: {
84
- data: {
85
- url: 'parcel',
86
- lineNumber: 1,
87
- columnNumber: 1,
88
- frame: '0xFFF'
89
- }
90
- }
91
- });
92
- trace.instantEvent({
93
- tid,
94
- ts: 0,
95
- ph: 'M',
96
- cat: ['__metadata'],
97
- name: 'thread_name',
98
- args: {
99
- name
100
- }
101
- });
102
- trace.instantEvent({
103
- tid,
104
- name: 'CpuProfile',
105
- id: this.getEventId(),
106
- cat: ['disabled-by-default-devtools.timeline'],
107
- ts: cpuEndTime,
108
- args: {
109
- data: {
110
- cpuProfile: profile
111
- }
112
- }
113
- });
114
- }
115
-
116
- pipe(writable) {
117
- return this.tracer.pipe(writable);
118
- }
119
-
120
- flush() {
121
- this.tracer.push(null);
122
- }
123
-
124
- }
125
-
126
- exports.default = Trace;
package/src/Profiler.js DELETED
@@ -1,93 +0,0 @@
1
- // @flow
2
- import type {Session} from 'inspector';
3
- import invariant from 'assert';
4
- import ThrowableDiagnostic from '@parcel/diagnostic';
5
-
6
- // https://chromedevtools.github.io/devtools-protocol/tot/Profiler#type-Profile
7
- export type Profile = {|
8
- nodes: Array<ProfileNode>,
9
- startTime: number,
10
- endTime: number,
11
- samples?: Array<number>,
12
- timeDeltas?: Array<number>,
13
- |};
14
-
15
- // https://chromedevtools.github.io/devtools-protocol/tot/Profiler#type-ProfileNode
16
- type ProfileNode = {|
17
- id: number,
18
- callFrame: CallFrame,
19
- hitCount?: number,
20
- children?: Array<number>,
21
- deoptReason?: string,
22
- positionTicks?: PositionTickInfo,
23
- |};
24
-
25
- // https://chromedevtools.github.io/devtools-protocol/tot/Runtime#type-CallFrame
26
- type CallFrame = {|
27
- functionName: string,
28
- scriptId: string,
29
- url: string,
30
- lineNumber: string,
31
- columnNumber: string,
32
- |};
33
-
34
- // https://chromedevtools.github.io/devtools-protocol/tot/Profiler#type-PositionTickInfo
35
- type PositionTickInfo = {|
36
- line: number,
37
- ticks: number,
38
- |};
39
-
40
- export default class Profiler {
41
- session: Session;
42
-
43
- startProfiling() {
44
- let inspector;
45
- try {
46
- inspector = require('inspector');
47
- } catch (err) {
48
- throw new ThrowableDiagnostic({
49
- diagnostic: {
50
- message: `The inspector module isn't available`,
51
- origin: '@parcel/workers',
52
- hints: ['Disable build profiling'],
53
- },
54
- });
55
- }
56
-
57
- this.session = new inspector.Session();
58
- this.session.connect();
59
-
60
- return Promise.all([
61
- this.sendCommand('Profiler.setSamplingInterval', {
62
- interval: 100,
63
- }),
64
- this.sendCommand('Profiler.enable'),
65
- this.sendCommand('Profiler.start'),
66
- ]);
67
- }
68
-
69
- sendCommand(method: string, params: mixed): Promise<{profile: Profile, ...}> {
70
- invariant(this.session != null);
71
- return new Promise((resolve, reject) => {
72
- this.session.post(method, params, (err, params) => {
73
- if (err == null) {
74
- resolve(params);
75
- } else {
76
- reject(err);
77
- }
78
- });
79
- });
80
- }
81
-
82
- destroy() {
83
- if (this.session != null) {
84
- this.session.disconnect();
85
- }
86
- }
87
-
88
- async stopProfiling(): Promise<Profile> {
89
- let res = await this.sendCommand('Profiler.stop');
90
- this.destroy();
91
- return res.profile;
92
- }
93
- }