Stores
Stores are objects that hold state (.item
, .items
, .itemsCount
, etc) and action functions that mutate state (.setItem()
, .setItems()
, .clearItems()
, etc).
Each collection has it store automatically generated in the runtime. It can be accessed with const personStore = useStore('person')
. Collection stores can also be extended to add state and functionality. To view all properties collection stores have, visit CollectionStore
const personStore = useStore('person')
// this action mutates the `.items` state
await personStore.$actions.getAll()
for( const people of personStore.items ) {
// const people: CollectionItemWithId<'person'>
console.log(people)
}
Types:
type StoreState = Record<string, unknown>
type Store = StoreState & {
$id: string
$actions: Record<string, (...args: unknown[])=> unknown>
$functions: Record<string, (...args: unknown[])=> unknown>
}
createStore()
createStore(fn: (context: StoreContext, config: unknown) => Store) => (context: StoreContext, config: unknown) => Store
This function creates a new store from a callback.
Example:
export myCustomStore = createStore(() => ({
state: {
counter: 0
},
actions: (state) => ({
increment() {
state.counter++
}
})
}))
createCollectionStore()
createCollectionStore(store: Store, context: StoreContext) => StorePrototype
It's not unusual to have to extend a store that was previously generated from a Description to add more state properties, actions, or getters. The createCollectionStore()
function does exactly that: it receives a Store
object and merges it into a new CollectionStore
object.
WARNING
The stores should follow a naming convention to make type inference work properly. Collections must be named-exported by ./stores
and have the same name as their collections.
Example:
export const employees = createStore((manager) => createCollectionStore({
$id: 'employees',
state: {
week_day: 1,
of_the_month: {},
},
getters: (state) => ({
weekDayName: () => {
return [
'sunday',
'monday',
'tuesday',
'wednesday',
'thursday',
'friday',
'saturday',
].at(state.week_day)
}
}),
actions: (state, actions) => ({
async getEmployeeOfTheWeek() {
const result = state.of_the_month = await actions.custom('getEmployeeOfTheWeek')
return result
}
})
}, manager))
useStore()
useStore(storeId: string) => Store
declare const useStore: (storeId: string, manager?: GlobalStateManager) => Store
Get's a store from it's name. Will throw an exception if the store is not found.
WARNING
useStore()
is meant to be called in Composition API, where dependency injection is available. If you want to use a store outside Composition API, consider declaring the store in Composition API then passing it as a parameter to your external function or passing the GlobalStateManager
parameter.
<script setup lang="ts">
import { myExternalFunction } from './utils'
// useStore() won't work outside components
const userStore = useStore('user')
const manager = getGlobalStateManager()
// myExternalFunction() hasn't access to provide/inject, so we pass userStore as a parameter
const fn1 = myExternalFunction(userStore)
// We can also pass the return of the function getGlobalStateManager and call useStore() with two
// parameters in our external function, like this: useStore('user', manager)
const fn2 = myExternalFunction(manager)
</script>
<template>
<aeria-button @click="fn1">fn1</aeria-button>
<aeria-button @click="fn2">fn2</aeria-button>
</template>
CollectionStore
Whenever you define a collection in the backend, it will be automatically reflected in a store in Aeria UI. Those are a special kind of store that contains states for inserting and retrieving items, pagination, collection metadata, and more, along with actions and a interface to interact with the collection endpoints.
item
TDocument
This property bears a document.
items
Array<TDocument>
This property bears a list of documents.
properties
TDescription['properties']
This property is a getter that computes to store.description.properties
.
$actions.get()
Will call $actions.store.$functions.get
and mutate store.item
with the retrieved document.
$actions.getAll()
Will call $actions.store.$functions.getAll
and mutate store.items
with the retrieved documents.
$actions.insert()
Will call $actions.store.$functions.insert
and mutate store.item
and store.items
with the retrieved document.
$actions.deepInsert()
Will call $actions.store.$functions.insert
recursively on each referenced collection present within the payload, and finally on the parent document, and then mutate store.item
and store.items
with the retrieved document.
$actions.remove()
Will call $actions.store.$functions.insert
and mutate store.item
and store.items
with the retrieved document.
$actions.removeAll()
Will call $actions.store.$functions.insert
and mutate store.item
and store.items
with the retrieved document.
$actions.useProperties()
(properties: Array<string>) => Record<string, CollectionProperty>
A helper function that will retrieved the specified properties from $actions.store.properties
. Example usage:
<aeria-form
v-bind="personStore.item"
:form="personStore.$actions.useProperties([
'name',
'age'
])"
></aeria-form>
$functions
Record<string, (...args: any[]) => any
This property is similar to $actions
, but contains a proxy object that maps to any endpoint of the collection, including custom and router-created ones, and won't produce any mutations in the state. Functions will return a Promise that will resolve to the response of the endpoint. For example:
const items = await personStore.$functions.getAll({})