@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
@@ -24,8 +24,32 @@ function channelPatterns(): string | undefined {
24
24
  return undefined
25
25
  }
26
26
 
27
+ /* One line for an AggregateError sub-error: its message, prefixed with the source
28
+ position when it carries one. A thrown `Bun.build` failure holds a `BuildMessage`
29
+ per diagnostic, each with a `position.file` — naming that file is the point, since
30
+ without it a codegen/parse failure reads as a detail-free "Bundle failed". */
31
+ function formatAggregateEntry(entry: unknown): string {
32
+ if (typeof entry === 'object' && entry !== null && 'message' in entry) {
33
+ const message = String((entry as { message: unknown }).message)
34
+ const position = (entry as { position?: { file?: string; line?: number; column?: number } })
35
+ .position
36
+ if (position?.file) {
37
+ return ` ${position.file}:${position.line ?? 0}:${position.column ?? 0} — ${message}`
38
+ }
39
+ return ` ${message}`
40
+ }
41
+ return ` ${String(entry)}`
42
+ }
43
+
27
44
  // Prefers a full stack trace when the value is an Error so logs include the call site.
45
+ // An AggregateError (a thrown Bun.build failure among them) carries the real diagnostics
46
+ // in `.errors` — its own message is only a summary ("Bundle failed") — so expand each one,
47
+ // or every per-file position is dropped and the failure reads with zero detail.
28
48
  function errorParts(value: unknown): { msg: string; stack?: string } {
49
+ if (value instanceof AggregateError && value.errors.length > 0) {
50
+ const details = value.errors.map(formatAggregateEntry).join('\n')
51
+ return { msg: `${value.message}\n${details}` }
52
+ }
29
53
  if (value instanceof Error) {
30
54
  return { msg: value.message, stack: value.stack }
31
55
  }
@@ -21,7 +21,10 @@ writing the subscriber's version source throws state_unsafe_mutation. The
21
21
  probes scan the registry at re-derive time, so a deferred ping reads state
22
22
  that is already current; marks within one tick coalesce into one notify.
23
23
  */
24
- export function createLifecycleChannel(): { track: () => void; mark: () => void } {
24
+ export function createLifecycleChannel(onIdle?: () => void): {
25
+ track: () => void
26
+ mark: () => void
27
+ } {
25
28
  let notify: (() => void) | undefined
26
29
  let tracker: (() => void) | undefined
27
30
  let marked = false
@@ -35,6 +38,9 @@ export function createLifecycleChannel(): { track: () => void; mark: () => void
35
38
  if (tracker === created) {
36
39
  tracker = undefined
37
40
  }
41
+ /* Last reader torn down — let an owner (the cache store's per-prefix map)
42
+ evict this now-inert channel instead of retaining it for the tab's life. */
43
+ onIdle?.()
38
44
  }
39
45
  })
40
46
  tracker = created
@@ -1,108 +1,77 @@
1
- import { createLivenessWatch } from './createLivenessWatch.ts'
2
-
3
1
  /*
4
- The reachability registry behind `abide/shared/reachable`. A probe transport
5
- and the timings are injected so the public name wires them from env + a real
6
- HEAD while tests drive scripted outcomes on tiny intervals.
7
-
8
- Per origin, the first read awaits one real probe (the FAITHFUL first answer —
9
- its latency, including a full timeout when the host is down, is the price of
10
- not guessing) and then hands the origin to a createLivenessWatch that re-probes
11
- every `intervalMs` to keep the value warm. Every later read resolves instantly
12
- off that warm value, fresh within one interval — the faithful cost is paid once.
2
+ The reachability registry behind `abide/shared/reachable`. A probe transport and the
3
+ TTL are injected so the public name wires them from env + a real HEAD while tests drive
4
+ scripted outcomes.
13
5
 
14
- The inaugural probe runs DIRECTLY, not through the watch: the watch's
15
- failureLimit (anti-flap) is right for the ongoing poll but would make a down
16
- host take failureLimit× the timeout to answer on the first call. The watch's
17
- injected probe doubles as the idle reaper a host nobody has read in `idleMs`
18
- stops polling (stop() during the probe changes the watched url, so the watch
19
- discards the result and never reschedules); the next read restarts it cold.
6
+ Per origin, a TTL memoize: the first read and any read after the cached verdict has
7
+ aged past `ttlMs` awaits a real probe (the FAITHFUL answer; its latency, a full timeout
8
+ when the host is down, is the price of not guessing) and caches the verdict with its
9
+ timestamp. Every read within the TTL resolves instantly off that cached value. Concurrent
10
+ reads of a cold/stale origin share the one in-flight probe. No background poll: a host that
11
+ goes down (or recovers) is noticed on the next read after its entry ages out, not
12
+ continuously.
20
13
  */
21
14
  export function createReachable(options: {
22
15
  probe: (origin: string) => Promise<boolean>
23
- intervalMs: number
24
- idleMs: number
16
+ ttlMs: number
25
17
  }): {
26
18
  reachable: (host: string | URL) => Promise<boolean>
27
- /* Stop every origin's poll — graceful shutdown, and test isolation. */
19
+ /* Drop every cached verdict — graceful reset and test isolation. */
28
20
  stop: () => void
29
- /* `using registry = createReachable(...)` — disposal stops every poll. */
21
+ /* `using registry = createReachable(...)` — disposal clears the cache. */
30
22
  [Symbol.dispose]: () => void
31
23
  } {
32
24
  type Entry = {
33
25
  alive: boolean
34
- /* The inaugural probe while it is still in flight; concurrent cold reads await the same one. */
26
+ /* `Date.now()` when `alive` was taken; a read past `ttlMs` re-probes. */
27
+ probedAt: number
28
+ /* A probe in flight — concurrent cold/stale reads await the same one. */
35
29
  inflight: Promise<boolean> | undefined
36
- watch: ReturnType<typeof createLivenessWatch> | undefined
37
- lastReadAt: number
38
- }
39
- const registry = new Map<string, Entry>()
40
-
41
- /* The ongoing poll's probe: reap an idle origin, else run the real probe. */
42
- function watchProbe(origin: string): Promise<boolean> {
43
- const entry = registry.get(origin)
44
- if (entry && Date.now() - entry.lastReadAt > options.idleMs) {
45
- entry.watch?.stop()
46
- registry.delete(origin)
47
- /* Discarded — stop() moved the watched url, so the watch won't reschedule. */
48
- return Promise.resolve(false)
49
- }
50
- return options.probe(origin)
51
30
  }
31
+ const cache = new Map<string, Entry>()
52
32
 
53
- function startWatch(entry: Entry, origin: string): void {
54
- entry.watch = createLivenessWatch({
55
- probe: watchProbe,
56
- onChange: (alive) => {
57
- entry.alive = alive
58
- },
59
- intervalMs: options.intervalMs,
60
- })
61
- entry.watch.watch(origin)
62
- }
63
-
64
- async function reachable(host: string | URL): Promise<boolean> {
65
- /*
66
- HEAD the origin root: this answers host connectivity, not endpoint
67
- health. A bare host string defaults to https (the external-dependency
68
- norm); an explicit http://… is honored.
69
- */
70
- const url =
71
- typeof host === 'string' && !/^https?:\/\//i.test(host) ? `https://${host}` : host
72
- const origin = new URL(url).origin
73
- const existing = registry.get(origin)
74
- if (existing) {
75
- existing.lastReadAt = Date.now()
76
- return existing.inflight ?? existing.alive
77
- }
78
- /* Cold: optimistic seed, but the first read awaits a real probe before returning. */
79
- const entry: Entry = {
80
- alive: true,
81
- inflight: undefined,
82
- watch: undefined,
83
- lastReadAt: Date.now(),
84
- }
85
- registry.set(origin, entry)
86
- /* A rejecting probe reads as unreachable, not a permanent wedge: without
87
- the catch a thrown probe leaves inflight set forever (every later read
88
- returns the rejected promise) and never starts the watch. */
33
+ /* Re-probe an origin, folding the verdict + its timestamp back into the entry. A rejecting
34
+ probe reads as unreachable, not a permanent wedge (without the catch a thrown probe would
35
+ leave `inflight` set forever). */
36
+ function refresh(origin: string, entry: Entry): Promise<boolean> {
89
37
  entry.inflight = options
90
38
  .probe(origin)
91
39
  .catch(() => false)
92
40
  .then((alive) => {
93
41
  entry.alive = alive
42
+ entry.probedAt = Date.now()
94
43
  entry.inflight = undefined
95
- startWatch(entry, origin)
96
44
  return alive
97
45
  })
98
46
  return entry.inflight
99
47
  }
100
48
 
101
- function stop(): void {
102
- for (const entry of registry.values()) {
103
- entry.watch?.stop()
49
+ function reachable(host: string | URL): Promise<boolean> {
50
+ /* HEAD the origin root: host connectivity, not endpoint health. A bare host defaults to
51
+ https (the external-dependency norm); an explicit http://… is honored. */
52
+ const url =
53
+ typeof host === 'string' && !/^https?:\/\//i.test(host) ? `https://${host}` : host
54
+ const origin = new URL(url).origin
55
+ const existing = cache.get(origin)
56
+ if (existing !== undefined) {
57
+ /* A probe already running → share it (dedupes concurrent cold/stale reads). */
58
+ if (existing.inflight !== undefined) {
59
+ return existing.inflight
60
+ }
61
+ /* Fresh within the TTL → instant warm read. */
62
+ if (Date.now() - existing.probedAt < options.ttlMs) {
63
+ return Promise.resolve(existing.alive)
64
+ }
65
+ /* Aged out → re-probe on this read. */
66
+ return refresh(origin, existing)
104
67
  }
105
- registry.clear()
68
+ const entry: Entry = { alive: true, probedAt: 0, inflight: undefined }
69
+ cache.set(origin, entry)
70
+ return refresh(origin, entry)
71
+ }
72
+
73
+ function stop(): void {
74
+ cache.clear()
106
75
  }
107
76
 
108
77
  return { reachable, stop, [Symbol.dispose]: stop }
@@ -4,22 +4,25 @@ import { HttpError } from './HttpError.ts'
4
4
  import { keyForRemoteCall } from './keyForRemoteCall.ts'
5
5
  import { REMOTE_FUNCTION } from './REMOTE_FUNCTION.ts'
6
6
  import { recordRemoteMeta } from './recordRemoteMeta.ts'
7
+ import { reviveWireOutput } from './reviveWireOutput.ts'
7
8
  import { rpcErrorRegistry } from './rpcErrorRegistry.ts'
8
9
  import { subscribableFromResponse } from './subscribableFromResponse.ts'
9
- import type { CacheOptions } from './types/CacheOptions.ts'
10
+ import type { CachePolicy } from './types/CachePolicy.ts'
10
11
  import type { ClientFlags } from './types/ClientFlags.ts'
11
12
  import type { HttpMethod } from './types/HttpMethod.ts'
13
+ import type { NamedAsyncIterable } from './types/NamedAsyncIterable.ts'
14
+ import type { OutputWirePlan } from './types/OutputWirePlan.ts'
12
15
  import type { RawRemoteFunction } from './types/RawRemoteFunction.ts'
13
16
  import type { RemoteFunction } from './types/RemoteFunction.ts'
14
17
  import type { RpcOptions } from './types/RpcOptions.ts'
15
- import type { Subscribable } from './types/Subscribable.ts'
18
+ import type { StreamPolicy } from './types/StreamPolicy.ts'
16
19
 
17
20
  /*
18
21
  Assembles the public RemoteFunction shape used identically by the
19
22
  server-side defineRpc (in-process handler invocation) and the
20
23
  client-side remoteProxy (network fetch). Centralising the wiring here
21
24
  keeps the call/raw/stream/fetch semantics — including WeakMap meta
22
- recording, Content-Type decode, and Subscribable derivation — in one
25
+ recording, Content-Type decode, and NamedAsyncIterable derivation — in one
23
26
  place so the two halves can't drift.
24
27
 
25
28
  - `buildRequest(args)` synthesizes the Request a meta reader (cache()) or
@@ -50,10 +53,19 @@ export function createRemoteFunction<Args, Return>(opts: {
50
53
  opts?: RpcOptions,
51
54
  ) => Promise<Response>
52
55
  parseArgsForFetch?: (request: Request) => Promise<Args | undefined>
53
- /* A streaming rpc (handler returns jsonl()/sse()): the bare call returns the Subscribable
56
+ /* A streaming rpc (handler returns jsonl()/sse()): the bare call returns the NamedAsyncIterable
54
57
  directly (the iterable IS the value) rather than decoding one Response body. Emitted by
55
58
  the bundler's syntactic scan; false/undefined keeps the decode-a-Response path. */
56
59
  streaming?: boolean
60
+ /* Endpoint cache/stream policy (ADR-0020) — stamped onto both callable variants so
61
+ readThrough reads it as the bottom policy layer. Declared once on the rpc definition. */
62
+ cache?: CachePolicy<Args>
63
+ stream?: StreamPolicy
64
+ /* Client-only: the output wire codec plan (ADR-0029) the remoteProxy stub carries — the decoded
65
+ response body's structured fields are revived through it (a `Set`/`Map`/`bigint`/`Date`). The
66
+ server defineRpc never sets it, so an in-process read is untouched. undefined leaves the body
67
+ as its honest-JSON form. */
68
+ outputWirePlan?: OutputWirePlan
57
69
  }): RemoteFunction<Args, Return> {
58
70
  const {
59
71
  method,
@@ -64,6 +76,9 @@ export function createRemoteFunction<Args, Return>(opts: {
64
76
  invoke,
65
77
  parseArgsForFetch,
66
78
  streaming,
79
+ cache: cachePolicy,
80
+ stream: streamPolicy,
81
+ outputWirePlan,
67
82
  } = opts
68
83
 
69
84
  /*
@@ -102,20 +117,21 @@ export function createRemoteFunction<Args, Return>(opts: {
102
117
  }
103
118
  rawCall.method = method
104
119
  rawCall.url = url
120
+ /* Endpoint policy on both variants so readThrough can read it off whichever the caller
121
+ passed (`fn` for the decoded read, `fn.raw` for the raw escape hatch). */
122
+ rawCall.cache = cachePolicy
123
+ rawCall.stream = streamPolicy
105
124
  /* Non-enumerable brand on both variants; see REMOTE_FUNCTION. */
106
125
  Object.defineProperty(rawCall, REMOTE_FUNCTION, { value: true })
107
126
  const raw = rawCall as RawRemoteFunction<Args>
108
127
 
109
- function callable(
110
- args: Args | FormData,
111
- opts?: RpcOptions,
112
- ): Promise<Return> | Subscribable<Return> {
113
- /* A streaming rpc (jsonl/sse) returns the Subscribable directly — the iterable IS the
128
+ function callable(args: Args | FormData): Promise<Return> | NamedAsyncIterable<Return> {
129
+ /* A streaming rpc (jsonl/sse) returns the NamedAsyncIterable directly — the iterable IS the
114
130
  value (for await / state(fn(args))). Deferred fetch, keyForRemoteCall-keyed so tail()
115
131
  dedupes readers; no decode, so the error-capture path below doesn't apply. */
116
132
  if (streaming) {
117
133
  return subscribableFromResponse(keyForRemoteCall(method, url, args), () =>
118
- raw(args as Args, opts),
134
+ raw(args as Args),
119
135
  )
120
136
  }
121
137
  /* The bare call IS the smart read: route through the cache store's smart-read
@@ -123,34 +139,40 @@ export function createRemoteFunction<Args, Return>(opts: {
123
139
  reactive, while a write is coalesce-only — the raw fetch moves to `.raw`.
124
140
  `cache.read(callable, …)` brand-reads `callable.raw` for the undecoded variant
125
141
  and decodes on the way out, so pass the callable (which carries `.raw`), not
126
- `raw`. `opts` supplies cache options (ttl/tags/throttle/debounce); per-call
127
- transport options live on `.raw` now. */
142
+ `raw`. There is no call-site options argument any more — all cache policy is read
143
+ from the endpoint (`callable.cache`); per-call transport options live on `.raw`. */
128
144
  const key = keyForRemoteCall(method, url, args)
129
- return cache
130
- .read(callable as RemoteFunction<Args, Return>, args as Args, opts as CacheOptions)
131
- .then(
132
- /* Capture the rejection into the rpc error registry (design Part 4) keyed by call
145
+ return cache.read(callable as RemoteFunction<Args, Return>, args as Args).then(
146
+ /* Capture the rejection into the rpc error registry (design Part 4) keyed by call
133
147
  identity, and clear it on success — the reactive `fn.error()` probe reads it. */
134
- (value) => {
135
- rpcErrorRegistry.clear(key)
136
- return value as Return
137
- },
138
- (error: unknown) => {
139
- /* A parked durable write throws a `kind: 'queued'` sentinel it's pending
140
- retry, not a failure. Don't record it, so fn.error() stays undefined for a
141
- merely-parked write (pending() already reflects it via the outbox). */
142
- if (!(error instanceof HttpError && error.kind === 'queued')) {
143
- rpcErrorRegistry.record(key, error)
144
- }
145
- throw error
146
- },
147
- )
148
+ (value) => {
149
+ rpcErrorRegistry.clear(key)
150
+ /* Revive the decoded body's structured fields per the baked output plan (ADR-0029):
151
+ a wire array → `Set`/`Map`, a digit string → `bigint`, an ISO string → `Date`. The
152
+ decoded value is call-private (a fresh decode or cloned warm value), so the revive
153
+ mutates in place. No plan (undefined every server-side read, or a client endpoint
154
+ with no structured field) returns the value untouched. */
155
+ return reviveWireOutput(value, outputWirePlan) as Return
156
+ },
157
+ (error: unknown) => {
158
+ rpcErrorRegistry.record(key, error)
159
+ throw error
160
+ },
161
+ )
148
162
  }
149
163
  callable.method = method
150
164
  callable.url = url
151
165
  callable.clients = clients
152
166
  callable.crossOrigin = crossOrigin
167
+ callable.cache = cachePolicy
168
+ callable.stream = streamPolicy
153
169
  callable.raw = raw
170
+ /* Stamp the output wire codec plan (ADR-0029) so the public `cache(fn, args)` and
171
+ `cache.peek(fn, args)` can revive the decoded body's structured fields (Set/Map/Date/bigint)
172
+ exactly as the bare `fn(args)` read does above — otherwise those two read APIs return the raw
173
+ honest-JSON form and disagree with `fn(args)`. A runtime affordance, not on the RemoteFunction
174
+ surface (read via cast in cache.ts, like `settled`); undefined server-side / plan-less. */
175
+ ;(callable as { outputWirePlan?: OutputWirePlan }).outputWirePlan = outputWirePlan
154
176
  /* Uniform runtime guard for every rpc — the per-rpc data typing lives entirely in the
155
177
  RpcErrorGuard<Errors> signature RemoteFunction projects onto it (Errors flows from the
156
178
  rpc helper's declared type, not from here). */