@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
package/src/appEntry.ts
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
// @ts-expect-error virtual module resolved by abideResolverPlugin
|
|
2
|
+
import { disconnectedHtml } from './_virtual/bundle-disconnected.ts'
|
|
3
|
+
// @ts-expect-error virtual module resolved by abideResolverPlugin
|
|
4
|
+
import bundleWindow from './_virtual/bundle-window.ts'
|
|
5
|
+
// @ts-expect-error virtual module resolved by abideResolverPlugin
|
|
6
|
+
import programName from './_virtual/cli-name.ts'
|
|
7
|
+
import type { BundleMenu } from './lib/bundle/BundleMenu.ts'
|
|
8
|
+
import type { BundleWindow } from './lib/bundle/BundleWindow.ts'
|
|
9
|
+
import { openWebview } from './lib/bundle/openWebview.ts'
|
|
10
|
+
import { envSchemaStore } from './lib/server/runtime/envSchemaStore.ts'
|
|
11
|
+
import { abideLog } from './lib/shared/abideLog.ts'
|
|
12
|
+
import { jsonSchemaForSchema } from './lib/shared/jsonSchemaForSchema.ts'
|
|
13
|
+
|
|
14
|
+
/*
|
|
15
|
+
Compiled bundle launcher entry — the executable a bundle runs. Instead of a blank
|
|
16
|
+
window it boots into a connect screen, letting the user either connect to a remote
|
|
17
|
+
server by URL or start the embedded server binary that ships beside this launcher.
|
|
18
|
+
|
|
19
|
+
The connect screen is served by a tiny control server, but that server can't live
|
|
20
|
+
on this main thread: `openWebview` calls `webview_run`, a native UI loop that
|
|
21
|
+
blocks the thread (and its JS event loop) until the window closes, so an
|
|
22
|
+
in-process `Bun.serve` would never answer. The control server runs in a Worker
|
|
23
|
+
instead (see controlServerWorker.ts) and hands back the origin to point the window
|
|
24
|
+
at; it also owns the embedded-server child and the native menu flag, since neither
|
|
25
|
+
can be driven from a main thread frozen inside webview_run.
|
|
26
|
+
|
|
27
|
+
Bun doesn't apply this build's plugins to the worker entry, so the worker can't
|
|
28
|
+
import abide's virtual modules; this entry imports them (the connect-screen HTML,
|
|
29
|
+
the app title) and passes them in the worker's `init` message.
|
|
30
|
+
|
|
31
|
+
The window owns the main thread; on close we tell the worker to reap its child.
|
|
32
|
+
*/
|
|
33
|
+
const window = bundleWindow as BundleWindow
|
|
34
|
+
const title = window.title ?? programName
|
|
35
|
+
|
|
36
|
+
/*
|
|
37
|
+
Derive the config form's JSON Schema here (the worker can't import the virtuals
|
|
38
|
+
that carry the schema) and pass the plain object through init — the validator
|
|
39
|
+
itself isn't serializable, but its JSON Schema is. Undefined when the app
|
|
40
|
+
declares no config, so the connect screen never gates Start.
|
|
41
|
+
|
|
42
|
+
Default source is src/server/config.ts's env schema, so one declaration drives
|
|
43
|
+
both boot validation and the setup form. Imported with skipValidation set — we
|
|
44
|
+
want the schema's shape, not a boot check the launcher has no business running.
|
|
45
|
+
`window.config` replaces it when set, for a bundle form that should differ from
|
|
46
|
+
the env schema.
|
|
47
|
+
*/
|
|
48
|
+
envSchemaStore.skipValidation = true
|
|
49
|
+
// @ts-expect-error virtual module resolved by abideResolverPlugin
|
|
50
|
+
await import('./_virtual/config.ts')
|
|
51
|
+
const formSchema = window.config ?? envSchemaStore.schema
|
|
52
|
+
const configSchema = formSchema ? jsonSchemaForSchema(formSchema) : undefined
|
|
53
|
+
|
|
54
|
+
/*
|
|
55
|
+
Spawn the control server worker. `__ABIDE_WORKER_ENTRY__` is the worker's absolute
|
|
56
|
+
path, injected by bundleApp via Bun's `define` so the specifier is a static literal
|
|
57
|
+
at build time — that's what makes `bun build --compile` embed the worker module
|
|
58
|
+
into the standalone binary. A relative specifier resolves against the build's cwd
|
|
59
|
+
(the consumer project), not this file, so it isn't found; a
|
|
60
|
+
`new URL(..., import.meta.url)` specifier isn't embedded at all.
|
|
61
|
+
*/
|
|
62
|
+
declare const __ABIDE_WORKER_ENTRY__: string
|
|
63
|
+
const worker = new Worker(__ABIDE_WORKER_ENTRY__)
|
|
64
|
+
|
|
65
|
+
worker.addEventListener('error', (event: ErrorEvent) => {
|
|
66
|
+
abideLog.error(`control server worker failed: ${event.message}`)
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
// Hand the worker the plugin-resolved data it can't import itself, then start it.
|
|
70
|
+
worker.postMessage({
|
|
71
|
+
type: 'init',
|
|
72
|
+
init: { disconnectedHtml: disconnectedHtml as string, title, programName, configSchema },
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
/*
|
|
76
|
+
The worker, once bound, resolves where the window should open and posts both the
|
|
77
|
+
control-server `origin` (for the File-menu action URLs) and the `target` to point
|
|
78
|
+
the window at now: the live server when it could resume the last connection, else
|
|
79
|
+
the connect screen. Resolving before this means a successful resume opens straight
|
|
80
|
+
at the app — no connect-screen flash — at the cost of a brief window-less moment
|
|
81
|
+
while it boots/probes (the OS shows the launching dock icon meanwhile).
|
|
82
|
+
*/
|
|
83
|
+
const { origin, target } = await new Promise<{ origin: string; target: string }>((resolve) => {
|
|
84
|
+
worker.addEventListener('message', (event: MessageEvent) => {
|
|
85
|
+
const data = event.data as { type: string; origin?: string; target?: string }
|
|
86
|
+
if (data.type === 'ready' && data.origin && data.target) {
|
|
87
|
+
resolve({ origin: data.origin, target: data.target })
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
/*
|
|
93
|
+
The built-in File menu (Start / Disconnect), placed before Edit. Each item is a
|
|
94
|
+
`navigate` repointing the window at a control-server URL the connect screen
|
|
95
|
+
interprets; the internal `role` drives the native validateMenuItem: gating (Start
|
|
96
|
+
when disconnected, Disconnect when connected). There's no Connect item — Disconnect
|
|
97
|
+
already returns to the connect screen, whose form is the place to point at another
|
|
98
|
+
server. Roled items are launcher-only, so they carry an extra field the public
|
|
99
|
+
BundleMenuItem type doesn't advertise — modelled here with a local type and bridged
|
|
100
|
+
to BundleMenu when handed to openWebview (which only serialises the menu to JSON).
|
|
101
|
+
*/
|
|
102
|
+
type FileMenuItem =
|
|
103
|
+
| { separator: true }
|
|
104
|
+
| {
|
|
105
|
+
label: string
|
|
106
|
+
shortcut?: string
|
|
107
|
+
navigate: string
|
|
108
|
+
role: 'start' | 'disconnect'
|
|
109
|
+
}
|
|
110
|
+
const fileMenu: { label: string; items: FileMenuItem[] } = {
|
|
111
|
+
label: 'File',
|
|
112
|
+
items: [
|
|
113
|
+
{ label: 'Start Server', navigate: `${origin}/?action=start`, role: 'start' },
|
|
114
|
+
{ separator: true },
|
|
115
|
+
{ label: 'Disconnect', navigate: `${origin}/?action=disconnect`, role: 'disconnect' },
|
|
116
|
+
],
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
abideLog.info(`opening ${title} window at ${target}`)
|
|
120
|
+
await openWebview({
|
|
121
|
+
url: target,
|
|
122
|
+
title,
|
|
123
|
+
width: window.width,
|
|
124
|
+
height: window.height,
|
|
125
|
+
menu: window.menu,
|
|
126
|
+
fileMenu: fileMenu as unknown as BundleMenu,
|
|
127
|
+
// Forward the window handle so the worker can bounce it back to the connect
|
|
128
|
+
// screen if the connected server stops responding.
|
|
129
|
+
onWindow: (handle) => {
|
|
130
|
+
if (handle) {
|
|
131
|
+
worker.postMessage({ type: 'window', handle: Number(handle) })
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
/*
|
|
137
|
+
Window closed — have the worker reap the embedded server child and stop its
|
|
138
|
+
control server before we exit, since both live on the worker thread. Bounded by a
|
|
139
|
+
timeout so a wedged worker can't keep the launcher alive.
|
|
140
|
+
*/
|
|
141
|
+
await new Promise<void>((resolve) => {
|
|
142
|
+
worker.addEventListener('message', (event: MessageEvent) => {
|
|
143
|
+
if ((event.data as { type?: string }).type === 'shutdownDone') {
|
|
144
|
+
resolve()
|
|
145
|
+
}
|
|
146
|
+
})
|
|
147
|
+
worker.postMessage({ type: 'shutdown' })
|
|
148
|
+
setTimeout(resolve, 1000)
|
|
149
|
+
})
|
|
150
|
+
worker.terminate()
|
|
151
|
+
process.exit(0)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<!--ssr:head-->
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div id="app"><!--ssr:body--></div>
|
|
10
|
+
<!--ssr:state-->
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
package/src/build.ts
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { clientBuildPlugins } from './clientBuildPlugins.ts'
|
|
2
|
+
import { abideLog } from './lib/shared/abideLog.ts'
|
|
3
|
+
import { exitOnBuildFailure } from './lib/shared/exitOnBuildFailure.ts'
|
|
4
|
+
|
|
5
|
+
const CLIENT_ENTRY = new URL('./clientEntry.ts', import.meta.url).pathname
|
|
6
|
+
|
|
7
|
+
/*
|
|
8
|
+
Builds the client-side bundle into `${cwd}/dist/_app`. Runs Bun.build with
|
|
9
|
+
the abide-ui `.abide` loader, the virtual-module resolver, and (optionally)
|
|
10
|
+
Tailwind. When `compress`, each emitted file is also
|
|
11
|
+
written as a gzip-compressed `.gz` sibling (level 9 — paid once at build
|
|
12
|
+
time) so the server can stream the precompressed bytes directly to any client
|
|
13
|
+
that accepts gzip (effectively all), and decompress on the fly otherwise. Dev
|
|
14
|
+
skips compression (compressing on every rebuild dwarfs the bundle itself) — the
|
|
15
|
+
server falls back to serving the plain bytes when no `.gz` sibling exists.
|
|
16
|
+
|
|
17
|
+
The bundle is emitted into a per-build staging dir, then swapped into
|
|
18
|
+
`_app` with two atomic renames. This keeps every build's writes isolated to
|
|
19
|
+
a unique path (so a stray concurrent build can never `rm` files Bun is
|
|
20
|
+
mid-flushing — the "writing sourcemap: No such file or directory" race) and
|
|
21
|
+
means a long-running dev server reading `_app` lazily off disk never sees a
|
|
22
|
+
half-built or emptied directory.
|
|
23
|
+
|
|
24
|
+
`clean` (one-shot builds) clears the whole dist up front so downstream
|
|
25
|
+
writers — the bundle's connect screen, the CLI manifest — start fresh; the
|
|
26
|
+
dev orchestrator passes `clean: false` to leave the live dist untouched and
|
|
27
|
+
only swap `_app` at the end.
|
|
28
|
+
|
|
29
|
+
Returns whether the build succeeded. Never throws: a thrown Bun.build / fs
|
|
30
|
+
error is logged and treated as a failed build, so the dev loop (and its
|
|
31
|
+
last-good server) survives instead of crashing and orphaning the child. By
|
|
32
|
+
default a failure exits the process (one-shot `abide build` / `compile`);
|
|
33
|
+
the dev orchestrator passes `exitOnFailure: false`.
|
|
34
|
+
*/
|
|
35
|
+
// @readme plumbing
|
|
36
|
+
export async function build({
|
|
37
|
+
cwd = process.cwd(),
|
|
38
|
+
minify = true,
|
|
39
|
+
compress = true,
|
|
40
|
+
clean = true,
|
|
41
|
+
exitOnFailure = true,
|
|
42
|
+
}: {
|
|
43
|
+
cwd?: string
|
|
44
|
+
minify?: boolean
|
|
45
|
+
compress?: boolean
|
|
46
|
+
clean?: boolean
|
|
47
|
+
exitOnFailure?: boolean
|
|
48
|
+
} = {}): Promise<boolean> {
|
|
49
|
+
const distDir = `${cwd}/dist`
|
|
50
|
+
const outDir = `${distDir}/_app`
|
|
51
|
+
// Per-build staging + holding dirs; the suffix isolates concurrent builds.
|
|
52
|
+
const buildId = crypto.randomUUID().slice(0, 8)
|
|
53
|
+
const stagingDir = `${distDir}/_app.staging-${buildId}`
|
|
54
|
+
const previousDir = `${distDir}/_app.old-${buildId}`
|
|
55
|
+
|
|
56
|
+
const fail = (): boolean => {
|
|
57
|
+
if (exitOnFailure) {
|
|
58
|
+
process.exit(1)
|
|
59
|
+
}
|
|
60
|
+
return false
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
// shell-rm/-mv are the impure boundary for the dist swap — Bun.$ is first-party.
|
|
65
|
+
if (clean) {
|
|
66
|
+
await Bun.$`rm -rf ${distDir}`.quiet()
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const plugins = await clientBuildPlugins({
|
|
70
|
+
cwd,
|
|
71
|
+
tailwindWarning: 'bun-plugin-tailwind not installed; building without Tailwind',
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
const result = await Bun.build({
|
|
75
|
+
entrypoints: [CLIENT_ENTRY],
|
|
76
|
+
outdir: stagingDir,
|
|
77
|
+
target: 'browser',
|
|
78
|
+
splitting: true,
|
|
79
|
+
minify,
|
|
80
|
+
sourcemap: 'linked',
|
|
81
|
+
naming: {
|
|
82
|
+
entry: 'client-[hash].[ext]',
|
|
83
|
+
chunk: '[name]-[hash].[ext]',
|
|
84
|
+
asset: '[name].[ext]',
|
|
85
|
+
},
|
|
86
|
+
plugins,
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
if (!result.success) {
|
|
90
|
+
await Bun.$`rm -rf ${stagingDir}`.quiet().nothrow()
|
|
91
|
+
if (exitOnFailure) {
|
|
92
|
+
exitOnBuildFailure(result)
|
|
93
|
+
}
|
|
94
|
+
result.logs.forEach((entry) => {
|
|
95
|
+
abideLog.error(entry)
|
|
96
|
+
})
|
|
97
|
+
return false
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Dev skips the gzip siblings (paths still point into stagingDir here).
|
|
101
|
+
const compressedBytes = compress
|
|
102
|
+
? (
|
|
103
|
+
await Promise.all(
|
|
104
|
+
result.outputs.map(async (output) => {
|
|
105
|
+
const bytes = await Bun.file(output.path).bytes()
|
|
106
|
+
const compressed = Bun.gzipSync(bytes, { level: 9 })
|
|
107
|
+
await Bun.write(`${output.path}.gz`, compressed)
|
|
108
|
+
return compressed.byteLength
|
|
109
|
+
}),
|
|
110
|
+
)
|
|
111
|
+
).reduce((total, length) => total + length, 0)
|
|
112
|
+
: 0
|
|
113
|
+
|
|
114
|
+
/*
|
|
115
|
+
Swap staging into _app with two renames: move any existing _app aside,
|
|
116
|
+
then rename staging into place. The window where _app is absent is a
|
|
117
|
+
single rename, so a reader (the running dev server) never observes a
|
|
118
|
+
partial bundle. nothrow on the first move: no _app exists on the first
|
|
119
|
+
build or after `clean`.
|
|
120
|
+
*/
|
|
121
|
+
await Bun.$`mv ${outDir} ${previousDir}`.quiet().nothrow()
|
|
122
|
+
await Bun.$`mv ${stagingDir} ${outDir}`.quiet()
|
|
123
|
+
await Bun.$`rm -rf ${previousDir}`.quiet().nothrow()
|
|
124
|
+
|
|
125
|
+
if (compress) {
|
|
126
|
+
abideLog.info(
|
|
127
|
+
`wrote ${result.outputs.length} files to ${outDir} (+${result.outputs.length} .gz, ${(compressedBytes / 1024).toFixed(1)} KiB total)`,
|
|
128
|
+
)
|
|
129
|
+
// Per-file paths are noise at startup; surface them only under DEBUG=abide:build.
|
|
130
|
+
const buildLog = abideLog.channel('abide:build')
|
|
131
|
+
result.outputs.forEach((output) => {
|
|
132
|
+
buildLog(` - ${output.path.replace(stagingDir, outDir)}`)
|
|
133
|
+
})
|
|
134
|
+
} else {
|
|
135
|
+
abideLog.info(`wrote ${result.outputs.length} files to ${outDir}`)
|
|
136
|
+
}
|
|
137
|
+
return true
|
|
138
|
+
} catch (error) {
|
|
139
|
+
abideLog.error(error)
|
|
140
|
+
await Bun.$`rm -rf ${stagingDir} ${previousDir}`.quiet().nothrow()
|
|
141
|
+
return fail()
|
|
142
|
+
}
|
|
143
|
+
}
|
package/src/buildCli.ts
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { dirname, join } from 'node:path'
|
|
2
|
+
import { build } from './build.ts'
|
|
3
|
+
import { compile } from './compile.ts'
|
|
4
|
+
import { abideLog } from './lib/shared/abideLog.ts'
|
|
5
|
+
import { detectTarget } from './lib/shared/detectTarget.ts'
|
|
6
|
+
import { exeSuffix } from './lib/shared/exeSuffix.ts'
|
|
7
|
+
import { exitOnBuildFailure } from './lib/shared/exitOnBuildFailure.ts'
|
|
8
|
+
import { programNameForPackage } from './lib/shared/programNameForPackage.ts'
|
|
9
|
+
import { readPackageJson } from './lib/shared/readPackageJson.ts'
|
|
10
|
+
import type { CompileTarget } from './lib/shared/types/CompileTarget.ts'
|
|
11
|
+
import { serverBuildPlugins } from './serverBuildPlugins.ts'
|
|
12
|
+
|
|
13
|
+
const DISCOVERY_ENTRY = new URL('./discoveryEntry.ts', import.meta.url).pathname
|
|
14
|
+
const CLI_ENTRY = new URL('./cliEntry.ts', import.meta.url).pathname
|
|
15
|
+
|
|
16
|
+
/*
|
|
17
|
+
CLI binary build. The CLI is a thin remote client — it bakes in the per-rpc
|
|
18
|
+
manifest and talks to a running server over HTTP — but the **full** binary ships
|
|
19
|
+
the compiled server beside it, so `/start` can spawn a local instance.
|
|
20
|
+
|
|
21
|
+
1. Client build (once): `build` produces the platform-independent `dist/_app`
|
|
22
|
+
the server binaries embed. It clears dist first, so it runs before everything.
|
|
23
|
+
2. Discovery: build the discovery entry into a temporary JS bundle and run it. It
|
|
24
|
+
imports every rpc/socket module so defineVerb / defineSocket populate the
|
|
25
|
+
registries, then prints the CLI manifest to stdout → `dist/cli-manifest.json`.
|
|
26
|
+
3. Per target: a server binary (`compile`, reusing the shared `dist/_app` via
|
|
27
|
+
`buildClient:false`) plus the CLI binary, written side by side. The resolver's
|
|
28
|
+
`abide:cli-manifest` virtual splices in the manifest from step 2.
|
|
29
|
+
|
|
30
|
+
`platforms` cross-compiles per target into `dist/cli-thin/<platform>/` (the layout
|
|
31
|
+
the /__abide/cli download endpoint serves): `<programName>` + `server` together.
|
|
32
|
+
*/
|
|
33
|
+
export async function buildCli({
|
|
34
|
+
cwd = process.cwd(),
|
|
35
|
+
target = detectTarget(),
|
|
36
|
+
outfile,
|
|
37
|
+
platforms,
|
|
38
|
+
}: {
|
|
39
|
+
cwd?: string
|
|
40
|
+
target?: CompileTarget
|
|
41
|
+
outfile?: string
|
|
42
|
+
platforms?: CompileTarget[]
|
|
43
|
+
} = {}): Promise<string[]> {
|
|
44
|
+
const distDir = `${cwd}/dist`
|
|
45
|
+
const manifestPath = `${distDir}/cli-manifest.json`
|
|
46
|
+
const discoveryOut = `${distDir}/_discovery.js`
|
|
47
|
+
|
|
48
|
+
const plugins = serverBuildPlugins({ cwd })
|
|
49
|
+
|
|
50
|
+
// Step 1 — client build once (clears dist, writes _app). Every server binary
|
|
51
|
+
// embeds it, so it must precede discovery and the per-target compiles.
|
|
52
|
+
await build({ cwd })
|
|
53
|
+
|
|
54
|
+
/*
|
|
55
|
+
Step 2 — discovery. Build a runnable bundle, execute it under bun, capture
|
|
56
|
+
stdout. We don't `bun build --compile` here because the discovery output is
|
|
57
|
+
throwaway; a plain JS bundle runs faster. Additive — does not clear dist.
|
|
58
|
+
*/
|
|
59
|
+
const discoveryResult = await Bun.build({
|
|
60
|
+
entrypoints: [DISCOVERY_ENTRY],
|
|
61
|
+
target: 'bun',
|
|
62
|
+
outdir: distDir,
|
|
63
|
+
naming: '_discovery.js',
|
|
64
|
+
plugins,
|
|
65
|
+
})
|
|
66
|
+
exitOnBuildFailure(discoveryResult)
|
|
67
|
+
|
|
68
|
+
const proc = Bun.spawn({
|
|
69
|
+
cmd: ['bun', discoveryOut],
|
|
70
|
+
cwd,
|
|
71
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
72
|
+
})
|
|
73
|
+
const [stdout, stderr, exitCode] = await Promise.all([
|
|
74
|
+
new Response(proc.stdout).text(),
|
|
75
|
+
new Response(proc.stderr).text(),
|
|
76
|
+
proc.exited,
|
|
77
|
+
])
|
|
78
|
+
if (exitCode !== 0) {
|
|
79
|
+
abideLog.error(`discovery exited ${exitCode}:\n${stderr}`)
|
|
80
|
+
process.exit(1)
|
|
81
|
+
}
|
|
82
|
+
await Bun.write(manifestPath, stdout)
|
|
83
|
+
await Bun.$`rm -f ${discoveryOut}`.quiet()
|
|
84
|
+
const entryCount = Object.keys(JSON.parse(stdout) as Record<string, unknown>).length
|
|
85
|
+
abideLog.info(`discovered ${entryCount} cli commands → ${manifestPath}`)
|
|
86
|
+
|
|
87
|
+
const programName = await readProgramName(cwd)
|
|
88
|
+
|
|
89
|
+
/*
|
|
90
|
+
Step 3 — compile a CLI binary + sibling server binary for a single target,
|
|
91
|
+
written side by side so `resolveServerBinary()` finds the server next to the
|
|
92
|
+
running CLI. The server reuses the shared client build (buildClient:false).
|
|
93
|
+
*/
|
|
94
|
+
async function buildTargetPair(platformTarget: CompileTarget, cliOut: string): Promise<string> {
|
|
95
|
+
const serverOut = join(dirname(cliOut), `server${exeSuffix(platformTarget)}`)
|
|
96
|
+
await compile({ cwd, target: platformTarget, outfile: serverOut, buildClient: false })
|
|
97
|
+
const result = await Bun.build({
|
|
98
|
+
entrypoints: [CLI_ENTRY],
|
|
99
|
+
target: 'bun',
|
|
100
|
+
compile: { target: platformTarget, outfile: cliOut },
|
|
101
|
+
plugins,
|
|
102
|
+
})
|
|
103
|
+
exitOnBuildFailure(result)
|
|
104
|
+
abideLog.success(`compiled cli + server: ${cliOut}`)
|
|
105
|
+
return cliOut
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (platforms && platforms.length > 0) {
|
|
109
|
+
// Cross-compile every target in parallel — each pair is independent.
|
|
110
|
+
return Promise.all(
|
|
111
|
+
platforms.map(async (platformTarget) => {
|
|
112
|
+
const shortName = platformTarget.replace(/^bun-/, '')
|
|
113
|
+
const cliOut = `${distDir}/cli-thin/${shortName}/${programName}${exeSuffix(platformTarget)}`
|
|
114
|
+
await Bun.$`mkdir -p ${`${distDir}/cli-thin/${shortName}`}`.quiet()
|
|
115
|
+
return buildTargetPair(platformTarget, cliOut)
|
|
116
|
+
}),
|
|
117
|
+
)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const cliOut = outfile ?? `${distDir}/cli${exeSuffix(target)}`
|
|
121
|
+
return [await buildTargetPair(target, cliOut)]
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async function readProgramName(cwd: string): Promise<string> {
|
|
125
|
+
const pkg = (await readPackageJson(cwd)) as { name?: string } | undefined
|
|
126
|
+
return programNameForPackage(pkg?.name)
|
|
127
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { clientBuildPlugins } from './clientBuildPlugins.ts'
|
|
2
|
+
import { abideLog } from './lib/shared/abideLog.ts'
|
|
3
|
+
import { exitOnBuildFailure } from './lib/shared/exitOnBuildFailure.ts'
|
|
4
|
+
|
|
5
|
+
const ENTRY = new URL('./bundleDisconnectedEntry.ts', import.meta.url).pathname
|
|
6
|
+
const CSS_ENTRY = new URL('./lib/bundle/disconnected.css', import.meta.url).pathname
|
|
7
|
+
|
|
8
|
+
/*
|
|
9
|
+
Default screen logo: a minimal inline-SVG abide mark, used when the project ships
|
|
10
|
+
no src/bundle/logo.png. Inline SVG keeps the bundle self-contained with no asset
|
|
11
|
+
file to vendor; a project overrides it just by adding the PNG.
|
|
12
|
+
*/
|
|
13
|
+
const DEFAULT_LOGO = `data:image/svg+xml,${encodeURIComponent(
|
|
14
|
+
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">' +
|
|
15
|
+
'<rect width="64" height="64" rx="16" fill="#111827"/>' +
|
|
16
|
+
'<text x="32" y="45" font-family="system-ui,sans-serif" font-size="38" ' +
|
|
17
|
+
'font-weight="700" fill="#fff" text-anchor="middle">b</text></svg>',
|
|
18
|
+
)}`
|
|
19
|
+
|
|
20
|
+
/*
|
|
21
|
+
Builds the bundle connect screen into a single self-contained HTML string and
|
|
22
|
+
writes it to `dist/bundle-disconnected.html`, which the launcher bakes in via the
|
|
23
|
+
`abide:bundle-disconnected` virtual. The client bundle (abide-ui component +
|
|
24
|
+
injected CSS + compiled Tailwind) is inlined into the page so the launcher serves
|
|
25
|
+
it with zero external requests; the logo is embedded as a data URI. The app title
|
|
26
|
+
(`window.__ABIDE_TITLE__`) is injected by the launcher at serve time, so a
|
|
27
|
+
`<!--abide:connect-config-->` marker is left in <head> for it.
|
|
28
|
+
|
|
29
|
+
Must run after the client build has cleared and repopulated dist (it writes a
|
|
30
|
+
file into dist), and before the launcher build that reads it. Uses no outdir of
|
|
31
|
+
its own — Bun.build artifacts are read from memory — so it never touches dist
|
|
32
|
+
beyond the one file it writes.
|
|
33
|
+
*/
|
|
34
|
+
export async function buildDisconnected({
|
|
35
|
+
cwd = process.cwd(),
|
|
36
|
+
}: {
|
|
37
|
+
cwd?: string
|
|
38
|
+
} = {}): Promise<string> {
|
|
39
|
+
const plugins = await clientBuildPlugins({
|
|
40
|
+
cwd,
|
|
41
|
+
tailwindWarning:
|
|
42
|
+
'bun-plugin-tailwind not installed; building connect screen without Tailwind',
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
/*
|
|
46
|
+
The Tailwind CSS rides as its own entrypoint rather than a `.css` import from
|
|
47
|
+
the entry (which TS can't type), so it compiles to a standalone artifact we
|
|
48
|
+
inline alongside the JS — the component carries no <style> of its own.
|
|
49
|
+
*/
|
|
50
|
+
const result = await Bun.build({
|
|
51
|
+
entrypoints: [ENTRY, CSS_ENTRY],
|
|
52
|
+
target: 'browser',
|
|
53
|
+
minify: true,
|
|
54
|
+
plugins,
|
|
55
|
+
})
|
|
56
|
+
exitOnBuildFailure(result)
|
|
57
|
+
|
|
58
|
+
// Collect the JS bundle + extracted CSS from the in-memory artifacts.
|
|
59
|
+
let js = ''
|
|
60
|
+
let css = ''
|
|
61
|
+
for (const output of result.outputs) {
|
|
62
|
+
const text = await output.text()
|
|
63
|
+
if (output.path.endsWith('.css')) {
|
|
64
|
+
css += text
|
|
65
|
+
} else if (output.path.endsWith('.js')) {
|
|
66
|
+
js += text
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const logo = await readLogo(cwd)
|
|
71
|
+
const html = composeHtml({ js, css, logo })
|
|
72
|
+
const outPath = `${cwd}/dist/bundle-disconnected.html`
|
|
73
|
+
await Bun.write(outPath, html)
|
|
74
|
+
abideLog.success(`built connect screen: ${outPath} (${(html.length / 1024).toFixed(1)} KiB)`)
|
|
75
|
+
return outPath
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Reads the project's src/bundle/logo.png as a data URI, or the default mark.
|
|
79
|
+
async function readLogo(cwd: string): Promise<string> {
|
|
80
|
+
const userLogo = Bun.file(`${cwd}/src/bundle/logo.png`)
|
|
81
|
+
if (await userLogo.exists()) {
|
|
82
|
+
const bytes = await userLogo.bytes()
|
|
83
|
+
return `data:image/png;base64,${bytes.toBase64()}`
|
|
84
|
+
}
|
|
85
|
+
return DEFAULT_LOGO
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/*
|
|
89
|
+
Escapes a closing `</script>` so an inline `<script>` body can't be terminated
|
|
90
|
+
early by content in the bundle (rare, but a `</script>` substring would break the
|
|
91
|
+
page). The browser still parses `<\/script>` as the intended characters.
|
|
92
|
+
*/
|
|
93
|
+
function escapeScriptBody(value: string): string {
|
|
94
|
+
return value.replace(/<\/(script)/gi, '<\\/$1')
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Assembles the final standalone HTML document from the inlined pieces.
|
|
98
|
+
function composeHtml({ js, css, logo }: { js: string; css: string; logo: string }): string {
|
|
99
|
+
const logoScript = `window.__ABIDE_LOGO__=${JSON.stringify(logo)}`
|
|
100
|
+
return `<!doctype html>
|
|
101
|
+
<html lang="en">
|
|
102
|
+
<head>
|
|
103
|
+
<meta charset="UTF-8" />
|
|
104
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
105
|
+
<!--abide:connect-config-->
|
|
106
|
+
<script>${escapeScriptBody(logoScript)}</script>
|
|
107
|
+
<!-- Paint the screen background before the client mounts, so there's no white
|
|
108
|
+
flash ahead of the splash (gray-50 / gray-950 to match the rendered screen). -->
|
|
109
|
+
<style>html,body{margin:0;background:#f9fafb}@media (prefers-color-scheme:dark){html,body{background:#030712}}</style>
|
|
110
|
+
<style>${css}</style>
|
|
111
|
+
</head>
|
|
112
|
+
<body>
|
|
113
|
+
<div id="app"></div>
|
|
114
|
+
<script type="module">${escapeScriptBody(js)}</script>
|
|
115
|
+
</body>
|
|
116
|
+
</html>
|
|
117
|
+
`
|
|
118
|
+
}
|