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 🙏

© 2025 – Pkg Stats / Ryan Hefner

refdata-storage

v6.2.1

Published

Document storage with schemas and versions

Downloads

11

Readme

Storage

Dynamic entity storage

Features

  • Versioning
  • Avro-style schema enforcement
  • Observable change events
  • Configurable adapters

Installation

npm install refdata-storage

Configuration

There are several ways a storage instance can be constructed. It is also possible to have multiple storage instances simultaneously within your application. Here are the main configuration setups with their respective use-cases.

Fully static setup

The storage instance always boots up from exactly the same externally controlled state. Ideal for test automation or as a source of static read-only reference data.

import createStorage from '@navarik/storage'

const storage = createStorage({
  schema: [ ...list of pre-defined schemas... ],
  data: [ ...list of pre-defined data objects (including their metadata portions)... ]
})

storage.init()

Note, that with this setup it is still possible to create schemas or entities, however these changes will not survive the application restart since the storage will be re-initialized from the static configuration each time storage.init() is called.

Static schema setup

Empty storage instance with pre-defined schemas. Entity persistance guarantee depends entirely on the provided entity changelog adapter. This setup most closely resembles classical RDBMS in the fact that schema changes would require code re-deployment and data changes would not.

import createStorage from '@navarik/storage'

const storage = createStorage({
  schema: [ ...list of pre-defined schemas... ],
  log: {
    schema: 'default',
    entity: myChangelogAdapterInstance
  }
})

storage.init()

Fully dynamic setup

Both, entity and schema persistance guarantee depends entirely on the given changelog adapter. The instance starts completely empty. Useful for multi-tenant services or user-controlled structured data storages.

import createStorage from '@navarik/storage'

const storage = createStorage({
  log: myChangelogAdapterInstance
})

storage.init()

Usage

import createStorage from '@navarik/storage'

const storage = createStorage()
storage.init()

async function main() {
  const schema = await storage.createSchema({
    name: 'test',
    fields: [
      { name: 'name', type: 'string' },
      { name: 'says', type: 'string' }
    ]
  })

  const entity = await storage.create('test', { name: 'doge', says: 'wow!' })

  console.log(entity)
}

main()

API

Factory & Configuration

Storage library's only export is factory function that is designed to generate storage instances based on provided configuration. Here are the configuratino options: schema: Array<Object> - provide static schemata in a form of an array of Avro-compatible schema definition JS objects. entity: Array<Object> - provide static entities in a form of an array of JS objects. log: 'default'|ChangeLogAdapter - global override for the change-log adapter log.schema: 'default'|ChangeLogAdapter - override for the schema change-log adapter log.entity: 'default'|ChangeLogAdapter - override for the entity change-log adapter index: 'default'|SearchIndexAdapter - global override for the local state's search index.schema: 'default'|SearchIndexAdapter - override for the schema search index adapter index.entity: 'default'|SearchIndexAdapter - override for the entity search index adapter

Instance API

init(): Promise<void> - initialize storage instance, read change-logs, re-generate search index. Usually this method is called once before any other API functions could be accessed.

isConnected(): boolean - returns true if all the adapters are connected and operational, false otherwize. Default in-memory adapters are always connected.

Schema management

getSchema: (name: string, [version: integer]): Promise<Schema> - returns schema for a given type name, undefined if no schema is found. Returns a specific version of the schema if version argument is provided, uses the latest version by default.

findSchema(filter: Object, [options: Object]): Promise<Array<Schema>> - looks for schemas that match provided filter. Supported search options: limit, offset. Returns empty array if there is no schemas matching the filter.

schemaNames(): Array<string> - returns a list of all registered entity types.

createSchema(body: Object): Promise<Schema> - registers new schema

updateSchema(name: string, body: Object): Promise<Schema> - updates existing schema

Entity management

get(id: string, [version: number, options = {}]): Promise<Entity> - fetches a single entity by its unique ID. Fetches a particular version if version argument is provided, otherwise uses the latest known version. Supported options: view ('brief' or 'canonical').

find(filter: Object, options: Object): Promise<Array<Entity>> - search for entities that match given filter. Supported search options: limit, offset, view ('brief' or 'canonical').

findContent(text: string, options: Object): Promise<Array<Entity>> - search for all the entities that have at least one field where the value includes given text. Supported options: view ('brief' or 'canonical').

count(filter: Object): Promise<number> - count the number of entities satisfying the given filter.

create(type: string, body: Object, options: Object): Promise<Entity> - create a new entity of a given type. Supported options: view ('brief' or 'canonical').

create(type: string, body: Array<Object>, options: Object): Promise<Array<Entity>> - bulk-create new entities of a given type. Supported options: view ('brief' or 'canonical').

update(id: string, body: Object, options: Object): Promise<Entity> - update existing entity. Supported options: view ('brief' or 'canonical').

validate(type: string, body: Object): string - validates given object against the schema of a given type and returns a string of discovered errors. Returns empty string.

isValid(type: string, body: Object): boolean - validates given object against the schema of a given type and returnd 'true' if the object is valid and 'false' otherwise.

observe(handler: (Entity) => void, [filter: Object]): void - give the system a callback to envoke on each entity change event. Optionally sets the filter allowing to trigger the callback only for matching entities.