Skip to content

Move implementation details into separate package#993

Draft
simolus3 wants to merge 12 commits into
v2from
internals-package
Draft

Move implementation details into separate package#993
simolus3 wants to merge 12 commits into
v2from
internals-package

Conversation

@simolus3

@simolus3 simolus3 commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

This moves @internal members from @powersync/common into the new @powersync/shared-internals package. The idea is that @powersync/shared-internals would never be imported by users, so we can change it freely. @powersync/common still contains and exports common interfaces relevant across multiple SDKs.

This PR effectively solves two long-term goals:

  1. We want to be explicit about our public API, and make it harder for users to accidentally rely on implementation details. Exporting stuff from @powersync/common (which is then re-exported from our SDKs) made it very easy to get this wrong. By moving things to @powersync/shared-internals (which we obviously wouldn't re-export), we're able to encapsulate implementation details much better.
  2. Adding new members to abstract classes shouldn't be a breaking change. Previously, AbstractPowerSyncDatabase was both a class and effectively a public interface. We often forgot about the second part, and added new methods without realizing that this is a breaking change! Since implementation details are now part of @powersync/shared-internals, interfaces are extracted explicitly.

For the most part, this PR just moves code around: Identify stuff marked as @internal in @powersync/common, move it into the internals package, update imports, repeat. There are two exceptions, which I'll outline below.

AbstractPowerSyncDatabase

This class is both an interface (users imported it from @powersync/common as a type) and an implementation detail (it's an abstract class only meant to be extended from our SDKs). This makes it very easy to leak implementation details into the interface, so this introduces a split:

  1. In @powersync/common, this introduces CommonPowerSyncDatabase: A TypeScript interface containing public members from the old AbstractPowerSyncDatabase class. When writing APIs that need to work across SDKs (attachments, React hooks, ...), this is the type to use.
  2. In @powersync/shared-internals, BasePowerSyncDatabase implements that interface, and our existing SDKs continue to extend that class.

There is a crucial detail here: We can't have an export class PowerSyncDatabase extends BasePowerSyncDatabase anymore, as that would leak everything defined on BasePowerSyncDatabase into the implicit interface for PowerSyncDatabase. So, we make the actual implementation class private and only export the constructor, which is declared to return a CommonPowerSyncDatabase.

SyncStatus

The sync status was a mix of public and private fields, with e.g. sync streams being derived from core extension data structures only. I don't want to keep those structures in @powersync/common because they're an implementation detail, so this restructures SyncStatus into a public interface and an internal implementation (in @powersync/shared-internals). A similar transformation is applied to some CRUD classes.

@changeset-bot

changeset-bot Bot commented Jun 15, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 98c6f74

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

This PR includes changesets to release 11 packages
Name Type
@powersync/react-native Major
@powersync/web Major
@powersync/capacitor Major
@powersync/common Minor
@powersync/tauri-plugin Minor
@powersync/node Minor
@powersync/nuxt Major
@powersync/vue Minor
@powersync/tanstack-react-query Patch
@powersync/diagnostics-app Patch
@powersync/op-sqlite 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

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.

1 participant