@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.
- package/dist/{adapter-I7yAV6iu.d.ts → adapter-t2aqQ__n.d.ts} +27 -1
- package/dist/adapters/electron.d.ts +7 -3
- package/dist/adapters/electron.js +50 -6
- package/dist/adapters/expo.d.ts +2 -2
- package/dist/adapters/expo.js +27 -6
- package/dist/adapters/memory.d.ts +2 -2
- package/dist/adapters/memory.js +1 -1
- package/dist/adapters/web-proxy.d.ts +19 -3
- package/dist/adapters/web-proxy.js +118 -6
- package/dist/adapters/web-worker.d.ts +12 -1
- package/dist/adapters/web-worker.js +27 -3
- package/dist/adapters/web.d.ts +11 -3
- package/dist/adapters/web.js +7 -4
- package/dist/browser-support.d.ts +56 -1
- package/dist/browser-support.js +11 -3
- package/dist/{chunk-ZRR5D2OD.js → chunk-2OK46ZBU.js} +118 -0
- package/dist/chunk-CBU263LI.js +30 -0
- package/dist/chunk-DCY4LAUD.js +494 -0
- package/dist/chunk-NVD7G7DZ.js +406 -0
- package/dist/index.d.ts +26 -7
- package/dist/index.js +188 -128
- package/dist/schema-BEgIA-rZ.d.ts +35 -0
- package/dist/types-DMrj3K4o.d.ts +132 -0
- package/package.json +1 -1
- package/dist/chunk-BXYZU3OL.js +0 -245
- package/dist/chunk-HIREU5S5.js +0 -193
- package/dist/schema-CjkXTqxn.d.ts +0 -35
- package/dist/types-C_aHfRDF.d.ts +0 -42
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { b as SQLiteConfig, a as SQLRow, S as SQLValue, R as RunResult } from './types-
|
|
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-
|
|
2
|
-
import { b as SQLiteConfig, a as SQLRow, S as SQLValue, R as RunResult } from '../types-
|
|
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-
|
|
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-
|
|
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
|
-
|
|
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
|
-
|
|
132
|
-
|
|
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
|
-
|
|
139
|
-
|
|
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();
|
package/dist/adapters/expo.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as SQLiteAdapter, P as PreparedStatement } from '../adapter-
|
|
2
|
-
import { b as SQLiteConfig, a as SQLRow, S as SQLValue, R as RunResult } from '../types-
|
|
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
|
package/dist/adapters/expo.js
CHANGED
|
@@ -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-
|
|
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
|
-
|
|
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
|
-
|
|
88
|
-
|
|
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
|
-
|
|
95
|
-
|
|
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-
|
|
2
|
-
import { b as SQLiteConfig, a as SQLRow, S as SQLValue, R as RunResult } from '../types-
|
|
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
|
package/dist/adapters/memory.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as SQLiteAdapter, P as PreparedStatement } from '../adapter-
|
|
2
|
-
import { b as SQLiteConfig, a as SQLRow, S as SQLValue, R as RunResult } from '../types-
|
|
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
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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 =
|
|
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-
|
|
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
|
-
|
|
4
|
-
|
|
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");
|
package/dist/adapters/web.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as SQLiteAdapter, P as PreparedStatement } from '../adapter-
|
|
2
|
-
import { b as SQLiteConfig, a as SQLRow, S as SQLValue, R as RunResult } from '../types-
|
|
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 };
|
package/dist/adapters/web.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
WebSQLiteAdapter,
|
|
3
|
-
createWebSQLiteAdapter
|
|
4
|
-
|
|
5
|
-
|
|
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
|
};
|