Skip to content

Universal PowerSync Diagnostics (POC) - #1094

Draft
khawarizmus wants to merge 30 commits into
mainfrom
diagnostics-poc
Draft

khawarizmus wants to merge 30 commits into
mainfrom
diagnostics-poc

Conversation

@khawarizmus

@khawarizmus khawarizmus commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

This PR implements a live-attach diagnostics tool built once and reused across different hosts.

New packages

  • @powersync/diagnostics-ui — the shared UI (contains six tabs: Sync Status, Data, Buckets, Streams, Config, Logs).
  • @powersync/diagnostics-core — the host-side client and the PostMessageTransport.
  • tools/diagnostics-extension — a Chrome DevTools extension (using WXT).

@powersync/common

  • Add the diagnostics subpath: the protocol, the agent, and the state mappers.
  • Add schema serialization: Schema.serialize() and fromSerialized(), with tests.
  • Promote connector and connectionOptions to the public database interface.
  • Add the diagnostics sync option.

@powersync/web

  • Add the BroadcastChannel transport and event source.
  • Add enableDiagnostics(db).

shared-internals

  • Fix the connector getter to persist for the connection lifetime.
  • Wire the core diagnostics event stream (HandleDiagnostics) into the JS SDK.

@powersync/nuxt

  • Replace the old inspector with the shared UI over the protocol.
  • Delete the interceptor, the schema inference, and the dead inspector code.

Notes

  • Draft PR for review.
  • The extension ships here for review. We may move it to its own repository later.

Claude code was used to steer the discovery and development. The code was reviewed and modified manually.

…ream, UI components, and schema inspection features
…t and enhance connection handling in extension
…ostMessageTransport, enhance package metadata, and add Chrome types
…play and integrate virtual scrolling for upload queue
…t detail component, and improved data handling features
@changeset-bot

changeset-bot Bot commented Sep 9, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 9c6336a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 13 packages
Name Type
@powersync/diagnostics-ui Minor
@powersync/web Minor
@powersync/shared-internals Minor
@powersync/diagnostics-core Minor
@powersync/diagnostics Minor
@powersync/nuxt Minor
@powersync/common Minor
@powersync/adapter-sql-js Patch
@powersync/tanstack-react-query Patch
@powersync/diagnostics-app Patch
@powersync/capacitor Patch
@powersync/node Patch
@powersync/react-native Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@simolus3 simolus3 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To share more context here (I've also shared that offline with more context @khawarizmus). I think the idea is awesome, my initial architectural complaints are:

  1. It's not clear whether we need a browser extension, so remove that from this PR which is already very big (you can open a follow-up PR for that separately).
  2. I think a JSON-based protocol over "any two way channel" is the wrong abstraction here. It e.g. forces us to re-invent an RPC protocol when some implementations we'll use (say the Dart VM service protocol) are already RPC based.
  3. None of this should require any changes to an existing SDK package (aside from forwarding core diagnostics events, but even that should likely be a separate PR to validate that the basic integration can work without SDK changes). We can likely inject an agent by writing a vite devtools package instead. Or initially, we could also expose it as a seperate package a user would depend on to expose the channel (e.g. a enablePowerSyncDiagnostics(port: MessagePort, db: BasePowerSyncDatabase)).
  4. Related to 2 and 3, the interface the diagnostics tool expects an SDK to provide should be an actual TypeScript interface with async methods and event listeners. It is the responsibility of each integration (vite, postMessage iframe, Dart) to figure out how to implement that interface by doing the serialization itself.

Add dependency-free `shapes.ts` and `integration.ts` as the tool-owned
protocol; move PROTOCOL.md into diagnostics-core and rewrite it to
interface + shapes.
Comment thread packages/diagnostics-ui/playground/mockDatabase.ts Fixed

@simolus3 simolus3 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't take a look at the UI yet, but the architecture of how devtools are served and integrated looks pretty good at this point. I'll also try to scaffold a Dart integration over the vm service protocol.

Comment thread packages/diagnostics-core/src/bridge.ts Outdated
*/

/** The shape exposed over comlink: `observeEvents` takes a proxied callback instead of a function. */
type Remote = Omit<SdkIntegration, 'observeEvents'> & {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's just make observeEvents return a promise on SdkIntegration, or a Promise<void> | void.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was addressed

Comment thread packages/diagnostics-core/src/index.ts Outdated
Comment on lines +6 to +13
// The JavaScript integration (runs in the app page) and the structural database it reads.
export * from './live-database.js';
export * from './agent.js';
export * from './state.js';

// Moving an integration across an iframe boundary, and deriving UI state from its events.
export * from './bridge.js';
export * from './store.js';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Relying on structural typing to avoid pulling in the JS SDK here is clever, but also feels somewhat fragile.

Given that these files are still only useful when providing diagnostics for JavaScript SDKs, maybe they shouldn't be part of the default export. I think putting them into a separate package is overkill, but maybe they should be exported from a separate entrypoint (say @powersync/diagnostics-core-js-web).

(and then if they're separate exports, I wouldn't mind this package having an optional dependency on @powersync/common and defining the JS agent on BasePowerSyncDatabase).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The JS-specific code now lives in @powersync/diagnostics-core/js. I kept the structural type instead of adding an optional @powersync/common dependency. The Vite client can now pass WebPowerSyncDatabase directly, and only the Playground UI mock needs to implement that small interface.

Comment thread packages/diagnostics-core/PROTOCOL.md Outdated

The tool never carries a wire format of its own. Request/response correlation, connection and reconnection are the implementation's concern.

## 2. The interface

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having the overview here is helpful, but it could also be part of the readme. Sections 2-5 of this document should be tsdoc comments instead.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was addressed. The relevant parts are now in the README, and the rest has been ported to tsdocs comments


/**
* Emitted by the core extension when diagnostics are enabled on the sync stream (see
* {@link https://github.com/powersync-ja/powersync-sqlite-core diagnostics}). Reports detailed

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is done

@bean1352
bean1352 added this pull request to stack #1110 September 17, 2026 10:58

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants