YouBothAgent▾
You — Business rules and flows you own. Read these yourself.
Both — Know the idea; your agent follows the details.
Agent — Conventions and references your agent follows. Look up as needed.
Introduction▾
Tutorials▾
System Architecture▾
Module Convention▾
Scalar Convention▾
model.store.ts
The store file manages client-side state and synchronizes with the server via Signals. It extends the functionality of Zustand.
🏪Client State
Manages UI state, form data, and cached server data in a reactive way.
Store Class Structure
Stores are defined using the store() function, which binds a Signal (server syncing definition) and an initial state.
product.store.ts
State Interaction
Stores provide built-in methods to interact with the state safely.
methodDescription
get()
Get the current snapshot of the store state.
set(state)
Update the store state. Merges shallowly.
pick(...keys)
Select specific properties from the state. Guaranteed to be non-nullable (throws if null/undefined).
⚡Non-nullable Guarantee
The 'pick' method throws an error immediately if any of the requested keys are null or undefined. Use 'get' if you need to handle nulls manually.
Standard Model API (Base)
These states and actions are automatically generated for every Store bound to a Signal. They handle the basic CRUD and form operations for the single model instance.
2.1. Base State (Standard)
fieldDescription
st.<model>: Full | null
The single instance of the model.
st.<model>Loading: string | boolean
Loading status of the single instance.
st.<model>Form: Default
Form state for creating or updating.
st.<model>FormLoading: string | boolean
Loading status of the form.
st.<model>Submit: Submit
Start time of the latest submit.
st.<model>ViewAt: Date
Time when the detailed view was accessed.
st.<model>Modal: string | null
Modal ID associated with this model.
2.2. Base Actions (Standard)
methodDescription
create<Class>InForm(options?): Promise<void>
Create a document using form state.
update<Class>InForm(options?): Promise<void>
Update a document using form state.
create<Class>(data, options?): Promise<void>
Create a new document with data.
update<Class>(id, data, options?): Promise<void>
Update an existing document.
remove<Class>(id, options?): Promise<void>
Remove a document.
check<Class>Submitable(disabled?): Promise<void>
Check if the form can be submitted.
submit<Class>(options?): Promise<void>
Submit the form (create or update).
new<Class>(partial?, options?): void
Initialize form for new creation.
edit<Class>(model, options?): Promise<void>
Initialize form for editing.
merge<Class>(model, data, options?): Promise<void>
Merge data into existing document.
view<Class>(model, options?): Promise<void>
Open detailed view.
set<Class>(...models): void
Manually set model cache.
reset<Class>(model?): void
Reset model state.
Slice Auto-Generated Features
State and methods are generated based on Slices defined in model.signal.ts. This includes the 'Default Slice' (always available) and any custom slices.
3.1. Slice Definition (Signal)
product.signal.ts
3.2. Generated Slice State
Replace <Slice> with the capitalized slice name. For the default slice, usually the <Slice> suffix is essentially the model name.
fieldDescription
st.default<Class>: Default
Default value for the slice.
st.<slice>List: DataList<Light>
List of data loaded by init/refresh.
st.<slice>ListLoading: boolean
Loading status of the list.
st.<slice>InitList: DataList<Light>
Initial list snapshot.
st.<slice>InitAt: Date
Time when the list was initialized.
st.<slice>Selection: DataList<Light>
Selected items in the list.
st.<slice>Insight: Insight
Insight data for the list (e.g. counts).
st.lastPageOf<Slice>: number
Last accessed page number.
st.pageOf<Slice>: number
Current page number.
st.limitOf<Slice>: number
Items per page.
st.queryArgsOf<Slice>: QueryArgs
Current query arguments.
st.sortOf<Slice>: Sort
Current sort setting.
3.3. Generated Slice Actions
methodDescription
init<Slice>(...args): Promise<void>
Initialize list with query args.
refresh<Slice>(initForm?): Promise<void>
Reload list with strict consistency.
select<Slice>(model, options?): void
Update selection state.
setPageOf<Slice>(page, options?): Promise<void>
Change page and reload.
loadMoreOf<Slice>(options?): Promise<void>
Append the rows after the ones loaded.
setLimitOf<Slice>(limit, options?): Promise<void>
Change list limit and reload.
setQueryArgsOf<Slice>(...args): Promise<void>
Change query arguments and reload.
setSortOf<Slice>(sort, options?): Promise<void>
Change sort and reload.
Usage Patterns
There are two distinct ways to interact with the Store: inside the Store class itself, and from React Components.
4.1. Inside Store Class
Use 'this.get()' to access state and 'this.anyAction()' to call methods. Use 'this.set()' for updates.
Inside Store
4.2. Inside React Component
Use 'st.use.stateName()' hooks for reactive state access and 'st.do.actionName()' for invoking actions.
Inside Component
Auto-Generated Setters
When you define a state property, a corresponding setter method is automatically added to 'st.do'. You can also use 'st.set' directly.
Setter Examples
Other Stores (Global)
Since the Store is a single global instance, you can access state and actions from other stores. However, you must explicitly cast 'this' to 'RootStore' to satisfy TypeScript.
RootStore: A type that merges all Store definitions in the application.
product.store.ts
Store Best Practices
1️⃣Use 'pick' for State Access
Prefer 'pick' over 'get' when you only need specific fields. It makes dependencies explicit.
2️⃣Keep Async Logic in Store
UI-related async operations (fetching, submitting) belong in the Store. Pure business logic belongs in the Service.