@abide/abide 0.123.2 → 0.124.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ABIDE.md +8 -5
- package/CHANGELOG.md +58 -0
- package/bin/abide.ts +36 -65
- package/docs/REGISTRY.md +45 -12
- package/docs/RULEBOOK.md +24 -14
- package/docs/abide.md +999 -459
- package/package.json +1 -1
- package/src/compiler/ARRAY_MUTATORS.ts +20 -0
- package/src/compiler/Diagnostics.ts +198 -0
- package/src/compiler/KeptChecker.ts +97 -0
- package/src/compiler/LoweredFile.ts +609 -0
- package/src/compiler/Lowering.ts +18 -1
- package/src/compiler/PositionedRefusal.ts +1 -1
- package/src/compiler/SHARED_NAMES.ts +2 -0
- package/src/compiler/ShadowHost.ts +670 -0
- package/src/compiler/ShadowMap.ts +1 -1
- package/src/compiler/TypeSession.ts +76 -1743
- package/src/compiler/appLayout.ts +28 -20
- package/src/compiler/appLints.ts +109 -0
- package/src/compiler/argsDefaultsIn.ts +1 -1
- package/src/compiler/checkApp.ts +64 -68
- package/src/compiler/checkedShadow.ts +2 -2
- package/src/compiler/classifyRead.ts +16 -1
- package/src/compiler/compileApp.ts +102 -71
- package/src/compiler/declaredExports.ts +46 -21
- package/src/compiler/diagnoseSources.ts +232 -0
- package/src/compiler/emitClient.ts +1 -1
- package/src/compiler/formatAbide.ts +7 -8
- package/src/compiler/handlersUnder.ts +32 -63
- package/src/compiler/lineOf.ts +0 -19
- package/src/compiler/matchersOf.ts +3 -3
- package/src/compiler/mountsOf.ts +3 -3
- package/src/compiler/reactiveReads.ts +235 -0
- package/src/compiler/reactiveTypes.ts +13 -0
- package/src/compiler/readSources.ts +16 -18
- package/src/compiler/readsIn.ts +181 -82
- package/src/compiler/routesDeclaration.ts +46 -0
- package/src/compiler/scaffold.ts +7 -2
- package/src/compiler/serveLanguage.ts +46 -74
- package/src/compiler/sharedModuleWrites.ts +1 -1
- package/src/compiler/splitImports.ts +2 -2
- package/src/compiler/templateWarnings.ts +1 -2
- package/src/compiler/trackingWarnings.ts +1 -1
- package/src/server/CLIENT_BUILD.ts +4 -32
- package/src/server/DesktopSession.ts +213 -0
- package/src/server/Followers.ts +399 -0
- package/src/server/MODULE_QUERIES.ts +6 -2
- package/src/server/PageRender.ts +201 -0
- package/src/server/RESUME_MILLISECONDS.ts +2 -0
- package/src/server/abideModules.ts +7 -7
- package/src/server/answerFailure.ts +3 -2
- package/src/server/answerRequest.ts +16 -369
- package/src/server/answerRpc.ts +48 -302
- package/src/server/answerSocket.ts +41 -490
- package/src/server/appBuild.ts +377 -0
- package/src/server/appKit.ts +1 -1
- package/src/server/appPlugins.ts +15 -17
- package/src/server/appTree.ts +6 -5
- package/src/server/argsContract.ts +209 -0
- package/src/server/bridgeRelay.ts +153 -65
- package/src/server/claudeCode.ts +30 -127
- package/src/server/config.ts +6 -7
- package/src/server/createApp.ts +38 -66
- package/src/server/csp.ts +1 -1
- package/src/server/deferredBuilds.ts +3 -16
- package/src/server/devWorker.ts +11 -15
- package/src/server/faceOf.ts +1 -1
- package/src/server/generatedSurfaces.ts +2 -1
- package/src/server/handlerFileMount.ts +40 -0
- package/src/server/index.ts +3 -3
- package/src/server/installServer.ts +5 -9
- package/src/server/invokeHandler.ts +230 -0
- package/src/server/mountHandlers.ts +184 -0
- package/src/server/openDesktopWindow.ts +308 -0
- package/src/server/packageDirectory.ts +14 -0
- package/src/server/preload.ts +21 -2
- package/src/server/principal.ts +5 -4
- package/src/server/remote.ts +2 -2
- package/src/server/render.ts +31 -59
- package/src/server/requestScope.ts +5 -36
- package/src/server/runCompiled.ts +1 -1
- package/src/server/runDesktop.ts +20 -448
- package/src/server/seedBuffer.ts +12 -12
- package/src/server/serveDev.ts +24 -58
- package/src/server/servedApp.ts +390 -0
- package/src/server/shell.ts +1 -1
- package/src/server/signInChanged.ts +20 -0
- package/src/server/surfaceOf.ts +3 -2
- package/src/server/versionOf.ts +7 -16
- package/src/shared/RPC_SERVER.ts +27 -31
- package/src/shared/Schema.ts +1 -2
- package/src/shared/applyPatch.ts +1 -1
- package/src/shared/index.ts +1 -1
- package/src/shared/{note.ts → issueReport.ts} +22 -0
- package/src/shared/loadCall.ts +66 -0
- package/src/shared/muxFrames.ts +1 -1
- package/src/shared/reactive/Keyed.ts +24 -16
- package/src/shared/reactive/Reactive.ts +37 -991
- package/src/shared/reactive/argsContract.ts +131 -4
- package/src/shared/reactive/byOf.ts +2 -5
- package/src/shared/reactive/callLoad.ts +8 -14
- package/src/shared/reactive/cellShape.ts +734 -0
- package/src/shared/reactive/index.ts +12 -23
- package/src/shared/reactive/pairReactive.ts +5 -3
- package/src/shared/reactive/patchLog.ts +79 -0
- package/src/shared/reactive/patchMarks.ts +34 -0
- package/src/shared/reactive/producer.ts +121 -0
- package/src/shared/reactive/recordWrites.ts +11 -14
- package/src/shared/reactive/scoped.ts +3 -2
- package/src/shared/reactive/selections.ts +209 -0
- package/src/shared/reactive/share.ts +4 -3
- package/src/shared/reactive/watch.ts +3 -4
- package/src/shared/rpc.ts +20 -24
- package/src/shared/validateJson.ts +1 -2
- package/src/shared/writePath.ts +29 -0
- package/src/ui/ArmRegion.ts +10 -4
- package/src/ui/Level.ts +11 -20
- package/src/ui/LevelChain.ts +272 -0
- package/src/ui/Router.ts +106 -313
- package/src/ui/Scope.ts +17 -3
- package/src/ui/TryRegion.ts +22 -23
- package/src/ui/bindSpread.ts +2 -4
- package/src/ui/listenForRoutes.ts +3 -10
- package/src/ui/outboxQueue.ts +23 -11
- package/src/ui/outcomeOf.ts +120 -0
- package/src/ui/reconcile.ts +4 -6
- package/src/ui/routing.ts +2 -1
- package/src/ui/rows.ts +2 -2
- package/src/ui/setAttribute.ts +12 -3
- package/src/ui/socketWire.ts +28 -13
- package/src/ui/wire.ts +9 -10
- package/src/compiler/Finding.ts +0 -2
- package/src/compiler/Refusals.ts +0 -65
- package/src/compiler/formatDiagnosis.ts +0 -20
- package/src/server/appDirectories.ts +0 -9
- package/src/server/argsFor.ts +0 -39
- package/src/server/buildDirectory.ts +0 -10
- package/src/server/coerceArgs.ts +0 -109
- package/src/server/derivedArgs.ts +0 -26
- package/src/server/runBuild.ts +0 -24
- package/src/server/serveBuild.ts +0 -144
- package/src/server/testBuild.ts +0 -220
- package/src/shared/LOAD_OFFLINE.ts +0 -15
- package/src/shared/LOAD_SIGNAL.ts +0 -10
- package/src/shared/issuesOf.ts +0 -18
- package/src/shared/reactive/ENTRY_LIVES.ts +0 -7
- package/src/shared/reactive/FOLLOWED.ts +0 -8
- package/src/shared/reactive/PATCHES.ts +0 -11
- package/src/shared/reactive/PATCH_SINKS.ts +0 -26
- package/src/shared/reactive/canonicalKey.ts +0 -95
package/ABIDE.md
CHANGED
|
@@ -7,7 +7,7 @@ rather than guessing from Svelte, Vue or React. It installs with the package:
|
|
|
7
7
|
|
|
8
8
|
- `node_modules/@abide/abide/docs/abide.md` — every documentation page in reading order, with a
|
|
9
9
|
working example for each task. It is long: read its Contents, then search for the page's
|
|
10
|
-
address, which heads each page as a comment — `<!--
|
|
10
|
+
address, which heads each page as a comment — `<!-- guide/keep-it-current.md -->`.
|
|
11
11
|
- `node_modules/@abide/abide/docs/REGISTRY.md` — every name an app can import or write, with its
|
|
12
12
|
signature and the rules that govern it.
|
|
13
13
|
- `node_modules/@abide/abide/docs/RULEBOOK.md` — every rule, numbered. A compiler or server
|
|
@@ -46,6 +46,8 @@ affected code saying what it did, and tell the user.
|
|
|
46
46
|
your changes are done.
|
|
47
47
|
- `bun run dev` — serves the app on a local port and rebuilds when a file changes.
|
|
48
48
|
- `bun run build` then `bun run start` — the production build, and the app served from it.
|
|
49
|
+
- `docker build .` — the scaffold's `Dockerfile` runs `abide compile` and ships the one executable it
|
|
50
|
+
writes on a distroless image, and nothing else of the app (RULEBOOK 38.132).
|
|
49
51
|
|
|
50
52
|
## Layout
|
|
51
53
|
|
|
@@ -91,11 +93,12 @@ affected code saying what it did, and tell the user.
|
|
|
91
93
|
- Change part of a value by writing through its path — `edits.kind = kind`, `items.push(item)`
|
|
92
94
|
(RULEBOOK 31.8, 31.9) — not by rebuilding it (`edits = { ...edits, kind }`,
|
|
93
95
|
`items = [...items, item]`). Bind through the path too: `bind:value={edits.kind}` (32.5), not a
|
|
94
|
-
`{ get, set }` pair. In a `.ts` file the same write is
|
|
95
|
-
not `edits.set({ ...edits(), kind })`.
|
|
96
|
+
`{ get, set }` pair. In a `.ts` file the same write is
|
|
97
|
+
`edits.patch((value) => { value.kind = kind })`, not `edits.set({ ...edits(), kind })`.
|
|
96
98
|
- Derive a value with `reactive(() => …)`. `watch` is only for reaching outside the reactive graph —
|
|
97
|
-
the DOM, a timer, an imperative API — and never assigns state
|
|
98
|
-
|
|
99
|
+
the DOM, a timer, an imperative API — and its run never assigns state, a value computed from what
|
|
100
|
+
it read being a derived value. What a timer or a call it started hands back is written when that
|
|
101
|
+
lands, the way an event handler writes. A user action's effect belongs in its event handler. A `watch` runs during a server render too (RULEBOOK 12.5), so one that starts a
|
|
99
102
|
timer or touches a browser global returns a `Disposer`.
|
|
100
103
|
- A preference the page renders — a currency, a theme, a panel left open — lives in a cookie:
|
|
101
104
|
`const theme = reactive(() => cookies().get('theme') ?? 'light')`, written with
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,63 @@
|
|
|
1
1
|
# @abide/abide
|
|
2
2
|
|
|
3
|
+
## 0.124.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 057aef8: `TypeSession` (from `@abide/abide/compiler`) no longer carries `hold`, `projectWith` or `projectionOf`. Every analysis now asks the shadow program through one `ShadowHost`, which owns the snapshot a question runs against, so a caller no longer holds the session and reaches for a raw project by hand.
|
|
8
|
+
- 1a7baec: `abide scaffold` writes a Dockerfile and `.dockerignore`: the app built with `abide compile` on the bun that scaffolded it, and an image on distroless holding the executable alone (RULEBOOK 38.132).
|
|
9
|
+
|
|
10
|
+
### Patch Changes
|
|
11
|
+
|
|
12
|
+
- b50ba69: ABIDE.md points at a page address the bundled docs really carry (`guide/keep-it-current.md`), and names the scaffold's Dockerfile and `abide compile` (RULEBOOK 38.132)
|
|
13
|
+
- d3cee54: ABIDE.md says what a `watch` may write: its run assigns no state, and what a timer or a call it started hands back is written when that lands, as an event handler writes
|
|
14
|
+
- de50907: followers owned per app and passed to the mux ([`19e48d5`](https://github.com/briancray/abide/commit/19e48d5d12bdd12e648867e213442cdba0425cc1))
|
|
15
|
+
- de50907: a ShadowHost every analysis asks through, and one reads fixed point ([`1d3e371`](https://github.com/briancray/abide/commit/1d3e3710a5c42c09b44004b5142b47e09bcb20c6))
|
|
16
|
+
- de50907: split runDesktop into a DesktopSession and the window it drives ([`2174dc2`](https://github.com/briancray/abide/commit/2174dc22fea7c092b5ccf10807fd747fd632416c))
|
|
17
|
+
- 5221322: each test file under the test preload starts cold, so a file passes whatever order bun runs the files in — 38.133 ([`2afa677`](https://github.com/briancray/abide/commit/2afa67778caa5a15248d00cb6219078995b2d342))
|
|
18
|
+
- de50907: the selection index into selections.ts ([`4c58131`](https://github.com/briancray/abide/commit/4c581310ba08ccceaf213600b6f8166e186195c5))
|
|
19
|
+
- de50907: one issueReport module for note and issuesOf ([`4d2b85d`](https://github.com/briancray/abide/commit/4d2b85d88da14b474eaa7979347e5ca6ffc6e837))
|
|
20
|
+
- de50907: editor questions asked of the lowering a check registered ([`57d65a8`](https://github.com/briancray/abide/commit/57d65a8c009d4e4b3a740362e7e85ee97a9e3b10))
|
|
21
|
+
- de50907: one module owns the call starting a load ([`8331a7d`](https://github.com/briancray/abide/commit/8331a7df809e0f851a3ebb1d4b99f0b708d1d2be))
|
|
22
|
+
- de50907: a producer port for the verbs outside the core spend ([`84bfbbd`](https://github.com/briancray/abide/commit/84bfbbddcc96ed6dbaec78348d279c5873269698))
|
|
23
|
+
- de50907: one handler invocation for the http and socket lanes ([`8828727`](https://github.com/briancray/abide/commit/8828727a3c2fa24b8c5b37ef8b580aaaf874c0d2))
|
|
24
|
+
- de50907: declare the Cell shape once, in cellShape.ts ([`8fee2f4`](https://github.com/briancray/abide/commit/8fee2f49e63535e92e59240531669794b6f23b16))
|
|
25
|
+
- de50907: the reads fixed point returns its answers rather than filling the caller's ([`c704569`](https://github.com/briancray/abide/commit/c7045690405bb633c329a5252429485eca03d5c8))
|
|
26
|
+
- de50907: decide a navigation's outcome in a pure outcomeOf, executed by Router ([`dc055fc`](https://github.com/briancray/abide/commit/dc055fc290782ebd9b4ea50b0db23a4c408835a4))
|
|
27
|
+
- de50907: one page-render session owns seeding, recording and early calls ([`fcfb07a`](https://github.com/briancray/abide/commit/fcfb07aa398cedafdbd5cef87cecb022c712f6fa))
|
|
28
|
+
- d870b05: `abide format` opens an expression `bun fmt` breaks onto lines of its own at its brace — `{name` rather than `{ name` — the first line outdented like the rest (RULEBOOK 38.126).
|
|
29
|
+
- 5e3caa6: An array mutator called on a reactive name in a `.abide` file is a write: `tags.push(tag)`, `deal.notes.splice(0, 1)` and the rest run on a copy that the name then holds, so the page repaints (RULEBOOK 31.9). The receiver's type decides it — a class's own `push` or a `Map`'s `set` is still the value's call. ABIDE.md names `items.push(item)` as the write again.
|
|
30
|
+
- 2350996: A page's module, and every module it imports, is now evaluated outside the request that first renders it. In an executable `abide compile` writes, a module's `reactive` was built as the first request's own rather than per request, so whatever that request left — a signed-out caller's refusal — stood for every caller after it (RULEBOOK 11.67).
|
|
31
|
+
- d98f382: `abide scaffold`'s `bunfig.toml` comments fit the 80-column line the formatter prints.
|
|
32
|
+
- 37dddd1: A file with no extension imported `with { type: 'text' }` — a `Dockerfile`, a `LICENSE`, a `Makefile` — is its text under `abide dev` and `abide start`, where the page used to answer 500 (RULEBOOK 34.21).
|
|
33
|
+
|
|
34
|
+
## 0.123.3
|
|
35
|
+
|
|
36
|
+
### Patch Changes
|
|
37
|
+
|
|
38
|
+
- abfff21: Router's doc names the LevelChain that stops a page's scope ([`00c3d2d`](https://github.com/briancray/abide/commit/00c3d2d8038c673e5a067b01402b0d270fa485b8))
|
|
39
|
+
- abfff21: a spread writes through setAttribute's compare-then-write (writeAttribute) ([`017a6ff`](https://github.com/briancray/abide/commit/017a6ff26a1e9ba460973b63b2c8ffc5f9e2f863))
|
|
40
|
+
- abfff21: the routed mount argument comment names LevelChain.mountFrom ([`0942e6e`](https://github.com/briancray/abide/commit/0942e6e9d6545dd24d41579fd5ec28e9478892d9))
|
|
41
|
+
- abfff21: a patch-log release run twice leaves a log a later follower opened ([`206d8df`](https://github.com/briancray/abide/commit/206d8dfde626592eb5ca885567f30afeed6b0b6e))
|
|
42
|
+
- abfff21: one patch log for followed values, and patch marks behind functions ([`3cdda11`](https://github.com/briancray/abide/commit/3cdda118d9a8ed4cbd32834c8cd7823c26f0b5fb))
|
|
43
|
+
- abfff21: one args contract for every way a handler is called ([`4e2dcab`](https://github.com/briancray/abide/commit/4e2dcab0bddaf555404fc22687e2efd41d28b500))
|
|
44
|
+
- abfff21: the {#try} ambient is Scope's private, set only through underBoundary; TryRegion swaps through ArmRegion's fills/armOf ([`54e6a91`](https://github.com/briancray/abide/commit/54e6a9158bd9fe167578479a3ce4669d13797457))
|
|
45
|
+
- abfff21: a file the layout has not seen is checked as painting only where it paints ([`587597f`](https://github.com/briancray/abide/commit/587597f23cdeb331816049ff0670b99eebcb1cd8))
|
|
46
|
+
- abfff21: one diagnostics sink owns the finding type, its placement, abide-ignore, order and printing for build, dev, check, format and the language server ([`6d11f57`](https://github.com/briancray/abide/commit/6d11f57adc226b45bd0ddf1b4a305ee6d7a7a000))
|
|
47
|
+
- abfff21: socketWire and outboxQueue each reset in one call (resetSocketWire, resetOutbox); tests stop reaching into Mux internals and draining the outbox by timing ([`721774f`](https://github.com/briancray/abide/commit/721774f93df6040e20015f03755879c4cf534a38))
|
|
48
|
+
- abfff21: a mounted handler is held to the schema its row derived, so a bundled executable coerces and validates its args (RULEBOOK 19.9) ([`76c92a5`](https://github.com/briancray/abide/commit/76c92a51f0b3f49ee95e95d8088c320d7a896341))
|
|
49
|
+
- abfff21: an editor shows the findings abide check has for a file — lints, handler warnings and the emit's refusals included (RULEBOOK 38.11) ([`9824535`](https://github.com/briancray/abide/commit/9824535e191b0f9748edaafadc0bc8ecc08f75d0))
|
|
50
|
+
- abfff21: simplify pass — one placedSource, packageDirectory in appTree, derivedArgs probes once, manifest read beside the table, PatchLog followers always a set, pairingStatus yields the code alone, KeptChecker's heard takes nothing ([`9a6e663`](https://github.com/briancray/abide/commit/9a6e66361364b841cb53362ace080eb1e7d0372f))
|
|
51
|
+
- abfff21: ServerRoute and ServerError stay private to answerRequest ([`9c51de6`](https://github.com/briancray/abide/commit/9c51de674db98e4c2793fa8f496ebe54924c087f))
|
|
52
|
+
- abfff21: the build on disk is one module, and booting from a compilation is one ordering ([`a3a5349`](https://github.com/briancray/abide/commit/a3a5349baa9c55c9a931f00d635a57743ddf1cdc))
|
|
53
|
+
|
|
54
|
+
An app with no `src/` — its root is its package — now keeps its default `.abide` build and its `bun test` build cache inside the package rather than in the directory above it, as RULEBOOK 38.27 has a build sit beside its app; an app with a `src/` is unchanged.
|
|
55
|
+
- abfff21: a LevelChain owns the routed levels and their head bracketing; Router takes a popped history step through one entry and keeps its step bookkeeping private ([`a4d9641`](https://github.com/briancray/abide/commit/a4d9641105f9d1f9958b9bb6fcf90323c07cd6a8))
|
|
56
|
+
- abfff21: a kept checker reopens a stale project, drops one that threw and owns its watchers, for dev and the language server alike ([`c733d7e`](https://github.com/briancray/abide/commit/c733d7ea7b648a02ed366ffe172aa3b996c7e0de))
|
|
57
|
+
- abfff21: a handler file's mount row is built once, for the compiler and the in-memory test app ([`c7db045`](https://github.com/briancray/abide/commit/c7db0459e89ba4ea74918f29d7823c87a9e01d47))
|
|
58
|
+
- abfff21: format the try and wire changes ([`c85913a`](https://github.com/briancray/abide/commit/c85913a0a36bc8e828885b795ba31340057a22ff))
|
|
59
|
+
- abfff21: the bridge relay writes its own frames and hears sign-ins rather than being told ([`ed69e87`](https://github.com/briancray/abide/commit/ed69e87be6e92f9980cb4f9b66edc59f56f7a88f))
|
|
60
|
+
|
|
3
61
|
## 0.123.2
|
|
4
62
|
|
|
5
63
|
### Patch Changes
|
package/bin/abide.ts
CHANGED
|
@@ -16,8 +16,8 @@ import {
|
|
|
16
16
|
type CompiledApp,
|
|
17
17
|
} from '#compiler/compileApp.ts'
|
|
18
18
|
import { compiledEntry } from '#compiler/compiledEntry.ts'
|
|
19
|
+
import { type Diagnosis, printDiagnoses } from '#compiler/Diagnostics.ts'
|
|
19
20
|
import { formatAbide } from '#compiler/formatAbide.ts'
|
|
20
|
-
import { formatDiagnosis } from '#compiler/formatDiagnosis.ts'
|
|
21
21
|
import { parseAbide } from '#compiler/parseAbide.ts'
|
|
22
22
|
import { scaffold } from '#compiler/scaffold.ts'
|
|
23
23
|
import { serveLanguage } from '#compiler/serveLanguage.ts'
|
|
@@ -26,15 +26,17 @@ import {
|
|
|
26
26
|
type Compilation,
|
|
27
27
|
serverMapsOf,
|
|
28
28
|
} from '#server/abideModules.ts'
|
|
29
|
-
import { banner } from '#server/banner.ts'
|
|
30
|
-
import { buildDirectory } from '#server/buildDirectory.ts'
|
|
31
29
|
import {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
30
|
+
buildDirectory,
|
|
31
|
+
type BuildFiles,
|
|
32
|
+
buildFiles,
|
|
33
|
+
builtFiles,
|
|
34
|
+
markBuild,
|
|
35
|
+
unmarkedBuild,
|
|
36
|
+
writeWhole,
|
|
37
|
+
} from '#server/appBuild.ts'
|
|
38
|
+
import { banner } from '#server/banner.ts'
|
|
39
|
+
import { ENCODING_SUFFIX } from '#server/CLIENT_BUILD.ts'
|
|
38
40
|
import { type ClientBundle, clientBundle } from '#server/clientBundle.ts'
|
|
39
41
|
import { type Given, type Host, runCommands } from '#server/commands.ts'
|
|
40
42
|
import { type AppPackage, packageUnder } from '#server/config.ts'
|
|
@@ -45,7 +47,6 @@ import { namesUnder } from '#server/namesUnder.ts'
|
|
|
45
47
|
import { skipped } from '#server/placement.ts'
|
|
46
48
|
import { DEFAULT_DOCUMENT, intoHead } from '#server/render.ts'
|
|
47
49
|
import { runtimeRefusal } from '#server/runtimeRefusal.ts'
|
|
48
|
-
import { pathsUnder, serveBuild } from '#server/serveBuild.ts'
|
|
49
50
|
import { serveDev } from '#server/serveDev.ts'
|
|
50
51
|
import { escapeText } from '#shared/escapeText.ts'
|
|
51
52
|
import { ICON_ADDRESSES, LAUNCHER_PAGE } from '#shared/LAUNCHER_FILES.ts'
|
|
@@ -72,12 +73,8 @@ const DISK: Host = {
|
|
|
72
73
|
// 38.100 — built in this process rather than a child, where nobody built it, and said on
|
|
73
74
|
// stderr: the command's stdout is its own — `openapi`'s document, `mcp`'s messages.
|
|
74
75
|
app: ({ values }) => {
|
|
75
|
-
const handle = appOnDisk(directoriesOf(values),
|
|
76
|
-
(
|
|
77
|
-
writeBuild({ root, out }, console.error),
|
|
78
|
-
))
|
|
79
|
-
? out
|
|
80
|
-
: undefined,
|
|
76
|
+
const handle = appOnDisk(directoriesOf(values), (root, out) =>
|
|
77
|
+
writeBuild({ root, out }, console.error),
|
|
81
78
|
)
|
|
82
79
|
return RUNTIME_REFUSAL === undefined
|
|
83
80
|
? handle
|
|
@@ -116,15 +113,12 @@ async function writeBuild(
|
|
|
116
113
|
process.env.NODE_ENV ??= 'production'
|
|
117
114
|
// 38.66 — what this build may remove is only what was written before it began.
|
|
118
115
|
const began = Date.now()
|
|
119
|
-
// 38.100 — a build that fails leaves no build
|
|
120
|
-
|
|
121
|
-
const marker = `${out}/${COMPILATION}`
|
|
122
|
-
await rm(marker, { force: true })
|
|
116
|
+
// 38.100 — before anything can fail, so a build that fails leaves no build.
|
|
117
|
+
const files = await unmarkedBuild(out)
|
|
123
118
|
// `--out` is a real flag rather than a constant because two test files each building into
|
|
124
119
|
// one `.abide/` is the contention CLAUDE.md's "checks" section already records once.
|
|
125
120
|
const app = await compileApp(root)
|
|
126
|
-
|
|
127
|
-
console.warn(formatDiagnosis(warning, process.cwd()))
|
|
121
|
+
printDiagnoses(app.warnings, console.warn)
|
|
128
122
|
if (
|
|
129
123
|
Object.keys(app.files).length === 0 &&
|
|
130
124
|
Object.keys(app.handlers).length === 0
|
|
@@ -138,14 +132,13 @@ async function writeBuild(
|
|
|
138
132
|
// 36.11 — the directories above `public` and the path below it ARE the address.
|
|
139
133
|
// `src/public/favicon.ico` answers at `/favicon.ico`, and nothing declares that anywhere.
|
|
140
134
|
await writeClient(
|
|
141
|
-
|
|
135
|
+
files,
|
|
142
136
|
await clientBundle(root, compilation, app.published, 'build'),
|
|
143
137
|
began,
|
|
144
138
|
)
|
|
145
139
|
// An app's static files are its own whether or not it has a page yet.
|
|
146
|
-
const copied = await copyPublic(root,
|
|
147
|
-
|
|
148
|
-
await writeWhole(marker, JSON.stringify(compilation))
|
|
140
|
+
const copied = await copyPublic(root, files, app.published, began)
|
|
141
|
+
await markBuild(files, compilation)
|
|
149
142
|
say(
|
|
150
143
|
`abide build: ${app.sources} source(s), ${copied} public file(s) -> ${out}`,
|
|
151
144
|
)
|
|
@@ -299,9 +292,7 @@ async function writtenEntry(
|
|
|
299
292
|
root,
|
|
300
293
|
sourceMaps: serverMapsOf(app, root),
|
|
301
294
|
package: packageUnder(root),
|
|
302
|
-
|
|
303
|
-
client: pathsUnder(`${out}/${CLIENT_DIRECTORY}`),
|
|
304
|
-
published: pathsUnder(`${out}/${PUBLIC_DIRECTORY}`),
|
|
295
|
+
...(await builtFiles(out)),
|
|
305
296
|
}),
|
|
306
297
|
)
|
|
307
298
|
return { entry, compilation: app }
|
|
@@ -443,7 +434,7 @@ async function writeIcon(root: string, resources: string): Promise<boolean> {
|
|
|
443
434
|
|
|
444
435
|
/** 38.79 — the public file the app's icon is drawn from: `/icon.icns`, else `/icon.png`. */
|
|
445
436
|
async function publishedIcon(root: string): Promise<string | undefined> {
|
|
446
|
-
const published =
|
|
437
|
+
const { published } = buildFiles(buildDirectory(root))
|
|
447
438
|
for (const address of [ICON_ADDRESSES.icns, ICON_ADDRESSES.png])
|
|
448
439
|
if (await Bun.file(`${published}${address}`).exists())
|
|
449
440
|
return `${published}${address}`
|
|
@@ -517,7 +508,7 @@ ${body}</dict>
|
|
|
517
508
|
*/
|
|
518
509
|
async function copyPublic(
|
|
519
510
|
root: string,
|
|
520
|
-
|
|
511
|
+
files: BuildFiles,
|
|
521
512
|
published: Map<string, string>,
|
|
522
513
|
began: number,
|
|
523
514
|
): Promise<number> {
|
|
@@ -528,35 +519,35 @@ async function copyPublic(
|
|
|
528
519
|
produced.add(address.slice(1))
|
|
529
520
|
copies.push(
|
|
530
521
|
writeWhole(
|
|
531
|
-
`${
|
|
522
|
+
`${files.published}${address}`,
|
|
532
523
|
Bun.file(`${root}/${source}`),
|
|
533
524
|
),
|
|
534
525
|
)
|
|
535
526
|
}
|
|
536
527
|
await Promise.all(copies)
|
|
537
528
|
// 38.66 — a public file the app no longer has is no longer answered.
|
|
538
|
-
await pruneStale(
|
|
529
|
+
await pruneStale(files.published, produced, began)
|
|
539
530
|
return published.size
|
|
540
531
|
}
|
|
541
532
|
|
|
542
533
|
/**
|
|
543
|
-
* Writes the client bundle (`clientBundle`) into
|
|
534
|
+
* Writes the client bundle (`clientBundle`) into the build, with its manifest and precompressed copies.
|
|
544
535
|
*
|
|
545
536
|
* 38.5 — the manifest beside the bundle, and every file in each encoding (`precompressed`). AN APP
|
|
546
537
|
* OF HANDLERS ALONE is written no client, and its manifest anyway, so `abide start` reads one shape
|
|
547
538
|
* whatever the app holds.
|
|
548
539
|
*/
|
|
549
540
|
async function writeClient(
|
|
550
|
-
|
|
541
|
+
files: BuildFiles,
|
|
551
542
|
bundle: ClientBundle,
|
|
552
543
|
began: number,
|
|
553
544
|
): Promise<void> {
|
|
554
|
-
const client =
|
|
545
|
+
const { client } = files
|
|
555
546
|
// 38.66 — STAGED, THEN MOVED IN FILE BY FILE. A second build into the same `out` — or `abide
|
|
556
547
|
// start` serving it — read a chunk half written, and emptying `client/` first took the one it
|
|
557
548
|
// was serving away. Every name but the manifest's is a hash of what it holds, so two builds of
|
|
558
549
|
// one tree move in the same bytes under the same names.
|
|
559
|
-
const staging = `${
|
|
550
|
+
const staging = `${dirname(client)}/.staging-${crypto.randomUUID()}`
|
|
560
551
|
try {
|
|
561
552
|
const written: Promise<void>[] = []
|
|
562
553
|
for (const [name, { bytes }] of bundle.files)
|
|
@@ -574,7 +565,7 @@ async function writeClient(
|
|
|
574
565
|
}
|
|
575
566
|
await Promise.all(moves)
|
|
576
567
|
await pruneStale(client, produced, began)
|
|
577
|
-
await writeWhole(
|
|
568
|
+
await writeWhole(files.manifest, JSON.stringify(bundle.manifest))
|
|
578
569
|
} finally {
|
|
579
570
|
await rm(staging, { recursive: true, force: true })
|
|
580
571
|
}
|
|
@@ -642,17 +633,6 @@ async function pruneStale(
|
|
|
642
633
|
await Promise.all(stale)
|
|
643
634
|
}
|
|
644
635
|
|
|
645
|
-
/**
|
|
646
|
-
* Writes `path` whole: to a name of its own beside it, then renamed over it.
|
|
647
|
-
*
|
|
648
|
-
* 38.66 — a reader, or a second build, finds the last complete file there and never a partial one.
|
|
649
|
-
*/
|
|
650
|
-
async function writeWhole(path: string, content: string | Blob): Promise<void> {
|
|
651
|
-
const partial = `${path}.${crypto.randomUUID()}.partial`
|
|
652
|
-
await Bun.write(partial, content)
|
|
653
|
-
await rename(partial, path)
|
|
654
|
-
}
|
|
655
|
-
|
|
656
636
|
/**
|
|
657
637
|
* Wraps a command body with the app's absolute root and build directory, or fails with no app.
|
|
658
638
|
*
|
|
@@ -741,24 +721,18 @@ async function check(
|
|
|
741
721
|
{ positionals }: Given,
|
|
742
722
|
): Promise<number> {
|
|
743
723
|
const within = namedDirectories(positionals)
|
|
744
|
-
const found =
|
|
745
|
-
|
|
746
|
-
let warnings = 0
|
|
747
|
-
for (const diagnosis of found) {
|
|
724
|
+
const found: Diagnosis[] = []
|
|
725
|
+
for (const diagnosis of await checkApp(root))
|
|
748
726
|
if (
|
|
749
|
-
within.length
|
|
750
|
-
|
|
727
|
+
within.length === 0 ||
|
|
728
|
+
within.some(
|
|
751
729
|
(directory) =>
|
|
752
730
|
diagnosis.path === directory ||
|
|
753
731
|
diagnosis.path.startsWith(`${directory}/`),
|
|
754
732
|
)
|
|
755
733
|
)
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
else if (diagnosis.category === 'warning') warnings += 1
|
|
759
|
-
else continue
|
|
760
|
-
console.log(formatDiagnosis(diagnosis, process.cwd()))
|
|
761
|
-
}
|
|
734
|
+
found.push(diagnosis)
|
|
735
|
+
const { errors, warnings } = printDiagnoses(found, console.log)
|
|
762
736
|
console.log(
|
|
763
737
|
`abide check: ${errors} error${errors === 1 ? '' : 's'}, ${warnings} warning${warnings === 1 ? '' : 's'}`,
|
|
764
738
|
)
|
|
@@ -802,10 +776,7 @@ async function format(within: string[], { values }: Given): Promise<number> {
|
|
|
802
776
|
next += 1
|
|
803
777
|
const text = await Bun.file(path).text()
|
|
804
778
|
const formatted = await formatAbide(path, text)
|
|
805
|
-
|
|
806
|
-
errors += 1
|
|
807
|
-
console.log(formatDiagnosis(finding, process.cwd()))
|
|
808
|
-
}
|
|
779
|
+
errors += printDiagnoses(formatted.findings, console.log).errors
|
|
809
780
|
if (formatted.text === text) continue
|
|
810
781
|
changed += 1
|
|
811
782
|
if (values.check)
|
package/docs/REGISTRY.md
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Every name an app author can write, with its type and what it is.
|
|
4
4
|
|
|
5
|
+
`@abide/abide/compiler`, and the `/runtime`, `/routing` and `/wire` entries a compiled bundle
|
|
6
|
+
imports, are tooling rather than surface an app author writes, and none of their names is a row.
|
|
7
|
+
|
|
5
8
|
## What this document is
|
|
6
9
|
|
|
7
10
|
A **registry**. One row per name, and the row answers exactly one question: *what is this?*
|
|
@@ -51,6 +54,7 @@ Accepted, Failures>` is the inner value's own `Accepted`. Then `Failures`, then
|
|
|
51
54
|
| Name | Signature | Meaning | Rules |
|
|
52
55
|
| --- | --- | --- | --- |
|
|
53
56
|
| `Reactive` | `Reactive<Stored = undefined, Accepted = Stored, Failures = never, Produced = Stored>` | The value type every producer in this design hands back. | 1.1, 1.2, 1.3, 1.4, 1.6, 1.7, 1.8, 9.1, 9.14 |
|
|
57
|
+
| `isReactive` | `(value: unknown) => value is Reactive<unknown>` | Whether a value is a `Reactive`. | 1.6 |
|
|
54
58
|
| `Keyed` | `Keyed<Stored, Args, Accepted = Stored, Failures = never, Produced = Stored>` | What a body declaring a parameter hands back: a factory carrying the probes and the triggers. | 4.13, 11.2, 11.4, 11.6, 11.23, 11.55 |
|
|
55
59
|
| `Accepted` | `unknown` | What a factory and a write take, before the gates run. | 4.1, 4.2 |
|
|
56
60
|
| `Stored` | `unknown` | What is held, and what a read returns. | 4.7, 5.2 |
|
|
@@ -213,28 +217,45 @@ type Gated<Gate, Accepted> = [Schema<Accepted>] extends [Gate] ? never : Failed<
|
|
|
213
217
|
|
|
214
218
|
| Name | Signature | Meaning | Rules |
|
|
215
219
|
| --- | --- | --- | --- |
|
|
216
|
-
| `Rpc` | `<Value, Args, Failures, Produced = Value>(args?: Args, options?: { signal?: AbortSignal; offline?: (args: Args) => Value }) => Reactive<Value, Value, Failures \| Failed<'HttpError', undefined>, Produced>` | A handler reached over http, or in process on a server. | 16.3, 16.4, 16.8, 16.11, 16.25, 16.26, 16.27, 16.28, 16.29, 16.33, 16.43, 16.48, 16.49, 16.62, 41.5, 41.7, 41.12, 41.21, 41.22, 41.25, 41.26, 41.27, 16.79, 16.80, 16.85 |
|
|
220
|
+
| `Rpc` | `<Value, Args, Failures = never, Produced = Value>(args?: Args, options?: { signal?: AbortSignal; offline?: (args: Args) => Value }) => Reactive<Value, Value, Failures \| Failed<'HttpError', undefined> \| Annotated<Args>, Produced>` | A handler reached over http, or in process on a server. | 16.3, 16.4, 16.8, 16.11, 16.25, 16.26, 16.27, 16.28, 16.29, 16.33, 16.43, 16.48, 16.49, 16.62, 41.5, 41.7, 41.12, 41.21, 41.22, 41.25, 41.26, 41.27, 16.79, 16.80, 16.85 |
|
|
217
221
|
| `offline` | `(args: Args) => Value` | What a call settles to where a browser could not get its answer. | 16.81, 16.82, 16.83, 16.84 |
|
|
218
222
|
| `Value` | `unknown` | What the addressed `Reactive` holds. | 16.3, 16.30 |
|
|
219
223
|
| `Produced` | `unknown` | What it yields, per the unit rule. | 1.2, 16.3 |
|
|
220
224
|
| `Args` | `Record<string, JsonValue> \| undefined` | The arguments, in the body on a mutation and in the URL on a `GET` or `DELETE`. | 11.24, 16.18, 19.15 |
|
|
221
225
|
| `Middleware` | `Middleware<Answer = never, Extra extends object = object> = <Given extends { request: Request } & Extra, Result>(next: (ctx?: Given) => Promise<Result>, ctx: Given) => Result \| Answer \| Failed<string, unknown> \| Promise<Result \| Answer \| Failed<string, unknown>>` | One rung, written once for every lane whose context carries `Extra`. | 16.14, 16.15, 16.16, 16.21, 37.14, 37.15 |
|
|
222
|
-
| `GET` | `<
|
|
223
|
-
| `GET` | `<
|
|
224
|
-
| `GET` | `<
|
|
226
|
+
| `GET` | `<Stored, Accepted, Failures, Produced>(handler: Reactive<Stored, Accepted, Failures, Produced>, options?: RpcOptions<undefined>) => Rpc<Stored, undefined, Failures, Produced>` | Declares a read any surface may call. | 16.1, 16.2, 16.5, 16.6, 16.30, 16.31, 16.32, 16.68, 16.76, 16.34, 16.35, 16.36, 16.37, 16.39, 16.44, 16.45, 16.46, 16.47, 16.75, 16.50, 16.51, 16.52, 16.64, 18.1, 18.3, 18.6, 18.8, 18.10, 18.12, 18.21, 18.24, 18.27 |
|
|
227
|
+
| `GET` | `<Stored, Args, Accepted, Failures, Produced>(handler: Keyed<Stored, Args, Accepted, Failures, Produced>, options?: RpcOptions<Args>) => Rpc<Stored, Args, Failures, Produced>` | The keyed overload, for a `Keyed` given an address. | 11.2, 16.1, 16.3, 16.6 |
|
|
228
|
+
| `GET` | `<Chunk, Shaped = Chunk[], Gate = Schema<Chunk[]>>(handler: () => AsyncGenerator<Chunk> \| Promise<AsyncGenerator<Chunk>>, options?: Shaping<Chunk[], Shaped, never, Gate> & RpcOptions<undefined>) => Rpc<Kept<Shaped>, undefined, Refusals<Shaped, Gate, Chunk[]>, Chunk>` | The streaming overload, whose options build the value it becomes beside its address. | 16.1, 16.6, 16.7, 16.44, 16.45, 16.46, 16.47 |
|
|
229
|
+
| `GET` | `<Chunk, Args, Shaped = Chunk[], Gate = Schema<Chunk[]>, ArgsGate = Schema<Args>>(handler: (args: Args) => AsyncGenerator<Chunk> \| Promise<AsyncGenerator<Chunk>>, options?: Shaping<Chunk[], Shaped, Args, Gate, ArgsGate> & RpcOptions<Args>) => Rpc<Kept<Shaped>, Args, Refusals<Shaped, Gate, Chunk[], ArgsGate, Args>, Chunk>` | The keyed streaming overload. | 11.2, 16.1, 16.6, 16.7 |
|
|
230
|
+
| `GET` | `<Chunk, Args, Shaped = Chunk[], Gate = Schema<Chunk[]>, ArgsGate = Schema<Args \| undefined>>(handler: (args?: Args) => AsyncGenerator<Chunk> \| Promise<AsyncGenerator<Chunk>>, options?: Shaping<Chunk[], Shaped, Args \| undefined, Gate, ArgsGate> & RpcOptions<Args \| undefined>) => Rpc<Kept<Shaped>, Args \| undefined, Refusals<Shaped, Gate, Chunk[], ArgsGate, Args \| undefined>, Chunk>` | The keyed streaming overload for a body whose parameter is optional. | 11.2 |
|
|
231
|
+
| `GET` | `<Computed, Shaped = Awaited<Computed>, Gate = Schema<Awaited<Computed>>>(handler: () => Computed, options?: Shaping<Awaited<Computed>, Shaped, never, Gate> & RpcOptions<undefined>) => Rpc<Kept<Shaped>, undefined, AdoptedFailures<Computed> \| Refusals<Shaped, Gate, Awaited<Computed>>, AdoptedProduced<Computed, Kept<Shaped>>>` | The plain-function overload, whose options (`ttl`, `global`, `debounce` and the rest) build the value it becomes beside its address. | 16.1, 16.6, 16.7 |
|
|
232
|
+
| `GET` | `<Computed, Args, Shaped = Awaited<Computed>, Gate = Schema<Awaited<Computed>>, ArgsGate = Schema<Args>>(handler: (args: Args) => Computed, options?: Shaping<Awaited<Computed>, Shaped, Args, Gate, ArgsGate> & RpcOptions<Args>) => Rpc<Kept<Shaped>, Args, AdoptedFailures<Computed> \| Refusals<Shaped, Gate, Awaited<Computed>, ArgsGate, Args>, AdoptedProduced<Computed, Kept<Shaped>>>` | The keyed plain-function overload. | 11.2, 16.1, 16.6, 16.7 |
|
|
233
|
+
| `GET` | `<Computed, Args, Shaped = Awaited<Computed>, Gate = Schema<Awaited<Computed>>, ArgsGate = Schema<Args \| undefined>>(handler: (args?: Args) => Computed, options?: Shaping<Awaited<Computed>, Shaped, Args \| undefined, Gate, ArgsGate> & RpcOptions<Args \| undefined>) => Rpc<Kept<Shaped>, Args \| undefined, AdoptedFailures<Computed> \| Refusals<Shaped, Gate, Awaited<Computed>, ArgsGate, Args \| undefined>, AdoptedProduced<Computed, Kept<Shaped>>>` | The keyed plain-function overload for a body whose parameter is optional. | 11.2 |
|
|
234
|
+
| `GET` | `<Accepted, Shaped = Accepted, Gate = Schema<Accepted>>(handler: Accepted \| PromiseLike<Accepted>, options?: Shaping<Accepted, Shaped, never, Gate> & RpcOptions<undefined>) => Rpc<Kept<Shaped>, undefined, Refusals<Shaped, Gate, Accepted>>` | The value overload, for what the handler owns outright, whose options build the value it becomes. | 16.1, 16.6, 16.7 |
|
|
225
235
|
| `POST` / `PUT` / `PATCH` / `DELETE` | same as `GET` | Declares a mutation. | 16.2, 16.7, 16.32, 16.68, 16.76, 16.38, 16.53 |
|
|
226
236
|
| `rpc.busy` | `(pattern?: Partial<Args>) => boolean` | `busy` narrowed to the handler's matching entries. | 13.2, 13.3, 13.12, 13.19, 46.11 |
|
|
227
237
|
| `rpc.ready` | `(pattern?: Partial<Args>) => boolean` | `ready` narrowed to the handler's matching entries. | 13.11, 13.12, 13.19 |
|
|
228
238
|
| `rpc.synced` | `(pattern?: Partial<Args>) => boolean` | `synced` narrowed to the handler's matching entries. | 13.12, 13.18, 13.19 |
|
|
229
239
|
| `rpc.invalidate` | `(pattern?: Partial<Args>) => void` | `invalidate` narrowed to the handler's matching entries. | 7.2, 7.3, 13.4, 13.12, 13.19 |
|
|
230
240
|
| `rpc.refresh` | `(pattern?: Partial<Args>) => void` | `refresh` narrowed to the handler's matching entries. | 7.4, 7.5, 13.4, 13.12, 13.19 |
|
|
231
|
-
| `rpc.isError` | `<Name extends
|
|
241
|
+
| `rpc.isError` | `<Name extends string>(error: unknown, name: Name) => error is Extract<Failures \| Failed<'HttpError', undefined> \| Annotated<Args>, { name: Name }>` | Whether a caught failure is the one named. | 16.8 |
|
|
232
242
|
| `rpc.raw` | `(args: Args, init?: RequestInit) => Promise<Response>` | The same call handed back as the raw response. | 16.11, 16.42 |
|
|
233
243
|
| `rpc.method` | `string` | The HTTP method. | 16.2 |
|
|
234
244
|
| `rpc.url` | `(args?: Args) => string` | The address, resolved against the mount. | 16.9, 16.10, 30.28 |
|
|
235
245
|
| `rpc.description` | `string \| undefined` | The human description. | 16.28 |
|
|
236
246
|
| `PatchOp` | `{ op: 'add' \| 'replace' \| 'test'; path: string; value: unknown } \| { op: 'remove'; path: string } \| { op: 'move' \| 'copy'; from: string; path: string }` | One JSON Patch operation (RFC 6902), its paths JSON Pointers, as a followed `GET` is sent what an `s.patch` wrote. | 18.11, 18.13 |
|
|
237
247
|
|
|
248
|
+
The aliases a call's failures and a plain handler's options are spelled through are declared
|
|
249
|
+
rather than listed, none of them being a name an app writes. `Annotated` is the `ValidationError` of
|
|
250
|
+
16.8, `never` wherever 19.9 derives no object's schema from `Args`:
|
|
251
|
+
|
|
252
|
+
```ts
|
|
253
|
+
type Annotated<Args> = 0 extends 1 & Args ? never : unknown extends Args ? never : Derived<Exclude<Args, undefined>>
|
|
254
|
+
type Derived<Member, Whole = Member> = Member extends readonly unknown[] | ((...given: never[]) => unknown) ? never : Member extends object ? [Whole] extends [Member] ? [keyof Member] extends [never] ? [string] extends [Member] ? Failed<'ValidationError', Issues<Whole>> : never : Failed<'ValidationError', Issues<Whole>> : never : never
|
|
255
|
+
type Shaping<Accepted, Shaped, Args = never, Gate = Schema<Accepted>, ArgsGate = Schema<Args>> = Omit<ReactiveOptions<Accepted, Kept<NoInfer<Shaped>>, never, Args>, 'transform' | 'schema' | 'args'> & { transform?: (value: Accepted) => Shaped; schema?: Gate & Schema<Accepted>; args?: [Args] extends [never] ? never : ArgsGate & Schema<Args> }
|
|
256
|
+
type Refusals<Shaped, Gate, Stored, ArgsGate = Schema<never>, Args = never> = Refused<Shaped> | Gated<Gate, Stored> | Gated<ArgsGate, Args>
|
|
257
|
+
```
|
|
258
|
+
|
|
238
259
|
### `RpcOptions`
|
|
239
260
|
|
|
240
261
|
| Name | Signature | Meaning | Rules |
|
|
@@ -349,9 +370,9 @@ type Gated<Gate, Accepted> = [Schema<Accepted>] extends [Gate] ? never : Failed<
|
|
|
349
370
|
|
|
350
371
|
| Name | Signature | Meaning | Rules |
|
|
351
372
|
| --- | --- | --- | --- |
|
|
352
|
-
| `claudeCode` | `(config?: ClaudeCodeConfig) => Provider` | The visitor's own Claude Code, reached through the bridge paired with their browser, as a provider. | 44.5, 44.13, 44.17, 44.18, 44.19, 44.
|
|
373
|
+
| `claudeCode` | `(config?: ClaudeCodeConfig) => Provider` | The visitor's own Claude Code, reached through the bridge paired with their browser, as a provider. | 44.5, 44.13, 44.17, 44.18, 44.19, 44.33 |
|
|
353
374
|
| `ClaudeCodeConfig` | `{ model?: string; fallbackModel?: string; systemPrompt?: string; appendSystemPrompt?: string; effort?: 'low' \| 'medium' \| 'high' \| 'xhigh' \| 'max'; maxBudgetUsd?: number; betas?: string[]; disallowedTools?: string[]; tools?: string[] }` | The Claude Code options a site may set for a turn, and the built-in tools it asks the visitor for. | 44.16, 44.29 |
|
|
354
|
-
| `claudeCode.bridgeCommand` | `(options?: { tools?: string[] }) => { command: string; link: string; expires: number }` | The command and the link that pair a bridge with this browser, granting the built-in tools it is given. | 44.14, 44.32, 44.33, 44.40
|
|
375
|
+
| `claudeCode.bridgeCommand` | `(options?: { tools?: string[] }) => { command: string; link: string; expires: number }` | The command and the link that pair a bridge with this browser, granting the built-in tools it is given. | 44.14, 44.32, 44.33, 44.40 |
|
|
355
376
|
| `claudeCode.bridge` | `(options?: { tools?: string[] }) => AsyncGenerator<BridgeStatus>` | This browser's pairing, as it changes. | 44.20, 44.22, 44.32, 44.33, 44.34, 44.40 |
|
|
356
377
|
| `BridgeStatus` | `{ paired: boolean; command: string \| undefined; link: string \| undefined }` | Whether a bridge is paired, and the command and the link that pair one where none is. | 44.20, 44.40 |
|
|
357
378
|
| `/__abide/bridge` | `GET`, `POST` | Where a bridge pairs, and is relayed its turns. | 36.7, 44.14, 44.15, 44.19, 44.23, 44.26, 16.57, 16.78 |
|
|
@@ -362,7 +383,8 @@ type Gated<Gate, Accepted> = [Schema<Accepted>] extends [Gate] ? never : Failed<
|
|
|
362
383
|
|
|
363
384
|
| Name | Signature | Meaning | Rules |
|
|
364
385
|
| --- | --- | --- | --- |
|
|
365
|
-
| `cookies` | `() =>
|
|
386
|
+
| `cookies` | `() => Cookies` | The cookies of the request being served, live and mutable. | 22.2, 22.3, 22.4, 22.5, 22.6, 22.7, 22.8, 22.10 |
|
|
387
|
+
| `Cookies` | `class Cookies implements Iterable<[string, string]> { get(name: string): string \| null; has(name: string): boolean; set(name: string, value: string, options?: CookieInit): void; set(options: CookieInit): void; delete(name: string, options?: Omit<CookieStoreDeleteOptions, 'name'>): void; delete(options: CookieStoreDeleteOptions): void; size: number; toJSON(): Record<string, string>; toSetCookieHeaders(): string[] }` | A cookie jar shaped like Bun's `CookieMap`. | 22.4, 22.5, 22.6 |
|
|
366
388
|
|
|
367
389
|
## `request`
|
|
368
390
|
|
|
@@ -499,7 +521,7 @@ type Gated<Gate, Accepted> = [Schema<Accepted>] extends [Gate] ? never : Failed<
|
|
|
499
521
|
|
|
500
522
|
| Name | Signature | Meaning | Rules |
|
|
501
523
|
| --- | --- | --- | --- |
|
|
502
|
-
| `csp` | `(sources?: Record<string, string[]>) => (next: (ctx?: { request: Request }) => Promise<Response>, ctx: { request: Request }) => Promise<Response>` | The rung that sets `content-security-policy`. | 29.1, 29.2, 29.5, 29.6, 29.7, 29.8 |
|
|
524
|
+
| `csp` | `(sources?: Record<string, string[]>) => (next: (ctx?: { request: Request }) => Promise<Response>, ctx: { request: Request }) => Response \| Promise<Response>` | The rung that sets `content-security-policy`. | 29.1, 29.2, 29.5, 29.6, 29.7, 29.8 |
|
|
503
525
|
| `csp.nonce` | `() => string` | This response's nonce, for the app's own inline script. | 29.3, 29.4, 29.9, 29.11 |
|
|
504
526
|
|
|
505
527
|
## `url`
|
|
@@ -539,7 +561,7 @@ type Gated<Gate, Accepted> = [Schema<Accepted>] extends [Gate] ? never : Failed<
|
|
|
539
561
|
| `foo.push(v)` | the same | 31.8, 31.9 |
|
|
540
562
|
| `const [a, b] = foo` / `...foo` | one read of the value | 31.12 |
|
|
541
563
|
| `foo.bar` | the value's `bar`, or the `Reactive`'s own `bar` where it declares one the value does not | 31.5 |
|
|
542
|
-
| `foo.bar(…)` | the `Reactive`
|
|
564
|
+
| `foo.bar(…)` | a call of the value's `bar`, or of the `Reactive`'s own `bar` where it declares one the value does not | 31.6 |
|
|
543
565
|
| `foo()` / `foo.set(v)` | the explicit forms | 31.7, 31.11 |
|
|
544
566
|
|
|
545
567
|
## Templating
|
|
@@ -850,7 +872,7 @@ rows a runner prints, and an adapter for an abide app.
|
|
|
850
872
|
|
|
851
873
|
| Name | Meaning | Rules |
|
|
852
874
|
| --- | --- | --- |
|
|
853
|
-
| `preload = ["@abide/harness/abide/preload"]` | The `[test]` preload that registers a DOM a test mounts into and measures, then abide's own. | 38.109, 38.119 |
|
|
875
|
+
| `preload = ["@abide/harness/abide/preload"]` | The `[test]` preload that registers a DOM a test mounts into and measures, then abide's own. | 38.109, 38.119, 38.133 |
|
|
854
876
|
|
|
855
877
|
# CLI
|
|
856
878
|
|
|
@@ -858,7 +880,7 @@ rows a runner prints, and an adapter for an abide app.
|
|
|
858
880
|
|
|
859
881
|
| Command | Meaning | Rules |
|
|
860
882
|
| --- | --- | --- |
|
|
861
|
-
| `abide scaffold <name>` | Writes a starter project. | 38.1, 38.42, 38.103, 38.104, 38.106, 38.112, 38.122, 38.124, 38.131 |
|
|
883
|
+
| `abide scaffold <name>` | Writes a starter project. | 38.1, 38.42, 38.103, 38.104, 38.106, 38.112, 38.122, 38.124, 38.131, 38.132 |
|
|
862
884
|
| `abide run <file> [args…]` | Runs a script under the abide runtime. | 38.2, 38.57 |
|
|
863
885
|
| `abide check [dir…]` | The type-checker over a `.abide` tree. | 38.3, 38.31, 38.32, 38.33, 38.40, 38.105, 38.123 |
|
|
864
886
|
| `abide format [--check] [dir…]` | The formatter over a `.abide` tree. | 38.25, 38.125, 38.126, 38.127, 38.128, 38.129 |
|
|
@@ -876,3 +898,14 @@ rows a runner prints, and an adapter for an abide app.
|
|
|
876
898
|
| `abide lsp` | The `.abide` language server, over stdio. | 38.11, 38.34, 38.39, 38.98, 38.116, 38.117, 38.118, 38.130 |
|
|
877
899
|
| `--help` · `-h` · `abide help` | Usage, generated from the command list. | 38.12, 38.113, 38.114 |
|
|
878
900
|
| `--version` · `-v` | The version of abide, or of the app a compiled executable holds. | 38.115 |
|
|
901
|
+
|
|
902
|
+
## `abide-bridge` — the bridge
|
|
903
|
+
|
|
904
|
+
`@abide/bridge`, a package of its own: what a visitor runs to put their own Claude Code behind a
|
|
905
|
+
site's `claudeCode`.
|
|
906
|
+
|
|
907
|
+
| Command | Meaning | Rules |
|
|
908
|
+
| --- | --- | --- |
|
|
909
|
+
| `abide-bridge <site> <code> [--claude <path>] [--env NAME=VALUE]… [-- <options>]` | This machine's Claude Code, paired with the browser a site minted the code for. | 44.15, 44.16, 44.24, 44.25, 44.27, 44.30, 44.44, 44.45, 44.46 |
|
|
910
|
+
| `abide-bridge install [--claude <path>] [--env NAME=VALUE]… [-- <options>]` | The app that opens a site's `abide-bridge` links on this machine, registered. | 44.41, 44.42, 44.43, 44.44 |
|
|
911
|
+
| `abide-bridge uninstall` | `abide-bridge install`, undone. | 44.43 |
|
package/docs/RULEBOOK.md
CHANGED
|
@@ -1559,9 +1559,11 @@ error naming the mount.
|
|
|
1559
1559
|
23.21 A `.abide` of the app's own directly in a directory under no fence MUST be a page, save a
|
|
1560
1560
|
`layout.abide`, an `error.abide` and the root's `launcher.abide`.
|
|
1561
1561
|
|
|
1562
|
-
23.22 A file of the app's own directly in a directory under no fence
|
|
1563
|
-
handler
|
|
1564
|
-
|
|
1562
|
+
23.22 A file of the app's own directly in a directory under no fence MUST be a `.abide`, a handler
|
|
1563
|
+
file (`<name>.handler.ts`), a param file (`<NAME>.param.ts`), a test file (`<name>.test.ts`), a bench
|
|
1564
|
+
file (`<name>.bench.ts`) or a declaration file (`<name>.d.ts`), and any other MUST be a build error
|
|
1565
|
+
naming the file and a `lib` directory — save a file directly in a root that holds its package's
|
|
1566
|
+
`package.json`, which MAY be any file but a `.ts`.
|
|
1565
1567
|
|
|
1566
1568
|
23.23 A server file of the app's own under no `lib` directory MUST be a build error naming the file
|
|
1567
1569
|
and a `lib` directory.
|
|
@@ -1891,8 +1893,8 @@ member, and the value's method otherwise.
|
|
|
1891
1893
|
31.8 A write through a member path into plain data MUST copy down that path and then write, and the
|
|
1892
1894
|
copy MUST NOT be optimized away.
|
|
1893
1895
|
|
|
1894
|
-
31.9 A mutator
|
|
1895
|
-
the member name.
|
|
1896
|
+
31.9 A call of an array's mutator through a member path MUST be a write per 31.8, run on a copy of
|
|
1897
|
+
the receiver, and MUST be resolved from the type of the receiver rather than from the member name.
|
|
1896
1898
|
|
|
1897
1899
|
31.10 A template-local binding MUST shadow a name bound to a `Reactive` for the body it is bound in.
|
|
1898
1900
|
|
|
@@ -1903,8 +1905,8 @@ the member name.
|
|
|
1903
1905
|
31.13 A name MUST hold the `Reactive` where the declared type of its position is a `Selection`, or a
|
|
1904
1906
|
type parameter constrained by one.
|
|
1905
1907
|
|
|
1906
|
-
31.14 A write through a member path that reaches a value which is not plain data —
|
|
1907
|
-
object whose prototype is `Object.prototype` or `null` — MUST assign on that value itself, MUST NOT
|
|
1908
|
+
31.14 A write through a member path that reaches a value which is not plain data — anything but an
|
|
1909
|
+
array or an object whose prototype is `Object.prototype` or `null` — MUST assign on that value itself, MUST NOT
|
|
1908
1910
|
copy it or any level above it, and MUST NOT wake a reader.
|
|
1909
1911
|
|
|
1910
1912
|
31.15 `route.url`, `route.params`, `route.name` and `route.navigating` MUST each be read and written
|
|
@@ -2281,8 +2283,9 @@ loads MUST NOT carry it.
|
|
|
2281
2283
|
34.20 A `<script server>` in a `.abide` file of the app's own under a `public` directory MUST be a
|
|
2282
2284
|
compile error.
|
|
2283
2285
|
|
|
2284
|
-
34.21 A file a script block imports `with { type: 'text' }`, a `.abide`
|
|
2285
|
-
as its text and typed a `string`, on a server, in a browser
|
|
2286
|
+
34.21 A file a script block imports `with { type: 'text' }`, a `.abide` and a file whose name has no
|
|
2287
|
+
extension among them, MUST be imported as its text and typed a `string`, on a server, in a browser
|
|
2288
|
+
and to the checker alike.
|
|
2286
2289
|
|
|
2287
2290
|
34.22 A binding a `<script server>` imports that its file's `<script module>` or `<script>` imports
|
|
2288
2291
|
from the same specifier under the same name MUST compile as that one binding, a value wherever any
|
|
@@ -2863,6 +2866,12 @@ editor holds.
|
|
|
2863
2866
|
38.131 The project `abide scaffold` writes MUST carry Tailwind wired: `bun-plugin-tailwind` declared
|
|
2864
2867
|
in its `bunfig.toml` (38.43), and a stylesheet importing `tailwindcss` that its root layout imports.
|
|
2865
2868
|
|
|
2869
|
+
38.132 The project `abide scaffold` writes MUST carry a Dockerfile whose image holds the executable
|
|
2870
|
+
`abide compile` writes and nothing else of the app.
|
|
2871
|
+
|
|
2872
|
+
38.133 Under `bun test` with `@abide/abide/test` preloaded, each test file after the first in a
|
|
2873
|
+
process MUST start as a bare `invalidate` (13.6) leaves the values the files before it loaded.
|
|
2874
|
+
|
|
2866
2875
|
# 39. Head and view transitions
|
|
2867
2876
|
|
|
2868
2877
|
39.1 A `<head>` element in a `.abide` file MUST contribute its children to the document head.
|
|
@@ -2968,7 +2977,8 @@ NOT be answered by a fixture.
|
|
|
2968
2977
|
|
|
2969
2978
|
40.16 Instrumentation the documentation adds to an `<Example>` MUST sit outside the render.
|
|
2970
2979
|
|
|
2971
|
-
40.17 A page MUST embed one `<Example>` per behavior it teaches, save a page 40.35
|
|
2980
|
+
40.17 A page MUST embed one `<Example>` per behavior it teaches, save a page or a section 40.35
|
|
2981
|
+
exempts.
|
|
2972
2982
|
|
|
2973
2983
|
40.18 An `<Example>` MUST demonstrate exactly one behavior.
|
|
2974
2984
|
|
|
@@ -3014,11 +3024,11 @@ about.
|
|
|
3014
3024
|
40.34 The documentation site MUST serve `docs/RULEBOOK.md` at `/rulebook`, read from the file as the
|
|
3015
3025
|
site builds, with each clause and each group anchored by its own number.
|
|
3016
3026
|
|
|
3017
|
-
40.35 A page whose every behavior is performed by a command, or decided by the
|
|
3018
|
-
served from, MAY embed no `<Example>`.
|
|
3027
|
+
40.35 A page, or a section of one, whose every behavior is performed by a command, or decided by the
|
|
3028
|
+
deployment an app is served from, MAY embed no `<Example>`.
|
|
3019
3029
|
|
|
3020
|
-
40.36 A page embedding no `<Example>` under 40.35 MUST name which of the two in its `SITE`
|
|
3021
|
-
`cardless`.
|
|
3030
|
+
40.36 A page embedding no `<Example>` at all under 40.35 MUST name which of the two in its `SITE`
|
|
3031
|
+
entry's `cardless`.
|
|
3022
3032
|
|
|
3023
3033
|
40.37 The documentation site MUST serve each chapter's feature directory at the address the chapter
|
|
3024
3034
|
app serves it at, with none of the site's chrome around its pages.
|