@abide/abide 0.100.0 → 0.102.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 +31 -0
- package/bin/abide.ts +227 -163
- package/docs/REGISTRY.md +726 -0
- package/docs/RULEBOOK.md +2753 -0
- package/docs/abide.md +12878 -0
- package/package.json +10 -3
- package/scaffold/AGENTS.md +31 -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 +262 -67
- package/src/compiler/argsSchemaOf.ts +1 -1
- package/src/compiler/checkApp.ts +43 -15
- package/src/compiler/checkedShadow.ts +39 -5
- package/src/compiler/classifyRead.ts +6 -4
- package/src/compiler/classifyTemplate.ts +1 -1
- package/src/compiler/compileApp.ts +433 -193
- package/src/compiler/compiledEntry.ts +43 -39
- package/src/compiler/componentGraph.ts +58 -71
- package/src/compiler/declaredExports.ts +24 -7
- package/src/compiler/emitClient.ts +141 -71
- package/src/compiler/emitComponent.ts +37 -8
- package/src/compiler/emitSource.ts +106 -13
- package/src/compiler/handlersUnder.ts +106 -56
- package/src/compiler/index.ts +7 -0
- package/src/compiler/mountsOf.ts +138 -0
- package/src/compiler/nearest.ts +14 -0
- package/src/compiler/parseAbide.ts +157 -20
- package/src/compiler/projectShadow.ts +213 -7
- package/src/compiler/reactiveTypes.ts +20 -7
- package/src/compiler/readSources.ts +15 -2
- package/src/compiler/readsIn.ts +61 -7
- package/src/compiler/renderMarkup.ts +3 -3
- package/src/compiler/scaffold.ts +30 -11
- package/src/compiler/serveLanguage.ts +125 -34
- package/src/compiler/sourceMapOf.ts +193 -0
- package/src/compiler/splitImports.ts +205 -83
- package/src/compiler/syncTypes.ts +32 -0
- package/src/compiler/tokenize.ts +14 -0
- package/src/compiler/writeDefaultProject.ts +1 -1
- package/src/compiler/writeTypes.ts +82 -0
- package/src/server/CLIENT_BUILD.ts +11 -13
- package/src/server/DEFAULT_PORT.ts +1 -1
- package/src/server/LAUNCHER_FILES.ts +9 -0
- package/src/server/MODULE_QUERIES.ts +18 -0
- package/src/server/TABLES.ts +7 -0
- package/src/server/VIRTUAL_DIRECTORY.ts +4 -5
- package/src/server/abideModules.ts +391 -0
- package/src/server/answerFailure.ts +16 -6
- package/src/server/answerRequest.ts +235 -106
- package/src/server/answerRpc.ts +124 -39
- package/src/server/answerSocket.ts +141 -48
- 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 +179 -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 +37 -37
- package/src/server/componentModules.d.ts +3 -1
- package/src/server/compressAnswer.ts +48 -14
- package/src/server/config.ts +25 -29
- package/src/server/configFields.ts +31 -25
- package/src/server/createApp.ts +59 -73
- package/src/server/devWorker.ts +144 -183
- package/src/server/executableName.ts +4 -0
- package/src/server/fenceServer.ts +37 -35
- package/src/server/generatedSurfaces.ts +99 -66
- package/src/server/hooks.ts +124 -52
- package/src/server/iconAccent.ts +191 -0
- package/src/server/index.ts +11 -7
- package/src/server/installSourceMaps.ts +88 -0
- package/src/server/launcherOptions.ts +34 -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 +5 -5
- package/src/server/negotiateEncoding.ts +1 -1
- 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 +52 -27
- package/src/server/serveBuild.ts +43 -52
- package/src/server/serveDev.ts +81 -39
- package/src/server/shell.ts +7 -22
- package/src/server/sourceMappings.ts +139 -0
- package/src/server/surfaceOf.ts +18 -3
- package/src/server/testBuild.ts +1 -19
- package/src/server/withAbideSources.ts +117 -0
- package/src/shared/ADDRESSES.ts +7 -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/GLOBAL_GETS.ts +9 -3
- package/src/shared/RESERVED_DIRECTORIES.ts +15 -0
- package/src/shared/RPC_SERVER.ts +2 -2
- 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 +1 -1
- package/src/shared/log.ts +27 -13
- package/src/shared/matchRoute.ts +23 -4
- package/src/shared/menuItem.ts +3 -3
- package/src/shared/reactive/Cursor.ts +3 -9
- package/src/shared/reactive/Keyed.ts +4 -3
- package/src/shared/reactive/NotLanded.ts +1 -1
- package/src/shared/reactive/Reactive.ts +81 -60
- 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 +155 -21
- package/src/shared/reactive/watch.ts +10 -6
- package/src/shared/refuse.ts +1 -1
- package/src/shared/routePattern.ts +82 -46
- package/src/shared/rpc.ts +47 -13
- 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 +38 -31
- 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/menuBridge.ts +1 -1
- package/src/ui/moveNode.ts +1 -1
- package/src/ui/reconcile.ts +2 -2
- package/src/ui/reportMenu.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 → page.abide} +0 -0
package/docs/RULEBOOK.md
ADDED
|
@@ -0,0 +1,2753 @@
|
|
|
1
|
+
# Rulebook
|
|
2
|
+
|
|
3
|
+
Every rule that governs behavior, stated once, numbered.
|
|
4
|
+
|
|
5
|
+
## What this document is
|
|
6
|
+
|
|
7
|
+
A **rulebook**. One clause per requirement, and the clause answers exactly one question: *what must
|
|
8
|
+
hold?*
|
|
9
|
+
|
|
10
|
+
## What belongs here, and what does not
|
|
11
|
+
|
|
12
|
+
| A statement | Goes | Because |
|
|
13
|
+
| --- | --- | --- |
|
|
14
|
+
| Constrains behavior, at build time or run time | here | a requirement is what two implementations have to agree on |
|
|
15
|
+
| Answerable from the type alone | REGISTRY.md | a signature is not a rule |
|
|
16
|
+
| Explains why the rule is this way | a guide in `packages/dogfood/src` | a reason is read once and never looked up |
|
|
17
|
+
| A measurement | the harness | a number in prose is a number nothing reruns |
|
|
18
|
+
|
|
19
|
+
## Format rules
|
|
20
|
+
|
|
21
|
+
These are immutable. A change to them is a change to what this document is.
|
|
22
|
+
|
|
23
|
+
1. **One clause states one requirement.** A clause carrying two is two clauses.
|
|
24
|
+
2. **A rule is stated exactly ONCE.** Any clause that needs another cites its number. A second
|
|
25
|
+
statement of a rule is drift, and only one of the two copies ever gets fixed.
|
|
26
|
+
3. **No clause carries a signature.** Types live in REGISTRY.md, and a check refuses a function
|
|
27
|
+
arrow here.
|
|
28
|
+
4. **Every clause names something** — a name from REGISTRY.md, or a term the table below defines.
|
|
29
|
+
A clause built on an undefined noun is prose about nothing, and a check refuses one.
|
|
30
|
+
5. **No rationale, no measurement, no example.** The word "because" is the tell.
|
|
31
|
+
6. **A group governing something REGISTRY does not name says so.** Most clauses hang off a name an
|
|
32
|
+
app writes, and the check that every clause is cited is what stops a rule drifting free of the
|
|
33
|
+
surface it governs. A few groups genuinely have no such name — the documentation system is not
|
|
34
|
+
part of the framework's surface — and one of those declares itself FREE-STANDING on the line
|
|
35
|
+
under its heading. The declaration is the exemption, so an uncited clause is either cited or
|
|
36
|
+
visibly excused, and never merely missed.
|
|
37
|
+
7. **A clause states what holds today.** A rule that stops holding is deleted, and the clauses
|
|
38
|
+
after it close the gap — every citation of a number is swept in the same change.
|
|
39
|
+
|
|
40
|
+
## Terms
|
|
41
|
+
|
|
42
|
+
A term below is a category the clauses are written over. It is defined here rather than in
|
|
43
|
+
REGISTRY.md because none of them is a name an app author writes.
|
|
44
|
+
|
|
45
|
+
| Term | Definition |
|
|
46
|
+
| --- | --- |
|
|
47
|
+
| read | A call to `s` or to `s.peek`. |
|
|
48
|
+
| write | A call to `s.set` or to `s.patch`. |
|
|
49
|
+
| gated | A production the `identity` comparison may collapse: one a write or a body mints, and not a chunk a stream lands. |
|
|
50
|
+
| probe | Any of `s.busy`, `s.ready`, `s.error`. |
|
|
51
|
+
| trigger | `s.refresh` or `s.invalidate`. |
|
|
52
|
+
| producer | A source a value can ask for a value: a body, a `store`, or the connection a subscriber's copy is carried over. |
|
|
53
|
+
| materialization | The making of a `Stored` from what a producer has yielded. |
|
|
54
|
+
| production | One materialization of a `Stored` that a reader may observe. |
|
|
55
|
+
| provisional | A body run that read a value which had not landed. |
|
|
56
|
+
| reader | An expression or effect that performed a read. |
|
|
57
|
+
| revalidation | A load started by `s.refresh` over a value still being served. |
|
|
58
|
+
| refusal | A `Failed` answered in place of a value. |
|
|
59
|
+
| wired | A `Reactive` a `socket` or an `Rpc` carries, at either end of the connection. |
|
|
60
|
+
| subscriber | A far end of a connection a wired `Reactive` is carried to. |
|
|
61
|
+
| version | The number one production of a `global` value a `GET` serves is named by on the wire. |
|
|
62
|
+
| namespace | The name a log line is written under, and what `DEBUG` selects. |
|
|
63
|
+
| entry | One key's slot in a `Keyed`. |
|
|
64
|
+
| scope | The lifetime a value is filed under and dropped with. |
|
|
65
|
+
| adoption | What a `reactive` body does with a `Reactive` it returned. |
|
|
66
|
+
| forwarding | The delegation between an adopting `Reactive` and the one it adopted. |
|
|
67
|
+
| propagation | The derivation of a probe from the values a body read. |
|
|
68
|
+
| sink | What 35.7 defines. |
|
|
69
|
+
| implementation | Anything claiming conformance to this document. |
|
|
70
|
+
| dependency's `.abide` | A `.abide` file under a `node_modules` directory or outside the app's root. |
|
|
71
|
+
|
|
72
|
+
RFC 2119 keywords are used as that document defines them: **MUST**, **MUST NOT**, **SHALL**,
|
|
73
|
+
**SHOULD**, **SHOULD NOT**, **MAY**.
|
|
74
|
+
|
|
75
|
+
# 1. The reactive value
|
|
76
|
+
|
|
77
|
+
1.1 Every producer in this design MUST hand back a `Reactive`.
|
|
78
|
+
|
|
79
|
+
1.2 `Produced` MUST be the unit the producer yielded: `Stored` for every producer but a streaming one,
|
|
80
|
+
and one chunk for a streaming producer.
|
|
81
|
+
|
|
82
|
+
1.3 `Failures` MUST be the union of the refusals the producer declared, and MUST carry the
|
|
83
|
+
validation refusal wherever a `schema` is declared, without the app declaring it.
|
|
84
|
+
|
|
85
|
+
1.4 A `Reactive` MUST be thenable.
|
|
86
|
+
|
|
87
|
+
1.5 `s.catch` and `s.finally` MUST derive from `s.then`.
|
|
88
|
+
|
|
89
|
+
1.6 Where a load is told apart from a value, a `Reactive` MUST be taken as a value.
|
|
90
|
+
|
|
91
|
+
1.7 Reaching a `Reactive` MUST start the work it is for, unless a window holds it back per 5.19.
|
|
92
|
+
|
|
93
|
+
1.8 Reaching a `Reactive` that already exists MUST join the standing work rather than start a
|
|
94
|
+
second.
|
|
95
|
+
|
|
96
|
+
# 2. Reads
|
|
97
|
+
|
|
98
|
+
2.1 A read MUST return what is held, and MUST NOT await.
|
|
99
|
+
|
|
100
|
+
2.2 A read MUST throw where a producer failed and no value has landed.
|
|
101
|
+
|
|
102
|
+
2.3 A rejected write MUST NOT cause a read to throw.
|
|
103
|
+
|
|
104
|
+
2.4 A failed revalidation MUST NOT cause a read to throw.
|
|
105
|
+
|
|
106
|
+
2.5 `s[Symbol.asyncIterator]` MUST yield the production in flight from its start, and MUST then
|
|
107
|
+
continue live.
|
|
108
|
+
|
|
109
|
+
2.6 On a value that is not a streaming producer, `s[Symbol.asyncIterator]` MUST hand back the
|
|
110
|
+
standing value once per turn, however many productions or patches landed since the last.
|
|
111
|
+
|
|
112
|
+
2.7 `s.then` MUST resolve with the value where `s.busy` becomes false and 2.2 would not throw.
|
|
113
|
+
|
|
114
|
+
2.8 `s.then` MUST reject with what 2.2 throws, where 2.2 would throw.
|
|
115
|
+
|
|
116
|
+
2.9 A read MUST throw `NotLanded` where nothing has landed and no producer has failed.
|
|
117
|
+
|
|
118
|
+
2.10 `s.peek` MUST return `undefined` where 2.9 would throw.
|
|
119
|
+
|
|
120
|
+
2.11 `s.peek` MUST NOT join the flow.
|
|
121
|
+
|
|
122
|
+
2.12 A `NotLanded` thrown into a tracked body MUST abort that body.
|
|
123
|
+
|
|
124
|
+
2.13 A body a `NotLanded` aborted MUST rerun when the value it names lands.
|
|
125
|
+
|
|
126
|
+
2.14 A `NotLanded` and a `Failed` MUST be distinguishable by brand.
|
|
127
|
+
|
|
128
|
+
# 3. Probes
|
|
129
|
+
|
|
130
|
+
3.1 A probe MUST NOT throw.
|
|
131
|
+
|
|
132
|
+
3.2 A probe MUST answer about the value a read would serve, running what that read would run, and
|
|
133
|
+
MUST NOT otherwise start work.
|
|
134
|
+
|
|
135
|
+
3.3 Reading a probe MUST subscribe to that probe alone.
|
|
136
|
+
|
|
137
|
+
3.4 A sink MUST be opened where `s.busy` is true and `s.ready` is false.
|
|
138
|
+
|
|
139
|
+
3.5 `s.ready` and `s.error` MUST be orthogonal: either MAY be true while the other is.
|
|
140
|
+
|
|
141
|
+
3.6 `s.ready` MUST NOT move for a load in flight.
|
|
142
|
+
|
|
143
|
+
3.7 A streaming producer MUST report `s.busy` true until the stream closes.
|
|
144
|
+
|
|
145
|
+
3.8 A streaming producer MUST report `s.ready` true from its first chunk.
|
|
146
|
+
|
|
147
|
+
3.9 A value with no producer MUST report `s.busy` false.
|
|
148
|
+
|
|
149
|
+
# 4. Writes and gates
|
|
150
|
+
|
|
151
|
+
4.1 `s.set` MUST accept a settled value or a load, and `reactive` MUST accept the same two.
|
|
152
|
+
|
|
153
|
+
4.2 A load given to either MUST make the `Reactive` loaded, at construction and at every write
|
|
154
|
+
alike.
|
|
155
|
+
|
|
156
|
+
4.3 Where a `schema` is declared it MUST run first, on the settled value.
|
|
157
|
+
|
|
158
|
+
4.4 What `schema` returns MUST be what `transform` receives.
|
|
159
|
+
|
|
160
|
+
4.5 A `schema` MUST refuse by throwing, and the throw MUST be caught and converted rather than
|
|
161
|
+
escape the write.
|
|
162
|
+
|
|
163
|
+
4.6 A `transform` MUST refuse by returning a `Failed` rather than by throwing, per 15.5.
|
|
164
|
+
|
|
165
|
+
4.7 A `transform` MUST run untracked, on the settled value, once per materialization of a `Stored`.
|
|
166
|
+
|
|
167
|
+
4.8 A `transform` MUST NOT run on a promise, and MUST NOT run per chunk.
|
|
168
|
+
|
|
169
|
+
4.9 A refused write MUST store nothing and MUST mint no production.
|
|
170
|
+
|
|
171
|
+
4.10 A refused write MUST fill `s.error`, and MUST NOT reach a `{:catch}`.
|
|
172
|
+
|
|
173
|
+
4.11 An accepted write or production MUST clear the standing `s.error`.
|
|
174
|
+
|
|
175
|
+
4.12 A failed revalidation MUST leave the held value being served, and MUST warn on
|
|
176
|
+
`abide:reactive` naming the value.
|
|
177
|
+
|
|
178
|
+
4.13 `s.set` MUST take the `Accepted` its factory declared, and a `Reactive` MUST carry that
|
|
179
|
+
`Accepted` wherever it is passed.
|
|
180
|
+
|
|
181
|
+
4.14 `reactive` called with no argument MUST land nothing.
|
|
182
|
+
|
|
183
|
+
4.15 `reactive` called with `undefined` MUST land `undefined`.
|
|
184
|
+
|
|
185
|
+
4.16 An opening `undefined`, the value form's or a body's first answer, MUST land without passing a
|
|
186
|
+
`schema`, a `transform`, a window or a `store`.
|
|
187
|
+
|
|
188
|
+
4.17 `s.set` MUST store a `Failed` it is given as a value rather than refuse the write.
|
|
189
|
+
|
|
190
|
+
4.18 `s.set` MUST hand back the refusal a gate refused it with, and nothing where it was accepted.
|
|
191
|
+
|
|
192
|
+
# 5. Productions and identity
|
|
193
|
+
|
|
194
|
+
5.1 A reader MUST be woken only when read identity changes.
|
|
195
|
+
|
|
196
|
+
5.2 A production whose identity matches the previous `Stored` MUST mint nothing, and MUST wake no
|
|
197
|
+
reader.
|
|
198
|
+
|
|
199
|
+
5.3 `identity` MUST be discriminated by arity: one parameter is a projection compared by `!==`, and
|
|
200
|
+
two is a comparator answering directly.
|
|
201
|
+
|
|
202
|
+
5.4 The default `identity` MUST be the reference.
|
|
203
|
+
|
|
204
|
+
5.5 `structural` MUST answer "not equal" wherever it cannot decide.
|
|
205
|
+
|
|
206
|
+
5.6 A write MUST mint a production of its own.
|
|
207
|
+
|
|
208
|
+
5.7 `s.patch` MUST mutate the production it serves in place rather than mint one.
|
|
209
|
+
|
|
210
|
+
5.8 `throttle` and `debounce` MUST cap how often a value changes for a reader.
|
|
211
|
+
|
|
212
|
+
5.9 A capped window MUST cap the wake, and MUST NOT itself drop a production.
|
|
213
|
+
|
|
214
|
+
5.10 A cursor over a streaming producer MUST deliver every chunk a window collapsed.
|
|
215
|
+
|
|
216
|
+
5.11 An implementation MUST NOT start work a window would discard.
|
|
217
|
+
|
|
218
|
+
5.12 `throttle` MUST allow a change immediately and then at most once per window.
|
|
219
|
+
|
|
220
|
+
5.13 `debounce` MUST delay a change until the changes stop.
|
|
221
|
+
|
|
222
|
+
5.14 Declaring both `throttle` and `debounce` MUST refuse at construction.
|
|
223
|
+
|
|
224
|
+
5.15 Where a `throttle` or a `debounce` window is holding a production back, the held value MUST
|
|
225
|
+
be served and `s.busy` MUST be true.
|
|
226
|
+
|
|
227
|
+
5.16 A `bind:` read MUST NOT be capped.
|
|
228
|
+
|
|
229
|
+
5.17 `throttle` and `debounce` on a streaming producer MUST cap how often its readers are woken.
|
|
230
|
+
|
|
231
|
+
5.18 A read of a capped streaming producer MUST serve the accumulation as the last release left it.
|
|
232
|
+
|
|
233
|
+
5.19 `throttle` and `debounce` on a `Keyed` MUST hold back starting a newly reached entry until the
|
|
234
|
+
window allows it.
|
|
235
|
+
|
|
236
|
+
5.20 An entry a `Keyed` window replaced with a later key before it started MUST NOT be started, and
|
|
237
|
+
MUST NOT be held.
|
|
238
|
+
|
|
239
|
+
5.21 An entry a `Keyed` window is holding back MUST report `s.busy` true.
|
|
240
|
+
|
|
241
|
+
5.22 `by` MUST key an element by the property it names, or by what the function it is returns for
|
|
242
|
+
that element.
|
|
243
|
+
|
|
244
|
+
5.23 `throttle` and `debounce` MUST cap the wakes an `s.patch` makes as they cap a production's.
|
|
245
|
+
|
|
246
|
+
5.24 `throttle` and `debounce` MUST hold an `s.refresh` as they hold a production, and a refresh a
|
|
247
|
+
window held MUST start one reload when the window closes.
|
|
248
|
+
|
|
249
|
+
# 6. Expiry
|
|
250
|
+
|
|
251
|
+
6.1 A `ttl` expiry MUST wake no reader.
|
|
252
|
+
|
|
253
|
+
6.2 `ttl` on a value with no producer MUST be inert.
|
|
254
|
+
|
|
255
|
+
6.3 An implementation MUST hold one expiry timer per value declaring `ttl`, armed at the deadline of
|
|
256
|
+
the production it serves.
|
|
257
|
+
|
|
258
|
+
6.4 A `ttl` expiry timer MUST NOT hold the process open.
|
|
259
|
+
|
|
260
|
+
6.5 A read finding the standing production past its `ttl` MUST NOT serve it.
|
|
261
|
+
|
|
262
|
+
6.6 A read finding the standing production past its `ttl` MUST run the producer.
|
|
263
|
+
|
|
264
|
+
6.7 A standing production past its `ttl` MUST be released.
|
|
265
|
+
|
|
266
|
+
6.8 A value whose standing production is past its `ttl` MUST report `s.ready` false.
|
|
267
|
+
|
|
268
|
+
6.9 An expiry MUST NOT report `s.busy` true.
|
|
269
|
+
|
|
270
|
+
6.10 A cursor MUST NOT be handed an `undefined` production.
|
|
271
|
+
|
|
272
|
+
6.11 A streaming producer's `ttl` MUST run from its run's close, and MUST NOT reach the run in
|
|
273
|
+
flight.
|
|
274
|
+
|
|
275
|
+
# 7. Triggers
|
|
276
|
+
|
|
277
|
+
7.1 Every `Reactive` MUST carry `s.refresh` and `s.invalidate`.
|
|
278
|
+
|
|
279
|
+
7.2 `s.invalidate` MUST drop the cache behind the value, and MUST NOT drop the value.
|
|
280
|
+
|
|
281
|
+
7.3 `s.invalidate` MUST NOT move a node and MUST NOT send a request.
|
|
282
|
+
|
|
283
|
+
7.4 `s.refresh` MUST keep serving what is held until the new value lands.
|
|
284
|
+
|
|
285
|
+
7.5 `s.refresh` MUST report `s.busy` true while the reload is in flight.
|
|
286
|
+
|
|
287
|
+
7.6 `s.refresh` and `s.invalidate` MUST be inert on a value with no producer, beside what 7.10 and
|
|
288
|
+
7.18 send its subscribers.
|
|
289
|
+
|
|
290
|
+
7.7 `s.invalidate` MUST mark the held value stale.
|
|
291
|
+
|
|
292
|
+
7.8 A load over a value marked stale MUST report `s.ready` false, and a read over it MUST throw
|
|
293
|
+
`NotLanded` until it lands.
|
|
294
|
+
|
|
295
|
+
7.9 An accepted production MUST clear the stale mark.
|
|
296
|
+
|
|
297
|
+
7.10 `s.invalidate` on a wired `Reactive` MUST invalidate every subscriber's copy.
|
|
298
|
+
|
|
299
|
+
7.11 `s.refresh` MUST reload whether or not anything subscribes.
|
|
300
|
+
|
|
301
|
+
7.12 The first read of a value `s.invalidate` marked MUST run its producer.
|
|
302
|
+
|
|
303
|
+
7.13 A read of a value built from one `s.invalidate` marked MUST run that producer first.
|
|
304
|
+
|
|
305
|
+
7.14 `s.invalidate` MUST NOT wake a reader, a probe's reader included.
|
|
306
|
+
|
|
307
|
+
7.15 `s.invalidate` MUST discard the load or the stream it finds in flight.
|
|
308
|
+
|
|
309
|
+
7.16 A value `s.invalidate` marked MUST NOT report `s.busy` true until a read or a probe runs its
|
|
310
|
+
producer.
|
|
311
|
+
|
|
312
|
+
7.17 A value `s.invalidate` marked MUST go on being served until a read or a probe runs its producer.
|
|
313
|
+
|
|
314
|
+
7.18 `s.refresh` on a wired `Reactive` MUST refresh every subscriber's copy.
|
|
315
|
+
|
|
316
|
+
# 8. Stores
|
|
317
|
+
|
|
318
|
+
8.1 A `Store` MUST provide both `get` and `set`.
|
|
319
|
+
|
|
320
|
+
8.2 A `Store`'s `get` MUST be a producer, and the value MUST therefore answer to 7.1.
|
|
321
|
+
|
|
322
|
+
8.3 A `Store`'s `get` MUST answer before the initial value, and the initial value MUST be what a
|
|
323
|
+
miss falls back to.
|
|
324
|
+
|
|
325
|
+
8.4 A synchronous `get` MUST NOT make the value loaded.
|
|
326
|
+
|
|
327
|
+
8.5 A restore MUST mint a production without running `schema` or `transform`.
|
|
328
|
+
|
|
329
|
+
8.6 A restore of a streaming producer MUST seed its accumulation with what was stored.
|
|
330
|
+
|
|
331
|
+
8.7 A restored stream MUST report `s.ready` true and `s.busy` false.
|
|
332
|
+
|
|
333
|
+
8.8 A `Store`'s `set` MUST run once per production, per 5.2.
|
|
334
|
+
|
|
335
|
+
8.9 A `Store`'s `set` on a streaming producer MUST run once at close, on the accumulation.
|
|
336
|
+
|
|
337
|
+
8.10 Writes to a `Store` MUST coalesce latest-wins, and MUST NOT queue.
|
|
338
|
+
|
|
339
|
+
8.11 A write to a `Store` MUST NOT block a reader.
|
|
340
|
+
|
|
341
|
+
8.12 A failed `Store` write MUST NOT detach the store; it MUST reach `onError` and warn on
|
|
342
|
+
`abide:reactive`.
|
|
343
|
+
|
|
344
|
+
8.13 A `Store`'s `set` MUST receive the `Reactive`'s own `ttl`, in milliseconds.
|
|
345
|
+
|
|
346
|
+
8.14 A `store` MUST run where the `Reactive` is constructed.
|
|
347
|
+
|
|
348
|
+
8.15 A value a `Store`'s `get` cannot read MUST be a miss, per 8.3.
|
|
349
|
+
|
|
350
|
+
8.16 A trigger on a `Reactive` with both a body and a `store` MUST run the body.
|
|
351
|
+
|
|
352
|
+
8.17 A `Store`'s `get` answering `undefined` MUST be a miss.
|
|
353
|
+
|
|
354
|
+
8.18 A `Store`'s `get` MUST NOT run while a write to that `Store` is in flight or held per 8.10,
|
|
355
|
+
the value of that write standing in its place.
|
|
356
|
+
|
|
357
|
+
8.19 A `Store`'s `get` answering a miss with nothing left to serve MUST land an error on `s.error`.
|
|
358
|
+
|
|
359
|
+
# 9. Streams and wired values
|
|
360
|
+
|
|
361
|
+
9.1 A streaming producer's `Stored` MUST be the chunks accumulated so far, materialized on the
|
|
362
|
+
read that asks for it.
|
|
363
|
+
|
|
364
|
+
9.2 An implementation MUST NOT accumulate chunks by copying the accumulation per chunk.
|
|
365
|
+
|
|
366
|
+
9.3 `identity` MUST compare against the previous production alone.
|
|
367
|
+
|
|
368
|
+
9.4 A production arriving over a connection MUST replace a write standing on the subscriber's copy.
|
|
369
|
+
|
|
370
|
+
9.5 A `store` MUST round-trip the latest production.
|
|
371
|
+
|
|
372
|
+
9.6 A `reactive` body declared as an async generator function MUST be a streaming producer from
|
|
373
|
+
construction, and a body whose run hands back an async generator, or a promise resolving to one,
|
|
374
|
+
MUST be one from that run on.
|
|
375
|
+
|
|
376
|
+
9.7 `s.refresh` on a streaming producer MUST serve the held accumulation until the new stream's
|
|
377
|
+
first chunk, and that stream's accumulation from then on.
|
|
378
|
+
|
|
379
|
+
9.8 A `schema` and a `transform` on a streaming producer MUST run on the accumulation a read
|
|
380
|
+
materializes, at most once per chunk the accumulation holds.
|
|
381
|
+
|
|
382
|
+
9.9 A streaming producer MUST wake its readers at most once per task.
|
|
383
|
+
|
|
384
|
+
9.10 `flushSync` MUST deliver the wakes a streaming producer is holding.
|
|
385
|
+
|
|
386
|
+
9.11 A write to a streaming producer MUST stand until its accumulation next changes, and an adoption
|
|
387
|
+
made by one (11.61) MUST end with it.
|
|
388
|
+
|
|
389
|
+
9.12 A write to a streaming producer MUST NOT move a cursor over it.
|
|
390
|
+
|
|
391
|
+
9.13 `s.patch` on a streaming producer MUST mutate its accumulation in place.
|
|
392
|
+
|
|
393
|
+
9.14 A subscriber's copy of a wired `Reactive` MUST report `s.busy` true until the first production
|
|
394
|
+
arrives.
|
|
395
|
+
|
|
396
|
+
# 10. Sharing
|
|
397
|
+
|
|
398
|
+
10.1 `reactive.share` MUST get or create in one call.
|
|
399
|
+
|
|
400
|
+
10.2 A key given to `reactive.share` MUST be a literal, and a non-literal MUST be a build error.
|
|
401
|
+
|
|
402
|
+
10.3 A key `Shared` declares MUST be checked against it, and a key it does not declare MUST be
|
|
403
|
+
inferred from the thunk.
|
|
404
|
+
|
|
405
|
+
10.4 A value created by `reactive.share` MUST NOT be evicted within its scope.
|
|
406
|
+
|
|
407
|
+
10.5 The scope of `reactive.share` MUST be the component instance and its descendants.
|
|
408
|
+
|
|
409
|
+
10.6 `reactive.share` MUST create in the calling scope where no ancestor holds that key.
|
|
410
|
+
|
|
411
|
+
10.7 An implementation MUST NOT provide a process-wide `reactive.share`.
|
|
412
|
+
|
|
413
|
+
# 11. Derived and keyed values
|
|
414
|
+
|
|
415
|
+
11.1 A `reactive` body declaring no parameter MUST produce an unkeyed, tracked `Reactive`.
|
|
416
|
+
|
|
417
|
+
11.2 A `reactive` body declaring one parameter MUST produce a keyed, untracked `Keyed`.
|
|
418
|
+
|
|
419
|
+
11.3 An implementation MUST NOT provide an option converting one `reactive` form into the other.
|
|
420
|
+
|
|
421
|
+
11.4 A `Keyed` MUST hold one entry per `Args` key, computed when that key is reached.
|
|
422
|
+
|
|
423
|
+
11.5 An unkeyed `reactive` MUST recompute on the first read that follows a change to a value its
|
|
424
|
+
body read.
|
|
425
|
+
|
|
426
|
+
11.6 A `Keyed` MUST NOT recompute for that reason, and `ttl`, `invalidate`, `refresh` and
|
|
427
|
+
eviction MUST be its only ways back.
|
|
428
|
+
|
|
429
|
+
11.7 Both `reactive` body forms MUST accept a write.
|
|
430
|
+
|
|
431
|
+
11.8 A write to a `reactive` that is not adopting MUST stand until the next recompute replaces it.
|
|
432
|
+
|
|
433
|
+
11.9 An implementation MUST NOT warn on a write to a `reactive`.
|
|
434
|
+
|
|
435
|
+
11.10 A write of a settled value to a `reactive` MUST move no probe.
|
|
436
|
+
|
|
437
|
+
11.11 A write of an unsettled value to a `reactive` MUST be a load, per 4.2 and 1.6.
|
|
438
|
+
|
|
439
|
+
11.12 A `Reactive` returned from a `reactive` body MUST be adopted, and MUST NOT be stored as a
|
|
440
|
+
value.
|
|
441
|
+
|
|
442
|
+
11.13 Adoption MUST mirror the adopted productions into the adopting `Reactive`.
|
|
443
|
+
|
|
444
|
+
11.14 An adopting `reactive` MUST run its own `transform` on the way in.
|
|
445
|
+
|
|
446
|
+
11.15 Adoption MUST forward members the adopted `Reactive` declares beyond the common face, by
|
|
447
|
+
delegation to whatever is currently adopted.
|
|
448
|
+
|
|
449
|
+
11.16 On re-adoption a `reactive` MUST clear where the newly adopted `Reactive` has nothing to serve.
|
|
450
|
+
|
|
451
|
+
11.17 Adoption MUST inherit the adopted `Reactive`'s `identity` where the outer declared none, for as
|
|
452
|
+
long as it adopts it.
|
|
453
|
+
|
|
454
|
+
11.18 A recompute landing on the same adopted `Reactive` MUST wake no reader.
|
|
455
|
+
|
|
456
|
+
11.19 An adopting `reactive` MUST report `s.busy` only where the newly adopted `Reactive` reports
|
|
457
|
+
it.
|
|
458
|
+
|
|
459
|
+
11.20 `s.busy` and `s.ready` MUST be the probes that propagate.
|
|
460
|
+
|
|
461
|
+
11.21 An unkeyed `reactive` MUST report `s.busy` for its own load, or for any value its body read.
|
|
462
|
+
|
|
463
|
+
11.22 An implementation MUST derive a propagated probe on the read that asks for it, and MUST NOT
|
|
464
|
+
hold a subscription per source for it.
|
|
465
|
+
|
|
466
|
+
11.23 A `Keyed` MUST propagate nothing.
|
|
467
|
+
|
|
468
|
+
11.24 An `Args` object MUST become a key by its canonical wire form: members sorted by name,
|
|
469
|
+
`undefined` members dropped, and `Date` written ISO.
|
|
470
|
+
|
|
471
|
+
11.25 An `Args` key MUST be structural.
|
|
472
|
+
|
|
473
|
+
11.26 The key MUST be taken before `args` runs.
|
|
474
|
+
|
|
475
|
+
11.27 The order over `Args` MUST be coerce, apply syntax defaults, canonicalize, validate, then
|
|
476
|
+
the body.
|
|
477
|
+
|
|
478
|
+
11.28 An `args` gate MUST refuse and MUST NOT decide which entry an `Args` object lands on.
|
|
479
|
+
|
|
480
|
+
11.29 A literal default written in the body's parameter MUST participate in the `Args` key, on
|
|
481
|
+
both sides, and an absent `Args` MUST be keyed as `{}` where the parameter writes one.
|
|
482
|
+
|
|
483
|
+
11.30 The build MUST warn where `args` declares a default the parameter does not.
|
|
484
|
+
|
|
485
|
+
11.31 A reactive value in an argument position MUST be read, and `Args` MUST be plain args.
|
|
486
|
+
|
|
487
|
+
11.32 A `reactive` without `global` MUST be request-local on a server and process-local in a browser.
|
|
488
|
+
|
|
489
|
+
11.33 `ttl: Infinity` without `global` MUST mean to the end of that scope.
|
|
490
|
+
|
|
491
|
+
11.34 `global: true` MUST place entries in a process-wide cache that outlives every request.
|
|
492
|
+
|
|
493
|
+
11.35 A `global` `reactive` MUST be bounded by its own `ttl` and by `invalidate`, and by nothing else.
|
|
494
|
+
|
|
495
|
+
11.36 An implementation MUST NOT evict a `global` entry on a size or a count limit.
|
|
496
|
+
|
|
497
|
+
11.37 `global: true` MUST be a build error on a body reading `request`, `response`, `principal`,
|
|
498
|
+
`cookies`, `csp.nonce` or `route`, and the error MUST name the ambient.
|
|
499
|
+
|
|
500
|
+
11.38 Coalescing of a `reactive` load MUST be within a scope: two reads of one key in one scope share
|
|
501
|
+
one load, and two scopes load twice.
|
|
502
|
+
|
|
503
|
+
11.39 A reader detaching from a `global` streaming `reactive` MUST NOT cancel the producer for the
|
|
504
|
+
readers that remain.
|
|
505
|
+
|
|
506
|
+
11.40 `args` on a `reactive` MUST check `Args`.
|
|
507
|
+
|
|
508
|
+
11.41 `args` MUST be unspellable on the unkeyed `reactive` overload, and spelling it MUST be a compile
|
|
509
|
+
error naming the overload.
|
|
510
|
+
|
|
511
|
+
11.42 `store` on a `Keyed` MUST accept a function of the `Args`.
|
|
512
|
+
|
|
513
|
+
11.43 `tags` MUST be what a `Selection` matches on, and MUST be the only selector reaching across
|
|
514
|
+
values.
|
|
515
|
+
|
|
516
|
+
11.44 The function form of `tags` MUST receive the value's `Args`.
|
|
517
|
+
|
|
518
|
+
11.45 A `Keyed`'s `ttl` MUST be the life of the entry.
|
|
519
|
+
|
|
520
|
+
11.46 A `reactive` MUST accept a `schema`, gating what its body produced.
|
|
521
|
+
|
|
522
|
+
11.47 An adopting `reactive` MUST run its own `schema` on the way in, as 11.14 has it run its
|
|
523
|
+
`transform`.
|
|
524
|
+
|
|
525
|
+
11.48 A `Keyed` MUST hold one expiry timer, armed at its oldest entry.
|
|
526
|
+
|
|
527
|
+
11.49 An entry MUST take the newest position on every production and every `s.patch`.
|
|
528
|
+
|
|
529
|
+
11.50 Every probe MUST forward from the adopted `Reactive` to the adopting one.
|
|
530
|
+
|
|
531
|
+
11.51 Every trigger on an adopting `Reactive` MUST reach the adopted one.
|
|
532
|
+
|
|
533
|
+
11.52 A provisional run MUST mint no production.
|
|
534
|
+
|
|
535
|
+
11.53 A reader joining a `global` `reactive`'s stream after it began MUST NOT be answered with a
|
|
536
|
+
refusal.
|
|
537
|
+
|
|
538
|
+
11.54 A `reactive` MUST NOT report `s.ready` before its body has run for the value being probed.
|
|
539
|
+
|
|
540
|
+
11.55 A probe over a key a `Keyed` has not computed MUST allocate no entry.
|
|
541
|
+
|
|
542
|
+
11.56 An implementation MUST NOT warn where two `Args` keys differ only in the case of a value.
|
|
543
|
+
|
|
544
|
+
11.57 An unkeyed `reactive` MUST NOT recompute before a read or an `Effect` asks for its value.
|
|
545
|
+
|
|
546
|
+
11.58 An unkeyed `reactive` MUST report `s.ready` only where every value its body read reports it.
|
|
547
|
+
|
|
548
|
+
11.59 `s.set` and `s.patch` on an adopting `Reactive`, given anything but a `Reactive`, MUST reach the
|
|
549
|
+
adopted `Reactive`.
|
|
550
|
+
|
|
551
|
+
11.60 `args` spelled on a `reactive` whose body declares no parameter MUST refuse at construction.
|
|
552
|
+
|
|
553
|
+
11.61 `s.set` given a `Reactive`, and `reactive` opened on one, MUST adopt it per 11.12, and MUST NOT
|
|
554
|
+
store it as a value — on a streaming producer, as a write that 11.59 does not reach through.
|
|
555
|
+
|
|
556
|
+
11.62 A body answering `undefined` MUST land `undefined`.
|
|
557
|
+
|
|
558
|
+
11.63 A body a `NotLanded` aborted that something probes MUST rerun in the turn that lands the
|
|
559
|
+
value it named.
|
|
560
|
+
|
|
561
|
+
11.64 Reaching a `Keyed` with an `Args` member 11.24 cannot write — anything outside `JsonValue`
|
|
562
|
+
but a `Date`, or a number that is not finite — MUST throw, naming the path to the member.
|
|
563
|
+
|
|
564
|
+
11.65 An adoption that would close a cycle of adopting `Reactive`s MUST be refused where it forms,
|
|
565
|
+
naming the cycle.
|
|
566
|
+
|
|
567
|
+
11.66 `s.set` MUST throw 11.65's refusal, and a body whose answer 11.65 refuses MUST fail with it.
|
|
568
|
+
|
|
569
|
+
11.67 A `reactive` without `global` MUST be built afresh in each request that reaches it, from its
|
|
570
|
+
declaration and never from what a write outside every request left.
|
|
571
|
+
|
|
572
|
+
11.68 A keyed value's body MUST be handed what its `args` gate returned.
|
|
573
|
+
|
|
574
|
+
11.69 A `Keyed` entry whose load is in flight MUST NOT be evicted by its `ttl`, and its life MUST
|
|
575
|
+
start again when the load ends.
|
|
576
|
+
|
|
577
|
+
11.70 `s.set` MUST take only a `Reactive` whose `Failures` are this value's.
|
|
578
|
+
|
|
579
|
+
# 12. Effects
|
|
580
|
+
|
|
581
|
+
12.1 A `Disposer` MUST run before each rerun of its `Effect`, and once more at teardown.
|
|
582
|
+
|
|
583
|
+
12.2 An `Effect` MUST run immediately, and again whenever a reactive value it read changes.
|
|
584
|
+
|
|
585
|
+
12.3 Where sources are given to `watch`, the `Effect` MUST run only when those sources change.
|
|
586
|
+
|
|
587
|
+
12.4 A `watch` registered inside a component MUST be owned by that component.
|
|
588
|
+
|
|
589
|
+
12.5 On a server a `watch` MUST rerun as it does in a browser, and its `Disposer` MUST run at the
|
|
590
|
+
teardown of the scope it was opened in.
|
|
591
|
+
|
|
592
|
+
12.6 A throw from an `Effect` or a `Disposer`, and a read of a failed `Reactive` inside one, MUST
|
|
593
|
+
reach `onError` as thrown, and MUST warn on `abide:watch` with the trace.
|
|
594
|
+
|
|
595
|
+
12.7 In a browser a throw from an `Effect` MUST additionally be re-thrown, to surface as an uncaught
|
|
596
|
+
error.
|
|
597
|
+
|
|
598
|
+
12.8 An `Effect` that threw MUST stop its `watch`.
|
|
599
|
+
|
|
600
|
+
12.9 `s.watch` MUST be `watch` narrowed to that `Reactive`, and MUST NOT diverge from it on 12.1,
|
|
601
|
+
12.2 or 12.8.
|
|
602
|
+
|
|
603
|
+
12.10 An `Effect` a write woke MUST run at the end of that turn, and MUST NOT run once per write.
|
|
604
|
+
|
|
605
|
+
12.11 `flushSync` MUST end the turn where it is called.
|
|
606
|
+
|
|
607
|
+
12.12 A read MUST answer what the writes in its turn left, whether or not the `Effect` values they
|
|
608
|
+
woke have run.
|
|
609
|
+
|
|
610
|
+
12.13 A `watch` registered inside a `{#if}` arm or a `{#for}` row MUST stop when the region
|
|
611
|
+
holding that arm or row is removed.
|
|
612
|
+
|
|
613
|
+
12.14 A `reactive` over a body that is not a stream, built where 12.4, 12.5 or 12.13 would own a
|
|
614
|
+
`watch`, MUST stop reading its sources once that owner stops and nothing else reads it, and MUST
|
|
615
|
+
answer a later read with what its body computes then.
|
|
616
|
+
|
|
617
|
+
# 13. Selections
|
|
618
|
+
|
|
619
|
+
13.1 A `Selection` MUST be one `Reactive`, one `Keyed`, one `Rpc`, or a set of `tags`.
|
|
620
|
+
|
|
621
|
+
13.2 `busy` over a `Selection` MUST answer whether ANY entry in it is busy.
|
|
622
|
+
|
|
623
|
+
13.3 An implementation MUST hold one signal per `Selection`, and MUST NOT hold one per entry.
|
|
624
|
+
|
|
625
|
+
13.4 `s.refresh`, `s.invalidate`, `k.refresh`, `k.invalidate`, `rpc.refresh` and `rpc.invalidate`
|
|
626
|
+
MUST be defined as `refresh` and `invalidate` over a `Selection`, and MUST NOT be a second
|
|
627
|
+
mechanism.
|
|
628
|
+
|
|
629
|
+
13.5 An implementation MUST NOT provide a free `done`, `success` or `error` over a `Selection`.
|
|
630
|
+
|
|
631
|
+
13.6 A bare `invalidate`, `refresh`, `busy` or `ready` MUST match only entries whose producer is a
|
|
632
|
+
load: a `store`, or a body that has handed back a pending answer or a stream.
|
|
633
|
+
|
|
634
|
+
13.7 A bare `refresh`, and `refresh` over a `Selection` that is not one `Reactive`, MUST reload
|
|
635
|
+
only entries something subscribes to and MUST mark the rest.
|
|
636
|
+
|
|
637
|
+
13.8 A `Selection` MUST be scope-bounded, and a tag MUST be scoped the same way.
|
|
638
|
+
|
|
639
|
+
13.9 A `Selection`'s signal MUST be keyed by the canonical form of its `tags`, and a bare
|
|
640
|
+
selection MUST hold exactly one.
|
|
641
|
+
|
|
642
|
+
13.10 On a server a bare `invalidate` and a bare `refresh` MUST each reach every `global` `reactive`
|
|
643
|
+
in the process.
|
|
644
|
+
|
|
645
|
+
13.11 `ready` over a `Selection` MUST answer whether EVERY entry in it is ready.
|
|
646
|
+
|
|
647
|
+
13.12 A pattern given beside a `Keyed` or an `Rpc` MUST narrow it to the entries whose `Args`
|
|
648
|
+
match the pattern.
|
|
649
|
+
|
|
650
|
+
13.13 A `Selection` made in any scope MUST reach every `global` `reactive` it matches, and every
|
|
651
|
+
entry of a `global` `Keyed` it matches.
|
|
652
|
+
|
|
653
|
+
13.14 A bare `refresh` MUST NOT rerun a synchronous derivation, which MUST recompute from the
|
|
654
|
+
load it reads.
|
|
655
|
+
|
|
656
|
+
13.15 On a server, a bare `invalidate` or `refresh`, or one over a set of `tags`, MUST also send the
|
|
657
|
+
same trigger to every copy a browser follows over the mux that the selection matches by the `tags`
|
|
658
|
+
its build copied, whether or not the server holds a value it matches, and MUST NOT send it to a copy
|
|
659
|
+
fed from a value the server holds.
|
|
660
|
+
|
|
661
|
+
13.16 A bare `refresh`, and `refresh` over a set of `tags`, MUST invalidate, and MUST NOT reload,
|
|
662
|
+
every value a mutation's `declare` built.
|
|
663
|
+
|
|
664
|
+
13.17 A bare `invalidate` or `refresh`, or one over a set of `tags`, MUST NOT invalidate a value a
|
|
665
|
+
mutation's `declare` built while its write is in flight.
|
|
666
|
+
|
|
667
|
+
# 14. Tracking
|
|
668
|
+
|
|
669
|
+
14.1 A `Reactive` MUST be tracked only where something downstream will be rebuilt from it.
|
|
670
|
+
|
|
671
|
+
14.2 A template expression MUST track the `Reactive` values it reads.
|
|
672
|
+
|
|
673
|
+
14.3 An unkeyed `reactive` body MUST track.
|
|
674
|
+
|
|
675
|
+
14.4 A keyed `reactive` body MUST NOT track.
|
|
676
|
+
|
|
677
|
+
14.5 A block body's binding MUST track, and MUST bind the value the block produced rather than a
|
|
678
|
+
`Reactive`.
|
|
679
|
+
|
|
680
|
+
14.6 A `watch` `Effect` MUST track, narrowed where 12.3 gives it sources.
|
|
681
|
+
|
|
682
|
+
14.7 A component `<script>` setup body MUST NOT track.
|
|
683
|
+
|
|
684
|
+
14.8 A branch-local `<script>` in a block body MUST NOT track.
|
|
685
|
+
|
|
686
|
+
14.9 An event handler and a `bind:` write-back MUST NOT track.
|
|
687
|
+
|
|
688
|
+
14.10 A `Transformer`, a `Disposer`, middleware and a lifecycle hook MUST NOT track.
|
|
689
|
+
|
|
690
|
+
14.11 A `Reactive` MUST push its own subscriber when it evaluates, whoever reached it.
|
|
691
|
+
|
|
692
|
+
14.12 On a server a tracked read of a value still in flight MUST open the sink 3.4 opens.
|
|
693
|
+
|
|
694
|
+
14.13 Tracking MUST be synchronous, and a read in a continuation after an `await` MUST register
|
|
695
|
+
against nothing.
|
|
696
|
+
|
|
697
|
+
14.14 The compiler MUST warn on a reactive read an `await` dominates inside a tracked body, naming
|
|
698
|
+
the read.
|
|
699
|
+
|
|
700
|
+
14.15 The compiler MUST warn on a reactive read in a condition position inside an unkeyed
|
|
701
|
+
`reactive` body, where what the condition decides reads another value, naming the read.
|
|
702
|
+
|
|
703
|
+
14.16 The compiler MUST warn on a reactive read inside a function a tracked body creates and
|
|
704
|
+
does not call synchronously, naming the read.
|
|
705
|
+
|
|
706
|
+
14.17 The compiler MUST warn on a reactive read left of `??` where the type the read yields
|
|
707
|
+
excludes `null` and `undefined`, naming `s.ready`.
|
|
708
|
+
|
|
709
|
+
14.18 The compiler MUST NOT warn under 14.16 on a read inside the `get` or `set` of a component's
|
|
710
|
+
`bind:` pair.
|
|
711
|
+
|
|
712
|
+
# 15. Refusals
|
|
713
|
+
|
|
714
|
+
15.1 A refusal MUST be a declared value, and MUST NOT be a status code or a transport concern.
|
|
715
|
+
|
|
716
|
+
15.2 A refusal MUST fill the `Failures` of the `Reactive` that produced it.
|
|
717
|
+
|
|
718
|
+
15.3 A refusal declared through `refuse.named` MUST default to status 400.
|
|
719
|
+
|
|
720
|
+
15.4 Constructing a `Failed` MUST be inert, and MUST NOT throw.
|
|
721
|
+
|
|
722
|
+
15.5 Returning a `Failed` MUST refuse.
|
|
723
|
+
|
|
724
|
+
15.6 `Failed` MUST be structural.
|
|
725
|
+
|
|
726
|
+
15.7 `notFound` MUST be returned where no route matched.
|
|
727
|
+
|
|
728
|
+
15.8 `validationError` MUST be returned where a `schema` or an `args` gate refuses, or where a call's
|
|
729
|
+
args leave a parameter of its route no spelling as a segment (30.3, 30.19) — in process as over the
|
|
730
|
+
wire, and before the handler runs — at status 422.
|
|
731
|
+
|
|
732
|
+
15.9 An implementation MUST declare no refusal names beyond those `notFound`, `validationError` and
|
|
733
|
+
`aborted` carry and the one 17.4 names.
|
|
734
|
+
|
|
735
|
+
15.10 An expression statement whose type is `Failed` MUST be a compile error naming both repairs.
|
|
736
|
+
|
|
737
|
+
15.11 Where `refuse.named` is given a `schema`, the data MUST be checked at construction.
|
|
738
|
+
|
|
739
|
+
15.12 A `message` given as a function MUST run at construction, on the data.
|
|
740
|
+
|
|
741
|
+
15.13 A `refuse.named` given no `message` MUST take its status's reason phrase (17.8), or its name
|
|
742
|
+
for a status with none. A throw from a `message` function MUST be caught, the `message` falling
|
|
743
|
+
back the same way, and MUST warn on `abide:refuse`.
|
|
744
|
+
|
|
745
|
+
15.14 The `schema` MUST run before the `message` function.
|
|
746
|
+
|
|
747
|
+
15.15 A `schema` refusal at construction MUST warn on `abide:refuse` rather than stop the `Failed`
|
|
748
|
+
being built.
|
|
749
|
+
|
|
750
|
+
15.16 An address that will not percent-decode MUST be answered `refuse(400)`.
|
|
751
|
+
|
|
752
|
+
15.17 A route, a file under a `public` directory and the built bundle MUST answer a method nothing at
|
|
753
|
+
that address answers with a refusal at status 405 carrying an `allow` naming the methods answered
|
|
754
|
+
there.
|
|
755
|
+
|
|
756
|
+
15.18 A refusal declared through `refuse.named` MUST carry data only where it is given a `schema`,
|
|
757
|
+
and its data's type MUST be inferred from that `schema`; a `message` function MUST be accepted only
|
|
758
|
+
beside one.
|
|
759
|
+
|
|
760
|
+
15.19 A `Keyed` entry or an `Rpc` whose last answer was a refusal at status 500 or above, or a throw,
|
|
761
|
+
MUST run its body again for the next reach rather than serve that answer.
|
|
762
|
+
|
|
763
|
+
15.20 A refusal below status 500 MUST be held for the next reach as a production is, until its
|
|
764
|
+
`ttl` ends.
|
|
765
|
+
|
|
766
|
+
15.21 A refusal MUST cross a wire as Problem Details (RFC 9457) under `application/problem+json`: its
|
|
767
|
+
name as `type`, or `about:blank` titled by its status's reason phrase where it was not declared, its
|
|
768
|
+
message as `detail`, and its data as a `data` member.
|
|
769
|
+
|
|
770
|
+
15.22 The `notFound` 15.7 returns, and the 405 15.17 answers at a route, MUST be painted as a page's
|
|
771
|
+
failure where the request prefers `text/html` over `application/json`, and MUST cross as 15.21
|
|
772
|
+
states otherwise.
|
|
773
|
+
|
|
774
|
+
# 16. Handlers and transports
|
|
775
|
+
|
|
776
|
+
16.1 A handler MUST be a `reactive`, a plain function, or a value.
|
|
777
|
+
|
|
778
|
+
16.2 `GET`, `POST`, `PUT`, `PATCH` and `DELETE` MUST give a handler an address over http: the route of
|
|
779
|
+
the file whose `<script server>` exports it, per 23.14, and then one segment named as the export.
|
|
780
|
+
|
|
781
|
+
16.3 An `Rpc` MUST hand back the same `Reactive` shape the handler had, `Produced` included.
|
|
782
|
+
|
|
783
|
+
16.4 An `Rpc` MUST be callable in both arms, the call being what issues the request.
|
|
784
|
+
|
|
785
|
+
16.5 Which arm `GET` takes MUST be read off a brand the factory stamped, and MUST NOT be inferred
|
|
786
|
+
from the shape.
|
|
787
|
+
|
|
788
|
+
16.6 `GET` over a plain function or a value MUST behave as `GET` over a `reactive` of it, built with
|
|
789
|
+
the options `GET` was handed; a `reactive` or a `Keyed` handed in MUST take the address's options
|
|
790
|
+
alone.
|
|
791
|
+
|
|
792
|
+
16.7 A mutation over a plain function or a value MUST have its value's `ttl` default to 0 unless its
|
|
793
|
+
options declare one.
|
|
794
|
+
|
|
795
|
+
16.8 `Failures` on an `Rpc` MUST be the union of what the handler declared, what its rungs
|
|
796
|
+
declared, and the undeclared `Failed` named `HttpError` per 17.4, with no data, which the transport
|
|
797
|
+
may answer any call with.
|
|
798
|
+
|
|
799
|
+
16.9 `rpc.url` MUST take the `Args`, MUST write each parameter of its route into the path, and MUST
|
|
800
|
+
carry the rest in the query on a `GET` or a `DELETE` alone.
|
|
801
|
+
|
|
802
|
+
16.10 `rpc.url` MUST resolve a mount-relative address at run time, and the build MUST NOT bake an
|
|
803
|
+
absolute one.
|
|
804
|
+
|
|
805
|
+
16.11 A `Middleware` rung MUST run on every call, in process as much as over the wire.
|
|
806
|
+
|
|
807
|
+
16.12 The rungs in registration order, the `ctx.args()` coerce-then-validate, and `timeout` MUST run
|
|
808
|
+
on every call.
|
|
809
|
+
|
|
810
|
+
16.13 The `Origin` gate on a mutation, `maxBodySize`, the `crossOrigin` preflight, the framing, the
|
|
811
|
+
`cache-control`, a status written through `response` and the seed buffer write MUST be wire-only.
|
|
812
|
+
|
|
813
|
+
16.14 `Middleware` rungs MUST be composed once at route-table construction, and MUST NOT be folded per call.
|
|
814
|
+
|
|
815
|
+
16.15 A composed `Middleware` chain MUST capture the rung and the next link, and MUST NOT capture anything
|
|
816
|
+
per-request.
|
|
817
|
+
|
|
818
|
+
16.16 A `Middleware` rung MUST short-circuit by returning what the handler would have returned.
|
|
819
|
+
|
|
820
|
+
16.17 `ctx.args()` MUST parse on first call and cache for the request.
|
|
821
|
+
|
|
822
|
+
16.18 `ctx.args()` MUST hand back `Args` coerced and validated against the `args` the value
|
|
823
|
+
declared.
|
|
824
|
+
|
|
825
|
+
16.19 Validation MUST be lazy, on that first `ctx.args()` call.
|
|
826
|
+
|
|
827
|
+
16.20 A body that will not parse as `Args` MUST be answered 400.
|
|
828
|
+
|
|
829
|
+
16.21 A throw from a `Middleware` rung MUST escape the whole onion rather than unwind through it.
|
|
830
|
+
|
|
831
|
+
16.22 `timeout` MUST raise the request's idle timeout, and MUST only raise it.
|
|
832
|
+
|
|
833
|
+
16.23 A request's `timeout` floor MUST be the maximum over every handler that ran in it.
|
|
834
|
+
|
|
835
|
+
16.24 `crossOrigin` MUST default to false, and where it is declared abide MUST answer the `OPTIONS`
|
|
836
|
+
preflight itself. An `OPTIONS` naming no `access-control-request-method` is no preflight, and MUST be
|
|
837
|
+
answered per 15.17.
|
|
838
|
+
|
|
839
|
+
16.25 A handler MUST be request-bound where its rungs or its body read the request scope, and
|
|
840
|
+
calling one from a scope that has none MUST be a build error, per 11.37.
|
|
841
|
+
|
|
842
|
+
16.26 Shape MUST belong to the `Reactive` and MUST NOT be declared at the transport; a transport MUST
|
|
843
|
+
read it.
|
|
844
|
+
|
|
845
|
+
16.27 A `schema` MUST run where its `Reactive` lives.
|
|
846
|
+
|
|
847
|
+
16.28 A browser MUST receive a generated `Rpc` wrapper carrying the method, the mount-relative address and
|
|
848
|
+
the description, and MUST NOT receive the `<script server>` that declared it.
|
|
849
|
+
|
|
850
|
+
16.29 Importing a module under a `server` directory from the client graph MUST be a compile error,
|
|
851
|
+
and MUST NOT be a silent stub.
|
|
852
|
+
|
|
853
|
+
16.30 An `Rpc` returning a raw `Value` MUST transport as `application/json`.
|
|
854
|
+
|
|
855
|
+
16.31 An `Rpc` returning `undefined` MUST answer 204 where no status was written through
|
|
856
|
+
`response`.
|
|
857
|
+
|
|
858
|
+
16.32 An `Rpc` returning an async generator MUST stream in the framing `Accept` names, and MUST
|
|
859
|
+
default to the first framing its chunk type admits.
|
|
860
|
+
|
|
861
|
+
16.33 The seed buffer MUST hold an `Rpc`'s transcript in the chunk type's default framing,
|
|
862
|
+
whichever framing the caller asked for.
|
|
863
|
+
|
|
864
|
+
16.34 An `Rpc` returning a binary MUST transport as `application/octet-stream`, or as a `Blob`'s own
|
|
865
|
+
type where it has one.
|
|
866
|
+
|
|
867
|
+
16.35 A returned `Blob` MUST be range-aware: abide MUST read `Range`, honor `If-Range` against the
|
|
868
|
+
ETag it derives, and answer 206, 416 and 304 as the protocol requires.
|
|
869
|
+
|
|
870
|
+
16.36 A handler MAY return a `Response`, and an in-process caller MUST receive it unconverted.
|
|
871
|
+
|
|
872
|
+
16.37 Where a handler returns a `Response`, `clients.mcp` and `clients.cli` MUST default to false.
|
|
873
|
+
|
|
874
|
+
16.38 A mutation MUST answer a request preferring `text/html` as a navigation: a returned
|
|
875
|
+
`redirect` passes through, a returned value becomes 303 back to the referrer, and a failure renders
|
|
876
|
+
`error.abide` at its own status.
|
|
877
|
+
|
|
878
|
+
16.39 A handler whose value carries a `Reactive` below its top level MUST be a compile error naming
|
|
879
|
+
the handler and the path to it.
|
|
880
|
+
|
|
881
|
+
16.40 A `Failed` escaping a handler MUST be answered at its own `status`.
|
|
882
|
+
|
|
883
|
+
16.41 A throw that is not a `Failed` MUST be answered 500.
|
|
884
|
+
|
|
885
|
+
16.42 `rpc.raw` MUST issue the call the `Rpc` issues, differing only in handing back the
|
|
886
|
+
`Response`. On a server it MUST be answered in process by the `App` answering the request it is made
|
|
887
|
+
in, and by the `App` built last only outside every request, until that `App` stops, after which
|
|
888
|
+
such a call MUST NOT reach it.
|
|
889
|
+
|
|
890
|
+
16.43 An `Rpc` call MUST evaluate its `Args` at the call, and MUST NOT re-evaluate them.
|
|
891
|
+
|
|
892
|
+
16.44 A jsonl answer MUST write one JSON value per line, per pull, typed `application/x-ndjson` where
|
|
893
|
+
the reader asks for that type and `application/jsonl` otherwise.
|
|
894
|
+
|
|
895
|
+
16.45 An sse answer MUST frame each value as `data: <json>` followed by a blank line, with
|
|
896
|
+
`text/event-stream`, `no-cache` and `X-Accel-Buffering: no`.
|
|
897
|
+
|
|
898
|
+
16.46 A stream of value chunks MUST admit jsonl and then sse, and a stream of binary chunks MUST
|
|
899
|
+
admit `application/octet-stream` alone.
|
|
900
|
+
|
|
901
|
+
16.47 Where no handler fixed the framing, the chunk type MUST be read from the first chunk
|
|
902
|
+
produced.
|
|
903
|
+
|
|
904
|
+
16.48 A call's `signal` MUST end the load the call reached only where every call that reached that
|
|
905
|
+
load passed a `signal`, and every one of those has aborted.
|
|
906
|
+
|
|
907
|
+
16.49 A load ended under 16.48 MUST keep serving what its value held, MUST report `s.busy` false,
|
|
908
|
+
MUST refuse with `aborted` at status 499, and MUST abort the request carrying it where one does.
|
|
909
|
+
|
|
910
|
+
16.50 A `HEAD` MUST be answered by the `GET` handler mounted at its address.
|
|
911
|
+
|
|
912
|
+
16.51 A `HEAD` MUST NOT take from the seed buffer.
|
|
913
|
+
|
|
914
|
+
16.52 An `Rpc` answer with no body — a 204, or a status `response` writes with nothing returned, a
|
|
915
|
+
`redirect` included — MUST NOT carry `content-type`.
|
|
916
|
+
|
|
917
|
+
16.53 The 303 16.38 answers MUST go to the mount's root where the referrer is absent or is not of
|
|
918
|
+
`APP_URL`'s origin, per 36.2.
|
|
919
|
+
|
|
920
|
+
16.54 `maxBodySize` and `ABIDE_MAX_REQUEST_BODY_SIZE` MUST default to no ceiling.
|
|
921
|
+
|
|
922
|
+
16.55 A mutation's body over the ceiling `maxBodySize` or `ABIDE_MAX_REQUEST_BODY_SIZE` sets MUST
|
|
923
|
+
be refused 413, whether its length was declared or streamed.
|
|
924
|
+
|
|
925
|
+
16.56 Where neither `timeout` nor `ABIDE_RPC_TIMEOUT` is set, a call MUST NOT raise the request's
|
|
926
|
+
idle timeout.
|
|
927
|
+
|
|
928
|
+
16.57 A `timeout` of `Infinity` MUST leave the request's idle timeout off.
|
|
929
|
+
|
|
930
|
+
16.58 Where a handler names no `timeout`, `ABIDE_RPC_TIMEOUT` MUST be its `timeout`.
|
|
931
|
+
|
|
932
|
+
16.59 A load that goes `timeout` milliseconds without settling, or without a stream's next chunk,
|
|
933
|
+
MUST be ended and MUST refuse with `refuse(504)`.
|
|
934
|
+
|
|
935
|
+
16.60 A load ended under 16.59 MUST keep serving what its value held, a stream's chunks so far
|
|
936
|
+
included, and MUST report `s.busy` false.
|
|
937
|
+
|
|
938
|
+
16.61 A call joining a load MUST NOT extend that load's `timeout`.
|
|
939
|
+
|
|
940
|
+
16.62 A call reaching a value whose last load ended under 16.48 MUST start a new load, under the `signal`
|
|
941
|
+
that call passed.
|
|
942
|
+
|
|
943
|
+
16.63 A throw answered once its request's signal has aborted — a handler's or a page render's — MUST
|
|
944
|
+
answer `aborted` at 499, and MUST NOT report the throw as unexpected.
|
|
945
|
+
|
|
946
|
+
16.64 An `Rpc` over a plain function MUST NOT run that function before the first call reaches it.
|
|
947
|
+
|
|
948
|
+
16.65 Each parameter of the route a handler's file answers at MUST reach the handler's `Args` from the
|
|
949
|
+
path.
|
|
950
|
+
|
|
951
|
+
16.66 A request naming a parameter of its route in its query or its body as well as its path MUST be
|
|
952
|
+
answered `refuse(400)`.
|
|
953
|
+
|
|
954
|
+
16.67 A handler whose `Args` does not declare each parameter of its route MUST be a build error
|
|
955
|
+
naming the handler and the parameter.
|
|
956
|
+
|
|
957
|
+
16.68 A refusal reaching a jsonl or an sse answer after its status was sent MUST be sent as its last
|
|
958
|
+
frame — a line `{"$refusal": <Problem Details>}`, or an `event: refusal` whose data is the Problem
|
|
959
|
+
Details — and a reader MUST refuse with it after the chunks before it.
|
|
960
|
+
|
|
961
|
+
16.69 A `[...rest]` segment MUST take the most parts of an address the segments after it leave, so
|
|
962
|
+
a handler declared under one MUST answer at its own name.
|
|
963
|
+
|
|
964
|
+
# 17. Response helpers
|
|
965
|
+
|
|
966
|
+
17.1 Every body helper MUST take `Values<T>`.
|
|
967
|
+
|
|
968
|
+
17.2 `page` MUST be defined as a write through `response` naming `text/html`, and MUST take what
|
|
969
|
+
a render produced rather than perform the render.
|
|
970
|
+
|
|
971
|
+
17.3 `redirect` MUST be defined as a write through `response` carrying a `RedirectStatus`,
|
|
972
|
+
defaulting to 302.
|
|
973
|
+
|
|
974
|
+
17.4 `refuse` on a server MUST hand back, per 15.5, the undeclared `Failed` named `HttpError` at
|
|
975
|
+
the given status.
|
|
976
|
+
|
|
977
|
+
17.5 `refuse` MUST carry no data, and MUST NOT take an options bag for any.
|
|
978
|
+
|
|
979
|
+
17.6 `jsonl`, `sse` and `bytes` MUST each be defined as a write through `response` fixing the
|
|
980
|
+
framing of a streaming answer.
|
|
981
|
+
|
|
982
|
+
17.7 An implementation MUST NOT negotiate past a framing a handler fixed.
|
|
983
|
+
|
|
984
|
+
17.8 An answer at a failure status (400-599) MUST carry that status's registered reason phrase as
|
|
985
|
+
its `statusText` when nothing wrote one, and `refuse` given no `message` MUST take the same phrase,
|
|
986
|
+
falling back to `HttpError` for a status with none.
|
|
987
|
+
|
|
988
|
+
17.9 `json` MUST be defined as a write through `response` fixing the answer as `application/json`,
|
|
989
|
+
serialized as a bare return is.
|
|
990
|
+
|
|
991
|
+
17.10 `json` given `undefined` MUST answer `null` at the status written through `response`, and MUST
|
|
992
|
+
NOT answer 204.
|
|
993
|
+
|
|
994
|
+
# 18. Following a `GET`
|
|
995
|
+
|
|
996
|
+
18.1 Every `GET` a page follows MUST be carried over a single web socket mux.
|
|
997
|
+
|
|
998
|
+
18.2 A subscription over the mux from another origin MUST be refused unless the handler's
|
|
999
|
+
`crossOrigin` admits that origin.
|
|
1000
|
+
|
|
1001
|
+
18.3 A client reading a `GET` MUST be subscribed over the socket mux to that handler's productions
|
|
1002
|
+
for those `Args`.
|
|
1003
|
+
|
|
1004
|
+
18.4 A subscriber's copy of a wired `Reactive` MUST carry what that `Reactive` declares of `by` as a
|
|
1005
|
+
property name, `tags` as a list of names, and `identity` as `structural`.
|
|
1006
|
+
|
|
1007
|
+
18.5 A `GET` answered from a `global` value MUST carry the version of the production it answered
|
|
1008
|
+
with as its `etag`.
|
|
1009
|
+
|
|
1010
|
+
18.6 A subscription to a `GET` MUST be sent the value standing where the version it names is not
|
|
1011
|
+
that value's version, and MUST NOT be sent it where it is.
|
|
1012
|
+
|
|
1013
|
+
18.7 A version MUST name one production or one `s.patch` of one value, and no other production or
|
|
1014
|
+
patch in this process or in any earlier one.
|
|
1015
|
+
|
|
1016
|
+
18.8 A subscription to a `GET` that declares `middleware` MUST run that `middleware` once as it opens,
|
|
1017
|
+
in the request it opens in, and MUST be sent productions only where the `middleware` admitted it.
|
|
1018
|
+
|
|
1019
|
+
18.9 A client subscribing to a `GET` MUST name the version the answer it holds carried.
|
|
1020
|
+
|
|
1021
|
+
18.10 A subscriber's copy of a `GET` MUST take every value sent to it.
|
|
1022
|
+
|
|
1023
|
+
18.11 An `s.patch` of a value a `GET` serves MUST be sent to a subscription standing at the version it
|
|
1024
|
+
was made over as what it wrote, as JSON Patch (RFC 6902), and MUST NOT be sent as the value.
|
|
1025
|
+
|
|
1026
|
+
18.12 A subscriber's copy of a `GET` sent what a patch wrote over a version it does not hold MUST read
|
|
1027
|
+
the value again.
|
|
1028
|
+
|
|
1029
|
+
18.13 An `s.patch` whose writes cannot be sent as data MUST be sent as the value.
|
|
1030
|
+
|
|
1031
|
+
18.14 A subscriber's copy of a `GET` MUST go stale when the `max-age` its answer carried runs out.
|
|
1032
|
+
|
|
1033
|
+
18.15 The build MUST warn where a `GET`'s `Reactive` declares `by` or `tags` by a value that is not a
|
|
1034
|
+
function and whose type is not the one 18.4 carries.
|
|
1035
|
+
|
|
1036
|
+
18.16 Every frame on one connection to the socket mux MUST be answered in one request scope, whose
|
|
1037
|
+
`request` is the upgrade's.
|
|
1038
|
+
|
|
1039
|
+
18.17 A connection's request scope MUST be torn down when the connection closes.
|
|
1040
|
+
|
|
1041
|
+
18.18 The signal of a connection's `request` MUST abort when the connection closes.
|
|
1042
|
+
|
|
1043
|
+
18.19 A `GET` 18.5 versions MUST answer `304 Not Modified`, with no body, where its `If-None-Match`
|
|
1044
|
+
names the version standing.
|
|
1045
|
+
|
|
1046
|
+
18.20 A `GET` 18.5 versions MUST answer a reader preferring `text/event-stream` with a follow of the
|
|
1047
|
+
value as server-sent events: each frame 18.6 through 18.13 would send it, its op as the `event`, its
|
|
1048
|
+
version as the `id` and its value or JSON Patch as the `data`, from the version `Last-Event-ID`
|
|
1049
|
+
names.
|
|
1050
|
+
|
|
1051
|
+
18.21 A subscriber's copy of a `GET` written to since it last took what the server sent MUST read the
|
|
1052
|
+
value again rather than apply what a patch wrote, as 18.12 has it for a version it does not hold.
|
|
1053
|
+
|
|
1054
|
+
18.22 A `GET` answered with a production its `global` value no longer stands at MUST carry no version.
|
|
1055
|
+
|
|
1056
|
+
18.23 A `GET` answered with a binary MUST carry no version.
|
|
1057
|
+
|
|
1058
|
+
18.24 A client MUST NOT subscribe to a `GET` whose answer was a binary or a refusal.
|
|
1059
|
+
|
|
1060
|
+
18.25 A browser's connection to the socket mux MUST be opened again, in every tab, on the
|
|
1061
|
+
`abide-principal` header 26.24 has an answer carry.
|
|
1062
|
+
|
|
1063
|
+
18.26 A subscription to a `GET` MUST pass the `middleware` 37.2 runs at the route of the file that
|
|
1064
|
+
declared it, as it opens, and MUST NOT be fed where a rung answered in the handler's place.
|
|
1065
|
+
|
|
1066
|
+
# 19. Mount paths and schemas
|
|
1067
|
+
|
|
1068
|
+
19.1 A route MUST be answered for each method by one file at most, a page answering `GET` and `HEAD`
|
|
1069
|
+
at its own, and a second MUST be a build error naming both files, two routes differing only in
|
|
1070
|
+
their parameters' names being one route.
|
|
1071
|
+
|
|
1072
|
+
19.2 A `Schema` MUST return what it accepts.
|
|
1073
|
+
|
|
1074
|
+
19.3 An implementation MUST NOT accept a predicate as a `Schema`.
|
|
1075
|
+
|
|
1076
|
+
19.4 The plain-function `Schema` form MUST throw what it refuses, and that throw MUST be caught where
|
|
1077
|
+
the schema runs and become the `''` entry of `Issues<T>`, or the whole of it per 19.20.
|
|
1078
|
+
|
|
1079
|
+
19.5 `Paths<T>` MUST be dot-joined, MUST be depth-limited, and MUST widen to `string` past the limit.
|
|
1080
|
+
|
|
1081
|
+
19.6 Coercion MUST belong to the pipeline, and MUST NOT be asked of a `Schema`.
|
|
1082
|
+
|
|
1083
|
+
19.7 A `GET` or `DELETE`'s text args MUST be coerced from the type the `JsonSchema` declares, before
|
|
1084
|
+
validation.
|
|
1085
|
+
|
|
1086
|
+
19.8 Coercion MUST happen at the `ctx.args()` that first asks, and every rung after it MUST see the
|
|
1087
|
+
coerced value.
|
|
1088
|
+
|
|
1089
|
+
19.9 Where no `schema` is given it MUST be derived from the type annotation and the argument
|
|
1090
|
+
defaults.
|
|
1091
|
+
|
|
1092
|
+
19.10 A default MUST make a member optional, and a defaulted parameter MUST make `Args` itself
|
|
1093
|
+
optional.
|
|
1094
|
+
|
|
1095
|
+
19.11 Where inference fails the compiler MUST read rather than refuse the file, and the derived
|
|
1096
|
+
`Schema` MUST widen.
|
|
1097
|
+
|
|
1098
|
+
19.12 A `Schema` that answers asynchronously MUST be refused.
|
|
1099
|
+
|
|
1100
|
+
19.13 A page that does not call `jsonSchema` MUST NOT carry `validateJson`.
|
|
1101
|
+
|
|
1102
|
+
19.14 A `JsonSchema` given as a `Schema` without `jsonSchema` MUST be refused, naming
|
|
1103
|
+
`jsonSchema`.
|
|
1104
|
+
|
|
1105
|
+
19.15 Every value a `<script server>` exports MUST be declared by a call of abide's
|
|
1106
|
+
`GET`, `POST`, `PUT`, `PATCH` or `DELETE` — however the language spells the export, the call or its
|
|
1107
|
+
import — and an export that is not MUST be a build error naming it.
|
|
1108
|
+
|
|
1109
|
+
19.16 A default in a keyed body's parameter or a handler's parameter that is not a literal MUST
|
|
1110
|
+
be refused at construction, naming its `Args` member, and the build MUST refuse one on a handler.
|
|
1111
|
+
|
|
1112
|
+
19.17 `route.url` MUST hold the address a page is served at, the path `APP_URL` names included, on
|
|
1113
|
+
the server as in the browser.
|
|
1114
|
+
|
|
1115
|
+
19.18 A request for the path `APP_URL` names, without its trailing `/`, MUST be redirected 308 to
|
|
1116
|
+
that path with one, by path alone.
|
|
1117
|
+
|
|
1118
|
+
19.19 A `Schema` derived per 19.9 MUST refuse a member its type does not declare, wherever the type
|
|
1119
|
+
carries no index signature.
|
|
1120
|
+
|
|
1121
|
+
19.20 An `Issues<T>` over a value that is not an object MUST be the bare list of messages, not a
|
|
1122
|
+
record keyed by `''`.
|
|
1123
|
+
|
|
1124
|
+
19.21 A request MUST be answered by the most specific route answering its method, ranked as 30.9
|
|
1125
|
+
ranks routes for `navigate`.
|
|
1126
|
+
|
|
1127
|
+
19.22 A `<script server>` that re-exports with `export * from` MUST be a build error naming its file.
|
|
1128
|
+
|
|
1129
|
+
# 20. Generated surfaces
|
|
1130
|
+
|
|
1131
|
+
20.1 Every surface `Clients` names MUST be derived from the route table, and MUST NOT be authored
|
|
1132
|
+
beside it.
|
|
1133
|
+
|
|
1134
|
+
20.2 Every key of `Clients` MUST default to true, but where 16.37 defaults it to false.
|
|
1135
|
+
|
|
1136
|
+
20.3 `Clients` MUST decide what is generated and listed, and MUST NOT decide who may call.
|
|
1137
|
+
|
|
1138
|
+
20.4 `ui: false` MUST generate no client wrapper, and importing that handler from the client graph
|
|
1139
|
+
MUST then be a compile error naming it.
|
|
1140
|
+
|
|
1141
|
+
20.5 `/__abide/openapi.json` and `/__abide/mcp` MUST be served from a `reactive` over the route table,
|
|
1142
|
+
and MUST take no `ttl`.
|
|
1143
|
+
|
|
1144
|
+
20.6 `/__abide/openapi.json` MUST publish OpenAPI 3.1, and MUST publish a handler's `JsonSchema`
|
|
1145
|
+
with no translation. It MUST declare every path parameter, with or without a schema, an optional or
|
|
1146
|
+
rest one as present and required as OpenAPI requires.
|
|
1147
|
+
|
|
1148
|
+
20.7 `/__abide/openapi.json` and `/__abide/mcp` MUST each be open exactly where the route table
|
|
1149
|
+
lists a handler for it. What a closed one answers is 36.7.
|
|
1150
|
+
|
|
1151
|
+
20.8 Every `/__abide/**` address MUST run inside the app's own middleware.
|
|
1152
|
+
|
|
1153
|
+
20.9 `/__abide/mcp` MUST publish a handler that reads as a tool and a resource according to which
|
|
1154
|
+
arm `GET` took, and MUST NOT require a flag to tell them apart.
|
|
1155
|
+
|
|
1156
|
+
20.10 A handler whose own `Middleware` rung would refuse a caller MUST still be listed, and MUST
|
|
1157
|
+
still be refused on the call.
|
|
1158
|
+
|
|
1159
|
+
20.11 `/__abide/openapi.json` MUST publish a `Schema`'s own JSON Schema where it has one, probing
|
|
1160
|
+
one spelling for it, and MUST publish the type-derived `JsonSchema` where it has none.
|
|
1161
|
+
|
|
1162
|
+
20.12 `/__abide/mcp` MUST refuse 403 a request whose `Origin` is another origin's, before it reads
|
|
1163
|
+
the body.
|
|
1164
|
+
|
|
1165
|
+
20.13 A handler's name on `/__abide/mcp` and `/__abide/openapi.json` MUST be its method in lower case
|
|
1166
|
+
and then its route, each joined by `_`, with every character but a letter, a digit and `-` written
|
|
1167
|
+
`_` and a segment's brackets and dots dropped, and two handlers sharing one MUST be a build error
|
|
1168
|
+
naming both.
|
|
1169
|
+
|
|
1170
|
+
# 21. Generated headers
|
|
1171
|
+
|
|
1172
|
+
21.1 Every response MUST carry `x-content-type-options: nosniff`.
|
|
1173
|
+
|
|
1174
|
+
21.2 Every response MUST carry `traceresponse`, a refusal included.
|
|
1175
|
+
|
|
1176
|
+
21.3 A page, an rpc answer and a refusal MUST default to `cache-control: private, no-store`.
|
|
1177
|
+
|
|
1178
|
+
21.4 `/__abide/openapi.json` and `/__abide/mcp` MUST answer `cache-control: no-store`. `/__abide/health`
|
|
1179
|
+
and `/__abide/principal` are answered as handlers (25.3) and carry 21.3's `private, no-store`.
|
|
1180
|
+
|
|
1181
|
+
21.5 The built bundle MUST answer `cache-control: public, max-age=31536000, immutable`.
|
|
1182
|
+
|
|
1183
|
+
21.6 A page MUST carry `referrer-policy: strict-origin-when-cross-origin`.
|
|
1184
|
+
|
|
1185
|
+
21.7 An answer that depends on a request header MUST carry `vary` naming it.
|
|
1186
|
+
|
|
1187
|
+
21.8 A `GET` over a `global` `reactive` MUST answer a `max-age` derived from that value's `ttl`, and an
|
|
1188
|
+
app MUST NOT be required to state the duration a second time.
|
|
1189
|
+
|
|
1190
|
+
21.9 A `GET` over a `global` `reactive` MUST answer `private`.
|
|
1191
|
+
|
|
1192
|
+
21.10 A write through `response` MUST override every header and the status the answer carries.
|
|
1193
|
+
|
|
1194
|
+
21.11 The `max-age` 21.8 derives MUST replace 21.3's `no-store`, and 21.3 MUST decide the rest
|
|
1195
|
+
of that header.
|
|
1196
|
+
|
|
1197
|
+
21.12 A file under a `public` directory MUST answer `cache-control: public, max-age=0, must-revalidate`.
|
|
1198
|
+
|
|
1199
|
+
21.13 A file under a `public` directory MUST answer an `etag` derived from its bytes.
|
|
1200
|
+
|
|
1201
|
+
21.14 A request whose `if-none-match` is `*`, or lists the `etag` 21.13 derives under weak
|
|
1202
|
+
comparison, MUST be answered 304.
|
|
1203
|
+
|
|
1204
|
+
21.15 An `Rpc` answer MUST carry `server-timing` with its handler's duration under a metric naming
|
|
1205
|
+
the run: `Seeded` where the `render`'s run answered it, `Cached` where a `global` production already
|
|
1206
|
+
held answered it, `Started` where it is a stream timed to its first chunk, and `Direct` otherwise.
|
|
1207
|
+
|
|
1208
|
+
21.16 The `max-age` 21.8 derives MUST be what is left of the answered production's `ttl`.
|
|
1209
|
+
|
|
1210
|
+
21.17 A `GET` over a `global` `reactive` whose `ttl` is `Infinity` MUST keep 21.3's `no-store`.
|
|
1211
|
+
|
|
1212
|
+
21.18 A page MUST default to `content-security-policy: frame-ancestors 'none'`.
|
|
1213
|
+
|
|
1214
|
+
21.19 `access-control-allow-origin` MUST name only an origin the handler's `crossOrigin` admits.
|
|
1215
|
+
|
|
1216
|
+
21.20 An answer whose request ran `middleware` rungs MUST carry `server-timing` `Middleware` with the
|
|
1217
|
+
time those rungs took apart from what they wrapped.
|
|
1218
|
+
|
|
1219
|
+
21.21 The `Direct` duration 21.15 carries MUST NOT include the time 21.20 counts.
|
|
1220
|
+
|
|
1221
|
+
# 22. Request-scoped ambients
|
|
1222
|
+
|
|
1223
|
+
22.1 `request`, `response` and `server` MUST throw outside a request.
|
|
1224
|
+
|
|
1225
|
+
22.2 `cookies` MUST be isomorphic, and on a server writes MUST be collected onto the response.
|
|
1226
|
+
|
|
1227
|
+
22.3 A cookie's `secure` MUST default from `NODE_ENV`.
|
|
1228
|
+
|
|
1229
|
+
22.4 A read of a cookie by name MUST track that name.
|
|
1230
|
+
|
|
1231
|
+
22.5 A write through `cookies` MUST wake the readers of that name alone.
|
|
1232
|
+
|
|
1233
|
+
22.6 Where the browser reports cookie changes, a change made outside `cookies` MUST wake the readers
|
|
1234
|
+
of that name.
|
|
1235
|
+
|
|
1236
|
+
22.7 Where the browser does not report them, a change made outside `cookies` MUST wake nothing.
|
|
1237
|
+
|
|
1238
|
+
22.8 `cookies` MUST throw outside a request on a server.
|
|
1239
|
+
|
|
1240
|
+
22.9 A write through `response` MUST be collected onto the response being built for the request
|
|
1241
|
+
being served.
|
|
1242
|
+
|
|
1243
|
+
22.10 A write through `cookies` or `response` MUST throw once the response headers are out, and on
|
|
1244
|
+
a connection to the socket mux, whose headers went out with the upgrade. A caller minted there MUST
|
|
1245
|
+
be that scope's alone.
|
|
1246
|
+
|
|
1247
|
+
# 23. Route and connectivity
|
|
1248
|
+
|
|
1249
|
+
23.1 Each member of `route` MUST be its own `Reactive`, and `route` MUST NOT be one `Reactive` over a
|
|
1250
|
+
composite.
|
|
1251
|
+
|
|
1252
|
+
23.2 `route.url` MUST be one `URL` instance per navigation, built when the route resolves.
|
|
1253
|
+
|
|
1254
|
+
23.3 A page route MUST be created where a `page.abide` with a template or a head has a route.
|
|
1255
|
+
|
|
1256
|
+
23.4 A page route's file path MUST determine its `route.url`.
|
|
1257
|
+
|
|
1258
|
+
23.5 `Params` MUST carry what `[param]`, `[[optional]]` and `[...rest]` matched.
|
|
1259
|
+
|
|
1260
|
+
23.6 `route.name` MUST be the resolution path.
|
|
1261
|
+
|
|
1262
|
+
23.7 In a browser `online` MUST be `navigator.onLine` and its events.
|
|
1263
|
+
|
|
1264
|
+
23.8 On a server `online` MUST be true.
|
|
1265
|
+
|
|
1266
|
+
23.9 In a page or a layout, `route.params()` MUST be typed by that file's own route: a required
|
|
1267
|
+
segment as text, an optional one as text that may be absent, a rest as a list, and in a layout any
|
|
1268
|
+
segment a page below it adds.
|
|
1269
|
+
|
|
1270
|
+
23.10 `reachable` MUST be true where the host answered a request, whatever the status it answered.
|
|
1271
|
+
|
|
1272
|
+
23.11 `reachable` MUST be false where the host has not answered within 5 seconds.
|
|
1273
|
+
|
|
1274
|
+
23.12 `reachable` MUST hold each host's answer for 60 seconds, as a `global` value's `ttl` holds one.
|
|
1275
|
+
|
|
1276
|
+
23.13 `reachable` MUST ask a host that names no scheme over https, and an origin as written.
|
|
1277
|
+
|
|
1278
|
+
23.14 A route MUST be the path of its file's directory below the app's `--root`.
|
|
1279
|
+
|
|
1280
|
+
23.15 A file under a `server` or `public` directory MUST NOT have a route.
|
|
1281
|
+
|
|
1282
|
+
23.16 A `server` or `public` directory under either of those two MUST be a build error naming
|
|
1283
|
+
both.
|
|
1284
|
+
|
|
1285
|
+
23.17 A route whose first segment is `__abide` MUST be a build error.
|
|
1286
|
+
|
|
1287
|
+
23.18 A `page.abide`, a `layout.abide` or an `error.abide` under a `server` or `public` directory
|
|
1288
|
+
MUST be a build error.
|
|
1289
|
+
|
|
1290
|
+
23.19 An `import '…' with { type: 'routes' }` in an app's `.abide` MUST place every `.abide` under the
|
|
1291
|
+
directory it names at the importing file's directory, routed by its path below the named directory
|
|
1292
|
+
as 23.14 routes the app's own, and a specifier naming no directory MUST be a build error.
|
|
1293
|
+
|
|
1294
|
+
23.20 A directory two `type: 'routes'` imports name, or one that is the app's own, MUST be a build
|
|
1295
|
+
error naming the mount.
|
|
1296
|
+
|
|
1297
|
+
# 24. Tracing
|
|
1298
|
+
|
|
1299
|
+
24.1 `trace` MUST be built on first ask and held for the request.
|
|
1300
|
+
|
|
1301
|
+
24.2 `trace.sampled` MUST carry the caller's sampling decision verbatim.
|
|
1302
|
+
|
|
1303
|
+
24.3 A span MUST be a `LogRecord`, and MUST NOT be a second feed.
|
|
1304
|
+
|
|
1305
|
+
24.4 A span MUST carry `startedAt` as ISO-8601 and its duration as a monotonic measurement.
|
|
1306
|
+
|
|
1307
|
+
24.5 `trace.headers` MUST carry `traceparent` naming the current span as parent.
|
|
1308
|
+
|
|
1309
|
+
24.6 A `trace.span` opened with `timing` MUST be carried in its answer's `server-timing` under its
|
|
1310
|
+
name, where it closed before the head was sent.
|
|
1311
|
+
|
|
1312
|
+
24.7 A `trace.span` opened with `timing` MUST throw where its name is not an HTTP token.
|
|
1313
|
+
|
|
1314
|
+
# 25. Health
|
|
1315
|
+
|
|
1316
|
+
25.1 `GET /__abide/health` MUST answer `Health` over http.
|
|
1317
|
+
|
|
1318
|
+
25.2 An app's own `onHealth` fields MUST win every collision.
|
|
1319
|
+
|
|
1320
|
+
25.3 `health` MUST be seeded per 41.5.
|
|
1321
|
+
|
|
1322
|
+
25.4 `Health` MUST admit a field an app declares on it for what its `onHealth` adds.
|
|
1323
|
+
|
|
1324
|
+
# 26. Principal
|
|
1325
|
+
|
|
1326
|
+
26.1 Each member of `principal` MUST be its own `Reactive`, per 23.1.
|
|
1327
|
+
|
|
1328
|
+
26.2 The identity members of `principal` MUST share one resolve per request.
|
|
1329
|
+
|
|
1330
|
+
26.3 A caller carrying `principal.error` MUST NOT be authenticated.
|
|
1331
|
+
|
|
1332
|
+
26.4 The baseline MUST win every collision in `Principal`.
|
|
1333
|
+
|
|
1334
|
+
26.5 `principal.caller` MUST be read off its own cookie or minted, and MUST need no resolution.
|
|
1335
|
+
|
|
1336
|
+
26.6 `principal.caller` MUST survive a sign-in.
|
|
1337
|
+
|
|
1338
|
+
26.7 `principal.caller` MUST NOT survive a sign-out, and `principal.clear` MUST rotate it.
|
|
1339
|
+
|
|
1340
|
+
26.8 `principal.set` MUST NOT rotate `principal.caller`.
|
|
1341
|
+
|
|
1342
|
+
26.9 `principal.clear` MUST sign the caller out for the rest of this request as well as the next.
|
|
1343
|
+
|
|
1344
|
+
26.10 `Principal` MUST never be null, and an anonymous visitor MUST be `authenticated` false.
|
|
1345
|
+
|
|
1346
|
+
26.11 The `principal` seal MUST be a JWT (RFC 7519) signed HS256 rather than encrypted, its payload
|
|
1347
|
+
the claims' own members beside `exp` and `iat`, and a token naming any other `alg` MUST read as no
|
|
1348
|
+
seal.
|
|
1349
|
+
|
|
1350
|
+
26.12 The principal cookie MUST be set `HttpOnly` and `SameSite=Lax`, and `Secure` in production.
|
|
1351
|
+
|
|
1352
|
+
26.13 A bad signature, a lapsed seal and a malformed cookie MUST be one answer: `principal` reports
|
|
1353
|
+
an anonymous caller.
|
|
1354
|
+
|
|
1355
|
+
26.14 A `principal` MUST be resolved at most once per request.
|
|
1356
|
+
|
|
1357
|
+
26.15 A `principal` seal MUST be refreshed once half spent.
|
|
1358
|
+
|
|
1359
|
+
26.16 An implementation MUST keep no server-side principal store and no revocation list.
|
|
1360
|
+
|
|
1361
|
+
26.17 `principal` MUST be seeded per 41.5.
|
|
1362
|
+
|
|
1363
|
+
26.18 The cookie the `principal` seal is carried in MUST be named `abide-principal`.
|
|
1364
|
+
|
|
1365
|
+
26.19 The cookie `principal.caller` is read from MUST be named `abide-caller`.
|
|
1366
|
+
|
|
1367
|
+
26.20 `principal.set` MUST throw where the sealed cookie would exceed the browser's cookie ceiling,
|
|
1368
|
+
naming the byte count.
|
|
1369
|
+
|
|
1370
|
+
26.21 `principal.set` MUST throw once the response headers are out.
|
|
1371
|
+
|
|
1372
|
+
26.22 `principal.caller` MUST throw in a browser.
|
|
1373
|
+
|
|
1374
|
+
26.23 Where a browser's load of the `principal` document is refused, `principal` MUST report an
|
|
1375
|
+
unauthenticated caller carrying that refusal as `principal.error`.
|
|
1376
|
+
|
|
1377
|
+
26.24 Where a handler's `principal.set` or `principal.clear` ran, its answer MUST say so in an
|
|
1378
|
+
`abide-principal` header, and a browser that reads `principal` MUST reload the document on it in
|
|
1379
|
+
every tab, serving the one it holds until the new one lands per 7.4.
|
|
1380
|
+
|
|
1381
|
+
26.25 `Principal` MUST admit a field an app declares on it, of any type.
|
|
1382
|
+
|
|
1383
|
+
# 27. Configuration
|
|
1384
|
+
|
|
1385
|
+
27.1 `config` MUST throw what `onConfig` threw.
|
|
1386
|
+
|
|
1387
|
+
27.2 Precedence MUST be derived, then `config` from the app, then the environment.
|
|
1388
|
+
|
|
1389
|
+
27.3 `APP_NAME`, `APP_VERSION` and `APP_DATA_DIR` MUST be derived where the config does not carry
|
|
1390
|
+
them.
|
|
1391
|
+
|
|
1392
|
+
27.4 `ConfigDefaults` MUST be synchronous by contract.
|
|
1393
|
+
|
|
1394
|
+
27.5 `config.invalidate` MUST re-read the environment and rerun `onConfig`.
|
|
1395
|
+
|
|
1396
|
+
27.6 Every `onConfig` filed MUST compose, in the order 37.7 states: the defaults each returns merged
|
|
1397
|
+
over the ones before it, and its schema run per 27.7.
|
|
1398
|
+
|
|
1399
|
+
27.7 Each `onConfig` `schema` MUST be checked last, over the whole document, and what each accepts
|
|
1400
|
+
MUST be merged over the document in the order 37.7 states.
|
|
1401
|
+
|
|
1402
|
+
27.8 A value out of `Env` MUST be coerced to the type of the default it overrides, and a value that
|
|
1403
|
+
will not coerce MUST keep that default.
|
|
1404
|
+
|
|
1405
|
+
27.9 `config` MUST be an unkeyed `global` `reactive` over the precedence 27.2 states.
|
|
1406
|
+
|
|
1407
|
+
27.10 Filing or unfiling `onConfig` MUST invalidate `config`, so a read taken before the app's
|
|
1408
|
+
module ran is not the one served after it.
|
|
1409
|
+
|
|
1410
|
+
27.11 `ConfigDefaults` MUST be handed the environment over what 27.3 derives.
|
|
1411
|
+
|
|
1412
|
+
27.12 `Config` MUST admit a field an app declares on it, of any type.
|
|
1413
|
+
|
|
1414
|
+
27.13 `abide check` and `abide lsp` MUST type `Config` with what the defaults of every `onConfig`
|
|
1415
|
+
called as a statement at the top of a `<script server>` return, and a union return with the keys
|
|
1416
|
+
every member of it has.
|
|
1417
|
+
|
|
1418
|
+
# 28. Logging
|
|
1419
|
+
|
|
1420
|
+
28.1 Every line MUST be appended to `log.records`, an ordinary `reactive` holding the lines kept as an
|
|
1421
|
+
array.
|
|
1422
|
+
|
|
1423
|
+
28.2 `log` MUST always write.
|
|
1424
|
+
|
|
1425
|
+
28.3 `log.warning` and `log.error` MUST always write.
|
|
1426
|
+
|
|
1427
|
+
28.4 `log.named` MUST prefix the app name, on a server and in a browser alike, and calling it again
|
|
1428
|
+
MUST append another segment.
|
|
1429
|
+
|
|
1430
|
+
28.5 A `Logger` MUST carry the same levels and the same `log.enabled` as `log`.
|
|
1431
|
+
|
|
1432
|
+
28.6 `log.enabled` MUST answer whether a gated line on that namespace would be written.
|
|
1433
|
+
|
|
1434
|
+
28.7 A namespace `log.enabled` reports closed MUST NOT run the measurement a gated line would report.
|
|
1435
|
+
|
|
1436
|
+
28.8 A correctness or a configuration failure MUST report on a namespace `abide:` names.
|
|
1437
|
+
|
|
1438
|
+
28.9 `DEBUG` MUST gate namespaces in debug-npm grammar, and MUST be read from the environment
|
|
1439
|
+
on a server.
|
|
1440
|
+
|
|
1441
|
+
28.10 `DEBUG` MUST reach a browser through the document rather than through the bundle.
|
|
1442
|
+
|
|
1443
|
+
28.11 A browser's own stored `DEBUG` setting MUST answer only where the document carries none, and
|
|
1444
|
+
MUST NOT override it.
|
|
1445
|
+
|
|
1446
|
+
28.12 The app name `log.named` prefixes MUST be read per line, so a logger named before the app's
|
|
1447
|
+
identity resolved writes under it once it has.
|
|
1448
|
+
|
|
1449
|
+
# 29. Content security policy
|
|
1450
|
+
|
|
1451
|
+
29.1 `csp` MUST be one `Middleware` rung.
|
|
1452
|
+
|
|
1453
|
+
29.2 `csp` MUST set `content-security-policy` on `text/html` only.
|
|
1454
|
+
|
|
1455
|
+
29.3 `csp.nonce` MUST be this response's nonce.
|
|
1456
|
+
|
|
1457
|
+
29.4 On a server, `csp.nonce` MUST be readable only inside a request scope, per 11.37.
|
|
1458
|
+
|
|
1459
|
+
29.5 The `csp` baseline MUST be `default-src 'self'`, `script-src 'self'`, `style-src 'self'`,
|
|
1460
|
+
`img-src 'self' data:`, `font-src 'self'`, `connect-src 'self'`, `style-src-attr 'unsafe-inline'`,
|
|
1461
|
+
`object-src 'none'`, `base-uri 'self'`, `frame-ancestors 'none'` and `form-action 'self'`.
|
|
1462
|
+
|
|
1463
|
+
29.6 `sources` MUST replace a directive rather than add to it.
|
|
1464
|
+
|
|
1465
|
+
29.7 A directive given an empty array in `sources` MUST be dropped.
|
|
1466
|
+
|
|
1467
|
+
29.8 A directive name the `csp` baseline lacks MUST be added.
|
|
1468
|
+
|
|
1469
|
+
29.9 The inline output `render` emits MUST be permitted by a build-time hash in `script-src`, and
|
|
1470
|
+
MUST NOT consume `csp.nonce`.
|
|
1471
|
+
|
|
1472
|
+
29.10 The inline output `render` emits MUST be byte-invariant across responses.
|
|
1473
|
+
|
|
1474
|
+
29.11 In a browser, `csp.nonce` MUST answer the nonce the document was served with.
|
|
1475
|
+
|
|
1476
|
+
# 30. Addresses and navigation
|
|
1477
|
+
|
|
1478
|
+
30.1 `url` MUST build an address from a route literal.
|
|
1479
|
+
|
|
1480
|
+
30.2 `url` MUST require a params argument where the literal carries a required segment, and MUST
|
|
1481
|
+
make it optional otherwise.
|
|
1482
|
+
|
|
1483
|
+
30.3 A required segment MUST map to a required key of `ParamsOf<P>`.
|
|
1484
|
+
|
|
1485
|
+
30.4 An `OptionalNames<P>` segment MUST map to an optional key, and leaving one out MUST omit that
|
|
1486
|
+
segment.
|
|
1487
|
+
|
|
1488
|
+
30.5 A `RestNames<P>` segment MUST map to an optional key taking an array as well as a scalar.
|
|
1489
|
+
|
|
1490
|
+
30.6 The `Query` argument MUST be last.
|
|
1491
|
+
|
|
1492
|
+
30.7 `navigate` MUST navigate, and MUST NOT reload the document.
|
|
1493
|
+
|
|
1494
|
+
30.8 A route `url` and `navigate` take MUST be a page route, per 23.14, and MUST NOT be a handler
|
|
1495
|
+
module's.
|
|
1496
|
+
|
|
1497
|
+
30.9 `navigate` MUST match the most specific route, ranking a static segment above a required
|
|
1498
|
+
one, a required above an optional, and an optional above a rest, and where one route ends, its end
|
|
1499
|
+
below a required segment and above an optional one.
|
|
1500
|
+
|
|
1501
|
+
30.10 An address `navigate` matches no route for MUST be left to the document, and MUST NOT be
|
|
1502
|
+
refused.
|
|
1503
|
+
|
|
1504
|
+
30.11 A page `navigate` reached MUST build its own markup, and a page the server painted MUST be
|
|
1505
|
+
hydrated where it stands.
|
|
1506
|
+
|
|
1507
|
+
30.12 `navigate` MUST stop the bindings of the page it replaced, per 12.13.
|
|
1508
|
+
|
|
1509
|
+
30.13 A plain click on a same-origin link a route matches MUST reach `navigate`, and a click
|
|
1510
|
+
carrying a modifier, a `target` or a `download` MUST NOT.
|
|
1511
|
+
|
|
1512
|
+
30.14 A pointer over, a press on or focus on a link 30.13 would take MUST load its route's chunks,
|
|
1513
|
+
and MUST NOT make an `Rpc` call.
|
|
1514
|
+
|
|
1515
|
+
30.15 `navigate` MUST pass the address it matched through `middleware` before it mounts the page.
|
|
1516
|
+
|
|
1517
|
+
30.16 A request `navigate` makes MUST be answered 204 with no body, at the status `middleware`
|
|
1518
|
+
wrote where it wrote one.
|
|
1519
|
+
|
|
1520
|
+
30.17 `navigate` MUST mount the route a redirect in that answer lands on, at the address it landed
|
|
1521
|
+
on.
|
|
1522
|
+
|
|
1523
|
+
30.18 `navigate` MUST leave an answer other than 204 to the document.
|
|
1524
|
+
|
|
1525
|
+
30.19 `url` MUST throw where a param, or a member of a rest param, is `.` or `..`.
|
|
1526
|
+
|
|
1527
|
+
30.20 A history step to an address that differs from the page shown only in its fragment MUST NOT
|
|
1528
|
+
pass through `middleware`, and MUST NOT remount the page.
|
|
1529
|
+
|
|
1530
|
+
30.21 `navigate` to the page shown, at an address carrying a fragment, MUST NOT pass through
|
|
1531
|
+
`middleware`, and MUST NOT remount the page.
|
|
1532
|
+
|
|
1533
|
+
30.22 A `navigate` that mounts a page, without `keepScroll`, MUST scroll to the element the address's
|
|
1534
|
+
fragment names, and to the top where it names none.
|
|
1535
|
+
|
|
1536
|
+
30.23 `navigate` to an address the route of the page shown matches MUST NOT remount the page, and
|
|
1537
|
+
MUST move `route.url` and `route.params` to that address.
|
|
1538
|
+
|
|
1539
|
+
30.24 A navigation 30.23 keeps the page for MUST pass through `middleware` where its path differs from
|
|
1540
|
+
the page shown, and MUST NOT where only its query or fragment does.
|
|
1541
|
+
|
|
1542
|
+
30.25 A `navigate` that does not remount the page MUST NOT move the scroll, except to the element a
|
|
1543
|
+
fragment it carries names.
|
|
1544
|
+
|
|
1545
|
+
30.26 `abide check` MUST refuse a `url` literal that no page of the app is filed under and no public
|
|
1546
|
+
file of the app is served at.
|
|
1547
|
+
|
|
1548
|
+
30.27 A `navigate` whose request fails, or whose route's chunks fail to load, MUST leave the address
|
|
1549
|
+
to the document.
|
|
1550
|
+
|
|
1551
|
+
# 31. Reading and writing by name
|
|
1552
|
+
|
|
1553
|
+
31.1 Inside a `.abide` file a name bound to a `Reactive` MUST be read wherever 31.3 does not hold it.
|
|
1554
|
+
|
|
1555
|
+
31.2 A read by name MUST be live.
|
|
1556
|
+
|
|
1557
|
+
31.3 A name MUST hold the `Reactive` only where the declared type of its position is a `Reactive`: an
|
|
1558
|
+
annotated binding, an annotated return, a `Reactive`-typed parameter, a `bind:` operand, an `await`
|
|
1559
|
+
operand — or where 31.14 holds it.
|
|
1560
|
+
|
|
1561
|
+
31.4 Assignment to such a name MUST be a write, and the assigned value MAY be settled, a load, or a
|
|
1562
|
+
`Reactive`.
|
|
1563
|
+
|
|
1564
|
+
31.5 A property access on such a name MUST reach the value, except a member declared on the
|
|
1565
|
+
`Reactive` type, which MUST reach that member bound to the `Reactive`.
|
|
1566
|
+
|
|
1567
|
+
31.6 A call on such a name MUST reach the `Reactive` API where the member is declared on the
|
|
1568
|
+
`Reactive` type, and the value's method otherwise.
|
|
1569
|
+
|
|
1570
|
+
31.7 `s` and `s.set` MUST keep compiling inside a `.abide` file.
|
|
1571
|
+
|
|
1572
|
+
31.8 A write through a member path into plain data MUST copy down that path and then write, and the
|
|
1573
|
+
copy MUST NOT be optimized away.
|
|
1574
|
+
|
|
1575
|
+
31.9 A mutator lifted per 31.8 MUST be resolved from the type of the `Reactive` rather than from
|
|
1576
|
+
the member name.
|
|
1577
|
+
|
|
1578
|
+
31.10 A template-local binding MUST shadow a name bound to a `Reactive` for the body it is bound in.
|
|
1579
|
+
|
|
1580
|
+
31.11 A read spelled `foo()` MUST take no arguments, and an argument MUST be a compile error.
|
|
1581
|
+
|
|
1582
|
+
31.12 A destructuring pattern or a spread over such a name MUST read it once.
|
|
1583
|
+
|
|
1584
|
+
31.13 The compiler MUST warn where 31.5 reaches a `Reactive` member the value's type also declares,
|
|
1585
|
+
naming the explicit read.
|
|
1586
|
+
|
|
1587
|
+
31.14 A name MUST hold the `Reactive` where the declared type of its position is a `Selection`, or a
|
|
1588
|
+
type parameter constrained by one.
|
|
1589
|
+
|
|
1590
|
+
31.15 A write through a member path that reaches a value which is not plain data — an array, or an
|
|
1591
|
+
object whose prototype is `Object.prototype` or `null` — MUST assign on that value itself, MUST NOT
|
|
1592
|
+
copy it or any level above it, and MUST NOT wake a reader.
|
|
1593
|
+
|
|
1594
|
+
31.16 `route.url`, `route.params`, `route.name` and `route.navigating` MUST each be read and written
|
|
1595
|
+
as a name bound to a `Reactive` is, per 31.1 to 31.7.
|
|
1596
|
+
|
|
1597
|
+
# 32. Templating
|
|
1598
|
+
|
|
1599
|
+
32.1 `{expr}` MUST render reactive text, escaped.
|
|
1600
|
+
|
|
1601
|
+
32.2 `{raw(...)}` MUST render raw HTML.
|
|
1602
|
+
|
|
1603
|
+
32.3 A `name={expr}` attribute or property expression MUST be reactive, whole or interpolated.
|
|
1604
|
+
|
|
1605
|
+
32.4 `on<event>` MUST bind a native listener on an element, and MUST be an ordinary prop on a
|
|
1606
|
+
component.
|
|
1607
|
+
|
|
1608
|
+
32.5 `bind:value` MUST read the property and write it back on input or change, through the member
|
|
1609
|
+
path where its operand is a path into a value (31.8).
|
|
1610
|
+
|
|
1611
|
+
32.6 `bind:prop` on a component MUST hand the child the caller's `Reactive`, or its `{ get, set }` pair,
|
|
1612
|
+
as that prop's write path.
|
|
1613
|
+
|
|
1614
|
+
32.7 A boolean bind MUST mirror a boolean DOM property as a boolean attribute, and MUST NOT write a
|
|
1615
|
+
string.
|
|
1616
|
+
|
|
1617
|
+
32.8 `bind:group` MUST compare against the input's own value, and MUST NOT emit a `group` attribute.
|
|
1618
|
+
|
|
1619
|
+
32.9 `bind:element` MUST accept a `Reactive` of an element, or a callback returning an optional
|
|
1620
|
+
`Disposer`.
|
|
1621
|
+
|
|
1622
|
+
32.10 `class:name` and `style:prop` MUST set one class or one style property.
|
|
1623
|
+
|
|
1624
|
+
32.11 `{...expr}` MUST spread props on a component and attributes on an element.
|
|
1625
|
+
|
|
1626
|
+
32.12 `{#if}` MUST render one branch.
|
|
1627
|
+
|
|
1628
|
+
32.13 `{#for}` with neither a key nor a `by` 32.32 reads MUST be positional.
|
|
1629
|
+
|
|
1630
|
+
32.14 `{#for}` without a key over a stateful body and a subject that reads a `Reactive` or calls a
|
|
1631
|
+
function MUST warn in development.
|
|
1632
|
+
|
|
1633
|
+
32.15 `{#for}` over an async iterable that is not also iterable MUST render each item as it
|
|
1634
|
+
arrives, and MUST append rather than reconcile.
|
|
1635
|
+
|
|
1636
|
+
32.16 `{#try}` MUST be a render-time boundary over a region, and a failure MUST replace the whole
|
|
1637
|
+
body.
|
|
1638
|
+
|
|
1639
|
+
32.17 A capitalized tag `<Name/>` MUST be a component invocation.
|
|
1640
|
+
|
|
1641
|
+
32.18 `<slot/>` MUST render children, and a fallback MUST render where none were passed.
|
|
1642
|
+
|
|
1643
|
+
32.19 An interpolated `style` attribute MUST lower to `style:prop` under a static property name, and
|
|
1644
|
+
MUST NOT be built as a string.
|
|
1645
|
+
|
|
1646
|
+
32.20 An interpolation in a URL-typed attribute MUST be scheme-checked, and a scheme outside
|
|
1647
|
+
`http:`, `https:`, `mailto:`, `tel:` or a relative reference MUST be dropped and warned on
|
|
1648
|
+
`abide:render`, naming the attribute and not the value.
|
|
1649
|
+
|
|
1650
|
+
32.21 A control block MUST bind each reactive read and probe call in its subject once for the body.
|
|
1651
|
+
|
|
1652
|
+
32.22 `{#for}` over an absent subject MUST iterate zero times.
|
|
1653
|
+
|
|
1654
|
+
32.23 A template expression a `NotLanded` aborted MUST leave what it last rendered in place.
|
|
1655
|
+
|
|
1656
|
+
32.24 `raw` MUST hand back a value branded as raw markup.
|
|
1657
|
+
|
|
1658
|
+
32.25 A bare `raw(...)` call MUST lower to a call to `raw` wherever a template expression whose
|
|
1659
|
+
value reaches markup holds it: a slot, an attribute value, a `{#if}` condition, a `{#for}` subject,
|
|
1660
|
+
and a value handed to a component. In a listener, a `bind:` operand and a `{#for}` key it MUST call
|
|
1661
|
+
what the file binds.
|
|
1662
|
+
|
|
1663
|
+
32.26 A slot MUST render a value branded by `raw` without escaping it.
|
|
1664
|
+
|
|
1665
|
+
32.27 Static text in a `.abide` template MUST render as markup, in body text and in an attribute
|
|
1666
|
+
value alike.
|
|
1667
|
+
|
|
1668
|
+
32.28 A static value in an attribute 32.20 scheme-checks MUST be escaped the way `{expr}` is.
|
|
1669
|
+
|
|
1670
|
+
32.29 A keyed `{#for}` MUST move a row it keeps, and the move MUST NOT take the row's nodes out of
|
|
1671
|
+
the document.
|
|
1672
|
+
|
|
1673
|
+
32.30 A slot MUST be bounded by an anchor pair of its own while it holds a value branded by `raw`,
|
|
1674
|
+
and MUST NOT be bounded by one while it holds none.
|
|
1675
|
+
|
|
1676
|
+
32.31 The anchor pair bounding a slot under 32.30 MUST be distinct from the one bounding a `{#if}`,
|
|
1677
|
+
a `{#for}`, a `{#try}`, a `<slot/>` or a `<Name/>`.
|
|
1678
|
+
|
|
1679
|
+
32.32 `{#for}` without a key over a subject that is a `Reactive` named alone MUST key its rows by
|
|
1680
|
+
that value's `by`, where it declares one.
|
|
1681
|
+
|
|
1682
|
+
32.33 A `{#for}` MUST NOT keep a row showing an item as it stood before an `s.patch` wrote to that
|
|
1683
|
+
item, or to an object the patch reached through it.
|
|
1684
|
+
|
|
1685
|
+
32.34 A `<Name/>` whose name is bound to a `Reactive`, or to a prop `props` hands back, MUST invoke
|
|
1686
|
+
the component the value holds.
|
|
1687
|
+
|
|
1688
|
+
32.35 A `<Name/>` under 32.34 MUST replace its component when the value changes to a different
|
|
1689
|
+
one, and MUST NOT rebuild it when the value is the same component.
|
|
1690
|
+
|
|
1691
|
+
32.36 A `<Name/>` under 32.34 whose value is absent MUST render nothing.
|
|
1692
|
+
|
|
1693
|
+
32.37 An attribute whose value is `null` or `undefined` MUST be absent; an attribute HTML reads by
|
|
1694
|
+
presence MUST be present or absent by the value's truthiness, and a string that makes one present
|
|
1695
|
+
MUST be written as its text; and any other MUST be written as its text — whether named or spread,
|
|
1696
|
+
and whether the server writes it or the browser does.
|
|
1697
|
+
|
|
1698
|
+
32.38 A `bind:element` callback's `Disposer` that hands back a thenable MUST keep the nodes holding
|
|
1699
|
+
that element in the document until it settles, and MUST remove them then.
|
|
1700
|
+
|
|
1701
|
+
32.39 An inline `{#component Name(pattern)}` MUST be TitleCase.
|
|
1702
|
+
|
|
1703
|
+
32.40 The pattern of a `{#component Name(pattern)}` MUST be read as the pattern of a `props` call,
|
|
1704
|
+
and its annotation as that call's type argument.
|
|
1705
|
+
|
|
1706
|
+
32.41 A `{#component Name(pattern)}` MUST be accepted wherever a node may stand in a `.abide`
|
|
1707
|
+
template: at its top level, inside an element, in a `{#if}`, `{#for}` or `{#try}` body, and in the
|
|
1708
|
+
body of another `{#component Name(pattern)}`.
|
|
1709
|
+
|
|
1710
|
+
32.42 Every name in scope where a `{#component Name(pattern)}` is written — its file's `<script>`
|
|
1711
|
+
and `<script module>` names, its file's imports, a `{#for}` row's item and index, a `{:catch e}`
|
|
1712
|
+
binding, and an enclosing `{#component Name(pattern)}`'s props — MUST be in scope in its body.
|
|
1713
|
+
|
|
1714
|
+
32.43 A `{#component Name(pattern)}` MUST be in scope throughout the body it is written in, before
|
|
1715
|
+
its declaration and in every body nested inside that one included, and in no other; that body is
|
|
1716
|
+
the template's top level, a `{#for}` row, a `{#if}` or `{#try}` arm, what stands between the tags
|
|
1717
|
+
of a `<Name/>` or a `<slot>`, or a `{#component Name(pattern)}`'s own, and an element around it is
|
|
1718
|
+
not one.
|
|
1719
|
+
|
|
1720
|
+
32.44 A `{#component Name(pattern)}` MUST be in scope in its own body.
|
|
1721
|
+
|
|
1722
|
+
32.45 A `<style>` block of a file MUST apply to the elements its `{#component Name(pattern)}`
|
|
1723
|
+
blocks write.
|
|
1724
|
+
|
|
1725
|
+
32.46 A `<script>` written in the body of a `{#component Name(pattern)}`, outside any block in it,
|
|
1726
|
+
MUST be that component's per-instance setup.
|
|
1727
|
+
|
|
1728
|
+
32.47 A `<style>` written in the body of a `{#component Name(pattern)}`, outside any block in it,
|
|
1729
|
+
MUST apply to the elements that component writes, and to no other element its file writes.
|
|
1730
|
+
|
|
1731
|
+
32.48 A `{#component Name(pattern)}` whose body holds two `<script>` blocks outside any block in it
|
|
1732
|
+
MUST be a build error.
|
|
1733
|
+
|
|
1734
|
+
32.49 A `{#component Name(pattern)}` whose name another `{#component Name(pattern)}` in the same
|
|
1735
|
+
body also declares MUST be a build error.
|
|
1736
|
+
|
|
1737
|
+
32.50 A `{#component Name(pattern)}` written directly between the tags of a `<Name/>` MUST be passed
|
|
1738
|
+
to that component as the prop its name spells.
|
|
1739
|
+
|
|
1740
|
+
32.51 A `{#component Name(pattern)}` passed under 32.50 MUST NOT be in scope in the body the
|
|
1741
|
+
`<Name/>` it is passed to stands in.
|
|
1742
|
+
|
|
1743
|
+
32.52 A `{#component Name(pattern)}` passed under 32.50 MUST NOT be among the children a `<slot/>`
|
|
1744
|
+
renders.
|
|
1745
|
+
|
|
1746
|
+
32.53 A `<Name/>` given a prop both as an attribute and as a `{#component Name(pattern)}` passed
|
|
1747
|
+
under 32.50 MUST be a build error.
|
|
1748
|
+
|
|
1749
|
+
32.54 `abide check` MUST hold a `{#component Name(pattern)}` passed under 32.50 to the type its
|
|
1750
|
+
component's `props` call declares for that prop, and MUST report a mismatch on the
|
|
1751
|
+
`{#component Name(pattern)}`.
|
|
1752
|
+
|
|
1753
|
+
32.55 A `{#component Name(pattern)}` at the template's top level whose name an import, a `<script>`
|
|
1754
|
+
declaration or a `<script module>` declaration of its file also binds MUST be a build error.
|
|
1755
|
+
|
|
1756
|
+
32.56 A `{:catch}` or a `{:finally}` anywhere but directly inside a `{#try}` MUST be a build
|
|
1757
|
+
error.
|
|
1758
|
+
|
|
1759
|
+
32.57 An `await` in a template expression — a slot, an attribute value, a listener, a `bind:`
|
|
1760
|
+
operand, a `{#if}` condition, a `{#for}` subject or key, or a value handed to a component — outside
|
|
1761
|
+
any function that expression declares, MUST be a compile error.
|
|
1762
|
+
|
|
1763
|
+
# 33. Props
|
|
1764
|
+
|
|
1765
|
+
33.1 `props` MUST be callable from a `<script>` block only, and calling it from a `<script module>`
|
|
1766
|
+
block MUST be a compile error.
|
|
1767
|
+
|
|
1768
|
+
33.2 A component with no `props` call MUST accept no props of its own, and a caller passing one
|
|
1769
|
+
MUST be an error.
|
|
1770
|
+
|
|
1771
|
+
33.3 `props` with no type argument MUST hand back an untyped record, which is the opt-out.
|
|
1772
|
+
|
|
1773
|
+
33.4 `props` MUST hand back one accessor per key, and the accessor's shape MUST be what that key's
|
|
1774
|
+
type declares.
|
|
1775
|
+
|
|
1776
|
+
33.5 A prop MUST be a live read of the caller's expression, and MUST NOT be a snapshot.
|
|
1777
|
+
|
|
1778
|
+
33.6 A write by name to a prop the caller bound MUST reach the caller's `Reactive`.
|
|
1779
|
+
|
|
1780
|
+
33.7 A write by name to a prop the caller did not bind MUST stand in the child until the caller's
|
|
1781
|
+
expression next changes.
|
|
1782
|
+
|
|
1783
|
+
33.8 `bind:` MUST be accepted on every prop, whatever type the child declares for it.
|
|
1784
|
+
|
|
1785
|
+
33.9 Destructuring `props` MUST keep every binding live.
|
|
1786
|
+
|
|
1787
|
+
33.10 The `props` lowering MUST be type-directed: a declared prop type with no index signature MUST give a
|
|
1788
|
+
fixed accessor per key, whatever the call site spelled.
|
|
1789
|
+
|
|
1790
|
+
33.11 A prop type carrying an index signature MUST take the dynamic form, where a spread is one
|
|
1791
|
+
live read with its keys enumerated per read.
|
|
1792
|
+
|
|
1793
|
+
33.12 An explicit prop MUST beat a `{...expr}` spread, whatever the source order.
|
|
1794
|
+
|
|
1795
|
+
33.13 Two `{...expr}` spreads against each other MUST resolve in source order.
|
|
1796
|
+
|
|
1797
|
+
33.14 The `props` pattern MUST be flat: renames, defaults and a rest element, and no nested
|
|
1798
|
+
patterns.
|
|
1799
|
+
|
|
1800
|
+
33.15 A `props` rest element MUST be live, one accessor per key the call site passed, and a member
|
|
1801
|
+
read by name MUST read `undefined` where the call site did not pass it.
|
|
1802
|
+
|
|
1803
|
+
33.16 `children` MUST always be accepted and MUST never be declared.
|
|
1804
|
+
|
|
1805
|
+
33.17 In a `.abide` template a run of whitespace carrying newlines but no space or tab MUST be
|
|
1806
|
+
dropped wherever it stands.
|
|
1807
|
+
|
|
1808
|
+
33.18 In a `.abide` template a run of whitespace that renders nothing but carries a newline and
|
|
1809
|
+
indentation MUST be dropped at both ends of every block body and of the top-level template.
|
|
1810
|
+
|
|
1811
|
+
33.19 The static text of a prop a `<Name/>` passes MUST reach the child as the characters it stands
|
|
1812
|
+
for, decoded by HTML's attribute-value rule, and each static piece of an interpolated one MUST be
|
|
1813
|
+
decoded on its own.
|
|
1814
|
+
|
|
1815
|
+
33.20 A `props` default MUST answer wherever the caller's expression reads `undefined`, the key
|
|
1816
|
+
left out included, and its binding MUST be typed without `undefined`.
|
|
1817
|
+
|
|
1818
|
+
33.21 A prop a `<Name/>` passes as a bare attribute, a name with no value, MUST reach the child as
|
|
1819
|
+
`true`.
|
|
1820
|
+
|
|
1821
|
+
33.22 A `props` rest element handed on whole MUST carry each key's value, read where it is read,
|
|
1822
|
+
and MUST NOT carry the accessor.
|
|
1823
|
+
|
|
1824
|
+
33.23 `Attributes<Tag>` MUST type each attribute `Tag` takes under its HTML name, by every value
|
|
1825
|
+
that writes that attribute per 32.37.
|
|
1826
|
+
|
|
1827
|
+
33.24 `Attributes<Tag>` MUST type an `on<event>` member's event as the one `Tag` dispatches, with
|
|
1828
|
+
that element as its `currentTarget`.
|
|
1829
|
+
|
|
1830
|
+
33.25 A `props` rest element MUST NOT hold `children`.
|
|
1831
|
+
|
|
1832
|
+
33.26 `Attributes<Tag>` over an SVG element MUST type the SVG attributes, presentation attributes
|
|
1833
|
+
included, under the names SVG spells them, and a tag both HTML and SVG name MUST be typed as the HTML
|
|
1834
|
+
element.
|
|
1835
|
+
|
|
1836
|
+
# 34. Script and style blocks
|
|
1837
|
+
|
|
1838
|
+
34.1 A `<script>` block MUST be per-instance component setup.
|
|
1839
|
+
|
|
1840
|
+
34.2 A `<script module>` block MUST be module scope, on a server as in a browser.
|
|
1841
|
+
|
|
1842
|
+
34.3 A `<script>`, a `<script module>` or a `<script server>` MUST NOT await at its top level, and
|
|
1843
|
+
one that does MUST be a compile error.
|
|
1844
|
+
|
|
1845
|
+
34.4 A `<style>` block written outside a block body MUST be component-scoped: every root element MUST
|
|
1846
|
+
carry a scope token, and every selector MUST require it on its rightmost compound.
|
|
1847
|
+
|
|
1848
|
+
34.5 `:global(…)` MUST exempt the compound inside it from carrying the scope token.
|
|
1849
|
+
|
|
1850
|
+
34.6 A stylesheet imported from any `<script>` in the file, or any `.ts` it reaches, MUST be a
|
|
1851
|
+
dependency of that component.
|
|
1852
|
+
|
|
1853
|
+
34.7 A branch-local `<script>` MUST run once each time the `{#for}` row or `{#if}` arm it is written
|
|
1854
|
+
in is built.
|
|
1855
|
+
|
|
1856
|
+
34.8 A name a branch-local `<script>` declares MUST be in scope in the body it is written in, and in
|
|
1857
|
+
no other.
|
|
1858
|
+
|
|
1859
|
+
34.9 A block body holding two branch-local `<script>` blocks MUST be a build error.
|
|
1860
|
+
|
|
1861
|
+
34.10 A `<script>` or a `<style>` inside a `{#try}` MUST be a build error.
|
|
1862
|
+
|
|
1863
|
+
34.11 A `<style>` written in a `{#for}` row or an `{#if}` arm MUST apply to the elements that body holds,
|
|
1864
|
+
and to no other element the component writes.
|
|
1865
|
+
|
|
1866
|
+
34.12 A `<script>` carrying a `lang` attribute MUST be a compile error.
|
|
1867
|
+
|
|
1868
|
+
34.13 `generics` on a component's `<script>` MUST declare that component's type parameters: its
|
|
1869
|
+
blocks and template MUST be checked for every type they admit, and a `<Name/>` MUST infer them from
|
|
1870
|
+
the props it passes.
|
|
1871
|
+
|
|
1872
|
+
34.14 A relative specifier any script block imports from MUST resolve against the `.abide` file it
|
|
1873
|
+
is written in.
|
|
1874
|
+
|
|
1875
|
+
34.15 A `.abide` file any script block names in an `import()` MUST resolve to the module that file
|
|
1876
|
+
compiles to, as a static import of it does.
|
|
1877
|
+
|
|
1878
|
+
34.16 A `.abide` file a server module imports MUST resolve to a function that binds its props and
|
|
1879
|
+
answers a `Component`, under `abide dev`, `abide start` and `abide compile` alike.
|
|
1880
|
+
|
|
1881
|
+
34.17 A name a `<script module>` exports MUST be exported from the module the file compiles to, on a
|
|
1882
|
+
server as in a browser.
|
|
1883
|
+
|
|
1884
|
+
34.18 A `<script>` that exports MUST be a compile error.
|
|
1885
|
+
|
|
1886
|
+
34.19 A write a `<script>` makes outside any function to a `let` or `var` its file's
|
|
1887
|
+
`<script module>` declares, holding no `Reactive`, MUST be warned on.
|
|
1888
|
+
|
|
1889
|
+
34.20 A `<script server>` block MUST be module scope run on a server alone, and the module a browser
|
|
1890
|
+
loads MUST NOT carry it.
|
|
1891
|
+
|
|
1892
|
+
34.21 A `<script server>` in a `.abide` file of the app's own under a `server` or `public` directory
|
|
1893
|
+
MUST be a compile error.
|
|
1894
|
+
|
|
1895
|
+
34.22 A `<script server>` exporting `default` MUST be a compile error.
|
|
1896
|
+
|
|
1897
|
+
34.23 A handler a `<script server>` exports MUST be exported from the module a browser loads as the
|
|
1898
|
+
wrapper 16.28 states, under the same name.
|
|
1899
|
+
|
|
1900
|
+
34.24 `abide sync`, `abide check`, `abide dev` and `abide build` MUST write, for every `.abide`
|
|
1901
|
+
under the root, a module typing what its `<script module>` and `<script server>` export, below
|
|
1902
|
+
`.abide/types` at the path the file has below the directory above the root, and MUST remove one whose
|
|
1903
|
+
`.abide` is gone; `abide lsp` MUST write an open file's as the editor holds it, and the scaffold MUST
|
|
1904
|
+
run `abide sync` on install without failing the install where it fails. A file `abide sync` or
|
|
1905
|
+
`abide check` refuses MUST be named, and MUST NOT stop the others being typed.
|
|
1906
|
+
|
|
1907
|
+
34.25 A file a script block imports `with { type: 'text' }`, a `.abide` among them, MUST be imported
|
|
1908
|
+
as its text and typed a `string`, on a server, in a browser and to the checker alike.
|
|
1909
|
+
|
|
1910
|
+
34.26 A binding a `<script server>` imports that its file's `<script module>` or `<script>` imports
|
|
1911
|
+
from the same specifier under the same name MUST compile as that one binding, a value wherever any
|
|
1912
|
+
of them imports it as one. Where that binding is a `.abide`'s default or namespace imported as a
|
|
1913
|
+
value by both, it MUST be a compile error, since the server block's is the bound function (34.16)
|
|
1914
|
+
and the other's the module (32.17).
|
|
1915
|
+
|
|
1916
|
+
34.27 A `.abide` file any script block imports MUST be compiled with the app that imports it,
|
|
1917
|
+
wherever it lies.
|
|
1918
|
+
|
|
1919
|
+
34.28 A dependency's `.abide` MUST be a component, and MUST NOT be an address, save where a mount
|
|
1920
|
+
places it (23.19).
|
|
1921
|
+
|
|
1922
|
+
34.29 A dependency's `.abide` MUST be typed by the project of the app that imports it.
|
|
1923
|
+
|
|
1924
|
+
34.30 A dependency's `.abide` MUST run on the abide that the app's root resolves.
|
|
1925
|
+
|
|
1926
|
+
34.31 A `<script server>` in a dependency's `.abide` MUST NOT give a handler an address of its own,
|
|
1927
|
+
save the one a mount places it at (23.19).
|
|
1928
|
+
|
|
1929
|
+
34.32 A name the framework reads off what a `<script module>` exports MUST be read off the loaded
|
|
1930
|
+
module when the thing that needs it runs, MUST be held to its type by the checker alone, and MUST
|
|
1931
|
+
NOT be read by evaluating the module during a build.
|
|
1932
|
+
|
|
1933
|
+
34.33 A `<script>` carrying a `server` attribute with a value, or beside any other attribute, MUST be
|
|
1934
|
+
a compile error.
|
|
1935
|
+
|
|
1936
|
+
34.34 A `</script>` that closes no `<script>` MUST be a compile error.
|
|
1937
|
+
|
|
1938
|
+
34.35 A `</script>` inside a string, a template, a comment or a regular expression in a `<script>`,
|
|
1939
|
+
`<script module>` or `<script server>` block MUST be a compile error.
|
|
1940
|
+
|
|
1941
|
+
# 35. Pages, rendering and sinks
|
|
1942
|
+
|
|
1943
|
+
35.1 A `layout.abide` MUST render every page whose route lies below its own through a slot.
|
|
1944
|
+
|
|
1945
|
+
35.2 An `error.abide` MUST be resolved nearest-ancestor by route, as a layout is.
|
|
1946
|
+
|
|
1947
|
+
35.3 An `error.abide` that itself fails MUST escalate past the boundary, and MUST warn on
|
|
1948
|
+
`abide:render`.
|
|
1949
|
+
|
|
1950
|
+
35.4 `render` MUST take a `Component` already bound to its props.
|
|
1951
|
+
|
|
1952
|
+
35.5 `render` MUST produce a document as its bytes.
|
|
1953
|
+
|
|
1954
|
+
35.6 `render` MUST render into abide's own document, which carries an encoding and a viewport, each
|
|
1955
|
+
keyed, and nothing else.
|
|
1956
|
+
|
|
1957
|
+
35.7 A sink MUST be a hole a `render` leaves where a value is still in flight, for the browser to
|
|
1958
|
+
fill once that value lands.
|
|
1959
|
+
|
|
1960
|
+
35.8 An attribute a sink fills MUST be filled on the element itself.
|
|
1961
|
+
|
|
1962
|
+
35.9 A sink inside RCDATA MUST fill through the element's own property rather than through markup.
|
|
1963
|
+
|
|
1964
|
+
35.10 The batching unit of a sink fill MUST be the turn and MUST NOT be the production.
|
|
1965
|
+
|
|
1966
|
+
35.11 A `render` MUST close when its walk is done, and MUST NOT write a sink's fill into the
|
|
1967
|
+
document it streams.
|
|
1968
|
+
|
|
1969
|
+
35.12 Two `layout.abide` files, or two `error.abide` files, at one route MUST be a build error naming
|
|
1970
|
+
both.
|
|
1971
|
+
|
|
1972
|
+
35.13 A `layout.abide` with no template MUST NOT wrap a page.
|
|
1973
|
+
|
|
1974
|
+
35.14 An `error.abide` with neither a template nor a head MUST NOT answer for a page.
|
|
1975
|
+
|
|
1976
|
+
35.15 The outermost component of a render — the root `layout.abide` of a page, or the component given
|
|
1977
|
+
to `render` — written inside `<html>` MUST write the document: its `<head>`'s children
|
|
1978
|
+
MUST contribute to the head as a `<head>` block's do, its `<body>`'s children MUST be its template,
|
|
1979
|
+
and the attributes of its `<html>` and `<body>` MUST be written onto the document's own two.
|
|
1980
|
+
|
|
1981
|
+
35.16 An `<html>` or `<body>` in a page, an error page or any layout but the root `layout.abide`,
|
|
1982
|
+
one nested in markup, one with markup beside it, or an `<html>` holding anything but a `<head>` and a
|
|
1983
|
+
`<body>`, MUST be a build error, and a component writing `<html>` placed inside another MUST be
|
|
1984
|
+
refused where it renders.
|
|
1985
|
+
|
|
1986
|
+
35.17 An attribute on the document's `<html>` or `<body>` MUST be typed, rendered and bound as one
|
|
1987
|
+
on any element is.
|
|
1988
|
+
|
|
1989
|
+
# 36. Environment and files
|
|
1990
|
+
|
|
1991
|
+
36.1 `PORT` MUST default to 3000, and a command's own port flag MUST override it by declaring it.
|
|
1992
|
+
|
|
1993
|
+
36.2 `APP_URL`'s origin MUST be what both origin gates compare against.
|
|
1994
|
+
|
|
1995
|
+
36.3 `NODE_ENV` MUST be read verbatim, and MUST be defaulted from the command where unset.
|
|
1996
|
+
|
|
1997
|
+
36.4 `APP_DATA_DIR` MUST be a path, and abide MUST NOT create it.
|
|
1998
|
+
|
|
1999
|
+
36.5 `ABIDE_PRINCIPAL_SECRET` MUST accept a comma-separated list.
|
|
2000
|
+
|
|
2001
|
+
36.6 `ABIDE_APP_TOKEN` and `ABIDE_APP_URL` MUST be read by the remote CLI only.
|
|
2002
|
+
|
|
2003
|
+
36.7 A closed surface — `/__abide/openapi.json` or `/__abide/mcp` (20.7), or `/__abide/bridge`
|
|
2004
|
+
(45.19) — MUST answer 404.
|
|
2005
|
+
|
|
2006
|
+
36.8 `ABIDE_LOG_FORMAT` unset MUST follow the TTY.
|
|
2007
|
+
|
|
2008
|
+
36.9 `NO_COLOR` MUST beat `FORCE_COLOR`.
|
|
2009
|
+
|
|
2010
|
+
36.10 A module MUST be importable from either graph unless it lies under a `server` directory, per
|
|
2011
|
+
16.29.
|
|
2012
|
+
|
|
2013
|
+
36.11 A file under a `public` directory MUST be answered at that directory's path below the app's
|
|
2014
|
+
`--root` followed by its own path below that directory, rooted at the mount rather than at the
|
|
2015
|
+
origin.
|
|
2016
|
+
|
|
2017
|
+
36.12 A file under a `public` directory MUST be answered with the bytes as authored.
|
|
2018
|
+
|
|
2019
|
+
36.13 A file under a `public` directory answered at a route's address, or at another such file's,
|
|
2020
|
+
MUST be refused by `abide build` and by `abide dev`, naming both.
|
|
2021
|
+
|
|
2022
|
+
36.14 A file under a `public` directory MUST carry a `content-type` derived from its extension.
|
|
2023
|
+
|
|
2024
|
+
36.15 A URL in the client bundle naming the address of a file under a `public` directory MUST resolve
|
|
2025
|
+
to that address below the path `APP_URL` names, and MUST NOT be resolved as a path on disk by
|
|
2026
|
+
`abide build` or by `abide dev`.
|
|
2027
|
+
|
|
2028
|
+
36.16 `NODE_ENV` MUST default to `development` under `abide dev`, and to `production` under
|
|
2029
|
+
`abide build` and `abide start`.
|
|
2030
|
+
|
|
2031
|
+
36.17 A file under a `public` directory whose `content-type` is `text/*` MUST name `charset=utf-8` where
|
|
2032
|
+
its extension's type names none.
|
|
2033
|
+
|
|
2034
|
+
36.18 A seed buffer entry whose stream transcript passes `ABIDE_MAX_STREAM_BUFFER_SIZE`, counted in
|
|
2035
|
+
the chunk type's default framing, MUST stop holding it, and the `Rpc` call it was for MUST be
|
|
2036
|
+
answered per 41.12.
|
|
2037
|
+
|
|
2038
|
+
# 37. Lifecycle hooks
|
|
2039
|
+
|
|
2040
|
+
37.1 A lifecycle hook MUST be called rather than exported, and MUST be filed at the route of the
|
|
2041
|
+
`<script server>` that called it, or at the root route where none did.
|
|
2042
|
+
|
|
2043
|
+
37.2 `middleware` filed below the root route MUST run after routing, over a request its route or a
|
|
2044
|
+
route below it answers, outermost route first.
|
|
2045
|
+
|
|
2046
|
+
37.3 `middleware` filed at the root route MUST run pre-routing, over the request and the response, and over the upgrade to the
|
|
2047
|
+
socket mux, which MUST open only at its own address below the mount, only in an app with a handler
|
|
2048
|
+
to carry, and MUST NOT open where a rung answered in the lane's place — under `abide dev` as under
|
|
2049
|
+
`abide start`.
|
|
2050
|
+
|
|
2051
|
+
37.4 `onStart` MUST wrap `createApp` and `onStop` MUST wrap `App.stop`, each composed in the order 37.7
|
|
2052
|
+
states, the first filed outermost.
|
|
2053
|
+
|
|
2054
|
+
37.5 `onError` MUST run on an unexpected error in a request its route or a route below it answers,
|
|
2055
|
+
nearest route first, and on one outside every request where filed at the root route.
|
|
2056
|
+
|
|
2057
|
+
37.6 A hook `onStart` or `onStop` wraps that throws MUST fail hard, and the server MUST NOT
|
|
2058
|
+
start.
|
|
2059
|
+
|
|
2060
|
+
37.7 `onConfig`, `onPrincipal`, `onStart`, `onStop` and `onHealth` MUST each compose every hook filed,
|
|
2061
|
+
by route depth, then by route, then in the order called — the answers of `onConfig` and
|
|
2062
|
+
`onPrincipal` merged, a later one's member over an earlier one's.
|
|
2063
|
+
|
|
2064
|
+
37.8 Under `abide start` and `abide dev`, a rejection nothing handled and a throw nothing caught MUST
|
|
2065
|
+
reach `onError` as 37.5's error does.
|
|
2066
|
+
|
|
2067
|
+
37.9 Under `abide dev`, a rejection nothing handled and a throw nothing caught MUST NOT end the
|
|
2068
|
+
process.
|
|
2069
|
+
|
|
2070
|
+
37.10 Under `abide start` and the executable's `start`, a rejection nothing handled and a throw
|
|
2071
|
+
nothing caught MUST stop the app through `App.stop`, and the process MUST then exit with 1.
|
|
2072
|
+
|
|
2073
|
+
37.11 Under `abide start` and the executable's `start`, `SIGTERM` and `SIGINT` MUST stop the app
|
|
2074
|
+
through `App.stop`, and the process MUST then exit with 0.
|
|
2075
|
+
|
|
2076
|
+
37.12 A second `SIGTERM` or `SIGINT` while the app is stopping MUST end the process at once.
|
|
2077
|
+
|
|
2078
|
+
# 38. Commands
|
|
2079
|
+
|
|
2080
|
+
38.1 `abide scaffold` MUST write a starter project, and MUST skip a step already done.
|
|
2081
|
+
|
|
2082
|
+
38.2 `abide run` MUST pass everything after the file to the script.
|
|
2083
|
+
|
|
2084
|
+
38.3 `abide check` MUST report every diagnostic on the `.abide` line.
|
|
2085
|
+
|
|
2086
|
+
38.4 `abide dev` MUST watch the project and keep the app up.
|
|
2087
|
+
|
|
2088
|
+
38.5 `abide build` MUST emit content-hashed chunks and a manifest, minified and precompressed.
|
|
2089
|
+
|
|
2090
|
+
38.6 `abide start` MUST boot what `abide build` produced.
|
|
2091
|
+
|
|
2092
|
+
38.7 `abide` given `--url` and no command MUST boot nothing.
|
|
2093
|
+
|
|
2094
|
+
38.8 `abide call` MUST be the one spelling for calling a handler, in argv and in the shell alike.
|
|
2095
|
+
|
|
2096
|
+
38.9 `abide openapi` and `abide mcp` MUST derive from the same route table the served surfaces do,
|
|
2097
|
+
per 20.1.
|
|
2098
|
+
|
|
2099
|
+
38.10 `abide compile` and `abide bundle` MUST produce a standalone artifact.
|
|
2100
|
+
|
|
2101
|
+
38.11 `abide lsp` MUST speak over stdio.
|
|
2102
|
+
|
|
2103
|
+
38.12 Asking `abide` for help MUST be a success, and an unknown command MUST NOT be.
|
|
2104
|
+
|
|
2105
|
+
38.13 `abide mcp` MUST be a bridge a model client spawns and kills, and `abide start` MUST NOT be
|
|
2106
|
+
put in that position.
|
|
2107
|
+
|
|
2108
|
+
38.14 `abide dev` MUST hold the app in a child process and keep the listener in its own.
|
|
2109
|
+
|
|
2110
|
+
38.15 `abide dev` MUST replace that process to reload, and MUST force-close every live socket on
|
|
2111
|
+
replacement.
|
|
2112
|
+
|
|
2113
|
+
38.16 `abide dev` MUST build the client into memory, unminified and entry-named by its source, and
|
|
2114
|
+
MUST write nothing to disk.
|
|
2115
|
+
|
|
2116
|
+
38.17 A client build that fails under `abide dev` MUST NOT stop the server, and the reload client
|
|
2117
|
+
MUST be served by the dev worker rather than out of the bundle.
|
|
2118
|
+
|
|
2119
|
+
38.18 `abide build` MUST copy every `public` directory into the built output, and each file MUST be
|
|
2120
|
+
listed in the manifest 38.5 emits.
|
|
2121
|
+
|
|
2122
|
+
38.19 `abide dev` MUST answer a file under a `public` directory out of the source tree, per 38.16.
|
|
2123
|
+
|
|
2124
|
+
38.20 `abide start` MUST answer what `abide build` bundled under `/__abide/client`, and MUST answer
|
|
2125
|
+
nothing else there.
|
|
2126
|
+
|
|
2127
|
+
38.21 `abide start` MUST answer 404 at an address no route matches, per 30.8.
|
|
2128
|
+
|
|
2129
|
+
38.22 The document `abide start` serves MUST load the client entry, and MUST load it from the head.
|
|
2130
|
+
|
|
2131
|
+
38.23 The document `abide start` serves MUST link the stylesheet `abide build` bundled, and MUST
|
|
2132
|
+
link none where the build bundled none.
|
|
2133
|
+
|
|
2134
|
+
38.24 A request `abide dev` has not begun to answer when it replaces the worker MUST be answered
|
|
2135
|
+
by the replacement.
|
|
2136
|
+
|
|
2137
|
+
38.25 `--root` MUST default to `src` where the working directory holds one, and to the working
|
|
2138
|
+
directory otherwise.
|
|
2139
|
+
|
|
2140
|
+
38.26 A command that finds no app at its `--root` MUST fail, naming where it looked.
|
|
2141
|
+
|
|
2142
|
+
38.27 `--out` MUST default beside the app rather than beside the working directory.
|
|
2143
|
+
|
|
2144
|
+
38.28 The document `abide start` or `abide dev` serves MUST preload, from the head, every chunk its
|
|
2145
|
+
route imports statically, and MUST NOT preload a chunk reached only through a dynamic import.
|
|
2146
|
+
|
|
2147
|
+
38.29 `abide start` MUST answer the document, the bundle and an `Rpc`'s JSON answer in an
|
|
2148
|
+
encoding the request accepts where it has one, and MUST name `accept-encoding` in `vary`.
|
|
2149
|
+
|
|
2150
|
+
38.30 `abide build` and `abide dev` MUST type an app with no `tsconfig.json` against a default
|
|
2151
|
+
project, and MUST NOT compile it untyped.
|
|
2152
|
+
|
|
2153
|
+
38.31 `abide check` MUST check each `.abide` file as the program it lowers to.
|
|
2154
|
+
|
|
2155
|
+
38.32 `abide check` MUST exit non-zero where it reports an error, and MUST exit zero where it reports
|
|
2156
|
+
warnings alone.
|
|
2157
|
+
|
|
2158
|
+
38.33 `abide check` MUST report a refusal the build would make as a finding, and MUST go on checking
|
|
2159
|
+
every file that refusal does not stop.
|
|
2160
|
+
|
|
2161
|
+
38.34 `abide lsp` MUST report what 38.3 reports, over the text the editor holds rather than the
|
|
2162
|
+
text on disk.
|
|
2163
|
+
|
|
2164
|
+
38.35 `abide dev` MUST send a response body as the app produces it.
|
|
2165
|
+
|
|
2166
|
+
38.36 `abide dev` MUST read no more of a response body whose length is not declared than the
|
|
2167
|
+
connection has taken.
|
|
2168
|
+
|
|
2169
|
+
38.37 A response `abide dev` has begun to answer when it replaces the worker MUST end in an error.
|
|
2170
|
+
|
|
2171
|
+
38.38 `abide dev` MUST answer in the identity encoding.
|
|
2172
|
+
|
|
2173
|
+
38.39 `abide lsp` MUST answer a hover and a jump to a definition about the text it last checked, with
|
|
2174
|
+
a name read by name as the `Reactive` it was declared as, a member of it as a member of the value, and
|
|
2175
|
+
a component tag as the component it invokes.
|
|
2176
|
+
|
|
2177
|
+
38.40 `abide check` MUST hold every attribute a component tag passes to the type its component's
|
|
2178
|
+
`props` call declares, and MUST report a mismatch on the attribute.
|
|
2179
|
+
|
|
2180
|
+
38.41 A worker `abide dev` did not replace that exits MUST be replaced, and every request it held
|
|
2181
|
+
MUST be answered or ended rather than left open.
|
|
2182
|
+
|
|
2183
|
+
38.42 The project `abide scaffold` writes MUST depend on the abide that wrote it in a spelling that
|
|
2184
|
+
installs, and MUST type the runtime its server modules run on.
|
|
2185
|
+
|
|
2186
|
+
38.43 `abide build` and `abide dev` MUST build the client with the plugins the app's `bunfig.toml`
|
|
2187
|
+
names under `[serve.static] plugins`, after abide's own.
|
|
2188
|
+
|
|
2189
|
+
38.44 The executable `abide compile` writes MUST read nothing from the app's source tree or its build
|
|
2190
|
+
when it runs.
|
|
2191
|
+
|
|
2192
|
+
38.45 The executable `abide compile` writes MUST NOT read a `bunfig.toml` where it is started.
|
|
2193
|
+
|
|
2194
|
+
38.46 `abide compile` given no `--out` MUST write the executable into the directory it was run from,
|
|
2195
|
+
named after the app's `package.json` name without its scope.
|
|
2196
|
+
|
|
2197
|
+
38.47 `abide compile --platforms` MUST write one executable per platform, each named with its
|
|
2198
|
+
platform as a suffix.
|
|
2199
|
+
|
|
2200
|
+
38.48 `abide compile` MUST refuse `--target` and `--platforms` given together.
|
|
2201
|
+
|
|
2202
|
+
38.49 The executable `abide compile` writes MUST take `--port` on `start` as `abide start` does.
|
|
2203
|
+
|
|
2204
|
+
38.50 The executable `abide compile` writes MUST answer every command `abide` answers.
|
|
2205
|
+
|
|
2206
|
+
38.51 The executable `abide compile` writes MUST refuse a command that needs the app's source, naming
|
|
2207
|
+
the `abide` command that runs it.
|
|
2208
|
+
|
|
2209
|
+
38.52 The usage the executable `abide compile` writes prints MUST NOT list a command it refuses, nor a
|
|
2210
|
+
flag only such a command reads.
|
|
2211
|
+
|
|
2212
|
+
38.53 `abide` and the executable given no command and no running app to talk to MUST serve the app
|
|
2213
|
+
and open 38.7's shell on it.
|
|
2214
|
+
|
|
2215
|
+
38.54 Leaving the shell 38.53 opens with `exit` MUST stop the app.
|
|
2216
|
+
|
|
2217
|
+
38.55 Input that ends MUST NOT stop the app `abide` serves under 38.53.
|
|
2218
|
+
|
|
2219
|
+
38.56 A script the executable's `run` imports MUST resolve `abide`'s entries and the app's handler
|
|
2220
|
+
modules to the ones the executable holds.
|
|
2221
|
+
|
|
2222
|
+
38.57 `abide run` and the executable's `run` MUST resolve the configuration under the app's identity.
|
|
2223
|
+
|
|
2224
|
+
38.58 `abide dev`, `abide start` and the app 38.53 serves MUST print every address the app answers at,
|
|
2225
|
+
the local one first.
|
|
2226
|
+
|
|
2227
|
+
38.59 38.7's shell MUST answer `help` with every word it takes.
|
|
2228
|
+
|
|
2229
|
+
38.60 A line the app logs while 38.7's shell is open on a terminal MUST NOT move the shell's prompt,
|
|
2230
|
+
nor the line being typed — `log` or the console alike.
|
|
2231
|
+
|
|
2232
|
+
38.61 `abide call`'s args MUST be `name=value` words, each value coerced by the app it reaches as
|
|
2233
|
+
19.7 coerces a query's and a name given twice a list, or one JSON object where the first word opens
|
|
2234
|
+
one.
|
|
2235
|
+
|
|
2236
|
+
38.62 38.7's shell MUST list and complete each handler `call` reaches that `clients.cli` does not
|
|
2237
|
+
withhold, with its args, and with its `description` where the declaration writes one as a literal.
|
|
2238
|
+
|
|
2239
|
+
38.63 `abide dev` given neither `--port` nor `PORT` MUST listen on the first free port from 3000
|
|
2240
|
+
through 3099.
|
|
2241
|
+
|
|
2242
|
+
38.64 `abide dev` given a port by `--port` or `PORT` MUST NOT listen on any other.
|
|
2243
|
+
|
|
2244
|
+
38.65 Each compile `abide dev` makes MUST compile the tree as it stands: what an earlier compile in
|
|
2245
|
+
the same process found MUST NOT change what a later one emits.
|
|
2246
|
+
|
|
2247
|
+
38.66 Each file `abide build` writes MUST replace its predecessor whole, and a build MUST remove from
|
|
2248
|
+
its output only a file it did not produce that was written before it began.
|
|
2249
|
+
|
|
2250
|
+
38.67 `abide start` and the executable's `start` MUST NOT read their input.
|
|
2251
|
+
|
|
2252
|
+
38.68 An `Rpc`'s JSON answer under 1024 bytes MUST be answered in the identity encoding.
|
|
2253
|
+
|
|
2254
|
+
38.69 `abide watch` MUST follow a `GET` per 18.20, and print its value and its value after each
|
|
2255
|
+
`s.patch`.
|
|
2256
|
+
|
|
2257
|
+
38.70 The executable `abide bundle` writes, started on macOS with no command, MUST open a window on
|
|
2258
|
+
the app rather than 38.53's shell, and given a command MUST answer it as 38.50 does.
|
|
2259
|
+
|
|
2260
|
+
38.71 The window `abide bundle`'s executable opens MUST show the launcher page where nothing is
|
|
2261
|
+
remembered, offering to start the app in the process and to connect to one running at a URL.
|
|
2262
|
+
|
|
2263
|
+
38.72 The launcher's start form MUST ask for each field the `onConfig` schema's JSON Schema
|
|
2264
|
+
declares, or each field `onConfig`'s defaults return where the schema has none, and MUST boot the
|
|
2265
|
+
app with its values as the environment, showing a refusal by field.
|
|
2266
|
+
|
|
2267
|
+
38.73 The launcher MUST remember a start's values or a connect's URL under `APP_DATA_DIR`, and MUST
|
|
2268
|
+
start or connect the same way at the next launch.
|
|
2269
|
+
|
|
2270
|
+
38.74 The `disconnect` role MUST stop the app the launcher serves, forget what 38.73 remembered, and
|
|
2271
|
+
show the launcher page.
|
|
2272
|
+
|
|
2273
|
+
38.75 The app `abide bundle`'s launcher serves MUST listen on loopback alone, on the port the last
|
|
2274
|
+
launch served it on where that port is free.
|
|
2275
|
+
|
|
2276
|
+
38.76 Quitting the launcher MUST stop the app it serves through `App.stop` before the process exits.
|
|
2277
|
+
|
|
2278
|
+
38.77 `abide bundle` MUST refuse on a platform other than macOS, naming `abide compile`.
|
|
2279
|
+
|
|
2280
|
+
38.78 `abide bundle` given no `--out` MUST write the `.app` into the directory it was run from, named
|
|
2281
|
+
as 38.46 names the executable.
|
|
2282
|
+
|
|
2283
|
+
38.79 `abide bundle` MUST give the `.app` the icon the public file answered at `/icon.icns` holds,
|
|
2284
|
+
or one drawn at every size from the one at `/icon.png` where there is no `.icns`.
|
|
2285
|
+
|
|
2286
|
+
38.80 The desktop app MUST read the `launcher` that `src/launcher.abide`'s `<script module>`
|
|
2287
|
+
exports as it launches, and MUST refuse to launch on a key it does not take, or a value of a type
|
|
2288
|
+
the key does not take.
|
|
2289
|
+
|
|
2290
|
+
38.81 `LauncherOptions` MUST NOT admit turning off both `start` and `connect`, and the desktop app
|
|
2291
|
+
MUST refuse to launch on a `launcher` that does.
|
|
2292
|
+
|
|
2293
|
+
38.82 Where the app's `src/launcher.abide` has markup of its own, the launcher MUST render it
|
|
2294
|
+
through `render`, bound to the `Launch` it would show, in place of its own page; one holding script
|
|
2295
|
+
blocks alone MUST leave the launcher's own page standing.
|
|
2296
|
+
|
|
2297
|
+
38.83 A form the `launcher` export turns off MUST have no address in `Launch`, MUST NOT be
|
|
2298
|
+
answered, and MUST NOT be done again at launch, and turning `connect` off MUST take the `connect`
|
|
2299
|
+
item out of the default menu bar.
|
|
2300
|
+
|
|
2301
|
+
38.84 The page `src/launcher.abide` renders MUST carry its own `<style>` in the head of the
|
|
2302
|
+
document it renders into.
|
|
2303
|
+
|
|
2304
|
+
38.85 A `src/launcher.abide` that fails to render MUST reach `onError`, and the launcher MUST
|
|
2305
|
+
show its own page in its place.
|
|
2306
|
+
|
|
2307
|
+
38.86 The window MUST open at the `launcher` export's `width` and `height` where no launch
|
|
2308
|
+
before it left a size, and MUST NOT be resized below its `minWidth` and `minHeight`.
|
|
2309
|
+
|
|
2310
|
+
38.87 The app's package name, as 38.46 names the executable, MUST name the app in its bundle, its
|
|
2311
|
+
menu bar and its `Launch`.
|
|
2312
|
+
|
|
2313
|
+
38.88 The desktop app's menu bar MUST be the application, File, Edit, View and Window menus, with
|
|
2314
|
+
the `menu` each layout and the page of the route the window shows exports from its
|
|
2315
|
+
`<script module>`, outermost first: a menu whose `label` names one already standing appends its
|
|
2316
|
+
items to that one, and any other stands before Window.
|
|
2317
|
+
|
|
2318
|
+
38.89 A `MenuItem` whose `MenuRole` AppKit answers MUST be sent down the responder chain, and MUST
|
|
2319
|
+
be disabled where nothing in the chain answers it.
|
|
2320
|
+
|
|
2321
|
+
38.90 Picking a `MenuItem` with an `href` MUST `navigate` to it in the page that exported it.
|
|
2322
|
+
|
|
2323
|
+
38.91 Picking a `menuItem` MUST run every function its `on` filed, in the page that exported it,
|
|
2324
|
+
whether the launcher serves that app or connected to it, and a throw from one MUST NOT stop the
|
|
2325
|
+
rest.
|
|
2326
|
+
|
|
2327
|
+
38.92 The menu bar MUST be told again after every navigation the page makes, and MUST be the
|
|
2328
|
+
default alone from each load the launcher starts until the page loaded tells it its route's `menu`.
|
|
2329
|
+
|
|
2330
|
+
38.93 The executable `abide compile` writes MUST carry the app's code as bytecode, and MUST still
|
|
2331
|
+
report an error at its source line.
|
|
2332
|
+
|
|
2333
|
+
38.94 The chunks `abide build` and `abide dev` emit MUST NOT load, for a route, a module of the
|
|
2334
|
+
framework that no name the route imports reaches.
|
|
2335
|
+
|
|
2336
|
+
38.95 `abide start` MUST compress an answer of 64 KB or more off the event loop, into the bytes the
|
|
2337
|
+
same encoding and quality make on it, and MUST compress a smaller one without yielding.
|
|
2338
|
+
|
|
2339
|
+
38.96 `abide dev` MUST abort a request's signal when its caller hangs up, and when the process
|
|
2340
|
+
answering it is replaced or ended.
|
|
2341
|
+
|
|
2342
|
+
38.97 A stack frame in a module compiled from a `.abide` MUST name the `.abide` and the line written
|
|
2343
|
+
there, under `abide dev`, `abide start` and `abide compile` alike, and the client bundle `abide dev`
|
|
2344
|
+
serves MUST carry a source map placing its positions in the `.abide`; the bundle `abide build` writes
|
|
2345
|
+
MUST NOT carry one.
|
|
2346
|
+
|
|
2347
|
+
38.98 `abide lsp` MUST answer a completion at a member access with the members of what the text it
|
|
2348
|
+
last checked holds there, as 38.39 answers a hover.
|
|
2349
|
+
|
|
2350
|
+
38.99 `abide dev` MUST rebuild when a dependency's `.abide` it compiled changes.
|
|
2351
|
+
|
|
2352
|
+
38.100 `abide start` and `createApp` MUST build the app first where its output holds no build.
|
|
2353
|
+
|
|
2354
|
+
38.101 The launcher's accent MUST be the most saturated hue of the app's icon (38.79), taken when
|
|
2355
|
+
`abide bundle` runs, and the platform's own accent where the icon gives none; `Launch` MUST carry
|
|
2356
|
+
the accent and the icon to `src/launcher.abide`.
|
|
2357
|
+
|
|
2358
|
+
38.102 The launcher's own page MUST show the app's icon, its name and a button for each form the
|
|
2359
|
+
`launcher` export leaves on. A button whose form asks for anything MUST open it in a modal dialog,
|
|
2360
|
+
a start that asks for nothing MUST start at once, a refused start or connect MUST show its dialog
|
|
2361
|
+
open on the refusal, and the `connect` menu role MUST show the connect dialog open.
|
|
2362
|
+
|
|
2363
|
+
38.103 The project `abide scaffold` writes MUST carry a `check` script that runs `abide check`.
|
|
2364
|
+
|
|
2365
|
+
38.104 The project `abide scaffold` writes MUST carry instructions for a coding agent that name where
|
|
2366
|
+
the installed package holds the documentation, the registry and the rulebook.
|
|
2367
|
+
|
|
2368
|
+
38.105 Every clause an `abide check` diagnostic or a refusal cites MUST resolve in a rulebook the
|
|
2369
|
+
published package holds.
|
|
2370
|
+
|
|
2371
|
+
38.106 The documentation the instructions `abide scaffold` writes name (38.104) MUST be every page
|
|
2372
|
+
as one markdown file, in reading order.
|
|
2373
|
+
|
|
2374
|
+
# 39. Head and view transitions
|
|
2375
|
+
|
|
2376
|
+
39.1 A `<head>` element in a `.abide` file MUST contribute its children to the document head.
|
|
2377
|
+
|
|
2378
|
+
39.2 A `<head>` element MUST be top level, and MUST NOT appear inside a control block.
|
|
2379
|
+
|
|
2380
|
+
39.3 The build MUST hoist `<head>` contributions at compile time.
|
|
2381
|
+
|
|
2382
|
+
39.4 `<head>` contributions MUST be merged by key, and the deepest contributor MUST win. The shell's
|
|
2383
|
+
`<head>` MUST be the outermost contributor.
|
|
2384
|
+
|
|
2385
|
+
39.5 A `<head>` contribution with no merge key MUST append in tree order.
|
|
2386
|
+
|
|
2387
|
+
39.6 On a client navigation the incoming page's keyed `<head>` contributions MUST replace the
|
|
2388
|
+
outgoing page's by key, and a layout's MUST NOT move.
|
|
2389
|
+
|
|
2390
|
+
39.7 View transitions MUST be turned on by a `<style>` rule naming a view-transition selector or
|
|
2391
|
+
property, and MUST NOT be turned on by a separate option.
|
|
2392
|
+
|
|
2393
|
+
39.8 Whether an app uses view transitions MUST be decided at build time from the compiled `<style>`
|
|
2394
|
+
blocks, and MUST NOT be decided by a runtime walk of the document's stylesheets.
|
|
2395
|
+
|
|
2396
|
+
39.9 A `view-transition-name` transition MUST be awaited to the point the DOM is written, and MUST
|
|
2397
|
+
NOT be awaited to the end of the animation.
|
|
2398
|
+
|
|
2399
|
+
39.10 A browser with no `view-transition-name` support MUST navigate as it otherwise would, and an
|
|
2400
|
+
app MUST NOT be required to feature-detect.
|
|
2401
|
+
|
|
2402
|
+
39.11 A `<head>` contribution's merge key MUST be the tag for `<title>` and `<base>`, the `name` or
|
|
2403
|
+
`property` attribute for `<meta>`, and `rel` with `href` for `<link>`.
|
|
2404
|
+
|
|
2405
|
+
39.12 The last `<head>` contribution for a key within one file MUST win.
|
|
2406
|
+
|
|
2407
|
+
39.13 In a browser, a `<head>` contribution that reads a value MUST follow it for as long as its page
|
|
2408
|
+
or layout is mounted.
|
|
2409
|
+
|
|
2410
|
+
39.14 On a client navigation, a keyed `<head>` contribution that a leaving page or layout made and
|
|
2411
|
+
no arriving one makes MUST return to the nearest kept layout's value for its key, and MUST be removed
|
|
2412
|
+
where no kept layout has that key.
|
|
2413
|
+
|
|
2414
|
+
# 40. Documentation
|
|
2415
|
+
|
|
2416
|
+
*Free-standing: these clauses govern the documentation system, which REGISTRY does not name — a
|
|
2417
|
+
`<Snippet>` is not something an app writes.*
|
|
2418
|
+
|
|
2419
|
+
40.1 The documentation site MUST be the package at `packages/dogfood`.
|
|
2420
|
+
|
|
2421
|
+
40.2 Every name REGISTRY carries MUST be documented against real `.abide` and `.ts` files.
|
|
2422
|
+
|
|
2423
|
+
40.3 Every `<Example>` SHOULD carry an end-to-end spec.
|
|
2424
|
+
|
|
2425
|
+
40.4 A file an `<Example>` names that is not part of the problem its summary names MUST NOT be
|
|
2426
|
+
one of its files.
|
|
2427
|
+
|
|
2428
|
+
40.5 `<Example>` MUST render the example's component inline, above a tab per file it is made
|
|
2429
|
+
of, and the render MUST NOT be one of those tabs.
|
|
2430
|
+
|
|
2431
|
+
40.6 `<Snippet>` MUST be how a page shows code from an example, in place of pasting it into a
|
|
2432
|
+
fence.
|
|
2433
|
+
|
|
2434
|
+
40.7 A `<Snippet>` anchor MUST be a line prefix matching exactly once, and the slice MUST run to the end
|
|
2435
|
+
of the construct it opens.
|
|
2436
|
+
|
|
2437
|
+
40.8 Several `<Snippet>` anchors separated by an elision MUST render as one fence in file
|
|
2438
|
+
order, with the gap marked rather than closed.
|
|
2439
|
+
|
|
2440
|
+
40.9 A `<Snippet>`'s caption, language and spine MUST be derived from its address.
|
|
2441
|
+
|
|
2442
|
+
40.10 A `<Snippet>` anchor matching none or matching two MUST fail the page it is on as it renders.
|
|
2443
|
+
|
|
2444
|
+
40.11 A page MUST declare in its `SITE` entry's `covers` which REGISTRY names it covers, and an
|
|
2445
|
+
overview or a reference page MUST declare none.
|
|
2446
|
+
|
|
2447
|
+
40.12 Every name `covers` may claim MUST be claimed by exactly one page.
|
|
2448
|
+
|
|
2449
|
+
40.13 The voice, the vocabulary and the register of a title against a nav label MUST be
|
|
2450
|
+
`docs/BRAND.md`'s, and MUST NOT be stated here.
|
|
2451
|
+
|
|
2452
|
+
40.14 An `<Example>` MUST run the component it names in the docs app, and MUST NOT run a
|
|
2453
|
+
stand-in for it.
|
|
2454
|
+
|
|
2455
|
+
40.15 A request an `<Example>` makes MUST be answered by the docs app's own handlers, and MUST
|
|
2456
|
+
NOT be answered by a fixture.
|
|
2457
|
+
|
|
2458
|
+
40.16 Instrumentation the documentation adds to an `<Example>` MUST sit outside the render.
|
|
2459
|
+
|
|
2460
|
+
40.17 A page MUST embed one `<Example>` per behavior it teaches.
|
|
2461
|
+
|
|
2462
|
+
40.18 An `<Example>` MUST demonstrate exactly one behavior.
|
|
2463
|
+
|
|
2464
|
+
40.19 A readout the hand-written arm paired with an `<Example>` renders MUST be one that example's
|
|
2465
|
+
own source names.
|
|
2466
|
+
|
|
2467
|
+
40.20 An `<Example>` MUST be embedded by exactly one page declaring `covers`.
|
|
2468
|
+
|
|
2469
|
+
40.21 An `<Example>` MUST model a pattern from an app `docs/BRAND.md` names.
|
|
2470
|
+
|
|
2471
|
+
40.22 Every `<Example>` a page embeds MUST be drawn from the same app.
|
|
2472
|
+
|
|
2473
|
+
40.23 A control an `<Example>` renders MUST sit with the value it changes.
|
|
2474
|
+
|
|
2475
|
+
40.24 An `<Example>` MUST prove the heading it sits under.
|
|
2476
|
+
|
|
2477
|
+
40.25 An `<Example>` MUST NOT carry code its proof does not need.
|
|
2478
|
+
|
|
2479
|
+
40.26 The capability an `<Example>` proves MUST be one the app it is drawn from would reach
|
|
2480
|
+
for.
|
|
2481
|
+
|
|
2482
|
+
40.27 A heading that carries an `<Example>` MUST be followed by it, with nothing between
|
|
2483
|
+
them.
|
|
2484
|
+
|
|
2485
|
+
40.28 An `<Example>`'s summary MUST state the situation it is in, and MUST NOT restate the
|
|
2486
|
+
heading.
|
|
2487
|
+
|
|
2488
|
+
40.29 A comment in an `<Example>`'s own source MUST fit on one line, and a reason longer than
|
|
2489
|
+
that MUST go in the copy after the card.
|
|
2490
|
+
|
|
2491
|
+
40.30 A page's lead MUST read standalone, being what a section overview shows for that page, and
|
|
2492
|
+
MUST NOT carry a relative link.
|
|
2493
|
+
|
|
2494
|
+
40.31 A page whose `covers` names one REGISTRY entry SHOULD open on a section giving that entry's
|
|
2495
|
+
forms, the options they share, and a link to its reference page.
|
|
2496
|
+
|
|
2497
|
+
40.32 A page reporting the build's own results MUST NOT be listed in `SITE`.
|
|
2498
|
+
|
|
2499
|
+
40.33 A documentation page MUST be a `page.abide` written by hand at its route, and its title, nav
|
|
2500
|
+
label, intent, lead, app and `covers` MUST be its `SITE` entry's alone.
|
|
2501
|
+
|
|
2502
|
+
40.34 An `<Example>` MUST render a component in the directory of the page that embeds it, and that
|
|
2503
|
+
component's handlers, hooks and data MUST be in its own file, save a file the example is about.
|
|
2504
|
+
|
|
2505
|
+
40.35 A page's `.md` twin MUST be derived from what its `page.abide` renders.
|
|
2506
|
+
|
|
2507
|
+
# 41. Rendering and hydration
|
|
2508
|
+
|
|
2509
|
+
41.1 `render` MUST send nothing until the page and every layout around it are set up and built, and a
|
|
2510
|
+
refusal or a throw before then MUST be answered at its own status by the nearest `error.abide`.
|
|
2511
|
+
|
|
2512
|
+
41.2 A render MUST start every asynchronous read up front and in parallel.
|
|
2513
|
+
|
|
2514
|
+
41.3 `render` MUST NOT be held for an unfinished stream: what the stream produced MUST go out
|
|
2515
|
+
inline, and the rest MUST be picked up by the client's own request.
|
|
2516
|
+
|
|
2517
|
+
41.4 A render MUST continue past a value still in flight, opening the sink 3.4 opens.
|
|
2518
|
+
|
|
2519
|
+
41.5 Data MUST reach a browser by answering that browser's own `Rpc` call from the seed buffer, and
|
|
2520
|
+
a document MUST NOT carry a copy of an answer.
|
|
2521
|
+
|
|
2522
|
+
41.6 Hydration MUST re-execute setup: every `<script>` and every `reactive` body runs
|
|
2523
|
+
again, and a serialized setup result MUST NOT be adopted.
|
|
2524
|
+
|
|
2525
|
+
41.7 The `Rpc` calls that re-execution makes MUST be answered from the seed buffer.
|
|
2526
|
+
|
|
2527
|
+
41.8 A `{#for}` block over a value the server already painted MUST be reconciled against that value by
|
|
2528
|
+
the block's key once it lands, and MUST NOT be appended to.
|
|
2529
|
+
|
|
2530
|
+
41.9 `render` MUST delimit a dynamic region with a comment anchor, and MUST NOT add a node, an
|
|
2531
|
+
attribute or a wrapper to the document for any other purpose than 41.20's script.
|
|
2532
|
+
|
|
2533
|
+
41.10 A hydration mismatch MUST rebuild the enclosing block and MUST NOT rebuild the page, warning
|
|
2534
|
+
on `abide:hydrate`.
|
|
2535
|
+
|
|
2536
|
+
41.11 A shared `layout.abide` MUST NOT be rebuilt between navigations.
|
|
2537
|
+
|
|
2538
|
+
41.12 An `Rpc` call the seed buffer cannot answer MUST fall through to running the handler, and
|
|
2539
|
+
MUST warn on `abide:hydrate`.
|
|
2540
|
+
|
|
2541
|
+
41.13 The seed buffer MUST be filled from the production the render already had, and a handler
|
|
2542
|
+
MUST NOT be run a second time to fill it.
|
|
2543
|
+
|
|
2544
|
+
41.14 A `{#for}` key the list repeats MUST reconcile the last row under that key, and MUST stop and
|
|
2545
|
+
remove every row it shadows.
|
|
2546
|
+
|
|
2547
|
+
41.15 A repeated `{#for}` key MUST warn once for the block on `abide:hydrate`.
|
|
2548
|
+
|
|
2549
|
+
41.16 A seed buffer entry MUST answer one `Rpc` call, and MUST be dropped once it has.
|
|
2550
|
+
|
|
2551
|
+
41.17 A seed buffer entry no `Rpc` call takes MUST be dropped 30 seconds after the `render` that
|
|
2552
|
+
filled it.
|
|
2553
|
+
|
|
2554
|
+
41.18 A seed buffer entry MUST be matched by `principal.caller`, the handler and the call's `Args`
|
|
2555
|
+
key.
|
|
2556
|
+
|
|
2557
|
+
41.19 A `render` MUST set up a page and every layout around it, and let the turn's queued microtasks
|
|
2558
|
+
run, before it builds any of their markup.
|
|
2559
|
+
|
|
2560
|
+
41.20 A `render` MUST write one inline script into the head once setup has run and before any
|
|
2561
|
+
markup, starting each `Rpc` call the setup made as the request the browser's `Rpc` makes for it.
|
|
2562
|
+
|
|
2563
|
+
41.21 The browser's `Rpc` MUST take a call 41.20's script started in place of making it, once.
|
|
2564
|
+
|
|
2565
|
+
41.22 An `Rpc` call for args a seed buffer entry already answered MUST NOT warn on
|
|
2566
|
+
`abide:hydrate`.
|
|
2567
|
+
|
|
2568
|
+
41.23 On the client, a `layout.abide` MUST NOT hydrate or build its markup before
|
|
2569
|
+
the page under it is set up.
|
|
2570
|
+
|
|
2571
|
+
41.24 Where hydration's setup chooses an arm of an `{#if cond}` other than the one the server painted,
|
|
2572
|
+
or no component for a `<Name/>` under 32.34 the server painted one for, the region MUST be filled
|
|
2573
|
+
from the choice rather than adopted, warning on `abide:hydrate`.
|
|
2574
|
+
|
|
2575
|
+
41.25 Hydration MUST NOT set up a page until every `Rpc` call `render` built its markup from settled
|
|
2576
|
+
has answered or failed.
|
|
2577
|
+
|
|
2578
|
+
41.26 An `Rpc` call answering a stream MUST NOT be waited for under 41.25.
|
|
2579
|
+
|
|
2580
|
+
41.27 An `Rpc` call `render` built the page's markup from in flight MUST be in flight as hydration
|
|
2581
|
+
adopts the page, however early its answer arrived.
|
|
2582
|
+
|
|
2583
|
+
# 42. The app object
|
|
2584
|
+
|
|
2585
|
+
42.1 `createApp` MUST build the route table and compose every `Middleware` rung, per 16.14.
|
|
2586
|
+
|
|
2587
|
+
42.2 `createApp` MUST read `config` where it builds the app, and MUST NOT leave that read to the
|
|
2588
|
+
first request.
|
|
2589
|
+
|
|
2590
|
+
42.3 `createApp` MUST NOT bind a socket.
|
|
2591
|
+
|
|
2592
|
+
42.4 A hook `onStart` wraps MUST NOT observe the port.
|
|
2593
|
+
|
|
2594
|
+
42.5 `App.fetch` MUST answer a `Request` where no socket is bound.
|
|
2595
|
+
|
|
2596
|
+
42.6 `App.fetch` MUST be `App.run` with dispatch over it, and MUST NOT be a second scope
|
|
2597
|
+
constructor.
|
|
2598
|
+
|
|
2599
|
+
42.7 `App.run` MUST run its function in one scope, and MUST hand back what that function returned.
|
|
2600
|
+
|
|
2601
|
+
42.8 A `Request` on `App.run` MUST be optional, and a scope made without one MUST be the scope 22.1
|
|
2602
|
+
and 22.8 throw in.
|
|
2603
|
+
|
|
2604
|
+
42.9 `App.listen` MUST be where the socket is bound, and MUST be what supplies `server`.
|
|
2605
|
+
|
|
2606
|
+
42.10 `App.stop` MUST stop accepting and drain what is in flight before `onStop` runs.
|
|
2607
|
+
|
|
2608
|
+
42.11 `App.stop` MUST end every stream it is still answering, close every open socket, and drop every
|
|
2609
|
+
seed entry its renders left, with its timer.
|
|
2610
|
+
|
|
2611
|
+
42.12 A second `App` in one process MUST share the first's `config` and `global` entries, per 27.9 and
|
|
2612
|
+
11.34.
|
|
2613
|
+
|
|
2614
|
+
42.13 A test MUST reach a handler through the same `App` a host holds, and abide MUST NOT generate a
|
|
2615
|
+
client of its own for one.
|
|
2616
|
+
|
|
2617
|
+
42.14 `App[Symbol.asyncDispose]` MUST be `App.stop`, so an `App` held by `await using` MUST stop as
|
|
2618
|
+
42.10 and 42.11 do when its scope exits.
|
|
2619
|
+
|
|
2620
|
+
42.15 `App.stop` asked again while the app is stopping MUST answer with the stop under way, and
|
|
2621
|
+
`onStop` MUST run once.
|
|
2622
|
+
|
|
2623
|
+
42.16 Under `bun test`, `createApp` MUST build the app at most once per state of its sources and
|
|
2624
|
+
the framework's, MUST NOT boot a build that state did not make, and MUST NOT require a prior
|
|
2625
|
+
`abide build`.
|
|
2626
|
+
|
|
2627
|
+
# 44. The measurement harness
|
|
2628
|
+
|
|
2629
|
+
*Free-standing: these clauses govern the measurement harness, which REGISTRY does not name — a
|
|
2630
|
+
`Sample` is not something an app writes.*
|
|
2631
|
+
|
|
2632
|
+
44.1 `harness/measure`, `harness/engine` and `harness/server` MUST each be reachable through only
|
|
2633
|
+
the dependency each is named for, and `harness/report` MUST have none.
|
|
2634
|
+
|
|
2635
|
+
44.2 A `Work` record MUST partition nodes moved by node kind, and MUST NOT carry a total across
|
|
2636
|
+
those kinds.
|
|
2637
|
+
|
|
2638
|
+
44.3 A DOM member `harness/measure` does not count MUST throw naming that member while a case is
|
|
2639
|
+
armed.
|
|
2640
|
+
|
|
2641
|
+
44.4 A patched member MUST tally only where no patched member is already tallying, and
|
|
2642
|
+
`harness/measure` MUST install its patches once for the process.
|
|
2643
|
+
|
|
2644
|
+
44.5 The patch set `harness/measure` installs MUST be the same list of interfaces and members in
|
|
2645
|
+
both substrates.
|
|
2646
|
+
|
|
2647
|
+
44.6 A `Work` record MUST NOT carry a duration, and `time` MUST throw while the counters are armed.
|
|
2648
|
+
|
|
2649
|
+
44.7 A floor MUST be measured by running one arm twice under its own name, and `ratio` MUST report
|
|
2650
|
+
a value inside that floor as a tag rather than as a number.
|
|
2651
|
+
|
|
2652
|
+
44.8 `batch` MUST interleave its arms, and MUST NOT run one arm in a block.
|
|
2653
|
+
|
|
2654
|
+
44.9 A `gate` MUST carry a revert installing the broken arm and what that arm reports, and a revert
|
|
2655
|
+
leaving the gate passing MUST be reported as a failure.
|
|
2656
|
+
|
|
2657
|
+
44.10 `ratio` MUST throw where two samples disagree on substrate, on case or on batch size, and
|
|
2658
|
+
where one arm is given twice.
|
|
2659
|
+
|
|
2660
|
+
44.11 A `Sample` MUST be at least 100 times the clock's measured resolution, and `batch` MUST throw
|
|
2661
|
+
rather than report a smaller one.
|
|
2662
|
+
|
|
2663
|
+
44.12 A refusal MUST be taken where the `Sample` is constructed, and MUST NOT be deferred to where
|
|
2664
|
+
it is reported.
|
|
2665
|
+
|
|
2666
|
+
44.13 `shares` MUST take the trace, the layer, the denominator and a threshold, and MUST throw
|
|
2667
|
+
where the layer runs outside the denominator.
|
|
2668
|
+
|
|
2669
|
+
44.14 `shares` MUST report an observed ceiling of zero for an op under one frame.
|
|
2670
|
+
|
|
2671
|
+
44.15 A count of calls MUST be taken with `spyOn`.
|
|
2672
|
+
|
|
2673
|
+
44.16 `retained` MUST throw in a process with a DOM.
|
|
2674
|
+
|
|
2675
|
+
44.17 `allocated` MUST report a batch mean, and MUST NOT report a count an exact integer can be
|
|
2676
|
+
compared against.
|
|
2677
|
+
|
|
2678
|
+
44.18 `batch` MUST throw in a parallel worker.
|
|
2679
|
+
|
|
2680
|
+
44.19 A hand-written arm under `harness/arms` MUST be paired with an `<Example>` of the same id.
|
|
2681
|
+
|
|
2682
|
+
44.20 `measure` MUST report `wakes`, `bindingRuns` and `descents` as absent where no record has been
|
|
2683
|
+
published, and MUST NOT report zero for one.
|
|
2684
|
+
|
|
2685
|
+
44.21 A published record MUST carry every field `measure` reads off it as a number, and `measure`
|
|
2686
|
+
MUST throw naming each field that is absent.
|
|
2687
|
+
|
|
2688
|
+
44.22 A counter `measure` reads rather than counts MUST be published as a fixed-shape record
|
|
2689
|
+
reached through `globalThis.__ABIDE_WORK__`.
|
|
2690
|
+
|
|
2691
|
+
44.23 `batch` MUST throw on a duration whose op touched an emulated DOM.
|
|
2692
|
+
# 45. The assistant
|
|
2693
|
+
|
|
2694
|
+
45.1 `assistant` MUST answer only through a handler that yields it, and MUST NOT mount an address
|
|
2695
|
+
of its own.
|
|
2696
|
+
|
|
2697
|
+
45.2 `assistant` MUST yield the same `AssistantEvent` sequence for one conversation whichever
|
|
2698
|
+
`Provider` ran it.
|
|
2699
|
+
|
|
2700
|
+
45.3 `assistant` MUST refuse 400, before any `Provider` is reached, a transcript whose last
|
|
2701
|
+
`AssistantMessage` is not the user's.
|
|
2702
|
+
|
|
2703
|
+
45.4 `assistant` MUST hold no conversation between calls, and MUST take the whole transcript with
|
|
2704
|
+
each one.
|
|
2705
|
+
|
|
2706
|
+
45.5 `claudeCode` MUST send a transcript to Claude Code as one message, its earlier turns folded
|
|
2707
|
+
above the last.
|
|
2708
|
+
|
|
2709
|
+
45.6 With `mcp`, the `Toolbox` `assistant` hands a `Provider` MUST list the tools `/__abide/mcp`
|
|
2710
|
+
lists, and MUST call each as a request through the app answering the request.
|
|
2711
|
+
|
|
2712
|
+
45.7 A `Toolbox` call MUST carry the asking request's `cookie` and `authorization` headers, and MUST
|
|
2713
|
+
NOT carry any other header of it.
|
|
2714
|
+
|
|
2715
|
+
45.8 `mcp` over an app whose route table lists no handler for `/__abide/mcp` MUST throw.
|
|
2716
|
+
|
|
2717
|
+
45.9 `claudeApi` MUST call the Messages API again with the tool results only while a turn stops for
|
|
2718
|
+
`tool_use`, and MUST send each assistant turn's blocks back as they arrived.
|
|
2719
|
+
|
|
2720
|
+
45.10 `claudeApi` MUST throw where no `apiKey` is given, and MUST NOT read a key from the
|
|
2721
|
+
environment.
|
|
2722
|
+
|
|
2723
|
+
45.11 A conversation reaching `maxTurns` with a tool call pending MUST end on a `done` whose `stop`
|
|
2724
|
+
is `max_turns`, and MUST NOT run that call.
|
|
2725
|
+
|
|
2726
|
+
45.12 `claudeApi` MUST send the results of one turn's tool calls back in one message.
|
|
2727
|
+
|
|
2728
|
+
45.13 `claudeCode` MUST run a turn on the Claude Code of the bridge paired with the asking browser,
|
|
2729
|
+
and MUST refuse 409 where none is paired.
|
|
2730
|
+
|
|
2731
|
+
45.14 A code `claudeCode.bridgeCommand` mints MUST pair one bridge with the browser that asked for
|
|
2732
|
+
it, once, and MUST NOT pair once it has expired.
|
|
2733
|
+
|
|
2734
|
+
45.15 A bridge MUST run Claude Code with its built-in tools off, no setting source read and no MCP
|
|
2735
|
+
server but the bridge's own, in an empty directory removed when the run ends.
|
|
2736
|
+
|
|
2737
|
+
45.16 A bridge MUST take from the site no Claude Code option `ClaudeCodeConfig` does not name.
|
|
2738
|
+
|
|
2739
|
+
45.17 An MCP request a bridge's Claude Code makes MUST be answered from the `Toolbox` of the turn it
|
|
2740
|
+
was made in.
|
|
2741
|
+
|
|
2742
|
+
45.18 `claudeCode` MUST end a turn's run on the bridge when the caller hangs up.
|
|
2743
|
+
|
|
2744
|
+
45.19 `/__abide/bridge` MUST be closed until `claudeCode` has minted a pairing code in that process.
|
|
2745
|
+
|
|
2746
|
+
45.20 `claudeCode.bridge` MUST yield a `BridgeStatus` whenever the asking browser's pairing changes,
|
|
2747
|
+
and MUST yield a fresh command where the standing one's code expires unpaired.
|
|
2748
|
+
|
|
2749
|
+
45.21 A failure the Messages API reports to `claudeApi`, or a bridge reports to `claudeCode`, MUST
|
|
2750
|
+
refuse 502.
|
|
2751
|
+
|
|
2752
|
+
45.22 A bridge `claudeCode.bridge` has watched MUST be sent away once nothing watches it and it has
|
|
2753
|
+
run no turn for 30 seconds.
|