@homeflare/alchemy 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/caddy/index.js.map +2 -2
  2. package/dist/launchd/index.js.map +2 -2
  3. package/dist/openbao/index.js +10 -8
  4. package/dist/openbao/index.js.map +4 -4
  5. package/dist/ownership/adopting.d.ts +34 -0
  6. package/dist/ownership/adopting.d.ts.map +1 -0
  7. package/dist/ownership/probe.d.ts +15 -5
  8. package/dist/ownership/probe.d.ts.map +1 -1
  9. package/dist/ownership/rows.d.ts +12 -0
  10. package/dist/ownership/rows.d.ts.map +1 -1
  11. package/dist/ownership/store-fixture.d.ts +10 -0
  12. package/dist/ownership/store-fixture.d.ts.map +1 -0
  13. package/dist/proxmox/fake-pve-lxc.d.ts +8 -0
  14. package/dist/proxmox/fake-pve-lxc.d.ts.map +1 -1
  15. package/dist/proxmox/index.js +147 -113
  16. package/dist/proxmox/index.js.map +8 -6
  17. package/dist/proxmox/lxc-adoption.d.ts +32 -0
  18. package/dist/proxmox/lxc-adoption.d.ts.map +1 -0
  19. package/dist/proxmox/lxc-harness.d.ts +12 -0
  20. package/dist/proxmox/lxc-harness.d.ts.map +1 -1
  21. package/dist/proxmox/lxc.d.ts +5 -5
  22. package/dist/proxmox/lxc.d.ts.map +1 -1
  23. package/dist/verify/cli.js +79 -29
  24. package/dist/verify/cli.js.map +8 -6
  25. package/dist/verify/fake-engine.d.ts +9 -1
  26. package/dist/verify/fake-engine.d.ts.map +1 -1
  27. package/dist/verify/index.d.ts +1 -1
  28. package/dist/verify/index.d.ts.map +1 -1
  29. package/dist/verify/index.js +67 -17
  30. package/dist/verify/index.js.map +8 -6
  31. package/dist/verify/plan-scope.d.ts +14 -0
  32. package/dist/verify/plan-scope.d.ts.map +1 -0
  33. package/dist/verify/recheck.d.ts +42 -0
  34. package/dist/verify/recheck.d.ts.map +1 -0
  35. package/dist/verify/rows.d.ts +13 -3
  36. package/dist/verify/rows.d.ts.map +1 -1
  37. package/dist/verify/spy.d.ts +12 -0
  38. package/dist/verify/spy.d.ts.map +1 -1
  39. package/dist/verify/verify.d.ts.map +1 -1
  40. package/docs/adopt-verify.md +13 -2
  41. package/docs/adopted-deploys.md +4 -2
  42. package/docs/ownership.md +1 -1
  43. package/docs/proxmox-lxc-adopt.md +83 -0
  44. package/docs/proxmox-lxc.md +7 -45
  45. package/docs/proxmox.md +2 -0
  46. package/package.json +1 -1
  47. package/src/ownership/adopting.test.ts +63 -0
  48. package/src/ownership/adopting.ts +46 -0
  49. package/src/ownership/ownership.test.ts +1 -34
  50. package/src/ownership/probe.ts +27 -14
  51. package/src/ownership/rows.ts +8 -2
  52. package/src/ownership/store-fixture.ts +50 -0
  53. package/src/proxmox/ceph-pool-adopt.test.ts +32 -0
  54. package/src/proxmox/fake-pve-lxc.ts +13 -1
  55. package/src/proxmox/lxc-adopt.test.ts +13 -20
  56. package/src/proxmox/lxc-adoption.ts +50 -0
  57. package/src/proxmox/lxc-guards.test.ts +6 -13
  58. package/src/proxmox/lxc-harness.ts +25 -2
  59. package/src/proxmox/lxc-ownership.test.ts +19 -14
  60. package/src/proxmox/lxc-strict-adopt.test.ts +104 -0
  61. package/src/proxmox/lxc.ts +16 -12
  62. package/src/verify/fake-engine.ts +24 -0
  63. package/src/verify/index.ts +1 -0
  64. package/src/verify/plan-scope.ts +34 -0
  65. package/src/verify/recheck.test.ts +56 -0
  66. package/src/verify/recheck.ts +71 -0
  67. package/src/verify/rows.ts +46 -5
  68. package/src/verify/spy.ts +14 -3
  69. package/src/verify/verify.test.ts +22 -0
  70. package/src/verify/verify.ts +38 -25
@@ -1048,7 +1048,7 @@ var ProxmoxHaRuleProvider = () => Provider12.effect(ProxmoxHaRule, Effect21.succ
1048
1048
  import { Resource as Resource13 } from "alchemy";
1049
1049
  import { isResolved as isResolved6 } from "alchemy/Diff";
1050
1050
  import * as Provider13 from "alchemy/Provider";
1051
- import * as Effect29 from "effect/Effect";
1051
+ import * as Effect31 from "effect/Effect";
1052
1052
 
1053
1053
  // src/ownership/adopt.ts
1054
1054
  import { AdoptPolicy } from "alchemy/AdoptPolicy";
@@ -1230,19 +1230,21 @@ var claimFor = (owner) => (what) => refuseTakeover(owner, what);
1230
1230
  // src/ownership/probe.ts
1231
1231
  import { Unowned as Unowned2 } from "alchemy/AdoptPolicy";
1232
1232
  import * as Effect26 from "effect/Effect";
1233
- var ownedRead = (ask, found, settled2) => Effect26.gen(function* () {
1234
- if (found === undefined || ask.output !== undefined)
1235
- return found;
1233
+ var provenOurs = (ask, settled2) => Effect26.gen(function* () {
1236
1234
  const recorded = yield* recordedInstance(ask.fqn, ask.instanceId);
1237
1235
  if (recorded === "absent")
1238
- return Unowned2(found);
1236
+ return false;
1239
1237
  if (recorded === "partial") {
1240
1238
  yield* Effect26.logWarning(`${ask.fqn}: the interrupted create's state row lacks part of the declaration (a prop ` + "was still an Output when it was written), so the live object is not proven ours");
1241
- return Unowned2(found);
1239
+ return false;
1242
1240
  }
1243
1241
  const unproven = (reason) => Effect26.as(Effect26.logWarning(`${ask.fqn}: the interrupted create's object could not be compared with its props ` + `(${reason instanceof Error ? reason.message : String(reason)}), so it is not treated as ours`), false);
1244
- const ours = yield* settled2.pipe(Effect26.catch(unproven), Effect26.catchDefect(unproven));
1245
- return ours ? found : Unowned2(found);
1242
+ return yield* settled2.pipe(Effect26.catch(unproven), Effect26.catchDefect(unproven));
1243
+ });
1244
+ var ownedRead = (ask, found, settled2) => Effect26.gen(function* () {
1245
+ if (found === undefined || ask.output !== undefined)
1246
+ return found;
1247
+ return (yield* provenOurs(ask, settled2)) ? found : Unowned2(found);
1246
1248
  });
1247
1249
 
1248
1250
  // src/proxmox/lxc-wire.ts
@@ -1693,12 +1695,28 @@ var identityRefusals = (news, olds, output) => {
1693
1695
  return reasons;
1694
1696
  };
1695
1697
 
1698
+ // src/proxmox/lxc-adoption.ts
1699
+ import * as Effect30 from "effect/Effect";
1700
+
1701
+ // src/ownership/adopting.ts
1702
+ import * as Effect27 from "effect/Effect";
1703
+ var adopting = (owner, settled2) => Effect27.gen(function* () {
1704
+ if (owner.output === undefined)
1705
+ return false;
1706
+ const generation = yield* recordedGeneration(owner.fqn, owner.instanceId);
1707
+ if (generation === undefined || generation.adopting === true)
1708
+ return true;
1709
+ if (generation.attr !== undefined && generation.attr !== null)
1710
+ return false;
1711
+ return !(yield* provenOurs(owner, settled2(generation.props)));
1712
+ });
1713
+
1696
1714
  // src/proxmox/lxc-lifecycle.ts
1697
- import * as Effect28 from "effect/Effect";
1715
+ import * as Effect29 from "effect/Effect";
1698
1716
 
1699
1717
  // src/proxmox/network-apply-read.ts
1700
- import * as Effect27 from "effect/Effect";
1701
- var stagedDiff = (target, node) => Effect27.gen(function* () {
1718
+ import * as Effect28 from "effect/Effect";
1719
+ var stagedDiff = (target, node) => Effect28.gen(function* () {
1702
1720
  const path = `nodes/${node}/network`;
1703
1721
  const credential = yield* leased(target, "read");
1704
1722
  const envelope = yield* pveEnvelopeWith(target, credential, "GET", path);
@@ -1711,8 +1729,8 @@ var pendingLines = (diff) => {
1711
1729
  `).filter((line) => (line.startsWith("+") || line.startsWith("-")) && !line.startsWith("+++") && !line.startsWith("---")).length;
1712
1730
  return Math.max(changed, 1);
1713
1731
  };
1714
- var pendingCount = (target, node) => stagedDiff(target, node).pipe(Effect27.map(pendingLines));
1715
- var clusterHealth = (target) => pve(target, "read", "GET", "cluster/status").pipe(Effect27.map((rows) => {
1732
+ var pendingCount = (target, node) => stagedDiff(target, node).pipe(Effect28.map(pendingLines));
1733
+ var clusterHealth = (target) => pve(target, "read", "GET", "cluster/status").pipe(Effect28.map((rows) => {
1716
1734
  const all = rows ?? [];
1717
1735
  const cluster = all.find((row) => row.type === "cluster");
1718
1736
  return {
@@ -1720,21 +1738,21 @@ var clusterHealth = (target) => pve(target, "read", "GET", "cluster/status").pip
1720
1738
  quorate: cluster === undefined ? true : bool(cluster.quorate)
1721
1739
  };
1722
1740
  }));
1723
- var degradedReason = (target) => clusterHealth(target).pipe(Effect27.map((health) => health.quorate && health.offline.length === 0 ? undefined : `quorate=${String(health.quorate)} offline=[${health.offline.join(", ")}]`));
1741
+ var degradedReason = (target) => clusterHealth(target).pipe(Effect28.map((health) => health.quorate && health.offline.length === 0 ? undefined : `quorate=${String(health.quorate)} offline=[${health.offline.join(", ")}]`));
1724
1742
  var UNREACHABLE = "the task could not be read -- the node stopped answering, or this lease cannot see it";
1725
1743
  var STILL_RUNNING = "still running when this provider stopped waiting";
1726
1744
  var ATTEMPTS = 30;
1727
- var awaitTask = (target, credential, node, upid, attempts = ATTEMPTS) => Effect27.gen(function* () {
1745
+ var awaitTask = (target, credential, node, upid, attempts = ATTEMPTS) => Effect28.gen(function* () {
1728
1746
  const path = `nodes/${node}/tasks/${upid}/status`;
1729
1747
  for (let attempt = 0;attempt < attempts; attempt += 1) {
1730
- const status = yield* pveWith(target, credential, "GET", path).pipe(Effect27.orElseSucceed(() => {
1748
+ const status = yield* pveWith(target, credential, "GET", path).pipe(Effect28.orElseSucceed(() => {
1731
1749
  return;
1732
1750
  }));
1733
1751
  if (status === undefined)
1734
1752
  return UNREACHABLE;
1735
1753
  if (status.status === "stopped")
1736
1754
  return text(status.exitstatus, "stopped with no exitstatus");
1737
- yield* Effect27.sleep("1 second");
1755
+ yield* Effect28.sleep("1 second");
1738
1756
  }
1739
1757
  return STILL_RUNNING;
1740
1758
  });
@@ -1747,17 +1765,17 @@ var guestPath = (where) => `nodes/${where.node}/lxc/${String(where.vmid)}`;
1747
1765
  var CREATE_POLLS = 180;
1748
1766
  var TASK_POLLS = 60;
1749
1767
  var isServerError = (error) => error instanceof PveError && error.status === 500;
1750
- var readLive = (where) => Effect28.gen(function* () {
1751
- const answer = yield* pve(where.target, "read", "GET", `${guestPath(where)}/config`).pipe(Effect28.map((data) => ({ data, error: undefined })), Effect28.catchIf(isServerError, (error) => Effect28.succeed({ data: undefined, error })));
1768
+ var readLive = (where) => Effect29.gen(function* () {
1769
+ const answer = yield* pve(where.target, "read", "GET", `${guestPath(where)}/config`).pipe(Effect29.map((data) => ({ data, error: undefined })), Effect29.catchIf(isServerError, (error) => Effect29.succeed({ data: undefined, error })));
1752
1770
  if (answer.data !== undefined && answer.data !== null)
1753
1771
  return answer.data;
1754
1772
  const rows = yield* pve(where.target, "read", "GET", "cluster/resources?type=vm");
1755
1773
  const found = (rows ?? []).find((row) => Number(row.vmid) === where.vmid);
1756
1774
  if (found !== undefined && found.node === where.node && found.type === "lxc") {
1757
- return yield* Effect28.fail(answer.error ?? new LxcRefusedError(`CT ${String(where.vmid)} is listed but its config read empty.`));
1775
+ return yield* Effect29.fail(answer.error ?? new LxcRefusedError(`CT ${String(where.vmid)} is listed but its config read empty.`));
1758
1776
  }
1759
1777
  if (found !== undefined) {
1760
- return yield* Effect28.fail(new LxcRefusedError(`vmid ${String(where.vmid)} is a ${text(found.type, "guest")} on ` + `${text(found.node, "?")}, not a container on ${where.node}. A migration is not an ` + "update and vmids are cluster-wide: declare the node it is on, or pick a free vmid."));
1778
+ return yield* Effect29.fail(new LxcRefusedError(`vmid ${String(where.vmid)} is a ${text(found.type, "guest")} on ` + `${text(found.node, "?")}, not a container on ${where.node}. A migration is not an ` + "update and vmids are cluster-wide: declare the node it is on, or pick a free vmid."));
1761
1779
  }
1762
1780
  return;
1763
1781
  });
@@ -1767,19 +1785,19 @@ var attributesOf = (where, live) => ({
1767
1785
  rawKeys: rawKeysOf(live),
1768
1786
  vmid: where.vmid
1769
1787
  });
1770
- var task = (where, method, path, what, polls, form) => Effect28.gen(function* () {
1788
+ var task = (where, method, path, what, polls, form) => Effect29.gen(function* () {
1771
1789
  const credential = yield* mint(where.target, "provision");
1772
1790
  const upid = text(yield* pveWith(where.target, credential, method, path, form));
1773
1791
  if (upid === "") {
1774
- return yield* Effect28.fail(new LxcRefusedError(`${what}: PVE returned no task id, so the write cannot be confirmed and is not claimed.`));
1792
+ return yield* Effect29.fail(new LxcRefusedError(`${what}: PVE returned no task id, so the write cannot be confirmed and is not claimed.`));
1775
1793
  }
1776
1794
  const exit = yield* awaitTask(where.target, credential, where.node, upid, polls);
1777
1795
  if (exit !== "OK") {
1778
- return yield* Effect28.fail(new LxcRefusedError(`${what}: task ${upid} ended "${exit}". Read \`pvesh get /nodes/${where.node}/tasks/` + `${upid}/log\` before running the deploy again.`));
1796
+ return yield* Effect29.fail(new LxcRefusedError(`${what}: task ${upid} ended "${exit}". Read \`pvesh get /nodes/${where.node}/tasks/` + `${upid}/log\` before running the deploy again.`));
1779
1797
  }
1780
1798
  });
1781
1799
  var createGuest = (props) => task(props, "POST", `nodes/${props.node}/lxc`, `create CT ${String(props.vmid)}`, CREATE_POLLS, createForm3(props));
1782
- var updateGuest = (props, change, digest) => Effect28.gen(function* () {
1800
+ var updateGuest = (props, change, digest) => Effect29.gen(function* () {
1783
1801
  if (Object.keys(change.put).length > 0 || change.clear.length > 0) {
1784
1802
  const form = withClears({ ...change.put, ...digest === "" ? {} : { digest } }, change.clear);
1785
1803
  yield* pve(props.target, "provision", "PUT", `${guestPath(props)}/config`, form);
@@ -1788,22 +1806,34 @@ var updateGuest = (props, change, digest) => Effect28.gen(function* () {
1788
1806
  yield* task(props, "PUT", `${guestPath(props)}/resize`, `grow ${grow.disk} of CT ${String(props.vmid)} to ${grow.size}`, TASK_POLLS, { disk: grow.disk, size: grow.size });
1789
1807
  }
1790
1808
  });
1791
- var destroyGuest = (where, declared) => Effect28.gen(function* () {
1809
+ var destroyGuest = (where, declared) => Effect29.gen(function* () {
1792
1810
  const live = yield* readLive(where);
1793
1811
  if (live === undefined)
1794
1812
  return;
1795
1813
  const drift = judge(declared, live).drift;
1796
1814
  if (drift.length > 0) {
1797
- return yield* Effect28.fail(new LxcRefusedError(`destroy CT ${String(where.vmid)}: the guest on ${where.node} no longer matches its last ` + `declaration (${drift.join(", ")}), so it may not be the guest this stack made. ` + "Nothing was deleted. Delete it by hand if it should go, or declare it again."));
1815
+ return yield* Effect29.fail(new LxcRefusedError(`destroy CT ${String(where.vmid)}: the guest on ${where.node} no longer matches its last ` + `declaration (${drift.join(", ")}), so it may not be the guest this stack made. ` + "Nothing was deleted. Delete it by hand if it should go, or declare it again."));
1798
1816
  }
1799
1817
  yield* task(where, "DELETE", guestPath(where), `destroy CT ${String(where.vmid)}`, TASK_POLLS);
1800
1818
  });
1801
1819
 
1820
+ // src/proxmox/lxc-adoption.ts
1821
+ var adoptionRefusal = (props, drift) => `CT ${String(props.vmid)} on ${props.node}: adopting it would change ${drift.join(", ")}. An ` + "adoption never changes a guest, so nothing is written. Declare what is live for these keys " + "(the plan names keys, never values) and plan again; change them after the adoption, as an " + "update.";
1822
+ var refuseAdoptedDrift = (owner, props, live, change) => Effect30.gen(function* () {
1823
+ if (change.drift.length === 0)
1824
+ return;
1825
+ const settled2 = (recorded) => Effect30.sync(() => judge(recorded, live).drift.length === 0);
1826
+ if (!(yield* adopting(owner, settled2)))
1827
+ return;
1828
+ return yield* Effect30.fail(new LxcRefusedError(adoptionRefusal(props, change.drift)));
1829
+ });
1830
+
1802
1831
  // src/proxmox/lxc.ts
1803
1832
  var ProxmoxLxc = Resource13("Proxmox.Lxc", { defaultRemovalPolicy: "retain" });
1804
- var refused = (reasons) => Effect29.fail(new LxcRefusedError(reasons.join(`
1833
+ var refused = (reasons) => Effect31.fail(new LxcRefusedError(reasons.join(`
1805
1834
  `)));
1806
- var diff = (news, olds, output) => Effect29.gen(function* () {
1835
+ var diff = (owner, news, olds) => Effect31.gen(function* () {
1836
+ const { output } = owner;
1807
1837
  const identity2 = identityRefusals(news, olds, output);
1808
1838
  if (identity2.length > 0)
1809
1839
  return yield* refused(identity2);
@@ -1816,20 +1846,21 @@ var diff = (news, olds, output) => Effect29.gen(function* () {
1816
1846
  const refusals = createRefusals(news);
1817
1847
  if (refusals.length > 0)
1818
1848
  return yield* refused(refusals);
1819
- yield* Effect29.logWarning(`Proxmox.Lxc ${news.node}/${String(news.vmid)}: the cluster lists no guest with this ` + "vmid -- a deploy CREATES it again from ostemplate, with new, empty volumes.");
1849
+ yield* Effect31.logWarning(`Proxmox.Lxc ${news.node}/${String(news.vmid)}: the cluster lists no guest with this ` + "vmid -- a deploy CREATES it again from ostemplate, with new, empty volumes.");
1820
1850
  return { action: "update" };
1821
1851
  }
1822
1852
  const change = judge(news, live);
1853
+ yield* refuseAdoptedDrift(owner, news, live, change);
1823
1854
  if (change.refuse.length > 0)
1824
1855
  return yield* refused(change.refuse);
1825
1856
  const moved = news.node !== output.node;
1826
1857
  if (change.drift.length === 0 && !moved)
1827
1858
  return { action: "noop" };
1828
1859
  const what = change.drift.length === 0 ? `the guest is on ${news.node} now, not ${output.node} -- a deploy re-records it, ` + "writing nothing." : `live config differs from the declaration in ${change.drift.join(", ")} -- a ` + "deploy writes these.";
1829
- yield* Effect29.logWarning(`Proxmox.Lxc ${news.node}/${String(news.vmid)}: ${what}`);
1860
+ yield* Effect31.logWarning(`Proxmox.Lxc ${news.node}/${String(news.vmid)}: ${what}`);
1830
1861
  return { action: "update" };
1831
1862
  });
1832
- var reconcile = (owner, news) => Effect29.gen(function* () {
1863
+ var reconcile = (owner, news) => Effect31.gen(function* () {
1833
1864
  const { output } = owner;
1834
1865
  const identity2 = identityRefusals(news, news, output);
1835
1866
  if (identity2.length > 0)
@@ -1850,6 +1881,7 @@ var reconcile = (owner, news) => Effect29.gen(function* () {
1850
1881
  `CT ${String(news.vmid)} already exists on ${news.node} and differs in ` + `${change.drift.join(", ")}, but this deploy planned a create. A create never writes ` + "onto an existing guest: plan again, so the plan can show it and adopt it."
1851
1882
  ]);
1852
1883
  }
1884
+ yield* refuseAdoptedDrift(owner, news, live, change);
1853
1885
  if (change.refuse.length > 0)
1854
1886
  return yield* refused(change.refuse);
1855
1887
  if (change.drift.length > 0)
@@ -1874,22 +1906,24 @@ var whereOf = (olds, output) => ({
1874
1906
  target: olds.target,
1875
1907
  vmid: output?.vmid ?? olds.vmid
1876
1908
  });
1877
- var read = (owner, olds) => Effect29.gen(function* () {
1909
+ var read = (owner, olds) => Effect31.gen(function* () {
1878
1910
  const where = whereOf(olds, owner.output);
1879
1911
  const live = yield* readLive(where);
1880
1912
  if (live === undefined)
1881
1913
  return;
1882
- const settled2 = Effect29.sync(() => judge(olds, live).drift.length === 0);
1914
+ const settled2 = Effect31.sync(() => judge(olds, live).drift.length === 0);
1883
1915
  return yield* ownedRead(owner, attributesOf(where, live), settled2);
1884
1916
  });
1885
1917
  var handlers10 = {
1886
1918
  delete: ({ olds, output }) => destroyGuest(whereOf(olds, output), olds),
1887
1919
  diff: ({
1920
+ fqn,
1921
+ instanceId,
1888
1922
  news,
1889
1923
  olds,
1890
1924
  output
1891
- }) => diff(news, olds, output),
1892
- list: () => Effect29.succeed([]),
1925
+ }) => diff({ fqn, instanceId, output }, news, olds),
1926
+ list: () => Effect31.succeed([]),
1893
1927
  read: ({
1894
1928
  fqn,
1895
1929
  instanceId,
@@ -1903,11 +1937,11 @@ var handlers10 = {
1903
1937
  output
1904
1938
  }) => reconcile({ fqn, instanceId, output }, news)
1905
1939
  };
1906
- var ProxmoxLxcProvider = () => Provider13.effect(ProxmoxLxc, Effect29.succeed(ProxmoxLxc.Provider.of(handlers10)).pipe(Effect29.map(provingResumes)));
1940
+ var ProxmoxLxcProvider = () => Provider13.effect(ProxmoxLxc, Effect31.succeed(ProxmoxLxc.Provider.of(handlers10)).pipe(Effect31.map(provingResumes)));
1907
1941
  // src/proxmox/metric-server.ts
1908
1942
  import { Resource as Resource14 } from "alchemy";
1909
1943
  import * as Provider14 from "alchemy/Provider";
1910
- import * as Effect30 from "effect/Effect";
1944
+ import * as Effect32 from "effect/Effect";
1911
1945
 
1912
1946
  // src/proxmox/metric-server-form.ts
1913
1947
  var UNSET2 = -1;
@@ -2015,22 +2049,22 @@ var handlers11 = pveHandlers({
2015
2049
  path: (props) => `cluster/metrics/server/${props.id}`,
2016
2050
  updateForm: update
2017
2051
  });
2018
- var ProxmoxMetricServerProvider = () => Provider14.effect(ProxmoxMetricServer, Effect30.succeed(ProxmoxMetricServer.Provider.of(handlers11)));
2052
+ var ProxmoxMetricServerProvider = () => Provider14.effect(ProxmoxMetricServer, Effect32.succeed(ProxmoxMetricServer.Provider.of(handlers11)));
2019
2053
  // src/proxmox/network-apply.ts
2020
2054
  import { Resource as Resource15 } from "alchemy";
2021
2055
  import { isResolved as isResolved7 } from "alchemy/Diff";
2022
2056
  import * as Provider15 from "alchemy/Provider";
2023
- import * as Effect31 from "effect/Effect";
2057
+ import * as Effect33 from "effect/Effect";
2024
2058
  var ProxmoxNetworkApply = Resource15("Proxmox.NetworkApply");
2025
- var read2 = (props) => pendingCount(props.target, props.node).pipe(Effect31.map((pending) => ({ node: props.node, pending })));
2026
- var diff2 = (news) => Effect31.gen(function* () {
2059
+ var read2 = (props) => pendingCount(props.target, props.node).pipe(Effect33.map((pending) => ({ node: props.node, pending })));
2060
+ var diff2 = (news) => Effect33.gen(function* () {
2027
2061
  if (!isResolved7(news))
2028
2062
  return;
2029
2063
  const { pending } = yield* read2(news);
2030
2064
  return pending === 0 ? { action: "noop" } : { action: "update" };
2031
2065
  });
2032
- var refuse = (node, why) => Effect31.die(new Error(`Proxmox.NetworkApply ${node}: ${why}`));
2033
- var apply = (props) => Effect31.gen(function* () {
2066
+ var refuse = (node, why) => Effect33.die(new Error(`Proxmox.NetworkApply ${node}: ${why}`));
2067
+ var apply = (props) => Effect33.gen(function* () {
2034
2068
  const node = props.node;
2035
2069
  const staged = yield* pendingCount(props.target, node);
2036
2070
  if (staged === 0)
@@ -2059,17 +2093,17 @@ var apply = (props) => Effect31.gen(function* () {
2059
2093
  return { node, pending: left };
2060
2094
  });
2061
2095
  var handlers12 = {
2062
- delete: () => Effect31.void,
2096
+ delete: () => Effect33.void,
2063
2097
  diff: ({ news }) => diff2(news),
2064
- list: () => Effect31.succeed([]),
2098
+ list: () => Effect33.succeed([]),
2065
2099
  read: ({ olds }) => read2(olds),
2066
2100
  reconcile: ({ news }) => apply(news)
2067
2101
  };
2068
- var ProxmoxNetworkApplyProvider = () => Provider15.effect(ProxmoxNetworkApply, Effect31.succeed(ProxmoxNetworkApply.Provider.of(handlers12)));
2102
+ var ProxmoxNetworkApplyProvider = () => Provider15.effect(ProxmoxNetworkApply, Effect33.succeed(ProxmoxNetworkApply.Provider.of(handlers12)));
2069
2103
  // src/proxmox/node-network.ts
2070
2104
  import { Resource as Resource16 } from "alchemy";
2071
2105
  import * as Provider16 from "alchemy/Provider";
2072
- import * as Effect32 from "effect/Effect";
2106
+ import * as Effect34 from "effect/Effect";
2073
2107
 
2074
2108
  // src/proxmox/node-network-form.ts
2075
2109
  var UNSET3 = -1;
@@ -2149,11 +2183,11 @@ var handlers13 = pveHandlers({
2149
2183
  path: (props) => `nodes/${props.node}/network/${props.iface}`,
2150
2184
  updateForm: updateBody2
2151
2185
  });
2152
- var ProxmoxNodeNetworkProvider = () => Provider16.effect(ProxmoxNodeNetwork, Effect32.succeed(ProxmoxNodeNetwork.Provider.of(handlers13)));
2186
+ var ProxmoxNodeNetworkProvider = () => Provider16.effect(ProxmoxNodeNetwork, Effect34.succeed(ProxmoxNodeNetwork.Provider.of(handlers13)));
2153
2187
  // src/proxmox/notification-target.ts
2154
2188
  import { Resource as Resource17 } from "alchemy";
2155
2189
  import * as Provider17 from "alchemy/Provider";
2156
- import * as Effect33 from "effect/Effect";
2190
+ import * as Effect35 from "effect/Effect";
2157
2191
 
2158
2192
  // src/proxmox/notification-target-form.ts
2159
2193
  var REPEATED_KEY = "\x00";
@@ -2209,15 +2243,15 @@ var handlers14 = pveHandlers({
2209
2243
  path: (props) => `cluster/notifications/endpoints/${props.type}/${props.name}`,
2210
2244
  updateForm: shape4
2211
2245
  });
2212
- var ProxmoxNotificationTargetProvider = () => Provider17.effect(ProxmoxNotificationTarget, Effect33.succeed(ProxmoxNotificationTarget.Provider.of(handlers14)));
2246
+ var ProxmoxNotificationTargetProvider = () => Provider17.effect(ProxmoxNotificationTarget, Effect35.succeed(ProxmoxNotificationTarget.Provider.of(handlers14)));
2213
2247
  // src/proxmox/pbs-datastore.ts
2214
2248
  import { Resource as Resource18 } from "alchemy";
2215
2249
  import { isResolved as isResolved8 } from "alchemy/Diff";
2216
2250
  import * as Provider18 from "alchemy/Provider";
2217
- import * as Effect36 from "effect/Effect";
2251
+ import * as Effect38 from "effect/Effect";
2218
2252
 
2219
2253
  // src/proxmox/pbs-datastore-form.ts
2220
- import * as Effect34 from "effect/Effect";
2254
+ import * as Effect36 from "effect/Effect";
2221
2255
  var attributes = (live, props) => ({
2222
2256
  backend: propertyString(live["backend"]),
2223
2257
  comment: text(live["comment"]),
@@ -2269,24 +2303,24 @@ var createForm4 = (props) => ({
2269
2303
  });
2270
2304
  var updateForm = (props) => mutable(props);
2271
2305
  var object2 = (props) => `config/datastore/${props.name}`;
2272
- var readOne = (props) => pve(props.target, "read", "GET", object2(props)).pipe(Effect34.map((live) => live === undefined || typeof live["name"] !== "string" ? undefined : attributes(live, props)), Effect34.orElseSucceed(() => {
2306
+ var readOne = (props) => pve(props.target, "read", "GET", object2(props)).pipe(Effect36.map((live) => live === undefined || typeof live["name"] !== "string" ? undefined : attributes(live, props)), Effect36.orElseSucceed(() => {
2273
2307
  return;
2274
2308
  }));
2275
2309
 
2276
2310
  // src/proxmox/pbs-datastore-guard.ts
2277
- import * as Effect35 from "effect/Effect";
2311
+ import * as Effect37 from "effect/Effect";
2278
2312
  var samePath = (left, right) => {
2279
2313
  const trim = (value) => value.length > 1 ? value.replace(/\/+$/, "") : value;
2280
2314
  return trim(left) === trim(right);
2281
2315
  };
2282
- var guardPath = (live, props) => live.path === "" || samePath(live.path, props.path) ? Effect35.void : Effect35.die(new Error(`${object2(props)}: declared path ${props.path} but PBS holds ${live.path}. \`path\` ` + "is create-only, so this cannot be reconciled and will NOT be planned as a silent " + "noop: backups would keep landing in the old directory behind a green plan. Correct " + "the declaration, or remove the datastore and declare a new one -- the contents live, " + "because `destroy-data` is never sent."));
2283
- var guardBackend = (live, props) => props.backend === undefined || propertyString(props.backend) === live.backend ? Effect35.void : Effect35.die(new Error(`${object2(props)}: declared backend ${props.backend} but PBS holds ` + `${live.backend === "" ? "(none — a local datastore)" : live.backend}. \`backend\` ` + "is create-only: PBS has no update for it, so this cannot be reconciled and will NOT " + "be planned as a silent noop. Correct the declaration to match what is really there, " + "or remove the datastore and declare a new one -- the contents live, because " + "`destroy-data` is never sent."));
2284
- var settle3 = (read3, done) => Effect35.gen(function* () {
2316
+ var guardPath = (live, props) => live.path === "" || samePath(live.path, props.path) ? Effect37.void : Effect37.die(new Error(`${object2(props)}: declared path ${props.path} but PBS holds ${live.path}. \`path\` ` + "is create-only, so this cannot be reconciled and will NOT be planned as a silent " + "noop: backups would keep landing in the old directory behind a green plan. Correct " + "the declaration, or remove the datastore and declare a new one -- the contents live, " + "because `destroy-data` is never sent."));
2317
+ var guardBackend = (live, props) => props.backend === undefined || propertyString(props.backend) === live.backend ? Effect37.void : Effect37.die(new Error(`${object2(props)}: declared backend ${props.backend} but PBS holds ` + `${live.backend === "" ? "(none — a local datastore)" : live.backend}. \`backend\` ` + "is create-only: PBS has no update for it, so this cannot be reconciled and will NOT " + "be planned as a silent noop. Correct the declaration to match what is really there, " + "or remove the datastore and declare a new one -- the contents live, because " + "`destroy-data` is never sent."));
2318
+ var settle3 = (read3, done) => Effect37.gen(function* () {
2285
2319
  for (let attempt = 0;attempt < 60; attempt += 1) {
2286
2320
  const live = yield* read3;
2287
2321
  if (done(live))
2288
2322
  return live;
2289
- yield* Effect35.sleep("2 seconds");
2323
+ yield* Effect37.sleep("2 seconds");
2290
2324
  }
2291
2325
  return yield* read3;
2292
2326
  });
@@ -2295,10 +2329,10 @@ var settle3 = (read3, done) => Effect35.gen(function* () {
2295
2329
  var PbsDatastore = Resource18("Pbs.Datastore", {
2296
2330
  defaultRemovalPolicy: "retain"
2297
2331
  });
2298
- var PbsDatastoreProvider = () => Provider18.effect(PbsDatastore, Effect36.succeed(PbsDatastore.Provider.of({
2299
- list: () => Effect36.succeed([]),
2332
+ var PbsDatastoreProvider = () => Provider18.effect(PbsDatastore, Effect38.succeed(PbsDatastore.Provider.of({
2333
+ list: () => Effect38.succeed([]),
2300
2334
  read: ({ olds }) => readOne(olds),
2301
- diff: ({ news, output }) => Effect36.gen(function* () {
2335
+ diff: ({ news, output }) => Effect38.gen(function* () {
2302
2336
  if (output === undefined || !isResolved8(news))
2303
2337
  return;
2304
2338
  const live = yield* readOne(news);
@@ -2308,7 +2342,7 @@ var PbsDatastoreProvider = () => Provider18.effect(PbsDatastore, Effect36.succee
2308
2342
  yield* guardBackend(live, news);
2309
2343
  return matches(live, news) ? { action: "noop" } : { action: "update" };
2310
2344
  }),
2311
- reconcile: Effect36.fn(function* ({ news }) {
2345
+ reconcile: Effect38.fn(function* ({ news }) {
2312
2346
  const live = yield* readOne(news);
2313
2347
  let upid;
2314
2348
  if (live === undefined) {
@@ -2323,22 +2357,22 @@ var PbsDatastoreProvider = () => Provider18.effect(PbsDatastore, Effect36.succee
2323
2357
  }
2324
2358
  const after = yield* settle3(readOne(news), (row) => row !== undefined && matches(row, news));
2325
2359
  if (after === undefined || !matches(after, news)) {
2326
- return yield* Effect36.die(new Error(`${object2(news)}: the write returned no error but the datastore still does not ` + `match the declaration after 120s. PBS answered with task ${upid ?? "(none)"} ` + "-- read it with `proxmox-backup-manager task log <upid>`. A slow disk is a " + "plausible cause (see `settle`); a create over an existing chunk store is not, " + "because PBS refuses that outright rather than timing out."));
2360
+ return yield* Effect38.die(new Error(`${object2(news)}: the write returned no error but the datastore still does not ` + `match the declaration after 120s. PBS answered with task ${upid ?? "(none)"} ` + "-- read it with `proxmox-backup-manager task log <upid>`. A slow disk is a " + "plausible cause (see `settle`); a create over an existing chunk store is not, " + "because PBS refuses that outright rather than timing out."));
2327
2361
  }
2328
2362
  return after;
2329
2363
  }),
2330
- delete: Effect36.fn(function* ({ olds }) {
2364
+ delete: Effect38.fn(function* ({ olds }) {
2331
2365
  yield* pve(olds.target, "provision", "DELETE", object2(olds));
2332
2366
  const left = yield* settle3(readOne(olds), (row) => row === undefined);
2333
2367
  if (left !== undefined) {
2334
- return yield* Effect36.die(new Error(`${object2(olds)}: the DELETE returned no error but the datastore is still in ` + "datastore.cfg after 120s. Either a backup, verify or GC task still holds it, " + "or the provision role lacks Datastore.Allocate on /datastore/" + `${olds.name}. Read the task log with \`proxmox-backup-manager task log <upid>\`.`));
2368
+ return yield* Effect38.die(new Error(`${object2(olds)}: the DELETE returned no error but the datastore is still in ` + "datastore.cfg after 120s. Either a backup, verify or GC task still holds it, " + "or the provision role lacks Datastore.Allocate on /datastore/" + `${olds.name}. Read the task log with \`proxmox-backup-manager task log <upid>\`.`));
2335
2369
  }
2336
2370
  })
2337
2371
  })));
2338
2372
  // src/proxmox/pbs-prune-job.ts
2339
2373
  import { Resource as Resource19 } from "alchemy";
2340
2374
  import * as Provider19 from "alchemy/Provider";
2341
- import * as Effect37 from "effect/Effect";
2375
+ import * as Effect39 from "effect/Effect";
2342
2376
 
2343
2377
  // src/proxmox/pbs-prune-job-form.ts
2344
2378
  var KEEP_KEYS = [
@@ -2413,11 +2447,11 @@ var handlers15 = pveHandlers({
2413
2447
  path: (props) => `config/prune/${props.id}`,
2414
2448
  updateForm: updateBody3
2415
2449
  });
2416
- var PbsPruneJobProvider = () => Provider19.effect(PbsPruneJob, Effect37.succeed(PbsPruneJob.Provider.of(handlers15)));
2450
+ var PbsPruneJobProvider = () => Provider19.effect(PbsPruneJob, Effect39.succeed(PbsPruneJob.Provider.of(handlers15)));
2417
2451
  // src/proxmox/pbs-sync-job.ts
2418
2452
  import { Resource as Resource20 } from "alchemy";
2419
2453
  import * as Provider20 from "alchemy/Provider";
2420
- import * as Effect38 from "effect/Effect";
2454
+ import * as Effect40 from "effect/Effect";
2421
2455
 
2422
2456
  // src/proxmox/pbs-sync-job-form.ts
2423
2457
  var UNSET4 = -1;
@@ -2493,11 +2527,11 @@ var handlers16 = pveHandlers({
2493
2527
 
2494
2528
  // src/proxmox/pbs-sync-job.ts
2495
2529
  var PbsSyncJob = Resource20("Pbs.SyncJob");
2496
- var PbsSyncJobProvider = () => Provider20.effect(PbsSyncJob, Effect38.succeed(PbsSyncJob.Provider.of(handlers16)));
2530
+ var PbsSyncJobProvider = () => Provider20.effect(PbsSyncJob, Effect40.succeed(PbsSyncJob.Provider.of(handlers16)));
2497
2531
  // src/proxmox/pbs-verify-job.ts
2498
2532
  import { Resource as Resource21 } from "alchemy";
2499
2533
  import * as Provider21 from "alchemy/Provider";
2500
- import * as Effect39 from "effect/Effect";
2534
+ import * as Effect41 from "effect/Effect";
2501
2535
 
2502
2536
  // src/proxmox/pbs-verify-job-form.ts
2503
2537
  var rechecks = (ignoreVerified, outdatedAfter) => {
@@ -2541,11 +2575,11 @@ var handlers17 = pveHandlers({
2541
2575
  path: (props) => `config/verify/${props.id}`,
2542
2576
  updateForm: shape7
2543
2577
  });
2544
- var PbsVerifyJobProvider = () => Provider21.effect(PbsVerifyJob, Effect39.succeed(PbsVerifyJob.Provider.of(handlers17)));
2578
+ var PbsVerifyJobProvider = () => Provider21.effect(PbsVerifyJob, Effect41.succeed(PbsVerifyJob.Provider.of(handlers17)));
2545
2579
  // src/proxmox/pool.ts
2546
2580
  import { Resource as Resource22 } from "alchemy";
2547
2581
  import * as Provider22 from "alchemy/Provider";
2548
- import * as Effect40 from "effect/Effect";
2582
+ import * as Effect42 from "effect/Effect";
2549
2583
  var ProxmoxPool = Resource22("Proxmox.Pool");
2550
2584
  var poolCreateForm = (props) => ({
2551
2585
  comment: props.comment ?? "",
@@ -2569,11 +2603,11 @@ var handlers18 = pveHandlers({
2569
2603
  path: (props) => `pools/${props.poolid}`,
2570
2604
  updateForm: poolUpdateForm
2571
2605
  });
2572
- var ProxmoxPoolProvider = () => Provider22.effect(ProxmoxPool, Effect40.succeed(ProxmoxPool.Provider.of(handlers18)));
2606
+ var ProxmoxPoolProvider = () => Provider22.effect(ProxmoxPool, Effect42.succeed(ProxmoxPool.Provider.of(handlers18)));
2573
2607
  // src/proxmox/qemu.ts
2574
2608
  import { Resource as Resource23 } from "alchemy";
2575
2609
  import * as Provider23 from "alchemy/Provider";
2576
- import * as Effect41 from "effect/Effect";
2610
+ import * as Effect43 from "effect/Effect";
2577
2611
  var ProxmoxVm = Resource23("Proxmox.Vm");
2578
2612
  var shape8 = (props) => ({
2579
2613
  cores: String(props.cores ?? 1),
@@ -2599,11 +2633,11 @@ var handlers19 = pveHandlers({
2599
2633
  path: (props) => `nodes/${props.node}/qemu/${String(props.vmid)}/config`,
2600
2634
  updateForm: shape8
2601
2635
  });
2602
- var ProxmoxVmProvider = () => Provider23.effect(ProxmoxVm, Effect41.succeed(ProxmoxVm.Provider.of(handlers19)));
2636
+ var ProxmoxVmProvider = () => Provider23.effect(ProxmoxVm, Effect43.succeed(ProxmoxVm.Provider.of(handlers19)));
2603
2637
  // src/proxmox/replication-job.ts
2604
2638
  import { Resource as Resource24 } from "alchemy";
2605
2639
  import * as Provider24 from "alchemy/Provider";
2606
- import * as Effect42 from "effect/Effect";
2640
+ import * as Effect44 from "effect/Effect";
2607
2641
 
2608
2642
  // src/proxmox/replication-job-form.ts
2609
2643
  var DEFAULT_SCHEDULE = "*/15";
@@ -2653,11 +2687,11 @@ var handlers20 = pveHandlers({
2653
2687
  path: (props) => `cluster/replication/${jobId(props)}`,
2654
2688
  updateForm: updateBody5
2655
2689
  });
2656
- var ProxmoxReplicationJobProvider = () => Provider24.effect(ProxmoxReplicationJob, Effect42.succeed(ProxmoxReplicationJob.Provider.of(handlers20)));
2690
+ var ProxmoxReplicationJobProvider = () => Provider24.effect(ProxmoxReplicationJob, Effect44.succeed(ProxmoxReplicationJob.Provider.of(handlers20)));
2657
2691
  // src/proxmox/role.ts
2658
2692
  import { Resource as Resource25 } from "alchemy";
2659
2693
  import * as Provider25 from "alchemy/Provider";
2660
- import * as Effect43 from "effect/Effect";
2694
+ import * as Effect45 from "effect/Effect";
2661
2695
  var ProxmoxRole = Resource25("Proxmox.Role");
2662
2696
  var canonical = (privs) => [...new Set(privs.map((priv) => priv.trim()).filter((priv) => priv.length > 0))].sort();
2663
2697
  var livePrivs = (live) => {
@@ -2674,15 +2708,15 @@ var handlers21 = pveHandlers({
2674
2708
  path: (props) => `access/roles/${props.roleid}`,
2675
2709
  updateForm: (props) => ({ privs: canonical(props.privs).join(",") })
2676
2710
  });
2677
- var ProxmoxRoleProvider = () => Provider25.effect(ProxmoxRole, Effect43.succeed(ProxmoxRole.Provider.of(handlers21)));
2711
+ var ProxmoxRoleProvider = () => Provider25.effect(ProxmoxRole, Effect45.succeed(ProxmoxRole.Provider.of(handlers21)));
2678
2712
  // src/proxmox/sdn-apply.ts
2679
2713
  import { Resource as Resource26 } from "alchemy";
2680
2714
  import { isResolved as isResolved9 } from "alchemy/Diff";
2681
2715
  import * as Provider26 from "alchemy/Provider";
2682
- import * as Effect45 from "effect/Effect";
2716
+ import * as Effect47 from "effect/Effect";
2683
2717
 
2684
2718
  // src/proxmox/sdn-apply-read.ts
2685
- import * as Effect44 from "effect/Effect";
2719
+ import * as Effect46 from "effect/Effect";
2686
2720
  var MARKED = [
2687
2721
  "cluster/sdn/zones",
2688
2722
  "cluster/sdn/vnets",
@@ -2691,7 +2725,7 @@ var MARKED = [
2691
2725
  "cluster/sdn/route-maps"
2692
2726
  ];
2693
2727
  var subsystemAbsent = (error) => error instanceof PveError && error.status === 501;
2694
- var markedPending = (target) => Effect44.all(MARKED.map((collection2) => pve(target, "read", "GET", `${collection2}?pending=1`).pipe(Effect44.map((rows) => (rows ?? []).filter((row) => row.state !== undefined).length), Effect44.catchIf(subsystemAbsent, () => Effect44.succeed(0)))), { concurrency: "unbounded" }).pipe(Effect44.map((counts) => counts.reduce((total, count2) => total + count2, 0)));
2728
+ var markedPending = (target) => Effect46.all(MARKED.map((collection2) => pve(target, "read", "GET", `${collection2}?pending=1`).pipe(Effect46.map((rows) => (rows ?? []).filter((row) => row.state !== undefined).length), Effect46.catchIf(subsystemAbsent, () => Effect46.succeed(0)))), { concurrency: "unbounded" }).pipe(Effect46.map((counts) => counts.reduce((total, count2) => total + count2, 0)));
2695
2729
  var fabricStaged = (staged, running) => {
2696
2730
  if (staged === undefined && running === undefined)
2697
2731
  return 0;
@@ -2699,9 +2733,9 @@ var fabricStaged = (staged, running) => {
2699
2733
  return "inconsistent";
2700
2734
  return staged === running ? 0 : 1;
2701
2735
  };
2702
- var fabricPending = (target) => Effect44.all(["pending", "running"].map((view) => pve(target, "read", "GET", `cluster/sdn/fabrics/all?${view}=1`).pipe(Effect44.map(canonical2), Effect44.catchIf(subsystemAbsent, () => Effect44.succeed(undefined)))), { concurrency: "unbounded" }).pipe(Effect44.flatMap(([staged, running]) => {
2736
+ var fabricPending = (target) => Effect46.all(["pending", "running"].map((view) => pve(target, "read", "GET", `cluster/sdn/fabrics/all?${view}=1`).pipe(Effect46.map(canonical2), Effect46.catchIf(subsystemAbsent, () => Effect46.succeed(undefined)))), { concurrency: "unbounded" }).pipe(Effect46.flatMap(([staged, running]) => {
2703
2737
  const verdict = fabricStaged(staged, running);
2704
- return verdict === "inconsistent" ? Effect44.die(new Error("cluster/sdn/fabrics/all answered 501 for one of ?pending=1 and ?running=1 and not " + "the other. Refusing to read that as a staged fabric change.")) : Effect44.succeed(verdict);
2738
+ return verdict === "inconsistent" ? Effect46.die(new Error("cluster/sdn/fabrics/all answered 501 for one of ?pending=1 and ?running=1 and not " + "the other. Refusing to read that as a staged fabric change.")) : Effect46.succeed(verdict);
2705
2739
  }));
2706
2740
  var canonical2 = (value) => JSON.stringify(sortDeep(value));
2707
2741
  var sortDeep = (value) => {
@@ -2714,39 +2748,39 @@ var sortDeep = (value) => {
2714
2748
  }
2715
2749
  return value;
2716
2750
  };
2717
- var sdnPendingCount = (target) => Effect44.all([markedPending(target), fabricPending(target)], { concurrency: "unbounded" }).pipe(Effect44.map(([marked, fabric]) => marked + fabric));
2751
+ var sdnPendingCount = (target) => Effect46.all([markedPending(target), fabricPending(target)], { concurrency: "unbounded" }).pipe(Effect46.map(([marked, fabric]) => marked + fabric));
2718
2752
 
2719
2753
  // src/proxmox/sdn-apply.ts
2720
2754
  var ProxmoxSdnApply = Resource26("Proxmox.SdnApply");
2721
- var read3 = (props) => sdnPendingCount(props.target).pipe(Effect45.map((pending) => ({ pending })));
2722
- var ProxmoxSdnApplyProvider = () => Provider26.effect(ProxmoxSdnApply, Effect45.succeed(ProxmoxSdnApply.Provider.of({
2723
- list: () => Effect45.succeed([]),
2724
- read: Effect45.fn(function* ({ olds }) {
2755
+ var read3 = (props) => sdnPendingCount(props.target).pipe(Effect47.map((pending) => ({ pending })));
2756
+ var ProxmoxSdnApplyProvider = () => Provider26.effect(ProxmoxSdnApply, Effect47.succeed(ProxmoxSdnApply.Provider.of({
2757
+ list: () => Effect47.succeed([]),
2758
+ read: Effect47.fn(function* ({ olds }) {
2725
2759
  return yield* read3(olds);
2726
2760
  }),
2727
- diff: Effect45.fn(function* ({ news }) {
2761
+ diff: Effect47.fn(function* ({ news }) {
2728
2762
  if (!isResolved9(news))
2729
2763
  return;
2730
2764
  const { pending } = yield* read3(news);
2731
2765
  return pending === 0 ? { action: "noop" } : { action: "update" };
2732
2766
  }),
2733
- reconcile: Effect45.fn(function* ({ news }) {
2767
+ reconcile: Effect47.fn(function* ({ news }) {
2734
2768
  const staged = yield* read3(news);
2735
2769
  if (staged.pending === 0)
2736
2770
  return staged;
2737
2771
  yield* pve(news.target, "provision", "PUT", "cluster/sdn");
2738
2772
  const after = yield* read3(news);
2739
2773
  if (after.pending !== 0) {
2740
- return yield* Effect45.die(new Error(`PUT /cluster/sdn returned no error but ${String(after.pending)} SDN object(s) ` + "are still staged. The running config does not match the declared one -- check " + "`pvesh get /cluster/sdn/zones --pending 1` for the objects PVE refused."));
2774
+ return yield* Effect47.die(new Error(`PUT /cluster/sdn returned no error but ${String(after.pending)} SDN object(s) ` + "are still staged. The running config does not match the declared one -- check " + "`pvesh get /cluster/sdn/zones --pending 1` for the objects PVE refused."));
2741
2775
  }
2742
2776
  return after;
2743
2777
  }),
2744
- delete: () => Effect45.void
2778
+ delete: () => Effect47.void
2745
2779
  })));
2746
2780
  // src/proxmox/sdn-subnet.ts
2747
2781
  import { Resource as Resource27 } from "alchemy";
2748
2782
  import * as Provider27 from "alchemy/Provider";
2749
- import * as Effect46 from "effect/Effect";
2783
+ import * as Effect48 from "effect/Effect";
2750
2784
 
2751
2785
  // src/proxmox/sdn-subnet-form.ts
2752
2786
  var subnetId = (props) => `${props.zone}-${props.cidr.replace("/", "-")}`;
@@ -2802,11 +2836,11 @@ var handlers22 = pveHandlers({
2802
2836
  path: (props) => `cluster/sdn/vnets/${props.vnet}/subnets/${subnetId(props)}`,
2803
2837
  updateForm: updateForm2
2804
2838
  });
2805
- var ProxmoxSdnSubnetProvider = () => Provider27.effect(ProxmoxSdnSubnet, Effect46.succeed(ProxmoxSdnSubnet.Provider.of(handlers22)));
2839
+ var ProxmoxSdnSubnetProvider = () => Provider27.effect(ProxmoxSdnSubnet, Effect48.succeed(ProxmoxSdnSubnet.Provider.of(handlers22)));
2806
2840
  // src/proxmox/sdn-vnet.ts
2807
2841
  import { Resource as Resource28 } from "alchemy";
2808
2842
  import * as Provider28 from "alchemy/Provider";
2809
- import * as Effect47 from "effect/Effect";
2843
+ import * as Effect49 from "effect/Effect";
2810
2844
  var ProxmoxSdnVnet = Resource28("Proxmox.SdnVnet");
2811
2845
  var tagOf = (value) => typeof value === "number" ? value : undefined;
2812
2846
  var shape10 = (props) => {
@@ -2843,11 +2877,11 @@ var handlers23 = pveHandlers({
2843
2877
  path: (props) => `cluster/sdn/vnets/${props.vnet}`,
2844
2878
  updateForm: updateForm3
2845
2879
  });
2846
- var ProxmoxSdnVnetProvider = () => Provider28.effect(ProxmoxSdnVnet, Effect47.succeed(ProxmoxSdnVnet.Provider.of(handlers23)));
2880
+ var ProxmoxSdnVnetProvider = () => Provider28.effect(ProxmoxSdnVnet, Effect49.succeed(ProxmoxSdnVnet.Provider.of(handlers23)));
2847
2881
  // src/proxmox/sdn-zone.ts
2848
2882
  import { Resource as Resource29 } from "alchemy";
2849
2883
  import * as Provider29 from "alchemy/Provider";
2850
- import * as Effect48 from "effect/Effect";
2884
+ import * as Effect50 from "effect/Effect";
2851
2885
  var ProxmoxSdnZone = Resource29("Proxmox.SdnZone");
2852
2886
  var sameIpam = (live, declared) => (live === "" ? "pve" : live) === (declared === undefined || declared === "" ? "pve" : declared);
2853
2887
  var body6 = (props) => ({
@@ -2899,11 +2933,11 @@ var handlers24 = pveHandlers({
2899
2933
  return withClears(fields, clear);
2900
2934
  }
2901
2935
  });
2902
- var ProxmoxSdnZoneProvider = () => Provider29.effect(ProxmoxSdnZone, Effect48.succeed(ProxmoxSdnZone.Provider.of(handlers24)));
2936
+ var ProxmoxSdnZoneProvider = () => Provider29.effect(ProxmoxSdnZone, Effect50.succeed(ProxmoxSdnZone.Provider.of(handlers24)));
2903
2937
  // src/proxmox/storage.ts
2904
2938
  import { Resource as Resource30 } from "alchemy";
2905
2939
  import * as Provider30 from "alchemy/Provider";
2906
- import * as Effect49 from "effect/Effect";
2940
+ import * as Effect51 from "effect/Effect";
2907
2941
  var ProxmoxStorage = Resource30("Proxmox.Storage", {
2908
2942
  defaultRemovalPolicy: "retain"
2909
2943
  });
@@ -2948,11 +2982,11 @@ var handlers25 = pveHandlers({
2948
2982
  path: (props) => `storage/${props.storage}`,
2949
2983
  updateForm: mutable2
2950
2984
  });
2951
- var ProxmoxStorageProvider = () => Provider30.effect(ProxmoxStorage, Effect49.succeed(ProxmoxStorage.Provider.of(handlers25)));
2985
+ var ProxmoxStorageProvider = () => Provider30.effect(ProxmoxStorage, Effect51.succeed(ProxmoxStorage.Provider.of(handlers25)));
2952
2986
  // src/proxmox/user.ts
2953
2987
  import { Resource as Resource31 } from "alchemy";
2954
2988
  import * as Provider31 from "alchemy/Provider";
2955
- import * as Effect50 from "effect/Effect";
2989
+ import * as Effect52 from "effect/Effect";
2956
2990
  var ProxmoxUser = Resource31("Proxmox.User");
2957
2991
  var str3 = (value) => typeof value === "string" ? value : "";
2958
2992
  var int2 = (value) => {
@@ -2992,14 +3026,14 @@ var handlers26 = pveHandlers({
2992
3026
  path: (props) => `access/users/${props.userid}`,
2993
3027
  updateForm: shape11
2994
3028
  });
2995
- var ProxmoxUserProvider = () => Provider31.effect(ProxmoxUser, Effect50.succeed(ProxmoxUser.Provider.of(handlers26)));
3029
+ var ProxmoxUserProvider = () => Provider31.effect(ProxmoxUser, Effect52.succeed(ProxmoxUser.Provider.of(handlers26)));
2996
3030
  // src/proxmox/zfs-pool.ts
2997
3031
  import { Resource as Resource32 } from "alchemy";
2998
3032
  import * as Provider32 from "alchemy/Provider";
2999
- import * as Effect52 from "effect/Effect";
3033
+ import * as Effect54 from "effect/Effect";
3000
3034
 
3001
3035
  // src/proxmox/zfs-pool-write.ts
3002
- import * as Effect51 from "effect/Effect";
3036
+ import * as Effect53 from "effect/Effect";
3003
3037
  var createForm6 = (props) => ({
3004
3038
  devices: props.devices.join(","),
3005
3039
  name: props.name,
@@ -3009,21 +3043,21 @@ var createForm6 = (props) => ({
3009
3043
  ...props["draid-config"] === undefined ? {} : { "draid-config": props["draid-config"] }
3010
3044
  });
3011
3045
  var SETTLE_ATTEMPTS = 30;
3012
- var createPool = (props, collection2, path, read4) => Effect51.gen(function* () {
3046
+ var createPool = (props, collection2, path, read4) => Effect53.gen(function* () {
3013
3047
  const existing = yield* read4(props);
3014
3048
  if (existing !== undefined)
3015
3049
  return existing;
3016
3050
  const upid = yield* pve(props.target, "provision", "POST", collection2, createForm6(props));
3017
- const settle4 = (attempts) => Effect51.gen(function* () {
3051
+ const settle4 = (attempts) => Effect53.gen(function* () {
3018
3052
  const live = yield* read4(props);
3019
3053
  if (live !== undefined || attempts <= 0)
3020
3054
  return live;
3021
- yield* Effect51.sleep("2 seconds");
3055
+ yield* Effect53.sleep("2 seconds");
3022
3056
  return yield* settle4(attempts - 1);
3023
3057
  });
3024
3058
  const after = yield* settle4(SETTLE_ATTEMPTS);
3025
3059
  if (after === undefined) {
3026
- return yield* Effect51.die(new Error(`${path}: POST returned ${text(upid, "(no UPID)")} but the pool has not appeared. That ` + "POST only forks a `zfscreate` worker, so the task holds the real error -- read it " + `with \`pvesh get /nodes/${props.node}/tasks/<upid>/log\`. NOTHING WAS RETRIED AND ` + "NOTHING WAS CLEANED UP: if the worker reached `zpool create`, the declared devices " + "have already been written to."));
3060
+ return yield* Effect53.die(new Error(`${path}: POST returned ${text(upid, "(no UPID)")} but the pool has not appeared. That ` + "POST only forks a `zfscreate` worker, so the task holds the real error -- read it " + `with \`pvesh get /nodes/${props.node}/tasks/<upid>/log\`. NOTHING WAS RETRIED AND ` + "NOTHING WAS CLEANED UP: if the worker reached `zpool create`, the declared devices " + "have already been written to."));
3027
3061
  }
3028
3062
  return after;
3029
3063
  });
@@ -3058,12 +3092,12 @@ var spec2 = {
3058
3092
  var ops5 = pveOperations(spec2);
3059
3093
  var handlers27 = {
3060
3094
  ...pveHandlers(spec2),
3061
- delete: Effect52.fn(function* ({ olds }) {
3095
+ delete: Effect54.fn(function* ({ olds }) {
3062
3096
  yield* destroyPool(olds, spec2.path(olds));
3063
3097
  }),
3064
3098
  reconcile: ({ news }) => createPool(news, spec2.collection(news), spec2.path(news), ops5.read)
3065
3099
  };
3066
- var ProxmoxZfsPoolProvider = () => Provider32.effect(ProxmoxZfsPool, Effect52.succeed(ProxmoxZfsPool.Provider.of(handlers27)));
3100
+ var ProxmoxZfsPoolProvider = () => Provider32.effect(ProxmoxZfsPool, Effect54.succeed(ProxmoxZfsPool.Provider.of(handlers27)));
3067
3101
  export {
3068
3102
  PbsDatastore,
3069
3103
  PbsDatastoreProvider,
@@ -3120,5 +3154,5 @@ export {
3120
3154
  ProxmoxZfsPoolProvider
3121
3155
  };
3122
3156
 
3123
- //# debugId=2E96DC8F7406C81F64756E2164756E21
3157
+ //# debugId=6EEA5191A9F0C54064756E2164756E21
3124
3158
  //# sourceMappingURL=index.js.map