database-devtools 0.1.3 → 0.1.5
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/README.md +13 -0
- package/dist/{DatabaseDevTools-CdpQJBqG.d.ts → DatabaseDevTools-CQXd9NST.d.ts} +5 -1
- package/dist/{DatabaseDevTools-sw1wX5nW.d.cts → DatabaseDevTools-CZmvO9uq.d.cts} +5 -1
- package/dist/{chunk-NHHA5CZP.js → chunk-SFLXGLHQ.js} +29 -14
- package/dist/chunk-SFLXGLHQ.js.map +1 -0
- package/dist/index.cjs +27 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/inspectors/sqlite/index.cjs +1 -1
- package/dist/inspectors/sqlite/index.cjs.map +1 -1
- package/dist/inspectors/sqlite/index.js +1 -1
- package/dist/inspectors/sqlite/index.js.map +1 -1
- package/dist/native.cjs +27 -12
- package/dist/native.cjs.map +1 -1
- package/dist/native.d.cts +1 -1
- package/dist/native.d.ts +1 -1
- package/dist/native.js +1 -1
- package/dist/web/assets/{index-DogMAkgu.js → index-Cyrcn84h.js} +27 -27
- package/dist/web/index.html +1 -1
- package/dist/web/sql-wasm.wasm +0 -0
- package/package.json +3 -2
- package/dist/chunk-NHHA5CZP.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -3,7 +3,7 @@ export { BroadcastMessage, BrowserConnectionInfo, ClientMessage, DEFAULT_DEVTOOL
|
|
|
3
3
|
export { A as AdapterCapabilities, D as DATABASE_DEVTOOLS_KIND, a as DatabaseKind, I as InspectorCapabilities, S as SNAPSHOT_KIND_HEADER, b as SNAPSHOT_MIME_HEADER, c as SNAPSHOT_NAME_HEADER, d as SQLITE_SNAPSHOT_MIME_TYPE, e as SnapshotExport, r as readDatabaseKindMarker } from './snapshot-Dknp_qP1.cjs';
|
|
4
4
|
import { D as DatabaseAdapter } from './adapter-DQyQ5ycj.cjs';
|
|
5
5
|
export { E as EditableDatabaseAdapter, W as WritableDatabaseAdapter, a as WriteResult, i as isEditableDatabaseAdapter, b as isWritableDatabaseAdapter } from './adapter-DQyQ5ycj.cjs';
|
|
6
|
-
export { D as DatabaseDevTools, a as DatabaseDevToolsProps, b as DatabaseDialect, F as FloatingButtonPosition } from './DatabaseDevTools-
|
|
6
|
+
export { D as DatabaseDevTools, a as DatabaseDevToolsProps, b as DatabaseDialect, F as FloatingButtonPosition } from './DatabaseDevTools-CZmvO9uq.cjs';
|
|
7
7
|
export { C as ColumnInfo, D as DatabaseInspector, I as InspectorDefinition, Q as QueryError, a as QueryResult, S as SchemaTable, T as TableInfo, b as TablePageRequest, c as TablePageResult } from './types-BQHZtFwx.cjs';
|
|
8
8
|
export { D as DeleteOperation, I as InsertOperation, U as UpdateOperation, W as WriteCellValue, a as WriteOperation } from './write-C3toEIMs.cjs';
|
|
9
9
|
export { A as AdapterDefinition, R as ResolveAdapterOptions } from './types-gT3gDw_T.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export { BroadcastMessage, BrowserConnectionInfo, ClientMessage, DEFAULT_DEVTOOL
|
|
|
3
3
|
export { A as AdapterCapabilities, D as DATABASE_DEVTOOLS_KIND, a as DatabaseKind, I as InspectorCapabilities, S as SNAPSHOT_KIND_HEADER, b as SNAPSHOT_MIME_HEADER, c as SNAPSHOT_NAME_HEADER, d as SQLITE_SNAPSHOT_MIME_TYPE, e as SnapshotExport, r as readDatabaseKindMarker } from './snapshot-Dknp_qP1.js';
|
|
4
4
|
import { D as DatabaseAdapter } from './adapter-cIF5P6qI.js';
|
|
5
5
|
export { E as EditableDatabaseAdapter, W as WritableDatabaseAdapter, a as WriteResult, i as isEditableDatabaseAdapter, b as isWritableDatabaseAdapter } from './adapter-cIF5P6qI.js';
|
|
6
|
-
export { D as DatabaseDevTools, a as DatabaseDevToolsProps, b as DatabaseDialect, F as FloatingButtonPosition } from './DatabaseDevTools-
|
|
6
|
+
export { D as DatabaseDevTools, a as DatabaseDevToolsProps, b as DatabaseDialect, F as FloatingButtonPosition } from './DatabaseDevTools-CQXd9NST.js';
|
|
7
7
|
export { C as ColumnInfo, D as DatabaseInspector, I as InspectorDefinition, Q as QueryError, a as QueryResult, S as SchemaTable, T as TableInfo, b as TablePageRequest, c as TablePageResult } from './types-6nco_RRp.js';
|
|
8
8
|
export { D as DeleteOperation, I as InsertOperation, U as UpdateOperation, W as WriteCellValue, a as WriteOperation } from './write-C3toEIMs.js';
|
|
9
9
|
export { A as AdapterDefinition, R as ResolveAdapterOptions } from './types-DkVlU6t-.js';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { DatabaseDevTools, handleBeginTransaction, handleCommitTransaction, handleExecuteWrite, handleRollbackTransaction, isEditableDatabaseAdapter, isWritableDatabaseAdapter } from './chunk-
|
|
1
|
+
export { DatabaseDevTools, handleBeginTransaction, handleCommitTransaction, handleExecuteWrite, handleRollbackTransaction, isEditableDatabaseAdapter, isWritableDatabaseAdapter } from './chunk-SFLXGLHQ.js';
|
|
2
2
|
import './chunk-O6AO7KHA.js';
|
|
3
3
|
export { fetchDeviceExportDatabase, fetchDeviceExportMeta, fetchDeviceExports, fetchProjectDatabase, fetchProjectDatabaseMeta, fetchProjectDatabases, resolveDeviceExportDatabaseMetaUrl, resolveDeviceExportDatabaseUrl, resolveDeviceExportsUrl, resolveProjectDatabaseMetaUrl, resolveProjectDatabaseUrl, resolveProjectDatabasesUrl } from './chunk-S4Z7A4TW.js';
|
|
4
4
|
export { createDevToolsClient, fetchSnapshot, handleDeviceSnapshotUpload } from './chunk-UNVCJMJK.js';
|
|
@@ -49,6 +49,7 @@ function configureSqliteWasm(locator) {
|
|
|
49
49
|
async function getSqlModule() {
|
|
50
50
|
if (!sqlModulePromise) {
|
|
51
51
|
sqlModulePromise = initSqlJs__default.default({
|
|
52
|
+
// Vite emits /assets/sql-wasm-<hash>.wasm; build-web.mjs also copies /sql-wasm.wasm.
|
|
52
53
|
locateFile: () => wasmLocator?.() ?? "/sql-wasm.wasm"
|
|
53
54
|
});
|
|
54
55
|
}
|
|
@@ -292,7 +293,6 @@ function registerSqliteInspector(options) {
|
|
|
292
293
|
}
|
|
293
294
|
getInspectorRegistry().register(sqliteInspectorDefinition);
|
|
294
295
|
}
|
|
295
|
-
registerSqliteInspector();
|
|
296
296
|
|
|
297
297
|
exports.SqliteInspector = SqliteInspector;
|
|
298
298
|
exports.SqliteSession = SqliteSession;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/inspector/registry.ts","../../../src/inspectors/sqlite/sqlModule.ts","../../../src/inspectors/sqlite/tableQuery.ts","../../../src/inspectors/sqlite/sqliteInspector.ts","../../../src/inspectors/sqlite/index.ts"],"names":["initSqlJs"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { DatabaseKind } from '../types/kind';\r\nimport type { DatabaseInspector, InspectorDefinition } from './types';\r\n\r\nexport class InspectorRegistry {\r\n private readonly definitions = new Map<string, InspectorDefinition>();\r\n\r\n register(definition: InspectorDefinition): void {\r\n this.definitions.set(definition.kind, definition);\r\n }\r\n\r\n get(kind: DatabaseKind): InspectorDefinition | undefined {\r\n return this.definitions.get(kind);\r\n }\r\n\r\n listSupported(): { kind: string; displayName: string }[] {\r\n return [...this.definitions.values()]\r\n .sort((left, right) => left.displayName.localeCompare(right.displayName))\r\n .map((definition) => ({\r\n kind: definition.kind,\r\n displayName: definition.displayName,\r\n }));\r\n }\r\n\r\n detectFromBytes(bytes: ArrayBuffer): InspectorDefinition | undefined {\r\n return [...this.definitions.values()].find((definition) => definition.canOpenBytes?.(bytes));\r\n }\r\n\r\n detectFromSnapshot(input: { kind: DatabaseKind; mimeType: string }): InspectorDefinition | undefined {\r\n const byKind = this.definitions.get(input.kind);\r\n\r\n if (byKind) {\r\n return byKind;\r\n }\r\n\r\n return [...this.definitions.values()].find((definition) =>\r\n definition.mimeTypes.includes(input.mimeType),\r\n );\r\n }\r\n}\r\n\r\nlet globalInspectorRegistry: InspectorRegistry | null = null;\r\n\r\nexport function getInspectorRegistry(): InspectorRegistry {\r\n if (!globalInspectorRegistry) {\r\n globalInspectorRegistry = new InspectorRegistry();\r\n }\r\n\r\n return globalInspectorRegistry;\r\n}\r\n\r\nexport function resetInspectorRegistry(): void {\r\n globalInspectorRegistry = null;\r\n}\r\n\r\nexport async function createInspectorForSnapshot(input: {\r\n kind: DatabaseKind;\r\n mimeType: string;\r\n bytes: ArrayBuffer;\r\n}): Promise<DatabaseInspector> {\r\n const registry = getInspectorRegistry();\r\n const definition =\r\n registry.get(input.kind) ??\r\n registry.detectFromBytes(input.bytes) ??\r\n registry.detectFromSnapshot(input);\r\n\r\n if (!definition) {\r\n throw new Error(`No inspector registered for database kind \"${input.kind}\"`);\r\n }\r\n\r\n const inspector = await definition.createInspector();\r\n await inspector.open(input.bytes);\r\n return inspector;\r\n}\r\n","import initSqlJs, { type SqlJsStatic } from 'sql.js';\r\n\r\nlet sqlModulePromise: Promise<SqlJsStatic> | null = null;\r\nlet wasmLocator: (() => string) | null = null;\r\n\r\nexport function configureSqliteWasm(locator: () => string): void {\r\n wasmLocator = locator;\r\n}\r\n\r\nexport async function getSqlModule(): Promise<SqlJsStatic> {\r\n if (!sqlModulePromise) {\r\n sqlModulePromise = initSqlJs({\r\n locateFile: () => wasmLocator?.() ?? '/sql-wasm.wasm',\r\n });\r\n }\r\n\r\n return sqlModulePromise;\r\n}\r\n","import type { ColumnInfo } from '../../types/inspection';\r\n\r\nexport function quoteIdentifier(name: string): string {\r\n return `\"${name.replace(/\"/g, '\"\"')}\"`;\r\n}\r\n\r\nexport function buildSearchClause(\r\n columns: ColumnInfo[],\r\n search: string | undefined,\r\n): { clause: string; params: string[] } {\r\n const term = search?.trim();\r\n\r\n if (!term || columns.length === 0) {\r\n return { clause: '', params: [] };\r\n }\r\n\r\n const pattern = `%${term}%`;\r\n const conditions = columns.map(\r\n (column) => `CAST(${quoteIdentifier(column.name)} AS TEXT) LIKE ?`,\r\n );\r\n\r\n return {\r\n clause: ` WHERE (${conditions.join(' OR ')})`,\r\n params: columns.map(() => pattern),\r\n };\r\n}\r\n\r\nexport function resolveSortColumn(\r\n columns: ColumnInfo[],\r\n sortColumn: string | null | undefined,\r\n): string | null {\r\n if (!sortColumn) {\r\n return null;\r\n }\r\n\r\n return columns.some((column) => column.name === sortColumn) ? sortColumn : null;\r\n}\r\n","import type {\r\n ColumnInfo,\r\n QueryResult,\r\n SchemaTable,\r\n TableInfo,\r\n TablePageRequest,\r\n TablePageResult,\r\n} from '../../types/inspection';\r\nimport type { DatabaseInspector } from '../../inspector/types';\r\nimport type { SnapshotExport } from '../../types/snapshot';\r\nimport { getSqlModule } from './sqlModule';\r\nimport { buildSearchClause, quoteIdentifier, resolveSortColumn } from './tableQuery';\r\n\r\nconst SQLITE_SNAPSHOT_MIME_TYPE = 'application/x-sqlite3';\r\n\r\nfunction normalizeCell(cell: unknown): string | number | null {\r\n if (cell === null || cell === undefined) {\r\n return null;\r\n }\r\n\r\n if (typeof cell === 'number' || typeof cell === 'string') {\r\n return cell;\r\n }\r\n\r\n if (cell instanceof Uint8Array) {\r\n return `[BLOB ${cell.byteLength} bytes]`;\r\n }\r\n\r\n return String(cell);\r\n}\r\n\r\nexport class SqliteSession {\r\n private readonly tableNames = new Set<string>();\r\n\r\n private constructor(private readonly db: import('sql.js').Database) {}\r\n\r\n static async open(bytes: ArrayBuffer): Promise<SqliteSession> {\r\n const SQL = await getSqlModule();\r\n const db = new SQL.Database(new Uint8Array(bytes));\r\n const session = new SqliteSession(db);\r\n session.listTables().forEach((table) => session.tableNames.add(table.name));\r\n return session;\r\n }\r\n\r\n close(): void {\r\n this.db.close();\r\n }\r\n\r\n listTables(): TableInfo[] {\r\n const statement = this.db.prepare(\r\n `SELECT name FROM sqlite_master\r\n WHERE type = 'table' AND name NOT LIKE 'sqlite_%'\r\n ORDER BY name`,\r\n );\r\n\r\n const tables: TableInfo[] = [];\r\n\r\n while (statement.step()) {\r\n const name = String(statement.get()[0]);\r\n const countStatement = this.db.prepare(`SELECT COUNT(*) AS c FROM ${quoteIdentifier(name)}`);\r\n\r\n countStatement.step();\r\n const rowCount = Number(countStatement.get()[0] ?? 0);\r\n countStatement.free();\r\n\r\n tables.push({ name, rowCount });\r\n }\r\n\r\n statement.free();\r\n return tables;\r\n }\r\n\r\n getSchema(): SchemaTable[] {\r\n const tables = this.listTables();\r\n\r\n return tables.map((table) => ({\r\n name: table.name,\r\n columns: this.getTableColumns(table.name),\r\n }));\r\n }\r\n\r\n getTableColumns(tableName: string): ColumnInfo[] {\r\n this.assertKnownTable(tableName);\r\n return this.readTableColumns(tableName);\r\n }\r\n\r\n fetchTablePage(request: TablePageRequest): TablePageResult {\r\n this.assertKnownTable(request.table);\r\n\r\n const columns = this.readTableColumns(request.table);\r\n const columnNames = columns.map((column) => column.name);\r\n const tableQuoted = quoteIdentifier(request.table);\r\n const { clause, params } = buildSearchClause(columns, request.search);\r\n const sortColumn = resolveSortColumn(columns, request.sortColumn);\r\n const sortDir = request.sortDir === 'desc' ? 'DESC' : 'ASC';\r\n const page = Math.max(1, request.page);\r\n const pageSize = Math.max(1, request.pageSize);\r\n const offset = (page - 1) * pageSize;\r\n\r\n const countStatement = this.db.prepare(`SELECT COUNT(*) AS c FROM ${tableQuoted}${clause}`);\r\n countStatement.bind(params);\r\n countStatement.step();\r\n const totalCount = Number(countStatement.get()[0] ?? 0);\r\n countStatement.free();\r\n\r\n const orderClause = sortColumn\r\n ? ` ORDER BY ${quoteIdentifier(sortColumn)} ${sortDir}`\r\n : '';\r\n const dataStatement = this.db.prepare(\r\n `SELECT * FROM ${tableQuoted}${clause}${orderClause} LIMIT ? OFFSET ?`,\r\n );\r\n dataStatement.bind([...params, pageSize, offset]);\r\n\r\n const rows: (string | number | null)[][] = [];\r\n\r\n while (dataStatement.step()) {\r\n rows.push(columnNames.map((_, index) => normalizeCell(dataStatement.get()[index])));\r\n }\r\n\r\n dataStatement.free();\r\n\r\n return {\r\n columns: columnNames,\r\n rows,\r\n totalCount,\r\n page,\r\n pageSize,\r\n };\r\n }\r\n\r\n executeQuery(sql: string): QueryResult {\r\n const startedAt = performance.now();\r\n const resultSets = this.db.exec(sql);\r\n const durationMs = performance.now() - startedAt;\r\n\r\n if (resultSets.length === 0) {\r\n return {\r\n columns: [],\r\n rows: [],\r\n rowCount: 0,\r\n durationMs,\r\n };\r\n }\r\n\r\n const primary = resultSets[0];\r\n\r\n return {\r\n columns: primary.columns,\r\n rows: primary.values.map((row) => row.map((cell) => normalizeCell(cell))),\r\n rowCount: primary.values.length,\r\n durationMs,\r\n };\r\n }\r\n\r\n private assertKnownTable(tableName: string): void {\r\n if (!this.tableNames.has(tableName)) {\r\n throw new Error(`Unknown table: ${tableName}`);\r\n }\r\n }\r\n\r\n private readTableColumns(tableName: string): ColumnInfo[] {\r\n const statement = this.db.prepare(`PRAGMA table_info(${quoteIdentifier(tableName)})`);\r\n const columns: ColumnInfo[] = [];\r\n\r\n while (statement.step()) {\r\n const row = statement.getAsObject() as {\r\n name: string;\r\n type: string;\r\n notnull: number;\r\n pk: number;\r\n dflt_value: string | null;\r\n };\r\n\r\n columns.push({\r\n name: row.name,\r\n type: row.type || 'ANY',\r\n notNull: row.notnull === 1,\r\n pk: row.pk > 0,\r\n defaultValue: row.dflt_value,\r\n });\r\n }\r\n\r\n statement.free();\r\n return columns;\r\n }\r\n}\r\n\r\nexport function isSqliteDatabase(bytes: ArrayBuffer): boolean {\r\n const header = new TextDecoder().decode(new Uint8Array(bytes, 0, 16));\r\n return header.startsWith('SQLite format 3');\r\n}\r\n\r\nexport function filterTables(tables: TableInfo[], search: string): TableInfo[] {\r\n const term = search.trim().toLowerCase();\r\n\r\n if (!term) {\r\n return tables;\r\n }\r\n\r\n return tables.filter((table) => table.name.toLowerCase().includes(term));\r\n}\r\n\r\nexport function sortTables(\r\n tables: TableInfo[],\r\n sortBy: 'name' | 'rows',\r\n direction: 'asc' | 'desc',\r\n): TableInfo[] {\r\n const sorted = [...tables].sort((left, right) => {\r\n if (sortBy === 'rows') {\r\n return left.rowCount - right.rowCount;\r\n }\r\n\r\n return left.name.localeCompare(right.name);\r\n });\r\n\r\n return direction === 'desc' ? sorted.reverse() : sorted;\r\n}\r\n\r\nexport class SqliteInspector implements DatabaseInspector {\r\n readonly kind = 'sqlite' as const;\r\n readonly capabilities = {\r\n explorer: true,\r\n schemaView: true,\r\n tableData: true,\r\n sqlWorkspace: true,\r\n };\r\n\r\n private session: SqliteSession | null = null;\r\n\r\n async open(snapshot: SnapshotExport | ArrayBuffer): Promise<void> {\r\n this.close();\r\n\r\n const bytes: ArrayBuffer =\r\n snapshot instanceof ArrayBuffer\r\n ? snapshot\r\n : new Uint8Array(snapshot.bytes).buffer;\r\n\r\n if (!isSqliteDatabase(bytes)) {\r\n throw new Error('Snapshot is not a valid SQLite database file');\r\n }\r\n\r\n this.session = await SqliteSession.open(bytes);\r\n }\r\n\r\n close(): void {\r\n this.session?.close();\r\n this.session = null;\r\n }\r\n\r\n listTables(): TableInfo[] {\r\n return this.requireSession().listTables();\r\n }\r\n\r\n getSchema(): SchemaTable[] {\r\n return this.requireSession().getSchema();\r\n }\r\n\r\n fetchTablePage(request: TablePageRequest): TablePageResult {\r\n return this.requireSession().fetchTablePage(request);\r\n }\r\n\r\n executeQuery(sql: string): QueryResult {\r\n return this.requireSession().executeQuery(sql);\r\n }\r\n\r\n private requireSession(): SqliteSession {\r\n if (!this.session) {\r\n throw new Error('No database loaded');\r\n }\r\n\r\n return this.session;\r\n }\r\n}\r\n\r\nexport const sqliteInspectorDefinition = {\r\n kind: 'sqlite' as const,\r\n displayName: 'SQLite',\r\n mimeTypes: [SQLITE_SNAPSHOT_MIME_TYPE, 'application/octet-stream'],\r\n canOpenBytes: isSqliteDatabase,\r\n createInspector: () => new SqliteInspector(),\r\n};\r\n","import { getInspectorRegistry } from '../../inspector/registry';\r\nimport { configureSqliteWasm } from './sqlModule';\r\nimport {\r\n filterTables,\r\n isSqliteDatabase,\r\n sortTables,\r\n sqliteInspectorDefinition,\r\n SqliteInspector,\r\n SqliteSession,\r\n} from './sqliteInspector';\r\n\r\nexport function registerSqliteInspector(options?: { wasmUrl?: string; locateWasm?: () => string }): void {\r\n if (options?.locateWasm) {\r\n configureSqliteWasm(options.locateWasm);\r\n } else if (options?.wasmUrl) {\r\n configureSqliteWasm(() => options.wasmUrl!);\r\n }\r\n\r\n getInspectorRegistry().register(sqliteInspectorDefinition);\r\n}\r\n\r\nexport {\r\n SqliteInspector,\r\n SqliteSession,\r\n filterTables,\r\n isSqliteDatabase,\r\n sortTables,\r\n sqliteInspectorDefinition,\r\n};\r\nexport { configureSqliteWasm } from './sqlModule';\r\n\r\nregisterSqliteInspector();\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/inspector/registry.ts","../../../src/inspectors/sqlite/sqlModule.ts","../../../src/inspectors/sqlite/tableQuery.ts","../../../src/inspectors/sqlite/sqliteInspector.ts","../../../src/inspectors/sqlite/index.ts"],"names":["initSqlJs"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { DatabaseKind } from '../types/kind';\r\nimport type { DatabaseInspector, InspectorDefinition } from './types';\r\n\r\nexport class InspectorRegistry {\r\n private readonly definitions = new Map<string, InspectorDefinition>();\r\n\r\n register(definition: InspectorDefinition): void {\r\n this.definitions.set(definition.kind, definition);\r\n }\r\n\r\n get(kind: DatabaseKind): InspectorDefinition | undefined {\r\n return this.definitions.get(kind);\r\n }\r\n\r\n listSupported(): { kind: string; displayName: string }[] {\r\n return [...this.definitions.values()]\r\n .sort((left, right) => left.displayName.localeCompare(right.displayName))\r\n .map((definition) => ({\r\n kind: definition.kind,\r\n displayName: definition.displayName,\r\n }));\r\n }\r\n\r\n detectFromBytes(bytes: ArrayBuffer): InspectorDefinition | undefined {\r\n return [...this.definitions.values()].find((definition) => definition.canOpenBytes?.(bytes));\r\n }\r\n\r\n detectFromSnapshot(input: { kind: DatabaseKind; mimeType: string }): InspectorDefinition | undefined {\r\n const byKind = this.definitions.get(input.kind);\r\n\r\n if (byKind) {\r\n return byKind;\r\n }\r\n\r\n return [...this.definitions.values()].find((definition) =>\r\n definition.mimeTypes.includes(input.mimeType),\r\n );\r\n }\r\n}\r\n\r\nlet globalInspectorRegistry: InspectorRegistry | null = null;\r\n\r\nexport function getInspectorRegistry(): InspectorRegistry {\r\n if (!globalInspectorRegistry) {\r\n globalInspectorRegistry = new InspectorRegistry();\r\n }\r\n\r\n return globalInspectorRegistry;\r\n}\r\n\r\nexport function resetInspectorRegistry(): void {\r\n globalInspectorRegistry = null;\r\n}\r\n\r\nexport async function createInspectorForSnapshot(input: {\r\n kind: DatabaseKind;\r\n mimeType: string;\r\n bytes: ArrayBuffer;\r\n}): Promise<DatabaseInspector> {\r\n const registry = getInspectorRegistry();\r\n const definition =\r\n registry.get(input.kind) ??\r\n registry.detectFromBytes(input.bytes) ??\r\n registry.detectFromSnapshot(input);\r\n\r\n if (!definition) {\r\n throw new Error(`No inspector registered for database kind \"${input.kind}\"`);\r\n }\r\n\r\n const inspector = await definition.createInspector();\r\n await inspector.open(input.bytes);\r\n return inspector;\r\n}\r\n","import initSqlJs, { type SqlJsStatic } from 'sql.js';\r\n\r\nlet sqlModulePromise: Promise<SqlJsStatic> | null = null;\r\nlet wasmLocator: (() => string) | null = null;\r\n\r\nexport function configureSqliteWasm(locator: () => string): void {\r\n wasmLocator = locator;\r\n}\r\n\r\nexport async function getSqlModule(): Promise<SqlJsStatic> {\r\n if (!sqlModulePromise) {\r\n sqlModulePromise = initSqlJs({\r\n // Vite emits /assets/sql-wasm-<hash>.wasm; build-web.mjs also copies /sql-wasm.wasm.\r\n locateFile: () => wasmLocator?.() ?? '/sql-wasm.wasm',\r\n });\r\n }\r\n\r\n return sqlModulePromise;\r\n}\r\n","import type { ColumnInfo } from '../../types/inspection';\r\n\r\nexport function quoteIdentifier(name: string): string {\r\n return `\"${name.replace(/\"/g, '\"\"')}\"`;\r\n}\r\n\r\nexport function buildSearchClause(\r\n columns: ColumnInfo[],\r\n search: string | undefined,\r\n): { clause: string; params: string[] } {\r\n const term = search?.trim();\r\n\r\n if (!term || columns.length === 0) {\r\n return { clause: '', params: [] };\r\n }\r\n\r\n const pattern = `%${term}%`;\r\n const conditions = columns.map(\r\n (column) => `CAST(${quoteIdentifier(column.name)} AS TEXT) LIKE ?`,\r\n );\r\n\r\n return {\r\n clause: ` WHERE (${conditions.join(' OR ')})`,\r\n params: columns.map(() => pattern),\r\n };\r\n}\r\n\r\nexport function resolveSortColumn(\r\n columns: ColumnInfo[],\r\n sortColumn: string | null | undefined,\r\n): string | null {\r\n if (!sortColumn) {\r\n return null;\r\n }\r\n\r\n return columns.some((column) => column.name === sortColumn) ? sortColumn : null;\r\n}\r\n","import type {\r\n ColumnInfo,\r\n QueryResult,\r\n SchemaTable,\r\n TableInfo,\r\n TablePageRequest,\r\n TablePageResult,\r\n} from '../../types/inspection';\r\nimport type { DatabaseInspector } from '../../inspector/types';\r\nimport type { SnapshotExport } from '../../types/snapshot';\r\nimport { getSqlModule } from './sqlModule';\r\nimport { buildSearchClause, quoteIdentifier, resolveSortColumn } from './tableQuery';\r\n\r\nconst SQLITE_SNAPSHOT_MIME_TYPE = 'application/x-sqlite3';\r\n\r\nfunction normalizeCell(cell: unknown): string | number | null {\r\n if (cell === null || cell === undefined) {\r\n return null;\r\n }\r\n\r\n if (typeof cell === 'number' || typeof cell === 'string') {\r\n return cell;\r\n }\r\n\r\n if (cell instanceof Uint8Array) {\r\n return `[BLOB ${cell.byteLength} bytes]`;\r\n }\r\n\r\n return String(cell);\r\n}\r\n\r\nexport class SqliteSession {\r\n private readonly tableNames = new Set<string>();\r\n\r\n private constructor(private readonly db: import('sql.js').Database) {}\r\n\r\n static async open(bytes: ArrayBuffer): Promise<SqliteSession> {\r\n const SQL = await getSqlModule();\r\n const db = new SQL.Database(new Uint8Array(bytes));\r\n const session = new SqliteSession(db);\r\n session.listTables().forEach((table) => session.tableNames.add(table.name));\r\n return session;\r\n }\r\n\r\n close(): void {\r\n this.db.close();\r\n }\r\n\r\n listTables(): TableInfo[] {\r\n const statement = this.db.prepare(\r\n `SELECT name FROM sqlite_master\r\n WHERE type = 'table' AND name NOT LIKE 'sqlite_%'\r\n ORDER BY name`,\r\n );\r\n\r\n const tables: TableInfo[] = [];\r\n\r\n while (statement.step()) {\r\n const name = String(statement.get()[0]);\r\n const countStatement = this.db.prepare(`SELECT COUNT(*) AS c FROM ${quoteIdentifier(name)}`);\r\n\r\n countStatement.step();\r\n const rowCount = Number(countStatement.get()[0] ?? 0);\r\n countStatement.free();\r\n\r\n tables.push({ name, rowCount });\r\n }\r\n\r\n statement.free();\r\n return tables;\r\n }\r\n\r\n getSchema(): SchemaTable[] {\r\n const tables = this.listTables();\r\n\r\n return tables.map((table) => ({\r\n name: table.name,\r\n columns: this.getTableColumns(table.name),\r\n }));\r\n }\r\n\r\n getTableColumns(tableName: string): ColumnInfo[] {\r\n this.assertKnownTable(tableName);\r\n return this.readTableColumns(tableName);\r\n }\r\n\r\n fetchTablePage(request: TablePageRequest): TablePageResult {\r\n this.assertKnownTable(request.table);\r\n\r\n const columns = this.readTableColumns(request.table);\r\n const columnNames = columns.map((column) => column.name);\r\n const tableQuoted = quoteIdentifier(request.table);\r\n const { clause, params } = buildSearchClause(columns, request.search);\r\n const sortColumn = resolveSortColumn(columns, request.sortColumn);\r\n const sortDir = request.sortDir === 'desc' ? 'DESC' : 'ASC';\r\n const page = Math.max(1, request.page);\r\n const pageSize = Math.max(1, request.pageSize);\r\n const offset = (page - 1) * pageSize;\r\n\r\n const countStatement = this.db.prepare(`SELECT COUNT(*) AS c FROM ${tableQuoted}${clause}`);\r\n countStatement.bind(params);\r\n countStatement.step();\r\n const totalCount = Number(countStatement.get()[0] ?? 0);\r\n countStatement.free();\r\n\r\n const orderClause = sortColumn\r\n ? ` ORDER BY ${quoteIdentifier(sortColumn)} ${sortDir}`\r\n : '';\r\n const dataStatement = this.db.prepare(\r\n `SELECT * FROM ${tableQuoted}${clause}${orderClause} LIMIT ? OFFSET ?`,\r\n );\r\n dataStatement.bind([...params, pageSize, offset]);\r\n\r\n const rows: (string | number | null)[][] = [];\r\n\r\n while (dataStatement.step()) {\r\n rows.push(columnNames.map((_, index) => normalizeCell(dataStatement.get()[index])));\r\n }\r\n\r\n dataStatement.free();\r\n\r\n return {\r\n columns: columnNames,\r\n rows,\r\n totalCount,\r\n page,\r\n pageSize,\r\n };\r\n }\r\n\r\n executeQuery(sql: string): QueryResult {\r\n const startedAt = performance.now();\r\n const resultSets = this.db.exec(sql);\r\n const durationMs = performance.now() - startedAt;\r\n\r\n if (resultSets.length === 0) {\r\n return {\r\n columns: [],\r\n rows: [],\r\n rowCount: 0,\r\n durationMs,\r\n };\r\n }\r\n\r\n const primary = resultSets[0];\r\n\r\n return {\r\n columns: primary.columns,\r\n rows: primary.values.map((row) => row.map((cell) => normalizeCell(cell))),\r\n rowCount: primary.values.length,\r\n durationMs,\r\n };\r\n }\r\n\r\n private assertKnownTable(tableName: string): void {\r\n if (!this.tableNames.has(tableName)) {\r\n throw new Error(`Unknown table: ${tableName}`);\r\n }\r\n }\r\n\r\n private readTableColumns(tableName: string): ColumnInfo[] {\r\n const statement = this.db.prepare(`PRAGMA table_info(${quoteIdentifier(tableName)})`);\r\n const columns: ColumnInfo[] = [];\r\n\r\n while (statement.step()) {\r\n const row = statement.getAsObject() as {\r\n name: string;\r\n type: string;\r\n notnull: number;\r\n pk: number;\r\n dflt_value: string | null;\r\n };\r\n\r\n columns.push({\r\n name: row.name,\r\n type: row.type || 'ANY',\r\n notNull: row.notnull === 1,\r\n pk: row.pk > 0,\r\n defaultValue: row.dflt_value,\r\n });\r\n }\r\n\r\n statement.free();\r\n return columns;\r\n }\r\n}\r\n\r\nexport function isSqliteDatabase(bytes: ArrayBuffer): boolean {\r\n const header = new TextDecoder().decode(new Uint8Array(bytes, 0, 16));\r\n return header.startsWith('SQLite format 3');\r\n}\r\n\r\nexport function filterTables(tables: TableInfo[], search: string): TableInfo[] {\r\n const term = search.trim().toLowerCase();\r\n\r\n if (!term) {\r\n return tables;\r\n }\r\n\r\n return tables.filter((table) => table.name.toLowerCase().includes(term));\r\n}\r\n\r\nexport function sortTables(\r\n tables: TableInfo[],\r\n sortBy: 'name' | 'rows',\r\n direction: 'asc' | 'desc',\r\n): TableInfo[] {\r\n const sorted = [...tables].sort((left, right) => {\r\n if (sortBy === 'rows') {\r\n return left.rowCount - right.rowCount;\r\n }\r\n\r\n return left.name.localeCompare(right.name);\r\n });\r\n\r\n return direction === 'desc' ? sorted.reverse() : sorted;\r\n}\r\n\r\nexport class SqliteInspector implements DatabaseInspector {\r\n readonly kind = 'sqlite' as const;\r\n readonly capabilities = {\r\n explorer: true,\r\n schemaView: true,\r\n tableData: true,\r\n sqlWorkspace: true,\r\n };\r\n\r\n private session: SqliteSession | null = null;\r\n\r\n async open(snapshot: SnapshotExport | ArrayBuffer): Promise<void> {\r\n this.close();\r\n\r\n const bytes: ArrayBuffer =\r\n snapshot instanceof ArrayBuffer\r\n ? snapshot\r\n : new Uint8Array(snapshot.bytes).buffer;\r\n\r\n if (!isSqliteDatabase(bytes)) {\r\n throw new Error('Snapshot is not a valid SQLite database file');\r\n }\r\n\r\n this.session = await SqliteSession.open(bytes);\r\n }\r\n\r\n close(): void {\r\n this.session?.close();\r\n this.session = null;\r\n }\r\n\r\n listTables(): TableInfo[] {\r\n return this.requireSession().listTables();\r\n }\r\n\r\n getSchema(): SchemaTable[] {\r\n return this.requireSession().getSchema();\r\n }\r\n\r\n fetchTablePage(request: TablePageRequest): TablePageResult {\r\n return this.requireSession().fetchTablePage(request);\r\n }\r\n\r\n executeQuery(sql: string): QueryResult {\r\n return this.requireSession().executeQuery(sql);\r\n }\r\n\r\n private requireSession(): SqliteSession {\r\n if (!this.session) {\r\n throw new Error('No database loaded');\r\n }\r\n\r\n return this.session;\r\n }\r\n}\r\n\r\nexport const sqliteInspectorDefinition = {\r\n kind: 'sqlite' as const,\r\n displayName: 'SQLite',\r\n mimeTypes: [SQLITE_SNAPSHOT_MIME_TYPE, 'application/octet-stream'],\r\n canOpenBytes: isSqliteDatabase,\r\n createInspector: () => new SqliteInspector(),\r\n};\r\n","import { getInspectorRegistry } from '../../inspector/registry';\r\nimport { configureSqliteWasm } from './sqlModule';\r\nimport {\r\n filterTables,\r\n isSqliteDatabase,\r\n sortTables,\r\n sqliteInspectorDefinition,\r\n SqliteInspector,\r\n SqliteSession,\r\n} from './sqliteInspector';\r\n\r\nexport function registerSqliteInspector(options?: { wasmUrl?: string; locateWasm?: () => string }): void {\r\n if (options?.locateWasm) {\r\n configureSqliteWasm(options.locateWasm);\r\n } else if (options?.wasmUrl) {\r\n configureSqliteWasm(() => options.wasmUrl!);\r\n }\r\n\r\n getInspectorRegistry().register(sqliteInspectorDefinition);\r\n}\r\n\r\nexport {\r\n SqliteInspector,\r\n SqliteSession,\r\n filterTables,\r\n isSqliteDatabase,\r\n sortTables,\r\n sqliteInspectorDefinition,\r\n};\r\nexport { configureSqliteWasm } from './sqlModule';\r\n"]}
|
|
@@ -9,6 +9,7 @@ function configureSqliteWasm(locator) {
|
|
|
9
9
|
async function getSqlModule() {
|
|
10
10
|
if (!sqlModulePromise) {
|
|
11
11
|
sqlModulePromise = initSqlJs({
|
|
12
|
+
// Vite emits /assets/sql-wasm-<hash>.wasm; build-web.mjs also copies /sql-wasm.wasm.
|
|
12
13
|
locateFile: () => wasmLocator?.() ?? "/sql-wasm.wasm"
|
|
13
14
|
});
|
|
14
15
|
}
|
|
@@ -252,7 +253,6 @@ function registerSqliteInspector(options) {
|
|
|
252
253
|
}
|
|
253
254
|
getInspectorRegistry().register(sqliteInspectorDefinition);
|
|
254
255
|
}
|
|
255
|
-
registerSqliteInspector();
|
|
256
256
|
|
|
257
257
|
export { SqliteInspector, SqliteSession, configureSqliteWasm, filterTables, isSqliteDatabase, registerSqliteInspector, sortTables, sqliteInspectorDefinition };
|
|
258
258
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/inspectors/sqlite/sqlModule.ts","../../../src/inspectors/sqlite/tableQuery.ts","../../../src/inspectors/sqlite/sqliteInspector.ts","../../../src/inspectors/sqlite/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import initSqlJs, { type SqlJsStatic } from 'sql.js';\r\n\r\nlet sqlModulePromise: Promise<SqlJsStatic> | null = null;\r\nlet wasmLocator: (() => string) | null = null;\r\n\r\nexport function configureSqliteWasm(locator: () => string): void {\r\n wasmLocator = locator;\r\n}\r\n\r\nexport async function getSqlModule(): Promise<SqlJsStatic> {\r\n if (!sqlModulePromise) {\r\n sqlModulePromise = initSqlJs({\r\n locateFile: () => wasmLocator?.() ?? '/sql-wasm.wasm',\r\n });\r\n }\r\n\r\n return sqlModulePromise;\r\n}\r\n","import type { ColumnInfo } from '../../types/inspection';\r\n\r\nexport function quoteIdentifier(name: string): string {\r\n return `\"${name.replace(/\"/g, '\"\"')}\"`;\r\n}\r\n\r\nexport function buildSearchClause(\r\n columns: ColumnInfo[],\r\n search: string | undefined,\r\n): { clause: string; params: string[] } {\r\n const term = search?.trim();\r\n\r\n if (!term || columns.length === 0) {\r\n return { clause: '', params: [] };\r\n }\r\n\r\n const pattern = `%${term}%`;\r\n const conditions = columns.map(\r\n (column) => `CAST(${quoteIdentifier(column.name)} AS TEXT) LIKE ?`,\r\n );\r\n\r\n return {\r\n clause: ` WHERE (${conditions.join(' OR ')})`,\r\n params: columns.map(() => pattern),\r\n };\r\n}\r\n\r\nexport function resolveSortColumn(\r\n columns: ColumnInfo[],\r\n sortColumn: string | null | undefined,\r\n): string | null {\r\n if (!sortColumn) {\r\n return null;\r\n }\r\n\r\n return columns.some((column) => column.name === sortColumn) ? sortColumn : null;\r\n}\r\n","import type {\r\n ColumnInfo,\r\n QueryResult,\r\n SchemaTable,\r\n TableInfo,\r\n TablePageRequest,\r\n TablePageResult,\r\n} from '../../types/inspection';\r\nimport type { DatabaseInspector } from '../../inspector/types';\r\nimport type { SnapshotExport } from '../../types/snapshot';\r\nimport { getSqlModule } from './sqlModule';\r\nimport { buildSearchClause, quoteIdentifier, resolveSortColumn } from './tableQuery';\r\n\r\nconst SQLITE_SNAPSHOT_MIME_TYPE = 'application/x-sqlite3';\r\n\r\nfunction normalizeCell(cell: unknown): string | number | null {\r\n if (cell === null || cell === undefined) {\r\n return null;\r\n }\r\n\r\n if (typeof cell === 'number' || typeof cell === 'string') {\r\n return cell;\r\n }\r\n\r\n if (cell instanceof Uint8Array) {\r\n return `[BLOB ${cell.byteLength} bytes]`;\r\n }\r\n\r\n return String(cell);\r\n}\r\n\r\nexport class SqliteSession {\r\n private readonly tableNames = new Set<string>();\r\n\r\n private constructor(private readonly db: import('sql.js').Database) {}\r\n\r\n static async open(bytes: ArrayBuffer): Promise<SqliteSession> {\r\n const SQL = await getSqlModule();\r\n const db = new SQL.Database(new Uint8Array(bytes));\r\n const session = new SqliteSession(db);\r\n session.listTables().forEach((table) => session.tableNames.add(table.name));\r\n return session;\r\n }\r\n\r\n close(): void {\r\n this.db.close();\r\n }\r\n\r\n listTables(): TableInfo[] {\r\n const statement = this.db.prepare(\r\n `SELECT name FROM sqlite_master\r\n WHERE type = 'table' AND name NOT LIKE 'sqlite_%'\r\n ORDER BY name`,\r\n );\r\n\r\n const tables: TableInfo[] = [];\r\n\r\n while (statement.step()) {\r\n const name = String(statement.get()[0]);\r\n const countStatement = this.db.prepare(`SELECT COUNT(*) AS c FROM ${quoteIdentifier(name)}`);\r\n\r\n countStatement.step();\r\n const rowCount = Number(countStatement.get()[0] ?? 0);\r\n countStatement.free();\r\n\r\n tables.push({ name, rowCount });\r\n }\r\n\r\n statement.free();\r\n return tables;\r\n }\r\n\r\n getSchema(): SchemaTable[] {\r\n const tables = this.listTables();\r\n\r\n return tables.map((table) => ({\r\n name: table.name,\r\n columns: this.getTableColumns(table.name),\r\n }));\r\n }\r\n\r\n getTableColumns(tableName: string): ColumnInfo[] {\r\n this.assertKnownTable(tableName);\r\n return this.readTableColumns(tableName);\r\n }\r\n\r\n fetchTablePage(request: TablePageRequest): TablePageResult {\r\n this.assertKnownTable(request.table);\r\n\r\n const columns = this.readTableColumns(request.table);\r\n const columnNames = columns.map((column) => column.name);\r\n const tableQuoted = quoteIdentifier(request.table);\r\n const { clause, params } = buildSearchClause(columns, request.search);\r\n const sortColumn = resolveSortColumn(columns, request.sortColumn);\r\n const sortDir = request.sortDir === 'desc' ? 'DESC' : 'ASC';\r\n const page = Math.max(1, request.page);\r\n const pageSize = Math.max(1, request.pageSize);\r\n const offset = (page - 1) * pageSize;\r\n\r\n const countStatement = this.db.prepare(`SELECT COUNT(*) AS c FROM ${tableQuoted}${clause}`);\r\n countStatement.bind(params);\r\n countStatement.step();\r\n const totalCount = Number(countStatement.get()[0] ?? 0);\r\n countStatement.free();\r\n\r\n const orderClause = sortColumn\r\n ? ` ORDER BY ${quoteIdentifier(sortColumn)} ${sortDir}`\r\n : '';\r\n const dataStatement = this.db.prepare(\r\n `SELECT * FROM ${tableQuoted}${clause}${orderClause} LIMIT ? OFFSET ?`,\r\n );\r\n dataStatement.bind([...params, pageSize, offset]);\r\n\r\n const rows: (string | number | null)[][] = [];\r\n\r\n while (dataStatement.step()) {\r\n rows.push(columnNames.map((_, index) => normalizeCell(dataStatement.get()[index])));\r\n }\r\n\r\n dataStatement.free();\r\n\r\n return {\r\n columns: columnNames,\r\n rows,\r\n totalCount,\r\n page,\r\n pageSize,\r\n };\r\n }\r\n\r\n executeQuery(sql: string): QueryResult {\r\n const startedAt = performance.now();\r\n const resultSets = this.db.exec(sql);\r\n const durationMs = performance.now() - startedAt;\r\n\r\n if (resultSets.length === 0) {\r\n return {\r\n columns: [],\r\n rows: [],\r\n rowCount: 0,\r\n durationMs,\r\n };\r\n }\r\n\r\n const primary = resultSets[0];\r\n\r\n return {\r\n columns: primary.columns,\r\n rows: primary.values.map((row) => row.map((cell) => normalizeCell(cell))),\r\n rowCount: primary.values.length,\r\n durationMs,\r\n };\r\n }\r\n\r\n private assertKnownTable(tableName: string): void {\r\n if (!this.tableNames.has(tableName)) {\r\n throw new Error(`Unknown table: ${tableName}`);\r\n }\r\n }\r\n\r\n private readTableColumns(tableName: string): ColumnInfo[] {\r\n const statement = this.db.prepare(`PRAGMA table_info(${quoteIdentifier(tableName)})`);\r\n const columns: ColumnInfo[] = [];\r\n\r\n while (statement.step()) {\r\n const row = statement.getAsObject() as {\r\n name: string;\r\n type: string;\r\n notnull: number;\r\n pk: number;\r\n dflt_value: string | null;\r\n };\r\n\r\n columns.push({\r\n name: row.name,\r\n type: row.type || 'ANY',\r\n notNull: row.notnull === 1,\r\n pk: row.pk > 0,\r\n defaultValue: row.dflt_value,\r\n });\r\n }\r\n\r\n statement.free();\r\n return columns;\r\n }\r\n}\r\n\r\nexport function isSqliteDatabase(bytes: ArrayBuffer): boolean {\r\n const header = new TextDecoder().decode(new Uint8Array(bytes, 0, 16));\r\n return header.startsWith('SQLite format 3');\r\n}\r\n\r\nexport function filterTables(tables: TableInfo[], search: string): TableInfo[] {\r\n const term = search.trim().toLowerCase();\r\n\r\n if (!term) {\r\n return tables;\r\n }\r\n\r\n return tables.filter((table) => table.name.toLowerCase().includes(term));\r\n}\r\n\r\nexport function sortTables(\r\n tables: TableInfo[],\r\n sortBy: 'name' | 'rows',\r\n direction: 'asc' | 'desc',\r\n): TableInfo[] {\r\n const sorted = [...tables].sort((left, right) => {\r\n if (sortBy === 'rows') {\r\n return left.rowCount - right.rowCount;\r\n }\r\n\r\n return left.name.localeCompare(right.name);\r\n });\r\n\r\n return direction === 'desc' ? sorted.reverse() : sorted;\r\n}\r\n\r\nexport class SqliteInspector implements DatabaseInspector {\r\n readonly kind = 'sqlite' as const;\r\n readonly capabilities = {\r\n explorer: true,\r\n schemaView: true,\r\n tableData: true,\r\n sqlWorkspace: true,\r\n };\r\n\r\n private session: SqliteSession | null = null;\r\n\r\n async open(snapshot: SnapshotExport | ArrayBuffer): Promise<void> {\r\n this.close();\r\n\r\n const bytes: ArrayBuffer =\r\n snapshot instanceof ArrayBuffer\r\n ? snapshot\r\n : new Uint8Array(snapshot.bytes).buffer;\r\n\r\n if (!isSqliteDatabase(bytes)) {\r\n throw new Error('Snapshot is not a valid SQLite database file');\r\n }\r\n\r\n this.session = await SqliteSession.open(bytes);\r\n }\r\n\r\n close(): void {\r\n this.session?.close();\r\n this.session = null;\r\n }\r\n\r\n listTables(): TableInfo[] {\r\n return this.requireSession().listTables();\r\n }\r\n\r\n getSchema(): SchemaTable[] {\r\n return this.requireSession().getSchema();\r\n }\r\n\r\n fetchTablePage(request: TablePageRequest): TablePageResult {\r\n return this.requireSession().fetchTablePage(request);\r\n }\r\n\r\n executeQuery(sql: string): QueryResult {\r\n return this.requireSession().executeQuery(sql);\r\n }\r\n\r\n private requireSession(): SqliteSession {\r\n if (!this.session) {\r\n throw new Error('No database loaded');\r\n }\r\n\r\n return this.session;\r\n }\r\n}\r\n\r\nexport const sqliteInspectorDefinition = {\r\n kind: 'sqlite' as const,\r\n displayName: 'SQLite',\r\n mimeTypes: [SQLITE_SNAPSHOT_MIME_TYPE, 'application/octet-stream'],\r\n canOpenBytes: isSqliteDatabase,\r\n createInspector: () => new SqliteInspector(),\r\n};\r\n","import { getInspectorRegistry } from '../../inspector/registry';\r\nimport { configureSqliteWasm } from './sqlModule';\r\nimport {\r\n filterTables,\r\n isSqliteDatabase,\r\n sortTables,\r\n sqliteInspectorDefinition,\r\n SqliteInspector,\r\n SqliteSession,\r\n} from './sqliteInspector';\r\n\r\nexport function registerSqliteInspector(options?: { wasmUrl?: string; locateWasm?: () => string }): void {\r\n if (options?.locateWasm) {\r\n configureSqliteWasm(options.locateWasm);\r\n } else if (options?.wasmUrl) {\r\n configureSqliteWasm(() => options.wasmUrl!);\r\n }\r\n\r\n getInspectorRegistry().register(sqliteInspectorDefinition);\r\n}\r\n\r\nexport {\r\n SqliteInspector,\r\n SqliteSession,\r\n filterTables,\r\n isSqliteDatabase,\r\n sortTables,\r\n sqliteInspectorDefinition,\r\n};\r\nexport { configureSqliteWasm } from './sqlModule';\r\n\r\nregisterSqliteInspector();\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/inspectors/sqlite/sqlModule.ts","../../../src/inspectors/sqlite/tableQuery.ts","../../../src/inspectors/sqlite/sqliteInspector.ts","../../../src/inspectors/sqlite/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import initSqlJs, { type SqlJsStatic } from 'sql.js';\r\n\r\nlet sqlModulePromise: Promise<SqlJsStatic> | null = null;\r\nlet wasmLocator: (() => string) | null = null;\r\n\r\nexport function configureSqliteWasm(locator: () => string): void {\r\n wasmLocator = locator;\r\n}\r\n\r\nexport async function getSqlModule(): Promise<SqlJsStatic> {\r\n if (!sqlModulePromise) {\r\n sqlModulePromise = initSqlJs({\r\n // Vite emits /assets/sql-wasm-<hash>.wasm; build-web.mjs also copies /sql-wasm.wasm.\r\n locateFile: () => wasmLocator?.() ?? '/sql-wasm.wasm',\r\n });\r\n }\r\n\r\n return sqlModulePromise;\r\n}\r\n","import type { ColumnInfo } from '../../types/inspection';\r\n\r\nexport function quoteIdentifier(name: string): string {\r\n return `\"${name.replace(/\"/g, '\"\"')}\"`;\r\n}\r\n\r\nexport function buildSearchClause(\r\n columns: ColumnInfo[],\r\n search: string | undefined,\r\n): { clause: string; params: string[] } {\r\n const term = search?.trim();\r\n\r\n if (!term || columns.length === 0) {\r\n return { clause: '', params: [] };\r\n }\r\n\r\n const pattern = `%${term}%`;\r\n const conditions = columns.map(\r\n (column) => `CAST(${quoteIdentifier(column.name)} AS TEXT) LIKE ?`,\r\n );\r\n\r\n return {\r\n clause: ` WHERE (${conditions.join(' OR ')})`,\r\n params: columns.map(() => pattern),\r\n };\r\n}\r\n\r\nexport function resolveSortColumn(\r\n columns: ColumnInfo[],\r\n sortColumn: string | null | undefined,\r\n): string | null {\r\n if (!sortColumn) {\r\n return null;\r\n }\r\n\r\n return columns.some((column) => column.name === sortColumn) ? sortColumn : null;\r\n}\r\n","import type {\r\n ColumnInfo,\r\n QueryResult,\r\n SchemaTable,\r\n TableInfo,\r\n TablePageRequest,\r\n TablePageResult,\r\n} from '../../types/inspection';\r\nimport type { DatabaseInspector } from '../../inspector/types';\r\nimport type { SnapshotExport } from '../../types/snapshot';\r\nimport { getSqlModule } from './sqlModule';\r\nimport { buildSearchClause, quoteIdentifier, resolveSortColumn } from './tableQuery';\r\n\r\nconst SQLITE_SNAPSHOT_MIME_TYPE = 'application/x-sqlite3';\r\n\r\nfunction normalizeCell(cell: unknown): string | number | null {\r\n if (cell === null || cell === undefined) {\r\n return null;\r\n }\r\n\r\n if (typeof cell === 'number' || typeof cell === 'string') {\r\n return cell;\r\n }\r\n\r\n if (cell instanceof Uint8Array) {\r\n return `[BLOB ${cell.byteLength} bytes]`;\r\n }\r\n\r\n return String(cell);\r\n}\r\n\r\nexport class SqliteSession {\r\n private readonly tableNames = new Set<string>();\r\n\r\n private constructor(private readonly db: import('sql.js').Database) {}\r\n\r\n static async open(bytes: ArrayBuffer): Promise<SqliteSession> {\r\n const SQL = await getSqlModule();\r\n const db = new SQL.Database(new Uint8Array(bytes));\r\n const session = new SqliteSession(db);\r\n session.listTables().forEach((table) => session.tableNames.add(table.name));\r\n return session;\r\n }\r\n\r\n close(): void {\r\n this.db.close();\r\n }\r\n\r\n listTables(): TableInfo[] {\r\n const statement = this.db.prepare(\r\n `SELECT name FROM sqlite_master\r\n WHERE type = 'table' AND name NOT LIKE 'sqlite_%'\r\n ORDER BY name`,\r\n );\r\n\r\n const tables: TableInfo[] = [];\r\n\r\n while (statement.step()) {\r\n const name = String(statement.get()[0]);\r\n const countStatement = this.db.prepare(`SELECT COUNT(*) AS c FROM ${quoteIdentifier(name)}`);\r\n\r\n countStatement.step();\r\n const rowCount = Number(countStatement.get()[0] ?? 0);\r\n countStatement.free();\r\n\r\n tables.push({ name, rowCount });\r\n }\r\n\r\n statement.free();\r\n return tables;\r\n }\r\n\r\n getSchema(): SchemaTable[] {\r\n const tables = this.listTables();\r\n\r\n return tables.map((table) => ({\r\n name: table.name,\r\n columns: this.getTableColumns(table.name),\r\n }));\r\n }\r\n\r\n getTableColumns(tableName: string): ColumnInfo[] {\r\n this.assertKnownTable(tableName);\r\n return this.readTableColumns(tableName);\r\n }\r\n\r\n fetchTablePage(request: TablePageRequest): TablePageResult {\r\n this.assertKnownTable(request.table);\r\n\r\n const columns = this.readTableColumns(request.table);\r\n const columnNames = columns.map((column) => column.name);\r\n const tableQuoted = quoteIdentifier(request.table);\r\n const { clause, params } = buildSearchClause(columns, request.search);\r\n const sortColumn = resolveSortColumn(columns, request.sortColumn);\r\n const sortDir = request.sortDir === 'desc' ? 'DESC' : 'ASC';\r\n const page = Math.max(1, request.page);\r\n const pageSize = Math.max(1, request.pageSize);\r\n const offset = (page - 1) * pageSize;\r\n\r\n const countStatement = this.db.prepare(`SELECT COUNT(*) AS c FROM ${tableQuoted}${clause}`);\r\n countStatement.bind(params);\r\n countStatement.step();\r\n const totalCount = Number(countStatement.get()[0] ?? 0);\r\n countStatement.free();\r\n\r\n const orderClause = sortColumn\r\n ? ` ORDER BY ${quoteIdentifier(sortColumn)} ${sortDir}`\r\n : '';\r\n const dataStatement = this.db.prepare(\r\n `SELECT * FROM ${tableQuoted}${clause}${orderClause} LIMIT ? OFFSET ?`,\r\n );\r\n dataStatement.bind([...params, pageSize, offset]);\r\n\r\n const rows: (string | number | null)[][] = [];\r\n\r\n while (dataStatement.step()) {\r\n rows.push(columnNames.map((_, index) => normalizeCell(dataStatement.get()[index])));\r\n }\r\n\r\n dataStatement.free();\r\n\r\n return {\r\n columns: columnNames,\r\n rows,\r\n totalCount,\r\n page,\r\n pageSize,\r\n };\r\n }\r\n\r\n executeQuery(sql: string): QueryResult {\r\n const startedAt = performance.now();\r\n const resultSets = this.db.exec(sql);\r\n const durationMs = performance.now() - startedAt;\r\n\r\n if (resultSets.length === 0) {\r\n return {\r\n columns: [],\r\n rows: [],\r\n rowCount: 0,\r\n durationMs,\r\n };\r\n }\r\n\r\n const primary = resultSets[0];\r\n\r\n return {\r\n columns: primary.columns,\r\n rows: primary.values.map((row) => row.map((cell) => normalizeCell(cell))),\r\n rowCount: primary.values.length,\r\n durationMs,\r\n };\r\n }\r\n\r\n private assertKnownTable(tableName: string): void {\r\n if (!this.tableNames.has(tableName)) {\r\n throw new Error(`Unknown table: ${tableName}`);\r\n }\r\n }\r\n\r\n private readTableColumns(tableName: string): ColumnInfo[] {\r\n const statement = this.db.prepare(`PRAGMA table_info(${quoteIdentifier(tableName)})`);\r\n const columns: ColumnInfo[] = [];\r\n\r\n while (statement.step()) {\r\n const row = statement.getAsObject() as {\r\n name: string;\r\n type: string;\r\n notnull: number;\r\n pk: number;\r\n dflt_value: string | null;\r\n };\r\n\r\n columns.push({\r\n name: row.name,\r\n type: row.type || 'ANY',\r\n notNull: row.notnull === 1,\r\n pk: row.pk > 0,\r\n defaultValue: row.dflt_value,\r\n });\r\n }\r\n\r\n statement.free();\r\n return columns;\r\n }\r\n}\r\n\r\nexport function isSqliteDatabase(bytes: ArrayBuffer): boolean {\r\n const header = new TextDecoder().decode(new Uint8Array(bytes, 0, 16));\r\n return header.startsWith('SQLite format 3');\r\n}\r\n\r\nexport function filterTables(tables: TableInfo[], search: string): TableInfo[] {\r\n const term = search.trim().toLowerCase();\r\n\r\n if (!term) {\r\n return tables;\r\n }\r\n\r\n return tables.filter((table) => table.name.toLowerCase().includes(term));\r\n}\r\n\r\nexport function sortTables(\r\n tables: TableInfo[],\r\n sortBy: 'name' | 'rows',\r\n direction: 'asc' | 'desc',\r\n): TableInfo[] {\r\n const sorted = [...tables].sort((left, right) => {\r\n if (sortBy === 'rows') {\r\n return left.rowCount - right.rowCount;\r\n }\r\n\r\n return left.name.localeCompare(right.name);\r\n });\r\n\r\n return direction === 'desc' ? sorted.reverse() : sorted;\r\n}\r\n\r\nexport class SqliteInspector implements DatabaseInspector {\r\n readonly kind = 'sqlite' as const;\r\n readonly capabilities = {\r\n explorer: true,\r\n schemaView: true,\r\n tableData: true,\r\n sqlWorkspace: true,\r\n };\r\n\r\n private session: SqliteSession | null = null;\r\n\r\n async open(snapshot: SnapshotExport | ArrayBuffer): Promise<void> {\r\n this.close();\r\n\r\n const bytes: ArrayBuffer =\r\n snapshot instanceof ArrayBuffer\r\n ? snapshot\r\n : new Uint8Array(snapshot.bytes).buffer;\r\n\r\n if (!isSqliteDatabase(bytes)) {\r\n throw new Error('Snapshot is not a valid SQLite database file');\r\n }\r\n\r\n this.session = await SqliteSession.open(bytes);\r\n }\r\n\r\n close(): void {\r\n this.session?.close();\r\n this.session = null;\r\n }\r\n\r\n listTables(): TableInfo[] {\r\n return this.requireSession().listTables();\r\n }\r\n\r\n getSchema(): SchemaTable[] {\r\n return this.requireSession().getSchema();\r\n }\r\n\r\n fetchTablePage(request: TablePageRequest): TablePageResult {\r\n return this.requireSession().fetchTablePage(request);\r\n }\r\n\r\n executeQuery(sql: string): QueryResult {\r\n return this.requireSession().executeQuery(sql);\r\n }\r\n\r\n private requireSession(): SqliteSession {\r\n if (!this.session) {\r\n throw new Error('No database loaded');\r\n }\r\n\r\n return this.session;\r\n }\r\n}\r\n\r\nexport const sqliteInspectorDefinition = {\r\n kind: 'sqlite' as const,\r\n displayName: 'SQLite',\r\n mimeTypes: [SQLITE_SNAPSHOT_MIME_TYPE, 'application/octet-stream'],\r\n canOpenBytes: isSqliteDatabase,\r\n createInspector: () => new SqliteInspector(),\r\n};\r\n","import { getInspectorRegistry } from '../../inspector/registry';\r\nimport { configureSqliteWasm } from './sqlModule';\r\nimport {\r\n filterTables,\r\n isSqliteDatabase,\r\n sortTables,\r\n sqliteInspectorDefinition,\r\n SqliteInspector,\r\n SqliteSession,\r\n} from './sqliteInspector';\r\n\r\nexport function registerSqliteInspector(options?: { wasmUrl?: string; locateWasm?: () => string }): void {\r\n if (options?.locateWasm) {\r\n configureSqliteWasm(options.locateWasm);\r\n } else if (options?.wasmUrl) {\r\n configureSqliteWasm(() => options.wasmUrl!);\r\n }\r\n\r\n getInspectorRegistry().register(sqliteInspectorDefinition);\r\n}\r\n\r\nexport {\r\n SqliteInspector,\r\n SqliteSession,\r\n filterTables,\r\n isSqliteDatabase,\r\n sortTables,\r\n sqliteInspectorDefinition,\r\n};\r\nexport { configureSqliteWasm } from './sqlModule';\r\n"]}
|
package/dist/native.cjs
CHANGED
|
@@ -1730,6 +1730,10 @@ function DevToolsProvider({
|
|
|
1730
1730
|
setDeviceId(persistedId);
|
|
1731
1731
|
setDeviceIdReady(true);
|
|
1732
1732
|
}
|
|
1733
|
+
}).catch(() => {
|
|
1734
|
+
if (!cancelled) {
|
|
1735
|
+
setDeviceIdReady(true);
|
|
1736
|
+
}
|
|
1733
1737
|
});
|
|
1734
1738
|
return () => {
|
|
1735
1739
|
cancelled = true;
|
|
@@ -2490,9 +2494,12 @@ function isFloatingButtonTap(totalMovement) {
|
|
|
2490
2494
|
}
|
|
2491
2495
|
var DEFAULT_ICON_SIZE = 22;
|
|
2492
2496
|
var DEFAULT_ICON_COLOR = "#f8fafc";
|
|
2497
|
+
var DEFAULT_BUTTON_COLOR = "#1e293b";
|
|
2493
2498
|
function FloatingDevToolsButton({
|
|
2494
2499
|
position = "bottom-right",
|
|
2495
2500
|
iconStyle,
|
|
2501
|
+
buttonColor,
|
|
2502
|
+
iconColor,
|
|
2496
2503
|
draggable = true,
|
|
2497
2504
|
snapToEdges = true,
|
|
2498
2505
|
floatingPosition,
|
|
@@ -2596,22 +2603,24 @@ function FloatingDevToolsButton({
|
|
|
2596
2603
|
if (!renderedPosition) {
|
|
2597
2604
|
return null;
|
|
2598
2605
|
}
|
|
2606
|
+
const resolvedButtonColor = buttonColor ?? DEFAULT_BUTTON_COLOR;
|
|
2607
|
+
const resolvedIconColor = iconColor ?? reactNative.StyleSheet.flatten(iconStyle)?.color ?? DEFAULT_ICON_COLOR;
|
|
2608
|
+
const buttonStyle = { backgroundColor: resolvedButtonColor };
|
|
2609
|
+
const statusDotStyle = {
|
|
2610
|
+
backgroundColor: getConnectionDotColor(connectionState),
|
|
2611
|
+
borderColor: resolvedButtonColor
|
|
2612
|
+
};
|
|
2599
2613
|
const buttonContent = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2600
2614
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2601
2615
|
MaterialCommunityIcons__default.default,
|
|
2602
2616
|
{
|
|
2603
|
-
color:
|
|
2617
|
+
color: resolvedIconColor,
|
|
2604
2618
|
name: "database",
|
|
2605
2619
|
size: DEFAULT_ICON_SIZE,
|
|
2606
2620
|
style: iconStyle
|
|
2607
2621
|
}
|
|
2608
2622
|
),
|
|
2609
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2610
|
-
reactNative.View,
|
|
2611
|
-
{
|
|
2612
|
-
style: [styles4.statusDot, { backgroundColor: getConnectionDotColor(connectionState) }]
|
|
2613
|
-
}
|
|
2614
|
-
)
|
|
2623
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles4.statusDot, statusDotStyle] })
|
|
2615
2624
|
] });
|
|
2616
2625
|
if (!draggable) {
|
|
2617
2626
|
const positionStyle = position === "bottom-left" ? styles4.bottomLeft : styles4.bottomRight;
|
|
@@ -2621,7 +2630,11 @@ function FloatingDevToolsButton({
|
|
|
2621
2630
|
accessibilityLabel: "Open Database DevTools",
|
|
2622
2631
|
accessibilityRole: "button",
|
|
2623
2632
|
onPress: openLauncher,
|
|
2624
|
-
style: ({ pressed }) => [
|
|
2633
|
+
style: ({ pressed }) => [
|
|
2634
|
+
styles4.button,
|
|
2635
|
+
buttonStyle,
|
|
2636
|
+
pressed && styles4.buttonPressed
|
|
2637
|
+
],
|
|
2625
2638
|
children: buttonContent
|
|
2626
2639
|
}
|
|
2627
2640
|
) });
|
|
@@ -2646,7 +2659,7 @@ function FloatingDevToolsButton({
|
|
|
2646
2659
|
accessibilityHint: "Drag to move. Tap to open DevTools launcher.",
|
|
2647
2660
|
accessibilityLabel: "Open Database DevTools",
|
|
2648
2661
|
accessibilityRole: "button",
|
|
2649
|
-
style: [styles4.button, dragPosition && styles4.buttonDragging],
|
|
2662
|
+
style: [styles4.button, buttonStyle, dragPosition && styles4.buttonDragging],
|
|
2650
2663
|
children: buttonContent
|
|
2651
2664
|
}
|
|
2652
2665
|
)
|
|
@@ -2675,7 +2688,6 @@ var styles4 = reactNative.StyleSheet.create({
|
|
|
2675
2688
|
width: FLOATING_BUTTON_SIZE,
|
|
2676
2689
|
height: FLOATING_BUTTON_SIZE,
|
|
2677
2690
|
borderRadius: FLOATING_BUTTON_SIZE / 2,
|
|
2678
|
-
backgroundColor: "#1e293b",
|
|
2679
2691
|
alignItems: "center",
|
|
2680
2692
|
justifyContent: "center",
|
|
2681
2693
|
shadowColor: "#000",
|
|
@@ -2698,8 +2710,7 @@ var styles4 = reactNative.StyleSheet.create({
|
|
|
2698
2710
|
width: 10,
|
|
2699
2711
|
height: 10,
|
|
2700
2712
|
borderRadius: 5,
|
|
2701
|
-
borderWidth: 2
|
|
2702
|
-
borderColor: "#1e293b"
|
|
2713
|
+
borderWidth: 2
|
|
2703
2714
|
}
|
|
2704
2715
|
});
|
|
2705
2716
|
var explorerColors = {
|
|
@@ -3842,6 +3853,8 @@ function DatabaseDevTools({
|
|
|
3842
3853
|
floatingPosition,
|
|
3843
3854
|
onFloatingPositionChange,
|
|
3844
3855
|
style,
|
|
3856
|
+
buttonColor,
|
|
3857
|
+
iconColor,
|
|
3845
3858
|
onConnectionStateChange
|
|
3846
3859
|
}) {
|
|
3847
3860
|
if (!isDevToolsEnabled(enabled)) {
|
|
@@ -3859,8 +3872,10 @@ function DatabaseDevTools({
|
|
|
3859
3872
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3860
3873
|
FloatingDevToolsButton,
|
|
3861
3874
|
{
|
|
3875
|
+
buttonColor,
|
|
3862
3876
|
draggable,
|
|
3863
3877
|
floatingPosition,
|
|
3878
|
+
iconColor,
|
|
3864
3879
|
iconStyle: style,
|
|
3865
3880
|
onFloatingPositionChange,
|
|
3866
3881
|
position,
|