@abide/abide 0.101.0 → 0.103.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/CHANGELOG.md +26 -0
- package/bin/abide.ts +226 -164
- package/docs/REGISTRY.md +730 -0
- package/docs/RULEBOOK.md +2768 -0
- package/docs/abide.md +13127 -0
- package/package.json +6 -3
- package/scaffold/AGENTS.md +38 -0
- package/scaffold/CLAUDE.md +1 -0
- package/scaffold/src/layout.abide +18 -0
- package/src/compiler/Lowering.ts +78 -9
- package/src/compiler/ShadowMap.ts +2 -2
- package/src/compiler/TypeSession.ts +341 -71
- package/src/compiler/appMap.ts +96 -0
- package/src/compiler/argsSchemaOf.ts +1 -1
- package/src/compiler/checkApp.ts +53 -8
- package/src/compiler/checkedShadow.ts +73 -6
- package/src/compiler/classifyRead.ts +6 -4
- package/src/compiler/classifyTemplate.ts +1 -1
- package/src/compiler/compileApp.ts +598 -200
- package/src/compiler/compiledEntry.ts +48 -40
- package/src/compiler/componentGraph.ts +57 -71
- package/src/compiler/declaredExports.ts +26 -9
- package/src/compiler/emitClient.ts +142 -72
- package/src/compiler/emitComponent.ts +41 -12
- package/src/compiler/emitSource.ts +102 -13
- package/src/compiler/handlersUnder.ts +164 -76
- package/src/compiler/hooksCalled.ts +35 -0
- package/src/compiler/index.ts +7 -0
- package/src/compiler/mountsOf.ts +150 -0
- package/src/compiler/nearest.ts +14 -0
- package/src/compiler/parseAbide.ts +157 -20
- package/src/compiler/projectShadow.ts +250 -19
- package/src/compiler/reactiveTypes.ts +20 -7
- package/src/compiler/readSources.ts +15 -2
- package/src/compiler/readsIn.ts +62 -8
- package/src/compiler/renderMarkup.ts +3 -3
- package/src/compiler/scaffold.ts +37 -15
- package/src/compiler/serveLanguage.ts +101 -34
- package/src/compiler/sharedModuleWrites.ts +2 -2
- package/src/compiler/sourceMapOf.ts +193 -0
- package/src/compiler/splitImports.ts +205 -83
- package/src/compiler/tokenize.ts +14 -0
- package/src/compiler/writeDefaultProject.ts +29 -2
- package/src/server/CLIENT_BUILD.ts +11 -13
- package/src/server/DEFAULT_PORT.ts +1 -1
- package/src/server/MODULE_QUERIES.ts +27 -0
- package/src/server/TABLES.ts +7 -0
- package/src/server/VIRTUAL_DIRECTORY.ts +4 -5
- package/src/server/abideModules.ts +457 -0
- package/src/server/answerFailure.ts +16 -6
- package/src/server/answerRequest.ts +241 -107
- package/src/server/answerRpc.ts +107 -33
- package/src/server/answerSocket.ts +65 -20
- package/src/server/answerValue.ts +22 -9
- package/src/server/appDirectories.ts +1 -1
- package/src/server/appPlugins.ts +1 -1
- package/src/server/appTree.ts +238 -0
- package/src/server/argsFor.ts +2 -2
- package/src/server/assistant.ts +2 -2
- package/src/server/bridgeRelay.ts +6 -8
- package/src/server/claudeCode.ts +0 -6
- package/src/server/clientBuildOptions.ts +8 -3
- package/src/server/coerceArgs.ts +1 -1
- package/src/server/commands.ts +38 -37
- package/src/server/componentModules.d.ts +2 -1
- package/src/server/compressAnswer.ts +4 -4
- package/src/server/config.ts +25 -29
- package/src/server/configFields.ts +31 -25
- package/src/server/createApp.ts +77 -79
- package/src/server/devWorker.ts +118 -181
- package/src/server/executableName.ts +4 -0
- package/src/server/fenceServer.ts +57 -32
- package/src/server/generatedSurfaces.ts +99 -66
- package/src/server/hooks.ts +137 -52
- package/src/server/iconAccent.ts +191 -0
- package/src/server/index.ts +12 -7
- package/src/server/installSourceMaps.ts +93 -0
- package/src/server/launcherOptions.ts +33 -31
- package/src/server/launcherPage.ts +107 -64
- package/src/server/manifestOf.ts +16 -13
- package/src/server/namesUnder.ts +2 -2
- package/src/server/nativeMenu.ts +6 -6
- package/src/server/negotiateEncoding.ts +1 -1
- package/src/server/preload.ts +13 -0
- package/src/server/principal.ts +10 -5
- package/src/server/realOrAsGiven.ts +10 -0
- package/src/server/refuseAddressCollision.ts +21 -14
- package/src/server/remote.ts +49 -52
- package/src/server/render.ts +65 -94
- package/src/server/renderComponent.ts +5 -0
- package/src/server/reportHealth.ts +2 -2
- package/src/server/requestScope.ts +12 -1
- package/src/server/runBuild.ts +24 -0
- package/src/server/runCompiled.ts +5 -5
- package/src/server/runDesktop.ts +48 -28
- package/src/server/serveBuild.ts +43 -52
- package/src/server/serveDev.ts +79 -37
- package/src/server/shell.ts +7 -22
- package/src/server/sourceMappings.ts +139 -0
- package/src/server/surfaceOf.ts +20 -3
- package/src/server/testBuild.ts +1 -19
- package/src/server/withAbideSources.ts +117 -0
- package/src/shared/ADDRESSES.ts +10 -18
- package/src/shared/APP_META.ts +7 -0
- package/src/shared/CopyOptions.ts +1 -1
- package/src/shared/DEBUG_META.ts +1 -1
- package/src/shared/LAUNCHER_FILES.ts +9 -0
- package/src/shared/RESERVED_DIRECTORIES.ts +24 -0
- package/src/shared/cookies.ts +2 -2
- package/src/shared/csp.ts +1 -1
- package/src/shared/escapeText.ts +1 -1
- package/src/shared/filledPath.ts +85 -0
- package/src/shared/framing.ts +79 -6
- package/src/shared/headKeyOf.ts +2 -0
- package/src/shared/index.ts +2 -1
- package/src/shared/log.ts +27 -13
- package/src/shared/matchRoute.ts +23 -4
- package/src/{ui → shared}/menuBridge.ts +2 -2
- package/src/shared/menuItem.ts +4 -4
- package/src/shared/onMenu.ts +58 -0
- package/src/shared/reactive/Keyed.ts +2 -2
- package/src/shared/reactive/NotLanded.ts +1 -1
- package/src/shared/reactive/Reactive.ts +43 -43
- package/src/shared/reactive/argsContract.ts +4 -4
- package/src/shared/reactive/canonicalKey.ts +4 -4
- package/src/shared/reactive/chunksOfStream.ts +6 -0
- package/src/shared/reactive/index.ts +1 -1
- package/src/shared/reactive/recordWrites.ts +103 -5
- package/src/shared/reactive/structural.ts +1 -1
- package/src/shared/reactive/tracking.ts +1 -1
- package/src/shared/reactive/watch.ts +3 -3
- package/src/shared/refuse.ts +1 -1
- package/src/{ui → shared}/reportMenu.ts +8 -10
- package/src/shared/routePattern.ts +122 -48
- package/src/shared/rpc.ts +37 -8
- package/src/shared/rpcRequest.ts +27 -3
- package/src/shared/url.ts +4 -44
- package/src/shared/writePath.ts +1 -1
- package/src/ui/LAYER_NAMES.ts +1 -1
- package/src/ui/List.ts +3 -3
- package/src/ui/MOUNTING_LEVEL.ts +18 -0
- package/src/ui/Mismatch.ts +1 -1
- package/src/ui/RawRun.ts +1 -1
- package/src/ui/Router.ts +37 -36
- package/src/ui/Scope.ts +1 -1
- package/src/ui/TryRegion.ts +2 -2
- package/src/ui/applyHead.ts +33 -0
- package/src/ui/index.ts +1 -1
- package/src/ui/moveNode.ts +1 -1
- package/src/ui/reconcile.ts +2 -2
- package/src/ui/routing.ts +2 -2
- package/src/ui/setAttribute.ts +1 -1
- package/src/ui/setText.ts +1 -1
- package/src/ui/socketWire.ts +9 -7
- package/src/ui/wire.ts +1 -1
- package/scaffold/src/server/app.ts +0 -6
- package/scaffold/src/shared/.gitkeep +0 -0
- package/scaffold/src/ui/app.html +0 -8
- package/src/server/componentImports.ts +0 -56
- /package/scaffold/src/{ui/pages/page.abide → index.abide} +0 -0
- /package/src/{compiler → shared}/SPECIFIERS.ts +0 -0
package/docs/REGISTRY.md
ADDED
|
@@ -0,0 +1,730 @@
|
|
|
1
|
+
# Registry
|
|
2
|
+
|
|
3
|
+
Every name an app author can write, with its type and what it is.
|
|
4
|
+
|
|
5
|
+
## What this document is
|
|
6
|
+
|
|
7
|
+
A **registry**. One row per name, and the row answers exactly one question: *what is this?*
|
|
8
|
+
|
|
9
|
+
## What belongs here, and what does not
|
|
10
|
+
|
|
11
|
+
| A statement | Goes | Because |
|
|
12
|
+
| --- | --- | --- |
|
|
13
|
+
| Answerable from the type alone | here | a signature and its one-line meaning are the same fact |
|
|
14
|
+
| Constrains behavior, at build time or run time | RULEBOOK.md | a requirement has a clause number, and is stated once |
|
|
15
|
+
| Explains why the design is this way | a guide in `packages/dogfood/src` | a reason is read once and never looked up |
|
|
16
|
+
| A measurement | the harness | a number in prose is a number nothing reruns |
|
|
17
|
+
|
|
18
|
+
## Format rules
|
|
19
|
+
|
|
20
|
+
These are immutable. A change to them is a change to what this document is.
|
|
21
|
+
|
|
22
|
+
1. **A row is a name that appears in application source.** An internal type nothing can be written
|
|
23
|
+
against is not a row.
|
|
24
|
+
2. **The meaning cell is ONE sentence**, and it states what the name *is*. Never when it runs, what
|
|
25
|
+
it requires, what it refuses, or what happens if it does.
|
|
26
|
+
3. **No requirement keyword appears in this document.** MUST, MUST NOT, SHALL, SHOULD, SHOULD NOT
|
|
27
|
+
and MAY belong to RULEBOOK.md, and a check refuses them here.
|
|
28
|
+
4. **No rationale, no measurement, no example.** A row that wants any of the three is a row whose
|
|
29
|
+
behavior is being restated; cite the clause instead.
|
|
30
|
+
5. **Behavior is cited, never described.** The `Rules` cell lists the clauses that govern the name.
|
|
31
|
+
`—` is permitted and is an admission: it says this name has no behavior of its own.
|
|
32
|
+
|
|
33
|
+
The one-sentence rule is what keeps the two documents apart. A second sentence is a rule every time.
|
|
34
|
+
|
|
35
|
+
## Type parameter order
|
|
36
|
+
|
|
37
|
+
Slots one and two are the two ends of the arrow the name is, the end a reader came for written
|
|
38
|
+
first. `Reactive<Stored, Accepted>` is a value read and then written,
|
|
39
|
+
`Rpc<Value, Args>` is a call answered and then made, `reactive<Accepted, Shaped>` is the value form
|
|
40
|
+
taking and then holding what its transform hands back, and `reactive<Computed, Args>` is a keyed body returning and then taking. Slot three is the
|
|
41
|
+
second value type wherever the first two did not already carry it, which on `Keyed<Stored, Args,
|
|
42
|
+
Accepted, Failures>` is the inner value's own `Accepted`. Then `Failures`, then
|
|
43
|
+
`Produced`.
|
|
44
|
+
|
|
45
|
+
# Reactive primitives
|
|
46
|
+
|
|
47
|
+
## `reactive` — the one value
|
|
48
|
+
|
|
49
|
+
### The value
|
|
50
|
+
|
|
51
|
+
| Name | Signature | Meaning | Rules |
|
|
52
|
+
| --- | --- | --- | --- |
|
|
53
|
+
| `Reactive` | `Reactive<Stored = undefined, Accepted = Stored, Failures = never, Produced = Stored>` | The value type every producer in this design hands back. | 1.1, 1.2, 1.3, 1.4, 1.6, 1.7, 1.8, 9.1, 9.14 |
|
|
54
|
+
| `Keyed` | `Keyed<Stored, Args, Accepted = Stored, Failures = never, Produced = Stored>` | What a body declaring a parameter hands back: a factory carrying the probes and the triggers. | 4.13, 11.2, 11.4, 11.6, 11.23, 11.55 |
|
|
55
|
+
| `Accepted` | `unknown` | What a factory and a write take, before the gates run. | 4.1, 4.2 |
|
|
56
|
+
| `Stored` | `unknown` | What is held, and what a read returns. | 4.7, 5.2 |
|
|
57
|
+
| `Failures` | union of `Failed` | What a read hands back in place of a value. | 1.3 |
|
|
58
|
+
| `Shaped` | `unknown` | What a `transform` hands back: the value to store, or a refusal. | 4.6, 4.9 |
|
|
59
|
+
| `Produced` | `unknown` | What a production carries, where that differs from what is stored. | 1.2, 9.3 |
|
|
60
|
+
| `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 |
|
|
61
|
+
| `reactive` | `<Computed, Shaped = Awaited<Computed>, Gate = Schema<Awaited<Computed>>>(body: () => Computed, options?: Omit<ReactiveOptions<Awaited<Computed>, Kept<Shaped>, never>, 'schema'> & { transform?: (value: Awaited<Computed>) => Shaped; schema?: Gate & Schema<Awaited<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 |
|
|
62
|
+
| `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 |
|
|
63
|
+
| `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 |
|
|
64
|
+
| `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 |
|
|
65
|
+
| `reactive` | `<Computed, Args, Shaped = Awaited<Computed>, Gate = Schema<Awaited<Computed>>, ArgsGate = Schema<Args>>(body: (args: Args) => Computed, options?: Omit<ReactiveOptions<Awaited<Computed>, Kept<Shaped>, never, Args>, 'schema' \| 'args'> & { transform?: (value: Awaited<Computed>) => Shaped; schema?: Gate & Schema<Awaited<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 |
|
|
66
|
+
| `reactive` | `<Computed, Args, Shaped = Awaited<Computed>, Gate = Schema<Awaited<Computed>>, ArgsGate = Schema<Args \| undefined>>(body: (args?: Args) => Computed, options?: Omit<ReactiveOptions<Awaited<Computed>, Kept<Shaped>, never, Args \| undefined>, 'schema' \| 'args'> & { transform?: (value: Awaited<Computed>) => Shaped; schema?: Gate & Schema<Awaited<Computed>>; args?: ArgsGate & Schema<Args \| undefined> }) => Keyed<Kept<Shaped>, Args \| undefined, Awaited<Computed>, AdoptedFailures<Computed> \| Refused<Shaped> \| Gated<Gate, Awaited<Computed>> \| Gated<ArgsGate, Args \| undefined>, AdoptedProduced<Computed, Kept<Shaped>>>` | The keyed overload for a body whose parameter is optional. | 11.2 |
|
|
67
|
+
| `reactive` | `<Accepted, Shaped = Accepted, Gate = Schema<Accepted>>(initial: Accepted \| Promise<Accepted>, options?: Omit<ReactiveOptions<Accepted, Kept<Shaped>, never>, 'schema'> & { transform?: (value: Accepted) => Shaped; schema?: Gate & Schema<Accepted> }) => Reactive<Kept<Shaped>, Accepted, Refused<Shaped> \| Gated<Gate, Accepted>>` | The value overload, for what the scope owns outright. | 4.1, 4.2, 4.14, 4.15, 4.16 |
|
|
68
|
+
| `reactive` | `<Accepted = undefined, Shaped = Accepted, Gate = Schema<Accepted>>(initial: undefined, options?: Omit<ReactiveOptions<Accepted, Kept<Shaped>, never>, 'schema'> & { transform?: (value: Accepted) => Shaped; schema?: Gate & Schema<Accepted> }) => Reactive<Kept<Shaped>, Accepted, Refused<Shaped> \| Gated<Gate, Accepted>>` | The undefined overload, for a value opening at `undefined`. | 4.15, 4.16 |
|
|
69
|
+
| `reactive` | `<Accepted>() => Reactive<Kept<Accepted>, Accepted, Refused<Accepted>>` | The empty overload, for a value nothing has written yet. | 4.14 |
|
|
70
|
+
| `Transformer` | `<Accepted, Stored, Failures = never>(value: Accepted) => Stored \| Failures` | The shape of a `transform`. | 4.6, 4.7, 4.8 |
|
|
71
|
+
| `Store` | `{ get: () => Stored \| undefined \| Promise<Stored \| undefined>; set: (value: Stored, retention: { ttl: number }) => void \| Promise<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 |
|
|
72
|
+
| `Shared` | `interface Shared {}` | The app's declaration-merged registry of shared keys. | 10.3 |
|
|
73
|
+
| `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 |
|
|
74
|
+
|
|
75
|
+
The aliases the overloads split a transform's return and a body's return through, and the one that
|
|
76
|
+
adds a declared `schema`'s refusal, are declared rather than listed, none of them being a name an app
|
|
77
|
+
writes:
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
type Kept<Shaped> = Exclude<Shaped, Failed<string, unknown>>
|
|
81
|
+
type Refused<Shaped> = Extract<Shaped, Failed<string, unknown>>
|
|
82
|
+
type AdoptedFailures<T> = T extends Reactive<unknown, never, infer Failures, unknown> ? Failures : never
|
|
83
|
+
type AdoptedProduced<T, Otherwise> = T extends Reactive<unknown, never, unknown, infer Produced> ? Produced : Otherwise
|
|
84
|
+
type Gated<Gate, Accepted> = [Schema<Accepted>] extends [Gate] ? never : Failed<'ValidationError', Issues<Accepted>>
|
|
85
|
+
```
|
|
86
|
+
### `ReactiveOptions`
|
|
87
|
+
|
|
88
|
+
| Name | Signature | Meaning | Rules |
|
|
89
|
+
| --- | --- | --- | --- |
|
|
90
|
+
| `schema` | `Schema<Accepted>` | The gate on the way in. | 1.3, 4.3, 4.4, 4.5, 11.46, 11.47 |
|
|
91
|
+
| `transform` | `(value: Accepted) => Shaped` | The shaping on the way to storage. | 4.6, 4.7, 4.8, 4.9, 11.14 |
|
|
92
|
+
| `store` | `Store<Stored> \| ((args: Args) => Store<Stored>)` | Where the value lives when the process does not. | 8.1, 8.2, 8.3, 8.14, 9.5, 11.42 |
|
|
93
|
+
| `identity` | `(next: Stored, previous: Stored) => unknown` | What makes it the same value. | 5.1, 5.2, 5.3, 5.4, 5.5, 9.3, 11.17, 18.4 |
|
|
94
|
+
| `structural` | `(next: unknown, previous: unknown) => boolean` | The by-value comparator an app declares on `identity`. | 5.4, 5.5, 18.4 |
|
|
95
|
+
| `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 |
|
|
96
|
+
| `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.11, 11.6, 11.35, 11.45, 11.48, 11.49, 11.69 |
|
|
97
|
+
| `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 |
|
|
98
|
+
| `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 |
|
|
99
|
+
| `tags` | `string[] \| ((args: Args) => string[])` | What a `Selection` matches on. | 11.43, 11.44, 18.4, 18.15 |
|
|
100
|
+
| `throttle` | `number` | A ceiling on how often the value changes. | 5.8, 5.9, 5.11, 5.12, 5.14, 5.15, 5.17, 5.18, 5.19, 5.20, 5.21, 5.23, 5.24 |
|
|
101
|
+
| `debounce` | `number` | A wait for the changes to stop before the value changes. | 5.8, 5.9, 5.11, 5.13, 5.14, 5.15, 5.17, 5.18, 5.19, 5.20, 5.21, 5.23, 5.24 |
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
### Reads
|
|
105
|
+
|
|
106
|
+
| Name | Signature | Meaning | Rules |
|
|
107
|
+
| --- | --- | --- | --- |
|
|
108
|
+
| `s` | `() => Stored` | Read the current value. | 2.1, 2.2, 2.3, 2.4, 2.9 |
|
|
109
|
+
| `s.peek` | `() => Stored \| undefined` | Read what is held without joining the flow. | 2.10, 2.11 |
|
|
110
|
+
| `NotLanded` | `Error & { name: 'NotLanded'; source: object }` | What a read throws where nothing has landed yet. | 2.9, 2.12, 2.13, 2.14, 7.8 |
|
|
111
|
+
| `s.then` | `<Result>(onSettled?: (value: Stored) => Result \| PromiseLike<Result>, onFailed?: (error: unknown) => Result \| PromiseLike<Result>) => Promise<Result>` | The settling, as a promise. | 1.4, 2.7, 2.8 |
|
|
112
|
+
| `s.catch` | `<Result>(onFailed: (error: unknown) => Result \| PromiseLike<Result>) => Promise<Stored \| Result>` | The settling's refusal path. | 1.4, 1.5 |
|
|
113
|
+
| `s.finally` | `(onSettled: () => void) => Promise<Stored>` | The settling's end, whichever way it went. | 1.4, 1.5 |
|
|
114
|
+
| `for await (… of s)` | `AsyncIterable<Produced>` | The live cursor face of a read. | 2.5, 2.6, 5.10, 6.10, 9.12 |
|
|
115
|
+
| `s[Symbol.asyncIterator]` | `() => AsyncIterator<Produced>` | The production in flight, and then what follows it. | 2.5, 6.10 |
|
|
116
|
+
|
|
117
|
+
### Writes
|
|
118
|
+
|
|
119
|
+
| Name | Signature | Meaning | Rules |
|
|
120
|
+
| --- | --- | --- | --- |
|
|
121
|
+
| `s.set` | `(value: Accepted \| Promise<Accepted> \| Reactive<Accepted, unknown, Failures, unknown>) => void \| Failures` | Write the current value here, gated by `identity`. | 3.6, 4.1, 4.2, 4.9, 4.13, 4.17, 4.18, 5.6, 9.4, 9.11, 9.12, 11.59, 11.61, 11.65, 11.66, 11.70 |
|
|
122
|
+
| `s.patch` | `(mutate: (value: Stored) => void) => void` | Mutate the value in place. | 5.7, 5.23, 9.13, 11.59, 18.11, 18.13, 32.33 |
|
|
123
|
+
|
|
124
|
+
### Probes
|
|
125
|
+
|
|
126
|
+
| Name | Signature | Meaning | Rules |
|
|
127
|
+
| --- | --- | --- | --- |
|
|
128
|
+
| `s.busy` | `() => boolean` | Work is in flight for this value. | 3.1, 3.2, 3.3, 3.4, 3.7, 3.9, 5.15, 7.5, 7.8, 11.19, 11.20, 11.21, 11.22, 11.50 |
|
|
129
|
+
| `s.ready` | `() => boolean` | There is a value to serve. | 3.1, 3.2, 3.3, 3.5, 3.6, 3.8, 7.8, 11.20, 11.54, 11.58 |
|
|
130
|
+
| `s.error` | `() => Failures \| undefined` | The standing refusal. | 3.1, 3.2, 3.3, 3.5, 4.10, 4.11, 4.12 |
|
|
131
|
+
| `s.isError` | `<Name extends Failures['name']>(error: unknown, name: Name) => error is Extract<Failures, { name: Name }>` | Whether a caught failure is the one named. | 3.1 |
|
|
132
|
+
|
|
133
|
+
### Triggers
|
|
134
|
+
|
|
135
|
+
| Name | Signature | Meaning | Rules |
|
|
136
|
+
| --- | --- | --- | --- |
|
|
137
|
+
| `s.invalidate` | `() => void` | Drop the cache behind the value. | 7.1, 7.2, 7.3, 7.6, 7.7, 7.9, 7.10, 7.12, 7.13, 7.14, 7.15, 7.16, 7.17, 11.51 |
|
|
138
|
+
| `s.refresh` | `() => void` | Reload while continuing to serve what is held. | 4.12, 7.1, 7.4, 7.5, 7.6, 7.11, 7.18, 11.51, 5.24 |
|
|
139
|
+
|
|
140
|
+
### Effects
|
|
141
|
+
|
|
142
|
+
| Name | Signature | Meaning | Rules |
|
|
143
|
+
| --- | --- | --- | --- |
|
|
144
|
+
| `s.watch` | `(effect: (value: Stored) => void \| Disposer) => () => void` | `watch` narrowed to this value. | 5.1, 12.9 |
|
|
145
|
+
|
|
146
|
+
### The keyed face
|
|
147
|
+
|
|
148
|
+
| Name | Signature | Meaning | Rules |
|
|
149
|
+
| --- | --- | --- | --- |
|
|
150
|
+
| `k.busy` | `(pattern?: Partial<Args>) => boolean` | `busy` narrowed to matching entries. | 13.2, 13.3, 13.12 |
|
|
151
|
+
| `k.ready` | `(pattern?: Partial<Args>) => boolean` | `ready` narrowed to matching entries. | 13.11, 13.12 |
|
|
152
|
+
| `k.invalidate` | `(pattern?: Partial<Args>) => void` | `invalidate` narrowed to matching entries. | 7.2, 7.3, 13.4, 13.12 |
|
|
153
|
+
| `k.refresh` | `(pattern?: Partial<Args>) => void` | `refresh` narrowed to matching entries. | 7.4, 7.5, 13.4, 13.12 |
|
|
154
|
+
|
|
155
|
+
## `watch` — the effect
|
|
156
|
+
|
|
157
|
+
| Name | Signature | Meaning | Rules |
|
|
158
|
+
| --- | --- | --- | --- |
|
|
159
|
+
| `Disposer` | `() => void` | What tears down the previous run. | 12.1 |
|
|
160
|
+
| `Effect` | `() => void \| Disposer` | What runs on change. | 12.2, 12.8, 14.6 |
|
|
161
|
+
| `watch` | `(effect: Effect) => () => void` | Begins a watch over whatever the effect reads. | 12.2, 12.4, 12.5, 12.6, 12.7, 12.10, 12.13 |
|
|
162
|
+
| `watch` | `(sources: Reactive<unknown, never, unknown, unknown> \| Reactive<unknown, never, unknown, unknown>[], effect: Effect) => () => void` | The narrowed form, over named sources. | 12.3 |
|
|
163
|
+
| `flushSync` | `() => void` | Ends the turn: every `Effect` a write woke runs now. | 9.10, 12.11, 12.12 |
|
|
164
|
+
|
|
165
|
+
## Selections — over many entries
|
|
166
|
+
|
|
167
|
+
| Name | Signature | Meaning | Rules |
|
|
168
|
+
| --- | --- | --- | --- |
|
|
169
|
+
| `Selection` | `Reactive<any, any, any, any> \| Keyed<any, any, any, any> \| Rpc<any, any, any, any> \| { tags: string[] }` | What is being asked about. | 13.1, 13.8, 13.9, 13.13, 31.14 |
|
|
170
|
+
| `busy` | `(selection?: Selection, pattern?: Partial<Args>) => boolean` | Whether any entry in the selection has work in flight. | 13.2, 13.3, 13.5, 13.12 |
|
|
171
|
+
| `ready` | `(selection?: Selection, pattern?: Partial<Args>) => boolean` | Whether every entry in the selection has a value to serve. | 13.3, 13.5, 13.11, 13.12 |
|
|
172
|
+
| `refresh` | `(selection?: Selection, pattern?: Partial<Args>) => void` | Stale-while-revalidate over the selection. | 13.4, 13.7, 13.10, 13.12, 13.14, 13.15, 13.16, 13.17 |
|
|
173
|
+
| `invalidate` | `(selection?: Selection, pattern?: Partial<Args>) => void` | Marks the selection stale. | 13.4, 13.6, 13.10, 13.12, 13.15, 13.17 |
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
## Refusals
|
|
177
|
+
|
|
178
|
+
| Name | Signature | Meaning | Rules |
|
|
179
|
+
| --- | --- | --- | --- |
|
|
180
|
+
| `refuse.named` | `<Name extends string>(name: Name, status?: number, message?: string) => ((data?: undefined) => Failed<Name, undefined>) & { is: (error: unknown) => error is Failed<Name, undefined> }` | A reusable factory for a named, narrowable failure. | 15.3, 15.13, 15.18 |
|
|
181
|
+
| `refuse.named` | `<Name extends string, Data extends JsonValue>(name: Name, status: number \| undefined, message: string \| ((data: Data) => string) \| undefined, options: { schema: Schema<Data> }) => ((data?: Data) => Failed<Name, Data>) & { is: (error: unknown) => error is Failed<Name, Data> }` | The same, carrying data its schema declares. | 15.3, 15.11, 15.12, 15.13, 15.14, 15.15, 15.18 |
|
|
182
|
+
| `Failed<Name, Data>` | `Error & { name: Name; status: number; message: string; data: Data }` | The one refusal type, in-process and over a wire alike. | 15.1, 15.2, 15.6, 16.40, 16.41, 15.21 |
|
|
183
|
+
| `return myError(data)` | `Failed<Name, Data>` | The one spelling for every refusal. | 15.4, 15.5 |
|
|
184
|
+
| `notFound` | `(data?: { path: string; method: string }) => Failed<'NotFound', { path: string; method: string }>` | Abide's own refusal for an address nothing answers. | 15.7, 15.9, 15.22 |
|
|
185
|
+
| `validationError` | `<T>(data?: Issues<T>) => Failed<'ValidationError', Issues<T>>` | Abide's own refusal for a schema or an `args` gate that refused, or a call's route parameter no segment can spell. | 15.8, 15.9 |
|
|
186
|
+
| `aborted` | `(data?: undefined) => Failed<'Aborted', undefined>` | Abide's own refusal for a load every caller aborted, and for a client that left. | 15.9, 16.49, 16.63 |
|
|
187
|
+
| `myError(data)` DISCARDED | compile error | A `Failed` built and thrown away. | 15.10 |
|
|
188
|
+
|
|
189
|
+
## Tracking
|
|
190
|
+
|
|
191
|
+
| Context | Meaning | Rules |
|
|
192
|
+
| --- | --- | --- |
|
|
193
|
+
| template expression | The flow itself. | 14.1, 14.2, 14.11, 14.17, 32.25, 32.57 |
|
|
194
|
+
| branch-local `<script>` | An item's own setup scope. | 14.8, 34.7, 34.8, 34.9, 34.10 |
|
|
195
|
+
| `reactive` body, unkeyed | The unkeyed body's own scope. | 14.3, 14.11, 14.15, 14.16, 14.17 |
|
|
196
|
+
| `reactive` body, keyed | The keyed body's own scope. | 14.4 |
|
|
197
|
+
| block body binding | A live read, like a prop. | 14.5 |
|
|
198
|
+
| `watch` effect, bare | The effect's own scope. | 14.6, 14.14, 14.16 |
|
|
199
|
+
| `watch` effect, over sources | The scope its sources narrow. | 12.3, 14.6 |
|
|
200
|
+
| component `<script>` setup | The component's own setup scope. | 14.7, 14.12, 14.13 |
|
|
201
|
+
| event handler | Not the flow. | 14.9 |
|
|
202
|
+
| `Transformer`, `Disposer`, middleware, lifecycle hooks | Not the flow. | 14.10 |
|
|
203
|
+
|
|
204
|
+
# Transports
|
|
205
|
+
|
|
206
|
+
## `rpc` — `reactive` + transport
|
|
207
|
+
|
|
208
|
+
### The call
|
|
209
|
+
|
|
210
|
+
| Name | Signature | Meaning | Rules |
|
|
211
|
+
| --- | --- | --- | --- |
|
|
212
|
+
| `Rpc` | `<Value, Args, Failures, Produced = Value>(args?: Args, options?: { signal?: AbortSignal }) => Reactive<Value, Value, Failures \| Failed<'HttpError', undefined>, Produced>` | A handler reached over http, or in process on a server. | 16.3, 16.4, 16.8, 16.11, 16.25, 16.26, 16.27, 16.28, 16.29, 16.33, 16.43, 16.48, 16.49, 16.62, 41.5, 41.7, 41.12, 41.21, 41.22, 41.25, 41.26, 41.27 |
|
|
213
|
+
| `Value` | `unknown` | What the addressed `Reactive` holds. | 16.3, 16.30 |
|
|
214
|
+
| `Produced` | `unknown` | What it yields, per the unit rule. | 1.2, 16.3 |
|
|
215
|
+
| `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 |
|
|
216
|
+
| `Middleware` | `<Ctx, Result>(next: (ctx?: Ctx) => Promise<Result>, ctx: Ctx) => Result \| Promise<Result>` | One rung of `middleware`. | 16.14, 16.15, 16.16, 16.21 |
|
|
217
|
+
| `GET` | `<Value, Args, Failures, RungFailures, Produced = Value>(handler: Reactive<Value, Value, Failures, Produced> \| Keyed<Value, Args, Value, Failures, Produced>, options?: RpcOptions<Args, RungFailures>) => Rpc<Value, Args, Failures \| RungFailures, 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.34, 16.35, 16.36, 16.37, 16.39, 16.44, 16.45, 16.46, 16.47, 16.50, 16.51, 16.52, 16.64, 18.1, 18.3, 18.6, 18.8, 18.10, 18.12, 18.21, 18.24 |
|
|
218
|
+
| `GET` | `<Value, Args, Failures, RungFailures, Produced = Value>(handler: (args?: Args) => Value, options?: RpcOptions<Args, RungFailures> & ReactiveOptions<Value, Value, Failures, Args>) => Rpc<Value, Args, Failures \| RungFailures, Produced>` | The plain-function overload, whose options build the value it becomes beside its address. | 16.1, 16.6, 16.7 |
|
|
219
|
+
| `GET` | `<Value, Failures, RungFailures>(handler: Value \| PromiseLike<Value>, options?: RpcOptions<undefined, RungFailures> & ReactiveOptions<Value, Value, Failures>) => Rpc<Value, undefined, Failures \| RungFailures>` | The value overload, for what the handler owns outright. | 16.1, 16.6, 16.7 |
|
|
220
|
+
| `POST` / `PUT` / `PATCH` / `DELETE` | same as `GET` | Declares a mutation. | 16.2, 16.7, 16.32, 16.68, 16.38, 16.53 |
|
|
221
|
+
| `rpc.busy` | `(pattern?: Partial<Args>) => boolean` | `busy` narrowed to the handler's matching entries. | 13.2, 13.3, 13.12 |
|
|
222
|
+
| `rpc.ready` | `(pattern?: Partial<Args>) => boolean` | `ready` narrowed to the handler's matching entries. | 13.11, 13.12 |
|
|
223
|
+
| `rpc.invalidate` | `(pattern?: Partial<Args>) => void` | `invalidate` narrowed to the handler's matching entries. | 7.2, 7.3, 13.4, 13.12 |
|
|
224
|
+
| `rpc.refresh` | `(pattern?: Partial<Args>) => void` | `refresh` narrowed to the handler's matching entries. | 7.4, 7.5, 13.4, 13.12 |
|
|
225
|
+
| `rpc.isError` | `<Name extends Failures['name']>(error: unknown, name: Name) => error is Extract<Failures, { name: Name }>` | Whether a caught failure is the one named. | 16.8 |
|
|
226
|
+
| `rpc.raw` | `(args: Args, init?: RequestInit) => Promise<Response>` | The same call handed back as the raw response. | 16.11, 16.42 |
|
|
227
|
+
| `rpc.method` | `string` | The HTTP method. | 16.2 |
|
|
228
|
+
| `rpc.url` | `(args?: Args) => string` | The address, resolved against the mount. | 16.9, 16.10 |
|
|
229
|
+
| `rpc.description` | `string \| undefined` | The human description. | 16.28 |
|
|
230
|
+
| `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 |
|
|
231
|
+
|
|
232
|
+
### `RpcOptions`
|
|
233
|
+
|
|
234
|
+
| Name | Signature | Meaning | Rules |
|
|
235
|
+
| --- | --- | --- | --- |
|
|
236
|
+
| `description` | `string` | The human description carried onto every generated surface. | 16.28 |
|
|
237
|
+
| `middleware` | `Middleware<{ request: Request; args: () => Args }, Value \| Failures>[]` | The rungs run per call. | 16.11, 16.12, 16.16, 16.17, 16.18, 16.19, 16.20 |
|
|
238
|
+
| `timeout` | `number` | How long the call may stay open, and the floor under the request's idle timeout. | 16.22, 16.23, 16.56, 16.57, 16.58, 16.59, 16.60, 16.61 |
|
|
239
|
+
| `clients` | `Clients` | Which surfaces carry this handler. | 16.37, 20.3 |
|
|
240
|
+
| `crossOrigin` | `boolean \| string[]` | Whether other origins may call it, or follow it over the mux. | 16.24, 18.2, 21.19 |
|
|
241
|
+
| `maxBodySize` | `number` | The largest request body a mutation will accept, in bytes. | 16.13, 16.54, 16.55 |
|
|
242
|
+
|
|
243
|
+
### Response helpers
|
|
244
|
+
|
|
245
|
+
| Name | Signature | Meaning | Rules |
|
|
246
|
+
| --- | --- | --- | --- |
|
|
247
|
+
| `Values<T>` | `Iterable<T> \| AsyncIterable<T> \| ReadableStream<T>` | What every body helper takes. | 17.1 |
|
|
248
|
+
| `page` | `<Body extends string \| Uint8Array \| Values<Uint8Array \| string>>(body: Body) => Body` | A rendered document as `text/html`. | 17.2 |
|
|
249
|
+
| `json` | `<T>(value: T) => T` | A value as JSON, fixed, with `undefined` sent as `null`. | 17.7, 17.9, 17.10 |
|
|
250
|
+
| `redirect` | `(to: string, status?: RedirectStatus) => undefined` | A navigation. | 16.52, 17.3 |
|
|
251
|
+
| `jsonl` | `<T>(values: Values<T>) => Values<T>` | One JSON value per line, fixed. | 16.44, 17.6, 17.7 |
|
|
252
|
+
| `sse` | `<T>(values: Values<T>) => Values<T>` | The same machine framed as server-sent events, fixed. | 16.45, 17.6, 17.7 |
|
|
253
|
+
| `bytes` | `(values: Values<Uint8Array>) => Values<Uint8Array>` | A stream of binary chunks, fixed. | 16.34, 17.6, 17.7 |
|
|
254
|
+
| `RedirectStatus` | `301 \| 302 \| 303 \| 307 \| 308` | The statuses a `redirect` may carry. | 17.3 |
|
|
255
|
+
| `refuse` | `(status: number, message?: string) => Failed<'HttpError', undefined>` | An undeclared refusal at a status. | 15.5, 15.9, 15.10, 15.16, 15.19, 15.20, 16.40, 17.4, 17.5, 17.8 |
|
|
256
|
+
|
|
257
|
+
## Mount paths
|
|
258
|
+
|
|
259
|
+
| File | Declares | Served at | Rules |
|
|
260
|
+
| --- | --- | --- | --- |
|
|
261
|
+
| `users/getUser.ts` | `export default GET(…)` | `/users/getUser` | 16.2, 16.73, 19.1, 19.20, 23.14 |
|
|
262
|
+
| `health.ts` | `export default GET(…)` | `/health` | 16.2, 23.14 |
|
|
263
|
+
| `media/[id]/save.ts` | `export default POST(…)` | `/media/[id]/save`, `id` reaching its `Args` | 16.2, 16.65, 16.66, 16.67, 16.69 |
|
|
264
|
+
| `media/[id]/lib/Comments.abide` | `const addComment = POST(…)` in its `<script server>` | `/__abide/handlers/media/id/lib/Comments/addComment` | 16.70, 16.71, 16.72 |
|
|
265
|
+
|
|
266
|
+
## Schemas
|
|
267
|
+
|
|
268
|
+
| Name | Signature | Meaning | Rules |
|
|
269
|
+
| --- | --- | --- | --- |
|
|
270
|
+
| `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 |
|
|
271
|
+
| `JsonValue` | `null \| boolean \| number \| string \| JsonValue[] \| { [k: string]: JsonValue }` | What an `Args` may hold. | — |
|
|
272
|
+
| `Issues<T>` | `T extends object ? Partial<Record<Paths<T> \| '', string[]>> : string[]` | What was wrong, keyed by where. | 19.4, 19.19 |
|
|
273
|
+
| `Paths<T>` | `string` | The dot-joined leaf paths of a type. | 19.5 |
|
|
274
|
+
| `JsonSchema` | `JsonValue` | A JSON Schema document, the native form. | 19.7, 19.14 |
|
|
275
|
+
| `jsonSchema` | `<T>(document: JsonSchema) => StandardSchemaV1<T>` | A JSON Schema document as a `Schema`, carrying its validator. | 19.13, 19.14, 20.11 |
|
|
276
|
+
| `validateJson` | `<T>(schema: JsonSchema, value: unknown) => Issues<T> \| null` | The native validator. | 19.13 |
|
|
277
|
+
|
|
278
|
+
## Headers abide generates
|
|
279
|
+
|
|
280
|
+
| Header | On | Meaning | Rules |
|
|
281
|
+
| --- | --- | --- | --- |
|
|
282
|
+
| `x-content-type-options: nosniff` | everything | The declared content type, held against a browser's guess. | 21.1 |
|
|
283
|
+
| `traceresponse` | everything | Correlates the answer, a failure included. | 21.2 |
|
|
284
|
+
| `cache-control: private, no-store` | a page, an rpc answer, any refusal | The default a write through `response` overrides. | 21.3, 21.10 |
|
|
285
|
+
| `cache-control: private, max-age=<ttl>` | a `GET` over a `global` `reactive` | The value's own duration, answered rather than restated. | 21.8, 21.9, 21.11, 21.16, 21.17, 18.14 |
|
|
286
|
+
| `cache-control: no-store` | `/__abide/openapi.json`, `/__abide/mcp` | Refuses caching for an answer about the app's surfaces. | 21.4 |
|
|
287
|
+
| `cache-control: public, max-age=31536000, immutable` | the built bundle | A chunk addressed by its own content hash. | 21.5 |
|
|
288
|
+
| `cache-control: public, max-age=0, must-revalidate` | a file under a `public` directory | A file at an address the build never chose. | 21.12 |
|
|
289
|
+
| `etag` | a file under a `public` directory | The answered bytes, addressed by their content. | 21.13, 21.14 |
|
|
290
|
+
| `referrer-policy: strict-origin-when-cross-origin` | a page | The browsers' own default, written down. | 21.6 |
|
|
291
|
+
| `vary` | wherever an answer depends on a request header | Names the header the answer varied on. | 21.7 |
|
|
292
|
+
| `content-security-policy: frame-ancestors 'none'` | a page | The default a write through `response` or `csp` overrides. | 21.18, 21.10 |
|
|
293
|
+
| `access-control-allow-origin` | an rpc answer to another origin | The origin a handler admitted. | 21.19, 16.24 |
|
|
294
|
+
| `allow: GET, HEAD` | a page, a public file or the bundle, asked by another method | The methods the address answers. | 15.17 |
|
|
295
|
+
| `server-timing` | an rpc answer; `Middleware` and a `timing` span on any answer | The handler's duration, named `Direct`, `Seeded` from the render's run, `Cached` from a held `global` production, or `Started` to a stream's first chunk; the rungs' time; and each `timing` span. | 21.15, 21.20, 21.21, 24.6 |
|
|
296
|
+
| `etag` | a `GET` answered from a `global` value | The version of the production answered. | 18.5, 18.6, 18.7, 18.9, 18.19, 18.20, 18.22, 18.23 |
|
|
297
|
+
|
|
298
|
+
# Generated surfaces
|
|
299
|
+
|
|
300
|
+
| Name | Signature | Meaning | Rules |
|
|
301
|
+
| --- | --- | --- | --- |
|
|
302
|
+
| `Clients` | `{ ui?: boolean; mcp?: boolean; cli?: boolean; openapi?: boolean }` | Which surfaces carry a handler. | 20.1, 20.2, 20.3, 20.4 |
|
|
303
|
+
| `clients` | `Clients` | The option a handler withholds a surface with. | 16.37, 20.3, 20.4 |
|
|
304
|
+
|
|
305
|
+
## OpenAPI
|
|
306
|
+
|
|
307
|
+
| Name | Signature | Meaning | Rules |
|
|
308
|
+
| --- | --- | --- | --- |
|
|
309
|
+
| `/__abide/openapi.json` | `GET` | The generated OpenAPI document. | 20.5, 20.6, 20.7, 20.8, 20.11, 20.13, 36.7 |
|
|
310
|
+
| `OpenApiDocument` | `JsonValue` | OpenAPI 3.1, whose schema dialect is `JsonSchema`. | 20.6 |
|
|
311
|
+
|
|
312
|
+
## MCP
|
|
313
|
+
|
|
314
|
+
| Name | Signature | Meaning | Rules |
|
|
315
|
+
| --- | --- | --- | --- |
|
|
316
|
+
| `/__abide/mcp` | `POST` | The streamable-http MCP endpoint. | 20.5, 20.7, 20.8, 20.9, 20.10, 20.12, 20.13, 36.7 |
|
|
317
|
+
|
|
318
|
+
# Assistant
|
|
319
|
+
|
|
320
|
+
| Name | Signature | Meaning | Rules |
|
|
321
|
+
| --- | --- | --- | --- |
|
|
322
|
+
| `assistant` | `(messages: AssistantMessage[], provider: Provider, options?: AssistantOptions) => AsyncGenerator<AssistantEvent>` | A conversation with a model, as the events it produces. | 45.1, 45.2, 45.3, 45.4, 45.21 |
|
|
323
|
+
| `AssistantMessage` | `{ role: 'user' \| 'assistant'; content: string }` | One turn of the transcript a caller sends. | 45.3, 45.4 |
|
|
324
|
+
| `AssistantEvent` | `{ type: 'text'; text: string } \| { type: 'tool'; id: string; name: 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, its result, and the end. | 45.2, 45.11 |
|
|
325
|
+
| `AssistantOptions` | `{ mcp?: boolean; maxTurns?: number }` | What `assistant` takes beside a provider. | 45.6, 45.8, 45.11 |
|
|
326
|
+
| `Provider` | `{ run(messages: AssistantMessage[], tools: Toolbox, limits: { maxTurns: number; signal: AbortSignal }): AsyncGenerator<AssistantEvent> }` | What runs a conversation. | 45.2 |
|
|
327
|
+
| `Toolbox` | `{ list: ToolDefinition[]; call(name: string, input: unknown): Promise<{ text: string; failed: boolean }> }` | The app's MCP tools, called as the asker. | 45.6, 45.7 |
|
|
328
|
+
| `ToolDefinition` | `{ name: string; description: string; inputSchema: unknown }` | A tool as the app's MCP surface lists it. | 45.6 |
|
|
329
|
+
|
|
330
|
+
## `claudeApi`
|
|
331
|
+
|
|
332
|
+
| Name | Signature | Meaning | Rules |
|
|
333
|
+
| --- | --- | --- | --- |
|
|
334
|
+
| `claudeApi` | `(config: ClaudeApiConfig) => Provider` | The Claude Messages API as a provider. | 45.9, 45.10, 45.12, 45.21 |
|
|
335
|
+
| `ClaudeApiConfig` | `{ apiKey: string; baseURL?: string; model: string; max_tokens: number; system?: string \| unknown[]; tools?: unknown[]; [field: string]: unknown }` | A Messages API request body, less `messages` and `stream`, with the client's key and origin. | 45.9, 45.10 |
|
|
336
|
+
|
|
337
|
+
## `claudeCode`
|
|
338
|
+
|
|
339
|
+
| Name | Signature | Meaning | Rules |
|
|
340
|
+
| --- | --- | --- | --- |
|
|
341
|
+
| `claudeCode` | `(config?: ClaudeCodeConfig) => Provider` | The visitor's own Claude Code, reached through the bridge paired with their browser, as a provider. | 45.5, 45.13, 45.17, 45.18, 45.19 |
|
|
342
|
+
| `ClaudeCodeConfig` | `{ model?: string; fallbackModel?: string; systemPrompt?: string; appendSystemPrompt?: string; effort?: 'low' \| 'medium' \| 'high' \| 'xhigh' \| 'max' }` | The Claude Code options a site may set for a turn. | 45.16 |
|
|
343
|
+
| `claudeCode.bridgeCommand` | `() => { command: string; expires: number }` | The command that pairs a bridge with this browser. | 45.14 |
|
|
344
|
+
| `claudeCode.bridge` | `() => AsyncGenerator<BridgeStatus>` | This browser's pairing, as it changes. | 45.20, 45.22 |
|
|
345
|
+
| `BridgeStatus` | `{ paired: boolean; command: string \| undefined }` | Whether a bridge is paired, and the command that pairs one where none is. | 45.20 |
|
|
346
|
+
| `/__abide/bridge` | `GET`, `POST` | Where a bridge pairs, and is relayed its turns. | 36.7, 45.14, 45.15, 45.19 |
|
|
347
|
+
|
|
348
|
+
# Ambient values
|
|
349
|
+
|
|
350
|
+
## `cookies`
|
|
351
|
+
|
|
352
|
+
| Name | Signature | Meaning | Rules |
|
|
353
|
+
| --- | --- | --- | --- |
|
|
354
|
+
| `cookies` | `() => CookieMap` | The cookies of the request being served, live and mutable. | 22.2, 22.3, 22.4, 22.5, 22.6, 22.7, 22.8, 22.10 |
|
|
355
|
+
|
|
356
|
+
## `request`
|
|
357
|
+
|
|
358
|
+
| Name | Signature | Meaning | Rules |
|
|
359
|
+
| --- | --- | --- | --- |
|
|
360
|
+
| `request` | `() => Request` | The request being served. | 18.16, 18.17, 18.18, 22.1 |
|
|
361
|
+
|
|
362
|
+
## `response`
|
|
363
|
+
|
|
364
|
+
| Name | Signature | Meaning | Rules |
|
|
365
|
+
| --- | --- | --- | --- |
|
|
366
|
+
| `response` | `() => { status: number; headers: Headers }` | The response being built for the request being served. | 16.13, 16.52, 21.10, 22.1, 22.9, 22.10 |
|
|
367
|
+
|
|
368
|
+
## `route`
|
|
369
|
+
|
|
370
|
+
| Name | Signature | Meaning | Rules |
|
|
371
|
+
| --- | --- | --- | --- |
|
|
372
|
+
| `route.url` | `Reactive<URL>` | Where we are. | 23.1, 23.2, 23.3, 23.4, 30.23, 19.16, 31.16 |
|
|
373
|
+
| `route.params` | `Reactive<Params>` | The matched route's segments. | 23.1, 23.5, 23.9, 30.23, 31.16 |
|
|
374
|
+
| `Params` | `Record<string, string \| string[]>` | What a matched route's segments are. | 23.5 |
|
|
375
|
+
| `route.name` | `Reactive<string>` | The resolution path. | 23.1, 23.6, 31.16 |
|
|
376
|
+
| `route.navigating` | `Reactive<boolean>` | Whether a navigation is in flight. | 23.1, 31.16 |
|
|
377
|
+
|
|
378
|
+
## `online`
|
|
379
|
+
|
|
380
|
+
| Name | Signature | Meaning | Rules |
|
|
381
|
+
| --- | --- | --- | --- |
|
|
382
|
+
| `online` | `Reactive<boolean>` | Whether the caller can reach the app. | 23.7, 23.8 |
|
|
383
|
+
|
|
384
|
+
## `reachable`
|
|
385
|
+
|
|
386
|
+
| Name | Signature | Meaning | Rules |
|
|
387
|
+
| --- | --- | --- | --- |
|
|
388
|
+
| `reachable` | `(host: string) => Promise<boolean>` | Whether a host answers at all. | 23.10, 23.11, 23.12, 23.13 |
|
|
389
|
+
|
|
390
|
+
## `trace`
|
|
391
|
+
|
|
392
|
+
| Name | Signature | Meaning | Rules |
|
|
393
|
+
| --- | --- | --- | --- |
|
|
394
|
+
| `trace` | `() => string` | The trace id of the operation this work belongs to. | 24.1 |
|
|
395
|
+
| `trace.sampled` | `() => boolean` | The caller's sampling decision, carried through verbatim. | 24.2 |
|
|
396
|
+
| `trace.span` | `<T>(name: string, body: () => T, options?: { timing?: boolean }) => T` | Opens a child span around a body. | 24.3, 24.4, 24.6, 24.7 |
|
|
397
|
+
| `trace.headers` | `() => Record<string, string>` | What an outbound request carries. | 24.5 |
|
|
398
|
+
|
|
399
|
+
## `server`
|
|
400
|
+
|
|
401
|
+
| Name | Signature | Meaning | Rules |
|
|
402
|
+
| --- | --- | --- | --- |
|
|
403
|
+
| `server` | `<WebSocketData>() => Server<WebSocketData>` | The listening server. | 22.1 |
|
|
404
|
+
|
|
405
|
+
## `health`
|
|
406
|
+
|
|
407
|
+
| Name | Signature | Meaning | Rules |
|
|
408
|
+
| --- | --- | --- | --- |
|
|
409
|
+
| `health` | `Rpc<Health, undefined>` | The account of the app this call is in. | 16.4, 25.1, 25.2, 25.3 |
|
|
410
|
+
| `Health` | `interface Health { version: string; abide: string; startedAt: string }` | The account itself, which an app widens with what its `onHealth` adds. | 25.4 |
|
|
411
|
+
| `onHealth` | `(report: () => unknown \| Promise<unknown>) => () => void` | The app's reporter, merged over the baseline. | 25.2 |
|
|
412
|
+
| `version` | `string` | The app's version. | — |
|
|
413
|
+
| `abide` | `string` | The framework's version. | — |
|
|
414
|
+
| `startedAt` | `string` | When the process started, ISO-8601. | — |
|
|
415
|
+
|
|
416
|
+
## `principal`
|
|
417
|
+
|
|
418
|
+
| Name | Signature | Meaning | Rules |
|
|
419
|
+
| --- | --- | --- | --- |
|
|
420
|
+
| `principal.authenticated` | `Reactive<boolean>` | Whether this caller presented something the server accepted. | 26.1, 26.2 |
|
|
421
|
+
| `principal.expiresAt` | `Reactive<string \| undefined>` | When the seal lapses. | 26.1, 26.2 |
|
|
422
|
+
| `principal.error` | `Reactive<Failed<string, unknown> \| undefined>` | The app's resolver, or a browser's load of the document, having failed. | 26.1, 26.3, 26.23 |
|
|
423
|
+
| `principal.resolved` | `Reactive<Principal>` | What `onPrincipal` returned, merged over the baseline. | 26.1, 26.4, 26.25 |
|
|
424
|
+
| `principal.caller` | `Reactive<string>` | Which browser, as against who they are. | 22.10, 26.5, 26.6, 26.7, 26.19, 26.22 |
|
|
425
|
+
| `principal.set` | `(claims: Record<string, unknown>) => Promise<void>` | Authenticates this caller. | 18.25, 26.8, 26.12, 26.16, 26.17, 26.18, 26.20, 26.21, 26.24 |
|
|
426
|
+
| `principal.clear` | `() => void` | Signs this caller out. | 18.25, 26.7, 26.9, 26.24 |
|
|
427
|
+
| `Principal` | `interface Principal { [claim: string]: unknown; authenticated: boolean; expiresAt?: string; error?: Failed<string, unknown> }` | The wire document. | 26.4, 26.10, 26.13, 26.14, 26.15, 26.25 |
|
|
428
|
+
| `authenticated` | `boolean` | Whether this caller presented a seal the server accepted. | 26.10 |
|
|
429
|
+
| `expiresAt` | `string \| undefined` | When the seal lapses. | 26.11 |
|
|
430
|
+
| `error` | `Failed<string, unknown> \| undefined` | The app's resolver having failed. | 26.3 |
|
|
431
|
+
|
|
432
|
+
## `config`
|
|
433
|
+
|
|
434
|
+
| Name | Signature | Meaning | Rules |
|
|
435
|
+
| --- | --- | --- | --- |
|
|
436
|
+
| `config` | `Reactive<Config>` | The resolved configuration document. | 27.1, 27.9 |
|
|
437
|
+
| `Config` | `interface Config { [field: string]: unknown; APP_NAME: string; APP_VERSION: string; APP_DATA_DIR: string }` | The resolved document, widened by what each `onConfig`'s defaults return, and by declaration merging. | 27.12, 27.13 |
|
|
438
|
+
| `Env` | `Record<string, string \| undefined>` | The process environment as read, before coercion. | 27.2, 27.8 |
|
|
439
|
+
| `config.invalidate` | `() => void` | The trigger over the resolved configuration. | 7.2, 27.5 |
|
|
440
|
+
| `onConfig` | `(fn: ConfigDefaults \| null, options?: ConfigOptions) => () => void` | The app's defaults and its schema. | 27.3, 27.4, 27.6, 27.10, 27.13 |
|
|
441
|
+
| `ConfigDefaults` | `(env: Env) => unknown` | The defaults function, synchronous by contract. | 27.4, 27.11 |
|
|
442
|
+
|
|
443
|
+
### `ConfigOptions`
|
|
444
|
+
|
|
445
|
+
| Name | Signature | Meaning | Rules |
|
|
446
|
+
| --- | --- | --- | --- |
|
|
447
|
+
| `schema` | `Schema<Config>` | The gate over the whole configuration document. | 27.7 |
|
|
448
|
+
|
|
449
|
+
# Helpers
|
|
450
|
+
|
|
451
|
+
## `log`
|
|
452
|
+
|
|
453
|
+
| Name | Signature | Meaning | Rules |
|
|
454
|
+
| --- | --- | --- | --- |
|
|
455
|
+
| `log` | `(...args: unknown[]) => void` | A message under the default namespace. | 28.1, 28.2 |
|
|
456
|
+
| `log.info` / `log.warning` / `log.error` / `log.debug` | `(...args: unknown[]) => void` | The four levels. | 28.3 |
|
|
457
|
+
| `log.named` | `(name: string) => Logger` | A logger under a named namespace. | 28.4, 28.5, 28.12 |
|
|
458
|
+
| `Logger` | `typeof log` | What `log.named` hands back. | 28.5 |
|
|
459
|
+
| `log.enabled` | `() => boolean` | Whether a gated line under this namespace would be written. | 28.6, 28.7 |
|
|
460
|
+
| `LogRecord` | `{ time: string; level: 'debug' \| 'info' \| 'warning' \| 'error'; namespace: string; message: string; trace: string }` | One line, as a value. | 24.3 |
|
|
461
|
+
| `log.records` | `Reactive<LogRecord[]>` | The lines kept, appended to as each is written. | 28.1 |
|
|
462
|
+
| `abide:request` | `debug` | One line per request. | 28.8 |
|
|
463
|
+
| `abide:socket` | `debug` | One line per frame on the socket mux. | 28.8 |
|
|
464
|
+
| `abide:lifecycle` | `debug` `error` | A lifecycle that ran. | 28.8 |
|
|
465
|
+
| `abide:principal` | `debug` `warning` | A principal set or cleared. | 28.8 |
|
|
466
|
+
| `abide:health` | `warning` | An `onHealth` that threw or answered a non-object. | 25.2, 28.8 |
|
|
467
|
+
| `abide:mcp` | `debug` `warning` | A handler withheld from MCP, or a tool published with no description. | 20.3, 20.9, 28.8 |
|
|
468
|
+
| `abide:openapi` | `warning` | A handler whose schema had no JSON Schema export. | 20.11, 28.8 |
|
|
469
|
+
| `abide:config` | `warning` | A second `onConfig` replacing the first. | 27.6, 28.8 |
|
|
470
|
+
| `abide:render` | `warning` | An `error.abide` that itself failed. | 28.8 |
|
|
471
|
+
| `abide:refuse` | `warning` | A message formatter that threw. | 15.13, 28.8 |
|
|
472
|
+
| `abide:reactive` | `warning` | A failed revalidation over a value still being served. | 4.12, 28.8 |
|
|
473
|
+
| `abide:watch` | `warning` | A `watch` effect or `Disposer` that threw. | 12.6, 28.8 |
|
|
474
|
+
| `abide:hydrate` / `abide:navigate` | `warning` | The browser lane. | 28.8, 41.10, 41.15, 41.24 |
|
|
475
|
+
|
|
476
|
+
## `csp`
|
|
477
|
+
|
|
478
|
+
| Name | Signature | Meaning | Rules |
|
|
479
|
+
| --- | --- | --- | --- |
|
|
480
|
+
| `csp` | `(sources?: Record<string, string[]>) => Middleware` | The rung that sets `content-security-policy`. | 29.1, 29.2, 29.5, 29.6, 29.7, 29.8 |
|
|
481
|
+
| `csp.nonce` | `() => string` | This response's nonce, for the app's own inline script. | 29.3, 29.4, 29.9, 29.11 |
|
|
482
|
+
|
|
483
|
+
## `url`
|
|
484
|
+
|
|
485
|
+
| Name | Signature | Meaning | Rules |
|
|
486
|
+
| --- | --- | --- | --- |
|
|
487
|
+
| `url` | `<P extends RouteLiteral>(url?: P, ...rest: HasParams<P> extends true ? [params: ParamsOf<P>, queryParams?: Query] : [params?: ParamsOf<P>, queryParams?: Query]) => string` | Builds an address from a route literal or a public file's address. | 30.1, 30.2, 30.8, 30.19, 30.26 |
|
|
488
|
+
| `HasParams<P>` | `boolean` | Whether the literal carries a required segment. | 30.2 |
|
|
489
|
+
| `HasSegments<P>` | `boolean` | Whether the literal carries a segment of any kind. | 30.2 |
|
|
490
|
+
| `RequiredNames<P>` | `string` | The required segment names. | 30.3 |
|
|
491
|
+
| `OptionalNames<P>` | `string` | The optional segment names. | 30.4 |
|
|
492
|
+
| `RestNames<P>` | `string` | The rest segment names. | 30.5 |
|
|
493
|
+
| `Query` | `Record<string, unknown> \| URLSearchParams` | The query half. | 30.6 |
|
|
494
|
+
| `ParamsOf<P>` | `& { [K in RequiredNames<P>]: string \| number } & { [K in OptionalNames<P>]?: string \| number } & { [K in RestNames<P>]?: string \| number \| (string \| number)[] }` | What a route literal's segments accept. | 30.3, 30.4, 30.5 |
|
|
495
|
+
| `RouteParams<P>` | `{ [K in RequiredNames<P>]: string } & { [K in OptionalNames<P>]?: string } & { [K in RestNames<P>]: string[] }` | What a page filed under `P` reads its params as. | 23.9 |
|
|
496
|
+
| `Routes` | `interface Routes {}` | The app's route literals and public file addresses, which `abide check` declares. | 30.26 |
|
|
497
|
+
| `RouteLiteral` | `[keyof Routes] extends [never] ? string : Extract<keyof Routes, string>` | What `url` takes. | 30.26 |
|
|
498
|
+
|
|
499
|
+
## `navigate`
|
|
500
|
+
|
|
501
|
+
| Name | Signature | Meaning | Rules |
|
|
502
|
+
| --- | --- | --- | --- |
|
|
503
|
+
| `navigate` | `(url?: URL \| string, options?: { replace?: boolean, keepScroll?: boolean }) => Promise<void>` | Navigates. | 30.7, 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 |
|
|
504
|
+
|
|
505
|
+
# `.abide` files
|
|
506
|
+
|
|
507
|
+
## Reading and writing by name
|
|
508
|
+
|
|
509
|
+
| Spelling | Means | Rules |
|
|
510
|
+
| --- | --- | --- |
|
|
511
|
+
| `foo` wherever the declared type of its position is not a `Reactive` | a live read | 31.1, 31.2, 31.10 |
|
|
512
|
+
| `const x: Reactive<…> = foo` / a `Reactive<…>`-typed parameter, return or `bind:` operand | the `Reactive` | 31.3 |
|
|
513
|
+
| `await foo` | the settling of the `Reactive`, which is its value | 1.4, 2.7, 31.3 |
|
|
514
|
+
| `refresh(foo)` / a `Selection`-typed parameter | the `Reactive` | 31.14 |
|
|
515
|
+
| `foo = bar` | a write | 31.4, 11.61 |
|
|
516
|
+
| `foo.bar = v` | a write through a path | 31.8, 31.15 |
|
|
517
|
+
| `foo.push(v)` | the same | 31.8, 31.9 |
|
|
518
|
+
| `const [a, b] = foo` / `...foo` | one read of the value | 31.12 |
|
|
519
|
+
| `foo.bar` | the value's `bar`, or the `Reactive`'s own `bar` where it declares one | 31.5, 31.13 |
|
|
520
|
+
| `foo.bar(…)` | the `Reactive` API where `bar` is a member | 31.6 |
|
|
521
|
+
| `foo()` / `foo.set(v)` | the explicit forms | 31.7, 31.11 |
|
|
522
|
+
|
|
523
|
+
## Templating
|
|
524
|
+
|
|
525
|
+
### Expressions
|
|
526
|
+
|
|
527
|
+
| Spelling | Meaning | Rules |
|
|
528
|
+
| --- | --- | --- |
|
|
529
|
+
| `{expr}` | Reactive text, escaped. | 32.1, 32.23 |
|
|
530
|
+
| formatting whitespace | What a run of whitespace renders as. | 33.17, 33.18 |
|
|
531
|
+
| `{raw(...)}` | Raw HTML. | 32.2, 32.25, 32.26, 32.30, 32.31 |
|
|
532
|
+
| `name={expr}` | A reactive attribute or property. | 32.3, 32.20, 32.23, 32.37 |
|
|
533
|
+
| `on<event>={fn}` | A native listener on an element, and an ordinary prop on a component. | 32.4 |
|
|
534
|
+
| `name="…{expr}…"` | An interpolated quoted value. | 32.3 |
|
|
535
|
+
| `bind:value` | Two-way bind on an element. | 5.16, 32.5 |
|
|
536
|
+
| `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 |
|
|
537
|
+
| `bind:checked` | A boolean bind on an input. | 32.7 |
|
|
538
|
+
| `bind:open` | The same, on a `<details>`. | 32.7 |
|
|
539
|
+
| `bind:group` | Radio or checkbox membership. | 32.8 |
|
|
540
|
+
| `bind:value={{get, set}}` | Two-way bind over an explicit accessor pair, on an element or a component. | 32.5, 32.6 |
|
|
541
|
+
| `bind:element={Reactive<Element> \| ((element: Element) => void \| Disposer)}` | A node reference. | 32.9, 32.38 |
|
|
542
|
+
| `class:name={cond}` | Toggles a class. | 32.10 |
|
|
543
|
+
| `style:prop={value}` | Sets one style property. | 32.10, 32.19 |
|
|
544
|
+
| `{...expr}` | Spreads props or attributes. | 32.11, 32.37, 33.12, 33.13 |
|
|
545
|
+
| static template text | What an author writes outside a slot, in body text and in an attribute value. | 32.27, 32.28 |
|
|
546
|
+
|
|
547
|
+
### Raw markup
|
|
548
|
+
|
|
549
|
+
| Name | Signature | Meaning | Rules |
|
|
550
|
+
| --- | --- | --- | --- |
|
|
551
|
+
| `raw` | `(value: unknown) => Raw` | The branding a value takes to render as markup rather than as text. | 32.2, 32.24, 32.26, 32.30, 32.31 |
|
|
552
|
+
| `Raw` | `class Raw { html: string }` | What `raw` hands back. | 32.24 |
|
|
553
|
+
|
|
554
|
+
### Control flow
|
|
555
|
+
|
|
556
|
+
| Spelling | Branches | Meaning | Rules |
|
|
557
|
+
| --- | --- | --- | --- |
|
|
558
|
+
| `{#if cond}` | `{:else if cond}`, `{:else}` | Conditional markup. | 32.12, 32.21, 41.24 |
|
|
559
|
+
| `{#for item, index of list by key}` | — | Repeats markup over a list, or over a cursor as it produces. | 32.13, 32.14, 32.15, 32.22, 32.29, 32.32, 32.33, 41.8, 41.14, 41.15 |
|
|
560
|
+
| `{#try}` | `{:catch e}`, `{:finally}` | A render-time boundary and a region. | 32.16, 32.56 |
|
|
561
|
+
|
|
562
|
+
### Components
|
|
563
|
+
|
|
564
|
+
| Spelling | Meaning | Rules |
|
|
565
|
+
| --- | --- | --- |
|
|
566
|
+
| `{#component Name(pattern)}` | An inline component. | 32.39, 32.40, 32.41, 32.42, 32.43, 32.44, 32.45, 32.46, 32.47, 32.48, 32.49, 32.50, 32.51, 32.52, 32.53, 32.54, 32.55 |
|
|
567
|
+
| `<Name/>` | A component invocation. | 32.17, 32.34, 32.35, 32.36, 33.19, 33.21, 41.24 |
|
|
568
|
+
| `<slot/>` | The position children render into. | 32.18 |
|
|
569
|
+
| `<slot>fallback</slot>` | Renders children, or a fallback. | 32.18 |
|
|
570
|
+
| `<Tag>…</Tag>` | Children passed to a component's slot. | 32.18 |
|
|
571
|
+
|
|
572
|
+
## Props
|
|
573
|
+
|
|
574
|
+
| Name | Signature | Meaning | Rules |
|
|
575
|
+
| --- | --- | --- | --- |
|
|
576
|
+
| `props` | `<Props>() => { [K in keyof Props]: Props[K] }` | One live accessor per prop the component declares. | 33.1, 33.2, 33.3, 33.4, 33.5, 33.6, 33.7, 33.8, 33.9, 33.10, 33.11, 33.14, 33.15, 33.20, 33.22, 33.25 |
|
|
577
|
+
| `Attributes<Tag>` | `Attributes<Tag extends keyof HTMLElementTagNameMap \| keyof SVGElementTagNameMap>` | The attributes an HTML or SVG element takes, typed as a component's props. | 33.23, 33.24, 33.26 |
|
|
578
|
+
| `children` | always accepted | What a caller passes between the tags. | 33.16, 32.18 |
|
|
579
|
+
|
|
580
|
+
## Script / style blocks
|
|
581
|
+
|
|
582
|
+
| Spelling | Meaning | Rules |
|
|
583
|
+
| --- | --- | --- |
|
|
584
|
+
| `<script>` | Per-instance component setup. | 14.7, 34.1, 34.3, 34.12, 34.13, 34.14, 34.15, 34.17, 34.29, 34.30 |
|
|
585
|
+
| `<script module>` | Module scope. | 34.2, 34.3, 34.12, 34.14, 34.15, 34.17, 34.18, 34.21, 34.30 |
|
|
586
|
+
| `<script server>` | Module scope on a server alone, declaring its file's private handlers and filing its hooks. | 16.28, 16.70, 34.3, 34.12, 34.17, 34.19, 34.20, 34.22, 34.28, 34.29, 34.30, 37.1 |
|
|
587
|
+
| `<style>` | Component-scoped styles. | 34.4, 34.5, 34.10, 34.11 |
|
|
588
|
+
| `import './app.css'` | A stylesheet the component depends on. | 34.6 |
|
|
589
|
+
| `:global(…)` | The per-selector escape from scoping. | 34.5 |
|
|
590
|
+
|
|
591
|
+
# Pages and routing
|
|
592
|
+
|
|
593
|
+
## Pages
|
|
594
|
+
|
|
595
|
+
| Path | Meaning | Rules |
|
|
596
|
+
| --- | --- | --- |
|
|
597
|
+
| `<head>` | A page's contribution to the document head. | 39.1, 39.2, 39.3, 39.4, 39.5, 39.6, 39.11, 39.12, 39.13, 39.14 |
|
|
598
|
+
| `view-transition-name` | What turns view transitions on, in the app's own stylesheet. | 39.7, 39.8, 39.9, 39.10 |
|
|
599
|
+
| `[name]` | A required dynamic segment. | 16.65, 23.5, 30.3 |
|
|
600
|
+
| `[[name]]` | An optional segment. | 23.5, 30.4 |
|
|
601
|
+
| `[...name]` | A rest segment, terminal. | 23.5, 30.5 |
|
|
602
|
+
| `/__abide/**` | Every endpoint abide controls. | 20.8 |
|
|
603
|
+
|
|
604
|
+
## `render`
|
|
605
|
+
|
|
606
|
+
| Name | Signature | Meaning | Rules |
|
|
607
|
+
| --- | --- | --- | --- |
|
|
608
|
+
| `Component` | `interface Component {}` | A component bound to its props. | 32.17, 34.16, 35.4 |
|
|
609
|
+
| `render` | `(component: Component) => Promise<Uint8Array>` | What produces a document. | 29.10, 35.4, 35.5, 35.6, 35.15, 35.16, 41.1, 41.2, 41.3, 41.4, 41.9, 41.13, 41.16, 41.17, 41.18, 41.19, 41.20, 35.11 |
|
|
610
|
+
|
|
611
|
+
## Sinks
|
|
612
|
+
|
|
613
|
+
| Spelling | Sink | Filled | Rules |
|
|
614
|
+
| --- | --- | --- | --- |
|
|
615
|
+
| `href={x}`, any attribute | the element | the attribute or property | 35.7, 35.8 |
|
|
616
|
+
| `class:`, `style:`, `bind:` | the element | the class, the style property, the bound property | 35.7 |
|
|
617
|
+
| `<title>{name}</title>` | the `<title>` | `.textContent` | 35.9, 35.10 |
|
|
618
|
+
| `<textarea>{v}</textarea>` | the `<textarea>` | `.defaultValue` | 35.9 |
|
|
619
|
+
|
|
620
|
+
# Configuration
|
|
621
|
+
|
|
622
|
+
## Environment variables
|
|
623
|
+
|
|
624
|
+
| Name | Type | Meaning | Rules |
|
|
625
|
+
| --- | --- | --- | --- |
|
|
626
|
+
| `PORT` | `number` | The listen port. | 36.1, 38.63, 38.64 |
|
|
627
|
+
| `APP_URL` | `string \| null` | The app's public URL. | 36.2, 19.17 |
|
|
628
|
+
| `NODE_ENV` | `string` | The environment name, verbatim. | 36.3, 36.16 |
|
|
629
|
+
| `APP_NAME` | `string` | The app's name, and `log`'s default namespace. | 27.3, 28.4 |
|
|
630
|
+
| `APP_VERSION` | `string` | The version beside that name. | 27.3 |
|
|
631
|
+
| `APP_DATA_DIR` | `string` | The platform's per-user data directory. | 27.3, 36.4 |
|
|
632
|
+
| `ABIDE_PRINCIPAL_SECRET` | `string \| null` | What seals the principal cookie. | 26.11, 36.5 |
|
|
633
|
+
| `ABIDE_PRINCIPAL_TTL` | `number` | The principal cookie's life, in ms. | 26.15, 26.16 |
|
|
634
|
+
| `ABIDE_APP_TOKEN` | `string \| null` | The bearer the remote CLI sends. | 36.6 |
|
|
635
|
+
| `ABIDE_APP_URL` | `string \| null` | Names an app somewhere else, for the remote CLI. | 36.6 |
|
|
636
|
+
| `ABIDE_RPC_TIMEOUT` | `number` | The default ms a call may go without progress. | 16.22, 16.56, 16.58 |
|
|
637
|
+
| `ABIDE_MAX_REQUEST_BODY_SIZE` | `number` | The default ceiling on a mutation's body. | 16.13, 16.54, 16.55 |
|
|
638
|
+
| `ABIDE_MAX_STREAM_BUFFER_SIZE` | `number` | The cap on a stream transcript held in memory. | 36.18 |
|
|
639
|
+
| `ABIDE_MAX_LOG_BUFFER_COUNT` | `number` | How many lines `log.records` is trimmed back to. | 28.1 |
|
|
640
|
+
| `ABIDE_LOG_FORMAT` | `'tsv' \| 'json' \| null` | The machine log format. | 36.8 |
|
|
641
|
+
| `DEBUG` | `string \| null` | Log-namespace gating. | 28.6, 28.9, 28.10, 28.11 |
|
|
642
|
+
| `NO_COLOR` | `string \| null` | Refuses ansi anywhere. | 36.9 |
|
|
643
|
+
| `FORCE_COLOR` | `string \| null` | Asks for the readable form off a pipe. | 36.9 |
|
|
644
|
+
|
|
645
|
+
## Files
|
|
646
|
+
|
|
647
|
+
| Path | Meaning | Rules |
|
|
648
|
+
| --- | --- | --- |
|
|
649
|
+
| `src/**` | The app's source. | 36.10, 38.25 |
|
|
650
|
+
| `**/server/**` | Source the browser never loads. | 16.29, 23.15, 23.16, 23.18, 36.10 |
|
|
651
|
+
| `**/lib/**` | The app's code that is no address: components and modules, on both sides. | 23.15, 23.16, 23.18, 23.22, 37.1 |
|
|
652
|
+
| `**/tests/**` | The app's tests. | 23.15, 23.16, 23.18, 23.22, 37.1, 38.109 |
|
|
653
|
+
| `**/public/**` | The files answered as authored, at their path below that directory. | 23.15, 23.16, 23.18, 36.11, 36.12, 36.13, 36.14, 36.15, 36.17, 21.12, 21.13, 21.14, 38.18, 38.19 |
|
|
654
|
+
| `src/public/favicon.ico` | The file answered at `/favicon.ico`. | 36.11 |
|
|
655
|
+
| `src/public/robots.txt` | The file answered at `/robots.txt`. | 36.11 |
|
|
656
|
+
| `src/public/icon.png` · `src/public/icon.icns` | The files answered at `/icon.png` and `/icon.icns`, and the desktop app's icon. | 36.11, 38.79 |
|
|
657
|
+
| `src/**/` | A directory of the app's, a segment of the route of every file directly in it. | 23.14, 23.17, 23.22 |
|
|
658
|
+
| `**/index.abide` | The page at its directory's route. | 19.1, 23.3, 23.4, 23.14, 23.18 |
|
|
659
|
+
| `**/<name>.abide` | The page at its directory's route and then `<name>`. | 19.1, 23.3, 23.4, 23.14, 23.21 |
|
|
660
|
+
| `**/<name>.ts` | A handler file: the handler its default export declares, at its directory's route and then `<name>`. | 16.2, 16.28, 16.73, 16.74, 19.1, 23.14, 23.22 |
|
|
661
|
+
| `**/layout.abide` | A layout, rendering every page below its route through a slot, and the hooks over that route. | 35.1, 35.12, 35.13, 37.2, 41.11, 41.19, 41.23 |
|
|
662
|
+
| `src/launcher.abide` | The desktop launcher, beside the root layout: the `onLauncher` it calls, and its page in place of the launcher's own where it has markup. | 38.80, 38.82, 38.84, 38.85, 38.107 |
|
|
663
|
+
| `src/layout.abide` | The root layout, whose `<script server>` is the app's own, and whose `<html>` is the document its pages are served in. | 35.15, 35.16, 35.17, 37.1, 37.3, 39.4 |
|
|
664
|
+
| `**/error.abide` | The page a refusal renders in. | 35.2, 35.3, 35.14 |
|
|
665
|
+
| `**/node_modules/**/*.abide` | A component a dependency ships as source, compiled with the app that imports it. | 34.23, 34.24, 34.25, 34.26, 34.27, 38.99 |
|
|
666
|
+
| `import '…' with { type: 'routes' }` | A package's directory mounted at the importing file's directory, its pages, layouts, error pages and handler files answering below it. | 23.19, 23.20 |
|
|
667
|
+
| `bunfig.toml` | The file whose `[serve.static] plugins` the client is built with. | 38.43 |
|
|
668
|
+
| `preload = ["@abide/abide/test"]` | The `[test]` preload a test imports the app's `.abide` files through. | 38.109 |
|
|
669
|
+
|
|
670
|
+
## Lifecycle hooks
|
|
671
|
+
|
|
672
|
+
| Name | Signature | Meaning | Rules |
|
|
673
|
+
| --- | --- | --- | --- |
|
|
674
|
+
| `middleware` | `(...rungs: Middleware<{ request: Request }, Response>[]) => () => void` | The per-request lane at the calling file's route. | 18.26, 37.2, 37.3 |
|
|
675
|
+
| `onStart` | `(fn: (start: () => Promise<void>) => void \| Promise<void>) => () => void` | Wraps the boot. | 37.4, 37.6 |
|
|
676
|
+
| `onStop` | `(fn: (stop: () => Promise<void>) => void \| Promise<void>) => () => void` | Mirrors it for teardown. | 37.4, 37.6 |
|
|
677
|
+
| `onError` | `(fn: (error: unknown) => unknown) => () => void` | Runs on an unexpected error at the calling file's route. | 37.5, 37.8 |
|
|
678
|
+
| `onConfig` | `(fn: ConfigDefaults \| null, options?: ConfigOptions) => () => void` | The app's config defaults. | 27.6, 37.7 |
|
|
679
|
+
| `onHealth` | `(report: () => unknown \| Promise<unknown>) => () => void` | The app's health reporter. | 25.2, 37.7 |
|
|
680
|
+
| `onPrincipal` | `(resolve: (claims: unknown) => unknown \| Promise<unknown>) => () => void` | Turns claims into the app's half of a principal. | 26.4, 37.7 |
|
|
681
|
+
| `onLauncher` | `(options: () => LauncherOptions) => () => void` | The window the desktop app opens and the forms its launcher offers. | 38.80, 38.81, 38.83, 38.86, 38.102, 38.107 |
|
|
682
|
+
|
|
683
|
+
## The desktop app
|
|
684
|
+
|
|
685
|
+
| Name | Signature | Meaning | Rules |
|
|
686
|
+
| --- | --- | --- | --- |
|
|
687
|
+
| `LauncherOptions` | `{ width?: number; height?: number; minWidth?: number; minHeight?: number } & ({ start?: true; connect?: boolean } \| { start: false; connect?: true })` | What an `onLauncher` may answer. | 38.80, 38.81 |
|
|
688
|
+
| `onMenu` | `(read: () => readonly MenuItem[]) => () => void` | The menus a layout or a page adds to the desktop app's menu bar while it stands. | 38.88, 38.92 |
|
|
689
|
+
| `MenuItem` | `'separator' \| MenuEntry \| { label: string; key?: string; role?: MenuRole; href?: string; items?: MenuItem[] }` | One entry in the menu bar or in a menu under it. | 38.89, 38.90 |
|
|
690
|
+
| `MenuRole` | `'about' \| 'hide' \| 'hideOthers' \| 'showAll' \| 'quit' \| 'connect' \| 'disconnect' \| 'close' \| 'undo' \| 'redo' \| 'cut' \| 'copy' \| 'paste' \| 'selectAll' \| 'reload' \| 'fullscreen' \| 'minimize' \| 'zoom' \| 'front'` | What a menu item does natively. | 38.74, 38.89 |
|
|
691
|
+
| `menuItem` | `(item: { label: string; key?: string; href?: string }) => MenuEntry` | A menu item the page that files it answers. | 38.91 |
|
|
692
|
+
| `MenuEntry` | `class MenuEntry { label: string; key: string \| undefined; href: string \| undefined }` | What `menuItem` makes. | 38.91 |
|
|
693
|
+
| `MenuEntry.on` | `(answer: () => unknown) => () => void` | Files a function run each time the item is picked. | 38.91 |
|
|
694
|
+
| `Launch` | `{ name: string; start: string \| undefined; connect: string \| undefined; fields: ConfigField[]; url: string; failure: { form: 'start' \| 'connect'; message: string; issues: Record<string, string[]> } \| undefined; focus: 'start' \| 'connect' \| undefined; icon: string \| undefined; accent: string \| undefined }` | The props a launch page is rendered with. | 38.82, 38.83, 38.87, 38.101 |
|
|
695
|
+
| `ConfigField` | `{ name: string; label: string; description: string \| undefined; input: 'text' \| 'number' \| 'checkbox' \| 'password' \| 'url' \| 'select'; options: string[] \| undefined; required: boolean; value: string }` | One input the start form asks for. | 38.72 |
|
|
696
|
+
|
|
697
|
+
# The app object
|
|
698
|
+
|
|
699
|
+
| Name | Signature | Meaning | Rules |
|
|
700
|
+
| --- | --- | --- | --- |
|
|
701
|
+
| `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 |
|
|
702
|
+
| `App` | `interface App` | What a host, a test or a script holds the app as. | 42.12, 42.13 |
|
|
703
|
+
| `App.fetch` | `(request: Request) => Promise<Response>` | The whole request path, entered in process. | 42.5, 42.6 |
|
|
704
|
+
| `App.run` | `<Result>(fn: () => Result \| Promise<Result>, options?: { request?: Request }) => Promise<Result>` | One scope around a function, and nothing else. | 42.7, 42.8, 11.38 |
|
|
705
|
+
| `App.listen` | `(options?: { port?: number; hostname?: string; unix?: string }) => Promise<void>` | The socket, bound. | 42.9 |
|
|
706
|
+
| `App.stop` | `() => Promise<void>` | The drain and the teardown. | 42.10, 42.11, 42.15, 37.4 |
|
|
707
|
+
| `App[Symbol.asyncDispose]` | `() => Promise<void>` | `App.stop`, under the name `await using` calls. | 42.14 |
|
|
708
|
+
|
|
709
|
+
# CLI
|
|
710
|
+
|
|
711
|
+
## Commands
|
|
712
|
+
|
|
713
|
+
| Command | Meaning | Rules |
|
|
714
|
+
| --- | --- | --- |
|
|
715
|
+
| `abide scaffold <name>` | Writes a starter project. | 38.1, 38.42, 38.103, 38.104, 38.106 |
|
|
716
|
+
| `abide run <file> [args…]` | Runs a script under the abide runtime. | 38.2, 38.57 |
|
|
717
|
+
| `abide check [dir…]` | The type-checker over a `.abide` tree. | 38.3, 38.31, 38.32, 38.33, 38.40, 38.105 |
|
|
718
|
+
| `abide routes [--json]` | Every address the app answers, the file answering it, and where each hook is filed. | 38.108 |
|
|
719
|
+
| `abide dev [--port <n>]` | Watches the project and keeps the app up. | 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 |
|
|
720
|
+
| `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 |
|
|
721
|
+
| `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 |
|
|
722
|
+
| `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 |
|
|
723
|
+
| `abide call <address> [args]` | One call to one handler. | 38.8, 38.61 |
|
|
724
|
+
| `abide openapi [--out <file>] [--url <origin>]` | The OpenAPI document written rather than served. | 38.9 |
|
|
725
|
+
| `abide mcp [--url <origin>]` | The app's MCP server over stdio. | 38.9, 38.13 |
|
|
726
|
+
| `abide watch <address> [args]` | A live subscription to one of the app's followed `GET`s. | 38.69 |
|
|
727
|
+
| `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 |
|
|
728
|
+
| `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 |
|
|
729
|
+
| `abide lsp` | The `.abide` language server, over stdio. | 38.11, 38.34, 38.39, 38.98 |
|
|
730
|
+
| `--help` · `-h` · `abide help` | Usage, generated from the command list. | 38.12 |
|