@abide/abide 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +607 -0
- package/LICENSE +21 -0
- package/README.md +154 -0
- package/bin/abide.ts +212 -0
- package/package.json +155 -0
- package/src/abideLsp.ts +211 -0
- package/src/abideModules.d.ts +8 -0
- package/src/abideResolverPlugin.ts +923 -0
- package/src/appEntry.ts +151 -0
- package/src/assets/app.html +12 -0
- package/src/build.ts +143 -0
- package/src/buildCli.ts +127 -0
- package/src/buildDisconnected.ts +118 -0
- package/src/bundleApp.ts +147 -0
- package/src/bundleDisconnectedEntry.ts +14 -0
- package/src/checkAbide.ts +77 -0
- package/src/cliEntry.ts +25 -0
- package/src/clientBuildPlugins.ts +33 -0
- package/src/clientEntry.ts +17 -0
- package/src/compile.ts +63 -0
- package/src/controlServerWorker.ts +426 -0
- package/src/devEntry.ts +250 -0
- package/src/discoveryEntry.ts +81 -0
- package/src/lib/bundle/BundleMenu.ts +12 -0
- package/src/lib/bundle/BundleMenuItem.ts +25 -0
- package/src/lib/bundle/BundleWindow.ts +37 -0
- package/src/lib/bundle/WEBVIEW_BUILD_REVISION.ts +9 -0
- package/src/lib/bundle/WEBVIEW_VERSION.ts +7 -0
- package/src/lib/bundle/bindConnectedFlag.ts +29 -0
- package/src/lib/bundle/bindRequestNavigate.ts +34 -0
- package/src/lib/bundle/buildWebviewLib.ts +111 -0
- package/src/lib/bundle/bundled.ts +35 -0
- package/src/lib/bundle/disconnected.abide +236 -0
- package/src/lib/bundle/disconnected.css +9 -0
- package/src/lib/bundle/ensureWebviewLib.ts +20 -0
- package/src/lib/bundle/exitWithParent.ts +28 -0
- package/src/lib/bundle/infoPlist.ts +46 -0
- package/src/lib/bundle/installDownloads.ts +24 -0
- package/src/lib/bundle/installMacMenu.ts +39 -0
- package/src/lib/bundle/listenLocalControlServer.ts +19 -0
- package/src/lib/bundle/native/abideMenu.mm +422 -0
- package/src/lib/bundle/native/webview.h +4557 -0
- package/src/lib/bundle/onMenu.ts +42 -0
- package/src/lib/bundle/openWebview.ts +104 -0
- package/src/lib/bundle/pngToIcns.ts +47 -0
- package/src/lib/bundle/probeAbideServer.ts +57 -0
- package/src/lib/bundle/resolveServerBinary.ts +12 -0
- package/src/lib/bundle/resolveWebviewLib.ts +53 -0
- package/src/lib/bundle/serverBinaryFilename.ts +8 -0
- package/src/lib/bundle/signMacApp.ts +37 -0
- package/src/lib/bundle/spawnEmbeddedServer.ts +64 -0
- package/src/lib/bundle/stableLocalPort.ts +19 -0
- package/src/lib/bundle/waitForServer.ts +23 -0
- package/src/lib/bundle/webviewCachePath.ts +23 -0
- package/src/lib/bundle/webviewLibName.ts +11 -0
- package/src/lib/cli/connectToServer.ts +23 -0
- package/src/lib/cli/createClient.ts +108 -0
- package/src/lib/cli/dispatchCommand.ts +71 -0
- package/src/lib/cli/loadEnvFromBinaryDir.ts +15 -0
- package/src/lib/cli/parseArgvForRpc.ts +100 -0
- package/src/lib/cli/printHelp.ts +119 -0
- package/src/lib/cli/printSessionHelp.ts +27 -0
- package/src/lib/cli/printSessionStatus.ts +21 -0
- package/src/lib/cli/printTrimmed.ts +8 -0
- package/src/lib/cli/printValue.ts +10 -0
- package/src/lib/cli/resolveCliTarget.ts +48 -0
- package/src/lib/cli/runCli.ts +176 -0
- package/src/lib/cli/runSession.ts +108 -0
- package/src/lib/cli/startLocalInstance.ts +14 -0
- package/src/lib/cli/tokenizeLine.ts +51 -0
- package/src/lib/cli/types/CliManifest.ts +9 -0
- package/src/lib/cli/types/CliManifestEntry.ts +17 -0
- package/src/lib/cli/types/CliTarget.ts +13 -0
- package/src/lib/mcp/annotationsForMethod.ts +29 -0
- package/src/lib/mcp/createMcpResourceServer.ts +102 -0
- package/src/lib/mcp/createMcpServer.ts +48 -0
- package/src/lib/mcp/dispatchMcpRequest.ts +138 -0
- package/src/lib/mcp/mcpResourceServerSlot.ts +18 -0
- package/src/lib/mcp/mcpSurface.ts +295 -0
- package/src/lib/mcp/toolResultFromResponse.ts +66 -0
- package/src/lib/mcp/types/JsonRpcRequest.ts +12 -0
- package/src/lib/mcp/types/JsonRpcResponse.ts +20 -0
- package/src/lib/mcp/types/McpResourceContents.ts +10 -0
- package/src/lib/mcp/types/McpResourceDescriptor.ts +6 -0
- package/src/lib/mcp/types/McpResourceServer.ts +12 -0
- package/src/lib/mcp/types/McpServer.ts +9 -0
- package/src/lib/mcp/types/McpServerOptions.ts +16 -0
- package/src/lib/server/AppModule.ts +47 -0
- package/src/lib/server/DELETE.ts +10 -0
- package/src/lib/server/GET.ts +10 -0
- package/src/lib/server/HEAD.ts +10 -0
- package/src/lib/server/PATCH.ts +10 -0
- package/src/lib/server/POST.ts +10 -0
- package/src/lib/server/PUT.ts +10 -0
- package/src/lib/server/agent.ts +86 -0
- package/src/lib/server/appDataDir.ts +16 -0
- package/src/lib/server/cli/buildEnvContent.ts +19 -0
- package/src/lib/server/cli/createTarGz.ts +77 -0
- package/src/lib/server/cli/handleCliDownload.ts +150 -0
- package/src/lib/server/cli/handleCliInstall.ts +37 -0
- package/src/lib/server/cli/installScript.ts +31 -0
- package/src/lib/server/cli/maxSourceMtime.ts +26 -0
- package/src/lib/server/cookies.ts +30 -0
- package/src/lib/server/env.ts +51 -0
- package/src/lib/server/error.ts +73 -0
- package/src/lib/server/json.ts +42 -0
- package/src/lib/server/jsonl.ts +47 -0
- package/src/lib/server/prompts/definePrompt.ts +21 -0
- package/src/lib/server/prompts/promptRegistry.ts +9 -0
- package/src/lib/server/prompts/registerPrompt.ts +6 -0
- package/src/lib/server/prompts/renderPromptTemplate.ts +17 -0
- package/src/lib/server/prompts/types/Prompt.ts +13 -0
- package/src/lib/server/prompts/types/PromptOptions.ts +12 -0
- package/src/lib/server/prompts/types/PromptRegistryEntry.ts +13 -0
- package/src/lib/server/prompts/types/PromptRoutes.ts +10 -0
- package/src/lib/server/reachable.ts +45 -0
- package/src/lib/server/redirect.ts +43 -0
- package/src/lib/server/request.ts +19 -0
- package/src/lib/server/rpc/defineVerb.ts +210 -0
- package/src/lib/server/rpc/dispatchVerbInProcess.ts +46 -0
- package/src/lib/server/rpc/findVerbByCommandName.ts +18 -0
- package/src/lib/server/rpc/parseArgs.ts +127 -0
- package/src/lib/server/rpc/readBodyWithinLimit.ts +44 -0
- package/src/lib/server/rpc/registerVerb.ts +6 -0
- package/src/lib/server/rpc/runWithVerbTimeout.ts +49 -0
- package/src/lib/server/rpc/types/RemoteHandler.ts +27 -0
- package/src/lib/server/rpc/types/RemoteRoutes.ts +13 -0
- package/src/lib/server/rpc/types/TypedResponse.ts +18 -0
- package/src/lib/server/rpc/types/VerbHelper.ts +87 -0
- package/src/lib/server/rpc/types/VerbRegistryEntry.ts +35 -0
- package/src/lib/server/rpc/unprocessed.ts +14 -0
- package/src/lib/server/rpc/verbRegistry.ts +11 -0
- package/src/lib/server/runtime/DEFAULT_PORT.ts +6 -0
- package/src/lib/server/runtime/DEV_READY_MESSAGE.ts +6 -0
- package/src/lib/server/runtime/DEV_REBUILD_MESSAGE.ts +4 -0
- package/src/lib/server/runtime/DEV_RELOAD_CLIENT_SCRIPT.ts +107 -0
- package/src/lib/server/runtime/SSR_SWAP_SCRIPT.ts +16 -0
- package/src/lib/server/runtime/acceptsGzip.ts +24 -0
- package/src/lib/server/runtime/buildCacheSnapshot.ts +61 -0
- package/src/lib/server/runtime/buildHealthPayload.ts +34 -0
- package/src/lib/server/runtime/buildInspectorSurface.ts +37 -0
- package/src/lib/server/runtime/buildOpenApiSpec.ts +106 -0
- package/src/lib/server/runtime/cacheControlForAsset.ts +22 -0
- package/src/lib/server/runtime/containsTraversal.ts +37 -0
- package/src/lib/server/runtime/createAppAssetServer.ts +76 -0
- package/src/lib/server/runtime/createAssetHeaderCache.ts +31 -0
- package/src/lib/server/runtime/createPublicAssetServer.ts +67 -0
- package/src/lib/server/runtime/createReachable.ts +109 -0
- package/src/lib/server/runtime/createRouteDispatcher.ts +127 -0
- package/src/lib/server/runtime/createServer.ts +674 -0
- package/src/lib/server/runtime/createUiPageRenderer.ts +181 -0
- package/src/lib/server/runtime/crossOriginForbidden.ts +17 -0
- package/src/lib/server/runtime/crossOriginGate.ts +29 -0
- package/src/lib/server/runtime/devClientFingerprint.ts +117 -0
- package/src/lib/server/runtime/devHotModuleResponse.ts +40 -0
- package/src/lib/server/runtime/devReloadResponse.ts +41 -0
- package/src/lib/server/runtime/disableIdleTimeoutForStream.ts +27 -0
- package/src/lib/server/runtime/envSchemaStore.ts +15 -0
- package/src/lib/server/runtime/findOpenPort.ts +21 -0
- package/src/lib/server/runtime/getActiveServer.ts +6 -0
- package/src/lib/server/runtime/globToPathSet.ts +29 -0
- package/src/lib/server/runtime/gzipResponse.ts +46 -0
- package/src/lib/server/runtime/inProcessServer.ts +20 -0
- package/src/lib/server/runtime/internalErrorResponse.ts +25 -0
- package/src/lib/server/runtime/isCrossOriginRequest.ts +23 -0
- package/src/lib/server/runtime/listenOnOpenPort.ts +36 -0
- package/src/lib/server/runtime/logExposedSurfaces.ts +156 -0
- package/src/lib/server/runtime/maybeMountInspector.ts +97 -0
- package/src/lib/server/runtime/mimeForExtension.ts +14 -0
- package/src/lib/server/runtime/pageUrlFromStore.ts +15 -0
- package/src/lib/server/runtime/parseIdleTimeout.ts +10 -0
- package/src/lib/server/runtime/parsePort.ts +11 -0
- package/src/lib/server/runtime/registryManifests.ts +66 -0
- package/src/lib/server/runtime/requestContext.ts +5 -0
- package/src/lib/server/runtime/resolvePageSnapshot.ts +25 -0
- package/src/lib/server/runtime/respondWithEmbeddedAsset.ts +18 -0
- package/src/lib/server/runtime/runWithRequestScope.ts +150 -0
- package/src/lib/server/runtime/safeJsonForScript.ts +17 -0
- package/src/lib/server/runtime/serializeCacheSnapshot.ts +45 -0
- package/src/lib/server/runtime/serverSlot.ts +13 -0
- package/src/lib/server/runtime/setActiveServer.ts +6 -0
- package/src/lib/server/runtime/snapshotEntryFromCache.ts +83 -0
- package/src/lib/server/runtime/streamCacheResolutions.ts +37 -0
- package/src/lib/server/runtime/streamFromIterator.ts +86 -0
- package/src/lib/server/runtime/types/Assets.ts +6 -0
- package/src/lib/server/runtime/types/DevReloadStamp.ts +18 -0
- package/src/lib/server/runtime/types/InspectorCacheEntry.ts +24 -0
- package/src/lib/server/runtime/types/InspectorCacheSnapshot.ts +11 -0
- package/src/lib/server/runtime/types/InspectorContext.ts +30 -0
- package/src/lib/server/runtime/types/InspectorSocket.ts +17 -0
- package/src/lib/server/runtime/types/InspectorSurface.ts +13 -0
- package/src/lib/server/runtime/types/InspectorVerb.ts +27 -0
- package/src/lib/server/runtime/types/RequestStore.ts +55 -0
- package/src/lib/server/runtime/warnUnguardedMcp.ts +32 -0
- package/src/lib/server/runtime/withResponseDefaults.ts +24 -0
- package/src/lib/server/server.ts +33 -0
- package/src/lib/server/socket.ts +32 -0
- package/src/lib/server/sockets/createSocketDispatcher.ts +337 -0
- package/src/lib/server/sockets/defineSocket.ts +179 -0
- package/src/lib/server/sockets/lookupSocket.ts +6 -0
- package/src/lib/server/sockets/registerSocket.ts +6 -0
- package/src/lib/server/sockets/socketOperations.ts +36 -0
- package/src/lib/server/sockets/socketRegistry.ts +9 -0
- package/src/lib/server/sockets/types/Socket.ts +23 -0
- package/src/lib/server/sockets/types/SocketClientFrame.ts +19 -0
- package/src/lib/server/sockets/types/SocketOperation.ts +22 -0
- package/src/lib/server/sockets/types/SocketOptions.ts +26 -0
- package/src/lib/server/sockets/types/SocketRegistryEntry.ts +19 -0
- package/src/lib/server/sockets/types/SocketRoutes.ts +10 -0
- package/src/lib/server/sockets/types/SocketServerFrame.ts +24 -0
- package/src/lib/server/sse.ts +54 -0
- package/src/lib/shared/ABIDE_PACKAGE_NAME.ts +7 -0
- package/src/lib/shared/ABIDE_VERSION.ts +9 -0
- package/src/lib/shared/CACHE_CONTROL_VALUES.ts +16 -0
- package/src/lib/shared/CACHE_WRAPPED.ts +8 -0
- package/src/lib/shared/CLI_PATH.ts +7 -0
- package/src/lib/shared/DEV_HOT_PREFIX.ts +7 -0
- package/src/lib/shared/DEV_RELOAD_PATH.ts +6 -0
- package/src/lib/shared/HEALTH_PATH.ts +7 -0
- package/src/lib/shared/HttpError.ts +20 -0
- package/src/lib/shared/IDENTITY_PATH.ts +6 -0
- package/src/lib/shared/INSPECTOR_PATH.ts +7 -0
- package/src/lib/shared/NAV_HEADER.ts +8 -0
- package/src/lib/shared/OFFLINE_HEADER.ts +8 -0
- package/src/lib/shared/REMOTE_FUNCTION.ts +8 -0
- package/src/lib/shared/REPLAYABLE_METHODS.ts +12 -0
- package/src/lib/shared/SOCKETS_PATH.ts +7 -0
- package/src/lib/shared/STREAMING_CONTENT_TYPES.ts +11 -0
- package/src/lib/shared/SocketDisconnectedError.ts +13 -0
- package/src/lib/shared/TEXT_PLAIN.ts +7 -0
- package/src/lib/shared/abideImportName.ts +44 -0
- package/src/lib/shared/abideLog.ts +38 -0
- package/src/lib/shared/activeCacheStore.ts +20 -0
- package/src/lib/shared/activePage.ts +25 -0
- package/src/lib/shared/appDataDir.ts +34 -0
- package/src/lib/shared/appNameSlot.ts +10 -0
- package/src/lib/shared/basePath.ts +10 -0
- package/src/lib/shared/basePathFromAppUrl.ts +20 -0
- package/src/lib/shared/baseSlot.ts +14 -0
- package/src/lib/shared/binaryDirEnvPath.ts +12 -0
- package/src/lib/shared/browserClientFlags.ts +10 -0
- package/src/lib/shared/buildRpcProxy.ts +39 -0
- package/src/lib/shared/buildRpcRequest.ts +70 -0
- package/src/lib/shared/buildSocketOverChannel.ts +58 -0
- package/src/lib/shared/bundleLayout.ts +36 -0
- package/src/lib/shared/cache.ts +951 -0
- package/src/lib/shared/cacheEntryFromSnapshot.ts +59 -0
- package/src/lib/shared/cacheStoreSlot.ts +16 -0
- package/src/lib/shared/cacheStores.ts +10 -0
- package/src/lib/shared/canonicalJson.ts +63 -0
- package/src/lib/shared/carriesBodyArgs.ts +13 -0
- package/src/lib/shared/clearLastConnection.ts +7 -0
- package/src/lib/shared/commandNameForUrl.ts +17 -0
- package/src/lib/shared/createCacheStore.ts +104 -0
- package/src/lib/shared/createChannelLog.ts +122 -0
- package/src/lib/shared/createLifecycleChannel.ts +56 -0
- package/src/lib/shared/createLivenessWatch.ts +118 -0
- package/src/lib/shared/createPushIterator.ts +127 -0
- package/src/lib/shared/createRemoteFunction.ts +122 -0
- package/src/lib/shared/createSubscriber.ts +55 -0
- package/src/lib/shared/createTraceContext.ts +21 -0
- package/src/lib/shared/dataDirEnvPath.ts +12 -0
- package/src/lib/shared/decodeResponse.ts +47 -0
- package/src/lib/shared/detectTarget.ts +27 -0
- package/src/lib/shared/detectVerbMethod.ts +17 -0
- package/src/lib/shared/emitLogRecord.ts +190 -0
- package/src/lib/shared/exeSuffix.ts +9 -0
- package/src/lib/shared/exitOnBuildFailure.ts +17 -0
- package/src/lib/shared/extraForwardHeaders.ts +16 -0
- package/src/lib/shared/fileStem.ts +9 -0
- package/src/lib/shared/findExportCallSite.ts +476 -0
- package/src/lib/shared/formatTraceparent.ts +6 -0
- package/src/lib/shared/forwardHeaders.ts +44 -0
- package/src/lib/shared/getRemoteMeta.ts +5 -0
- package/src/lib/shared/globalCacheStore.ts +15 -0
- package/src/lib/shared/globalCacheStoreSlot.ts +14 -0
- package/src/lib/shared/health.ts +179 -0
- package/src/lib/shared/healthReadSlot.ts +11 -0
- package/src/lib/shared/healthSeedSlot.ts +12 -0
- package/src/lib/shared/html.ts +38 -0
- package/src/lib/shared/importNamesToStrip.ts +13 -0
- package/src/lib/shared/invalidateEvent.ts +11 -0
- package/src/lib/shared/invalidateTripwire.ts +40 -0
- package/src/lib/shared/isAbideHealthPayload.ts +11 -0
- package/src/lib/shared/isCompileTarget.ts +15 -0
- package/src/lib/shared/isDebugEnabled.ts +26 -0
- package/src/lib/shared/isDebugNegated.ts +19 -0
- package/src/lib/shared/isModuleNotFound.ts +16 -0
- package/src/lib/shared/isReadOnlyMethod.ts +14 -0
- package/src/lib/shared/isReplayableMethod.ts +7 -0
- package/src/lib/shared/isStreamingResponse.ts +11 -0
- package/src/lib/shared/isSubscribable.ts +15 -0
- package/src/lib/shared/jsonSchemaForPromptArguments.ts +29 -0
- package/src/lib/shared/jsonSchemaForSchema.ts +39 -0
- package/src/lib/shared/jsonlErrorFrame.ts +24 -0
- package/src/lib/shared/keyForRemoteCall.ts +29 -0
- package/src/lib/shared/keyMatchesPrefix.ts +9 -0
- package/src/lib/shared/lastConnectionPath.ts +7 -0
- package/src/lib/shared/layoutChainForRoute.ts +22 -0
- package/src/lib/shared/loadEnvFile.ts +17 -0
- package/src/lib/shared/loadEnvFromDataDir.ts +14 -0
- package/src/lib/shared/log.ts +24 -0
- package/src/lib/shared/logClosingRecord.ts +28 -0
- package/src/lib/shared/logTapSlot.ts +13 -0
- package/src/lib/shared/manifestModule.ts +39 -0
- package/src/lib/shared/matchesDebugPattern.ts +16 -0
- package/src/lib/shared/memoizeByKey.ts +32 -0
- package/src/lib/shared/normalizeTarget.ts +10 -0
- package/src/lib/shared/online.ts +51 -0
- package/src/lib/shared/page.ts +30 -0
- package/src/lib/shared/pageSlot.ts +17 -0
- package/src/lib/shared/pageUrlForFile.ts +14 -0
- package/src/lib/shared/parseBoundedEnvInt.ts +20 -0
- package/src/lib/shared/parseDebugPatterns.ts +21 -0
- package/src/lib/shared/parseEnv.ts +30 -0
- package/src/lib/shared/parsePromptMarkdown.ts +35 -0
- package/src/lib/shared/parseRouteSegments.ts +22 -0
- package/src/lib/shared/parseTraceparent.ts +26 -0
- package/src/lib/shared/pending.ts +30 -0
- package/src/lib/shared/prepareRpcModule.ts +59 -0
- package/src/lib/shared/prepareSocketModule.ts +49 -0
- package/src/lib/shared/probeRegistries.ts +68 -0
- package/src/lib/shared/producerKey.ts +32 -0
- package/src/lib/shared/programNameForPackage.ts +14 -0
- package/src/lib/shared/promptNameForFile.ts +10 -0
- package/src/lib/shared/queryStringFromArgs.ts +27 -0
- package/src/lib/shared/randomHexId.ts +14 -0
- package/src/lib/shared/readEnvFile.ts +15 -0
- package/src/lib/shared/readLastConnection.ts +18 -0
- package/src/lib/shared/readPackageJson.ts +9 -0
- package/src/lib/shared/recordRemoteMeta.ts +5 -0
- package/src/lib/shared/refreshing.ts +31 -0
- package/src/lib/shared/remoteMetaStore.ts +16 -0
- package/src/lib/shared/requestScopeSlot.ts +15 -0
- package/src/lib/shared/resolveClientFlags.ts +20 -0
- package/src/lib/shared/responseErrorText.ts +9 -0
- package/src/lib/shared/rpcTimeoutSlot.ts +9 -0
- package/src/lib/shared/rpcUrlForFile.ts +19 -0
- package/src/lib/shared/runningAsStandaloneBinary.ts +13 -0
- package/src/lib/shared/selectorMatcher.ts +68 -0
- package/src/lib/shared/selectorPrefix.ts +39 -0
- package/src/lib/shared/serializeEnv.ts +18 -0
- package/src/lib/shared/setAppName.ts +5 -0
- package/src/lib/shared/setBaseResolver.ts +6 -0
- package/src/lib/shared/setCacheStoreResolver.ts +6 -0
- package/src/lib/shared/setGlobalCacheStoreResolver.ts +6 -0
- package/src/lib/shared/setPageResolver.ts +7 -0
- package/src/lib/shared/setRequestScopeResolver.ts +6 -0
- package/src/lib/shared/snippet.ts +25 -0
- package/src/lib/shared/socketNameForFile.ts +11 -0
- package/src/lib/shared/socketTapSlot.ts +12 -0
- package/src/lib/shared/sseErrorFrame.ts +29 -0
- package/src/lib/shared/streamResponse.ts +169 -0
- package/src/lib/shared/stripImport.ts +27 -0
- package/src/lib/shared/subscribableFromResponse.ts +51 -0
- package/src/lib/shared/tailProbeSlot.ts +16 -0
- package/src/lib/shared/toBunRoutePattern.ts +28 -0
- package/src/lib/shared/toScopeSet.ts +4 -0
- package/src/lib/shared/trace.ts +16 -0
- package/src/lib/shared/types/CacheEntry.ts +84 -0
- package/src/lib/shared/types/CacheInvalidation.ts +9 -0
- package/src/lib/shared/types/CacheOnContext.ts +25 -0
- package/src/lib/shared/types/CacheOptions.ts +39 -0
- package/src/lib/shared/types/CacheSelector.ts +17 -0
- package/src/lib/shared/types/CacheSnapshot.ts +16 -0
- package/src/lib/shared/types/CacheSnapshotEntry.ts +17 -0
- package/src/lib/shared/types/CacheStats.ts +13 -0
- package/src/lib/shared/types/CacheStore.ts +39 -0
- package/src/lib/shared/types/ChannelLog.ts +13 -0
- package/src/lib/shared/types/ClientFlags.ts +11 -0
- package/src/lib/shared/types/CompileTarget.ts +6 -0
- package/src/lib/shared/types/FrameworkLog.ts +13 -0
- package/src/lib/shared/types/HttpVerb.ts +1 -0
- package/src/lib/shared/types/LastConnection.ts +9 -0
- package/src/lib/shared/types/Log.ts +13 -0
- package/src/lib/shared/types/LogRecord.ts +42 -0
- package/src/lib/shared/types/LogVoice.ts +7 -0
- package/src/lib/shared/types/PageSnapshot.ts +14 -0
- package/src/lib/shared/types/PromptArgument.ts +12 -0
- package/src/lib/shared/types/RawRemoteFunction.ts +14 -0
- package/src/lib/shared/types/RemoteCallable.ts +12 -0
- package/src/lib/shared/types/RemoteFunction.ts +47 -0
- package/src/lib/shared/types/ReplayableMethod.ts +7 -0
- package/src/lib/shared/types/RequestScopeInfo.ts +16 -0
- package/src/lib/shared/types/RpcInvoker.ts +6 -0
- package/src/lib/shared/types/SocketChannel.ts +17 -0
- package/src/lib/shared/types/SocketSubCallbacks.ts +13 -0
- package/src/lib/shared/types/StandardSchemaV1.ts +56 -0
- package/src/lib/shared/types/StreamedResolution.ts +10 -0
- package/src/lib/shared/types/Subscribable.ts +26 -0
- package/src/lib/shared/types/TailHooks.ts +12 -0
- package/src/lib/shared/types/TailOptions.ts +10 -0
- package/src/lib/shared/types/TraceContext.ts +17 -0
- package/src/lib/shared/url.ts +118 -0
- package/src/lib/shared/withBase.ts +11 -0
- package/src/lib/shared/withBaseUrl.ts +17 -0
- package/src/lib/shared/withJsonSchema.ts +21 -0
- package/src/lib/shared/writeDts.ts +12 -0
- package/src/lib/shared/writeHealthDts.ts +36 -0
- package/src/lib/shared/writeLastConnection.ts +13 -0
- package/src/lib/shared/writePublicAssetsDts.ts +31 -0
- package/src/lib/shared/writeRoutesDts.ts +73 -0
- package/src/lib/shared/writeRpcDts.ts +49 -0
- package/src/lib/shared/writeTestRpcDts.ts +45 -0
- package/src/lib/shared/writeTestSocketsDts.ts +34 -0
- package/src/lib/test/assertAgentFrameConformance.ts +73 -0
- package/src/lib/test/createScriptedSurface.ts +45 -0
- package/src/lib/test/createTestApp.ts +203 -0
- package/src/lib/test/createTestSocketChannel.ts +142 -0
- package/src/lib/ui/README.md +86 -0
- package/src/lib/ui/compile/SSR_ESCAPE.ts +25 -0
- package/src/lib/ui/compile/UI_RUNTIME_IMPORTS.ts +36 -0
- package/src/lib/ui/compile/VOID_TAGS.ts +21 -0
- package/src/lib/ui/compile/abideUiPlugin.ts +65 -0
- package/src/lib/ui/compile/analyzeComponent.ts +117 -0
- package/src/lib/ui/compile/assetModulesFile.ts +32 -0
- package/src/lib/ui/compile/branchElements.ts +50 -0
- package/src/lib/ui/compile/collectAbideDiagnostics.ts +59 -0
- package/src/lib/ui/compile/compileComponent.ts +20 -0
- package/src/lib/ui/compile/compileModule.ts +116 -0
- package/src/lib/ui/compile/compileSSR.ts +36 -0
- package/src/lib/ui/compile/compileShadow.ts +352 -0
- package/src/lib/ui/compile/createShadowLanguageService.ts +197 -0
- package/src/lib/ui/compile/createShadowProgram.ts +96 -0
- package/src/lib/ui/compile/decodeHtmlEntities.ts +49 -0
- package/src/lib/ui/compile/desugarSignals.ts +133 -0
- package/src/lib/ui/compile/escapeHtml.ts +15 -0
- package/src/lib/ui/compile/generateBuild.ts +638 -0
- package/src/lib/ui/compile/generateSSR.ts +380 -0
- package/src/lib/ui/compile/groupBindParts.ts +28 -0
- package/src/lib/ui/compile/hoistCells.ts +120 -0
- package/src/lib/ui/compile/loadShadowTsConfig.ts +31 -0
- package/src/lib/ui/compile/lowerDocAccess.ts +202 -0
- package/src/lib/ui/compile/nearestProjectRoot.ts +16 -0
- package/src/lib/ui/compile/parseTemplate.ts +396 -0
- package/src/lib/ui/compile/partitionSlots.ts +36 -0
- package/src/lib/ui/compile/prepareNestedScript.ts +42 -0
- package/src/lib/ui/compile/remapShadowDiagnostic.ts +30 -0
- package/src/lib/ui/compile/renameSignalRefs.ts +85 -0
- package/src/lib/ui/compile/resolveAbideImports.ts +29 -0
- package/src/lib/ui/compile/scopeCss.ts +115 -0
- package/src/lib/ui/compile/shadowNaming.ts +11 -0
- package/src/lib/ui/compile/sourceToShadowOffset.ts +24 -0
- package/src/lib/ui/compile/staticAttrValue.ts +13 -0
- package/src/lib/ui/compile/stripEffects.ts +32 -0
- package/src/lib/ui/compile/types/AbideDiagnostic.ts +14 -0
- package/src/lib/ui/compile/types/AnalyzedComponent.ts +25 -0
- package/src/lib/ui/compile/types/CompiledShadow.ts +15 -0
- package/src/lib/ui/compile/types/TemplateAttr.ts +16 -0
- package/src/lib/ui/compile/types/TemplateNode.ts +78 -0
- package/src/lib/ui/compile/types/TextPart.ts +8 -0
- package/src/lib/ui/derived.ts +28 -0
- package/src/lib/ui/doc.ts +15 -0
- package/src/lib/ui/dom/appendSnippet.ts +34 -0
- package/src/lib/ui/dom/appendStatic.ts +27 -0
- package/src/lib/ui/dom/appendText.ts +114 -0
- package/src/lib/ui/dom/applyResolved.ts +72 -0
- package/src/lib/ui/dom/attach.ts +20 -0
- package/src/lib/ui/dom/attr.ts +19 -0
- package/src/lib/ui/dom/awaitBlock.ts +224 -0
- package/src/lib/ui/dom/cloneStatic.ts +52 -0
- package/src/lib/ui/dom/each.ts +115 -0
- package/src/lib/ui/dom/eachAsync.ts +153 -0
- package/src/lib/ui/dom/hydrate.ts +35 -0
- package/src/lib/ui/dom/mount.ts +29 -0
- package/src/lib/ui/dom/mountChild.ts +33 -0
- package/src/lib/ui/dom/on.ts +15 -0
- package/src/lib/ui/dom/openChild.ts +22 -0
- package/src/lib/ui/dom/openRoot.ts +20 -0
- package/src/lib/ui/dom/switchBlock.ts +75 -0
- package/src/lib/ui/dom/text.ts +20 -0
- package/src/lib/ui/dom/tryBlock.ts +112 -0
- package/src/lib/ui/dom/types/EachRow.ts +3 -0
- package/src/lib/ui/dom/types/SwitchCase.ts +6 -0
- package/src/lib/ui/dom/when.ts +73 -0
- package/src/lib/ui/effect.ts +16 -0
- package/src/lib/ui/installHotBridge.ts +73 -0
- package/src/lib/ui/matchRoute.ts +89 -0
- package/src/lib/ui/navigate.ts +17 -0
- package/src/lib/ui/probeNavigation.ts +33 -0
- package/src/lib/ui/remoteProxy.ts +97 -0
- package/src/lib/ui/renderChain.ts +50 -0
- package/src/lib/ui/renderToStream.ts +104 -0
- package/src/lib/ui/router.ts +286 -0
- package/src/lib/ui/runtime/OUTLET_TAG.ts +8 -0
- package/src/lib/ui/runtime/OWNER.ts +8 -0
- package/src/lib/ui/runtime/REACTIVE_CONTEXT.ts +14 -0
- package/src/lib/ui/runtime/RENDER.ts +23 -0
- package/src/lib/ui/runtime/RESUME.ts +16 -0
- package/src/lib/ui/runtime/applyPatchToTree.ts +41 -0
- package/src/lib/ui/runtime/claimChild.ts +10 -0
- package/src/lib/ui/runtime/clientPage.ts +16 -0
- package/src/lib/ui/runtime/createComputedNode.ts +16 -0
- package/src/lib/ui/runtime/createDoc.ts +177 -0
- package/src/lib/ui/runtime/createEffectNode.ts +58 -0
- package/src/lib/ui/runtime/createSignalNode.ts +16 -0
- package/src/lib/ui/runtime/detachLink.ts +21 -0
- package/src/lib/ui/runtime/endTracking.ts +24 -0
- package/src/lib/ui/runtime/enterRenderPass.ts +12 -0
- package/src/lib/ui/runtime/exitRenderPass.ts +7 -0
- package/src/lib/ui/runtime/firstOutlet.ts +22 -0
- package/src/lib/ui/runtime/flushEffects.ts +17 -0
- package/src/lib/ui/runtime/hotInstances.ts +10 -0
- package/src/lib/ui/runtime/hotReloadEnabled.ts +8 -0
- package/src/lib/ui/runtime/hotReplace.ts +25 -0
- package/src/lib/ui/runtime/nextBlockId.ts +11 -0
- package/src/lib/ui/runtime/pathExists.ts +23 -0
- package/src/lib/ui/runtime/readNode.ts +17 -0
- package/src/lib/ui/runtime/registerHotInstance.ts +23 -0
- package/src/lib/ui/runtime/runNode.ts +28 -0
- package/src/lib/ui/runtime/runtimePath.ts +9 -0
- package/src/lib/ui/runtime/scope.ts +24 -0
- package/src/lib/ui/runtime/toTeardown.ts +26 -0
- package/src/lib/ui/runtime/track.ts +58 -0
- package/src/lib/ui/runtime/trigger.ts +44 -0
- package/src/lib/ui/runtime/types/Cell.ts +5 -0
- package/src/lib/ui/runtime/types/Derived.ts +3 -0
- package/src/lib/ui/runtime/types/Doc.ts +19 -0
- package/src/lib/ui/runtime/types/EffectResult.ts +10 -0
- package/src/lib/ui/runtime/types/HotInstance.ts +14 -0
- package/src/lib/ui/runtime/types/NavVerdict.ts +9 -0
- package/src/lib/ui/runtime/types/Patch.ts +11 -0
- package/src/lib/ui/runtime/types/ReactiveLink.ts +21 -0
- package/src/lib/ui/runtime/types/ReactiveNode.ts +25 -0
- package/src/lib/ui/runtime/types/Route.ts +8 -0
- package/src/lib/ui/runtime/types/RouteLoader.ts +7 -0
- package/src/lib/ui/runtime/types/SsrRender.ts +22 -0
- package/src/lib/ui/runtime/types/State.ts +3 -0
- package/src/lib/ui/runtime/types/Teardown.ts +5 -0
- package/src/lib/ui/runtime/types/UiComponent.ts +16 -0
- package/src/lib/ui/runtime/types/UiProps.ts +15 -0
- package/src/lib/ui/runtime/unlinkDeps.ts +20 -0
- package/src/lib/ui/runtime/untrack.ts +20 -0
- package/src/lib/ui/runtime/valueAtPath.ts +18 -0
- package/src/lib/ui/runtime/writeNode.ts +16 -0
- package/src/lib/ui/socketChannel.ts +227 -0
- package/src/lib/ui/socketProxy.ts +25 -0
- package/src/lib/ui/startClient.ts +58 -0
- package/src/lib/ui/state.ts +25 -0
- package/src/lib/ui/tail.ts +324 -0
- package/src/lib/ui/types/Layouts.ts +9 -0
- package/src/lib/ui/types/Pages.ts +8 -0
- package/src/preload.ts +19 -0
- package/src/scaffold.ts +153 -0
- package/src/serverBuildPlugins.ts +19 -0
- package/src/serverEntry.ts +95 -0
- package/template/bunfig.toml +4 -0
- package/template/package.json +18 -0
- package/template/src/app.ts +28 -0
- package/template/src/bundle/icon.png +0 -0
- package/template/src/cli/banner.txt +3 -0
- package/template/src/cli/footer.txt +1 -0
- package/template/src/server/config.ts +17 -0
- package/template/src/server/rpc/getHello.ts +36 -0
- package/template/src/ui/Layout.abide +19 -0
- package/template/src/ui/app.css +21 -0
- package/template/src/ui/app.html +24 -0
- package/template/src/ui/pages/about/page.abide +9 -0
- package/template/src/ui/pages/page.abide +22 -0
- package/template/test/app.test.ts +30 -0
- package/template/tsconfig.json +18 -0
- package/tsconfig.app.json +17 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { html } from '../shared/html.ts'
|
|
2
|
+
import { snippet } from '../shared/snippet.ts'
|
|
3
|
+
import { derived } from './derived.ts'
|
|
4
|
+
import { doc } from './doc.ts'
|
|
5
|
+
import { appendSnippet } from './dom/appendSnippet.ts'
|
|
6
|
+
import { appendStatic } from './dom/appendStatic.ts'
|
|
7
|
+
import { appendText } from './dom/appendText.ts'
|
|
8
|
+
import { attach } from './dom/attach.ts'
|
|
9
|
+
import { attr } from './dom/attr.ts'
|
|
10
|
+
import { awaitBlock } from './dom/awaitBlock.ts'
|
|
11
|
+
import { cloneStatic } from './dom/cloneStatic.ts'
|
|
12
|
+
import { each } from './dom/each.ts'
|
|
13
|
+
import { eachAsync } from './dom/eachAsync.ts'
|
|
14
|
+
import { hydrate } from './dom/hydrate.ts'
|
|
15
|
+
import { mount } from './dom/mount.ts'
|
|
16
|
+
import { mountChild } from './dom/mountChild.ts'
|
|
17
|
+
import { on } from './dom/on.ts'
|
|
18
|
+
import { openChild } from './dom/openChild.ts'
|
|
19
|
+
import { openRoot } from './dom/openRoot.ts'
|
|
20
|
+
import { switchBlock } from './dom/switchBlock.ts'
|
|
21
|
+
import { tryBlock } from './dom/tryBlock.ts'
|
|
22
|
+
import { when } from './dom/when.ts'
|
|
23
|
+
import { effect } from './effect.ts'
|
|
24
|
+
import { enterRenderPass } from './runtime/enterRenderPass.ts'
|
|
25
|
+
import { exitRenderPass } from './runtime/exitRenderPass.ts'
|
|
26
|
+
import { hotReloadEnabled } from './runtime/hotReloadEnabled.ts'
|
|
27
|
+
import { hotReplace } from './runtime/hotReplace.ts'
|
|
28
|
+
import { nextBlockId } from './runtime/nextBlockId.ts'
|
|
29
|
+
import { state } from './state.ts'
|
|
30
|
+
|
|
31
|
+
/*
|
|
32
|
+
Dev-only: exposes the abide-ui runtime plus `hotReplace` on `window.__abide`, and
|
|
33
|
+
flips on `hotReloadEnabled` so `mountChild` records every instance it mounts. A
|
|
34
|
+
hot module (the dev server's standalone recompile of one edited `.abide`) reads
|
|
35
|
+
its runtime from this object instead of importing fresh copies — so it shares the
|
|
36
|
+
one reactive graph and instance registry — then calls `hotReplace` to swap every
|
|
37
|
+
live instance in place. The keys mirror `UI_RUNTIME_IMPORTS` (+ `hotReplace`); a
|
|
38
|
+
test guards that pairing. `startClient` calls this when the server marks the page
|
|
39
|
+
dev (the live-reload script sets `window.__abideDev`).
|
|
40
|
+
*/
|
|
41
|
+
export function installHotBridge(): void {
|
|
42
|
+
;(globalThis as { __abide?: Record<string, unknown> }).__abide = {
|
|
43
|
+
html,
|
|
44
|
+
snippet,
|
|
45
|
+
doc,
|
|
46
|
+
state,
|
|
47
|
+
derived,
|
|
48
|
+
effect,
|
|
49
|
+
mount,
|
|
50
|
+
openChild,
|
|
51
|
+
openRoot,
|
|
52
|
+
appendText,
|
|
53
|
+
appendSnippet,
|
|
54
|
+
appendStatic,
|
|
55
|
+
cloneStatic,
|
|
56
|
+
attr,
|
|
57
|
+
on,
|
|
58
|
+
attach,
|
|
59
|
+
each,
|
|
60
|
+
eachAsync,
|
|
61
|
+
when,
|
|
62
|
+
awaitBlock,
|
|
63
|
+
tryBlock,
|
|
64
|
+
switchBlock,
|
|
65
|
+
mountChild,
|
|
66
|
+
hydrate,
|
|
67
|
+
nextBlockId,
|
|
68
|
+
enterRenderPass,
|
|
69
|
+
exitRenderPass,
|
|
70
|
+
hotReplace,
|
|
71
|
+
}
|
|
72
|
+
hotReloadEnabled.current = true
|
|
73
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { RouteSegment } from '../shared/parseRouteSegments.ts'
|
|
2
|
+
import { parseRouteSegments } from '../shared/parseRouteSegments.ts'
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
Per-route parse cache. The route set is stable across a session, so parsing a
|
|
6
|
+
pattern into segments (and counting its literals, the specificity tie-breaker) is
|
|
7
|
+
done once per route rather than twice per route on every navigation. Keyed by the
|
|
8
|
+
pattern string; entries never need eviction since routes don't churn.
|
|
9
|
+
*/
|
|
10
|
+
const PARSED_ROUTES = new Map<string, { segments: RouteSegment[]; literals: number }>()
|
|
11
|
+
|
|
12
|
+
function parsedRoute(route: string): { segments: RouteSegment[]; literals: number } {
|
|
13
|
+
let parsed = PARSED_ROUTES.get(route)
|
|
14
|
+
if (parsed === undefined) {
|
|
15
|
+
const segments = parseRouteSegments(route)
|
|
16
|
+
const literals = segments.filter((segment) => segment.kind === 'literal').length
|
|
17
|
+
parsed = { segments, literals }
|
|
18
|
+
PARSED_ROUTES.set(route, parsed)
|
|
19
|
+
}
|
|
20
|
+
return parsed
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/*
|
|
24
|
+
Client route matcher: given the registered route patterns and the current
|
|
25
|
+
pathname, returns the matching route + decoded params, or undefined. Mirrors the
|
|
26
|
+
server's segment grammar via the shared `parseRouteSegments` (literal / `[name]` /
|
|
27
|
+
`[...rest]`), so client navigation decodes params the same way SSR does. The most
|
|
28
|
+
specific match wins — the pattern with the most literal segments — so a static
|
|
29
|
+
route beats a param route at the same depth.
|
|
30
|
+
*/
|
|
31
|
+
export function matchRoute(
|
|
32
|
+
routes: string[],
|
|
33
|
+
pathname: string,
|
|
34
|
+
): { route: string; params: Record<string, string> } | undefined {
|
|
35
|
+
/* Normalize a trailing slash (except root) so `/users/` matches `/users` —
|
|
36
|
+
otherwise the extra empty segment makes the length guard reject it (a 404 the
|
|
37
|
+
server's own routing wouldn't give) or lets `/users/[id]` capture an empty id. */
|
|
38
|
+
const normalized =
|
|
39
|
+
pathname.length > 1 && pathname.endsWith('/') ? pathname.slice(0, -1) : pathname
|
|
40
|
+
const pathSegments = normalized.split('/')
|
|
41
|
+
let best: { route: string; params: Record<string, string>; literals: number } | undefined
|
|
42
|
+
for (const route of routes) {
|
|
43
|
+
const parsed = parsedRoute(route)
|
|
44
|
+
const params = matchSegments(parsed.segments, pathSegments)
|
|
45
|
+
if (params === undefined) {
|
|
46
|
+
continue
|
|
47
|
+
}
|
|
48
|
+
if (best === undefined || parsed.literals > best.literals) {
|
|
49
|
+
best = { route, params, literals: parsed.literals }
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return best === undefined ? undefined : { route: best.route, params: best.params }
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* Matches one parsed pattern against the path's segments, capturing params;
|
|
56
|
+
undefined on mismatch. A catch-all consumes every remaining segment. */
|
|
57
|
+
function matchSegments(
|
|
58
|
+
segments: RouteSegment[],
|
|
59
|
+
pathSegments: string[],
|
|
60
|
+
): Record<string, string> | undefined {
|
|
61
|
+
const params: Record<string, string> = {}
|
|
62
|
+
for (let index = 0; index < segments.length; index += 1) {
|
|
63
|
+
const segment = segments[index]
|
|
64
|
+
if (segment === undefined) {
|
|
65
|
+
return undefined
|
|
66
|
+
}
|
|
67
|
+
if (segment.kind === 'param' && segment.catchAll) {
|
|
68
|
+
params[segment.name] = pathSegments.slice(index).join('/')
|
|
69
|
+
return params
|
|
70
|
+
}
|
|
71
|
+
const value = pathSegments[index]
|
|
72
|
+
if (value === undefined) {
|
|
73
|
+
return undefined
|
|
74
|
+
}
|
|
75
|
+
if (segment.kind === 'literal') {
|
|
76
|
+
if (segment.value !== value) {
|
|
77
|
+
return undefined
|
|
78
|
+
}
|
|
79
|
+
} else {
|
|
80
|
+
/* A `[name]` param never captures an empty segment (e.g. `/users//5`). */
|
|
81
|
+
if (value === '') {
|
|
82
|
+
return undefined
|
|
83
|
+
}
|
|
84
|
+
params[segment.name] = value
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/* No catch-all consumed the tail, so the path must have no extra segments. */
|
|
88
|
+
return pathSegments.length === segments.length ? params : undefined
|
|
89
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { runtimePath } from './runtime/runtimePath.ts'
|
|
2
|
+
|
|
3
|
+
/* Navigates to `path`: writes a history entry (when available) and updates the
|
|
4
|
+
reactive route, which re-mounts the matching page via `router`. `replace` swaps
|
|
5
|
+
the current entry instead of pushing — used when honouring a server redirect, so
|
|
6
|
+
the blocked URL isn't left behind in history. */
|
|
7
|
+
// @readme plumbing
|
|
8
|
+
export function navigate(path: string, replace = false): void {
|
|
9
|
+
if (typeof history !== 'undefined') {
|
|
10
|
+
if (replace) {
|
|
11
|
+
history.replaceState({}, '', path)
|
|
12
|
+
} else {
|
|
13
|
+
history.pushState({}, '', path)
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
runtimePath.value = path
|
|
17
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { NAV_HEADER } from '../shared/NAV_HEADER.ts'
|
|
2
|
+
import type { NavVerdict } from './runtime/types/NavVerdict.ts'
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
The client router's SPA navigation probe: runs `path` through the server's
|
|
6
|
+
app.handle without a render. It's a fetch stamped with NAV_HEADER, which the page
|
|
7
|
+
dispatcher answers 204 once handle() has cleared it — so the round trip pays for
|
|
8
|
+
handle()'s auth/redirect gating, not a server render. fetch follows handle()'s
|
|
9
|
+
redirects server-side, so a redirected response's `url` is the final cleared
|
|
10
|
+
location: same-origin yields a soft client redirect (the router re-probes there),
|
|
11
|
+
cross-origin a full browser load. A non-OK status (handle() blocked it) or a thrown
|
|
12
|
+
fetch (offline) also hands off to the browser, so the server's real response —
|
|
13
|
+
a login page, an error page — is what renders.
|
|
14
|
+
*/
|
|
15
|
+
// @readme plumbing
|
|
16
|
+
export async function probeNavigation(path: string): Promise<NavVerdict> {
|
|
17
|
+
let response: Response
|
|
18
|
+
try {
|
|
19
|
+
response = await fetch(path, { headers: { [NAV_HEADER]: '1' } })
|
|
20
|
+
} catch {
|
|
21
|
+
return { kind: 'reload', url: path }
|
|
22
|
+
}
|
|
23
|
+
if (response.redirected) {
|
|
24
|
+
const target = new URL(response.url)
|
|
25
|
+
return target.origin === location.origin
|
|
26
|
+
? { kind: 'redirect', path: target.pathname + target.search }
|
|
27
|
+
: { kind: 'reload', url: response.url }
|
|
28
|
+
}
|
|
29
|
+
if (!response.ok) {
|
|
30
|
+
return { kind: 'reload', url: path }
|
|
31
|
+
}
|
|
32
|
+
return { kind: 'mount' }
|
|
33
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { browserClientFlags } from '../shared/browserClientFlags.ts'
|
|
2
|
+
import { buildRpcRequest } from '../shared/buildRpcRequest.ts'
|
|
3
|
+
import { createRemoteFunction } from '../shared/createRemoteFunction.ts'
|
|
4
|
+
import { HttpError } from '../shared/HttpError.ts'
|
|
5
|
+
import { OFFLINE_HEADER } from '../shared/OFFLINE_HEADER.ts'
|
|
6
|
+
import { rpcTimeoutSlot } from '../shared/rpcTimeoutSlot.ts'
|
|
7
|
+
import { trace } from '../shared/trace.ts'
|
|
8
|
+
import type { HttpVerb } from '../shared/types/HttpVerb.ts'
|
|
9
|
+
import type { RemoteFunction } from '../shared/types/RemoteFunction.ts'
|
|
10
|
+
import { withBase } from '../shared/withBase.ts'
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
Client-side substitute for a verb-defined handler. The bundler emits one
|
|
14
|
+
call per verb export inside an `$rpc/**` module (GET / POST / …): server
|
|
15
|
+
target uses defineVerb (real handler), browser target uses remoteProxy
|
|
16
|
+
(fetch over the network). Both paths produce identical RemoteFunction
|
|
17
|
+
shapes and identical WeakMap metadata so cache() works the same on either
|
|
18
|
+
side.
|
|
19
|
+
|
|
20
|
+
`url` is the flat rpc route. Args go in the JSON body (POST/PUT/PATCH) or
|
|
21
|
+
the query string (GET/DELETE/HEAD). Plain `fn(args)` decodes the Response
|
|
22
|
+
by Content-Type and throws HttpError on non-2xx; `.raw(args)` is the
|
|
23
|
+
escape hatch that returns the Response untouched.
|
|
24
|
+
*/
|
|
25
|
+
// @readme plumbing
|
|
26
|
+
export function remoteProxy<Args, Return>(
|
|
27
|
+
method: HttpVerb,
|
|
28
|
+
url: string,
|
|
29
|
+
): RemoteFunction<Args, Return> {
|
|
30
|
+
return createRemoteFunction<Args, Return>({
|
|
31
|
+
method,
|
|
32
|
+
url,
|
|
33
|
+
clients: browserClientFlags,
|
|
34
|
+
/*
|
|
35
|
+
The Request URL carries the mount base so the fetch routes through the
|
|
36
|
+
proxy (/v2/rpc/…); the cache key keeps the bare `url` (keyForRemoteCall
|
|
37
|
+
reads fn.url), so SSR snapshots round-trip base-independently.
|
|
38
|
+
*/
|
|
39
|
+
buildRequest: (args) =>
|
|
40
|
+
buildRpcRequest({
|
|
41
|
+
method,
|
|
42
|
+
url: withBase(url),
|
|
43
|
+
args,
|
|
44
|
+
baseUrl: window.location.href,
|
|
45
|
+
headers: rpcHeaders(),
|
|
46
|
+
}),
|
|
47
|
+
/*
|
|
48
|
+
Forcing `getRequest()` once builds the Request and seeds the
|
|
49
|
+
cache meta thunk in createRemoteFunction with the same instance,
|
|
50
|
+
so cache() readers don't reconstruct it.
|
|
51
|
+
*/
|
|
52
|
+
invoke: (_args, getRequest) => fetchWithTimeout(getRequest()),
|
|
53
|
+
})
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/*
|
|
57
|
+
Applies the env-configured client timeout (ABIDE_CLIENT_TIMEOUT, ms) when one
|
|
58
|
+
is set; an unset slot fetches unbounded, exactly as before. A timeout abort
|
|
59
|
+
surfaces as a 504 HttpError so a consumer reads an honest status instead of a
|
|
60
|
+
raw DOMException → 500. Other rejections (genuine network failure) propagate untouched.
|
|
61
|
+
*/
|
|
62
|
+
function fetchWithTimeout(request: Request): Promise<Response> {
|
|
63
|
+
const timeout = rpcTimeoutSlot.ms
|
|
64
|
+
if (timeout === undefined) {
|
|
65
|
+
return fetch(request)
|
|
66
|
+
}
|
|
67
|
+
return fetch(request, { signal: AbortSignal.timeout(timeout) }).catch((error: unknown) => {
|
|
68
|
+
if (error instanceof DOMException && error.name === 'TimeoutError') {
|
|
69
|
+
throw new HttpError(
|
|
70
|
+
new Response('client timeout', { status: 504, statusText: 'Gateway Timeout' }),
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
throw error
|
|
74
|
+
})
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/*
|
|
78
|
+
abide's per-RPC headers: the page traceparent (continues the server trace) and,
|
|
79
|
+
only while offline, the offline marker so the handler's online() reflects the
|
|
80
|
+
caller's connectivity. Returns undefined when neither applies so the
|
|
81
|
+
allocation-free fetch path stays the common case.
|
|
82
|
+
*/
|
|
83
|
+
function rpcHeaders(): Headers | undefined {
|
|
84
|
+
const headers = new Headers()
|
|
85
|
+
let any = false
|
|
86
|
+
const traceparent = trace()
|
|
87
|
+
if (traceparent) {
|
|
88
|
+
headers.set('traceparent', traceparent)
|
|
89
|
+
any = true
|
|
90
|
+
}
|
|
91
|
+
/* Presence = offline; absence = online/unknown. navigator.onLine's offline signal is the reliable direction. */
|
|
92
|
+
if (typeof navigator !== 'undefined' && navigator.onLine === false) {
|
|
93
|
+
headers.set(OFFLINE_HEADER, '1')
|
|
94
|
+
any = true
|
|
95
|
+
}
|
|
96
|
+
return any ? headers : undefined
|
|
97
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { enterRenderPass } from './runtime/enterRenderPass.ts'
|
|
2
|
+
import { exitRenderPass } from './runtime/exitRenderPass.ts'
|
|
3
|
+
import { OUTLET_TAG } from './runtime/OUTLET_TAG.ts'
|
|
4
|
+
import type { SsrRender } from './runtime/types/SsrRender.ts'
|
|
5
|
+
import type { UiComponent } from './runtime/types/UiComponent.ts'
|
|
6
|
+
|
|
7
|
+
const OUTLET_OPEN = `<${OUTLET_TAG}>`
|
|
8
|
+
const OUTLET_CLOSE = `</${OUTLET_TAG}>`
|
|
9
|
+
const OUTLET_PLACEHOLDER = `${OUTLET_OPEN}${OUTLET_CLOSE}`
|
|
10
|
+
|
|
11
|
+
/*
|
|
12
|
+
Server-renders a route's layout chain wrapped around its page into one SsrRender.
|
|
13
|
+
`views` is ordered outermost layout → … → page. The whole chain renders under a
|
|
14
|
+
SINGLE render pass: one outer `enterRenderPass` resets the block-id counter, then
|
|
15
|
+
each `render()` runs nested (depth > 0, no reset), so every `await`/`try` block
|
|
16
|
+
across all layers draws a unique id from the shared counter — in the same
|
|
17
|
+
layer-sequential order the client hydrates them, keeping the streamed fragments and
|
|
18
|
+
the resume manifest aligned.
|
|
19
|
+
|
|
20
|
+
The html nests inner-to-outer: each parent's empty `<abide-outlet>` is filled with
|
|
21
|
+
the accumulated child html — the outlet ELEMENT is kept (it stays the live mount
|
|
22
|
+
container the client router fills/hydrates the child into, found by tag), so the
|
|
23
|
+
SSR DOM and the client-nested DOM match exactly. Awaits concatenate (already
|
|
24
|
+
uniquely numbered); state merges. A single component renders unchanged — its own
|
|
25
|
+
render with no wrapping. A layout missing its `<slot/>` is a build error surfaced here.
|
|
26
|
+
*/
|
|
27
|
+
export function renderChain(views: UiComponent[], params: Record<string, string>): SsrRender {
|
|
28
|
+
enterRenderPass()
|
|
29
|
+
try {
|
|
30
|
+
const renders = views.map((view) => view.render(params))
|
|
31
|
+
let html = renders[renders.length - 1]?.html ?? ''
|
|
32
|
+
for (let index = renders.length - 2; index >= 0; index -= 1) {
|
|
33
|
+
const parent = renders[index] as SsrRender
|
|
34
|
+
if (!parent.html.includes(OUTLET_PLACEHOLDER)) {
|
|
35
|
+
throw new Error('[abide] a layout.abide must contain exactly one <slot/> outlet')
|
|
36
|
+
}
|
|
37
|
+
/* Fill the outlet element (keep it), function replacement so `$&`/`$\`` in
|
|
38
|
+
the child html insert literally. */
|
|
39
|
+
const child = html
|
|
40
|
+
html = parent.html.replace(OUTLET_PLACEHOLDER, () => OUTLET_OPEN + child + OUTLET_CLOSE)
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
html,
|
|
44
|
+
awaits: renders.flatMap((render) => render.awaits),
|
|
45
|
+
state: Object.assign({}, ...renders.map((render) => render.state)),
|
|
46
|
+
}
|
|
47
|
+
} finally {
|
|
48
|
+
exitRenderPass()
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type { ResumeEntry } from './runtime/RESUME.ts'
|
|
2
|
+
import type { SsrAwait, SsrRender } from './runtime/types/SsrRender.ts'
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
Out-of-order SSR streaming. Yields the pending shell first (so the browser paints
|
|
6
|
+
immediately), then one resolved fragment per await block as its promise settles —
|
|
7
|
+
in completion order, not source order, so a slow read never blocks a fast one.
|
|
8
|
+
Each resolved fragment is a `<abide-resolve data-id="ID" data-resume="…">…</abide-resolve>`
|
|
9
|
+
that `applyResolved` swaps into the matching `<!--abide:await:ID-->` boundary; the
|
|
10
|
+
`data-resume` payload is the JSON-serialized value, registered for hydration so an
|
|
11
|
+
`await` block adopts the resolved branch on resume instead of re-running.
|
|
12
|
+
|
|
13
|
+
This is the await-block-streams half of the cache rule: a top-level `await` in the
|
|
14
|
+
script would have blocked the shell (inlined), but an await *block* flushes its
|
|
15
|
+
shell now and streams the value when ready. Driven by a plain `render()` result,
|
|
16
|
+
so it composes with any transport (HTTP chunked, a socket frame, a test).
|
|
17
|
+
|
|
18
|
+
A `then` on the `await` tag makes the block BLOCKING: it settles before the first
|
|
19
|
+
flush, its resolved branch spliced into its (empty) boundary and its value seeded
|
|
20
|
+
into the resume manifest inline — so the value is in the first paint, no pending
|
|
21
|
+
shell, no swap. The first yield therefore awaits all blocking blocks; only the
|
|
22
|
+
remaining streaming blocks flush out of order after it.
|
|
23
|
+
*/
|
|
24
|
+
// @readme plumbing
|
|
25
|
+
export async function* renderToStream(render: () => SsrRender): AsyncGenerator<string> {
|
|
26
|
+
const { html, awaits } = render()
|
|
27
|
+
/* Blocking awaits (a `then` on the `await` tag) settle BEFORE the first flush:
|
|
28
|
+
their resolved branch is spliced into its empty boundary and its value registered
|
|
29
|
+
inline, so the first paint already has the value — no pending, no swap. */
|
|
30
|
+
const blocking = awaits.filter((block) => block.blocking === true)
|
|
31
|
+
let shell = html
|
|
32
|
+
const resumed: Record<number, ResumeEntry> = {}
|
|
33
|
+
for (const settled of await Promise.all(blocking.map(settle))) {
|
|
34
|
+
shell = spliceResolved(shell, settled.id, settled.html)
|
|
35
|
+
resumed[settled.id] = settled.resume
|
|
36
|
+
}
|
|
37
|
+
yield shell + resumeScript(resumed)
|
|
38
|
+
/* Streaming awaits flush their resolved fragment out of order as each settles. */
|
|
39
|
+
const inflight = new Map<number, Promise<Settled>>()
|
|
40
|
+
for (const block of awaits) {
|
|
41
|
+
if (block.blocking !== true) {
|
|
42
|
+
inflight.set(block.id, settle(block))
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
while (inflight.size > 0) {
|
|
46
|
+
const resolved = await Promise.race(inflight.values())
|
|
47
|
+
inflight.delete(resolved.id)
|
|
48
|
+
const resume = encodeResume(resolved.resume)
|
|
49
|
+
yield `<abide-resolve data-id="${resolved.id}" data-resume="${resume}">${resolved.html}</abide-resolve>`
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/* Inserts a blocking await's resolved markup into its (empty) boundary in the shell,
|
|
54
|
+
between the open and close markers. */
|
|
55
|
+
function spliceResolved(shell: string, id: number, resolved: string): string {
|
|
56
|
+
const open = `<!--abide:await:${id}-->`
|
|
57
|
+
const close = `<!--/abide:await:${id}-->`
|
|
58
|
+
/* A function replacement, so a `$&`/`$\`` etc. in the rendered value is inserted
|
|
59
|
+
literally rather than interpreted as a special replacement pattern. */
|
|
60
|
+
return shell.replace(`${open}${close}`, () => `${open}${resolved}${close}`)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/* A self-contained script seeding the resume manifest with the blocking values, so
|
|
64
|
+
client hydration adopts each resolved branch instead of re-running the promise.
|
|
65
|
+
Empty when no blocking awaits settled. */
|
|
66
|
+
function resumeScript(resumed: Record<number, ResumeEntry>): string {
|
|
67
|
+
if (Object.keys(resumed).length === 0) {
|
|
68
|
+
return ''
|
|
69
|
+
}
|
|
70
|
+
const payload = JSON.stringify(resumed).replace(/</g, '\\u003c')
|
|
71
|
+
return `<script>Object.assign(window.__abideResume=window.__abideResume||{},${payload})</script>`
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
type Settled = { id: number; html: string; resume: ResumeEntry }
|
|
75
|
+
|
|
76
|
+
/* Awaits one block's promise and renders the resolved or error branch to HTML,
|
|
77
|
+
capturing the value (serializable) for the resume manifest. Errors serialize as
|
|
78
|
+
their message — enough for the catch branch, without leaking a stack. */
|
|
79
|
+
function settle(block: SsrAwait): Promise<Settled> {
|
|
80
|
+
return Promise.resolve(block.promise()).then(
|
|
81
|
+
(value) => ({ id: block.id, html: block.then(value), resume: { ok: true, value } }),
|
|
82
|
+
(error) => {
|
|
83
|
+
/* No catch branch → surface the rejection (500 before the first flush,
|
|
84
|
+
mid-stream error after) instead of swallowing it into an empty fragment. */
|
|
85
|
+
if (block.catch === undefined) {
|
|
86
|
+
throw error
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
id: block.id,
|
|
90
|
+
html: block.catch(error),
|
|
91
|
+
resume: { ok: false, error: String(error) },
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/* JSON for an HTML double-quoted attribute: escape `"` and `&` (and `<` for safety
|
|
98
|
+
inside markup). `applyResolved`/the inline swap script decode it via the DOM. */
|
|
99
|
+
function encodeResume(resume: ResumeEntry): string {
|
|
100
|
+
return JSON.stringify(resume)
|
|
101
|
+
.replace(/&/g, '&')
|
|
102
|
+
.replace(/"/g, '"')
|
|
103
|
+
.replace(/</g, '<')
|
|
104
|
+
}
|