@gscdump/cloudflare 2.1.0 → 2.2.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/arrow.mjs +2 -1
- package/dist/engine.mjs +17 -13
- package/dist/server-tail/duckdb-iceberg-executor.mjs +8 -4
- package/dist/workers-duckdb.mjs +10 -8
- package/package.json +5 -5
package/dist/arrow.mjs
CHANGED
|
@@ -43,7 +43,8 @@ function rowsToArrowIPC(rows, schemaColumns) {
|
|
|
43
43
|
}
|
|
44
44
|
if (hasString || !hasValue) types[name] = utf8();
|
|
45
45
|
}
|
|
46
|
-
const
|
|
46
|
+
const table = tableFromArrays(data, { types });
|
|
47
|
+
const ipc = tableToIPC(table, { format: "stream" });
|
|
47
48
|
if (!ipc) throw new Error("rowsToArrowIPC: tableToIPC returned null");
|
|
48
49
|
return ipc;
|
|
49
50
|
}
|
package/dist/engine.mjs
CHANGED
|
@@ -10,20 +10,24 @@ function createAnalyticsEngineRuntime() {
|
|
|
10
10
|
bucket: env.R2_DATA,
|
|
11
11
|
bucketName: env.R2_BUCKET_NAME
|
|
12
12
|
});
|
|
13
|
+
const dataSource = hooks.onR2Write ? {
|
|
14
|
+
...baseDataSource,
|
|
15
|
+
async write(key, bytes) {
|
|
16
|
+
hooks.onR2Write(bytes.byteLength);
|
|
17
|
+
return baseDataSource.write(key, bytes);
|
|
18
|
+
}
|
|
19
|
+
} : baseDataSource;
|
|
20
|
+
const manifestStore = createD1ManifestStore(db);
|
|
21
|
+
const codec = createDucklingsCodec(env);
|
|
22
|
+
const executor = createDucklingsExecutor(env, {
|
|
23
|
+
rowCache,
|
|
24
|
+
...hooks.duckdbRpcTimeoutMs !== void 0 ? { rpcTimeoutMs: hooks.duckdbRpcTimeoutMs } : {}
|
|
25
|
+
});
|
|
13
26
|
return createStorageEngine({
|
|
14
|
-
dataSource
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
+
dataSource,
|
|
28
|
+
manifestStore,
|
|
29
|
+
codec,
|
|
30
|
+
executor
|
|
27
31
|
});
|
|
28
32
|
} };
|
|
29
33
|
}
|
|
@@ -48,16 +48,20 @@ function createDuckDbIcebergExecutor(config) {
|
|
|
48
48
|
return unwrapResult(await sendResult(sql), duckDbIcebergErrorToException);
|
|
49
49
|
}
|
|
50
50
|
function runSqlResult(sql, params = []) {
|
|
51
|
-
|
|
51
|
+
const resolved = resolveTablePlaceholders(sql, config);
|
|
52
|
+
return sendResult(bindLiterals(resolved, params));
|
|
52
53
|
}
|
|
53
54
|
function runSql(sql, params = []) {
|
|
54
|
-
|
|
55
|
+
const resolved = resolveTablePlaceholders(sql, config);
|
|
56
|
+
return send(bindLiterals(resolved, params));
|
|
55
57
|
}
|
|
56
58
|
function runPlan(plan) {
|
|
57
|
-
|
|
59
|
+
const resolved = plan.sql.split(TABLE_PLACEHOLDER).join(icebergTableRef(config, plan.table));
|
|
60
|
+
return send(bindLiterals(resolved, plan.params));
|
|
58
61
|
}
|
|
59
62
|
function runPlanResult(plan) {
|
|
60
|
-
|
|
63
|
+
const resolved = plan.sql.split(TABLE_PLACEHOLDER).join(icebergTableRef(config, plan.table));
|
|
64
|
+
return sendResult(bindLiterals(resolved, plan.params));
|
|
61
65
|
}
|
|
62
66
|
function runArchetypeResult(query) {
|
|
63
67
|
if (query.archetype === "arbitrary-sql") return runSqlResult(query.sql, query.params ?? []);
|
package/dist/workers-duckdb.mjs
CHANGED
|
@@ -10,12 +10,12 @@ function resolveSvc(env) {
|
|
|
10
10
|
}
|
|
11
11
|
const DUCKDB_RPC_TIMEOUT_MS = 22e3;
|
|
12
12
|
const WORKER_R2_MAX_FILES = 96;
|
|
13
|
-
const WORKER_R2_MAX_BYTES =
|
|
13
|
+
const WORKER_R2_MAX_BYTES = 67108864;
|
|
14
14
|
const WORKER_R2_DECODE_CONCURRENCY = 2;
|
|
15
15
|
const WORKER_R2_HEAD_CONCURRENCY = 4;
|
|
16
|
-
const IPC_CHUNK_BUDGET =
|
|
17
|
-
const IPC_DIRECT_CALL_BUDGET =
|
|
18
|
-
const IPC_STAGED_TOTAL_BUDGET =
|
|
16
|
+
const IPC_CHUNK_BUDGET = 8388608;
|
|
17
|
+
const IPC_DIRECT_CALL_BUDGET = 31457280;
|
|
18
|
+
const IPC_STAGED_TOTAL_BUDGET = 67108864;
|
|
19
19
|
var DuckDBServiceTimeoutError = class extends Error {
|
|
20
20
|
name = "DuckDBServiceTimeoutError";
|
|
21
21
|
constructor(timeoutMs) {
|
|
@@ -94,7 +94,7 @@ function assertWorkerReadBudget(opts) {
|
|
|
94
94
|
}
|
|
95
95
|
if (totalBytes > maxBytes) throw new Error(`createDucklingsExecutor: planned read spans ${totalBytes} bytes, exceeding the ${maxBytes} byte Worker budget. Narrow the date range or route through a background/windowed query.`);
|
|
96
96
|
}
|
|
97
|
-
const ROW_CACHE_MAX_BYTES =
|
|
97
|
+
const ROW_CACHE_MAX_BYTES = 16777216;
|
|
98
98
|
function estimateRowsBytes(rows) {
|
|
99
99
|
if (rows.length === 0) return 0;
|
|
100
100
|
const cols = Object.keys(rows[0]).length;
|
|
@@ -297,7 +297,8 @@ function createDucklingsExecutor(env, opts = {}) {
|
|
|
297
297
|
});
|
|
298
298
|
const merged = [];
|
|
299
299
|
for (const rows of perFile) merged.push(...rows);
|
|
300
|
-
const
|
|
300
|
+
const placeholderTable = placeholderTables?.[placeholder] ?? table;
|
|
301
|
+
const chunks = rowsToArrowIPCChunks(merged, SCHEMAS[placeholderTable]?.columns, {
|
|
301
302
|
maxChunkBytes,
|
|
302
303
|
placeholder
|
|
303
304
|
});
|
|
@@ -309,11 +310,12 @@ function createDucklingsExecutor(env, opts = {}) {
|
|
|
309
310
|
tableChunks[tmp] = chunks;
|
|
310
311
|
}
|
|
311
312
|
signal?.throwIfAborted();
|
|
312
|
-
const
|
|
313
|
+
const rewritten = sql.replace(READ_PARQUET_PLACEHOLDER, (_, placeholder) => {
|
|
313
314
|
const tmp = tempNames[placeholder];
|
|
314
315
|
if (!tmp) throw new Error(`createDucklingsExecutor: SQL references {{${placeholder}}} but no fileKeys entry provided`);
|
|
315
316
|
return tmp;
|
|
316
|
-
})
|
|
317
|
+
});
|
|
318
|
+
const finalSql = bindLiterals(rewritten, params);
|
|
317
319
|
const canInlineTables = totalIpcBytes <= maxDirectCallBytes && Object.values(tableChunks).every((chunks) => chunks.length === 1);
|
|
318
320
|
let result;
|
|
319
321
|
if (canInlineTables) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gscdump/cloudflare",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.2.0",
|
|
5
5
|
"description": "Cloudflare-Workers-flavored helpers for the gscdump analytics stack: AnalyticsEnv binding contract, R2 SigV4 presigner, DuckDB Workers shims, engine factory.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Harlan Wilton",
|
|
@@ -47,10 +47,10 @@
|
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@uwdata/flechette": "^2.5.0",
|
|
50
|
-
"@gscdump/contracts": "^2.
|
|
51
|
-
"@gscdump/engine": "^2.
|
|
52
|
-
"@gscdump/engine-sqlite": "^2.
|
|
53
|
-
"gscdump": "^2.
|
|
50
|
+
"@gscdump/contracts": "^2.2.0",
|
|
51
|
+
"@gscdump/engine": "^2.2.0",
|
|
52
|
+
"@gscdump/engine-sqlite": "^2.2.0",
|
|
53
|
+
"gscdump": "^2.2.0"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@cloudflare/vitest-pool-workers": "^0.18.8",
|