@framers/sql-storage-adapter 0.7.2 → 0.7.4

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.
Files changed (194) hide show
  1. package/README.md +41 -0
  2. package/dist/adapters/electron/preload.cjs +289 -0
  3. package/dist/adapters/electron/renderer.d.ts +9 -0
  4. package/dist/adapters/electron/renderer.d.ts.map +1 -0
  5. package/dist/adapters/electron/renderer.js +8 -0
  6. package/dist/adapters/electron/renderer.js.map +1 -0
  7. package/dist/cjs/adapters/__tests__/indexedDbAdapter.spec.d.ts +2 -0
  8. package/dist/cjs/adapters/__tests__/indexedDbAdapter.spec.js +133 -0
  9. package/dist/cjs/adapters/baseStorageAdapter.d.ts +368 -0
  10. package/dist/cjs/adapters/baseStorageAdapter.js +744 -0
  11. package/dist/cjs/adapters/betterSqliteAdapter.d.ts +124 -0
  12. package/dist/cjs/adapters/betterSqliteAdapter.js +334 -0
  13. package/dist/cjs/adapters/capacitorSqliteAdapter.d.ts +83 -0
  14. package/dist/cjs/adapters/capacitorSqliteAdapter.js +250 -0
  15. package/dist/cjs/adapters/electron/electronMainAdapter.d.ts +251 -0
  16. package/dist/cjs/adapters/electron/electronMainAdapter.js +392 -0
  17. package/dist/cjs/adapters/electron/electronRendererAdapter.d.ts +177 -0
  18. package/dist/cjs/adapters/electron/electronRendererAdapter.js +283 -0
  19. package/dist/cjs/adapters/electron/index.d.ts +74 -0
  20. package/dist/cjs/adapters/electron/index.js +86 -0
  21. package/dist/cjs/adapters/electron/ipc/channels.d.ts +196 -0
  22. package/dist/cjs/adapters/electron/ipc/channels.js +127 -0
  23. package/dist/cjs/adapters/electron/ipc/index.d.ts +11 -0
  24. package/dist/cjs/adapters/electron/ipc/index.js +38 -0
  25. package/dist/cjs/adapters/electron/ipc/protocol.d.ts +78 -0
  26. package/dist/cjs/adapters/electron/ipc/protocol.js +341 -0
  27. package/dist/cjs/adapters/electron/ipc/types.d.ts +248 -0
  28. package/dist/cjs/adapters/electron/ipc/types.js +15 -0
  29. package/dist/cjs/adapters/electron/migration/autoMigrator.d.ts +184 -0
  30. package/dist/cjs/adapters/electron/migration/autoMigrator.js +441 -0
  31. package/dist/cjs/adapters/electron/migration/index.d.ts +9 -0
  32. package/dist/cjs/adapters/electron/migration/index.js +29 -0
  33. package/dist/cjs/adapters/electron/preload.d.ts +126 -0
  34. package/dist/cjs/adapters/electron/preload.js +233 -0
  35. package/dist/cjs/adapters/electron/recovery/corruptionDetector.d.ts +214 -0
  36. package/dist/cjs/adapters/electron/recovery/corruptionDetector.js +359 -0
  37. package/dist/cjs/adapters/electron/recovery/index.d.ts +11 -0
  38. package/dist/cjs/adapters/electron/recovery/index.js +34 -0
  39. package/dist/cjs/adapters/electron/recovery/walCheckpoint.d.ts +186 -0
  40. package/dist/cjs/adapters/electron/recovery/walCheckpoint.js +263 -0
  41. package/dist/cjs/adapters/electron/renderer.d.ts +9 -0
  42. package/dist/cjs/adapters/electron/renderer.js +33 -0
  43. package/dist/cjs/adapters/electron/window/index.d.ts +9 -0
  44. package/dist/cjs/adapters/electron/window/index.js +29 -0
  45. package/dist/cjs/adapters/electron/window/windowManager.d.ts +190 -0
  46. package/dist/cjs/adapters/electron/window/windowManager.js +321 -0
  47. package/dist/cjs/adapters/indexedDbAdapter.d.ts +490 -0
  48. package/dist/cjs/adapters/indexedDbAdapter.js +993 -0
  49. package/dist/cjs/adapters/postgresAdapter.d.ts +424 -0
  50. package/dist/cjs/adapters/postgresAdapter.js +889 -0
  51. package/dist/cjs/adapters/sqlJsAdapter.d.ts +64 -0
  52. package/dist/cjs/adapters/sqlJsAdapter.js +268 -0
  53. package/dist/cjs/adapters/supabase.d.ts +58 -0
  54. package/dist/cjs/adapters/supabase.js +401 -0
  55. package/dist/cjs/codecs/BrowserBlobCodec.d.ts +14 -0
  56. package/dist/cjs/codecs/BrowserBlobCodec.js +57 -0
  57. package/dist/cjs/codecs/NodeBlobCodec.d.ts +14 -0
  58. package/dist/cjs/codecs/NodeBlobCodec.js +59 -0
  59. package/dist/cjs/core/contracts/blobCodec.d.ts +15 -0
  60. package/dist/cjs/core/contracts/blobCodec.js +15 -0
  61. package/dist/cjs/core/contracts/context.d.ts +221 -0
  62. package/dist/cjs/core/contracts/context.js +15 -0
  63. package/dist/cjs/core/contracts/dialect.d.ts +154 -0
  64. package/dist/cjs/core/contracts/dialect.js +15 -0
  65. package/dist/cjs/core/contracts/events.d.ts +225 -0
  66. package/dist/cjs/core/contracts/events.js +15 -0
  67. package/dist/cjs/core/contracts/exporter.d.ts +13 -0
  68. package/dist/cjs/core/contracts/exporter.js +15 -0
  69. package/dist/cjs/core/contracts/extensions.d.ts +73 -0
  70. package/dist/cjs/core/contracts/extensions.js +15 -0
  71. package/dist/cjs/core/contracts/features.d.ts +25 -0
  72. package/dist/cjs/core/contracts/features.js +61 -0
  73. package/dist/cjs/core/contracts/fts.d.ts +66 -0
  74. package/dist/cjs/core/contracts/fts.js +15 -0
  75. package/dist/cjs/core/contracts/hooks.d.ts +481 -0
  76. package/dist/cjs/core/contracts/hooks.js +140 -0
  77. package/dist/cjs/core/contracts/index.d.ts +260 -0
  78. package/dist/cjs/core/contracts/index.js +41 -0
  79. package/dist/cjs/core/contracts/limitations.d.ts +46 -0
  80. package/dist/cjs/core/contracts/limitations.js +218 -0
  81. package/dist/cjs/core/contracts/performance.d.ts +308 -0
  82. package/dist/cjs/core/contracts/performance.js +144 -0
  83. package/dist/cjs/core/database.d.ts +220 -0
  84. package/dist/cjs/core/database.js +136 -0
  85. package/dist/cjs/core/portable.d.ts +24 -0
  86. package/dist/cjs/core/portable.js +68 -0
  87. package/dist/cjs/core/resolver.d.ts +77 -0
  88. package/dist/cjs/core/resolver.js +235 -0
  89. package/dist/cjs/dialects/PostgresDialect.d.ts +35 -0
  90. package/dist/cjs/dialects/PostgresDialect.js +143 -0
  91. package/dist/cjs/dialects/SqliteDialect.d.ts +35 -0
  92. package/dist/cjs/dialects/SqliteDialect.js +142 -0
  93. package/dist/cjs/dialects/shared.d.ts +17 -0
  94. package/dist/cjs/dialects/shared.js +90 -0
  95. package/dist/cjs/exporters/PostgresExporter.d.ts +14 -0
  96. package/dist/cjs/exporters/PostgresExporter.js +61 -0
  97. package/dist/cjs/exporters/SqliteFileExporter.d.ts +16 -0
  98. package/dist/cjs/exporters/SqliteFileExporter.js +43 -0
  99. package/dist/cjs/features/auth/authJsAdapter.d.ts +110 -0
  100. package/dist/cjs/features/auth/authJsAdapter.js +251 -0
  101. package/dist/cjs/features/backup/cloudBackup.d.ts +219 -0
  102. package/dist/cjs/features/backup/cloudBackup.js +209 -0
  103. package/dist/cjs/features/kv/idb.d.ts +79 -0
  104. package/dist/cjs/features/kv/idb.js +32 -0
  105. package/dist/cjs/features/kv/index.d.ts +14 -0
  106. package/dist/cjs/features/kv/index.js +40 -0
  107. package/dist/cjs/features/kv/indexedDbKeyValueStore.d.ts +77 -0
  108. package/dist/cjs/features/kv/indexedDbKeyValueStore.js +116 -0
  109. package/dist/cjs/features/kv/keyValueStore.d.ts +48 -0
  110. package/dist/cjs/features/kv/keyValueStore.js +67 -0
  111. package/dist/cjs/features/kv/sqlKeyValueStore.d.ts +34 -0
  112. package/dist/cjs/features/kv/sqlKeyValueStore.js +81 -0
  113. package/dist/cjs/features/kv/valueCodec.d.ts +35 -0
  114. package/dist/cjs/features/kv/valueCodec.js +426 -0
  115. package/dist/cjs/features/migrations/dataExport.d.ts +77 -0
  116. package/dist/cjs/features/migrations/dataExport.js +194 -0
  117. package/dist/cjs/features/migrations/dataImport.d.ts +54 -0
  118. package/dist/cjs/features/migrations/dataImport.js +300 -0
  119. package/dist/cjs/features/migrations/migration.d.ts +89 -0
  120. package/dist/cjs/features/migrations/migration.js +187 -0
  121. package/dist/cjs/features/migrations/schemaMigrations.d.ts +93 -0
  122. package/dist/cjs/features/migrations/schemaMigrations.js +220 -0
  123. package/dist/cjs/features/sync/conflicts/conflictResolver.d.ts +222 -0
  124. package/dist/cjs/features/sync/conflicts/conflictResolver.js +366 -0
  125. package/dist/cjs/features/sync/conflicts/index.d.ts +9 -0
  126. package/dist/cjs/features/sync/conflicts/index.js +21 -0
  127. package/dist/cjs/features/sync/crossPlatformSync.d.ts +281 -0
  128. package/dist/cjs/features/sync/crossPlatformSync.js +551 -0
  129. package/dist/cjs/features/sync/devices/deviceManager.d.ts +243 -0
  130. package/dist/cjs/features/sync/devices/deviceManager.js +450 -0
  131. package/dist/cjs/features/sync/devices/index.d.ts +10 -0
  132. package/dist/cjs/features/sync/devices/index.js +21 -0
  133. package/dist/cjs/features/sync/index.d.ts +37 -0
  134. package/dist/cjs/features/sync/index.js +111 -0
  135. package/dist/cjs/features/sync/protocol/index.d.ts +11 -0
  136. package/dist/cjs/features/sync/protocol/index.js +23 -0
  137. package/dist/cjs/features/sync/protocol/messages.d.ts +348 -0
  138. package/dist/cjs/features/sync/protocol/messages.js +215 -0
  139. package/dist/cjs/features/sync/protocol/vectorClock.d.ts +164 -0
  140. package/dist/cjs/features/sync/protocol/vectorClock.js +256 -0
  141. package/dist/cjs/features/sync/syncManager.d.ts +348 -0
  142. package/dist/cjs/features/sync/syncManager.js +455 -0
  143. package/dist/cjs/features/sync/tables/index.d.ts +10 -0
  144. package/dist/cjs/features/sync/tables/index.js +21 -0
  145. package/dist/cjs/features/sync/tables/syncLogManager.d.ts +216 -0
  146. package/dist/cjs/features/sync/tables/syncLogManager.js +423 -0
  147. package/dist/cjs/features/sync/transport/httpTransport.d.ts +123 -0
  148. package/dist/cjs/features/sync/transport/httpTransport.js +346 -0
  149. package/dist/cjs/features/sync/transport/index.d.ts +12 -0
  150. package/dist/cjs/features/sync/transport/index.js +25 -0
  151. package/dist/cjs/features/sync/transport/transport.d.ts +259 -0
  152. package/dist/cjs/features/sync/transport/transport.js +163 -0
  153. package/dist/cjs/features/sync/transport/websocketTransport.d.ts +126 -0
  154. package/dist/cjs/features/sync/transport/websocketTransport.js +342 -0
  155. package/dist/cjs/fts/PostgresFts.d.ts +29 -0
  156. package/dist/cjs/fts/PostgresFts.js +77 -0
  157. package/dist/cjs/fts/SqliteFts5.d.ts +22 -0
  158. package/dist/cjs/fts/SqliteFts5.js +58 -0
  159. package/dist/cjs/index.d.ts +31 -0
  160. package/dist/cjs/index.js +103 -0
  161. package/dist/cjs/package.json +3 -0
  162. package/dist/cjs/shared/connectionGate.d.ts +94 -0
  163. package/dist/cjs/shared/connectionGate.js +77 -0
  164. package/dist/cjs/shared/errors.d.ts +23 -0
  165. package/dist/cjs/shared/errors.js +45 -0
  166. package/dist/cjs/shared/logger.d.ts +26 -0
  167. package/dist/cjs/shared/logger.js +40 -0
  168. package/dist/cjs/shared/parameterUtils.d.ts +16 -0
  169. package/dist/cjs/shared/parameterUtils.js +59 -0
  170. package/dist/cjs/shared/postgresTarget.d.ts +11 -0
  171. package/dist/cjs/shared/postgresTarget.js +30 -0
  172. package/dist/cjs/shared/segment.d.ts +43 -0
  173. package/dist/cjs/shared/segment.js +63 -0
  174. package/dist/cjs/shared/serializedTransaction.d.ts +14 -0
  175. package/dist/cjs/shared/serializedTransaction.js +74 -0
  176. package/dist/cjs/shared/splitSqlStatements.d.ts +27 -0
  177. package/dist/cjs/shared/splitSqlStatements.js +163 -0
  178. package/dist/cjs/shared/sqlPlaceholders.d.ts +48 -0
  179. package/dist/cjs/shared/sqlPlaceholders.js +263 -0
  180. package/dist/cjs/types/index.d.ts +29 -0
  181. package/dist/cjs/types/index.js +33 -0
  182. package/dist/core/portable.d.ts +24 -0
  183. package/dist/core/portable.d.ts.map +1 -0
  184. package/dist/core/portable.js +24 -0
  185. package/dist/core/portable.js.map +1 -0
  186. package/dist/features/auth/authJsAdapter.d.ts +110 -0
  187. package/dist/features/auth/authJsAdapter.d.ts.map +1 -0
  188. package/dist/features/auth/authJsAdapter.js +248 -0
  189. package/dist/features/auth/authJsAdapter.js.map +1 -0
  190. package/dist/index.d.ts +1 -0
  191. package/dist/index.d.ts.map +1 -1
  192. package/dist/index.js +1 -0
  193. package/dist/index.js.map +1 -1
  194. package/package.json +149 -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