@lensmcp/cluster 1.25.10 → 1.25.11
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/basic-ssl.js +1 -1
- package/build-host.js +1 -1
- package/build-scope-patterns.js +1 -1
- package/bundle-parent.js +1 -1
- package/checkout-cache.js +1 -1
- package/create-webpack-dev.js +1 -1
- package/create-webpack-prod.js +1 -1
- package/dev-devtool.js +1 -1
- package/devserver-notifier.js +1 -1
- package/devserver-transport.js +1 -1
- package/error-stack-release.js +1 -1
- package/executors/build/build.impl.js +1 -1
- package/executors/gateway/body-stall.js +1 -1
- package/executors/gateway/canonical-path.js +1 -1
- package/executors/gateway/client-ip.js +1 -1
- package/executors/gateway/gateway-errors.js +1 -1
- package/executors/gateway/gateway.impl.js +1 -1
- package/executors/gateway/gateway.lib.js +1 -1
- package/executors/gateway/health-check.js +1 -1
- package/executors/gateway/jwks-verify.js +1 -1
- package/executors/gateway/jwt-claims.js +1 -1
- package/executors/gateway/main.prod-gateway.js +2 -2
- package/executors/gateway/main.rollout.js +4 -4
- package/executors/gateway/manifest.js +1 -1
- package/executors/gateway/metrics.js +1 -1
- package/executors/gateway/otel-tracing.js +1 -1
- package/executors/gateway/prod-config.js +1 -1
- package/executors/gateway/prod-gateway.lib.js +1 -1
- package/executors/gateway/prod-runtime/access-log.js +1 -1
- package/executors/gateway/prod-runtime/app.js +1 -1
- package/executors/gateway/prod-runtime/auth.js +1 -1
- package/executors/gateway/prod-runtime/body-stall.js +1 -1
- package/executors/gateway/prod-runtime/cors.js +1 -1
- package/executors/gateway/prod-runtime/edge.js +1 -1
- package/executors/gateway/prod-runtime/handler.js +1 -1
- package/executors/gateway/prod-runtime/hooks.js +1 -1
- package/executors/gateway/prod-runtime/observability.js +1 -1
- package/executors/gateway/prod-runtime/rollout.js +1 -1
- package/executors/gateway/prod-runtime/routing.js +1 -1
- package/executors/gateway/prod-runtime/server.js +1 -1
- package/executors/gateway/prod-runtime/trust.js +1 -1
- package/executors/gateway/prod-runtime/upgrade.js +7 -7
- package/executors/gateway/prod-runtime/upstream.js +1 -1
- package/executors/gateway/providers-prod.js +1 -1
- package/executors/gateway/rate-limit.js +2 -2
- package/executors/gateway/registry-source.js +1 -1
- package/executors/gateway/rollout-ops.js +2 -2
- package/executors/gateway/runtime/act.js +1 -1
- package/executors/gateway/runtime/auth.js +1 -1
- package/executors/gateway/runtime/chooser.js +12 -12
- package/executors/gateway/runtime/control.js +2 -2
- package/executors/gateway/runtime/dev-auth.js +1 -1
- package/executors/gateway/runtime/discovery.js +1 -1
- package/executors/gateway/runtime/edge.js +1 -1
- package/executors/gateway/runtime/guest-graph.js +2 -2
- package/executors/gateway/runtime/guest-replay.js +2 -2
- package/executors/gateway/runtime/handler.js +1 -1
- package/executors/gateway/runtime/hmr-reload.js +1 -1
- package/executors/gateway/runtime/hooks.js +1 -1
- package/executors/gateway/runtime/instance.js +2 -2
- package/executors/gateway/runtime/lens-children.js +1 -1
- package/executors/gateway/runtime/lifecycle.js +3 -3
- package/executors/gateway/runtime/observability.js +2 -2
- package/executors/gateway/runtime/own-log.js +4 -4
- package/executors/gateway/runtime/pod-env.js +2 -2
- package/executors/gateway/runtime/pod-output.js +1 -1
- package/executors/gateway/runtime/pod-probe.js +1 -1
- package/executors/gateway/runtime/process-names.js +1 -1
- package/executors/gateway/runtime/project-graph-store.js +1 -1
- package/executors/gateway/runtime/proxy.js +1 -1
- package/executors/gateway/runtime/registration-guards.js +1 -1
- package/executors/gateway/runtime/route-registry.js +1 -1
- package/executors/gateway/runtime/scope.js +1 -1
- package/executors/gateway/runtime/serve-launch.js +3 -3
- package/executors/gateway/runtime/server.js +2 -2
- package/executors/gateway/runtime/service-keys.js +1 -1
- package/executors/gateway/runtime/shared-build.js +4 -4
- package/executors/gateway/runtime/source-poller.js +1 -1
- package/executors/gateway/runtime/types.js +1 -1
- package/executors/gateway/runtime/upgrade.js +1 -1
- package/executors/gateway/runtime/workspace-log.js +1 -1
- package/executors/gateway/runtime/workspace-middleware.js +1 -1
- package/executors/gateway/runtime/workspace-registry.js +1 -1
- package/executors/gateway/ssrf-guard.js +1 -1
- package/executors/serve/serve.impl.js +1 -1
- package/executors/trust/hostname.js +1 -1
- package/executors/trust/trust.impl.js +3 -3
- package/exit-reason.js +2 -2
- package/fork-ts-check-reporter.js +1 -1
- package/gateway.js +1 -1
- package/gc-notice.js +1 -1
- package/graph-snapshot.js +1 -1
- package/handoff-retire.js +1 -1
- package/heap-snapshot.js +1 -1
- package/hot-swap-registries.js +1 -1
- package/index.js +1 -1
- package/inspector-secret.js +1 -1
- package/main.devserver.js +11 -11
- package/notice-generation.js +1 -1
- package/package.json +4 -4
- package/perf/heavy-barrel-import.js +1 -1
- package/perf/perf-config.js +1 -1
- package/perf/perf-rule-events.js +2 -2
- package/perf/perf-rules-analysis.js +1 -1
- package/perf/perf-rules-plugin.js +1 -1
- package/perf/source-scan.js +5 -5
- package/perf/workspace-libraries.js +2 -2
- package/pod-memory-events.js +2 -2
- package/pod-memory.js +1 -1
- package/pod-sock.js +1 -1
- package/process-name.js +1 -1
- package/redis-disconnect-fix.js +1 -1
- package/schema-first-instance.js +1 -1
- package/serve-runner.js +1 -1
- package/service-build-events.js +1 -1
- package/shared-build/attach.js +2 -2
- package/shared-build/host.js +3 -3
- package/shared-build/protocol.js +1 -1
- package/shared-build/shared-compilation.js +3 -3
- package/shared-build/signature.js +1 -1
- package/stdio-guard.js +1 -1
- package/swap-mode.js +1 -1
- package/swap-recycle.js +1 -1
- package/tsgo-check-plugin.js +4 -4
- package/typecheck-bus.js +3 -3
- package/typecheck-queue.js +1 -1
- package/worker-supervisor.js +2 -2
- package/workspace-paths.js +1 -1
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`)[0]})`}return helpersByRoot.set(e,s),s}u(loadNxHelpers,"loadNxHelpers"),i(loadNxHelpers,"loadNxHelpers");const ROOT_DOTENV_LOAD=[".local.env",".env.local",".env"],ROOT_DOTENV_UNLOAD=[".env",".local.env",".env.local"];function nxExecutorEnv(e,r,s,o,_){const t={...s};t.FORCE_COLOR==="0"&&(t.NO_COLOR="1",delete t.FORCE_COLOR),e.loadAndExpandDotEnvFile(ROOT_DOTENV_LOAD.map(a=>path.join(r,a)),t),t.NX_CLI_SET="true",t.NX_VERBOSE_LOGGING=String(t.NX_VERBOSE_LOGGING==="true"),t.NX_TUI="false",t.NX_LOAD_DOT_ENV_FILES!=="false"&&(t.NX_LOAD_DOT_ENV_FILES="true");const n={...t};for(const a of ROOT_DOTENV_UNLOAD)e.unloadDotEnvFile(path.join(r,a),n);t.NX_LOAD_DOT_ENV_FILES==="true"&&e.loadAndExpandDotEnvFile(e.getEnvFilesForTask(o,_).map(a=>path.join(r,a)),n),n.FORCE_COLOR=t.FORCE_COLOR===void 0?"true":t.FORCE_COLOR,n.NX_WORKSPACE_ROOT=r,n.NX_TASK_TARGET_PROJECT=o.target.project,n.NX_TASK_TARGET_TARGET=o.target.target,o.target.configuration?n.NX_TASK_TARGET_CONFIGURATION=o.target.configuration:delete n.NX_TASK_TARGET_CONFIGURATION,n.LERNA_PACKAGE_NAME=o.target.project,n.NX_TUI="false",o.target.target==="test"&&(n.NX_TERMINAL_CAPTURE_STDERR="true");for(const a of["NX_TASK_HASH","NX_SKIP_NX_CACHE","NX_TERMINAL_OUTPUT_PATH","NX_STREAM_OUTPUT","NX_PREFIX_OUTPUT","NX_SET_CLI"])delete n[a];return(t.NX_SKIP_NX_CACHE==="true"||t.NX_DISABLE_NX_CACHE==="true")&&(n.NX_SKIP_NX_CACHE="true"),n.NX_FORKED_TASK_EXECUTOR="true",{env:n,isVerbose:t.NX_VERBOSE_LOGGING==="true"}}u(nxExecutorEnv,"nxExecutorEnv"),i(nxExecutorEnv,"nxExecutorEnv");function inferredBy(e,r,s){const o=e.sourceMaps?.[r],_=new Set([path.posix.join(r,"project.json"),path.posix.join(r,"package.json"),"nx.json"]),t=`targets.${s}`;let n=!1;for(const[a,[
|
|
3
|
-
`)[0]})`)}const
|
|
1
|
+
"use strict";var A=Object.defineProperty;var E=(e,r)=>A(e,"name",{value:r,configurable:!0});var T=Object.defineProperty,u=E((e,r)=>T(e,"name",{value:r,configurable:!0}),"u"),h=Object.defineProperty,i=u((e,r)=>h(e,"name",{value:r,configurable:!0}),"i");Object.defineProperty(exports,"__esModule",{value:!0}),exports.RUNNER_ROOT_FLAG=exports.SERVE_RUNNER_ROLE=exports.SERVE_RUNNER_EXECUTOR=void 0,exports.serveRunnerEnabled=serveRunnerEnabled,exports.serveRunnerScript=serveRunnerScript,exports.serveRunnerArgs=serveRunnerArgs,exports.isServeRunnerCommand=isServeRunnerCommand,exports.isServeRunnerCommandOf=isServeRunnerCommandOf,exports.loadNxHelpers=loadNxHelpers,exports.nxExecutorEnv=nxExecutorEnv,exports.planServeLaunch=planServeLaunch;const tslib_1=require("tslib"),fs=tslib_1.__importStar(require("node:fs")),node_module_1=require("node:module"),path=tslib_1.__importStar(require("node:path"));exports.SERVE_RUNNER_EXECUTOR="@lensmcp/cluster:serve",exports.SERVE_RUNNER_ROLE="serve",exports.RUNNER_ROOT_FLAG="--workspace-root=";function serveRunnerEnabled(e=process.env){const r=(e.LENSMCP_SERVE_RUNNER??"").trim().toLowerCase();return!["0","off","false","no","nx"].includes(r)}E(serveRunnerEnabled,"serveRunnerEnabled"),u(serveRunnerEnabled,"serveRunnerEnabled"),i(serveRunnerEnabled,"serveRunnerEnabled");function serveRunnerScript(e=path.join(__dirname,"../../..")){const r=path.join(e,"serve-runner.js");if(fs.existsSync(r))return{path:r,execArgv:[]};const s=path.join(e,"serve-runner.ts");if(fs.existsSync(s))try{return{path:s,execArgv:["--require",require.resolve("@swc-node/register")]}}catch{return}}E(serveRunnerScript,"serveRunnerScript"),u(serveRunnerScript,"serveRunnerScript"),i(serveRunnerScript,"serveRunnerScript");function serveRunnerArgs(e,r,s){return["run",e,`--childCount=${r}`,`${exports.RUNNER_ROOT_FLAG}${s}`]}E(serveRunnerArgs,"serveRunnerArgs"),u(serveRunnerArgs,"serveRunnerArgs"),i(serveRunnerArgs,"serveRunnerArgs");function isServeRunnerCommand(e){return/\bserve-runner\.(js|ts)\b/.test(e)&&e.includes(` ${exports.RUNNER_ROOT_FLAG}`)}E(isServeRunnerCommand,"isServeRunnerCommand"),u(isServeRunnerCommand,"isServeRunnerCommand"),i(isServeRunnerCommand,"isServeRunnerCommand");function isServeRunnerCommandOf(e,r){return isServeRunnerCommand(e)&&e.trimEnd().endsWith(` ${exports.RUNNER_ROOT_FLAG}${r.replace(/\/+$/,"")}`)}E(isServeRunnerCommandOf,"isServeRunnerCommandOf"),u(isServeRunnerCommandOf,"isServeRunnerCommandOf"),i(isServeRunnerCommandOf,"isServeRunnerCommandOf");const helpersByRoot=new Map;function loadNxHelpers(e){const r=helpersByRoot.get(e);if(r)return r;let s;try{const o=(0,node_module_1.createRequire)(path.join(e,"package.json")),_=o("nx/package.json").version,t=o("nx/src/tasks-runner/task-env"),n=o("nx/src/tasks-runner/create-task-graph"),a=o("nx/src/config/nx-json"),l=o("nx/src/utils/cache-directory"),c=o.resolve("nx/src/command-line/run/run"),R=[["getEnvFilesForTask",t.getEnvFilesForTask],["loadAndExpandDotEnvFile",t.loadAndExpandDotEnvFile],["unloadDotEnvFile",t.unloadDotEnvFile],["createTaskGraph",n.createTaskGraph],["readNxJson",a.readNxJson],["workspaceDataDirectoryForWorkspace",l.workspaceDataDirectoryForWorkspace]].filter(([,N])=>typeof N!="function").map(([N])=>N);s=R.length>0?`nx ${_} has no ${R.join(", ")}`:{version:_,runModule:c,createTaskGraph:n.createTaskGraph,getEnvFilesForTask:t.getEnvFilesForTask,loadAndExpandDotEnvFile:t.loadAndExpandDotEnvFile,unloadDotEnvFile:t.unloadDotEnvFile,readNxJson:a.readNxJson,workspaceDataDirectoryForWorkspace:l.workspaceDataDirectoryForWorkspace}}catch(o){s=`cannot load the workspace's nx (${o.message.split(`
|
|
2
|
+
`)[0]})`}return helpersByRoot.set(e,s),s}E(loadNxHelpers,"loadNxHelpers"),u(loadNxHelpers,"loadNxHelpers"),i(loadNxHelpers,"loadNxHelpers");const ROOT_DOTENV_LOAD=[".local.env",".env.local",".env"],ROOT_DOTENV_UNLOAD=[".env",".local.env",".env.local"];function nxExecutorEnv(e,r,s,o,_){const t={...s};t.FORCE_COLOR==="0"&&(t.NO_COLOR="1",delete t.FORCE_COLOR),e.loadAndExpandDotEnvFile(ROOT_DOTENV_LOAD.map(a=>path.join(r,a)),t),t.NX_CLI_SET="true",t.NX_VERBOSE_LOGGING=String(t.NX_VERBOSE_LOGGING==="true"),t.NX_TUI="false",t.NX_LOAD_DOT_ENV_FILES!=="false"&&(t.NX_LOAD_DOT_ENV_FILES="true");const n={...t};for(const a of ROOT_DOTENV_UNLOAD)e.unloadDotEnvFile(path.join(r,a),n);t.NX_LOAD_DOT_ENV_FILES==="true"&&e.loadAndExpandDotEnvFile(e.getEnvFilesForTask(o,_).map(a=>path.join(r,a)),n),n.FORCE_COLOR=t.FORCE_COLOR===void 0?"true":t.FORCE_COLOR,n.NX_WORKSPACE_ROOT=r,n.NX_TASK_TARGET_PROJECT=o.target.project,n.NX_TASK_TARGET_TARGET=o.target.target,o.target.configuration?n.NX_TASK_TARGET_CONFIGURATION=o.target.configuration:delete n.NX_TASK_TARGET_CONFIGURATION,n.LERNA_PACKAGE_NAME=o.target.project,n.NX_TUI="false",o.target.target==="test"&&(n.NX_TERMINAL_CAPTURE_STDERR="true");for(const a of["NX_TASK_HASH","NX_SKIP_NX_CACHE","NX_TERMINAL_OUTPUT_PATH","NX_STREAM_OUTPUT","NX_PREFIX_OUTPUT","NX_SET_CLI"])delete n[a];return(t.NX_SKIP_NX_CACHE==="true"||t.NX_DISABLE_NX_CACHE==="true")&&(n.NX_SKIP_NX_CACHE="true"),n.NX_FORKED_TASK_EXECUTOR="true",{env:n,isVerbose:t.NX_VERBOSE_LOGGING==="true"}}E(nxExecutorEnv,"nxExecutorEnv"),u(nxExecutorEnv,"nxExecutorEnv"),i(nxExecutorEnv,"nxExecutorEnv");function inferredBy(e,r,s){const o=e.sourceMaps?.[r],_=new Set([path.posix.join(r,"project.json"),path.posix.join(r,"package.json"),"nx.json"]),t=`targets.${s}`;let n=!1;for(const[a,[l,c]]of Object.entries(o??{}))if(!(a!==t&&!a.startsWith(`${t}.`))&&(n=!0,!l||!_.has(l)))return`${c}${l?` (from ${l})`:""}`;return n?void 0:"a source the project graph does not record"}E(inferredBy,"inferredBy"),u(inferredBy,"inferredBy"),i(inferredBy,"inferredBy");function planServeLaunch(e){const r=i(p=>({kind:"nx",reason:p}),"nx");if(!serveRunnerEnabled(e.gatewayEnv??process.env))return r("LENSMCP_SERVE_RUNNER is off");if(!e.stores)return r("the gateway was started without an Nx project graph");const s=e.stores.get(e.root);if(!s)return r("a workspace registered into this gateway that it holds no project graph for");const o=s.current();if(!o)return s.refreshIfStale(),r(`no project graph${s.lastError()?` (${s.lastError()})`:""}`);const _=s.staleReason();if(_)return s.refreshIfStale(),r(_);const t=o.projectGraph.nodes[e.project],n=t?.data.targets?.[e.target];if(!t||!n)return r(`${e.project}:${e.target} is not in the project graph`);if(n.executor!==exports.SERVE_RUNNER_EXECUTOR)return r(`its executor is ${n.executor??"(none)"}, not ${exports.SERVE_RUNNER_EXECUTOR}`);if(!o.sourceMaps)return r("this nx reports no source maps, so the gateway cannot tell a declared target from an inferred one");const a=inferredBy(o,t.data.root,e.target);if(a)return r(`part of the target is inferred by ${a}`);const l=e.gatewayEnv??process.env;if(e.baseEnv.NX_CACHE_PROJECT_GRAPH==="false"||l.NX_CACHE_PROJECT_GRAPH==="false")return r("NX_CACHE_PROJECT_GRAPH=false \u2014 the executor reads nx's graph cache");const c=loadNxHelpers(e.root);if(typeof c=="string")return r(c);const R=e.script??serveRunnerScript();if(!R)return r("serve-runner.js is missing from @lensmcp/cluster");if(!fs.existsSync(path.join(c.workspaceDataDirectoryForWorkspace(e.root),"project-graph.json")))return r("nx has no project-graph cache on disk for the executor to read");const N={childCount:e.childCount,__overrides_unparsed__:[`--childCount=${e.childCount}`]};let v;try{v=c.createTaskGraph(o.projectGraph,{},[e.project],[e.target],void 0,N)}catch(p){return r(`nx could not build its task graph (${p.message.split(`
|
|
3
|
+
`)[0]})`)}const d=Object.values(v.tasks).find(p=>p.target.project===e.project&&p.target.target===e.target);if(!d)return r(`nx's task graph has no ${e.project}:${e.target}`);const f=Object.keys(v.tasks).filter(p=>p!==d.id);if(f.length>0)return r(`dependsOn: nx would run ${f.join(", ")} first`);const x=new Set(c.readNxJson(e.root).sync?.disabledTaskSyncGenerators??[]),O=(n.syncGenerators??[]).filter(p=>!x.has(p));if(O.length>0)return r(`sync generators nx would run first: ${O.join(", ")}`);d.startTime=Date.now();const{env:g,isVerbose:S}=nxExecutorEnv(c,e.root,e.baseEnv,d,o.projectGraph);return{kind:"runner",taskId:d.id,env:g,script:R,message:{nxRunModule:c.runModule,targetDescription:d.target,overrides:d.overrides,isVerbose:S,taskGraph:v}}}E(planServeLaunch,"planServeLaunch"),u(planServeLaunch,"planServeLaunch"),i(planServeLaunch,"planServeLaunch");
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";var ge=Object.defineProperty;var A=(s,r)=>ge(s,"name",{value:r,configurable:!0});var he=Object.defineProperty,n=A((s,r)=>he(s,"name",{value:r,configurable:!0}),"n");Object.defineProperty(exports,"__esModule",{value:!0}),exports.GATEWAY_H2_IDLE_SESSION_MS_DEFAULT=exports.GATEWAY_MAX_H2_STREAMS_DEFAULT=exports.GATEWAY_MAX_H2_SESSIONS_DEFAULT=exports.GATEWAY_MAX_CONNECTIONS_DEFAULT=exports.BENIGN_SOCKET_ERRNOS=void 0,exports.buildEdgeVerifierPool=buildEdgeVerifierPool,exports.classifyClientError=classifyClientError,exports.createClientErrorLogGate=createClientErrorLogGate,exports.retirePreviousWorkspace=retirePreviousWorkspace,exports.resolveMaxConnections=resolveMaxConnections,exports.h2BudgetFromEnv=h2BudgetFromEnv,exports.createH2Governor=createH2Governor,exports.startGateway=startGateway;const tslib_1=require("tslib"),http=tslib_1.__importStar(require("node:http")),path=tslib_1.__importStar(require("node:path")),discovery_1=require("./discovery"),scope_1=require("./scope"),route_registry_1=require("./route-registry"),act_1=require("./act"),control_1=require("./control"),workspace_middleware_1=require("./workspace-middleware"),workspace_registry_1=require("./workspace-registry"),service_keys_1=require("./service-keys"),source_poller_1=require("./source-poller"),client_ip_1=require("../client-ip"),workspace_log_1=require("./workspace-log"),own_log_1=require("./own-log"),observability_1=require("./observability"),lifecycle_1=require("./lifecycle"),process_names_1=require("./process-names"),project_graph_store_1=require("./project-graph-store"),serve_launch_1=require("./serve-launch"),process_name_1=require("../../../process-name"),protocol_1=require("../../../shared-build/protocol"),lens_children_1=require("./lens-children"),proxy_1=require("./proxy"),auth_1=require("./auth"),hooks_1=require("./hooks"),handler_1=require("./handler"),upgrade_1=require("./upgrade"),jwks_verify_1=require("../jwks-verify"),types_1=require("./types");function insecureLocalFetch(s,r){return new Promise((u,m)=>{const a=(s.startsWith("https:")?require("node:https"):require("node:http")).request(s,{method:"GET",headers:r?.headers,rejectUnauthorized:!1},w=>{const _=[];w.on("data",g=>_.push(g)),w.on("end",()=>{const g=w.statusCode??0,l=Buffer.concat(_).toString("utf8");u({ok:g>=200&&g<300,status:g,json:n(async()=>JSON.parse(l),"json")})})});a.on("error",m),a.end()})}A(insecureLocalFetch,"insecureLocalFetch"),n(insecureLocalFetch,"insecureLocalFetch");function buildEdgeVerifierPool(s){const r=process.env.LENSMCP_GW_JWKS_URL,u=process.env.LENSMCP_GW_JWT_ISS,m=new Map;let a;const w=n((_,g)=>{console.log(`[gateway] edge JWT: verifying via JWKS ${_}${g}`);const l=(0,jwks_verify_1.createJwksVerifier)({jwksUrl:_,...u?{issuer:u}:{},fetchImpl:insecureLocalFetch});return l.refresh().catch(o=>console.warn("[gateway] edge JWKS warm failed (will retry):",o.message)),l},"make");return{for(_){if(r)return a??=w(r,"");const g=_.split(":")[0].toLowerCase();let l;for(const d of s()){const S=d.host;if(typeof S!="string"||!/^auth\./.test(S)||S.startsWith("internal."))continue;const T=S.slice(5);(g===T||g.endsWith(`.${T}`))&&(!l||T.length>l.length)&&(l=T)}if(!l)return;let o=m.get(l);return o||(o=w(`https://auth.${l}/jwks.json`,` (auto-derived for apex ${l})`),m.set(l,o)),o},stop(){a?.stop();for(const _ of m.values())_.stop()}}}A(buildEdgeVerifierPool,"buildEdgeVerifierPool"),n(buildEdgeVerifierPool,"buildEdgeVerifierPool"),exports.BENIGN_SOCKET_ERRNOS=new Set(["ECONNRESET","EPIPE","ETIMEDOUT","ECONNABORTED","ECANCELED"]);function classifyClientError(s,r){return s&&exports.BENIGN_SOCKET_ERRNOS.has(s)?{status:null,report:!1,cause:"client-abort"}:s==="HPE_INVALID_EOF_STATE"?{status:null,report:!1,cause:"truncated-at-eof"}:s==="ERR_HTTP_REQUEST_TIMEOUT"?{status:408,report:!0,cause:"request-timeout"}:s==="HPE_HEADER_OVERFLOW"?{status:431,report:!0,cause:"header-overflow"}:s?.startsWith("HPE_")?{status:400,report:!0,cause:"parse-error"}:{status:400,report:!0,cause:s??r??"unknown"}}A(classifyClientError,"classifyClientError"),n(classifyClientError,"classifyClientError");const CLIENT_ERROR_REASON={400:"Bad Request",408:"Request Timeout",431:"Request Header Fields Too Large"};function createClientErrorLogGate(s=1e4){const r=new Map;return u=>{const m=Date.now(),a=r.get(u)??0;return m-a<s?!1:(r.set(u,m),!0)}}A(createClientErrorLogGate,"createClientErrorLogGate"),n(createClientErrorLogGate,"createClientErrorLogGate");function guardInboundSocket(s){s.on("error",r=>{exports.BENIGN_SOCKET_ERRNOS.has(r.code??"")||console.warn(`[gateway] inbound socket error (${r.code??r.message}) \u2014 dropping this connection only`),s.destroy()})}A(guardInboundSocket,"guardInboundSocket"),n(guardInboundSocket,"guardInboundSocket");function retirePreviousWorkspace(s,r,u){const m=s.get(r);if(!m)return!1;s.delete(r),u==="re-registered"&&console.log(`[gateway] workspace '${r}' re-registered \u2014 retiring the children of its previous registration first.`);try{m()}catch(a){console.warn(`[gateway] could not fully retire the previous registration of '${r}' (${u}): ${a.message}`)}return!0}A(retirePreviousWorkspace,"retirePreviousWorkspace"),n(retirePreviousWorkspace,"retirePreviousWorkspace"),exports.GATEWAY_MAX_CONNECTIONS_DEFAULT=512,exports.GATEWAY_MAX_H2_SESSIONS_DEFAULT=64,exports.GATEWAY_MAX_H2_STREAMS_DEFAULT=4096,exports.GATEWAY_H2_IDLE_SESSION_MS_DEFAULT=3e5;function parseBudget(s,r){if(s===void 0||s.trim()==="")return r;const u=Number(s);return!Number.isFinite(u)||u<0?r:Math.floor(u)}A(parseBudget,"parseBudget"),n(parseBudget,"parseBudget");function resolveMaxConnections(s){return parseBudget(s,exports.GATEWAY_MAX_CONNECTIONS_DEFAULT)}A(resolveMaxConnections,"resolveMaxConnections"),n(resolveMaxConnections,"resolveMaxConnections");function h2BudgetFromEnv(s=process.env){return{maxSessions:parseBudget(s.LENSMCP_MAX_H2_SESSIONS,exports.GATEWAY_MAX_H2_SESSIONS_DEFAULT),maxStreams:parseBudget(s.LENSMCP_MAX_H2_STREAMS,exports.GATEWAY_MAX_H2_STREAMS_DEFAULT),idleSessionMs:parseBudget(s.LENSMCP_H2_IDLE_MS,exports.GATEWAY_H2_IDLE_SESSION_MS_DEFAULT)}}A(h2BudgetFromEnv,"h2BudgetFromEnv"),n(h2BudgetFromEnv,"h2BudgetFromEnv");function createH2Governor(s,r){const{NGHTTP2_ENHANCE_YOUR_CALM:u,NGHTTP2_REFUSED_STREAM:m}=require("node:http2").constants,a=new Map;let w=0;const _=n(o=>{o.idle&&(clearTimeout(o.idle),o.idle=void 0)},"disarm"),g=n((o,d)=>{_(d),!(s.idleSessionMs<=0||d.open>0)&&(d.idle=setTimeout(()=>{o.destroyed||o.closed||(r("session-reclaimed",{idleMs:s.idleSessionMs,sessions:a.size}),a.delete(o),o.close())},s.idleSessionMs),d.idle.unref?.())},"arm"),l=n(()=>{for(const[o,d]of a)if(!(d.open>0||o.destroyed))return _(d),a.delete(o),r("session-reclaimed",{reason:"cap",sessions:a.size+1,maxSessions:s.maxSessions}),o.close(),!0;return!1},"reclaimOldestIdle");return{admitSession(o){if(s.maxSessions>0&&a.size>=s.maxSessions&&!l()){r("session-refused",{sessions:a.size,maxSessions:s.maxSessions,streams:w});try{o.goaway(u)}catch{}try{o.close()}catch{}return!1}const d={open:0};return a.set(o,d),g(o,d),o.once("close",()=>{_(d),a.delete(o)}),!0},admitStream(o,d){const S=a.get(o);if(!S)return!0;if(s.maxStreams>0&&w>=s.maxStreams){r("stream-refused",{streams:w,maxStreams:s.maxStreams,sessions:a.size});try{d.close(m)}catch{}return!1}return w+=1,S.open+=1,_(S),d.once("close",()=>{w=Math.max(0,w-1),S.open=Math.max(0,S.open-1),S.open===0&&a.has(o)&&g(o,S)}),!0},dispose(){for(const o of a.values())_(o);a.clear()}}}A(createH2Governor,"createH2Governor"),n(createH2Governor,"createH2Governor");async function startGateway(s,r){const u=s.https!==!1,m=s.ports?.length?s.ports:[443],a=s.scanTtlMs??1500,w=s.startupTimeoutMs??12e4,_=s.sweepMs??1e4,g=s.trafficFlushMs??5e3;let l=!1;const o=process.env.LENSMCP_EVENT_FILE??path.join(r.root,".lensmcp","events.jsonl"),d=(0,own_log_1.startOwnLogRotation)(r.root),S=(0,scope_1.readLensScope)(r.root),T=S.key,x=S.sockNs!==T?S.sockNs:void 0,X=r.projectsConfigurations?.projects??{},J=(0,discovery_1.projectSourceRoots)(r.root,X,r.projectDependencies),{routes:G,services:N,instance:V}=(0,discovery_1.discoverRoutes)(r.root,X,void 0,T,J,x,S.instance);if(G.length===0)throw new Error("[gateway] no project declares a `cluster` field \u2014 nothing to route.");const j=new route_registry_1.RouteRegistry;j.register({wsKey:T,...x?{sockNs:x}:{},root:r.root,routes:G,services:N,...V?{instance:V}:{}});const R=[];let z=n(()=>{},"refreshCert");const Q=n(()=>{(0,route_registry_1.rebuildRoutesInPlace)(R,j),z()},"rebuildRoutes");Q();const{serviceKeys:ae,keyToProject:ie,keyToWorkspace:ce}=(0,service_keys_1.loadServiceKeys)(r.root,N,T),le=(0,client_ip_1.createClientIpResolver)({...(0,client_ip_1.clientIpOptionsFromEnv)(),...s.trustProxyHops!==void 0?{trustProxyHops:s.trustProxyHops}:{},...s.clientIpHeader?{clientIpHeader:s.clientIpHeader}:{},...s.clientIpTrustedProxies?{clientIpTrustedProxies:s.clientIpTrustedProxies}:{}}),E={root:r.root,wsKey:T,...x?{sockNs:x}:{},eventFile:o,routes:R,registry:j,rebuildRoutes:Q,services:N,serviceKeys:ae,keyToProject:ie,keyToWorkspace:ce,clientIp:le,bodyStallMs:s.bodyStallMs??types_1.BODY_STALL_MS,scanTtlMs:a,startupTimeoutMs:w,sweepMs:_,trafficFlushMs:g,https:u,projectRoots:Object.fromEntries(Object.entries(r.projectsConfigurations?.projects??{}).map(([e,t])=>[e,path.resolve(r.root,t.root)])),projectSourceRoots:J,...r.projectGraphStore?{graphStores:(0,project_graph_store_1.createProjectGraphStores)(r.projectGraphStore)}:{},...s.sharedCompiler!==void 0?{sharedCompiler:s.sharedCompiler}:{},stopped:n(()=>l,"stopped")};(0,process_name_1.prelinkProcessNames)((0,process_names_1.gatewayProcessNames)(N,{runner:(0,serve_launch_1.serveRunnerEnabled)()&&!!r.projectGraphStore,sharedBuild:(0,protocol_1.sharedCompilerEnabled)(process.env,s.sharedCompiler),label:T||path.basename(r.root),lens:{key:T,dashboard:s.dashboard!==!1,mcp:s.mcp!==!1&&G.some(e=>!!e.lens)}}));const f=(0,observability_1.createObservability)(o,{trafficFlushMs:g}),ue=createClientErrorLogGate(),k=h2BudgetFromEnv(),de=createClientErrorLogGate(3e4),q=createH2Governor(k,(e,t)=>{de(e)&&console.warn(`[gateway] h2 aggregate budget: ${e} (${JSON.stringify(t)}). These are the FRONT DOOR's ceilings, not an upstream's \u2014 raise/disable with LENSMCP_MAX_H2_SESSIONS / LENSMCP_MAX_H2_STREAMS / LENSMCP_H2_IDLE_MS / LENSMCP_MAX_CONNECTIONS (0 = unbounded).`),f.emit(e==="session-reclaimed"?"info":"warning",`h2 aggregate budget: ${e}`,`gateway-h2-budget:${e}`,{kind:"h2-aggregate-budget",event:e,project:"gateway",...t})}),v=(0,lifecycle_1.createServiceLayer)(E,f),L=(0,lens_children_1.createLensChildren)(E,f,s),W=new Map;let D;if(s.middleware){const e=require(path.resolve(r.root,s.middleware));D=e.default??e}const K=(0,workspace_middleware_1.createWorkspaceMiddleware)({ownerKey:T,...D?{owner:D}:{},policy:(0,workspace_middleware_1.guestMiddlewarePolicy)()}),O=process.env.LENSMCP_GW_ACT==="0"?void 0:(0,act_1.createActStore)({dir:path.join(path.dirname((0,control_1.controlSocketPath)()),"identities")});let b;try{b=(0,control_1.startControlServer)({rt:E,killService:n((e,t)=>v.killSpawned(e,t),"killService"),restartService:n((e,t)=>v.restartService(e,t),"restartService"),...O?{act:O}:{},onRegister:n(async e=>{retirePreviousWorkspace(W,e.wsKey,"re-registered"),K.set(e.wsKey,e.root,e.middleware);const t=await L.hostWorkspaceDashboard(e),h=await L.hostWorkspaceApps(e);W.set(e.wsKey,()=>{try{t?.()}finally{h()}})},"onRegister"),onUnregister:n(e=>{retirePreviousWorkspace(W,e.wsKey,"unregistered"),K.drop(e.wsKey),v.stopBuildHost(e.root)},"onUnregister")})}catch(e){console.warn("[gateway] control plane failed to start (multi-workspace register disabled):",e.message)}const I=(0,proxy_1.createProxy)(E,f,v),Z=buildEdgeVerifierPool(()=>E.routes),ee=(0,auth_1.createEdgeAuth)(E,f,Z,O),pe=n(e=>{const t=e.route?.wsKey,h=K.for(t);if(h)try{const i=t?E.registry.get(t):void 0;h(e.req,{...t?{wsKey:t}:{},...i?{root:i.root}:{},env:i?.instance?.env??{}})}catch(i){f.traceStep(e.trace,"auth",{mode:"middleware",ok:!1,reason:i.message}),e.route&&f.finishTrace(e.trace,e.route.project,401),e.sendError(401,"unauthorized",`Gateway middleware rejected the request: ${i.message}`)}},"builtinMiddleware"),se=s.hooks??{},re=(0,hooks_1.createHooks)({...se,afterAuth:[pe,...se.afterAuth??[]]}),te=(0,handler_1.createHandler)({rt:E,obs:f,auth:ee,proxy:I,hooks:re}),oe=(0,upgrade_1.createUpgrade)({rt:E,auth:ee,proxy:I,hooks:re,obs:f}),_e=f.startEdgeFlusher(),Se=v.startSweeper(),ne=(0,source_poller_1.createSourcePoller)({services:n(()=>E.registry.allServices(),"services"),serviceKey:n(e=>E.serviceKeys[(0,service_keys_1.serviceKeyId)(e.wsKey,e.project)],"serviceKey"),emit:n((e,t,h,i,p)=>f.emit(t,h,i,{wsKey:e.wsKey,...p},void 0,e.wsKey===E.wsKey?void 0:path.join(e.root,".lensmcp","events.jsonl")),"emit"),scanTtlMs:a,stopped:n(()=>l,"stopped")});(0,source_poller_1.sourcesEnabled)()&&ne.start(),await L.bootSingletonsAndApps();for(const e of N)e.decl.eager&&v.ensureUp(e);let P,F,H;if(u){const e=require("../../../basic-ssl"),t=(0,service_keys_1.gatewayCacheDir)(r.root);H=n(()=>e.getCertificateSync(t,"gateway",E.routes.map(h=>h.host).filter(h=>!!h)),"mintCert"),P=H(),F=e.caCertPath()}const U=[],$=[],Y=s.maxConnections??resolveMaxConnections(process.env.LENSMCP_MAX_CONNECTIONS);for(const e of m){const t=P?require("node:http2").createSecureServer({key:P,cert:P,allowHTTP1:!0,maxSessionMemory:512,settings:{maxConcurrentStreams:512},peerMaxConcurrentStreams:512,streamResetBurst:s.h2ResetBurst??types_1.GATEWAY_H2_RESET_BURST,streamResetRate:s.h2ResetRate??types_1.GATEWAY_H2_RESET_RATE},(i,p)=>te(i,p)):http.createServer(te);t.on("upgrade",oe),t.on("error",i=>console.error(`[gateway] port ${e}: ${i.code}`)),t.on("connection",guardInboundSocket),t.on("secureConnection",guardInboundSocket),t.on("tlsClientError",(i,p)=>p.destroy()),t.on("clientError",(i,p)=>{const c=i,y=classifyClientError(c.code,c.message);if(y.report&&ue(y.cause)){const C=p.remoteAddress??"unknown",M=y.status===null?"dropped":String(y.status);console.warn(`[gateway] inbound H1 clientError from ${C}: ${y.cause} (${c.code??c.message}${c.bytesParsed!==void 0?`, bytesParsed=${c.bytesParsed}`:""}) \u2192 ${M}. This status is the GATEWAY's, not the upstream service's.`),f.emit("warning",`inbound clientError: ${y.cause} \u2192 ${M}`,`gateway-client-error:${y.cause}`,{kind:"gateway-client-error",cause:y.cause,code:c.code??null,status:y.status,peer:C,bytesParsed:c.bytesParsed??null})}y.status!==null&&p.writable&&p.end(`HTTP/1.1 ${y.status} ${CLIENT_ERROR_REASON[y.status]}\r
|
|
1
|
+
"use strict";var me=Object.defineProperty;var v=(r,t)=>me(r,"name",{value:t,configurable:!0});var ge=Object.defineProperty,A=v((r,t)=>ge(r,"name",{value:t,configurable:!0}),"A"),he=Object.defineProperty,n=A((r,t)=>he(r,"name",{value:t,configurable:!0}),"n");Object.defineProperty(exports,"__esModule",{value:!0}),exports.GATEWAY_H2_IDLE_SESSION_MS_DEFAULT=exports.GATEWAY_MAX_H2_STREAMS_DEFAULT=exports.GATEWAY_MAX_H2_SESSIONS_DEFAULT=exports.GATEWAY_MAX_CONNECTIONS_DEFAULT=exports.BENIGN_SOCKET_ERRNOS=void 0,exports.buildEdgeVerifierPool=buildEdgeVerifierPool,exports.classifyClientError=classifyClientError,exports.createClientErrorLogGate=createClientErrorLogGate,exports.retirePreviousWorkspace=retirePreviousWorkspace,exports.resolveMaxConnections=resolveMaxConnections,exports.h2BudgetFromEnv=h2BudgetFromEnv,exports.createH2Governor=createH2Governor,exports.startGateway=startGateway;const tslib_1=require("tslib"),http=tslib_1.__importStar(require("node:http")),path=tslib_1.__importStar(require("node:path")),discovery_1=require("./discovery"),scope_1=require("./scope"),route_registry_1=require("./route-registry"),act_1=require("./act"),control_1=require("./control"),workspace_middleware_1=require("./workspace-middleware"),workspace_registry_1=require("./workspace-registry"),service_keys_1=require("./service-keys"),source_poller_1=require("./source-poller"),client_ip_1=require("../client-ip"),workspace_log_1=require("./workspace-log"),own_log_1=require("./own-log"),observability_1=require("./observability"),lifecycle_1=require("./lifecycle"),process_names_1=require("./process-names"),project_graph_store_1=require("./project-graph-store"),serve_launch_1=require("./serve-launch"),process_name_1=require("../../../process-name"),protocol_1=require("../../../shared-build/protocol"),lens_children_1=require("./lens-children"),proxy_1=require("./proxy"),auth_1=require("./auth"),hooks_1=require("./hooks"),handler_1=require("./handler"),upgrade_1=require("./upgrade"),jwks_verify_1=require("../jwks-verify"),types_1=require("./types");function insecureLocalFetch(r,t){return new Promise((u,m)=>{const a=(r.startsWith("https:")?require("node:https"):require("node:http")).request(r,{method:"GET",headers:t?.headers,rejectUnauthorized:!1},w=>{const _=[];w.on("data",g=>_.push(g)),w.on("end",()=>{const g=w.statusCode??0,l=Buffer.concat(_).toString("utf8");u({ok:g>=200&&g<300,status:g,json:n(async()=>JSON.parse(l),"json")})})});a.on("error",m),a.end()})}v(insecureLocalFetch,"insecureLocalFetch"),A(insecureLocalFetch,"insecureLocalFetch"),n(insecureLocalFetch,"insecureLocalFetch");function buildEdgeVerifierPool(r){const t=process.env.LENSMCP_GW_JWKS_URL,u=process.env.LENSMCP_GW_JWT_ISS,m=new Map;let a;const w=n((_,g)=>{console.log(`[gateway] edge JWT: verifying via JWKS ${_}${g}`);const l=(0,jwks_verify_1.createJwksVerifier)({jwksUrl:_,...u?{issuer:u}:{},fetchImpl:insecureLocalFetch});return l.refresh().catch(s=>console.warn("[gateway] edge JWKS warm failed (will retry):",s.message)),l},"make");return{for(_){if(t)return a??=w(t,"");const g=_.split(":")[0].toLowerCase();let l;for(const d of r()){const S=d.host;if(typeof S!="string"||!/^auth\./.test(S)||S.startsWith("internal."))continue;const T=S.slice(5);(g===T||g.endsWith(`.${T}`))&&(!l||T.length>l.length)&&(l=T)}if(!l)return;let s=m.get(l);return s||(s=w(`https://auth.${l}/jwks.json`,` (auto-derived for apex ${l})`),m.set(l,s)),s},stop(){a?.stop();for(const _ of m.values())_.stop()}}}v(buildEdgeVerifierPool,"buildEdgeVerifierPool"),A(buildEdgeVerifierPool,"buildEdgeVerifierPool"),n(buildEdgeVerifierPool,"buildEdgeVerifierPool"),exports.BENIGN_SOCKET_ERRNOS=new Set(["ECONNRESET","EPIPE","ETIMEDOUT","ECONNABORTED","ECANCELED"]);function classifyClientError(r,t){return r&&exports.BENIGN_SOCKET_ERRNOS.has(r)?{status:null,report:!1,cause:"client-abort"}:r==="HPE_INVALID_EOF_STATE"?{status:null,report:!1,cause:"truncated-at-eof"}:r==="ERR_HTTP_REQUEST_TIMEOUT"?{status:408,report:!0,cause:"request-timeout"}:r==="HPE_HEADER_OVERFLOW"?{status:431,report:!0,cause:"header-overflow"}:r?.startsWith("HPE_")?{status:400,report:!0,cause:"parse-error"}:{status:400,report:!0,cause:r??t??"unknown"}}v(classifyClientError,"classifyClientError"),A(classifyClientError,"classifyClientError"),n(classifyClientError,"classifyClientError");const CLIENT_ERROR_REASON={400:"Bad Request",408:"Request Timeout",431:"Request Header Fields Too Large"};function createClientErrorLogGate(r=1e4){const t=new Map;return u=>{const m=Date.now(),a=t.get(u)??0;return m-a<r?!1:(t.set(u,m),!0)}}v(createClientErrorLogGate,"createClientErrorLogGate"),A(createClientErrorLogGate,"createClientErrorLogGate"),n(createClientErrorLogGate,"createClientErrorLogGate");function guardInboundSocket(r){r.on("error",t=>{exports.BENIGN_SOCKET_ERRNOS.has(t.code??"")||console.warn(`[gateway] inbound socket error (${t.code??t.message}) \u2014 dropping this connection only`),r.destroy()})}v(guardInboundSocket,"guardInboundSocket"),A(guardInboundSocket,"guardInboundSocket"),n(guardInboundSocket,"guardInboundSocket");function retirePreviousWorkspace(r,t,u){const m=r.get(t);if(!m)return!1;r.delete(t),u==="re-registered"&&console.log(`[gateway] workspace '${t}' re-registered \u2014 retiring the children of its previous registration first.`);try{m()}catch(a){console.warn(`[gateway] could not fully retire the previous registration of '${t}' (${u}): ${a.message}`)}return!0}v(retirePreviousWorkspace,"retirePreviousWorkspace"),A(retirePreviousWorkspace,"retirePreviousWorkspace"),n(retirePreviousWorkspace,"retirePreviousWorkspace"),exports.GATEWAY_MAX_CONNECTIONS_DEFAULT=512,exports.GATEWAY_MAX_H2_SESSIONS_DEFAULT=64,exports.GATEWAY_MAX_H2_STREAMS_DEFAULT=4096,exports.GATEWAY_H2_IDLE_SESSION_MS_DEFAULT=3e5;function parseBudget(r,t){if(r===void 0||r.trim()==="")return t;const u=Number(r);return!Number.isFinite(u)||u<0?t:Math.floor(u)}v(parseBudget,"parseBudget"),A(parseBudget,"parseBudget"),n(parseBudget,"parseBudget");function resolveMaxConnections(r){return parseBudget(r,exports.GATEWAY_MAX_CONNECTIONS_DEFAULT)}v(resolveMaxConnections,"resolveMaxConnections"),A(resolveMaxConnections,"resolveMaxConnections"),n(resolveMaxConnections,"resolveMaxConnections");function h2BudgetFromEnv(r=process.env){return{maxSessions:parseBudget(r.LENSMCP_MAX_H2_SESSIONS,exports.GATEWAY_MAX_H2_SESSIONS_DEFAULT),maxStreams:parseBudget(r.LENSMCP_MAX_H2_STREAMS,exports.GATEWAY_MAX_H2_STREAMS_DEFAULT),idleSessionMs:parseBudget(r.LENSMCP_H2_IDLE_MS,exports.GATEWAY_H2_IDLE_SESSION_MS_DEFAULT)}}v(h2BudgetFromEnv,"h2BudgetFromEnv"),A(h2BudgetFromEnv,"h2BudgetFromEnv"),n(h2BudgetFromEnv,"h2BudgetFromEnv");function createH2Governor(r,t){const{NGHTTP2_ENHANCE_YOUR_CALM:u,NGHTTP2_REFUSED_STREAM:m}=require("node:http2").constants,a=new Map;let w=0;const _=n(s=>{s.idle&&(clearTimeout(s.idle),s.idle=void 0)},"disarm"),g=n((s,d)=>{_(d),!(r.idleSessionMs<=0||d.open>0)&&(d.idle=setTimeout(()=>{s.destroyed||s.closed||(t("session-reclaimed",{idleMs:r.idleSessionMs,sessions:a.size}),a.delete(s),s.close())},r.idleSessionMs),d.idle.unref?.())},"arm"),l=n(()=>{for(const[s,d]of a)if(!(d.open>0||s.destroyed))return _(d),a.delete(s),t("session-reclaimed",{reason:"cap",sessions:a.size+1,maxSessions:r.maxSessions}),s.close(),!0;return!1},"reclaimOldestIdle");return{admitSession(s){if(r.maxSessions>0&&a.size>=r.maxSessions&&!l()){t("session-refused",{sessions:a.size,maxSessions:r.maxSessions,streams:w});try{s.goaway(u)}catch{}try{s.close()}catch{}return!1}const d={open:0};return a.set(s,d),g(s,d),s.once("close",()=>{_(d),a.delete(s)}),!0},admitStream(s,d){const S=a.get(s);if(!S)return!0;if(r.maxStreams>0&&w>=r.maxStreams){t("stream-refused",{streams:w,maxStreams:r.maxStreams,sessions:a.size});try{d.close(m)}catch{}return!1}return w+=1,S.open+=1,_(S),d.once("close",()=>{w=Math.max(0,w-1),S.open=Math.max(0,S.open-1),S.open===0&&a.has(s)&&g(s,S)}),!0},dispose(){for(const s of a.values())_(s);a.clear()}}}v(createH2Governor,"createH2Governor"),A(createH2Governor,"createH2Governor"),n(createH2Governor,"createH2Governor");async function startGateway(r,t){const u=r.https!==!1,m=r.ports?.length?r.ports:[443],a=r.scanTtlMs??1500,w=r.startupTimeoutMs??12e4,_=r.sweepMs??1e4,g=r.trafficFlushMs??5e3;let l=!1;const s=process.env.LENSMCP_EVENT_FILE??path.join(t.root,".lensmcp","events.jsonl"),d=(0,own_log_1.startOwnLogRotation)(t.root),S=(0,scope_1.readLensScope)(t.root),T=S.key,k=S.sockNs!==T?S.sockNs:void 0,V=t.projectsConfigurations?.projects??{},J=(0,discovery_1.projectSourceRoots)(t.root,V,t.projectDependencies),{routes:j,services:P,instance:z}=(0,discovery_1.discoverRoutes)(t.root,V,void 0,T,J,k,S.instance);if(j.length===0)throw new Error("[gateway] no project declares a `cluster` field \u2014 nothing to route.");const q=new route_registry_1.RouteRegistry;q.register({wsKey:T,...k?{sockNs:k}:{},root:t.root,routes:j,services:P,...z?{instance:z}:{}});const R=[];let Q=n(()=>{},"refreshCert");const Z=n(()=>{(0,route_registry_1.rebuildRoutesInPlace)(R,q),Q()},"rebuildRoutes");Z();const{serviceKeys:ie,keyToProject:ce,keyToWorkspace:le}=(0,service_keys_1.loadServiceKeys)(t.root,P,T),ue=(0,client_ip_1.createClientIpResolver)({...(0,client_ip_1.clientIpOptionsFromEnv)(),...r.trustProxyHops!==void 0?{trustProxyHops:r.trustProxyHops}:{},...r.clientIpHeader?{clientIpHeader:r.clientIpHeader}:{},...r.clientIpTrustedProxies?{clientIpTrustedProxies:r.clientIpTrustedProxies}:{}}),E={root:t.root,wsKey:T,...k?{sockNs:k}:{},eventFile:s,routes:R,registry:q,rebuildRoutes:Z,services:P,serviceKeys:ie,keyToProject:ce,keyToWorkspace:le,clientIp:ue,bodyStallMs:r.bodyStallMs??types_1.BODY_STALL_MS,scanTtlMs:a,startupTimeoutMs:w,sweepMs:_,trafficFlushMs:g,https:u,projectRoots:Object.fromEntries(Object.entries(t.projectsConfigurations?.projects??{}).map(([e,o])=>[e,path.resolve(t.root,o.root)])),projectSourceRoots:J,...t.projectGraphStore?{graphStores:(0,project_graph_store_1.createProjectGraphStores)(t.projectGraphStore)}:{},...r.sharedCompiler!==void 0?{sharedCompiler:r.sharedCompiler}:{},stopped:n(()=>l,"stopped")};(0,process_name_1.prelinkProcessNames)((0,process_names_1.gatewayProcessNames)(P,{runner:(0,serve_launch_1.serveRunnerEnabled)()&&!!t.projectGraphStore,sharedBuild:(0,protocol_1.sharedCompilerEnabled)(process.env,r.sharedCompiler),label:T||path.basename(t.root),lens:{key:T,dashboard:r.dashboard!==!1,mcp:r.mcp!==!1&&j.some(e=>!!e.lens)}}));const f=(0,observability_1.createObservability)(s,{trafficFlushMs:g}),de=createClientErrorLogGate(),b=h2BudgetFromEnv(),pe=createClientErrorLogGate(3e4),W=createH2Governor(b,(e,o)=>{pe(e)&&console.warn(`[gateway] h2 aggregate budget: ${e} (${JSON.stringify(o)}). These are the FRONT DOOR's ceilings, not an upstream's \u2014 raise/disable with LENSMCP_MAX_H2_SESSIONS / LENSMCP_MAX_H2_STREAMS / LENSMCP_H2_IDLE_MS / LENSMCP_MAX_CONNECTIONS (0 = unbounded).`),f.emit(e==="session-reclaimed"?"info":"warning",`h2 aggregate budget: ${e}`,`gateway-h2-budget:${e}`,{kind:"h2-aggregate-budget",event:e,project:"gateway",...o})}),M=(0,lifecycle_1.createServiceLayer)(E,f),L=(0,lens_children_1.createLensChildren)(E,f,r),F=new Map;let D;if(r.middleware){const e=require(path.resolve(t.root,r.middleware));D=e.default??e}const K=(0,workspace_middleware_1.createWorkspaceMiddleware)({ownerKey:T,...D?{owner:D}:{},policy:(0,workspace_middleware_1.guestMiddlewarePolicy)()}),O=process.env.LENSMCP_GW_ACT==="0"?void 0:(0,act_1.createActStore)({dir:path.join(path.dirname((0,control_1.controlSocketPath)()),"identities")});let I;try{I=(0,control_1.startControlServer)({rt:E,killService:n((e,o)=>M.killSpawned(e,o),"killService"),restartService:n((e,o)=>M.restartService(e,o),"restartService"),...O?{act:O}:{},onRegister:n(async e=>{retirePreviousWorkspace(F,e.wsKey,"re-registered"),K.set(e.wsKey,e.root,e.middleware);const o=await L.hostWorkspaceDashboard(e),h=await L.hostWorkspaceApps(e);F.set(e.wsKey,()=>{try{o?.()}finally{h()}})},"onRegister"),onUnregister:n(e=>{retirePreviousWorkspace(F,e.wsKey,"unregistered"),K.drop(e.wsKey),M.stopBuildHost(e.root)},"onUnregister")})}catch(e){console.warn("[gateway] control plane failed to start (multi-workspace register disabled):",e.message)}const H=(0,proxy_1.createProxy)(E,f,M),ee=buildEdgeVerifierPool(()=>E.routes),re=(0,auth_1.createEdgeAuth)(E,f,ee,O),_e=n(e=>{const o=e.route?.wsKey,h=K.for(o);if(h)try{const i=o?E.registry.get(o):void 0;h(e.req,{...o?{wsKey:o}:{},...i?{root:i.root}:{},env:i?.instance?.env??{}})}catch(i){f.traceStep(e.trace,"auth",{mode:"middleware",ok:!1,reason:i.message}),e.route&&f.finishTrace(e.trace,e.route.project,401),e.sendError(401,"unauthorized",`Gateway middleware rejected the request: ${i.message}`)}},"builtinMiddleware"),te=r.hooks??{},oe=(0,hooks_1.createHooks)({...te,afterAuth:[_e,...te.afterAuth??[]]}),se=(0,handler_1.createHandler)({rt:E,obs:f,auth:re,proxy:H,hooks:oe}),ne=(0,upgrade_1.createUpgrade)({rt:E,auth:re,proxy:H,hooks:oe,obs:f}),Se=f.startEdgeFlusher(),Ee=M.startSweeper(),ae=(0,source_poller_1.createSourcePoller)({services:n(()=>E.registry.allServices(),"services"),serviceKey:n(e=>E.serviceKeys[(0,service_keys_1.serviceKeyId)(e.wsKey,e.project)],"serviceKey"),emit:n((e,o,h,i,p)=>f.emit(o,h,i,{wsKey:e.wsKey,...p},void 0,e.wsKey===E.wsKey?void 0:path.join(e.root,".lensmcp","events.jsonl")),"emit"),scanTtlMs:a,stopped:n(()=>l,"stopped")});(0,source_poller_1.sourcesEnabled)()&&ae.start(),await L.bootSingletonsAndApps();for(const e of P)e.decl.eager&&M.ensureUp(e);let x,U,$;if(u){const e=require("../../../basic-ssl"),o=(0,service_keys_1.gatewayCacheDir)(t.root);$=n(()=>e.getCertificateSync(o,"gateway",E.routes.map(h=>h.host).filter(h=>!!h)),"mintCert"),x=$(),U=e.caCertPath()}const B=[],G=[],Y=r.maxConnections??resolveMaxConnections(process.env.LENSMCP_MAX_CONNECTIONS);for(const e of m){const o=x?require("node:http2").createSecureServer({key:x,cert:x,allowHTTP1:!0,maxSessionMemory:512,settings:{maxConcurrentStreams:512},peerMaxConcurrentStreams:512,streamResetBurst:r.h2ResetBurst??types_1.GATEWAY_H2_RESET_BURST,streamResetRate:r.h2ResetRate??types_1.GATEWAY_H2_RESET_RATE},(i,p)=>se(i,p)):http.createServer(se);o.on("upgrade",ne),o.on("error",i=>console.error(`[gateway] port ${e}: ${i.code}`)),o.on("connection",guardInboundSocket),o.on("secureConnection",guardInboundSocket),o.on("tlsClientError",(i,p)=>p.destroy()),o.on("clientError",(i,p)=>{const c=i,y=classifyClientError(c.code,c.message);if(y.report&&de(y.cause)){const N=p.remoteAddress??"unknown",C=y.status===null?"dropped":String(y.status);console.warn(`[gateway] inbound H1 clientError from ${N}: ${y.cause} (${c.code??c.message}${c.bytesParsed!==void 0?`, bytesParsed=${c.bytesParsed}`:""}) \u2192 ${C}. This status is the GATEWAY's, not the upstream service's.`),f.emit("warning",`inbound clientError: ${y.cause} \u2192 ${C}`,`gateway-client-error:${y.cause}`,{kind:"gateway-client-error",cause:y.cause,code:c.code??null,status:y.status,peer:N,bytesParsed:c.bytesParsed??null})}y.status!==null&&p.writable&&p.end(`HTTP/1.1 ${y.status} ${CLIENT_ERROR_REASON[y.status]}\r
|
|
2
2
|
\r
|
|
3
|
-
`),p.destroy()}),
|
|
3
|
+
`),p.destroy()}),o.keepAliveTimeout=types_1.GATEWAY_KEEPALIVE_TIMEOUT_MS,o.headersTimeout=r.headersTimeoutMs??types_1.GATEWAY_HEADERS_TIMEOUT_MS,Y>0&&(o.maxConnections=Y);const h=r.connectionsCheckingIntervalMs??types_1.GATEWAY_CONN_CHECK_MS;if(h>0&&(o.connectionsCheckingInterval=h),x!=null){const i=o,{NGHTTP2_CANCEL:p}=require("node:http2").constants;i.on("session",c=>{if(!W.admitSession(c)){c.on("error",()=>{});return}let y=0,N=0;c.on("stream",C=>{W.admitStream(c,C)&&C.once("close",()=>{c.destroyed?N+=1:C.rstCode===p&&(y+=1)})}),c.once("close",()=>{N!==0&&(console.warn(`[gateway] h2 session closed with ${N} stream(s) in flight after ${y} client reset(s) \u2014 every in-flight fetch on that connection failed at once (ERR_HTTP2_PROTOCOL_ERROR in the browser). Reset budget: LENSMCP_H2_RESET_BURST/LENSMCP_H2_RESET_RATE (issues/closed/foodguard-14).`),f.emit("warning",`h2 session lost with ${N} stream(s) in flight`,"gateway-h2-session-lost",{kind:"h2-session-lost",project:"gateway",inflight:N,clientResets:y}))}),c.on("error",C=>{const ye=C.code??C.message;console.warn(`[gateway] h2 session error (${ye}) \u2014 dropping this session only`),c.destroyed||c.destroy()})}),i.on("sessionError",c=>{console.warn(`[gateway] h2 sessionError: ${c.code??c.message}`)})}await new Promise(i=>{o.listen(e,()=>{const p=o.address()?.port??e;G.push(p),console.log(`[gateway] Listening on ${x?"https":"http"}://localhost:${p}`),i()})}),B.push(o)}$&&(Q=n(()=>{const e=$();for(const o of B)o.setSecureContext?.({key:e,cert:e})},"refreshCert")),console.log("[gateway] Routes:");for(const e of R){const o=e.pool?`pods@${e.pool.dir}`:e.target;console.log(`[gateway] ${e.host??"(default)"} \u2192 ${o}${e.prependPrefix?` (+${e.prependPrefix})`:""}${e.internal?" [internal: no middleware]":""} [${e.project}]`)}U&&console.log(`[gateway] CA: ${U} \u2014 one-time setup via the trust executor.`);const X=n(e=>e>0?String(e):"unbounded","unbounded");return console.log(`[gateway] front-door budget: \u2264${X(Y)} connections, \u2264${X(b.maxSessions)} h2 sessions (each \u2264512 MB session memory, \u2264512 streams), \u2264${X(b.maxStreams)} open streams in total, idle h2 session reclaimed after ${b.idleSessionMs>0?`${Math.round(b.idleSessionMs/1e3)}s`:"never"}. Override: LENSMCP_MAX_CONNECTIONS / LENSMCP_MAX_H2_SESSIONS / LENSMCP_MAX_H2_STREAMS / LENSMCP_H2_IDLE_MS (0 = unbounded).`),f.emit("info",`gateway up: ${R.length} routes on ${G.join("/")}`,"cluster-gateway",{kind:"gateway-up",project:"gateway",ports:G,routes:R.map(e=>({host:e.host??"(default)",project:e.project,mode:e.pool?"pods":"tcp",internal:!!e.internal,prependPrefix:e.prependPrefix}))}),I&&process.env.LENSMCP_GUEST_REPLAY!=="0"&&I.replay().catch(e=>console.warn("[gateway] guest replay failed:",e.message)),{ports:G,routes:R,services:P,stop:n(async()=>{if(!l){l=!0,clearInterval(Se),clearInterval(Ee),ae.stop(),f.emit("info","gateway down","cluster-gateway",{kind:"gateway-down",project:"gateway"}),ee.stop(),I?.close(),O?.flush(),(0,workspace_registry_1.unregisterWorkspace)(T);for(const e of P)M.killSpawned(e,"gateway shutdown");M.stopRetiringTrees(),await M.stopBuildHost(),await L.reapAll(),ne.closeTunnels(),await Promise.all(B.map(e=>new Promise(o=>{let h=!1;const i=n(()=>{h||(h=!0,o())},"done"),p=e;e.close(()=>i());try{p.closeIdleConnections?.()}catch{}setTimeout(()=>{try{p.closeAllConnections?.()}catch{}i()},types_1.GATEWAY_STOP_GRACE_MS).unref?.()}))),H.closeProxy(),H.destroyAgents(),W.dispose(),(0,workspace_log_1.closeWorkspaceLogs)(),d()}},"stop"),...E.lensSupervisor?{lensSupervisor:E.lensSupervisor}:{},...E.graphStores?{graphStores:E.graphStores}:{}}}v(startGateway,"startGateway"),A(startGateway,"startGateway"),n(startGateway,"startGateway");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var k=Object.defineProperty;var d=(e,r)=>k(e,"name",{value:r,configurable:!0});var l=Object.defineProperty,a=d((e,r)=>l(e,"name",{value:r,configurable:!0}),"a"),h=Object.defineProperty,y=a((e,r)=>h(e,"name",{value:r,configurable:!0}),"y");Object.defineProperty(exports,"__esModule",{value:!0}),exports.gatewayCacheDir=gatewayCacheDir,exports.serviceKeyId=serviceKeyId,exports.loadServiceKeys=loadServiceKeys,exports.adoptServiceKeys=adoptServiceKeys;const tslib_1=require("tslib"),node_crypto_1=require("node:crypto"),fs=tslib_1.__importStar(require("node:fs")),path=tslib_1.__importStar(require("node:path")),checkout_cache_1=require("../../../checkout-cache");function gatewayCacheDir(e){return(0,checkout_cache_1.checkoutCacheDir)(e,"davnx-webpack")}d(gatewayCacheDir,"gatewayCacheDir"),a(gatewayCacheDir,"gatewayCacheDir"),y(gatewayCacheDir,"gatewayCacheDir");function serviceKeyId(e,r){return`${e??""} ${r}`}d(serviceKeyId,"serviceKeyId"),a(serviceKeyId,"serviceKeyId"),y(serviceKeyId,"serviceKeyId");function loadServiceKeys(e,r,p,S){const n=gatewayCacheDir(e),j=path.join(n,"service-keys.json");let t={};try{t=JSON.parse(fs.readFileSync(j,"utf8"))}catch{}let u=!1;const v=[];for(const[c,f]of Object.entries(t))S?.(f)&&(t[c]=(0,node_crypto_1.randomBytes)(16).toString("hex"),u=!0,v.push(c));for(const c of r)t[c.project]||(t[c.project]=(0,node_crypto_1.randomBytes)(16).toString("hex"),u=!0);if(u)try{fs.mkdirSync(n,{recursive:!0}),fs.writeFileSync(j,JSON.stringify(t,null,2))}catch{}const o=p??r[0]?.wsKey,s={};for(const[c,f]of Object.entries(t))s[serviceKeyId(o,c)]=f;const i=new Map(Object.entries(t).map(([c,f])=>[f,c])),K=new Map(o?Object.values(t).map(c=>[c,o]):[]);return{serviceKeys:s,keyToProject:i,keyToWorkspace:K,byProject:t,regenerated:v}}d(loadServiceKeys,"loadServiceKeys"),a(loadServiceKeys,"loadServiceKeys"),y(loadServiceKeys,"loadServiceKeys");function adoptServiceKeys(e,r,p,S){const n=S??p[0]?.wsKey,j=y(o=>{const s=e.keyToWorkspace?.get(o);return s!==void 0&&s!==n},"taken"),{byProject:t,regenerated:u}=loadServiceKeys(r,p,n,j),v=[];for(const o of p){const s=serviceKeyId(o.wsKey??n,o.project),i=t[o.project];if(!i||e.serviceKeys[s]===i)continue;e.serviceKeys[s]=i,e.keyToProject.set(i,o.project);const K=o.wsKey??n;K&&e.keyToWorkspace?.set(i,K),v.push(o.project)}return{added:v,regenerated:u}}d(adoptServiceKeys,"adoptServiceKeys"),a(adoptServiceKeys,"adoptServiceKeys"),y(adoptServiceKeys,"adoptServiceKeys");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`)){const
|
|
3
|
-
`))
|
|
4
|
-
`)},"relayOut");return
|
|
1
|
+
"use strict";var L=Object.defineProperty;var v=(o,t)=>L(o,"name",{value:t,configurable:!0});var A=Object.defineProperty,y=v((o,t)=>A(o,"name",{value:t,configurable:!0}),"y"),j=Object.defineProperty,i=y((o,t)=>j(o,"name",{value:t,configurable:!0}),"i");Object.defineProperty(exports,"__esModule",{value:!0}),exports.HOST_MAX_RESTARTS=void 0,exports.buildHostScript=buildHostScript,exports.workspaceBuildHostScript=workspaceBuildHostScript,exports.createSharedBuildRelay=createSharedBuildRelay;const tslib_1=require("tslib"),node_child_process_1=require("node:child_process"),fs=tslib_1.__importStar(require("node:fs")),node_module_1=require("node:module"),path=tslib_1.__importStar(require("node:path")),process_name_1=require("../../../process-name"),protocol_1=require("../../../shared-build/protocol"),pod_env_1=require("./pod-env"),registration_guards_1=require("./registration-guards");exports.HOST_MAX_RESTARTS=3;const CRASH_WINDOW_MS=6e4;function buildHostScript(o=path.join(__dirname,"../../..")){const t=path.join(o,"build-host.js");if(fs.existsSync(t))return{path:t,execArgv:[]};const u=path.join(o,"build-host.ts");if(fs.existsSync(u))try{return{path:u,execArgv:["--require",require.resolve("@swc-node/register")]}}catch{return}}v(buildHostScript,"buildHostScript"),y(buildHostScript,"buildHostScript"),i(buildHostScript,"buildHostScript");function workspaceBuildHostScript(o){try{return{path:(0,node_module_1.createRequire)(path.join(o,"package.json")).resolve("@lensmcp/cluster/build-host.js"),execArgv:[]}}catch{return}}v(workspaceBuildHostScript,"workspaceBuildHostScript"),y(workspaceBuildHostScript,"workspaceBuildHostScript"),i(workspaceBuildHostScript,"workspaceBuildHostScript");function createSharedBuildRelay(o,t={}){const u=t.script===void 0?buildHostScript():t.script??void 0,_=t.scriptFor??workspaceBuildHostScript,h=new Map,f=new WeakMap,d=(0,registration_guards_1.canonicalRoot)(o.root),g=i(e=>{const a=(0,registration_guards_1.canonicalRoot)(e.root);let c=h.get(a);return c||(c=a===d?createWorkspaceRelay(o,{root:o.root,...o.wsKey?{wsKey:o.wsKey}:{},...o.sockNs?{sockNs:o.sockNs}:{},eventFile:o.eventFile},u,t):createWorkspaceRelay(o,{root:e.root,...e.wsKey?{wsKey:e.wsKey}:{},...e.sockNs?{sockNs:e.sockNs}:{},eventFile:path.join(e.root,".lensmcp","events.jsonl")},_(e.root),t),h.set(a,c)),c},"relayFor");return{offeredTo:i(e=>(0,protocol_1.sharedCompilerEnabled)(t.gatewayEnv??process.env,o.sharedCompiler)&&g(e).offered(),"offeredTo"),attach(e,a,c){const m=g(e);f.set(c,m),m.attach(`${e.project}#g${a}`,c)},detach:i(e=>f.get(e)?.detach(e),"detach"),hostPid:i((e=o.root)=>h.get((0,registration_guards_1.canonicalRoot)(e))?.hostPid(),"hostPid"),release(e){const a=(0,registration_guards_1.canonicalRoot)(e),c=h.get(a);return h.delete(a),c?.stop()??Promise.resolve()},async stop(){const e=[...h.values()];h.clear(),await Promise.all(e.map(a=>a.stop()))}}}v(createSharedBuildRelay,"createSharedBuildRelay"),y(createSharedBuildRelay,"createSharedBuildRelay"),i(createSharedBuildRelay,"createSharedBuildRelay");function createWorkspaceRelay(o,t,u,_){const h=_.spawnProcess??node_child_process_1.spawn,f=_.log??(r=>console.log(r)),d=new Map,g=new WeakMap;let e,a=[],c,m=!1;const N=(0,registration_guards_1.canonicalRoot)(t.root)===(0,registration_guards_1.canonicalRoot)(o.root)?"this workspace":`'${t.wsKey??path.basename(t.root)}'`,R=i((r,s)=>{if(!r.connected)return;const n={channel:protocol_1.SHARED_BUILD_CHANNEL,event:s};try{r.send(n,void 0,void 0,()=>{})}catch{}},"toRunner"),E=i(r=>{if(e?.connected)try{e.send(r,void 0,void 0,()=>{})}catch{}},"toHost"),P=i(()=>{if(_.reapStale===!1)return;let r;try{r=(0,node_child_process_1.execFileSync)("ps",["ax","-ww","-o","pid=,pgid=,command="],{encoding:"utf8",timeout:5e3})}catch{return}for(const s of r.split(`
|
|
2
|
+
`)){const n=s.match(/^\s*(\d+)\s+(\d+)\s+(.*)$/);if(!n||!(0,protocol_1.isBuildHostCommandOf)(n[3],t.root))continue;const l=Number(n[1]),p=Number(n[2]);if(!(l===e?.pid||l===process.pid)){try{process.kill(-p,"SIGKILL")}catch{try{process.kill(l,"SIGKILL")}catch{}}f(`[gateway] reaped a stale build host (pid ${l}) of ${N}`)}}},"reapStaleHosts"),k=i(()=>{if(e||m||c||!u)return e;P();const r=t.wsKey||path.basename(t.root),s={...(0,pod_env_1.podBaseEnv)(process.env,o.root,t.root),NX_DAEMON:"false",NODE_ENV:"development",NX_WORKSPACE_ROOT:t.root,...t.wsKey?{LENSMCP_WS_KEY:t.wsKey}:{},...t.sockNs?{LENSMCP_SOCK_NS:t.sockNs}:{},LENSMCP_EVENT_FILE:t.eventFile,LENSMCP_GATEWAY_PID:String(process.pid)},n=h((0,process_name_1.namedExecPath)((0,process_name_1.processName)(r,protocol_1.BUILD_HOST_ROLE)),[...u.execArgv,u.path,...(0,protocol_1.buildHostArgs)(t.root)],{cwd:t.root,detached:!0,env:s,stdio:["ignore","pipe","pipe","ipc"]});e=n,f(`[gateway] build host starting (one compilation for the services of ${N} \u2014 LENSMCP_SHARED_COMPILER)`);const l=i(p=>S=>{if(!o.stopped())for(const w of S.toString().split(`
|
|
3
|
+
`))w.trim()&&p.write(`[build] ${w}
|
|
4
|
+
`)},"relayOut");return n.stdout?.on("data",l(process.stdout)),n.stderr?.on("data",l(process.stderr)),n.on("message",p=>{if(p?.type==="member"){const S=d.get(p.member);S&&R(S.proc,p.event)}}),n.on("exit",(p,S)=>{if(e===n&&(e=void 0),m||o.stopped())return;const w=Date.now();if(a=[...a.filter(b=>w-b<CRASH_WINDOW_MS),w],a.length>=exports.HOST_MAX_RESTARTS){c=`the build host exited ${a.length} times in a minute (last: ${p??S})`,f(`[gateway] ${c} \u2014 every service compiles on its own from now on`);for(const b of d.values())R(b.proc,{type:"refused",reason:c});d.clear();return}if(d.size!==0&&(f(`[gateway] build host exited (${p??S}) \u2014 restarting it for ${d.size} service tree(s)`),k()))for(const[b,{join:H}]of d)E({type:"join",member:b,join:H})}),n},"start"),x=i(r=>{const s=g.get(r);!s||d.get(s)?.proc!==r||(d.delete(s),E({type:"leave",member:s}))},"detach");return{offered:i(()=>!!u&&!c,"offered"),attach:i((r,s)=>{g.set(s,r),s.on("message",n=>{if((0,protocol_1.isRunnerJoinMessage)(n)){if(c||!k()){R(s,{type:"refused",reason:c??"the build host could not be started"});return}d.set(r,{proc:s,join:n.join}),E({type:"join",member:r,join:n.join})}}),s.once("exit",()=>x(s))},"attach"),detach:x,hostPid:i(()=>e?.pid,"hostPid"),stop(){m=!0,d.clear();const r=e;return e=void 0,!r||r.exitCode!==null||r.signalCode!==null?Promise.resolve():new Promise(s=>{const n=i(()=>{clearTimeout(l),s()},"done");r.once("exit",n);try{process.kill(-r.pid,"SIGTERM")}catch{try{r.kill("SIGTERM")}catch{}}const l=setTimeout(()=>{try{process.kill(-r.pid,"SIGKILL")}catch{try{r.kill("SIGKILL")}catch{}}s()},6e3);l.unref?.()})}}}v(createWorkspaceRelay,"createWorkspaceRelay"),y(createWorkspaceRelay,"createWorkspaceRelay"),i(createWorkspaceRelay,"createWorkspaceRelay");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var C=Object.defineProperty;var g=(e,t)=>C(e,"name",{value:t,configurable:!0});var U=Object.defineProperty,u=g((e,t)=>U(e,"name",{value:t,configurable:!0}),"u");Object.defineProperty(exports,"__esModule",{value:!0}),exports.sourceSame=exports.sourceFull=exports.sourceStaleAfterMs=exports.SOURCE_BACKOFF_MAX_MS=exports.SOURCE_DECLARATION_REPORT_MS=exports.SOURCE_NOT_RUNNING_REPORT_MS=exports.SOURCE_MAX_PER_SERVICE=exports.SOURCE_MAX_GROUPS=exports.SOURCE_MAX_BYTES=exports.SOURCE_ERROR_MAX=exports.LOOP_MAX_INTERVAL_SEC=exports.SOURCE_FULL_REPORT_MS=exports.TRAFFIC_DEFAULT_RATE_LIMITED=exports.TRAFFIC_DEFAULT_P95_MS=exports.TRAFFIC_DEFAULT_FAILURE_PCT=exports.STORE_DEFAULT_ORPHAN_MIN=exports.STORE_DEFAULT_ERROR_RATE_PCT=exports.STORE_DEFAULT_QUOTA_PCT=exports.LOOP_DEFAULT_IDLE_MIN=exports.QUEUE_DEFAULT_STALLED_MIN=exports.QUEUE_DEFAULT_OLDEST_WAIT_MIN=exports.SOURCE_MIN_INTERVAL_SEC=exports.SOURCE_DEFAULT_INTERVAL_SEC=exports.TRAFFIC_DIRECTIONS=exports.LOOP_OUTCOMES=exports.SOURCE_SNAPSHOT_FIELD=exports.TRAFFIC_WIRE_SCHEMA=exports.STORE_WIRE_SCHEMA=exports.LOOP_WIRE_SCHEMA=exports.QUEUE_WIRE_SCHEMA=exports.SOURCE_KINDS_READ=exports.SOURCE_KINDS=exports.sourcesConcurrency=exports.sourcesTimeoutMs=exports.sourcesEnabled=void 0,exports.sourceBackoffMs=sourceBackoffMs,exports.parseSourceDecls=parseSourceDecls,exports.parseQueueSnapshot=parseQueueSnapshot,exports.parseLoopSnapshot=parseLoopSnapshot,exports.parseStoreSnapshot=parseStoreSnapshot,exports.parseTrafficSnapshot=parseTrafficSnapshot,exports.sourceDigest=sourceDigest,exports.keepQueueSnapshot=keepQueueSnapshot,exports.keepLoopSnapshot=keepLoopSnapshot,exports.keepStoreSnapshot=keepStoreSnapshot,exports.keepTrafficSnapshot=keepTrafficSnapshot,exports.buildSourcePollRaw=buildSourcePollRaw,exports.buildSourceDeclarationRaw=buildSourceDeclarationRaw,exports.sourcePollTitle=sourcePollTitle,exports.requestOverSocket=requestOverSocket,exports.createSourcePoller=createSourcePoller;const tslib_1=require("tslib"),node_crypto_1=require("node:crypto"),http=tslib_1.__importStar(require("node:http")),discovery_1=require("./discovery"),readEnv=u(e=>process.env[e],"readEnv"),envInt=u((e,t,o)=>{const n=Number(readEnv(e));return Number.isInteger(n)&&n>=o?n:t},"envInt"),sourcesEnabled=u(()=>readEnv("LENSMCP_SOURCES")!=="0","sourcesEnabled");exports.sourcesEnabled=sourcesEnabled;const sourcesTimeoutMs=u(()=>envInt("LENSMCP_SOURCES_TIMEOUT_MS",3e3,100),"sourcesTimeoutMs");exports.sourcesTimeoutMs=sourcesTimeoutMs;const sourcesConcurrency=u(()=>envInt("LENSMCP_SOURCES_CONCURRENCY",4,1),"sourcesConcurrency");exports.sourcesConcurrency=sourcesConcurrency,exports.SOURCE_KINDS=["queue","loop","store","traffic"],exports.SOURCE_KINDS_READ=["queue","loop","store","traffic"],exports.QUEUE_WIRE_SCHEMA="lensmcp.queue/v1",exports.LOOP_WIRE_SCHEMA="lensmcp.loop/v1",exports.STORE_WIRE_SCHEMA="lensmcp.store/v1",exports.TRAFFIC_WIRE_SCHEMA="lensmcp.traffic/v1",exports.SOURCE_SNAPSHOT_FIELD={queue:"snapshot",loop:"loop",store:"store",traffic:"traffic"},exports.LOOP_OUTCOMES=["ok","failed","skipped"],exports.TRAFFIC_DIRECTIONS=["inbound","outbound"],exports.SOURCE_DEFAULT_INTERVAL_SEC=10,exports.SOURCE_MIN_INTERVAL_SEC=2,exports.QUEUE_DEFAULT_OLDEST_WAIT_MIN=10,exports.QUEUE_DEFAULT_STALLED_MIN=15,exports.LOOP_DEFAULT_IDLE_MIN=10,exports.STORE_DEFAULT_QUOTA_PCT=90,exports.STORE_DEFAULT_ERROR_RATE_PCT=5,exports.STORE_DEFAULT_ORPHAN_MIN=60,exports.TRAFFIC_DEFAULT_FAILURE_PCT=5,exports.TRAFFIC_DEFAULT_P95_MS=2e3,exports.TRAFFIC_DEFAULT_RATE_LIMITED=1,exports.SOURCE_FULL_REPORT_MS=6e4,exports.LOOP_MAX_INTERVAL_SEC=86400,exports.SOURCE_ERROR_MAX=500,exports.SOURCE_MAX_BYTES=256*1024,exports.SOURCE_MAX_GROUPS=500,exports.SOURCE_MAX_PER_SERVICE=16,exports.SOURCE_NOT_RUNNING_REPORT_MS=6e4,exports.SOURCE_DECLARATION_REPORT_MS=5*6e4,exports.SOURCE_BACKOFF_MAX_MS=6e4;const sourceStaleAfterMs=u(e=>Math.max(3e4,3*Math.max(0,e)),"sourceStaleAfterMs");exports.sourceStaleAfterMs=sourceStaleAfterMs;function sourceBackoffMs(e,t){return t<=1?e:Math.min(e*2**Math.min(t-1,10),Math.max(e,exports.SOURCE_BACKOFF_MAX_MS))}g(sourceBackoffMs,"sourceBackoffMs"),u(sourceBackoffMs,"sourceBackoffMs");const isPolled=u(e=>e.path!==void 0,"isPolled"),ENTRY_KEYS={queue:["kind","name","path","intervalSec","thresholds"],loop:["kind","name","path","intervalSec","thresholds","feeds"],store:["kind","name","path","intervalSec","thresholds"],traffic:["kind","name","path","intervalSec","thresholds"]},finite=u(e=>typeof e=="number"&&Number.isFinite(e),"finite"),MINUTES={ok:u(e=>finite(e)&&e>0&&e<=10080,"ok"),must:"must be minutes, more than 0 and at most 10080"},PERCENT={ok:u(e=>finite(e)&&e>0&&e<=100,"ok"),must:"must be a percent, more than 0 and at most 100"},MILLISECONDS={ok:u(e=>finite(e)&&e>0&&e<=6e5,"ok"),must:"must be milliseconds, more than 0 and at most 600000"},COUNT={ok:u(e=>Number.isInteger(e)&&e>=1&&e<=1e6,"ok"),must:"must be a count, a whole number from 1 to 1000000"},THRESHOLDS={queue:{oldestWaitMin:{def:exports.QUEUE_DEFAULT_OLDEST_WAIT_MIN,...MINUTES},stalledMin:{def:exports.QUEUE_DEFAULT_STALLED_MIN,...MINUTES}},loop:{idleMin:{def:exports.LOOP_DEFAULT_IDLE_MIN,...MINUTES}},store:{quotaPct:{def:exports.STORE_DEFAULT_QUOTA_PCT,...PERCENT},errorRatePct:{def:exports.STORE_DEFAULT_ERROR_RATE_PCT,...PERCENT},orphanMin:{def:exports.STORE_DEFAULT_ORPHAN_MIN,...MINUTES}},traffic:{failurePct:{def:exports.TRAFFIC_DEFAULT_FAILURE_PCT,...PERCENT},p95Ms:{def:exports.TRAFFIC_DEFAULT_P95_MS,...MILLISECONDS},rateLimited:{def:exports.TRAFFIC_DEFAULT_RATE_LIMITED,...COUNT}}},PATH_RE=/^\/(?!\/)[^\s#\u0000-\u001f\u007f]{0,511}$/,NAME_RE=/^[^\u0000-\u001f\u007f]{1,100}$/,isObj=u(e=>typeof e=="object"&&e!==null&&!Array.isArray(e),"isObj");function parseSourceDecls(e){const t=[],o=[],n=[];if(e===void 0)return{sources:t,problems:o};if(!Array.isArray(e))return{sources:t,problems:["`sources` is not a list of { kind, name, path } entries \u2014 no source is read"]};e.forEach((i,l)=>{const E=`sources[${l}]`;if(!isObj(i)){o.push(`${E} is not an object \u2014 not read`);return}const d=typeof i.name=="string"&&i.name.trim()?`${E} "${i.name}"`:E,r=i.kind;if(typeof r!="string"||!exports.SOURCE_KINDS_READ.includes(r)){o.push(`${d}: kind ${JSON.stringify(r??null)} is not a source kind (${exports.SOURCE_KINDS.join(", ")}) \u2014 not read`);return}const a=r,p=Object.keys(i).filter(_=>!ENTRY_KEYS[a].includes(_));if(p.length){o.push(`${d}: unknown key${p.length===1?"":"s"} ${p.map(_=>JSON.stringify(_)).join(", ")} for a ${a} source (known: ${ENTRY_KEYS[a].join(", ")}) \u2014 not read`);return}const R=i.name;if(typeof R!="string"||!R.trim()||!NAME_RE.test(R)){o.push(`${E}: name ${JSON.stringify(R??null)} must be 1\u2013100 characters, not blank \u2014 not read`);return}if(t.some(_=>_.name===R)){o.push(`${d}: the name is declared twice on this service \u2014 read once`);return}const h=i.path;if(h===void 0&&a!=="traffic"&&a!=="loop"){o.push(`${d}: a ${a} source needs a path \u2014 the route on the service that answers "lensmcp.${a}/v1" (only a loop or a traffic source may go without one, as push-only) \u2014 not read`);return}if(h!==void 0&&(typeof h!="string"||!PATH_RE.test(h)||h.split("?")[0].split("/").includes(".."))){o.push(`${d}: path ${JSON.stringify(h)} must be a route on the service, starting with "/" (e.g. "/api/dev/lens/backlog") \u2014 not read`);return}const m=i.intervalSec;if(m!==void 0&&!(typeof m=="number"&&Number.isInteger(m)&&m>=exports.SOURCE_MIN_INTERVAL_SEC&&m<=3600)){o.push(`${d}: intervalSec ${JSON.stringify(m)} must be a whole number of seconds from ${exports.SOURCE_MIN_INTERVAL_SEC} to 3600 \u2014 not read`);return}const A=i.thresholds;if(A!==void 0&&!isObj(A)){o.push(`${d}: thresholds must be an object \u2014 not read`);return}const b=isObj(A)?A:{},I=THRESHOLDS[a],s=Object.keys(I),c=Object.keys(b).filter(_=>!s.includes(_));if(c.length){o.push(`${d}: unknown threshold${c.length===1?"":"s"} ${c.map(_=>JSON.stringify(_)).join(", ")} for a ${a} source (known: ${s.join(", ")}) \u2014 not read`);return}const f=s.find(_=>b[_]!==void 0&&!I[_].ok(b[_]));if(f){o.push(`${d}: thresholds.${f} ${JSON.stringify(b[f])} ${I[f].must} \u2014 not read`);return}if(t.length>=exports.SOURCE_MAX_PER_SERVICE){o.push(`${d}: more than ${exports.SOURCE_MAX_PER_SERVICE} sources on one service \u2014 not read`);return}const O={};for(const _ of s)O[_]=b[_]??I[_].def;const S={kind:a,name:R,...h!==void 0?{path:h}:{},intervalSec:m??exports.SOURCE_DEFAULT_INTERVAL_SEC,thresholds:O};t.push(S),a==="loop"&&i.feeds!==void 0&&n.push({decl:S,label:d,feeds:i.feeds})});for(const{decl:i,label:l,feeds:E}of n)typeof E!="string"||!E.trim()?o.push(`${l}: feeds ${JSON.stringify(E)} must be the name of a queue source on this service \u2014 read without it`):t.some(d=>d.kind==="queue"&&d.name===E)?i.feeds=E:o.push(`${l}: feeds ${JSON.stringify(E)} names no queue source on this service \u2014 read without it`);return{sources:t,problems:o}}g(parseSourceDecls,"parseSourceDecls"),u(parseSourceDecls,"parseSourceDecls");const ISO_RE=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?(?:Z|[+-]\d{2}:?\d{2})$/,isIso=u(e=>typeof e=="string"&&ISO_RE.test(e)&&!Number.isNaN(Date.parse(e)),"isIso"),isCount=u(e=>typeof e=="number"&&Number.isSafeInteger(e)&&e>=0,"isCount"),notSchema=u((e,t)=>`schema is ${e===void 0?"absent":JSON.stringify(e).slice(0,60)}, not "${t}"`,"notSchema"),keyWrong=u((e,t,o)=>{if(typeof e!="string"||e.length===0||e.length>200)return`${t}.key must be a string of 1\u2013200 characters`;if(o.has(e))return`${t}.key ${JSON.stringify(e)} appears twice`;o.add(e)},"keyWrong"),labelsWrong=u((e,t)=>{if(e===void 0)return;if(!isObj(e))return`${t}.labels must be an object of strings`;const o=Object.entries(e);if(o.length>16)return`${t}.labels has more than 16 entries`;for(const[n,i]of o)if(n.length===0||n.length>64||typeof i!="string"||i.length>200)return`${t}.labels.${n.slice(0,64)} must be a string of at most 200 characters`},"labelsWrong"),overCap=u((e,t)=>`${e} ${t} \u2014 at most ${exports.SOURCE_MAX_GROUPS}; cap them and say \`truncated: { ${t}: <dropped> }\``,"overCap");function parseQueueSnapshot(e){const t=u(d=>({ok:!1,reason:d}),"fail");if(!isObj(e))return t("the snapshot is not a JSON object");if(e.schema!==exports.QUEUE_WIRE_SCHEMA)return t(notSchema(e.schema,exports.QUEUE_WIRE_SCHEMA));const o=e.at;if(!isIso(o))return t("`at` is not an ISO time");const n=e.truncated;if(n!==void 0&&!(isObj(n)&&isCount(n.groups)))return t("`truncated` must be { groups: <how many were dropped> }, or absent");const i=e.groups;if(!Array.isArray(i))return t("`groups` is not a list");if(i.length>exports.SOURCE_MAX_GROUPS)return t(overCap(i.length,"groups"));const l=new Set,E=[];for(let d=0;d<i.length;d++){const r=i[d],a=`groups[${d}]`;if(!isObj(r))return t(`${a} is not an object`);const p=keyWrong(r.key,a,l);if(p)return t(p);if(!isCount(r.pending))return t(`${a}.pending must be a whole number \u2265 0`);for(const A of["inFlight","failed","completedInWindow"])if(r[A]!==void 0&&!isCount(r[A]))return t(`${a}.${A} must be a whole number \u2265 0, or absent`);const R=r.oldestPendingAt;if(R!=null&&!isIso(R))return t(`${a}.oldestPendingAt must be an ISO time, null, or absent`);const h=r.labels,m=labelsWrong(h,a);if(m)return t(m);E.push({key:r.key,...h!==void 0?{labels:h}:{},pending:r.pending,...r.inFlight!==void 0?{inFlight:r.inFlight}:{},...r.failed!==void 0?{failed:r.failed}:{},...R!==void 0?{oldestPendingAt:R}:{},...r.completedInWindow!==void 0?{completedInWindow:r.completedInWindow}:{}})}return{ok:!0,at:o,groups:E,...n!==void 0?{truncated:{groups:n.groups}}:{}}}g(parseQueueSnapshot,"parseQueueSnapshot"),u(parseQueueSnapshot,"parseQueueSnapshot");const LOOP_COUNTS=["lastDurationMs","lastItems","runsInWindow","itemsInWindow","failuresInWindow","windowSec"],cutText=u((e,t)=>{if(e.length<=t)return e;const o=t-1,n=e.charCodeAt(o-1);return`${e.slice(0,n>=55296&&n<=56319?o-1:o)}\u2026`},"cutText");function parseLoopSnapshot(e){const t=u(a=>({ok:!1,reason:a}),"fail");if(!isObj(e))return t("the snapshot is not a JSON object");if(e.schema!==exports.LOOP_WIRE_SCHEMA)return t(notSchema(e.schema,exports.LOOP_WIRE_SCHEMA));const o=e.at;if(!isIso(o))return t("`at` is not an ISO time");const n=e.intervalSec;if(!(typeof n=="number"&&Number.isFinite(n)&&n>0&&n<=exports.LOOP_MAX_INTERVAL_SEC))return t(`\`intervalSec\` must be the loop's own period in seconds, more than 0 and at most ${exports.LOOP_MAX_INTERVAL_SEC}`);const i=e.lastRunAt;if(i===void 0)return t("`lastRunAt` is absent \u2014 say null if the loop has not run since the service started");if(i!==null&&!isIso(i))return t("`lastRunAt` must be an ISO time, or null if the loop has not run since the service started");for(const a of LOOP_COUNTS)if(e[a]!==void 0&&!isCount(e[a]))return t(`\`${a}\` must be a whole number \u2265 0, or absent`);const l=e.lastOutcome;if(l!==void 0&&!exports.LOOP_OUTCOMES.includes(l))return t(`\`lastOutcome\` must be ${exports.LOOP_OUTCOMES.join(", ")}, or absent`);const E=e.nextRunAt;if(E!=null&&!isIso(E))return t("`nextRunAt` must be an ISO time, null, or absent");const d=e.lastError;if(d!==void 0&&typeof d!="string")return t("`lastError` must be a string, or absent");const r=u(a=>e[a]!==void 0?{[a]:e[a]}:{},"count");return{ok:!0,loop:{at:o,intervalSec:n,lastRunAt:i,...r("lastDurationMs"),...l!==void 0?{lastOutcome:l}:{},...r("lastItems"),...E!==void 0?{nextRunAt:E}:{},...r("runsInWindow"),...r("itemsInWindow"),...r("failuresInWindow"),...r("windowSec"),...d!==void 0?{lastError:cutText(d,exports.SOURCE_ERROR_MAX)}:{}}}}g(parseLoopSnapshot,"parseLoopSnapshot"),u(parseLoopSnapshot,"parseLoopSnapshot");const STORE_COUNTS=["opsInWindow","writesInWindow","deletesInWindow","errorsInWindow","windowSec"];function parseStoreSnapshot(e){const t=u(p=>({ok:!1,reason:p}),"fail");if(!isObj(e))return t("the snapshot is not a JSON object");if(e.schema!==exports.STORE_WIRE_SCHEMA)return t(notSchema(e.schema,exports.STORE_WIRE_SCHEMA));const o=e.at;if(!isIso(o))return t("`at` is not an ISO time");for(const p of["objects","bytes"])if(!isCount(e[p]))return t(`\`${p}\` must be a whole number \u2265 0`);const n=e.quotaBytes;if(n!=null&&!isCount(n))return t("`quotaBytes` must be a whole number \u2265 0, null when it has no quota, or absent");for(const p of STORE_COUNTS)if(e[p]!==void 0&&!isCount(e[p]))return t(`\`${p}\` must be a whole number \u2265 0, or absent`);const i=e.lastWriteAt;if(i!=null&&!isIso(i))return t("`lastWriteAt` must be an ISO time, null, or absent");const l=e.lastError;if(l!==void 0&&typeof l!="string")return t("`lastError` must be a string, or absent");const E=e.truncated;if(E!==void 0&&!(isObj(E)&&isCount(E.groups)))return t("`truncated` must be { groups: <how many were dropped> }, or absent");const d=e.groups;let r;if(d!==void 0){if(!Array.isArray(d))return t("`groups` must be a list, or absent");if(d.length>exports.SOURCE_MAX_GROUPS)return t(overCap(d.length,"groups"));const p=new Set;r=[];for(let R=0;R<d.length;R++){const h=d[R],m=`groups[${R}]`;if(!isObj(h))return t(`${m} is not an object`);const A=keyWrong(h.key,m,p);if(A)return t(A);for(const s of["objects","bytes"])if(!isCount(h[s]))return t(`${m}.${s} must be a whole number \u2265 0`);const b=h.labels,I=labelsWrong(b,m);if(I)return t(I);r.push({key:h.key,...b!==void 0?{labels:b}:{},objects:h.objects,bytes:h.bytes})}}const a=u(p=>e[p]!==void 0?{[p]:e[p]}:{},"count");return{ok:!0,store:{at:o,objects:e.objects,bytes:e.bytes,...n!==void 0?{quotaBytes:n}:{},...a("opsInWindow"),...a("writesInWindow"),...a("deletesInWindow"),...a("errorsInWindow"),...a("windowSec"),...i!==void 0?{lastWriteAt:i}:{},...l!==void 0?{lastError:cutText(l,exports.SOURCE_ERROR_MAX)}:{},...r?{groups:r}:{},...E!==void 0?{truncated:{groups:E.groups}}:{}}}}g(parseStoreSnapshot,"parseStoreSnapshot"),u(parseStoreSnapshot,"parseStoreSnapshot");const TRAFFIC_COUNTS=["messagesInWindow","failuresInWindow","rateLimitedInWindow"];function parseTrafficSnapshot(e){const t=u(r=>({ok:!1,reason:r}),"fail");if(!isObj(e))return t("the snapshot is not a JSON object");if(e.schema!==exports.TRAFFIC_WIRE_SCHEMA)return t(notSchema(e.schema,exports.TRAFFIC_WIRE_SCHEMA));const o=e.at;if(!isIso(o))return t("`at` is not an ISO time");const n=e.windowSec;if(n!==void 0&&!isCount(n))return t("`windowSec` must be a whole number \u2265 0, or absent");const i=e.truncated;if(i!==void 0&&!(isObj(i)&&isCount(i.channels)))return t("`truncated` must be { channels: <how many were dropped> }, or absent");const l=e.channels;if(!Array.isArray(l))return t("`channels` is not a list");if(l.length>exports.SOURCE_MAX_GROUPS)return t(overCap(l.length,"channels"));const E=new Set,d=[];for(let r=0;r<l.length;r++){const a=l[r],p=`channels[${r}]`;if(!isObj(a))return t(`${p} is not an object`);const R=keyWrong(a.key,p,E);if(R)return t(R);const h=a.direction;if(h!==void 0&&!exports.TRAFFIC_DIRECTIONS.includes(h))return t(`${p}.direction must be ${exports.TRAFFIC_DIRECTIONS.join(", ")}, or absent`);const m=a.counterpart;if(m!==void 0&&!(typeof m=="string"&&m.length>0&&m.length<=200))return t(`${p}.counterpart must be a string of 1\u2013200 characters, or absent`);for(const O of TRAFFIC_COUNTS)if(a[O]!==void 0&&!isCount(a[O]))return t(`${p}.${O} must be a whole number \u2265 0, or absent`);const A=a.p95Ms;if(A!==void 0&&!(finite(A)&&A>=0))return t(`${p}.p95Ms must be milliseconds \u2265 0, or absent`);const b=a.lastAt;if(b!=null&&!isIso(b))return t(`${p}.lastAt must be an ISO time, null, or absent`);const I=a.lastError;if(I!==void 0&&typeof I!="string")return t(`${p}.lastError must be a string, or absent`);const s=a.labels,c=labelsWrong(s,p);if(c)return t(c);const f=u(O=>a[O]!==void 0?{[O]:a[O]}:{},"count");d.push({key:a.key,...s!==void 0?{labels:s}:{},...h!==void 0?{direction:h}:{},...m!==void 0?{counterpart:m}:{},...f("messagesInWindow"),...f("failuresInWindow"),...f("rateLimitedInWindow"),...A!==void 0?{p95Ms:A}:{},...b!==void 0?{lastAt:b}:{},...I!==void 0?{lastError:cutText(I,exports.SOURCE_ERROR_MAX)}:{}})}return{ok:!0,traffic:{at:o,...n!==void 0?{windowSec:n}:{},channels:d,...i!==void 0?{truncated:{channels:i.channels}}:{}}}}g(parseTrafficSnapshot,"parseTrafficSnapshot"),u(parseTrafficSnapshot,"parseTrafficSnapshot");const sourceFull=u((e,t)=>({[exports.SOURCE_SNAPSHOT_FIELD[e]]:t}),"sourceFull");exports.sourceFull=sourceFull;const declRaw=u(e=>({sourceKind:e.kind,name:e.name,...e.path!==void 0?{path:e.path}:{},intervalSec:e.intervalSec,thresholds:{...e.thresholds},...e.feeds!==void 0?{feeds:e.feeds}:{}}),"declRaw"),canonical=u(e=>{if(Array.isArray(e))return e.map(canonical);if(!isObj(e))return e;const t={};for(const o of Object.keys(e).sort())t[o]=canonical(e[o]);return t},"canonical");function sourceDigest(e){return(0,node_crypto_1.createHash)("sha1").update(JSON.stringify(canonical(e))??"null").digest("hex").slice(0,16)}g(sourceDigest,"sourceDigest"),u(sourceDigest,"sourceDigest");const oldestOf=u(e=>e.pending>0&&e.oldestPendingAt?Date.parse(e.oldestPendingAt):Number.POSITIVE_INFINITY,"oldestOf");function keepQueueSnapshot(e,t,o,n){const i={groups:t.length,pending:0,inFlight:0,failed:0};let l;for(const r of t)i.pending+=r.pending,i.inFlight+=r.inFlight??0,i.failed+=r.failed??0,r.completedInWindow!==void 0&&(l=(l??0)+r.completedInWindow);l!==void 0&&(i.completedInWindow=l);const E=[...t].sort((r,a)=>oldestOf(r)-oldestOf(a)||a.pending-r.pending||(r.key<a.key?-1:r.key>a.key?1:0)).map(({key:r,...a})=>({group:r,...a})),d=n?{groups:n.groups}:void 0;return{at:e,receivedAt:o,totals:i,groups:E,...d?{truncated:d}:{},digest:sourceDigest({groups:E,truncated:d??null})}}g(keepQueueSnapshot,"keepQueueSnapshot"),u(keepQueueSnapshot,"keepQueueSnapshot");function keepLoopSnapshot(e,t){const{at:o,...n}=e;return{at:o,receivedAt:t,digest:sourceDigest(n),...n}}g(keepLoopSnapshot,"keepLoopSnapshot"),u(keepLoopSnapshot,"keepLoopSnapshot");const byKey=u((e,t)=>e<t?-1:e>t?1:0,"byKey");function keepStoreSnapshot(e,t){const{at:o,groups:n,truncated:i,...l}=e,E=n?[...n].sort((r,a)=>a.bytes-r.bytes||a.objects-r.objects||byKey(r.key,a.key)).map(({key:r,...a})=>({group:r,...a})):void 0,d={...l,...E?{groups:E}:{},...i?{truncated:{groups:i.groups}}:{}};return{at:o,receivedAt:t,digest:sourceDigest(d),...d}}g(keepStoreSnapshot,"keepStoreSnapshot"),u(keepStoreSnapshot,"keepStoreSnapshot");const messagesOf=u(e=>e.messagesInWindow??-1,"messagesOf");function keepTrafficSnapshot(e,t){const{at:o,channels:n,truncated:i,...l}=e,E=[...n].sort((r,a)=>messagesOf(a)-messagesOf(r)||byKey(r.key,a.key)).map(({key:r,...a})=>({channel:r,...a})),d={...l,channels:E,...i?{truncated:{channels:i.channels}}:{}};return{at:o,receivedAt:t,digest:sourceDigest(d),...d}}g(keepTrafficSnapshot,"keepTrafficSnapshot"),u(keepTrafficSnapshot,"keepTrafficSnapshot");const sourceSame=u(e=>({digest:e.digest,at:e.at,receivedAt:e.receivedAt}),"sourceSame");exports.sourceSame=sourceSame;function buildSourcePollRaw(e,t,o,n,i,l){return{kind:"source-poll",provenance:"reported",project:e,...declRaw(t),state:o.state,...o.detail!==void 0?{detail:o.detail}:{},...o.status!==void 0?{status:o.status}:{},polledAt:o.polledAt,...o.durationMs!==void 0?{durationMs:o.durationMs}:{},reportEveryMs:n,...i>0?{failures:i}:{},...l??{}}}g(buildSourcePollRaw,"buildSourcePollRaw"),u(buildSourcePollRaw,"buildSourcePollRaw");function buildSourceDeclarationRaw(e,t){return{kind:"source-declaration",project:e,sources:t.sources.map(declRaw),problems:[...t.problems]}}g(buildSourceDeclarationRaw,"buildSourceDeclarationRaw"),u(buildSourceDeclarationRaw,"buildSourceDeclarationRaw");const span=u(e=>{const t=Math.round(e/6e4);return e<6e4?`${Math.max(0,Math.round(e/1e3))}s`:t<120?`${t}m`:`${Math.floor(t/60)}h${t%60?` ${t%60}m`:""}`},"span"),loopWords=u(e=>`${e.lastRunAt===null?"has not run since the service started":`last run ${span(Math.max(0,Date.parse(e.at)-Date.parse(e.lastRunAt)))} before it was measured`}${e.lastOutcome?`, ${e.lastOutcome}`:""}${e.lastItems!==void 0?`, ${e.lastItems} item${e.lastItems===1?"":"s"}`:""}`,"loopWords"),plural=u((e,t)=>`${e} ${t}${e===1?"":"s"}`,"plural"),byteSize=u(e=>{const t=["B","kB","MB","GB","TB","PB"];let o=e,n=0;for(;o>=999.5&&n<t.length-1;)o/=1e3,n+=1;return n===0?`${e} B`:`${o<9.95?o.toFixed(1):Math.round(o)} ${t[n]}`},"byteSize"),storeWords=u(e=>{const t=typeof e.quotaBytes=="number"&&e.quotaBytes>0?` of ${byteSize(e.quotaBytes)} (${Math.round(e.bytes/e.quotaBytes*1e3)/10}%)`:"",o=e.errorsInWindow?`, ${plural(e.errorsInWindow,"error")}${e.windowSec?` in ${span(e.windowSec*1e3)}`:""}`:"";return`${plural(e.objects,"object")}, ${byteSize(e.bytes)}${t}${o}`},"storeWords"),trafficWords=u(e=>{let t,o=0,n=0;for(const l of e.channels)l.messagesInWindow!==void 0&&(t=(t??0)+l.messagesInWindow),o+=l.failuresInWindow??0,n+=l.rateLimitedInWindow??0;const i=t!==void 0?`, ${plural(t,"message")}${e.windowSec?` in ${span(e.windowSec*1e3)}`:""}`:"";return`${plural(e.channels.length,"channel")}${i}${o?`, ${o} failed`:""}${n?`, ${n} rate-limited`:""}`},"trafficWords");function sourcePollTitle(e,t){const o=`${e.sourceKind} ${e.project}/${e.name} (reported)`,n=t??e[exports.SOURCE_SNAPSHOT_FIELD[e.sourceKind]];if(e.state!=="current"||!n)return`${o}: ${e.state}${e.detail?` \u2014 ${e.detail}`:""}`;if(e.sourceKind==="loop")return`${o}: ${loopWords(n)}`;if(e.sourceKind==="store")return`${o}: ${storeWords(n)}`;if(e.sourceKind==="traffic")return`${o}: ${trafficWords(n)}`;const i=n,l=i.groups.find(d=>d.pending>0&&d.oldestPendingAt),E=l?.oldestPendingAt?Date.parse(i.at)-Date.parse(l.oldestPendingAt):void 0;return`${o}: ${i.totals.pending} pending in ${i.totals.groups} group${i.totals.groups===1?"":"s"}${E!==void 0?`, oldest waiting ${span(Math.max(0,E))}`:""}`}g(sourcePollTitle,"sourcePollTitle"),u(sourcePollTitle,"sourcePollTitle");function requestOverSocket(e,t,o,n,i=exports.SOURCE_MAX_BYTES){return new Promise(l=>{let E=!1,d;const r=u(p=>{E||(E=!0,clearTimeout(a),l(p))},"finish"),a=setTimeout(()=>{r({ok:!1,code:"ETIMEDOUT",message:`no answer within ${n} ms`}),d?.destroy()},n);a.unref?.();try{d=http.request({socketPath:e,path:t,method:"GET",agent:!1,headers:o},p=>{const R=[];let h=0;p.on("data",m=>{if(!E){if(h+=m.length,h>i){r({ok:!0,status:p.statusCode??0,body:"",truncated:!0}),p.destroy();return}R.push(m)}}),p.on("end",()=>r({ok:!0,status:p.statusCode??0,body:Buffer.concat(R).toString("utf8"),truncated:!1})),p.on("error",m=>r({ok:!1,code:m.code??"ERESPONSE",message:m.message}))}),d.on("error",p=>r({ok:!1,code:p.code??"EREQUEST",message:p.message})),d.end()}catch(p){r({ok:!1,code:p.code??"EREQUEST",message:p.message})}})}g(requestOverSocket,"requestOverSocket"),u(requestOverSocket,"requestOverSocket");const snippet=u(e=>e.replace(/\s+/g," ").trim().slice(0,160),"snippet");function readSnapshot(e,t,o){let n;try{n=JSON.parse(t)}catch{return{ok:!1,reason:`not JSON: ${snippet(t)||"(an empty body)"}`}}if(e==="loop"){const l=parseLoopSnapshot(n);return l.ok===!0?{ok:!0,kept:keepLoopSnapshot(l.loop,o)}:l}if(e==="store"){const l=parseStoreSnapshot(n);return l.ok===!0?{ok:!0,kept:keepStoreSnapshot(l.store,o)}:l}if(e==="traffic"){const l=parseTrafficSnapshot(n);return l.ok===!0?{ok:!0,kept:keepTrafficSnapshot(l.traffic,o)}:l}const i=parseQueueSnapshot(n);return i.ok===!0?{ok:!0,kept:keepQueueSnapshot(i.at,i.groups,o,i.truncated)}:i}g(readSnapshot,"readSnapshot"),u(readSnapshot,"readSnapshot");function createSourcePoller(e){const t=e.now??Date.now,o=e.timeoutMs??(0,exports.sourcesTimeoutMs)(),n=Math.max(1,e.maxConcurrent??(0,exports.sourcesConcurrency)()),i=e.socketOf??(s=>(0,discovery_1.pickSock)(s.pool,e.scanTtlMs??1500)),l=e.request??requestOverSocket,E=e.log??(s=>console.warn(s)),d=new WeakMap,r=new Map;let a=0,p;const R=u(s=>{const c=s.decl;let f=d.get(c);if(!f){f=parseSourceDecls(s.decl.sources),d.set(c,f);for(const S of f.problems)E(`[gateway] ${s.project}: cluster.sources \u2014 ${S}`)}const O=t();return(f.reportedAt===void 0||O-f.reportedAt>=exports.SOURCE_DECLARATION_REPORT_MS)&&(f.reportedAt=O,e.emit(s,f.problems.length?"warning":"info",f.problems.length?`sources ${s.project}: ${f.problems.length} cluster.sources entr${f.problems.length===1?"y":"ies"} not read \u2014 ${f.problems[0]}`:`sources ${s.project}: reads ${f.sources.map(S=>`${S.kind} "${S.name}"${isPolled(S)?"":" (push-only)"}`).join(", ")}`,`source-declaration:${s.wsKey}:${s.project}`,buildSourceDeclarationRaw(s.project,f))),f},"declarationOf"),h=u(s=>{if(s.state==="starting")return{notRunning:"it is starting \u2014 read once it is up"};const c=i(s);return c?{socket:c}:{notRunning:s.state==="up"?"it has no live pod socket \u2014 no pod runs it now":"it is scaled to zero \u2014 the lens does not start a service to read a source"}},"reach"),m=u((s,c)=>{const f=s.good;if(f)return s.full&&s.full.digest===f.digest&&c-s.full.at<exports.SOURCE_FULL_REPORT_MS?{same:(0,exports.sourceSame)(f)}:(s.full={digest:f.digest,at:c},(0,exports.sourceFull)(s.decl.kind,f))},"carried"),A=u((s,c)=>{const f=s.last;if(!f)return;const O=t();if(!c&&s.reportedAt!==void 0&&O-s.reportedAt<s.reportEveryMs)return;s.reportedAt=O;const S=buildSourcePollRaw(s.svc.project,s.decl,f,s.reportEveryMs,s.failures,m(s,O)),_=f.state==="unreachable"||f.state==="refused"||f.state==="malformed";e.emit(s.svc,_?"warning":"info",sourcePollTitle(S,s.good),`source:${s.svc.wsKey}:${s.svc.project}:${s.decl.name}`,S)},"report"),b=u(async s=>{const c=t(),f=s.decl.intervalSec*1e3;s.inFlight=!0,a+=1;const O=s.last?.state;try{const S=h(s.svc);if("notRunning"in S){s.last={state:"not-running",detail:S.notRunning,polledAt:c},s.failures=0,s.nextAt=c+f,s.reportEveryMs=exports.SOURCE_NOT_RUNNING_REPORT_MS,A(s,O!=="not-running");return}const _=e.serviceKey(s.svc),T=await l(S.socket,s.decl.path,{accept:"application/json","x-lensmcp-probe":`source:${s.decl.kind}`,..._?{"x-internal-token":_}:{}},o,exports.SOURCE_MAX_BYTES),x=Math.max(0,t()-c);if(T.ok===!1){const $=T.code==="ECONNREFUSED"||T.code==="ENOENT";s.last=$&&s.svc.state!=="up"?{state:"not-running",detail:`nothing listens on its pod socket \u2014 the service is ${s.svc.state}`,polledAt:c,durationMs:x}:{state:"unreachable",detail:T.code==="ETIMEDOUT"?T.message:`${T.code}: ${snippet(T.message)}`,polledAt:c,durationMs:x}}else if(T.status<200||T.status>299){const $=snippet(T.body);s.last={state:"refused",status:T.status,detail:`HTTP ${T.status}${$?`: ${$}`:""}`,polledAt:c,durationMs:x}}else if(T.truncated)s.last={state:"malformed",detail:`the snapshot is larger than ${exports.SOURCE_MAX_BYTES/1024} KiB`,polledAt:c,durationMs:x};else{const $=readSnapshot(s.decl.kind,T.body,t());$.ok===!0?(s.good=$.kept,s.last={state:"current",polledAt:c,durationMs:x}):s.last={state:"malformed",detail:$.reason,polledAt:c,durationMs:x}}const v=s.last.state==="unreachable"||s.last.state==="refused"||s.last.state==="malformed";s.failures=v?s.failures+1:0;const M=v?sourceBackoffMs(f,s.failures):f;s.nextAt=c+M,s.reportEveryMs=s.last.state==="not-running"?exports.SOURCE_NOT_RUNNING_REPORT_MS:M,A(s,s.last.state!=="not-running"||O!=="not-running")}catch(S){s.last={state:"unreachable",detail:`the poll failed: ${snippet(S?.message??String(S))}`,polledAt:c},s.failures+=1,s.nextAt=c+sourceBackoffMs(f,s.failures),s.reportEveryMs=s.nextAt-c,A(s,!0)}finally{s.inFlight=!1,a-=1}},"pollOne"),I=u(async()=>{if(e.stopped?.())return;const s=new Set;for(const S of e.services())if(S.decl.sources!==void 0)for(const _ of R(S).sources){if(!isPolled(_))continue;const T=`${S.wsKey} ${S.project} ${_.kind} ${_.name}`;s.add(T);const x=r.get(T);x?(x.svc!==S||x.decl!==_)&&(x.svc=S,x.decl=_):r.set(T,{svc:S,decl:_,nextAt:0,inFlight:!1,failures:0,reportEveryMs:_.intervalSec*1e3})}for(const[S,_]of[...r.entries()])!s.has(S)&&!_.inFlight&&r.delete(S);const c=t(),f=[...r.values()].filter(S=>!S.inFlight&&c>=S.nextAt).sort((S,_)=>S.nextAt-_.nextAt),O=[];for(const S of f){if(a>=n)break;O.push(b(S))}await Promise.all(O)},"tick");return{tick:I,start(s=1e3){return p&&clearInterval(p),p=setInterval(()=>{I().catch(c=>console.error("[gateway] source poll error:",c))},s),p.unref(),p},stop(){p&&clearInterval(p),p=void 0},snapshot(){const s=t();return[...r.values()].map(c=>{const f=c.last!==void 0&&s-c.last.polledAt>(0,exports.sourceStaleAfterMs)(c.reportEveryMs);return{wsKey:c.svc.wsKey,project:c.svc.project,name:c.decl.name,kind:c.decl.kind,path:c.decl.path,state:c.last?f?"stale":c.last.state:"never-polled",...c.last?.detail!==void 0?{detail:c.last.detail}:{},...c.last?.status!==void 0?{status:c.last.status}:{},...c.last?{polledAt:c.last.polledAt}:{},failures:c.failures,nextAt:c.nextAt,...c.good?{...(0,exports.sourceFull)(c.decl.kind,c.good),ageMs:Math.max(0,s-c.good.receivedAt)}:{}}})}}}g(createSourcePoller,"createSourcePoller"),u(createSourcePoller,"createSourcePoller");
|
|
1
|
+
"use strict";var k=Object.defineProperty;var b=(e,t)=>k(e,"name",{value:t,configurable:!0});var C=Object.defineProperty,g=b((e,t)=>C(e,"name",{value:t,configurable:!0}),"g"),U=Object.defineProperty,u=g((e,t)=>U(e,"name",{value:t,configurable:!0}),"u");Object.defineProperty(exports,"__esModule",{value:!0}),exports.sourceSame=exports.sourceFull=exports.sourceStaleAfterMs=exports.SOURCE_BACKOFF_MAX_MS=exports.SOURCE_DECLARATION_REPORT_MS=exports.SOURCE_NOT_RUNNING_REPORT_MS=exports.SOURCE_MAX_PER_SERVICE=exports.SOURCE_MAX_GROUPS=exports.SOURCE_MAX_BYTES=exports.SOURCE_ERROR_MAX=exports.LOOP_MAX_INTERVAL_SEC=exports.SOURCE_FULL_REPORT_MS=exports.TRAFFIC_DEFAULT_RATE_LIMITED=exports.TRAFFIC_DEFAULT_P95_MS=exports.TRAFFIC_DEFAULT_FAILURE_PCT=exports.STORE_DEFAULT_ORPHAN_MIN=exports.STORE_DEFAULT_ERROR_RATE_PCT=exports.STORE_DEFAULT_QUOTA_PCT=exports.LOOP_DEFAULT_IDLE_MIN=exports.QUEUE_DEFAULT_STALLED_MIN=exports.QUEUE_DEFAULT_OLDEST_WAIT_MIN=exports.SOURCE_MIN_INTERVAL_SEC=exports.SOURCE_DEFAULT_INTERVAL_SEC=exports.TRAFFIC_DIRECTIONS=exports.LOOP_OUTCOMES=exports.SOURCE_SNAPSHOT_FIELD=exports.TRAFFIC_WIRE_SCHEMA=exports.STORE_WIRE_SCHEMA=exports.LOOP_WIRE_SCHEMA=exports.QUEUE_WIRE_SCHEMA=exports.SOURCE_KINDS_READ=exports.SOURCE_KINDS=exports.sourcesConcurrency=exports.sourcesTimeoutMs=exports.sourcesEnabled=void 0,exports.sourceBackoffMs=sourceBackoffMs,exports.parseSourceDecls=parseSourceDecls,exports.parseQueueSnapshot=parseQueueSnapshot,exports.parseLoopSnapshot=parseLoopSnapshot,exports.parseStoreSnapshot=parseStoreSnapshot,exports.parseTrafficSnapshot=parseTrafficSnapshot,exports.sourceDigest=sourceDigest,exports.keepQueueSnapshot=keepQueueSnapshot,exports.keepLoopSnapshot=keepLoopSnapshot,exports.keepStoreSnapshot=keepStoreSnapshot,exports.keepTrafficSnapshot=keepTrafficSnapshot,exports.buildSourcePollRaw=buildSourcePollRaw,exports.buildSourceDeclarationRaw=buildSourceDeclarationRaw,exports.sourcePollTitle=sourcePollTitle,exports.requestOverSocket=requestOverSocket,exports.createSourcePoller=createSourcePoller;const tslib_1=require("tslib"),node_crypto_1=require("node:crypto"),http=tslib_1.__importStar(require("node:http")),discovery_1=require("./discovery"),readEnv=u(e=>process.env[e],"readEnv"),envInt=u((e,t,s)=>{const n=Number(readEnv(e));return Number.isInteger(n)&&n>=s?n:t},"envInt"),sourcesEnabled=u(()=>readEnv("LENSMCP_SOURCES")!=="0","sourcesEnabled");exports.sourcesEnabled=sourcesEnabled;const sourcesTimeoutMs=u(()=>envInt("LENSMCP_SOURCES_TIMEOUT_MS",3e3,100),"sourcesTimeoutMs");exports.sourcesTimeoutMs=sourcesTimeoutMs;const sourcesConcurrency=u(()=>envInt("LENSMCP_SOURCES_CONCURRENCY",4,1),"sourcesConcurrency");exports.sourcesConcurrency=sourcesConcurrency,exports.SOURCE_KINDS=["queue","loop","store","traffic"],exports.SOURCE_KINDS_READ=["queue","loop","store","traffic"],exports.QUEUE_WIRE_SCHEMA="lensmcp.queue/v1",exports.LOOP_WIRE_SCHEMA="lensmcp.loop/v1",exports.STORE_WIRE_SCHEMA="lensmcp.store/v1",exports.TRAFFIC_WIRE_SCHEMA="lensmcp.traffic/v1",exports.SOURCE_SNAPSHOT_FIELD={queue:"snapshot",loop:"loop",store:"store",traffic:"traffic"},exports.LOOP_OUTCOMES=["ok","failed","skipped"],exports.TRAFFIC_DIRECTIONS=["inbound","outbound"],exports.SOURCE_DEFAULT_INTERVAL_SEC=10,exports.SOURCE_MIN_INTERVAL_SEC=2,exports.QUEUE_DEFAULT_OLDEST_WAIT_MIN=10,exports.QUEUE_DEFAULT_STALLED_MIN=15,exports.LOOP_DEFAULT_IDLE_MIN=10,exports.STORE_DEFAULT_QUOTA_PCT=90,exports.STORE_DEFAULT_ERROR_RATE_PCT=5,exports.STORE_DEFAULT_ORPHAN_MIN=60,exports.TRAFFIC_DEFAULT_FAILURE_PCT=5,exports.TRAFFIC_DEFAULT_P95_MS=2e3,exports.TRAFFIC_DEFAULT_RATE_LIMITED=1,exports.SOURCE_FULL_REPORT_MS=6e4,exports.LOOP_MAX_INTERVAL_SEC=86400,exports.SOURCE_ERROR_MAX=500,exports.SOURCE_MAX_BYTES=256*1024,exports.SOURCE_MAX_GROUPS=500,exports.SOURCE_MAX_PER_SERVICE=16,exports.SOURCE_NOT_RUNNING_REPORT_MS=6e4,exports.SOURCE_DECLARATION_REPORT_MS=5*6e4,exports.SOURCE_BACKOFF_MAX_MS=6e4;const sourceStaleAfterMs=u(e=>Math.max(3e4,3*Math.max(0,e)),"sourceStaleAfterMs");exports.sourceStaleAfterMs=sourceStaleAfterMs;function sourceBackoffMs(e,t){return t<=1?e:Math.min(e*2**Math.min(t-1,10),Math.max(e,exports.SOURCE_BACKOFF_MAX_MS))}b(sourceBackoffMs,"sourceBackoffMs"),g(sourceBackoffMs,"sourceBackoffMs"),u(sourceBackoffMs,"sourceBackoffMs");const isPolled=u(e=>e.path!==void 0,"isPolled"),ENTRY_KEYS={queue:["kind","name","path","intervalSec","thresholds"],loop:["kind","name","path","intervalSec","thresholds","feeds"],store:["kind","name","path","intervalSec","thresholds"],traffic:["kind","name","path","intervalSec","thresholds"]},finite=u(e=>typeof e=="number"&&Number.isFinite(e),"finite"),MINUTES={ok:u(e=>finite(e)&&e>0&&e<=10080,"ok"),must:"must be minutes, more than 0 and at most 10080"},PERCENT={ok:u(e=>finite(e)&&e>0&&e<=100,"ok"),must:"must be a percent, more than 0 and at most 100"},MILLISECONDS={ok:u(e=>finite(e)&&e>0&&e<=6e5,"ok"),must:"must be milliseconds, more than 0 and at most 600000"},COUNT={ok:u(e=>Number.isInteger(e)&&e>=1&&e<=1e6,"ok"),must:"must be a count, a whole number from 1 to 1000000"},THRESHOLDS={queue:{oldestWaitMin:{def:exports.QUEUE_DEFAULT_OLDEST_WAIT_MIN,...MINUTES},stalledMin:{def:exports.QUEUE_DEFAULT_STALLED_MIN,...MINUTES}},loop:{idleMin:{def:exports.LOOP_DEFAULT_IDLE_MIN,...MINUTES}},store:{quotaPct:{def:exports.STORE_DEFAULT_QUOTA_PCT,...PERCENT},errorRatePct:{def:exports.STORE_DEFAULT_ERROR_RATE_PCT,...PERCENT},orphanMin:{def:exports.STORE_DEFAULT_ORPHAN_MIN,...MINUTES}},traffic:{failurePct:{def:exports.TRAFFIC_DEFAULT_FAILURE_PCT,...PERCENT},p95Ms:{def:exports.TRAFFIC_DEFAULT_P95_MS,...MILLISECONDS},rateLimited:{def:exports.TRAFFIC_DEFAULT_RATE_LIMITED,...COUNT}}},PATH_RE=/^\/(?!\/)[^\s#\u0000-\u001f\u007f]{0,511}$/,NAME_RE=/^[^\u0000-\u001f\u007f]{1,100}$/,isObj=u(e=>typeof e=="object"&&e!==null&&!Array.isArray(e),"isObj");function parseSourceDecls(e){const t=[],s=[],n=[];if(e===void 0)return{sources:t,problems:s};if(!Array.isArray(e))return{sources:t,problems:["`sources` is not a list of { kind, name, path } entries \u2014 no source is read"]};e.forEach((i,l)=>{const S=`sources[${l}]`;if(!isObj(i)){s.push(`${S} is not an object \u2014 not read`);return}const d=typeof i.name=="string"&&i.name.trim()?`${S} "${i.name}"`:S,r=i.kind;if(typeof r!="string"||!exports.SOURCE_KINDS_READ.includes(r)){s.push(`${d}: kind ${JSON.stringify(r??null)} is not a source kind (${exports.SOURCE_KINDS.join(", ")}) \u2014 not read`);return}const a=r,p=Object.keys(i).filter(_=>!ENTRY_KEYS[a].includes(_));if(p.length){s.push(`${d}: unknown key${p.length===1?"":"s"} ${p.map(_=>JSON.stringify(_)).join(", ")} for a ${a} source (known: ${ENTRY_KEYS[a].join(", ")}) \u2014 not read`);return}const R=i.name;if(typeof R!="string"||!R.trim()||!NAME_RE.test(R)){s.push(`${S}: name ${JSON.stringify(R??null)} must be 1\u2013100 characters, not blank \u2014 not read`);return}if(t.some(_=>_.name===R)){s.push(`${d}: the name is declared twice on this service \u2014 read once`);return}const h=i.path;if(h===void 0&&a!=="traffic"&&a!=="loop"){s.push(`${d}: a ${a} source needs a path \u2014 the route on the service that answers "lensmcp.${a}/v1" (only a loop or a traffic source may go without one, as push-only) \u2014 not read`);return}if(h!==void 0&&(typeof h!="string"||!PATH_RE.test(h)||h.split("?")[0].split("/").includes(".."))){s.push(`${d}: path ${JSON.stringify(h)} must be a route on the service, starting with "/" (e.g. "/api/dev/lens/backlog") \u2014 not read`);return}const m=i.intervalSec;if(m!==void 0&&!(typeof m=="number"&&Number.isInteger(m)&&m>=exports.SOURCE_MIN_INTERVAL_SEC&&m<=3600)){s.push(`${d}: intervalSec ${JSON.stringify(m)} must be a whole number of seconds from ${exports.SOURCE_MIN_INTERVAL_SEC} to 3600 \u2014 not read`);return}const A=i.thresholds;if(A!==void 0&&!isObj(A)){s.push(`${d}: thresholds must be an object \u2014 not read`);return}const I=isObj(A)?A:{},x=THRESHOLDS[a],o=Object.keys(x),c=Object.keys(I).filter(_=>!o.includes(_));if(c.length){s.push(`${d}: unknown threshold${c.length===1?"":"s"} ${c.map(_=>JSON.stringify(_)).join(", ")} for a ${a} source (known: ${o.join(", ")}) \u2014 not read`);return}const f=o.find(_=>I[_]!==void 0&&!x[_].ok(I[_]));if(f){s.push(`${d}: thresholds.${f} ${JSON.stringify(I[f])} ${x[f].must} \u2014 not read`);return}if(t.length>=exports.SOURCE_MAX_PER_SERVICE){s.push(`${d}: more than ${exports.SOURCE_MAX_PER_SERVICE} sources on one service \u2014 not read`);return}const O={};for(const _ of o)O[_]=I[_]??x[_].def;const E={kind:a,name:R,...h!==void 0?{path:h}:{},intervalSec:m??exports.SOURCE_DEFAULT_INTERVAL_SEC,thresholds:O};t.push(E),a==="loop"&&i.feeds!==void 0&&n.push({decl:E,label:d,feeds:i.feeds})});for(const{decl:i,label:l,feeds:S}of n)typeof S!="string"||!S.trim()?s.push(`${l}: feeds ${JSON.stringify(S)} must be the name of a queue source on this service \u2014 read without it`):t.some(d=>d.kind==="queue"&&d.name===S)?i.feeds=S:s.push(`${l}: feeds ${JSON.stringify(S)} names no queue source on this service \u2014 read without it`);return{sources:t,problems:s}}b(parseSourceDecls,"parseSourceDecls"),g(parseSourceDecls,"parseSourceDecls"),u(parseSourceDecls,"parseSourceDecls");const ISO_RE=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?(?:Z|[+-]\d{2}:?\d{2})$/,isIso=u(e=>typeof e=="string"&&ISO_RE.test(e)&&!Number.isNaN(Date.parse(e)),"isIso"),isCount=u(e=>typeof e=="number"&&Number.isSafeInteger(e)&&e>=0,"isCount"),notSchema=u((e,t)=>`schema is ${e===void 0?"absent":JSON.stringify(e).slice(0,60)}, not "${t}"`,"notSchema"),keyWrong=u((e,t,s)=>{if(typeof e!="string"||e.length===0||e.length>200)return`${t}.key must be a string of 1\u2013200 characters`;if(s.has(e))return`${t}.key ${JSON.stringify(e)} appears twice`;s.add(e)},"keyWrong"),labelsWrong=u((e,t)=>{if(e===void 0)return;if(!isObj(e))return`${t}.labels must be an object of strings`;const s=Object.entries(e);if(s.length>16)return`${t}.labels has more than 16 entries`;for(const[n,i]of s)if(n.length===0||n.length>64||typeof i!="string"||i.length>200)return`${t}.labels.${n.slice(0,64)} must be a string of at most 200 characters`},"labelsWrong"),overCap=u((e,t)=>`${e} ${t} \u2014 at most ${exports.SOURCE_MAX_GROUPS}; cap them and say \`truncated: { ${t}: <dropped> }\``,"overCap");function parseQueueSnapshot(e){const t=u(d=>({ok:!1,reason:d}),"fail");if(!isObj(e))return t("the snapshot is not a JSON object");if(e.schema!==exports.QUEUE_WIRE_SCHEMA)return t(notSchema(e.schema,exports.QUEUE_WIRE_SCHEMA));const s=e.at;if(!isIso(s))return t("`at` is not an ISO time");const n=e.truncated;if(n!==void 0&&!(isObj(n)&&isCount(n.groups)))return t("`truncated` must be { groups: <how many were dropped> }, or absent");const i=e.groups;if(!Array.isArray(i))return t("`groups` is not a list");if(i.length>exports.SOURCE_MAX_GROUPS)return t(overCap(i.length,"groups"));const l=new Set,S=[];for(let d=0;d<i.length;d++){const r=i[d],a=`groups[${d}]`;if(!isObj(r))return t(`${a} is not an object`);const p=keyWrong(r.key,a,l);if(p)return t(p);if(!isCount(r.pending))return t(`${a}.pending must be a whole number \u2265 0`);for(const A of["inFlight","failed","completedInWindow"])if(r[A]!==void 0&&!isCount(r[A]))return t(`${a}.${A} must be a whole number \u2265 0, or absent`);const R=r.oldestPendingAt;if(R!=null&&!isIso(R))return t(`${a}.oldestPendingAt must be an ISO time, null, or absent`);const h=r.labels,m=labelsWrong(h,a);if(m)return t(m);S.push({key:r.key,...h!==void 0?{labels:h}:{},pending:r.pending,...r.inFlight!==void 0?{inFlight:r.inFlight}:{},...r.failed!==void 0?{failed:r.failed}:{},...R!==void 0?{oldestPendingAt:R}:{},...r.completedInWindow!==void 0?{completedInWindow:r.completedInWindow}:{}})}return{ok:!0,at:s,groups:S,...n!==void 0?{truncated:{groups:n.groups}}:{}}}b(parseQueueSnapshot,"parseQueueSnapshot"),g(parseQueueSnapshot,"parseQueueSnapshot"),u(parseQueueSnapshot,"parseQueueSnapshot");const LOOP_COUNTS=["lastDurationMs","lastItems","runsInWindow","itemsInWindow","failuresInWindow","windowSec"],cutText=u((e,t)=>{if(e.length<=t)return e;const s=t-1,n=e.charCodeAt(s-1);return`${e.slice(0,n>=55296&&n<=56319?s-1:s)}\u2026`},"cutText");function parseLoopSnapshot(e){const t=u(a=>({ok:!1,reason:a}),"fail");if(!isObj(e))return t("the snapshot is not a JSON object");if(e.schema!==exports.LOOP_WIRE_SCHEMA)return t(notSchema(e.schema,exports.LOOP_WIRE_SCHEMA));const s=e.at;if(!isIso(s))return t("`at` is not an ISO time");const n=e.intervalSec;if(!(typeof n=="number"&&Number.isFinite(n)&&n>0&&n<=exports.LOOP_MAX_INTERVAL_SEC))return t(`\`intervalSec\` must be the loop's own period in seconds, more than 0 and at most ${exports.LOOP_MAX_INTERVAL_SEC}`);const i=e.lastRunAt;if(i===void 0)return t("`lastRunAt` is absent \u2014 say null if the loop has not run since the service started");if(i!==null&&!isIso(i))return t("`lastRunAt` must be an ISO time, or null if the loop has not run since the service started");for(const a of LOOP_COUNTS)if(e[a]!==void 0&&!isCount(e[a]))return t(`\`${a}\` must be a whole number \u2265 0, or absent`);const l=e.lastOutcome;if(l!==void 0&&!exports.LOOP_OUTCOMES.includes(l))return t(`\`lastOutcome\` must be ${exports.LOOP_OUTCOMES.join(", ")}, or absent`);const S=e.nextRunAt;if(S!=null&&!isIso(S))return t("`nextRunAt` must be an ISO time, null, or absent");const d=e.lastError;if(d!==void 0&&typeof d!="string")return t("`lastError` must be a string, or absent");const r=u(a=>e[a]!==void 0?{[a]:e[a]}:{},"count");return{ok:!0,loop:{at:s,intervalSec:n,lastRunAt:i,...r("lastDurationMs"),...l!==void 0?{lastOutcome:l}:{},...r("lastItems"),...S!==void 0?{nextRunAt:S}:{},...r("runsInWindow"),...r("itemsInWindow"),...r("failuresInWindow"),...r("windowSec"),...d!==void 0?{lastError:cutText(d,exports.SOURCE_ERROR_MAX)}:{}}}}b(parseLoopSnapshot,"parseLoopSnapshot"),g(parseLoopSnapshot,"parseLoopSnapshot"),u(parseLoopSnapshot,"parseLoopSnapshot");const STORE_COUNTS=["opsInWindow","writesInWindow","deletesInWindow","errorsInWindow","windowSec"];function parseStoreSnapshot(e){const t=u(p=>({ok:!1,reason:p}),"fail");if(!isObj(e))return t("the snapshot is not a JSON object");if(e.schema!==exports.STORE_WIRE_SCHEMA)return t(notSchema(e.schema,exports.STORE_WIRE_SCHEMA));const s=e.at;if(!isIso(s))return t("`at` is not an ISO time");for(const p of["objects","bytes"])if(!isCount(e[p]))return t(`\`${p}\` must be a whole number \u2265 0`);const n=e.quotaBytes;if(n!=null&&!isCount(n))return t("`quotaBytes` must be a whole number \u2265 0, null when it has no quota, or absent");for(const p of STORE_COUNTS)if(e[p]!==void 0&&!isCount(e[p]))return t(`\`${p}\` must be a whole number \u2265 0, or absent`);const i=e.lastWriteAt;if(i!=null&&!isIso(i))return t("`lastWriteAt` must be an ISO time, null, or absent");const l=e.lastError;if(l!==void 0&&typeof l!="string")return t("`lastError` must be a string, or absent");const S=e.truncated;if(S!==void 0&&!(isObj(S)&&isCount(S.groups)))return t("`truncated` must be { groups: <how many were dropped> }, or absent");const d=e.groups;let r;if(d!==void 0){if(!Array.isArray(d))return t("`groups` must be a list, or absent");if(d.length>exports.SOURCE_MAX_GROUPS)return t(overCap(d.length,"groups"));const p=new Set;r=[];for(let R=0;R<d.length;R++){const h=d[R],m=`groups[${R}]`;if(!isObj(h))return t(`${m} is not an object`);const A=keyWrong(h.key,m,p);if(A)return t(A);for(const o of["objects","bytes"])if(!isCount(h[o]))return t(`${m}.${o} must be a whole number \u2265 0`);const I=h.labels,x=labelsWrong(I,m);if(x)return t(x);r.push({key:h.key,...I!==void 0?{labels:I}:{},objects:h.objects,bytes:h.bytes})}}const a=u(p=>e[p]!==void 0?{[p]:e[p]}:{},"count");return{ok:!0,store:{at:s,objects:e.objects,bytes:e.bytes,...n!==void 0?{quotaBytes:n}:{},...a("opsInWindow"),...a("writesInWindow"),...a("deletesInWindow"),...a("errorsInWindow"),...a("windowSec"),...i!==void 0?{lastWriteAt:i}:{},...l!==void 0?{lastError:cutText(l,exports.SOURCE_ERROR_MAX)}:{},...r?{groups:r}:{},...S!==void 0?{truncated:{groups:S.groups}}:{}}}}b(parseStoreSnapshot,"parseStoreSnapshot"),g(parseStoreSnapshot,"parseStoreSnapshot"),u(parseStoreSnapshot,"parseStoreSnapshot");const TRAFFIC_COUNTS=["messagesInWindow","failuresInWindow","rateLimitedInWindow"];function parseTrafficSnapshot(e){const t=u(r=>({ok:!1,reason:r}),"fail");if(!isObj(e))return t("the snapshot is not a JSON object");if(e.schema!==exports.TRAFFIC_WIRE_SCHEMA)return t(notSchema(e.schema,exports.TRAFFIC_WIRE_SCHEMA));const s=e.at;if(!isIso(s))return t("`at` is not an ISO time");const n=e.windowSec;if(n!==void 0&&!isCount(n))return t("`windowSec` must be a whole number \u2265 0, or absent");const i=e.truncated;if(i!==void 0&&!(isObj(i)&&isCount(i.channels)))return t("`truncated` must be { channels: <how many were dropped> }, or absent");const l=e.channels;if(!Array.isArray(l))return t("`channels` is not a list");if(l.length>exports.SOURCE_MAX_GROUPS)return t(overCap(l.length,"channels"));const S=new Set,d=[];for(let r=0;r<l.length;r++){const a=l[r],p=`channels[${r}]`;if(!isObj(a))return t(`${p} is not an object`);const R=keyWrong(a.key,p,S);if(R)return t(R);const h=a.direction;if(h!==void 0&&!exports.TRAFFIC_DIRECTIONS.includes(h))return t(`${p}.direction must be ${exports.TRAFFIC_DIRECTIONS.join(", ")}, or absent`);const m=a.counterpart;if(m!==void 0&&!(typeof m=="string"&&m.length>0&&m.length<=200))return t(`${p}.counterpart must be a string of 1\u2013200 characters, or absent`);for(const O of TRAFFIC_COUNTS)if(a[O]!==void 0&&!isCount(a[O]))return t(`${p}.${O} must be a whole number \u2265 0, or absent`);const A=a.p95Ms;if(A!==void 0&&!(finite(A)&&A>=0))return t(`${p}.p95Ms must be milliseconds \u2265 0, or absent`);const I=a.lastAt;if(I!=null&&!isIso(I))return t(`${p}.lastAt must be an ISO time, null, or absent`);const x=a.lastError;if(x!==void 0&&typeof x!="string")return t(`${p}.lastError must be a string, or absent`);const o=a.labels,c=labelsWrong(o,p);if(c)return t(c);const f=u(O=>a[O]!==void 0?{[O]:a[O]}:{},"count");d.push({key:a.key,...o!==void 0?{labels:o}:{},...h!==void 0?{direction:h}:{},...m!==void 0?{counterpart:m}:{},...f("messagesInWindow"),...f("failuresInWindow"),...f("rateLimitedInWindow"),...A!==void 0?{p95Ms:A}:{},...I!==void 0?{lastAt:I}:{},...x!==void 0?{lastError:cutText(x,exports.SOURCE_ERROR_MAX)}:{}})}return{ok:!0,traffic:{at:s,...n!==void 0?{windowSec:n}:{},channels:d,...i!==void 0?{truncated:{channels:i.channels}}:{}}}}b(parseTrafficSnapshot,"parseTrafficSnapshot"),g(parseTrafficSnapshot,"parseTrafficSnapshot"),u(parseTrafficSnapshot,"parseTrafficSnapshot");const sourceFull=u((e,t)=>({[exports.SOURCE_SNAPSHOT_FIELD[e]]:t}),"sourceFull");exports.sourceFull=sourceFull;const declRaw=u(e=>({sourceKind:e.kind,name:e.name,...e.path!==void 0?{path:e.path}:{},intervalSec:e.intervalSec,thresholds:{...e.thresholds},...e.feeds!==void 0?{feeds:e.feeds}:{}}),"declRaw"),canonical=u(e=>{if(Array.isArray(e))return e.map(canonical);if(!isObj(e))return e;const t={};for(const s of Object.keys(e).sort())t[s]=canonical(e[s]);return t},"canonical");function sourceDigest(e){return(0,node_crypto_1.createHash)("sha1").update(JSON.stringify(canonical(e))??"null").digest("hex").slice(0,16)}b(sourceDigest,"sourceDigest"),g(sourceDigest,"sourceDigest"),u(sourceDigest,"sourceDigest");const oldestOf=u(e=>e.pending>0&&e.oldestPendingAt?Date.parse(e.oldestPendingAt):Number.POSITIVE_INFINITY,"oldestOf");function keepQueueSnapshot(e,t,s,n){const i={groups:t.length,pending:0,inFlight:0,failed:0};let l;for(const r of t)i.pending+=r.pending,i.inFlight+=r.inFlight??0,i.failed+=r.failed??0,r.completedInWindow!==void 0&&(l=(l??0)+r.completedInWindow);l!==void 0&&(i.completedInWindow=l);const S=[...t].sort((r,a)=>oldestOf(r)-oldestOf(a)||a.pending-r.pending||(r.key<a.key?-1:r.key>a.key?1:0)).map(({key:r,...a})=>({group:r,...a})),d=n?{groups:n.groups}:void 0;return{at:e,receivedAt:s,totals:i,groups:S,...d?{truncated:d}:{},digest:sourceDigest({groups:S,truncated:d??null})}}b(keepQueueSnapshot,"keepQueueSnapshot"),g(keepQueueSnapshot,"keepQueueSnapshot"),u(keepQueueSnapshot,"keepQueueSnapshot");function keepLoopSnapshot(e,t){const{at:s,...n}=e;return{at:s,receivedAt:t,digest:sourceDigest(n),...n}}b(keepLoopSnapshot,"keepLoopSnapshot"),g(keepLoopSnapshot,"keepLoopSnapshot"),u(keepLoopSnapshot,"keepLoopSnapshot");const byKey=u((e,t)=>e<t?-1:e>t?1:0,"byKey");function keepStoreSnapshot(e,t){const{at:s,groups:n,truncated:i,...l}=e,S=n?[...n].sort((r,a)=>a.bytes-r.bytes||a.objects-r.objects||byKey(r.key,a.key)).map(({key:r,...a})=>({group:r,...a})):void 0,d={...l,...S?{groups:S}:{},...i?{truncated:{groups:i.groups}}:{}};return{at:s,receivedAt:t,digest:sourceDigest(d),...d}}b(keepStoreSnapshot,"keepStoreSnapshot"),g(keepStoreSnapshot,"keepStoreSnapshot"),u(keepStoreSnapshot,"keepStoreSnapshot");const messagesOf=u(e=>e.messagesInWindow??-1,"messagesOf");function keepTrafficSnapshot(e,t){const{at:s,channels:n,truncated:i,...l}=e,S=[...n].sort((r,a)=>messagesOf(a)-messagesOf(r)||byKey(r.key,a.key)).map(({key:r,...a})=>({channel:r,...a})),d={...l,channels:S,...i?{truncated:{channels:i.channels}}:{}};return{at:s,receivedAt:t,digest:sourceDigest(d),...d}}b(keepTrafficSnapshot,"keepTrafficSnapshot"),g(keepTrafficSnapshot,"keepTrafficSnapshot"),u(keepTrafficSnapshot,"keepTrafficSnapshot");const sourceSame=u(e=>({digest:e.digest,at:e.at,receivedAt:e.receivedAt}),"sourceSame");exports.sourceSame=sourceSame;function buildSourcePollRaw(e,t,s,n,i,l){return{kind:"source-poll",provenance:"reported",project:e,...declRaw(t),state:s.state,...s.detail!==void 0?{detail:s.detail}:{},...s.status!==void 0?{status:s.status}:{},polledAt:s.polledAt,...s.durationMs!==void 0?{durationMs:s.durationMs}:{},reportEveryMs:n,...i>0?{failures:i}:{},...l??{}}}b(buildSourcePollRaw,"buildSourcePollRaw"),g(buildSourcePollRaw,"buildSourcePollRaw"),u(buildSourcePollRaw,"buildSourcePollRaw");function buildSourceDeclarationRaw(e,t){return{kind:"source-declaration",project:e,sources:t.sources.map(declRaw),problems:[...t.problems]}}b(buildSourceDeclarationRaw,"buildSourceDeclarationRaw"),g(buildSourceDeclarationRaw,"buildSourceDeclarationRaw"),u(buildSourceDeclarationRaw,"buildSourceDeclarationRaw");const span=u(e=>{const t=Math.round(e/6e4);return e<6e4?`${Math.max(0,Math.round(e/1e3))}s`:t<120?`${t}m`:`${Math.floor(t/60)}h${t%60?` ${t%60}m`:""}`},"span"),loopWords=u(e=>`${e.lastRunAt===null?"has not run since the service started":`last run ${span(Math.max(0,Date.parse(e.at)-Date.parse(e.lastRunAt)))} before it was measured`}${e.lastOutcome?`, ${e.lastOutcome}`:""}${e.lastItems!==void 0?`, ${e.lastItems} item${e.lastItems===1?"":"s"}`:""}`,"loopWords"),plural=u((e,t)=>`${e} ${t}${e===1?"":"s"}`,"plural"),byteSize=u(e=>{const t=["B","kB","MB","GB","TB","PB"];let s=e,n=0;for(;s>=999.5&&n<t.length-1;)s/=1e3,n+=1;return n===0?`${e} B`:`${s<9.95?s.toFixed(1):Math.round(s)} ${t[n]}`},"byteSize"),storeWords=u(e=>{const t=typeof e.quotaBytes=="number"&&e.quotaBytes>0?` of ${byteSize(e.quotaBytes)} (${Math.round(e.bytes/e.quotaBytes*1e3)/10}%)`:"",s=e.errorsInWindow?`, ${plural(e.errorsInWindow,"error")}${e.windowSec?` in ${span(e.windowSec*1e3)}`:""}`:"";return`${plural(e.objects,"object")}, ${byteSize(e.bytes)}${t}${s}`},"storeWords"),trafficWords=u(e=>{let t,s=0,n=0;for(const l of e.channels)l.messagesInWindow!==void 0&&(t=(t??0)+l.messagesInWindow),s+=l.failuresInWindow??0,n+=l.rateLimitedInWindow??0;const i=t!==void 0?`, ${plural(t,"message")}${e.windowSec?` in ${span(e.windowSec*1e3)}`:""}`:"";return`${plural(e.channels.length,"channel")}${i}${s?`, ${s} failed`:""}${n?`, ${n} rate-limited`:""}`},"trafficWords");function sourcePollTitle(e,t){const s=`${e.sourceKind} ${e.project}/${e.name} (reported)`,n=t??e[exports.SOURCE_SNAPSHOT_FIELD[e.sourceKind]];if(e.state!=="current"||!n)return`${s}: ${e.state}${e.detail?` \u2014 ${e.detail}`:""}`;if(e.sourceKind==="loop")return`${s}: ${loopWords(n)}`;if(e.sourceKind==="store")return`${s}: ${storeWords(n)}`;if(e.sourceKind==="traffic")return`${s}: ${trafficWords(n)}`;const i=n,l=i.groups.find(d=>d.pending>0&&d.oldestPendingAt),S=l?.oldestPendingAt?Date.parse(i.at)-Date.parse(l.oldestPendingAt):void 0;return`${s}: ${i.totals.pending} pending in ${i.totals.groups} group${i.totals.groups===1?"":"s"}${S!==void 0?`, oldest waiting ${span(Math.max(0,S))}`:""}`}b(sourcePollTitle,"sourcePollTitle"),g(sourcePollTitle,"sourcePollTitle"),u(sourcePollTitle,"sourcePollTitle");function requestOverSocket(e,t,s,n,i=exports.SOURCE_MAX_BYTES){return new Promise(l=>{let S=!1,d;const r=u(p=>{S||(S=!0,clearTimeout(a),l(p))},"finish"),a=setTimeout(()=>{r({ok:!1,code:"ETIMEDOUT",message:`no answer within ${n} ms`}),d?.destroy()},n);a.unref?.();try{d=http.request({socketPath:e,path:t,method:"GET",agent:!1,headers:s},p=>{const R=[];let h=0;p.on("data",m=>{if(!S){if(h+=m.length,h>i){r({ok:!0,status:p.statusCode??0,body:"",truncated:!0}),p.destroy();return}R.push(m)}}),p.on("end",()=>r({ok:!0,status:p.statusCode??0,body:Buffer.concat(R).toString("utf8"),truncated:!1})),p.on("error",m=>r({ok:!1,code:m.code??"ERESPONSE",message:m.message}))}),d.on("error",p=>r({ok:!1,code:p.code??"EREQUEST",message:p.message})),d.end()}catch(p){r({ok:!1,code:p.code??"EREQUEST",message:p.message})}})}b(requestOverSocket,"requestOverSocket"),g(requestOverSocket,"requestOverSocket"),u(requestOverSocket,"requestOverSocket");const snippet=u(e=>e.replace(/\s+/g," ").trim().slice(0,160),"snippet");function readSnapshot(e,t,s){let n;try{n=JSON.parse(t)}catch{return{ok:!1,reason:`not JSON: ${snippet(t)||"(an empty body)"}`}}if(e==="loop"){const l=parseLoopSnapshot(n);return l.ok===!0?{ok:!0,kept:keepLoopSnapshot(l.loop,s)}:l}if(e==="store"){const l=parseStoreSnapshot(n);return l.ok===!0?{ok:!0,kept:keepStoreSnapshot(l.store,s)}:l}if(e==="traffic"){const l=parseTrafficSnapshot(n);return l.ok===!0?{ok:!0,kept:keepTrafficSnapshot(l.traffic,s)}:l}const i=parseQueueSnapshot(n);return i.ok===!0?{ok:!0,kept:keepQueueSnapshot(i.at,i.groups,s,i.truncated)}:i}b(readSnapshot,"readSnapshot"),g(readSnapshot,"readSnapshot"),u(readSnapshot,"readSnapshot");function createSourcePoller(e){const t=e.now??Date.now,s=e.timeoutMs??(0,exports.sourcesTimeoutMs)(),n=Math.max(1,e.maxConcurrent??(0,exports.sourcesConcurrency)()),i=e.socketOf??(o=>(0,discovery_1.pickSock)(o.pool,e.scanTtlMs??1500)),l=e.request??requestOverSocket,S=e.log??(o=>console.warn(o)),d=new WeakMap,r=new Map;let a=0,p;const R=u(o=>{const c=o.decl;let f=d.get(c);if(!f){f=parseSourceDecls(o.decl.sources),d.set(c,f);for(const E of f.problems)S(`[gateway] ${o.project}: cluster.sources \u2014 ${E}`)}const O=t();return(f.reportedAt===void 0||O-f.reportedAt>=exports.SOURCE_DECLARATION_REPORT_MS)&&(f.reportedAt=O,e.emit(o,f.problems.length?"warning":"info",f.problems.length?`sources ${o.project}: ${f.problems.length} cluster.sources entr${f.problems.length===1?"y":"ies"} not read \u2014 ${f.problems[0]}`:`sources ${o.project}: reads ${f.sources.map(E=>`${E.kind} "${E.name}"${isPolled(E)?"":" (push-only)"}`).join(", ")}`,`source-declaration:${o.wsKey}:${o.project}`,buildSourceDeclarationRaw(o.project,f))),f},"declarationOf"),h=u(o=>{if(o.state==="starting")return{notRunning:"it is starting \u2014 read once it is up"};const c=i(o);return c?{socket:c}:{notRunning:o.state==="up"?"it has no live pod socket \u2014 no pod runs it now":"it is scaled to zero \u2014 the lens does not start a service to read a source"}},"reach"),m=u((o,c)=>{const f=o.good;if(f)return o.full&&o.full.digest===f.digest&&c-o.full.at<exports.SOURCE_FULL_REPORT_MS?{same:(0,exports.sourceSame)(f)}:(o.full={digest:f.digest,at:c},(0,exports.sourceFull)(o.decl.kind,f))},"carried"),A=u((o,c)=>{const f=o.last;if(!f)return;const O=t();if(!c&&o.reportedAt!==void 0&&O-o.reportedAt<o.reportEveryMs)return;o.reportedAt=O;const E=buildSourcePollRaw(o.svc.project,o.decl,f,o.reportEveryMs,o.failures,m(o,O)),_=f.state==="unreachable"||f.state==="refused"||f.state==="malformed";e.emit(o.svc,_?"warning":"info",sourcePollTitle(E,o.good),`source:${o.svc.wsKey}:${o.svc.project}:${o.decl.name}`,E)},"report"),I=u(async o=>{const c=t(),f=o.decl.intervalSec*1e3;o.inFlight=!0,a+=1;const O=o.last?.state;try{const E=h(o.svc);if("notRunning"in E){o.last={state:"not-running",detail:E.notRunning,polledAt:c},o.failures=0,o.nextAt=c+f,o.reportEveryMs=exports.SOURCE_NOT_RUNNING_REPORT_MS,A(o,O!=="not-running");return}const _=e.serviceKey(o.svc),T=await l(E.socket,o.decl.path,{accept:"application/json","x-lensmcp-probe":`source:${o.decl.kind}`,..._?{"x-internal-token":_}:{}},s,exports.SOURCE_MAX_BYTES),$=Math.max(0,t()-c);if(T.ok===!1){const v=T.code==="ECONNREFUSED"||T.code==="ENOENT";o.last=v&&o.svc.state!=="up"?{state:"not-running",detail:`nothing listens on its pod socket \u2014 the service is ${o.svc.state}`,polledAt:c,durationMs:$}:{state:"unreachable",detail:T.code==="ETIMEDOUT"?T.message:`${T.code}: ${snippet(T.message)}`,polledAt:c,durationMs:$}}else if(T.status<200||T.status>299){const v=snippet(T.body);o.last={state:"refused",status:T.status,detail:`HTTP ${T.status}${v?`: ${v}`:""}`,polledAt:c,durationMs:$}}else if(T.truncated)o.last={state:"malformed",detail:`the snapshot is larger than ${exports.SOURCE_MAX_BYTES/1024} KiB`,polledAt:c,durationMs:$};else{const v=readSnapshot(o.decl.kind,T.body,t());v.ok===!0?(o.good=v.kept,o.last={state:"current",polledAt:c,durationMs:$}):o.last={state:"malformed",detail:v.reason,polledAt:c,durationMs:$}}const M=o.last.state==="unreachable"||o.last.state==="refused"||o.last.state==="malformed";o.failures=M?o.failures+1:0;const y=M?sourceBackoffMs(f,o.failures):f;o.nextAt=c+y,o.reportEveryMs=o.last.state==="not-running"?exports.SOURCE_NOT_RUNNING_REPORT_MS:y,A(o,o.last.state!=="not-running"||O!=="not-running")}catch(E){o.last={state:"unreachable",detail:`the poll failed: ${snippet(E?.message??String(E))}`,polledAt:c},o.failures+=1,o.nextAt=c+sourceBackoffMs(f,o.failures),o.reportEveryMs=o.nextAt-c,A(o,!0)}finally{o.inFlight=!1,a-=1}},"pollOne"),x=u(async()=>{if(e.stopped?.())return;const o=new Set;for(const E of e.services())if(E.decl.sources!==void 0)for(const _ of R(E).sources){if(!isPolled(_))continue;const T=`${E.wsKey} ${E.project} ${_.kind} ${_.name}`;o.add(T);const $=r.get(T);$?($.svc!==E||$.decl!==_)&&($.svc=E,$.decl=_):r.set(T,{svc:E,decl:_,nextAt:0,inFlight:!1,failures:0,reportEveryMs:_.intervalSec*1e3})}for(const[E,_]of[...r.entries()])!o.has(E)&&!_.inFlight&&r.delete(E);const c=t(),f=[...r.values()].filter(E=>!E.inFlight&&c>=E.nextAt).sort((E,_)=>E.nextAt-_.nextAt),O=[];for(const E of f){if(a>=n)break;O.push(I(E))}await Promise.all(O)},"tick");return{tick:x,start(o=1e3){return p&&clearInterval(p),p=setInterval(()=>{x().catch(c=>console.error("[gateway] source poll error:",c))},o),p.unref(),p},stop(){p&&clearInterval(p),p=void 0},snapshot(){const o=t();return[...r.values()].map(c=>{const f=c.last!==void 0&&o-c.last.polledAt>(0,exports.sourceStaleAfterMs)(c.reportEveryMs);return{wsKey:c.svc.wsKey,project:c.svc.project,name:c.decl.name,kind:c.decl.kind,path:c.decl.path,state:c.last?f?"stale":c.last.state:"never-polled",...c.last?.detail!==void 0?{detail:c.last.detail}:{},...c.last?.status!==void 0?{status:c.last.status}:{},...c.last?{polledAt:c.last.polledAt}:{},failures:c.failures,nextAt:c.nextAt,...c.good?{...(0,exports.sourceFull)(c.decl.kind,c.good),ageMs:Math.max(0,o-c.good.receivedAt)}:{}}})}}}b(createSourcePoller,"createSourcePoller"),g(createSourcePoller,"createSourcePoller"),u(createSourcePoller,"createSourcePoller");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var C=Object.defineProperty;var L=(_,E)=>C(_,"name",{value:E,configurable:!0});var O=Object.defineProperty,e=L((_,E)=>O(_,"name",{value:E,configurable:!0}),"e"),M=Object.defineProperty,R=e((_,E)=>M(_,"name",{value:E,configurable:!0}),"R");Object.defineProperty(exports,"__esModule",{value:!0}),exports.GATEWAY_H2_RESET_RATE=exports.GATEWAY_H2_RESET_BURST=exports.BODY_STALL_MS=exports.GATEWAY_CONN_CHECK_MS=exports.GATEWAY_MAX_CONNECTIONS=exports.GATEWAY_STOP_GRACE_MS=exports.GATEWAY_HEADERS_TIMEOUT_MS=exports.GATEWAY_KEEPALIVE_TIMEOUT_MS=exports.LENS_REQUEST_RECOVERY_WAIT_MS=exports.LENS_REPLACEMENT_DRAIN_MS=exports.LENS_REPLACEMENT_READY_MS=exports.LENS_RESTART_MODE=exports.LENS_RECYCLE_KILL_GRACE_MS=exports.LENS_PARKED_PORT_REPROBE_MS=exports.MAX_PORT_CONFLICT_RETRIES=exports.CHILD_START_FAIL_MS=exports.PORT_FREE_POLL_MS=exports.PORT_FREE_WAIT_MS=exports.LENS_PROBE_BOOT_GRACE_MS=exports.LENS_PROBE_COOLDOWN_MS=exports.LENS_PROBE_TIMEOUT_MS=exports.LENS_PROBE_FAILS=exports.LENS_PROBE_GRACE_MS=exports.MAX_COLD_STARTS=exports.POD_MAX_CONCURRENT_ROLLS=exports.POD_ROLL_READY_MS=exports.POD_RECYCLE_MODE=exports.POD_WATCHER_SILENT=exports.POD_WATCHER_UNVERIFIED=exports.LENS_WATCH_SCOPE_ENABLED=exports.LENS_WATCHER_UNVERIFIED=exports.LENS_WATCHER_PROBE_ENABLED=exports.LENS_PROBE_ENABLED=exports.POD_STALE_RECYCLE_COOLDOWN_MS=exports.POD_STALE_SCAN_MS=exports.POD_RECYCLE_SETTLE_MS=exports.POD_STALE_GRACE_MS=exports.POD_MAX_AGE_MS=exports.POD_RECYCLE_ENABLED=exports.WEDGE_RECYCLE_GRACE_MS=exports.POD_ALIVE_PATH=exports.POD_WEDGE_CONFIRM_MS=exports.POD_ALIVE_PROBE_TIMEOUT_MS=exports.POD_SLOW_FIRST_BYTE_MS=exports.POD_RESPONSE_TIMEOUT_MS=exports.UPSTREAM_HEAL_STEP_MS=exports.UPSTREAM_HEAL_WINDOW_MS=exports.SERVICE_RESTART_WINDOW_MS=exports.SERVICE_MAX_RESTARTS=exports.SERVICE_ERROR_THROTTLE_MS=void 0;const tslib_1=require("tslib"),os=tslib_1.__importStar(require("node:os"));function envInt(_,E,T=!1){const S=Number(process.env[_]);return!Number.isFinite(S)||S<0?E:S===0?T?0:E:S}L(envInt,"envInt"),e(envInt,"envInt"),R(envInt,"envInt"),exports.SERVICE_ERROR_THROTTLE_MS=5e3,exports.SERVICE_MAX_RESTARTS=5,exports.SERVICE_RESTART_WINDOW_MS=6e4,exports.UPSTREAM_HEAL_WINDOW_MS=8e3,exports.UPSTREAM_HEAL_STEP_MS=300,exports.POD_RESPONSE_TIMEOUT_MS=(()=>{const _=Number(process.env.LENSMCP_POD_RESPONSE_TIMEOUT_MS);return Number.isFinite(_)&&_>0?_:3e4})(),exports.POD_SLOW_FIRST_BYTE_MS=envInt("LENSMCP_POD_SLOW_FIRST_BYTE_MS",10*6e4,!0),exports.POD_ALIVE_PROBE_TIMEOUT_MS=envInt("LENSMCP_POD_ALIVE_PROBE_TIMEOUT_MS",1e3),exports.POD_WEDGE_CONFIRM_MS=envInt("LENSMCP_POD_WEDGE_CONFIRM_MS",1e4,!0),exports.POD_ALIVE_PATH="/__lensmcp/alive",exports.WEDGE_RECYCLE_GRACE_MS=(()=>{const _=Number(process.env.LENSMCP_WEDGE_RECYCLE_GRACE_MS);return Number.isFinite(_)&&_>0?_:15e3})(),exports.POD_RECYCLE_ENABLED=process.env.LENSMCP_POD_RECYCLE!=="0",exports.POD_MAX_AGE_MS=envInt("LENSMCP_POD_MAX_AGE_MS",240*6e4,!0),exports.POD_STALE_GRACE_MS=envInt("LENSMCP_POD_STALE_GRACE_MS",1e4),exports.POD_RECYCLE_SETTLE_MS=envInt("LENSMCP_POD_RECYCLE_SETTLE_MS",8e3),exports.POD_STALE_SCAN_MS=envInt("LENSMCP_POD_STALE_SCAN_MS",3e4),exports.POD_STALE_RECYCLE_COOLDOWN_MS=envInt("LENSMCP_POD_STALE_RECYCLE_COOLDOWN_MS",6e4),exports.LENS_PROBE_ENABLED=process.env.LENSMCP_LENS_PROBE!=="0",exports.LENS_WATCHER_PROBE_ENABLED=process.env.LENSMCP_LENS_WATCHER_PROBE!=="0",exports.LENS_WATCHER_UNVERIFIED=process.env.LENSMCP_LENS_WATCHER_UNVERIFIED==="keep"?"keep":"recycle",exports.LENS_WATCH_SCOPE_ENABLED=process.env.LENSMCP_LENS_WATCH_SCOPE!=="0",exports.POD_WATCHER_UNVERIFIED=process.env.LENSMCP_POD_WATCHER_UNVERIFIED==="keep"?"keep":"recycle",exports.POD_WATCHER_SILENT=process.env.LENSMCP_POD_WATCHER_SILENT==="recycle"?"recycle":"keep",exports.POD_RECYCLE_MODE=process.env.LENSMCP_POD_RECYCLE_MODE==="in-place"?"in-place":"rolling",exports.POD_ROLL_READY_MS=envInt("LENSMCP_POD_ROLL_READY_MS",18e4),exports.POD_MAX_CONCURRENT_ROLLS=envInt("LENSMCP_POD_MAX_CONCURRENT_ROLLS",2,!0),exports.MAX_COLD_STARTS=envInt("LENSMCP_MAX_COLD_STARTS",Math.max(2,Math.floor(os.availableParallelism()/2)),!0),exports.LENS_PROBE_GRACE_MS=envInt("LENSMCP_LENS_PROBE_GRACE_MS",45e3),exports.LENS_PROBE_FAILS=envInt("LENSMCP_LENS_PROBE_FAILS",2),exports.LENS_PROBE_TIMEOUT_MS=envInt("LENSMCP_LENS_PROBE_TIMEOUT_MS",1e3),exports.LENS_PROBE_COOLDOWN_MS=envInt("LENSMCP_LENS_PROBE_COOLDOWN_MS",3e4),exports.LENS_PROBE_BOOT_GRACE_MS=envInt("LENSMCP_LENS_PROBE_BOOT_GRACE_MS",24e4),exports.PORT_FREE_WAIT_MS=envInt("LENSMCP_PORT_FREE_WAIT_MS",1e4),exports.PORT_FREE_POLL_MS=envInt("LENSMCP_PORT_FREE_POLL_MS",250),exports.CHILD_START_FAIL_MS=envInt("LENSMCP_CHILD_START_FAIL_MS",1e4),exports.MAX_PORT_CONFLICT_RETRIES=envInt("LENSMCP_MAX_PORT_CONFLICT_RETRIES",5),exports.LENS_PARKED_PORT_REPROBE_MS=envInt("LENSMCP_PARKED_PORT_REPROBE_MS",3e5),exports.LENS_RECYCLE_KILL_GRACE_MS=envInt("LENSMCP_RECYCLE_KILL_GRACE_MS",5e3),exports.LENS_RESTART_MODE=process.env.LENSMCP_LENS_RESTART_MODE==="in-place"?"in-place":"rolling",exports.LENS_REPLACEMENT_READY_MS=envInt("LENSMCP_LENS_REPLACEMENT_READY_MS",3e4),exports.LENS_REPLACEMENT_DRAIN_MS=envInt("LENSMCP_LENS_REPLACEMENT_DRAIN_MS",2e3,!0),exports.LENS_REQUEST_RECOVERY_WAIT_MS=envInt("LENSMCP_LENS_REQUEST_RECOVERY_WAIT_MS",15e3),exports.GATEWAY_KEEPALIVE_TIMEOUT_MS=envInt("LENSMCP_KEEPALIVE_TIMEOUT_MS",76e3),exports.GATEWAY_HEADERS_TIMEOUT_MS=envInt("LENSMCP_HEADERS_TIMEOUT_MS",6e4),exports.GATEWAY_STOP_GRACE_MS=envInt("LENSMCP_STOP_GRACE_MS",3e3),exports.GATEWAY_MAX_CONNECTIONS=envInt("LENSMCP_MAX_CONNECTIONS",0,!0),exports.GATEWAY_CONN_CHECK_MS=envInt("LENSMCP_CONN_CHECK_MS",0,!0),exports.BODY_STALL_MS=envInt("LENSMCP_BODY_STALL_MS",6e4,!0),exports.GATEWAY_H2_RESET_BURST=envInt("LENSMCP_H2_RESET_BURST",1e5),exports.GATEWAY_H2_RESET_RATE=envInt("LENSMCP_H2_RESET_RATE",1e4);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var P=Object.defineProperty;var v=(a,o)=>P(a,"name",{value:o,configurable:!0});var K=Object.defineProperty,w=v((a,o)=>K(a,"name",{value:o,configurable:!0}),"w"),M=Object.defineProperty,u=w((a,o)=>M(a,"name",{value:o,configurable:!0}),"u");Object.defineProperty(exports,"__esModule",{value:!0}),exports.LENS_HMR_REFUSAL_REPORT_MS=void 0,exports.createUpgrade=createUpgrade;const tslib_1=require("tslib"),path=tslib_1.__importStar(require("node:path")),manifest_1=require("../manifest"),discovery_1=require("./discovery"),edge_1=require("./edge"),hmr_reload_1=require("./hmr-reload"),service_keys_1=require("./service-keys");exports.LENS_HMR_REFUSAL_REPORT_MS=1e4;function accountUpgrade(a,o){const i=a.svc;if(!i||o.destroyed)return;i.inflight+=1,i.lastUsed=Date.now();let d=!1;o.once("close",()=>{d||(d=!0,i.inflight-=1,i.lastUsed=Date.now())})}v(accountUpgrade,"accountUpgrade"),w(accountUpgrade,"accountUpgrade"),u(accountUpgrade,"accountUpgrade");function createUpgrade(a){const{rt:o,auth:i,proxy:d,hooks:p,obs:S}=a,y=new Set,k=u(e=>{e.destroyed||(y.add(e),e.once("close",()=>y.delete(e)))},"track");d.proxy.on?.("open",k);const _=new WeakMap,m=new Map,R=u((e,r)=>{const s=Date.now();s-(m.get(e.frontendKey)??0)<exports.LENS_HMR_REFUSAL_REPORT_MS||(m.set(e.frontendKey,s),console.warn(`[gateway] lens HMR socket refused: ${e.frontendKey} at ${e.target} answered ${r} for a tab on ${e.host} \u2014 that tab loads but gets no hot updates; the lens runtime reloads it once if it had a socket before.`),S?.emit("warning",`lens HMR socket refused: ${e.frontendKey} (${r})`,`cluster-lens-hmr-refused:${e.frontendKey}`,{kind:"lens-hmr-refused",frontendKey:e.frontendKey,host:e.host,target:e.target,answer:r},void 0,e.busFile))},"reportRefusal");d.proxy.on?.("proxyReqWs",(e,r)=>{const s=_.get(r);if(!s)return;const c=e;c.once("upgrade",()=>{s.answered=!0}),c.once("response",g=>{s.answered=!0,R(s,`HTTP ${g.statusCode??"?"}`)})});const U=u(async(e,r,s)=>{(0,edge_1.stripOwnedHeaders)(e);const c=(0,edge_1.canonicalize)(e.url??"/");if(c===void 0){r.destroy();return}e.url=c.path+c.query;const g=(e.headers.host||"").split(":")[0],t=(0,manifest_1.matchRoute)(o.routes,g,c.policy+c.query);if(!t){r.destroy();return}(0,edge_1.resolveClientIp)(o,e);const l=p.upgradeContext(e,r,void 0);if(l.route=t,t.internal){const n=i.internal(e,t,void 0);if(!n.ok){r.destroy();return}l.caller=n.caller}else{const n=i.public(e,t,void 0,c.policy);if(!n.ok){r.destroy();return}if(l.claims=n.claims,p.has("afterAuth")&&(await p.run("afterAuth",l),l.responded()))return}const x=t.pool?o.serviceKeys[(0,service_keys_1.serviceKeyId)(t.svc?.wsKey,t.project)]:void 0;if(x&&(e.headers["x-internal-token"]=x),t.prependPrefix&&!e.url?.startsWith(t.prependPrefix)&&(e.url=t.prependPrefix+(e.url??"/")),(0,edge_1.stampForwardingHeaders)(o,e),p.has("onUpgrade")&&(await p.run("onUpgrade",l),l.responded()))return;const h=t.pool?(()=>{const n=(0,discovery_1.pickSock)(t.pool,o.scanTtlMs);return n?{socketPath:n}:void 0})():t.target;if(!h){r.destroy();return}if(t.lens&&String(e.headers["sec-websocket-protocol"]??"").split(",").map(n=>n.trim()).includes("vite-hmr")){const n=t.lens.workspaceKey?`${t.lens.workspaceKey}:${t.lens.project}`:t.lens.project;(0,hmr_reload_1.registerHmrClient)(o,n,r);const f=!t.lens.workspaceRoot||path.resolve(t.lens.workspaceRoot)===path.resolve(o.root??"");_.set(e,{frontendKey:n,host:g,target:String(h),answered:!1,...f?{}:{busFile:path.join(t.lens.workspaceRoot,".lensmcp","events.jsonl")}})}accountUpgrade(t,r),d.proxy.ws(e,r,s,{target:h,changeOrigin:!t.pool,agent:d.agentForTarget(h)},n=>{const f=_.get(e);f&&!f.answered&&R(f,n?.code??n?.message??"an error"),r.destroy()})},"run"),b=u(((e,r,s)=>{r.on("error",()=>r.destroy()),k(r),U(e,r,s).catch(()=>r.destroy())}),"listener");return b.closeTunnels=()=>{const e=[...y];for(const r of e)r.destroy();return y.clear(),e.length},b}v(createUpgrade,"createUpgrade"),w(createUpgrade,"createUpgrade"),u(createUpgrade,"createUpgrade");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var d=Object.defineProperty;var o=(e,t)=>d(e,"name",{value:t,configurable:!0});var a=Object.defineProperty,r=o((e,t)=>a(e,"name",{value:t,configurable:!0}),"r"),s=Object.defineProperty,n=r((e,t)=>s(e,"name",{value:t,configurable:!0}),"n");Object.defineProperty(exports,"__esModule",{value:!0}),exports.workspaceLogWriter=workspaceLogWriter,exports.closeWorkspaceLogs=closeWorkspaceLogs;const tslib_1=require("tslib"),fs=tslib_1.__importStar(require("node:fs")),path=tslib_1.__importStar(require("node:path")),inspector_secret_1=require("../../../inspector-secret"),fds=new Map,written=new Map,MAX_BYTES=50*1024*1024,CHECK_EVERY=1024*1024;function ensurePrivateDir(e){fs.mkdirSync(e,{recursive:!0,mode:448});try{const t=fs.statSync(e);(t.mode&63)!==0&&(typeof process.getuid!="function"||t.uid===process.getuid())&&fs.chmodSync(e,448)}catch{}}o(ensurePrivateDir,"ensurePrivateDir"),r(ensurePrivateDir,"ensurePrivateDir"),n(ensurePrivateDir,"ensurePrivateDir");function ownerOnly(e){try{fs.chmodSync(e,384)}catch{}}o(ownerOnly,"ownerOnly"),r(ownerOnly,"ownerOnly"),n(ownerOnly,"ownerOnly");function ensureFd(e){const t=fds.get(e);if(t!==void 0)return t;try{ensurePrivateDir(path.dirname(e));const c=fs.openSync(e,"a",384);return ownerOnly(e),fds.set(e,c),written.set(e,0),c}catch{return}}o(ensureFd,"ensureFd"),r(ensureFd,"ensureFd"),n(ensureFd,"ensureFd");function closeFd(e){const t=fds.get(e);if(fds.delete(e),written.delete(e),t!==void 0)try{fs.closeSync(t)}catch{}}o(closeFd,"closeFd"),r(closeFd,"closeFd"),n(closeFd,"closeFd");function rotateIfHuge(e){try{if(fs.statSync(e).size<=MAX_BYTES)return}catch{return}closeFd(e);try{fs.renameSync(e,`${e}.1`)}catch{}ownerOnly(`${e}.1`)}o(rotateIfHuge,"rotateIfHuge"),r(rotateIfHuge,"rotateIfHuge"),n(rotateIfHuge,"rotateIfHuge");function workspaceLogWriter(e){const t=path.join(e,".lensmcp","gateway.log");if(ensureFd(t)!==void 0)return c=>{const i=ensureFd(t);if(i===void 0)return;try{fs.writeSync(i,(0,inspector_secret_1.redactInspectorUrls)(c))}catch{closeFd(t);return}const u=(written.get(t)??0)+c.length;u>=CHECK_EVERY?(written.set(t,0),rotateIfHuge(t)):written.set(t,u)}}o(workspaceLogWriter,"workspaceLogWriter"),r(workspaceLogWriter,"workspaceLogWriter"),n(workspaceLogWriter,"workspaceLogWriter");function closeWorkspaceLogs(){for(const e of[...fds.keys()])closeFd(e)}o(closeWorkspaceLogs,"closeWorkspaceLogs"),r(closeWorkspaceLogs,"closeWorkspaceLogs"),n(closeWorkspaceLogs,"closeWorkspaceLogs");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var p=Object.defineProperty;var d=(e,r)=>p(e,"name",{value:r,configurable:!0});var w=Object.defineProperty,a=d((e,r)=>w(e,"name",{value:r,configurable:!0}),"a"),c=Object.defineProperty,i=a((e,r)=>c(e,"name",{value:r,configurable:!0}),"i");Object.defineProperty(exports,"__esModule",{value:!0}),exports.guestMiddlewarePolicy=guestMiddlewarePolicy,exports.findGatewayMiddleware=findGatewayMiddleware,exports.loadMiddleware=loadMiddleware,exports.createWorkspaceMiddleware=createWorkspaceMiddleware;const tslib_1=require("tslib"),fs=tslib_1.__importStar(require("node:fs")),path=tslib_1.__importStar(require("node:path"));function guestMiddlewarePolicy(e=process.env){const r=e.LENSMCP_GUEST_MIDDLEWARE;return r==="owner"||r==="none"?r:"own"}d(guestMiddlewarePolicy,"guestMiddlewarePolicy"),a(guestMiddlewarePolicy,"guestMiddlewarePolicy"),i(guestMiddlewarePolicy,"guestMiddlewarePolicy");function findGatewayMiddleware(e,r){for(const n of Object.values(r)){let o;try{o=JSON.parse(fs.readFileSync(path.join(e,n.root,"project.json"),"utf8"))}catch{continue}for(const t of Object.values(o.targets??{}))if(t?.executor==="@lensmcp/cluster:gateway"&&typeof t.options?.middleware=="string"&&t.options.middleware)return t.options.middleware}}d(findGatewayMiddleware,"findGatewayMiddleware"),a(findGatewayMiddleware,"findGatewayMiddleware"),i(findGatewayMiddleware,"findGatewayMiddleware");function loadMiddleware(e){const r=require.resolve(e);delete require.cache[r];const n=require(r),o=n.default??n;if(typeof o!="function")throw new Error(`${e} exports no function`);return o}d(loadMiddleware,"loadMiddleware"),a(loadMiddleware,"loadMiddleware"),i(loadMiddleware,"loadMiddleware");function createWorkspaceMiddleware(e){const r=e.policy??"own",n=e.load??loadMiddleware,o=new Map;return{set(t,u,l){if(t===e.ownerKey)return;if(!l){o.set(t,void 0);return}const s=path.resolve(u,l);try{o.set(t,n(s)),r==="own"&&console.log(`[gateway] '${t}' routes run its own middleware: ${s}`)}catch(f){o.set(t,void 0),console.warn(`[gateway] could not load '${t}''s middleware ${s} (${f.message}) \u2014 its routes run with NO middleware until it registers again`)}},drop(t){o.delete(t)},for(t){if(t===void 0||t===e.ownerKey||r==="owner")return e.owner;if(r!=="none")return o.get(t)}}}d(createWorkspaceMiddleware,"createWorkspaceMiddleware"),a(createWorkspaceMiddleware,"createWorkspaceMiddleware"),i(createWorkspaceMiddleware,"createWorkspaceMiddleware");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var u=Object.defineProperty;var o=(r,e)=>u(r,"name",{value:e,configurable:!0});var p=Object.defineProperty,i=o((r,e)=>p(r,"name",{value:e,configurable:!0}),"i"),c=Object.defineProperty,s=i((r,e)=>c(r,"name",{value:e,configurable:!0}),"s");Object.defineProperty(exports,"__esModule",{value:!0}),exports.processStamp=processStamp,exports.registryPath=registryPath,exports.readWorkspaces=readWorkspaces,exports.registerWorkspace=registerWorkspace,exports.unregisterWorkspace=unregisterWorkspace,exports.isWorkspaceLive=isWorkspaceLive;const tslib_1=require("tslib"),node_child_process_1=require("node:child_process"),fs=tslib_1.__importStar(require("node:fs")),os=tslib_1.__importStar(require("node:os")),path=tslib_1.__importStar(require("node:path"));function processStamp(r){if(!r||r<=0||process.platform==="win32")return"";try{return(0,node_child_process_1.execFileSync)("ps",["-p",String(r),"-o","lstart="],{encoding:"utf8",timeout:2e3,stdio:["ignore","pipe","ignore"]}).trim()}catch{return""}}o(processStamp,"processStamp"),i(processStamp,"processStamp"),s(processStamp,"processStamp");function registryPath(){const r=process.env.LENSMCP_HOME||os.homedir();return path.join(r,".lensmcp","workspaces.json")}o(registryPath,"registryPath"),i(registryPath,"registryPath"),s(registryPath,"registryPath");function readWorkspaces(r=registryPath()){try{const e=JSON.parse(fs.readFileSync(r,"utf8"));return Array.isArray(e)?e.filter(t=>!!t&&typeof t.key=="string"&&typeof t.base=="string"):[]}catch{return[]}}o(readWorkspaces,"readWorkspaces"),i(readWorkspaces,"readWorkspaces"),s(readWorkspaces,"readWorkspaces");function writeWorkspaces(r,e=registryPath()){try{fs.mkdirSync(path.dirname(e),{recursive:!0}),fs.writeFileSync(e,JSON.stringify(r,null,2))}catch{}}o(writeWorkspaces,"writeWorkspaces"),i(writeWorkspaces,"writeWorkspaces"),s(writeWorkspaces,"writeWorkspaces");function registerWorkspace(r,e=registryPath()){const t=readWorkspaces(e).filter(n=>n.key!==r.key);t.push(r),t.sort((n,a)=>n.key.localeCompare(a.key)),writeWorkspaces(t,e)}o(registerWorkspace,"registerWorkspace"),i(registerWorkspace,"registerWorkspace"),s(registerWorkspace,"registerWorkspace");function unregisterWorkspace(r,e=registryPath()){writeWorkspaces(readWorkspaces(e).filter(t=>t.key!==r),e)}o(unregisterWorkspace,"unregisterWorkspace"),i(unregisterWorkspace,"unregisterWorkspace"),s(unregisterWorkspace,"unregisterWorkspace");function isWorkspaceLive(r){if(!r.pid||r.pid<=0)return!1;try{process.kill(r.pid,0)}catch(t){if(t.code!=="EPERM")return!1}if(!r.procStamp)return!0;const e=processStamp(r.pid);return e===""?!0:e===r.procStamp}o(isWorkspaceLive,"isWorkspaceLive"),i(isWorkspaceLive,"isWorkspaceLive"),s(isWorkspaceLive,"isWorkspaceLive");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var b=Object.defineProperty;var c=(e,t)=>b(e,"name",{value:t,configurable:!0});var h=Object.defineProperty,l=c((e,t)=>h(e,"name",{value:t,configurable:!0}),"l"),u=Object.defineProperty,i=l((e,t)=>u(e,"name",{value:t,configurable:!0}),"i");Object.defineProperty(exports,"__esModule",{value:!0}),exports.SsrfBlockedError=void 0,exports.isBlockedAddress=isBlockedAddress,exports.assertFetchableUrl=assertFetchableUrl,exports.safeFetch=safeFetch,exports.pinnedLookup=pinnedLookup;const node_net_1=require("node:net"),promises_1=require("node:dns/promises");class SsrfBlockedError extends Error{static{c(this,"SsrfBlockedError")}static{l(this,"SsrfBlockedError")}static{i(this,"SsrfBlockedError")}constructor(t,o,r,s){super(`SSRF guard blocked ${o??"request"}: ${t}${r?` (${r})`:""}`,s!==void 0?{cause:s}:void 0),this.name="SsrfBlockedError",this.reason=t,this.url=o,this.address=r}}exports.SsrfBlockedError=SsrfBlockedError;function buildDefaultBlockList(){const e=new node_net_1.BlockList;return e.addSubnet("0.0.0.0",8,"ipv4"),e.addSubnet("10.0.0.0",8,"ipv4"),e.addSubnet("100.64.0.0",10,"ipv4"),e.addSubnet("127.0.0.0",8,"ipv4"),e.addSubnet("169.254.0.0",16,"ipv4"),e.addSubnet("172.16.0.0",12,"ipv4"),e.addSubnet("192.0.0.0",24,"ipv4"),e.addSubnet("192.168.0.0",16,"ipv4"),e.addSubnet("198.18.0.0",15,"ipv4"),e.addSubnet("240.0.0.0",4,"ipv4"),e.addAddress("::","ipv6"),e.addAddress("::1","ipv6"),e.addSubnet("fc00::",7,"ipv6"),e.addSubnet("fe80::",10,"ipv6"),e}c(buildDefaultBlockList,"buildDefaultBlockList"),l(buildDefaultBlockList,"buildDefaultBlockList"),i(buildDefaultBlockList,"buildDefaultBlockList");const DEFAULT_BLOCK_LIST=buildDefaultBlockList();function isBlockedAddress(e,t=DEFAULT_BLOCK_LIST){const o=(0,node_net_1.isIP)(e);return o===0?!0:t.check(e,o===6?"ipv6":"ipv4")}c(isBlockedAddress,"isBlockedAddress"),l(isBlockedAddress,"isBlockedAddress"),i(isBlockedAddress,"isBlockedAddress");const stripBrackets=i(e=>e.startsWith("[")&&e.endsWith("]")?e.slice(1,-1):e,"stripBrackets"),defaultResolve=i(async e=>(await(0,promises_1.lookup)(e,{all:!0,verbatim:!0})).map(t=>t.address),"defaultResolve");async function assertFetchableUrl(e,t={}){const o=t.allowedProtocols??["http:","https:"];let r;try{r=new URL(e)}catch{throw new SsrfBlockedError("malformed-url",String(e))}if(!o.includes(r.protocol))throw new SsrfBlockedError(`scheme-not-allowed:${r.protocol}`,r.href);if(r.username!==""||r.password!=="")throw new SsrfBlockedError("embedded-credentials",r.href);const s=stripBrackets(r.hostname);if(s==="")throw new SsrfBlockedError("missing-host",r.href);if(t.allowPrivate)return{url:r,hostname:s,addresses:(0,node_net_1.isIP)(s)?[s]:[]};const d=t.blockList??DEFAULT_BLOCK_LIST;if((0,node_net_1.isIP)(s)!==0){if(isBlockedAddress(s,d))throw new SsrfBlockedError("blocked-address",r.href,s);return{url:r,hostname:s,addresses:[s]}}const f=t.resolve??defaultResolve;let a;try{a=await f(s)}catch(n){throw new SsrfBlockedError("dns-resolution-failed",r.href,void 0,n)}if(a.length===0)throw new SsrfBlockedError("dns-no-records",r.href);for(const n of a)if(isBlockedAddress(n,d))throw new SsrfBlockedError("blocked-resolved-address",r.href,n);return{url:r,hostname:s,addresses:a}}c(assertFetchableUrl,"assertFetchableUrl"),l(assertFetchableUrl,"assertFetchableUrl"),i(assertFetchableUrl,"assertFetchableUrl");async function safeFetch(e,t={},o={}){const r=o.fetchImpl??globalThis.fetch,s=o.maxRedirects??5;let d=e;for(let f=0;;f++){const{url:a}=await assertFetchableUrl(d,o),n=await r(a,{...t,redirect:"manual"}),p=n.headers.get("location");if(n.status>=300&&n.status<400&&p){if(f>=s)throw new SsrfBlockedError("too-many-redirects",a.href);d=new URL(p,a).href;continue}return n}}c(safeFetch,"safeFetch"),l(safeFetch,"safeFetch"),i(safeFetch,"safeFetch");function pinnedLookup(e){const t=e.map(o=>({address:o,family:(0,node_net_1.isIP)(o)===6?6:4}));return(o,r,s)=>{const d=typeof r=="function"?r:s,f=typeof r=="object"&&r!==null&&r.all===!0;if(t.length===0){d(new Error(`SSRF guard: no pinned address for ${o}`));return}f?d(null,t):d(null,t[0].address,t[0].family)}}c(pinnedLookup,"pinnedLookup"),l(pinnedLookup,"pinnedLookup"),i(pinnedLookup,"pinnedLookup");
|