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 🙏

© 2024 – Pkg Stats / Ryan Hefner

blazestore

v1.0.0

Published

![image](https://raw.githubusercontent.com/dwyl/repo-badges/4720fcd2ccfadea4715475628987cf7c95542373/svg/coverage-100.svg)

Downloads

11

Readme

Blazestore

image

Why

Firestore is cool database packed with a lot of features. Sometimes the number of features can be overwhelming and it feels like you have to get PhD in Firestore's docs to perform a simple CRUD operation. The goal of this library is to provide easy-to-use and type-safe API to interact with firestore instance, whilst still leaving the ability to use original API for more advanced use cases.

What

Blazestore is a tiny wrapper around firebase/firestore package offering simple interface to do basic operations against firestore instance. Collections and documents created with this package are not special in any way and can be interacted throughout regular firebase/firestore API. To get firebase collection reference just use collection.reference. All limitations imposed by firestore (e.g.: you cannot filter by two different fields at the same time without composed index) are still applicable.

How

To use Blazestore first you need to create firestore instance and initialize firebase app with firestore in your code. You can follow steps in firebase documentation to do this. Then you just need to supply database, collection name and type to Collection constructor, the type is optional but highly recommended as it will be used for all operations against that collection.

import { getFirestore } from 'firebase/firestore';
import { Collection } from 'blazestore';

const db = getFirestore();

type Pokemon = {
  name: string;
  type?: string;
};

const pokemons = new Collection<Pokemon>('pokemon', db);

Then you can access all basic CRUD operations:

const mewTwoId = await pokemons.create({ name: 'Mewtwo' });
const allPokemons = pokemons.read();
await pokemons.update(mewTwoId, { type: 'psycho' });
await pokemons.delete(mewTwoId);

const unsubscribe = pokemons.subscribe(({ name }) => {
  console.log(name); // This will log all pokemons names every time a pokemon is added/updated/deleted
});
unsubscribe(); // Call it when you do not need data anymore to free precious RAM

Unlike in firestore API, when reading data, document is returned as plain object together with id of that document.

Note that you are not allowed to specify id for document. Id is automatically assigned by firestore. If you want to specify id for your document you have to use different property name.

Deep dive

Querying data

When reading the data, either with collection.read or collection.subscribe, you can supply Query Parameters object that will be used to filter, limit, and sort your data. QueryParameters type is based on a type of the document in the collection to provide better intellisense.

QueryParameters type as well as types of its individual components are exported from the library so you can construct object outside of method calls whilst preserving type safety. Keep in mind that these types are generic and require type of a document used in collection.

  • Filtering - to filter the data you have to supply where object with property name matching property name in document type. Type for property value is based on document type as well. Whenever you are in doubt just hit ctrl+space and let typescript intellisense take the wheel.
    If you specify more than one field inside where object they will be merged using AND logic. Also please keep in mind that you need to first create composite index for these fields.

    type Pokemon = {
      pokedexIndex: number;
      name: string;
      types: string[];
      isEvolution: boolean;
    };
    
    const allFireTypePokemons = pokemon.read({ where: { types: { contains: 'fire' } } });
    const mew = pokemon.read({ where: { name: { is: 'mew' } } });
  • Sorting - to sort the data you have to supply sortBy object with property name matching property name in document type and value set to either Ascending or Descending

    type Pokemon = {
      pokedexIndex: number;
      name: string;
    };
    
    await collection.create({ name: 'Ivysaur', pokedexId: 2, });
    await collection.create({ name: 'Venusaur', pokedexId: 3, });
    await collection.create({ name: 'Bulbasaur', pokedexId: 1, });
    const result = await collection.read({ sortBy: { pokedexId: 'Ascending' } });
    result.forEach(({name})=>console.log(name)) // 'Bulbasaur', 'Ivysaur', 'Venusaur'
  • Limits - you can also limit the number of records that are returned from the query by supplying takeFirst or takeLast.

    type Pokemon = {
      pokedexIndex: number;
      name: string;
    };
    
    await collection.create({ name: 'Ivysaur', pokedexId: 2, });
    await collection.create({ name: 'Venusaur', pokedexId: 3, });
    await collection.create({ name: 'Bulbasaur', pokedexId: 1, });
    const [bulbasaur] = await collection.read({ sortBy: { pokedexId: 'Ascending' }, takeFirst: 1 });
    const [venusaur] = await collection.read({ sortBy: { pokedexId: 'Ascending' }, takeLast: 3 });

Collection ref

It might happen that your needs exceed capabilities of this library. Should that happen, you can use official firestore API as usual. For your convenience collection has reference field that lets you access underlying collection reference.

import { query, orderBy, startAt, getDocs, getFirestore } from "firebase/firestore"; 
import { Collection } from 'blazestore';

const db = getFirestore();

type Pokemon = {
  name: string;
  pokedexIndex: number;
};

const pokemons = new Collection<Pokemon>('pokemon', db);
const result = await getDocs(query(pokemons.reference, orderBy("pokedexIndex"), startAt(3)));

React

To please React users there is also useCollection hook that is tiny wrapper around collection.subscribe method. It accepts collection and optionally QueryParameters object and returns state variable that changes every time collection is updated (that includes adding, removing and updating document). Subscription will be reset whenever QueryParameters change.

type Pokemon = {
  name: string;
  pokedexIndex: number;
};

const pokemonsCollection = new Collection<Pokemon>("pokemon", db);
const sortBy = { pokedexIndex: "Ascending" } as const;

const Pokedex = () => {
  const pokemons = useCollection(pokemonsCollection, { sortBy });

  return (
    <ul>
      {pokemons.map(({ pokedexIndex, name }) => (
        <li key={pokedexIndex}>{name}</li>
      ))}
    </ul>
  );
};

Running locally

Both test and examples take advantage of firebase emulators. To run either of them locally first you will need to setup emulators on your machine. To do so, please follow official guide. Once you are done with a setup simply run pnpm db from root folder.