@rgomezp/ganon v2.4.7
React Native Ganon SDK provides seamless storage management and cloud backup capabilities using Firestore and a local storage manager (MMKV).
Overview
Ganon is a storage and backup management SDK that simplifies integrating Firestore and a local storage system in React Native projects. It provides a typed instance of a storage managers and a simple API for data locally as well as syncing to Firebase.
Install
# npm
npm install @rgomezp/ganon
# yarn
yarn add @rgomezp/ganonConfiguration
Ganon requires configuration to map local storage data to Firestore backup.
Storage Mapping
Define a storage mapping interface. Include the identifier key you will use to track users.
import { BaseStorageMapping } from '@rgomezp/ganon';
// Define a mapping interface
interface MyMapping extends BaseStorageMapping {
email: string; // identifier key
booksRead: number;
books: { [key: string]: { title: string } };
}Cloud Config
Define a configuration object for Firestore backups. Maps documents to document and sub-collection keys.
You can exclude the identifier key as this is handled automatically.
interface CloudBackupConfig {
[key: string]: {
docKeys?: string[];
subcollectionKeys?: string[];
type?: 'string' | 'number' | 'boolean' | 'object' | 'array';
schema?: JSONSchema7; // JSON Schema for validating object/array data
}
}Example with Schema Validation:
import { CloudBackupConfig } from '@rgomezp/ganon';
import { JSONSchema7 } from 'json-schema';
// Define a mapping interface
interface MyMapping extends BaseStorageMapping {
email: string; // identifier key
booksRead: number;
books: {
[key: string]: {
title: string;
author: string;
rating: number;
genres: string[];
publishedDate: string;
}
};
userPreferences: {
theme: 'light' | 'dark';
notifications: boolean;
fontSize: number;
};
}
// Define JSON schemas for validation
const bookSchema: JSONSchema7 = {
type: 'object',
required: ['title', 'author', 'rating', 'genres', 'publishedDate'],
properties: {
title: { type: 'string', minLength: 1 },
author: { type: 'string', minLength: 1 },
rating: { type: 'number', minimum: 0, maximum: 5 },
genres: {
type: 'array',
items: { type: 'string' },
minItems: 1
},
publishedDate: {
type: 'string',
format: 'date'
}
}
};
const userPreferencesSchema: JSONSchema7 = {
type: 'object',
required: ['theme', 'notifications', 'fontSize'],
properties: {
theme: {
type: 'string',
enum: ['light', 'dark']
},
notifications: { type: 'boolean' },
fontSize: {
type: 'number',
minimum: 12,
maximum: 24
}
}
};
const cloudConfig: CloudBackupConfig<MyMapping> = {
reading: {
docKeys: ['booksRead'],
subcollectionKeys: ['books'],
type: 'object',
schema: bookSchema
},
preferences: {
docKeys: ['userPreferences'],
type: 'object',
schema: userPreferencesSchema
}
};This configuration: 1. Defines strict schemas for both books and user preferences 2. Validates data structure and types before syncing to Firestore 3. Ensures required fields are present 4. Enforces value constraints (e.g., rating between 0-5, font size between 12-24) 5. Validates date formats and enum values
When using this configuration, Ganon will automatically validate data against these schemas before syncing to Firestore. If validation fails, the sync operation will be rejected and an error will be thrown.
Ganon Config
| Property | Type | Description |
|---|---|---|
identifierKey | string | Unique user identifier key for users (e.g. email, uid) |
cloudConfig | CloudBackupConfig<T> | Configuration object for Firestore backups where T is your custom storage mapping. |
logLevel | LogLevel | LogLevel enum |
onSyncConflict | ConflictHandler<T> | Optional handler for resolving sync conflicts |
Conflict Resolution
Ganon provides a robust conflict resolution system to handle synchronization conflicts that occur when data is modified both locally and remotely between syncs.
Basic Configuration
import { ConflictHandler } from '@rgomezp/ganon';
const conflictHandler: ConflictHandler<MyMapping> = (conflict) => {
// Always prefer local changes
return { strategy: 'local' };
};
const config = {
// ... other config options
onSyncConflict: conflictHandler
};Resolution Strategies
- Local Strategy: Keep local changes
{ strategy: 'local' }- Remote Strategy: Accept remote changes
{ strategy: 'remote' }- Custom Strategy: Provide merged value
{
strategy: 'custom',
customValue: mergedData
}For detailed conflict resolution documentation, see Conflict Resolution Guide.
Setup
Create a new file called ganon.ts. We must use the instance in order for our types to work as expected.
Export the instance for usage across your codebase.
import Ganon, { LogLevel } from "@rgomezp/ganon";
import cloudBackupConfig from "./cloudBackupConfig";
import { StorageMapping } from "src/models/StorageMapping";
const logLevel = process.env.NODE_ENV === 'development' ? LogLevel.VERBOSE : LogLevel.NONE;
// Initialize once using your specialized type.
export const ganon: Ganon<StorageMapping> = Ganon.init<StorageMapping>({
identifierKey: 'email',
cloudConfig: cloudBackupConfig,
logLevel,
});Usage
import { ganon } from "<path_to_file>/ganon";
ganon.set("booksRead", 5);🤝 Contributing
Contributions, issues, and feature requests are welcome!
Feel free to check the issues page.
Show your support
Give a ⭐️ if this project helped you!
Follow
- Twitter: @ro_gmzp
- Github: @rgomezp
- LinkedIn: Rodrigo Gomez-Palacio
📝 License
Copyright © 2025 Honey Wolf LLC This project is Unlicensed.
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
7 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago