@framers/sql-storage-adapter 0.7.2 → 0.7.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/README.md +20 -0
- package/dist/adapters/electron/preload.cjs +289 -0
- package/dist/adapters/electron/renderer.d.ts +9 -0
- package/dist/adapters/electron/renderer.d.ts.map +1 -0
- package/dist/adapters/electron/renderer.js +8 -0
- package/dist/adapters/electron/renderer.js.map +1 -0
- package/dist/cjs/adapters/__tests__/indexedDbAdapter.spec.d.ts +2 -0
- package/dist/cjs/adapters/__tests__/indexedDbAdapter.spec.js +133 -0
- package/dist/cjs/adapters/baseStorageAdapter.d.ts +368 -0
- package/dist/cjs/adapters/baseStorageAdapter.js +744 -0
- package/dist/cjs/adapters/betterSqliteAdapter.d.ts +124 -0
- package/dist/cjs/adapters/betterSqliteAdapter.js +334 -0
- package/dist/cjs/adapters/capacitorSqliteAdapter.d.ts +83 -0
- package/dist/cjs/adapters/capacitorSqliteAdapter.js +250 -0
- package/dist/cjs/adapters/electron/electronMainAdapter.d.ts +251 -0
- package/dist/cjs/adapters/electron/electronMainAdapter.js +392 -0
- package/dist/cjs/adapters/electron/electronRendererAdapter.d.ts +177 -0
- package/dist/cjs/adapters/electron/electronRendererAdapter.js +283 -0
- package/dist/cjs/adapters/electron/index.d.ts +74 -0
- package/dist/cjs/adapters/electron/index.js +86 -0
- package/dist/cjs/adapters/electron/ipc/channels.d.ts +196 -0
- package/dist/cjs/adapters/electron/ipc/channels.js +127 -0
- package/dist/cjs/adapters/electron/ipc/index.d.ts +11 -0
- package/dist/cjs/adapters/electron/ipc/index.js +38 -0
- package/dist/cjs/adapters/electron/ipc/protocol.d.ts +78 -0
- package/dist/cjs/adapters/electron/ipc/protocol.js +341 -0
- package/dist/cjs/adapters/electron/ipc/types.d.ts +248 -0
- package/dist/cjs/adapters/electron/ipc/types.js +15 -0
- package/dist/cjs/adapters/electron/migration/autoMigrator.d.ts +184 -0
- package/dist/cjs/adapters/electron/migration/autoMigrator.js +441 -0
- package/dist/cjs/adapters/electron/migration/index.d.ts +9 -0
- package/dist/cjs/adapters/electron/migration/index.js +29 -0
- package/dist/cjs/adapters/electron/preload.d.ts +126 -0
- package/dist/cjs/adapters/electron/preload.js +233 -0
- package/dist/cjs/adapters/electron/recovery/corruptionDetector.d.ts +214 -0
- package/dist/cjs/adapters/electron/recovery/corruptionDetector.js +359 -0
- package/dist/cjs/adapters/electron/recovery/index.d.ts +11 -0
- package/dist/cjs/adapters/electron/recovery/index.js +34 -0
- package/dist/cjs/adapters/electron/recovery/walCheckpoint.d.ts +186 -0
- package/dist/cjs/adapters/electron/recovery/walCheckpoint.js +263 -0
- package/dist/cjs/adapters/electron/renderer.d.ts +9 -0
- package/dist/cjs/adapters/electron/renderer.js +33 -0
- package/dist/cjs/adapters/electron/window/index.d.ts +9 -0
- package/dist/cjs/adapters/electron/window/index.js +29 -0
- package/dist/cjs/adapters/electron/window/windowManager.d.ts +190 -0
- package/dist/cjs/adapters/electron/window/windowManager.js +321 -0
- package/dist/cjs/adapters/indexedDbAdapter.d.ts +490 -0
- package/dist/cjs/adapters/indexedDbAdapter.js +993 -0
- package/dist/cjs/adapters/postgresAdapter.d.ts +424 -0
- package/dist/cjs/adapters/postgresAdapter.js +889 -0
- package/dist/cjs/adapters/sqlJsAdapter.d.ts +64 -0
- package/dist/cjs/adapters/sqlJsAdapter.js +268 -0
- package/dist/cjs/adapters/supabase.d.ts +58 -0
- package/dist/cjs/adapters/supabase.js +401 -0
- package/dist/cjs/codecs/BrowserBlobCodec.d.ts +14 -0
- package/dist/cjs/codecs/BrowserBlobCodec.js +57 -0
- package/dist/cjs/codecs/NodeBlobCodec.d.ts +14 -0
- package/dist/cjs/codecs/NodeBlobCodec.js +59 -0
- package/dist/cjs/core/contracts/blobCodec.d.ts +15 -0
- package/dist/cjs/core/contracts/blobCodec.js +15 -0
- package/dist/cjs/core/contracts/context.d.ts +221 -0
- package/dist/cjs/core/contracts/context.js +15 -0
- package/dist/cjs/core/contracts/dialect.d.ts +154 -0
- package/dist/cjs/core/contracts/dialect.js +15 -0
- package/dist/cjs/core/contracts/events.d.ts +225 -0
- package/dist/cjs/core/contracts/events.js +15 -0
- package/dist/cjs/core/contracts/exporter.d.ts +13 -0
- package/dist/cjs/core/contracts/exporter.js +15 -0
- package/dist/cjs/core/contracts/extensions.d.ts +73 -0
- package/dist/cjs/core/contracts/extensions.js +15 -0
- package/dist/cjs/core/contracts/features.d.ts +25 -0
- package/dist/cjs/core/contracts/features.js +61 -0
- package/dist/cjs/core/contracts/fts.d.ts +66 -0
- package/dist/cjs/core/contracts/fts.js +15 -0
- package/dist/cjs/core/contracts/hooks.d.ts +481 -0
- package/dist/cjs/core/contracts/hooks.js +140 -0
- package/dist/cjs/core/contracts/index.d.ts +260 -0
- package/dist/cjs/core/contracts/index.js +41 -0
- package/dist/cjs/core/contracts/limitations.d.ts +46 -0
- package/dist/cjs/core/contracts/limitations.js +218 -0
- package/dist/cjs/core/contracts/performance.d.ts +308 -0
- package/dist/cjs/core/contracts/performance.js +144 -0
- package/dist/cjs/core/database.d.ts +220 -0
- package/dist/cjs/core/database.js +136 -0
- package/dist/cjs/core/portable.d.ts +23 -0
- package/dist/cjs/core/portable.js +66 -0
- package/dist/cjs/core/resolver.d.ts +77 -0
- package/dist/cjs/core/resolver.js +235 -0
- package/dist/cjs/dialects/PostgresDialect.d.ts +35 -0
- package/dist/cjs/dialects/PostgresDialect.js +143 -0
- package/dist/cjs/dialects/SqliteDialect.d.ts +35 -0
- package/dist/cjs/dialects/SqliteDialect.js +142 -0
- package/dist/cjs/dialects/shared.d.ts +17 -0
- package/dist/cjs/dialects/shared.js +90 -0
- package/dist/cjs/exporters/PostgresExporter.d.ts +14 -0
- package/dist/cjs/exporters/PostgresExporter.js +61 -0
- package/dist/cjs/exporters/SqliteFileExporter.d.ts +16 -0
- package/dist/cjs/exporters/SqliteFileExporter.js +43 -0
- package/dist/cjs/features/backup/cloudBackup.d.ts +219 -0
- package/dist/cjs/features/backup/cloudBackup.js +209 -0
- package/dist/cjs/features/kv/idb.d.ts +79 -0
- package/dist/cjs/features/kv/idb.js +32 -0
- package/dist/cjs/features/kv/index.d.ts +14 -0
- package/dist/cjs/features/kv/index.js +40 -0
- package/dist/cjs/features/kv/indexedDbKeyValueStore.d.ts +77 -0
- package/dist/cjs/features/kv/indexedDbKeyValueStore.js +116 -0
- package/dist/cjs/features/kv/keyValueStore.d.ts +48 -0
- package/dist/cjs/features/kv/keyValueStore.js +67 -0
- package/dist/cjs/features/kv/sqlKeyValueStore.d.ts +34 -0
- package/dist/cjs/features/kv/sqlKeyValueStore.js +81 -0
- package/dist/cjs/features/kv/valueCodec.d.ts +35 -0
- package/dist/cjs/features/kv/valueCodec.js +426 -0
- package/dist/cjs/features/migrations/dataExport.d.ts +77 -0
- package/dist/cjs/features/migrations/dataExport.js +194 -0
- package/dist/cjs/features/migrations/dataImport.d.ts +54 -0
- package/dist/cjs/features/migrations/dataImport.js +300 -0
- package/dist/cjs/features/migrations/migration.d.ts +89 -0
- package/dist/cjs/features/migrations/migration.js +187 -0
- package/dist/cjs/features/migrations/schemaMigrations.d.ts +93 -0
- package/dist/cjs/features/migrations/schemaMigrations.js +220 -0
- package/dist/cjs/features/sync/conflicts/conflictResolver.d.ts +222 -0
- package/dist/cjs/features/sync/conflicts/conflictResolver.js +366 -0
- package/dist/cjs/features/sync/conflicts/index.d.ts +9 -0
- package/dist/cjs/features/sync/conflicts/index.js +21 -0
- package/dist/cjs/features/sync/crossPlatformSync.d.ts +281 -0
- package/dist/cjs/features/sync/crossPlatformSync.js +551 -0
- package/dist/cjs/features/sync/devices/deviceManager.d.ts +243 -0
- package/dist/cjs/features/sync/devices/deviceManager.js +450 -0
- package/dist/cjs/features/sync/devices/index.d.ts +10 -0
- package/dist/cjs/features/sync/devices/index.js +21 -0
- package/dist/cjs/features/sync/index.d.ts +37 -0
- package/dist/cjs/features/sync/index.js +111 -0
- package/dist/cjs/features/sync/protocol/index.d.ts +11 -0
- package/dist/cjs/features/sync/protocol/index.js +23 -0
- package/dist/cjs/features/sync/protocol/messages.d.ts +348 -0
- package/dist/cjs/features/sync/protocol/messages.js +215 -0
- package/dist/cjs/features/sync/protocol/vectorClock.d.ts +164 -0
- package/dist/cjs/features/sync/protocol/vectorClock.js +256 -0
- package/dist/cjs/features/sync/syncManager.d.ts +348 -0
- package/dist/cjs/features/sync/syncManager.js +455 -0
- package/dist/cjs/features/sync/tables/index.d.ts +10 -0
- package/dist/cjs/features/sync/tables/index.js +21 -0
- package/dist/cjs/features/sync/tables/syncLogManager.d.ts +216 -0
- package/dist/cjs/features/sync/tables/syncLogManager.js +423 -0
- package/dist/cjs/features/sync/transport/httpTransport.d.ts +123 -0
- package/dist/cjs/features/sync/transport/httpTransport.js +346 -0
- package/dist/cjs/features/sync/transport/index.d.ts +12 -0
- package/dist/cjs/features/sync/transport/index.js +25 -0
- package/dist/cjs/features/sync/transport/transport.d.ts +259 -0
- package/dist/cjs/features/sync/transport/transport.js +163 -0
- package/dist/cjs/features/sync/transport/websocketTransport.d.ts +126 -0
- package/dist/cjs/features/sync/transport/websocketTransport.js +342 -0
- package/dist/cjs/fts/PostgresFts.d.ts +29 -0
- package/dist/cjs/fts/PostgresFts.js +77 -0
- package/dist/cjs/fts/SqliteFts5.d.ts +22 -0
- package/dist/cjs/fts/SqliteFts5.js +58 -0
- package/dist/cjs/index.d.ts +30 -0
- package/dist/cjs/index.js +101 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/shared/connectionGate.d.ts +94 -0
- package/dist/cjs/shared/connectionGate.js +77 -0
- package/dist/cjs/shared/errors.d.ts +23 -0
- package/dist/cjs/shared/errors.js +45 -0
- package/dist/cjs/shared/logger.d.ts +26 -0
- package/dist/cjs/shared/logger.js +40 -0
- package/dist/cjs/shared/parameterUtils.d.ts +16 -0
- package/dist/cjs/shared/parameterUtils.js +59 -0
- package/dist/cjs/shared/postgresTarget.d.ts +11 -0
- package/dist/cjs/shared/postgresTarget.js +30 -0
- package/dist/cjs/shared/segment.d.ts +43 -0
- package/dist/cjs/shared/segment.js +63 -0
- package/dist/cjs/shared/serializedTransaction.d.ts +14 -0
- package/dist/cjs/shared/serializedTransaction.js +74 -0
- package/dist/cjs/shared/splitSqlStatements.d.ts +27 -0
- package/dist/cjs/shared/splitSqlStatements.js +163 -0
- package/dist/cjs/shared/sqlPlaceholders.d.ts +48 -0
- package/dist/cjs/shared/sqlPlaceholders.js +263 -0
- package/dist/cjs/types/index.d.ts +29 -0
- package/dist/cjs/types/index.js +33 -0
- package/dist/core/portable.d.ts +23 -0
- package/dist/core/portable.d.ts.map +1 -0
- package/dist/core/portable.js +23 -0
- package/dist/core/portable.js.map +1 -0
- package/package.json +139 -24
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
var capacitorSqliteAdapter_exports = {};
|
|
29
|
+
__export(capacitorSqliteAdapter_exports, {
|
|
30
|
+
CapacitorSqliteAdapter: () => CapacitorSqliteAdapter,
|
|
31
|
+
createCapacitorSqliteAdapter: () => createCapacitorSqliteAdapter
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(capacitorSqliteAdapter_exports);
|
|
34
|
+
var import_parameterUtils = require("../shared/parameterUtils.js");
|
|
35
|
+
var import_sqlPlaceholders = require("../shared/sqlPlaceholders.js");
|
|
36
|
+
var import_serializedTransaction = require("../shared/serializedTransaction.js");
|
|
37
|
+
var import_connectionGate = require("../shared/connectionGate.js");
|
|
38
|
+
var import_segment = require("../shared/segment.js");
|
|
39
|
+
const LONG_WAIT_MS = 1e4;
|
|
40
|
+
const isCapacitorPlugin = (value) => {
|
|
41
|
+
if (!value || typeof value !== "object") {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
const candidate = value;
|
|
45
|
+
return typeof candidate.createConnection === "function";
|
|
46
|
+
};
|
|
47
|
+
const loadCapacitorSqlite = async () => {
|
|
48
|
+
try {
|
|
49
|
+
const mod = await Promise.resolve().then(() => __toESM(require("@capacitor-community/sqlite")));
|
|
50
|
+
if (isCapacitorPlugin(mod)) {
|
|
51
|
+
return mod;
|
|
52
|
+
}
|
|
53
|
+
if (mod && typeof mod === "object") {
|
|
54
|
+
const { default: defaultExport, CapacitorSQLite } = mod;
|
|
55
|
+
if (isCapacitorPlugin(defaultExport)) {
|
|
56
|
+
return defaultExport;
|
|
57
|
+
}
|
|
58
|
+
if (isCapacitorPlugin(CapacitorSQLite)) {
|
|
59
|
+
return CapacitorSQLite;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
} catch (error) {
|
|
64
|
+
console.warn("[StorageAdapter] @capacitor-community/sqlite module not available.", error);
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
const toRunResult = (answer) => {
|
|
69
|
+
const outer = answer ?? {};
|
|
70
|
+
const inner = typeof outer.changes === "object" && outer.changes !== null ? outer.changes : outer;
|
|
71
|
+
const changes = typeof inner.changes === "number" ? inner.changes : 0;
|
|
72
|
+
const lastId = inner.lastId;
|
|
73
|
+
return {
|
|
74
|
+
changes,
|
|
75
|
+
lastInsertRowid: typeof lastId === "number" || typeof lastId === "string" ? lastId : null
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
class CapacitorSqliteAdapter {
|
|
79
|
+
/** @throws {Error} When `options.segment` is not a name a segment can take. */
|
|
80
|
+
constructor(options = {}) {
|
|
81
|
+
this.options = options;
|
|
82
|
+
this.kind = "capacitor-sqlite";
|
|
83
|
+
this.capabilities = /* @__PURE__ */ new Set([
|
|
84
|
+
"transactions",
|
|
85
|
+
"wal",
|
|
86
|
+
"locks",
|
|
87
|
+
"persistence"
|
|
88
|
+
]);
|
|
89
|
+
this.plugin = null;
|
|
90
|
+
this.connection = null;
|
|
91
|
+
this.runSerializedTransaction = (0, import_serializedTransaction.createSerializedTransactionRunner)();
|
|
92
|
+
this.gate = (0, import_connectionGate.createConnectionGate)(null, { withoutContext: "wait" });
|
|
93
|
+
this.inFlight = /* @__PURE__ */ new Set();
|
|
94
|
+
this.longWaitReported = false;
|
|
95
|
+
this.longWait = {
|
|
96
|
+
afterMs: LONG_WAIT_MS,
|
|
97
|
+
onLongWait: () => this.reportLongWait()
|
|
98
|
+
};
|
|
99
|
+
this.dbName = options.database ?? "app";
|
|
100
|
+
this.segment = options.segment === void 0 ? void 0 : (0, import_segment.validateSegment)(options.segment);
|
|
101
|
+
}
|
|
102
|
+
async open(options) {
|
|
103
|
+
if (this.connection) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
this.plugin = await loadCapacitorSqlite();
|
|
107
|
+
if (!this.plugin) {
|
|
108
|
+
throw new Error("@capacitor-community/sqlite is unavailable. Install the plugin or choose a different adapter.");
|
|
109
|
+
}
|
|
110
|
+
const adapterOptions = options?.adapterOptions;
|
|
111
|
+
const requestedName = typeof adapterOptions?.database === "string" ? adapterOptions.database : void 0;
|
|
112
|
+
const configuredName = this.options.database;
|
|
113
|
+
const resolvedDbName = (0, import_segment.segmentName)(requestedName ?? configuredName ?? this.dbName, this.segment);
|
|
114
|
+
this.connection = await this.plugin.createConnection(resolvedDbName, false, "no-encryption", 1, false);
|
|
115
|
+
await this.connection.open();
|
|
116
|
+
if (this.options.enableWal ?? true) {
|
|
117
|
+
try {
|
|
118
|
+
await this.connection.execute("PRAGMA journal_mode = WAL;");
|
|
119
|
+
} catch (error) {
|
|
120
|
+
console.warn("[StorageAdapter] Failed to enable WAL on Capacitor SQLite.", error);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (options?.foreignKeys !== void 0) {
|
|
124
|
+
await this.connection.execute(`PRAGMA foreign_keys = ${options.foreignKeys ? "ON" : "OFF"};`, false);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
async run(statement, parameters) {
|
|
128
|
+
return (0, import_connectionGate.whenAdmitted)(this.gate, () => this.track(this.runNow(statement, parameters, true)), void 0, this.longWait);
|
|
129
|
+
}
|
|
130
|
+
async get(statement, parameters) {
|
|
131
|
+
const rows = await this.all(statement, parameters);
|
|
132
|
+
return rows.length > 0 ? rows[0] : null;
|
|
133
|
+
}
|
|
134
|
+
async all(statement, parameters) {
|
|
135
|
+
return (0, import_connectionGate.whenAdmitted)(this.gate, () => this.track(this.allNow(statement, parameters)), void 0, this.longWait);
|
|
136
|
+
}
|
|
137
|
+
async exec(script) {
|
|
138
|
+
return (0, import_connectionGate.whenAdmitted)(this.gate, () => this.track(this.execNow(script, true)), void 0, this.longWait);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Executes a callback within a database transaction.
|
|
142
|
+
*
|
|
143
|
+
* Callbacks run one at a time, since every transaction shares the one
|
|
144
|
+
* connection. The callback's statements go through the handle it receives;
|
|
145
|
+
* a statement issued through the adapter itself while the callback runs
|
|
146
|
+
* waits until the transaction ends, so a callback must not await one.
|
|
147
|
+
*/
|
|
148
|
+
async transaction(fn) {
|
|
149
|
+
this.ensureConnection();
|
|
150
|
+
const queued = setTimeout(() => this.reportLongWait(), LONG_WAIT_MS);
|
|
151
|
+
return this.runSerializedTransaction(() => {
|
|
152
|
+
clearTimeout(queued);
|
|
153
|
+
return this.gate.hold(async (token) => {
|
|
154
|
+
await Promise.allSettled([...this.inFlight]);
|
|
155
|
+
const conn = this.ensureConnection();
|
|
156
|
+
await conn.beginTransaction();
|
|
157
|
+
const transactionAdapter = (0, import_serializedTransaction.createSharedConnectionTransactionAdapter)(this.handleStatements(token));
|
|
158
|
+
try {
|
|
159
|
+
const result = await fn(transactionAdapter);
|
|
160
|
+
await conn.commitTransaction();
|
|
161
|
+
return result;
|
|
162
|
+
} catch (error) {
|
|
163
|
+
try {
|
|
164
|
+
await conn.rollbackTransaction();
|
|
165
|
+
} catch {
|
|
166
|
+
}
|
|
167
|
+
throw error;
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
async close() {
|
|
173
|
+
if (this.connection) {
|
|
174
|
+
await this.connection.close();
|
|
175
|
+
this.connection = null;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* The statements of one transaction's handle: they carry the transaction's
|
|
180
|
+
* token, so the gate admits them while the transaction is open, and run
|
|
181
|
+
* inside the plugin's open transaction.
|
|
182
|
+
*/
|
|
183
|
+
handleStatements(token) {
|
|
184
|
+
return {
|
|
185
|
+
kind: this.kind,
|
|
186
|
+
capabilities: this.capabilities,
|
|
187
|
+
open: async () => {
|
|
188
|
+
},
|
|
189
|
+
close: async () => {
|
|
190
|
+
},
|
|
191
|
+
run: (statement, parameters) => (0, import_connectionGate.whenAdmitted)(this.gate, () => this.runNow(statement, parameters, false), token),
|
|
192
|
+
get: async (statement, parameters) => {
|
|
193
|
+
const rows = await (0, import_connectionGate.whenAdmitted)(this.gate, () => this.allNow(statement, parameters), token);
|
|
194
|
+
return rows.length > 0 ? rows[0] : null;
|
|
195
|
+
},
|
|
196
|
+
all: (statement, parameters) => (0, import_connectionGate.whenAdmitted)(this.gate, () => this.allNow(statement, parameters), token),
|
|
197
|
+
exec: (script) => (0, import_connectionGate.whenAdmitted)(this.gate, () => this.execNow(script, false), token),
|
|
198
|
+
// The handle answers a nested transaction() itself and never calls this.
|
|
199
|
+
transaction: (fn) => fn(this)
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* @param ownTransaction - true for a statement from outside a transaction:
|
|
204
|
+
* the plugin runs it in a transaction of its own, as it always has.
|
|
205
|
+
*/
|
|
206
|
+
async runNow(statement, parameters, ownTransaction) {
|
|
207
|
+
({ statement, parameters } = (0, import_sqlPlaceholders.toSqliteStatement)(statement, parameters));
|
|
208
|
+
const conn = this.ensureConnection();
|
|
209
|
+
const { positional } = (0, import_parameterUtils.normaliseParameters)(parameters);
|
|
210
|
+
return toRunResult(await conn.run(statement, positional ?? [], ownTransaction));
|
|
211
|
+
}
|
|
212
|
+
async allNow(statement, parameters) {
|
|
213
|
+
({ statement, parameters } = (0, import_sqlPlaceholders.toSqliteStatement)(statement, parameters));
|
|
214
|
+
const conn = this.ensureConnection();
|
|
215
|
+
const { positional } = (0, import_parameterUtils.normaliseParameters)(parameters);
|
|
216
|
+
const result = await conn.query(statement, positional ?? []);
|
|
217
|
+
return result.values ?? [];
|
|
218
|
+
}
|
|
219
|
+
async execNow(script, ownTransaction) {
|
|
220
|
+
const conn = this.ensureConnection();
|
|
221
|
+
await conn.execute(script, ownTransaction);
|
|
222
|
+
}
|
|
223
|
+
/** Keeps a statement sent from outside a transaction in `inFlight` until it answers. */
|
|
224
|
+
track(sent) {
|
|
225
|
+
this.inFlight.add(sent);
|
|
226
|
+
const forget = () => {
|
|
227
|
+
this.inFlight.delete(sent);
|
|
228
|
+
};
|
|
229
|
+
sent.then(forget, forget);
|
|
230
|
+
return sent;
|
|
231
|
+
}
|
|
232
|
+
reportLongWait() {
|
|
233
|
+
if (this.longWaitReported)
|
|
234
|
+
return;
|
|
235
|
+
this.longWaitReported = true;
|
|
236
|
+
console.warn(`[StorageAdapter] A Capacitor SQLite statement has waited ${LONG_WAIT_MS / 1e3} s for an open transaction to end. Inside a transaction() callback, run statements through the callback's handle: one run through the adapter itself waits for the transaction, and the transaction waits for it.`);
|
|
237
|
+
}
|
|
238
|
+
ensureConnection() {
|
|
239
|
+
if (!this.connection) {
|
|
240
|
+
throw new Error("Storage adapter not opened. Call open() before executing statements.");
|
|
241
|
+
}
|
|
242
|
+
return this.connection;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
const createCapacitorSqliteAdapter = (options) => new CapacitorSqliteAdapter(options);
|
|
246
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
247
|
+
0 && (module.exports = {
|
|
248
|
+
CapacitorSqliteAdapter,
|
|
249
|
+
createCapacitorSqliteAdapter
|
|
250
|
+
});
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Electron Main Process Storage Adapter.
|
|
3
|
+
*
|
|
4
|
+
* Wraps BetterSqliteAdapter for use in Electron's main process.
|
|
5
|
+
* Handles IPC communication, WAL management, crash recovery,
|
|
6
|
+
* and multi-window coordination.
|
|
7
|
+
*
|
|
8
|
+
* ## Architecture
|
|
9
|
+
* This adapter runs in the main process and owns the actual database connection.
|
|
10
|
+
* Renderer processes communicate with it via IPC using ElectronRendererAdapter.
|
|
11
|
+
*
|
|
12
|
+
* ## Features
|
|
13
|
+
* - WAL mode with configurable checkpointing
|
|
14
|
+
* - Integrity checking and auto-repair
|
|
15
|
+
* - Multi-window change broadcasting
|
|
16
|
+
* - Cloud backup scheduling
|
|
17
|
+
* - Auto-migration on app updates
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import { createElectronMainAdapter } from '@framers/sql-storage-adapter/electron';
|
|
22
|
+
* import { app } from 'electron';
|
|
23
|
+
* import path from 'path';
|
|
24
|
+
*
|
|
25
|
+
* const db = await createElectronMainAdapter({
|
|
26
|
+
* filePath: path.join(app.getPath('userData'), 'app.db'),
|
|
27
|
+
* wal: { enabled: true, checkpointInterval: 300000 },
|
|
28
|
+
* recovery: { enabled: true, checkOnOpen: true },
|
|
29
|
+
* });
|
|
30
|
+
*
|
|
31
|
+
* await db.open();
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
import type { StorageAdapter, StorageCapability, StorageOpenOptions, StorageParameters, StorageRunResult, BatchOperation, BatchResult, PreparedStatement } from '../../core/contracts/index.js';
|
|
35
|
+
/**
|
|
36
|
+
* WAL (Write-Ahead Logging) configuration.
|
|
37
|
+
*/
|
|
38
|
+
export interface WalConfig {
|
|
39
|
+
/** Enable WAL mode (default: true) */
|
|
40
|
+
enabled?: boolean;
|
|
41
|
+
/** Checkpoint interval in milliseconds (default: 300000 = 5 minutes) */
|
|
42
|
+
checkpointInterval?: number;
|
|
43
|
+
/** Auto-checkpoint threshold in pages (default: 1000) */
|
|
44
|
+
autoCheckpointPages?: number;
|
|
45
|
+
/** Synchronous mode: OFF, NORMAL, FULL, EXTRA (default: NORMAL) */
|
|
46
|
+
synchronous?: 'OFF' | 'NORMAL' | 'FULL' | 'EXTRA';
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Recovery and integrity check configuration.
|
|
50
|
+
*/
|
|
51
|
+
export interface RecoveryConfig {
|
|
52
|
+
/** Enable recovery features (default: true) */
|
|
53
|
+
enabled?: boolean;
|
|
54
|
+
/** Run integrity check on open (default: true) */
|
|
55
|
+
checkOnOpen?: boolean;
|
|
56
|
+
/** Attempt auto-repair on corruption (default: true) */
|
|
57
|
+
autoRepair?: boolean;
|
|
58
|
+
/** Maximum time for integrity check in ms (default: 30000) */
|
|
59
|
+
integrityCheckTimeout?: number;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Auto-migration configuration.
|
|
63
|
+
*/
|
|
64
|
+
export interface MigrationConfig {
|
|
65
|
+
/** Enable auto-migration (default: false) */
|
|
66
|
+
enabled?: boolean;
|
|
67
|
+
/** Path to migrations directory */
|
|
68
|
+
migrationsPath?: string;
|
|
69
|
+
/** Run migrations on app version change (default: true) */
|
|
70
|
+
runOnVersionChange?: boolean;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Cloud backup configuration.
|
|
74
|
+
*/
|
|
75
|
+
export interface BackupConfig {
|
|
76
|
+
/** Enable cloud backups (default: false) */
|
|
77
|
+
enabled?: boolean;
|
|
78
|
+
/** Backup interval in milliseconds (default: 3600000 = 1 hour) */
|
|
79
|
+
interval?: number;
|
|
80
|
+
/** Maximum backups to keep (default: 7) */
|
|
81
|
+
maxBackups?: number;
|
|
82
|
+
/** Backup provider (implement your own) */
|
|
83
|
+
provider?: CloudBackupProvider;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Cloud backup provider interface.
|
|
87
|
+
*/
|
|
88
|
+
export interface CloudBackupProvider {
|
|
89
|
+
upload(localPath: string, remotePath: string): Promise<void>;
|
|
90
|
+
download(remotePath: string, localPath: string): Promise<void>;
|
|
91
|
+
list(): Promise<{
|
|
92
|
+
path: string;
|
|
93
|
+
createdAt: Date;
|
|
94
|
+
size: number;
|
|
95
|
+
}[]>;
|
|
96
|
+
delete(remotePath: string): Promise<void>;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Multi-window coordination configuration.
|
|
100
|
+
*/
|
|
101
|
+
export interface MultiWindowConfig {
|
|
102
|
+
/** Enable multi-window support (default: true) */
|
|
103
|
+
enabled?: boolean;
|
|
104
|
+
/** Broadcast changes to other windows (default: true) */
|
|
105
|
+
broadcastChanges?: boolean;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Full configuration for ElectronMainAdapter.
|
|
109
|
+
*/
|
|
110
|
+
export interface ElectronMainAdapterOptions {
|
|
111
|
+
/** Path to SQLite database file */
|
|
112
|
+
filePath: string;
|
|
113
|
+
/** WAL configuration */
|
|
114
|
+
wal?: WalConfig;
|
|
115
|
+
/** Recovery configuration */
|
|
116
|
+
recovery?: RecoveryConfig;
|
|
117
|
+
/** Migration configuration */
|
|
118
|
+
migration?: MigrationConfig;
|
|
119
|
+
/** Backup configuration */
|
|
120
|
+
backup?: BackupConfig;
|
|
121
|
+
/** Multi-window configuration */
|
|
122
|
+
multiWindow?: MultiWindowConfig;
|
|
123
|
+
/** Enable verbose logging (default: false) */
|
|
124
|
+
verbose?: boolean;
|
|
125
|
+
/**
|
|
126
|
+
* A database file of its own: the segment goes into the file's name, before
|
|
127
|
+
* its extension (`app.db` becomes `app-agentos.db`), and `getFilePath()`
|
|
128
|
+
* and the backups name that file. The renderer's IPC channels are one set
|
|
129
|
+
* per process, so a segmented adapter leaves them to the app's adapter
|
|
130
|
+
* without a segment: it serves the main process alone.
|
|
131
|
+
*/
|
|
132
|
+
segment?: string;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Electron Main Process Storage Adapter.
|
|
136
|
+
*
|
|
137
|
+
* This adapter is designed to run exclusively in Electron's main process.
|
|
138
|
+
* It wraps BetterSqliteAdapter and adds Electron-specific features like
|
|
139
|
+
* IPC handling, multi-window coordination, and crash recovery.
|
|
140
|
+
*/
|
|
141
|
+
export declare class ElectronMainAdapter implements StorageAdapter {
|
|
142
|
+
readonly kind = "electron-main";
|
|
143
|
+
readonly capabilities: ReadonlySet<StorageCapability>;
|
|
144
|
+
private innerAdapter;
|
|
145
|
+
private isInitialized;
|
|
146
|
+
private walCheckpointTimer;
|
|
147
|
+
private backupTimer;
|
|
148
|
+
private readonly options;
|
|
149
|
+
/** The database file: `options.filePath` with the segment in its name. */
|
|
150
|
+
private readonly filePath;
|
|
151
|
+
private readonly walConfig;
|
|
152
|
+
private readonly recoveryConfig;
|
|
153
|
+
private readonly multiWindowConfig;
|
|
154
|
+
constructor(options: ElectronMainAdapterOptions);
|
|
155
|
+
/**
|
|
156
|
+
* Open the database and initialize all subsystems.
|
|
157
|
+
*/
|
|
158
|
+
open(openOptions?: StorageOpenOptions): Promise<void>;
|
|
159
|
+
/**
|
|
160
|
+
* Close the database and cleanup all subsystems.
|
|
161
|
+
*/
|
|
162
|
+
close(): Promise<void>;
|
|
163
|
+
run(statement: string, parameters?: StorageParameters): Promise<StorageRunResult>;
|
|
164
|
+
get<T = unknown>(statement: string, parameters?: StorageParameters): Promise<T | null>;
|
|
165
|
+
all<T = unknown>(statement: string, parameters?: StorageParameters): Promise<T[]>;
|
|
166
|
+
exec(script: string): Promise<void>;
|
|
167
|
+
transaction<T>(fn: (trx: StorageAdapter) => Promise<T>): Promise<T>;
|
|
168
|
+
batch(operations: BatchOperation[]): Promise<BatchResult>;
|
|
169
|
+
prepare?<T = unknown>(statement: string): PreparedStatement<T>;
|
|
170
|
+
/**
|
|
171
|
+
* Configure WAL mode on the database.
|
|
172
|
+
*/
|
|
173
|
+
private configureWalMode;
|
|
174
|
+
/**
|
|
175
|
+
* Start the WAL checkpoint timer.
|
|
176
|
+
*/
|
|
177
|
+
private startWalCheckpointTimer;
|
|
178
|
+
/**
|
|
179
|
+
* Run a WAL checkpoint.
|
|
180
|
+
*/
|
|
181
|
+
runWalCheckpoint(): Promise<{
|
|
182
|
+
framesCheckpointed: number;
|
|
183
|
+
totalFrames: number;
|
|
184
|
+
}>;
|
|
185
|
+
/**
|
|
186
|
+
* Run an integrity check on the database.
|
|
187
|
+
*/
|
|
188
|
+
runIntegrityCheck(): Promise<{
|
|
189
|
+
ok: boolean;
|
|
190
|
+
issues: string[];
|
|
191
|
+
}>;
|
|
192
|
+
/**
|
|
193
|
+
* Attempt to repair the database.
|
|
194
|
+
*/
|
|
195
|
+
private attemptRepair;
|
|
196
|
+
/**
|
|
197
|
+
* Start the backup scheduler.
|
|
198
|
+
*/
|
|
199
|
+
private startBackupScheduler;
|
|
200
|
+
/**
|
|
201
|
+
* Run a backup.
|
|
202
|
+
*/
|
|
203
|
+
runBackup(): Promise<void>;
|
|
204
|
+
/**
|
|
205
|
+
* Cleanup old backups beyond the retention limit.
|
|
206
|
+
*/
|
|
207
|
+
private cleanupOldBackups;
|
|
208
|
+
/**
|
|
209
|
+
* Broadcast a database change to all windows.
|
|
210
|
+
*/
|
|
211
|
+
private broadcastChange;
|
|
212
|
+
/**
|
|
213
|
+
* Detect mutation type from SQL statement.
|
|
214
|
+
*/
|
|
215
|
+
private detectMutationType;
|
|
216
|
+
/**
|
|
217
|
+
* Extract table names from SQL statement.
|
|
218
|
+
*/
|
|
219
|
+
private extractTables;
|
|
220
|
+
/**
|
|
221
|
+
* Log a message if verbose mode is enabled.
|
|
222
|
+
*/
|
|
223
|
+
private log;
|
|
224
|
+
/**
|
|
225
|
+
* Check if the adapter is initialized.
|
|
226
|
+
*/
|
|
227
|
+
isOpen(): boolean;
|
|
228
|
+
/**
|
|
229
|
+
* Get the database file path.
|
|
230
|
+
*/
|
|
231
|
+
getFilePath(): string;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Create an Electron Main Process Storage Adapter.
|
|
235
|
+
*
|
|
236
|
+
* @param options - Adapter configuration
|
|
237
|
+
* @returns ElectronMainAdapter instance
|
|
238
|
+
*
|
|
239
|
+
* @example
|
|
240
|
+
* ```typescript
|
|
241
|
+
* const db = createElectronMainAdapter({
|
|
242
|
+
* filePath: path.join(app.getPath('userData'), 'app.db'),
|
|
243
|
+
* wal: { enabled: true },
|
|
244
|
+
* recovery: { checkOnOpen: true },
|
|
245
|
+
* });
|
|
246
|
+
*
|
|
247
|
+
* await db.open();
|
|
248
|
+
* ```
|
|
249
|
+
*/
|
|
250
|
+
export declare function createElectronMainAdapter(options: ElectronMainAdapterOptions): ElectronMainAdapter;
|
|
251
|
+
//# sourceMappingURL=electronMainAdapter.d.ts.map
|