@zixt/host 0.0.157 → 0.0.158

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.
Files changed (2) hide show
  1. package/dist/index.js +103 -12
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -28,7 +28,7 @@ import { homedir as homedir6 } from "node:os";
28
28
  // package.json
29
29
  var package_default = {
30
30
  name: "@zixt/host",
31
- version: "0.0.157",
31
+ version: "0.0.158",
32
32
  type: "module",
33
33
  exports: {
34
34
  ".": "./src/client.ts",
@@ -20027,6 +20027,11 @@ var CLOSE_CODES = {
20027
20027
  revoked: 4004
20028
20028
  };
20029
20029
  var UNSUPPORTED_PROTOCOL_CLOSE_REASON = "unsupported protocol version";
20030
+ function parseUnsupportedProtocolCloseReason(detail) {
20031
+ if (detail === UNSUPPORTED_PROTOCOL_CLOSE_REASON) return { cloudProtocolVersion: null };
20032
+ const match = /^unsupported protocol version; cloud protocol (\d{1,6})$/.exec(detail);
20033
+ return match ? { cloudProtocolVersion: Number(match[1]) } : null;
20034
+ }
20030
20035
  var CLOSE_REASON_MAX_BYTES = 123;
20031
20036
 
20032
20037
  // ../../packages/contracts/src/webhook-automations.ts
@@ -26382,7 +26387,7 @@ var HostClient = class _HostClient {
26382
26387
  await this.unwindAllRuns("host connection was replaced by a newer client", "client_shutdown");
26383
26388
  return;
26384
26389
  }
26385
- const versionMismatch = code === CLOSE_CODES.protocolError && detail === UNSUPPORTED_PROTOCOL_CLOSE_REASON;
26390
+ const versionMismatch = code === CLOSE_CODES.protocolError && detail !== void 0 && parseUnsupportedProtocolCloseReason(detail) !== null;
26386
26391
  if (versionMismatch) {
26387
26392
  this.opts.onStatus?.("incompatible", detail);
26388
26393
  this.stopped = true;
@@ -30499,6 +30504,29 @@ function installedReleaseVersion(entry, root = versionsRoot()) {
30499
30504
  if (!version2 || !VERSION_DIR.test(version2)) return null;
30500
30505
  return resolve8(entry) === resolve8(installedReleaseEntry(version2, root)) ? version2 : null;
30501
30506
  }
30507
+ function compareReleaseVersions(left, right) {
30508
+ const parse4 = (version2) => version2.split(/[-+]/, 1)[0].split(".").map((part) => Number(part));
30509
+ const leftParts = parse4(left);
30510
+ const rightParts = parse4(right);
30511
+ for (let index = 0; index < 3; index += 1) {
30512
+ const difference = (leftParts[index] ?? 0) - (rightParts[index] ?? 0);
30513
+ if (difference !== 0) return difference;
30514
+ }
30515
+ return 0;
30516
+ }
30517
+ async function newestInstalledReleaseBelow(version2, excluded, root = versionsRoot()) {
30518
+ let names;
30519
+ try {
30520
+ names = await readdir6(root);
30521
+ } catch {
30522
+ return null;
30523
+ }
30524
+ const candidates = names.filter((name) => VERSION_DIR.test(name)).filter((name) => !excluded.has(name) && compareReleaseVersions(name, version2) < 0).sort(compareReleaseVersions).reverse();
30525
+ for (const candidate of candidates) {
30526
+ if (await validInstalledRelease(candidate, root)) return candidate;
30527
+ }
30528
+ return null;
30529
+ }
30502
30530
  function currentReleaseEntry(root = versionsRoot(), platform = process.platform) {
30503
30531
  return join12(root, platform === "win32" ? "current-launcher.cjs" : CURRENT_RELEASE_ENTRY);
30504
30532
  }
@@ -31603,6 +31631,7 @@ async function superviseHost(options = {}) {
31603
31631
  });
31604
31632
  const attempted = /* @__PURE__ */ new Set();
31605
31633
  let unsatisfiableUpdates = 0;
31634
+ const cloudRefusedVersions = /* @__PURE__ */ new Set();
31606
31635
  const waitOrShutdown = async (ms) => {
31607
31636
  if (shuttingDown2) return false;
31608
31637
  if (!customDelay) {
@@ -31683,6 +31712,14 @@ async function superviseHost(options = {}) {
31683
31712
  rollbackCandidate = null;
31684
31713
  }
31685
31714
  };
31715
+ const parkRefusedCandidate = async (version2) => {
31716
+ if (!releaseStore || releaseState?.candidateVersion !== version2) return;
31717
+ await releaseStore.clear();
31718
+ if (releaseState?.candidateVersion === version2) {
31719
+ releaseState = null;
31720
+ rollbackCandidate = null;
31721
+ }
31722
+ };
31686
31723
  const markReleaseValidated = async (version2) => {
31687
31724
  if (releaseState?.phase !== "probation" || releaseState.candidateVersion !== version2 || !releaseStore) {
31688
31725
  return;
@@ -31991,21 +32028,66 @@ async function superviseHost(options = {}) {
31991
32028
  const target = await published();
31992
32029
  let updateLanded = false;
31993
32030
  let rejectedUpdate = null;
32031
+ if (runtimeMs >= FAST_UPDATE_EXIT_MS) cloudRefusedVersions.clear();
31994
32032
  if (target === null) {
31995
32033
  log2(
31996
32034
  "Zixt Host: a newer release was reported but the registry is unreachable; staying on the current version"
31997
32035
  );
31998
32036
  } else if (target === command.version) {
32037
+ cloudRefusedVersions.add(target);
32038
+ await parkRefusedCandidate(target);
31999
32039
  if (unsatisfiableUpdates === 0) {
32000
32040
  log2(
32001
32041
  `Zixt Host: ${target} is the newest published Zixt Host, so no update can satisfy this cloud; the cloud this Machine is paired to speaks a newer Host protocol than any published release`
32002
32042
  );
32043
+ }
32044
+ const compatible = await newestInstalledReleaseBelow(target, cloudRefusedVersions);
32045
+ if (compatible) {
32046
+ log2(
32047
+ `Zixt Host: running installed ${compatible} while the cloud catches up with ${target}; this Machine returns to ${target} by itself once the cloud speaks its protocol`
32048
+ );
32049
+ command = {
32050
+ entry: installedReleaseEntry(compatible),
32051
+ version: compatible,
32052
+ // The parked newest release is not for this worker to re-request:
32053
+ // its own update checks skip it while the cloud stays behind.
32054
+ rejectedVersion: target
32055
+ };
32056
+ updateLanded = true;
32057
+ } else if (unsatisfiableUpdates === 0) {
32003
32058
  log2(
32004
- "Zixt Host: pair this Machine with a cloud running a published release, or start the Host from the same source checkout that cloud runs; this Machine connects by itself once a matching release is published"
32059
+ "Zixt Host: no older installed release remains to serve this cloud; pair this Machine with a cloud running a published release, or start the Host from the same source checkout that cloud runs; this Machine connects by itself once a matching release is published"
32060
+ );
32061
+ }
32062
+ } else if (cloudRefusedVersions.has(target)) {
32063
+ if (command.version && runtimeMs < FAST_UPDATE_EXIT_MS) {
32064
+ cloudRefusedVersions.add(command.version);
32065
+ await parkRefusedCandidate(command.version);
32066
+ }
32067
+ const compatible = command.version ? await newestInstalledReleaseBelow(command.version, cloudRefusedVersions) : null;
32068
+ if (compatible) {
32069
+ log2(
32070
+ `Zixt Host: ${target} is still refused by the paired cloud; running installed ${compatible} until the cloud updates`
32071
+ );
32072
+ command = {
32073
+ entry: installedReleaseEntry(compatible),
32074
+ version: compatible,
32075
+ rejectedVersion: target
32076
+ };
32077
+ updateLanded = true;
32078
+ } else {
32079
+ log2(
32080
+ `Zixt Host: the paired cloud refuses every installed release; waiting for the cloud or a newer published release`
32005
32081
  );
32006
32082
  }
32007
32083
  } else if (attempted.has(target)) {
32008
- log2(`Zixt Host: already running ${target}; ignoring a repeated update request`);
32084
+ if (command.version !== target && await validInstalledRelease(target)) {
32085
+ log2(`Zixt Host: returning to installed ${target} now that the cloud accepts it`);
32086
+ command = { entry: installedReleaseEntry(target), version: target };
32087
+ updateLanded = true;
32088
+ } else {
32089
+ log2(`Zixt Host: already running ${target}; ignoring a repeated update request`);
32090
+ }
32009
32091
  } else {
32010
32092
  let entry;
32011
32093
  const attempt = { failure: null };
@@ -44831,8 +44913,10 @@ var BrowserManager = class {
44831
44913
  }
44832
44914
  throw new Error("browser cookies changed too many times while synchronizing");
44833
44915
  });
44834
- const tracked = next.finally(() => {
44835
- if (this.cookieSyncTails.get(profileKey) === tracked) this.cookieSyncTails.delete(profileKey);
44916
+ const tracked = next.catch(() => {
44917
+ }).finally(() => {
44918
+ if (this.cookieSyncTails.get(profileKey) === tracked)
44919
+ this.cookieSyncTails.delete(profileKey);
44836
44920
  });
44837
44921
  this.cookieSyncTails.set(profileKey, tracked);
44838
44922
  return next;
@@ -48702,14 +48786,21 @@ var client = new HostClient({
48702
48786
  });
48703
48787
  queueMicrotask(() => shutdown(DO_NOT_RESTART_EXIT_CODE));
48704
48788
  break;
48705
- case "incompatible":
48706
- log.error("Zixt Cloud refused this Host as too old to connect", {
48707
- ...connectionContext,
48708
- protocol: PROTOCOL_VERSION,
48709
- next: packagedBuild ? "Zixt checks the published release now; nothing to do on this Machine" : "Update this checkout through Git and restart the Host"
48710
- });
48789
+ case "incompatible": {
48790
+ const refusal = detail ? parseUnsupportedProtocolCloseReason(detail) : null;
48791
+ const cloudBehind = refusal?.cloudProtocolVersion != null && refusal.cloudProtocolVersion < PROTOCOL_VERSION;
48792
+ log.error(
48793
+ cloudBehind ? "Zixt Cloud is behind this Host and refused the connection" : "Zixt Cloud refused this Host as too old to connect",
48794
+ {
48795
+ ...connectionContext,
48796
+ protocol: PROTOCOL_VERSION,
48797
+ ...refusal?.cloudProtocolVersion != null ? { cloudProtocol: refusal.cloudProtocolVersion } : {},
48798
+ next: packagedBuild ? cloudBehind ? "Zixt runs the newest installed release this cloud accepts until the cloud updates" : "Zixt checks the published release now; nothing to do on this Machine" : cloudBehind ? "Deploy the paired cloud, or run this checkout at the revision that cloud runs" : "Update this checkout through Git and restart the Host"
48799
+ }
48800
+ );
48711
48801
  queueMicrotask(() => shutdown(packagedBuild ? UPDATE_EXIT_CODE : DO_NOT_RESTART_EXIT_CODE));
48712
48802
  break;
48803
+ }
48713
48804
  case "rejected":
48714
48805
  log.error("Zixt Cloud refused this Machine", {
48715
48806
  ...connectionContext,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zixt/host",
3
- "version": "0.0.157",
3
+ "version": "0.0.158",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./src/client.ts",