traceperf 0.2.1 → 1.3.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.
Files changed (268) hide show
  1. package/README.md +608 -253
  2. package/dist/__tests__/helpers/console.d.ts +9 -0
  3. package/dist/__tests__/helpers/console.js +25 -0
  4. package/dist/__tests__/helpers/console.js.map +1 -0
  5. package/dist/auto.d.ts +30 -0
  6. package/dist/auto.js +91 -0
  7. package/dist/auto.js.map +1 -0
  8. package/dist/browser.d.ts +52 -144
  9. package/dist/browser.js +112 -439
  10. package/dist/browser.js.map +1 -1
  11. package/dist/cli.d.ts +68 -0
  12. package/dist/cli.js +528 -0
  13. package/dist/cli.js.map +1 -0
  14. package/dist/core/allocations.d.ts +38 -0
  15. package/dist/core/allocations.js +85 -0
  16. package/dist/core/allocations.js.map +1 -0
  17. package/dist/core/cpu-profile.d.ts +84 -0
  18. package/dist/core/cpu-profile.js +181 -0
  19. package/dist/core/cpu-profile.js.map +1 -0
  20. package/dist/core/env.d.ts +10 -0
  21. package/dist/core/env.js +40 -0
  22. package/dist/core/env.js.map +1 -0
  23. package/dist/core/event-loop.d.ts +30 -0
  24. package/dist/core/event-loop.js +43 -0
  25. package/dist/core/event-loop.js.map +1 -0
  26. package/dist/core/explain.d.ts +48 -0
  27. package/dist/core/explain.js +236 -0
  28. package/dist/core/explain.js.map +1 -0
  29. package/dist/core/exporters.d.ts +111 -0
  30. package/dist/core/exporters.js +236 -0
  31. package/dist/core/exporters.js.map +1 -0
  32. package/dist/core/index.d.ts +9 -3
  33. package/dist/core/index.js +9 -3
  34. package/dist/core/index.js.map +1 -1
  35. package/dist/core/optimized-performance-monitor.d.ts +180 -26
  36. package/dist/core/optimized-performance-monitor.js +687 -175
  37. package/dist/core/optimized-performance-monitor.js.map +1 -1
  38. package/dist/core/prometheus.d.ts +36 -0
  39. package/dist/core/prometheus.js +93 -0
  40. package/dist/core/prometheus.js.map +1 -0
  41. package/dist/core/records.d.ts +97 -0
  42. package/dist/core/records.js +87 -0
  43. package/dist/core/records.js.map +1 -0
  44. package/dist/core/stats.d.ts +45 -0
  45. package/dist/core/stats.js +136 -0
  46. package/dist/core/stats.js.map +1 -0
  47. package/dist/core/timeline.d.ts +28 -0
  48. package/dist/core/timeline.js +65 -0
  49. package/dist/core/timeline.js.map +1 -0
  50. package/dist/drivers.d.ts +51 -0
  51. package/dist/drivers.js +205 -0
  52. package/dist/drivers.js.map +1 -0
  53. package/dist/esm/auto.d.ts +30 -0
  54. package/dist/esm/auto.js +87 -0
  55. package/dist/esm/auto.js.map +1 -0
  56. package/dist/esm/browser.d.ts +52 -144
  57. package/dist/esm/browser.js +101 -445
  58. package/dist/esm/browser.js.map +1 -1
  59. package/dist/esm/cli.d.ts +68 -0
  60. package/dist/esm/cli.js +520 -0
  61. package/dist/esm/cli.js.map +1 -0
  62. package/dist/esm/core/allocations.d.ts +38 -0
  63. package/dist/esm/core/allocations.js +82 -0
  64. package/dist/esm/core/allocations.js.map +1 -0
  65. package/dist/esm/core/cpu-profile.d.ts +84 -0
  66. package/dist/esm/core/cpu-profile.js +176 -0
  67. package/dist/esm/core/cpu-profile.js.map +1 -0
  68. package/dist/esm/core/env.d.ts +10 -0
  69. package/dist/esm/core/env.js +35 -0
  70. package/dist/esm/core/env.js.map +1 -0
  71. package/dist/esm/core/event-loop.d.ts +30 -0
  72. package/dist/esm/core/event-loop.js +40 -0
  73. package/dist/esm/core/event-loop.js.map +1 -0
  74. package/dist/esm/core/explain.d.ts +48 -0
  75. package/dist/esm/core/explain.js +232 -0
  76. package/dist/esm/core/explain.js.map +1 -0
  77. package/dist/esm/core/exporters.d.ts +111 -0
  78. package/dist/esm/core/exporters.js +229 -0
  79. package/dist/esm/core/exporters.js.map +1 -0
  80. package/dist/esm/core/index.d.ts +10 -4
  81. package/dist/esm/core/index.js +10 -4
  82. package/dist/esm/core/index.js.map +1 -1
  83. package/dist/esm/core/optimized-performance-monitor.d.ts +180 -26
  84. package/dist/esm/core/optimized-performance-monitor.js +685 -173
  85. package/dist/esm/core/optimized-performance-monitor.js.map +1 -1
  86. package/dist/esm/core/prometheus.d.ts +36 -0
  87. package/dist/esm/core/prometheus.js +89 -0
  88. package/dist/esm/core/prometheus.js.map +1 -0
  89. package/dist/esm/core/records.d.ts +97 -0
  90. package/dist/esm/core/records.js +82 -0
  91. package/dist/esm/core/records.js.map +1 -0
  92. package/dist/esm/core/stats.d.ts +45 -0
  93. package/dist/esm/core/stats.js +131 -0
  94. package/dist/esm/core/stats.js.map +1 -0
  95. package/dist/esm/core/timeline.d.ts +28 -0
  96. package/dist/esm/core/timeline.js +62 -0
  97. package/dist/esm/core/timeline.js.map +1 -0
  98. package/dist/esm/drivers.d.ts +51 -0
  99. package/dist/esm/drivers.js +197 -0
  100. package/dist/esm/drivers.js.map +1 -0
  101. package/dist/esm/index.d.ts +13 -5
  102. package/dist/esm/index.js +21 -17
  103. package/dist/esm/index.js.map +1 -1
  104. package/dist/esm/instrument.d.ts +88 -0
  105. package/dist/esm/instrument.js +274 -0
  106. package/dist/esm/instrument.js.map +1 -0
  107. package/dist/esm/integrations.d.ts +70 -0
  108. package/dist/esm/integrations.js +197 -0
  109. package/dist/esm/integrations.js.map +1 -0
  110. package/dist/esm/node-builtins.d.ts +1 -0
  111. package/dist/esm/node-builtins.js +32 -0
  112. package/dist/esm/node-builtins.js.map +1 -0
  113. package/dist/esm/package.json +3 -0
  114. package/dist/esm/register.d.ts +20 -0
  115. package/dist/esm/register.js +98 -0
  116. package/dist/esm/register.js.map +1 -0
  117. package/dist/esm/report-html.d.ts +11 -0
  118. package/dist/esm/report-html.js +106 -0
  119. package/dist/esm/report-html.js.map +1 -0
  120. package/dist/esm/types/index.d.ts +4 -80
  121. package/dist/esm/types/index.js +1 -2
  122. package/dist/esm/types/index.js.map +1 -1
  123. package/dist/esm/types/options.d.ts +72 -0
  124. package/dist/esm/types/options.js +2 -0
  125. package/dist/esm/types/options.js.map +1 -0
  126. package/dist/esm/watch.d.ts +17 -0
  127. package/dist/esm/watch.js +87 -0
  128. package/dist/esm/watch.js.map +1 -0
  129. package/dist/index.d.ts +10 -2
  130. package/dist/index.js +26 -29
  131. package/dist/index.js.map +1 -1
  132. package/dist/instrument.d.ts +88 -0
  133. package/dist/instrument.js +282 -0
  134. package/dist/instrument.js.map +1 -0
  135. package/dist/integrations.d.ts +70 -0
  136. package/dist/integrations.js +205 -0
  137. package/dist/integrations.js.map +1 -0
  138. package/dist/node-builtins.d.ts +1 -0
  139. package/dist/node-builtins.js +67 -0
  140. package/dist/node-builtins.js.map +1 -0
  141. package/dist/register.d.ts +20 -0
  142. package/dist/register.js +103 -0
  143. package/dist/register.js.map +1 -0
  144. package/dist/report-html.d.ts +11 -0
  145. package/dist/report-html.js +109 -0
  146. package/dist/report-html.js.map +1 -0
  147. package/dist/traceperf.browser.js +1910 -0
  148. package/dist/traceperf.browser.min.js +6 -0
  149. package/dist/types/index.d.ts +4 -80
  150. package/dist/types/index.js +1 -2
  151. package/dist/types/index.js.map +1 -1
  152. package/dist/types/options.d.ts +72 -0
  153. package/dist/types/{config.js → options.js} +1 -1
  154. package/dist/types/options.js.map +1 -0
  155. package/dist/watch.d.ts +17 -0
  156. package/dist/watch.js +90 -0
  157. package/dist/watch.js.map +1 -0
  158. package/package.json +99 -19
  159. package/dist/core/config.d.ts +0 -77
  160. package/dist/core/config.js +0 -116
  161. package/dist/core/config.js.map +0 -1
  162. package/dist/core/constants.d.ts +0 -78
  163. package/dist/core/constants.js +0 -109
  164. package/dist/core/constants.js.map +0 -1
  165. package/dist/core/logger.d.ts +0 -97
  166. package/dist/core/logger.js +0 -186
  167. package/dist/core/logger.js.map +0 -1
  168. package/dist/esm/core/config.d.ts +0 -77
  169. package/dist/esm/core/config.js +0 -112
  170. package/dist/esm/core/config.js.map +0 -1
  171. package/dist/esm/core/constants.d.ts +0 -78
  172. package/dist/esm/core/constants.js +0 -106
  173. package/dist/esm/core/constants.js.map +0 -1
  174. package/dist/esm/core/logger.d.ts +0 -97
  175. package/dist/esm/core/logger.js +0 -182
  176. package/dist/esm/core/logger.js.map +0 -1
  177. package/dist/esm/formatters/ascii.d.ts +0 -52
  178. package/dist/esm/formatters/ascii.js +0 -100
  179. package/dist/esm/formatters/ascii.js.map +0 -1
  180. package/dist/esm/formatters/cli.d.ts +0 -50
  181. package/dist/esm/formatters/cli.js +0 -96
  182. package/dist/esm/formatters/cli.js.map +0 -1
  183. package/dist/esm/formatters/index.d.ts +0 -3
  184. package/dist/esm/formatters/index.js +0 -4
  185. package/dist/esm/formatters/index.js.map +0 -1
  186. package/dist/esm/formatters/json.d.ts +0 -45
  187. package/dist/esm/formatters/json.js +0 -85
  188. package/dist/esm/formatters/json.js.map +0 -1
  189. package/dist/esm/trackers/execution.d.ts +0 -101
  190. package/dist/esm/trackers/execution.js +0 -226
  191. package/dist/esm/trackers/execution.js.map +0 -1
  192. package/dist/esm/trackers/index.d.ts +0 -2
  193. package/dist/esm/trackers/index.js +0 -3
  194. package/dist/esm/trackers/index.js.map +0 -1
  195. package/dist/esm/trackers/performance.d.ts +0 -68
  196. package/dist/esm/trackers/performance.js +0 -112
  197. package/dist/esm/trackers/performance.js.map +0 -1
  198. package/dist/esm/types/config.d.ts +0 -142
  199. package/dist/esm/types/config.js +0 -2
  200. package/dist/esm/types/config.js.map +0 -1
  201. package/dist/esm/types/logger.d.ts +0 -147
  202. package/dist/esm/types/logger.js +0 -2
  203. package/dist/esm/types/logger.js.map +0 -1
  204. package/dist/esm/utils/colors.d.ts +0 -87
  205. package/dist/esm/utils/colors.js +0 -146
  206. package/dist/esm/utils/colors.js.map +0 -1
  207. package/dist/esm/utils/index.d.ts +0 -3
  208. package/dist/esm/utils/index.js +0 -4
  209. package/dist/esm/utils/index.js.map +0 -1
  210. package/dist/esm/utils/proxy-tracker.d.ts +0 -68
  211. package/dist/esm/utils/proxy-tracker.js +0 -127
  212. package/dist/esm/utils/proxy-tracker.js.map +0 -1
  213. package/dist/esm/utils/stack.d.ts +0 -63
  214. package/dist/esm/utils/stack.js +0 -110
  215. package/dist/esm/utils/stack.js.map +0 -1
  216. package/dist/esm/utils/string.d.ts +0 -29
  217. package/dist/esm/utils/string.js +0 -45
  218. package/dist/esm/utils/string.js.map +0 -1
  219. package/dist/esm/utils/timing.d.ts +0 -65
  220. package/dist/esm/utils/timing.js +0 -99
  221. package/dist/esm/utils/timing.js.map +0 -1
  222. package/dist/formatters/ascii.d.ts +0 -52
  223. package/dist/formatters/ascii.js +0 -104
  224. package/dist/formatters/ascii.js.map +0 -1
  225. package/dist/formatters/cli.d.ts +0 -50
  226. package/dist/formatters/cli.js +0 -100
  227. package/dist/formatters/cli.js.map +0 -1
  228. package/dist/formatters/index.d.ts +0 -3
  229. package/dist/formatters/index.js +0 -20
  230. package/dist/formatters/index.js.map +0 -1
  231. package/dist/formatters/json.d.ts +0 -45
  232. package/dist/formatters/json.js +0 -89
  233. package/dist/formatters/json.js.map +0 -1
  234. package/dist/trackers/execution.d.ts +0 -101
  235. package/dist/trackers/execution.js +0 -230
  236. package/dist/trackers/execution.js.map +0 -1
  237. package/dist/trackers/index.d.ts +0 -2
  238. package/dist/trackers/index.js +0 -19
  239. package/dist/trackers/index.js.map +0 -1
  240. package/dist/trackers/performance.d.ts +0 -68
  241. package/dist/trackers/performance.js +0 -116
  242. package/dist/trackers/performance.js.map +0 -1
  243. package/dist/types/config.d.ts +0 -142
  244. package/dist/types/config.js.map +0 -1
  245. package/dist/types/logger.d.ts +0 -147
  246. package/dist/types/logger.js +0 -3
  247. package/dist/types/logger.js.map +0 -1
  248. package/dist/types.d.ts +0 -65
  249. package/dist/types.js +0 -6
  250. package/dist/types.js.map +0 -1
  251. package/dist/utils/colors.d.ts +0 -87
  252. package/dist/utils/colors.js +0 -160
  253. package/dist/utils/colors.js.map +0 -1
  254. package/dist/utils/index.d.ts +0 -3
  255. package/dist/utils/index.js +0 -20
  256. package/dist/utils/index.js.map +0 -1
  257. package/dist/utils/proxy-tracker.d.ts +0 -68
  258. package/dist/utils/proxy-tracker.js +0 -131
  259. package/dist/utils/proxy-tracker.js.map +0 -1
  260. package/dist/utils/stack.d.ts +0 -63
  261. package/dist/utils/stack.js +0 -116
  262. package/dist/utils/stack.js.map +0 -1
  263. package/dist/utils/string.d.ts +0 -29
  264. package/dist/utils/string.js +0 -50
  265. package/dist/utils/string.js.map +0 -1
  266. package/dist/utils/timing.d.ts +0 -65
  267. package/dist/utils/timing.js +0 -106
  268. package/dist/utils/timing.js.map +0 -1
@@ -0,0 +1,1910 @@
1
+ /*! traceperf v1.3.0 | MIT License | browser global build */
2
+ "use strict";
3
+ var TracePerf = (() => {
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
6
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
7
+ }) : x)(function(x) {
8
+ if (typeof require !== "undefined") return require.apply(this, arguments);
9
+ throw Error('Dynamic require of "' + x + '" is not supported');
10
+ });
11
+ var __commonJS = (cb, mod) => function __require2() {
12
+ try {
13
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
14
+ } catch (e) {
15
+ throw mod = 0, e;
16
+ }
17
+ };
18
+
19
+ // dist/core/records.js
20
+ var require_records = __commonJS({
21
+ "dist/core/records.js"(exports) {
22
+ "use strict";
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.coveredLength = coveredLength;
25
+ exports.walkRecords = walkRecords;
26
+ exports.formatTree = formatTree;
27
+ function coveredLength(intervals) {
28
+ if (intervals.length === 0)
29
+ return 0;
30
+ const sorted = intervals.slice().sort((a, b) => a[0] - b[0]);
31
+ let total = 0;
32
+ let [curStart, curEnd] = sorted[0];
33
+ for (let i = 1; i < sorted.length; i++) {
34
+ const [start, end] = sorted[i];
35
+ if (start > curEnd) {
36
+ total += curEnd - curStart;
37
+ curStart = start;
38
+ curEnd = end;
39
+ } else if (end > curEnd) {
40
+ curEnd = end;
41
+ }
42
+ }
43
+ return total + (curEnd - curStart);
44
+ }
45
+ function walkRecords(root, visit, depth = 0) {
46
+ visit(root, depth);
47
+ for (const child of root.children) {
48
+ walkRecords(child, visit, depth + 1);
49
+ }
50
+ }
51
+ var formatMs = (ms) => `${ms.toFixed(3)} ms`;
52
+ function formatError(error) {
53
+ return error instanceof Error ? error.message : String(error);
54
+ }
55
+ function formatLine(record, options) {
56
+ const args = record.args && record.args.length > 0 ? `(${record.args.join(", ")})` : "";
57
+ let line = `${record.label}${args}: ${formatMs(record.duration)}`;
58
+ if (options.detailed) {
59
+ const extra = [];
60
+ if (record.children.length > 0)
61
+ extra.push(`self ${formatMs(record.selfDuration)}`);
62
+ if (record.async)
63
+ extra.push(`sync ${formatMs(record.syncDuration)}`);
64
+ if (extra.length > 0)
65
+ line += ` (${extra.join(", ")})`;
66
+ }
67
+ if (record.memoryDelta !== void 0) {
68
+ const kb = (record.memoryDelta / 1024).toFixed(2);
69
+ line += ` \u{1F4CA} ${record.memoryDelta >= 0 ? "+" : ""}${kb} KB`;
70
+ if (record.memoryDelta < 0)
71
+ line += " (gc)";
72
+ }
73
+ if (options.detailed && options.blockingThreshold !== void 0 && options.blockingThreshold > 0 && record.syncDuration >= options.blockingThreshold) {
74
+ line += ` \u26A0 blocked event loop ${formatMs(record.syncDuration)}`;
75
+ }
76
+ if (options.showErrors && record.error !== void 0 && record.error !== null) {
77
+ line += ` \u2716 ${formatError(record.error)}`;
78
+ }
79
+ return line;
80
+ }
81
+ function formatTree(root, options = {}) {
82
+ const lines = [];
83
+ const visit = (record, ancestors, isLast) => {
84
+ const prefix = ancestors.map((hasMoreSiblings) => hasMoreSiblings ? "\u2502 " : " ").join("");
85
+ lines.push(`${prefix}${isLast ? "\u2514\u2500 " : "\u251C\u2500 "}${formatLine(record, options)}`);
86
+ const shown = record.children.filter((child) => child.duration >= child.threshold);
87
+ shown.forEach((child, i) => visit(child, [...ancestors, !isLast], i === shown.length - 1));
88
+ };
89
+ visit(root, [], true);
90
+ return lines.join("\n");
91
+ }
92
+ }
93
+ });
94
+
95
+ // dist/core/stats.js
96
+ var require_stats = __commonJS({
97
+ "dist/core/stats.js"(exports) {
98
+ "use strict";
99
+ Object.defineProperty(exports, "__esModule", { value: true });
100
+ exports.StatsCollector = exports.OTHER_LABEL = void 0;
101
+ exports.formatStatsTable = formatStatsTable;
102
+ var records_1 = require_records();
103
+ exports.OTHER_LABEL = "(other)";
104
+ var LabelAccumulator = class {
105
+ constructor(reservoirSize) {
106
+ this.reservoirSize = reservoirSize;
107
+ this.count = 0;
108
+ this.errors = 0;
109
+ this.total = 0;
110
+ this.selfTotal = 0;
111
+ this.min = Infinity;
112
+ this.max = -Infinity;
113
+ this.samples = [];
114
+ }
115
+ add(duration, selfDuration, failed) {
116
+ this.count++;
117
+ this.total += duration;
118
+ this.selfTotal += selfDuration;
119
+ if (failed)
120
+ this.errors++;
121
+ if (duration < this.min)
122
+ this.min = duration;
123
+ if (duration > this.max)
124
+ this.max = duration;
125
+ if (this.samples.length < this.reservoirSize) {
126
+ this.samples.push(duration);
127
+ } else {
128
+ const slot = Math.floor(Math.random() * this.count);
129
+ if (slot < this.reservoirSize)
130
+ this.samples[slot] = duration;
131
+ }
132
+ }
133
+ snapshot() {
134
+ const sorted = this.samples.slice().sort((a, b) => a - b);
135
+ const pct = (p) => {
136
+ if (sorted.length === 0)
137
+ return 0;
138
+ const rank = Math.min(sorted.length - 1, Math.max(0, Math.ceil(p * sorted.length) - 1));
139
+ return sorted[rank];
140
+ };
141
+ return {
142
+ count: this.count,
143
+ errors: this.errors,
144
+ total: this.total,
145
+ mean: this.count ? this.total / this.count : 0,
146
+ min: this.count ? this.min : 0,
147
+ max: this.count ? this.max : 0,
148
+ p50: pct(0.5),
149
+ p95: pct(0.95),
150
+ p99: pct(0.99),
151
+ selfMean: this.count ? this.selfTotal / this.count : 0
152
+ };
153
+ }
154
+ };
155
+ var StatsCollector = class {
156
+ constructor(options = {}) {
157
+ var _a, _b;
158
+ this.labels = /* @__PURE__ */ new Map();
159
+ this.reservoirSize = Math.max(1, (_a = options.reservoirSize) !== null && _a !== void 0 ? _a : 1024);
160
+ this.maxLabels = Math.max(1, (_b = options.maxLabels) !== null && _b !== void 0 ? _b : 1e3);
161
+ }
162
+ /** Record one execution (not its children) */
163
+ add(record) {
164
+ let label = record.label;
165
+ let acc = this.labels.get(label);
166
+ if (!acc) {
167
+ if (this.labels.size >= this.maxLabels - 1) {
168
+ label = exports.OTHER_LABEL;
169
+ acc = this.labels.get(label);
170
+ }
171
+ if (!acc) {
172
+ acc = new LabelAccumulator(this.reservoirSize);
173
+ this.labels.set(label, acc);
174
+ }
175
+ }
176
+ acc.add(record.duration, record.selfDuration, record.error !== void 0 && record.error !== null);
177
+ }
178
+ /** Record a whole finished tree */
179
+ addTree(root) {
180
+ (0, records_1.walkRecords)(root, (record) => this.add(record));
181
+ }
182
+ get(label) {
183
+ var _a;
184
+ return (_a = this.labels.get(label)) === null || _a === void 0 ? void 0 : _a.snapshot();
185
+ }
186
+ all() {
187
+ const out = {};
188
+ this.labels.forEach((acc, label) => {
189
+ out[label] = acc.snapshot();
190
+ });
191
+ return out;
192
+ }
193
+ reset() {
194
+ this.labels = /* @__PURE__ */ new Map();
195
+ }
196
+ };
197
+ exports.StatsCollector = StatsCollector;
198
+ function formatStatsTable(stats) {
199
+ const rows = Object.keys(stats).map((label) => ({ label, ...stats[label] })).sort((a, b) => b.total - a.total);
200
+ if (rows.length === 0)
201
+ return "traceperf: no calls recorded";
202
+ const head = ["label", "calls", "errors", "total ms", "mean", "p50", "p95", "p99", "max", "self mean"];
203
+ const body = rows.map((r) => [
204
+ r.label,
205
+ String(r.count),
206
+ String(r.errors),
207
+ r.total.toFixed(1),
208
+ r.mean.toFixed(3),
209
+ r.p50.toFixed(3),
210
+ r.p95.toFixed(3),
211
+ r.p99.toFixed(3),
212
+ r.max.toFixed(3),
213
+ r.selfMean.toFixed(3)
214
+ ]);
215
+ const widths = head.map((h, i) => Math.max(h.length, ...body.map((row) => row[i].length)));
216
+ const fmt = (cells) => cells.map((c, i) => i === 0 ? c.padEnd(widths[i]) : c.padStart(widths[i])).join(" ");
217
+ return [fmt(head), widths.map((w) => "-".repeat(w)).join(" "), ...body.map(fmt)].join("\n");
218
+ }
219
+ }
220
+ });
221
+
222
+ // dist/core/exporters.js
223
+ var require_exporters = __commonJS({
224
+ "dist/core/exporters.js"(exports) {
225
+ "use strict";
226
+ Object.defineProperty(exports, "__esModule", { value: true });
227
+ exports.toChromeTrace = toChromeTrace;
228
+ exports.createTraceRecorder = createTraceRecorder;
229
+ exports.openTelemetryExporter = openTelemetryExporter;
230
+ exports.recordToJSON = recordToJSON;
231
+ exports.jsonLinesExporter = jsonLinesExporter;
232
+ var records_1 = require_records();
233
+ function toChromeTrace(roots) {
234
+ const events = [];
235
+ const lanes = [];
236
+ const fits = (lane, start, end) => {
237
+ while (lane.length > 0 && lane[lane.length - 1] <= start)
238
+ lane.pop();
239
+ return lane.length === 0 || end <= lane[lane.length - 1];
240
+ };
241
+ const place = (record, preferred) => {
242
+ const candidates = [preferred, ...lanes.map((_, i) => i).filter((i) => i !== preferred)];
243
+ for (const i of candidates) {
244
+ if (lanes[i] && fits(lanes[i], record.startTime, record.endTime)) {
245
+ lanes[i].push(record.endTime);
246
+ return i;
247
+ }
248
+ }
249
+ lanes.push([record.endTime]);
250
+ return lanes.length - 1;
251
+ };
252
+ const all = [];
253
+ const sortedRoots = roots.slice().sort((a, b) => a.startTime - b.startTime);
254
+ const visit = (record, parentLane) => {
255
+ all.push({ record, parentLane });
256
+ };
257
+ sortedRoots.forEach((root) => (0, records_1.walkRecords)(root, (r) => visit(r, 0)));
258
+ all.sort((a, b) => a.record.startTime - b.record.startTime || b.record.duration - a.record.duration);
259
+ const laneOf = /* @__PURE__ */ new Map();
260
+ for (const { record } of all) {
261
+ const preferred = record.parentId !== null && laneOf.has(record.parentId) ? laneOf.get(record.parentId) : 0;
262
+ const lane = place(record, preferred);
263
+ laneOf.set(record.id, lane);
264
+ const args = { selfMs: record.selfDuration, syncMs: record.syncDuration };
265
+ if (record.memoryDelta !== void 0)
266
+ args.memoryDeltaBytes = record.memoryDelta;
267
+ if (record.args && record.args.length)
268
+ args.args = record.args;
269
+ if (record.error !== void 0 && record.error !== null) {
270
+ args.error = record.error instanceof Error ? record.error.message : String(record.error);
271
+ }
272
+ events.push({
273
+ name: record.label,
274
+ cat: "traceperf",
275
+ ph: "X",
276
+ ts: Math.round(record.startTime * 1e3),
277
+ dur: Math.max(0, Math.round(record.duration * 1e3)),
278
+ pid: 1,
279
+ tid: lane + 1,
280
+ args
281
+ });
282
+ }
283
+ const meta = [
284
+ { name: "process_name", cat: "__metadata", ph: "M", ts: 0, pid: 1, tid: 0, args: { name: "traceperf" } },
285
+ ...lanes.map((_, i) => ({
286
+ name: "thread_name",
287
+ cat: "__metadata",
288
+ ph: "M",
289
+ ts: 0,
290
+ pid: 1,
291
+ tid: i + 1,
292
+ args: { name: i === 0 ? "main" : `concurrent ${i}` }
293
+ }))
294
+ ];
295
+ return { traceEvents: [...meta, ...events], displayTimeUnit: "ms" };
296
+ }
297
+ function createTraceRecorder(options = {}) {
298
+ var _a;
299
+ const maxRoots = Math.max(1, (_a = options.maxRoots) !== null && _a !== void 0 ? _a : 1e4);
300
+ const roots = [];
301
+ let stopped = false;
302
+ return {
303
+ name: "chrome-trace",
304
+ roots,
305
+ onComplete(root) {
306
+ if (stopped)
307
+ return;
308
+ roots.push(root);
309
+ if (roots.length > maxRoots)
310
+ roots.shift();
311
+ },
312
+ stop() {
313
+ if (!stopped) {
314
+ stopped = true;
315
+ if (options.onStop)
316
+ options.onStop();
317
+ }
318
+ return toChromeTrace(roots);
319
+ }
320
+ };
321
+ }
322
+ var OTEL_STATUS_ERROR = 2;
323
+ function decorateSpan(span, record) {
324
+ span.setAttribute("traceperf.self_ms", record.selfDuration);
325
+ span.setAttribute("traceperf.sync_ms", record.syncDuration);
326
+ span.setAttribute("traceperf.async", record.async);
327
+ if (record.memoryDelta !== void 0)
328
+ span.setAttribute("traceperf.memory_delta_bytes", record.memoryDelta);
329
+ if (record.args && record.args.length)
330
+ span.setAttribute("traceperf.args", record.args.join(", "));
331
+ if (record.error !== void 0 && record.error !== null) {
332
+ span.recordException(record.error);
333
+ span.setStatus({
334
+ code: OTEL_STATUS_ERROR,
335
+ message: record.error instanceof Error ? record.error.message : String(record.error)
336
+ });
337
+ }
338
+ }
339
+ function openTelemetryExporter(api, options = {}) {
340
+ var _a, _b;
341
+ const tracer = (_a = options.tracer) !== null && _a !== void 0 ? _a : api.trace.getTracer((_b = options.tracerName) !== null && _b !== void 0 ? _b : "traceperf");
342
+ if (options.live) {
343
+ if (typeof api.context.with !== "function") {
344
+ throw new Error("openTelemetryExporter: live mode needs api.context.with (pass @opentelemetry/api)");
345
+ }
346
+ const spans = /* @__PURE__ */ new Map();
347
+ return {
348
+ name: "opentelemetry-live",
349
+ onStart(execution) {
350
+ spans.set(execution.id, tracer.startSpan(execution.label, { startTime: execution.startEpochMs }, api.context.active()));
351
+ },
352
+ wrap(execution, run) {
353
+ const span = spans.get(execution.id);
354
+ if (!span)
355
+ return run();
356
+ return api.context.with(api.trace.setSpan(api.context.active(), span), run);
357
+ },
358
+ onComplete(root) {
359
+ (0, records_1.walkRecords)(root, (record) => {
360
+ const span = spans.get(record.id);
361
+ if (!span)
362
+ return;
363
+ spans.delete(record.id);
364
+ if (span.updateName)
365
+ span.updateName(record.label);
366
+ decorateSpan(span, record);
367
+ span.end(record.startEpochMs + record.duration);
368
+ });
369
+ }
370
+ };
371
+ }
372
+ const startContexts = /* @__PURE__ */ new Map();
373
+ return {
374
+ name: "opentelemetry",
375
+ onStart(execution) {
376
+ if (execution.parentId === null)
377
+ startContexts.set(execution.id, api.context.active());
378
+ },
379
+ onComplete(root) {
380
+ var _a2;
381
+ const parentContext = (_a2 = startContexts.get(root.id)) !== null && _a2 !== void 0 ? _a2 : api.context.active();
382
+ startContexts.delete(root.id);
383
+ const emit = (record, ctx) => {
384
+ const span = tracer.startSpan(record.label, { startTime: record.startEpochMs }, ctx);
385
+ decorateSpan(span, record);
386
+ const childCtx = api.trace.setSpan(ctx, span);
387
+ record.children.forEach((child) => emit(child, childCtx));
388
+ span.end(record.startEpochMs + record.duration);
389
+ };
390
+ emit(root, parentContext);
391
+ }
392
+ };
393
+ }
394
+ function recordToJSON(record) {
395
+ return {
396
+ label: record.label,
397
+ start: new Date(record.startEpochMs).toISOString(),
398
+ durationMs: record.duration,
399
+ selfMs: record.selfDuration,
400
+ syncMs: record.syncDuration,
401
+ async: record.async,
402
+ ...record.memoryDelta !== void 0 ? { memoryDeltaBytes: record.memoryDelta } : {},
403
+ ...record.args && record.args.length ? { args: record.args } : {},
404
+ ...record.error !== void 0 && record.error !== null ? { error: record.error instanceof Error ? record.error.message : String(record.error) } : {},
405
+ children: record.children.map(recordToJSON)
406
+ };
407
+ }
408
+ function jsonLinesExporter(write) {
409
+ const out = write !== null && write !== void 0 ? write : ((line) => {
410
+ const proc = typeof process !== "undefined" ? process : void 0;
411
+ if (proc && proc.stdout && typeof proc.stdout.write === "function")
412
+ proc.stdout.write(line + "\n");
413
+ else
414
+ console.log(line);
415
+ });
416
+ return {
417
+ name: "json-lines",
418
+ onComplete(root) {
419
+ out(JSON.stringify(recordToJSON(root)));
420
+ }
421
+ };
422
+ }
423
+ }
424
+ });
425
+
426
+ // dist/core/env.js
427
+ var require_env = __commonJS({
428
+ "dist/core/env.js"(exports) {
429
+ "use strict";
430
+ Object.defineProperty(exports, "__esModule", { value: true });
431
+ exports.loadNodeBuiltin = exports.provideNodeBuiltins = void 0;
432
+ var provided = {};
433
+ var provideNodeBuiltins = (modules) => {
434
+ Object.assign(provided, modules);
435
+ };
436
+ exports.provideNodeBuiltins = provideNodeBuiltins;
437
+ var loadNodeBuiltin = (id) => {
438
+ if (provided[id])
439
+ return provided[id];
440
+ try {
441
+ const proc = typeof process !== "undefined" ? process : void 0;
442
+ if (!proc || !proc.versions || !proc.versions.node)
443
+ return void 0;
444
+ if (typeof proc.getBuiltinModule === "function") {
445
+ return proc.getBuiltinModule(id);
446
+ }
447
+ const req = typeof __require === "function" ? __require : void 0;
448
+ return req ? req(id) : void 0;
449
+ } catch (_a) {
450
+ return void 0;
451
+ }
452
+ };
453
+ exports.loadNodeBuiltin = loadNodeBuiltin;
454
+ }
455
+ });
456
+
457
+ // dist/core/optimized-performance-monitor.js
458
+ var require_optimized_performance_monitor = __commonJS({
459
+ "dist/core/optimized-performance-monitor.js"(exports) {
460
+ "use strict";
461
+ Object.defineProperty(exports, "__esModule", { value: true });
462
+ exports.OptimizedPerformanceMonitor = exports.OptimizedExecutionTracker = exports.formatArg = exports.getDuration = exports.getTimestamp = exports.getMemoryUsage = exports.TrackingModes = void 0;
463
+ var records_1 = require_records();
464
+ var stats_1 = require_stats();
465
+ var exporters_1 = require_exporters();
466
+ var env_1 = require_env();
467
+ exports.TrackingModes = {
468
+ PERFORMANCE: "performance",
469
+ BALANCED: "balanced",
470
+ DETAILED: "detailed",
471
+ DEBUG: "debug"
472
+ };
473
+ var DEFAULT_TRACKING_MODE = exports.TrackingModes.BALANCED;
474
+ var v8Module = (0, env_1.loadNodeBuiltin)("v8");
475
+ var readHeapUsed = v8Module && typeof v8Module.getHeapStatistics === "function" ? () => v8Module.getHeapStatistics().used_heap_size : void 0;
476
+ var getMemoryUsage = () => {
477
+ var _a;
478
+ if (readHeapUsed) {
479
+ return readHeapUsed();
480
+ }
481
+ if (typeof process !== "undefined" && process.memoryUsage) {
482
+ const mem = process.memoryUsage();
483
+ return mem.heapUsed;
484
+ } else if (typeof performance !== "undefined" && "memory" in performance) {
485
+ return ((_a = performance.memory) === null || _a === void 0 ? void 0 : _a.usedJSHeapSize) || 0;
486
+ }
487
+ return 0;
488
+ };
489
+ exports.getMemoryUsage = getMemoryUsage;
490
+ exports.getTimestamp = // Clock chosen once at load time (the hot path should not re-detect it)
491
+ typeof performance !== "undefined" && typeof performance.now === "function" ? () => performance.now() * 1e6 : typeof process !== "undefined" && typeof process.hrtime === "function" ? () => {
492
+ const hrTime = process.hrtime();
493
+ return hrTime[0] * 1e9 + hrTime[1];
494
+ } : () => Date.now() * 1e6;
495
+ var getDuration = (startTime) => {
496
+ return (0, exports.getTimestamp)() - startTime;
497
+ };
498
+ exports.getDuration = getDuration;
499
+ var EPOCH_OFFSET_MS = Date.now() - (0, exports.getTimestamp)() / 1e6;
500
+ var MAX_ARG_LENGTH = 50;
501
+ var formatArg = (arg) => {
502
+ var _a, _b;
503
+ let text;
504
+ try {
505
+ if (typeof arg === "string") {
506
+ text = JSON.stringify(arg.length > MAX_ARG_LENGTH ? arg.slice(0, MAX_ARG_LENGTH) : arg);
507
+ } else if (typeof arg === "function") {
508
+ text = `[Function ${arg.name || "anonymous"}]`;
509
+ } else if (Array.isArray(arg)) {
510
+ text = `Array(${arg.length})`;
511
+ } else if (arg !== null && typeof arg === "object") {
512
+ const keys = Object.keys(arg);
513
+ if (keys.length <= 5) {
514
+ text = JSON.stringify(arg);
515
+ } else {
516
+ const name = ((_a = arg.constructor) === null || _a === void 0 ? void 0 : _a.name) || "Object";
517
+ text = `${name}{${keys.length} keys}`;
518
+ }
519
+ } else {
520
+ text = String(arg);
521
+ }
522
+ } catch (_c) {
523
+ const name = (_b = arg === null || arg === void 0 ? void 0 : arg.constructor) === null || _b === void 0 ? void 0 : _b.name;
524
+ text = typeof name === "string" && name ? `[${name}]` : "[object]";
525
+ }
526
+ return text.length > MAX_ARG_LENGTH ? `${text.slice(0, MAX_ARG_LENGTH - 1)}\u2026` : text;
527
+ };
528
+ exports.formatArg = formatArg;
529
+ var loadAsyncLocalStorage = () => {
530
+ var _a, _b;
531
+ return (_b = (_a = (0, env_1.loadNodeBuiltin)("async_hooks")) === null || _a === void 0 ? void 0 : _a.AsyncLocalStorage) !== null && _b !== void 0 ? _b : (
532
+ // Edge runtimes (e.g. Next.js Edge) expose it as a global
533
+ typeof globalThis !== "undefined" ? globalThis.AsyncLocalStorage : void 0
534
+ );
535
+ };
536
+ var createExecutionContext = (provided) => {
537
+ const AsyncLocalStorage = provided !== null && provided !== void 0 ? provided : loadAsyncLocalStorage();
538
+ if (AsyncLocalStorage) {
539
+ const storage = new AsyncLocalStorage();
540
+ return {
541
+ current: () => {
542
+ var _a;
543
+ return (_a = storage.getStore()) !== null && _a !== void 0 ? _a : null;
544
+ },
545
+ run: (executionId, fn) => storage.run(executionId, fn),
546
+ // AsyncLocalStorage.run forwards extra arguments to the callback
547
+ apply: (executionId, fn, thisArg, args) => storage.run(executionId, Reflect.apply, fn, thisArg, args)
548
+ };
549
+ }
550
+ let current = null;
551
+ const run = (executionId, fn) => {
552
+ const previous = current;
553
+ current = executionId;
554
+ try {
555
+ return fn();
556
+ } finally {
557
+ current = previous;
558
+ }
559
+ };
560
+ return {
561
+ current: () => current,
562
+ run,
563
+ apply: (executionId, fn, thisArg, args) => run(executionId, () => fn.apply(thisArg, args))
564
+ };
565
+ };
566
+ var NOOP_SPAN = {
567
+ id: "",
568
+ setLabel: () => void 0,
569
+ run: (fn) => fn(),
570
+ end: () => void 0
571
+ };
572
+ var clampRate = (rate) => Math.max(0, Math.min(1, rate));
573
+ var isNativePromise = (value) => value !== null && typeof value === "object" && (value instanceof Promise || typeof value.then === "function" && Object.prototype.toString.call(value) === "[object Promise]");
574
+ var OptimizedExecutionTracker = class {
575
+ /**
576
+ * Create a new execution tracker
577
+ * @param options Tracker configuration options
578
+ */
579
+ constructor(options = {}) {
580
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
581
+ this.executionTree = /* @__PURE__ */ new Map();
582
+ this.currentExecutionId = 0;
583
+ this.activeExecutions = /* @__PURE__ */ new Map();
584
+ this.plugins = [];
585
+ this.wrappers = [];
586
+ this.failedPlugins = /* @__PURE__ */ new Set();
587
+ this.showMemoryUsage = (_a = options.showMemoryUsage) !== null && _a !== void 0 ? _a : true;
588
+ this.enableNestedTracking = (_b = options.enableNestedTracking) !== null && _b !== void 0 ? _b : true;
589
+ this.silent = (_c = options.silent) !== null && _c !== void 0 ? _c : false;
590
+ this.trackingMode = (_d = options.trackingMode) !== null && _d !== void 0 ? _d : exports.TrackingModes.BALANCED;
591
+ this.defaultThreshold = (_e = options.threshold) !== null && _e !== void 0 ? _e : 0;
592
+ this.defaultSampleRate = clampRate((_f = options.sampleRate) !== null && _f !== void 0 ? _f : 1);
593
+ this.context = createExecutionContext(options.asyncLocalStorage);
594
+ this.enabled = (_g = options.enabled) !== null && _g !== void 0 ? _g : true;
595
+ this.blockingThreshold = (_h = options.blockingThreshold) !== null && _h !== void 0 ? _h : 50;
596
+ this.reporter = (_j = options.reporter) !== null && _j !== void 0 ? _j : null;
597
+ this.stats = options.stats === false ? null : new stats_1.StatsCollector(typeof options.stats === "object" ? options.stats : {});
598
+ (options.plugins || []).forEach((plugin) => this.use(plugin));
599
+ }
600
+ /**
601
+ * Register a plugin. Returns a function that removes it again.
602
+ */
603
+ use(plugin) {
604
+ this.plugins = [...this.plugins, plugin];
605
+ this.wrappers = this.plugins.filter((p) => typeof p.wrap === "function");
606
+ return () => {
607
+ this.plugins = this.plugins.filter((p) => p !== plugin);
608
+ this.wrappers = this.plugins.filter((p) => typeof p.wrap === "function");
609
+ };
610
+ }
611
+ /**
612
+ * Run `run` inside every plugin's wrap() (first registered = outermost).
613
+ * A wrap() that throws before calling run is reported once and skipped.
614
+ */
615
+ _wrap(execution, run) {
616
+ let next = run;
617
+ for (let i = this.wrappers.length - 1; i >= 0; i--) {
618
+ const plugin = this.wrappers[i];
619
+ const inner = next;
620
+ next = () => {
621
+ let ran = false;
622
+ const once = () => {
623
+ ran = true;
624
+ return inner();
625
+ };
626
+ try {
627
+ return plugin.wrap(execution, once);
628
+ } catch (error) {
629
+ if (ran)
630
+ throw error;
631
+ this._pluginFailed(plugin, "wrap", error);
632
+ return inner();
633
+ }
634
+ };
635
+ }
636
+ return next();
637
+ }
638
+ _pluginFailed(plugin, hook, error) {
639
+ if (!this.failedPlugins.has(plugin)) {
640
+ this.failedPlugins.add(plugin);
641
+ console.warn(`traceperf: plugin ${plugin.name || "(unnamed)"} threw in ${hook}:`, error);
642
+ }
643
+ }
644
+ _callPlugins(hook, payload) {
645
+ for (const plugin of this.plugins) {
646
+ const fn = plugin[hook];
647
+ if (!fn)
648
+ continue;
649
+ try {
650
+ fn.call(plugin, payload);
651
+ } catch (error) {
652
+ this._pluginFailed(plugin, hook, error);
653
+ }
654
+ }
655
+ }
656
+ /**
657
+ * Start timing a function execution
658
+ * @param label Function name or label
659
+ * @param parentExecutionId ID of parent execution if nested
660
+ * @param options Additional options
661
+ * @returns Execution ID
662
+ */
663
+ startTimer(label, parentExecutionId = null, options = {}, args = options.args) {
664
+ var _a, _b, _c, _d;
665
+ const trackingMode = (_a = options.trackingMode) !== null && _a !== void 0 ? _a : this.trackingMode;
666
+ const trackMemory = (_b = options.trackMemory) !== null && _b !== void 0 ? _b : this.showMemoryUsage;
667
+ const collectMemory = trackingMode !== exports.TrackingModes.PERFORMANCE && trackMemory;
668
+ const startTime = (0, exports.getTimestamp)();
669
+ const executionId = (++this.currentExecutionId).toString();
670
+ const execution = {
671
+ id: executionId,
672
+ label: label || "anonymous",
673
+ startTime,
674
+ endTime: 0,
675
+ duration: 0,
676
+ parentId: parentExecutionId,
677
+ children: [],
678
+ args: options.captureArgs && args ? Array.from(args).map(exports.formatArg) : void 0,
679
+ complete: false,
680
+ silent: (_c = options.silent) !== null && _c !== void 0 ? _c : this.silent,
681
+ trackingMode,
682
+ threshold: (_d = options.threshold) !== null && _d !== void 0 ? _d : this.defaultThreshold
683
+ };
684
+ if (collectMemory) {
685
+ execution.memoryAtStart = (0, exports.getMemoryUsage)();
686
+ execution.memoryAtEnd = 0;
687
+ execution.memoryDelta = 0;
688
+ }
689
+ if (parentExecutionId && this.activeExecutions.has(parentExecutionId)) {
690
+ const parent = this.activeExecutions.get(parentExecutionId);
691
+ if (parent && parent.children) {
692
+ parent.children.push(executionId);
693
+ }
694
+ }
695
+ this.activeExecutions.set(executionId, execution);
696
+ if (this.plugins.length > 0) {
697
+ this._callPlugins("onStart", {
698
+ id: executionId,
699
+ label: execution.label,
700
+ parentId: parentExecutionId,
701
+ startEpochMs: EPOCH_OFFSET_MS + startTime / 1e6
702
+ });
703
+ }
704
+ return executionId;
705
+ }
706
+ /**
707
+ * End timing a function execution
708
+ * @param executionId ID of the execution to end
709
+ * @param result Result of the function
710
+ * @param error Error if the function threw
711
+ * @returns Execution data
712
+ */
713
+ endTimer(executionId, result, error = null) {
714
+ if (!this.activeExecutions.has(executionId)) {
715
+ return null;
716
+ }
717
+ const execution = this.activeExecutions.get(executionId);
718
+ this.activeExecutions.delete(executionId);
719
+ execution.endTime = (0, exports.getTimestamp)();
720
+ execution.duration = execution.endTime - execution.startTime;
721
+ execution.result = result;
722
+ execution.error = error;
723
+ execution.complete = true;
724
+ if (execution.memoryAtStart !== void 0) {
725
+ execution.memoryAtEnd = (0, exports.getMemoryUsage)();
726
+ execution.memoryDelta = execution.memoryAtEnd - (execution.memoryAtStart || 0);
727
+ }
728
+ const parentRunning = execution.parentId !== null && this.activeExecutions.has(execution.parentId);
729
+ if (parentRunning) {
730
+ this.executionTree.set(executionId, execution);
731
+ return execution;
732
+ }
733
+ const record = this._toRecord(execution);
734
+ if (execution.children.length > 0) {
735
+ this._release(execution);
736
+ }
737
+ if (this.stats) {
738
+ this.stats.addTree(record);
739
+ }
740
+ if (!record.silent && record.trackingMode !== exports.TrackingModes.PERFORMANCE && record.duration >= record.threshold) {
741
+ this._report(record);
742
+ }
743
+ if (this.plugins.length > 0) {
744
+ this._callPlugins("onComplete", record);
745
+ }
746
+ return execution;
747
+ }
748
+ /**
749
+ * Drop a finished execution and its finished descendants
750
+ */
751
+ _release(execution) {
752
+ for (const childId of execution.children) {
753
+ const child = this.executionTree.get(childId);
754
+ if (child) {
755
+ this.executionTree.delete(childId);
756
+ this._release(child);
757
+ }
758
+ }
759
+ }
760
+ /**
761
+ * Mark the end of the synchronous part of an execution that returned a promise
762
+ */
763
+ markSyncEnd(executionId) {
764
+ const execution = this.activeExecutions.get(executionId);
765
+ if (execution) {
766
+ execution.syncEndTime = (0, exports.getTimestamp)();
767
+ }
768
+ }
769
+ /**
770
+ * Convert a finished execution (and its finished children) to a record tree
771
+ */
772
+ _toRecord(execution) {
773
+ var _a, _b, _c;
774
+ const startTime = execution.startTime / 1e6;
775
+ const endTime = execution.endTime / 1e6;
776
+ const duration = execution.duration / 1e6;
777
+ const children = [];
778
+ let covered = 0;
779
+ if (execution.children.length > 0) {
780
+ for (const childId of execution.children) {
781
+ const child = this.executionTree.get(childId);
782
+ if (child) {
783
+ children.push(this._toRecord(child));
784
+ }
785
+ }
786
+ covered = (0, records_1.coveredLength)(children.map((c) => [Math.max(c.startTime, startTime), Math.min(c.endTime, endTime)]));
787
+ }
788
+ const isAsync = execution.syncEndTime !== void 0;
789
+ const record = {
790
+ id: execution.id,
791
+ label: execution.label,
792
+ parentId: execution.parentId,
793
+ startTime,
794
+ endTime,
795
+ startEpochMs: EPOCH_OFFSET_MS + startTime,
796
+ duration,
797
+ selfDuration: Math.max(0, duration - covered),
798
+ syncDuration: isAsync ? (execution.syncEndTime - execution.startTime) / 1e6 : duration,
799
+ async: isAsync,
800
+ children,
801
+ threshold: (_a = execution.threshold) !== null && _a !== void 0 ? _a : 0,
802
+ trackingMode: (_b = execution.trackingMode) !== null && _b !== void 0 ? _b : this.trackingMode,
803
+ silent: (_c = execution.silent) !== null && _c !== void 0 ? _c : this.silent
804
+ };
805
+ if (execution.memoryAtStart !== void 0 && execution.memoryDelta !== void 0) {
806
+ record.memoryDelta = execution.memoryDelta;
807
+ }
808
+ if (execution.error !== null && execution.error !== void 0) {
809
+ record.error = execution.error;
810
+ }
811
+ if (execution.args && execution.args.length > 0) {
812
+ record.args = execution.args;
813
+ }
814
+ return record;
815
+ }
816
+ /**
817
+ * Print a finished tree (or hand it to the custom reporter)
818
+ */
819
+ _report(record) {
820
+ if (this.reporter) {
821
+ this.reporter(record);
822
+ return;
823
+ }
824
+ const detailed = record.trackingMode === exports.TrackingModes.DETAILED || record.trackingMode === exports.TrackingModes.DEBUG;
825
+ console.log((0, records_1.formatTree)(record, {
826
+ detailed,
827
+ showErrors: detailed,
828
+ blockingThreshold: this.blockingThreshold
829
+ }));
830
+ }
831
+ /**
832
+ * Run one call of `fn` with tracking (shared by createTrackable and track)
833
+ */
834
+ _invoke(fn, thisArg, args, options, label) {
835
+ if (!this.enabled) {
836
+ return fn.apply(thisArg, args);
837
+ }
838
+ const sampleRate = options.sampleRate !== void 0 ? clampRate(options.sampleRate) : this.defaultSampleRate;
839
+ const shouldSample = Math.random() < sampleRate;
840
+ if (!shouldSample) {
841
+ return fn.apply(thisArg, args);
842
+ }
843
+ const nested = this.enableNestedTracking && options.enableNestedTracking !== false;
844
+ const explicitParentId = options.parentExecutionId || null;
845
+ const parentExecutionId = explicitParentId !== null && explicitParentId !== void 0 ? explicitParentId : nested ? this.context.current() : null;
846
+ const executionId = this.startTimer(label, parentExecutionId, options, args);
847
+ let result;
848
+ try {
849
+ if (this.wrappers.length > 0) {
850
+ result = this._wrap({ id: executionId, label, parentId: parentExecutionId }, () => nested ? this.context.apply(executionId, fn, thisArg, args) : fn.apply(thisArg, args));
851
+ } else {
852
+ result = nested ? this.context.apply(executionId, fn, thisArg, args) : fn.apply(thisArg, args);
853
+ }
854
+ } catch (error) {
855
+ this.endTimer(executionId, void 0, error);
856
+ throw error;
857
+ }
858
+ if (isNativePromise(result)) {
859
+ this.markSyncEnd(executionId);
860
+ return result.then((resolvedValue) => {
861
+ this.endTimer(executionId, resolvedValue);
862
+ return resolvedValue;
863
+ }, (error) => {
864
+ this.endTimer(executionId, void 0, error);
865
+ throw error;
866
+ });
867
+ }
868
+ this.endTimer(executionId, result);
869
+ return result;
870
+ }
871
+ /**
872
+ * Create a trackable version of a function
873
+ * @param fn Function to track
874
+ * @param options Tracking options
875
+ * @returns Tracked version of the function
876
+ */
877
+ createTrackable(fn, options = {}) {
878
+ var _a;
879
+ if (typeof fn !== "function") {
880
+ throw new Error("First argument must be a function");
881
+ }
882
+ const label = options.label || fn.name || "anonymous";
883
+ const silent = (_a = options.silent) !== null && _a !== void 0 ? _a : this.silent;
884
+ const trackingMode = options.trackingMode || this.trackingMode;
885
+ if (trackingMode === exports.TrackingModes.PERFORMANCE && silent && !this.enableNestedTracking) {
886
+ return fn;
887
+ }
888
+ const invoke = (thisArg, args) => this._invoke(fn, thisArg, args, options, label);
889
+ const trackedFn = function(...args) {
890
+ return invoke(this, args);
891
+ };
892
+ Object.defineProperty(trackedFn, "name", { value: fn.name, configurable: true });
893
+ Object.defineProperty(trackedFn, "length", { value: fn.length });
894
+ return trackedFn;
895
+ }
896
+ /**
897
+ * Start a manually-ended execution (a "span"). Use `run()` to execute code
898
+ * as part of it, so tracked calls inside attach as children, and `end()`
899
+ * when the work is finished.
900
+ */
901
+ startSpan(label, options = {}) {
902
+ if (!this.enabled) {
903
+ return NOOP_SPAN;
904
+ }
905
+ const sampleRate = options.sampleRate !== void 0 ? clampRate(options.sampleRate) : this.defaultSampleRate;
906
+ if (!(Math.random() < sampleRate)) {
907
+ return NOOP_SPAN;
908
+ }
909
+ const nested = this.enableNestedTracking && options.enableNestedTracking !== false;
910
+ const explicitParentId = options.parentExecutionId || null;
911
+ const parentExecutionId = explicitParentId !== null && explicitParentId !== void 0 ? explicitParentId : nested ? this.context.current() : null;
912
+ const executionId = this.startTimer(label || "anonymous", parentExecutionId, {
913
+ trackMemory: options.trackMemory,
914
+ silent: options.silent,
915
+ trackingMode: options.trackingMode,
916
+ threshold: options.threshold
917
+ });
918
+ let ended = false;
919
+ return {
920
+ id: executionId,
921
+ setLabel: (newLabel) => {
922
+ const execution = this.activeExecutions.get(executionId);
923
+ if (execution && newLabel) {
924
+ execution.label = newLabel;
925
+ }
926
+ },
927
+ run: (fn) => {
928
+ const runInContext = () => nested ? this.context.run(executionId, fn) : fn();
929
+ const result = this.wrappers.length > 0 ? this._wrap({ id: executionId, label: label || "anonymous", parentId: parentExecutionId }, runInContext) : runInContext();
930
+ const execution = this.activeExecutions.get(executionId);
931
+ if (execution && execution.syncEndTime === void 0) {
932
+ execution.syncEndTime = (0, exports.getTimestamp)();
933
+ }
934
+ return result;
935
+ },
936
+ end: (error) => {
937
+ if (ended)
938
+ return;
939
+ ended = true;
940
+ this.endTimer(executionId, void 0, error !== null && error !== void 0 ? error : null);
941
+ }
942
+ };
943
+ }
944
+ /**
945
+ * Track a module's methods
946
+ * @param module Module to track
947
+ * @param options Tracking options
948
+ * @returns Tracked module
949
+ */
950
+ trackModule(module2, options = {}) {
951
+ var _a;
952
+ if (!module2 || typeof module2 !== "object") {
953
+ throw new Error("Module must be an object");
954
+ }
955
+ const prefix = options.prefix || "";
956
+ const trackingMode = options.trackingMode || this.trackingMode;
957
+ if (trackingMode === exports.TrackingModes.PERFORMANCE && ((_a = options.silent) !== null && _a !== void 0 ? _a : this.silent) && !this.enableNestedTracking) {
958
+ return module2;
959
+ }
960
+ const trackedModule = Object.create(Object.getPrototypeOf(module2));
961
+ Object.getOwnPropertyNames(module2).forEach((key) => {
962
+ const descriptor = Object.getOwnPropertyDescriptor(module2, key);
963
+ if (!descriptor)
964
+ return;
965
+ if (typeof module2[key] === "function") {
966
+ const methodOptions = {
967
+ ...options,
968
+ label: `${prefix}${key}`
969
+ };
970
+ trackedModule[key] = this.createTrackable(module2[key], methodOptions);
971
+ } else {
972
+ Object.defineProperty(trackedModule, key, descriptor);
973
+ }
974
+ });
975
+ return trackedModule;
976
+ }
977
+ /**
978
+ * Track a function execution directly
979
+ * @param fn Function to track
980
+ * @param options Tracking options
981
+ * @returns Function result
982
+ */
983
+ track(fn, options = {}) {
984
+ var _a;
985
+ if (typeof fn !== "function") {
986
+ throw new Error("First argument must be a function");
987
+ }
988
+ if ((options.trackingMode || this.trackingMode) === exports.TrackingModes.PERFORMANCE && ((_a = options.silent) !== null && _a !== void 0 ? _a : this.silent) && !this.enableNestedTracking) {
989
+ return fn.apply(options.thisContext, options.args || []);
990
+ }
991
+ const label = options.label || fn.name || "anonymous";
992
+ return this._invoke(fn, options.thisContext, options.args || [], options, label);
993
+ }
994
+ /**
995
+ * Reset the tracker state
996
+ */
997
+ reset() {
998
+ this.executionTree = /* @__PURE__ */ new Map();
999
+ this.currentExecutionId = 0;
1000
+ this.activeExecutions = /* @__PURE__ */ new Map();
1001
+ if (this.stats) {
1002
+ this.stats.reset();
1003
+ }
1004
+ }
1005
+ };
1006
+ exports.OptimizedExecutionTracker = OptimizedExecutionTracker;
1007
+ var OptimizedPerformanceMonitor = class {
1008
+ /**
1009
+ * Create a new performance monitor instance
1010
+ * @param options Configuration options
1011
+ */
1012
+ constructor(options = {}) {
1013
+ var _a, _b, _c;
1014
+ this.config = {
1015
+ trackingMode: options.trackingMode || DEFAULT_TRACKING_MODE,
1016
+ silent: options.silent || false,
1017
+ trackMemory: options.trackMemory !== void 0 ? options.trackMemory : true,
1018
+ enableNestedTracking: options.enableNestedTracking !== void 0 ? options.enableNestedTracking : true,
1019
+ threshold: (_a = options.threshold) !== null && _a !== void 0 ? _a : 0,
1020
+ sampleRate: options.sampleRate !== void 0 ? clampRate(options.sampleRate) : 1,
1021
+ enabled: (_b = options.enabled) !== null && _b !== void 0 ? _b : true,
1022
+ blockingThreshold: (_c = options.blockingThreshold) !== null && _c !== void 0 ? _c : 50
1023
+ };
1024
+ this.executionTracker = new OptimizedExecutionTracker({
1025
+ trackingMode: this.config.trackingMode,
1026
+ silent: this.config.silent,
1027
+ showMemoryUsage: this.config.trackMemory,
1028
+ enableNestedTracking: this.config.enableNestedTracking,
1029
+ threshold: this.config.threshold,
1030
+ sampleRate: this.config.sampleRate,
1031
+ enabled: this.config.enabled,
1032
+ blockingThreshold: this.config.blockingThreshold,
1033
+ stats: options.stats,
1034
+ reporter: options.reporter,
1035
+ plugins: options.plugins,
1036
+ asyncLocalStorage: options.asyncLocalStorage
1037
+ });
1038
+ if (options.onComplete) {
1039
+ this.onComplete(options.onComplete);
1040
+ }
1041
+ }
1042
+ /**
1043
+ * Track a function execution
1044
+ * @param fn The function to track
1045
+ * @param options Tracking options
1046
+ * @returns Result of the tracked function
1047
+ */
1048
+ track(fn, options = {}) {
1049
+ if (typeof fn !== "function") {
1050
+ throw new Error("First argument must be a function");
1051
+ }
1052
+ return this.executionTracker.track(fn, options);
1053
+ }
1054
+ /**
1055
+ * Create a trackable version of a function
1056
+ * @param fn The function to track
1057
+ * @param options Tracking options
1058
+ * @returns Tracked version of the function
1059
+ */
1060
+ createTrackable(fn, options = {}) {
1061
+ if (typeof fn !== "function") {
1062
+ throw new Error("First argument must be a function");
1063
+ }
1064
+ return this.executionTracker.createTrackable(fn, options);
1065
+ }
1066
+ /**
1067
+ * Register a module for tracking
1068
+ * @param module The module or object containing methods to track
1069
+ * @param options Tracking options
1070
+ * @returns Modified module with tracked methods
1071
+ */
1072
+ registerModule(module2, options = {}) {
1073
+ if (!module2 || typeof module2 !== "object") {
1074
+ throw new Error("Module must be an object");
1075
+ }
1076
+ return this.executionTracker.trackModule(module2, options);
1077
+ }
1078
+ /**
1079
+ * Track every method of an object or class instance, including methods
1080
+ * inherited from its prototype, without copying it. Returns a proxy:
1081
+ * state changes go to the original object, and methods run with the
1082
+ * original object as `this` (so private #fields keep working).
1083
+ */
1084
+ trackObject(target, options = {}) {
1085
+ var _a;
1086
+ if (!target || typeof target !== "object" && typeof target !== "function") {
1087
+ throw new Error("trackObject expects an object");
1088
+ }
1089
+ const ctorName = target.constructor && target.constructor !== Object ? target.constructor.name : "";
1090
+ const prefix = (_a = options.prefix) !== null && _a !== void 0 ? _a : ctorName ? `${ctorName}.` : "";
1091
+ const trackOptions = { ...options };
1092
+ delete trackOptions.prefix;
1093
+ const cache = /* @__PURE__ */ new Map();
1094
+ const wrap = (original, key, proxy2) => {
1095
+ var _a2;
1096
+ const tracked = this.createTrackable(original, {
1097
+ ...trackOptions,
1098
+ label: (_a2 = trackOptions.label) !== null && _a2 !== void 0 ? _a2 : `${prefix}${key}`
1099
+ });
1100
+ return function(...args) {
1101
+ return tracked.apply(this === proxy2 ? target : this, args);
1102
+ };
1103
+ };
1104
+ const proxy = new Proxy(target, {
1105
+ get: (obj, key, receiver) => {
1106
+ const value = Reflect.get(obj, key, receiver);
1107
+ if (typeof value !== "function" || typeof key === "symbol" || key === "constructor" || Object.prototype[key] === value) {
1108
+ return value;
1109
+ }
1110
+ const hit = cache.get(key);
1111
+ if (hit && hit.original === value) {
1112
+ return hit.tracked;
1113
+ }
1114
+ const tracked = wrap(value, key, proxy);
1115
+ cache.set(key, { original: value, tracked });
1116
+ return tracked;
1117
+ }
1118
+ });
1119
+ return proxy;
1120
+ }
1121
+ /**
1122
+ * Method decorator. Works with TypeScript 5 / TC39 standard decorators and
1123
+ * with legacy `experimentalDecorators`. The label defaults to
1124
+ * "ClassName.method".
1125
+ *
1126
+ * class UserService {
1127
+ * @tp.traced()
1128
+ * async getUser(id: string) { ... }
1129
+ * }
1130
+ */
1131
+ traced(options = {}) {
1132
+ const trackables = /* @__PURE__ */ new Map();
1133
+ const trackedFor = (fn, label) => {
1134
+ let tracked = trackables.get(label);
1135
+ if (!tracked) {
1136
+ tracked = this.createTrackable(fn, { ...options, label });
1137
+ trackables.set(label, tracked);
1138
+ }
1139
+ return tracked;
1140
+ };
1141
+ const ownerName = (receiver) => {
1142
+ var _a;
1143
+ return typeof receiver === "function" ? receiver.name : ((_a = receiver === null || receiver === void 0 ? void 0 : receiver.constructor) === null || _a === void 0 ? void 0 : _a.name) || "anonymous";
1144
+ };
1145
+ const wrapMethod = (fn, methodName) => {
1146
+ const wrapped = function(...args) {
1147
+ var _a;
1148
+ const label = (_a = options.label) !== null && _a !== void 0 ? _a : `${ownerName(this)}.${methodName}`;
1149
+ return trackedFor(fn, label).apply(this, args);
1150
+ };
1151
+ Object.defineProperty(wrapped, "name", { value: fn.name, configurable: true });
1152
+ Object.defineProperty(wrapped, "length", { value: fn.length, configurable: true });
1153
+ return wrapped;
1154
+ };
1155
+ return (target, context, descriptor) => {
1156
+ if (typeof target === "function" && context && typeof context === "object" && "kind" in context) {
1157
+ if (context.kind !== "method") {
1158
+ throw new TypeError("@traced can only decorate methods");
1159
+ }
1160
+ return wrapMethod(target, String(context.name));
1161
+ }
1162
+ if (descriptor && typeof descriptor.value === "function") {
1163
+ descriptor.value = wrapMethod(descriptor.value, String(context));
1164
+ return descriptor;
1165
+ }
1166
+ throw new TypeError("@traced can only decorate methods");
1167
+ };
1168
+ }
1169
+ /**
1170
+ * Start a manually-ended execution (a span), e.g. for a request:
1171
+ *
1172
+ * const span = tp.start('GET /users');
1173
+ * span.run(() => next()); // tracked calls inside become children
1174
+ * res.on('finish', () => span.end());
1175
+ */
1176
+ start(label, options = {}) {
1177
+ return this.executionTracker.startSpan(label, options);
1178
+ }
1179
+ /**
1180
+ * Register a plugin (exporter, custom sink). Returns an unsubscribe function.
1181
+ */
1182
+ use(plugin) {
1183
+ return this.executionTracker.use(plugin);
1184
+ }
1185
+ /**
1186
+ * Call `listener` with every finished top-level execution tree (even when
1187
+ * silent or below threshold). Returns an unsubscribe function.
1188
+ */
1189
+ onComplete(listener) {
1190
+ return this.use({ name: "onComplete", onComplete: listener });
1191
+ }
1192
+ /**
1193
+ * Call `listener` for every finished call (nested ones included) that
1194
+ * took at least `threshold` ms. Pass a number, or per-label thresholds
1195
+ * with an optional '*' default:
1196
+ *
1197
+ * tp.onSlow(200, (call, root) => logger.warn(`${call.label} took ${call.duration}ms in ${root.label}`));
1198
+ * tp.onSlow({ 'db.query': 50, 'GET /search': 500, '*': 1000 }, alert);
1199
+ *
1200
+ * Works in every tracking mode and when silent. Returns an unsubscribe function.
1201
+ */
1202
+ onSlow(threshold, listener) {
1203
+ const limitFor = typeof threshold === "number" ? () => threshold : (label) => label in threshold ? threshold[label] : threshold["*"];
1204
+ return this.use({
1205
+ name: "onSlow",
1206
+ onComplete: (root) => {
1207
+ (0, records_1.walkRecords)(root, (record) => {
1208
+ const limit = limitFor(record.label);
1209
+ if (limit !== void 0 && record.duration >= limit)
1210
+ listener(record, root);
1211
+ });
1212
+ }
1213
+ });
1214
+ }
1215
+ getStats(label) {
1216
+ const stats = this.executionTracker.stats;
1217
+ if (label !== void 0) {
1218
+ return stats ? stats.get(label) : void 0;
1219
+ }
1220
+ return stats ? stats.all() : {};
1221
+ }
1222
+ /** Clear collected statistics */
1223
+ resetStats() {
1224
+ if (this.executionTracker.stats) {
1225
+ this.executionTracker.stats.reset();
1226
+ }
1227
+ return this;
1228
+ }
1229
+ /** Statistics as a text table, slowest total first */
1230
+ formatStats() {
1231
+ return (0, stats_1.formatStatsTable)(this.getStats());
1232
+ }
1233
+ /** Print the statistics table to the console */
1234
+ printStats() {
1235
+ console.log(this.formatStats());
1236
+ return this;
1237
+ }
1238
+ /**
1239
+ * Start recording finished calls for a Chrome/Perfetto trace.
1240
+ *
1241
+ * const recording = tp.startTrace();
1242
+ * await work();
1243
+ * fs.writeFileSync('trace.json', JSON.stringify(recording.stop()));
1244
+ *
1245
+ * Open the file in https://ui.perfetto.dev or chrome://tracing.
1246
+ */
1247
+ startTrace(options = {}) {
1248
+ let unsubscribe = () => void 0;
1249
+ const recorder = (0, exporters_1.createTraceRecorder)({ maxRoots: options.maxRoots, onStop: () => unsubscribe() });
1250
+ unsubscribe = this.use(recorder);
1251
+ return recorder;
1252
+ }
1253
+ /** Turn tracking on */
1254
+ enable() {
1255
+ this.config.enabled = true;
1256
+ this.executionTracker.enabled = true;
1257
+ return this;
1258
+ }
1259
+ /** Turn tracking off: tracked functions become plain pass-through calls */
1260
+ disable() {
1261
+ this.config.enabled = false;
1262
+ this.executionTracker.enabled = false;
1263
+ return this;
1264
+ }
1265
+ /** Whether tracking is on */
1266
+ isEnabled() {
1267
+ return this.config.enabled;
1268
+ }
1269
+ /**
1270
+ * Set configuration options
1271
+ * @param config Configuration to update
1272
+ * @returns Current configuration after update
1273
+ */
1274
+ setConfig(config = {}) {
1275
+ if (config.trackingMode) {
1276
+ this.config.trackingMode = config.trackingMode;
1277
+ this.executionTracker.trackingMode = config.trackingMode;
1278
+ }
1279
+ if (config.silent !== void 0) {
1280
+ this.config.silent = config.silent;
1281
+ this.executionTracker.silent = config.silent;
1282
+ }
1283
+ if (config.trackMemory !== void 0) {
1284
+ this.config.trackMemory = config.trackMemory;
1285
+ this.executionTracker.showMemoryUsage = config.trackMemory;
1286
+ }
1287
+ if (config.enableNestedTracking !== void 0) {
1288
+ this.config.enableNestedTracking = config.enableNestedTracking;
1289
+ this.executionTracker.enableNestedTracking = config.enableNestedTracking;
1290
+ }
1291
+ if (config.threshold !== void 0) {
1292
+ this.config.threshold = config.threshold;
1293
+ this.executionTracker.defaultThreshold = config.threshold;
1294
+ }
1295
+ if (config.sampleRate !== void 0) {
1296
+ this.config.sampleRate = clampRate(config.sampleRate);
1297
+ this.executionTracker.defaultSampleRate = this.config.sampleRate;
1298
+ }
1299
+ if (config.enabled !== void 0) {
1300
+ this.config.enabled = config.enabled;
1301
+ this.executionTracker.enabled = config.enabled;
1302
+ }
1303
+ if (config.blockingThreshold !== void 0) {
1304
+ this.config.blockingThreshold = config.blockingThreshold;
1305
+ this.executionTracker.blockingThreshold = config.blockingThreshold;
1306
+ }
1307
+ if (config.reporter !== void 0) {
1308
+ this.executionTracker.reporter = config.reporter;
1309
+ }
1310
+ if (config.plugins) {
1311
+ config.plugins.forEach((plugin) => this.use(plugin));
1312
+ }
1313
+ if (config.onComplete) {
1314
+ this.onComplete(config.onComplete);
1315
+ }
1316
+ return { ...this.config };
1317
+ }
1318
+ /**
1319
+ * Enable silent mode (no console output)
1320
+ * @returns This instance for chaining
1321
+ */
1322
+ enableSilentMode() {
1323
+ this.config.silent = true;
1324
+ this.executionTracker.silent = true;
1325
+ return this;
1326
+ }
1327
+ /**
1328
+ * Disable silent mode (allow console output)
1329
+ * @returns This instance for chaining
1330
+ */
1331
+ disableSilentMode() {
1332
+ this.config.silent = false;
1333
+ this.executionTracker.silent = false;
1334
+ return this;
1335
+ }
1336
+ /**
1337
+ * Set the tracking mode
1338
+ * @param mode Tracking mode from TrackingMode enum
1339
+ * @returns This instance for chaining
1340
+ */
1341
+ setTrackingMode(mode) {
1342
+ this.config.trackingMode = mode;
1343
+ this.executionTracker.trackingMode = mode;
1344
+ return this;
1345
+ }
1346
+ /**
1347
+ * Get the current tracking mode
1348
+ */
1349
+ getTrackingMode() {
1350
+ return this.config.trackingMode;
1351
+ }
1352
+ /**
1353
+ * Enable memory usage tracking
1354
+ * @returns This instance for chaining
1355
+ */
1356
+ enableMemoryTracking() {
1357
+ this.config.trackMemory = true;
1358
+ this.executionTracker.showMemoryUsage = true;
1359
+ return this;
1360
+ }
1361
+ /**
1362
+ * Disable memory usage tracking
1363
+ * @returns This instance for chaining
1364
+ */
1365
+ disableMemoryTracking() {
1366
+ this.config.trackMemory = false;
1367
+ this.executionTracker.showMemoryUsage = false;
1368
+ return this;
1369
+ }
1370
+ /**
1371
+ * Set the sampling rate
1372
+ * @param rate Sampling rate between 0.0 and 1.0
1373
+ * @returns This instance for chaining
1374
+ */
1375
+ setSampleRate(rate) {
1376
+ this.config.sampleRate = clampRate(rate);
1377
+ this.executionTracker.defaultSampleRate = this.config.sampleRate;
1378
+ return this;
1379
+ }
1380
+ /**
1381
+ * Reset the tracker state (in-flight executions and statistics)
1382
+ * @returns This instance for chaining
1383
+ */
1384
+ reset() {
1385
+ this.executionTracker.reset();
1386
+ return this;
1387
+ }
1388
+ };
1389
+ exports.OptimizedPerformanceMonitor = OptimizedPerformanceMonitor;
1390
+ }
1391
+ });
1392
+
1393
+ // dist/core/timeline.js
1394
+ var require_timeline = __commonJS({
1395
+ "dist/core/timeline.js"(exports) {
1396
+ "use strict";
1397
+ Object.defineProperty(exports, "__esModule", { value: true });
1398
+ exports.performanceTimeline = performanceTimeline;
1399
+ var records_1 = require_records();
1400
+ function performanceTimeline(options = {}) {
1401
+ var _a;
1402
+ const perf = typeof performance !== "undefined" ? performance : void 0;
1403
+ const supported = !!perf && typeof perf.measure === "function";
1404
+ const track = (_a = options.track) !== null && _a !== void 0 ? _a : "traceperf";
1405
+ return {
1406
+ name: "performance-timeline",
1407
+ onComplete(root) {
1408
+ if (!supported)
1409
+ return;
1410
+ (0, records_1.walkRecords)(root, (record) => {
1411
+ const failed = record.error !== void 0 && record.error !== null;
1412
+ const properties = [
1413
+ ["duration", `${record.duration.toFixed(3)} ms`],
1414
+ ["self", `${record.selfDuration.toFixed(3)} ms`]
1415
+ ];
1416
+ if (record.async)
1417
+ properties.push(["sync", `${record.syncDuration.toFixed(3)} ms`]);
1418
+ if (record.memoryDelta !== void 0)
1419
+ properties.push(["heap \u0394", `${(record.memoryDelta / 1024).toFixed(2)} KB`]);
1420
+ if (failed)
1421
+ properties.push(["error", record.error instanceof Error ? record.error.message : String(record.error)]);
1422
+ try {
1423
+ perf.measure(record.label, {
1424
+ start: record.startTime,
1425
+ duration: record.duration,
1426
+ detail: {
1427
+ devtools: {
1428
+ dataType: "track-entry",
1429
+ track,
1430
+ ...options.trackGroup ? { trackGroup: options.trackGroup } : {},
1431
+ color: failed ? "error" : "primary",
1432
+ properties,
1433
+ tooltipText: `${record.label}: ${record.duration.toFixed(2)} ms`
1434
+ }
1435
+ }
1436
+ });
1437
+ if (!options.keep && typeof perf.clearMeasures === "function")
1438
+ perf.clearMeasures(record.label);
1439
+ } catch (_a2) {
1440
+ }
1441
+ });
1442
+ }
1443
+ };
1444
+ }
1445
+ }
1446
+ });
1447
+
1448
+ // dist/instrument.js
1449
+ var require_instrument = __commonJS({
1450
+ "dist/instrument.js"(exports) {
1451
+ "use strict";
1452
+ Object.defineProperty(exports, "__esModule", { value: true });
1453
+ exports.instrumentFetch = instrumentFetch;
1454
+ exports.instrumentHttp = instrumentHttp;
1455
+ exports.instrumentMethods = instrumentMethods;
1456
+ exports.prismaExtension = prismaExtension;
1457
+ exports.normalizePath = normalizePath;
1458
+ exports.instrumentHttpServer = instrumentHttpServer;
1459
+ var env_1 = require_env();
1460
+ var PATCHED = /* @__PURE__ */ Symbol.for("traceperf.instrumented");
1461
+ function describeUrl(input) {
1462
+ try {
1463
+ if (typeof input === "string" || input instanceof URL) {
1464
+ const url = new URL(String(input), "http://localhost");
1465
+ return { host: url.host, path: url.pathname };
1466
+ }
1467
+ if (input && typeof input.url === "string") {
1468
+ const url = new URL(input.url, "http://localhost");
1469
+ return { method: input.method, host: url.host, path: url.pathname };
1470
+ }
1471
+ } catch (_a) {
1472
+ }
1473
+ return { host: "unknown", path: "" };
1474
+ }
1475
+ function instrumentFetch(tp, options = {}) {
1476
+ const g = typeof globalThis !== "undefined" ? globalThis : void 0;
1477
+ if (!g || typeof g.fetch !== "function")
1478
+ return () => void 0;
1479
+ if (g.fetch[PATCHED])
1480
+ return () => void 0;
1481
+ const { errorStatus = 500, ...trackOptions } = options;
1482
+ const original = g.fetch;
1483
+ const patched = function fetch(input, init) {
1484
+ const { method: inputMethod, host, path } = describeUrl(input);
1485
+ const method = init && init.method || inputMethod || "GET";
1486
+ const span = tp.start(`fetch ${method.toUpperCase()} ${host}${path}`, trackOptions);
1487
+ let promise;
1488
+ try {
1489
+ promise = span.run(() => original.call(this, input, init));
1490
+ } catch (error) {
1491
+ span.end(error);
1492
+ throw error;
1493
+ }
1494
+ return Promise.resolve(promise).then((response) => {
1495
+ span.end(response && response.status >= errorStatus ? new Error(`HTTP ${response.status}`) : void 0);
1496
+ return response;
1497
+ }, (error) => {
1498
+ span.end(error);
1499
+ throw error;
1500
+ });
1501
+ };
1502
+ patched[PATCHED] = original;
1503
+ g.fetch = patched;
1504
+ return () => {
1505
+ if (g.fetch === patched)
1506
+ g.fetch = original;
1507
+ };
1508
+ }
1509
+ function instrumentHttp(tp, options = {}) {
1510
+ const { errorStatus = 500, ...trackOptions } = options;
1511
+ const restores = [];
1512
+ for (const moduleName of ["http", "https"]) {
1513
+ const mod = (0, env_1.loadNodeBuiltin)(moduleName);
1514
+ if (!mod)
1515
+ continue;
1516
+ for (const fnName of ["request", "get"]) {
1517
+ const original = mod[fnName];
1518
+ if (typeof original !== "function" || original[PATCHED])
1519
+ continue;
1520
+ const patched = function(...args) {
1521
+ const span = tp.start(`${moduleName} request`, trackOptions);
1522
+ let req;
1523
+ try {
1524
+ req = span.run(() => original.apply(this, args));
1525
+ } catch (error) {
1526
+ span.end(error);
1527
+ throw error;
1528
+ }
1529
+ const host = typeof req.getHeader === "function" && req.getHeader("host") || req.host || "unknown";
1530
+ span.setLabel(`${moduleName} ${req.method || "GET"} ${host}${String(req.path || "").split("?")[0]}`);
1531
+ let ended = false;
1532
+ let statusError;
1533
+ const end = (error = statusError) => {
1534
+ if (ended)
1535
+ return;
1536
+ ended = true;
1537
+ span.end(error);
1538
+ };
1539
+ req.once("response", (res) => {
1540
+ statusError = res.statusCode >= errorStatus ? new Error(`HTTP ${res.statusCode}`) : void 0;
1541
+ res.once("end", () => end());
1542
+ res.once("close", () => end());
1543
+ });
1544
+ req.once("error", (error) => end(error));
1545
+ req.once("close", () => end());
1546
+ return req;
1547
+ };
1548
+ patched[PATCHED] = original;
1549
+ mod[fnName] = patched;
1550
+ restores.push(() => {
1551
+ if (mod[fnName] === patched)
1552
+ mod[fnName] = original;
1553
+ });
1554
+ }
1555
+ }
1556
+ return () => restores.forEach((restore) => restore());
1557
+ }
1558
+ function instrumentMethods(tp, target, methods, options = {}) {
1559
+ const { prefix, labelFor, ...trackOptions } = options;
1560
+ const ctor = target.constructor;
1561
+ const ownerName = typeof target === "function" ? target.name : ctor && ctor.prototype === target ? ctor.name : ctor && ctor !== Object ? ctor.name : "";
1562
+ const labelPrefix = prefix !== null && prefix !== void 0 ? prefix : ownerName ? `${ownerName}.` : "";
1563
+ const names = methods !== null && methods !== void 0 ? methods : Object.getOwnPropertyNames(target).filter((name) => {
1564
+ if (name === "constructor")
1565
+ return false;
1566
+ const descriptor = Object.getOwnPropertyDescriptor(target, name);
1567
+ return !!descriptor && typeof descriptor.value === "function";
1568
+ });
1569
+ const restores = [];
1570
+ for (const name of names) {
1571
+ const original = target[name];
1572
+ if (typeof original !== "function" || original[PATCHED])
1573
+ continue;
1574
+ const patched = function(...args) {
1575
+ const label = labelFor ? labelFor(name, args) : `${labelPrefix}${name}`;
1576
+ return tp.track(() => original.apply(this, args), { ...trackOptions, label });
1577
+ };
1578
+ Object.defineProperty(patched, "name", { value: original.name, configurable: true });
1579
+ Object.defineProperty(patched, "length", { value: original.length, configurable: true });
1580
+ patched[PATCHED] = original;
1581
+ const hadOwn = Object.prototype.hasOwnProperty.call(target, name);
1582
+ target[name] = patched;
1583
+ restores.push(() => {
1584
+ if (target[name] !== patched)
1585
+ return;
1586
+ if (hadOwn)
1587
+ target[name] = original;
1588
+ else
1589
+ delete target[name];
1590
+ });
1591
+ }
1592
+ return () => restores.forEach((restore) => restore());
1593
+ }
1594
+ function prismaExtension(tp, options = {}) {
1595
+ return {
1596
+ name: "traceperf",
1597
+ query: {
1598
+ $allModels: {
1599
+ $allOperations(params) {
1600
+ var _a, _b;
1601
+ const label = (_a = options.label) !== null && _a !== void 0 ? _a : `prisma.${(_b = params.model) !== null && _b !== void 0 ? _b : "raw"}.${params.operation}`;
1602
+ return tp.track(() => params.query(params.args), { ...options, label });
1603
+ }
1604
+ }
1605
+ }
1606
+ };
1607
+ }
1608
+ function normalizePath(url) {
1609
+ let path = String(url || "/");
1610
+ const q = path.search(/[?#]/);
1611
+ if (q !== -1)
1612
+ path = path.slice(0, q);
1613
+ if (!path)
1614
+ return "/";
1615
+ if (!/\d/.test(path))
1616
+ return path;
1617
+ const segments = path.split("/");
1618
+ for (let i = 0; i < segments.length; i++) {
1619
+ const seg = segments[i];
1620
+ if (seg && /\d/.test(seg) && isIdSegment(seg))
1621
+ segments[i] = ":id";
1622
+ }
1623
+ return segments.join("/");
1624
+ }
1625
+ var UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
1626
+ function isIdSegment(seg) {
1627
+ if (/^\d+$/.test(seg))
1628
+ return true;
1629
+ if (seg.length === 36 && UUID.test(seg))
1630
+ return true;
1631
+ if (seg.length >= 16 && /^[0-9a-f]+$/i.test(seg))
1632
+ return true;
1633
+ return seg.length >= 20 && /^[A-Za-z0-9_-]+$/.test(seg);
1634
+ }
1635
+ function instrumentHttpServer(tp, options = {}) {
1636
+ const { errorStatus = 500, labelFor, ignore, ...trackOptions } = options;
1637
+ const restores = [];
1638
+ for (const moduleName of ["http", "https"]) {
1639
+ const mod = (0, env_1.loadNodeBuiltin)(moduleName);
1640
+ const proto = mod && mod.Server && mod.Server.prototype;
1641
+ if (!proto)
1642
+ continue;
1643
+ const original = proto.emit;
1644
+ if (typeof original !== "function" || original[PATCHED])
1645
+ continue;
1646
+ const hadOwn = Object.prototype.hasOwnProperty.call(proto, "emit");
1647
+ const patched = function(event, req, res, ...rest) {
1648
+ if (event !== "request" || !req || !res || typeof res.once !== "function" || ignore && ignore(req)) {
1649
+ return original.call(this, event, req, res, ...rest);
1650
+ }
1651
+ const label = labelFor ? labelFor(req) : `${req.method || "GET"} ${normalizePath(req.url)}`;
1652
+ const span = tp.start(label, trackOptions);
1653
+ if (!span.id)
1654
+ return original.call(this, event, req, res, ...rest);
1655
+ let ended = false;
1656
+ const end = (error) => {
1657
+ if (ended)
1658
+ return;
1659
+ ended = true;
1660
+ span.end(error);
1661
+ };
1662
+ res.once("finish", () => end(res.statusCode >= errorStatus ? new Error(`HTTP ${res.statusCode}`) : void 0));
1663
+ res.once("close", () => end(res.writableFinished ? void 0 : new Error("connection closed before the response was sent")));
1664
+ try {
1665
+ return span.run(() => original.call(this, event, req, res, ...rest));
1666
+ } catch (error) {
1667
+ end(error);
1668
+ throw error;
1669
+ }
1670
+ };
1671
+ patched[PATCHED] = original;
1672
+ proto.emit = patched;
1673
+ restores.push(() => {
1674
+ if (proto.emit !== patched)
1675
+ return;
1676
+ if (hadOwn)
1677
+ proto.emit = original;
1678
+ else
1679
+ delete proto.emit;
1680
+ });
1681
+ }
1682
+ return () => restores.forEach((restore) => restore());
1683
+ }
1684
+ }
1685
+ });
1686
+
1687
+ // dist/browser.js
1688
+ var require_browser = __commonJS({
1689
+ "dist/browser.js"(exports, module) {
1690
+ Object.defineProperty(exports, "__esModule", { value: true });
1691
+ exports.instrumentFetch = exports.formatTree = exports.recordToJSON = exports.openTelemetryExporter = exports.jsonLinesExporter = exports.toChromeTrace = exports.performanceTimeline = exports.BrowserLogger = exports.TrackingMode = void 0;
1692
+ exports.createBrowserLogger = createBrowserLogger;
1693
+ exports.createTracePerf = createTracePerf;
1694
+ var optimized_performance_monitor_1 = require_optimized_performance_monitor();
1695
+ exports.TrackingMode = optimized_performance_monitor_1.TrackingModes;
1696
+ var preserveSignature = (wrapper, fn) => {
1697
+ Object.defineProperty(wrapper, "name", { value: fn.name, configurable: true });
1698
+ Object.defineProperty(wrapper, "length", { value: fn.length, configurable: true });
1699
+ };
1700
+ var BrowserLogger = class extends optimized_performance_monitor_1.OptimizedPerformanceMonitor {
1701
+ constructor(config = {}) {
1702
+ super({
1703
+ trackingMode: config.trackingMode,
1704
+ silent: config.silent,
1705
+ trackMemory: config.trackMemory,
1706
+ enableNestedTracking: config.enableNestedTracking,
1707
+ threshold: config.threshold,
1708
+ sampleRate: config.sampleRate,
1709
+ enabled: config.enabled,
1710
+ blockingThreshold: config.blockingThreshold,
1711
+ stats: config.stats,
1712
+ plugins: config.plugins,
1713
+ onComplete: config.onComplete,
1714
+ reporter: config.reporter,
1715
+ asyncLocalStorage: config.asyncLocalStorage
1716
+ });
1717
+ this._mode = "dev";
1718
+ this._indentLevel = 0;
1719
+ this._mode = config.mode || "dev";
1720
+ this._slowThreshold = config.performanceThreshold || 100;
1721
+ if (!config.reporter) {
1722
+ this.setConfig({ reporter: (root) => console.log(this.formatFlow(root)) });
1723
+ }
1724
+ }
1725
+ /**
1726
+ * Render an execution tree in the browser output format
1727
+ */
1728
+ formatFlow(root) {
1729
+ const lines = ["Execution Flow:"];
1730
+ const visit = (record, level) => {
1731
+ const indent = " ".repeat(level);
1732
+ const slowThreshold = record.threshold > 0 ? record.threshold : this._slowThreshold;
1733
+ const isSlow = record.duration > slowThreshold;
1734
+ const memory = record.memoryDelta !== void 0 && record.memoryDelta > 0 ? ` [${formatMemorySize(record.memoryDelta)}]` : "";
1735
+ lines.push(`${indent}\u2192 ${record.label} (${record.duration.toFixed(2)}ms)${isSlow ? " [SLOW]" : ""}${memory}`);
1736
+ const suggestion = isSlow ? slowSuggestion(record.label, record.duration) : "";
1737
+ if (suggestion) {
1738
+ lines.push(`${indent} \u26A0\uFE0F ${suggestion}`);
1739
+ }
1740
+ record.children.filter((child) => child.duration >= child.threshold).forEach((child) => visit(child, level + 1));
1741
+ };
1742
+ visit(root, 0);
1743
+ return lines.join("\n");
1744
+ }
1745
+ info(message, ...args) {
1746
+ this.log("info", message, args);
1747
+ }
1748
+ warn(message, ...args) {
1749
+ this.log("warn", message, args);
1750
+ }
1751
+ error(message, ...args) {
1752
+ this.log("error", message, args);
1753
+ }
1754
+ debug(message, ...args) {
1755
+ if (this._mode === "prod") {
1756
+ return;
1757
+ }
1758
+ this.log("debug", message, args);
1759
+ }
1760
+ group(label) {
1761
+ this.info(label);
1762
+ this._indentLevel++;
1763
+ if (typeof console.group === "function") {
1764
+ console.group(label);
1765
+ }
1766
+ }
1767
+ groupEnd() {
1768
+ if (this._indentLevel > 0) {
1769
+ this._indentLevel--;
1770
+ }
1771
+ if (typeof console.groupEnd === "function") {
1772
+ console.groupEnd();
1773
+ }
1774
+ }
1775
+ setMode(mode) {
1776
+ this._mode = mode;
1777
+ }
1778
+ getMode() {
1779
+ return this._mode;
1780
+ }
1781
+ /**
1782
+ * Set the tracking mode
1783
+ * @param mode Tracking mode from TrackingMode enum
1784
+ * @returns This instance for chaining
1785
+ */
1786
+ setTrackingMode(mode) {
1787
+ super.setTrackingMode(mode);
1788
+ return this;
1789
+ }
1790
+ /**
1791
+ * Create a trackable version of a function. Calls go through `track()`,
1792
+ * so nested trackables attach to their caller.
1793
+ */
1794
+ createTrackable(fn, options = {}) {
1795
+ const label = options.label || fn.name || "anonymous";
1796
+ const run = (thisArg, args) => this.track(() => fn.apply(thisArg, args), {
1797
+ ...options,
1798
+ label
1799
+ });
1800
+ const tracked = function(...args) {
1801
+ return run(this, args);
1802
+ };
1803
+ preserveSignature(tracked, fn);
1804
+ return tracked;
1805
+ }
1806
+ log(level, message, args) {
1807
+ if (this._mode === "prod" && level !== "error") {
1808
+ return;
1809
+ }
1810
+ if (this._mode === "staging" && (level === "debug" || level === "info")) {
1811
+ return;
1812
+ }
1813
+ let formattedMessage;
1814
+ if (typeof message === "string") {
1815
+ formattedMessage = message;
1816
+ } else {
1817
+ try {
1818
+ formattedMessage = JSON.stringify(message, null, 2);
1819
+ } catch (_a) {
1820
+ formattedMessage = String(message);
1821
+ }
1822
+ }
1823
+ const indent = " ".repeat(this._indentLevel);
1824
+ formattedMessage = `${indent}${formattedMessage}`;
1825
+ switch (level) {
1826
+ case "info":
1827
+ console.info(formattedMessage, ...args);
1828
+ break;
1829
+ case "warn":
1830
+ console.warn(formattedMessage, ...args);
1831
+ break;
1832
+ case "error":
1833
+ console.error(formattedMessage, ...args);
1834
+ break;
1835
+ case "debug":
1836
+ console.debug(formattedMessage, ...args);
1837
+ break;
1838
+ }
1839
+ }
1840
+ };
1841
+ exports.BrowserLogger = BrowserLogger;
1842
+ function formatMemorySize(bytes) {
1843
+ if (bytes < 1024) {
1844
+ return `${bytes.toFixed(2)}B`;
1845
+ } else if (bytes < 1024 * 1024) {
1846
+ return `${(bytes / 1024).toFixed(2)}KB`;
1847
+ } else if (bytes < 1024 * 1024 * 1024) {
1848
+ return `${(bytes / (1024 * 1024)).toFixed(2)}MB`;
1849
+ }
1850
+ return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)}GB`;
1851
+ }
1852
+ function slowSuggestion(name, duration) {
1853
+ if (duration > 500) {
1854
+ return `Function "${name}" took ${duration.toFixed(2)}ms to execute. Consider optimizing or breaking it down into smaller functions.`;
1855
+ } else if (duration > 200) {
1856
+ return `Function "${name}" took ${duration.toFixed(2)}ms to execute. Consider optimizing if called frequently.`;
1857
+ } else if (duration > 100) {
1858
+ return `Function "${name}" took ${duration.toFixed(2)}ms to execute. Monitor if called in critical paths.`;
1859
+ }
1860
+ return "";
1861
+ }
1862
+ function createBrowserLogger(config = {}) {
1863
+ if (config.logger instanceof BrowserLogger) {
1864
+ return config.logger;
1865
+ }
1866
+ return new BrowserLogger(config);
1867
+ }
1868
+ function createTracePerf(config = {}) {
1869
+ return createBrowserLogger(config);
1870
+ }
1871
+ var browserLogger = createBrowserLogger();
1872
+ exports.default = browserLogger;
1873
+ var timeline_1 = require_timeline();
1874
+ Object.defineProperty(exports, "performanceTimeline", { enumerable: true, get: function() {
1875
+ return timeline_1.performanceTimeline;
1876
+ } });
1877
+ var exporters_1 = require_exporters();
1878
+ Object.defineProperty(exports, "toChromeTrace", { enumerable: true, get: function() {
1879
+ return exporters_1.toChromeTrace;
1880
+ } });
1881
+ Object.defineProperty(exports, "jsonLinesExporter", { enumerable: true, get: function() {
1882
+ return exporters_1.jsonLinesExporter;
1883
+ } });
1884
+ Object.defineProperty(exports, "openTelemetryExporter", { enumerable: true, get: function() {
1885
+ return exporters_1.openTelemetryExporter;
1886
+ } });
1887
+ Object.defineProperty(exports, "recordToJSON", { enumerable: true, get: function() {
1888
+ return exporters_1.recordToJSON;
1889
+ } });
1890
+ var records_1 = require_records();
1891
+ Object.defineProperty(exports, "formatTree", { enumerable: true, get: function() {
1892
+ return records_1.formatTree;
1893
+ } });
1894
+ var instrument_1 = require_instrument();
1895
+ Object.defineProperty(exports, "instrumentFetch", { enumerable: true, get: function() {
1896
+ return instrument_1.instrumentFetch;
1897
+ } });
1898
+ if (typeof module !== "undefined" && module.exports) {
1899
+ module.exports = Object.assign(browserLogger, module.exports, {
1900
+ default: browserLogger,
1901
+ createBrowserLogger,
1902
+ createTracePerf,
1903
+ BrowserLogger,
1904
+ TrackingMode: exports.TrackingMode
1905
+ });
1906
+ }
1907
+ }
1908
+ });
1909
+ return require_browser();
1910
+ })();