Skip to content

Latest commit

 

History

History
345 lines (261 loc) · 8.17 KB

File metadata and controls

345 lines (261 loc) · 8.17 KB

Offline Queue Engine 🚀

npm version License: MIT

Reliable offline-first request queue for web & Node.js apps

🎮 Live Interactive Demo | 📦 npm Package | 💻 Demo Source

Queue HTTP requests when offline and automatically sync them when the network reconnects. Perfect for PWAs, mobile apps, fintech, delivery apps, and any application requiring reliable data persistence.

✨ Features

  • 🔄 Automatic Sync - Detects network changes and syncs queued requests
  • 📦 Persistent Storage - IndexedDB (50MB+), LocalStorage, or Memory adapters
  • 🎯 Priority Queue - High, normal, low priority levels
  • ♻️ Smart Retry Logic - Exponential backoff with configurable max retries
  • 🪝 Lifecycle Hooks - onSuccess, onFailure, onRetry callbacks
  • 🌐 Universal - Works in browser and Node.js environments
  • 🎨 Framework Agnostic - Use with React, Vue, Angular, or vanilla JS
  • 📘 TypeScript First - Full type definitions included
  • 🪶 Lightweight - Minimal dependencies

📦 Installation

npm install offline-queue-engine

🚀 Quick Start

Try it live: Interactive Demo

import { OfflineQueueEngine } from 'offline-queue-engine';

// Create queue instance
const queue = new OfflineQueueEngine({
  hooks: {
    onSuccess: (item) => console.log('✅ Synced:', item),
    onFailure: (item, error) => console.error('❌ Failed:', error),
    onRetry: (item, count) => console.log('🔁 Retry attempt:', count)
  }
});

// Add requests to queue
await queue.add({
  url: '/api/orders',
  method: 'POST',
  body: { item: 'Pizza', quantity: 2 },
  priority: 'high'
});

That's it! Requests are automatically:

  • ✅ Persisted to IndexedDB
  • ✅ Sent when online
  • ✅ Retried on failure
  • ✅ Synced on reconnect

📖 API Reference

Constructor

new OfflineQueueEngine(config?: QueueConfig)

Options:

Option Type Default Description
storage StorageAdapter IndexedDBStore Storage adapter (IndexedDB, LocalStorage, Memory)
hooks Hooks {} Lifecycle callbacks
autoSync boolean true Auto-sync on network reconnect
maxRetries number 5 Maximum retry attempts

Methods

add(request: CreateRequestInput): Promise<void>

Add a request to the queue.

await queue.add({
  url: '/api/save',
  method: 'POST',
  body: { name: 'John' },
  headers: { 'Authorization': 'Bearer token' },
  priority: 'high' // 'high' | 'normal' | 'low'
});

sync(): Promise<void>

Manually trigger queue processing.

await queue.sync();

size(): number

Get current queue size.

const pending = queue.size();
console.log(`${pending} requests pending`);

clear(): Promise<void>

Clear all queued requests.

await queue.clear();

isOnline(): boolean

Check network status.

if (queue.isOnline()) {
  console.log('Connected');
}

destroy(): void

Cleanup and remove event listeners.

queue.destroy();

🎯 Use Cases

Payment Apps

// Ensure payment requests are never lost
await queue.add({
  url: '/api/payments',
  method: 'POST',
  body: { amount: 99.99, userId: '123' },
  priority: 'high'
});

Form Submissions

// Save form data offline
await queue.add({
  url: '/api/leads',
  method: 'POST',
  body: formData,
  priority: 'normal'
});

Chat Applications

// Queue messages when offline
await queue.add({
  url: '/api/messages',
  method: 'POST',
  body: { text: 'Hello!', chatId: '456' },
  priority: 'high'
});

🔧 Advanced Configuration

Custom Storage Adapter

import { OfflineQueueEngine, LocalStorageStore } from 'offline-queue-engine';

const queue = new OfflineQueueEngine({
  storage: new LocalStorageStore()
});

All Lifecycle Hooks

const queue = new OfflineQueueEngine({
  hooks: {
    onSuccess: (item) => {
      console.log('Request succeeded:', item.url);
      // Update UI, show notification, etc.
    },
    onFailure: (item, error) => {
      console.error('Request failed permanently:', error);
      // Log to error tracking service
    },
    onRetry: (item, retryCount) => {
      console.log(`Retry ${retryCount} for ${item.url}`);
      // Show retry indicator in UI
    }
  },
  maxRetries: 3,
  autoSync: true
});

Custom Retry Strategy

import { shouldRetry, calculateBackoff } from 'offline-queue-engine';

// Check if request should retry
const retry = shouldRetry(500, 2, 5); // status, retryCount, maxRetries

// Calculate exponential backoff
const delay = calculateBackoff(2, 1000); // retryCount, baseDelay (ms)
// Returns: 4000ms (1s * 2^2)

🌐 Framework Examples

React

import { useEffect, useState } from 'react';
import { OfflineQueueEngine } from 'offline-queue-engine';

function App() {
  const [queue] = useState(() => new OfflineQueueEngine({
    hooks: {
      onSuccess: () => console.log('Synced!')
    }
  }));

  const handleSubmit = async (data) => {
    await queue.add({
      url: '/api/data',
      method: 'POST',
      body: data
    });
  };

  useEffect(() => {
    return () => queue.destroy();
  }, []);

  return <form onSubmit={handleSubmit}>...</form>;
}

Vue

import { OfflineQueueEngine } from 'offline-queue-engine';

export default {
  data() {
    return {
      queue: new OfflineQueueEngine()
    };
  },
  methods: {
    async submitForm(data) {
      await this.queue.add({
        url: '/api/data',
        method: 'POST',
        body: data
      });
    }
  },
  beforeUnmount() {
    this.queue.destroy();
  }
};

🧪 Testing

For testing, use the MemoryStore adapter:

import { OfflineQueueEngine, MemoryStore } from 'offline-queue-engine';

const queue = new OfflineQueueEngine({
  storage: new MemoryStore() // Non-persistent, fast
});

📊 Storage Adapters Comparison

Adapter Capacity Persistent Async Best For
IndexedDBStore 50MB+ ✅ Yes ✅ Yes Production apps (default)
LocalStorageStore ~5-10MB ✅ Yes ❌ No Simple apps, small queues
MemoryStore RAM only ❌ No ✅ Yes Testing, development

🔒 Retry Strategy

The engine uses smart retry logic:

  • Retries: Network errors, 5xx server errors
  • No retry: 4xx client errors (bad request, auth, etc.)
  • 📈 Exponential backoff: 1s → 2s → 4s → 8s → 16s (max 30s)
  • 🛑 Max retries: 5 attempts by default (configurable)

🌟 Why This Library?

Most offline queue solutions are:

  • ❌ Framework-specific
  • ❌ Heavyweight
  • ❌ Complex to configure
  • ❌ Poor TypeScript support

offline-queue-engine is:

  • ✅ Universal (browser + Node.js)
  • ✅ Lightweight (~5KB gzipped)
  • ✅ Simple API
  • ✅ Full TypeScript support
  • ✅ Production-tested

📝 License

MIT © Sahil Laskar

🤝 Contributing

Contributions welcome! Please open an issue or PR.

📚 Live Demo & Examples

🎮 Try the Interactive Demo

The live demo includes 6 comprehensive examples:

  • 🚀 Basic Usage - Simple queuing and offline handling
  • 🎯 Priority Queue - High/Normal/Low priority demonstration
  • ♻️ Retry Logic - Smart retry with exponential backoff
  • 💾 Storage Adapters - Memory/LocalStorage/IndexedDB comparison
  • 🪝 Lifecycle Hooks - Event tracking and callbacks
  • Advanced Features - Batch operations, custom headers, manual sync

Demo Source Code: github.com/Sakil9051/demo-offline-queue


Built with ❤️ for offline-first applications