@abide/abide 0.42.0 → 0.43.1
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/AGENTS.md +234 -300
- package/CHANGELOG.md +41 -0
- package/README.md +50 -93
- package/package.json +3 -2
- package/src/abideResolverPlugin.ts +104 -14
- package/src/buildCli.ts +1 -1
- package/src/discoveryEntry.ts +3 -3
- package/src/lib/bundle/BundleMenuItem.ts +1 -1
- package/src/lib/cli/createClient.ts +12 -12
- package/src/lib/cli/dispatchCommand.ts +1 -1
- package/src/lib/cli/printSessionStatus.ts +1 -1
- package/src/lib/cli/resolveCliTarget.ts +1 -1
- package/src/lib/cli/runCli.ts +1 -1
- package/src/lib/cli/types/CliManifest.ts +1 -1
- package/src/lib/cli/types/CliManifestEntry.ts +2 -2
- package/src/lib/mcp/annotationsForMethod.ts +5 -5
- package/src/lib/mcp/createMcpServer.ts +3 -3
- package/src/lib/mcp/mcpSurface.ts +14 -14
- package/src/lib/mcp/types/McpServerOptions.ts +1 -1
- package/src/lib/server/DELETE.ts +4 -4
- package/src/lib/server/GET.ts +4 -4
- package/src/lib/server/HEAD.ts +4 -4
- package/src/lib/server/PATCH.ts +4 -4
- package/src/lib/server/POST.ts +4 -4
- package/src/lib/server/PUT.ts +4 -4
- package/src/lib/server/agent.ts +4 -4
- package/src/lib/server/env.ts +1 -1
- package/src/lib/server/error.ts +49 -7
- package/src/lib/server/json.ts +1 -1
- package/src/lib/server/rpc/buildErrorConstructors.ts +19 -0
- package/src/lib/server/rpc/{defineVerb.ts → defineRpc.ts} +52 -34
- package/src/lib/server/rpc/{dispatchVerbInProcess.ts → dispatchRpcInProcess.ts} +3 -3
- package/src/lib/server/rpc/fieldErrorsFromIssues.ts +23 -0
- package/src/lib/server/rpc/{findVerbByCommandName.ts → findRpcByCommandName.ts} +5 -5
- package/src/lib/server/rpc/parseArgs.ts +6 -6
- package/src/lib/server/rpc/readBodyWithinLimit.ts +2 -2
- package/src/lib/server/rpc/registerRpc.ts +6 -0
- package/src/lib/server/rpc/{verbRegistry.ts → rpcRegistry.ts} +4 -4
- package/src/lib/server/rpc/{runWithVerbTimeout.ts → runWithRpcTimeout.ts} +4 -4
- package/src/lib/server/rpc/types/RemoteHandler.ts +9 -3
- package/src/lib/server/rpc/types/{VerbHelper.ts → RpcHelper.ts} +57 -23
- package/src/lib/server/rpc/types/{VerbRegistryEntry.ts → RpcRegistryEntry.ts} +3 -3
- package/src/lib/server/rpc/types/TypedResponse.ts +2 -2
- package/src/lib/server/rpc/unprocessed.ts +6 -7
- package/src/lib/server/rpc/validationError.ts +17 -0
- package/src/lib/server/runtime/buildInspectorSurface.ts +7 -7
- package/src/lib/server/runtime/buildOpenApiSpec.ts +6 -6
- package/src/lib/server/runtime/createRouteDispatcher.ts +7 -7
- package/src/lib/server/runtime/createServer.ts +4 -4
- package/src/lib/server/runtime/crossOriginForbidden.ts +1 -1
- package/src/lib/server/runtime/crossOriginGate.ts +4 -4
- package/src/lib/server/runtime/logExposedSurfaces.ts +4 -4
- package/src/lib/server/runtime/registryManifests.ts +2 -2
- package/src/lib/server/runtime/types/InspectorCacheEntry.ts +1 -1
- package/src/lib/server/runtime/types/InspectorRpc.ts +27 -0
- package/src/lib/server/runtime/types/InspectorSurface.ts +4 -4
- package/src/lib/server/runtime/types/RequestStore.ts +1 -1
- package/src/lib/server/runtime/warnUnguardedMcp.ts +2 -2
- package/src/lib/server/sockets/createSocketDispatcher.ts +15 -14
- package/src/lib/server/sockets/types/SocketOperation.ts +2 -2
- package/src/lib/shared/HttpError.ts +15 -1
- package/src/lib/shared/UNREACHABLE_STATUSES.ts +13 -0
- package/src/lib/shared/buildRpcRequest.ts +5 -5
- package/src/lib/shared/cache.ts +50 -168
- package/src/lib/shared/carriesBodyArgs.ts +4 -4
- package/src/lib/shared/createCacheStore.ts +12 -0
- package/src/lib/shared/createRemoteFunction.ts +11 -6
- package/src/lib/shared/decodeResponse.ts +2 -2
- package/src/lib/shared/detectRpcMethod.ts +17 -0
- package/src/lib/shared/emitLogRecord.ts +3 -3
- package/src/lib/shared/extraForwardHeaders.ts +1 -1
- package/src/lib/shared/findExportCallSite.ts +30 -273
- package/src/lib/shared/forwardHeaders.ts +2 -2
- package/src/lib/shared/httpErrorFor.ts +26 -0
- package/src/lib/shared/isAsciiWhitespace.ts +5 -0
- package/src/lib/shared/isIdentPart.ts +9 -0
- package/src/lib/shared/isIdentStart.ts +8 -0
- package/src/lib/shared/isReadOnlyMethod.ts +4 -4
- package/src/lib/shared/keyForRemoteCall.ts +4 -4
- package/src/lib/shared/log.ts +1 -1
- package/src/lib/shared/outboxProbeSlot.ts +20 -0
- package/src/lib/shared/pending.ts +4 -1
- package/src/lib/shared/prepareRpcModule.ts +96 -14
- package/src/lib/shared/probeRegistries.ts +17 -4
- package/src/lib/shared/queryStringFromArgs.ts +1 -1
- package/src/lib/shared/remoteMetaStore.ts +2 -2
- package/src/lib/shared/resolveClientFlags.ts +1 -1
- package/src/lib/shared/skipNonCode.ts +230 -0
- package/src/lib/shared/streamResponse.ts +9 -6
- package/src/lib/shared/stripImport.ts +3 -3
- package/src/lib/shared/types/CacheEntry.ts +2 -4
- package/src/lib/shared/types/CacheOnContext.ts +1 -11
- package/src/lib/shared/types/CacheStore.ts +13 -7
- package/src/lib/shared/types/ClientFlags.ts +1 -1
- package/src/lib/shared/types/ErrorConstructors.ts +17 -0
- package/src/lib/shared/types/ErrorDescriptor.ts +10 -0
- package/src/lib/shared/types/ErrorSpec.ts +11 -0
- package/src/lib/shared/types/HttpMethod.ts +1 -0
- package/src/lib/shared/types/Outbox.ts +9 -0
- package/src/lib/shared/types/OutboxEntry.ts +27 -0
- package/src/lib/shared/types/RawRemoteFunction.ts +2 -2
- package/src/lib/shared/types/RemoteCallable.ts +2 -2
- package/src/lib/shared/types/RemoteFunction.ts +21 -6
- package/src/lib/shared/types/RequestScopeInfo.ts +1 -1
- package/src/lib/shared/types/RpcErrorGuard.ts +40 -0
- package/src/lib/shared/types/RpcInvoker.ts +1 -1
- package/src/lib/shared/types/StandardSchemaV1.ts +1 -1
- package/src/lib/shared/types/ValidationErrorData.ts +20 -0
- package/src/lib/shared/url.ts +3 -3
- package/src/lib/shared/writeRpcDts.ts +7 -7
- package/src/lib/shared/writeTestRpcDts.ts +3 -3
- package/src/lib/test/createTestApp.ts +10 -10
- package/src/lib/ui/compile/awaitPlan.ts +48 -0
- package/src/lib/ui/compile/compileShadow.ts +89 -21
- package/src/lib/ui/compile/desugarSignals.ts +42 -6
- package/src/lib/ui/compile/generateBuild.ts +43 -60
- package/src/lib/ui/compile/generateSSR.ts +84 -54
- package/src/lib/ui/compile/ifPlan.ts +30 -0
- package/src/lib/ui/compile/parseTemplate.ts +41 -11
- package/src/lib/ui/compile/stripEffects.ts +17 -9
- package/src/lib/ui/compile/switchPlan.ts +22 -0
- package/src/lib/ui/compile/tryPlan.ts +29 -0
- package/src/lib/ui/compile/types/TemplateAttr.ts +8 -2
- package/src/lib/ui/compile/types/TemplateNode.ts +6 -2
- package/src/lib/ui/createScope.ts +20 -2
- package/src/lib/ui/dom/disposeRange.ts +6 -10
- package/src/lib/ui/dom/hydrate.ts +2 -5
- package/src/lib/ui/dom/mount.ts +1 -2
- package/src/lib/ui/dom/withScope.ts +6 -9
- package/src/lib/ui/effect.ts +4 -2
- package/src/lib/ui/navigate.ts +40 -13
- package/src/lib/ui/outbox.ts +30 -110
- package/src/lib/ui/remoteProxy.ts +160 -10
- package/src/lib/ui/router.ts +45 -15
- package/src/lib/ui/rpcOutbox/createOutboxQueue.ts +281 -0
- package/src/lib/ui/rpcOutbox/outboxRegistry.ts +69 -0
- package/src/lib/ui/socketChannel.ts +7 -1
- package/src/lib/ui/types/Scope.ts +20 -5
- package/template/CLAUDE.md +1 -1
- package/template/src/server/rpc/getHello.ts +3 -3
- package/template/test/app.test.ts +2 -2
- package/src/lib/server/rpc/registerVerb.ts +0 -6
- package/src/lib/server/runtime/types/InspectorVerb.ts +0 -27
- package/src/lib/shared/detectVerbMethod.ts +0 -17
- package/src/lib/shared/types/HttpVerb.ts +0 -1
- package/src/lib/ui/types/Outbox.ts +0 -14
|
@@ -80,7 +80,13 @@ export function getSocketChannel(): SocketChannel {
|
|
|
80
80
|
if (document.hidden) {
|
|
81
81
|
return
|
|
82
82
|
}
|
|
83
|
-
|
|
83
|
+
/* A socket reference in ANY non-closed state means one is already in play — bail.
|
|
84
|
+
CONNECTING/OPEN are healthy; CLOSING means a close event is still pending and the
|
|
85
|
+
close handler (which alone nulls `ws` and re-arms the backoff) hasn't run yet.
|
|
86
|
+
Spawning here would orphan that socket: its deferred close fires against the shared
|
|
87
|
+
`ws`, draining the fresh connection's subs and nulling it. The close handler always
|
|
88
|
+
clears `ws`, so reconnection is never stranded — it just sequences after the close. */
|
|
89
|
+
if (ws) {
|
|
84
90
|
return
|
|
85
91
|
}
|
|
86
92
|
const scheme = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { computed } from '../computed.ts'
|
|
2
|
+
import type { effect } from '../effect.ts'
|
|
2
3
|
import type { linked } from '../linked.ts'
|
|
3
4
|
import type { Cell } from '../runtime/types/Cell.ts'
|
|
4
5
|
import type { Patch } from '../runtime/types/Patch.ts'
|
|
@@ -35,14 +36,28 @@ export type Scope = {
|
|
|
35
36
|
cell: <T>(path: string) => Cell<T>
|
|
36
37
|
derive: <T>(path: string, compute: () => T) => () => T
|
|
37
38
|
snapshot: () => unknown
|
|
38
|
-
/*
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
/* The reactive primitives — namespaced under the scope, but AMBIENT-bound, not
|
|
40
|
+
receiver-bound (unlike the data methods above, which act on THIS scope's doc).
|
|
41
|
+
`state`/`linked`/`computed`/`effect` create their cell in whatever scope is currently
|
|
42
|
+
rendering and own their teardown to the finest ambient BUILD WINDOW — a control-flow
|
|
43
|
+
branch or list row, not the whole component. So `someScope.computed(fn)` does NOT
|
|
44
|
+
create state in someScope; the receiver is namespacing only, the cells bind the
|
|
45
|
+
ambient window. Binding them to the receiver instead would leak a branch-local cell
|
|
46
|
+
past a branch flip (the build window is finer-grained than the lexical scope — see
|
|
47
|
+
ADR-0012). Forms: a writable `state(x, transform)` gate, a reseeding `linked`, the
|
|
48
|
+
read-only `computed(compute)` (a writable computed does not exist — that write is
|
|
49
|
+
expressed at the binding `bind:value={{ get, set }}`; the serializable computed doc
|
|
50
|
+
slot is `derive` above), and `effect`, the reaction re-run on dep change (the SSR
|
|
51
|
+
back-end strips it — effects are client lifecycle). */
|
|
43
52
|
state: typeof state
|
|
44
53
|
linked: typeof linked
|
|
45
54
|
computed: typeof computed
|
|
55
|
+
effect: typeof effect
|
|
56
|
+
/* Adopts a teardown into this scope's lifetime — the build's reactivity stopper
|
|
57
|
+
(effects/listeners), run first on `dispose` (before children, before capabilities).
|
|
58
|
+
Internal: the mount core registers the build's disposer here so a component has ONE
|
|
59
|
+
teardown (`dispose`) rather than a separate stop + dispose composed at every site. */
|
|
60
|
+
own: (dispose: () => void) => void
|
|
46
61
|
/* tree */
|
|
47
62
|
child: (initial?: unknown) => Scope
|
|
48
63
|
root: () => Scope
|
package/template/CLAUDE.md
CHANGED
|
@@ -15,7 +15,7 @@ at `node_modules/@abide/abide/README.md`.
|
|
|
15
15
|
|
|
16
16
|
- One export per file, named after the file. No barrels — import each name by its
|
|
17
17
|
own path (`@abide/abide/server/GET`, `@abide/abide/shared/cache`, …).
|
|
18
|
-
-
|
|
18
|
+
- RPCs live in `src/server/rpc/<name>.ts`; sockets in `src/server/sockets/`;
|
|
19
19
|
pages are `**/page.abide`, layouts `**/layout.abide`.
|
|
20
20
|
- Generated types land in `src/.abide/` — do not hand-edit them; run `abide dev`/
|
|
21
21
|
`abide check` to regenerate.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/*
|
|
2
|
-
RPC module — every file under src/server/rpc/ exposes exactly one
|
|
2
|
+
RPC module — every file under src/server/rpc/ exposes exactly one RPC: a remote
|
|
3
3
|
function. The filename is the export name and the URL path (under `/rpc/`),
|
|
4
|
-
and the imported
|
|
5
|
-
HTTP method. The bundler swaps the runtime per build target: direct call on
|
|
4
|
+
and the imported method helper (GET / POST / PUT / PATCH / DELETE / HEAD) picks
|
|
5
|
+
the HTTP method. The bundler swaps the runtime per build target: direct call on
|
|
6
6
|
the server, fetch over the network on the client.
|
|
7
7
|
|
|
8
8
|
Args (what the caller passes in) come from the handler's parameter type —
|
|
@@ -3,12 +3,12 @@ Test module — `createTestApp()` boots your real app on an ephemeral port (the
|
|
|
3
3
|
same wiring as `abide start`, no fixtures) and hands back the whole surface:
|
|
4
4
|
|
|
5
5
|
app.fetch(path) — pages and raw HTTP, origin + mount base resolved
|
|
6
|
-
app.rpc.<
|
|
6
|
+
app.rpc.<name>(args) — RPCs over the real pipeline (CSRF, cookies, base),
|
|
7
7
|
typed and decoded; .raw(args) for the Response
|
|
8
8
|
app.sockets.<name> — a live Socket: iterate it, .tail(n), .publish(m)
|
|
9
9
|
app.health() — the /__abide/health payload
|
|
10
10
|
|
|
11
|
-
`app.rpc` / `app.sockets` are typed from your own
|
|
11
|
+
`app.rpc` / `app.sockets` are typed from your own RPCs and sockets — generated
|
|
12
12
|
into src/.abide during a build, so the keys exist with no imports. The abide
|
|
13
13
|
preload (see bunfig.toml) makes the project's routes resolvable under bun test.
|
|
14
14
|
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
One RPC verb projected for the inspector: the registry entry reduced to the
|
|
3
|
-
serializable facts the UI renders — where it mounts, its method, which
|
|
4
|
-
non-browser surfaces advertise it, and its argument/result shapes as JSON
|
|
5
|
-
Schema. Schemas project through jsonSchemaForSchema (same as MCP/OpenAPI), so
|
|
6
|
-
a verb whose library can't render a schema still lists with an opaque shape.
|
|
7
|
-
*/
|
|
8
|
-
export type InspectorVerb = {
|
|
9
|
-
/* Registry key — the rpc URL the verb mounts at (e.g. /rpc/users/create). */
|
|
10
|
-
url: string
|
|
11
|
-
/* HTTP method bound to the verb. */
|
|
12
|
-
method: string
|
|
13
|
-
/* Which surfaces advertise it (browser/mcp/cli), from the verb's ClientFlags. */
|
|
14
|
-
clients: Record<string, boolean>
|
|
15
|
-
/* Argument-bag shape as JSON Schema; undefined when the verb declares none. */
|
|
16
|
-
inputSchema: Record<string, unknown> | undefined
|
|
17
|
-
/* Success-body shape as JSON Schema; undefined when the verb declares none. */
|
|
18
|
-
outputSchema: Record<string, unknown> | undefined
|
|
19
|
-
/* True when the verb declares a filesSchema — it accepts multipart File parts. */
|
|
20
|
-
files: boolean
|
|
21
|
-
/* Per-verb handler deadline in ms; undefined = no deadline. */
|
|
22
|
-
timeout: number | undefined
|
|
23
|
-
/* Per-verb received-body cap in bytes; undefined = Bun's server-wide ceiling. */
|
|
24
|
-
maxBodySize: number | undefined
|
|
25
|
-
/* True when the verb opts out of the same-origin CSRF gate. */
|
|
26
|
-
crossOrigin: boolean | undefined
|
|
27
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { HttpVerb } from './types/HttpVerb.ts'
|
|
2
|
-
|
|
3
|
-
/*
|
|
4
|
-
Reads the HTTP verb of an $rpc module from its source. Every file under
|
|
5
|
-
src/server/rpc/ follows the convention `export const <name> = GET(fn)` (the
|
|
6
|
-
verb helper picks the method, possibly with an explicit generic
|
|
7
|
-
`GET<{…}>(fn)`), so the helper name at the export is the method. Returns
|
|
8
|
-
undefined when no verb export matches — the caller skips the file rather
|
|
9
|
-
than guessing. Used by the rpc.d.ts codegen to type url() against
|
|
10
|
-
query-carrying verbs; matching the same convention the bundler rewrites
|
|
11
|
-
keeps the two from drifting.
|
|
12
|
-
*/
|
|
13
|
-
const VERB_EXPORT = /export\s+const\s+\w+\s*=\s*(GET|POST|PUT|PATCH|DELETE|HEAD)\s*[<(]/
|
|
14
|
-
|
|
15
|
-
export function detectVerbMethod(source: string): HttpVerb | undefined {
|
|
16
|
-
return (source.match(VERB_EXPORT)?.[1] as HttpVerb | undefined) ?? undefined
|
|
17
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export type HttpVerb = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD'
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
A durable, FIFO queue of pending mutations that drains when the client is online —
|
|
3
|
-
the local-first half of "act now, sync later". `enqueue` records a serializable
|
|
4
|
-
payload (persisted, so it survives a reload) and tries to drain; `pending` is a
|
|
5
|
-
reactive read of the payloads still in flight (for a "3 unsynced" indicator);
|
|
6
|
-
`flush` drains on demand (and is what the reconnect effect calls); `dispose` stops
|
|
7
|
-
draining and detaches persistence.
|
|
8
|
-
*/
|
|
9
|
-
export type Outbox<T> = {
|
|
10
|
-
enqueue: (payload: T) => void
|
|
11
|
-
pending: () => T[]
|
|
12
|
-
flush: () => Promise<void>
|
|
13
|
-
dispose: () => void
|
|
14
|
-
}
|