npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@rgomezp/ganon

v2.7.3

Published

React Native firestore wrapper

Readme

React Native Ganon SDK provides seamless storage management and cloud backup capabilities using Firestore and a local storage manager (MMKV).

Overview

GanonDB 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.

Note: Supabase & other DBs are coming soon.


Install

# npm
npm install @potionforge/ganon

# yarn
yarn add @potionforge/ganon

Configuration

GanonDB 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 '@potionforge/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 '@potionforge/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 | | conflictResolutionConfig | Partial<ConflictResolutionConfig> | Optional configuration for handling data conflicts during sync operations | | integrityFailureConfig | Partial<IntegrityFailureConfig> | Optional configuration for handling integrity failures during sync operations |

Conflict Resolution & Integrity Failure Handling

Ganon provides robust systems to handle both data conflicts and integrity failures during synchronization.

Conflict Resolution Configuration

import { ConflictResolutionStrategy, ConflictMergeStrategy } from '@potionforge/ganon';

const config = {
  // ... other config options
  conflictResolutionConfig: {
    strategy: ConflictResolutionStrategy.LOCAL_WINS,
    mergeStrategy: ConflictMergeStrategy.DEEP_MERGE,
    notifyOnConflict: true,
    trackConflicts: true,
    maxTrackedConflicts: 100
  }
};

Conflict Resolution Strategies

  1. Local Wins: Use local data as source of truth
strategy: ConflictResolutionStrategy.LOCAL_WINS
  1. Remote Wins: Use remote data as source of truth
strategy: ConflictResolutionStrategy.REMOTE_WINS
  1. Last Modified Wins: Use data with most recent timestamp
strategy: ConflictResolutionStrategy.LAST_MODIFIED_WINS

Integrity Failure Configuration

import { IntegrityFailureRecoveryStrategy } from '@potionforge/ganon';

const config = {
  // ... other config options
  integrityFailureConfig: {
    maxRetries: 3,
    retryDelay: 1000,
    recoveryStrategy: IntegrityFailureRecoveryStrategy.FORCE_REFRESH,
    notifyOnFailure: true
  }
};

Integrity Failure Recovery Strategies

  1. Force Refresh: Refresh metadata and re-fetch data
recoveryStrategy: IntegrityFailureRecoveryStrategy.FORCE_REFRESH
  1. Use Local: Trust local data over remote
recoveryStrategy: IntegrityFailureRecoveryStrategy.USE_LOCAL
  1. Use Remote: Trust remote data over local
recoveryStrategy: IntegrityFailureRecoveryStrategy.USE_REMOTE
  1. Skip: Skip problematic keys and continue
recoveryStrategy: IntegrityFailureRecoveryStrategy.SKIP

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 "@potionforge/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

Basic Operations

import { ganon } from "<path_to_file>/ganon";

ganon.set("booksRead", 5);

Advanced Sync Operations

Hydration with Conflict Resolution

import { ConflictResolutionStrategy, IntegrityFailureRecoveryStrategy } from '@potionforge/ganon';

// Hydrate specific keys with custom conflict resolution
const result = await ganon.hydrate(
  ['booksRead', 'books'],
  {
    strategy: ConflictResolutionStrategy.LOCAL_WINS,
    notifyOnConflict: true
  },
  {
    maxRetries: 5,
    recoveryStrategy: IntegrityFailureRecoveryStrategy.FORCE_REFRESH
  }
);

console.log(`Restored ${result.restoredKeys.length} keys`);
console.log(`Failed ${result.failedKeys.length} keys`);

Force Hydration

// Force hydrate specific keys regardless of version comparison
const result = await ganon.forceHydrate(
  ['userPreferences'],
  {
    strategy: ConflictResolutionStrategy.REMOTE_WINS
  },
  {
    recoveryStrategy: IntegrityFailureRecoveryStrategy.USE_REMOTE
  }
);

Restore All Data

// Restore all data from cloud (no per-invocation config needed)
const result = await ganon.restore();

Available Enums and Types

Ganon exports several enums and types for configuration and type safety:

import {
  // Conflict Resolution
  ConflictResolutionStrategy,
  ConflictMergeStrategy,
  ConflictResolutionConfig,

  // Integrity Failure Handling
  IntegrityFailureRecoveryStrategy,
  IntegrityFailureConfig,

  // Sync Status
  SyncStatus,

  // Results
  RestoreResult,
  BackupResult,

  // Logging
  LogLevel
} from '@potionforge/ganon';

Conflict Resolution Enums

  • ConflictResolutionStrategy.LOCAL_WINS - Use local data
  • ConflictResolutionStrategy.REMOTE_WINS - Use remote data
  • ConflictResolutionStrategy.LAST_MODIFIED_WINS - Use most recent data

Integrity Failure Recovery Enums

  • IntegrityFailureRecoveryStrategy.FORCE_REFRESH - Refresh metadata and re-fetch
  • IntegrityFailureRecoveryStrategy.USE_LOCAL - Trust local data
  • IntegrityFailureRecoveryStrategy.USE_REMOTE - Trust remote data
  • IntegrityFailureRecoveryStrategy.SKIP - Skip problematic keys

🤝 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

📝 License

Copyright © 2025 Honey Wolf LLC This project is Proprietary Licensed.