/svelte

A tiny (179 bytes) connector for Storeon and Svelte

Primary LanguageJavaScriptMIT LicenseMIT

Storeon Svelte

npm version Build Status

Storeon logo by Anton Lovchikov

Svelte is the smallest JS framework, but even so, it contains many built-in features. One of them is a svelte/store. But why we need to use a third-party store? @storeon/svelte has several advantages compared with the built-in one.

  • Size. 179 bytes (+ Storeon itself) instead of 485 bytes (minified and gzipped).
  • Ecosystem. Many additional tools can be combined with a store.
  • Speed. Bind components to the changes in the exact store that you need.

Install

npm install -S @storeon/svelte

or

yarn add @storeon/svelte

How to use (Demo)

Create store using storeon module:

store.js

import { createStoreon } from 'storeon'

let counter = store => {
  store.on('@init', () => ({ count: 0 }))
  store.on('inc', ({ count }) => ({ count: count + 1 }))
}

export const store = createStoreon([counter])

Using TypeScript you can pass State and Events interface to the createStoreon function:

store.ts

import { StoreonModule, createStoreon } from 'storeon'

interface State {
  count: number
}

interface Events {
  'inc': undefined
  'set': number
}

let counter = (store: StoreonModule<State, Events>) => {
  store.on('@init', () => ({ count: 0 }))
  store.on('inc', ({ count }) => ({ count: count + 1 }))
  store.on('set', (_, event) => ({ count: event}))
};

export const store = createStoreon<State, Events>([counter])

App.svelte

Provide store to Svelte Context using provideStoreon from @storeon/svelte

<script>
  import { provideStoreon } from '@storeon/svelte'
  import { store } from './store'
  import Counter from './Counter.svelte'

  provideStoreon(store)
</script>

<Counter />

Import useStoreon function from our @storeon/svelte module and use it for getting state and dispatching new events:

Child.svelte

<script>
  import { useStoreon } from '@storeon/svelte';

  const { count, dispatch } = useStoreon('count');

  function increment() {
    dispatch('inc');
  }
</script>

<h1>The count is {$count}</h1>

<button on:click={increment}>+</button>

Using typescript you can pass State and Events interfaces to useStoreon function to be full type safe

<script lang="typescript">
  import { useStoreon } from '@storeon/svelte';
  import { State, Events } from './store'

  const { count, dispatch } = useStoreon<State, Events>('count');

  function increment() {
    dispatch('inc');
  }
</script>

<h1>The count is {$count}</h1>

<button on:click={increment}>+</button>

Usage with @storeon/router

If you want to use the @storeon/svelte with the @storeon/router you should import the router.createRouter from @storeon/router and add this module to createStoreon

store.js

import { createStoreon } from 'storeon'
import { createRouter } from '@storeon/router';

const store = createStoreon([
  createRouter([
    ['/', () => ({ page: 'home' })],
    ['/blog', () => ({ page: 'blog' })],
  ])
])

And use it like:

App.svelte

<script>
  import { provideStoreon } from '@storeon/svelte'
  import { store } from './store'
  import Counter from './Child.svelte'

  provideStoreon(store)
</script>

<Counter />

Child.svelte

<script>
  import { useStoreon } from '@storeon/svelte';
  import router from '@storeon/router'

  const { [router.key]: route } = useStoreon(router.key)
</script>

You can access the router like default svelte store via $:
{$route.match.page}