@ooopsstudio/performance 0.9.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 (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +50 -0
  3. package/dist/budget-engine-KDA4FRYU.js +160 -0
  4. package/dist/budget-engine-KDA4FRYU.js.map +1 -0
  5. package/dist/chunk-2XXIOHOO.js +58 -0
  6. package/dist/chunk-2XXIOHOO.js.map +1 -0
  7. package/dist/chunk-3GMKPRQP.js +197 -0
  8. package/dist/chunk-3GMKPRQP.js.map +1 -0
  9. package/dist/chunk-J6KBSLYO.js +118 -0
  10. package/dist/chunk-J6KBSLYO.js.map +1 -0
  11. package/dist/chunk-MMO5UEUU.js +20 -0
  12. package/dist/chunk-MMO5UEUU.js.map +1 -0
  13. package/dist/chunk-RL2752FW.js +31 -0
  14. package/dist/chunk-RL2752FW.js.map +1 -0
  15. package/dist/chunk-RY65GERM.js +159 -0
  16. package/dist/chunk-RY65GERM.js.map +1 -0
  17. package/dist/chunk-W72QW2AD.js +29 -0
  18. package/dist/chunk-W72QW2AD.js.map +1 -0
  19. package/dist/chunk-ZAXGEDZW.js +1184 -0
  20. package/dist/chunk-ZAXGEDZW.js.map +1 -0
  21. package/dist/custom/exporters/http.d.ts +11 -0
  22. package/dist/custom/exporters/http.js +364 -0
  23. package/dist/custom/exporters/http.js.map +1 -0
  24. package/dist/custom/exporters/raw.d.ts +8 -0
  25. package/dist/custom/exporters/raw.js +6 -0
  26. package/dist/custom/exporters/raw.js.map +1 -0
  27. package/dist/custom.d.ts +58 -0
  28. package/dist/custom.js +299 -0
  29. package/dist/custom.js.map +1 -0
  30. package/dist/development.d.ts +19 -0
  31. package/dist/development.js +55 -0
  32. package/dist/development.js.map +1 -0
  33. package/dist/event-export-manager-DEB64LWZ.js +632 -0
  34. package/dist/event-export-manager-DEB64LWZ.js.map +1 -0
  35. package/dist/index.d.ts +26 -0
  36. package/dist/index.js +205 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/monitors-VNNUIKAK.js +753 -0
  39. package/dist/monitors-VNNUIKAK.js.map +1 -0
  40. package/dist/n1-detector-6IQ2DINP.js +247 -0
  41. package/dist/n1-detector-6IQ2DINP.js.map +1 -0
  42. package/dist/observability.d.ts +32 -0
  43. package/dist/observability.js +76 -0
  44. package/dist/observability.js.map +1 -0
  45. package/dist/ports-DwUYdKj-.d.ts +23 -0
  46. package/dist/production.d.ts +19 -0
  47. package/dist/production.js +42 -0
  48. package/dist/production.js.map +1 -0
  49. package/dist/public/types.d.ts +11 -0
  50. package/dist/public/types.js +3 -0
  51. package/dist/public/types.js.map +1 -0
  52. package/package.json +74 -0
@@ -0,0 +1,753 @@
1
+ import { createPerformanceOnError, nsToMs } from './chunk-RY65GERM.js';
2
+ import './chunk-RL2752FW.js';
3
+
4
+ // src/performance/features/core/event-loop-monitor.ts
5
+ function createEventLoopMonitor(options) {
6
+ const {
7
+ clock,
8
+ intervalMs = 1e3,
9
+ onSaturationAlert,
10
+ onPerfEvent,
11
+ thresholds = {}
12
+ } = options;
13
+ if (!Number.isSafeInteger(intervalMs) || intervalMs <= 0 || intervalMs > 2147483647) {
14
+ throw new Error("Event loop intervalMs must be between 1 and 2147483647");
15
+ }
16
+ const configuredThresholds = [thresholds.info, thresholds.warn, thresholds.critical].filter((value) => value !== void 0);
17
+ if (!configuredThresholds.every((value) => Number.isFinite(value) && value >= 0)) {
18
+ throw new Error("Event loop monitor thresholds must be non-negative finite numbers");
19
+ }
20
+ if (thresholds.info !== void 0 && thresholds.warn !== void 0 && thresholds.info > thresholds.warn || thresholds.warn !== void 0 && thresholds.critical !== void 0 && thresholds.warn > thresholds.critical || thresholds.info !== void 0 && thresholds.critical !== void 0 && thresholds.info > thresholds.critical) {
21
+ throw new Error("Event loop monitor thresholds must satisfy info <= warn <= critical");
22
+ }
23
+ const criticalThreshold = thresholds.critical ?? Math.max(100, thresholds.warn ?? thresholds.info ?? 0);
24
+ const warnThreshold = thresholds.warn ?? Math.min(Math.max(50, thresholds.info ?? 0), criticalThreshold);
25
+ const infoThreshold = thresholds.info ?? Math.min(20, warnThreshold);
26
+ let timeoutId = null;
27
+ let immediateId = null;
28
+ let running = false;
29
+ const lagSamples = [];
30
+ let currentLag = null;
31
+ const scheduleNext = () => {
32
+ if (!running) return;
33
+ running = false;
34
+ try {
35
+ timeoutId = setTimeout(scheduleMeasurement, intervalMs);
36
+ running = true;
37
+ timeoutId.unref?.();
38
+ } catch {
39
+ }
40
+ };
41
+ function measureLag() {
42
+ let scheduled;
43
+ try {
44
+ scheduled = clock.nowHr();
45
+ } catch {
46
+ scheduleNext();
47
+ return;
48
+ }
49
+ try {
50
+ immediateId = setImmediate(() => {
51
+ immediateId = null;
52
+ if (!running) {
53
+ return;
54
+ }
55
+ let executed;
56
+ try {
57
+ executed = clock.nowHr();
58
+ } catch {
59
+ scheduleNext();
60
+ return;
61
+ }
62
+ const lagMs = nsToMs(executed - scheduled);
63
+ if (!Number.isFinite(lagMs) || lagMs < 0) {
64
+ scheduleNext();
65
+ return;
66
+ }
67
+ currentLag = lagMs;
68
+ lagSamples.push(lagMs);
69
+ if (lagSamples.length > 100) {
70
+ lagSamples.shift();
71
+ }
72
+ if (onPerfEvent) {
73
+ try {
74
+ const end = clock.now();
75
+ onPerfEvent({
76
+ name: "event_loop_lag",
77
+ duration: lagMs,
78
+ start: end - lagMs,
79
+ end,
80
+ source: "runtime"
81
+ });
82
+ } catch {
83
+ }
84
+ }
85
+ if (onSaturationAlert) {
86
+ let severity = null;
87
+ let threshold = 0;
88
+ if (lagMs >= criticalThreshold) {
89
+ severity = "critical";
90
+ threshold = criticalThreshold;
91
+ } else if (lagMs >= warnThreshold) {
92
+ severity = "warn";
93
+ threshold = warnThreshold;
94
+ } else if (lagMs >= infoThreshold) {
95
+ severity = "info";
96
+ threshold = infoThreshold;
97
+ }
98
+ if (severity) {
99
+ try {
100
+ onSaturationAlert({
101
+ reason: "event_loop_lag",
102
+ severity,
103
+ value: lagMs,
104
+ threshold
105
+ });
106
+ } catch {
107
+ }
108
+ }
109
+ }
110
+ scheduleNext();
111
+ });
112
+ } catch {
113
+ running = false;
114
+ }
115
+ }
116
+ function scheduleMeasurement() {
117
+ if (!running) {
118
+ return;
119
+ }
120
+ measureLag();
121
+ }
122
+ function calculatePercentiles(sorted, percentile) {
123
+ if (sorted.length === 0) {
124
+ return 0;
125
+ }
126
+ const index = Math.ceil(percentile / 100 * sorted.length) - 1;
127
+ return sorted[Math.max(0, index)] ?? 0;
128
+ }
129
+ return {
130
+ start() {
131
+ if (running) {
132
+ return;
133
+ }
134
+ running = true;
135
+ scheduleMeasurement();
136
+ },
137
+ stop() {
138
+ running = false;
139
+ if (timeoutId !== null) {
140
+ clearTimeout(timeoutId);
141
+ timeoutId = null;
142
+ }
143
+ if (immediateId !== null) {
144
+ clearImmediate(immediateId);
145
+ immediateId = null;
146
+ }
147
+ },
148
+ getStats() {
149
+ if (lagSamples.length === 0) {
150
+ return null;
151
+ }
152
+ const sorted = [...lagSamples].sort((a, b) => a - b);
153
+ const mean = sorted.reduce((sum, val) => sum + val, 0) / sorted.length;
154
+ return {
155
+ mean,
156
+ p95: calculatePercentiles(sorted, 95),
157
+ p99: calculatePercentiles(sorted, 99),
158
+ max: sorted[sorted.length - 1] ?? 0,
159
+ sampleCount: sorted.length
160
+ };
161
+ },
162
+ getCurrentLag() {
163
+ return currentLag;
164
+ }
165
+ };
166
+ }
167
+
168
+ // src/performance/features/core/gc-monitor.ts
169
+ var perfHooksModuleCache = null;
170
+ var perfHooksLoadingPromise = null;
171
+ var MAX_GC_ENTRIES_PER_CALLBACK = 256;
172
+ function createGCMonitor(options) {
173
+ const {
174
+ clock,
175
+ errors,
176
+ onSaturationAlert,
177
+ onPerfEvent,
178
+ thresholds = {}
179
+ } = options;
180
+ const onError = createPerformanceOnError(errors, {
181
+ operation: "module-load",
182
+ monitor: "gc-monitor"
183
+ });
184
+ let perfHooks = null;
185
+ if (perfHooksModuleCache && perfHooksModuleCache.PerformanceObserver) {
186
+ const Observer = perfHooksModuleCache.PerformanceObserver;
187
+ perfHooks = {
188
+ PerformanceObserver: Observer
189
+ };
190
+ } else {
191
+ if (!perfHooksLoadingPromise) {
192
+ perfHooksLoadingPromise = import('perf_hooks').then((module) => {
193
+ perfHooksModuleCache = module;
194
+ }).catch((error) => {
195
+ perfHooksModuleCache = null;
196
+ perfHooksLoadingPromise = null;
197
+ onError(error, { module: "perf_hooks" });
198
+ });
199
+ }
200
+ }
201
+ const pauseTimeThresholds = { ...thresholds.pauseTime ?? {} };
202
+ const heapUsageThresholds = { ...thresholds.heapUsage ?? {} };
203
+ validatePair(pauseTimeThresholds, "GC pause-time");
204
+ validatePair(heapUsageThresholds, "GC heap-usage", 1);
205
+ let majorCount = 0;
206
+ let minorCount = 0;
207
+ const pauseTimes = [];
208
+ let observer = null;
209
+ let heapCheckIntervalId = null;
210
+ let running = false;
211
+ function startObserver() {
212
+ if (!perfHooks || observer || !running) {
213
+ return;
214
+ }
215
+ let candidate = null;
216
+ try {
217
+ candidate = new perfHooks.PerformanceObserver((list) => {
218
+ try {
219
+ let processed = 0;
220
+ for (const entry of list.getEntries()) {
221
+ if (processed >= MAX_GC_ENTRIES_PER_CALLBACK) {
222
+ onError(new Error("GC observer callback entry limit exceeded"), {
223
+ operation: "gc-monitor.entry-limit"
224
+ });
225
+ break;
226
+ }
227
+ processed += 1;
228
+ if (entry.entryType === "gc") {
229
+ handleGCEvent(entry.detail?.kind ?? 2, entry.duration);
230
+ }
231
+ }
232
+ } catch (error) {
233
+ onError(error, { operation: "gc-monitor.observer" });
234
+ }
235
+ });
236
+ candidate.observe({ entryTypes: ["gc"] });
237
+ observer = candidate;
238
+ heapCheckIntervalId = setInterval(safeCheckHeapUsage, 5e3);
239
+ heapCheckIntervalId.unref?.();
240
+ } catch (error) {
241
+ const partialObserver = candidate;
242
+ candidate = null;
243
+ observer = null;
244
+ if (heapCheckIntervalId !== null) {
245
+ clearInterval(heapCheckIntervalId);
246
+ heapCheckIntervalId = null;
247
+ }
248
+ try {
249
+ partialObserver?.disconnect();
250
+ } catch (cleanupError) {
251
+ onError(cleanupError, { operation: "gc-monitor.start-cleanup" });
252
+ }
253
+ running = false;
254
+ onError(error, { operation: "gc-monitor.start" });
255
+ }
256
+ }
257
+ if (!perfHooks && perfHooksLoadingPromise) {
258
+ void perfHooksLoadingPromise.then(() => {
259
+ if (!perfHooksModuleCache?.PerformanceObserver) {
260
+ return;
261
+ }
262
+ perfHooks = { PerformanceObserver: perfHooksModuleCache.PerformanceObserver };
263
+ startObserver();
264
+ });
265
+ }
266
+ function handleGCEvent(kind, pauseTimeMs) {
267
+ if (!running) {
268
+ return;
269
+ }
270
+ if (!Number.isFinite(pauseTimeMs) || pauseTimeMs < 0) {
271
+ onError(new Error("GC pause duration must be a non-negative finite number"), {
272
+ operation: "gc-monitor.invalid-entry"
273
+ });
274
+ return;
275
+ }
276
+ if (kind === 1) {
277
+ minorCount++;
278
+ } else {
279
+ majorCount++;
280
+ }
281
+ pauseTimes.push(pauseTimeMs);
282
+ if (pauseTimes.length > 100) {
283
+ pauseTimes.shift();
284
+ }
285
+ if (onPerfEvent) {
286
+ try {
287
+ const end = clock.now();
288
+ onPerfEvent({
289
+ name: `gc_${kind === 1 ? "minor" : "major"}`,
290
+ duration: pauseTimeMs,
291
+ start: end - pauseTimeMs,
292
+ end,
293
+ labels: {
294
+ kind: kind === 1 ? "minor" : "major"
295
+ },
296
+ source: "runtime"
297
+ });
298
+ } catch (error) {
299
+ onError(error, { operation: "gc-monitor.perf-event" });
300
+ }
301
+ }
302
+ if (onSaturationAlert) {
303
+ let severity = null;
304
+ let threshold = 0;
305
+ if (pauseTimeThresholds.critical !== void 0 && pauseTimeMs >= pauseTimeThresholds.critical) {
306
+ severity = "critical";
307
+ threshold = pauseTimeThresholds.critical;
308
+ } else if (pauseTimeThresholds.warn !== void 0 && pauseTimeMs >= pauseTimeThresholds.warn) {
309
+ severity = "warn";
310
+ threshold = pauseTimeThresholds.warn;
311
+ }
312
+ if (severity) {
313
+ try {
314
+ onSaturationAlert({
315
+ reason: `gc_pause_${kind === 1 ? "minor" : "major"}`,
316
+ severity,
317
+ value: pauseTimeMs,
318
+ threshold
319
+ });
320
+ } catch (error) {
321
+ onError(error, { operation: "gc-monitor.saturation-alert" });
322
+ }
323
+ }
324
+ }
325
+ }
326
+ function checkHeapUsage() {
327
+ if (!running) {
328
+ return;
329
+ }
330
+ if (!onSaturationAlert) {
331
+ return;
332
+ }
333
+ const usage = process.memoryUsage();
334
+ const heapLimit = usage.heapLimit ?? usage.heapTotal;
335
+ const heapUsed = usage.heapUsed;
336
+ if (heapLimit > 0) {
337
+ const utilization = heapUsed / heapLimit;
338
+ let severity = null;
339
+ let threshold = 0;
340
+ if (heapUsageThresholds.critical !== void 0 && utilization >= heapUsageThresholds.critical) {
341
+ severity = "critical";
342
+ threshold = heapUsageThresholds.critical;
343
+ } else if (heapUsageThresholds.warn !== void 0 && utilization >= heapUsageThresholds.warn) {
344
+ severity = "warn";
345
+ threshold = heapUsageThresholds.warn;
346
+ }
347
+ if (severity) {
348
+ try {
349
+ onSaturationAlert({
350
+ reason: "heap_usage",
351
+ severity,
352
+ value: utilization,
353
+ threshold
354
+ });
355
+ } catch (error) {
356
+ onError(error, { operation: "gc-monitor.saturation-alert" });
357
+ }
358
+ }
359
+ }
360
+ }
361
+ function safeCheckHeapUsage() {
362
+ try {
363
+ checkHeapUsage();
364
+ } catch (error) {
365
+ onError(error, { operation: "gc-monitor.heap-check" });
366
+ }
367
+ }
368
+ return {
369
+ start() {
370
+ if (running) {
371
+ return;
372
+ }
373
+ try {
374
+ running = true;
375
+ startObserver();
376
+ } catch (error) {
377
+ running = false;
378
+ onError(error, { operation: "gc-monitor.start" });
379
+ }
380
+ },
381
+ stop() {
382
+ running = false;
383
+ const activeObserver = observer;
384
+ observer = null;
385
+ try {
386
+ activeObserver?.disconnect();
387
+ } catch (error) {
388
+ onError(error, { operation: "gc-monitor.stop" });
389
+ }
390
+ const activeHeapCheckInterval = heapCheckIntervalId;
391
+ heapCheckIntervalId = null;
392
+ if (activeHeapCheckInterval !== null) {
393
+ clearInterval(activeHeapCheckInterval);
394
+ }
395
+ },
396
+ getStats() {
397
+ const totalPauseTimeMs = pauseTimes.reduce((sum, val) => sum + val, 0);
398
+ const avgPauseTimeMs = pauseTimes.length > 0 ? totalPauseTimeMs / pauseTimes.length : 0;
399
+ const maxPauseTimeMs = pauseTimes.length > 0 ? Math.max(...pauseTimes) : 0;
400
+ return {
401
+ majorCount,
402
+ minorCount,
403
+ totalPauseTimeMs,
404
+ avgPauseTimeMs,
405
+ maxPauseTimeMs
406
+ };
407
+ },
408
+ getHeapUsage() {
409
+ if (typeof process === "undefined" || !process.memoryUsage) {
410
+ return null;
411
+ }
412
+ const usage = process.memoryUsage();
413
+ const result = {
414
+ heapUsed: usage.heapUsed,
415
+ heapTotal: usage.heapTotal
416
+ };
417
+ const heapLimit = usage.heapLimit;
418
+ if (heapLimit !== void 0) {
419
+ result.heapLimit = heapLimit;
420
+ }
421
+ return result;
422
+ }
423
+ };
424
+ }
425
+ function validatePair(thresholds, name, max = Number.POSITIVE_INFINITY) {
426
+ const values = [thresholds.warn, thresholds.critical].filter((value) => value !== void 0);
427
+ if (!values.every((value) => Number.isFinite(value) && value >= 0 && value <= max)) {
428
+ throw new Error(`${name} thresholds must be finite numbers between 0 and ${max}`);
429
+ }
430
+ if (thresholds.warn !== void 0 && thresholds.critical !== void 0 && thresholds.warn > thresholds.critical) {
431
+ throw new Error(`${name} thresholds must satisfy warn <= critical`);
432
+ }
433
+ }
434
+
435
+ // src/performance/features/core/resource-load-average.ts
436
+ var osModuleCache = null;
437
+ var osModuleLoadingPromise = null;
438
+ function getResourceLoadAverage(onError) {
439
+ if (typeof process === "undefined" || process.platform === "win32") return void 0;
440
+ try {
441
+ if (osModuleCache) {
442
+ return osModuleCache.loadavg();
443
+ }
444
+ if (osModuleLoadingPromise === null) {
445
+ osModuleLoadingPromise = import('os').then((module) => {
446
+ osModuleCache = { loadavg: () => {
447
+ const load = module.loadavg();
448
+ return [load[0] ?? 0, load[1] ?? 0, load[2] ?? 0];
449
+ } };
450
+ }).catch((error) => {
451
+ osModuleCache = null;
452
+ osModuleLoadingPromise = null;
453
+ onError(error, { module: "os" });
454
+ });
455
+ }
456
+ } catch {
457
+ }
458
+ return void 0;
459
+ }
460
+
461
+ // src/performance/features/core/resource-monitor.ts
462
+ function createResourceMonitor(options) {
463
+ const {
464
+ clock,
465
+ errors,
466
+ intervalMs = 5e3,
467
+ onSaturationAlert,
468
+ onPerfEvent,
469
+ thresholds = {}
470
+ } = options;
471
+ const onError = createPerformanceOnError(errors, {
472
+ operation: "module-load",
473
+ monitor: "resource-monitor"
474
+ });
475
+ if (!Number.isSafeInteger(intervalMs) || intervalMs <= 0 || intervalMs > 2147483647) {
476
+ throw new Error("Resource monitor intervalMs must be between 1 and 2147483647");
477
+ }
478
+ const cpuThresholds = { ...thresholds.cpu ?? {} };
479
+ const memoryThresholds = { ...thresholds.memory ?? {} };
480
+ validateThresholds(cpuThresholds, "CPU");
481
+ validateThresholds(memoryThresholds, "memory", 1);
482
+ let intervalId = null;
483
+ let lastCPUUsage = null;
484
+ let lastCPUCollectedAt = null;
485
+ let running = false;
486
+ function safeCollectStats() {
487
+ if (!running) {
488
+ return;
489
+ }
490
+ try {
491
+ collectStats();
492
+ } catch (error) {
493
+ onError(error, { operation: "resource-monitor.tick" });
494
+ }
495
+ }
496
+ function collectStats() {
497
+ if (typeof process === "undefined" || typeof process.cpuUsage !== "function" || typeof process.memoryUsage !== "function") {
498
+ return;
499
+ }
500
+ const now = clock.now();
501
+ const cpuUsage = process.cpuUsage();
502
+ if (lastCPUUsage) {
503
+ const elapsedMs = lastCPUCollectedAt !== null && now > lastCPUCollectedAt ? now - lastCPUCollectedAt : intervalMs;
504
+ const userDelta = Math.max(0, cpuUsage.user - lastCPUUsage.user);
505
+ const systemDelta = Math.max(0, cpuUsage.system - lastCPUUsage.system);
506
+ const totalDelta = userDelta + systemDelta;
507
+ if (onPerfEvent) {
508
+ try {
509
+ onPerfEvent({
510
+ name: "cpu_usage",
511
+ duration: totalDelta / 1e3,
512
+ // Convert to ms
513
+ start: now - elapsedMs,
514
+ end: now,
515
+ labels: {
516
+ user: String(userDelta / 1e3),
517
+ system: String(systemDelta / 1e3),
518
+ utilization: String(totalDelta / (elapsedMs * 1e3))
519
+ },
520
+ source: "runtime"
521
+ });
522
+ } catch (error) {
523
+ onError(error, { operation: "resource-monitor.perf-event" });
524
+ }
525
+ }
526
+ const cpuUtilization = totalDelta / (elapsedMs * 1e3);
527
+ if (onSaturationAlert) {
528
+ let severity = null;
529
+ let threshold = 0;
530
+ if (cpuThresholds.critical !== void 0 && cpuUtilization >= cpuThresholds.critical) {
531
+ severity = "critical";
532
+ threshold = cpuThresholds.critical;
533
+ } else if (cpuThresholds.warn !== void 0 && cpuUtilization >= cpuThresholds.warn) {
534
+ severity = "warn";
535
+ threshold = cpuThresholds.warn;
536
+ } else if (cpuThresholds.info !== void 0 && cpuUtilization >= cpuThresholds.info) {
537
+ severity = "info";
538
+ threshold = cpuThresholds.info;
539
+ }
540
+ if (severity) {
541
+ try {
542
+ onSaturationAlert({
543
+ reason: "cpu_saturation",
544
+ severity,
545
+ value: cpuUtilization,
546
+ threshold
547
+ });
548
+ } catch (error) {
549
+ onError(error, { operation: "resource-monitor.saturation-alert" });
550
+ }
551
+ }
552
+ }
553
+ }
554
+ lastCPUUsage = cpuUsage;
555
+ lastCPUCollectedAt = now;
556
+ const memoryUsage = process.memoryUsage();
557
+ const memoryStats = {
558
+ rss: memoryUsage.rss,
559
+ heapUsed: memoryUsage.heapUsed,
560
+ heapTotal: memoryUsage.heapTotal,
561
+ external: memoryUsage.external
562
+ };
563
+ if (onPerfEvent) {
564
+ try {
565
+ onPerfEvent({
566
+ name: "memory_usage",
567
+ duration: 0,
568
+ // Memory is a snapshot, not a duration
569
+ start: now,
570
+ end: now,
571
+ labels: {
572
+ rss: String(memoryStats.rss),
573
+ heapUsed: String(memoryStats.heapUsed),
574
+ heapTotal: String(memoryStats.heapTotal),
575
+ external: String(memoryStats.external)
576
+ },
577
+ source: "runtime"
578
+ });
579
+ } catch (error) {
580
+ onError(error, { operation: "resource-monitor.perf-event" });
581
+ }
582
+ }
583
+ if (memoryStats.heapTotal > 0 && onSaturationAlert) {
584
+ const memoryUtilization = memoryStats.heapUsed / memoryStats.heapTotal;
585
+ let severity = null;
586
+ let threshold = 0;
587
+ if (memoryThresholds.critical !== void 0 && memoryUtilization >= memoryThresholds.critical) {
588
+ severity = "critical";
589
+ threshold = memoryThresholds.critical;
590
+ } else if (memoryThresholds.warn !== void 0 && memoryUtilization >= memoryThresholds.warn) {
591
+ severity = "warn";
592
+ threshold = memoryThresholds.warn;
593
+ } else if (memoryThresholds.info !== void 0 && memoryUtilization >= memoryThresholds.info) {
594
+ severity = "info";
595
+ threshold = memoryThresholds.info;
596
+ }
597
+ if (severity) {
598
+ try {
599
+ onSaturationAlert({
600
+ reason: "memory_pressure",
601
+ severity,
602
+ value: memoryUtilization,
603
+ threshold
604
+ });
605
+ } catch (error) {
606
+ onError(error, { operation: "resource-monitor.saturation-alert" });
607
+ }
608
+ }
609
+ }
610
+ }
611
+ return {
612
+ start() {
613
+ if (intervalId !== null) {
614
+ return;
615
+ }
616
+ if (typeof process !== "undefined" && typeof process.cpuUsage === "function") {
617
+ lastCPUUsage = process.cpuUsage();
618
+ lastCPUCollectedAt = clock.now();
619
+ }
620
+ running = true;
621
+ intervalId = setInterval(safeCollectStats, intervalMs);
622
+ intervalId.unref?.();
623
+ },
624
+ stop() {
625
+ running = false;
626
+ if (intervalId !== null) {
627
+ clearInterval(intervalId);
628
+ intervalId = null;
629
+ }
630
+ lastCPUUsage = null;
631
+ lastCPUCollectedAt = null;
632
+ },
633
+ getStats() {
634
+ if (typeof process === "undefined" || typeof process.cpuUsage !== "function" || typeof process.memoryUsage !== "function") {
635
+ return null;
636
+ }
637
+ const cpuUsage = process.cpuUsage();
638
+ const memoryUsage = process.memoryUsage();
639
+ const cpu = {
640
+ user: cpuUsage.user,
641
+ system: cpuUsage.system,
642
+ total: cpuUsage.user + cpuUsage.system
643
+ };
644
+ const memory = {
645
+ rss: memoryUsage.rss,
646
+ heapUsed: memoryUsage.heapUsed,
647
+ heapTotal: memoryUsage.heapTotal,
648
+ external: memoryUsage.external
649
+ };
650
+ const loadAverage = getResourceLoadAverage(onError);
651
+ const stats = {
652
+ cpu,
653
+ memory
654
+ };
655
+ if (loadAverage) {
656
+ stats.loadAverage = loadAverage;
657
+ }
658
+ return stats;
659
+ }
660
+ };
661
+ }
662
+ function validateThresholds(thresholds, name, max = Number.POSITIVE_INFINITY) {
663
+ const ordered = [thresholds.info, thresholds.warn, thresholds.critical].filter((value) => value !== void 0);
664
+ if (!ordered.every((value) => Number.isFinite(value) && value >= 0 && value <= max)) {
665
+ throw new Error(`${name} thresholds must be finite numbers between 0 and ${max}`);
666
+ }
667
+ if (thresholds.info !== void 0 && thresholds.warn !== void 0 && thresholds.info > thresholds.warn || thresholds.warn !== void 0 && thresholds.critical !== void 0 && thresholds.warn > thresholds.critical || thresholds.info !== void 0 && thresholds.critical !== void 0 && thresholds.info > thresholds.critical) {
668
+ throw new Error(`${name} thresholds must satisfy info <= warn <= critical`);
669
+ }
670
+ }
671
+
672
+ // src/performance/utils/error-boundary.ts
673
+ function withErrorBoundary(fn, errors, context) {
674
+ const onError = createPerformanceOnError(errors, {
675
+ stage: "monitor",
676
+ ...context ? { step: Object.values(context)[0] } : {}
677
+ });
678
+ return ((...args) => {
679
+ try {
680
+ return fn(...args);
681
+ } catch (error) {
682
+ onError(error);
683
+ return void 0;
684
+ }
685
+ });
686
+ }
687
+
688
+ // src/performance/core/runtime/monitors.ts
689
+ function createMonitors(options) {
690
+ const monitors = {};
691
+ const safelyEmitEvent = (event) => {
692
+ try {
693
+ options.onPerfEvent(event);
694
+ } catch {
695
+ }
696
+ };
697
+ const safelyEmitAlert = (alert) => {
698
+ try {
699
+ options.onSaturationAlert?.(alert);
700
+ } catch {
701
+ }
702
+ };
703
+ try {
704
+ if (options.enableEventLoopMonitor) {
705
+ monitors.eventLoopMonitor = createEventLoopMonitor({
706
+ clock: options.clock,
707
+ onPerfEvent: safelyEmitEvent,
708
+ onSaturationAlert: safelyEmitAlert
709
+ });
710
+ withErrorBoundary(() => monitors.eventLoopMonitor?.start(), options.errors, { operation: "eventLoopMonitor.start" })();
711
+ }
712
+ if (options.enableGCMonitor) {
713
+ monitors.gcMonitor = createGCMonitor({
714
+ clock: options.clock,
715
+ ...options.errors ? { errors: options.errors } : {},
716
+ onPerfEvent: safelyEmitEvent,
717
+ onSaturationAlert: safelyEmitAlert
718
+ });
719
+ withErrorBoundary(() => monitors.gcMonitor?.start(), options.errors, { operation: "gcMonitor.start" })();
720
+ }
721
+ if (options.enableResourceMonitor) {
722
+ monitors.resourceMonitor = createResourceMonitor({
723
+ clock: options.clock,
724
+ ...options.errors ? { errors: options.errors } : {},
725
+ onPerfEvent: safelyEmitEvent,
726
+ onSaturationAlert: safelyEmitAlert
727
+ });
728
+ withErrorBoundary(() => monitors.resourceMonitor?.start(), options.errors, { operation: "resourceMonitor.start" })();
729
+ }
730
+ } catch (error) {
731
+ stopAllMonitors(monitors);
732
+ throw error;
733
+ }
734
+ return monitors;
735
+ }
736
+ function stopAllMonitors(monitors) {
737
+ try {
738
+ monitors.eventLoopMonitor?.stop();
739
+ } catch {
740
+ }
741
+ try {
742
+ monitors.gcMonitor?.stop();
743
+ } catch {
744
+ }
745
+ try {
746
+ monitors.resourceMonitor?.stop();
747
+ } catch {
748
+ }
749
+ }
750
+
751
+ export { createMonitors, stopAllMonitors };
752
+ //# sourceMappingURL=monitors-VNNUIKAK.js.map
753
+ //# sourceMappingURL=monitors-VNNUIKAK.js.map