defineStore

Returns the app-wide reactive store called name, creating it on the first call. Available in every script and exported from @realmorg/realm.

defineStore<T extends object>(name: string, initial: T, options?: StoreOptions): T

interface StoreOptions {
  persist?: "local" | "session" | StorageAdapter;
}

interface StorageAdapter {
  get(key: string): string | null;
  set(key: string, value: string): void;
}
const cart = defineStore("cart", {
  items: [],
  get count() {
    return this.items.length;
  },
}, { persist: "local" });

Parameters

Parameter Type Default Meaning
name string required Store name, shared by the whole page
initial plain object required Initial state. Used only on the first call for this name
options.persist "local", "session" or StorageAdapter none Save the store after every change and restore it on creation

Returns the same reactive proxy for every call with the same name. Later calls ignore initial and options.

Persistence

Topic Behaviour
Key realm:<name>
Format JSON.stringify(store), written once on creation and again after every change (batched per microtask)
Restore On creation, each saved field that is a data property of initial is written to the store. Getter values are ignored
Corrupt data Logs Stored value for store "name" is not valid JSON and was ignored. and keeps initial
"local" / "session" localStorage / sessionStorage
Custom adapter Any object with synchronous get(key) and set(key, value), for example one backed by cookies or an in-memory Map

Sharing a store

Two components that call defineStore("cart", …) get the same object. To share one definition, put it in a module and import it:

// cart.js
import { defineStore } from "https://cdn.jsdelivr.net/npm/@realmorg/realm@alpha/dist/index.js";

export const cart = defineStore("cart", { items: [] }, { persist: "local" });

Use the same version for index.js (or realm.js) as the page uses to start REALM. Both files load the same runtime chunk, so the store is shared.

Example

Previewindex.htmlstore-add.htmlstore-count.html
Add an item

The basket holds items.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>defineStore demo</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@realmorg/realm@alpha/dist/realm.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@realmorg/ui@alpha/dist/theme.css">
  <script type="module" src="https://cdn.jsdelivr.net/npm/@realmorg/realm@alpha/dist/realm.js"></script>
</head>
<body>
  <import-element from="https://cdn.jsdelivr.net/npm/@realmorg/ui@alpha/components/button.html"></import-element>

  <import-element from="./store-add.html"></import-element>
  <import-element from="./store-count.html"></import-element>

  <store-add></store-add>
  <store-count></store-count>
</body>
</html>
<custom-element name="store-add">
  <script>
    const basket = defineStore("reference-basket", { items: [] });

    function add() {
      basket.items.push(`Item ${basket.items.length + 1}`);
    }
  </script>

  <ui-button onclick="add()">Add an item</ui-button>
</custom-element>
<custom-element name="store-count">
  <script>
    const basket = defineStore("reference-basket", { items: [] });
  </script>

  <p>The basket holds <slot name="#basket.items.length"></slot> items.</p>
</custom-element>

Edit this page on GitHub · View as Markdown