@parcel/workers 2.0.0-nightly.140 → 2.0.0-nightly.1400

Sign up to get free protection for your applications and to get access to all the features.
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
- }