@gscdump/engine-duckdb-wasm 0.32.10 → 0.32.11
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/index.d.mts +24 -1
- package/dist/index.mjs +154 -68
- package/package.json +4 -4
package/dist/index.d.mts
CHANGED
|
@@ -136,6 +136,12 @@ interface AttachOpfsTablesOptions {
|
|
|
136
136
|
version?: string;
|
|
137
137
|
/** Ticks once per file as it lands in OPFS + registers. UI progress. */
|
|
138
138
|
onFileProgress?: (info: OpfsFileProgress) => void;
|
|
139
|
+
/**
|
|
140
|
+
* Low-volume diagnostics for the OPFS attach waterfall. This is intentionally
|
|
141
|
+
* phase-level rather than a logger so hosts can join it with their own route
|
|
142
|
+
* timings without parsing console text.
|
|
143
|
+
*/
|
|
144
|
+
onTiming?: (info: OpfsAttachTiming) => void;
|
|
139
145
|
/**
|
|
140
146
|
* Serializer for the operations that mutate the DuckDB-WASM virtual
|
|
141
147
|
* filesystem / catalog (`registerFileHandle`, `dropFile`, `CREATE`/`DROP
|
|
@@ -178,6 +184,23 @@ interface OpfsFileProgress {
|
|
|
178
184
|
bytes: number;
|
|
179
185
|
/** `'cache-hit'` — already in OPFS, verified; `'downloaded'` — fetched. */
|
|
180
186
|
outcome: 'cache-hit' | 'downloaded';
|
|
187
|
+
/** Time spent probing/downloading/writing this file before DuckDB registration. */
|
|
188
|
+
materialiseMs?: number;
|
|
189
|
+
/** Time spent inside DuckDB's file-registration mutation lock for this file. */
|
|
190
|
+
registerMs?: number;
|
|
191
|
+
/** End-to-end file phase time, materialise + register + callback overhead. */
|
|
192
|
+
totalMs?: number;
|
|
193
|
+
}
|
|
194
|
+
type OpfsAttachTimingStage = 'persist' | 'root' | 'plan' | 'duckdb-import' | 'sweep' | 'materialise' | 'register' | 'downloads' | 'view' | 'recovery' | 'total';
|
|
195
|
+
interface OpfsAttachTiming {
|
|
196
|
+
stage: OpfsAttachTimingStage;
|
|
197
|
+
durationMs: number;
|
|
198
|
+
table?: string;
|
|
199
|
+
file?: string;
|
|
200
|
+
files?: number;
|
|
201
|
+
tables?: number;
|
|
202
|
+
bytes?: number;
|
|
203
|
+
outcome?: 'cache-hit' | 'downloaded';
|
|
181
204
|
}
|
|
182
205
|
/** Handle returned from {@link attachOpfsParquetTables}. */
|
|
183
206
|
interface OpfsAttachedHandle {
|
|
@@ -484,4 +507,4 @@ declare function createBrowserAnalysisRuntime(boot: DuckDBWasmBootResult, option
|
|
|
484
507
|
version?: number | string;
|
|
485
508
|
attachedTables?: readonly string[];
|
|
486
509
|
}): BrowserAnalysisRuntime;
|
|
487
|
-
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 OpfsAttachedHandle, type OpfsFileProgress, type OpfsParquetFile, type OpfsParquetTable, OpfsQuotaExceededError, type QueryResult, type ResolveWindowOptions, type ResolvedWindow, type Schema, type ScopedRunnerOptions, type StrikingMomentumOptions, type StrikingMomentumRow, 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, strikingMomentum, tableForArchetype };
|
|
510
|
+
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 StrikingMomentumOptions, type StrikingMomentumRow, 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, strikingMomentum, tableForArchetype };
|
package/dist/index.mjs
CHANGED
|
@@ -567,6 +567,28 @@ var OpfsQuotaExceededError = class extends Error {
|
|
|
567
567
|
const DEFAULT_CONCURRENCY = 2;
|
|
568
568
|
const OPFS_PREFIX = "gscdump-snapshot__";
|
|
569
569
|
const RECOVER_BUFFER_PREFIX = "gscdump-recover__";
|
|
570
|
+
const MAX_CONTENT_HASH_SLUG_CACHE = 4096;
|
|
571
|
+
const contentHashSlugCache = /* @__PURE__ */ new Map();
|
|
572
|
+
function nowMs() {
|
|
573
|
+
return globalThis.performance?.now?.() ?? Date.now();
|
|
574
|
+
}
|
|
575
|
+
function emitTiming(onTiming, info) {
|
|
576
|
+
try {
|
|
577
|
+
onTiming?.(info);
|
|
578
|
+
} catch {}
|
|
579
|
+
}
|
|
580
|
+
async function timed(onTiming, stage, meta, fn) {
|
|
581
|
+
const started = nowMs();
|
|
582
|
+
try {
|
|
583
|
+
return await fn();
|
|
584
|
+
} finally {
|
|
585
|
+
emitTiming(onTiming, {
|
|
586
|
+
...meta,
|
|
587
|
+
stage,
|
|
588
|
+
durationMs: nowMs() - started
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
}
|
|
570
592
|
const dbRegistries = /* @__PURE__ */ new WeakMap();
|
|
571
593
|
function getOpfsRegistry(db, protocol) {
|
|
572
594
|
let registry = dbRegistries.get(db);
|
|
@@ -636,6 +658,20 @@ async function estimateOpfsStorage() {
|
|
|
636
658
|
} : {};
|
|
637
659
|
}
|
|
638
660
|
async function contentHashSlug(contentHash) {
|
|
661
|
+
const cached = contentHashSlugCache.get(contentHash);
|
|
662
|
+
if (cached) return cached;
|
|
663
|
+
if (contentHashSlugCache.size >= MAX_CONTENT_HASH_SLUG_CACHE) {
|
|
664
|
+
const oldest = contentHashSlugCache.keys().next().value;
|
|
665
|
+
if (oldest !== void 0) contentHashSlugCache.delete(oldest);
|
|
666
|
+
}
|
|
667
|
+
const promise = deriveContentHashSlug(contentHash).catch((err) => {
|
|
668
|
+
contentHashSlugCache.delete(contentHash);
|
|
669
|
+
throw err;
|
|
670
|
+
});
|
|
671
|
+
contentHashSlugCache.set(contentHash, promise);
|
|
672
|
+
return promise;
|
|
673
|
+
}
|
|
674
|
+
async function deriveContentHashSlug(contentHash) {
|
|
639
675
|
const digest = await globalThis.crypto.subtle.digest("SHA-256", new TextEncoder().encode(contentHash));
|
|
640
676
|
const bytes = new Uint8Array(digest);
|
|
641
677
|
let hex = "";
|
|
@@ -724,43 +760,49 @@ async function runWithConcurrency$1(items, concurrency, fn) {
|
|
|
724
760
|
await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, worker));
|
|
725
761
|
}
|
|
726
762
|
async function attachOpfsParquetTables(options) {
|
|
727
|
-
const { db, conn, tables, schema = "main", fetch: fetchImpl = globalThis.fetch.bind(globalThis), fetchInit, fetchConcurrency = DEFAULT_CONCURRENCY, signal, version, onFileProgress, withDb = (fn) => fn(), recoverContention = true } = options;
|
|
728
|
-
|
|
729
|
-
|
|
763
|
+
const { db, conn, tables, schema = "main", fetch: fetchImpl = globalThis.fetch.bind(globalThis), fetchInit, fetchConcurrency = DEFAULT_CONCURRENCY, signal, version, onFileProgress, onTiming, withDb = (fn) => fn(), recoverContention = true } = options;
|
|
764
|
+
const totalStarted = nowMs();
|
|
765
|
+
await timed(onTiming, "persist", {}, requestPersistentStorage);
|
|
766
|
+
const root = await timed(onTiming, "root", {}, getOpfsRoot);
|
|
730
767
|
const flat = [];
|
|
731
768
|
const expectedByTable = /* @__PURE__ */ new Map();
|
|
732
|
-
|
|
733
|
-
const
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
769
|
+
await timed(onTiming, "plan", { tables: tables.length }, async () => {
|
|
770
|
+
for (const t of tables) {
|
|
771
|
+
const expected = /* @__PURE__ */ new Set();
|
|
772
|
+
for (let i = 0; i < t.files.length; i++) {
|
|
773
|
+
const file = t.files[i];
|
|
774
|
+
const slug = file.contentHash ? await contentHashSlug(file.contentHash) : void 0;
|
|
775
|
+
const name = opfsFileName(t.table, slug, i);
|
|
776
|
+
flat.push({
|
|
777
|
+
table: t.table,
|
|
778
|
+
file,
|
|
779
|
+
name
|
|
780
|
+
});
|
|
781
|
+
expected.add(name);
|
|
782
|
+
}
|
|
783
|
+
if (t.overlay) {
|
|
784
|
+
const slug = t.overlay.contentHash ? await contentHashSlug(t.overlay.contentHash) : void 0;
|
|
785
|
+
const name = opfsFileName(t.table, slug, t.files.length);
|
|
786
|
+
flat.push({
|
|
787
|
+
table: t.table,
|
|
788
|
+
file: t.overlay,
|
|
789
|
+
name,
|
|
790
|
+
overlay: true
|
|
791
|
+
});
|
|
792
|
+
expected.add(name);
|
|
793
|
+
}
|
|
794
|
+
expectedByTable.set(t.table, expected);
|
|
755
795
|
}
|
|
756
|
-
|
|
757
|
-
}
|
|
796
|
+
});
|
|
758
797
|
const total = flat.length;
|
|
759
798
|
const overlayNames = /* @__PURE__ */ new Map();
|
|
760
799
|
const expectedCount = new Map(tables.map((t) => [t.table, t.files.length + (t.overlay ? 1 : 0)]));
|
|
761
|
-
const { DuckDBDataProtocol } = await import("@duckdb/duckdb-wasm");
|
|
800
|
+
const { DuckDBDataProtocol } = await timed(onTiming, "duckdb-import", {}, () => import("@duckdb/duckdb-wasm"));
|
|
762
801
|
const registry = getOpfsRegistry(db, DuckDBDataProtocol.BROWSER_FSACCESS);
|
|
763
|
-
await
|
|
802
|
+
await timed(onTiming, "sweep", {
|
|
803
|
+
files: total,
|
|
804
|
+
tables: tables.length
|
|
805
|
+
}, () => sweepStaleEntries(root, registry, expectedByTable)).catch(() => {});
|
|
764
806
|
const tableFiles = /* @__PURE__ */ new Map();
|
|
765
807
|
const degraded = /* @__PURE__ */ new Set();
|
|
766
808
|
const degradeReason = /* @__PURE__ */ new Map();
|
|
@@ -776,10 +818,23 @@ async function attachOpfsParquetTables(options) {
|
|
|
776
818
|
const runDownloads = () => runWithConcurrency$1(flat, Math.max(1, fetchConcurrency), async (item, index) => {
|
|
777
819
|
if (degraded.has(item.table)) return;
|
|
778
820
|
signal?.throwIfAborted();
|
|
821
|
+
const fileStarted = nowMs();
|
|
779
822
|
const name = item.name;
|
|
780
823
|
let result;
|
|
824
|
+
let materialiseMs = 0;
|
|
825
|
+
let registerMs = 0;
|
|
781
826
|
try {
|
|
827
|
+
const materialiseStarted = nowMs();
|
|
782
828
|
result = await materialiseFile(root, name, item.file, fetchImpl, fetchInit, signal);
|
|
829
|
+
materialiseMs = nowMs() - materialiseStarted;
|
|
830
|
+
emitTiming(onTiming, {
|
|
831
|
+
stage: "materialise",
|
|
832
|
+
durationMs: materialiseMs,
|
|
833
|
+
table: item.table,
|
|
834
|
+
file: name,
|
|
835
|
+
bytes: item.file.bytes,
|
|
836
|
+
outcome: result.outcome
|
|
837
|
+
});
|
|
783
838
|
} catch (err) {
|
|
784
839
|
if (isAbortError$1(err)) throw err;
|
|
785
840
|
if (isQuotaError(err)) {
|
|
@@ -795,7 +850,17 @@ async function attachOpfsParquetTables(options) {
|
|
|
795
850
|
throw err;
|
|
796
851
|
}
|
|
797
852
|
try {
|
|
853
|
+
const registerStarted = nowMs();
|
|
798
854
|
await withDb(() => registry.acquire(name, () => result.handle));
|
|
855
|
+
registerMs = nowMs() - registerStarted;
|
|
856
|
+
emitTiming(onTiming, {
|
|
857
|
+
stage: "register",
|
|
858
|
+
durationMs: registerMs,
|
|
859
|
+
table: item.table,
|
|
860
|
+
file: name,
|
|
861
|
+
bytes: item.file.bytes,
|
|
862
|
+
outcome: result.outcome
|
|
863
|
+
});
|
|
799
864
|
acquiredNames.add(name);
|
|
800
865
|
} catch (err) {
|
|
801
866
|
if (isAbortError$1(err)) throw err;
|
|
@@ -820,11 +885,17 @@ async function attachOpfsParquetTables(options) {
|
|
|
820
885
|
index,
|
|
821
886
|
total,
|
|
822
887
|
bytes: item.file.bytes,
|
|
823
|
-
outcome: result.outcome
|
|
888
|
+
outcome: result.outcome,
|
|
889
|
+
materialiseMs,
|
|
890
|
+
registerMs,
|
|
891
|
+
totalMs: nowMs() - fileStarted
|
|
824
892
|
});
|
|
825
893
|
});
|
|
826
894
|
try {
|
|
827
|
-
await
|
|
895
|
+
await timed(onTiming, "downloads", {
|
|
896
|
+
files: total,
|
|
897
|
+
tables: tables.length
|
|
898
|
+
}, runDownloads);
|
|
828
899
|
} catch (err) {
|
|
829
900
|
await withDb(() => registry.release([...acquiredNames])).catch(() => {});
|
|
830
901
|
throw err;
|
|
@@ -847,7 +918,10 @@ async function attachOpfsParquetTables(options) {
|
|
|
847
918
|
const lakeNames = overlayName ? files.map((f) => f.name).filter((n) => n !== overlayName) : files.map((f) => f.name);
|
|
848
919
|
try {
|
|
849
920
|
signal?.throwIfAborted();
|
|
850
|
-
await
|
|
921
|
+
await timed(onTiming, "view", {
|
|
922
|
+
table: t.table,
|
|
923
|
+
files: files.length
|
|
924
|
+
}, () => withDb(() => conn.query(overlayName ? readParquetViewWithOverlaySql(schema, t.table, lakeNames, overlayName) : readParquetViewSql$1(schema, t.table, lakeNames))));
|
|
851
925
|
} catch (err) {
|
|
852
926
|
if (isAbortError$1(err)) {
|
|
853
927
|
await withDb(() => detachOpfs(registry, conn, schema, attached, [...acquiredNames])).catch(() => {});
|
|
@@ -868,43 +942,48 @@ async function attachOpfsParquetTables(options) {
|
|
|
868
942
|
for (const f of files) registeredNames.push(f.name);
|
|
869
943
|
}
|
|
870
944
|
const recoverTableToBuffers = async (t) => {
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
const
|
|
876
|
-
|
|
877
|
-
|
|
945
|
+
return timed(onTiming, "recovery", {
|
|
946
|
+
table: t.table,
|
|
947
|
+
files: t.files.length + (t.overlay ? 1 : 0)
|
|
948
|
+
}, async () => {
|
|
949
|
+
const readOne = async (file, index) => {
|
|
950
|
+
const cached = await readOpfsSnapshotFile(t.table, file.contentHash, index, file.bytes);
|
|
951
|
+
if (cached) return cached;
|
|
952
|
+
signal?.throwIfAborted();
|
|
953
|
+
const resp = await fetchImpl(file.url, {
|
|
954
|
+
...fetchInit,
|
|
955
|
+
signal
|
|
956
|
+
});
|
|
957
|
+
if (!resp.ok) throw new Error(`[engine-duckdb-wasm/opfs] recover ${file.url} failed: ${resp.status}`);
|
|
958
|
+
return new Uint8Array(await resp.arrayBuffer());
|
|
959
|
+
};
|
|
960
|
+
const lakeNames = [];
|
|
961
|
+
for (let i = 0; i < t.files.length; i++) {
|
|
962
|
+
const buf = await readOne(t.files[i], i);
|
|
963
|
+
const name = `${RECOVER_BUFFER_PREFIX}${t.table}_${i}.parquet`;
|
|
964
|
+
await withDb(() => db.registerFileBuffer(name, buf));
|
|
965
|
+
bufferFiles.push(name);
|
|
966
|
+
lakeNames.push(name);
|
|
967
|
+
bytesAttached += t.files[i].bytes;
|
|
968
|
+
}
|
|
969
|
+
let overlayName;
|
|
970
|
+
if (t.overlay) {
|
|
971
|
+
const buf = await readOne(t.overlay, t.files.length);
|
|
972
|
+
overlayName = `${RECOVER_BUFFER_PREFIX}${t.table}_overlay.parquet`;
|
|
973
|
+
await withDb(() => db.registerFileBuffer(overlayName, buf));
|
|
974
|
+
bufferFiles.push(overlayName);
|
|
975
|
+
bytesAttached += t.overlay.bytes;
|
|
976
|
+
}
|
|
977
|
+
const body = overlayViewBody({
|
|
978
|
+
lakeSelect: lakeNames.length ? lakeSelect(lakeNames) : null,
|
|
979
|
+
overlaySelect: overlayName ? `SELECT * REPLACE (CAST(date AS DATE) AS date) FROM read_parquet(['${overlayName.replace(/'/g, "''")}'], union_by_name = true)` : null,
|
|
980
|
+
materializeLake: false
|
|
878
981
|
});
|
|
879
|
-
if (!
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
for (let i = 0; i < t.files.length; i++) {
|
|
884
|
-
const buf = await readOne(t.files[i], i);
|
|
885
|
-
const name = `${RECOVER_BUFFER_PREFIX}${t.table}_${i}.parquet`;
|
|
886
|
-
await withDb(() => db.registerFileBuffer(name, buf));
|
|
887
|
-
bufferFiles.push(name);
|
|
888
|
-
lakeNames.push(name);
|
|
889
|
-
bytesAttached += t.files[i].bytes;
|
|
890
|
-
}
|
|
891
|
-
let overlayName;
|
|
892
|
-
if (t.overlay) {
|
|
893
|
-
const buf = await readOne(t.overlay, t.files.length);
|
|
894
|
-
overlayName = `${RECOVER_BUFFER_PREFIX}${t.table}_overlay.parquet`;
|
|
895
|
-
await withDb(() => db.registerFileBuffer(overlayName, buf));
|
|
896
|
-
bufferFiles.push(overlayName);
|
|
897
|
-
bytesAttached += t.overlay.bytes;
|
|
898
|
-
}
|
|
899
|
-
const body = overlayViewBody({
|
|
900
|
-
lakeSelect: lakeNames.length ? lakeSelect(lakeNames) : null,
|
|
901
|
-
overlaySelect: overlayName ? `SELECT * REPLACE (CAST(date AS DATE) AS date) FROM read_parquet(['${overlayName.replace(/'/g, "''")}'], union_by_name = true)` : null,
|
|
902
|
-
materializeLake: false
|
|
982
|
+
if (!body) return false;
|
|
983
|
+
await withDb(() => conn.query(`CREATE OR REPLACE VIEW ${schema}.${t.table} AS ${body}`));
|
|
984
|
+
bufferViews.push(t.table);
|
|
985
|
+
return true;
|
|
903
986
|
});
|
|
904
|
-
if (!body) return false;
|
|
905
|
-
await withDb(() => conn.query(`CREATE OR REPLACE VIEW ${schema}.${t.table} AS ${body}`));
|
|
906
|
-
bufferViews.push(t.table);
|
|
907
|
-
return true;
|
|
908
987
|
};
|
|
909
988
|
if (recoverContention && !signal?.aborted) for (const t of tables) {
|
|
910
989
|
if (!degraded.has(t.table) || degradeReason.get(t.table) !== "contention") continue;
|
|
@@ -915,6 +994,13 @@ async function attachOpfsParquetTables(options) {
|
|
|
915
994
|
bufferFiles.length = before;
|
|
916
995
|
}
|
|
917
996
|
}
|
|
997
|
+
emitTiming(onTiming, {
|
|
998
|
+
stage: "total",
|
|
999
|
+
durationMs: nowMs() - totalStarted,
|
|
1000
|
+
files: total,
|
|
1001
|
+
tables: tables.length,
|
|
1002
|
+
bytes: bytesAttached
|
|
1003
|
+
});
|
|
918
1004
|
let detached = false;
|
|
919
1005
|
return {
|
|
920
1006
|
version,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gscdump/engine-duckdb-wasm",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.32.
|
|
4
|
+
"version": "0.32.11",
|
|
5
5
|
"description": "DuckDB-WASM engine adapter for @gscdump/analysis — typed browser analytics against parquet via R2.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Harlan Wilton",
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"drizzle-orm": "1.0.0-rc.3",
|
|
48
|
-
"@gscdump/contracts": "0.32.
|
|
49
|
-
"@gscdump/engine": "0.32.
|
|
50
|
-
"gscdump": "0.32.
|
|
48
|
+
"@gscdump/contracts": "0.32.11",
|
|
49
|
+
"@gscdump/engine": "0.32.11",
|
|
50
|
+
"gscdump": "0.32.11"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@duckdb/duckdb-wasm": "^1.32.0",
|