@gscdump/engine 0.31.4 → 0.31.6

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,4 +1,4 @@
1
- import { AsyncBuffer } from "hyparquet";
1
+ import { AsyncBuffer } from "./hyparquet.mjs";
2
2
  import { Writer } from "hyparquet-writer/src/types.js";
3
3
  interface WriterOptions {
4
4
  /**
@@ -1,7 +1,6 @@
1
+ import { asyncBufferFromUrl, cachedAsyncBuffer, parseDecimal } from "./hyparquet.mjs";
2
+ import { ByteWriter, parquetWrite } from "./hyparquet-writer.mjs";
1
3
  import { gunzip } from "./hyparquet-compressors.mjs";
2
- import { asyncBufferFromUrl, cachedAsyncBuffer } from "hyparquet";
3
- import { ByteWriter, parquetWrite } from "hyparquet-writer";
4
- import { parseDecimal } from "hyparquet/src/convert.js";
5
4
  function readZigZag(reader) {
6
5
  let result = 0;
7
6
  let shift = 0;
@@ -1,4 +1,4 @@
1
- import { ParquetQueryFilter } from "hyparquet";
1
+ import { ParquetQueryFilter } from "./libs/hyparquet.mjs";
2
2
  import { BuilderState, SearchType, SearchType as SearchType$1 } from "gscdump/query";
3
3
  import { Grain, Grain as Grain$1, Row, Row as Row$1, TableName, TableName as TableName$1, TenantCtx, TenantCtx as TenantCtx$1 } from "@gscdump/contracts";
4
4
  /**
@@ -1,6 +1,6 @@
1
1
  import { CodecCtx, DataSource, ParquetCodec, Row, TableName } from "../_chunks/storage.mjs";
2
+ import { ParquetQueryFilter } from "../_chunks/libs/hyparquet.mjs";
2
3
  import { ColumnDef } from "../_chunks/schema.mjs";
3
- import { ParquetQueryFilter } from "hyparquet";
4
4
  declare function encodeRowsToParquet(table: TableName, rows: readonly Row[]): Uint8Array;
5
5
  interface EncodeFlexOptions {
6
6
  /** Columns defining the output schema + order. */
@@ -1,6 +1,6 @@
1
1
  import { SCHEMAS, TABLE_METADATA, dedupeByNaturalKey } from "../_chunks/schema.mjs";
2
- import { parquetReadObjects } from "hyparquet";
3
- import { ByteWriter, parquetWriteRows } from "hyparquet-writer";
2
+ import { parquetReadObjects } from "../_chunks/libs/hyparquet.mjs";
3
+ import { ByteWriter$1 as ByteWriter, parquetWriteRows } from "../_chunks/libs/hyparquet-writer.mjs";
4
4
  const ROW_GROUP_SIZE = 25e3;
5
5
  function basicTypeFor(colType) {
6
6
  if (colType === "VARCHAR") return "STRING";
package/dist/rollups.mjs CHANGED
@@ -603,44 +603,61 @@ const queryCanonicalVariantsRollup = {
603
603
  });
604
604
  if (parts.length === 0) return [];
605
605
  const partitions = parts.map((p) => p.partition);
606
- return (await runPagedQuery({
607
- engine,
608
- ctx,
609
- table: "queries",
610
- ...searchType !== void 0 ? { searchType } : {},
611
- fileSets: { FILES: {
606
+ const byCanonical = /* @__PURE__ */ new Map();
607
+ let cursor = null;
608
+ for (;;) {
609
+ const after = cursor === null ? "" : `AND query > '${cursor.replace(/'/g, "''")}'`;
610
+ const { rows } = await engine.runSQL({
611
+ ctx,
612
612
  table: "queries",
613
- partitions
614
- } },
615
- orderBy: "joinKey",
616
- pageRows: ROLLUP_PAGE_ROWS_WIDE,
617
- coreSql: `
618
- WITH per_variant AS (
613
+ ...searchType !== void 0 ? { searchType } : {},
614
+ fileSets: { FILES: {
615
+ table: "queries",
616
+ partitions
617
+ } },
618
+ sql: `
619
619
  SELECT
620
620
  COALESCE(NULLIF(query_canonical, ''), query) AS joinKey,
621
621
  query AS query,
622
622
  SUM(clicks) AS clicks,
623
623
  SUM(impressions) AS impressions,
624
- SUM(sum_position) AS sum_pos,
625
- ROW_NUMBER() OVER (PARTITION BY COALESCE(NULLIF(query_canonical, ''), query) ORDER BY SUM(clicks) DESC) AS rn,
626
- COUNT(*) OVER (PARTITION BY COALESCE(NULLIF(query_canonical, ''), query)) AS variantCount
624
+ SUM(sum_position) AS sum_pos
627
625
  FROM read_parquet({{FILES}}, union_by_name = true)
626
+ WHERE query IS NOT NULL ${after}
628
627
  GROUP BY COALESCE(NULLIF(query_canonical, ''), query), query
629
- )
630
- SELECT
631
- joinKey,
632
- MAX(variantCount)::BIGINT AS variantCount,
633
- MAX(CASE WHEN rn = 1 THEN query END) AS canonicalName,
634
- GROUP_CONCAT(CASE WHEN rn <= 10 THEN query || ':::' || clicks || ':::' || impressions || ':::' || CAST(ROUND(CAST(sum_pos AS REAL) / NULLIF(impressions, 0) + 1, 1) AS TEXT) END, '||') AS variants
635
- FROM per_variant
636
- GROUP BY joinKey
637
- `
638
- })).map((r) => ({
639
- joinKey: String(r.joinKey),
640
- variantCount: BigInt(r.variantCount),
641
- canonicalName: r.canonicalName == null ? null : String(r.canonicalName),
642
- variants: r.variants == null ? null : String(r.variants)
643
- }));
628
+ ORDER BY query
629
+ LIMIT ${ROLLUP_PAGE_ROWS_WIDE}
630
+ `
631
+ });
632
+ for (const r of rows) {
633
+ const joinKey = String(r.joinKey);
634
+ const list = byCanonical.get(joinKey);
635
+ const v = {
636
+ query: String(r.query),
637
+ clicks: Number(r.clicks),
638
+ impressions: Number(r.impressions),
639
+ sumPos: Number(r.sum_pos)
640
+ };
641
+ if (list) list.push(v);
642
+ else byCanonical.set(joinKey, [v]);
643
+ }
644
+ if (rows.length < 2e4) break;
645
+ cursor = String(rows[rows.length - 1].query);
646
+ }
647
+ const out = [];
648
+ for (const [joinKey, variants] of byCanonical) {
649
+ variants.sort((a, b) => b.clicks - a.clicks || a.query.localeCompare(b.query));
650
+ const canonicalName = variants[0]?.query ?? null;
651
+ const top = variants.slice(0, 10).filter((v) => v.impressions > 0);
652
+ const variantsStr = top.length === 0 ? null : top.map((v) => `${v.query}:::${v.clicks}:::${v.impressions}:::${(v.sumPos / v.impressions + 1).toFixed(1)}`).join("||");
653
+ out.push({
654
+ joinKey,
655
+ variantCount: BigInt(variants.length),
656
+ canonicalName,
657
+ variants: variantsStr
658
+ });
659
+ }
660
+ return out;
644
661
  }
645
662
  };
646
663
  const queryCanonicalDailyRollup = {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@gscdump/engine",
3
3
  "type": "module",
4
- "version": "0.31.4",
4
+ "version": "0.31.6",
5
5
  "description": "Append-only Parquet/DuckDB storage engine + planner + adapters for the gscdump pipeline. Node + edge runtimes; opt-in heavy peers.",
6
6
  "author": {
7
7
  "name": "Harlan Wilton",
@@ -171,33 +171,25 @@
171
171
  "node": ">=18"
172
172
  },
173
173
  "peerDependencies": {
174
- "@duckdb/duckdb-wasm": "^1.32.0",
175
- "hyparquet": "^1.26.1",
176
- "hyparquet-writer": "^0.16.1"
174
+ "@duckdb/duckdb-wasm": "^1.32.0"
177
175
  },
178
176
  "peerDependenciesMeta": {
179
177
  "@duckdb/duckdb-wasm": {
180
178
  "optional": true
181
- },
182
- "hyparquet": {
183
- "optional": true
184
- },
185
- "hyparquet-writer": {
186
- "optional": true
187
179
  }
188
180
  },
189
181
  "dependencies": {
190
182
  "drizzle-orm": "1.0.0-rc.3",
191
- "hyparquet": "^1.26.1",
192
- "hyparquet-writer": "^0.16.1",
193
183
  "proper-lockfile": "^4.1.2",
194
- "gscdump": "0.31.4",
195
- "@gscdump/contracts": "0.31.4"
184
+ "gscdump": "0.31.6",
185
+ "@gscdump/contracts": "0.31.6"
196
186
  },
197
187
  "devDependencies": {
198
188
  "@duckdb/duckdb-wasm": "^1.32.0",
199
189
  "@types/proper-lockfile": "^4.1.4",
200
190
  "aws4fetch": "^1.0.20",
191
+ "hyparquet": "^1.26.1",
192
+ "hyparquet-writer": "^0.16.1",
201
193
  "icebird": "^0.8.10",
202
194
  "tsx": "^4.22.4",
203
195
  "unstorage": "^1.17.5",