@adriangalilea/utils 4.0.0 → 4.1.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/README.md +11 -0
- package/dist/metrics/cli.d.ts +3 -1
- package/dist/metrics/cli.d.ts.map +1 -1
- package/dist/metrics/cli.js +55 -1
- package/dist/metrics/cli.js.map +1 -1
- package/dist/metrics/report.d.ts +34 -0
- package/dist/metrics/report.d.ts.map +1 -1
- package/dist/metrics/report.js +59 -0
- package/dist/metrics/report.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,6 +26,17 @@ Readers propagate database errors rather than presenting missing data as zero.
|
|
|
26
26
|
`renderMetrics(rows, { daily? })` from `metrics/cli` renders it with the existing
|
|
27
27
|
ANSI-aware `cli.table` helpers. Both discover every recorded metric from its
|
|
28
28
|
declaration metadata. No product-specific metric list belongs in a renderer.
|
|
29
|
+
|
|
30
|
+
For period comparisons, `metricWindows(days, { now?, includeToday? })` from
|
|
31
|
+
`metrics/report` returns adjacent equal-length `current` and `previous` UTC ranges.
|
|
32
|
+
By default both contain completed days; `includeToday` marks the current window
|
|
33
|
+
`partial`. Fetch those ranges through your adapter, then call
|
|
34
|
+
`compareMetrics(currentRows, previousRows)` and
|
|
35
|
+
`renderMetricComparison(comparisons)` from `metrics/cli`. Comparisons include
|
|
36
|
+
disappearing series, count changes and weighted timing-average changes. Percent
|
|
37
|
+
change is null without a nonzero baseline; missing timing samples stay null.
|
|
38
|
+
Changing a metric's kind or unit across the inputs is rejected. Missing observations
|
|
39
|
+
are not proof that collection was running: deltas compare recorded data only.
|
|
29
40
|
The SQL adapter accepts a libSQL-compatible client; D1 or another store can implement
|
|
30
41
|
the injected `write(measurement)` contract instead. No database client is bundled.
|
|
31
42
|
|
package/dist/metrics/cli.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { type DailyMetric } from "./report.js";
|
|
1
|
+
import { type DailyMetric, type MetricComparison } from "./report.js";
|
|
2
|
+
/** Neutral deltas: increasing a metric does not necessarily mean improvement. */
|
|
3
|
+
export declare function renderMetricComparison(comparisons: readonly MetricComparison[]): string;
|
|
2
4
|
/** Render declarations stored beside observations; adding a metric requires no panel edit. */
|
|
3
5
|
export declare function renderMetrics(rows: readonly DailyMetric[], options?: {
|
|
4
6
|
daily?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/metrics/cli.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/metrics/cli.ts"],"names":[],"mappings":"AACA,OAAO,EACN,KAAK,WAAW,EAEhB,KAAK,gBAAgB,EAErB,MAAM,aAAa,CAAC;AAErB,iFAAiF;AACjF,wBAAgB,sBAAsB,CACrC,WAAW,EAAE,SAAS,gBAAgB,EAAE,GACtC,MAAM,CA2DR;AAED,8FAA8F;AAC9F,wBAAgB,aAAa,CAC5B,IAAI,EAAE,SAAS,WAAW,EAAE,EAC5B,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAC/B,MAAM,CAoDR"}
|
package/dist/metrics/cli.js
CHANGED
|
@@ -1,5 +1,59 @@
|
|
|
1
1
|
import { table, ui } from "../cli/index.js";
|
|
2
|
-
import { summarizeMetrics } from "./report.js";
|
|
2
|
+
import { summarizeMetrics, } from "./report.js";
|
|
3
|
+
/** Neutral deltas: increasing a metric does not necessarily mean improvement. */
|
|
4
|
+
export function renderMetricComparison(comparisons) {
|
|
5
|
+
if (!comparisons.length)
|
|
6
|
+
return "No recorded measurements in either window.";
|
|
7
|
+
const number = (n) => new Intl.NumberFormat("en-US", { maximumFractionDigits: 2 }).format(n);
|
|
8
|
+
const signed = (n) => `${n > 0 ? "+" : ""}${number(n)}`;
|
|
9
|
+
const delta = (value) => `${signed(value.absolute)} (${value.percent === null ? "no baseline" : `${signed(value.percent)}%`})`;
|
|
10
|
+
const groups = new Map();
|
|
11
|
+
for (const row of comparisons) {
|
|
12
|
+
const key = JSON.stringify([row.project, row.key]);
|
|
13
|
+
const group = groups.get(key) ?? [];
|
|
14
|
+
group.push(row);
|
|
15
|
+
groups.set(key, group);
|
|
16
|
+
}
|
|
17
|
+
return [...groups.values()]
|
|
18
|
+
.map((group) => {
|
|
19
|
+
const timing = group[0].kind === "timing";
|
|
20
|
+
const average = (n) => n == null ? "—" : `${number(n)} ${group[0].unit}`.trim();
|
|
21
|
+
return [
|
|
22
|
+
ui.head(`${group[0].project} · ${group[0].label}${timing ? " (samples)" : ""}`),
|
|
23
|
+
table(group.map((r) => [
|
|
24
|
+
Object.entries(r.dimensions)
|
|
25
|
+
.map(([k, v]) => `${k}=${v}`)
|
|
26
|
+
.join(" · ") || "all",
|
|
27
|
+
number(r.current?.count ?? 0),
|
|
28
|
+
number(r.previous?.count ?? 0),
|
|
29
|
+
delta(r.countChange),
|
|
30
|
+
...(timing
|
|
31
|
+
? [
|
|
32
|
+
average(r.current?.average),
|
|
33
|
+
average(r.previous?.average),
|
|
34
|
+
r.averageChange ? delta(r.averageChange) : "—",
|
|
35
|
+
]
|
|
36
|
+
: []),
|
|
37
|
+
]), {
|
|
38
|
+
head: [
|
|
39
|
+
"breakdown",
|
|
40
|
+
"current",
|
|
41
|
+
"previous",
|
|
42
|
+
"change",
|
|
43
|
+
...(timing ? ["avg current", "avg previous", "avg change"] : []),
|
|
44
|
+
],
|
|
45
|
+
align: [
|
|
46
|
+
"l",
|
|
47
|
+
"r",
|
|
48
|
+
"r",
|
|
49
|
+
"r",
|
|
50
|
+
...(timing ? ["r", "r", "r"] : []),
|
|
51
|
+
],
|
|
52
|
+
}),
|
|
53
|
+
].join("\n");
|
|
54
|
+
})
|
|
55
|
+
.join("\n\n");
|
|
56
|
+
}
|
|
3
57
|
/** Render declarations stored beside observations; adding a metric requires no panel edit. */
|
|
4
58
|
export function renderMetrics(rows, options = {}) {
|
|
5
59
|
if (!rows.length)
|
package/dist/metrics/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/metrics/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/metrics/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/metrics/report.d.ts
CHANGED
|
@@ -22,6 +22,40 @@ export interface MetricTotal {
|
|
|
22
22
|
sum: number;
|
|
23
23
|
average: number | null;
|
|
24
24
|
}
|
|
25
|
+
export interface MetricChange {
|
|
26
|
+
absolute: number;
|
|
27
|
+
/** Null when a percentage has no nonzero baseline. */
|
|
28
|
+
percent: number | null;
|
|
29
|
+
}
|
|
30
|
+
export interface MetricComparison {
|
|
31
|
+
project: string;
|
|
32
|
+
key: string;
|
|
33
|
+
label: string;
|
|
34
|
+
kind: string;
|
|
35
|
+
unit: string;
|
|
36
|
+
dimensions: Record<string, string>;
|
|
37
|
+
current: MetricTotal | null;
|
|
38
|
+
previous: MetricTotal | null;
|
|
39
|
+
countChange: MetricChange;
|
|
40
|
+
averageChange: MetricChange | null;
|
|
41
|
+
}
|
|
42
|
+
/** Adjacent equal-length UTC windows; completed days by default. */
|
|
43
|
+
export declare function metricWindows(days: number, options?: {
|
|
44
|
+
now?: Date;
|
|
45
|
+
includeToday?: boolean;
|
|
46
|
+
}): {
|
|
47
|
+
current: {
|
|
48
|
+
from: string;
|
|
49
|
+
to: string;
|
|
50
|
+
};
|
|
51
|
+
previous: {
|
|
52
|
+
from: string;
|
|
53
|
+
to: string;
|
|
54
|
+
};
|
|
55
|
+
partial: boolean;
|
|
56
|
+
};
|
|
57
|
+
/** Compare recorded observations; absent series have zero counts, never zero latency. */
|
|
58
|
+
export declare function compareMetrics(current: readonly DailyMetric[], previous: readonly DailyMetric[]): MetricComparison[];
|
|
25
59
|
/** One report shape for terminal and web. No product names or metric lists. */
|
|
26
60
|
export declare function summarizeMetrics(rows: readonly DailyMetric[]): MetricTotal[];
|
|
27
61
|
//# sourceMappingURL=report.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/metrics/report.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,MAAM,WAAW,WAAW;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,WAAW;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,+EAA+E;AAC/E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,GAAG,WAAW,EAAE,CAiC5E"}
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/metrics/report.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,MAAM,WAAW,WAAW;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,WAAW;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAC;IAC7B,WAAW,EAAE,YAAY,CAAC;IAC1B,aAAa,EAAE,YAAY,GAAG,IAAI,CAAC;CACnC;AAED,oEAAoE;AACpE,wBAAgB,aAAa,CAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,IAAI,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,CAAA;CAAO;;;;;;;;;;EAkBpD;AASD,yFAAyF;AACzF,wBAAgB,cAAc,CAC7B,OAAO,EAAE,SAAS,WAAW,EAAE,EAC/B,QAAQ,EAAE,SAAS,WAAW,EAAE,GAC9B,gBAAgB,EAAE,CA4CpB;AAED,+EAA+E;AAC/E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,GAAG,WAAW,EAAE,CAiC5E"}
|
package/dist/metrics/report.js
CHANGED
|
@@ -1,3 +1,62 @@
|
|
|
1
|
+
/** Adjacent equal-length UTC windows; completed days by default. */
|
|
2
|
+
export function metricWindows(days, options = {}) {
|
|
3
|
+
if (!Number.isInteger(days) || days < 1 || days > 3660)
|
|
4
|
+
throw new Error("metrics: window must be 1–3660 days");
|
|
5
|
+
const day = 86_400_000;
|
|
6
|
+
const today = Date.parse((options.now ?? new Date()).toISOString().slice(0, 10));
|
|
7
|
+
const end = today - (options.includeToday ? 0 : day);
|
|
8
|
+
const iso = (value) => new Date(value).toISOString().slice(0, 10);
|
|
9
|
+
return {
|
|
10
|
+
current: { from: iso(end - (days - 1) * day), to: iso(end) },
|
|
11
|
+
previous: {
|
|
12
|
+
from: iso(end - (2 * days - 1) * day),
|
|
13
|
+
to: iso(end - days * day),
|
|
14
|
+
},
|
|
15
|
+
partial: options.includeToday === true,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
const seriesKey = (row) => JSON.stringify([
|
|
19
|
+
row.project,
|
|
20
|
+
row.key,
|
|
21
|
+
Object.entries(row.dimensions).sort(([a], [b]) => a.localeCompare(b)),
|
|
22
|
+
]);
|
|
23
|
+
/** Compare recorded observations; absent series have zero counts, never zero latency. */
|
|
24
|
+
export function compareMetrics(current, previous) {
|
|
25
|
+
const now = new Map(summarizeMetrics(current).map((row) => [seriesKey(row), row]));
|
|
26
|
+
const before = new Map(summarizeMetrics(previous).map((row) => [seriesKey(row), row]));
|
|
27
|
+
const change = (a, b) => ({
|
|
28
|
+
absolute: a - b,
|
|
29
|
+
percent: b === 0 ? (a === 0 ? 0 : null) : ((a - b) / b) * 100,
|
|
30
|
+
});
|
|
31
|
+
return [...new Set([...now.keys(), ...before.keys()])]
|
|
32
|
+
.map((key) => {
|
|
33
|
+
const a = now.get(key) ?? null;
|
|
34
|
+
const b = before.get(key) ?? null;
|
|
35
|
+
const metadata = a ?? b;
|
|
36
|
+
if (!metadata)
|
|
37
|
+
throw new Error("metrics: missing comparison series");
|
|
38
|
+
if (a && b && (a.kind !== b.kind || a.unit !== b.unit))
|
|
39
|
+
throw new Error(`metrics: changed meaning for ${metadata.project}.${metadata.key}; use a new key`);
|
|
40
|
+
return {
|
|
41
|
+
project: metadata.project,
|
|
42
|
+
key: metadata.key,
|
|
43
|
+
label: metadata.label,
|
|
44
|
+
kind: metadata.kind,
|
|
45
|
+
unit: metadata.unit,
|
|
46
|
+
dimensions: metadata.dimensions,
|
|
47
|
+
current: a,
|
|
48
|
+
previous: b,
|
|
49
|
+
countChange: change(a?.count ?? 0, b?.count ?? 0),
|
|
50
|
+
averageChange: a?.average != null && b?.average != null
|
|
51
|
+
? change(a.average, b.average)
|
|
52
|
+
: null,
|
|
53
|
+
};
|
|
54
|
+
})
|
|
55
|
+
.sort((a, b) => a.project.localeCompare(b.project) ||
|
|
56
|
+
a.key.localeCompare(b.key) ||
|
|
57
|
+
Math.abs(b.countChange.absolute) - Math.abs(a.countChange.absolute) ||
|
|
58
|
+
seriesKey(a).localeCompare(seriesKey(b)));
|
|
59
|
+
}
|
|
1
60
|
/** One report shape for terminal and web. No product names or metric lists. */
|
|
2
61
|
export function summarizeMetrics(rows) {
|
|
3
62
|
const totals = new Map();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/metrics/report.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/metrics/report.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED