Store
Share global UI state with a built-in store.
Built-in file type Store
- The default export object in app/stores/<name>.store.ts is registered as store.<name> with the same name.
- Store also recognizes subfolders recursively. Folders are for organizing purposes. File names must be unique across app/stores.
- The state and functions that change the state are placed in one file, and there is no need for separate import, reactive, or state management packages.
- The store file uses an English variable name and is placed directly under app/stores.
- A function can read and change the state of the same module as this.
- Generated store types provide autocomplete directly in Cake20 View TSX.
// app/stores/cart.store.ts
type CartItem = {
id: string;
name: string;
price: number;
count: number;
};
export const config = {
// "none": Until refresh |"session": Up to current tab |"local": Remains even if you close the browser
persist: "local"
} as const;
export default {
items: [] as CartItem[],
add(item: Omit<CartItem, "count">) {
const found = this.items.find((row) => row.id === item.id);
if (found) {
found.count++;
return;
}
this.items.push({ ...item, count: 1 });
},
remove(id: string) {
this.items = this.items.filter((item) => item.id !== id);
},
clear() {
this.items = [];
}
};Used in Cake20 View
- store is used in all Cake20 View pages, layouts, and components without import.
- State is reactive, so reading it directly or changing it with a function updates the screen immediately.
- Since it is a browser UI-only interface, it is not used in server code such as API, Task, or Job.
export const computed = {
total: () =>
store.cart.items.reduce(
(sum, item) => sum + item.price * item.count,
0
)
};
export const addCake = () => {
store.cart.add({
id: "strawberry",
name: "strawberry cake",
price: 32000
});
};
export default () => (
<>
<Button onClick={addCake}>Add to cart</Button>
<p>{store.cart.items.length} items · {computed.total().toLocaleString()} won</p>
</>
);Storage method
- Currently, the only item that can be set in store config is persist.
- none is memory, session is sessionStorage, local is localStorage, and the state of the module is stored as JSON.
- Omitting config or persist will only keep the current page in memory, like persist: "none".
- The stored values are merged into the default state at startup, so functions declared in the file are preserved.
- The local module automatically synchronizes changes made in other tabs of the same website.
- The test address and operation address have different origins, so their saved states are not mixed.
- The UI preview in the manager also separates the storage area into the base path for each website.
- Functions, circular references, and values that cannot be expressed in JSON are not used for storage.
- Authentication tokens, passwords, secrets and sensitive information are not stored in the store. Login uses the HttpOnly cookie of server auth.
// Persist after closing and reopening the browser
export const config = { persist: "local" } as const;
// Keep current tab until you close it
export const config = { persist: "session" } as const;
// Maintained only in memory and reset when refreshed
export const config = { persist: "none" } as const;
// Reset one or all modules to default values
store.$reset("cart");
store.$reset();