@abide/abide 0.124.0 → 0.125.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ABIDE.md +4 -0
- package/CHANGELOG.md +43 -0
- package/bin/abide.ts +3 -2
- package/docs/REGISTRY.md +67 -41
- package/docs/RULEBOOK.md +207 -20
- package/docs/abide.md +392 -68
- package/package.json +1 -1
- package/src/compiler/Lowering.ts +29 -4
- package/src/compiler/appMap.ts +14 -1
- package/src/compiler/declaredExports.ts +41 -0
- package/src/compiler/handlersUnder.ts +1 -0
- package/src/compiler/hookCalls.ts +1 -0
- package/src/compiler/projectShadow.ts +53 -2
- package/src/compiler/readsIn.ts +39 -34
- package/src/server/BRIDGE_VERSION.ts +1 -1
- package/src/server/PageRender.ts +7 -8
- package/src/server/abideModules.ts +6 -0
- package/src/server/answerRequest.ts +115 -52
- package/src/server/answerSocket.ts +6 -5
- package/src/server/answerWorker.ts +34 -23
- package/src/server/assistant.ts +141 -35
- package/src/server/banner.ts +9 -5
- package/src/server/bridgeRelay.ts +3 -3
- package/src/server/callerOf.ts +5 -0
- package/src/server/claudeCode.ts +20 -11
- package/src/server/commands.ts +14 -7
- package/src/server/createApp.ts +65 -12
- package/src/server/devWorker.ts +18 -16
- package/src/server/generatedSurfaces.ts +6 -5
- package/src/server/handlerFileMount.ts +2 -0
- package/src/server/hooks.ts +54 -8
- package/src/server/index.ts +18 -4
- package/src/server/invokeHandler.ts +1 -1
- package/src/server/mountHandlers.ts +6 -0
- package/src/server/principal.ts +3 -2
- package/src/server/render.ts +11 -2
- package/src/server/requestScope.ts +61 -1
- package/src/server/responseRelay.ts +9 -3
- package/src/server/serveDev.ts +18 -3
- package/src/server/sqliteStore.ts +65 -0
- package/src/server/testMount.ts +1 -0
- package/src/shared/AssistantEvent.ts +40 -0
- package/src/shared/BrowserHooks.ts +73 -0
- package/src/shared/CURRENT_ROUTER.ts +3 -1
- package/src/shared/Issues.ts +11 -3
- package/src/shared/Middleware.ts +9 -9
- package/src/shared/UNEXPECTED.ts +1 -1
- package/src/shared/answerOf.ts +9 -4
- package/src/shared/imagePiece.ts +85 -0
- package/src/shared/index.ts +17 -0
- package/src/shared/isServer.ts +15 -0
- package/src/shared/navigate.ts +10 -3
- package/src/shared/onError.ts +51 -0
- package/src/shared/onRefusal.ts +47 -0
- package/src/shared/online.ts +5 -1
- package/src/shared/reactive/Keyed.ts +12 -1
- package/src/shared/reactive/Reactive.ts +65 -26
- package/src/shared/reactive/cellShape.ts +4 -3
- package/src/shared/reactive/poll.ts +49 -0
- package/src/shared/reactive/scoped.ts +10 -1
- package/src/shared/reactive/scoping.ts +14 -0
- package/src/shared/reactive/watch.ts +19 -8
- package/src/shared/resultsOf.ts +21 -0
- package/src/shared/route.ts +18 -4
- package/src/shared/rpc.ts +112 -26
- package/src/shared/seededDocument.ts +5 -6
- package/src/shared/storedValue.ts +32 -0
- package/src/shared/webStore.ts +54 -0
- package/src/ui/Router.ts +42 -9
- package/src/ui/outboxQueue.ts +1 -1
- package/src/ui/wire.ts +4 -4
- package/src/shared/KEEP_OPENED.ts +0 -7
- /package/src/{server → shared}/IMAGE_TYPES.ts +0 -0
package/ABIDE.md
CHANGED
|
@@ -29,12 +29,16 @@ affected code saying what it did, and tell the user.
|
|
|
29
29
|
calls it. Every component has a test that `mount`s it and counts the work an
|
|
30
30
|
interaction did with `measure`, both from `@abide/harness/abide` (RULEBOOK 38.119, 43.23) — a
|
|
31
31
|
test that only reads the text back passes against a component doing ten times the work.
|
|
32
|
+
A prop the test moves is handed as a getter — `Label({ get label() { return source() } })` —
|
|
33
|
+
and is read through it on every read (RULEBOOK 38.134); any other prop is the value it was given.
|
|
32
34
|
A test waits on a value landing — `await` the handler call, or the `Reactive` the component
|
|
33
35
|
reads, which is thenable (RULEBOOK 1.4) — never on `Bun.sleep` or a timer. Break the code once and
|
|
34
36
|
watch a new test fail; a test that has never failed has not been shown to test anything.
|
|
35
37
|
Called outside a request, a `GET` keeps its answer for the whole test process: a test that changes
|
|
36
38
|
the data behind one calls its `invalidate()` in `beforeEach`. A handler that reads `config()` or
|
|
37
39
|
`principal` runs inside `app.run(…)` of `await createApp()`, where the app's `onConfig` has run.
|
|
40
|
+
A request sent as someone is `app.fetch(request, { principal, caller })` (RULEBOOK 42.20, 42.21),
|
|
41
|
+
never a hand-written `abide-principal` or `abide-caller` cookie.
|
|
38
42
|
`mount` sets no route, so a page stays thin: it reads the route and hands what it needs to a
|
|
39
43
|
component in `lib/`, and the test mounts that component.
|
|
40
44
|
- `bun run bench` — runs `harness-bench`: every `*.bench.ts` under `src/`, kept beside the code it
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,48 @@
|
|
|
1
1
|
# @abide/abide
|
|
2
2
|
|
|
3
|
+
## 0.125.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- e948e8e: `App.fetch` takes a `principal` and a `caller`, and `App.run` a `caller`, each answered as over the request's cookies with no cookie written — 42.20, 42.21
|
|
8
|
+
- 74eacfc: an assistant's `tool` and `result` events carry the handler they called (`{ method, address }`, as its `Rpc` reads them) and a result the value it answered, read off the app's own surface whichever provider ran the conversation — `resultsOf(events, handler)` is every successful call's value, typed as the handler's; a `Provider` now yields `ProviderEvent`s naming each tool as its `Toolbox` lists it; `AssistantMessage`, `AssistantContent` and `AssistantEvent` are exported from `@abide/abide` for the browser; `imagePiece(file)` and `imageFiles(dataTransfer)` turn a pasted, dropped or picked image into a turn's image piece, drawn down to 1568px — 44.48-44.55
|
|
9
|
+
- 1eaf716: `assistant` takes a `signal` in its options: aborting it ends the conversation at once, refused `aborted` at 499, even while the provider is stuck in an await — the same end a client leaving now gets — 44.57
|
|
10
|
+
- fd731a2: a `BridgeStatus` and `claudeCode.bridgeCommand()` carry `install`, the command that installs the bridge app the pairing link opens at the release the pairing command runs, so a page no longer parses the release out of `command` — 44.56
|
|
11
|
+
- c5ea214: `onError` from `@abide/abide`, called in a layout's or a page's `<script>`, hears in the browser what nothing caught — an uncaught throw, an unhandled rejection such as a call's refusal no handler caught, and an effect's throw — once each, nearest component first, for as long as the component stands — 37.16, 37.17, 37.18
|
|
12
|
+
- 17fdafe: `onRefusal` from `@abide/abide`, called in a layout's or a page's `<script>`, is handed in the browser every refusal a call over http is answered with — the handler's, a proxy's 401, the 503 for no answer, and one an `outbox` send gets — with the call's method and URL, once each, nearest component first, for as long as the component stands; the value still refuses — 37.22-37.27
|
|
13
|
+
- b436c3e: `abide dev`, `abide start`, the shell's app and a compiled executable's `start` take `--hostname` and listen on that interface alone — every interface where none is named, and the banner then lists no network address — 38.136; and `requestIP()` answers where the request being served came from, the same under `start`, `dev` and `App.listen`, or `'in-process'` for one no listener received — 22.12, 22.13
|
|
14
|
+
- c49316f: `isServer()` answers which side the running work is on — true inside a request, an `App.run` or a `render` even with a DOM preloaded, so an in-process test takes the server branch; an effect's throw no longer fails a server render beside that DOM, and `online` is true there — 22.11, 12.7, 23.8
|
|
15
|
+
- 02f34f7: a `middleware` rung is handed `ctx.lane` — the `Lane` that answers its request: a page, a handler, a public file, `openapi`, `mcp`, `bridge`, the socket upgrade, or the rest of `/__abide` — so a gate need not spell out abide's own addresses, and is handed the request below the mount — 37.19, 37.20
|
|
16
|
+
- 801345f: `poll` — a reactive option that refreshes the value every `poll` milliseconds, skipping a tick while it is busy and stopping with the value's owner or its `Keyed` (RULEBOOK 7.20 through 7.25)
|
|
17
|
+
- 3ffb8c0: `route.index` is the entry's place in the history the app's router wrote, and `navigate(by)` steps the history and settles once the step has arrived — 23.28, 23.29, 30.38, 30.39
|
|
18
|
+
- 380be01: `abide routes` names the rungs each handler's `middleware` declares, as written, and `--json` carries them as `middleware` on every route — `null` where the options are not written inline — 38.135
|
|
19
|
+
- 226e6a7: a refusal a rung names is on its `Rpc`'s failures and narrows by name, and `Middleware` takes the refusals it may answer with as a third parameter — 16.8, 16.86
|
|
20
|
+
- cbcd422: `webStore` (from `@abide/abide`) and `sqliteStore` (from `@abide/abide/server`) — shipped `Store`s for Web Storage, following other tabs' writes and inert on a server, and for a `bun:sqlite` table; both keep the value's `ttl` beside it and run an optional `schema` over what they read (RULEBOOK 8.22 through 8.28)
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- 6f2742a: a handler whose parameter carries no annotation takes its `Args` from the `args` its options declare, now stated and gated — 16.87
|
|
25
|
+
- eb201fb: one spelling each for a server's stops, a refused call and a present member; endedBy races a fresh abort per step ([`47dffbf`](https://github.com/briancray/abide/commit/47dffbf3563895200aabed1fc4d7a65aa6764fe0))
|
|
26
|
+
- eb201fb: a render outside every request is torn down as a request is, and so is mount's server pass — 12.5, 38.119 ([`a7a2ada`](https://github.com/briancray/abide/commit/a7a2ada76a61df4f6632542b01083383d6218910))
|
|
27
|
+
- eb201fb: renumber clauses 22.11-12, 37.16-17, 38.134-135 to follow those merged beside them ([`d4ca7c5`](https://github.com/briancray/abide/commit/d4ca7c57ec2deb91eef08c6182729d561da5e8c6))
|
|
28
|
+
- eb201fb: a navigation the worker forwards is the page that hydrates — chromium sends it navigate with its destination empty — 41.29, 45.25 ([`f94c1bd`](https://github.com/briancray/abide/commit/f94c1bd4cfd9a416036bd8d918ce109f07642b66))
|
|
29
|
+
- 5d05e0e: `onError` from `@abide/abide` throws where it could never file — a `<script server>`, a server module, a module's top level, a later callback — naming `@abide/abide/server`'s, rather than doing nothing (RULEBOOK 37.21).
|
|
30
|
+
- 693c7f3: `abide check` holds an element's `bind:` to what the element writes back — a numeric input's `number | undefined`, a text field's string, a `<select>`'s strings, a boolean for `checked` and `open`, files for `files` — and a `type` written as an expression to the union of them — 32.78
|
|
31
|
+
- 20bb20a: a handler's value, and any `reactive` a module declares, built on a server where it is first reached, is no longer owned by the render or the component setup that reached it first — so it is not released when that one ends, and the next read neither runs its body again nor restarts its stream. A request's own instance is still that request's — 12.17
|
|
32
|
+
- d3b0202: `Issues<typeof handler>` is the issues of what the handler is called with, so a form's refusal state names the handler rather than `Parameters<typeof handler>[0]` — 19.26
|
|
33
|
+
- ce73c75: a prop handed to a component bound for `mount` as a getter is read through it on every read — 38.134
|
|
34
|
+
- e93eaf6: A mutator on a `Reactive` list typed with `undefined` or `null` — `drafts?.push(d)`, or `drafts.push(d)` once narrowed — is a write that wakes its readers, as on a list typed without them — 31.9
|
|
35
|
+
- 92f7c58: the offline worker asks the network for a navigation as that navigation, so a sign-in proxy redirects it rather than answering a fetch 401, and drops a saved copy the network answers over with a redirect or a 4xx — 45.25, 45.26
|
|
36
|
+
- 26ebcb7: a stream whose owner stopped and whose last reader left is started again by the next read, rather than staying stopped — a `{#for}` row or `{#if}` arm that comes back, or a streamed `GET` shared by a reader that left; and `mount` tears its server pass down as `render` does — 12.14, 12.16
|
|
37
|
+
- f215b78: a store miss that falls back to the initial value no longer writes it back through `set`, so a server render no longer overwrites a browser's store with the default — 8.8
|
|
38
|
+
|
|
39
|
+
## 0.124.1
|
|
40
|
+
|
|
41
|
+
### Patch Changes
|
|
42
|
+
|
|
43
|
+
- cd07376: a throttled or debounced body is busy while its window holds a run, and an await waits for it — 5.15 ([`1482fd3`](https://github.com/briancray/abide/commit/1482fd3368675794ab6db48ff1ff2c5b8861d68c))
|
|
44
|
+
- cd07376: a bind: through a path is checked as the get/set pair the build emits — 32.5 ([`c91d03f`](https://github.com/briancray/abide/commit/c91d03f816af91f994314fc17b2101d8ec77ec51))
|
|
45
|
+
|
|
3
46
|
## 0.124.0
|
|
4
47
|
|
|
5
48
|
### Minor Changes
|
package/bin/abide.ts
CHANGED
|
@@ -821,14 +821,15 @@ async function lsp({ values }: Given): Promise<number> {
|
|
|
821
821
|
*/
|
|
822
822
|
async function dev(
|
|
823
823
|
{ root }: AppDirectories,
|
|
824
|
-
{ values: { port } }: Given,
|
|
824
|
+
{ values: { port, hostname } }: Given,
|
|
825
825
|
): Promise<undefined> {
|
|
826
826
|
process.env.NODE_ENV ??= 'development'
|
|
827
827
|
const server = await serveDev({
|
|
828
828
|
root,
|
|
829
829
|
port: port === undefined ? undefined : Number(port),
|
|
830
|
+
hostname,
|
|
830
831
|
})
|
|
831
|
-
console.log(banner('abide', 'dev', packageUnder(root), server))
|
|
832
|
+
console.log(banner('abide', 'dev', packageUnder(root), server, hostname))
|
|
832
833
|
return undefined
|
|
833
834
|
}
|
|
834
835
|
|
package/docs/REGISTRY.md
CHANGED
|
@@ -62,8 +62,8 @@ Accepted, Failures>` is the inner value's own `Accepted`. Then `Failures`, then
|
|
|
62
62
|
| `Shaped` | `unknown` | What a `transform` hands back: the value to store, or a refusal. | 4.6, 4.9 |
|
|
63
63
|
| `Produced` | `unknown` | What a production carries, where that differs from what is stored. | 1.2, 9.3 |
|
|
64
64
|
| `Args` | `Record<string, JsonValue> \| undefined` | The key of a keyed value. | 9.4, 11.24, 11.25, 11.26, 11.27, 11.29, 11.31, 11.64, 19.15 |
|
|
65
|
-
| `reactive` | `<Computed, Shaped = Awaited<Computed>, Gate = Schema<Awaited<Computed>>>(body: () => Computed, options?: Omit<ReactiveOptions<Awaited<NoInfer<Computed>>, Kept<Shaped>, never>, 'schema'> & { transform?: (value: Awaited<NoInfer<Computed>>) => Shaped; schema?: Gate & Schema<Awaited<NoInfer<Computed>>> }) => Reactive<Kept<Shaped>, Awaited<Computed>, AdoptedFailures<Computed> \| Refused<Shaped> \| Gated<Gate, Awaited<Computed>>, AdoptedProduced<Computed, Kept<Shaped>>>` | The unkeyed body overload. | 3.9, 11.1, 11.3, 11.5, 11.7, 11.8, 11.9, 11.10, 11.11, 11.12, 11.13, 11.14, 11.15, 11.16, 11.17, 11.18, 11.19, 11.20, 11.21, 11.22, 11.32, 11.33, 11.50, 11.51, 11.52, 11.53, 11.54, 11.57, 11.58, 41.6, 11.62, 11.63, 11.65, 11.66, 12.14, 19.24 |
|
|
66
|
-
| `reactive` | `<Chunk, Shaped = Chunk[], Gate = Schema<Chunk[]>>(body: () => AsyncGenerator<Chunk> \| Promise<AsyncGenerator<Chunk>>, options?: Omit<ReactiveOptions<Chunk[], Kept<Shaped>, never>, 'schema'> & { transform?: (value: Chunk[]) => Shaped; schema?: Gate & Schema<Chunk[]> }) => Reactive<Kept<Shaped>, Chunk[], Refused<Shaped> \| Gated<Gate, Chunk[]>, Chunk>` | The streaming body overload. | 3.7, 3.8, 4.8, 9.1, 9.2, 9.6, 9.7, 9.8, 9.9 |
|
|
65
|
+
| `reactive` | `<Computed, Shaped = Awaited<Computed>, Gate = Schema<Awaited<Computed>>>(body: () => Computed, options?: Omit<ReactiveOptions<Awaited<NoInfer<Computed>>, Kept<Shaped>, never>, 'schema'> & { transform?: (value: Awaited<NoInfer<Computed>>) => Shaped; schema?: Gate & Schema<Awaited<NoInfer<Computed>>> }) => Reactive<Kept<Shaped>, Awaited<Computed>, AdoptedFailures<Computed> \| Refused<Shaped> \| Gated<Gate, Awaited<Computed>>, AdoptedProduced<Computed, Kept<Shaped>>>` | The unkeyed body overload. | 3.9, 11.1, 11.3, 11.5, 11.7, 11.8, 11.9, 11.10, 11.11, 11.12, 11.13, 11.14, 11.15, 11.16, 11.17, 11.18, 11.19, 11.20, 11.21, 11.22, 11.32, 11.33, 11.50, 11.51, 11.52, 11.53, 11.54, 11.57, 11.58, 41.6, 11.62, 11.63, 11.65, 11.66, 12.14, 12.17, 19.24 |
|
|
66
|
+
| `reactive` | `<Chunk, Shaped = Chunk[], Gate = Schema<Chunk[]>>(body: () => AsyncGenerator<Chunk> \| Promise<AsyncGenerator<Chunk>>, options?: Omit<ReactiveOptions<Chunk[], Kept<Shaped>, never>, 'schema'> & { transform?: (value: Chunk[]) => Shaped; schema?: Gate & Schema<Chunk[]> }) => Reactive<Kept<Shaped>, Chunk[], Refused<Shaped> \| Gated<Gate, Chunk[]>, Chunk>` | The streaming body overload. | 3.7, 3.8, 4.8, 9.1, 9.2, 9.6, 9.7, 9.8, 9.9, 12.14, 12.17, 12.16 |
|
|
67
67
|
| `reactive` | `<Chunk, Args, Shaped = Chunk[], Gate = Schema<Chunk[]>, ArgsGate = Schema<Args>>(body: (args: Args) => AsyncGenerator<Chunk> \| Promise<AsyncGenerator<Chunk>>, options?: Omit<ReactiveOptions<Chunk[], Kept<Shaped>, never, Args>, 'schema' \| 'args'> & { transform?: (value: Chunk[]) => Shaped; schema?: Gate & Schema<Chunk[]>; args?: ArgsGate & Schema<Args> }) => Keyed<Kept<Shaped>, Args, Chunk[], Refused<Shaped> \| Gated<Gate, Chunk[]> \| Gated<ArgsGate, Args>, Chunk>` | The keyed streaming body overload. | 9.6, 9.9 |
|
|
68
68
|
| `reactive` | `<Chunk, Args, Shaped = Chunk[], Gate = Schema<Chunk[]>, ArgsGate = Schema<Args \| undefined>>(body: (args?: Args) => AsyncGenerator<Chunk> \| Promise<AsyncGenerator<Chunk>>, options?: Omit<ReactiveOptions<Chunk[], Kept<Shaped>, never, Args \| undefined>, 'schema' \| 'args'> & { transform?: (value: Chunk[]) => Shaped; schema?: Gate & Schema<Chunk[]>; args?: ArgsGate & Schema<Args \| undefined> }) => Keyed<Kept<Shaped>, Args \| undefined, Chunk[], Refused<Shaped> \| Gated<Gate, Chunk[]> \| Gated<ArgsGate, Args \| undefined>, Chunk>` | The keyed streaming overload for a body whose parameter is optional. | 11.2 |
|
|
69
69
|
| `reactive` | `<Computed, Args, Shaped = Awaited<Computed>, Gate = Schema<Awaited<Computed>>, ArgsGate = Schema<Args>>(body: (args: Args) => Computed, options?: Omit<ReactiveOptions<Awaited<NoInfer<Computed>>, Kept<Shaped>, never, Args>, 'schema' \| 'args'> & { transform?: (value: Awaited<NoInfer<Computed>>) => Shaped; schema?: Gate & Schema<Awaited<NoInfer<Computed>>>; args?: ArgsGate & Schema<Args> }) => Keyed<Kept<Shaped>, Args, Awaited<Computed>, AdoptedFailures<Computed> \| Refused<Shaped> \| Gated<Gate, Awaited<Computed>> \| Gated<ArgsGate, Args>, AdoptedProduced<Computed, Kept<Shaped>>>` | The keyed body overload. | 11.2, 11.3, 11.4, 11.6, 11.7, 11.23, 11.55, 11.62, 19.24 |
|
|
@@ -73,6 +73,8 @@ Accepted, Failures>` is the inner value's own `Accepted`. Then `Failures`, then
|
|
|
73
73
|
| `reactive` | `<Accepted>() => Reactive<Kept<Accepted>, Accepted, Refused<Accepted>>` | The empty overload, for a value nothing has written yet. | 4.14 |
|
|
74
74
|
| `Transformer` | `<Accepted, Stored, Failures = never>(value: Accepted) => Stored \| Failures` | The shape of a `transform`. | 4.6, 4.7, 4.8 |
|
|
75
75
|
| `Store` | `{ get: () => Stored \| undefined \| Promise<Stored \| undefined>; set: (value: Stored, retention: { ttl: number }) => void \| Promise<void>; watch?: (changed: () => void) => () => void }` | Where a value lives when this process does not. | 8.1, 8.2, 8.3, 8.4, 8.5, 8.6, 8.7, 8.8, 8.9, 8.10, 8.11, 8.12, 8.13, 8.14, 8.15, 8.16, 8.17, 8.18, 8.19, 8.20, 8.21 |
|
|
76
|
+
| `webStore` | `<Stored>(key: string, options?: { area?: 'local' \| 'session'; schema?: Schema<Stored> }) => Store<Stored>` | A `Store` kept in the browser's Web Storage. | 8.22, 8.23, 8.24, 8.26, 8.27, 8.28 |
|
|
77
|
+
| `sqliteStore` | `<Stored>(database: Database \| string, key: string, options?: { table?: string; schema?: Schema<Stored> }) => Store<Stored>` | A `Store` kept in a `bun:sqlite` table, from `@abide/abide/server`. | 8.25, 8.26, 8.27, 8.28 |
|
|
76
78
|
| `Shared` | `interface Shared {}` | The app's declaration-merged registry of shared keys. | 10.3 |
|
|
77
79
|
| `reactive.share` | `<Key extends string, Value>(key: Key, create: () => Reactive<Value>) => Key extends keyof Shared ? Reactive<Shared[Key]> : Reactive<Value>` | Get-or-create a reactive value in the component's scope by key. | 10.1, 10.2, 10.4, 10.5, 10.6, 10.7 |
|
|
78
80
|
|
|
@@ -98,6 +100,7 @@ type Gated<Gate, Accepted> = [Schema<Accepted>] extends [Gate] ? never : Failed<
|
|
|
98
100
|
| `structural` | `(next: unknown, previous: unknown) => boolean` | The by-value comparator an app declares on `identity`. | 5.4, 5.5, 18.4 |
|
|
99
101
|
| `by` | `(keyof Element & string) \| ((element: Element) => unknown)`, over the `Element` a `Stored` array holds | What tells one element of the value from another. | 5.22, 18.4, 18.15, 32.32 |
|
|
100
102
|
| `ttl` | `number` | The life of a production, or of a keyed entry. | 6.1, 6.2, 6.3, 6.4, 6.5, 6.6, 6.7, 6.8, 6.9, 6.10, 11.6, 11.35, 11.45, 11.48, 11.49, 11.69 |
|
|
103
|
+
| `poll` | `number` | How often the value refreshes itself, in milliseconds. | 7.20, 7.21, 7.22, 7.23, 7.24, 7.25 |
|
|
101
104
|
| `args` | `Schema<Args>` | The gate on a keyed value's args. | 9.4, 11.28, 11.30, 11.40, 11.41, 11.56, 11.60, 11.68, 11.72 |
|
|
102
105
|
| `global` | `boolean` | Opts out of the default scope into one cache shared by every caller in the process. | 11.34, 11.35, 11.36, 11.37, 11.38, 11.39, 11.53, 11.67 |
|
|
103
106
|
| `tags` | `string[] \| ((args: Args) => string[])` | What a `Selection` matches on. | 11.43, 11.44, 18.4, 18.15 |
|
|
@@ -222,16 +225,16 @@ type Gated<Gate, Accepted> = [Schema<Accepted>] extends [Gate] ? never : Failed<
|
|
|
222
225
|
| `Value` | `unknown` | What the addressed `Reactive` holds. | 16.3, 16.30 |
|
|
223
226
|
| `Produced` | `unknown` | What it yields, per the unit rule. | 1.2, 16.3 |
|
|
224
227
|
| `Args` | `Record<string, JsonValue> \| undefined` | The arguments, in the body on a mutation and in the URL on a `GET` or `DELETE`. | 11.24, 16.18, 19.15 |
|
|
225
|
-
| `Middleware` | `Middleware<Answer = never, Extra extends object = object> = <Given extends { request: Request } & Extra, Result>(next: (ctx?: Given) => Promise<Result>, ctx: Given) => Result \| Answer \|
|
|
226
|
-
| `GET` | `<Stored, Accepted, Failures, Produced>(handler: Reactive<Stored, Accepted, Failures, Produced>, options?: RpcOptions<undefined>) => Rpc<Stored, undefined, Failures
|
|
227
|
-
| `GET` | `<Stored, Args, Accepted, Failures, Produced>(handler: Keyed<Stored, Args, Accepted, Failures, Produced>, options?: RpcOptions<Args>) => Rpc<Stored, Args, Failures
|
|
228
|
-
| `GET` | `<Chunk, Shaped = Chunk[], Gate = Schema<Chunk[]
|
|
229
|
-
| `GET` | `<Chunk, Args, Shaped = Chunk[], Gate = Schema<Chunk[]>, ArgsGate = Schema<Args
|
|
230
|
-
| `GET` | `<Chunk, Args, Shaped = Chunk[], Gate = Schema<Chunk[]>, ArgsGate = Schema<Args \| undefined
|
|
231
|
-
| `GET` | `<Computed, Shaped = Awaited<Computed>, Gate = Schema<Awaited<Computed
|
|
232
|
-
| `GET` | `<Computed, Args, Shaped = Awaited<Computed>, Gate = Schema<Awaited<Computed>>, ArgsGate = Schema<Args
|
|
233
|
-
| `GET` | `<Computed, Args, Shaped = Awaited<Computed>, Gate = Schema<Awaited<Computed>>, ArgsGate = Schema<Args \| undefined
|
|
234
|
-
| `GET` | `<Accepted, Shaped = Accepted, Gate = Schema<Accepted
|
|
228
|
+
| `Middleware` | `Middleware<Answer = never, Extra extends object = object, Refused extends Failed<string, unknown> = Failed<string, unknown>> = <Given extends { request: Request } & Extra, Result>(next: (ctx?: Given) => Promise<Result>, ctx: Given) => Result \| Answer \| Refused \| Promise<Result \| Answer \| Refused>` | One rung, written once for every lane whose context carries `Extra`. | 16.8, 16.14, 16.15, 16.16, 16.21, 16.86, 37.14, 37.15 |
|
|
229
|
+
| `GET` | `<Stored, Accepted, Failures, Produced, Answers extends readonly unknown[] = unknown[]>(handler: Reactive<Stored, Accepted, Failures, Produced>, options?: RpcOptions<undefined, Answers>) => Rpc<Stored, undefined, Failures \| RungRefusals<Answers>, Produced>` | Declares a read any surface may call. | 16.1, 16.2, 16.5, 16.6, 16.30, 16.31, 16.32, 16.68, 16.76, 16.34, 16.35, 16.36, 16.37, 16.39, 16.44, 16.45, 16.46, 16.47, 16.75, 16.50, 16.51, 16.52, 16.64, 12.17, 18.1, 18.3, 18.6, 18.8, 18.10, 18.12, 18.21, 18.24, 18.27 |
|
|
230
|
+
| `GET` | `<Stored, Args, Accepted, Failures, Produced, Answers extends readonly unknown[] = unknown[]>(handler: Keyed<Stored, Args, Accepted, Failures, Produced>, options?: RpcOptions<Args, Answers>) => Rpc<Stored, Args, Failures \| RungRefusals<Answers>, Produced>` | The keyed overload, for a `Keyed` given an address. | 11.2, 16.1, 16.3, 16.6 |
|
|
231
|
+
| `GET` | `<Chunk, Shaped = Chunk[], Gate = Schema<Chunk[]>, Answers extends readonly unknown[] = unknown[]>(handler: () => AsyncGenerator<Chunk> \| Promise<AsyncGenerator<Chunk>>, options?: Shaping<Chunk[], Shaped, never, Gate> & RpcOptions<undefined, Answers>) => Rpc<Kept<Shaped>, undefined, Refusals<Shaped, Gate, Chunk[]> \| RungRefusals<Answers>, Chunk>` | The streaming overload, whose options build the value it becomes beside its address. | 16.1, 16.6, 16.7, 16.44, 16.45, 16.46, 16.47 |
|
|
232
|
+
| `GET` | `<Chunk, Args, Shaped = Chunk[], Gate = Schema<Chunk[]>, ArgsGate = Schema<Args>, Answers extends readonly unknown[] = unknown[]>(handler: (args: Args) => AsyncGenerator<Chunk> \| Promise<AsyncGenerator<Chunk>>, options?: Shaping<Chunk[], Shaped, Args, Gate, ArgsGate> & RpcOptions<Args, Answers>) => Rpc<Kept<Shaped>, Args, Refusals<Shaped, Gate, Chunk[], ArgsGate, Args> \| RungRefusals<Answers>, Chunk>` | The keyed streaming overload. | 11.2, 16.1, 16.6, 16.7, 16.87 |
|
|
233
|
+
| `GET` | `<Chunk, Args, Shaped = Chunk[], Gate = Schema<Chunk[]>, ArgsGate = Schema<Args \| undefined>, Answers extends readonly unknown[] = unknown[]>(handler: (args?: Args) => AsyncGenerator<Chunk> \| Promise<AsyncGenerator<Chunk>>, options?: Shaping<Chunk[], Shaped, Args \| undefined, Gate, ArgsGate> & RpcOptions<Args \| undefined, Answers>) => Rpc<Kept<Shaped>, Args \| undefined, Refusals<Shaped, Gate, Chunk[], ArgsGate, Args \| undefined> \| RungRefusals<Answers>, Chunk>` | The keyed streaming overload for a body whose parameter is optional. | 11.2, 16.87 |
|
|
234
|
+
| `GET` | `<Computed, Shaped = Awaited<Computed>, Gate = Schema<Awaited<Computed>>, Answers extends readonly unknown[] = unknown[]>(handler: () => Computed, options?: Shaping<Awaited<Computed>, Shaped, never, Gate> & RpcOptions<undefined, Answers>) => Rpc<Kept<Shaped>, undefined, AdoptedFailures<Computed> \| Refusals<Shaped, Gate, Awaited<Computed>> \| RungRefusals<Answers>, AdoptedProduced<Computed, Kept<Shaped>>>` | The plain-function overload, whose options (`ttl`, `global`, `debounce` and the rest) build the value it becomes beside its address. | 16.1, 16.6, 16.7 |
|
|
235
|
+
| `GET` | `<Computed, Args, Shaped = Awaited<Computed>, Gate = Schema<Awaited<Computed>>, ArgsGate = Schema<Args>, Answers extends readonly unknown[] = unknown[]>(handler: (args: Args) => Computed, options?: Shaping<Awaited<Computed>, Shaped, Args, Gate, ArgsGate> & RpcOptions<Args, Answers>) => Rpc<Kept<Shaped>, Args, AdoptedFailures<Computed> \| Refusals<Shaped, Gate, Awaited<Computed>, ArgsGate, Args> \| RungRefusals<Answers>, AdoptedProduced<Computed, Kept<Shaped>>>` | The keyed plain-function overload. | 11.2, 16.1, 16.6, 16.7, 16.87 |
|
|
236
|
+
| `GET` | `<Computed, Args, Shaped = Awaited<Computed>, Gate = Schema<Awaited<Computed>>, ArgsGate = Schema<Args \| undefined>, Answers extends readonly unknown[] = unknown[]>(handler: (args?: Args) => Computed, options?: Shaping<Awaited<Computed>, Shaped, Args \| undefined, Gate, ArgsGate> & RpcOptions<Args \| undefined, Answers>) => Rpc<Kept<Shaped>, Args \| undefined, AdoptedFailures<Computed> \| Refusals<Shaped, Gate, Awaited<Computed>, ArgsGate, Args \| undefined> \| RungRefusals<Answers>, AdoptedProduced<Computed, Kept<Shaped>>>` | The keyed plain-function overload for a body whose parameter is optional. | 11.2, 16.87 |
|
|
237
|
+
| `GET` | `<Accepted, Shaped = Accepted, Gate = Schema<Accepted>, Answers extends readonly unknown[] = unknown[]>(handler: Accepted \| PromiseLike<Accepted>, options?: Shaping<Accepted, Shaped, never, Gate> & RpcOptions<undefined, Answers>) => Rpc<Kept<Shaped>, undefined, Refusals<Shaped, Gate, Accepted> \| RungRefusals<Answers>>` | The value overload, for what the handler owns outright, whose options build the value it becomes. | 16.1, 16.6, 16.7 |
|
|
235
238
|
| `POST` / `PUT` / `PATCH` / `DELETE` | same as `GET` | Declares a mutation. | 16.2, 16.7, 16.32, 16.68, 16.76, 16.38, 16.53 |
|
|
236
239
|
| `rpc.busy` | `(pattern?: Partial<Args>) => boolean` | `busy` narrowed to the handler's matching entries. | 13.2, 13.3, 13.12, 13.19, 46.11 |
|
|
237
240
|
| `rpc.ready` | `(pattern?: Partial<Args>) => boolean` | `ready` narrowed to the handler's matching entries. | 13.11, 13.12, 13.19 |
|
|
@@ -246,7 +249,8 @@ type Gated<Gate, Accepted> = [Schema<Accepted>] extends [Gate] ? never : Failed<
|
|
|
246
249
|
| `PatchOp` | `{ op: 'add' \| 'replace' \| 'test'; path: string; value: unknown } \| { op: 'remove'; path: string } \| { op: 'move' \| 'copy'; from: string; path: string }` | One JSON Patch operation (RFC 6902), its paths JSON Pointers, as a followed `GET` is sent what an `s.patch` wrote. | 18.11, 18.13 |
|
|
247
250
|
|
|
248
251
|
The aliases a call's failures and a plain handler's options are spelled through are declared
|
|
249
|
-
rather than listed, none of them being a name an app writes. `
|
|
252
|
+
rather than listed, none of them being a name an app writes. `RungRefusals` is what 16.86 carries,
|
|
253
|
+
and `Annotated` is the `ValidationError` of
|
|
250
254
|
16.8, `never` wherever 19.9 derives no object's schema from `Args`:
|
|
251
255
|
|
|
252
256
|
```ts
|
|
@@ -254,6 +258,8 @@ type Annotated<Args> = 0 extends 1 & Args ? never : unknown extends Args ? never
|
|
|
254
258
|
type Derived<Member, Whole = Member> = Member extends readonly unknown[] | ((...given: never[]) => unknown) ? never : Member extends object ? [Whole] extends [Member] ? [keyof Member] extends [never] ? [string] extends [Member] ? Failed<'ValidationError', Issues<Whole>> : never : Failed<'ValidationError', Issues<Whole>> : never : never
|
|
255
259
|
type Shaping<Accepted, Shaped, Args = never, Gate = Schema<Accepted>, ArgsGate = Schema<Args>> = Omit<ReactiveOptions<Accepted, Kept<NoInfer<Shaped>>, never, Args>, 'transform' | 'schema' | 'args'> & { transform?: (value: Accepted) => Shaped; schema?: Gate & Schema<Accepted>; args?: [Args] extends [never] ? never : ArgsGate & Schema<Args> }
|
|
256
260
|
type Refusals<Shaped, Gate, Stored, ArgsGate = Schema<never>, Args = never> = Refused<Shaped> | Gated<Gate, Stored> | Gated<ArgsGate, Args>
|
|
261
|
+
type RungRefusals<Answers extends readonly unknown[]> = Answers[number] extends infer Answer ? Answer extends Failed<infer Name, unknown> ? string extends Name ? never : Answer : never : never
|
|
262
|
+
type Reached = { readonly [REACHED]: true }
|
|
257
263
|
```
|
|
258
264
|
|
|
259
265
|
### `RpcOptions`
|
|
@@ -261,7 +267,7 @@ type Refusals<Shaped, Gate, Stored, ArgsGate = Schema<never>, Args = never> = Re
|
|
|
261
267
|
| Name | Signature | Meaning | Rules |
|
|
262
268
|
| --- | --- | --- | --- |
|
|
263
269
|
| `description` | `string` | The human description carried onto every generated surface. | 16.28 |
|
|
264
|
-
| `middleware` | `(
|
|
270
|
+
| `middleware` | `{ [At in keyof Answers]: (next: (ctx?: { request: Request; args: () => Args }) => Promise<Reached>, ctx: { request: Request; args: () => Args }) => Answers[At] \| Promise<Answers[At]> }` | The rungs run per call. | 16.8, 16.11, 16.12, 16.16, 16.17, 16.18, 16.19, 16.20, 16.86 |
|
|
265
271
|
| `timeout` | `number` | How long the call may go without progress. | 16.22, 16.58, 16.59, 16.60, 16.61, 16.77 |
|
|
266
272
|
| `clients` | `Clients` | Which surfaces carry this handler. | 16.37, 20.3 |
|
|
267
273
|
| `crossOrigin` | `boolean \| string[]` | Whether other origins may call it, or follow it over the mux. | 16.24, 18.2, 21.19 |
|
|
@@ -296,7 +302,7 @@ type Refusals<Shaped, Gate, Stored, ArgsGate = Schema<never>, Args = never> = Re
|
|
|
296
302
|
| --- | --- | --- | --- |
|
|
297
303
|
| `Schema<T>` | `((value: unknown) => T) \| StandardSchemaV1<T>` | The two forms a shape may be declared in. | 19.2, 19.3, 19.4, 19.6, 19.8, 19.9, 19.10, 19.18, 19.11, 19.12 |
|
|
298
304
|
| `JsonValue` | `null \| boolean \| number \| string \| JsonValue[] \| { [k: string]: JsonValue }` | What an `Args` may hold. | — |
|
|
299
|
-
| `Issues<T>` | `T extends object ? Partial<Record<Paths<T> \| '', string[]>> : string[]` | What was wrong, keyed by where. | 19.4, 19.19 |
|
|
305
|
+
| `Issues<T>` | `T extends Rpc<infer _Value, infer Args, infer _Failures, infer _Produced> ? Issues<Args> : T extends object ? Partial<Record<Paths<T> \| '', string[]>> : string[]` | What was wrong, keyed by where. | 19.4, 19.19, 19.26 |
|
|
300
306
|
| `Paths<T>` | `string` | The dot-joined leaf paths of a type. | 19.5 |
|
|
301
307
|
| `JsonSchema` | `JsonValue` | A JSON Schema document, the native form. | 19.7, 19.14 |
|
|
302
308
|
| `jsonSchema` | `<T>(document: JsonSchema) => StandardSchemaV1<T>` | A JSON Schema document as a `Schema`, carrying its validator. | 19.13, 19.14, 19.23, 20.11 |
|
|
@@ -349,15 +355,19 @@ type Refusals<Shaped, Gate, Stored, ArgsGate = Schema<never>, Args = never> = Re
|
|
|
349
355
|
|
|
350
356
|
| Name | Signature | Meaning | Rules |
|
|
351
357
|
| --- | --- | --- | --- |
|
|
352
|
-
| `assistant` | `(messages: AssistantMessage[], provider: Provider, options?: AssistantOptions) => AsyncGenerator<AssistantEvent>` | A conversation with a model, as the events it produces. | 44.1, 44.2, 44.3, 44.4, 44.21, 44.36, 44.37, 44.39 |
|
|
358
|
+
| `assistant` | `(messages: AssistantMessage[], provider: Provider, options?: AssistantOptions) => AsyncGenerator<AssistantEvent>` | A conversation with a model, as the events it produces. | 44.1, 44.2, 44.3, 44.4, 44.21, 44.36, 44.37, 44.39, 44.57 |
|
|
353
359
|
| `AssistantMessage` | `{ role: 'user' \| 'assistant'; content: string \| AssistantContent[] }` | One turn of the transcript a caller sends: its words, or its pieces in order. | 44.3, 44.4 |
|
|
354
360
|
| `AssistantContent` | `{ type: 'text'; text: string } \| { type: 'image'; data: string; mimeType: string }` | A piece of a turn: words, or an image as base64 with its type. | 44.5, 44.35, 44.36, 44.37, 44.38, 44.39 |
|
|
355
|
-
| `AssistantEvent` | `{ type: 'text'; text: string } \| { type: 'tool'; id: string; name: string } \| { type: 'input'; id: string; input: unknown } \| { type: 'result'; id: string; text: string; failed: boolean } \| { type: 'done'; stop: string; usage: { input: number; output: number } }` | What a conversation produces: text, a tool call as it starts, its input once written, its result, and the end. | 44.2, 44.11, 44.28 |
|
|
356
|
-
| `AssistantOptions` | `{ mcp?: boolean; maxTurns?: number }` | What `assistant` takes beside a provider. | 44.6, 44.8, 44.11 |
|
|
357
|
-
| `Provider` | `{ run(messages: (AssistantMessage & { content: AssistantContent[] })[], tools: Toolbox, limits: { maxTurns: number; signal: AbortSignal }): AsyncGenerator<
|
|
361
|
+
| `AssistantEvent` | `{ type: 'text'; text: string } \| { type: 'tool'; id: string; name: string; handler: { method: string; address: string } \| undefined } \| { type: 'input'; id: string; input: unknown } \| { type: 'result'; id: string; text: string; failed: boolean; handler: { method: string; address: string } \| undefined; value: unknown } \| { type: 'done'; stop: string; usage: { input: number; output: number } }` | What a conversation produces: text, a tool call as it starts, its input once written, its result, and the end. | 44.2, 44.11, 44.28, 44.48, 44.49 |
|
|
362
|
+
| `AssistantOptions` | `{ mcp?: boolean; maxTurns?: number; signal?: AbortSignal }` | What `assistant` takes beside a provider. | 44.6, 44.8, 44.11, 44.57 |
|
|
363
|
+
| `Provider` | `{ run(messages: (AssistantMessage & { content: AssistantContent[] })[], tools: Toolbox, limits: { maxTurns: number; signal: AbortSignal }): AsyncGenerator<ProviderEvent> }` | What runs a conversation. | 44.2, 44.28, 44.39, 44.50, 44.57 |
|
|
364
|
+
| `ProviderEvent` | `Exclude<AssistantEvent, { type: 'tool' \| 'result' }> \| { type: 'tool'; id: string; name: string } \| { type: 'result'; id: string; text: string; failed: boolean }` | An `AssistantEvent` as a provider yields it, before `assistant` reads the handler and the value off the app's surface. | 44.28, 44.35, 44.50 |
|
|
358
365
|
| `Toolbox` | `{ list: ToolDefinition[]; call(name: string, input: unknown): Promise<ToolAnswer> }` | The app's MCP tools, called as the asker. | 44.6, 44.7, 44.35 |
|
|
359
366
|
| `ToolAnswer` | `{ content: AssistantContent[]; failed: boolean }` | What a tool call answered: its pieces, and whether it failed. | 20.21, 20.22, 44.35 |
|
|
360
367
|
| `ToolDefinition` | `{ name: string; description: string; inputSchema: unknown; annotations: { readOnlyHint: boolean; destructiveHint: boolean; idempotentHint: boolean }; outputSchema: unknown }` | A tool as the app's MCP surface lists it. | 20.14, 20.16, 20.19, 44.6 |
|
|
368
|
+
| `resultsOf` | `<Value>(events: readonly AssistantEvent[], handler: Rpc<Value, never, unknown, unknown>) => Value[]` | What a conversation's calls to one handler answered. | 44.51 |
|
|
369
|
+
| `imagePiece` | `(image: Blob) => Promise<{ type: 'image'; data: string; mimeType: string }>` | An image as a turn's image piece, drawn down to what a model looks at. | 44.52, 44.53, 44.54 |
|
|
370
|
+
| `imageFiles` | `(data: DataTransfer \| null) => File[]` | The images a paste or a drop carries that a model is shown. | 44.55 |
|
|
361
371
|
|
|
362
372
|
## `claudeApi`
|
|
363
373
|
|
|
@@ -372,9 +382,9 @@ type Refusals<Shaped, Gate, Stored, ArgsGate = Schema<never>, Args = never> = Re
|
|
|
372
382
|
| --- | --- | --- | --- |
|
|
373
383
|
| `claudeCode` | `(config?: ClaudeCodeConfig) => Provider` | The visitor's own Claude Code, reached through the bridge paired with their browser, as a provider. | 44.5, 44.13, 44.17, 44.18, 44.19, 44.33 |
|
|
374
384
|
| `ClaudeCodeConfig` | `{ model?: string; fallbackModel?: string; systemPrompt?: string; appendSystemPrompt?: string; effort?: 'low' \| 'medium' \| 'high' \| 'xhigh' \| 'max'; maxBudgetUsd?: number; betas?: string[]; disallowedTools?: string[]; tools?: string[] }` | The Claude Code options a site may set for a turn, and the built-in tools it asks the visitor for. | 44.16, 44.29 |
|
|
375
|
-
| `claudeCode.bridgeCommand` | `(options?: { tools?: string[] }) => { command: string; link: string; expires: number }` | The command and the link that pair a bridge with this browser, granting the built-in tools it is given. | 44.14, 44.32, 44.33, 44.40 |
|
|
385
|
+
| `claudeCode.bridgeCommand` | `(options?: { tools?: string[] }) => { command: string; link: string; install: string; expires: number }` | The command and the link that pair a bridge with this browser, granting the built-in tools it is given, and the command that installs the app the link opens. | 44.14, 44.32, 44.33, 44.40, 44.56 |
|
|
376
386
|
| `claudeCode.bridge` | `(options?: { tools?: string[] }) => AsyncGenerator<BridgeStatus>` | This browser's pairing, as it changes. | 44.20, 44.22, 44.32, 44.33, 44.34, 44.40 |
|
|
377
|
-
| `BridgeStatus` | `{ paired: boolean; command: string \| undefined; link: string \| undefined }` | Whether a bridge is paired, and the command and the link that pair one where none is. | 44.20, 44.40 |
|
|
387
|
+
| `BridgeStatus` | `{ paired: boolean; command: string \| undefined; link: string \| undefined; install: string \| undefined }` | Whether a bridge is paired, and the command and the link that pair one where none is, with the command that installs the app the link opens. | 44.20, 44.40, 44.56 |
|
|
378
388
|
| `/__abide/bridge` | `GET`, `POST` | Where a bridge pairs, and is relayed its turns. | 36.7, 44.14, 44.15, 44.19, 44.23, 44.26, 16.57, 16.78 |
|
|
379
389
|
|
|
380
390
|
# Ambient values
|
|
@@ -392,6 +402,13 @@ type Refusals<Shaped, Gate, Stored, ArgsGate = Schema<never>, Args = never> = Re
|
|
|
392
402
|
| --- | --- | --- | --- |
|
|
393
403
|
| `request` | `() => Request` | The request being served. | 18.16, 18.17, 18.18, 22.1 |
|
|
394
404
|
|
|
405
|
+
## `requestIP`
|
|
406
|
+
|
|
407
|
+
| Name | Signature | Meaning | Rules |
|
|
408
|
+
| --- | --- | --- | --- |
|
|
409
|
+
| `requestIP` | `() => ReceivedFrom \| 'in-process'` | Where the request being served came from. | 22.1, 22.12, 22.13 |
|
|
410
|
+
| `ReceivedFrom` | `{ address: string; family: 'IPv4' \| 'IPv6'; port: number } \| null` | The peer a listener received a request from. | 22.12 |
|
|
411
|
+
|
|
395
412
|
## `response`
|
|
396
413
|
|
|
397
414
|
| Name | Signature | Meaning | Rules |
|
|
@@ -406,6 +423,7 @@ type Refusals<Shaped, Gate, Stored, ArgsGate = Schema<never>, Args = never> = Re
|
|
|
406
423
|
| `route.params` | `Reactive<Params>` | The matched route's segments — typed by its own route in a page or a layout, and `Params` in any other file. | 23.1, 23.5, 23.9, 30.23, 31.15 |
|
|
407
424
|
| `Params` | `Record<string, string \| string[]>` | What a matched route's segments are. | 23.5 |
|
|
408
425
|
| `route.name` | `Reactive<string>` | The resolution path, the same under any mount path. | 23.1, 23.6, 23.14, 31.15 |
|
|
426
|
+
| `route.index` | `Reactive<number>` | The place of the entry the address bar stands at in the history this app's router wrote. | 23.1, 23.28, 23.29, 31.15 |
|
|
409
427
|
| `route.navigating` | `Reactive<boolean>` | Whether a navigation is in flight. | 23.1, 31.15 |
|
|
410
428
|
|
|
411
429
|
## `online`
|
|
@@ -446,6 +464,12 @@ type Refusals<Shaped, Gate, Stored, ArgsGate = Schema<never>, Args = never> = Re
|
|
|
446
464
|
| --- | --- | --- | --- |
|
|
447
465
|
| `server` | `<WebSocketData>() => Server<WebSocketData>` | The listening server. | 22.1 |
|
|
448
466
|
|
|
467
|
+
## `isServer`
|
|
468
|
+
|
|
469
|
+
| Name | Signature | Meaning | Rules |
|
|
470
|
+
| --- | --- | --- | --- |
|
|
471
|
+
| `isServer` | `() => boolean` | Whether the work running is a server's. | 22.11, 12.7, 23.7, 23.8 |
|
|
472
|
+
|
|
449
473
|
## `health`
|
|
450
474
|
|
|
451
475
|
| Name | Signature | Meaning | Rules |
|
|
@@ -544,7 +568,7 @@ type Refusals<Shaped, Gate, Stored, ArgsGate = Schema<never>, Args = never> = Re
|
|
|
544
568
|
|
|
545
569
|
| Name | Signature | Meaning | Rules |
|
|
546
570
|
| --- | --- | --- | --- |
|
|
547
|
-
| `navigate` | `(url?: URL \| string, options?: { replace?: boolean, keepScroll?: boolean })
|
|
571
|
+
| `navigate` | `{ (by: number): Promise<void>; (url?: URL \| string, options?: { replace?: boolean, keepScroll?: boolean }): Promise<void> }` | Navigates to an address, or steps through the history. | 30.7, 30.38, 30.39, 30.9, 30.10, 30.11, 30.12, 30.13, 30.14, 30.15, 30.16, 30.17, 30.18, 30.20, 30.21, 30.22, 30.23, 30.24, 30.25, 30.27, 30.29, 30.30, 30.31, 30.32, 45.12, 45.24 |
|
|
548
572
|
|
|
549
573
|
# `.abide` files
|
|
550
574
|
|
|
@@ -576,13 +600,13 @@ type Refusals<Shaped, Gate, Stored, ArgsGate = Schema<never>, Args = never> = Re
|
|
|
576
600
|
| `name={expr}` | A reactive attribute or property. | 32.3, 32.20, 32.23, 32.37, 32.70, 32.71 |
|
|
577
601
|
| `on<event>={fn}` | A native listener on an element, and an ordinary prop on a component. | 32.4, 32.75 |
|
|
578
602
|
| `name="…{expr}…"` | An interpolated quoted value. | 32.3, 32.71 |
|
|
579
|
-
| `bind:value` | Two-way bind on an element. | 5.16, 32.5, 32.58, 32.59, 32.60, 32.61, 32.62, 32.72, 32.74, 32.75, 32.76 |
|
|
603
|
+
| `bind:value` | Two-way bind on an element. | 5.16, 32.5, 32.58, 32.59, 32.60, 32.61, 32.62, 32.72, 32.74, 32.75, 32.76, 32.78 |
|
|
580
604
|
| `bind:prop={state}` | Hands a component prop the caller's `Reactive`, or a `{get, set}` pair, to write through. | 32.6, 33.6, 33.8, 14.18, 32.76 |
|
|
581
|
-
| `bind:checked` | A boolean bind on an input. | 32.7, 32.72, 32.74, 32.75, 32.76 |
|
|
582
|
-
| `bind:open` | The same, on a `<details>`. | 32.7, 32.72, 32.74, 32.75, 32.76 |
|
|
605
|
+
| `bind:checked` | A boolean bind on an input. | 32.7, 32.72, 32.74, 32.75, 32.76, 32.78 |
|
|
606
|
+
| `bind:open` | The same, on a `<details>`. | 32.7, 32.72, 32.74, 32.75, 32.76, 32.78 |
|
|
583
607
|
| `bind:group` | Radio or checkbox membership. | 32.8, 32.72, 32.74, 32.75, 32.76 |
|
|
584
|
-
| `bind:files` | A file input's files, as a list. | 32.73, 32.72, 32.74, 32.75, 32.76 |
|
|
585
|
-
| `bind:value={{get, set}}` | Two-way bind over an explicit accessor pair, on an element or a component. | 32.5, 32.6 |
|
|
608
|
+
| `bind:files` | A file input's files, as a list. | 32.73, 32.72, 32.74, 32.75, 32.76, 32.78 |
|
|
609
|
+
| `bind:value={{get, set}}` | Two-way bind over an explicit accessor pair, on an element or a component. | 32.5, 32.6, 32.78 |
|
|
586
610
|
| `bind:element={Reactive<Element> \| ((element: Element) => void \| Disposer)}` | A node reference. | 32.9, 32.38, 32.66, 32.68, 32.69 |
|
|
587
611
|
| `class:name={cond}` | Toggles a class. | 32.10, 32.71 |
|
|
588
612
|
| `style:prop={value}` | Sets one style property. | 32.10, 32.19, 32.71 |
|
|
@@ -645,7 +669,7 @@ type Refusals<Shaped, Gate, Stored, ArgsGate = Schema<never>, Args = never> = Re
|
|
|
645
669
|
| `[[name]]` | An optional segment. | 23.5, 30.4, 30.34, 30.36 |
|
|
646
670
|
| `[...name]` | A rest segment, terminal. | 23.5, 30.5, 30.34, 30.36 |
|
|
647
671
|
| `[name=NAME]` · `[[name=NAME]]` · `[...name=NAME]` | A dynamic segment a param file's matcher decides. | 19.1, 23.26, 23.27, 30.19, 30.35, 30.36, 30.37 |
|
|
648
|
-
| `/__abide/**` | Every endpoint abide controls. | 20.8 |
|
|
672
|
+
| `/__abide/**` | Every endpoint abide controls. | 20.8, 37.19 |
|
|
649
673
|
|
|
650
674
|
## `render`
|
|
651
675
|
|
|
@@ -683,7 +707,7 @@ type Refusals<Shaped, Gate, Stored, ArgsGate = Schema<never>, Args = never> = Re
|
|
|
683
707
|
| `ABIDE_MAX_REQUEST_BODY_SIZE` | `number` | The default ceiling on a mutation's body. | 16.13, 16.54, 16.55, 16.78 |
|
|
684
708
|
| `ABIDE_MAX_SOCKET_MESSAGE_SIZE` | `number` | The ceiling on a frame received over the socket mux, in bytes. | 18.28 |
|
|
685
709
|
| `ABIDE_MAX_SOCKET_SUBSCRIPTIONS` | `number` | How many values one connection to the socket mux may follow. | 18.31, 18.32 |
|
|
686
|
-
| `ABIDE_OFFLINE` | `boolean` | Whether the app keeps its pages and its bundle on the device, for when the network is gone. | 45.1, 45.2, 45.3, 45.4, 45.5, 45.6, 45.7, 45.8, 45.9, 45.10, 45.11, 45.12, 45.13, 45.14, 45.15, 45.16, 45.17, 45.18, 45.19, 45.20, 45.21, 45.22, 45.23, 45.24 |
|
|
710
|
+
| `ABIDE_OFFLINE` | `boolean` | Whether the app keeps its pages and its bundle on the device, for when the network is gone. | 45.1, 45.2, 45.3, 45.4, 45.5, 45.6, 45.7, 45.8, 45.9, 45.10, 45.11, 45.12, 45.13, 45.14, 45.15, 45.16, 45.17, 45.18, 45.19, 45.20, 45.21, 45.22, 45.23, 45.24, 45.25, 45.26 |
|
|
687
711
|
| `ABIDE_STOP_TIMEOUT` | `number` | How long `App.stop` drains, in ms. | 42.17, 42.18 |
|
|
688
712
|
| `ABIDE_MAX_STREAM_BUFFER_SIZE` | `number` | The cap on a stream transcript held in memory. | 36.18 |
|
|
689
713
|
| `ABIDE_MAX_LOG_BUFFER_COUNT` | `number` | How many lines `log.records` is trimmed back to. | 28.1 |
|
|
@@ -724,10 +748,12 @@ type Refusals<Shaped, Gate, Stored, ArgsGate = Schema<never>, Args = never> = Re
|
|
|
724
748
|
|
|
725
749
|
| Name | Signature | Meaning | Rules |
|
|
726
750
|
| --- | --- | --- | --- |
|
|
727
|
-
| `middleware` | `(...rungs: ((next: (ctx?: { request: Request }) => Promise<Response>, ctx: { request: Request }) => Response \| Failed<string, unknown> \| Promise<Response \| Failed<string, unknown>>)[]) => () => void` | The per-request lane at the calling file's route. | 18.26, 37.2, 37.3, 37.13, 37.14, 37.15 |
|
|
751
|
+
| `middleware` | `(...rungs: ((next: (ctx?: { request: Request }) => Promise<Response>, ctx: { request: Request; lane: Lane }) => Response \| Failed<string, unknown> \| Promise<Response \| Failed<string, unknown>>)[]) => () => void` | The per-request lane at the calling file's route. | 18.26, 37.2, 37.3, 37.13, 37.14, 37.15, 37.19, 37.20 |
|
|
752
|
+
| `Lane` | `'page' \| 'handler' \| 'file' \| 'openapi' \| 'mcp' \| 'bridge' \| 'socket' \| 'abide'` | What answers a request a `middleware` rung is handed. | 37.19 |
|
|
728
753
|
| `onStart` | `(fn: (start: () => Promise<void>) => void \| Promise<void>) => () => void` | Wraps the boot. | 37.4, 37.6, 37.13 |
|
|
729
754
|
| `onStop` | `(fn: (stop: () => Promise<void>) => void \| Promise<void>) => () => void` | Mirrors it for teardown. | 37.4, 37.6, 37.13 |
|
|
730
|
-
| `onError` | `(fn: (error: unknown) => unknown) => () => void` | Runs on an unexpected error at the calling file's route. | 37.5, 37.8, 37.13 |
|
|
755
|
+
| `onError` | `(fn: (error: unknown) => unknown) => () => void` | Runs on an unexpected error at the calling file's route, or in the browser below the calling component. | 37.5, 37.8, 37.13, 37.16, 37.17, 37.18, 37.21, 12.6 |
|
|
756
|
+
| `onRefusal` | `(fn: (refusal: Failed<string, unknown>, call: { method: 'GET' \| 'POST' \| 'PUT' \| 'PATCH' \| 'DELETE'; url: string }) => unknown) => () => void` | What the browser hands each refusal a call over http is answered with, below the calling component. | 37.13, 37.22, 37.23, 37.24, 37.25, 37.26, 37.27 |
|
|
731
757
|
| `onConfig` | `(fn: ConfigDefaults \| null, options?: ConfigOptions) => () => void` | The app's config defaults. | 27.6, 37.7, 37.13 |
|
|
732
758
|
| `onHealth` | `(report: () => unknown \| Promise<unknown>) => () => void` | The app's health reporter. | 25.2, 37.7, 37.13 |
|
|
733
759
|
| `onPrincipal` | `(resolve: (claims: unknown) => unknown \| Promise<unknown>) => () => void` | Turns claims into the app's half of a principal. | 26.4, 37.7, 37.13 |
|
|
@@ -753,8 +779,8 @@ type Refusals<Shaped, Gate, Stored, ArgsGate = Schema<never>, Args = never> = Re
|
|
|
753
779
|
| --- | --- | --- | --- |
|
|
754
780
|
| `createApp` | `() => Promise<App>` | The app built and booted, with no socket bound. | 42.1, 42.2, 42.3, 42.4, 42.16, 37.4, 37.6, 38.100 |
|
|
755
781
|
| `App` | `interface App` | What a host, a test or a script holds the app as. | 42.12, 42.13 |
|
|
756
|
-
| `App.fetch` | `(request: Request) => Promise<Response>` | The whole request path, entered in process. | 42.5, 42.6 |
|
|
757
|
-
| `App.run` | `<Result>(fn: () => Result \| Promise<Result>, options?: { request?: Request; principal?: Record<string, unknown
|
|
782
|
+
| `App.fetch` | `(request: Request, options?: { principal?: Record<string, unknown>; caller?: string }) => Promise<Response>` | The whole request path, entered in process. | 42.5, 42.6, 42.20, 42.21 |
|
|
783
|
+
| `App.run` | `<Result>(fn: () => Result \| Promise<Result>, options?: { request?: Request; principal?: Record<string, unknown>; caller?: string }) => Promise<Result>` | One scope around a function, and nothing else. | 42.7, 42.8, 42.19, 42.21, 11.38 |
|
|
758
784
|
| `App.listen` | `(options?: { port?: number; hostname?: string; unix?: string }) => Promise<void>` | The socket, bound. | 42.9, 16.23, 16.56, 18.28, 18.29, 18.30 |
|
|
759
785
|
| `App.stop` | `() => Promise<void>` | The drain and the teardown. | 42.10, 42.11, 42.15, 42.17, 37.4 |
|
|
760
786
|
| `App[Symbol.asyncDispose]` | `() => Promise<void>` | `App.stop`, under the name `await using` calls. | 42.14 |
|
|
@@ -763,7 +789,7 @@ type Refusals<Shaped, Gate, Stored, ArgsGate = Schema<never>, Args = never> = Re
|
|
|
763
789
|
|
|
764
790
|
| Name | Signature | Meaning | Rules |
|
|
765
791
|
| --- | --- | --- | --- |
|
|
766
|
-
| `mount` | `(component: Component) => Promise<Mounted>` | A bound component, rendered into the document's body and hydrated there. | 38.119, 38.121 |
|
|
792
|
+
| `mount` | `(component: Component) => Promise<Mounted>` | A bound component, rendered into the document's body and hydrated there. | 38.119, 38.121, 38.134 |
|
|
767
793
|
| `Mounted` | `{ stop(): void; [Symbol.dispose](): void }` | A component `mount` hydrated, until it is stopped. | 38.119 |
|
|
768
794
|
|
|
769
795
|
# The measurement harness
|
|
@@ -787,7 +813,7 @@ rows a runner prints, and an adapter for an abide app.
|
|
|
787
813
|
|
|
788
814
|
| Name | Meaning | Rules |
|
|
789
815
|
| --- | --- | --- |
|
|
790
|
-
| `preload = ["@abide/harness/preload"]` | The `[test]` preload that registers a DOM with the measure lane's patches installed. | 43.4, 43.28 |
|
|
816
|
+
| `preload = ["@abide/harness/preload"]` | The `[test]` preload that registers a DOM with the measure lane's patches installed. | 43.4, 43.28, 43.35 |
|
|
791
817
|
|
|
792
818
|
## `@abide/harness/engine` — what the browser engine did
|
|
793
819
|
|
|
@@ -884,16 +910,16 @@ rows a runner prints, and an adapter for an abide app.
|
|
|
884
910
|
| `abide run <file> [args…]` | Runs a script under the abide runtime. | 38.2, 38.57 |
|
|
885
911
|
| `abide check [dir…]` | The type-checker over a `.abide` tree. | 38.3, 38.31, 38.32, 38.33, 38.40, 38.105, 38.123 |
|
|
886
912
|
| `abide format [--check] [dir…]` | The formatter over a `.abide` tree. | 38.25, 38.125, 38.126, 38.127, 38.128, 38.129 |
|
|
887
|
-
| `abide routes [--json]` | Every address the app answers, the file answering it, what each matcher takes, and where each hook is filed. | 38.108, 38.123 |
|
|
888
|
-
| `abide dev [--port <n>]` | Watches the project and keeps the app up. | 16.23, 16.56, 37.8, 37.9, 38.4, 38.14, 38.15, 38.16, 38.17, 38.19, 38.24, 38.25, 38.26, 38.28, 38.30, 38.35, 38.36, 38.37, 38.38, 38.41, 38.43, 38.58, 38.63, 38.64, 38.65, 38.94, 38.96, 38.97, 38.123 |
|
|
913
|
+
| `abide routes [--json]` | Every address the app answers, the file answering it, what each matcher takes, the rungs each handler names, and where each hook is filed. | 38.108, 38.123, 38.135 |
|
|
914
|
+
| `abide dev [--port <n>] [--hostname <host>]` | Watches the project and keeps the app up. | 16.23, 16.56, 37.8, 37.9, 38.4, 38.14, 38.15, 38.16, 38.17, 38.19, 38.24, 38.25, 38.26, 38.28, 38.30, 38.35, 38.36, 38.37, 38.38, 38.41, 38.43, 38.58, 38.63, 38.64, 38.65, 38.94, 38.96, 38.97, 38.123, 38.136 |
|
|
889
915
|
| `abide build` | Builds the client into content-hashed chunks and a manifest. | 38.43, 38.5, 38.18, 38.25, 38.26, 38.27, 38.30, 38.66, 38.94, 38.123 |
|
|
890
|
-
| `abide start [--port <n>]` | Boots the built app. | 37.8, 37.10, 37.11, 37.12, 38.6, 38.100, 38.20, 38.21, 38.22, 38.23, 38.25, 38.26, 38.27, 38.28, 38.29, 38.58, 38.67, 38.68, 38.95, 38.97, 38.110, 38.123 |
|
|
891
|
-
| `abide [--url <origin>] [--port <n>]` | The interactive shell — on the built app it boots, or on the running app `--url` names. | 37.8, 37.10, 37.11, 37.12, 38.6, 38.7, 38.53, 38.54, 38.55, 38.58, 38.59, 38.60, 38.62, 38.123 |
|
|
916
|
+
| `abide start [--port <n>] [--hostname <host>]` | Boots the built app. | 37.8, 37.10, 37.11, 37.12, 38.6, 38.100, 38.20, 38.21, 38.22, 38.23, 38.25, 38.26, 38.27, 38.28, 38.29, 38.58, 38.67, 38.68, 38.95, 38.97, 38.110, 38.123, 38.136 |
|
|
917
|
+
| `abide [--url <origin>] [--port <n>] [--hostname <host>]` | The interactive shell — on the built app it boots, or on the running app `--url` names. | 37.8, 37.10, 37.11, 37.12, 38.6, 38.7, 38.53, 38.54, 38.55, 38.58, 38.59, 38.60, 38.62, 38.123, 38.136 |
|
|
892
918
|
| `abide call <address> [args]` | One call to one handler. | 38.8, 38.61, 38.110 |
|
|
893
919
|
| `abide openapi [--url <origin>]` | The OpenAPI document printed rather than served. | 38.9, 38.25, 38.110, 38.111, 38.123 |
|
|
894
920
|
| `abide mcp [--url <origin>]` | The app's MCP server over stdio. | 38.9, 38.13, 38.25, 38.110, 38.123 |
|
|
895
921
|
| `abide watch <address> [args]` | A live subscription to one of the app's followed `GET`s. | 38.69 |
|
|
896
|
-
| `abide compile [--target] [--out] [--platforms]` | One standalone executable. | 37.8, 37.10, 37.11, 37.12, 38.10, 38.25, 38.26, 38.44, 38.45, 38.46, 38.47, 38.48, 38.49, 38.50, 38.51, 38.52, 38.56, 38.93, 38.97, 38.123 |
|
|
922
|
+
| `abide compile [--target] [--out] [--platforms]` | One standalone executable. | 37.8, 37.10, 37.11, 37.12, 38.10, 38.25, 38.26, 38.44, 38.45, 38.46, 38.47, 38.48, 38.49, 38.50, 38.51, 38.52, 38.56, 38.93, 38.97, 38.123, 38.136 |
|
|
897
923
|
| `abide bundle [--out]` | A desktop app for the host platform, with a window on the app. | 38.10, 38.25, 38.26, 38.70, 38.71, 38.72, 38.73, 38.74, 38.75, 38.76, 38.77, 38.78, 38.79, 38.80, 38.81, 38.82, 38.83, 38.84, 38.85, 38.86, 38.87, 38.88, 38.89, 38.90, 38.91, 38.92, 38.101, 38.102, 38.123 |
|
|
898
924
|
| `abide lsp` | The `.abide` language server, over stdio. | 38.11, 38.34, 38.39, 38.98, 38.116, 38.117, 38.118, 38.130 |
|
|
899
925
|
| `--help` · `-h` · `abide help` | Usage, generated from the command list. | 38.12, 38.113, 38.114 |
|
|
@@ -906,6 +932,6 @@ site's `claudeCode`.
|
|
|
906
932
|
|
|
907
933
|
| Command | Meaning | Rules |
|
|
908
934
|
| --- | --- | --- |
|
|
909
|
-
| `abide-bridge <site> <code> [--claude <path>] [--env NAME=VALUE]… [-- <options>]` | This machine's Claude Code, paired with the browser a site minted the code for. | 44.15, 44.16, 44.24, 44.25, 44.27, 44.30, 44.44, 44.45, 44.46 |
|
|
935
|
+
| `abide-bridge <site> <code> [--claude <path>] [--env NAME=VALUE]… [-- <options>]` | This machine's Claude Code, paired with the browser a site minted the code for. | 44.15, 44.16, 44.24, 44.25, 44.27, 44.30, 44.44, 44.45, 44.46, 44.47 |
|
|
910
936
|
| `abide-bridge install [--claude <path>] [--env NAME=VALUE]… [-- <options>]` | The app that opens a site's `abide-bridge` links on this machine, registered. | 44.41, 44.42, 44.43, 44.44 |
|
|
911
937
|
| `abide-bridge uninstall` | `abide-bridge install`, undone. | 44.43 |
|