MCPcopy Index your code
hub / github.com/MacFJA/svelte-persistent-runes

github.com/MacFJA/svelte-persistent-runes @1.1.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release 1.1.0 ↗ · + Follow
23 symbols 56 edges 7 files 0 documented · 0%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Svelte persistent runes

A Svelte reactive rune that keep its value through pages and reloads

GitHub Repo stars NPM bundle size Download per week License NPM version Checked with Biome

[ D E M O ]

Installation

With NPM

npm install --save-dev @macfja/svelte-persistent-runes
# or
yarn add --save-dev @macfja/svelte-persistent-runes
# or
pnpm add --save-dev @macfja/svelte-persistent-runes
# or
deno install --dev npm:@macfja/svelte-persistent-runes

Quickstart

Update your ./svelte.config.js to add a new preprocessor:

 import adapter from '@sveltejs/adapter-auto';
+import persist from "@macfja/svelte-persistent-runes/preprocessor"
 const config = {
+   preprocess: [persist()],
    kit: {
        adapter: adapter()
    }
 };
 export default config;

Replace your $state with $persist:

 <script>
+import "@macfja/svelte-persistent-runes"
-let count = $state(0);
+let count = $persist(0, 'counter');
 </script>

Usage

This library have 2 parts: - A preprocessor to add the $persist rune (and optionally a Vite plugin). - A set of configuration to persist your data.

You MUST add the preprocessor to use $persist. It's as simple as to add it in your Svelte configuration (svelte.config.js) with the import of @macfja/svelte-persistent-runes/plugins

./svelte.config.js

import adapter from '@sveltejs/adapter-auto';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
import { persistPreprocessor } from "@macfja/svelte-persistent-runes/plugins"

/** @type {import('@sveltejs/kit').Config} */
const config = {
    preprocess: [vitePreprocess(), persistPreprocessor()],
    kit: {
        adapter: adapter()
    }
};

export default config;

[!IMPORTANT] If you are using *.svelte.js/*.svelte.ts file you need to also add a Vite plugin:

./vite.config.ts

```ts import { sveltekit } from '@sveltejs/kit/vite'; import { defineConfig } from 'vite'; import { persistPlugin as persist } from "@macfja/svelte-persistent-runes/plugins";

export default defineConfig({ plugins: [persist(), sveltekit()] }); ```

Now that the preprocessor is added, you can use the $persist rune instead of the $state rune.

./src/anywhere/component.svelte

<script>
import "@macfja/svelte-persistent-runes"
let count = $persist(0, 'counter');
</script>



    <button onclick={() => (count -= 1)} aria-label="Decrease the counter by one">-</button>


<strong>{count}</strong>


    <button onclick={() => (count += 1)} aria-label="Increase the counter by one">+</button>



./src/anywhere/data.svelte.ts

import "@macfja/svelte-persistent-runes"
export class Person {
    name = $persist('John', 'user-name')
    age = $persist(33, 'user-age')

    greet(): string {
        return `Hello ${this.name}`;
    }
    birthday(): string {
        this.age += 1;
        return `Happy birthday ${this.name}!`
    }
}
export const currentUser = new Person()

[!IMPORTANT] You need to import import "@macfja/svelte-persistent-runes" to prevent Typescript to complain about the unknown function $persist


You can add this import in an ambient Typescript Module (like ./src/app.d.ts in SvelteKit), and you won't need to import it in every file

Definition

type PersistentRunesOptions = {
    /**
     * Convert the source data into its string representation
     * @param input The source data
     * @return The string representation of data
     */
    serialize<T>(input: T): string;
    /**
     * Convert back the string representation into the source data
     * @param input The string representation of the date
     * @return The new data based on its string representation
     */
    deserialize<T>(input: string): T;
    /**
     * Write data into the store
     * @param key The storage key to write
     * @param value The data to write
     */
    storageWrite(key: string, value: string): void;
    /**
     * Read data from the storage
     * @param key The storage key to read
     * @returns The data or `undefined` if the data don't exist in the storage
     */
    storageRead(key: string): string | undefined;
};

/**
 * A reactive state, that can restore its state upon page reload
 * @param initial The initial value of the state
 * @param key The storage key of the state. Must be unique in your application
 * @param options The persistence options (how and where)
 */
declare function $persist<T>(initial: T, key: string, options?: Partial<PersistentRunesOption>)

Options

You can customize how and where the state value is persisted.

The $persist runes take a third (and optional) parameter of type PersistentRunesOption.

The options consist of 2 main part: the serializer and the storage. It can be defined as a plain object or as the result of the buildOptions (impoerted from @macfja/svelte-persistent-runes/options)

/**
 * Create a `PersistentRunesOptions` from a serializer and a storage
 * @param serializer The serializer to use (if `undefined` then `JsonSerializer` will be used)
 * @param storage The storage to use (if `undefined` then `BrowserLocalStorage` will be used)
 */
declare function buildOptions(
    serializer: PersistentRunesSerializer | undefined, 
    storage: PersistentRunesStorage | undefined
): PersistentRunesOptions;

The serializer

The serializer part of the option are: - serialize: This function is responsible for converting the original type into a string - deserialize: This function is responsible to convert back a string to the original type

The library have several built-in serializer: - JsonSerializerFactory: factory to create a JSON based serializer - JsonSerializer: A basic JSON serializer (no replacer, nor reviver) - DevalueSerializerFactory: factory to create a Devalue based serializer - DevalueSerializer: A basic Devalue serializer (no reducers, nor revivers) - ESSerializerSerializerFactory: factory to create a ESSerializer based serializer - ESSerializerSerializer: A basic ESSerializer serializer (no SerializeOptions, nor classes) - MacfjaSerializerFactory: factory to create a @macfja/serializer based serializer - MacfjaSerializer: A basic @macfja/serializer serializer (no additional classes mapping) - SuperJsonSerializer: A superjson serializer - NextJsonSerializerFactory: factory to create a next-json based serializer - NextJsonSerializerFactory: A basic next-json serializer (no options, nor replacers, nor revivers) - PhpSerializeSerializerFactory: factory to create a php-serialize based serializer - PhpSerializeSerializer: A basic php-serialize serializer (no options) - SerializeAnythingSerializerFactory: factory to create a serialize-anything based serializer - SerializeAnythingSerializer: A basic serialize-anything serializer (no options)

The storage

The storage part of the option are: - storageWrite: This function is responsible to write data into the storage - storageRead: This function is responsible to read data from the storage

The library have several built-in storage: - BrowserCookieStorageFactory: factory to create a Cookie based storage (DOM API, browser only) - BrowserCookieStorage: A basic Cookie storage (no particular options, except for samesite: Strict) - BrowserLocalStorage: a browser localStorage storage (DOM API, browser only) - BrowserSessionStorage: a browser sessionStorage storage (DOM API, browser only) - addEncryptionStorage: a wrapper function to add AES GCM encryption on stored data

Example

Browser session storage and @macfja/serializer

<script>
import "@macfja/svelte-persistent-runes"
import {
    buildOptions,
    MacfjaSerializer,
    BrowserSessionStorage
} "@macfja/svelte-persistent-runes/options"
let count = $persist(0, 'counter', buildOptions(MacfjaSerializer, BrowserSessionStorage));
</script>



    <button onclick={() => (count -= 1)} aria-label="Decrease the counter by one">-</button>


<strong>{count}</strong>


    <button onclick={() => (count += 1)} aria-label="Increase the counter by one">+</button>



Browser local storage, encrypted and SuperJson

<script>
import "@macfja/svelte-persistent-runes"
import {
    buildOptions,
    SuperJsnoSerializer,
    BrowserLocalStorage,
    addEncryptionStorage
} "@macfja/svelte-persistent-runes/options"
let count = $persist(0, 'counter', buildOptions(
    SuperJsnoSerializer,
    addEncryptionStorage(BrowserLocalStorage, '12345678901234567890123456879012')
);
</script>



    <button onclick={() => (count -= 1)} aria-label="Decrease the counter by one">-</button>


<strong>{count}</strong>


    <button onclick={() => (count += 1)} aria-label="Increase the counter by one">+</button>



Core symbols most depended-on inside this repo

Shape

Function 23

Languages

TypeScript100%

Modules by API surface

src/serializer-factory.ts9 symbols
src/options.ts7 symbols
src/plugins.ts5 symbols
src/index.ts2 symbols

For agents

$ claude mcp add svelte-persistent-runes \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page