@gscdump/cloudflare 0.35.11 → 0.36.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/dist/server-tail/index.mjs +30 -28
- package/package.json +5 -5
|
@@ -78,22 +78,19 @@ function moverClause(movers) {
|
|
|
78
78
|
const curImpr = "COALESCE(c.impressions, 0)";
|
|
79
79
|
const prevImpr = "COALESCE(p.impressions, 0)";
|
|
80
80
|
switch (movers) {
|
|
81
|
-
case "improving": return {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
case "lost": return
|
|
94
|
-
where: `${curImpr} = 0 AND ${prevImpr} > 0`,
|
|
95
|
-
order: `${prevImpr} DESC`
|
|
96
|
-
};
|
|
81
|
+
case "improving": return { where: `${curClicks} > ${prevClicks}` };
|
|
82
|
+
case "declining": return { where: `${curClicks} < ${prevClicks}` };
|
|
83
|
+
case "new": return { where: `${prevImpr} = 0 AND ${curImpr} > 0` };
|
|
84
|
+
case "lost": return { where: `${curImpr} = 0 AND ${prevImpr} > 0` };
|
|
85
|
+
default: throw new Error(`[archetype-sql] unknown movers mode: ${movers}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function moverOrderByAlias(movers) {
|
|
89
|
+
switch (movers) {
|
|
90
|
+
case "improving": return "(clicks - prevClicks) DESC";
|
|
91
|
+
case "declining": return "(clicks - prevClicks) ASC";
|
|
92
|
+
case "new": return "clicks DESC, impressions DESC";
|
|
93
|
+
case "lost": return "prevImpressions DESC";
|
|
97
94
|
default: throw new Error(`[archetype-sql] unknown movers mode: ${movers}`);
|
|
98
95
|
}
|
|
99
96
|
}
|
|
@@ -183,10 +180,14 @@ function buildTopNBreakdown(q, pruned, mode) {
|
|
|
183
180
|
const w = partitionWhere(q, pruned, mode);
|
|
184
181
|
if (!q.orderBy || !q.orderBy.metric || !q.orderBy.dir) throw new Error(`[archetype-sql] top-n-breakdown requires orderBy.{metric,dir}, got: ${JSON.stringify(q.orderBy)}`);
|
|
185
182
|
const order = `${metricAlias(q.orderBy.metric)} ${q.orderBy.dir.toUpperCase()}`;
|
|
186
|
-
const compareOrder = `COALESCE(c.${metricAlias(q.orderBy.metric)}, 0) ${q.orderBy.dir.toUpperCase()}`;
|
|
187
183
|
const limit = `LIMIT ${Math.max(0, Math.floor(q.limit))}`;
|
|
188
184
|
const offset = q.offset && q.offset > 0 ? ` OFFSET ${Math.floor(q.offset)}` : "";
|
|
189
|
-
const
|
|
185
|
+
const metricList0 = q.metrics.includes(q.orderBy.metric) ? q.metrics : [...q.metrics, q.orderBy.metric];
|
|
186
|
+
const metricList = q.compareRange && q.movers ? [.../* @__PURE__ */ new Set([
|
|
187
|
+
...metricList0,
|
|
188
|
+
"clicks",
|
|
189
|
+
"impressions"
|
|
190
|
+
])] : metricList0;
|
|
190
191
|
const variantSel = q.dimension === "queryCanonical" ? ", COUNT(DISTINCT query) AS variantCount" : "";
|
|
191
192
|
if (q.dimension === "device") {
|
|
192
193
|
if (q.compareRange) {
|
|
@@ -199,9 +200,8 @@ function buildTopNBreakdown(q, pruned, mode) {
|
|
|
199
200
|
const metrics = ml.map((m) => metricExprForSource(m, source)).join(", ");
|
|
200
201
|
return `SELECT '${suffix.toUpperCase()}' AS device, ${metrics} FROM ${TABLE_PLACEHOLDER} WHERE ${clause}`;
|
|
201
202
|
}).join(" UNION ALL ");
|
|
202
|
-
const
|
|
203
|
-
const
|
|
204
|
-
const sql = `WITH cur AS (${deviceSelects(w.clause, metricList)}), prev AS (${deviceSelects(wPrev.clause, STD_METRICS)}) SELECT COALESCE(c.device, p.device) AS device, ${curCols}, ${prevCols} FROM cur c FULL OUTER JOIN prev p ON c.device = p.device ORDER BY ${compareOrder} ${limit}${offset}`;
|
|
203
|
+
const inner = `SELECT COALESCE(c.device, p.device) AS device, ${metricList.map((m) => coalesceMetric(m, "c", m)).join(", ")}, ${STD_METRICS.map((m) => coalesceMetric(m, "p", prevAlias(m))).join(", ")} FROM cur c FULL OUTER JOIN prev p ON c.device = p.device`;
|
|
204
|
+
const sql = `WITH cur AS (${deviceSelects(w.clause, metricList)}), prev AS (${deviceSelects(wPrev.clause, STD_METRICS)}) SELECT * FROM (${inner}) t ORDER BY ${order} ${limit}${offset}`;
|
|
205
205
|
return {
|
|
206
206
|
table,
|
|
207
207
|
params: [...DEVICE_SUFFIXES.flatMap(() => w.params), ...DEVICE_SUFFIXES.flatMap(() => wPrev.params)],
|
|
@@ -232,10 +232,10 @@ function buildTopNBreakdown(q, pruned, mode) {
|
|
|
232
232
|
const curCols = metricList.map((m) => coalesceMetric(m, "c", m)).join(", ");
|
|
233
233
|
const prevCols = STD_METRICS.map((m) => coalesceMetric(m, "p", prevAlias(m))).join(", ");
|
|
234
234
|
const variantOut = q.dimension === "queryCanonical" ? ", c.variantCount AS variantCount" : "";
|
|
235
|
-
const
|
|
236
|
-
const
|
|
237
|
-
const
|
|
238
|
-
const sql = `WITH cur AS (SELECT ${col} AS k, ${curMetrics}${variantSel} FROM ${TABLE_PLACEHOLDER} WHERE ${w.clause}${facet.sql} GROUP BY ${col}), prev AS (SELECT ${col} AS k, ${prevMetrics} FROM ${TABLE_PLACEHOLDER} WHERE ${wPrev.clause}${facet.sql} GROUP BY ${col}) SELECT
|
|
235
|
+
const moverWhere = q.movers ? `WHERE ${moverClause(q.movers).where} ` : "";
|
|
236
|
+
const outerOrder = q.movers ? moverOrderByAlias(q.movers) : order;
|
|
237
|
+
const inner = `SELECT COALESCE(c.k, p.k) AS ${q.dimension}, ${curCols}, ${prevCols}${variantOut}${totalCol} FROM cur c FULL OUTER JOIN prev p ON c.k = p.k ${moverWhere}`;
|
|
238
|
+
const sql = `WITH cur AS (SELECT ${col} AS k, ${curMetrics}${variantSel} FROM ${TABLE_PLACEHOLDER} WHERE ${w.clause}${facet.sql} GROUP BY ${col}), prev AS (SELECT ${col} AS k, ${prevMetrics} FROM ${TABLE_PLACEHOLDER} WHERE ${wPrev.clause}${facet.sql} GROUP BY ${col}) SELECT * FROM (${inner}) t ORDER BY ${outerOrder} ${limit}${offset}`;
|
|
239
239
|
return {
|
|
240
240
|
table,
|
|
241
241
|
params: [
|
|
@@ -380,13 +380,15 @@ function createServerTailDispatcher(config) {
|
|
|
380
380
|
async function runOn(engine, query) {
|
|
381
381
|
if (engine === "r2-sql") {
|
|
382
382
|
const res = await config.r2Sql.runArchetype(query);
|
|
383
|
+
const { rows, totalRows } = extractTotal(res.rows);
|
|
383
384
|
return {
|
|
384
385
|
archetype: query.archetype,
|
|
385
|
-
rows
|
|
386
|
+
rows,
|
|
386
387
|
source: sourceFor("r2-sql"),
|
|
387
388
|
meta: {
|
|
388
|
-
rowCount:
|
|
389
|
-
queryMs: res.queryMs
|
|
389
|
+
rowCount: rows.length,
|
|
390
|
+
queryMs: res.queryMs,
|
|
391
|
+
...totalRows !== void 0 ? { totalRows } : {}
|
|
390
392
|
}
|
|
391
393
|
};
|
|
392
394
|
}
|
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.36.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,10 +46,10 @@
|
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@uwdata/flechette": "^2.5.0",
|
|
48
48
|
"aws4fetch": "^1.0.20",
|
|
49
|
-
"@gscdump/
|
|
50
|
-
"@gscdump/engine-sqlite": "0.
|
|
51
|
-
"
|
|
52
|
-
"gscdump": "0.
|
|
49
|
+
"@gscdump/contracts": "0.36.0",
|
|
50
|
+
"@gscdump/engine-sqlite": "0.36.0",
|
|
51
|
+
"gscdump": "0.36.0",
|
|
52
|
+
"@gscdump/engine": "0.36.0"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@cloudflare/vitest-pool-workers": "^0.18.0",
|