database-devtools 0.1.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.
- package/LICENSE +5 -0
- package/dist/adapter/index.cjs +314 -0
- package/dist/adapter/index.cjs.map +1 -0
- package/dist/adapter/index.d.cts +34 -0
- package/dist/adapter/index.d.ts +34 -0
- package/dist/adapter/index.js +6 -0
- package/dist/adapter/index.js.map +1 -0
- package/dist/adapter-BjJm71wW.d.cts +30 -0
- package/dist/adapter-DJSjDewg.d.ts +30 -0
- package/dist/adapters/sqlite/index.cjs +251 -0
- package/dist/adapters/sqlite/index.cjs.map +1 -0
- package/dist/adapters/sqlite/index.d.cts +21 -0
- package/dist/adapters/sqlite/index.d.ts +21 -0
- package/dist/adapters/sqlite/index.js +6 -0
- package/dist/adapters/sqlite/index.js.map +1 -0
- package/dist/chunk-2JGL2JVD.js +52 -0
- package/dist/chunk-2JGL2JVD.js.map +1 -0
- package/dist/chunk-AZECU6D7.js +27 -0
- package/dist/chunk-AZECU6D7.js.map +1 -0
- package/dist/chunk-BLOSGEQV.js +71 -0
- package/dist/chunk-BLOSGEQV.js.map +1 -0
- package/dist/chunk-CPVVIH5G.js +258 -0
- package/dist/chunk-CPVVIH5G.js.map +1 -0
- package/dist/chunk-DGUM43GV.js +10 -0
- package/dist/chunk-DGUM43GV.js.map +1 -0
- package/dist/chunk-HIDZTOJ3.js +9 -0
- package/dist/chunk-HIDZTOJ3.js.map +1 -0
- package/dist/chunk-I65IM47D.js +243 -0
- package/dist/chunk-I65IM47D.js.map +1 -0
- package/dist/chunk-MXVIGMVT.js +3 -0
- package/dist/chunk-MXVIGMVT.js.map +1 -0
- package/dist/chunk-O6AO7KHA.js +3 -0
- package/dist/chunk-O6AO7KHA.js.map +1 -0
- package/dist/chunk-TNDOAHT5.js +1784 -0
- package/dist/chunk-TNDOAHT5.js.map +1 -0
- package/dist/chunk-ZS5MZR75.js +655 -0
- package/dist/chunk-ZS5MZR75.js.map +1 -0
- package/dist/cli.cjs +2053 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/client/index.cjs +947 -0
- package/dist/client/index.cjs.map +1 -0
- package/dist/client/index.d.cts +75 -0
- package/dist/client/index.d.ts +75 -0
- package/dist/client/index.js +98 -0
- package/dist/client/index.js.map +1 -0
- package/dist/createDevToolsServer-B7NQ_5H4.d.cts +292 -0
- package/dist/createDevToolsServer-DlNMoCJR.d.ts +292 -0
- package/dist/handleDeviceSnapshot-CR-4QMdk.d.ts +116 -0
- package/dist/handleDeviceSnapshot-cYGuitSc.d.cts +116 -0
- package/dist/index.cjs +5877 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +61 -0
- package/dist/index.d.ts +61 -0
- package/dist/index.js +2748 -0
- package/dist/index.js.map +1 -0
- package/dist/inspector/index.cjs +57 -0
- package/dist/inspector/index.cjs.map +1 -0
- package/dist/inspector/index.d.cts +26 -0
- package/dist/inspector/index.d.ts +26 -0
- package/dist/inspector/index.js +5 -0
- package/dist/inspector/index.js.map +1 -0
- package/dist/inspectors/sqlite/index.cjs +306 -0
- package/dist/inspectors/sqlite/index.cjs.map +1 -0
- package/dist/inspectors/sqlite/index.d.cts +53 -0
- package/dist/inspectors/sqlite/index.d.ts +53 -0
- package/dist/inspectors/sqlite/index.js +260 -0
- package/dist/inspectors/sqlite/index.js.map +1 -0
- package/dist/register-BuicFu9L.d.cts +32 -0
- package/dist/register-aITLN9Q9.d.ts +32 -0
- package/dist/server/index.cjs +1948 -0
- package/dist/server/index.cjs.map +1 -0
- package/dist/server/index.d.cts +15 -0
- package/dist/server/index.d.ts +15 -0
- package/dist/server/index.js +7 -0
- package/dist/server/index.js.map +1 -0
- package/dist/snapshot-Dhyecgo2.d.cts +33 -0
- package/dist/snapshot-Dhyecgo2.d.ts +33 -0
- package/dist/types/protocol.cjs +309 -0
- package/dist/types/protocol.cjs.map +1 -0
- package/dist/types/protocol.d.cts +291 -0
- package/dist/types/protocol.d.ts +291 -0
- package/dist/types/protocol.js +4 -0
- package/dist/types/protocol.js.map +1 -0
- package/dist/types-BRLJdBRY.d.cts +16 -0
- package/dist/types-CF6qEU-_.d.ts +16 -0
- package/dist/types-CIA11diJ.d.cts +62 -0
- package/dist/types-CKVRCX-e.d.ts +62 -0
- package/dist/web/assets/index-CLEaIsUd.css +1 -0
- package/dist/web/assets/index-DQrPRTOy.js +100 -0
- package/dist/web/assets/sql-wasm-UFUCzYNW.wasm +0 -0
- package/dist/web/index.html +26 -0
- package/dist/write-C3toEIMs.d.cts +21 -0
- package/dist/write-C3toEIMs.d.ts +21 -0
- package/package.json +137 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/adapter/errors.ts
|
|
4
|
+
var AdapterResolutionError = class extends Error {
|
|
5
|
+
constructor(supported, hint) {
|
|
6
|
+
super(formatAdapterResolutionMessage(supported, hint));
|
|
7
|
+
this.supported = supported;
|
|
8
|
+
this.hint = hint;
|
|
9
|
+
}
|
|
10
|
+
supported;
|
|
11
|
+
hint;
|
|
12
|
+
name = "AdapterResolutionError";
|
|
13
|
+
};
|
|
14
|
+
function formatAdapterResolutionMessage(supported, hint) {
|
|
15
|
+
const lines = [
|
|
16
|
+
"Unable to determine the database type.",
|
|
17
|
+
"",
|
|
18
|
+
"Supported databases:",
|
|
19
|
+
...supported.map((entry) => ` \u2022 ${entry.displayName}`),
|
|
20
|
+
"",
|
|
21
|
+
"Try specifying a type:",
|
|
22
|
+
' <DatabaseDevTools database={db} type="sqlite" />',
|
|
23
|
+
"",
|
|
24
|
+
"Or provide a custom adapter:",
|
|
25
|
+
" <DatabaseDevTools database={db} adapter={myAdapter} />"
|
|
26
|
+
];
|
|
27
|
+
if (hint === "install-package") {
|
|
28
|
+
lines.push(
|
|
29
|
+
"",
|
|
30
|
+
"For SQLite, install expo-sqlite:",
|
|
31
|
+
" npm install expo-sqlite"
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
return lines.join("\n");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// src/types/kind.ts
|
|
38
|
+
var DATABASE_DEVTOOLS_KIND = /* @__PURE__ */ Symbol.for("@database-devtools/kind");
|
|
39
|
+
function readDatabaseKindMarker(value) {
|
|
40
|
+
if (typeof value !== "object" || value === null) {
|
|
41
|
+
return void 0;
|
|
42
|
+
}
|
|
43
|
+
const marker = value[DATABASE_DEVTOOLS_KIND];
|
|
44
|
+
return typeof marker === "string" ? marker : void 0;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// src/adapter/registry.ts
|
|
48
|
+
var AdapterRegistry = class {
|
|
49
|
+
definitions = /* @__PURE__ */ new Map();
|
|
50
|
+
register(definition) {
|
|
51
|
+
this.definitions.set(definition.kind, definition);
|
|
52
|
+
}
|
|
53
|
+
get(kind) {
|
|
54
|
+
return this.definitions.get(kind);
|
|
55
|
+
}
|
|
56
|
+
listSupported() {
|
|
57
|
+
return [...this.definitions.values()].sort((left, right) => left.displayName.localeCompare(right.displayName)).map((definition) => ({
|
|
58
|
+
kind: definition.kind,
|
|
59
|
+
displayName: definition.displayName
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
detect(database) {
|
|
63
|
+
const markerKind = readDatabaseKindMarker(database);
|
|
64
|
+
if (markerKind) {
|
|
65
|
+
const marked = this.definitions.get(markerKind);
|
|
66
|
+
if (marked) {
|
|
67
|
+
return marked;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const matches = [...this.definitions.values()].filter((definition) => {
|
|
71
|
+
try {
|
|
72
|
+
return definition.detect(database);
|
|
73
|
+
} catch {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}).sort((left, right) => right.priority - left.priority);
|
|
77
|
+
return matches[0];
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
var globalRegistry = null;
|
|
81
|
+
function getAdapterRegistry() {
|
|
82
|
+
if (!globalRegistry) {
|
|
83
|
+
globalRegistry = new AdapterRegistry();
|
|
84
|
+
}
|
|
85
|
+
return globalRegistry;
|
|
86
|
+
}
|
|
87
|
+
function resetAdapterRegistry() {
|
|
88
|
+
globalRegistry = null;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// src/types/snapshot.ts
|
|
92
|
+
var SQLITE_SNAPSHOT_MIME_TYPE = "application/x-sqlite3";
|
|
93
|
+
|
|
94
|
+
// src/adapters/sqlite/buildWriteSql.ts
|
|
95
|
+
var IDENTIFIER_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
96
|
+
function quoteIdentifier(name) {
|
|
97
|
+
if (!IDENTIFIER_PATTERN.test(name)) {
|
|
98
|
+
throw new Error(`Invalid identifier: ${name}`);
|
|
99
|
+
}
|
|
100
|
+
return `"${name.replace(/"/g, '""')}"`;
|
|
101
|
+
}
|
|
102
|
+
function buildInsertSql(operation) {
|
|
103
|
+
const columns = Object.keys(operation.values);
|
|
104
|
+
if (columns.length === 0) {
|
|
105
|
+
throw new Error("Insert requires at least one column value");
|
|
106
|
+
}
|
|
107
|
+
const quotedColumns = columns.map(quoteIdentifier).join(", ");
|
|
108
|
+
const placeholders = columns.map(() => "?").join(", ");
|
|
109
|
+
const sql = `INSERT INTO ${quoteIdentifier(operation.table)} (${quotedColumns}) VALUES (${placeholders})`;
|
|
110
|
+
const params = columns.map((column) => operation.values[column] ?? null);
|
|
111
|
+
return { sql, params };
|
|
112
|
+
}
|
|
113
|
+
function buildUpdateSql(operation) {
|
|
114
|
+
const valueColumns = Object.keys(operation.values);
|
|
115
|
+
const pkColumns = Object.keys(operation.primaryKey);
|
|
116
|
+
if (valueColumns.length === 0) {
|
|
117
|
+
throw new Error("Update requires at least one column value");
|
|
118
|
+
}
|
|
119
|
+
if (pkColumns.length === 0) {
|
|
120
|
+
throw new Error("Update requires a primary key");
|
|
121
|
+
}
|
|
122
|
+
const setClause = valueColumns.map((column) => `${quoteIdentifier(column)} = ?`).join(", ");
|
|
123
|
+
const whereClause = pkColumns.map((column) => `${quoteIdentifier(column)} = ?`).join(" AND ");
|
|
124
|
+
const sql = `UPDATE ${quoteIdentifier(operation.table)} SET ${setClause} WHERE ${whereClause}`;
|
|
125
|
+
const params = [
|
|
126
|
+
...valueColumns.map((column) => operation.values[column] ?? null),
|
|
127
|
+
...pkColumns.map((column) => operation.primaryKey[column] ?? null)
|
|
128
|
+
];
|
|
129
|
+
return { sql, params };
|
|
130
|
+
}
|
|
131
|
+
function buildDeleteSql(operation) {
|
|
132
|
+
const pkColumns = Object.keys(operation.primaryKey);
|
|
133
|
+
if (pkColumns.length === 0) {
|
|
134
|
+
throw new Error("Delete requires a primary key");
|
|
135
|
+
}
|
|
136
|
+
const whereClause = pkColumns.map((column) => `${quoteIdentifier(column)} = ?`).join(" AND ");
|
|
137
|
+
const sql = `DELETE FROM ${quoteIdentifier(operation.table)} WHERE ${whereClause}`;
|
|
138
|
+
const params = pkColumns.map((column) => operation.primaryKey[column] ?? null);
|
|
139
|
+
return { sql, params };
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// src/adapters/sqlite/createExpoSqliteAdapter.ts
|
|
143
|
+
function createExpoSqliteAdapter(options) {
|
|
144
|
+
const { database } = options;
|
|
145
|
+
let inTransaction = false;
|
|
146
|
+
let operationQueue = Promise.resolve();
|
|
147
|
+
const enqueue = async (operation) => {
|
|
148
|
+
const next = operationQueue.then(operation);
|
|
149
|
+
operationQueue = next.then(
|
|
150
|
+
() => void 0,
|
|
151
|
+
() => void 0
|
|
152
|
+
);
|
|
153
|
+
return next;
|
|
154
|
+
};
|
|
155
|
+
const assertTransaction = () => {
|
|
156
|
+
if (!inTransaction) {
|
|
157
|
+
throw new Error("No open transaction. Call beginTransaction() first.");
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
const runWrite = async (operation) => {
|
|
161
|
+
assertTransaction();
|
|
162
|
+
let sql;
|
|
163
|
+
let params;
|
|
164
|
+
switch (operation.kind) {
|
|
165
|
+
case "insert": {
|
|
166
|
+
const built = buildInsertSql(operation);
|
|
167
|
+
sql = built.sql;
|
|
168
|
+
params = built.params;
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
case "update": {
|
|
172
|
+
const built = buildUpdateSql(operation);
|
|
173
|
+
sql = built.sql;
|
|
174
|
+
params = built.params;
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
case "delete": {
|
|
178
|
+
const built = buildDeleteSql(operation);
|
|
179
|
+
sql = built.sql;
|
|
180
|
+
params = built.params;
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
default: {
|
|
184
|
+
const exhaustive = operation;
|
|
185
|
+
throw new Error(`Unsupported write operation: ${exhaustive.kind}`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
const result = await database.runAsync(sql, params);
|
|
189
|
+
return { rowsAffected: result.changes };
|
|
190
|
+
};
|
|
191
|
+
return {
|
|
192
|
+
kind: "sqlite",
|
|
193
|
+
dialect: "sqlite",
|
|
194
|
+
id: options.id ?? database.databasePath,
|
|
195
|
+
name: options.name ?? "SQLite",
|
|
196
|
+
capabilities: {
|
|
197
|
+
exportSnapshot: true,
|
|
198
|
+
executeQuery: false,
|
|
199
|
+
listTables: false,
|
|
200
|
+
getSchema: false,
|
|
201
|
+
transactionalWrites: true,
|
|
202
|
+
observeChanges: false,
|
|
203
|
+
importSnapshot: false
|
|
204
|
+
},
|
|
205
|
+
async exportSnapshot() {
|
|
206
|
+
return enqueue(async () => {
|
|
207
|
+
if (inTransaction) {
|
|
208
|
+
throw new Error("Cannot export while a write transaction is open");
|
|
209
|
+
}
|
|
210
|
+
await database.execAsync("PRAGMA wal_checkpoint(FULL)");
|
|
211
|
+
const bytes = await database.serializeAsync();
|
|
212
|
+
return {
|
|
213
|
+
bytes,
|
|
214
|
+
mimeType: SQLITE_SNAPSHOT_MIME_TYPE,
|
|
215
|
+
kind: "sqlite",
|
|
216
|
+
exportedAt: Date.now()
|
|
217
|
+
};
|
|
218
|
+
});
|
|
219
|
+
},
|
|
220
|
+
async beginTransaction() {
|
|
221
|
+
return enqueue(async () => {
|
|
222
|
+
if (inTransaction) {
|
|
223
|
+
throw new Error("Transaction already open");
|
|
224
|
+
}
|
|
225
|
+
await database.execAsync("BEGIN IMMEDIATE");
|
|
226
|
+
inTransaction = true;
|
|
227
|
+
});
|
|
228
|
+
},
|
|
229
|
+
async commitTransaction() {
|
|
230
|
+
return enqueue(async () => {
|
|
231
|
+
assertTransaction();
|
|
232
|
+
try {
|
|
233
|
+
await database.execAsync("COMMIT");
|
|
234
|
+
} finally {
|
|
235
|
+
inTransaction = false;
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
},
|
|
239
|
+
async rollbackTransaction() {
|
|
240
|
+
return enqueue(async () => {
|
|
241
|
+
if (!inTransaction) {
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
try {
|
|
245
|
+
await database.execAsync("ROLLBACK");
|
|
246
|
+
} finally {
|
|
247
|
+
inTransaction = false;
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
},
|
|
251
|
+
executeWrite: (operation) => enqueue(() => runWrite(operation))
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// src/adapters/sqlite/detect.ts
|
|
256
|
+
function detectExpoSqlite(database) {
|
|
257
|
+
return typeof database === "object" && database !== null && typeof database.execAsync === "function" && typeof database.serializeAsync === "function" && typeof database.runAsync === "function" && typeof database.databasePath === "string";
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// src/adapters/sqlite/register.ts
|
|
261
|
+
var sqliteAdapterDefinition = {
|
|
262
|
+
kind: "sqlite",
|
|
263
|
+
displayName: "SQLite",
|
|
264
|
+
priority: 100,
|
|
265
|
+
detect: detectExpoSqlite,
|
|
266
|
+
create: (database) => createExpoSqliteAdapter({
|
|
267
|
+
database,
|
|
268
|
+
name: database.databasePath
|
|
269
|
+
})
|
|
270
|
+
};
|
|
271
|
+
function registerSqliteAdapter() {
|
|
272
|
+
getAdapterRegistry().register(sqliteAdapterDefinition);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// src/adapter/registerBuiltins.ts
|
|
276
|
+
async function registerBuiltInAdapters() {
|
|
277
|
+
registerSqliteAdapter();
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// src/adapter/resolveAdapter.ts
|
|
281
|
+
async function resolveAdapter(database, options = {}) {
|
|
282
|
+
if (options.adapter) {
|
|
283
|
+
return options.adapter;
|
|
284
|
+
}
|
|
285
|
+
if (!database) {
|
|
286
|
+
throw new AdapterResolutionError([], "adapter");
|
|
287
|
+
}
|
|
288
|
+
await registerBuiltInAdapters();
|
|
289
|
+
const registry = getAdapterRegistry();
|
|
290
|
+
if (options.type) {
|
|
291
|
+
const definition = registry.get(options.type);
|
|
292
|
+
if (!definition) {
|
|
293
|
+
throw new AdapterResolutionError(registry.listSupported(), "type");
|
|
294
|
+
}
|
|
295
|
+
return definition.create(database);
|
|
296
|
+
}
|
|
297
|
+
const detected = registry.detect(database);
|
|
298
|
+
if (!detected) {
|
|
299
|
+
throw new AdapterResolutionError(
|
|
300
|
+
registry.listSupported(),
|
|
301
|
+
registry.listSupported().length === 0 ? "install-package" : "type"
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
return detected.create(database);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
exports.AdapterRegistry = AdapterRegistry;
|
|
308
|
+
exports.AdapterResolutionError = AdapterResolutionError;
|
|
309
|
+
exports.getAdapterRegistry = getAdapterRegistry;
|
|
310
|
+
exports.registerBuiltInAdapters = registerBuiltInAdapters;
|
|
311
|
+
exports.resetAdapterRegistry = resetAdapterRegistry;
|
|
312
|
+
exports.resolveAdapter = resolveAdapter;
|
|
313
|
+
//# sourceMappingURL=index.cjs.map
|
|
314
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/adapter/errors.ts","../../src/types/kind.ts","../../src/adapter/registry.ts","../../src/types/snapshot.ts","../../src/adapters/sqlite/buildWriteSql.ts","../../src/adapters/sqlite/createExpoSqliteAdapter.ts","../../src/adapters/sqlite/detect.ts","../../src/adapters/sqlite/register.ts","../../src/adapter/registerBuiltins.ts","../../src/adapter/resolveAdapter.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["import type { DatabaseKind } from '../types/kind';\r\n\r\nexport type SupportedDatabase = {\r\n kind: DatabaseKind;\r\n displayName: string;\r\n};\r\n\r\nexport class AdapterResolutionError extends Error {\r\n readonly name = 'AdapterResolutionError';\r\n\r\n constructor(\r\n public readonly supported: SupportedDatabase[],\r\n public readonly hint: 'type' | 'adapter' | 'install-package',\r\n ) {\r\n super(formatAdapterResolutionMessage(supported, hint));\r\n }\r\n}\r\n\r\nexport function formatAdapterResolutionMessage(\r\n supported: SupportedDatabase[],\r\n hint: 'type' | 'adapter' | 'install-package',\r\n): string {\r\n const lines = [\r\n 'Unable to determine the database type.',\r\n '',\r\n 'Supported databases:',\r\n ...supported.map((entry) => ` • ${entry.displayName}`),\r\n '',\r\n 'Try specifying a type:',\r\n ' <DatabaseDevTools database={db} type=\"sqlite\" />',\r\n '',\r\n 'Or provide a custom adapter:',\r\n ' <DatabaseDevTools database={db} adapter={myAdapter} />',\r\n ];\r\n\r\n if (hint === 'install-package') {\r\n lines.push(\r\n '',\r\n 'For SQLite, install expo-sqlite:',\r\n ' npm install expo-sqlite',\r\n );\r\n }\r\n\r\n return lines.join('\\n');\r\n}\r\n","/** Supported database engine identifiers. */\r\nexport type DatabaseKind = 'sqlite' | 'realm' | 'duckdb' | (string & {});\r\n\r\nexport const DATABASE_DEVTOOLS_KIND = Symbol.for('@database-devtools/kind');\r\n\r\nexport function readDatabaseKindMarker(value: unknown): DatabaseKind | undefined {\r\n if (typeof value !== 'object' || value === null) {\r\n return undefined;\r\n }\r\n\r\n const marker = (value as Record<symbol, unknown>)[DATABASE_DEVTOOLS_KIND];\r\n\r\n return typeof marker === 'string' ? (marker as DatabaseKind) : undefined;\r\n}\r\n","import { readDatabaseKindMarker } from '../types/kind';\r\nimport type { AdapterDefinition } from './types';\r\n\r\nexport class AdapterRegistry {\r\n private readonly definitions = new Map<string, AdapterDefinition>();\r\n\r\n register(definition: AdapterDefinition): void {\r\n this.definitions.set(definition.kind, definition);\r\n }\r\n\r\n get(kind: string): AdapterDefinition | undefined {\r\n return this.definitions.get(kind);\r\n }\r\n\r\n listSupported(): { kind: string; displayName: string }[] {\r\n return [...this.definitions.values()]\r\n .sort((left, right) => left.displayName.localeCompare(right.displayName))\r\n .map((definition) => ({\r\n kind: definition.kind,\r\n displayName: definition.displayName,\r\n }));\r\n }\r\n\r\n detect(database: unknown): AdapterDefinition | undefined {\r\n const markerKind = readDatabaseKindMarker(database);\r\n\r\n if (markerKind) {\r\n const marked = this.definitions.get(markerKind);\r\n\r\n if (marked) {\r\n return marked;\r\n }\r\n }\r\n\r\n const matches = [...this.definitions.values()]\r\n .filter((definition) => {\r\n try {\r\n return definition.detect(database);\r\n } catch {\r\n return false;\r\n }\r\n })\r\n .sort((left, right) => right.priority - left.priority);\r\n\r\n return matches[0];\r\n }\r\n}\r\n\r\nlet globalRegistry: AdapterRegistry | null = null;\r\n\r\nexport function getAdapterRegistry(): AdapterRegistry {\r\n if (!globalRegistry) {\r\n globalRegistry = new AdapterRegistry();\r\n }\r\n\r\n return globalRegistry;\r\n}\r\n\r\nexport function resetAdapterRegistry(): void {\r\n globalRegistry = null;\r\n}\r\n","import type { DatabaseKind } from '../types/kind';\r\n\r\nexport const SNAPSHOT_KIND_HEADER = 'x-database-kind';\r\nexport const SNAPSHOT_MIME_HEADER = 'x-snapshot-mime-type';\r\nexport const SNAPSHOT_NAME_HEADER = 'x-database-name';\r\n\r\nexport const SQLITE_SNAPSHOT_MIME_TYPE = 'application/x-sqlite3';\r\n\r\nexport type SnapshotExport = {\r\n bytes: Uint8Array;\r\n mimeType: string;\r\n kind: DatabaseKind;\r\n exportedAt?: number;\r\n};\r\n","import type {\r\n DeleteOperation,\r\n InsertOperation,\r\n UpdateOperation,\r\n WriteCellValue,\r\n} from '../../types/write';\r\n\r\nconst IDENTIFIER_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;\r\n\r\nexport function quoteIdentifier(name: string): string {\r\n if (!IDENTIFIER_PATTERN.test(name)) {\r\n throw new Error(`Invalid identifier: ${name}`);\r\n }\r\n\r\n return `\"${name.replace(/\"/g, '\"\"')}\"`;\r\n}\r\n\r\nexport function buildInsertSql(operation: InsertOperation): { sql: string; params: WriteCellValue[] } {\r\n const columns = Object.keys(operation.values);\r\n\r\n if (columns.length === 0) {\r\n throw new Error('Insert requires at least one column value');\r\n }\r\n\r\n const quotedColumns = columns.map(quoteIdentifier).join(', ');\r\n const placeholders = columns.map(() => '?').join(', ');\r\n const sql = `INSERT INTO ${quoteIdentifier(operation.table)} (${quotedColumns}) VALUES (${placeholders})`;\r\n const params = columns.map((column) => operation.values[column] ?? null);\r\n\r\n return { sql, params };\r\n}\r\n\r\nexport function buildUpdateSql(operation: UpdateOperation): { sql: string; params: WriteCellValue[] } {\r\n const valueColumns = Object.keys(operation.values);\r\n const pkColumns = Object.keys(operation.primaryKey);\r\n\r\n if (valueColumns.length === 0) {\r\n throw new Error('Update requires at least one column value');\r\n }\r\n\r\n if (pkColumns.length === 0) {\r\n throw new Error('Update requires a primary key');\r\n }\r\n\r\n const setClause = valueColumns.map((column) => `${quoteIdentifier(column)} = ?`).join(', ');\r\n const whereClause = pkColumns.map((column) => `${quoteIdentifier(column)} = ?`).join(' AND ');\r\n const sql = `UPDATE ${quoteIdentifier(operation.table)} SET ${setClause} WHERE ${whereClause}`;\r\n const params = [\r\n ...valueColumns.map((column) => operation.values[column] ?? null),\r\n ...pkColumns.map((column) => operation.primaryKey[column] ?? null),\r\n ];\r\n\r\n return { sql, params };\r\n}\r\n\r\nexport function buildDeleteSql(operation: DeleteOperation): { sql: string; params: WriteCellValue[] } {\r\n const pkColumns = Object.keys(operation.primaryKey);\r\n\r\n if (pkColumns.length === 0) {\r\n throw new Error('Delete requires a primary key');\r\n }\r\n\r\n const whereClause = pkColumns.map((column) => `${quoteIdentifier(column)} = ?`).join(' AND ');\r\n const sql = `DELETE FROM ${quoteIdentifier(operation.table)} WHERE ${whereClause}`;\r\n const params = pkColumns.map((column) => operation.primaryKey[column] ?? null);\r\n\r\n return { sql, params };\r\n}\r\n","import type { WritableDatabaseAdapter } from '../../types/adapter';\r\nimport type { WriteOperation } from '../../types/write';\r\nimport { SQLITE_SNAPSHOT_MIME_TYPE } from '../../types/snapshot';\r\nimport {\r\n buildDeleteSql,\r\n buildInsertSql,\r\n buildUpdateSql,\r\n} from './buildWriteSql';\r\nimport type { ExpoSqliteDatabase } from './types';\r\n\r\nexport type CreateExpoSqliteAdapterOptions = {\r\n database: ExpoSqliteDatabase;\r\n id?: string;\r\n name?: string;\r\n};\r\n\r\nexport function createExpoSqliteAdapter(\r\n options: CreateExpoSqliteAdapterOptions,\r\n): WritableDatabaseAdapter {\r\n const { database } = options;\r\n let inTransaction = false;\r\n let operationQueue: Promise<void> = Promise.resolve();\r\n\r\n const enqueue = async <T>(operation: () => Promise<T>): Promise<T> => {\r\n const next = operationQueue.then(operation);\r\n operationQueue = next.then(\r\n () => undefined,\r\n () => undefined,\r\n );\r\n return next;\r\n };\r\n\r\n const assertTransaction = (): void => {\r\n if (!inTransaction) {\r\n throw new Error('No open transaction. Call beginTransaction() first.');\r\n }\r\n };\r\n\r\n const runWrite = async (operation: WriteOperation) => {\r\n assertTransaction();\r\n\r\n let sql: string;\r\n let params: unknown[];\r\n\r\n switch (operation.kind) {\r\n case 'insert': {\r\n const built = buildInsertSql(operation);\r\n sql = built.sql;\r\n params = built.params;\r\n break;\r\n }\r\n case 'update': {\r\n const built = buildUpdateSql(operation);\r\n sql = built.sql;\r\n params = built.params;\r\n break;\r\n }\r\n case 'delete': {\r\n const built = buildDeleteSql(operation);\r\n sql = built.sql;\r\n params = built.params;\r\n break;\r\n }\r\n default: {\r\n const exhaustive: never = operation;\r\n throw new Error(`Unsupported write operation: ${(exhaustive as WriteOperation).kind}`);\r\n }\r\n }\r\n\r\n const result = await database.runAsync(sql, params);\r\n return { rowsAffected: result.changes };\r\n };\r\n\r\n return {\r\n kind: 'sqlite',\r\n dialect: 'sqlite',\r\n id: options.id ?? database.databasePath,\r\n name: options.name ?? 'SQLite',\r\n capabilities: {\r\n exportSnapshot: true,\r\n executeQuery: false,\r\n listTables: false,\r\n getSchema: false,\r\n transactionalWrites: true,\r\n observeChanges: false,\r\n importSnapshot: false,\r\n },\r\n async exportSnapshot() {\r\n return enqueue(async () => {\r\n if (inTransaction) {\r\n throw new Error('Cannot export while a write transaction is open');\r\n }\r\n\r\n await database.execAsync('PRAGMA wal_checkpoint(FULL)');\r\n const bytes = await database.serializeAsync();\r\n\r\n return {\r\n bytes,\r\n mimeType: SQLITE_SNAPSHOT_MIME_TYPE,\r\n kind: 'sqlite' as const,\r\n exportedAt: Date.now(),\r\n };\r\n });\r\n },\r\n async beginTransaction() {\r\n return enqueue(async () => {\r\n if (inTransaction) {\r\n throw new Error('Transaction already open');\r\n }\r\n\r\n await database.execAsync('BEGIN IMMEDIATE');\r\n inTransaction = true;\r\n });\r\n },\r\n async commitTransaction() {\r\n return enqueue(async () => {\r\n assertTransaction();\r\n\r\n try {\r\n await database.execAsync('COMMIT');\r\n } finally {\r\n inTransaction = false;\r\n }\r\n });\r\n },\r\n async rollbackTransaction() {\r\n return enqueue(async () => {\r\n if (!inTransaction) {\r\n return;\r\n }\r\n\r\n try {\r\n await database.execAsync('ROLLBACK');\r\n } finally {\r\n inTransaction = false;\r\n }\r\n });\r\n },\r\n executeWrite: (operation) => enqueue(() => runWrite(operation)),\r\n };\r\n}\r\n","import type { ExpoSqliteDatabase, ExpoSqliteInspectableDatabase } from './types';\r\n\r\nexport function detectExpoSqlite(database: unknown): database is ExpoSqliteDatabase {\r\n return (\r\n typeof database === 'object' &&\r\n database !== null &&\r\n typeof (database as ExpoSqliteDatabase).execAsync === 'function' &&\r\n typeof (database as ExpoSqliteDatabase).serializeAsync === 'function' &&\r\n typeof (database as ExpoSqliteDatabase).runAsync === 'function' &&\r\n typeof (database as ExpoSqliteDatabase).databasePath === 'string'\r\n );\r\n}\r\n\r\nexport function detectExpoSqliteInspectable(\r\n database: unknown,\r\n): database is ExpoSqliteInspectableDatabase {\r\n return (\r\n detectExpoSqlite(database) &&\r\n typeof (database as ExpoSqliteInspectableDatabase).getAllAsync === 'function' &&\r\n typeof (database as ExpoSqliteInspectableDatabase).getFirstAsync === 'function'\r\n );\r\n}\r\n","import { getAdapterRegistry } from '../../adapter/registry';\r\nimport type { AdapterDefinition } from '../../adapter/types';\r\nimport { createExpoSqliteAdapter } from './createExpoSqliteAdapter';\r\nimport { detectExpoSqlite } from './detect';\r\nimport type { ExpoSqliteDatabase } from './types';\r\n\r\nexport const sqliteAdapterDefinition: AdapterDefinition = {\r\n kind: 'sqlite',\r\n displayName: 'SQLite',\r\n priority: 100,\r\n detect: detectExpoSqlite,\r\n create: (database) =>\r\n createExpoSqliteAdapter({\r\n database: database as ExpoSqliteDatabase,\r\n name: (database as ExpoSqliteDatabase).databasePath,\r\n }),\r\n};\r\n\r\nexport function registerSqliteAdapter(): void {\r\n getAdapterRegistry().register(sqliteAdapterDefinition);\r\n}\r\n","import { registerSqliteAdapter } from '../adapters/sqlite/register';\r\n\r\nexport async function registerBuiltInAdapters(): Promise<void> {\r\n registerSqliteAdapter();\r\n}\r\n","import type { DatabaseAdapter } from '../types/adapter';\r\nimport { AdapterResolutionError } from './errors';\r\nimport { getAdapterRegistry } from './registry';\r\nimport { registerBuiltInAdapters } from './registerBuiltins';\r\nimport type { ResolveAdapterOptions } from './types';\r\n\r\nexport async function resolveAdapter(\r\n database: unknown,\r\n options: ResolveAdapterOptions = {},\r\n): Promise<DatabaseAdapter> {\r\n if (options.adapter) {\r\n return options.adapter;\r\n }\r\n\r\n if (!database) {\r\n throw new AdapterResolutionError([], 'adapter');\r\n }\r\n\r\n await registerBuiltInAdapters();\r\n\r\n const registry = getAdapterRegistry();\r\n\r\n if (options.type) {\r\n const definition = registry.get(options.type);\r\n\r\n if (!definition) {\r\n throw new AdapterResolutionError(registry.listSupported(), 'type');\r\n }\r\n\r\n return definition.create(database);\r\n }\r\n\r\n const detected = registry.detect(database);\r\n\r\n if (!detected) {\r\n throw new AdapterResolutionError(\r\n registry.listSupported(),\r\n registry.listSupported().length === 0 ? 'install-package' : 'type',\r\n );\r\n }\r\n\r\n return detected.create(database);\r\n}\r\n"]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { A as AdapterDefinition, R as ResolveAdapterOptions } from '../types-BRLJdBRY.cjs';
|
|
2
|
+
import { D as DatabaseKind } from '../snapshot-Dhyecgo2.cjs';
|
|
3
|
+
import { D as DatabaseAdapter } from '../adapter-BjJm71wW.cjs';
|
|
4
|
+
import '../write-C3toEIMs.cjs';
|
|
5
|
+
|
|
6
|
+
type SupportedDatabase = {
|
|
7
|
+
kind: DatabaseKind;
|
|
8
|
+
displayName: string;
|
|
9
|
+
};
|
|
10
|
+
declare class AdapterResolutionError extends Error {
|
|
11
|
+
readonly supported: SupportedDatabase[];
|
|
12
|
+
readonly hint: 'type' | 'adapter' | 'install-package';
|
|
13
|
+
readonly name = "AdapterResolutionError";
|
|
14
|
+
constructor(supported: SupportedDatabase[], hint: 'type' | 'adapter' | 'install-package');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
declare class AdapterRegistry {
|
|
18
|
+
private readonly definitions;
|
|
19
|
+
register(definition: AdapterDefinition): void;
|
|
20
|
+
get(kind: string): AdapterDefinition | undefined;
|
|
21
|
+
listSupported(): {
|
|
22
|
+
kind: string;
|
|
23
|
+
displayName: string;
|
|
24
|
+
}[];
|
|
25
|
+
detect(database: unknown): AdapterDefinition | undefined;
|
|
26
|
+
}
|
|
27
|
+
declare function getAdapterRegistry(): AdapterRegistry;
|
|
28
|
+
declare function resetAdapterRegistry(): void;
|
|
29
|
+
|
|
30
|
+
declare function resolveAdapter(database: unknown, options?: ResolveAdapterOptions): Promise<DatabaseAdapter>;
|
|
31
|
+
|
|
32
|
+
declare function registerBuiltInAdapters(): Promise<void>;
|
|
33
|
+
|
|
34
|
+
export { AdapterDefinition, AdapterRegistry, AdapterResolutionError, ResolveAdapterOptions, getAdapterRegistry, registerBuiltInAdapters, resetAdapterRegistry, resolveAdapter };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { A as AdapterDefinition, R as ResolveAdapterOptions } from '../types-CF6qEU-_.js';
|
|
2
|
+
import { D as DatabaseKind } from '../snapshot-Dhyecgo2.js';
|
|
3
|
+
import { D as DatabaseAdapter } from '../adapter-DJSjDewg.js';
|
|
4
|
+
import '../write-C3toEIMs.js';
|
|
5
|
+
|
|
6
|
+
type SupportedDatabase = {
|
|
7
|
+
kind: DatabaseKind;
|
|
8
|
+
displayName: string;
|
|
9
|
+
};
|
|
10
|
+
declare class AdapterResolutionError extends Error {
|
|
11
|
+
readonly supported: SupportedDatabase[];
|
|
12
|
+
readonly hint: 'type' | 'adapter' | 'install-package';
|
|
13
|
+
readonly name = "AdapterResolutionError";
|
|
14
|
+
constructor(supported: SupportedDatabase[], hint: 'type' | 'adapter' | 'install-package');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
declare class AdapterRegistry {
|
|
18
|
+
private readonly definitions;
|
|
19
|
+
register(definition: AdapterDefinition): void;
|
|
20
|
+
get(kind: string): AdapterDefinition | undefined;
|
|
21
|
+
listSupported(): {
|
|
22
|
+
kind: string;
|
|
23
|
+
displayName: string;
|
|
24
|
+
}[];
|
|
25
|
+
detect(database: unknown): AdapterDefinition | undefined;
|
|
26
|
+
}
|
|
27
|
+
declare function getAdapterRegistry(): AdapterRegistry;
|
|
28
|
+
declare function resetAdapterRegistry(): void;
|
|
29
|
+
|
|
30
|
+
declare function resolveAdapter(database: unknown, options?: ResolveAdapterOptions): Promise<DatabaseAdapter>;
|
|
31
|
+
|
|
32
|
+
declare function registerBuiltInAdapters(): Promise<void>;
|
|
33
|
+
|
|
34
|
+
export { AdapterDefinition, AdapterRegistry, AdapterResolutionError, ResolveAdapterOptions, getAdapterRegistry, registerBuiltInAdapters, resetAdapterRegistry, resolveAdapter };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { AdapterResolutionError, registerBuiltInAdapters, resolveAdapter } from '../chunk-BLOSGEQV.js';
|
|
2
|
+
export { AdapterRegistry, getAdapterRegistry, resetAdapterRegistry } from '../chunk-I65IM47D.js';
|
|
3
|
+
import '../chunk-HIDZTOJ3.js';
|
|
4
|
+
import '../chunk-DGUM43GV.js';
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { D as DatabaseKind, A as AdapterCapabilities, S as SnapshotExport } from './snapshot-Dhyecgo2.cjs';
|
|
2
|
+
import { a as WriteOperation } from './write-C3toEIMs.cjs';
|
|
3
|
+
|
|
4
|
+
/** Database adapter interface for export and write operations on the live device. */
|
|
5
|
+
interface DatabaseAdapter {
|
|
6
|
+
readonly kind: DatabaseKind;
|
|
7
|
+
/** @deprecated Use `kind` instead. */
|
|
8
|
+
readonly dialect: DatabaseKind;
|
|
9
|
+
readonly id: string;
|
|
10
|
+
readonly name: string;
|
|
11
|
+
readonly capabilities: AdapterCapabilities;
|
|
12
|
+
exportSnapshot(): Promise<SnapshotExport>;
|
|
13
|
+
}
|
|
14
|
+
type WriteResult = {
|
|
15
|
+
rowsAffected: number;
|
|
16
|
+
};
|
|
17
|
+
/** Adapter that supports transactional writes on the live device database. */
|
|
18
|
+
interface WritableDatabaseAdapter extends DatabaseAdapter {
|
|
19
|
+
beginTransaction(): Promise<void>;
|
|
20
|
+
commitTransaction(): Promise<void>;
|
|
21
|
+
rollbackTransaction(): Promise<void>;
|
|
22
|
+
executeWrite(operation: WriteOperation): Promise<WriteResult>;
|
|
23
|
+
}
|
|
24
|
+
/** @deprecated Use `WritableDatabaseAdapter` instead. */
|
|
25
|
+
type EditableDatabaseAdapter = WritableDatabaseAdapter;
|
|
26
|
+
declare function isWritableDatabaseAdapter(adapter: DatabaseAdapter | undefined): adapter is WritableDatabaseAdapter;
|
|
27
|
+
/** @deprecated Use `isWritableDatabaseAdapter` instead. */
|
|
28
|
+
declare const isEditableDatabaseAdapter: typeof isWritableDatabaseAdapter;
|
|
29
|
+
|
|
30
|
+
export { type DatabaseAdapter as D, type EditableDatabaseAdapter as E, type WritableDatabaseAdapter as W, type WriteResult as a, isWritableDatabaseAdapter as b, isEditableDatabaseAdapter as i };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { D as DatabaseKind, A as AdapterCapabilities, S as SnapshotExport } from './snapshot-Dhyecgo2.js';
|
|
2
|
+
import { a as WriteOperation } from './write-C3toEIMs.js';
|
|
3
|
+
|
|
4
|
+
/** Database adapter interface for export and write operations on the live device. */
|
|
5
|
+
interface DatabaseAdapter {
|
|
6
|
+
readonly kind: DatabaseKind;
|
|
7
|
+
/** @deprecated Use `kind` instead. */
|
|
8
|
+
readonly dialect: DatabaseKind;
|
|
9
|
+
readonly id: string;
|
|
10
|
+
readonly name: string;
|
|
11
|
+
readonly capabilities: AdapterCapabilities;
|
|
12
|
+
exportSnapshot(): Promise<SnapshotExport>;
|
|
13
|
+
}
|
|
14
|
+
type WriteResult = {
|
|
15
|
+
rowsAffected: number;
|
|
16
|
+
};
|
|
17
|
+
/** Adapter that supports transactional writes on the live device database. */
|
|
18
|
+
interface WritableDatabaseAdapter extends DatabaseAdapter {
|
|
19
|
+
beginTransaction(): Promise<void>;
|
|
20
|
+
commitTransaction(): Promise<void>;
|
|
21
|
+
rollbackTransaction(): Promise<void>;
|
|
22
|
+
executeWrite(operation: WriteOperation): Promise<WriteResult>;
|
|
23
|
+
}
|
|
24
|
+
/** @deprecated Use `WritableDatabaseAdapter` instead. */
|
|
25
|
+
type EditableDatabaseAdapter = WritableDatabaseAdapter;
|
|
26
|
+
declare function isWritableDatabaseAdapter(adapter: DatabaseAdapter | undefined): adapter is WritableDatabaseAdapter;
|
|
27
|
+
/** @deprecated Use `isWritableDatabaseAdapter` instead. */
|
|
28
|
+
declare const isEditableDatabaseAdapter: typeof isWritableDatabaseAdapter;
|
|
29
|
+
|
|
30
|
+
export { type DatabaseAdapter as D, type EditableDatabaseAdapter as E, type WritableDatabaseAdapter as W, type WriteResult as a, isWritableDatabaseAdapter as b, isEditableDatabaseAdapter as i };
|