Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(toolbar): Refactor toolbar and enhance functionality #1219

Merged
merged 34 commits into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
684dfac
Replace esbuild with vite
msfstef May 1, 2024
ee582ed
Switch from react to preact for smaller bundle size
msfstef May 1, 2024
94e9352
Refactor CSS to use css modules
msfstef May 1, 2024
2e46c53
Refactor css for SQLTab
msfstef May 1, 2024
3ecde14
Add some css module configuration
msfstef May 1, 2024
910e3b4
Slight refactor for toolbar opening and closing
msfstef May 1, 2024
1bf7fb8
Reintroduce React and RadixUI
msfstef May 1, 2024
a6fabf8
Update tabs with radix ui element
msfstef May 1, 2024
7f48f7d
Prettier connection status tab
msfstef May 1, 2024
4ac9105
Refactor shape and local db tab
msfstef May 1, 2024
a88e00c
Add table introspection for local db
msfstef May 1, 2024
990deda
Add tooltip to reset db button
msfstef May 1, 2024
a832308
Add data grid dependency
msfstef May 2, 2024
1cd4c0a
Simplify styling for Shell section
msfstef May 2, 2024
5ad54aa
Ensure scrollability in shell tab
msfstef May 2, 2024
0af4082
Remove unused import
msfstef May 2, 2024
8b0d1ba
Add InspectTable tab with full tables
msfstef May 2, 2024
5f5924e
Add eslint to the mix
msfstef May 2, 2024
ac5a2da
Push new pnpm lock
msfstef May 2, 2024
22d6634
Import types from expo-sqlite
msfstef May 2, 2024
7bf54c7
Subscribe to data changes to tables
msfstef May 2, 2024
d99e85d
Full height table in the shell tab
msfstef May 2, 2024
5050ed3
Fix minor theming issues
msfstef May 8, 2024
1e7ae6f
Move table into its own component
msfstef May 8, 2024
528da2a
Add ability to resize columns for table
msfstef May 8, 2024
f1817e2
Style the data grid tables using the radix theme
msfstef May 8, 2024
e5a5fff
Minor styling changes
msfstef May 8, 2024
54b8ecd
Add changeset
msfstef May 8, 2024
1d62f47
Add some more API tests
msfstef May 8, 2024
4490b6a
Rmove debug toolbar from package.json
msfstef May 8, 2024
5b77936
Add prepublish build step to toolbar
msfstef May 9, 2024
5362561
Use shadow dom to circumvent css bleeding
msfstef May 13, 2024
27ad6a0
Use slightly darker colors
msfstef May 14, 2024
76ac2c2
Update glide data grid to alpha version to fix shadow dom issues
msfstef May 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/chilled-flowers-march.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@electric-sql/debug-toolbar": minor
---

Complete restyling of toolbar and new features (table inspector, shape inspector)
4 changes: 2 additions & 2 deletions .github/workflows/toolbar_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
node-version: 18
cache: pnpm
- run: make deps
- run: pnpm run check-styleguide
- run: make check_styleguide
check_types:
name: Check types
runs-on: ubuntu-latest
Expand All @@ -41,7 +41,7 @@ jobs:
node-version: 18
cache: pnpm
- run: make deps
- run: pnpm run typecheck
- run: make check_types
test:
runs-on: ubuntu-latest
strategy:
Expand Down
2 changes: 1 addition & 1 deletion clients/typescript/src/drivers/expo-sqlite/mock.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Row } from '../../util/types'
import { Query, ResultSet, SQLiteCallback } from 'expo-sqlite/src/SQLite.types'
import { type Query, type ResultSet, type SQLiteCallback } from 'expo-sqlite'
import { Database } from './database'

export class MockDatabase implements Database {
Expand Down
20 changes: 20 additions & 0 deletions components/toolbar/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module.exports = {
parser: '@typescript-eslint/parser', // Specifies the ESLint parser
extends: [
'plugin:react/recommended', // Uses the recommended rules from @eslint-plugin-react
'plugin:@typescript-eslint/recommended', // Uses the recommended rules from @typescript-eslint/eslint-plugin
],
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
ecmaFeatures: {
jsx: true,
},
},
rules: {},
settings: {
react: {
version: 'detect',
},
},
}
9 changes: 8 additions & 1 deletion components/toolbar/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@ deps:
pnpm install --frozen-lockfile
make -C ../../clients/typescript build

build: deps
build:
deps
pnpm run build

check_types:
pnpm run typecheck

check_styleguide:
pnpm run check-styleguide

tests:
CI=true pnpm run test
42 changes: 0 additions & 42 deletions components/toolbar/builder.js

This file was deleted.

32 changes: 22 additions & 10 deletions components/toolbar/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,50 @@
"version": "1.0.2",
"type": "module",
"main": "dist/index.cjs.js",
"module": "dist/index.esm.js",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"author": "ElectricSQL",
"license": "Apache-2.0",
"scripts": {
"build": "rm -rf ./dist && node builder.js && tsc -p tsconfig.build.json",
"check-styleguide": "prettier --check --loglevel warn .",
"build": "rm -rf ./dist && vite build && tsc -p tsconfig.build.json",
"check-styleguide": "prettier --check --loglevel warn . && eslint src --quiet",
"typecheck": "tsc --noEmit",
"prepublishOnly": "pnpm build",
"test": "vitest run"
},
"engines": {
"node": ">=16.11.0"
},
"dependencies": {
"@glideapps/glide-data-grid": "^6.0.4-alpha8",
"@radix-ui/themes": "^3.0.3",
"clsx": "^2.1.1",
"codemirror": "^5.65.16",
"react": "^18.2.0",
"lodash": "^4.17.21",
"marked": "^4.0.10",
"react": "^18.3.1",
"react-codemirror2": "^8.0.0",
"react-dom": "^18.2.0"
"react-dom": "^18.3.1",
"react-responsive-carousel": "^3.2.23",
"sql-formatter": "^15.3.1"
},
"devDependencies": {
"@types/better-sqlite3": "7.6.3",
"@types/node": "^20.12.7",
"@types/react": "^18.2.0",
"@types/react-dom": "^18.2.0",
"@types/react": "^18.3.1",
"@types/react-dom": "^18.3.0",
"@typescript-eslint/eslint-plugin": "^7.8.0",
"@typescript-eslint/parser": "^7.8.0",
"@vitejs/plugin-react": "^4.2.1",
"better-sqlite3": "^8.4.0",
"electric-sql": "workspace:*",
"esbuild": "^0.20.2",
"esbuild-plugin-inline-image": "^0.0.9",
"esbuild-plugin-inline-import": "^1.0.4",
"eslint": "^8.22.0",
"eslint-plugin-react": "^7.34.1",
"jsdom": "24.0.0",
"prettier": "3.2.5",
"typescript": "^5.4.5",
"vite": "^5.2.10",
"vite-plugin-css-injected-by-js": "^3.5.1",
"vitest": "^1.5.0"
},
"peerDependencies": {
Expand Down
25 changes: 24 additions & 1 deletion components/toolbar/src/api/interface.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
import { Shape } from 'electric-sql/satellite'
import { Row, Statement, ConnectivityState } from 'electric-sql/util'

export type UnsubscribeFunction = () => void

export type DebugShape = Shape & { id: string }

export interface TableColumn {
name: string
type: 'NULL' | 'INTEGER' | 'REAL' | 'TEXT' | 'BLOB'
}

export interface DbTableInfo {
name: string
sql: string
columns: TableColumn[]
}

export interface ToolbarInterface {
getSatelliteNames(): string[]
getSatelliteStatus(name: string): ConnectivityState | null
Expand All @@ -12,8 +26,17 @@ export interface ToolbarInterface {

toggleSatelliteStatus(name: string): Promise<void>

getSatelliteShapeSubscriptions(name: string): string[]
getSatelliteShapeSubscriptions(name: string): DebugShape[]

resetDb(dbName: string): Promise<void>
queryDb(dbName: string, statement: Statement): Promise<Row[]>

getDbTables(dbName: string): Promise<DbTableInfo[]>
getElectricTables(dbName: string): Promise<DbTableInfo[]>

subscribeToDbTable(
dbName: string,
tableName: string,
callback: () => void,
): UnsubscribeFunction
}
99 changes: 92 additions & 7 deletions components/toolbar/src/api/toolbar.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
import { ToolbarInterface, UnsubscribeFunction } from './interface'
import {
DbTableInfo,
DebugShape,
TableColumn,
ToolbarInterface,
UnsubscribeFunction,
} from './interface'
import { Row, Statement, ConnectivityState } from 'electric-sql/util'
import { Registry, GlobalRegistry, Satellite } from 'electric-sql/satellite'
import {
Registry,
GlobalRegistry,
Satellite,
Shape,
} from 'electric-sql/satellite'
import { SubscriptionsManager } from 'electric-sql/satellite/shapes'

export class Toolbar implements ToolbarInterface {
Expand Down Expand Up @@ -48,15 +59,19 @@ export class Toolbar implements ToolbarInterface {
return sat.connectWithBackoff()
}

getSatelliteShapeSubscriptions(name: string): string[] {
getSatelliteShapeSubscriptions(name: string): DebugShape[] {
const sat = this.getSatellite(name)
//@ts-expect-error accessing private field
const manager = sat['subscriptions'] as SubscriptionsManager
const shapes = JSON.parse(manager.serialize()) as Record<string, any>
const shapes = JSON.parse(manager.serialize()) as Record<
string,
{ definition: Shape }[]
>
return Object.entries(shapes).flatMap((shapeKeyDef) =>
shapeKeyDef[1].map((x: any) =>
JSON.stringify({ id: shapeKeyDef[0], ...x.definition }, null, 2),
),
shapeKeyDef[1].map((x) => ({
id: shapeKeyDef[0],
...x.definition,
})),
)
}

Expand All @@ -76,4 +91,74 @@ export class Toolbar implements ToolbarInterface {
const sat = this.getSatellite(dbName)
return sat.adapter.query(statement)
}

async getDbTables(dbName: string): Promise<DbTableInfo[]> {
const adapter = this.getSatellite(dbName).adapter
const tables = (await adapter.query({
sql: `
SELECT name, sql FROM sqlite_master WHERE type='table'
AND name NOT LIKE 'sqlite_%'
AND name NOT LIKE '_electric_%'`,
})) as unknown as Omit<DbTableInfo, 'columns'>[]

return Promise.all(
tables.map(async (tbl) => ({
...tbl,
columns: await this.getTableColumns(dbName, tbl.name),
})),
)
}

async getElectricTables(dbName: string): Promise<DbTableInfo[]> {
const adapter = this.getSatellite(dbName).adapter
const tables = (await adapter.query({
sql: `
SELECT name, sql FROM sqlite_master WHERE type='table'
AND name LIKE '_electric_%'`,
})) as unknown as Omit<DbTableInfo, 'columns'>[]

return Promise.all(
tables.map(async (tbl) => ({
...tbl,
columns: await this.getTableColumns(dbName, tbl.name),
})),
)
}

subscribeToDbTable(
dbName: string,
tableName: string,
callback: () => void,
): UnsubscribeFunction {
const sat = this.getSatellite(dbName)
const unsubscribe = sat.notifier.subscribeToDataChanges((notification) => {
if (notification.dbName !== dbName) return
for (const change of notification.changes) {
if (
change.qualifiedTablename.tablename === tableName ||
// always trigger an update if subscribing to internal tables
tableName.startsWith('_electric')
) {
callback()
return
}
}
})

return unsubscribe
}

private async getTableColumns(
dbName: string,
tableName: string,
): Promise<TableColumn[]> {
const adapter = this.getSatellite(dbName).adapter
const columns = await adapter.query({
sql: `PRAGMA table_info(${tableName})`,
})
return columns.map((c) => ({
name: c.name,
type: c.type,
})) as TableColumn[]
}
}
Loading
Loading