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

@simple-persist/core

v0.1.5

Published

Typescript decorator for persisting data in browser applications

Downloads

8

Readme

SimplePersist Core

TypeScript property decorator for easy client-side persistance

Table of Contents

Installation

npm install @simple-persist/core

Quick start

Add @Persist() decorator to any class property:

import { Persist } from '@simple-persist/core';

class Foo {
  @Persist() public bar;
}

Note: For more features (like persisting Angular forms or RxJS Subjects) check out our extensions!

Caveats

Multi-instance use

SimplePersist is best fit for singleton use. Class instances are not observed, meaning multiple instances of the same class can cause unexpected behavior:

const foo1 = new Foo();
foo1.bar = 'baz';

const foo2 = new Foo();
console.log(foo2.bar); // Displays 'baz'.

You can overcome this by writing your own keygen.

Types

By default SimplePersist can only persist scalars, as well as objects and arrays containing scalars. (Basically stuff that survives JSON.parse(JSON.stringify(value)).) You can overcome this by writing your own middleware to serialize & rehydrate your objects.

Storage

SimplePersist uses localStorage by default. You can switch to sessionStorage or use cookieStorage from cookie‑storage like so:

import { CookieStorage } from 'cookie-storage';

class Foo {
  @Persist({ storage: sessionStorage }) public bar;
  // or
  @Persist({ storage: new CookieStorage() }) public baz;
}

You can write your own storage too!

Advanced use

Imperative syntax

For imperative programming use the Persistor class:

import { Persistor, JsonMiddleware } from '@simple-persist/core';

const persistor = new Persistor<string>({
  keygens: [() => 'foo'],
  middlewares: [new JsonMiddleware()],
  storage: localStorage,
});

persistor.set('bar'); // Saves 'bar' as the value of 'foo' to storage.
persistor.get(); // Loads the value of 'foo' from storage.
persistor.delete(); // Deletes 'foo' from storage.

Note: All configuration options of Persistor are optionally available for @Persist() as well. Use the same syntax to define custom keygens, middlewares or storage for your decorator!

Keygens

By default @Persist() uses property names as key. This can easily become an issue:

class FooA {
  @Persist()
  public bar; // Persists as 'bar'.
}
class FooB {
  @Persist()
  public bar; // Persists as 'bar' too, which creates conflict. :(
}

You can use a custom keygen to overcome this issue. Keygens are functions that modify the default key:

class FooA {
  @Persist({ keygens: [() => 'FooA.bar'] })
  public bar; // Persists as 'FooA.bar'.
}
class FooB {
  @Persist({ keygens: [() => 'FooB.bar'] })
  public bar; // Persists as 'FooB.bar'.
}

Alternatively:

class FooA {
  @Persist({ keygens: [(key) => `FooA.${key}`] })
  public bar; // Persists as 'FooA.bar'.
}
class FooB {
  @Persist({ keygens: [(key) => `FooB.${key}`] })
  public bar; // Persists as 'FooB.bar'.
}

Note: If you set up multiple keygens, they will be chained by SimplePersist.

You can write your own keygen by implementing the Keygen interface.

Middlewares

SimplePersist can encode values before saving them to storage. This happens by utilizing a middleware. Middlewares consist of two methods: encode and decode.

As an example, take a look at the built-in JsonMiddleware. (This is the default middleware when using @Persist().)

import { Middleware } from '@simple-persist/core';

export class JsonMiddleware implements Middleware<any, string> {
  public encode(value: any): string {
    return JSON.stringify(value);
  }

  public decode(value: string | null | undefined): any | null | undefined {
    return value && JSON.parse(value);
  }
}

These methods are run automatically by SimplePersist. encode() will be called before saving to storage, decode() will be called after loading from storage.

Note: If you set up multiple middlewares, encoders will be chained in the defined order, decoders in reverse order.

Write your own middleware by implementing the Middleware interface or use an extension!

Storages

The native localStorage and sessionStorage (from the global scope) are compatible with SimplePersist by design:

class Foo {
  @Persist({ storage: sessionStorage }) public bar;
}

You can also write your own storage wrapper by implementing the native Storage interface or use an extension.

Extensions

We have you covered for some of the common use cases. Check out these extensions and let me know if you miss anything!

| NamePackage | Description | |:---|:---| | @PersistControl()@simple‑persist/angular | Decorator for handling Angular forms. | | @PersistSubject()@simple‑persist/rxjs | Decorator for handling RxJS Subjects & BehaviorSubjects. | | ConsoleMiddleware@simple‑persist/core | Middleware for displaying values on the console. (Useful for debuging.) | | CookieStoragecookie‑storage | Storage interface for cookies. | | DateMiddleware@simple‑persist/core | Middleware for handling JavaScript Date objects. | | JsonMiddleware@simple‑persist/core | Middleware for encoding to & from JSON. (Default when using @Persist().) |

Read more

Check out my article about the reasoning behind this package: Do we need state management in Angular?

Collaboration

Feel free to suggest features, open issues, or contribute! Also let me know about your extensions, so I can link them in this document.