Skip to content

Commit 91c75a8

Browse files
authored
Merge pull request #76 from cardmagic/docs/agent-guide-names
Show each database adapter and the cancel call
2 parents f8fdb1d + 66cf87d commit 91c75a8

3 files changed

Lines changed: 44 additions & 1 deletion

File tree

‎CHANGELOG.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
- The agent guide now lists the import path, the call, and the driver of each
6+
SQL database adapter, and it shows how to cancel a reminder with
7+
`unschedule()`. Agents in the Track B evaluation invented the names
8+
`solid-objects/database/postgres` and `this.cancelReminder()`.
9+
310
## 1.0.0 - 2026-10-13
411

512
- Version 1.0 freezes the public API under semantic versioning.

‎docs/agents.md‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,14 @@ const runtime = configure({
9595
await runtime.install()
9696
```
9797

98+
Each SQL database has its own adapter. Import the adapter from its own path:
99+
100+
| Database | Import | Call | Driver |
101+
| ---------- | ---------------------------------------------------------------- | ---------------------------------- | ------------------------------- |
102+
| SQLite | `import { sqlite } from "solid-objects/database/sqlite"` | `sqlite({ path: "app.sqlite3" })` | None. Node.js has `node:sqlite` |
103+
| PostgreSQL | `import { postgresql } from "solid-objects/database/postgresql"` | `postgresql({ connectionString })` | `npm install pg` |
104+
| MySQL | `import { mysql } from "solid-objects/database/mysql"` | `mysql({ connectionString })` | `npm install mysql2` |
105+
98106
Every authorization callback denies by default. Do step 5 before you call an
99107
actor. [Configuration](configuration.md) lists each option and database
100108
adapter.
@@ -199,7 +207,8 @@ Obey these rules in actor code:
199207
- Public methods are ordered operations. Each one takes no argument or one
200208
object argument.
201209
- Use `this.schedule({ at, key })` for delayed work. A new `schedule` with the
202-
same key moves the alarm.
210+
same key moves the alarm. `this.unschedule("expire", { key: buyer })` cancels
211+
it.
203212
- Use `this.reject(code, { message })` for a business rule failure that must
204213
not retry. The second argument is an object, for example
205214
`this.reject("room_full", { message: "The room is full" })`.
@@ -221,6 +230,8 @@ Avoid these mistakes:
221230
| ---------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
222231
| `this.schedule({ at, key })` with no operation after it | `this.schedule({ at, key }).expire({ buyer })`. A `schedule()` call with no operation after it fails the turn with `ScheduleWithoutOperation` |
223232
| `this.reject("room full")` or `this.reject(code, message)` | `this.reject("room_full", { message: "The room is full" })` |
233+
| `postgres()` from `solid-objects/database/postgres` | `postgresql({ connectionString })` from `solid-objects/database/postgresql`. Step 4 lists each adapter |
234+
| A guessed cancel method, such as `this.cancelReminder()` | `this.unschedule("expire", { key: buyer })`. `this.unscheduleAll("expire")` cancels every key of one operation |
224235
| `registerEffect(name, (context, argumentsValue) => ...)` | `registerEffect(name, (argumentsValue, context) => ...)`. The staged arguments come first |
225236
| A worker process that never names the actor class | `runtime.register(TicketSale)` before `runtime.run(signal)`. See step 7 |
226237

‎test/agent-guide.test.ts‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { readFileSync } from "node:fs"
2+
import { describe, expect, it } from "vitest"
3+
4+
const guide = readFileSync(new URL("../docs/agents.md", import.meta.url), "utf8")
5+
const packageDefinition = JSON.parse(
6+
readFileSync(new URL("../package.json", import.meta.url), "utf8"),
7+
) as { exports: Record<string, { types: string; import: string }> }
8+
9+
describe("agent guide", () => {
10+
it("names the import path of each server database adapter", () => {
11+
const adapters = Object.keys(packageDefinition.exports).filter(
12+
(path) => path.startsWith("./database/") && !path.endsWith("-wasm"),
13+
)
14+
expect(adapters).toEqual(
15+
expect.arrayContaining(["./database/sqlite", "./database/postgresql", "./database/mysql"]),
16+
)
17+
for (const adapter of adapters) {
18+
expect(guide, adapter).toContain(`"solid-objects${adapter.slice(1)}"`)
19+
}
20+
})
21+
22+
it("shows how to cancel a reminder", () => {
23+
expect(guide).toContain('this.unschedule("expire", { key: buyer })')
24+
})
25+
})

0 commit comments

Comments
 (0)