@gscdump/engine 0.7.5 → 0.8.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.
@@ -1,115 +0,0 @@
1
- import { r as inferLegacyTier } from "../_chunks/storage.mjs";
2
- function readOnly(name) {
3
- throw new Error(`http adapter is read-only: ${name} is not supported`);
4
- }
5
- function encodeKey(key) {
6
- return key.split("/").map(encodeURIComponent).join("/");
7
- }
8
- const TRAILING_SLASH = /\/$/;
9
- function createHttpDataSource(opts) {
10
- const base = opts.baseUrl.replace(TRAILING_SLASH, "");
11
- const sign = opts.signUrl ?? ((key) => `${base}/${encodeKey(key)}`);
12
- const useHttpfs = opts.useDuckDBHttpfs ?? true;
13
- async function readBytes(key, range, signal) {
14
- const url = sign(key);
15
- const headers = {};
16
- if (range) headers.Range = `bytes=${range.offset}-${range.offset + range.length - 1}`;
17
- const res = await fetch(url, {
18
- headers,
19
- signal
20
- });
21
- if (!res.ok) throw new Error(`http read failed ${res.status} ${res.statusText} for ${url}`);
22
- return new Uint8Array(await res.arrayBuffer());
23
- }
24
- return {
25
- read: readBytes,
26
- async write() {
27
- readOnly("write");
28
- },
29
- async delete() {
30
- readOnly("delete");
31
- },
32
- async list() {
33
- readOnly("list");
34
- },
35
- async head(key) {
36
- const res = await fetch(sign(key), { method: "HEAD" });
37
- if (!res.ok) return void 0;
38
- const len = res.headers.get("content-length");
39
- return len == null ? void 0 : { bytes: Number(len) };
40
- },
41
- uri(key) {
42
- return useHttpfs ? sign(key) : void 0;
43
- }
44
- };
45
- }
46
- function matchesFilter(entry, filter) {
47
- if (entry.userId !== filter.userId) return false;
48
- if (filter.siteId !== void 0 && entry.siteId !== filter.siteId) return false;
49
- if (filter.table !== void 0 && entry.table !== filter.table) return false;
50
- if (filter.partitions && !filter.partitions.includes(entry.partition)) return false;
51
- if (filter.tier !== void 0 && inferLegacyTier(entry) !== filter.tier) return false;
52
- return true;
53
- }
54
- function matchesWatermark(w, filter) {
55
- if (w.userId !== filter.userId) return false;
56
- if (filter.siteId !== void 0 && w.siteId !== filter.siteId) return false;
57
- if (filter.table !== void 0 && w.table !== filter.table) return false;
58
- return true;
59
- }
60
- function createHttpManifestStore(opts) {
61
- const fetchImpl = opts.fetchImpl ?? fetch;
62
- let cache = null;
63
- async function load() {
64
- if (!cache) cache = (async () => {
65
- const res = await fetchImpl(opts.manifestUrl);
66
- if (!res.ok) throw new Error(`manifest fetch failed ${res.status} ${res.statusText} for ${opts.manifestUrl}`);
67
- const parsed = await res.json();
68
- if (parsed.version !== 1) throw new Error(`unsupported manifest version ${parsed.version}`);
69
- return parsed;
70
- })();
71
- return cache;
72
- }
73
- return {
74
- async listLive(filter) {
75
- const { entries } = await load();
76
- return entries.filter((e) => e.retiredAt === void 0 && matchesFilter(e, filter));
77
- },
78
- async listAll(filter) {
79
- const { entries } = await load();
80
- return entries.filter((e) => matchesFilter(e, filter));
81
- },
82
- async getWatermarks(filter) {
83
- const { watermarks = [] } = await load();
84
- return watermarks.filter((w) => matchesWatermark(w, filter));
85
- },
86
- async getSyncStates(_filter) {
87
- return [];
88
- },
89
- async listRetired() {
90
- return [];
91
- },
92
- async registerVersion() {
93
- readOnly("registerVersion");
94
- },
95
- async registerVersions() {
96
- readOnly("registerVersions");
97
- },
98
- async delete() {
99
- readOnly("delete");
100
- },
101
- async bumpWatermark() {
102
- readOnly("bumpWatermark");
103
- },
104
- async setSyncState() {
105
- readOnly("setSyncState");
106
- },
107
- async withLock(_, fn) {
108
- return fn();
109
- },
110
- async purgeTenant() {
111
- readOnly("purgeTenant");
112
- }
113
- };
114
- }
115
- export { createHttpDataSource, createHttpManifestStore };
@@ -1,3 +0,0 @@
1
- import { InspectionSqlDriver } from "../entities.mjs";
2
- declare function createWaSqliteDriver(bytes: Uint8Array | undefined): Promise<InspectionSqlDriver>;
3
- export { createWaSqliteDriver };
@@ -1,42 +0,0 @@
1
- async function createWaSqliteDriver(bytes) {
2
- const [factoryMod, apiMod] = await Promise.all([import("wa-sqlite/dist/wa-sqlite.mjs"), import("wa-sqlite")]);
3
- const wasmModule = await factoryMod.default();
4
- const sqlite3 = apiMod.Factory(wasmModule);
5
- const db = await sqlite3.open_v2(":memory:");
6
- if (bytes && bytes.byteLength > 0) await sqlite3.deserialize(db, "main", bytes);
7
- async function runStatement(sql, params) {
8
- const prepared = await sqlite3.prepare_v2(db, sql);
9
- if (!prepared) return [];
10
- const { stmt } = prepared;
11
- const rows = [];
12
- sqlite3.bind_collection(stmt, params);
13
- let rc = await sqlite3.step(stmt);
14
- while (rc === sqlite3.SQLITE_ROW) {
15
- const colCount = sqlite3.column_count(stmt);
16
- const row = {};
17
- for (let i = 0; i < colCount; i++) row[sqlite3.column_name(stmt, i)] = sqlite3.column(stmt, i);
18
- rows.push(row);
19
- rc = await sqlite3.step(stmt);
20
- }
21
- await sqlite3.finalize(stmt);
22
- return rows;
23
- }
24
- return {
25
- async exec(sql) {
26
- await sqlite3.exec(db, sql);
27
- },
28
- async run(sql, params) {
29
- await runStatement(sql, params);
30
- },
31
- async all(sql, params) {
32
- return runStatement(sql, params);
33
- },
34
- async serialize() {
35
- return sqlite3.serialize(db, "main");
36
- },
37
- async close() {
38
- await sqlite3.close(db);
39
- }
40
- };
41
- }
42
- export { createWaSqliteDriver };
@@ -1,3 +0,0 @@
1
- import { InspectionSqlDriver } from "../entities.mjs";
2
- declare function createBetterSqliteDriver(bytes: Uint8Array | undefined): InspectionSqlDriver;
3
- export { createBetterSqliteDriver };
@@ -1,32 +0,0 @@
1
- import { createRequire } from "node:module";
2
- import process from "node:process";
3
- import { fileURLToPath } from "node:url";
4
- import { Buffer } from "node:buffer";
5
- const require_ = createRequire(typeof __filename !== "undefined" ? __filename : typeof import.meta !== "undefined" ? fileURLToPath(import.meta.url) : process.cwd());
6
- function loadBetterSqlite() {
7
- const mod = require_("better-sqlite3");
8
- return typeof mod === "function" ? mod : mod.default;
9
- }
10
- function createBetterSqliteDriver(bytes) {
11
- const Database = loadBetterSqlite();
12
- const db = bytes ? new Database(Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength)) : new Database(":memory:");
13
- return {
14
- exec(sql) {
15
- db.exec(sql);
16
- },
17
- run(sql, params) {
18
- db.prepare(sql).run(...params);
19
- },
20
- all(sql, params) {
21
- return db.prepare(sql).all(...params);
22
- },
23
- serialize() {
24
- const buf = db.serialize();
25
- return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
26
- },
27
- close() {
28
- db.close();
29
- }
30
- };
31
- }
32
- export { createBetterSqliteDriver };
@@ -1,31 +0,0 @@
1
- import { D as StorageEngine, N as TableName, a as DataSource, w as Row } from "../_chunks/storage.mjs";
2
- interface NodeHarnessOptions {
3
- dataDir: string;
4
- /** Tenant user id. Defaults to `'local'` for single-user CLI installs. */
5
- userId?: string;
6
- /** Name of the manifest file under `dataDir`. Defaults to `manifest.json`. */
7
- manifestFilename?: string;
8
- }
9
- interface NodeHarness {
10
- engine: StorageEngine;
11
- /**
12
- * Underlying filesystem-backed DataSource. Exposed so commands that write
13
- * derivative artifacts (rollups, exports) don't have to re-instantiate it.
14
- */
15
- dataSource: DataSource;
16
- dataDir: string;
17
- userId: string;
18
- siteIdFor: (siteUrl: string) => string;
19
- runRawSql: (opts: {
20
- sql: string;
21
- siteUrl: string;
22
- table: TableName;
23
- params?: unknown[];
24
- }) => Promise<{
25
- rows: Row[];
26
- sql: string;
27
- keys: string[];
28
- }>;
29
- }
30
- declare function createNodeHarness(opts: NodeHarnessOptions): NodeHarness;
31
- export { NodeHarness, NodeHarnessOptions, createNodeHarness };
@@ -1,45 +0,0 @@
1
- import { a as createDuckDBExecutor, i as createDuckDBCodec, n as createStorageEngine } from "../_chunks/engine.mjs";
2
- import { createNodeDuckDBHandle } from "./duckdb-node.mjs";
3
- import { createFilesystemDataSource, createFilesystemManifestStore } from "./filesystem.mjs";
4
- import path from "node:path";
5
- import { encodeSiteId } from "gscdump/tenant";
6
- function createNodeHarness(opts) {
7
- const dataDir = opts.dataDir;
8
- const userId = opts.userId ?? "local";
9
- const manifestFilename = opts.manifestFilename ?? "manifest.json";
10
- const handle = createNodeDuckDBHandle();
11
- const factory = { getDuckDB: async () => handle };
12
- const dataSource = createFilesystemDataSource({ rootDir: dataDir });
13
- const engine = createStorageEngine({
14
- dataSource,
15
- manifestStore: createFilesystemManifestStore({ path: path.join(dataDir, manifestFilename) }),
16
- codec: createDuckDBCodec(factory),
17
- executor: createDuckDBExecutor(factory)
18
- });
19
- async function runRawSql(runOpts) {
20
- const result = await engine.runSQL({
21
- ctx: {
22
- userId,
23
- siteId: encodeSiteId(runOpts.siteUrl)
24
- },
25
- table: runOpts.table,
26
- fileSets: { FILES: { table: runOpts.table } },
27
- sql: runOpts.sql,
28
- params: runOpts.params ?? []
29
- });
30
- return {
31
- rows: result.rows,
32
- sql: result.sql,
33
- keys: result.objectKeys
34
- };
35
- }
36
- return {
37
- engine,
38
- dataSource,
39
- dataDir,
40
- userId,
41
- siteIdFor: encodeSiteId,
42
- runRawSql
43
- };
44
- }
45
- export { createNodeHarness };
File without changes