Components
Client and server building blocks when using Drizzleasy.
Client Hook: useOptimisticCrud
'use client'
import { useOptimisticCrud, createFn } from '@remcostoeten/drizzleasy'
type TTodo = { id: string; title: string; completed: boolean }
type TProps = { initialTodos: TTodo[] }
export function TodoList(props: TProps) {
const { data, isPending, optimisticCreate } = useOptimisticCrud<TTodo>(props.initialTodos)
const create = createFn<TTodo>()
function handleCreate(formData: FormData) {
const title = String(formData.get('title') || '')
optimisticCreate({ title, completed: false }, function onCreate() {
return create('todos')({ id: crypto.randomUUID(), title, completed: false })
})
}
return (
<form action={handleCreate}>
<input name="title" placeholder="Add todo" />
<button disabled={isPending}>{isPending ? 'Adding…' : 'Add'}</button>
</form>
)
}Transitions: withTransition
'use client'
import { withTransition } from '@remcostoeten/drizzleasy'
async function saveUserAction() {
'use server'
// ... perform mutation and return { data?, error? }
}
const save = withTransition(saveUserAction)
export function SaveButton() {
return <button onClick={save}>Save</button>
}Server actions pattern
'use server'
import { createFn, readFn, updateFn, destroyFn } from '@remcostoeten/drizzleasy'
type TUser = { id: string; email: string; name: string; status: 'active' | 'inactive' }
const create = createFn<TUser>()
const read = readFn<TUser>()
const update = updateFn<TUser>()
const destroy = destroyFn<TUser>()
export async function createUser(data: { email: string; name: string }) {
return create('users')({ id: crypto.randomUUID(), email: data.email, name: data.name, status: 'active' })
}
export async function getUsers() {
return read('users')()
}
export async function deactivateUser(id: string) {
return update('users')(id, { status: 'inactive' })
}
export async function removeUser(id: string) {
return destroy('users')(id)
}