svelte-keyed

A writable derived store for objects and arrays

Usage no npm install needed!

<script type="module">
  import svelteKeyed from 'https://cdn.skypack.dev/svelte-keyed';
</script>

README

svelte-keyed-banner

svelte-keyed

npm version npm downloads license build coverage size

A writable derived store for objects and arrays!

const user = writable({ name: { first: 'Rich', last: 'Harris' } });
const firstName = keyed(user, 'name.first');

$firstName = 'Bryan';

console.log($user); // { name: { first: 'Bryan', last: 'Harris' } };

Installation

$ npm i -D svelte-keyed

Since Svelte automatically bundles all required dependencies, you only need to install this package as a dev dependency with the -D flag.

API

keyed takes a writable object store and a keypath, and returns a writable store whose changes are reflected on the original store.

Nullable parents

If the parent store is nullable, then the child store will also be nullable.

const user = writable<User | undefined>(undefined);
const firstName = keyed(user, 'name.first'); // string | undefined

Nested objects

To access a nested object, provide a keypath.

Properties are accessed with dot notation, and arrays can be indexed with bracket notation.

const email = keyed(settings, 'profiles[0].email');

Motivations

We usually read and write properties of an object store with auto-subscriptions.

<input bind:value={$name.first}/>

However, auto-subscriptions are isolated to a Svelte component. svelte-keyed aims to solve several common limitations listed below.

Context stores

Often, we want to set a property or element of a store into component context, then allow child components to read / write to the property.

<!-- Settings.svelte -->
<script>
  setContext('profileSettings', keyed(settings, 'profile'));
</script>

<GeneralSettings />
<ProfileSettings />
<!-- ProfileSettings.svelte -->
<script>
  const profileSettings = getContext('profileSettings');
</script>

<input type="text" bind:value={$profileSettings.username} />

Helper functions

One important method to reduce clutter on your component is to extract functionality into external helper functions. svelte-keyed allows you to create derived Writable stores that can be passed into or returned from helper functions.

<!-- Settings.svelte -->
<script>
  const stats = writable({ userClicks: 0, userTaps: 0 });
  const clicks = keyed(stats, 'userClicks');
</script>

<div use:trackClicks={clicks} />
<input use:trackClicks={clicks} />
export const trackClicks = (node, clicks) => {
    const listen = () => {
        clicks.update(($clicks) => $clicks + 1);
    };
    node.addEventListener('click', listen);
    return {
        destroy() {
            node.removeEventListener('click', listen);
        },
    };
};