@flakiness/sdk 0.150.2 → 0.152.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/browser.js CHANGED
@@ -29,6 +29,47 @@ var Multimap = class {
29
29
  }
30
30
  };
31
31
  function normalizeReport(report) {
32
+ report = deduplicateTestsSuitesEnvironments(report);
33
+ function cleanupTestStep(step) {
34
+ return {
35
+ ...step,
36
+ duration: step.duration === 0 ? void 0 : step.duration,
37
+ steps: step.steps && step.steps.length ? step.steps.map(cleanupTestStep) : void 0
38
+ };
39
+ }
40
+ function cleanupAttempt(attempt) {
41
+ return {
42
+ ...attempt,
43
+ status: attempt.status === "passed" ? void 0 : attempt.status,
44
+ expectedStatus: attempt.expectedStatus === "passed" ? void 0 : attempt.expectedStatus,
45
+ environmentIdx: attempt.environmentIdx === 0 ? void 0 : attempt.environmentIdx,
46
+ duration: attempt.duration === 0 ? void 0 : attempt.duration,
47
+ stdout: attempt.stdout && attempt.stdout.length ? attempt.stdout : void 0,
48
+ stderr: attempt.stderr && attempt.stderr.length ? attempt.stderr : void 0,
49
+ attachments: attempt.attachments && attempt.attachments.length ? attempt.attachments : void 0,
50
+ steps: attempt.steps && attempt.steps.length ? attempt.steps.map(cleanupTestStep) : void 0
51
+ };
52
+ }
53
+ function cleanupTest(test) {
54
+ return {
55
+ ...test,
56
+ attempts: test.attempts.map(cleanupAttempt)
57
+ };
58
+ }
59
+ function cleanupSuite(suite) {
60
+ return {
61
+ ...suite,
62
+ tests: suite.tests && suite.tests.length ? suite.tests.map(cleanupTest) : void 0,
63
+ suites: suite.suites && suite.suites.length ? suite.suites.map(cleanupSuite) : void 0
64
+ };
65
+ }
66
+ return {
67
+ ...report,
68
+ tests: report.tests && report.tests.length ? report.tests.map(cleanupTest) : void 0,
69
+ suites: report.suites && report.suites.length ? report.suites.map(cleanupSuite) : void 0
70
+ };
71
+ }
72
+ function deduplicateTestsSuitesEnvironments(report) {
32
73
  const gEnvs = /* @__PURE__ */ new Map();
33
74
  const gSuites = /* @__PURE__ */ new Map();
34
75
  const gTests = new Multimap();
@@ -50,9 +91,15 @@ function normalizeReport(report) {
50
91
  gTestIds.set(test, testId);
51
92
  gSuiteTests.set(suiteId, test);
52
93
  for (const attempt of test.attempts) {
53
- const env = report.environments[attempt.environmentIdx];
94
+ const env = report.environments[attempt.environmentIdx ?? 0];
54
95
  const envId = gEnvIds.get(env);
55
96
  usedEnvIds.add(envId);
97
+ if (attempt.annotations && !attempt.annotations.length)
98
+ delete attempt.annotations;
99
+ if (attempt.stdout && !attempt.stdout.length)
100
+ delete attempt.stdout;
101
+ if (attempt.stderr && !attempt.stderr.length)
102
+ delete attempt.stderr;
56
103
  }
57
104
  }
58
105
  }
@@ -77,7 +124,7 @@ function normalizeReport(report) {
77
124
  tags: tags.length ? tags : void 0,
78
125
  attempts: tests2.map((t) => t.attempts).flat().map((attempt) => ({
79
126
  ...attempt,
80
- environmentIdx: envIdToIndex.get(gEnvIds.get(report.environments[attempt.environmentIdx]))
127
+ environmentIdx: envIdToIndex.get(gEnvIds.get(report.environments[attempt.environmentIdx ?? 0]))
81
128
  }))
82
129
  };
83
130
  });
@@ -96,14 +143,14 @@ function normalizeReport(report) {
96
143
  });
97
144
  }
98
145
  visitTests2(report.tests ?? [], "suiteless");
99
- for (const suite of report.suites)
146
+ for (const suite of report.suites ?? [])
100
147
  visitSuite(suite);
101
148
  const newEnvironments = [...usedEnvIds];
102
149
  const envIdToIndex = new Map(newEnvironments.map((envId, index) => [envId, index]));
103
150
  return {
104
151
  ...report,
105
152
  environments: newEnvironments.map((envId) => gEnvs.get(envId)),
106
- suites: transformSuites(report.suites),
153
+ suites: transformSuites(report.suites ?? []),
107
154
  tests: transformTests(report.tests ?? [])
108
155
  };
109
156
  }
@@ -144,7 +191,7 @@ function visitTests(report, testVisitor) {
144
191
  }
145
192
  for (const test of report.tests ?? [])
146
193
  testVisitor(test, []);
147
- for (const suite of report.suites)
194
+ for (const suite of report.suites ?? [])
148
195
  visitSuite(suite, []);
149
196
  }
150
197
  export {
package/lib/index.js CHANGED
@@ -46,6 +46,86 @@ function azure() {
46
46
  }
47
47
  }
48
48
 
49
+ // src/cpuUtilization.ts
50
+ import os from "os";
51
+
52
+ // src/_telemetry.ts
53
+ function addTelemetryPoint(collection, newPoint, precision) {
54
+ const lastPoint = collection.at(-1);
55
+ const preLastPoint = collection.at(-2);
56
+ if (lastPoint && preLastPoint && Math.abs(lastPoint.value - preLastPoint.value) < precision && Math.abs(lastPoint.value - newPoint.value) < precision) {
57
+ lastPoint.timestamp = newPoint.timestamp;
58
+ } else {
59
+ collection.push(newPoint);
60
+ }
61
+ }
62
+ function toProtocolTelemetry(collection) {
63
+ if (!collection.length)
64
+ return [];
65
+ let lastTimestamp = collection[0].timestamp;
66
+ return collection.map((x, idx) => {
67
+ const dts = idx === 0 ? x.timestamp : x.timestamp - lastTimestamp;
68
+ lastTimestamp = x.timestamp;
69
+ return [dts, Math.round(x.value * 100) / 100];
70
+ });
71
+ }
72
+
73
+ // src/cpuUtilization.ts
74
+ function sampleCpus() {
75
+ return os.cpus().map((cpu) => {
76
+ const totalTicks = cpu.times.user + cpu.times.nice + cpu.times.sys + cpu.times.irq + cpu.times.idle;
77
+ const idleTicks = cpu.times.idle;
78
+ const busyTicks = totalTicks - idleTicks;
79
+ return { totalTicks, busyTicks };
80
+ });
81
+ }
82
+ var CPUUtilization = class {
83
+ _lastSample = sampleCpus();
84
+ _precision;
85
+ _cpuAvg = [];
86
+ _cpuMax = [];
87
+ /**
88
+ * @param options.precision - Minimum change in percentage points to record a new data point. Defaults to 7.
89
+ */
90
+ constructor(options) {
91
+ this._precision = options?.precision ?? 7;
92
+ }
93
+ /**
94
+ * Records the current CPU utilization since the last sample.
95
+ * The first call primes the baseline; subsequent calls record deltas.
96
+ */
97
+ sample() {
98
+ const newSample = sampleCpus();
99
+ if (newSample.length === this._lastSample.length) {
100
+ const utilization = newSample.map(
101
+ (cpu, idx) => (
102
+ // If the CPU did no work since the last sample, then it's
103
+ // utilization is effectively 0.
104
+ cpu.totalTicks === this._lastSample[idx].totalTicks ? 0 : (cpu.busyTicks - this._lastSample[idx].busyTicks) / (cpu.totalTicks - this._lastSample[idx].totalTicks) * 100
105
+ )
106
+ );
107
+ const timestamp = Date.now();
108
+ addTelemetryPoint(this._cpuAvg, {
109
+ timestamp,
110
+ value: utilization.reduce((acc, x) => acc + x) / utilization.length
111
+ }, this._precision);
112
+ addTelemetryPoint(this._cpuMax, {
113
+ timestamp,
114
+ value: Math.max(...utilization)
115
+ }, this._precision);
116
+ }
117
+ this._lastSample = newSample;
118
+ }
119
+ /**
120
+ * Adds collected CPU telemetry to the report.
121
+ */
122
+ enrich(report) {
123
+ report.cpuCount = os.cpus().length;
124
+ report.cpuMax = toProtocolTelemetry(this._cpuMax);
125
+ report.cpuAvg = toProtocolTelemetry(this._cpuAvg);
126
+ }
127
+ };
128
+
49
129
  // src/gitWorktree.ts
50
130
  import assert from "assert";
51
131
  import { exec } from "child_process";
@@ -335,23 +415,154 @@ async function listCommits(gitRoot, head, count) {
335
415
  }
336
416
  }
337
417
 
418
+ // src/ramUtilization.ts
419
+ import { spawnSync as spawnSync2 } from "child_process";
420
+ import os2 from "os";
421
+ function getAvailableMemMacOS() {
422
+ const lines = spawnSync2("vm_stat", { encoding: "utf8" }).stdout.trim().split("\n");
423
+ const pageSize = parseInt(lines[0].match(/page size of (\d+) bytes/)[1], 10);
424
+ if (isNaN(pageSize)) {
425
+ console.warn("[flakiness.io] Error detecting macos page size");
426
+ return 0;
427
+ }
428
+ let totalFree = 0;
429
+ for (const line of lines) {
430
+ if (/Pages (free|inactive|speculative):/.test(line)) {
431
+ const match = line.match(/\d+/);
432
+ if (match)
433
+ totalFree += parseInt(match[0], 10);
434
+ }
435
+ }
436
+ return totalFree * pageSize;
437
+ }
438
+ var RAMUtilization = class {
439
+ _precision;
440
+ _totalBytes = os2.totalmem();
441
+ _ram = [];
442
+ /**
443
+ * @param options.precision - Minimum change in percentage points to record a new data point. Defaults to 1.
444
+ */
445
+ constructor(options) {
446
+ this._precision = options?.precision ?? 1;
447
+ }
448
+ /**
449
+ * Records the current RAM utilization.
450
+ */
451
+ sample() {
452
+ const freeBytes = os2.platform() === "darwin" ? getAvailableMemMacOS() : os2.freemem();
453
+ addTelemetryPoint(this._ram, {
454
+ timestamp: Date.now(),
455
+ value: (this._totalBytes - freeBytes) / this._totalBytes * 100
456
+ }, this._precision);
457
+ }
458
+ /**
459
+ * Adds collected RAM telemetry to the report.
460
+ */
461
+ enrich(report) {
462
+ report.ramBytes = this._totalBytes;
463
+ report.ram = toProtocolTelemetry(this._ram);
464
+ }
465
+ };
466
+
338
467
  // src/reportUtils.ts
339
468
  var reportUtils_exports = {};
340
469
  __export(reportUtils_exports, {
470
+ collectSources: () => collectSources,
341
471
  createDataAttachment: () => createDataAttachment,
342
472
  createEnvironment: () => createEnvironment,
343
473
  createFileAttachment: () => createFileAttachment,
344
- createTestStepSnippetsInplace: () => createTestStepSnippetsInplace,
345
474
  normalizeReport: () => normalizeReport,
346
475
  stripAnsi: () => stripAnsi,
347
476
  visitTests: () => visitTests
348
477
  });
349
478
 
350
- // src/createEnvironment.ts
479
+ // src/collectSources.ts
351
480
  import fs2 from "fs";
352
- import os from "os";
481
+ function collectLocationsFromTestStep(testStep, onLocation) {
482
+ onLocation(testStep.location);
483
+ for (const step of testStep.steps ?? [])
484
+ collectLocationsFromTestStep(step, onLocation);
485
+ }
486
+ function collectLocationsFromTest(test, onLocation) {
487
+ onLocation(test.location);
488
+ for (const attempt of test.attempts) {
489
+ for (const annotation of attempt.annotations ?? [])
490
+ onLocation(annotation.location);
491
+ for (const err of attempt.errors ?? [])
492
+ onLocation(err.location);
493
+ for (const step of attempt.steps ?? [])
494
+ collectLocationsFromTestStep(step, onLocation);
495
+ }
496
+ }
497
+ function collectLocationsFromSuite(suite, onLocation) {
498
+ onLocation(suite.location);
499
+ for (const child of suite.suites ?? [])
500
+ collectLocationsFromSuite(child, onLocation);
501
+ for (const test of suite.tests ?? [])
502
+ collectLocationsFromTest(test, onLocation);
503
+ }
504
+ function collectLocationsFromReport(report, onLocation) {
505
+ for (const e of report.unattributedErrors ?? [])
506
+ onLocation(e.location);
507
+ for (const test of report.tests ?? [])
508
+ collectLocationsFromTest(test, onLocation);
509
+ for (const suite of report.suites ?? [])
510
+ collectLocationsFromSuite(suite, onLocation);
511
+ }
512
+ function lineNumbersToChunks(lineNumbers, options) {
513
+ const context = options.context;
514
+ const result = [];
515
+ let current;
516
+ for (const ln of Array.from(lineNumbers).sort((a, b) => a - b)) {
517
+ const span = [ln - context, ln + context];
518
+ if (!current || current[1] + 1 < span[0]) {
519
+ result.push(span);
520
+ current = span;
521
+ } else {
522
+ current[1] = span[1];
523
+ }
524
+ }
525
+ return result;
526
+ }
527
+ function collectSources(worktree, report) {
528
+ const filesToLines = /* @__PURE__ */ new Map();
529
+ collectLocationsFromReport(report, (location) => {
530
+ if (!location)
531
+ return;
532
+ let lineNumbers = filesToLines.get(location.file);
533
+ if (!lineNumbers) {
534
+ lineNumbers = /* @__PURE__ */ new Set();
535
+ filesToLines.set(location.file, lineNumbers);
536
+ }
537
+ lineNumbers.add(location.line);
538
+ });
539
+ const sources = [];
540
+ for (const [gitFilePath, lineNumbers] of filesToLines) {
541
+ let source;
542
+ try {
543
+ source = fs2.readFileSync(worktree.absolutePath(gitFilePath), "utf-8");
544
+ } catch (e) {
545
+ continue;
546
+ }
547
+ const sourceLines = source.split("\n");
548
+ for (const chunk of lineNumbersToChunks(lineNumbers, { context: 5 })) {
549
+ const from = Math.max(chunk[0] - 1, 0);
550
+ const to = Math.min(chunk[1], sourceLines.length);
551
+ sources.push({
552
+ filePath: gitFilePath,
553
+ lineOffset: from !== 0 ? from + 1 : void 0,
554
+ text: sourceLines.slice(from, to).join("\n")
555
+ });
556
+ }
557
+ }
558
+ report.sources = sources;
559
+ }
560
+
561
+ // src/createEnvironment.ts
562
+ import fs3 from "fs";
563
+ import os3 from "os";
353
564
  function readLinuxOSRelease() {
354
- const osReleaseText = fs2.readFileSync("/etc/os-release", "utf-8");
565
+ const osReleaseText = fs3.readFileSync("/etc/os-release", "utf-8");
355
566
  return new Map(osReleaseText.toLowerCase().split("\n").filter((line) => line.includes("=")).map((line) => {
356
567
  line = line.trim();
357
568
  let [key, value] = line.split("=");
@@ -376,7 +587,7 @@ function osDarwinInfo() {
376
587
  function osWinInfo() {
377
588
  const name = "win";
378
589
  const arch = process.arch;
379
- const version = os.release();
590
+ const version = os3.release();
380
591
  return { name, arch, version };
381
592
  }
382
593
  function getOSInfo() {
@@ -401,74 +612,11 @@ function createEnvironment(options) {
401
612
  osName: osInfo.name,
402
613
  osVersion: osInfo.version
403
614
  },
404
- userSuppliedData: {
615
+ metadata: {
405
616
  ...extractEnvConfiguration(),
406
- ...options.userSuppliedData ?? {}
407
- },
408
- opaqueData: options.opaqueData
409
- };
410
- }
411
-
412
- // src/createTestStepSnippets.ts
413
- import { codeFrameColumns } from "@babel/code-frame";
414
- import fs3 from "fs";
415
-
416
- // src/visitTests.ts
417
- function visitTests(report, testVisitor) {
418
- function visitSuite(suite, parents) {
419
- parents.push(suite);
420
- for (const test of suite.tests ?? [])
421
- testVisitor(test, parents);
422
- for (const childSuite of suite.suites ?? [])
423
- visitSuite(childSuite, parents);
424
- parents.pop();
425
- }
426
- for (const test of report.tests ?? [])
427
- testVisitor(test, []);
428
- for (const suite of report.suites)
429
- visitSuite(suite, []);
430
- }
431
-
432
- // src/createTestStepSnippets.ts
433
- function createTestStepSnippetsInplace(worktree, report) {
434
- const allSteps = /* @__PURE__ */ new Map();
435
- visitTests(report, (test) => {
436
- for (const attempt of test.attempts) {
437
- for (const step of attempt.steps ?? []) {
438
- if (!step.location)
439
- continue;
440
- let fileSteps = allSteps.get(step.location.file);
441
- if (!fileSteps) {
442
- fileSteps = /* @__PURE__ */ new Set();
443
- allSteps.set(step.location.file, fileSteps);
444
- }
445
- fileSteps.add(step);
446
- }
447
- }
448
- });
449
- for (const [gitFilePath, steps] of allSteps) {
450
- let source;
451
- try {
452
- source = fs3.readFileSync(worktree.absolutePath(gitFilePath), "utf-8");
453
- } catch (e) {
454
- continue;
455
- }
456
- const lines = source.split("\n").length;
457
- const highlighted = codeFrameColumns(source, { start: { line: lines, column: 1 } }, { highlightCode: true, linesAbove: lines, linesBelow: 0 });
458
- const highlightedLines = highlighted.split("\n");
459
- const lineWithArrow = highlightedLines[highlightedLines.length - 1];
460
- for (const step of steps) {
461
- if (!step.location)
462
- continue;
463
- if (step.location.line < 2 || step.location.line >= lines)
464
- continue;
465
- const snippetLines = highlightedLines.slice(step.location.line - 2, step.location.line + 1);
466
- const index = lineWithArrow.indexOf("^");
467
- const shiftedArrow = lineWithArrow.slice(0, index) + " ".repeat(step.location.column - 1) + lineWithArrow.slice(index);
468
- snippetLines.splice(2, 0, shiftedArrow);
469
- step.snippet = snippetLines.join("\n");
617
+ ...options.metadata ?? {}
470
618
  }
471
- }
619
+ };
472
620
  }
473
621
 
474
622
  // src/normalizeReport.ts
@@ -485,6 +633,47 @@ var Multimap = class {
485
633
  }
486
634
  };
487
635
  function normalizeReport(report) {
636
+ report = deduplicateTestsSuitesEnvironments(report);
637
+ function cleanupTestStep(step) {
638
+ return {
639
+ ...step,
640
+ duration: step.duration === 0 ? void 0 : step.duration,
641
+ steps: step.steps && step.steps.length ? step.steps.map(cleanupTestStep) : void 0
642
+ };
643
+ }
644
+ function cleanupAttempt(attempt) {
645
+ return {
646
+ ...attempt,
647
+ status: attempt.status === "passed" ? void 0 : attempt.status,
648
+ expectedStatus: attempt.expectedStatus === "passed" ? void 0 : attempt.expectedStatus,
649
+ environmentIdx: attempt.environmentIdx === 0 ? void 0 : attempt.environmentIdx,
650
+ duration: attempt.duration === 0 ? void 0 : attempt.duration,
651
+ stdout: attempt.stdout && attempt.stdout.length ? attempt.stdout : void 0,
652
+ stderr: attempt.stderr && attempt.stderr.length ? attempt.stderr : void 0,
653
+ attachments: attempt.attachments && attempt.attachments.length ? attempt.attachments : void 0,
654
+ steps: attempt.steps && attempt.steps.length ? attempt.steps.map(cleanupTestStep) : void 0
655
+ };
656
+ }
657
+ function cleanupTest(test) {
658
+ return {
659
+ ...test,
660
+ attempts: test.attempts.map(cleanupAttempt)
661
+ };
662
+ }
663
+ function cleanupSuite(suite) {
664
+ return {
665
+ ...suite,
666
+ tests: suite.tests && suite.tests.length ? suite.tests.map(cleanupTest) : void 0,
667
+ suites: suite.suites && suite.suites.length ? suite.suites.map(cleanupSuite) : void 0
668
+ };
669
+ }
670
+ return {
671
+ ...report,
672
+ tests: report.tests && report.tests.length ? report.tests.map(cleanupTest) : void 0,
673
+ suites: report.suites && report.suites.length ? report.suites.map(cleanupSuite) : void 0
674
+ };
675
+ }
676
+ function deduplicateTestsSuitesEnvironments(report) {
488
677
  const gEnvs = /* @__PURE__ */ new Map();
489
678
  const gSuites = /* @__PURE__ */ new Map();
490
679
  const gTests = new Multimap();
@@ -506,9 +695,15 @@ function normalizeReport(report) {
506
695
  gTestIds.set(test, testId);
507
696
  gSuiteTests.set(suiteId, test);
508
697
  for (const attempt of test.attempts) {
509
- const env = report.environments[attempt.environmentIdx];
698
+ const env = report.environments[attempt.environmentIdx ?? 0];
510
699
  const envId = gEnvIds.get(env);
511
700
  usedEnvIds.add(envId);
701
+ if (attempt.annotations && !attempt.annotations.length)
702
+ delete attempt.annotations;
703
+ if (attempt.stdout && !attempt.stdout.length)
704
+ delete attempt.stdout;
705
+ if (attempt.stderr && !attempt.stderr.length)
706
+ delete attempt.stderr;
512
707
  }
513
708
  }
514
709
  }
@@ -533,7 +728,7 @@ function normalizeReport(report) {
533
728
  tags: tags.length ? tags : void 0,
534
729
  attempts: tests2.map((t) => t.attempts).flat().map((attempt) => ({
535
730
  ...attempt,
536
- environmentIdx: envIdToIndex.get(gEnvIds.get(report.environments[attempt.environmentIdx]))
731
+ environmentIdx: envIdToIndex.get(gEnvIds.get(report.environments[attempt.environmentIdx ?? 0]))
537
732
  }))
538
733
  };
539
734
  });
@@ -552,14 +747,14 @@ function normalizeReport(report) {
552
747
  });
553
748
  }
554
749
  visitTests2(report.tests ?? [], "suiteless");
555
- for (const suite of report.suites)
750
+ for (const suite of report.suites ?? [])
556
751
  visitSuite(suite);
557
752
  const newEnvironments = [...usedEnvIds];
558
753
  const envIdToIndex = new Map(newEnvironments.map((envId, index) => [envId, index]));
559
754
  return {
560
755
  ...report,
561
756
  environments: newEnvironments.map((envId) => gEnvs.get(envId)),
562
- suites: transformSuites(report.suites),
757
+ suites: transformSuites(report.suites ?? []),
563
758
  tests: transformTests(report.tests ?? [])
564
759
  };
565
760
  }
@@ -758,94 +953,21 @@ var ReportUpload = class {
758
953
  }
759
954
  };
760
955
 
761
- // src/systemUtilizationSampler.ts
762
- import { spawnSync as spawnSync2 } from "child_process";
763
- import os2 from "os";
764
- function getAvailableMemMacOS() {
765
- const lines = spawnSync2("vm_stat", { encoding: "utf8" }).stdout.trim().split("\n");
766
- const pageSize = parseInt(lines[0].match(/page size of (\d+) bytes/)[1], 10);
767
- if (isNaN(pageSize)) {
768
- console.warn("[flakiness.io] Error detecting macos page size");
769
- return 0;
770
- }
771
- let totalFree = 0;
772
- for (const line of lines) {
773
- if (/Pages (free|inactive|speculative):/.test(line)) {
774
- const match = line.match(/\d+/);
775
- if (match)
776
- totalFree += parseInt(match[0], 10);
777
- }
778
- }
779
- return totalFree * pageSize;
780
- }
781
- function getSystemUtilization() {
782
- let idleTicks = 0;
783
- let totalTicks = 0;
784
- for (const cpu of os2.cpus()) {
785
- totalTicks += cpu.times.user + cpu.times.nice + cpu.times.sys + cpu.times.irq + cpu.times.idle;
786
- idleTicks += cpu.times.idle;
956
+ // src/visitTests.ts
957
+ function visitTests(report, testVisitor) {
958
+ function visitSuite(suite, parents) {
959
+ parents.push(suite);
960
+ for (const test of suite.tests ?? [])
961
+ testVisitor(test, parents);
962
+ for (const childSuite of suite.suites ?? [])
963
+ visitSuite(childSuite, parents);
964
+ parents.pop();
787
965
  }
788
- return {
789
- idleTicks,
790
- totalTicks,
791
- timestamp: Date.now(),
792
- freeBytes: os2.platform() === "darwin" ? getAvailableMemMacOS() : os2.freemem()
793
- };
794
- }
795
- function toFKUtilization(sample, previous) {
796
- const idleTicks = sample.idleTicks - previous.idleTicks;
797
- const totalTicks = sample.totalTicks - previous.totalTicks;
798
- const cpuUtilization = Math.floor((1 - idleTicks / totalTicks) * 1e4) / 100;
799
- const memoryUtilization = Math.floor((1 - sample.freeBytes / os2.totalmem()) * 1e4) / 100;
800
- return {
801
- cpuUtilization,
802
- memoryUtilization,
803
- dts: sample.timestamp - previous.timestamp
804
- };
966
+ for (const test of report.tests ?? [])
967
+ testVisitor(test, []);
968
+ for (const suite of report.suites ?? [])
969
+ visitSuite(suite, []);
805
970
  }
806
- var SystemUtilizationSampler = class {
807
- /**
808
- * The accumulated system utilization data.
809
- *
810
- * This object is populated as samples are collected and can be directly included in
811
- * Flakiness reports. It contains:
812
- * - `samples` - Array of utilization samples with CPU/memory percentages and durations
813
- * - `startTimestamp` - Timestamp when sampling began
814
- * - `totalMemoryBytes` - Total system memory in bytes
815
- */
816
- result;
817
- _lastSample = getSystemUtilization();
818
- _timer;
819
- /**
820
- * Creates a new SystemUtilizationSampler and starts sampling immediately.
821
- *
822
- * The first sample is collected after 50ms, and subsequent samples are collected
823
- * every 1000ms. Call `dispose()` to stop sampling and clean up resources.
824
- */
825
- constructor() {
826
- this.result = {
827
- samples: [],
828
- startTimestamp: this._lastSample.timestamp,
829
- totalMemoryBytes: os2.totalmem()
830
- };
831
- this._timer = setTimeout(this._addSample.bind(this), 50);
832
- }
833
- _addSample() {
834
- const sample = getSystemUtilization();
835
- this.result.samples.push(toFKUtilization(sample, this._lastSample));
836
- this._lastSample = sample;
837
- this._timer = setTimeout(this._addSample.bind(this), 1e3);
838
- }
839
- /**
840
- * Stops sampling and cleans up resources.
841
- *
842
- * Call this method when you're done collecting utilization data to stop the sampling
843
- * timer and prevent memory leaks. The `result` object remains accessible after disposal.
844
- */
845
- dispose() {
846
- clearTimeout(this._timer);
847
- }
848
- };
849
971
 
850
972
  // src/showReport.ts
851
973
  import chalk from "chalk";
@@ -1187,11 +1309,12 @@ async function writeReport(report, attachments, outputFolder) {
1187
1309
  }
1188
1310
  export {
1189
1311
  CIUtils,
1312
+ CPUUtilization,
1190
1313
  FlakinessProjectConfig,
1191
1314
  FlakinessReport,
1192
1315
  GitWorktree,
1316
+ RAMUtilization,
1193
1317
  reportUtils_exports as ReportUtils,
1194
- SystemUtilizationSampler,
1195
1318
  showReport,
1196
1319
  uploadReport,
1197
1320
  writeReport
package/package.json CHANGED
@@ -1,7 +1,11 @@
1
1
  {
2
2
  "name": "@flakiness/sdk",
3
- "version": "0.150.2",
3
+ "version": "0.152.0",
4
4
  "private": false,
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/flakiness/nodejs-sdk.git"
8
+ },
5
9
  "exports": {
6
10
  ".": {
7
11
  "types": "./types/src/index.d.ts",
@@ -15,7 +19,7 @@
15
19
  }
16
20
  },
17
21
  "type": "module",
18
- "description": "",
22
+ "description": "Comprehensive SDK for creating and managing Flakiness JSON Reports in Node.js",
19
23
  "types": "./types/index.d.ts",
20
24
  "scripts": {
21
25
  "minor": "./version.mjs minor",
@@ -25,7 +29,6 @@
25
29
  "author": "Degu Labs, Inc",
26
30
  "license": "MIT",
27
31
  "devDependencies": {
28
- "@types/babel__code-frame": "^7.0.6",
29
32
  "@types/debug": "^4.1.12",
30
33
  "@types/node": "^25.0.3",
31
34
  "esbuild": "^0.27.0",
@@ -34,8 +37,7 @@
34
37
  "typescript": "^5.6.2"
35
38
  },
36
39
  "dependencies": {
37
- "@babel/code-frame": "^7.26.2",
38
- "@flakiness/flakiness-report": "^0.16.0",
40
+ "@flakiness/flakiness-report": "^0.18.0",
39
41
  "chalk": "^5.6.2",
40
42
  "debug": "^4.4.3",
41
43
  "open": "^10.2.0",
@@ -0,0 +1,7 @@
1
+ export type TelemetryPoint = {
2
+ timestamp: number;
3
+ value: number;
4
+ };
5
+ export declare function addTelemetryPoint(collection: TelemetryPoint[], newPoint: TelemetryPoint, precision: number): void;
6
+ export declare function toProtocolTelemetry(collection: TelemetryPoint[]): [number, number][];
7
+ //# sourceMappingURL=_telemetry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_telemetry.d.ts","sourceRoot":"","sources":["../../src/_telemetry.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,cAAc,EAAE,EAAE,QAAQ,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,QAY1G;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CASpF"}
@@ -0,0 +1,14 @@
1
+ import { FlakinessReport as FK } from '@flakiness/flakiness-report';
2
+ import { GitWorktree } from './gitWorktree.js';
3
+ /**
4
+ * Extracts source code snippets referenced by locations in the report.
5
+ *
6
+ * Scans all locations in the report (tests, steps, errors, annotations) and collects
7
+ * the relevant source code chunks with surrounding context (±5 lines). The collected
8
+ * sources are stored directly in `report.sources`.
9
+ *
10
+ * @param worktree - Git worktree for resolving file paths.
11
+ * @param report - Report to scan and enrich with source snippets.
12
+ */
13
+ export declare function collectSources(worktree: GitWorktree, report: FK.Report): void;
14
+ //# sourceMappingURL=collectSources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collectSources.d.ts","sourceRoot":"","sources":["../../src/collectSources.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,IAAI,EAAE,EAAE,MAAM,6BAA6B,CAAC;AAEpE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAqD/C;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,QAiCtE"}
@@ -0,0 +1,30 @@
1
+ import { FlakinessReport as FK } from "@flakiness/flakiness-report";
2
+ /**
3
+ * Tracks CPU utilization over time by recording periodic samples.
4
+ *
5
+ * Call `sample()` at desired intervals (e.g., test start/end, every second) to record
6
+ * CPU usage. The class tracks both average and max utilization across all CPU cores.
7
+ * Use `enrich()` to add the collected telemetry to a report.
8
+ */
9
+ export declare class CPUUtilization {
10
+ private _lastSample;
11
+ private _precision;
12
+ private _cpuAvg;
13
+ private _cpuMax;
14
+ /**
15
+ * @param options.precision - Minimum change in percentage points to record a new data point. Defaults to 7.
16
+ */
17
+ constructor(options?: {
18
+ precision?: number;
19
+ });
20
+ /**
21
+ * Records the current CPU utilization since the last sample.
22
+ * The first call primes the baseline; subsequent calls record deltas.
23
+ */
24
+ sample(): void;
25
+ /**
26
+ * Adds collected CPU telemetry to the report.
27
+ */
28
+ enrich(report: FK.Report): void;
29
+ }
30
+ //# sourceMappingURL=cpuUtilization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cpuUtilization.d.ts","sourceRoot":"","sources":["../../src/cpuUtilization.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,IAAI,EAAE,EAAE,MAAM,6BAA6B,CAAC;AAkBpE;;;;;;GAMG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,WAAW,CAAgB;IAEnC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,OAAO,CAAwB;IAEvC;;OAEG;gBACS,OAAO,CAAC,EAAE;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB;IAID;;;OAGG;IACH,MAAM;IAwBN;;OAEG;IACH,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM;CAKzB"}
@@ -9,16 +9,13 @@ import { FlakinessReport } from '@flakiness/flakiness-report';
9
9
  *
10
10
  * @param {Object} options - Configuration object for the environment.
11
11
  * @param {string} options.name - Human-readable name for the environment (e.g., 'CI', 'Local Dev', 'Staging').
12
- * @param {Record<string, string>} [options.userSuppliedData] - Additional key-value pairs to include
12
+ * @param {Record<string, string>} [options.metadata] - Additional key-value pairs to include
13
13
  * in the environment data. These are merged with `FK_ENV_*` environment variables.
14
- * @param {any} [options.opaqueData] - Optional opaque data object that will be stored with the
15
- * environment but not used for environment deduplication.
16
14
  *
17
15
  * @returns {FlakinessReport.Environment} Environment object containing:
18
16
  * - `name` - The provided environment name
19
17
  * - `systemData` - Automatically detected OS information (arch, name, version)
20
- * - `userSuppliedData` - Merged data from `FK_ENV_*` variables and `userSuppliedData` option
21
- * - `opaqueData` - The provided opaque data, if any
18
+ * - `metadata` - Merged data from `FK_ENV_*` variables and `userSuppliedData` option
22
19
  *
23
20
  * @example
24
21
  * ```typescript
@@ -28,13 +25,12 @@ import { FlakinessReport } from '@flakiness/flakiness-report';
28
25
  * // With custom data
29
26
  * const env = createEnvironment({
30
27
  * name: 'Staging',
31
- * userSuppliedData: { region: 'us-east-1', instance: 'large' }
28
+ * metadata: { region: 'us-east-1', instance: 'large' }
32
29
  * });
33
30
  * ```
34
31
  */
35
32
  export declare function createEnvironment(options: {
36
33
  name: string;
37
- userSuppliedData?: Record<string, string>;
38
- opaqueData?: any;
34
+ metadata?: Record<string, string>;
39
35
  }): FlakinessReport.Environment;
40
36
  //# sourceMappingURL=createEnvironment.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"createEnvironment.d.ts","sourceRoot":"","sources":["../../src/createEnvironment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAwD9D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,UAAU,CAAC,EAAE,GAAG,CAAC;CAClB,GAAG,eAAe,CAAC,WAAW,CAe9B"}
1
+ {"version":3,"file":"createEnvironment.d.ts","sourceRoot":"","sources":["../../src/createEnvironment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAwD9D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC,GAAG,eAAe,CAAC,WAAW,CAc9B"}
@@ -1,8 +1,9 @@
1
1
  export { FlakinessReport } from '@flakiness/flakiness-report';
2
2
  export { CIUtils } from './ciUtils.js';
3
+ export { CPUUtilization } from './cpuUtilization.js';
3
4
  export { GitWorktree } from './gitWorktree.js';
5
+ export { RAMUtilization } from './ramUtilization.js';
4
6
  export * as ReportUtils from './reportUtils.js';
5
- export { SystemUtilizationSampler } from './systemUtilizationSampler.js';
6
7
  export { showReport } from './showReport.js';
7
8
  export { uploadReport } from './uploadReport.js';
8
9
  export { writeReport } from './writeReport.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAG9D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAGzE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAG9D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAC;AAGhD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import { FlakinessReport } from "@flakiness/flakiness-report";
2
2
  /**
3
3
  * Normalizes a Flakiness report by deduplicating environments, suites, and tests.
4
+ * It also drops the fields from JSON that are equal to their default values.
4
5
  *
5
6
  * This function processes a report to:
6
7
  * - Deduplicate environments based on their content (using stable hashing)
@@ -1 +1 @@
1
- {"version":3,"file":"normalizeReport.d.ts","sourceRoot":"","sources":["../../src/normalizeReport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAyB9D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,CAAC,MAAM,GAAG,eAAe,CAAC,MAAM,CA2FtF"}
1
+ {"version":3,"file":"normalizeReport.d.ts","sourceRoot":"","sources":["../../src/normalizeReport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAyB9D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,CAAC,MAAM,GAAG,eAAe,CAAC,MAAM,CA+CtF"}
@@ -0,0 +1,28 @@
1
+ import { FlakinessReport as FK } from '@flakiness/flakiness-report';
2
+ /**
3
+ * Tracks RAM utilization over time by recording periodic samples.
4
+ *
5
+ * Call `sample()` at desired intervals (e.g., test start/end, every second) to record
6
+ * memory usage as a percentage of total system RAM. Use `enrich()` to add the collected
7
+ * telemetry to a report.
8
+ */
9
+ export declare class RAMUtilization {
10
+ private _precision;
11
+ private _totalBytes;
12
+ private _ram;
13
+ /**
14
+ * @param options.precision - Minimum change in percentage points to record a new data point. Defaults to 1.
15
+ */
16
+ constructor(options?: {
17
+ precision?: number;
18
+ });
19
+ /**
20
+ * Records the current RAM utilization.
21
+ */
22
+ sample(): void;
23
+ /**
24
+ * Adds collected RAM telemetry to the report.
25
+ */
26
+ enrich(report: FK.Report): void;
27
+ }
28
+ //# sourceMappingURL=ramUtilization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ramUtilization.d.ts","sourceRoot":"","sources":["../../src/ramUtilization.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,IAAI,EAAE,EAAE,MAAM,6BAA6B,CAAC;AA4BpE;;;;;;GAMG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAAiB;IAEpC,OAAO,CAAC,IAAI,CAAwB;IAEpC;;OAEG;gBACS,OAAO,CAAC,EAAE;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB;IAID;;OAEG;IACH,MAAM;IAQN;;OAEG;IACH,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM;CAIzB"}
@@ -1,5 +1,5 @@
1
+ export { collectSources } from './collectSources.js';
1
2
  export { createEnvironment } from './createEnvironment.js';
2
- export { createTestStepSnippetsInplace } from './createTestStepSnippets.js';
3
3
  export { normalizeReport } from './normalizeReport.js';
4
4
  export { stripAnsi } from './stripAnsi.js';
5
5
  export { createDataAttachment, createFileAttachment } from './uploadReport.js';
@@ -1 +1 @@
1
- {"version":3,"file":"reportUtils.d.ts","sourceRoot":"","sources":["../../src/reportUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,UAAU,EAAE,cAAc,EAC1B,cAAc,EACf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"reportUtils.d.ts","sourceRoot":"","sources":["../../src/reportUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,UAAU,EAAE,cAAc,EAC1B,cAAc,EACf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC"}
@@ -1,30 +0,0 @@
1
- import { FlakinessReport } from '@flakiness/flakiness-report';
2
- import { GitWorktree } from './gitWorktree.js';
3
- /**
4
- * Generates code snippets for test steps and attaches them to the report in-place.
5
- *
6
- * This function reads source files from the git worktree and creates highlighted code snippets
7
- * for each test step that has a location. The snippets include 3 lines of context (1 before,
8
- * the line itself, 1 after) with syntax highlighting and a visual indicator pointing to the
9
- * exact column position.
10
- *
11
- * The snippets are attached directly to the `step.snippet` property of each test step in the
12
- * report object. Steps without locations or with invalid file paths are silently skipped.
13
- *
14
- * @param {GitWorktree} worktree - Git worktree instance used to resolve file paths from
15
- * git-relative paths to absolute paths for reading source files.
16
- *
17
- * @param {FlakinessReport.Report} report - Flakiness report to process. The report is modified
18
- * in-place by adding `snippet` properties to test steps.
19
- *
20
- * @returns {void} This function modifies the report in-place and does not return a value.
21
- *
22
- * @example
23
- * ```typescript
24
- * const worktree = GitWorktree.create(process.cwd());
25
- * createTestStepSnippetsInplace(worktree, report);
26
- * // Report steps now have .snippet properties with highlighted code
27
- * ```
28
- */
29
- export declare function createTestStepSnippetsInplace(worktree: GitWorktree, report: FlakinessReport.Report): void;
30
- //# sourceMappingURL=createTestStepSnippets.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"createTestStepSnippets.d.ts","sourceRoot":"","sources":["../../src/createTestStepSnippets.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE9D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG/C;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,eAAe,CAAC,MAAM,QA4ClG"}
@@ -1,43 +0,0 @@
1
- import { FlakinessReport } from "@flakiness/flakiness-report";
2
- /**
3
- * Samples and records system CPU and memory utilization over time.
4
- *
5
- * This class continuously monitors system resource usage at regular intervals and stores
6
- * the samples in a format suitable for inclusion in Flakiness reports. Sampling starts
7
- * immediately upon construction and continues until `dispose()` is called.
8
- *
9
- * The first sample is collected after 50ms, and subsequent samples are collected every
10
- * 1000ms (1 second). CPU utilization is calculated as a percentage based on CPU tick
11
- * differences between samples. Memory utilization uses platform-specific methods for
12
- * accurate measurement (especially on macOS).
13
- */
14
- export declare class SystemUtilizationSampler {
15
- /**
16
- * The accumulated system utilization data.
17
- *
18
- * This object is populated as samples are collected and can be directly included in
19
- * Flakiness reports. It contains:
20
- * - `samples` - Array of utilization samples with CPU/memory percentages and durations
21
- * - `startTimestamp` - Timestamp when sampling began
22
- * - `totalMemoryBytes` - Total system memory in bytes
23
- */
24
- readonly result: FlakinessReport.SystemUtilization;
25
- private _lastSample;
26
- private _timer;
27
- /**
28
- * Creates a new SystemUtilizationSampler and starts sampling immediately.
29
- *
30
- * The first sample is collected after 50ms, and subsequent samples are collected
31
- * every 1000ms. Call `dispose()` to stop sampling and clean up resources.
32
- */
33
- constructor();
34
- private _addSample;
35
- /**
36
- * Stops sampling and cleans up resources.
37
- *
38
- * Call this method when you're done collecting utilization data to stop the sampling
39
- * timer and prevent memory leaks. The `result` object remains accessible after disposal.
40
- */
41
- dispose(): void;
42
- }
43
- //# sourceMappingURL=systemUtilizationSampler.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"systemUtilizationSampler.d.ts","sourceRoot":"","sources":["../../src/systemUtilizationSampler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AA6D9D;;;;;;;;;;;GAWG;AACH,qBAAa,wBAAwB;IACnC;;;;;;;;OAQG;IACH,SAAgB,MAAM,EAAE,eAAe,CAAC,iBAAiB,CAAC;IAE1D,OAAO,CAAC,WAAW,CAA0B;IAC7C,OAAO,CAAC,MAAM,CAAiB;IAE/B;;;;;OAKG;;IAWH,OAAO,CAAC,UAAU;IAOlB;;;;;OAKG;IACH,OAAO;CAGR"}