### Quick Start: Dexie Sync Kit Setup Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/README.md Demonstrates the basic setup for Dexie Sync Kit, including database definition, route configuration, and starting the sync engine. ```typescript import Dexie from 'dexie'; import { startSync, defineRoutes } from '@dexie-kit/sync'; // 1. Define your database const db = new Dexie('myapp'); db.version(1).stores({ posts: '++id, title, updatedAt', comments: '++id, postId, content, updatedAt', }); // 2. Configure sync routes const routes = defineRoutes({ posts: { push: { create: { method: 'POST', url: '/api/posts', body: (item) => item, }, update: { method: 'PUT', url: (item) => `/api/posts/${item.id}`, body: (item) => item, }, delete: { method: 'DELETE', url: (item) => `/api/posts/${item.id}`, }, }, pull: { method: 'GET', url: '/api/posts', query: async (ctx) => ({ updated_after: await ctx.getCheckpoint('pull:posts') || 0, }), mapResponse: (response) => response.data, onComplete: async (response, ctx) => { const latest = Math.max( ...response.data.map(p => new Date(p.updatedAt).getTime()) ); await ctx.setCheckpoint('pull:posts', latest); }, }, }, }); // 3. Start sync const syncEngine = startSync(db, { baseUrl: 'https://api.example.com', auth: { getHeaders: async () => ({ 'Authorization': `Bearer ${await getToken()}`, }), }, routes, conflicts: { policy: 'server-wins', }, sync: { interval: 30000, // Sync every 30 seconds onOnline: true, // Sync when coming online }, }); // 4. Use your app normally await db.posts.add({ title: 'Hello World' }); // Sync happens automatically! await syncEngine.start(); ``` -------------------------------- ### Dexie Sync Kit Setup and Usage Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/.github-summary.md Demonstrates how to initialize and start the Dexie Sync Kit for offline-first synchronization with a REST API. Includes defining database schema, configuring sync routes, and handling data synchronization. ```typescript import Dexie from 'dexie'; import { startSync, defineRoutes } from '@dexie-kit/sync'; const db = new Dexie('myapp'); db.version(1).stores({ posts: '++id, title, updatedAt', }); const syncEngine = startSync(db, { baseUrl: 'https://api.example.com', auth: { getHeaders: async () => ({ Authorization: `Bearer ${token}` }) }, routes: defineRoutes({ posts: { push: { create: { method: 'POST', url: '/api/posts' }, update: { method: 'PUT', url: (item) => `/api/posts/${item.id}` }, delete: { method: 'DELETE', url: (item) => `/api/posts/${item.id}` }, }, pull: { method: 'GET', url: '/api/posts', query: async (ctx) => ({ updated_after: await ctx.getCheckpoint('pull:posts') || 0 }), mapResponse: (res) => res.data, onComplete: async (res, ctx) => { const latest = Math.max(...res.data.map(p => new Date(p.updatedAt).getTime())); await ctx.setCheckpoint('pull:posts', latest); }, }, }, }), conflicts: { policy: 'server-wins' }, sync: { interval: 30000, onOnline: true }, }); await syncEngine.start(); // Use Dexie normally - sync happens automatically! await db.posts.add({ title: 'Hello World', updatedAt: new Date() }); ``` -------------------------------- ### Install Dependencies Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/CONTRIBUTING.md Install all necessary project dependencies using npm. ```bash npm install ``` -------------------------------- ### Install Dexie Sync Kit and Dexie Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/README.md Install the necessary packages for Dexie Sync Kit and Dexie.js using npm. ```bash npm install @dexie-kit/sync dexie ``` -------------------------------- ### Example Commit Message Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/CONTRIBUTING.md Follow this format for clear and concise commit messages, starting with a verb and keeping the subject line brief. ```git Add support for custom pagination strategies - Implement cursor-based pagination - Add offset-based pagination - Update documentation with examples ``` -------------------------------- ### startSync Function Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/README.md Initializes and starts the synchronization engine for a given Dexie database instance with a specified configuration. ```APIDOC ## startSync(db, config) ### Description Starts sync for a Dexie database. ### Parameters - `db` (Dexie) - Your Dexie database instance - `config` (SyncConfig) - Sync configuration ### Returns `SyncEngine` ``` -------------------------------- ### Example Workflow - Commit and Push Changes Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/PUBLISHING.md After making changes and creating a changeset, commit them and push to your feature branch. ```bash git add . git commit -m "feat: add custom retry strategies" git push origin feature/my-feature ``` -------------------------------- ### Backend API Endpoints for Dexie Sync Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/examples/basic-usage.md These JavaScript examples illustrate the required backend API endpoints for handling GET, POST, PUT, and DELETE requests for posts, as expected by the Dexie Sync Kit configuration. They include logic for querying based on update time, creating, updating with version checks, and deleting resources. ```javascript // GET /api/posts?updated_after=1234567890&limit=100 app.get('/api/posts', async (req, res) => { const { updated_after = '0', limit = '100' } = req.query; const posts = await db.posts.findMany({ where: { updatedAt: { gt: new Date(Number(updated_after)) } }, orderBy: { updatedAt: 'asc' }, take: Number(limit) }); res.json({ data: posts }); }); // POST /api/posts app.post('/api/posts', async (req, res) => { const post = await db.posts.create({ data: { ...req.body, updatedAt: new Date(), version: 1 } }); res.status(201).json(post); }); // PUT /api/posts/:id app.put('/api/posts/:id', async (req, res) => { const { expectedVersion, ...data } = req.body; const current = await db.posts.findUnique({ where: { id: req.params.id } }); if (!current) { return res.status(404).json({ error: 'Not found' }); } // Check version for conflict detection if (expectedVersion && current.version !== expectedVersion) { return res.status(409).json({ error: 'Version conflict', serverVersion: current.version, serverData: current }); } const updated = await db.posts.update({ where: { id: req.params.id }, data: { ...data, version: current.version + 1, updatedAt: new Date() } }); res.json(updated); }); // DELETE /api/posts/:id app.delete('/api/posts/:id', async (req, res) => { await db.posts.delete({ where: { id: req.params.id } }); res.status(204).send(); }); ``` -------------------------------- ### Dexie Sync Kit Setup and Configuration Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/examples/basic-usage.md This snippet shows how to define your Dexie database, configure API routes for push and pull operations, set up authentication, handle conflicts, and initialize the sync engine. It's used for setting up the core synchronization logic. ```typescript import Dexie from 'dexie'; import { startSync, defineRoutes } from '@dexie-kit/sync'; // 1. Define your database const db = new Dexie('myapp'); db.version(1).stores({ posts: '++id, title, content, updatedAt, version', comments: '++id, postId, content, updatedAt', }); // 2. Configure routes const routes = defineRoutes({ posts: { // Push configuration (local -> server) push: { create: { method: 'POST', url: '/api/posts', body: (item) => ({ title: item.title, content: item.content, updatedAt: item.updatedAt, }), }, update: { method: 'PUT', url: (item) => `/api/posts/${item.id}`, body: (item) => ({ title: item.title, content: item.content, updatedAt: item.updatedAt, version: item.version, }), }, delete: { method: 'DELETE', url: (item) => `/api/posts/${item.id}`, }, }, // Pull configuration (server -> local) pull: { method: 'GET', url: '/api/posts', query: async (ctx) => { const lastSync = await ctx.getCheckpoint('pull:posts'); return { updated_after: lastSync || 0, limit: 100, }; }, mapResponse: (response) => response.data, onComplete: async (response, ctx) => { if (response.data.length > 0) { const latest = Math.max( ...response.data.map((p: any) => new Date(p.updatedAt).getTime()) ); await ctx.setCheckpoint('pull:posts', latest); } }, }, }, }); // 3. Start sync const syncEngine = startSync(db, { baseUrl: 'https://api.example.com', auth: { getHeaders: async () => { // Get your auth token const token = localStorage.getItem('auth_token'); return { 'Authorization': `Bearer ${token}`, }; }, onAuthError: async (error) => { if (error.status === 401) { // Refresh token or redirect to login console.log('Auth error, please login again'); } }, }, routes, conflicts: { policy: 'server-wins', // or 'client-wins', 'lww', 'custom' }, sync: { interval: 30000, // Sync every 30 seconds onOnline: true, // Sync when coming online }, }); // 4. Start the sync engine await syncEngine.start(); // 5. Use your app normally await db.posts.add({ title: 'My First Post', content: 'Hello World!', updatedAt: new Date().toISOString(), version: 1, }); // Changes are automatically queued and synced! // Listen to events syncEngine.on('sync-complete', (result) => { console.log('Sync complete:', result); console.log(`Pushed: ${result.push.pushed}, Pulled: ${result.pull.pulled}`); }); syncEngine.on('sync-error', (error) => { console.error('Sync failed:', error); }); // Manually trigger sync await syncEngine.sync(); // Check status const status = syncEngine.getStatus(); console.log('Status:', status); // Get metrics const metrics = await syncEngine.getMetrics(); console.log('Queue depth:', metrics.queue.depth); console.log('Last sync:', new Date(metrics.sync.lastSyncCompleted)); ``` -------------------------------- ### Express.js Backend Example for Posts API Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/README.md This example demonstrates how to implement CRUD endpoints for a 'posts' resource using Express.js and Dexie.js, including timestamp filtering for delta queries. ```typescript app.get('/api/posts', async (req, res) => { const { updated_after = '0' } = req.query; const posts = await db.posts.findMany({ where: { updatedAt: { gt: new Date(Number(updated_after)) } }, orderBy: { updatedAt: 'asc' } }); res.json({ data: posts }); }); app.post('/api/posts', async (req, res) => { const post = await db.posts.create({ data: { ...req.body, updatedAt: new Date() } }); res.status(201).json(post); }); app.put('/api/posts/:id', async (req, res) => { const post = await db.posts.update({ where: { id: req.params.id }, data: { ...req.body, updatedAt: new Date() } }); res.json(post); }); app.delete('/api/posts/:id', async (req, res) => { await db.posts.delete({ where: { id: req.params.id } }); res.status(204).send(); }); ``` -------------------------------- ### Create a New Feature Branch Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/CONTRIBUTING.md Start a new branch for your feature development, following a consistent naming convention. ```bash git checkout -b feature/your-feature-name ``` -------------------------------- ### SyncEngine Lifecycle Methods Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/README.md Control the lifecycle of the sync engine. Use these methods to start, stop, pause, or resume synchronization. ```typescript // Lifecycle await syncEngine.start(); await syncEngine.stop(); await syncEngine.pause(); await syncEngine.resume(); ``` -------------------------------- ### Create a Changeset Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/PUBLISHING.md Run this command to initiate the creation of a changeset file, which prompts for version type and change summary. ```bash npm run changeset ``` -------------------------------- ### Build the Project Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/CONTRIBUTING.md Compile the project's code into distributable artifacts. ```bash npm run build ``` -------------------------------- ### Manual Publishing - Build and Publish Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/PUBLISHING.md Execute this command to manually build the package and publish it to npm. This is a fallback for automated workflows. ```bash npm run release ``` -------------------------------- ### Clone the Repository Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/CONTRIBUTING.md Clone your forked repository to your local machine and navigate into the project directory. ```bash git clone https://github.com/YOUR_USERNAME/dexie-kit-sync.git cd dexie-kit-sync ``` -------------------------------- ### Run Tests Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/CONTRIBUTING.md Execute the project's test suite to ensure code quality and functionality. ```bash npm test ``` -------------------------------- ### Full Dexie Sync Kit Configuration Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/README.md This snippet shows a comprehensive configuration for Dexie Sync Kit, covering sync intervals, authentication, push/pull strategies, conflict resolution, error handling, and observability. ```typescript startSync(db, { baseUrl: 'https://api.example.com', routes: { // ... route config }, auth: { getHeaders: async () => ({ 'Authorization': `Bearer ${token}`, }), onAuthError: async (error) => { if (error.status === 401) { await refreshToken(); } }, maxAuthRetries: 3, }, sync: { interval: 30000, onOnline: true, onVisibilityChange: true, push: { batchSize: 10, concurrency: 3, }, pull: { pageSize: 100, maxPages: 10, }, }, conflicts: { policy: 'lww', onConflict: async (conflict) => { // Custom resolution return conflict.remote; }, }, errors: { maxRetries: 5, retryDelay: (attempt) => Math.min(1000 * Math.pow(2, attempt), 60000), }, observability: { enabled: true, metricsInterval: 30000, onMetrics: (metrics) => { console.log('Metrics:', metrics); }, }, }); ``` -------------------------------- ### SyncEngine Methods Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/README.md Provides methods to control the lifecycle, trigger manual sync operations, and query the status of the synchronization engine. ```APIDOC ## SyncEngine Methods ### Lifecycle - `await syncEngine.start()` - `await syncEngine.stop()` - `await syncEngine.pause()` - `await syncEngine.resume()` ### Manual Sync - `const result = await syncEngine.sync()` - `await syncEngine.push()` - `await syncEngine.pull()` - `await syncEngine.syncTable('posts')` ### Status - `const status = syncEngine.getStatus()` - `const isOnline = syncEngine.isOnline()` - `const isSyncing = syncEngine.isSyncing()` - `const depth = await syncEngine.getQueueDepth()` ### Events - `syncEngine.on('sync-complete', (result) => { ... });` ### Advanced - `const health = await syncEngine.healthCheck()` - `const deadLetters = await syncEngine.getDeadLetters()` - `await syncEngine.retryDeadLetter(id)` ``` -------------------------------- ### Manual Publishing - Update Version and Changelog Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/PUBLISHING.md Use this command for manual updates to the package version and changelog, typically in emergency situations. ```bash npm run version ``` -------------------------------- ### SyncEngine Status and Information Methods Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/README.md Retrieve the current status and state of the sync engine. Useful for monitoring and debugging. ```typescript // Status const status = syncEngine.getStatus(); const isOnline = syncEngine.isOnline(); const isSyncing = syncEngine.isSyncing(); const depth = await syncEngine.getQueueDepth(); ``` -------------------------------- ### Push Changes to Fork Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/CONTRIBUTING.md Push your feature branch to your forked repository on GitHub. ```bash git push origin feature/your-feature-name ``` -------------------------------- ### SyncEngine Manual Sync Methods Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/README.md Manually trigger synchronization processes. These methods allow for on-demand pushing, pulling, or syncing specific tables. ```typescript // Manual sync const result = await syncEngine.sync(); await syncEngine.push(); await syncEngine.pull(); await syncEngine.syncTable('posts'); ``` -------------------------------- ### Lint Code Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/CONTRIBUTING.md Check the code for style and potential errors using ESLint. ```bash npm run lint ``` -------------------------------- ### Commit Changes Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/CONTRIBUTING.md Commit your changes with a descriptive message summarizing the modifications. ```bash git commit -m "Description of your changes" ``` -------------------------------- ### SyncEngine Event Handling Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/README.md Subscribe to various sync events to react to different stages of the synchronization process. This allows for custom logging or UI updates. ```typescript // Events syncEngine.on('sync-complete', (result) => { console.log('Synced!', result); }); ``` -------------------------------- ### SyncEngine Advanced Methods Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/README.md Access advanced functionalities like health checks, managing dead-lettered items, and retrying failed operations. ```typescript // Advanced const health = await syncEngine.healthCheck(); const deadLetters = await syncEngine.getDeadLetters(); await syncEngine.retryDeadLetter(id); ``` -------------------------------- ### Typecheck Code Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/CONTRIBUTING.md Verify the TypeScript types throughout the project. ```bash npm run typecheck ``` -------------------------------- ### Sync Events Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/README.md Listens for various events emitted by the synchronization engine to track sync progress, errors, and network status changes. ```APIDOC ## Events - `sync-start` - Sync started - `sync-complete` - Sync completed - `sync-error` - Sync failed - `push-start` - Push started - `push-complete` - Push completed - `push-error` - Push failed - `pull-start` - Pull started - `pull-complete` - Pull completed - `pull-error` - Pull failed - `conflict` - Conflict detected - `online` - Network online - `offline` - Network offline - `metrics` - Metrics update ``` -------------------------------- ### Controlling Table-Specific Synchronization Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/examples/basic-usage.md Manage synchronization at the table level by pausing, resuming, or syncing specific tables. ```typescript // Pause specific table await syncEngine.pauseTable('posts'); // Resume specific table await syncEngine.resumeTable('posts'); // Sync specific table only await syncEngine.syncTable('posts'); ``` -------------------------------- ### Custom Conflict Resolution Policy Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/examples/basic-usage.md Implement a custom conflict resolution policy by defining the `onConflict` function. This allows for specific merge logic when conflicts arise. ```typescript startSync(db, { // ... other config conflicts: { policy: 'custom', onConflict: async (conflict) => { const { table, key, local, remote } = conflict; // Custom merge logic return { ...remote, title: local.title, // Keep local title content: remote.content // Use server content }; } } }); ``` -------------------------------- ### Monitoring Sync Health and Dead Letters Source: https://github.com/abdussamadbello/dexie-sync-kit/blob/main/examples/basic-usage.md Check the health of the synchronization process and retrieve items that failed to sync. Failed items can be retried. ```typescript // Health check const health = await syncEngine.healthCheck(); if (!health.healthy) { console.warn('Sync issues:', health.issues); } // Dead letter queue const deadLetters = await syncEngine.getDeadLetters(); console.log('Failed items:', deadLetters); // Retry failed items for (const item of deadLetters) { await syncEngine.retryDeadLetter(item.id); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.