Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | 10x 10x 10x 10x 14x 14x 3x 1x 1x 6x 1x 5x 4x 4x 4x 2x 2x 1x 1x 5x | // Connection status reactive store using Svelte 5 runes.
// Tracks the PowerSync connection state: offline → syncing → online.
type ConnectionStatus = 'online' | 'syncing' | 'offline';
type StatusListener = (status: ConnectionStatus) => void;
// Internal subscriber list (for programmatic subscription outside Svelte components)
// Using plain Set, not SvelteSet — this is a module-level listener registry, not reactive UI state.
// eslint-disable-next-line svelte/prefer-svelte-reactivity
const listeners = new Set<StatusListener>();
// Reactive state object — readable from anywhere, updated via setConnectionStatus
export const connectionStatus = {
// Svelte 5 $state cannot be exported directly as a top-level rune
// outside a .svelte file. We expose a plain object and use a module-level
// variable with a getter/setter pattern that consumers can $state-wrap locally.
get value(): ConnectionStatus {
return _status;
},
};
let _status: ConnectionStatus = 'offline';
/**
* Update the connection status. Called by the PowerSync status subscription
* in the application layout and by tests.
*/
export function setConnectionStatus(status: ConnectionStatus): void {
_status = status;
for (const listener of listeners) {
listener(status);
}
}
/**
* Subscribe to connection status changes.
* Returns an unsubscribe function.
*
* Use inside Svelte components via $effect:
* $effect(() => {
* const unsub = subscribeToStatus((s) => (myStatus = s));
* return unsub;
* });
*/
export function subscribeToStatus(listener: StatusListener): () => void {
listeners.add(listener);
return () => listeners.delete(listener);
}
/**
* Wire up PowerSync's built-in status observable to our reactive store.
* Call this once after the database is connected (e.g. in the root layout).
*
* Uses the real PowerSync SDK API: `db.registerListener({ statusChanged })`.
* The `statusChanged` callback receives a `SyncStatus` object with:
* - `connected: boolean`
* - `dataFlowStatus.downloading: boolean`
* - `dataFlowStatus.uploading: boolean`
*
* @param db - The PowerSyncDatabase instance (or any object with `registerListener`)
* @returns A cleanup function to unregister the listener
*/
export function connectStatusToDB(db: {
registerListener?: (listener: {
statusChanged?: (status: {
connected: boolean;
dataFlowStatus: { downloading?: boolean; uploading?: boolean };
}) => void;
}) => () => void;
}): () => void {
if (!db.registerListener) {
return () => {};
}
const unregister = db.registerListener({
statusChanged(status) {
const { connected } = status;
const { downloading, uploading } = status.dataFlowStatus;
if (connected && (downloading || uploading)) {
setConnectionStatus('syncing');
} else if (connected) {
setConnectionStatus('online');
} else {
setConnectionStatus('offline');
}
},
});
return unregister;
}
|