Skip to Content

StoreOptions

Advanced configuration options for the Store.

Import

import type { StoreOptions } from '@gluonic/client'

Type Definition

Complete interface from implementation:

export type StoreOptions = { // Debugging debug?: boolean // Authentication onUnauthenticated?: () => void | Promise<void> // Transformation transformByModel?: Record<string, (op: 'i'|'u'|'d', payload: Record<string, any>) => Record<string, any>> // Sync adapters downsync?: DownsyncAdapter realtime?: RealtimeAdapter // Instrumentation callbacks logger?: { debug?: (...a: any[]) => void info?: (...a: any[]) => void warn?: (...a: any[]) => void error?: (...a: any[]) => void } onFrameApplied?: (info: { count: number, minSid?: number, maxSid?: number, ms: number }) => void onReconnect?: (info: { attempt: number, backoffMs: number }) => void onQueueResult?: (info: { id: string, result: 'ok'|'permanent'|'retry' }) => void // Performance applyChunkSize?: number }

Total: 10 configuration options. All are optional - Store works with defaults.


Options Reference

debug

debug?: boolean

Default: false

Description: Enable debug logging to console.

Example:

const client = SyncClient({ server, storage, models, performance: { debug: true // Logs all sync operations } })

onUnauthenticated

onUnauthenticated?: () => void | Promise<void>

Description: Callback when server returns 401/403 (unauthenticated).

Use case: Redirect to login, clear tokens, show auth dialog

Example:

const client = SyncClient({ server, storage, models, auth: { onUnauthenticated: () => { // Clear token localStorage.removeItem('token') // Redirect to login router.push('/login') } } })

transformByModel

transformByModel?: Record<string, ( op: 'i'|'u'|'d', payload: Record<string, any> ) => Record<string, any>>

Description: Transform data before storing in pool (per model type).

Use case: Data normalization, field mapping, computed fields

Example:

const client = SyncClient({ server, storage, models, transformByModel: { task: (op, payload) => { // Add computed field return { ...payload, displayTitle: payload.title?.toUpperCase() } }, user: (op, payload) => { // Normalize email return { ...payload, email: payload.email?.toLowerCase() } } } })

downsync

downsync?: DownsyncAdapter

Description: Custom adapter for delta sync and bootstrap.

Default: HTTP adapter created from server URL

Example:

const client = SyncClient({ server, storage, models, downsync: { fetchDelta: async (since, token, onUnauthenticated) => { // Custom delta sync implementation }, fetchBootstrap: async (token, onUnauthenticated) => { // Custom bootstrap implementation } } })

See: DownsyncAdapter


realtime

realtime?: RealtimeAdapter

Description: Custom adapter for WebSocket real-time updates.

Default: WebSocket adapter created from server URL

Example:

const client = SyncClient({ server, storage, models, realtime: { connect: (token, onFrames, onError, onClose) => { // Custom WebSocket implementation const ws = new WebSocket('wss://custom.com/ws') // ... return { close: () => ws.close() } } } })

See: RealtimeAdapter


logger

logger?: { debug?: (...a: any[]) => void info?: (...a: any[]) => void warn?: (...a: any[]) => void error?: (...a: any[]) => void }

Description: Custom logging functions for sync operations.

Default: No logging (silent)

Example:

import * as Sentry from '@sentry/react' const client = SyncClient({ server, storage, models, logger: { debug: (...args) => console.debug('[Gluonic]', ...args), info: (...args) => console.info('[Gluonic]', ...args), warn: (...args) => console.warn('[Gluonic]', ...args), error: (...args) => { console.error('[Gluonic]', ...args) Sentry.captureException(new Error(args.join(' '))) } } })

onFrameApplied

onFrameApplied?: (info: { count: number minSid?: number maxSid?: number ms: number }) => void

Description: Callback after applying sync frames (for monitoring).

Info object:

  • count - Number of frames applied
  • minSid - Lowest sync ID in batch
  • maxSid - Highest sync ID in batch
  • ms - Time taken to apply (milliseconds)

Example:

const client = SyncClient({ server, storage, models, onFrameApplied: (info) => { console.log(`Applied ${info.count} frames in ${info.ms}ms`) // Track performance analytics.track('sync_frames_applied', { count: info.count, duration_ms: info.ms, sync_range: `${info.minSid}-${info.maxSid}` }) } })

onReconnect

onReconnect?: (info: { attempt: number backoffMs: number }) => void

Description: Callback when WebSocket reconnects (for monitoring).

Info object:

  • attempt - Reconnect attempt number (1, 2, 3…)
  • backoffMs - Backoff delay in milliseconds

Example:

const client = SyncClient({ server, storage, models, onReconnect: (info) => { console.log(`Reconnect attempt ${info.attempt}, waiting ${info.backoffMs}ms`) if (info.attempt > 5) { toast.error('Connection unstable, please check your network') } } })

onQueueResult

onQueueResult?: (info: { id: string result: 'ok'|'permanent'|'retry' }) => void

Description: Callback when transaction queue item is processed.

Info object:

  • id - Transaction ID
  • result - Processing result:
    • 'ok' - Successfully confirmed by server
    • 'permanent' - Permanent failure (won’t retry)
    • 'retry' - Temporary failure (will retry)

Example:

const client = SyncClient({ server, storage, models, onQueueResult: (info) => { if (info.result === 'permanent') { console.error(`Transaction ${info.id} failed permanently`) toast.error('Failed to sync changes') } else if (info.result === 'retry') { console.warn(`Transaction ${info.id} will retry`) } } })

applyChunkSize

applyChunkSize?: number

Default: 100

Description: Number of frames to process in each chunk (for performance).

Use case:

  • Large syncs with thousands of frames
  • Prevents UI blocking
  • Allows UI updates between chunks

Example:

const client = SyncClient({ server, storage, models, performance: { applyChunkSize: 500 // Process 500 frames at a time } })

Performance:

  • Lower value (50): More responsive UI, slower total sync
  • Higher value (1000): Faster total sync, longer UI blocks
  • Default (100): Good balance

Usage

In SyncClient

StoreOptions are passed through SyncClient config:

const client = SyncClient({ server: 'https://api.example.com/sync/v1', storage: DrizzleAdapter({ db }), models: [Task, User], // StoreOptions auth: { onUnauthenticated: () => router.push('/login') }, performance: { debug: true, applyChunkSize: 500 }, downsync: customDownsyncAdapter, realtime: customRealtimeAdapter, logger: customLogger, onFrameApplied: (info) => trackPerformance(info), onReconnect: (info) => handleReconnect(info), onQueueResult: (info) => handleQueueResult(info) })

Complete Example

import { SyncClient } from '@gluonic/client' import { DrizzleAdapter } from '@gluonic/client-drizzle' import * as Sentry from '@sentry/react' const client = SyncClient({ server: 'https://api.example.com/sync/v1', storage: DrizzleAdapter({ db }), models: [Task, User, Project], // Authentication auth: { onUnauthenticated: () => { localStorage.removeItem('token') window.location.href = '/login' } }, // Performance performance: { debug: process.env.NODE_ENV === 'development', applyChunkSize: 500 }, // Logging logger: { error: (...args) => { console.error('[Gluonic]', ...args) Sentry.captureException(new Error(args.join(' '))) }, warn: (...args) => console.warn('[Gluonic]', ...args), info: (...args) => console.info('[Gluonic]', ...args), debug: (...args) => console.debug('[Gluonic]', ...args) }, // Monitoring onFrameApplied: (info) => { analytics.track('sync_frames', { count: info.count, duration_ms: info.ms }) }, onReconnect: (info) => { if (info.attempt > 3) { toast.warning('Connection unstable') } }, onQueueResult: (info) => { if (info.result === 'permanent') { Sentry.captureMessage(`Transaction failed: ${info.id}`) } } })

See Also

Last updated on