@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,54 @@
1
+ /**
2
+ * Data import utilities for cross-adapter migration and restoration.
3
+ * Supports importing from JSON, SQL dumps, and CSV files.
4
+ */
5
+ import type { StorageAdapter } from '../../core/contracts/index.js';
6
+ import type { ExportedData } from './dataExport.js';
7
+ /**
8
+ * Options for data import.
9
+ */
10
+ export interface DataImportOptions {
11
+ /** Drop existing tables before import */
12
+ dropTables?: boolean;
13
+ /** Skip schema creation (data only) */
14
+ skipSchema?: boolean;
15
+ /** Skip data import (schema only) */
16
+ skipData?: boolean;
17
+ /** Batch size for inserts */
18
+ batchSize?: number;
19
+ /** Tables to import (all if not specified) */
20
+ tables?: string[];
21
+ /** On conflict strategy */
22
+ onConflict?: 'replace' | 'ignore' | 'error';
23
+ }
24
+ /**
25
+ * Import result with statistics.
26
+ */
27
+ export interface ImportResult {
28
+ success: boolean;
29
+ tablesImported: number;
30
+ rowsImported: number;
31
+ errors?: string[];
32
+ duration: number;
33
+ }
34
+ /**
35
+ * Import data from exported JSON format.
36
+ */
37
+ export declare function importData(adapter: StorageAdapter, data: ExportedData, options?: DataImportOptions): Promise<ImportResult>;
38
+ /**
39
+ * Import data from JSON string.
40
+ */
41
+ export declare function importFromJSON(adapter: StorageAdapter, jsonString: string, options?: DataImportOptions): Promise<ImportResult>;
42
+ /**
43
+ * Import data from SQL dump.
44
+ */
45
+ export declare function importFromSQL(adapter: StorageAdapter, sqlDump: string, options?: DataImportOptions): Promise<ImportResult>;
46
+ /**
47
+ * Import data from CSV.
48
+ */
49
+ export declare function importFromCSV(adapter: StorageAdapter, tableName: string, csvContent: string, options?: DataImportOptions): Promise<ImportResult>;
50
+ /**
51
+ * Migrate data from one adapter to another.
52
+ */
53
+ export declare function migrateAdapter(sourceAdapter: StorageAdapter, targetAdapter: StorageAdapter, options?: DataImportOptions): Promise<ImportResult>;
54
+ //# sourceMappingURL=dataImport.d.ts.map
@@ -0,0 +1,300 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+ var dataImport_exports = {};
29
+ __export(dataImport_exports, {
30
+ importData: () => importData,
31
+ importFromCSV: () => importFromCSV,
32
+ importFromJSON: () => importFromJSON,
33
+ importFromSQL: () => importFromSQL,
34
+ migrateAdapter: () => migrateAdapter
35
+ });
36
+ module.exports = __toCommonJS(dataImport_exports);
37
+ var import_splitSqlStatements = require("../../shared/splitSqlStatements.js");
38
+ async function importData(adapter, data, options = {}) {
39
+ const startTime = Date.now();
40
+ const { dropTables = false, skipSchema = false, skipData = false, batchSize = 100, tables, onConflict = "error" } = options;
41
+ const errors = [];
42
+ let tablesImported = 0;
43
+ let rowsImported = 0;
44
+ let tablesToImport;
45
+ if (tables) {
46
+ tablesToImport = tables;
47
+ } else {
48
+ const dataTables = Object.keys(data.data);
49
+ const schemaTables = data.schema?.map((s) => s.name) || [];
50
+ tablesToImport = Array.from(/* @__PURE__ */ new Set([...dataTables, ...schemaTables]));
51
+ }
52
+ try {
53
+ if (!skipSchema && data.schema) {
54
+ for (const tableSchema of data.schema) {
55
+ if (!tablesToImport.includes(tableSchema.name))
56
+ continue;
57
+ try {
58
+ if (dropTables) {
59
+ await adapter.run(`DROP TABLE IF EXISTS ${escapeIdentifier(tableSchema.name)}`);
60
+ }
61
+ await createTable(adapter, tableSchema);
62
+ if (skipData) {
63
+ tablesImported++;
64
+ }
65
+ } catch (error) {
66
+ const errorMsg = `Schema error for ${tableSchema.name}: ${error.message}`;
67
+ errors.push(errorMsg);
68
+ if (onConflict === "error") {
69
+ return {
70
+ success: false,
71
+ tablesImported,
72
+ rowsImported,
73
+ errors,
74
+ duration: Date.now() - startTime
75
+ };
76
+ }
77
+ }
78
+ }
79
+ }
80
+ if (!skipData) {
81
+ for (const [tableName, rows] of Object.entries(data.data)) {
82
+ if (!tablesToImport.includes(tableName))
83
+ continue;
84
+ if (!Array.isArray(rows) || rows.length === 0)
85
+ continue;
86
+ try {
87
+ const imported = await importTableData(adapter, tableName, rows, {
88
+ batchSize,
89
+ onConflict
90
+ });
91
+ rowsImported += imported;
92
+ tablesImported++;
93
+ } catch (error) {
94
+ errors.push(`Data error for ${tableName}: ${error.message}`);
95
+ }
96
+ }
97
+ }
98
+ return {
99
+ success: errors.length === 0,
100
+ tablesImported,
101
+ rowsImported,
102
+ errors: errors.length > 0 ? errors : void 0,
103
+ duration: Date.now() - startTime
104
+ };
105
+ } catch (error) {
106
+ return {
107
+ success: false,
108
+ tablesImported,
109
+ rowsImported,
110
+ errors: [...errors, `Fatal error: ${error.message}`],
111
+ duration: Date.now() - startTime
112
+ };
113
+ }
114
+ }
115
+ async function importFromJSON(adapter, jsonString, options = {}) {
116
+ try {
117
+ const data = JSON.parse(jsonString);
118
+ return await importData(adapter, data, options);
119
+ } catch (error) {
120
+ return {
121
+ success: false,
122
+ tablesImported: 0,
123
+ rowsImported: 0,
124
+ errors: [`JSON parse error: ${error.message}`],
125
+ duration: 0
126
+ };
127
+ }
128
+ }
129
+ async function importFromSQL(adapter, sqlDump, options = {}) {
130
+ const startTime = Date.now();
131
+ const errors = [];
132
+ let statementsExecuted = 0;
133
+ try {
134
+ const statements = (0, import_splitSqlStatements.splitSqlStatements)(sqlDump);
135
+ for (const statement of statements) {
136
+ try {
137
+ if (options.tables) {
138
+ const matchesTable = options.tables.some((table) => statement.toLowerCase().includes(table.toLowerCase()));
139
+ if (!matchesTable)
140
+ continue;
141
+ }
142
+ await adapter.run(statement);
143
+ statementsExecuted++;
144
+ } catch (error) {
145
+ errors.push(`SQL error in statement: ${error.message}`);
146
+ }
147
+ }
148
+ return {
149
+ success: errors.length === 0,
150
+ tablesImported: statementsExecuted,
151
+ rowsImported: 0,
152
+ // Cannot accurately count from SQL
153
+ errors: errors.length > 0 ? errors : void 0,
154
+ duration: Date.now() - startTime
155
+ };
156
+ } catch (error) {
157
+ return {
158
+ success: false,
159
+ tablesImported: 0,
160
+ rowsImported: 0,
161
+ errors: [...errors, `Fatal error: ${error.message}`],
162
+ duration: Date.now() - startTime
163
+ };
164
+ }
165
+ }
166
+ async function importFromCSV(adapter, tableName, csvContent, options = {}) {
167
+ const startTime = Date.now();
168
+ try {
169
+ const rows = parseCSV(csvContent);
170
+ if (rows.length === 0) {
171
+ return {
172
+ success: true,
173
+ tablesImported: 0,
174
+ rowsImported: 0,
175
+ duration: Date.now() - startTime
176
+ };
177
+ }
178
+ const imported = await importTableData(adapter, tableName, rows, {
179
+ batchSize: options.batchSize || 100,
180
+ onConflict: options.onConflict || "error"
181
+ });
182
+ return {
183
+ success: true,
184
+ tablesImported: 1,
185
+ rowsImported: imported,
186
+ duration: Date.now() - startTime
187
+ };
188
+ } catch (error) {
189
+ return {
190
+ success: false,
191
+ tablesImported: 0,
192
+ rowsImported: 0,
193
+ errors: [`CSV import error: ${error.message}`],
194
+ duration: Date.now() - startTime
195
+ };
196
+ }
197
+ }
198
+ async function migrateAdapter(sourceAdapter, targetAdapter, options = {}) {
199
+ const { exportData } = await Promise.resolve().then(() => __toESM(require("./dataExport.js")));
200
+ const exportedData = await exportData(sourceAdapter, {
201
+ tables: options.tables,
202
+ includeSchema: !options.skipSchema
203
+ });
204
+ return await importData(targetAdapter, exportedData, options);
205
+ }
206
+ async function createTable(adapter, schema) {
207
+ if (schema.columns.length === 0) {
208
+ throw new Error(`Cannot create table ${schema.name} without column definitions`);
209
+ }
210
+ const columnDefs = schema.columns.map((col) => {
211
+ let def = `${escapeIdentifier(col.name)} ${col.type}`;
212
+ if (!col.nullable)
213
+ def += " NOT NULL";
214
+ if (col.defaultValue)
215
+ def += ` DEFAULT ${col.defaultValue}`;
216
+ return def;
217
+ });
218
+ const createSQL = `CREATE TABLE IF NOT EXISTS ${escapeIdentifier(schema.name)} (
219
+ ${columnDefs.join(",\n ")}
220
+ )`;
221
+ await adapter.run(createSQL);
222
+ }
223
+ async function importTableData(adapter, tableName, rows, options) {
224
+ let imported = 0;
225
+ const { batchSize, onConflict } = options;
226
+ for (let i = 0; i < rows.length; i += batchSize) {
227
+ const batch = rows.slice(i, i + batchSize);
228
+ for (const row of batch) {
229
+ const record = row;
230
+ const columns = Object.keys(record);
231
+ const placeholders = columns.map(() => "?");
232
+ let insertSQL = `INSERT `;
233
+ if (onConflict === "replace") {
234
+ insertSQL = `INSERT OR REPLACE `;
235
+ } else if (onConflict === "ignore") {
236
+ insertSQL = `INSERT OR IGNORE `;
237
+ }
238
+ insertSQL += `INTO ${escapeIdentifier(tableName)} (${columns.map(escapeIdentifier).join(", ")}) VALUES (${placeholders.join(", ")})`;
239
+ try {
240
+ await adapter.run(insertSQL, columns.map((col) => record[col]));
241
+ imported++;
242
+ } catch (error) {
243
+ if (onConflict === "error") {
244
+ throw error;
245
+ }
246
+ }
247
+ }
248
+ }
249
+ return imported;
250
+ }
251
+ function parseCSV(content) {
252
+ const lines = content.split("\n").filter((line) => line.trim().length > 0);
253
+ if (lines.length === 0)
254
+ return [];
255
+ const headers = parseCSVLine(lines[0]);
256
+ const rows = [];
257
+ for (let i = 1; i < lines.length; i++) {
258
+ const values = parseCSVLine(lines[i]);
259
+ const row = {};
260
+ headers.forEach((header, idx) => {
261
+ row[header] = values[idx] ?? null;
262
+ });
263
+ rows.push(row);
264
+ }
265
+ return rows;
266
+ }
267
+ function parseCSVLine(line) {
268
+ const values = [];
269
+ let current = "";
270
+ let inQuotes = false;
271
+ for (let i = 0; i < line.length; i++) {
272
+ const char = line[i];
273
+ if (char === '"') {
274
+ if (inQuotes && line[i + 1] === '"') {
275
+ current += '"';
276
+ i++;
277
+ } else {
278
+ inQuotes = !inQuotes;
279
+ }
280
+ } else if (char === "," && !inQuotes) {
281
+ values.push(current);
282
+ current = "";
283
+ } else {
284
+ current += char;
285
+ }
286
+ }
287
+ values.push(current);
288
+ return values;
289
+ }
290
+ function escapeIdentifier(identifier) {
291
+ return `"${identifier.replace(/"/g, '""')}"`;
292
+ }
293
+ // Annotate the CommonJS export names for ESM import in node:
294
+ 0 && (module.exports = {
295
+ importData,
296
+ importFromCSV,
297
+ importFromJSON,
298
+ importFromSQL,
299
+ migrateAdapter
300
+ });
@@ -0,0 +1,89 @@
1
+ /**
2
+ * High-level migration utilities for moving data between adapters.
3
+ * Simplifies common migration scenarios like local -> Supabase, Supabase -> local, etc.
4
+ */
5
+ import type { StorageAdapter } from '../../core/contracts/index.js';
6
+ import { type ImportResult, type DataImportOptions } from './dataImport.js';
7
+ /**
8
+ * Migration strategy for handling conflicts and errors.
9
+ */
10
+ export interface MigrationStrategy {
11
+ /** Whether to drop existing tables */
12
+ dropExisting?: boolean;
13
+ /** How to handle conflicts during import */
14
+ onConflict?: 'replace' | 'ignore' | 'error';
15
+ /** Whether to verify data after migration */
16
+ verify?: boolean;
17
+ /** Batch size for operations */
18
+ batchSize?: number;
19
+ /** Tables to migrate (all if not specified) */
20
+ tables?: string[];
21
+ }
22
+ /**
23
+ * Migration result with detailed statistics.
24
+ */
25
+ export interface MigrationResult extends ImportResult {
26
+ sourceAdapter: string;
27
+ targetAdapter: string;
28
+ verification?: VerificationResult;
29
+ }
30
+ /**
31
+ * Verification result after migration.
32
+ */
33
+ export interface VerificationResult {
34
+ passed: boolean;
35
+ tableCounts: Record<string, {
36
+ source: number;
37
+ target: number;
38
+ match: boolean;
39
+ }>;
40
+ errors?: string[];
41
+ }
42
+ /**
43
+ * Migrate from Better-SQLite3 (local) to Supabase.
44
+ */
45
+ export declare function migrateLocalToSupabase(localAdapter: StorageAdapter, supabaseAdapter: StorageAdapter, strategy?: MigrationStrategy): Promise<MigrationResult>;
46
+ /**
47
+ * Migrate from Supabase to Better-SQLite3 (local).
48
+ */
49
+ export declare function migrateSupabaseToLocal(supabaseAdapter: StorageAdapter, localAdapter: StorageAdapter, strategy?: MigrationStrategy): Promise<MigrationResult>;
50
+ /**
51
+ * Migrate from Supabase to PostgreSQL.
52
+ */
53
+ export declare function migrateSupabaseToPostgres(supabaseAdapter: StorageAdapter, postgresAdapter: StorageAdapter, strategy?: MigrationStrategy): Promise<MigrationResult>;
54
+ /**
55
+ * Migrate from SQL.js (browser) to Capacitor SQLite (mobile).
56
+ */
57
+ export declare function migrateBrowserToMobile(sqlJsAdapter: StorageAdapter, capacitorAdapter: StorageAdapter, strategy?: MigrationStrategy): Promise<MigrationResult>;
58
+ /**
59
+ * Generic migration between any two adapters.
60
+ */
61
+ export declare function migrateAdapters(sourceAdapter: StorageAdapter, targetAdapter: StorageAdapter, strategy?: MigrationStrategy): Promise<MigrationResult>;
62
+ /**
63
+ * Create a backup of an adapter to JSON file.
64
+ */
65
+ export declare function createBackup(adapter: StorageAdapter, options?: {
66
+ tables?: string[];
67
+ pretty?: boolean;
68
+ }): Promise<string>;
69
+ /**
70
+ * Restore from a backup JSON string.
71
+ */
72
+ export declare function restoreFromBackup(adapter: StorageAdapter, backupJSON: string, options?: DataImportOptions): Promise<ImportResult>;
73
+ /**
74
+ * Clone an adapter's data to another adapter.
75
+ */
76
+ export declare function cloneAdapter(sourceAdapter: StorageAdapter, targetAdapter: StorageAdapter, options?: MigrationStrategy): Promise<MigrationResult>;
77
+ /**
78
+ * Sync data between two adapters (bidirectional).
79
+ * NOTE: This is a simple implementation - for production use, implement proper conflict resolution.
80
+ */
81
+ export declare function syncAdapters(adapter1: StorageAdapter, adapter2: StorageAdapter, strategy?: MigrationStrategy): Promise<{
82
+ toAdapter2: MigrationResult;
83
+ toAdapter1: MigrationResult;
84
+ }>;
85
+ /**
86
+ * Get migration summary for display.
87
+ */
88
+ export declare function formatMigrationResult(result: MigrationResult): string;
89
+ //# sourceMappingURL=migration.d.ts.map
@@ -0,0 +1,187 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+ var migration_exports = {};
29
+ __export(migration_exports, {
30
+ cloneAdapter: () => cloneAdapter,
31
+ createBackup: () => createBackup,
32
+ formatMigrationResult: () => formatMigrationResult,
33
+ migrateAdapters: () => migrateAdapters,
34
+ migrateBrowserToMobile: () => migrateBrowserToMobile,
35
+ migrateLocalToSupabase: () => migrateLocalToSupabase,
36
+ migrateSupabaseToLocal: () => migrateSupabaseToLocal,
37
+ migrateSupabaseToPostgres: () => migrateSupabaseToPostgres,
38
+ restoreFromBackup: () => restoreFromBackup,
39
+ syncAdapters: () => syncAdapters
40
+ });
41
+ module.exports = __toCommonJS(migration_exports);
42
+ var import_dataExport = require("./dataExport.js");
43
+ var import_dataImport = require("./dataImport.js");
44
+ async function migrateLocalToSupabase(localAdapter, supabaseAdapter, strategy = {}) {
45
+ return await executeMigration(localAdapter, supabaseAdapter, "better-sqlite3", "supabase", strategy);
46
+ }
47
+ async function migrateSupabaseToLocal(supabaseAdapter, localAdapter, strategy = {}) {
48
+ return await executeMigration(supabaseAdapter, localAdapter, "supabase", "better-sqlite3", strategy);
49
+ }
50
+ async function migrateSupabaseToPostgres(supabaseAdapter, postgresAdapter, strategy = {}) {
51
+ return await executeMigration(supabaseAdapter, postgresAdapter, "supabase", "postgres", strategy);
52
+ }
53
+ async function migrateBrowserToMobile(sqlJsAdapter, capacitorAdapter, strategy = {}) {
54
+ return await executeMigration(sqlJsAdapter, capacitorAdapter, "sql.js", "capacitor-sqlite", strategy);
55
+ }
56
+ async function migrateAdapters(sourceAdapter, targetAdapter, strategy = {}) {
57
+ return await executeMigration(sourceAdapter, targetAdapter, "unknown", "unknown", strategy);
58
+ }
59
+ async function executeMigration(sourceAdapter, targetAdapter, sourceName, targetName, strategy) {
60
+ const importOptions = {
61
+ dropTables: strategy.dropExisting,
62
+ onConflict: strategy.onConflict,
63
+ batchSize: strategy.batchSize,
64
+ tables: strategy.tables
65
+ };
66
+ const result = await (0, import_dataImport.migrateAdapter)(sourceAdapter, targetAdapter, importOptions);
67
+ const migrationResult = {
68
+ ...result,
69
+ sourceAdapter: sourceName,
70
+ targetAdapter: targetName
71
+ };
72
+ if (strategy.verify && result.success) {
73
+ migrationResult.verification = await verifyMigration(sourceAdapter, targetAdapter, strategy.tables);
74
+ }
75
+ return migrationResult;
76
+ }
77
+ async function verifyMigration(sourceAdapter, targetAdapter, tables) {
78
+ const errors = [];
79
+ const tableCounts = {};
80
+ try {
81
+ const sourceData = await (0, import_dataExport.exportData)(sourceAdapter, { tables, includeSchema: false });
82
+ const targetData = await (0, import_dataExport.exportData)(targetAdapter, { tables, includeSchema: false });
83
+ for (const tableName of Object.keys(sourceData.data)) {
84
+ const sourceCount = sourceData.data[tableName]?.length || 0;
85
+ const targetCount = targetData.data[tableName]?.length || 0;
86
+ const match = sourceCount === targetCount;
87
+ tableCounts[tableName] = {
88
+ source: sourceCount,
89
+ target: targetCount,
90
+ match
91
+ };
92
+ if (!match) {
93
+ errors.push(`Table ${tableName}: source has ${sourceCount} rows, target has ${targetCount} rows`);
94
+ }
95
+ }
96
+ for (const tableName of Object.keys(targetData.data)) {
97
+ if (!sourceData.data[tableName]) {
98
+ errors.push(`Table ${tableName} exists in target but not in source`);
99
+ }
100
+ }
101
+ return {
102
+ passed: errors.length === 0,
103
+ tableCounts,
104
+ errors: errors.length > 0 ? errors : void 0
105
+ };
106
+ } catch (error) {
107
+ return {
108
+ passed: false,
109
+ tableCounts,
110
+ errors: [`Verification failed: ${error.message}`]
111
+ };
112
+ }
113
+ }
114
+ async function createBackup(adapter, options = {}) {
115
+ return await (0, import_dataExport.exportAsJSON)(adapter, {
116
+ tables: options.tables,
117
+ includeSchema: true,
118
+ pretty: options.pretty ?? true
119
+ });
120
+ }
121
+ async function restoreFromBackup(adapter, backupJSON, options = {}) {
122
+ const { importFromJSON } = await Promise.resolve().then(() => __toESM(require("./dataImport.js")));
123
+ return await importFromJSON(adapter, backupJSON, options);
124
+ }
125
+ async function cloneAdapter(sourceAdapter, targetAdapter, options = {}) {
126
+ return await migrateAdapters(sourceAdapter, targetAdapter, {
127
+ ...options,
128
+ verify: options.verify ?? true
129
+ });
130
+ }
131
+ async function syncAdapters(adapter1, adapter2, strategy = {}) {
132
+ const toAdapter2 = await migrateAdapters(adapter1, adapter2, {
133
+ ...strategy,
134
+ onConflict: "replace"
135
+ });
136
+ const toAdapter1 = await migrateAdapters(adapter2, adapter1, {
137
+ ...strategy,
138
+ onConflict: "replace"
139
+ });
140
+ return { toAdapter2, toAdapter1 };
141
+ }
142
+ function formatMigrationResult(result) {
143
+ const lines = [];
144
+ lines.push("=".repeat(60));
145
+ lines.push("Migration Result");
146
+ lines.push("=".repeat(60));
147
+ lines.push(`Source: ${result.sourceAdapter}`);
148
+ lines.push(`Target: ${result.targetAdapter}`);
149
+ lines.push(`Status: ${result.success ? "[OK] SUCCESS" : "[X] FAILED"}`);
150
+ lines.push(`Duration: ${result.duration}ms`);
151
+ lines.push(`Tables: ${result.tablesImported}`);
152
+ lines.push(`Rows: ${result.rowsImported}`);
153
+ if (result.errors && result.errors.length > 0) {
154
+ lines.push("\nErrors:");
155
+ result.errors.forEach((err) => lines.push(` [X] ${err}`));
156
+ }
157
+ if (result.verification) {
158
+ lines.push("\nVerification:");
159
+ lines.push(`Status: ${result.verification.passed ? "[OK] PASSED" : "[X] FAILED"}`);
160
+ if (Object.keys(result.verification.tableCounts).length > 0) {
161
+ lines.push("\nTable Counts:");
162
+ for (const [table, counts] of Object.entries(result.verification.tableCounts)) {
163
+ const status = counts.match ? "[OK]" : "[X]";
164
+ lines.push(` ${status} ${table}: source=${counts.source}, target=${counts.target}`);
165
+ }
166
+ }
167
+ if (result.verification.errors && result.verification.errors.length > 0) {
168
+ lines.push("\nVerification Errors:");
169
+ result.verification.errors.forEach((err) => lines.push(` [X] ${err}`));
170
+ }
171
+ }
172
+ lines.push("=".repeat(60));
173
+ return lines.join("\n");
174
+ }
175
+ // Annotate the CommonJS export names for ESM import in node:
176
+ 0 && (module.exports = {
177
+ cloneAdapter,
178
+ createBackup,
179
+ formatMigrationResult,
180
+ migrateAdapters,
181
+ migrateBrowserToMobile,
182
+ migrateLocalToSupabase,
183
+ migrateSupabaseToLocal,
184
+ migrateSupabaseToPostgres,
185
+ restoreFromBackup,
186
+ syncAdapters
187
+ });