@uptimizr/db 1.0.1 → 2.0.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 (88) hide show
  1. package/AGENTS.md +103 -1
  2. package/README.md +100 -3
  3. package/dist/cli/createProject.js +23 -6
  4. package/dist/cli/createProject.js.map +1 -1
  5. package/dist/cli/seed.js +12 -4
  6. package/dist/cli/seed.js.map +1 -1
  7. package/dist/duckdb/audit.d.ts +13 -0
  8. package/dist/duckdb/audit.d.ts.map +1 -0
  9. package/dist/duckdb/audit.js +67 -0
  10. package/dist/duckdb/audit.js.map +1 -0
  11. package/dist/duckdb/client.d.ts.map +1 -1
  12. package/dist/duckdb/client.js +4 -0
  13. package/dist/duckdb/client.js.map +1 -1
  14. package/dist/duckdb/migrations.d.ts.map +1 -1
  15. package/dist/duckdb/migrations.js +97 -0
  16. package/dist/duckdb/migrations.js.map +1 -1
  17. package/dist/duckdb/projects.d.ts +9 -5
  18. package/dist/duckdb/projects.d.ts.map +1 -1
  19. package/dist/duckdb/projects.js +54 -24
  20. package/dist/duckdb/projects.js.map +1 -1
  21. package/dist/duckdb/queries.d.ts +7 -0
  22. package/dist/duckdb/queries.d.ts.map +1 -1
  23. package/dist/duckdb/queries.js +10 -1
  24. package/dist/duckdb/queries.js.map +1 -1
  25. package/dist/duckdb/sceneRegions.d.ts +24 -0
  26. package/dist/duckdb/sceneRegions.d.ts.map +1 -0
  27. package/dist/duckdb/sceneRegions.js +72 -0
  28. package/dist/duckdb/sceneRegions.js.map +1 -0
  29. package/dist/index.d.ts +8 -2
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +18 -1
  32. package/dist/index.js.map +1 -1
  33. package/dist/metadata.d.ts +195 -9
  34. package/dist/metadata.d.ts.map +1 -1
  35. package/dist/metadata.js +192 -0
  36. package/dist/metadata.js.map +1 -1
  37. package/dist/parity/compare.d.ts +22 -0
  38. package/dist/parity/compare.d.ts.map +1 -1
  39. package/dist/parity/compare.js +31 -0
  40. package/dist/parity/compare.js.map +1 -1
  41. package/dist/query/aggregations.d.ts +8 -0
  42. package/dist/query/aggregations.d.ts.map +1 -1
  43. package/dist/query/aggregations.js +78 -0
  44. package/dist/query/aggregations.js.map +1 -1
  45. package/dist/query/coerce.d.ts +94 -0
  46. package/dist/query/coerce.d.ts.map +1 -0
  47. package/dist/query/coerce.js +191 -0
  48. package/dist/query/coerce.js.map +1 -0
  49. package/dist/query/summary/cluster.d.ts +78 -0
  50. package/dist/query/summary/cluster.d.ts.map +1 -0
  51. package/dist/query/summary/cluster.js +200 -0
  52. package/dist/query/summary/cluster.js.map +1 -0
  53. package/dist/query/summary/columns.d.ts +66 -0
  54. package/dist/query/summary/columns.d.ts.map +1 -0
  55. package/dist/query/summary/columns.js +98 -0
  56. package/dist/query/summary/columns.js.map +1 -0
  57. package/dist/query/summary/format.d.ts +31 -0
  58. package/dist/query/summary/format.d.ts.map +1 -0
  59. package/dist/query/summary/format.js +119 -0
  60. package/dist/query/summary/format.js.map +1 -0
  61. package/dist/query/summary/index.d.ts +19 -0
  62. package/dist/query/summary/index.d.ts.map +1 -0
  63. package/dist/query/summary/index.js +16 -0
  64. package/dist/query/summary/index.js.map +1 -0
  65. package/dist/query/summary/reading.d.ts +26 -0
  66. package/dist/query/summary/reading.d.ts.map +1 -0
  67. package/dist/query/summary/reading.js +169 -0
  68. package/dist/query/summary/reading.js.map +1 -0
  69. package/dist/query/summary/schema.d.ts +217 -0
  70. package/dist/query/summary/schema.d.ts.map +1 -0
  71. package/dist/query/summary/schema.js +167 -0
  72. package/dist/query/summary/schema.js.map +1 -0
  73. package/dist/query/summary/stats.d.ts +33 -0
  74. package/dist/query/summary/stats.d.ts.map +1 -0
  75. package/dist/query/summary/stats.js +73 -0
  76. package/dist/query/summary/stats.js.map +1 -0
  77. package/dist/query/summary/summarize.d.ts +57 -0
  78. package/dist/query/summary/summarize.d.ts.map +1 -0
  79. package/dist/query/summary/summarize.js +424 -0
  80. package/dist/query/summary/summarize.js.map +1 -0
  81. package/dist/query/summary/types.d.ts +223 -0
  82. package/dist/query/summary/types.d.ts.map +1 -0
  83. package/dist/query/summary/types.js +8 -0
  84. package/dist/query/summary/types.js.map +1 -0
  85. package/dist/query/types.d.ts +13 -0
  86. package/dist/query/types.d.ts.map +1 -1
  87. package/llms.txt +7 -3
  88. package/package.json +10 -4
@@ -0,0 +1,33 @@
1
+ /**
2
+ * The two small statistics a summary needs: an interval on a share, and the
3
+ * slope of an ordered series. Both are pure, closed-form and deterministic —
4
+ * a summary must say the same thing every time it is asked.
5
+ */
6
+ import type { ShareInterval, TrendDirection } from "./types.js";
7
+ /** z for a two-sided 95% normal interval. */
8
+ export declare const Z_95 = 1.959963984540054;
9
+ /**
10
+ * **Wilson score interval** on a proportion.
11
+ *
12
+ * Used instead of the textbook normal approximation because a summary's shares
13
+ * are routinely extreme: a mesh with 3 clicks out of 9,130 has `p̂ ≈ 0.0003`,
14
+ * where `p̂ ± z·√(p̂(1-p̂)/n)` happily reaches below zero. Wilson stays inside
15
+ * `[0, 1]` and behaves at small `n`, which is exactly the regime an agent is
16
+ * most likely to over-read.
17
+ *
18
+ * Returns `null` when the proportion is not defined (no trials, or a count
19
+ * outside `0..trials` — which happens whenever the "total" is not really the
20
+ * denominator of the row, e.g. a truncated top-N list).
21
+ */
22
+ export declare function wilsonInterval(successes: number, trials: number, z?: number): ShareInterval | null;
23
+ /** The least-squares slope of `values` against their index; `null` under 2 points. */
24
+ export declare function leastSquaresSlope(values: readonly number[]): number | null;
25
+ /**
26
+ * Classify a slope as a direction.
27
+ *
28
+ * "Flat" is deliberately generous: the total drift across the series has to
29
+ * exceed 5% of the series' mean magnitude before it is called a trend, so
30
+ * ordinary sampling noise on a short range does not get reported as a move.
31
+ */
32
+ export declare function trendOf(values: readonly number[], slope: number | null): TrendDirection;
33
+ //# sourceMappingURL=stats.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../../src/query/summary/stats.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEhE,6CAA6C;AAC7C,eAAO,MAAM,IAAI,oBAAoB,CAAC;AAEtC;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,CAAC,GAAE,MAAa,GACf,aAAa,GAAG,IAAI,CAStB;AAED,sFAAsF;AACtF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAe1E;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,cAAc,CASvF"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * The two small statistics a summary needs: an interval on a share, and the
3
+ * slope of an ordered series. Both are pure, closed-form and deterministic —
4
+ * a summary must say the same thing every time it is asked.
5
+ */
6
+ /** z for a two-sided 95% normal interval. */
7
+ export const Z_95 = 1.959963984540054;
8
+ /**
9
+ * **Wilson score interval** on a proportion.
10
+ *
11
+ * Used instead of the textbook normal approximation because a summary's shares
12
+ * are routinely extreme: a mesh with 3 clicks out of 9,130 has `p̂ ≈ 0.0003`,
13
+ * where `p̂ ± z·√(p̂(1-p̂)/n)` happily reaches below zero. Wilson stays inside
14
+ * `[0, 1]` and behaves at small `n`, which is exactly the regime an agent is
15
+ * most likely to over-read.
16
+ *
17
+ * Returns `null` when the proportion is not defined (no trials, or a count
18
+ * outside `0..trials` — which happens whenever the "total" is not really the
19
+ * denominator of the row, e.g. a truncated top-N list).
20
+ */
21
+ export function wilsonInterval(successes, trials, z = Z_95) {
22
+ if (!Number.isFinite(successes) || !Number.isFinite(trials))
23
+ return null;
24
+ if (trials <= 0 || successes < 0 || successes > trials)
25
+ return null;
26
+ const p = successes / trials;
27
+ const z2 = z * z;
28
+ const denominator = 1 + z2 / trials;
29
+ const centre = (p + z2 / (2 * trials)) / denominator;
30
+ const margin = (z / denominator) * Math.sqrt((p * (1 - p)) / trials + z2 / (4 * trials * trials));
31
+ return { low: Math.max(0, centre - margin), high: Math.min(1, centre + margin) };
32
+ }
33
+ /** The least-squares slope of `values` against their index; `null` under 2 points. */
34
+ export function leastSquaresSlope(values) {
35
+ const n = values.length;
36
+ if (n < 2)
37
+ return null;
38
+ const meanX = (n - 1) / 2;
39
+ let meanY = 0;
40
+ for (const value of values)
41
+ meanY += value;
42
+ meanY /= n;
43
+ let covariance = 0;
44
+ let variance = 0;
45
+ for (let i = 0; i < n; i++) {
46
+ const dx = i - meanX;
47
+ covariance += dx * (values[i] - meanY);
48
+ variance += dx * dx;
49
+ }
50
+ return variance === 0 ? null : covariance / variance;
51
+ }
52
+ /**
53
+ * Classify a slope as a direction.
54
+ *
55
+ * "Flat" is deliberately generous: the total drift across the series has to
56
+ * exceed 5% of the series' mean magnitude before it is called a trend, so
57
+ * ordinary sampling noise on a short range does not get reported as a move.
58
+ */
59
+ export function trendOf(values, slope) {
60
+ if (slope == null || values.length < 2)
61
+ return "flat";
62
+ let magnitude = 0;
63
+ for (const value of values)
64
+ magnitude += Math.abs(value);
65
+ magnitude /= values.length;
66
+ const drift = Math.abs(slope) * (values.length - 1);
67
+ if (magnitude === 0)
68
+ return drift === 0 ? "flat" : slope > 0 ? "up" : "down";
69
+ if (drift < 0.05 * magnitude)
70
+ return "flat";
71
+ return slope > 0 ? "up" : "down";
72
+ }
73
+ //# sourceMappingURL=stats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.js","sourceRoot":"","sources":["../../../src/query/summary/stats.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * **Agent-shaped result envelopes** (ADR 0051 §2, design sketch §B.1).
3
+ *
4
+ * `summarizeRows(metric, rows, ctx)` and `tableResult(metric, rows, ctx)` are
5
+ * the two functions the collector calls to turn an aggregation's rows into the
6
+ * `table` and `summary` envelopes. They are pure, registry-driven and
7
+ * browser-safe: no store, no I/O, no `node:` import — everything they know about
8
+ * a metric comes from its {@link MetricDefinition}.
9
+ *
10
+ * ## Which summary a metric gets
11
+ *
12
+ * The `grain` decides, because the grain is what makes a row *mean* something:
13
+ *
14
+ * | grain | shape | what it reports |
15
+ * | -------------------------- | ----------- | -------------------------------------------- |
16
+ * | `bucket` | `series` | first/last/min/max, trend and slope |
17
+ * | `bin`, `voxel` | `clusters` | greedily merged hotspots (`cluster.ts`) |
18
+ * | `project` (or no `label`) | `record` | the single row, plus its `rateOf` rates |
19
+ * | everything else | `ranked` | top rows by the measure, with a `rest` bucket |
20
+ *
21
+ * A metric that cannot produce its grain's shape (a `bin` metric that declares
22
+ * too few `index` columns, say) falls back to `ranked`, so every metric always
23
+ * gets *a* summary.
24
+ *
25
+ * ## Shares are only claimed where they are true
26
+ *
27
+ * `total` and every `share` are reported only when the measure's unit is
28
+ * additive (`format.ts`). Summing FPS or a ratio across meshes produces a number
29
+ * that means nothing, and a share derived from it would be worse than no share
30
+ * at all — so those come back `null` and the `reading` says why.
31
+ *
32
+ * ## Bounded, always
33
+ *
34
+ * `top` and `clusters` are capped at the registry's `limits.maxSummaryRows`.
35
+ * That is the whole point of the envelope: a 500-bin heatmap must cost the same
36
+ * number of tokens as a 5-bin one.
37
+ */
38
+ import { type MetricDefinition, type MetricId } from "@uptimizr/metrics";
39
+ import type { ResultSummary, SummaryContext, TableResult } from "./types.js";
40
+ /** A row as it leaves a store: a flat bag of scalars. */
41
+ export type ResultRow = Readonly<Record<string, unknown>>;
42
+ /**
43
+ * `format=table`: the same rows as `full`, wrapped in a `meta` envelope that
44
+ * says what they are, what was asked for, how much data is behind them and
45
+ * whether the row cap hid any.
46
+ */
47
+ export declare function tableResult<Row extends ResultRow>(metric: MetricId | MetricDefinition, rows: readonly Row[], ctx?: SummaryContext): TableResult<Row> | null;
48
+ /**
49
+ * Summarise a metric's rows into the bounded `format=summary` envelope.
50
+ *
51
+ * `metric` may be a registry id or a resolved definition; an unknown id returns
52
+ * `null` so a caller can fall back to the raw rows rather than fail a request.
53
+ * `rows` must be the rows the store produced, already numerically coerced
54
+ * (every store runner does that at its edge — ADR 0051 §2).
55
+ */
56
+ export declare function summarizeRows(metric: MetricId | MetricDefinition, rows: readonly ResultRow[], ctx?: SummaryContext): ResultSummary | null;
57
+ //# sourceMappingURL=summarize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summarize.d.ts","sourceRoot":"","sources":["../../../src/query/summary/summarize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,EAAa,KAAK,gBAAgB,EAAE,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAiBpF,OAAO,KAAK,EAUV,aAAa,EAKb,cAAc,EAEd,WAAW,EACZ,MAAM,YAAY,CAAC;AAEpB,yDAAyD;AACzD,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAmH1D;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,SAAS,SAAS,EAC/C,MAAM,EAAE,QAAQ,GAAG,gBAAgB,EACnC,IAAI,EAAE,SAAS,GAAG,EAAE,EACpB,GAAG,GAAE,cAAmB,GACvB,WAAW,CAAC,GAAG,CAAC,GAAG,IAAI,CAezB;AA+RD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,QAAQ,GAAG,gBAAgB,EACnC,IAAI,EAAE,SAAS,SAAS,EAAE,EAC1B,GAAG,GAAE,cAAmB,GACvB,aAAa,GAAG,IAAI,CAkBtB"}
@@ -0,0 +1,424 @@
1
+ /**
2
+ * **Agent-shaped result envelopes** (ADR 0051 §2, design sketch §B.1).
3
+ *
4
+ * `summarizeRows(metric, rows, ctx)` and `tableResult(metric, rows, ctx)` are
5
+ * the two functions the collector calls to turn an aggregation's rows into the
6
+ * `table` and `summary` envelopes. They are pure, registry-driven and
7
+ * browser-safe: no store, no I/O, no `node:` import — everything they know about
8
+ * a metric comes from its {@link MetricDefinition}.
9
+ *
10
+ * ## Which summary a metric gets
11
+ *
12
+ * The `grain` decides, because the grain is what makes a row *mean* something:
13
+ *
14
+ * | grain | shape | what it reports |
15
+ * | -------------------------- | ----------- | -------------------------------------------- |
16
+ * | `bucket` | `series` | first/last/min/max, trend and slope |
17
+ * | `bin`, `voxel` | `clusters` | greedily merged hotspots (`cluster.ts`) |
18
+ * | `project` (or no `label`) | `record` | the single row, plus its `rateOf` rates |
19
+ * | everything else | `ranked` | top rows by the measure, with a `rest` bucket |
20
+ *
21
+ * A metric that cannot produce its grain's shape (a `bin` metric that declares
22
+ * too few `index` columns, say) falls back to `ranked`, so every metric always
23
+ * gets *a* summary.
24
+ *
25
+ * ## Shares are only claimed where they are true
26
+ *
27
+ * `total` and every `share` are reported only when the measure's unit is
28
+ * additive (`format.ts`). Summing FPS or a ratio across meshes produces a number
29
+ * that means nothing, and a share derived from it would be worse than no share
30
+ * at all — so those come back `null` and the `reading` says why.
31
+ *
32
+ * ## Bounded, always
33
+ *
34
+ * `top` and `clusters` are capped at the registry's `limits.maxSummaryRows`.
35
+ * That is the whole point of the envelope: a 500-bin heatmap must cost the same
36
+ * number of tokens as a 5-bin one.
37
+ */
38
+ import { getMetric } from "@uptimizr/metrics";
39
+ import { clusterCells } from "./cluster.js";
40
+ import { axisColumn, columnsOf, gridColumns, labelColumn, measureColumn, numberAt, sampleSizeOf, sumColumn, weightColumn, } from "./columns.js";
41
+ import { isAdditiveUnit } from "./format.js";
42
+ import { readingFor } from "./reading.js";
43
+ import { leastSquaresSlope, trendOf, wilsonInterval, Z_95 } from "./stats.js";
44
+ /**
45
+ * Filters a summarised row can be narrowed by. Restricted to the filters the
46
+ * metric itself accepts, so every hint is directly actionable — a hint an
47
+ * endpoint would silently ignore is worse than no hint.
48
+ */
49
+ const DRILL_FILTERS = ["scene", "session", "mesh", "source"];
50
+ /** Resolve an id or a definition to a definition. */
51
+ function resolve(metric) {
52
+ return typeof metric === "string" ? getMetric(metric) : metric;
53
+ }
54
+ /** The requested window, normalised to `null` where the caller omitted it. */
55
+ function rangeOf(ctx) {
56
+ return { since: ctx.range?.since ?? null, until: ctx.range?.until ?? null };
57
+ }
58
+ /**
59
+ * Applied filters with `format` and anything unset stripped. Iterates the
60
+ * metric's **declared** filter and path-parameter ids (a closed registry
61
+ * allowlist) rather than the keys of the request object, so an unexpected key
62
+ * can never become a property of the envelope.
63
+ */
64
+ function filtersOf(metric, ctx) {
65
+ const out = {};
66
+ const source = ctx.filters ?? {};
67
+ const declared = [...metric.filters, ...(metric.endpoint?.pathParams ?? [])];
68
+ for (const id of declared) {
69
+ if (id === "format")
70
+ continue;
71
+ const value = Object.hasOwn(source, id) ? source[id] : undefined;
72
+ if (value === undefined || value === null)
73
+ continue;
74
+ out[id] = value;
75
+ }
76
+ return out;
77
+ }
78
+ function limitsOf(metric) {
79
+ return { maxRows: metric.limits.maxRows, maxSummaryRows: metric.limits.maxSummaryRows };
80
+ }
81
+ /** Whether the row cap was reached, so more rows may exist behind it. */
82
+ function isTruncated(metric, rows, ctx) {
83
+ const cap = ctx.limit ?? metric.limits.maxRows;
84
+ return Number.isFinite(cap) && rows.length >= cap;
85
+ }
86
+ /** What `total` counts, and whether it may be summed at all. */
87
+ function measureOf(column) {
88
+ if (column == null)
89
+ return null;
90
+ const [name, semantics] = column;
91
+ return { column: name, unit: semantics.unit ?? null, additive: isAdditiveUnit(semantics.unit) };
92
+ }
93
+ /** Registry caveats plus the ones that are only true of *this* result. */
94
+ function caveatsFor(metric, rows, ctx, extra = []) {
95
+ const caveats = [...metric.caveats, ...extra, ...(ctx.caveats ?? [])];
96
+ if (rows.length === 0) {
97
+ caveats.push("No rows matched the selected range and filters — read this as 'no data', not as zero.");
98
+ }
99
+ if (isTruncated(metric, rows, ctx)) {
100
+ caveats.push(`Rows were capped at ${ctx.limit ?? metric.limits.maxRows}; totals and shares below describe ` +
101
+ "the returned rows only, not the whole range.");
102
+ }
103
+ return caveats;
104
+ }
105
+ /** Filters that would narrow a subsequent query to this row. */
106
+ function drillFor(metric, row) {
107
+ const hints = {};
108
+ for (const filter of DRILL_FILTERS) {
109
+ if (!metric.filters.includes(filter))
110
+ continue;
111
+ const column = [filter, `${filter}_id`].find((candidate) => candidate in metric.columns && candidate in row);
112
+ if (column == null)
113
+ continue;
114
+ const value = row[column];
115
+ if (typeof value === "string" && value.length > 0)
116
+ hints[filter] = value;
117
+ }
118
+ return Object.keys(hints).length > 0 ? hints : undefined;
119
+ }
120
+ /** The Wilson note, present only when the shares really are proportions. */
121
+ function confidenceFor(measure, total) {
122
+ if (measure == null || !measure.additive || total == null || total <= 0)
123
+ return undefined;
124
+ if (measure.unit !== "count" && measure.unit !== "sessions")
125
+ return undefined;
126
+ const noun = measure.unit === "sessions" ? "sessions" : "events";
127
+ return {
128
+ kind: "wilson",
129
+ level: 0.95,
130
+ note: `Shares are proportions of ${total} ${noun}; each \`shareInterval\` is a 95% Wilson score ` +
131
+ "interval, which stays inside 0..1 at the small counts a long tail produces.",
132
+ };
133
+ }
134
+ // --- table ----------------------------------------------------------------
135
+ /**
136
+ * `format=table`: the same rows as `full`, wrapped in a `meta` envelope that
137
+ * says what they are, what was asked for, how much data is behind them and
138
+ * whether the row cap hid any.
139
+ */
140
+ export function tableResult(metric, rows, ctx = {}) {
141
+ const definition = resolve(metric);
142
+ if (definition == null)
143
+ return null;
144
+ return {
145
+ meta: {
146
+ metric: definition.id,
147
+ range: rangeOf(ctx),
148
+ filters: filtersOf(definition, ctx),
149
+ sampleSize: sampleSizeOf(definition, rows),
150
+ rows: rows.length,
151
+ truncated: isTruncated(definition, rows, ctx),
152
+ limits: limitsOf(definition),
153
+ },
154
+ rows,
155
+ };
156
+ }
157
+ // --- summary --------------------------------------------------------------
158
+ /** Fields every summary shares, computed once. */
159
+ function baseOf(metric, rows, ctx, measure, total, extraCaveats = []) {
160
+ const confidence = confidenceFor(measure, total);
161
+ return {
162
+ metric: metric.id,
163
+ range: rangeOf(ctx),
164
+ filters: filtersOf(metric, ctx),
165
+ sampleSize: sampleSizeOf(metric, rows),
166
+ total,
167
+ measure,
168
+ ...(confidence != null ? { confidence } : {}),
169
+ caveats: caveatsFor(metric, rows, ctx, extraCaveats),
170
+ };
171
+ }
172
+ function rankedSummary(metric, rows, ctx, cap) {
173
+ const measureCol = measureColumn(metric);
174
+ const labelCol = labelColumn(metric);
175
+ const measure = measureOf(measureCol);
176
+ const total = measure?.additive === true ? sumColumn(rows, measureCol?.[0]) : null;
177
+ // Rank by the measure, highest first; ties fall back to the label so the order
178
+ // is a function of the row *set* rather than of what the store happened to emit.
179
+ const ordered = [...rows].sort((a, b) => {
180
+ const left = measureCol == null ? null : numberAt(a, measureCol[0]);
181
+ const right = measureCol == null ? null : numberAt(b, measureCol[0]);
182
+ if (left !== right) {
183
+ if (left == null)
184
+ return 1;
185
+ if (right == null)
186
+ return -1;
187
+ return right - left;
188
+ }
189
+ const leftLabel = labelCol == null ? "" : String(a[labelCol[0]] ?? "");
190
+ const rightLabel = labelCol == null ? "" : String(b[labelCol[0]] ?? "");
191
+ return leftLabel < rightLabel ? -1 : leftLabel > rightLabel ? 1 : 0;
192
+ });
193
+ const listed = ordered.slice(0, cap);
194
+ // A Wilson interval is only meaningful where the share really is a proportion
195
+ // of a count — the same condition that decides whether `confidence` is present.
196
+ const proportional = confidenceFor(measure, total) != null;
197
+ const top = listed.map((row) => {
198
+ const value = measureCol == null ? null : numberAt(row, measureCol[0]);
199
+ const share = total != null && total > 0 && value != null ? value / total : null;
200
+ const interval = proportional && value != null && total != null ? wilsonInterval(value, total, Z_95) : null;
201
+ const drill = drillFor(metric, row);
202
+ return {
203
+ label: labelCol == null ? "" : String(row[labelCol[0]] ?? ""),
204
+ value,
205
+ share,
206
+ ...(interval != null ? { shareInterval: interval } : {}),
207
+ ...(drill != null ? { drill } : {}),
208
+ };
209
+ });
210
+ const listedValue = measureCol == null ? null : sumColumn(listed, measureCol[0]);
211
+ const restValue = total != null && listedValue != null ? total - listedValue : null;
212
+ return {
213
+ ...baseOf(metric, rows, ctx, measure, total),
214
+ kind: "ranked",
215
+ top,
216
+ rest: {
217
+ rows: Math.max(0, rows.length - listed.length),
218
+ value: restValue,
219
+ share: total != null && total > 0 && restValue != null ? restValue / total : null,
220
+ },
221
+ };
222
+ }
223
+ function seriesSummary(metric, rows, ctx) {
224
+ const axis = axisColumn(metric);
225
+ const measureCol = measureColumn(metric);
226
+ if (axis == null || measureCol == null)
227
+ return null;
228
+ const measure = measureOf(measureCol);
229
+ // Collapse every row sharing a bucket. Additive measures sum (`mesh_trend` is
230
+ // one row per mesh *and* bucket); non-additive ones average, because adding
231
+ // two days' median FPS together would be meaningless.
232
+ const buckets = new Map();
233
+ for (const row of rows) {
234
+ const key = row[axis[0]];
235
+ const value = numberAt(row, measureCol[0]);
236
+ if (value == null)
237
+ continue;
238
+ const id = typeof key === "number" ? `n:${key}` : `s:${String(key ?? "")}`;
239
+ const bucket = buckets.get(id);
240
+ if (bucket) {
241
+ bucket.sum += value;
242
+ bucket.count += 1;
243
+ }
244
+ else {
245
+ buckets.set(id, { key, sum: value, count: 1 });
246
+ }
247
+ }
248
+ const points = [...buckets.values()]
249
+ .map((bucket) => ({
250
+ key: bucket.key,
251
+ value: measure?.additive === true ? bucket.sum : bucket.sum / bucket.count,
252
+ }))
253
+ .sort((a, b) => {
254
+ if (typeof a.key === "number" && typeof b.key === "number")
255
+ return a.key - b.key;
256
+ const left = String(a.key ?? "");
257
+ const right = String(b.key ?? "");
258
+ return left < right ? -1 : left > right ? 1 : 0;
259
+ });
260
+ const values = points.map((point) => point.value);
261
+ const slope = leastSquaresSlope(values);
262
+ const lowest = points.reduce((best, point) => (best == null || point.value < best.value ? point : best), undefined);
263
+ const highest = points.reduce((best, point) => (best == null || point.value > best.value ? point : best), undefined);
264
+ const first = points[0];
265
+ const last = points[points.length - 1];
266
+ const total = measure?.additive === true ? sumColumn(rows, measureCol[0]) : null;
267
+ const labelOf = (point) => point == null ? null : point.key == null ? null : String(point.key);
268
+ return {
269
+ ...baseOf(metric, rows, ctx, measure, total),
270
+ kind: "series",
271
+ series: {
272
+ axis: axis[0],
273
+ points: points.length,
274
+ first: first?.value ?? null,
275
+ last: last?.value ?? null,
276
+ min: lowest?.value ?? null,
277
+ max: highest?.value ?? null,
278
+ firstLabel: labelOf(first),
279
+ lastLabel: labelOf(last),
280
+ minLabel: labelOf(lowest),
281
+ maxLabel: labelOf(highest),
282
+ trend: trendOf(values, slope),
283
+ slope,
284
+ },
285
+ };
286
+ }
287
+ function clusterSummary(metric, rows, ctx, cap) {
288
+ const axes = gridColumns(metric, metric.grain === "voxel" ? 3 : 2);
289
+ const weightCol = weightColumn(metric);
290
+ if (axes == null || weightCol == null)
291
+ return null;
292
+ const measure = measureOf(weightCol);
293
+ if (measure == null || !measure.additive)
294
+ return null;
295
+ const cells = [];
296
+ for (const row of rows) {
297
+ const coords = axes.map(([name]) => numberAt(row, name));
298
+ if (coords.some((coordinate) => coordinate == null))
299
+ continue;
300
+ const weight = numberAt(row, weightCol[0]);
301
+ if (weight == null)
302
+ continue;
303
+ cells.push({ coords: coords, weight });
304
+ }
305
+ const result = clusterCells(cells, {
306
+ densityThreshold: ctx.densityThreshold,
307
+ maxClusters: cap,
308
+ });
309
+ const total = result.totalWeight > 0 ? result.totalWeight : null;
310
+ // A cluster's world-space box, when the collector told us the effective cell
311
+ // size and the metric accepts a `region` drill-down (ADR 0040 §4).
312
+ const canDrillRegion = ctx.cellSize != null &&
313
+ ctx.cellSize > 0 &&
314
+ axes.length === 3 &&
315
+ metric.filters.includes("region");
316
+ const clusters = result.clusters.map((cluster) => {
317
+ if (!canDrillRegion)
318
+ return cluster;
319
+ const size = ctx.cellSize;
320
+ const box = [
321
+ ...cluster.extent.min.map((value) => value * size),
322
+ ...cluster.extent.max.map((value) => (value + 1) * size),
323
+ ];
324
+ return { ...cluster, drill: { region: box.join(",") } };
325
+ });
326
+ const extraCaveats = result.occupiedCells > 0
327
+ ? [
328
+ `Hotspots are merged from cells at or above a density threshold of ` +
329
+ `${result.densityThreshold} (the mean weight per occupied cell); looser cells are ` +
330
+ "reported in `rest` rather than clustered.",
331
+ "Cluster coordinates are grid indices, not world coordinates — multiply by the " +
332
+ "effective `cellSize` to place them (ADR 0040 §1). Spatial labelling (nearest mesh, " +
333
+ "named region) is not part of this envelope.",
334
+ ]
335
+ : [];
336
+ return {
337
+ ...baseOf(metric, rows, ctx, measure, total, extraCaveats),
338
+ kind: "clusters",
339
+ axes: axes.map(([name]) => name),
340
+ occupiedCells: result.occupiedCells,
341
+ densityThreshold: result.densityThreshold,
342
+ clusters,
343
+ rest: {
344
+ clusters: result.rest.clusters,
345
+ cells: result.rest.cells,
346
+ weight: total == null ? null : result.rest.weight,
347
+ share: total != null && total > 0 ? result.rest.weight / total : null,
348
+ },
349
+ };
350
+ }
351
+ function recordSummary(metric, rows, ctx) {
352
+ const row = rows[0];
353
+ const measureCol = measureColumn(metric);
354
+ const measure = measureOf(measureCol);
355
+ const record = {};
356
+ if (row != null) {
357
+ for (const [name] of columnsOf(metric)) {
358
+ if (!(name in row))
359
+ continue;
360
+ const value = row[name];
361
+ record[name] =
362
+ value == null
363
+ ? null
364
+ : typeof value === "number" || typeof value === "string" || typeof value === "boolean"
365
+ ? value
366
+ : null;
367
+ }
368
+ }
369
+ // Every column that declares itself a rate of another one, resolved against
370
+ // the row — the numbers a reader would otherwise have to divide by hand.
371
+ const rates = {};
372
+ for (const [name, semantics] of columnsOf(metric)) {
373
+ if (semantics.rateOf == null || row == null)
374
+ continue;
375
+ const numerator = numberAt(row, name);
376
+ const denominator = numberAt(row, semantics.rateOf);
377
+ rates[name] = {
378
+ value: numerator != null && denominator != null && denominator > 0
379
+ ? numerator / denominator
380
+ : null,
381
+ numerator: name,
382
+ denominator: semantics.rateOf,
383
+ };
384
+ }
385
+ const total = row == null || measureCol == null ? null : numberAt(row, measureCol[0]);
386
+ const extra = rows.length > 1
387
+ ? [`Only the first of ${rows.length} rows is summarised; read \`format=table\` for the rest.`]
388
+ : [];
389
+ return {
390
+ ...baseOf(metric, rows, ctx, measure, total, extra),
391
+ kind: "record",
392
+ record,
393
+ rates,
394
+ };
395
+ }
396
+ /**
397
+ * Summarise a metric's rows into the bounded `format=summary` envelope.
398
+ *
399
+ * `metric` may be a registry id or a resolved definition; an unknown id returns
400
+ * `null` so a caller can fall back to the raw rows rather than fail a request.
401
+ * `rows` must be the rows the store produced, already numerically coerced
402
+ * (every store runner does that at its edge — ADR 0051 §2).
403
+ */
404
+ export function summarizeRows(metric, rows, ctx = {}) {
405
+ const definition = resolve(metric);
406
+ if (definition == null)
407
+ return null;
408
+ const cap = Math.max(0, ctx.maxRows ?? definition.limits.maxSummaryRows);
409
+ let summary = null;
410
+ if (definition.grain === "bucket") {
411
+ summary = seriesSummary(definition, rows, ctx);
412
+ }
413
+ else if (definition.grain === "bin" || definition.grain === "voxel") {
414
+ summary = clusterSummary(definition, rows, ctx, cap);
415
+ }
416
+ else if (definition.grain === "project" || labelColumn(definition) == null) {
417
+ summary = recordSummary(definition, rows, ctx);
418
+ }
419
+ // Leaderboards, and the fallback for any metric that cannot produce its
420
+ // grain's shape (too few `index` columns, no axis, a non-additive weight).
421
+ summary ??= rankedSummary(definition, rows, ctx, cap);
422
+ return { ...summary, reading: readingFor(definition, summary) };
423
+ }
424
+ //# sourceMappingURL=summarize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summarize.js","sourceRoot":"","sources":["../../../src/query/summary/summarize.ts"],"names":[],"mappings":"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"}