Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

dbinspect

Inspect the embedded databases inside your running Dart or Flutter application, from a desktop client, over a paired connection.

Add one package to your app, forward a port, and browse your live data — no adb pull, no copying a .db off the device and wondering whether you also took its -wal.

These are the Apache-2.0 client-side libraries. They are engine-neutral and product-neutral: they speak a documented wire protocol, and any client that speaks it can drive them.

Three languages, one protocol

The protocol is not a Dart protocol. A bridge is whatever speaks it, and this repository holds the engine-neutral core for each language it is implemented in, beside the specification that binds all of them.

Language Core Status Registry
Dart / Flutter dart/dbinspect_bridge shipped pub.dev dbinspect_bridge
JVM — desktop and native Android jvm/dbinspect-bridge M3, not yet written Maven Central org.dizitart:dbinspect-bridge
Rust rust/dbinspect-bridge M4, not yet written crates.io dbinspect-bridge

A core depends on no database. It is the protocol, pairing, the transport and the release guard. Everything that knows about an actual storage engine is a separate adapter that depends on a core:

Adapter Language Lives in
dart/dbinspect_sqfliteSqfliteAdapter Dart here
dbinspect_drift, dbinspect_hive (M8) Dart here
nitrite_bridge Dart nitrite-flutter packages/
org.dizitart:nitrite-bridge JVM nitrite-java nitrite-bridge/
nitrite-bridge Rust nitrite-rust nitrite-bridge/

An adapter never depends on another adapter, so inspecting a SQLite database pulls in no Nitrite and inspecting a Nitrite database pulls in no SQLite — and, because the core is here rather than inside a database's own repository, you can inspect a JVM or Rust database that has nothing to do with Nitrite by writing an adapter against the core. That is the whole reason the split exists. A JDBC, H2, MapDB, redb or sled adapter is a downstream package; none is scheduled here, and none needs anything from us to be written.

This repository sits in the nitrite organisation, and that says nothing about what it depends on. It is there because docs/THREAT-MODEL.md §7 is the acceptance criteria for the three nitrite-bridge adapters above, and a specification is easier to maintain beside the implementations it binds.

Use

import 'package:dbinspect_bridge/dbinspect_bridge.dart';
import 'package:dbinspect_sqflite/dbinspect_sqflite.dart';

await startBridge(
  appName: 'example_app',
  adapters: [
    SqfliteAdapter(executor: db, id: 'app', displayName: 'app.db'),
  ],
);

The pairing code is printed to your logger in a banner. Type it into the client to connect.

Safe by default

It is not in your release build. startBridge returns null behind a compile-time constant, so the AOT compiler drops the server and the protocol strings entirely. Opt back in on purpose with --dart-define=DBINSPECT_BRIDGE=true.

It binds 127.0.0.1. Reaching it from another machine is meant to be a deliberate act — adb forward tcp:9000 tcp:9000 or an SSH tunnel. Setting bindAddress forces TLS with a certificate generated for the session, whose SHA-256 fingerprint goes in the banner for the client to pin.

Everything beyond reading is off. edit, sql and snapshot are false and regex is absent unless you opt in per adapter. An operation that is off is absent from the reported capabilities, not merely refused when called.

Pairing is not a formality. 40 bits, regenerated per run, compared in constant time, with a failure budget that is per bridge session rather than per connection — ten wrong guesses close pairing until the application restarts.

Documents

Document What it covers
docs/PROTOCOL.md The JSON-RPC wire protocol, frozen at v1. Additive changes only.
docs/THREAT-MODEL.md The threat model. §5 is binding architecture, §7 is binding acceptance criteria.

Both are binding on every implementation of the protocol, in every language, and conformance/ is how that is checked rather than asserted: a black-box suite that pairs with a running bridge and reads what it puts on the wire, taking a host:port and a pairing code and nothing else. The same invocation drives the Dart bridge today and the JVM and Rust bridges when they land — which is what freezing the protocol was for.

cd conformance && dart run bin/dbinspect_conformance.dart 127.0.0.1:53219 J8K4M2QX

Checks

Each Dart package is plain dart pub — pure Dart, no Flutter, no workspace wiring. They must stay that way: they are embedded in other people's applications and requiring a Flutter SDK to build one would be a real cost to a server-side or CLI user.

for p in dart/*; do (cd "$p" && dart pub get && dart format --output=none --set-exit-if-changed . && dart analyze --fatal-infos && dart test) || break; done

jvm/ and rust/ get their own CI jobs when they land. The language is a directory, not the shape of the repository.

Two checks need more than a Dart SDK and so have jobs of their own. dart/dbinspect_sqflite/example/flutter_app is a Flutter app with the bridge in it over a 50k-row table, and it is what they run against:

cd dart/dbinspect_sqflite/example/flutter_app && ./tool/verify_release_apk.sh
dart tool/measure_page_latency.dart <host:port> <code>

The first builds the release APK and greps it for the protocol strings — §7 criterion 2 on a shipped artifact rather than on a probe binary — with the --dart-define opt-in as its negative control. The second measures what a client waits for a page, reporting the round trip and the adapter's own share separately, and runs against a bridge in any language.

conformance/ is a job of its own and is minutes long: one of the criteria it carries is "ten wrong pairing codes close the gate", and the bridge's backoff is a real four-minute wait that exists to be that slow.

Clients

Fanlight is a desktop client for this protocol (Windows / macOS / Linux) and is a separate, commercial product. The protocol is open and these libraries are Apache-2.0; nothing here depends on Fanlight, and writing another client requires only docs/PROTOCOL.md.

Licence

Apache-2.0. See LICENSE.

About

Inspect the embedded databases inside your running Dart or Flutter application, from a desktop client, over a paired connection. Apache-2.0.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages