@uptimizr/db 2.0.1 → 2.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/AGENTS.md +228 -3
- package/README.md +13 -0
- package/dist/duckdb/migrations.d.ts.map +1 -1
- package/dist/duckdb/migrations.js +169 -0
- package/dist/duckdb/migrations.js.map +1 -1
- package/dist/duckdb/panelSpecs.d.ts +29 -0
- package/dist/duckdb/panelSpecs.d.ts.map +1 -0
- package/dist/duckdb/panelSpecs.js +104 -0
- package/dist/duckdb/panelSpecs.js.map +1 -0
- package/dist/duckdb/projectMetadata.d.ts +43 -0
- package/dist/duckdb/projectMetadata.d.ts.map +1 -0
- package/dist/duckdb/projectMetadata.js +222 -0
- package/dist/duckdb/projectMetadata.js.map +1 -0
- package/dist/duckdb/subscriptions.d.ts +45 -0
- package/dist/duckdb/subscriptions.d.ts.map +1 -0
- package/dist/duckdb/subscriptions.js +202 -0
- package/dist/duckdb/subscriptions.js.map +1 -0
- package/dist/index.d.ts +18 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +48 -3
- package/dist/index.js.map +1 -1
- package/dist/insights/anomalies.d.ts +213 -0
- package/dist/insights/anomalies.d.ts.map +1 -0
- package/dist/insights/anomalies.js +340 -0
- package/dist/insights/anomalies.js.map +1 -0
- package/dist/insights/baseline.d.ts +51 -0
- package/dist/insights/baseline.d.ts.map +1 -0
- package/dist/insights/baseline.js +48 -0
- package/dist/insights/baseline.js.map +1 -0
- package/dist/insights/buckets.d.ts +114 -0
- package/dist/insights/buckets.d.ts.map +1 -0
- package/dist/insights/buckets.js +220 -0
- package/dist/insights/buckets.js.map +1 -0
- package/dist/insights/changepoint.d.ts +130 -0
- package/dist/insights/changepoint.d.ts.map +1 -0
- package/dist/insights/changepoint.js +209 -0
- package/dist/insights/changepoint.js.map +1 -0
- package/dist/insights/evaluate.d.ts +63 -0
- package/dist/insights/evaluate.d.ts.map +1 -0
- package/dist/insights/evaluate.js +158 -0
- package/dist/insights/evaluate.js.map +1 -0
- package/dist/insights/health.d.ts +219 -0
- package/dist/insights/health.d.ts.map +1 -0
- package/dist/insights/health.js +349 -0
- package/dist/insights/health.js.map +1 -0
- package/dist/insights/index.d.ts +45 -0
- package/dist/insights/index.d.ts.map +1 -0
- package/dist/insights/index.js +40 -0
- package/dist/insights/index.js.map +1 -0
- package/dist/insights/measures.d.ts +222 -0
- package/dist/insights/measures.d.ts.map +1 -0
- package/dist/insights/measures.js +431 -0
- package/dist/insights/measures.js.map +1 -0
- package/dist/insights/movers.d.ts +123 -0
- package/dist/insights/movers.d.ts.map +1 -0
- package/dist/insights/movers.js +166 -0
- package/dist/insights/movers.js.map +1 -0
- package/dist/insights/significance.d.ts +221 -0
- package/dist/insights/significance.d.ts.map +1 -0
- package/dist/insights/significance.js +531 -0
- package/dist/insights/significance.js.map +1 -0
- package/dist/insights/stats.d.ts +104 -0
- package/dist/insights/stats.d.ts.map +1 -0
- package/dist/insights/stats.js +181 -0
- package/dist/insights/stats.js.map +1 -0
- package/dist/insights/windows.d.ts +95 -0
- package/dist/insights/windows.d.ts.map +1 -0
- package/dist/insights/windows.js +97 -0
- package/dist/insights/windows.js.map +1 -0
- package/dist/metadata.d.ts +178 -1
- package/dist/metadata.d.ts.map +1 -1
- package/dist/metadata.js +80 -0
- package/dist/metadata.js.map +1 -1
- package/dist/narrative/build.d.ts +78 -0
- package/dist/narrative/build.d.ts.map +1 -0
- package/dist/narrative/build.js +437 -0
- package/dist/narrative/build.js.map +1 -0
- package/dist/narrative/index.d.ts +14 -0
- package/dist/narrative/index.d.ts.map +1 -0
- package/dist/narrative/index.js +13 -0
- package/dist/narrative/index.js.map +1 -0
- package/dist/narrative/text.d.ts +25 -0
- package/dist/narrative/text.d.ts.map +1 -0
- package/dist/narrative/text.js +41 -0
- package/dist/narrative/text.js.map +1 -0
- package/dist/parity/cases.d.ts +3 -0
- package/dist/parity/cases.d.ts.map +1 -1
- package/dist/parity/cases.js +387 -7
- package/dist/parity/cases.js.map +1 -1
- package/dist/parity/compare.d.ts +19 -0
- package/dist/parity/compare.d.ts.map +1 -1
- package/dist/parity/compare.js +19 -0
- package/dist/parity/compare.js.map +1 -1
- package/dist/parity/fixtures.d.ts.map +1 -1
- package/dist/parity/fixtures.js +25 -0
- package/dist/parity/fixtures.js.map +1 -1
- package/dist/query/aggregations.d.ts +46 -1
- package/dist/query/aggregations.d.ts.map +1 -1
- package/dist/query/aggregations.js +86 -0
- package/dist/query/aggregations.js.map +1 -1
- package/dist/query/clickhouseDialect.d.ts.map +1 -1
- package/dist/query/clickhouseDialect.js +5 -1
- package/dist/query/clickhouseDialect.js.map +1 -1
- package/dist/query/customEventVocabulary.d.ts +46 -0
- package/dist/query/customEventVocabulary.d.ts.map +1 -0
- package/dist/query/customEventVocabulary.js +127 -0
- package/dist/query/customEventVocabulary.js.map +1 -0
- package/dist/query/dsl/builders.d.ts +38 -0
- package/dist/query/dsl/builders.d.ts.map +1 -0
- package/dist/query/dsl/builders.js +35 -0
- package/dist/query/dsl/builders.js.map +1 -0
- package/dist/query/dsl/compare.d.ts +167 -0
- package/dist/query/dsl/compare.d.ts.map +1 -0
- package/dist/query/dsl/compare.js +358 -0
- package/dist/query/dsl/compare.js.map +1 -0
- package/dist/query/dsl/compile.d.ts +89 -0
- package/dist/query/dsl/compile.d.ts.map +1 -0
- package/dist/query/dsl/compile.js +174 -0
- package/dist/query/dsl/compile.js.map +1 -0
- package/dist/query/dsl/explain.d.ts +115 -0
- package/dist/query/dsl/explain.d.ts.map +1 -0
- package/dist/query/dsl/explain.js +143 -0
- package/dist/query/dsl/explain.js.map +1 -0
- package/dist/query/dsl/generic.d.ts +127 -0
- package/dist/query/dsl/generic.d.ts.map +1 -0
- package/dist/query/dsl/generic.js +323 -0
- package/dist/query/dsl/generic.js.map +1 -0
- package/dist/query/dsl/index.d.ts +30 -0
- package/dist/query/dsl/index.d.ts.map +1 -0
- package/dist/query/dsl/index.js +23 -0
- package/dist/query/dsl/index.js.map +1 -0
- package/dist/query/dsl/order.d.ts +41 -0
- package/dist/query/dsl/order.d.ts.map +1 -0
- package/dist/query/dsl/order.js +55 -0
- package/dist/query/dsl/order.js.map +1 -0
- package/dist/query/dsl/significance.d.ts +130 -0
- package/dist/query/dsl/significance.d.ts.map +1 -0
- package/dist/query/dsl/significance.js +224 -0
- package/dist/query/dsl/significance.js.map +1 -0
- package/dist/query/index.d.ts +2 -0
- package/dist/query/index.d.ts.map +1 -1
- package/dist/query/index.js +8 -0
- package/dist/query/index.js.map +1 -1
- package/dist/query/summary/index.d.ts +4 -2
- package/dist/query/summary/index.d.ts.map +1 -1
- package/dist/query/summary/index.js +2 -1
- package/dist/query/summary/index.js.map +1 -1
- package/dist/query/summary/labels.d.ts +101 -0
- package/dist/query/summary/labels.d.ts.map +1 -0
- package/dist/query/summary/labels.js +261 -0
- package/dist/query/summary/labels.js.map +1 -0
- package/dist/query/summary/reading.d.ts.map +1 -1
- package/dist/query/summary/reading.js +21 -2
- package/dist/query/summary/reading.js.map +1 -1
- package/dist/query/summary/schema.d.ts +250 -20
- package/dist/query/summary/schema.d.ts.map +1 -1
- package/dist/query/summary/schema.js +135 -123
- package/dist/query/summary/schema.js.map +1 -1
- package/dist/query/summary/summarize.d.ts.map +1 -1
- package/dist/query/summary/summarize.js +91 -5
- package/dist/query/summary/summarize.js.map +1 -1
- package/dist/query/summary/types.d.ts +77 -2
- package/dist/query/summary/types.d.ts.map +1 -1
- package/dist/query/types.d.ts +47 -1
- package/dist/query/types.d.ts.map +1 -1
- package/dist/subscriptions.d.ts +208 -0
- package/dist/subscriptions.d.ts.map +1 -0
- package/dist/subscriptions.js +153 -0
- package/dist/subscriptions.js.map +1 -0
- package/llms.txt +9 -0
- package/package.json +8 -8
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panelSpecs.js","sourceRoot":"","sources":["../../src/duckdb/panelSpecs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { type AnnotationRecord, type CreateAnnotationInput, type CreateSavedAnalysisInput, type GlossaryEntryRecord, type ListAnnotationsOptions, type MetadataListOptions, type PutGlossaryEntryInput, type SavedAnalysisRecord } from "../metadata.js";
|
|
2
|
+
import type { DuckdbClient } from "./client.js";
|
|
3
|
+
/**
|
|
4
|
+
* Create one annotation and return the stored row.
|
|
5
|
+
*
|
|
6
|
+
* Refuses with {@link MetadataLimitError} once the project holds
|
|
7
|
+
* {@link METADATA_LIMITS.annotations} rows: metadata is curated notes, not an
|
|
8
|
+
* unbounded write surface, and refusing is more honest than evicting somebody
|
|
9
|
+
* else's note.
|
|
10
|
+
*/
|
|
11
|
+
export declare function createAnnotation(client: DuckdbClient, projectId: string, input: CreateAnnotationInput): Promise<AnnotationRecord>;
|
|
12
|
+
/**
|
|
13
|
+
* A project's annotations, newest first.
|
|
14
|
+
*
|
|
15
|
+
* The optional `since`/`until` bounds are an **overlap** filter, not a
|
|
16
|
+
* containment one: an annotation matches when its period intersects the
|
|
17
|
+
* requested window, and a standing note (no period at all) always matches
|
|
18
|
+
* because it is about the project rather than about a moment.
|
|
19
|
+
*/
|
|
20
|
+
export declare function listAnnotations(client: DuckdbClient, projectId: string, opts?: ListAnnotationsOptions): Promise<AnnotationRecord[]>;
|
|
21
|
+
/**
|
|
22
|
+
* Delete one annotation of this project. Returns whether a row was removed, so
|
|
23
|
+
* the route can answer 404 for an id that is not there (or belongs to another
|
|
24
|
+
* project — the two are indistinguishable to the caller, deliberately).
|
|
25
|
+
*/
|
|
26
|
+
export declare function deleteAnnotation(client: DuckdbClient, projectId: string, id: string): Promise<boolean>;
|
|
27
|
+
/**
|
|
28
|
+
* Upsert one glossary entry and return the stored row. Idempotent: the term is
|
|
29
|
+
* the identity, so re-defining it replaces the meaning instead of accumulating
|
|
30
|
+
* duplicates. The per-project cap applies only when a *new* term is added.
|
|
31
|
+
*/
|
|
32
|
+
export declare function putGlossaryEntry(client: DuckdbClient, projectId: string, input: PutGlossaryEntryInput): Promise<GlossaryEntryRecord>;
|
|
33
|
+
/** A project's whole glossary, ordered by term (stable for diffs and prompts). */
|
|
34
|
+
export declare function listGlossary(client: DuckdbClient, projectId: string, opts?: MetadataListOptions): Promise<GlossaryEntryRecord[]>;
|
|
35
|
+
/** Delete one term. Returns whether it existed. */
|
|
36
|
+
export declare function deleteGlossaryEntry(client: DuckdbClient, projectId: string, term: string): Promise<boolean>;
|
|
37
|
+
/** Create one saved analysis and return the stored row. */
|
|
38
|
+
export declare function createSavedAnalysis(client: DuckdbClient, projectId: string, input: CreateSavedAnalysisInput): Promise<SavedAnalysisRecord>;
|
|
39
|
+
/** A project's saved analyses, newest first. */
|
|
40
|
+
export declare function listSavedAnalyses(client: DuckdbClient, projectId: string, opts?: MetadataListOptions): Promise<SavedAnalysisRecord[]>;
|
|
41
|
+
/** Delete one saved analysis. Returns whether it existed. */
|
|
42
|
+
export declare function deleteSavedAnalysis(client: DuckdbClient, projectId: string, id: string): Promise<boolean>;
|
|
43
|
+
//# sourceMappingURL=projectMetadata.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projectMetadata.d.ts","sourceRoot":"","sources":["../../src/duckdb/projectMetadata.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,gBAAgB,EAErB,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC7B,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAE3B,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACzB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAiEhD;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,gBAAgB,CAAC,CAqC3B;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE,sBAA2B,GAChC,OAAO,CAAC,gBAAgB,EAAE,CAAC,CA6B7B;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,OAAO,CAAC,CAYlB;AAkBD;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,mBAAmB,CAAC,CA8B9B;AAED,kFAAkF;AAClF,wBAAsB,YAAY,CAChC,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE,mBAAwB,GAC7B,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAUhC;AAED,mDAAmD;AACnD,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,OAAO,CAAC,CAYlB;AA6BD,2DAA2D;AAC3D,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,wBAAwB,GAC9B,OAAO,CAAC,mBAAmB,CAAC,CA8B9B;AAED,gDAAgD;AAChD,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE,mBAAwB,GAC7B,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAUhC;AAED,6DAA6D;AAC7D,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,OAAO,CAAC,CAYlB"}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { METADATA_LIMITS, MetadataLimitError, clampMetadataLimit, parseSavedAnalysisQuery, } from "../metadata.js";
|
|
3
|
+
const ANNOTATION_COLS = `id, project_id, target_kind, target_id,
|
|
4
|
+
epoch_ms(since) AS since_ms, epoch_ms(until) AS until_ms, text,
|
|
5
|
+
author_kind, author_key_id,
|
|
6
|
+
epoch_ms(created_at) AS created_at_ms, epoch_ms(updated_at) AS updated_at_ms`;
|
|
7
|
+
function toDate(ms) {
|
|
8
|
+
return ms == null ? null : new Date(Number(ms));
|
|
9
|
+
}
|
|
10
|
+
function rowToAnnotation(row) {
|
|
11
|
+
return {
|
|
12
|
+
id: row.id,
|
|
13
|
+
projectId: row.project_id,
|
|
14
|
+
targetKind: row.target_kind,
|
|
15
|
+
targetId: row.target_id,
|
|
16
|
+
since: toDate(row.since_ms),
|
|
17
|
+
until: toDate(row.until_ms),
|
|
18
|
+
text: row.text,
|
|
19
|
+
authorKind: row.author_kind,
|
|
20
|
+
authorKeyId: row.author_key_id,
|
|
21
|
+
createdAt: new Date(Number(row.created_at_ms)),
|
|
22
|
+
updatedAt: new Date(Number(row.updated_at_ms)),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/** `SELECT count(*)` as a plain number, whatever width the driver returns. */
|
|
26
|
+
async function countRows(client, sql, params) {
|
|
27
|
+
const rows = await client.all(sql, params);
|
|
28
|
+
return Number(rows[0]?.n ?? 0);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Create one annotation and return the stored row.
|
|
32
|
+
*
|
|
33
|
+
* Refuses with {@link MetadataLimitError} once the project holds
|
|
34
|
+
* {@link METADATA_LIMITS.annotations} rows: metadata is curated notes, not an
|
|
35
|
+
* unbounded write surface, and refusing is more honest than evicting somebody
|
|
36
|
+
* else's note.
|
|
37
|
+
*/
|
|
38
|
+
export async function createAnnotation(client, projectId, input) {
|
|
39
|
+
const count = await countRows(client, `SELECT count(*) AS n FROM annotations WHERE project_id = $projectId`, { projectId });
|
|
40
|
+
if (count >= METADATA_LIMITS.annotations) {
|
|
41
|
+
throw new MetadataLimitError("annotations", METADATA_LIMITS.annotations);
|
|
42
|
+
}
|
|
43
|
+
const { annotation } = input;
|
|
44
|
+
const id = randomUUID();
|
|
45
|
+
await client.run(`INSERT INTO annotations
|
|
46
|
+
(id, project_id, target_kind, target_id, since, until, text,
|
|
47
|
+
author_kind, author_key_id, created_at, updated_at)
|
|
48
|
+
VALUES ($id, $projectId, $targetKind, $targetId,
|
|
49
|
+
CASE WHEN $sinceUs IS NULL THEN NULL ELSE make_timestamp($sinceUs) END,
|
|
50
|
+
CASE WHEN $untilUs IS NULL THEN NULL ELSE make_timestamp($untilUs) END,
|
|
51
|
+
$text, $authorKind, $authorKeyId, now(), now())`, {
|
|
52
|
+
id,
|
|
53
|
+
projectId,
|
|
54
|
+
targetKind: annotation.targetKind,
|
|
55
|
+
targetId: annotation.targetId ?? null,
|
|
56
|
+
sinceUs: annotation.since == null ? null : annotation.since * 1000,
|
|
57
|
+
untilUs: annotation.until == null ? null : annotation.until * 1000,
|
|
58
|
+
text: annotation.text,
|
|
59
|
+
authorKind: input.authorKind,
|
|
60
|
+
authorKeyId: input.authorKeyId,
|
|
61
|
+
});
|
|
62
|
+
const rows = await client.all(`SELECT ${ANNOTATION_COLS} FROM annotations WHERE id = $id`, { id });
|
|
63
|
+
// The row was just inserted on the same connection, so it is always there.
|
|
64
|
+
return rowToAnnotation(rows[0]);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* A project's annotations, newest first.
|
|
68
|
+
*
|
|
69
|
+
* The optional `since`/`until` bounds are an **overlap** filter, not a
|
|
70
|
+
* containment one: an annotation matches when its period intersects the
|
|
71
|
+
* requested window, and a standing note (no period at all) always matches
|
|
72
|
+
* because it is about the project rather than about a moment.
|
|
73
|
+
*/
|
|
74
|
+
export async function listAnnotations(client, projectId, opts = {}) {
|
|
75
|
+
const limit = clampMetadataLimit(opts.limit);
|
|
76
|
+
const params = { projectId };
|
|
77
|
+
const where = ["project_id = $projectId"];
|
|
78
|
+
if (opts.targetKind != null) {
|
|
79
|
+
where.push("target_kind = $targetKind");
|
|
80
|
+
params.targetKind = opts.targetKind;
|
|
81
|
+
}
|
|
82
|
+
if (opts.targetId != null) {
|
|
83
|
+
where.push("target_id = $targetId");
|
|
84
|
+
params.targetId = opts.targetId;
|
|
85
|
+
}
|
|
86
|
+
if (opts.since != null) {
|
|
87
|
+
where.push("(until IS NULL OR until >= make_timestamp($since))");
|
|
88
|
+
params.since = Math.trunc(opts.since) * 1000;
|
|
89
|
+
}
|
|
90
|
+
if (opts.until != null) {
|
|
91
|
+
where.push("(since IS NULL OR since < make_timestamp($until))");
|
|
92
|
+
params.until = Math.trunc(opts.until) * 1000;
|
|
93
|
+
}
|
|
94
|
+
const rows = await client.all(`SELECT ${ANNOTATION_COLS}
|
|
95
|
+
FROM annotations
|
|
96
|
+
WHERE ${where.join(" AND ")}
|
|
97
|
+
ORDER BY created_at DESC, id DESC
|
|
98
|
+
LIMIT ${limit}`, params);
|
|
99
|
+
return rows.map(rowToAnnotation);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Delete one annotation of this project. Returns whether a row was removed, so
|
|
103
|
+
* the route can answer 404 for an id that is not there (or belongs to another
|
|
104
|
+
* project — the two are indistinguishable to the caller, deliberately).
|
|
105
|
+
*/
|
|
106
|
+
export async function deleteAnnotation(client, projectId, id) {
|
|
107
|
+
const before = await countRows(client, `SELECT count(*) AS n FROM annotations WHERE project_id = $projectId AND id = $id`, { projectId, id });
|
|
108
|
+
if (before === 0)
|
|
109
|
+
return false;
|
|
110
|
+
await client.run(`DELETE FROM annotations WHERE project_id = $projectId AND id = $id`, {
|
|
111
|
+
projectId,
|
|
112
|
+
id,
|
|
113
|
+
});
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
function rowToGlossaryEntry(row) {
|
|
117
|
+
return {
|
|
118
|
+
projectId: row.project_id,
|
|
119
|
+
term: row.term,
|
|
120
|
+
meaning: row.meaning,
|
|
121
|
+
updatedAt: new Date(Number(row.updated_at_ms)),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Upsert one glossary entry and return the stored row. Idempotent: the term is
|
|
126
|
+
* the identity, so re-defining it replaces the meaning instead of accumulating
|
|
127
|
+
* duplicates. The per-project cap applies only when a *new* term is added.
|
|
128
|
+
*/
|
|
129
|
+
export async function putGlossaryEntry(client, projectId, input) {
|
|
130
|
+
const { term, meaning } = input.entry;
|
|
131
|
+
const existing = await countRows(client, `SELECT count(*) AS n FROM glossary WHERE project_id = $projectId AND term = $term`, { projectId, term });
|
|
132
|
+
if (existing === 0) {
|
|
133
|
+
const count = await countRows(client, `SELECT count(*) AS n FROM glossary WHERE project_id = $projectId`, { projectId });
|
|
134
|
+
if (count >= METADATA_LIMITS.glossary) {
|
|
135
|
+
throw new MetadataLimitError("glossary", METADATA_LIMITS.glossary);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
await client.run(`INSERT INTO glossary (project_id, term, meaning, updated_at)
|
|
139
|
+
VALUES ($projectId, $term, $meaning, now())
|
|
140
|
+
ON CONFLICT (project_id, term)
|
|
141
|
+
DO UPDATE SET meaning = EXCLUDED.meaning, updated_at = now()`, { projectId, term, meaning });
|
|
142
|
+
const rows = await client.all(`SELECT project_id, term, meaning, epoch_ms(updated_at) AS updated_at_ms
|
|
143
|
+
FROM glossary WHERE project_id = $projectId AND term = $term`, { projectId, term });
|
|
144
|
+
return rowToGlossaryEntry(rows[0]);
|
|
145
|
+
}
|
|
146
|
+
/** A project's whole glossary, ordered by term (stable for diffs and prompts). */
|
|
147
|
+
export async function listGlossary(client, projectId, opts = {}) {
|
|
148
|
+
const limit = clampMetadataLimit(opts.limit, METADATA_LIMITS.glossary, METADATA_LIMITS.glossary);
|
|
149
|
+
const rows = await client.all(`SELECT project_id, term, meaning, epoch_ms(updated_at) AS updated_at_ms
|
|
150
|
+
FROM glossary WHERE project_id = $projectId
|
|
151
|
+
ORDER BY term
|
|
152
|
+
LIMIT ${limit}`, { projectId });
|
|
153
|
+
return rows.map(rowToGlossaryEntry);
|
|
154
|
+
}
|
|
155
|
+
/** Delete one term. Returns whether it existed. */
|
|
156
|
+
export async function deleteGlossaryEntry(client, projectId, term) {
|
|
157
|
+
const before = await countRows(client, `SELECT count(*) AS n FROM glossary WHERE project_id = $projectId AND term = $term`, { projectId, term });
|
|
158
|
+
if (before === 0)
|
|
159
|
+
return false;
|
|
160
|
+
await client.run(`DELETE FROM glossary WHERE project_id = $projectId AND term = $term`, {
|
|
161
|
+
projectId,
|
|
162
|
+
term,
|
|
163
|
+
});
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
const ANALYSIS_COLS = `id, project_id, title, query, conclusion, author_kind, author_key_id,
|
|
167
|
+
epoch_ms(created_at) AS created_at_ms`;
|
|
168
|
+
function rowToSavedAnalysis(row) {
|
|
169
|
+
return {
|
|
170
|
+
id: row.id,
|
|
171
|
+
projectId: row.project_id,
|
|
172
|
+
title: row.title,
|
|
173
|
+
query: parseSavedAnalysisQuery(row.query),
|
|
174
|
+
conclusion: row.conclusion,
|
|
175
|
+
authorKind: row.author_kind,
|
|
176
|
+
authorKeyId: row.author_key_id,
|
|
177
|
+
createdAt: new Date(Number(row.created_at_ms)),
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
/** Create one saved analysis and return the stored row. */
|
|
181
|
+
export async function createSavedAnalysis(client, projectId, input) {
|
|
182
|
+
const count = await countRows(client, `SELECT count(*) AS n FROM saved_analyses WHERE project_id = $projectId`, { projectId });
|
|
183
|
+
if (count >= METADATA_LIMITS.savedAnalyses) {
|
|
184
|
+
throw new MetadataLimitError("savedAnalyses", METADATA_LIMITS.savedAnalyses);
|
|
185
|
+
}
|
|
186
|
+
const { analysis } = input;
|
|
187
|
+
const id = randomUUID();
|
|
188
|
+
await client.run(`INSERT INTO saved_analyses
|
|
189
|
+
(id, project_id, title, query, conclusion, author_kind, author_key_id, created_at)
|
|
190
|
+
VALUES ($id, $projectId, $title, $query, $conclusion, $authorKind, $authorKeyId, now())`, {
|
|
191
|
+
id,
|
|
192
|
+
projectId,
|
|
193
|
+
title: analysis.title,
|
|
194
|
+
query: JSON.stringify(analysis.query),
|
|
195
|
+
conclusion: analysis.conclusion ?? null,
|
|
196
|
+
authorKind: input.authorKind,
|
|
197
|
+
authorKeyId: input.authorKeyId,
|
|
198
|
+
});
|
|
199
|
+
const rows = await client.all(`SELECT ${ANALYSIS_COLS} FROM saved_analyses WHERE id = $id`, { id });
|
|
200
|
+
return rowToSavedAnalysis(rows[0]);
|
|
201
|
+
}
|
|
202
|
+
/** A project's saved analyses, newest first. */
|
|
203
|
+
export async function listSavedAnalyses(client, projectId, opts = {}) {
|
|
204
|
+
const limit = clampMetadataLimit(opts.limit);
|
|
205
|
+
const rows = await client.all(`SELECT ${ANALYSIS_COLS}
|
|
206
|
+
FROM saved_analyses WHERE project_id = $projectId
|
|
207
|
+
ORDER BY created_at DESC, id DESC
|
|
208
|
+
LIMIT ${limit}`, { projectId });
|
|
209
|
+
return rows.map(rowToSavedAnalysis);
|
|
210
|
+
}
|
|
211
|
+
/** Delete one saved analysis. Returns whether it existed. */
|
|
212
|
+
export async function deleteSavedAnalysis(client, projectId, id) {
|
|
213
|
+
const before = await countRows(client, `SELECT count(*) AS n FROM saved_analyses WHERE project_id = $projectId AND id = $id`, { projectId, id });
|
|
214
|
+
if (before === 0)
|
|
215
|
+
return false;
|
|
216
|
+
await client.run(`DELETE FROM saved_analyses WHERE project_id = $projectId AND id = $id`, {
|
|
217
|
+
projectId,
|
|
218
|
+
id,
|
|
219
|
+
});
|
|
220
|
+
return true;
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=projectMetadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projectMetadata.js","sourceRoot":"","sources":["../../src/duckdb/projectMetadata.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { Subscription } from "@uptimizr/schema";
|
|
2
|
+
import { type SubscriptionDeliveryOutcome, type SubscriptionEventInput, type SubscriptionEventQueryOptions, type SubscriptionEventRecord, type SubscriptionRecord } from "../subscriptions.js";
|
|
3
|
+
import type { DuckdbClient } from "./client.js";
|
|
4
|
+
/** A project's subscriptions, oldest first. */
|
|
5
|
+
export declare function listSubscriptions(client: DuckdbClient, projectId: string): Promise<SubscriptionRecord[]>;
|
|
6
|
+
/** Every enabled subscription across every project — the scheduler's resume read. */
|
|
7
|
+
export declare function listEnabledSubscriptions(client: DuckdbClient, limit?: number): Promise<SubscriptionRecord[]>;
|
|
8
|
+
/** One subscription, or `null` when it does not exist in this project. */
|
|
9
|
+
export declare function getSubscription(client: DuckdbClient, projectId: string, id: string): Promise<SubscriptionRecord | null>;
|
|
10
|
+
/**
|
|
11
|
+
* Store a new subscription.
|
|
12
|
+
*
|
|
13
|
+
* The per-project cap is checked and the row inserted inside one transaction on
|
|
14
|
+
* the exclusive connection, so two concurrent creates cannot both read
|
|
15
|
+
* `count = 99` and both insert.
|
|
16
|
+
*/
|
|
17
|
+
export declare function createSubscription(client: DuckdbClient, projectId: string, sub: Subscription): Promise<SubscriptionRecord>;
|
|
18
|
+
/** Enable or disable one subscription. `null` when it does not exist. */
|
|
19
|
+
export declare function setSubscriptionEnabled(client: DuckdbClient, projectId: string, id: string, enabled: boolean): Promise<SubscriptionRecord | null>;
|
|
20
|
+
/** Delete a subscription and its firings. `false` when it did not exist. */
|
|
21
|
+
export declare function deleteSubscription(client: DuckdbClient, projectId: string, id: string): Promise<boolean>;
|
|
22
|
+
/**
|
|
23
|
+
* Write back what a delivery attempt learned. Each field is optional, so a
|
|
24
|
+
* successful delivery (`firedAt`, `failures: 0`, `lastError: null`) and a failed
|
|
25
|
+
* one (`lastError`, `failures: n`) use the same call.
|
|
26
|
+
*/
|
|
27
|
+
export declare function recordSubscriptionOutcome(client: DuckdbClient, projectId: string, id: string, outcome: SubscriptionDeliveryOutcome): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* The webhook signing secret for one subscription, or `null`.
|
|
30
|
+
*
|
|
31
|
+
* The only path that reads the column. Everything else — the list, the get, the
|
|
32
|
+
* API responses — selects {@link SELECT_COLS}, which deliberately omits it.
|
|
33
|
+
*/
|
|
34
|
+
export declare function getWebhookSecret(client: DuckdbClient, projectId: string, id: string): Promise<string | null>;
|
|
35
|
+
/**
|
|
36
|
+
* Append one firing and drop everything past the retained window.
|
|
37
|
+
*
|
|
38
|
+
* The trim is a `DELETE … WHERE "at" < (the Nth newest)` rather than a row-number
|
|
39
|
+
* window, because DuckDB will not delete from a CTE over the same table. Both
|
|
40
|
+
* statements run in one transaction, so the bound is never observed broken.
|
|
41
|
+
*/
|
|
42
|
+
export declare function recordSubscriptionEvent(client: DuckdbClient, entry: SubscriptionEventInput): Promise<void>;
|
|
43
|
+
/** A subscription's recent firings, newest first. */
|
|
44
|
+
export declare function listSubscriptionEvents(client: DuckdbClient, projectId: string, id: string, opts?: SubscriptionEventQueryOptions): Promise<SubscriptionEventRecord[]>;
|
|
45
|
+
//# sourceMappingURL=subscriptions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscriptions.d.ts","sourceRoot":"","sources":["../../src/duckdb/subscriptions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAUL,KAAK,2BAA2B,EAChC,KAAK,sBAAsB,EAC3B,KAAK,6BAA6B,EAClC,KAAK,uBAAuB,EAE5B,KAAK,kBAAkB,EAExB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA6BhD,+CAA+C;AAC/C,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAQ/B;AAED,qFAAqF;AACrF,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,YAAY,EACpB,KAAK,GAAE,MAAkC,GACxC,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAS/B;AAED,0EAA0E;AAC1E,wBAAsB,eAAe,CACnC,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAQpC;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,YAAY,GAChB,OAAO,CAAC,kBAAkB,CAAC,CAyC7B;AAED,yEAAyE;AACzE,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAOpC;AAED,4EAA4E;AAC5E,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,OAAO,CAAC,CAqBlB;AAED;;;;GAIG;AACH,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOxB;AAED;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,sBAAsB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAiCf;AAED,qDAAqD;AACrD,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,EACV,IAAI,GAAE,6BAAkC,GACvC,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAUpC"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { MAX_ENABLED_SUBSCRIPTIONS, MAX_SUBSCRIPTIONS_PER_PROJECT, MAX_SUBSCRIPTION_EVENTS, SubscriptionLimitError, clampEventLimit, clampSubscriptionError, rowToSubscription, rowToSubscriptionEvent, toSubscriptionColumns, } from "../subscriptions.js";
|
|
3
|
+
/**
|
|
4
|
+
* **Conditional subscriptions** for the DuckDB single-file store (ADR 0051 §6 /
|
|
5
|
+
* sketch §F.1–F.2).
|
|
6
|
+
*
|
|
7
|
+
* Two tables, both plain metadata — no event type is added and
|
|
8
|
+
* `@uptimizr/schema`'s event union is untouched:
|
|
9
|
+
*
|
|
10
|
+
* - `subscriptions` — one row per standing question, keyed by `id` and scoped to
|
|
11
|
+
* a project. The declaration itself lives in a JSON `config` column; the
|
|
12
|
+
* scalars beside it are exactly what the store must filter, order or update.
|
|
13
|
+
* - `subscription_events` — the bounded firing log, last
|
|
14
|
+
* {@link MAX_SUBSCRIPTION_EVENTS} per subscription. The trim runs inside the
|
|
15
|
+
* same transaction as the insert, so the bound holds even if the collector
|
|
16
|
+
* dies between the two.
|
|
17
|
+
*
|
|
18
|
+
* `at` is a DuckDB keyword, so it is double-quoted here and in the migration —
|
|
19
|
+
* the column name matches the other three engines, where it needs no quoting.
|
|
20
|
+
*/
|
|
21
|
+
const SELECT_COLS = `id, project_id, name, metric, config, enabled,
|
|
22
|
+
epoch_ms(created_at) AS created_at_ms,
|
|
23
|
+
epoch_ms(updated_at) AS updated_at_ms,
|
|
24
|
+
epoch_ms(last_fired_at) AS last_fired_at_ms,
|
|
25
|
+
last_error, failures`;
|
|
26
|
+
const EVENT_COLS = `id, subscription_id, project_id, epoch_ms("at") AS at_ms, payload`;
|
|
27
|
+
/** A project's subscriptions, oldest first. */
|
|
28
|
+
export async function listSubscriptions(client, projectId) {
|
|
29
|
+
const rows = await client.all(`SELECT ${SELECT_COLS} FROM subscriptions
|
|
30
|
+
WHERE project_id = $projectId
|
|
31
|
+
ORDER BY created_at, id`, { projectId });
|
|
32
|
+
return rows.map(rowToSubscription);
|
|
33
|
+
}
|
|
34
|
+
/** Every enabled subscription across every project — the scheduler's resume read. */
|
|
35
|
+
export async function listEnabledSubscriptions(client, limit = MAX_ENABLED_SUBSCRIPTIONS) {
|
|
36
|
+
const capped = Math.min(Math.max(Math.trunc(limit), 1), MAX_ENABLED_SUBSCRIPTIONS);
|
|
37
|
+
const rows = await client.all(`SELECT ${SELECT_COLS} FROM subscriptions
|
|
38
|
+
WHERE enabled
|
|
39
|
+
ORDER BY created_at, id
|
|
40
|
+
LIMIT ${capped}`);
|
|
41
|
+
return rows.map(rowToSubscription);
|
|
42
|
+
}
|
|
43
|
+
/** One subscription, or `null` when it does not exist in this project. */
|
|
44
|
+
export async function getSubscription(client, projectId, id) {
|
|
45
|
+
const rows = await client.all(`SELECT ${SELECT_COLS} FROM subscriptions
|
|
46
|
+
WHERE project_id = $projectId AND id = $id`, { projectId, id });
|
|
47
|
+
const row = rows[0];
|
|
48
|
+
return row == null ? null : rowToSubscription(row);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Store a new subscription.
|
|
52
|
+
*
|
|
53
|
+
* The per-project cap is checked and the row inserted inside one transaction on
|
|
54
|
+
* the exclusive connection, so two concurrent creates cannot both read
|
|
55
|
+
* `count = 99` and both insert.
|
|
56
|
+
*/
|
|
57
|
+
export async function createSubscription(client, projectId, sub) {
|
|
58
|
+
const id = `sub_${randomUUID().replace(/-/g, "").slice(0, 24)}`;
|
|
59
|
+
const cols = toSubscriptionColumns(sub);
|
|
60
|
+
await client.exclusive(async (con) => {
|
|
61
|
+
await con.run("BEGIN TRANSACTION");
|
|
62
|
+
try {
|
|
63
|
+
const reader = await con.runAndReadAll(`SELECT count(*) AS n FROM subscriptions WHERE project_id = $projectId`, { projectId });
|
|
64
|
+
const counted = reader.getRowObjects()[0]?.n;
|
|
65
|
+
if (Number(counted ?? 0) >= MAX_SUBSCRIPTIONS_PER_PROJECT) {
|
|
66
|
+
throw new SubscriptionLimitError();
|
|
67
|
+
}
|
|
68
|
+
await con.run(`INSERT INTO subscriptions
|
|
69
|
+
(id, project_id, name, metric, config, webhook_secret, enabled,
|
|
70
|
+
created_at, updated_at, last_fired_at, last_error, failures)
|
|
71
|
+
VALUES ($id, $projectId, $name, $metric, $config, $webhookSecret, $enabled,
|
|
72
|
+
now(), now(), NULL, NULL, 0)`, {
|
|
73
|
+
id,
|
|
74
|
+
projectId,
|
|
75
|
+
name: cols.name,
|
|
76
|
+
metric: cols.metric,
|
|
77
|
+
config: cols.config,
|
|
78
|
+
webhookSecret: cols.webhookSecret,
|
|
79
|
+
enabled: cols.enabled,
|
|
80
|
+
});
|
|
81
|
+
await con.run("COMMIT");
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
await con.run("ROLLBACK");
|
|
85
|
+
throw err;
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
const stored = await getSubscription(client, projectId, id);
|
|
89
|
+
// The row was just inserted in a committed transaction; a null here would mean
|
|
90
|
+
// the store lost it, which is a fault, not an empty result.
|
|
91
|
+
if (stored == null)
|
|
92
|
+
throw new Error(`subscription ${id} vanished after insert`);
|
|
93
|
+
return stored;
|
|
94
|
+
}
|
|
95
|
+
/** Enable or disable one subscription. `null` when it does not exist. */
|
|
96
|
+
export async function setSubscriptionEnabled(client, projectId, id, enabled) {
|
|
97
|
+
await client.run(`UPDATE subscriptions SET enabled = $enabled, updated_at = now()
|
|
98
|
+
WHERE project_id = $projectId AND id = $id`, { projectId, id, enabled });
|
|
99
|
+
return getSubscription(client, projectId, id);
|
|
100
|
+
}
|
|
101
|
+
/** Delete a subscription and its firings. `false` when it did not exist. */
|
|
102
|
+
export async function deleteSubscription(client, projectId, id) {
|
|
103
|
+
const existing = await getSubscription(client, projectId, id);
|
|
104
|
+
if (existing == null)
|
|
105
|
+
return false;
|
|
106
|
+
await client.exclusive(async (con) => {
|
|
107
|
+
await con.run("BEGIN TRANSACTION");
|
|
108
|
+
try {
|
|
109
|
+
await con.run(`DELETE FROM subscription_events WHERE project_id = $projectId AND subscription_id = $id`, { projectId, id });
|
|
110
|
+
await con.run(`DELETE FROM subscriptions WHERE project_id = $projectId AND id = $id`, {
|
|
111
|
+
projectId,
|
|
112
|
+
id,
|
|
113
|
+
});
|
|
114
|
+
await con.run("COMMIT");
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
await con.run("ROLLBACK");
|
|
118
|
+
throw err;
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Write back what a delivery attempt learned. Each field is optional, so a
|
|
125
|
+
* successful delivery (`firedAt`, `failures: 0`, `lastError: null`) and a failed
|
|
126
|
+
* one (`lastError`, `failures: n`) use the same call.
|
|
127
|
+
*/
|
|
128
|
+
export async function recordSubscriptionOutcome(client, projectId, id, outcome) {
|
|
129
|
+
const sets = ["updated_at = now()"];
|
|
130
|
+
const params = { projectId, id };
|
|
131
|
+
if (outcome.firedAt != null) {
|
|
132
|
+
sets.push("last_fired_at = make_timestamp($firedAtUs)");
|
|
133
|
+
params.firedAtUs = outcome.firedAt.getTime() * 1000;
|
|
134
|
+
}
|
|
135
|
+
if (outcome.lastError !== undefined) {
|
|
136
|
+
sets.push("last_error = $lastError");
|
|
137
|
+
params.lastError = outcome.lastError == null ? null : clampSubscriptionError(outcome.lastError);
|
|
138
|
+
}
|
|
139
|
+
if (outcome.failures !== undefined) {
|
|
140
|
+
sets.push("failures = CAST($failures AS BIGINT)");
|
|
141
|
+
params.failures = Math.max(0, Math.trunc(outcome.failures));
|
|
142
|
+
}
|
|
143
|
+
await client.run(`UPDATE subscriptions SET ${sets.join(", ")}
|
|
144
|
+
WHERE project_id = $projectId AND id = $id`, params);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* The webhook signing secret for one subscription, or `null`.
|
|
148
|
+
*
|
|
149
|
+
* The only path that reads the column. Everything else — the list, the get, the
|
|
150
|
+
* API responses — selects {@link SELECT_COLS}, which deliberately omits it.
|
|
151
|
+
*/
|
|
152
|
+
export async function getWebhookSecret(client, projectId, id) {
|
|
153
|
+
const rows = await client.all(`SELECT webhook_secret FROM subscriptions WHERE project_id = $projectId AND id = $id`, { projectId, id });
|
|
154
|
+
const secret = rows[0]?.webhook_secret;
|
|
155
|
+
return secret == null || secret === "" ? null : secret;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Append one firing and drop everything past the retained window.
|
|
159
|
+
*
|
|
160
|
+
* The trim is a `DELETE … WHERE "at" < (the Nth newest)` rather than a row-number
|
|
161
|
+
* window, because DuckDB will not delete from a CTE over the same table. Both
|
|
162
|
+
* statements run in one transaction, so the bound is never observed broken.
|
|
163
|
+
*/
|
|
164
|
+
export async function recordSubscriptionEvent(client, entry) {
|
|
165
|
+
const at = entry.at ?? new Date();
|
|
166
|
+
await client.exclusive(async (con) => {
|
|
167
|
+
await con.run("BEGIN TRANSACTION");
|
|
168
|
+
try {
|
|
169
|
+
await con.run(`INSERT INTO subscription_events (id, subscription_id, project_id, "at", payload)
|
|
170
|
+
VALUES ($id, $subscriptionId, $projectId, make_timestamp($atUs), $payload)`, {
|
|
171
|
+
id: randomUUID(),
|
|
172
|
+
subscriptionId: entry.subscriptionId,
|
|
173
|
+
projectId: entry.projectId,
|
|
174
|
+
atUs: at.getTime() * 1000,
|
|
175
|
+
payload: JSON.stringify(entry.payload),
|
|
176
|
+
});
|
|
177
|
+
await con.run(`DELETE FROM subscription_events
|
|
178
|
+
WHERE subscription_id = $subscriptionId
|
|
179
|
+
AND id NOT IN (
|
|
180
|
+
SELECT id FROM subscription_events
|
|
181
|
+
WHERE subscription_id = $subscriptionId
|
|
182
|
+
ORDER BY "at" DESC, id DESC
|
|
183
|
+
LIMIT ${MAX_SUBSCRIPTION_EVENTS}
|
|
184
|
+
)`, { subscriptionId: entry.subscriptionId });
|
|
185
|
+
await con.run("COMMIT");
|
|
186
|
+
}
|
|
187
|
+
catch (err) {
|
|
188
|
+
await con.run("ROLLBACK");
|
|
189
|
+
throw err;
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
/** A subscription's recent firings, newest first. */
|
|
194
|
+
export async function listSubscriptionEvents(client, projectId, id, opts = {}) {
|
|
195
|
+
const limit = clampEventLimit(opts.limit);
|
|
196
|
+
const rows = await client.all(`SELECT ${EVENT_COLS} FROM subscription_events
|
|
197
|
+
WHERE project_id = $projectId AND subscription_id = $id
|
|
198
|
+
ORDER BY "at" DESC, id DESC
|
|
199
|
+
LIMIT ${limit}`, { projectId, id });
|
|
200
|
+
return rows.map(rowToSubscriptionEvent);
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=subscriptions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscriptions.js","sourceRoot":"","sources":["../../src/duckdb/subscriptions.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -17,6 +17,8 @@ export { toNodeSampleRow, nodeSampleRowToEvent } from "./events.js";
|
|
|
17
17
|
export type { NodeSampleRow } from "./events.js";
|
|
18
18
|
export { hashApiKey, apiKeyPrefix, generateApiKey } from "./metadata.js";
|
|
19
19
|
export { API_KEY_CAPABILITIES, AUDIT_PARAMS_MAX_LENGTH, AUDIT_TOOL_MAX_LENGTH, DEFAULT_API_KEY_CAPABILITIES, clampAuditTool, hasCapability, isApiKeyCapability, parseApiKeyCapabilities, parseCapabilityList, serializeApiKeyCapabilities, serializeAuditParams, toApiKeyColumns, toApiKeyRateLimit, } from "./metadata.js";
|
|
20
|
+
export { METADATA_LIMITS, MetadataLimitError, clampMetadataLimit, parsePanelSpec, parseSavedAnalysisQuery, } from "./metadata.js";
|
|
21
|
+
export type { AnnotationRecord, AnnotationTargetKind, CreateAnnotationInput, CreatePanelSpecInput, CreateSavedAnalysisInput, GlossaryEntryRecord, ListAnnotationsOptions, MetadataAuthor, MetadataAuthorKind, MetadataListOptions, MetadataTable, PanelSpecRecord, PutGlossaryEntryInput, SavedAnalysisRecord, UpdatePanelSpecInput, } from "./metadata.js";
|
|
20
22
|
export type { Project, AgentAuditEntry, AgentAuditInput, ApiKeyRecord, ApiKeyCapability, ApiKeyRateLimit, AuditQueryOptions, AuditSurface, CreateApiKeyOptions, ResolvedApiKey, SceneRepresentation, SceneRepresentationKind, SceneRepresentationSummary, SceneRegionRecord, SceneRegionSummary, } from "./metadata.js";
|
|
21
23
|
export type { Dialect, ParamType, AsofJoinSpec } from "./query/dialect.js";
|
|
22
24
|
export { duckdbDialect, toDuckdbTimestamp } from "./query/duckdbDialect.js";
|
|
@@ -25,11 +27,18 @@ export { postgresDialect, toPostgresTimestamp, POSTGRES_NEAREST_ROW_JOIN, } from
|
|
|
25
27
|
export { mssqlDialect, toMssqlTimestamp, toTsql, mssqlVectorElement, MSSQL_NEAREST_ROW_JOIN, MSSQL_BIN_COLLATION, MSSQL_QUANTILE_FUNCTION, } from "./query/mssqlDialect.js";
|
|
26
28
|
export { renderNativeAsofJoin, renderNearestRowJoin, toPositionalParams, } from "./query/relational.js";
|
|
27
29
|
export type { NearestRowJoinTokens, PositionalQuery } from "./query/relational.js";
|
|
28
|
-
export { buildListSessions, buildPointerHeatmap, buildMeshUvHeatmap, buildWorldHeatmap, buildWorldHeatmapStats, buildGazeHeatmap, buildGazeHeatmapStats, buildCameraDirectionHeatmap, buildViewCoverageHistogram, buildCameraPositionHeatmap, defaultCellSizeForBounds, buildSessionTrajectory, buildAggregateTrajectories, buildClickGazeRay, buildFlowHeatmap, buildTopMeshes, buildTopMeshesBySource, buildTopMeshesTrend, buildMeshDwell, buildMeshBlindSpots, buildMeshInteractionKinds, buildReachability, buildTopInputActions, buildDeadClicks, buildRageClicks, buildHoverDwell, buildCompileStalls, buildResourceSummary, buildCapabilityChanges, buildCameraGestures, buildPerfSummary, buildRenderScaleTruth, buildPerfDistribution, buildFpsHistogram, buildFrameTimePercentiles, buildJankRate, buildPerfChurn, buildPerfByDevice, buildPerfByScene, buildResourcePercentiles, buildStabilityCounts, buildGraphicsDiagnosticCounts, buildErrorHeatmap, buildBoundaryHeatmap, buildBoundaryHeatmapStats, buildBoundaryContacts, buildRenderingTechnology, buildPerfDaily, buildEventsDaily, buildDistinctScenes, buildTimeseries, buildEventTypeCounts, buildSceneCoverage, buildPerfHeatmap, buildCameraDistance, buildNavigationStats, buildBacktrackRatio, buildXrRotationRate, buildXrSourceUsage, buildXrAbandonment, buildXrLocomotionComfort, buildTrackingQuality, buildInteractionsBySource, buildArPlacementTimeToPlace, buildArPlacementAttempts, buildArPlacementSurfaces, buildFunnel, buildSceneRetention, buildLoadBounceFunnel, buildVariantLeaderboard, } from "./query/aggregations.js";
|
|
30
|
+
export { buildListSessions, buildPointerHeatmap, buildMeshUvHeatmap, buildWorldHeatmap, buildWorldHeatmapStats, buildGazeHeatmap, buildGazeHeatmapStats, buildCameraDirectionHeatmap, buildViewCoverageHistogram, buildCameraPositionHeatmap, defaultCellSizeForBounds, buildSessionTrajectory, buildAggregateTrajectories, buildClickGazeRay, buildFlowHeatmap, buildTopMeshes, buildTopMeshesBySource, buildTopMeshesTrend, buildMeshDwell, buildMeshBlindSpots, buildMeshInteractionKinds, buildReachability, buildTopInputActions, buildCustomEventVocabulary, CUSTOM_EVENT_VOCABULARY_LIMIT, CUSTOM_EVENT_VOCABULARY_MAX_LIMIT, CUSTOM_EVENT_VOCABULARY_SAMPLE_ROWS, CUSTOM_EVENT_VOCABULARY_MAX_SAMPLE_ROWS, buildDeadClicks, buildRageClicks, buildHoverDwell, buildCompileStalls, buildResourceSummary, buildCapabilityChanges, buildCameraGestures, buildPerfSummary, buildRenderScaleTruth, buildPerfDistribution, buildFpsHistogram, buildFrameTimePercentiles, buildJankRate, buildPerfChurn, buildPerfByDevice, buildPerfByScene, buildResourcePercentiles, buildStabilityCounts, buildGraphicsDiagnosticCounts, buildErrorHeatmap, buildBoundaryHeatmap, buildBoundaryHeatmapStats, buildBoundaryContacts, buildRenderingTechnology, buildPerfDaily, buildEventsDaily, buildDistinctScenes, buildTimeseries, buildEventTypeCounts, buildSceneCoverage, buildPerfHeatmap, buildCameraDistance, buildNavigationStats, buildBacktrackRatio, buildXrRotationRate, buildXrSourceUsage, buildXrAbandonment, buildXrLocomotionComfort, buildTrackingQuality, buildInteractionsBySource, buildArPlacementTimeToPlace, buildArPlacementAttempts, buildArPlacementSurfaces, buildFunnel, buildSceneRetention, buildLoadBounceFunnel, buildVariantLeaderboard, } from "./query/aggregations.js";
|
|
31
|
+
export { foldCustomEventVocabulary, CUSTOM_EVENT_VOCABULARY_MAX_PROPS, } from "./query/customEventVocabulary.js";
|
|
32
|
+
export type { FoldCustomEventVocabularyOptions } from "./query/customEventVocabulary.js";
|
|
29
33
|
export { coerceRows, numericColumns, numericColumnsOfMetric } from "./query/coerce.js";
|
|
30
34
|
export type { CoerceRowsOptions } from "./query/coerce.js";
|
|
35
|
+
export { DEFAULT_ALPHA, ORDER_AFTER_CAP_CAVEAT, applyOrder, compileGenericGroupBy, builderFor, cameraTypeForMode, channelRows, compareRows, comparisonKeys, compileMetric, compileQuery, explainQuery, explainSpec, genericResultColumns, planWarnings, reordersCappedResult, sampleOf, silentChannels, studentTTwoSided, summarizeComparison, toBuilderOptions, twoProportionZ, welchT, wilsonScoreInterval, } from "./query/dsl/index.js";
|
|
36
|
+
export type { AggregationBuilder, ComparisonBasis, ComparisonContext, ComparisonMeta, ComparisonResult, ComparisonRow, ComparisonSide, ExplainParam, ExplainParamType, GenericDeviceFilter, GenericEventPredicate, GenericQueryOptions, MeanSignificance, MetricQueryOptions, MoversSummary, PlanContext, Proportion, ProportionSignificance, QueryPlan, QueryResolution, ResultOrder, Sample, ScoreInterval, Significance, } from "./query/dsl/index.js";
|
|
31
37
|
export * from "./query/summary/index.js";
|
|
32
|
-
export
|
|
38
|
+
export * from "./insights/index.js";
|
|
39
|
+
export type { QuerySpec, RangeOptions, SceneOptions, SourceOptions, SessionOptions, MeshOptions, RegionOptions, ErrorHeatmapOptions, WorldAabb, CameraModeOptions, TimeseriesOptions, SessionSummaryRow, HeatmapBinRow, WorldHeatmapBinRow, SpatialStatsRow, PositionBinRow, TrajectoryPointRow, AggregateTrajectoryPointRow, DirectionBinRow, ViewCoverageHistogramRow, ClickGazeRayRow, FlowLinkRow, MeshCountRow, MeshDwellRow, MeshBlindSpotRow, MeshInteractionKindRow, ReachabilityBinRow, MeshSourceCountRow, MeshTrendPointRow, InputActionCountRow, CustomEventVocabularyOptions, CustomEventVocabularyRow, CustomEventVocabularySampleRow, CustomPropType, DeadClickRow, RageClickRow, HoverDwellRow, CompileStallRow, ArPlacementTimeToPlaceRow, ArPlacementAttemptsRow, ArPlacementSurfaceRow, ResourceSummaryRow, CapabilityChangeRow, CameraGestureRow, PerfSummaryRow, RenderScaleTruthRow, PerfDistributionRow, FpsHistogramRow, FrameTimePercentileRow, JankRateRow, PerfChurnOptions, PerfChurnRow, PerfByDeviceRow, PerfBySceneRow, ResourcePercentileRow, StabilityCountRow, GraphicsDiagnosticCountRow, RenderingTechnologyRow, PerfDailyRow, EventsDailyRow, SceneRow, TimeseriesBucketRow, EventTypeCountRow, CoverageVoxelRow, PerfHeatmapVoxelRow, CameraDistanceBucketRow, NavigationStatsRow, BacktrackRatioRow, XrRotationRateRow, XrSourceUsageRow, XrAbandonmentRow, XrLocomotionRow, BoundaryContactsRow, TrackingQualityRow, InteractionSourceRow, FunnelStepInput, FunnelOptions, FunnelStepResultRow, SceneRetentionOptions, SceneRetentionRow, LoadBounceFunnelOptions, LoadBounceBandRow, VariantLeaderboardOptions, VariantLeaderboardRow, } from "./query/types.js";
|
|
40
|
+
export { DEFAULT_COOLDOWN, MASKED_SECRET, MAX_ENABLED_SUBSCRIPTIONS, MAX_SUBSCRIPTIONS_PER_PROJECT, MAX_SUBSCRIPTION_EVENTS, SUBSCRIPTION_ERROR_MAX_LENGTH, SubscriptionLimitError, clampEventLimit, clampSubscriptionError, rowToSubscription, rowToSubscriptionEvent, toSubscriptionColumns, } from "./subscriptions.js";
|
|
41
|
+
export type { SubscriptionDeliveryOutcome, SubscriptionEventInput, SubscriptionEventQueryOptions, SubscriptionEventRecord, SubscriptionEventRowLike, SubscriptionRecord, SubscriptionRowLike, SubscriptionStore, } from "./subscriptions.js";
|
|
33
42
|
export { createDuckdbClient, convertValue } from "./duckdb/client.js";
|
|
34
43
|
export type { DuckdbClient, DuckdbRow } from "./duckdb/client.js";
|
|
35
44
|
export { DUCKDB_MIGRATIONS, migrateDuckdb } from "./duckdb/migrations.js";
|
|
@@ -39,9 +48,14 @@ export { createProject as duckdbCreateProject, getProject as duckdbGetProject, c
|
|
|
39
48
|
export { recordAudit as duckdbRecordAudit, listAudit as duckdbListAudit, pruneAudit as duckdbPruneAudit, } from "./duckdb/audit.js";
|
|
40
49
|
export { upsertSceneProxy as duckdbUpsertSceneProxy, getSceneRepresentation as duckdbGetSceneRepresentation, listSceneRepresentations as duckdbListSceneRepresentations, } from "./duckdb/sceneRegistry.js";
|
|
41
50
|
export { putSceneRegions as duckdbPutSceneRegions, getSceneRegions as duckdbGetSceneRegions, listSceneRegions as duckdbListSceneRegions, } from "./duckdb/sceneRegions.js";
|
|
51
|
+
export { createAnnotation as duckdbCreateAnnotation, listAnnotations as duckdbListAnnotations, deleteAnnotation as duckdbDeleteAnnotation, putGlossaryEntry as duckdbPutGlossaryEntry, listGlossary as duckdbListGlossary, deleteGlossaryEntry as duckdbDeleteGlossaryEntry, createSavedAnalysis as duckdbCreateSavedAnalysis, listSavedAnalyses as duckdbListSavedAnalyses, deleteSavedAnalysis as duckdbDeleteSavedAnalysis, } from "./duckdb/projectMetadata.js";
|
|
52
|
+
export { createPanelSpec as duckdbCreatePanelSpec, listPanelSpecs as duckdbListPanelSpecs, updatePanelSpec as duckdbUpdatePanelSpec, deletePanelSpec as duckdbDeletePanelSpec, } from "./duckdb/panelSpecs.js";
|
|
53
|
+
export { listSubscriptions as duckdbListSubscriptions, listEnabledSubscriptions as duckdbListEnabledSubscriptions, getSubscription as duckdbGetSubscription, createSubscription as duckdbCreateSubscription, setSubscriptionEnabled as duckdbSetSubscriptionEnabled, deleteSubscription as duckdbDeleteSubscription, recordSubscriptionOutcome as duckdbRecordSubscriptionOutcome, getWebhookSecret as duckdbGetWebhookSecret, recordSubscriptionEvent as duckdbRecordSubscriptionEvent, listSubscriptionEvents as duckdbListSubscriptionEvents, } from "./duckdb/subscriptions.js";
|
|
42
54
|
export { PARITY_PROJECT_ID, PARITY_T0, PARITY_RANGE, PARITY_DAY_RANGE, PARITY_DAY, PARITY_EVENTS, } from "./parity/fixtures.js";
|
|
43
|
-
export { PARITY_ABS_TOLERANCE, PARITY_REL_TOLERANCE, diffParity, numericColumnsForSpec, } from "./parity/compare.js";
|
|
55
|
+
export { ENGINE_FORMATTED_COLUMNS, PARITY_ABS_TOLERANCE, PARITY_REL_TOLERANCE, diffParity, numericColumnsForSpec, } from "./parity/compare.js";
|
|
44
56
|
export type { ParityRow, ParityCompareOptions } from "./parity/compare.js";
|
|
45
|
-
export { PARITY_CASES } from "./parity/cases.js";
|
|
57
|
+
export { GENERIC_PARITY_CASE_NAMES, PARITY_CASES } from "./parity/cases.js";
|
|
46
58
|
export type { ParityCase } from "./parity/cases.js";
|
|
59
|
+
export { buildSessionNarrative, renderSessionNarrativeText } from "./narrative/index.js";
|
|
60
|
+
export type { SessionNarrative, SessionNarrativeOptions } from "./narrative/index.js";
|
|
47
61
|
//# sourceMappingURL=index.d.ts.map
|