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

@megasquid/firestore-fetch

v0.1.5

Published

A powerful, observable-based Firestore data fetcher for web apps using the official Firebase JavaScript SDK.

Readme

@megasquid/firestore-fetch

A powerful, observable-based Firestore data fetcher for web apps using the official Firebase JavaScript SDK.

@megasquid/firestore-fetch provides a reactive and highly flexible way to query and compose data from Firestore. It focuses on reads: streaming documents and collections, composing multi-source fetches (including subcollections and reference resolution), and automatically injecting lightweight _meta information into every document.

Key differentiators:

  • Observable-first API built on RxJS (streams for doc$, col$, colGroup$, and the advanced fetch() builder).
  • Declarative FetchConfig to describe complex data shapes (multiple docs, collections, subcollections, and properties) in one call.
  • Automatic _meta augmentation (path, id, segments, timestamps) so downstream code always has identity and path info.
  • Designed for the standard firebase/firestore JavaScript SDK (modular or namespaced use).

Installation

npm install @megasquid/firestore-fetch firebase

Basic usage

The package is read-focused. It’s intended to be extended by your app to add write helpers (so you can adapt write semantics and security rules as needed). Example of creating an Angular service that extends FirestoreFetch:

// app/services/firestore.service.ts (Angular example)
import { Injectable } from '@angular/core';
import { FirestoreFetch, Meta } from '@megasquid/firestore-fetch';

@Injectable({ providedIn: 'root' })
export class FirestoreService extends FirestoreFetch {
	constructor() {
		// Provide a meta factory so `_meta` is created for new docs
		super((path: string) => ({
			path,
			id: path.split('/').pop() || '',
			segments: path.split('/'),
			createdAt: new Date().toISOString(),
			updatedAt: new Date().toISOString(),
		}));
	}

	// Add write methods (see "Extending with Write Operations")
}

Core concepts

  • Automatic _meta field: every document returned from doc$, col$, colGroup$ or fetch() is enriched with _meta containing path, id, segments and optional timestamps. This makes it trivial to persist changes or resolve related resources.
  • Lightweight DocumentReference: use ref(path) to create a serializable { id, path } reference (preferred for storing refs in documents that will be passed through JSON or stored in Firestore fields).
  • Declarative fetch: fetch() accepts a FetchConfig | FetchConfig[] describing what to fetch. Use asNamedProperty to shape results and subCollections/properties to attach nested data.

API overview

  • doc$(path: string): Observable<(T & Meta) | null> — Stream a single document with _meta.
  • col$(path: string, filters?, orderBy?, limit?): Observable<(T & Meta)[] | null> — Stream a collection with optional filters, ordering, and limit.
  • colGroup$(segment: string, filters?, orderBy?, limit?): Observable<(T & Meta)[] | null> — Collection group queries across all parents.
  • fetch(config|configs, buildConfig?): Observable — Advanced multi-source builder that composes results, resolves references, and attaches subcollections.
  • id(): string — Generate a Firestore-compatible random document id.
  • ref(path: string) — Create a lightweight { id, path } reference object.
  • clone(obj: any): any — Deep clone preserving Firestore-like values (refs, timestamps where applicable).

Practical recipes

  • Listen to a document:
this.ffs.doc$<User>('users/abc').subscribe(user => {
	// user._meta.path === 'users/abc'
});
  • Stream a collection with filters and ordering:
this.ffs.col$<Post>(
	'posts',
	[ ['published', '==', true] ],
	['createdAt', 'desc'],
	20
).subscribe(posts => {
	// posts: (Post & Meta)[]
});
  • Fetch a document with subcollections and resolved refs:
this.ffs.fetch<{ hunt: Hunt & Meta }>([
	{
		path: 'hunts/abc',
		asNamedProperty: 'hunt',
		subCollections: [ { path: 'loot' }, { path: 'rewards' } ],
		properties: { '$.coverImage': {} }
	}
], { merge: true, onlyNamedProperties: true })
.subscribe(({ hunt }) => {
	console.log(hunt.loot, hunt.coverImage);
});

Extending with Write Operations

@megasquid/firestore-fetch purposely focuses on reads so you can implement writes in the way that fits your app and security rules. Example using the official Firebase SDK's write helpers:

import { getFirestore, doc, setDoc, updateDoc, deleteDoc } from 'firebase/firestore';

class FirestoreService extends FirestoreFetch {
	private db = getFirestore();

	async set(path: string, data: any, options = { merge: true }) {
		const meta = data._meta ? { ...data._meta, updatedAt: new Date().toISOString() } : this.createMeta(path);
		const payload = { ...data, _meta: meta };
		await setDoc(doc(this.db, path), payload, { merge: options.merge } as any);
		return payload;
	}

	async update(path: string, patch: any) {
		const patchWithMeta = { ...patch, '_meta.updatedAt': new Date().toISOString() } as any;
		await updateDoc(doc(this.db, path), patchWithMeta);
	}

	async delete(path: string) {
		await deleteDoc(doc(this.db, path));
	}
}

Documentation and examples

For real-world usage examples (how the library is used across an app, pipes, services, and recipes) see the project docs:

  • docs/firestore-fetch.md — practical examples and recipes from a real app (LootletApp).

Contributing and notes

  • This package is intentionally read-centric and designed to be extended for writes so your app can keep full control of security, validation, and triggers.
  • If you use server SDKs or cloud functions, adapt write helpers accordingly (use Admin SDK patterns server-side).

License

MIT

Last updated: 2025-10-26