Change subscriptions & sync

These examples mirror the Change subscriptions & sync section in Storion Studio’s documentation, showing how to keep UI and multiple contexts in sync without polling.

Overview

The Storion engine that powers Storion Studio supports change subscriptions and an optional cross-context hook. In your own app, you can subscribe to table or row changes so multiple components stay in sync when data is updated—without polling.

Subscribe to table changes

Use db.subscribe to listen to changes at different scopes:

Example: subscribe to all changes in a table

import { createDatabase } from '@storion/storion';

const db = await createDatabase({ name: 'myapp', storage: 'localStorage' });

// Subscribe to all changes in the "todos" table
const unsubscribe = db.subscribe('todos', (event) => {
  console.log(event.type, event.row); // 'insert' | 'update' | 'delete' | 'tableCreated' | 'tableDeleted'
  // Refresh your UI or state here
});

// later:
unsubscribe();

Change event shape

type StorionChangeEvent = {
  type: 'insert' | 'update' | 'delete' | 'tableCreated' | 'tableDeleted';
  dbName: string;
  tableName: string;
  row?: any;          // inserted/updated row (current state)
  rowId?: number;     // id of the row (for update/delete)
  previousRow?: any;  // for update/delete, the row before the change
};

Cross-context sync (extension ↔ webapp)

For advanced setups, Storion can act as the source of truth in one context (for example, a Chrome extension) and stream change events to another context (for example, a webapp) over a custom transport.

The library provides db.setChangeBroadcaster on the producer side and createChangeListener on the receiver side.

Producer: broadcast changes with db.setChangeBroadcaster

// Producer side (e.g. extension popup/background)
db.setChangeBroadcaster({
  broadcastChange(event) {
    window.postMessage({ source: 'storion-change', payload: event }, '*');
  }
});

Consumer: receive changes with createChangeListener

import { createChangeListener } from '@storion/storion';

const transport = {
  onMessage(handler) {
    function listener(ev) {
      if (!ev.data || ev.data.source !== 'storion-change') return;
      handler(ev.data.payload);
    }
    window.addEventListener('message', listener);
    return () => window.removeEventListener('message', listener);
  }
};

const stop = createChangeListener(transport, (event) => {
  console.log('Received change from another context:', event);
  // e.g. refetch data or update local UI state
});

This wiring is optional: Storion works offline by default. Use cross-context sync when you want a separate admin UI (such as Storion Studio) to drive live changes in your app.