@camstack/system 1.2.131 → 1.2.132

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.
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_chunk = require("../../chunk-Cek0wNdY.js");
3
3
  const require_dist = require("../../dist-DqcaE-k1.js");
4
- const require_lan_http_bind = require("../../lan-http-bind-DmgpFP6_.js");
4
+ const require_tls = require("../../tls-u8QCJCFE.js");
5
5
  let node_fs_promises = require("node:fs/promises");
6
6
  let node_path = require("node:path");
7
7
  let node_os = require("node:os");
@@ -202,7 +202,7 @@ var LocalNetworkAddon = class extends require_dist.BaseAddon {
202
202
  notificationBaseUrl: "",
203
203
  viewerBaseUrls: [],
204
204
  httpEnabled: true,
205
- httpPort: require_lan_http_bind.DEFAULT_LAN_HTTP_PORT,
205
+ httpPort: require_tls.DEFAULT_LAN_HTTP_PORT,
206
206
  localHostname: ""
207
207
  });
208
208
  }
@@ -237,7 +237,7 @@ var LocalNetworkAddon = class extends require_dist.BaseAddon {
237
237
  const allow = this.config.allowedAddresses;
238
238
  const interfaces = applyAllowlist(this.enumerate(), allow);
239
239
  await this.reconcileMeshEndpoint();
240
- const httpState = require_lan_http_bind.readLanHttpState();
240
+ const httpState = require_tls.readLanHttpState();
241
241
  return buildEndpoints(interfaces, httpsPort, includeLoopback, ipv4Only, this.publicHostname, scheme, this.meshEndpoint, {
242
242
  enabled: this.config.httpEnabled !== false,
243
243
  listening: httpState.listening,
@@ -320,29 +320,29 @@ var LocalNetworkAddon = class extends require_dist.BaseAddon {
320
320
  },
321
321
  getTlsStatus: async () => this.snapshotTls(false),
322
322
  regenerateCertificate: async (_input) => {
323
- if (require_lan_http_bind.readTlsMode(this.tlsDataDir()) === "uploaded") throw new Error("Cannot regenerate an uploaded certificate — revert to generated first.");
324
- const extraSans = [...require_lan_http_bind.readExtraSans(this.tlsDataDir())];
325
- await require_lan_http_bind.reissueTlsLeaf(this.tlsDataDir(), { extraSans });
323
+ if (require_tls.readTlsMode(this.tlsDataDir()) === "uploaded") throw new Error("Cannot regenerate an uploaded certificate — revert to generated first.");
324
+ const extraSans = [...require_tls.readExtraSans(this.tlsDataDir())];
325
+ await require_tls.reissueTlsLeaf(this.tlsDataDir(), { extraSans });
326
326
  return this.snapshotTls(true);
327
327
  },
328
328
  uploadCertificate: async ({ certPem, keyPem, caPem }) => {
329
- const valid = require_lan_http_bind.validateUploadedTls(certPem, keyPem);
329
+ const valid = require_tls.validateUploadedTls(certPem, keyPem);
330
330
  if (!valid.ok) throw new Error(valid.error);
331
331
  const dir = (0, node_path.join)(this.tlsDataDir(), "tls");
332
332
  await (0, node_fs_promises.mkdir)(dir, { recursive: true });
333
333
  await (0, node_fs_promises.writeFile)((0, node_path.join)(dir, "camstack.crt"), certPem.endsWith("\n") ? certPem : `${certPem}\n`);
334
334
  await (0, node_fs_promises.writeFile)((0, node_path.join)(dir, "camstack.key"), keyPem.endsWith("\n") ? keyPem : `${keyPem}\n`, { mode: 384 });
335
335
  if (caPem && caPem.trim() !== "") await (0, node_fs_promises.writeFile)((0, node_path.join)(dir, "camstack-ca.crt"), caPem.endsWith("\n") ? caPem : `${caPem}\n`);
336
- require_lan_http_bind.writeTlsMode(this.tlsDataDir(), "uploaded");
336
+ require_tls.writeTlsMode(this.tlsDataDir(), "uploaded");
337
337
  return this.snapshotTls(true);
338
338
  },
339
339
  downloadCa: async () => {
340
340
  return { pem: this.snapshotTls(false).caCertPem ?? "" };
341
341
  },
342
342
  revertToGeneratedCertificate: async () => {
343
- require_lan_http_bind.writeTlsMode(this.tlsDataDir(), "generated");
344
- const extraSans = [...require_lan_http_bind.readExtraSans(this.tlsDataDir())];
345
- await require_lan_http_bind.ensureTlsCert(this.tlsDataDir(), { extraSans });
343
+ require_tls.writeTlsMode(this.tlsDataDir(), "generated");
344
+ const extraSans = [...require_tls.readExtraSans(this.tlsDataDir())];
345
+ await require_tls.ensureTlsCert(this.tlsDataDir(), { extraSans });
346
346
  return this.snapshotTls(true);
347
347
  }
348
348
  };
@@ -403,7 +403,7 @@ var LocalNetworkAddon = class extends require_dist.BaseAddon {
403
403
  min: 1,
404
404
  max: 65535,
405
405
  step: 1,
406
- default: require_lan_http_bind.DEFAULT_LAN_HTTP_PORT,
406
+ default: require_tls.DEFAULT_LAN_HTTP_PORT,
407
407
  showWhen: {
408
408
  field: "httpEnabled",
409
409
  equals: true
@@ -497,13 +497,13 @@ var LocalNetworkAddon = class extends require_dist.BaseAddon {
497
497
  }
498
498
  resolvedHttpPort() {
499
499
  const port = this.config.httpPort;
500
- return Number.isInteger(port) && port >= 1 && port <= 65535 ? port : require_lan_http_bind.DEFAULT_LAN_HTTP_PORT;
500
+ return Number.isInteger(port) && port >= 1 && port <= 65535 ? port : require_tls.DEFAULT_LAN_HTTP_PORT;
501
501
  }
502
502
  tlsDataDir() {
503
503
  return this.ctx.nodeDataDir ?? this.ctx.dataDir;
504
504
  }
505
505
  snapshotTls(restartRequired) {
506
- const status = require_lan_http_bind.readTlsAccessStatus(this.tlsDataDir(), restartRequired);
506
+ const status = require_tls.readTlsAccessStatus(this.tlsDataDir(), restartRequired);
507
507
  return {
508
508
  ...status,
509
509
  sans: [...status.sans]
@@ -521,15 +521,15 @@ var LocalNetworkAddon = class extends require_dist.BaseAddon {
521
521
  const httpsPort = (await this.resolveAdvertisedListenPort(null)).port;
522
522
  const httpPort = this.resolvedHttpPort();
523
523
  if (this.config.httpEnabled !== false && httpPort === httpsPort) throw new Error(`HTTP port ${httpPort} cannot equal the HTTPS listen port`);
524
- await require_lan_http_bind.applyLanHttp({
524
+ await require_tls.applyLanHttp({
525
525
  enabled: this.config.httpEnabled !== false,
526
526
  port: httpPort,
527
527
  host: "0.0.0.0"
528
528
  });
529
529
  if (hostname !== "") {
530
- require_lan_http_bind.writeExtraSans(this.tlsDataDir(), [hostname]);
531
- if (require_lan_http_bind.readTlsMode(this.tlsDataDir()) === "generated") await require_lan_http_bind.ensureTlsCert(this.tlsDataDir(), { extraSans: [hostname] });
532
- } else require_lan_http_bind.writeExtraSans(this.tlsDataDir(), []);
530
+ require_tls.writeExtraSans(this.tlsDataDir(), [hostname]);
531
+ if (require_tls.readTlsMode(this.tlsDataDir()) === "generated") await require_tls.ensureTlsCert(this.tlsDataDir(), { extraSans: [hostname] });
532
+ } else require_tls.writeExtraSans(this.tlsDataDir(), []);
533
533
  }
534
534
  /**
535
535
  * The port this hub is actually listening on, plus the provenance of the
@@ -1,5 +1,5 @@
1
1
  import { Gt as EventCategory, Y as localNetworkCapability, yt as BaseAddon } from "../../dist-BUEU7B1V.mjs";
2
- import { c as readExtraSans, d as writeExtraSans, f as writeTlsMode, g as reissueTlsLeaf, l as readTlsAccessStatus, m as ensureTlsCert, o as readLanHttpState, p as validateUploadedTls, r as applyLanHttp, t as DEFAULT_LAN_HTTP_PORT, u as readTlsMode } from "../../lan-http-bind-jKrj6OjQ.mjs";
2
+ import { S as readLanHttpState, _ as DEFAULT_LAN_HTTP_PORT, a as writeTlsMode, i as writeExtraSans, l as reissueTlsLeaf, n as readTlsAccessStatus, o as validateUploadedTls, r as readTlsMode, s as ensureTlsCert, t as readExtraSans, y as applyLanHttp } from "../../tls-CQhPGSJm.mjs";
3
3
  import { mkdir, writeFile } from "node:fs/promises";
4
4
  import { join } from "node:path";
5
5
  import * as os from "node:os";
@@ -21,3 +21,28 @@ export declare class DataPlaneRegistry {
21
21
  */
22
22
  match(addonId: string, subPath: string): DataPlaneMatch | null;
23
23
  }
24
+ /** What the hub knows about an addon when it re-evaluates its data-planes. */
25
+ export interface DataPlaneEligibility {
26
+ /** The addon still has an entry in the registry service. */
27
+ readonly hasEntry: boolean;
28
+ /** That entry is a FORKED addon — the only kind that serves a data-plane today. */
29
+ readonly isForked: boolean;
30
+ /** The child process is currently known to the child registry. */
31
+ readonly childKnown: boolean;
32
+ }
33
+ /**
34
+ * Whether an addon can serve a data-plane RIGHT NOW.
35
+ *
36
+ * Extracted as a predicate because the three ways of answering "no" used to be
37
+ * three early `return`s inside the mount path, and every one of them left the
38
+ * PREVIOUS registration standing. The registry then held a `baseUrl` pointing
39
+ * at the port of a process that no longer existed, and `/addon/:addonId/*` kept
40
+ * reverse-proxying to it — a 502 per request until a replacement child finished
41
+ * handshaking, and forever for an addon removed from disk. `unregisterAddon`
42
+ * existed for exactly this and had no call site anywhere in the repo.
43
+ *
44
+ * A `false` here means UNREGISTER, never "leave it alone". Dropping is the safe
45
+ * direction: an absent data-plane falls through to the control-route path,
46
+ * while a stale one sends live traffic at a dead socket.
47
+ */
48
+ export declare function canServeDataPlane(state: DataPlaneEligibility): boolean;
package/dist/index.d.ts CHANGED
@@ -39,10 +39,11 @@ export type { FeatureConfigReader, FeatureFlag, FeatureManifest, } from './featu
39
39
  export { FeatureManager } from './feature/feature-manager.js';
40
40
  export type { AuthenticatedFileServerOptions, ByteRange, FileResolveResult, FileServerHandle, FileServerTokenVerifier, } from './http/authenticated-file-server.js';
41
41
  export { contentTypeFor, createAuthenticatedFileServer, parseRangeHeader, parseTokenizedUrl, resolveFilePath, } from './http/authenticated-file-server.js';
42
- export type { DataPlaneMatch } from './http/data-plane-registry.js';
43
- export { DataPlaneRegistry } from './http/data-plane-registry.js';
42
+ export type { DataPlaneEligibility, DataPlaneMatch } from './http/data-plane-registry.js';
43
+ export { canServeDataPlane, DataPlaneRegistry } from './http/data-plane-registry.js';
44
44
  export type { FileDataPlaneOptions } from './http/file-data-plane.js';
45
45
  export { createFileDataPlaneHandler } from './http/file-data-plane.js';
46
+ export { allFamiliesListenHost, applyLanHttp, bindPendingLanHttp, closeLanHttp, DEFAULT_LAN_HTTP_PORT, readLanHttpState, registerLanHttpHandler, } from './http/lan-http-bind.js';
46
47
  export type { ReverseProxyOptions } from './http/reverse-proxy.js';
47
48
  export { proxyToUpstream } from './http/reverse-proxy.js';
48
49
  export type { HeapReclaimer, HeapReclaimOptions, HeapSample, HeapWatchSink, RunnerHeapWatchOptions, } from './kernel/heap-watch.js';
@@ -80,7 +81,6 @@ export { StorageLocationManager } from './storage/storage-location-manager.js';
80
81
  export type { IFileStorage, IStorageLocation, IStorageProvider as ICoreStorageProvider, IStructuredStorage, QueryFilter, StorageRecord, } from './storage/storage-manager.js';
81
82
  export { StorageManager } from './storage/storage-manager.js';
82
83
  export * from './tls/index.js';
83
- export { applyLanHttp, allFamiliesListenHost, bindPendingLanHttp, closeLanHttp, DEFAULT_LAN_HTTP_PORT, readLanHttpState, registerLanHttpHandler, } from './http/lan-http-bind.js';
84
84
  export { IntegrationRegistry } from './builtins/sqlite-storage/integration-registry.js';
85
85
  export { type EnsureAddonNativePrebuildsOptions, ensureAddonNativePrebuilds, type NativeEnsureOutcome, type NativeEnsureResult, } from './kernel/deps/ensure-addon-natives.js';
86
86
  export { type EnsureNativePrebuildsOptions, ensureNativePrebuilds, hasDotNode, NATIVE_SCAN_DEPTH, type PrebuildFetchFn, type PrebuildTarget, TRADITIONAL_NATIVE_PACKAGES, } from './kernel/deps/ensure-native-prebuilds.js';
package/dist/index.js CHANGED
@@ -25,9 +25,9 @@ const require_builtins_system_config_system_config_addon = require("./builtins/s
25
25
  require("./builtins/system-config/index.js");
26
26
  const require_builtins_winston_logging_index = require("./builtins/winston-logging/index.js");
27
27
  const require_file_data_plane = require("./file-data-plane-DO8KbxCe.js");
28
+ const require_tls$1 = require("./tls-u8QCJCFE.js");
28
29
  const require_manifest_python_deps = require("./manifest-python-deps-BTkFwAk_.js");
29
30
  const require_resource_monitor = require("./resource-monitor-CdnzxBLP.js");
30
- const require_lan_http_bind = require("./lan-http-bind-DmgpFP6_.js");
31
31
  const require_custom_action_registry = require("./custom-action-registry-jY0NOZK8.js");
32
32
  let zod = require("zod");
33
33
  let node_crypto = require("node:crypto");
@@ -373,6 +373,24 @@ var DataPlaneRegistry = class {
373
373
  };
374
374
  }
375
375
  };
376
+ /**
377
+ * Whether an addon can serve a data-plane RIGHT NOW.
378
+ *
379
+ * Extracted as a predicate because the three ways of answering "no" used to be
380
+ * three early `return`s inside the mount path, and every one of them left the
381
+ * PREVIOUS registration standing. The registry then held a `baseUrl` pointing
382
+ * at the port of a process that no longer existed, and `/addon/:addonId/*` kept
383
+ * reverse-proxying to it — a 502 per request until a replacement child finished
384
+ * handshaking, and forever for an addon removed from disk. `unregisterAddon`
385
+ * existed for exactly this and had no call site anywhere in the repo.
386
+ *
387
+ * A `false` here means UNREGISTER, never "leave it alone". Dropping is the safe
388
+ * direction: an absent data-plane falls through to the control-route path,
389
+ * while a stale one sends live traffic at a dead socket.
390
+ */
391
+ function canServeDataPlane(state) {
392
+ return state.hasEntry && state.isForked && state.childKnown;
393
+ }
376
394
  //#endregion
377
395
  //#region src/http/reverse-proxy.ts
378
396
  /**
@@ -95060,8 +95078,8 @@ exports.AddonRouteRegistry = AddonRouteRegistry;
95060
95078
  exports.AlertCenterAddon = require_builtins_alerts_alerts_addon.AlertCenterAddon;
95061
95079
  exports.ApiKeyManager = require_builtins_local_auth_local_auth_addon.ApiKeyManager;
95062
95080
  exports.AuthManager = require_builtins_local_auth_local_auth_addon.AuthManager;
95063
- exports.CA_COMMON_NAME = require_lan_http_bind.CA_COMMON_NAME;
95064
- exports.CA_VALIDITY_DAYS = require_lan_http_bind.CA_VALIDITY_DAYS;
95081
+ exports.CA_COMMON_NAME = require_tls$1.CA_COMMON_NAME;
95082
+ exports.CA_VALIDITY_DAYS = require_tls$1.CA_VALIDITY_DAYS;
95065
95083
  exports.CLUSTER_SECRET_MISMATCH_TYPE = CLUSTER_SECRET_MISMATCH_TYPE;
95066
95084
  exports.CLUSTER_SECRET_REJECTED_EXIT_CODE = CLUSTER_SECRET_REJECTED_EXIT_CODE;
95067
95085
  exports.CORE_CAP_SERVICE_NAME = CORE_CAP_SERVICE_NAME;
@@ -95078,7 +95096,7 @@ exports.ConsoleLoggingAddon = require_builtins_console_logging_index.ConsoleLogg
95078
95096
  exports.CoreBlocksAddon = require_builtins_core_blocks_core_blocks_addon.CoreBlocksAddon;
95079
95097
  exports.CustomActionRegistry = require_custom_action_registry.CustomActionRegistry;
95080
95098
  exports.DEFAULT_DATA_PATH = DEFAULT_DATA_PATH;
95081
- exports.DEFAULT_LAN_HTTP_PORT = require_lan_http_bind.DEFAULT_LAN_HTTP_PORT;
95099
+ exports.DEFAULT_LAN_HTTP_PORT = require_tls$1.DEFAULT_LAN_HTTP_PORT;
95082
95100
  exports.DEVICE_SETTINGS_CONTRIBUTION_METHODS = require_dist.DEVICE_SETTINGS_CONTRIBUTION_METHODS;
95083
95101
  exports.DEVICE_STATUS_METHOD = require_dist.DEVICE_STATUS_METHOD;
95084
95102
  exports.DataPlaneRegistry = DataPlaneRegistry;
@@ -95109,7 +95127,7 @@ exports.HubNodeRegistry = HubNodeRegistry;
95109
95127
  exports.INFRA_CAPABILITIES = INFRA_CAPABILITIES;
95110
95128
  exports.IntegrationRegistry = IntegrationRegistry;
95111
95129
  exports.JobJournal = JobJournal;
95112
- exports.LEAF_RENEWAL_WINDOW_DAYS = require_lan_http_bind.LEAF_RENEWAL_WINDOW_DAYS;
95130
+ exports.LEAF_RENEWAL_WINDOW_DAYS = require_tls$1.LEAF_RENEWAL_WINDOW_DAYS;
95113
95131
  exports.LifecycleJobEngine = LifecycleJobEngine;
95114
95132
  exports.LifecycleStateMachine = LifecycleStateMachine;
95115
95133
  exports.LivenessMonitorAddon = require_builtins_liveness_monitor_liveness_monitor_addon.LivenessMonitorAddon;
@@ -95120,7 +95138,7 @@ exports.LogManager = LogManager;
95120
95138
  exports.LogRingBuffer = LogRingBuffer;
95121
95139
  exports.LokiDestination = require_builtins_loki_logging_index.LokiDestination$1;
95122
95140
  exports.LokiLoggingAddon = require_builtins_loki_logging_index.LokiLoggingAddon$1;
95123
- exports.MAX_LEAF_VALIDITY_DAYS = require_lan_http_bind.MAX_LEAF_VALIDITY_DAYS;
95141
+ exports.MAX_LEAF_VALIDITY_DAYS = require_tls$1.MAX_LEAF_VALIDITY_DAYS;
95124
95142
  exports.METHOD_ACCESS_MAP = require_dist.METHOD_ACCESS_MAP;
95125
95143
  exports.ModelDownloadService = require_file_data_plane.ModelDownloadService;
95126
95144
  exports.NATIVE_PROVIDER_SERVICE_INFIX = require_manifest_python_deps.NATIVE_PROVIDER_SERVICE_INFIX;
@@ -95146,7 +95164,7 @@ exports.ReadinessRegistry = require_dist.ReadinessRegistry;
95146
95164
  exports.ReadinessTimeoutError = require_dist.ReadinessTimeoutError;
95147
95165
  exports.ReplEngine = ReplEngine;
95148
95166
  exports.RingBuffer = RingBuffer;
95149
- exports.SERVER_AUTH_OID = require_lan_http_bind.SERVER_AUTH_OID;
95167
+ exports.SERVER_AUTH_OID = require_tls$1.SERVER_AUTH_OID;
95150
95168
  exports.ScopedLogger = ScopedLogger;
95151
95169
  exports.ScopedTokenManager = require_builtins_local_auth_local_auth_addon.ScopedTokenManager;
95152
95170
  exports.SocketChannel = require_manifest_python_deps.SocketChannel;
@@ -95170,9 +95188,9 @@ exports.WinstonLoggingAddon = require_builtins_winston_logging_index.WinstonLogg
95170
95188
  exports.__resetCapUsageRegistryForTests = require_manifest_python_deps.__resetCapUsageRegistryForTests;
95171
95189
  exports.adaptBrokerToCluster = require_manifest_python_deps.adaptBrokerToCluster;
95172
95190
  exports.addonSettingsCapability = require_dist.addonSettingsCapability;
95173
- exports.allFamiliesListenHost = require_lan_http_bind.allFamiliesListenHost;
95174
- exports.applyLanHttp = require_lan_http_bind.applyLanHttp;
95175
- exports.bindPendingLanHttp = require_lan_http_bind.bindPendingLanHttp;
95191
+ exports.allFamiliesListenHost = require_tls$1.allFamiliesListenHost;
95192
+ exports.applyLanHttp = require_tls$1.applyLanHttp;
95193
+ exports.bindPendingLanHttp = require_tls$1.bindPendingLanHttp;
95176
95194
  exports.bootstrapSchema = bootstrapSchema;
95177
95195
  exports.brokerCallForCap = require_manifest_python_deps.brokerCallForCap;
95178
95196
  exports.brokerTransportLink = require_manifest_python_deps.brokerTransportLink;
@@ -95192,6 +95210,7 @@ exports.buildUdsNativeCapProxy = require_manifest_python_deps.buildUdsNativeCapP
95192
95210
  exports.builderMountedCapNames = builderMountedCapNames;
95193
95211
  exports.callRegisterNodeWithRetry = callRegisterNodeWithRetry;
95194
95212
  exports.callWithServiceDiscovery = require_manifest_python_deps.callWithServiceDiscovery;
95213
+ exports.canServeDataPlane = canServeDataPlane;
95195
95214
  exports.capActionName = require_manifest_python_deps.capActionName;
95196
95215
  exports.capActionSuffix = require_manifest_python_deps.capActionSuffix;
95197
95216
  exports.capBareAction = require_manifest_python_deps.capBareAction;
@@ -95199,10 +95218,10 @@ exports.capServiceName = require_manifest_python_deps.capServiceName;
95199
95218
  exports.classifyAddonDir = classifyAddonDir;
95200
95219
  exports.classifyCapRoute = require_manifest_python_deps.classifyCapRoute;
95201
95220
  exports.clearPendingRestart = clearPendingRestart;
95202
- exports.closeLanHttp = require_lan_http_bind.closeLanHttp;
95221
+ exports.closeLanHttp = require_tls$1.closeLanHttp;
95203
95222
  exports.clusterEventTopic = require_manifest_python_deps.clusterEventTopic;
95204
95223
  exports.clusterSecretMatches = clusterSecretMatches;
95205
- exports.collectCertIdentity = require_lan_http_bind.collectCertIdentity;
95224
+ exports.collectCertIdentity = require_tls$1.collectCertIdentity;
95206
95225
  exports.collectModelFiles = require_file_data_plane.collectModelFiles;
95207
95226
  exports.contentTypeFor = require_file_data_plane.contentTypeFor;
95208
95227
  exports.copyDirRecursive = copyDirRecursive;
@@ -95269,8 +95288,8 @@ Object.defineProperty(exports, "ensurePython", {
95269
95288
  return _camstack_types_node.ensurePython;
95270
95289
  }
95271
95290
  });
95272
- exports.ensureTlsCert = require_lan_http_bind.ensureTlsCert;
95273
- exports.evaluateExistingCert = require_lan_http_bind.evaluateExistingCert;
95291
+ exports.ensureTlsCert = require_tls$1.ensureTlsCert;
95292
+ exports.evaluateExistingCert = require_tls$1.evaluateExistingCert;
95274
95293
  exports.expandCapMethods = require_dist.expandCapMethods;
95275
95294
  exports.fetchJson = require_file_data_plane.fetchJson;
95276
95295
  Object.defineProperty(exports, "findInPath", {
@@ -95335,7 +95354,7 @@ exports.isInfraCapability = isInfraCapability;
95335
95354
  exports.isModelDownloaded = require_file_data_plane.isModelDownloaded;
95336
95355
  exports.isSourceNewer = isSourceNewer;
95337
95356
  exports.isolatedBuiltinPhase = isolatedBuiltinPhase;
95338
- exports.loadTlsCert = require_lan_http_bind.loadTlsCert;
95357
+ exports.loadTlsCert = require_tls$1.loadTlsCert;
95339
95358
  exports.localEndpointPath = require_manifest_python_deps.localEndpointPath;
95340
95359
  exports.localProviderLink = require_manifest_python_deps.localProviderLink;
95341
95360
  exports.mountNativeCapService = require_manifest_python_deps.mountNativeCapService;
@@ -95345,15 +95364,15 @@ exports.parseTokenizedUrl = require_file_data_plane.parseTokenizedUrl;
95345
95364
  exports.partitionIsolatedBuiltinIds = partitionIsolatedBuiltinIds;
95346
95365
  exports.proxyToUpstream = proxyToUpstream;
95347
95366
  exports.quarantineAddonResidue = quarantineAddonResidue;
95348
- exports.readExtraSans = require_lan_http_bind.readExtraSans;
95349
- exports.readLanHttpState = require_lan_http_bind.readLanHttpState;
95367
+ exports.readExtraSans = require_tls$1.readExtraSans;
95368
+ exports.readLanHttpState = require_tls$1.readLanHttpState;
95350
95369
  exports.readPendingRestart = readPendingRestart;
95351
- exports.readTlsAccessStatus = require_lan_http_bind.readTlsAccessStatus;
95352
- exports.readTlsMode = require_lan_http_bind.readTlsMode;
95370
+ exports.readTlsAccessStatus = require_tls$1.readTlsAccessStatus;
95371
+ exports.readTlsMode = require_tls$1.readTlsMode;
95353
95372
  exports.readinessKey = require_dist.readinessKey;
95354
95373
  exports.registerEventBusService = require_manifest_python_deps.registerEventBusService;
95355
- exports.registerLanHttpHandler = require_lan_http_bind.registerLanHttpHandler;
95356
- exports.reissueTlsLeaf = require_lan_http_bind.reissueTlsLeaf;
95374
+ exports.registerLanHttpHandler = require_tls$1.registerLanHttpHandler;
95375
+ exports.reissueTlsLeaf = require_tls$1.reissueTlsLeaf;
95357
95376
  exports.resolveFilePath = require_file_data_plane.resolveFilePath;
95358
95377
  exports.resolveHwAccel = require_manifest_python_deps.resolveHwAccel;
95359
95378
  exports.resolveNpmInvocation = require_manifest_python_deps.resolveNpmInvocation;
@@ -95375,8 +95394,8 @@ exports.stripCamstackDeps = stripCamstackDeps;
95375
95394
  exports.subscribePassthrough = require_manifest_python_deps.subscribePassthrough;
95376
95395
  exports.udsChildLogToWorkerEntry = require_manifest_python_deps.udsChildLogToWorkerEntry;
95377
95396
  exports.validateProviderRegistrations = require_manifest_python_deps.validateProviderRegistrations;
95378
- exports.validateUploadedTls = require_lan_http_bind.validateUploadedTls;
95397
+ exports.validateUploadedTls = require_tls$1.validateUploadedTls;
95379
95398
  exports.waitUntilReady = waitUntilReady;
95380
- exports.writeExtraSans = require_lan_http_bind.writeExtraSans;
95399
+ exports.writeExtraSans = require_tls$1.writeExtraSans;
95381
95400
  exports.writePendingRestart = writePendingRestart;
95382
- exports.writeTlsMode = require_lan_http_bind.writeTlsMode;
95401
+ exports.writeTlsMode = require_tls$1.writeTlsMode;
package/dist/index.mjs CHANGED
@@ -24,9 +24,9 @@ import { SystemConfigAddon } from "./builtins/system-config/system-config.addon.
24
24
  import "./builtins/system-config/index.mjs";
25
25
  import { WinstonDestination, WinstonLoggingAddon } from "./builtins/winston-logging/index.mjs";
26
26
  import { a as parseTokenizedUrl, c as collectModelFiles, d as downloadModel, f as ensureModel, h as isModelDownloaded, i as parseRangeHeader, l as deleteModelFromDisk, m as getModelFilePath, n as contentTypeFor, o as resolveFilePath, p as fetchJson, r as createAuthenticatedFileServer, s as ModelDownloadService, t as createFileDataPlaneHandler, u as downloadFile } from "./file-data-plane-BhKdxJgf.mjs";
27
+ import { C as registerLanHttpHandler, S as readLanHttpState, _ as DEFAULT_LAN_HTTP_PORT, a as writeTlsMode, b as bindPendingLanHttp, c as loadTlsCert, d as collectCertIdentity, f as CA_VALIDITY_DAYS, g as evaluateExistingCert, h as SERVER_AUTH_OID, i as writeExtraSans, l as reissueTlsLeaf, m as MAX_LEAF_VALIDITY_DAYS, n as readTlsAccessStatus, o as validateUploadedTls, p as LEAF_RENEWAL_WINDOW_DAYS, r as readTlsMode, s as ensureTlsCert, t as readExtraSans, u as CA_COMMON_NAME, v as allFamiliesListenHost, x as closeLanHttp, y as applyLanHttp } from "./tls-CQhPGSJm.mjs";
27
28
  import { $ as buildNativeCapProxy, A as createHubCapForwardService, At as buildHeapSample, B as AGENT_CAP_FWD_ACTION, C as brokerTransportLink, Ct as runNpm, D as localProviderLink, Dt as HEAP_WATCH_INTERVAL_MS, E as ipcParentLink, Et as HEAP_RECLAIM_TRIGGER_MB, F as createUdsLogger, Ft as strandedMb, G as callWithServiceDiscovery, H as CapRouteResolver, I as createUdsLoggerWithControl, J as UdsLocalTransportServer, K as createLocalTransport, L as LocalChildClient, M as createUdsEventBridge, Mt as shouldReclaim, N as createUdsEventBus, Nt as startHeapWatch, O as HUB_CAP_FWD_ACTION, Ot as HEAP_WATCH_WARN_RATIO, P as udsChildLogToWorkerEntry, Pt as startRunnerHeapWatch, Q as encodeFrame, R as LocalChildRegistry, S as brokerCallForCap, St as resolveNpmInvocation, T as ipcChildLink, Tt as HEAP_RECLAIM_MIN_INTERVAL_MS, U as CapRouteError, V as AGENT_CAP_FWD_SERVICE, W as classifyCapRoute, X as localEndpointPath, Y as SocketChannel, Z as FrameDecoder, _ as createKernelHwAccel, _t as CapabilityHandle, a as getWorkerDeviceRegistry, b as __resetCapUsageRegistryForTests, bt as installManifestNativeDeps, c as setHubConnected, ct as NATIVE_PROVIDER_SERVICE_INFIX, d as getBrokerEventBus, dt as capBareAction, et as buildUdsNativeCapProxy, f as getMoleculerEventStats, ft as capServiceName, g as AddonDepsManager, gt as DeviceRegistry, h as subscribePassthrough, ht as serializeTypedArrays, i as createUdsAddonContext, it as mountNativeCapService, j as createParentUnownedCallHandler, jt as createV8Reclaimer, k as HUB_CAP_FWD_SERVICE, kt as RUNNER_HEAP_WATCH_INTERVAL_MS, l as EVENT_TOPIC_PREFIX, lt as capActionName, m as setNodeEventInterest, mt as deserializeTypedArrays, n as adaptBrokerToCluster, o as getOrInitReadinessRegistry, ot as createAddonService, p as registerEventBusService, pt as parseCapAction, q as UdsLocalTransportClient, r as createAddonContext, s as getOrInitReadinessRegistryForClient, st as validateProviderRegistrations, t as installManifestPythonDeps, tt as createBrokerDeviceManagerApi, u as clusterEventTopic, ut as capActionSuffix, v as resolveHwAccel, vt as CapabilityUnavailableError, w as buildLinkChain, wt as createAddonDataPlaneFacility, x as getCapUsageRegistry, xt as resolveAddonClass, y as CapUsageRegistry, yt as copyBundledNativeModules, z as UDS_NO_ROUTE_PREFIX } from "./manifest-python-deps-Dmcnb287.mjs";
28
29
  import { n as getSinglePidStats, t as getPidStats } from "./resource-monitor-BWmQ5i-o.mjs";
29
- import { C as evaluateExistingCert, S as SERVER_AUTH_OID, _ as CA_COMMON_NAME, a as closeLanHttp, b as LEAF_RENEWAL_WINDOW_DAYS, c as readExtraSans, d as writeExtraSans, f as writeTlsMode, g as reissueTlsLeaf, h as loadTlsCert, i as bindPendingLanHttp, l as readTlsAccessStatus, m as ensureTlsCert, n as allFamiliesListenHost, o as readLanHttpState, p as validateUploadedTls, r as applyLanHttp, s as registerLanHttpHandler, t as DEFAULT_LAN_HTTP_PORT, u as readTlsMode, v as collectCertIdentity, x as MAX_LEAF_VALIDITY_DAYS, y as CA_VALIDITY_DAYS } from "./lan-http-bind-jKrj6OjQ.mjs";
30
30
  import { t as CustomActionRegistry } from "./custom-action-registry-F__gp_VX.mjs";
31
31
  import { z } from "zod";
32
32
  import { createHash, randomUUID, timingSafeEqual } from "node:crypto";
@@ -366,6 +366,24 @@ var DataPlaneRegistry = class {
366
366
  };
367
367
  }
368
368
  };
369
+ /**
370
+ * Whether an addon can serve a data-plane RIGHT NOW.
371
+ *
372
+ * Extracted as a predicate because the three ways of answering "no" used to be
373
+ * three early `return`s inside the mount path, and every one of them left the
374
+ * PREVIOUS registration standing. The registry then held a `baseUrl` pointing
375
+ * at the port of a process that no longer existed, and `/addon/:addonId/*` kept
376
+ * reverse-proxying to it — a 502 per request until a replacement child finished
377
+ * handshaking, and forever for an addon removed from disk. `unregisterAddon`
378
+ * existed for exactly this and had no call site anywhere in the repo.
379
+ *
380
+ * A `false` here means UNREGISTER, never "leave it alone". Dropping is the safe
381
+ * direction: an absent data-plane falls through to the control-route path,
382
+ * while a stale one sends live traffic at a dead socket.
383
+ */
384
+ function canServeDataPlane(state) {
385
+ return state.hasEntry && state.isForked && state.childKnown;
386
+ }
369
387
  //#endregion
370
388
  //#region src/http/reverse-proxy.ts
371
389
  /**
@@ -95038,4 +95056,4 @@ var LifecycleJobEngine = class {
95038
95056
  }
95039
95057
  };
95040
95058
  //#endregion
95041
- export { AGENT_CAP_FWD_ACTION, AGENT_CAP_FWD_SERVICE, AGENT_READINESS_SERVICE_NAME, ALL_CAPABILITY_DEFINITIONS, AddonApiFactory, AddonDepsManager, AddonEngineManager, AddonHealthMonitor, AddonInstaller, AddonLoader, AddonManifest, AddonRouteRegistry, AlertCenterAddon, ApiKeyManager, AuthManager, CA_COMMON_NAME, CA_VALIDITY_DAYS, CLUSTER_SECRET_MISMATCH_TYPE, CLUSTER_SECRET_REJECTED_EXIT_CODE, CORE_CAP_SERVICE_NAME, CapRouteError, CapRouteResolver, CapUsageRegistry, CapabilityHandle, CapabilityRegistry, CapabilityUnavailableError, ConfigManager, ConfigStore, ConsoleDestination, ConsoleLoggingAddon, CoreBlocksAddon, CustomActionRegistry, DEFAULT_DATA_PATH, DEFAULT_LAN_HTTP_PORT, DEVICE_SETTINGS_CONTRIBUTION_METHODS, DEVICE_STATUS_METHOD, DataPlaneRegistry, DeviceManagerAddon, DeviceRegistry, DeviceStore, EVENT_TOPIC_PREFIX, EngineManagerResolver, EventBus, FeatureManager, FilesystemStorageAddon, FilesystemStorageProvider, FrameDecoder, FsStorageBackend, HEALTH_MONITOR_GRACE_PERIOD_MS, HEALTH_MONITOR_RETRY_INTERVALS_MS, HEALTH_MONITOR_TICK_MS, HEAP_RECLAIM_MIN_INTERVAL_MS, HEAP_RECLAIM_TRIGGER_MB, HEAP_WATCH_INTERVAL_MS, HEAP_WATCH_WARN_RATIO, HUB_CAP_FWD_ACTION, HUB_CAP_FWD_SERVICE, HubForwarderAddon, HubForwarderDestination, HubLogForwarder, HubNodeRegistry, INFRA_CAPABILITIES, IntegrationRegistry, JobJournal, LEAF_RENEWAL_WINDOW_DAYS, LifecycleJobEngine, LifecycleStateMachine, LivenessMonitorAddon, LocalAuthAddon, LocalChildClient, LocalChildRegistry, LogManager, LogRingBuffer, LokiDestination, LokiLoggingAddon, MAX_LEAF_VALIDITY_DAYS, METHOD_ACCESS_MAP, ModelDownloadService, NATIVE_PROVIDER_SERVICE_INFIX, NATIVE_SCAN_DEPTH, NativeMetricsAddon, NativeMetricsProvider, NetworkQualityTracker, NotificationService, PYTHON_VERSION, PipelineRunner, PipelineValidator, PythonEnvManager, QUARANTINE_DIRNAME, RESTART_MARKER_FILE, RUNNER_HEAP_WATCH_INTERVAL_MS, RUNTIME_DEFAULTS, ReadinessRegistry, ReadinessTimeoutError, ReplEngine, RingBuffer, SERVER_AUTH_OID, ScopedLogger, ScopedTokenManager, SocketChannel, SqliteSettingsAddon, SqliteSettingsBackend, StagingArea, StorageLocationManager, StorageManager, StorageOrchestratorAddon, StorageOrchestratorService, SystemConfigAddon, SystemEventBus, TRADITIONAL_NATIVE_PACKAGES, ToastService, UDS_NO_ROUTE_PREFIX, UdsLocalTransportClient, UdsLocalTransportServer, UserManager, WinstonDestination, WinstonLoggingAddon, __resetCapUsageRegistryForTests, adaptBrokerToCluster, addonSettingsCapability, allFamiliesListenHost, applyLanHttp, bindPendingLanHttp, bootstrapSchema, brokerCallForCap, brokerTransportLink, buildBinaryPath, buildCapRouters, buildHeapSample, buildLinkChain, buildNativeCapProxy, buildNodeManifest, buildStorageLocationRegistry, buildUdsNativeCapProxy, builderMountedCapNames, callRegisterNodeWithRetry, callWithServiceDiscovery, capActionName, capActionSuffix, capBareAction, capServiceName, classifyAddonDir, classifyCapRoute, clearPendingRestart, closeLanHttp, clusterEventTopic, clusterSecretMatches, collectCertIdentity, collectModelFiles, contentTypeFor, copyDirRecursive, copyExtraFileDirs, createAddonContext, createAddonDataPlaneFacility, createAddonService, createAuthenticatedFileServer, createBroker, createBrokerDeviceManagerApi, createCoreCapService, createDoorSettingsView, createFileDataPlaneHandler, createHubCapForwardService, createHubService, createKernelHwAccel, createLocalTransport, createParentUnownedCallHandler, createProcessService, createReadinessService, createReadinessServiceForRegistry, createScopedProcessManager, createStreamProbeBrokerService, createUdsAddonContext, createUdsEventBridge, createUdsEventBus, createUdsLogger, createUdsLoggerWithControl, createV8Reclaimer, deleteModelFromDisk, deriveAgentListenPort, describeProviderKindDrift, detectWorkspacePackagesDir, downloadBinary, downloadFile, downloadModel, emitDownForOwnedCaps, encodeFrame, ensureAddonNativePrebuilds, ensureBinary, ensureDir, ensureFfmpeg, ensureLibraryBuilt, ensureModel, ensureNativePrebuilds, ensurePython, ensureTlsCert, evaluateExistingCert, expandCapMethods, fetchJson, findInPath, formatLogLine, getBrokerEventBus, getCapUsageRegistry, getFfmpegDownloadUrl, getModelFilePath, getMoleculerEventStats, getOrInitReadinessRegistry, getOrInitReadinessRegistryForClient, getPidStats, getPlatformInfo, getPythonDownloadUrl, getRestartMarkerPath, getSinglePidStats, getWorkerDeviceRegistry, hasDotNode, hashClusterSecret, installManifestNativeDeps, installManifestPythonDeps, installPackageFromNpm, installPythonPackages, installPythonRequirements, ipcChildLink, ipcParentLink, isAddonDeploySource, isArrayOutputSchema, isClusterSecretMismatchError, isCollectionArrayMethod, isInfraCapability, isModelDownloaded, isSourceNewer, isolatedBuiltinPhase, loadTlsCert, localEndpointPath, localProviderLink, mountNativeCapService, parseCapAction, parseRangeHeader, parseTokenizedUrl, partitionIsolatedBuiltinIds, proxyToUpstream, quarantineAddonResidue, readExtraSans, readLanHttpState, readPendingRestart, readTlsAccessStatus, readTlsMode, readinessKey, registerEventBusService, registerLanHttpHandler, reissueTlsLeaf, resolveFilePath, resolveHwAccel, resolveNpmInvocation, runHubAddonBoot, runNpm, scheduleSelfRestart, scopeKey, scopesAllowAddon, scopesAllowDeviceCap, selectAddonResidue, serializeTypedArrays, setHubConnected, setNodeEventInterest, shouldReclaim, startHeapWatch, startRunnerHeapWatch, strandedMb, stripCamstackDeps, subscribePassthrough, udsChildLogToWorkerEntry, validateProviderRegistrations, validateUploadedTls, waitUntilReady, writeExtraSans, writePendingRestart, writeTlsMode };
95059
+ export { AGENT_CAP_FWD_ACTION, AGENT_CAP_FWD_SERVICE, AGENT_READINESS_SERVICE_NAME, ALL_CAPABILITY_DEFINITIONS, AddonApiFactory, AddonDepsManager, AddonEngineManager, AddonHealthMonitor, AddonInstaller, AddonLoader, AddonManifest, AddonRouteRegistry, AlertCenterAddon, ApiKeyManager, AuthManager, CA_COMMON_NAME, CA_VALIDITY_DAYS, CLUSTER_SECRET_MISMATCH_TYPE, CLUSTER_SECRET_REJECTED_EXIT_CODE, CORE_CAP_SERVICE_NAME, CapRouteError, CapRouteResolver, CapUsageRegistry, CapabilityHandle, CapabilityRegistry, CapabilityUnavailableError, ConfigManager, ConfigStore, ConsoleDestination, ConsoleLoggingAddon, CoreBlocksAddon, CustomActionRegistry, DEFAULT_DATA_PATH, DEFAULT_LAN_HTTP_PORT, DEVICE_SETTINGS_CONTRIBUTION_METHODS, DEVICE_STATUS_METHOD, DataPlaneRegistry, DeviceManagerAddon, DeviceRegistry, DeviceStore, EVENT_TOPIC_PREFIX, EngineManagerResolver, EventBus, FeatureManager, FilesystemStorageAddon, FilesystemStorageProvider, FrameDecoder, FsStorageBackend, HEALTH_MONITOR_GRACE_PERIOD_MS, HEALTH_MONITOR_RETRY_INTERVALS_MS, HEALTH_MONITOR_TICK_MS, HEAP_RECLAIM_MIN_INTERVAL_MS, HEAP_RECLAIM_TRIGGER_MB, HEAP_WATCH_INTERVAL_MS, HEAP_WATCH_WARN_RATIO, HUB_CAP_FWD_ACTION, HUB_CAP_FWD_SERVICE, HubForwarderAddon, HubForwarderDestination, HubLogForwarder, HubNodeRegistry, INFRA_CAPABILITIES, IntegrationRegistry, JobJournal, LEAF_RENEWAL_WINDOW_DAYS, LifecycleJobEngine, LifecycleStateMachine, LivenessMonitorAddon, LocalAuthAddon, LocalChildClient, LocalChildRegistry, LogManager, LogRingBuffer, LokiDestination, LokiLoggingAddon, MAX_LEAF_VALIDITY_DAYS, METHOD_ACCESS_MAP, ModelDownloadService, NATIVE_PROVIDER_SERVICE_INFIX, NATIVE_SCAN_DEPTH, NativeMetricsAddon, NativeMetricsProvider, NetworkQualityTracker, NotificationService, PYTHON_VERSION, PipelineRunner, PipelineValidator, PythonEnvManager, QUARANTINE_DIRNAME, RESTART_MARKER_FILE, RUNNER_HEAP_WATCH_INTERVAL_MS, RUNTIME_DEFAULTS, ReadinessRegistry, ReadinessTimeoutError, ReplEngine, RingBuffer, SERVER_AUTH_OID, ScopedLogger, ScopedTokenManager, SocketChannel, SqliteSettingsAddon, SqliteSettingsBackend, StagingArea, StorageLocationManager, StorageManager, StorageOrchestratorAddon, StorageOrchestratorService, SystemConfigAddon, SystemEventBus, TRADITIONAL_NATIVE_PACKAGES, ToastService, UDS_NO_ROUTE_PREFIX, UdsLocalTransportClient, UdsLocalTransportServer, UserManager, WinstonDestination, WinstonLoggingAddon, __resetCapUsageRegistryForTests, adaptBrokerToCluster, addonSettingsCapability, allFamiliesListenHost, applyLanHttp, bindPendingLanHttp, bootstrapSchema, brokerCallForCap, brokerTransportLink, buildBinaryPath, buildCapRouters, buildHeapSample, buildLinkChain, buildNativeCapProxy, buildNodeManifest, buildStorageLocationRegistry, buildUdsNativeCapProxy, builderMountedCapNames, callRegisterNodeWithRetry, callWithServiceDiscovery, canServeDataPlane, capActionName, capActionSuffix, capBareAction, capServiceName, classifyAddonDir, classifyCapRoute, clearPendingRestart, closeLanHttp, clusterEventTopic, clusterSecretMatches, collectCertIdentity, collectModelFiles, contentTypeFor, copyDirRecursive, copyExtraFileDirs, createAddonContext, createAddonDataPlaneFacility, createAddonService, createAuthenticatedFileServer, createBroker, createBrokerDeviceManagerApi, createCoreCapService, createDoorSettingsView, createFileDataPlaneHandler, createHubCapForwardService, createHubService, createKernelHwAccel, createLocalTransport, createParentUnownedCallHandler, createProcessService, createReadinessService, createReadinessServiceForRegistry, createScopedProcessManager, createStreamProbeBrokerService, createUdsAddonContext, createUdsEventBridge, createUdsEventBus, createUdsLogger, createUdsLoggerWithControl, createV8Reclaimer, deleteModelFromDisk, deriveAgentListenPort, describeProviderKindDrift, detectWorkspacePackagesDir, downloadBinary, downloadFile, downloadModel, emitDownForOwnedCaps, encodeFrame, ensureAddonNativePrebuilds, ensureBinary, ensureDir, ensureFfmpeg, ensureLibraryBuilt, ensureModel, ensureNativePrebuilds, ensurePython, ensureTlsCert, evaluateExistingCert, expandCapMethods, fetchJson, findInPath, formatLogLine, getBrokerEventBus, getCapUsageRegistry, getFfmpegDownloadUrl, getModelFilePath, getMoleculerEventStats, getOrInitReadinessRegistry, getOrInitReadinessRegistryForClient, getPidStats, getPlatformInfo, getPythonDownloadUrl, getRestartMarkerPath, getSinglePidStats, getWorkerDeviceRegistry, hasDotNode, hashClusterSecret, installManifestNativeDeps, installManifestPythonDeps, installPackageFromNpm, installPythonPackages, installPythonRequirements, ipcChildLink, ipcParentLink, isAddonDeploySource, isArrayOutputSchema, isClusterSecretMismatchError, isCollectionArrayMethod, isInfraCapability, isModelDownloaded, isSourceNewer, isolatedBuiltinPhase, loadTlsCert, localEndpointPath, localProviderLink, mountNativeCapService, parseCapAction, parseRangeHeader, parseTokenizedUrl, partitionIsolatedBuiltinIds, proxyToUpstream, quarantineAddonResidue, readExtraSans, readLanHttpState, readPendingRestart, readTlsAccessStatus, readTlsMode, readinessKey, registerEventBusService, registerLanHttpHandler, reissueTlsLeaf, resolveFilePath, resolveHwAccel, resolveNpmInvocation, runHubAddonBoot, runNpm, scheduleSelfRestart, scopeKey, scopesAllowAddon, scopesAllowDeviceCap, selectAddonResidue, serializeTypedArrays, setHubConnected, setNodeEventInterest, shouldReclaim, startHeapWatch, startRunnerHeapWatch, strandedMb, stripCamstackDeps, subscribePassthrough, udsChildLogToWorkerEntry, validateProviderRegistrations, validateUploadedTls, waitUntilReady, writeExtraSans, writePendingRestart, writeTlsMode };
@@ -8,6 +8,139 @@ import { tmpdir } from "node:os";
8
8
  import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
9
9
  import { createServer } from "node:http";
10
10
  import { isIP } from "node:net";
11
+ //#region src/http/lan-http-bind.ts
12
+ /**
13
+ * Second HTTP listener that shares the hub's existing request handler.
14
+ *
15
+ * Fastify is one protocol per instance; HTTPS stays on :4443 and this
16
+ * binds a plain `http.Server` that emits `request` AND `upgrade` onto the
17
+ * same handler graph (tRPC HTTP, cookies, data-plane, static, tRPC WS).
18
+ *
19
+ * Forwarding only `request` is not enough: the viewer speaks tRPC exclusively
20
+ * over WebSocket (`wsLink`). `/health` wins the LAN race, then `ws://…/trpc`
21
+ * hangs because nobody handles the upgrade on this socket.
22
+ */
23
+ var DEFAULT_HTTP_PORT = 4480;
24
+ var handlers = null;
25
+ var server = null;
26
+ var pending = null;
27
+ var state = {
28
+ listening: false,
29
+ error: null,
30
+ port: DEFAULT_HTTP_PORT
31
+ };
32
+ var boundRequestedHost = null;
33
+ var DEFAULT_LAN_HTTP_PORT = DEFAULT_HTTP_PORT;
34
+ /** Map "all IPv4" to dual-stack IPv6 (`::`, ipv6Only false) so IPv4 still works. */
35
+ function allFamiliesListenHost(host) {
36
+ if (host === "0.0.0.0" || host === "*" || host === "") return {
37
+ host: "::",
38
+ ipv6Only: false
39
+ };
40
+ return {
41
+ host,
42
+ ipv6Only: false
43
+ };
44
+ }
45
+ function registerLanHttpHandler(next) {
46
+ handlers = next;
47
+ }
48
+ function readLanHttpState() {
49
+ return state;
50
+ }
51
+ async function applyLanHttp(options) {
52
+ pending = options;
53
+ if (!options.enabled) {
54
+ await closeLanHttp();
55
+ state = {
56
+ listening: false,
57
+ error: null,
58
+ port: options.port
59
+ };
60
+ return state;
61
+ }
62
+ if (handlers === null) {
63
+ state = {
64
+ listening: false,
65
+ error: "HTTP listener is not registered yet",
66
+ port: options.port
67
+ };
68
+ return state;
69
+ }
70
+ if (server !== null && state.listening && (options.port === 0 || state.port === options.port) && boundRequestedHost === options.host) return state;
71
+ await closeLanHttp();
72
+ try {
73
+ const bound = await listenHttp(options.port, options.host, handlers);
74
+ server = bound;
75
+ boundRequestedHost = options.host;
76
+ const addr = bound.address();
77
+ state = {
78
+ listening: true,
79
+ error: null,
80
+ port: typeof addr === "object" && addr !== null ? addr.port : options.port
81
+ };
82
+ return state;
83
+ } catch (err) {
84
+ server = null;
85
+ state = {
86
+ listening: false,
87
+ error: err instanceof Error ? err.message : String(err),
88
+ port: options.port
89
+ };
90
+ return state;
91
+ }
92
+ }
93
+ /** After the hub registers the Fastify request handler, bind whatever was pending. */
94
+ async function bindPendingLanHttp() {
95
+ if (pending === null) return applyLanHttp({
96
+ enabled: true,
97
+ port: DEFAULT_HTTP_PORT,
98
+ host: "0.0.0.0"
99
+ });
100
+ return applyLanHttp(pending);
101
+ }
102
+ async function closeLanHttp() {
103
+ const current = server;
104
+ server = null;
105
+ boundRequestedHost = null;
106
+ if (current === null) return;
107
+ await new Promise((resolve) => {
108
+ current.close(() => resolve());
109
+ });
110
+ }
111
+ function listenHttp(port, host, next) {
112
+ const resolved = allFamiliesListenHost(host);
113
+ return listenOn(port, resolved, next).catch((err) => {
114
+ if (resolved.host === "::" && host !== "::") return listenOn(port, {
115
+ host: "0.0.0.0",
116
+ ipv6Only: false
117
+ }, next);
118
+ throw err;
119
+ });
120
+ }
121
+ function listenOn(port, bind, next) {
122
+ return new Promise((resolve, reject) => {
123
+ const created = createServer(next.onRequest);
124
+ created.on("upgrade", next.onUpgrade);
125
+ const onError = (err) => {
126
+ created.off("listening", onListening);
127
+ created.close();
128
+ reject(err);
129
+ };
130
+ const onListening = () => {
131
+ created.off("error", onError);
132
+ resolve(created);
133
+ };
134
+ created.once("error", onError);
135
+ created.once("listening", onListening);
136
+ created.listen({
137
+ port,
138
+ host: bind.host,
139
+ ipv6Only: bind.ipv6Only
140
+ });
141
+ });
142
+ }
143
+ //#endregion
11
144
  //#region src/tls/cert-evaluation.ts
12
145
  /**
13
146
  * The regeneration rule (D227), as a pure function.
@@ -616,137 +749,4 @@ function readTlsAccessStatus(dataDir, restartRequired = false) {
616
749
  }
617
750
  }
618
751
  //#endregion
619
- //#region src/http/lan-http-bind.ts
620
- /**
621
- * Second HTTP listener that shares the hub's existing request handler.
622
- *
623
- * Fastify is one protocol per instance; HTTPS stays on :4443 and this
624
- * binds a plain `http.Server` that emits `request` AND `upgrade` onto the
625
- * same handler graph (tRPC HTTP, cookies, data-plane, static, tRPC WS).
626
- *
627
- * Forwarding only `request` is not enough: the viewer speaks tRPC exclusively
628
- * over WebSocket (`wsLink`). `/health` wins the LAN race, then `ws://…/trpc`
629
- * hangs because nobody handles the upgrade on this socket.
630
- */
631
- var DEFAULT_HTTP_PORT = 4480;
632
- var handlers = null;
633
- var server = null;
634
- var pending = null;
635
- var state = {
636
- listening: false,
637
- error: null,
638
- port: DEFAULT_HTTP_PORT
639
- };
640
- var boundRequestedHost = null;
641
- var DEFAULT_LAN_HTTP_PORT = DEFAULT_HTTP_PORT;
642
- /** Map "all IPv4" to dual-stack IPv6 (`::`, ipv6Only false) so IPv4 still works. */
643
- function allFamiliesListenHost(host) {
644
- if (host === "0.0.0.0" || host === "*" || host === "") return {
645
- host: "::",
646
- ipv6Only: false
647
- };
648
- return {
649
- host,
650
- ipv6Only: false
651
- };
652
- }
653
- function registerLanHttpHandler(next) {
654
- handlers = next;
655
- }
656
- function readLanHttpState() {
657
- return state;
658
- }
659
- async function applyLanHttp(options) {
660
- pending = options;
661
- if (!options.enabled) {
662
- await closeLanHttp();
663
- state = {
664
- listening: false,
665
- error: null,
666
- port: options.port
667
- };
668
- return state;
669
- }
670
- if (handlers === null) {
671
- state = {
672
- listening: false,
673
- error: "HTTP listener is not registered yet",
674
- port: options.port
675
- };
676
- return state;
677
- }
678
- if (server !== null && state.listening && (options.port === 0 || state.port === options.port) && boundRequestedHost === options.host) return state;
679
- await closeLanHttp();
680
- try {
681
- const bound = await listenHttp(options.port, options.host, handlers);
682
- server = bound;
683
- boundRequestedHost = options.host;
684
- const addr = bound.address();
685
- state = {
686
- listening: true,
687
- error: null,
688
- port: typeof addr === "object" && addr !== null ? addr.port : options.port
689
- };
690
- return state;
691
- } catch (err) {
692
- server = null;
693
- state = {
694
- listening: false,
695
- error: err instanceof Error ? err.message : String(err),
696
- port: options.port
697
- };
698
- return state;
699
- }
700
- }
701
- /** After the hub registers the Fastify request handler, bind whatever was pending. */
702
- async function bindPendingLanHttp() {
703
- if (pending === null) return applyLanHttp({
704
- enabled: true,
705
- port: DEFAULT_HTTP_PORT,
706
- host: "0.0.0.0"
707
- });
708
- return applyLanHttp(pending);
709
- }
710
- async function closeLanHttp() {
711
- const current = server;
712
- server = null;
713
- boundRequestedHost = null;
714
- if (current === null) return;
715
- await new Promise((resolve) => {
716
- current.close(() => resolve());
717
- });
718
- }
719
- function listenHttp(port, host, next) {
720
- const resolved = allFamiliesListenHost(host);
721
- return listenOn(port, resolved, next).catch((err) => {
722
- if (resolved.host === "::" && host !== "::") return listenOn(port, {
723
- host: "0.0.0.0",
724
- ipv6Only: false
725
- }, next);
726
- throw err;
727
- });
728
- }
729
- function listenOn(port, bind, next) {
730
- return new Promise((resolve, reject) => {
731
- const created = createServer(next.onRequest);
732
- created.on("upgrade", next.onUpgrade);
733
- const onError = (err) => {
734
- created.off("listening", onListening);
735
- created.close();
736
- reject(err);
737
- };
738
- const onListening = () => {
739
- created.off("error", onError);
740
- resolve(created);
741
- };
742
- created.once("error", onError);
743
- created.once("listening", onListening);
744
- created.listen({
745
- port,
746
- host: bind.host,
747
- ipv6Only: bind.ipv6Only
748
- });
749
- });
750
- }
751
- //#endregion
752
- export { evaluateExistingCert as C, SERVER_AUTH_OID as S, CA_COMMON_NAME as _, closeLanHttp as a, LEAF_RENEWAL_WINDOW_DAYS as b, readExtraSans as c, writeExtraSans as d, writeTlsMode as f, reissueTlsLeaf as g, loadTlsCert as h, bindPendingLanHttp as i, readTlsAccessStatus as l, ensureTlsCert as m, allFamiliesListenHost as n, readLanHttpState as o, validateUploadedTls as p, applyLanHttp as r, registerLanHttpHandler as s, DEFAULT_LAN_HTTP_PORT as t, readTlsMode as u, collectCertIdentity as v, MAX_LEAF_VALIDITY_DAYS as x, CA_VALIDITY_DAYS as y };
752
+ export { registerLanHttpHandler as C, readLanHttpState as S, DEFAULT_LAN_HTTP_PORT as _, writeTlsMode as a, bindPendingLanHttp as b, loadTlsCert as c, collectCertIdentity as d, CA_VALIDITY_DAYS as f, evaluateExistingCert as g, SERVER_AUTH_OID as h, writeExtraSans as i, reissueTlsLeaf as l, MAX_LEAF_VALIDITY_DAYS as m, readTlsAccessStatus as n, validateUploadedTls as o, LEAF_RENEWAL_WINDOW_DAYS as p, readTlsMode as r, ensureTlsCert as s, readExtraSans as t, CA_COMMON_NAME as u, allFamiliesListenHost as v, closeLanHttp as x, applyLanHttp as y };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/system",
3
- "version": "1.2.131",
3
+ "version": "1.2.132",
4
4
  "description": "Core addon for CamStack — builtins, pipeline, process management, auth, logging, events",
5
5
  "keywords": [
6
6
  "camstack",
@@ -9,6 +9,139 @@ node_os = require_chunk.__toESM(node_os);
9
9
  let node_fs = require("node:fs");
10
10
  let node_http = require("node:http");
11
11
  let node_net = require("node:net");
12
+ //#region src/http/lan-http-bind.ts
13
+ /**
14
+ * Second HTTP listener that shares the hub's existing request handler.
15
+ *
16
+ * Fastify is one protocol per instance; HTTPS stays on :4443 and this
17
+ * binds a plain `http.Server` that emits `request` AND `upgrade` onto the
18
+ * same handler graph (tRPC HTTP, cookies, data-plane, static, tRPC WS).
19
+ *
20
+ * Forwarding only `request` is not enough: the viewer speaks tRPC exclusively
21
+ * over WebSocket (`wsLink`). `/health` wins the LAN race, then `ws://…/trpc`
22
+ * hangs because nobody handles the upgrade on this socket.
23
+ */
24
+ var DEFAULT_HTTP_PORT = 4480;
25
+ var handlers = null;
26
+ var server = null;
27
+ var pending = null;
28
+ var state = {
29
+ listening: false,
30
+ error: null,
31
+ port: DEFAULT_HTTP_PORT
32
+ };
33
+ var boundRequestedHost = null;
34
+ var DEFAULT_LAN_HTTP_PORT = DEFAULT_HTTP_PORT;
35
+ /** Map "all IPv4" to dual-stack IPv6 (`::`, ipv6Only false) so IPv4 still works. */
36
+ function allFamiliesListenHost(host) {
37
+ if (host === "0.0.0.0" || host === "*" || host === "") return {
38
+ host: "::",
39
+ ipv6Only: false
40
+ };
41
+ return {
42
+ host,
43
+ ipv6Only: false
44
+ };
45
+ }
46
+ function registerLanHttpHandler(next) {
47
+ handlers = next;
48
+ }
49
+ function readLanHttpState() {
50
+ return state;
51
+ }
52
+ async function applyLanHttp(options) {
53
+ pending = options;
54
+ if (!options.enabled) {
55
+ await closeLanHttp();
56
+ state = {
57
+ listening: false,
58
+ error: null,
59
+ port: options.port
60
+ };
61
+ return state;
62
+ }
63
+ if (handlers === null) {
64
+ state = {
65
+ listening: false,
66
+ error: "HTTP listener is not registered yet",
67
+ port: options.port
68
+ };
69
+ return state;
70
+ }
71
+ if (server !== null && state.listening && (options.port === 0 || state.port === options.port) && boundRequestedHost === options.host) return state;
72
+ await closeLanHttp();
73
+ try {
74
+ const bound = await listenHttp(options.port, options.host, handlers);
75
+ server = bound;
76
+ boundRequestedHost = options.host;
77
+ const addr = bound.address();
78
+ state = {
79
+ listening: true,
80
+ error: null,
81
+ port: typeof addr === "object" && addr !== null ? addr.port : options.port
82
+ };
83
+ return state;
84
+ } catch (err) {
85
+ server = null;
86
+ state = {
87
+ listening: false,
88
+ error: err instanceof Error ? err.message : String(err),
89
+ port: options.port
90
+ };
91
+ return state;
92
+ }
93
+ }
94
+ /** After the hub registers the Fastify request handler, bind whatever was pending. */
95
+ async function bindPendingLanHttp() {
96
+ if (pending === null) return applyLanHttp({
97
+ enabled: true,
98
+ port: DEFAULT_HTTP_PORT,
99
+ host: "0.0.0.0"
100
+ });
101
+ return applyLanHttp(pending);
102
+ }
103
+ async function closeLanHttp() {
104
+ const current = server;
105
+ server = null;
106
+ boundRequestedHost = null;
107
+ if (current === null) return;
108
+ await new Promise((resolve) => {
109
+ current.close(() => resolve());
110
+ });
111
+ }
112
+ function listenHttp(port, host, next) {
113
+ const resolved = allFamiliesListenHost(host);
114
+ return listenOn(port, resolved, next).catch((err) => {
115
+ if (resolved.host === "::" && host !== "::") return listenOn(port, {
116
+ host: "0.0.0.0",
117
+ ipv6Only: false
118
+ }, next);
119
+ throw err;
120
+ });
121
+ }
122
+ function listenOn(port, bind, next) {
123
+ return new Promise((resolve, reject) => {
124
+ const created = (0, node_http.createServer)(next.onRequest);
125
+ created.on("upgrade", next.onUpgrade);
126
+ const onError = (err) => {
127
+ created.off("listening", onListening);
128
+ created.close();
129
+ reject(err);
130
+ };
131
+ const onListening = () => {
132
+ created.off("error", onError);
133
+ resolve(created);
134
+ };
135
+ created.once("error", onError);
136
+ created.once("listening", onListening);
137
+ created.listen({
138
+ port,
139
+ host: bind.host,
140
+ ipv6Only: bind.ipv6Only
141
+ });
142
+ });
143
+ }
144
+ //#endregion
12
145
  //#region src/tls/cert-evaluation.ts
13
146
  /**
14
147
  * The regeneration rule (D227), as a pure function.
@@ -617,139 +750,6 @@ function readTlsAccessStatus(dataDir, restartRequired = false) {
617
750
  }
618
751
  }
619
752
  //#endregion
620
- //#region src/http/lan-http-bind.ts
621
- /**
622
- * Second HTTP listener that shares the hub's existing request handler.
623
- *
624
- * Fastify is one protocol per instance; HTTPS stays on :4443 and this
625
- * binds a plain `http.Server` that emits `request` AND `upgrade` onto the
626
- * same handler graph (tRPC HTTP, cookies, data-plane, static, tRPC WS).
627
- *
628
- * Forwarding only `request` is not enough: the viewer speaks tRPC exclusively
629
- * over WebSocket (`wsLink`). `/health` wins the LAN race, then `ws://…/trpc`
630
- * hangs because nobody handles the upgrade on this socket.
631
- */
632
- var DEFAULT_HTTP_PORT = 4480;
633
- var handlers = null;
634
- var server = null;
635
- var pending = null;
636
- var state = {
637
- listening: false,
638
- error: null,
639
- port: DEFAULT_HTTP_PORT
640
- };
641
- var boundRequestedHost = null;
642
- var DEFAULT_LAN_HTTP_PORT = DEFAULT_HTTP_PORT;
643
- /** Map "all IPv4" to dual-stack IPv6 (`::`, ipv6Only false) so IPv4 still works. */
644
- function allFamiliesListenHost(host) {
645
- if (host === "0.0.0.0" || host === "*" || host === "") return {
646
- host: "::",
647
- ipv6Only: false
648
- };
649
- return {
650
- host,
651
- ipv6Only: false
652
- };
653
- }
654
- function registerLanHttpHandler(next) {
655
- handlers = next;
656
- }
657
- function readLanHttpState() {
658
- return state;
659
- }
660
- async function applyLanHttp(options) {
661
- pending = options;
662
- if (!options.enabled) {
663
- await closeLanHttp();
664
- state = {
665
- listening: false,
666
- error: null,
667
- port: options.port
668
- };
669
- return state;
670
- }
671
- if (handlers === null) {
672
- state = {
673
- listening: false,
674
- error: "HTTP listener is not registered yet",
675
- port: options.port
676
- };
677
- return state;
678
- }
679
- if (server !== null && state.listening && (options.port === 0 || state.port === options.port) && boundRequestedHost === options.host) return state;
680
- await closeLanHttp();
681
- try {
682
- const bound = await listenHttp(options.port, options.host, handlers);
683
- server = bound;
684
- boundRequestedHost = options.host;
685
- const addr = bound.address();
686
- state = {
687
- listening: true,
688
- error: null,
689
- port: typeof addr === "object" && addr !== null ? addr.port : options.port
690
- };
691
- return state;
692
- } catch (err) {
693
- server = null;
694
- state = {
695
- listening: false,
696
- error: err instanceof Error ? err.message : String(err),
697
- port: options.port
698
- };
699
- return state;
700
- }
701
- }
702
- /** After the hub registers the Fastify request handler, bind whatever was pending. */
703
- async function bindPendingLanHttp() {
704
- if (pending === null) return applyLanHttp({
705
- enabled: true,
706
- port: DEFAULT_HTTP_PORT,
707
- host: "0.0.0.0"
708
- });
709
- return applyLanHttp(pending);
710
- }
711
- async function closeLanHttp() {
712
- const current = server;
713
- server = null;
714
- boundRequestedHost = null;
715
- if (current === null) return;
716
- await new Promise((resolve) => {
717
- current.close(() => resolve());
718
- });
719
- }
720
- function listenHttp(port, host, next) {
721
- const resolved = allFamiliesListenHost(host);
722
- return listenOn(port, resolved, next).catch((err) => {
723
- if (resolved.host === "::" && host !== "::") return listenOn(port, {
724
- host: "0.0.0.0",
725
- ipv6Only: false
726
- }, next);
727
- throw err;
728
- });
729
- }
730
- function listenOn(port, bind, next) {
731
- return new Promise((resolve, reject) => {
732
- const created = (0, node_http.createServer)(next.onRequest);
733
- created.on("upgrade", next.onUpgrade);
734
- const onError = (err) => {
735
- created.off("listening", onListening);
736
- created.close();
737
- reject(err);
738
- };
739
- const onListening = () => {
740
- created.off("error", onError);
741
- resolve(created);
742
- };
743
- created.once("error", onError);
744
- created.once("listening", onListening);
745
- created.listen({
746
- port,
747
- host: bind.host,
748
- ipv6Only: bind.ipv6Only
749
- });
750
- });
751
- }
752
- //#endregion
753
753
  Object.defineProperty(exports, "CA_COMMON_NAME", {
754
754
  enumerable: true,
755
755
  get: function() {