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

@ffdb/react-native

v0.3.14

Published

FFDB secure-session and native SQLite adapter contracts for React Native

Readme

@ffdb/react-native

Runtime-neutral storage contracts for using FFDB from React Native or Expo. This package does not depend on a particular native storage or SQLite library. It exports:

  • ReactNativeSessionStore, which adapts an asynchronous key/value store to the @ffdb/client end-user SessionStore contract;
  • NativeSQLiteReplica, a durable ReplicaAdapter for @ffdb/sync-client;
  • AsyncKeyValueStorage, NativeSQLiteDriver, SQLiteResult, and SQLitePrimitive, which applications implement for their chosen runtime.

It does not bundle Expo SecureStore, AsyncStorage, Expo SQLite, a fetch polyfill, or React components.

pnpm add --save-exact @ffdb/[email protected] @ffdb/[email protected] \
  @ffdb/[email protected]

The matching GitHub Release also provides checksum-listed .tgz files for verified offline installation.

Secure end-user sessions

Refresh and access tokens are credentials. Back ReactNativeSessionStore with OS-protected secure storage, not plain AsyncStorage. For Expo SecureStore, adapt the method names explicitly:

import * as SecureStore from "expo-secure-store";
import { FFDBClient } from "@ffdb/client";
import {
  ReactNativeSessionStore,
  type AsyncKeyValueStorage,
} from "@ffdb/react-native";

const secureStorage: AsyncKeyValueStorage = {
  getItem: (key) => SecureStore.getItemAsync(key),
  setItem: (key, value) => SecureStore.setItemAsync(key, value),
  removeItem: (key) => SecureStore.deleteItemAsync(key),
};

const client = new FFDBClient({
  baseUrl: process.env.EXPO_PUBLIC_FFDB_API_URL!,
  projectId: process.env.EXPO_PUBLIC_FFDB_PROJECT_ID!,
  sessionStore: new ReactNativeSessionStore(secureStorage),
  // Supply fetch here only when the runtime does not provide a compatible one.
});

Only public API URL/project identifiers belong in EXPO_PUBLIC_* variables. Never put a developer API key, password, access token, or refresh token there. Changing Expo environment files requires restarting the development server.

The store removes malformed or structurally invalid persisted session JSON and returns null. Storage availability, biometric/access-control policy, backup behavior, device migration, token size limits, and at-rest protection remain the application's responsibility.

Native SQLite replica

import { OfflineSyncClient } from "@ffdb/sync-client";
import { NativeSQLiteReplica } from "@ffdb/react-native";

const replica = new NativeSQLiteReplica(nativeSQLiteDriver);
await replica.initialize();

const sync = new OfflineSyncClient(client, replica);
await sync.sync();

const draft = await sync.getRow("drafts", draftId);
const drafts = await sync.listRows("drafts");

nativeSQLiteDriver is an application-supplied wrapper. Its contract is more important than the library-specific method names:

  • execute(sql, parameters) binds positional parameters and returns rows as objects plus a changes count;
  • transaction(work) gives the callback a driver bound to one real SQLite transaction, commits only after the callback resolves, and rolls back every callback write when it rejects;
  • the SQLite build must support STRICT tables and the documented ON CONFLICT DO UPDATE ... WHERE statements;
  • calls made through the callback driver must not escape or interleave outside that transaction.

initialize() creates private __ffdb_client_* metadata, row-cache, pending, and rejection tables. It is also called lazily. Do not expose those tables to untrusted SQL or treat their JSON representation as the application's schema. The adapter stores snapshot replacement, pulled changes, mutation bookkeeping, cursor advances, and optimistic local mutations atomically. It implements the same typed getRow(table, primaryKey), deterministic listRows(table), getPending(limit), and getRejected(limit) APIs as the browser, Node, and memory replicas. These methods return decoded records without exposing the private SQLite connection. Applications that need arbitrary local queries can implement ReplicaAdapter alongside a richer safe read model.

NativeSQLiteReplica is not proof that every native SQLite wrapper satisfies the contract. Test rollback, parameter binding, row-object conversion, concurrent transactions, app restart, and the exact SQLite version on every supported platform before claiming durable offline behavior.

Networking and lifecycle

OfflineSyncClient performs network work through the supplied FFDBClient; this package never calls fetch itself. Use an HTTPS API URL outside explicit localhost development, pass a compatible fetch implementation if the runtime lacks one, and handle network errors at the sync boundary. The packages do not subscribe to NetInfo or AppState. Applications decide when to pause, resume, and call sync(), and may pass an AbortSignal when a screen or task is cancelled.