@gscdump/cloudflare 1.4.0 → 1.4.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.
package/dist/arrow.mjs ADDED
@@ -0,0 +1,50 @@
1
+ import { float64, int32, int64, tableFromArrays, tableToIPC, utf8 } from "@uwdata/flechette";
2
+ function arrowTypeForColumn(type) {
3
+ switch (type) {
4
+ case "VARCHAR":
5
+ case "DATE": return utf8();
6
+ case "BIGINT": return int64();
7
+ case "INTEGER": return int32();
8
+ case "DOUBLE": return float64();
9
+ }
10
+ }
11
+ function rowsToArrowIPC(rows, schemaColumns) {
12
+ const colNames = [];
13
+ const seen = /* @__PURE__ */ new Set();
14
+ const add = (name) => {
15
+ if (!seen.has(name)) {
16
+ seen.add(name);
17
+ colNames.push(name);
18
+ }
19
+ };
20
+ if (schemaColumns) for (const c of schemaColumns) add(c.name);
21
+ for (const row of rows) for (const key in row) add(key);
22
+ const schemaType = /* @__PURE__ */ new Map();
23
+ if (schemaColumns) for (const c of schemaColumns) schemaType.set(c.name, c.type);
24
+ const data = {};
25
+ const types = {};
26
+ for (const name of colNames) {
27
+ const values = rows.map((r) => r[name] ?? null);
28
+ data[name] = values;
29
+ const known = schemaType.get(name);
30
+ if (known) {
31
+ types[name] = arrowTypeForColumn(known);
32
+ continue;
33
+ }
34
+ let hasString = false;
35
+ let hasValue = false;
36
+ for (const v of values) {
37
+ if (v === null || v === void 0) continue;
38
+ hasValue = true;
39
+ if (typeof v === "string") {
40
+ hasString = true;
41
+ break;
42
+ }
43
+ }
44
+ if (hasString || !hasValue) types[name] = utf8();
45
+ }
46
+ const ipc = tableToIPC(tableFromArrays(data, { types }), { format: "stream" });
47
+ if (!ipc) throw new Error("rowsToArrowIPC: tableToIPC returned null");
48
+ return ipc;
49
+ }
50
+ export { rowsToArrowIPC };
@@ -0,0 +1,17 @@
1
+ import { AnalyticsEnv } from "./env.mjs";
2
+ import { createStorageEngine } from "@gscdump/engine";
3
+ /**
4
+ * Optional per-request hooks for telemetry / tracing. Hosts wire these in
5
+ * to bridge engine activity into their own metrics pipeline.
6
+ */
7
+ interface AnalyticsEngineHooks {
8
+ /** Called once per R2 PUT, with the byte size of the payload. */
9
+ onR2Write?: (byteLength: number) => void;
10
+ /** Override the interactive 22-second DuckDB RPC budget for background work. */
11
+ duckdbRpcTimeoutMs?: number;
12
+ }
13
+ interface AnalyticsEngineRuntime {
14
+ getEngine: (env: AnalyticsEnv, db: any, hooks?: AnalyticsEngineHooks) => ReturnType<typeof createStorageEngine> | null;
15
+ }
16
+ declare function getAnalyticsEngine(env: AnalyticsEnv, db: any, hooks?: AnalyticsEngineHooks): ReturnType<typeof createStorageEngine> | null;
17
+ export { AnalyticsEngineHooks, AnalyticsEngineRuntime, getAnalyticsEngine };
@@ -0,0 +1,35 @@
1
+ import { createDucklingsCodec, createDucklingsExecutor, createDucklingsRowCache } from "./workers-duckdb.mjs";
2
+ import { createStorageEngine } from "@gscdump/engine";
3
+ import { createD1ManifestStore } from "@gscdump/engine-sqlite";
4
+ import { createR2DataSource } from "@gscdump/engine/r2";
5
+ function createAnalyticsEngineRuntime() {
6
+ const rowCache = createDucklingsRowCache();
7
+ return { getEngine(env, db, hooks = {}) {
8
+ if (!env.R2_DATA) return null;
9
+ const baseDataSource = createR2DataSource({
10
+ bucket: env.R2_DATA,
11
+ bucketName: env.R2_BUCKET_NAME
12
+ });
13
+ return createStorageEngine({
14
+ dataSource: hooks.onR2Write ? {
15
+ ...baseDataSource,
16
+ async write(key, bytes) {
17
+ hooks.onR2Write(bytes.byteLength);
18
+ return baseDataSource.write(key, bytes);
19
+ }
20
+ } : baseDataSource,
21
+ manifestStore: createD1ManifestStore(db),
22
+ codec: createDucklingsCodec(env),
23
+ executor: createDucklingsExecutor(env, {
24
+ rowCache,
25
+ ...hooks.duckdbRpcTimeoutMs !== void 0 ? { rpcTimeoutMs: hooks.duckdbRpcTimeoutMs } : {}
26
+ })
27
+ });
28
+ } };
29
+ }
30
+ let sharedRuntime;
31
+ function getAnalyticsEngine(env, db, hooks = {}) {
32
+ sharedRuntime ??= createAnalyticsEngineRuntime();
33
+ return sharedRuntime.getEngine(env, db, hooks);
34
+ }
35
+ export { getAnalyticsEngine };
package/dist/env.d.mts ADDED
@@ -0,0 +1,45 @@
1
+ interface AnalyticsEnv {
2
+ /** R2 bucket holding parquet + rollup + entity data. Required in origin mode. */
3
+ R2_DATA?: R2Bucket;
4
+ /** Human name of the R2 bucket (used by the presigner when building public URLs). */
5
+ R2_BUCKET_NAME?: string;
6
+ /** Optional: D1 database holding the r2_manifest mirror + sync state. */
7
+ DB?: D1Database;
8
+ /**
9
+ * Optional: DuckDB service binding (Workers RPC) for server-side execution.
10
+ * Structural shape — any binding with `runSQL` + `ping` satisfies it, so
11
+ * hosts can declare their own binding interface without coupling to this one.
12
+ * Request tables use Arrow IPC chunks. Small queries pass tables inline to
13
+ * `runSQL`; larger queries stage chunks via `stageArrowTable`, then call
14
+ * `runSQL` with only SQL, and finally `dropTables`.
15
+ */
16
+ DUCKDB_SVC?: {
17
+ runSQL: (args: {
18
+ sql: string;
19
+ tables?: Record<string, {
20
+ ipc: Uint8Array;
21
+ }>;
22
+ deadlineAt?: number;
23
+ }) => Promise<{
24
+ rows: unknown[];
25
+ sql: string;
26
+ }>;
27
+ stageArrowTable?: (args: {
28
+ table: string;
29
+ ipc: Uint8Array;
30
+ }) => Promise<void>;
31
+ dropTables?: (args: {
32
+ tables: string[];
33
+ }) => Promise<void>;
34
+ ping: () => Promise<string>;
35
+ };
36
+ /** Route override: force D1 as the manifest source even if R2 is bound. */
37
+ ANALYTICS_FORCE_D1?: string;
38
+ /** Route override: disable R2 reads entirely (consumer / legacy mode). */
39
+ R2_READS_ENABLED?: string;
40
+ /** R2 S3-API credentials for presigning (origin mode when the worker can't proxy). */
41
+ R2_ACCESS_KEY_ID?: string;
42
+ R2_SECRET_ACCESS_KEY?: string;
43
+ CLOUDFLARE_ACCOUNT_ID?: string;
44
+ }
45
+ export { AnalyticsEnv };
package/dist/index.d.mts CHANGED
@@ -1,90 +1,5 @@
1
- import { ParquetCodec, QueryExecutor, Row, createStorageEngine } from "@gscdump/engine";
2
- interface AnalyticsEnv {
3
- /** R2 bucket holding parquet + rollup + entity data. Required in origin mode. */
4
- R2_DATA?: R2Bucket;
5
- /** Human name of the R2 bucket (used by the presigner when building public URLs). */
6
- R2_BUCKET_NAME?: string;
7
- /** Optional: D1 database holding the r2_manifest mirror + sync state. */
8
- DB?: D1Database;
9
- /**
10
- * Optional: DuckDB service binding (Workers RPC) for server-side execution.
11
- * Structural shape — any binding with `runSQL` + `ping` satisfies it, so
12
- * hosts can declare their own binding interface without coupling to this one.
13
- * Request tables use Arrow IPC chunks. Small queries pass tables inline to
14
- * `runSQL`; larger queries stage chunks via `stageArrowTable`, then call
15
- * `runSQL` with only SQL, and finally `dropTables`.
16
- */
17
- DUCKDB_SVC?: {
18
- runSQL: (args: {
19
- sql: string;
20
- tables?: Record<string, {
21
- ipc: Uint8Array;
22
- }>;
23
- deadlineAt?: number;
24
- }) => Promise<{
25
- rows: unknown[];
26
- sql: string;
27
- }>;
28
- stageArrowTable?: (args: {
29
- table: string;
30
- ipc: Uint8Array;
31
- }) => Promise<void>;
32
- dropTables?: (args: {
33
- tables: string[];
34
- }) => Promise<void>;
35
- ping: () => Promise<string>;
36
- };
37
- /** Route override: force D1 as the manifest source even if R2 is bound. */
38
- ANALYTICS_FORCE_D1?: string;
39
- /** Route override: disable R2 reads entirely (consumer / legacy mode). */
40
- R2_READS_ENABLED?: string;
41
- /** R2 S3-API credentials for presigning (origin mode when the worker can't proxy). */
42
- R2_ACCESS_KEY_ID?: string;
43
- R2_SECRET_ACCESS_KEY?: string;
44
- CLOUDFLARE_ACCOUNT_ID?: string;
45
- }
46
- /**
47
- * Optional per-request hooks for telemetry / tracing. Hosts wire these in
48
- * to bridge engine activity into their own metrics pipeline.
49
- */
50
- interface AnalyticsEngineHooks {
51
- /** Called once per R2 PUT, with the byte size of the payload. */
52
- onR2Write?: (byteLength: number) => void;
53
- /** Override the interactive 22-second DuckDB RPC budget for background work. */
54
- duckdbRpcTimeoutMs?: number;
55
- }
56
- interface AnalyticsEngineRuntime {
57
- getEngine: (env: AnalyticsEnv, db: any, hooks?: AnalyticsEngineHooks) => ReturnType<typeof createStorageEngine> | null;
58
- }
59
- declare function getAnalyticsEngine(env: AnalyticsEnv, db: any, hooks?: AnalyticsEngineHooks): ReturnType<typeof createStorageEngine> | null;
60
- interface InflightDedupe<T> {
61
- dedupe: (key: string, run: () => Promise<T>) => Promise<T>;
62
- has: (key: string) => boolean;
63
- clear: () => void;
64
- }
65
- declare function createInflightDedupe<T>(): InflightDedupe<T>;
66
- interface HostedR2QueryKeyInput {
67
- userId: string | number;
68
- siteId: string;
69
- state: unknown;
70
- comparison?: unknown;
71
- comparisonFilter?: string;
72
- }
73
- declare function getHostedR2QueryKey(input: HostedR2QueryKeyInput): string;
74
- declare function createDucklingsCodec(_env: AnalyticsEnv): ParquetCodec;
75
- interface DucklingsRowCache {
76
- clear: () => void;
77
- get: (key: string) => Row[] | undefined;
78
- put: (key: string, rows: Row[]) => void;
79
- }
80
- declare function createDucklingsRowCache(maxBytes?: number): DucklingsRowCache;
81
- interface DucklingsExecutorOptions {
82
- ipcChunkBytes?: number;
83
- ipcDirectCallBytes?: number;
84
- ipcTotalBytes?: number;
85
- /** Per-RPC wall/queue budget. Interactive default is 22 seconds. */
86
- rpcTimeoutMs?: number;
87
- rowCache?: DucklingsRowCache;
88
- }
89
- declare function createDucklingsExecutor(env: AnalyticsEnv, opts?: DucklingsExecutorOptions): QueryExecutor;
1
+ import { AnalyticsEnv } from "./env.mjs";
2
+ import { AnalyticsEngineHooks, AnalyticsEngineRuntime, getAnalyticsEngine } from "./engine.mjs";
3
+ import { HostedR2QueryKeyInput, InflightDedupe, createInflightDedupe, getHostedR2QueryKey } from "./inflight-dedupe.mjs";
4
+ import { DucklingsRowCache, createDucklingsCodec, createDucklingsExecutor, createDucklingsRowCache } from "./workers-duckdb.mjs";
90
5
  export { type AnalyticsEngineHooks, type AnalyticsEngineRuntime, type AnalyticsEnv, type DucklingsRowCache, type HostedR2QueryKeyInput, type InflightDedupe, createDucklingsCodec, createDucklingsExecutor, createDucklingsRowCache, createInflightDedupe, getAnalyticsEngine, getHostedR2QueryKey };