@calimero-network/mero-js 7.0.4 → 7.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -749,23 +749,61 @@ function unwrap(response) {
749
749
  return response?.data;
750
750
  }
751
751
  function compareSemver(a, b) {
752
- const pa = a.split(".");
753
- const pb = b.split(".");
754
- const n = Math.max(pa.length, pb.length);
752
+ const [coreA, preA] = splitVersion(a);
753
+ const [coreB, preB] = splitVersion(b);
754
+ const na = coreA.split(".");
755
+ const nb = coreB.split(".");
756
+ const n = Math.max(na.length, nb.length);
755
757
  for (let i = 0; i < n; i++) {
756
- const sa = pa[i] ?? "0";
757
- const sb = pb[i] ?? "0";
758
- const na = Number.parseInt(sa, 10);
759
- const nb = Number.parseInt(sb, 10);
760
- if (Number.isNaN(na) || Number.isNaN(nb)) {
761
- const c = sa.localeCompare(sb);
762
- if (c !== 0) return c;
763
- } else if (na !== nb) {
764
- return na - nb;
765
- }
758
+ const c = compareSemverId(na[i] ?? "0", nb[i] ?? "0");
759
+ if (c !== 0) return c;
760
+ }
761
+ if (preA === void 0 && preB === void 0) return 0;
762
+ if (preA === void 0) return 1;
763
+ if (preB === void 0) return -1;
764
+ const pa = preA.split(".");
765
+ const pb = preB.split(".");
766
+ const m = Math.max(pa.length, pb.length);
767
+ for (let i = 0; i < m; i++) {
768
+ if (i >= pa.length) return -1;
769
+ if (i >= pb.length) return 1;
770
+ const c = compareSemverId(pa[i], pb[i]);
771
+ if (c !== 0) return c;
766
772
  }
767
773
  return 0;
768
774
  }
775
+ function splitVersion(v) {
776
+ const core = v.split("+", 1)[0];
777
+ const dash = core.indexOf("-");
778
+ return dash === -1 ? [core, void 0] : [core.slice(0, dash), core.slice(dash + 1)];
779
+ }
780
+ function compareSemverId(a, b) {
781
+ const na = /^\d+$/.test(a);
782
+ const nb = /^\d+$/.test(b);
783
+ if (na && nb) {
784
+ const d = Number(a) - Number(b);
785
+ return d < 0 ? -1 : d > 0 ? 1 : 0;
786
+ }
787
+ if (na) return -1;
788
+ if (nb) return 1;
789
+ return a < b ? -1 : a > b ? 1 : 0;
790
+ }
791
+ async function fetchRegistry(url, kind, context) {
792
+ return withRetry(
793
+ async () => {
794
+ const resp = await fetch(url, { signal: AbortSignal.timeout(1e4) });
795
+ if (!resp.ok) {
796
+ const err = new Error(
797
+ `registry ${kind} fetch failed (${resp.status}) for ${context}`
798
+ );
799
+ err.status = resp.status;
800
+ throw err;
801
+ }
802
+ return resp;
803
+ },
804
+ { attempts: 3 }
805
+ );
806
+ }
769
807
  var AdminApiClient = class {
770
808
  constructor(httpClient) {
771
809
  this.httpClient = httpClient;
@@ -795,12 +833,7 @@ var AdminApiClient = class {
795
833
  `/api/v2/bundles/${encodeURIComponent(packageName)}/${encodeURIComponent(version)}`,
796
834
  base
797
835
  ).toString();
798
- const resp = await fetch(manifestUrl);
799
- if (!resp.ok) {
800
- throw new Error(
801
- `registry manifest fetch failed (${resp.status}) for ${packageName}@${version}`
802
- );
803
- }
836
+ const resp = await fetchRegistry(manifestUrl, "manifest", `${packageName}@${version}`);
804
837
  const bundle = await resp.json();
805
838
  const pkg = encodeURIComponent(bundle.package);
806
839
  const ver = encodeURIComponent(bundle.appVersion);
@@ -823,12 +856,7 @@ var AdminApiClient = class {
823
856
  async getRegistryVersions(registryUrl, packageName) {
824
857
  const url = new URL("/api/v2/bundles", new URL(registryUrl).origin);
825
858
  url.searchParams.set("package", packageName);
826
- const resp = await fetch(url.toString());
827
- if (!resp.ok) {
828
- throw new Error(
829
- `registry versions fetch failed (${resp.status}) for ${packageName}`
830
- );
831
- }
859
+ const resp = await fetchRegistry(url.toString(), "versions", packageName);
832
860
  const bundles = await resp.json();
833
861
  return (Array.isArray(bundles) ? bundles : []).map((b) => b.appVersion).filter((v) => typeof v === "string").sort((a, b) => compareSemver(b, a));
834
862
  }
@@ -1556,6 +1584,7 @@ var SseClient = class {
1556
1584
  this.abortController = null;
1557
1585
  this.reconnectTimer = null;
1558
1586
  this.subscribedContextIds = /* @__PURE__ */ new Set();
1587
+ this.subscribedGroupIds = /* @__PURE__ */ new Set();
1559
1588
  this.closed = false;
1560
1589
  this.listeners = { connect: [], event: [], error: [] };
1561
1590
  this.baseUrl = opts.baseUrl.replace(/\/+$/, "");
@@ -1678,21 +1707,25 @@ var SseClient = class {
1678
1707
  if (msg.type === "connect" && msg.session_id) {
1679
1708
  this.sessionId = msg.session_id;
1680
1709
  this.emit("connect", msg.session_id);
1681
- if (this.subscribedContextIds.size > 0) {
1682
- this.sendSubscription("subscribe", [...this.subscribedContextIds]);
1710
+ if (this.subscribedContextIds.size > 0 || this.subscribedGroupIds.size > 0) {
1711
+ this.sendSubscription("subscribe", {
1712
+ contextIds: [...this.subscribedContextIds],
1713
+ groupIds: [...this.subscribedGroupIds]
1714
+ });
1683
1715
  }
1684
1716
  return;
1685
1717
  }
1686
- if (msg.result && msg.result.contextId) {
1687
- let eventData = msg.result.data;
1688
- if (Array.isArray(eventData)) {
1689
- try {
1690
- const bytes = new Uint8Array(eventData);
1691
- const text = new TextDecoder().decode(bytes);
1692
- eventData = JSON.parse(text);
1693
- } catch {
1694
- }
1718
+ if (!msg.result) return;
1719
+ let eventData = msg.result.data;
1720
+ if (Array.isArray(eventData)) {
1721
+ try {
1722
+ const bytes = new Uint8Array(eventData);
1723
+ const text = new TextDecoder().decode(bytes);
1724
+ eventData = JSON.parse(text);
1725
+ } catch {
1695
1726
  }
1727
+ }
1728
+ if (msg.result.contextId) {
1696
1729
  this.emit("event", {
1697
1730
  contextId: msg.result.contextId,
1698
1731
  // Forward the event tag (sibling of `data` in core's flattened
@@ -1700,31 +1733,52 @@ var SseClient = class {
1700
1733
  type: msg.result.type,
1701
1734
  data: eventData
1702
1735
  });
1736
+ return;
1737
+ }
1738
+ if (msg.result.groupId) {
1739
+ this.emit("event", {
1740
+ groupId: msg.result.groupId,
1741
+ type: msg.result.type,
1742
+ data: eventData
1743
+ });
1703
1744
  }
1704
1745
  } catch {
1705
1746
  }
1706
1747
  }
1707
- async subscribe(contextIds) {
1708
- const newIds = contextIds.filter((id) => !this.subscribedContextIds.has(id));
1709
- for (const id of contextIds) {
1748
+ async subscribe(idsOrOpts) {
1749
+ const opts = Array.isArray(idsOrOpts) ? { contextIds: idsOrOpts } : idsOrOpts;
1750
+ const newContextIds = (opts.contextIds ?? []).filter((id) => !this.subscribedContextIds.has(id));
1751
+ const newGroupIds = (opts.groupIds ?? []).filter((id) => !this.subscribedGroupIds.has(id));
1752
+ for (const id of opts.contextIds ?? []) {
1710
1753
  this.subscribedContextIds.add(id);
1711
1754
  }
1712
- if (newIds.length > 0 && this.sessionId) {
1713
- await this.sendSubscription("subscribe", newIds);
1755
+ for (const id of opts.groupIds ?? []) {
1756
+ this.subscribedGroupIds.add(id);
1757
+ }
1758
+ if ((newContextIds.length > 0 || newGroupIds.length > 0) && this.sessionId) {
1759
+ await this.sendSubscription("subscribe", { contextIds: newContextIds, groupIds: newGroupIds });
1714
1760
  }
1715
1761
  }
1716
- async unsubscribe(contextIds) {
1717
- const hadIds = contextIds.filter((id) => this.subscribedContextIds.has(id));
1718
- for (const id of contextIds) {
1762
+ async unsubscribe(idsOrOpts) {
1763
+ const opts = Array.isArray(idsOrOpts) ? { contextIds: idsOrOpts } : idsOrOpts;
1764
+ const hadContextIds = (opts.contextIds ?? []).filter((id) => this.subscribedContextIds.has(id));
1765
+ const hadGroupIds = (opts.groupIds ?? []).filter((id) => this.subscribedGroupIds.has(id));
1766
+ for (const id of opts.contextIds ?? []) {
1719
1767
  this.subscribedContextIds.delete(id);
1720
1768
  }
1721
- if (hadIds.length > 0 && this.sessionId) {
1722
- await this.sendSubscription("unsubscribe", hadIds);
1769
+ for (const id of opts.groupIds ?? []) {
1770
+ this.subscribedGroupIds.delete(id);
1771
+ }
1772
+ if ((hadContextIds.length > 0 || hadGroupIds.length > 0) && this.sessionId) {
1773
+ await this.sendSubscription("unsubscribe", { contextIds: hadContextIds, groupIds: hadGroupIds });
1723
1774
  }
1724
1775
  }
1725
- async sendSubscription(method, contextIds) {
1776
+ async sendSubscription(method, ids) {
1726
1777
  try {
1727
1778
  const token = await this.getAuthToken();
1779
+ const params = {};
1780
+ if (ids.contextIds && ids.contextIds.length > 0) params.contextIds = ids.contextIds;
1781
+ if (ids.groupIds && ids.groupIds.length > 0) params.groupIds = ids.groupIds;
1728
1782
  const response = await fetch(`${this.baseUrl}/sse/subscription`, {
1729
1783
  method: "POST",
1730
1784
  headers: {
@@ -1734,7 +1788,7 @@ var SseClient = class {
1734
1788
  body: JSON.stringify({
1735
1789
  id: this.sessionId,
1736
1790
  method,
1737
- params: { contextIds }
1791
+ params
1738
1792
  })
1739
1793
  });
1740
1794
  if (!response.ok) {
@@ -1774,6 +1828,7 @@ var SseClient = class {
1774
1828
  }
1775
1829
  this.sessionId = null;
1776
1830
  this.subscribedContextIds.clear();
1831
+ this.subscribedGroupIds.clear();
1777
1832
  }
1778
1833
  };
1779
1834
 
@@ -1785,6 +1840,7 @@ var _WsClient = class _WsClient {
1785
1840
  this.reconnectAttempt = 0;
1786
1841
  this.reconnectTimer = null;
1787
1842
  this.subscribedContextIds = /* @__PURE__ */ new Set();
1843
+ this.subscribedGroupIds = /* @__PURE__ */ new Set();
1788
1844
  this.listeners = { connect: [], event: [], error: [] };
1789
1845
  this.baseUrl = opts.baseUrl.replace(/\/+$/, "");
1790
1846
  this.getAuthToken = opts.getAuthToken;
@@ -1816,7 +1872,7 @@ var _WsClient = class _WsClient {
1816
1872
  }
1817
1873
  }
1818
1874
  async connect() {
1819
- if (this.ws && (this.ws.readyState === WebSocket.CONNECTING || this.ws.readyState === WebSocket.OPEN)) {
1875
+ if (this.ws && (this.ws.readyState === 0 || this.ws.readyState === 1)) {
1820
1876
  return;
1821
1877
  }
1822
1878
  this.closed = false;
@@ -1830,13 +1886,7 @@ var _WsClient = class _WsClient {
1830
1886
  this.ws.onopen = () => {
1831
1887
  this.reconnectAttempt = 0;
1832
1888
  this.emit("connect");
1833
- if (this.subscribedContextIds.size > 0) {
1834
- this.sendMessage({
1835
- id: null,
1836
- method: "subscribe",
1837
- params: { contextIds: [...this.subscribedContextIds] }
1838
- });
1839
- }
1889
+ this.resubscribeAfterReconnect();
1840
1890
  };
1841
1891
  this.ws.onmessage = (event) => {
1842
1892
  this.handleMessage(event.data);
@@ -1860,16 +1910,17 @@ var _WsClient = class _WsClient {
1860
1910
  if (typeof raw !== "string") return;
1861
1911
  try {
1862
1912
  const msg = JSON.parse(raw);
1863
- if (msg.result && msg.result.contextId) {
1864
- let eventData = msg.result.data;
1865
- if (Array.isArray(eventData)) {
1866
- try {
1867
- const bytes = new Uint8Array(eventData);
1868
- const text = new TextDecoder().decode(bytes);
1869
- eventData = JSON.parse(text);
1870
- } catch {
1871
- }
1913
+ if (!msg.result) return;
1914
+ let eventData = msg.result.data;
1915
+ if (Array.isArray(eventData)) {
1916
+ try {
1917
+ const bytes = new Uint8Array(eventData);
1918
+ const text = new TextDecoder().decode(bytes);
1919
+ eventData = JSON.parse(text);
1920
+ } catch {
1872
1921
  }
1922
+ }
1923
+ if (msg.result.contextId) {
1873
1924
  this.emit("event", {
1874
1925
  contextId: msg.result.contextId,
1875
1926
  // Forward the event tag (sibling of `data` in core's flattened
@@ -1877,36 +1928,66 @@ var _WsClient = class _WsClient {
1877
1928
  type: msg.result.type,
1878
1929
  data: eventData
1879
1930
  });
1931
+ return;
1932
+ }
1933
+ if (msg.result.groupId) {
1934
+ this.emit("event", {
1935
+ groupId: msg.result.groupId,
1936
+ type: msg.result.type,
1937
+ data: eventData
1938
+ });
1880
1939
  }
1881
1940
  } catch {
1882
1941
  }
1883
1942
  }
1884
- subscribe(contextIds) {
1885
- for (const id of contextIds) {
1943
+ subscribe(idsOrOpts) {
1944
+ const opts = Array.isArray(idsOrOpts) ? { contextIds: idsOrOpts } : idsOrOpts;
1945
+ for (const id of opts.contextIds ?? []) {
1886
1946
  this.subscribedContextIds.add(id);
1887
1947
  }
1888
- if (this.ws && this.ws.readyState === WebSocket.OPEN) {
1948
+ for (const id of opts.groupIds ?? []) {
1949
+ this.subscribedGroupIds.add(id);
1950
+ }
1951
+ if (this.ws && this.ws.readyState === 1) {
1889
1952
  this.sendMessage({
1890
1953
  id: null,
1891
1954
  method: "subscribe",
1892
- params: { contextIds }
1955
+ params: this.buildSubscriptionParams(opts.contextIds ?? [], opts.groupIds ?? [])
1893
1956
  });
1894
1957
  }
1895
1958
  }
1896
- unsubscribe(contextIds) {
1897
- for (const id of contextIds) {
1959
+ unsubscribe(idsOrOpts) {
1960
+ const opts = Array.isArray(idsOrOpts) ? { contextIds: idsOrOpts } : idsOrOpts;
1961
+ for (const id of opts.contextIds ?? []) {
1898
1962
  this.subscribedContextIds.delete(id);
1899
1963
  }
1900
- if (this.ws && this.ws.readyState === WebSocket.OPEN) {
1964
+ for (const id of opts.groupIds ?? []) {
1965
+ this.subscribedGroupIds.delete(id);
1966
+ }
1967
+ if (this.ws && this.ws.readyState === 1) {
1901
1968
  this.sendMessage({
1902
1969
  id: null,
1903
1970
  method: "unsubscribe",
1904
- params: { contextIds }
1971
+ params: this.buildSubscriptionParams(opts.contextIds ?? [], opts.groupIds ?? [])
1905
1972
  });
1906
1973
  }
1907
1974
  }
1975
+ resubscribeAfterReconnect() {
1976
+ if (this.subscribedContextIds.size === 0 && this.subscribedGroupIds.size === 0) return;
1977
+ this.sendMessage({
1978
+ id: null,
1979
+ method: "subscribe",
1980
+ params: this.buildSubscriptionParams([...this.subscribedContextIds], [...this.subscribedGroupIds])
1981
+ });
1982
+ }
1983
+ buildSubscriptionParams(contextIds, groupIds) {
1984
+ const params = {};
1985
+ if (contextIds.length > 0) params.contextIds = contextIds;
1986
+ if (groupIds.length > 0) params.groupIds = groupIds;
1987
+ return params;
1988
+ }
1908
1989
  sendMessage(msg) {
1909
- if (this.ws && this.ws.readyState === WebSocket.OPEN) {
1990
+ if (this.ws && this.ws.readyState === 1) {
1910
1991
  this.ws.send(JSON.stringify(msg));
1911
1992
  }
1912
1993
  }
@@ -1937,6 +2018,7 @@ var _WsClient = class _WsClient {
1937
2018
  this.ws = null;
1938
2019
  }
1939
2020
  this.subscribedContextIds.clear();
2021
+ this.subscribedGroupIds.clear();
1940
2022
  }
1941
2023
  };
1942
2024
  _WsClient.MAX_BACKOFF_MS = 3e4;