@gscdump/cloudflare 5.3.0 → 5.3.1

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,5 +1,6 @@
1
1
  import { ArchetypeQuery } from "@gscdump/contracts/archetypes";
2
2
  export declare const TABLE_PLACEHOLDER = "{{TABLE}}";
3
+ export declare const COMPARISON_TABLE_PLACEHOLDER = "{{TABLE_PREVIOUS}}";
3
4
  export type ArchetypeFactTable = 'pages' | 'queries' | 'countries' | 'page_queries' | 'dates';
4
5
  export interface ArchetypeSqlPlan {
5
6
  sql: string;
@@ -9,6 +10,8 @@ export interface ArchetypeSqlPlan {
9
10
  export type PartitionPredicateMode = 'bare' | 'r2-sql-concat';
10
11
  export type PartitionKeyEncoding = 'int' | 'string';
11
12
  export interface BuildArchetypeSqlOptions {
13
+ /** Resolve comparison files independently from the current window. */
14
+ separateComparisonTable?: boolean;
12
15
  /**
13
16
  * Set by the DuckDB file-list executor, which reads raw Iceberg parquet
14
17
  * directly via `read_parquet([...])`, bypassing the catalog metadata layer
@@ -1,7 +1,8 @@
1
1
  const TABLE_PLACEHOLDER = "{{TABLE}}";
2
+ const COMPARISON_TABLE_PLACEHOLDER = "{{TABLE_PREVIOUS}}";
2
3
  const FACT_ALIAS = "fact";
3
- function factTableRef() {
4
- return `${TABLE_PLACEHOLDER} AS ${FACT_ALIAS}`;
4
+ function factTableRef(placeholder = TABLE_PLACEHOLDER) {
5
+ return `${placeholder} AS ${FACT_ALIAS}`;
5
6
  }
6
7
  function dimColumn(dim) {
7
8
  if (dim === "page") return "url";
@@ -184,7 +185,8 @@ function buildEntityDailySparkline(q, pruned, mode) {
184
185
  sql: `SELECT date, ${col} AS entity, ${metricExpr(q.metric)} FROM ${factTableRef()} WHERE ${w.clause} AND ${col} IN (${inList}) GROUP BY date, ${col} ORDER BY date ASC`
185
186
  };
186
187
  }
187
- function buildTopNBreakdown(q, pruned, mode) {
188
+ function buildTopNBreakdown(q, pruned, mode, separateComparisonTable = false) {
189
+ const previousTable = separateComparisonTable ? COMPARISON_TABLE_PLACEHOLDER : TABLE_PLACEHOLDER;
188
190
  const table = tableForTopNBreakdown(q);
189
191
  const w = partitionWhere(q, pruned, mode);
190
192
  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)}`);
@@ -204,13 +206,13 @@ function buildTopNBreakdown(q, pruned, mode) {
204
206
  ...q,
205
207
  range: q.compareRange
206
208
  }, pruned, mode);
207
- const deviceSelects = (clause, ml) => DEVICE_SUFFIXES.map((suffix) => {
209
+ const deviceSelects = (clause, ml, placeholder = TABLE_PLACEHOLDER) => DEVICE_SUFFIXES.map((suffix) => {
208
210
  const source = deviceSource(suffix);
209
211
  const metrics = ml.map((m) => metricExprForSource(m, source)).join(", ");
210
- return `SELECT '${suffix.toUpperCase()}' AS device, ${metrics} FROM ${factTableRef()} WHERE ${clause}`;
212
+ return `SELECT '${suffix.toUpperCase()}' AS device, ${metrics} FROM ${factTableRef(placeholder)} WHERE ${clause}`;
211
213
  }).join(" UNION ALL ");
212
214
  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`;
213
- 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}`;
215
+ const sql = `WITH cur AS (${deviceSelects(w.clause, metricList)}), prev AS (${deviceSelects(wPrev.clause, STD_METRICS, previousTable)}) SELECT * FROM (${inner}) t ORDER BY ${order} ${limit}${offset}`;
214
216
  return {
215
217
  table,
216
218
  params: [...DEVICE_SUFFIXES.flatMap(() => w.params), ...DEVICE_SUFFIXES.flatMap(() => wPrev.params)],
@@ -244,7 +246,7 @@ function buildTopNBreakdown(q, pruned, mode) {
244
246
  const moverWhere = q.movers ? `WHERE ${moverClause(q.movers).where} ` : "";
245
247
  const outerOrder = q.movers ? moverOrderByAlias(q.movers) : order;
246
248
  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}`;
247
- const sql = `WITH cur AS (SELECT ${col} AS k, ${curMetrics}${variantSel} FROM ${factTableRef()} WHERE ${w.clause}${facet.sql} GROUP BY ${col}), prev AS (SELECT ${col} AS k, ${prevMetrics} FROM ${factTableRef()} WHERE ${wPrev.clause}${facet.sql} GROUP BY ${col}) SELECT * FROM (${inner}) t ORDER BY ${outerOrder} ${limit}${offset}`;
249
+ const sql = `WITH cur AS (SELECT ${col} AS k, ${curMetrics}${variantSel} FROM ${factTableRef()} WHERE ${w.clause}${facet.sql} GROUP BY ${col}), prev AS (SELECT ${col} AS k, ${prevMetrics} FROM ${factTableRef(previousTable)} WHERE ${wPrev.clause}${facet.sql} GROUP BY ${col}) SELECT * FROM (${inner}) t ORDER BY ${outerOrder} ${limit}${offset}`;
248
250
  return {
249
251
  table,
250
252
  params: [
@@ -334,7 +336,7 @@ function buildArchetypeSql(query, opts = {}) {
334
336
  case "site-daily-timeseries": return buildSiteDailyTimeseries(query, pruned, mode);
335
337
  case "entity-daily-timeseries": return buildEntityDailyTimeseries(query, pruned, mode);
336
338
  case "entity-daily-sparkline": return buildEntityDailySparkline(query, pruned, mode);
337
- case "top-n-breakdown": return buildTopNBreakdown(query, pruned, mode);
339
+ case "top-n-breakdown": return buildTopNBreakdown(query, pruned, mode, opts.separateComparisonTable);
338
340
  case "single-row-lookup": return buildSingleRowLookup(query, pruned, mode);
339
341
  case "multi-series-stacked-daily": return buildMultiSeriesStackedDaily(query, pruned, mode);
340
342
  case "two-dimension-detail": return buildTwoDimensionDetail(query, pruned, mode);
@@ -342,4 +344,4 @@ function buildArchetypeSql(query, opts = {}) {
342
344
  case "aux-cloud-only": throw new Error("buildArchetypeSql: aux-cloud-only is not an Iceberg query");
343
345
  }
344
346
  }
345
- export { TABLE_PLACEHOLDER, buildArchetypeSql };
347
+ export { COMPARISON_TABLE_PLACEHOLDER, TABLE_PLACEHOLDER, buildArchetypeSql };
@@ -1,6 +1,6 @@
1
- import { ArchetypeSqlPlan, BuildArchetypeSqlOptions, TABLE_PLACEHOLDER, buildArchetypeSql } from "./archetype-sql.mjs";
1
+ import { ArchetypeSqlPlan, BuildArchetypeSqlOptions, COMPARISON_TABLE_PLACEHOLDER, TABLE_PLACEHOLDER, buildArchetypeSql } from "./archetype-sql.mjs";
2
2
  import { DuckDbIcebergError, DuckDbIcebergExecutor, DuckDbIcebergExecutorConfig, DuckDbIcebergQueryError, DuckDbIcebergResult, DuckDbIcebergRow, DuckDbIcebergTimeoutError, DuckDbSvc, createDuckDbIcebergExecutor } from "./duckdb-iceberg-executor.mjs";
3
3
  import { R2SqlClient, R2SqlClientConfig, R2SqlError, R2SqlQueryError, R2SqlResult, R2SqlRow, R2SqlTimeoutError, createR2SqlClient, inlineParams } from "./r2-sql-client.mjs";
4
4
  import { ServerTailDispatcher, ServerTailDispatcherConfig, ServerTailEngine, ServerTailRoutingError, createServerTailDispatcher, resolveServerTailEngine, resolveServerTailEngineResult } from "./dispatcher.mjs";
5
5
  import { R2SqlTransport, R2SqlTransportConfig, R2SqlTransportMetrics, R2SqlTransportResult, R2SqlTransportRow, createR2SqlTransport } from "./r2-sql-transport.mjs";
6
- export { type ArchetypeSqlPlan, type BuildArchetypeSqlOptions, DuckDbIcebergError, type DuckDbIcebergExecutor, type DuckDbIcebergExecutorConfig, type DuckDbIcebergQueryError, type DuckDbIcebergResult, type DuckDbIcebergRow, DuckDbIcebergTimeoutError, type DuckDbSvc, type R2SqlClient, type R2SqlClientConfig, R2SqlError, type R2SqlQueryError, type R2SqlResult, type R2SqlRow, R2SqlTimeoutError, type R2SqlTransport, type R2SqlTransportConfig, type R2SqlTransportMetrics, type R2SqlTransportResult, type R2SqlTransportRow, type ServerTailDispatcher, type ServerTailDispatcherConfig, type ServerTailEngine, ServerTailRoutingError, TABLE_PLACEHOLDER, buildArchetypeSql, createDuckDbIcebergExecutor, createR2SqlClient, createR2SqlTransport, createServerTailDispatcher, inlineParams, resolveServerTailEngine, resolveServerTailEngineResult };
6
+ export { type ArchetypeSqlPlan, type BuildArchetypeSqlOptions, COMPARISON_TABLE_PLACEHOLDER, DuckDbIcebergError, type DuckDbIcebergExecutor, type DuckDbIcebergExecutorConfig, type DuckDbIcebergQueryError, type DuckDbIcebergResult, type DuckDbIcebergRow, DuckDbIcebergTimeoutError, type DuckDbSvc, type R2SqlClient, type R2SqlClientConfig, R2SqlError, type R2SqlQueryError, type R2SqlResult, type R2SqlRow, R2SqlTimeoutError, type R2SqlTransport, type R2SqlTransportConfig, type R2SqlTransportMetrics, type R2SqlTransportResult, type R2SqlTransportRow, type ServerTailDispatcher, type ServerTailDispatcherConfig, type ServerTailEngine, ServerTailRoutingError, TABLE_PLACEHOLDER, buildArchetypeSql, createDuckDbIcebergExecutor, createR2SqlClient, createR2SqlTransport, createServerTailDispatcher, inlineParams, resolveServerTailEngine, resolveServerTailEngineResult };
@@ -1,6 +1,6 @@
1
- import { TABLE_PLACEHOLDER, buildArchetypeSql } from "./archetype-sql.mjs";
1
+ import { COMPARISON_TABLE_PLACEHOLDER, TABLE_PLACEHOLDER, buildArchetypeSql } from "./archetype-sql.mjs";
2
2
  import { ServerTailRoutingError, createServerTailDispatcher, resolveServerTailEngine, resolveServerTailEngineResult } from "./dispatcher.mjs";
3
3
  import { DuckDbIcebergError, DuckDbIcebergTimeoutError, createDuckDbIcebergExecutor } from "./duckdb-iceberg-executor.mjs";
4
4
  import { createR2SqlTransport } from "./r2-sql-transport.mjs";
5
5
  import { R2SqlError, R2SqlTimeoutError, createR2SqlClient, inlineParams } from "./r2-sql-client.mjs";
6
- export { DuckDbIcebergError, DuckDbIcebergTimeoutError, R2SqlError, R2SqlTimeoutError, ServerTailRoutingError, TABLE_PLACEHOLDER, buildArchetypeSql, createDuckDbIcebergExecutor, createR2SqlClient, createR2SqlTransport, createServerTailDispatcher, inlineParams, resolveServerTailEngine, resolveServerTailEngineResult };
6
+ export { COMPARISON_TABLE_PLACEHOLDER, DuckDbIcebergError, DuckDbIcebergTimeoutError, R2SqlError, R2SqlTimeoutError, ServerTailRoutingError, TABLE_PLACEHOLDER, buildArchetypeSql, createDuckDbIcebergExecutor, createR2SqlClient, createR2SqlTransport, createServerTailDispatcher, inlineParams, resolveServerTailEngine, resolveServerTailEngineResult };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@gscdump/cloudflare",
3
3
  "type": "module",
4
- "version": "5.3.0",
4
+ "version": "5.3.1",
5
5
  "description": "Cloudflare Workers helpers for server-tail queries and in-flight request deduplication.",
6
6
  "author": {
7
7
  "name": "Harlan Wilton",
@@ -41,7 +41,7 @@
41
41
  "dependencies": {
42
42
  "@gscdump/contracts": "^5.3.0",
43
43
  "@gscdump/engine": "^5.3.0",
44
- "gscdump": "^5.3.0"
44
+ "gscdump": "^5.3.1"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@cloudflare/vitest-pool-workers": "^0.22.0",