0.1.4 • Published 2 months ago

@serge-ivo/firestore-wrapper v0.1.4

Weekly downloads
-
License
MIT
Repository
github
Last release
2 months ago

@serge-ivo/firestore-wrapper

npm version license

Drop-in replacement for firebase/firestore that puts a rate-limiter in front of every read/write.
Unofficial project – not affiliated with Google or Firebase.


✨ Why?

PainWrapper fix
Blowing through Firestore’s free-tier reads or writesHard-caps or queues traffic by global or per-collection limits.
Developers forget to throttle expensive listenersThe wrapper intercepts the SDK itself – no discipline required.
You want “same API, extra safety”export * from the real SDK; only getDoc, setDoc, etc. are guarded.

🛠️ Install

# add the wrapper alongside firebase
npm install firebase @serge-ivo/firestore-wrapper
# or
yarn add firebase @serge-ivo/firestore-wrapper

🚀 Two integration styles

1. Explicit (import the wrapper directly)

import { initializeApp } from "firebase/app";
import {
  doc,
  getDoc,
  configureRateLimits, // only extra symbol
} from "@serge-ivo/firestore-wrapper";

configureRateLimits({
  global: { read: 1_000, write: 500, windowMs: 60_000 },
  perCollection: { users: { read: 200 } },
  behavior: "throw",
});

const app = initializeApp(firebaseConfig);
const snap = await getDoc(doc("users/alice")); // ← throttled

Developers must remember to use the wrapper path in new files.


2. Seamless alias (devs keep firebase/firestore)

Ideal for large codebases where you don’t want to touch hundreds of imports.

  1. Side-effect import once to hard-code limits:

    // src/firestore-limits.ts
    import { configureRateLimits } from "@serge-ivo/firestore-wrapper";
    
    configureRateLimits({
      global: { read: 1_000, write: 500, windowMs: 60_000 },
      behavior: "throw",
    });
    // main.ts
    import "./firestore-limits"; //  ← must run before first Firestore call
    import ReactDOM from "react-dom/client";
    import App from "./App";
  2. Vite alias that rewrites only your source imports:

    // vite.config.ts
    import { defineConfig } from "vite";
    
    export default defineConfig({
      plugins: [
        {
          name: "alias-firestore-wrapper",
          enforce: "pre",
          resolveId(source, importer) {
            if (
              source === "firebase/firestore" &&
              importer && // may be undefined in virtual modules
              !importer.includes("node_modules")
            ) {
              return this.resolve("@serge-ivo/firestore-wrapper", importer, {
                skipSelf: true,
              });
            }
          },
        },
      ],
    });
    • Every import originating in your code (src/**) is rewritten.
    • Imports inside node_modules (including the wrapper itself) see the real SDK, avoiding circular alias problems.

That’s it—developers still write:

import { collection, query, onSnapshot } from "firebase/firestore";

…but at runtime those calls go through the wrapper and respect your limits.


⚙️ API (what you can tweak)

configureRateLimits({
  global: { read, write, windowMs },
  perCollection: { "<collection>": { read, write } },
  behavior: "throw" | "queue" | "log",
  onLimitExceeded(details) {
    /* optional hook */
  },
});
  • throw – default, rejects extra calls.
  • queue – waits until the sliding window has room, then continues.
  • log – allows the call but console.warns when a limit is hit.

🧪 Testing tip

import { rateLimiter } from "@serge-ivo/firestore-wrapper";

beforeEach(() => {
  rateLimiter.reset(); // clear counters
  rateLimiter.configure({ global: { read: 2, windowMs: 100 } });
});

rateLimiter.reset() is handy for unit tests that simulate bursts.


🔒 Security & disclaimers

  • Compatible with Firebase SDK ≥ 10 – peer range is >=10 <12.
  • Works against the Firebase Emulator Suite identically.
  • Not an official Google product; use at your own risk.

🪪 License

MIT

Copy/paste over your existing **README.md** (or merge sections you like).
It now includes:

* The quick explicit approach **and** the seamless alias pattern.
* Hard-coded limiter example.
* API table and testing snippet.
0.1.4

2 months ago

0.1.3

2 months ago

0.1.2

2 months ago

0.1.1

2 months ago

0.1.0

2 months ago