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
The basket holds
<!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>