@xnetjs/sqlite 0.0.2 → 0.0.3

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,4 +1,4 @@
1
- import { b as SQLiteConfig, a as SQLRow, S as SQLValue, R as RunResult } from './types-C_aHfRDF.js';
1
+ import { b as SQLiteConfig, a as SQLRow, S as SQLValue, R as RunResult, k as SQLiteNodeBatchApplyInput, l as SQLiteNodeBatchApplyResult, d as SQLiteOperationStats } from './types-DMrj3K4o.js';
2
2
 
3
3
  /**
4
4
  * @xnetjs/sqlite - SQLite adapter interface definitions
@@ -81,6 +81,24 @@ interface SQLiteAdapter {
81
81
  * })
82
82
  */
83
83
  transaction<T>(fn: () => Promise<T>): Promise<T>;
84
+ /**
85
+ * Execute a list of SQL statements inside one transaction.
86
+ *
87
+ * This is primarily for proxy/worker-backed adapters where a callback
88
+ * transaction would cross a serialization boundary. Implementations should
89
+ * execute all operations atomically and roll back on the first failure.
90
+ */
91
+ transactionBatch?(operations: Array<{
92
+ sql: string;
93
+ params?: SQLValue[];
94
+ }>): Promise<void>;
95
+ /**
96
+ * Execute a node-store batch using compact typed row payloads.
97
+ *
98
+ * Worker-backed adapters can use this to avoid transferring a very large
99
+ * array of repeated SQL strings over Comlink.
100
+ */
101
+ applyNodeBatch?(input: SQLiteNodeBatchApplyInput): Promise<SQLiteNodeBatchApplyResult>;
84
102
  /**
85
103
  * Begin a manual transaction.
86
104
  * Must be followed by commit() or rollback().
@@ -140,6 +158,14 @@ interface SQLiteAdapter {
140
158
  * or 'memory' if using in-memory fallback.
141
159
  */
142
160
  getStorageMode(): Promise<'opfs' | 'memory'> | 'opfs' | 'memory';
161
+ /**
162
+ * Optional cumulative operation counters for import diagnostics.
163
+ */
164
+ getOperationStats?(): Promise<SQLiteOperationStats> | SQLiteOperationStats;
165
+ /**
166
+ * Reset cumulative operation counters when starting a focused measurement.
167
+ */
168
+ resetOperationStats?(): Promise<void> | void;
143
169
  }
144
170
  /**
145
171
  * Prepared statement for repeated execution.
@@ -1,7 +1,7 @@
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';
1
+ import { S as SQLiteAdapter, P as PreparedStatement } from '../adapter-t2aqQ__n.js';
2
+ import { b as SQLiteConfig, a as SQLRow, S as SQLValue, R as RunResult } from '../types-DMrj3K4o.js';
3
3
  import Database from 'better-sqlite3';
4
- export { a as SCHEMA_DDL, S as SCHEMA_VERSION } from '../schema-CjkXTqxn.js';
4
+ export { a as SCHEMA_DDL, S as SCHEMA_VERSION } from '../schema-BEgIA-rZ.js';
5
5
 
6
6
  /**
7
7
  * @xnetjs/sqlite - Electron SQLite adapter using better-sqlite3
@@ -37,6 +37,10 @@ declare class ElectronSQLiteAdapter implements SQLiteAdapter {
37
37
  run(sql: string, params?: SQLValue[]): Promise<RunResult>;
38
38
  exec(sql: string): Promise<void>;
39
39
  transaction<T>(fn: () => Promise<T>): Promise<T>;
40
+ transactionBatch(operations: Array<{
41
+ sql: string;
42
+ params?: SQLValue[];
43
+ }>): Promise<void>;
40
44
  /**
41
45
  * Synchronous transaction for performance-critical batch operations.
42
46
  * Prefer this over async transaction when the body is synchronous.
@@ -1,7 +1,10 @@
1
+ import {
2
+ isSQLiteCorruptionError
3
+ } from "../chunk-CBU263LI.js";
1
4
  import {
2
5
  SCHEMA_DDL,
3
6
  SCHEMA_VERSION
4
- } from "../chunk-HIREU5S5.js";
7
+ } from "../chunk-NVD7G7DZ.js";
5
8
 
6
9
  // src/adapters/electron.ts
7
10
  var DatabaseConstructor = null;
@@ -104,10 +107,41 @@ var ElectronSQLiteAdapter = class {
104
107
  await this.commit();
105
108
  return result;
106
109
  } catch (err) {
107
- await this.rollback();
110
+ if (this.inTransaction) {
111
+ try {
112
+ await this.rollback();
113
+ } catch (rollbackErr) {
114
+ if (isSQLiteCorruptionError(rollbackErr) && !isSQLiteCorruptionError(err)) {
115
+ throw rollbackErr;
116
+ }
117
+ }
118
+ }
108
119
  throw err;
109
120
  }
110
121
  }
122
+ async transactionBatch(operations) {
123
+ this.ensureOpen();
124
+ if (operations.length === 0) return;
125
+ if (this.inTransaction) {
126
+ throw new Error("Transaction already in progress");
127
+ }
128
+ let currentSql = operations[0].sql;
129
+ try {
130
+ this.transactionSync(() => {
131
+ for (const operation of operations) {
132
+ currentSql = operation.sql;
133
+ const stmt = this.getOrPrepare(operation.sql);
134
+ if (operation.params) {
135
+ stmt.run(...operation.params);
136
+ } else {
137
+ stmt.run();
138
+ }
139
+ }
140
+ });
141
+ } catch (err) {
142
+ throw this.wrapError(err, currentSql);
143
+ }
144
+ }
111
145
  /**
112
146
  * Synchronous transaction for performance-critical batch operations.
113
147
  * Prefer this over async transaction when the body is synchronous.
@@ -128,15 +162,25 @@ var ElectronSQLiteAdapter = class {
128
162
  if (!this.inTransaction) {
129
163
  throw new Error("No transaction in progress");
130
164
  }
131
- this.db.exec("COMMIT");
132
- this.inTransaction = false;
165
+ try {
166
+ this.db.exec("COMMIT");
167
+ this.inTransaction = false;
168
+ } catch (err) {
169
+ if (isSQLiteCorruptionError(err)) {
170
+ this.inTransaction = false;
171
+ }
172
+ throw err;
173
+ }
133
174
  }
134
175
  async rollback() {
135
176
  if (!this.inTransaction) {
136
177
  return;
137
178
  }
138
- this.db.exec("ROLLBACK");
139
- this.inTransaction = false;
179
+ try {
180
+ this.db.exec("ROLLBACK");
181
+ } finally {
182
+ this.inTransaction = false;
183
+ }
140
184
  }
141
185
  async prepare(sql) {
142
186
  this.ensureOpen();
@@ -1,5 +1,5 @@
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';
1
+ import { S as SQLiteAdapter, P as PreparedStatement } from '../adapter-t2aqQ__n.js';
2
+ import { b as SQLiteConfig, a as SQLRow, S as SQLValue, R as RunResult } from '../types-DMrj3K4o.js';
3
3
 
4
4
  /**
5
5
  * @xnetjs/sqlite - Expo SQLite adapter using expo-sqlite
@@ -1,7 +1,10 @@
1
+ import {
2
+ isSQLiteCorruptionError
3
+ } from "../chunk-CBU263LI.js";
1
4
  import {
2
5
  SCHEMA_DDL,
3
6
  SCHEMA_VERSION
4
- } from "../chunk-HIREU5S5.js";
7
+ } from "../chunk-NVD7G7DZ.js";
5
8
 
6
9
  // src/adapters/expo.ts
7
10
  var ExpoSQLiteAdapter = class {
@@ -69,7 +72,15 @@ var ExpoSQLiteAdapter = class {
69
72
  await this.commit();
70
73
  return result;
71
74
  } catch (err) {
72
- await this.rollback();
75
+ if (this.inTransaction) {
76
+ try {
77
+ await this.rollback();
78
+ } catch (rollbackErr) {
79
+ if (isSQLiteCorruptionError(rollbackErr) && !isSQLiteCorruptionError(err)) {
80
+ throw rollbackErr;
81
+ }
82
+ }
83
+ }
73
84
  throw err;
74
85
  }
75
86
  }
@@ -84,15 +95,25 @@ var ExpoSQLiteAdapter = class {
84
95
  if (!this.inTransaction) {
85
96
  throw new Error("No transaction in progress");
86
97
  }
87
- await this.exec("COMMIT");
88
- this.inTransaction = false;
98
+ try {
99
+ await this.exec("COMMIT");
100
+ this.inTransaction = false;
101
+ } catch (err) {
102
+ if (isSQLiteCorruptionError(err)) {
103
+ this.inTransaction = false;
104
+ }
105
+ throw err;
106
+ }
89
107
  }
90
108
  async rollback() {
91
109
  if (!this.inTransaction) {
92
110
  return;
93
111
  }
94
- await this.exec("ROLLBACK");
95
- this.inTransaction = false;
112
+ try {
113
+ await this.exec("ROLLBACK");
114
+ } finally {
115
+ this.inTransaction = false;
116
+ }
96
117
  }
97
118
  async prepare(sql) {
98
119
  this.ensureOpen();
@@ -1,5 +1,5 @@
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';
1
+ import { S as SQLiteAdapter, P as PreparedStatement } from '../adapter-t2aqQ__n.js';
2
+ import { b as SQLiteConfig, a as SQLRow, S as SQLValue, R as RunResult } from '../types-DMrj3K4o.js';
3
3
 
4
4
  /**
5
5
  * @xnetjs/sqlite - In-memory SQLite adapter for testing
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  SCHEMA_DDL_CORE,
3
3
  SCHEMA_VERSION
4
- } from "../chunk-HIREU5S5.js";
4
+ } from "../chunk-NVD7G7DZ.js";
5
5
 
6
6
  // src/adapters/memory.ts
7
7
  var MemorySQLiteAdapter = class {
@@ -1,5 +1,5 @@
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';
1
+ import { S as SQLiteAdapter, P as PreparedStatement } from '../adapter-t2aqQ__n.js';
2
+ import { b as SQLiteConfig, a as SQLRow, S as SQLValue, R as RunResult, k as SQLiteNodeBatchApplyInput, l as SQLiteNodeBatchApplyResult, d as SQLiteOperationStats } from '../types-DMrj3K4o.js';
3
3
 
4
4
  /**
5
5
  * @xnetjs/sqlite - Main thread proxy for SQLite Web Worker
@@ -24,7 +24,11 @@ declare class WebSQLiteProxy implements SQLiteAdapter {
24
24
  private worker;
25
25
  private proxy;
26
26
  private _config;
27
+ private inTransaction;
28
+ private operationStats;
29
+ private createWorkerProxy;
27
30
  open(config: SQLiteConfig): Promise<void>;
31
+ resetStorage(config: SQLiteConfig): Promise<void>;
28
32
  close(): Promise<void>;
29
33
  isOpen(): boolean;
30
34
  query<T extends SQLRow = SQLRow>(sql: string, params?: SQLValue[]): Promise<T[]>;
@@ -48,6 +52,7 @@ declare class WebSQLiteProxy implements SQLiteAdapter {
48
52
  sql: string;
49
53
  params?: SQLValue[];
50
54
  }>): Promise<void>;
55
+ applyNodeBatch(input: SQLiteNodeBatchApplyInput): Promise<SQLiteNodeBatchApplyResult>;
51
56
  beginTransaction(): Promise<void>;
52
57
  commit(): Promise<void>;
53
58
  rollback(): Promise<void>;
@@ -59,6 +64,16 @@ declare class WebSQLiteProxy implements SQLiteAdapter {
59
64
  vacuum(): Promise<void>;
60
65
  checkpoint(): Promise<number>;
61
66
  getStorageMode(): Promise<'opfs' | 'memory'>;
67
+ /**
68
+ * Create a MessagePort connected directly to the SQLite worker.
69
+ *
70
+ * The returned port speaks the same Comlink `SQLiteWorkerHandler`
71
+ * protocol as this proxy and can be transferred to another worker
72
+ * (e.g. the data worker) so its storage calls skip the main thread.
73
+ */
74
+ createMessagePort(): Promise<MessagePort>;
75
+ getOperationStats(): SQLiteOperationStats;
76
+ resetOperationStats(): void;
62
77
  }
63
78
  /**
64
79
  * Create a WebSQLiteProxy ready for use.
@@ -71,5 +86,6 @@ declare class WebSQLiteProxy implements SQLiteAdapter {
71
86
  * ```
72
87
  */
73
88
  declare function createWebSQLiteProxy(config: SQLiteConfig): Promise<WebSQLiteProxy>;
89
+ declare function resetWebSQLiteStorage(config: SQLiteConfig): Promise<void>;
74
90
 
75
- export { WebSQLiteProxy, createWebSQLiteProxy };
91
+ export { WebSQLiteProxy, createWebSQLiteProxy, resetWebSQLiteStorage };
@@ -8,14 +8,32 @@ function log(...args) {
8
8
  console.log(...args);
9
9
  }
10
10
  }
11
+ function createEmptyOperationStats() {
12
+ return {
13
+ queryCount: 0,
14
+ queryOneCount: 0,
15
+ runCount: 0,
16
+ execCount: 0,
17
+ transactionCount: 0,
18
+ transactionBatchCount: 0,
19
+ transactionBatchOperationCount: 0,
20
+ workerRequestCount: 0
21
+ };
22
+ }
23
+ function cloneOperationStats(stats) {
24
+ return { ...stats };
25
+ }
26
+ function estimateNodeBatchSqlOperations(input) {
27
+ const indexOperations = input.indexMode === "defer-schema" ? 0 : input.nodes.length + input.scalarIndexRows.length + input.ftsNodeIds.length + input.ftsRows.length + input.affectedSchemaIds.length;
28
+ return input.nodes.length * 2 + input.properties.length + input.changes.length + indexOperations + 1;
29
+ }
11
30
  var WebSQLiteProxy = class {
12
31
  worker = null;
13
32
  proxy = null;
14
33
  _config = null;
15
- async open(config) {
16
- if (this.worker) {
17
- throw new Error("Already open. Call close() first.");
18
- }
34
+ inTransaction = false;
35
+ operationStats = createEmptyOperationStats();
36
+ createWorkerProxy() {
19
37
  log("[WebSQLiteProxy] Creating worker...");
20
38
  this.worker = new Worker(new URL("./web-worker.js", import.meta.url), { type: "module" });
21
39
  this.worker.onerror = (event) => {
@@ -26,8 +44,16 @@ var WebSQLiteProxy = class {
26
44
  };
27
45
  log("[WebSQLiteProxy] Worker created, wrapping with Comlink...");
28
46
  this.proxy = Comlink.wrap(this.worker);
47
+ return this.proxy;
48
+ }
49
+ async open(config) {
50
+ if (this.worker) {
51
+ throw new Error("Already open. Call close() first.");
52
+ }
53
+ const proxy = this.createWorkerProxy();
29
54
  log("[WebSQLiteProxy] Calling proxy.open()...");
30
- const openPromise = this.proxy.open(config);
55
+ const openPromise = proxy.open(config);
56
+ this.operationStats.workerRequestCount += 1;
31
57
  const timeoutPromise = new Promise(
32
58
  (_, reject) => setTimeout(() => reject(new Error("Worker initialization timeout after 15s")), 15e3)
33
59
  );
@@ -35,8 +61,25 @@ var WebSQLiteProxy = class {
35
61
  log("[WebSQLiteProxy] proxy.open() completed");
36
62
  this._config = config;
37
63
  }
64
+ async resetStorage(config) {
65
+ if (this.worker) {
66
+ throw new Error("Already open. Call close() first.");
67
+ }
68
+ const proxy = this.createWorkerProxy();
69
+ const resetPromise = proxy.resetStorage(config);
70
+ this.operationStats.workerRequestCount += 1;
71
+ const timeoutPromise = new Promise(
72
+ (_, reject) => setTimeout(() => reject(new Error("Worker storage reset timeout after 15s")), 15e3)
73
+ );
74
+ try {
75
+ await Promise.race([resetPromise, timeoutPromise]);
76
+ } finally {
77
+ await this.close();
78
+ }
79
+ }
38
80
  async close() {
39
81
  if (this.proxy) {
82
+ this.operationStats.workerRequestCount += 1;
40
83
  await this.proxy.close();
41
84
  this.proxy = null;
42
85
  }
@@ -45,26 +88,35 @@ var WebSQLiteProxy = class {
45
88
  this.worker = null;
46
89
  }
47
90
  this._config = null;
91
+ this.inTransaction = false;
48
92
  }
49
93
  isOpen() {
50
94
  return this.proxy !== null;
51
95
  }
52
96
  async query(sql, params) {
53
97
  if (!this.proxy) throw new Error("Database not open");
98
+ this.operationStats.queryCount += 1;
99
+ this.operationStats.workerRequestCount += 1;
54
100
  const result = await this.proxy.query(sql, params);
55
101
  return result;
56
102
  }
57
103
  async queryOne(sql, params) {
58
104
  if (!this.proxy) throw new Error("Database not open");
105
+ this.operationStats.queryOneCount += 1;
106
+ this.operationStats.workerRequestCount += 1;
59
107
  const result = await this.proxy.queryOne(sql, params);
60
108
  return result;
61
109
  }
62
110
  async run(sql, params) {
63
111
  if (!this.proxy) throw new Error("Database not open");
112
+ this.operationStats.runCount += 1;
113
+ this.operationStats.workerRequestCount += 1;
64
114
  return this.proxy.run(sql, params);
65
115
  }
66
116
  async exec(sql) {
67
117
  if (!this.proxy) throw new Error("Database not open");
118
+ this.operationStats.execCount += 1;
119
+ this.operationStats.workerRequestCount += 1;
68
120
  return this.proxy.exec(sql);
69
121
  }
70
122
  async transaction(_fn) {
@@ -84,29 +136,61 @@ var WebSQLiteProxy = class {
84
136
  */
85
137
  async transactionBatch(operations) {
86
138
  if (!this.proxy) throw new Error("Database not open");
139
+ this.operationStats.transactionBatchCount += 1;
140
+ this.operationStats.transactionBatchOperationCount += operations.length;
141
+ this.operationStats.workerRequestCount += 1;
87
142
  await this.proxy.transaction(operations);
88
143
  }
144
+ async applyNodeBatch(input) {
145
+ if (!this.proxy) throw new Error("Database not open");
146
+ this.operationStats.transactionBatchCount += 1;
147
+ this.operationStats.transactionBatchOperationCount += estimateNodeBatchSqlOperations(input);
148
+ this.operationStats.workerRequestCount += 1;
149
+ return this.proxy.applyNodeBatch(input);
150
+ }
89
151
  async beginTransaction() {
90
152
  if (!this.proxy) throw new Error("Database not open");
153
+ if (this.inTransaction) {
154
+ throw new Error("Transaction already in progress");
155
+ }
156
+ this.operationStats.execCount += 1;
157
+ this.operationStats.workerRequestCount += 1;
91
158
  await this.proxy.exec("BEGIN IMMEDIATE");
159
+ this.inTransaction = true;
92
160
  }
93
161
  async commit() {
94
162
  if (!this.proxy) throw new Error("Database not open");
163
+ if (!this.inTransaction) {
164
+ throw new Error("No transaction in progress");
165
+ }
166
+ this.operationStats.execCount += 1;
167
+ this.operationStats.workerRequestCount += 1;
95
168
  await this.proxy.exec("COMMIT");
169
+ this.inTransaction = false;
96
170
  }
97
171
  async rollback() {
98
172
  if (!this.proxy) throw new Error("Database not open");
173
+ if (!this.inTransaction) {
174
+ return;
175
+ }
176
+ this.operationStats.execCount += 1;
177
+ this.operationStats.workerRequestCount += 1;
99
178
  await this.proxy.exec("ROLLBACK");
179
+ this.inTransaction = false;
100
180
  }
101
181
  async prepare(_sql) {
102
182
  throw new Error("Prepared statements not supported in proxy. Use query() or run() directly.");
103
183
  }
104
184
  async getSchemaVersion() {
105
185
  if (!this.proxy) throw new Error("Database not open");
186
+ this.operationStats.queryOneCount += 1;
187
+ this.operationStats.workerRequestCount += 1;
106
188
  return this.proxy.getSchemaVersion();
107
189
  }
108
190
  async setSchemaVersion(version) {
109
191
  if (!this.proxy) throw new Error("Database not open");
192
+ this.operationStats.runCount += 1;
193
+ this.operationStats.workerRequestCount += 1;
110
194
  await this.proxy.run("INSERT INTO _schema_version (version, applied_at) VALUES (?, ?)", [
111
195
  version,
112
196
  Date.now()
@@ -121,10 +205,12 @@ var WebSQLiteProxy = class {
121
205
  }
122
206
  async getDatabaseSize() {
123
207
  if (!this.proxy) throw new Error("Database not open");
208
+ this.operationStats.workerRequestCount += 1;
124
209
  return this.proxy.getDatabaseSize();
125
210
  }
126
211
  async vacuum() {
127
212
  if (!this.proxy) throw new Error("Database not open");
213
+ this.operationStats.workerRequestCount += 1;
128
214
  return this.proxy.vacuum();
129
215
  }
130
216
  async checkpoint() {
@@ -134,6 +220,7 @@ var WebSQLiteProxy = class {
134
220
  if (!this.proxy) throw new Error("Database not open");
135
221
  try {
136
222
  log("[WebSQLiteProxy] Calling proxy.getStorageMode()...");
223
+ this.operationStats.workerRequestCount += 1;
137
224
  const mode = await this.proxy.getStorageMode();
138
225
  log("[WebSQLiteProxy] getStorageMode() returned:", mode);
139
226
  return mode;
@@ -142,13 +229,38 @@ var WebSQLiteProxy = class {
142
229
  throw err;
143
230
  }
144
231
  }
232
+ /**
233
+ * Create a MessagePort connected directly to the SQLite worker.
234
+ *
235
+ * The returned port speaks the same Comlink `SQLiteWorkerHandler`
236
+ * protocol as this proxy and can be transferred to another worker
237
+ * (e.g. the data worker) so its storage calls skip the main thread.
238
+ */
239
+ async createMessagePort() {
240
+ if (!this.proxy) throw new Error("Database not open");
241
+ const channel = new MessageChannel();
242
+ this.operationStats.workerRequestCount += 1;
243
+ await this.proxy.connectPort(Comlink.transfer(channel.port1, [channel.port1]));
244
+ return channel.port2;
245
+ }
246
+ getOperationStats() {
247
+ return cloneOperationStats(this.operationStats);
248
+ }
249
+ resetOperationStats() {
250
+ this.operationStats = createEmptyOperationStats();
251
+ }
145
252
  };
146
253
  async function createWebSQLiteProxy(config) {
147
254
  const proxy = new WebSQLiteProxy();
148
255
  await proxy.open(config);
149
256
  return proxy;
150
257
  }
258
+ async function resetWebSQLiteStorage(config) {
259
+ const proxy = new WebSQLiteProxy();
260
+ await proxy.resetStorage(config);
261
+ }
151
262
  export {
152
263
  WebSQLiteProxy,
153
- createWebSQLiteProxy
264
+ createWebSQLiteProxy,
265
+ resetWebSQLiteStorage
154
266
  };
@@ -1,4 +1,4 @@
1
- import { b as SQLiteConfig, a as SQLRow, S as SQLValue, R as RunResult } from '../types-C_aHfRDF.js';
1
+ import { b as SQLiteConfig, a as SQLRow, S as SQLValue, R as RunResult, k as SQLiteNodeBatchApplyInput, l as SQLiteNodeBatchApplyResult } from '../types-DMrj3K4o.js';
2
2
 
3
3
  /**
4
4
  * @xnetjs/sqlite - Web Worker entry point for SQLite WASM
@@ -13,6 +13,7 @@ import { b as SQLiteConfig, a as SQLRow, S as SQLValue, R as RunResult } from '.
13
13
  declare class SQLiteWorkerHandler {
14
14
  private adapter;
15
15
  open(config: SQLiteConfig): Promise<void>;
16
+ resetStorage(config: SQLiteConfig): Promise<void>;
16
17
  close(): Promise<void>;
17
18
  isOpen(): boolean;
18
19
  query<T extends SQLRow = SQLRow>(sql: string, params?: SQLValue[]): Promise<T[]>;
@@ -23,10 +24,20 @@ declare class SQLiteWorkerHandler {
23
24
  sql: string;
24
25
  params?: SQLValue[];
25
26
  }>): Promise<void>;
27
+ applyNodeBatch(input: SQLiteNodeBatchApplyInput): Promise<SQLiteNodeBatchApplyResult>;
26
28
  getSchemaVersion(): Promise<number>;
27
29
  vacuum(): Promise<void>;
28
30
  getDatabaseSize(): Promise<number>;
29
31
  getStorageMode(): Promise<'opfs' | 'memory'>;
32
+ /**
33
+ * Expose this handler on an additional MessagePort.
34
+ *
35
+ * Lets another worker (e.g. the data worker from @xnetjs/data-bridge)
36
+ * talk to this SQLite worker directly without routing every storage call
37
+ * through the main thread. The port is created on the main thread with
38
+ * `WebSQLiteProxy.createMessagePort()` and transferred to the peer.
39
+ */
40
+ connectPort(port: MessagePort): void;
30
41
  }
31
42
 
32
43
  export { SQLiteWorkerHandler };
@@ -1,7 +1,9 @@
1
1
  import {
2
- createWebSQLiteAdapter
3
- } from "../chunk-BXYZU3OL.js";
4
- import "../chunk-HIREU5S5.js";
2
+ createWebSQLiteAdapter,
3
+ resetWebSQLiteOpfsStorage
4
+ } from "../chunk-DCY4LAUD.js";
5
+ import "../chunk-CBU263LI.js";
6
+ import "../chunk-NVD7G7DZ.js";
5
7
 
6
8
  // src/adapters/web-worker.ts
7
9
  import * as Comlink from "comlink";
@@ -24,6 +26,13 @@ var SQLiteWorkerHandler = class {
24
26
  this.adapter = await createWebSQLiteAdapter(config);
25
27
  log("[SQLiteWorkerHandler] open() completed");
26
28
  }
29
+ async resetStorage(config) {
30
+ if (this.adapter) {
31
+ await this.adapter.close();
32
+ this.adapter = null;
33
+ }
34
+ await resetWebSQLiteOpfsStorage(config);
35
+ }
27
36
  async close() {
28
37
  if (this.adapter) {
29
38
  await this.adapter.close();
@@ -57,6 +66,10 @@ var SQLiteWorkerHandler = class {
57
66
  }
58
67
  });
59
68
  }
69
+ async applyNodeBatch(input) {
70
+ if (!this.adapter) throw new Error("Database not open");
71
+ return this.adapter.applyNodeBatch(input);
72
+ }
60
73
  async getSchemaVersion() {
61
74
  if (!this.adapter) throw new Error("Database not open");
62
75
  return this.adapter.getSchemaVersion();
@@ -73,6 +86,17 @@ var SQLiteWorkerHandler = class {
73
86
  if (!this.adapter) throw new Error("Database not open");
74
87
  return this.adapter.getStorageMode();
75
88
  }
89
+ /**
90
+ * Expose this handler on an additional MessagePort.
91
+ *
92
+ * Lets another worker (e.g. the data worker from @xnetjs/data-bridge)
93
+ * talk to this SQLite worker directly without routing every storage call
94
+ * through the main thread. The port is created on the main thread with
95
+ * `WebSQLiteProxy.createMessagePort()` and transferred to the peer.
96
+ */
97
+ connectPort(port) {
98
+ Comlink.expose(this, port);
99
+ }
76
100
  };
77
101
  var handler = new SQLiteWorkerHandler();
78
102
  log("[SQLiteWorker] Handler instance created");
@@ -1,5 +1,5 @@
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';
1
+ import { S as SQLiteAdapter, P as PreparedStatement } from '../adapter-t2aqQ__n.js';
2
+ import { b as SQLiteConfig, a as SQLRow, S as SQLValue, R as RunResult, k as SQLiteNodeBatchApplyInput, l as SQLiteNodeBatchApplyResult } from '../types-DMrj3K4o.js';
3
3
 
4
4
  /**
5
5
  * @xnetjs/sqlite - Web SQLite adapter using @sqlite.org/sqlite-wasm
@@ -8,6 +8,13 @@ import { b as SQLiteConfig, a as SQLRow, S as SQLValue, R as RunResult } from '.
8
8
  * Must run in a Web Worker for OPFS access.
9
9
  */
10
10
 
11
+ /**
12
+ * Remove xNet's OPFS-backed SQLite storage for the supplied database path.
13
+ *
14
+ * This must run in a worker because the SAH-pool VFS uses synchronous OPFS
15
+ * handles. It is intentionally scoped to xNet's SQLite VFS directory.
16
+ */
17
+ declare function resetWebSQLiteOpfsStorage(config: SQLiteConfig): Promise<void>;
11
18
  /**
12
19
  * SQLite adapter for web browsers using @sqlite.org/sqlite-wasm.
13
20
  *
@@ -44,6 +51,7 @@ declare class WebSQLiteAdapter implements SQLiteAdapter {
44
51
  exec(sql: string): Promise<void>;
45
52
  private execSync;
46
53
  transaction<T>(fn: () => Promise<T>): Promise<T>;
54
+ applyNodeBatch(input: SQLiteNodeBatchApplyInput): Promise<SQLiteNodeBatchApplyResult>;
47
55
  beginTransaction(): Promise<void>;
48
56
  commit(): Promise<void>;
49
57
  rollback(): Promise<void>;
@@ -61,4 +69,4 @@ declare class WebSQLiteAdapter implements SQLiteAdapter {
61
69
  */
62
70
  declare function createWebSQLiteAdapter(config: SQLiteConfig): Promise<WebSQLiteAdapter>;
63
71
 
64
- export { WebSQLiteAdapter, createWebSQLiteAdapter };
72
+ export { WebSQLiteAdapter, createWebSQLiteAdapter, resetWebSQLiteOpfsStorage };
@@ -1,9 +1,12 @@
1
1
  import {
2
2
  WebSQLiteAdapter,
3
- createWebSQLiteAdapter
4
- } from "../chunk-BXYZU3OL.js";
5
- import "../chunk-HIREU5S5.js";
3
+ createWebSQLiteAdapter,
4
+ resetWebSQLiteOpfsStorage
5
+ } from "../chunk-DCY4LAUD.js";
6
+ import "../chunk-CBU263LI.js";
7
+ import "../chunk-NVD7G7DZ.js";
6
8
  export {
7
9
  WebSQLiteAdapter,
8
- createWebSQLiteAdapter
10
+ createWebSQLiteAdapter,
11
+ resetWebSQLiteOpfsStorage
9
12
  };