@gscdump/cloudflare 0.26.10 → 0.27.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.
|
@@ -1,24 +1,13 @@
|
|
|
1
|
-
import { ArchetypeQuery, ArchetypeResult, ArchetypeResultRow } from "@gscdump/
|
|
1
|
+
import { ArchetypeQuery, ArchetypeResult, ArchetypeResultRow } from "@gscdump/contracts/archetypes";
|
|
2
2
|
import { Result } from "gscdump/result";
|
|
3
|
-
import { IcebergTableName } from "@gscdump/engine/iceberg";
|
|
4
3
|
import { ServerTailDirective } from "@gscdump/contracts";
|
|
5
|
-
/** Placeholder substituted for the engine-specific table reference. */
|
|
6
4
|
declare const TABLE_PLACEHOLDER = "{{TABLE}}";
|
|
7
|
-
|
|
5
|
+
type ArchetypeFactTable = 'pages' | 'queries' | 'countries' | 'page_queries' | 'dates';
|
|
8
6
|
interface ArchetypeSqlPlan {
|
|
9
|
-
/** SQL with `{{TABLE}}` standing in for the table reference. */
|
|
10
7
|
sql: string;
|
|
11
|
-
/** Bound parameters, in `?`-order. */
|
|
12
8
|
params: unknown[];
|
|
13
|
-
|
|
14
|
-
table: IcebergTableName;
|
|
9
|
+
table: ArchetypeFactTable;
|
|
15
10
|
}
|
|
16
|
-
/**
|
|
17
|
-
* Translate an archetype query to a dialect-neutral SQL plan.
|
|
18
|
-
*
|
|
19
|
-
* Throws for `arbitrary-sql` (caller-supplied SQL, handled by the DuckDB
|
|
20
|
-
* executor directly) and `aux-cloud-only` (not an Iceberg query).
|
|
21
|
-
*/
|
|
22
11
|
declare function buildArchetypeSql(query: ArchetypeQuery): ArchetypeSqlPlan;
|
|
23
12
|
/** Row returned by the DuckDB sibling. */
|
|
24
13
|
type DuckDbIcebergRow = Record<string, string | number | null>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { bindLiterals
|
|
2
|
-
import { ARCHETYPE_EXECUTION_CLASS } from "@gscdump/
|
|
1
|
+
import { bindLiterals } from "@gscdump/engine";
|
|
2
|
+
import { ARCHETYPE_EXECUTION_CLASS } from "@gscdump/contracts/archetypes";
|
|
3
3
|
import { err, ok, unwrapResult } from "gscdump/result";
|
|
4
4
|
const TABLE_PLACEHOLDER = "{{TABLE}}";
|
|
5
5
|
function dimColumn(dim) {
|
|
@@ -7,6 +7,14 @@ function dimColumn(dim) {
|
|
|
7
7
|
if (dim === "queryCanonical") return "query_canonical";
|
|
8
8
|
return dim;
|
|
9
9
|
}
|
|
10
|
+
function tableForDimensions(dims) {
|
|
11
|
+
const set = new Set(dims.filter((d) => d !== "date"));
|
|
12
|
+
if (set.has("page") && (set.has("query") || set.has("queryCanonical"))) return "page_queries";
|
|
13
|
+
if (set.has("query") || set.has("queryCanonical")) return "queries";
|
|
14
|
+
if (set.has("country")) return "countries";
|
|
15
|
+
if (set.has("device")) return "dates";
|
|
16
|
+
return "pages";
|
|
17
|
+
}
|
|
10
18
|
function metricExpr(metric) {
|
|
11
19
|
switch (metric) {
|
|
12
20
|
case "clicks": return "SUM(clicks) AS clicks";
|
|
@@ -128,7 +136,7 @@ function buildSiteDailyTimeseries(q) {
|
|
|
128
136
|
};
|
|
129
137
|
}
|
|
130
138
|
function buildEntityDailyTimeseries(q) {
|
|
131
|
-
const table =
|
|
139
|
+
const table = tableForDimensions([q.entity.dimension]);
|
|
132
140
|
const w = partitionWhere(q);
|
|
133
141
|
const col = dimColumn(q.entity.dimension);
|
|
134
142
|
const metrics = q.metrics.map(metricExpr).join(", ");
|
|
@@ -139,10 +147,10 @@ function buildEntityDailyTimeseries(q) {
|
|
|
139
147
|
};
|
|
140
148
|
}
|
|
141
149
|
function buildEntityDailySparkline(q) {
|
|
142
|
-
const table =
|
|
150
|
+
const table = tableForDimensions([q.dimension]);
|
|
143
151
|
const w = partitionWhere(q);
|
|
144
152
|
const col = dimColumn(q.dimension);
|
|
145
|
-
if (q.entities.length === 0) throw new Error("entity-daily-sparkline: empty entities
|
|
153
|
+
if (q.entities.length === 0) throw new Error("entity-daily-sparkline: empty entities - resolver must pre-resolve the top-N list");
|
|
146
154
|
const inList = q.entities.map(sqlStringLiteral).join(", ");
|
|
147
155
|
return {
|
|
148
156
|
table,
|
|
@@ -151,7 +159,7 @@ function buildEntityDailySparkline(q) {
|
|
|
151
159
|
};
|
|
152
160
|
}
|
|
153
161
|
function buildTopNBreakdown(q) {
|
|
154
|
-
const table =
|
|
162
|
+
const table = tableForDimensions([q.dimension]);
|
|
155
163
|
const w = partitionWhere(q);
|
|
156
164
|
const order = `${q.orderBy.metric} ${q.orderBy.dir.toUpperCase()}`;
|
|
157
165
|
const limit = `LIMIT ${Math.max(0, Math.floor(q.limit))}`;
|
|
@@ -226,7 +234,7 @@ function buildTopNBreakdown(q) {
|
|
|
226
234
|
}
|
|
227
235
|
function buildSingleRowLookup(q) {
|
|
228
236
|
const dims = Object.keys(q.match);
|
|
229
|
-
const table =
|
|
237
|
+
const table = tableForDimensions(dims);
|
|
230
238
|
const w = partitionWhere(q);
|
|
231
239
|
const params = [...w.params];
|
|
232
240
|
let clause = w.clause;
|
|
@@ -243,7 +251,7 @@ function buildSingleRowLookup(q) {
|
|
|
243
251
|
};
|
|
244
252
|
}
|
|
245
253
|
function buildMultiSeriesStackedDaily(q) {
|
|
246
|
-
const table =
|
|
254
|
+
const table = tableForDimensions([q.seriesDimension]);
|
|
247
255
|
const w = partitionWhere(q);
|
|
248
256
|
if (q.seriesDimension === "device") {
|
|
249
257
|
const selects = DEVICE_SUFFIXES.map((suffix) => {
|
|
@@ -296,7 +304,7 @@ function buildArchetypeSql(query) {
|
|
|
296
304
|
case "single-row-lookup": return buildSingleRowLookup(query);
|
|
297
305
|
case "multi-series-stacked-daily": return buildMultiSeriesStackedDaily(query);
|
|
298
306
|
case "two-dimension-detail": return buildTwoDimensionDetail(query);
|
|
299
|
-
case "arbitrary-sql": throw new Error("buildArchetypeSql: arbitrary-sql carries caller SQL
|
|
307
|
+
case "arbitrary-sql": throw new Error("buildArchetypeSql: arbitrary-sql carries caller SQL - the DuckDB executor runs it verbatim");
|
|
300
308
|
case "aux-cloud-only": throw new Error("buildArchetypeSql: aux-cloud-only is not an Iceberg query");
|
|
301
309
|
}
|
|
302
310
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gscdump/cloudflare",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.27.0",
|
|
5
5
|
"description": "Cloudflare-Workers-flavored helpers for the gscdump analytics stack: AnalyticsEnv binding contract, R2 SigV4 presigner, size-hint HMAC, DuckDB Workers shims, engine factory.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Harlan Wilton",
|
|
@@ -46,15 +46,14 @@
|
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@uwdata/flechette": "^2.5.0",
|
|
48
48
|
"aws4fetch": "^1.0.20",
|
|
49
|
-
"@gscdump/contracts": "0.
|
|
50
|
-
"gscdump": "0.
|
|
51
|
-
"@gscdump/
|
|
52
|
-
"
|
|
53
|
-
"@gscdump/engine-sqlite": "0.26.10"
|
|
49
|
+
"@gscdump/contracts": "0.27.0",
|
|
50
|
+
"@gscdump/engine": "0.27.0",
|
|
51
|
+
"@gscdump/engine-sqlite": "0.27.0",
|
|
52
|
+
"gscdump": "0.27.0"
|
|
54
53
|
},
|
|
55
54
|
"devDependencies": {
|
|
56
55
|
"@cloudflare/vitest-pool-workers": "^0.16.15",
|
|
57
|
-
"@cloudflare/workers-types": "^4.
|
|
56
|
+
"@cloudflare/workers-types": "^4.20260616.1",
|
|
58
57
|
"h3": "^1.15.11",
|
|
59
58
|
"typescript": "^6.0.3",
|
|
60
59
|
"wrangler": "^4.100.0"
|