@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.d.ts CHANGED
@@ -11,7 +11,7 @@ export { RpcClient, RpcError } from './rpc';
11
11
  export type { MigrateMyEntriesSummary } from './rpc';
12
12
  export type { ExecuteParams } from './rpc';
13
13
  export { SseClient, WsClient } from './events';
14
- export type { SseEventData, WsEventData, AppVersionChangedEvent } from './events';
14
+ export type { SseEventData, WsEventData, AppVersionChangedEvent, GroupMembershipEventData } from './events';
15
15
  export * from './cloud';
16
16
  export * from './capabilities';
17
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACjD,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGzD,cAAc,eAAe,CAAC;AAG9B,cAAc,YAAY,CAAC;AAG3B,cAAc,aAAa,CAAC;AAG5B,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC9D,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAGnE,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AACzE,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGhD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,YAAY,EAAE,uBAAuB,EAAE,MAAM,OAAO,CAAC;AACrD,YAAY,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAG3C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAC/C,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAGlF,cAAc,SAAS,CAAC;AAGxB,cAAc,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACjD,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGzD,cAAc,eAAe,CAAC;AAG9B,cAAc,YAAY,CAAC;AAG3B,cAAc,aAAa,CAAC;AAG5B,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC9D,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAGnE,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AACzE,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGhD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,YAAY,EAAE,uBAAuB,EAAE,MAAM,OAAO,CAAC;AACrD,YAAY,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAG3C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAC/C,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AAG5G,cAAc,SAAS,CAAC;AAGxB,cAAc,gBAAgB,CAAC"}
package/dist/index.mjs CHANGED
@@ -688,23 +688,61 @@ function unwrap(response) {
688
688
  return response?.data;
689
689
  }
690
690
  function compareSemver(a, b) {
691
- const pa = a.split(".");
692
- const pb = b.split(".");
693
- const n = Math.max(pa.length, pb.length);
691
+ const [coreA, preA] = splitVersion(a);
692
+ const [coreB, preB] = splitVersion(b);
693
+ const na = coreA.split(".");
694
+ const nb = coreB.split(".");
695
+ const n = Math.max(na.length, nb.length);
694
696
  for (let i = 0; i < n; i++) {
695
- const sa = pa[i] ?? "0";
696
- const sb = pb[i] ?? "0";
697
- const na = Number.parseInt(sa, 10);
698
- const nb = Number.parseInt(sb, 10);
699
- if (Number.isNaN(na) || Number.isNaN(nb)) {
700
- const c = sa.localeCompare(sb);
701
- if (c !== 0) return c;
702
- } else if (na !== nb) {
703
- return na - nb;
704
- }
697
+ const c = compareSemverId(na[i] ?? "0", nb[i] ?? "0");
698
+ if (c !== 0) return c;
699
+ }
700
+ if (preA === void 0 && preB === void 0) return 0;
701
+ if (preA === void 0) return 1;
702
+ if (preB === void 0) return -1;
703
+ const pa = preA.split(".");
704
+ const pb = preB.split(".");
705
+ const m = Math.max(pa.length, pb.length);
706
+ for (let i = 0; i < m; i++) {
707
+ if (i >= pa.length) return -1;
708
+ if (i >= pb.length) return 1;
709
+ const c = compareSemverId(pa[i], pb[i]);
710
+ if (c !== 0) return c;
705
711
  }
706
712
  return 0;
707
713
  }
714
+ function splitVersion(v) {
715
+ const core = v.split("+", 1)[0];
716
+ const dash = core.indexOf("-");
717
+ return dash === -1 ? [core, void 0] : [core.slice(0, dash), core.slice(dash + 1)];
718
+ }
719
+ function compareSemverId(a, b) {
720
+ const na = /^\d+$/.test(a);
721
+ const nb = /^\d+$/.test(b);
722
+ if (na && nb) {
723
+ const d = Number(a) - Number(b);
724
+ return d < 0 ? -1 : d > 0 ? 1 : 0;
725
+ }
726
+ if (na) return -1;
727
+ if (nb) return 1;
728
+ return a < b ? -1 : a > b ? 1 : 0;
729
+ }
730
+ async function fetchRegistry(url, kind, context) {
731
+ return withRetry(
732
+ async () => {
733
+ const resp = await fetch(url, { signal: AbortSignal.timeout(1e4) });
734
+ if (!resp.ok) {
735
+ const err = new Error(
736
+ `registry ${kind} fetch failed (${resp.status}) for ${context}`
737
+ );
738
+ err.status = resp.status;
739
+ throw err;
740
+ }
741
+ return resp;
742
+ },
743
+ { attempts: 3 }
744
+ );
745
+ }
708
746
  var AdminApiClient = class {
709
747
  constructor(httpClient) {
710
748
  this.httpClient = httpClient;
@@ -734,12 +772,7 @@ var AdminApiClient = class {
734
772
  `/api/v2/bundles/${encodeURIComponent(packageName)}/${encodeURIComponent(version)}`,
735
773
  base
736
774
  ).toString();
737
- const resp = await fetch(manifestUrl);
738
- if (!resp.ok) {
739
- throw new Error(
740
- `registry manifest fetch failed (${resp.status}) for ${packageName}@${version}`
741
- );
742
- }
775
+ const resp = await fetchRegistry(manifestUrl, "manifest", `${packageName}@${version}`);
743
776
  const bundle = await resp.json();
744
777
  const pkg = encodeURIComponent(bundle.package);
745
778
  const ver = encodeURIComponent(bundle.appVersion);
@@ -762,12 +795,7 @@ var AdminApiClient = class {
762
795
  async getRegistryVersions(registryUrl, packageName) {
763
796
  const url = new URL("/api/v2/bundles", new URL(registryUrl).origin);
764
797
  url.searchParams.set("package", packageName);
765
- const resp = await fetch(url.toString());
766
- if (!resp.ok) {
767
- throw new Error(
768
- `registry versions fetch failed (${resp.status}) for ${packageName}`
769
- );
770
- }
798
+ const resp = await fetchRegistry(url.toString(), "versions", packageName);
771
799
  const bundles = await resp.json();
772
800
  return (Array.isArray(bundles) ? bundles : []).map((b) => b.appVersion).filter((v) => typeof v === "string").sort((a, b) => compareSemver(b, a));
773
801
  }
@@ -1495,6 +1523,7 @@ var SseClient = class {
1495
1523
  this.abortController = null;
1496
1524
  this.reconnectTimer = null;
1497
1525
  this.subscribedContextIds = /* @__PURE__ */ new Set();
1526
+ this.subscribedGroupIds = /* @__PURE__ */ new Set();
1498
1527
  this.closed = false;
1499
1528
  this.listeners = { connect: [], event: [], error: [] };
1500
1529
  this.baseUrl = opts.baseUrl.replace(/\/+$/, "");
@@ -1617,21 +1646,25 @@ var SseClient = class {
1617
1646
  if (msg.type === "connect" && msg.session_id) {
1618
1647
  this.sessionId = msg.session_id;
1619
1648
  this.emit("connect", msg.session_id);
1620
- if (this.subscribedContextIds.size > 0) {
1621
- this.sendSubscription("subscribe", [...this.subscribedContextIds]);
1649
+ if (this.subscribedContextIds.size > 0 || this.subscribedGroupIds.size > 0) {
1650
+ this.sendSubscription("subscribe", {
1651
+ contextIds: [...this.subscribedContextIds],
1652
+ groupIds: [...this.subscribedGroupIds]
1653
+ });
1622
1654
  }
1623
1655
  return;
1624
1656
  }
1625
- if (msg.result && msg.result.contextId) {
1626
- let eventData = msg.result.data;
1627
- if (Array.isArray(eventData)) {
1628
- try {
1629
- const bytes = new Uint8Array(eventData);
1630
- const text = new TextDecoder().decode(bytes);
1631
- eventData = JSON.parse(text);
1632
- } catch {
1633
- }
1657
+ if (!msg.result) return;
1658
+ let eventData = msg.result.data;
1659
+ if (Array.isArray(eventData)) {
1660
+ try {
1661
+ const bytes = new Uint8Array(eventData);
1662
+ const text = new TextDecoder().decode(bytes);
1663
+ eventData = JSON.parse(text);
1664
+ } catch {
1634
1665
  }
1666
+ }
1667
+ if (msg.result.contextId) {
1635
1668
  this.emit("event", {
1636
1669
  contextId: msg.result.contextId,
1637
1670
  // Forward the event tag (sibling of `data` in core's flattened
@@ -1639,31 +1672,52 @@ var SseClient = class {
1639
1672
  type: msg.result.type,
1640
1673
  data: eventData
1641
1674
  });
1675
+ return;
1676
+ }
1677
+ if (msg.result.groupId) {
1678
+ this.emit("event", {
1679
+ groupId: msg.result.groupId,
1680
+ type: msg.result.type,
1681
+ data: eventData
1682
+ });
1642
1683
  }
1643
1684
  } catch {
1644
1685
  }
1645
1686
  }
1646
- async subscribe(contextIds) {
1647
- const newIds = contextIds.filter((id) => !this.subscribedContextIds.has(id));
1648
- for (const id of contextIds) {
1687
+ async subscribe(idsOrOpts) {
1688
+ const opts = Array.isArray(idsOrOpts) ? { contextIds: idsOrOpts } : idsOrOpts;
1689
+ const newContextIds = (opts.contextIds ?? []).filter((id) => !this.subscribedContextIds.has(id));
1690
+ const newGroupIds = (opts.groupIds ?? []).filter((id) => !this.subscribedGroupIds.has(id));
1691
+ for (const id of opts.contextIds ?? []) {
1649
1692
  this.subscribedContextIds.add(id);
1650
1693
  }
1651
- if (newIds.length > 0 && this.sessionId) {
1652
- await this.sendSubscription("subscribe", newIds);
1694
+ for (const id of opts.groupIds ?? []) {
1695
+ this.subscribedGroupIds.add(id);
1696
+ }
1697
+ if ((newContextIds.length > 0 || newGroupIds.length > 0) && this.sessionId) {
1698
+ await this.sendSubscription("subscribe", { contextIds: newContextIds, groupIds: newGroupIds });
1653
1699
  }
1654
1700
  }
1655
- async unsubscribe(contextIds) {
1656
- const hadIds = contextIds.filter((id) => this.subscribedContextIds.has(id));
1657
- for (const id of contextIds) {
1701
+ async unsubscribe(idsOrOpts) {
1702
+ const opts = Array.isArray(idsOrOpts) ? { contextIds: idsOrOpts } : idsOrOpts;
1703
+ const hadContextIds = (opts.contextIds ?? []).filter((id) => this.subscribedContextIds.has(id));
1704
+ const hadGroupIds = (opts.groupIds ?? []).filter((id) => this.subscribedGroupIds.has(id));
1705
+ for (const id of opts.contextIds ?? []) {
1658
1706
  this.subscribedContextIds.delete(id);
1659
1707
  }
1660
- if (hadIds.length > 0 && this.sessionId) {
1661
- await this.sendSubscription("unsubscribe", hadIds);
1708
+ for (const id of opts.groupIds ?? []) {
1709
+ this.subscribedGroupIds.delete(id);
1710
+ }
1711
+ if ((hadContextIds.length > 0 || hadGroupIds.length > 0) && this.sessionId) {
1712
+ await this.sendSubscription("unsubscribe", { contextIds: hadContextIds, groupIds: hadGroupIds });
1662
1713
  }
1663
1714
  }
1664
- async sendSubscription(method, contextIds) {
1715
+ async sendSubscription(method, ids) {
1665
1716
  try {
1666
1717
  const token = await this.getAuthToken();
1718
+ const params = {};
1719
+ if (ids.contextIds && ids.contextIds.length > 0) params.contextIds = ids.contextIds;
1720
+ if (ids.groupIds && ids.groupIds.length > 0) params.groupIds = ids.groupIds;
1667
1721
  const response = await fetch(`${this.baseUrl}/sse/subscription`, {
1668
1722
  method: "POST",
1669
1723
  headers: {
@@ -1673,7 +1727,7 @@ var SseClient = class {
1673
1727
  body: JSON.stringify({
1674
1728
  id: this.sessionId,
1675
1729
  method,
1676
- params: { contextIds }
1730
+ params
1677
1731
  })
1678
1732
  });
1679
1733
  if (!response.ok) {
@@ -1713,6 +1767,7 @@ var SseClient = class {
1713
1767
  }
1714
1768
  this.sessionId = null;
1715
1769
  this.subscribedContextIds.clear();
1770
+ this.subscribedGroupIds.clear();
1716
1771
  }
1717
1772
  };
1718
1773
 
@@ -1724,6 +1779,7 @@ var _WsClient = class _WsClient {
1724
1779
  this.reconnectAttempt = 0;
1725
1780
  this.reconnectTimer = null;
1726
1781
  this.subscribedContextIds = /* @__PURE__ */ new Set();
1782
+ this.subscribedGroupIds = /* @__PURE__ */ new Set();
1727
1783
  this.listeners = { connect: [], event: [], error: [] };
1728
1784
  this.baseUrl = opts.baseUrl.replace(/\/+$/, "");
1729
1785
  this.getAuthToken = opts.getAuthToken;
@@ -1755,7 +1811,7 @@ var _WsClient = class _WsClient {
1755
1811
  }
1756
1812
  }
1757
1813
  async connect() {
1758
- if (this.ws && (this.ws.readyState === WebSocket.CONNECTING || this.ws.readyState === WebSocket.OPEN)) {
1814
+ if (this.ws && (this.ws.readyState === 0 || this.ws.readyState === 1)) {
1759
1815
  return;
1760
1816
  }
1761
1817
  this.closed = false;
@@ -1769,13 +1825,7 @@ var _WsClient = class _WsClient {
1769
1825
  this.ws.onopen = () => {
1770
1826
  this.reconnectAttempt = 0;
1771
1827
  this.emit("connect");
1772
- if (this.subscribedContextIds.size > 0) {
1773
- this.sendMessage({
1774
- id: null,
1775
- method: "subscribe",
1776
- params: { contextIds: [...this.subscribedContextIds] }
1777
- });
1778
- }
1828
+ this.resubscribeAfterReconnect();
1779
1829
  };
1780
1830
  this.ws.onmessage = (event) => {
1781
1831
  this.handleMessage(event.data);
@@ -1799,16 +1849,17 @@ var _WsClient = class _WsClient {
1799
1849
  if (typeof raw !== "string") return;
1800
1850
  try {
1801
1851
  const msg = JSON.parse(raw);
1802
- if (msg.result && msg.result.contextId) {
1803
- let eventData = msg.result.data;
1804
- if (Array.isArray(eventData)) {
1805
- try {
1806
- const bytes = new Uint8Array(eventData);
1807
- const text = new TextDecoder().decode(bytes);
1808
- eventData = JSON.parse(text);
1809
- } catch {
1810
- }
1852
+ if (!msg.result) return;
1853
+ let eventData = msg.result.data;
1854
+ if (Array.isArray(eventData)) {
1855
+ try {
1856
+ const bytes = new Uint8Array(eventData);
1857
+ const text = new TextDecoder().decode(bytes);
1858
+ eventData = JSON.parse(text);
1859
+ } catch {
1811
1860
  }
1861
+ }
1862
+ if (msg.result.contextId) {
1812
1863
  this.emit("event", {
1813
1864
  contextId: msg.result.contextId,
1814
1865
  // Forward the event tag (sibling of `data` in core's flattened
@@ -1816,36 +1867,66 @@ var _WsClient = class _WsClient {
1816
1867
  type: msg.result.type,
1817
1868
  data: eventData
1818
1869
  });
1870
+ return;
1871
+ }
1872
+ if (msg.result.groupId) {
1873
+ this.emit("event", {
1874
+ groupId: msg.result.groupId,
1875
+ type: msg.result.type,
1876
+ data: eventData
1877
+ });
1819
1878
  }
1820
1879
  } catch {
1821
1880
  }
1822
1881
  }
1823
- subscribe(contextIds) {
1824
- for (const id of contextIds) {
1882
+ subscribe(idsOrOpts) {
1883
+ const opts = Array.isArray(idsOrOpts) ? { contextIds: idsOrOpts } : idsOrOpts;
1884
+ for (const id of opts.contextIds ?? []) {
1825
1885
  this.subscribedContextIds.add(id);
1826
1886
  }
1827
- if (this.ws && this.ws.readyState === WebSocket.OPEN) {
1887
+ for (const id of opts.groupIds ?? []) {
1888
+ this.subscribedGroupIds.add(id);
1889
+ }
1890
+ if (this.ws && this.ws.readyState === 1) {
1828
1891
  this.sendMessage({
1829
1892
  id: null,
1830
1893
  method: "subscribe",
1831
- params: { contextIds }
1894
+ params: this.buildSubscriptionParams(opts.contextIds ?? [], opts.groupIds ?? [])
1832
1895
  });
1833
1896
  }
1834
1897
  }
1835
- unsubscribe(contextIds) {
1836
- for (const id of contextIds) {
1898
+ unsubscribe(idsOrOpts) {
1899
+ const opts = Array.isArray(idsOrOpts) ? { contextIds: idsOrOpts } : idsOrOpts;
1900
+ for (const id of opts.contextIds ?? []) {
1837
1901
  this.subscribedContextIds.delete(id);
1838
1902
  }
1839
- if (this.ws && this.ws.readyState === WebSocket.OPEN) {
1903
+ for (const id of opts.groupIds ?? []) {
1904
+ this.subscribedGroupIds.delete(id);
1905
+ }
1906
+ if (this.ws && this.ws.readyState === 1) {
1840
1907
  this.sendMessage({
1841
1908
  id: null,
1842
1909
  method: "unsubscribe",
1843
- params: { contextIds }
1910
+ params: this.buildSubscriptionParams(opts.contextIds ?? [], opts.groupIds ?? [])
1844
1911
  });
1845
1912
  }
1846
1913
  }
1914
+ resubscribeAfterReconnect() {
1915
+ if (this.subscribedContextIds.size === 0 && this.subscribedGroupIds.size === 0) return;
1916
+ this.sendMessage({
1917
+ id: null,
1918
+ method: "subscribe",
1919
+ params: this.buildSubscriptionParams([...this.subscribedContextIds], [...this.subscribedGroupIds])
1920
+ });
1921
+ }
1922
+ buildSubscriptionParams(contextIds, groupIds) {
1923
+ const params = {};
1924
+ if (contextIds.length > 0) params.contextIds = contextIds;
1925
+ if (groupIds.length > 0) params.groupIds = groupIds;
1926
+ return params;
1927
+ }
1847
1928
  sendMessage(msg) {
1848
- if (this.ws && this.ws.readyState === WebSocket.OPEN) {
1929
+ if (this.ws && this.ws.readyState === 1) {
1849
1930
  this.ws.send(JSON.stringify(msg));
1850
1931
  }
1851
1932
  }
@@ -1876,6 +1957,7 @@ var _WsClient = class _WsClient {
1876
1957
  this.ws = null;
1877
1958
  }
1878
1959
  this.subscribedContextIds.clear();
1960
+ this.subscribedGroupIds.clear();
1879
1961
  }
1880
1962
  };
1881
1963
  _WsClient.MAX_BACKOFF_MS = 3e4;