@parcel/profiler 2.12.1-dev.3185 → 2.12.1-dev.3195

Sign up to get free protection for your applications and to get access to all the features.
package/lib/Tracer.d.ts CHANGED
@@ -1,9 +1,10 @@
1
- import type { TraceEvent, IDisposable, MeasurementOptions, PluginTracer as IPluginTracer } from "@parcel/types";
1
+ import type { TraceEvent, IDisposable, PluginTracer as IPluginTracer } from "@parcel/types";
2
2
  import type { TraceMeasurement as ITraceMeasurement } from "./types";
3
3
  export default class Tracer {
4
4
 
5
5
  onTrace(cb: (event: TraceEvent) => unknown): IDisposable;
6
- measure<T>({ args, categories, name }: MeasurementOptions, fn: () => T): T;
6
+ wrap(name: string, fn: () => unknown): Promise<void>;
7
+ createMeasurement(name: string, category?: string, argumentName?: string, otherArgs?: Record<string, unknown>): ITraceMeasurement | null;
7
8
  get enabled(): boolean;
8
9
  enable(): void;
9
10
  disable(): void;
@@ -23,6 +24,5 @@ export declare class PluginTracer implements IPluginTracer {
23
24
  constructor(opts: TracerOpts);
24
25
  get enabled(): boolean;
25
26
  createMeasurement(name: string, category?: string, argumentName?: string, otherArgs?: Record<string, unknown>): ITraceMeasurement | null;
26
- measure<T>(options: MeasurementOptions, fn: () => T): T;
27
27
  }
28
28
  export {};
package/lib/Tracer.js CHANGED
@@ -62,37 +62,38 @@ class Tracer {
62
62
  onTrace(cb) {
63
63
  return this.#traceEmitter.addListener(cb);
64
64
  }
65
- measure({
66
- args = {},
67
- categories,
68
- name
69
- }, fn) {
70
- if (!this.enabled) {
71
- return fn();
72
- }
73
- let measurement = new TraceMeasurement(this, name, pid, tid, {
74
- categories,
75
- args
76
- });
77
- let result;
78
- let hasFinally = false;
65
+ async wrap(name, fn) {
66
+ let measurement = this.createMeasurement(name);
79
67
  try {
80
- result = fn();
81
- // @ts-expect-error TypeScript types cannot infer that finally can exist
82
- if (result != null && typeof result === 'object' && typeof result.finally === 'function') {
83
- hasFinally = true;
84
- // @ts-expect-error
85
- // $FlowFixMe[incompatible-use] This will run for a promise type, but it cannot be easily typed in Flow
86
- result = result.finally(() => {
87
- measurement === null || measurement === void 0 || measurement.end();
88
- });
89
- }
68
+ await fn();
90
69
  } finally {
91
- if (!hasFinally) {
92
- measurement === null || measurement === void 0 || measurement.end();
70
+ measurement && measurement.end();
71
+ }
72
+ }
73
+ createMeasurement(name, category = 'Core', argumentName, otherArgs) {
74
+ if (!this.enabled) return null;
75
+
76
+ // We create `args` in a fairly verbose way to avoid object
77
+ // allocation where not required.
78
+ let args;
79
+ if (typeof argumentName === 'string') {
80
+ args = {
81
+ name: argumentName
82
+ };
83
+ }
84
+ if (typeof otherArgs === 'object') {
85
+ if (typeof args == 'undefined') {
86
+ args = {};
87
+ }
88
+ for (const [k, v] of Object.entries(otherArgs)) {
89
+ args[k] = v;
93
90
  }
94
91
  }
95
- return result;
92
+ const data = {
93
+ categories: [category],
94
+ args
95
+ };
96
+ return new TraceMeasurement(this, name, pid, tid, data);
96
97
  }
97
98
  get enabled() {
98
99
  return this.#enabled;
@@ -124,44 +125,7 @@ class PluginTracer {
124
125
  return tracer.enabled;
125
126
  }
126
127
  createMeasurement(name, category, argumentName, otherArgs) {
127
- if (!this.enabled) return null;
128
-
129
- // We create `args` in a fairly verbose way to avoid object
130
- // allocation where not required.
131
- let args;
132
- if (typeof argumentName === 'string') {
133
- args = {
134
- name: argumentName
135
- };
136
- }
137
- if (typeof otherArgs === 'object') {
138
- if (typeof args == 'undefined') {
139
- args = {};
140
- }
141
- for (const [k, v] of Object.entries(otherArgs)) {
142
- args[k] = v;
143
- }
144
- }
145
- const data = {
146
- categories: [`${this.category}:${this.origin}${typeof category === 'string' ? `:${category}` : ''}`],
147
- args
148
- };
149
- return new TraceMeasurement(tracer, name, pid, tid, data);
150
- }
151
- measure(options, fn) {
152
- var _options$args;
153
- if (!this.enabled) {
154
- return fn();
155
- }
156
- return tracer.measure({
157
- ...options,
158
- // $FlowFixMe[cannot-spread-inexact]
159
- args: {
160
- origin: this.origin,
161
- ...((_options$args = options.args) !== null && _options$args !== void 0 ? _options$args : {})
162
- },
163
- categories: [this.category, ...options.categories]
164
- }, fn);
128
+ return tracer.createMeasurement(name, `${this.category}:${this.origin}${typeof category === 'string' ? `:${category}` : ''}`, argumentName, otherArgs);
165
129
  }
166
130
  }
167
131
  exports.PluginTracer = PluginTracer;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parcel/profiler",
3
- "version": "2.12.1-dev.3185+298c035e0",
3
+ "version": "2.12.1-dev.3195+7afdafedd",
4
4
  "description": "Blazing fast, zero configuration web application bundler",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -17,17 +17,17 @@
17
17
  "main": "lib/index.js",
18
18
  "source": "src/index.js",
19
19
  "engines": {
20
- "node": ">= 12.0.0"
20
+ "node": ">= 16.0.0"
21
21
  },
22
22
  "scripts": {
23
23
  "build-ts": "flow-to-ts src/*.js --write && rm -f ./src/*.d.ts && tsc --emitDeclarationOnly --declaration --esModuleInterop --target es2015 --moduleResolution node16 --module node16 src/*.ts && mkdir -p lib && mv src/*.d.ts lib/. && rm src/*.ts && node build-ts.js",
24
24
  "check-ts": "tsc --noEmit lib/index.d.ts"
25
25
  },
26
26
  "dependencies": {
27
- "@parcel/diagnostic": "2.0.0-dev.1562+298c035e0",
28
- "@parcel/events": "2.0.0-dev.1562+298c035e0",
29
- "@parcel/types-internal": "2.12.1-dev.3185+298c035e0",
27
+ "@parcel/diagnostic": "2.0.0-dev.1572+7afdafedd",
28
+ "@parcel/events": "2.0.0-dev.1572+7afdafedd",
29
+ "@parcel/types-internal": "2.12.1-dev.3195+7afdafedd",
30
30
  "chrome-trace-event": "^1.0.2"
31
31
  },
32
- "gitHead": "298c035e0ffb82d7c5579ce233cc35dce2fe1061"
32
+ "gitHead": "7afdafedd7f01d82b9868ec004b3966a88006300"
33
33
  }
package/src/Tracer.js CHANGED
@@ -3,7 +3,6 @@
3
3
  import type {
4
4
  TraceEvent,
5
5
  IDisposable,
6
- MeasurementOptions,
7
6
  PluginTracer as IPluginTracer,
8
7
  } from '@parcel/types';
9
8
  import type {
@@ -65,44 +64,44 @@ export default class Tracer {
65
64
  return this.#traceEmitter.addListener(cb);
66
65
  }
67
66
 
68
- measure<T>(
69
- {args = {}, categories, name}: MeasurementOptions,
70
- fn: () => T,
71
- ): T {
72
- if (!this.enabled) {
73
- return fn();
67
+ async wrap(name: string, fn: () => mixed): Promise<void> {
68
+ let measurement = this.createMeasurement(name);
69
+ try {
70
+ await fn();
71
+ } finally {
72
+ measurement && measurement.end();
74
73
  }
74
+ }
75
75
 
76
- let measurement = new TraceMeasurement(this, name, pid, tid, {
77
- categories,
78
- args,
79
- });
80
-
81
- let result: T;
82
- let hasFinally = false;
76
+ createMeasurement(
77
+ name: string,
78
+ category: string = 'Core',
79
+ argumentName?: string,
80
+ otherArgs?: {[key: string]: mixed},
81
+ ): ITraceMeasurement | null {
82
+ if (!this.enabled) return null;
83
83
 
84
- try {
85
- result = fn();
86
- // @ts-expect-error TypeScript types cannot infer that finally can exist
87
- if (
88
- result != null &&
89
- typeof result === 'object' &&
90
- typeof result.finally === 'function'
91
- ) {
92
- hasFinally = true;
93
- // @ts-expect-error
94
- // $FlowFixMe[incompatible-use] This will run for a promise type, but it cannot be easily typed in Flow
95
- result = result.finally(() => {
96
- measurement?.end();
97
- });
84
+ // We create `args` in a fairly verbose way to avoid object
85
+ // allocation where not required.
86
+ let args: {[key: string]: mixed};
87
+ if (typeof argumentName === 'string') {
88
+ args = {name: argumentName};
89
+ }
90
+ if (typeof otherArgs === 'object') {
91
+ if (typeof args == 'undefined') {
92
+ args = {};
98
93
  }
99
- } finally {
100
- if (!hasFinally) {
101
- measurement?.end();
94
+ for (const [k, v] of Object.entries(otherArgs)) {
95
+ args[k] = v;
102
96
  }
103
97
  }
104
98
 
105
- return result;
99
+ const data: TraceMeasurementData = {
100
+ categories: [category],
101
+ args,
102
+ };
103
+
104
+ return new TraceMeasurement(this, name, pid, tid, data);
106
105
  }
107
106
 
108
107
  get enabled(): boolean {
@@ -129,7 +128,6 @@ type TracerOpts = {|
129
128
  origin: string,
130
129
  category: string,
131
130
  |};
132
-
133
131
  export class PluginTracer implements IPluginTracer {
134
132
  /** @private */
135
133
  origin: string;
@@ -153,51 +151,13 @@ export class PluginTracer implements IPluginTracer {
153
151
  argumentName?: string,
154
152
  otherArgs?: {[key: string]: mixed},
155
153
  ): ITraceMeasurement | null {
156
- if (!this.enabled) return null;
157
-
158
- // We create `args` in a fairly verbose way to avoid object
159
- // allocation where not required.
160
- let args: {[key: string]: mixed};
161
- if (typeof argumentName === 'string') {
162
- args = {name: argumentName};
163
- }
164
- if (typeof otherArgs === 'object') {
165
- if (typeof args == 'undefined') {
166
- args = {};
167
- }
168
- for (const [k, v] of Object.entries(otherArgs)) {
169
- args[k] = v;
170
- }
171
- }
172
-
173
- const data: TraceMeasurementData = {
174
- categories: [
175
- `${this.category}:${this.origin}${
176
- typeof category === 'string' ? `:${category}` : ''
177
- }`,
178
- ],
179
- args,
180
- };
181
-
182
- return new TraceMeasurement(tracer, name, pid, tid, data);
183
- }
184
-
185
- measure<T>(options: MeasurementOptions, fn: () => T): T {
186
- if (!this.enabled) {
187
- return fn();
188
- }
189
-
190
- return tracer.measure(
191
- {
192
- ...options,
193
- // $FlowFixMe[cannot-spread-inexact]
194
- args: {
195
- origin: this.origin,
196
- ...(options.args ?? {}),
197
- },
198
- categories: [this.category, ...options.categories],
199
- },
200
- fn,
154
+ return tracer.createMeasurement(
155
+ name,
156
+ `${this.category}:${this.origin}${
157
+ typeof category === 'string' ? `:${category}` : ''
158
+ }`,
159
+ argumentName,
160
+ otherArgs,
201
161
  );
202
162
  }
203
163
  }
@@ -5,123 +5,74 @@ import assert from 'assert';
5
5
  describe('Tracer', () => {
6
6
  let onTrace;
7
7
  let traceDisposable;
8
- let opts = {name: 'test', categories: ['tracer']};
9
-
10
8
  beforeEach(() => {
11
9
  onTrace = sinon.spy();
12
10
  traceDisposable = tracer.onTrace(onTrace);
13
11
  tracer.enable();
14
12
  });
15
-
16
13
  afterEach(() => {
17
14
  traceDisposable.dispose();
18
15
  });
19
16
 
20
- describe('measure()', () => {
21
- let cases = [
22
- ['synchronous', () => () => {}],
23
- ['asynchronous', () => async () => {}],
24
- ];
25
-
26
- for (let [type, createFn] of cases) {
27
- describe(`given a ${type} function`, () => {
28
- it('does not trace when disabled', async () => {
29
- tracer.disable();
30
-
31
- let result = tracer.measure(opts, sinon.spy());
32
- if (type === 'asynchronous') {
33
- sinon.assert.notCalled(onTrace);
34
- await result;
35
- }
36
-
37
- assert(onTrace.notCalled);
38
- });
39
-
40
- it('emits a basic trace event', async () => {
41
- let result = tracer.measure(opts, createFn());
42
- if (type === 'asynchronous') {
43
- sinon.assert.notCalled(onTrace);
44
- await result;
45
- }
46
-
47
- sinon.assert.calledOnce(onTrace);
48
- sinon.assert.calledWith(
49
- onTrace,
50
- sinon.match({
51
- type: 'trace',
52
- name: 'test',
53
- args: {},
54
- categories: ['tracer'],
55
- duration: sinon.match.number,
56
- }),
57
- );
58
- });
59
-
60
- it('emits a complex trace event', async () => {
61
- let result = tracer.measure(
62
- {...opts, args: {hello: 'world'}},
63
- createFn(),
64
- );
65
- if (type === 'asynchronous') {
66
- sinon.assert.notCalled(onTrace);
67
- await result;
68
- }
69
-
70
- sinon.assert.calledOnce(onTrace);
71
- sinon.assert.calledWith(
72
- onTrace,
73
- sinon.match({
74
- type: 'trace',
75
- name: 'test',
76
- args: {hello: 'world'},
77
- categories: ['tracer'],
78
- duration: sinon.match.number,
79
- }),
80
- );
81
- });
82
- });
83
- }
17
+ it('returns no measurement when disabled', () => {
18
+ tracer.disable();
19
+ const measurement = tracer.createMeasurement('test');
20
+ assert(measurement == null);
21
+ assert(onTrace.notCalled);
84
22
  });
85
-
86
- describe('PluginTracer', () => {
87
- const pluginTracer = new PluginTracer({
88
- origin: 'origin',
89
- category: 'cat',
90
- });
91
-
92
- describe(`measure()`, () => {
93
- it('emits events with origin and category', () => {
94
- pluginTracer.measure(opts, sinon.spy());
95
-
96
- sinon.assert.calledOnce(onTrace);
97
- sinon.assert.calledWith(
98
- onTrace,
99
- sinon.match({
100
- type: 'trace',
101
- name: 'test',
102
- args: {origin: 'origin'},
103
- categories: ['cat', 'tracer'],
104
- duration: sinon.match.number,
105
- }),
106
- );
107
- });
23
+ it('emits a basic trace event', () => {
24
+ const measurement = tracer.createMeasurement('test');
25
+ measurement.end();
26
+ sinon.assert.calledWith(
27
+ onTrace,
28
+ sinon.match({
29
+ type: 'trace',
30
+ name: 'test',
31
+ args: undefined,
32
+ duration: sinon.match.number,
33
+ }),
34
+ );
35
+ });
36
+ it('emits a complex trace event', () => {
37
+ const measurement = tracer.createMeasurement('test', 'myPlugin', 'aaargh', {
38
+ extra: 'data',
108
39
  });
40
+ measurement.end();
41
+ sinon.assert.calledWith(
42
+ onTrace,
43
+ sinon.match({
44
+ type: 'trace',
45
+ name: 'test',
46
+ categories: ['myPlugin'],
47
+ args: {extra: 'data', name: 'aaargh'},
48
+ duration: sinon.match.number,
49
+ }),
50
+ );
51
+ });
52
+ it('calling end twice on measurment should be a no-op', () => {
53
+ const measurement = tracer.createMeasurement('test');
54
+ measurement.end();
55
+ measurement.end();
56
+ sinon.assert.calledOnce(onTrace);
57
+ });
109
58
 
110
- describe('createMeasurement()', () => {
111
- it('emits events with origin and category', () => {
112
- pluginTracer.createMeasurement('test', 'customCat').end();
113
-
114
- sinon.assert.calledOnce(onTrace);
115
- sinon.assert.calledWith(
116
- onTrace,
117
- sinon.match({
118
- type: 'trace',
119
- name: 'test',
120
- categories: ['cat:origin:customCat'],
121
- duration: sinon.match.number,
122
- }),
123
- );
59
+ describe('PluginTracer', () => {
60
+ it('emits events with proper origin/category', () => {
61
+ const pluginTracer = new PluginTracer({
62
+ origin: 'origin',
63
+ category: 'cat',
124
64
  });
65
+ const measurement = pluginTracer.createMeasurement('test', 'customCat');
66
+ measurement.end();
67
+ sinon.assert.calledWith(
68
+ onTrace,
69
+ sinon.match({
70
+ type: 'trace',
71
+ name: 'test',
72
+ categories: ['cat:origin:customCat'],
73
+ duration: sinon.match.number,
74
+ }),
75
+ );
125
76
  });
126
77
  });
127
78
  });