@atlaspack/profiler 2.14.15-typescript-e769947a5.0 → 2.14.15-typescript-6de04fbae.0
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/lib/{SamplingProfiler.d.ts → SamplingProfiler.d.mts} +1 -1
- package/lib/SamplingProfiler.js +100 -58
- package/lib/SamplingProfiler.js.flow +47 -0
- package/lib/SamplingProfiler.mjs +51 -0
- package/lib/{Trace.d.ts → Trace.d.mts} +3 -3
- package/lib/Trace.js +126 -112
- package/lib/Trace.js.flow +15 -0
- package/lib/Trace.mjs +111 -0
- package/lib/{Tracer.d.ts → Tracer.d.mts} +3 -3
- package/lib/Tracer.js +112 -114
- package/lib/Tracer.js.flow +46 -0
- package/lib/Tracer.mjs +114 -0
- package/lib/index.d.mts +4 -0
- package/lib/index.js +22 -22
- package/lib/index.mjs +3 -0
- package/lib/types.js +4 -1
- package/lib/types.mjs +1 -0
- package/package.json +21 -9
- package/src/SamplingProfiler.mts +94 -0
- package/src/{Trace.js → Trace.mts} +5 -9
- package/src/{Tracer.js → Tracer.mts} +28 -23
- package/src/index.mts +4 -0
- package/src/types.mts +6 -0
- package/test/{Tracer.test.js → Tracer.test.mts} +9 -4
- package/tsconfig.json +4 -0
- package/build-ts.js +0 -8
- package/lib/index.d.ts +0 -4
- package/src/SamplingProfiler.js +0 -93
- /package/{src/index.js → lib/index.js.flow} +0 -0
- /package/lib/{types.d.ts → types.d.mts} +0 -0
- /package/{src/types.js → lib/types.js.flow} +0 -0
package/lib/Tracer.js
CHANGED
|
@@ -1,131 +1,129 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
2
|
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
|
|
3
|
+
value: true
|
|
5
4
|
});
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
};
|
|
12
|
-
return data;
|
|
13
|
-
}
|
|
14
|
-
function _perf_hooks() {
|
|
15
|
-
const data = require("perf_hooks");
|
|
16
|
-
_perf_hooks = function () {
|
|
17
|
-
return data;
|
|
18
|
-
};
|
|
19
|
-
return data;
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: all[name]
|
|
9
|
+
});
|
|
20
10
|
}
|
|
21
|
-
|
|
11
|
+
_export(exports, {
|
|
12
|
+
PluginTracer: function() {
|
|
13
|
+
return PluginTracer;
|
|
14
|
+
},
|
|
15
|
+
default: function() {
|
|
16
|
+
return Tracer;
|
|
17
|
+
},
|
|
18
|
+
tracer: function() {
|
|
19
|
+
return tracer;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
const _events = require("@atlaspack/events");
|
|
23
|
+
const _perf_hooks = require("perf_hooks");
|
|
22
24
|
let tid;
|
|
23
25
|
try {
|
|
24
|
-
|
|
25
|
-
} catch
|
|
26
|
-
|
|
26
|
+
tid = require('worker_threads').threadId;
|
|
27
|
+
} catch {
|
|
28
|
+
tid = 0;
|
|
27
29
|
}
|
|
28
30
|
const pid = process.pid;
|
|
29
31
|
class TraceMeasurement {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
32
|
+
#active = true;
|
|
33
|
+
#name;
|
|
34
|
+
#pid;
|
|
35
|
+
#tid;
|
|
36
|
+
#start;
|
|
37
|
+
// $FlowFixMe
|
|
38
|
+
#data;
|
|
39
|
+
constructor(tracer, name, pid, tid, data){
|
|
40
|
+
this.#name = name;
|
|
41
|
+
this.#pid = pid;
|
|
42
|
+
this.#tid = tid;
|
|
43
|
+
this.#start = _perf_hooks.performance.now();
|
|
44
|
+
this.#data = data;
|
|
45
|
+
}
|
|
46
|
+
end() {
|
|
47
|
+
if (!this.#active) return;
|
|
48
|
+
const duration = _perf_hooks.performance.now() - this.#start;
|
|
49
|
+
tracer.trace({
|
|
50
|
+
type: 'trace',
|
|
51
|
+
name: this.#name,
|
|
52
|
+
pid: this.#pid,
|
|
53
|
+
tid: this.#tid,
|
|
54
|
+
duration,
|
|
55
|
+
ts: this.#start,
|
|
56
|
+
...this.#data
|
|
57
|
+
});
|
|
58
|
+
this.#active = false;
|
|
59
|
+
}
|
|
58
60
|
}
|
|
59
61
|
class Tracer {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
async wrap(name, fn) {
|
|
66
|
-
let measurement = this.createMeasurement(name);
|
|
67
|
-
try {
|
|
68
|
-
await fn();
|
|
69
|
-
} finally {
|
|
70
|
-
measurement && measurement.end();
|
|
62
|
+
#traceEmitter = new _events.ValueEmitter();
|
|
63
|
+
#enabled = false;
|
|
64
|
+
onTrace(cb) {
|
|
65
|
+
return this.#traceEmitter.addListener(cb);
|
|
71
66
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (typeof argumentName === 'string') {
|
|
80
|
-
args = {
|
|
81
|
-
name: argumentName
|
|
82
|
-
};
|
|
67
|
+
async wrap(name, fn) {
|
|
68
|
+
let measurement = this.createMeasurement(name);
|
|
69
|
+
try {
|
|
70
|
+
await fn();
|
|
71
|
+
} finally{
|
|
72
|
+
measurement && measurement.end();
|
|
73
|
+
}
|
|
83
74
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
args
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
75
|
+
createMeasurement(name, category = 'Core', argumentName, otherArgs) {
|
|
76
|
+
if (!this.enabled) return null;
|
|
77
|
+
// We create `args` in a fairly verbose way to avoid object
|
|
78
|
+
// allocation where not required.
|
|
79
|
+
let args;
|
|
80
|
+
if (typeof argumentName === 'string') {
|
|
81
|
+
args = {
|
|
82
|
+
name: argumentName
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
if (typeof otherArgs === 'object') {
|
|
86
|
+
if (typeof args == 'undefined') {
|
|
87
|
+
args = {};
|
|
88
|
+
}
|
|
89
|
+
for (const [k, v] of Object.entries(otherArgs)){
|
|
90
|
+
args[k] = v;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const data = {
|
|
94
|
+
categories: [
|
|
95
|
+
category
|
|
96
|
+
],
|
|
97
|
+
args
|
|
98
|
+
};
|
|
99
|
+
return new TraceMeasurement(this, name, pid, tid, data);
|
|
100
|
+
}
|
|
101
|
+
get enabled() {
|
|
102
|
+
return this.#enabled;
|
|
103
|
+
}
|
|
104
|
+
enable() {
|
|
105
|
+
this.#enabled = true;
|
|
106
|
+
}
|
|
107
|
+
disable() {
|
|
108
|
+
this.#enabled = false;
|
|
109
|
+
}
|
|
110
|
+
trace(event) {
|
|
111
|
+
if (!this.#enabled) return;
|
|
112
|
+
this.#traceEmitter.emit(event);
|
|
91
113
|
}
|
|
92
|
-
const data = {
|
|
93
|
-
categories: [category],
|
|
94
|
-
args
|
|
95
|
-
};
|
|
96
|
-
return new TraceMeasurement(this, name, pid, tid, data);
|
|
97
|
-
}
|
|
98
|
-
get enabled() {
|
|
99
|
-
return this.#enabled;
|
|
100
|
-
}
|
|
101
|
-
enable() {
|
|
102
|
-
this.#enabled = true;
|
|
103
|
-
}
|
|
104
|
-
disable() {
|
|
105
|
-
this.#enabled = false;
|
|
106
|
-
}
|
|
107
|
-
trace(event) {
|
|
108
|
-
if (!this.#enabled) return;
|
|
109
|
-
this.#traceEmitter.emit(event);
|
|
110
|
-
}
|
|
111
114
|
}
|
|
112
|
-
|
|
113
|
-
const tracer = exports.tracer = new Tracer();
|
|
115
|
+
const tracer = new Tracer();
|
|
114
116
|
class PluginTracer {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
createMeasurement(name, category, argumentName, otherArgs) {
|
|
128
|
-
return tracer.createMeasurement(name, `${this.category}:${this.origin}${typeof category === 'string' ? `:${category}` : ''}`, argumentName, otherArgs);
|
|
129
|
-
}
|
|
117
|
+
/** @private */ origin;
|
|
118
|
+
/** @private */ category;
|
|
119
|
+
/** @private */ constructor(opts){
|
|
120
|
+
this.origin = opts.origin;
|
|
121
|
+
this.category = opts.category;
|
|
122
|
+
}
|
|
123
|
+
get enabled() {
|
|
124
|
+
return tracer.enabled;
|
|
125
|
+
}
|
|
126
|
+
createMeasurement(name, category, argumentName, otherArgs) {
|
|
127
|
+
return tracer.createMeasurement(name, `${this.category}:${this.origin}${typeof category === 'string' ? `:${category}` : ''}`, argumentName, otherArgs);
|
|
128
|
+
}
|
|
130
129
|
}
|
|
131
|
-
exports.PluginTracer = PluginTracer;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// @flow strict-local
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
TraceEvent,
|
|
5
|
+
IDisposable,
|
|
6
|
+
PluginTracer as IPluginTracer,
|
|
7
|
+
} from '@atlaspack/types';
|
|
8
|
+
import type {
|
|
9
|
+
TraceMeasurement as ITraceMeasurement,
|
|
10
|
+
TraceMeasurementData,
|
|
11
|
+
} from './types';
|
|
12
|
+
import {ValueEmitter} from '@atlaspack/events';
|
|
13
|
+
import {performance} from 'perf_hooks';
|
|
14
|
+
|
|
15
|
+
declare export default class Tracer {
|
|
16
|
+
enabled: boolean;
|
|
17
|
+
onTrace(cb: (event: TraceEvent) => mixed): IDisposable;
|
|
18
|
+
wrap(name: string, fn: () => mixed): Promise<void> ;
|
|
19
|
+
createMeasurement(
|
|
20
|
+
name: string,
|
|
21
|
+
category?: string,
|
|
22
|
+
argumentName?: string,
|
|
23
|
+
otherArgs?: {[key: string]: mixed},
|
|
24
|
+
): ITraceMeasurement | null;
|
|
25
|
+
enable(): void;
|
|
26
|
+
disable(): void;
|
|
27
|
+
trace(event: TraceEvent): void;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export var tracer: Tracer;
|
|
31
|
+
|
|
32
|
+
type TracerOpts = {|
|
|
33
|
+
origin: string,
|
|
34
|
+
category: string,
|
|
35
|
+
|};
|
|
36
|
+
|
|
37
|
+
declare export class PluginTracer implements IPluginTracer {
|
|
38
|
+
enabled: boolean;
|
|
39
|
+
constructor(opts: TracerOpts): PluginTracer;
|
|
40
|
+
createMeasurement(
|
|
41
|
+
name: string,
|
|
42
|
+
category?: string,
|
|
43
|
+
argumentName?: string,
|
|
44
|
+
otherArgs?: {[key: string]: mixed},
|
|
45
|
+
): ITraceMeasurement | null;
|
|
46
|
+
}
|
package/lib/Tracer.mjs
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { ValueEmitter } from '@atlaspack/events';
|
|
2
|
+
import { performance } from 'perf_hooks';
|
|
3
|
+
let tid;
|
|
4
|
+
try {
|
|
5
|
+
tid = require('worker_threads').threadId;
|
|
6
|
+
}
|
|
7
|
+
catch {
|
|
8
|
+
tid = 0;
|
|
9
|
+
}
|
|
10
|
+
const pid = process.pid;
|
|
11
|
+
class TraceMeasurement {
|
|
12
|
+
#active = true;
|
|
13
|
+
#name;
|
|
14
|
+
#pid;
|
|
15
|
+
#tid;
|
|
16
|
+
#start;
|
|
17
|
+
// $FlowFixMe
|
|
18
|
+
#data;
|
|
19
|
+
constructor(tracer, name, pid, tid, data) {
|
|
20
|
+
this.#name = name;
|
|
21
|
+
this.#pid = pid;
|
|
22
|
+
this.#tid = tid;
|
|
23
|
+
this.#start = performance.now();
|
|
24
|
+
this.#data = data;
|
|
25
|
+
}
|
|
26
|
+
end() {
|
|
27
|
+
if (!this.#active)
|
|
28
|
+
return;
|
|
29
|
+
const duration = performance.now() - this.#start;
|
|
30
|
+
tracer.trace({
|
|
31
|
+
type: 'trace',
|
|
32
|
+
name: this.#name,
|
|
33
|
+
pid: this.#pid,
|
|
34
|
+
tid: this.#tid,
|
|
35
|
+
duration,
|
|
36
|
+
ts: this.#start,
|
|
37
|
+
...this.#data,
|
|
38
|
+
});
|
|
39
|
+
this.#active = false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export default class Tracer {
|
|
43
|
+
#traceEmitter = new ValueEmitter();
|
|
44
|
+
#enabled = false;
|
|
45
|
+
onTrace(cb) {
|
|
46
|
+
return this.#traceEmitter.addListener(cb);
|
|
47
|
+
}
|
|
48
|
+
async wrap(name, fn) {
|
|
49
|
+
let measurement = this.createMeasurement(name);
|
|
50
|
+
try {
|
|
51
|
+
await fn();
|
|
52
|
+
}
|
|
53
|
+
finally {
|
|
54
|
+
measurement && measurement.end();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
createMeasurement(name, category = 'Core', argumentName, otherArgs) {
|
|
58
|
+
if (!this.enabled)
|
|
59
|
+
return null;
|
|
60
|
+
// We create `args` in a fairly verbose way to avoid object
|
|
61
|
+
// allocation where not required.
|
|
62
|
+
let args;
|
|
63
|
+
if (typeof argumentName === 'string') {
|
|
64
|
+
args = {
|
|
65
|
+
name: argumentName,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
if (typeof otherArgs === 'object') {
|
|
69
|
+
if (typeof args == 'undefined') {
|
|
70
|
+
args = {};
|
|
71
|
+
}
|
|
72
|
+
for (const [k, v] of Object.entries(otherArgs)) {
|
|
73
|
+
args[k] = v;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const data = {
|
|
77
|
+
categories: [category],
|
|
78
|
+
args,
|
|
79
|
+
};
|
|
80
|
+
return new TraceMeasurement(this, name, pid, tid, data);
|
|
81
|
+
}
|
|
82
|
+
get enabled() {
|
|
83
|
+
return this.#enabled;
|
|
84
|
+
}
|
|
85
|
+
enable() {
|
|
86
|
+
this.#enabled = true;
|
|
87
|
+
}
|
|
88
|
+
disable() {
|
|
89
|
+
this.#enabled = false;
|
|
90
|
+
}
|
|
91
|
+
trace(event) {
|
|
92
|
+
if (!this.#enabled)
|
|
93
|
+
return;
|
|
94
|
+
this.#traceEmitter.emit(event);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
export const tracer = new Tracer();
|
|
98
|
+
export class PluginTracer {
|
|
99
|
+
/** @private */
|
|
100
|
+
origin;
|
|
101
|
+
/** @private */
|
|
102
|
+
category;
|
|
103
|
+
/** @private */
|
|
104
|
+
constructor(opts) {
|
|
105
|
+
this.origin = opts.origin;
|
|
106
|
+
this.category = opts.category;
|
|
107
|
+
}
|
|
108
|
+
get enabled() {
|
|
109
|
+
return tracer.enabled;
|
|
110
|
+
}
|
|
111
|
+
createMeasurement(name, category, argumentName, otherArgs) {
|
|
112
|
+
return tracer.createMeasurement(name, `${this.category}:${this.origin}${typeof category === 'string' ? `:${category}` : ''}`, argumentName, otherArgs);
|
|
113
|
+
}
|
|
114
|
+
}
|
package/lib/index.d.mts
ADDED
package/lib/index.js
CHANGED
|
@@ -3,31 +3,31 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
function _export(target, all) {
|
|
7
|
+
for (var name in all) Object.defineProperty(target, name, {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: all[name]
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
_export(exports, {
|
|
13
|
+
PluginTracer: function () {
|
|
9
14
|
return _Tracer.PluginTracer;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
Object.defineProperty(exports, "SamplingProfiler", {
|
|
13
|
-
enumerable: true,
|
|
14
|
-
get: function () {
|
|
15
|
+
},
|
|
16
|
+
SamplingProfiler: function () {
|
|
15
17
|
return _SamplingProfiler.default;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
Object.defineProperty(exports, "Trace", {
|
|
19
|
-
enumerable: true,
|
|
20
|
-
get: function () {
|
|
18
|
+
},
|
|
19
|
+
Trace: function () {
|
|
21
20
|
return _Trace.default;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
Object.defineProperty(exports, "tracer", {
|
|
25
|
-
enumerable: true,
|
|
26
|
-
get: function () {
|
|
21
|
+
},
|
|
22
|
+
tracer: function () {
|
|
27
23
|
return _Tracer.tracer;
|
|
28
24
|
}
|
|
29
25
|
});
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
function
|
|
26
|
+
const _SamplingProfiler = /*#__PURE__*/_interop_require_default(require("./SamplingProfiler.mjs"));
|
|
27
|
+
const _Trace = /*#__PURE__*/_interop_require_default(require("./Trace.mjs"));
|
|
28
|
+
const _Tracer = require("./Tracer.mjs");
|
|
29
|
+
function _interop_require_default(obj) {
|
|
30
|
+
return obj && obj.__esModule ? obj : {
|
|
31
|
+
default: obj
|
|
32
|
+
};
|
|
33
|
+
}
|
package/lib/index.mjs
ADDED
package/lib/types.js
CHANGED
package/lib/types.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaspack/profiler",
|
|
3
|
-
"version": "2.14.15-typescript-
|
|
3
|
+
"version": "2.14.15-typescript-6de04fbae.0",
|
|
4
4
|
"description": "Blazing fast, zero configuration web application bundler",
|
|
5
5
|
"license": "(MIT OR Apache-2.0)",
|
|
6
|
+
"type": "commonjs",
|
|
6
7
|
"publishConfig": {
|
|
7
8
|
"access": "public"
|
|
8
9
|
},
|
|
@@ -11,20 +12,31 @@
|
|
|
11
12
|
"url": "https://github.com/atlassian-labs/atlaspack.git"
|
|
12
13
|
},
|
|
13
14
|
"main": "lib/index.js",
|
|
14
|
-
"
|
|
15
|
+
"types": "lib/index.d.mts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"atlaspack::sources": "./src/index.mts",
|
|
19
|
+
"types": [
|
|
20
|
+
"./lib/index.d.mts",
|
|
21
|
+
"./src/index.mts"
|
|
22
|
+
],
|
|
23
|
+
"import": "./lib/index.mjs",
|
|
24
|
+
"require": "./lib/index.js",
|
|
25
|
+
"default": "./lib/index.js"
|
|
26
|
+
},
|
|
27
|
+
"./*": "./*"
|
|
28
|
+
},
|
|
15
29
|
"engines": {
|
|
16
30
|
"node": ">= 16.0.0"
|
|
17
31
|
},
|
|
18
32
|
"scripts": {
|
|
19
|
-
"build-
|
|
20
|
-
"check-ts": "tsc --noEmit lib/index.d.ts"
|
|
33
|
+
"build-tsc": "LINK_LIB=true node ../../../scripts/build-tsc.mjs"
|
|
21
34
|
},
|
|
22
35
|
"dependencies": {
|
|
23
|
-
"@atlaspack/diagnostic": "2.14.2-typescript-
|
|
24
|
-
"@atlaspack/events": "2.14.2-typescript-
|
|
25
|
-
"@atlaspack/types-internal": "2.14.15-typescript-
|
|
36
|
+
"@atlaspack/diagnostic": "2.14.2-typescript-6de04fbae.0",
|
|
37
|
+
"@atlaspack/events": "2.14.2-typescript-6de04fbae.0",
|
|
38
|
+
"@atlaspack/types-internal": "2.14.15-typescript-6de04fbae.0",
|
|
26
39
|
"chrome-trace-event": "^1.0.2"
|
|
27
40
|
},
|
|
28
|
-
"
|
|
29
|
-
"gitHead": "e769947a5b0c22d9477211ac1ce6614e6bf9def3"
|
|
41
|
+
"gitHead": "6de04fbaeccfba1e7832c737f6318cbd603fc74d"
|
|
30
42
|
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { Session } from "inspector";
|
|
2
|
+
import ThrowableDiagnostic from "@atlaspack/diagnostic";
|
|
3
|
+
|
|
4
|
+
// https://chromedevtools.github.io/devtools-protocol/tot/Profiler#type-Profile
|
|
5
|
+
export type Profile = {
|
|
6
|
+
nodes: Array<ProfileNode>;
|
|
7
|
+
startTime: number;
|
|
8
|
+
endTime: number;
|
|
9
|
+
samples?: Array<number>;
|
|
10
|
+
timeDeltas?: Array<number>;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
// https://chromedevtools.github.io/devtools-protocol/tot/Profiler#type-ProfileNode
|
|
14
|
+
type ProfileNode = {
|
|
15
|
+
id: number;
|
|
16
|
+
callFrame: CallFrame;
|
|
17
|
+
hitCount?: number;
|
|
18
|
+
children?: Array<number>;
|
|
19
|
+
deoptReason?: string;
|
|
20
|
+
positionTicks?: PositionTickInfo;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// https://chromedevtools.github.io/devtools-protocol/tot/Runtime#type-CallFrame
|
|
24
|
+
type CallFrame = {
|
|
25
|
+
functionName: string;
|
|
26
|
+
scriptId: string;
|
|
27
|
+
url: string;
|
|
28
|
+
lineNumber: string;
|
|
29
|
+
columnNumber: string;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// https://chromedevtools.github.io/devtools-protocol/tot/Profiler#type-PositionTickInfo
|
|
33
|
+
type PositionTickInfo = {
|
|
34
|
+
line: number;
|
|
35
|
+
ticks: number;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export default class SamplingProfiler {
|
|
39
|
+
session: Session | undefined;
|
|
40
|
+
|
|
41
|
+
async startProfiling(): Promise<unknown> {
|
|
42
|
+
let inspector: typeof import('inspector');
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
inspector = await import('inspector');
|
|
46
|
+
} catch (err) {
|
|
47
|
+
throw new ThrowableDiagnostic({
|
|
48
|
+
diagnostic: {
|
|
49
|
+
message: `The inspector module isn't available`,
|
|
50
|
+
origin: '@atlaspack/workers',
|
|
51
|
+
hints: ['Disable build profiling']
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
if (!this.session) {
|
|
56
|
+
this.session = new inspector.Session()
|
|
57
|
+
}
|
|
58
|
+
this.session.connect();
|
|
59
|
+
return Promise.all([this.sendCommand('Profiler.setSamplingInterval', {
|
|
60
|
+
interval: 100
|
|
61
|
+
}), this.sendCommand('Profiler.enable'), this.sendCommand('Profiler.start')]);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
sendCommand(method: string, params?: any): Promise<{
|
|
65
|
+
profile: Profile;
|
|
66
|
+
}> {
|
|
67
|
+
if (!this.session) {
|
|
68
|
+
throw new Error('No session set')
|
|
69
|
+
}
|
|
70
|
+
return new Promise((resolve, reject) => {
|
|
71
|
+
this.session!.post(method, params, (err, p) => {
|
|
72
|
+
if (err == null) {
|
|
73
|
+
resolve((p as {
|
|
74
|
+
profile: Profile;
|
|
75
|
+
}));
|
|
76
|
+
} else {
|
|
77
|
+
reject(err);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
destroy() {
|
|
84
|
+
if (this.session != null) {
|
|
85
|
+
this.session.disconnect();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async stopProfiling(): Promise<Profile> {
|
|
90
|
+
let res = await this.sendCommand('Profiler.stop');
|
|
91
|
+
this.destroy();
|
|
92
|
+
return res.profile;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import type {Profile} from './SamplingProfiler';
|
|
1
|
+
import type {Profile} from './SamplingProfiler.mts';
|
|
3
2
|
import type {Writable} from 'stream';
|
|
4
3
|
import {Tracer} from 'chrome-trace-event';
|
|
5
4
|
|
|
@@ -38,7 +37,6 @@ export default class Trace {
|
|
|
38
37
|
},
|
|
39
38
|
},
|
|
40
39
|
});
|
|
41
|
-
|
|
42
40
|
this.tracer.instantEvent({
|
|
43
41
|
name: 'TracingStartedInBrowser',
|
|
44
42
|
id: this.getEventId(),
|
|
@@ -56,13 +54,12 @@ export default class Trace {
|
|
|
56
54
|
if (this.eventId === 0) {
|
|
57
55
|
this.init(profile.startTime);
|
|
58
56
|
}
|
|
57
|
+
|
|
59
58
|
const trace = this.tracer;
|
|
60
59
|
const tid = this.tid;
|
|
61
60
|
this.tid++;
|
|
62
|
-
|
|
63
61
|
const cpuStartTime = profile.startTime;
|
|
64
62
|
const cpuEndTime = profile.endTime;
|
|
65
|
-
|
|
66
63
|
trace.instantEvent({
|
|
67
64
|
tid,
|
|
68
65
|
id: this.getEventId(),
|
|
@@ -74,7 +71,6 @@ export default class Trace {
|
|
|
74
71
|
},
|
|
75
72
|
ts: cpuStartTime,
|
|
76
73
|
});
|
|
77
|
-
|
|
78
74
|
trace.completeEvent({
|
|
79
75
|
tid,
|
|
80
76
|
name: 'EvaluateScript',
|
|
@@ -91,16 +87,16 @@ export default class Trace {
|
|
|
91
87
|
},
|
|
92
88
|
},
|
|
93
89
|
});
|
|
94
|
-
|
|
95
90
|
trace.instantEvent({
|
|
96
91
|
tid,
|
|
97
92
|
ts: 0,
|
|
98
93
|
ph: 'M',
|
|
99
94
|
cat: ['__metadata'],
|
|
100
95
|
name: 'thread_name',
|
|
101
|
-
args: {
|
|
96
|
+
args: {
|
|
97
|
+
name,
|
|
98
|
+
},
|
|
102
99
|
});
|
|
103
|
-
|
|
104
100
|
trace.instantEvent({
|
|
105
101
|
tid,
|
|
106
102
|
name: 'CpuProfile',
|