@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,127 @@
1
+ /*
2
+ Single-slot-mailbox AsyncIterator factory shared by the in-process
3
+ socket fan-out (defineSocket) and the client-side ws proxy
4
+ (socketProxy). Callers push values, signal end, signal an error, or
5
+ signal a transport disconnect; the iterator drains a queue then awaits
6
+ the next push. Cancellation runs the optional `onClose` so subscribers
7
+ can drop their backref. `disconnect()` is terminal like `error()` but
8
+ throws the typed SocketDisconnectedError so consumers can tell a
9
+ recoverable transport loss from an application error.
10
+
11
+ The pending-value buffer is bounded: a subscriber whose `next()` falls
12
+ behind a chatty producer would otherwise grow it without limit, which on
13
+ the server is a remotely-triggerable memory-exhaustion vector. At the cap
14
+ the oldest pending value is dropped (live fan-out is latest-wins) so
15
+ memory stays bounded; terminal end/error slots are always appended and
16
+ never dropped.
17
+ */
18
+
19
+ import { SocketDisconnectedError } from './SocketDisconnectedError.ts'
20
+
21
+ type Slot<T> =
22
+ | { kind: 'value'; value: T }
23
+ | { kind: 'control'; run: () => void }
24
+ | { kind: 'end' }
25
+ | { kind: 'error'; message: string }
26
+ | { kind: 'disconnect' }
27
+
28
+ export type PushIterator<T> = AsyncIterator<T, void, undefined> & {
29
+ push(value: T): void
30
+ /*
31
+ Queues an in-band signal (e.g. the replay/live boundary): `run` executes
32
+ inside next() when drained, strictly ordered against pushed values, and
33
+ is invisible to the consumer — next() continues to the following slot.
34
+ Never dropped by the buffer cap.
35
+ */
36
+ control(run: () => void): void
37
+ end(): void
38
+ error(message: string): void
39
+ disconnect(): void
40
+ }
41
+
42
+ const DEFAULT_MAX_BUFFER = 1024
43
+
44
+ export function createPushIterator<T>(
45
+ onClose?: () => void,
46
+ maxBuffer = DEFAULT_MAX_BUFFER,
47
+ ): PushIterator<T> {
48
+ const buffer: Slot<T>[] = []
49
+ let waiter: ((slot: Slot<T>) => void) | undefined
50
+ let closed = false
51
+
52
+ function deliver(slot: Slot<T>): void {
53
+ if (closed) {
54
+ return
55
+ }
56
+ if (waiter) {
57
+ const wake = waiter
58
+ waiter = undefined
59
+ wake(slot)
60
+ return
61
+ }
62
+ // Drop the oldest pending value before exceeding the cap.
63
+ if (slot.kind === 'value' && buffer.length >= maxBuffer) {
64
+ buffer.shift()
65
+ }
66
+ buffer.push(slot)
67
+ }
68
+
69
+ function close(): void {
70
+ if (closed) {
71
+ return
72
+ }
73
+ closed = true
74
+ onClose?.()
75
+ }
76
+
77
+ return {
78
+ push(value) {
79
+ deliver({ kind: 'value', value })
80
+ },
81
+ control(run) {
82
+ deliver({ kind: 'control', run })
83
+ },
84
+ end() {
85
+ deliver({ kind: 'end' })
86
+ },
87
+ error(message) {
88
+ deliver({ kind: 'error', message })
89
+ },
90
+ disconnect() {
91
+ deliver({ kind: 'disconnect' })
92
+ },
93
+ async next() {
94
+ while (true) {
95
+ if (closed) {
96
+ return { value: undefined, done: true }
97
+ }
98
+ const slot = buffer.shift() ?? (await new Promise<Slot<T>>((r) => (waiter = r)))
99
+ if (slot.kind === 'control') {
100
+ slot.run()
101
+ continue
102
+ }
103
+ if (slot.kind === 'end') {
104
+ close()
105
+ return { value: undefined, done: true }
106
+ }
107
+ if (slot.kind === 'error') {
108
+ close()
109
+ throw new Error(slot.message)
110
+ }
111
+ if (slot.kind === 'disconnect') {
112
+ close()
113
+ throw new SocketDisconnectedError()
114
+ }
115
+ return { value: slot.value, done: false }
116
+ }
117
+ },
118
+ async return() {
119
+ if (!closed) {
120
+ close()
121
+ waiter?.({ kind: 'end' })
122
+ waiter = undefined
123
+ }
124
+ return { value: undefined, done: true }
125
+ },
126
+ }
127
+ }
@@ -0,0 +1,122 @@
1
+ import { decodeResponse } from './decodeResponse.ts'
2
+ import { HttpError } from './HttpError.ts'
3
+ import { keyForRemoteCall } from './keyForRemoteCall.ts'
4
+ import { REMOTE_FUNCTION } from './REMOTE_FUNCTION.ts'
5
+ import { recordRemoteMeta } from './recordRemoteMeta.ts'
6
+ import { subscribableFromResponse } from './subscribableFromResponse.ts'
7
+ import type { ClientFlags } from './types/ClientFlags.ts'
8
+ import type { HttpVerb } from './types/HttpVerb.ts'
9
+ import type { RawRemoteFunction } from './types/RawRemoteFunction.ts'
10
+ import type { RemoteFunction } from './types/RemoteFunction.ts'
11
+ import type { Subscribable } from './types/Subscribable.ts'
12
+
13
+ /*
14
+ Assembles the public RemoteFunction shape used identically by the
15
+ server-side defineVerb (in-process handler invocation) and the
16
+ client-side remoteProxy (network fetch). Centralising the wiring here
17
+ keeps the call/raw/stream/fetch semantics — including WeakMap meta
18
+ recording, Content-Type decode, and Subscribable derivation — in one
19
+ place so the two halves can't drift.
20
+
21
+ - `buildRequest(args)` synthesizes the Request a meta reader (cache()) or
22
+ the client invoke needs. Server uses the inbound request's URL as the
23
+ base; client uses window.location. The result is memoised inside the
24
+ per-call `getRequest` thunk so the Request is built at most once per
25
+ call regardless of how many readers pull on it.
26
+ - `invoke(args, getRequest)` actually runs the call: server defineVerb
27
+ runs the handler and ignores `getRequest`; client remoteProxy calls
28
+ `fetch(getRequest())`. The thunk lets the server skip the Request
29
+ allocation entirely on the SSR hot path — the only consumer that ever
30
+ forces it is cache(), via the meta thunk recorded below.
31
+ - `parseArgsForFetch` is optional and only set by the server, so the
32
+ framework's router can call `.fetch(inboundRequest)` and have the
33
+ handler receive parsed args. Client `remoteProxy.fetch` just
34
+ forwards the request through invoke().
35
+ */
36
+ export function createRemoteFunction<Args, Return>(opts: {
37
+ method: HttpVerb
38
+ url: string
39
+ clients: ClientFlags
40
+ /* Server-side only: exempts a mutating verb from the router's same-origin CSRF gate. */
41
+ crossOrigin?: boolean
42
+ buildRequest: (args: Args | undefined) => Request
43
+ invoke: (args: Args | undefined, getRequest: () => Request) => Promise<Response>
44
+ parseArgsForFetch?: (request: Request) => Promise<Args | undefined>
45
+ }): RemoteFunction<Args, Return> {
46
+ const { method, url, clients, crossOrigin, buildRequest, invoke, parseArgsForFetch } = opts
47
+
48
+ /*
49
+ Dispatch is the one-stop entry for both the plain call (no prebuilt
50
+ Request) and the fetch path (router hands us the inbound Request as
51
+ `prebuilt`). The `getRequest` thunk lazily synthesizes — or
52
+ short-circuits to the prebuilt one — and caches the result so the
53
+ client invoke + the cache meta reader share a single Request.
54
+ */
55
+ function dispatch(args: Args | undefined, prebuilt?: Request): Promise<Response> {
56
+ let cached = prebuilt
57
+ function getRequest(): Request {
58
+ if (cached === undefined) {
59
+ cached = buildRequest(args)
60
+ }
61
+ return cached
62
+ }
63
+ const promise = invoke(args, getRequest)
64
+ recordRemoteMeta(promise, getRequest)
65
+ return promise
66
+ }
67
+
68
+ /*
69
+ A body verb may receive a FormData in place of typed Args (the upload
70
+ escape hatch). It flows through dispatch only into buildRpcRequest /
71
+ keyForRemoteCall, both of which take it as-is, so the cast to Args is a
72
+ contained type lie — buildRpcRequest's `instanceof FormData` branch handles
73
+ it at runtime.
74
+ */
75
+ function rawCall(args: Args | FormData): Promise<Response> {
76
+ return dispatch(args as Args)
77
+ }
78
+ rawCall.method = method
79
+ rawCall.url = url
80
+ /* Non-enumerable brand on both variants; see REMOTE_FUNCTION. */
81
+ Object.defineProperty(rawCall, REMOTE_FUNCTION, { value: true })
82
+ const raw = rawCall as RawRemoteFunction<Args>
83
+
84
+ function callable(args: Args | FormData): Promise<Return> {
85
+ return raw(args).then(decodeResponse) as Promise<Return>
86
+ }
87
+ callable.method = method
88
+ callable.url = url
89
+ callable.clients = clients
90
+ callable.crossOrigin = crossOrigin
91
+ callable.raw = raw
92
+ callable.stream = (args?: Args | FormData): Subscribable<Return> => {
93
+ return subscribableFromResponse(keyForRemoteCall(method, url, args), () =>
94
+ raw(args as Args),
95
+ )
96
+ }
97
+ Object.defineProperty(callable, REMOTE_FUNCTION, { value: true })
98
+ callable.fetch = parseArgsForFetch
99
+ ? async (request: Request): Promise<Response> => {
100
+ let args: Args | undefined
101
+ try {
102
+ args = await parseArgsForFetch(request)
103
+ } catch (error) {
104
+ /*
105
+ Parse-stage rejections that already chose their wire shape
106
+ (readBodyWithinLimit's 413) return it; anything else (e.g.
107
+ malformed JSON) keeps propagating to the scope's catch.
108
+ Handler errors are outside this try on purpose — throwing
109
+ is the app.handleError path, `return error(...)` the wire one.
110
+ */
111
+ if (error instanceof HttpError) {
112
+ return error.response
113
+ }
114
+ throw error
115
+ }
116
+ return dispatch(args, request)
117
+ }
118
+ : (request: Request): Promise<Response> => {
119
+ return dispatch(undefined, request)
120
+ }
121
+ return callable as RemoteFunction<Args, Return>
122
+ }
@@ -0,0 +1,55 @@
1
+ import { createSignalNode } from '../ui/runtime/createSignalNode.ts'
2
+ import { OWNER } from '../ui/runtime/OWNER.ts'
3
+ import { track } from '../ui/runtime/track.ts'
4
+ import { trigger } from '../ui/runtime/trigger.ts'
5
+
6
+ /*
7
+ abide-ui-native `createSubscriber`: open-on-first-read, close-on-last-reader,
8
+ grounded in abide's own signal core (no external reactivity library). The
9
+ reactivity substrate lives in `../ui/runtime` — pure, DOM-free signal primitives
10
+ that the isomorphic shared layer reuses, the same way the cache reuses other
11
+ shared machinery.
12
+
13
+ `start` opens the resource and returns a cleanup; the returned `subscribe()`,
14
+ read inside a abide-ui effect/derived, registers that reader (via `track`) and
15
+ re-runs it whenever `update` fires.
16
+
17
+ Lifecycle rides the signal node's observer set. The resource opens SYNCHRONOUSLY
18
+ on the first tracked read — a consumer like tail() flips state in
19
+ `start` that its very read path checks, so a deferred open would let it read a
20
+ not-yet-open entry and evict it. The close is deferred to a microtask scheduled on
21
+ a reader's scope disposal: an effect re-run momentarily drops then re-adds itself
22
+ as an observer, so checking on the microtask (not synchronously) avoids tearing the
23
+ resource down and reopening it across a re-run. Called outside any tracking scope,
24
+ `track` is a no-op, observers stay empty, and the resource never opens — matching
25
+ the open-on-first-read contract.
26
+ */
27
+ // @readme plumbing
28
+ export function createSubscriber(start: (update: () => void) => () => void): () => void {
29
+ const node = createSignalNode(undefined)
30
+ let cleanup: (() => void) | undefined
31
+ let closeScheduled = false
32
+
33
+ const maybeClose = (): void => {
34
+ closeScheduled = false
35
+ if (node.subsHead === undefined && cleanup !== undefined) {
36
+ cleanup()
37
+ cleanup = undefined
38
+ }
39
+ }
40
+
41
+ return () => {
42
+ track(node)
43
+ /* Open eagerly on the first reader within a tracking scope. */
44
+ if (cleanup === undefined && node.subsHead !== undefined) {
45
+ cleanup = start(() => trigger(node))
46
+ }
47
+ /* Close once this reader's scope tears down and no observers remain. */
48
+ OWNER.current?.push(() => {
49
+ if (!closeScheduled) {
50
+ closeScheduled = true
51
+ queueMicrotask(maybeClose)
52
+ }
53
+ })
54
+ }
55
+ }
@@ -0,0 +1,21 @@
1
+ import { parseTraceparent } from './parseTraceparent.ts'
2
+ import { randomHexId } from './randomHexId.ts'
3
+ import type { TraceContext } from './types/TraceContext.ts'
4
+
5
+ /*
6
+ Builds this request's trace position from an inbound `traceparent` header.
7
+ Prefer-incoming rule: a valid header keeps its trace id and sampling flags
8
+ (abide never overwrites a trace someone upstream started); the header's span
9
+ id becomes `parentSpanId`. Either way abide mints a fresh `spanId` for this
10
+ request — the one outbound hops carry as parent. No header (or a malformed
11
+ one) starts a new trace, sampled ('01') so downstream recorders keep it.
12
+ */
13
+ export function createTraceContext(header: string | null | undefined): TraceContext {
14
+ const incoming = header ? parseTraceparent(header) : undefined
15
+ return {
16
+ traceId: incoming?.traceId ?? randomHexId(16),
17
+ spanId: randomHexId(8),
18
+ parentSpanId: incoming?.spanId,
19
+ flags: incoming?.flags ?? '01',
20
+ }
21
+ }
@@ -0,0 +1,12 @@
1
+ import { join } from 'node:path'
2
+ import { appDataDir } from './appDataDir.ts'
3
+
4
+ /*
5
+ The user's `.env` in the program's per-user data dir — the cwd-independent
6
+ config layer the connect-screen form writes and the server loads first at
7
+ boot. One statement of the location so the writer (controlServerWorker), the
8
+ boot loader (loadEnvFromDataDir), and the embedded-port resolver can't drift.
9
+ */
10
+ export function dataDirEnvPath(programName: string): string {
11
+ return join(appDataDir(programName), '.env')
12
+ }
@@ -0,0 +1,47 @@
1
+ import { HttpError } from './HttpError.ts'
2
+ import { isStreamingResponse } from './isStreamingResponse.ts'
3
+
4
+ /*
5
+ Decodes a Response into the natural body value based on Content-Type:
6
+ application/json (or `*\/+json`) → parsed JSON
7
+ text/* → string
8
+ 204 No Content / empty body → undefined
9
+ everything else → Blob
10
+
11
+ Non-2xx responses throw HttpError so the happy path never has to check
12
+ `.ok` — error handling moves into try/catch (or unhandled exception
13
+ propagation), and the success path types as Promise<Return> cleanly.
14
+
15
+ Streaming Content-Types (SSE / JSONL / NDJSON) throw a clear error
16
+ rather than silently doing the wrong thing: response.text() would hang
17
+ forever on a never-ending body and response.json() would fail mid-parse.
18
+ The error points callers at the right tools — `tail(fn.stream(args))`
19
+ for a shared reactive view, or `fn.stream(args)` directly for a fresh
20
+ per-call AsyncIterable — both of which know how to consume the body
21
+ frame-by-frame.
22
+
23
+ Callers that need headers, streaming, or per-status branching should use
24
+ the `.raw(args)` escape hatch on the remote function instead — that
25
+ returns the underlying Response untouched.
26
+ */
27
+ export async function decodeResponse(response: Response): Promise<unknown> {
28
+ if (!response.ok) {
29
+ throw new HttpError(response)
30
+ }
31
+ if (response.status === 204) {
32
+ return undefined
33
+ }
34
+ const contentType = (response.headers.get('content-type') ?? '').toLowerCase()
35
+ if (isStreamingResponse(response)) {
36
+ throw new Error(
37
+ `[abide] response at ${response.url} is a stream (${contentType}) — use tail(fn.stream(args)) for a reactive view, or fn.stream(args) for per-call iteration, instead of awaiting the bare call or cache()`,
38
+ )
39
+ }
40
+ if (contentType.includes('json')) {
41
+ return response.json()
42
+ }
43
+ if (contentType.startsWith('text/')) {
44
+ return response.text()
45
+ }
46
+ return response.blob()
47
+ }
@@ -0,0 +1,27 @@
1
+ import type { CompileTarget } from './types/CompileTarget.ts'
2
+
3
+ /*
4
+ Picks the Bun compile target matching the current host. Throws if the
5
+ platform/arch pair isn't one of the supported Bun standalone targets — the
6
+ CLI's `--target` flag is the escape hatch for cross-compilation.
7
+ */
8
+ const HOST_TO_TARGET: Record<string, CompileTarget> = {
9
+ 'darwin-arm64': 'bun-darwin-arm64',
10
+ 'darwin-x64': 'bun-darwin-x64',
11
+ 'linux-arm64': 'bun-linux-arm64',
12
+ 'linux-x64': 'bun-linux-x64',
13
+ 'win32-x64': 'bun-windows-x64',
14
+ }
15
+
16
+ export function detectTarget(
17
+ platform: NodeJS.Platform = process.platform,
18
+ arch: NodeJS.Architecture = process.arch,
19
+ ): CompileTarget {
20
+ const target = HOST_TO_TARGET[`${platform}-${arch}`]
21
+ if (!target) {
22
+ throw new Error(
23
+ `[abide] unsupported host platform ${platform}/${arch}. Pass --target=<bun-...> explicitly.`,
24
+ )
25
+ }
26
+ return target
27
+ }
@@ -0,0 +1,17 @@
1
+ import type { HttpVerb } from './types/HttpVerb.ts'
2
+
3
+ /*
4
+ Reads the HTTP verb of an $rpc module from its source. Every file under
5
+ src/server/rpc/ follows the convention `export const <name> = GET(fn)` (the
6
+ verb helper picks the method, possibly with an explicit generic
7
+ `GET<{…}>(fn)`), so the helper name at the export is the method. Returns
8
+ undefined when no verb export matches — the caller skips the file rather
9
+ than guessing. Used by the rpc.d.ts codegen to type url() against
10
+ query-carrying verbs; matching the same convention the bundler rewrites
11
+ keeps the two from drifting.
12
+ */
13
+ const VERB_EXPORT = /export\s+const\s+\w+\s*=\s*(GET|POST|PUT|PATCH|DELETE|HEAD)\s*[<(]/
14
+
15
+ export function detectVerbMethod(source: string): HttpVerb | undefined {
16
+ return (source.match(VERB_EXPORT)?.[1] as HttpVerb | undefined) ?? undefined
17
+ }
@@ -0,0 +1,190 @@
1
+ import { logTapSlot } from './logTapSlot.ts'
2
+ import { requestScopeSlot } from './requestScopeSlot.ts'
3
+ import type { LogRecord } from './types/LogRecord.ts'
4
+ import type { LogVoice } from './types/LogVoice.ts'
5
+
6
+ const hasBun = typeof Bun !== 'undefined'
7
+ const useColor = hasBun && Bun.enableANSIColors
8
+ const RESET = '\x1b[0m'
9
+ const DIM = '\x1b[2m'
10
+
11
+ // Wraps `text` in a Bun-resolved ANSI color escape; no-op when colors are disabled or unavailable (browser).
12
+ function paint(color: string, text: string): string {
13
+ if (!useColor) {
14
+ return text
15
+ }
16
+ return `${Bun.color(color, 'ansi-256')}${text}${RESET}`
17
+ }
18
+
19
+ // Applies the ANSI dim attribute; no-op when colors are disabled.
20
+ function dim(text: string): string {
21
+ if (!useColor) {
22
+ return text
23
+ }
24
+ return `${DIM}${text}${RESET}`
25
+ }
26
+
27
+ // Maps an HTTP status code to a color that matches the usual server-log convention.
28
+ function colorStatus(status: number): string {
29
+ if (status >= 500) {
30
+ return paint('red', String(status))
31
+ }
32
+ if (status >= 400) {
33
+ return paint('yellow', String(status))
34
+ }
35
+ if (status >= 300) {
36
+ return paint('cyan', String(status))
37
+ }
38
+ return paint('green', String(status))
39
+ }
40
+
41
+ // Maps an HTTP method to a color so the request log line is easy to scan.
42
+ function colorMethod(method: string): string {
43
+ const upper = method.toUpperCase()
44
+ if (upper === 'GET') {
45
+ return paint('green', upper)
46
+ }
47
+ if (upper === 'POST') {
48
+ return paint('blue', upper)
49
+ }
50
+ if (upper === 'PUT' || upper === 'PATCH') {
51
+ return paint('yellow', upper)
52
+ }
53
+ if (upper === 'DELETE') {
54
+ return paint('red', upper)
55
+ }
56
+ return paint('white', upper)
57
+ }
58
+
59
+ /* json emission is a server concern (stdout ingestion); the browser console always gets tsv. Read per call — log volume never makes this hot. */
60
+ function useJson(): boolean {
61
+ return typeof process !== 'undefined' && process.env.ABIDE_LOG_FORMAT === 'json'
62
+ }
63
+
64
+ /* `+12.30ms` — unpadded: the timing trails the line, so no width keeps columns aligned. */
65
+ function formatElapsed(ms: number): string {
66
+ return `+${ms.toFixed(2)}ms`
67
+ }
68
+
69
+ /*
70
+ Builds the record from the emission's own fields plus the ambient request
71
+ scope (trace, elapsed, verb+path), then renders it through the active
72
+ formatter. The scope is read at emission time so a record emitted from a
73
+ stream-flush callback re-entered into the scope still carries its context.
74
+ Internal seam shared by the public logger and the framework's closing-record
75
+ emitter; console.* is the side effect — logging is intentionally impure.
76
+ */
77
+ export function emitLogRecord(fields: Omit<LogRecord, 'ts'>, voice?: LogVoice): void {
78
+ const scope = requestScopeSlot.resolver?.()
79
+ const record: LogRecord = { ts: Date.now(), ...fields }
80
+ if (scope) {
81
+ record.trace = scope.trace.traceId
82
+ record.requestSpan = scope.trace.spanId
83
+ record.parentSpan = scope.trace.parentSpanId
84
+ record.elapsedMs = scope.elapsedMs
85
+ record.method = fields.method ?? scope.method
86
+ record.path = fields.path ?? scope.path
87
+ }
88
+ // Hand the finished record to the inspector tap (when installed) before
89
+ // formatting — it observes the same structure the console receives.
90
+ logTapSlot.tap?.(record)
91
+ if (useJson()) {
92
+ printJson(record)
93
+ return
94
+ }
95
+ printTsv(record, voice)
96
+ }
97
+
98
+ /*
99
+ One JSON object per line on the level-matched console stream. Undefined
100
+ fields drop out of JSON.stringify; non-serialisable `data` degrades to its
101
+ String form rather than killing the record.
102
+ */
103
+ function printJson(record: LogRecord): void {
104
+ const payload = { ...record, ts: new Date(record.ts).toISOString() }
105
+ let line: string
106
+ try {
107
+ line = JSON.stringify(payload)
108
+ } catch {
109
+ line = JSON.stringify({ ...payload, data: String(record.data) })
110
+ }
111
+ consoleFor(record.level)(line)
112
+ }
113
+
114
+ function consoleFor(level: LogRecord['level']): (...args: unknown[]) => void {
115
+ if (level === 'error') {
116
+ return console.error
117
+ }
118
+ if (level === 'warn') {
119
+ return console.warn
120
+ }
121
+ return console.log
122
+ }
123
+
124
+ /*
125
+ The unified tsv line (the default format): tab-separated
126
+ `<trace8> <verb path> [channel] <message> +0.00ms`. Inside a
127
+ request scope the trace column leads and the elapsed-at-emission timing
128
+ trails; a closing record emitted outside one (asset hits sidestep the scope)
129
+ pads a blank trace column and trails its serve duration instead, so request
130
+ lines stay aligned whatever produced them. Every record speaks on a channel
131
+ (the app name, 'abide', or a diagnostic channel), shown as a dim `[name]`
132
+ tag opening the message field. The verb+path pair is one field — it's the
133
+ line's anchor unit — and the tag folds into the message field so field
134
+ positions stay stable for cut/awk consumers.
135
+ */
136
+ function printTsv(record: LogRecord, voice?: LogVoice): void {
137
+ const fields: string[] = []
138
+ const closing = record.status !== undefined
139
+ if (record.trace) {
140
+ fields.push(dim(record.trace.slice(0, 8)))
141
+ } else if (closing) {
142
+ fields.push(' '.repeat(8))
143
+ }
144
+ if (record.method && record.path) {
145
+ fields.push(`${colorMethod(record.method)} ${record.path}`)
146
+ }
147
+ const message: string[] = []
148
+ if (record.channel) {
149
+ message.push(dim(`[${record.channel}]`))
150
+ }
151
+ message.push(tsvBody(record, voice))
152
+ fields.push(message.join(' '))
153
+ if (record.elapsedMs !== undefined) {
154
+ fields.push(dim(formatElapsed(record.elapsedMs)))
155
+ } else if (closing && record.durationMs !== undefined) {
156
+ fields.push(dim(formatElapsed(record.durationMs)))
157
+ }
158
+ const writer = consoleFor(record.level)
159
+ if (record.data !== undefined) {
160
+ writer(fields.join('\t'), record.data)
161
+ return
162
+ }
163
+ writer(fields.join('\t'))
164
+ }
165
+
166
+ // The message field after the context fields, styled by level/kind/voice.
167
+ function tsvBody(record: LogRecord, voice?: LogVoice): string {
168
+ /* Closing request record: status is the message; the duration rides the elapsed column. */
169
+ if (record.status !== undefined) {
170
+ return colorStatus(record.status)
171
+ }
172
+ /* log.trace operation record: name + settled duration. */
173
+ if (record.name !== undefined && record.durationMs !== undefined) {
174
+ const failure = record.level === 'error' ? ` ${paint('red', record.msg)}` : ''
175
+ return `${record.name} ${dim(`${record.durationMs.toFixed(2)}ms`)}${failure}`
176
+ }
177
+ if (record.level === 'error') {
178
+ return paint('red', record.stack ?? record.msg)
179
+ }
180
+ if (record.level === 'warn') {
181
+ return paint('yellow', record.msg)
182
+ }
183
+ if (voice === 'success') {
184
+ return paint('green', record.msg)
185
+ }
186
+ if (voice === 'detail') {
187
+ return dim(record.msg)
188
+ }
189
+ return record.msg
190
+ }
@@ -0,0 +1,9 @@
1
+ import type { CompileTarget } from './types/CompileTarget.ts'
2
+
3
+ /*
4
+ Executable filename suffix for a compile target — `.exe` on Windows targets,
5
+ empty elsewhere. Single source so every cross-compile output path agrees.
6
+ */
7
+ export function exeSuffix(target: CompileTarget): string {
8
+ return target.includes('windows') ? '.exe' : ''
9
+ }
@@ -0,0 +1,17 @@
1
+ import type { BuildOutput } from 'bun'
2
+ import { abideLog } from './abideLog.ts'
3
+
4
+ /*
5
+ On a failed Bun.build(), logs each diagnostic and exits non-zero. Every abide
6
+ build entrypoint (build / compile / buildCli / bundleApp) funnels its result
7
+ through here so failure reporting can't drift between them.
8
+ */
9
+ export function exitOnBuildFailure(result: BuildOutput): void {
10
+ if (result.success) {
11
+ return
12
+ }
13
+ result.logs.forEach((entry) => {
14
+ abideLog.error(entry)
15
+ })
16
+ process.exit(1)
17
+ }
@@ -0,0 +1,16 @@
1
+ /*
2
+ App-configured inbound header names to forward onto in-process rpc Requests,
3
+ on top of the built-in FORWARDED_HEADERS. Set once at boot from
4
+ app.forwardHeaders so the SSR in-process path (defineVerb) and the MCP
5
+ dispatcher honour the same list without re-reading app config per call. A
6
+ module-level slot rather than threaded config because both call sites are deep
7
+ in the request path and the value is fixed for the process lifetime.
8
+ */
9
+ let names: readonly string[] = []
10
+
11
+ export const extraForwardHeaders = {
12
+ get: (): readonly string[] => names,
13
+ set: (configured: readonly string[]): void => {
14
+ names = configured
15
+ },
16
+ }
@@ -0,0 +1,9 @@
1
+ /*
2
+ The bare filename of a path, with directory and trailing extension stripped —
3
+ e.g. `users/list.ts` → `list`, `/_virtual/mcp-resources.ts` → `mcp-resources`.
4
+ Used to derive a virtual-module name from its path and to check an $rpc /
5
+ $sockets module's single export name against its file stem.
6
+ */
7
+ export function fileStem(path: string): string {
8
+ return (path.split('/').pop() ?? '').replace(/\.[^.]+$/, '')
9
+ }