@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,151 @@
1
+ // @ts-expect-error virtual module resolved by abideResolverPlugin
2
+ import { disconnectedHtml } from './_virtual/bundle-disconnected.ts'
3
+ // @ts-expect-error virtual module resolved by abideResolverPlugin
4
+ import bundleWindow from './_virtual/bundle-window.ts'
5
+ // @ts-expect-error virtual module resolved by abideResolverPlugin
6
+ import programName from './_virtual/cli-name.ts'
7
+ import type { BundleMenu } from './lib/bundle/BundleMenu.ts'
8
+ import type { BundleWindow } from './lib/bundle/BundleWindow.ts'
9
+ import { openWebview } from './lib/bundle/openWebview.ts'
10
+ import { envSchemaStore } from './lib/server/runtime/envSchemaStore.ts'
11
+ import { abideLog } from './lib/shared/abideLog.ts'
12
+ import { jsonSchemaForSchema } from './lib/shared/jsonSchemaForSchema.ts'
13
+
14
+ /*
15
+ Compiled bundle launcher entry — the executable a bundle runs. Instead of a blank
16
+ window it boots into a connect screen, letting the user either connect to a remote
17
+ server by URL or start the embedded server binary that ships beside this launcher.
18
+
19
+ The connect screen is served by a tiny control server, but that server can't live
20
+ on this main thread: `openWebview` calls `webview_run`, a native UI loop that
21
+ blocks the thread (and its JS event loop) until the window closes, so an
22
+ in-process `Bun.serve` would never answer. The control server runs in a Worker
23
+ instead (see controlServerWorker.ts) and hands back the origin to point the window
24
+ at; it also owns the embedded-server child and the native menu flag, since neither
25
+ can be driven from a main thread frozen inside webview_run.
26
+
27
+ Bun doesn't apply this build's plugins to the worker entry, so the worker can't
28
+ import abide's virtual modules; this entry imports them (the connect-screen HTML,
29
+ the app title) and passes them in the worker's `init` message.
30
+
31
+ The window owns the main thread; on close we tell the worker to reap its child.
32
+ */
33
+ const window = bundleWindow as BundleWindow
34
+ const title = window.title ?? programName
35
+
36
+ /*
37
+ Derive the config form's JSON Schema here (the worker can't import the virtuals
38
+ that carry the schema) and pass the plain object through init — the validator
39
+ itself isn't serializable, but its JSON Schema is. Undefined when the app
40
+ declares no config, so the connect screen never gates Start.
41
+
42
+ Default source is src/server/config.ts's env schema, so one declaration drives
43
+ both boot validation and the setup form. Imported with skipValidation set — we
44
+ want the schema's shape, not a boot check the launcher has no business running.
45
+ `window.config` replaces it when set, for a bundle form that should differ from
46
+ the env schema.
47
+ */
48
+ envSchemaStore.skipValidation = true
49
+ // @ts-expect-error virtual module resolved by abideResolverPlugin
50
+ await import('./_virtual/config.ts')
51
+ const formSchema = window.config ?? envSchemaStore.schema
52
+ const configSchema = formSchema ? jsonSchemaForSchema(formSchema) : undefined
53
+
54
+ /*
55
+ Spawn the control server worker. `__ABIDE_WORKER_ENTRY__` is the worker's absolute
56
+ path, injected by bundleApp via Bun's `define` so the specifier is a static literal
57
+ at build time — that's what makes `bun build --compile` embed the worker module
58
+ into the standalone binary. A relative specifier resolves against the build's cwd
59
+ (the consumer project), not this file, so it isn't found; a
60
+ `new URL(..., import.meta.url)` specifier isn't embedded at all.
61
+ */
62
+ declare const __ABIDE_WORKER_ENTRY__: string
63
+ const worker = new Worker(__ABIDE_WORKER_ENTRY__)
64
+
65
+ worker.addEventListener('error', (event: ErrorEvent) => {
66
+ abideLog.error(`control server worker failed: ${event.message}`)
67
+ })
68
+
69
+ // Hand the worker the plugin-resolved data it can't import itself, then start it.
70
+ worker.postMessage({
71
+ type: 'init',
72
+ init: { disconnectedHtml: disconnectedHtml as string, title, programName, configSchema },
73
+ })
74
+
75
+ /*
76
+ The worker, once bound, resolves where the window should open and posts both the
77
+ control-server `origin` (for the File-menu action URLs) and the `target` to point
78
+ the window at now: the live server when it could resume the last connection, else
79
+ the connect screen. Resolving before this means a successful resume opens straight
80
+ at the app — no connect-screen flash — at the cost of a brief window-less moment
81
+ while it boots/probes (the OS shows the launching dock icon meanwhile).
82
+ */
83
+ const { origin, target } = await new Promise<{ origin: string; target: string }>((resolve) => {
84
+ worker.addEventListener('message', (event: MessageEvent) => {
85
+ const data = event.data as { type: string; origin?: string; target?: string }
86
+ if (data.type === 'ready' && data.origin && data.target) {
87
+ resolve({ origin: data.origin, target: data.target })
88
+ }
89
+ })
90
+ })
91
+
92
+ /*
93
+ The built-in File menu (Start / Disconnect), placed before Edit. Each item is a
94
+ `navigate` repointing the window at a control-server URL the connect screen
95
+ interprets; the internal `role` drives the native validateMenuItem: gating (Start
96
+ when disconnected, Disconnect when connected). There's no Connect item — Disconnect
97
+ already returns to the connect screen, whose form is the place to point at another
98
+ server. Roled items are launcher-only, so they carry an extra field the public
99
+ BundleMenuItem type doesn't advertise — modelled here with a local type and bridged
100
+ to BundleMenu when handed to openWebview (which only serialises the menu to JSON).
101
+ */
102
+ type FileMenuItem =
103
+ | { separator: true }
104
+ | {
105
+ label: string
106
+ shortcut?: string
107
+ navigate: string
108
+ role: 'start' | 'disconnect'
109
+ }
110
+ const fileMenu: { label: string; items: FileMenuItem[] } = {
111
+ label: 'File',
112
+ items: [
113
+ { label: 'Start Server', navigate: `${origin}/?action=start`, role: 'start' },
114
+ { separator: true },
115
+ { label: 'Disconnect', navigate: `${origin}/?action=disconnect`, role: 'disconnect' },
116
+ ],
117
+ }
118
+
119
+ abideLog.info(`opening ${title} window at ${target}`)
120
+ await openWebview({
121
+ url: target,
122
+ title,
123
+ width: window.width,
124
+ height: window.height,
125
+ menu: window.menu,
126
+ fileMenu: fileMenu as unknown as BundleMenu,
127
+ // Forward the window handle so the worker can bounce it back to the connect
128
+ // screen if the connected server stops responding.
129
+ onWindow: (handle) => {
130
+ if (handle) {
131
+ worker.postMessage({ type: 'window', handle: Number(handle) })
132
+ }
133
+ },
134
+ })
135
+
136
+ /*
137
+ Window closed — have the worker reap the embedded server child and stop its
138
+ control server before we exit, since both live on the worker thread. Bounded by a
139
+ timeout so a wedged worker can't keep the launcher alive.
140
+ */
141
+ await new Promise<void>((resolve) => {
142
+ worker.addEventListener('message', (event: MessageEvent) => {
143
+ if ((event.data as { type?: string }).type === 'shutdownDone') {
144
+ resolve()
145
+ }
146
+ })
147
+ worker.postMessage({ type: 'shutdown' })
148
+ setTimeout(resolve, 1000)
149
+ })
150
+ worker.terminate()
151
+ process.exit(0)
@@ -0,0 +1,12 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <!--ssr:head-->
7
+ </head>
8
+ <body>
9
+ <div id="app"><!--ssr:body--></div>
10
+ <!--ssr:state-->
11
+ </body>
12
+ </html>
package/src/build.ts ADDED
@@ -0,0 +1,143 @@
1
+ import { clientBuildPlugins } from './clientBuildPlugins.ts'
2
+ import { abideLog } from './lib/shared/abideLog.ts'
3
+ import { exitOnBuildFailure } from './lib/shared/exitOnBuildFailure.ts'
4
+
5
+ const CLIENT_ENTRY = new URL('./clientEntry.ts', import.meta.url).pathname
6
+
7
+ /*
8
+ Builds the client-side bundle into `${cwd}/dist/_app`. Runs Bun.build with
9
+ the abide-ui `.abide` loader, the virtual-module resolver, and (optionally)
10
+ Tailwind. When `compress`, each emitted file is also
11
+ written as a gzip-compressed `.gz` sibling (level 9 — paid once at build
12
+ time) so the server can stream the precompressed bytes directly to any client
13
+ that accepts gzip (effectively all), and decompress on the fly otherwise. Dev
14
+ skips compression (compressing on every rebuild dwarfs the bundle itself) — the
15
+ server falls back to serving the plain bytes when no `.gz` sibling exists.
16
+
17
+ The bundle is emitted into a per-build staging dir, then swapped into
18
+ `_app` with two atomic renames. This keeps every build's writes isolated to
19
+ a unique path (so a stray concurrent build can never `rm` files Bun is
20
+ mid-flushing — the "writing sourcemap: No such file or directory" race) and
21
+ means a long-running dev server reading `_app` lazily off disk never sees a
22
+ half-built or emptied directory.
23
+
24
+ `clean` (one-shot builds) clears the whole dist up front so downstream
25
+ writers — the bundle's connect screen, the CLI manifest — start fresh; the
26
+ dev orchestrator passes `clean: false` to leave the live dist untouched and
27
+ only swap `_app` at the end.
28
+
29
+ Returns whether the build succeeded. Never throws: a thrown Bun.build / fs
30
+ error is logged and treated as a failed build, so the dev loop (and its
31
+ last-good server) survives instead of crashing and orphaning the child. By
32
+ default a failure exits the process (one-shot `abide build` / `compile`);
33
+ the dev orchestrator passes `exitOnFailure: false`.
34
+ */
35
+ // @readme plumbing
36
+ export async function build({
37
+ cwd = process.cwd(),
38
+ minify = true,
39
+ compress = true,
40
+ clean = true,
41
+ exitOnFailure = true,
42
+ }: {
43
+ cwd?: string
44
+ minify?: boolean
45
+ compress?: boolean
46
+ clean?: boolean
47
+ exitOnFailure?: boolean
48
+ } = {}): Promise<boolean> {
49
+ const distDir = `${cwd}/dist`
50
+ const outDir = `${distDir}/_app`
51
+ // Per-build staging + holding dirs; the suffix isolates concurrent builds.
52
+ const buildId = crypto.randomUUID().slice(0, 8)
53
+ const stagingDir = `${distDir}/_app.staging-${buildId}`
54
+ const previousDir = `${distDir}/_app.old-${buildId}`
55
+
56
+ const fail = (): boolean => {
57
+ if (exitOnFailure) {
58
+ process.exit(1)
59
+ }
60
+ return false
61
+ }
62
+
63
+ try {
64
+ // shell-rm/-mv are the impure boundary for the dist swap — Bun.$ is first-party.
65
+ if (clean) {
66
+ await Bun.$`rm -rf ${distDir}`.quiet()
67
+ }
68
+
69
+ const plugins = await clientBuildPlugins({
70
+ cwd,
71
+ tailwindWarning: 'bun-plugin-tailwind not installed; building without Tailwind',
72
+ })
73
+
74
+ const result = await Bun.build({
75
+ entrypoints: [CLIENT_ENTRY],
76
+ outdir: stagingDir,
77
+ target: 'browser',
78
+ splitting: true,
79
+ minify,
80
+ sourcemap: 'linked',
81
+ naming: {
82
+ entry: 'client-[hash].[ext]',
83
+ chunk: '[name]-[hash].[ext]',
84
+ asset: '[name].[ext]',
85
+ },
86
+ plugins,
87
+ })
88
+
89
+ if (!result.success) {
90
+ await Bun.$`rm -rf ${stagingDir}`.quiet().nothrow()
91
+ if (exitOnFailure) {
92
+ exitOnBuildFailure(result)
93
+ }
94
+ result.logs.forEach((entry) => {
95
+ abideLog.error(entry)
96
+ })
97
+ return false
98
+ }
99
+
100
+ // Dev skips the gzip siblings (paths still point into stagingDir here).
101
+ const compressedBytes = compress
102
+ ? (
103
+ await Promise.all(
104
+ result.outputs.map(async (output) => {
105
+ const bytes = await Bun.file(output.path).bytes()
106
+ const compressed = Bun.gzipSync(bytes, { level: 9 })
107
+ await Bun.write(`${output.path}.gz`, compressed)
108
+ return compressed.byteLength
109
+ }),
110
+ )
111
+ ).reduce((total, length) => total + length, 0)
112
+ : 0
113
+
114
+ /*
115
+ Swap staging into _app with two renames: move any existing _app aside,
116
+ then rename staging into place. The window where _app is absent is a
117
+ single rename, so a reader (the running dev server) never observes a
118
+ partial bundle. nothrow on the first move: no _app exists on the first
119
+ build or after `clean`.
120
+ */
121
+ await Bun.$`mv ${outDir} ${previousDir}`.quiet().nothrow()
122
+ await Bun.$`mv ${stagingDir} ${outDir}`.quiet()
123
+ await Bun.$`rm -rf ${previousDir}`.quiet().nothrow()
124
+
125
+ if (compress) {
126
+ abideLog.info(
127
+ `wrote ${result.outputs.length} files to ${outDir} (+${result.outputs.length} .gz, ${(compressedBytes / 1024).toFixed(1)} KiB total)`,
128
+ )
129
+ // Per-file paths are noise at startup; surface them only under DEBUG=abide:build.
130
+ const buildLog = abideLog.channel('abide:build')
131
+ result.outputs.forEach((output) => {
132
+ buildLog(` - ${output.path.replace(stagingDir, outDir)}`)
133
+ })
134
+ } else {
135
+ abideLog.info(`wrote ${result.outputs.length} files to ${outDir}`)
136
+ }
137
+ return true
138
+ } catch (error) {
139
+ abideLog.error(error)
140
+ await Bun.$`rm -rf ${stagingDir} ${previousDir}`.quiet().nothrow()
141
+ return fail()
142
+ }
143
+ }
@@ -0,0 +1,127 @@
1
+ import { dirname, join } from 'node:path'
2
+ import { build } from './build.ts'
3
+ import { compile } from './compile.ts'
4
+ import { abideLog } from './lib/shared/abideLog.ts'
5
+ import { detectTarget } from './lib/shared/detectTarget.ts'
6
+ import { exeSuffix } from './lib/shared/exeSuffix.ts'
7
+ import { exitOnBuildFailure } from './lib/shared/exitOnBuildFailure.ts'
8
+ import { programNameForPackage } from './lib/shared/programNameForPackage.ts'
9
+ import { readPackageJson } from './lib/shared/readPackageJson.ts'
10
+ import type { CompileTarget } from './lib/shared/types/CompileTarget.ts'
11
+ import { serverBuildPlugins } from './serverBuildPlugins.ts'
12
+
13
+ const DISCOVERY_ENTRY = new URL('./discoveryEntry.ts', import.meta.url).pathname
14
+ const CLI_ENTRY = new URL('./cliEntry.ts', import.meta.url).pathname
15
+
16
+ /*
17
+ CLI binary build. The CLI is a thin remote client — it bakes in the per-rpc
18
+ manifest and talks to a running server over HTTP — but the **full** binary ships
19
+ the compiled server beside it, so `/start` can spawn a local instance.
20
+
21
+ 1. Client build (once): `build` produces the platform-independent `dist/_app`
22
+ the server binaries embed. It clears dist first, so it runs before everything.
23
+ 2. Discovery: build the discovery entry into a temporary JS bundle and run it. It
24
+ imports every rpc/socket module so defineVerb / defineSocket populate the
25
+ registries, then prints the CLI manifest to stdout → `dist/cli-manifest.json`.
26
+ 3. Per target: a server binary (`compile`, reusing the shared `dist/_app` via
27
+ `buildClient:false`) plus the CLI binary, written side by side. The resolver's
28
+ `abide:cli-manifest` virtual splices in the manifest from step 2.
29
+
30
+ `platforms` cross-compiles per target into `dist/cli-thin/<platform>/` (the layout
31
+ the /__abide/cli download endpoint serves): `<programName>` + `server` together.
32
+ */
33
+ export async function buildCli({
34
+ cwd = process.cwd(),
35
+ target = detectTarget(),
36
+ outfile,
37
+ platforms,
38
+ }: {
39
+ cwd?: string
40
+ target?: CompileTarget
41
+ outfile?: string
42
+ platforms?: CompileTarget[]
43
+ } = {}): Promise<string[]> {
44
+ const distDir = `${cwd}/dist`
45
+ const manifestPath = `${distDir}/cli-manifest.json`
46
+ const discoveryOut = `${distDir}/_discovery.js`
47
+
48
+ const plugins = serverBuildPlugins({ cwd })
49
+
50
+ // Step 1 — client build once (clears dist, writes _app). Every server binary
51
+ // embeds it, so it must precede discovery and the per-target compiles.
52
+ await build({ cwd })
53
+
54
+ /*
55
+ Step 2 — discovery. Build a runnable bundle, execute it under bun, capture
56
+ stdout. We don't `bun build --compile` here because the discovery output is
57
+ throwaway; a plain JS bundle runs faster. Additive — does not clear dist.
58
+ */
59
+ const discoveryResult = await Bun.build({
60
+ entrypoints: [DISCOVERY_ENTRY],
61
+ target: 'bun',
62
+ outdir: distDir,
63
+ naming: '_discovery.js',
64
+ plugins,
65
+ })
66
+ exitOnBuildFailure(discoveryResult)
67
+
68
+ const proc = Bun.spawn({
69
+ cmd: ['bun', discoveryOut],
70
+ cwd,
71
+ stdio: ['ignore', 'pipe', 'pipe'],
72
+ })
73
+ const [stdout, stderr, exitCode] = await Promise.all([
74
+ new Response(proc.stdout).text(),
75
+ new Response(proc.stderr).text(),
76
+ proc.exited,
77
+ ])
78
+ if (exitCode !== 0) {
79
+ abideLog.error(`discovery exited ${exitCode}:\n${stderr}`)
80
+ process.exit(1)
81
+ }
82
+ await Bun.write(manifestPath, stdout)
83
+ await Bun.$`rm -f ${discoveryOut}`.quiet()
84
+ const entryCount = Object.keys(JSON.parse(stdout) as Record<string, unknown>).length
85
+ abideLog.info(`discovered ${entryCount} cli commands → ${manifestPath}`)
86
+
87
+ const programName = await readProgramName(cwd)
88
+
89
+ /*
90
+ Step 3 — compile a CLI binary + sibling server binary for a single target,
91
+ written side by side so `resolveServerBinary()` finds the server next to the
92
+ running CLI. The server reuses the shared client build (buildClient:false).
93
+ */
94
+ async function buildTargetPair(platformTarget: CompileTarget, cliOut: string): Promise<string> {
95
+ const serverOut = join(dirname(cliOut), `server${exeSuffix(platformTarget)}`)
96
+ await compile({ cwd, target: platformTarget, outfile: serverOut, buildClient: false })
97
+ const result = await Bun.build({
98
+ entrypoints: [CLI_ENTRY],
99
+ target: 'bun',
100
+ compile: { target: platformTarget, outfile: cliOut },
101
+ plugins,
102
+ })
103
+ exitOnBuildFailure(result)
104
+ abideLog.success(`compiled cli + server: ${cliOut}`)
105
+ return cliOut
106
+ }
107
+
108
+ if (platforms && platforms.length > 0) {
109
+ // Cross-compile every target in parallel — each pair is independent.
110
+ return Promise.all(
111
+ platforms.map(async (platformTarget) => {
112
+ const shortName = platformTarget.replace(/^bun-/, '')
113
+ const cliOut = `${distDir}/cli-thin/${shortName}/${programName}${exeSuffix(platformTarget)}`
114
+ await Bun.$`mkdir -p ${`${distDir}/cli-thin/${shortName}`}`.quiet()
115
+ return buildTargetPair(platformTarget, cliOut)
116
+ }),
117
+ )
118
+ }
119
+
120
+ const cliOut = outfile ?? `${distDir}/cli${exeSuffix(target)}`
121
+ return [await buildTargetPair(target, cliOut)]
122
+ }
123
+
124
+ async function readProgramName(cwd: string): Promise<string> {
125
+ const pkg = (await readPackageJson(cwd)) as { name?: string } | undefined
126
+ return programNameForPackage(pkg?.name)
127
+ }
@@ -0,0 +1,118 @@
1
+ import { clientBuildPlugins } from './clientBuildPlugins.ts'
2
+ import { abideLog } from './lib/shared/abideLog.ts'
3
+ import { exitOnBuildFailure } from './lib/shared/exitOnBuildFailure.ts'
4
+
5
+ const ENTRY = new URL('./bundleDisconnectedEntry.ts', import.meta.url).pathname
6
+ const CSS_ENTRY = new URL('./lib/bundle/disconnected.css', import.meta.url).pathname
7
+
8
+ /*
9
+ Default screen logo: a minimal inline-SVG abide mark, used when the project ships
10
+ no src/bundle/logo.png. Inline SVG keeps the bundle self-contained with no asset
11
+ file to vendor; a project overrides it just by adding the PNG.
12
+ */
13
+ const DEFAULT_LOGO = `data:image/svg+xml,${encodeURIComponent(
14
+ '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">' +
15
+ '<rect width="64" height="64" rx="16" fill="#111827"/>' +
16
+ '<text x="32" y="45" font-family="system-ui,sans-serif" font-size="38" ' +
17
+ 'font-weight="700" fill="#fff" text-anchor="middle">b</text></svg>',
18
+ )}`
19
+
20
+ /*
21
+ Builds the bundle connect screen into a single self-contained HTML string and
22
+ writes it to `dist/bundle-disconnected.html`, which the launcher bakes in via the
23
+ `abide:bundle-disconnected` virtual. The client bundle (abide-ui component +
24
+ injected CSS + compiled Tailwind) is inlined into the page so the launcher serves
25
+ it with zero external requests; the logo is embedded as a data URI. The app title
26
+ (`window.__ABIDE_TITLE__`) is injected by the launcher at serve time, so a
27
+ `<!--abide:connect-config-->` marker is left in <head> for it.
28
+
29
+ Must run after the client build has cleared and repopulated dist (it writes a
30
+ file into dist), and before the launcher build that reads it. Uses no outdir of
31
+ its own — Bun.build artifacts are read from memory — so it never touches dist
32
+ beyond the one file it writes.
33
+ */
34
+ export async function buildDisconnected({
35
+ cwd = process.cwd(),
36
+ }: {
37
+ cwd?: string
38
+ } = {}): Promise<string> {
39
+ const plugins = await clientBuildPlugins({
40
+ cwd,
41
+ tailwindWarning:
42
+ 'bun-plugin-tailwind not installed; building connect screen without Tailwind',
43
+ })
44
+
45
+ /*
46
+ The Tailwind CSS rides as its own entrypoint rather than a `.css` import from
47
+ the entry (which TS can't type), so it compiles to a standalone artifact we
48
+ inline alongside the JS — the component carries no <style> of its own.
49
+ */
50
+ const result = await Bun.build({
51
+ entrypoints: [ENTRY, CSS_ENTRY],
52
+ target: 'browser',
53
+ minify: true,
54
+ plugins,
55
+ })
56
+ exitOnBuildFailure(result)
57
+
58
+ // Collect the JS bundle + extracted CSS from the in-memory artifacts.
59
+ let js = ''
60
+ let css = ''
61
+ for (const output of result.outputs) {
62
+ const text = await output.text()
63
+ if (output.path.endsWith('.css')) {
64
+ css += text
65
+ } else if (output.path.endsWith('.js')) {
66
+ js += text
67
+ }
68
+ }
69
+
70
+ const logo = await readLogo(cwd)
71
+ const html = composeHtml({ js, css, logo })
72
+ const outPath = `${cwd}/dist/bundle-disconnected.html`
73
+ await Bun.write(outPath, html)
74
+ abideLog.success(`built connect screen: ${outPath} (${(html.length / 1024).toFixed(1)} KiB)`)
75
+ return outPath
76
+ }
77
+
78
+ // Reads the project's src/bundle/logo.png as a data URI, or the default mark.
79
+ async function readLogo(cwd: string): Promise<string> {
80
+ const userLogo = Bun.file(`${cwd}/src/bundle/logo.png`)
81
+ if (await userLogo.exists()) {
82
+ const bytes = await userLogo.bytes()
83
+ return `data:image/png;base64,${bytes.toBase64()}`
84
+ }
85
+ return DEFAULT_LOGO
86
+ }
87
+
88
+ /*
89
+ Escapes a closing `</script>` so an inline `<script>` body can't be terminated
90
+ early by content in the bundle (rare, but a `</script>` substring would break the
91
+ page). The browser still parses `<\/script>` as the intended characters.
92
+ */
93
+ function escapeScriptBody(value: string): string {
94
+ return value.replace(/<\/(script)/gi, '<\\/$1')
95
+ }
96
+
97
+ // Assembles the final standalone HTML document from the inlined pieces.
98
+ function composeHtml({ js, css, logo }: { js: string; css: string; logo: string }): string {
99
+ const logoScript = `window.__ABIDE_LOGO__=${JSON.stringify(logo)}`
100
+ return `<!doctype html>
101
+ <html lang="en">
102
+ <head>
103
+ <meta charset="UTF-8" />
104
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
105
+ <!--abide:connect-config-->
106
+ <script>${escapeScriptBody(logoScript)}</script>
107
+ <!-- Paint the screen background before the client mounts, so there's no white
108
+ flash ahead of the splash (gray-50 / gray-950 to match the rendered screen). -->
109
+ <style>html,body{margin:0;background:#f9fafb}@media (prefers-color-scheme:dark){html,body{background:#030712}}</style>
110
+ <style>${css}</style>
111
+ </head>
112
+ <body>
113
+ <div id="app"></div>
114
+ <script type="module">${escapeScriptBody(js)}</script>
115
+ </body>
116
+ </html>
117
+ `
118
+ }