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

json-repo

v1.2.4

Published

Read and write data to JSON files using the repository pattern.

Downloads

6

Readme

Json File Repository - IoT Shaman

npm badge Build Status Coverage Status

In-memory repository with Json file persistence.

Sometimes as developers we have the need to store and retrieve persistent data, but dont need all the power that comes with a traditional data persistence solution. The Json File Repository (json-repo) is an in-memory data repository that conveniently persists data to a Json file, anywhere on the host device. This allows applications to receive the benefits of a repository abstraction, without having to model, provision and connect to, say, a SQL database. When you initialize an implementation of the repository, it will load any data located in the provided file path (if it exists), and when you make changes to the repository simply call "saveChanges()" to persist the data into the Json file.

Requirements

  • Node JS
  • Typescript

Installation

npm install json-repo --save

Quick Start

Getting started with json-repo is really quick and simple. First, create an a model to provide types for the data we are going to store: For example:

//file: foo.ts
export class Foo {
  bar: string;
}

Next, we need to create an implementation of the base "RepositoryContext" class:

//file: sample-context.ts
import { RepositoryContext, Repository } from 'json-repo';
import { Foo } from './foo';

export class SampleDataContext extends RepositoryContext {
  constructor(dataPath: string) { super(dataPath); }
  models = {
    baz: new Repository<Foo>()
  }
}

Finally, we need to initialize the context in our application:

import * as path from 'path';
import { SampleDataContext } from './sample-context';
import { Foo } from './foo';

const jsonFilePath = path.join(__dirname, 'db.json');
let context = new SampleDataContext(jsonFilePath);
context.initialize().then(_ => {
  //you can now use the context
  let foo = new Foo(); foo.bar = 'baz';
  context.models.baz.add('1', foo);
  return context.saveChanges();
});

API Reference

The below information describes how to use the built-in features of json-repo.

RepositoryContext

The "RepositoryContext" is an abstract class that allows you to communicate with various repositories. All repositories in a given implementation will store their data in the same JSON file. The RepositoryContext takes 2 optional arguments in its constructor, that allow you to configure its behavior.

//provided from the repository-context.d.ts file
export declare abstract class RepositoryContext {
  abstract models: {
    [key: string]: IRepository<any>;
  };
  constructor(dataPath?: string, entityNodeService?: IEntityNodeService);
  initialize: () => Promise<void>;
  saveChanges: () => Promise<void>;
}
  • models: the models property stores a collection of repository objects. These repository objects represent your domain objects. Each value in models is a key value pair, with the key being the common name of the domain object, and the value being an implementation of the Repository class, with the generic argument set to the typed class of your domain model.

  • constructor: the dataPath argument, when provided, tells the repository context where the data file is; when not provided, the repository context will be in-memory only, and as such will not persist the data. The entityNodeService object allows you to provide a custom implementation of IEntityNodeService, which gives you additional control over how and where you persist data; to use the built-in JSON file persistence, do not provide a value for entityNodeService.

  • initialize: the initialize method will look for any data in the persistent storage layer and load it into memory. If no data is found, the repository context will initialize each repository with a blank array. If a new repository was added and does not yet exist in persistent storage, that repository will be initialized with a blank array.

  • saveChanges: saveChanges will ask the persistent storage layer to store the contents of the repository. If there was no data path provided to the constructor, or nothing has changed in the repositories, this will be a noop.

Repository

The "Repository" interface is defined as a generic, with the type argument representing a domain object. Some built-in methods are provided to manage and query the repository. The default implementation of IRepository is Repository, and can also be extended if you wish to provide additional functionality.

//provided from the repository.d.ts file
export declare class Repository<T> {
  get state(): string;
  protected _state: string;
  protected data: {
      [key: string]: T;
  };
  load: (data: EntityNode[]) => void;
  extract: () => EntityNode[];
  find: (key: string) => T;
  filter: (filter: (item: T) => boolean) => T[];
  add: (key: string, item: T) => void;
  addRange: (items: [{key: string, item: T}]) => void;
  update: (key: string, action: (item: T) => T) => void;
  delete: (key: string) => void;
  markCurrent: () => void;
}

EntityNode

An "EntityNode" is the core persistent storage block of a repository. When files are written to and read from the persistent storage layer, EntityNode objects are what is used. Entity nodes are simply key value pairs, where the key represents a unique key to store and retrieve data, and a value which contains the concrete domain object. For most implementations, you will never use the EntityNode object, but it can be useful if you are extending the repository class, or needing to wipe or reload the entire repository.

//provided from the entity-node.d.ts file
export declare class EntityNode {
  key: string;
  value: any;
}

IEntityNodeService

The implementation of "IEntityNodeService" acts as the persistent storage layer, reading to and writing from some storage mechanism. The built-in implementation of IEntityNodeService is calls "JsonFileService", and is provided by default to all "RepositoryContext" objects. If you wish to provide a custom data persistence solution, you can achieve this by creating a custom implementation of IEntityNodeService.

//provided from the entity-node-service.d.ts file
export interface IEntityNodeService {
  getEntityNodes(path: string): Promise<{[model: string]: EntityNode[];}>;
  persistEntityNodes<T>(path: string, data: T): Promise<void>;
}