@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,674 @@
|
|
|
1
|
+
import type { BunRequest, Server } from 'bun'
|
|
2
|
+
import { createMcpResourceServer } from '../../mcp/createMcpResourceServer.ts'
|
|
3
|
+
import { setMcpResourceServer } from '../../mcp/mcpResourceServerSlot.ts'
|
|
4
|
+
import type { McpServer } from '../../mcp/types/McpServer.ts'
|
|
5
|
+
import { abideLog } from '../../shared/abideLog.ts'
|
|
6
|
+
import { basePathFromAppUrl } from '../../shared/basePathFromAppUrl.ts'
|
|
7
|
+
import { NO_STORE } from '../../shared/CACHE_CONTROL_VALUES.ts'
|
|
8
|
+
import { CLI_PATH } from '../../shared/CLI_PATH.ts'
|
|
9
|
+
import { DEV_HOT_PREFIX } from '../../shared/DEV_HOT_PREFIX.ts'
|
|
10
|
+
import { DEV_RELOAD_PATH } from '../../shared/DEV_RELOAD_PATH.ts'
|
|
11
|
+
import { extraForwardHeaders } from '../../shared/extraForwardHeaders.ts'
|
|
12
|
+
import { HEALTH_PATH } from '../../shared/HEALTH_PATH.ts'
|
|
13
|
+
import { healthReadSlot } from '../../shared/healthReadSlot.ts'
|
|
14
|
+
import { IDENTITY_PATH } from '../../shared/IDENTITY_PATH.ts'
|
|
15
|
+
import { INSPECTOR_PATH } from '../../shared/INSPECTOR_PATH.ts'
|
|
16
|
+
import { isDebugNegated } from '../../shared/isDebugNegated.ts'
|
|
17
|
+
import { logClosingRecord } from '../../shared/logClosingRecord.ts'
|
|
18
|
+
import { OFFLINE_HEADER } from '../../shared/OFFLINE_HEADER.ts'
|
|
19
|
+
import { parseBoundedEnvInt } from '../../shared/parseBoundedEnvInt.ts'
|
|
20
|
+
import { SOCKETS_PATH } from '../../shared/SOCKETS_PATH.ts'
|
|
21
|
+
import { setAppName } from '../../shared/setAppName.ts'
|
|
22
|
+
import { setBaseResolver } from '../../shared/setBaseResolver.ts'
|
|
23
|
+
import { setRequestScopeResolver } from '../../shared/setRequestScopeResolver.ts'
|
|
24
|
+
import { TEXT_PLAIN } from '../../shared/TEXT_PLAIN.ts'
|
|
25
|
+
import { toBunRoutePattern } from '../../shared/toBunRoutePattern.ts'
|
|
26
|
+
import type { Layouts } from '../../ui/types/Layouts.ts'
|
|
27
|
+
import type { Pages } from '../../ui/types/Pages.ts'
|
|
28
|
+
import type { AppModule } from '../AppModule.ts'
|
|
29
|
+
import { handleCliDownload } from '../cli/handleCliDownload.ts'
|
|
30
|
+
import { handleCliInstall } from '../cli/handleCliInstall.ts'
|
|
31
|
+
import type { PromptRoutes } from '../prompts/types/PromptRoutes.ts'
|
|
32
|
+
import type { RemoteRoutes } from '../rpc/types/RemoteRoutes.ts'
|
|
33
|
+
import { createSocketDispatcher } from '../sockets/createSocketDispatcher.ts'
|
|
34
|
+
import type { SocketRoutes } from '../sockets/types/SocketRoutes.ts'
|
|
35
|
+
import { buildHealthPayload } from './buildHealthPayload.ts'
|
|
36
|
+
import { buildOpenApiSpec } from './buildOpenApiSpec.ts'
|
|
37
|
+
import { createAppAssetServer } from './createAppAssetServer.ts'
|
|
38
|
+
import { createPublicAssetServer } from './createPublicAssetServer.ts'
|
|
39
|
+
import { createRouteDispatcher } from './createRouteDispatcher.ts'
|
|
40
|
+
import { createUiPageRenderer } from './createUiPageRenderer.ts'
|
|
41
|
+
import { crossOriginGate } from './crossOriginGate.ts'
|
|
42
|
+
import { DEFAULT_PORT } from './DEFAULT_PORT.ts'
|
|
43
|
+
import { DEV_READY_MESSAGE } from './DEV_READY_MESSAGE.ts'
|
|
44
|
+
import { DEV_REBUILD_MESSAGE } from './DEV_REBUILD_MESSAGE.ts'
|
|
45
|
+
import { DEV_RELOAD_CLIENT_SCRIPT } from './DEV_RELOAD_CLIENT_SCRIPT.ts'
|
|
46
|
+
import { devClientFingerprint } from './devClientFingerprint.ts'
|
|
47
|
+
import { devHotModuleResponse } from './devHotModuleResponse.ts'
|
|
48
|
+
import { devReloadResponse } from './devReloadResponse.ts'
|
|
49
|
+
import { disableIdleTimeoutForStream } from './disableIdleTimeoutForStream.ts'
|
|
50
|
+
import { gzipResponse } from './gzipResponse.ts'
|
|
51
|
+
import { internalErrorResponse } from './internalErrorResponse.ts'
|
|
52
|
+
import { listenOnOpenPort } from './listenOnOpenPort.ts'
|
|
53
|
+
import { logExposedSurfaces } from './logExposedSurfaces.ts'
|
|
54
|
+
import { maybeMountInspector } from './maybeMountInspector.ts'
|
|
55
|
+
import { parseIdleTimeout } from './parseIdleTimeout.ts'
|
|
56
|
+
import { parsePort } from './parsePort.ts'
|
|
57
|
+
import { ensureRegistriesLoaded, setRegistryManifests } from './registryManifests.ts'
|
|
58
|
+
import { requestContext } from './requestContext.ts'
|
|
59
|
+
import { runWithRequestScope } from './runWithRequestScope.ts'
|
|
60
|
+
import { setActiveServer } from './setActiveServer.ts'
|
|
61
|
+
import type { Assets } from './types/Assets.ts'
|
|
62
|
+
import type { RequestStore } from './types/RequestStore.ts'
|
|
63
|
+
import { warnUnguardedMcp } from './warnUnguardedMcp.ts'
|
|
64
|
+
|
|
65
|
+
const SOCKETS_REST_PREFIX = `${SOCKETS_PATH}/`
|
|
66
|
+
const MCP_PATH = '/__abide/mcp'
|
|
67
|
+
const CLI_DOWNLOAD_PREFIX = `${CLI_PATH}/`
|
|
68
|
+
// Dev-only manual rebuild trigger; POSTing signals the orchestrator to rebuild + restart.
|
|
69
|
+
const DEV_REBUILD_PATH = '/__abide/reload'
|
|
70
|
+
/*
|
|
71
|
+
Unlike the framework's own plumbing routes above (the socket multiplex, MCP
|
|
72
|
+
endpoint, CLI download), the OpenAPI document describes the app's public HTTP
|
|
73
|
+
surface — the /rpc/* verbs — rather than abide internals, so it sits at the
|
|
74
|
+
conventional root path where external tooling and scanners expect to find it
|
|
75
|
+
(/openapi.json, alongside /swagger.json, /.well-known/*) rather than under the
|
|
76
|
+
/__abide/ namespace.
|
|
77
|
+
*/
|
|
78
|
+
const OPENAPI_PATH = '/openapi.json'
|
|
79
|
+
|
|
80
|
+
/*
|
|
81
|
+
Starts a Bun HTTP server that ties together the framework conventions:
|
|
82
|
+
page.abide under src/ui/pages/ for views (layout.abide wraps the pages beneath
|
|
83
|
+
it), one named export per file under src/server/rpc/ for verb-bound remote
|
|
84
|
+
functions, one named export
|
|
85
|
+
per file under src/server/sockets/ for broadcast sockets, and an optional
|
|
86
|
+
app.ts for boot-time setup, request middleware, and error fallback. Page
|
|
87
|
+
URLs and rpc URLs live in disjoint spaces — pages mount at the folder
|
|
88
|
+
path, rpc files mount at `/rpc/<file path>` — so each registered URL
|
|
89
|
+
resolves to exactly one thing. Per request, an AsyncLocalStorage
|
|
90
|
+
RequestStore carries the cache store and request metadata.
|
|
91
|
+
*/
|
|
92
|
+
export async function createServer({
|
|
93
|
+
pages,
|
|
94
|
+
layouts = {},
|
|
95
|
+
rpc,
|
|
96
|
+
sockets,
|
|
97
|
+
prompts,
|
|
98
|
+
shell,
|
|
99
|
+
app,
|
|
100
|
+
assets,
|
|
101
|
+
publicAssets,
|
|
102
|
+
mcpResources,
|
|
103
|
+
mcp,
|
|
104
|
+
cliProgramName,
|
|
105
|
+
appInfo,
|
|
106
|
+
distDir = `${process.cwd()}/dist`,
|
|
107
|
+
publicDir = `${process.cwd()}/src/ui/public`,
|
|
108
|
+
resourcesDir = `${process.cwd()}/src/mcp/resources`,
|
|
109
|
+
// A configured PORT is honored as-is; left undefined, the real listener
|
|
110
|
+
// scans upward from 3000 at bind time (see buildServer / listenOnOpenPort).
|
|
111
|
+
port = parsePort(process.env.PORT),
|
|
112
|
+
/*
|
|
113
|
+
Bun's per-connection idle timeout in seconds (its own default is 10).
|
|
114
|
+
Surfaced for apps whose unary handlers legitimately compute longer than
|
|
115
|
+
that; streaming responses opt out per-request via disableIdleTimeoutForStream
|
|
116
|
+
regardless of this floor.
|
|
117
|
+
*/
|
|
118
|
+
idleTimeout = parseIdleTimeout(process.env.ABIDE_IDLE_TIMEOUT) ?? 10,
|
|
119
|
+
/*
|
|
120
|
+
Bun's server-wide request body ceiling, enforced natively by Bun.serve
|
|
121
|
+
(its own default is ~128MB). Surfaced as an option + env so deployments
|
|
122
|
+
can raise/lower it; per-verb tightening is the verbs' maxBodySize.
|
|
123
|
+
*/
|
|
124
|
+
maxRequestBodySize = parseBoundedEnvInt(
|
|
125
|
+
process.env.ABIDE_MAX_REQUEST_BODY_SIZE,
|
|
126
|
+
0,
|
|
127
|
+
Number.MAX_SAFE_INTEGER,
|
|
128
|
+
),
|
|
129
|
+
// Under `abide dev` the orchestrator sets this: mount the live-reload SSE
|
|
130
|
+
// channel and inject its client into the served shell.
|
|
131
|
+
dev = false,
|
|
132
|
+
}: {
|
|
133
|
+
pages: Pages
|
|
134
|
+
layouts?: Layouts
|
|
135
|
+
rpc: RemoteRoutes
|
|
136
|
+
sockets: SocketRoutes
|
|
137
|
+
prompts: PromptRoutes
|
|
138
|
+
shell: string
|
|
139
|
+
app?: AppModule
|
|
140
|
+
assets?: Assets
|
|
141
|
+
publicAssets?: Assets
|
|
142
|
+
mcpResources?: Assets
|
|
143
|
+
mcp?: McpServer
|
|
144
|
+
cliProgramName?: string
|
|
145
|
+
appInfo?: { name: string; version: string }
|
|
146
|
+
distDir?: string
|
|
147
|
+
publicDir?: string
|
|
148
|
+
resourcesDir?: string
|
|
149
|
+
port?: number
|
|
150
|
+
idleTimeout?: number
|
|
151
|
+
maxRequestBodySize?: number
|
|
152
|
+
dev?: boolean
|
|
153
|
+
}): Promise<Server<unknown>> {
|
|
154
|
+
/*
|
|
155
|
+
Publish the ALS request scope to the shared layer: trace() and log line
|
|
156
|
+
prefixes resolve through this. Registered here (not serverEntry) so the
|
|
157
|
+
HTTP test harness gets the same behaviour as a real boot. elapsedMs is
|
|
158
|
+
computed at read time so every log line carries a current value.
|
|
159
|
+
*/
|
|
160
|
+
setRequestScopeResolver(() => {
|
|
161
|
+
const store = requestContext.getStore()
|
|
162
|
+
if (!store) {
|
|
163
|
+
return undefined
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
trace: store.trace,
|
|
167
|
+
elapsedMs: (Bun.nanoseconds() - store.start) / 1e6,
|
|
168
|
+
method: store.req.method,
|
|
169
|
+
path: store.url.pathname,
|
|
170
|
+
/* The calling client's reported connectivity — drives server-side online(). Absent header = online. */
|
|
171
|
+
online: !store.req.headers.has(OFFLINE_HEADER),
|
|
172
|
+
}
|
|
173
|
+
})
|
|
174
|
+
/*
|
|
175
|
+
health() during an SSR render marks its request through this slot; the
|
|
176
|
+
renderer stamps the health payload into __SSR__ only for marked requests,
|
|
177
|
+
so the client seed stays reader-driven like the poll itself.
|
|
178
|
+
*/
|
|
179
|
+
healthReadSlot.mark = () => {
|
|
180
|
+
const store = requestContext.getStore()
|
|
181
|
+
if (store) {
|
|
182
|
+
store.healthRead = true
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
// In dev, append the live-reload client to the shell so every rendered
|
|
186
|
+
// page reconnects to /__abide/dev and reloads after a restart.
|
|
187
|
+
const devShell = dev ? shell.replace('</body>', `${DEV_RELOAD_CLIENT_SCRIPT}</body>`) : shell
|
|
188
|
+
/*
|
|
189
|
+
Mount base from APP_URL's pathname (e.g. https://foo.com/v2 → /v2). Install
|
|
190
|
+
the server-side resolver so url() prefixes SSR-generated links, and rewrite
|
|
191
|
+
the shell's framework `/_app` entry + css refs to carry the base — relative
|
|
192
|
+
code-split chunks inherit it from the entry's own URL. '' (root mount) is a
|
|
193
|
+
no-op on both. See setBaseResolver / startClient for the client half.
|
|
194
|
+
*/
|
|
195
|
+
const base = basePathFromAppUrl(process.env.APP_URL)
|
|
196
|
+
setBaseResolver(() => base)
|
|
197
|
+
// Rebase the shell's rooted `/_app/` entry refs onto the mount base, matching
|
|
198
|
+
// either quote style so a custom app.html using single quotes still rewrites.
|
|
199
|
+
const activeShell = base ? devShell.replace(/(["'])\/_app\//g, `$1${base}/_app/`) : devShell
|
|
200
|
+
/*
|
|
201
|
+
Boot-path disk scans run concurrently — they share no data, and under
|
|
202
|
+
`abide dev` the worker-swap window is bounded by exactly this boot.
|
|
203
|
+
devClientFingerprint (dev only) hashes the browser-visible surface so the
|
|
204
|
+
live-reload channel reloads only when a worker swap changed what the
|
|
205
|
+
browser would render; the asset servers glob public/ and the build tree
|
|
206
|
+
(embedded gzip map in a compiled binary, dist/ on disk).
|
|
207
|
+
*/
|
|
208
|
+
const [clientFingerprint, servePublicAsset, serveAppAsset] = await Promise.all([
|
|
209
|
+
dev
|
|
210
|
+
? devClientFingerprint({
|
|
211
|
+
srcDir: `${process.cwd()}/src`,
|
|
212
|
+
publicDir,
|
|
213
|
+
shell: activeShell,
|
|
214
|
+
projectRoot: process.cwd(),
|
|
215
|
+
})
|
|
216
|
+
: undefined,
|
|
217
|
+
createPublicAssetServer({ publicDir, publicAssets }),
|
|
218
|
+
createAppAssetServer({ distDir, assets }),
|
|
219
|
+
])
|
|
220
|
+
setRegistryManifests({ rpc, sockets, prompts })
|
|
221
|
+
setMcpResourceServer(createMcpResourceServer({ resourcesDir, mcpResources }))
|
|
222
|
+
const cliName = cliProgramName ?? 'app'
|
|
223
|
+
/* The app's public identity, shared by the identity probe and the OpenAPI spec. */
|
|
224
|
+
const appName = appInfo?.name ?? cliName
|
|
225
|
+
const appVersion = appInfo?.version ?? '0.0.0'
|
|
226
|
+
/* The app's default log channel — every unchanneled record speaks as [appName]. */
|
|
227
|
+
setAppName(appName)
|
|
228
|
+
/*
|
|
229
|
+
Opt-in inspector (ABIDE_ENABLE_INSPECTOR=true): a dynamically-imported
|
|
230
|
+
`@abide/inspector` handler, or undefined when the flag is off / the package
|
|
231
|
+
isn't installed. Resolved at boot so the fetch route below can branch on it.
|
|
232
|
+
*/
|
|
233
|
+
const inspectorHandler = await maybeMountInspector({ name: appName, version: appVersion })
|
|
234
|
+
/* Built on first request, then reused — the verb registry is frozen after load. */
|
|
235
|
+
let openApiSpec: ReturnType<typeof buildOpenApiSpec> | undefined
|
|
236
|
+
const cliCwd = process.cwd()
|
|
237
|
+
|
|
238
|
+
/* Request closing records are on by default — DEBUG=-abide is the off switch (negation, like the abide channel itself). */
|
|
239
|
+
const logRequests = !isDebugNegated('abide')
|
|
240
|
+
|
|
241
|
+
// App-configured headers extend the in-process forward allowlist for the process lifetime.
|
|
242
|
+
extraForwardHeaders.set(app?.forwardHeaders ?? [])
|
|
243
|
+
|
|
244
|
+
/*
|
|
245
|
+
SSR document assembly — abide-ui page render wrapped in its layout chain, cache
|
|
246
|
+
snapshot, `__SSR__` state tag, shell splicing (buffered, or streamed for pages
|
|
247
|
+
with await blocks) — lives behind createUiPageRenderer. Error pages are not
|
|
248
|
+
framework-resolved; renderError returns undefined and the 404 path serves plain.
|
|
249
|
+
*/
|
|
250
|
+
const { renderPage, renderError } = createUiPageRenderer({
|
|
251
|
+
shell: activeShell,
|
|
252
|
+
base,
|
|
253
|
+
clientTimeout: parseBoundedEnvInt(process.env.ABIDE_CLIENT_TIMEOUT, 1, 600_000),
|
|
254
|
+
pages,
|
|
255
|
+
layouts,
|
|
256
|
+
/* The wire payload, rebuilt per marked render — the __SSR__ health seed must match what /__abide/health serves. */
|
|
257
|
+
healthPayload: (request) => buildHealthPayload(request, { app, appName, appVersion }),
|
|
258
|
+
})
|
|
259
|
+
|
|
260
|
+
/*
|
|
261
|
+
Route dispatch — rpc-vs-page-vs-404 resolution and method matching — lives
|
|
262
|
+
behind createRouteDispatcher; renderPage is injected so those decisions stay
|
|
263
|
+
testable without SSR. buildRoutes() below binds the returned handler per URL.
|
|
264
|
+
*/
|
|
265
|
+
const buildRouteHandler = createRouteDispatcher({ pages, rpc, renderPage })
|
|
266
|
+
|
|
267
|
+
/*
|
|
268
|
+
Page URLs (folder paths, e.g. `/media/[id]`) get translated to Bun's
|
|
269
|
+
pattern syntax (`/media/:id`) at registration. Bun's `*` wildcard
|
|
270
|
+
matches but does not capture into req.params, so for `[...rest]`
|
|
271
|
+
routes the catch-all value is reconstructed from the request URL by
|
|
272
|
+
slicing the pathname segments after the catch-all's pattern index.
|
|
273
|
+
The reconstructed value is set under the original name (e.g. `rest`)
|
|
274
|
+
so the page component's $props destructure stays consistent with the
|
|
275
|
+
file path. Page URLs and rpc URLs (always `/rpc/...`, flat) are
|
|
276
|
+
disjoint by construction, so a plain object needs no deduplication.
|
|
277
|
+
*/
|
|
278
|
+
const routes: Record<string, (req: BunRequest) => Promise<Response>> = {}
|
|
279
|
+
for (const routeUrl of Object.keys(pages)) {
|
|
280
|
+
const handler = buildRouteHandler(routeUrl)
|
|
281
|
+
const { pattern, catchAllName } = toBunRoutePattern(routeUrl)
|
|
282
|
+
const catchAllIndex = catchAllName
|
|
283
|
+
? routeUrl.split('/').findIndex((segment) => segment.startsWith('[...'))
|
|
284
|
+
: -1
|
|
285
|
+
/* Only catch-all routes copy req.params (to write the reconstructed
|
|
286
|
+
segment); plain routes pass it through — it's never mutated downstream. */
|
|
287
|
+
routes[pattern] =
|
|
288
|
+
catchAllName && catchAllIndex !== -1
|
|
289
|
+
? (req) => {
|
|
290
|
+
const pathParams = {
|
|
291
|
+
...((req.params as Record<string, string> | undefined) ?? {}),
|
|
292
|
+
}
|
|
293
|
+
const url = new URL(req.url)
|
|
294
|
+
pathParams[catchAllName] = url.pathname
|
|
295
|
+
.split('/')
|
|
296
|
+
.slice(catchAllIndex)
|
|
297
|
+
.join('/')
|
|
298
|
+
return dispatchRequest(req, pathParams, handler, url)
|
|
299
|
+
}
|
|
300
|
+
: (req) =>
|
|
301
|
+
dispatchRequest(
|
|
302
|
+
req,
|
|
303
|
+
(req.params as Record<string, string> | undefined) ?? {},
|
|
304
|
+
handler,
|
|
305
|
+
)
|
|
306
|
+
}
|
|
307
|
+
for (const routeUrl of Object.keys(rpc)) {
|
|
308
|
+
const handler = buildRouteHandler(routeUrl)
|
|
309
|
+
routes[routeUrl] = (req) => dispatchRequest(req, {}, handler)
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function dispatchRequest(
|
|
313
|
+
req: Request,
|
|
314
|
+
pathParams: Record<string, string>,
|
|
315
|
+
handler: (
|
|
316
|
+
req: Request,
|
|
317
|
+
pathParams: Record<string, string>,
|
|
318
|
+
store: RequestStore,
|
|
319
|
+
) => Promise<Response>,
|
|
320
|
+
/* Pre-parsed by the fetch fallback; routes-table callers omit it. */
|
|
321
|
+
url?: URL,
|
|
322
|
+
): Promise<Response> {
|
|
323
|
+
return runWithRequestScope(req, { app, logRequests, url }, async (store) => {
|
|
324
|
+
const response = app?.handle
|
|
325
|
+
? await app.handle(req, (next) => handler(next, pathParams, store))
|
|
326
|
+
: await handler(req, pathParams, store)
|
|
327
|
+
/* Gzip compressible dynamic bodies (SSR HTML, rpc/json, 404) when the
|
|
328
|
+
client accepts it; streaming frame protocols and static assets are
|
|
329
|
+
passed through untouched (see gzipResponse). */
|
|
330
|
+
const encoded = gzipResponse(req, response)
|
|
331
|
+
// Streaming bodies (sse/jsonl, socket tail) opt out of the idle timeout.
|
|
332
|
+
return disableIdleTimeoutForStream(server, req, encoded)
|
|
333
|
+
})
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/*
|
|
337
|
+
Abide's only native WebSocket surface is the sockets hub: every Socket
|
|
338
|
+
declared under src/server/sockets/ multiplexes onto one framework-owned
|
|
339
|
+
connection per client at /__abide/sockets. The dispatcher owns the
|
|
340
|
+
open/message/close handlers below; user code never sees the raw ws
|
|
341
|
+
lifecycle. Steady-state fan-out rides Bun's native server.publish so
|
|
342
|
+
a busy socket doesn't iterate JS per subscriber per message.
|
|
343
|
+
*/
|
|
344
|
+
const socketDispatcher = createSocketDispatcher(sockets)
|
|
345
|
+
|
|
346
|
+
/*
|
|
347
|
+
Bind the real server on `boundPort`. Only the port varies between scan
|
|
348
|
+
attempts, so the rest of the config lives inline and just the port is spread
|
|
349
|
+
in — passing the literal straight to Bun.serve keeps contextual typing of the
|
|
350
|
+
websocket handlers (and Server<unknown> pins Bun's WebSocketData generic so
|
|
351
|
+
upgrade({ data: {} }) typechecks).
|
|
352
|
+
*/
|
|
353
|
+
const bindAt = (boundPort: number): Server<unknown> =>
|
|
354
|
+
Bun.serve({
|
|
355
|
+
port: boundPort,
|
|
356
|
+
idleTimeout,
|
|
357
|
+
maxRequestBodySize,
|
|
358
|
+
/*
|
|
359
|
+
Dev workers overlap during a restart: the replacement binds while its
|
|
360
|
+
predecessor still serves, and the kernel keeps delivering connections
|
|
361
|
+
to the old listener until it stops — the port never refuses a request
|
|
362
|
+
mid-swap. Dev-only: in production a port collision should fail loudly.
|
|
363
|
+
*/
|
|
364
|
+
reusePort: dev,
|
|
365
|
+
|
|
366
|
+
websocket: {
|
|
367
|
+
open(ws) {
|
|
368
|
+
socketDispatcher.open(ws)
|
|
369
|
+
},
|
|
370
|
+
message(ws, data) {
|
|
371
|
+
socketDispatcher.message(ws, data)
|
|
372
|
+
},
|
|
373
|
+
close(ws) {
|
|
374
|
+
socketDispatcher.close(ws)
|
|
375
|
+
},
|
|
376
|
+
},
|
|
377
|
+
|
|
378
|
+
routes,
|
|
379
|
+
|
|
380
|
+
async fetch(req, bunServer) {
|
|
381
|
+
const url = new URL(req.url)
|
|
382
|
+
/*
|
|
383
|
+
Health/identity probe — answered directly, ahead of any app.handle
|
|
384
|
+
middleware, so the bundle's connect screen, the CLI, and the client
|
|
385
|
+
health() can confirm a URL really is a live abide server even when
|
|
386
|
+
the app guards everything behind auth (reporting
|
|
387
|
+
`authenticated: false` requires exactly that). The app's optional
|
|
388
|
+
health hook contributes fields; the framework's identity keys win
|
|
389
|
+
on collision, and a thrown hook is logged and skipped so an app
|
|
390
|
+
bug can't masquerade as an unreachable server. IDENTITY_PATH is
|
|
391
|
+
the compatibility alias for the same payload.
|
|
392
|
+
*/
|
|
393
|
+
if (url.pathname === HEALTH_PATH || url.pathname === IDENTITY_PATH) {
|
|
394
|
+
const payload = await buildHealthPayload(req, { app, appName, appVersion })
|
|
395
|
+
return gzipResponse(
|
|
396
|
+
req,
|
|
397
|
+
Response.json(
|
|
398
|
+
/*
|
|
399
|
+
The IDENTITY_PATH alias keeps the legacy `abide: true`
|
|
400
|
+
shape: already-shipped probers check it with strict
|
|
401
|
+
equality, and a version string would make them treat
|
|
402
|
+
an upgraded healthy server as not-abide.
|
|
403
|
+
*/
|
|
404
|
+
url.pathname === IDENTITY_PATH ? { ...payload, abide: true } : payload,
|
|
405
|
+
{ headers: { 'Cache-Control': NO_STORE } },
|
|
406
|
+
),
|
|
407
|
+
)
|
|
408
|
+
}
|
|
409
|
+
/*
|
|
410
|
+
Inspector surface — answered directly, ahead of app.handle, since
|
|
411
|
+
it's privileged operator tooling gated by ABIDE_ENABLE_INSPECTOR
|
|
412
|
+
(not the app's user auth). Undefined handler = flag off, so the
|
|
413
|
+
whole block compiles out of the hot path when the inspector's off.
|
|
414
|
+
*/
|
|
415
|
+
if (
|
|
416
|
+
inspectorHandler &&
|
|
417
|
+
(url.pathname === INSPECTOR_PATH ||
|
|
418
|
+
url.pathname.startsWith(`${INSPECTOR_PATH}/`))
|
|
419
|
+
) {
|
|
420
|
+
// The events feed is long-lived SSE: opt it out of the idle
|
|
421
|
+
// timeout, else Bun reaps it and the reconnect replays the
|
|
422
|
+
// whole buffer (duplicate boot logs every ~10s).
|
|
423
|
+
return disableIdleTimeoutForStream(
|
|
424
|
+
bunServer,
|
|
425
|
+
req,
|
|
426
|
+
await inspectorHandler(req, url),
|
|
427
|
+
)
|
|
428
|
+
}
|
|
429
|
+
/*
|
|
430
|
+
Dev live-reload channel — answered directly, ahead of app.handle,
|
|
431
|
+
so a restart-driven reconnect always lands even when the app guards
|
|
432
|
+
everything behind auth. Only mounted under `abide dev`.
|
|
433
|
+
*/
|
|
434
|
+
if (clientFingerprint !== undefined && url.pathname === DEV_RELOAD_PATH) {
|
|
435
|
+
// Long-lived SSE: opt out of the idle timeout, else Bun reaps
|
|
436
|
+
// it and the reconnect triggers a spurious reload loop.
|
|
437
|
+
return disableIdleTimeoutForStream(
|
|
438
|
+
bunServer,
|
|
439
|
+
req,
|
|
440
|
+
devReloadResponse(clientFingerprint),
|
|
441
|
+
)
|
|
442
|
+
}
|
|
443
|
+
/* Component hot module — the browser imports one edited `.abide`'s
|
|
444
|
+
hot build here instead of reloading (dev component HMR). */
|
|
445
|
+
if (clientFingerprint !== undefined && url.pathname.startsWith(DEV_HOT_PREFIX)) {
|
|
446
|
+
return devHotModuleResponse(
|
|
447
|
+
decodeURIComponent(url.pathname.slice(DEV_HOT_PREFIX.length)),
|
|
448
|
+
)
|
|
449
|
+
}
|
|
450
|
+
/*
|
|
451
|
+
Manual rebuild trigger: signal the orchestrator parent over IPC to
|
|
452
|
+
rebuild + restart. Same-origin sibling of the live-reload channel, so
|
|
453
|
+
a script refreshes on the app's own port. process.send exists only when
|
|
454
|
+
the dev orchestrator spawned us with ipc; the optional chain no-ops on a
|
|
455
|
+
bare server.
|
|
456
|
+
*/
|
|
457
|
+
if (dev && req.method === 'POST' && url.pathname === DEV_REBUILD_PATH) {
|
|
458
|
+
process.send?.(DEV_REBUILD_MESSAGE)
|
|
459
|
+
return new Response('rebuilding\n', {
|
|
460
|
+
headers: { 'Content-Type': TEXT_PLAIN },
|
|
461
|
+
})
|
|
462
|
+
}
|
|
463
|
+
if (url.pathname === SOCKETS_PATH) {
|
|
464
|
+
// Reject cross-origin upgrades (CSWSH) before handing off to Bun.
|
|
465
|
+
const upgradeForbidden = crossOriginGate(req, url)
|
|
466
|
+
if (upgradeForbidden) {
|
|
467
|
+
return upgradeForbidden
|
|
468
|
+
}
|
|
469
|
+
if (bunServer.upgrade(req, { data: {} })) {
|
|
470
|
+
return undefined as unknown as Response
|
|
471
|
+
}
|
|
472
|
+
return new Response('Upgrade failed', {
|
|
473
|
+
status: 400,
|
|
474
|
+
headers: { 'Content-Type': TEXT_PLAIN },
|
|
475
|
+
})
|
|
476
|
+
}
|
|
477
|
+
/*
|
|
478
|
+
HTTP face of a socket (`/__abide/sockets/<name>`) — tail over
|
|
479
|
+
SSE / JSON and publish — for the CLI and MCP. Runs through
|
|
480
|
+
dispatchRequest so app.handle auth applies, like the rpc paths.
|
|
481
|
+
The socket name may contain `/` (nested files), so it's the
|
|
482
|
+
whole remaining pathname, percent-decoded.
|
|
483
|
+
*/
|
|
484
|
+
if (url.pathname.startsWith(SOCKETS_REST_PREFIX)) {
|
|
485
|
+
/*
|
|
486
|
+
Gate cross-origin browser publishes (CSRF, see crossOriginGate).
|
|
487
|
+
GET tail reads stay open cross-origin like rpc reads; only
|
|
488
|
+
the mutating POST is gated.
|
|
489
|
+
*/
|
|
490
|
+
const publishForbidden = crossOriginGate(req, url, { allowReadOnly: true })
|
|
491
|
+
if (publishForbidden) {
|
|
492
|
+
return publishForbidden
|
|
493
|
+
}
|
|
494
|
+
const name = decodeURIComponent(url.pathname.slice(SOCKETS_REST_PREFIX.length))
|
|
495
|
+
return dispatchRequest(
|
|
496
|
+
req,
|
|
497
|
+
{},
|
|
498
|
+
async () => socketDispatcher.rest(req, name),
|
|
499
|
+
url,
|
|
500
|
+
)
|
|
501
|
+
}
|
|
502
|
+
if (url.pathname === MCP_PATH && mcp) {
|
|
503
|
+
// Gate cross-site browser posts (CSRF, see crossOriginGate).
|
|
504
|
+
const mcpForbidden = crossOriginGate(req, url)
|
|
505
|
+
if (mcpForbidden) {
|
|
506
|
+
return mcpForbidden
|
|
507
|
+
}
|
|
508
|
+
return dispatchRequest(req, {}, async () => mcp.handle(req), url)
|
|
509
|
+
}
|
|
510
|
+
if (url.pathname === CLI_PATH) {
|
|
511
|
+
return dispatchRequest(req, {}, async () => handleCliInstall(req, cliName), url)
|
|
512
|
+
}
|
|
513
|
+
if (url.pathname.startsWith(CLI_DOWNLOAD_PREFIX)) {
|
|
514
|
+
const platform = url.pathname.slice(CLI_DOWNLOAD_PREFIX.length)
|
|
515
|
+
return dispatchRequest(
|
|
516
|
+
req,
|
|
517
|
+
{},
|
|
518
|
+
async () => handleCliDownload(req, platform, cliName, cliCwd),
|
|
519
|
+
url,
|
|
520
|
+
)
|
|
521
|
+
}
|
|
522
|
+
if (url.pathname === OPENAPI_PATH) {
|
|
523
|
+
return dispatchRequest(
|
|
524
|
+
req,
|
|
525
|
+
{},
|
|
526
|
+
async () => {
|
|
527
|
+
if (!openApiSpec) {
|
|
528
|
+
await ensureRegistriesLoaded()
|
|
529
|
+
openApiSpec = buildOpenApiSpec({
|
|
530
|
+
title: appName,
|
|
531
|
+
version: appVersion,
|
|
532
|
+
})
|
|
533
|
+
}
|
|
534
|
+
return Response.json(openApiSpec, {
|
|
535
|
+
headers: { 'Cache-Control': NO_STORE },
|
|
536
|
+
})
|
|
537
|
+
},
|
|
538
|
+
url,
|
|
539
|
+
)
|
|
540
|
+
}
|
|
541
|
+
/*
|
|
542
|
+
Static assets sidestep ALS + the per-request CacheStore + the
|
|
543
|
+
app.handle middleware: they have no need for cache() and the
|
|
544
|
+
allocation overhead matters on a cold page load that pulls
|
|
545
|
+
dozens of chunks. The global server.error() handler still
|
|
546
|
+
catches anything that goes wrong inside serveAppAsset.
|
|
547
|
+
*/
|
|
548
|
+
if (url.pathname.startsWith('/_app/')) {
|
|
549
|
+
if (!logRequests) {
|
|
550
|
+
return serveAppAsset(req, url)
|
|
551
|
+
}
|
|
552
|
+
const start = Bun.nanoseconds()
|
|
553
|
+
const response = await serveAppAsset(req, url)
|
|
554
|
+
const ms = (Bun.nanoseconds() - start) / 1e6
|
|
555
|
+
logClosingRecord(
|
|
556
|
+
req.method,
|
|
557
|
+
`${url.pathname}${url.search}`,
|
|
558
|
+
response.status,
|
|
559
|
+
ms,
|
|
560
|
+
)
|
|
561
|
+
return response
|
|
562
|
+
}
|
|
563
|
+
/*
|
|
564
|
+
Files under public/ are served at the site root, sidestepping
|
|
565
|
+
ALS + middleware like the /_app/ assets do. A miss returns
|
|
566
|
+
undefined so the request falls through to the 404 / middleware
|
|
567
|
+
path below.
|
|
568
|
+
*/
|
|
569
|
+
const publicStart = Bun.nanoseconds()
|
|
570
|
+
const publicResponse = await servePublicAsset(req, url)
|
|
571
|
+
if (publicResponse) {
|
|
572
|
+
if (logRequests) {
|
|
573
|
+
logClosingRecord(
|
|
574
|
+
req.method,
|
|
575
|
+
`${url.pathname}${url.search}`,
|
|
576
|
+
publicResponse.status,
|
|
577
|
+
(Bun.nanoseconds() - publicStart) / 1e6,
|
|
578
|
+
)
|
|
579
|
+
}
|
|
580
|
+
return publicResponse
|
|
581
|
+
}
|
|
582
|
+
/*
|
|
583
|
+
Unknown routes still run through dispatchRequest so user-defined
|
|
584
|
+
app.handle middleware can rewrite the request, serve a custom
|
|
585
|
+
404, or branch on the URL. The inner handler returns the
|
|
586
|
+
framework's default 404 when nothing intervenes.
|
|
587
|
+
*/
|
|
588
|
+
return dispatchRequest(
|
|
589
|
+
req,
|
|
590
|
+
{},
|
|
591
|
+
async (_req, _pathParams, store) => {
|
|
592
|
+
return (
|
|
593
|
+
(await renderError(404, 'Not Found', store)) ??
|
|
594
|
+
new Response('Not Found', {
|
|
595
|
+
status: 404,
|
|
596
|
+
headers: { 'Content-Type': TEXT_PLAIN, 'Cache-Control': NO_STORE },
|
|
597
|
+
})
|
|
598
|
+
)
|
|
599
|
+
},
|
|
600
|
+
url,
|
|
601
|
+
)
|
|
602
|
+
},
|
|
603
|
+
|
|
604
|
+
error(err) {
|
|
605
|
+
abideLog.error(err)
|
|
606
|
+
return internalErrorResponse(err)
|
|
607
|
+
},
|
|
608
|
+
})
|
|
609
|
+
|
|
610
|
+
/*
|
|
611
|
+
A configured PORT binds that exact port — a collision surfaces loudly rather
|
|
612
|
+
than silently moving, since something connecting to the app needs a known
|
|
613
|
+
address. With none set, scan upward from 3000 binding the real listener, so
|
|
614
|
+
whichever server wins the port keeps it (no probe-release gap to lose it in,
|
|
615
|
+
which used to crash boot on EADDRINUSE instead of stepping to the next port).
|
|
616
|
+
*/
|
|
617
|
+
const server: Server<unknown> =
|
|
618
|
+
port === undefined ? listenOnOpenPort(bindAt, DEFAULT_PORT) : bindAt(port)
|
|
619
|
+
|
|
620
|
+
/*
|
|
621
|
+
Publishes the live server through `abide/server` before invoking the
|
|
622
|
+
user's init() hook. The exported `server()` function reads from this
|
|
623
|
+
slot and throws on access before the slot is set, so init() callers
|
|
624
|
+
can hold the import at module scope and still see the real instance
|
|
625
|
+
once boot completes.
|
|
626
|
+
*/
|
|
627
|
+
setActiveServer(server)
|
|
628
|
+
|
|
629
|
+
const cleanup = app?.init ? await app.init({ server }) : undefined
|
|
630
|
+
/*
|
|
631
|
+
Close the listener deterministically on shutdown. Always registered (even
|
|
632
|
+
with no init cleanup) so the socket is released via server.stop rather than
|
|
633
|
+
left to abrupt process exit — which leaves the port in TIME_WAIT and races
|
|
634
|
+
a fast restart. A watchdog force-exits if a user cleanup hangs, so a stuck
|
|
635
|
+
cleanup can't keep the process (and its port) alive.
|
|
636
|
+
*/
|
|
637
|
+
const shutdown = async () => {
|
|
638
|
+
server.stop(true)
|
|
639
|
+
if (typeof cleanup === 'function') {
|
|
640
|
+
setTimeout(() => process.exit(0), 3000).unref()
|
|
641
|
+
try {
|
|
642
|
+
await cleanup()
|
|
643
|
+
} catch (err) {
|
|
644
|
+
abideLog.error(err)
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
process.exit(0)
|
|
648
|
+
}
|
|
649
|
+
process.once('SIGINT', shutdown)
|
|
650
|
+
process.once('SIGTERM', shutdown)
|
|
651
|
+
|
|
652
|
+
/*
|
|
653
|
+
Diagnostic only, and only under `abide` debug logging — eager-loads the
|
|
654
|
+
registry to print the page/socket/rpc surface maps (routing + which
|
|
655
|
+
declarations reach mcp/cli/openapi), making abide's multimodal-by-default
|
|
656
|
+
exposure auditable. Awaited so `ready` lands after all of abide's own
|
|
657
|
+
startup output rather than interleaving with it.
|
|
658
|
+
*/
|
|
659
|
+
if (logRequests) {
|
|
660
|
+
await logExposedSurfaces({ pages })
|
|
661
|
+
}
|
|
662
|
+
// Unguarded machine surface check — app.handle is the blessed auth seam.
|
|
663
|
+
if (mcp && !app?.handle) {
|
|
664
|
+
await warnUnguardedMcp()
|
|
665
|
+
}
|
|
666
|
+
abideLog.success(`ready at http://localhost:${server.port}`)
|
|
667
|
+
// Tell the dev orchestrator (when it spawned us with ipc) that boot is
|
|
668
|
+
// complete, so it can retire the previous worker — finishing the
|
|
669
|
+
// zero-downtime swap. No-op on a bare server: process.send is undefined.
|
|
670
|
+
if (dev) {
|
|
671
|
+
process.send?.(DEV_READY_MESSAGE)
|
|
672
|
+
}
|
|
673
|
+
return server
|
|
674
|
+
}
|