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
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
// src/types/protocol.ts
|
|
2
|
+
var DevToolsRole = {
|
|
3
|
+
MOBILE: "mobile",
|
|
4
|
+
BROWSER: "browser"
|
|
5
|
+
};
|
|
6
|
+
var MessageType = {
|
|
7
|
+
REGISTER: "register",
|
|
8
|
+
PING: "ping",
|
|
9
|
+
PONG: "pong",
|
|
10
|
+
DEVICE_STATUS: "deviceStatus",
|
|
11
|
+
BROADCAST: "broadcast",
|
|
12
|
+
REFRESH_REQUEST: "refreshRequest",
|
|
13
|
+
SNAPSHOT_UPLOAD_REQUESTED: "snapshotUploadRequested",
|
|
14
|
+
REFRESH_STATUS: "refreshStatus",
|
|
15
|
+
SNAPSHOT_READY: "snapshotReady",
|
|
16
|
+
REFRESH_ERROR: "refreshError",
|
|
17
|
+
EXPORT_SNAPSHOT_REQUEST: "exportSnapshotRequest",
|
|
18
|
+
EXPORT_SNAPSHOT_ERROR: "exportSnapshotError",
|
|
19
|
+
BEGIN_TRANSACTION_REQUEST: "beginTransactionRequest",
|
|
20
|
+
COMMIT_TRANSACTION_REQUEST: "commitTransactionRequest",
|
|
21
|
+
ROLLBACK_TRANSACTION_REQUEST: "rollbackTransactionRequest",
|
|
22
|
+
WRITE_REQUEST: "writeRequest",
|
|
23
|
+
BEGIN_TRANSACTION: "beginTransaction",
|
|
24
|
+
COMMIT_TRANSACTION: "commitTransaction",
|
|
25
|
+
ROLLBACK_TRANSACTION: "rollbackTransaction",
|
|
26
|
+
EXECUTE_WRITE: "executeWrite",
|
|
27
|
+
TRANSACTION_ACK: "transactionAck",
|
|
28
|
+
WRITE_ACK: "writeAck",
|
|
29
|
+
TRANSACTION_STATUS: "transactionStatus",
|
|
30
|
+
WRITE_RESULT: "writeResult",
|
|
31
|
+
WRITE_ERROR: "writeError"
|
|
32
|
+
};
|
|
33
|
+
var DEVTOOLS_WS_PATH = "/ws";
|
|
34
|
+
var DEFAULT_DEVTOOLS_PORT = 3847;
|
|
35
|
+
var DEFAULT_DEVTOOLS_HOST = "0.0.0.0";
|
|
36
|
+
var HEARTBEAT_INTERVAL_MS = 3e4;
|
|
37
|
+
var HEARTBEAT_TIMEOUT_MS = 1e4;
|
|
38
|
+
var DEVICE_SNAPSHOT_API_PATH = "/api/devices";
|
|
39
|
+
var PROJECT_DATABASE_API_PATH = "/api/project/database";
|
|
40
|
+
var PROJECT_DATABASE_META_API_PATH = "/api/project/database/meta";
|
|
41
|
+
var PROJECT_DATABASES_API_PATH = "/api/project/databases";
|
|
42
|
+
var PROJECT_DEVICE_EXPORTS_API_PATH = "/api/project/devices";
|
|
43
|
+
var SNAPSHOT_API_PATH = DEVICE_SNAPSHOT_API_PATH;
|
|
44
|
+
var REFRESH_TIMEOUT_MS = 6e4;
|
|
45
|
+
var SYNC_TIMEOUT_MS = REFRESH_TIMEOUT_MS;
|
|
46
|
+
var WRITE_TRANSACTION_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
47
|
+
var MAX_SNAPSHOT_BYTES = 50 * 1024 * 1024;
|
|
48
|
+
function createMessage(message) {
|
|
49
|
+
return { ...message, timestamp: Date.now() };
|
|
50
|
+
}
|
|
51
|
+
function buildDevToolsHttpUrl(host = "localhost", port = DEFAULT_DEVTOOLS_PORT) {
|
|
52
|
+
return `http://${host}:${port}`;
|
|
53
|
+
}
|
|
54
|
+
function buildDevToolsWsUrl(host = "localhost", port = DEFAULT_DEVTOOLS_PORT) {
|
|
55
|
+
return `ws://${host}:${port}${DEVTOOLS_WS_PATH}`;
|
|
56
|
+
}
|
|
57
|
+
function buildDeviceSnapshotUrl(httpBaseUrl, deviceId) {
|
|
58
|
+
const base = httpBaseUrl.replace(/\/$/, "");
|
|
59
|
+
return `${base}${DEVICE_SNAPSHOT_API_PATH}/${encodeURIComponent(deviceId)}/snapshot`;
|
|
60
|
+
}
|
|
61
|
+
function buildSnapshotUrl(httpBaseUrl, deviceId) {
|
|
62
|
+
return buildDeviceSnapshotUrl(httpBaseUrl, deviceId);
|
|
63
|
+
}
|
|
64
|
+
function wsUrlToHttpUrl(wsUrl) {
|
|
65
|
+
const url = new URL(wsUrl);
|
|
66
|
+
url.protocol = url.protocol === "wss:" ? "https:" : "http:";
|
|
67
|
+
url.pathname = "";
|
|
68
|
+
url.search = "";
|
|
69
|
+
url.hash = "";
|
|
70
|
+
return url.toString().replace(/\/$/, "");
|
|
71
|
+
}
|
|
72
|
+
function hasMessageType(value) {
|
|
73
|
+
return typeof value === "object" && value !== null && typeof value.type === "string";
|
|
74
|
+
}
|
|
75
|
+
function isRegisterMessage(value) {
|
|
76
|
+
if (!hasMessageType(value) || value.type !== MessageType.REGISTER) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
const message = value;
|
|
80
|
+
return message.role === DevToolsRole.MOBILE || message.role === DevToolsRole.BROWSER;
|
|
81
|
+
}
|
|
82
|
+
function isPongMessage(value) {
|
|
83
|
+
if (!hasMessageType(value) || value.type !== MessageType.PONG) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
const message = value;
|
|
87
|
+
return typeof message.pingId === "string";
|
|
88
|
+
}
|
|
89
|
+
function isRefreshRequestMessage(value) {
|
|
90
|
+
if (!hasMessageType(value) || value.type !== MessageType.REFRESH_REQUEST) {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
const message = value;
|
|
94
|
+
return typeof message.deviceId === "string" && message.refreshType === "snapshot";
|
|
95
|
+
}
|
|
96
|
+
function isSnapshotUploadRequestedMessage(value) {
|
|
97
|
+
if (!hasMessageType(value) || value.type !== MessageType.SNAPSHOT_UPLOAD_REQUESTED) {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
const message = value;
|
|
101
|
+
return typeof message.deviceId === "string" && message.refreshType === "snapshot";
|
|
102
|
+
}
|
|
103
|
+
function isRefreshStatusMessage(value) {
|
|
104
|
+
if (!hasMessageType(value) || value.type !== MessageType.REFRESH_STATUS) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
const message = value;
|
|
108
|
+
return typeof message.deviceId === "string" && typeof message.state === "string";
|
|
109
|
+
}
|
|
110
|
+
function isSnapshotReadyMessage(value) {
|
|
111
|
+
if (!hasMessageType(value) || value.type !== MessageType.SNAPSHOT_READY) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
const message = value;
|
|
115
|
+
return typeof message.deviceId === "string" && typeof message.size === "number" && typeof message.exportedAt === "number" && typeof message.kind === "string" && typeof message.mimeType === "string";
|
|
116
|
+
}
|
|
117
|
+
function isRefreshErrorMessage(value) {
|
|
118
|
+
if (!hasMessageType(value) || value.type !== MessageType.REFRESH_ERROR) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
const message = value;
|
|
122
|
+
return typeof message.deviceId === "string" && typeof message.code === "string";
|
|
123
|
+
}
|
|
124
|
+
function isExportSnapshotRequestMessage(value) {
|
|
125
|
+
if (!hasMessageType(value) || value.type !== MessageType.EXPORT_SNAPSHOT_REQUEST) {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
const message = value;
|
|
129
|
+
return message.refreshType === "snapshot";
|
|
130
|
+
}
|
|
131
|
+
function isExportSnapshotErrorMessage(value) {
|
|
132
|
+
if (!hasMessageType(value) || value.type !== MessageType.EXPORT_SNAPSHOT_ERROR) {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
const message = value;
|
|
136
|
+
return typeof message.code === "string" && typeof message.message === "string";
|
|
137
|
+
}
|
|
138
|
+
function isBeginTransactionRequestMessage(value) {
|
|
139
|
+
if (!hasMessageType(value) || value.type !== MessageType.BEGIN_TRANSACTION_REQUEST) {
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
const message = value;
|
|
143
|
+
return typeof message.transactionId === "string" && typeof message.deviceId === "string";
|
|
144
|
+
}
|
|
145
|
+
function isCommitTransactionRequestMessage(value) {
|
|
146
|
+
if (!hasMessageType(value) || value.type !== MessageType.COMMIT_TRANSACTION_REQUEST) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
const message = value;
|
|
150
|
+
return typeof message.transactionId === "string" && typeof message.deviceId === "string";
|
|
151
|
+
}
|
|
152
|
+
function isRollbackTransactionRequestMessage(value) {
|
|
153
|
+
if (!hasMessageType(value) || value.type !== MessageType.ROLLBACK_TRANSACTION_REQUEST) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
const message = value;
|
|
157
|
+
return typeof message.transactionId === "string" && typeof message.deviceId === "string";
|
|
158
|
+
}
|
|
159
|
+
function isWriteRequestMessage(value) {
|
|
160
|
+
if (!hasMessageType(value) || value.type !== MessageType.WRITE_REQUEST) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
const message = value;
|
|
164
|
+
return typeof message.writeId === "string" && typeof message.transactionId === "string" && typeof message.deviceId === "string" && typeof message.operation === "object" && message.operation !== null;
|
|
165
|
+
}
|
|
166
|
+
function isTransactionAckMessage(value) {
|
|
167
|
+
if (!hasMessageType(value) || value.type !== MessageType.TRANSACTION_ACK) {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
const message = value;
|
|
171
|
+
return typeof message.transactionId === "string" && (message.action === "begin" || message.action === "commit" || message.action === "rollback") && typeof message.ok === "boolean";
|
|
172
|
+
}
|
|
173
|
+
function isWriteAckMessage(value) {
|
|
174
|
+
if (!hasMessageType(value) || value.type !== MessageType.WRITE_ACK) {
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
const message = value;
|
|
178
|
+
return typeof message.writeId === "string" && typeof message.transactionId === "string" && typeof message.ok === "boolean";
|
|
179
|
+
}
|
|
180
|
+
function isClientMessage(value) {
|
|
181
|
+
return isRegisterMessage(value) || isPongMessage(value) || isRefreshRequestMessage(value) || isExportSnapshotRequestMessage(value) || isBeginTransactionRequestMessage(value) || isCommitTransactionRequestMessage(value) || isRollbackTransactionRequestMessage(value) || isWriteRequestMessage(value) || isTransactionAckMessage(value) || isWriteAckMessage(value);
|
|
182
|
+
}
|
|
183
|
+
function isPingMessage(value) {
|
|
184
|
+
if (!hasMessageType(value) || value.type !== MessageType.PING) {
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
const message = value;
|
|
188
|
+
return typeof message.pingId === "string";
|
|
189
|
+
}
|
|
190
|
+
function isDeviceStatusMessage(value) {
|
|
191
|
+
if (!hasMessageType(value) || value.type !== MessageType.DEVICE_STATUS) {
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
const message = value;
|
|
195
|
+
return typeof message.payload === "object" && message.payload !== null;
|
|
196
|
+
}
|
|
197
|
+
function isBroadcastMessage(value) {
|
|
198
|
+
if (!hasMessageType(value) || value.type !== MessageType.BROADCAST) {
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
return true;
|
|
202
|
+
}
|
|
203
|
+
function isBeginTransactionMessage(value) {
|
|
204
|
+
if (!hasMessageType(value) || value.type !== MessageType.BEGIN_TRANSACTION) {
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
const message = value;
|
|
208
|
+
return typeof message.transactionId === "string";
|
|
209
|
+
}
|
|
210
|
+
function isCommitTransactionMessage(value) {
|
|
211
|
+
if (!hasMessageType(value) || value.type !== MessageType.COMMIT_TRANSACTION) {
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
const message = value;
|
|
215
|
+
return typeof message.transactionId === "string";
|
|
216
|
+
}
|
|
217
|
+
function isRollbackTransactionMessage(value) {
|
|
218
|
+
if (!hasMessageType(value) || value.type !== MessageType.ROLLBACK_TRANSACTION) {
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
const message = value;
|
|
222
|
+
return typeof message.transactionId === "string";
|
|
223
|
+
}
|
|
224
|
+
function isExecuteWriteMessage(value) {
|
|
225
|
+
if (!hasMessageType(value) || value.type !== MessageType.EXECUTE_WRITE) {
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
const message = value;
|
|
229
|
+
return typeof message.writeId === "string" && typeof message.transactionId === "string" && typeof message.operation === "object" && message.operation !== null;
|
|
230
|
+
}
|
|
231
|
+
function isTransactionStatusMessage(value) {
|
|
232
|
+
if (!hasMessageType(value) || value.type !== MessageType.TRANSACTION_STATUS) {
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
const message = value;
|
|
236
|
+
return typeof message.transactionId === "string" && typeof message.deviceId === "string" && typeof message.state === "string";
|
|
237
|
+
}
|
|
238
|
+
function isWriteResultMessage(value) {
|
|
239
|
+
if (!hasMessageType(value) || value.type !== MessageType.WRITE_RESULT) {
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
const message = value;
|
|
243
|
+
return typeof message.writeId === "string" && typeof message.transactionId === "string" && typeof message.rowsAffected === "number";
|
|
244
|
+
}
|
|
245
|
+
function isWriteErrorMessage(value) {
|
|
246
|
+
if (!hasMessageType(value) || value.type !== MessageType.WRITE_ERROR) {
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
const message = value;
|
|
250
|
+
return typeof message.transactionId === "string" && typeof message.code === "string";
|
|
251
|
+
}
|
|
252
|
+
function isServerMessage(value) {
|
|
253
|
+
return isPingMessage(value) || isDeviceStatusMessage(value) || isBroadcastMessage(value) || isSnapshotUploadRequestedMessage(value) || isRefreshStatusMessage(value) || isSnapshotReadyMessage(value) || isRefreshErrorMessage(value) || isExportSnapshotErrorMessage(value) || isBeginTransactionMessage(value) || isCommitTransactionMessage(value) || isRollbackTransactionMessage(value) || isExecuteWriteMessage(value) || isTransactionStatusMessage(value) || isWriteResultMessage(value) || isWriteErrorMessage(value);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
export { DEFAULT_DEVTOOLS_HOST, DEFAULT_DEVTOOLS_PORT, DEVICE_SNAPSHOT_API_PATH, DEVTOOLS_WS_PATH, DevToolsRole, HEARTBEAT_INTERVAL_MS, HEARTBEAT_TIMEOUT_MS, MAX_SNAPSHOT_BYTES, MessageType, PROJECT_DATABASES_API_PATH, PROJECT_DATABASE_API_PATH, PROJECT_DATABASE_META_API_PATH, PROJECT_DEVICE_EXPORTS_API_PATH, REFRESH_TIMEOUT_MS, SNAPSHOT_API_PATH, SYNC_TIMEOUT_MS, WRITE_TRANSACTION_TIMEOUT_MS, buildDevToolsHttpUrl, buildDevToolsWsUrl, buildDeviceSnapshotUrl, buildSnapshotUrl, createMessage, isBeginTransactionMessage, isBeginTransactionRequestMessage, isBroadcastMessage, isClientMessage, isCommitTransactionMessage, isCommitTransactionRequestMessage, isDeviceStatusMessage, isExecuteWriteMessage, isExportSnapshotErrorMessage, isExportSnapshotRequestMessage, isPingMessage, isPongMessage, isRefreshErrorMessage, isRefreshRequestMessage, isRefreshStatusMessage, isRegisterMessage, isRollbackTransactionMessage, isRollbackTransactionRequestMessage, isServerMessage, isSnapshotReadyMessage, isSnapshotUploadRequestedMessage, isTransactionAckMessage, isTransactionStatusMessage, isWriteAckMessage, isWriteErrorMessage, isWriteRequestMessage, isWriteResultMessage, wsUrlToHttpUrl };
|
|
257
|
+
//# sourceMappingURL=chunk-CPVVIH5G.js.map
|
|
258
|
+
//# sourceMappingURL=chunk-CPVVIH5G.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types/protocol.ts"],"names":[],"mappings":"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","file":"chunk-CPVVIH5G.js","sourcesContent":["import type { WriteOperation } from './write';\r\n\r\n/** Client and server roles on the WebSocket hub. */\r\nexport const DevToolsRole = {\r\n MOBILE: 'mobile',\r\n BROWSER: 'browser',\r\n} as const;\r\n\r\nexport type DevToolsRole = (typeof DevToolsRole)[keyof typeof DevToolsRole];\r\n\r\n/** All wire message type identifiers. */\r\nexport const MessageType = {\r\n REGISTER: 'register',\r\n PING: 'ping',\r\n PONG: 'pong',\r\n DEVICE_STATUS: 'deviceStatus',\r\n BROADCAST: 'broadcast',\r\n REFRESH_REQUEST: 'refreshRequest',\r\n SNAPSHOT_UPLOAD_REQUESTED: 'snapshotUploadRequested',\r\n REFRESH_STATUS: 'refreshStatus',\r\n SNAPSHOT_READY: 'snapshotReady',\r\n REFRESH_ERROR: 'refreshError',\r\n EXPORT_SNAPSHOT_REQUEST: 'exportSnapshotRequest',\r\n EXPORT_SNAPSHOT_ERROR: 'exportSnapshotError',\r\n BEGIN_TRANSACTION_REQUEST: 'beginTransactionRequest',\r\n COMMIT_TRANSACTION_REQUEST: 'commitTransactionRequest',\r\n ROLLBACK_TRANSACTION_REQUEST: 'rollbackTransactionRequest',\r\n WRITE_REQUEST: 'writeRequest',\r\n BEGIN_TRANSACTION: 'beginTransaction',\r\n COMMIT_TRANSACTION: 'commitTransaction',\r\n ROLLBACK_TRANSACTION: 'rollbackTransaction',\r\n EXECUTE_WRITE: 'executeWrite',\r\n TRANSACTION_ACK: 'transactionAck',\r\n WRITE_ACK: 'writeAck',\r\n TRANSACTION_STATUS: 'transactionStatus',\r\n WRITE_RESULT: 'writeResult',\r\n WRITE_ERROR: 'writeError',\r\n} as const;\r\n\r\nexport type MessageTypeValue = (typeof MessageType)[keyof typeof MessageType];\r\n\r\n/** Shared base for every protocol message. */\r\nexport interface DevToolsMessageBase {\r\n type: MessageTypeValue;\r\n timestamp: number;\r\n}\r\n\r\nexport type DeviceMetadata = {\r\n platform?: string;\r\n appName?: string;\r\n [key: string]: string | undefined;\r\n};\r\n\r\n/** Client → Server: register role on connect. */\r\nexport interface RegisterMessage extends DevToolsMessageBase {\r\n type: typeof MessageType.REGISTER;\r\n role: DevToolsRole;\r\n deviceId?: string;\r\n metadata?: DeviceMetadata;\r\n}\r\n\r\n/** Server → Client: heartbeat probe. */\r\nexport interface PingMessage extends DevToolsMessageBase {\r\n type: typeof MessageType.PING;\r\n pingId: string;\r\n}\r\n\r\n/** Client → Server: heartbeat response. */\r\nexport interface PongMessage extends DevToolsMessageBase {\r\n type: typeof MessageType.PONG;\r\n pingId: string;\r\n}\r\n\r\nexport type BrowserConnectionInfo = {\r\n connectionId: string;\r\n connectedAt: number;\r\n};\r\n\r\nexport type MobileDeviceInfo = {\r\n deviceId: string;\r\n connectionId: string;\r\n connectedAt: number;\r\n metadata?: DeviceMetadata;\r\n};\r\n\r\nexport type DeviceStatusPayload = {\r\n browserCount: number;\r\n mobileCount: number;\r\n browsers: BrowserConnectionInfo[];\r\n mobiles: MobileDeviceInfo[];\r\n};\r\n\r\n/** Server → Client: hub snapshot after connect/disconnect. */\r\nexport interface DeviceStatusMessage extends DevToolsMessageBase {\r\n type: typeof MessageType.DEVICE_STATUS;\r\n payload: DeviceStatusPayload;\r\n}\r\n\r\n/** Server → Client: generic routed envelope for future features. */\r\nexport interface BroadcastMessage extends DevToolsMessageBase {\r\n type: typeof MessageType.BROADCAST;\r\n payload: unknown;\r\n}\r\n\r\nexport type RefreshType = 'snapshot';\r\n\r\nexport type RefreshState =\r\n | 'requested'\r\n | 'exporting'\r\n | 'uploading'\r\n | 'ready'\r\n | 'failed'\r\n | 'timeout';\r\n\r\n/** @deprecated Use RefreshState */\r\nexport type SyncState = RefreshState;\r\n\r\nexport type RefreshErrorCode =\r\n | 'DEVICE_OFFLINE'\r\n | 'REFRESH_IN_PROGRESS'\r\n | 'EXPORT_FAILED'\r\n | 'UPLOAD_FAILED'\r\n | 'TIMEOUT'\r\n | 'SNAPSHOT_NOT_FOUND'\r\n | 'INVALID_REQUEST';\r\n\r\n/** @deprecated Use RefreshErrorCode */\r\nexport type SyncErrorCode = RefreshErrorCode;\r\n\r\n/** Browser → Server: request a database snapshot from a mobile device. */\r\nexport interface RefreshRequestMessage extends DevToolsMessageBase {\r\n type: typeof MessageType.REFRESH_REQUEST;\r\n deviceId: string;\r\n refreshType: RefreshType;\r\n}\r\n\r\n/** Server → Mobile: export database and upload via REST. */\r\nexport interface SnapshotUploadRequestedMessage extends DevToolsMessageBase {\r\n type: typeof MessageType.SNAPSHOT_UPLOAD_REQUESTED;\r\n deviceId: string;\r\n refreshType: RefreshType;\r\n}\r\n\r\n/** Server → Browser: refresh progress update. */\r\nexport interface RefreshStatusMessage extends DevToolsMessageBase {\r\n type: typeof MessageType.REFRESH_STATUS;\r\n deviceId: string;\r\n state: RefreshState;\r\n message?: string;\r\n}\r\n\r\n/** Server → Browser: snapshot uploaded and ready to download. */\r\nexport interface SnapshotReadyMessage extends DevToolsMessageBase {\r\n type: typeof MessageType.SNAPSHOT_READY;\r\n deviceId: string;\r\n size: number;\r\n exportedAt: number;\r\n kind: string;\r\n mimeType: string;\r\n databaseName?: string;\r\n}\r\n\r\n/** Server → Browser: refresh failed. */\r\nexport interface RefreshErrorMessage extends DevToolsMessageBase {\r\n type: typeof MessageType.REFRESH_ERROR;\r\n deviceId: string;\r\n code: RefreshErrorCode;\r\n message: string;\r\n}\r\n\r\n/** Mobile → Server: push database snapshot to the web inspector. */\r\nexport interface ExportSnapshotRequestMessage extends DevToolsMessageBase {\r\n type: typeof MessageType.EXPORT_SNAPSHOT_REQUEST;\r\n refreshType: RefreshType;\r\n}\r\n\r\n/** Server → Mobile: export request failed before upload. */\r\nexport interface ExportSnapshotErrorMessage extends DevToolsMessageBase {\r\n type: typeof MessageType.EXPORT_SNAPSHOT_ERROR;\r\n code: RefreshErrorCode;\r\n message: string;\r\n}\r\n\r\nexport type RefreshInitiator = 'browser' | 'mobile';\r\n\r\nexport type TransactionStatusState =\r\n | 'idle'\r\n | 'opening'\r\n | 'open'\r\n | 'committing'\r\n | 'rolling_back'\r\n | 'failed';\r\n\r\nexport type WriteErrorCode =\r\n | 'DEVICE_OFFLINE'\r\n | 'NO_TRANSACTION'\r\n | 'TRANSACTION_BUSY'\r\n | 'INVALID_OPERATION'\r\n | 'WRITE_FAILED'\r\n | 'ADAPTER_ERROR'\r\n | 'TIMEOUT';\r\n\r\n/** Browser → Server: open a write transaction on a device. */\r\nexport interface BeginTransactionRequestMessage extends DevToolsMessageBase {\r\n type: typeof MessageType.BEGIN_TRANSACTION_REQUEST;\r\n transactionId: string;\r\n deviceId: string;\r\n}\r\n\r\n/** Browser → Server: commit the active transaction. */\r\nexport interface CommitTransactionRequestMessage extends DevToolsMessageBase {\r\n type: typeof MessageType.COMMIT_TRANSACTION_REQUEST;\r\n transactionId: string;\r\n deviceId: string;\r\n}\r\n\r\n/** Browser → Server: roll back the active transaction. */\r\nexport interface RollbackTransactionRequestMessage extends DevToolsMessageBase {\r\n type: typeof MessageType.ROLLBACK_TRANSACTION_REQUEST;\r\n transactionId: string;\r\n deviceId: string;\r\n}\r\n\r\n/** Browser → Server: execute a structured write inside a transaction. */\r\nexport interface WriteRequestMessage extends DevToolsMessageBase {\r\n type: typeof MessageType.WRITE_REQUEST;\r\n writeId: string;\r\n transactionId: string;\r\n deviceId: string;\r\n operation: WriteOperation;\r\n}\r\n\r\n/** Server → Mobile: begin a transaction on the live database. */\r\nexport interface BeginTransactionMessage extends DevToolsMessageBase {\r\n type: typeof MessageType.BEGIN_TRANSACTION;\r\n transactionId: string;\r\n}\r\n\r\n/** Server → Mobile: commit the open transaction. */\r\nexport interface CommitTransactionMessage extends DevToolsMessageBase {\r\n type: typeof MessageType.COMMIT_TRANSACTION;\r\n transactionId: string;\r\n}\r\n\r\n/** Server → Mobile: roll back the open transaction. */\r\nexport interface RollbackTransactionMessage extends DevToolsMessageBase {\r\n type: typeof MessageType.ROLLBACK_TRANSACTION;\r\n transactionId: string;\r\n}\r\n\r\n/** Server → Mobile: run a structured write operation. */\r\nexport interface ExecuteWriteMessage extends DevToolsMessageBase {\r\n type: typeof MessageType.EXECUTE_WRITE;\r\n writeId: string;\r\n transactionId: string;\r\n operation: WriteOperation;\r\n}\r\n\r\n/** Mobile → Server: transaction lifecycle acknowledgement. */\r\nexport interface TransactionAckMessage extends DevToolsMessageBase {\r\n type: typeof MessageType.TRANSACTION_ACK;\r\n transactionId: string;\r\n action: 'begin' | 'commit' | 'rollback';\r\n ok: boolean;\r\n message?: string;\r\n}\r\n\r\n/** Mobile → Server: write operation acknowledgement. */\r\nexport interface WriteAckMessage extends DevToolsMessageBase {\r\n type: typeof MessageType.WRITE_ACK;\r\n writeId: string;\r\n transactionId: string;\r\n ok: boolean;\r\n rowsAffected?: number;\r\n message?: string;\r\n}\r\n\r\n/** Server → Browser: transaction state update. */\r\nexport interface TransactionStatusMessage extends DevToolsMessageBase {\r\n type: typeof MessageType.TRANSACTION_STATUS;\r\n transactionId: string;\r\n deviceId: string;\r\n state: TransactionStatusState;\r\n message?: string;\r\n}\r\n\r\n/** Server → Browser: write succeeded. */\r\nexport interface WriteResultMessage extends DevToolsMessageBase {\r\n type: typeof MessageType.WRITE_RESULT;\r\n writeId: string;\r\n transactionId: string;\r\n rowsAffected: number;\r\n}\r\n\r\n/** Server → Browser: write or transaction failed. */\r\nexport interface WriteErrorMessage extends DevToolsMessageBase {\r\n type: typeof MessageType.WRITE_ERROR;\r\n transactionId: string;\r\n writeId?: string;\r\n code: WriteErrorCode;\r\n message: string;\r\n}\r\n\r\nexport type ClientMessage =\r\n | RegisterMessage\r\n | PongMessage\r\n | RefreshRequestMessage\r\n | ExportSnapshotRequestMessage\r\n | BeginTransactionRequestMessage\r\n | CommitTransactionRequestMessage\r\n | RollbackTransactionRequestMessage\r\n | WriteRequestMessage\r\n | TransactionAckMessage\r\n | WriteAckMessage;\r\n\r\nexport type ServerMessage =\r\n | PingMessage\r\n | DeviceStatusMessage\r\n | BroadcastMessage\r\n | SnapshotUploadRequestedMessage\r\n | RefreshStatusMessage\r\n | SnapshotReadyMessage\r\n | RefreshErrorMessage\r\n | ExportSnapshotErrorMessage\r\n | BeginTransactionMessage\r\n | CommitTransactionMessage\r\n | RollbackTransactionMessage\r\n | ExecuteWriteMessage\r\n | TransactionStatusMessage\r\n | WriteResultMessage\r\n | WriteErrorMessage;\r\n\r\nexport type DevToolsMessage = ClientMessage | ServerMessage;\r\n\r\nexport const DEVTOOLS_WS_PATH = '/ws';\r\n\r\nexport const DEFAULT_DEVTOOLS_PORT = 3847;\r\n\r\nexport const DEFAULT_DEVTOOLS_HOST = '0.0.0.0';\r\n\r\nexport const HEARTBEAT_INTERVAL_MS = 30_000;\r\n\r\nexport const HEARTBEAT_TIMEOUT_MS = 10_000;\r\n\r\nexport const DEVICE_SNAPSHOT_API_PATH = '/api/devices';\r\n\r\nexport const PROJECT_DATABASE_API_PATH = '/api/project/database';\r\n\r\nexport const PROJECT_DATABASE_META_API_PATH = '/api/project/database/meta';\r\n\r\nexport const PROJECT_DATABASES_API_PATH = '/api/project/databases';\r\n\r\nexport const PROJECT_DEVICE_EXPORTS_API_PATH = '/api/project/devices';\r\n\r\n/** @deprecated Use DEVICE_SNAPSHOT_API_PATH */\r\nexport const SNAPSHOT_API_PATH = DEVICE_SNAPSHOT_API_PATH;\r\n\r\nexport const REFRESH_TIMEOUT_MS = 60_000;\r\n\r\n/** @deprecated Use REFRESH_TIMEOUT_MS */\r\nexport const SYNC_TIMEOUT_MS = REFRESH_TIMEOUT_MS;\r\n\r\nexport const WRITE_TRANSACTION_TIMEOUT_MS = 5 * 60 * 1000;\r\n\r\nexport const MAX_SNAPSHOT_BYTES = 50 * 1024 * 1024;\r\n\r\nexport function createMessage<T extends DevToolsMessageBase>(\r\n message: Omit<T, 'timestamp'>,\r\n): T {\r\n return { ...message, timestamp: Date.now() } as T;\r\n}\r\n\r\nexport function buildDevToolsHttpUrl(\r\n host = 'localhost',\r\n port = DEFAULT_DEVTOOLS_PORT,\r\n): string {\r\n return `http://${host}:${port}`;\r\n}\r\n\r\nexport function buildDevToolsWsUrl(\r\n host = 'localhost',\r\n port = DEFAULT_DEVTOOLS_PORT,\r\n): string {\r\n return `ws://${host}:${port}${DEVTOOLS_WS_PATH}`;\r\n}\r\n\r\nexport function buildDeviceSnapshotUrl(httpBaseUrl: string, deviceId: string): string {\r\n const base = httpBaseUrl.replace(/\\/$/, '');\r\n return `${base}${DEVICE_SNAPSHOT_API_PATH}/${encodeURIComponent(deviceId)}/snapshot`;\r\n}\r\n\r\n/** @deprecated Use buildDeviceSnapshotUrl */\r\nexport function buildSnapshotUrl(httpBaseUrl: string, deviceId: string): string {\r\n return buildDeviceSnapshotUrl(httpBaseUrl, deviceId);\r\n}\r\n\r\nexport function wsUrlToHttpUrl(wsUrl: string): string {\r\n const url = new URL(wsUrl);\r\n url.protocol = url.protocol === 'wss:' ? 'https:' : 'http:';\r\n url.pathname = '';\r\n url.search = '';\r\n url.hash = '';\r\n return url.toString().replace(/\\/$/, '');\r\n}\r\n\r\nfunction hasMessageType(value: unknown): value is { type: string } {\r\n return typeof value === 'object' && value !== null && typeof (value as { type: unknown }).type === 'string';\r\n}\r\n\r\nexport function isRegisterMessage(value: unknown): value is RegisterMessage {\r\n if (!hasMessageType(value) || value.type !== MessageType.REGISTER) {\r\n return false;\r\n }\r\n\r\n const message = value as RegisterMessage;\r\n return (\r\n message.role === DevToolsRole.MOBILE || message.role === DevToolsRole.BROWSER\r\n );\r\n}\r\n\r\nexport function isPongMessage(value: unknown): value is PongMessage {\r\n if (!hasMessageType(value) || value.type !== MessageType.PONG) {\r\n return false;\r\n }\r\n\r\n const message = value as PongMessage;\r\n return typeof message.pingId === 'string';\r\n}\r\n\r\nexport function isRefreshRequestMessage(value: unknown): value is RefreshRequestMessage {\r\n if (!hasMessageType(value) || value.type !== MessageType.REFRESH_REQUEST) {\r\n return false;\r\n }\r\n\r\n const message = value as RefreshRequestMessage;\r\n return typeof message.deviceId === 'string' && message.refreshType === 'snapshot';\r\n}\r\n\r\nexport function isSnapshotUploadRequestedMessage(\r\n value: unknown,\r\n): value is SnapshotUploadRequestedMessage {\r\n if (!hasMessageType(value) || value.type !== MessageType.SNAPSHOT_UPLOAD_REQUESTED) {\r\n return false;\r\n }\r\n\r\n const message = value as SnapshotUploadRequestedMessage;\r\n return typeof message.deviceId === 'string' && message.refreshType === 'snapshot';\r\n}\r\n\r\nexport function isRefreshStatusMessage(value: unknown): value is RefreshStatusMessage {\r\n if (!hasMessageType(value) || value.type !== MessageType.REFRESH_STATUS) {\r\n return false;\r\n }\r\n\r\n const message = value as RefreshStatusMessage;\r\n return typeof message.deviceId === 'string' && typeof message.state === 'string';\r\n}\r\n\r\nexport function isSnapshotReadyMessage(value: unknown): value is SnapshotReadyMessage {\r\n if (!hasMessageType(value) || value.type !== MessageType.SNAPSHOT_READY) {\r\n return false;\r\n }\r\n\r\n const message = value as SnapshotReadyMessage;\r\n return (\r\n typeof message.deviceId === 'string' &&\r\n typeof message.size === 'number' &&\r\n typeof message.exportedAt === 'number' &&\r\n typeof message.kind === 'string' &&\r\n typeof message.mimeType === 'string'\r\n );\r\n}\r\n\r\nexport function isRefreshErrorMessage(value: unknown): value is RefreshErrorMessage {\r\n if (!hasMessageType(value) || value.type !== MessageType.REFRESH_ERROR) {\r\n return false;\r\n }\r\n\r\n const message = value as RefreshErrorMessage;\r\n return typeof message.deviceId === 'string' && typeof message.code === 'string';\r\n}\r\n\r\nexport function isExportSnapshotRequestMessage(\r\n value: unknown,\r\n): value is ExportSnapshotRequestMessage {\r\n if (!hasMessageType(value) || value.type !== MessageType.EXPORT_SNAPSHOT_REQUEST) {\r\n return false;\r\n }\r\n\r\n const message = value as ExportSnapshotRequestMessage;\r\n return message.refreshType === 'snapshot';\r\n}\r\n\r\nexport function isExportSnapshotErrorMessage(\r\n value: unknown,\r\n): value is ExportSnapshotErrorMessage {\r\n if (!hasMessageType(value) || value.type !== MessageType.EXPORT_SNAPSHOT_ERROR) {\r\n return false;\r\n }\r\n\r\n const message = value as ExportSnapshotErrorMessage;\r\n return typeof message.code === 'string' && typeof message.message === 'string';\r\n}\r\n\r\nexport function isBeginTransactionRequestMessage(\r\n value: unknown,\r\n): value is BeginTransactionRequestMessage {\r\n if (!hasMessageType(value) || value.type !== MessageType.BEGIN_TRANSACTION_REQUEST) {\r\n return false;\r\n }\r\n\r\n const message = value as BeginTransactionRequestMessage;\r\n return typeof message.transactionId === 'string' && typeof message.deviceId === 'string';\r\n}\r\n\r\nexport function isCommitTransactionRequestMessage(\r\n value: unknown,\r\n): value is CommitTransactionRequestMessage {\r\n if (!hasMessageType(value) || value.type !== MessageType.COMMIT_TRANSACTION_REQUEST) {\r\n return false;\r\n }\r\n\r\n const message = value as CommitTransactionRequestMessage;\r\n return typeof message.transactionId === 'string' && typeof message.deviceId === 'string';\r\n}\r\n\r\nexport function isRollbackTransactionRequestMessage(\r\n value: unknown,\r\n): value is RollbackTransactionRequestMessage {\r\n if (!hasMessageType(value) || value.type !== MessageType.ROLLBACK_TRANSACTION_REQUEST) {\r\n return false;\r\n }\r\n\r\n const message = value as RollbackTransactionRequestMessage;\r\n return typeof message.transactionId === 'string' && typeof message.deviceId === 'string';\r\n}\r\n\r\nexport function isWriteRequestMessage(value: unknown): value is WriteRequestMessage {\r\n if (!hasMessageType(value) || value.type !== MessageType.WRITE_REQUEST) {\r\n return false;\r\n }\r\n\r\n const message = value as WriteRequestMessage;\r\n return (\r\n typeof message.writeId === 'string' &&\r\n typeof message.transactionId === 'string' &&\r\n typeof message.deviceId === 'string' &&\r\n typeof message.operation === 'object' &&\r\n message.operation !== null\r\n );\r\n}\r\n\r\nexport function isTransactionAckMessage(value: unknown): value is TransactionAckMessage {\r\n if (!hasMessageType(value) || value.type !== MessageType.TRANSACTION_ACK) {\r\n return false;\r\n }\r\n\r\n const message = value as TransactionAckMessage;\r\n return (\r\n typeof message.transactionId === 'string' &&\r\n (message.action === 'begin' || message.action === 'commit' || message.action === 'rollback') &&\r\n typeof message.ok === 'boolean'\r\n );\r\n}\r\n\r\nexport function isWriteAckMessage(value: unknown): value is WriteAckMessage {\r\n if (!hasMessageType(value) || value.type !== MessageType.WRITE_ACK) {\r\n return false;\r\n }\r\n\r\n const message = value as WriteAckMessage;\r\n return (\r\n typeof message.writeId === 'string' &&\r\n typeof message.transactionId === 'string' &&\r\n typeof message.ok === 'boolean'\r\n );\r\n}\r\n\r\nexport function isClientMessage(value: unknown): value is ClientMessage {\r\n return (\r\n isRegisterMessage(value) ||\r\n isPongMessage(value) ||\r\n isRefreshRequestMessage(value) ||\r\n isExportSnapshotRequestMessage(value) ||\r\n isBeginTransactionRequestMessage(value) ||\r\n isCommitTransactionRequestMessage(value) ||\r\n isRollbackTransactionRequestMessage(value) ||\r\n isWriteRequestMessage(value) ||\r\n isTransactionAckMessage(value) ||\r\n isWriteAckMessage(value)\r\n );\r\n}\r\n\r\nexport function isPingMessage(value: unknown): value is PingMessage {\r\n if (!hasMessageType(value) || value.type !== MessageType.PING) {\r\n return false;\r\n }\r\n\r\n const message = value as PingMessage;\r\n return typeof message.pingId === 'string';\r\n}\r\n\r\nexport function isDeviceStatusMessage(value: unknown): value is DeviceStatusMessage {\r\n if (!hasMessageType(value) || value.type !== MessageType.DEVICE_STATUS) {\r\n return false;\r\n }\r\n\r\n const message = value as DeviceStatusMessage;\r\n return typeof message.payload === 'object' && message.payload !== null;\r\n}\r\n\r\nexport function isBroadcastMessage(value: unknown): value is BroadcastMessage {\r\n if (!hasMessageType(value) || value.type !== MessageType.BROADCAST) {\r\n return false;\r\n }\r\n\r\n return true;\r\n}\r\n\r\nexport function isBeginTransactionMessage(value: unknown): value is BeginTransactionMessage {\r\n if (!hasMessageType(value) || value.type !== MessageType.BEGIN_TRANSACTION) {\r\n return false;\r\n }\r\n\r\n const message = value as BeginTransactionMessage;\r\n return typeof message.transactionId === 'string';\r\n}\r\n\r\nexport function isCommitTransactionMessage(value: unknown): value is CommitTransactionMessage {\r\n if (!hasMessageType(value) || value.type !== MessageType.COMMIT_TRANSACTION) {\r\n return false;\r\n }\r\n\r\n const message = value as CommitTransactionMessage;\r\n return typeof message.transactionId === 'string';\r\n}\r\n\r\nexport function isRollbackTransactionMessage(value: unknown): value is RollbackTransactionMessage {\r\n if (!hasMessageType(value) || value.type !== MessageType.ROLLBACK_TRANSACTION) {\r\n return false;\r\n }\r\n\r\n const message = value as RollbackTransactionMessage;\r\n return typeof message.transactionId === 'string';\r\n}\r\n\r\nexport function isExecuteWriteMessage(value: unknown): value is ExecuteWriteMessage {\r\n if (!hasMessageType(value) || value.type !== MessageType.EXECUTE_WRITE) {\r\n return false;\r\n }\r\n\r\n const message = value as ExecuteWriteMessage;\r\n return (\r\n typeof message.writeId === 'string' &&\r\n typeof message.transactionId === 'string' &&\r\n typeof message.operation === 'object' &&\r\n message.operation !== null\r\n );\r\n}\r\n\r\nexport function isTransactionStatusMessage(value: unknown): value is TransactionStatusMessage {\r\n if (!hasMessageType(value) || value.type !== MessageType.TRANSACTION_STATUS) {\r\n return false;\r\n }\r\n\r\n const message = value as TransactionStatusMessage;\r\n return (\r\n typeof message.transactionId === 'string' &&\r\n typeof message.deviceId === 'string' &&\r\n typeof message.state === 'string'\r\n );\r\n}\r\n\r\nexport function isWriteResultMessage(value: unknown): value is WriteResultMessage {\r\n if (!hasMessageType(value) || value.type !== MessageType.WRITE_RESULT) {\r\n return false;\r\n }\r\n\r\n const message = value as WriteResultMessage;\r\n return (\r\n typeof message.writeId === 'string' &&\r\n typeof message.transactionId === 'string' &&\r\n typeof message.rowsAffected === 'number'\r\n );\r\n}\r\n\r\nexport function isWriteErrorMessage(value: unknown): value is WriteErrorMessage {\r\n if (!hasMessageType(value) || value.type !== MessageType.WRITE_ERROR) {\r\n return false;\r\n }\r\n\r\n const message = value as WriteErrorMessage;\r\n return typeof message.transactionId === 'string' && typeof message.code === 'string';\r\n}\r\n\r\nexport function isServerMessage(value: unknown): value is ServerMessage {\r\n return (\r\n isPingMessage(value) ||\r\n isDeviceStatusMessage(value) ||\r\n isBroadcastMessage(value) ||\r\n isSnapshotUploadRequestedMessage(value) ||\r\n isRefreshStatusMessage(value) ||\r\n isSnapshotReadyMessage(value) ||\r\n isRefreshErrorMessage(value) ||\r\n isExportSnapshotErrorMessage(value) ||\r\n isBeginTransactionMessage(value) ||\r\n isCommitTransactionMessage(value) ||\r\n isRollbackTransactionMessage(value) ||\r\n isExecuteWriteMessage(value) ||\r\n isTransactionStatusMessage(value) ||\r\n isWriteResultMessage(value) ||\r\n isWriteErrorMessage(value)\r\n );\r\n}\r\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
export { __require };
|
|
9
|
+
//# sourceMappingURL=chunk-DGUM43GV.js.map
|
|
10
|
+
//# sourceMappingURL=chunk-DGUM43GV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-DGUM43GV.js"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// src/types/snapshot.ts
|
|
2
|
+
var SNAPSHOT_KIND_HEADER = "x-database-kind";
|
|
3
|
+
var SNAPSHOT_MIME_HEADER = "x-snapshot-mime-type";
|
|
4
|
+
var SNAPSHOT_NAME_HEADER = "x-database-name";
|
|
5
|
+
var SQLITE_SNAPSHOT_MIME_TYPE = "application/x-sqlite3";
|
|
6
|
+
|
|
7
|
+
export { SNAPSHOT_KIND_HEADER, SNAPSHOT_MIME_HEADER, SNAPSHOT_NAME_HEADER, SQLITE_SNAPSHOT_MIME_TYPE };
|
|
8
|
+
//# sourceMappingURL=chunk-HIDZTOJ3.js.map
|
|
9
|
+
//# sourceMappingURL=chunk-HIDZTOJ3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types/snapshot.ts"],"names":[],"mappings":";AAEO,IAAM,oBAAA,GAAuB;AAC7B,IAAM,oBAAA,GAAuB;AAC7B,IAAM,oBAAA,GAAuB;AAE7B,IAAM,yBAAA,GAA4B","file":"chunk-HIDZTOJ3.js","sourcesContent":["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"]}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { SQLITE_SNAPSHOT_MIME_TYPE } from './chunk-HIDZTOJ3.js';
|
|
2
|
+
|
|
3
|
+
// src/types/kind.ts
|
|
4
|
+
var DATABASE_DEVTOOLS_KIND = /* @__PURE__ */ Symbol.for("@database-devtools/kind");
|
|
5
|
+
function readDatabaseKindMarker(value) {
|
|
6
|
+
if (typeof value !== "object" || value === null) {
|
|
7
|
+
return void 0;
|
|
8
|
+
}
|
|
9
|
+
const marker = value[DATABASE_DEVTOOLS_KIND];
|
|
10
|
+
return typeof marker === "string" ? marker : void 0;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// src/adapter/registry.ts
|
|
14
|
+
var AdapterRegistry = class {
|
|
15
|
+
definitions = /* @__PURE__ */ new Map();
|
|
16
|
+
register(definition) {
|
|
17
|
+
this.definitions.set(definition.kind, definition);
|
|
18
|
+
}
|
|
19
|
+
get(kind) {
|
|
20
|
+
return this.definitions.get(kind);
|
|
21
|
+
}
|
|
22
|
+
listSupported() {
|
|
23
|
+
return [...this.definitions.values()].sort((left, right) => left.displayName.localeCompare(right.displayName)).map((definition) => ({
|
|
24
|
+
kind: definition.kind,
|
|
25
|
+
displayName: definition.displayName
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
detect(database) {
|
|
29
|
+
const markerKind = readDatabaseKindMarker(database);
|
|
30
|
+
if (markerKind) {
|
|
31
|
+
const marked = this.definitions.get(markerKind);
|
|
32
|
+
if (marked) {
|
|
33
|
+
return marked;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const matches = [...this.definitions.values()].filter((definition) => {
|
|
37
|
+
try {
|
|
38
|
+
return definition.detect(database);
|
|
39
|
+
} catch {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}).sort((left, right) => right.priority - left.priority);
|
|
43
|
+
return matches[0];
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
var globalRegistry = null;
|
|
47
|
+
function getAdapterRegistry() {
|
|
48
|
+
if (!globalRegistry) {
|
|
49
|
+
globalRegistry = new AdapterRegistry();
|
|
50
|
+
}
|
|
51
|
+
return globalRegistry;
|
|
52
|
+
}
|
|
53
|
+
function resetAdapterRegistry() {
|
|
54
|
+
globalRegistry = null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// src/adapters/sqlite/buildWriteSql.ts
|
|
58
|
+
var IDENTIFIER_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
59
|
+
function quoteIdentifier(name) {
|
|
60
|
+
if (!IDENTIFIER_PATTERN.test(name)) {
|
|
61
|
+
throw new Error(`Invalid identifier: ${name}`);
|
|
62
|
+
}
|
|
63
|
+
return `"${name.replace(/"/g, '""')}"`;
|
|
64
|
+
}
|
|
65
|
+
function buildInsertSql(operation) {
|
|
66
|
+
const columns = Object.keys(operation.values);
|
|
67
|
+
if (columns.length === 0) {
|
|
68
|
+
throw new Error("Insert requires at least one column value");
|
|
69
|
+
}
|
|
70
|
+
const quotedColumns = columns.map(quoteIdentifier).join(", ");
|
|
71
|
+
const placeholders = columns.map(() => "?").join(", ");
|
|
72
|
+
const sql = `INSERT INTO ${quoteIdentifier(operation.table)} (${quotedColumns}) VALUES (${placeholders})`;
|
|
73
|
+
const params = columns.map((column) => operation.values[column] ?? null);
|
|
74
|
+
return { sql, params };
|
|
75
|
+
}
|
|
76
|
+
function buildUpdateSql(operation) {
|
|
77
|
+
const valueColumns = Object.keys(operation.values);
|
|
78
|
+
const pkColumns = Object.keys(operation.primaryKey);
|
|
79
|
+
if (valueColumns.length === 0) {
|
|
80
|
+
throw new Error("Update requires at least one column value");
|
|
81
|
+
}
|
|
82
|
+
if (pkColumns.length === 0) {
|
|
83
|
+
throw new Error("Update requires a primary key");
|
|
84
|
+
}
|
|
85
|
+
const setClause = valueColumns.map((column) => `${quoteIdentifier(column)} = ?`).join(", ");
|
|
86
|
+
const whereClause = pkColumns.map((column) => `${quoteIdentifier(column)} = ?`).join(" AND ");
|
|
87
|
+
const sql = `UPDATE ${quoteIdentifier(operation.table)} SET ${setClause} WHERE ${whereClause}`;
|
|
88
|
+
const params = [
|
|
89
|
+
...valueColumns.map((column) => operation.values[column] ?? null),
|
|
90
|
+
...pkColumns.map((column) => operation.primaryKey[column] ?? null)
|
|
91
|
+
];
|
|
92
|
+
return { sql, params };
|
|
93
|
+
}
|
|
94
|
+
function buildDeleteSql(operation) {
|
|
95
|
+
const pkColumns = Object.keys(operation.primaryKey);
|
|
96
|
+
if (pkColumns.length === 0) {
|
|
97
|
+
throw new Error("Delete requires a primary key");
|
|
98
|
+
}
|
|
99
|
+
const whereClause = pkColumns.map((column) => `${quoteIdentifier(column)} = ?`).join(" AND ");
|
|
100
|
+
const sql = `DELETE FROM ${quoteIdentifier(operation.table)} WHERE ${whereClause}`;
|
|
101
|
+
const params = pkColumns.map((column) => operation.primaryKey[column] ?? null);
|
|
102
|
+
return { sql, params };
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// src/adapters/sqlite/createExpoSqliteAdapter.ts
|
|
106
|
+
function createExpoSqliteAdapter(options) {
|
|
107
|
+
const { database } = options;
|
|
108
|
+
let inTransaction = false;
|
|
109
|
+
let operationQueue = Promise.resolve();
|
|
110
|
+
const enqueue = async (operation) => {
|
|
111
|
+
const next = operationQueue.then(operation);
|
|
112
|
+
operationQueue = next.then(
|
|
113
|
+
() => void 0,
|
|
114
|
+
() => void 0
|
|
115
|
+
);
|
|
116
|
+
return next;
|
|
117
|
+
};
|
|
118
|
+
const assertTransaction = () => {
|
|
119
|
+
if (!inTransaction) {
|
|
120
|
+
throw new Error("No open transaction. Call beginTransaction() first.");
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
const runWrite = async (operation) => {
|
|
124
|
+
assertTransaction();
|
|
125
|
+
let sql;
|
|
126
|
+
let params;
|
|
127
|
+
switch (operation.kind) {
|
|
128
|
+
case "insert": {
|
|
129
|
+
const built = buildInsertSql(operation);
|
|
130
|
+
sql = built.sql;
|
|
131
|
+
params = built.params;
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
case "update": {
|
|
135
|
+
const built = buildUpdateSql(operation);
|
|
136
|
+
sql = built.sql;
|
|
137
|
+
params = built.params;
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
case "delete": {
|
|
141
|
+
const built = buildDeleteSql(operation);
|
|
142
|
+
sql = built.sql;
|
|
143
|
+
params = built.params;
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
default: {
|
|
147
|
+
const exhaustive = operation;
|
|
148
|
+
throw new Error(`Unsupported write operation: ${exhaustive.kind}`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
const result = await database.runAsync(sql, params);
|
|
152
|
+
return { rowsAffected: result.changes };
|
|
153
|
+
};
|
|
154
|
+
return {
|
|
155
|
+
kind: "sqlite",
|
|
156
|
+
dialect: "sqlite",
|
|
157
|
+
id: options.id ?? database.databasePath,
|
|
158
|
+
name: options.name ?? "SQLite",
|
|
159
|
+
capabilities: {
|
|
160
|
+
exportSnapshot: true,
|
|
161
|
+
executeQuery: false,
|
|
162
|
+
listTables: false,
|
|
163
|
+
getSchema: false,
|
|
164
|
+
transactionalWrites: true,
|
|
165
|
+
observeChanges: false,
|
|
166
|
+
importSnapshot: false
|
|
167
|
+
},
|
|
168
|
+
async exportSnapshot() {
|
|
169
|
+
return enqueue(async () => {
|
|
170
|
+
if (inTransaction) {
|
|
171
|
+
throw new Error("Cannot export while a write transaction is open");
|
|
172
|
+
}
|
|
173
|
+
await database.execAsync("PRAGMA wal_checkpoint(FULL)");
|
|
174
|
+
const bytes = await database.serializeAsync();
|
|
175
|
+
return {
|
|
176
|
+
bytes,
|
|
177
|
+
mimeType: SQLITE_SNAPSHOT_MIME_TYPE,
|
|
178
|
+
kind: "sqlite",
|
|
179
|
+
exportedAt: Date.now()
|
|
180
|
+
};
|
|
181
|
+
});
|
|
182
|
+
},
|
|
183
|
+
async beginTransaction() {
|
|
184
|
+
return enqueue(async () => {
|
|
185
|
+
if (inTransaction) {
|
|
186
|
+
throw new Error("Transaction already open");
|
|
187
|
+
}
|
|
188
|
+
await database.execAsync("BEGIN IMMEDIATE");
|
|
189
|
+
inTransaction = true;
|
|
190
|
+
});
|
|
191
|
+
},
|
|
192
|
+
async commitTransaction() {
|
|
193
|
+
return enqueue(async () => {
|
|
194
|
+
assertTransaction();
|
|
195
|
+
try {
|
|
196
|
+
await database.execAsync("COMMIT");
|
|
197
|
+
} finally {
|
|
198
|
+
inTransaction = false;
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
},
|
|
202
|
+
async rollbackTransaction() {
|
|
203
|
+
return enqueue(async () => {
|
|
204
|
+
if (!inTransaction) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
try {
|
|
208
|
+
await database.execAsync("ROLLBACK");
|
|
209
|
+
} finally {
|
|
210
|
+
inTransaction = false;
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
},
|
|
214
|
+
executeWrite: (operation) => enqueue(() => runWrite(operation))
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// src/adapters/sqlite/detect.ts
|
|
219
|
+
function detectExpoSqlite(database) {
|
|
220
|
+
return typeof database === "object" && database !== null && typeof database.execAsync === "function" && typeof database.serializeAsync === "function" && typeof database.runAsync === "function" && typeof database.databasePath === "string";
|
|
221
|
+
}
|
|
222
|
+
function detectExpoSqliteInspectable(database) {
|
|
223
|
+
return detectExpoSqlite(database) && typeof database.getAllAsync === "function" && typeof database.getFirstAsync === "function";
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// src/adapters/sqlite/register.ts
|
|
227
|
+
var sqliteAdapterDefinition = {
|
|
228
|
+
kind: "sqlite",
|
|
229
|
+
displayName: "SQLite",
|
|
230
|
+
priority: 100,
|
|
231
|
+
detect: detectExpoSqlite,
|
|
232
|
+
create: (database) => createExpoSqliteAdapter({
|
|
233
|
+
database,
|
|
234
|
+
name: database.databasePath
|
|
235
|
+
})
|
|
236
|
+
};
|
|
237
|
+
function registerSqliteAdapter() {
|
|
238
|
+
getAdapterRegistry().register(sqliteAdapterDefinition);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
export { AdapterRegistry, DATABASE_DEVTOOLS_KIND, buildDeleteSql, buildInsertSql, buildUpdateSql, createExpoSqliteAdapter, detectExpoSqlite, detectExpoSqliteInspectable, getAdapterRegistry, quoteIdentifier, readDatabaseKindMarker, registerSqliteAdapter, resetAdapterRegistry, sqliteAdapterDefinition };
|
|
242
|
+
//# sourceMappingURL=chunk-I65IM47D.js.map
|
|
243
|
+
//# sourceMappingURL=chunk-I65IM47D.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types/kind.ts","../src/adapter/registry.ts","../src/adapters/sqlite/buildWriteSql.ts","../src/adapters/sqlite/createExpoSqliteAdapter.ts","../src/adapters/sqlite/detect.ts","../src/adapters/sqlite/register.ts"],"names":[],"mappings":"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","file":"chunk-I65IM47D.js","sourcesContent":["/** 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 {\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"]}
|