@adriangalilea/utils 5.0.0 → 7.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.
package/README.md CHANGED
@@ -8,35 +8,45 @@ TypeScript utilities - logger, currency, offensive programming, file operations,
8
8
  import { createClient } from "@libsql/client"
9
9
  import { defineMetrics } from "@adriangalilea/utils/metrics"
10
10
  import { libsqlDriver } from "@adriangalilea/utils/metrics/libsql"
11
- import { metricsWriter } from "@adriangalilea/utils/metrics/sqlite"
11
+ import { metricsStore } from "@adriangalilea/utils/metrics/sqlite"
12
12
 
13
13
  const driver = libsqlDriver(createClient({ url: process.env.METRICS_DATABASE_URL!, authToken: process.env.METRICS_AUTH_TOKEN }))
14
14
  const metrics = defineMetrics({
15
15
  installCopy: { kind: "counter", label: "install command copies", dimensions: { component: ["chat", "glass"] } },
16
- }, { write: metricsWriter(driver, "my-project") })
16
+ }, { store: metricsStore(driver, "my-project") })
17
17
 
18
18
  await metrics.installCopy.bump({ dimensions: { component: "chat" } })
19
19
  ```
20
20
 
21
- One SQLite dialect, many stores. `metrics/sqlite` holds the schema, the writer and
21
+ One SQLite dialect, many stores. `metrics/sqlite` holds the schema, the store and
22
22
  the readers over a `MetricsDriver`: two verbs, `query(statement)` for rows and
23
23
  `transact(statements)` for an all-or-nothing write batch. `metrics/libsql` wraps a
24
24
  Turso / libSQL client, `metrics/d1` wraps a Cloudflare D1 binding (`d1Driver(env.DB)`),
25
25
  each with the driver's native calls and structural types, so no database client is
26
26
  bundled. Any other SQLite driver implements the two verbs in a few lines (the test
27
- does it over `node:sqlite`). A store that does not speak SQLite implements the
28
- injected `write(measurement)` contract and its own readers returning the
29
- `metrics/report` types.
30
-
31
- Provision the exported `METRICS_SCHEMA` once before collecting. `describe()` returns
32
- the declarations; the writer stores labels beside daily counters so reports
33
- discover metrics without another hardcoded list. `readMetrics(driver, { from, to,
34
- project? })` returns daily rows with labels and dimensions, using inclusive UTC dates.
35
- `readAudience(driver, { from, to, project }, describe().overlaps)` answers who did it
36
- from the opt-in per-user rows: per key, distinct actors, actors with more than one
37
- sample on a single day, actors seen on more than one day, then each declared
38
- overlap as `fromUsers` and `bothUsers`. Readers propagate database errors rather
39
- than presenting missing data as zero.
27
+ does it over `node:sqlite`). Readers need only `query`, a `MetricsReader`:
28
+ `metrics/d1-rest` reads a D1 database over Cloudflare's REST API from a process with
29
+ no binding (`d1RestReader({ accountId, databaseId, token })`). A store that does not
30
+ speak SQLite implements the `MetricsStore` contract, `declare(schema)` and
31
+ `write(measurement)`, and its own readers returning the `metrics/report` types.
32
+
33
+ **The store describes itself.** `declare` runs once per process before the first
34
+ sample and carries the whole schema: kinds, labels, help, units, per-user flags and
35
+ overlaps. Every later sample is one small transaction. A reader therefore never needs
36
+ the declaring code: `readSchema(reader, project)` returns what a project declared,
37
+ and `readReport(reader, { project, days, includeToday? })` returns everything a panel
38
+ renders in one call, `{ project, window, schema, daily, audience }`. A changed kind or
39
+ unit is refused at declaration and every sample of that process fails loudly; a store
40
+ that was briefly away is asked again by the next sample.
41
+
42
+ Provision the exported `METRICS_SCHEMA` once before collecting. `readMetrics(reader,
43
+ { from, to, project? })` returns daily rows with labels and dimensions, using inclusive
44
+ UTC dates. `readAudience(reader, { from, to, project }, schema)` answers who did it
45
+ from the opt-in per-user rows: one row per declared per-user metric (zeros when nobody
46
+ touched it), with distinct actors, actors with more than one sample on a single day,
47
+ actors seen on more than one day, then each declared overlap as `fromUsers` and
48
+ `bothUsers`. Readers propagate database errors rather than presenting missing data
49
+ as zero.
40
50
  `summarizeMetrics(rows)` from `metrics/report` produces one generic report shape;
41
51
  `renderMetrics(rows, { daily? })` from `metrics/cli` renders it with the existing
42
52
  ANSI-aware `cli.table` helpers. Both discover every recorded metric from its
@@ -52,8 +62,7 @@ disappearing series, count changes and weighted timing-average changes. Percent
52
62
  change is null without a nonzero baseline; missing timing samples stay null.
53
63
  Changing a metric's kind or unit across the inputs is rejected. Missing observations
54
64
  are not proof that collection was running: deltas compare recorded data only.
55
- The writer rejects changes to an existing key's kind or unit atomically, before
56
- adding observations. Use a new key for a new meaning; labels and help can be edited.
65
+ Use a new key for a new meaning; labels, help and the per-user flag can be edited.
57
66
 
58
67
  Measurements validate finite nonnegative samples, positive integer counts, and
59
68
  declared dimension values. Calls resolve even when validation or storage fails;
@@ -68,15 +77,18 @@ Enable it only with a deletion and retention policy; no identity is inferred.
68
77
  `overlaps: [["a", "b"]]` declares unordered audience overlap, not an ordered funnel.
69
78
  Daily totals support counts and averages, not percentile latency or event ordering.
70
79
 
71
- **5.0 migration:** `sqliteMetricsWriter(client, project)` and `MetricsDatabase` are
72
- gone. Wrap the client in a driver, `libsqlDriver(client)` or `d1Driver(binding)`, and
73
- pass it to `metricsWriter(driver, project)`, `readMetrics(driver, …)` and the new
74
- `readAudience(driver, …)`. A private store with its own tables moves its rows into
75
- `METRICS_SCHEMA` (`project`, `key`, `dimensions` as `'{}'` when it had none, `day`,
76
- `user` as text) and seeds `metric_definition` for the keys it already holds, or the
77
- history stays invisible to `readMetrics` until each key's first write. Metric keys and
78
- dimensions are storage identifiers: introduce a new key when changing meaning rather
79
- than relabelling history.
80
+ **7.0 migration:** `defineMetrics` takes `store: metricsStore(driver, project)` instead
81
+ of `write: metricsWriter(...)`; a custom store implements `declare` and `write`, and
82
+ `Measurement` no longer carries `spec`. Existing tables gain a column and a table:
83
+ `ALTER TABLE metric_definition ADD COLUMN per_user INTEGER NOT NULL DEFAULT 0` and the
84
+ `metric_project` table from `METRICS_SCHEMA` (one row per project, its overlaps as
85
+ JSON; a 6.0 `metric_overlap` table is dropped); the first sample after the deploy
86
+ declares the real flags, labels and overlaps. Ingestion credentials need add and
87
+ update on every metric table and never delete: the store reconciles nothing. `readAudience` takes the schema
88
+ (`readSchema(reader, project)`) instead of an overlap list and returns a row per
89
+ declared per-user key. `readReport` replaces hand-rolled window + rows + audience
90
+ composition. Metric keys and dimensions are storage identifiers: introduce a new key
91
+ when changing meaning rather than relabelling history.
80
92
 
81
93
  ## Installation
82
94
 
@@ -0,0 +1,15 @@
1
+ import type { MetricsReader } from "./sqlite.js";
2
+ export interface D1RestOptions {
3
+ accountId: string;
4
+ databaseId: string;
5
+ /** A Cloudflare API token with D1 read on the database. */
6
+ token: string;
7
+ fetch?: typeof fetch;
8
+ }
9
+ /**
10
+ * A D1 database read over Cloudflare's REST API, for a process that has no binding
11
+ * (a Next server, a CLI). A reader only: one REST call cannot transact, so writes stay
12
+ * with `metrics/d1` inside the Worker that owns the binding.
13
+ */
14
+ export declare function d1RestReader(options: D1RestOptions): MetricsReader;
15
+ //# sourceMappingURL=d1-rest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"d1-rest.d.ts","sourceRoot":"","sources":["../../src/metrics/d1-rest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,WAAW,aAAa;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,aAAa,CAyBlE"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * A D1 database read over Cloudflare's REST API, for a process that has no binding
3
+ * (a Next server, a CLI). A reader only: one REST call cannot transact, so writes stay
4
+ * with `metrics/d1` inside the Worker that owns the binding.
5
+ */
6
+ export function d1RestReader(options) {
7
+ const url = `https://api.cloudflare.com/client/v4/accounts/${options.accountId}/d1/database/${options.databaseId}/query`;
8
+ const call = options.fetch ?? fetch;
9
+ return {
10
+ async query({ sql, args }) {
11
+ const response = await call(url, {
12
+ method: "POST",
13
+ headers: {
14
+ authorization: `Bearer ${options.token}`,
15
+ "content-type": "application/json",
16
+ },
17
+ body: JSON.stringify({ sql, params: args }),
18
+ });
19
+ const data = (await response.json());
20
+ if (!response.ok || !data.success)
21
+ throw new Error(`metrics: d1 ${data.errors?.[0]?.message ?? response.status}`);
22
+ return data.result?.[0]?.results ?? [];
23
+ },
24
+ };
25
+ }
26
+ //# sourceMappingURL=d1-rest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"d1-rest.js","sourceRoot":"","sources":["../../src/metrics/d1-rest.ts"],"names":[],"mappings":"AAUA;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,OAAsB;IAClD,MAAM,GAAG,GAAG,iDAAiD,OAAO,CAAC,SAAS,gBAAgB,OAAO,CAAC,UAAU,QAAQ,CAAC;IACzH,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC;IACpC,OAAO;QACN,KAAK,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE;YACxB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE;gBAChC,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACR,aAAa,EAAE,UAAU,OAAO,CAAC,KAAK,EAAE;oBACxC,cAAc,EAAE,kBAAkB;iBAClC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;aAC3C,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAIlC,CAAC;YACF,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO;gBAChC,MAAM,IAAI,KAAK,CACd,eAAe,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,QAAQ,CAAC,MAAM,EAAE,CAC7D,CAAC;YACH,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,EAAE,CAAC;QACxC,CAAC;KACD,CAAC;AACH,CAAC"}
@@ -14,10 +14,27 @@ export interface Measurement {
14
14
  sum: number;
15
15
  user?: string | number;
16
16
  dimensions: Record<string, string>;
17
- spec: MetricSpec;
17
+ }
18
+ export interface MetricsSchema {
19
+ metrics: Array<{
20
+ key: string;
21
+ } & MetricSpec>;
22
+ overlaps: Array<{
23
+ from: string;
24
+ to: string;
25
+ }>;
26
+ }
27
+ /**
28
+ * Where measurements go. `declare` runs once per process before the first write and
29
+ * carries the whole schema (kinds, labels, per-user flags, overlaps), so a store is
30
+ * self-describing and a reader never needs the declaring code. `write` carries one sample.
31
+ */
32
+ export interface MetricsStore {
33
+ declare(schema: MetricsSchema): Promise<unknown>;
34
+ write(measurement: Measurement): Promise<unknown>;
18
35
  }
19
36
  export interface MetricsOptions<Keys extends string = string> {
20
- write: (measurement: Measurement) => Promise<unknown>;
37
+ store: MetricsStore;
21
38
  /** Unordered user overlap, not an ordered conversion funnel. */
22
39
  overlaps?: ReadonlyArray<readonly [Keys, Keys]>;
23
40
  /** Failures are visible by default, but never reject a measurement call. */
@@ -36,15 +53,6 @@ export interface CounterHandle {
36
53
  export interface TimingHandle {
37
54
  record(value: number, options?: SampleOptions): Promise<void>;
38
55
  }
39
- export interface MetricsSchema {
40
- metrics: Array<{
41
- key: string;
42
- } & MetricSpec>;
43
- overlaps: Array<{
44
- from: string;
45
- to: string;
46
- }>;
47
- }
48
56
  export type Metrics<Spec extends Record<string, MetricSpec>> = {
49
57
  [K in keyof Spec]: Spec[K]["kind"] extends "counter" ? CounterHandle : TimingHandle;
50
58
  } & {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/metrics/index.ts"],"names":[],"mappings":"AAAA,qGAAqG;AACrG,MAAM,MAAM,UAAU,GAAG;IACxB,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;CAC/C,CAAC;AAEF,MAAM,WAAW,WAAW;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,IAAI,EAAE,UAAU,CAAC;CACjB;AAED,MAAM,WAAW,cAAc,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM;IAC3D,KAAK,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACtD,gEAAgE;IAChE,QAAQ,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IAChD,4EAA4E;IAC5E,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC7B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AACD,MAAM,WAAW,aAAa;IAC7B,IAAI,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG;QAAE,CAAC,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9D;AACD,MAAM,WAAW,YAAY;IAC5B,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9D;AACD,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,UAAU,CAAC,CAAC;IAC7C,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC9C;AACD,MAAM,MAAM,OAAO,CAAC,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,IAAI;KAC7D,CAAC,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,SAAS,GACjD,aAAa,GACb,YAAY;CACf,GAAG;IAAE,QAAQ,IAAI,aAAa,CAAA;CAAE,CAAC;AAIlC,wBAAgB,aAAa,CAAC,KAAK,CAAC,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,EAC1E,KAAK,EAAE,IAAI,EACX,IAAI,EAAE,cAAc,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,MAAM,CAAC,CAAC,GAC/C,OAAO,CAAC,IAAI,CAAC,CAqGf"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/metrics/index.ts"],"names":[],"mappings":"AAAA,qGAAqG;AACrG,MAAM,MAAM,UAAU,GAAG;IACxB,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;CAC/C,CAAC;AAEF,MAAM,WAAW,WAAW;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,UAAU,CAAC,CAAC;IAC7C,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC9C;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC5B,OAAO,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACjD,KAAK,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAClD;AAED,MAAM,WAAW,cAAc,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM;IAC3D,KAAK,EAAE,YAAY,CAAC;IACpB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IAChD,4EAA4E;IAC5E,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC7B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AACD,MAAM,WAAW,aAAa;IAC7B,IAAI,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG;QAAE,CAAC,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9D;AACD,MAAM,WAAW,YAAY;IAC5B,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9D;AACD,MAAM,MAAM,OAAO,CAAC,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,IAAI;KAC7D,CAAC,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,SAAS,GACjD,aAAa,GACb,YAAY;CACf,GAAG;IAAE,QAAQ,IAAI,aAAa,CAAA;CAAE,CAAC;AAIlC,wBAAgB,aAAa,CAAC,KAAK,CAAC,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,EAC1E,KAAK,EAAE,IAAI,EACX,IAAI,EAAE,cAAc,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,MAAM,CAAC,CAAC,GAC/C,OAAO,CAAC,IAAI,CAAC,CA8Gf"}
@@ -23,8 +23,23 @@ export function defineMetrics(input, opts) {
23
23
  throw new Error("metrics: overlap requires two declared perUser metrics");
24
24
  return { from, to };
25
25
  });
26
+ const describe = () => structuredClone({
27
+ metrics: Object.entries(spec).map(([key, s]) => ({ key, ...s })),
28
+ overlaps,
29
+ });
26
30
  const report = opts.onError ??
27
31
  ((_error, key) => console.warn(`metrics: measurement failed (${key})`));
32
+ // The schema reaches the store once per process, ahead of the first sample. A failed
33
+ // declaration is retried by the next sample, so a store that was briefly away recovers
34
+ // and a store that refuses the schema (a changed kind) fails every sample, loudly.
35
+ let declared;
36
+ const declare = () => {
37
+ declared ??= opts.store.declare(describe()).catch((error) => {
38
+ declared = undefined;
39
+ throw error;
40
+ });
41
+ return declared;
42
+ };
28
43
  async function write(key, count, sum, options) {
29
44
  try {
30
45
  if (!Number.isSafeInteger(count) ||
@@ -49,14 +64,14 @@ export function defineMetrics(input, opts) {
49
64
  ? !Number.isSafeInteger(user)
50
65
  : typeof user !== "string" || !user.length || user.length > 128))
51
66
  throw new Error("metrics: invalid user identifier");
52
- await opts.write({
67
+ await declare();
68
+ await opts.store.write({
53
69
  key,
54
70
  day: (opts.now?.() ?? new Date()).toISOString().slice(0, 10),
55
71
  count,
56
72
  sum,
57
73
  user,
58
74
  dimensions,
59
- spec: structuredClone(s),
60
75
  });
61
76
  }
62
77
  catch (error) {
@@ -75,12 +90,6 @@ export function defineMetrics(input, opts) {
75
90
  ? { bump: (o) => write(key, o?.n ?? 1, 0, o) }
76
91
  : { record: (value, o) => write(key, 1, value, o) };
77
92
  }
78
- return {
79
- ...out,
80
- describe: () => structuredClone({
81
- metrics: Object.entries(spec).map(([key, s]) => ({ key, ...s })),
82
- overlaps,
83
- }),
84
- };
93
+ return { ...out, describe };
85
94
  }
86
95
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/metrics/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/metrics/index.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import type { MetricsSchema } from "./index.js";
1
2
  /** Store-independent daily observations, shared by adapters and renderers. */
2
3
  export interface DailyMetric {
3
4
  project: string;
@@ -34,6 +35,20 @@ export interface Audience {
34
35
  metrics: AudienceMetric[];
35
36
  overlaps: AudienceOverlap[];
36
37
  }
38
+ export interface MetricsWindow {
39
+ from: string;
40
+ to: string;
41
+ /** The window ends on the current, incomplete UTC day. */
42
+ partial: boolean;
43
+ }
44
+ /** One project, one window, everything a panel renders; the schema comes from the store. */
45
+ export interface MetricsReport {
46
+ project: string;
47
+ window: MetricsWindow;
48
+ schema: MetricsSchema;
49
+ daily: DailyMetric[];
50
+ audience: Audience;
51
+ }
37
52
  export interface MetricTotal {
38
53
  project: string;
39
54
  key: string;
@@ -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,wFAAwF;AACxF,MAAM,WAAW,cAAc;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,uBAAuB;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,WAAW,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,cAAc,EAAE,MAAM,CAAC;CACvB;AAED,oFAAoF;AACpF,MAAM,WAAW,eAAe;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACxB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC5B;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,CAqC5E"}
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/metrics/report.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/metrics/report.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/metrics/report.ts"],"names":[],"mappings":"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"}
@@ -1,41 +1,52 @@
1
- import type { Measurement } from "./index.js";
2
- import type { Audience, DailyMetric } from "./report.js";
1
+ import type { MetricsSchema, MetricsStore } from "./index.js";
2
+ import { type Audience, type DailyMetric, type MetricsReport } from "./report.js";
3
3
  export type SqlValue = string | number;
4
4
  export interface SqlStatement {
5
5
  sql: string;
6
6
  args: SqlValue[];
7
7
  }
8
+ /** Reads need one verb. `metrics/d1-rest` is a reader only: a REST call cannot transact. */
9
+ export interface MetricsReader {
10
+ /** The rows of one read statement. */
11
+ query(statement: SqlStatement): Promise<Iterable<Record<string, unknown>>>;
12
+ }
8
13
  /**
9
14
  * The SQLite dialect below needs exactly two verbs from a store. `metrics/libsql` and
10
15
  * `metrics/d1` implement them with each driver's native calls; any driver that speaks
11
16
  * SQLite (node:sqlite, bun:sqlite, better-sqlite3) does the same in a few lines.
12
17
  */
13
- export interface MetricsDriver {
14
- /** The rows of one read statement. */
15
- query(statement: SqlStatement): Promise<Iterable<Record<string, unknown>>>;
18
+ export interface MetricsDriver extends MetricsReader {
16
19
  /** Every statement or none: a constraint failure in any of them rolls the batch back. */
17
20
  transact(statements: SqlStatement[]): Promise<unknown>;
18
21
  }
19
22
  /** Run explicitly during provisioning, never on a user's request. */
20
- export declare const METRICS_SCHEMA: readonly ["CREATE TABLE IF NOT EXISTS metric_definition (project TEXT NOT NULL, key TEXT NOT NULL, kind TEXT NOT NULL, label TEXT NOT NULL, help TEXT NOT NULL, unit TEXT NOT NULL, PRIMARY KEY(project, key))", "CREATE TABLE IF NOT EXISTS metric_daily (project TEXT NOT NULL, key TEXT NOT NULL, dimensions TEXT NOT NULL, day TEXT NOT NULL, count INTEGER NOT NULL CHECK(count >= 0), sum REAL NOT NULL CHECK(sum >= 0), PRIMARY KEY(project, key, dimensions, day))", "CREATE TABLE IF NOT EXISTS metric_user_daily (project TEXT NOT NULL, key TEXT NOT NULL, dimensions TEXT NOT NULL, day TEXT NOT NULL, user TEXT NOT NULL, count INTEGER NOT NULL CHECK(count >= 0), sum REAL NOT NULL CHECK(sum >= 0), PRIMARY KEY(project, key, dimensions, day, user))", "CREATE INDEX IF NOT EXISTS metric_user_identity ON metric_user_daily(project, user)"];
21
- export declare function metricsWriter(driver: MetricsDriver, project: string): (m: Measurement) => Promise<void>;
23
+ export declare const METRICS_SCHEMA: readonly ["CREATE TABLE IF NOT EXISTS metric_definition (project TEXT NOT NULL, key TEXT NOT NULL, kind TEXT NOT NULL, label TEXT NOT NULL, help TEXT NOT NULL, unit TEXT NOT NULL, per_user INTEGER NOT NULL, PRIMARY KEY(project, key))", "CREATE TABLE IF NOT EXISTS metric_project (project TEXT NOT NULL, overlaps TEXT NOT NULL, PRIMARY KEY(project))", "CREATE TABLE IF NOT EXISTS metric_daily (project TEXT NOT NULL, key TEXT NOT NULL, dimensions TEXT NOT NULL, day TEXT NOT NULL, count INTEGER NOT NULL CHECK(count >= 0), sum REAL NOT NULL CHECK(sum >= 0), PRIMARY KEY(project, key, dimensions, day))", "CREATE TABLE IF NOT EXISTS metric_user_daily (project TEXT NOT NULL, key TEXT NOT NULL, dimensions TEXT NOT NULL, day TEXT NOT NULL, user TEXT NOT NULL, count INTEGER NOT NULL CHECK(count >= 0), sum REAL NOT NULL CHECK(sum >= 0), PRIMARY KEY(project, key, dimensions, day, user))", "CREATE INDEX IF NOT EXISTS metric_user_identity ON metric_user_daily(project, user)"];
24
+ /** One project's store over a SQLite driver. */
25
+ export declare function metricsStore(driver: MetricsDriver, project: string): MetricsStore;
26
+ /** What one project declared, as the store holds it: the reader needs no declaring code. */
27
+ export declare function readSchema(reader: MetricsReader, project: string): Promise<MetricsSchema>;
22
28
  /** Inclusive UTC dates. Errors propagate: unavailable data must never read as zero. */
23
- export declare function readMetrics(driver: MetricsDriver, range: {
29
+ export declare function readMetrics(reader: MetricsReader, range: {
24
30
  from: string;
25
31
  to: string;
26
32
  project?: string;
27
33
  }): Promise<DailyMetric[]>;
28
34
  /**
29
- * Who did it, over the opt-in per-user rows of one project, all dimensions folded: per key,
30
- * distinct actors, actors with more than one sample on a single day, actors seen on more
31
- * than one day; then the declared unordered overlaps. Keys nobody touched are absent.
35
+ * Who did it, over one project's opt-in per-user rows, all dimensions folded: one row per
36
+ * declared per-user metric (zeros when nobody touched it in the window) with distinct
37
+ * actors, actors with more than one sample on a single day, actors seen on more than one
38
+ * day; then every declared unordered overlap.
32
39
  */
33
- export declare function readAudience(driver: MetricsDriver, range: {
40
+ export declare function readAudience(reader: MetricsReader, range: {
34
41
  from: string;
35
42
  to: string;
36
43
  project: string;
37
- }, overlaps: ReadonlyArray<{
38
- from: string;
39
- to: string;
40
- }>): Promise<Audience>;
44
+ }, schema: MetricsSchema): Promise<Audience>;
45
+ /** Everything a panel renders for one project over the last `days` UTC days, in one call. */
46
+ export declare function readReport(reader: MetricsReader, options: {
47
+ project: string;
48
+ days: number;
49
+ includeToday?: boolean;
50
+ now?: Date;
51
+ }): Promise<MetricsReport>;
41
52
  //# sourceMappingURL=sqlite.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/metrics/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEzD,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;AACvC,MAAM,WAAW,YAAY;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,QAAQ,EAAE,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC7B,sCAAsC;IACtC,KAAK,CAAC,SAAS,EAAE,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAC3E,yFAAyF;IACzF,QAAQ,CAAC,UAAU,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACvD;AAED,qEAAqE;AACrE,eAAO,MAAM,cAAc,g0BAKjB,CAAC;AAiBX,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,IAErD,GAAG,WAAW,mBAoC5B;AAED,uFAAuF;AACvF,wBAAsB,WAAW,CAChC,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GACnD,OAAO,CAAC,WAAW,EAAE,CAAC,CAmBxB;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CACjC,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EACpD,QAAQ,EAAE,aAAa,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,GACnD,OAAO,CAAC,QAAQ,CAAC,CA0CnB"}
1
+ {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/metrics/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC3E,OAAO,EACN,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,aAAa,EAElB,MAAM,aAAa,CAAC;AAErB,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;AACvC,MAAM,WAAW,YAAY;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,QAAQ,EAAE,CAAC;CACjB;AAED,4FAA4F;AAC5F,MAAM,WAAW,aAAa;IAC7B,sCAAsC;IACtC,KAAK,CAAC,SAAS,EAAE,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CAC3E;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAc,SAAQ,aAAa;IACnD,yFAAyF;IACzF,QAAQ,CAAC,UAAU,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACvD;AAED,qEAAqE;AACrE,eAAO,MAAM,cAAc,88BAMjB,CAAC;AAiBX,gDAAgD;AAChD,wBAAgB,YAAY,CAC3B,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,MAAM,GACb,YAAY,CAkDd;AAED,4FAA4F;AAC5F,wBAAsB,UAAU,CAC/B,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,MAAM,GACb,OAAO,CAAC,aAAa,CAAC,CA2BxB;AAED,uFAAuF;AACvF,wBAAsB,WAAW,CAChC,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GACnD,OAAO,CAAC,WAAW,EAAE,CAAC,CAmBxB;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CACjC,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EACpD,MAAM,EAAE,aAAa,GACnB,OAAO,CAAC,QAAQ,CAAC,CAmDnB;AAED,6FAA6F;AAC7F,wBAAsB,UAAU,CAC/B,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE;IACR,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,GAAG,CAAC,EAAE,IAAI,CAAC;CACX,GACC,OAAO,CAAC,aAAa,CAAC,CAkBxB"}
@@ -1,6 +1,8 @@
1
+ import { metricWindows, } from "./report.js";
1
2
  /** Run explicitly during provisioning, never on a user's request. */
2
3
  export const METRICS_SCHEMA = [
3
- `CREATE TABLE IF NOT EXISTS metric_definition (project TEXT NOT NULL, key TEXT NOT NULL, kind TEXT NOT NULL, label TEXT NOT NULL, help TEXT NOT NULL, unit TEXT NOT NULL, PRIMARY KEY(project, key))`,
4
+ `CREATE TABLE IF NOT EXISTS metric_definition (project TEXT NOT NULL, key TEXT NOT NULL, kind TEXT NOT NULL, label TEXT NOT NULL, help TEXT NOT NULL, unit TEXT NOT NULL, per_user INTEGER NOT NULL, PRIMARY KEY(project, key))`,
5
+ `CREATE TABLE IF NOT EXISTS metric_project (project TEXT NOT NULL, overlaps TEXT NOT NULL, PRIMARY KEY(project))`,
4
6
  `CREATE TABLE IF NOT EXISTS metric_daily (project TEXT NOT NULL, key TEXT NOT NULL, dimensions TEXT NOT NULL, day TEXT NOT NULL, count INTEGER NOT NULL CHECK(count >= 0), sum REAL NOT NULL CHECK(sum >= 0), PRIMARY KEY(project, key, dimensions, day))`,
5
7
  `CREATE TABLE IF NOT EXISTS metric_user_daily (project TEXT NOT NULL, key TEXT NOT NULL, dimensions TEXT NOT NULL, day TEXT NOT NULL, user TEXT NOT NULL, count INTEGER NOT NULL CHECK(count >= 0), sum REAL NOT NULL CHECK(sum >= 0), PRIMARY KEY(project, key, dimensions, day, user))`,
6
8
  `CREATE INDEX IF NOT EXISTS metric_user_identity ON metric_user_daily(project, user)`,
@@ -19,51 +21,93 @@ function assertRange(range) {
19
21
  if (range.from > range.to)
20
22
  throw new Error("metrics: reversed date range");
21
23
  }
22
- export function metricsWriter(driver, project) {
24
+ /** One project's store over a SQLite driver. */
25
+ export function metricsStore(driver, project) {
23
26
  assertProject(project);
24
- return async (m) => {
25
- const dimensions = JSON.stringify(m.dimensions);
26
- const statements = [
27
- {
28
- // NOT NULL makes a changed kind/unit fail the whole atomic batch, including counts.
29
- // Labels/help may evolve, but historical measurements must retain their meaning.
30
- sql: `INSERT INTO metric_definition VALUES (?, ?, ?, ?, ?, ?) ON CONFLICT(project, key) DO UPDATE SET kind=CASE WHEN kind=excluded.kind THEN kind ELSE NULL END, label=excluded.label, help=excluded.help, unit=CASE WHEN unit=excluded.unit THEN unit ELSE NULL END`,
27
+ return {
28
+ async declare(schema) {
29
+ const statements = schema.metrics.map((m) => ({
30
+ // NOT NULL makes a changed kind/unit fail the whole atomic batch. Labels, help
31
+ // and the per-user flag may evolve; historical measurements keep their meaning.
32
+ sql: `INSERT INTO metric_definition VALUES (?, ?, ?, ?, ?, ?, ?) ON CONFLICT(project, key) DO UPDATE SET kind=CASE WHEN kind=excluded.kind THEN kind ELSE NULL END, label=excluded.label, help=excluded.help, unit=CASE WHEN unit=excluded.unit THEN unit ELSE NULL END, per_user=excluded.per_user`,
31
33
  args: [
32
34
  project,
33
35
  m.key,
34
- m.spec.kind,
35
- m.spec.label,
36
- m.spec.help ?? "",
37
- m.spec.unit ?? "",
36
+ m.kind,
37
+ m.label,
38
+ m.help ?? "",
39
+ m.unit ?? "",
40
+ m.perUser ? 1 : 0,
38
41
  ],
39
- },
40
- {
41
- sql: `INSERT INTO metric_daily VALUES (?, ?, ?, ?, ?, ?) ON CONFLICT(project, key, dimensions, day) DO UPDATE SET count=count+excluded.count, sum=sum+excluded.sum`,
42
- args: [project, m.key, dimensions, m.day, m.count, m.sum],
43
- },
44
- ];
45
- if (m.user !== undefined)
42
+ }));
43
+ // One row per project, replaced whole: an ingestion credential can add and update
44
+ // but never delete, so the declared set is a value, not a table to reconcile.
46
45
  statements.push({
47
- sql: `INSERT INTO metric_user_daily VALUES (?, ?, ?, ?, ?, ?, ?) ON CONFLICT(project, key, dimensions, day, user) DO UPDATE SET count=count+excluded.count, sum=sum+excluded.sum`,
48
- args: [
49
- project,
50
- m.key,
51
- dimensions,
52
- m.day,
53
- String(m.user),
54
- m.count,
55
- m.sum,
56
- ],
46
+ sql: `INSERT INTO metric_project VALUES (?, ?) ON CONFLICT(project) DO UPDATE SET overlaps=excluded.overlaps`,
47
+ args: [project, JSON.stringify(schema.overlaps)],
57
48
  });
58
- await driver.transact(statements);
49
+ await driver.transact(statements);
50
+ },
51
+ async write(m) {
52
+ const dimensions = JSON.stringify(m.dimensions);
53
+ const statements = [
54
+ {
55
+ sql: `INSERT INTO metric_daily VALUES (?, ?, ?, ?, ?, ?) ON CONFLICT(project, key, dimensions, day) DO UPDATE SET count=count+excluded.count, sum=sum+excluded.sum`,
56
+ args: [project, m.key, dimensions, m.day, m.count, m.sum],
57
+ },
58
+ ];
59
+ if (m.user !== undefined)
60
+ statements.push({
61
+ sql: `INSERT INTO metric_user_daily VALUES (?, ?, ?, ?, ?, ?, ?) ON CONFLICT(project, key, dimensions, day, user) DO UPDATE SET count=count+excluded.count, sum=sum+excluded.sum`,
62
+ args: [
63
+ project,
64
+ m.key,
65
+ dimensions,
66
+ m.day,
67
+ String(m.user),
68
+ m.count,
69
+ m.sum,
70
+ ],
71
+ });
72
+ await driver.transact(statements);
73
+ },
74
+ };
75
+ }
76
+ /** What one project declared, as the store holds it: the reader needs no declaring code. */
77
+ export async function readSchema(reader, project) {
78
+ assertProject(project);
79
+ const [definitions, projects] = await Promise.all([
80
+ reader.query({
81
+ sql: `SELECT key, kind, label, help, unit, per_user FROM metric_definition WHERE project = ? ORDER BY key`,
82
+ args: [project],
83
+ }),
84
+ reader.query({
85
+ sql: `SELECT overlaps FROM metric_project WHERE project = ?`,
86
+ args: [project],
87
+ }),
88
+ ]);
89
+ const [row] = Array.from(projects);
90
+ const overlaps = row
91
+ ? JSON.parse(String(row.overlaps))
92
+ : [];
93
+ return {
94
+ metrics: Array.from(definitions, (r) => ({
95
+ key: String(r.key),
96
+ kind: String(r.kind),
97
+ label: String(r.label),
98
+ ...(r.help ? { help: String(r.help) } : {}),
99
+ ...(r.unit ? { unit: String(r.unit) } : {}),
100
+ ...(Number(r.per_user) ? { perUser: true } : {}),
101
+ })),
102
+ overlaps,
59
103
  };
60
104
  }
61
105
  /** Inclusive UTC dates. Errors propagate: unavailable data must never read as zero. */
62
- export async function readMetrics(driver, range) {
106
+ export async function readMetrics(reader, range) {
63
107
  assertRange(range);
64
108
  if (range.project !== undefined)
65
109
  assertProject(range.project);
66
- const rows = await driver.query({
110
+ const rows = await reader.query({
67
111
  sql: `SELECT d.*, s.label, s.kind, s.help, s.unit FROM metric_daily d JOIN metric_definition s USING(project, key) WHERE day >= ? AND day <= ? ${range.project ? "AND project = ?" : ""} ORDER BY project, key, dimensions, day`,
68
112
  args: [range.from, range.to, ...(range.project ? [range.project] : [])],
69
113
  });
@@ -81,29 +125,34 @@ export async function readMetrics(driver, range) {
81
125
  }));
82
126
  }
83
127
  /**
84
- * Who did it, over the opt-in per-user rows of one project, all dimensions folded: per key,
85
- * distinct actors, actors with more than one sample on a single day, actors seen on more
86
- * than one day; then the declared unordered overlaps. Keys nobody touched are absent.
128
+ * Who did it, over one project's opt-in per-user rows, all dimensions folded: one row per
129
+ * declared per-user metric (zeros when nobody touched it in the window) with distinct
130
+ * actors, actors with more than one sample on a single day, actors seen on more than one
131
+ * day; then every declared unordered overlap.
87
132
  */
88
- export async function readAudience(driver, range, overlaps) {
133
+ export async function readAudience(reader, range, schema) {
89
134
  assertRange(range);
90
135
  assertProject(range.project);
91
- const window = [range.project, range.from, range.to];
92
- const perKey = await driver.query({
93
- sql: `WITH per_day AS (SELECT key, user, day, SUM(count) AS count FROM metric_user_daily WHERE project = ? AND day >= ? AND day <= ? GROUP BY key, user, day), per_user AS (SELECT key, user, COUNT(*) AS days, MAX(count) AS peak FROM per_day GROUP BY key, user) SELECT key, COUNT(*) AS uniques, SUM(CASE WHEN peak > 1 THEN 1 ELSE 0 END) AS repeat_users, SUM(CASE WHEN days > 1 THEN 1 ELSE 0 END) AS returning_users FROM per_user GROUP BY key ORDER BY key`,
94
- args: [...window],
136
+ const perKey = new Map(Array.from(await reader.query({
137
+ sql: `WITH per_day AS (SELECT key, user, day, SUM(count) AS count FROM metric_user_daily WHERE project = ? AND day >= ? AND day <= ? GROUP BY key, user, day), per_user AS (SELECT key, user, COUNT(*) AS days, MAX(count) AS peak FROM per_day GROUP BY key, user) SELECT key, COUNT(*) AS uniques, SUM(CASE WHEN peak > 1 THEN 1 ELSE 0 END) AS repeat_users, SUM(CASE WHEN days > 1 THEN 1 ELSE 0 END) AS returning_users FROM per_user GROUP BY key`,
138
+ args: [range.project, range.from, range.to],
139
+ }), (r) => [String(r.key), r]));
140
+ const metrics = schema.metrics
141
+ .filter((m) => m.perUser)
142
+ .map((m) => {
143
+ const r = perKey.get(m.key);
144
+ return {
145
+ project: range.project,
146
+ key: m.key,
147
+ uniques: Number(r?.uniques ?? 0),
148
+ repeatUsers: Number(r?.repeat_users ?? 0),
149
+ returningUsers: Number(r?.returning_users ?? 0),
150
+ };
95
151
  });
96
- const metrics = Array.from(perKey, (r) => ({
97
- project: range.project,
98
- key: String(r.key),
99
- uniques: Number(r.uniques),
100
- repeatUsers: Number(r.repeat_users),
101
- returningUsers: Number(r.returning_users),
102
- }));
103
- const shared = [];
104
152
  const actors = `SELECT DISTINCT user FROM metric_user_daily WHERE project = ? AND key = ? AND day >= ? AND day <= ?`;
105
- for (const pair of overlaps) {
106
- const [row] = Array.from(await driver.query({
153
+ const overlaps = [];
154
+ for (const pair of schema.overlaps) {
155
+ const [row] = Array.from(await reader.query({
107
156
  sql: `WITH a AS (${actors}), b AS (${actors}) SELECT (SELECT COUNT(*) FROM a) AS from_users, (SELECT COUNT(*) FROM a WHERE user IN (SELECT user FROM b)) AS both_users`,
108
157
  args: [
109
158
  range.project,
@@ -116,7 +165,7 @@ export async function readAudience(driver, range, overlaps) {
116
165
  range.to,
117
166
  ],
118
167
  }));
119
- shared.push({
168
+ overlaps.push({
120
169
  project: range.project,
121
170
  from: pair.from,
122
171
  to: pair.to,
@@ -124,6 +173,26 @@ export async function readAudience(driver, range, overlaps) {
124
173
  bothUsers: Number(row?.both_users ?? 0),
125
174
  });
126
175
  }
127
- return { metrics, overlaps: shared };
176
+ return { metrics, overlaps };
177
+ }
178
+ /** Everything a panel renders for one project over the last `days` UTC days, in one call. */
179
+ export async function readReport(reader, options) {
180
+ const { current, partial } = metricWindows(options.days, {
181
+ now: options.now,
182
+ includeToday: options.includeToday,
183
+ });
184
+ const range = { ...current, project: options.project };
185
+ const schema = await readSchema(reader, options.project);
186
+ const [daily, audience] = await Promise.all([
187
+ readMetrics(reader, range),
188
+ readAudience(reader, range, schema),
189
+ ]);
190
+ return {
191
+ project: options.project,
192
+ window: { ...current, partial },
193
+ schema,
194
+ daily,
195
+ audience,
196
+ };
128
197
  }
129
198
  //# sourceMappingURL=sqlite.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../src/metrics/sqlite.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../src/metrics/sqlite.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adriangalilea/utils",
3
- "version": "5.0.0",
3
+ "version": "7.0.0",
4
4
  "description": "TypeScript utilities - logger, currency, formatter, GramIO bot plugins, and more",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -200,6 +200,10 @@
200
200
  "types": "./dist/metrics/d1.d.ts",
201
201
  "default": "./dist/metrics/d1.js"
202
202
  },
203
+ "./metrics/d1-rest": {
204
+ "types": "./dist/metrics/d1-rest.d.ts",
205
+ "default": "./dist/metrics/d1-rest.js"
206
+ },
203
207
  "./metrics/report": {
204
208
  "types": "./dist/metrics/report.d.ts",
205
209
  "default": "./dist/metrics/report.js"