@abide/abide 0.28.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 (562) hide show
  1. package/CHANGELOG.md +607 -0
  2. package/LICENSE +21 -0
  3. package/README.md +154 -0
  4. package/bin/abide.ts +212 -0
  5. package/package.json +155 -0
  6. package/src/abideLsp.ts +211 -0
  7. package/src/abideModules.d.ts +8 -0
  8. package/src/abideResolverPlugin.ts +923 -0
  9. package/src/appEntry.ts +151 -0
  10. package/src/assets/app.html +12 -0
  11. package/src/build.ts +143 -0
  12. package/src/buildCli.ts +127 -0
  13. package/src/buildDisconnected.ts +118 -0
  14. package/src/bundleApp.ts +147 -0
  15. package/src/bundleDisconnectedEntry.ts +14 -0
  16. package/src/checkAbide.ts +77 -0
  17. package/src/cliEntry.ts +25 -0
  18. package/src/clientBuildPlugins.ts +33 -0
  19. package/src/clientEntry.ts +17 -0
  20. package/src/compile.ts +63 -0
  21. package/src/controlServerWorker.ts +426 -0
  22. package/src/devEntry.ts +250 -0
  23. package/src/discoveryEntry.ts +81 -0
  24. package/src/lib/bundle/BundleMenu.ts +12 -0
  25. package/src/lib/bundle/BundleMenuItem.ts +25 -0
  26. package/src/lib/bundle/BundleWindow.ts +37 -0
  27. package/src/lib/bundle/WEBVIEW_BUILD_REVISION.ts +9 -0
  28. package/src/lib/bundle/WEBVIEW_VERSION.ts +7 -0
  29. package/src/lib/bundle/bindConnectedFlag.ts +29 -0
  30. package/src/lib/bundle/bindRequestNavigate.ts +34 -0
  31. package/src/lib/bundle/buildWebviewLib.ts +111 -0
  32. package/src/lib/bundle/bundled.ts +35 -0
  33. package/src/lib/bundle/disconnected.abide +236 -0
  34. package/src/lib/bundle/disconnected.css +9 -0
  35. package/src/lib/bundle/ensureWebviewLib.ts +20 -0
  36. package/src/lib/bundle/exitWithParent.ts +28 -0
  37. package/src/lib/bundle/infoPlist.ts +46 -0
  38. package/src/lib/bundle/installDownloads.ts +24 -0
  39. package/src/lib/bundle/installMacMenu.ts +39 -0
  40. package/src/lib/bundle/listenLocalControlServer.ts +19 -0
  41. package/src/lib/bundle/native/abideMenu.mm +422 -0
  42. package/src/lib/bundle/native/webview.h +4557 -0
  43. package/src/lib/bundle/onMenu.ts +42 -0
  44. package/src/lib/bundle/openWebview.ts +104 -0
  45. package/src/lib/bundle/pngToIcns.ts +47 -0
  46. package/src/lib/bundle/probeAbideServer.ts +57 -0
  47. package/src/lib/bundle/resolveServerBinary.ts +12 -0
  48. package/src/lib/bundle/resolveWebviewLib.ts +53 -0
  49. package/src/lib/bundle/serverBinaryFilename.ts +8 -0
  50. package/src/lib/bundle/signMacApp.ts +37 -0
  51. package/src/lib/bundle/spawnEmbeddedServer.ts +64 -0
  52. package/src/lib/bundle/stableLocalPort.ts +19 -0
  53. package/src/lib/bundle/waitForServer.ts +23 -0
  54. package/src/lib/bundle/webviewCachePath.ts +23 -0
  55. package/src/lib/bundle/webviewLibName.ts +11 -0
  56. package/src/lib/cli/connectToServer.ts +23 -0
  57. package/src/lib/cli/createClient.ts +108 -0
  58. package/src/lib/cli/dispatchCommand.ts +71 -0
  59. package/src/lib/cli/loadEnvFromBinaryDir.ts +15 -0
  60. package/src/lib/cli/parseArgvForRpc.ts +100 -0
  61. package/src/lib/cli/printHelp.ts +119 -0
  62. package/src/lib/cli/printSessionHelp.ts +27 -0
  63. package/src/lib/cli/printSessionStatus.ts +21 -0
  64. package/src/lib/cli/printTrimmed.ts +8 -0
  65. package/src/lib/cli/printValue.ts +10 -0
  66. package/src/lib/cli/resolveCliTarget.ts +48 -0
  67. package/src/lib/cli/runCli.ts +176 -0
  68. package/src/lib/cli/runSession.ts +108 -0
  69. package/src/lib/cli/startLocalInstance.ts +14 -0
  70. package/src/lib/cli/tokenizeLine.ts +51 -0
  71. package/src/lib/cli/types/CliManifest.ts +9 -0
  72. package/src/lib/cli/types/CliManifestEntry.ts +17 -0
  73. package/src/lib/cli/types/CliTarget.ts +13 -0
  74. package/src/lib/mcp/annotationsForMethod.ts +29 -0
  75. package/src/lib/mcp/createMcpResourceServer.ts +102 -0
  76. package/src/lib/mcp/createMcpServer.ts +48 -0
  77. package/src/lib/mcp/dispatchMcpRequest.ts +138 -0
  78. package/src/lib/mcp/mcpResourceServerSlot.ts +18 -0
  79. package/src/lib/mcp/mcpSurface.ts +295 -0
  80. package/src/lib/mcp/toolResultFromResponse.ts +66 -0
  81. package/src/lib/mcp/types/JsonRpcRequest.ts +12 -0
  82. package/src/lib/mcp/types/JsonRpcResponse.ts +20 -0
  83. package/src/lib/mcp/types/McpResourceContents.ts +10 -0
  84. package/src/lib/mcp/types/McpResourceDescriptor.ts +6 -0
  85. package/src/lib/mcp/types/McpResourceServer.ts +12 -0
  86. package/src/lib/mcp/types/McpServer.ts +9 -0
  87. package/src/lib/mcp/types/McpServerOptions.ts +16 -0
  88. package/src/lib/server/AppModule.ts +47 -0
  89. package/src/lib/server/DELETE.ts +10 -0
  90. package/src/lib/server/GET.ts +10 -0
  91. package/src/lib/server/HEAD.ts +10 -0
  92. package/src/lib/server/PATCH.ts +10 -0
  93. package/src/lib/server/POST.ts +10 -0
  94. package/src/lib/server/PUT.ts +10 -0
  95. package/src/lib/server/agent.ts +86 -0
  96. package/src/lib/server/appDataDir.ts +16 -0
  97. package/src/lib/server/cli/buildEnvContent.ts +19 -0
  98. package/src/lib/server/cli/createTarGz.ts +77 -0
  99. package/src/lib/server/cli/handleCliDownload.ts +150 -0
  100. package/src/lib/server/cli/handleCliInstall.ts +37 -0
  101. package/src/lib/server/cli/installScript.ts +31 -0
  102. package/src/lib/server/cli/maxSourceMtime.ts +26 -0
  103. package/src/lib/server/cookies.ts +30 -0
  104. package/src/lib/server/env.ts +51 -0
  105. package/src/lib/server/error.ts +73 -0
  106. package/src/lib/server/json.ts +42 -0
  107. package/src/lib/server/jsonl.ts +47 -0
  108. package/src/lib/server/prompts/definePrompt.ts +21 -0
  109. package/src/lib/server/prompts/promptRegistry.ts +9 -0
  110. package/src/lib/server/prompts/registerPrompt.ts +6 -0
  111. package/src/lib/server/prompts/renderPromptTemplate.ts +17 -0
  112. package/src/lib/server/prompts/types/Prompt.ts +13 -0
  113. package/src/lib/server/prompts/types/PromptOptions.ts +12 -0
  114. package/src/lib/server/prompts/types/PromptRegistryEntry.ts +13 -0
  115. package/src/lib/server/prompts/types/PromptRoutes.ts +10 -0
  116. package/src/lib/server/reachable.ts +45 -0
  117. package/src/lib/server/redirect.ts +43 -0
  118. package/src/lib/server/request.ts +19 -0
  119. package/src/lib/server/rpc/defineVerb.ts +210 -0
  120. package/src/lib/server/rpc/dispatchVerbInProcess.ts +46 -0
  121. package/src/lib/server/rpc/findVerbByCommandName.ts +18 -0
  122. package/src/lib/server/rpc/parseArgs.ts +127 -0
  123. package/src/lib/server/rpc/readBodyWithinLimit.ts +44 -0
  124. package/src/lib/server/rpc/registerVerb.ts +6 -0
  125. package/src/lib/server/rpc/runWithVerbTimeout.ts +49 -0
  126. package/src/lib/server/rpc/types/RemoteHandler.ts +27 -0
  127. package/src/lib/server/rpc/types/RemoteRoutes.ts +13 -0
  128. package/src/lib/server/rpc/types/TypedResponse.ts +18 -0
  129. package/src/lib/server/rpc/types/VerbHelper.ts +87 -0
  130. package/src/lib/server/rpc/types/VerbRegistryEntry.ts +35 -0
  131. package/src/lib/server/rpc/unprocessed.ts +14 -0
  132. package/src/lib/server/rpc/verbRegistry.ts +11 -0
  133. package/src/lib/server/runtime/DEFAULT_PORT.ts +6 -0
  134. package/src/lib/server/runtime/DEV_READY_MESSAGE.ts +6 -0
  135. package/src/lib/server/runtime/DEV_REBUILD_MESSAGE.ts +4 -0
  136. package/src/lib/server/runtime/DEV_RELOAD_CLIENT_SCRIPT.ts +107 -0
  137. package/src/lib/server/runtime/SSR_SWAP_SCRIPT.ts +16 -0
  138. package/src/lib/server/runtime/acceptsGzip.ts +24 -0
  139. package/src/lib/server/runtime/buildCacheSnapshot.ts +61 -0
  140. package/src/lib/server/runtime/buildHealthPayload.ts +34 -0
  141. package/src/lib/server/runtime/buildInspectorSurface.ts +37 -0
  142. package/src/lib/server/runtime/buildOpenApiSpec.ts +106 -0
  143. package/src/lib/server/runtime/cacheControlForAsset.ts +22 -0
  144. package/src/lib/server/runtime/containsTraversal.ts +37 -0
  145. package/src/lib/server/runtime/createAppAssetServer.ts +76 -0
  146. package/src/lib/server/runtime/createAssetHeaderCache.ts +31 -0
  147. package/src/lib/server/runtime/createPublicAssetServer.ts +67 -0
  148. package/src/lib/server/runtime/createReachable.ts +109 -0
  149. package/src/lib/server/runtime/createRouteDispatcher.ts +127 -0
  150. package/src/lib/server/runtime/createServer.ts +674 -0
  151. package/src/lib/server/runtime/createUiPageRenderer.ts +181 -0
  152. package/src/lib/server/runtime/crossOriginForbidden.ts +17 -0
  153. package/src/lib/server/runtime/crossOriginGate.ts +29 -0
  154. package/src/lib/server/runtime/devClientFingerprint.ts +117 -0
  155. package/src/lib/server/runtime/devHotModuleResponse.ts +40 -0
  156. package/src/lib/server/runtime/devReloadResponse.ts +41 -0
  157. package/src/lib/server/runtime/disableIdleTimeoutForStream.ts +27 -0
  158. package/src/lib/server/runtime/envSchemaStore.ts +15 -0
  159. package/src/lib/server/runtime/findOpenPort.ts +21 -0
  160. package/src/lib/server/runtime/getActiveServer.ts +6 -0
  161. package/src/lib/server/runtime/globToPathSet.ts +29 -0
  162. package/src/lib/server/runtime/gzipResponse.ts +46 -0
  163. package/src/lib/server/runtime/inProcessServer.ts +20 -0
  164. package/src/lib/server/runtime/internalErrorResponse.ts +25 -0
  165. package/src/lib/server/runtime/isCrossOriginRequest.ts +23 -0
  166. package/src/lib/server/runtime/listenOnOpenPort.ts +36 -0
  167. package/src/lib/server/runtime/logExposedSurfaces.ts +156 -0
  168. package/src/lib/server/runtime/maybeMountInspector.ts +97 -0
  169. package/src/lib/server/runtime/mimeForExtension.ts +14 -0
  170. package/src/lib/server/runtime/pageUrlFromStore.ts +15 -0
  171. package/src/lib/server/runtime/parseIdleTimeout.ts +10 -0
  172. package/src/lib/server/runtime/parsePort.ts +11 -0
  173. package/src/lib/server/runtime/registryManifests.ts +66 -0
  174. package/src/lib/server/runtime/requestContext.ts +5 -0
  175. package/src/lib/server/runtime/resolvePageSnapshot.ts +25 -0
  176. package/src/lib/server/runtime/respondWithEmbeddedAsset.ts +18 -0
  177. package/src/lib/server/runtime/runWithRequestScope.ts +150 -0
  178. package/src/lib/server/runtime/safeJsonForScript.ts +17 -0
  179. package/src/lib/server/runtime/serializeCacheSnapshot.ts +45 -0
  180. package/src/lib/server/runtime/serverSlot.ts +13 -0
  181. package/src/lib/server/runtime/setActiveServer.ts +6 -0
  182. package/src/lib/server/runtime/snapshotEntryFromCache.ts +83 -0
  183. package/src/lib/server/runtime/streamCacheResolutions.ts +37 -0
  184. package/src/lib/server/runtime/streamFromIterator.ts +86 -0
  185. package/src/lib/server/runtime/types/Assets.ts +6 -0
  186. package/src/lib/server/runtime/types/DevReloadStamp.ts +18 -0
  187. package/src/lib/server/runtime/types/InspectorCacheEntry.ts +24 -0
  188. package/src/lib/server/runtime/types/InspectorCacheSnapshot.ts +11 -0
  189. package/src/lib/server/runtime/types/InspectorContext.ts +30 -0
  190. package/src/lib/server/runtime/types/InspectorSocket.ts +17 -0
  191. package/src/lib/server/runtime/types/InspectorSurface.ts +13 -0
  192. package/src/lib/server/runtime/types/InspectorVerb.ts +27 -0
  193. package/src/lib/server/runtime/types/RequestStore.ts +55 -0
  194. package/src/lib/server/runtime/warnUnguardedMcp.ts +32 -0
  195. package/src/lib/server/runtime/withResponseDefaults.ts +24 -0
  196. package/src/lib/server/server.ts +33 -0
  197. package/src/lib/server/socket.ts +32 -0
  198. package/src/lib/server/sockets/createSocketDispatcher.ts +337 -0
  199. package/src/lib/server/sockets/defineSocket.ts +179 -0
  200. package/src/lib/server/sockets/lookupSocket.ts +6 -0
  201. package/src/lib/server/sockets/registerSocket.ts +6 -0
  202. package/src/lib/server/sockets/socketOperations.ts +36 -0
  203. package/src/lib/server/sockets/socketRegistry.ts +9 -0
  204. package/src/lib/server/sockets/types/Socket.ts +23 -0
  205. package/src/lib/server/sockets/types/SocketClientFrame.ts +19 -0
  206. package/src/lib/server/sockets/types/SocketOperation.ts +22 -0
  207. package/src/lib/server/sockets/types/SocketOptions.ts +26 -0
  208. package/src/lib/server/sockets/types/SocketRegistryEntry.ts +19 -0
  209. package/src/lib/server/sockets/types/SocketRoutes.ts +10 -0
  210. package/src/lib/server/sockets/types/SocketServerFrame.ts +24 -0
  211. package/src/lib/server/sse.ts +54 -0
  212. package/src/lib/shared/ABIDE_PACKAGE_NAME.ts +7 -0
  213. package/src/lib/shared/ABIDE_VERSION.ts +9 -0
  214. package/src/lib/shared/CACHE_CONTROL_VALUES.ts +16 -0
  215. package/src/lib/shared/CACHE_WRAPPED.ts +8 -0
  216. package/src/lib/shared/CLI_PATH.ts +7 -0
  217. package/src/lib/shared/DEV_HOT_PREFIX.ts +7 -0
  218. package/src/lib/shared/DEV_RELOAD_PATH.ts +6 -0
  219. package/src/lib/shared/HEALTH_PATH.ts +7 -0
  220. package/src/lib/shared/HttpError.ts +20 -0
  221. package/src/lib/shared/IDENTITY_PATH.ts +6 -0
  222. package/src/lib/shared/INSPECTOR_PATH.ts +7 -0
  223. package/src/lib/shared/NAV_HEADER.ts +8 -0
  224. package/src/lib/shared/OFFLINE_HEADER.ts +8 -0
  225. package/src/lib/shared/REMOTE_FUNCTION.ts +8 -0
  226. package/src/lib/shared/REPLAYABLE_METHODS.ts +12 -0
  227. package/src/lib/shared/SOCKETS_PATH.ts +7 -0
  228. package/src/lib/shared/STREAMING_CONTENT_TYPES.ts +11 -0
  229. package/src/lib/shared/SocketDisconnectedError.ts +13 -0
  230. package/src/lib/shared/TEXT_PLAIN.ts +7 -0
  231. package/src/lib/shared/abideImportName.ts +44 -0
  232. package/src/lib/shared/abideLog.ts +38 -0
  233. package/src/lib/shared/activeCacheStore.ts +20 -0
  234. package/src/lib/shared/activePage.ts +25 -0
  235. package/src/lib/shared/appDataDir.ts +34 -0
  236. package/src/lib/shared/appNameSlot.ts +10 -0
  237. package/src/lib/shared/basePath.ts +10 -0
  238. package/src/lib/shared/basePathFromAppUrl.ts +20 -0
  239. package/src/lib/shared/baseSlot.ts +14 -0
  240. package/src/lib/shared/binaryDirEnvPath.ts +12 -0
  241. package/src/lib/shared/browserClientFlags.ts +10 -0
  242. package/src/lib/shared/buildRpcProxy.ts +39 -0
  243. package/src/lib/shared/buildRpcRequest.ts +70 -0
  244. package/src/lib/shared/buildSocketOverChannel.ts +58 -0
  245. package/src/lib/shared/bundleLayout.ts +36 -0
  246. package/src/lib/shared/cache.ts +951 -0
  247. package/src/lib/shared/cacheEntryFromSnapshot.ts +59 -0
  248. package/src/lib/shared/cacheStoreSlot.ts +16 -0
  249. package/src/lib/shared/cacheStores.ts +10 -0
  250. package/src/lib/shared/canonicalJson.ts +63 -0
  251. package/src/lib/shared/carriesBodyArgs.ts +13 -0
  252. package/src/lib/shared/clearLastConnection.ts +7 -0
  253. package/src/lib/shared/commandNameForUrl.ts +17 -0
  254. package/src/lib/shared/createCacheStore.ts +104 -0
  255. package/src/lib/shared/createChannelLog.ts +122 -0
  256. package/src/lib/shared/createLifecycleChannel.ts +56 -0
  257. package/src/lib/shared/createLivenessWatch.ts +118 -0
  258. package/src/lib/shared/createPushIterator.ts +127 -0
  259. package/src/lib/shared/createRemoteFunction.ts +122 -0
  260. package/src/lib/shared/createSubscriber.ts +55 -0
  261. package/src/lib/shared/createTraceContext.ts +21 -0
  262. package/src/lib/shared/dataDirEnvPath.ts +12 -0
  263. package/src/lib/shared/decodeResponse.ts +47 -0
  264. package/src/lib/shared/detectTarget.ts +27 -0
  265. package/src/lib/shared/detectVerbMethod.ts +17 -0
  266. package/src/lib/shared/emitLogRecord.ts +190 -0
  267. package/src/lib/shared/exeSuffix.ts +9 -0
  268. package/src/lib/shared/exitOnBuildFailure.ts +17 -0
  269. package/src/lib/shared/extraForwardHeaders.ts +16 -0
  270. package/src/lib/shared/fileStem.ts +9 -0
  271. package/src/lib/shared/findExportCallSite.ts +476 -0
  272. package/src/lib/shared/formatTraceparent.ts +6 -0
  273. package/src/lib/shared/forwardHeaders.ts +44 -0
  274. package/src/lib/shared/getRemoteMeta.ts +5 -0
  275. package/src/lib/shared/globalCacheStore.ts +15 -0
  276. package/src/lib/shared/globalCacheStoreSlot.ts +14 -0
  277. package/src/lib/shared/health.ts +179 -0
  278. package/src/lib/shared/healthReadSlot.ts +11 -0
  279. package/src/lib/shared/healthSeedSlot.ts +12 -0
  280. package/src/lib/shared/html.ts +38 -0
  281. package/src/lib/shared/importNamesToStrip.ts +13 -0
  282. package/src/lib/shared/invalidateEvent.ts +11 -0
  283. package/src/lib/shared/invalidateTripwire.ts +40 -0
  284. package/src/lib/shared/isAbideHealthPayload.ts +11 -0
  285. package/src/lib/shared/isCompileTarget.ts +15 -0
  286. package/src/lib/shared/isDebugEnabled.ts +26 -0
  287. package/src/lib/shared/isDebugNegated.ts +19 -0
  288. package/src/lib/shared/isModuleNotFound.ts +16 -0
  289. package/src/lib/shared/isReadOnlyMethod.ts +14 -0
  290. package/src/lib/shared/isReplayableMethod.ts +7 -0
  291. package/src/lib/shared/isStreamingResponse.ts +11 -0
  292. package/src/lib/shared/isSubscribable.ts +15 -0
  293. package/src/lib/shared/jsonSchemaForPromptArguments.ts +29 -0
  294. package/src/lib/shared/jsonSchemaForSchema.ts +39 -0
  295. package/src/lib/shared/jsonlErrorFrame.ts +24 -0
  296. package/src/lib/shared/keyForRemoteCall.ts +29 -0
  297. package/src/lib/shared/keyMatchesPrefix.ts +9 -0
  298. package/src/lib/shared/lastConnectionPath.ts +7 -0
  299. package/src/lib/shared/layoutChainForRoute.ts +22 -0
  300. package/src/lib/shared/loadEnvFile.ts +17 -0
  301. package/src/lib/shared/loadEnvFromDataDir.ts +14 -0
  302. package/src/lib/shared/log.ts +24 -0
  303. package/src/lib/shared/logClosingRecord.ts +28 -0
  304. package/src/lib/shared/logTapSlot.ts +13 -0
  305. package/src/lib/shared/manifestModule.ts +39 -0
  306. package/src/lib/shared/matchesDebugPattern.ts +16 -0
  307. package/src/lib/shared/memoizeByKey.ts +32 -0
  308. package/src/lib/shared/normalizeTarget.ts +10 -0
  309. package/src/lib/shared/online.ts +51 -0
  310. package/src/lib/shared/page.ts +30 -0
  311. package/src/lib/shared/pageSlot.ts +17 -0
  312. package/src/lib/shared/pageUrlForFile.ts +14 -0
  313. package/src/lib/shared/parseBoundedEnvInt.ts +20 -0
  314. package/src/lib/shared/parseDebugPatterns.ts +21 -0
  315. package/src/lib/shared/parseEnv.ts +30 -0
  316. package/src/lib/shared/parsePromptMarkdown.ts +35 -0
  317. package/src/lib/shared/parseRouteSegments.ts +22 -0
  318. package/src/lib/shared/parseTraceparent.ts +26 -0
  319. package/src/lib/shared/pending.ts +30 -0
  320. package/src/lib/shared/prepareRpcModule.ts +59 -0
  321. package/src/lib/shared/prepareSocketModule.ts +49 -0
  322. package/src/lib/shared/probeRegistries.ts +68 -0
  323. package/src/lib/shared/producerKey.ts +32 -0
  324. package/src/lib/shared/programNameForPackage.ts +14 -0
  325. package/src/lib/shared/promptNameForFile.ts +10 -0
  326. package/src/lib/shared/queryStringFromArgs.ts +27 -0
  327. package/src/lib/shared/randomHexId.ts +14 -0
  328. package/src/lib/shared/readEnvFile.ts +15 -0
  329. package/src/lib/shared/readLastConnection.ts +18 -0
  330. package/src/lib/shared/readPackageJson.ts +9 -0
  331. package/src/lib/shared/recordRemoteMeta.ts +5 -0
  332. package/src/lib/shared/refreshing.ts +31 -0
  333. package/src/lib/shared/remoteMetaStore.ts +16 -0
  334. package/src/lib/shared/requestScopeSlot.ts +15 -0
  335. package/src/lib/shared/resolveClientFlags.ts +20 -0
  336. package/src/lib/shared/responseErrorText.ts +9 -0
  337. package/src/lib/shared/rpcTimeoutSlot.ts +9 -0
  338. package/src/lib/shared/rpcUrlForFile.ts +19 -0
  339. package/src/lib/shared/runningAsStandaloneBinary.ts +13 -0
  340. package/src/lib/shared/selectorMatcher.ts +68 -0
  341. package/src/lib/shared/selectorPrefix.ts +39 -0
  342. package/src/lib/shared/serializeEnv.ts +18 -0
  343. package/src/lib/shared/setAppName.ts +5 -0
  344. package/src/lib/shared/setBaseResolver.ts +6 -0
  345. package/src/lib/shared/setCacheStoreResolver.ts +6 -0
  346. package/src/lib/shared/setGlobalCacheStoreResolver.ts +6 -0
  347. package/src/lib/shared/setPageResolver.ts +7 -0
  348. package/src/lib/shared/setRequestScopeResolver.ts +6 -0
  349. package/src/lib/shared/snippet.ts +25 -0
  350. package/src/lib/shared/socketNameForFile.ts +11 -0
  351. package/src/lib/shared/socketTapSlot.ts +12 -0
  352. package/src/lib/shared/sseErrorFrame.ts +29 -0
  353. package/src/lib/shared/streamResponse.ts +169 -0
  354. package/src/lib/shared/stripImport.ts +27 -0
  355. package/src/lib/shared/subscribableFromResponse.ts +51 -0
  356. package/src/lib/shared/tailProbeSlot.ts +16 -0
  357. package/src/lib/shared/toBunRoutePattern.ts +28 -0
  358. package/src/lib/shared/toScopeSet.ts +4 -0
  359. package/src/lib/shared/trace.ts +16 -0
  360. package/src/lib/shared/types/CacheEntry.ts +84 -0
  361. package/src/lib/shared/types/CacheInvalidation.ts +9 -0
  362. package/src/lib/shared/types/CacheOnContext.ts +25 -0
  363. package/src/lib/shared/types/CacheOptions.ts +39 -0
  364. package/src/lib/shared/types/CacheSelector.ts +17 -0
  365. package/src/lib/shared/types/CacheSnapshot.ts +16 -0
  366. package/src/lib/shared/types/CacheSnapshotEntry.ts +17 -0
  367. package/src/lib/shared/types/CacheStats.ts +13 -0
  368. package/src/lib/shared/types/CacheStore.ts +39 -0
  369. package/src/lib/shared/types/ChannelLog.ts +13 -0
  370. package/src/lib/shared/types/ClientFlags.ts +11 -0
  371. package/src/lib/shared/types/CompileTarget.ts +6 -0
  372. package/src/lib/shared/types/FrameworkLog.ts +13 -0
  373. package/src/lib/shared/types/HttpVerb.ts +1 -0
  374. package/src/lib/shared/types/LastConnection.ts +9 -0
  375. package/src/lib/shared/types/Log.ts +13 -0
  376. package/src/lib/shared/types/LogRecord.ts +42 -0
  377. package/src/lib/shared/types/LogVoice.ts +7 -0
  378. package/src/lib/shared/types/PageSnapshot.ts +14 -0
  379. package/src/lib/shared/types/PromptArgument.ts +12 -0
  380. package/src/lib/shared/types/RawRemoteFunction.ts +14 -0
  381. package/src/lib/shared/types/RemoteCallable.ts +12 -0
  382. package/src/lib/shared/types/RemoteFunction.ts +47 -0
  383. package/src/lib/shared/types/ReplayableMethod.ts +7 -0
  384. package/src/lib/shared/types/RequestScopeInfo.ts +16 -0
  385. package/src/lib/shared/types/RpcInvoker.ts +6 -0
  386. package/src/lib/shared/types/SocketChannel.ts +17 -0
  387. package/src/lib/shared/types/SocketSubCallbacks.ts +13 -0
  388. package/src/lib/shared/types/StandardSchemaV1.ts +56 -0
  389. package/src/lib/shared/types/StreamedResolution.ts +10 -0
  390. package/src/lib/shared/types/Subscribable.ts +26 -0
  391. package/src/lib/shared/types/TailHooks.ts +12 -0
  392. package/src/lib/shared/types/TailOptions.ts +10 -0
  393. package/src/lib/shared/types/TraceContext.ts +17 -0
  394. package/src/lib/shared/url.ts +118 -0
  395. package/src/lib/shared/withBase.ts +11 -0
  396. package/src/lib/shared/withBaseUrl.ts +17 -0
  397. package/src/lib/shared/withJsonSchema.ts +21 -0
  398. package/src/lib/shared/writeDts.ts +12 -0
  399. package/src/lib/shared/writeHealthDts.ts +36 -0
  400. package/src/lib/shared/writeLastConnection.ts +13 -0
  401. package/src/lib/shared/writePublicAssetsDts.ts +31 -0
  402. package/src/lib/shared/writeRoutesDts.ts +73 -0
  403. package/src/lib/shared/writeRpcDts.ts +49 -0
  404. package/src/lib/shared/writeTestRpcDts.ts +45 -0
  405. package/src/lib/shared/writeTestSocketsDts.ts +34 -0
  406. package/src/lib/test/assertAgentFrameConformance.ts +73 -0
  407. package/src/lib/test/createScriptedSurface.ts +45 -0
  408. package/src/lib/test/createTestApp.ts +203 -0
  409. package/src/lib/test/createTestSocketChannel.ts +142 -0
  410. package/src/lib/ui/README.md +86 -0
  411. package/src/lib/ui/compile/SSR_ESCAPE.ts +25 -0
  412. package/src/lib/ui/compile/UI_RUNTIME_IMPORTS.ts +36 -0
  413. package/src/lib/ui/compile/VOID_TAGS.ts +21 -0
  414. package/src/lib/ui/compile/abideUiPlugin.ts +65 -0
  415. package/src/lib/ui/compile/analyzeComponent.ts +117 -0
  416. package/src/lib/ui/compile/assetModulesFile.ts +32 -0
  417. package/src/lib/ui/compile/branchElements.ts +50 -0
  418. package/src/lib/ui/compile/collectAbideDiagnostics.ts +59 -0
  419. package/src/lib/ui/compile/compileComponent.ts +20 -0
  420. package/src/lib/ui/compile/compileModule.ts +116 -0
  421. package/src/lib/ui/compile/compileSSR.ts +36 -0
  422. package/src/lib/ui/compile/compileShadow.ts +352 -0
  423. package/src/lib/ui/compile/createShadowLanguageService.ts +197 -0
  424. package/src/lib/ui/compile/createShadowProgram.ts +96 -0
  425. package/src/lib/ui/compile/decodeHtmlEntities.ts +49 -0
  426. package/src/lib/ui/compile/desugarSignals.ts +133 -0
  427. package/src/lib/ui/compile/escapeHtml.ts +15 -0
  428. package/src/lib/ui/compile/generateBuild.ts +638 -0
  429. package/src/lib/ui/compile/generateSSR.ts +380 -0
  430. package/src/lib/ui/compile/groupBindParts.ts +28 -0
  431. package/src/lib/ui/compile/hoistCells.ts +120 -0
  432. package/src/lib/ui/compile/loadShadowTsConfig.ts +31 -0
  433. package/src/lib/ui/compile/lowerDocAccess.ts +202 -0
  434. package/src/lib/ui/compile/nearestProjectRoot.ts +16 -0
  435. package/src/lib/ui/compile/parseTemplate.ts +396 -0
  436. package/src/lib/ui/compile/partitionSlots.ts +36 -0
  437. package/src/lib/ui/compile/prepareNestedScript.ts +42 -0
  438. package/src/lib/ui/compile/remapShadowDiagnostic.ts +30 -0
  439. package/src/lib/ui/compile/renameSignalRefs.ts +85 -0
  440. package/src/lib/ui/compile/resolveAbideImports.ts +29 -0
  441. package/src/lib/ui/compile/scopeCss.ts +115 -0
  442. package/src/lib/ui/compile/shadowNaming.ts +11 -0
  443. package/src/lib/ui/compile/sourceToShadowOffset.ts +24 -0
  444. package/src/lib/ui/compile/staticAttrValue.ts +13 -0
  445. package/src/lib/ui/compile/stripEffects.ts +32 -0
  446. package/src/lib/ui/compile/types/AbideDiagnostic.ts +14 -0
  447. package/src/lib/ui/compile/types/AnalyzedComponent.ts +25 -0
  448. package/src/lib/ui/compile/types/CompiledShadow.ts +15 -0
  449. package/src/lib/ui/compile/types/TemplateAttr.ts +16 -0
  450. package/src/lib/ui/compile/types/TemplateNode.ts +78 -0
  451. package/src/lib/ui/compile/types/TextPart.ts +8 -0
  452. package/src/lib/ui/derived.ts +28 -0
  453. package/src/lib/ui/doc.ts +15 -0
  454. package/src/lib/ui/dom/appendSnippet.ts +34 -0
  455. package/src/lib/ui/dom/appendStatic.ts +27 -0
  456. package/src/lib/ui/dom/appendText.ts +114 -0
  457. package/src/lib/ui/dom/applyResolved.ts +72 -0
  458. package/src/lib/ui/dom/attach.ts +20 -0
  459. package/src/lib/ui/dom/attr.ts +19 -0
  460. package/src/lib/ui/dom/awaitBlock.ts +224 -0
  461. package/src/lib/ui/dom/cloneStatic.ts +52 -0
  462. package/src/lib/ui/dom/each.ts +115 -0
  463. package/src/lib/ui/dom/eachAsync.ts +153 -0
  464. package/src/lib/ui/dom/hydrate.ts +35 -0
  465. package/src/lib/ui/dom/mount.ts +29 -0
  466. package/src/lib/ui/dom/mountChild.ts +33 -0
  467. package/src/lib/ui/dom/on.ts +15 -0
  468. package/src/lib/ui/dom/openChild.ts +22 -0
  469. package/src/lib/ui/dom/openRoot.ts +20 -0
  470. package/src/lib/ui/dom/switchBlock.ts +75 -0
  471. package/src/lib/ui/dom/text.ts +20 -0
  472. package/src/lib/ui/dom/tryBlock.ts +112 -0
  473. package/src/lib/ui/dom/types/EachRow.ts +3 -0
  474. package/src/lib/ui/dom/types/SwitchCase.ts +6 -0
  475. package/src/lib/ui/dom/when.ts +73 -0
  476. package/src/lib/ui/effect.ts +16 -0
  477. package/src/lib/ui/installHotBridge.ts +73 -0
  478. package/src/lib/ui/matchRoute.ts +89 -0
  479. package/src/lib/ui/navigate.ts +17 -0
  480. package/src/lib/ui/probeNavigation.ts +33 -0
  481. package/src/lib/ui/remoteProxy.ts +97 -0
  482. package/src/lib/ui/renderChain.ts +50 -0
  483. package/src/lib/ui/renderToStream.ts +104 -0
  484. package/src/lib/ui/router.ts +286 -0
  485. package/src/lib/ui/runtime/OUTLET_TAG.ts +8 -0
  486. package/src/lib/ui/runtime/OWNER.ts +8 -0
  487. package/src/lib/ui/runtime/REACTIVE_CONTEXT.ts +14 -0
  488. package/src/lib/ui/runtime/RENDER.ts +23 -0
  489. package/src/lib/ui/runtime/RESUME.ts +16 -0
  490. package/src/lib/ui/runtime/applyPatchToTree.ts +41 -0
  491. package/src/lib/ui/runtime/claimChild.ts +10 -0
  492. package/src/lib/ui/runtime/clientPage.ts +16 -0
  493. package/src/lib/ui/runtime/createComputedNode.ts +16 -0
  494. package/src/lib/ui/runtime/createDoc.ts +177 -0
  495. package/src/lib/ui/runtime/createEffectNode.ts +58 -0
  496. package/src/lib/ui/runtime/createSignalNode.ts +16 -0
  497. package/src/lib/ui/runtime/detachLink.ts +21 -0
  498. package/src/lib/ui/runtime/endTracking.ts +24 -0
  499. package/src/lib/ui/runtime/enterRenderPass.ts +12 -0
  500. package/src/lib/ui/runtime/exitRenderPass.ts +7 -0
  501. package/src/lib/ui/runtime/firstOutlet.ts +22 -0
  502. package/src/lib/ui/runtime/flushEffects.ts +17 -0
  503. package/src/lib/ui/runtime/hotInstances.ts +10 -0
  504. package/src/lib/ui/runtime/hotReloadEnabled.ts +8 -0
  505. package/src/lib/ui/runtime/hotReplace.ts +25 -0
  506. package/src/lib/ui/runtime/nextBlockId.ts +11 -0
  507. package/src/lib/ui/runtime/pathExists.ts +23 -0
  508. package/src/lib/ui/runtime/readNode.ts +17 -0
  509. package/src/lib/ui/runtime/registerHotInstance.ts +23 -0
  510. package/src/lib/ui/runtime/runNode.ts +28 -0
  511. package/src/lib/ui/runtime/runtimePath.ts +9 -0
  512. package/src/lib/ui/runtime/scope.ts +24 -0
  513. package/src/lib/ui/runtime/toTeardown.ts +26 -0
  514. package/src/lib/ui/runtime/track.ts +58 -0
  515. package/src/lib/ui/runtime/trigger.ts +44 -0
  516. package/src/lib/ui/runtime/types/Cell.ts +5 -0
  517. package/src/lib/ui/runtime/types/Derived.ts +3 -0
  518. package/src/lib/ui/runtime/types/Doc.ts +19 -0
  519. package/src/lib/ui/runtime/types/EffectResult.ts +10 -0
  520. package/src/lib/ui/runtime/types/HotInstance.ts +14 -0
  521. package/src/lib/ui/runtime/types/NavVerdict.ts +9 -0
  522. package/src/lib/ui/runtime/types/Patch.ts +11 -0
  523. package/src/lib/ui/runtime/types/ReactiveLink.ts +21 -0
  524. package/src/lib/ui/runtime/types/ReactiveNode.ts +25 -0
  525. package/src/lib/ui/runtime/types/Route.ts +8 -0
  526. package/src/lib/ui/runtime/types/RouteLoader.ts +7 -0
  527. package/src/lib/ui/runtime/types/SsrRender.ts +22 -0
  528. package/src/lib/ui/runtime/types/State.ts +3 -0
  529. package/src/lib/ui/runtime/types/Teardown.ts +5 -0
  530. package/src/lib/ui/runtime/types/UiComponent.ts +16 -0
  531. package/src/lib/ui/runtime/types/UiProps.ts +15 -0
  532. package/src/lib/ui/runtime/unlinkDeps.ts +20 -0
  533. package/src/lib/ui/runtime/untrack.ts +20 -0
  534. package/src/lib/ui/runtime/valueAtPath.ts +18 -0
  535. package/src/lib/ui/runtime/writeNode.ts +16 -0
  536. package/src/lib/ui/socketChannel.ts +227 -0
  537. package/src/lib/ui/socketProxy.ts +25 -0
  538. package/src/lib/ui/startClient.ts +58 -0
  539. package/src/lib/ui/state.ts +25 -0
  540. package/src/lib/ui/tail.ts +324 -0
  541. package/src/lib/ui/types/Layouts.ts +9 -0
  542. package/src/lib/ui/types/Pages.ts +8 -0
  543. package/src/preload.ts +19 -0
  544. package/src/scaffold.ts +153 -0
  545. package/src/serverBuildPlugins.ts +19 -0
  546. package/src/serverEntry.ts +95 -0
  547. package/template/bunfig.toml +4 -0
  548. package/template/package.json +18 -0
  549. package/template/src/app.ts +28 -0
  550. package/template/src/bundle/icon.png +0 -0
  551. package/template/src/cli/banner.txt +3 -0
  552. package/template/src/cli/footer.txt +1 -0
  553. package/template/src/server/config.ts +17 -0
  554. package/template/src/server/rpc/getHello.ts +36 -0
  555. package/template/src/ui/Layout.abide +19 -0
  556. package/template/src/ui/app.css +21 -0
  557. package/template/src/ui/app.html +24 -0
  558. package/template/src/ui/pages/about/page.abide +9 -0
  559. package/template/src/ui/pages/page.abide +22 -0
  560. package/template/test/app.test.ts +30 -0
  561. package/template/tsconfig.json +18 -0
  562. package/tsconfig.app.json +17 -0
@@ -0,0 +1,73 @@
1
+ import { html } from '../shared/html.ts'
2
+ import { snippet } from '../shared/snippet.ts'
3
+ import { derived } from './derived.ts'
4
+ import { doc } from './doc.ts'
5
+ import { appendSnippet } from './dom/appendSnippet.ts'
6
+ import { appendStatic } from './dom/appendStatic.ts'
7
+ import { appendText } from './dom/appendText.ts'
8
+ import { attach } from './dom/attach.ts'
9
+ import { attr } from './dom/attr.ts'
10
+ import { awaitBlock } from './dom/awaitBlock.ts'
11
+ import { cloneStatic } from './dom/cloneStatic.ts'
12
+ import { each } from './dom/each.ts'
13
+ import { eachAsync } from './dom/eachAsync.ts'
14
+ import { hydrate } from './dom/hydrate.ts'
15
+ import { mount } from './dom/mount.ts'
16
+ import { mountChild } from './dom/mountChild.ts'
17
+ import { on } from './dom/on.ts'
18
+ import { openChild } from './dom/openChild.ts'
19
+ import { openRoot } from './dom/openRoot.ts'
20
+ import { switchBlock } from './dom/switchBlock.ts'
21
+ import { tryBlock } from './dom/tryBlock.ts'
22
+ import { when } from './dom/when.ts'
23
+ import { effect } from './effect.ts'
24
+ import { enterRenderPass } from './runtime/enterRenderPass.ts'
25
+ import { exitRenderPass } from './runtime/exitRenderPass.ts'
26
+ import { hotReloadEnabled } from './runtime/hotReloadEnabled.ts'
27
+ import { hotReplace } from './runtime/hotReplace.ts'
28
+ import { nextBlockId } from './runtime/nextBlockId.ts'
29
+ import { state } from './state.ts'
30
+
31
+ /*
32
+ Dev-only: exposes the abide-ui runtime plus `hotReplace` on `window.__abide`, and
33
+ flips on `hotReloadEnabled` so `mountChild` records every instance it mounts. A
34
+ hot module (the dev server's standalone recompile of one edited `.abide`) reads
35
+ its runtime from this object instead of importing fresh copies — so it shares the
36
+ one reactive graph and instance registry — then calls `hotReplace` to swap every
37
+ live instance in place. The keys mirror `UI_RUNTIME_IMPORTS` (+ `hotReplace`); a
38
+ test guards that pairing. `startClient` calls this when the server marks the page
39
+ dev (the live-reload script sets `window.__abideDev`).
40
+ */
41
+ export function installHotBridge(): void {
42
+ ;(globalThis as { __abide?: Record<string, unknown> }).__abide = {
43
+ html,
44
+ snippet,
45
+ doc,
46
+ state,
47
+ derived,
48
+ effect,
49
+ mount,
50
+ openChild,
51
+ openRoot,
52
+ appendText,
53
+ appendSnippet,
54
+ appendStatic,
55
+ cloneStatic,
56
+ attr,
57
+ on,
58
+ attach,
59
+ each,
60
+ eachAsync,
61
+ when,
62
+ awaitBlock,
63
+ tryBlock,
64
+ switchBlock,
65
+ mountChild,
66
+ hydrate,
67
+ nextBlockId,
68
+ enterRenderPass,
69
+ exitRenderPass,
70
+ hotReplace,
71
+ }
72
+ hotReloadEnabled.current = true
73
+ }
@@ -0,0 +1,89 @@
1
+ import type { RouteSegment } from '../shared/parseRouteSegments.ts'
2
+ import { parseRouteSegments } from '../shared/parseRouteSegments.ts'
3
+
4
+ /*
5
+ Per-route parse cache. The route set is stable across a session, so parsing a
6
+ pattern into segments (and counting its literals, the specificity tie-breaker) is
7
+ done once per route rather than twice per route on every navigation. Keyed by the
8
+ pattern string; entries never need eviction since routes don't churn.
9
+ */
10
+ const PARSED_ROUTES = new Map<string, { segments: RouteSegment[]; literals: number }>()
11
+
12
+ function parsedRoute(route: string): { segments: RouteSegment[]; literals: number } {
13
+ let parsed = PARSED_ROUTES.get(route)
14
+ if (parsed === undefined) {
15
+ const segments = parseRouteSegments(route)
16
+ const literals = segments.filter((segment) => segment.kind === 'literal').length
17
+ parsed = { segments, literals }
18
+ PARSED_ROUTES.set(route, parsed)
19
+ }
20
+ return parsed
21
+ }
22
+
23
+ /*
24
+ Client route matcher: given the registered route patterns and the current
25
+ pathname, returns the matching route + decoded params, or undefined. Mirrors the
26
+ server's segment grammar via the shared `parseRouteSegments` (literal / `[name]` /
27
+ `[...rest]`), so client navigation decodes params the same way SSR does. The most
28
+ specific match wins — the pattern with the most literal segments — so a static
29
+ route beats a param route at the same depth.
30
+ */
31
+ export function matchRoute(
32
+ routes: string[],
33
+ pathname: string,
34
+ ): { route: string; params: Record<string, string> } | undefined {
35
+ /* Normalize a trailing slash (except root) so `/users/` matches `/users` —
36
+ otherwise the extra empty segment makes the length guard reject it (a 404 the
37
+ server's own routing wouldn't give) or lets `/users/[id]` capture an empty id. */
38
+ const normalized =
39
+ pathname.length > 1 && pathname.endsWith('/') ? pathname.slice(0, -1) : pathname
40
+ const pathSegments = normalized.split('/')
41
+ let best: { route: string; params: Record<string, string>; literals: number } | undefined
42
+ for (const route of routes) {
43
+ const parsed = parsedRoute(route)
44
+ const params = matchSegments(parsed.segments, pathSegments)
45
+ if (params === undefined) {
46
+ continue
47
+ }
48
+ if (best === undefined || parsed.literals > best.literals) {
49
+ best = { route, params, literals: parsed.literals }
50
+ }
51
+ }
52
+ return best === undefined ? undefined : { route: best.route, params: best.params }
53
+ }
54
+
55
+ /* Matches one parsed pattern against the path's segments, capturing params;
56
+ undefined on mismatch. A catch-all consumes every remaining segment. */
57
+ function matchSegments(
58
+ segments: RouteSegment[],
59
+ pathSegments: string[],
60
+ ): Record<string, string> | undefined {
61
+ const params: Record<string, string> = {}
62
+ for (let index = 0; index < segments.length; index += 1) {
63
+ const segment = segments[index]
64
+ if (segment === undefined) {
65
+ return undefined
66
+ }
67
+ if (segment.kind === 'param' && segment.catchAll) {
68
+ params[segment.name] = pathSegments.slice(index).join('/')
69
+ return params
70
+ }
71
+ const value = pathSegments[index]
72
+ if (value === undefined) {
73
+ return undefined
74
+ }
75
+ if (segment.kind === 'literal') {
76
+ if (segment.value !== value) {
77
+ return undefined
78
+ }
79
+ } else {
80
+ /* A `[name]` param never captures an empty segment (e.g. `/users//5`). */
81
+ if (value === '') {
82
+ return undefined
83
+ }
84
+ params[segment.name] = value
85
+ }
86
+ }
87
+ /* No catch-all consumed the tail, so the path must have no extra segments. */
88
+ return pathSegments.length === segments.length ? params : undefined
89
+ }
@@ -0,0 +1,17 @@
1
+ import { runtimePath } from './runtime/runtimePath.ts'
2
+
3
+ /* Navigates to `path`: writes a history entry (when available) and updates the
4
+ reactive route, which re-mounts the matching page via `router`. `replace` swaps
5
+ the current entry instead of pushing — used when honouring a server redirect, so
6
+ the blocked URL isn't left behind in history. */
7
+ // @readme plumbing
8
+ export function navigate(path: string, replace = false): void {
9
+ if (typeof history !== 'undefined') {
10
+ if (replace) {
11
+ history.replaceState({}, '', path)
12
+ } else {
13
+ history.pushState({}, '', path)
14
+ }
15
+ }
16
+ runtimePath.value = path
17
+ }
@@ -0,0 +1,33 @@
1
+ import { NAV_HEADER } from '../shared/NAV_HEADER.ts'
2
+ import type { NavVerdict } from './runtime/types/NavVerdict.ts'
3
+
4
+ /*
5
+ The client router's SPA navigation probe: runs `path` through the server's
6
+ app.handle without a render. It's a fetch stamped with NAV_HEADER, which the page
7
+ dispatcher answers 204 once handle() has cleared it — so the round trip pays for
8
+ handle()'s auth/redirect gating, not a server render. fetch follows handle()'s
9
+ redirects server-side, so a redirected response's `url` is the final cleared
10
+ location: same-origin yields a soft client redirect (the router re-probes there),
11
+ cross-origin a full browser load. A non-OK status (handle() blocked it) or a thrown
12
+ fetch (offline) also hands off to the browser, so the server's real response —
13
+ a login page, an error page — is what renders.
14
+ */
15
+ // @readme plumbing
16
+ export async function probeNavigation(path: string): Promise<NavVerdict> {
17
+ let response: Response
18
+ try {
19
+ response = await fetch(path, { headers: { [NAV_HEADER]: '1' } })
20
+ } catch {
21
+ return { kind: 'reload', url: path }
22
+ }
23
+ if (response.redirected) {
24
+ const target = new URL(response.url)
25
+ return target.origin === location.origin
26
+ ? { kind: 'redirect', path: target.pathname + target.search }
27
+ : { kind: 'reload', url: response.url }
28
+ }
29
+ if (!response.ok) {
30
+ return { kind: 'reload', url: path }
31
+ }
32
+ return { kind: 'mount' }
33
+ }
@@ -0,0 +1,97 @@
1
+ import { browserClientFlags } from '../shared/browserClientFlags.ts'
2
+ import { buildRpcRequest } from '../shared/buildRpcRequest.ts'
3
+ import { createRemoteFunction } from '../shared/createRemoteFunction.ts'
4
+ import { HttpError } from '../shared/HttpError.ts'
5
+ import { OFFLINE_HEADER } from '../shared/OFFLINE_HEADER.ts'
6
+ import { rpcTimeoutSlot } from '../shared/rpcTimeoutSlot.ts'
7
+ import { trace } from '../shared/trace.ts'
8
+ import type { HttpVerb } from '../shared/types/HttpVerb.ts'
9
+ import type { RemoteFunction } from '../shared/types/RemoteFunction.ts'
10
+ import { withBase } from '../shared/withBase.ts'
11
+
12
+ /*
13
+ Client-side substitute for a verb-defined handler. The bundler emits one
14
+ call per verb export inside an `$rpc/**` module (GET / POST / …): server
15
+ target uses defineVerb (real handler), browser target uses remoteProxy
16
+ (fetch over the network). Both paths produce identical RemoteFunction
17
+ shapes and identical WeakMap metadata so cache() works the same on either
18
+ side.
19
+
20
+ `url` is the flat rpc route. Args go in the JSON body (POST/PUT/PATCH) or
21
+ the query string (GET/DELETE/HEAD). Plain `fn(args)` decodes the Response
22
+ by Content-Type and throws HttpError on non-2xx; `.raw(args)` is the
23
+ escape hatch that returns the Response untouched.
24
+ */
25
+ // @readme plumbing
26
+ export function remoteProxy<Args, Return>(
27
+ method: HttpVerb,
28
+ url: string,
29
+ ): RemoteFunction<Args, Return> {
30
+ return createRemoteFunction<Args, Return>({
31
+ method,
32
+ url,
33
+ clients: browserClientFlags,
34
+ /*
35
+ The Request URL carries the mount base so the fetch routes through the
36
+ proxy (/v2/rpc/…); the cache key keeps the bare `url` (keyForRemoteCall
37
+ reads fn.url), so SSR snapshots round-trip base-independently.
38
+ */
39
+ buildRequest: (args) =>
40
+ buildRpcRequest({
41
+ method,
42
+ url: withBase(url),
43
+ args,
44
+ baseUrl: window.location.href,
45
+ headers: rpcHeaders(),
46
+ }),
47
+ /*
48
+ Forcing `getRequest()` once builds the Request and seeds the
49
+ cache meta thunk in createRemoteFunction with the same instance,
50
+ so cache() readers don't reconstruct it.
51
+ */
52
+ invoke: (_args, getRequest) => fetchWithTimeout(getRequest()),
53
+ })
54
+ }
55
+
56
+ /*
57
+ Applies the env-configured client timeout (ABIDE_CLIENT_TIMEOUT, ms) when one
58
+ is set; an unset slot fetches unbounded, exactly as before. A timeout abort
59
+ surfaces as a 504 HttpError so a consumer reads an honest status instead of a
60
+ raw DOMException → 500. Other rejections (genuine network failure) propagate untouched.
61
+ */
62
+ function fetchWithTimeout(request: Request): Promise<Response> {
63
+ const timeout = rpcTimeoutSlot.ms
64
+ if (timeout === undefined) {
65
+ return fetch(request)
66
+ }
67
+ return fetch(request, { signal: AbortSignal.timeout(timeout) }).catch((error: unknown) => {
68
+ if (error instanceof DOMException && error.name === 'TimeoutError') {
69
+ throw new HttpError(
70
+ new Response('client timeout', { status: 504, statusText: 'Gateway Timeout' }),
71
+ )
72
+ }
73
+ throw error
74
+ })
75
+ }
76
+
77
+ /*
78
+ abide's per-RPC headers: the page traceparent (continues the server trace) and,
79
+ only while offline, the offline marker so the handler's online() reflects the
80
+ caller's connectivity. Returns undefined when neither applies so the
81
+ allocation-free fetch path stays the common case.
82
+ */
83
+ function rpcHeaders(): Headers | undefined {
84
+ const headers = new Headers()
85
+ let any = false
86
+ const traceparent = trace()
87
+ if (traceparent) {
88
+ headers.set('traceparent', traceparent)
89
+ any = true
90
+ }
91
+ /* Presence = offline; absence = online/unknown. navigator.onLine's offline signal is the reliable direction. */
92
+ if (typeof navigator !== 'undefined' && navigator.onLine === false) {
93
+ headers.set(OFFLINE_HEADER, '1')
94
+ any = true
95
+ }
96
+ return any ? headers : undefined
97
+ }
@@ -0,0 +1,50 @@
1
+ import { enterRenderPass } from './runtime/enterRenderPass.ts'
2
+ import { exitRenderPass } from './runtime/exitRenderPass.ts'
3
+ import { OUTLET_TAG } from './runtime/OUTLET_TAG.ts'
4
+ import type { SsrRender } from './runtime/types/SsrRender.ts'
5
+ import type { UiComponent } from './runtime/types/UiComponent.ts'
6
+
7
+ const OUTLET_OPEN = `<${OUTLET_TAG}>`
8
+ const OUTLET_CLOSE = `</${OUTLET_TAG}>`
9
+ const OUTLET_PLACEHOLDER = `${OUTLET_OPEN}${OUTLET_CLOSE}`
10
+
11
+ /*
12
+ Server-renders a route's layout chain wrapped around its page into one SsrRender.
13
+ `views` is ordered outermost layout → … → page. The whole chain renders under a
14
+ SINGLE render pass: one outer `enterRenderPass` resets the block-id counter, then
15
+ each `render()` runs nested (depth > 0, no reset), so every `await`/`try` block
16
+ across all layers draws a unique id from the shared counter — in the same
17
+ layer-sequential order the client hydrates them, keeping the streamed fragments and
18
+ the resume manifest aligned.
19
+
20
+ The html nests inner-to-outer: each parent's empty `<abide-outlet>` is filled with
21
+ the accumulated child html — the outlet ELEMENT is kept (it stays the live mount
22
+ container the client router fills/hydrates the child into, found by tag), so the
23
+ SSR DOM and the client-nested DOM match exactly. Awaits concatenate (already
24
+ uniquely numbered); state merges. A single component renders unchanged — its own
25
+ render with no wrapping. A layout missing its `<slot/>` is a build error surfaced here.
26
+ */
27
+ export function renderChain(views: UiComponent[], params: Record<string, string>): SsrRender {
28
+ enterRenderPass()
29
+ try {
30
+ const renders = views.map((view) => view.render(params))
31
+ let html = renders[renders.length - 1]?.html ?? ''
32
+ for (let index = renders.length - 2; index >= 0; index -= 1) {
33
+ const parent = renders[index] as SsrRender
34
+ if (!parent.html.includes(OUTLET_PLACEHOLDER)) {
35
+ throw new Error('[abide] a layout.abide must contain exactly one <slot/> outlet')
36
+ }
37
+ /* Fill the outlet element (keep it), function replacement so `$&`/`$\`` in
38
+ the child html insert literally. */
39
+ const child = html
40
+ html = parent.html.replace(OUTLET_PLACEHOLDER, () => OUTLET_OPEN + child + OUTLET_CLOSE)
41
+ }
42
+ return {
43
+ html,
44
+ awaits: renders.flatMap((render) => render.awaits),
45
+ state: Object.assign({}, ...renders.map((render) => render.state)),
46
+ }
47
+ } finally {
48
+ exitRenderPass()
49
+ }
50
+ }
@@ -0,0 +1,104 @@
1
+ import type { ResumeEntry } from './runtime/RESUME.ts'
2
+ import type { SsrAwait, SsrRender } from './runtime/types/SsrRender.ts'
3
+
4
+ /*
5
+ Out-of-order SSR streaming. Yields the pending shell first (so the browser paints
6
+ immediately), then one resolved fragment per await block as its promise settles —
7
+ in completion order, not source order, so a slow read never blocks a fast one.
8
+ Each resolved fragment is a `<abide-resolve data-id="ID" data-resume="…">…</abide-resolve>`
9
+ that `applyResolved` swaps into the matching `<!--abide:await:ID-->` boundary; the
10
+ `data-resume` payload is the JSON-serialized value, registered for hydration so an
11
+ `await` block adopts the resolved branch on resume instead of re-running.
12
+
13
+ This is the await-block-streams half of the cache rule: a top-level `await` in the
14
+ script would have blocked the shell (inlined), but an await *block* flushes its
15
+ shell now and streams the value when ready. Driven by a plain `render()` result,
16
+ so it composes with any transport (HTTP chunked, a socket frame, a test).
17
+
18
+ A `then` on the `await` tag makes the block BLOCKING: it settles before the first
19
+ flush, its resolved branch spliced into its (empty) boundary and its value seeded
20
+ into the resume manifest inline — so the value is in the first paint, no pending
21
+ shell, no swap. The first yield therefore awaits all blocking blocks; only the
22
+ remaining streaming blocks flush out of order after it.
23
+ */
24
+ // @readme plumbing
25
+ export async function* renderToStream(render: () => SsrRender): AsyncGenerator<string> {
26
+ const { html, awaits } = render()
27
+ /* Blocking awaits (a `then` on the `await` tag) settle BEFORE the first flush:
28
+ their resolved branch is spliced into its empty boundary and its value registered
29
+ inline, so the first paint already has the value — no pending, no swap. */
30
+ const blocking = awaits.filter((block) => block.blocking === true)
31
+ let shell = html
32
+ const resumed: Record<number, ResumeEntry> = {}
33
+ for (const settled of await Promise.all(blocking.map(settle))) {
34
+ shell = spliceResolved(shell, settled.id, settled.html)
35
+ resumed[settled.id] = settled.resume
36
+ }
37
+ yield shell + resumeScript(resumed)
38
+ /* Streaming awaits flush their resolved fragment out of order as each settles. */
39
+ const inflight = new Map<number, Promise<Settled>>()
40
+ for (const block of awaits) {
41
+ if (block.blocking !== true) {
42
+ inflight.set(block.id, settle(block))
43
+ }
44
+ }
45
+ while (inflight.size > 0) {
46
+ const resolved = await Promise.race(inflight.values())
47
+ inflight.delete(resolved.id)
48
+ const resume = encodeResume(resolved.resume)
49
+ yield `<abide-resolve data-id="${resolved.id}" data-resume="${resume}">${resolved.html}</abide-resolve>`
50
+ }
51
+ }
52
+
53
+ /* Inserts a blocking await's resolved markup into its (empty) boundary in the shell,
54
+ between the open and close markers. */
55
+ function spliceResolved(shell: string, id: number, resolved: string): string {
56
+ const open = `<!--abide:await:${id}-->`
57
+ const close = `<!--/abide:await:${id}-->`
58
+ /* A function replacement, so a `$&`/`$\`` etc. in the rendered value is inserted
59
+ literally rather than interpreted as a special replacement pattern. */
60
+ return shell.replace(`${open}${close}`, () => `${open}${resolved}${close}`)
61
+ }
62
+
63
+ /* A self-contained script seeding the resume manifest with the blocking values, so
64
+ client hydration adopts each resolved branch instead of re-running the promise.
65
+ Empty when no blocking awaits settled. */
66
+ function resumeScript(resumed: Record<number, ResumeEntry>): string {
67
+ if (Object.keys(resumed).length === 0) {
68
+ return ''
69
+ }
70
+ const payload = JSON.stringify(resumed).replace(/</g, '\\u003c')
71
+ return `<script>Object.assign(window.__abideResume=window.__abideResume||{},${payload})</script>`
72
+ }
73
+
74
+ type Settled = { id: number; html: string; resume: ResumeEntry }
75
+
76
+ /* Awaits one block's promise and renders the resolved or error branch to HTML,
77
+ capturing the value (serializable) for the resume manifest. Errors serialize as
78
+ their message — enough for the catch branch, without leaking a stack. */
79
+ function settle(block: SsrAwait): Promise<Settled> {
80
+ return Promise.resolve(block.promise()).then(
81
+ (value) => ({ id: block.id, html: block.then(value), resume: { ok: true, value } }),
82
+ (error) => {
83
+ /* No catch branch → surface the rejection (500 before the first flush,
84
+ mid-stream error after) instead of swallowing it into an empty fragment. */
85
+ if (block.catch === undefined) {
86
+ throw error
87
+ }
88
+ return {
89
+ id: block.id,
90
+ html: block.catch(error),
91
+ resume: { ok: false, error: String(error) },
92
+ }
93
+ },
94
+ )
95
+ }
96
+
97
+ /* JSON for an HTML double-quoted attribute: escape `"` and `&` (and `<` for safety
98
+ inside markup). `applyResolved`/the inline swap script decode it via the DOM. */
99
+ function encodeResume(resume: ResumeEntry): string {
100
+ return JSON.stringify(resume)
101
+ .replace(/&/g, '&amp;')
102
+ .replace(/"/g, '&quot;')
103
+ .replace(/</g, '&lt;')
104
+ }