Offline queue
Pass offline: true when constructing the client and the SDK exposes cstar.offlineQueue. Failed mutations buffer there and auto-flush when the network
comes back. Optional localStorage persistence survives page reloads.
Enable
import { CStarClient } from '@cstar.help/js';
const cstar = new CStarClient({
apiKey: 'sk_live_...',
teamId: 'your-team-id',
offline: true // Memory storage, auto-flush on
});
// Or pass options:
const persistedClient = new CStarClient({
apiKey: 'sk_live_...',
teamId: 'your-team-id',
offline: { storage: 'localStorage' } // Survives page reloads in the browser
}); Without the offline flag, cstar.offlineQueue is null.
With it, a write (POST, PATCH, PUT or DELETE) that can't reach the network is queued and rejects
with a CStarError whose code is queued_offline and whose queueId names the queued item. Each queued write
carries an idempotency key from its first try, so a replay never makes a second record.
try {
await cstar.tickets.create({ title: 'Bug report', customerId });
} catch (err) {
if (err.code === 'queued_offline') showToast('Saved. It sends when you are back online.');
else throw err;
} Enqueue manually
Most callers won't touch this. The SDK enqueues for you when a mutation fails to reach the network. But you can prime the queue yourself if you know you're working offline:
const id = cstar.offlineQueue.enqueue('POST', '/tickets', {
title: 'Bug report',
priority: 'high'
});
// Returns the queue item ID for later inspection Flush
Auto-flush kicks in on the browser's online event. Trigger manually if needed:
const results = await cstar.offlineQueue.flush();
for (const r of results) {
if (r.success) log.info('replayed', r.id);
else log.error('replay failed', r.id, r.error);
} Control auto-flush
// Pause replays (useful while testing)
cstar.offlineQueue.disableAutoFlush();
// Re-enable
cstar.offlineQueue.enableAutoFlush();
// Drop everything (e.g. on logout)
cstar.offlineQueue.clear(); Pair with idempotency keys
Replays are at-least-once. If a queued POST succeeded server-side but the response was lost, the
replay creates a duplicate row unless you sent an idempotencyKey on the original call. Pass
one on every mutation that goes through the queue.