Skip to content

feat(plugins): add replication plugin for external database sync (#72) - #339

Open
almagas wants to merge 1 commit into
outerbase:mainfrom
granbellllc-png:feat/external-source-replication-plugin-72
Open

almagas wants to merge 1 commit into
outerbase:mainfrom
granbellllc-png:feat/external-source-replication-plugin-72

Conversation

@almagas

@almagas almagas commented Nov 10, 2026

Copy link
Copy Markdown

Description

Resolves #72

This PR introduces the Replication Plugin (starbasedb:replication) for StarbaseDB, providing pull-based data synchronization from external data sources (e.g. Supabase/PostgreSQL, MySQL) directly into the internal Durable Object SQLite instance. This enables StarbaseDB instances to act as high-speed, close-to-the-edge read replicas of central databases.


Key Capabilities

  1. Incremental Cursor-Based Pull:

    • Supports tracking progress with cursorColumn (e.g., id, updated_at, timestamp).
    • Syncs only new or modified records (WHERE cursorColumn > previousCursor ORDER BY cursorColumn ASC LIMIT batchSize).
    • Supports forceFull mode to bypass cursors when a full re-sync is needed.
  2. Idempotent Upserts:

    • Applies INSERT OR REPLACE INTO keyed on primaryKey (defaults to id), preventing duplicates and handling updates seamlessly.
  3. Schema-Aware Auto Table Provisioning:

    • Automatically provisions destination tables in SQLite on first sync with proper type mapping (INTEGER, REAL, TEXT) and PRIMARY KEY.
    • Handles schema-qualified names (e.g. public.users replicates cleanly into target table users).
    • Escapes SQL identifiers to support reserved keywords and special characters.
  4. State Persistence & Observability:

    • Tracks replication metadata in SQLite table _starbase_replication_state:
      • table_name: Primary key
      • cursor_value: Last processed cursor
      • last_sync_at: Epoch timestamp of last successful sync
      • total_rows_synced: Cumulative sync counter
      • status: 'idle' | 'syncing' | 'synced' | 'error'
      • last_error: Diagnostic message on failures
  5. Concurrency Lock Guard:

    • In-flight table lock prevents overlapping sync executions on the same table.
  6. REST API Interface (/replication/*):

    • GET /replication/status: Reports sync states, table count, and active synchronizations.
    • POST /replication/sync: Triggers immediate synchronization for a single table or all configured tables.
    • POST /replication/configure: Dynamically registers new table configurations at runtime.
    • POST /replication/reset: Resets replication state and cursors.
  7. Scheduled Alarm / Cron Integration:

    • Exposes syncAll() and handleCron() for invocation via Cloudflare Worker scheduled events or CronPlugin.

Testing & Verification

  • Added comprehensive Vitest suite in plugins/replication/index.test.ts (17 tests covering initialization, REST routes, incremental cursors, lock guards, error states, and cron handling).
  • All 172 tests in the repository pass with 0 failures:
    Test Files  20 passed (20)
         Tests  172 passed (172)
    

/claim #72

…erbase#72)

- Implement ReplicationPlugin extending StarbasePlugin
- Support pull-based synchronization from external data sources (Postgres, Supabase, MySQL) to internal Durable Object SQLite
- Cursor tracking via configurable cursorColumn (id, updated_at, sequence) for incremental sync
- Idempotent upserts with INSERT OR REPLACE INTO keyed by primaryKey
- Schema-aware auto-provisioning of destination tables with type inference and identifier escaping
- Concurrency lock guard per table to prevent overlapping sync tasks
- REST API under /replication (GET /status, POST /sync, POST /configure, POST /reset)
- Cron/Alarm integration support via handleCron() and syncAll()
- Comprehensive Vitest unit & integration test coverage (17/17 tests passing)
- Complete technical documentation in README.md and meta.json
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.

Replicate data from external source to internal source with a Plugin

1 participant