-
-
Notifications
You must be signed in to change notification settings - Fork 0
Forms State And Data
Status: Implemented across @effuse/use, @effuse/store, and
@effuse/query. Compatibility remains experimental.
useForm creates reactive field values, errors, validity, submission state,
and validation behavior.
const form = useForm({
initialValues: { email: '' },
validate: {
email: [required(), email()],
},
onSubmit: async (values) => {
await register(values);
},
});Use labels, native controls, and explicit error output in templates. Server validation should be mapped into the same field/error model rather than stored in unrelated component state.
@effuse/store provides reactive state, selectors, slices, actions, async
actions, cancellation, persistence-related hooks, and Effect-based execution.
const cart = createStore('cart', {
items: [] as CartItem[],
add(item: CartItem) {
this.items.value = [...this.items.value, item];
},
});For capability-owned state, expose the store through a layer service or derived props. Components should bind to the layer rather than rely on ambient string lookup as the primary architecture.
@effuse/query provides query clients, caches, observers, retries, mutations,
infinite queries, query options, key factories, and reactive cache metadata.
const users = useQuery({
queryKey: ['users'],
queryFn: () => fetch('/api/users').then((r) => r.json()),
});Server state belongs in query caches; durable application commands and capabilities belong in layers. A query can call a manifest client instead of hard-coding a URL.
@effuse/i18n supports typed translations, locale state, nested keys,
interpolation, and pluralization. Install its runtime once and consume
translations through the package hooks or an application layer boundary.
@effuse/ink renders reactive Markdown and supports mapped Effuse components.
Treat Markdown input as content, and apply an application security policy when
content is not trusted.