Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/chanced/classy-store

class based stores for svelte
https://github.com/chanced/classy-store

state-management stores svelte typescript

Last synced: 3 months ago
JSON representation

class based stores for svelte

Awesome Lists containing this project

README

        

# classy-store

class stores for svelte.

## Usage

```bash
npm i classy-store

# yarn add classy-store
```

You must enable `experimentalDecorators` in your tsconfig to use the `@mutator` decorator.

### Define a store

```typescript
import { mutator, Store } from "classy-store";
export class Spike extends Store {
name: string;
count: number;
constructor(name: string, count?: number) {
super();
this.name = name;
this.count = count ?? 0;
}
@mutator
inc(n = 1) {
this.count = this.count + n;
return this.count;
}

@mutator
async delayed() {
await new Promise((res) => setTimeout(res, 500));
this.count + 100;
}
}
```

### Use the store

```html

import { Spike } from '$lib/spike';
let spike = new Spike('this is a store');

Hello {$spike.name}

Bindings

Using @mutator allows for methods:


$spike.inc()}>{$spike.count}

methods can be promises:


{ $spike.delayed(); }}>level up
```

#### @mutator

`@mutator` is a wrapper around your method which executes `store.broadcast` after your method is finished altering the store's state.

- If your method returns a `Promise`, `broadcast` is called immediately and again when the promise is resolved or rejected.
- If a `Promise` is returned, `executing[methodName]` is set to `Execution.Running`.
- If the `Promise` resolves successfully, `executing[methodName]` is set to `Execution.Resolved`.
- If the `Promise` is rejected, `executing[methodName]` is set to `Execution.Rejected`
- If the `Promise` is rejected, an `"error"` event is emitted with the reason.

```html

import { Spike } from '$lib/spike';
import { Execution } from 'classy-store'
let spike = new Spike('this is a store');
let disabled = false
$: disabled = $spike.executing.delayed === Execution.Running

{$spike.count}
```

#### errors

The default error handler stores `_errors` in a queue on your store.
The max size a configurable by setting `maxErrorsToStore` on `Options`
passed to the `Store` constructor.

#### Derived stores

The stores can be derived:

```html

import { Spike } from "$lib/spike";
import { derived } from "svelte/store";
let spike = new Spike("this is a store");
const screaming = derived(spike, ($spike) => $spike.name.toUpperCase());

hello {$screaming}

```

#### Custom Events
The stores are event emitters although more work is needed on that front.

If you wish to emit custom events, type your store such as:

```typescript
interface MyEvents {
example: (value: string) => void;
}

class Spike extends Store {
constructor() {
super();
this.emit("example", "example should be typed");
}
}
```
#### Partial updates

You can update the store with a new instance or a partial of the fields:

```html

import { Spike } from "$lib/spike";
let spike = new Spike("this is a store");

Hello {$spike.name}


{ $spike.set({name:"..."})}}>
```

## Notes

Please feel free to create an issue for any question, feedback or bug you encounter.

### Example REPL

A [very simple javascript REPL is available here](https://svelte.dev/repl/585cbc7da2554a578a1f4d7661116bd0?version=3.41.0).

### Dependencies

- [typed-emitter](https://github.com/andywer/typed-emitter)
- [events](https://github.com/browserify/events)

## TODO:

- better name
- tests
- better docs

## License
MIT