@abide/abide 0.48.0 → 0.50.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.
Files changed (360) hide show
  1. package/AGENTS.md +85 -59
  2. package/CHANGELOG.md +216 -0
  3. package/README.md +21 -10
  4. package/package.json +15 -4
  5. package/src/abideLsp.ts +5 -6
  6. package/src/abideResolverPlugin.ts +197 -169
  7. package/src/build.ts +79 -56
  8. package/src/buildCli.ts +3 -5
  9. package/src/buildDisconnected.ts +2 -5
  10. package/src/bundleApp.ts +2 -3
  11. package/src/checkAbide.ts +12 -2
  12. package/src/compile.ts +2 -4
  13. package/src/devEntry.ts +113 -28
  14. package/src/discoveryEntry.ts +3 -2
  15. package/src/lib/bundle/disconnected.abide +69 -73
  16. package/src/lib/bundle/infoPlist.ts +13 -7
  17. package/src/lib/bundle/installDownloads.ts +13 -3
  18. package/src/lib/bundle/installMacMenu.ts +13 -3
  19. package/src/lib/bundle/spawnEmbeddedServer.ts +13 -4
  20. package/src/lib/bundle/waitForServer.ts +6 -1
  21. package/src/lib/cli/parseArgvForRpc.ts +36 -9
  22. package/src/lib/cli/tokenizeArgvFlags.ts +4 -2
  23. package/src/lib/mcp/createMcpResourceServer.ts +13 -2
  24. package/src/lib/mcp/mcpTools.ts +15 -6
  25. package/src/lib/mcp/toolResultFromResponse.ts +40 -12
  26. package/src/lib/server/error.ts +6 -6
  27. package/src/lib/server/json.ts +17 -3
  28. package/src/lib/server/rpc/defineRpc.ts +58 -24
  29. package/src/lib/server/rpc/parseArgs.ts +113 -14
  30. package/src/lib/server/rpc/resolveRpcJsonSchema.ts +28 -0
  31. package/src/lib/server/rpc/runWithRpcTimeout.ts +12 -1
  32. package/src/lib/server/rpc/types/RpcHelper.ts +75 -105
  33. package/src/lib/server/rpc/types/RpcRegistryEntry.ts +24 -9
  34. package/src/lib/server/rpc/validationError.ts +1 -1
  35. package/src/lib/server/runtime/DEV_RELOAD_CLIENT_SCRIPT.ts +0 -15
  36. package/src/lib/server/runtime/buildCacheSnapshot.ts +10 -9
  37. package/src/lib/server/runtime/buildInspectorSurface.ts +6 -4
  38. package/src/lib/server/runtime/buildOpenApiSpec.ts +55 -11
  39. package/src/lib/server/runtime/buildPreloadManifest.ts +12 -10
  40. package/src/lib/server/runtime/createAppAssetServer.ts +18 -15
  41. package/src/lib/server/runtime/createAppRouteResolver.ts +145 -0
  42. package/src/lib/server/runtime/createPlumbingRouter.ts +212 -0
  43. package/src/lib/server/runtime/createRouteDispatcher.ts +4 -10
  44. package/src/lib/server/runtime/createServer.ts +120 -324
  45. package/src/lib/server/runtime/createUiPageRenderer.ts +137 -26
  46. package/src/lib/server/runtime/devClientFingerprint.ts +19 -34
  47. package/src/lib/server/runtime/finalizeResponse.ts +11 -1
  48. package/src/lib/server/runtime/installAmbientScopeStore.ts +30 -9
  49. package/src/lib/server/runtime/logExposedSurfaces.ts +8 -7
  50. package/src/lib/server/runtime/pathStore.ts +15 -0
  51. package/src/lib/server/runtime/registryManifests.ts +1 -1
  52. package/src/lib/server/runtime/renderCellBarrierStore.ts +15 -0
  53. package/src/lib/server/runtime/runWithRequestScope.ts +3 -0
  54. package/src/lib/server/runtime/serializeCacheSnapshot.ts +6 -4
  55. package/src/lib/server/runtime/snapshotEntryFromCache.ts +24 -16
  56. package/src/lib/server/runtime/streamCacheResolutions.ts +14 -7
  57. package/src/lib/server/runtime/streamFromIterator.ts +30 -2
  58. package/src/lib/server/runtime/textResponse.ts +23 -0
  59. package/src/lib/server/runtime/types/DevReloadStamp.ts +6 -10
  60. package/src/lib/server/runtime/types/InspectorCacheEntry.ts +1 -1
  61. package/src/lib/server/runtime/types/RequestStore.ts +27 -0
  62. package/src/lib/server/runtime/warnUnguardedMcp.ts +15 -5
  63. package/src/lib/server/sockets/createSocketDispatcher.ts +9 -11
  64. package/src/lib/server/sockets/defineSocket.ts +5 -4
  65. package/src/lib/server/sse.ts +5 -1
  66. package/src/lib/shared/ASYNC_CELL.ts +5 -0
  67. package/src/lib/shared/DEV_REBUILD_PATH.ts +6 -0
  68. package/src/lib/shared/HTTP_METHODS.ts +6 -0
  69. package/src/lib/shared/HttpError.ts +1 -5
  70. package/src/lib/shared/MCP_PATH.ts +6 -0
  71. package/src/lib/shared/PROXIED_SERVER_SUBDIRS.ts +15 -0
  72. package/src/lib/shared/REF_JSON_TAGS.ts +13 -1
  73. package/src/lib/shared/RPC_SHIM_GLOBALS.ts +9 -0
  74. package/src/lib/shared/activeCacheStore.ts +1 -0
  75. package/src/lib/shared/activePage.ts +1 -0
  76. package/src/lib/shared/buildArtifact.ts +20 -0
  77. package/src/lib/shared/buildRpcRequest.ts +6 -2
  78. package/src/lib/shared/buildSocketOverChannel.ts +4 -3
  79. package/src/lib/shared/bundleGraphFromMetafile.ts +68 -0
  80. package/src/lib/shared/cache.ts +156 -131
  81. package/src/lib/shared/canonicalJson.ts +24 -1
  82. package/src/lib/shared/changeAffectsClient.ts +12 -7
  83. package/src/lib/shared/createCacheStore.ts +31 -8
  84. package/src/lib/shared/createChannelLog.ts +24 -0
  85. package/src/lib/shared/createLifecycleChannel.ts +7 -1
  86. package/src/lib/shared/createReachable.ts +47 -78
  87. package/src/lib/shared/createRemoteFunction.ts +52 -30
  88. package/src/lib/shared/createRpcServerProgram.ts +820 -0
  89. package/src/lib/shared/decodeRefJson.ts +4 -4
  90. package/src/lib/shared/decodeResponse.ts +2 -2
  91. package/src/lib/shared/decodeWireBody.ts +35 -0
  92. package/src/lib/shared/detectRpcMethod.ts +8 -1
  93. package/src/lib/shared/done.ts +8 -2
  94. package/src/lib/shared/encodeRefJson.ts +4 -4
  95. package/src/lib/shared/encodeWireBody.ts +18 -0
  96. package/src/lib/shared/exitOnBuildFailure.ts +4 -3
  97. package/src/lib/{server/rpc → shared}/fieldErrorsFromIssues.ts +5 -1
  98. package/src/lib/shared/generateDeclarations.ts +72 -0
  99. package/src/lib/shared/hasSeedableRequest.ts +25 -0
  100. package/src/lib/shared/hydrationWindow.ts +53 -0
  101. package/src/lib/shared/isAsyncCell.ts +11 -0
  102. package/src/lib/shared/isAsyncIterable.ts +8 -0
  103. package/src/lib/shared/isSubscribable.ts +3 -3
  104. package/src/lib/shared/isThenable.ts +9 -0
  105. package/src/lib/shared/jsonSchemaForType.ts +258 -0
  106. package/src/lib/shared/lenientDecode.ts +15 -0
  107. package/src/lib/shared/loadProjectTsConfig.ts +28 -0
  108. package/src/lib/shared/markFrameworkSourcesIgnored.ts +1 -1
  109. package/src/lib/shared/matchRoute.ts +4 -14
  110. package/src/lib/shared/parseEnv.ts +17 -6
  111. package/src/lib/shared/peek.ts +14 -0
  112. package/src/lib/shared/pending.ts +9 -6
  113. package/src/lib/shared/pendingAsyncCellsSlot.ts +13 -0
  114. package/src/lib/shared/prepareRpcModule.ts +91 -93
  115. package/src/lib/shared/prepareSocketModule.ts +3 -2
  116. package/src/lib/shared/probeRegistries.ts +5 -18
  117. package/src/lib/shared/reachable.ts +7 -10
  118. package/src/lib/shared/refresh.ts +12 -2
  119. package/src/lib/shared/refreshing.ts +8 -2
  120. package/src/lib/shared/resolvedCellsSlot.ts +13 -0
  121. package/src/lib/shared/reviveWireField.ts +49 -0
  122. package/src/lib/shared/reviveWireOutput.ts +36 -0
  123. package/src/lib/shared/rpcServerForRoot.ts +25 -0
  124. package/src/lib/shared/scanPages.ts +25 -0
  125. package/src/lib/shared/serializeEnv.ts +18 -6
  126. package/src/lib/shared/snapshotShippable.ts +8 -7
  127. package/src/lib/shared/snippet.ts +11 -6
  128. package/src/lib/shared/streamedCellsSlot.ts +14 -0
  129. package/src/lib/shared/subscribableFromResponse.ts +4 -4
  130. package/src/lib/shared/subscribableProbes.ts +1 -1
  131. package/src/lib/shared/tailProbeSlot.ts +1 -1
  132. package/src/lib/shared/types/AsyncComputed.ts +20 -0
  133. package/src/lib/shared/types/AsyncState.ts +13 -0
  134. package/src/lib/shared/types/CacheEntry.ts +7 -7
  135. package/src/lib/shared/types/CacheOptions.ts +23 -37
  136. package/src/lib/shared/types/CachePolicy.ts +25 -0
  137. package/src/lib/shared/types/CacheSnapshotEntry.ts +6 -5
  138. package/src/lib/shared/types/ErrorJsonSchemas.ts +8 -0
  139. package/src/lib/shared/types/HttpMethod.ts +3 -1
  140. package/src/lib/shared/types/InputCoercion.ts +17 -0
  141. package/src/lib/shared/types/{Subscribable.ts → NamedAsyncIterable.ts} +1 -1
  142. package/src/lib/shared/types/OutputWirePlan.ts +17 -0
  143. package/src/lib/shared/types/PagesScan.ts +7 -0
  144. package/src/lib/shared/types/PendingAsyncCells.ts +10 -0
  145. package/src/lib/shared/types/RawRemoteFunction.ts +6 -0
  146. package/src/lib/shared/types/RemoteCallable.ts +8 -7
  147. package/src/lib/shared/types/RemoteFunction.ts +16 -15
  148. package/src/lib/shared/types/ResolvedCells.ts +11 -0
  149. package/src/lib/shared/types/ReturnBody.ts +15 -0
  150. package/src/lib/shared/types/RpcBuildStamps.ts +23 -0
  151. package/src/lib/shared/types/RpcErrorGuard.ts +3 -8
  152. package/src/lib/shared/types/Socket.ts +4 -4
  153. package/src/lib/shared/types/SsrPayload.ts +5 -1
  154. package/src/lib/shared/types/StreamPolicy.ts +11 -0
  155. package/src/lib/shared/types/StreamedCells.ts +19 -0
  156. package/src/lib/shared/types/StreamedResolution.ts +24 -6
  157. package/src/lib/shared/types/TailHooks.ts +1 -1
  158. package/src/lib/shared/types/WireKind.ts +11 -0
  159. package/src/lib/shared/url.ts +5 -0
  160. package/src/lib/shared/validationHttpError.ts +33 -0
  161. package/src/lib/shared/warmSeedKey.ts +16 -0
  162. package/src/lib/shared/wireJsonReplacer.ts +30 -0
  163. package/src/lib/shared/writeRpcDts.ts +11 -1
  164. package/src/lib/shared/writeTestSocketsDts.ts +1 -1
  165. package/src/lib/test/createTestApp.ts +19 -1
  166. package/src/lib/ui/README.md +1 -1
  167. package/src/lib/ui/activePendingCells.ts +14 -0
  168. package/src/lib/ui/compile/BLOCK_KEYWORDS.ts +21 -0
  169. package/src/lib/ui/compile/SSR_ESCAPE.ts +4 -1
  170. package/src/lib/ui/compile/UI_RUNTIME_IMPORTS.ts +35 -7
  171. package/src/lib/ui/compile/abideUiPlugin.ts +19 -2
  172. package/src/lib/ui/compile/analyzeComponent.ts +89 -6
  173. package/src/lib/ui/compile/assignmentTargetNames.ts +54 -0
  174. package/src/lib/ui/compile/asyncInterpolationFields.ts +152 -0
  175. package/src/lib/ui/compile/asyncValuePositionError.ts +21 -0
  176. package/src/lib/ui/compile/asyncValuePositionInterpolations.ts +64 -0
  177. package/src/lib/ui/compile/attrLiftPosition.ts +18 -0
  178. package/src/lib/ui/compile/bindListenEvent.ts +5 -6
  179. package/src/lib/ui/compile/cachedSourceFile.ts +40 -0
  180. package/src/lib/ui/compile/catchBinding.ts +7 -5
  181. package/src/lib/ui/compile/classifyInterpolationType.ts +46 -0
  182. package/src/lib/ui/compile/collectAbideDiagnostics.ts +96 -0
  183. package/src/lib/ui/compile/compileComponent.ts +19 -3
  184. package/src/lib/ui/compile/compileModule.ts +27 -58
  185. package/src/lib/ui/compile/compileSSR.ts +52 -13
  186. package/src/lib/ui/compile/compileShadow.ts +265 -42
  187. package/src/lib/ui/compile/composeProps.ts +15 -4
  188. package/src/lib/ui/compile/createShadowLanguageService.ts +116 -68
  189. package/src/lib/ui/compile/createShadowProgram.ts +35 -6
  190. package/src/lib/ui/compile/declaredNames.ts +36 -0
  191. package/src/lib/ui/compile/desugarSignals.ts +419 -37
  192. package/src/lib/ui/compile/expressionIsPrefixEvaluable.ts +19 -0
  193. package/src/lib/ui/compile/generateBuild.ts +74 -17
  194. package/src/lib/ui/compile/generateSSR.ts +286 -75
  195. package/src/lib/ui/compile/hoistableAwaits.ts +193 -0
  196. package/src/lib/ui/compile/hoistableChildRenders.ts +112 -0
  197. package/src/lib/ui/compile/interpolatedTemplateLiteral.ts +3 -1
  198. package/src/lib/ui/compile/interpolationClassifierForRoot.ts +37 -0
  199. package/src/lib/ui/compile/isSpuriousAsyncReadDiagnostic.ts +174 -0
  200. package/src/lib/ui/compile/isWhitespaceText.ts +10 -2
  201. package/src/lib/ui/compile/liftAsyncSubExpressions.ts +166 -0
  202. package/src/lib/ui/compile/lowerAsyncInterpolations.ts +92 -0
  203. package/src/lib/ui/compile/lowerContext.ts +10 -0
  204. package/src/lib/ui/compile/lowerDocAccess.ts +51 -10
  205. package/src/lib/ui/compile/lowerScript.ts +40 -4
  206. package/src/lib/ui/compile/nodeAtShadowOffset.ts +28 -0
  207. package/src/lib/ui/compile/parseTemplate.ts +18 -1090
  208. package/src/lib/ui/compile/parseTemplateRecovering.ts +1385 -0
  209. package/src/lib/ui/compile/referencedIdentifiers.ts +35 -0
  210. package/src/lib/ui/compile/renameSignalRefs.ts +26 -40
  211. package/src/lib/ui/compile/resolveReactiveExport.ts +4 -7
  212. package/src/lib/ui/compile/scopeCss.ts +27 -4
  213. package/src/lib/ui/compile/seedTypeClassifierForRoot.ts +65 -0
  214. package/src/lib/ui/compile/shadowInterpolationClassifier.ts +47 -0
  215. package/src/lib/ui/compile/sourceFileOptionsSignature.ts +20 -0
  216. package/src/lib/ui/compile/structuralHeadTokens.ts +107 -0
  217. package/src/lib/ui/compile/templateSemanticTokens.ts +21 -0
  218. package/src/lib/ui/compile/templateStartOffset.ts +15 -0
  219. package/src/lib/ui/compile/tryPlan.ts +4 -3
  220. package/src/lib/ui/compile/types/AnalyzedComponent.ts +4 -0
  221. package/src/lib/ui/compile/types/AsyncInterpolationField.ts +19 -0
  222. package/src/lib/ui/compile/types/InterpolationClassifier.ts +12 -0
  223. package/src/lib/ui/compile/types/InterpolationKind.ts +7 -0
  224. package/src/lib/ui/compile/types/ParseDiagnostic.ts +8 -0
  225. package/src/lib/ui/compile/types/SeedTypeClassifier.ts +15 -0
  226. package/src/lib/ui/compile/types/TemplateNode.ts +36 -4
  227. package/src/lib/ui/compile/types/ValuePositionInterpolation.ts +13 -0
  228. package/src/lib/ui/compile/writtenTemplateNames.ts +84 -0
  229. package/src/lib/ui/computed.ts +28 -1
  230. package/src/lib/ui/createScope.ts +35 -68
  231. package/src/lib/ui/dom/anchoredBranch.ts +142 -0
  232. package/src/lib/ui/dom/appendText.ts +8 -3
  233. package/src/lib/ui/dom/awaitBlock.ts +62 -75
  234. package/src/lib/ui/dom/bindProp.ts +22 -0
  235. package/src/lib/ui/dom/bindableProp.ts +47 -0
  236. package/src/lib/ui/dom/cellPending.ts +24 -0
  237. package/src/lib/ui/dom/discardBoundary.ts +24 -6
  238. package/src/lib/ui/dom/disposeRange.ts +2 -1
  239. package/src/lib/ui/dom/each.ts +41 -12
  240. package/src/lib/ui/dom/eachAsync.ts +39 -3
  241. package/src/lib/ui/dom/fillBefore.ts +6 -7
  242. package/src/lib/ui/dom/fillBoundary.ts +2 -3
  243. package/src/lib/ui/dom/fillRange.ts +4 -4
  244. package/src/lib/ui/dom/hydrate.ts +6 -12
  245. package/src/lib/ui/dom/isComment.ts +1 -1
  246. package/src/lib/ui/dom/matchingRangeClose.ts +29 -0
  247. package/src/lib/ui/dom/mergeProps.ts +1 -1
  248. package/src/lib/ui/dom/mount.ts +1 -2
  249. package/src/lib/ui/dom/mountChild.ts +9 -40
  250. package/src/lib/ui/dom/mountRange.ts +2 -3
  251. package/src/lib/ui/dom/mountSlot.ts +1 -1
  252. package/src/lib/ui/dom/mountStreamedChild.ts +84 -0
  253. package/src/lib/ui/dom/mountSwappableRange.ts +46 -4
  254. package/src/lib/ui/dom/mutateDocContainer.ts +65 -0
  255. package/src/lib/ui/dom/on.ts +2 -2
  256. package/src/lib/ui/dom/readCell.ts +40 -0
  257. package/src/lib/ui/dom/restProps.ts +2 -2
  258. package/src/lib/ui/dom/spreadProps.ts +3 -4
  259. package/src/lib/ui/dom/switchBlock.ts +30 -7
  260. package/src/lib/ui/dom/tryBlock.ts +233 -70
  261. package/src/lib/ui/dom/types/SwitchCase.ts +5 -1
  262. package/src/lib/ui/dom/when.ts +12 -2
  263. package/src/lib/ui/dom/withScope.ts +9 -2
  264. package/src/lib/ui/finalizeStreamedChildren.ts +89 -0
  265. package/src/lib/ui/flight.ts +56 -0
  266. package/src/lib/ui/html.ts +12 -1
  267. package/src/lib/ui/isolateCellBarrier.ts +17 -0
  268. package/src/lib/ui/linked.ts +48 -2
  269. package/src/lib/ui/props.ts +17 -0
  270. package/src/lib/ui/remoteProxy.ts +84 -159
  271. package/src/lib/ui/renderChain.ts +53 -13
  272. package/src/lib/ui/renderToStream.ts +22 -18
  273. package/src/lib/ui/resumeSeedScript.ts +1 -1
  274. package/src/lib/ui/router.ts +86 -53
  275. package/src/lib/ui/runtime/AsyncCellError.ts +20 -0
  276. package/src/lib/ui/runtime/CELL_SEED.ts +14 -0
  277. package/src/lib/ui/runtime/CHILD_PRESENT.ts +2 -2
  278. package/src/lib/ui/runtime/CURRENT_BOUNDARY.ts +11 -0
  279. package/src/lib/ui/runtime/CURRENT_PATH.ts +29 -0
  280. package/src/lib/ui/runtime/RENDER.ts +10 -7
  281. package/src/lib/ui/runtime/RESUME.ts +4 -4
  282. package/src/lib/ui/runtime/STREAMED_CELLS.ts +57 -0
  283. package/src/lib/ui/runtime/ambientPathBacking.ts +32 -0
  284. package/src/lib/ui/runtime/applyPatchToTree.ts +17 -4
  285. package/src/lib/ui/runtime/blockId.ts +31 -0
  286. package/src/lib/ui/runtime/boundaryFor.ts +11 -0
  287. package/src/lib/ui/runtime/cellBarrierBacking.ts +30 -0
  288. package/src/lib/ui/runtime/createAsyncCell.ts +300 -0
  289. package/src/lib/ui/runtime/createDoc.ts +31 -54
  290. package/src/lib/ui/runtime/createEffectNode.ts +9 -0
  291. package/src/lib/ui/runtime/enterRenderPass.ts +5 -4
  292. package/src/lib/ui/runtime/flushEffects.ts +33 -1
  293. package/src/lib/ui/runtime/isAsyncFunction.ts +14 -0
  294. package/src/lib/ui/runtime/nextBlockId.ts +8 -7
  295. package/src/lib/ui/runtime/renderPath.ts +16 -0
  296. package/src/lib/ui/runtime/scope.ts +11 -0
  297. package/src/lib/ui/runtime/toTeardown.ts +10 -3
  298. package/src/lib/ui/runtime/types/Boundary.ts +9 -0
  299. package/src/lib/ui/runtime/types/RenderContext.ts +9 -7
  300. package/src/lib/ui/runtime/types/SsrRender.ts +9 -2
  301. package/src/lib/ui/runtime/types/UiComponent.ts +1 -5
  302. package/src/lib/ui/runtime/types/UiProps.ts +6 -5
  303. package/src/lib/ui/runtime/withOptionalPath.ts +8 -0
  304. package/src/lib/ui/runtime/withPath.ts +16 -0
  305. package/src/lib/ui/runtime/withPathFrom.ts +20 -0
  306. package/src/lib/ui/runtime/withoutHydration.ts +22 -0
  307. package/src/lib/ui/seedStreamedResolution.ts +31 -6
  308. package/src/lib/ui/settleAsyncCells.ts +24 -0
  309. package/src/lib/ui/socketProxy.ts +1 -1
  310. package/src/lib/ui/startClient.ts +16 -31
  311. package/src/lib/ui/state.ts +9 -3
  312. package/src/lib/ui/trackedComputed.ts +68 -0
  313. package/src/lib/ui/types/Scope.ts +8 -24
  314. package/src/lib/ui/watch.ts +3 -3
  315. package/src/serverEntry.ts +14 -0
  316. package/template/src/server/rpc/getHello.ts +15 -13
  317. package/template/test/app.test.ts +1 -1
  318. package/src/lib/server/runtime/devHotModuleResponse.ts +0 -41
  319. package/src/lib/shared/DEV_HOT_PREFIX.ts +0 -7
  320. package/src/lib/shared/UNREACHABLE_STATUSES.ts +0 -13
  321. package/src/lib/shared/hasReplayableRequest.ts +0 -17
  322. package/src/lib/shared/hydratingSlot.ts +0 -12
  323. package/src/lib/shared/outboxProbeSlot.ts +0 -20
  324. package/src/lib/shared/types/Outbox.ts +0 -9
  325. package/src/lib/shared/types/OutboxEntry.ts +0 -27
  326. package/src/lib/shared/types/SmartReadOptions.ts +0 -36
  327. package/src/lib/shared/wakeHydrationPeeks.ts +0 -20
  328. package/src/lib/ui/COMPONENT_WRAPPER_PREFIX.ts +0 -5
  329. package/src/lib/ui/compile/REACTIVE_CALLEES.ts +0 -11
  330. package/src/lib/ui/compile/assertRuntimeHelpersBound.ts +0 -80
  331. package/src/lib/ui/compile/markupTokens.ts +0 -313
  332. package/src/lib/ui/compile/structuralBlockTokens.ts +0 -100
  333. package/src/lib/ui/dom/applyResolved.ts +0 -87
  334. package/src/lib/ui/dom/scopeLabel.ts +0 -21
  335. package/src/lib/ui/dom/text.ts +0 -20
  336. package/src/lib/ui/history.ts +0 -101
  337. package/src/lib/ui/installHotBridge.ts +0 -93
  338. package/src/lib/ui/installInspectorBridge.ts +0 -140
  339. package/src/lib/ui/outbox.ts +0 -35
  340. package/src/lib/ui/persist.ts +0 -115
  341. package/src/lib/ui/rpcOutbox/createOutboxQueue.ts +0 -281
  342. package/src/lib/ui/rpcOutbox/outboxRegistry.ts +0 -69
  343. package/src/lib/ui/runtime/PATCH_BUS.ts +0 -28
  344. package/src/lib/ui/runtime/captureModelDoc.ts +0 -28
  345. package/src/lib/ui/runtime/hotInstances.ts +0 -10
  346. package/src/lib/ui/runtime/hotReloadEnabled.ts +0 -8
  347. package/src/lib/ui/runtime/hotReplace.ts +0 -38
  348. package/src/lib/ui/runtime/liveScopes.ts +0 -15
  349. package/src/lib/ui/runtime/localStoragePersistence.ts +0 -47
  350. package/src/lib/ui/runtime/registerHotInstance.ts +0 -23
  351. package/src/lib/ui/runtime/seedModelDoc.ts +0 -26
  352. package/src/lib/ui/runtime/types/HotInstance.ts +0 -22
  353. package/src/lib/ui/runtime/types/PatchEvent.ts +0 -16
  354. package/src/lib/ui/seedResolved.ts +0 -28
  355. package/src/lib/ui/sync.ts +0 -48
  356. package/src/lib/ui/types/History.ts +0 -14
  357. package/src/lib/ui/types/PersistHandle.ts +0 -11
  358. package/src/lib/ui/types/PersistenceStore.ts +0 -12
  359. package/src/lib/ui/types/ResolvedFrame.ts +0 -15
  360. package/src/lib/ui/types/SyncTransport.ts +0 -13
package/AGENTS.md CHANGED
@@ -26,7 +26,7 @@ src/server/rpc/getMessages.ts
26
26
  └─ OpenAPI operation in /openapi.json
27
27
  ```
28
28
 
29
- An `inputSchema` (any Standard Schema library — zod, valibot, arktype,
29
+ A `schemas.input` (any Standard Schema library — zod, valibot, arktype,
30
30
  unadapted) is the gate: it unlocks the CLI, and for read-only methods
31
31
  (GET/HEAD) the MCP tool. A mutating method (POST/PUT/PATCH/DELETE) never
32
32
  auto-exposes to MCP — it requires explicit `clients: { mcp: true }`.
@@ -76,35 +76,43 @@ For tests, add `preload = ["@abide/abide/preload"]` under `[test]` in
76
76
  ## Authoring contracts
77
77
 
78
78
  **RPC** — the handler receives the schema-validated args
79
- (`InferOutput<inputSchema>`); typed generics on the helper are a compile error
79
+ (`InferOutput<schemas.input>`); typed generics on the helper are a compile error
80
80
  — type the parameter, let the body infer. Inside it, `request()` / `cookies()`
81
81
  / `server()` read the request scope. Return `json(data)` (or `jsonl` / `sse`
82
- for streams, `error` / `redirect`, or a raw `Response`). Options:
83
- `inputSchema`, `outputSchema`, `filesSchema` (validates uploaded `File` parts,
84
- kept out of the JSON-Schema projection), `clients: { browser, mcp, cli }`,
85
- `crossOrigin` (exempts a mutating rpc from the same-origin CSRF gate),
82
+ for streams, `error` / `redirect`, or a raw `Response`). Options are namespaced
83
+ (ADR-0020): `schemas: { input, output, files }` (`files` validates uploaded
84
+ `File` parts, kept out of the JSON-Schema projection); `clients: { browser, mcp,
85
+ cli }`; `crossOrigin` (exempts a mutating rpc from the same-origin CSRF gate);
86
86
  `timeout` (handler deadline in ms → 504 on every surface, composed into
87
- `request().signal`), `maxBodySize` (per-rpc 413 cap), `outbox` (durable
88
- delivery, mutating methods only). Query args on GET/HEAD/DELETE travel as
89
- strings coerce in the schema (`z.coerce.number()`). A body rpc also accepts
87
+ `request().signal`); `maxBodySize` (per-rpc 413 cap); on read helpers (GET/HEAD)
88
+ `cache: { ttl, tags, throttle, debounce, shared }` (the endpoint's
89
+ retention/refetch policy) and `stream: { n }` (replay depth). Kind-scoped by type:
90
+ `cache`/`stream` on a write is a compile error. Query args on GET/HEAD/DELETE travel as
91
+ strings — coerce in the schema (`z.coerce.number()`). Beyond scalars, a
92
+ type-directed wire codec (ADR-0028/0029) revives a top-level arg field into the
93
+ runtime value its declared type names — a numeric string → `number`/`bigint`, a
94
+ `Date` from an ISO string, a `Set` from a JSON array, a `Map` from an entries
95
+ array/object — resolved through the warm server program; reviving is fail-open
96
+ (an unrevivable value passes through as its JSON form). A body rpc also accepts
90
97
  a `FormData` in place of typed args (the upload escape hatch): text fields
91
- validate as args, `File` parts validate against `filesSchema`.
92
-
93
- **Consuming an rpc** — the bare call `fn(args, opts?)` IS the smart read:
94
- cached, coalesced, reactive, stale-while-revalidate for replayable (GET/HEAD)
95
- reads; the second arg takes `{ ttl, tags, throttle, debounce, shared, n }`
96
- (retention and the refetch clock — not transport). `ttl` defaults to `0` on
97
- the server (coalesce-only — the request is the atomic unit, nothing is
98
- retained past it) and `Infinity` on the client (retain until invalidate/
99
- refresh). `shared: true` selects the process-level store instead of the
100
- request-scoped default (server) it does not by itself retain, pair it with
101
- an explicit `ttl` (e.g. `{ shared: true, ttl: Infinity }`) to memoise across
102
- requests, for an external endpoint, never per-user data; on the client it is
103
- a no-op (one tab store). A read with no request in flight (e.g. a background
104
- job) also resolves against the process-level store. During SSR the same call
105
- resolves
106
- in-process and its value is baked into the HTML so hydration starts warm
107
- there is no `cache()` wrapper; the bare call carries the caching. Around it:
98
+ validate as args, `File` parts validate against `schemas.files`.
99
+
100
+ **Consuming an rpc** — the bare call `fn(args)` IS the smart read: cached,
101
+ coalesced, reactive, stale-while-revalidate for replayable (GET/HEAD) reads.
102
+ There are no call-site options (ADR-0020) all retention/refetch policy is
103
+ declared once on the endpoint's `cache`/`stream`. `ttl` defaults to `Infinity`:
104
+ an entry is retained for its store's lifetime — the request on the server (a
105
+ non-shared read dies with the request), the tab on the client (until
106
+ invalidate/refresh); a write coalesces only (ttl 0, the mutation idiom).
107
+ `shared` selects the process-level store instead of the request-scoped default
108
+ (server); with the default `Infinity` ttl it memoises across requests (an
109
+ explicit `ttl` bounds it) — for an external endpoint, never per-user data; on
110
+ the client it is a no-op (one tab store). A read with no request in flight (e.g.
111
+ a background job) resolves against the process-level store and coalesces only
112
+ (so it can't leak forever). During SSR the same call — any method — resolves
113
+ in-process and its value is baked into the HTML so hydration starts warm without
114
+ a re-fetch (an inline write seeds too, ADR-0036; only unprompted refetch stays
115
+ GET/HEAD) — there is no `cache()` wrapper; the bare call carries the caching. Around it:
108
116
  `fn.raw(args, init?)` returns the raw `Response` (per-call transport options —
109
117
  `signal`, `headers`, `keepalive`, … — live here); `fn.refresh(args?)`
110
118
  refetches keeping the stale value visible; `fn.patch(args?, updater)` mutates
@@ -113,24 +121,16 @@ it synchronously; `fn.pending(args?)` / `fn.refreshing(args?)` are reactive
113
121
  probes; `fn.error(args?)` is the rpc's last typed error; `fn.watch(args?,
114
122
  handler)` pipes each resolved value to a handler (client-only; SSR-inert);
115
123
  `fn.isError(e, kind?)` type-guards a caught error against the rpc's declared
116
- error kinds; `fn.outbox()` exposes a durable rpc's parked-write queue. A
124
+ error kinds. A
117
125
  handler that returns `jsonl()`/`sse()` makes the bare call return a
118
- `Subscribable` (`for await` it) — detected at build, nothing to declare;
126
+ `NamedAsyncIterable` (`for await` it) — detected at build, nothing to declare;
119
127
  awaiting a streaming call is a compile error.
120
128
 
121
129
  **Typed errors** — declare a constructor with
122
130
  `error.typed(name, status, schema?)` and `return` it from the handler; the
123
131
  client's `HttpError` then carries `kind` (the name) and `data` (the schema's
124
132
  payload), narrowed via `rpc.isError`. The framework reserves
125
- `kind: 'validation'` (422, `data: ValidationErrorData`) and `kind: 'queued'`
126
- (a durable call parked while unreachable; `data` is the parked `OutboxEntry`).
127
-
128
- **Durable outbox** — an `outbox: true` (mutating) rpc still fetches and throws
129
- normally, but an unreachable server (transport failure or 502/503/504/52x)
130
- parks the request for replay as a side-effect and throws `kind: 'queued'`;
131
- once a backlog exists new calls park straight to the tail so writes stay
132
- ordered. Nothing auto-drains: replay via `rpc.outbox.retry()` or the global
133
- `outbox.retry()`; cancel via an entry's `controller.abort()`.
133
+ `kind: 'validation'` (422, `data: ValidationErrorData`).
134
134
 
135
135
  **Socket** — `socket<T>(opts)` or `socket({ schema, … })` (with a schema, `T`
136
136
  infers and publishes validate). Options: `tail` (retained frames, default 1 —
@@ -138,8 +138,9 @@ infers and publishes validate). Options: `tail` (retained frames, default 1 —
138
138
  `clientPublish` (accept browser/HTTP publishes, off by default), `clients`
139
139
  (mcp/cli exposure; a schema flips both on by default). The socket IS the
140
140
  `AsyncIterable` — iterating is the live stream, no replay. Members:
141
- `broadcast(msg)` (isomorphic publish — server fans out in-process + to remote
142
- subscribers, client sends a validated `pub` frame), `tail(count?)` (a
141
+ `publish(msg)` (isomorphic — mirrors Bun's `server.publish()`; server fans out
142
+ in-process + to remote subscribers, client sends a validated `pub` frame),
143
+ `tail(count?)` (a
143
144
  subscription seeded with retained frames), `peek()` (latest retained frame),
144
145
  `refresh()` (drop local frames and re-pull the server tail; server-side
145
146
  no-op), `watch(handler)` ≡ `watch(socket, handler)` (client-only, SSR-inert),
@@ -189,13 +190,14 @@ cells read/written through `.value`.
189
190
  | `state.share(key, value)` / `state.shared(key)` | members of `state` | Put a named value on the ambient scope / read the closest ancestor's |
190
191
  | `watch(source, handler)` | `@abide/abide/ui/watch` | The single reaction primitive (client-only, stripped from SSR). Sources: a bare thunk `watch(() => …)` (auto-tracked effect), a state cell, a cell array, a socket/stream (`handler(frame)` per frame with reconnect replay), an rpc (`watch(fn, args?, handler)` — runs the smart read, `handler(value)` on each change). Returns a scope-tied disposer |
191
192
  | `html(str)` / `` html`…` `` | `@abide/abide/ui/html` | Brands trusted raw HTML so `{expr}` inserts nodes instead of escaped text; plain `{value}` always escapes |
192
- | `props()` | ambient (no import) | The prop reader: `const { name = fallback, ...rest } = props()`; a page's props are its route params |
193
+ | `props()` | `@abide/abide/ui/props` | The prop reader, resolved by import binding (alias-safe) like `state`: `const { name = fallback, ...rest } = props()`; a page/layout's declared props are additive with its route-param shape. `children` is an ordinary declared prop (`const { children } = props<{ children: Snippet }>()`), not ambient |
193
194
 
194
195
  Bindings and directives (the attribute kinds `readAttributes` parses):
195
196
 
196
197
  | Form | Spec |
197
198
  | --- | --- |
198
- | `{expr}` | Text interpolation, escaped; a snippet or `html`-branded value mounts as nodes |
199
+ | `{expr}` | Text interpolation, escaped; a snippet or `html`-branded value mounts as nodes. Type-directed (ADR-0032): a `Promise`/`AsyncIterable`-typed `{expr}` (or an async sub-expression) lifts to a peek-cell — `undefined` while pending (composes with `??`/`?.`), then the resolved value / latest frame; a plain value binds directly |
200
+ | `{await expr}` | Explicit **blocking** await — renders the awaited value inline during SSR. Valid in every position (ADR-0032): content, an attribute, an `{#if}`/`{#switch}` subject, a `{#for}` source |
199
201
  | `name={expr}` | Attribute/prop bound to an expression |
200
202
  | `name="a {expr} b"` | Interpolated attribute — a literal `{` in a quoted value always interpolates (write `&lbrace;` for a literal brace) |
201
203
  | `{...expr}` | Spread — props onto a component, attributes onto a native element (rejected on `<template>`) |
@@ -203,6 +205,7 @@ Bindings and directives (the attribute kinds `readAttributes` parses):
203
205
  | `bind:value={cell}` | Two-way input/select/textarea binding. `<input type="number"/"range">` writes back a number; `<select>` re-applies against late-mounting options and `<select multiple>` binds an array of selected values |
204
206
  | `bind:value={{ get, set }}` | Writable-computed binding: read via `get()`, write via `set(next)` |
205
207
  | `bind:checked={cell}` / `bind:group={cell}` | Checkbox boolean / radio-group value (SSR emits boolean attributes bare — `checked`, `open`, `selected` on the matching option) |
208
+ | `bind:prop={target}` (on a component) | Two-way prop binding — the same `target` forms as an element bind (an lvalue or `{ get, set }`). The child reads `prop` normally; if it writes `prop` or forwards it to another `bind:`, those writes flow back to `target`. Bindability is usage-inferred (no child-side marker): a prop only read stays read-only, and a `bind:prop` whose child never writes is simply one-way |
206
209
  | `class:name={cond}` | Toggles a class; merges with a reactive `class` base in one effect |
207
210
  | `style:property={value}` | Sets one style property; merges with a reactive `style` base |
208
211
  | `attach={fn}` | Runs `fn(element)` at build time; an optional returned teardown runs on dispose |
@@ -220,10 +223,25 @@ error):
220
223
  | `{#try}…{:catch e}…{:finally}…{/try}` | Synchronous error boundary around a build/reactive throw |
221
224
  | `{#snippet name(args)}…{/snippet}` | Declares a reusable builder, called as an interpolation: `{name(args)}`; a snippet value passes through props like any other value |
222
225
 
226
+ A `Promise`/`AsyncIterable` (or an async sub-expression) lifts to a peek-cell in
227
+ **every** position (ADR-0032) — content, an attribute, an `{#if}`/`{#switch}`
228
+ subject, a plain `{#for}` source — reading `undefined` while pending, so
229
+ `{getFoo() ?? 'Loading…'}` shows the fallback, `{#if getFoo()}` takes the else
230
+ branch, and a pending `{#for}` renders empty. A leading `await` makes it
231
+ SSR-blocking (resolved inline); no `await` streams (pending shell, resolves on the
232
+ client). The one rejection is a raw `AsyncIterable` driving a plain `{#for}` —
233
+ iterate its frames with `{#for await}`.
234
+
223
235
  Components are capitalised tags (`<Panel prop={x}>…</Panel>`); nested content
224
- renders where the component calls `{children()}` — the single fill point
225
- (`{#if children}{children()}{:else}…{/if}` for a fallback; there are no named
226
- slots and no `<slot>` element). A layout's `{children()}` is the route outlet.
236
+ becomes the component's `children` prop an ordinary declared prop of type
237
+ `Snippet`, read with `const { children } = props<{ children: Snippet }>()`
238
+ and called as `{children()}` the single fill point (`{#if children}
239
+ {children()}{:else}…{/if}` for a fallback; there are no named slots and no
240
+ `<slot>` element). Slotted content (`<Panel>…</Panel>`) and an explicit
241
+ `children={aSnippet}` attribute set the same prop — slotted content rides in
242
+ as the trailing prop layer, so it wins over an explicit `children` attribute
243
+ on the same tag (`mergeProps`, last layer wins per key). A layout's
244
+ `{children()}` is the route outlet.
227
245
 
228
246
  `<script>` and `<style>` are **not component-root-only**: either may sit
229
247
  inside a control-flow branch, scoped to that branch. A nested `<script>`
@@ -233,15 +251,16 @@ there — imports live in the leading `<script>`). A **root** `<style>` is
233
251
  component-scoped; a nested `<style>` scopes to its sibling subtree only.
234
252
 
235
253
  Removed forms throw migration errors at parse time: the `<slot>` element (use
236
- `{children()}`), `<template name>` snippets (use `{#snippet}`), and all
237
- `<template if/each/await/switch/…>` control flow (use `{#…}` blocks).
254
+ a declared `children: Snippet` prop, called `{children()}`), `<template
255
+ name>` snippets (use `{#snippet}`), and all `<template
256
+ if/each/await/switch/…>` control flow (use `{#…}` blocks).
238
257
 
239
258
  ## Server surface — `abide/server/*`
240
259
 
241
260
  ### RPC — `@documentation rpc`
242
261
 
243
262
  - `@abide/abide/server/GET` — GET rpc helper: `export const x = GET(handler, opts?)` inside `src/server/rpc/`; the bundler rewrites it to the server dispatcher or the browser proxy — calling it outside an rpc module throws.
244
- - `@abide/abide/server/POST` — POST rpc helper (mutating: accepts `outbox`, JSON/FormData body).
263
+ - `@abide/abide/server/POST` — POST rpc helper (mutating: JSON/FormData body).
245
264
  - `@abide/abide/server/PUT` — PUT rpc helper (mutating).
246
265
  - `@abide/abide/server/PATCH` — PATCH rpc helper (mutating).
247
266
  - `@abide/abide/server/DELETE` — DELETE rpc helper (mutating; args travel in the query string).
@@ -293,7 +312,7 @@ Removed forms throw migration errors at parse time: the `<slot>` element (use
293
312
 
294
313
  Probes report, never act — reading one opens no fetch and no stream.
295
314
 
296
- - `@abide/abide/shared/pending` — `pending(selector?, args?)`: reactive "no value yet" probe over calls and streams (global, per-rpc, per-call, tagged, per-subscribable; a durable rpc's parked writes count too).
315
+ - `@abide/abide/shared/pending` — `pending(selector?, args?)`: reactive "no value yet" probe over calls and streams (global, per-rpc, per-call, tagged, per-subscribable).
297
316
  - `@abide/abide/shared/refreshing` — `refreshing(selector?, args?)`: "holding a value while a fresher one is in flight" — the SWR reload / stream-reconnect badge.
298
317
  - `@abide/abide/shared/peek` — `peek(fn, args?)` / `peek(socket)`: the retained value (or latest frame), synchronously, `T | undefined`; reactive inside a tracking scope.
299
318
  - `@abide/abide/shared/done` — `done(subscribable)`: true once a stream closed (stream-only; a cache read's "done" is `!pending && !refreshing`).
@@ -301,7 +320,7 @@ Probes report, never act — reading one opens no fetch and no stream.
301
320
 
302
321
  ### Errors — `@documentation response`
303
322
 
304
- - `@abide/abide/shared/HttpError` — thrown by rpc calls on non-2xx; carries `status`, `statusText`, the raw `response`, and — for typed/validation/queued errors — `kind` + `data`.
323
+ - `@abide/abide/shared/HttpError` — thrown by rpc calls on non-2xx; carries `status`, `statusText`, the raw `response`, and — for typed/validation errors — `kind` + `data`.
305
324
  - `@abide/abide/shared/ValidationErrorData` — the `data` shape of a `kind: 'validation'` failure: the raw Standard Schema `issues` plus a `fields` (field → first message) map.
306
325
 
307
326
  ### Schema projection — `@documentation rpc`
@@ -325,7 +344,7 @@ Probes report, never act — reading one opens no fetch and no stream.
325
344
 
326
345
  ### Templating — `@documentation templating`
327
346
 
328
- - `@abide/abide/shared/snippet` — `snippet(payload)`: brands a snippet payload so a `{expr}` interpolation mounts it (client: a DOM builder; server: the rendered string); the compiler wraps `{#snippet}` bodies in this. Also exports the `Snippet<P>` type and `snippetPayload(value)` (the payload, or undefined for plain values).
347
+ - `@abide/abide/shared/snippet` — `snippet(payload)`: brands a snippet payload so a `{expr}` interpolation mounts it (client: a DOM builder; server: the rendered string); the compiler wraps `{#snippet}` bodies in this. Also exports the `Snippet<Args>` type — a callable `(...args: Args) => SnippetValue`, generic over its call arguments (`children` is `Snippet`, invoked `children()`; a row snippet is `Snippet<[Item]>`, invoked `row(item)`) — plus `SnippetValue` (the internal payload brand) and `snippetPayload(value)` (a branded value's payload, or undefined for plain values).
329
348
 
330
349
  ### Shared plumbing — `@documentation plumbing`
331
350
 
@@ -337,6 +356,7 @@ Probes report, never act — reading one opens no fetch and no stream.
337
356
 
338
357
  - `@abide/abide/ui/state` — the `state` primitive: `state(initial, transform?)` writable cell, `state.computed(fn)` read-only derived, `state.linked(fn, transform?)` writable-reseeded, `state.share(key, value)` / `state.shared(key)` ambient context. In `.abide` files the compiler lowers reads/writes to plain variable syntax; in `.ts` the cell is read/written through `.value`.
339
358
  - `@abide/abide/ui/watch` — `watch(source, handler)`: the single reaction primitive over a thunk, cell, cell array, socket/stream, or rpc (see the grammar table). Client-only; the compiler strips author calls from SSR, and the `socket.watch` / `fn.watch` instance sugar is SSR-inert.
359
+ - `@abide/abide/ui/props` — `props<T>()`: the prop reader, resolved by import binding (alias-safe) like `state`; a required import — there is no ambient `props()`. Destructure declared props off it (`const { name, ...rest } = props<T>()`); a page/layout's declared `T` is additive with its auto-typed route-param shape. `children` is an ordinary declared prop, not ambient: `const { children } = props<{ children: Snippet }>()` (`Snippet` from `@abide/abide/shared/snippet`).
340
360
 
341
361
  ### Templating — `@documentation templating`
342
362
 
@@ -346,10 +366,6 @@ Probes report, never act — reading one opens no fetch and no stream.
346
366
 
347
367
  - `@abide/abide/ui/navigate` — `navigate(path, params?, options?)`: typed programmatic navigation off the route map; params interpolate through `url()` (base-correct). Options `{ replace, keepScroll }`. The module also exports `navigatePath(path, options?)` (already-resolved paths — the router's own entry, no re-basing) and the `NavigateOptions` type.
348
368
 
349
- ### Outbox — `@documentation ui`
350
-
351
- - `@abide/abide/ui/outbox` — the global reactive outbox: `outbox()` lists every durable rpc's undelivered entries (each tagged with its `rpc`), member `outbox.retry()` drains every queue. Empty list server-side. Types `GlobalOutbox`, `GlobalOutboxEntry`.
352
-
353
369
  ### UI plumbing — `@documentation plumbing`
354
370
 
355
371
  Compiler/runtime machinery — published so generated code, the type shadow, and
@@ -362,14 +378,18 @@ tests can import it, not for app code.
362
378
  - `@abide/abide/ui/router` — `router(...)`: the client router — fills layout/page chains into comment-marker outlet boundaries, intercepts in-app links, buckets/restores scroll per history entry.
363
379
  - `@abide/abide/ui/startClient` — `startClient(...)`: the client entry — reads every `__SSR__` field into its shared slot (cache seed, health seed, client timeout, resume manifest), hydrates the chain, starts the router.
364
380
  - `@abide/abide/ui/renderToStream` — `renderToStream(render)`: out-of-order SSR streaming — shell first, then one `<abide-resolve>` fragment per streaming await block in completion order; blocking (`then`-head) awaits render inline.
365
- - `@abide/abide/ui/remoteProxy` — `remoteProxy(method, url, opts?)`: the browser-side rpc stub the bundler emits (fetch, decode, HttpError, outbox parking, streaming); the `DurableOptions` type rides along.
381
+ - `@abide/abide/ui/remoteProxy` — `remoteProxy(method, url, opts?)`: the browser-side rpc stub the bundler emits (fetch, decode, HttpError, streaming); the `RemoteProxyOptions` type rides along.
366
382
  - `@abide/abide/ui/socketProxy` — `socketProxy(name)`: the browser-side socket stub — the identical `Socket<T>` shape over the page's lazily-opened multiplexed ws channel.
367
383
  - `@abide/abide/ui/runtime/escapeKey` — JSON-Pointer-escapes one reactive-doc path key (`~`→`~0`, `/`→`~1`).
384
+ - `@abide/abide/ui/runtime/withPath` — pushes one `escapeKey`-escaped render-path segment for the duration of a synchronous `build`, relative to the ambient path (the render-path identity a layout layer / child mount composes); restores after. A reactively-rebuilt block uses `withPathFrom` with a captured base instead.
385
+ - `@abide/abide/ui/runtime/renderPath` — the render-path a `<Child/>` mounts under: composes a child's ordinal onto the ambient path (`withPath(ordinal, …)`) to produce the `abide:await:CHILDPATH` boundary id, computed identically on both sides so the streamed-child adopter never drifts. Server-emit-only.
386
+ - `@abide/abide/ui/runtime/blockId` — allocates an await/try block id namespaced by the ambient render-path (`${path}:${n}`, per-path document-order counter), so sibling child renders can run concurrently during SSR without their block ids interleaving; the bare (`path === ''`) case keeps the plain `0,1,2…` form.
368
387
  - `@abide/abide/ui/runtime/nextBlockId` — the next await/try block id in the current render pass (document order, shared across inlined children).
369
388
  - `@abide/abide/ui/runtime/enterRenderPass` — marks entry into a render/mount; the outermost resets the block-id counter.
370
389
  - `@abide/abide/ui/runtime/exitRenderPass` — unwinds `enterRenderPass`'s depth.
371
390
  - `@abide/abide/ui/dom/mount` — mounts a top-level page/layout into a host under an ownership scope; returns the unmount.
372
391
  - `@abide/abide/ui/dom/mountChild` — mounts a nested child component as a comment-marker range (dev builds also register it with the hot bridge).
392
+ - `@abide/abide/ui/dom/mountStreamedChild` — the client mount for a HOISTABLE child (ADR-0039): a dual-mode adopter that probes the hydration cursor to tell whether the server inlined the child (settled) or streamed it (`abide:await:CHILDPATH` boundary, already swapped in), then adopts the range in place — falling back to a create-mount on a client navigation or an unfilled boundary. Registers with the hot bridge like `mountChild`.
373
393
  - `@abide/abide/ui/dom/mountSlot` — mounts a component's passed-children content as a marker-bounded range.
374
394
  - `@abide/abide/ui/dom/outlet` — a layout's outlet: an empty `<!--abide:outlet-->…<!--/abide:outlet-->` boundary the router fills.
375
395
  - `@abide/abide/ui/dom/hydrate` — adopts server-rendered DOM instead of rebuilding: runs the build with a claim cursor over the existing nodes.
@@ -380,7 +400,6 @@ tests can import it, not for app code.
380
400
  - `@abide/abide/ui/dom/appendText` — a reactive `{expr}` text node under a parent.
381
401
  - `@abide/abide/ui/dom/appendTextAt` — a reactive text node mounted at a skeleton anchor (text interleaved with element siblings).
382
402
  - `@abide/abide/ui/dom/appendSnippet` — mounts a `{snippet(args)}` interpolation's builder into a marker-bounded range.
383
- - `@abide/abide/ui/dom/text` — a text node whose content tracks a reactive read.
384
403
  - `@abide/abide/ui/dom/attr` — binds an element attribute to a read (boolean true → bare attribute, false/nullish → removed).
385
404
  - `@abide/abide/ui/dom/on` — attaches an event listener whose removal is registered with the ownership scope.
386
405
  - `@abide/abide/ui/dom/attach` — runs an `attach={fn}` attachment and registers its optional teardown.
@@ -391,12 +410,20 @@ tests can import it, not for app code.
391
410
  - `@abide/abide/ui/dom/switchBlock` — `{#switch}` runtime (also `{#if}` chains with `{:else if}` branches).
392
411
  - `@abide/abide/ui/dom/awaitBlock` — `{#await}` runtime: pending → resolved/error branch swap, teardown-generation guarded.
393
412
  - `@abide/abide/ui/dom/tryBlock` — `{#try}` runtime: synchronous error boundary around a subtree build.
394
- - `@abide/abide/ui/dom/applyResolved` — consumes a streamed SSR `<abide-resolve>` chunk, swapping it into its await boundary (the bundle-side counterpart of the doc stream's inline scripts).
395
413
  - `@abide/abide/ui/dom/mergeProps` — composes a child's props from explicit thunk runs, spread layers, and the trailing children layer.
396
414
  - `@abide/abide/ui/dom/spreadProps` — wraps a `{...source}` spread layer so every key resolves to a live value thunk.
397
415
  - `@abide/abide/ui/dom/restProps` — the live unconsumed-props object behind `const { …, ...rest } = props()`.
416
+ - `@abide/abide/ui/dom/bindProp` — the parent half of a component `bind:prop`: annotates a prop's value thunk with a `set` write-back channel.
417
+ - `@abide/abide/ui/dom/bindableProp` — the child half: the writable cell a component gets for a prop it writes or forwards (pass-through to the parent when bound, a local reseeding cell when not).
398
418
  - `@abide/abide/ui/dom/spreadAttrs` — spreads an object's keys onto a native element (`<div {...rest}>`), keys enumerated once.
419
+ - `@abide/abide/ui/dom/mutateDocContainer` — the lowering for an in-place mutating container method on a reactive doc (`model.items.splice(…)`, `.sort()`, a Set `.add()`, a Map `.set()`, …): clones the array/Map/Set, applies the mutation to the copy, and writes it back through `replace` so a real patch fires (readers wake, the render tree re-derives); returns the native method's result unchanged.
399
420
  - `@abide/abide/ui/dom/readCall` — guarded method call on a reactive-doc read (the `model.draft.trim()` lowering).
421
+ - `@abide/abide/ui/dom/readCell` — unified read for a `linked`/async-`computed` reference (the `$$readCell(NAME)` lowering): peeks an async cell, reads `.value` off a sync one.
422
+ - `@abide/abide/ui/dom/cellPending` — whether a control-flow subject (`{#if}`/`{#switch}`) is a still-loading async cell (no value, no error) so the block renders no branch while pending instead of flashing its `{:else}`; a plain/settled value is never pending.
423
+ - `@abide/abide/ui/settleAsyncCells` — the SSR Tier-2 await-barrier (the `await $$settleAsyncCells()` lowering emitted between a component's cell declarations and its template): drains + awaits the request-scoped in-flight async-cell promises so their resolved values bake into the first-pass HTML.
424
+ - `@abide/abide/ui/flight` — the SSR flight-starter (`$$flight(() => expr)`): hoists a hoistable await's promise into the synchronous render prefix so independent flights overlap instead of serializing; normalises a synchronous loader throw to a rejected promise and carries a synchronous `.settled` snapshot for `finalizeStreamedChildren`. Server-emit-only.
425
+ - `@abide/abide/ui/isolateCellBarrier` — runs a hoisted child render (`$$isolateCellBarrier`) under its own async-cell barrier list (ALS-backed on the server) so its cell registrations and `$$settleAsyncCells` drain stay isolated from concurrent siblings and the page; an inert passthrough on the client. Server-emit-only.
426
+ - `@abide/abide/ui/finalizeStreamedChildren` — the ADR-0039 when-to-stream decision run once after a component's body walk (`await $$finalizeStreamedChildren(...)`): fills each hoistable child's reserved output slot — inlining a settled flight byte-identically to the pre-ADR path, rethrowing a rejected one, or emitting an `abide:await:CHILDPATH` boundary + streaming `SsrAwait` for a still-pending one. Server-emit-only.
400
427
 
401
428
  ## Build / tooling
402
429
 
@@ -435,7 +462,7 @@ tests can import it, not for app code.
435
462
 
436
463
  | Route | Serves |
437
464
  | --- | --- |
438
- | `/openapi.json` | The OpenAPI document projected from every rpc's method, URL, and schemas |
465
+ | `/openapi.json` | The OpenAPI document projected from every rpc's method, URL, and schemas. The 200 response body comes from `schemas.output` or, absent one, the handler's return type projected to JSON Schema (ADR-0030 D2); each `error.typed(...)` branch the handler can return surfaces as its own status response (ADR-0030) |
439
466
  | `/__abide/mcp` | The MCP endpoint (tools from rpcs/sockets, prompts, resources); auth flows from the inbound request |
440
467
  | `/__abide/health` | Liveness + identity JSON: framework version, app name/version, plus the app `health(request)` hook's fields; answered ahead of `app.handle` |
441
468
  | `/__abide/identity` | Compatibility alias for the same payload with the legacy `abide: true` marker |
@@ -443,7 +470,6 @@ tests can import it, not for app code.
443
470
  | `/__abide/sockets/<name>` | A socket's HTTP face: `GET` = retained tail as JSON (SSE stream under `Accept: text/event-stream`; `?tail=N` caps/seeds), `POST` = publish gated by `clientPublish`; 404 unless the socket is exposed to mcp/cli |
444
471
  | `/__abide/cli` | `GET` = shell install script; `/__abide/cli/<platform>` streams the thin-CLI tarball (cli + server binaries, `.env` baked with `ABIDE_APP_URL`/`ABIDE_APP_TOKEN`) |
445
472
  | `/__abide/inspector` | The `@abide/inspector` UI, mounted only under `ABIDE_ENABLE_INSPECTOR=true` |
446
- | `/__abide/hot/<moduleId>` | Dev-only component hot-module endpoint backing `.abide` HMR |
447
473
 
448
474
  ## Environment variables
449
475