@gscdump/engine-duckdb-wasm 1.4.0 → 1.4.2
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/archetype-sql.d.mts +15 -0
- package/dist/archetype-sql.mjs +373 -0
- package/dist/drizzle-adapter/client.d.mts +9 -0
- package/dist/drizzle-adapter/client.mjs +20 -0
- package/dist/drizzle-adapter/driver.d.mts +14 -0
- package/dist/drizzle-adapter/driver.mjs +21 -0
- package/dist/drizzle-adapter/index.d.mts +3 -0
- package/dist/drizzle-adapter/index.mjs +3 -0
- package/dist/drizzle-adapter/session.d.mts +8 -0
- package/dist/drizzle-adapter/session.mjs +28 -0
- package/dist/index.d.mts +9 -493
- package/dist/index.mjs +9 -1555
- package/dist/opfs-registry.mjs +89 -0
- package/dist/opfs.d.mts +195 -0
- package/dist/opfs.mjs +584 -0
- package/dist/overlay-view.d.mts +33 -0
- package/dist/overlay-view.mjs +10 -0
- package/dist/runner.d.mts +28 -0
- package/dist/runner.mjs +19 -0
- package/dist/runtime.d.mts +210 -0
- package/dist/runtime.mjs +429 -0
- package/dist/schema.d.mts +2 -0
- package/dist/schema.mjs +2 -0
- package/package.json +4 -4
package/dist/index.d.mts
CHANGED
|
@@ -1,495 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
1
|
+
import { CompiledArchetypeSql, compileArchetypeSql, tableForArchetype } from "./archetype-sql.mjs";
|
|
2
|
+
import { DuckDBWasmClient, createClient } from "./drizzle-adapter/client.mjs";
|
|
3
|
+
import { DuckDBWasmDatabase, DuckDBWasmDrizzleDatabase, drizzle } from "./drizzle-adapter/driver.mjs";
|
|
4
|
+
import "./drizzle-adapter/index.mjs";
|
|
5
|
+
import { AttachOpfsTablesOptions, OpfsAttachTiming, OpfsAttachTimingStage, OpfsAttachedHandle, OpfsFileProgress, OpfsParquetFile, OpfsParquetTable, OpfsQuotaExceededError, attachOpfsParquetTables, clearOpfsSnapshotCache, estimateOpfsStorage, readOpfsSnapshotFile, requestPersistentStorage } from "./opfs.mjs";
|
|
6
|
+
import { overlayViewBody } from "./overlay-view.mjs";
|
|
7
|
+
import { Schema, countries, dates, hourly_pages, page_queries, pages, queries, schema } from "./schema.mjs";
|
|
8
|
+
import { InsightRunner, InsightRunnerOptions, ScopedRunnerOptions, TableScope, createInsightRunner, mergeScope, scopeFor } from "./runner.mjs";
|
|
9
|
+
import { AnalyzeResult, AttachParquetTablesOptions, AttachParquetUrlTablesOptions, AttachedTablesHandle, BootDuckDBWasmOptions, BrowserAnalysisRuntime, BrowserAttachBudgetExceededError, BrowserAttachError, BrowserParquetFile, BrowserParquetTable, BrowserParquetUrlTable, DuckDBWasmBootResult, QueryResult, attachParquetTables, attachParquetUrlTables, attachParquetUrlTablesResult, bootDuckDBWasm, browserAttachErrors, createBrowserAnalysisRuntime, isBrowserAttachError } from "./runtime.mjs";
|
|
8
10
|
import { ComparisonMode, ResolveWindowOptions, ResolvedWindow, WindowPreset, resolveWindow } from "@gscdump/engine/period";
|
|
9
|
-
import { ArchetypeQuery } from "@gscdump/contracts/archetypes";
|
|
10
|
-
import { AsyncDuckDB, AsyncDuckDBConnection, DuckDBBundles, DuckDBConfig } from "@duckdb/duckdb-wasm";
|
|
11
|
-
import { AnalysisParams } from "@gscdump/engine/analysis-types";
|
|
12
|
-
/** A compiled, parameterised statement. */
|
|
13
|
-
interface CompiledArchetypeSql {
|
|
14
|
-
sql: string;
|
|
15
|
-
params: unknown[];
|
|
16
|
-
/** The fact-table view the query reads. */
|
|
17
|
-
table: string;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Compile one archetype query to DuckDB SQL. Throws for `aux-cloud-only`.
|
|
21
|
-
*/
|
|
22
|
-
declare function compileArchetypeSql(query: ArchetypeQuery): CompiledArchetypeSql;
|
|
23
|
-
/** The fact-table view an archetype reads — drives per-table browser routing. */
|
|
24
|
-
declare function tableForArchetype(query: ArchetypeQuery): string | null;
|
|
25
|
-
interface DuckDBWasmClient {
|
|
26
|
-
db: AsyncDuckDB;
|
|
27
|
-
conn: AsyncDuckDBConnection;
|
|
28
|
-
query: (sql: string, params?: unknown[]) => Promise<Record<string, unknown>[]>;
|
|
29
|
-
close: () => Promise<void>;
|
|
30
|
-
}
|
|
31
|
-
declare function createClient(db: AsyncDuckDB, conn: AsyncDuckDBConnection): Promise<DuckDBWasmClient>;
|
|
32
|
-
type Row = Record<string, unknown>;
|
|
33
|
-
interface DuckDBWasmQueryResultHKT extends PgQueryResultHKT {
|
|
34
|
-
type: Assume<this['row'], Row>[];
|
|
35
|
-
}
|
|
36
|
-
type SchemaRelations<TSchema extends Schema$1> = ExtractTablesWithRelations<Record<string, never>, TSchema>;
|
|
37
|
-
declare class DuckDBWasmDatabase<TRelations extends AnyRelations = EmptyRelations> extends PgAsyncDatabase<DuckDBWasmQueryResultHKT, TRelations> {
|
|
38
|
-
static readonly [entityKind]: string;
|
|
39
|
-
}
|
|
40
|
-
interface DuckDBWasmDrizzleDatabase<TSchema extends Schema$1 = Record<string, never>, TRelations extends AnyRelations = SchemaRelations<TSchema>> extends DuckDBWasmDatabase<TRelations> {
|
|
41
|
-
$client: Promise<DuckDBWasmClient>;
|
|
42
|
-
}
|
|
43
|
-
declare function drizzle<TSchema extends Schema$1 = Record<string, never>, TRelations extends AnyRelations = SchemaRelations<TSchema>>(client: Promise<DuckDBWasmClient> | DuckDBWasmClient, config?: DrizzleConfig<TSchema, TRelations>): DuckDBWasmDrizzleDatabase<TSchema, TRelations>;
|
|
44
|
-
/** A parquet data file to materialise into OPFS. */
|
|
45
|
-
interface OpfsParquetFile {
|
|
46
|
-
/** Same-origin URL carrying a signed size hint + short-lived access token. */
|
|
47
|
-
url: string;
|
|
48
|
-
/** Expected byte size — drives progress + a cheap pre-verify shortcut. */
|
|
49
|
-
bytes: number;
|
|
50
|
-
/**
|
|
51
|
-
* Opaque content-stable identifier for this file (e.g. the Iceberg data-
|
|
52
|
-
* file object key). Encoded into the OPFS filename so the same hash is the
|
|
53
|
-
* same cache entry. NOT required to be a SHA-256. When omitted, the cache
|
|
54
|
-
* key falls back to `(table, index)` and only the byte size is verified
|
|
55
|
-
* (degraded — stale entries can survive a content change).
|
|
56
|
-
*/
|
|
57
|
-
contentHash?: string;
|
|
58
|
-
/** Row count — diagnostics only. */
|
|
59
|
-
rowCount?: number;
|
|
60
|
-
}
|
|
61
|
-
/** One logical table and the parquet files that compose it. */
|
|
62
|
-
interface OpfsParquetTable {
|
|
63
|
-
/** Iceberg table name — becomes the DuckDB view name. */
|
|
64
|
-
table: string;
|
|
65
|
-
files: OpfsParquetFile[];
|
|
66
|
-
/**
|
|
67
|
-
* Recent-window overlay parquet (the non-stable tail the lake excludes). When
|
|
68
|
-
* present it is materialised into OPFS alongside `files` and the view unions
|
|
69
|
-
* it with an anti-join dedup: the lake (`files`) serves every day it has, the
|
|
70
|
-
* overlay serves ONLY days the lake lacks. So a stale overlay whose days have
|
|
71
|
-
* since landed in the lake can't double-count, and a day that stabilised but
|
|
72
|
-
* isn't yet in the lake still serves from the overlay. Its `contentHash` must
|
|
73
|
-
* change when the overlay bytes change (it is overwritten in place) so the
|
|
74
|
-
* cache re-downloads.
|
|
75
|
-
*/
|
|
76
|
-
overlay?: OpfsParquetFile;
|
|
77
|
-
}
|
|
78
|
-
interface AttachOpfsTablesOptions {
|
|
79
|
-
db: AsyncDuckDB;
|
|
80
|
-
conn: AsyncDuckDBConnection;
|
|
81
|
-
tables: OpfsParquetTable[];
|
|
82
|
-
/** DuckDB schema the views are created in. Default `main`. */
|
|
83
|
-
schema?: string;
|
|
84
|
-
/** `fetch` override (tests). Default `globalThis.fetch`. */
|
|
85
|
-
fetch?: typeof fetch;
|
|
86
|
-
/** Request init for the parquet downloads (auth headers, credentials mode). */
|
|
87
|
-
fetchInit?: RequestInit;
|
|
88
|
-
/** Caps simultaneous downloads. Default 2. */
|
|
89
|
-
fetchConcurrency?: number;
|
|
90
|
-
/** Abort signal threaded through downloads + registration. */
|
|
91
|
-
signal?: AbortSignal;
|
|
92
|
-
/** Snapshot version associated with this file set — echoed on the handle. */
|
|
93
|
-
version?: string;
|
|
94
|
-
/** Ticks once per file as it lands in OPFS + registers. UI progress. */
|
|
95
|
-
onFileProgress?: (info: OpfsFileProgress) => void;
|
|
96
|
-
/**
|
|
97
|
-
* Low-volume diagnostics for the OPFS attach waterfall. This is intentionally
|
|
98
|
-
* phase-level rather than a logger so hosts can join it with their own route
|
|
99
|
-
* timings without parsing console text.
|
|
100
|
-
*/
|
|
101
|
-
onTiming?: (info: OpfsAttachTiming) => void;
|
|
102
|
-
/**
|
|
103
|
-
* Serializer for the operations that mutate the DuckDB-WASM virtual
|
|
104
|
-
* filesystem / catalog (`registerFileHandle`, `dropFile`, `CREATE`/`DROP
|
|
105
|
-
* VIEW`) — those are not concurrency-safe across consumers sharing one
|
|
106
|
-
* `AsyncDuckDB`. Callers with a shared DB pass their global attach mutex
|
|
107
|
-
* here so ONLY these mutations serialize; the parquet downloads (network +
|
|
108
|
-
* OPFS writes, no DB interaction) run outside the lock and overlap across
|
|
109
|
-
* concurrent attaches. Wrapping the whole `attachOpfsParquetTables` call in
|
|
110
|
-
* the mutex instead serializes every table's downloads end-to-end — the
|
|
111
|
-
* dominant cold-load cost.
|
|
112
|
-
*
|
|
113
|
-
* The returned handle's `detach()` is NOT routed through this — callers
|
|
114
|
-
* that pass a lock typically already hold it around teardown, and the lock
|
|
115
|
-
* is not reentrant.
|
|
116
|
-
*
|
|
117
|
-
* Default: run inline (caller owns the DB exclusively).
|
|
118
|
-
*/
|
|
119
|
-
withDb?: <T>(fn: () => Promise<T>) => Promise<T>;
|
|
120
|
-
/**
|
|
121
|
-
* Recover a table degraded by an OPFS sync-access-handle / write conflict
|
|
122
|
-
* (the multi-tab case — another tab holds the file's exclusive handle) by
|
|
123
|
-
* reading the already-cached bytes via the lock-free File API (or HTTP on a
|
|
124
|
-
* genuine cache miss) and registering them as in-memory buffers, so the table
|
|
125
|
-
* attaches from the shared cache instead of being pushed back to the caller.
|
|
126
|
-
* Quota / incomplete degradations are NEVER recovered this way — buffering a
|
|
127
|
-
* quota-exceeding set risks OOM, and the caller routes those to its tail.
|
|
128
|
-
* Default true.
|
|
129
|
-
*/
|
|
130
|
-
recoverContention?: boolean;
|
|
131
|
-
}
|
|
132
|
-
interface OpfsFileProgress {
|
|
133
|
-
table: string;
|
|
134
|
-
/** OPFS file name. */
|
|
135
|
-
file: string;
|
|
136
|
-
/** Index within the flat file list. */
|
|
137
|
-
index: number;
|
|
138
|
-
/** Total files across all tables. */
|
|
139
|
-
total: number;
|
|
140
|
-
/** Bytes of this file (cumulative caller-side). */
|
|
141
|
-
bytes: number;
|
|
142
|
-
/** `'cache-hit'` — already in OPFS, verified; `'downloaded'` — fetched. */
|
|
143
|
-
outcome: 'cache-hit' | 'downloaded';
|
|
144
|
-
/** Time spent probing/downloading/writing this file before DuckDB registration. */
|
|
145
|
-
materialiseMs?: number;
|
|
146
|
-
/** Time spent inside DuckDB's file-registration mutation lock for this file. */
|
|
147
|
-
registerMs?: number;
|
|
148
|
-
/** End-to-end file phase time, materialise + register + callback overhead. */
|
|
149
|
-
totalMs?: number;
|
|
150
|
-
}
|
|
151
|
-
type OpfsAttachTimingStage = 'persist' | 'root' | 'plan' | 'duckdb-import' | 'sweep' | 'materialise' | 'register' | 'downloads' | 'view' | 'recovery' | 'total';
|
|
152
|
-
interface OpfsAttachTiming {
|
|
153
|
-
stage: OpfsAttachTimingStage;
|
|
154
|
-
durationMs: number;
|
|
155
|
-
table?: string;
|
|
156
|
-
file?: string;
|
|
157
|
-
files?: number;
|
|
158
|
-
tables?: number;
|
|
159
|
-
bytes?: number;
|
|
160
|
-
outcome?: 'cache-hit' | 'downloaded';
|
|
161
|
-
}
|
|
162
|
-
/** Handle returned from {@link attachOpfsParquetTables}. */
|
|
163
|
-
interface OpfsAttachedHandle {
|
|
164
|
-
version: string | undefined;
|
|
165
|
-
/** Tables that successfully attached (a per-table failure drops only that table). */
|
|
166
|
-
tables: string[];
|
|
167
|
-
schema: string;
|
|
168
|
-
/** Total bytes materialised into OPFS for this attach. */
|
|
169
|
-
bytesAttached: number;
|
|
170
|
-
/**
|
|
171
|
-
* Tables that could NOT be attached because OPFS ran out of quota. The
|
|
172
|
-
* caller routes these to the server tail. Empty on a clean attach.
|
|
173
|
-
*/
|
|
174
|
-
degradedTables: string[];
|
|
175
|
-
/**
|
|
176
|
-
* Why each degraded table degraded. 'quota' is actionable (the caller can
|
|
177
|
-
* reclaim space via `clearOpfsSnapshotCache` and retry once); 'contention'
|
|
178
|
-
* and 'incomplete' are transient multi-tab races the buffer fallback
|
|
179
|
-
* already absorbs.
|
|
180
|
-
*/
|
|
181
|
-
degradeReasons: Partial<Record<string, 'quota' | 'contention' | 'incomplete'>>;
|
|
182
|
-
/** Detach the created views + release the registered OPFS file handles. */
|
|
183
|
-
detach: () => Promise<void>;
|
|
184
|
-
}
|
|
185
|
-
/**
|
|
186
|
-
* Raised when OPFS cannot hold the file set. Carries the partial state so the
|
|
187
|
-
* caller can degrade — attach what fit, route the rest server-side.
|
|
188
|
-
*/
|
|
189
|
-
declare class OpfsQuotaExceededError extends Error {
|
|
190
|
-
name: string;
|
|
191
|
-
/** Tables that did not fit. */
|
|
192
|
-
readonly degradedTables: string[];
|
|
193
|
-
constructor(message: string, degradedTables: string[]);
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Request persistent storage so the browser is less likely to evict the OPFS
|
|
197
|
-
* cache under pressure. Returns the granted state — `false` is normal for an
|
|
198
|
-
* un-engaged origin and is NOT an error; it just means eviction is possible.
|
|
199
|
-
*/
|
|
200
|
-
declare function requestPersistentStorage(): Promise<boolean>;
|
|
201
|
-
/** Best-effort `{ usageBytes, quotaBytes }` from the Storage API. */
|
|
202
|
-
declare function estimateOpfsStorage(): Promise<{
|
|
203
|
-
usageBytes?: number;
|
|
204
|
-
quotaBytes?: number;
|
|
205
|
-
}>;
|
|
206
|
-
/**
|
|
207
|
-
* Read a content-addressed OPFS snapshot file via the async File API and return
|
|
208
|
-
* its bytes, or null when absent / size-mismatched (partial / stale write).
|
|
209
|
-
*
|
|
210
|
-
* `getFile()` takes NO lock — unlike DuckDB's `BROWSER_FSACCESS` sync access
|
|
211
|
-
* handle — so it reads cleanly while ANOTHER tab holds the same file open. That
|
|
212
|
-
* is the basis for cross-tab cache sharing: a tab that loses the exclusive-handle
|
|
213
|
-
* race reads the shared cached bytes here instead of re-downloading. The
|
|
214
|
-
* filename derivation is the SAME `opfsFileName` + `contentHashSlug` the attach
|
|
215
|
-
* path writes, so consumers reuse the engine's naming with no replicated slug
|
|
216
|
-
* logic to drift out of lock-step. `index` is only the disambiguator for the
|
|
217
|
-
* degraded no-`contentHash` fallback (mirrors `attachOpfsParquetTables`).
|
|
218
|
-
*/
|
|
219
|
-
declare function readOpfsSnapshotFile(table: string, contentHash: string | undefined, index: number, expectedBytes: number): Promise<Uint8Array | null>;
|
|
220
|
-
/**
|
|
221
|
-
* Download every parquet file in `tables` into OPFS, content-hash verify, and
|
|
222
|
-
* attach them as DuckDB-WASM views. Attach-once: call this once per
|
|
223
|
-
* `(site, table)` span; re-query without re-attaching for filter / range
|
|
224
|
-
* changes inside the span.
|
|
225
|
-
*
|
|
226
|
-
* Quota handling: a `QuotaExceededError` while writing a table's files does
|
|
227
|
-
* NOT throw — that table is recorded in `degradedTables` and skipped; the
|
|
228
|
-
* caller routes it to the server tail. The remaining tables still attach.
|
|
229
|
-
*/
|
|
230
|
-
declare function attachOpfsParquetTables(options: AttachOpfsTablesOptions): Promise<OpfsAttachedHandle>;
|
|
231
|
-
/**
|
|
232
|
-
* Delete every OPFS entry this module created. Used to reclaim space after a
|
|
233
|
-
* quota error, or to force a clean re-download. Best-effort — missing entries
|
|
234
|
-
* are ignored.
|
|
235
|
-
*/
|
|
236
|
-
declare function clearOpfsSnapshotCache(): Promise<void>;
|
|
237
|
-
/**
|
|
238
|
-
* Browser-side recent-overlay merge-on-read SQL — shared by the OPFS attach path
|
|
239
|
-
* (`opfs.ts`) and the in-memory buffer attach path (consumers'
|
|
240
|
-
* `registerParquetView`).
|
|
241
|
-
*
|
|
242
|
-
* The lake serves every day it has; the overlay serves ONLY days the lake lacks
|
|
243
|
-
* (`date NOT IN (SELECT DISTINCT date FROM lake)`), unioned with
|
|
244
|
-
* `UNION ALL BY NAME`. This is the browser sibling of the server's
|
|
245
|
-
* `overlayMergeEnvelope` (in gscdump.com); kept SEPARATE because the browser path
|
|
246
|
-
* can read the lake once via a `MATERIALIZED` CTE (CPU-bound DuckDB-WASM, bounded
|
|
247
|
-
* per-site buffers) where the server's many-s3-file reads prefer projection
|
|
248
|
-
* pushdown over a re-scan.
|
|
249
|
-
*
|
|
250
|
-
* Both `lakeSelect` / `overlaySelect` must already expose a `date` column cast to
|
|
251
|
-
* DATE (the overlay stores ISO strings; `SELECT * REPLACE (CAST(date AS DATE) AS
|
|
252
|
-
* date)`), so `UNION ALL BY NAME` merges them type-uniformly.
|
|
253
|
-
*/
|
|
254
|
-
/**
|
|
255
|
-
* The view BODY (no `CREATE VIEW` wrapper) merging a base lake relation and a
|
|
256
|
-
* recent overlay. Returns null when neither side exists; the lake verbatim with
|
|
257
|
-
* no overlay; the overlay verbatim with no lake (every recent row is wanted).
|
|
258
|
-
*
|
|
259
|
-
* `materializeLake` (default true): wrap the lake in a `MATERIALIZED` CTE so it is
|
|
260
|
-
* scanned ONCE and reused for both the served rows and the anti-join date set — a
|
|
261
|
-
* plain CTE inlines and re-scans the parquet, the dominant cost in DuckDB-WASM.
|
|
262
|
-
* Set false to keep the streaming re-scan shape (lower peak memory, two scans).
|
|
263
|
-
*/
|
|
264
|
-
declare function overlayViewBody(args: {
|
|
265
|
-
lakeSelect: string | null;
|
|
266
|
-
overlaySelect: string | null;
|
|
267
|
-
materializeLake?: boolean;
|
|
268
|
-
}): string | null;
|
|
269
|
-
interface InsightRunnerOptions {
|
|
270
|
-
db: AsyncDuckDB;
|
|
271
|
-
conn: AsyncDuckDBConnection;
|
|
272
|
-
logger?: boolean;
|
|
273
|
-
}
|
|
274
|
-
interface InsightRunner {
|
|
275
|
-
db: DuckDBWasmDrizzleDatabase<Schema>;
|
|
276
|
-
client: Promise<DuckDBWasmClient>;
|
|
277
|
-
close: () => Promise<void>;
|
|
278
|
-
}
|
|
279
|
-
declare function createInsightRunner(opts: InsightRunnerOptions): Promise<InsightRunner>;
|
|
280
|
-
/**
|
|
281
|
-
* Build a per-table predicate set from {siteId, window}. The returned
|
|
282
|
-
* `wherePredicates` composes with user-level filters via `mergeScope`.
|
|
283
|
-
*
|
|
284
|
-
* Note: the current SCHEMAS don't include `site_id` on any table (snapshots
|
|
285
|
-
* are already per-site), so `siteId` is a no-op for now — kept in the API
|
|
286
|
-
* so consumers can add the predicate without an interface change when
|
|
287
|
-
* multi-site snapshots land.
|
|
288
|
-
*/
|
|
289
|
-
declare const scopeFor: (table: "countries" | "dates" | "hourly_pages" | "page_queries" | "pages" | "queries" | "search_appearance" | "search_appearance_page_queries" | "search_appearance_pages" | "search_appearance_queries", opts: ScopedRunnerOptions) => TableScope, mergeScope: typeof import("@gscdump/engine/scope").mergeScope;
|
|
290
|
-
interface QueryResult {
|
|
291
|
-
rows: Record<string, unknown>[];
|
|
292
|
-
queryMs: number;
|
|
293
|
-
}
|
|
294
|
-
interface AnalyzeResult {
|
|
295
|
-
results: Record<string, unknown>[];
|
|
296
|
-
meta: Record<string, unknown>;
|
|
297
|
-
queryMs: number;
|
|
298
|
-
}
|
|
299
|
-
interface DuckDBWasmBootResult {
|
|
300
|
-
db: AsyncDuckDB;
|
|
301
|
-
conn: AsyncDuckDBConnection;
|
|
302
|
-
}
|
|
303
|
-
interface BootDuckDBWasmOptions {
|
|
304
|
-
/**
|
|
305
|
-
* DuckDB-WASM logger. Defaults to a `ConsoleLogger` thresholded at
|
|
306
|
-
* `LogLevel.WARNING`, so real warnings/errors still surface but the per-query
|
|
307
|
-
* INFO events (START/OK/RUN) — which DuckDB's default `ConsoleLogger()` emits
|
|
308
|
-
* as raw objects, flooding the host console with dozens of lines per render —
|
|
309
|
-
* are dropped. Pass `new ConsoleLogger(LogLevel.DEBUG)` to see everything, or
|
|
310
|
-
* `new VoidLogger()` to silence it entirely.
|
|
311
|
-
*/
|
|
312
|
-
logger?: unknown;
|
|
313
|
-
/**
|
|
314
|
-
* Override the jsDelivr-hosted bundle map. Required in environments where
|
|
315
|
-
* the default CDN is unreachable or where hosts must serve the WASM +
|
|
316
|
-
* worker assets themselves (e.g. Cloudflare Workers' 25 MB per-asset cap).
|
|
317
|
-
*/
|
|
318
|
-
bundles?: DuckDBBundles;
|
|
319
|
-
/**
|
|
320
|
-
* Extra DuckDB open config. The browser runtime always forces HTTP files
|
|
321
|
-
* into range-only mode (reliable HEAD probes, no full HTTP fallback) so a
|
|
322
|
-
* server that cannot answer bounded reads fails closed.
|
|
323
|
-
*/
|
|
324
|
-
config?: DuckDBConfig;
|
|
325
|
-
/**
|
|
326
|
-
* Cap DuckDB's memory with `SET memory_limit=<value>` right after open (e.g.
|
|
327
|
-
* `'2GB'`, `'512MB'`). A runaway query then errors with a clean
|
|
328
|
-
* out-of-memory rather than growing the WASM heap until the tab crashes —
|
|
329
|
-
* DuckDB has no statement-level timeout, so abandoned queries are otherwise
|
|
330
|
-
* only stopped by the caller's `AbortSignal` (which the runtime forwards to
|
|
331
|
-
* `conn.cancelSent()`). Opt-in: omit to keep DuckDB-WASM's default sizing.
|
|
332
|
-
* Accepts `<number>` with an optional `B`/`KB`/`MB`/`GB`/`TB` suffix.
|
|
333
|
-
*/
|
|
334
|
-
memoryLimit?: string;
|
|
335
|
-
}
|
|
336
|
-
interface BrowserParquetFile {
|
|
337
|
-
bytes: Uint8Array;
|
|
338
|
-
name?: string;
|
|
339
|
-
}
|
|
340
|
-
interface BrowserParquetTable {
|
|
341
|
-
table: string;
|
|
342
|
-
files: BrowserParquetFile[];
|
|
343
|
-
}
|
|
344
|
-
interface BrowserParquetUrlTable {
|
|
345
|
-
table: string;
|
|
346
|
-
urls: string[];
|
|
347
|
-
}
|
|
348
|
-
interface AttachParquetTablesOptions {
|
|
349
|
-
db: AsyncDuckDB;
|
|
350
|
-
conn: AsyncDuckDBConnection;
|
|
351
|
-
tables: BrowserParquetTable[];
|
|
352
|
-
schema?: string;
|
|
353
|
-
}
|
|
354
|
-
interface AttachParquetUrlTablesOptions {
|
|
355
|
-
db: AsyncDuckDB;
|
|
356
|
-
conn: AsyncDuckDBConnection;
|
|
357
|
-
tables: BrowserParquetUrlTable[];
|
|
358
|
-
fetch?: typeof fetch;
|
|
359
|
-
schema?: string;
|
|
360
|
-
/**
|
|
361
|
-
* Request init used only for runtime-owned HEAD / one-byte Range preflights.
|
|
362
|
-
* DuckDB-WASM's internal HTTP reader cannot receive custom fetch headers;
|
|
363
|
-
* URL reads must therefore be authorized by the URL itself.
|
|
364
|
-
*/
|
|
365
|
-
fetchInit?: RequestInit;
|
|
366
|
-
/**
|
|
367
|
-
* Caps simultaneous URL preflights. Browser source endpoints should already
|
|
368
|
-
* return small, coverage-planned URL sets; this is the runtime's local
|
|
369
|
-
* guard against accidental unbounded attachment.
|
|
370
|
-
*/
|
|
371
|
-
fetchConcurrency?: number;
|
|
372
|
-
/** Reject before preflight when the URL set exceeds this many parquet files. */
|
|
373
|
-
maxFiles?: number;
|
|
374
|
-
/** Reject before registration when hinted or authoritative bytes exceed budget. */
|
|
375
|
-
maxBytes?: number;
|
|
376
|
-
/** Abort signal passed through to URL preflights and registration. */
|
|
377
|
-
signal?: AbortSignal;
|
|
378
|
-
/**
|
|
379
|
-
* How DuckDB reads the parquet bytes:
|
|
380
|
-
* - `'http'` (default): register the URL as an HTTP file; DuckDB issues
|
|
381
|
-
* its own range reads during query execution. Right for large parquet
|
|
382
|
-
* where only some column chunks are touched per query.
|
|
383
|
-
* - `'buffer'`: fetch the full file once into an `ArrayBuffer` and register
|
|
384
|
-
* it via `registerFileBuffer`. DuckDB makes zero HTTP calls after
|
|
385
|
-
* registration — every query reads from the in-memory copy. Right for
|
|
386
|
-
* tiny files (e.g. `dates` daily-totals parquet, <50 KB per file) where
|
|
387
|
-
* the per-file round-trip overhead dominates the actual bytes moved.
|
|
388
|
-
*/
|
|
389
|
-
attachMode?: 'http' | 'buffer';
|
|
390
|
-
/**
|
|
391
|
-
* When `true` (default), skip per-file HEAD/Range preflight if the URL
|
|
392
|
-
* carries a signed `?s=<bytes>.<sig>` size hint — the size is already
|
|
393
|
-
* known and DuckDB will learn `Accept-Ranges` from its first read.
|
|
394
|
-
* Eliminates one round-trip per file on hosts that mint size hints. Set
|
|
395
|
-
* `false` to force preflight against URLs whose size you don't trust.
|
|
396
|
-
*/
|
|
397
|
-
trustSizeHint?: boolean;
|
|
398
|
-
/**
|
|
399
|
-
* Manifest version the caller associates with this set of URLs. Returned
|
|
400
|
-
* on the resulting handle so callers can compare against a fresh manifest
|
|
401
|
-
* probe without re-attaching. Purely advisory — the runtime never derives
|
|
402
|
-
* behavior from the value itself.
|
|
403
|
-
*/
|
|
404
|
-
version?: number | string;
|
|
405
|
-
/**
|
|
406
|
-
* Called once per parquet file after it's been fetched and registered with
|
|
407
|
-
* DuckDB. For URL-backed HTTP files this means "preflighted and registered"
|
|
408
|
-
* rather than fully downloaded; DuckDB then performs range reads during the
|
|
409
|
-
* query. Fires in bounded-concurrency completion order, which is still not
|
|
410
|
-
* guaranteed to match manifest URL order. Used by UI progress indicators to
|
|
411
|
-
* tick a per-site counter; a no-op default keeps the hot path free.
|
|
412
|
-
*/
|
|
413
|
-
onFileAttached?: (info: {
|
|
414
|
-
table: string;
|
|
415
|
-
index: number;
|
|
416
|
-
total: number;
|
|
417
|
-
}) => void;
|
|
418
|
-
}
|
|
419
|
-
/**
|
|
420
|
-
* Handle returned from {@link attachParquetUrlTables}. Lets callers detach
|
|
421
|
-
* the created views (for lazy re-attach on a new manifest version) or cheap-
|
|
422
|
-
* check the embedded version against a fresh probe.
|
|
423
|
-
*/
|
|
424
|
-
interface AttachedTablesHandle {
|
|
425
|
-
version: number | string | undefined;
|
|
426
|
-
tables: string[];
|
|
427
|
-
schema: string;
|
|
428
|
-
detach: () => Promise<void>;
|
|
429
|
-
}
|
|
430
|
-
interface BrowserAnalysisRuntime {
|
|
431
|
-
db: AsyncDuckDB;
|
|
432
|
-
conn: AsyncDuckDBConnection;
|
|
433
|
-
query: (sql: string, params?: unknown[], signal?: AbortSignal) => Promise<QueryResult>;
|
|
434
|
-
analyze: (params: AnalysisParams, registry: AnalyzerRegistry, options?: {
|
|
435
|
-
signal?: AbortSignal;
|
|
436
|
-
}) => Promise<AnalyzeResult>;
|
|
437
|
-
/**
|
|
438
|
-
* Returns true when `expected` doesn't match the version the runtime was
|
|
439
|
-
* attached with — cheap check callers can run before each query to decide
|
|
440
|
-
* whether to detach + re-attach against a fresher manifest. Undefined
|
|
441
|
-
* values on either side compare equal so the no-version path is a no-op.
|
|
442
|
-
*/
|
|
443
|
-
isStale: (expected: number | string | undefined) => boolean;
|
|
444
|
-
/** Update the runtime's cached manifest version in-place (e.g. after a re-attach). */
|
|
445
|
-
setVersion: (version: number | string | undefined) => void;
|
|
446
|
-
/**
|
|
447
|
-
* Update the list of attached table names. Lets callers fast-fail in
|
|
448
|
-
* `analyze()` when a SQL plan references a table that wasn't in the manifest
|
|
449
|
-
* for this site (e.g. site has only `queries` parquet, analyzer wants
|
|
450
|
-
* `page_queries`) — surface a clean `AttachedTableMissingError` so the
|
|
451
|
-
* caller can route to cloud fallback without paying the SQL execution cost.
|
|
452
|
-
*/
|
|
453
|
-
setAttachedTables: (tables: readonly string[]) => void;
|
|
454
|
-
close: () => Promise<void>;
|
|
455
|
-
}
|
|
456
|
-
declare class BrowserAttachBudgetExceededError extends Error {
|
|
457
|
-
name: string;
|
|
458
|
-
}
|
|
459
|
-
interface BrowserAttachError {
|
|
460
|
-
kind: 'browser-attach-budget-exceeded';
|
|
461
|
-
message: string;
|
|
462
|
-
/** Which budget tripped: the file count, the hinted byte plan, or the running byte plan. */
|
|
463
|
-
budget: 'maxFiles' | 'maxBytes';
|
|
464
|
-
}
|
|
465
|
-
declare const browserAttachErrors: {
|
|
466
|
-
readonly maxFilesExceeded: (files: number, maxFiles: number) => BrowserAttachError;
|
|
467
|
-
readonly hintedBytesExceeded: (hintedBytes: number, maxBytes: number) => BrowserAttachError;
|
|
468
|
-
readonly plannedBytesExceeded: (plannedBytes: number, maxBytes: number) => BrowserAttachError;
|
|
469
|
-
};
|
|
470
|
-
declare function isBrowserAttachError(value: unknown): value is BrowserAttachError;
|
|
471
|
-
declare function bootDuckDBWasm(options?: BootDuckDBWasmOptions): Promise<DuckDBWasmBootResult>;
|
|
472
|
-
declare function attachParquetTables(options: AttachParquetTablesOptions): Promise<void>;
|
|
473
|
-
/**
|
|
474
|
-
* Errors-as-values core for {@link attachParquetUrlTables}: returns a typed
|
|
475
|
-
* {@link BrowserAttachError} when the requested file set blows the local file-
|
|
476
|
-
* count / byte budget, so callers can branch (route the affected tables
|
|
477
|
-
* server-side) instead of catching an untyped throw. WASM/DuckDB/HTTP IO
|
|
478
|
-
* failures stay defects and propagate. `attachParquetUrlTables` is the thin
|
|
479
|
-
* throwing wrapper preserving the historical `BrowserAttachBudgetExceededError`.
|
|
480
|
-
*/
|
|
481
|
-
declare function attachParquetUrlTablesResult(options: AttachParquetUrlTablesOptions): Promise<Result<AttachedTablesHandle, BrowserAttachError>>;
|
|
482
|
-
/**
|
|
483
|
-
* Attach browser parquet URL tables, throwing
|
|
484
|
-
* {@link BrowserAttachBudgetExceededError} when the requested set blows the
|
|
485
|
-
* file-count / byte budget. Thin throwing wrapper over
|
|
486
|
-
* {@link attachParquetUrlTablesResult}; existing call sites and their
|
|
487
|
-
* `instanceof BrowserAttachBudgetExceededError` checks keep holding.
|
|
488
|
-
*/
|
|
489
|
-
declare function attachParquetUrlTables(options: AttachParquetUrlTablesOptions): Promise<AttachedTablesHandle>;
|
|
490
|
-
declare function createBrowserAnalysisRuntime(boot: DuckDBWasmBootResult, options?: {
|
|
491
|
-
schema?: string;
|
|
492
|
-
version?: number | string;
|
|
493
|
-
attachedTables?: readonly string[];
|
|
494
|
-
}): BrowserAnalysisRuntime;
|
|
495
11
|
export { type AnalyzeResult, type AttachOpfsTablesOptions, type AttachParquetTablesOptions, type AttachParquetUrlTablesOptions, type AttachedTablesHandle, type BootDuckDBWasmOptions, type BrowserAnalysisRuntime, BrowserAttachBudgetExceededError, type BrowserAttachError, type BrowserParquetFile, type BrowserParquetTable, type BrowserParquetUrlTable, type ComparisonMode, type CompiledArchetypeSql, type DuckDBWasmBootResult, type DuckDBWasmClient, DuckDBWasmDatabase, type DuckDBWasmDrizzleDatabase, type InsightRunner, type InsightRunnerOptions, type OpfsAttachTiming, type OpfsAttachTimingStage, type OpfsAttachedHandle, type OpfsFileProgress, type OpfsParquetFile, type OpfsParquetTable, OpfsQuotaExceededError, type QueryResult, type ResolveWindowOptions, type ResolvedWindow, type Schema, type ScopedRunnerOptions, type TableScope, type WindowPreset, attachOpfsParquetTables, attachParquetTables, attachParquetUrlTables, attachParquetUrlTablesResult, bootDuckDBWasm, browserAttachErrors, clearOpfsSnapshotCache, compileArchetypeSql, countries, createBrowserAnalysisRuntime, createClient, createInsightRunner, dates, drizzle, estimateOpfsStorage, hourly_pages, isBrowserAttachError, mergeScope, overlayViewBody, page_queries, pages, queries, readOpfsSnapshotFile, requestPersistentStorage, resolveWindow, schema, scopeFor, tableForArchetype };
|