@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.
- package/CHANGELOG.md +3 -1781
- package/bin/abide.ts +788 -204
- package/package.json +30 -152
- package/scaffold/src/server/app.ts +6 -0
- package/scaffold/src/shared/.gitkeep +0 -0
- package/scaffold/src/ui/app.html +8 -0
- package/scaffold/src/ui/pages/page.abide +13 -0
- package/src/compiler/CHARACTER_REFERENCES.ts +2242 -0
- package/src/compiler/CheckerAnswer.ts +62 -0
- package/src/compiler/Cursor.ts +367 -0
- package/src/compiler/Finding.ts +2 -0
- package/src/compiler/Lowering.ts +648 -0
- package/src/compiler/PositionTable.ts +125 -0
- package/src/compiler/REACTIVE_MEMBERS.ts +36 -0
- package/src/compiler/SHARED_NAMES.ts +45 -0
- package/src/compiler/SPECIFIERS.ts +16 -0
- package/src/compiler/ShadowMap.ts +144 -0
- package/src/compiler/TemplateNode.ts +176 -0
- package/src/compiler/TypeSession.ts +1079 -0
- package/src/compiler/VOID_ELEMENTS.ts +22 -0
- package/src/compiler/aliasedSymbol.ts +15 -0
- package/src/compiler/ambientReadsIn.ts +152 -0
- package/src/compiler/argsDefaultsIn.ts +173 -0
- package/src/compiler/argsSchemaOf.ts +230 -0
- package/src/compiler/checkApp.ts +117 -0
- package/src/compiler/checkedShadow.ts +182 -0
- package/src/compiler/classifyRead.ts +577 -0
- package/src/compiler/classifyTemplate.ts +501 -0
- package/src/compiler/compileApp.ts +559 -0
- package/src/compiler/compiledEntry.ts +141 -0
- package/src/compiler/componentGraph.ts +139 -0
- package/src/compiler/declaredExports.ts +645 -0
- package/src/compiler/decodeCharacterReferences.ts +111 -0
- package/src/compiler/emitClient.ts +1343 -0
- package/src/compiler/emitComponent.ts +162 -0
- package/src/compiler/emitSource.ts +91 -0
- package/src/compiler/formatDiagnosis.ts +19 -0
- package/src/compiler/handlersUnder.ts +109 -0
- package/src/compiler/index.ts +15 -0
- package/src/compiler/invocationProps.ts +67 -0
- package/src/compiler/isNamedAlone.ts +9 -0
- package/src/compiler/lineOf.ts +38 -0
- package/src/compiler/parseAbide.ts +1341 -0
- package/src/compiler/projectShadow.ts +643 -0
- package/src/compiler/reactiveOptions.ts +82 -0
- package/src/compiler/reactiveTypes.ts +222 -0
- package/src/compiler/readSources.ts +100 -0
- package/src/compiler/readsIn.ts +1023 -0
- package/src/compiler/renderMarkup.ts +781 -0
- package/src/compiler/scaffold.ts +105 -0
- package/src/compiler/scopeStyles.ts +309 -0
- package/src/compiler/serveLanguage.ts +405 -0
- package/src/compiler/shareScope.ts +51 -0
- package/src/compiler/sharedModuleWrites.ts +88 -0
- package/src/compiler/splitImports.ts +387 -0
- package/src/compiler/templateWarnings.ts +128 -0
- package/src/compiler/tokenize.ts +317 -0
- package/src/compiler/trackingWarnings.ts +279 -0
- package/src/compiler/writeDefaultProject.ts +42 -0
- package/src/server/BRIDGE_VERSION.ts +3 -0
- package/src/server/CLIENT_BUILD.ts +56 -0
- package/src/server/DEFAULT_PORT.ts +6 -0
- package/src/server/DOCUMENT_HEADERS.ts +11 -0
- package/src/server/Inbox.ts +36 -0
- package/src/server/LogPanel.ts +239 -0
- package/src/server/MCP_PROTOCOL_VERSION.ts +3 -0
- package/src/server/SETTLE_MILLISECONDS.ts +7 -0
- package/src/server/VIRTUAL_DIRECTORY.ts +6 -0
- package/src/server/answerFailure.ts +91 -0
- package/src/server/answerRequest.ts +560 -0
- package/src/server/answerRpc.ts +537 -0
- package/src/server/answerSocket.ts +537 -0
- package/src/server/answerValue.ts +375 -0
- package/src/server/appDirectories.ts +9 -0
- package/src/server/appKit.ts +204 -0
- package/src/server/appPlugins.ts +26 -0
- package/src/server/argsFor.ts +40 -0
- package/src/server/assistant.ts +163 -0
- package/src/server/banner.ts +43 -0
- package/src/server/bridgeRelay.ts +249 -0
- package/src/server/buildDirectory.ts +10 -0
- package/src/server/callerOf.ts +60 -0
- package/src/server/claudeApi.ts +224 -0
- package/src/server/claudeCode.ts +187 -0
- package/src/server/clientBuildOptions.ts +49 -0
- package/src/server/coerceArgs.ts +110 -0
- package/src/server/commands.ts +442 -0
- package/src/server/componentImports.ts +56 -0
- package/src/server/componentModules.d.ts +9 -0
- package/src/server/compressAnswer.ts +66 -0
- package/src/server/config.ts +192 -0
- package/src/server/configFields.ts +92 -0
- package/src/server/createApp.ts +428 -0
- package/src/server/crossingOrigin.ts +49 -0
- package/src/server/csp.ts +77 -0
- package/src/server/devWorker.ts +613 -0
- package/src/server/faultPolicy.ts +59 -0
- package/src/server/fenceServer.ts +48 -0
- package/src/server/generatedSurfaces.ts +430 -0
- package/src/server/hooks.ts +190 -0
- package/src/server/index.ts +87 -0
- package/src/server/installServer.ts +47 -0
- package/src/server/launcherOptions.ts +62 -0
- package/src/server/launcherPage.ts +156 -0
- package/src/server/manifestOf.ts +114 -0
- package/src/server/muxUpgrade.ts +72 -0
- package/src/server/namesUnder.ts +15 -0
- package/src/server/nativeMenu.ts +296 -0
- package/src/server/negotiateEncoding.ts +39 -0
- package/src/server/plainAnswer.ts +19 -0
- package/src/server/prefers.ts +25 -0
- package/src/server/principal.ts +261 -0
- package/src/server/qualitiesOf.ts +22 -0
- package/src/server/randomToken.ts +9 -0
- package/src/server/reachable.ts +31 -0
- package/src/server/refuseAddressCollision.ts +30 -0
- package/src/server/remote.ts +242 -0
- package/src/server/render.ts +464 -0
- package/src/server/renderComponent.ts +33 -0
- package/src/server/reportHealth.ts +46 -0
- package/src/server/requestScope.ts +435 -0
- package/src/server/responseHelpers.ts +75 -0
- package/src/server/runCompiled.ts +44 -0
- package/src/server/runDesktop.ts +572 -0
- package/src/server/seedBuffer.ts +293 -0
- package/src/server/serveBuild.ts +198 -0
- package/src/server/serveDev.ts +499 -0
- package/src/server/shell.ts +506 -0
- package/src/server/surfaceOf.ts +47 -0
- package/src/server/testBuild.ts +237 -0
- package/src/server/trace.ts +151 -0
- package/src/server/versionOf.ts +109 -0
- package/src/server/withoutTrailingSlash.ts +4 -0
- package/src/shared/ADDRESSES.ts +69 -0
- package/src/shared/ANCHORS.ts +54 -0
- package/src/shared/Attributes.ts +339 -0
- package/src/shared/BOOLEAN_ATTRIBUTES.ts +41 -0
- package/src/shared/CHILDREN.ts +11 -0
- package/src/shared/CURRENT_ROUTER.ts +25 -0
- package/src/shared/CopyOptions.ts +19 -0
- package/src/shared/DEBUG_META.ts +6 -0
- package/src/shared/EARLY_CALLS.ts +8 -0
- package/src/shared/FAILURE_STATUS_TEXT.ts +48 -0
- package/src/shared/Failed.ts +146 -0
- package/src/shared/GLOBAL_GETS.ts +7 -0
- package/src/shared/Issues.ts +49 -0
- package/src/shared/JsonValue.ts +18 -0
- package/src/shared/LOAD_SIGNAL.ts +10 -0
- package/src/shared/MOUNT_META.ts +6 -0
- package/src/shared/Middleware.ts +34 -0
- package/src/shared/NAVIGATION_HEADER.ts +7 -0
- package/src/shared/PRINCIPAL_HEADER.ts +6 -0
- package/src/shared/RPC_SERVER.ts +67 -0
- package/src/shared/Raw.ts +90 -0
- package/src/shared/Schema.ts +229 -0
- package/src/shared/UNEXPECTED.ts +11 -0
- package/src/shared/URL_ATTRIBUTES.ts +19 -0
- package/src/shared/VERSION_HEADER.ts +6 -0
- package/src/shared/WORK.ts +37 -0
- package/src/shared/anchorMarkup.ts +15 -0
- package/src/shared/answerOf.ts +141 -0
- package/src/shared/applyPatch.ts +173 -0
- package/src/shared/armAnchor.ts +17 -0
- package/src/shared/attributeText.ts +50 -0
- package/src/shared/boundValue.ts +58 -0
- package/src/shared/cookies.ts +271 -0
- package/src/shared/csp.ts +55 -0
- package/src/shared/decodedOrKept.ts +14 -0
- package/src/shared/escapeText.ts +103 -0
- package/src/shared/framing.ts +131 -0
- package/src/shared/headKeyOf.ts +34 -0
- package/src/shared/health.ts +51 -0
- package/src/shared/index.ts +117 -0
- package/src/shared/isEventName.ts +10 -0
- package/src/shared/isRecord.ts +4 -0
- package/src/shared/issuesOf.ts +18 -0
- package/src/shared/jsonSchema.ts +50 -0
- package/src/shared/listOf.ts +20 -0
- package/src/shared/log.ts +284 -0
- package/src/shared/matchRoute.ts +99 -0
- package/src/shared/menuItem.ts +80 -0
- package/src/shared/mount.ts +45 -0
- package/src/shared/muxFrames.ts +35 -0
- package/src/shared/navigate.ts +26 -0
- package/src/shared/note.ts +24 -0
- package/src/shared/numberFromText.ts +10 -0
- package/src/shared/online.ts +19 -0
- package/src/shared/paint.ts +4 -0
- package/src/shared/principal.ts +145 -0
- package/src/shared/principalRotated.ts +47 -0
- package/src/shared/propCell.ts +99 -0
- package/src/shared/props.ts +24 -0
- package/src/shared/putOwn.ts +24 -0
- package/src/shared/queryText.ts +18 -0
- package/src/shared/reactive/CELL.ts +8 -0
- package/src/shared/reactive/Cursor.ts +223 -0
- package/src/shared/reactive/ENTRY_LIVES.ts +7 -0
- package/src/shared/reactive/Expiry.ts +103 -0
- package/src/shared/reactive/FOLLOWED.ts +8 -0
- package/src/shared/reactive/KEYED_BRAND.ts +8 -0
- package/src/shared/reactive/Keyed.ts +423 -0
- package/src/shared/reactive/MUTATION.ts +5 -0
- package/src/shared/reactive/NO_INITIAL.ts +6 -0
- package/src/shared/reactive/NotLanded.ts +21 -0
- package/src/shared/reactive/PATCHES.ts +11 -0
- package/src/shared/reactive/PATCH_SINKS.ts +26 -0
- package/src/shared/reactive/REACTIVE_BRAND.ts +9 -0
- package/src/shared/reactive/RESHAPING.ts +13 -0
- package/src/shared/reactive/Reactive.ts +4480 -0
- package/src/shared/reactive/SELECTION_MEMBERS.ts +12 -0
- package/src/shared/reactive/STREAMING.ts +5 -0
- package/src/shared/reactive/argsContract.ts +97 -0
- package/src/shared/reactive/byOf.ts +18 -0
- package/src/shared/reactive/callLoad.ts +200 -0
- package/src/shared/reactive/canonicalKey.ts +95 -0
- package/src/shared/reactive/chunksOfStream.ts +51 -0
- package/src/shared/reactive/index.ts +542 -0
- package/src/shared/reactive/isReactive.ts +19 -0
- package/src/shared/reactive/isThenable.ts +14 -0
- package/src/shared/reactive/matchesPattern.ts +16 -0
- package/src/shared/reactive/pairReactive.ts +41 -0
- package/src/shared/reactive/parameterDefaults.ts +356 -0
- package/src/shared/reactive/recordWrites.ts +472 -0
- package/src/shared/reactive/scoped.ts +157 -0
- package/src/shared/reactive/scoping.ts +64 -0
- package/src/shared/reactive/share.ts +91 -0
- package/src/shared/reactive/structural.ts +62 -0
- package/src/shared/reactive/tracking.ts +418 -0
- package/src/shared/reactive/watch.ts +310 -0
- package/src/shared/refuse.ts +224 -0
- package/src/shared/route.ts +29 -0
- package/src/shared/routePattern.ts +146 -0
- package/src/shared/rpc.ts +496 -0
- package/src/shared/rpcRequest.ts +73 -0
- package/src/shared/safeUrl.ts +68 -0
- package/src/shared/seededDocument.ts +36 -0
- package/src/shared/setUpLevels.ts +53 -0
- package/src/shared/slotValue.ts +34 -0
- package/src/shared/spread.ts +79 -0
- package/src/shared/takeEarlyCall.ts +86 -0
- package/src/shared/url.ts +140 -0
- package/src/shared/validateJson.ts +578 -0
- package/src/shared/versionInEtag.ts +14 -0
- package/src/shared/writePath.ts +95 -0
- package/src/ui/ArmRegion.ts +185 -0
- package/src/ui/LAYER_NAMES.ts +30 -0
- package/src/ui/List.ts +273 -0
- package/src/ui/Mismatch.ts +32 -0
- package/src/ui/RawRun.ts +99 -0
- package/src/ui/Router.ts +698 -0
- package/src/ui/Scope.ts +115 -0
- package/src/ui/TryRegion.ts +278 -0
- package/src/ui/adoptWalk.ts +126 -0
- package/src/ui/applyHead.ts +146 -0
- package/src/ui/bindElement.ts +44 -0
- package/src/ui/bindProperty.ts +79 -0
- package/src/ui/bindSpread.ts +44 -0
- package/src/ui/escapeless.ts +14 -0
- package/src/ui/index.ts +64 -0
- package/src/ui/leave.ts +35 -0
- package/src/ui/listenForRoutes.ts +92 -0
- package/src/ui/measureLayer.ts +34 -0
- package/src/ui/menuBridge.ts +19 -0
- package/src/ui/moveNode.ts +34 -0
- package/src/ui/parseMarkup.ts +35 -0
- package/src/ui/reconcile.ts +368 -0
- package/src/ui/regions.ts +137 -0
- package/src/ui/reportMenu.ts +57 -0
- package/src/ui/routing.ts +18 -0
- package/src/ui/rowKeyOf.ts +19 -0
- package/src/ui/rows.ts +99 -0
- package/src/ui/setAttribute.ts +37 -0
- package/src/ui/setClass.ts +27 -0
- package/src/ui/setMarkup.ts +20 -0
- package/src/ui/setStyleProperty.ts +30 -0
- package/src/ui/setText.ts +28 -0
- package/src/ui/socketWire.ts +258 -0
- package/src/ui/wire.ts +141 -0
- package/AGENTS.md +0 -446
- package/README.md +0 -249
- package/src/abideLsp.ts +0 -251
- package/src/abideModules.d.ts +0 -8
- package/src/abideResolverPlugin.ts +0 -1101
- package/src/appEntry.ts +0 -161
- package/src/assets/app.html +0 -12
- package/src/build.ts +0 -189
- package/src/buildCli.ts +0 -125
- package/src/buildDisconnected.ts +0 -117
- package/src/bundleApp.ts +0 -146
- package/src/bundleDisconnectedEntry.ts +0 -14
- package/src/checkAbide.ts +0 -145
- package/src/cliEntry.ts +0 -25
- package/src/clientBuildPlugins.ts +0 -33
- package/src/clientEntry.ts +0 -17
- package/src/compile.ts +0 -61
- package/src/controlServerWorker.ts +0 -433
- package/src/devEntry.ts +0 -381
- package/src/discoveryEntry.ts +0 -82
- package/src/initAgent.ts +0 -50
- package/src/lib/bundle/BundleMenu.ts +0 -12
- package/src/lib/bundle/BundleMenuItem.ts +0 -25
- package/src/lib/bundle/BundleWindow.ts +0 -37
- package/src/lib/bundle/WEBVIEW_BUILD_REVISION.ts +0 -9
- package/src/lib/bundle/WEBVIEW_VERSION.ts +0 -7
- package/src/lib/bundle/bindConnectedFlag.ts +0 -29
- package/src/lib/bundle/bindRequestNavigate.ts +0 -34
- package/src/lib/bundle/buildWebviewLib.ts +0 -111
- package/src/lib/bundle/bundled.ts +0 -35
- package/src/lib/bundle/disconnected.abide +0 -265
- package/src/lib/bundle/disconnected.css +0 -9
- package/src/lib/bundle/ensureWebviewLib.ts +0 -20
- package/src/lib/bundle/exitWithParent.ts +0 -30
- package/src/lib/bundle/infoPlist.ts +0 -52
- package/src/lib/bundle/installDownloads.ts +0 -34
- package/src/lib/bundle/installMacMenu.ts +0 -49
- package/src/lib/bundle/listenLocalControlServer.ts +0 -19
- package/src/lib/bundle/native/abideMenu.mm +0 -422
- package/src/lib/bundle/native/webview.h +0 -4557
- package/src/lib/bundle/onMenu.ts +0 -42
- package/src/lib/bundle/openWebview.ts +0 -104
- package/src/lib/bundle/pngToIcns.ts +0 -47
- package/src/lib/bundle/probeAbideServer.ts +0 -57
- package/src/lib/bundle/resolveServerBinary.ts +0 -12
- package/src/lib/bundle/resolveWebviewLib.ts +0 -53
- package/src/lib/bundle/serverBinaryFilename.ts +0 -8
- package/src/lib/bundle/signMacApp.ts +0 -37
- package/src/lib/bundle/spawnEmbeddedServer.ts +0 -73
- package/src/lib/bundle/stableLocalPort.ts +0 -19
- package/src/lib/bundle/waitForServer.ts +0 -28
- package/src/lib/bundle/webviewCachePath.ts +0 -23
- package/src/lib/bundle/webviewLibName.ts +0 -11
- package/src/lib/cli/completeCli.ts +0 -38
- package/src/lib/cli/connectToServer.ts +0 -23
- package/src/lib/cli/createClient.ts +0 -108
- package/src/lib/cli/dispatchCommand.ts +0 -72
- package/src/lib/cli/loadEnvFromBinaryDir.ts +0 -15
- package/src/lib/cli/parseArgvForRpc.ts +0 -131
- package/src/lib/cli/printCommandHelp.ts +0 -43
- package/src/lib/cli/printSessionHelp.ts +0 -28
- package/src/lib/cli/printSessionStatus.ts +0 -21
- package/src/lib/cli/printTopLevelHelp.ts +0 -83
- package/src/lib/cli/printTrimmed.ts +0 -8
- package/src/lib/cli/printValue.ts +0 -10
- package/src/lib/cli/renderCliCompletions.ts +0 -56
- package/src/lib/cli/resolveCliTarget.ts +0 -47
- package/src/lib/cli/runCli.ts +0 -188
- package/src/lib/cli/runSession.ts +0 -107
- package/src/lib/cli/startLocalInstance.ts +0 -14
- package/src/lib/cli/tokenizeArgvFlags.ts +0 -86
- package/src/lib/cli/tokenizeLine.ts +0 -51
- package/src/lib/cli/types/CliManifest.ts +0 -11
- package/src/lib/cli/types/CliManifestEntry.ts +0 -17
- package/src/lib/cli/types/CliTarget.ts +0 -13
- package/src/lib/mcp/annotationsForMethod.ts +0 -29
- package/src/lib/mcp/buildPrompts.ts +0 -25
- package/src/lib/mcp/createMcpResourceServer.ts +0 -113
- package/src/lib/mcp/createMcpServer.ts +0 -56
- package/src/lib/mcp/dispatchMcpRequest.ts +0 -159
- package/src/lib/mcp/mcpResourceServerSlot.ts +0 -13
- package/src/lib/mcp/mcpSurface.ts +0 -57
- package/src/lib/mcp/mcpTools.ts +0 -196
- package/src/lib/mcp/renderPrompt.ts +0 -25
- package/src/lib/mcp/toolResultFromResponse.ts +0 -100
- package/src/lib/mcp/types/JsonRpcRequest.ts +0 -12
- package/src/lib/mcp/types/JsonRpcResponse.ts +0 -20
- package/src/lib/mcp/types/McpResourceContents.ts +0 -10
- package/src/lib/mcp/types/McpResourceDescriptor.ts +0 -6
- package/src/lib/mcp/types/McpResourceServer.ts +0 -12
- package/src/lib/mcp/types/McpServer.ts +0 -9
- package/src/lib/mcp/types/McpServerOptions.ts +0 -16
- package/src/lib/mcp/types/McpSurface.ts +0 -15
- package/src/lib/mcp/types/PromptDescriptor.ts +0 -5
- package/src/lib/mcp/types/PromptMessage.ts +0 -2
- package/src/lib/mcp/types/ToolDescriptor.ts +0 -7
- package/src/lib/mcp/types/ToolResult.ts +0 -2
- package/src/lib/server/AppModule.ts +0 -47
- package/src/lib/server/DELETE.ts +0 -10
- package/src/lib/server/GET.ts +0 -10
- package/src/lib/server/HEAD.ts +0 -10
- package/src/lib/server/PATCH.ts +0 -10
- package/src/lib/server/POST.ts +0 -10
- package/src/lib/server/PUT.ts +0 -10
- package/src/lib/server/agent.ts +0 -86
- package/src/lib/server/appDataDir.ts +0 -16
- package/src/lib/server/cli/buildEnvContent.ts +0 -19
- package/src/lib/server/cli/createTarGz.ts +0 -77
- package/src/lib/server/cli/handleCliDownload.ts +0 -152
- package/src/lib/server/cli/handleCliInstall.ts +0 -37
- package/src/lib/server/cli/installScript.ts +0 -31
- package/src/lib/server/cli/maxSourceMtime.ts +0 -26
- package/src/lib/server/cookies.ts +0 -30
- package/src/lib/server/env.ts +0 -51
- package/src/lib/server/error.ts +0 -110
- package/src/lib/server/json.ts +0 -57
- package/src/lib/server/jsonl.ts +0 -47
- package/src/lib/server/prompts/definePrompt.ts +0 -21
- package/src/lib/server/prompts/promptRegistry.ts +0 -9
- package/src/lib/server/prompts/registerPrompt.ts +0 -6
- package/src/lib/server/prompts/renderPromptTemplate.ts +0 -17
- package/src/lib/server/prompts/types/Prompt.ts +0 -14
- package/src/lib/server/prompts/types/PromptOptions.ts +0 -12
- package/src/lib/server/prompts/types/PromptRegistryEntry.ts +0 -13
- package/src/lib/server/prompts/types/PromptRoutes.ts +0 -10
- package/src/lib/server/redirect.ts +0 -43
- package/src/lib/server/render.ts +0 -70
- package/src/lib/server/request.ts +0 -19
- package/src/lib/server/rpc/defineRpc.ts +0 -271
- package/src/lib/server/rpc/dispatchRpcInProcess.ts +0 -46
- package/src/lib/server/rpc/findRpcByCommandName.ts +0 -18
- package/src/lib/server/rpc/parseArgs.ts +0 -244
- package/src/lib/server/rpc/readBodyWithinLimit.ts +0 -47
- package/src/lib/server/rpc/registerRpc.ts +0 -6
- package/src/lib/server/rpc/resolveRpcJsonSchema.ts +0 -28
- package/src/lib/server/rpc/rpcRegistry.ts +0 -11
- package/src/lib/server/rpc/runWithRpcTimeout.ts +0 -58
- package/src/lib/server/rpc/types/RemoteHandler.ts +0 -31
- package/src/lib/server/rpc/types/RemoteRoutes.ts +0 -13
- package/src/lib/server/rpc/types/RpcHelper.ts +0 -185
- package/src/lib/server/rpc/types/RpcRegistryEntry.ts +0 -50
- package/src/lib/server/rpc/types/TypedError.ts +0 -18
- package/src/lib/server/rpc/types/TypedResponse.ts +0 -18
- package/src/lib/server/rpc/unprocessed.ts +0 -13
- package/src/lib/server/rpc/validationError.ts +0 -17
- package/src/lib/server/runtime/DEFAULT_PORT.ts +0 -6
- package/src/lib/server/runtime/DEV_READY_MESSAGE.ts +0 -6
- package/src/lib/server/runtime/DEV_REBUILD_MESSAGE.ts +0 -4
- package/src/lib/server/runtime/DEV_RELOAD_CLIENT_SCRIPT.ts +0 -92
- package/src/lib/server/runtime/SSR_SWAP_SCRIPT.ts +0 -19
- package/src/lib/server/runtime/STATUS_TEXT.ts +0 -22
- package/src/lib/server/runtime/STREAMED_HTML_HEADER.ts +0 -13
- package/src/lib/server/runtime/acceptsGzip.ts +0 -33
- package/src/lib/server/runtime/amendBroadcaster.ts +0 -53
- package/src/lib/server/runtime/buildCacheSnapshot.ts +0 -63
- package/src/lib/server/runtime/buildHealthPayload.ts +0 -34
- package/src/lib/server/runtime/buildInFlightSnapshot.ts +0 -35
- package/src/lib/server/runtime/buildInspectorSurface.ts +0 -47
- package/src/lib/server/runtime/buildOpenApiSpec.ts +0 -150
- package/src/lib/server/runtime/buildPreloadManifest.ts +0 -153
- package/src/lib/server/runtime/cacheControlForAsset.ts +0 -22
- package/src/lib/server/runtime/cacheStalenessBroadcaster.ts +0 -33
- package/src/lib/server/runtime/containsTraversal.ts +0 -41
- package/src/lib/server/runtime/createAppAssetServer.ts +0 -100
- package/src/lib/server/runtime/createAppRouteResolver.ts +0 -145
- package/src/lib/server/runtime/createAssetHeaderCache.ts +0 -31
- package/src/lib/server/runtime/createPlumbingRouter.ts +0 -212
- package/src/lib/server/runtime/createPublicAssetServer.ts +0 -76
- package/src/lib/server/runtime/createRouteDispatcher.ts +0 -121
- package/src/lib/server/runtime/createServer.ts +0 -605
- package/src/lib/server/runtime/createUiPageRenderer.ts +0 -489
- package/src/lib/server/runtime/crossOriginForbidden.ts +0 -17
- package/src/lib/server/runtime/crossOriginGate.ts +0 -29
- package/src/lib/server/runtime/devClientFingerprint.ts +0 -103
- package/src/lib/server/runtime/devReloadResponse.ts +0 -41
- package/src/lib/server/runtime/disableIdleTimeoutForStream.ts +0 -27
- package/src/lib/server/runtime/envSchemaStore.ts +0 -15
- package/src/lib/server/runtime/finalizeResponse.ts +0 -42
- package/src/lib/server/runtime/findOpenPort.ts +0 -21
- package/src/lib/server/runtime/flushingGzipStream.ts +0 -62
- package/src/lib/server/runtime/getActiveServer.ts +0 -6
- package/src/lib/server/runtime/globToPathSet.ts +0 -29
- package/src/lib/server/runtime/gzipResponse.ts +0 -57
- package/src/lib/server/runtime/inFlightRequests.ts +0 -13
- package/src/lib/server/runtime/inProcessServer.ts +0 -20
- package/src/lib/server/runtime/installAmbientScopeStore.ts +0 -54
- package/src/lib/server/runtime/internalErrorResponse.ts +0 -28
- package/src/lib/server/runtime/isCrossOriginRequest.ts +0 -23
- package/src/lib/server/runtime/listenOnOpenPort.ts +0 -36
- package/src/lib/server/runtime/logExposedSurfaces.ts +0 -156
- package/src/lib/server/runtime/maybeMountInspector.ts +0 -104
- package/src/lib/server/runtime/mimeForExtension.ts +0 -14
- package/src/lib/server/runtime/pageRenderSlot.ts +0 -15
- package/src/lib/server/runtime/pageUrlFromStore.ts +0 -15
- package/src/lib/server/runtime/parseIdleTimeout.ts +0 -10
- package/src/lib/server/runtime/parsePort.ts +0 -11
- package/src/lib/server/runtime/pathStore.ts +0 -15
- package/src/lib/server/runtime/registryManifests.ts +0 -66
- package/src/lib/server/runtime/renderCellBarrierStore.ts +0 -15
- package/src/lib/server/runtime/requestContext.ts +0 -5
- package/src/lib/server/runtime/resolvePageSnapshot.ts +0 -25
- package/src/lib/server/runtime/respondWithEmbeddedAsset.ts +0 -18
- package/src/lib/server/runtime/runWithRequestScope.ts +0 -165
- package/src/lib/server/runtime/serializeCacheSnapshot.ts +0 -31
- package/src/lib/server/runtime/serverSlot.ts +0 -13
- package/src/lib/server/runtime/setActiveServer.ts +0 -6
- package/src/lib/server/runtime/snapshotEntryFromCache.ts +0 -121
- package/src/lib/server/runtime/streamCacheResolutions.ts +0 -44
- package/src/lib/server/runtime/streamFromIterator.ts +0 -124
- package/src/lib/server/runtime/textResponse.ts +0 -23
- package/src/lib/server/runtime/typedErrorResponse.ts +0 -26
- package/src/lib/server/runtime/types/Assets.ts +0 -6
- package/src/lib/server/runtime/types/DevReloadStamp.ts +0 -14
- package/src/lib/server/runtime/types/InspectorCacheEntry.ts +0 -24
- package/src/lib/server/runtime/types/InspectorCacheSnapshot.ts +0 -11
- package/src/lib/server/runtime/types/InspectorContext.ts +0 -34
- package/src/lib/server/runtime/types/InspectorInFlightRequest.ts +0 -20
- package/src/lib/server/runtime/types/InspectorInFlightSnapshot.ts +0 -10
- package/src/lib/server/runtime/types/InspectorPrompt.ts +0 -15
- package/src/lib/server/runtime/types/InspectorRpc.ts +0 -27
- package/src/lib/server/runtime/types/InspectorSocket.ts +0 -17
- package/src/lib/server/runtime/types/InspectorSurface.ts +0 -16
- package/src/lib/server/runtime/types/RequestStore.ts +0 -125
- package/src/lib/server/runtime/warnUnguardedMcp.ts +0 -43
- package/src/lib/server/runtime/withResponseDefaults.ts +0 -29
- package/src/lib/server/server.ts +0 -33
- package/src/lib/server/socket.ts +0 -32
- package/src/lib/server/sockets/amendFamilyEntry.ts +0 -39
- package/src/lib/server/sockets/createSocketDispatcher.ts +0 -397
- package/src/lib/server/sockets/defineSocket.ts +0 -225
- package/src/lib/server/sockets/lookupSocket.ts +0 -6
- package/src/lib/server/sockets/registerSocket.ts +0 -18
- package/src/lib/server/sockets/socketOperations.ts +0 -36
- package/src/lib/server/sockets/socketRegistry.ts +0 -9
- package/src/lib/server/sockets/types/SocketOperation.ts +0 -22
- package/src/lib/server/sockets/types/SocketOptions.ts +0 -26
- package/src/lib/server/sockets/types/SocketRegistryEntry.ts +0 -19
- package/src/lib/server/sockets/types/SocketRoutes.ts +0 -10
- package/src/lib/server/sse.ts +0 -58
- package/src/lib/shared/ABIDE_PACKAGE_NAME.ts +0 -7
- package/src/lib/shared/ABIDE_VERSION.ts +0 -9
- package/src/lib/shared/AMEND_TOPIC_PREFIX.ts +0 -9
- package/src/lib/shared/ASYNC_CELL.ts +0 -5
- package/src/lib/shared/CACHE_CONTROL_VALUES.ts +0 -16
- package/src/lib/shared/CACHE_STALENESS_SOCKET.ts +0 -8
- package/src/lib/shared/CLI_PATH.ts +0 -7
- package/src/lib/shared/DEFER.ts +0 -8
- package/src/lib/shared/DEV_REBUILD_PATH.ts +0 -6
- package/src/lib/shared/DEV_RELOAD_PATH.ts +0 -6
- package/src/lib/shared/HEALTH_PATH.ts +0 -7
- package/src/lib/shared/HTTP_METHODS.ts +0 -6
- package/src/lib/shared/HttpError.ts +0 -30
- package/src/lib/shared/IDENTITY_PATH.ts +0 -6
- package/src/lib/shared/INSPECTOR_PATH.ts +0 -7
- package/src/lib/shared/MCP_PATH.ts +0 -6
- package/src/lib/shared/NAV_HEADER.ts +0 -8
- package/src/lib/shared/OFFLINE_HEADER.ts +0 -8
- package/src/lib/shared/PROXIED_SERVER_SUBDIRS.ts +0 -15
- package/src/lib/shared/REF_JSON_HEADER.ts +0 -9
- package/src/lib/shared/REF_JSON_TAGS.ts +0 -43
- package/src/lib/shared/REMOTE_FUNCTION.ts +0 -8
- package/src/lib/shared/REPLAYABLE_METHODS.ts +0 -12
- package/src/lib/shared/RESERVED_SOCKET_PREFIX.ts +0 -8
- package/src/lib/shared/RPC_ARGS_TYPE.ts +0 -7
- package/src/lib/shared/RPC_SHIM_GLOBALS.ts +0 -9
- package/src/lib/shared/SEEDS.ts +0 -33
- package/src/lib/shared/SOCKETS_PATH.ts +0 -7
- package/src/lib/shared/SOCKET_SEED.ts +0 -12
- package/src/lib/shared/SSR_SCRIPT_ID.ts +0 -11
- package/src/lib/shared/STREAMING_CONTENT_TYPES.ts +0 -12
- package/src/lib/shared/SocketDisconnectedError.ts +0 -13
- package/src/lib/shared/TEXT_PLAIN.ts +0 -7
- package/src/lib/shared/abideImportName.ts +0 -44
- package/src/lib/shared/abideLog.ts +0 -38
- package/src/lib/shared/activeCacheStore.ts +0 -12
- package/src/lib/shared/activePage.ts +0 -12
- package/src/lib/shared/amend.ts +0 -48
- package/src/lib/shared/amendBroadcastSlot.ts +0 -19
- package/src/lib/shared/appDataDir.ts +0 -34
- package/src/lib/shared/appNameSlot.ts +0 -10
- package/src/lib/shared/applyAmendLocally.ts +0 -20
- package/src/lib/shared/applyCacheStalenessLocally.ts +0 -18
- package/src/lib/shared/assertExhaustive.ts +0 -14
- package/src/lib/shared/attachRpcSelectorMethods.ts +0 -44
- package/src/lib/shared/attachSocketSelectorMethods.ts +0 -34
- package/src/lib/shared/augmentModule.ts +0 -18
- package/src/lib/shared/basePath.ts +0 -11
- package/src/lib/shared/basePathFromAppUrl.ts +0 -20
- package/src/lib/shared/baseSlot.ts +0 -9
- package/src/lib/shared/binaryDirEnvPath.ts +0 -12
- package/src/lib/shared/bodyValueForKind.ts +0 -34
- package/src/lib/shared/browserClientFlags.ts +0 -10
- package/src/lib/shared/buildArtifact.ts +0 -20
- package/src/lib/shared/buildRpcProxy.ts +0 -39
- package/src/lib/shared/buildRpcRequest.ts +0 -81
- package/src/lib/shared/buildSocketOverChannel.ts +0 -102
- package/src/lib/shared/bundleGraphFromMetafile.ts +0 -68
- package/src/lib/shared/bundleLayout.ts +0 -36
- package/src/lib/shared/cache.ts +0 -1584
- package/src/lib/shared/cacheEntryFromSnapshot.ts +0 -77
- package/src/lib/shared/cacheManagedSlot.ts +0 -10
- package/src/lib/shared/cacheReaderSocketSlot.ts +0 -11
- package/src/lib/shared/cacheStalenessSlot.ts +0 -21
- package/src/lib/shared/cacheStoreSlot.ts +0 -12
- package/src/lib/shared/cacheStores.ts +0 -10
- package/src/lib/shared/canonicalJson.ts +0 -86
- package/src/lib/shared/carriesBodyArgs.ts +0 -13
- package/src/lib/shared/changeAffectsClient.ts +0 -40
- package/src/lib/shared/clearLastConnection.ts +0 -7
- package/src/lib/shared/commandNameForUrl.ts +0 -17
- package/src/lib/shared/contentBodyKind.ts +0 -27
- package/src/lib/shared/contentTypeOf.ts +0 -6
- package/src/lib/shared/createCacheStore.ts +0 -147
- package/src/lib/shared/createChannelLog.ts +0 -146
- package/src/lib/shared/createLifecycleChannel.ts +0 -62
- package/src/lib/shared/createLivenessWatch.ts +0 -118
- package/src/lib/shared/createPushIterator.ts +0 -132
- package/src/lib/shared/createReachable.ts +0 -78
- package/src/lib/shared/createRemoteFunction.ts +0 -210
- package/src/lib/shared/createResolverSlot.ts +0 -30
- package/src/lib/shared/createRpcServerProgram.ts +0 -1007
- package/src/lib/shared/createSocketSubRegistry.ts +0 -112
- package/src/lib/shared/createSubscriber.ts +0 -55
- package/src/lib/shared/createTraceContext.ts +0 -21
- package/src/lib/shared/dataDirEnvPath.ts +0 -12
- package/src/lib/shared/debugGate.ts +0 -90
- package/src/lib/shared/decodeRefJson.ts +0 -112
- package/src/lib/shared/decodeResponse.ts +0 -54
- package/src/lib/shared/decodeWireBody.ts +0 -35
- package/src/lib/shared/detectRpcMethod.ts +0 -24
- package/src/lib/shared/detectTarget.ts +0 -27
- package/src/lib/shared/docSnapshotsSlot.ts +0 -13
- package/src/lib/shared/done.ts +0 -20
- package/src/lib/shared/emitLogRecord.ts +0 -217
- package/src/lib/shared/encodeRefJson.ts +0 -108
- package/src/lib/shared/encodeSeedValue.ts +0 -24
- package/src/lib/shared/encodeWireBody.ts +0 -18
- package/src/lib/shared/escapeHtml.ts +0 -15
- package/src/lib/shared/escapeRegex.ts +0 -9
- package/src/lib/shared/exeSuffix.ts +0 -9
- package/src/lib/shared/exitOnBuildFailure.ts +0 -18
- package/src/lib/shared/extraForwardHeaders.ts +0 -16
- package/src/lib/shared/fieldErrorsFromIssues.ts +0 -27
- package/src/lib/shared/fileName.ts +0 -9
- package/src/lib/shared/fileStem.ts +0 -11
- package/src/lib/shared/findExportCallSite.ts +0 -233
- package/src/lib/shared/formatTraceparent.ts +0 -6
- package/src/lib/shared/forwardHeaders.ts +0 -44
- package/src/lib/shared/generateDeclarations.ts +0 -72
- package/src/lib/shared/getRemoteMeta.ts +0 -5
- package/src/lib/shared/hasSeedableRequest.ts +0 -25
- package/src/lib/shared/health.ts +0 -179
- package/src/lib/shared/healthReadSlot.ts +0 -11
- package/src/lib/shared/healthSeedSlot.ts +0 -12
- package/src/lib/shared/html.ts +0 -19
- package/src/lib/shared/httpErrorFor.ts +0 -26
- package/src/lib/shared/hydrationWindow.ts +0 -53
- package/src/lib/shared/importNamesToStrip.ts +0 -13
- package/src/lib/shared/invalidate.ts +0 -39
- package/src/lib/shared/invalidateEvent.ts +0 -11
- package/src/lib/shared/invalidateTripwire.ts +0 -40
- package/src/lib/shared/isAbideHealthPayload.ts +0 -11
- package/src/lib/shared/isAsciiWhitespace.ts +0 -5
- package/src/lib/shared/isAsyncCell.ts +0 -11
- package/src/lib/shared/isAsyncIterable.ts +0 -8
- package/src/lib/shared/isCompileTarget.ts +0 -21
- package/src/lib/shared/isDebugEnabled.ts +0 -19
- package/src/lib/shared/isDebugNegated.ts +0 -17
- package/src/lib/shared/isIdentPart.ts +0 -9
- package/src/lib/shared/isIdentStart.ts +0 -8
- package/src/lib/shared/isLayoutFile.ts +0 -12
- package/src/lib/shared/isModuleNotFound.ts +0 -18
- package/src/lib/shared/isReadOnlyMethod.ts +0 -14
- package/src/lib/shared/isReplayableMethod.ts +0 -7
- package/src/lib/shared/isStreamingResponse.ts +0 -12
- package/src/lib/shared/isSubscribable.ts +0 -15
- package/src/lib/shared/isThenable.ts +0 -9
- package/src/lib/shared/jsonSchemaForPromptArguments.ts +0 -29
- package/src/lib/shared/jsonSchemaForSchema.ts +0 -39
- package/src/lib/shared/jsonSchemaForType.ts +0 -245
- package/src/lib/shared/jsonlErrorFrame.ts +0 -24
- package/src/lib/shared/keyForRemoteCall.ts +0 -30
- package/src/lib/shared/keyMatchesPrefix.ts +0 -9
- package/src/lib/shared/keyPrefixForRemote.ts +0 -12
- package/src/lib/shared/lastConnectionPath.ts +0 -7
- package/src/lib/shared/layoutChainForRoute.ts +0 -22
- package/src/lib/shared/lenientDecode.ts +0 -15
- package/src/lib/shared/loadEnvFile.ts +0 -17
- package/src/lib/shared/loadEnvFromDataDir.ts +0 -14
- package/src/lib/shared/loadProjectTsConfig.ts +0 -28
- package/src/lib/shared/log.ts +0 -24
- package/src/lib/shared/logClosingRecord.ts +0 -28
- package/src/lib/shared/logTapSlot.ts +0 -13
- package/src/lib/shared/manifestModule.ts +0 -39
- package/src/lib/shared/markFrameworkSourcesIgnored.ts +0 -47
- package/src/lib/shared/matchRoute.ts +0 -165
- package/src/lib/shared/matcherFromEnvelope.ts +0 -31
- package/src/lib/shared/memoizeByKey.ts +0 -32
- package/src/lib/shared/messageFromError.ts +0 -6
- package/src/lib/shared/normalizePathname.ts +0 -11
- package/src/lib/shared/normalizeTarget.ts +0 -10
- package/src/lib/shared/online.ts +0 -51
- package/src/lib/shared/page.ts +0 -30
- package/src/lib/shared/pageSlot.ts +0 -17
- package/src/lib/shared/pageUrlForFile.ts +0 -14
- package/src/lib/shared/parseBoundedEnvInt.ts +0 -20
- package/src/lib/shared/parseEnv.ts +0 -41
- package/src/lib/shared/parsePromptMarkdown.ts +0 -35
- package/src/lib/shared/parseRouteSegments.ts +0 -31
- package/src/lib/shared/parseTraceparent.ts +0 -26
- package/src/lib/shared/peek.ts +0 -46
- package/src/lib/shared/pending.ts +0 -36
- package/src/lib/shared/pendingAsyncCellsSlot.ts +0 -13
- package/src/lib/shared/prepareRemoteExport.ts +0 -40
- package/src/lib/shared/prepareRpcModule.ts +0 -240
- package/src/lib/shared/prepareSocketModule.ts +0 -46
- package/src/lib/shared/probeRegistries.ts +0 -68
- package/src/lib/shared/producerKey.ts +0 -32
- package/src/lib/shared/programNameForPackage.ts +0 -16
- package/src/lib/shared/promptNameForFile.ts +0 -10
- package/src/lib/shared/queryStringFromArgs.ts +0 -38
- package/src/lib/shared/randomHexId.ts +0 -14
- package/src/lib/shared/reachable.ts +0 -99
- package/src/lib/shared/readEnvFile.ts +0 -15
- package/src/lib/shared/readLastConnection.ts +0 -18
- package/src/lib/shared/readPackageJson.ts +0 -9
- package/src/lib/shared/recordRemoteMeta.ts +0 -5
- package/src/lib/shared/refresh.ts +0 -39
- package/src/lib/shared/refreshing.ts +0 -37
- package/src/lib/shared/remoteMetaStore.ts +0 -16
- package/src/lib/shared/requestScopeSlot.ts +0 -13
- package/src/lib/shared/resolveClientFlags.ts +0 -20
- package/src/lib/shared/resolvedCellsSlot.ts +0 -13
- package/src/lib/shared/responseBodyKind.ts +0 -35
- package/src/lib/shared/responseErrorText.ts +0 -9
- package/src/lib/shared/reviveWireField.ts +0 -49
- package/src/lib/shared/reviveWireOutput.ts +0 -36
- package/src/lib/shared/routeParamsShape.ts +0 -20
- package/src/lib/shared/rpcErrorRegistry.ts +0 -69
- package/src/lib/shared/rpcServerForRoot.ts +0 -25
- package/src/lib/shared/rpcTimeoutSlot.ts +0 -9
- package/src/lib/shared/rpcUrlForFile.ts +0 -19
- package/src/lib/shared/runningAsStandaloneBinary.ts +0 -13
- package/src/lib/shared/safeJsonForScript.ts +0 -17
- package/src/lib/shared/scanPages.ts +0 -25
- package/src/lib/shared/selectorMatcher.ts +0 -55
- package/src/lib/shared/selectorPrefix.ts +0 -32
- package/src/lib/shared/serializeEnv.ts +0 -30
- package/src/lib/shared/serializeSelector.ts +0 -69
- package/src/lib/shared/setAppName.ts +0 -5
- package/src/lib/shared/setOwnProperty.ts +0 -19
- package/src/lib/shared/setsIntersect.ts +0 -15
- package/src/lib/shared/sharedCacheStore.ts +0 -14
- package/src/lib/shared/sharedCacheStoreSlot.ts +0 -10
- package/src/lib/shared/skipNonCode.ts +0 -230
- package/src/lib/shared/snapshotShippable.ts +0 -23
- package/src/lib/shared/snippet.ts +0 -30
- package/src/lib/shared/socketNameForFile.ts +0 -11
- package/src/lib/shared/socketTailsSlot.ts +0 -13
- package/src/lib/shared/socketTapSlot.ts +0 -12
- package/src/lib/shared/sseErrorFrame.ts +0 -29
- package/src/lib/shared/streamResponse.ts +0 -180
- package/src/lib/shared/streamedCellsSlot.ts +0 -14
- package/src/lib/shared/stripImport.ts +0 -29
- package/src/lib/shared/subscribableFromResponse.ts +0 -51
- package/src/lib/shared/subscribableProbes.ts +0 -111
- package/src/lib/shared/tailProbeSlot.ts +0 -23
- package/src/lib/shared/toTagSet.ts +0 -4
- package/src/lib/shared/trace.ts +0 -16
- package/src/lib/shared/types/AmendApply.ts +0 -15
- package/src/lib/shared/types/AsyncComputed.ts +0 -20
- package/src/lib/shared/types/AsyncState.ts +0 -13
- package/src/lib/shared/types/CacheEntry.ts +0 -100
- package/src/lib/shared/types/CacheInvalidation.ts +0 -9
- package/src/lib/shared/types/CacheOnContext.ts +0 -15
- package/src/lib/shared/types/CacheOptions.ts +0 -53
- package/src/lib/shared/types/CachePolicy.ts +0 -31
- package/src/lib/shared/types/CacheReaderHook.ts +0 -11
- package/src/lib/shared/types/CacheSelector.ts +0 -17
- package/src/lib/shared/types/CacheSnapshotEntry.ts +0 -32
- package/src/lib/shared/types/CacheStalenessApply.ts +0 -13
- package/src/lib/shared/types/CacheStalenessFrame.ts +0 -24
- package/src/lib/shared/types/CacheStats.ts +0 -13
- package/src/lib/shared/types/CacheStore.ts +0 -45
- package/src/lib/shared/types/ChannelLog.ts +0 -13
- package/src/lib/shared/types/ClientFlags.ts +0 -13
- package/src/lib/shared/types/CompileTarget.ts +0 -6
- package/src/lib/shared/types/DebugGate.ts +0 -10
- package/src/lib/shared/types/DocSnapshots.ts +0 -12
- package/src/lib/shared/types/ErrorJsonSchemas.ts +0 -8
- package/src/lib/shared/types/ErrorSpec.ts +0 -11
- package/src/lib/shared/types/FrameworkLog.ts +0 -13
- package/src/lib/shared/types/HttpMethod.ts +0 -3
- package/src/lib/shared/types/InputCoercion.ts +0 -17
- package/src/lib/shared/types/LastConnection.ts +0 -9
- package/src/lib/shared/types/Log.ts +0 -13
- package/src/lib/shared/types/LogRecord.ts +0 -42
- package/src/lib/shared/types/LogVoice.ts +0 -7
- package/src/lib/shared/types/NamedAsyncIterable.ts +0 -26
- package/src/lib/shared/types/OutputWirePlan.ts +0 -17
- package/src/lib/shared/types/PageSnapshot.ts +0 -14
- package/src/lib/shared/types/PagesScan.ts +0 -7
- package/src/lib/shared/types/PendingAsyncCells.ts +0 -10
- package/src/lib/shared/types/PromptArgument.ts +0 -12
- package/src/lib/shared/types/RawRemoteFunction.ts +0 -20
- package/src/lib/shared/types/RemoteCallable.ts +0 -40
- package/src/lib/shared/types/RemoteFunction.ts +0 -116
- package/src/lib/shared/types/ReplayableMethod.ts +0 -7
- package/src/lib/shared/types/RequestScopeInfo.ts +0 -16
- package/src/lib/shared/types/ResolvedCells.ts +0 -11
- package/src/lib/shared/types/ResolverSlot.ts +0 -13
- package/src/lib/shared/types/ReturnBody.ts +0 -15
- package/src/lib/shared/types/RpcBuildStamps.ts +0 -32
- package/src/lib/shared/types/RpcError.ts +0 -26
- package/src/lib/shared/types/RpcErrorGuard.ts +0 -35
- package/src/lib/shared/types/RpcInvoker.ts +0 -6
- package/src/lib/shared/types/RpcOptions.ts +0 -22
- package/src/lib/shared/types/Socket.ts +0 -54
- package/src/lib/shared/types/SocketChannel.ts +0 -17
- package/src/lib/shared/types/SocketClientFrame.ts +0 -19
- package/src/lib/shared/types/SocketServerFrame.ts +0 -24
- package/src/lib/shared/types/SocketSubCallbacks.ts +0 -13
- package/src/lib/shared/types/SocketTails.ts +0 -13
- package/src/lib/shared/types/SourceMap.ts +0 -14
- package/src/lib/shared/types/SsrBootState.ts +0 -27
- package/src/lib/shared/types/SsrPayload.ts +0 -36
- package/src/lib/shared/types/StandardSchemaV1.ts +0 -56
- package/src/lib/shared/types/StreamPolicy.ts +0 -11
- package/src/lib/shared/types/StreamedCells.ts +0 -19
- package/src/lib/shared/types/StreamedResolution.ts +0 -28
- package/src/lib/shared/types/TailHooks.ts +0 -13
- package/src/lib/shared/types/TraceContext.ts +0 -17
- package/src/lib/shared/types/ValidationErrorData.ts +0 -20
- package/src/lib/shared/types/WireKind.ts +0 -11
- package/src/lib/shared/url.ts +0 -141
- package/src/lib/shared/validationHttpError.ts +0 -33
- package/src/lib/shared/warmSeedKey.ts +0 -16
- package/src/lib/shared/wireJsonReplacer.ts +0 -30
- package/src/lib/shared/withBase.ts +0 -10
- package/src/lib/shared/withBaseUrl.ts +0 -17
- package/src/lib/shared/withCacheManaged.ts +0 -18
- package/src/lib/shared/withJsonSchema.ts +0 -21
- package/src/lib/shared/writeDts.ts +0 -19
- package/src/lib/shared/writeHealthDts.ts +0 -36
- package/src/lib/shared/writeLastConnection.ts +0 -13
- package/src/lib/shared/writePublicAssetsDts.ts +0 -27
- package/src/lib/shared/writeRoutesDts.ts +0 -41
- package/src/lib/shared/writeRpcDts.ts +0 -60
- package/src/lib/shared/writeTestRpcDts.ts +0 -45
- package/src/lib/shared/writeTestSocketsDts.ts +0 -34
- package/src/lib/test/assertAgentFrameConformance.ts +0 -73
- package/src/lib/test/createScriptedSurface.ts +0 -45
- package/src/lib/test/createTestApp.ts +0 -242
- package/src/lib/test/createTestSocketChannel.ts +0 -85
- package/src/lib/ui/README.md +0 -86
- package/src/lib/ui/activePendingCells.ts +0 -14
- package/src/lib/ui/amendReaderHook.ts +0 -125
- package/src/lib/ui/compile/ABIDE_SEMANTIC_TOKENS_LEGEND.ts +0 -79
- package/src/lib/ui/compile/AbideCompileError.ts +0 -16
- package/src/lib/ui/compile/BLOCK_KEYWORDS.ts +0 -21
- package/src/lib/ui/compile/SSR_ESCAPE.ts +0 -40
- package/src/lib/ui/compile/TS_PRINTER.ts +0 -7
- package/src/lib/ui/compile/UI_RUNTIME_IMPORTS.ts +0 -86
- package/src/lib/ui/compile/VOID_TAGS.ts +0 -22
- package/src/lib/ui/compile/abideUiPlugin.ts +0 -109
- package/src/lib/ui/compile/analyzeComponent.ts +0 -222
- package/src/lib/ui/compile/asOutlet.ts +0 -30
- package/src/lib/ui/compile/assertTranspiles.ts +0 -19
- package/src/lib/ui/compile/assetModulesFile.ts +0 -32
- package/src/lib/ui/compile/assignmentTargetNames.ts +0 -54
- package/src/lib/ui/compile/asyncInterpolationFields.ts +0 -152
- package/src/lib/ui/compile/asyncValuePositionError.ts +0 -21
- package/src/lib/ui/compile/asyncValuePositionInterpolations.ts +0 -64
- package/src/lib/ui/compile/attrLiftPosition.ts +0 -18
- package/src/lib/ui/compile/awaitPlan.ts +0 -60
- package/src/lib/ui/compile/awaitSubjectExpr.ts +0 -23
- package/src/lib/ui/compile/bindListenEvent.ts +0 -18
- package/src/lib/ui/compile/cachedShadowProgram.ts +0 -39
- package/src/lib/ui/compile/cachedSourceFile.ts +0 -40
- package/src/lib/ui/compile/catchBinding.ts +0 -10
- package/src/lib/ui/compile/classStyleMergePlan.ts +0 -108
- package/src/lib/ui/compile/classifyInterpolationType.ts +0 -46
- package/src/lib/ui/compile/collectAbideDiagnostics.ts +0 -166
- package/src/lib/ui/compile/compileComponent.ts +0 -46
- package/src/lib/ui/compile/compileModule.ts +0 -306
- package/src/lib/ui/compile/compileSSR.ts +0 -119
- package/src/lib/ui/compile/compileShadow.ts +0 -1326
- package/src/lib/ui/compile/componentOrdinals.ts +0 -39
- package/src/lib/ui/compile/composeProps.ts +0 -64
- package/src/lib/ui/compile/createShadowLanguageService.ts +0 -348
- package/src/lib/ui/compile/createShadowProgram.ts +0 -127
- package/src/lib/ui/compile/createShadowScope.ts +0 -42
- package/src/lib/ui/compile/declaredNames.ts +0 -36
- package/src/lib/ui/compile/decodeHtmlEntities.ts +0 -53
- package/src/lib/ui/compile/destructureBindingNames.ts +0 -38
- package/src/lib/ui/compile/desugarSignals.ts +0 -1113
- package/src/lib/ui/compile/eachPlan.ts +0 -61
- package/src/lib/ui/compile/elementPlan.ts +0 -55
- package/src/lib/ui/compile/encodeSemanticTokens.ts +0 -60
- package/src/lib/ui/compile/expressionIsPrefixEvaluable.ts +0 -19
- package/src/lib/ui/compile/generateBuild.ts +0 -903
- package/src/lib/ui/compile/generateSSR.ts +0 -973
- package/src/lib/ui/compile/groupBindParts.ts +0 -28
- package/src/lib/ui/compile/hasTopLevelAwait.ts +0 -28
- package/src/lib/ui/compile/hoistCells.ts +0 -120
- package/src/lib/ui/compile/hoistableAwaits.ts +0 -183
- package/src/lib/ui/compile/hoistableChildRenders.ts +0 -112
- package/src/lib/ui/compile/identifierReferencePattern.ts +0 -13
- package/src/lib/ui/compile/ifPlan.ts +0 -36
- package/src/lib/ui/compile/interpolatedTemplateLiteral.ts +0 -27
- package/src/lib/ui/compile/interpolationClassifierForRoot.ts +0 -32
- package/src/lib/ui/compile/isAnchorPositioned.ts +0 -19
- package/src/lib/ui/compile/isControlFlow.ts +0 -20
- package/src/lib/ui/compile/isFunctionScopeBoundary.ts +0 -20
- package/src/lib/ui/compile/isPlainIdentifier.ts +0 -7
- package/src/lib/ui/compile/isSpuriousAsyncReadDiagnostic.ts +0 -215
- package/src/lib/ui/compile/isTextLeaf.ts +0 -16
- package/src/lib/ui/compile/isWhitespaceText.ts +0 -19
- package/src/lib/ui/compile/liftAsyncSubExpressions.ts +0 -166
- package/src/lib/ui/compile/liftScriptSeed.ts +0 -47
- package/src/lib/ui/compile/loadShadowTsConfig.ts +0 -31
- package/src/lib/ui/compile/lowerAsyncInterpolations.ts +0 -92
- package/src/lib/ui/compile/lowerCompoundAssignment.ts +0 -49
- package/src/lib/ui/compile/lowerContext.ts +0 -167
- package/src/lib/ui/compile/lowerDocAccess.ts +0 -302
- package/src/lib/ui/compile/lowerScript.ts +0 -190
- package/src/lib/ui/compile/lowerUpdateExpression.ts +0 -32
- package/src/lib/ui/compile/makeVarNamer.ts +0 -10
- package/src/lib/ui/compile/nearestProjectRoot.ts +0 -16
- package/src/lib/ui/compile/nodeAtShadowOffset.ts +0 -28
- package/src/lib/ui/compile/offsetToLineColumn.ts +0 -16
- package/src/lib/ui/compile/offsetToPosition.ts +0 -9
- package/src/lib/ui/compile/pagePropsType.ts +0 -23
- package/src/lib/ui/compile/parseTemplate.ts +0 -25
- package/src/lib/ui/compile/parseTemplateRecovering.ts +0 -1385
- package/src/lib/ui/compile/prepareNestedScript.ts +0 -62
- package/src/lib/ui/compile/reactiveBinding.ts +0 -47
- package/src/lib/ui/compile/referencedIdentifiers.ts +0 -35
- package/src/lib/ui/compile/remapShadowDiagnostic.ts +0 -30
- package/src/lib/ui/compile/renameSignalRefs.ts +0 -425
- package/src/lib/ui/compile/resolveAbideImports.ts +0 -29
- package/src/lib/ui/compile/resolveBranches.ts +0 -21
- package/src/lib/ui/compile/resolveReactiveExport.ts +0 -92
- package/src/lib/ui/compile/scopeAttr.ts +0 -9
- package/src/lib/ui/compile/scopeCss.ts +0 -138
- package/src/lib/ui/compile/seedTypeClassifierForRoot.ts +0 -60
- package/src/lib/ui/compile/shadowInterpolationClassifier.ts +0 -47
- package/src/lib/ui/compile/shadowNaming.ts +0 -11
- package/src/lib/ui/compile/signalCallee.ts +0 -24
- package/src/lib/ui/compile/skeletonContext.ts +0 -133
- package/src/lib/ui/compile/skeletonable.ts +0 -68
- package/src/lib/ui/compile/snippetPlan.ts +0 -28
- package/src/lib/ui/compile/sourceFileOptionsSignature.ts +0 -20
- package/src/lib/ui/compile/sourceToShadowOffset.ts +0 -24
- package/src/lib/ui/compile/spreadExcludedNames.ts +0 -27
- package/src/lib/ui/compile/staticAttr.ts +0 -11
- package/src/lib/ui/compile/staticAttrValue.ts +0 -13
- package/src/lib/ui/compile/staticTextPart.ts +0 -12
- package/src/lib/ui/compile/stripEffects.ts +0 -48
- package/src/lib/ui/compile/structuralHeadTokens.ts +0 -107
- package/src/lib/ui/compile/switchPlan.ts +0 -28
- package/src/lib/ui/compile/templateAnchorAdapter.ts +0 -61
- package/src/lib/ui/compile/templateElementAdapter.ts +0 -44
- package/src/lib/ui/compile/templateSemanticTokens.ts +0 -21
- package/src/lib/ui/compile/templateStartOffset.ts +0 -15
- package/src/lib/ui/compile/tryPlan.ts +0 -37
- package/src/lib/ui/compile/types/AbideDiagnostic.ts +0 -14
- package/src/lib/ui/compile/types/AnalyzedComponent.ts +0 -42
- package/src/lib/ui/compile/types/AsyncInterpolationField.ts +0 -19
- package/src/lib/ui/compile/types/Binding.ts +0 -24
- package/src/lib/ui/compile/types/CompiledShadow.ts +0 -27
- package/src/lib/ui/compile/types/ElementPlan.ts +0 -43
- package/src/lib/ui/compile/types/InterpolationClassifier.ts +0 -12
- package/src/lib/ui/compile/types/InterpolationKind.ts +0 -7
- package/src/lib/ui/compile/types/ParseDiagnostic.ts +0 -8
- package/src/lib/ui/compile/types/SeedTypeClassifier.ts +0 -15
- package/src/lib/ui/compile/types/SemanticToken.ts +0 -11
- package/src/lib/ui/compile/types/ShadowKind.ts +0 -9
- package/src/lib/ui/compile/types/ShadowScope.ts +0 -19
- package/src/lib/ui/compile/types/SkeletonContext.ts +0 -21
- package/src/lib/ui/compile/types/TemplateAttr.ts +0 -34
- package/src/lib/ui/compile/types/TemplateNode.ts +0 -137
- package/src/lib/ui/compile/types/TextPart.ts +0 -8
- package/src/lib/ui/compile/types/ValuePositionInterpolation.ts +0 -13
- package/src/lib/ui/compile/unwrapParens.ts +0 -10
- package/src/lib/ui/compile/walkAnchorOrder.ts +0 -57
- package/src/lib/ui/compile/walkElementOrder.ts +0 -60
- package/src/lib/ui/compile/withBindings.ts +0 -45
- package/src/lib/ui/compile/wrapReactionCellSources.ts +0 -121
- package/src/lib/ui/compile/wrapReactiveSeeds.ts +0 -44
- package/src/lib/ui/compile/wrapSeed.ts +0 -28
- package/src/lib/ui/compile/writtenTemplateNames.ts +0 -84
- package/src/lib/ui/computed.ts +0 -75
- package/src/lib/ui/createScope.ts +0 -157
- package/src/lib/ui/dom/MATHML_NAMESPACE.ts +0 -6
- package/src/lib/ui/dom/SVG_NAMESPACE.ts +0 -8
- package/src/lib/ui/dom/adoptRange.ts +0 -27
- package/src/lib/ui/dom/anchorCursor.ts +0 -25
- package/src/lib/ui/dom/anchoredBranch.ts +0 -153
- package/src/lib/ui/dom/appendSnippet.ts +0 -75
- package/src/lib/ui/dom/appendStatic.ts +0 -26
- package/src/lib/ui/dom/appendText.ts +0 -160
- package/src/lib/ui/dom/appendTextAt.ts +0 -39
- package/src/lib/ui/dom/assertClaimedText.ts +0 -30
- package/src/lib/ui/dom/attach.ts +0 -25
- package/src/lib/ui/dom/attr.ts +0 -57
- package/src/lib/ui/dom/awaitBlock.ts +0 -314
- package/src/lib/ui/dom/awaitSubject.ts +0 -118
- package/src/lib/ui/dom/bindProp.ts +0 -22
- package/src/lib/ui/dom/bindSelectValue.ts +0 -48
- package/src/lib/ui/dom/bindableProp.ts +0 -47
- package/src/lib/ui/dom/buildDetachedRange.ts +0 -31
- package/src/lib/ui/dom/cellPending.ts +0 -24
- package/src/lib/ui/dom/claimText.ts +0 -38
- package/src/lib/ui/dom/clearBetween.ts +0 -16
- package/src/lib/ui/dom/cloneStatic.ts +0 -69
- package/src/lib/ui/dom/commentData.ts +0 -14
- package/src/lib/ui/dom/depthZeroNodes.ts +0 -34
- package/src/lib/ui/dom/discardAndRebuild.ts +0 -23
- package/src/lib/ui/dom/discardBoundary.ts +0 -46
- package/src/lib/ui/dom/disposeRange.ts +0 -18
- package/src/lib/ui/dom/domAnchorAdapter.ts +0 -29
- package/src/lib/ui/dom/domElementAdapter.ts +0 -20
- package/src/lib/ui/dom/each.ts +0 -253
- package/src/lib/ui/dom/eachAsync.ts +0 -188
- package/src/lib/ui/dom/effectiveChildNamespace.ts +0 -13
- package/src/lib/ui/dom/enterNamespace.ts +0 -20
- package/src/lib/ui/dom/fillBefore.ts +0 -42
- package/src/lib/ui/dom/fillBoundary.ts +0 -38
- package/src/lib/ui/dom/fillRange.ts +0 -30
- package/src/lib/ui/dom/foreignWrapperTag.ts +0 -22
- package/src/lib/ui/dom/hydrate.ts +0 -34
- package/src/lib/ui/dom/inheritedNamespace.ts +0 -19
- package/src/lib/ui/dom/isComment.ts +0 -6
- package/src/lib/ui/dom/isElement.ts +0 -6
- package/src/lib/ui/dom/markerDepthDelta.ts +0 -19
- package/src/lib/ui/dom/matchingRangeClose.ts +0 -29
- package/src/lib/ui/dom/mergeProps.ts +0 -32
- package/src/lib/ui/dom/mount.ts +0 -30
- package/src/lib/ui/dom/mountChild.ts +0 -129
- package/src/lib/ui/dom/mountRange.ts +0 -48
- package/src/lib/ui/dom/mountSlot.ts +0 -38
- package/src/lib/ui/dom/mountSwappableRange.ts +0 -122
- package/src/lib/ui/dom/moveRange.ts +0 -19
- package/src/lib/ui/dom/mutateDocContainer.ts +0 -65
- package/src/lib/ui/dom/on.ts +0 -33
- package/src/lib/ui/dom/openMarker.ts +0 -22
- package/src/lib/ui/dom/outlet.ts +0 -63
- package/src/lib/ui/dom/parseRawNodes.ts +0 -17
- package/src/lib/ui/dom/readCall.ts +0 -29
- package/src/lib/ui/dom/readCell.ts +0 -55
- package/src/lib/ui/dom/readTextOrSuspend.ts +0 -21
- package/src/lib/ui/dom/removeRange.ts +0 -18
- package/src/lib/ui/dom/replaceRange.ts +0 -24
- package/src/lib/ui/dom/restProps.ts +0 -32
- package/src/lib/ui/dom/skeleton.ts +0 -153
- package/src/lib/ui/dom/spreadAttrs.ts +0 -95
- package/src/lib/ui/dom/spreadProps.ts +0 -31
- package/src/lib/ui/dom/switchBlock.ts +0 -80
- package/src/lib/ui/dom/templateFor.ts +0 -28
- package/src/lib/ui/dom/tryBlock.ts +0 -263
- package/src/lib/ui/dom/types/EachRow.ts +0 -21
- package/src/lib/ui/dom/types/SkeletonHoles.ts +0 -10
- package/src/lib/ui/dom/types/SwitchCase.ts +0 -11
- package/src/lib/ui/dom/when.ts +0 -58
- package/src/lib/ui/dom/withScope.ts +0 -37
- package/src/lib/ui/dom/withSuspense.ts +0 -22
- package/src/lib/ui/dom/writeCell.ts +0 -22
- package/src/lib/ui/effect.ts +0 -24
- package/src/lib/ui/enterScope.ts +0 -18
- package/src/lib/ui/exitScope.ts +0 -8
- package/src/lib/ui/finalizeStreamedChildren.ts +0 -88
- package/src/lib/ui/flight.ts +0 -56
- package/src/lib/ui/html.ts +0 -39
- package/src/lib/ui/isolateCellBarrier.ts +0 -17
- package/src/lib/ui/linked.ts +0 -125
- package/src/lib/ui/navigate.ts +0 -77
- package/src/lib/ui/probeNavigation.ts +0 -33
- package/src/lib/ui/props.ts +0 -17
- package/src/lib/ui/remoteProxy.ts +0 -256
- package/src/lib/ui/renderChain.ts +0 -113
- package/src/lib/ui/renderToStream.ts +0 -128
- package/src/lib/ui/resumeSeedScript.ts +0 -27
- package/src/lib/ui/router.ts +0 -649
- package/src/lib/ui/runtime/AsyncCellError.ts +0 -21
- package/src/lib/ui/runtime/BRANCH_SEGMENT.ts +0 -24
- package/src/lib/ui/runtime/CELL_SEED.ts +0 -12
- package/src/lib/ui/runtime/CHILD_PRESENT.ts +0 -8
- package/src/lib/ui/runtime/CURRENT_BOUNDARY.ts +0 -11
- package/src/lib/ui/runtime/CURRENT_PATH.ts +0 -29
- package/src/lib/ui/runtime/CURRENT_SCOPE.ts +0 -23
- package/src/lib/ui/runtime/DOC_SEED.ts +0 -10
- package/src/lib/ui/runtime/HOLE_ATTRIBUTE.ts +0 -9
- package/src/lib/ui/runtime/NODE_STATE.ts +0 -22
- package/src/lib/ui/runtime/OUTLET_MARKER.ts +0 -10
- package/src/lib/ui/runtime/OUTLET_TAG.ts +0 -7
- package/src/lib/ui/runtime/OWNER.ts +0 -8
- package/src/lib/ui/runtime/PENDING_OUTLET.ts +0 -8
- package/src/lib/ui/runtime/RANGE_MARKER.ts +0 -18
- package/src/lib/ui/runtime/REACTIVE_CONTEXT.ts +0 -20
- package/src/lib/ui/runtime/RENDER.ts +0 -35
- package/src/lib/ui/runtime/REQUEST_SUPERSEDED.ts +0 -8
- package/src/lib/ui/runtime/RESUME.ts +0 -21
- package/src/lib/ui/runtime/SEED_MARKS.ts +0 -14
- package/src/lib/ui/runtime/STREAMED_CELLS.ts +0 -57
- package/src/lib/ui/runtime/SuspenseSignal.ts +0 -24
- package/src/lib/ui/runtime/abortNode.ts +0 -22
- package/src/lib/ui/runtime/ambientPathBacking.ts +0 -32
- package/src/lib/ui/runtime/ambientScopeBacking.ts +0 -26
- package/src/lib/ui/runtime/applyPatchToTree.ts +0 -54
- package/src/lib/ui/runtime/batch.ts +0 -22
- package/src/lib/ui/runtime/blockId.ts +0 -31
- package/src/lib/ui/runtime/boundaryFor.ts +0 -11
- package/src/lib/ui/runtime/cellBarrierBacking.ts +0 -30
- package/src/lib/ui/runtime/claimChild.ts +0 -8
- package/src/lib/ui/runtime/claimExpected.ts +0 -27
- package/src/lib/ui/runtime/claimMarker.ts +0 -13
- package/src/lib/ui/runtime/claimRun.ts +0 -22
- package/src/lib/ui/runtime/clientPage.ts +0 -116
- package/src/lib/ui/runtime/consumeSeed.ts +0 -38
- package/src/lib/ui/runtime/createAsyncCell.ts +0 -358
- package/src/lib/ui/runtime/createComputedNode.ts +0 -19
- package/src/lib/ui/runtime/createDoc.ts +0 -334
- package/src/lib/ui/runtime/createEffectNode.ts +0 -81
- package/src/lib/ui/runtime/createSignalNode.ts +0 -19
- package/src/lib/ui/runtime/currentAbortSignal.ts +0 -26
- package/src/lib/ui/runtime/detachLink.ts +0 -21
- package/src/lib/ui/runtime/endTracking.ts +0 -24
- package/src/lib/ui/runtime/enterRenderPass.ts +0 -13
- package/src/lib/ui/runtime/escapeKey.ts +0 -19
- package/src/lib/ui/runtime/exitRenderPass.ts +0 -7
- package/src/lib/ui/runtime/flushEffects.ts +0 -91
- package/src/lib/ui/runtime/generationGuard.ts +0 -40
- package/src/lib/ui/runtime/historyEntries.ts +0 -151
- package/src/lib/ui/runtime/inScope.ts +0 -19
- package/src/lib/ui/runtime/isAsyncFunction.ts +0 -14
- package/src/lib/ui/runtime/nextBlockId.ts +0 -12
- package/src/lib/ui/runtime/parkCursor.ts +0 -10
- package/src/lib/ui/runtime/pathSegments.ts +0 -10
- package/src/lib/ui/runtime/reactiveAbortState.ts +0 -15
- package/src/lib/ui/runtime/readNode.ts +0 -38
- package/src/lib/ui/runtime/renderPath.ts +0 -16
- package/src/lib/ui/runtime/reportHydrationDivergence.ts +0 -30
- package/src/lib/ui/runtime/routeBareSeed.ts +0 -28
- package/src/lib/ui/runtime/runHydrationPass.ts +0 -69
- package/src/lib/ui/runtime/runNode.ts +0 -75
- package/src/lib/ui/runtime/runtimePath.ts +0 -9
- package/src/lib/ui/runtime/scope.ts +0 -46
- package/src/lib/ui/runtime/scopeGroup.ts +0 -40
- package/src/lib/ui/runtime/toTeardown.ts +0 -38
- package/src/lib/ui/runtime/track.ts +0 -60
- package/src/lib/ui/runtime/trigger.ts +0 -74
- package/src/lib/ui/runtime/types/AbideHistoryState.ts +0 -9
- package/src/lib/ui/runtime/types/Boundary.ts +0 -9
- package/src/lib/ui/runtime/types/Cell.ts +0 -7
- package/src/lib/ui/runtime/types/Computed.ts +0 -3
- package/src/lib/ui/runtime/types/Doc.ts +0 -24
- package/src/lib/ui/runtime/types/EffectResult.ts +0 -10
- package/src/lib/ui/runtime/types/HydrationCursor.ts +0 -8
- package/src/lib/ui/runtime/types/NavVerdict.ts +0 -9
- package/src/lib/ui/runtime/types/Patch.ts +0 -11
- package/src/lib/ui/runtime/types/PathWalk.ts +0 -10
- package/src/lib/ui/runtime/types/ReactiveLink.ts +0 -21
- package/src/lib/ui/runtime/types/ReactiveNode.ts +0 -33
- package/src/lib/ui/runtime/types/RenderContext.ts +0 -10
- package/src/lib/ui/runtime/types/Route.ts +0 -9
- package/src/lib/ui/runtime/types/RouteLoader.ts +0 -7
- package/src/lib/ui/runtime/types/SsrRender.ts +0 -34
- package/src/lib/ui/runtime/types/State.ts +0 -3
- package/src/lib/ui/runtime/types/Teardown.ts +0 -5
- package/src/lib/ui/runtime/types/UiComponent.ts +0 -24
- package/src/lib/ui/runtime/types/UiProps.ts +0 -12
- package/src/lib/ui/runtime/unescapeKey.ts +0 -12
- package/src/lib/ui/runtime/unlinkDeps.ts +0 -28
- package/src/lib/ui/runtime/untrack.ts +0 -20
- package/src/lib/ui/runtime/updateIfNecessary.ts +0 -40
- package/src/lib/ui/runtime/walkPath.ts +0 -41
- package/src/lib/ui/runtime/withOptionalPath.ts +0 -8
- package/src/lib/ui/runtime/withPath.ts +0 -16
- package/src/lib/ui/runtime/withPathFrom.ts +0 -20
- package/src/lib/ui/runtime/withoutHydration.ts +0 -22
- package/src/lib/ui/runtime/writeNode.ts +0 -16
- package/src/lib/ui/scope.ts +0 -20
- package/src/lib/ui/seedBootState.ts +0 -53
- package/src/lib/ui/seedStreamedResolution.ts +0 -56
- package/src/lib/ui/settleAsyncCells.ts +0 -51
- package/src/lib/ui/socketChannel.ts +0 -156
- package/src/lib/ui/socketProxy.ts +0 -47
- package/src/lib/ui/startClient.ts +0 -156
- package/src/lib/ui/state.ts +0 -77
- package/src/lib/ui/subscribeCacheStaleness.ts +0 -85
- package/src/lib/ui/trackedComputed.ts +0 -68
- package/src/lib/ui/tryEncodeResume.ts +0 -11
- package/src/lib/ui/types/Layouts.ts +0 -9
- package/src/lib/ui/types/Pages.ts +0 -8
- package/src/lib/ui/types/Scope.ts +0 -68
- package/src/lib/ui/watch.ts +0 -150
- package/src/preload.ts +0 -19
- package/src/scaffold.ts +0 -153
- package/src/serverBuildPlugins.ts +0 -25
- package/src/serverEntry.ts +0 -138
- package/src/zodCjsPlugin.ts +0 -51
- package/template/.zed/settings.json +0 -10
- package/template/CLAUDE.md +0 -22
- package/template/bunfig.toml +0 -4
- package/template/package.json +0 -21
- package/template/src/app.ts +0 -28
- package/template/src/bundle/icon.png +0 -0
- package/template/src/cli/banner.txt +0 -3
- package/template/src/cli/footer.txt +0 -1
- package/template/src/server/config.ts +0 -17
- package/template/src/server/rpc/getHello.ts +0 -38
- package/template/src/ui/app.css +0 -21
- package/template/src/ui/app.html +0 -24
- package/template/src/ui/pages/about/page.abide +0 -7
- package/template/src/ui/pages/layout.abide +0 -19
- package/template/src/ui/pages/page.abide +0 -19
- package/template/test/app.test.ts +0 -30
- package/template/tsconfig.json +0 -18
- package/tsconfig.app.json +0 -17
package/src/lib/shared/cache.ts
DELETED
|
@@ -1,1584 +0,0 @@
|
|
|
1
|
-
import { abideLog } from './abideLog.ts'
|
|
2
|
-
import { activeCacheStore } from './activeCacheStore.ts'
|
|
3
|
-
import { cacheStores } from './cacheStores.ts'
|
|
4
|
-
import { decodeResponse } from './decodeResponse.ts'
|
|
5
|
-
import { getRemoteMeta } from './getRemoteMeta.ts'
|
|
6
|
-
import { HttpError } from './HttpError.ts'
|
|
7
|
-
import { hydrationWindow } from './hydrationWindow.ts'
|
|
8
|
-
import { invalidateEvent } from './invalidateEvent.ts'
|
|
9
|
-
import { invalidateTripwire } from './invalidateTripwire.ts'
|
|
10
|
-
import { keyForRemoteCall } from './keyForRemoteCall.ts'
|
|
11
|
-
import { producerKey } from './producerKey.ts'
|
|
12
|
-
import { REMOTE_FUNCTION } from './REMOTE_FUNCTION.ts'
|
|
13
|
-
import { REPLAYABLE_METHODS } from './REPLAYABLE_METHODS.ts'
|
|
14
|
-
import { reviveWireOutput } from './reviveWireOutput.ts'
|
|
15
|
-
import { rpcErrorRegistry } from './rpcErrorRegistry.ts'
|
|
16
|
-
import { SocketDisconnectedError } from './SocketDisconnectedError.ts'
|
|
17
|
-
import { selectorMatcher } from './selectorMatcher.ts'
|
|
18
|
-
import { selectorPrefix } from './selectorPrefix.ts'
|
|
19
|
-
import { sharedCacheStore } from './sharedCacheStore.ts'
|
|
20
|
-
import { openStreamProbe } from './subscribableProbes.ts'
|
|
21
|
-
import { toTagSet } from './toTagSet.ts'
|
|
22
|
-
import type { CacheEntry } from './types/CacheEntry.ts'
|
|
23
|
-
import type { CacheOnContext } from './types/CacheOnContext.ts'
|
|
24
|
-
import type { CacheOptions } from './types/CacheOptions.ts'
|
|
25
|
-
import type { CachePolicy } from './types/CachePolicy.ts'
|
|
26
|
-
import type { CacheSelector } from './types/CacheSelector.ts'
|
|
27
|
-
import type { CacheStore } from './types/CacheStore.ts'
|
|
28
|
-
import type { NamedAsyncIterable } from './types/NamedAsyncIterable.ts'
|
|
29
|
-
import type { OutputWirePlan } from './types/OutputWirePlan.ts'
|
|
30
|
-
import type { RawRemoteFunction } from './types/RawRemoteFunction.ts'
|
|
31
|
-
import type { RemoteFunction } from './types/RemoteFunction.ts'
|
|
32
|
-
import { withCacheManaged } from './withCacheManaged.ts'
|
|
33
|
-
|
|
34
|
-
type AnyRemote<Args, Return> = RemoteFunction<Args, Return> | RawRemoteFunction<Args>
|
|
35
|
-
type Producer<Args, Return> = (args?: Args) => Promise<Return>
|
|
36
|
-
|
|
37
|
-
/* Per-read lifecycle diagnostics, opt-in via DEBUG=abide:cache (browser: the abide-debug localStorage key). */
|
|
38
|
-
const cacheLog = abideLog.channel('abide:cache')
|
|
39
|
-
|
|
40
|
-
/*
|
|
41
|
-
Tallies one read and narrates it on the diagnostics channel. The sink is the
|
|
42
|
-
request/tab store even when the data store is the process-level shared one —
|
|
43
|
-
attribution follows the asker, so a request's closing record reflects every
|
|
44
|
-
read it made. A settled retained entry (including the warm SSR sync path) is
|
|
45
|
-
a hit; an unsettled entry is a coalesced join of an in-flight call; no entry
|
|
46
|
-
is a miss that invokes the producer/remote.
|
|
47
|
-
*/
|
|
48
|
-
function recordRead(sink: CacheStore, key: string, existing: CacheEntry | undefined): void {
|
|
49
|
-
if (!existing) {
|
|
50
|
-
sink.stats.misses += 1
|
|
51
|
-
cacheLog(`miss ${key}`)
|
|
52
|
-
return
|
|
53
|
-
}
|
|
54
|
-
if (existing.settled === true) {
|
|
55
|
-
sink.stats.hits += 1
|
|
56
|
-
cacheLog(`hit ${key}`)
|
|
57
|
-
return
|
|
58
|
-
}
|
|
59
|
-
sink.stats.coalesced += 1
|
|
60
|
-
cacheLog(`coalesced ${key}`)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/*
|
|
64
|
-
Reads a call through a cache store. `cache(fn, args?)` checks the store for a
|
|
65
|
-
prior entry and returns a shared promise on hit, or invokes `fn` once and stores
|
|
66
|
-
its promise on miss — a direct read-through call, not a curried invoker. Args
|
|
67
|
-
lead (the common refinement).
|
|
68
|
-
|
|
69
|
-
A REMOTE rpc carries no call-site options (ADR-0020): its cache policy lives on
|
|
70
|
-
the endpoint definition (`GET(fn, { cache: {...} })`) and readThrough reads it as
|
|
71
|
-
the bottom layer. A plain PRODUCER has no endpoint, so it keeps a trailing
|
|
72
|
-
`options?: CacheOptions` (ttl/tags/throttle/debounce/shared) — its only policy
|
|
73
|
-
home. ttl = 0 → dedupe only; ttl > 0 → entry expires `ttl` ms after the promise
|
|
74
|
-
resolves. Omitted ttl → retained for the store's lifetime: a producer or a remote
|
|
75
|
-
READ is kept as long as its store lives (the request on the server, the tab on the
|
|
76
|
-
client), while a remote WRITE coalesces only (ttl 0 — the mutation idiom). A remote
|
|
77
|
-
read made outside any request scope falls back to the process store and coalesces
|
|
78
|
-
only too, so a scopeless read can't leak forever. See CachePolicy.
|
|
79
|
-
|
|
80
|
-
Coalescing is always on: identical in-flight calls share one flight — double-
|
|
81
|
-
submit coalescing and pending() visibility with nothing retained beyond the
|
|
82
|
-
store's atomic unit (the whole request on the server: one render, one effect; the
|
|
83
|
-
in-flight window in the tab). Caching is the retention `ttl` adds on top.
|
|
84
|
-
|
|
85
|
-
`fn` is either a remote function (a GET/POST/... helper) or a plain producer
|
|
86
|
-
returning a Promise:
|
|
87
|
-
|
|
88
|
-
cache(getPost, { id }) // → Promise<Post> (decoded body; policy on the endpoint)
|
|
89
|
-
cache(getPost.raw, { id }) // → Promise<Response> (raw escape hatch)
|
|
90
|
-
cache(fetchRates) // → Promise<Rates> (plain producer, no args)
|
|
91
|
-
cache(computeReport, input, { ttl: 60_000 }) // producer options trail
|
|
92
|
-
|
|
93
|
-
Remote calls key on fn.method + fn.url + args and store the underlying Response
|
|
94
|
-
(the decoded view is derived on the way out for the non-raw variant; both share
|
|
95
|
-
one entry). Producers have no wire identity, so they key on the producer's
|
|
96
|
-
reference + args — pass a hoisted/stable function to dedupe (an inline arrow is a
|
|
97
|
-
new reference every call and never does; a warning fires once per such call
|
|
98
|
-
site), and the promise is stored and handed back as-is (no Response, no decode,
|
|
99
|
-
no SSR snapshot).
|
|
100
|
-
|
|
101
|
-
`options.shared` (producer) / `cache.shared` (endpoint) puts the entry in the
|
|
102
|
-
process-level store instead of the request-scoped one, so a value computed in one
|
|
103
|
-
request is reused by later requests — the memoise-an-external-endpoint case.
|
|
104
|
-
Default (omitted) is request-scoped on the server, which keeps per-user data from
|
|
105
|
-
leaking across requests; on the client there is one tab store either way, so it is
|
|
106
|
-
a no-op.
|
|
107
|
-
|
|
108
|
-
Reactivity is implicit: the read calls `store.subscribe(key)`, which registers
|
|
109
|
-
the surrounding state.computed() / effect() scope. Invalidating the key then
|
|
110
|
-
re-runs that scope, which calls cache() again and gets a fresh entry. Outside a
|
|
111
|
-
tracking scope subscribe() is a no-op, so cache() works the same in server code
|
|
112
|
-
and plain client code.
|
|
113
|
-
|
|
114
|
-
SSR: how you consume the call decides inline vs streaming (during SSR only the
|
|
115
|
-
pending branch of a `<template await>` renders):
|
|
116
|
-
|
|
117
|
-
const post = await cache(getPost, { id }) // blocks render → baked into
|
|
118
|
-
// the initial SSR HTML
|
|
119
|
-
<template await={cache(getPost, { id })}> // renders pending → shell flushes
|
|
120
|
-
// now, value streams in on the
|
|
121
|
-
// same response when it resolves
|
|
122
|
-
|
|
123
|
-
The two don't mix within one component. A top-level `await` flips the async
|
|
124
|
-
render into await-everything mode and sweeps in every promise created
|
|
125
|
-
in that same component instance — so a sibling `<template await>` gets awaited
|
|
126
|
-
and inlined too, buffering the whole response to the slowest read. The markup
|
|
127
|
-
form doesn't change this: an await block renders its pending branch but render()
|
|
128
|
-
still blocks. To get both on one page,
|
|
129
|
-
isolate each blocking (top-level await) read in its own child component and
|
|
130
|
-
keep streaming reads in a parent that never top-level awaits — the
|
|
131
|
-
await-everything mode is per component instance, so a child's await blocks only
|
|
132
|
-
the child.
|
|
133
|
-
*/
|
|
134
|
-
// @documentation cache
|
|
135
|
-
/**
|
|
136
|
-
* @deprecated Streaming rpcs (jsonl/sse) aren't cacheable — a stream has no single
|
|
137
|
-
* value to retain. Consume it with `state(fn(args))` (reactive) or `for await (… of
|
|
138
|
-
* fn(args))` (imperative). This overload is selected first for a streaming rpc so the
|
|
139
|
-
* mistake is a red squiggle at the keyboard; the `decodeResponse` guard also throws.
|
|
140
|
-
*/
|
|
141
|
-
export function cache<Args>(
|
|
142
|
-
fn: RemoteFunction<Args, AsyncIterable<unknown>>,
|
|
143
|
-
...rest: never[]
|
|
144
|
-
): never
|
|
145
|
-
export function cache<Args, Return>(fn: RemoteFunction<Args, Return>, args?: Args): Promise<Return>
|
|
146
|
-
export function cache<Args>(fn: RawRemoteFunction<Args>, args?: Args): Promise<Response>
|
|
147
|
-
export function cache<Args, Return>(
|
|
148
|
-
fn: Producer<Args, Return>,
|
|
149
|
-
args?: Args,
|
|
150
|
-
options?: CacheOptions,
|
|
151
|
-
): Promise<Return>
|
|
152
|
-
export function cache<Args, Return>(
|
|
153
|
-
fn: AnyRemote<Args, Return> | Producer<Args, Return>,
|
|
154
|
-
args?: Args,
|
|
155
|
-
options?: CacheOptions,
|
|
156
|
-
): Promise<Return | Response> {
|
|
157
|
-
const result = readThrough(fn, args, options, false)
|
|
158
|
-
/* Revive the decoded body's structured fields (Set/Map/Date/bigint) so `cache(fn, args)`
|
|
159
|
-
matches the bare `fn(args)` read (createRemoteFunction.callable revives there) — without
|
|
160
|
-
this the two read APIs disagree for a typed field, and both violate the declared Return.
|
|
161
|
-
A producer / a raw `Response` carry no plan and pass through untouched; the decoded value is
|
|
162
|
-
call-private (fresh decode or cloned warm value), so revive mutates it in place. */
|
|
163
|
-
const plan = (fn as { outputWirePlan?: OutputWirePlan }).outputWirePlan
|
|
164
|
-
if (plan === undefined) {
|
|
165
|
-
return result
|
|
166
|
-
}
|
|
167
|
-
return result.then((value) =>
|
|
168
|
-
value instanceof Response ? value : (reviveWireOutput(value, plan) as Return),
|
|
169
|
-
)
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/*
|
|
173
|
-
The smart bare rpc call routes here (createRemoteFunction.callable → cache.read):
|
|
174
|
-
identical to cache() except a replayable read gets unconditional SWR retention —
|
|
175
|
-
its value is kept for display regardless of ttl, and ttl marks a staleness
|
|
176
|
-
deadline (the next read past it revalidates in the background) instead of driving
|
|
177
|
-
eviction. No call-site options (ADR-0020): all policy is read off the endpoint
|
|
178
|
-
(fn.cache). Always a decoded RemoteFunction read (the callable carries .raw), so
|
|
179
|
-
it returns Promise<Return>. `key` is the caller's already-derived cache key (the
|
|
180
|
-
callable keys its rpc-error registry with it) — threaded through so readThrough
|
|
181
|
-
reuses it instead of re-deriving the identical string; omitted, readThrough derives.
|
|
182
|
-
*/
|
|
183
|
-
function smartRead<Args, Return>(
|
|
184
|
-
fn: RemoteFunction<Args, Return>,
|
|
185
|
-
args?: Args,
|
|
186
|
-
key?: string,
|
|
187
|
-
): Promise<Return> {
|
|
188
|
-
return readThrough(fn, args, undefined, true, key) as Promise<Return>
|
|
189
|
-
}
|
|
190
|
-
cache.read = smartRead
|
|
191
|
-
|
|
192
|
-
/*
|
|
193
|
-
The shared read-through core. `smart` marks the smart bare call, which enables
|
|
194
|
-
unconditional SWR retention for a replayable read — but only on the client (see
|
|
195
|
-
smartRead / entry.retain and the `retain` computation below); the public cache()
|
|
196
|
-
passes false, keeping its explicit drop-on-ttl / drop-on-invalidate old surface.
|
|
197
|
-
A remote's policy is read off the endpoint (fn.cache — ADR-0020); a producer's
|
|
198
|
-
policy is its explicit cache() `options`.
|
|
199
|
-
*/
|
|
200
|
-
function readThrough<Args, Return>(
|
|
201
|
-
fn: AnyRemote<Args, Return> | Producer<Args, Return>,
|
|
202
|
-
args: Args | undefined,
|
|
203
|
-
options: CacheOptions | undefined,
|
|
204
|
-
smart: boolean,
|
|
205
|
-
precomputedKey?: string,
|
|
206
|
-
): Promise<Return | Response> {
|
|
207
|
-
/*
|
|
208
|
-
A remote function carries the REMOTE_FUNCTION brand (set by
|
|
209
|
-
createRemoteFunction on both variants); a plain producer never does — exact,
|
|
210
|
-
unlike a `url` property check a user function could satisfy by accident.
|
|
211
|
-
Among remotes, the "raw" variant lacks its own `.raw` sibling (only the
|
|
212
|
-
decoded callable carries one), which selects whether the decode step runs
|
|
213
|
-
on the way out.
|
|
214
|
-
*/
|
|
215
|
-
const isRemote = REMOTE_FUNCTION in fn
|
|
216
|
-
const isRaw = isRemote && !('raw' in fn)
|
|
217
|
-
const rawFn = !isRemote
|
|
218
|
-
? undefined
|
|
219
|
-
: isRaw
|
|
220
|
-
? (fn as RawRemoteFunction<Args>)
|
|
221
|
-
: (fn as RemoteFunction<Args, Return>).raw
|
|
222
|
-
const method = isRemote ? (rawFn as RawRemoteFunction<Args>).method : undefined
|
|
223
|
-
const replayable = method !== undefined && REPLAYABLE_METHODS.has(method.toUpperCase())
|
|
224
|
-
/* Remote policy is endpoint-declared — the bottom (and only) layer; a producer has no
|
|
225
|
-
endpoint, so its explicit cache() options stand in. */
|
|
226
|
-
const policy = isRemote ? resolveEndpointCache(fn as AnyRemote<Args, Return>, args) : options
|
|
227
|
-
/* SWR retention is a client concern (the tab store lives; revalidation is
|
|
228
|
-
visible). On the server there is no live UI to hold stale, so a smart read
|
|
229
|
-
never retains — it coalesces only. Unconditional for a replayable read now
|
|
230
|
-
(no swr toggle to opt out of). */
|
|
231
|
-
const retain = smart && replayable && typeof window !== 'undefined'
|
|
232
|
-
/*
|
|
233
|
-
ttl defaults to Infinity — an entry is retained for as long as its STORE lives, and
|
|
234
|
-
the store's lifetime (not ttl) is what ends a read: the request-scoped store on the
|
|
235
|
-
server (so a non-shared read dies with the request regardless of ttl), the tab store
|
|
236
|
-
on the client (until invalidate/refresh). `shared` selects the process store, where
|
|
237
|
-
the default Infinity memoises across requests and an explicit ttl bounds it — so
|
|
238
|
-
`shared` alone is "memoise", not a store-selector that retains nothing.
|
|
239
|
-
*/
|
|
240
|
-
const store = policy?.shared ? sharedCacheStore() : activeCacheStore()
|
|
241
|
-
/*
|
|
242
|
-
Two cases force coalesce-only (ttl 0) when the caller stated no ttl — nothing retained
|
|
243
|
-
beyond the in-flight window:
|
|
244
|
-
- a write (non-replayable remote): dropped on settle so a re-submit of the same body
|
|
245
|
-
isn't blocked by a retained entry (the mutation idiom);
|
|
246
|
-
- a read that resolved to the process store WITHOUT `shared` — a server read outside any
|
|
247
|
-
request scope, where activeCacheStore() falls back to the shared store. Nothing bounds
|
|
248
|
-
its lifetime there, so retaining it would leak forever.
|
|
249
|
-
Both apply on either side and however the call is made. An explicit `shared` defeats both:
|
|
250
|
-
it is a deliberate "memoise this across requests" opt-in (a POST that is a pure function
|
|
251
|
-
of its args, using the body only to carry a large payload — highlightCode), so it retains
|
|
252
|
-
in the process store with the default Infinity ttl rather than dropping on settle. An
|
|
253
|
-
explicit `ttl` already defeats them via the `ttl === undefined` guard above.
|
|
254
|
-
*/
|
|
255
|
-
const coalesceOnly =
|
|
256
|
-
isRemote &&
|
|
257
|
-
policy?.ttl === undefined &&
|
|
258
|
-
!policy?.shared &&
|
|
259
|
-
(!replayable || (typeof window === 'undefined' && store === sharedCacheStore()))
|
|
260
|
-
const effectiveOptions = coalesceOnly ? { ...policy, ttl: 0 } : policy
|
|
261
|
-
if (!isRemote) {
|
|
262
|
-
warnAnonymousProducer(fn as Producer<Args, Return>)
|
|
263
|
-
}
|
|
264
|
-
if (!isRemote) {
|
|
265
|
-
return invokeProducer(store, fn as Producer<Args, Return>, args, effectiveOptions)
|
|
266
|
-
}
|
|
267
|
-
const remote = rawFn as RawRemoteFunction<Args>
|
|
268
|
-
/* Reuse the caller's derived key when it threaded one (the smart bare call already
|
|
269
|
-
computes it for its rpc-error registry, and remote is that callable's .raw — same
|
|
270
|
-
method/url, so the string is identical). Otherwise derive it — the public cache()
|
|
271
|
-
and the raw path pass none. Saves a query-encode / canonical-json stringify per read,
|
|
272
|
-
warm hits included. */
|
|
273
|
-
const key = precomputedKey ?? keyForRemoteCall(remote.method, remote.url, args)
|
|
274
|
-
if (
|
|
275
|
-
!effectiveOptions?.shared &&
|
|
276
|
-
effectiveOptions?.ttl !== undefined &&
|
|
277
|
-
effectiveOptions.ttl > 0 &&
|
|
278
|
-
store !== sharedCacheStore()
|
|
279
|
-
) {
|
|
280
|
-
warnEphemeralTtl(key)
|
|
281
|
-
}
|
|
282
|
-
store.subscribe(key)
|
|
283
|
-
let existing = store.entries.get(key)
|
|
284
|
-
recordRead(effectiveOptions?.shared ? activeCacheStore() : store, key, existing)
|
|
285
|
-
/*
|
|
286
|
-
Negative-cache short-circuit: a prior failed load retained under errorTtl
|
|
287
|
-
re-surfaces the same failure with no network until its window elapses — a
|
|
288
|
-
Response is re-served (raw) or re-decoded to throw the same HttpError, a
|
|
289
|
-
network Error is re-rejected. Past the deadline (the sweep may not have fired
|
|
290
|
-
yet) evict it here so the read below is a clean miss that retries.
|
|
291
|
-
*/
|
|
292
|
-
if (existing?.errorResult !== undefined) {
|
|
293
|
-
if (existing.expiresAt !== undefined && existing.expiresAt > Date.now()) {
|
|
294
|
-
const failure = existing.errorResult
|
|
295
|
-
if (failure instanceof Response) {
|
|
296
|
-
return isRaw
|
|
297
|
-
? (Promise.resolve(failure.clone()) as Promise<Return | Response>)
|
|
298
|
-
: (decodeResponse(failure.clone()) as Promise<Return | Response>)
|
|
299
|
-
}
|
|
300
|
-
return Promise.reject(failure)
|
|
301
|
-
}
|
|
302
|
-
evictIfCurrent(store, existing)
|
|
303
|
-
existing = undefined
|
|
304
|
-
}
|
|
305
|
-
if (existing) {
|
|
306
|
-
tagEntry(existing, effectiveOptions?.tags)
|
|
307
|
-
attachPolicy(existing, effectiveOptions, () => remote(args as Args), retain)
|
|
308
|
-
adoptTtl(store, existing, effectiveOptions, retain)
|
|
309
|
-
/* Access-triggered staleness: reading a retained entry past its ttl deadline
|
|
310
|
-
kicks a background revalidation now (stale value stays visible below,
|
|
311
|
-
refreshing() true). Guarded on `!refreshing` so a read while one is already
|
|
312
|
-
in flight doesn't queue a redundant refetch. This is the whole staleness
|
|
313
|
-
mechanism — no timer polls an untouched entry. */
|
|
314
|
-
if (
|
|
315
|
-
existing.retain === true &&
|
|
316
|
-
existing.refreshing !== true &&
|
|
317
|
-
existing.expiresAt !== undefined &&
|
|
318
|
-
existing.expiresAt <= Date.now()
|
|
319
|
-
) {
|
|
320
|
-
scheduleInvalidationRefetch(store, existing)
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
/*
|
|
324
|
-
Warm path: a value pre-decoded onto the entry — by the SSR cache
|
|
325
|
-
snapshot the client seeds its store from — is served without a network
|
|
326
|
-
round-trip. It resolves on a
|
|
327
|
-
microtask (a settled Promise), not synchronously, so every cache() read
|
|
328
|
-
is uniformly `Promise<Return>` and `.then`/`.catch`/`.finally` chain
|
|
329
|
-
cleanly. Raw callers take the Response path; after an invalidate the
|
|
330
|
-
replacement entry carries no value and falls through to a live fetch.
|
|
331
|
-
|
|
332
|
-
abide-ui hydration is seamless regardless: a `<template await>` adopts
|
|
333
|
-
the server-rendered DOM from the streamed resume manifest (it never calls
|
|
334
|
-
cache() on the first pass), so a microtask warm read costs no flash — the
|
|
335
|
-
snapshot's job is keeping post-hydration reads (reactivity, invalidation,
|
|
336
|
-
navigation) warm, not driving the initial paint.
|
|
337
|
-
|
|
338
|
-
Each warm read resolves to its own clone of the stored value: it is
|
|
339
|
-
decoded once and would otherwise be shared by reference across every
|
|
340
|
-
reader of the key, so one mutating it would corrupt the others. A live
|
|
341
|
-
fetch hands each reader a fresh object; cloning keeps warm reads the same.
|
|
342
|
-
*/
|
|
343
|
-
if (!isRaw && existing !== undefined && existing.value !== undefined) {
|
|
344
|
-
return Promise.resolve(cloneWarmValue(existing.value)) as Promise<Return>
|
|
345
|
-
}
|
|
346
|
-
const responsePromise = invokeRemote(
|
|
347
|
-
store,
|
|
348
|
-
key,
|
|
349
|
-
existing,
|
|
350
|
-
rawFn as RawRemoteFunction<Args>,
|
|
351
|
-
args,
|
|
352
|
-
effectiveOptions,
|
|
353
|
-
retain,
|
|
354
|
-
)
|
|
355
|
-
if (isRaw) {
|
|
356
|
-
return responsePromise
|
|
357
|
-
}
|
|
358
|
-
return responsePromise.then(decodeResponse) as Promise<Return>
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
/*
|
|
362
|
-
Deep-copies a warm value so each reader gets its own mutable object — the
|
|
363
|
-
no-shared-mutation invariant the warm path turns on (a live fetch hands every
|
|
364
|
-
reader a fresh object; a warm read must match). A warm value only ever comes
|
|
365
|
-
from the json or text body kinds (bodyValueForKind): json yields JSON.parse
|
|
366
|
-
output and text yields a string, so the whole population is JSON-round-trippable
|
|
367
|
-
by construction — no Date/Map/Blob/cycle a structuredClone would be needed for.
|
|
368
|
-
A primitive (string/number/boolean from a text or scalar-json body) is immutable,
|
|
369
|
-
so it is returned as-is with no copy. An object/array goes through a JSON
|
|
370
|
-
round-trip, ~2x faster than structuredClone for this exact shape (measured:
|
|
371
|
-
773µs→516µs on a 149KB list, 3.4ms→1.7ms on 474KB) while producing the same
|
|
372
|
-
fresh, mutable, isomorphic-with-a-cold-read copy.
|
|
373
|
-
*/
|
|
374
|
-
function cloneWarmValue(value: unknown): unknown {
|
|
375
|
-
if (typeof value !== 'object' || value === null) {
|
|
376
|
-
return value
|
|
377
|
-
}
|
|
378
|
-
return JSON.parse(JSON.stringify(value))
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
/*
|
|
382
|
-
Resolves an rpc endpoint's declared cache policy (ADR-0020) into a plain
|
|
383
|
-
CacheOptions for the read-through machinery, evaluating the `tags` function form
|
|
384
|
-
against this call's args. Both remote variants (decoded + raw) carry `.cache`, so
|
|
385
|
-
either can be passed. Undefined when the endpoint declared no policy (method
|
|
386
|
-
defaults still apply below).
|
|
387
|
-
*/
|
|
388
|
-
function resolveEndpointCache<Args, Return>(
|
|
389
|
-
fn: AnyRemote<Args, Return>,
|
|
390
|
-
args: Args | undefined,
|
|
391
|
-
): CacheOptions | undefined {
|
|
392
|
-
const policy = (fn as { cache?: CachePolicy<Args> }).cache
|
|
393
|
-
if (policy === undefined) {
|
|
394
|
-
return undefined
|
|
395
|
-
}
|
|
396
|
-
const tags = typeof policy.tags === 'function' ? policy.tags(args as Args) : policy.tags
|
|
397
|
-
return {
|
|
398
|
-
ttl: policy.ttl,
|
|
399
|
-
tags,
|
|
400
|
-
shared: policy.shared,
|
|
401
|
-
throttle: policy.throttle,
|
|
402
|
-
debounce: policy.debounce,
|
|
403
|
-
errorTtl: policy.errorTtl,
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
/*
|
|
408
|
-
The keep-stale-and-revalidate refetch window, or undefined when the entry should
|
|
409
|
-
hard-drop on invalidate instead. Present when the smart bare call retains a
|
|
410
|
-
replayable read (`defaultOn`, SWR unconditional — the window is just the endpoint's
|
|
411
|
-
throttle/debounce, or `{}` = fire immediately) OR when a policy explicitly declares
|
|
412
|
-
a throttle/debounce window (producer options / endpoint cache). Collapsing this here
|
|
413
|
-
lets every downstream site treat "is a refetch window armed" as a single
|
|
414
|
-
defined/undefined check.
|
|
415
|
-
*/
|
|
416
|
-
function refetchWindow(
|
|
417
|
-
options: CacheOptions | undefined,
|
|
418
|
-
defaultOn: boolean,
|
|
419
|
-
): { throttle?: number; debounce?: number } | undefined {
|
|
420
|
-
const hasWindow = options?.throttle !== undefined || options?.debounce !== undefined
|
|
421
|
-
if (defaultOn || hasWindow) {
|
|
422
|
-
return { throttle: options?.throttle, debounce: options?.debounce }
|
|
423
|
-
}
|
|
424
|
-
return undefined
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
/*
|
|
428
|
-
An anonymous producer mints a fresh identity per wrap, so it never coalesces
|
|
429
|
-
and probes never match it — silently. Warn once per distinct source text (the
|
|
430
|
-
function object itself is fresh each time, so reference identity can't dedupe
|
|
431
|
-
the warning).
|
|
432
|
-
*/
|
|
433
|
-
const warnedAnonymousProducers = new Set<string>()
|
|
434
|
-
function warnAnonymousProducer(producer: (args?: never) => unknown): void {
|
|
435
|
-
if (producer.name !== '') {
|
|
436
|
-
return
|
|
437
|
-
}
|
|
438
|
-
const source = producer.toString()
|
|
439
|
-
if (warnedAnonymousProducers.has(source)) {
|
|
440
|
-
return
|
|
441
|
-
}
|
|
442
|
-
warnedAnonymousProducers.add(source)
|
|
443
|
-
abideLog.warn(
|
|
444
|
-
'cache() received an anonymous function — each call mints a fresh identity, so it never coalesces and pending()/refreshing() never match it. Hoist it to a named binding, or add a tag to probe it from elsewhere.',
|
|
445
|
-
)
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
/* Warn once per key when a ttl>0 read lands in an ephemeral (request-scoped)
|
|
449
|
-
store — the ttl expires with the request. `shared` (the process store) or a
|
|
450
|
-
client tab store are the retention homes; a request-scoped ttl is dead config. */
|
|
451
|
-
const warnedEphemeralTtl = new Set<string>()
|
|
452
|
-
function warnEphemeralTtl(key: string): void {
|
|
453
|
-
if (warnedEphemeralTtl.has(key)) {
|
|
454
|
-
return
|
|
455
|
-
}
|
|
456
|
-
warnedEphemeralTtl.add(key)
|
|
457
|
-
abideLog.warn(
|
|
458
|
-
`cache(): a request-scoped ttl expires with the request — add \`shared\` to cache "${key}" across requests, or drop the ttl.`,
|
|
459
|
-
)
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
/*
|
|
463
|
-
Producer path: key on the producer's reference + args, share the
|
|
464
|
-
in-flight/retained promise on hit, and store the value promise as-is on miss — no
|
|
465
|
-
Response, no decode, no SSR request metadata.
|
|
466
|
-
*/
|
|
467
|
-
function invokeProducer<Args, Return>(
|
|
468
|
-
store: CacheStore,
|
|
469
|
-
producer: Producer<Args, Return>,
|
|
470
|
-
args: Args | undefined,
|
|
471
|
-
options: CacheOptions | undefined,
|
|
472
|
-
): Promise<Return> {
|
|
473
|
-
const key = producerKey(producer, args)
|
|
474
|
-
store.subscribe(key)
|
|
475
|
-
const existing = store.entries.get(key)
|
|
476
|
-
recordRead(options?.shared ? activeCacheStore() : store, key, existing)
|
|
477
|
-
if (existing) {
|
|
478
|
-
tagEntry(existing, options?.tags)
|
|
479
|
-
attachPolicy(existing, options, () => producer(args), false)
|
|
480
|
-
const shared = existing.promise as Promise<Return>
|
|
481
|
-
/* A coalesced join waits on the in-flight producer — time the block so the
|
|
482
|
-
waterfall shows it; a settled hit returns immediately, so no span. */
|
|
483
|
-
return existing.settled === true
|
|
484
|
-
? shared
|
|
485
|
-
: cacheLog.trace<Return>(`cache wait ${key}`, () => shared)
|
|
486
|
-
}
|
|
487
|
-
/* Miss: time the producer run — where a request's time actually goes (an
|
|
488
|
-
external fetch, a computation). Producer path only; the remote path must
|
|
489
|
-
keep its own promise so getRemoteMeta can read the recorded Request. The
|
|
490
|
-
producer runs cache-managed so a bare RPC inside it isn't scope-bound — the
|
|
491
|
-
cache coalesces and owns this flight. */
|
|
492
|
-
const promise = cacheLog.trace<Return>(`cache ${key}`, () =>
|
|
493
|
-
withCacheManaged(() => producer(args)),
|
|
494
|
-
)
|
|
495
|
-
registerEntry(store, key, promise, options, undefined, () => producer(args), false)
|
|
496
|
-
return promise
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
function invokeRemote<Args>(
|
|
500
|
-
store: CacheStore,
|
|
501
|
-
key: string,
|
|
502
|
-
existing: CacheEntry | undefined,
|
|
503
|
-
rawFn: RawRemoteFunction<Args>,
|
|
504
|
-
args: Args | undefined,
|
|
505
|
-
options: CacheOptions | undefined,
|
|
506
|
-
retain: boolean,
|
|
507
|
-
): Promise<Response> {
|
|
508
|
-
if (existing) {
|
|
509
|
-
return shareable(existing.promise as Promise<Response>)
|
|
510
|
-
}
|
|
511
|
-
/* Cache-managed: the shared flight isn't bound to the reader that triggered the
|
|
512
|
-
miss, so its scope disposing can't abort a request other readers still join. */
|
|
513
|
-
const promise = withCacheManaged(() => rawFn(args as Args))
|
|
514
|
-
const request = getRemoteMeta(promise)
|
|
515
|
-
if (!request) {
|
|
516
|
-
throw new Error(
|
|
517
|
-
'[abide] cache() received a function whose call did not record metadata — was it produced by a rpc helper?',
|
|
518
|
-
)
|
|
519
|
-
}
|
|
520
|
-
registerEntry(store, key, promise, options, request, () => rawFn(args as Args), retain)
|
|
521
|
-
return shareable(promise)
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
/*
|
|
525
|
-
Stores a fresh entry and wires its settle / ttl / eviction lifecycle. Shared by
|
|
526
|
-
the remote and producer paths; `request` is set for remote entries (drives the
|
|
527
|
-
SSR snapshot) and undefined for producers.
|
|
528
|
-
*/
|
|
529
|
-
function registerEntry(
|
|
530
|
-
store: CacheStore,
|
|
531
|
-
key: string,
|
|
532
|
-
promise: Promise<unknown>,
|
|
533
|
-
options: CacheOptions | undefined,
|
|
534
|
-
request: Request | undefined,
|
|
535
|
-
refetch: () => Promise<unknown>,
|
|
536
|
-
retain: boolean,
|
|
537
|
-
): CacheEntry {
|
|
538
|
-
const ttl = options?.ttl
|
|
539
|
-
/* Capture the refetch thunk + window when a smart retained read (SWR unconditional)
|
|
540
|
-
or an explicit throttle/debounce window is present. */
|
|
541
|
-
const policy = refetchWindow(options, retain)
|
|
542
|
-
const invalidation = policy
|
|
543
|
-
? { refetch, throttle: policy.throttle, debounce: policy.debounce }
|
|
544
|
-
: undefined
|
|
545
|
-
/*
|
|
546
|
-
A prior entry for this key was dropped by invalidate() and is awaiting its
|
|
547
|
-
next read — consume the marker so this replacement read reports as a reload
|
|
548
|
-
(refreshing()) until it settles, not as a first-ever load.
|
|
549
|
-
*/
|
|
550
|
-
const refreshing = store.pendingRefresh.delete(key) || undefined
|
|
551
|
-
const entry: CacheEntry = {
|
|
552
|
-
key,
|
|
553
|
-
promise,
|
|
554
|
-
request,
|
|
555
|
-
ttl,
|
|
556
|
-
expiresAt: undefined,
|
|
557
|
-
tags: options?.tags === undefined ? undefined : toTagSet(options.tags),
|
|
558
|
-
refreshing,
|
|
559
|
-
invalidation,
|
|
560
|
-
retain: retain || undefined,
|
|
561
|
-
}
|
|
562
|
-
store.entries.set(key, entry)
|
|
563
|
-
store.markLifecycle(key)
|
|
564
|
-
/*
|
|
565
|
-
A ttl=0 remote entry in the request-scoped server store is kept until the
|
|
566
|
-
store dies with the response. The request is the server's atomic unit, so
|
|
567
|
-
a ttl=0 entry retains nothing beyond it but coalesces everything within
|
|
568
|
-
it: identical calls during one render — any method — share one effect
|
|
569
|
-
deterministically, regardless of settle timing, and the post-render SSR
|
|
570
|
-
snapshot can still pick up replayable entries (the snapshot applies its
|
|
571
|
-
own method filter; writes never ship). The keep never applies on the
|
|
572
|
-
client (the tab store outlives any unit — a kept write would block every
|
|
573
|
-
future re-submit, so entries evict the moment they settle), to producer
|
|
574
|
-
entries (no request), or when the resolved store is the process-level
|
|
575
|
-
`shared` store — including a non-shared read made outside an inbound
|
|
576
|
-
request, where the resolver falls back to `sharedCacheStore()` (Decision
|
|
577
|
-
1): that store is never request-scoped, so keeping it would leak forever.
|
|
578
|
-
The `store !== sharedCacheStore()` check is what tells a genuinely
|
|
579
|
-
request-scoped store apart from that fallback.
|
|
580
|
-
*/
|
|
581
|
-
const keepZeroTtlForRequest =
|
|
582
|
-
request !== undefined &&
|
|
583
|
-
!options?.shared &&
|
|
584
|
-
typeof window === 'undefined' &&
|
|
585
|
-
store !== sharedCacheStore()
|
|
586
|
-
function deleteIfCurrent() {
|
|
587
|
-
evictIfCurrent(store, entry)
|
|
588
|
-
}
|
|
589
|
-
promise.then(
|
|
590
|
-
(result) => {
|
|
591
|
-
/*
|
|
592
|
-
Mark settled so SSR snapshot serialization can tell awaited entries
|
|
593
|
-
(resolved by the time render() returns → inline) from {#await} ones
|
|
594
|
-
(still pending → stream). Set before the ttl branches below since a
|
|
595
|
-
ttl=0 server entry stays in the store for the snapshot.
|
|
596
|
-
*/
|
|
597
|
-
entry.settled = true
|
|
598
|
-
/* The reload finished — this entry now holds fresh data, no longer refreshing. */
|
|
599
|
-
entry.refreshing = false
|
|
600
|
-
store.markLifecycle(key)
|
|
601
|
-
/*
|
|
602
|
-
An error-status Response is a failed load, not a value to retain: fetch
|
|
603
|
-
resolves (it only rejects on a network fault) on a 4xx/5xx, so without
|
|
604
|
-
this the entry would be served as a hit for the whole ttl, even after the
|
|
605
|
-
backend recovers. Evict it so the next read retries — unless the endpoint
|
|
606
|
-
opted into the negative cache (errorTtl), which retains the failure for a
|
|
607
|
-
bounded window (see retainErroredEntry). Mirrors fireRefetch, which guards
|
|
608
|
-
revalidation results with the same `!result.ok` check.
|
|
609
|
-
*/
|
|
610
|
-
if (result instanceof Response && !result.ok) {
|
|
611
|
-
retainErroredEntry(store, entry, options, result.status, result)
|
|
612
|
-
return
|
|
613
|
-
}
|
|
614
|
-
/*
|
|
615
|
-
A post-invalidate reload registers with refreshing=true; an invalidation
|
|
616
|
-
firing while it was in flight parked its refetch on policy.pending
|
|
617
|
-
(fireRefetch bails when refreshing). This settle path — not fireRefetch —
|
|
618
|
-
cleared the flag, so drain the parked refetch here or it's lost and the
|
|
619
|
-
entry keeps data that predates the invalidation.
|
|
620
|
-
*/
|
|
621
|
-
if (entry.invalidation?.pending) {
|
|
622
|
-
reschedulePendingRefetch(store, entry, entry.invalidation)
|
|
623
|
-
}
|
|
624
|
-
/*
|
|
625
|
-
Smart retained read: the display value is kept unconditionally — never
|
|
626
|
-
hard-evicted on settle. ttl marks a staleness deadline (the next read past
|
|
627
|
-
it revalidates in the background, stale stays visible, refreshing() true)
|
|
628
|
-
instead of eviction; ttl 0/undefined retain with no staleness clock.
|
|
629
|
-
*/
|
|
630
|
-
if (entry.retain) {
|
|
631
|
-
materializeRetained(store, entry, result)
|
|
632
|
-
if (ttl !== undefined && ttl > 0) {
|
|
633
|
-
stampStaleDeadline(entry, ttl)
|
|
634
|
-
}
|
|
635
|
-
return
|
|
636
|
-
}
|
|
637
|
-
if (ttl === 0) {
|
|
638
|
-
if (!keepZeroTtlForRequest) {
|
|
639
|
-
deleteIfCurrent()
|
|
640
|
-
}
|
|
641
|
-
return
|
|
642
|
-
}
|
|
643
|
-
if (ttl !== undefined) {
|
|
644
|
-
armTtlExpiry(store, entry, ttl)
|
|
645
|
-
}
|
|
646
|
-
},
|
|
647
|
-
(error) => {
|
|
648
|
-
/* A network-level fault (fetch rejects — no Response, so no status/Retry-After):
|
|
649
|
-
negative-cache it under the status-0 window if opted in, else evict-and-retry. */
|
|
650
|
-
retainErroredEntry(
|
|
651
|
-
store,
|
|
652
|
-
entry,
|
|
653
|
-
options,
|
|
654
|
-
0,
|
|
655
|
-
error instanceof Error ? error : new Error(String(error)),
|
|
656
|
-
)
|
|
657
|
-
},
|
|
658
|
-
)
|
|
659
|
-
return entry
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
/*
|
|
663
|
-
Evicts `entry` unless a newer entry already owns the key (a concurrent
|
|
664
|
-
invalidate-and-reread must not lose its replacement). Disarms any policy timer
|
|
665
|
-
first — an armed timer would otherwise refetch a key that no longer exists.
|
|
666
|
-
*/
|
|
667
|
-
function evictIfCurrent(store: CacheStore, entry: CacheEntry): void {
|
|
668
|
-
if (store.entries.get(entry.key) === entry) {
|
|
669
|
-
clearTimeout(entry.invalidation?.timer)
|
|
670
|
-
store.entries.delete(entry.key)
|
|
671
|
-
store.markLifecycle(entry.key)
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
/*
|
|
676
|
-
A failed load is retained (negative cache), not evicted, only when the endpoint
|
|
677
|
-
opted in with `errorTtl` for this status — otherwise it evicts so the next read
|
|
678
|
-
retries (the default). With a window the failure is buffered so reads within it
|
|
679
|
-
re-surface it with no network: a Response is stored as a pristine clone the read
|
|
680
|
-
path re-clones per serve (never consuming errorResult itself), a network Error is
|
|
681
|
-
stored as-is and re-rejected. `armTtlExpiry` hard-evicts at the deadline, so the
|
|
682
|
-
next read retries. A `Retry-After` header overrides the configured window as the
|
|
683
|
-
authoritative delay.
|
|
684
|
-
*/
|
|
685
|
-
function retainErroredEntry(
|
|
686
|
-
store: CacheStore,
|
|
687
|
-
entry: CacheEntry,
|
|
688
|
-
options: CacheOptions | undefined,
|
|
689
|
-
status: number,
|
|
690
|
-
failure: Response | Error,
|
|
691
|
-
): void {
|
|
692
|
-
const configured = errorTtlFor(options, status)
|
|
693
|
-
/* Not opted in for this status → default evict-and-retry (Retry-After is honoured
|
|
694
|
-
only under an explicit errorTtl, so no existing endpoint's behaviour shifts). */
|
|
695
|
-
if (configured === undefined) {
|
|
696
|
-
evictIfCurrent(store, entry)
|
|
697
|
-
return
|
|
698
|
-
}
|
|
699
|
-
const window =
|
|
700
|
-
failure instanceof Response ? (retryAfterMs(failure.headers) ?? configured) : configured
|
|
701
|
-
if (window <= 0) {
|
|
702
|
-
evictIfCurrent(store, entry)
|
|
703
|
-
return
|
|
704
|
-
}
|
|
705
|
-
if (store.entries.get(entry.key) !== entry) {
|
|
706
|
-
return
|
|
707
|
-
}
|
|
708
|
-
entry.errorResult = failure instanceof Response ? failure.clone() : failure
|
|
709
|
-
entry.settled = true
|
|
710
|
-
armTtlExpiry(store, entry, window)
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
/* Resolves the endpoint's `errorTtl` against a failed status: a number applies to
|
|
714
|
-
any status, a function returns a per-status window (or undefined to keep the
|
|
715
|
-
immediate-retry default for that status). `status` is 0 for a network fault. */
|
|
716
|
-
function errorTtlFor(options: CacheOptions | undefined, status: number): number | undefined {
|
|
717
|
-
const policy = options?.errorTtl
|
|
718
|
-
if (typeof policy === 'function') {
|
|
719
|
-
return policy(status)
|
|
720
|
-
}
|
|
721
|
-
return policy
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
/* Parses a `Retry-After` header to ms — a delta-seconds integer or an HTTP-date —
|
|
725
|
-
clamped to >= 0. Returns undefined when absent or unparseable so the caller falls
|
|
726
|
-
back to the configured errorTtl. */
|
|
727
|
-
function retryAfterMs(headers: Headers): number | undefined {
|
|
728
|
-
const value = headers.get('retry-after')
|
|
729
|
-
if (value === null) {
|
|
730
|
-
return undefined
|
|
731
|
-
}
|
|
732
|
-
const seconds = Number(value)
|
|
733
|
-
if (Number.isFinite(seconds)) {
|
|
734
|
-
return seconds > 0 ? seconds * 1000 : 0
|
|
735
|
-
}
|
|
736
|
-
const when = Date.parse(value)
|
|
737
|
-
if (Number.isNaN(when)) {
|
|
738
|
-
return undefined
|
|
739
|
-
}
|
|
740
|
-
const delta = when - Date.now()
|
|
741
|
-
return delta > 0 ? delta : 0
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
/* Arms the ttl > 0 expiry sweep; `expiresAt` re-checks at fire time so a refreshed deadline survives. */
|
|
745
|
-
function armTtlExpiry(store: CacheStore, entry: CacheEntry, ttl: number): void {
|
|
746
|
-
entry.expiresAt = Date.now() + ttl
|
|
747
|
-
scheduleTtlSweep(store, entry)
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
/* setTimeout clamps a delay beyond 2^31-1 ms (~24.8 days) to ~1ms, which would
|
|
751
|
-
fire the sweep instantly, find the deadline unexpired, and never re-arm —
|
|
752
|
-
the entry would live forever. Chain capped hops until the deadline is in
|
|
753
|
-
reach; each hop bails once a newer entry owns the key. */
|
|
754
|
-
const MAX_TIMEOUT_DELAY = 2147483647
|
|
755
|
-
|
|
756
|
-
function scheduleTtlSweep(store: CacheStore, entry: CacheEntry): void {
|
|
757
|
-
if (store.entries.get(entry.key) !== entry) {
|
|
758
|
-
return
|
|
759
|
-
}
|
|
760
|
-
const remaining = (entry.expiresAt ?? 0) - Date.now()
|
|
761
|
-
if (remaining > MAX_TIMEOUT_DELAY) {
|
|
762
|
-
setTimeout(() => scheduleTtlSweep(store, entry), MAX_TIMEOUT_DELAY).unref?.()
|
|
763
|
-
return
|
|
764
|
-
}
|
|
765
|
-
setTimeout(() => {
|
|
766
|
-
if ((entry.expiresAt ?? 0) <= Date.now()) {
|
|
767
|
-
evictIfCurrent(store, entry)
|
|
768
|
-
}
|
|
769
|
-
}, remaining).unref?.()
|
|
770
|
-
}
|
|
771
|
-
|
|
772
|
-
/*
|
|
773
|
-
Stamps the smart-read staleness deadline. Revalidation is access-triggered, NOT
|
|
774
|
-
timer-driven: once `expiresAt` has passed, the NEXT read of the entry (see the
|
|
775
|
-
staleness branch in readThrough) schedules a background revalidation — the stale
|
|
776
|
-
value stays visible, refreshing() flips true, and fireRefetch re-stamps a fresh
|
|
777
|
-
deadline on success. No `setTimeout`, so an entry no reader touches never refetches
|
|
778
|
-
on its own — no background polling accretes across a session.
|
|
779
|
-
*/
|
|
780
|
-
function stampStaleDeadline(entry: CacheEntry, ttl: number): void {
|
|
781
|
-
entry.expiresAt = Date.now() + ttl
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
/*
|
|
785
|
-
Decodes a retained read's Response onto entry.value so peek() can read the current
|
|
786
|
-
value synchronously, and reads take the warm (cloned) path. Client-only: on the
|
|
787
|
-
server the SSR snapshot serializer owns value materialization (from the response
|
|
788
|
-
body it inlines), so leaving entry.value untouched there keeps the snapshot path
|
|
789
|
-
unchanged. Async decode (a microtask); markLifecycle re-runs a peek() scope once
|
|
790
|
-
the value lands. A non-Response (a producer retain — not currently reachable) is
|
|
791
|
-
stored as-is.
|
|
792
|
-
*/
|
|
793
|
-
function materializeRetained(store: CacheStore, entry: CacheEntry, result: unknown): void {
|
|
794
|
-
if (typeof window === 'undefined') {
|
|
795
|
-
return
|
|
796
|
-
}
|
|
797
|
-
if (result instanceof Response) {
|
|
798
|
-
decodeResponse(result.clone()).then(
|
|
799
|
-
(value) => {
|
|
800
|
-
/* Only if this entry still owns the key and hasn't been re-mutated meanwhile. */
|
|
801
|
-
if (store.entries.get(entry.key) === entry) {
|
|
802
|
-
entry.value = value
|
|
803
|
-
store.markLifecycle(entry.key)
|
|
804
|
-
}
|
|
805
|
-
},
|
|
806
|
-
() => undefined,
|
|
807
|
-
)
|
|
808
|
-
return
|
|
809
|
-
}
|
|
810
|
-
entry.value = result
|
|
811
|
-
store.markLifecycle(entry.key)
|
|
812
|
-
}
|
|
813
|
-
|
|
814
|
-
/*
|
|
815
|
-
Mirrors tagEntry/attachPolicy for retention: a hydrated snapshot entry ships
|
|
816
|
-
without its wrap options (they live at call sites, not on the wire), so the
|
|
817
|
-
first read adopts its call site's ttl declaration. Omitted = forever, exactly
|
|
818
|
-
as shipped; ttl > 0 = the expiry clock starts at this read; ttl = 0 = the warm
|
|
819
|
-
value exists only to complete the hydration render — the SSR request's atomic
|
|
820
|
-
unit ends here — so eviction is deferred one macrotask (every reader in the
|
|
821
|
-
same hydration pass still gets the warm value, no invalidate event fires, and
|
|
822
|
-
the already-painted DOM stays put) and the next read fetches live. The first
|
|
823
|
-
reader consumes the flag, so its declaration wins; live entries never carry
|
|
824
|
-
the flag and keep the ttl they registered with.
|
|
825
|
-
*/
|
|
826
|
-
function adoptTtl(
|
|
827
|
-
store: CacheStore,
|
|
828
|
-
entry: CacheEntry,
|
|
829
|
-
options: CacheOptions | undefined,
|
|
830
|
-
retain: boolean,
|
|
831
|
-
): void {
|
|
832
|
-
if (entry.hydrated !== true) {
|
|
833
|
-
return
|
|
834
|
-
}
|
|
835
|
-
entry.hydrated = false
|
|
836
|
-
/* A smart read adopting a hydrated entry retains it and stamps the staleness
|
|
837
|
-
deadline, mirroring registerEntry's retain branch — never the hard-evict path. */
|
|
838
|
-
if (retain) {
|
|
839
|
-
entry.retain = true
|
|
840
|
-
const ttl = options?.ttl
|
|
841
|
-
entry.ttl = ttl
|
|
842
|
-
if (ttl !== undefined && ttl > 0) {
|
|
843
|
-
stampStaleDeadline(entry, ttl)
|
|
844
|
-
}
|
|
845
|
-
return
|
|
846
|
-
}
|
|
847
|
-
const ttl = options?.ttl
|
|
848
|
-
if (ttl === undefined) {
|
|
849
|
-
return
|
|
850
|
-
}
|
|
851
|
-
entry.ttl = ttl
|
|
852
|
-
if (ttl === 0) {
|
|
853
|
-
setTimeout(() => evictIfCurrent(store, entry), 0).unref?.()
|
|
854
|
-
return
|
|
855
|
-
}
|
|
856
|
-
armTtlExpiry(store, entry, ttl)
|
|
857
|
-
}
|
|
858
|
-
|
|
859
|
-
/*
|
|
860
|
-
Returns a promise that resolves to a fresh clone of the underlying Response.
|
|
861
|
-
Multiple readers can each consume the body independently — the stored
|
|
862
|
-
promise's Response is never consumed directly, so clones always succeed.
|
|
863
|
-
*/
|
|
864
|
-
function shareable(promise: Promise<Response>): Promise<Response> {
|
|
865
|
-
return promise.then((response) => response.clone())
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
/*
|
|
869
|
-
Invalidates every entry matching the selector (see selectorMatcher) across both
|
|
870
|
-
the request/tab store and the process-level store, and notifies readers.
|
|
871
|
-
`args` narrows a fn selector to exactly that call's entry — derived through
|
|
872
|
-
the same encoders the read path uses, so other args variants stay warm. An entry
|
|
873
|
-
with a refetch policy is kept and its refetch coalesced (stale served
|
|
874
|
-
until it resolves); every other match is dropped so the next read refetches —
|
|
875
|
-
its key recorded in pendingRefresh so that read reports as a reload (refreshing())
|
|
876
|
-
rather than a first-ever load. An empty or unmatched selector is a no-op on the
|
|
877
|
-
cache; the lifecycle ping still fires but recomputes pending() to the same value.
|
|
878
|
-
*/
|
|
879
|
-
function invalidate<Args, Return>(arg?: CacheSelector<Args, Return>, args?: Args): void {
|
|
880
|
-
/* Resolve the fn-selector prefix once; the matcher, the label, and the exact-key
|
|
881
|
-
fast path all consume it. */
|
|
882
|
-
const prefix = selectorPrefix(arg, args)
|
|
883
|
-
invalidateMatching(
|
|
884
|
-
selectorMatcher(arg, args, prefix),
|
|
885
|
-
selectorLabel(arg, args, prefix),
|
|
886
|
-
prefix,
|
|
887
|
-
exactSelectorKey(arg, args, prefix),
|
|
888
|
-
)
|
|
889
|
-
}
|
|
890
|
-
|
|
891
|
-
/*
|
|
892
|
-
The single entry key a `fn + args` selector targets: args narrows the match to one
|
|
893
|
-
call, so the resolved prefix IS the exact key — the apply loops can `Map.get` it
|
|
894
|
-
directly instead of scanning every store. undefined for an all / bare-fn-prefix /
|
|
895
|
-
tag selector (which may match many entries) so those still scan, and for a producer
|
|
896
|
-
never cached (prefix undefined) whose scan matches nothing anyway.
|
|
897
|
-
*/
|
|
898
|
-
function exactSelectorKey<Args, Return>(
|
|
899
|
-
arg: CacheSelector<Args, Return> | undefined,
|
|
900
|
-
args: Args | undefined,
|
|
901
|
-
prefix: string | undefined,
|
|
902
|
-
): string | undefined {
|
|
903
|
-
return typeof arg === 'function' && args !== undefined ? prefix : undefined
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
/*
|
|
907
|
-
The ONE per-store selection dispatch every selector-driven verb runs through: an exact
|
|
908
|
-
key (a fn + args selector, from exactSelectorKey) picks its single candidate via a
|
|
909
|
-
direct Map.get instead of scanning; any other selector scans the store against
|
|
910
|
-
`matches`. Shared so the fast path and the scan can't diverge across
|
|
911
|
-
invalidate / refresh / amend (ADR-0041).
|
|
912
|
-
*/
|
|
913
|
-
function applyToMatching(
|
|
914
|
-
store: CacheStore,
|
|
915
|
-
exactKey: string | undefined,
|
|
916
|
-
matches: (entry: CacheEntry) => boolean,
|
|
917
|
-
apply: (entry: CacheEntry) => void,
|
|
918
|
-
): void {
|
|
919
|
-
if (exactKey !== undefined) {
|
|
920
|
-
const entry = store.entries.get(exactKey)
|
|
921
|
-
if (entry !== undefined) {
|
|
922
|
-
apply(entry)
|
|
923
|
-
}
|
|
924
|
-
return
|
|
925
|
-
}
|
|
926
|
-
/* Deleting the current entry mid-iteration is spec-safe on a Map; no snapshot needed. */
|
|
927
|
-
for (const entry of store.entries.values()) {
|
|
928
|
-
if (matches(entry)) {
|
|
929
|
-
apply(entry)
|
|
930
|
-
}
|
|
931
|
-
}
|
|
932
|
-
}
|
|
933
|
-
|
|
934
|
-
/*
|
|
935
|
-
The per-entry drop/refetch decision of invalidate() — the single seam so the full
|
|
936
|
-
scan and the exact-key fast path can't diverge (ADR-0041). A refetch-policy entry is
|
|
937
|
-
kept and its refetch coalesced; every other match is dropped so the next read reloads.
|
|
938
|
-
*/
|
|
939
|
-
function invalidateEntry(
|
|
940
|
-
store: CacheStore,
|
|
941
|
-
entry: CacheEntry,
|
|
942
|
-
matched: string[],
|
|
943
|
-
affected: string[],
|
|
944
|
-
): void {
|
|
945
|
-
matched.push(entry.key)
|
|
946
|
-
if (entry.invalidation) {
|
|
947
|
-
scheduleInvalidationRefetch(store, entry)
|
|
948
|
-
} else {
|
|
949
|
-
store.entries.delete(entry.key)
|
|
950
|
-
/* Flag the next read a reload (refreshing()) — but only if a reader is
|
|
951
|
-
holding the value now; with none on screen the next read is a first
|
|
952
|
-
load, and an ungated add would linger forever on the tab store. */
|
|
953
|
-
if (store.hasReader(entry.key)) {
|
|
954
|
-
store.pendingRefresh.add(entry.key)
|
|
955
|
-
}
|
|
956
|
-
affected.push(entry.key)
|
|
957
|
-
}
|
|
958
|
-
}
|
|
959
|
-
|
|
960
|
-
/*
|
|
961
|
-
The store-loop body of invalidate(), driven by a raw entry predicate rather than a
|
|
962
|
-
selector — a local invalidate() and a wire-driven one (a server broadcast decoded via
|
|
963
|
-
matcherFromEnvelope) share the per-entry `invalidateEntry` seam and can't diverge
|
|
964
|
-
(ADR-0041). `label` feeds the cycle tripwire; `prefix` (undefined for a tag selector)
|
|
965
|
-
resets recorded rpc errors for the selector. `exactKey` (a fn + args selector's one
|
|
966
|
-
key, from exactSelectorKey) picks that entry directly instead of scanning; the
|
|
967
|
-
wire-driven path passes none and scans as before.
|
|
968
|
-
*/
|
|
969
|
-
function invalidateMatching(
|
|
970
|
-
matches: (entry: CacheEntry) => boolean,
|
|
971
|
-
label: string,
|
|
972
|
-
prefix: string | undefined,
|
|
973
|
-
exactKey?: string,
|
|
974
|
-
): void {
|
|
975
|
-
invalidateTripwire(label)
|
|
976
|
-
/* Reset any recorded rpc errors for this selector too (independent of cache entries — a
|
|
977
|
-
bare call that errored never became one). Only fn selectors resolve a prefix. */
|
|
978
|
-
if (prefix !== undefined) {
|
|
979
|
-
rpcErrorRegistry.clearMatching(prefix)
|
|
980
|
-
}
|
|
981
|
-
for (const store of cacheStores()) {
|
|
982
|
-
const matched: string[] = []
|
|
983
|
-
const affected: string[] = []
|
|
984
|
-
applyToMatching(store, exactKey, matches, (entry) =>
|
|
985
|
-
invalidateEntry(store, entry, matched, affected),
|
|
986
|
-
)
|
|
987
|
-
/* Every match changed state (probes re-derive); only the dropped subset
|
|
988
|
-
changed its visible value (readers re-read) — swr matches stay put. */
|
|
989
|
-
notify(store, matched, affected)
|
|
990
|
-
}
|
|
991
|
-
}
|
|
992
|
-
|
|
993
|
-
/*
|
|
994
|
-
Human-readable selector identity for the tripwire and cache.on coverage: the
|
|
995
|
-
key prefix for fn selectors — the exact key when args narrow it — falling
|
|
996
|
-
back to the function's name for a producer never cached, the tag list for
|
|
997
|
-
a `{ tags }` selector, `*` for the bare form.
|
|
998
|
-
*/
|
|
999
|
-
function selectorLabel<Args, Return>(
|
|
1000
|
-
arg?: CacheSelector<Args, Return>,
|
|
1001
|
-
args?: Args,
|
|
1002
|
-
prefix?: string,
|
|
1003
|
-
): string {
|
|
1004
|
-
if (arg === undefined) {
|
|
1005
|
-
return '*'
|
|
1006
|
-
}
|
|
1007
|
-
if (typeof arg === 'function') {
|
|
1008
|
-
return prefix ?? selectorPrefix(arg, args) ?? (arg.name || 'anonymous producer')
|
|
1009
|
-
}
|
|
1010
|
-
return `tags: ${[...toTagSet(arg.tags ?? [])].join(', ')}`
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1013
|
-
cache.invalidate = invalidate
|
|
1014
|
-
cache.invalidateMatching = invalidateMatching
|
|
1015
|
-
|
|
1016
|
-
/*
|
|
1017
|
-
The smart-call refetch: refetches every entry matching the selector, keeping the
|
|
1018
|
-
stale value visible (refreshing() true) until the fresh value swaps in — never
|
|
1019
|
-
blanks. This is the old invalidate reborn as *refetch*: because SWR retains the
|
|
1020
|
-
value, there is no "invalidate that drops to pending" for the smart call. Follows
|
|
1021
|
-
invalidate's exact selector grammar (fn / fn+args / { tags } / bare = all).
|
|
1022
|
-
|
|
1023
|
-
Only a match with a live reader refetches: refresh keeps the stale value visible
|
|
1024
|
-
until the fresh one swaps in, and with no reader on screen there is nothing to
|
|
1025
|
-
swap into — so a match whose reactive scope has torn down ("no longer has
|
|
1026
|
-
listeners") drops instead of firing a wasted network refetch, and the next read
|
|
1027
|
-
reloads it fresh.
|
|
1028
|
-
|
|
1029
|
-
A smart-read match already carries an invalidation policy, so it routes straight
|
|
1030
|
-
through scheduleInvalidationRefetch (throttle/debounce-honouring). A policy-less
|
|
1031
|
-
remote match (an explicit cache() entry, or a hydrated one) gets a refetch armed
|
|
1032
|
-
on the fly by replaying its stored Request. A policy-less producer match has no
|
|
1033
|
-
way to re-run, so it drops (the next read reloads) — the invalidate fallback.
|
|
1034
|
-
*/
|
|
1035
|
-
function refresh<Args, Return>(arg?: CacheSelector<Args, Return>, args?: Args): void {
|
|
1036
|
-
const prefix = selectorPrefix(arg, args)
|
|
1037
|
-
refreshMatching(
|
|
1038
|
-
selectorMatcher(arg, args, prefix),
|
|
1039
|
-
selectorLabel(arg, args, prefix),
|
|
1040
|
-
prefix,
|
|
1041
|
-
exactSelectorKey(arg, args, prefix),
|
|
1042
|
-
)
|
|
1043
|
-
}
|
|
1044
|
-
|
|
1045
|
-
/*
|
|
1046
|
-
The per-entry refetch/drop decision of refresh() — the single seam shared by the full
|
|
1047
|
-
scan and the exact-key fast path (ADR-0041). Only a match with a live reader refetches;
|
|
1048
|
-
a reader-less match drops so the next read reloads.
|
|
1049
|
-
*/
|
|
1050
|
-
function refreshEntry(
|
|
1051
|
-
store: CacheStore,
|
|
1052
|
-
entry: CacheEntry,
|
|
1053
|
-
matched: string[],
|
|
1054
|
-
affected: string[],
|
|
1055
|
-
): void {
|
|
1056
|
-
matched.push(entry.key)
|
|
1057
|
-
/* No live reader is holding this key — its reactive scope has torn down (or
|
|
1058
|
-
it was never read reactively and already dropped). A refresh has no
|
|
1059
|
-
on-screen value to keep-stale-and-swap, so firing the network now is
|
|
1060
|
-
wasted work that may be stale again before anything shows it. Drop the
|
|
1061
|
-
entry so the next read reloads fresh instead — the same lazy path a
|
|
1062
|
-
reader-less invalidate() takes. */
|
|
1063
|
-
if (!store.hasReader(entry.key)) {
|
|
1064
|
-
store.entries.delete(entry.key)
|
|
1065
|
-
return
|
|
1066
|
-
}
|
|
1067
|
-
/* Arm a refetch on the fly for a policy-less remote entry by replaying its
|
|
1068
|
-
stored Request — so a refresh always refetches-and-swaps, never blanks. */
|
|
1069
|
-
if (entry.invalidation === undefined && entry.request !== undefined) {
|
|
1070
|
-
const request = entry.request
|
|
1071
|
-
entry.invalidation = { refetch: () => fetch(request.clone()) }
|
|
1072
|
-
}
|
|
1073
|
-
if (entry.invalidation !== undefined) {
|
|
1074
|
-
scheduleInvalidationRefetch(store, entry)
|
|
1075
|
-
} else {
|
|
1076
|
-
/* No policy, no request (a producer never cached with a refetch window): drop so the
|
|
1077
|
-
next read reloads. A reader is holding it (checked above), so flag the
|
|
1078
|
-
next read a reload (refreshing()). */
|
|
1079
|
-
store.entries.delete(entry.key)
|
|
1080
|
-
store.pendingRefresh.add(entry.key)
|
|
1081
|
-
affected.push(entry.key)
|
|
1082
|
-
}
|
|
1083
|
-
}
|
|
1084
|
-
|
|
1085
|
-
/*
|
|
1086
|
-
The store-loop body of refresh(), driven by a raw entry predicate — the refetch
|
|
1087
|
-
analogue of invalidateMatching, so a local refresh() and a wire-driven one share the
|
|
1088
|
-
per-entry `refreshEntry` seam (ADR-0041). `exactKey` (a fn + args selector's one key)
|
|
1089
|
-
picks that entry directly instead of scanning; the wire-driven path passes none.
|
|
1090
|
-
*/
|
|
1091
|
-
function refreshMatching(
|
|
1092
|
-
matches: (entry: CacheEntry) => boolean,
|
|
1093
|
-
label: string,
|
|
1094
|
-
prefix: string | undefined,
|
|
1095
|
-
exactKey?: string,
|
|
1096
|
-
): void {
|
|
1097
|
-
invalidateTripwire(label)
|
|
1098
|
-
if (prefix !== undefined) {
|
|
1099
|
-
rpcErrorRegistry.clearMatching(prefix)
|
|
1100
|
-
}
|
|
1101
|
-
for (const store of cacheStores()) {
|
|
1102
|
-
const matched: string[] = []
|
|
1103
|
-
const affected: string[] = []
|
|
1104
|
-
applyToMatching(store, exactKey, matches, (entry) =>
|
|
1105
|
-
refreshEntry(store, entry, matched, affected),
|
|
1106
|
-
)
|
|
1107
|
-
/* Mark the whole match set (probes re-derive); emit only the dropped subset — the
|
|
1108
|
-
refetched entries emit when their fresh value lands (fireRefetch). */
|
|
1109
|
-
notify(store, matched, affected)
|
|
1110
|
-
}
|
|
1111
|
-
}
|
|
1112
|
-
|
|
1113
|
-
cache.refresh = refresh
|
|
1114
|
-
cache.refreshMatching = refreshMatching
|
|
1115
|
-
|
|
1116
|
-
/*
|
|
1117
|
-
Local value mutation: replaces the retained value of every entry matching the
|
|
1118
|
-
selector via `updater(current)`, re-renders readers, and fires NO network — the
|
|
1119
|
-
optimistic-update / real-time primitive (feed a socket frame straight into a
|
|
1120
|
-
cached list). The next value is stored onto `entry.value`, which the read path
|
|
1121
|
-
serves warm (cloned per read), so it persists across reads until a refresh /
|
|
1122
|
-
invalidate replaces the entry. `current` comes from `entry.value` when already
|
|
1123
|
-
materialized, else decoded from the settled/in-flight promise (async — readers
|
|
1124
|
-
re-render when the amend lands). Follows the selector grammar, but only fn / args
|
|
1125
|
-
/ tags select a value to mutate; a not-yet-read key has nothing to amend.
|
|
1126
|
-
*/
|
|
1127
|
-
function amend<Args, Return>(
|
|
1128
|
-
arg: CacheSelector<Args, Return>,
|
|
1129
|
-
args: Args | undefined,
|
|
1130
|
-
updater: (current: Return) => Return,
|
|
1131
|
-
isValue: boolean,
|
|
1132
|
-
): void {
|
|
1133
|
-
const prefix = selectorPrefix(arg, args)
|
|
1134
|
-
const exactKey = exactSelectorKey(arg, args, prefix)
|
|
1135
|
-
const matches = selectorMatcher(arg, args, prefix)
|
|
1136
|
-
/* The exact-key arm is the optimistic-update / socket-frame path, potentially once
|
|
1137
|
-
per frame — a direct Map.get through the shared dispatch, no scan. */
|
|
1138
|
-
for (const store of cacheStores()) {
|
|
1139
|
-
applyToMatching(store, exactKey, matches, (entry) =>
|
|
1140
|
-
applyAmend(store, entry, updater as (current: unknown) => unknown, isValue),
|
|
1141
|
-
)
|
|
1142
|
-
}
|
|
1143
|
-
}
|
|
1144
|
-
|
|
1145
|
-
cache.amend = amend
|
|
1146
|
-
|
|
1147
|
-
/*
|
|
1148
|
-
Synchronous, non-triggering value probe: returns the currently-retained value for
|
|
1149
|
-
a call, or undefined when nothing is retained (no entry, or not yet settled). Never
|
|
1150
|
-
invokes — reading it opens no fetch. Reactive: it subscribes the key AND taps the
|
|
1151
|
-
key's lifecycle channel (the exact key is a one-entry prefix, same as
|
|
1152
|
-
pending(fn, args)) so a state.computed / on / template scope re-runs both when the
|
|
1153
|
-
value changes (invalidate, amend) and when a retained value lands —
|
|
1154
|
-
materializeRetained's async decode signals only markLifecycle, no invalidate event,
|
|
1155
|
-
so without the lifecycle tap a scope that read undefined would never see the value
|
|
1156
|
-
arrive. Outside a tracking scope it is a one-shot snapshot. Returns a clone (like
|
|
1157
|
-
the warm read path) so a caller mutating it can't corrupt the retained value.
|
|
1158
|
-
`peek(sub)` for a subscribable is wired on the socket side.
|
|
1159
|
-
*/
|
|
1160
|
-
function peek<Args, Return>(
|
|
1161
|
-
fn: RemoteFunction<Args, Return> | RawRemoteFunction<Args> | Producer<Args, Return>,
|
|
1162
|
-
args?: Args,
|
|
1163
|
-
): Return | undefined {
|
|
1164
|
-
const isRemote = REMOTE_FUNCTION in fn
|
|
1165
|
-
const rawFn = !isRemote
|
|
1166
|
-
? undefined
|
|
1167
|
-
: 'raw' in fn
|
|
1168
|
-
? (fn as RemoteFunction<Args, Return>).raw
|
|
1169
|
-
: (fn as RawRemoteFunction<Args>)
|
|
1170
|
-
const key = isRemote
|
|
1171
|
-
? // biome-ignore lint/style/noNonNullAssertion: rawFn is undefined only when !isRemote, so this branch has it
|
|
1172
|
-
keyForRemoteCall(rawFn!.method, rawFn!.url, args)
|
|
1173
|
-
: producerKey(fn as Producer<Args, Return>, args)
|
|
1174
|
-
const active = activeCacheStore()
|
|
1175
|
-
active.subscribe(key)
|
|
1176
|
-
active.trackLifecycle(key)
|
|
1177
|
-
let entry = active.entries.get(key)
|
|
1178
|
-
if (entry === undefined) {
|
|
1179
|
-
const shared = sharedCacheStore()
|
|
1180
|
-
shared.subscribe(key)
|
|
1181
|
-
shared.trackLifecycle(key)
|
|
1182
|
-
entry = shared.entries.get(key)
|
|
1183
|
-
}
|
|
1184
|
-
if (entry === undefined || entry.settled !== true || entry.value === undefined) {
|
|
1185
|
-
return undefined
|
|
1186
|
-
}
|
|
1187
|
-
/* SSR congruence: the server materializes no cache value, so server-side peek is
|
|
1188
|
-
uniformly undefined and the SSR render shows the fallback. Returning a snapshot-
|
|
1189
|
-
seeded warm value here — mid-hydration — would diverge from that server text and
|
|
1190
|
-
corrupt the claimed text node. Withhold it until the pass ends; the trackLifecycle
|
|
1191
|
-
tap above lets hydrationWindow.wake re-run this scope on the congruent value. */
|
|
1192
|
-
if (hydrationWindow.active) {
|
|
1193
|
-
return undefined
|
|
1194
|
-
}
|
|
1195
|
-
/* Revive structured fields after cloning: the clone is the honest-JSON wire form, and revive
|
|
1196
|
-
turns a wire array into its declared Set/Map and an ISO string into a Date — so peek matches
|
|
1197
|
-
fn(args) / cache(fn, args). A raw or producer read carries no plan → the clone passes through
|
|
1198
|
-
untouched (revive is a no-op on an undefined plan). */
|
|
1199
|
-
const plan =
|
|
1200
|
-
isRemote && 'raw' in fn
|
|
1201
|
-
? (fn as { outputWirePlan?: OutputWirePlan }).outputWirePlan
|
|
1202
|
-
: undefined
|
|
1203
|
-
return reviveWireOutput(cloneWarmValue(entry.value), plan) as Return
|
|
1204
|
-
}
|
|
1205
|
-
|
|
1206
|
-
cache.peek = peek
|
|
1207
|
-
|
|
1208
|
-
/*
|
|
1209
|
-
Applies one entry's amend: materialize the current decoded value (warm value if
|
|
1210
|
-
present, else decode the promise — a Response for a remote entry, cloned so the
|
|
1211
|
-
readers' own clones still succeed), run the updater, store it warm, and emit so
|
|
1212
|
-
readers re-read. Fire-and-forget on the async branch: amend() stays sync-return.
|
|
1213
|
-
*/
|
|
1214
|
-
function applyAmend(
|
|
1215
|
-
store: CacheStore,
|
|
1216
|
-
entry: CacheEntry,
|
|
1217
|
-
updater: (current: unknown) => unknown,
|
|
1218
|
-
isValue: boolean,
|
|
1219
|
-
): void {
|
|
1220
|
-
function apply(current: unknown): void {
|
|
1221
|
-
entry.value = updater(current)
|
|
1222
|
-
notify(store, [entry.key], [entry.key])
|
|
1223
|
-
}
|
|
1224
|
-
/* A value-form amend is current-independent (its updater ignores the argument), so set it
|
|
1225
|
-
directly and synchronously like the wire path (amendByKey) — never defer to the in-flight
|
|
1226
|
-
promise. Deferring would drop the value if that fetch rejects (the reject handler below
|
|
1227
|
-
swallows it), diverging local value-amend from the broadcast receive path. */
|
|
1228
|
-
if (isValue || entry.value !== undefined) {
|
|
1229
|
-
apply(entry.value)
|
|
1230
|
-
return
|
|
1231
|
-
}
|
|
1232
|
-
const currentValue =
|
|
1233
|
-
entry.request !== undefined
|
|
1234
|
-
? (entry.promise as Promise<Response>).then((response) =>
|
|
1235
|
-
decodeResponse(response.clone()),
|
|
1236
|
-
)
|
|
1237
|
-
: (entry.promise as Promise<unknown>)
|
|
1238
|
-
currentValue.then(apply, () => undefined)
|
|
1239
|
-
}
|
|
1240
|
-
|
|
1241
|
-
/*
|
|
1242
|
-
Wire-driven value apply (ADR-0043): set the retained value of the entry at an exact
|
|
1243
|
-
cache key and re-render its readers — the receive half of a server amend broadcast. A
|
|
1244
|
-
direct set, not the applyAmend materialize-current dance: the frame carries the
|
|
1245
|
-
authoritative value now, and the receiving subscriber is by construction reading this
|
|
1246
|
-
key. A key with no local entry is a no-op (nothing to amend).
|
|
1247
|
-
*/
|
|
1248
|
-
function amendByKey(key: string, value: unknown): void {
|
|
1249
|
-
for (const store of cacheStores()) {
|
|
1250
|
-
const entry = store.entries.get(key)
|
|
1251
|
-
if (entry !== undefined) {
|
|
1252
|
-
entry.value = value
|
|
1253
|
-
notify(store, [entry.key], [entry.key])
|
|
1254
|
-
}
|
|
1255
|
-
}
|
|
1256
|
-
}
|
|
1257
|
-
|
|
1258
|
-
cache.amendByKey = amendByKey
|
|
1259
|
-
|
|
1260
|
-
/*
|
|
1261
|
-
Event-driven cache maintenance: subscribes to a NamedAsyncIterable (socket or rpc
|
|
1262
|
-
stream) and runs `handler` once per frame — the declarative home for "this
|
|
1263
|
-
socket event stales that cached data", replacing the hand-rolled $effect +
|
|
1264
|
-
tail() + edge-detection pattern. Bare iteration means live frames only
|
|
1265
|
-
(ADR-0004): no replay seed, a frame is an event, nothing is retained.
|
|
1266
|
-
|
|
1267
|
-
Delivery is sequential: frame N+1 is not pulled until N's handler (sync or
|
|
1268
|
-
async) settles, so ordering holds and before/after work sits naturally
|
|
1269
|
-
between frames; a slow handler queues frames rather than racing itself.
|
|
1270
|
-
The context's `invalidate` is this binding's scoped copy — same grammar and
|
|
1271
|
-
effect as cache.invalidate, but each call is recorded in the binding's
|
|
1272
|
-
coverage set (attribution by function identity, so it survives awaits).
|
|
1273
|
-
|
|
1274
|
-
On a transport loss (the typed SocketDisconnectedError) frames may have been
|
|
1275
|
-
missed, and a missed frame is a missed invalidation — silently stale data. The
|
|
1276
|
-
binding can't know what it missed, so it conservatively re-invalidates its
|
|
1277
|
-
whole coverage set, then reopens the source (the channel's backoff owns retry
|
|
1278
|
-
timing); over-invalidating costs a refetch, never correctness. A handler
|
|
1279
|
-
throw is logged and the binding lives on — one bad frame must not detach
|
|
1280
|
-
freshness; a server error frame or clean end is terminal, mirroring tail.
|
|
1281
|
-
|
|
1282
|
-
No-op on the server (inert dispose): SSR can't hold a stream across the
|
|
1283
|
-
request boundary — bindings attach client-side, where the snapshot has
|
|
1284
|
-
already seeded the cache. Dispose aborts `signal`, stops delivery, and
|
|
1285
|
-
closes the subscription.
|
|
1286
|
-
*/
|
|
1287
|
-
function on<T>(
|
|
1288
|
-
source: NamedAsyncIterable<T>,
|
|
1289
|
-
handler: (frame: T, context: CacheOnContext) => void | Promise<void>,
|
|
1290
|
-
): () => void {
|
|
1291
|
-
if (typeof window === 'undefined') {
|
|
1292
|
-
return () => undefined
|
|
1293
|
-
}
|
|
1294
|
-
const controller = new AbortController()
|
|
1295
|
-
/* Coverage replays on reconnect; keyed by selector identity so repeats dedupe. */
|
|
1296
|
-
const coverage = new Map<string, () => void>()
|
|
1297
|
-
const context: CacheOnContext = {
|
|
1298
|
-
invalidate<Args, Return>(arg?: CacheSelector<Args, Return>, args?: Args): void {
|
|
1299
|
-
coverage.set(selectorLabel(arg, args), () => invalidate(arg, args))
|
|
1300
|
-
invalidate(arg, args)
|
|
1301
|
-
},
|
|
1302
|
-
signal: controller.signal,
|
|
1303
|
-
}
|
|
1304
|
-
/* Register-on-consume: consuming a named subscribable populates the probe registry so
|
|
1305
|
-
pending()/refreshing()/error()/done()(source) work — the stream-side analog of a call
|
|
1306
|
-
populating the cache store. Driven by this one loop, so watch(socket) / for-await all
|
|
1307
|
-
register through here. An unnamed source (rare) skips probe tracking. */
|
|
1308
|
-
const probe = source.name ? openStreamProbe(source.name) : undefined
|
|
1309
|
-
/* `let`: the reconnect path swaps in a fresh iterator; dispose closes the current one. */
|
|
1310
|
-
let iterator = source[Symbol.asyncIterator]()
|
|
1311
|
-
;(async () => {
|
|
1312
|
-
while (!controller.signal.aborted) {
|
|
1313
|
-
let next: IteratorResult<T>
|
|
1314
|
-
try {
|
|
1315
|
-
next = await iterator.next()
|
|
1316
|
-
} catch (error) {
|
|
1317
|
-
if (controller.signal.aborted) {
|
|
1318
|
-
return
|
|
1319
|
-
}
|
|
1320
|
-
if (error instanceof SocketDisconnectedError) {
|
|
1321
|
-
probe?.reconnecting()
|
|
1322
|
-
coverage.forEach((replay) => {
|
|
1323
|
-
replay()
|
|
1324
|
-
})
|
|
1325
|
-
iterator = source[Symbol.asyncIterator]()
|
|
1326
|
-
continue
|
|
1327
|
-
}
|
|
1328
|
-
probe?.errored(error instanceof Error ? error : new Error(String(error)))
|
|
1329
|
-
abideLog.error(error)
|
|
1330
|
-
return
|
|
1331
|
-
}
|
|
1332
|
-
if (controller.signal.aborted) {
|
|
1333
|
-
return
|
|
1334
|
-
}
|
|
1335
|
-
if (next.done === true) {
|
|
1336
|
-
probe?.done()
|
|
1337
|
-
return
|
|
1338
|
-
}
|
|
1339
|
-
probe?.frame()
|
|
1340
|
-
try {
|
|
1341
|
-
await handler(next.value, context)
|
|
1342
|
-
} catch (error) {
|
|
1343
|
-
abideLog.error(error)
|
|
1344
|
-
}
|
|
1345
|
-
}
|
|
1346
|
-
})()
|
|
1347
|
-
return () => {
|
|
1348
|
-
controller.abort()
|
|
1349
|
-
probe?.close()
|
|
1350
|
-
iterator.return?.(undefined)?.catch(() => undefined)
|
|
1351
|
-
}
|
|
1352
|
-
}
|
|
1353
|
-
|
|
1354
|
-
cache.on = on
|
|
1355
|
-
|
|
1356
|
-
/*
|
|
1357
|
-
Schedules a coalesced refetch per the entry's refetch policy. No window:
|
|
1358
|
-
fire immediately (throttle defaults to 0, so the leading-edge branch always
|
|
1359
|
-
takes). debounce: (re)arm a timer that fires after N ms of quiet. throttle: fire
|
|
1360
|
-
on the leading edge when a full window has elapsed since the last fire, else arm
|
|
1361
|
-
a single trailing timer for the remainder — so a continuous invalidation stream
|
|
1362
|
-
refetches at most once per window.
|
|
1363
|
-
*/
|
|
1364
|
-
function scheduleInvalidationRefetch(store: CacheStore, entry: CacheEntry): void {
|
|
1365
|
-
const policy = entry.invalidation
|
|
1366
|
-
if (!policy) {
|
|
1367
|
-
return
|
|
1368
|
-
}
|
|
1369
|
-
if (policy.debounce !== undefined) {
|
|
1370
|
-
clearTimeout(policy.timer)
|
|
1371
|
-
policy.timer = armTimer(store, entry, policy.debounce)
|
|
1372
|
-
return
|
|
1373
|
-
}
|
|
1374
|
-
const throttleMs = policy.throttle ?? 0
|
|
1375
|
-
const elapsed = Date.now() - (policy.lastFiredAt ?? Number.NEGATIVE_INFINITY)
|
|
1376
|
-
if (elapsed >= throttleMs) {
|
|
1377
|
-
fireRefetch(store, entry)
|
|
1378
|
-
return
|
|
1379
|
-
}
|
|
1380
|
-
if (policy.timer === undefined) {
|
|
1381
|
-
policy.timer = armTimer(store, entry, throttleMs - elapsed)
|
|
1382
|
-
}
|
|
1383
|
-
}
|
|
1384
|
-
|
|
1385
|
-
function armTimer(store: CacheStore, entry: CacheEntry, ms: number): ReturnType<typeof setTimeout> {
|
|
1386
|
-
const timer = setTimeout(() => {
|
|
1387
|
-
if (entry.invalidation) {
|
|
1388
|
-
entry.invalidation.timer = undefined
|
|
1389
|
-
}
|
|
1390
|
-
fireRefetch(store, entry)
|
|
1391
|
-
}, ms)
|
|
1392
|
-
timer.unref?.()
|
|
1393
|
-
return timer
|
|
1394
|
-
}
|
|
1395
|
-
|
|
1396
|
-
/*
|
|
1397
|
-
Runs the captured refetch once, keeping the stale value visible until it
|
|
1398
|
-
resolves, then swaps the fresh result in and notifies readers. A refetch already
|
|
1399
|
-
in flight is left to finish — the key is stable, so it already fetches the latest
|
|
1400
|
-
state. Failure arrives on either settle path: a remote refetch resolves with the
|
|
1401
|
-
Response even on an error status (fetch rejects only on network loss), a producer
|
|
1402
|
-
rejects. Both route to settleRefetchFailure — stale kept, except a 404 evicts.
|
|
1403
|
-
*/
|
|
1404
|
-
function fireRefetch(store: CacheStore, entry: CacheEntry): void {
|
|
1405
|
-
const policy = entry.invalidation
|
|
1406
|
-
if (!policy) {
|
|
1407
|
-
return
|
|
1408
|
-
}
|
|
1409
|
-
/* A refetch is already running: record the request so it re-fires on settle
|
|
1410
|
-
(the in-flight one may predate this newer invalidation) instead of dropping it. */
|
|
1411
|
-
if (entry.refreshing) {
|
|
1412
|
-
policy.pending = true
|
|
1413
|
-
return
|
|
1414
|
-
}
|
|
1415
|
-
entry.refreshing = true
|
|
1416
|
-
policy.lastFiredAt = Date.now()
|
|
1417
|
-
/* Mark, don't emit: refreshing() re-derives when revalidation begins, but the
|
|
1418
|
-
stale value is still on screen — the settle handlers emit once it lands. */
|
|
1419
|
-
notify(store, [entry.key], [])
|
|
1420
|
-
const inflight = policy.refetch()
|
|
1421
|
-
inflight.then(
|
|
1422
|
-
(result) => {
|
|
1423
|
-
entry.refreshing = false
|
|
1424
|
-
reschedulePendingRefetch(store, entry, policy)
|
|
1425
|
-
/* Dropped or replaced while in flight — discard this result. */
|
|
1426
|
-
if (store.entries.get(entry.key) !== entry) {
|
|
1427
|
-
return
|
|
1428
|
-
}
|
|
1429
|
-
if (result instanceof Response && !result.ok) {
|
|
1430
|
-
settleRefetchFailure(store, entry, result.status)
|
|
1431
|
-
return
|
|
1432
|
-
}
|
|
1433
|
-
entry.promise = inflight
|
|
1434
|
-
entry.value = undefined
|
|
1435
|
-
entry.settled = true
|
|
1436
|
-
/* Re-materialize the retained value from the fresh Response so peek() stays
|
|
1437
|
-
current after a background revalidation. */
|
|
1438
|
-
if (entry.retain) {
|
|
1439
|
-
materializeRetained(store, entry, result)
|
|
1440
|
-
}
|
|
1441
|
-
/* Restart the freshness clock from the revalidation — without this the
|
|
1442
|
-
entry keeps its original expiresAt and would read as stale (or be evicted
|
|
1443
|
-
at the old deadline) despite holding fresh data. Mirrors registerEntry's
|
|
1444
|
-
settle path: a retained smart read re-stamps the staleness deadline (the
|
|
1445
|
-
next read past it revalidates), a windowed producer entry re-arms the eviction
|
|
1446
|
-
clock. */
|
|
1447
|
-
if (entry.ttl !== undefined && entry.ttl !== 0) {
|
|
1448
|
-
if (entry.retain) {
|
|
1449
|
-
stampStaleDeadline(entry, entry.ttl)
|
|
1450
|
-
} else {
|
|
1451
|
-
armTtlExpiry(store, entry, entry.ttl)
|
|
1452
|
-
}
|
|
1453
|
-
}
|
|
1454
|
-
/* Fresh value landed — mark and emit so readers re-read. */
|
|
1455
|
-
notify(store, [entry.key], [entry.key])
|
|
1456
|
-
},
|
|
1457
|
-
(error) => {
|
|
1458
|
-
entry.refreshing = false
|
|
1459
|
-
reschedulePendingRefetch(store, entry, policy)
|
|
1460
|
-
if (store.entries.get(entry.key) !== entry) {
|
|
1461
|
-
return
|
|
1462
|
-
}
|
|
1463
|
-
settleRefetchFailure(
|
|
1464
|
-
store,
|
|
1465
|
-
entry,
|
|
1466
|
-
error instanceof HttpError ? error.status : undefined,
|
|
1467
|
-
)
|
|
1468
|
-
},
|
|
1469
|
-
)
|
|
1470
|
-
}
|
|
1471
|
-
|
|
1472
|
-
/*
|
|
1473
|
-
Re-schedules a refetch requested while one was already in flight (fireRefetch
|
|
1474
|
-
recorded it on policy.pending). Runs after the in-flight refetch settles so the
|
|
1475
|
-
newer invalidation isn't lost; honours the throttle/debounce window since
|
|
1476
|
-
lastFiredAt was just stamped. No-op if the entry was dropped or replaced.
|
|
1477
|
-
*/
|
|
1478
|
-
function reschedulePendingRefetch(
|
|
1479
|
-
store: CacheStore,
|
|
1480
|
-
entry: CacheEntry,
|
|
1481
|
-
policy: NonNullable<CacheEntry['invalidation']>,
|
|
1482
|
-
): void {
|
|
1483
|
-
if (!policy.pending) {
|
|
1484
|
-
return
|
|
1485
|
-
}
|
|
1486
|
-
policy.pending = false
|
|
1487
|
-
if (store.entries.get(entry.key) === entry) {
|
|
1488
|
-
scheduleInvalidationRefetch(store, entry)
|
|
1489
|
-
}
|
|
1490
|
-
}
|
|
1491
|
-
|
|
1492
|
-
/*
|
|
1493
|
-
A failed revalidation keeps the stale entry — blanking data a reader is showing
|
|
1494
|
-
over a transient error would make every background refresh a risk. 404 is the
|
|
1495
|
-
exception: the resource is gone, so the retained value is a ghost an invalidation
|
|
1496
|
-
stream would refetch forever. Evict it exactly as invalidate() drops a policy-less
|
|
1497
|
-
entry (pendingRefresh marks the next read a reload; the notify re-runs readers),
|
|
1498
|
-
so a live read replaces it and surfaces the proper error once.
|
|
1499
|
-
*/
|
|
1500
|
-
function settleRefetchFailure(store: CacheStore, entry: CacheEntry, status?: number): void {
|
|
1501
|
-
if (status === 404) {
|
|
1502
|
-
evictIfCurrent(store, entry)
|
|
1503
|
-
/* Same reader-gating as invalidate: only flag a reload if one is on screen. */
|
|
1504
|
-
if (store.hasReader(entry.key)) {
|
|
1505
|
-
store.pendingRefresh.add(entry.key)
|
|
1506
|
-
}
|
|
1507
|
-
/* Value gone — mark and emit so the next read replaces it. */
|
|
1508
|
-
notify(store, [entry.key], [entry.key])
|
|
1509
|
-
return
|
|
1510
|
-
}
|
|
1511
|
-
/* Mark, don't emit: stale value kept, only the refreshing flag cleared. */
|
|
1512
|
-
notify(store, [entry.key], [])
|
|
1513
|
-
}
|
|
1514
|
-
|
|
1515
|
-
/* Folds new tags into an entry's existing set without duplicating them. */
|
|
1516
|
-
function mergeTags(existing: Set<string> | undefined, incoming: string[]): Set<string> {
|
|
1517
|
-
return new Set([...(existing ?? []), ...toTagSet(incoming)])
|
|
1518
|
-
}
|
|
1519
|
-
|
|
1520
|
-
/*
|
|
1521
|
-
Tags an existing entry with a read's tags so a later cache.invalidate({ tags })
|
|
1522
|
-
reaches entries hydrated from the SSR snapshot (which carry a value but no tags)
|
|
1523
|
-
without a refetch. Merges rather than replaces so a read tagging one group can't
|
|
1524
|
-
drop tags another read site already added; a no-op when the read passes no tags.
|
|
1525
|
-
*/
|
|
1526
|
-
function tagEntry(entry: CacheEntry, tags: CacheOptions['tags']): void {
|
|
1527
|
-
if (tags !== undefined) {
|
|
1528
|
-
entry.tags = mergeTags(entry.tags, tags)
|
|
1529
|
-
}
|
|
1530
|
-
}
|
|
1531
|
-
|
|
1532
|
-
/*
|
|
1533
|
-
Mirrors tagEntry for invalidate policies: a read declaring a policy arms an
|
|
1534
|
-
existing entry that lacks one. Hydrated snapshot entries carry a value but no
|
|
1535
|
-
refetch thunk — without this, the first invalidate after hydration would hard-
|
|
1536
|
-
drop the entry (a pending flash) instead of revalidating stale-in-place, and a
|
|
1537
|
-
policy-less first read would permanently win over a later read that declared
|
|
1538
|
-
one. An entry that already has a policy keeps it (first policy wins; the key
|
|
1539
|
-
is the same call, so the thunks are interchangeable).
|
|
1540
|
-
*/
|
|
1541
|
-
function attachPolicy(
|
|
1542
|
-
entry: CacheEntry,
|
|
1543
|
-
options: CacheOptions | undefined,
|
|
1544
|
-
refetch: () => Promise<unknown>,
|
|
1545
|
-
defaultOn: boolean,
|
|
1546
|
-
): void {
|
|
1547
|
-
/* A smart read hitting a bare existing entry (e.g. one an explicit cache()
|
|
1548
|
-
created first) adopts unconditional retention too. */
|
|
1549
|
-
if (defaultOn) {
|
|
1550
|
-
entry.retain = true
|
|
1551
|
-
}
|
|
1552
|
-
const policy = refetchWindow(options, defaultOn)
|
|
1553
|
-
if (entry.invalidation || !policy) {
|
|
1554
|
-
return
|
|
1555
|
-
}
|
|
1556
|
-
entry.invalidation = { refetch, throttle: policy.throttle, debounce: policy.debounce }
|
|
1557
|
-
}
|
|
1558
|
-
|
|
1559
|
-
/*
|
|
1560
|
-
The single notification seam, holding the cache's freshness invariant in one
|
|
1561
|
-
place instead of by hand at every mutation site. Two reader audiences, two
|
|
1562
|
-
channels: every key in `marked` had its state change, so the lifecycle channels
|
|
1563
|
-
fire and the pending()/refreshing() probes re-derive; only the keys in `emitted`
|
|
1564
|
-
had their VISIBLE value change, so the 'invalidate' event fires and the reading
|
|
1565
|
-
scope re-reads. The two sets diverge by design — a refetch start marks but does
|
|
1566
|
-
not emit (the stale value is still on screen), an invalidate-drop does both, an
|
|
1567
|
-
a keep-stale (refetch-policy) invalidate marks the whole match set while emitting only the dropped subset.
|
|
1568
|
-
The trailing store-wide mark fires even when nothing matched, so a bare probe
|
|
1569
|
-
still re-derives (to the same value); marks coalesce per microtask, so a key in
|
|
1570
|
-
both lists is not double work.
|
|
1571
|
-
*/
|
|
1572
|
-
function notify(store: CacheStore, marked: string[], emitted: string[]): void {
|
|
1573
|
-
marked.forEach((key) => {
|
|
1574
|
-
store.markLifecycle(key)
|
|
1575
|
-
})
|
|
1576
|
-
if (emitted.length > 0) {
|
|
1577
|
-
emit(store, emitted)
|
|
1578
|
-
}
|
|
1579
|
-
store.markLifecycle()
|
|
1580
|
-
}
|
|
1581
|
-
|
|
1582
|
-
function emit(store: CacheStore, keys: string[]): void {
|
|
1583
|
-
store.events.dispatchEvent(invalidateEvent(keys))
|
|
1584
|
-
}
|