@xnetjs/sqlite 0.0.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.
@@ -0,0 +1,176 @@
1
+ import {
2
+ SCHEMA_DDL_CORE,
3
+ SCHEMA_VERSION
4
+ } from "../chunk-HIREU5S5.js";
5
+
6
+ // src/adapters/memory.ts
7
+ var MemorySQLiteAdapter = class {
8
+ db = null;
9
+ opened = false;
10
+ inTransaction = false;
11
+ async open(_config) {
12
+ const initSqlJs = await import("sql.js").then((m) => m.default);
13
+ const SQL = await initSqlJs();
14
+ this.db = new SQL.Database();
15
+ this.opened = true;
16
+ this.db.run("PRAGMA foreign_keys = ON");
17
+ }
18
+ async close() {
19
+ if (this.db) {
20
+ this.db.close();
21
+ this.db = null;
22
+ }
23
+ this.opened = false;
24
+ }
25
+ isOpen() {
26
+ return this.opened;
27
+ }
28
+ async query(sql, params) {
29
+ this.ensureOpen();
30
+ try {
31
+ const stmt = this.db.prepare(sql);
32
+ if (params && params.length > 0) {
33
+ stmt.bind(params);
34
+ }
35
+ const rows = [];
36
+ while (stmt.step()) {
37
+ rows.push(stmt.getAsObject());
38
+ }
39
+ stmt.free();
40
+ return rows;
41
+ } catch (err) {
42
+ throw new Error(`Query failed: ${err.message}
43
+ SQL: ${sql}`);
44
+ }
45
+ }
46
+ async queryOne(sql, params) {
47
+ const rows = await this.query(sql, params);
48
+ return rows[0] ?? null;
49
+ }
50
+ async run(sql, params) {
51
+ this.ensureOpen();
52
+ try {
53
+ const stmt = this.db.prepare(sql);
54
+ if (params && params.length > 0) {
55
+ stmt.run(params);
56
+ } else {
57
+ stmt.run();
58
+ }
59
+ stmt.free();
60
+ const lastIdResult = this.db.exec("SELECT last_insert_rowid() as id");
61
+ const lastId = lastIdResult.length > 0 && lastIdResult[0].values.length > 0 ? BigInt(lastIdResult[0].values[0][0]) : BigInt(0);
62
+ return {
63
+ changes: this.db.getRowsModified(),
64
+ lastInsertRowid: lastId
65
+ };
66
+ } catch (err) {
67
+ throw new Error(`Run failed: ${err.message}
68
+ SQL: ${sql}`);
69
+ }
70
+ }
71
+ async exec(sql) {
72
+ this.ensureOpen();
73
+ try {
74
+ this.db.run(sql);
75
+ } catch (err) {
76
+ throw new Error(`Exec failed: ${err.message}
77
+ SQL: ${sql}`);
78
+ }
79
+ }
80
+ async transaction(fn) {
81
+ await this.beginTransaction();
82
+ try {
83
+ const result = await fn();
84
+ await this.commit();
85
+ return result;
86
+ } catch (err) {
87
+ await this.rollback();
88
+ throw err;
89
+ }
90
+ }
91
+ async beginTransaction() {
92
+ if (this.inTransaction) {
93
+ throw new Error("Transaction already in progress");
94
+ }
95
+ await this.exec("BEGIN TRANSACTION");
96
+ this.inTransaction = true;
97
+ }
98
+ async commit() {
99
+ if (!this.inTransaction) {
100
+ throw new Error("No transaction in progress");
101
+ }
102
+ await this.exec("COMMIT");
103
+ this.inTransaction = false;
104
+ }
105
+ async rollback() {
106
+ if (!this.inTransaction) {
107
+ throw new Error("No transaction in progress");
108
+ }
109
+ await this.exec("ROLLBACK");
110
+ this.inTransaction = false;
111
+ }
112
+ async prepare(sql) {
113
+ this.ensureOpen();
114
+ return {
115
+ query: async (params) => this.query(sql, params),
116
+ queryOne: async (params) => this.queryOne(sql, params),
117
+ run: async (params) => this.run(sql, params),
118
+ finalize: async () => {
119
+ }
120
+ };
121
+ }
122
+ async getSchemaVersion() {
123
+ try {
124
+ const row = await this.queryOne(
125
+ "SELECT version FROM _schema_version ORDER BY version DESC LIMIT 1"
126
+ );
127
+ return row?.version ?? 0;
128
+ } catch {
129
+ return 0;
130
+ }
131
+ }
132
+ async setSchemaVersion(version) {
133
+ await this.run("INSERT INTO _schema_version (version, applied_at) VALUES (?, ?)", [
134
+ version,
135
+ Date.now()
136
+ ]);
137
+ }
138
+ async applySchema(version, sql) {
139
+ const currentVersion = await this.getSchemaVersion();
140
+ if (currentVersion >= version) {
141
+ return false;
142
+ }
143
+ await this.transaction(async () => {
144
+ await this.exec(sql);
145
+ await this.setSchemaVersion(version);
146
+ });
147
+ return true;
148
+ }
149
+ async getDatabaseSize() {
150
+ return 0;
151
+ }
152
+ async vacuum() {
153
+ await this.exec("VACUUM");
154
+ }
155
+ async checkpoint() {
156
+ return 0;
157
+ }
158
+ getStorageMode() {
159
+ return "memory";
160
+ }
161
+ ensureOpen() {
162
+ if (!this.opened || !this.db) {
163
+ throw new Error("Database not open. Call open() first.");
164
+ }
165
+ }
166
+ };
167
+ async function createMemorySQLiteAdapter() {
168
+ const adapter = new MemorySQLiteAdapter();
169
+ await adapter.open({ path: ":memory:" });
170
+ await adapter.applySchema(SCHEMA_VERSION, SCHEMA_DDL_CORE);
171
+ return adapter;
172
+ }
173
+ export {
174
+ MemorySQLiteAdapter,
175
+ createMemorySQLiteAdapter
176
+ };
@@ -0,0 +1,75 @@
1
+ import { S as SQLiteAdapter, P as PreparedStatement } from '../adapter-I7yAV6iu.js';
2
+ import { b as SQLiteConfig, a as SQLRow, S as SQLValue, R as RunResult } from '../types-C_aHfRDF.js';
3
+
4
+ /**
5
+ * @xnetjs/sqlite - Main thread proxy for SQLite Web Worker
6
+ *
7
+ * This provides a SQLiteAdapter-compatible interface that communicates
8
+ * with the SQLite worker via postMessage/Comlink.
9
+ */
10
+
11
+ /**
12
+ * SQLite proxy for the main thread.
13
+ *
14
+ * This wraps the Web Worker and provides the SQLiteAdapter interface
15
+ * for use in the main thread React components.
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * const proxy = await createWebSQLiteProxy({ path: '/xnet.db' })
20
+ * const nodes = await proxy.query('SELECT * FROM nodes')
21
+ * ```
22
+ */
23
+ declare class WebSQLiteProxy implements SQLiteAdapter {
24
+ private worker;
25
+ private proxy;
26
+ private _config;
27
+ open(config: SQLiteConfig): Promise<void>;
28
+ close(): Promise<void>;
29
+ isOpen(): boolean;
30
+ query<T extends SQLRow = SQLRow>(sql: string, params?: SQLValue[]): Promise<T[]>;
31
+ queryOne<T extends SQLRow = SQLRow>(sql: string, params?: SQLValue[]): Promise<T | null>;
32
+ run(sql: string, params?: SQLValue[]): Promise<RunResult>;
33
+ exec(sql: string): Promise<void>;
34
+ transaction<T>(_fn: () => Promise<T>): Promise<T>;
35
+ /**
36
+ * Execute multiple operations in a single transaction.
37
+ * This is the recommended way to do transactions across the worker boundary.
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * await proxy.transactionBatch([
42
+ * { sql: 'INSERT INTO nodes ...', params: [...] },
43
+ * { sql: 'UPDATE nodes ...', params: [...] }
44
+ * ])
45
+ * ```
46
+ */
47
+ transactionBatch(operations: Array<{
48
+ sql: string;
49
+ params?: SQLValue[];
50
+ }>): Promise<void>;
51
+ beginTransaction(): Promise<void>;
52
+ commit(): Promise<void>;
53
+ rollback(): Promise<void>;
54
+ prepare(_sql: string): Promise<PreparedStatement>;
55
+ getSchemaVersion(): Promise<number>;
56
+ setSchemaVersion(version: number): Promise<void>;
57
+ applySchema(version: number, sql: string): Promise<boolean>;
58
+ getDatabaseSize(): Promise<number>;
59
+ vacuum(): Promise<void>;
60
+ checkpoint(): Promise<number>;
61
+ getStorageMode(): Promise<'opfs' | 'memory'>;
62
+ }
63
+ /**
64
+ * Create a WebSQLiteProxy ready for use.
65
+ *
66
+ * @example
67
+ * ```typescript
68
+ * const db = await createWebSQLiteProxy({ path: '/xnet.db' })
69
+ * const nodes = await db.query('SELECT * FROM nodes')
70
+ * await db.close()
71
+ * ```
72
+ */
73
+ declare function createWebSQLiteProxy(config: SQLiteConfig): Promise<WebSQLiteProxy>;
74
+
75
+ export { WebSQLiteProxy, createWebSQLiteProxy };
@@ -0,0 +1,154 @@
1
+ // src/adapters/web-proxy.ts
2
+ import * as Comlink from "comlink";
3
+ function isDebugEnabled() {
4
+ return typeof localStorage !== "undefined" && localStorage.getItem("xnet:sqlite:debug") === "true";
5
+ }
6
+ function log(...args) {
7
+ if (isDebugEnabled()) {
8
+ console.log(...args);
9
+ }
10
+ }
11
+ var WebSQLiteProxy = class {
12
+ worker = null;
13
+ proxy = null;
14
+ _config = null;
15
+ async open(config) {
16
+ if (this.worker) {
17
+ throw new Error("Already open. Call close() first.");
18
+ }
19
+ log("[WebSQLiteProxy] Creating worker...");
20
+ this.worker = new Worker(new URL("./web-worker.js", import.meta.url), { type: "module" });
21
+ this.worker.onerror = (event) => {
22
+ console.error("[WebSQLiteProxy] Worker error:", event);
23
+ };
24
+ this.worker.onmessageerror = (event) => {
25
+ console.error("[WebSQLiteProxy] Worker message error:", event);
26
+ };
27
+ log("[WebSQLiteProxy] Worker created, wrapping with Comlink...");
28
+ this.proxy = Comlink.wrap(this.worker);
29
+ log("[WebSQLiteProxy] Calling proxy.open()...");
30
+ const openPromise = this.proxy.open(config);
31
+ const timeoutPromise = new Promise(
32
+ (_, reject) => setTimeout(() => reject(new Error("Worker initialization timeout after 15s")), 15e3)
33
+ );
34
+ await Promise.race([openPromise, timeoutPromise]);
35
+ log("[WebSQLiteProxy] proxy.open() completed");
36
+ this._config = config;
37
+ }
38
+ async close() {
39
+ if (this.proxy) {
40
+ await this.proxy.close();
41
+ this.proxy = null;
42
+ }
43
+ if (this.worker) {
44
+ this.worker.terminate();
45
+ this.worker = null;
46
+ }
47
+ this._config = null;
48
+ }
49
+ isOpen() {
50
+ return this.proxy !== null;
51
+ }
52
+ async query(sql, params) {
53
+ if (!this.proxy) throw new Error("Database not open");
54
+ const result = await this.proxy.query(sql, params);
55
+ return result;
56
+ }
57
+ async queryOne(sql, params) {
58
+ if (!this.proxy) throw new Error("Database not open");
59
+ const result = await this.proxy.queryOne(sql, params);
60
+ return result;
61
+ }
62
+ async run(sql, params) {
63
+ if (!this.proxy) throw new Error("Database not open");
64
+ return this.proxy.run(sql, params);
65
+ }
66
+ async exec(sql) {
67
+ if (!this.proxy) throw new Error("Database not open");
68
+ return this.proxy.exec(sql);
69
+ }
70
+ async transaction(_fn) {
71
+ throw new Error("Complex transactions not supported in proxy. Use transactionBatch() instead.");
72
+ }
73
+ /**
74
+ * Execute multiple operations in a single transaction.
75
+ * This is the recommended way to do transactions across the worker boundary.
76
+ *
77
+ * @example
78
+ * ```typescript
79
+ * await proxy.transactionBatch([
80
+ * { sql: 'INSERT INTO nodes ...', params: [...] },
81
+ * { sql: 'UPDATE nodes ...', params: [...] }
82
+ * ])
83
+ * ```
84
+ */
85
+ async transactionBatch(operations) {
86
+ if (!this.proxy) throw new Error("Database not open");
87
+ await this.proxy.transaction(operations);
88
+ }
89
+ async beginTransaction() {
90
+ if (!this.proxy) throw new Error("Database not open");
91
+ await this.proxy.exec("BEGIN IMMEDIATE");
92
+ }
93
+ async commit() {
94
+ if (!this.proxy) throw new Error("Database not open");
95
+ await this.proxy.exec("COMMIT");
96
+ }
97
+ async rollback() {
98
+ if (!this.proxy) throw new Error("Database not open");
99
+ await this.proxy.exec("ROLLBACK");
100
+ }
101
+ async prepare(_sql) {
102
+ throw new Error("Prepared statements not supported in proxy. Use query() or run() directly.");
103
+ }
104
+ async getSchemaVersion() {
105
+ if (!this.proxy) throw new Error("Database not open");
106
+ return this.proxy.getSchemaVersion();
107
+ }
108
+ async setSchemaVersion(version) {
109
+ if (!this.proxy) throw new Error("Database not open");
110
+ await this.proxy.run("INSERT INTO _schema_version (version, applied_at) VALUES (?, ?)", [
111
+ version,
112
+ Date.now()
113
+ ]);
114
+ }
115
+ async applySchema(version, sql) {
116
+ const currentVersion = await this.getSchemaVersion();
117
+ if (currentVersion >= version) return false;
118
+ await this.exec(sql);
119
+ await this.setSchemaVersion(version);
120
+ return true;
121
+ }
122
+ async getDatabaseSize() {
123
+ if (!this.proxy) throw new Error("Database not open");
124
+ return this.proxy.getDatabaseSize();
125
+ }
126
+ async vacuum() {
127
+ if (!this.proxy) throw new Error("Database not open");
128
+ return this.proxy.vacuum();
129
+ }
130
+ async checkpoint() {
131
+ return 0;
132
+ }
133
+ async getStorageMode() {
134
+ if (!this.proxy) throw new Error("Database not open");
135
+ try {
136
+ log("[WebSQLiteProxy] Calling proxy.getStorageMode()...");
137
+ const mode = await this.proxy.getStorageMode();
138
+ log("[WebSQLiteProxy] getStorageMode() returned:", mode);
139
+ return mode;
140
+ } catch (err) {
141
+ console.error("[WebSQLiteProxy] getStorageMode() failed:", err);
142
+ throw err;
143
+ }
144
+ }
145
+ };
146
+ async function createWebSQLiteProxy(config) {
147
+ const proxy = new WebSQLiteProxy();
148
+ await proxy.open(config);
149
+ return proxy;
150
+ }
151
+ export {
152
+ WebSQLiteProxy,
153
+ createWebSQLiteProxy
154
+ };
@@ -0,0 +1,32 @@
1
+ import { b as SQLiteConfig, a as SQLRow, S as SQLValue, R as RunResult } from '../types-C_aHfRDF.js';
2
+
3
+ /**
4
+ * @xnetjs/sqlite - Web Worker entry point for SQLite WASM
5
+ *
6
+ * This file runs in a Web Worker and handles all SQLite operations.
7
+ * The main thread communicates with it via postMessage/Comlink.
8
+ */
9
+
10
+ /**
11
+ * SQLite worker handler that wraps the adapter for message-based communication.
12
+ */
13
+ declare class SQLiteWorkerHandler {
14
+ private adapter;
15
+ open(config: SQLiteConfig): Promise<void>;
16
+ close(): Promise<void>;
17
+ isOpen(): boolean;
18
+ query<T extends SQLRow = SQLRow>(sql: string, params?: SQLValue[]): Promise<T[]>;
19
+ queryOne<T extends SQLRow = SQLRow>(sql: string, params?: SQLValue[]): Promise<T | null>;
20
+ run(sql: string, params?: SQLValue[]): Promise<RunResult>;
21
+ exec(sql: string): Promise<void>;
22
+ transaction(operations: Array<{
23
+ sql: string;
24
+ params?: SQLValue[];
25
+ }>): Promise<void>;
26
+ getSchemaVersion(): Promise<number>;
27
+ vacuum(): Promise<void>;
28
+ getDatabaseSize(): Promise<number>;
29
+ getStorageMode(): Promise<'opfs' | 'memory'>;
30
+ }
31
+
32
+ export { SQLiteWorkerHandler };
@@ -0,0 +1,81 @@
1
+ import {
2
+ createWebSQLiteAdapter
3
+ } from "../chunk-BXYZU3OL.js";
4
+ import "../chunk-HIREU5S5.js";
5
+
6
+ // src/adapters/web-worker.ts
7
+ import * as Comlink from "comlink";
8
+ function isDebugEnabled() {
9
+ return typeof self !== "undefined" && typeof localStorage !== "undefined" && localStorage.getItem("xnet:sqlite:debug") === "true";
10
+ }
11
+ function log(...args) {
12
+ if (isDebugEnabled()) {
13
+ console.log(...args);
14
+ }
15
+ }
16
+ log("[SQLiteWorker] Worker script loaded, Comlink imported");
17
+ var SQLiteWorkerHandler = class {
18
+ adapter = null;
19
+ async open(config) {
20
+ log("[SQLiteWorkerHandler] open() called with config:", config);
21
+ if (this.adapter) {
22
+ throw new Error("Database already open");
23
+ }
24
+ this.adapter = await createWebSQLiteAdapter(config);
25
+ log("[SQLiteWorkerHandler] open() completed");
26
+ }
27
+ async close() {
28
+ if (this.adapter) {
29
+ await this.adapter.close();
30
+ this.adapter = null;
31
+ }
32
+ }
33
+ isOpen() {
34
+ return this.adapter?.isOpen() ?? false;
35
+ }
36
+ async query(sql, params) {
37
+ if (!this.adapter) throw new Error("Database not open");
38
+ return this.adapter.query(sql, params);
39
+ }
40
+ async queryOne(sql, params) {
41
+ if (!this.adapter) throw new Error("Database not open");
42
+ return this.adapter.queryOne(sql, params);
43
+ }
44
+ async run(sql, params) {
45
+ if (!this.adapter) throw new Error("Database not open");
46
+ return this.adapter.run(sql, params);
47
+ }
48
+ async exec(sql) {
49
+ if (!this.adapter) throw new Error("Database not open");
50
+ return this.adapter.exec(sql);
51
+ }
52
+ async transaction(operations) {
53
+ if (!this.adapter) throw new Error("Database not open");
54
+ await this.adapter.transaction(async () => {
55
+ for (const op of operations) {
56
+ await this.adapter.run(op.sql, op.params);
57
+ }
58
+ });
59
+ }
60
+ async getSchemaVersion() {
61
+ if (!this.adapter) throw new Error("Database not open");
62
+ return this.adapter.getSchemaVersion();
63
+ }
64
+ async vacuum() {
65
+ if (!this.adapter) throw new Error("Database not open");
66
+ return this.adapter.vacuum();
67
+ }
68
+ async getDatabaseSize() {
69
+ if (!this.adapter) throw new Error("Database not open");
70
+ return this.adapter.getDatabaseSize();
71
+ }
72
+ async getStorageMode() {
73
+ if (!this.adapter) throw new Error("Database not open");
74
+ return this.adapter.getStorageMode();
75
+ }
76
+ };
77
+ var handler = new SQLiteWorkerHandler();
78
+ log("[SQLiteWorker] Handler instance created");
79
+ log("[SQLiteWorker] Exposing handler via Comlink...");
80
+ Comlink.expose(handler);
81
+ log("[SQLiteWorker] Handler exposed - worker ready!");
@@ -0,0 +1,64 @@
1
+ import { S as SQLiteAdapter, P as PreparedStatement } from '../adapter-I7yAV6iu.js';
2
+ import { b as SQLiteConfig, a as SQLRow, S as SQLValue, R as RunResult } from '../types-C_aHfRDF.js';
3
+
4
+ /**
5
+ * @xnetjs/sqlite - Web SQLite adapter using @sqlite.org/sqlite-wasm
6
+ *
7
+ * Uses the official SQLite WASM package with OPFS for browser-based persistence.
8
+ * Must run in a Web Worker for OPFS access.
9
+ */
10
+
11
+ /**
12
+ * SQLite adapter for web browsers using @sqlite.org/sqlite-wasm.
13
+ *
14
+ * Uses the opfs-sahpool VFS for OPFS persistence which:
15
+ * - Works in Safari 16.4+ (unlike the opfs VFS which needs 17+)
16
+ * - Doesn't require COOP/COEP headers
17
+ * - Provides best performance
18
+ *
19
+ * Must run in a Web Worker for OPFS access.
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * // In a Web Worker
24
+ * const adapter = new WebSQLiteAdapter()
25
+ * await adapter.open({ path: '/xnet.db' })
26
+ *
27
+ * const nodes = await adapter.query('SELECT * FROM nodes')
28
+ * ```
29
+ */
30
+ declare class WebSQLiteAdapter implements SQLiteAdapter {
31
+ private sqlite3;
32
+ private db;
33
+ private poolUtil;
34
+ private _config;
35
+ private inTransaction;
36
+ private storageMode;
37
+ open(config: SQLiteConfig): Promise<void>;
38
+ close(): Promise<void>;
39
+ isOpen(): boolean;
40
+ getStorageMode(): 'opfs' | 'memory';
41
+ query<T extends SQLRow = SQLRow>(sql: string, params?: SQLValue[]): Promise<T[]>;
42
+ queryOne<T extends SQLRow = SQLRow>(sql: string, params?: SQLValue[]): Promise<T | null>;
43
+ run(sql: string, params?: SQLValue[]): Promise<RunResult>;
44
+ exec(sql: string): Promise<void>;
45
+ private execSync;
46
+ transaction<T>(fn: () => Promise<T>): Promise<T>;
47
+ beginTransaction(): Promise<void>;
48
+ commit(): Promise<void>;
49
+ rollback(): Promise<void>;
50
+ prepare(sql: string): Promise<PreparedStatement>;
51
+ getSchemaVersion(): Promise<number>;
52
+ setSchemaVersion(version: number): Promise<void>;
53
+ applySchema(version: number, sql: string): Promise<boolean>;
54
+ getDatabaseSize(): Promise<number>;
55
+ vacuum(): Promise<void>;
56
+ checkpoint(): Promise<number>;
57
+ private ensureOpen;
58
+ }
59
+ /**
60
+ * Create a WebSQLiteAdapter with schema applied.
61
+ */
62
+ declare function createWebSQLiteAdapter(config: SQLiteConfig): Promise<WebSQLiteAdapter>;
63
+
64
+ export { WebSQLiteAdapter, createWebSQLiteAdapter };
@@ -0,0 +1,9 @@
1
+ import {
2
+ WebSQLiteAdapter,
3
+ createWebSQLiteAdapter
4
+ } from "../chunk-BXYZU3OL.js";
5
+ import "../chunk-HIREU5S5.js";
6
+ export {
7
+ WebSQLiteAdapter,
8
+ createWebSQLiteAdapter
9
+ };
@@ -0,0 +1,67 @@
1
+ /**
2
+ * @xnetjs/sqlite - Browser support detection for OPFS-based SQLite
3
+ */
4
+ /**
5
+ * Result of browser support check.
6
+ */
7
+ interface BrowserSupport {
8
+ /** OPFS is available */
9
+ opfs: boolean;
10
+ /** Web Workers are available */
11
+ worker: boolean;
12
+ /** Browser is fully supported for SQLite-WASM with OPFS */
13
+ supported: boolean;
14
+ /** Reason for lack of support (if not supported) */
15
+ reason?: string;
16
+ /** Warning message for soft failures (app can still work with fallback) */
17
+ warning?: string;
18
+ }
19
+ /**
20
+ * Check if the current browser supports SQLite-WASM with OPFS.
21
+ *
22
+ * Requirements:
23
+ * - Web Workers (for running SQLite off the main thread)
24
+ * - Origin Private File System (OPFS) for persistent storage
25
+ *
26
+ * Supported browsers:
27
+ * - Chrome 102+ (March 2022)
28
+ * - Edge 102+ (March 2022)
29
+ * - Firefox 111+ (March 2023)
30
+ * - Safari 16.4+ (March 2023)
31
+ *
32
+ * Note: If OPFS test fails but APIs exist, we allow the app to proceed
33
+ * with a warning. The worker will fall back to in-memory mode if needed.
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * const support = await checkBrowserSupport()
38
+ * if (!support.supported) {
39
+ * showUnsupportedBrowserMessage(support.reason!)
40
+ * return
41
+ * }
42
+ * if (support.warning) {
43
+ * showWarningBanner(support.warning)
44
+ * }
45
+ * // Proceed with SQLite initialization
46
+ * ```
47
+ */
48
+ declare function checkBrowserSupport(): Promise<BrowserSupport>;
49
+ /**
50
+ * Show an unsupported browser message to the user.
51
+ *
52
+ * This replaces the app content with a helpful message explaining
53
+ * that the browser is not supported and suggesting alternatives.
54
+ *
55
+ * @param reason - The reason for lack of support
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * const support = await checkBrowserSupport()
60
+ * if (!support.supported) {
61
+ * showUnsupportedBrowserMessage(support.reason!)
62
+ * }
63
+ * ```
64
+ */
65
+ declare function showUnsupportedBrowserMessage(reason: string): void;
66
+
67
+ export { type BrowserSupport, checkBrowserSupport, showUnsupportedBrowserMessage };
@@ -0,0 +1,8 @@
1
+ import {
2
+ checkBrowserSupport,
3
+ showUnsupportedBrowserMessage
4
+ } from "./chunk-ZRR5D2OD.js";
5
+ export {
6
+ checkBrowserSupport,
7
+ showUnsupportedBrowserMessage
8
+ };