快速入门
快速入门
几分钟内你就会得到一个小而完整的工作区:一个模型、它的集合,以及一个带一个页面的应用,并完成检查与构建。同一份源码可以用 bolt dev 在本地运行,用 bolt start 在你自己的服务器上运行,也可以在 Colony 的工作区工作室中运行。
tasks/
├── package.json
├── tsconfig.json
└── src/
├── +workspace.ts
├── data/
│ ├── model/+tasks.model.ts
│ └── collection/tasks/+collection.ts
└── app/tasks/
├── +app.ts
└── +board.page.svelte 1. 创建包
{
"name": "tasks",
"private": true,
"type": "module",
"scripts": { "check": "bolt check", "build": "bolt build", "dev": "bolt dev", "test": "bolt test" },
"dependencies": {
"@norbital-ai/bolt": "0.0.1",
"@norbital-ai/ui": "0.0.1",
"effect": "4.0.0-rc.112",
"svelte": "^5.57.1",
"vite": "^8.2.2"
},
"devDependencies": {
"@norbital-ai/bolt-server": "0.0.1",
"@effect/vitest": "4.0.0-rc.112",
"@sveltejs/vite-plugin-svelte": "^7.3.1",
"svelte-check": "^4.7.6",
"typescript": "6.0.3",
"vitest": "4.1.11"
}
} { "extends": "./.norbital/tsconfig.json" } 工作区是一个依赖 @norbital-ai/bolt 与 @norbital-ai/ui 的包。它的 tsconfig.json 继承生成的 .norbital/tsconfig.json。没有 vite.config.ts,也没有 SvelteKit 配置:构建由编译器负责。
2. 声明工作区
// src/+workspace.ts
import { workspace } from '@norbital-ai/bolt';
export default workspace({ tz: 'Asia/Singapore', locale: 'en-SG', apps: ['tasks'] }); src/+workspace.ts 是唯一必需的文件。它设定所有日期与数字所使用的时区和区域设置,以及应用在启动器中的顺序。
3. 定义模型
// src/data/model/+tasks.model.ts
import { model } from '@norbital-ai/bolt';
export default model({
description: 'Work the team has to do.',
icon: 'lucide:list-todo',
label: 'title',
fields: {
title: { kind: 'text' },
status: {
kind: 'state',
initial: 'open',
states: { open: { to: ['done'] }, done: { to: ['open'], edit: 'none' } }
},
due_on: { kind: 'date', optional: true }
},
search: { text: ['title'] }
}); 模型就是存储。文件夹名 tasks 就是模型名;fields 是带类型的字面量,label 是记录标题,而 state 字段是唯一的锁:每个状态列出它可以转到哪里,以及处于该状态时还能编辑什么。
4. 以集合公开它
// src/data/collection/tasks/+collection.ts
import { collection } from '@norbital-ai/bolt';
export default collection('tasks', {
read: { fields: 'all' },
create: { input: { columns: ['title', 'due_on'] } },
update: { input: { columns: ['title', 'status', 'due_on'] } },
delete: {}
}); 没有集合的模型对外不可见。集合规定任何调用方最多能读取什么(read.fields),以及创建与更新接受哪些字段。声明 delete 即公开删除;未声明的操作就不存在。
5. 添加应用与页面
// src/app/tasks/+app.ts
import { app } from '@norbital-ai/bolt';
export default app('tasks', {
title: 'Tasks',
description: 'Everything the team is working on.',
icon: 'lucide:list-todo',
pages: { board: { title: 'Board', icon: 'lucide:kanban' } }
}); +app.ts 为应用命名,并按导航顺序列出它的页面;文件夹中的每个 +<page>.page.svelte 都需要一个条目。这里的标题是字面量;一旦工作区有了 src/i18n/,它们就改为消息目录键。
<!-- src/app/tasks/+board.page.svelte -->
<script lang="ts">
import { Board } from '@norbital-ai/ui';
import { AppShell } from '@norbital-ai/ui/layout';
</script>
<AppShell icon="lucide:list-todo" title="Tasks" description="Everything the team is working on.">
<Board of="tasks" by="status" card={['title', 'due_on']} />
</AppShell> 页面就是一个 Svelte 组件。Board of="tasks" 实时读取该集合,按状态字段分组,并提供“新建”以及每位查看者可执行的状态转移。
6. 检查、运行与构建
pnpm install
pnpm exec bolt check # layout, names, schema, tsc, svelte-check and doctor, every error at once
pnpm exec bolt dev # the workspace on a local PGlite, reloading on save
pnpm exec bolt build # .norbital/artifact/: the one artifact every host runs bolt check 运行每一个阶段——布局、名称、打包、数据库结构、tsc、svelte-check 与 doctor——并一次报告所有错误;没有警告。bolt dev 在本地 PGlite 数据库上运行工作区,并在保存时重新加载。bolt build 写出所有宿主都运行的制品。
capabilities.apps 中列出该应用时才能看到它,并且只能通过授权访问集合:参见策略。下一步
你现在拥有了一个可构建的工作区。从这里开始: