@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,58 @@
1
+ import { OWNER } from './OWNER.ts'
2
+ import { REACTIVE_CONTEXT } from './REACTIVE_CONTEXT.ts'
3
+ import { runNode } from './runNode.ts'
4
+ import { toTeardown } from './toTeardown.ts'
5
+ import type { EffectResult } from './types/EffectResult.ts'
6
+ import type { ReactiveNode } from './types/ReactiveNode.ts'
7
+ import type { Teardown } from './types/Teardown.ts'
8
+ import { unlinkDeps } from './unlinkDeps.ts'
9
+
10
+ /*
11
+ Creates an effect: a side-effecting node that runs once immediately (capturing
12
+ its dependencies) and again whenever any of them change. The body may return a
13
+ teardown — run before each re-run and on dispose — and may be async (its teardown
14
+ then runs once the promise settles, never awaited). Returns a dispose that runs
15
+ the final teardown and unlinks the node from the graph, so a torn-down effect
16
+ leaves no back-links and no live resource — the open-on-first-read /
17
+ close-on-last-reader lifecycle. When created inside a `scope()` build, the
18
+ disposer is also registered with the owner so the whole component tears down
19
+ together.
20
+ */
21
+ export function createEffectNode(fn: () => EffectResult): () => void {
22
+ /* The body's teardown, replaced each run. Held in this closure rather than on
23
+ ReactiveNode so signals and computeds — which share the node shape and the
24
+ read/write hot path — pay nothing for a feature only effects use. */
25
+ let cleanup: Teardown | undefined
26
+ /* Runs the previous run's teardown before re-running and on dispose, exactly
27
+ once each. */
28
+ const runCleanup = (): void => {
29
+ if (cleanup !== undefined) {
30
+ const teardown = cleanup
31
+ cleanup = undefined
32
+ teardown()
33
+ }
34
+ }
35
+ const node: ReactiveNode = {
36
+ value: undefined,
37
+ compute: () => {
38
+ runCleanup()
39
+ cleanup = toTeardown(fn())
40
+ },
41
+ depsHead: undefined,
42
+ depsTail: undefined,
43
+ subsHead: undefined,
44
+ subsTail: undefined,
45
+ dirty: false,
46
+ isEffect: true,
47
+ }
48
+ runNode(node)
49
+ const dispose = () => {
50
+ runCleanup()
51
+ unlinkDeps(node)
52
+ REACTIVE_CONTEXT.pendingEffects.delete(node)
53
+ }
54
+ if (OWNER.current !== undefined) {
55
+ OWNER.current.push(dispose)
56
+ }
57
+ return dispose
58
+ }
@@ -0,0 +1,16 @@
1
+ import type { ReactiveNode } from './types/ReactiveNode.ts'
2
+
3
+ /* Creates a writable leaf node holding `value` with no compute — the source a
4
+ document path or a `state()` cell is backed by. */
5
+ export function createSignalNode(value: unknown): ReactiveNode {
6
+ return {
7
+ value,
8
+ compute: undefined,
9
+ depsHead: undefined,
10
+ depsTail: undefined,
11
+ subsHead: undefined,
12
+ subsTail: undefined,
13
+ dirty: false,
14
+ isEffect: false,
15
+ }
16
+ }
@@ -0,0 +1,21 @@
1
+ import type { ReactiveLink } from './types/ReactiveLink.ts'
2
+
3
+ /*
4
+ Removes an edge from its source's subscriber list — the `*Sub` splice of an O(1)
5
+ unlink. Used when a recompute drops a dependency it no longer reads (`runNode`'s
6
+ trim) and when a node tears down entirely (`unlinkDeps`). Leaves the edge's `*Dep`
7
+ pointers alone; the caller owns the observer-side list it is walking.
8
+ */
9
+ export function detachLink(link: ReactiveLink): void {
10
+ const { dep, prevSub, nextSub } = link
11
+ if (prevSub !== undefined) {
12
+ prevSub.nextSub = nextSub
13
+ } else {
14
+ dep.subsHead = nextSub
15
+ }
16
+ if (nextSub !== undefined) {
17
+ nextSub.prevSub = prevSub
18
+ } else {
19
+ dep.subsTail = prevSub
20
+ }
21
+ }
@@ -0,0 +1,24 @@
1
+ import { detachLink } from './detachLink.ts'
2
+ import type { ReactiveNode } from './types/ReactiveNode.ts'
3
+
4
+ /*
5
+ Closes a dependency-capture pass: every edge trailing the recompute cursor
6
+ (`depsTail`) is a dependency last run read but this run didn't, so unlink it from
7
+ its source and truncate the list at the cursor. `track` advanced the cursor past
8
+ each reused edge during compute, so the cursor is the new tail. A node that read
9
+ nothing leaves the cursor at the start (`undefined`), dropping every edge.
10
+ */
11
+ export function endTracking(node: ReactiveNode): void {
12
+ const cursor = node.depsTail
13
+ let stale = cursor === undefined ? node.depsHead : cursor.nextDep
14
+ while (stale !== undefined) {
15
+ const next = stale.nextDep
16
+ detachLink(stale)
17
+ stale = next
18
+ }
19
+ if (cursor !== undefined) {
20
+ cursor.nextDep = undefined
21
+ } else {
22
+ node.depsHead = undefined
23
+ }
24
+ }
@@ -0,0 +1,12 @@
1
+ import { RENDER } from './RENDER.ts'
2
+
3
+ /* Marks entry into a render/mount. The OUTERMOST one (depth 0) resets the block-id
4
+ counter so every render pass starts at 0; a child component's render/mount runs
5
+ at depth > 0 and continues the parent's counter. Pair with `exitRenderPass`. */
6
+ // @readme plumbing
7
+ export function enterRenderPass(): void {
8
+ if (RENDER.depth === 0) {
9
+ RENDER.blockId = 0
10
+ }
11
+ RENDER.depth += 1
12
+ }
@@ -0,0 +1,7 @@
1
+ import { RENDER } from './RENDER.ts'
2
+
3
+ /* Marks exit from a render/mount, unwinding the depth `enterRenderPass` raised. */
4
+ // @readme plumbing
5
+ export function exitRenderPass(): void {
6
+ RENDER.depth -= 1
7
+ }
@@ -0,0 +1,22 @@
1
+ import { OUTLET_TAG } from './OUTLET_TAG.ts'
2
+
3
+ /*
4
+ The first `<abide-outlet>` in `root`'s subtree, in document order — the position
5
+ the router fills with the next layer of a route's layout chain. A depth-first walk
6
+ over `children` rather than `querySelector`: the router runs against real DOM and
7
+ the test mini-DOM alike, and only the former has `querySelector`. Tag comparison is
8
+ case-insensitive (the real DOM uppercases `tagName`, the mini-DOM keeps it as
9
+ created). Returns undefined when the layout declares no `<slot/>`.
10
+ */
11
+ export function firstOutlet(root: Element): Element | undefined {
12
+ for (const child of root.children) {
13
+ if (child.tagName.toLowerCase() === OUTLET_TAG) {
14
+ return child
15
+ }
16
+ const nested = firstOutlet(child)
17
+ if (nested !== undefined) {
18
+ return nested
19
+ }
20
+ }
21
+ return undefined
22
+ }
@@ -0,0 +1,17 @@
1
+ import { REACTIVE_CONTEXT } from './REACTIVE_CONTEXT.ts'
2
+ import { runNode } from './runNode.ts'
3
+
4
+ /*
5
+ Drains queued effects synchronously. Snapshots and clears the queue each pass so
6
+ an effect that dirties further effects re-queues them for the next pass rather
7
+ than mutating the set mid-iteration; loops until the graph settles.
8
+ */
9
+ export function flushEffects(): void {
10
+ while (REACTIVE_CONTEXT.pendingEffects.size > 0) {
11
+ const batch = [...REACTIVE_CONTEXT.pendingEffects]
12
+ REACTIVE_CONTEXT.pendingEffects.clear()
13
+ for (const node of batch) {
14
+ runNode(node)
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,10 @@
1
+ import type { HotInstance } from './types/HotInstance.ts'
2
+
3
+ /*
4
+ Live component instances grouped by module id (`UiComponent.__abideId`).
5
+ `mountChild` adds each instance it mounts while hot reload is active; `hotReplace`
6
+ walks a module's set to swap every instance when that module is edited. The set's
7
+ remove callback (filed with the mounting owner) drops an instance on unmount, so
8
+ no stale record survives to be swapped into a detached host.
9
+ */
10
+ export const hotInstances: Map<string, Set<HotInstance>> = new Map()
@@ -0,0 +1,8 @@
1
+ /*
2
+ Whether abide-ui hot-module replacement is active. Off by default, so production
3
+ and ordinary dev render exactly as before — `mountChild` takes the plain path.
4
+ The dev client sets it true once the hot bridge is in place, switching every
5
+ child mount onto the path that records its instance so an edited component can be
6
+ disposed and re-run where it stands.
7
+ */
8
+ export const hotReloadEnabled: { current: boolean } = { current: false }
@@ -0,0 +1,25 @@
1
+ import { hotInstances } from './hotInstances.ts'
2
+ import type { UiComponent } from './types/UiComponent.ts'
3
+
4
+ /*
5
+ Swaps every live instance of an edited component to its new factory. Per instance:
6
+ dispose the current scope and its DOM (the mount disposer clears the host), then
7
+ re-run `next` into the same host with the same props — so state above the boundary
8
+ survives (props are thunks that re-read the parent's live signals) while the
9
+ component's own state resets. The hot module calls this on load with its freshly
10
+ compiled `next`. Returns whether it swapped at least one instance: false (the edited
11
+ component has none mounted — e.g. a router-mounted page, or a hidden branch) tells
12
+ the caller to fall back to a full reload, since nothing on screen would update.
13
+ */
14
+ export function hotReplace(moduleId: string, next: UiComponent): boolean {
15
+ const set = hotInstances.get(moduleId)
16
+ if (set === undefined || set.size === 0) {
17
+ return false
18
+ }
19
+ for (const instance of set) {
20
+ instance.dispose()
21
+ instance.factory = next
22
+ instance.dispose = next(instance.host, instance.props)
23
+ }
24
+ return true
25
+ }
@@ -0,0 +1,11 @@
1
+ import { RENDER } from './RENDER.ts'
2
+
3
+ /* The next block id in the current render pass. `await`/`try` blocks draw from it
4
+ in document order — shared across a component and the children it inlines — so a
5
+ page id and a child component's id never collide in the global `RESUME` manifest. */
6
+ // @readme plumbing
7
+ export function nextBlockId(): number {
8
+ const id = RENDER.blockId
9
+ RENDER.blockId += 1
10
+ return id
11
+ }
@@ -0,0 +1,23 @@
1
+ /*
2
+ Whether a `/`-joined path still resolves through `tree` — every segment present
3
+ in its container. The `in` operator covers both shapes: an object key, an array's
4
+ own index (in range) or its `length`. Distinguishes a path the tree no longer has
5
+ (a deleted key, an out-of-range index after a shrink) from one holding a genuine
6
+ `undefined`, which `valueAtPath` alone can't — used to evict dead reactive nodes.
7
+ */
8
+ export function pathExists(tree: unknown, path: string): boolean {
9
+ if (path === '') {
10
+ return tree !== undefined
11
+ }
12
+ let current: unknown = tree
13
+ for (const segment of path.split('/')) {
14
+ if (current === null || typeof current !== 'object') {
15
+ return false
16
+ }
17
+ if (!(segment in current)) {
18
+ return false
19
+ }
20
+ current = (current as Record<string, unknown>)[segment]
21
+ }
22
+ return true
23
+ }
@@ -0,0 +1,17 @@
1
+ import { runNode } from './runNode.ts'
2
+ import { track } from './track.ts'
3
+ import type { ReactiveNode } from './types/ReactiveNode.ts'
4
+
5
+ /*
6
+ Reads a node's current value and subscribes the running observer to it. A dirty
7
+ computed recomputes first (lazy pull); a signal returns its stored value
8
+ directly. Tracking happens after recompute so the reader links to the computed
9
+ itself, not its transitive deps.
10
+ */
11
+ export function readNode(node: ReactiveNode): unknown {
12
+ if (node.compute !== undefined && node.dirty) {
13
+ runNode(node)
14
+ }
15
+ track(node)
16
+ return node.value
17
+ }
@@ -0,0 +1,23 @@
1
+ import { hotInstances } from './hotInstances.ts'
2
+ import type { HotInstance } from './types/HotInstance.ts'
3
+
4
+ /*
5
+ Records a live component instance under its module id and returns a remove
6
+ callback. `mountChild` files the remove with the mounting owner, so the instance
7
+ leaves the registry when its parent (or branch/row) tears down — the module's set
8
+ is dropped once empty, leaving no orphan keys.
9
+ */
10
+ export function registerHotInstance(moduleId: string, instance: HotInstance): () => void {
11
+ let set = hotInstances.get(moduleId)
12
+ if (set === undefined) {
13
+ set = new Set()
14
+ hotInstances.set(moduleId, set)
15
+ }
16
+ set.add(instance)
17
+ return () => {
18
+ set.delete(instance)
19
+ if (set.size === 0) {
20
+ hotInstances.delete(moduleId)
21
+ }
22
+ }
23
+ }
@@ -0,0 +1,28 @@
1
+ import { endTracking } from './endTracking.ts'
2
+ import { REACTIVE_CONTEXT } from './REACTIVE_CONTEXT.ts'
3
+ import type { ReactiveNode } from './types/ReactiveNode.ts'
4
+
5
+ /*
6
+ Runs a compute node (computed or effect) with dependency capture. Rewinds the
7
+ recompute cursor (`depsTail`) to the start of the dependency list, installs itself
8
+ as the current observer so reads inside `compute` re-link via `track`, runs, then
9
+ trims every edge `track` didn't reuse — last run's dependencies that weren't read
10
+ this time. Re-capturing every run is what makes dependencies dynamic: a branch not
11
+ taken this run leaves its edges past the cursor, so they are dropped here. Returns
12
+ the fresh value (used by lazy computed reads).
13
+ */
14
+ export function runNode(node: ReactiveNode): unknown {
15
+ /* Rewind: track() walks forward from here, reusing matching edges in order. */
16
+ node.depsTail = undefined
17
+ const previous = REACTIVE_CONTEXT.observer
18
+ REACTIVE_CONTEXT.observer = node
19
+ try {
20
+ node.value = node.compute?.()
21
+ node.dirty = false
22
+ return node.value
23
+ } finally {
24
+ REACTIVE_CONTEXT.observer = previous
25
+ /* Drop the edges `track` didn't reuse — last run's now-stale dependencies. */
26
+ endTracking(node)
27
+ }
28
+ }
@@ -0,0 +1,9 @@
1
+ import { state } from '../state.ts'
2
+ import type { State } from './types/State.ts'
3
+
4
+ /* The current route as a reactive signal — read by `router` to pick the page,
5
+ written by `navigate`/`popstate`. Defaults to `/` where there is no location
6
+ (the server, which routes by request URL instead). */
7
+ export const runtimePath: State<string> = state(
8
+ typeof location !== 'undefined' ? location.pathname + location.search + location.hash : '/',
9
+ )
@@ -0,0 +1,24 @@
1
+ import { OWNER } from './OWNER.ts'
2
+
3
+ /*
4
+ Runs `build` under a fresh ownership scope so every effect and listener created
5
+ inside is collected, and returns a disposer that tears them all down in reverse
6
+ order (children before parents). Save/restore of the previous owner makes scopes
7
+ nest — a list row's scope sits inside its component's scope.
8
+ */
9
+ export function scope(build: () => void): () => void {
10
+ const previous = OWNER.current
11
+ const disposers: Array<() => void> = []
12
+ OWNER.current = disposers
13
+ try {
14
+ build()
15
+ } finally {
16
+ OWNER.current = previous
17
+ }
18
+ return () => {
19
+ for (let index = disposers.length - 1; index >= 0; index -= 1) {
20
+ disposers[index]?.()
21
+ }
22
+ disposers.length = 0
23
+ }
24
+ }
@@ -0,0 +1,26 @@
1
+ import type { EffectResult } from './types/EffectResult.ts'
2
+ import type { Teardown } from './types/Teardown.ts'
3
+
4
+ /*
5
+ Normalises an effect/attachment body's return into a single callable teardown (or
6
+ undefined when it returned nothing). A function is the teardown itself; a promise
7
+ is wrapped so the teardown runs once it settles — chained, never awaited, so a
8
+ dispose mid-setup still tears down without blocking the caller. Shared by
9
+ `createEffectNode` (runs it on re-run + dispose) and `attach` (registers it with
10
+ the owner scope).
11
+ */
12
+ export function toTeardown(result: EffectResult): Teardown | undefined {
13
+ if (typeof result === 'function') {
14
+ return result
15
+ }
16
+ if (result instanceof Promise) {
17
+ return () => {
18
+ result.then((teardown) => {
19
+ if (typeof teardown === 'function') {
20
+ teardown()
21
+ }
22
+ })
23
+ }
24
+ }
25
+ return undefined
26
+ }
@@ -0,0 +1,58 @@
1
+ import { REACTIVE_CONTEXT } from './REACTIVE_CONTEXT.ts'
2
+ import type { ReactiveLink } from './types/ReactiveLink.ts'
3
+ import type { ReactiveNode } from './types/ReactiveNode.ts'
4
+
5
+ /*
6
+ Links a node being read to the observer currently running, in both directions, so
7
+ a later write to the node reaches the observer and a recompute can unlink it. A
8
+ no-op outside any tracking scope — reads in plain code (and on the server)
9
+ register nothing, so the same callable works tracked and untracked.
10
+
11
+ Edge reuse keeps a settled observer allocation-free across runs. `depsTail` is the
12
+ recompute cursor (rewound by `runNode` before compute); the edge just past it is
13
+ what last run captured at this position. If that edge already points at `dep`, the
14
+ observer is reading the same source in the same order as before — advance the
15
+ cursor and reuse the edge, allocating nothing. Otherwise splice a fresh edge in at
16
+ the cursor; `runNode` trims whatever stale edges trail the cursor when compute ends.
17
+
18
+ A consecutive re-read of the same source (`dep` already the edge at the cursor) is
19
+ absorbed by the reuse check, so `{x} … {x}` in one computation links `x` once.
20
+ */
21
+ export function track(dep: ReactiveNode): void {
22
+ const sub = REACTIVE_CONTEXT.observer
23
+ if (sub === undefined) {
24
+ return
25
+ }
26
+ /* The edge to reuse: the one after the cursor, or the head when the cursor sits
27
+ at the start of this run. */
28
+ const reusable = sub.depsTail === undefined ? sub.depsHead : sub.depsTail.nextDep
29
+ if (reusable !== undefined && reusable.dep === dep) {
30
+ sub.depsTail = reusable
31
+ return
32
+ }
33
+ const link: ReactiveLink = {
34
+ dep,
35
+ sub,
36
+ prevDep: sub.depsTail,
37
+ nextDep: reusable,
38
+ prevSub: dep.subsTail,
39
+ nextSub: undefined,
40
+ }
41
+ /* Splice into the observer's dependency list at the cursor. */
42
+ if (sub.depsTail !== undefined) {
43
+ sub.depsTail.nextDep = link
44
+ } else {
45
+ sub.depsHead = link
46
+ }
47
+ if (reusable !== undefined) {
48
+ reusable.prevDep = link
49
+ }
50
+ sub.depsTail = link
51
+ /* Append onto the source's subscriber list (order there is irrelevant). */
52
+ if (dep.subsTail !== undefined) {
53
+ dep.subsTail.nextSub = link
54
+ } else {
55
+ dep.subsHead = link
56
+ }
57
+ dep.subsTail = link
58
+ }
@@ -0,0 +1,44 @@
1
+ import { flushEffects } from './flushEffects.ts'
2
+ import { REACTIVE_CONTEXT } from './REACTIVE_CONTEXT.ts'
3
+ import type { ReactiveNode } from './types/ReactiveNode.ts'
4
+
5
+ /*
6
+ Invalidates the observer cone of a just-written node: effect observers are
7
+ queued, computed observers are marked dirty and recursed into (their value may
8
+ now differ, so their own observers must learn of it). Recompute is lazy — a
9
+ computed recomputes on next read — so this pass only invalidates and collects.
10
+
11
+ The subscriber list is walked live: invalidate runs no compute and no effect, so
12
+ nothing re-subscribes (the only mutators of a subscriber list, `track` and
13
+ `runNode`, run inside compute execution, which only `flushEffects` reaches — after
14
+ this pass). The re-subscribe hazard belongs to the flush, where `flushEffects`
15
+ defends with its own snapshot. `nextSub` is read before recursing, so the walk
16
+ holds no reference a downstream pass could invalidate.
17
+ */
18
+ function invalidate(node: ReactiveNode): void {
19
+ let link = node.subsHead
20
+ while (link !== undefined) {
21
+ const observer = link.sub
22
+ const next = link.nextSub
23
+ if (observer.isEffect) {
24
+ REACTIVE_CONTEXT.pendingEffects.add(observer)
25
+ } else if (!observer.dirty) {
26
+ observer.dirty = true
27
+ invalidate(observer)
28
+ }
29
+ link = next
30
+ }
31
+ }
32
+
33
+ /*
34
+ Propagates a change forward from a just-written node. Invalidation collects the
35
+ whole cone first; the queued effects flush once, at the outermost trigger (or,
36
+ inside a batch, when the batch owner exits) — never mid-propagation, so an effect
37
+ never runs against a half-invalidated graph.
38
+ */
39
+ export function trigger(node: ReactiveNode): void {
40
+ invalidate(node)
41
+ if (REACTIVE_CONTEXT.batchDepth === 0) {
42
+ flushEffects()
43
+ }
44
+ }
@@ -0,0 +1,5 @@
1
+ /* A stable reactive accessor bound to one document path: `get` subscribes the
2
+ running observer, `set` mutates that path and wakes its readers — all path
3
+ resolution done once at bind time, so the access itself is string-free. This
4
+ is the shape the template compiler emits for a `{path}` read / write. */
5
+ export type Cell<T> = { get: () => T; set: (value: T) => void }
@@ -0,0 +1,3 @@
1
+ /* A read-only reactive cell computed from other cells. Reading `.value`
2
+ subscribes the running observer and lazily recomputes if a dependency changed. */
3
+ export type Derived<T> = { readonly value: T }
@@ -0,0 +1,19 @@
1
+ import type { Cell } from './Cell.ts'
2
+ import type { Patch } from './Patch.ts'
3
+
4
+ /*
5
+ A reactive document: a single immutable tree addressed by path. `read` subscribes
6
+ the running observer to a path and returns its current value; `apply` (and the
7
+ `replace`/`add`/`remove` sugar) advances the tree by one patch and wakes exactly
8
+ the readers whose paths the patch touched. `snapshot` returns the current root —
9
+ plain, serializable data, which is what makes the document resumable.
10
+ */
11
+ export type Doc = {
12
+ read: <T>(path: string) => T
13
+ cell: <T>(path: string) => Cell<T>
14
+ apply: (patch: Patch) => void
15
+ replace: (path: string, value: unknown) => void
16
+ add: (path: string, value: unknown) => void
17
+ remove: (path: string) => void
18
+ snapshot: () => unknown
19
+ }
@@ -0,0 +1,10 @@
1
+ import type { Teardown } from './Teardown.ts'
2
+
3
+ /*
4
+ What an effect or attachment body returns: a teardown to run before its next run
5
+ and on dispose, nothing, or — when the body is async — a promise of either. The
6
+ async case tracks only the reads before its first `await`; reads after it are not
7
+ captured by the reactive graph.
8
+ */
9
+ // biome-ignore lint/suspicious/noConfusingVoidType: an effect body with no return is void; the union is the real contract
10
+ export type EffectResult = void | Teardown | Promise<void | Teardown>
@@ -0,0 +1,14 @@
1
+ import type { UiComponent } from './UiComponent.ts'
2
+
3
+ /*
4
+ A live component instance the hot-reload registry tracks: its wrapper host, the
5
+ factory that built it, the props (thunks re-read on a swap so the parent's live
6
+ state still flows through), and the disposer for its current scope + DOM. A swap
7
+ mutates `factory`/`dispose` in place (see `hotReplace`).
8
+ */
9
+ export type HotInstance = {
10
+ host: Element
11
+ factory: UiComponent
12
+ props: Parameters<UiComponent>[1]
13
+ dispose: () => void
14
+ }
@@ -0,0 +1,9 @@
1
+ /* What the navigation probe decided after running the destination through the
2
+ server's app.handle: `mount` it client-side (handle() cleared it), `redirect`
3
+ to where handle() pointed (same-origin — the router re-probes there), or `reload`
4
+ via a full browser navigation (handle() blocked it, redirected cross-origin, or
5
+ the probe itself failed) so the server's real response is what the user sees. */
6
+ export type NavVerdict =
7
+ | { kind: 'mount' }
8
+ | { kind: 'redirect'; path: string }
9
+ | { kind: 'reload'; url: string }
@@ -0,0 +1,11 @@
1
+ /*
2
+ A serializable change against a document path. `replace` overwrites the value at
3
+ a path; `add` inserts (into an array at an index or `-` to push, or sets an
4
+ object key); `remove` deletes it. The path is `/`-joined segments; `''` is the
5
+ document root. Being plain data is the whole point — a patch is the unit that
6
+ flows from a transition to the DOM, to persistence, and over the wire.
7
+ */
8
+ export type Patch =
9
+ | { op: 'replace'; path: string; value: unknown }
10
+ | { op: 'add'; path: string; value: unknown }
11
+ | { op: 'remove'; path: string }
@@ -0,0 +1,21 @@
1
+ import type { ReactiveNode } from './ReactiveNode.ts'
2
+
3
+ /*
4
+ One dependency edge in the reactive graph: `sub` (the observer) reads `dep` (the
5
+ source). The edge is threaded into two intrusive doubly-linked lists at once — the
6
+ source's list of subscribers (the `*Sub` pointers, walked forward on a write) and
7
+ the observer's list of dependencies (the `*Dep` pointers, walked on recompute to
8
+ reuse or drop edges). Replacing the former `Set` on each side makes link/unlink
9
+ O(1) with no per-edge allocation once a node settles, and propagation a sequential
10
+ pointer walk instead of a hashed-set iteration.
11
+ */
12
+ export type ReactiveLink = {
13
+ dep: ReactiveNode
14
+ sub: ReactiveNode
15
+ /* Siblings in `sub`'s dependency list (the edges `sub` captured, in read order). */
16
+ prevDep: ReactiveLink | undefined
17
+ nextDep: ReactiveLink | undefined
18
+ /* Siblings in `dep`'s subscriber list (every observer reading `dep`). */
19
+ prevSub: ReactiveLink | undefined
20
+ nextSub: ReactiveLink | undefined
21
+ }
@@ -0,0 +1,25 @@
1
+ import type { ReactiveLink } from './ReactiveLink.ts'
2
+
3
+ /*
4
+ A node in the reactive graph. A signal has a value and no compute; a computed has
5
+ both; an effect has a compute and runs for its side effects. Dependencies (the
6
+ nodes this node read on its last run) and subscribers (the nodes that read this
7
+ one) are each held as an intrusive doubly-linked list of `ReactiveLink` edges
8
+ rather than a `Set` — a write walks `subsHead → nextSub` forward to dependents, a
9
+ recompute walks `depsHead → nextDep` to reuse still-live edges and drop stale
10
+ back-links, both O(1) per edge with no allocation once the node settles.
11
+
12
+ `depsTail` doubles as the recompute cursor: `runNode` rewinds it before compute
13
+ and `track` advances it past each reused edge, so whatever trails it afterward is
14
+ this run's stale dependencies, trimmed in one pass.
15
+ */
16
+ export type ReactiveNode = {
17
+ value: unknown
18
+ compute: (() => unknown) | undefined
19
+ depsHead: ReactiveLink | undefined
20
+ depsTail: ReactiveLink | undefined
21
+ subsHead: ReactiveLink | undefined
22
+ subsTail: ReactiveLink | undefined
23
+ dirty: boolean
24
+ isEffect: boolean
25
+ }
@@ -0,0 +1,8 @@
1
+ /* A routable page: mounts into a host (optionally with props) and may return a
2
+ disposer the router calls when navigating away. A compiled `.abide` default
3
+ export also carries `hydrate` (adopt SSR in place) and `hydratable` (false when
4
+ the page has an `await` block), which the router uses for the initial render. */
5
+ export type Route = ((host: Element, props?: unknown) => (() => void) | undefined) & {
6
+ hydrate?: (host: Element, props?: unknown) => () => void
7
+ hydratable?: boolean
8
+ }