Skip to content

High-performance WatermelonDB adapter for AWS Amplify DataStore with JSI support

License

MIT, Unknown licenses found

Licenses found

MIT
LICENSE
Unknown
LICENSE-APACHE
Notifications You must be signed in to change notification settings

anivar/amplify-watermelondb-adapter

Repository files navigation

πŸ‰βš‘ amplify-watermelondb-adapter

npm version npm downloads npm bundle size License: MIT TypeScript Node.js Version React Native Amplify DataStore WatermelonDB GitHub

A WatermelonDB adapter for AWS Amplify DataStore

This adapter integrates WatermelonDB as a storage adapter for AWS Amplify DataStore, providing an alternative to the default SQLite adapter.

🎯 Overview

About AWS Amplify DataStore

AWS Amplify DataStore provides a programming model for leveraging shared and distributed data:

  • πŸ”„ Automatic sync between cloud and local data
  • πŸ” Built-in auth and conflict resolution
  • πŸ“Š GraphQL API integration
  • 🌐 Cross-platform support - Web, React Native, iOS, Android

About WatermelonDB

WatermelonDB is a reactive database framework built for React and React Native applications:

  • 😎 Lazy loading - Records load on demand
  • ⚑ Native SQLite performance with JSI on React Native
  • ✨ Fully reactive - UI updates automatically when data changes
  • πŸ“ˆ Designed for scale - Handles large datasets efficiently

Integration

This adapter allows you to use WatermelonDB as the storage engine for Amplify DataStore:

// Standard DataStore setup
import { DataStore } from '@aws-amplify/datastore';
import { SQLiteAdapter } from '@aws-amplify/datastore-storage-adapter';

DataStore.configure({
  storageAdapter: SQLiteAdapter
});

// With WatermelonDB adapter
import { WatermelonDBAdapter } from 'amplify-watermelondb-adapter';

DataStore.configure({
  storageAdapter: new WatermelonDBAdapter()
});

πŸš€ Platform Support

The adapter automatically selects the optimal storage engine for each platform:

Platform Storage Engine Features
React Native iOS/Android JSI + SQLite Native performance with JSI bridge
Web LokiJS + IndexedDB Browser-optimized with IndexedDB persistence
Node.js better-sqlite3 Server-grade SQLite performance
Fallback In-Memory Development and testing scenarios

πŸ’‘ Use Cases

This adapter is suitable for applications that:

  • πŸ“± Use DataStore for offline-first functionality
  • πŸ“ˆ Work with large datasets or complex queries
  • ⚑ Need reactive UI updates when data changes
  • πŸ”„ Want WatermelonDB's performance benefits
  • πŸ—οΈ Require cross-platform compatibility

πŸ› οΈ Installation

npm install amplify-watermelondb-adapter @nozbe/watermelondb
# or
yarn add amplify-watermelondb-adapter @nozbe/watermelondb

🎯 Quick Start

Zero Configuration Setup

import { configureDataStoreWithWatermelonDB } from 'amplify-watermelondb-adapter';

// That's it! DataStore now uses WatermelonDB
configureDataStoreWithWatermelonDB();

// Use DataStore as normal - but faster!
const todos = await DataStore.query(Todo);

Migration from Existing Apps

Already using DataStore? Migration takes 2 minutes:

import { createFallbackConfiguration } from 'amplify-watermelondb-adapter';
import { SQLiteAdapter } from '@aws-amplify/datastore-storage-adapter';

// Your existing configuration
const config = {
  authProviders: { /* your auth */ },
  syncExpressions: [ /* your rules */ ]
};

// Automatic upgrade with fallback safety net
createFallbackConfiguration(
  config,
  SQLiteAdapter, // Falls back if needed
  { enableDebugLogging: true }
);

πŸ”₯ Advanced Features

🏒 Multi-Tenant Support

Integrates subscription variables from Amplify PR #14564 for multi-tenant GraphQL filtering.

import { WatermelonDBAdapter } from 'amplify-watermelondb-adapter';

const adapter = new WatermelonDBAdapter();

// Configure subscription variables for multi-tenant filtering
adapter.setSubscriptionVariables({
  tenantId: 'tenant-456',
  userId: 'user-789'
});

// Dynamic schema switching
adapter.setAlternativeSchema(alternativeSchema, () => {
  // Your logic to determine which schema to use
  return shouldUseAlternative() ? 'alternative' : 'primary';
});

πŸ“‘ WebSocket Health Monitoring

Implements connection health monitoring from Amplify PR #14563 with auto-reconnection capabilities.

// Monitor WebSocket connection health
adapter.startWebSocketHealthMonitoring({
  interval: 30000, // 30 seconds
  onHealthCheck: (isHealthy) => {
    console.log(`WebSocket health: ${isHealthy ? 'βœ…' : '❌'}`);
  },
  onReconnect: () => {
    console.log('Attempting WebSocket reconnection...');
  }
});

// Track keep-alive timestamps for debugging
adapter.trackKeepAlive(); // Stores in AsyncStorage

πŸ“Š Performance Monitoring

import { getWatermelonDBMetrics } from 'amplify-watermelondb-adapter';

// Monitor your performance gains
const metrics = getWatermelonDBMetrics();
console.log(`Dispatcher: ${metrics.dispatcherType}`); // "jsi" on RN
console.log(`Cache hits: ${metrics.cacheHitRate}%`); // Track efficiency

πŸŽ›οΈ Fine-Tuning

new WatermelonDBAdapter({
  // Optimize for your use case
  cacheMaxSize: 500,        // More cache for read-heavy apps
  cacheTTL: 60 * 60 * 1000, // 1 hour for stable data
  batchSize: 5000,          // Larger batches for bulk imports
  conflictStrategy: 'ACCEPT_REMOTE' // Your sync strategy
});

πŸ” Enhanced Query Operators

Supports 'in' and 'notIn' operators from Amplify PR #14544 for advanced filtering.

// Query with 'in' operator
const priorityTasks = await DataStore.query(Todo, todo =>
  todo.priority.in([1, 2, 3])
);

// Query with 'notIn' operator
const nonUrgentTasks = await DataStore.query(Todo, todo =>
  todo.status.notIn(['urgent', 'critical'])
);

πŸ”„ Reactive Queries

// WatermelonDB's magic: truly reactive queries
DataStore.observe(Todo).subscribe(msg => {
  // Component auto-updates when ANY todo changes
  // Even from different screens or background sync!
});

✨ Features

Core Features

  • πŸ‰ WatermelonDB Integration - Seamlessly integrates with WatermelonDB's reactive architecture
  • πŸ”Œ Drop-in replacement - Minimal configuration changes required
  • πŸ“š Full TypeScript - Complete type safety and IntelliSense
  • πŸ”„ Automatic fallback - Falls back to in-memory storage if initialization fails
  • βš™οΈ Configurable - Customizable cache, batch size, and conflict resolution
  • πŸ› οΈ Development-friendly - Comprehensive error handling and debugging support
  • πŸ‰ JSI Performance - Leverages WatermelonDB's JSI dispatcher on React Native
  • πŸš€ Cross-platform - Works on iOS, Android, Web, and Node.js
  • πŸ’Ύ Smart Caching - Built-in LRU cache with configurable TTL

πŸ†• Latest Features

  • 🏒 Multi-Tenant Support - Dynamic schema switching for multi-tenant applications
  • πŸ“‘ Subscription Variables - Filter GraphQL subscriptions per tenant/user (Amplify PR #14564)
  • πŸ”Œ WebSocket Health Monitoring - Auto-reconnection with health checks (Amplify PR #14563)
  • πŸ“ Keep-Alive Tracking - Debug connection issues with AsyncStorage timestamps
  • πŸ” Enhanced Operators - Full support for 'in' and 'notIn' query operators (Amplify PR #14544)

πŸŽ“ Examples

πŸ‰ E-commerce App

// Query products with WatermelonDB's reactive performance
const products = await DataStore.query(Product,
  p => p.inStock.eq(true),
  { limit: 1000 }
);

πŸ‰ Chat Application

// Real-time messaging with reactive updates
DataStore.observe(Message, m =>
  m.conversationId.eq(currentChat)
).subscribe(update => {
  // UI updates automatically when data changes
});

πŸ“Š Technical Specifications

Adapter performance characteristics from automated tests:

πŸ‰ WatermelonDB Adapter Performance Metrics
==========================================

Operation                 | Average Time
--------------------------|-------------
Adapter Creation          | 0.03ms
Config Validation         | 0.05ms
Dispatcher Detection      | 0.01ms
Schema Version Lookup     | 0.02ms
Memory (1000 instances)   | 2.65MB
Concurrent Creation       | 500 adapters in 0.96ms

πŸ”— Compatibility

Compatible with:

  • πŸ‰ AWS Amplify DataStore - v4.x and v5.x
  • πŸ‰ GraphQL subscriptions - Full support
  • πŸ‰ Multi-auth rules - All authentication strategies
  • πŸ‰ Conflict resolution - Version-based and custom strategies
  • πŸ‰ Schema migrations - Automatic schema handling
  • πŸ‰ DataStore Selective Sync - Predicate-based syncing

πŸ“¦ What's Included

  • πŸ‰ WatermelonDBAdapter - Core adapter implementation
  • πŸ”§ Integration helpers - Easy setup utilities
  • πŸ“Š Performance monitoring - Metrics collection
  • πŸ”„ Migration tools - Upgrade from SQLiteAdapter
  • πŸ“š TypeScript definitions - Full type safety
  • 🎯 Examples - Real-world usage patterns

🚦 Getting Started

  1. πŸ‰ Install the package

    npm install amplify-watermelondb-adapter @nozbe/watermelondb
  2. πŸ‰ Configure DataStore

    import { configureDataStoreWithWatermelonDB } from 'amplify-watermelondb-adapter';
    configureDataStoreWithWatermelonDB();
  3. πŸ‰ Start using DataStore - Same API, WatermelonDB performance!

πŸ“‹ API Reference

New Methods

Method Description
setSubscriptionVariables(vars) Set GraphQL subscription filtering variables for multi-tenant support
getSubscriptionVariables() Get current subscription variables
setAlternativeSchema(schema, selector) Configure alternative schema for runtime switching
startWebSocketHealthMonitoring(options) Start monitoring WebSocket connection health
stopWebSocketHealthMonitoring() Stop WebSocket health monitoring
trackKeepAlive() Store keep-alive timestamp in AsyncStorage

Core Methods

Method Description
setup(schema, ...) Initialize adapter with DataStore schema
query(model, predicate, pagination) Query records with optional filtering
save(model, condition) Save or update a model instance
delete(model, condition) Delete model(s)
observe(model, predicate) Subscribe to real-time changes
batchSave(model, items) Efficiently save multiple items

πŸ“– Documentation

πŸ€” FAQ

Q: Is this production-ready? A: Yes! The adapter has comprehensive test coverage and follows production-grade patterns.

Q: Does it support all DataStore features? A: Yes! The adapter implements the complete DataStore storage interface.

Q: What if WatermelonDB fails to initialize? A: The adapter automatically falls back to in-memory storage to prevent app crashes.

Q: What platforms are supported? A: iOS, Android, Web, and Node.js with automatic platform detection.

πŸ›Ÿ Support

πŸ™ Acknowledgments

  • πŸ‰ AWS Amplify - For the DataStore framework
  • πŸ‰ WatermelonDB - For the reactive database architecture
  • πŸ‰ React Native - For cross-platform mobile development

πŸ“„ License

MIT License - See LICENSE file for details.


πŸ‰ Built with WatermelonDB's reactive performance for Amplify DataStore πŸ‰

Bringing WatermelonDB's ⚑ performance to AWS Amplify DataStore πŸ‰

About

High-performance WatermelonDB adapter for AWS Amplify DataStore with JSI support

Resources

License

MIT, Unknown licenses found

Licenses found

MIT
LICENSE
Unknown
LICENSE-APACHE

Contributing

Stars

Watchers

Forks

Packages

No packages published