# @simple-persist/core

> Typescript decorator for persisting data in browser applications

Latest version **0.1.5** (published 2023-10-27) · ISC license · 0 weekly downloads

## Install

```sh
npm install @simple-persist/core
pnpm add @simple-persist/core
yarn add @simple-persist/core
bun add @simple-persist/core
```

## Health

**Score 30/100 (F)** — status: abandoned.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.1.5 |
| Published | 2023-10-27 |
| First published | 2023-10-10 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 0 |
| Unpacked size | 62.6 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 2 |
| Author | Balazs Kovacs |
| Maintainers | kobalazs |
| Keywords | persist, storage, decorator, declarative |

## Links

- npm: https://www.npmjs.com/package/@simple-persist/core
- Repository: https://github.com/kobalazs/simple-persist-core
- Homepage: https://github.com/kobalazs/simple-persist-core#readme
- Issues: https://github.com/kobalazs/simple-persist-core/issues
- npm.io page: https://npm.io/package/@simple-persist/core

## Alternatives

- [localforage](https://npm.io/package/localforage.md) — 6.2M weekly downloads
- [localforage-observable](https://npm.io/package/localforage-observable.md) — 30.8K weekly downloads
- [@y/y](https://npm.io/package/@y/y.md) — 30.1K weekly downloads
- [@metaobjectsdev/render](https://npm.io/package/@metaobjectsdev/render.md) — 3.5K weekly downloads
- [@ledgerhq/coin-algorand](https://npm.io/package/@ledgerhq/coin-algorand.md) — 1.1K weekly downloads

## Recent versions

- 0.1.5 (latest) — 2023-10-27
- 0.1.4 — 2023-10-19
- 0.1.3 — 2023-10-14
- 0.1.2 — 2023-10-13
- 0.1.1 — 2023-10-13
- 0.1.0 — 2023-10-12
- 0.0.6 — 2023-10-10

## README

# SimplePersist Core
TypeScript property decorator for easy client-side persistance

#### Table of Contents
* [Installation](#installation)
* [Quick start](#quick-start)
* [Caveats](#caveats)
  * [Multi-instance use](#multi-instance-use)
  * [Types](#types)
  * [Storage](#storage)
* [Advanced use](#advanced-use)
  * [Imperative syntax](#imperative-syntax)
  * [Keygens](#keygens)
  * [Middlewares](#middlewares)
  * [Storages](#storages)
* [Extensions](#extensions)
* [Read more](#read-more)
* [Collaboration](#collaboration)

## Installation
```bash
npm install @simple-persist/core
```

## Quick start
Add `@Persist()` decorator to any class property:
```ts
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](#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:
```ts
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](#keygens).

### 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](#middlewares) to serialize & rehydrate your objects.

### Storage
SimplePersist uses `localStorage` by default. You can switch to `sessionStorage` or use `cookieStorage` from [cookie&#8209;storage](https://www.npmjs.com/package/cookie-storage) like so:
```ts
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](#storages) too!

## Advanced use

### Imperative syntax
For imperative programming use the `Persistor` class:
```ts
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:
```ts
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:
```ts
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:
```ts
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()`.)
```ts
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](#extensions)!

### Storages
The native `localStorage` and `sessionStorage` (from the global scope) are compatible with SimplePersist by design:
```ts
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).

## Extensions
We have you covered for some of the common use cases. Check out these extensions and [let me know](https://github.com/kobalazs) if you miss anything!

| Name<br>Package  | Description  |
|:---|:---|
| **@PersistControl()**<br>[@simple&#8209;persist/angular](https://www.npmjs.com/package/@simple-persist/angular)  | Decorator for handling Angular forms.  |
| **@PersistSubject()**<br>[@simple&#8209;persist/rxjs](https://www.npmjs.com/package/@simple-persist/rxjs)  | Decorator for handling RxJS Subjects & BehaviorSubjects.  |
| **ConsoleMiddleware**<br>@simple&#8209;persist/core  | Middleware for displaying values on the console. (Useful for debuging.)  |
| **CookieStorage**<br>[cookie&#8209;storage](https://www.npmjs.com/package/cookie-storage)  | Storage interface for cookies.  |
| **DateMiddleware**<br>@simple&#8209;persist/core  | Middleware for handling JavaScript Date objects.  |
| **JsonMiddleware**<br>@simple&#8209;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?](https://medium.com/@kobalazs/do-we-need-state-management-in-angular-baf612823b16)

## Collaboration

Feel free to [suggest features](https://github.com/kobalazs), [open issues](https://github.com/kobalazs/simple-persist-core/issues), or [contribute](https://github.com/kobalazs/simple-persist-core/pulls)! Also let me know about your extensions, so I can link them in this document.

---
_Source: https://npm.io/package/@simple-persist/core · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
