0.1.5 • Published 6 months ago

@simple-persist/core v0.1.5

Weekly downloads
-
License
ISC
Repository
github
Last release
6 months ago

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 cookiestorage 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!

NamePackageDescription
@PersistControl()@simplepersist/angularDecorator for handling Angular forms.
@PersistSubject()@simplepersist/rxjsDecorator for handling RxJS Subjects & BehaviorSubjects.
ConsoleMiddleware@simplepersist/coreMiddleware for displaying values on the console. (Useful for debuging.)
CookieStoragecookiestorageStorage interface for cookies.
DateMiddleware@simplepersist/coreMiddleware for handling JavaScript Date objects.
JsonMiddleware@simplepersist/coreMiddleware 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.

0.1.5

6 months ago

0.1.4

7 months ago

0.1.3

7 months ago

0.1.2

7 months ago

0.1.1

7 months ago

0.1.0

7 months ago

0.0.6

7 months ago