People example
Browse, filter, detail, and trend over a registered People resource with correct temporal meaning.
The People example shows the classic table-to-cards adaptation on a small employee list — plus a detail view and a monthly headcount chart. No AI involved.
Run it#
- 1
Open the scenario
Open People in the playground. You should see a table of synthetic employees.
- 2
Run the scenario steps
Choose Engineering only, Open Ada, then Monthly headcount. You should see a filtered table, a detail view, and a month-end trend chart.
- 3
Inspect the run
Choose Inspect. You should see the validated request, the result, and the reason that view was picked.
- 4
Shrink the region
Make the region narrower. You should see the table swap to cards with the same rows and filter.
- 5
Run it locally
Choose More → Export project, unzip the download, then run
pnpm installandpnpm dev. You should see a local browse view and the statusrenderer-ready.
What it exercises#
- Browse a typed collection with stable identity per row.
- Filter by team while keeping stable identity on the returned rows.
- Open one person in detail, including on a narrow layout.
- Chart a registered month-end measure by month.
- Reject an unknown field, invalid aggregate, or unregistered view.
Make it yours#
- Swap the synthetic rows for your data adapter.
- Read permissions from your real app state.
- Keep each row's identity stable and its meaning explicit.
- Dispose the app when the host removes the surface.
When it fails#
An unknown field or view returns a diagnostic and keeps the last permitted view. A denied permission read returns no data. Fix the contract or the trusted policy, then send the request again.
Local browse starter source#
The exported project renders one browse view. The additional Playground steps above require their resource meanings, forms/actions, or custom registrations; they are not bundled in this minimal starter. Follow Connect your data to add those contracts.
{
"name": "aeliqo-people-example",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc --noEmit && vite build"
},
"dependencies": {
"@varendo/core": "0.1.0",
"@varendo/runtime": "0.1.0",
"@varendo/web": "0.1.0",
"zod": "4.5.4"
},
"devDependencies": {
"typescript": "7.0.2",
"vite": "8.2.2"
}
}{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "Bundler",
"lib": [
"ES2022",
"DOM"
],
"types": [
"vite/client"
],
"strict": true,
"noEmit": true
},
"include": [
"src/**/*.ts"
]
}<!doctype html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>People · Varendo</title></head><body><main><h1>People</h1><p id="status" role="status">Loading…</p><div id="app"></div></main><script type="module" src="/src/main.ts"></script></body></html>import {defineResource} from '@varendo/core';
import {createQueryFunctionRegistry} from '@varendo/core/expressions';
import {createLocalDataService} from '@varendo/runtime/data';
import {createAeliqoApp} from '@varendo/web/app';
import {z} from 'zod';
import './style.css';
const resource = defineResource({
id: 'people', revision: 'people-1', label: 'People', identity: ['id'],
schema: z.object({id: z.string(), name: z.string(), team: z.string(), location: z.string()}),
fields: {name: {label: 'Name'}, team: {label: 'Team', role: 'dimension'}, location: {label: 'Location'}},
presentation: {allowedViews: ["table","cards"]},
});
const functions = createQueryFunctionRegistry({version: '2'});
if (!functions.ok) throw new Error(functions.diagnostics[0].message);
const data = createLocalDataService({
snapshot: {catalog: resource.catalog, sourceRevision: 'synthetic-1', records: {people: [
{
"id": "p-1",
"name": "Ada Chen",
"team": "Design",
"location": "Jakarta"
},
{
"id": "p-2",
"name": "Sam Rivera",
"team": "Engineering",
"location": "Lisbon"
}
]}},
functionRegistry: functions.value,
sourceLimits: {rows: 1_000, bytes: 1_000_000},
authorize: () => ({ok: true, value: {scopeDigest: 'local-demo', policyRevision: 'policy-1'}}),
});
const app = createAeliqoApp({
resources: [{resource, data}],
authority: {read: () => ({ok: true, value: {
principalKey: 'local-user', scopeDigest: 'local-demo', policyRevision: 'policy-1',
experienceRevision: 'web-1', grants: ['task.evaluate', 'result.inspect', 'experience.commit'],
readContext: {principal: 'local-user'},
}})},
});
const target = document.querySelector<HTMLElement>('#app');
if (target === null) throw new Error('The app target is missing.');
const mounted = app.mount({target, regionId: 'main', resourceId: resource.id});
if (!mounted.ok) throw new Error(mounted.diagnostics[0].message);
const receipt = await app.render({regionId: 'main', intent: {
version: '1', id: 'people-browse', kind: 'browse', resource: resource.id,
fields: ["name","team","location"],
}});
document.querySelector('#status')!.textContent = receipt.status;
window.addEventListener('pagehide', () => app.dispose(), {once: true});:root{font-family:Inter,ui-sans-serif,system-ui;color:#202033;background:#f7f7fb}body{margin:0}main{inline-size:min(72rem,calc(100% - 2rem));margin:3rem auto}#app{container-type:inline-size;min-block-size:20rem}# People · Varendo 0.1.0
Synthetic source project exported from the Varendo playground. Install requires the pinned 0.1.0 packages to be published to npm.
```sh
pnpm install
pnpm dev
```
The application works without an AI provider. Replace the local snapshot and authority adapter with application-owned implementations before using real data.