Typed framework bindings
useEntities, useEntity, and useMutation for Vue, React, and Svelte on top of trellis/schema.
Generic hooks in trellis/react, trellis/vue, and trellis/svelte accept string types and loose records. Typed bindings take a defineType schema handle and infer row shapes, where filters, and resolve specs.
| Framework | Import path |
|---|---|
| Vue 3 | trellis/vue/typed |
| React 18+ | trellis/react/typed |
| Svelte 5 | trellis/svelte/typed |
Install
npm install trellis@^3.2.0
Run a Trellis entity server (graph sidecar) in remote mode. Local embedded kernel subscriptions are not live yet.
npx trellis serve --port 8230
# or: just graph-nav (from trellis repo serves :8230 + Vite demo)
Vue
<script setup lang="ts">
import { TrellisDb } from "trellis/client/sdk";
import { useEntities, useEntity, useMutation } from "trellis/vue/typed";
import { NavItem, NavSection } from "./schema";
const client = new TrellisDb({ url: "http://localhost:8230" });
await client.registerType(NavSection);
await client.registerType(NavItem);
const sections = useEntities(client, NavSection, { resolve: { items: true } });
const nav = useMutation(client, NavSection);
</script>
<template>
<ul v-if="!sections.loading">
<li v-for="s in sections.data" :key="s.id">{{ s.label }}</li>
</ul>
</template>
Vue API
| Composable | Returns |
|---|---|
useEntities(client, schema, opts?) | { data, loading, error } list |
useEntity(client, schema, id, opts?) | { data, loading, error } single row |
useMutation(client, schema) | create, update, delete typed to schema |
opts may include where (field equality or whereCondition filters) and resolve (relation expansion).
React
import { useEntities, useMutation } from "trellis/react/typed";
function Sidebar({ client }: { client: TrellisDb }) {
const { data: sections, loading } = useEntities(client, NavSection, {
resolve: { items: true },
});
const nav = useMutation(client, NavSection);
// ...
}
Semantics match Vue: same liveEntities / liveEntity signals underneath.
Svelte
<script lang="ts">
import { useEntities, useMutation } from "trellis/svelte/typed";
const sections = useEntities(client, NavSection, { resolve: { items: true } });
const nav = useMutation(client, NavSection);
</script>
Svelte 5 runes bridge the shared Signal from trellis/client.
Generic vs typed
Generic (trellis/react) | Typed (trellis/react/typed) | |
|---|---|---|
| Type param | Manual <T> | Inferred from defineType |
where | Untyped record | Schema field keys |
resolve | Not available | InferResolvedType aware |
| Entry | React hooks | This page |
Parity demo
The graph-nav example ships React, Vue, and Svelte entries that share one schema.ts and one WebSocket channel. Open two tabs on the same framework URL; edits sync within a second.
From the trellis repo:
just graph-nav
# Hub: http://localhost:4200/ React / Vue / Svelte mounts
Full walkthrough: Typed SDK guide.