@abide/abide 0.58.0 → 0.100.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 (1198) hide show
  1. package/CHANGELOG.md +3 -1781
  2. package/bin/abide.ts +788 -204
  3. package/package.json +30 -152
  4. package/scaffold/src/server/app.ts +6 -0
  5. package/scaffold/src/shared/.gitkeep +0 -0
  6. package/scaffold/src/ui/app.html +8 -0
  7. package/scaffold/src/ui/pages/page.abide +13 -0
  8. package/src/compiler/CHARACTER_REFERENCES.ts +2242 -0
  9. package/src/compiler/CheckerAnswer.ts +62 -0
  10. package/src/compiler/Cursor.ts +367 -0
  11. package/src/compiler/Finding.ts +2 -0
  12. package/src/compiler/Lowering.ts +648 -0
  13. package/src/compiler/PositionTable.ts +125 -0
  14. package/src/compiler/REACTIVE_MEMBERS.ts +36 -0
  15. package/src/compiler/SHARED_NAMES.ts +45 -0
  16. package/src/compiler/SPECIFIERS.ts +16 -0
  17. package/src/compiler/ShadowMap.ts +144 -0
  18. package/src/compiler/TemplateNode.ts +176 -0
  19. package/src/compiler/TypeSession.ts +1079 -0
  20. package/src/compiler/VOID_ELEMENTS.ts +22 -0
  21. package/src/compiler/aliasedSymbol.ts +15 -0
  22. package/src/compiler/ambientReadsIn.ts +152 -0
  23. package/src/compiler/argsDefaultsIn.ts +173 -0
  24. package/src/compiler/argsSchemaOf.ts +230 -0
  25. package/src/compiler/checkApp.ts +117 -0
  26. package/src/compiler/checkedShadow.ts +182 -0
  27. package/src/compiler/classifyRead.ts +577 -0
  28. package/src/compiler/classifyTemplate.ts +501 -0
  29. package/src/compiler/compileApp.ts +559 -0
  30. package/src/compiler/compiledEntry.ts +141 -0
  31. package/src/compiler/componentGraph.ts +139 -0
  32. package/src/compiler/declaredExports.ts +645 -0
  33. package/src/compiler/decodeCharacterReferences.ts +111 -0
  34. package/src/compiler/emitClient.ts +1343 -0
  35. package/src/compiler/emitComponent.ts +162 -0
  36. package/src/compiler/emitSource.ts +91 -0
  37. package/src/compiler/formatDiagnosis.ts +19 -0
  38. package/src/compiler/handlersUnder.ts +109 -0
  39. package/src/compiler/index.ts +15 -0
  40. package/src/compiler/invocationProps.ts +67 -0
  41. package/src/compiler/isNamedAlone.ts +9 -0
  42. package/src/compiler/lineOf.ts +38 -0
  43. package/src/compiler/parseAbide.ts +1341 -0
  44. package/src/compiler/projectShadow.ts +643 -0
  45. package/src/compiler/reactiveOptions.ts +82 -0
  46. package/src/compiler/reactiveTypes.ts +222 -0
  47. package/src/compiler/readSources.ts +100 -0
  48. package/src/compiler/readsIn.ts +1023 -0
  49. package/src/compiler/renderMarkup.ts +781 -0
  50. package/src/compiler/scaffold.ts +105 -0
  51. package/src/compiler/scopeStyles.ts +309 -0
  52. package/src/compiler/serveLanguage.ts +405 -0
  53. package/src/compiler/shareScope.ts +51 -0
  54. package/src/compiler/sharedModuleWrites.ts +88 -0
  55. package/src/compiler/splitImports.ts +387 -0
  56. package/src/compiler/templateWarnings.ts +128 -0
  57. package/src/compiler/tokenize.ts +317 -0
  58. package/src/compiler/trackingWarnings.ts +279 -0
  59. package/src/compiler/writeDefaultProject.ts +42 -0
  60. package/src/server/BRIDGE_VERSION.ts +3 -0
  61. package/src/server/CLIENT_BUILD.ts +56 -0
  62. package/src/server/DEFAULT_PORT.ts +6 -0
  63. package/src/server/DOCUMENT_HEADERS.ts +11 -0
  64. package/src/server/Inbox.ts +36 -0
  65. package/src/server/LogPanel.ts +239 -0
  66. package/src/server/MCP_PROTOCOL_VERSION.ts +3 -0
  67. package/src/server/SETTLE_MILLISECONDS.ts +7 -0
  68. package/src/server/VIRTUAL_DIRECTORY.ts +6 -0
  69. package/src/server/answerFailure.ts +91 -0
  70. package/src/server/answerRequest.ts +560 -0
  71. package/src/server/answerRpc.ts +537 -0
  72. package/src/server/answerSocket.ts +537 -0
  73. package/src/server/answerValue.ts +375 -0
  74. package/src/server/appDirectories.ts +9 -0
  75. package/src/server/appKit.ts +204 -0
  76. package/src/server/appPlugins.ts +26 -0
  77. package/src/server/argsFor.ts +40 -0
  78. package/src/server/assistant.ts +163 -0
  79. package/src/server/banner.ts +43 -0
  80. package/src/server/bridgeRelay.ts +249 -0
  81. package/src/server/buildDirectory.ts +10 -0
  82. package/src/server/callerOf.ts +60 -0
  83. package/src/server/claudeApi.ts +224 -0
  84. package/src/server/claudeCode.ts +187 -0
  85. package/src/server/clientBuildOptions.ts +49 -0
  86. package/src/server/coerceArgs.ts +110 -0
  87. package/src/server/commands.ts +442 -0
  88. package/src/server/componentImports.ts +56 -0
  89. package/src/server/componentModules.d.ts +9 -0
  90. package/src/server/compressAnswer.ts +66 -0
  91. package/src/server/config.ts +192 -0
  92. package/src/server/configFields.ts +92 -0
  93. package/src/server/createApp.ts +428 -0
  94. package/src/server/crossingOrigin.ts +49 -0
  95. package/src/server/csp.ts +77 -0
  96. package/src/server/devWorker.ts +613 -0
  97. package/src/server/faultPolicy.ts +59 -0
  98. package/src/server/fenceServer.ts +48 -0
  99. package/src/server/generatedSurfaces.ts +430 -0
  100. package/src/server/hooks.ts +190 -0
  101. package/src/server/index.ts +87 -0
  102. package/src/server/installServer.ts +47 -0
  103. package/src/server/launcherOptions.ts +62 -0
  104. package/src/server/launcherPage.ts +156 -0
  105. package/src/server/manifestOf.ts +114 -0
  106. package/src/server/muxUpgrade.ts +72 -0
  107. package/src/server/namesUnder.ts +15 -0
  108. package/src/server/nativeMenu.ts +296 -0
  109. package/src/server/negotiateEncoding.ts +39 -0
  110. package/src/server/plainAnswer.ts +19 -0
  111. package/src/server/prefers.ts +25 -0
  112. package/src/server/principal.ts +261 -0
  113. package/src/server/qualitiesOf.ts +22 -0
  114. package/src/server/randomToken.ts +9 -0
  115. package/src/server/reachable.ts +31 -0
  116. package/src/server/refuseAddressCollision.ts +30 -0
  117. package/src/server/remote.ts +242 -0
  118. package/src/server/render.ts +464 -0
  119. package/src/server/renderComponent.ts +33 -0
  120. package/src/server/reportHealth.ts +46 -0
  121. package/src/server/requestScope.ts +435 -0
  122. package/src/server/responseHelpers.ts +75 -0
  123. package/src/server/runCompiled.ts +44 -0
  124. package/src/server/runDesktop.ts +572 -0
  125. package/src/server/seedBuffer.ts +293 -0
  126. package/src/server/serveBuild.ts +198 -0
  127. package/src/server/serveDev.ts +499 -0
  128. package/src/server/shell.ts +506 -0
  129. package/src/server/surfaceOf.ts +47 -0
  130. package/src/server/testBuild.ts +237 -0
  131. package/src/server/trace.ts +151 -0
  132. package/src/server/versionOf.ts +109 -0
  133. package/src/server/withoutTrailingSlash.ts +4 -0
  134. package/src/shared/ADDRESSES.ts +69 -0
  135. package/src/shared/ANCHORS.ts +54 -0
  136. package/src/shared/Attributes.ts +339 -0
  137. package/src/shared/BOOLEAN_ATTRIBUTES.ts +41 -0
  138. package/src/shared/CHILDREN.ts +11 -0
  139. package/src/shared/CURRENT_ROUTER.ts +25 -0
  140. package/src/shared/CopyOptions.ts +19 -0
  141. package/src/shared/DEBUG_META.ts +6 -0
  142. package/src/shared/EARLY_CALLS.ts +8 -0
  143. package/src/shared/FAILURE_STATUS_TEXT.ts +48 -0
  144. package/src/shared/Failed.ts +146 -0
  145. package/src/shared/GLOBAL_GETS.ts +7 -0
  146. package/src/shared/Issues.ts +49 -0
  147. package/src/shared/JsonValue.ts +18 -0
  148. package/src/shared/LOAD_SIGNAL.ts +10 -0
  149. package/src/shared/MOUNT_META.ts +6 -0
  150. package/src/shared/Middleware.ts +34 -0
  151. package/src/shared/NAVIGATION_HEADER.ts +7 -0
  152. package/src/shared/PRINCIPAL_HEADER.ts +6 -0
  153. package/src/shared/RPC_SERVER.ts +67 -0
  154. package/src/shared/Raw.ts +90 -0
  155. package/src/shared/Schema.ts +229 -0
  156. package/src/shared/UNEXPECTED.ts +11 -0
  157. package/src/shared/URL_ATTRIBUTES.ts +19 -0
  158. package/src/shared/VERSION_HEADER.ts +6 -0
  159. package/src/shared/WORK.ts +37 -0
  160. package/src/shared/anchorMarkup.ts +15 -0
  161. package/src/shared/answerOf.ts +141 -0
  162. package/src/shared/applyPatch.ts +173 -0
  163. package/src/shared/armAnchor.ts +17 -0
  164. package/src/shared/attributeText.ts +50 -0
  165. package/src/shared/boundValue.ts +58 -0
  166. package/src/shared/cookies.ts +271 -0
  167. package/src/shared/csp.ts +55 -0
  168. package/src/shared/decodedOrKept.ts +14 -0
  169. package/src/shared/escapeText.ts +103 -0
  170. package/src/shared/framing.ts +131 -0
  171. package/src/shared/headKeyOf.ts +34 -0
  172. package/src/shared/health.ts +51 -0
  173. package/src/shared/index.ts +117 -0
  174. package/src/shared/isEventName.ts +10 -0
  175. package/src/shared/isRecord.ts +4 -0
  176. package/src/shared/issuesOf.ts +18 -0
  177. package/src/shared/jsonSchema.ts +50 -0
  178. package/src/shared/listOf.ts +20 -0
  179. package/src/shared/log.ts +284 -0
  180. package/src/shared/matchRoute.ts +99 -0
  181. package/src/shared/menuItem.ts +80 -0
  182. package/src/shared/mount.ts +45 -0
  183. package/src/shared/muxFrames.ts +35 -0
  184. package/src/shared/navigate.ts +26 -0
  185. package/src/shared/note.ts +24 -0
  186. package/src/shared/numberFromText.ts +10 -0
  187. package/src/shared/online.ts +19 -0
  188. package/src/shared/paint.ts +4 -0
  189. package/src/shared/principal.ts +145 -0
  190. package/src/shared/principalRotated.ts +47 -0
  191. package/src/shared/propCell.ts +99 -0
  192. package/src/shared/props.ts +24 -0
  193. package/src/shared/putOwn.ts +24 -0
  194. package/src/shared/queryText.ts +18 -0
  195. package/src/shared/reactive/CELL.ts +8 -0
  196. package/src/shared/reactive/Cursor.ts +223 -0
  197. package/src/shared/reactive/ENTRY_LIVES.ts +7 -0
  198. package/src/shared/reactive/Expiry.ts +103 -0
  199. package/src/shared/reactive/FOLLOWED.ts +8 -0
  200. package/src/shared/reactive/KEYED_BRAND.ts +8 -0
  201. package/src/shared/reactive/Keyed.ts +423 -0
  202. package/src/shared/reactive/MUTATION.ts +5 -0
  203. package/src/shared/reactive/NO_INITIAL.ts +6 -0
  204. package/src/shared/reactive/NotLanded.ts +21 -0
  205. package/src/shared/reactive/PATCHES.ts +11 -0
  206. package/src/shared/reactive/PATCH_SINKS.ts +26 -0
  207. package/src/shared/reactive/REACTIVE_BRAND.ts +9 -0
  208. package/src/shared/reactive/RESHAPING.ts +13 -0
  209. package/src/shared/reactive/Reactive.ts +4480 -0
  210. package/src/shared/reactive/SELECTION_MEMBERS.ts +12 -0
  211. package/src/shared/reactive/STREAMING.ts +5 -0
  212. package/src/shared/reactive/argsContract.ts +97 -0
  213. package/src/shared/reactive/byOf.ts +18 -0
  214. package/src/shared/reactive/callLoad.ts +200 -0
  215. package/src/shared/reactive/canonicalKey.ts +95 -0
  216. package/src/shared/reactive/chunksOfStream.ts +51 -0
  217. package/src/shared/reactive/index.ts +542 -0
  218. package/src/shared/reactive/isReactive.ts +19 -0
  219. package/src/shared/reactive/isThenable.ts +14 -0
  220. package/src/shared/reactive/matchesPattern.ts +16 -0
  221. package/src/shared/reactive/pairReactive.ts +41 -0
  222. package/src/shared/reactive/parameterDefaults.ts +356 -0
  223. package/src/shared/reactive/recordWrites.ts +472 -0
  224. package/src/shared/reactive/scoped.ts +157 -0
  225. package/src/shared/reactive/scoping.ts +64 -0
  226. package/src/shared/reactive/share.ts +91 -0
  227. package/src/shared/reactive/structural.ts +62 -0
  228. package/src/shared/reactive/tracking.ts +418 -0
  229. package/src/shared/reactive/watch.ts +310 -0
  230. package/src/shared/refuse.ts +224 -0
  231. package/src/shared/route.ts +29 -0
  232. package/src/shared/routePattern.ts +146 -0
  233. package/src/shared/rpc.ts +496 -0
  234. package/src/shared/rpcRequest.ts +73 -0
  235. package/src/shared/safeUrl.ts +68 -0
  236. package/src/shared/seededDocument.ts +36 -0
  237. package/src/shared/setUpLevels.ts +53 -0
  238. package/src/shared/slotValue.ts +34 -0
  239. package/src/shared/spread.ts +79 -0
  240. package/src/shared/takeEarlyCall.ts +86 -0
  241. package/src/shared/url.ts +140 -0
  242. package/src/shared/validateJson.ts +578 -0
  243. package/src/shared/versionInEtag.ts +14 -0
  244. package/src/shared/writePath.ts +95 -0
  245. package/src/ui/ArmRegion.ts +185 -0
  246. package/src/ui/LAYER_NAMES.ts +30 -0
  247. package/src/ui/List.ts +273 -0
  248. package/src/ui/Mismatch.ts +32 -0
  249. package/src/ui/RawRun.ts +99 -0
  250. package/src/ui/Router.ts +698 -0
  251. package/src/ui/Scope.ts +115 -0
  252. package/src/ui/TryRegion.ts +278 -0
  253. package/src/ui/adoptWalk.ts +126 -0
  254. package/src/ui/applyHead.ts +146 -0
  255. package/src/ui/bindElement.ts +44 -0
  256. package/src/ui/bindProperty.ts +79 -0
  257. package/src/ui/bindSpread.ts +44 -0
  258. package/src/ui/escapeless.ts +14 -0
  259. package/src/ui/index.ts +64 -0
  260. package/src/ui/leave.ts +35 -0
  261. package/src/ui/listenForRoutes.ts +92 -0
  262. package/src/ui/measureLayer.ts +34 -0
  263. package/src/ui/menuBridge.ts +19 -0
  264. package/src/ui/moveNode.ts +34 -0
  265. package/src/ui/parseMarkup.ts +35 -0
  266. package/src/ui/reconcile.ts +368 -0
  267. package/src/ui/regions.ts +137 -0
  268. package/src/ui/reportMenu.ts +57 -0
  269. package/src/ui/routing.ts +18 -0
  270. package/src/ui/rowKeyOf.ts +19 -0
  271. package/src/ui/rows.ts +99 -0
  272. package/src/ui/setAttribute.ts +37 -0
  273. package/src/ui/setClass.ts +27 -0
  274. package/src/ui/setMarkup.ts +20 -0
  275. package/src/ui/setStyleProperty.ts +30 -0
  276. package/src/ui/setText.ts +28 -0
  277. package/src/ui/socketWire.ts +258 -0
  278. package/src/ui/wire.ts +141 -0
  279. package/AGENTS.md +0 -446
  280. package/README.md +0 -249
  281. package/src/abideLsp.ts +0 -251
  282. package/src/abideModules.d.ts +0 -8
  283. package/src/abideResolverPlugin.ts +0 -1101
  284. package/src/appEntry.ts +0 -161
  285. package/src/assets/app.html +0 -12
  286. package/src/build.ts +0 -189
  287. package/src/buildCli.ts +0 -125
  288. package/src/buildDisconnected.ts +0 -117
  289. package/src/bundleApp.ts +0 -146
  290. package/src/bundleDisconnectedEntry.ts +0 -14
  291. package/src/checkAbide.ts +0 -145
  292. package/src/cliEntry.ts +0 -25
  293. package/src/clientBuildPlugins.ts +0 -33
  294. package/src/clientEntry.ts +0 -17
  295. package/src/compile.ts +0 -61
  296. package/src/controlServerWorker.ts +0 -433
  297. package/src/devEntry.ts +0 -381
  298. package/src/discoveryEntry.ts +0 -82
  299. package/src/initAgent.ts +0 -50
  300. package/src/lib/bundle/BundleMenu.ts +0 -12
  301. package/src/lib/bundle/BundleMenuItem.ts +0 -25
  302. package/src/lib/bundle/BundleWindow.ts +0 -37
  303. package/src/lib/bundle/WEBVIEW_BUILD_REVISION.ts +0 -9
  304. package/src/lib/bundle/WEBVIEW_VERSION.ts +0 -7
  305. package/src/lib/bundle/bindConnectedFlag.ts +0 -29
  306. package/src/lib/bundle/bindRequestNavigate.ts +0 -34
  307. package/src/lib/bundle/buildWebviewLib.ts +0 -111
  308. package/src/lib/bundle/bundled.ts +0 -35
  309. package/src/lib/bundle/disconnected.abide +0 -265
  310. package/src/lib/bundle/disconnected.css +0 -9
  311. package/src/lib/bundle/ensureWebviewLib.ts +0 -20
  312. package/src/lib/bundle/exitWithParent.ts +0 -30
  313. package/src/lib/bundle/infoPlist.ts +0 -52
  314. package/src/lib/bundle/installDownloads.ts +0 -34
  315. package/src/lib/bundle/installMacMenu.ts +0 -49
  316. package/src/lib/bundle/listenLocalControlServer.ts +0 -19
  317. package/src/lib/bundle/native/abideMenu.mm +0 -422
  318. package/src/lib/bundle/native/webview.h +0 -4557
  319. package/src/lib/bundle/onMenu.ts +0 -42
  320. package/src/lib/bundle/openWebview.ts +0 -104
  321. package/src/lib/bundle/pngToIcns.ts +0 -47
  322. package/src/lib/bundle/probeAbideServer.ts +0 -57
  323. package/src/lib/bundle/resolveServerBinary.ts +0 -12
  324. package/src/lib/bundle/resolveWebviewLib.ts +0 -53
  325. package/src/lib/bundle/serverBinaryFilename.ts +0 -8
  326. package/src/lib/bundle/signMacApp.ts +0 -37
  327. package/src/lib/bundle/spawnEmbeddedServer.ts +0 -73
  328. package/src/lib/bundle/stableLocalPort.ts +0 -19
  329. package/src/lib/bundle/waitForServer.ts +0 -28
  330. package/src/lib/bundle/webviewCachePath.ts +0 -23
  331. package/src/lib/bundle/webviewLibName.ts +0 -11
  332. package/src/lib/cli/completeCli.ts +0 -38
  333. package/src/lib/cli/connectToServer.ts +0 -23
  334. package/src/lib/cli/createClient.ts +0 -108
  335. package/src/lib/cli/dispatchCommand.ts +0 -72
  336. package/src/lib/cli/loadEnvFromBinaryDir.ts +0 -15
  337. package/src/lib/cli/parseArgvForRpc.ts +0 -131
  338. package/src/lib/cli/printCommandHelp.ts +0 -43
  339. package/src/lib/cli/printSessionHelp.ts +0 -28
  340. package/src/lib/cli/printSessionStatus.ts +0 -21
  341. package/src/lib/cli/printTopLevelHelp.ts +0 -83
  342. package/src/lib/cli/printTrimmed.ts +0 -8
  343. package/src/lib/cli/printValue.ts +0 -10
  344. package/src/lib/cli/renderCliCompletions.ts +0 -56
  345. package/src/lib/cli/resolveCliTarget.ts +0 -47
  346. package/src/lib/cli/runCli.ts +0 -188
  347. package/src/lib/cli/runSession.ts +0 -107
  348. package/src/lib/cli/startLocalInstance.ts +0 -14
  349. package/src/lib/cli/tokenizeArgvFlags.ts +0 -86
  350. package/src/lib/cli/tokenizeLine.ts +0 -51
  351. package/src/lib/cli/types/CliManifest.ts +0 -11
  352. package/src/lib/cli/types/CliManifestEntry.ts +0 -17
  353. package/src/lib/cli/types/CliTarget.ts +0 -13
  354. package/src/lib/mcp/annotationsForMethod.ts +0 -29
  355. package/src/lib/mcp/buildPrompts.ts +0 -25
  356. package/src/lib/mcp/createMcpResourceServer.ts +0 -113
  357. package/src/lib/mcp/createMcpServer.ts +0 -56
  358. package/src/lib/mcp/dispatchMcpRequest.ts +0 -159
  359. package/src/lib/mcp/mcpResourceServerSlot.ts +0 -13
  360. package/src/lib/mcp/mcpSurface.ts +0 -57
  361. package/src/lib/mcp/mcpTools.ts +0 -196
  362. package/src/lib/mcp/renderPrompt.ts +0 -25
  363. package/src/lib/mcp/toolResultFromResponse.ts +0 -100
  364. package/src/lib/mcp/types/JsonRpcRequest.ts +0 -12
  365. package/src/lib/mcp/types/JsonRpcResponse.ts +0 -20
  366. package/src/lib/mcp/types/McpResourceContents.ts +0 -10
  367. package/src/lib/mcp/types/McpResourceDescriptor.ts +0 -6
  368. package/src/lib/mcp/types/McpResourceServer.ts +0 -12
  369. package/src/lib/mcp/types/McpServer.ts +0 -9
  370. package/src/lib/mcp/types/McpServerOptions.ts +0 -16
  371. package/src/lib/mcp/types/McpSurface.ts +0 -15
  372. package/src/lib/mcp/types/PromptDescriptor.ts +0 -5
  373. package/src/lib/mcp/types/PromptMessage.ts +0 -2
  374. package/src/lib/mcp/types/ToolDescriptor.ts +0 -7
  375. package/src/lib/mcp/types/ToolResult.ts +0 -2
  376. package/src/lib/server/AppModule.ts +0 -47
  377. package/src/lib/server/DELETE.ts +0 -10
  378. package/src/lib/server/GET.ts +0 -10
  379. package/src/lib/server/HEAD.ts +0 -10
  380. package/src/lib/server/PATCH.ts +0 -10
  381. package/src/lib/server/POST.ts +0 -10
  382. package/src/lib/server/PUT.ts +0 -10
  383. package/src/lib/server/agent.ts +0 -86
  384. package/src/lib/server/appDataDir.ts +0 -16
  385. package/src/lib/server/cli/buildEnvContent.ts +0 -19
  386. package/src/lib/server/cli/createTarGz.ts +0 -77
  387. package/src/lib/server/cli/handleCliDownload.ts +0 -152
  388. package/src/lib/server/cli/handleCliInstall.ts +0 -37
  389. package/src/lib/server/cli/installScript.ts +0 -31
  390. package/src/lib/server/cli/maxSourceMtime.ts +0 -26
  391. package/src/lib/server/cookies.ts +0 -30
  392. package/src/lib/server/env.ts +0 -51
  393. package/src/lib/server/error.ts +0 -110
  394. package/src/lib/server/json.ts +0 -57
  395. package/src/lib/server/jsonl.ts +0 -47
  396. package/src/lib/server/prompts/definePrompt.ts +0 -21
  397. package/src/lib/server/prompts/promptRegistry.ts +0 -9
  398. package/src/lib/server/prompts/registerPrompt.ts +0 -6
  399. package/src/lib/server/prompts/renderPromptTemplate.ts +0 -17
  400. package/src/lib/server/prompts/types/Prompt.ts +0 -14
  401. package/src/lib/server/prompts/types/PromptOptions.ts +0 -12
  402. package/src/lib/server/prompts/types/PromptRegistryEntry.ts +0 -13
  403. package/src/lib/server/prompts/types/PromptRoutes.ts +0 -10
  404. package/src/lib/server/redirect.ts +0 -43
  405. package/src/lib/server/render.ts +0 -70
  406. package/src/lib/server/request.ts +0 -19
  407. package/src/lib/server/rpc/defineRpc.ts +0 -271
  408. package/src/lib/server/rpc/dispatchRpcInProcess.ts +0 -46
  409. package/src/lib/server/rpc/findRpcByCommandName.ts +0 -18
  410. package/src/lib/server/rpc/parseArgs.ts +0 -244
  411. package/src/lib/server/rpc/readBodyWithinLimit.ts +0 -47
  412. package/src/lib/server/rpc/registerRpc.ts +0 -6
  413. package/src/lib/server/rpc/resolveRpcJsonSchema.ts +0 -28
  414. package/src/lib/server/rpc/rpcRegistry.ts +0 -11
  415. package/src/lib/server/rpc/runWithRpcTimeout.ts +0 -58
  416. package/src/lib/server/rpc/types/RemoteHandler.ts +0 -31
  417. package/src/lib/server/rpc/types/RemoteRoutes.ts +0 -13
  418. package/src/lib/server/rpc/types/RpcHelper.ts +0 -185
  419. package/src/lib/server/rpc/types/RpcRegistryEntry.ts +0 -50
  420. package/src/lib/server/rpc/types/TypedError.ts +0 -18
  421. package/src/lib/server/rpc/types/TypedResponse.ts +0 -18
  422. package/src/lib/server/rpc/unprocessed.ts +0 -13
  423. package/src/lib/server/rpc/validationError.ts +0 -17
  424. package/src/lib/server/runtime/DEFAULT_PORT.ts +0 -6
  425. package/src/lib/server/runtime/DEV_READY_MESSAGE.ts +0 -6
  426. package/src/lib/server/runtime/DEV_REBUILD_MESSAGE.ts +0 -4
  427. package/src/lib/server/runtime/DEV_RELOAD_CLIENT_SCRIPT.ts +0 -92
  428. package/src/lib/server/runtime/SSR_SWAP_SCRIPT.ts +0 -19
  429. package/src/lib/server/runtime/STATUS_TEXT.ts +0 -22
  430. package/src/lib/server/runtime/STREAMED_HTML_HEADER.ts +0 -13
  431. package/src/lib/server/runtime/acceptsGzip.ts +0 -33
  432. package/src/lib/server/runtime/amendBroadcaster.ts +0 -53
  433. package/src/lib/server/runtime/buildCacheSnapshot.ts +0 -63
  434. package/src/lib/server/runtime/buildHealthPayload.ts +0 -34
  435. package/src/lib/server/runtime/buildInFlightSnapshot.ts +0 -35
  436. package/src/lib/server/runtime/buildInspectorSurface.ts +0 -47
  437. package/src/lib/server/runtime/buildOpenApiSpec.ts +0 -150
  438. package/src/lib/server/runtime/buildPreloadManifest.ts +0 -153
  439. package/src/lib/server/runtime/cacheControlForAsset.ts +0 -22
  440. package/src/lib/server/runtime/cacheStalenessBroadcaster.ts +0 -33
  441. package/src/lib/server/runtime/containsTraversal.ts +0 -41
  442. package/src/lib/server/runtime/createAppAssetServer.ts +0 -100
  443. package/src/lib/server/runtime/createAppRouteResolver.ts +0 -145
  444. package/src/lib/server/runtime/createAssetHeaderCache.ts +0 -31
  445. package/src/lib/server/runtime/createPlumbingRouter.ts +0 -212
  446. package/src/lib/server/runtime/createPublicAssetServer.ts +0 -76
  447. package/src/lib/server/runtime/createRouteDispatcher.ts +0 -121
  448. package/src/lib/server/runtime/createServer.ts +0 -605
  449. package/src/lib/server/runtime/createUiPageRenderer.ts +0 -489
  450. package/src/lib/server/runtime/crossOriginForbidden.ts +0 -17
  451. package/src/lib/server/runtime/crossOriginGate.ts +0 -29
  452. package/src/lib/server/runtime/devClientFingerprint.ts +0 -103
  453. package/src/lib/server/runtime/devReloadResponse.ts +0 -41
  454. package/src/lib/server/runtime/disableIdleTimeoutForStream.ts +0 -27
  455. package/src/lib/server/runtime/envSchemaStore.ts +0 -15
  456. package/src/lib/server/runtime/finalizeResponse.ts +0 -42
  457. package/src/lib/server/runtime/findOpenPort.ts +0 -21
  458. package/src/lib/server/runtime/flushingGzipStream.ts +0 -62
  459. package/src/lib/server/runtime/getActiveServer.ts +0 -6
  460. package/src/lib/server/runtime/globToPathSet.ts +0 -29
  461. package/src/lib/server/runtime/gzipResponse.ts +0 -57
  462. package/src/lib/server/runtime/inFlightRequests.ts +0 -13
  463. package/src/lib/server/runtime/inProcessServer.ts +0 -20
  464. package/src/lib/server/runtime/installAmbientScopeStore.ts +0 -54
  465. package/src/lib/server/runtime/internalErrorResponse.ts +0 -28
  466. package/src/lib/server/runtime/isCrossOriginRequest.ts +0 -23
  467. package/src/lib/server/runtime/listenOnOpenPort.ts +0 -36
  468. package/src/lib/server/runtime/logExposedSurfaces.ts +0 -156
  469. package/src/lib/server/runtime/maybeMountInspector.ts +0 -104
  470. package/src/lib/server/runtime/mimeForExtension.ts +0 -14
  471. package/src/lib/server/runtime/pageRenderSlot.ts +0 -15
  472. package/src/lib/server/runtime/pageUrlFromStore.ts +0 -15
  473. package/src/lib/server/runtime/parseIdleTimeout.ts +0 -10
  474. package/src/lib/server/runtime/parsePort.ts +0 -11
  475. package/src/lib/server/runtime/pathStore.ts +0 -15
  476. package/src/lib/server/runtime/registryManifests.ts +0 -66
  477. package/src/lib/server/runtime/renderCellBarrierStore.ts +0 -15
  478. package/src/lib/server/runtime/requestContext.ts +0 -5
  479. package/src/lib/server/runtime/resolvePageSnapshot.ts +0 -25
  480. package/src/lib/server/runtime/respondWithEmbeddedAsset.ts +0 -18
  481. package/src/lib/server/runtime/runWithRequestScope.ts +0 -165
  482. package/src/lib/server/runtime/serializeCacheSnapshot.ts +0 -31
  483. package/src/lib/server/runtime/serverSlot.ts +0 -13
  484. package/src/lib/server/runtime/setActiveServer.ts +0 -6
  485. package/src/lib/server/runtime/snapshotEntryFromCache.ts +0 -121
  486. package/src/lib/server/runtime/streamCacheResolutions.ts +0 -44
  487. package/src/lib/server/runtime/streamFromIterator.ts +0 -124
  488. package/src/lib/server/runtime/textResponse.ts +0 -23
  489. package/src/lib/server/runtime/typedErrorResponse.ts +0 -26
  490. package/src/lib/server/runtime/types/Assets.ts +0 -6
  491. package/src/lib/server/runtime/types/DevReloadStamp.ts +0 -14
  492. package/src/lib/server/runtime/types/InspectorCacheEntry.ts +0 -24
  493. package/src/lib/server/runtime/types/InspectorCacheSnapshot.ts +0 -11
  494. package/src/lib/server/runtime/types/InspectorContext.ts +0 -34
  495. package/src/lib/server/runtime/types/InspectorInFlightRequest.ts +0 -20
  496. package/src/lib/server/runtime/types/InspectorInFlightSnapshot.ts +0 -10
  497. package/src/lib/server/runtime/types/InspectorPrompt.ts +0 -15
  498. package/src/lib/server/runtime/types/InspectorRpc.ts +0 -27
  499. package/src/lib/server/runtime/types/InspectorSocket.ts +0 -17
  500. package/src/lib/server/runtime/types/InspectorSurface.ts +0 -16
  501. package/src/lib/server/runtime/types/RequestStore.ts +0 -125
  502. package/src/lib/server/runtime/warnUnguardedMcp.ts +0 -43
  503. package/src/lib/server/runtime/withResponseDefaults.ts +0 -29
  504. package/src/lib/server/server.ts +0 -33
  505. package/src/lib/server/socket.ts +0 -32
  506. package/src/lib/server/sockets/amendFamilyEntry.ts +0 -39
  507. package/src/lib/server/sockets/createSocketDispatcher.ts +0 -397
  508. package/src/lib/server/sockets/defineSocket.ts +0 -225
  509. package/src/lib/server/sockets/lookupSocket.ts +0 -6
  510. package/src/lib/server/sockets/registerSocket.ts +0 -18
  511. package/src/lib/server/sockets/socketOperations.ts +0 -36
  512. package/src/lib/server/sockets/socketRegistry.ts +0 -9
  513. package/src/lib/server/sockets/types/SocketOperation.ts +0 -22
  514. package/src/lib/server/sockets/types/SocketOptions.ts +0 -26
  515. package/src/lib/server/sockets/types/SocketRegistryEntry.ts +0 -19
  516. package/src/lib/server/sockets/types/SocketRoutes.ts +0 -10
  517. package/src/lib/server/sse.ts +0 -58
  518. package/src/lib/shared/ABIDE_PACKAGE_NAME.ts +0 -7
  519. package/src/lib/shared/ABIDE_VERSION.ts +0 -9
  520. package/src/lib/shared/AMEND_TOPIC_PREFIX.ts +0 -9
  521. package/src/lib/shared/ASYNC_CELL.ts +0 -5
  522. package/src/lib/shared/CACHE_CONTROL_VALUES.ts +0 -16
  523. package/src/lib/shared/CACHE_STALENESS_SOCKET.ts +0 -8
  524. package/src/lib/shared/CLI_PATH.ts +0 -7
  525. package/src/lib/shared/DEFER.ts +0 -8
  526. package/src/lib/shared/DEV_REBUILD_PATH.ts +0 -6
  527. package/src/lib/shared/DEV_RELOAD_PATH.ts +0 -6
  528. package/src/lib/shared/HEALTH_PATH.ts +0 -7
  529. package/src/lib/shared/HTTP_METHODS.ts +0 -6
  530. package/src/lib/shared/HttpError.ts +0 -30
  531. package/src/lib/shared/IDENTITY_PATH.ts +0 -6
  532. package/src/lib/shared/INSPECTOR_PATH.ts +0 -7
  533. package/src/lib/shared/MCP_PATH.ts +0 -6
  534. package/src/lib/shared/NAV_HEADER.ts +0 -8
  535. package/src/lib/shared/OFFLINE_HEADER.ts +0 -8
  536. package/src/lib/shared/PROXIED_SERVER_SUBDIRS.ts +0 -15
  537. package/src/lib/shared/REF_JSON_HEADER.ts +0 -9
  538. package/src/lib/shared/REF_JSON_TAGS.ts +0 -43
  539. package/src/lib/shared/REMOTE_FUNCTION.ts +0 -8
  540. package/src/lib/shared/REPLAYABLE_METHODS.ts +0 -12
  541. package/src/lib/shared/RESERVED_SOCKET_PREFIX.ts +0 -8
  542. package/src/lib/shared/RPC_ARGS_TYPE.ts +0 -7
  543. package/src/lib/shared/RPC_SHIM_GLOBALS.ts +0 -9
  544. package/src/lib/shared/SEEDS.ts +0 -33
  545. package/src/lib/shared/SOCKETS_PATH.ts +0 -7
  546. package/src/lib/shared/SOCKET_SEED.ts +0 -12
  547. package/src/lib/shared/SSR_SCRIPT_ID.ts +0 -11
  548. package/src/lib/shared/STREAMING_CONTENT_TYPES.ts +0 -12
  549. package/src/lib/shared/SocketDisconnectedError.ts +0 -13
  550. package/src/lib/shared/TEXT_PLAIN.ts +0 -7
  551. package/src/lib/shared/abideImportName.ts +0 -44
  552. package/src/lib/shared/abideLog.ts +0 -38
  553. package/src/lib/shared/activeCacheStore.ts +0 -12
  554. package/src/lib/shared/activePage.ts +0 -12
  555. package/src/lib/shared/amend.ts +0 -48
  556. package/src/lib/shared/amendBroadcastSlot.ts +0 -19
  557. package/src/lib/shared/appDataDir.ts +0 -34
  558. package/src/lib/shared/appNameSlot.ts +0 -10
  559. package/src/lib/shared/applyAmendLocally.ts +0 -20
  560. package/src/lib/shared/applyCacheStalenessLocally.ts +0 -18
  561. package/src/lib/shared/assertExhaustive.ts +0 -14
  562. package/src/lib/shared/attachRpcSelectorMethods.ts +0 -44
  563. package/src/lib/shared/attachSocketSelectorMethods.ts +0 -34
  564. package/src/lib/shared/augmentModule.ts +0 -18
  565. package/src/lib/shared/basePath.ts +0 -11
  566. package/src/lib/shared/basePathFromAppUrl.ts +0 -20
  567. package/src/lib/shared/baseSlot.ts +0 -9
  568. package/src/lib/shared/binaryDirEnvPath.ts +0 -12
  569. package/src/lib/shared/bodyValueForKind.ts +0 -34
  570. package/src/lib/shared/browserClientFlags.ts +0 -10
  571. package/src/lib/shared/buildArtifact.ts +0 -20
  572. package/src/lib/shared/buildRpcProxy.ts +0 -39
  573. package/src/lib/shared/buildRpcRequest.ts +0 -81
  574. package/src/lib/shared/buildSocketOverChannel.ts +0 -102
  575. package/src/lib/shared/bundleGraphFromMetafile.ts +0 -68
  576. package/src/lib/shared/bundleLayout.ts +0 -36
  577. package/src/lib/shared/cache.ts +0 -1584
  578. package/src/lib/shared/cacheEntryFromSnapshot.ts +0 -77
  579. package/src/lib/shared/cacheManagedSlot.ts +0 -10
  580. package/src/lib/shared/cacheReaderSocketSlot.ts +0 -11
  581. package/src/lib/shared/cacheStalenessSlot.ts +0 -21
  582. package/src/lib/shared/cacheStoreSlot.ts +0 -12
  583. package/src/lib/shared/cacheStores.ts +0 -10
  584. package/src/lib/shared/canonicalJson.ts +0 -86
  585. package/src/lib/shared/carriesBodyArgs.ts +0 -13
  586. package/src/lib/shared/changeAffectsClient.ts +0 -40
  587. package/src/lib/shared/clearLastConnection.ts +0 -7
  588. package/src/lib/shared/commandNameForUrl.ts +0 -17
  589. package/src/lib/shared/contentBodyKind.ts +0 -27
  590. package/src/lib/shared/contentTypeOf.ts +0 -6
  591. package/src/lib/shared/createCacheStore.ts +0 -147
  592. package/src/lib/shared/createChannelLog.ts +0 -146
  593. package/src/lib/shared/createLifecycleChannel.ts +0 -62
  594. package/src/lib/shared/createLivenessWatch.ts +0 -118
  595. package/src/lib/shared/createPushIterator.ts +0 -132
  596. package/src/lib/shared/createReachable.ts +0 -78
  597. package/src/lib/shared/createRemoteFunction.ts +0 -210
  598. package/src/lib/shared/createResolverSlot.ts +0 -30
  599. package/src/lib/shared/createRpcServerProgram.ts +0 -1007
  600. package/src/lib/shared/createSocketSubRegistry.ts +0 -112
  601. package/src/lib/shared/createSubscriber.ts +0 -55
  602. package/src/lib/shared/createTraceContext.ts +0 -21
  603. package/src/lib/shared/dataDirEnvPath.ts +0 -12
  604. package/src/lib/shared/debugGate.ts +0 -90
  605. package/src/lib/shared/decodeRefJson.ts +0 -112
  606. package/src/lib/shared/decodeResponse.ts +0 -54
  607. package/src/lib/shared/decodeWireBody.ts +0 -35
  608. package/src/lib/shared/detectRpcMethod.ts +0 -24
  609. package/src/lib/shared/detectTarget.ts +0 -27
  610. package/src/lib/shared/docSnapshotsSlot.ts +0 -13
  611. package/src/lib/shared/done.ts +0 -20
  612. package/src/lib/shared/emitLogRecord.ts +0 -217
  613. package/src/lib/shared/encodeRefJson.ts +0 -108
  614. package/src/lib/shared/encodeSeedValue.ts +0 -24
  615. package/src/lib/shared/encodeWireBody.ts +0 -18
  616. package/src/lib/shared/escapeHtml.ts +0 -15
  617. package/src/lib/shared/escapeRegex.ts +0 -9
  618. package/src/lib/shared/exeSuffix.ts +0 -9
  619. package/src/lib/shared/exitOnBuildFailure.ts +0 -18
  620. package/src/lib/shared/extraForwardHeaders.ts +0 -16
  621. package/src/lib/shared/fieldErrorsFromIssues.ts +0 -27
  622. package/src/lib/shared/fileName.ts +0 -9
  623. package/src/lib/shared/fileStem.ts +0 -11
  624. package/src/lib/shared/findExportCallSite.ts +0 -233
  625. package/src/lib/shared/formatTraceparent.ts +0 -6
  626. package/src/lib/shared/forwardHeaders.ts +0 -44
  627. package/src/lib/shared/generateDeclarations.ts +0 -72
  628. package/src/lib/shared/getRemoteMeta.ts +0 -5
  629. package/src/lib/shared/hasSeedableRequest.ts +0 -25
  630. package/src/lib/shared/health.ts +0 -179
  631. package/src/lib/shared/healthReadSlot.ts +0 -11
  632. package/src/lib/shared/healthSeedSlot.ts +0 -12
  633. package/src/lib/shared/html.ts +0 -19
  634. package/src/lib/shared/httpErrorFor.ts +0 -26
  635. package/src/lib/shared/hydrationWindow.ts +0 -53
  636. package/src/lib/shared/importNamesToStrip.ts +0 -13
  637. package/src/lib/shared/invalidate.ts +0 -39
  638. package/src/lib/shared/invalidateEvent.ts +0 -11
  639. package/src/lib/shared/invalidateTripwire.ts +0 -40
  640. package/src/lib/shared/isAbideHealthPayload.ts +0 -11
  641. package/src/lib/shared/isAsciiWhitespace.ts +0 -5
  642. package/src/lib/shared/isAsyncCell.ts +0 -11
  643. package/src/lib/shared/isAsyncIterable.ts +0 -8
  644. package/src/lib/shared/isCompileTarget.ts +0 -21
  645. package/src/lib/shared/isDebugEnabled.ts +0 -19
  646. package/src/lib/shared/isDebugNegated.ts +0 -17
  647. package/src/lib/shared/isIdentPart.ts +0 -9
  648. package/src/lib/shared/isIdentStart.ts +0 -8
  649. package/src/lib/shared/isLayoutFile.ts +0 -12
  650. package/src/lib/shared/isModuleNotFound.ts +0 -18
  651. package/src/lib/shared/isReadOnlyMethod.ts +0 -14
  652. package/src/lib/shared/isReplayableMethod.ts +0 -7
  653. package/src/lib/shared/isStreamingResponse.ts +0 -12
  654. package/src/lib/shared/isSubscribable.ts +0 -15
  655. package/src/lib/shared/isThenable.ts +0 -9
  656. package/src/lib/shared/jsonSchemaForPromptArguments.ts +0 -29
  657. package/src/lib/shared/jsonSchemaForSchema.ts +0 -39
  658. package/src/lib/shared/jsonSchemaForType.ts +0 -245
  659. package/src/lib/shared/jsonlErrorFrame.ts +0 -24
  660. package/src/lib/shared/keyForRemoteCall.ts +0 -30
  661. package/src/lib/shared/keyMatchesPrefix.ts +0 -9
  662. package/src/lib/shared/keyPrefixForRemote.ts +0 -12
  663. package/src/lib/shared/lastConnectionPath.ts +0 -7
  664. package/src/lib/shared/layoutChainForRoute.ts +0 -22
  665. package/src/lib/shared/lenientDecode.ts +0 -15
  666. package/src/lib/shared/loadEnvFile.ts +0 -17
  667. package/src/lib/shared/loadEnvFromDataDir.ts +0 -14
  668. package/src/lib/shared/loadProjectTsConfig.ts +0 -28
  669. package/src/lib/shared/log.ts +0 -24
  670. package/src/lib/shared/logClosingRecord.ts +0 -28
  671. package/src/lib/shared/logTapSlot.ts +0 -13
  672. package/src/lib/shared/manifestModule.ts +0 -39
  673. package/src/lib/shared/markFrameworkSourcesIgnored.ts +0 -47
  674. package/src/lib/shared/matchRoute.ts +0 -165
  675. package/src/lib/shared/matcherFromEnvelope.ts +0 -31
  676. package/src/lib/shared/memoizeByKey.ts +0 -32
  677. package/src/lib/shared/messageFromError.ts +0 -6
  678. package/src/lib/shared/normalizePathname.ts +0 -11
  679. package/src/lib/shared/normalizeTarget.ts +0 -10
  680. package/src/lib/shared/online.ts +0 -51
  681. package/src/lib/shared/page.ts +0 -30
  682. package/src/lib/shared/pageSlot.ts +0 -17
  683. package/src/lib/shared/pageUrlForFile.ts +0 -14
  684. package/src/lib/shared/parseBoundedEnvInt.ts +0 -20
  685. package/src/lib/shared/parseEnv.ts +0 -41
  686. package/src/lib/shared/parsePromptMarkdown.ts +0 -35
  687. package/src/lib/shared/parseRouteSegments.ts +0 -31
  688. package/src/lib/shared/parseTraceparent.ts +0 -26
  689. package/src/lib/shared/peek.ts +0 -46
  690. package/src/lib/shared/pending.ts +0 -36
  691. package/src/lib/shared/pendingAsyncCellsSlot.ts +0 -13
  692. package/src/lib/shared/prepareRemoteExport.ts +0 -40
  693. package/src/lib/shared/prepareRpcModule.ts +0 -240
  694. package/src/lib/shared/prepareSocketModule.ts +0 -46
  695. package/src/lib/shared/probeRegistries.ts +0 -68
  696. package/src/lib/shared/producerKey.ts +0 -32
  697. package/src/lib/shared/programNameForPackage.ts +0 -16
  698. package/src/lib/shared/promptNameForFile.ts +0 -10
  699. package/src/lib/shared/queryStringFromArgs.ts +0 -38
  700. package/src/lib/shared/randomHexId.ts +0 -14
  701. package/src/lib/shared/reachable.ts +0 -99
  702. package/src/lib/shared/readEnvFile.ts +0 -15
  703. package/src/lib/shared/readLastConnection.ts +0 -18
  704. package/src/lib/shared/readPackageJson.ts +0 -9
  705. package/src/lib/shared/recordRemoteMeta.ts +0 -5
  706. package/src/lib/shared/refresh.ts +0 -39
  707. package/src/lib/shared/refreshing.ts +0 -37
  708. package/src/lib/shared/remoteMetaStore.ts +0 -16
  709. package/src/lib/shared/requestScopeSlot.ts +0 -13
  710. package/src/lib/shared/resolveClientFlags.ts +0 -20
  711. package/src/lib/shared/resolvedCellsSlot.ts +0 -13
  712. package/src/lib/shared/responseBodyKind.ts +0 -35
  713. package/src/lib/shared/responseErrorText.ts +0 -9
  714. package/src/lib/shared/reviveWireField.ts +0 -49
  715. package/src/lib/shared/reviveWireOutput.ts +0 -36
  716. package/src/lib/shared/routeParamsShape.ts +0 -20
  717. package/src/lib/shared/rpcErrorRegistry.ts +0 -69
  718. package/src/lib/shared/rpcServerForRoot.ts +0 -25
  719. package/src/lib/shared/rpcTimeoutSlot.ts +0 -9
  720. package/src/lib/shared/rpcUrlForFile.ts +0 -19
  721. package/src/lib/shared/runningAsStandaloneBinary.ts +0 -13
  722. package/src/lib/shared/safeJsonForScript.ts +0 -17
  723. package/src/lib/shared/scanPages.ts +0 -25
  724. package/src/lib/shared/selectorMatcher.ts +0 -55
  725. package/src/lib/shared/selectorPrefix.ts +0 -32
  726. package/src/lib/shared/serializeEnv.ts +0 -30
  727. package/src/lib/shared/serializeSelector.ts +0 -69
  728. package/src/lib/shared/setAppName.ts +0 -5
  729. package/src/lib/shared/setOwnProperty.ts +0 -19
  730. package/src/lib/shared/setsIntersect.ts +0 -15
  731. package/src/lib/shared/sharedCacheStore.ts +0 -14
  732. package/src/lib/shared/sharedCacheStoreSlot.ts +0 -10
  733. package/src/lib/shared/skipNonCode.ts +0 -230
  734. package/src/lib/shared/snapshotShippable.ts +0 -23
  735. package/src/lib/shared/snippet.ts +0 -30
  736. package/src/lib/shared/socketNameForFile.ts +0 -11
  737. package/src/lib/shared/socketTailsSlot.ts +0 -13
  738. package/src/lib/shared/socketTapSlot.ts +0 -12
  739. package/src/lib/shared/sseErrorFrame.ts +0 -29
  740. package/src/lib/shared/streamResponse.ts +0 -180
  741. package/src/lib/shared/streamedCellsSlot.ts +0 -14
  742. package/src/lib/shared/stripImport.ts +0 -29
  743. package/src/lib/shared/subscribableFromResponse.ts +0 -51
  744. package/src/lib/shared/subscribableProbes.ts +0 -111
  745. package/src/lib/shared/tailProbeSlot.ts +0 -23
  746. package/src/lib/shared/toTagSet.ts +0 -4
  747. package/src/lib/shared/trace.ts +0 -16
  748. package/src/lib/shared/types/AmendApply.ts +0 -15
  749. package/src/lib/shared/types/AsyncComputed.ts +0 -20
  750. package/src/lib/shared/types/AsyncState.ts +0 -13
  751. package/src/lib/shared/types/CacheEntry.ts +0 -100
  752. package/src/lib/shared/types/CacheInvalidation.ts +0 -9
  753. package/src/lib/shared/types/CacheOnContext.ts +0 -15
  754. package/src/lib/shared/types/CacheOptions.ts +0 -53
  755. package/src/lib/shared/types/CachePolicy.ts +0 -31
  756. package/src/lib/shared/types/CacheReaderHook.ts +0 -11
  757. package/src/lib/shared/types/CacheSelector.ts +0 -17
  758. package/src/lib/shared/types/CacheSnapshotEntry.ts +0 -32
  759. package/src/lib/shared/types/CacheStalenessApply.ts +0 -13
  760. package/src/lib/shared/types/CacheStalenessFrame.ts +0 -24
  761. package/src/lib/shared/types/CacheStats.ts +0 -13
  762. package/src/lib/shared/types/CacheStore.ts +0 -45
  763. package/src/lib/shared/types/ChannelLog.ts +0 -13
  764. package/src/lib/shared/types/ClientFlags.ts +0 -13
  765. package/src/lib/shared/types/CompileTarget.ts +0 -6
  766. package/src/lib/shared/types/DebugGate.ts +0 -10
  767. package/src/lib/shared/types/DocSnapshots.ts +0 -12
  768. package/src/lib/shared/types/ErrorJsonSchemas.ts +0 -8
  769. package/src/lib/shared/types/ErrorSpec.ts +0 -11
  770. package/src/lib/shared/types/FrameworkLog.ts +0 -13
  771. package/src/lib/shared/types/HttpMethod.ts +0 -3
  772. package/src/lib/shared/types/InputCoercion.ts +0 -17
  773. package/src/lib/shared/types/LastConnection.ts +0 -9
  774. package/src/lib/shared/types/Log.ts +0 -13
  775. package/src/lib/shared/types/LogRecord.ts +0 -42
  776. package/src/lib/shared/types/LogVoice.ts +0 -7
  777. package/src/lib/shared/types/NamedAsyncIterable.ts +0 -26
  778. package/src/lib/shared/types/OutputWirePlan.ts +0 -17
  779. package/src/lib/shared/types/PageSnapshot.ts +0 -14
  780. package/src/lib/shared/types/PagesScan.ts +0 -7
  781. package/src/lib/shared/types/PendingAsyncCells.ts +0 -10
  782. package/src/lib/shared/types/PromptArgument.ts +0 -12
  783. package/src/lib/shared/types/RawRemoteFunction.ts +0 -20
  784. package/src/lib/shared/types/RemoteCallable.ts +0 -40
  785. package/src/lib/shared/types/RemoteFunction.ts +0 -116
  786. package/src/lib/shared/types/ReplayableMethod.ts +0 -7
  787. package/src/lib/shared/types/RequestScopeInfo.ts +0 -16
  788. package/src/lib/shared/types/ResolvedCells.ts +0 -11
  789. package/src/lib/shared/types/ResolverSlot.ts +0 -13
  790. package/src/lib/shared/types/ReturnBody.ts +0 -15
  791. package/src/lib/shared/types/RpcBuildStamps.ts +0 -32
  792. package/src/lib/shared/types/RpcError.ts +0 -26
  793. package/src/lib/shared/types/RpcErrorGuard.ts +0 -35
  794. package/src/lib/shared/types/RpcInvoker.ts +0 -6
  795. package/src/lib/shared/types/RpcOptions.ts +0 -22
  796. package/src/lib/shared/types/Socket.ts +0 -54
  797. package/src/lib/shared/types/SocketChannel.ts +0 -17
  798. package/src/lib/shared/types/SocketClientFrame.ts +0 -19
  799. package/src/lib/shared/types/SocketServerFrame.ts +0 -24
  800. package/src/lib/shared/types/SocketSubCallbacks.ts +0 -13
  801. package/src/lib/shared/types/SocketTails.ts +0 -13
  802. package/src/lib/shared/types/SourceMap.ts +0 -14
  803. package/src/lib/shared/types/SsrBootState.ts +0 -27
  804. package/src/lib/shared/types/SsrPayload.ts +0 -36
  805. package/src/lib/shared/types/StandardSchemaV1.ts +0 -56
  806. package/src/lib/shared/types/StreamPolicy.ts +0 -11
  807. package/src/lib/shared/types/StreamedCells.ts +0 -19
  808. package/src/lib/shared/types/StreamedResolution.ts +0 -28
  809. package/src/lib/shared/types/TailHooks.ts +0 -13
  810. package/src/lib/shared/types/TraceContext.ts +0 -17
  811. package/src/lib/shared/types/ValidationErrorData.ts +0 -20
  812. package/src/lib/shared/types/WireKind.ts +0 -11
  813. package/src/lib/shared/url.ts +0 -141
  814. package/src/lib/shared/validationHttpError.ts +0 -33
  815. package/src/lib/shared/warmSeedKey.ts +0 -16
  816. package/src/lib/shared/wireJsonReplacer.ts +0 -30
  817. package/src/lib/shared/withBase.ts +0 -10
  818. package/src/lib/shared/withBaseUrl.ts +0 -17
  819. package/src/lib/shared/withCacheManaged.ts +0 -18
  820. package/src/lib/shared/withJsonSchema.ts +0 -21
  821. package/src/lib/shared/writeDts.ts +0 -19
  822. package/src/lib/shared/writeHealthDts.ts +0 -36
  823. package/src/lib/shared/writeLastConnection.ts +0 -13
  824. package/src/lib/shared/writePublicAssetsDts.ts +0 -27
  825. package/src/lib/shared/writeRoutesDts.ts +0 -41
  826. package/src/lib/shared/writeRpcDts.ts +0 -60
  827. package/src/lib/shared/writeTestRpcDts.ts +0 -45
  828. package/src/lib/shared/writeTestSocketsDts.ts +0 -34
  829. package/src/lib/test/assertAgentFrameConformance.ts +0 -73
  830. package/src/lib/test/createScriptedSurface.ts +0 -45
  831. package/src/lib/test/createTestApp.ts +0 -242
  832. package/src/lib/test/createTestSocketChannel.ts +0 -85
  833. package/src/lib/ui/README.md +0 -86
  834. package/src/lib/ui/activePendingCells.ts +0 -14
  835. package/src/lib/ui/amendReaderHook.ts +0 -125
  836. package/src/lib/ui/compile/ABIDE_SEMANTIC_TOKENS_LEGEND.ts +0 -79
  837. package/src/lib/ui/compile/AbideCompileError.ts +0 -16
  838. package/src/lib/ui/compile/BLOCK_KEYWORDS.ts +0 -21
  839. package/src/lib/ui/compile/SSR_ESCAPE.ts +0 -40
  840. package/src/lib/ui/compile/TS_PRINTER.ts +0 -7
  841. package/src/lib/ui/compile/UI_RUNTIME_IMPORTS.ts +0 -86
  842. package/src/lib/ui/compile/VOID_TAGS.ts +0 -22
  843. package/src/lib/ui/compile/abideUiPlugin.ts +0 -109
  844. package/src/lib/ui/compile/analyzeComponent.ts +0 -222
  845. package/src/lib/ui/compile/asOutlet.ts +0 -30
  846. package/src/lib/ui/compile/assertTranspiles.ts +0 -19
  847. package/src/lib/ui/compile/assetModulesFile.ts +0 -32
  848. package/src/lib/ui/compile/assignmentTargetNames.ts +0 -54
  849. package/src/lib/ui/compile/asyncInterpolationFields.ts +0 -152
  850. package/src/lib/ui/compile/asyncValuePositionError.ts +0 -21
  851. package/src/lib/ui/compile/asyncValuePositionInterpolations.ts +0 -64
  852. package/src/lib/ui/compile/attrLiftPosition.ts +0 -18
  853. package/src/lib/ui/compile/awaitPlan.ts +0 -60
  854. package/src/lib/ui/compile/awaitSubjectExpr.ts +0 -23
  855. package/src/lib/ui/compile/bindListenEvent.ts +0 -18
  856. package/src/lib/ui/compile/cachedShadowProgram.ts +0 -39
  857. package/src/lib/ui/compile/cachedSourceFile.ts +0 -40
  858. package/src/lib/ui/compile/catchBinding.ts +0 -10
  859. package/src/lib/ui/compile/classStyleMergePlan.ts +0 -108
  860. package/src/lib/ui/compile/classifyInterpolationType.ts +0 -46
  861. package/src/lib/ui/compile/collectAbideDiagnostics.ts +0 -166
  862. package/src/lib/ui/compile/compileComponent.ts +0 -46
  863. package/src/lib/ui/compile/compileModule.ts +0 -306
  864. package/src/lib/ui/compile/compileSSR.ts +0 -119
  865. package/src/lib/ui/compile/compileShadow.ts +0 -1326
  866. package/src/lib/ui/compile/componentOrdinals.ts +0 -39
  867. package/src/lib/ui/compile/composeProps.ts +0 -64
  868. package/src/lib/ui/compile/createShadowLanguageService.ts +0 -348
  869. package/src/lib/ui/compile/createShadowProgram.ts +0 -127
  870. package/src/lib/ui/compile/createShadowScope.ts +0 -42
  871. package/src/lib/ui/compile/declaredNames.ts +0 -36
  872. package/src/lib/ui/compile/decodeHtmlEntities.ts +0 -53
  873. package/src/lib/ui/compile/destructureBindingNames.ts +0 -38
  874. package/src/lib/ui/compile/desugarSignals.ts +0 -1113
  875. package/src/lib/ui/compile/eachPlan.ts +0 -61
  876. package/src/lib/ui/compile/elementPlan.ts +0 -55
  877. package/src/lib/ui/compile/encodeSemanticTokens.ts +0 -60
  878. package/src/lib/ui/compile/expressionIsPrefixEvaluable.ts +0 -19
  879. package/src/lib/ui/compile/generateBuild.ts +0 -903
  880. package/src/lib/ui/compile/generateSSR.ts +0 -973
  881. package/src/lib/ui/compile/groupBindParts.ts +0 -28
  882. package/src/lib/ui/compile/hasTopLevelAwait.ts +0 -28
  883. package/src/lib/ui/compile/hoistCells.ts +0 -120
  884. package/src/lib/ui/compile/hoistableAwaits.ts +0 -183
  885. package/src/lib/ui/compile/hoistableChildRenders.ts +0 -112
  886. package/src/lib/ui/compile/identifierReferencePattern.ts +0 -13
  887. package/src/lib/ui/compile/ifPlan.ts +0 -36
  888. package/src/lib/ui/compile/interpolatedTemplateLiteral.ts +0 -27
  889. package/src/lib/ui/compile/interpolationClassifierForRoot.ts +0 -32
  890. package/src/lib/ui/compile/isAnchorPositioned.ts +0 -19
  891. package/src/lib/ui/compile/isControlFlow.ts +0 -20
  892. package/src/lib/ui/compile/isFunctionScopeBoundary.ts +0 -20
  893. package/src/lib/ui/compile/isPlainIdentifier.ts +0 -7
  894. package/src/lib/ui/compile/isSpuriousAsyncReadDiagnostic.ts +0 -215
  895. package/src/lib/ui/compile/isTextLeaf.ts +0 -16
  896. package/src/lib/ui/compile/isWhitespaceText.ts +0 -19
  897. package/src/lib/ui/compile/liftAsyncSubExpressions.ts +0 -166
  898. package/src/lib/ui/compile/liftScriptSeed.ts +0 -47
  899. package/src/lib/ui/compile/loadShadowTsConfig.ts +0 -31
  900. package/src/lib/ui/compile/lowerAsyncInterpolations.ts +0 -92
  901. package/src/lib/ui/compile/lowerCompoundAssignment.ts +0 -49
  902. package/src/lib/ui/compile/lowerContext.ts +0 -167
  903. package/src/lib/ui/compile/lowerDocAccess.ts +0 -302
  904. package/src/lib/ui/compile/lowerScript.ts +0 -190
  905. package/src/lib/ui/compile/lowerUpdateExpression.ts +0 -32
  906. package/src/lib/ui/compile/makeVarNamer.ts +0 -10
  907. package/src/lib/ui/compile/nearestProjectRoot.ts +0 -16
  908. package/src/lib/ui/compile/nodeAtShadowOffset.ts +0 -28
  909. package/src/lib/ui/compile/offsetToLineColumn.ts +0 -16
  910. package/src/lib/ui/compile/offsetToPosition.ts +0 -9
  911. package/src/lib/ui/compile/pagePropsType.ts +0 -23
  912. package/src/lib/ui/compile/parseTemplate.ts +0 -25
  913. package/src/lib/ui/compile/parseTemplateRecovering.ts +0 -1385
  914. package/src/lib/ui/compile/prepareNestedScript.ts +0 -62
  915. package/src/lib/ui/compile/reactiveBinding.ts +0 -47
  916. package/src/lib/ui/compile/referencedIdentifiers.ts +0 -35
  917. package/src/lib/ui/compile/remapShadowDiagnostic.ts +0 -30
  918. package/src/lib/ui/compile/renameSignalRefs.ts +0 -425
  919. package/src/lib/ui/compile/resolveAbideImports.ts +0 -29
  920. package/src/lib/ui/compile/resolveBranches.ts +0 -21
  921. package/src/lib/ui/compile/resolveReactiveExport.ts +0 -92
  922. package/src/lib/ui/compile/scopeAttr.ts +0 -9
  923. package/src/lib/ui/compile/scopeCss.ts +0 -138
  924. package/src/lib/ui/compile/seedTypeClassifierForRoot.ts +0 -60
  925. package/src/lib/ui/compile/shadowInterpolationClassifier.ts +0 -47
  926. package/src/lib/ui/compile/shadowNaming.ts +0 -11
  927. package/src/lib/ui/compile/signalCallee.ts +0 -24
  928. package/src/lib/ui/compile/skeletonContext.ts +0 -133
  929. package/src/lib/ui/compile/skeletonable.ts +0 -68
  930. package/src/lib/ui/compile/snippetPlan.ts +0 -28
  931. package/src/lib/ui/compile/sourceFileOptionsSignature.ts +0 -20
  932. package/src/lib/ui/compile/sourceToShadowOffset.ts +0 -24
  933. package/src/lib/ui/compile/spreadExcludedNames.ts +0 -27
  934. package/src/lib/ui/compile/staticAttr.ts +0 -11
  935. package/src/lib/ui/compile/staticAttrValue.ts +0 -13
  936. package/src/lib/ui/compile/staticTextPart.ts +0 -12
  937. package/src/lib/ui/compile/stripEffects.ts +0 -48
  938. package/src/lib/ui/compile/structuralHeadTokens.ts +0 -107
  939. package/src/lib/ui/compile/switchPlan.ts +0 -28
  940. package/src/lib/ui/compile/templateAnchorAdapter.ts +0 -61
  941. package/src/lib/ui/compile/templateElementAdapter.ts +0 -44
  942. package/src/lib/ui/compile/templateSemanticTokens.ts +0 -21
  943. package/src/lib/ui/compile/templateStartOffset.ts +0 -15
  944. package/src/lib/ui/compile/tryPlan.ts +0 -37
  945. package/src/lib/ui/compile/types/AbideDiagnostic.ts +0 -14
  946. package/src/lib/ui/compile/types/AnalyzedComponent.ts +0 -42
  947. package/src/lib/ui/compile/types/AsyncInterpolationField.ts +0 -19
  948. package/src/lib/ui/compile/types/Binding.ts +0 -24
  949. package/src/lib/ui/compile/types/CompiledShadow.ts +0 -27
  950. package/src/lib/ui/compile/types/ElementPlan.ts +0 -43
  951. package/src/lib/ui/compile/types/InterpolationClassifier.ts +0 -12
  952. package/src/lib/ui/compile/types/InterpolationKind.ts +0 -7
  953. package/src/lib/ui/compile/types/ParseDiagnostic.ts +0 -8
  954. package/src/lib/ui/compile/types/SeedTypeClassifier.ts +0 -15
  955. package/src/lib/ui/compile/types/SemanticToken.ts +0 -11
  956. package/src/lib/ui/compile/types/ShadowKind.ts +0 -9
  957. package/src/lib/ui/compile/types/ShadowScope.ts +0 -19
  958. package/src/lib/ui/compile/types/SkeletonContext.ts +0 -21
  959. package/src/lib/ui/compile/types/TemplateAttr.ts +0 -34
  960. package/src/lib/ui/compile/types/TemplateNode.ts +0 -137
  961. package/src/lib/ui/compile/types/TextPart.ts +0 -8
  962. package/src/lib/ui/compile/types/ValuePositionInterpolation.ts +0 -13
  963. package/src/lib/ui/compile/unwrapParens.ts +0 -10
  964. package/src/lib/ui/compile/walkAnchorOrder.ts +0 -57
  965. package/src/lib/ui/compile/walkElementOrder.ts +0 -60
  966. package/src/lib/ui/compile/withBindings.ts +0 -45
  967. package/src/lib/ui/compile/wrapReactionCellSources.ts +0 -121
  968. package/src/lib/ui/compile/wrapReactiveSeeds.ts +0 -44
  969. package/src/lib/ui/compile/wrapSeed.ts +0 -28
  970. package/src/lib/ui/compile/writtenTemplateNames.ts +0 -84
  971. package/src/lib/ui/computed.ts +0 -75
  972. package/src/lib/ui/createScope.ts +0 -157
  973. package/src/lib/ui/dom/MATHML_NAMESPACE.ts +0 -6
  974. package/src/lib/ui/dom/SVG_NAMESPACE.ts +0 -8
  975. package/src/lib/ui/dom/adoptRange.ts +0 -27
  976. package/src/lib/ui/dom/anchorCursor.ts +0 -25
  977. package/src/lib/ui/dom/anchoredBranch.ts +0 -153
  978. package/src/lib/ui/dom/appendSnippet.ts +0 -75
  979. package/src/lib/ui/dom/appendStatic.ts +0 -26
  980. package/src/lib/ui/dom/appendText.ts +0 -160
  981. package/src/lib/ui/dom/appendTextAt.ts +0 -39
  982. package/src/lib/ui/dom/assertClaimedText.ts +0 -30
  983. package/src/lib/ui/dom/attach.ts +0 -25
  984. package/src/lib/ui/dom/attr.ts +0 -57
  985. package/src/lib/ui/dom/awaitBlock.ts +0 -314
  986. package/src/lib/ui/dom/awaitSubject.ts +0 -118
  987. package/src/lib/ui/dom/bindProp.ts +0 -22
  988. package/src/lib/ui/dom/bindSelectValue.ts +0 -48
  989. package/src/lib/ui/dom/bindableProp.ts +0 -47
  990. package/src/lib/ui/dom/buildDetachedRange.ts +0 -31
  991. package/src/lib/ui/dom/cellPending.ts +0 -24
  992. package/src/lib/ui/dom/claimText.ts +0 -38
  993. package/src/lib/ui/dom/clearBetween.ts +0 -16
  994. package/src/lib/ui/dom/cloneStatic.ts +0 -69
  995. package/src/lib/ui/dom/commentData.ts +0 -14
  996. package/src/lib/ui/dom/depthZeroNodes.ts +0 -34
  997. package/src/lib/ui/dom/discardAndRebuild.ts +0 -23
  998. package/src/lib/ui/dom/discardBoundary.ts +0 -46
  999. package/src/lib/ui/dom/disposeRange.ts +0 -18
  1000. package/src/lib/ui/dom/domAnchorAdapter.ts +0 -29
  1001. package/src/lib/ui/dom/domElementAdapter.ts +0 -20
  1002. package/src/lib/ui/dom/each.ts +0 -253
  1003. package/src/lib/ui/dom/eachAsync.ts +0 -188
  1004. package/src/lib/ui/dom/effectiveChildNamespace.ts +0 -13
  1005. package/src/lib/ui/dom/enterNamespace.ts +0 -20
  1006. package/src/lib/ui/dom/fillBefore.ts +0 -42
  1007. package/src/lib/ui/dom/fillBoundary.ts +0 -38
  1008. package/src/lib/ui/dom/fillRange.ts +0 -30
  1009. package/src/lib/ui/dom/foreignWrapperTag.ts +0 -22
  1010. package/src/lib/ui/dom/hydrate.ts +0 -34
  1011. package/src/lib/ui/dom/inheritedNamespace.ts +0 -19
  1012. package/src/lib/ui/dom/isComment.ts +0 -6
  1013. package/src/lib/ui/dom/isElement.ts +0 -6
  1014. package/src/lib/ui/dom/markerDepthDelta.ts +0 -19
  1015. package/src/lib/ui/dom/matchingRangeClose.ts +0 -29
  1016. package/src/lib/ui/dom/mergeProps.ts +0 -32
  1017. package/src/lib/ui/dom/mount.ts +0 -30
  1018. package/src/lib/ui/dom/mountChild.ts +0 -129
  1019. package/src/lib/ui/dom/mountRange.ts +0 -48
  1020. package/src/lib/ui/dom/mountSlot.ts +0 -38
  1021. package/src/lib/ui/dom/mountSwappableRange.ts +0 -122
  1022. package/src/lib/ui/dom/moveRange.ts +0 -19
  1023. package/src/lib/ui/dom/mutateDocContainer.ts +0 -65
  1024. package/src/lib/ui/dom/on.ts +0 -33
  1025. package/src/lib/ui/dom/openMarker.ts +0 -22
  1026. package/src/lib/ui/dom/outlet.ts +0 -63
  1027. package/src/lib/ui/dom/parseRawNodes.ts +0 -17
  1028. package/src/lib/ui/dom/readCall.ts +0 -29
  1029. package/src/lib/ui/dom/readCell.ts +0 -55
  1030. package/src/lib/ui/dom/readTextOrSuspend.ts +0 -21
  1031. package/src/lib/ui/dom/removeRange.ts +0 -18
  1032. package/src/lib/ui/dom/replaceRange.ts +0 -24
  1033. package/src/lib/ui/dom/restProps.ts +0 -32
  1034. package/src/lib/ui/dom/skeleton.ts +0 -153
  1035. package/src/lib/ui/dom/spreadAttrs.ts +0 -95
  1036. package/src/lib/ui/dom/spreadProps.ts +0 -31
  1037. package/src/lib/ui/dom/switchBlock.ts +0 -80
  1038. package/src/lib/ui/dom/templateFor.ts +0 -28
  1039. package/src/lib/ui/dom/tryBlock.ts +0 -263
  1040. package/src/lib/ui/dom/types/EachRow.ts +0 -21
  1041. package/src/lib/ui/dom/types/SkeletonHoles.ts +0 -10
  1042. package/src/lib/ui/dom/types/SwitchCase.ts +0 -11
  1043. package/src/lib/ui/dom/when.ts +0 -58
  1044. package/src/lib/ui/dom/withScope.ts +0 -37
  1045. package/src/lib/ui/dom/withSuspense.ts +0 -22
  1046. package/src/lib/ui/dom/writeCell.ts +0 -22
  1047. package/src/lib/ui/effect.ts +0 -24
  1048. package/src/lib/ui/enterScope.ts +0 -18
  1049. package/src/lib/ui/exitScope.ts +0 -8
  1050. package/src/lib/ui/finalizeStreamedChildren.ts +0 -88
  1051. package/src/lib/ui/flight.ts +0 -56
  1052. package/src/lib/ui/html.ts +0 -39
  1053. package/src/lib/ui/isolateCellBarrier.ts +0 -17
  1054. package/src/lib/ui/linked.ts +0 -125
  1055. package/src/lib/ui/navigate.ts +0 -77
  1056. package/src/lib/ui/probeNavigation.ts +0 -33
  1057. package/src/lib/ui/props.ts +0 -17
  1058. package/src/lib/ui/remoteProxy.ts +0 -256
  1059. package/src/lib/ui/renderChain.ts +0 -113
  1060. package/src/lib/ui/renderToStream.ts +0 -128
  1061. package/src/lib/ui/resumeSeedScript.ts +0 -27
  1062. package/src/lib/ui/router.ts +0 -649
  1063. package/src/lib/ui/runtime/AsyncCellError.ts +0 -21
  1064. package/src/lib/ui/runtime/BRANCH_SEGMENT.ts +0 -24
  1065. package/src/lib/ui/runtime/CELL_SEED.ts +0 -12
  1066. package/src/lib/ui/runtime/CHILD_PRESENT.ts +0 -8
  1067. package/src/lib/ui/runtime/CURRENT_BOUNDARY.ts +0 -11
  1068. package/src/lib/ui/runtime/CURRENT_PATH.ts +0 -29
  1069. package/src/lib/ui/runtime/CURRENT_SCOPE.ts +0 -23
  1070. package/src/lib/ui/runtime/DOC_SEED.ts +0 -10
  1071. package/src/lib/ui/runtime/HOLE_ATTRIBUTE.ts +0 -9
  1072. package/src/lib/ui/runtime/NODE_STATE.ts +0 -22
  1073. package/src/lib/ui/runtime/OUTLET_MARKER.ts +0 -10
  1074. package/src/lib/ui/runtime/OUTLET_TAG.ts +0 -7
  1075. package/src/lib/ui/runtime/OWNER.ts +0 -8
  1076. package/src/lib/ui/runtime/PENDING_OUTLET.ts +0 -8
  1077. package/src/lib/ui/runtime/RANGE_MARKER.ts +0 -18
  1078. package/src/lib/ui/runtime/REACTIVE_CONTEXT.ts +0 -20
  1079. package/src/lib/ui/runtime/RENDER.ts +0 -35
  1080. package/src/lib/ui/runtime/REQUEST_SUPERSEDED.ts +0 -8
  1081. package/src/lib/ui/runtime/RESUME.ts +0 -21
  1082. package/src/lib/ui/runtime/SEED_MARKS.ts +0 -14
  1083. package/src/lib/ui/runtime/STREAMED_CELLS.ts +0 -57
  1084. package/src/lib/ui/runtime/SuspenseSignal.ts +0 -24
  1085. package/src/lib/ui/runtime/abortNode.ts +0 -22
  1086. package/src/lib/ui/runtime/ambientPathBacking.ts +0 -32
  1087. package/src/lib/ui/runtime/ambientScopeBacking.ts +0 -26
  1088. package/src/lib/ui/runtime/applyPatchToTree.ts +0 -54
  1089. package/src/lib/ui/runtime/batch.ts +0 -22
  1090. package/src/lib/ui/runtime/blockId.ts +0 -31
  1091. package/src/lib/ui/runtime/boundaryFor.ts +0 -11
  1092. package/src/lib/ui/runtime/cellBarrierBacking.ts +0 -30
  1093. package/src/lib/ui/runtime/claimChild.ts +0 -8
  1094. package/src/lib/ui/runtime/claimExpected.ts +0 -27
  1095. package/src/lib/ui/runtime/claimMarker.ts +0 -13
  1096. package/src/lib/ui/runtime/claimRun.ts +0 -22
  1097. package/src/lib/ui/runtime/clientPage.ts +0 -116
  1098. package/src/lib/ui/runtime/consumeSeed.ts +0 -38
  1099. package/src/lib/ui/runtime/createAsyncCell.ts +0 -358
  1100. package/src/lib/ui/runtime/createComputedNode.ts +0 -19
  1101. package/src/lib/ui/runtime/createDoc.ts +0 -334
  1102. package/src/lib/ui/runtime/createEffectNode.ts +0 -81
  1103. package/src/lib/ui/runtime/createSignalNode.ts +0 -19
  1104. package/src/lib/ui/runtime/currentAbortSignal.ts +0 -26
  1105. package/src/lib/ui/runtime/detachLink.ts +0 -21
  1106. package/src/lib/ui/runtime/endTracking.ts +0 -24
  1107. package/src/lib/ui/runtime/enterRenderPass.ts +0 -13
  1108. package/src/lib/ui/runtime/escapeKey.ts +0 -19
  1109. package/src/lib/ui/runtime/exitRenderPass.ts +0 -7
  1110. package/src/lib/ui/runtime/flushEffects.ts +0 -91
  1111. package/src/lib/ui/runtime/generationGuard.ts +0 -40
  1112. package/src/lib/ui/runtime/historyEntries.ts +0 -151
  1113. package/src/lib/ui/runtime/inScope.ts +0 -19
  1114. package/src/lib/ui/runtime/isAsyncFunction.ts +0 -14
  1115. package/src/lib/ui/runtime/nextBlockId.ts +0 -12
  1116. package/src/lib/ui/runtime/parkCursor.ts +0 -10
  1117. package/src/lib/ui/runtime/pathSegments.ts +0 -10
  1118. package/src/lib/ui/runtime/reactiveAbortState.ts +0 -15
  1119. package/src/lib/ui/runtime/readNode.ts +0 -38
  1120. package/src/lib/ui/runtime/renderPath.ts +0 -16
  1121. package/src/lib/ui/runtime/reportHydrationDivergence.ts +0 -30
  1122. package/src/lib/ui/runtime/routeBareSeed.ts +0 -28
  1123. package/src/lib/ui/runtime/runHydrationPass.ts +0 -69
  1124. package/src/lib/ui/runtime/runNode.ts +0 -75
  1125. package/src/lib/ui/runtime/runtimePath.ts +0 -9
  1126. package/src/lib/ui/runtime/scope.ts +0 -46
  1127. package/src/lib/ui/runtime/scopeGroup.ts +0 -40
  1128. package/src/lib/ui/runtime/toTeardown.ts +0 -38
  1129. package/src/lib/ui/runtime/track.ts +0 -60
  1130. package/src/lib/ui/runtime/trigger.ts +0 -74
  1131. package/src/lib/ui/runtime/types/AbideHistoryState.ts +0 -9
  1132. package/src/lib/ui/runtime/types/Boundary.ts +0 -9
  1133. package/src/lib/ui/runtime/types/Cell.ts +0 -7
  1134. package/src/lib/ui/runtime/types/Computed.ts +0 -3
  1135. package/src/lib/ui/runtime/types/Doc.ts +0 -24
  1136. package/src/lib/ui/runtime/types/EffectResult.ts +0 -10
  1137. package/src/lib/ui/runtime/types/HydrationCursor.ts +0 -8
  1138. package/src/lib/ui/runtime/types/NavVerdict.ts +0 -9
  1139. package/src/lib/ui/runtime/types/Patch.ts +0 -11
  1140. package/src/lib/ui/runtime/types/PathWalk.ts +0 -10
  1141. package/src/lib/ui/runtime/types/ReactiveLink.ts +0 -21
  1142. package/src/lib/ui/runtime/types/ReactiveNode.ts +0 -33
  1143. package/src/lib/ui/runtime/types/RenderContext.ts +0 -10
  1144. package/src/lib/ui/runtime/types/Route.ts +0 -9
  1145. package/src/lib/ui/runtime/types/RouteLoader.ts +0 -7
  1146. package/src/lib/ui/runtime/types/SsrRender.ts +0 -34
  1147. package/src/lib/ui/runtime/types/State.ts +0 -3
  1148. package/src/lib/ui/runtime/types/Teardown.ts +0 -5
  1149. package/src/lib/ui/runtime/types/UiComponent.ts +0 -24
  1150. package/src/lib/ui/runtime/types/UiProps.ts +0 -12
  1151. package/src/lib/ui/runtime/unescapeKey.ts +0 -12
  1152. package/src/lib/ui/runtime/unlinkDeps.ts +0 -28
  1153. package/src/lib/ui/runtime/untrack.ts +0 -20
  1154. package/src/lib/ui/runtime/updateIfNecessary.ts +0 -40
  1155. package/src/lib/ui/runtime/walkPath.ts +0 -41
  1156. package/src/lib/ui/runtime/withOptionalPath.ts +0 -8
  1157. package/src/lib/ui/runtime/withPath.ts +0 -16
  1158. package/src/lib/ui/runtime/withPathFrom.ts +0 -20
  1159. package/src/lib/ui/runtime/withoutHydration.ts +0 -22
  1160. package/src/lib/ui/runtime/writeNode.ts +0 -16
  1161. package/src/lib/ui/scope.ts +0 -20
  1162. package/src/lib/ui/seedBootState.ts +0 -53
  1163. package/src/lib/ui/seedStreamedResolution.ts +0 -56
  1164. package/src/lib/ui/settleAsyncCells.ts +0 -51
  1165. package/src/lib/ui/socketChannel.ts +0 -156
  1166. package/src/lib/ui/socketProxy.ts +0 -47
  1167. package/src/lib/ui/startClient.ts +0 -156
  1168. package/src/lib/ui/state.ts +0 -77
  1169. package/src/lib/ui/subscribeCacheStaleness.ts +0 -85
  1170. package/src/lib/ui/trackedComputed.ts +0 -68
  1171. package/src/lib/ui/tryEncodeResume.ts +0 -11
  1172. package/src/lib/ui/types/Layouts.ts +0 -9
  1173. package/src/lib/ui/types/Pages.ts +0 -8
  1174. package/src/lib/ui/types/Scope.ts +0 -68
  1175. package/src/lib/ui/watch.ts +0 -150
  1176. package/src/preload.ts +0 -19
  1177. package/src/scaffold.ts +0 -153
  1178. package/src/serverBuildPlugins.ts +0 -25
  1179. package/src/serverEntry.ts +0 -138
  1180. package/src/zodCjsPlugin.ts +0 -51
  1181. package/template/.zed/settings.json +0 -10
  1182. package/template/CLAUDE.md +0 -22
  1183. package/template/bunfig.toml +0 -4
  1184. package/template/package.json +0 -21
  1185. package/template/src/app.ts +0 -28
  1186. package/template/src/bundle/icon.png +0 -0
  1187. package/template/src/cli/banner.txt +0 -3
  1188. package/template/src/cli/footer.txt +0 -1
  1189. package/template/src/server/config.ts +0 -17
  1190. package/template/src/server/rpc/getHello.ts +0 -38
  1191. package/template/src/ui/app.css +0 -21
  1192. package/template/src/ui/app.html +0 -24
  1193. package/template/src/ui/pages/about/page.abide +0 -7
  1194. package/template/src/ui/pages/layout.abide +0 -19
  1195. package/template/src/ui/pages/page.abide +0 -19
  1196. package/template/test/app.test.ts +0 -30
  1197. package/template/tsconfig.json +0 -18
  1198. package/tsconfig.app.json +0 -17
@@ -0,0 +1,4480 @@
1
+ // THE REACTIVE VALUE. RULEBOOK 1.1: every producer in this design hands back one of
2
+ // these, and after the collapse there is exactly one other result type beside it.
3
+ //
4
+ // The value is a FUNCTION capturing one record, `Cell`, that carries its state, and
5
+ // REACHING its members through one shared prototype. CLAUDE.md, hot paths: prefer a class
6
+ // or a plain record to a closure that captures its enclosing scope. A per-instance closure
7
+ // set would be an allocation and a captured scope per member per value, and a page
8
+ // holds one per row — and copying the shared ones onto each instance instead was 87% of
9
+ // what a value cost to construct. See `MEMBER_PROTOTYPE`.
10
+ //
11
+ // Every field `Cell` declares is written in its constructor, in one order, `undefined`
12
+ // included — a shape that grows a field on a later path is two hidden classes and every
13
+ // read downstream of it deoptimises.
14
+
15
+ import { type Failed, isFailed, isFailedNamed } from '../Failed.ts'
16
+ import { namedLogger } from '../log.ts'
17
+ import { validationError } from '../refuse.ts'
18
+ import { type Found, runSchema, type Schema } from '../Schema.ts'
19
+ import { UNEXPECTED } from '../UNEXPECTED.ts'
20
+ import { WORK } from '../WORK.ts'
21
+ import { CELL } from './CELL.ts'
22
+ import { ENTRY_LIVES } from './ENTRY_LIVES.ts'
23
+ import { armTimer, type Expiry, expiryFor } from './Expiry.ts'
24
+ import { FOLLOWED } from './FOLLOWED.ts'
25
+ import { Cursor, hasCursorBehind, keepPlaces, type Retained } from './Cursor.ts'
26
+ import { isReactive } from './isReactive.ts'
27
+ import { isThenable } from './isThenable.ts'
28
+ import { MUTATION } from './MUTATION.ts'
29
+ import { NO_INITIAL } from './NO_INITIAL.ts'
30
+ import { NotLanded } from './NotLanded.ts'
31
+ import { PATCH_SINKS, type PatchOp } from './PATCH_SINKS.ts'
32
+ import { REACTIVE_BRAND } from './REACTIVE_BRAND.ts'
33
+ import { recordWrites } from './recordWrites.ts'
34
+ import { STREAMING } from './STREAMING.ts'
35
+ import { currentScope, runInScope, type Scope } from './scoping.ts'
36
+ import {
37
+ CHECK,
38
+ CLEAN,
39
+ DIRTY,
40
+ detach,
41
+ detachProbes,
42
+ dropProbeReader,
43
+ newSubscriber,
44
+ RELEASING,
45
+ type Subscriber,
46
+ TRACKING,
47
+ type Tracked,
48
+ track,
49
+ trackProbe,
50
+ truncate,
51
+ untracked,
52
+ } from './tracking.ts'
53
+ import { owned, owning, watchOver } from './watch.ts'
54
+
55
+ /**
56
+ * The shape of a `transform`: the accepted value in, the stored value or a refusal out.
57
+ *
58
+ * Named because the registry names it and because 4.6 is written over it: the `Failures` arm of
59
+ * the return is the refusal, not an error channel beside it.
60
+ */
61
+ export type Transformer<Accepted, Stored, Failures = never> = (
62
+ value: Accepted,
63
+ ) => Stored | Failures
64
+
65
+ /**
66
+ * Where a value is persisted: a `get` to restore it and a `set` to write it.
67
+ *
68
+ * Both halves, and no way to spell either alone (8.1). `get` answering `undefined` is a miss
69
+ * (8.17), so the miss is in `get`'s type rather than in `Stored`: a store over a value with a body
70
+ * is typed by what the body produces, and a `Store<T | undefined>` there could not be written.
71
+ */
72
+ export type Store<Stored> = {
73
+ get: () => Stored | undefined | Promise<Stored | undefined>
74
+ set: (value: Stored, retention: { ttl: number }) => void | Promise<void>
75
+ }
76
+
77
+ /**
78
+ * What `identity` accepts: a one-parameter projection or a two-parameter comparator.
79
+ *
80
+ * ONE SIGNATURE, NOT A UNION OF TWO. A union of signatures with different arities gives an arrow no
81
+ * contextual type, so `identity: (turn) => turn.text` read its parameter as `any`. A projection
82
+ * declares one parameter and is still assignable here; 5.3 tells the two apart by that arity.
83
+ */
84
+ export type Identity<Stored> = (next: Stored, previous: Stored) => unknown
85
+
86
+ /**
87
+ * The options a `Reactive` is built with: its gates, retention, caps, store and tags.
88
+ *
89
+ * `Failures` IS INFERRED FROM `transform`, which is what makes `s.error` and `s.isError`
90
+ * typed rather than `undefined`. 4.6 has a transform refuse by RETURNING, so its return
91
+ * type is the one place a value's failures are declared — naming them a second time on the
92
+ * factory would be a declaration that can disagree with the code.
93
+ */
94
+ export type ReactiveOptions<
95
+ Accepted,
96
+ Stored,
97
+ // CONSTRAINED TO `Failed`, and that is the registry's own row — "union of `Failed`" —
98
+ // rather than a convenience. Unconstrained, inference against `Stored | Failures`
99
+ // takes the WHOLE return type into `Failures`, so `s.error()` came back typed
100
+ // `number | Failed<…>` and `.data` did not exist on it. The bound is what tells the
101
+ // two halves of that union apart.
102
+ Failures extends Failed<string, unknown> = never,
103
+ // `never` on every overload but the keyed ones, which is what makes `args` unspellable
104
+ // on the unkeyed form (11.41): its field type collapses to `never` there.
105
+ Args = never,
106
+ > = {
107
+ /**
108
+ * The schema gating a keyed value's args.
109
+ *
110
+ * RULEBOOK 11.40, 11.28, 11.68: the gate on a keyed value's args — what it returns is what the
111
+ * body is handed, and the key was taken before it ran (11.26).
112
+ */
113
+ args?: [Args] extends [never] ? never : Schema<Args>
114
+ /**
115
+ * What makes a gated write a repeat: a projection or a comparator.
116
+ *
117
+ * RULEBOOK 5.3: discriminated by arity — one parameter is a projection compared by
118
+ * `!==`, two is a comparator answering directly.
119
+ */
120
+ identity?: Identity<Stored>
121
+ /**
122
+ * The life of a production, in milliseconds.
123
+ *
124
+ * RULEBOOK 6.1 through 6.6. Inert on a value with no producer (6.2), which is decided
125
+ * once — see `expiryFor`.
126
+ */
127
+ ttl?: number
128
+ /**
129
+ * The gate on the way in, run before `transform` on every way in.
130
+ *
131
+ * RULEBOOK 4.3: THE GATE ON THE WAY IN, and it runs FIRST — before `transform`, on
132
+ * the settled value, on every way in alike: a write, what a body produced (11.46) and
133
+ * what an adoption mirrors (11.47).
134
+ */
135
+ schema?: Schema<Accepted>
136
+ /**
137
+ * Shapes a settled value on the way in, or refuses it by returning a `Failed`.
138
+ *
139
+ * RULEBOOK 4.6, 4.7: runs untracked, on the settled value, once per materialisation,
140
+ * and refuses by RETURNING a `Failed` rather than by throwing. A throw here would be
141
+ * indistinguishable from the body having failed, and 4.9 has a refused write mint
142
+ * nothing where a failed producer (2.3) may still have something to say.
143
+ */
144
+ transform?: Transformer<Accepted, Stored, Failures>
145
+ /**
146
+ * Wakes a reader at once, then at most once per window.
147
+ *
148
+ * RULEBOOK 5.8, 5.12: a change reaches a reader immediately and then at most once per
149
+ * window. Declaring this beside `debounce` is refused at construction (5.14).
150
+ */
151
+ throttle?: number
152
+ /** Wakes a reader once the changes stop (RULEBOOK 5.8, 5.13). */
153
+ debounce?: number
154
+ /**
155
+ * What a `Selection` matches on; the function form is handed the entry's args.
156
+ *
157
+ * RULEBOOK 11.43, 11.44: what a `Selection` matches on, and the one selector that reaches
158
+ * across values. The function form is handed the entry's args, and `undefined` on a value
159
+ * that has none — which is the only value it is ever `undefined` on.
160
+ */
161
+ tags?: string[] | ((args: ArgsOf<Args>) => string[])
162
+ /**
163
+ * Where the value lives when the process does not.
164
+ *
165
+ * RULEBOOK 8, 9.5, 11.42: where the value lives when the process does not. The function form
166
+ * is handed the entry's args, so each key of a `Keyed` has a store of its own.
167
+ */
168
+ store?: Store<Stored> | ((args: ArgsOf<Args>) => Store<Stored>)
169
+ /**
170
+ * One value for the whole process rather than one per request.
171
+ *
172
+ * RULEBOOK 11.32, 11.34: one value for the whole process rather than one per request. Inert in a
173
+ * browser, where the process IS the scope.
174
+ */
175
+ global?: boolean
176
+ /**
177
+ * What tells one array element from another.
178
+ *
179
+ * RULEBOOK 5.22, 32.32: what tells one element from another. The property-name form is the one
180
+ * that crosses a wire (18.4) — a function has no serialisation.
181
+ */
182
+ by?:
183
+ | (keyof ElementOf<Stored> & string)
184
+ | ((element: ElementOf<Stored>) => unknown)
185
+ }
186
+
187
+ /**
188
+ * What a function-form option is handed: the entry's args, or `undefined` on a value whose body
189
+ * takes none (11.44).
190
+ */
191
+ type ArgsOf<Args> = [Args] extends [never] ? undefined : Args
192
+
193
+ /**
194
+ * `unknown` on a value that is not an array, where `by` has no element to key and names no property.
195
+ */
196
+ type ElementOf<Stored> =
197
+ NonNullable<Stored> extends readonly (infer Element)[] ? Element : unknown
198
+
199
+ /**
200
+ * The reactive value: a callable read, plus its probes, writes, triggers and cursors.
201
+ *
202
+ * `Produced` is the fourth parameter and RULEBOOK 1.2 is what it means: the unit the
203
+ * producer yielded, which is `Stored` for every producer but a stream, and one chunk for a
204
+ * streaming producer (9.1). It defaults to `Stored`, so the parameter is invisible to
205
+ * everything that is not a stream.
206
+ */
207
+ export type Reactive<
208
+ Stored,
209
+ Accepted = Stored,
210
+ Failures = never,
211
+ Produced = Stored,
212
+ > = {
213
+ /**
214
+ * Reads the value; throws where nothing has landed.
215
+ *
216
+ * RULEBOOK 2.2: throws where nothing has landed. Move 7 is what makes this `Stored`
217
+ * rather than `Stored | undefined` — the absence moved to `peek`.
218
+ */
219
+ (): Stored
220
+ peek(): Stored | undefined
221
+ busy(): boolean
222
+ ready(): boolean
223
+ error(): Failures | undefined
224
+ /**
225
+ * Narrows a caught error to this value's failure of that name.
226
+ *
227
+ * 3.1: the narrowing, and it takes the error rather than reading one — `s.error` is
228
+ * the probe, this is the type guard over whatever was caught.
229
+ */
230
+ isError<Name extends string>(
231
+ error: unknown,
232
+ name: Name,
233
+ ): error is Extract<Failures, { name: Name }>
234
+ /**
235
+ * Writes a value, gated by `identity`; returns the refusal where a gate refused it.
236
+ *
237
+ * Gated by `identity`, and local. The divergence that once split by PRODUCER
238
+ * splits by MEMBER instead. Hands back the refusal where a gate refused the write (4.18).
239
+ * A `Reactive` IS IN THE UNION because 11.61 adopts one rather than storing it, and it is
240
+ * spelled out rather than left to `PromiseLike`: a `Reactive` satisfies that (1.4), and
241
+ * taking it through that arm is exactly the settle-to-a-snapshot 1.6 refuses. Its failures are
242
+ * this value's, since the adopted value's refusal becomes this one's: an `Rpc` call carries
243
+ * `HttpError` (16.8), so a value read through one is written through another.
244
+ */
245
+ set(
246
+ value:
247
+ | Accepted
248
+ | PromiseLike<Accepted>
249
+ | Reactive<Accepted, unknown, Failures, unknown>,
250
+ // biome-ignore lint/suspicious/noConfusingVoidType: same reason as `watch` below — a `set` that returns nothing infers `void`, and 4.18's refusal is the other arm.
251
+ ): void | Failures
252
+ patch(mutate: (value: Stored) => void): void
253
+ refresh(): void
254
+ invalidate(): void
255
+ // biome-ignore lint/suspicious/noConfusingVoidType: `void` is the RETURN POSITION of an author's effect, and it is load-bearing. `undefined` there refuses `(v) => { read(v) }` — a block body returning nothing infers `void`, which is not assignable to `undefined` — so the rule's fix would reject the ordinary effect.
256
+ watch(effect: (value: Stored) => void | (() => void)): () => void
257
+ /** The production in flight, and then what follows it (2.5). */
258
+ [Symbol.asyncIterator](): AsyncIterator<Produced>
259
+ then<Result>(
260
+ onSettled?: (value: Stored) => Result | PromiseLike<Result>,
261
+ onFailed?: (error: unknown) => Result | PromiseLike<Result>,
262
+ ): Promise<Result>
263
+ catch<Result>(
264
+ onFailed: (error: unknown) => Result | PromiseLike<Result>,
265
+ ): Promise<Stored | Result>
266
+ finally(onSettled: () => void): Promise<Stored>
267
+ }
268
+
269
+ /** The standing adoption: what is adopted, and the way to stop mirroring it. */
270
+ type Adoption = { source: Cell; stop: () => void }
271
+
272
+ /**
273
+ * The window a `throttle` or a `debounce` holds open, allocated only where one is declared.
274
+ *
275
+ * THE WINDOW A `throttle` OR A `debounce` HOLDS OPEN (RULEBOOK 5.8). One field on the
276
+ * cell rather than one per window field, allocated only where a value declared one — the
277
+ * shape `adoption` already uses, and for the same reason.
278
+ *
279
+ * WHAT A WINDOW CAPS IS THE WAKE, NEVER THE PRODUCTION (5.9). Every write still mints and
280
+ * the ordinal moves. What waits is the value a READER sees and the cascade that tells it so,
281
+ * which is the whole of 5.8's "how often a value changes for a reader".
282
+ *
283
+ * WHAT IT COSTS EVERY VALUE THAT NEVER CAPS: one field load and one branch on the write
284
+ * path, plus `serve` as a frame rather than five stores inline. Measured at 0.99x -> 1.08x
285
+ * against the hand-written arm on the since-removed `publish into a capped ring` case, consistent across three
286
+ * runs over a 0.7% floor — about 1.3 ns on a 14.7 ns op. Moving the comparison target
287
+ * behind the gate did not recover it, so it is the frame and the branch rather than a
288
+ * wasted load. Inlining `serve` into the uncapped arm would buy it back for a second copy
289
+ * of the reader-visible transition, and this file has already paid for one of those: the
290
+ * trade is stated rather than taken, 1.3 ns being nowhere near perception.
291
+ */
292
+ type Cap = {
293
+ /**
294
+ * True for a throttle, which lets the leading change through; false for a debounce.
295
+ *
296
+ * 5.12 against 5.13, and the only difference between the two mechanisms: a throttle
297
+ * lets the leading change through and holds what follows, a debounce holds everything
298
+ * until the changes stop.
299
+ */
300
+ leading: boolean
301
+ ms: number
302
+ timer: ReturnType<typeof setTimeout> | null
303
+ /**
304
+ * The production the window is holding back, while `holding` is set.
305
+ *
306
+ * The production the window is holding back. `holding` is a field rather than a test
307
+ * against `held`, because `undefined` is a value an app can write and so cannot carry
308
+ * the absence.
309
+ */
310
+ held: unknown
311
+ holding: boolean
312
+ /**
313
+ * The last production minted, which the identity gate compares against.
314
+ *
315
+ * WHAT THE IDENTITY GATE COMPARES AGAINST. On every uncapped value that is `cell.value`
316
+ * and the two are one thing; a window moves the last production MINTED apart from the
317
+ * last one RELEASED, and comparing against the released one would collapse a production
318
+ * 5.9 forbids dropping — A, B, A inside one window is three productions, and only the
319
+ * third's own predecessor makes it a repeat.
320
+ */
321
+ minted: unknown
322
+ /**
323
+ * Whether the window is holding back a body run.
324
+ *
325
+ * A BODY RUN THE WINDOW IS HOLDING BACK (5.11), against `holding`'s production. The two
326
+ * are separate flags because they can stand together: a stream has a body AND tells its
327
+ * chunks through the window (5.17), so one close can owe a run and a telling at once.
328
+ */
329
+ owed: boolean
330
+ /**
331
+ * Whether the window is holding back a refresh, started when it closes.
332
+ *
333
+ * 5.24 — A RELOAD THE WINDOW IS HOLDING BACK: a refresh made inside it, started when it closes.
334
+ * Started there rather than owed like a run, because 7.11 reloads whether or not anything reads
335
+ * and an owed run waits for a read to pull it.
336
+ */
337
+ reloading: boolean
338
+ }
339
+
340
+ /**
341
+ * A value's store and the state of its writes, allocated only where a `store` was declared.
342
+ *
343
+ * A VALUE'S STORE AND WHAT ITS WRITES ARE DOING, allocated only where a `store` was declared.
344
+ *
345
+ * 8.10: ONE WRITE IN FLIGHT AND ONE PENDING. A production arriving while a write is out replaces
346
+ * the pending value rather than queueing behind it: a slow store handed every intermediate is doing
347
+ * work nobody can observe, and a queue is how it grows without bound behind a fast writer.
348
+ */
349
+ type Persisted = {
350
+ store: Store<unknown>
351
+ /** The value's own `ttl`, taken once, and infinity where it declares none (8.13). */
352
+ ttl: number
353
+ /**
354
+ * Set while a restore mints its production, so what was just read is not written back (8.8).
355
+ */
356
+ restoring: boolean
357
+ writing: boolean
358
+ pending: boolean
359
+ /**
360
+ * The newest value handed to the store and not yet confirmed.
361
+ *
362
+ * THE NEWEST VALUE THE APP HAS HANDED THE STORE, standing until the store confirms it. It is
363
+ * what `pending` sends next, and what 8.18 serves a re-read in place of calling `get`.
364
+ */
365
+ unconfirmed: unknown
366
+ }
367
+
368
+ /**
369
+ * A streaming producer's own state; `null` on every value whose body is not an async generator.
370
+ *
371
+ * A STREAMING PRODUCER'S OWN STATE (9.1, 9.2, 9.6), and `null` on every value whose body is
372
+ * not an async generator — the shape `cap` and `adoption` already use.
373
+ *
374
+ * THE ACCUMULATION IS PUSHED INTO AND MATERIALISED ON THE READ. A chunk is one push and one
375
+ * cascade; the copy a reader is handed is taken by the read that follows, so a hundred
376
+ * chunks between two reads are one copy rather than a hundred (9.2). The copy is FRESH per
377
+ * chunk count and has to be: a reader holding an earlier snapshot still holds what it read,
378
+ * and a value derived from this one compares by reference — the live buffer handed out would
379
+ * be collapsed at every derived identity gate after the first chunk.
380
+ *
381
+ * WHAT THAT COSTS WHERE A READ FOLLOWS EVERY CHUNK is a copy of the accumulation per read,
382
+ * and a reader woken per chunk made that a copy per chunk: twenty thousand chunks landing in
383
+ * one task took 61 ms against 1.9 ms for the hand-written arm. 9.9 is what bounds it — the
384
+ * wake is held to one per task, which is the unit a browser paints between, so the reads it
385
+ * drops were never visible. A reader that reads per chunk on its own, unwoken, is still a
386
+ * copy per read.
387
+ */
388
+ type Stream = {
389
+ /**
390
+ * The accumulation of the run being served — and the same array as `ring`, so a cursor
391
+ * walks the chunks this holds rather than a second copy of them.
392
+ */
393
+ chunks: unknown[]
394
+ /** The accumulation's version: moves on every release, patch and new run. */
395
+ version: number
396
+ /**
397
+ * Which accumulation `value` stands for, as a `version` rather than a chunk count.
398
+ *
399
+ * A version rather than a chunk count because a patch changes the accumulation without
400
+ * changing its length (9.13), and a write stands at the version it was made at until the
401
+ * accumulation moves past it (9.11). -1 where nothing has been materialised.
402
+ */
403
+ materialisedAt: number
404
+ /**
405
+ * Whether `value` is a write rather than a materialisation.
406
+ *
407
+ * WHETHER `value` IS A WRITE rather than a materialisation, while `materialisedAt` stands. A value
408
+ * forwarding this stream serves the write the way it would have served a production (11.59).
409
+ */
410
+ written: boolean
411
+ /**
412
+ * How many chunks a reader has been told of.
413
+ *
414
+ * HOW MANY CHUNKS A READER HAS BEEN TOLD OF. Every chunk as it lands, without a cap; with one,
415
+ * only what the window has released (5.18) — the rest are in `chunks` for a cursor (5.10) and
416
+ * out of what a read materialises until the release.
417
+ */
418
+ visible: number
419
+ /** The run in flight, told to return when a newer run supersedes it. */
420
+ iterator: AsyncIterator<unknown> | null
421
+ /**
422
+ * Which run is current; only a new run moves it.
423
+ *
424
+ * WHICH RUN IS CURRENT, and only a new run moves it. Apart from `generation`, which every
425
+ * write moves so that a load it overtook lands nowhere — a write over a stream stands beside
426
+ * the stream (9.11) rather than superseding it, and sharing the counter stopped the stream.
427
+ */
428
+ run: number
429
+ /**
430
+ * Whether a wake is already held for this task, so the next chunk only pushes.
431
+ *
432
+ * 9.9: chunks have landed that the readers have not been told about, and the value is
433
+ * already in `WAKING` — so the next chunk in this task pushes and does nothing else.
434
+ */
435
+ waking: boolean
436
+ /**
437
+ * A probe moved under the held wake — the first chunk making the value ready, or one
438
+ * clearing a standing error — and the wake owes it to the guards as well.
439
+ */
440
+ probesOwed: boolean
441
+ /**
442
+ * The stream this one forwards, and `null` on a value that produces its own.
443
+ *
444
+ * THE STREAM THIS ONE FORWARDS (11.15), and `null` on a value that produces its own. A
445
+ * value adopting a stream IS that stream to a cursor, a guard and an await, so it holds
446
+ * the adopted value's buffer and ring rather than copies — and this is what stops a
447
+ * trigger on it starting its body as though the body were the generator.
448
+ */
449
+ source: Cell | null
450
+ /**
451
+ * How far the forwarding value's ordinals run ahead of the adopted value's, fixed when
452
+ * the forwarding begins so the adopter's cursor positions go on from its own.
453
+ */
454
+ ordinalOffset: number
455
+ /**
456
+ * Whether what is served is a run that closed.
457
+ *
458
+ * WHETHER WHAT IS SERVED IS A RUN THAT CLOSED, which is the only accumulation a deadline
459
+ * reaches (6.11). A run in flight has minted nothing, so `expiry.at` says nothing about it —
460
+ * without this the standing arm reads `at` as 0 and drops the value on its first read.
461
+ */
462
+ closed: boolean
463
+ }
464
+
465
+ function newStream(source: Cell | null): Stream {
466
+ return {
467
+ chunks: EMPTY_RING,
468
+ version: 0,
469
+ visible: 0,
470
+ materialisedAt: -1,
471
+ written: false,
472
+ iterator: null,
473
+ run: 0,
474
+ waking: false,
475
+ probesOwed: false,
476
+ source,
477
+ ordinalOffset: 0,
478
+ closed: false,
479
+ }
480
+ }
481
+
482
+ /** Turns `cell` into a streaming producer, forwarding `source`'s stream when it has one. */
483
+ function becomeStream(cell: Cell, source: Cell | null): Stream {
484
+ const stream = newStream(source)
485
+ cell.stream = stream
486
+ cell.plain = false
487
+ cell.bareWrite = false
488
+ simpleShape(cell)
489
+ cell.direct = false
490
+ return stream
491
+ }
492
+
493
+ /**
494
+ * Starts a closed run's clock: the close is a streaming producer's mint (6.11), as `produce` is
495
+ * every other producer's. A failed or superseded run never reaches here, so it starts no clock.
496
+ */
497
+ function closeRun(cell: Cell, stream: Stream): void {
498
+ // Materialised here so 9.8's gates run on the accumulation the run closed with.
499
+ if (heldValue(cell) === undefined) return
500
+ stream.closed = true
501
+ const expiry = cell.expiry
502
+ if (expiry !== null) {
503
+ expiry.at = Date.now()
504
+ // A closed run replaces what 6.7 released, so the value is no longer waiting for one.
505
+ expiry.dropped = false
506
+ armNext(cell, expiry)
507
+ }
508
+ }
509
+
510
+ /**
511
+ * The prototype every `async function*` has, and so the declaration 9.6 reads at construction.
512
+ * Taken from a literal because the constructor has no global name.
513
+ */
514
+ const ASYNC_GENERATOR_FUNCTION = Object.getPrototypeOf(async function* () {})
515
+
516
+ /** The prototype of every async generator function's own `prototype`, which its generators have. */
517
+ const ASYNC_GENERATOR = ASYNC_GENERATOR_FUNCTION.prototype
518
+
519
+ /** Whether a run handed back an async generator, which 9.6 makes the run's stream. */
520
+ function isAsyncGenerator(value: unknown): value is AsyncGenerator {
521
+ if (typeof value !== 'object' || value === null) return false
522
+ const own = Object.getPrototypeOf(value)
523
+ return own !== null && Object.getPrototypeOf(own) === ASYNC_GENERATOR
524
+ }
525
+
526
+ /**
527
+ * Whether a body is an async generator function, and so a streaming producer.
528
+ *
529
+ * Exported for what wraps a body and has to keep its kind — `args` in `Keyed.ts`.
530
+ */
531
+ export function isStreamBody(body: (args: never) => unknown): boolean {
532
+ return Object.getPrototypeOf(body) === ASYNC_GENERATOR_FUNCTION
533
+ }
534
+
535
+ /**
536
+ * A value's internal state record, apart from the callable an app holds.
537
+ *
538
+ * THE INTERNAL FACE, AND A SECOND OBJECT. With the fields on the callable itself, every
539
+ * one was a property added to a FUNCTION at construction, and that was most of what a
540
+ * value cost to make: moving them here took `construct a value` from 123 ns to 87 under
541
+ * JSC and from 101 to 83 under V8, and a derived value's construction, a chain and a
542
+ * layered DAG 7-13% with it. Nothing measured moved the other way. The callable captures
543
+ * its record, so a read is one context load — the hand-written arm's one captured
544
+ * variable — and a member reaches the record through `CELL`, one load ahead of what it
545
+ * did before.
546
+ *
547
+ * THE FIELD COUNT SITS ON A VM BOUNDARY AND IT IS NOT A LEVER. Both engines give an
548
+ * object a fixed inline slot budget and spill the rest to an out-of-line store, and this
549
+ * record is over it — so the count moves numbers that have nothing to do with the work.
550
+ * Two independent measurements say the same thing from opposite ends. Taking `Cell` to
551
+ * 38 is worth ~11% of `construct a value` and ~6-9% of the derived case, and it does not
552
+ * matter HOW the four go: a consolidation into one record and four fields simply deleted
553
+ * buy the same number, so the consolidation is not what pays. Going the other way,
554
+ * 42 -> 46, is FREE — above the budget the out-of-line store already exists. And dropping
555
+ * ONE field moved chain 20 and both layered DAGs +4.2% under V8 while moving nothing
556
+ * under JSC; adding a DEAD boolean back put all three within 0.6%, which is the proof it
557
+ * was layout and not work — that same dead boolean then cost the probe walk 6-7%.
558
+ *
559
+ * So the boundary is worth KNOWING and not worth engineering around. Adding a field
560
+ * costs nothing; getting under costs a structural change that the next field added here
561
+ * silently undoes, and it re-rolls in a different direction for every row. If
562
+ * construction ever needs that 11%, shed fields — do not build machinery to shed them.
563
+ * And when a V8-only move of this size shows up on a graph row, the first thing to check
564
+ * is whether the field count changed.
565
+ */
566
+ class Cell {
567
+ /**
568
+ * Who reads this value, on the value edge.
569
+ *
570
+ * ARRAYS, not sets. The mark walk walks this per write and a set's iterator
571
+ * allocates; removal is O(n) against a reader count that is small by construction.
572
+ */
573
+ declare readers: Subscriber[]
574
+ /**
575
+ * Who asked about this value's PROBES — a different edge from `readers`, and see
576
+ * `markProbes` for what that buys.
577
+ */
578
+ declare probeReaders: Subscriber[]
579
+ declare sources: Cell[]
580
+ /**
581
+ * The values whose PROBES this body asked about — a `Cell` is a `Subscriber`, so it
582
+ * carries the reader half of the probe edge as well as the source half.
583
+ */
584
+ declare probeSources: Cell[]
585
+ declare cursor: number
586
+ /** See `Subscriber.seen`. */
587
+ declare seen: Set<Cell> | null
588
+ declare seenThrough: number
589
+ declare scanningFrom: number
590
+ declare label: string
591
+ declare body: ((args: unknown) => unknown) | null
592
+ declare args: unknown
593
+ declare value: unknown
594
+ declare landed: boolean
595
+ /**
596
+ * Whether a read may answer with `value`.
597
+ *
598
+ * WHETHER A READ MAY ANSWER WITH `value`. Implies `landed`, and is false over a landed value
599
+ * a trigger, an abort or an adoption has stopped serving — which is the state `landed`
600
+ * alone cannot say.
601
+ */
602
+ declare servable: boolean
603
+ /**
604
+ * Whether a read can return `value` straight, without going a frame in.
605
+ *
606
+ * `state === CLEAN && servable` — the whole of "this read can return the field",
607
+ * maintained rather than recomputed. A read is the hottest path in the design and it
608
+ * was three loads and three branches to decide.
609
+ *
610
+ * THE INVARIANT IS ONE-DIRECTIONAL and that is what makes it safe to maintain by
611
+ * hand: `true` is written only where all three are known to hold, and every
612
+ * transition that can break one of them writes `false`. So a site that forgets to
613
+ * set it true costs a frame on the reads that follow and cannot serve a wrong value,
614
+ * which is the opposite of how a maintained flag usually fails.
615
+ */
616
+ declare direct: boolean
617
+ declare loading: boolean
618
+ declare failure: unknown
619
+ /**
620
+ * The compiled `identity` comparator.
621
+ *
622
+ * `null` IS the default — see `comparatorFor`.
623
+ */
624
+ declare identityFn: ((next: unknown, previous: unknown) => boolean) | null
625
+ /**
626
+ * The comparator this value DECLARED, which `identityFn` returns to when an adoption ends.
627
+ *
628
+ * 11.17 inherits the adopted value's `identity` only where the outer declared none, and only
629
+ * for as long as it adopts: kept on `identityFn` alone, the inherited comparator outlived the
630
+ * adoption and gated the outer's own productions — `flag() ? inner : count()` with `inner`
631
+ * keyed on `.id` read every number as the same `undefined` and never woke again.
632
+ */
633
+ declare declaredIdentityFn:
634
+ | ((next: unknown, previous: unknown) => boolean)
635
+ | null
636
+ declare transform: ((value: unknown) => unknown) | null
637
+ /**
638
+ * `null` on every value that declares no `schema`, which keeps the gate off the write
639
+ * path of everything that did not ask for one.
640
+ */
641
+ declare schema: Schema<unknown> | null
642
+ /**
643
+ * A streaming producer's chunk buffer, for a cursor to walk (2.5); `EMPTY_RING` on every
644
+ * other value, whose cursor answers the standing production from `value`.
645
+ */
646
+ declare ring: unknown[]
647
+ /**
648
+ * The ordinal before `ring[0]`, so `ring[index]` carries ordinal `ringBase + index + 1` and a
649
+ * cursor finds its place from the ordinal it holds.
650
+ */
651
+ declare ringBase: number
652
+ /**
653
+ * `null` on every value that declares no `ttl`, and on every value 6.2 makes it inert
654
+ * for. Its presence is also what holds `direct` false — see `serve`.
655
+ */
656
+ declare expiry: Expiry | null
657
+ declare ordinal: number
658
+ declare generation: number
659
+ declare alive: boolean
660
+ declare isEffect: boolean
661
+ declare isMirror: boolean
662
+ declare adopter: Tracked | null
663
+ /**
664
+ * The mark: `CLEAN`, `CHECK` or `DIRTY`.
665
+ *
666
+ * `CLEAN`, `CHECK` or `DIRTY` — see `tracking.ts`. Stamped on every transitive
667
+ * reader BEFORE anything runs, so a body that reaches a source which has not caught
668
+ * up yet pulls it forward; `running` is what stops a body already on the stack being
669
+ * re-entered.
670
+ *
671
+ * ONE RUN PER NODE PER WRITE is the contract, and the state carries it without a
672
+ * cascade counter: a node that has run is `CLEAN`, and only a source PRODUCING can
673
+ * mark it again — which a source it already read cannot do, because reading it is
674
+ * what resolved it.
675
+ */
676
+ declare state: number
677
+ declare running: boolean
678
+ /**
679
+ * Whether the last run aborted on a value that had not landed.
680
+ *
681
+ * 2.13: A RUN THAT ABORTED ON A VALUE THAT HAD NOT LANDED, and is owed the rest of itself
682
+ * when that value arrives. Push-pull leaves a marked body for the read that wants it, and
683
+ * that is right for a body which RAN — this one did not, so nothing downstream can pull it:
684
+ * a reader guarding on `ready()` asks the probe edge and never the value, and the guard would
685
+ * answer false for as long as nobody read through it.
686
+ */
687
+ declare aborted: boolean
688
+ /**
689
+ * The value this one adopted, or `null`.
690
+ *
691
+ * WHAT THIS VALUE'S BODY HANDED BACK, where it handed back another `Reactive`
692
+ * (11.12). `null` on every value that is not adopting, which is nearly all of them —
693
+ * one field rather than two, and the record is allocated only where there is one.
694
+ */
695
+ declare adoption: Adoption | null
696
+ /**
697
+ * `null` on every value declaring neither `throttle` nor `debounce`, which is nearly
698
+ * all of them.
699
+ */
700
+ declare cap: Cap | null
701
+ /**
702
+ * `null` on every value declaring no `tags`, which keeps `markProbes` from looking up a
703
+ * selection signal for any of them.
704
+ */
705
+ declare tags: string[] | null
706
+ /** Whether `declare` built this value for a mutation, which a sweep invalidates (13.16). */
707
+ declare mutation: boolean
708
+ /** `null` on every value declaring no `store`, which is what keeps `serve` from persisting. */
709
+ declare store: Persisted | null
710
+ /**
711
+ * The declared `by`.
712
+ *
713
+ * 5.22 — held as declared rather than as a function, so the property name is still there to send.
714
+ */
715
+ declare by: string | ((element: unknown) => unknown) | null
716
+ /** The probe pass this cell was last visited in. See `walkBusy` and `walkReady`. */
717
+ declare probePass: number
718
+ /**
719
+ * `OWES_NOTHING`, `OWES_ABOVE` or `OWES_RELOAD` — what an `invalidate` left for the next read
720
+ * to do. See `invalidateOne`.
721
+ */
722
+ declare owes: number
723
+ /** The value this record is the state of — what `NotLanded` names as its source. */
724
+ declare callable: Reactive<unknown> | null
725
+ /** `null` on every value whose body is not an async generator, which is nearly all. */
726
+ declare stream: Stream | null
727
+ /**
728
+ * Whether a read may ever take the field straight, fixed at construction.
729
+ *
730
+ * WHETHER A READ MAY EVER TAKE THE FIELD STRAIGHT, fixed at construction: no expiry to
731
+ * check and no accumulation to materialise. `setDirect` reads this one field where it
732
+ * would otherwise read one per mechanism that needs the read to go a frame in.
733
+ */
734
+ declare plain: boolean
735
+ /**
736
+ * Whether a settled write goes straight to `produce`, past no gate.
737
+ *
738
+ * NOTHING STANDS BETWEEN A SETTLED WRITE AND `produce`: no `schema`, no `transform`, and no
739
+ * stream whose writes stand apart from its chunks (9.11, 9.12). One field where the write and
740
+ * the recompute each tested two, maintained where a forwarded stream comes and goes.
741
+ */
742
+ declare bareWrite: boolean
743
+ /**
744
+ * Whether a gated write can take `SIMPLE_PROTOTYPE`'s short path.
745
+ *
746
+ * EVERYTHING A GATED WRITE WOULD OTHERWISE ASK, IN ONE FIELD: no cap holding the
747
+ * production back, no expiry, no store to persist through, no
748
+ * declared `identity`, and `bareWrite`'s own three. A value carrying none of them has a
749
+ * `produce` -> `serve` -> `cascade` that reduces to three stores and a mark — which is
750
+ * what `SIMPLE_PROTOTYPE.set` spells out rather than calls.
751
+ *
752
+ * IT SELECTS A PROTOTYPE AND IS NOT READ ON THE WRITE PATH. See `SIMPLE_PROTOTYPE`.
753
+ *
754
+ * MAINTAINED, NOT FIXED: three of the fields under it move after construction —
755
+ * `bareWrite` and `plain` where a forwarded stream comes and goes, `identityFn` where an
756
+ * adoption takes the inner value's. `simpleShape` is called at each of those.
757
+ */
758
+ declare simple: boolean
759
+ /**
760
+ * The scope this value was built in, and so the one its body runs under.
761
+ *
762
+ * 11.32 — THE SCOPE THIS VALUE WAS BUILT IN, and so the one its body runs under. `undefined` in a
763
+ * browser, and on a server for a value built outside any request.
764
+ */
765
+ declare scope: Scope | undefined
766
+ /**
767
+ * Whether this value is one for the whole process, in every scope.
768
+ *
769
+ * 11.34, 13.13 — one value for the process, and so inside every scope a selection is made in. An
770
+ * entry of a `global` keyed value is one too, whichever request first reached it.
771
+ */
772
+ declare global: boolean
773
+ /**
774
+ * The one weak handle every selection index holds this value by, or `null` where none does.
775
+ *
776
+ * 13.1 AND 13.6: a value filed for the bare sweep or carrying `tags` is findable by one, and
777
+ * every index holds the same handle, so an eviction drops it from all of them at once.
778
+ */
779
+ declare ref: WeakRef<Cell> | null
780
+ /**
781
+ * Whether this value is filed for the bare selection — once, where it first becomes a load.
782
+ *
783
+ * See `fileProducer`. Not cleared by an eviction: dropping `ref` is what takes an evicted entry
784
+ * out, and this staying set is what keeps its next load from filing it again.
785
+ */
786
+ declare filed: boolean
787
+ /**
788
+ * Whether what this value was built in has stopped — the setup or the request that owned it.
789
+ *
790
+ * 12.14. Set by `orphan`; the value lets go of its sources once nothing
791
+ * reads it (`releaseOrphan`), which may be at once or when the last reader outside its owner leaves.
792
+ */
793
+ declare orphaned: boolean
794
+
795
+ constructor(
796
+ label: string,
797
+ body: ((args: unknown) => unknown) | null,
798
+ args: unknown,
799
+ options: ReactiveOptions<unknown, unknown, never> | undefined,
800
+ streaming: boolean,
801
+ ) {
802
+ // Every field, in one order, `undefined` included.
803
+ this.readers = []
804
+ this.probeReaders = []
805
+ this.sources = []
806
+ this.probeSources = []
807
+ this.cursor = 0
808
+ this.seen = null
809
+ this.seenThrough = 0
810
+ this.scanningFrom = -1
811
+ this.label = label
812
+ this.body = body
813
+ this.args = args
814
+ this.value = undefined
815
+ this.landed = false
816
+ this.servable = false
817
+ this.direct = false
818
+ this.loading = false
819
+ this.failure = undefined
820
+ this.identityFn = comparatorFor(
821
+ options?.identity as Identity<unknown> | undefined,
822
+ )
823
+ this.declaredIdentityFn = this.identityFn
824
+ this.transform = (options?.transform ?? null) as
825
+ | ((value: unknown) => unknown)
826
+ | null
827
+ this.schema = (options?.schema ?? null) as Schema<unknown> | null
828
+ this.ring = EMPTY_RING
829
+ this.ringBase = 0
830
+ // 6.2 DECIDED ONCE, here rather than per production: a body is what makes a value a
831
+ // producer, and a plain state is the one this must not reach. See `expiryFor`.
832
+ this.expiry = expiryFor(
833
+ options?.ttl,
834
+ // A store is a producer too (8.2): there is somewhere to get the value back from, so
835
+ // `ttl` on a value holding one drops rather than being inert.
836
+ body !== null || options?.store !== undefined,
837
+ )
838
+ this.ordinal = 0
839
+ this.generation = 0
840
+ this.alive = true
841
+ this.state = CLEAN
842
+ this.running = false
843
+ this.aborted = false
844
+ this.adoption = null
845
+ this.cap = capFor(label, options?.throttle, options?.debounce)
846
+ const tags = options?.tags
847
+ this.tags =
848
+ tags === undefined
849
+ ? null
850
+ : typeof tags === 'function'
851
+ ? tags(args as never)
852
+ : tags
853
+ this.mutation =
854
+ (options as { [MUTATION]?: true } | undefined)?.[MUTATION] === true
855
+ const store = options?.store
856
+ this.store =
857
+ store === undefined
858
+ ? null
859
+ : {
860
+ store: (typeof store === 'function'
861
+ ? store(args as never)
862
+ : store) as Store<unknown>,
863
+ ttl: options?.ttl ?? Number.POSITIVE_INFINITY,
864
+ restoring: false,
865
+ writing: false,
866
+ pending: false,
867
+ unconfirmed: undefined,
868
+ }
869
+ this.by = (options?.by ?? null) as
870
+ | string
871
+ | ((element: unknown) => unknown)
872
+ | null
873
+ this.probePass = 0
874
+ this.owes = OWES_NOTHING
875
+ this.isEffect = false
876
+ this.isMirror = false
877
+ this.adopter = null
878
+ this.callable = null
879
+ this.stream = streaming ? newStream(null) : null
880
+ this.plain = this.expiry === null && this.stream === null
881
+ this.bareWrite =
882
+ this.schema === null && this.transform === null && !streaming
883
+ this.simple = false
884
+ this.scope = currentScope()
885
+ this.global = options?.global === true
886
+ this.ref = null
887
+ this.filed = false
888
+ this.orphaned = false
889
+ simpleShape(this)
890
+ }
891
+
892
+ notify(): void {
893
+ run(this)
894
+ }
895
+ }
896
+
897
+ /** What a member's `this` is, and the one way from the value an app holds to its record. */
898
+ type Callable = { [CELL]: Cell }
899
+
900
+ /**
901
+ * Throws where a value declares both `throttle` and `debounce`.
902
+ *
903
+ * 5.14 is a BUILD error and there is no build yet, so it lands at construction — the
904
+ * earliest moment that exists, and the one the app still has a stack for. Naming the value
905
+ * is the clause's own requirement; without it a page declaring both on one of forty values
906
+ * says only that something did. One statement for both producers of a window: a value's
907
+ * (5.8) and a keyed value's, which caps starts rather than wakes (5.19).
908
+ */
909
+ export function refuseBothCaps(
910
+ label: string,
911
+ throttle: number | undefined,
912
+ debounce: number | undefined,
913
+ ): void {
914
+ if (throttle !== undefined && debounce !== undefined)
915
+ throw new Error(
916
+ `${label} declares both throttle and debounce. A value is capped one way or the other.`,
917
+ )
918
+ }
919
+
920
+ function capFor(
921
+ label: string,
922
+ throttle: number | undefined,
923
+ debounce: number | undefined,
924
+ ): Cap | null {
925
+ refuseBothCaps(label, throttle, debounce)
926
+ const ms = throttle ?? debounce
927
+ if (ms === undefined) return null
928
+ return {
929
+ leading: throttle !== undefined,
930
+ ms,
931
+ timer: null,
932
+ held: undefined,
933
+ holding: false,
934
+ minted: undefined,
935
+ owed: false,
936
+ reloading: false,
937
+ }
938
+ }
939
+
940
+ /**
941
+ * Compiles `identity` into a comparator, or `null` for the default `Object.is`.
942
+ *
943
+ * THE DEFAULT IS THE REFERENCE, and `structural` is exported for an app to pass.
944
+ *
945
+ * THE CASE FOR A STRUCTURAL DEFAULT IS REAL: a reload that fetched an equal
946
+ * payload builds a FRESH object, so a reference compare never fires and every reader
947
+ * wakes on a value that did not change. What decides it against that is the cost on
948
+ * the shape an app actually holds — a compare walks the whole value on EVERY write,
949
+ * where the wake it avoids is paid only when the payload really is equal. A grid of
950
+ * rows re-assembled per recompute pays the deep walk every time and collapses never.
951
+ *
952
+ * So the framework takes the cheap, predictable default — `===` is what JavaScript
953
+ * means by "the same value" — and the app names `identity: structural` on the values
954
+ * where re-materialisation is the common case. 5.5's "not equal wherever it cannot
955
+ * decide" is unchanged; it is just no longer the default reading.
956
+ *
957
+ * `identity` is discriminated by ARITY (5.3), once, at construction — not per compare.
958
+ *
959
+ * NULL IS THE DEFAULT, not a function that implements it. `produce` compares against
960
+ * `null` and calls `Object.is` directly, which takes an INDIRECT call off the write path:
961
+ * the site is polymorphic across the default, a projection closure and whatever an app
962
+ * passed, so it is not one an engine can speculate through. The saving is the indirection
963
+ * rather than the comparison — `Object.is` is itself the fastest spelling of it.
964
+ */
965
+ function comparatorFor(
966
+ identity: Identity<unknown> | undefined,
967
+ ): ((next: unknown, previous: unknown) => boolean) | null {
968
+ if (identity === undefined) return null
969
+ if (identity.length >= 2)
970
+ return identity as (next: unknown, previous: unknown) => boolean
971
+ const project = identity as (value: unknown) => unknown
972
+ return (next, previous) => project(next) === project(previous)
973
+ }
974
+
975
+ /**
976
+ * Recomputes `simple` and re-seats the callable on the matching prototype.
977
+ *
978
+ * `simple` IN ONE PLACE, and the prototype that goes with it. A second copy of this
979
+ * conjunction is the drift that would let one of the four sites go on reading `true` after
980
+ * the field under it moved — and what the short write would then skip is a cap, a ring or a
981
+ * declared `identity`, silently.
982
+ *
983
+ * THE CALLABLE IS RE-SEATED ONLY WHERE IT IS ON ONE OF THESE TWO. A value that is adopting or
984
+ * forwarding a stream carries a prototype of its own and keeps it; the field is still
985
+ * maintained, so the seat it lands on when the adoption drops is the right one.
986
+ */
987
+ function simpleShape(cell: Cell): void {
988
+ cell.simple =
989
+ cell.bareWrite &&
990
+ // `plain` carries `expiry === null` and `stream === null` already.
991
+ cell.plain &&
992
+ cell.cap === null &&
993
+ cell.store === null &&
994
+ cell.identityFn === null
995
+ const callable = cell.callable
996
+ if (callable === null) return
997
+ const seat = Object.getPrototypeOf(callable)
998
+ if (seat !== MEMBER_PROTOTYPE && seat !== SIMPLE_PROTOTYPE) return
999
+ Object.setPrototypeOf(
1000
+ callable as object,
1001
+ cell.simple ? SIMPLE_PROTOTYPE : MEMBER_PROTOTYPE,
1002
+ )
1003
+ }
1004
+
1005
+ /**
1006
+ * The effect queue a mark walk fills and the drain empties.
1007
+ *
1008
+ * THE EFFECT QUEUE. A mark walk runs no body, so something has to run the ones that
1009
+ * must: every EFFECT the walk reached lands here and is resolved by the drain at the end of
1010
+ * the turn. Derived values are NOT queued — nothing runs them until something reads them,
1011
+ * which is the whole of push-pull — save 2.13's aborted body, see `drainPending`.
1012
+ *
1013
+ * An array and a read cursor rather than `shift()`: an effect that writes appends to the
1014
+ * queue the drain is already walking, and shifting would move every remaining entry per
1015
+ * take.
1016
+ * A COUNT RATHER THAN THE ARRAY'S OWN LENGTH, and the array is never truncated.
1017
+ * `PENDING.length = 0` is what an engine reads as "this array is finished with", and it
1018
+ * hands the backing store back — so the next write's push allocated one again, on every
1019
+ * write that reaches an effect. Holding the capacity and moving a cursor over it makes a
1020
+ * push a plain indexed store.
1021
+ */
1022
+ const PENDING: (Subscriber | null)[] = []
1023
+ let pendingCount = 0
1024
+ let pendingAt = 0
1025
+ /**
1026
+ * Whether a drain is already in flight.
1027
+ *
1028
+ * A write made from inside an effect appends to the queue the outer drain is walking rather than
1029
+ * opening a second one, which is what orders a nested write's effects AFTER the one that made it
1030
+ * rather than underneath it.
1031
+ */
1032
+ let draining = false
1033
+ /** Whether a drain is already queued for the end of this turn. */
1034
+ let scheduled = false
1035
+
1036
+ /**
1037
+ * Queues the drain for the end of this turn.
1038
+ *
1039
+ * THE DRAIN IS DEFERRED AND THE MARK IS NOT, which is the whole of the batching and is
1040
+ * only safe because reads PULL. A write stamps the graph synchronously, so a read taken
1041
+ * immediately after one is correct — it resolves what it finds marked. What waits for the
1042
+ * end of the turn is the part that touches the page.
1043
+ *
1044
+ * WITHOUT IT EVERY WRITE IS ITS OWN FLUSH. Measured against a binding that writes on every
1045
+ * wake: ten writes in one handler were ten `.data` writes where one value is ever seen,
1046
+ * and three values written together were five, because the binding reading all three ran
1047
+ * once per write. A diamond was already one — that is what the depth-first resolve buys,
1048
+ * and this is the same insight one turn up.
1049
+ */
1050
+ function schedule(): void {
1051
+ if (scheduled || draining) return
1052
+ scheduled = true
1053
+ queueMicrotask(flush)
1054
+ }
1055
+
1056
+ function flush(): void {
1057
+ scheduled = false
1058
+ if (pendingCount === 0 || draining) return
1059
+ drainPending()
1060
+ }
1061
+
1062
+ /**
1063
+ * Runs every pending effect now rather than at the end of the turn.
1064
+ *
1065
+ * THE ESCAPE FROM THE BATCH, and batching is what makes it necessary. Everything that has
1066
+ * to see the page as the writes left it — a test, a measurement, a server rendering to a
1067
+ * string — needs the turn to end on demand rather than when the microtask queue says so.
1068
+ * It is the only way to observe an effect in the same turn as the write that caused it.
1069
+ */
1070
+ export function flushSync(): void {
1071
+ // IT DOES NOT CLEAR `scheduled`. The microtask already queued will fire and find the
1072
+ // queue empty, which costs nothing — where clearing it makes the NEXT write in this
1073
+ // same turn queue another one, and a write-then-flush loop pays `queueMicrotask` per
1074
+ // write rather than once per turn. Measured at 26.5 ns a write against 14.2 before the
1075
+ // flush was there at all.
1076
+ // 9.10: a wake a stream is holding for the next task is one this turn ends too.
1077
+ if (WAKING.length !== 0) wakeStreams()
1078
+ if (pendingCount === 0 || draining) return
1079
+ drainPending()
1080
+ }
1081
+
1082
+ /**
1083
+ * Sets `direct` where `when` holds and the value is `plain`.
1084
+ *
1085
+ * WHAT A VALUE CARRYING A `ttl` GIVES UP, stated once because four paths restore `direct`
1086
+ * and a fifth that forgot would serve an expired production with nothing about the output
1087
+ * saying so. `direct` is the one load and one branch the read path gets; an expiry cell
1088
+ * is never direct, so every read of it goes a frame in to `readIndirect` — which is
1089
+ * exactly where 6.5 and 6.6 are answered, and is why a value declaring no `ttl`
1090
+ * never reaches a clock. See `Expiry.ts`. A stream is never direct either, for the same
1091
+ * shape of reason: its read is where the accumulation is materialised (9.1).
1092
+ */
1093
+ function setDirect(cell: Cell, when: boolean): void {
1094
+ cell.direct = when && cell.plain
1095
+ }
1096
+
1097
+ /**
1098
+ * Marks a production's readers `wanted` and everything beyond them `CHECK`, running nothing.
1099
+ *
1100
+ * ONE WALK BEFORE ANYTHING RUNS, SETTING A FLAG AND RUNNING NOTHING. Direct readers of
1101
+ * the cell that produced are `DIRTY` — a source of theirs demonstrably moved. Everything
1102
+ * beyond them is `CHECK`, because whether the change REACHES them is not known until the
1103
+ * nodes between have been asked, and 5.2 says a derived value that recomputes to what it
1104
+ * already held wakes nobody.
1105
+ *
1106
+ * This is the ordering fix too: without the walk, A -> B, A -> C, B + C -> D resolves D
1107
+ * from B while C still holds its old value, and the production D mints there carries
1108
+ * `b_new + c_old` — a value the system was never in, which reaches `watch` and the
1109
+ * ordinal. With it, D's read of C finds C marked and pulls it forward first.
1110
+ */
1111
+ function markReaders(cell: Cell, wanted: number): void {
1112
+ const readers = cell.readers
1113
+ for (let index = 0; index < readers.length; index += 1) {
1114
+ const reader = readers[index] as Subscriber
1115
+ // A mark never weakens, and stopping where one is already at least this strong
1116
+ // keeps the walk O(V) rather than O(paths) over a shared subgraph. Skipping one
1117
+ // that is RUNNING is what stops a body re-marking itself when a source it pulled
1118
+ // forward produces underneath it.
1119
+ if (!reader.alive || reader.running || reader.state >= wanted) continue
1120
+ // One node VISITED. Past the guard above, so it counts what the walk did rather than
1121
+ // what it was offered — the difference between the two is the whole of the O(V) claim.
1122
+ WORK.descents += 1
1123
+ const was = reader.state
1124
+ reader.state = wanted
1125
+ if (reader.isEffect) {
1126
+ // A MIRROR RUNS HERE rather than at the end of the turn: it carries a VALUE,
1127
+ // and a read taken before the drain has to find it. No body runs inside it —
1128
+ // the production it mints marks on through this same walk. BUT ONLY WHERE WHAT
1129
+ // IT MIRRORS HAS PRODUCED: an adopted DERIVED value reached by this walk is only
1130
+ // marked, still holding what it held, and copied here it is copied stale and the
1131
+ // reader left clean. That one is queued like any effect, and the drain's `CHECK`
1132
+ // pulls the derived body forward before the mirror copies anything.
1133
+ if (reader.isMirror && cell.state === CLEAN) {
1134
+ reader.state = CLEAN
1135
+ reader.notify()
1136
+ continue
1137
+ }
1138
+ // Queued once. An upgrade from `CHECK` to `DIRTY` finds it already there.
1139
+ if (was === CLEAN) {
1140
+ PENDING[pendingCount] = reader
1141
+ pendingCount += 1
1142
+ }
1143
+ continue
1144
+ }
1145
+ const below = reader as unknown as Cell
1146
+ // Marked is not directly servable, whatever it holds.
1147
+ below.direct = false
1148
+ // 2.13, 3.2, AND THE ONLY PLACE PUSH-PULL RUNS A DERIVED BODY. What is asking is a GUARD: a
1149
+ // reader on the probe edge asks `ready()` and never the value, so no read of its will pull
1150
+ // this body forward, and what the probe answers is about the value a read WOULD serve
1151
+ // (3.2) — a body whose inputs moved to a load is not ready, whatever its last run held. So
1152
+ // the drain pulls it, and the guard wakes only where a probe moved. A reader on the VALUE
1153
+ // edge needs none of this — its own read pulls — so this is the probe edge alone, and a
1154
+ // body nothing probes stays as lazy as 11.5 makes it.
1155
+ if (was === CLEAN && below.probeReaders.length !== 0) {
1156
+ PENDING[pendingCount] = reader
1157
+ pendingCount += 1
1158
+ }
1159
+ // 5.11: A CAPPED BODY IS A BARRIER IN THE CASCADE. The mark arrives here and
1160
+ // stops — nothing downstream is woken (5.8) and the body does not run, so the
1161
+ // load it would have issued is never issued rather than issued and discarded.
1162
+ // That is the whole difference between capping a value and capping a body: a
1163
+ // value's production has already been handed in and must be retained (5.9),
1164
+ // where a body's work has not started yet and 5.11 says not to start it.
1165
+ //
1166
+ // THE WINDOW IS ARMED HERE BECAUSE THIS IS WHERE A SOURCE PRODUCING IS VISIBLE.
1167
+ // A read cannot tell one change from ten, so a debounce armed at the read fires
1168
+ // a fixed interval after the first change rather than once the changes stop.
1169
+ //
1170
+ // THE LOAD IS NOT MEASURABLE. It was the reason to expect a cost here — one more
1171
+ // field read per marked node in the hottest walk in the core — and across two
1172
+ // runs the abide arm is flat on every graph row: chain 20 at 2.47x against a
1173
+ // 2.44x-2.50x baseline, DAG 5x3 at 1.96x against 1.93x, fan-in 100 unchanged. The
1174
+ // ratios wobble because the hand-written arm moves with machine state; `below` was
1175
+ // stored to on the line above, so this reads a line already in cache.
1176
+ const cap = below.cap
1177
+ if (cap !== null && below.body !== null) {
1178
+ if (windowHolds(below, cap)) {
1179
+ cap.owed = true
1180
+ // BACK TO CLEAN so the next source production marks it again and re-arms.
1181
+ // Left marked it takes this walk's own `state >= wanted` short-circuit,
1182
+ // and the changes after the first become invisible to the window.
1183
+ below.state = CLEAN
1184
+ setDirect(below, below.servable)
1185
+ continue
1186
+ }
1187
+ }
1188
+ // Only a node this walk has not reached descends, and only where it HAS a
1189
+ // subtree: one already marked is already at least `CHECK`, which is the
1190
+ // strongest thing this walk could say, and one with no readers is the shape
1191
+ // push-pull makes most of — a fan of a hundred derived values that nothing
1192
+ // downstream reads was entering the walk a hundred times to loop over nothing.
1193
+ if (was === CLEAN && below.readers.length !== 0)
1194
+ markReaders(below, CHECK)
1195
+ }
1196
+ }
1197
+
1198
+ /**
1199
+ * Pulls a marked value up to date, running its body only if a source produced.
1200
+ *
1201
+ * PULL. A `DIRTY` cell runs. A `CHECK` cell asks its sources first and runs only if one
1202
+ * of them produced — `produce` is what upgrades a reader from `CHECK` to `DIRTY`, so
1203
+ * "did anything actually reach me" is answered by the mark arriving during the walk
1204
+ * rather than by comparing versions afterwards.
1205
+ */
1206
+ function resolve(cell: Cell): void {
1207
+ const state = cell.state
1208
+ if (state === CLEAN) return
1209
+ // On the stack already: its value is whatever its run has reached, and re-entering
1210
+ // is the cycle guard.
1211
+ if (cell.running) return
1212
+ if (state === CHECK) {
1213
+ const sources = cell.sources
1214
+ for (let index = 0; index < sources.length; index += 1) {
1215
+ // The CLEAN test is here rather than behind the call: a node this walk did
1216
+ // not reach is the common source, and asking it costs a load instead of a
1217
+ // frame. A body with a thousand sources of which one moved asks all thousand.
1218
+ const source = sources[index] as Cell
1219
+ if (source.state !== CLEAN) resolve(source)
1220
+ // Resolving that source produced, and the production marked this cell. The
1221
+ // rest of the sources are pulled forward by the body's own reads.
1222
+ if (cell.state === DIRTY) break
1223
+ }
1224
+ if (cell.state !== DIRTY) {
1225
+ cell.state = CLEAN
1226
+ // Nothing it reads moved, so what it already holds is servable again. The
1227
+ // mark cleared this on the way down and only here can it come back — a
1228
+ // `CHECK` that resolves to nothing never reaches `produce`.
1229
+ setDirect(cell, cell.servable)
1230
+ return
1231
+ }
1232
+ }
1233
+ cell.state = CLEAN
1234
+ run(cell)
1235
+ }
1236
+
1237
+ /**
1238
+ * Runs a queued effect only if something it reads actually moved.
1239
+ *
1240
+ * An effect whose turn has come and which the drain's `DIRTY` arm did not take. `CHECK`
1241
+ * is the case eager could not express: the effect was reached by the mark walk, and
1242
+ * whether anything it reads actually moved is decided here rather than by running it and
1243
+ * letting it read the same values again.
1244
+ */
1245
+ function resolveEffect(reader: Subscriber): void {
1246
+ if (!reader.alive) {
1247
+ reader.state = CLEAN
1248
+ return
1249
+ }
1250
+ // Brought current since it was queued — a guard's probe pulls the cell it queued (3.2) — so
1251
+ // there is nothing owed, and a second run would wake that guard onto what it already saw.
1252
+ if (reader.state === CLEAN) return
1253
+ if (reader.state === CHECK) {
1254
+ const sources = reader.sources
1255
+ for (let index = 0; index < sources.length; index += 1) {
1256
+ const source = sources[index] as unknown as Cell
1257
+ if (source.state !== CLEAN) resolve(source)
1258
+ if (reader.state === DIRTY) break
1259
+ }
1260
+ if (reader.state !== DIRTY) {
1261
+ reader.state = CLEAN
1262
+ return
1263
+ }
1264
+ }
1265
+ // CLEARED BEFORE, not after: `running` is what blocks a re-mark while the body is on
1266
+ // the stack, and clearing after would drop a mark a nested write legitimately made.
1267
+ reader.state = CLEAN
1268
+ reader.notify()
1269
+ }
1270
+
1271
+ /**
1272
+ * Wakes the probe readers of everything downstream whose floor moved.
1273
+ *
1274
+ * A PROBE MOVED, AND NO VALUE DID. Going loading on a refresh, coming back on a settle,
1275
+ * losing what there was to serve on an invalidate — each changes what every reader
1276
+ * DOWNSTREAM reports (11.20's floor) and mints nothing for a cascade to carry.
1277
+ *
1278
+ * It walks the VALUE edge downstream to find the cells whose floor moved, and wakes the
1279
+ * `probeReaders` of each — never their `readers`. That distinction is the whole point: the
1280
+ * rows painting the value are not woken, and the guards asking about it are.
1281
+ */
1282
+ function markProbes(cell: Cell, pass: number): void {
1283
+ if (cell.probePass === pass) return
1284
+ cell.probePass = pass
1285
+ markAsked(cell.probeReaders)
1286
+ // 13.3: a guard over a tag selection asked the SELECTION, so it hears through the selection's
1287
+ // signal rather than through this value's own probe readers.
1288
+ if (cell.tags !== null) markSignals(cell.tags)
1289
+ // The bare selection's guard hears every filed value's floor move; one load where nothing asks.
1290
+ if (EVERY_PRODUCER.probeReaders.length !== 0 && cell.filed)
1291
+ markAsked(EVERY_PRODUCER.probeReaders)
1292
+ // The floor of everything built from this one moved with it — what READ it, and what
1293
+ // ADOPTED it (11.50), which is on this list as its mirror rather than as itself.
1294
+ const readers = cell.readers
1295
+ for (let index = 0; index < readers.length; index += 1) {
1296
+ const reader = readers[index] as Subscriber
1297
+ if (!reader.isEffect) markProbes(reader as unknown as Cell, pass)
1298
+ else if (reader.adopter !== null)
1299
+ markProbes(reader.adopter as unknown as Cell, pass)
1300
+ }
1301
+ }
1302
+
1303
+ function markAsked(asked: Subscriber[]): void {
1304
+ for (let index = 0; index < asked.length; index += 1) {
1305
+ const reader = asked[index] as Subscriber
1306
+ if (!reader.alive || reader.running || reader.state === DIRTY) continue
1307
+ const was = reader.state
1308
+ reader.state = DIRTY
1309
+ if (reader.isEffect) {
1310
+ if (was === CLEAN) {
1311
+ PENDING[pendingCount] = reader
1312
+ pendingCount += 1
1313
+ }
1314
+ continue
1315
+ }
1316
+ const below = reader as unknown as Cell
1317
+ below.direct = false
1318
+ if (was === CLEAN && below.readers.length !== 0)
1319
+ markReaders(below, CHECK)
1320
+ }
1321
+ }
1322
+
1323
+ /**
1324
+ * Opens a probe cascade for a move no production carries.
1325
+ *
1326
+ * The cascade's shape, for a move no production carries. Safe to share `probePass` with
1327
+ * `walkBusy` and `walkReady`: this marks and queues, and nothing runs until the drain
1328
+ * below it, so a probe read can never be inside this walk.
1329
+ */
1330
+ function probesMoved(cell: Cell): void {
1331
+ PROBE_PASS += 1
1332
+ markProbes(cell, PROBE_PASS)
1333
+ if (draining || pendingCount === 0) return
1334
+ schedule()
1335
+ }
1336
+
1337
+ /**
1338
+ * Wakes the guards subscribed to `signal`'s probe edge — a node that is nothing but that edge.
1339
+ *
1340
+ * What a `Keyed`'s statics hear an entry being reached or released through: membership is not a
1341
+ * probe of any entry, so a guard asked before a key existed has no entry to hear it from.
1342
+ */
1343
+ export function signalMoved(signal: Tracked): void {
1344
+ if (signal.probeReaders.length === 0) return
1345
+ markAsked(signal.probeReaders)
1346
+ if (draining || pendingCount === 0) return
1347
+ schedule()
1348
+ }
1349
+
1350
+ /**
1351
+ * Marks a production's readers and schedules the effects it reached.
1352
+ *
1353
+ * THE CASCADE, WHICH NO LONGER RUNS A SINGLE DERIVED BODY. It marks, and it schedules the
1354
+ * effects the mark reached for the drain at the end of the turn (see `schedule`); everything
1355
+ * else is run by the read that wants it.
1356
+ */
1357
+ function cascade(cell: Cell): void {
1358
+ // A DERIVED VALUE NOTHING READS is the shape push-pull creates most of: a fan of a
1359
+ // hundred, of which one is read. Testing the length here rather than entering the
1360
+ // walk takes a call frame off every one of the other ninety-nine.
1361
+ if (cell.readers.length !== 0) markReaders(cell, DIRTY)
1362
+ // A write made from inside an effect appends to the queue the outer drain is
1363
+ // walking. Opening a second drain here would run the nested write's effects
1364
+ // underneath the effect that made it and before that effect had finished.
1365
+ if (draining) return
1366
+ // NOTHING TO RUN IS THE COMMON WRITE, and it must not pay for the drain. Writing
1367
+ // `PENDING.length = 0` unconditionally cost 35 ns on a write with no readers at all
1368
+ // — six times the whole op — because a length store is not free even where the array
1369
+ // is already empty. Every write in a graph whose effects are all upstream of it
1370
+ // takes this arm.
1371
+ if (pendingCount === 0) return
1372
+ schedule()
1373
+ }
1374
+
1375
+ /**
1376
+ * Runs the queued effects, abandoning the queue if one throws.
1377
+ *
1378
+ * THE DRAIN, BEHIND ITS OWN FRAME. A `try`/`finally` in `cascade` is a `try`/`finally`
1379
+ * on every write, and the arm that needs it is the one that actually has an effect to
1380
+ * run — so the guard is up there and the handler is down here.
1381
+ */
1382
+ function drainPending(): void {
1383
+ draining = true
1384
+ try {
1385
+ // Re-read `pendingCount` per turn: an effect that writes appends to the queue
1386
+ // this loop is walking, and those belong to this drain rather than the next write.
1387
+ while (pendingAt < pendingCount) {
1388
+ const reader = PENDING[pendingAt] as Subscriber
1389
+ // THE SLOT IS RELEASED, THE ARRAY IS NOT. Holding the capacity is what keeps a
1390
+ // push a plain indexed store, and a slot left pointing at a drained subscriber
1391
+ // holds its `notify` — and through it the effect body and the whole scope that
1392
+ // body closed over — until another effect happens to land on that index. A
1393
+ // disposed `watch` stayed reachable to the next high-water mark, which on a page
1394
+ // is every node the torn-down component built. One store per effect ALREADY RUN,
1395
+ // against a body call.
1396
+ PENDING[pendingAt] = null
1397
+ pendingAt += 1
1398
+ // A DIRECT READER OF WHAT WAS WRITTEN is `DIRTY`, which is the overwhelming
1399
+ // shape and asks nothing: there is no source to interrogate, because the
1400
+ // mark says one of them already produced.
1401
+ if (reader.state === DIRTY && reader.alive) {
1402
+ reader.state = CLEAN
1403
+ reader.notify()
1404
+ continue
1405
+ }
1406
+ resolveEffect(reader)
1407
+ }
1408
+ } finally {
1409
+ // The queue is abandoned rather than carried into the next write: an effect that
1410
+ // threw has already stopped its own watch (12.8), and a half-drained queue
1411
+ // outliving the throw would run it against a later write's marks. The tail is
1412
+ // released for the reason the loop above releases each slot; on the path that did
1413
+ // not throw the cursor has already reached the count and this walks nothing.
1414
+ //
1415
+ // THE MARK GOES WITH THE QUEUE, and that is what abandoning has to mean. A reader
1416
+ // left standing at `DIRTY` with nothing holding it takes `markReaders`' own
1417
+ // `state >= wanted` short-circuit on every later write, so it is never queued
1418
+ // again — one effect throwing left every sibling it had not reached permanently
1419
+ // deaf, silently, while the value went on being right. Back to `CLEAN` is the
1420
+ // state the next write's mark can reach.
1421
+ //
1422
+ // AN EFFECT ONLY, THOUGH. The queue is not effects alone: `markReaders` also pushes a
1423
+ // derived CELL on 2.13's aborted-body path, and for one of those `state` is not a
1424
+ // reminder to run — it IS the pull the next read takes (`state !== CLEAN` is what sends
1425
+ // a read a frame in). Forced back to `CLEAN` it is not deaf, it is settled: the read
1426
+ // path skips `resolve`, the aborted body is never re-run and the `ready()` guard that
1427
+ // queued it answers false for the life of the page — undoing, on any throw anywhere in
1428
+ // the drain, exactly what that push was added to repair.
1429
+ for (let index = pendingAt; index < pendingCount; index += 1) {
1430
+ const abandoned = PENDING[index] as Subscriber
1431
+ PENDING[index] = null
1432
+ if (abandoned.isEffect) abandoned.state = CLEAN
1433
+ }
1434
+ pendingAt = 0
1435
+ pendingCount = 0
1436
+ draining = false
1437
+ }
1438
+ }
1439
+
1440
+ /**
1441
+ * Mints one production and serves it, or collapses it as a repeat; returns the ordinal.
1442
+ *
1443
+ * One production. A write that `identity` deems a repeat mints nothing and wakes nobody (5.2).
1444
+ */
1445
+ function produce(cell: Cell, produced: unknown): number {
1446
+ // 7.9: AN ACCEPTED PRODUCTION SETTLES THE RELOAD AN INVALIDATE OWED — ahead of the gate, since
1447
+ // a write 5.2 collapses was still accepted. Left standing, the next read unserved this value
1448
+ // and reloaded over it. A look above (`OWES_ABOVE`) is not this value's mark and stays: 11.8
1449
+ // has a write stand without settling what it is built from.
1450
+ if (cell.owes === OWES_RELOAD) cell.owes = OWES_NOTHING
1451
+ const cap = cell.cap
1452
+ // 5.9: the gate compares against the last production MINTED. That is the held value
1453
+ // on everything that never caps, and `cap.minted` is where a window has moved the two
1454
+ // apart.
1455
+ //
1456
+ // A CAP OVER A BODY MOVES NEITHER. 5.11 caps the RUN there, so the production goes
1457
+ // straight out and `capped` — which writes `cap.minted` for a production — is never
1458
+ // reached. Read unconditionally, `previous` was `undefined` on every recompute of a
1459
+ // capped derived value, so 5.2 collapsed nothing and every reader woke on a value that
1460
+ // had not moved.
1461
+ // The same test `produce` already picks `capped` by, one frame down.
1462
+ if (cell.landed) {
1463
+ const previous =
1464
+ cap === null || cell.body !== null ? cell.value : cap.minted
1465
+ if (
1466
+ cell.identityFn === null
1467
+ ? // `Object.is` rather than `===` for one case: a repeated `NaN` is the
1468
+ // same value and would otherwise wake every reader forever. Called
1469
+ // rather than spelled out — an engine intrinsifies it, and the
1470
+ // hand-written equivalent measured 0.80 ns against its 0.66 ns on the
1471
+ // same input.
1472
+ Object.is(produced, previous)
1473
+ : cell.identityFn(produced, previous)
1474
+ ) {
1475
+ // The value did not move, so 5.2 mints nothing — but a load in flight is over and
1476
+ // `busy` has moved, which a reader that asked about it has to hear. A standing
1477
+ // failure is the third probe moving: 4.11 clears it below, and a guard on
1478
+ // `error` hears that the same way one on `busy` hears the load ending.
1479
+ //
1480
+ // 4.11: an ACCEPTED write clears the standing error, and a write the identity gate
1481
+ // collapses was still accepted — it produced nothing because the value was already
1482
+ // the one being written, not because it failed. Leaving the failure standing left
1483
+ // `s.error()` reporting a load that a later write superseded.
1484
+ const wasServable = cell.servable
1485
+ const settling = settleProbes(cell)
1486
+ cell.servable = true
1487
+ setDirect(cell, cell.state === CLEAN)
1488
+ // THE VALUE EDGE MOVED TOO WHERE THERE WAS NOTHING TO SERVE, whatever the gate
1489
+ // says about the payload — the same split `refused` makes, and for the same
1490
+ // reason. A read taken while this was unservable THREW, so a body that reached
1491
+ // it aborted: it is `CLEAN`, holds nothing, and nothing downstream will ever
1492
+ // pull it. Left silent, an `invalidate` whose reload landed the value it already
1493
+ // held stranded every value built from it at `ready()` false for the life of the
1494
+ // page. Over a value still being served nothing a reader can see moved (5.1) and
1495
+ // this stays quiet, which is the arm 5.2 is about.
1496
+ if (!wasServable) cascade(cell)
1497
+ if (settling) probesMoved(cell)
1498
+ return cell.ordinal
1499
+ }
1500
+ }
1501
+ const moved = settleProbes(cell)
1502
+ // ONE CLOCK READ PER PRODUCTION, AND ONLY WHERE ONE WAS ASKED FOR. The `null` test is
1503
+ // a load and a compare; the `Date.now()` behind it is the part a value declaring no
1504
+ // `ttl` must not pay.
1505
+ const expiry = cell.expiry
1506
+ const mintedAt = expiry === null ? 0 : Date.now()
1507
+ // 6.10: AN `undefined` IS SERVED AND MOVES NO ORDINAL, so no cursor is handed one — it is not a
1508
+ // message, and not a JSON value either.
1509
+ if (produced !== undefined) cell.ordinal += 1
1510
+ if (expiry !== null) {
1511
+ expiry.at = mintedAt
1512
+ // A production is what 6.7 released being replaced, so the value is no longer
1513
+ // waiting for one (6.6). The timer is armed in `serve` rather than here, where
1514
+ // the value is not servable yet and the deadline it holds cannot be read.
1515
+ expiry.dropped = false
1516
+ }
1517
+ // A BODY'S CAP GATED THE RUN, NOT WHAT IT PRODUCED (5.11): the window has already
1518
+ // decided this run should happen, and holding its production too would delay it a
1519
+ // second window.
1520
+ if (cap !== null && cell.body === null)
1521
+ return capped(cell, cap, produced, moved)
1522
+ serve(cell, produced)
1523
+ cascade(cell)
1524
+ if (moved) probesMoved(cell)
1525
+ return cell.ordinal
1526
+ }
1527
+
1528
+ /**
1529
+ * Ends the load and the standing refusal; returns whether a probe moved.
1530
+ *
1531
+ * WHAT A PRODUCTION ENDS: the load in flight (`busy`) and a standing refusal (`error`, which 4.11
1532
+ * clears). What it hands back is whether a probe moved — either of those, or `ready`, there having
1533
+ * been nothing to serve — read BEFORE the change it describes, and it is the probe move the caller
1534
+ * owes. A plain write on a value already serving moves none of them, which is the common path.
1535
+ */
1536
+ function settleProbes(cell: Cell): boolean {
1537
+ const moved = cell.loading || !cell.servable || cell.failure !== undefined
1538
+ cell.loading = false
1539
+ cell.failure = undefined
1540
+ return moved
1541
+ }
1542
+
1543
+ /**
1544
+ * Makes a production what readers see: stores it, arms its deadline, persists it.
1545
+ *
1546
+ * THE READER-VISIBLE HALF OF A PRODUCTION, which is exactly what a window separates from
1547
+ * the production itself. One copy, reached from the uncapped write and from the release
1548
+ * alike — the alternative was a second spelling of the transition, which is the drift this
1549
+ * file has already paid for once.
1550
+ */
1551
+ function serve(cell: Cell, value: unknown): void {
1552
+ cell.value = value
1553
+ cell.landed = true
1554
+ cell.servable = true
1555
+ // THE ONE PLACE `direct` IS SET TRUE ON A PRODUCTION, and it reads the state rather
1556
+ // than assuming it: a write can land on a value a mark walk has already reached, and
1557
+ // 11.8 has that write STAND without clearing the recompute owed to it.
1558
+ setDirect(cell, cell.state === CLEAN)
1559
+ // 6.3's ONE ARMING SITE, and it is here because this is the line that makes the value
1560
+ // servable — `armNext` reads the deadline off a production that has landed, and from
1561
+ // `produce` it would be reading one that had not.
1562
+ if (cell.expiry !== null) armNext(cell, cell.expiry)
1563
+ // 8.8: every production that reaches a reader is written, and nothing else is — a write the
1564
+ // identity gate collapsed never arrives here.
1565
+ if (cell.store !== null) persist(cell, cell.store, value)
1566
+ }
1567
+
1568
+ /**
1569
+ * Whether a window holds this arrival, opening or pushing back the window either way.
1570
+ *
1571
+ * HOLD OR GO, for everything a window caps — a body's run (5.11), a refresh (5.24), a production
1572
+ * and a stream's chunks (5.17) — and the window is opened or pushed back either way. 5.12: a
1573
+ * throttle with no window open lets this one through and opens one, and re-arming inside an open
1574
+ * one would make it a debounce. 5.13: a debounce holds everything and every arrival pushes its
1575
+ * window back, so the release is what happens when they stop.
1576
+ */
1577
+ function windowHolds(cell: Cell, cap: Cap): boolean {
1578
+ const open = cap.timer !== null
1579
+ if (!open || !cap.leading) openWindow(cell, cap)
1580
+ return open || !cap.leading
1581
+ }
1582
+
1583
+ /**
1584
+ * Whether an arrival passes the window; the first landing always does.
1585
+ *
1586
+ * 5.15: the first landing goes through, having nothing to collapse against — and a debounce's
1587
+ * window is not opened by it, where a throttle's is.
1588
+ */
1589
+ function passes(cell: Cell, cap: Cap): boolean {
1590
+ if (cell.landed) return !windowHolds(cell, cap)
1591
+ if (cap.leading) openWindow(cell, cap)
1592
+ return true
1593
+ }
1594
+
1595
+ /**
1596
+ * Whether a production wakes readers now; holds it for the window's close if not.
1597
+ *
1598
+ * A production's wake goes now or is held for the window's close — the pass-or-hold tail that a
1599
+ * write (`capped`) and a patch (5.23) share. The window moves `minted` apart from `value` either way.
1600
+ */
1601
+ function wakes(cell: Cell, cap: Cap, produced: unknown): boolean {
1602
+ cap.minted = produced
1603
+ if (passes(cell, cap)) return true
1604
+ hold(cell, cap, produced)
1605
+ return false
1606
+ }
1607
+
1608
+ /**
1609
+ * Whether a stream's readers are told of its chunks now, or at the window's close.
1610
+ *
1611
+ * A stream's chunks: the buffer already has them, so what the window holds is the telling (5.17).
1612
+ */
1613
+ function tellsChunks(cell: Cell, cap: Cap | null): boolean {
1614
+ if (cap === null || passes(cell, cap)) return true
1615
+ cap.holding = true
1616
+ return false
1617
+ }
1618
+
1619
+ /**
1620
+ * Serves a minted production now or holds it for the window; returns the ordinal.
1621
+ *
1622
+ * The production has minted; what is left is whether it reaches a reader now or waits for
1623
+ * the window. Behind its own frame because the uncapped write never arrives here.
1624
+ */
1625
+ function capped(
1626
+ cell: Cell,
1627
+ cap: Cap,
1628
+ produced: unknown,
1629
+ moved: boolean,
1630
+ ): number {
1631
+ // 5.15 CANNOT BE SATISFIED BY HOLDING THE FIRST LANDING: there is no held value to go
1632
+ // on serving, so a reader would get neither the value it had nor the one that arrived
1633
+ // — a `debounce` of 300 left a value not ready for 300 ms after construction. A window
1634
+ // collapses a RUN of changes and the first landing has nothing to collapse with.
1635
+ if (wakes(cell, cap, produced)) {
1636
+ serve(cell, produced)
1637
+ cascade(cell)
1638
+ if (moved) probesMoved(cell)
1639
+ }
1640
+ return cell.ordinal
1641
+ }
1642
+
1643
+ /**
1644
+ * Holds a production for the window's close and marks the value busy.
1645
+ *
1646
+ * HELD FOR THE WINDOW'S CLOSE, which `release` serves. 5.15: `loading` IS "work in flight", and a
1647
+ * window with something held is exactly that — so the probe answers from the field it already
1648
+ * reads rather than from a second one. `isBusy` is the leaf a spinner reads every frame and a load
1649
+ * it did not need was refused there once already.
1650
+ */
1651
+ function hold(cell: Cell, cap: Cap, value: unknown): void {
1652
+ cap.held = value
1653
+ cap.holding = true
1654
+ cell.loading = true
1655
+ // Nothing a reader can see moved, and `busy` did.
1656
+ probesMoved(cell)
1657
+ }
1658
+
1659
+ /**
1660
+ * Serves the held production as the window closes.
1661
+ *
1662
+ * The window closing, and the one wake per window that 5.12 and 5.13 each allow.
1663
+ */
1664
+ function release(cell: Cell, cap: Cap): void {
1665
+ cap.holding = false
1666
+ const value = cap.held
1667
+ cap.held = undefined
1668
+ cell.loading = false
1669
+ serve(cell, value)
1670
+ cascade(cell)
1671
+ // The close is a `busy` edge (5.15) even though the value's readiness never moved.
1672
+ probesMoved(cell)
1673
+ }
1674
+
1675
+ function releaseHeld(cell: Cell, cap: Cap): void {
1676
+ const stream = cell.stream
1677
+ if (stream !== null) {
1678
+ cap.holding = false
1679
+ releaseChunks(cell, stream)
1680
+ } else release(cell, cap)
1681
+ }
1682
+
1683
+ function openWindow(cell: Cell, cap: Cap): void {
1684
+ // 5.13 NEEDS THIS: a debounce calls in here on every production inside its window, and
1685
+ // the reset is what "until the changes stop" means. Without it each write arms its own
1686
+ // timer and the first to fire releases — a fixed delay from the FIRST change, which
1687
+ // reads identically to a debounce under any run of writes made in one turn.
1688
+ if (cap.timer !== null) clearTimeout(cap.timer)
1689
+ // `armTimer` for 6.4's reason, which a window shares with a deadline: a timer never holds the
1690
+ // process open. The keyed window already armed through it, so the two agree.
1691
+ armTimer(cap, cap.ms, () => {
1692
+ cap.timer = null
1693
+ // 5.24: the reload the window held back, which is the run as well. A production held beside
1694
+ // it is served first — the reload re-reads a store that production has not been written to
1695
+ // yet, and skipping it dropped the write and left `holding` standing.
1696
+ if (cap.reloading) {
1697
+ cap.reloading = false
1698
+ cap.owed = false
1699
+ if (cap.holding) releaseHeld(cell, cap)
1700
+ reloadNow(cell)
1701
+ if (cap.leading) openWindow(cell, cap)
1702
+ return
1703
+ }
1704
+ // 5.11: the run the window held back. Marking and cascading is all it does — the
1705
+ // body is pulled forward by the read that wants it, which is the same laziness
1706
+ // every other recompute gets.
1707
+ if (cap.owed) {
1708
+ cap.owed = false
1709
+ cell.state = DIRTY
1710
+ cell.direct = false
1711
+ cascade(cell)
1712
+ return
1713
+ }
1714
+ // A throttle's window ending with nothing held is the window simply over: the
1715
+ // next write leads again. With something held it releases and opens another, so a
1716
+ // run of writes wakes once per window rather than twice at every boundary.
1717
+ if (!cap.holding) return
1718
+ // A STREAM'S WINDOW HOLDS CHUNKS rather than a production, and closing it tells the readers
1719
+ // what landed meanwhile. Branched HERE, in the timer, rather than inside `release`: a stream
1720
+ // call reachable from `release` sits on the path every capped write walks through `capped`,
1721
+ // and measured 8.4 ns -> 10.5 ns on a capped write under V8 with no stream in it.
1722
+ releaseHeld(cell, cap)
1723
+ // A write made by one of the effects this release woke has already opened the
1724
+ // next window, and opening a second here would leave `cap.timer` pointing at this
1725
+ // one while that one goes on to fire and clear it.
1726
+ if (cap.leading) openWindow(cell, cap)
1727
+ })
1728
+ }
1729
+
1730
+ /**
1731
+ * Gates a value through `schema` and `transform`, then produces it.
1732
+ *
1733
+ * THE WAY IN, AND THE ORDER IS 4.3 THEN 4.4: the schema gates, and what it RETURNS is
1734
+ * what `transform` receives — not the original value. A transform reading the raw input
1735
+ * where a schema had normalised it is a second answer to what this value holds.
1736
+ * What it hands back is the ordinal, or the refusal a gate answered with (4.18) — `unknown`
1737
+ * because the one caller that cares tells the two apart by type.
1738
+ */
1739
+ function accept(cell: Cell, value: unknown): unknown {
1740
+ let checked = value
1741
+ if (cell.schema !== null) {
1742
+ // 4.5: THE THROW IS CAUGHT AND CONVERTED rather than escaping the write. A schema
1743
+ // that threw past this would take down the caller of `s.set`, which is a template
1744
+ // expression or an event handler — 4.10 has a refused write fill `s.error`, and
1745
+ // nothing about a refusal is exceptional enough to unwind an app for.
1746
+ const answer = runSchema(cell.schema, value)
1747
+ // 15.8: a schema that refused is a `ValidationError` at 422 — the request parsed
1748
+ // and its contents are wrong, which is exactly what a schema that RAN found out.
1749
+ if (answer.issues !== null)
1750
+ return refused(cell, validationError<Found>(answer.issues))
1751
+ checked = answer.value
1752
+ }
1753
+ const transform = cell.transform
1754
+ if (transform === null) return produce(cell, checked)
1755
+ // 4.7 — A `transform` RUNS UNTRACKED: a write can be made from inside a tracked body
1756
+ // (`watch(() => target.set(…))`, a recompute that writes), and run tracked, the transform's
1757
+ // reads were attributed to that reader — which then re-ran on a value it never read, with
1758
+ // those reads spliced into its cursor-ordered `sources`.
1759
+ const shaped = untracked(transform, checked, undefined)
1760
+ // 4.6 AND 4.9: a `transform` that returned a refusal stops the write here — nothing is
1761
+ // stored, no production is minted, and the ordinal does not move. The test is behind
1762
+ // the `transform === null` arm, so a value that declares none never reaches it.
1763
+ if (isFailed(shaped)) return refused(cell, shaped)
1764
+ return produce(cell, shaped)
1765
+ }
1766
+
1767
+ /**
1768
+ * `accept` for a stream: the same two gates, then `standWrite`.
1769
+ *
1770
+ * `accept` FOR A STREAM, AND A SECOND COPY OF THE GATES ON PURPOSE. The branch to `standWrite`
1771
+ * measured 8.4 ns -> 10.9 ns on a capped write under V8 wherever it sat on a value's write
1772
+ * path — in `accept`, at the top of `produce`, in the write member — though no
1773
+ * value ever took it; a bare read of `cell.stream` in the same place cost nothing. So a stream's
1774
+ * writes are reached by a prototype of their own (`STREAM_PROTOTYPE`) and never share a call
1775
+ * site with a value's. The copy is the two gates in 4.3's order, and a change to either is a
1776
+ * change to both.
1777
+ */
1778
+ function acceptIntoStream(cell: Cell, stream: Stream, value: unknown): unknown {
1779
+ let checked = value
1780
+ if (cell.schema !== null) {
1781
+ const answer = runSchema(cell.schema, value)
1782
+ if (answer.issues !== null)
1783
+ return refused(cell, validationError<Found>(answer.issues))
1784
+ checked = answer.value
1785
+ }
1786
+ const transform = cell.transform
1787
+ let shaped = checked
1788
+ if (transform !== null) {
1789
+ shaped = untracked(transform, checked, undefined)
1790
+ if (isFailed(shaped)) return refused(cell, shaped)
1791
+ }
1792
+ return standWrite(cell, stream, shaped)
1793
+ }
1794
+
1795
+ /**
1796
+ * A write to a stream, from its own `set`. A load handed to one lands through the
1797
+ * same gates when it settles, and a newer write supersedes it the way it would on a value.
1798
+ */
1799
+ function writeStream(cell: Cell, value: unknown): unknown {
1800
+ cell.generation += 1
1801
+ // 9.11: a write replaces the write standing, and one following a `Reactive` lets go of it.
1802
+ if (cell.adoption !== null) unfollow(cell)
1803
+ if (isThenable(value) && !isReactive(value)) {
1804
+ const generation = cell.generation
1805
+ value.then(
1806
+ (settled) => {
1807
+ if (cell.generation === generation)
1808
+ acceptIntoStream(cell, cell.stream as Stream, settled)
1809
+ },
1810
+ (failed: unknown) => {
1811
+ if (cell.generation === generation) refused(cell, failed)
1812
+ },
1813
+ )
1814
+ return undefined
1815
+ }
1816
+ const answer = acceptIntoStream(cell, cell.stream as Stream, value)
1817
+ return typeof answer === 'number' ? undefined : answer
1818
+ }
1819
+
1820
+ /**
1821
+ * Stands a write over a stream as its value, without minting an ordinal.
1822
+ *
1823
+ * 9.11 AND 9.12: A WRITE OVER A STREAM IS A VALUE, NOT A CHUNK. It stands at the version of the
1824
+ * accumulation it was made over, and the first chunk or patch that moves the version past it
1825
+ * puts the accumulation back on the next read — and it mints no ordinal, which is what a cursor
1826
+ * holds its place by: `ring[i]` is ordinal `ringBase + i + 1`, and an ordinal with nothing in the
1827
+ * ring behind it handed the cursor `undefined`.
1828
+ */
1829
+ function standWrite(cell: Cell, stream: Stream, value: unknown): number {
1830
+ // 7.9, as `produce` settles it.
1831
+ if (cell.owes === OWES_RELOAD) cell.owes = OWES_NOTHING
1832
+ // 5.2 against what is served now, which on a stream may not have been materialised yet.
1833
+ if (cell.servable) {
1834
+ const previous = heldValue(cell)
1835
+ if (
1836
+ cell.identityFn === null
1837
+ ? Object.is(value, previous)
1838
+ : cell.identityFn(value, previous)
1839
+ )
1840
+ return cell.ordinal
1841
+ }
1842
+ cell.value = value
1843
+ stream.materialisedAt = stream.version
1844
+ stream.written = true
1845
+ const moved = !cell.servable || cell.failure !== undefined
1846
+ landChunks(cell)
1847
+ cascade(cell)
1848
+ if (moved) probesMoved(cell)
1849
+ return cell.ordinal
1850
+ }
1851
+
1852
+ /**
1853
+ * Leaves a failure standing as `s.error`; returns it.
1854
+ *
1855
+ * 4.10: WHAT A REFUSED WRITE LEAVES BEHIND is the standing `s.error`, and this is the one
1856
+ * statement of it — the rejected-load arm in `absorb` reached the same five lines and a
1857
+ * second copy is the drift this file is arranged against.
1858
+ *
1859
+ * ONE STATEMENT FOR EVERY PRODUCER: a refused write, a rejected load, and a body that threw or
1860
+ * returned a `Failed` in its own run all land here.
1861
+ *
1862
+ * WITH NOTHING SERVED THE FAILURE HAS TO PROPAGATE, AND 4.12 IS THE CASE THAT MUST NOT. A read
1863
+ * of an unservable value throws, so a reader parked on that throw — a `then` waiter, a body that
1864
+ * aborted — is answered by this failure or by nothing, and it opens a cascade like a production.
1865
+ * `servable` rather than `landed`: an invalidated value has landed and is unserved (7.8), and
1866
+ * testing `landed` left the reader its unserve woke parked on `NotLanded` for the life of the
1867
+ * value. A refusal over a value still being served changes nothing a reader can see, and waking
1868
+ * there would be a wake on an unchanged value (5.1).
1869
+ */
1870
+ function refused(cell: Cell, failure: unknown): unknown {
1871
+ cell.loading = false
1872
+ cell.failure = failure
1873
+ // BOTH PROBES MOVED AND NEITHER IS ON THE VALUE EDGE: `busy` went false where the load
1874
+ // had set it true, and `error` went from nothing to this. A guard that asked about
1875
+ // either is woken here or never.
1876
+ probesMoved(cell)
1877
+ if (!cell.servable) cascade(cell)
1878
+ return failure
1879
+ }
1880
+
1881
+ /**
1882
+ * Takes in a write or a body's answer, waiting on it first where it is a load.
1883
+ *
1884
+ * A load. 4.2: a load given to a write makes the value loaded, at construction and at
1885
+ * every write alike. `generation` is what makes a stale settle a no-op — a refresh
1886
+ * landing after an invalidate must not overwrite the newer run's answer.
1887
+ *
1888
+ * `answered` IS A BODY'S ANSWER, and 15.5 has one that settles to a `Failed` refuse. A write that
1889
+ * settles to one is not an answer, and 4.17 stores it as it would a settled one.
1890
+ */
1891
+ function absorb(cell: Cell, result: unknown, answered: boolean): void {
1892
+ // THE BRAND IS READ BEFORE `then` (RULEBOOK 1.6). A `Reactive` is thenable by 1.4,
1893
+ // so a guard written the other way round settles a live value to one snapshot — a write
1894
+ // of `other` would hand back `other`'s current value instead of `other`.
1895
+ if (!isThenable(result) || isReactive(result)) {
1896
+ accept(cell, result)
1897
+ return
1898
+ }
1899
+ const generation = cell.generation
1900
+ // A PROBE MOVES WITHOUT A PRODUCTION — 11.22 derives a propagated probe on the read that
1901
+ // asks for it rather than pushing it. Going loading
1902
+ // changes what every reader downstream reports and mints no value for a cascade to
1903
+ // carry, so the flip opens one itself.
1904
+ beginLoad(cell)
1905
+ ;(result as PromiseLike<unknown>).then(
1906
+ (settled) => {
1907
+ if (cell.generation !== generation) return
1908
+ if (answered && isFailed(settled)) refused(cell, settled)
1909
+ // 9.6 — a run's promise resolving to an async generator hands one back too. Its
1910
+ // probes move so `streamingOrSettled` hears the value turn.
1911
+ else if (isAsyncGenerator(settled)) {
1912
+ promoteToStream(cell, settled)
1913
+ probesMoved(cell)
1914
+ } else accept(cell, settled)
1915
+ },
1916
+ (failed) => {
1917
+ if (cell.generation !== generation) return
1918
+ refused(cell, failed)
1919
+ },
1920
+ )
1921
+ }
1922
+
1923
+ /**
1924
+ * Makes a value mirror another; returns the refusal where that would close a cycle.
1925
+ *
1926
+ * ADOPTION. RULEBOOK 11.12: a `Reactive` a body hands back is ADOPTED, and is not stored
1927
+ * as a value — the outer value serves what the inner one serves and goes on serving it as
1928
+ * the inner produces. A `Reactive` the app wants to hold as data goes inside a record —
1929
+ * `reactive({ inner })` — where nothing mistakes it for a production.
1930
+ *
1931
+ * IT IS A `watch` OVER THE INNER VALUE, not a third subscriber mechanism: 12.3's narrowed
1932
+ * form is exactly "run this when that one changes", which is what mirroring is.
1933
+ *
1934
+ * 11.65 — THE ONE PLACE `adoption` IS SET, so it is the one place a cycle can form, and refusing
1935
+ * it here is what lets every walk of the chain be a plain loop to its end. The walk is over the
1936
+ * inner's chain, which cannot cycle for the same reason, and it runs per adoption rather than per
1937
+ * read. The refusal is handed back rather than thrown: 11.66 has the two callers answer it
1938
+ * differently.
1939
+ */
1940
+ function adopt(cell: Cell, inner: Cell): Error | undefined {
1941
+ const standing = cell.adoption
1942
+ if (standing !== null && standing.source === inner) {
1943
+ // 11.18: the same one again is not a change, and re-subscribing would mint a
1944
+ // production out of a recompute that decided nothing. BUT A TRIGGER CAN HAVE
1945
+ // LEFT THIS VALUE LOADING OR WITH NOTHING TO SERVE, and nothing but a production
1946
+ // of the inner would ever settle it — which an inner with no producer never
1947
+ // makes. So the mirror runs again where there is something to settle, and the
1948
+ // identity gate is what keeps it waking nobody where the inner did not move.
1949
+ if (cell.loading || !cell.servable) mirror(cell, inner)
1950
+ return undefined
1951
+ }
1952
+ // The same source again was checked when it was first adopted, so only a new one is walked.
1953
+ const cycle = closesCycle(cell, inner)
1954
+ if (cycle !== undefined) return cycle
1955
+ // 11.19 MOVES WITH THE ADOPTION ITSELF, and no production carries that move. An adopter with
1956
+ // nothing to serve — `reactive()` before a `paid = payInvoice(…)` — re-adopted onto a call in
1957
+ // flight goes busy while the mirror's `unserve` finds nothing to lose and wakes no guard, so
1958
+ // `{paid.busy() ? 'paying…' : ''}` never painted the load it was asking about.
1959
+ const wasBusy = standing !== null && busyNow(standing.source)
1960
+ if (standing !== null) standing.stop()
1961
+ // 11.17: the adopted value's `identity` is inherited where the outer declared none —
1962
+ // THIS inner's, so a re-adoption onto another one does not keep the first one's.
1963
+ // Assigned before the first mirror, or the production that mirror makes is gated by
1964
+ // the wrong comparison.
1965
+ cell.identityFn = cell.declaredIdentityFn ?? inner.identityFn
1966
+ simpleShape(cell)
1967
+ const stop = watchOver([inner], cell, (): undefined => {
1968
+ mirror(cell, inner)
1969
+ return undefined
1970
+ })
1971
+ cell.adoption = { source: inner, stop }
1972
+ // 11.59: an adopting value's writes are the adopted value's, reached through a prototype of its
1973
+ // own rather than a branch on every value's write path — see `acceptIntoStream` for what such a
1974
+ // branch costs under V8 even where nothing takes it.
1975
+ Object.setPrototypeOf(cell.callable as object, ADOPTING_PROTOTYPE)
1976
+ if (!cell.loading && busyNow(inner) !== wasBusy) probesMoved(cell)
1977
+ return undefined
1978
+ }
1979
+
1980
+ /** The refusal where adopting `inner` would close a cycle through `cell` (11.65). */
1981
+ function closesCycle(cell: Cell, inner: Cell): Error | undefined {
1982
+ for (
1983
+ let at: Cell | undefined = inner;
1984
+ at !== undefined;
1985
+ at = at.adoption?.source
1986
+ )
1987
+ if (at === cell)
1988
+ return new Error(
1989
+ 'An adoption would close a cycle: these values would adopt each other, so no one of them holds the value. RULEBOOK 11.65.',
1990
+ )
1991
+ return undefined
1992
+ }
1993
+
1994
+ /**
1995
+ * Stands a `Reactive` written over a stream as a write that follows it.
1996
+ *
1997
+ * 11.61 ON A STREAM IS 9.11'S WRITE, FOLLOWING, and it is the standing write rather than a second
1998
+ * mechanism: `written` over the version it was made at, with `value` re-landed through `standWrite`
1999
+ * each time the followed value moves, so it mints no ordinal (9.12). What it follows is held on
2000
+ * `adoption`, which is what the probes already walk (11.19, 11.50) and what `markProbes` reaches
2001
+ * through the mirror. The stream keeps its own prototype — a later write is a write over the stream
2002
+ * and replaces this one, where 11.59 would have handed it on — and `adoptedCellOf` stops here, so a
2003
+ * cursor and a replay are the stream's.
2004
+ */
2005
+ function follow(cell: Cell, stream: Stream, inner: Cell): Error | undefined {
2006
+ const standing = cell.adoption
2007
+ // 11.18: the same one again is not a change.
2008
+ if (standing !== null && standing.source === inner) return undefined
2009
+ const cycle = closesCycle(cell, inner)
2010
+ if (cycle !== undefined) return cycle
2011
+ // A write supersedes a load a previous write left in flight.
2012
+ cell.generation += 1
2013
+ // 11.19 as `adopt` has it: following a call in flight is a busy move nothing mints.
2014
+ const wasBusy = standing !== null && busyNow(standing.source)
2015
+ if (standing !== null) unfollow(cell)
2016
+ // What `standWrite`'s identity gate compares against is what is served now.
2017
+ heldValue(cell)
2018
+ stream.materialisedAt = stream.version
2019
+ stream.written = true
2020
+ const stop = watchOver([inner], cell, (): undefined => {
2021
+ // The accumulation moved past the write. The drop is `wakeStreams`'s or the read's, not
2022
+ // this one's: a mirror runs inside the mark walk over `inner.readers`, and detaching here
2023
+ // would splice the list that walk is iterating.
2024
+ if (!stream.written || stream.materialisedAt !== stream.version)
2025
+ return undefined
2026
+ if (inner.owes !== OWES_NOTHING) settleOwed(inner)
2027
+ // 11.16: the followed value has nothing to serve, so neither has this.
2028
+ if (!inner.servable) unserve(cell)
2029
+ else acceptIntoStream(cell, stream, heldValue(inner))
2030
+ return undefined
2031
+ })
2032
+ cell.adoption = { source: inner, stop }
2033
+ if (!cell.loading && busyNow(inner) !== wasBusy) probesMoved(cell)
2034
+ return undefined
2035
+ }
2036
+
2037
+ /** Lets go of the `Reactive` a stream's standing write follows. */
2038
+ function unfollow(cell: Cell): void {
2039
+ const standing = cell.adoption as Adoption
2040
+ cell.adoption = null
2041
+ standing.stop()
2042
+ }
2043
+
2044
+ /**
2045
+ * Stops serving the value, waking both its readers and its guards.
2046
+ *
2047
+ * LOSING WHAT THERE WAS TO SERVE, AND BOTH EDGES HEAR IT, whichever way it was lost: a trigger's
2048
+ * debt settling (7.8), a re-adoption onto nothing (11.16), or a run aborting (11.58). The readers
2049
+ * hear it through `cascade` and the GUARDS through `probesMoved`. With only the first,
2050
+ * `{#if outer.ready()}{outer()}{:else}spinner{/if}` re-pointed onto an inner with nothing to serve
2051
+ * stays on the value branch permanently while the read under it throws, the inner never having
2052
+ * moved a probe of its own.
2053
+ */
2054
+ function unserve(cell: Cell): void {
2055
+ if (!cell.servable) return
2056
+ cell.servable = false
2057
+ cell.direct = false
2058
+ cascade(cell)
2059
+ probesMoved(cell)
2060
+ }
2061
+
2062
+ function mirror(cell: Cell, inner: Cell): void {
2063
+ // 7.13 through the adoption: the re-settle a re-run of the adopter makes reaches a reload the
2064
+ // adopted value owes, rather than finding it unservable and giving up.
2065
+ if (inner.owes !== OWES_NOTHING) settleOwed(inner)
2066
+ const adopted = inner.stream
2067
+ if (adopted !== null) {
2068
+ forwardStream(cell, inner, adopted)
2069
+ return
2070
+ }
2071
+ if (cell.stream !== null) stopForwarding(cell)
2072
+ if (!inner.servable) {
2073
+ // 11.16: the newly adopted has nothing to serve, so neither has this.
2074
+ unserve(cell)
2075
+ return
2076
+ }
2077
+ const value = heldValue(inner)
2078
+ // 11.13 FOR A PATCH (5.7): the inner woke holding the reference this already serves. Only a patch
2079
+ // does that — a production of the same reference is stopped at the inner's own identity gate —
2080
+ // and the gate `accept` runs here would read it as no change at all, so it wakes as a patch.
2081
+ if (cell.servable && !cell.loading && value === heldValue(cell)) {
2082
+ wakePatched(cell, value)
2083
+ return
2084
+ }
2085
+ // 11.13 mirrors the production into the outer value, and 11.14 runs the OUTER's own
2086
+ // `transform` on the way in — which is `accept`, and is why this does not call
2087
+ // `produce` directly.
2088
+ accept(cell, value)
2089
+ }
2090
+
2091
+ /**
2092
+ * Stops mirroring the adopted value and restores the non-adopting prototype.
2093
+ *
2094
+ * 11.12 governs what a body HANDS BACK, so a run that hands back something else is no
2095
+ * longer adopting. Without this the mirror outlives the recompute that ended it: a body
2096
+ * reading `flag() ? inner : 99` goes on serving 99 until `inner` produces, and then
2097
+ * serves what `inner` produced — a value its own body never computed. The probes read
2098
+ * through `adoption` too, so a stale one is also a floor taken from a value nothing reads
2099
+ * any more.
2100
+ */
2101
+ function dropAdoption(cell: Cell): void {
2102
+ if (cell.adoption === null) return
2103
+ unfollow(cell)
2104
+ const stream = cell.stream
2105
+ // 9.11: AN OWN STREAM'S `adoption` IS A WRITE IT FOLLOWS, not a stream it forwards — the
2106
+ // discriminator `adoptedCellOf` reads. Letting go of the write is all there is: the stream is
2107
+ // its own, so is its prototype, and `follow` never touched `identityFn`. Stopping it as a
2108
+ // forward nulled the stream a queued `wakeStreams` was about to read.
2109
+ if (stream !== null && stream.source === null) return
2110
+ if (stream !== null) stopForwarding(cell)
2111
+ // 11.17 inherited the identity for the length of the adoption only.
2112
+ cell.identityFn = cell.declaredIdentityFn
2113
+ simpleShape(cell)
2114
+ Object.setPrototypeOf(
2115
+ cell.callable as object,
2116
+ cell.simple ? SIMPLE_PROTOTYPE : MEMBER_PROTOTYPE,
2117
+ )
2118
+ }
2119
+
2120
+ /**
2121
+ * Makes an adopter forward an adopted stream's buffer, ring and ordinals.
2122
+ *
2123
+ * 11.15 FOR A STREAM: the adopter takes the adopted value's buffer, ring and ordinals by
2124
+ * reference and materialises from them on its own reads, through its own gates (11.14, 9.8).
2125
+ * Mirroring the value instead copied the accumulation once per wake whether or not anything
2126
+ * read it, and handed a cursor over the adopter whole accumulations where it wanted chunks.
2127
+ */
2128
+ function forwardStream(cell: Cell, inner: Cell, adopted: Stream): void {
2129
+ let stream = cell.stream
2130
+ if (stream === null) {
2131
+ stream = becomeStream(cell, inner)
2132
+ stream.ordinalOffset = cell.ordinal - inner.ringBase
2133
+ }
2134
+ // The adopted version is this one's: a chunk or a patch of the stream moves both, and a write
2135
+ // made on this value is made on the stream (11.59).
2136
+ stream.chunks = adopted.chunks
2137
+ stream.version = adopted.version
2138
+ stream.visible = adopted.visible
2139
+ if (adopted.written && adopted.materialisedAt === adopted.version) {
2140
+ stream.materialisedAt = stream.version
2141
+ stream.written = true
2142
+ gateInto(cell, inner.value)
2143
+ }
2144
+ cell.ring = inner.ring
2145
+ cell.ringBase = inner.ringBase + stream.ordinalOffset
2146
+ cell.ordinal = inner.ordinal + stream.ordinalOffset
2147
+ if (!inner.servable) {
2148
+ // 11.16, as for a value: the adopted has nothing to serve, so neither has this.
2149
+ unserve(cell)
2150
+ return
2151
+ }
2152
+ // The adopter's OWN load — the body run that handed the stream back — is over. `busy` goes
2153
+ // on answering through the adoption (11.19) for as long as the stream is open.
2154
+ const moved = settleProbes(cell)
2155
+ landChunks(cell)
2156
+ cascade(cell)
2157
+ if (moved) probesMoved(cell)
2158
+ }
2159
+
2160
+ function stopForwarding(cell: Cell): void {
2161
+ cell.stream = null
2162
+ cell.plain = cell.expiry === null
2163
+ cell.bareWrite = cell.schema === null && cell.transform === null
2164
+ simpleShape(cell)
2165
+ cell.ring = EMPTY_RING
2166
+ // The ring is empty and the next production is `ordinal + 1`, at index zero.
2167
+ cell.ringBase = cell.ordinal
2168
+ }
2169
+
2170
+ /**
2171
+ * Runs a value's body, tracking its reads; abandons the run where a read had not landed.
2172
+ *
2173
+ * THE ABORT. A body that reads a value which has not landed throws `NotLanded`, and
2174
+ * this catches it and returns — the body is ABANDONED, not retried in place. The read
2175
+ * that threw has already registered this cell as a reader of it (tracking happens
2176
+ * before the throw), so the source landing is what re-runs the body.
2177
+ *
2178
+ * "Throw a sentinel and re-run" was refused once on three grounds. Two are answered
2179
+ * by the reach starting the work (1.7) — the loads are in flight before the body
2180
+ * runs, so the abort costs a re-entry rather than a round trip. The third, that
2181
+ * nothing on a server wakes an abandoned body, is answered by the sink rather than
2182
+ * by a subscriber.
2183
+ */
2184
+ function run(cell: Cell): void {
2185
+ const body = cell.body
2186
+ if (body === null) return
2187
+ // A body cannot meaningfully re-enter itself, and a cycle in the graph is the case
2188
+ // where the cascade would try: `a` reads `b` and `b` reads `a`. Without this the
2189
+ // recursion is unbounded and the failure is a stack overflow rather than a value.
2190
+ if (cell.running) return
2191
+ cell.generation += 1
2192
+ cell.state = CLEAN
2193
+ cell.running = true
2194
+ const reader = cell as unknown as Subscriber
2195
+ // No closure and no `withReader` frame: a run allocated one closure per recompute,
2196
+ // and a recompute is per write on every derived value in the graph.
2197
+ const previous = TRACKING.reader
2198
+ TRACKING.reader = reader
2199
+ // THE RUN'S CURSOR, spelled out rather than behind a call frame on a path walked once
2200
+ // per node per write. Zero is also "has diverged nowhere yet": see `tracking.ts`.
2201
+ reader.cursor = 0
2202
+ // The probe edge is rebuilt rather than cursored: a guard that stops being taken has
2203
+ // to stop waking, and a body reads few probes where it reads many values.
2204
+ if (reader.probeSources.length !== 0) detachProbes(reader)
2205
+ let produced: unknown
2206
+ try {
2207
+ // 11.32 — UNDER THE VALUE'S OWN SCOPE, not the ambient one. A drain runs every body a
2208
+ // turn's writes woke, and the turn is whichever request scheduled it — so without this a
2209
+ // body filed under one request reads the values of another.
2210
+ produced = runInScope(cell.scope, body, cell.args)
2211
+ } catch (thrown) {
2212
+ TRACKING.reader = previous
2213
+ if (reader.cursor < reader.sources.length) truncate(reader)
2214
+ cell.running = false
2215
+ if (thrown instanceof NotLanded) {
2216
+ cell.loading = true
2217
+ // 2.13: the mark a source's production makes is what finishes this run, and
2218
+ // `markReaders` queues it rather than leaving it for a read that may never come.
2219
+ cell.aborted = true
2220
+ // NOT EVERYTHING IT READS IS READY, so neither is this — 11.58, and the same
2221
+ // sentence 11.16 makes for a re-adoption. It stops serving rather than handing
2222
+ // back a figure it computed from a source that has since gone away, and that
2223
+ // is a move its readers have to hear even though the aborted run minted
2224
+ // nothing for a cascade to carry.
2225
+ if (cell.servable) unserve(cell)
2226
+ else probesMoved(cell)
2227
+ return
2228
+ }
2229
+ refused(cell, thrown)
2230
+ return
2231
+ }
2232
+ TRACKING.reader = previous
2233
+ cell.aborted = false
2234
+ // A body that read FEWER values than last time leaves a tail nothing reads, and
2235
+ // that is the only thing the truncation has to do — so the test is here and the call
2236
+ // is the rare arm.
2237
+ if (reader.cursor < reader.sources.length) truncate(reader)
2238
+ cell.running = false
2239
+ // A VALUE THAT WAS ADOPTING AND IS NOT ANY MORE. Behind the `adoption` load so every
2240
+ // other recompute pays one field test rather than the brand read below it.
2241
+ if (cell.adoption !== null) {
2242
+ if (isReactive(produced)) {
2243
+ adoptAnswer(cell, produced)
2244
+ return
2245
+ }
2246
+ dropAdoption(cell)
2247
+ }
2248
+ // 4.16: a body's first answer of `undefined` is an opening, and lands past the pipeline.
2249
+ if (produced === undefined && !cell.landed) {
2250
+ landOpening(cell)
2251
+ return
2252
+ }
2253
+ // The settled, untransformed recompute is the common shape, and `absorb` -> `accept`
2254
+ // -> `produce` is three frames behind it. A recompute runs per write on every
2255
+ // derived value in the graph, so the frames are paid per edge.
2256
+ //
2257
+ // SPELLING `produce` OUT HERE WAS TRIED AND IS NOT WORTH IT: copying the identity
2258
+ // gate and the seven stores into this branch took the recompute from
2259
+ // 23.58 ns to 22.42 ns and the chain of twenty from 583 to 563 — 5% and 3% — for
2260
+ // twenty-five duplicated lines of the most subtle logic in the file. A second copy
2261
+ // of the production rule is the drift every document here is arranged to stop.
2262
+ // BOTH GATES, NOT ONE. This arm exists to skip `absorb` -> `accept` -> `produce` for the
2263
+ // settled, ungated recompute — and `accept` is where 4.3 runs the schema, so testing
2264
+ // only `transform` here routed every body production straight past its own gate
2265
+ // (11.46). The gate was written, the tests were written, and this path answered them
2266
+ // without ever reaching it.
2267
+ const primitive =
2268
+ produced === null ||
2269
+ (typeof produced !== 'object' && typeof produced !== 'function')
2270
+ if (cell.bareWrite && primitive) {
2271
+ produce(cell, produced)
2272
+ return
2273
+ }
2274
+ // 15.5 — A BODY THAT RETURNS A REFUSAL REFUSES. Past the primitive arm, so a recompute
2275
+ // answering a number pays nothing for it, and ahead of the object arm, because a `Failed` is
2276
+ // an object with no `then` and that arm would store it as the value. It lands the way a
2277
+ // body's throw does above, a refusal being the same observable move whichever way the body
2278
+ // said it.
2279
+ if (!primitive && isFailed(produced)) {
2280
+ refused(cell, produced)
2281
+ return
2282
+ }
2283
+ // 9.6 — ON ANY RUN: `() => flag() ? rows() : 0` hands its generator back once the flag turns.
2284
+ if (!primitive && isAsyncGenerator(produced)) {
2285
+ promoteToStream(cell, produced)
2286
+ return
2287
+ }
2288
+ if (
2289
+ cell.bareWrite &&
2290
+ typeof (produced as PromiseLike<unknown>).then !== 'function'
2291
+ ) {
2292
+ produce(cell, produced)
2293
+ return
2294
+ }
2295
+ // 11.12 BEFORE `absorb`, and the order is the whole of it: a `Reactive` is thenable
2296
+ // (1.4), so absorbing one would settle a live value to a single snapshot — which is
2297
+ // the hazard 1.6 names, answered here by adopting instead of storing.
2298
+ if (isReactive(produced)) {
2299
+ adoptAnswer(cell, produced)
2300
+ return
2301
+ }
2302
+ absorb(cell, produced, true)
2303
+ }
2304
+
2305
+ /**
2306
+ * Adopts what a body handed back, refusing the body where that would close a cycle.
2307
+ *
2308
+ * 11.66 — a body's answer that 11.65 refuses is the body's failure.
2309
+ */
2310
+ function adoptAnswer(cell: Cell, produced: unknown): void {
2311
+ const cycle = adopt(cell, (produced as Callable)[CELL])
2312
+ if (cycle !== undefined) refused(cell, cycle)
2313
+ }
2314
+
2315
+ /**
2316
+ * Lands an opening `undefined` as loaded, past the pipeline.
2317
+ *
2318
+ * 4.16: AN OPENING `undefined` IS LOADED AND IS NOT A PRODUCTION THROUGH THE PIPELINE. No `schema`
2319
+ * judges it, no `transform` shapes it, no window holds it and no `store` writes it — it is the value
2320
+ * being empty, and the first real production is what those are for. It mints no ordinal (6.10).
2321
+ */
2322
+ function landOpening(cell: Cell): void {
2323
+ const moved = settleProbes(cell)
2324
+ cell.value = undefined
2325
+ cell.landed = true
2326
+ cell.servable = true
2327
+ setDirect(cell, cell.state === CLEAN)
2328
+ cascade(cell)
2329
+ if (moved) probesMoved(cell)
2330
+ }
2331
+
2332
+ /**
2333
+ * Starts a value's producer: a stream's generator, or a body's run.
2334
+ *
2335
+ * WHAT STARTS A PRODUCER, for the three callers that start one: construction, `refresh`
2336
+ * and `invalidate`. A stream is dispatched HERE rather than inside `run`, which a recompute
2337
+ * walks per node per write — and a stream is never recomputed, having no tracked source to
2338
+ * be marked by (14.13).
2339
+ */
2340
+ function startProducer(cell: Cell): void {
2341
+ const stream = cell.stream
2342
+ if (stream === null || stream.source !== null) run(cell)
2343
+ else startStream(cell, stream)
2344
+ }
2345
+
2346
+ /**
2347
+ * Supersedes the run in flight and tells its iterator to return.
2348
+ *
2349
+ * The run in flight stops reaching the value. A generator suspended inside an `await` takes the
2350
+ * request once it reaches a `yield`, and whatever it yields before then is dropped by the run
2351
+ * test in `pump`.
2352
+ */
2353
+ function stopStream(stream: Stream): void {
2354
+ stream.run += 1
2355
+ const superseded = stream.iterator
2356
+ stream.iterator = null
2357
+ if (superseded !== null && typeof superseded.return === 'function')
2358
+ superseded.return().then(undefined, () => undefined)
2359
+ }
2360
+
2361
+ function startStream(cell: Cell, stream: Stream): void {
2362
+ // UNTRACKED. Calling an async generator function runs none of its body — every read in
2363
+ // it happens after an `await`, where 14.13 has it register against nothing — so the
2364
+ // reader standing on this stack is not one this body could ever be attributed to.
2365
+ const iterator = untracked(
2366
+ openStream,
2367
+ cell.body as (args: unknown) => AsyncIterable<unknown>,
2368
+ cell.args,
2369
+ )
2370
+ pumpRun(cell, stream, iterator)
2371
+ }
2372
+
2373
+ /**
2374
+ * 9.6 — a value whose run handed back an async generator: a streaming producer from that run on,
2375
+ * the generator being the run's stream, and every start after it the body's next one.
2376
+ */
2377
+ function promoteToStream(cell: Cell, generator: AsyncIterable<unknown>): void {
2378
+ let stream = cell.stream
2379
+ if (stream === null) {
2380
+ stream = becomeStream(cell, null)
2381
+ Object.setPrototypeOf(cell.callable as object, STREAM_PROTOTYPE)
2382
+ }
2383
+ pumpRun(cell, stream, generator[Symbol.asyncIterator]())
2384
+ }
2385
+
2386
+ /** Supersedes the run in flight with one reading `iterator`. */
2387
+ function pumpRun(
2388
+ cell: Cell,
2389
+ stream: Stream,
2390
+ iterator: AsyncIterator<unknown>,
2391
+ ): void {
2392
+ stopStream(stream)
2393
+ const run = stream.run
2394
+ beginLoad(cell)
2395
+ stream.iterator = iterator
2396
+ // 11.32 — a generator's body runs inside each `next()`, so the pump is what carries the scope.
2397
+ runInScope(
2398
+ cell.scope,
2399
+ () => pump(cell, stream, iterator, run),
2400
+ undefined,
2401
+ ).then(undefined, (thrown: unknown) =>
2402
+ pumpFailed(cell, stream, run, thrown),
2403
+ )
2404
+ }
2405
+
2406
+ /**
2407
+ * Refuses a run whose pump threw past `next()` — landing a chunk, closing, or a gate a close reads
2408
+ * through (a `transform` that throws). 2.4 as for a generator's own throw, and the run stops.
2409
+ */
2410
+ function pumpFailed(
2411
+ cell: Cell,
2412
+ stream: Stream,
2413
+ run: number,
2414
+ thrown: unknown,
2415
+ ): void {
2416
+ if (stream.run !== run) return
2417
+ stopStream(stream)
2418
+ refused(cell, thrown)
2419
+ }
2420
+
2421
+ function openStream(
2422
+ body: (args: unknown) => AsyncIterable<unknown>,
2423
+ args: unknown,
2424
+ ): AsyncIterator<unknown> {
2425
+ return body(args)[Symbol.asyncIterator]()
2426
+ }
2427
+
2428
+ async function pump(
2429
+ cell: Cell,
2430
+ stream: Stream,
2431
+ iterator: AsyncIterator<unknown>,
2432
+ run: number,
2433
+ ): Promise<void> {
2434
+ // 9.7: nothing of this run is served until it says something, so the accumulation
2435
+ // being served is the previous run's until the first chunk replaces it.
2436
+ let begun = false
2437
+ for (;;) {
2438
+ let step: IteratorResult<unknown>
2439
+ try {
2440
+ step = await iterator.next()
2441
+ } catch (failed) {
2442
+ if (stream.run !== run) return
2443
+ stream.iterator = null
2444
+ // 2.4: what the stream had already said goes on being served, with the failure
2445
+ // standing beside it — and 2.2 where it had said nothing.
2446
+ refused(cell, failed)
2447
+ return
2448
+ }
2449
+ if (stream.run !== run) return
2450
+ if (step.done === true) break
2451
+ if (!begun) {
2452
+ begun = true
2453
+ beginAccumulation(cell, stream)
2454
+ }
2455
+ acceptChunk(cell, stream, step.value)
2456
+ }
2457
+ stream.iterator = null
2458
+ // THE CLOSE RELEASES WHAT A WINDOW IS HOLDING. A stream that has finished has nothing left to
2459
+ // collapse, and an await resolving here would otherwise be handed the accumulation as the last
2460
+ // release left it rather than the whole of it (2.7).
2461
+ const cap = cell.cap
2462
+ if (cap?.holding) {
2463
+ if (cap.timer !== null) clearTimeout(cap.timer)
2464
+ cap.timer = null
2465
+ cap.holding = false
2466
+ releaseChunks(cell, stream)
2467
+ }
2468
+ const moved = !begun || cell.loading
2469
+ if (!begun) {
2470
+ // A stream that closed with nothing in it has finished, and what it accumulated is
2471
+ // no chunks — a value, where waiting on would be a load that never ends.
2472
+ beginAccumulation(cell, stream)
2473
+ landChunks(cell)
2474
+ cascade(cell)
2475
+ }
2476
+ cell.loading = false
2477
+ // 3.7: `busy` held until the close, and this is the close.
2478
+ if (moved) probesMoved(cell)
2479
+ // 6.11, AFTER THE CASCADE ABOVE: the entry is what a read would answer with, so it is taken
2480
+ // once the last chunk has landed and the value is servable.
2481
+ closeRun(cell, stream)
2482
+ // 8.9: a stream is written once, at the close, with the accumulation and never a partial.
2483
+ if (cell.store !== null) writeStore(cell, cell.store, heldValue(cell))
2484
+ }
2485
+
2486
+ function beginAccumulation(cell: Cell, stream: Stream): void {
2487
+ stream.closed = false
2488
+ const chunks: unknown[] = []
2489
+ stream.chunks = chunks
2490
+ stream.visible = 0
2491
+ stream.version += 1
2492
+ // A cursor holds ordinals, and `ring[i]` carries `ringBase + i + 1` — so the new run's
2493
+ // first chunk is the next ordinal, and a cursor from the previous run clamps forward.
2494
+ cell.ring = chunks
2495
+ cell.ringBase = cell.ordinal
2496
+ }
2497
+
2498
+ /**
2499
+ * Pushes one chunk into the accumulation, as one ungated production.
2500
+ *
2501
+ * ONE CHUNK IS ONE PRODUCTION, and ungated: an accumulation that grew is a different value
2502
+ * whatever `identity` says about its last element.
2503
+ */
2504
+ function acceptChunk(cell: Cell, stream: Stream, chunk: unknown): void {
2505
+ stream.chunks.push(chunk)
2506
+ cell.ordinal += 1
2507
+ // 3.8: `ready` from the first chunk, and `error` cleared by an accepted production (4.11).
2508
+ if (!cell.servable || cell.failure !== undefined) stream.probesOwed = true
2509
+ // 5.17: THE WINDOW CAPS THE WAKE, and the chunk is already in the buffer for a cursor.
2510
+ if (tellsChunks(cell, cell.cap)) releaseChunks(cell, stream)
2511
+ }
2512
+
2513
+ /**
2514
+ * Tells readers of every chunk landed so far, waking them at most once per task.
2515
+ *
2516
+ * What a reader is told of: every chunk landed so far becomes what a read materialises, and the
2517
+ * wake goes out at most once per task (9.9).
2518
+ */
2519
+ function releaseChunks(cell: Cell, stream: Stream): void {
2520
+ stream.visible = stream.chunks.length
2521
+ stream.version += 1
2522
+ landChunks(cell)
2523
+ wakeLater(cell, stream)
2524
+ }
2525
+
2526
+ /**
2527
+ * The streams holding a wake, all drained by one task.
2528
+ *
2529
+ * THE STREAMS HOLDING A WAKE, and one task drains all of them — never a task per stream.
2530
+ * The pull is untouched: a read taken before the task runs materialises what has landed
2531
+ * (12.12), so what waits is only the telling.
2532
+ */
2533
+ const WAKING: Cell[] = []
2534
+ let wakeQueued = false
2535
+
2536
+ function wakeLater(cell: Cell, stream: Stream): void {
2537
+ if (stream.waking) return
2538
+ stream.waking = true
2539
+ WAKING.push(cell)
2540
+ if (wakeQueued) return
2541
+ wakeQueued = true
2542
+ nextTask(wakeStreams)
2543
+ }
2544
+
2545
+ function wakeStreams(): void {
2546
+ wakeQueued = false
2547
+ // The length is re-read per turn: a mirror the cascade runs can land on another stream.
2548
+ for (let index = 0; index < WAKING.length; index += 1) {
2549
+ const cell = WAKING[index] as Cell
2550
+ const stream = cell.stream as Stream
2551
+ stream.waking = false
2552
+ let owed = stream.probesOwed
2553
+ stream.probesOwed = false
2554
+ // 9.11: the chunk ended a write following a `Reactive`, whose probes were this one's.
2555
+ if (cell.adoption !== null) {
2556
+ unfollow(cell)
2557
+ owed = true
2558
+ }
2559
+ cascade(cell)
2560
+ if (owed) probesMoved(cell)
2561
+ }
2562
+ WAKING.length = 0
2563
+ }
2564
+
2565
+ /**
2566
+ * Posts a function to the next task; made on first use.
2567
+ *
2568
+ * THE NEXT TASK. `setImmediate` where the runtime has one — bun, and so every server — and a
2569
+ * `MessageChannel` post in a browser, which has none and clamps a nested `setTimeout` to 4 ms.
2570
+ * The channel is made on first use, so a page that never streams never opens one.
2571
+ */
2572
+ let postTask: ((run: () => void) => void) | null = null
2573
+
2574
+ function nextTask(run: () => void): void {
2575
+ if (postTask === null) postTask = taskPoster()
2576
+ postTask(run)
2577
+ }
2578
+
2579
+ function taskPoster(): (run: () => void) => void {
2580
+ if (typeof setImmediate === 'function')
2581
+ return (run) => {
2582
+ setImmediate(run)
2583
+ }
2584
+ const channel = new MessageChannel()
2585
+ let queued: (() => void) | null = null
2586
+ channel.port1.onmessage = (): void => {
2587
+ const run = queued
2588
+ queued = null
2589
+ run?.()
2590
+ }
2591
+ return (run) => {
2592
+ queued = run
2593
+ channel.port2.postMessage(null)
2594
+ }
2595
+ }
2596
+
2597
+ function landChunks(cell: Cell): void {
2598
+ cell.failure = undefined
2599
+ cell.landed = true
2600
+ cell.servable = true
2601
+ cell.direct = false
2602
+ }
2603
+
2604
+ /**
2605
+ * Materialises a stream's visible chunks into `value`, through both gates.
2606
+ *
2607
+ * 9.1 AND 9.8: the read that asks is where the accumulation becomes a `Stored`, through both
2608
+ * gates, once per chunk count however many reads ask.
2609
+ */
2610
+ function materialise(cell: Cell, stream: Stream): void {
2611
+ if (stream.materialisedAt === stream.version || !cell.servable) return
2612
+ // 9.11: the accumulation moved past a write following a `Reactive`, which lets go of it here
2613
+ // where no chunk's wake did — a patch, or a run that closed empty. Only an own stream follows;
2614
+ // a forwarding one's `adoption` is what it forwards.
2615
+ if (cell.adoption !== null && stream.source === null) unfollow(cell)
2616
+ stream.materialisedAt = stream.version
2617
+ stream.written = false
2618
+ gateInto(cell, stream.chunks.slice(0, stream.visible))
2619
+ }
2620
+
2621
+ /**
2622
+ * Gates a forwarded slice or write into `value`, untracked.
2623
+ *
2624
+ * What a forwarding value's read takes in, through its own gates (11.14, 9.8): a slice of the
2625
+ * accumulation, or a write standing on the stream it forwards.
2626
+ * 4.7: the gates run untracked, and this is reached from inside whatever read asked.
2627
+ */
2628
+ function gateInto(cell: Cell, raw: unknown): void {
2629
+ untracked(gateThrough, cell, raw)
2630
+ }
2631
+
2632
+ function gateThrough(cell: Cell, raw: unknown): void {
2633
+ let checked: unknown = raw
2634
+ if (cell.schema !== null) {
2635
+ const answer = runSchema(cell.schema, checked)
2636
+ if (answer.issues !== null) {
2637
+ // 4.9: nothing is stored, so the snapshot before this one goes on serving.
2638
+ refused(cell, validationError<Found>(answer.issues))
2639
+ return
2640
+ }
2641
+ checked = answer.value
2642
+ }
2643
+ const transform = cell.transform
2644
+ if (transform !== null) {
2645
+ const shaped = transform(checked)
2646
+ if (isFailed(shaped)) {
2647
+ refused(cell, shaped)
2648
+ return
2649
+ }
2650
+ checked = shaped
2651
+ }
2652
+ cell.value = checked
2653
+ }
2654
+
2655
+ /**
2656
+ * What is held, for the paths that hand the value to somebody other than a reader — an
2657
+ * effect, a waiter, an adoption's mirror.
2658
+ */
2659
+ function heldValue(cell: Cell): unknown {
2660
+ const stream = cell.stream
2661
+ if (stream !== null) materialise(cell, stream)
2662
+ return cell.value
2663
+ }
2664
+
2665
+ /**
2666
+ * Releases the standing production at its deadline, waking nobody.
2667
+ *
2668
+ * 6.7: THE DROP, AND IT IS THE WHOLE OF WHAT A DEADLINE DOES. The production is
2669
+ * RELEASED rather than merely stopped being served, and that is the difference between a
2670
+ * `ttl` that bounds memory and one that only bounds freshness: a body returning a large
2671
+ * payload holds it until something replaces it, and on a value nothing reads again that
2672
+ * is the life of the process.
2673
+ *
2674
+ * 6.9: `loading` IS NOT SET, because nothing has been started. 6.6 has the producer run
2675
+ * on the READ that follows, so between the deadline and that read the value is neither
2676
+ * ready nor busy — which is exactly what those two probes mean, and is why `s.ready`
2677
+ * needs no clock of its own: it reads `servable`, and this is what moved it.
2678
+ *
2679
+ * 6.1: NOTHING IS WOKEN. A wake here would cause the read that runs the producer, and a
2680
+ * `ttl` would then reload every value on its deadline whether or not anything wanted it —
2681
+ * which is `s.refresh` (7.4) wearing a different name.
2682
+ */
2683
+ function dropStanding(cell: Cell, expiry: Expiry): void {
2684
+ expiry.dropped = true
2685
+ cell.value = undefined
2686
+ cell.landed = false
2687
+ cell.servable = false
2688
+ cell.direct = false
2689
+ }
2690
+
2691
+ /**
2692
+ * Arms the timer for the nearest deadline this value holds.
2693
+ *
2694
+ * 6.3: THE STANDING PRODUCTION'S DEADLINE, where a deadline reaches it. A value with nothing
2695
+ * left to expire arms nothing, which is what stops the callback below keeping every `ttl` value
2696
+ * alive for the life of the process: it names its cell.
2697
+ */
2698
+ function armNext(cell: Cell, expiry: Expiry): void {
2699
+ if (expiry.timer !== null) return
2700
+ if (!standingLive(cell, expiry)) return
2701
+ const deadline = expiry.at + expiry.ms
2702
+ armTimer(expiry, deadline - Date.now(), () => {
2703
+ sweepExpiry(cell)
2704
+ })
2705
+ }
2706
+
2707
+ /**
2708
+ * Whether the value has a producer to run again: a body or a store.
2709
+ *
2710
+ * WHETHER THERE IS A PRODUCER TO RUN AGAIN: a body, or a store (8.2), which is somewhere to get the
2711
+ * value back from. A value with neither holds what the app put there, and a deadline or a trigger
2712
+ * has nothing to reload it with (6.2, 7.6).
2713
+ */
2714
+ function reloads(cell: Cell): boolean {
2715
+ return cell.body !== null || cell.store !== null
2716
+ }
2717
+
2718
+ /**
2719
+ * Runs the producer again: the body, or a re-read of the store.
2720
+ *
2721
+ * RUN THE PRODUCER AGAIN, for a trigger (7.4), a debt a read settles (7.13) and a deadline a read
2722
+ * follows (6.6). `startProducer` rather than `run`: on a streaming producer the body is the
2723
+ * generator, and running it as a recompute would store the iterator it hands back (9.6).
2724
+ */
2725
+ function reload(cell: Cell): void {
2726
+ if (cell.body !== null) startProducer(cell)
2727
+ else rereadStore(cell, cell.store as Persisted)
2728
+ }
2729
+
2730
+ /**
2731
+ * Marks a load started and moves `busy`.
2732
+ *
2733
+ * A LOAD HAS STARTED, and `busy` is the probe it moves (3.7) — a guard that asked has to hear it,
2734
+ * and nothing a reader can see has moved yet. Called WHERE THE LOAD STARTS — a pending answer taken
2735
+ * in, a stream opened, a store read that did not answer at once — and nowhere ahead of it. A caller
2736
+ * that set `loading` on its way in made each of those find it already set and stay silent, so a
2737
+ * reload a read started was one no `busy` guard ever saw; and a synchronous body that is no load at
2738
+ * all woke every guard onto a `busy` that was false again by the time it ran.
2739
+ */
2740
+ function beginLoad(cell: Cell): void {
2741
+ // Ahead of the early return: a deferred keyed entry is `loading` before its first start.
2742
+ if (!cell.filed && reloads(cell)) fileProducer(cell)
2743
+ if (cell.loading) return
2744
+ cell.loading = true
2745
+ probesMoved(cell)
2746
+ }
2747
+
2748
+ /**
2749
+ * Whether a deadline reaches the standing production.
2750
+ *
2751
+ * WHETHER A DEADLINE REACHES THE STANDING PRODUCTION: there is a producer to reload it (6.2), 6.7
2752
+ * has not already released it, and it is being served — which is what keeps a value whose load is
2753
+ * in flight from arming against the production that load is replacing.
2754
+ *
2755
+ * AND WHAT IS SERVED WAS MINTED, which every producer but a streaming one answers yes to the moment
2756
+ * it is servable. A stream serves the run it is building (9.1), and that run has minted nothing
2757
+ * until it closes (6.11) — so a deadline has nothing to measure from and must not drop it.
2758
+ */
2759
+ function standingLive(cell: Cell, expiry: Expiry): boolean {
2760
+ if (!reloads(cell) || expiry.dropped || !cell.servable) return false
2761
+ const stream = cell.stream
2762
+ return stream === null || stream.closed
2763
+ }
2764
+
2765
+ /**
2766
+ * Drops what has expired and re-arms against the nearest deadline.
2767
+ *
2768
+ * 6.3's timer, fired — AND IT MAY BE EARLY. The standing deadline moves forward on every
2769
+ * production and re-arming per production would be a `setTimeout` per write. So the timer is
2770
+ * left where it was, and this re-arms against whatever is nearest now. An early fire drops nothing and
2771
+ * costs one re-arm per window.
2772
+ */
2773
+ function sweepExpiry(cell: Cell): void {
2774
+ const expiry = cell.expiry
2775
+ if (expiry === null) return
2776
+ expiry.timer = null
2777
+ if (standingLive(cell, expiry) && Date.now() - expiry.at >= expiry.ms)
2778
+ dropStanding(cell, expiry)
2779
+ armNext(cell, expiry)
2780
+ }
2781
+
2782
+ /**
2783
+ * The read's expiry check: drops a production past its deadline and reloads it.
2784
+ *
2785
+ * THE READ'S HALF. The timer above is what normally moves the probes, and this is the
2786
+ * backstop for one that fired late — a clamped background tab, a blocked loop, a `ttl`
2787
+ * under the clamp. 6.5 is written about the READ rather than about when the
2788
+ * timer got there.
2789
+ *
2790
+ * A VALUE WITH NO BODY REACHES HERE AND TURNS ROUND, one frame per read, and that is
2791
+ * deliberate: `setDirect` tests one field, and telling one from a body value there would put a
2792
+ * second load on the path every value in the design walks. 6.2 is the same sentence from the other side — with no body
2793
+ * there is nothing to call, so what the app put there stands.
2794
+ */
2795
+ function expire(cell: Cell): void {
2796
+ if (!reloads(cell)) return
2797
+ const expiry = cell.expiry as Expiry
2798
+ if (standingLive(cell, expiry) && Date.now() - expiry.at >= expiry.ms)
2799
+ dropStanding(cell, expiry)
2800
+ // 6.6: THE PRODUCER RUNS ON THE READ THAT FOLLOWS, and `dropped` is what tells this
2801
+ // from an `invalidate` whose load is still in flight. No combination of the cell's own
2802
+ // fields separates them — both are unservable with a body — and reading it wrong runs
2803
+ // the body again on every read for as long as the load takes.
2804
+ if (!expiry.dropped) return
2805
+ expiry.dropped = false
2806
+ // Work is started NOW, which is the first moment 6.9 stops applying — and `busy` moves where
2807
+ // the load actually starts, not here (see `beginLoad`).
2808
+ reload(cell)
2809
+ }
2810
+
2811
+ /**
2812
+ * The read's slow path, for every reason `direct` is false.
2813
+ *
2814
+ * EVERY REASON `direct` IS FALSE, told apart here rather than on the read. It is the
2815
+ * pull and the refusal in one frame, and it is correct however the flag got to false —
2816
+ * which is what lets the flag be conservative.
2817
+ */
2818
+ function readIndirect(cell: Cell): unknown {
2819
+ if (cell.owes !== OWES_NOTHING) settleOwed(cell)
2820
+ if (cell.state !== CLEAN) resolve(cell)
2821
+ // 6.5: THE READ THAT FOLLOWS. Every value carrying an expiry arrives here and no
2822
+ // other value does, which is the whole of what `setDirect` buys.
2823
+ if (cell.expiry !== null) expire(cell)
2824
+ if (cell.stream !== null) materialise(cell, cell.stream)
2825
+ if (!cell.servable) {
2826
+ // 2.3: a failed producer with nothing landed is the one case holding no value
2827
+ // and a refusal that explains the absence.
2828
+ const failure = failureOf(cell)
2829
+ if (failure !== undefined) throw failure
2830
+ throw new NotLanded(cell.callable as object, cell.label)
2831
+ }
2832
+ return cell.value
2833
+ }
2834
+
2835
+ /**
2836
+ * Every value that is not streaming shares this as its `ring`. The field stays monomorphically an
2837
+ * Array — CLAUDE.md's shape rule — and only a stream's own chunk buffer is ever pushed to. Frozen so
2838
+ * that if anything ever does push here, it says so rather than corrupting every other value at once.
2839
+ */
2840
+ const EMPTY_RING = Object.freeze([]) as unknown as unknown[]
2841
+
2842
+ /**
2843
+ * The current probe pass, stamped on each cell a probe walk visits.
2844
+ *
2845
+ * A VISITED STAMP, NOT A STACK GUARD, and the difference is an asymptote. Added before
2846
+ * the recursion and removed after it, a guard only says a node is on the CURRENT PATH —
2847
+ * so a shared subgraph is re-walked once per path that reaches it, and a 26-cell DAG
2848
+ * with 130 edges cost 19,660 edge visits and 4,010 hash operations per probe read.
2849
+ *
2850
+ * The stamp MEMOISES, and it is sound for one reason worth stating: within a pass,
2851
+ * "already visited while the walk is still running" IMPLIES "not busy", because a busy
2852
+ * node short-circuits the whole walk at its first visit. So a second arrival at a
2853
+ * stamped node answers false without descending.
2854
+ *
2855
+ * This is the exhaustive case rather than the rare one: the walk short-circuits on
2856
+ * `true`, so the full traversal is the ALL-IDLE graph — the spinner read that renders
2857
+ * no spinner, every frame.
2858
+ */
2859
+ let PROBE_PASS = 0
2860
+
2861
+ /**
2862
+ * Whether this value or anything it reads or adopts is loading.
2863
+ *
2864
+ * Propagation, derived on the read that asks (11.22) rather than held as a
2865
+ * subscription per source. 11.20: a value is busy where a source it read is busy —
2866
+ * and the premise is what `busy` MEANS, not which trigger produced it, so a refresh
2867
+ * over a landed source reports through here even though the body never re-ran.
2868
+ */
2869
+ function walkBusy(cell: Cell, pass: number): boolean {
2870
+ if (cell.loading) return true
2871
+ const adoption = cell.adoption
2872
+ if (cell.sources.length === 0 && adoption === null) return false
2873
+ if (cell.probePass === pass) return false
2874
+ cell.probePass = pass
2875
+ // 11.19: an adopting value reports busy only where the adopted one does — and the
2876
+ // adopted is not in `sources`, because the cursor protocol owns that list and would
2877
+ // truncate anything the body did not read on its next run.
2878
+ if (adoption !== null && walkBusy(adoption.source, pass)) return true
2879
+ const sources = cell.sources
2880
+ for (let index = 0; index < sources.length; index += 1)
2881
+ if (walkBusy(sources[index] as Cell, pass)) return true
2882
+ return false
2883
+ }
2884
+
2885
+ /**
2886
+ * `busy` for a reader: subscribes it to the probe, then answers.
2887
+ *
2888
+ * 3.3: READING A PROBE SUBSCRIBES. Without it the canonical template shape can never come
2889
+ * back: `{#if s.ready()}{s()}{:else}spinner{/if}` renders the spinner, and in that branch it
2890
+ * never reads `s()` — so it subscribes to NOTHING, and the value landing wakes nobody. It
2891
+ * is stuck on the spinner for the life of the page, with the value sitting right there.
2892
+ *
2893
+ * ON ITS OWN EDGE, which is 3.3's "that probe alone" and is bought by what the other
2894
+ * spelling costs the DOM. Subscribing a probe reader through the VALUE edge works and is
2895
+ * twenty lines lighter — and then a load STARTING wakes every reader of the value, which
2896
+ * on a fifty-row list is fifty `.data` writes with the same string in them. Measured with
2897
+ * `harness/measure`: a refresh that changed nothing reported 50 dataWrites, 50 of them
2898
+ * redundant. That is precisely what 5.2's identity gate exists to stop, and it cannot see
2899
+ * a wake nobody minted a production for.
2900
+ */
2901
+ function isBusy(cell: Cell): boolean {
2902
+ probe(cell)
2903
+ return busyNow(cell)
2904
+ }
2905
+
2906
+ /**
2907
+ * The standing refusal: the value's own, or the one on what it adopts.
2908
+ *
2909
+ * 11.50 FOR `error`: the standing refusal is the value's own, or else the one standing on what
2910
+ * it adopts. Unlike `busy` and `ready` it does not propagate from what a body READ (11.20) —
2911
+ * a derived value whose source failed has either a figure of its own or its own refusal.
2912
+ */
2913
+ function failureOf(cell: Cell): unknown {
2914
+ let at = cell
2915
+ while (at.failure === undefined && at.adoption !== null)
2916
+ at = at.adoption.source
2917
+ return at.failure
2918
+ }
2919
+
2920
+ /**
2921
+ * `busy` without subscribing.
2922
+ *
2923
+ * `busy` WITHOUT SUBSCRIBING, for a caller that is not a reader — `then` asks it and must not
2924
+ * become a probe edge of whatever body happens to be on the stack.
2925
+ *
2926
+ * A VALUE WITH NOTHING UNDER IT ANSWERS FROM ITS OWN FIELD, here and in `readyNow`. The walks
2927
+ * already test this, one frame in — hoisting it costs nothing to the graph case and is the whole
2928
+ * of the probe for a state, which is what `{#if user.ready()}` reads. Leaving it inside took a
2929
+ * leaf `ready` from 1.07 ns to 2.05 ns for a pass counter nobody was going to read.
2930
+ */
2931
+ function busyNow(cell: Cell): boolean {
2932
+ if (cell.loading) return true
2933
+ if (cell.sources.length === 0 && cell.adoption === null) return false
2934
+ PROBE_PASS += 1
2935
+ return walkBusy(cell, PROBE_PASS)
2936
+ }
2937
+
2938
+ /**
2939
+ * Whether this value and everything it reads or adopts has something to serve.
2940
+ *
2941
+ * THE OTHER HALF OF THE FLOOR, and the quantifiers are not a pair of preferences: `busy`
2942
+ * asks whether ANYTHING it reads is loading, `ready` whether EVERYTHING it reads has
2943
+ * something to serve. That is the only pairing under which `busy && !ready` reads as one
2944
+ * sentence, and it is what makes a value no better than the worst thing it was built from.
2945
+ *
2946
+ * WITHOUT IT A DERIVED VALUE OUTRANKED ITS SOURCE: `source.invalidate()` left the source
2947
+ * reporting `ready` false while the value derived from it reported true and went on
2948
+ * serving the figure it had computed before — right by its own lights, and a lie about the
2949
+ * data. Nothing in the output says so, which is why this is a walk and not a field.
2950
+ *
2951
+ * The stamp MEMOISES the same way `walkBusy`'s does and is sound for the mirrored reason:
2952
+ * this walk short-circuits on NOT ready, so a second arrival at a node the walk is still
2953
+ * inside is a node that has not refused, and answering `true` there is answering what the
2954
+ * first visit will.
2955
+ */
2956
+ function walkReady(cell: Cell, pass: number): boolean {
2957
+ if (!cell.servable) return false
2958
+ const adoption = cell.adoption
2959
+ if (cell.sources.length === 0 && adoption === null) return true
2960
+ if (cell.probePass === pass) return true
2961
+ cell.probePass = pass
2962
+ if (adoption !== null && !walkReady(adoption.source, pass)) return false
2963
+ const sources = cell.sources
2964
+ for (let index = 0; index < sources.length; index += 1)
2965
+ if (!walkReady(sources[index] as Cell, pass)) return false
2966
+ return true
2967
+ }
2968
+
2969
+ function isReady(cell: Cell): boolean {
2970
+ probe(cell)
2971
+ return readyNow(cell)
2972
+ }
2973
+
2974
+ /**
2975
+ * The body run where it is owed, before a probe answers about it.
2976
+ *
2977
+ * 3.2 — A PROBE ANSWERS ABOUT THE VALUE A READ WOULD SERVE. Under push-pull a write leaves every
2978
+ * derived value it reached unrun, so a probe that walked what the last run left answered about a
2979
+ * value nothing would serve: `x.ready()` true over a body whose inputs had moved to a load, and the
2980
+ * read the guard admitted threw `NotLanded`. `peek` pulls for the same reason.
2981
+ */
2982
+ function bringCurrent(cell: Cell): void {
2983
+ if (cell.owes !== OWES_NOTHING) settleOwed(cell)
2984
+ if (cell.state !== CLEAN) resolve(cell)
2985
+ }
2986
+
2987
+ /** What every probe does before it answers: subscribes the reader (3.3), then brings `cell` current. */
2988
+ function probe(cell: Cell): void {
2989
+ const reader = TRACKING.reader
2990
+ if (reader !== null) trackProbe(cell, reader)
2991
+ bringCurrent(cell)
2992
+ }
2993
+
2994
+ function readyNow(cell: Cell): boolean {
2995
+ if (!cell.servable) return false
2996
+ if (cell.sources.length === 0 && cell.adoption === null) return true
2997
+ PROBE_PASS += 1
2998
+ return walkReady(cell, PROBE_PASS)
2999
+ }
3000
+
3001
+ /**
3002
+ * A promise of the value once it is servable and not busy, or of its failure.
3003
+ *
3004
+ * 2.7: SETTLED IS SERVABLE AND NOT BUSY, and it is both halves — `busy` as the probe answers
3005
+ * it, through what the value read and what it adopted. Resolving on `servable` alone handed a
3006
+ * caller awaiting a refresh the value the refresh was replacing, and a caller awaiting a stream
3007
+ * its first chunk; reading the value's own `loading` alone did the same through an adoption.
3008
+ *
3009
+ * `untilStreaming` answers `STREAMING` the moment the value is a stream instead (9.6), for a
3010
+ * reader that forwards its chunks rather than waiting out the run.
3011
+ */
3012
+ function settled(cell: Cell, untilStreaming = false): Promise<unknown> {
3013
+ // 1.7: awaiting a value is reaching it, so what a read would pull is pulled here too — a reload
3014
+ // an invalidate owed, a recompute a write left marked, and a reload a `ttl` drop owes (6.6):
3015
+ // with nothing served and nothing loading, the await would wait on a probe nothing moves.
3016
+ //
3017
+ // ONLY ONCE THE TIMER HAS DROPPED IT. The read's half of 6.5 — a production still served past
3018
+ // its deadline — is not taken here, because 16.7's `ttl` of 0 makes every mutation's production
3019
+ // past its deadline the moment it lands, and the await that answers the call ran it again.
3020
+ if (cell.owes !== OWES_NOTHING) settleOwed(cell)
3021
+ if (cell.state !== CLEAN) resolve(cell)
3022
+ if (cell.expiry?.dropped) expire(cell)
3023
+ if (untilStreaming && cell.stream !== null)
3024
+ return Promise.resolve(STREAMING)
3025
+ if (cell.servable && !busyNow(cell)) return Promise.resolve(heldValue(cell))
3026
+ if (!cell.landed && !busyNow(cell)) {
3027
+ const failure = failureOf(cell)
3028
+ if (failure !== undefined) return Promise.reject(failure)
3029
+ }
3030
+ return new Promise((settle, fail) => {
3031
+ // THE ONE CELL IT WAITS ON, declared rather than tracked. It was registered outside
3032
+ // the tracking protocol, so without this a `CHECK` mark arriving from further
3033
+ // upstream would have nothing to resolve against.
3034
+ const waiter: Subscriber = newSubscriber([cell], null)
3035
+ waiter.notify = (): void => {
3036
+ // THE WAITER PULLS. A value built from a source that has just landed is marked and
3037
+ // not yet re-run — nothing else reads it — so asking whether it is busy before
3038
+ // pulling it answers from the run that aborted, and the await never settles.
3039
+ if (cell.state !== CLEAN) resolve(cell)
3040
+ if (untilStreaming && cell.stream !== null) {
3041
+ waiter.alive = false
3042
+ dropProbeReader(cell, waiter)
3043
+ settle(STREAMING)
3044
+ return
3045
+ }
3046
+ if (busyNow(cell)) return
3047
+ if (cell.servable) {
3048
+ waiter.alive = false
3049
+ dropProbeReader(cell, waiter)
3050
+ settle(heldValue(cell))
3051
+ return
3052
+ }
3053
+ if (cell.landed) return
3054
+ const failure = failureOf(cell)
3055
+ if (failure !== undefined) {
3056
+ waiter.alive = false
3057
+ dropProbeReader(cell, waiter)
3058
+ fail(failure)
3059
+ }
3060
+ }
3061
+ // ON THE PROBE EDGE, because what it waits for is a probe: every way to settled moves
3062
+ // `busy` or `ready` here or upstream, and `markProbes` carries an upstream move down
3063
+ // the value and adoption edges — where a stream's close mints nothing a value reader
3064
+ // would be woken by.
3065
+ cell.probeReaders.push(waiter)
3066
+ })
3067
+ }
3068
+
3069
+ /**
3070
+ * Runs an effect with this value each time it changes; returns the disposer.
3071
+ *
3072
+ * 12.9: `s.watch` IS `watch` NARROWED TO THIS VALUE, and now structurally rather than by
3073
+ * matching its policy clause for clause. 12.3 is the general form — sources given rather
3074
+ * than discovered — and one source given is what `s.watch` means. What was here before was
3075
+ * a second copy of the subscriber, the disposer, the re-entrancy guard and 12.8, which is
3076
+ * exactly the divergence 12.9 forbids: the copy had no `catch` at all, so a throwing effect
3077
+ * re-ran into the same throw on every write where `watch` stops.
3078
+ *
3079
+ * The value is handed over rather than read, so the effect never reaches the tracked path
3080
+ * and never throws `NotLanded` from this source.
3081
+ */
3082
+ function watchCell(
3083
+ cell: Cell,
3084
+ // biome-ignore lint/suspicious/noConfusingVoidType: `void` is an EFFECT'S RETURN POSITION and is load-bearing. `undefined` there refuses the ordinary effect — a block body that returns nothing infers `void`, which is not assignable to `undefined` — so the rule's own fix would reject every caller that does not return a disposer.
3085
+ effect: (value: unknown) => void | (() => void),
3086
+ ): () => void {
3087
+ return owned(
3088
+ watchOver([cell], null, () => {
3089
+ // 2.2 holds here as a SKIP rather than a throw: an effect has nothing to be handed
3090
+ // until something has landed, and its turn comes when it does.
3091
+ if (!cell.servable) return undefined
3092
+ return effect(heldValue(cell))
3093
+ }),
3094
+ )
3095
+ }
3096
+
3097
+ function patchCell(cell: Cell, mutate: (value: unknown) => void): void {
3098
+ // 2.2: there is nothing to mutate where nothing has landed, and handing the callback
3099
+ // `undefined` failed inside the app's own code instead.
3100
+ if (!cell.landed) throw new NotLanded(cell.callable as object, cell.label)
3101
+ const stream = cell.stream
3102
+ if (stream === null) {
3103
+ const cap = cell.cap
3104
+ // THE HEAD IS THE LAST PRODUCTION MINTED, which a window may be holding apart from the one
3105
+ // served: patching the served one overwrote the held production with it, and the write
3106
+ // the window held was never seen.
3107
+ const head = cap?.holding && cell.body === null ? cap.held : cell.value
3108
+ recordWrites(head, mutate, PATCH_SINKS.get(cell))
3109
+ // 5.7: REPLACES THE HEAD PRODUCTION RATHER THAN APPENDING ONE, so the ordinal does not
3110
+ // move: the follow's version tells a patch from a production by exactly that, and sends a
3111
+ // patch as its writes (18.11). A cursor reads the change off the object's patch epoch
3112
+ // instead. The wake was never the ordinal's doing — it is the cascade's.
3113
+ //
3114
+ // 5.23 — AND THE CASCADE IS WHAT A WINDOW CAPS. The object has already changed, so what is
3115
+ // held is the wake alone: readers are told once per window, and `busy` stands meanwhile
3116
+ // (5.15). A body's cap caps its runs instead (5.11), so a patch there wakes as before.
3117
+ //
3118
+ // 8.8 AS `serve` READS IT: a patch the window held is written by the release that serves
3119
+ // it, so a run of patches in one window is one write rather than one per patch (5.11).
3120
+ wakePatched(cell, head)
3121
+ return
3122
+ }
3123
+ // 9.13: the accumulation itself, so the next chunk lands after the change rather than
3124
+ // rebuilding a snapshot from chunks the patch never saw.
3125
+ const before = stream.chunks.length
3126
+ // A CURSOR BEHIND needs where the patch wrote, which its ops say: the follow's own sink, or one
3127
+ // of this patch's alone where nothing follows the value.
3128
+ const followed = PATCH_SINKS.get(cell)
3129
+ const sink =
3130
+ followed ??
3131
+ (hasCursorBehind(cell) ? { ops: [], lost: false } : undefined)
3132
+ const from = sink === undefined ? 0 : sink.ops.length
3133
+ recordWrites(stream.chunks, mutate, sink)
3134
+ // 5.7 AS THE VALUE BRANCH KEEPS IT: a patch mints no ordinal, so an accumulation it grew or
3135
+ // shrank moves the ring's base instead — `ring[i]` stays ordinal `ringBase + i + 1` and the
3136
+ // next chunk lands one past the ordinal a caught-up cursor holds. And what it added is shown.
3137
+ const grown = stream.chunks.length - before
3138
+ if (grown !== 0) {
3139
+ const edited =
3140
+ sink === undefined || sink.lost
3141
+ ? undefined
3142
+ : firstWritten(sink.ops, from, before)
3143
+ if (edited !== undefined) keepPlaces(cell, edited, grown)
3144
+ cell.ringBase -= grown
3145
+ stream.visible = Math.min(
3146
+ Math.max(stream.visible + grown, 0),
3147
+ stream.chunks.length,
3148
+ )
3149
+ }
3150
+ stream.version += 1
3151
+ // 5.23, as for a chunk (5.17): the window's close is what tells the readers.
3152
+ if (tellsChunks(cell, cell.cap)) cascade(cell)
3153
+ }
3154
+
3155
+ /**
3156
+ * The lowest index of an accumulation the ops from `from` on wrote at, or `undefined` where they
3157
+ * wrote none — a reorder is sent whole, and says nothing of where.
3158
+ */
3159
+ function firstWritten(
3160
+ ops: PatchOp[],
3161
+ from: number,
3162
+ length: number,
3163
+ ): number | undefined {
3164
+ let lowest: number | undefined
3165
+ for (let at = from; at < ops.length; at += 1) {
3166
+ const path = (ops[at] as PatchOp).path
3167
+ const slash = path.indexOf('/', 1)
3168
+ const step = path.slice(1, slash === -1 ? path.length : slash)
3169
+ const index = step === '-' ? length : Number(step)
3170
+ if (lowest === undefined || index < lowest) lowest = index
3171
+ }
3172
+ return lowest
3173
+ }
3174
+
3175
+ function wakePatched(cell: Cell, head: unknown): void {
3176
+ const cap = cell.cap
3177
+ if (cap === null || cell.body !== null || wakes(cell, cap, head)) {
3178
+ cascade(cell)
3179
+ if (cell.store !== null) persist(cell, cell.store, cell.value)
3180
+ }
3181
+ }
3182
+
3183
+ /**
3184
+ * What an `invalidate` leaves behind: nothing owed, a look above, or a reload.
3185
+ *
3186
+ * WHAT AN INVALIDATE LEAVES BEHIND, and it is a debt rather than a mark. The mark walk's states
3187
+ * are the wrong tool: a node marked `CHECK` or `DIRTY` without its effects queued is one a later
3188
+ * write's walk stops at — `state >= wanted` — and the effects below it are never woken for a
3189
+ * change that really happened. So nothing in the graph's state moves; the invalidated value OWES
3190
+ * A RELOAD, the values built from it OWE A LOOK ABOVE, and none of them is directly servable, so
3191
+ * the read that reaches any of them goes a frame in and settles the debt first (7.12, 7.13).
3192
+ */
3193
+ const OWES_NOTHING: number = 0
3194
+ const OWES_ABOVE: number = 1
3195
+ const OWES_RELOAD: number = 2
3196
+
3197
+ /**
3198
+ * Visits a value and each value down its adoption chain.
3199
+ *
3200
+ * 11.51 IS EVERY TRIGGER AND EVERY ADOPTER, and the chain is walked rather than recursed
3201
+ * into: the reach into `adoption.source` sat PAST the "no producer" return, so an adoption made by
3202
+ * `outer.set(inner)` (11.61) — which leaves `body` null — swallowed both triggers whole.
3203
+ *
3204
+ * 13.6 is what the "no producer" arm is for: an entry with nothing to reload is skipped, and what
3205
+ * it ADOPTS still has to be reached.
3206
+ */
3207
+ function eachAdopted(cell: Cell, visit: (cell: Cell) => void): void {
3208
+ let at: Cell = cell
3209
+ for (;;) {
3210
+ visit(at)
3211
+ // 11.51: the data is behind whatever the body handed back, not in the body itself
3212
+ // — AFTER the run, so the reach is to what is adopted now rather than what was.
3213
+ const adoption = at.adoption
3214
+ if (adoption === null) return
3215
+ at = adoption.source
3216
+ }
3217
+ }
3218
+
3219
+ function refreshOne(cell: Cell): void {
3220
+ // 7.6: inert on a value with no producer. 8.2 makes a store one, so a refresh re-reads it —
3221
+ // another tab may have written.
3222
+ if (!reloads(cell)) return
3223
+ // 5.24 — A WINDOW HOLDS A REFRESH AS IT HOLDS A PRODUCTION: a throttle lets the first through
3224
+ // and opens, a debounce holds every one and is pushed back by each, and what a window held is
3225
+ // one reload when it closes. Three refreshes in a row were three loads, two of them superseded.
3226
+ const cap = cell.cap
3227
+ if (cap !== null && windowHolds(cell, cap)) {
3228
+ cap.reloading = true
3229
+ return
3230
+ }
3231
+ reloadNow(cell)
3232
+ }
3233
+
3234
+ function reloadNow(cell: Cell): void {
3235
+ // A refresh IS the reload an invalidate owed, so the read after it must not run a second.
3236
+ if (cell.owes === OWES_RELOAD) reloadOwed(cell)
3237
+ else reload(cell)
3238
+ }
3239
+
3240
+ /**
3241
+ * Settles an owed reload: stops serving, then runs the producer.
3242
+ *
3243
+ * 7.8: THE HELD VALUE WAS MARKED WRONG, so the reload that settles the mark is not served over —
3244
+ * by a refresh or by the read that follows (7.13) alike. Unserved AHEAD of the reload, and the
3245
+ * order is load-bearing: re-adopting the same value re-mirrors only where the adopter is not
3246
+ * serving (11.18), and that mirror is what reaches a reload the adopted value owes. What it costs
3247
+ * is a reload answering at once with the value it held: its readers were woken by the unserve, and
3248
+ * read the same value again.
3249
+ */
3250
+ function reloadOwed(cell: Cell): void {
3251
+ cell.owes = OWES_NOTHING
3252
+ unserve(cell)
3253
+ reload(cell)
3254
+ }
3255
+
3256
+ /**
3257
+ * Marks one value as owing a reload, without running or waking anything.
3258
+ *
3259
+ * 7.3, 7.12, 7.14 AND 7.17: A MARK, NOT A LOAD, AND NOT A MOVE. Nothing runs, nothing is sent and
3260
+ * no reader wakes — a guard asking `ready()` included — so a server saying "yours is stale" moves
3261
+ * nothing on screen. The mark is a debt the next HIT settles: a read, or a probe, which answers about
3262
+ * the value a read would serve (3.2) and so runs the reload itself. That is what keeps a guard that
3263
+ * asks later from admitting a read that throws, and from stranding a placeholder that never reads.
3264
+ */
3265
+ function invalidateOne(cell: Cell): void {
3266
+ // 7.6 — sent on to the browsers following it whether or not there is a producer to mark.
3267
+ const followed = FOLLOWED.get(cell)
3268
+ if (followed !== undefined) for (const sendOn of followed) sendOn()
3269
+ if (!reloads(cell)) return
3270
+ // Not directly servable, so the next read goes a frame in and settles the debt.
3271
+ cell.direct = false
3272
+ // 7.15: work already in flight was started from what this says is wrong. A load's answer
3273
+ // lands nowhere once `generation` has moved; a stream is stopped outright.
3274
+ cell.generation += 1
3275
+ cell.loading = false
3276
+ const stream = cell.stream
3277
+ if (stream !== null && stream.source === null) stopStream(stream)
3278
+ cell.owes = OWES_RELOAD
3279
+ owedBelow(cell)
3280
+ }
3281
+
3282
+ /**
3283
+ * Flags everything built from this value as owing a look above.
3284
+ *
3285
+ * Every value built from this one — read from it, or adopting it — goes a frame in on its next
3286
+ * read, which is where 7.13's pull happens. A value already owing something has had its own
3287
+ * downstream flagged, so the walk stops there.
3288
+ */
3289
+ function owedBelow(cell: Cell): void {
3290
+ const readers = cell.readers
3291
+ for (let index = 0; index < readers.length; index += 1) {
3292
+ const reader = readers[index] as Subscriber
3293
+ const below = (reader.isEffect
3294
+ ? reader.adopter
3295
+ : reader) as unknown as Cell | null
3296
+ if (below === null) continue
3297
+ below.direct = false
3298
+ if (below.owes !== OWES_NOTHING) continue
3299
+ below.owes = OWES_ABOVE
3300
+ owedBelow(below)
3301
+ }
3302
+ }
3303
+
3304
+ /**
3305
+ * Settles what an `invalidate` left this value owing.
3306
+ *
3307
+ * THE READ SETTLES THE DEBT. A value owing a reload runs its producer; one owing a look above
3308
+ * reloads whatever above it owes one, and the cascade from what that reload mints marks it the
3309
+ * ordinary way — so a reload that lands the same value leaves it serving what it held.
3310
+ */
3311
+ function settleOwed(cell: Cell): void {
3312
+ if (cell.owes === OWES_RELOAD) {
3313
+ reloadOwed(cell)
3314
+ return
3315
+ }
3316
+ cell.owes = OWES_NOTHING
3317
+ pullAbove(cell)
3318
+ // Nothing above it changed what it computed, so it is servable straight again.
3319
+ if (cell.state === CLEAN) setDirect(cell, cell.servable)
3320
+ }
3321
+
3322
+ function pullAbove(cell: Cell): void {
3323
+ const sources = cell.sources
3324
+ for (let index = 0; index < sources.length; index += 1) {
3325
+ const source = sources[index] as Cell
3326
+ if (source.owes !== OWES_NOTHING) settleOwed(source)
3327
+ }
3328
+ const adoption = cell.adoption
3329
+ if (adoption !== null && adoption.source.owes !== OWES_NOTHING)
3330
+ settleOwed(adoption.source)
3331
+ }
3332
+
3333
+ /**
3334
+ * The general `set`: adopts a `Reactive`, absorbs a load, or gates a value.
3335
+ *
3336
+ * 4.18: a refusal comes back to the caller, and only a refusal — an accepted write is `void`,
3337
+ * whatever ordinal `accept` minted for it. Behind its own frame so the settled, ungated
3338
+ * write above it stays small enough to be inlined into whatever loop calls `set`.
3339
+ */
3340
+ function setThroughGates(cell: Cell, value: unknown): unknown {
3341
+ // 11.61: A `Reactive` WRITTEN IS ADOPTED, never stored — the same sentence 11.12 makes about
3342
+ // one a body hands back, and the brand is read before `then` for the same reason (1.6). It is
3343
+ // off the common write path rather than in front of it: a settled primitive never reaches this
3344
+ // frame at all, and what does is a thenable or a callable.
3345
+ if (isReactive(value)) {
3346
+ // 11.66 — a write that would close a cycle throws, as misuse rather than a refusal of data.
3347
+ const cycle = adopt(cell, (value as unknown as Callable)[CELL])
3348
+ if (cycle !== undefined) throw cycle
3349
+ return undefined
3350
+ }
3351
+ if (!isThenable(value)) {
3352
+ const answer = accept(cell, value)
3353
+ return typeof answer === 'number' ? undefined : answer
3354
+ }
3355
+ absorb(cell, value, false)
3356
+ return undefined
3357
+ }
3358
+
3359
+ /**
3360
+ * Lands what a value opens with: a `Reactive` adopted, anything else absorbed.
3361
+ *
3362
+ * 11.61 AT CONSTRUCTION — `reactive(other)` opens on `other` the way `s.set(other)` writes it, by
3363
+ * adopting it rather than storing it, so the two spellings agree (31.8). Stored, the value held
3364
+ * `other`'s getter, and a read handed back a function.
3365
+ */
3366
+ function open(cell: Cell, initial: unknown): void {
3367
+ if (!isReactive(initial)) {
3368
+ absorb(cell, initial, false)
3369
+ return
3370
+ }
3371
+ const cycle = adopt(cell, (initial as unknown as Callable)[CELL])
3372
+ if (cycle !== undefined) throw cycle
3373
+ }
3374
+
3375
+ /**
3376
+ * Starts the producer of a keyed entry a window was holding back.
3377
+ *
3378
+ * 5.19 AND 5.21: AN ENTRY A WINDOW IS HOLDING BACK is busy with nothing to serve, and starting it is
3379
+ * the window's call. Starting runs the producer the reach would have run.
3380
+ */
3381
+ export function startDeferred(value: unknown): void {
3382
+ startProducer((value as Callable)[CELL])
3383
+ }
3384
+
3385
+ /**
3386
+ * Ends the load of a keyed entry a window superseded before it started.
3387
+ *
3388
+ * 5.20: an entry the window superseded before it started. Nothing is in flight for it any more,
3389
+ * and a reader still holding it hears that.
3390
+ */
3391
+ export function abandonDeferred(value: unknown): void {
3392
+ const cell = (value as Callable)[CELL]
3393
+ if (!cell.loading) return
3394
+ cell.loading = false
3395
+ probesMoved(cell)
3396
+ }
3397
+
3398
+ // ── `store` ──────────────────────────────────────────────────────────────────────────────
3399
+
3400
+ /**
3401
+ * Calls the store's `get`, taking a throw as a miss.
3402
+ *
3403
+ * 8.15: a `get` that throws cannot read the value, and that is a miss — warned, because a store
3404
+ * that can never be read is one an app wants to hear about.
3405
+ */
3406
+ function readStore(cell: Cell, persisted: Persisted): unknown {
3407
+ try {
3408
+ return persisted.store.get()
3409
+ } catch (failed) {
3410
+ warnStore(
3411
+ cell,
3412
+ 'could not be read, and is taken as a miss (8.15)',
3413
+ failed,
3414
+ )
3415
+ return undefined
3416
+ }
3417
+ }
3418
+
3419
+ /**
3420
+ * The logger a store failure warns through.
3421
+ *
3422
+ * 8.12 — under the namespace the clause names; a failed write also reaches `onError`, through
3423
+ * `storeWriteFailed`.
3424
+ */
3425
+ const STORE_LOG = namedLogger('abide:reactive')
3426
+
3427
+ function warnStore(cell: Cell, what: string, failed: unknown): void {
3428
+ STORE_LOG.warning(`${cell.label}: a store ${what}.`, failed)
3429
+ }
3430
+
3431
+ /**
3432
+ * Restores a value from its store at construction, falling back on a miss.
3433
+ *
3434
+ * 8.4: A SYNCHRONOUS `get` IS NOT A LOAD — the value is there at construction and nothing is
3435
+ * pending. An unsettled one is a load like any other, and a write made while it is out supersedes
3436
+ * it the way a write supersedes any load: `generation` moves, and the answer lands nowhere.
3437
+ */
3438
+ function restoreFirst(
3439
+ cell: Cell,
3440
+ persisted: Persisted,
3441
+ initial: unknown,
3442
+ ): void {
3443
+ const answer = readStore(cell, persisted)
3444
+ if (!isThenable(answer)) {
3445
+ settleRestore(cell, persisted, answer, initial)
3446
+ return
3447
+ }
3448
+ cell.loading = true
3449
+ const generation = cell.generation
3450
+ answer.then(
3451
+ (value) => {
3452
+ if (cell.generation === generation)
3453
+ settleRestore(cell, persisted, value, initial)
3454
+ },
3455
+ (failed: unknown) => {
3456
+ if (cell.generation !== generation) return
3457
+ warnStore(
3458
+ cell,
3459
+ 'could not be read, and is taken as a miss (8.15)',
3460
+ failed,
3461
+ )
3462
+ settleRestore(cell, persisted, undefined, initial)
3463
+ },
3464
+ )
3465
+ }
3466
+
3467
+ function settleRestore(
3468
+ cell: Cell,
3469
+ persisted: Persisted,
3470
+ value: unknown,
3471
+ initial: unknown,
3472
+ ): void {
3473
+ if (value !== undefined) {
3474
+ restore(cell, persisted, value)
3475
+ return
3476
+ }
3477
+ // A MISS IS THE VALUE WITHOUT A STORE: the body runs, or the initial value lands (8.3).
3478
+ if (cell.body !== null) startProducer(cell)
3479
+ else if (initial === undefined) landOpening(cell)
3480
+ else if (initial !== NO_INITIAL) open(cell, initial)
3481
+ else if (cell.loading) {
3482
+ cell.loading = false
3483
+ probesMoved(cell)
3484
+ }
3485
+ }
3486
+
3487
+ /**
3488
+ * Mints a stored value as a production, ungated and not written back.
3489
+ *
3490
+ * 8.5: A RESTORE IS NOT A WRITE. It mints the production straight — no `schema`, no `transform`,
3491
+ * those gating what goes in and a restore being what was already stored — and 8.8 does not write
3492
+ * it back.
3493
+ */
3494
+ function restore(cell: Cell, persisted: Persisted, value: unknown): void {
3495
+ persisted.restoring = true
3496
+ try {
3497
+ const stream = cell.stream
3498
+ if (stream === null) produce(cell, value)
3499
+ else restoreStream(cell, stream, value as unknown[])
3500
+ } finally {
3501
+ persisted.restoring = false
3502
+ }
3503
+ }
3504
+
3505
+ /**
3506
+ * Restores a stream's stored accumulation as a finished run.
3507
+ *
3508
+ * 8.6 AND 8.7: the chunk buffer is seeded with the accumulation, and the stream reads as finished — ready,
3509
+ * and not busy — with its body never started.
3510
+ */
3511
+ function restoreStream(cell: Cell, stream: Stream, chunks: unknown[]): void {
3512
+ beginAccumulation(cell, stream)
3513
+ for (let index = 0; index < chunks.length; index += 1) {
3514
+ stream.chunks.push(chunks[index])
3515
+ cell.ordinal += 1
3516
+ }
3517
+ stream.visible = stream.chunks.length
3518
+ stream.version += 1
3519
+ const moved = settleProbes(cell)
3520
+ landChunks(cell)
3521
+ cascade(cell)
3522
+ if (moved) probesMoved(cell)
3523
+ // 8.7 SAYS THE BODY NEVER STARTS, AND `pump` IS WHAT REACHES `closeRun` — so the
3524
+ // restored accumulation is entered as a closed run here or nothing ever does it.
3525
+ // Without this `standingLive` answers false for the life of the value, which takes
3526
+ // the `ttl` out of `expire` and `sweepExpiry` silently — it never drops and never
3527
+ // re-reads the store.
3528
+ closeRun(cell, stream)
3529
+ }
3530
+
3531
+ /**
3532
+ * Reloads a value whose only producer is its store.
3533
+ *
3534
+ * A refresh, an invalidate or an expiry of a value whose only producer is its store. A hit
3535
+ * restores; a miss leaves what is held being served, there being nothing newer to replace it with.
3536
+ *
3537
+ * 8.18: A WRITE THE APP HAS MADE IS THE NEWEST TRUTH, so while one is unconfirmed the store is not
3538
+ * asked at all and the written value stands in its place. Asking took the value BACKWARDS and left
3539
+ * it there: `s.set(99)` over a store still holding 1 leaves a `set` in flight, a `refresh` in the
3540
+ * same turn read 1 and produced it, and the queued write then landed 99 in the store — the cell
3541
+ * serving 1 and the store holding 99 for the life of the value, with `restoring` stopping the
3542
+ * reverted value from being written back and no probe moving to say so.
3543
+ */
3544
+ function rereadStore(cell: Cell, persisted: Persisted): void {
3545
+ if (persisted.writing) {
3546
+ restore(cell, persisted, persisted.unconfirmed)
3547
+ return
3548
+ }
3549
+ const answer = readStore(cell, persisted)
3550
+ if (!isThenable(answer)) {
3551
+ settleReread(cell, persisted, answer)
3552
+ return
3553
+ }
3554
+ beginLoad(cell)
3555
+ const generation = cell.generation
3556
+ answer.then(
3557
+ (value) => {
3558
+ if (cell.generation !== generation) return
3559
+ settleReread(cell, persisted, value)
3560
+ },
3561
+ (failed: unknown) => {
3562
+ if (cell.generation !== generation) return
3563
+ warnStore(
3564
+ cell,
3565
+ 'could not be read, and is taken as a miss (8.15)',
3566
+ failed,
3567
+ )
3568
+ settleReread(cell, persisted, undefined)
3569
+ },
3570
+ )
3571
+ }
3572
+
3573
+ /**
3574
+ * Lands a store re-read, letting an unconfirmed write win.
3575
+ *
3576
+ * 8.18 IS READ ON THE WAY OUT AS WELL AS ON THE WAY IN. A write made while the `get` was in flight
3577
+ * is newer than whatever that `get` answers, hit or miss, and `generation` does not separate them
3578
+ * — a write moves it only where it is a LOAD (4.2), and a settled `s.set` never touches it.
3579
+ */
3580
+ function settleReread(cell: Cell, persisted: Persisted, value: unknown): void {
3581
+ if (persisted.writing) restore(cell, persisted, persisted.unconfirmed)
3582
+ else if (value !== undefined) restore(cell, persisted, value)
3583
+ else settleMiss(cell)
3584
+ }
3585
+
3586
+ function settleMiss(cell: Cell): void {
3587
+ // 8.19: NOTHING LEFT TO SERVE. The miss reached a value that holds nothing — an expiry
3588
+ // released the standing production (6.7) and the re-read 6.6 owes it came back empty, and
3589
+ // there is no body to fall through to on a value whose only producer is its store. Left as a
3590
+ // miss it read as `NotLanded` with all three probes silent for the life of the value, and
3591
+ // `expire` returned at `dropped` on every later read, so nothing ever asked again.
3592
+ if (!cell.landed) {
3593
+ refused(
3594
+ cell,
3595
+ new Error(
3596
+ `${cell.label}: its store answered no value and nothing is held (RULEBOOK 8.19).`,
3597
+ ),
3598
+ )
3599
+ return
3600
+ }
3601
+ const wasServable = cell.servable
3602
+ const wasLoading = cell.loading
3603
+ cell.servable = true
3604
+ cell.loading = false
3605
+ setDirect(cell, cell.state === CLEAN)
3606
+ if (cell.servable !== wasServable) cascade(cell)
3607
+ if (wasLoading || cell.servable !== wasServable) probesMoved(cell)
3608
+ }
3609
+
3610
+ /**
3611
+ * Writes a production to the store, unless it is a restore or a stream's.
3612
+ *
3613
+ * A restore is what was just read, and a stream is written at its close (8.9) — neither is
3614
+ * persisted from here.
3615
+ */
3616
+ function persist(cell: Cell, persisted: Persisted, value: unknown): void {
3617
+ if (persisted.restoring || cell.stream !== null) return
3618
+ writeStore(cell, persisted, value)
3619
+ }
3620
+
3621
+ function writeStore(cell: Cell, persisted: Persisted, value: unknown): void {
3622
+ persisted.unconfirmed = value
3623
+ if (persisted.writing) {
3624
+ persisted.pending = true
3625
+ return
3626
+ }
3627
+ persisted.writing = true
3628
+ sendStore(cell, persisted, value)
3629
+ }
3630
+
3631
+ function storeWriteFailed(cell: Cell, failed: unknown): void {
3632
+ warnStore(cell, 'write failed, and the store stays attached (8.12)', failed)
3633
+ UNEXPECTED.report?.(failed)
3634
+ }
3635
+
3636
+ /**
3637
+ * Hands one value to the store's `set`, warning where it fails.
3638
+ *
3639
+ * 8.11: the write never blocks a reader — the value is already held, and `set` is only how it
3640
+ * leaves. 8.12: a failed write warns and leaves the store attached, so the next is written.
3641
+ */
3642
+ function sendStore(cell: Cell, persisted: Persisted, value: unknown): void {
3643
+ let sent: unknown
3644
+ try {
3645
+ sent = persisted.store.set(value, { ttl: persisted.ttl })
3646
+ } catch (failed) {
3647
+ storeWriteFailed(cell, failed)
3648
+ sent = undefined
3649
+ }
3650
+ if (!isThenable(sent)) {
3651
+ storeWritten(cell, persisted)
3652
+ return
3653
+ }
3654
+ sent.then(
3655
+ () => {
3656
+ storeWritten(cell, persisted)
3657
+ },
3658
+ (failed: unknown) => {
3659
+ storeWriteFailed(cell, failed)
3660
+ storeWritten(cell, persisted)
3661
+ },
3662
+ )
3663
+ }
3664
+
3665
+ function storeWritten(cell: Cell, persisted: Persisted): void {
3666
+ if (!persisted.pending) {
3667
+ persisted.writing = false
3668
+ persisted.unconfirmed = undefined
3669
+ return
3670
+ }
3671
+ // `unconfirmed` IS ALREADY THE ONE TO SEND — 8.10 coalesces latest-wins, so every write made
3672
+ // while this one was out overwrote it, and the send below is the newest of them.
3673
+ persisted.pending = false
3674
+ sendStore(cell, persisted, persisted.unconfirmed)
3675
+ }
3676
+
3677
+ // ── Selections over `tags`, and the bare sweep ──────────────────────────────────────────
3678
+
3679
+ /**
3680
+ * Each tag to the values carrying it, held weakly.
3681
+ *
3682
+ * THE INDEX HOLDS VALUES WEAKLY. A tag is a way to find a value, never a reason to keep one, and a
3683
+ * strong index would hold every tagged value a page ever made for the life of the process. A
3684
+ * collected value is pruned from its sets by the next sweep that finds it gone.
3685
+ */
3686
+ const TAGGED = new Map<string, Set<WeakRef<Cell>>>()
3687
+
3688
+ /**
3689
+ * Every value whose producer is a LOAD, held weakly — what a bare selection sweeps.
3690
+ *
3691
+ * 13.6: A BARE SWEEP REACHES PRODUCERS, and of those it files the ones that LOAD: a value holding
3692
+ * a `store`, filed where it is built, and a body the first time it starts a load — a pending
3693
+ * answer or a stream (`beginLoad`). A synchronous body is a derivation: reloading it recomputes
3694
+ * what its sources already say, and whatever load it reads is filed on its own. And filing is
3695
+ * what every filed value pays — a weak handle measured ~230 ns a value under V8 against ~20 under
3696
+ * JSC — so a value with nothing to load never pays it: a derivation per cell per row stays at
3697
+ * what it cost before, and a load pays it beside the promise it already allocates.
3698
+ *
3699
+ * Held weakly for `TAGGED`'s reason. AN ARRAY, COMPACTED, RATHER THAN A `Set`: a `Set` of weak
3700
+ * handles measured ~120 ns a filing under JSC against ~10 for a push. What a `Set` bought was an
3701
+ * O(1) delete on eviction; here an evicted value drops its `ref` instead, and a handle whose value
3702
+ * no longer points back at it is dead, the same as one whose value was collected. Because a bare
3703
+ * sweep may never run, the filing that finds the array past `compactProducersAt` compacts it, and
3704
+ * the bar doubles past what survives, so the walk is amortised over the filings between two.
3705
+ */
3706
+ let filedProducers: WeakRef<Cell>[] = []
3707
+ let compactProducersAt = 1024
3708
+
3709
+ /**
3710
+ * The probe signal a guard over a selection subscribes to.
3711
+ *
3712
+ * 13.3 AND 13.9: ONE SIGNAL PER SELECTION, keyed by its canonical tags. A guard over a selection
3713
+ * subscribes to this, never to each entry — the probe edge `trackProbe` makes, from a node that
3714
+ * is nothing but that edge.
3715
+ */
3716
+ type Signal = { readers: Subscriber[]; probeReaders: Subscriber[] }
3717
+ const SIGNALS = new Map<string, Signal>()
3718
+ const SIGNALS_BY_TAG = new Map<string, Signal[]>()
3719
+ /**
3720
+ * The bare selection's one signal. Not a key in `SIGNALS`: `{ tags: [] }` canonicalises to the
3721
+ * empty set and matches nothing, where the bare selection matches every filed load in reach.
3722
+ */
3723
+ const EVERY_PRODUCER: Signal = { readers: [], probeReaders: [] }
3724
+
3725
+ function refOf(cell: Cell): WeakRef<Cell> {
3726
+ let ref = cell.ref
3727
+ if (ref === null) {
3728
+ ref = new WeakRef(cell)
3729
+ cell.ref = ref
3730
+ }
3731
+ return ref
3732
+ }
3733
+
3734
+ function tagCell(cell: Cell): void {
3735
+ const ref = refOf(cell)
3736
+ for (const tag of cell.tags as string[]) {
3737
+ let carrying = TAGGED.get(tag)
3738
+ if (carrying === undefined) {
3739
+ carrying = new Set()
3740
+ TAGGED.set(tag, carrying)
3741
+ }
3742
+ carrying.add(ref)
3743
+ }
3744
+ }
3745
+
3746
+ function fileProducer(cell: Cell): void {
3747
+ cell.filed = true
3748
+ filedProducers.push(refOf(cell))
3749
+ if (filedProducers.length > compactProducersAt) {
3750
+ filedProducers = liveProducers()
3751
+ compactProducersAt = Math.max(1024, filedProducers.length * 2)
3752
+ }
3753
+ }
3754
+
3755
+ /** The handles whose value is still standing and still filed — neither collected nor evicted. */
3756
+ function liveProducers(): WeakRef<Cell>[] {
3757
+ const live: WeakRef<Cell>[] = []
3758
+ for (let index = 0; index < filedProducers.length; index += 1) {
3759
+ const ref = filedProducers[index] as WeakRef<Cell>
3760
+ if (ref.deref()?.ref === ref) live.push(ref)
3761
+ }
3762
+ return live
3763
+ }
3764
+
3765
+ /**
3766
+ * Removes an evicted value from every selection index.
3767
+ *
3768
+ * What an eviction calls: an entry out of its `Keyed` is out of every selection with it, rather
3769
+ * than reachable by a sweep until a collection happens to run.
3770
+ */
3771
+ export function leaveSelections(value: unknown): void {
3772
+ const cell = (value as Callable)[CELL]
3773
+ const ref = cell.ref
3774
+ if (ref === null) return
3775
+ // What takes it out of `filedProducers`: a handle its value no longer points back at is dead.
3776
+ cell.ref = null
3777
+ if (cell.tags === null) return
3778
+ for (const tag of cell.tags) {
3779
+ const carrying = TAGGED.get(tag)
3780
+ if (carrying === undefined) continue
3781
+ carrying.delete(ref)
3782
+ if (carrying.size === 0) TAGGED.delete(tag)
3783
+ }
3784
+ }
3785
+
3786
+ /**
3787
+ * Takes every value filed so far out of the bare selection, each filed again by its next load.
3788
+ *
3789
+ * A TEST'S SEAM, with no caller in the framework — `bareSelection.test.ts` calls it before its
3790
+ * first case: a page's process ends with the page, and a test process runs every file before this
3791
+ * one in it. What those files left held — a module's `global`
3792
+ * value, a follow the page keeps for its life — is in reach of a bare sweep (13.13), and a bare
3793
+ * `refresh()` reloads it and reads `busy()` true while it asks.
3794
+ */
3795
+ export function unfileProducers(): void {
3796
+ for (let index = 0; index < filedProducers.length; index += 1) {
3797
+ const cell = (filedProducers[index] as WeakRef<Cell>).deref()
3798
+ if (cell !== undefined) cell.filed = false
3799
+ }
3800
+ filedProducers = []
3801
+ }
3802
+
3803
+ /**
3804
+ * The values a selection reaches in the current scope, `global` values included: those carrying
3805
+ * any of `tags`, or every filed load where `tags` is `null` — the bare selection.
3806
+ *
3807
+ * 13.8 — A SELECTION IS SCOPE-BOUNDED, and a tag with it, so a selection inside one request never
3808
+ * reaches the values another request filed. 13.13 — a `global` value is in every scope, so every
3809
+ * selection reaches it, and 13.10 is the bare case of that. In a browser every cell's scope is
3810
+ * `undefined`, and so is this.
3811
+ */
3812
+ function inReach(tags: string[] | null): Cell[] {
3813
+ const scope = currentScope()
3814
+ if (tags === null) {
3815
+ filedProducers = liveProducers()
3816
+ const found: Cell[] = []
3817
+ for (let index = 0; index < filedProducers.length; index += 1) {
3818
+ const cell = (
3819
+ filedProducers[index] as WeakRef<Cell>
3820
+ ).deref() as Cell
3821
+ if (cell.scope === scope || cell.global) found.push(cell)
3822
+ }
3823
+ return found
3824
+ }
3825
+ const found = new Set<Cell>()
3826
+ for (const tag of tags) {
3827
+ const refs = TAGGED.get(tag)
3828
+ if (refs === undefined) continue
3829
+ for (const ref of refs) {
3830
+ const cell = ref.deref()
3831
+ if (cell === undefined) refs.delete(ref)
3832
+ else if (cell.scope === scope || cell.global) found.add(cell)
3833
+ }
3834
+ }
3835
+ return [...found]
3836
+ }
3837
+
3838
+ function trackSignal(tags: string[] | null): void {
3839
+ const reader = TRACKING.reader
3840
+ if (reader === null) return
3841
+ if (tags === null) {
3842
+ trackProbe(EVERY_PRODUCER as unknown as Tracked, reader)
3843
+ return
3844
+ }
3845
+ const key = JSON.stringify([...new Set(tags)].sort())
3846
+ let signal = SIGNALS.get(key)
3847
+ if (signal === undefined) {
3848
+ signal = { readers: [], probeReaders: [] }
3849
+ SIGNALS.set(key, signal)
3850
+ for (const tag of tags) {
3851
+ const signals = SIGNALS_BY_TAG.get(tag)
3852
+ if (signals === undefined) SIGNALS_BY_TAG.set(tag, [signal])
3853
+ else signals.push(signal)
3854
+ }
3855
+ }
3856
+ trackProbe(signal as unknown as Tracked, reader)
3857
+ }
3858
+
3859
+ function markSignals(tags: string[]): void {
3860
+ for (const tag of tags) {
3861
+ const signals = SIGNALS_BY_TAG.get(tag)
3862
+ if (signals === undefined) continue
3863
+ for (const signal of signals) markAsked(signal.probeReaders)
3864
+ }
3865
+ }
3866
+
3867
+ /**
3868
+ * Whether any value in the selection is busy; a reader subscribes to the selection.
3869
+ *
3870
+ * `null` is the bare selection — every filed load in reach — and so for the three below.
3871
+ */
3872
+ export function busyOver(tags: string[] | null): boolean {
3873
+ trackSignal(tags)
3874
+ for (const cell of inReach(tags)) if (busyNow(cell)) return true
3875
+ return false
3876
+ }
3877
+
3878
+ /** Whether every value in the selection is ready; a reader subscribes to the selection. */
3879
+ export function readyOver(tags: string[] | null): boolean {
3880
+ trackSignal(tags)
3881
+ for (const cell of inReach(tags)) if (!readyNow(cell)) return false
3882
+ return true
3883
+ }
3884
+
3885
+ /**
3886
+ * Invalidates every value in the selection, and what each adopts.
3887
+ *
3888
+ * THE BARE SWEEP VISITS EACH VALUE ALONE: whatever an adoption reaches that has a producer is filed
3889
+ * itself, so walking the chain as well would visit it twice.
3890
+ */
3891
+ export function invalidateOver(tags: string[] | null): void {
3892
+ for (const cell of inReach(tags)) invalidateIn(cell, tags)
3893
+ }
3894
+
3895
+ function invalidateIn(cell: Cell, tags: string[] | null): void {
3896
+ // 13.17 — A WRITE IN FLIGHT IS LEFT TO LAND: marked, its caller's await pulls the reload, and a
3897
+ // mutation's reload is the write sent again.
3898
+ if (cell.mutation && cell.loading) return
3899
+ if (tags === null) invalidateOne(cell)
3900
+ else eachAdopted(cell, invalidateOne)
3901
+ }
3902
+
3903
+ /**
3904
+ * Refreshes the values in the selection, or marks the ones nothing reads.
3905
+ *
3906
+ * 13.7: RELOADED WHERE SOMETHING READS IT, MARKED WHERE NOTHING DOES. A mark is the recompute a
3907
+ * write would have owed it — `DIRTY` and not directly servable — so the next read pulls the reload
3908
+ * and until then nothing is requested. A stream is refreshed rather than marked: a pull runs a
3909
+ * BODY, and a stream's body is a generator that only `startStream` knows how to run.
3910
+ */
3911
+ export function refreshOver(tags: string[] | null): void {
3912
+ for (const cell of inReach(tags)) {
3913
+ // 13.16 — a mutation's reload is its write sent again, so a sweep marks it instead.
3914
+ if (cell.mutation) invalidateIn(cell, tags)
3915
+ else if (
3916
+ readByAny(cell.readers) ||
3917
+ readByAny(cell.probeReaders) ||
3918
+ cell.stream !== null
3919
+ ) {
3920
+ if (tags === null) refreshOne(cell)
3921
+ else eachAdopted(cell, refreshOne)
3922
+ } else if (cell.body !== null) {
3923
+ cell.state = DIRTY
3924
+ cell.direct = false
3925
+ }
3926
+ }
3927
+ }
3928
+
3929
+ /**
3930
+ * Whether any of `readers` is something reading the value rather than a keyed entry's lifetime.
3931
+ *
3932
+ * THE LIFETIME IS THE ONE MIRROR WITH NO ADOPTER (`Subscriber.isMirror`): it subscribes to an entry
3933
+ * of a keyed value declaring `ttl` to hear its productions (11.45), and counted here it had 13.7
3934
+ * reload every such entry nothing reads.
3935
+ */
3936
+ function readByAny(readers: Subscriber[]): boolean {
3937
+ for (let index = 0; index < readers.length; index += 1) {
3938
+ const reader = readers[index] as Subscriber
3939
+ if (!reader.isMirror || reader.adopter !== null) return true
3940
+ }
3941
+ return false
3942
+ }
3943
+
3944
+ const MEMBERS = {
3945
+ peek(this: Callable): unknown {
3946
+ const cell = this[CELL]
3947
+ // PULLS, like a read. Under push-pull a write leaves every derived value it
3948
+ // reached unrun, so a `peek` that only read the field would answer with the
3949
+ // value the last read left behind — 2.2 moved the ABSENCE here, not staleness.
3950
+ bringCurrent(cell)
3951
+ // A `peek` IS A READ by the rulebook's own term, so 6.5 and 6.6 reach it
3952
+ // the same way. What it does not join is the FLOW (2.10) — an expiry is not a
3953
+ // subscription, and a `peek` that went on serving a production `s()` had already
3954
+ // dropped would be two answers to what is held.
3955
+ if (cell.expiry !== null) expire(cell)
3956
+ if (!cell.servable) return undefined
3957
+ return heldValue(cell)
3958
+ },
3959
+ busy(this: Callable): boolean {
3960
+ return isBusy(this[CELL])
3961
+ },
3962
+ ready(this: Callable): boolean {
3963
+ return isReady(this[CELL])
3964
+ },
3965
+ error(this: Callable): unknown {
3966
+ const cell = this[CELL]
3967
+ // 3.3 ON THE THIRD PROBE. `error` is a probe by the rulebook's own term, so a body
3968
+ // reading it subscribes the same way `busy` and `ready` do — without this edge
3969
+ // `{#if s.error()}` reads `undefined` once and nothing wakes it when a load fails,
3970
+ // because a refusal marks the VALUE readers and this body never read the value.
3971
+ probe(cell)
3972
+ return failureOf(cell)
3973
+ },
3974
+ /**
3975
+ * The shared `isFailedNamed`, since this member reads no cell.
3976
+ *
3977
+ * THE ONE MEMBER THAT READS NO CELL, so it is the shared function itself — `Rpc.isError` is the
3978
+ * same one. Its first parameter is the error, as the member's is.
3979
+ */
3980
+ isError: isFailedNamed,
3981
+ set(this: Callable, value: unknown): unknown {
3982
+ const cell = this[CELL]
3983
+ cell.generation += 1
3984
+ // The settled, untransformed write is the overwhelming common shape, and the
3985
+ // general path is two call frames and a thenable probe behind it. Inlined here
3986
+ // rather than behind `isThenable` so a primitive write tests two types.
3987
+ // The same pair as the recompute arm above, and for the same reason: a `set` that
3988
+ // skipped `accept` skipped 4.3 with it.
3989
+ if (
3990
+ cell.bareWrite &&
3991
+ (value === null ||
3992
+ (typeof value !== 'object' && typeof value !== 'function') ||
3993
+ typeof (value as PromiseLike<unknown>).then !== 'function')
3994
+ ) {
3995
+ produce(cell, value)
3996
+ return undefined
3997
+ }
3998
+ return setThroughGates(cell, value)
3999
+ },
4000
+ patch(this: Callable, mutate: (value: unknown) => void): void {
4001
+ patchCell(this[CELL], mutate)
4002
+ },
4003
+ refresh(this: Callable): void {
4004
+ eachAdopted(this[CELL], refreshOne)
4005
+ },
4006
+ invalidate(this: Callable): void {
4007
+ eachAdopted(this[CELL], invalidateOne)
4008
+ },
4009
+ watch(
4010
+ this: Callable,
4011
+ // biome-ignore lint/suspicious/noConfusingVoidType: `void` is an EFFECT'S RETURN POSITION and is load-bearing. `undefined` there refuses the ordinary effect — a block body that returns nothing infers `void`, which is not assignable to `undefined` — so the rule's own fix would reject every caller that does not return a disposer.
4012
+ effect: (value: unknown) => void | (() => void),
4013
+ ): () => void {
4014
+ return watchCell(this[CELL], effect)
4015
+ },
4016
+ [Symbol.asyncIterator](this: Callable): AsyncIterator<unknown> {
4017
+ const cell = this[CELL]
4018
+ // 2.5: "the production in flight, from its start". Starting one ordinal back is
4019
+ // what includes it rather than skipping to whatever comes next — and clamped at
4020
+ // zero, where a value nothing has produced into must WAIT rather than hand over
4021
+ // the `undefined` it is holding.
4022
+ // A STREAM'S PRODUCTION IN FLIGHT IS THE STREAM, so its start is the run's first
4023
+ // chunk rather than the latest one.
4024
+ const from =
4025
+ cell.stream !== null
4026
+ ? cell.ringBase
4027
+ : cell.ordinal > 0
4028
+ ? cell.ordinal - 1
4029
+ : 0
4030
+ return new Cursor(cell, from)
4031
+ },
4032
+ // biome-ignore lint/suspicious/noThenProperty: RULEBOOK 1.4 — a `Reactive` MUST be thenable, which is what this rule warns about. Banning it buys a discrimination rather than a semantics, and 16.4's in-process `Rpc` arm is what that discrimination would have cost. 1.6 is the guard that makes thenability safe — the brand is read before `then`.
4033
+ then(
4034
+ this: Callable,
4035
+ onSettled?: (value: unknown) => unknown,
4036
+ onFailed?: (error: unknown) => unknown,
4037
+ ): Promise<unknown> {
4038
+ return settled(this[CELL]).then(onSettled, onFailed)
4039
+ },
4040
+ catch(
4041
+ this: Callable,
4042
+ onFailed: (error: unknown) => unknown,
4043
+ ): Promise<unknown> {
4044
+ return settled(this[CELL]).catch(onFailed)
4045
+ },
4046
+ finally(this: Callable, onSettled: () => void): Promise<unknown> {
4047
+ return settled(this[CELL]).finally(onSettled)
4048
+ },
4049
+ }
4050
+
4051
+ /**
4052
+ * The cell `value` serves from, through every adoption.
4053
+ *
4054
+ * 11.12: an adopting value serves the adopted value's production, and an adoption of an adoption
4055
+ * goes on down — so a follow's version (18.7) and its feed name the cell that actually produced.
4056
+ */
4057
+ export function servedCellOf(value: unknown): Retained {
4058
+ return adoptedCellOf(value)
4059
+ }
4060
+
4061
+ /**
4062
+ * When the production `value` serves stops being servable, as a wall-clock time.
4063
+ *
4064
+ * 21.8 — WHEN THE PRODUCTION A VALUE IS SERVING STOPS BEING SERVABLE, as a wall-clock time: its
4065
+ * own `ttl` from when it was minted (6.5), or its entry's from when the entry last produced
4066
+ * (11.45), through whatever it adopts. Infinity where neither bounds it.
4067
+ */
4068
+ export function deadlineOf(value: unknown): number {
4069
+ const cell = adoptedCellOf(value)
4070
+ if (cell.expiry !== null) return cell.expiry.at + cell.expiry.ms
4071
+ const entry = ENTRY_LIVES.get(cell)
4072
+ return entry === undefined ? Number.POSITIVE_INFINITY : entry.at + entry.ms
4073
+ }
4074
+
4075
+ /**
4076
+ * The generation of the load `value` has in flight, or `undefined`.
4077
+ *
4078
+ * 16.48 — WHICH LOAD A VALUE HAS IN FLIGHT, as the generation that started it, or `undefined` where
4079
+ * none is. Read off the cell rather than through `busy`, which is a probe and would subscribe the
4080
+ * caller that asked (3.3).
4081
+ */
4082
+ export function loadOf(value: unknown): number | undefined {
4083
+ const cell = (value as Callable)[CELL]
4084
+ return cell.loading ? cell.generation : undefined
4085
+ }
4086
+
4087
+ /**
4088
+ * The generation `value`'s past stands at, or `undefined` while a load is in flight.
4089
+ *
4090
+ * What 21.15's `Cached` compares across a call, read through adoption as `servedCellOf` is.
4091
+ */
4092
+ export function heldGenerationOf(value: unknown): number | undefined {
4093
+ const cell = adoptedCellOf(value)
4094
+ return cell.loading ? undefined : cell.generation
4095
+ }
4096
+
4097
+ /**
4098
+ * Whether `value` stands on a failure the next reach runs again rather than serves.
4099
+ *
4100
+ * 15.19, 15.20 — A REFUSAL BELOW 500 IS AN ANSWER, held as a production is: the caller asked for
4101
+ * something that is not there, and asking again changes nothing. One at 500 or above, and a throw,
4102
+ * is the server's own trouble, and holding it for a `ttl` replays an outage after it has passed.
4103
+ */
4104
+ export function failedTransiently(value: unknown): boolean {
4105
+ const cell = (value as Callable)[CELL]
4106
+ const failure = cell.failure
4107
+ if (cell.loading || failure === undefined) return false
4108
+ return !isFailed(failure) || failure.status >= 500
4109
+ }
4110
+
4111
+ /**
4112
+ * Ends `value`'s load in flight, refusing it with `failure`.
4113
+ *
4114
+ * 16.49 — THE LOAD IN FLIGHT, ENDED WHERE IT STANDS. The generation moves so a settle arriving after
4115
+ * is the stale one `absorb` already drops, a stream stops reaching the value, and the value refuses
4116
+ * with `failure` — which leaves what it held being served (2.4), a stream's chunks so far included.
4117
+ */
4118
+ export function abandonLoad(value: unknown, failure: unknown): void {
4119
+ const cell = (value as Callable)[CELL]
4120
+ if (!cell.loading) return
4121
+ cell.generation += 1
4122
+ if (cell.stream !== null) stopStream(cell.stream)
4123
+ refused(cell, failure)
4124
+ }
4125
+
4126
+ /**
4127
+ * `value` settled (1.4), or `STREAMING` once it turns out to stream (9.6) — whichever comes first.
4128
+ *
4129
+ * A body whose promise resolves to a generator is not a stream until it does, so a reader deciding
4130
+ * between framing chunks and answering one value has to wait for the first of the two — and is
4131
+ * answered which it was, rather than asking `isStreaming` after and reading a later turn's state.
4132
+ */
4133
+ export function streamingOrSettled(value: unknown): Promise<unknown> {
4134
+ return settled((value as Callable)[CELL], true)
4135
+ }
4136
+
4137
+ /**
4138
+ * Whether `value` is a streaming producer's `Reactive`.
4139
+ *
4140
+ * A streaming producer's own `Reactive` — a body declared as an async generator, or one whose run
4141
+ * handed one back (9.6).
4142
+ */
4143
+ export function isStreaming(value: unknown): boolean {
4144
+ if (!isReactive(value)) return false
4145
+ const stream = (value as Partial<Callable>)[CELL]?.stream
4146
+ return stream !== null && stream !== undefined
4147
+ }
4148
+
4149
+ /**
4150
+ * The chunks a streaming value has told its readers of, from index `from` on.
4151
+ *
4152
+ * 16.32 — THE CHUNKS A STREAMING VALUE HAS TOLD ITS READERS OF PAST `from`, for a writer sending each
4153
+ * once. Ungated they are read out of the accumulation in place, to `visible` rather than its length
4154
+ * (5.18): a read materialises a copy of the whole of it (9.1), which for a writer woken per chunk is
4155
+ * n²/2 elements copied to send n. A schema or a transform has to see the whole accumulation (9.8),
4156
+ * so a gated value answers from what a read would.
4157
+ */
4158
+ export function* chunksFrom(value: unknown, from: number): Generator<unknown> {
4159
+ const cell = (value as Callable)[CELL]
4160
+ if (cell.schema === null && cell.transform === null) {
4161
+ const stream = cell.stream as Stream
4162
+ for (let index = from; index < stream.visible; index += 1)
4163
+ yield stream.chunks[index]
4164
+ return
4165
+ }
4166
+ const held = MEMBERS.peek.call(value as Callable)
4167
+ if (Array.isArray(held))
4168
+ for (let index = from; index < held.length; index += 1)
4169
+ yield held[index]
4170
+ }
4171
+
4172
+ function adoptedCellOf(value: unknown): Cell {
4173
+ let cell = (value as Callable)[CELL]
4174
+ // A stream's own `adoption` is a write it follows (9.11), and its past is its own.
4175
+ while (cell.adoption !== null && cell.stream?.source !== null)
4176
+ cell = cell.adoption.source
4177
+ return cell
4178
+ }
4179
+
4180
+ /**
4181
+ * The keys of every `Reactive` member.
4182
+ *
4183
+ * What a value filed outside every scope forwards (`scoped.ts`): read off the record, so a member
4184
+ * added here is forwarded without a second list to keep in step.
4185
+ */
4186
+ export const MEMBER_KEYS: readonly PropertyKey[] = Reflect.ownKeys(MEMBERS)
4187
+
4188
+ /**
4189
+ * Builds a `Reactive` prototype: every member, the overrides, and the brand.
4190
+ *
4191
+ * ONE PROTOTYPE, NOT A COPY OF EVERY MEMBER PER VALUE. `Object.assign(self, MEMBERS)` was 437
4192
+ * of the 501 ns a value cost to construct under bun's JSC and 855 of 985 under V8 —
4193
+ * 87% of the whole, on a path a table walks once per cell per row. The members are the
4194
+ * same objects either way; what changes is whether each instance carries its own slot
4195
+ * for them.
4196
+ *
4197
+ * Under `Function.prototype` so the value stays CALLABLE and `instanceof Function`
4198
+ * holds: callability is an internal slot, not something the prototype chain grants, but
4199
+ * `.call`, `.bind` and the rest are reached through it.
4200
+ *
4201
+ * THE BRAND MOVES HERE TOO, and 1.6's guard is unaffected: `isReactive` reads the
4202
+ * symbol, and an inherited read answers the same. The `defineProperty` it used to take
4203
+ * was another 24 ns per value for a non-enumerability nothing reads.
4204
+ *
4205
+ * IT IS NOT ONLY CONSTRUCTION. A function carrying 43 own properties is a big enough
4206
+ * object that V8 stops tracking it with a map, and every access to every field pays for
4207
+ * that — so moving the members off the instance made the V8 numbers 1.7x on a read,
4208
+ * 2.3x on `ready` and 3.7x on a write with one watcher (44.3 ns -> 12.1 ns), none of which
4209
+ * was the change's motive. Bun's JSC and WebKit are flat to slightly better.
4210
+ *
4211
+ * A SYNTHETIC PROBE SAID THE OPPOSITE and was wrong, which is the note worth keeping: a
4212
+ * stand-in with 14 no-op members read 2.33 ns -> 2.88 ns on the same path, so the trade
4213
+ * looked real until the same measurement was taken on this file. The stand-in's members
4214
+ * were small enough to keep the instance out of the slow mode the real ones put it in.
4215
+ *
4216
+ * THE BRAND IS PUT ON HERE RATHER THAN AT EACH PROTOTYPE, `scoped.ts`'s forwarder included. Every
4217
+ * prototype is the same three lines with a different override record, and the one of them that
4218
+ * mattered was the `defineProperty`: a prototype added without it is a value `isReactive` answers FALSE
4219
+ * for, which every guard in the design reads first (1.6) — so the slot would hand a `Reactive`
4220
+ * to `String()` and the template would render `[object Object]`, with nothing throwing.
4221
+ */
4222
+ export function brandedPrototype(
4223
+ overrides?: Record<PropertyKey, unknown>,
4224
+ ): Record<PropertyKey, unknown> {
4225
+ const prototype = Object.assign(
4226
+ Object.create(Function.prototype) as Record<PropertyKey, unknown>,
4227
+ MEMBERS,
4228
+ overrides,
4229
+ )
4230
+ Object.defineProperty(prototype, REACTIVE_BRAND, { value: true })
4231
+ return prototype
4232
+ }
4233
+
4234
+ const MEMBER_PROTOTYPE = brandedPrototype()
4235
+
4236
+ /**
4237
+ * The member prototype of a streaming value, whose writes stand over the stream.
4238
+ *
4239
+ * THE SAME MEMBERS WITH A STREAM'S WRITES — see `acceptIntoStream` for why they are not a branch.
4240
+ * Chosen once, when a value is built over a stream body, and kept for its life — a stream following
4241
+ * a `Reactive` it was set to (11.61) stays on it. A value ADOPTING a stream moves to
4242
+ * `ADOPTING_PROTOTYPE` instead, like any adoption.
4243
+ */
4244
+ const STREAM_PROTOTYPE = brandedPrototype({
4245
+ set(this: Callable, value: unknown): unknown {
4246
+ const cell = this[CELL]
4247
+ // 11.61: a `Reactive` written is adopted, and on a stream that is a write following it.
4248
+ if (isReactive(value)) {
4249
+ // 11.66 — a cycle throws, as `setThroughGates` does.
4250
+ const cycle = follow(
4251
+ cell,
4252
+ cell.stream as Stream,
4253
+ (value as unknown as Callable)[CELL],
4254
+ )
4255
+ if (cycle !== undefined) throw cycle
4256
+ return undefined
4257
+ }
4258
+ return writeStream(cell, value)
4259
+ },
4260
+ })
4261
+
4262
+ /**
4263
+ * The member prototype of an adopting value, whose writes reach what it adopts.
4264
+ *
4265
+ * THE SAME MEMBERS WITH AN ADOPTING VALUE'S WRITES, which reach what it adopts (11.59) — through that
4266
+ * value's own members, so a stream's writes stay a stream's and an adoption of an adoption goes on
4267
+ * down — an adopting source is on this prototype for exactly as long as `adoption` is set. A
4268
+ * `Reactive` given to `set` is adopted HERE instead (11.61), or a value re-pointed at a new source
4269
+ * would hand that source to the one it is leaving.
4270
+ */
4271
+ const ADOPTING_PROTOTYPE = brandedPrototype({
4272
+ set(this: Callable, value: unknown): unknown {
4273
+ const adoption = this[CELL].adoption
4274
+ if (adoption === null || isReactive(value))
4275
+ return MEMBERS.set.call(this, value)
4276
+ return (adoption.source.callable as Reactive<unknown>).set(value)
4277
+ },
4278
+ patch(this: Callable, mutate: (value: unknown) => void): void {
4279
+ const adoption = this[CELL].adoption
4280
+ if (adoption === null) patchCell(this[CELL], mutate)
4281
+ else (adoption.source.callable as Reactive<unknown>).patch(mutate)
4282
+ },
4283
+ })
4284
+
4285
+ /**
4286
+ * The member prototype of a `simple` value, with the common `set` spelled out.
4287
+ *
4288
+ * THE SAME MEMBERS WITH THE COMMON WRITE SPELLED OUT, and a prototype rather than a branch
4289
+ * for the reason `acceptIntoStream` already gives: a test in the shared `set` that a value
4290
+ * can never take still costs that value. Measured — `identity: structural`, which fails such
4291
+ * a test on its first load and goes on to the same `produce` it always did, went from 51 ns
4292
+ * to 57 with the test in `set`, and to 57 again with the short arm moved behind its own
4293
+ * frame instead, so it was never the size of `set`. The seat takes that value back to the
4294
+ * baseline path exactly, because it IS the baseline path.
4295
+ *
4296
+ * ON A `simple` VALUE THAT IS ALREADY SERVING, `produce` -> `serve` -> `cascade` reduces to
4297
+ * what is below: the cap, the expiry and the store are absent by `simple`; `moved`
4298
+ * is false by the three state tests, so no probe moves and nothing settles; no reload is
4299
+ * owed, so 7.9 has nothing to settle; and every status field `serve` writes is already at the
4300
+ * value it writes. The state tests are the `moved` computation and `produce`'s 7.9 test, read
4301
+ * here to prove the rest is dead rather than to pick a branch, and anything they refuse falls
4302
+ * through to `MEMBERS.set`, which is unchanged.
4303
+ */
4304
+ const SIMPLE_PROTOTYPE = brandedPrototype({
4305
+ set(this: Callable, value: unknown): unknown {
4306
+ const cell = this[CELL]
4307
+ if (
4308
+ cell.servable &&
4309
+ !cell.loading &&
4310
+ cell.failure === undefined &&
4311
+ cell.owes !== OWES_RELOAD &&
4312
+ (value === null ||
4313
+ (typeof value !== 'object' && typeof value !== 'function') ||
4314
+ typeof (value as PromiseLike<unknown>).then !== 'function')
4315
+ ) {
4316
+ // INSIDE THE ARM, so the fallback below bumps it once rather than twice.
4317
+ // A generation is only ever compared against a snapshot a load took, so
4318
+ // two bumps ahead of the snapshot discard exactly what one does — but the
4319
+ // field is the sort of thing a later reader comes to reason about, and a
4320
+ // write that counts as two is a thing to have to un-learn.
4321
+ cell.generation += 1
4322
+ // 5.2, and `simple` is what makes `Object.is` the whole gate.
4323
+ if (Object.is(value, cell.value)) {
4324
+ // The collapse arm's one lasting effect: `produce` restores `direct`
4325
+ // here, because a write can land on a value a mark walk has reached.
4326
+ cell.direct = cell.state === CLEAN
4327
+ return undefined
4328
+ }
4329
+ cell.value = value
4330
+ // 6.10: an `undefined` is served and moves no ordinal.
4331
+ if (value !== undefined) cell.ordinal += 1
4332
+ // `setDirect`, with `plain` known true by `simple`.
4333
+ cell.direct = cell.state === CLEAN
4334
+ if (cell.readers.length !== 0) markReaders(cell, DIRTY)
4335
+ // `cascade`'s tail. A write made from inside an effect appends to the drain
4336
+ // already walking rather than opening a second one.
4337
+ if (!draining && pendingCount !== 0) schedule()
4338
+ return undefined
4339
+ }
4340
+ return MEMBERS.set.call(this, value)
4341
+ },
4342
+ })
4343
+
4344
+ /**
4345
+ * Marks `cell`'s owner as stopped, and releases it where nothing reads it.
4346
+ *
4347
+ * 12.14 — what a component's setup or a request built a derived value in has ended. A value
4348
+ * still read from outside it — handed to something that outlives it — stays wired until that last
4349
+ * reader leaves (`RELEASING`), so nothing that reads it is left with a stale value.
4350
+ */
4351
+ function orphan(cell: Cell): void {
4352
+ cell.orphaned = true
4353
+ if (cell.readers.length === 0 && cell.probeReaders.length === 0)
4354
+ releaseOrphan(cell)
4355
+ }
4356
+
4357
+ /**
4358
+ * Lets go of everything an orphaned value reads, and leaves it owing a run.
4359
+ *
4360
+ * Left subscribed, a value a dropped row built stayed on its sources' reader lists for the life of
4361
+ * the page, and an adopting one's mirror ran on every write to what it adopted. Released, it holds
4362
+ * what it last served; a read that reaches it later — it escaped its owner — runs the body again
4363
+ * and subscribes afresh, so it is never stale, and from then on it is nobody's to release. A
4364
+ * stream is stopped rather than owed: it is never recomputed (14.13), only started.
4365
+ */
4366
+ function releaseOrphan(cell: Cell): void {
4367
+ cell.orphaned = false
4368
+ const stream = cell.stream
4369
+ if (stream !== null && stream.source === null) stopStream(stream)
4370
+ dropAdoption(cell)
4371
+ detach(cell as unknown as Subscriber)
4372
+ cell.aborted = false
4373
+ if (cell.body !== null && stream === null) {
4374
+ cell.state = DIRTY
4375
+ cell.direct = false
4376
+ }
4377
+ }
4378
+
4379
+ RELEASING.unread = (source: Tracked): void => releaseOrphan(source as Cell)
4380
+
4381
+ /** Builds a `Reactive` over a new `Cell` and starts the work it is for (1.7). */
4382
+ export function createReactive<
4383
+ Stored,
4384
+ Accepted,
4385
+ Failures extends Failed<string, unknown>,
4386
+ Produced = Stored,
4387
+ >(
4388
+ label: string,
4389
+ body: ((args: unknown) => unknown) | null,
4390
+ args: unknown,
4391
+ initial: unknown,
4392
+ options: ReactiveOptions<Accepted, Stored, Failures> | undefined,
4393
+ // 5.19: a keyed value's window decides when this entry's producer starts, not the reach.
4394
+ deferred = false,
4395
+ // A KEYED ENTRY IS ITS CACHE'S, held for whoever reaches it next and not the setup or the
4396
+ // request that reached it first (12.4, 12.5) — so it is never orphaned by one. Only the entry:
4397
+ // what its body opens is owned as any body's is, or a rung's `watch` outlives its request.
4398
+ cached = false,
4399
+ ): Reactive<Stored, Accepted, Failures, Produced> {
4400
+ // 11.41 IS A COMPILE ERROR THE TYPES CANNOT RAISE: a body declaring no parameter is still
4401
+ // assignable to the keyed overload's `(args: Args) => Computed`, so the checker falls through
4402
+ // to it and accepts the call. Like 5.14 it lands at construction instead, the earliest moment
4403
+ // there is — and a keyed value strips `args` before building an entry, so any that arrives
4404
+ // here was spelled on a form that has no args to gate.
4405
+ if ((options as { args?: unknown } | undefined)?.args !== undefined)
4406
+ throw new Error(
4407
+ `${label} declares args with no parameter to gate. args belongs to a keyed reactive, whose body declares one.`,
4408
+ )
4409
+ // 9.6 AT CONSTRUCTION for a declared stream; a body handing one back is promoted by its run.
4410
+ const streaming = body !== null && isStreamBody(body)
4411
+ const cell = new Cell(
4412
+ label,
4413
+ body,
4414
+ args,
4415
+ options as ReactiveOptions<unknown, unknown, never> | undefined,
4416
+ streaming,
4417
+ )
4418
+ // THE READ IS THE CALLABLE'S OWN BODY, not a call it makes. It stood as
4419
+ // `return read(self)` and that was a second frame on the hottest path in the design —
4420
+ // a template pays it per slot per row, and a recompute pays it once per source it
4421
+ // reads plus once for itself.
4422
+ //
4423
+ // IT CAPTURES `cell` AND NOTHING ELSE. Every other local here is dead by the time it
4424
+ // returns, so the scope it keeps alive is the one slot the read needs.
4425
+ const self = function readValue(): unknown {
4426
+ // TRACKING, WITH ITS COMMON ARM SPELLED OUT. A body reads the same values in the
4427
+ // same order on almost every run, so the shape that matters is "the source at the
4428
+ // cursor is the one we already had" — a pointer compare and an increment, with no
4429
+ // call and no set operation. `track` is the divergence.
4430
+ const reader = TRACKING.reader
4431
+ if (reader !== null) {
4432
+ const at = reader.cursor
4433
+ if (reader.sources[at] === cell) reader.cursor = at + 1
4434
+ else track(cell, reader)
4435
+ }
4436
+ // ONE LOAD AND ONE BRANCH FOR THE WHOLE COMMON PATH. `direct` is the pull and
4437
+ // the refusal answered at once — see its declaration. It stood as
4438
+ // three tests and stripping them to one measured 2.39 ns -> 1.86 ns on a read and
4439
+ // 4.03 ns -> 3.07 ns over a thousand values, which is memory traffic rather than
4440
+ // branches: a read walked four fields where the hand-written arm reads one
4441
+ // captured variable.
4442
+ if (cell.direct) return cell.value
4443
+ return readIndirect(cell)
4444
+ } as unknown as Callable
4445
+ // BEFORE THE FIELD, not after: an engine keys its inline caches on the shape a
4446
+ // property was added to, and re-pointing the prototype afterwards invalidates the
4447
+ // transition the store just built.
4448
+ Object.setPrototypeOf(
4449
+ self,
4450
+ streaming
4451
+ ? STREAM_PROTOTYPE
4452
+ : cell.simple
4453
+ ? SIMPLE_PROTOTYPE
4454
+ : MEMBER_PROTOTYPE,
4455
+ )
4456
+ self[CELL] = cell
4457
+ cell.callable = self as unknown as Reactive<unknown>
4458
+ if (cell.tags !== null) tagCell(cell)
4459
+ if (cell.store !== null) fileProducer(cell)
4460
+ // 12.14 — A DERIVED VALUE IS ITS OWNER'S, as a watch is: built in a setup or a request, it
4461
+ // lets go of what it reads once that ends and nothing else reads it. A plain value reads
4462
+ // nothing, so it has nothing to let go of.
4463
+ if (body !== null && !cached && owning()) owned(() => orphan(cell))
4464
+
4465
+ // 1.7: reaching an instance starts the work it is for. For the value form that is
4466
+ // the initial write; for a body it is the first run, which 11.4 has happening once
4467
+ // per key rather than once per read.
4468
+ //
4469
+ // AN ABSENT OPENING VALUE MINTS NOTHING: a value nobody has written reads as not landed
4470
+ // (2.2, 4.14) rather than serving an `undefined` its own type says is a `Stored`.
4471
+ // 8.3 AND 8.14: a store answers first, where the value is constructed, and whatever it misses
4472
+ // falls back to what the value would have done without one.
4473
+ if (cell.store !== null) restoreFirst(cell, cell.store, initial)
4474
+ else if (body === null) {
4475
+ if (initial === undefined) landOpening(cell)
4476
+ else if (initial !== NO_INITIAL) open(cell, initial)
4477
+ } else if (deferred) cell.loading = true
4478
+ else startProducer(cell)
4479
+ return self as unknown as Reactive<Stored, Accepted, Failures, Produced>
4480
+ }