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 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/types/protocol.ts","../../src/types/snapshot.ts","../../src/utils/logger.ts","../../src/server/attachWebUi.ts","../../src/server/attachWebSocket.ts","../../src/utils/ids.ts","../../src/server/connectionManager.ts","../../src/server/cors.ts","../../src/server/deviceRegistry.ts","../../src/server/heartbeat.ts","../../src/server/messageRouter.ts","../../src/server/pendingRefreshStore.ts","../../src/server/refreshCoordinator.ts","../../src/server/projectData.ts","../../src/server/deviceExportStorage.ts","../../src/server/migrateLegacyActiveDb.ts","../../src/server/snapshotFileStore.ts","../../src/server/snapshotStore.ts","../../src/server/writeCoordinator.ts","../../src/server/writeSessionManager.ts","../../src/server/createDevToolsServer.ts"],"names":["path","existsSync","express","WebSocketServer","mkdir","readFile","writeFile","stat","rm","absolutePath","createServer"],"mappings":"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","file":"index.cjs","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","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","const RESET = '\\x1b[0m';\r\nconst GREEN = '\\x1b[32m';\r\nconst YELLOW = '\\x1b[33m';\r\nconst CYAN = '\\x1b[36m';\r\nconst RED = '\\x1b[31m';\r\nconst DIM = '\\x1b[2m';\r\n\r\nconst PREFIX = `${DIM}[database-devtools]${RESET}`;\r\n\r\nfunction log(color: string, symbol: string, message: string): void {\r\n console.log(`${PREFIX} ${color}${symbol}${RESET} ${message}`);\r\n}\r\n\r\nexport const logger = {\r\n browserConnected(connectionId?: string): void {\r\n const suffix = connectionId ? ` ${DIM}(${connectionId})${RESET}` : '';\r\n log(GREEN, '✓', `Browser Connected${suffix}`);\r\n },\r\n\r\n browserDisconnected(connectionId?: string): void {\r\n const suffix = connectionId ? ` ${DIM}(${connectionId})${RESET}` : '';\r\n log(YELLOW, '✓', `Browser Disconnected${suffix}`);\r\n },\r\n\r\n mobileConnected(deviceId?: string): void {\r\n const suffix = deviceId ? ` ${DIM}(deviceId: ${deviceId})${RESET}` : '';\r\n log(GREEN, '✓', `Mobile Connected${suffix}`);\r\n },\r\n\r\n mobileDisconnected(deviceId?: string): void {\r\n const suffix = deviceId ? ` ${DIM}(deviceId: ${deviceId})${RESET}` : '';\r\n log(YELLOW, '✓', `Mobile Disconnected${suffix}`);\r\n },\r\n\r\n broadcastSent(target?: string): void {\r\n const suffix = target ? ` ${DIM}→ ${target}${RESET}` : '';\r\n log(CYAN, '✓', `Broadcast Sent${suffix}`);\r\n },\r\n\r\n serverStarted(url: string, wsUrl: string, webUiEnabled = false): void {\r\n log(GREEN, '✓', `Server started at ${url}`);\r\n log(GREEN, '✓', `WebSocket endpoint ${wsUrl}`);\r\n\r\n if (webUiEnabled) {\r\n log(GREEN, '✓', `Browser UI available at ${url}`);\r\n }\r\n },\r\n\r\n heartbeatTimeout(connectionId: string): void {\r\n log(RED, '✓', `Heartbeat timeout — removing ${connectionId}`);\r\n },\r\n\r\n refreshStarted(deviceId: string): void {\r\n log(CYAN, '↻', `Refresh started ${DIM}(${deviceId})${RESET}`);\r\n },\r\n\r\n refreshUploaded(deviceId: string, bytes: number): void {\r\n log(GREEN, '↻', `Snapshot uploaded ${DIM}(${deviceId}, ${bytes} bytes)${RESET}`);\r\n },\r\n\r\n refreshFailed(deviceId: string, code: string, message: string): void {\r\n log(RED, '↻', `Refresh failed ${DIM}(${deviceId}: ${code})${RESET} ${message}`);\r\n },\r\n\r\n /** @deprecated Use refreshStarted */\r\n syncStarted(syncId: string, deviceId: string): void {\r\n this.refreshStarted(deviceId);\r\n },\r\n\r\n /** @deprecated Use refreshUploaded */\r\n syncUploaded(syncId: string, bytes: number): void {\r\n this.refreshUploaded(syncId, bytes);\r\n },\r\n\r\n /** @deprecated Use refreshFailed */\r\n syncFailed(syncId: string, code: string, message: string): void {\r\n this.refreshFailed(syncId, code, message);\r\n },\r\n\r\n error(message: string): void {\r\n log(RED, '✗', message);\r\n },\r\n};\r\n","import { existsSync } from 'node:fs';\r\nimport path from 'node:path';\r\nimport type { Express, Request, Response } from 'express';\r\nimport express from 'express';\r\n\r\nfunction shouldServeSpa(request: Request): boolean {\r\n if (request.method !== 'GET' && request.method !== 'HEAD') {\r\n return false;\r\n }\r\n\r\n if (request.path.startsWith('/api')) {\r\n return false;\r\n }\r\n\r\n if (request.path === '/health') {\r\n return false;\r\n }\r\n\r\n return true;\r\n}\r\n\r\nexport function attachWebUi(app: Express, webDistPath: string): void {\r\n const indexPath = path.join(webDistPath, 'index.html');\r\n\r\n if (!existsSync(indexPath)) {\r\n return;\r\n }\r\n\r\n app.use(\r\n express.static(webDistPath, {\r\n index: false,\r\n setHeaders(response, filePath) {\r\n if (filePath.endsWith('.wasm')) {\r\n response.setHeader('Content-Type', 'application/wasm');\r\n }\r\n },\r\n }),\r\n );\r\n\r\n app.get('*', (request: Request, response: Response, next) => {\r\n if (!shouldServeSpa(request)) {\r\n next();\r\n return;\r\n }\r\n\r\n response.sendFile(indexPath);\r\n });\r\n}\r\n","import type { Server } from 'node:http';\r\nimport { WebSocketServer, type WebSocket } from 'ws';\r\nimport {\r\n DEVTOOLS_WS_PATH,\r\n DevToolsRole,\r\n isBeginTransactionRequestMessage,\r\n isCommitTransactionRequestMessage,\r\n isExportSnapshotRequestMessage,\r\n isPongMessage,\r\n isRefreshRequestMessage,\r\n isRegisterMessage,\r\n isRollbackTransactionRequestMessage,\r\n isTransactionAckMessage,\r\n isWriteAckMessage,\r\n isWriteRequestMessage,\r\n} from '../types/protocol';\r\nimport { logger } from '../utils/logger';\r\nimport type { ConnectionManager } from './connectionManager';\r\nimport type { Heartbeat } from './heartbeat';\r\nimport type { MessageRouter } from './messageRouter';\r\nimport type { RefreshCoordinator } from './refreshCoordinator';\r\nimport type { SnapshotFileStore } from './snapshotFileStore';\r\nimport type { WriteCoordinator } from './writeCoordinator';\r\n\r\nexport type AttachWebSocketOptions = {\r\n snapshotFileStore?: SnapshotFileStore;\r\n};\r\n\r\nexport type AttachWebSocketResult = {\r\n wss: WebSocketServer;\r\n};\r\n\r\nexport function attachWebSocket(\r\n httpServer: Server,\r\n connectionManager: ConnectionManager,\r\n router: MessageRouter,\r\n heartbeat: Heartbeat,\r\n refreshCoordinator: RefreshCoordinator,\r\n writeCoordinator: WriteCoordinator,\r\n options?: AttachWebSocketOptions,\r\n): AttachWebSocketResult {\r\n const wss = new WebSocketServer({ server: httpServer, path: DEVTOOLS_WS_PATH });\r\n\r\n const handleDisconnect = (socket: WebSocket): void => {\r\n const client = connectionManager.remove(socket);\r\n\r\n if (!client) {\r\n return;\r\n }\r\n\r\n if (client.role === DevToolsRole.MOBILE) {\r\n if (client.deviceId) {\r\n writeCoordinator.rollbackSessionsForDevice(client.deviceId);\r\n }\r\n\r\n logger.mobileDisconnected(client.deviceId);\r\n } else {\r\n writeCoordinator.rollbackSessionsOnBrowserDisconnect(client.connectionId);\r\n logger.browserDisconnected(client.connectionId);\r\n }\r\n\r\n router.broadcastDeviceStatus();\r\n };\r\n\r\n wss.on('connection', (socket: WebSocket) => {\r\n socket.on('message', (raw) => {\r\n let parsed: unknown;\r\n\r\n try {\r\n parsed = JSON.parse(String(raw));\r\n } catch {\r\n return;\r\n }\r\n\r\n if (isRegisterMessage(parsed)) {\r\n const existing = connectionManager.getBySocket(socket);\r\n\r\n if (existing) {\r\n return;\r\n }\r\n\r\n const client = connectionManager.add({\r\n socket,\r\n role: parsed.role,\r\n deviceId: parsed.deviceId,\r\n metadata: parsed.metadata,\r\n });\r\n\r\n if (client.role === DevToolsRole.MOBILE) {\r\n logger.mobileConnected(client.deviceId);\r\n\r\n if (client.deviceId && options?.snapshotFileStore) {\r\n void options.snapshotFileStore\r\n .reconcileOnMobileConnect({\r\n deviceId: client.deviceId,\r\n bundleId: client.metadata?.bundleId,\r\n })\r\n .finally(() => {\r\n router.broadcastDeviceStatus();\r\n });\r\n return;\r\n }\r\n } else {\r\n logger.browserConnected(client.connectionId);\r\n }\r\n\r\n router.broadcastDeviceStatus();\r\n return;\r\n }\r\n\r\n if (isPongMessage(parsed)) {\r\n connectionManager.updateLastPong(socket);\r\n return;\r\n }\r\n\r\n if (isRefreshRequestMessage(parsed)) {\r\n refreshCoordinator.handleRefreshRequest(socket, parsed);\r\n return;\r\n }\r\n\r\n if (isExportSnapshotRequestMessage(parsed)) {\r\n refreshCoordinator.handleMobileExportRequest(socket, parsed);\r\n return;\r\n }\r\n\r\n if (isBeginTransactionRequestMessage(parsed)) {\r\n writeCoordinator.handleBeginTransactionRequest(socket, parsed);\r\n return;\r\n }\r\n\r\n if (isCommitTransactionRequestMessage(parsed)) {\r\n writeCoordinator.handleCommitTransactionRequest(socket, parsed);\r\n return;\r\n }\r\n\r\n if (isRollbackTransactionRequestMessage(parsed)) {\r\n writeCoordinator.handleRollbackTransactionRequest(socket, parsed);\r\n return;\r\n }\r\n\r\n if (isWriteRequestMessage(parsed)) {\r\n writeCoordinator.handleWriteRequest(socket, parsed);\r\n return;\r\n }\r\n\r\n if (isTransactionAckMessage(parsed)) {\r\n writeCoordinator.handleTransactionAck(parsed);\r\n return;\r\n }\r\n\r\n if (isWriteAckMessage(parsed)) {\r\n writeCoordinator.handleWriteAck(parsed);\r\n }\r\n });\r\n\r\n socket.on('close', () => {\r\n handleDisconnect(socket);\r\n });\r\n\r\n socket.on('error', () => {\r\n handleDisconnect(socket);\r\n });\r\n });\r\n\r\n heartbeat.start();\r\n\r\n return { wss };\r\n}\r\n","export function generateConnectionId(): string {\r\n return generateUniqueId('conn');\r\n}\r\n\r\nexport function generateDeviceId(): string {\r\n return generateUniqueId('device');\r\n}\r\n\r\nexport function generatePingId(): string {\r\n return generateUniqueId('ping');\r\n}\r\n\r\nexport function generateSyncId(): string {\r\n return generateUniqueId('sync');\r\n}\r\n\r\nexport function generateTransactionId(): string {\r\n return generateUniqueId('txn');\r\n}\r\n\r\nexport function generateWriteId(): string {\r\n return generateUniqueId('write');\r\n}\r\n\r\nfunction generateUniqueId(prefix: string): string {\r\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\r\n return `${prefix}-${crypto.randomUUID()}`;\r\n }\r\n\r\n const random = Math.random().toString(36).slice(2, 10);\r\n return `${prefix}-${Date.now()}-${random}`;\r\n}\r\n","import type { WebSocket } from 'ws';\nimport type { DevToolsRole, DeviceMetadata } from '../types/protocol';\nimport { generateConnectionId } from '../utils/ids';\n\nexport type ConnectedClient = {\n socket: WebSocket;\n connectionId: string;\n role: DevToolsRole;\n deviceId?: string;\n metadata?: DeviceMetadata;\n connectedAt: number;\n lastPongAt: number;\n};\n\nexport type RegisterClientInput = {\n socket: WebSocket;\n role: DevToolsRole;\n deviceId?: string;\n metadata?: DeviceMetadata;\n};\n\nexport class ConnectionManager {\n private readonly clients = new Map<WebSocket, ConnectedClient>();\n\n add(input: RegisterClientInput): ConnectedClient {\n const now = Date.now();\n const client: ConnectedClient = {\n socket: input.socket,\n connectionId: generateConnectionId(),\n role: input.role,\n deviceId: input.deviceId,\n metadata: input.metadata,\n connectedAt: now,\n lastPongAt: now,\n };\n\n this.clients.set(input.socket, client);\n return client;\n }\n\n remove(socket: WebSocket): ConnectedClient | undefined {\n const client = this.clients.get(socket);\n\n if (client) {\n this.clients.delete(socket);\n }\n\n return client;\n }\n\n getBySocket(socket: WebSocket): ConnectedClient | undefined {\n return this.clients.get(socket);\n }\n\n getByConnectionId(connectionId: string): ConnectedClient | undefined {\n for (const client of this.clients.values()) {\n if (client.connectionId === connectionId) {\n return client;\n }\n }\n\n return undefined;\n }\n\n getByDeviceId(deviceId: string): ConnectedClient | undefined {\n for (const client of this.clients.values()) {\n if (client.deviceId === deviceId) {\n return client;\n }\n }\n\n return undefined;\n }\n\n getByRole(role: DevToolsRole): ConnectedClient[] {\n return [...this.clients.values()].filter((client) => client.role === role);\n }\n\n updateLastPong(socket: WebSocket): void {\n const client = this.clients.get(socket);\n\n if (client) {\n client.lastPongAt = Date.now();\n }\n }\n\n getAll(): ConnectedClient[] {\n return [...this.clients.values()];\n }\n}\n","import type { NextFunction, Request, Response } from 'express';\r\nimport {\r\n SNAPSHOT_KIND_HEADER,\r\n SNAPSHOT_MIME_HEADER,\r\n SNAPSHOT_NAME_HEADER,\r\n} from '../types/snapshot';\r\n\r\nconst ALLOWED_METHODS = 'GET, POST, OPTIONS';\r\n\r\nconst ALLOWED_HEADERS = [\r\n 'Content-Type',\r\n SNAPSHOT_KIND_HEADER,\r\n SNAPSHOT_MIME_HEADER,\r\n SNAPSHOT_NAME_HEADER,\r\n].join(', ');\r\n\r\nexport type CorsOptions = {\r\n /** Fixed origin, or `*` when request has no Origin header. */\r\n allowedOrigin?: string;\r\n};\r\n\r\nexport function resolveCorsOrigin(\r\n requestOrigin: string | undefined,\r\n configuredOrigin?: string,\r\n): string {\r\n if (configuredOrigin) {\r\n return configuredOrigin;\r\n }\r\n\r\n if (!requestOrigin) {\r\n return '*';\r\n }\r\n\r\n try {\r\n const url = new URL(requestOrigin);\r\n const isLocalDev =\r\n url.hostname === 'localhost' ||\r\n url.hostname === '127.0.0.1' ||\r\n url.hostname === '10.0.2.2';\r\n\r\n if (isLocalDev) {\r\n return requestOrigin;\r\n }\r\n } catch {\r\n return '*';\r\n }\r\n\r\n return '*';\r\n}\r\n\r\nexport function createCorsMiddleware(options: CorsOptions = {}) {\r\n const configuredOrigin = options.allowedOrigin ?? process.env.DATABASE_DEVTOOLS_CORS_ORIGIN;\r\n\r\n return (request: Request, response: Response, next: NextFunction): void => {\r\n const origin = resolveCorsOrigin(request.header('origin'), configuredOrigin);\r\n\r\n response.setHeader('Access-Control-Allow-Origin', origin);\r\n response.setHeader('Access-Control-Allow-Methods', ALLOWED_METHODS);\r\n response.setHeader('Access-Control-Allow-Headers', ALLOWED_HEADERS);\r\n response.setHeader('Vary', 'Origin');\r\n\r\n if (request.method === 'OPTIONS') {\r\n response.status(204).end();\r\n return;\r\n }\r\n\r\n next();\r\n };\r\n}\r\n","import type { ConnectionManager } from './connectionManager';\nimport type { DeviceStatusPayload } from '../types/protocol';\nimport { DevToolsRole } from '../types/protocol';\n\nexport class DeviceRegistry {\n constructor(private readonly connectionManager: ConnectionManager) {}\n\n snapshot(): DeviceStatusPayload {\n const browsers = this.connectionManager\n .getByRole(DevToolsRole.BROWSER)\n .map((client) => ({\n connectionId: client.connectionId,\n connectedAt: client.connectedAt,\n }));\n\n const mobiles = this.connectionManager\n .getByRole(DevToolsRole.MOBILE)\n .map((client) => ({\n deviceId: client.deviceId ?? client.connectionId,\n connectionId: client.connectionId,\n connectedAt: client.connectedAt,\n metadata: client.metadata,\n }));\n\n return {\n browserCount: browsers.length,\n mobileCount: mobiles.length,\n browsers,\n mobiles,\n };\n }\n}\n","import {\n createMessage,\n HEARTBEAT_INTERVAL_MS,\n HEARTBEAT_TIMEOUT_MS,\n MessageType,\n type PingMessage,\n} from '../types/protocol';\nimport { generatePingId } from '../utils/ids';\nimport { logger } from '../utils/logger';\nimport type { ConnectionManager } from './connectionManager';\nimport type { MessageRouter } from './messageRouter';\n\nexport class Heartbeat {\n private interval: ReturnType<typeof setInterval> | null = null;\n\n constructor(\n private readonly connectionManager: ConnectionManager,\n private readonly router: MessageRouter,\n ) {}\n\n start(): void {\n if (this.interval !== null) {\n return;\n }\n\n this.interval = setInterval(() => {\n this.pingAll();\n this.removeStaleConnections();\n }, HEARTBEAT_INTERVAL_MS);\n }\n\n stop(): void {\n if (this.interval !== null) {\n clearInterval(this.interval);\n this.interval = null;\n }\n }\n\n private pingAll(): void {\n const pingId = generatePingId();\n const message = createMessage<PingMessage>({\n type: MessageType.PING,\n pingId,\n });\n\n for (const client of this.connectionManager.getAll()) {\n this.router.sendToSocket(client.socket, message);\n }\n }\n\n private removeStaleConnections(): void {\n const now = Date.now();\n\n for (const client of this.connectionManager.getAll()) {\n if (now - client.lastPongAt > HEARTBEAT_INTERVAL_MS + HEARTBEAT_TIMEOUT_MS) {\n logger.heartbeatTimeout(client.connectionId);\n client.socket.terminate();\n this.connectionManager.remove(client.socket);\n }\n }\n }\n}\n","import type { WebSocket } from 'ws';\nimport {\n createMessage,\n DevToolsRole,\n MessageType,\n type BroadcastMessage,\n type DeviceStatusMessage,\n type ServerMessage,\n} from '../types/protocol';\nimport { logger } from '../utils/logger';\nimport type { ConnectionManager } from './connectionManager';\nimport type { DeviceRegistry } from './deviceRegistry';\n\nexport type OutboundMessage = ServerMessage;\n\nexport class MessageRouter {\n constructor(\n private readonly connectionManager: ConnectionManager,\n private readonly deviceRegistry: DeviceRegistry,\n ) {}\n\n sendToSocket(socket: WebSocket, message: OutboundMessage): void {\n if (socket.readyState === socket.OPEN) {\n socket.send(JSON.stringify(message));\n }\n }\n\n sendToBrowser(connectionId: string, message: OutboundMessage): void {\n const client = this.connectionManager.getByConnectionId(connectionId);\n\n if (client?.role === DevToolsRole.BROWSER) {\n this.sendToSocket(client.socket, message);\n }\n }\n\n sendToMobile(deviceId: string, message: OutboundMessage): void {\n const client = this.connectionManager.getByDeviceId(deviceId);\n\n if (client?.role === DevToolsRole.MOBILE) {\n this.sendToSocket(client.socket, message);\n }\n }\n\n broadcastToBrowsers(message: OutboundMessage): void {\n for (const client of this.connectionManager.getByRole(DevToolsRole.BROWSER)) {\n this.sendToSocket(client.socket, message);\n }\n\n logger.broadcastSent('browsers');\n }\n\n broadcastToMobiles(message: OutboundMessage): void {\n for (const client of this.connectionManager.getByRole(DevToolsRole.MOBILE)) {\n this.sendToSocket(client.socket, message);\n }\n\n logger.broadcastSent('mobiles');\n }\n\n broadcastToAll(message: OutboundMessage): void {\n for (const client of this.connectionManager.getAll()) {\n this.sendToSocket(client.socket, message);\n }\n\n logger.broadcastSent('all');\n }\n\n broadcast(message: unknown, target: 'browsers' | 'mobiles' | 'all' = 'all'): void {\n const broadcastMessage = createMessage<BroadcastMessage>({\n type: MessageType.BROADCAST,\n payload: message,\n });\n\n if (target === 'browsers') {\n this.broadcastToBrowsers(broadcastMessage);\n return;\n }\n\n if (target === 'mobiles') {\n this.broadcastToMobiles(broadcastMessage);\n return;\n }\n\n this.broadcastToAll(broadcastMessage);\n }\n\n broadcastDeviceStatus(): void {\n const message = createMessage<DeviceStatusMessage>({\n type: MessageType.DEVICE_STATUS,\n payload: this.deviceRegistry.snapshot(),\n });\n\n this.broadcastToAll(message);\n }\n}\n","import type { RefreshInitiator, RefreshType } from '../types/protocol';\r\nimport { REFRESH_TIMEOUT_MS } from '../types/protocol';\r\n\r\nexport type PendingRefresh = {\r\n deviceId: string;\r\n refreshType: RefreshType;\r\n startedAt: number;\r\n initiator: RefreshInitiator;\r\n browserConnectionId?: string;\r\n notifyAllBrowsers?: boolean;\r\n};\r\n\r\nexport class PendingRefreshStore {\r\n private readonly pendingByDevice = new Map<string, PendingRefresh>();\r\n\r\n create(input: PendingRefresh): void {\r\n this.pendingByDevice.set(input.deviceId, input);\r\n }\r\n\r\n get(deviceId: string): PendingRefresh | undefined {\r\n return this.pendingByDevice.get(deviceId);\r\n }\r\n\r\n has(deviceId: string): boolean {\r\n return this.pendingByDevice.has(deviceId);\r\n }\r\n\r\n remove(deviceId: string): void {\r\n this.pendingByDevice.delete(deviceId);\r\n }\r\n\r\n getExpired(now = Date.now()): PendingRefresh[] {\r\n return [...this.pendingByDevice.values()].filter(\r\n (pending) => now - pending.startedAt >= REFRESH_TIMEOUT_MS,\r\n );\r\n }\r\n}\r\n","import type { WebSocket } from 'ws';\r\nimport {\r\n createMessage,\r\n DevToolsRole,\r\n MessageType,\r\n type ExportSnapshotErrorMessage,\r\n type ExportSnapshotRequestMessage,\r\n type RefreshErrorCode,\r\n type RefreshErrorMessage,\r\n type RefreshRequestMessage,\r\n type RefreshState,\r\n type RefreshStatusMessage,\r\n type SnapshotReadyMessage,\r\n type SnapshotUploadRequestedMessage,\r\n} from '../types/protocol';\r\nimport { logger } from '../utils/logger';\r\nimport type { ConnectionManager } from './connectionManager';\r\nimport type { MessageRouter } from './messageRouter';\r\nimport type { PendingRefreshStore } from './pendingRefreshStore';\r\nimport type { SnapshotFileStore } from './snapshotFileStore';\r\nimport type { SnapshotStore } from './snapshotStore';\r\n\r\nexport class RefreshCoordinator {\r\n constructor(\r\n private readonly connectionManager: ConnectionManager,\r\n private readonly router: MessageRouter,\r\n private readonly pending: PendingRefreshStore,\r\n private readonly snapshots: SnapshotStore,\r\n private readonly snapshotFiles?: SnapshotFileStore,\r\n ) {}\r\n\r\n handleRefreshRequest(browserSocket: WebSocket, message: RefreshRequestMessage): void {\r\n const browser = this.connectionManager.getBySocket(browserSocket);\r\n\r\n if (!browser || browser.role !== DevToolsRole.BROWSER) {\r\n return;\r\n }\r\n\r\n if (message.refreshType !== 'snapshot') {\r\n this.sendRefreshError(browser.connectionId, {\r\n deviceId: message.deviceId,\r\n code: 'INVALID_REQUEST',\r\n message: `Unsupported refresh type: ${message.refreshType}`,\r\n });\r\n return;\r\n }\r\n\r\n const mobile = this.connectionManager.getByDeviceId(message.deviceId);\r\n\r\n if (!mobile) {\r\n this.sendRefreshError(browser.connectionId, {\r\n deviceId: message.deviceId,\r\n code: 'DEVICE_OFFLINE',\r\n message: `Device ${message.deviceId} is not connected`,\r\n });\r\n return;\r\n }\r\n\r\n if (this.pending.has(message.deviceId)) {\r\n this.sendRefreshError(browser.connectionId, {\r\n deviceId: message.deviceId,\r\n code: 'REFRESH_IN_PROGRESS',\r\n message: 'A refresh is already in progress for this device',\r\n });\r\n return;\r\n }\r\n\r\n this.pending.create({\r\n deviceId: message.deviceId,\r\n initiator: 'browser',\r\n browserConnectionId: browser.connectionId,\r\n refreshType: message.refreshType,\r\n startedAt: Date.now(),\r\n });\r\n\r\n logger.refreshStarted(message.deviceId);\r\n\r\n this.sendRefreshStatus(browser.connectionId, message.deviceId, 'requested');\r\n this.sendRefreshStatus(browser.connectionId, message.deviceId, 'exporting');\r\n\r\n this.requestMobileUpload(message.deviceId, message.refreshType);\r\n }\r\n\r\n handleMobileExportRequest(mobileSocket: WebSocket, message: ExportSnapshotRequestMessage): void {\r\n const mobile = this.connectionManager.getBySocket(mobileSocket);\r\n\r\n if (!mobile || mobile.role !== DevToolsRole.MOBILE || !mobile.deviceId) {\r\n return;\r\n }\r\n\r\n if (message.refreshType !== 'snapshot') {\r\n this.sendExportSnapshotError(mobileSocket, {\r\n code: 'INVALID_REQUEST',\r\n message: `Unsupported refresh type: ${message.refreshType}`,\r\n });\r\n return;\r\n }\r\n\r\n if (this.pending.has(mobile.deviceId)) {\r\n this.sendExportSnapshotError(mobileSocket, {\r\n code: 'REFRESH_IN_PROGRESS',\r\n message: 'An export is already in progress for this device',\r\n });\r\n return;\r\n }\r\n\r\n this.pending.create({\r\n deviceId: mobile.deviceId,\r\n initiator: 'mobile',\r\n notifyAllBrowsers: true,\r\n refreshType: message.refreshType,\r\n startedAt: Date.now(),\r\n });\r\n\r\n logger.refreshStarted(mobile.deviceId);\r\n\r\n this.requestMobileUpload(mobile.deviceId, message.refreshType);\r\n }\r\n\r\n async handleSnapshotUpload(\r\n deviceId: string,\r\n body: Buffer,\r\n metadata?: { kind?: string; mimeType?: string; databaseName?: string },\r\n ): Promise<{ ok: true; stored: SnapshotReadyMessage } | { ok: false; code: RefreshErrorCode }> {\r\n const pending = this.pending.get(deviceId);\r\n\r\n if (!pending) {\r\n return { ok: false, code: 'SNAPSHOT_NOT_FOUND' };\r\n }\r\n\r\n if (pending.browserConnectionId) {\r\n this.sendRefreshStatus(pending.browserConnectionId, deviceId, 'uploading');\r\n }\r\n\r\n const stored = this.snapshots.set(deviceId, body, {\r\n kind: metadata?.kind ?? 'sqlite',\r\n mimeType: metadata?.mimeType ?? 'application/x-sqlite3',\r\n databaseName: metadata?.databaseName,\r\n });\r\n\r\n const mobile = this.connectionManager.getByDeviceId(deviceId);\r\n\r\n await this.snapshotFiles?.persistDeviceSnapshot({\r\n deviceId,\r\n bytes: body,\r\n kind: stored.kind,\r\n mimeType: stored.mimeType,\r\n databaseName: stored.databaseName,\r\n bundleId: mobile?.metadata?.bundleId,\r\n });\r\n\r\n logger.refreshUploaded(deviceId, body.byteLength);\r\n\r\n const readyMessage = createMessage<SnapshotReadyMessage>({\r\n type: MessageType.SNAPSHOT_READY,\r\n deviceId,\r\n size: body.byteLength,\r\n exportedAt: stored.exportedAt,\r\n kind: stored.kind,\r\n mimeType: stored.mimeType,\r\n ...(stored.databaseName ? { databaseName: stored.databaseName } : {}),\r\n });\r\n\r\n if (pending.notifyAllBrowsers) {\r\n this.router.broadcastToBrowsers(readyMessage);\r\n } else if (pending.browserConnectionId) {\r\n this.sendRefreshStatus(pending.browserConnectionId, deviceId, 'ready');\r\n this.router.sendToBrowser(pending.browserConnectionId, readyMessage);\r\n }\r\n\r\n this.pending.remove(deviceId);\r\n\r\n return { ok: true, stored: readyMessage };\r\n }\r\n\r\n getSnapshot(deviceId: string): Buffer | undefined {\r\n return this.snapshots.getBytes(deviceId);\r\n }\r\n\r\n async getSnapshotAsync(deviceId: string): Promise<Buffer | undefined> {\r\n if (this.snapshotFiles) {\r\n const fromDisk = await this.snapshotFiles.readDeviceSnapshot(deviceId);\r\n\r\n if (fromDisk) {\r\n return fromDisk;\r\n }\r\n }\r\n\r\n return this.snapshots.getBytes(deviceId);\r\n }\r\n\r\n checkTimeouts(): void {\r\n for (const pending of this.pending.getExpired()) {\r\n if (pending.initiator === 'mobile') {\r\n this.failMobileExport(\r\n pending.deviceId,\r\n 'TIMEOUT',\r\n 'Export timed out waiting for device upload',\r\n );\r\n continue;\r\n }\r\n\r\n if (pending.browserConnectionId) {\r\n this.failRefresh(\r\n pending.deviceId,\r\n pending.browserConnectionId,\r\n 'TIMEOUT',\r\n 'Refresh timed out waiting for device upload',\r\n );\r\n } else {\r\n this.pending.remove(pending.deviceId);\r\n }\r\n }\r\n }\r\n\r\n private requestMobileUpload(deviceId: string, refreshType: 'snapshot'): void {\r\n this.router.sendToMobile(\r\n deviceId,\r\n createMessage<SnapshotUploadRequestedMessage>({\r\n type: MessageType.SNAPSHOT_UPLOAD_REQUESTED,\r\n deviceId,\r\n refreshType,\r\n }),\r\n );\r\n }\r\n\r\n private failRefresh(\r\n deviceId: string,\r\n browserConnectionId: string,\r\n code: RefreshErrorCode,\r\n message: string,\r\n ): void {\r\n logger.refreshFailed(deviceId, code, message);\r\n\r\n this.sendRefreshError(browserConnectionId, {\r\n deviceId,\r\n code,\r\n message,\r\n });\r\n\r\n this.pending.remove(deviceId);\r\n }\r\n\r\n private failMobileExport(\r\n deviceId: string,\r\n code: RefreshErrorCode,\r\n message: string,\r\n ): void {\r\n logger.refreshFailed(deviceId, code, message);\r\n\r\n const mobile = this.connectionManager.getByDeviceId(deviceId);\r\n\r\n if (mobile) {\r\n this.sendExportSnapshotError(mobile.socket, { code, message });\r\n }\r\n\r\n const refreshError = createMessage<RefreshErrorMessage>({\r\n type: MessageType.REFRESH_ERROR,\r\n deviceId,\r\n code,\r\n message,\r\n });\r\n\r\n this.router.broadcastToBrowsers(refreshError);\r\n this.pending.remove(deviceId);\r\n }\r\n\r\n private sendRefreshStatus(\r\n browserConnectionId: string,\r\n deviceId: string,\r\n state: RefreshState,\r\n ): void {\r\n const statusMessage = createMessage<RefreshStatusMessage>({\r\n type: MessageType.REFRESH_STATUS,\r\n deviceId,\r\n state,\r\n });\r\n\r\n this.router.sendToBrowser(browserConnectionId, statusMessage);\r\n }\r\n\r\n private sendRefreshError(\r\n browserConnectionId: string,\r\n input: {\r\n deviceId: string;\r\n code: RefreshErrorCode;\r\n message: string;\r\n },\r\n ): void {\r\n const message = createMessage<RefreshErrorMessage>({\r\n type: MessageType.REFRESH_ERROR,\r\n deviceId: input.deviceId,\r\n code: input.code,\r\n message: input.message,\r\n });\r\n\r\n this.router.sendToBrowser(browserConnectionId, message);\r\n logger.refreshFailed(input.deviceId, input.code, input.message);\r\n }\r\n\r\n private sendExportSnapshotError(\r\n mobileSocket: WebSocket,\r\n input: {\r\n code: RefreshErrorCode;\r\n message: string;\r\n },\r\n ): void {\r\n const message = createMessage<ExportSnapshotErrorMessage>({\r\n type: MessageType.EXPORT_SNAPSHOT_ERROR,\r\n code: input.code,\r\n message: input.message,\r\n });\r\n\r\n this.router.sendToSocket(mobileSocket, message);\r\n }\r\n}\r\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\r\nimport path from 'node:path';\r\n\r\nexport const DEFAULT_DATA_DIR = '.devtools';\r\n\r\n/** @deprecated Legacy single-database path. Removed — use per-device exports instead. */\r\nexport const DEFAULT_DATABASE_RELATIVE_PATH = 'databases/active.db';\r\n\r\nexport type ProjectDevToolsConfig = {\r\n /** @deprecated No longer used. */\r\n defaultDatabase?: string;\r\n deviceSync?: {\r\n /** @deprecated Ignored — active.db is no longer written. */\r\n promoteLatestToActive?: boolean;\r\n };\r\n};\r\n\r\nexport type DatabaseManifestEntry = {\r\n id: string;\r\n label: string;\r\n relativePath: string;\r\n source: 'active' | 'device';\r\n deviceId?: string;\r\n bundleId?: string;\r\n storageKey?: string;\r\n kind: string;\r\n mimeType: string;\r\n databaseName?: string;\r\n size: number;\r\n updatedAt: number;\r\n};\r\n\r\nexport type DatabaseManifest = {\r\n version: 1;\r\n /** @deprecated No longer written. */\r\n activeDatabase?: string;\r\n entries: DatabaseManifestEntry[];\r\n};\r\n\r\nexport type PersistDeviceSnapshotInput = {\r\n deviceId: string;\r\n bytes: Buffer;\r\n kind: string;\r\n mimeType: string;\r\n databaseName?: string;\r\n bundleId?: string;\r\n};\r\n\r\nexport type PersistDeviceSnapshotResult = {\r\n deviceRelativePath: string;\r\n exportedAt: number;\r\n size: number;\r\n};\r\n\r\nconst DEFAULT_CONFIG: ProjectDevToolsConfig = {\r\n deviceSync: {\r\n promoteLatestToActive: false,\r\n },\r\n};\r\n\r\nexport function resolveDataDir(explicitDir?: string): string {\r\n const fromEnv = process.env.DATABASE_DEVTOOLS_DATA_DIR?.trim();\r\n\r\n if (explicitDir?.trim()) {\r\n return path.resolve(explicitDir.trim());\r\n }\r\n\r\n if (fromEnv) {\r\n return path.resolve(fromEnv);\r\n }\r\n\r\n return path.resolve(process.cwd(), DEFAULT_DATA_DIR);\r\n}\r\n\r\nexport function isPersistenceEnabled(): boolean {\r\n const flag = process.env.DATABASE_DEVTOOLS_SNAPSHOT_PERSIST?.trim().toLowerCase();\r\n\r\n if (flag === '0' || flag === 'false' || flag === 'off') {\r\n return false;\r\n }\r\n\r\n return true;\r\n}\r\n\r\nexport function sanitizePathSegment(value: string): string {\r\n return value.replace(/[^a-zA-Z0-9._-]+/g, '_');\r\n}\r\n\r\nexport function resolveProjectPaths(dataDir: string) {\r\n const databasesDir = path.join(dataDir, 'databases');\r\n const devicesDir = path.join(databasesDir, 'devices');\r\n const configPath = path.join(dataDir, 'devtools.json');\r\n const manifestPath = path.join(dataDir, 'manifest.json');\r\n\r\n return {\r\n dataDir,\r\n databasesDir,\r\n devicesDir,\r\n configPath,\r\n manifestPath,\r\n };\r\n}\r\n\r\nexport async function ensureProjectDirectories(dataDir: string): Promise<void> {\r\n const paths = resolveProjectPaths(dataDir);\r\n\r\n await mkdir(paths.devicesDir, { recursive: true });\r\n}\r\n\r\nexport async function loadProjectConfig(dataDir: string): Promise<ProjectDevToolsConfig> {\r\n const { configPath } = resolveProjectPaths(dataDir);\r\n\r\n try {\r\n const raw = await readFile(configPath, 'utf8');\r\n const parsed = JSON.parse(raw) as ProjectDevToolsConfig;\r\n\r\n return {\r\n ...DEFAULT_CONFIG,\r\n ...parsed,\r\n deviceSync: {\r\n promoteLatestToActive: false,\r\n },\r\n };\r\n } catch {\r\n return { ...DEFAULT_CONFIG };\r\n }\r\n}\r\n\r\nexport async function writeDefaultProjectConfig(dataDir: string): Promise<void> {\r\n const { configPath } = resolveProjectPaths(dataDir);\r\n\r\n try {\r\n await readFile(configPath, 'utf8');\r\n } catch {\r\n await mkdir(dataDir, { recursive: true });\r\n await writeFile(configPath, `${JSON.stringify(DEFAULT_CONFIG, null, 2)}\\n`, 'utf8');\r\n }\r\n}\r\n\r\nexport function resolveActiveDatabasePath(dataDir: string, config: ProjectDevToolsConfig): string {\r\n const relative = config.defaultDatabase ?? DEFAULT_DATABASE_RELATIVE_PATH;\r\n return path.join(dataDir, relative);\r\n}\r\n\r\nexport function deviceDatabaseFileName(deviceId: string): string {\r\n return `Database-${sanitizePathSegment(deviceId)}.db`;\r\n}\r\n\r\nexport const DEVICE_EXPORT_FILE_NAME = 'database.db';\r\n\r\nexport function resolveDeviceStorageKey(input: { bundleId?: string; deviceId: string }): string {\r\n const bundleId = input.bundleId?.trim();\r\n\r\n if (bundleId) {\r\n return sanitizePathSegment(bundleId);\r\n }\r\n\r\n return sanitizePathSegment(input.deviceId);\r\n}\r\n\r\nexport function deviceStorageManifestId(storageKey: string): string {\r\n return `device:${storageKey}`;\r\n}\r\n\r\nexport function deviceStorageRelativePath(storageKey: string): string {\r\n return path\r\n .join('databases', 'devices', storageKey, DEVICE_EXPORT_FILE_NAME)\r\n .replace(/\\\\/g, '/');\r\n}\r\n\r\nexport function deviceDatabaseRelativePath(deviceId: string): string {\r\n const segment = sanitizePathSegment(deviceId);\r\n return path\r\n .join('databases', 'devices', segment, deviceDatabaseFileName(deviceId))\r\n .replace(/\\\\/g, '/');\r\n}\r\n\r\n/** @deprecated Legacy path — migrated reads still check this location. */\r\nexport function deviceLatestRelativePath(deviceId: string): string {\r\n return path.join('databases', 'devices', sanitizePathSegment(deviceId), 'latest.db').replace(/\\\\/g, '/');\r\n}\r\n\r\nexport async function readManifest(dataDir: string): Promise<DatabaseManifest> {\r\n const { manifestPath } = resolveProjectPaths(dataDir);\r\n\r\n try {\r\n const raw = await readFile(manifestPath, 'utf8');\r\n const parsed = JSON.parse(raw) as DatabaseManifest;\r\n\r\n if (parsed.version !== 1 || !Array.isArray(parsed.entries)) {\r\n return { version: 1, entries: [] };\r\n }\r\n\r\n return parsed;\r\n } catch {\r\n return { version: 1, entries: [] };\r\n }\r\n}\r\n\r\nexport async function writeManifest(dataDir: string, manifest: DatabaseManifest): Promise<void> {\r\n const { manifestPath } = resolveProjectPaths(dataDir);\r\n\r\n await mkdir(dataDir, { recursive: true });\r\n await writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\\n`, 'utf8');\r\n}\r\n\r\nexport function upsertManifestEntry(\r\n manifest: DatabaseManifest,\r\n entry: DatabaseManifestEntry,\r\n): DatabaseManifest {\r\n const entries = manifest.entries.filter((item) => item.id !== entry.id);\r\n entries.push(entry);\r\n\r\n entries.sort((left, right) => right.updatedAt - left.updatedAt);\r\n\r\n return {\r\n version: manifest.version,\r\n entries,\r\n };\r\n}\r\n","import type { DatabaseManifestEntry } from './projectData';\r\nimport { deviceStorageManifestId, sanitizePathSegment } from './projectData';\r\n\r\nexport type ListedDeviceExportLike = {\r\n id: string;\r\n deviceId?: string;\r\n bundleId?: string;\r\n storageKey?: string;\r\n databaseName?: string;\r\n updatedAt: number;\r\n};\r\n\r\nexport function deriveStorageKeyFromEntry(entry: DatabaseManifestEntry): string {\r\n if (entry.storageKey) {\r\n return entry.storageKey;\r\n }\r\n\r\n if (entry.bundleId) {\r\n return sanitizePathSegment(entry.bundleId);\r\n }\r\n\r\n const match = entry.relativePath.match(/databases\\/devices\\/([^/]+)\\//);\r\n\r\n if (match?.[1]) {\r\n return match[1];\r\n }\r\n\r\n if (entry.deviceId) {\r\n return sanitizePathSegment(entry.deviceId);\r\n }\r\n\r\n return entry.id;\r\n}\r\n\r\nexport function findManifestEntryByDeviceId(\r\n entries: DatabaseManifestEntry[],\r\n deviceId: string,\r\n): DatabaseManifestEntry | undefined {\r\n return entries.find((entry) => entry.source === 'device' && entry.deviceId === deviceId);\r\n}\r\n\r\nexport type PruneDeviceExportsInput = {\r\n keepStorageKey: string;\r\n keepDeviceId: string;\r\n bundleId?: string;\r\n databaseName?: string;\r\n};\r\n\r\nexport function selectDeviceExportEntriesToPrune(\r\n entries: DatabaseManifestEntry[],\r\n keep: PruneDeviceExportsInput,\r\n): DatabaseManifestEntry[] {\r\n const keepManifestId = deviceStorageManifestId(keep.keepStorageKey);\r\n\r\n return entries.filter((entry) => {\r\n if (entry.source !== 'device') {\r\n return false;\r\n }\r\n\r\n if (entry.id === keepManifestId) {\r\n return false;\r\n }\r\n\r\n const entryStorageKey = deriveStorageKeyFromEntry(entry);\r\n\r\n if (entryStorageKey === keep.keepStorageKey) {\r\n return true;\r\n }\r\n\r\n if (keep.bundleId && entry.bundleId === keep.bundleId) {\r\n return true;\r\n }\r\n\r\n if (\r\n keep.bundleId &&\r\n keep.databaseName &&\r\n !entry.bundleId &&\r\n entry.databaseName === keep.databaseName\r\n ) {\r\n return true;\r\n }\r\n\r\n if (\r\n !keep.bundleId &&\r\n keep.databaseName &&\r\n entry.databaseName === keep.databaseName &&\r\n entry.deviceId !== keep.keepDeviceId\r\n ) {\r\n return true;\r\n }\r\n\r\n return false;\r\n });\r\n}\r\n\r\nexport function dedupeListedDeviceExports<T extends ListedDeviceExportLike>(entries: T[]): T[] {\r\n const byStorageKey = new Map<string, T>();\r\n\r\n for (const entry of entries) {\r\n const storageKey = entry.storageKey\r\n ? entry.storageKey\r\n : entry.bundleId\r\n ? sanitizePathSegment(entry.bundleId)\r\n : entry.deviceId\r\n ? sanitizePathSegment(entry.deviceId)\r\n : entry.id;\r\n\r\n const existing = byStorageKey.get(storageKey);\r\n\r\n if (!existing || entry.updatedAt > existing.updatedAt) {\r\n byStorageKey.set(storageKey, entry);\r\n }\r\n }\r\n\r\n return [...byStorageKey.values()].sort((left, right) => right.updatedAt - left.updatedAt);\r\n}\r\n\r\nexport type ReconcileLegacyExportsInput = {\r\n entries: DatabaseManifestEntry[];\r\n preferredDeviceId?: string;\r\n};\r\n\r\nexport function reconcileLegacyManifestEntries(\r\n input: ReconcileLegacyExportsInput,\r\n): DatabaseManifestEntry[] {\r\n const deviceEntries = input.entries.filter((entry) => entry.source === 'device');\r\n const otherEntries = input.entries.filter((entry) => entry.source !== 'device');\r\n const groups = new Map<string, DatabaseManifestEntry[]>();\r\n\r\n for (const entry of deviceEntries) {\r\n const groupKey = entry.bundleId\r\n ? `bundle:${entry.bundleId}`\r\n : entry.databaseName\r\n ? `db:${entry.databaseName}`\r\n : `device:${deriveStorageKeyFromEntry(entry)}`;\r\n\r\n const group = groups.get(groupKey) ?? [];\r\n group.push(entry);\r\n groups.set(groupKey, group);\r\n }\r\n\r\n const keptDeviceEntries: DatabaseManifestEntry[] = [];\r\n\r\n for (const group of groups.values()) {\r\n if (group.length === 1) {\r\n keptDeviceEntries.push(group[0]!);\r\n continue;\r\n }\r\n\r\n const preferred = input.preferredDeviceId\r\n ? group.find((entry) => entry.deviceId === input.preferredDeviceId)\r\n : undefined;\r\n\r\n const newest = [...group].sort((left, right) => right.updatedAt - left.updatedAt)[0]!;\r\n keptDeviceEntries.push(preferred ?? newest);\r\n }\r\n\r\n return [...otherEntries, ...keptDeviceEntries].sort((left, right) => right.updatedAt - left.updatedAt);\r\n}\r\n\r\nexport function removedManifestEntries(\r\n before: DatabaseManifestEntry[],\r\n after: DatabaseManifestEntry[],\r\n): DatabaseManifestEntry[] {\r\n const afterIds = new Set(after.map((entry) => entry.id));\r\n return before.filter((entry) => !afterIds.has(entry.id));\r\n}\r\n","import { readFile, rm, stat, writeFile } from 'node:fs/promises';\r\nimport path from 'node:path';\r\nimport {\r\n DEFAULT_DATABASE_RELATIVE_PATH,\r\n readManifest,\r\n resolveProjectPaths,\r\n writeManifest,\r\n type DatabaseManifest,\r\n type ProjectDevToolsConfig,\r\n} from './projectData';\r\n\r\nconst NORMALIZED_CONFIG: ProjectDevToolsConfig = {\r\n deviceSync: {\r\n promoteLatestToActive: false,\r\n },\r\n};\r\n\r\nexport function stripLegacyActiveManifest(manifest: DatabaseManifest): DatabaseManifest {\r\n const entries = manifest.entries.filter(\r\n (entry) =>\r\n entry.source !== 'active' &&\r\n entry.id !== 'active' &&\r\n !entry.id.startsWith('import:'),\r\n );\r\n\r\n return {\r\n version: 1,\r\n entries,\r\n };\r\n}\r\n\r\nexport function normalizeProjectConfig(config: ProjectDevToolsConfig): ProjectDevToolsConfig {\r\n return {\r\n ...NORMALIZED_CONFIG,\r\n deviceSync: {\r\n ...NORMALIZED_CONFIG.deviceSync,\r\n promoteLatestToActive: false,\r\n },\r\n };\r\n}\r\n\r\nexport async function migrateLegacyActiveDatabase(dataDir: string): Promise<boolean> {\r\n const { configPath } = resolveProjectPaths(dataDir);\r\n const manifest = await readManifest(dataDir);\r\n const stripped = stripLegacyActiveManifest(manifest);\r\n const activeDbPath = path.join(dataDir, DEFAULT_DATABASE_RELATIVE_PATH);\r\n\r\n let changed =\r\n stripped.entries.length !== manifest.entries.length || Boolean(manifest.activeDatabase);\r\n\r\n if (changed) {\r\n await writeManifest(dataDir, stripped);\r\n }\r\n\r\n try {\r\n await stat(activeDbPath);\r\n const hasDeviceExports = stripped.entries.some((entry) => entry.source === 'device');\r\n\r\n if (hasDeviceExports || manifest.entries.some((entry) => entry.source === 'active')) {\r\n await rm(activeDbPath, { force: true });\r\n changed = true;\r\n }\r\n } catch {\r\n // active.db not present\r\n }\r\n\r\n try {\r\n const raw = await readFile(configPath, 'utf8');\r\n const parsed = JSON.parse(raw) as ProjectDevToolsConfig;\r\n\r\n if (parsed.defaultDatabase || parsed.deviceSync?.promoteLatestToActive) {\r\n await writeFile(\r\n configPath,\r\n `${JSON.stringify(normalizeProjectConfig(parsed), null, 2)}\\n`,\r\n 'utf8',\r\n );\r\n changed = true;\r\n }\r\n } catch {\r\n // config will be created on next export\r\n }\r\n\r\n const importsDir = path.join(dataDir, 'databases', 'imports');\r\n\r\n try {\r\n await stat(importsDir);\r\n await rm(importsDir, { recursive: true, force: true });\r\n changed = true;\r\n } catch {\r\n // imports directory not present\r\n }\r\n\r\n return changed;\r\n}\r\n","import { mkdir, readFile, rm, stat, writeFile } from 'node:fs/promises';\r\nimport path from 'node:path';\r\nimport { SQLITE_SNAPSHOT_MIME_TYPE } from '../types/snapshot';\r\nimport {\r\n dedupeListedDeviceExports,\r\n findManifestEntryByDeviceId,\r\n reconcileLegacyManifestEntries,\r\n removedManifestEntries,\r\n selectDeviceExportEntriesToPrune,\r\n} from './deviceExportStorage';\r\nimport { migrateLegacyActiveDatabase } from './migrateLegacyActiveDb';\r\nimport {\r\n deviceDatabaseRelativePath,\r\n deviceLatestRelativePath,\r\n deviceStorageManifestId,\r\n deviceStorageRelativePath,\r\n ensureProjectDirectories,\r\n isPersistenceEnabled,\r\n readManifest,\r\n resolveDataDir,\r\n resolveDeviceStorageKey,\r\n resolveProjectPaths,\r\n sanitizePathSegment,\r\n upsertManifestEntry,\r\n writeDefaultProjectConfig,\r\n writeManifest,\r\n type DatabaseManifestEntry,\r\n type PersistDeviceSnapshotInput,\r\n type PersistDeviceSnapshotResult,\r\n} from './projectData';\r\n\r\nexport type ProjectDatabaseMeta = {\r\n exists: boolean;\r\n relativePath?: string;\r\n absolutePath?: string;\r\n kind?: string;\r\n mimeType?: string;\r\n databaseName?: string;\r\n size?: number;\r\n updatedAt?: number;\r\n source?: DatabaseManifestEntry['source'];\r\n deviceId?: string;\r\n};\r\n\r\nexport type ListedProjectDatabase = {\r\n id: string;\r\n label: string;\r\n relativePath: string;\r\n source: DatabaseManifestEntry['source'];\r\n deviceId?: string;\r\n bundleId?: string;\r\n storageKey?: string;\r\n databaseName?: string;\r\n size: number;\r\n updatedAt: number;\r\n};\r\n\r\nexport class SnapshotFileStore {\r\n private readonly dataDir: string;\r\n private readonly enabled: boolean;\r\n\r\n constructor(options?: { dataDir?: string; enabled?: boolean }) {\r\n this.dataDir = resolveDataDir(options?.dataDir);\r\n this.enabled = options?.enabled ?? isPersistenceEnabled();\r\n }\r\n\r\n getDataDir(): string {\r\n return this.dataDir;\r\n }\r\n\r\n isEnabled(): boolean {\r\n return this.enabled;\r\n }\r\n\r\n async persistDeviceSnapshot(\r\n input: PersistDeviceSnapshotInput,\r\n ): Promise<PersistDeviceSnapshotResult | null> {\r\n if (!this.enabled) {\r\n return null;\r\n }\r\n\r\n await writeDefaultProjectConfig(this.dataDir);\r\n await ensureProjectDirectories(this.dataDir);\r\n\r\n const storageKey = resolveDeviceStorageKey({\r\n bundleId: input.bundleId,\r\n deviceId: input.deviceId,\r\n });\r\n const deviceRelativePath = deviceStorageRelativePath(storageKey);\r\n const deviceAbsolutePath = path.join(this.dataDir, deviceRelativePath);\r\n const exportedAt = Date.now();\r\n\r\n await this.pruneDeviceExports({\r\n keepStorageKey: storageKey,\r\n keepDeviceId: input.deviceId,\r\n bundleId: input.bundleId,\r\n databaseName: input.databaseName,\r\n });\r\n\r\n await mkdir(path.dirname(deviceAbsolutePath), { recursive: true });\r\n await writeFile(deviceAbsolutePath, input.bytes);\r\n\r\n const manifest = await readManifest(this.dataDir);\r\n\r\n const deviceEntry: DatabaseManifestEntry = {\r\n id: deviceStorageManifestId(storageKey),\r\n label: input.databaseName ?? `Device ${input.deviceId}`,\r\n relativePath: deviceRelativePath.replace(/\\\\/g, '/'),\r\n source: 'device',\r\n deviceId: input.deviceId,\r\n bundleId: input.bundleId,\r\n storageKey,\r\n kind: input.kind,\r\n mimeType: input.mimeType,\r\n databaseName: input.databaseName,\r\n size: input.bytes.byteLength,\r\n updatedAt: exportedAt,\r\n };\r\n\r\n const nextManifest = upsertManifestEntry(manifest, deviceEntry);\r\n\r\n await writeManifest(this.dataDir, nextManifest);\r\n\r\n return {\r\n deviceRelativePath: deviceRelativePath.replace(/\\\\/g, '/'),\r\n exportedAt,\r\n size: input.bytes.byteLength,\r\n };\r\n }\r\n\r\n async reconcileOnMobileConnect(input: {\r\n deviceId: string;\r\n bundleId?: string;\r\n }): Promise<void> {\r\n if (!this.enabled) {\r\n return;\r\n }\r\n\r\n await this.reconcileLegacyExports(input.deviceId);\r\n\r\n const storageKey = resolveDeviceStorageKey({\r\n bundleId: input.bundleId,\r\n deviceId: input.deviceId,\r\n });\r\n const manifest = await readManifest(this.dataDir);\r\n const canonicalEntry = manifest.entries.find(\r\n (entry) => entry.source === 'device' && entry.storageKey === storageKey,\r\n );\r\n\r\n if (canonicalEntry && canonicalEntry.deviceId !== input.deviceId) {\r\n const updated = upsertManifestEntry(manifest, {\r\n ...canonicalEntry,\r\n deviceId: input.deviceId,\r\n bundleId: input.bundleId ?? canonicalEntry.bundleId,\r\n updatedAt: Date.now(),\r\n });\r\n\r\n await writeManifest(this.dataDir, updated);\r\n }\r\n\r\n await this.pruneDeviceExports({\r\n keepStorageKey: storageKey,\r\n keepDeviceId: input.deviceId,\r\n bundleId: input.bundleId,\r\n databaseName: canonicalEntry?.databaseName,\r\n });\r\n }\r\n\r\n async readDeviceSnapshot(deviceId: string): Promise<Buffer | undefined> {\r\n return this.readDeviceDatabase(deviceId);\r\n }\r\n\r\n async readDeviceDatabase(deviceId: string): Promise<Buffer | undefined> {\r\n if (!this.enabled) {\r\n return undefined;\r\n }\r\n\r\n const resolved = await this.resolveDeviceDatabaseFile(deviceId);\r\n\r\n if (!resolved) {\r\n return undefined;\r\n }\r\n\r\n try {\r\n return await readFile(resolved.absolutePath);\r\n } catch {\r\n return undefined;\r\n }\r\n }\r\n\r\n async getDeviceDatabaseMeta(deviceId: string): Promise<ProjectDatabaseMeta> {\r\n if (!this.enabled) {\r\n return { exists: false, deviceId };\r\n }\r\n\r\n const resolved = await this.resolveDeviceDatabaseFile(deviceId);\r\n\r\n if (!resolved) {\r\n return { exists: false, deviceId };\r\n }\r\n\r\n try {\r\n const fileStat = await stat(resolved.absolutePath);\r\n const manifest = await readManifest(this.dataDir);\r\n const entry = manifest.entries.find(\r\n (item) => item.deviceId === deviceId && item.source === 'device',\r\n );\r\n\r\n return {\r\n exists: true,\r\n relativePath: resolved.relativePath,\r\n absolutePath: resolved.absolutePath,\r\n kind: entry?.kind ?? 'sqlite',\r\n mimeType: entry?.mimeType ?? SQLITE_SNAPSHOT_MIME_TYPE,\r\n databaseName: entry?.databaseName ?? path.basename(resolved.absolutePath),\r\n size: fileStat.size,\r\n updatedAt: entry?.updatedAt ?? fileStat.mtimeMs,\r\n source: 'device',\r\n deviceId,\r\n };\r\n } catch {\r\n return { exists: false, deviceId, relativePath: resolved.relativePath };\r\n }\r\n }\r\n\r\n async listDeviceExports(): Promise<ListedProjectDatabase[]> {\r\n await this.reconcileLegacyExports();\r\n const databases = await this.listDatabases();\r\n const deviceExports = databases.filter((entry) => entry.source === 'device' && entry.deviceId);\r\n return dedupeListedDeviceExports(deviceExports);\r\n }\r\n\r\n private async reconcileLegacyExports(preferredDeviceId?: string): Promise<void> {\r\n if (!this.enabled) {\r\n return;\r\n }\r\n\r\n await migrateLegacyActiveDatabase(this.dataDir);\r\n\r\n const manifest = await readManifest(this.dataDir);\r\n const nextEntries = reconcileLegacyManifestEntries({\r\n entries: manifest.entries,\r\n preferredDeviceId,\r\n });\r\n\r\n if (nextEntries.length === manifest.entries.length) {\r\n const sameOrder = nextEntries.every((entry, index) => entry.id === manifest.entries[index]?.id);\r\n\r\n if (sameOrder) {\r\n return;\r\n }\r\n }\r\n\r\n const removed = removedManifestEntries(manifest.entries, nextEntries);\r\n\r\n for (const entry of removed) {\r\n await this.deleteEntryFiles(entry);\r\n }\r\n\r\n await writeManifest(this.dataDir, {\r\n ...manifest,\r\n entries: nextEntries,\r\n });\r\n }\r\n\r\n private async pruneDeviceExports(input: {\r\n keepStorageKey: string;\r\n keepDeviceId: string;\r\n bundleId?: string;\r\n databaseName?: string;\r\n }): Promise<void> {\r\n const manifest = await readManifest(this.dataDir);\r\n const removed = selectDeviceExportEntriesToPrune(manifest.entries, input);\r\n\r\n if (removed.length === 0) {\r\n return;\r\n }\r\n\r\n for (const entry of removed) {\r\n await this.deleteEntryFiles(entry);\r\n }\r\n\r\n const removedIds = new Set(removed.map((entry) => entry.id));\r\n\r\n await writeManifest(this.dataDir, {\r\n ...manifest,\r\n entries: manifest.entries.filter((entry) => !removedIds.has(entry.id)),\r\n });\r\n }\r\n\r\n private async deleteEntryFiles(entry: DatabaseManifestEntry): Promise<void> {\r\n const absolutePath = path.join(this.dataDir, entry.relativePath);\r\n\r\n try {\r\n await rm(absolutePath, { force: true });\r\n } catch {\r\n // ignore missing files\r\n }\r\n\r\n try {\r\n await rm(path.dirname(absolutePath), { recursive: true, force: true });\r\n } catch {\r\n // ignore cleanup failures\r\n }\r\n }\r\n\r\n private manifestEntryToListed(entry: DatabaseManifestEntry, fileStat: { size: number }): ListedProjectDatabase {\r\n return {\r\n id: entry.id,\r\n label: entry.label,\r\n relativePath: entry.relativePath,\r\n source: entry.source,\r\n deviceId: entry.deviceId,\r\n bundleId: entry.bundleId,\r\n storageKey: entry.storageKey,\r\n databaseName: entry.databaseName,\r\n size: fileStat.size,\r\n updatedAt: entry.updatedAt,\r\n };\r\n }\r\n\r\n private async resolveDeviceDatabaseFile(\r\n deviceId: string,\r\n ): Promise<{ relativePath: string; absolutePath: string } | undefined> {\r\n const manifest = await readManifest(this.dataDir);\r\n const manifestEntry = findManifestEntryByDeviceId(manifest.entries, deviceId);\r\n\r\n if (manifestEntry) {\r\n const absolutePath = path.join(this.dataDir, manifestEntry.relativePath);\r\n\r\n try {\r\n await stat(absolutePath);\r\n return { relativePath: manifestEntry.relativePath, absolutePath };\r\n } catch {\r\n // fall through to legacy paths\r\n }\r\n }\r\n\r\n const candidates = [\r\n deviceDatabaseRelativePath(deviceId),\r\n deviceLatestRelativePath(deviceId),\r\n ];\r\n\r\n for (const relativePath of candidates) {\r\n const absolutePath = path.join(this.dataDir, relativePath);\r\n\r\n try {\r\n await stat(absolutePath);\r\n return { relativePath, absolutePath };\r\n } catch {\r\n // try next candidate\r\n }\r\n }\r\n\r\n if (!manifestEntry) {\r\n return undefined;\r\n }\r\n\r\n const absolutePath = path.join(this.dataDir, manifestEntry.relativePath);\r\n\r\n try {\r\n await stat(absolutePath);\r\n return { relativePath: manifestEntry.relativePath, absolutePath };\r\n } catch {\r\n return undefined;\r\n }\r\n }\r\n\r\n /** @deprecated Proxies to the newest device export for backward-compatible API callers. */\r\n async readActiveDatabase(): Promise<Buffer | undefined> {\r\n if (!this.enabled) {\r\n return undefined;\r\n }\r\n\r\n const meta = await this.getActiveDatabaseMeta();\r\n\r\n if (!meta.exists || !meta.deviceId) {\r\n return undefined;\r\n }\r\n\r\n return this.readDeviceDatabase(meta.deviceId);\r\n }\r\n\r\n /** @deprecated Proxies to the newest device export for backward-compatible API callers. */\r\n async getActiveDatabaseMeta(): Promise<ProjectDatabaseMeta> {\r\n if (!this.enabled) {\r\n return { exists: false };\r\n }\r\n\r\n await migrateLegacyActiveDatabase(this.dataDir);\r\n\r\n const exports = await this.listDeviceExports();\r\n const latest = exports[0];\r\n\r\n if (!latest?.deviceId) {\r\n return { exists: false };\r\n }\r\n\r\n return this.getDeviceDatabaseMeta(latest.deviceId);\r\n }\r\n\r\n async listDatabases(): Promise<ListedProjectDatabase[]> {\r\n if (!this.enabled) {\r\n return [];\r\n }\r\n\r\n await ensureProjectDirectories(this.dataDir);\r\n await this.reconcileLegacyExports();\r\n\r\n const manifest = await readManifest(this.dataDir);\r\n const listed = new Map<string, ListedProjectDatabase>();\r\n\r\n for (const entry of manifest.entries) {\r\n if (entry.source === 'active' || entry.id.startsWith('import:')) {\r\n continue;\r\n }\r\n\r\n const absolutePath = path.join(this.dataDir, entry.relativePath);\r\n\r\n try {\r\n const fileStat = await stat(absolutePath);\r\n\r\n listed.set(entry.id, this.manifestEntryToListed(entry, fileStat));\r\n } catch {\r\n // Ignore missing files from manifest.\r\n }\r\n }\r\n\r\n return [...listed.values()].sort((left, right) => right.updatedAt - left.updatedAt);\r\n }\r\n\r\n async readDatabaseByRelativePath(relativePath: string): Promise<Buffer | undefined> {\r\n if (!this.enabled) {\r\n return undefined;\r\n }\r\n\r\n const normalized = relativePath.replace(/\\\\/g, '/');\r\n const absolutePath = path.resolve(this.dataDir, normalized);\r\n const dataDirResolved = path.resolve(this.dataDir);\r\n\r\n if (!absolutePath.startsWith(dataDirResolved)) {\r\n return undefined;\r\n }\r\n\r\n if (!normalized.toLowerCase().endsWith('.db')) {\r\n return undefined;\r\n }\r\n\r\n try {\r\n return await readFile(absolutePath);\r\n } catch {\r\n return undefined;\r\n }\r\n }\r\n\r\n getDeviceDirectoryName(deviceId: string): string {\r\n return sanitizePathSegment(deviceId);\r\n }\r\n}\r\n","export type StoredSnapshot = {\r\n deviceId: string;\r\n bytes: Buffer;\r\n kind: string;\r\n mimeType: string;\r\n databaseName?: string;\r\n exportedAt: number;\r\n};\r\n\r\nexport class SnapshotStore {\r\n private readonly snapshots = new Map<string, StoredSnapshot>();\r\n\r\n set(\r\n deviceId: string,\r\n bytes: Buffer,\r\n metadata: { kind: string; mimeType: string; databaseName?: string },\r\n ): StoredSnapshot {\r\n const stored: StoredSnapshot = {\r\n deviceId,\r\n bytes,\r\n kind: metadata.kind,\r\n mimeType: metadata.mimeType,\r\n databaseName: metadata.databaseName,\r\n exportedAt: Date.now(),\r\n };\r\n\r\n this.snapshots.set(deviceId, stored);\r\n return stored;\r\n }\r\n\r\n get(deviceId: string): StoredSnapshot | undefined {\r\n return this.snapshots.get(deviceId);\r\n }\r\n\r\n getBytes(deviceId: string): Buffer | undefined {\r\n return this.snapshots.get(deviceId)?.bytes;\r\n }\r\n}\r\n","import type { WebSocket } from 'ws';\r\nimport {\r\n createMessage,\r\n DevToolsRole,\r\n MessageType,\r\n type BeginTransactionMessage,\r\n type BeginTransactionRequestMessage,\r\n type CommitTransactionMessage,\r\n type CommitTransactionRequestMessage,\r\n type ExecuteWriteMessage,\r\n type RollbackTransactionMessage,\r\n type RollbackTransactionRequestMessage,\r\n type TransactionAckMessage,\r\n type TransactionStatusMessage,\r\n type WriteAckMessage,\r\n type WriteErrorCode,\r\n type WriteErrorMessage,\r\n type WriteRequestMessage,\r\n type WriteResultMessage,\r\n} from '../types/protocol';\r\nimport { logger } from '../utils/logger';\r\nimport type { ConnectionManager } from './connectionManager';\r\nimport type { MessageRouter } from './messageRouter';\r\nimport type { WriteSessionManager, WriteSession } from './writeSessionManager';\r\n\r\nexport class WriteCoordinator {\r\n constructor(\r\n private readonly connectionManager: ConnectionManager,\r\n private readonly router: MessageRouter,\r\n private readonly sessions: WriteSessionManager,\r\n ) {}\r\n\r\n handleBeginTransactionRequest(\r\n browserSocket: WebSocket,\r\n message: BeginTransactionRequestMessage,\r\n ): void {\r\n const browser = this.connectionManager.getBySocket(browserSocket);\r\n\r\n if (!browser || browser.role !== DevToolsRole.BROWSER) {\r\n return;\r\n }\r\n\r\n const mobile = this.connectionManager.getByDeviceId(message.deviceId);\r\n\r\n if (!mobile) {\r\n this.sendWriteError(browser.connectionId, {\r\n transactionId: message.transactionId,\r\n code: 'DEVICE_OFFLINE',\r\n message: `Device ${message.deviceId} is not connected`,\r\n });\r\n return;\r\n }\r\n\r\n if (this.sessions.getActiveForDevice(message.deviceId)) {\r\n this.sendWriteError(browser.connectionId, {\r\n transactionId: message.transactionId,\r\n code: 'TRANSACTION_BUSY',\r\n message: 'A transaction is already open for this device',\r\n });\r\n return;\r\n }\r\n\r\n this.sessions.create({\r\n transactionId: message.transactionId,\r\n deviceId: message.deviceId,\r\n browserConnectionId: browser.connectionId,\r\n });\r\n\r\n logger.syncStarted(message.transactionId, message.deviceId);\r\n\r\n this.router.sendToMobile(\r\n message.deviceId,\r\n createMessage<BeginTransactionMessage>({\r\n type: MessageType.BEGIN_TRANSACTION,\r\n transactionId: message.transactionId,\r\n }),\r\n );\r\n }\r\n\r\n handleCommitTransactionRequest(\r\n browserSocket: WebSocket,\r\n message: CommitTransactionRequestMessage,\r\n ): void {\r\n const browser = this.connectionManager.getBySocket(browserSocket);\r\n const session = this.sessions.get(message.transactionId);\r\n\r\n if (!browser || browser.role !== DevToolsRole.BROWSER || !session) {\r\n return;\r\n }\r\n\r\n if (session.browserConnectionId !== browser.connectionId) {\r\n return;\r\n }\r\n\r\n if (session.state !== 'open') {\r\n this.sendWriteError(browser.connectionId, {\r\n transactionId: message.transactionId,\r\n code: 'NO_TRANSACTION',\r\n message: 'Transaction is not open',\r\n });\r\n return;\r\n }\r\n\r\n this.sessions.setState(message.transactionId, 'committing');\r\n\r\n this.router.sendToMobile(\r\n session.deviceId,\r\n createMessage<CommitTransactionMessage>({\r\n type: MessageType.COMMIT_TRANSACTION,\r\n transactionId: message.transactionId,\r\n }),\r\n );\r\n }\r\n\r\n handleRollbackTransactionRequest(\r\n browserSocket: WebSocket,\r\n message: RollbackTransactionRequestMessage,\r\n ): void {\r\n const browser = this.connectionManager.getBySocket(browserSocket);\r\n const session = this.sessions.get(message.transactionId);\r\n\r\n if (!browser || browser.role !== DevToolsRole.BROWSER || !session) {\r\n return;\r\n }\r\n\r\n if (session.browserConnectionId !== browser.connectionId) {\r\n return;\r\n }\r\n\r\n if (session.state !== 'open' && session.state !== 'committing') {\r\n this.sendWriteError(browser.connectionId, {\r\n transactionId: message.transactionId,\r\n code: 'NO_TRANSACTION',\r\n message: 'Transaction is not open',\r\n });\r\n return;\r\n }\r\n\r\n this.sessions.setState(message.transactionId, 'rolling_back');\r\n\r\n this.router.sendToMobile(\r\n session.deviceId,\r\n createMessage<RollbackTransactionMessage>({\r\n type: MessageType.ROLLBACK_TRANSACTION,\r\n transactionId: message.transactionId,\r\n }),\r\n );\r\n }\r\n\r\n handleWriteRequest(browserSocket: WebSocket, message: WriteRequestMessage): void {\r\n const browser = this.connectionManager.getBySocket(browserSocket);\r\n const session = this.sessions.get(message.transactionId);\r\n\r\n if (!browser || browser.role !== DevToolsRole.BROWSER || !session) {\r\n return;\r\n }\r\n\r\n if (session.browserConnectionId !== browser.connectionId) {\r\n return;\r\n }\r\n\r\n if (session.state !== 'open') {\r\n this.sendWriteError(browser.connectionId, {\r\n transactionId: message.transactionId,\r\n writeId: message.writeId,\r\n code: 'NO_TRANSACTION',\r\n message: 'Transaction is not open',\r\n });\r\n return;\r\n }\r\n\r\n const mobile = this.connectionManager.getByDeviceId(session.deviceId);\r\n\r\n if (!mobile) {\r\n this.sendWriteError(browser.connectionId, {\r\n transactionId: message.transactionId,\r\n writeId: message.writeId,\r\n code: 'DEVICE_OFFLINE',\r\n message: `Device ${session.deviceId} is not connected`,\r\n });\r\n return;\r\n }\r\n\r\n this.sessions.incrementPendingWrites(message.transactionId);\r\n\r\n this.router.sendToMobile(\r\n session.deviceId,\r\n createMessage<ExecuteWriteMessage>({\r\n type: MessageType.EXECUTE_WRITE,\r\n writeId: message.writeId,\r\n transactionId: message.transactionId,\r\n operation: message.operation,\r\n }),\r\n );\r\n }\r\n\r\n handleTransactionAck(message: TransactionAckMessage): void {\r\n const session = this.sessions.get(message.transactionId);\r\n\r\n if (!session) {\r\n return;\r\n }\r\n\r\n if (!message.ok) {\r\n this.sessions.setState(message.transactionId, 'failed');\r\n this.sendWriteError(session.browserConnectionId, {\r\n transactionId: message.transactionId,\r\n code: message.action === 'begin' ? 'ADAPTER_ERROR' : 'WRITE_FAILED',\r\n message: message.message ?? `Transaction ${message.action} failed`,\r\n });\r\n this.sessions.remove(message.transactionId);\r\n return;\r\n }\r\n\r\n if (message.action === 'begin') {\r\n this.sendTransactionStatus(session.browserConnectionId, {\r\n transactionId: message.transactionId,\r\n deviceId: session.deviceId,\r\n state: 'open',\r\n });\r\n return;\r\n }\r\n\r\n if (message.action === 'commit') {\r\n this.sendTransactionStatus(session.browserConnectionId, {\r\n transactionId: message.transactionId,\r\n deviceId: session.deviceId,\r\n state: 'idle',\r\n });\r\n this.sessions.remove(message.transactionId);\r\n return;\r\n }\r\n\r\n this.sendTransactionStatus(session.browserConnectionId, {\r\n transactionId: message.transactionId,\r\n deviceId: session.deviceId,\r\n state: 'idle',\r\n message: message.message,\r\n });\r\n this.sessions.remove(message.transactionId);\r\n }\r\n\r\n handleWriteAck(message: WriteAckMessage): void {\r\n const session = this.sessions.get(message.transactionId);\r\n\r\n if (!session) {\r\n return;\r\n }\r\n\r\n this.sessions.decrementPendingWrites(message.transactionId);\r\n\r\n if (!message.ok) {\r\n this.sendWriteError(session.browserConnectionId, {\r\n transactionId: message.transactionId,\r\n writeId: message.writeId,\r\n code: 'WRITE_FAILED',\r\n message: message.message ?? 'Write operation failed',\r\n });\r\n return;\r\n }\r\n\r\n this.router.sendToBrowser(\r\n session.browserConnectionId,\r\n createMessage<WriteResultMessage>({\r\n type: MessageType.WRITE_RESULT,\r\n writeId: message.writeId,\r\n transactionId: message.transactionId,\r\n rowsAffected: message.rowsAffected ?? 0,\r\n }),\r\n );\r\n }\r\n\r\n checkTimeouts(): void {\r\n for (const session of this.sessions.getExpired()) {\r\n this.rollbackSession(session, 'TIMEOUT', 'Write transaction timed out');\r\n }\r\n }\r\n\r\n rollbackSessionsOnBrowserDisconnect(browserConnectionId: string): void {\r\n for (const session of this.sessions.getByBrowserConnectionId(browserConnectionId)) {\r\n this.rollbackSession(session, 'NO_TRANSACTION', 'Browser disconnected');\r\n }\r\n }\r\n\r\n rollbackSessionsForDevice(deviceId: string): void {\r\n for (const session of this.sessions.getByDeviceId(deviceId)) {\r\n this.rollbackSession(session, 'NO_TRANSACTION', 'Device disconnected');\r\n }\r\n }\r\n\r\n private rollbackSession(\r\n session: WriteSession,\r\n code: WriteErrorCode,\r\n message: string,\r\n ): void {\r\n logger.syncFailed(session.transactionId, code, message);\r\n\r\n this.sendWriteError(session.browserConnectionId, {\r\n transactionId: session.transactionId,\r\n code,\r\n message,\r\n });\r\n\r\n this.router.sendToMobile(\r\n session.deviceId,\r\n createMessage<RollbackTransactionMessage>({\r\n type: MessageType.ROLLBACK_TRANSACTION,\r\n transactionId: session.transactionId,\r\n }),\r\n );\r\n\r\n this.sessions.remove(session.transactionId);\r\n }\r\n\r\n private sendTransactionStatus(\r\n browserConnectionId: string,\r\n payload: Omit<TransactionStatusMessage, 'type' | 'timestamp'>,\r\n ): void {\r\n this.router.sendToBrowser(\r\n browserConnectionId,\r\n createMessage<TransactionStatusMessage>({\r\n type: MessageType.TRANSACTION_STATUS,\r\n ...payload,\r\n }),\r\n );\r\n }\r\n\r\n private sendWriteError(\r\n browserConnectionId: string,\r\n payload: {\r\n transactionId: string;\r\n writeId?: string;\r\n code: WriteErrorCode;\r\n message: string;\r\n },\r\n ): void {\r\n this.router.sendToBrowser(\r\n browserConnectionId,\r\n createMessage<WriteErrorMessage>({\r\n type: MessageType.WRITE_ERROR,\r\n ...payload,\r\n }),\r\n );\r\n }\r\n}\r\n","import type { TransactionStatusState } from '../types/protocol';\r\nimport { WRITE_TRANSACTION_TIMEOUT_MS } from '../types/protocol';\r\n\r\nexport type WriteSession = {\r\n transactionId: string;\r\n deviceId: string;\r\n browserConnectionId: string;\r\n state: TransactionStatusState;\r\n pendingWrites: number;\r\n createdAt: number;\r\n};\r\n\r\nexport class WriteSessionManager {\r\n private readonly sessions = new Map<string, WriteSession>();\r\n private readonly activeByDevice = new Map<string, string>();\r\n\r\n create(input: {\r\n transactionId: string;\r\n deviceId: string;\r\n browserConnectionId: string;\r\n }): WriteSession {\r\n const session: WriteSession = {\r\n transactionId: input.transactionId,\r\n deviceId: input.deviceId,\r\n browserConnectionId: input.browserConnectionId,\r\n state: 'opening',\r\n pendingWrites: 0,\r\n createdAt: Date.now(),\r\n };\r\n\r\n this.sessions.set(input.transactionId, session);\r\n this.activeByDevice.set(input.deviceId, input.transactionId);\r\n return session;\r\n }\r\n\r\n get(transactionId: string): WriteSession | undefined {\r\n return this.sessions.get(transactionId);\r\n }\r\n\r\n getActiveForDevice(deviceId: string): WriteSession | undefined {\r\n const transactionId = this.activeByDevice.get(deviceId);\r\n\r\n if (!transactionId) {\r\n return undefined;\r\n }\r\n\r\n return this.sessions.get(transactionId);\r\n }\r\n\r\n setState(transactionId: string, state: TransactionStatusState): WriteSession | undefined {\r\n const session = this.sessions.get(transactionId);\r\n\r\n if (!session) {\r\n return undefined;\r\n }\r\n\r\n session.state = state;\r\n return session;\r\n }\r\n\r\n incrementPendingWrites(transactionId: string): WriteSession | undefined {\r\n const session = this.sessions.get(transactionId);\r\n\r\n if (!session) {\r\n return undefined;\r\n }\r\n\r\n session.pendingWrites += 1;\r\n return session;\r\n }\r\n\r\n decrementPendingWrites(transactionId: string): WriteSession | undefined {\r\n const session = this.sessions.get(transactionId);\r\n\r\n if (!session) {\r\n return undefined;\r\n }\r\n\r\n session.pendingWrites = Math.max(0, session.pendingWrites - 1);\r\n return session;\r\n }\r\n\r\n remove(transactionId: string): void {\r\n const session = this.sessions.get(transactionId);\r\n\r\n if (!session) {\r\n return;\r\n }\r\n\r\n if (this.activeByDevice.get(session.deviceId) === transactionId) {\r\n this.activeByDevice.delete(session.deviceId);\r\n }\r\n\r\n this.sessions.delete(transactionId);\r\n }\r\n\r\n getExpired(now = Date.now()): WriteSession[] {\r\n return [...this.sessions.values()].filter((session) => {\r\n if (session.state === 'idle' || session.state === 'failed') {\r\n return false;\r\n }\r\n\r\n return now - session.createdAt >= WRITE_TRANSACTION_TIMEOUT_MS;\r\n });\r\n }\r\n\r\n getByBrowserConnectionId(browserConnectionId: string): WriteSession[] {\r\n return [...this.sessions.values()].filter(\r\n (session) => session.browserConnectionId === browserConnectionId,\r\n );\r\n }\r\n\r\n getByDeviceId(deviceId: string): WriteSession[] {\r\n return [...this.sessions.values()].filter((session) => session.deviceId === deviceId);\r\n }\r\n}\r\n","import express from 'express';\r\nimport { createServer, type Server } from 'node:http';\r\nimport {\r\n DEFAULT_DEVTOOLS_HOST,\r\n DEFAULT_DEVTOOLS_PORT,\r\n DEVICE_SNAPSHOT_API_PATH,\r\n MAX_SNAPSHOT_BYTES,\r\n PROJECT_DATABASE_API_PATH,\r\n PROJECT_DATABASE_META_API_PATH,\r\n PROJECT_DATABASES_API_PATH,\r\n PROJECT_DEVICE_EXPORTS_API_PATH,\r\n buildDevToolsHttpUrl,\r\n buildDevToolsWsUrl,\r\n} from '../types/protocol';\r\nimport { SNAPSHOT_KIND_HEADER, SNAPSHOT_MIME_HEADER, SNAPSHOT_NAME_HEADER, SQLITE_SNAPSHOT_MIME_TYPE } from '../types/snapshot';\r\nimport { logger } from '../utils/logger';\r\nimport { attachWebUi } from './attachWebUi';\r\nimport { attachWebSocket } from './attachWebSocket';\r\nimport { ConnectionManager } from './connectionManager';\r\nimport { createCorsMiddleware } from './cors';\r\nimport { DeviceRegistry } from './deviceRegistry';\r\nimport { Heartbeat } from './heartbeat';\r\nimport { MessageRouter } from './messageRouter';\r\nimport { PendingRefreshStore } from './pendingRefreshStore';\r\nimport { RefreshCoordinator } from './refreshCoordinator';\r\nimport { SnapshotFileStore } from './snapshotFileStore';\r\nimport { SnapshotStore } from './snapshotStore';\r\nimport { WriteCoordinator } from './writeCoordinator';\r\nimport { WriteSessionManager } from './writeSessionManager';\r\n\r\nexport type DevToolsServerOptions = {\r\n host?: string;\r\n port?: number;\r\n dataDir?: string;\r\n snapshotPersistence?: boolean;\r\n webDistPath?: string;\r\n};\r\n\r\nexport type DevToolsServerUrls = {\r\n httpUrl: string;\r\n wsUrl: string;\r\n webUiEnabled: boolean;\r\n};\r\n\r\nexport type DevToolsServer = {\r\n app: express.Express;\r\n httpServer: Server;\r\n connectionManager: ConnectionManager;\r\n deviceRegistry: DeviceRegistry;\r\n router: MessageRouter;\r\n heartbeat: Heartbeat;\r\n snapshotStore: SnapshotStore;\r\n snapshotFileStore: SnapshotFileStore;\r\n pendingRefreshStore: PendingRefreshStore;\r\n writeSessions: WriteSessionManager;\r\n refreshCoordinator: RefreshCoordinator;\r\n writeCoordinator: WriteCoordinator;\r\n urls: DevToolsServerUrls;\r\n close: () => Promise<void>;\r\n};\r\n\r\nexport async function createDevToolsServer(\r\n options: DevToolsServerOptions = {},\r\n): Promise<DevToolsServer> {\r\n const host = options.host ?? DEFAULT_DEVTOOLS_HOST;\r\n const port = options.port ?? DEFAULT_DEVTOOLS_PORT;\r\n\r\n const app = express();\r\n const connectionManager = new ConnectionManager();\r\n const deviceRegistry = new DeviceRegistry(connectionManager);\r\n const router = new MessageRouter(connectionManager, deviceRegistry);\r\n const heartbeat = new Heartbeat(connectionManager, router);\r\n const snapshotStore = new SnapshotStore();\r\n const snapshotFileStore = new SnapshotFileStore({\r\n dataDir: options.dataDir,\r\n enabled: options.snapshotPersistence,\r\n });\r\n const pendingRefreshStore = new PendingRefreshStore();\r\n const writeSessions = new WriteSessionManager();\r\n\r\n const refreshCoordinator = new RefreshCoordinator(\r\n connectionManager,\r\n router,\r\n pendingRefreshStore,\r\n snapshotStore,\r\n snapshotFileStore,\r\n );\r\n const writeCoordinator = new WriteCoordinator(connectionManager, router, writeSessions);\r\n\r\n app.use(createCorsMiddleware());\r\n\r\n app.get('/health', (_request, response) => {\r\n response.json({ ok: true, ...deviceRegistry.snapshot() });\r\n });\r\n\r\n app.post(\r\n `${DEVICE_SNAPSHOT_API_PATH}/:deviceId/snapshot`,\r\n express.raw({ type: 'application/octet-stream', limit: MAX_SNAPSHOT_BYTES }),\r\n async (request, response) => {\r\n const deviceId = decodeURIComponent(request.params.deviceId);\r\n const body = request.body;\r\n\r\n if (!Buffer.isBuffer(body) || body.length === 0) {\r\n response.status(400).json({ ok: false, error: 'Empty snapshot body' });\r\n return;\r\n }\r\n\r\n const kindHeader = request.header(SNAPSHOT_KIND_HEADER);\r\n const mimeHeader = request.header(SNAPSHOT_MIME_HEADER);\r\n const nameHeader = request.header(SNAPSHOT_NAME_HEADER);\r\n\r\n const result = await refreshCoordinator.handleSnapshotUpload(deviceId, body, {\r\n kind: typeof kindHeader === 'string' ? kindHeader : undefined,\r\n mimeType: typeof mimeHeader === 'string' ? mimeHeader : undefined,\r\n databaseName: typeof nameHeader === 'string' ? nameHeader : undefined,\r\n });\r\n\r\n if (!result.ok) {\r\n response.status(result.code === 'SNAPSHOT_NOT_FOUND' ? 404 : 400).json({\r\n ok: false,\r\n error: result.code,\r\n });\r\n return;\r\n }\r\n\r\n response.status(201).json({ ok: true, deviceId, size: body.byteLength });\r\n },\r\n );\r\n\r\n app.get(`${DEVICE_SNAPSHOT_API_PATH}/:deviceId/snapshot`, async (request, response) => {\r\n const deviceId = decodeURIComponent(request.params.deviceId);\r\n const snapshot = await refreshCoordinator.getSnapshotAsync(deviceId);\r\n\r\n if (!snapshot) {\r\n response.status(404).json({ ok: false, error: 'SNAPSHOT_NOT_FOUND' });\r\n return;\r\n }\r\n\r\n response\r\n .status(200)\r\n .set('Content-Type', 'application/octet-stream')\r\n .send(snapshot);\r\n });\r\n\r\n app.get(PROJECT_DATABASE_META_API_PATH, async (_request, response) => {\r\n const meta = await snapshotFileStore.getActiveDatabaseMeta();\r\n response.json(meta);\r\n });\r\n\r\n app.get(PROJECT_DATABASES_API_PATH, async (_request, response) => {\r\n const databases = await snapshotFileStore.listDatabases();\r\n response.json({ databases });\r\n });\r\n\r\n app.get(PROJECT_DEVICE_EXPORTS_API_PATH, async (_request, response) => {\r\n const devices = await snapshotFileStore.listDeviceExports();\r\n response.json({ devices });\r\n });\r\n\r\n app.get(`${PROJECT_DEVICE_EXPORTS_API_PATH}/:deviceId/database/meta`, async (request, response) => {\r\n const deviceId = decodeURIComponent(request.params.deviceId);\r\n const meta = await snapshotFileStore.getDeviceDatabaseMeta(deviceId);\r\n response.json(meta);\r\n });\r\n\r\n app.get(`${PROJECT_DEVICE_EXPORTS_API_PATH}/:deviceId/database`, async (request, response) => {\r\n const deviceId = decodeURIComponent(request.params.deviceId);\r\n const meta = await snapshotFileStore.getDeviceDatabaseMeta(deviceId);\r\n\r\n if (!meta.exists) {\r\n response.status(404).json({ ok: false, error: 'DEVICE_DATABASE_NOT_FOUND', deviceId });\r\n return;\r\n }\r\n\r\n const bytes = await snapshotFileStore.readDeviceDatabase(deviceId);\r\n\r\n if (!bytes) {\r\n response.status(404).json({ ok: false, error: 'DEVICE_DATABASE_NOT_FOUND', deviceId });\r\n return;\r\n }\r\n\r\n response\r\n .status(200)\r\n .set('Content-Type', meta.mimeType ?? SQLITE_SNAPSHOT_MIME_TYPE)\r\n .send(bytes);\r\n });\r\n\r\n app.get(PROJECT_DATABASE_API_PATH, async (_request, response) => {\r\n const meta = await snapshotFileStore.getActiveDatabaseMeta();\r\n\r\n if (!meta.exists) {\r\n response.status(404).json({ ok: false, error: 'PROJECT_DATABASE_NOT_FOUND' });\r\n return;\r\n }\r\n\r\n const bytes = await snapshotFileStore.readActiveDatabase();\r\n\r\n if (!bytes) {\r\n response.status(404).json({ ok: false, error: 'PROJECT_DATABASE_NOT_FOUND' });\r\n return;\r\n }\r\n\r\n response\r\n .status(200)\r\n .set('Content-Type', meta.mimeType ?? SQLITE_SNAPSHOT_MIME_TYPE)\r\n .send(bytes);\r\n });\r\n\r\n if (options.webDistPath) {\r\n attachWebUi(app, options.webDistPath);\r\n }\r\n\r\n const httpServer = createServer(app);\r\n attachWebSocket(\r\n httpServer,\r\n connectionManager,\r\n router,\r\n heartbeat,\r\n refreshCoordinator,\r\n writeCoordinator,\r\n { snapshotFileStore },\r\n );\r\n\r\n const refreshTimeoutInterval = setInterval(() => {\r\n refreshCoordinator.checkTimeouts();\r\n writeCoordinator.checkTimeouts();\r\n }, 5_000);\r\n\r\n if (snapshotFileStore.isEnabled()) {\r\n await snapshotFileStore.listDeviceExports();\r\n }\r\n\r\n await new Promise<void>((resolve, reject) => {\r\n httpServer.once('error', reject);\r\n httpServer.listen(port, host, () => resolve());\r\n });\r\n\r\n const displayHost = host === '0.0.0.0' ? 'localhost' : host;\r\n const httpUrl = buildDevToolsHttpUrl(displayHost, port);\r\n const wsUrl = buildDevToolsWsUrl(displayHost, port);\r\n const webUiEnabled = Boolean(options.webDistPath);\r\n\r\n logger.serverStarted(httpUrl, wsUrl, webUiEnabled);\r\n\r\n return {\r\n app,\r\n httpServer,\r\n connectionManager,\r\n deviceRegistry,\r\n router,\r\n heartbeat,\r\n snapshotStore,\r\n snapshotFileStore,\r\n pendingRefreshStore,\r\n writeSessions,\r\n refreshCoordinator,\r\n writeCoordinator,\r\n urls: {\r\n httpUrl,\r\n wsUrl,\r\n webUiEnabled,\r\n },\r\n close: () =>\r\n new Promise((resolve, reject) => {\r\n clearInterval(refreshTimeoutInterval);\r\n heartbeat.stop();\r\n httpServer.close((error) => {\r\n if (error) {\r\n reject(error);\r\n return;\r\n }\r\n\r\n resolve();\r\n });\r\n }),\r\n };\r\n}\r\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export { C as ConnectedClient, a as ConnectionManager, D as DevToolsServer, b as DevToolsServerOptions, c as DeviceRegistry, H as Heartbeat, M as MessageRouter, O as OutboundMessage, P as PendingRefresh, d as PendingRefreshStore, R as RefreshCoordinator, S as SnapshotStore, e as StoredSnapshot, f as createDevToolsServer } from '../createDevToolsServer-B7NQ_5H4.cjs';
|
|
2
|
+
import { Request, Response, NextFunction } from 'express';
|
|
3
|
+
import 'node:http';
|
|
4
|
+
import 'ws';
|
|
5
|
+
import '../types/protocol.cjs';
|
|
6
|
+
import '../write-C3toEIMs.cjs';
|
|
7
|
+
|
|
8
|
+
type CorsOptions = {
|
|
9
|
+
/** Fixed origin, or `*` when request has no Origin header. */
|
|
10
|
+
allowedOrigin?: string;
|
|
11
|
+
};
|
|
12
|
+
declare function resolveCorsOrigin(requestOrigin: string | undefined, configuredOrigin?: string): string;
|
|
13
|
+
declare function createCorsMiddleware(options?: CorsOptions): (request: Request, response: Response, next: NextFunction) => void;
|
|
14
|
+
|
|
15
|
+
export { type CorsOptions, createCorsMiddleware, resolveCorsOrigin };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export { C as ConnectedClient, a as ConnectionManager, D as DevToolsServer, b as DevToolsServerOptions, c as DeviceRegistry, H as Heartbeat, M as MessageRouter, O as OutboundMessage, P as PendingRefresh, d as PendingRefreshStore, R as RefreshCoordinator, S as SnapshotStore, e as StoredSnapshot, f as createDevToolsServer } from '../createDevToolsServer-DlNMoCJR.js';
|
|
2
|
+
import { Request, Response, NextFunction } from 'express';
|
|
3
|
+
import 'node:http';
|
|
4
|
+
import 'ws';
|
|
5
|
+
import '../types/protocol.js';
|
|
6
|
+
import '../write-C3toEIMs.js';
|
|
7
|
+
|
|
8
|
+
type CorsOptions = {
|
|
9
|
+
/** Fixed origin, or `*` when request has no Origin header. */
|
|
10
|
+
allowedOrigin?: string;
|
|
11
|
+
};
|
|
12
|
+
declare function resolveCorsOrigin(requestOrigin: string | undefined, configuredOrigin?: string): string;
|
|
13
|
+
declare function createCorsMiddleware(options?: CorsOptions): (request: Request, response: Response, next: NextFunction) => void;
|
|
14
|
+
|
|
15
|
+
export { type CorsOptions, createCorsMiddleware, resolveCorsOrigin };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { ConnectionManager, DeviceRegistry, Heartbeat, MessageRouter, PendingRefreshStore, RefreshCoordinator, SnapshotStore, createCorsMiddleware, createDevToolsServer, resolveCorsOrigin } from '../chunk-TNDOAHT5.js';
|
|
2
|
+
import '../chunk-AZECU6D7.js';
|
|
3
|
+
import '../chunk-CPVVIH5G.js';
|
|
4
|
+
import '../chunk-HIDZTOJ3.js';
|
|
5
|
+
import '../chunk-DGUM43GV.js';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
type AdapterCapabilities = {
|
|
2
|
+
exportSnapshot: boolean;
|
|
3
|
+
executeQuery: boolean;
|
|
4
|
+
listTables: boolean;
|
|
5
|
+
getSchema: boolean;
|
|
6
|
+
transactionalWrites: boolean;
|
|
7
|
+
observeChanges: boolean;
|
|
8
|
+
importSnapshot: boolean;
|
|
9
|
+
};
|
|
10
|
+
type InspectorCapabilities = {
|
|
11
|
+
explorer: boolean;
|
|
12
|
+
schemaView: boolean;
|
|
13
|
+
tableData: boolean;
|
|
14
|
+
sqlWorkspace: boolean;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/** Supported database engine identifiers. */
|
|
18
|
+
type DatabaseKind = 'sqlite' | 'realm' | 'duckdb' | (string & {});
|
|
19
|
+
declare const DATABASE_DEVTOOLS_KIND: unique symbol;
|
|
20
|
+
declare function readDatabaseKindMarker(value: unknown): DatabaseKind | undefined;
|
|
21
|
+
|
|
22
|
+
declare const SNAPSHOT_KIND_HEADER = "x-database-kind";
|
|
23
|
+
declare const SNAPSHOT_MIME_HEADER = "x-snapshot-mime-type";
|
|
24
|
+
declare const SNAPSHOT_NAME_HEADER = "x-database-name";
|
|
25
|
+
declare const SQLITE_SNAPSHOT_MIME_TYPE = "application/x-sqlite3";
|
|
26
|
+
type SnapshotExport = {
|
|
27
|
+
bytes: Uint8Array;
|
|
28
|
+
mimeType: string;
|
|
29
|
+
kind: DatabaseKind;
|
|
30
|
+
exportedAt?: number;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export { type AdapterCapabilities as A, type DatabaseKind as D, type InspectorCapabilities as I, type SnapshotExport as S, DATABASE_DEVTOOLS_KIND as a, SNAPSHOT_KIND_HEADER as b, SNAPSHOT_MIME_HEADER as c, SNAPSHOT_NAME_HEADER as d, SQLITE_SNAPSHOT_MIME_TYPE as e, readDatabaseKindMarker as r };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
type AdapterCapabilities = {
|
|
2
|
+
exportSnapshot: boolean;
|
|
3
|
+
executeQuery: boolean;
|
|
4
|
+
listTables: boolean;
|
|
5
|
+
getSchema: boolean;
|
|
6
|
+
transactionalWrites: boolean;
|
|
7
|
+
observeChanges: boolean;
|
|
8
|
+
importSnapshot: boolean;
|
|
9
|
+
};
|
|
10
|
+
type InspectorCapabilities = {
|
|
11
|
+
explorer: boolean;
|
|
12
|
+
schemaView: boolean;
|
|
13
|
+
tableData: boolean;
|
|
14
|
+
sqlWorkspace: boolean;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/** Supported database engine identifiers. */
|
|
18
|
+
type DatabaseKind = 'sqlite' | 'realm' | 'duckdb' | (string & {});
|
|
19
|
+
declare const DATABASE_DEVTOOLS_KIND: unique symbol;
|
|
20
|
+
declare function readDatabaseKindMarker(value: unknown): DatabaseKind | undefined;
|
|
21
|
+
|
|
22
|
+
declare const SNAPSHOT_KIND_HEADER = "x-database-kind";
|
|
23
|
+
declare const SNAPSHOT_MIME_HEADER = "x-snapshot-mime-type";
|
|
24
|
+
declare const SNAPSHOT_NAME_HEADER = "x-database-name";
|
|
25
|
+
declare const SQLITE_SNAPSHOT_MIME_TYPE = "application/x-sqlite3";
|
|
26
|
+
type SnapshotExport = {
|
|
27
|
+
bytes: Uint8Array;
|
|
28
|
+
mimeType: string;
|
|
29
|
+
kind: DatabaseKind;
|
|
30
|
+
exportedAt?: number;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export { type AdapterCapabilities as A, type DatabaseKind as D, type InspectorCapabilities as I, type SnapshotExport as S, DATABASE_DEVTOOLS_KIND as a, SNAPSHOT_KIND_HEADER as b, SNAPSHOT_MIME_HEADER as c, SNAPSHOT_NAME_HEADER as d, SQLITE_SNAPSHOT_MIME_TYPE as e, readDatabaseKindMarker as r };
|