@gscdump/cloudflare 0.35.10 → 0.35.12

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.
@@ -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
- where: `${curClicks} > ${prevClicks}`,
83
- order: `(${curClicks} - ${prevClicks}) DESC`
84
- };
85
- case "declining": return {
86
- where: `${curClicks} < ${prevClicks}`,
87
- order: `(${curClicks} - ${prevClicks}) ASC`
88
- };
89
- case "new": return {
90
- where: `${prevImpr} = 0 AND ${curImpr} > 0`,
91
- order: `${curClicks} DESC, ${curImpr} DESC`
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
  }
@@ -185,7 +182,12 @@ function buildTopNBreakdown(q, pruned, mode) {
185
182
  const order = `${metricAlias(q.orderBy.metric)} ${q.orderBy.dir.toUpperCase()}`;
186
183
  const limit = `LIMIT ${Math.max(0, Math.floor(q.limit))}`;
187
184
  const offset = q.offset && q.offset > 0 ? ` OFFSET ${Math.floor(q.offset)}` : "";
188
- const metricList = q.metrics.includes(q.orderBy.metric) ? q.metrics : [...q.metrics, q.orderBy.metric];
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;
189
191
  const variantSel = q.dimension === "queryCanonical" ? ", COUNT(DISTINCT query) AS variantCount" : "";
190
192
  if (q.dimension === "device") {
191
193
  if (q.compareRange) {
@@ -198,9 +200,8 @@ function buildTopNBreakdown(q, pruned, mode) {
198
200
  const metrics = ml.map((m) => metricExprForSource(m, source)).join(", ");
199
201
  return `SELECT '${suffix.toUpperCase()}' AS device, ${metrics} FROM ${TABLE_PLACEHOLDER} WHERE ${clause}`;
200
202
  }).join(" UNION ALL ");
201
- const curCols = metricList.map((m) => coalesceMetric(m, "c", m)).join(", ");
202
- const prevCols = STD_METRICS.map((m) => coalesceMetric(m, "p", prevAlias(m))).join(", ");
203
- 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 ${order} ${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}`;
204
205
  return {
205
206
  table,
206
207
  params: [...DEVICE_SUFFIXES.flatMap(() => w.params), ...DEVICE_SUFFIXES.flatMap(() => wPrev.params)],
@@ -231,10 +232,10 @@ function buildTopNBreakdown(q, pruned, mode) {
231
232
  const curCols = metricList.map((m) => coalesceMetric(m, "c", m)).join(", ");
232
233
  const prevCols = STD_METRICS.map((m) => coalesceMetric(m, "p", prevAlias(m))).join(", ");
233
234
  const variantOut = q.dimension === "queryCanonical" ? ", c.variantCount AS variantCount" : "";
234
- const mover = q.movers ? moverClause(q.movers) : null;
235
- const moverWhere = mover ? `WHERE ${mover.where} ` : "";
236
- const orderSql = mover ? `ORDER BY ${mover.order}` : `ORDER BY ${order}`;
237
- 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 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}${orderSql} ${limit}${offset}`;
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}`;
238
239
  return {
239
240
  table,
240
241
  params: [
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@gscdump/cloudflare",
3
3
  "type": "module",
4
- "version": "0.35.10",
4
+ "version": "0.35.12",
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/contracts": "0.35.10",
50
- "@gscdump/engine": "0.35.10",
51
- "@gscdump/engine-sqlite": "0.35.10",
52
- "gscdump": "0.35.10"
49
+ "@gscdump/contracts": "0.35.12",
50
+ "@gscdump/engine": "0.35.12",
51
+ "@gscdump/engine-sqlite": "0.35.12",
52
+ "gscdump": "0.35.12"
53
53
  },
54
54
  "devDependencies": {
55
55
  "@cloudflare/vitest-pool-workers": "^0.18.0",