@framers/sql-storage-adapter 0.1.0 → 0.3.0

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 (127) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +241 -363
  3. package/dist/adapters/__tests__/indexedDbAdapter.spec.d.ts +2 -0
  4. package/dist/adapters/__tests__/indexedDbAdapter.spec.d.ts.map +1 -0
  5. package/dist/adapters/__tests__/indexedDbAdapter.spec.js +137 -0
  6. package/dist/adapters/__tests__/indexedDbAdapter.spec.js.map +1 -0
  7. package/dist/adapters/baseStorageAdapter.d.ts +1 -1
  8. package/dist/adapters/baseStorageAdapter.d.ts.map +1 -1
  9. package/dist/adapters/betterSqliteAdapter.d.ts +27 -1
  10. package/dist/adapters/betterSqliteAdapter.d.ts.map +1 -1
  11. package/dist/adapters/betterSqliteAdapter.js +81 -16
  12. package/dist/adapters/betterSqliteAdapter.js.map +1 -1
  13. package/dist/adapters/capacitorSqliteAdapter.d.ts +1 -1
  14. package/dist/adapters/capacitorSqliteAdapter.d.ts.map +1 -1
  15. package/dist/adapters/capacitorSqliteAdapter.js +27 -4
  16. package/dist/adapters/capacitorSqliteAdapter.js.map +1 -1
  17. package/dist/adapters/indexedDbAdapter.d.ts +189 -0
  18. package/dist/adapters/indexedDbAdapter.d.ts.map +1 -0
  19. package/dist/adapters/indexedDbAdapter.js +367 -0
  20. package/dist/adapters/indexedDbAdapter.js.map +1 -0
  21. package/dist/adapters/postgresAdapter.d.ts +7 -1
  22. package/dist/adapters/postgresAdapter.d.ts.map +1 -1
  23. package/dist/adapters/postgresAdapter.js +19 -2
  24. package/dist/adapters/postgresAdapter.js.map +1 -1
  25. package/dist/adapters/sqlJsAdapter.d.ts +1 -1
  26. package/dist/adapters/sqlJsAdapter.d.ts.map +1 -1
  27. package/dist/adapters/sqlJsAdapter.js +16 -2
  28. package/dist/adapters/sqlJsAdapter.js.map +1 -1
  29. package/dist/adapters/supabase.d.ts +3 -3
  30. package/dist/adapters/supabase.d.ts.map +1 -1
  31. package/dist/adapters/supabase.js +11 -7
  32. package/dist/adapters/supabase.js.map +1 -1
  33. package/dist/agentos/AgentOSStorageAdapter.d.ts +320 -0
  34. package/dist/agentos/AgentOSStorageAdapter.d.ts.map +1 -0
  35. package/dist/agentos/AgentOSStorageAdapter.js +406 -0
  36. package/dist/agentos/AgentOSStorageAdapter.js.map +1 -0
  37. package/dist/agentos/index.d.ts +7 -0
  38. package/dist/agentos/index.d.ts.map +1 -0
  39. package/dist/agentos/index.js +7 -0
  40. package/dist/agentos/index.js.map +1 -0
  41. package/dist/{types → core/contracts}/context.d.ts +2 -2
  42. package/dist/core/contracts/context.d.ts.map +1 -0
  43. package/dist/core/contracts/context.js.map +1 -0
  44. package/dist/{types → core/contracts}/events.d.ts +1 -1
  45. package/dist/core/contracts/events.d.ts.map +1 -0
  46. package/dist/core/contracts/events.js.map +1 -0
  47. package/dist/{types → core/contracts}/extensions.d.ts +3 -3
  48. package/dist/core/contracts/extensions.d.ts.map +1 -0
  49. package/dist/core/contracts/extensions.js.map +1 -0
  50. package/dist/{types.d.ts → core/contracts/index.d.ts} +1 -1
  51. package/dist/core/contracts/index.d.ts.map +1 -0
  52. package/dist/{types.js → core/contracts/index.js} +1 -1
  53. package/dist/core/contracts/index.js.map +1 -0
  54. package/dist/core/contracts/limitations.d.ts.map +1 -0
  55. package/dist/core/contracts/limitations.js.map +1 -0
  56. package/dist/{database.d.ts → core/database.d.ts} +16 -3
  57. package/dist/core/database.d.ts.map +1 -0
  58. package/dist/{database.js → core/database.js} +39 -8
  59. package/dist/core/database.js.map +1 -0
  60. package/dist/{resolver.d.ts → core/resolver.d.ts} +4 -4
  61. package/dist/core/resolver.d.ts.map +1 -0
  62. package/dist/{resolver.js → core/resolver.js} +24 -8
  63. package/dist/core/resolver.js.map +1 -0
  64. package/dist/{utils → features/backup}/cloudBackup.d.ts +1 -1
  65. package/dist/features/backup/cloudBackup.d.ts.map +1 -0
  66. package/dist/{utils → features/backup}/cloudBackup.js +2 -2
  67. package/dist/features/backup/cloudBackup.js.map +1 -0
  68. package/dist/{utils → features/migrations}/dataExport.d.ts +1 -1
  69. package/dist/features/migrations/dataExport.d.ts.map +1 -0
  70. package/dist/features/migrations/dataExport.js.map +1 -0
  71. package/dist/{utils → features/migrations}/dataImport.d.ts +1 -1
  72. package/dist/features/migrations/dataImport.d.ts.map +1 -0
  73. package/dist/features/migrations/dataImport.js.map +1 -0
  74. package/dist/{utils → features/migrations}/migration.d.ts +2 -2
  75. package/dist/features/migrations/migration.d.ts.map +1 -0
  76. package/dist/{utils → features/migrations}/migration.js +6 -6
  77. package/dist/features/migrations/migration.js.map +1 -0
  78. package/dist/{utils → features/sync}/syncManager.d.ts +11 -5
  79. package/dist/features/sync/syncManager.d.ts.map +1 -0
  80. package/dist/{utils → features/sync}/syncManager.js +40 -10
  81. package/dist/features/sync/syncManager.js.map +1 -0
  82. package/dist/index.d.ts +12 -11
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +18 -19
  85. package/dist/index.js.map +1 -1
  86. package/dist/{utils → shared}/parameterUtils.d.ts +1 -1
  87. package/dist/shared/parameterUtils.d.ts.map +1 -0
  88. package/dist/shared/parameterUtils.js.map +1 -0
  89. package/dist/types/index.d.ts +11 -0
  90. package/dist/types/index.d.ts.map +1 -0
  91. package/dist/types/index.js +11 -0
  92. package/dist/types/index.js.map +1 -0
  93. package/package.json +22 -6
  94. package/dist/database.d.ts.map +0 -1
  95. package/dist/database.js.map +0 -1
  96. package/dist/resolver.d.ts.map +0 -1
  97. package/dist/resolver.js.map +0 -1
  98. package/dist/types/context.d.ts.map +0 -1
  99. package/dist/types/context.js.map +0 -1
  100. package/dist/types/events.d.ts.map +0 -1
  101. package/dist/types/events.js.map +0 -1
  102. package/dist/types/extensions.d.ts.map +0 -1
  103. package/dist/types/extensions.js.map +0 -1
  104. package/dist/types/limitations.d.ts.map +0 -1
  105. package/dist/types/limitations.js.map +0 -1
  106. package/dist/types.d.ts.map +0 -1
  107. package/dist/types.js.map +0 -1
  108. package/dist/utils/cloudBackup.d.ts.map +0 -1
  109. package/dist/utils/cloudBackup.js.map +0 -1
  110. package/dist/utils/dataExport.d.ts.map +0 -1
  111. package/dist/utils/dataExport.js.map +0 -1
  112. package/dist/utils/dataImport.d.ts.map +0 -1
  113. package/dist/utils/dataImport.js.map +0 -1
  114. package/dist/utils/migration.d.ts.map +0 -1
  115. package/dist/utils/migration.js.map +0 -1
  116. package/dist/utils/parameterUtils.d.ts.map +0 -1
  117. package/dist/utils/parameterUtils.js.map +0 -1
  118. package/dist/utils/syncManager.d.ts.map +0 -1
  119. package/dist/utils/syncManager.js.map +0 -1
  120. /package/dist/{types → core/contracts}/context.js +0 -0
  121. /package/dist/{types → core/contracts}/events.js +0 -0
  122. /package/dist/{types → core/contracts}/extensions.js +0 -0
  123. /package/dist/{types → core/contracts}/limitations.d.ts +0 -0
  124. /package/dist/{types → core/contracts}/limitations.js +0 -0
  125. /package/dist/{utils → features/migrations}/dataExport.js +0 -0
  126. /package/dist/{utils → features/migrations}/dataImport.js +0 -0
  127. /package/dist/{utils → shared}/parameterUtils.js +0 -0
@@ -0,0 +1,189 @@
1
+ /**
2
+ * @fileoverview IndexedDB Storage Adapter for AgentOS
3
+ * @description Browser-native SQL storage using IndexedDB with sql.js for full client-side operation.
4
+ * Supports transactions, persistence to IndexedDB, and offline-first workflows.
5
+ *
6
+ * **Use cases:**
7
+ * - Fully client-side AgentOS (no backend needed)
8
+ * - Progressive Web Apps (PWAs)
9
+ * - Offline-capable agents
10
+ * - Privacy-first applications (data never leaves browser)
11
+ *
12
+ * **Architecture:**
13
+ * - Uses sql.js (SQLite compiled to WebAssembly) for SQL execution
14
+ * - Persists database to IndexedDB for durability across sessions
15
+ * - Auto-saves after each transaction
16
+ * - Supports import/export for data portability
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * import { IndexedDbAdapter } from '../adapters/indexedDbAdapter';
21
+ *
22
+ * const adapter = new IndexedDbAdapter({
23
+ * dbName: 'agentos-client-db',
24
+ * autoSave: true,
25
+ * saveIntervalMs: 5000,
26
+ * });
27
+ *
28
+ * await adapter.open();
29
+ * await adapter.run('CREATE TABLE sessions (id TEXT PRIMARY KEY, data TEXT)');
30
+ * await adapter.run('INSERT INTO sessions VALUES (?, ?)', ['session-1', '{"events": []}']);
31
+ *
32
+ * const session = await adapter.get('SELECT * FROM sessions WHERE id = ?', ['session-1']);
33
+ * console.log(session);
34
+ * ```
35
+ */
36
+ import type { StorageAdapter, StorageCapability, StorageOpenOptions, StorageParameters, StorageRunResult } from '../core/contracts';
37
+ /**
38
+ * Configuration for IndexedDB adapter.
39
+ */
40
+ export interface IndexedDbAdapterOptions {
41
+ /** IndexedDB database name (default: 'agentos-db') */
42
+ dbName?: string;
43
+ /** IndexedDB object store name (default: 'sqliteDb') */
44
+ storeName?: string;
45
+ /** Auto-save to IndexedDB after each write (default: true) */
46
+ autoSave?: boolean;
47
+ /** Save interval in milliseconds for batched writes (default: 5000) */
48
+ saveIntervalMs?: number;
49
+ /** sql.js configuration (e.g., locateFile for wasm) */
50
+ sqlJsConfig?: any;
51
+ }
52
+ /**
53
+ * Storage adapter using IndexedDB + sql.js for client-side SQL persistence.
54
+ *
55
+ * **Capabilities:**
56
+ * - ✅ Transactions
57
+ * - ✅ Persistence (IndexedDB)
58
+ * - ✅ Full SQL support (via sql.js)
59
+ * - ✅ Export/import
60
+ * - ❌ Concurrent writes (single-threaded)
61
+ * - ❌ Server-side (browser only)
62
+ *
63
+ * **Performance:**
64
+ * - Fast reads (in-memory SQL)
65
+ * - Moderate writes (IndexedDB persistence)
66
+ * - Auto-save batching reduces IDB overhead
67
+ *
68
+ * @example Client-side AgentOS
69
+ * ```typescript
70
+ * const adapter = new IndexedDbAdapter({ dbName: 'my-app-db' });
71
+ * const agentos = new AgentOS();
72
+ * await agentos.initialize({
73
+ * storageAdapter: adapter,
74
+ * // ... other config
75
+ * });
76
+ * ```
77
+ */
78
+ export declare class IndexedDbAdapter implements StorageAdapter {
79
+ readonly kind = "indexeddb";
80
+ readonly capabilities: ReadonlySet<StorageCapability>;
81
+ private SQL;
82
+ private db;
83
+ private idb;
84
+ private saveTimer;
85
+ private dirty;
86
+ private readonly dbName;
87
+ private readonly storeName;
88
+ private readonly autoSave;
89
+ private readonly saveIntervalMs;
90
+ private readonly sqlJsConfig;
91
+ constructor(options?: IndexedDbAdapterOptions);
92
+ /**
93
+ * Opens IndexedDB and initializes sql.js database.
94
+ * Loads existing database from IndexedDB if present.
95
+ */
96
+ open(_options?: StorageOpenOptions): Promise<void>;
97
+ /**
98
+ * Executes a SQL statement that doesn't return rows (INSERT, UPDATE, DELETE, CREATE, etc.).
99
+ * @param statement SQL statement with ? or :name placeholders
100
+ * @param parameters Positional array or named object
101
+ * @returns Result with changes count and last insert row ID
102
+ */
103
+ run(statement: string, parameters?: StorageParameters): Promise<StorageRunResult>;
104
+ /**
105
+ * Executes a SQL query and returns the first row.
106
+ * @param statement SELECT statement
107
+ * @param parameters Query parameters
108
+ * @returns First row as object or null if no results
109
+ */
110
+ get<T>(statement: string, parameters?: StorageParameters): Promise<T | null>;
111
+ /**
112
+ * Executes a SQL query and returns all matching rows.
113
+ * @param statement SELECT statement
114
+ * @param parameters Query parameters
115
+ * @returns Array of result rows as objects
116
+ */
117
+ all<T>(statement: string, parameters?: StorageParameters): Promise<T[]>;
118
+ /**
119
+ * Executes a script containing multiple SQL statements.
120
+ */
121
+ exec(script: string): Promise<void>;
122
+ /**
123
+ * Executes a callback within a database transaction.
124
+ */
125
+ transaction<T>(fn: (trx: StorageAdapter) => Promise<T>): Promise<T>;
126
+ /**
127
+ * Begins a transaction. sql.js executes all statements in implicit transactions,
128
+ * so this is a no-op for compatibility.
129
+ */
130
+ beginTransaction(): Promise<void>;
131
+ /**
132
+ * Commits the current transaction.
133
+ */
134
+ commit(): Promise<void>;
135
+ /**
136
+ * Rolls back the current transaction.
137
+ */
138
+ rollback(): Promise<void>;
139
+ /**
140
+ * Closes the database and persists final state to IndexedDB.
141
+ */
142
+ close(): Promise<void>;
143
+ /**
144
+ * Exports the database as a Uint8Array (SQLite file format).
145
+ * Can be downloaded or stored externally.
146
+ * @returns SQLite database file as binary
147
+ */
148
+ exportDatabase(): Uint8Array;
149
+ /**
150
+ * Imports a database from a Uint8Array (SQLite file).
151
+ * Replaces the current database.
152
+ * @param data SQLite database file
153
+ */
154
+ importDatabase(data: Uint8Array): Promise<void>;
155
+ /**
156
+ * Opens or creates the IndexedDB database.
157
+ */
158
+ private openIndexedDb;
159
+ /**
160
+ * Loads the SQLite database from IndexedDB.
161
+ * @returns Binary database or null if not found
162
+ */
163
+ private loadFromIndexedDb;
164
+ /**
165
+ * Saves the SQLite database to IndexedDB.
166
+ */
167
+ private saveToIndexedDb;
168
+ /**
169
+ * Persists to IndexedDB if auto-save is enabled.
170
+ */
171
+ private persistIfNeeded;
172
+ /**
173
+ * Starts auto-save interval.
174
+ */
175
+ private startAutoSave;
176
+ /**
177
+ * Ensures the database is open.
178
+ */
179
+ private ensureOpen;
180
+ /**
181
+ * Normalizes last insert row ID to string or number.
182
+ */
183
+ private normaliseRowId;
184
+ /**
185
+ * Prepares a SQL statement for execution.
186
+ */
187
+ private prepareInternal;
188
+ }
189
+ //# sourceMappingURL=indexedDbAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexedDbAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/indexedDbAdapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAIH,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,mBAAmB,CAAC;AAG3B;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uEAAuE;IACvE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,uDAAuD;IAEvD,WAAW,CAAC,EAAE,GAAG,CAAC;CACnB;AAID;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,qBAAa,gBAAiB,YAAW,cAAc;IACrD,SAAgB,IAAI,eAAe;IACnC,SAAgB,YAAY,EAAE,WAAW,CAAC,iBAAiB,CAAC,CAA4C;IAExG,OAAO,CAAC,GAAG,CAA4B;IACvC,OAAO,CAAC,EAAE,CAA8B;IACxC,OAAO,CAAC,GAAG,CAA4B;IACvC,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,KAAK,CAAS;IAEtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAExC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAM;gBAEtB,OAAO,GAAE,uBAA4B;IAQjD;;;OAGG;IACU,IAAI,CAAC,QAAQ,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB/D;;;;;OAKG;IACU,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA4B9F;;;;;OAKG;IACU,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAKzF;;;;;OAKG;IACU,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IA8BpF;;OAEG;IACU,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOhD;;OAEG;IACU,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAehF;;;OAGG;IACU,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAK9C;;OAEG;IACU,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAMpC;;OAEG;IACU,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAItC;;OAEG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAqBnC;;;;OAIG;IACI,cAAc,IAAI,UAAU;IAKnC;;;;OAIG;IACU,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ5D;;OAEG;IACH,OAAO,CAAC,aAAa;IAgBrB;;;OAGG;YACW,iBAAiB;IAa/B;;OAEG;YACW,eAAe;IAkB7B;;OAEG;YACW,eAAe;IAO7B;;OAEG;IACH,OAAO,CAAC,aAAa;IAQrB;;OAEG;IACH,OAAO,CAAC,UAAU;IAMlB;;OAEG;IACH,OAAO,CAAC,cAAc;IAUtB;;OAEG;IACH,OAAO,CAAC,eAAe;CAIxB"}
@@ -0,0 +1,367 @@
1
+ /**
2
+ * @fileoverview IndexedDB Storage Adapter for AgentOS
3
+ * @description Browser-native SQL storage using IndexedDB with sql.js for full client-side operation.
4
+ * Supports transactions, persistence to IndexedDB, and offline-first workflows.
5
+ *
6
+ * **Use cases:**
7
+ * - Fully client-side AgentOS (no backend needed)
8
+ * - Progressive Web Apps (PWAs)
9
+ * - Offline-capable agents
10
+ * - Privacy-first applications (data never leaves browser)
11
+ *
12
+ * **Architecture:**
13
+ * - Uses sql.js (SQLite compiled to WebAssembly) for SQL execution
14
+ * - Persists database to IndexedDB for durability across sessions
15
+ * - Auto-saves after each transaction
16
+ * - Supports import/export for data portability
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * import { IndexedDbAdapter } from '../adapters/indexedDbAdapter';
21
+ *
22
+ * const adapter = new IndexedDbAdapter({
23
+ * dbName: 'agentos-client-db',
24
+ * autoSave: true,
25
+ * saveIntervalMs: 5000,
26
+ * });
27
+ *
28
+ * await adapter.open();
29
+ * await adapter.run('CREATE TABLE sessions (id TEXT PRIMARY KEY, data TEXT)');
30
+ * await adapter.run('INSERT INTO sessions VALUES (?, ?)', ['session-1', '{"events": []}']);
31
+ *
32
+ * const session = await adapter.get('SELECT * FROM sessions WHERE id = ?', ['session-1']);
33
+ * console.log(session);
34
+ * ```
35
+ */
36
+ import initSqlJs from 'sql.js';
37
+ import { normaliseParameters } from '../shared/parameterUtils';
38
+ const DB_VERSION = 1;
39
+ /**
40
+ * Storage adapter using IndexedDB + sql.js for client-side SQL persistence.
41
+ *
42
+ * **Capabilities:**
43
+ * - ✅ Transactions
44
+ * - ✅ Persistence (IndexedDB)
45
+ * - ✅ Full SQL support (via sql.js)
46
+ * - ✅ Export/import
47
+ * - ❌ Concurrent writes (single-threaded)
48
+ * - ❌ Server-side (browser only)
49
+ *
50
+ * **Performance:**
51
+ * - Fast reads (in-memory SQL)
52
+ * - Moderate writes (IndexedDB persistence)
53
+ * - Auto-save batching reduces IDB overhead
54
+ *
55
+ * @example Client-side AgentOS
56
+ * ```typescript
57
+ * const adapter = new IndexedDbAdapter({ dbName: 'my-app-db' });
58
+ * const agentos = new AgentOS();
59
+ * await agentos.initialize({
60
+ * storageAdapter: adapter,
61
+ * // ... other config
62
+ * });
63
+ * ```
64
+ */
65
+ export class IndexedDbAdapter {
66
+ constructor(options = {}) {
67
+ this.kind = 'indexeddb';
68
+ this.capabilities = new Set(['transactions', 'persistence']);
69
+ this.SQL = null;
70
+ this.db = null;
71
+ this.idb = null;
72
+ this.saveTimer = null;
73
+ this.dirty = false;
74
+ this.dbName = options.dbName || 'agentos-db';
75
+ this.storeName = options.storeName || 'sqliteDb';
76
+ this.autoSave = options.autoSave ?? true;
77
+ this.saveIntervalMs = options.saveIntervalMs || 5000;
78
+ this.sqlJsConfig = options.sqlJsConfig || {};
79
+ }
80
+ /**
81
+ * Opens IndexedDB and initializes sql.js database.
82
+ * Loads existing database from IndexedDB if present.
83
+ */
84
+ async open(_options) {
85
+ if (this.db) {
86
+ return; // Already open
87
+ }
88
+ // Initialize sql.js
89
+ this.SQL = await initSqlJs(this.sqlJsConfig);
90
+ // Open IndexedDB
91
+ this.idb = await this.openIndexedDb();
92
+ // Load existing database from IndexedDB or create new
93
+ const existingData = await this.loadFromIndexedDb();
94
+ if (existingData) {
95
+ this.db = new this.SQL.Database(existingData);
96
+ }
97
+ else {
98
+ this.db = new this.SQL.Database();
99
+ }
100
+ // Start auto-save interval
101
+ if (this.autoSave) {
102
+ this.startAutoSave();
103
+ }
104
+ }
105
+ /**
106
+ * Executes a SQL statement that doesn't return rows (INSERT, UPDATE, DELETE, CREATE, etc.).
107
+ * @param statement SQL statement with ? or :name placeholders
108
+ * @param parameters Positional array or named object
109
+ * @returns Result with changes count and last insert row ID
110
+ */
111
+ async run(statement, parameters) {
112
+ this.ensureOpen();
113
+ const stmt = this.db.prepare(statement);
114
+ try {
115
+ const { named, positional } = normaliseParameters(parameters);
116
+ if (named) {
117
+ stmt.bind(named);
118
+ }
119
+ else if (positional) {
120
+ stmt.bind(positional);
121
+ }
122
+ stmt.step();
123
+ const rowIdResult = this.db.exec('SELECT last_insert_rowid() AS id');
124
+ const rawRowId = rowIdResult[0]?.values?.[0]?.[0];
125
+ const lastInsertRowid = this.normaliseRowId(rawRowId);
126
+ this.dirty = true;
127
+ await this.persistIfNeeded();
128
+ return {
129
+ changes: this.db.getRowsModified(),
130
+ lastInsertRowid,
131
+ };
132
+ }
133
+ finally {
134
+ stmt.free();
135
+ }
136
+ }
137
+ /**
138
+ * Executes a SQL query and returns the first row.
139
+ * @param statement SELECT statement
140
+ * @param parameters Query parameters
141
+ * @returns First row as object or null if no results
142
+ */
143
+ async get(statement, parameters) {
144
+ const rows = await this.all(statement, parameters);
145
+ return rows.length > 0 ? rows[0] : null;
146
+ }
147
+ /**
148
+ * Executes a SQL query and returns all matching rows.
149
+ * @param statement SELECT statement
150
+ * @param parameters Query parameters
151
+ * @returns Array of result rows as objects
152
+ */
153
+ async all(statement, parameters) {
154
+ this.ensureOpen();
155
+ const stmt = this.db.prepare(statement);
156
+ try {
157
+ const { named, positional } = normaliseParameters(parameters);
158
+ if (named) {
159
+ stmt.bind(named);
160
+ }
161
+ else if (positional) {
162
+ stmt.bind(positional);
163
+ }
164
+ const results = [];
165
+ const columnNames = stmt.getColumnNames();
166
+ while (stmt.step()) {
167
+ const row = stmt.get();
168
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
169
+ const obj = {};
170
+ columnNames.forEach((col, idx) => {
171
+ obj[col] = row[idx];
172
+ });
173
+ results.push(obj);
174
+ }
175
+ return results;
176
+ }
177
+ finally {
178
+ stmt.free();
179
+ }
180
+ }
181
+ /**
182
+ * Executes a script containing multiple SQL statements.
183
+ */
184
+ async exec(script) {
185
+ this.ensureOpen();
186
+ this.db.exec(script);
187
+ this.dirty = true;
188
+ await this.persistIfNeeded();
189
+ }
190
+ /**
191
+ * Executes a callback within a database transaction.
192
+ */
193
+ async transaction(fn) {
194
+ this.ensureOpen();
195
+ await this.run('BEGIN TRANSACTION');
196
+ try {
197
+ const result = await fn(this);
198
+ await this.run('COMMIT');
199
+ this.dirty = true;
200
+ await this.persistIfNeeded();
201
+ return result;
202
+ }
203
+ catch (error) {
204
+ await this.run('ROLLBACK');
205
+ throw error;
206
+ }
207
+ }
208
+ /**
209
+ * Begins a transaction. sql.js executes all statements in implicit transactions,
210
+ * so this is a no-op for compatibility.
211
+ */
212
+ async beginTransaction() {
213
+ // sql.js uses auto-commit; explicit BEGIN is optional
214
+ await this.run('BEGIN');
215
+ }
216
+ /**
217
+ * Commits the current transaction.
218
+ */
219
+ async commit() {
220
+ await this.run('COMMIT');
221
+ this.dirty = true;
222
+ await this.persistIfNeeded();
223
+ }
224
+ /**
225
+ * Rolls back the current transaction.
226
+ */
227
+ async rollback() {
228
+ await this.run('ROLLBACK');
229
+ }
230
+ /**
231
+ * Closes the database and persists final state to IndexedDB.
232
+ */
233
+ async close() {
234
+ if (this.saveTimer) {
235
+ clearInterval(this.saveTimer);
236
+ this.saveTimer = null;
237
+ }
238
+ if (this.dirty) {
239
+ await this.saveToIndexedDb();
240
+ }
241
+ if (this.db) {
242
+ this.db.close();
243
+ this.db = null;
244
+ }
245
+ if (this.idb) {
246
+ this.idb.close();
247
+ this.idb = null;
248
+ }
249
+ }
250
+ /**
251
+ * Exports the database as a Uint8Array (SQLite file format).
252
+ * Can be downloaded or stored externally.
253
+ * @returns SQLite database file as binary
254
+ */
255
+ exportDatabase() {
256
+ this.ensureOpen();
257
+ return this.db.export();
258
+ }
259
+ /**
260
+ * Imports a database from a Uint8Array (SQLite file).
261
+ * Replaces the current database.
262
+ * @param data SQLite database file
263
+ */
264
+ async importDatabase(data) {
265
+ this.ensureOpen();
266
+ this.db.close();
267
+ this.db = new this.SQL.Database(data);
268
+ this.dirty = true;
269
+ await this.saveToIndexedDb();
270
+ }
271
+ /**
272
+ * Opens or creates the IndexedDB database.
273
+ */
274
+ openIndexedDb() {
275
+ return new Promise((resolve, reject) => {
276
+ const req = indexedDB.open(this.dbName, DB_VERSION);
277
+ req.onupgradeneeded = () => {
278
+ const db = req.result;
279
+ if (!db.objectStoreNames.contains(this.storeName)) {
280
+ db.createObjectStore(this.storeName);
281
+ }
282
+ };
283
+ req.onsuccess = () => resolve(req.result);
284
+ req.onerror = () => reject(req.error);
285
+ });
286
+ }
287
+ /**
288
+ * Loads the SQLite database from IndexedDB.
289
+ * @returns Binary database or null if not found
290
+ */
291
+ async loadFromIndexedDb() {
292
+ if (!this.idb)
293
+ return null;
294
+ return new Promise((resolve, reject) => {
295
+ const tx = this.idb.transaction(this.storeName, 'readonly');
296
+ const store = tx.objectStore(this.storeName);
297
+ const req = store.get('db');
298
+ req.onsuccess = () => resolve(req.result || null);
299
+ req.onerror = () => reject(req.error);
300
+ });
301
+ }
302
+ /**
303
+ * Saves the SQLite database to IndexedDB.
304
+ */
305
+ async saveToIndexedDb() {
306
+ if (!this.idb || !this.db)
307
+ return;
308
+ const data = this.db.export();
309
+ return new Promise((resolve, reject) => {
310
+ const tx = this.idb.transaction(this.storeName, 'readwrite');
311
+ const store = tx.objectStore(this.storeName);
312
+ const req = store.put(data, 'db');
313
+ req.onsuccess = () => {
314
+ this.dirty = false;
315
+ resolve();
316
+ };
317
+ req.onerror = () => reject(req.error);
318
+ });
319
+ }
320
+ /**
321
+ * Persists to IndexedDB if auto-save is enabled.
322
+ */
323
+ async persistIfNeeded() {
324
+ if (this.autoSave && !this.saveTimer) {
325
+ // Immediate save on first write, then batched
326
+ await this.saveToIndexedDb();
327
+ }
328
+ }
329
+ /**
330
+ * Starts auto-save interval.
331
+ */
332
+ startAutoSave() {
333
+ this.saveTimer = setInterval(async () => {
334
+ if (this.dirty) {
335
+ await this.saveToIndexedDb();
336
+ }
337
+ }, this.saveIntervalMs);
338
+ }
339
+ /**
340
+ * Ensures the database is open.
341
+ */
342
+ ensureOpen() {
343
+ if (!this.db) {
344
+ throw new Error('IndexedDbAdapter: Database not open. Call open() first.');
345
+ }
346
+ }
347
+ /**
348
+ * Normalizes last insert row ID to string or number.
349
+ */
350
+ normaliseRowId(value) {
351
+ if (typeof value === 'number' || typeof value === 'string') {
352
+ return value;
353
+ }
354
+ if (typeof value === 'bigint') {
355
+ return value.toString();
356
+ }
357
+ return null;
358
+ }
359
+ /**
360
+ * Prepares a SQL statement for execution.
361
+ */
362
+ prepareInternal(statement) {
363
+ this.ensureOpen();
364
+ return this.db.prepare(statement);
365
+ }
366
+ }
367
+ //# sourceMappingURL=indexedDbAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexedDbAdapter.js","sourceRoot":"","sources":["../../src/adapters/indexedDbAdapter.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { StorageAdapter, StorageCapability, StorageOpenOptions, StorageParameters, StorageRunResult } from '../types';
1
+ import type { StorageAdapter, StorageCapability, StorageOpenOptions, StorageParameters, StorageRunResult } from '../core/contracts';
2
2
  /**
3
3
  * Configuration options for PostgreSQL adapter.
4
4
  * Supports both connection strings and granular configuration.
@@ -137,6 +137,12 @@ export interface PostgresAdapterOptions {
137
137
  * - Connection pool handles transient failures
138
138
  * - Falls back to SQLite if PostgreSQL unavailable
139
139
  */
140
+ /**
141
+ * Production-grade PostgreSQL adapter backed by pg.Pool.
142
+ *
143
+ * Safe to import in browser bundles; will only throw if `open()` is invoked
144
+ * in a browser environment.
145
+ */
140
146
  export declare class PostgresAdapter implements StorageAdapter {
141
147
  readonly kind = "postgres";
142
148
  readonly capabilities: ReadonlySet<StorageCapability>;
@@ -1 +1 @@
1
- {"version":3,"file":"postgresAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/postgresAdapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAG3H;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oBAAoB;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kCAAkC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yDAAyD;IACzD,GAAG,CAAC,EAAE,OAAO,GAAG;QAAE,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3F,yCAAyC;IACzC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qCAAqC;IACrC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,yDAAyD;IACzD,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,+CAA+C;IAC/C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAgDD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkGG;AACH,qBAAa,eAAgB,YAAW,cAAc;IACpD,SAAgB,IAAI,cAAc;IAClC,SAAgB,YAAY,EAAE,WAAW,CAAC,iBAAiB,CAAC,CAQzD;IAEH,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,mBAAmB,CAA2B;gBAE1C,OAAO,EAAE,sBAAsB,GAAG,MAAM;IASvC,IAAI,CAAC,WAAW,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAmDrD,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAOjF,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAO5E,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAOvE,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQnC,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAoBnE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAOrB,WAAW;CAS1B;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,gBAAgB,EAAE,MAAM,GAAG,cAAc,CAAC;AAEhF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,GAAG,cAAc,CAAC"}
1
+ {"version":3,"file":"postgresAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/postgresAdapter.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAGpI;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oBAAoB;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kCAAkC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yDAAyD;IACzD,GAAG,CAAC,EAAE,OAAO,GAAG;QAAE,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3F,yCAAyC;IACzC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qCAAqC;IACrC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,yDAAyD;IACzD,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,+CAA+C;IAC/C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAgDD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkGG;AACH;;;;;GAKG;AACH,qBAAa,eAAgB,YAAW,cAAc;IACpD,SAAgB,IAAI,cAAc;IAClC,SAAgB,YAAY,EAAE,WAAW,CAAC,iBAAiB,CAAC,CAQzD;IAEH,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,mBAAmB,CAA2B;gBAE1C,OAAO,EAAE,sBAAsB,GAAG,MAAM;IASvC,IAAI,CAAC,WAAW,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAuDrD,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAWjF,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAO5E,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAOvE,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQnC,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAoBnE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAOrB,WAAW;CAS1B;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,gBAAgB,EAAE,MAAM,GAAG,cAAc,CAAC;AAEhF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,GAAG,cAAc,CAAC"}
@@ -1,5 +1,9 @@
1
+ // NOTE: Browser safety - we avoid throwing at module load so bundlers can include
2
+ // this file without crashing. A runtime error will be thrown inside `open()` if
3
+ // execution actually occurs in a browser.
4
+ const __isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
1
5
  import { Pool } from 'pg';
2
- import { normaliseParameters } from '../utils/parameterUtils';
6
+ import { normaliseParameters } from '../shared/parameterUtils';
3
7
  const isPositional = (statement) => statement.includes('?');
4
8
  const buildNamedStatement = (statement, named) => {
5
9
  const order = [];
@@ -134,6 +138,12 @@ const splitStatements = (script) => script
134
138
  * - Connection pool handles transient failures
135
139
  * - Falls back to SQLite if PostgreSQL unavailable
136
140
  */
141
+ /**
142
+ * Production-grade PostgreSQL adapter backed by pg.Pool.
143
+ *
144
+ * Safe to import in browser bundles; will only throw if `open()` is invoked
145
+ * in a browser environment.
146
+ */
137
147
  export class PostgresAdapter {
138
148
  constructor(options) {
139
149
  this.kind = 'postgres';
@@ -160,6 +170,9 @@ export class PostgresAdapter {
160
170
  if (this.pool) {
161
171
  return;
162
172
  }
173
+ if (__isBrowser) {
174
+ throw new Error('[StorageAdapter] PostgreSQL adapter cannot be opened in a browser environment.');
175
+ }
163
176
  // Build pool configuration
164
177
  const poolConfig = {};
165
178
  // Use connection string if provided
@@ -207,7 +220,11 @@ export class PostgresAdapter {
207
220
  const executor = await this.getExecutor();
208
221
  const { text, values } = prepareStatement(statement, parameters);
209
222
  const result = await executor.query(text, values);
210
- return { changes: result.rowCount ?? 0, lastInsertRowid: result.rows?.[0]?.id ?? null };
223
+ const firstRow = result.rows?.[0];
224
+ const lastInsertRowid = (firstRow && typeof firstRow === 'object' && 'id' in firstRow)
225
+ ? firstRow.id
226
+ : null;
227
+ return { changes: result.rowCount ?? 0, lastInsertRowid };
211
228
  }
212
229
  async get(statement, parameters) {
213
230
  const executor = await this.getExecutor();