@framers/sql-storage-adapter 0.7.1 → 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 +43 -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/dist/features/migrations/schemaMigrations.d.ts +93 -0
- package/dist/features/migrations/schemaMigrations.d.ts.map +1 -0
- package/dist/features/migrations/schemaMigrations.js +216 -0
- package/dist/features/migrations/schemaMigrations.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +139 -24
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import type { StorageAdapter, StorageOpenOptions, StorageParameters, StorageRunResult, StorageCapability, BatchOperation, BatchResult } from '../core/contracts/index.js';
|
|
2
|
+
/** Options of the better-sqlite3 adapter. */
|
|
3
|
+
export interface BetterSqliteAdapterOptions {
|
|
4
|
+
/**
|
|
5
|
+
* A database file of its own: the segment goes into the file's name, before
|
|
6
|
+
* its extension (`app.sqlite3` becomes `app-agentos.sqlite3`), for the
|
|
7
|
+
* default path and for a path given to `open()`. `:memory:` stays as it is.
|
|
8
|
+
*/
|
|
9
|
+
segment?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Native SQLite adapter using better-sqlite3.
|
|
13
|
+
*
|
|
14
|
+
* ## Performance Characteristics
|
|
15
|
+
* - Synchronous operations (unique among adapters)
|
|
16
|
+
* - ~100,000 simple queries/second on modern hardware
|
|
17
|
+
* - Efficient for single-writer, multiple-reader scenarios
|
|
18
|
+
*
|
|
19
|
+
* ## Limitations
|
|
20
|
+
* - Single writer at a time (readers don't block)
|
|
21
|
+
* - No network access (local files only)
|
|
22
|
+
* - Platform-specific native binaries required
|
|
23
|
+
*
|
|
24
|
+
* ## When to Use
|
|
25
|
+
* - Desktop applications (Electron, Node.js)
|
|
26
|
+
* - Development and testing
|
|
27
|
+
* - Single-user applications
|
|
28
|
+
* - When synchronous operations are needed
|
|
29
|
+
*
|
|
30
|
+
* ## Graceful Degradation
|
|
31
|
+
* - Falls back to sql.js if native module unavailable
|
|
32
|
+
* - Automatically enables WAL mode for better concurrency
|
|
33
|
+
* - Handles database corruption with automatic recovery
|
|
34
|
+
*/
|
|
35
|
+
/**
|
|
36
|
+
* Native SQLite adapter backed by the `better-sqlite3` module.
|
|
37
|
+
*
|
|
38
|
+
* Features:
|
|
39
|
+
* - Synchronous & high-performance local storage
|
|
40
|
+
* - WAL support, prepared statements, batched writes
|
|
41
|
+
* - Graceful degradation when the native module is absent
|
|
42
|
+
*
|
|
43
|
+
* Browser Safety:
|
|
44
|
+
* This class can be imported in browser bundles without immediate failure.
|
|
45
|
+
* A runtime error is only thrown if `open()` is invoked in a browser context.
|
|
46
|
+
*/
|
|
47
|
+
export declare class BetterSqliteAdapter implements StorageAdapter {
|
|
48
|
+
private readonly defaultFilePath;
|
|
49
|
+
readonly kind = "better-sqlite3";
|
|
50
|
+
readonly capabilities: ReadonlySet<StorageCapability>;
|
|
51
|
+
private module;
|
|
52
|
+
private db;
|
|
53
|
+
private preparedStatements;
|
|
54
|
+
private readonly runSerializedTransaction;
|
|
55
|
+
/**
|
|
56
|
+
* Holds statements from outside an open transaction until it ends, so they
|
|
57
|
+
* neither join it nor read what it has not committed. open() gives it Node's
|
|
58
|
+
* AsyncLocalStorage, which tells the transaction's own statements apart.
|
|
59
|
+
*/
|
|
60
|
+
private gate;
|
|
61
|
+
private readonly segment;
|
|
62
|
+
/**
|
|
63
|
+
* Creates a new better-sqlite3 adapter instance.
|
|
64
|
+
*
|
|
65
|
+
* @param defaultFilePath - Absolute path to the SQLite database file.
|
|
66
|
+
* Will be created if it doesn't exist.
|
|
67
|
+
* @param options - The adapter's segment.
|
|
68
|
+
* @throws {Error} When `options.segment` is not a name a segment can take.
|
|
69
|
+
*/
|
|
70
|
+
constructor(defaultFilePath: string, options?: BetterSqliteAdapterOptions);
|
|
71
|
+
/**
|
|
72
|
+
* Open (or no-op if already open) the underlying native database.
|
|
73
|
+
*
|
|
74
|
+
* Throws a descriptive error if called in a browser environment.
|
|
75
|
+
*/
|
|
76
|
+
open(options?: StorageOpenOptions): Promise<void>;
|
|
77
|
+
run(statement: string, parameters?: StorageParameters): Promise<StorageRunResult>;
|
|
78
|
+
get<T = unknown>(statement: string, parameters?: StorageParameters): Promise<T | null>;
|
|
79
|
+
all<T>(statement: string, parameters?: StorageParameters): Promise<T[]>;
|
|
80
|
+
exec(script: string): Promise<void>;
|
|
81
|
+
private runNow;
|
|
82
|
+
private getNow;
|
|
83
|
+
private allNow;
|
|
84
|
+
private execNow;
|
|
85
|
+
/**
|
|
86
|
+
* The statements of one transaction's handle: they carry the transaction's
|
|
87
|
+
* token, so the gate admits them whatever async context runs them (a callback
|
|
88
|
+
* may reach its handle through an AsyncResource made before the transaction).
|
|
89
|
+
*/
|
|
90
|
+
private handleStatements;
|
|
91
|
+
transaction<T>(fn: (trx: StorageAdapter) => Promise<T>): Promise<T>;
|
|
92
|
+
close(): Promise<void>;
|
|
93
|
+
/**
|
|
94
|
+
* Execute multiple operations efficiently in a single transaction.
|
|
95
|
+
*
|
|
96
|
+
* Much faster than executing operations individually, especially
|
|
97
|
+
* for bulk inserts. Automatically wraps in a transaction.
|
|
98
|
+
*
|
|
99
|
+
* @param operations - Array of SQL operations to execute
|
|
100
|
+
* @returns Results of the batch operation
|
|
101
|
+
*/
|
|
102
|
+
batch(operations: BatchOperation[]): Promise<BatchResult>;
|
|
103
|
+
private batchNow;
|
|
104
|
+
private prepareInternal;
|
|
105
|
+
private ensureOpen;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Factory helper.
|
|
109
|
+
*/
|
|
110
|
+
/**
|
|
111
|
+
* Factory helper for creating a BetterSqliteAdapter.
|
|
112
|
+
*
|
|
113
|
+
* Path Resolution:
|
|
114
|
+
* - Absolute paths are used as-is.
|
|
115
|
+
* - Relative paths are resolved against the current working directory instead
|
|
116
|
+
* of the adapter file location (simpler & bundler neutral).
|
|
117
|
+
* - Special values like ':memory:' and 'file:' URIs are passed through.
|
|
118
|
+
* - With `options.segment`, the file's name carries the segment
|
|
119
|
+
* (`app.sqlite3` becomes `app-agentos.sqlite3`).
|
|
120
|
+
*
|
|
121
|
+
* @throws {Error} When `options.segment` is not a name a segment can take.
|
|
122
|
+
*/
|
|
123
|
+
export declare const createBetterSqliteAdapter: (filePath: string, options?: BetterSqliteAdapterOptions) => StorageAdapter;
|
|
124
|
+
//# sourceMappingURL=betterSqliteAdapter.d.ts.map
|
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
const __importMetaUrl = require('url').pathToFileURL(__filename).href;
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var betterSqliteAdapter_exports = {};
|
|
30
|
+
__export(betterSqliteAdapter_exports, {
|
|
31
|
+
BetterSqliteAdapter: () => BetterSqliteAdapter,
|
|
32
|
+
createBetterSqliteAdapter: () => createBetterSqliteAdapter
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(betterSqliteAdapter_exports);
|
|
35
|
+
var import_path = __toESM(require("path"));
|
|
36
|
+
var import_parameterUtils = require("../shared/parameterUtils.js");
|
|
37
|
+
var import_sqlPlaceholders = require("../shared/sqlPlaceholders.js");
|
|
38
|
+
var import_serializedTransaction = require("../shared/serializedTransaction.js");
|
|
39
|
+
var import_connectionGate = require("../shared/connectionGate.js");
|
|
40
|
+
var import_segment = require("../shared/segment.js");
|
|
41
|
+
const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined";
|
|
42
|
+
const versionOf = (require2) => {
|
|
43
|
+
try {
|
|
44
|
+
const pkg = require2("better-sqlite3/package.json");
|
|
45
|
+
return typeof pkg.version === "string" ? pkg.version : void 0;
|
|
46
|
+
} catch {
|
|
47
|
+
return void 0;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
const loadBetterSqlite = async () => {
|
|
51
|
+
const { createRequire } = await Promise.resolve().then(() => __toESM(require("module")));
|
|
52
|
+
try {
|
|
53
|
+
const imported = await Promise.resolve().then(() => __toESM(require("better-sqlite3")));
|
|
54
|
+
return { module: imported, version: versionOf(createRequire(__importMetaUrl)) };
|
|
55
|
+
} catch {
|
|
56
|
+
try {
|
|
57
|
+
const require2 = createRequire(import_path.default.join(process.cwd(), "noop.js"));
|
|
58
|
+
return { module: require2("better-sqlite3"), version: versionOf(require2) };
|
|
59
|
+
} catch (error) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
const betterSqliteRuntimeRefusal = (version, nodeApi) => {
|
|
65
|
+
const major = Number(version?.split(".")[0]);
|
|
66
|
+
if (!(major >= 13)) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
const api = Number(nodeApi);
|
|
70
|
+
if (api >= 10) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
const has = Number.isFinite(api) && api > 0 ? `Node-API ${api}` : "no Node-API version";
|
|
74
|
+
return `better-sqlite3 ${version} needs Node-API 10 (Node.js 22.14+ or 23.6+, Electron 35+), and this runtime has ${has}. Install better-sqlite3 12 for this runtime, or choose another adapter.`;
|
|
75
|
+
};
|
|
76
|
+
const loadTransactionContext = async () => {
|
|
77
|
+
try {
|
|
78
|
+
const { AsyncLocalStorage } = await Promise.resolve().then(() => __toESM(require("async_hooks")));
|
|
79
|
+
return new AsyncLocalStorage();
|
|
80
|
+
} catch {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
const normaliseRowId = (rowId) => {
|
|
85
|
+
if (rowId === null || rowId === void 0) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
return typeof rowId === "bigint" ? rowId.toString() : rowId;
|
|
89
|
+
};
|
|
90
|
+
class BetterSqliteAdapter {
|
|
91
|
+
/**
|
|
92
|
+
* Creates a new better-sqlite3 adapter instance.
|
|
93
|
+
*
|
|
94
|
+
* @param defaultFilePath - Absolute path to the SQLite database file.
|
|
95
|
+
* Will be created if it doesn't exist.
|
|
96
|
+
* @param options - The adapter's segment.
|
|
97
|
+
* @throws {Error} When `options.segment` is not a name a segment can take.
|
|
98
|
+
*/
|
|
99
|
+
constructor(defaultFilePath, options = {}) {
|
|
100
|
+
this.defaultFilePath = defaultFilePath;
|
|
101
|
+
this.kind = "better-sqlite3";
|
|
102
|
+
this.capabilities = /* @__PURE__ */ new Set([
|
|
103
|
+
"sync",
|
|
104
|
+
// Unique: supports synchronous operations
|
|
105
|
+
"transactions",
|
|
106
|
+
// Full ACID transaction support
|
|
107
|
+
"wal",
|
|
108
|
+
// Write-Ahead Logging for better concurrency
|
|
109
|
+
"locks",
|
|
110
|
+
// OS-level file locking prevents corruption
|
|
111
|
+
"persistence",
|
|
112
|
+
// File-based storage survives restarts
|
|
113
|
+
"prepared",
|
|
114
|
+
// Prepared statements for performance
|
|
115
|
+
"batch"
|
|
116
|
+
// Efficient batch operations
|
|
117
|
+
]);
|
|
118
|
+
this.module = null;
|
|
119
|
+
this.db = null;
|
|
120
|
+
this.preparedStatements = /* @__PURE__ */ new Map();
|
|
121
|
+
this.runSerializedTransaction = (0, import_serializedTransaction.createSerializedTransactionRunner)();
|
|
122
|
+
this.gate = (0, import_connectionGate.createConnectionGate)(null);
|
|
123
|
+
this.segment = options.segment === void 0 ? void 0 : (0, import_segment.validateSegment)(options.segment);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Open (or no-op if already open) the underlying native database.
|
|
127
|
+
*
|
|
128
|
+
* Throws a descriptive error if called in a browser environment.
|
|
129
|
+
*/
|
|
130
|
+
async open(options) {
|
|
131
|
+
if (this.db) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (isBrowser) {
|
|
135
|
+
throw new Error("[StorageAdapter] better-sqlite3 adapter cannot be opened in a browser environment.");
|
|
136
|
+
}
|
|
137
|
+
const loaded = await loadBetterSqlite();
|
|
138
|
+
if (!loaded) {
|
|
139
|
+
throw new Error("better-sqlite3 module is not available. Install it or choose another adapter.");
|
|
140
|
+
}
|
|
141
|
+
const refusal = betterSqliteRuntimeRefusal(loaded.version, process.versions?.napi);
|
|
142
|
+
if (refusal) {
|
|
143
|
+
throw new Error(refusal);
|
|
144
|
+
}
|
|
145
|
+
this.module = loaded.module;
|
|
146
|
+
const moduleReference = this.module;
|
|
147
|
+
const DatabaseCtor = moduleReference.default ?? moduleReference;
|
|
148
|
+
const resolvedPath = (0, import_segment.segmentFilePath)(options?.filePath ?? this.defaultFilePath, this.segment);
|
|
149
|
+
if (resolvedPath !== ":memory:" && !resolvedPath.startsWith("file:")) {
|
|
150
|
+
const fs = await Promise.resolve().then(() => __toESM(require("fs")));
|
|
151
|
+
const parentDir = import_path.default.dirname(resolvedPath);
|
|
152
|
+
if (!fs.existsSync(parentDir)) {
|
|
153
|
+
fs.mkdirSync(parentDir, { recursive: true });
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
const databaseOptions = options?.readOnly ? { readonly: true } : void 0;
|
|
157
|
+
this.gate = (0, import_connectionGate.createConnectionGate)(await loadTransactionContext());
|
|
158
|
+
this.db = new DatabaseCtor(resolvedPath, databaseOptions);
|
|
159
|
+
if (options?.foreignKeys !== void 0) {
|
|
160
|
+
this.db.exec(`PRAGMA foreign_keys = ${options.foreignKeys ? "ON" : "OFF"}`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
async run(statement, parameters) {
|
|
164
|
+
return (0, import_connectionGate.whenAdmitted)(this.gate, () => this.runNow(statement, parameters));
|
|
165
|
+
}
|
|
166
|
+
async get(statement, parameters) {
|
|
167
|
+
return (0, import_connectionGate.whenAdmitted)(this.gate, () => this.getNow(statement, parameters));
|
|
168
|
+
}
|
|
169
|
+
async all(statement, parameters) {
|
|
170
|
+
return (0, import_connectionGate.whenAdmitted)(this.gate, () => this.allNow(statement, parameters));
|
|
171
|
+
}
|
|
172
|
+
async exec(script) {
|
|
173
|
+
return (0, import_connectionGate.whenAdmitted)(this.gate, () => this.execNow(script));
|
|
174
|
+
}
|
|
175
|
+
runNow(statement, parameters) {
|
|
176
|
+
({ statement, parameters } = (0, import_sqlPlaceholders.toSqliteStatement)(statement, parameters));
|
|
177
|
+
parameters = (0, import_sqlPlaceholders.integersAsBigInt)(parameters);
|
|
178
|
+
const stmt = this.prepareInternal(statement);
|
|
179
|
+
const { named, positional } = (0, import_parameterUtils.normaliseParameters)(parameters);
|
|
180
|
+
const result = named ? stmt.run(named) : stmt.run(positional ?? []);
|
|
181
|
+
return { changes: result.changes, lastInsertRowid: normaliseRowId(result.lastInsertRowid) };
|
|
182
|
+
}
|
|
183
|
+
getNow(statement, parameters) {
|
|
184
|
+
({ statement, parameters } = (0, import_sqlPlaceholders.toSqliteStatement)(statement, parameters));
|
|
185
|
+
parameters = (0, import_sqlPlaceholders.integersAsBigInt)(parameters);
|
|
186
|
+
const stmt = this.prepareInternal(statement);
|
|
187
|
+
const { named, positional } = (0, import_parameterUtils.normaliseParameters)(parameters);
|
|
188
|
+
const row = named ? stmt.get(named) : stmt.get(positional ?? []);
|
|
189
|
+
return row ?? null;
|
|
190
|
+
}
|
|
191
|
+
allNow(statement, parameters) {
|
|
192
|
+
({ statement, parameters } = (0, import_sqlPlaceholders.toSqliteStatement)(statement, parameters));
|
|
193
|
+
parameters = (0, import_sqlPlaceholders.integersAsBigInt)(parameters);
|
|
194
|
+
const stmt = this.prepareInternal(statement);
|
|
195
|
+
const { named, positional } = (0, import_parameterUtils.normaliseParameters)(parameters);
|
|
196
|
+
const rows = named ? stmt.all(named) : stmt.all(positional ?? []);
|
|
197
|
+
return rows;
|
|
198
|
+
}
|
|
199
|
+
execNow(script) {
|
|
200
|
+
this.ensureOpen();
|
|
201
|
+
this.db.exec(script);
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* The statements of one transaction's handle: they carry the transaction's
|
|
205
|
+
* token, so the gate admits them whatever async context runs them (a callback
|
|
206
|
+
* may reach its handle through an AsyncResource made before the transaction).
|
|
207
|
+
*/
|
|
208
|
+
handleStatements(token) {
|
|
209
|
+
return {
|
|
210
|
+
kind: this.kind,
|
|
211
|
+
capabilities: this.capabilities,
|
|
212
|
+
open: async () => {
|
|
213
|
+
},
|
|
214
|
+
close: async () => {
|
|
215
|
+
},
|
|
216
|
+
run: (statement, parameters) => (0, import_connectionGate.whenAdmitted)(this.gate, () => this.runNow(statement, parameters), token),
|
|
217
|
+
get: (statement, parameters) => (0, import_connectionGate.whenAdmitted)(this.gate, () => this.getNow(statement, parameters), token),
|
|
218
|
+
all: (statement, parameters) => (0, import_connectionGate.whenAdmitted)(this.gate, () => this.allNow(statement, parameters), token),
|
|
219
|
+
exec: (script) => (0, import_connectionGate.whenAdmitted)(this.gate, () => this.execNow(script), token),
|
|
220
|
+
batch: (operations) => (0, import_connectionGate.whenAdmitted)(this.gate, () => this.batchNow(operations), token),
|
|
221
|
+
// The handle answers a nested transaction() itself and never calls this.
|
|
222
|
+
transaction: (fn) => fn(this)
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
async transaction(fn) {
|
|
226
|
+
this.ensureOpen();
|
|
227
|
+
const openToken = this.gate.inside() ? this.gate.openToken() : null;
|
|
228
|
+
if (openToken) {
|
|
229
|
+
return fn((0, import_serializedTransaction.createSharedConnectionTransactionAdapter)(this.handleStatements(openToken)));
|
|
230
|
+
}
|
|
231
|
+
return this.runSerializedTransaction(() => this.gate.hold(async (token) => {
|
|
232
|
+
this.ensureOpen();
|
|
233
|
+
this.db.exec("BEGIN");
|
|
234
|
+
const transactionAdapter = (0, import_serializedTransaction.createSharedConnectionTransactionAdapter)(this.handleStatements(token));
|
|
235
|
+
try {
|
|
236
|
+
const result = await fn(transactionAdapter);
|
|
237
|
+
this.db.exec("COMMIT");
|
|
238
|
+
return result;
|
|
239
|
+
} catch (error) {
|
|
240
|
+
try {
|
|
241
|
+
this.db.exec("ROLLBACK");
|
|
242
|
+
} catch {
|
|
243
|
+
}
|
|
244
|
+
throw error;
|
|
245
|
+
}
|
|
246
|
+
}));
|
|
247
|
+
}
|
|
248
|
+
async close() {
|
|
249
|
+
this.gate.dispose();
|
|
250
|
+
this.gate = (0, import_connectionGate.createConnectionGate)(null);
|
|
251
|
+
if (this.db) {
|
|
252
|
+
this.preparedStatements.clear();
|
|
253
|
+
this.db.close();
|
|
254
|
+
this.db = null;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Execute multiple operations efficiently in a single transaction.
|
|
259
|
+
*
|
|
260
|
+
* Much faster than executing operations individually, especially
|
|
261
|
+
* for bulk inserts. Automatically wraps in a transaction.
|
|
262
|
+
*
|
|
263
|
+
* @param operations - Array of SQL operations to execute
|
|
264
|
+
* @returns Results of the batch operation
|
|
265
|
+
*/
|
|
266
|
+
async batch(operations) {
|
|
267
|
+
return (0, import_connectionGate.whenAdmitted)(this.gate, () => this.batchNow(operations));
|
|
268
|
+
}
|
|
269
|
+
batchNow(operations) {
|
|
270
|
+
this.ensureOpen();
|
|
271
|
+
const results = [];
|
|
272
|
+
const errors = [];
|
|
273
|
+
let successful = 0;
|
|
274
|
+
let failed = 0;
|
|
275
|
+
const transaction = this.db.transaction(() => {
|
|
276
|
+
operations.forEach((op, index) => {
|
|
277
|
+
try {
|
|
278
|
+
const prepared = (0, import_sqlPlaceholders.toSqliteStatement)(op.statement, op.parameters);
|
|
279
|
+
const stmt = this.prepareInternal(prepared.statement);
|
|
280
|
+
const { named, positional } = (0, import_parameterUtils.normaliseParameters)((0, import_sqlPlaceholders.integersAsBigInt)(prepared.parameters));
|
|
281
|
+
const result = named ? stmt.run(named) : stmt.run(positional ?? []);
|
|
282
|
+
results.push({
|
|
283
|
+
changes: result.changes,
|
|
284
|
+
lastInsertRowid: normaliseRowId(result.lastInsertRowid)
|
|
285
|
+
});
|
|
286
|
+
successful++;
|
|
287
|
+
} catch (error) {
|
|
288
|
+
failed++;
|
|
289
|
+
errors.push({
|
|
290
|
+
index,
|
|
291
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
});
|
|
296
|
+
try {
|
|
297
|
+
transaction();
|
|
298
|
+
} catch (error) {
|
|
299
|
+
return {
|
|
300
|
+
successful: 0,
|
|
301
|
+
failed: operations.length,
|
|
302
|
+
errors: [{
|
|
303
|
+
index: -1,
|
|
304
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
305
|
+
}]
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
return { successful, failed, results, errors };
|
|
309
|
+
}
|
|
310
|
+
prepareInternal(statement) {
|
|
311
|
+
this.ensureOpen();
|
|
312
|
+
if (!this.preparedStatements.has(statement)) {
|
|
313
|
+
this.preparedStatements.set(statement, this.db.prepare(statement));
|
|
314
|
+
}
|
|
315
|
+
return this.preparedStatements.get(statement);
|
|
316
|
+
}
|
|
317
|
+
ensureOpen() {
|
|
318
|
+
if (!this.db) {
|
|
319
|
+
throw new Error("Storage adapter not opened. Call open() before executing statements.");
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
const createBetterSqliteAdapter = (filePath, options) => {
|
|
324
|
+
if (filePath === ":memory:" || filePath.startsWith("file:")) {
|
|
325
|
+
return new BetterSqliteAdapter(filePath, options);
|
|
326
|
+
}
|
|
327
|
+
const resolved = import_path.default.isAbsolute(filePath) ? filePath : import_path.default.resolve(process.cwd(), filePath);
|
|
328
|
+
return new BetterSqliteAdapter(resolved, options);
|
|
329
|
+
};
|
|
330
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
331
|
+
0 && (module.exports = {
|
|
332
|
+
BetterSqliteAdapter,
|
|
333
|
+
createBetterSqliteAdapter
|
|
334
|
+
});
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { StorageAdapter, StorageCapability, StorageOpenOptions, StorageParameters, StorageRunResult } from '../core/contracts/index.js';
|
|
2
|
+
export interface CapacitorAdapterOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Database name. Defaults to `app`.
|
|
5
|
+
*/
|
|
6
|
+
database?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Whether to enable WAL when platform supports it.
|
|
9
|
+
*/
|
|
10
|
+
enableWal?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* A database of its own: the segment is appended to the database name
|
|
13
|
+
* (`app` becomes `app-agentos`), whether the name comes from `database` or
|
|
14
|
+
* from `open()`'s `adapterOptions.database`.
|
|
15
|
+
*/
|
|
16
|
+
segment?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Adapter using @capacitor-community/sqlite for native mobile targets.
|
|
20
|
+
*
|
|
21
|
+
* Transactions use the plugin's beginTransaction, commitTransaction and
|
|
22
|
+
* rollbackTransaction (plugin 5.0.7 and later). The plugin runs every other
|
|
23
|
+
* execute and run call in a transaction of its own, which cannot nest in an
|
|
24
|
+
* open one, so the statements of a transaction's callback go to the plugin
|
|
25
|
+
* with `transaction` false.
|
|
26
|
+
*/
|
|
27
|
+
export declare class CapacitorSqliteAdapter implements StorageAdapter {
|
|
28
|
+
private readonly options;
|
|
29
|
+
readonly kind = "capacitor-sqlite";
|
|
30
|
+
readonly capabilities: ReadonlySet<StorageCapability>;
|
|
31
|
+
private plugin;
|
|
32
|
+
private connection;
|
|
33
|
+
private dbName;
|
|
34
|
+
/** The connection is shared, so transaction() runs one callback at a time. */
|
|
35
|
+
private readonly runSerializedTransaction;
|
|
36
|
+
/**
|
|
37
|
+
* Holds statements from outside an open transaction until it ends. A WebView
|
|
38
|
+
* has no async context to tell the callback's own statements apart, so the
|
|
39
|
+
* callback's handle is the only way into an open transaction.
|
|
40
|
+
*/
|
|
41
|
+
private readonly gate;
|
|
42
|
+
/** Statements sent to the plugin from outside a transaction and not yet answered. */
|
|
43
|
+
private readonly inFlight;
|
|
44
|
+
private longWaitReported;
|
|
45
|
+
private readonly longWait;
|
|
46
|
+
private readonly segment;
|
|
47
|
+
/** @throws {Error} When `options.segment` is not a name a segment can take. */
|
|
48
|
+
constructor(options?: CapacitorAdapterOptions);
|
|
49
|
+
open(options?: StorageOpenOptions): Promise<void>;
|
|
50
|
+
run(statement: string, parameters?: StorageParameters): Promise<StorageRunResult>;
|
|
51
|
+
get<T>(statement: string, parameters?: StorageParameters): Promise<T | null>;
|
|
52
|
+
all<T>(statement: string, parameters?: StorageParameters): Promise<T[]>;
|
|
53
|
+
exec(script: string): Promise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* Executes a callback within a database transaction.
|
|
56
|
+
*
|
|
57
|
+
* Callbacks run one at a time, since every transaction shares the one
|
|
58
|
+
* connection. The callback's statements go through the handle it receives;
|
|
59
|
+
* a statement issued through the adapter itself while the callback runs
|
|
60
|
+
* waits until the transaction ends, so a callback must not await one.
|
|
61
|
+
*/
|
|
62
|
+
transaction<T>(fn: (trx: StorageAdapter) => Promise<T>): Promise<T>;
|
|
63
|
+
close(): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* The statements of one transaction's handle: they carry the transaction's
|
|
66
|
+
* token, so the gate admits them while the transaction is open, and run
|
|
67
|
+
* inside the plugin's open transaction.
|
|
68
|
+
*/
|
|
69
|
+
private handleStatements;
|
|
70
|
+
/**
|
|
71
|
+
* @param ownTransaction - true for a statement from outside a transaction:
|
|
72
|
+
* the plugin runs it in a transaction of its own, as it always has.
|
|
73
|
+
*/
|
|
74
|
+
private runNow;
|
|
75
|
+
private allNow;
|
|
76
|
+
private execNow;
|
|
77
|
+
/** Keeps a statement sent from outside a transaction in `inFlight` until it answers. */
|
|
78
|
+
private track;
|
|
79
|
+
private reportLongWait;
|
|
80
|
+
private ensureConnection;
|
|
81
|
+
}
|
|
82
|
+
export declare const createCapacitorSqliteAdapter: (options?: CapacitorAdapterOptions) => StorageAdapter;
|
|
83
|
+
//# sourceMappingURL=capacitorSqliteAdapter.d.ts.map
|