@anuma/sdk 9.1.0 → 9.1.2

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
@@ -1826,11 +1826,12 @@ function parseRetryAfterMs(header) {
1826
1826
 
1827
1827
  // src/lib/memory/store/remotePersistence.ts
1828
1828
  var RemoteMemoryError = class extends Error {
1829
- constructor(message, status, code, retryAfterMs) {
1829
+ constructor(message, status, code, retryAfterMs, rateLimitBucket) {
1830
1830
  super(message);
1831
1831
  this.status = status;
1832
1832
  this.code = code;
1833
1833
  this.retryAfterMs = retryAfterMs;
1834
+ this.rateLimitBucket = rateLimitBucket;
1834
1835
  this.name = "RemoteMemoryError";
1835
1836
  }
1836
1837
  };
@@ -1849,6 +1850,14 @@ function createNearbyRequest(options, apiPath = "/api/private-memories") {
1849
1850
  throw new Error("timeoutMs must be a positive number");
1850
1851
  const root = base.href.replace(/\/$/, "") + apiPath;
1851
1852
  const fetcher = options.fetch ?? globalThis.fetch;
1853
+ const cooldowns = /* @__PURE__ */ new Map();
1854
+ const memoryBudget = (path, method) => {
1855
+ if (method === "PUT")
1856
+ return path === "/topics" ? "private-memory-import" : "private-memory-write";
1857
+ if (method === "POST" && ["/import", "/memories/batch", "/topics/import"].includes(path))
1858
+ return "private-memory-import";
1859
+ return "private-memory-read";
1860
+ };
1852
1861
  const request = async (path, init = {}, signal) => {
1853
1862
  const controller = new AbortController();
1854
1863
  let timedOut = false;
@@ -1872,6 +1881,25 @@ function createNearbyRequest(options, apiPath = "/api/private-memories") {
1872
1881
  const token = await Promise.race([options.getToken(), aborted]);
1873
1882
  if (controller.signal.aborted) await aborted;
1874
1883
  if (!token) throw new RemoteMemoryError("Authentication required", 401);
1884
+ const pathname = path.split("?")[0];
1885
+ const route = `${init.method ?? "GET"} ${pathname}`;
1886
+ const budgets = ["*", route];
1887
+ if (apiPath === "/api/private-memories")
1888
+ budgets.push("private-memory-ip", memoryBudget(pathname, init.method ?? "GET"));
1889
+ for (const bucket of budgets) {
1890
+ const cooldown = cooldowns.get(bucket);
1891
+ if (!cooldown) continue;
1892
+ const remaining = cooldown.until - Date.now();
1893
+ if (remaining > 0)
1894
+ throw new RemoteMemoryError(
1895
+ cooldown.error.message,
1896
+ 429,
1897
+ cooldown.error.code,
1898
+ remaining,
1899
+ cooldown.error.rateLimitBucket
1900
+ );
1901
+ cooldowns.delete(bucket);
1902
+ }
1875
1903
  const response = await fetcher(root + path, {
1876
1904
  ...init,
1877
1905
  headers: {
@@ -1884,12 +1912,18 @@ function createNearbyRequest(options, apiPath = "/api/private-memories") {
1884
1912
  if (!response.ok) {
1885
1913
  const body = await response.json().catch(() => null);
1886
1914
  const retryAfter = parseRetryAfterMs(response.headers.get("Retry-After"));
1887
- throw new RemoteMemoryError(
1915
+ const error = new RemoteMemoryError(
1888
1916
  record(body) && typeof body.detail === "string" ? body.detail : `Nearby request failed (${response.status})`,
1889
1917
  response.status,
1890
1918
  record(body) && typeof body.code === "string" ? body.code : void 0,
1891
- retryAfter ?? void 0
1919
+ retryAfter ?? void 0,
1920
+ record(body) && typeof body.rate_limit_bucket === "string" ? body.rate_limit_bucket : void 0
1892
1921
  );
1922
+ if (response.status === 429 && retryAfter !== null && retryAfter > 0 && (!error.code || error.code === "rate_limited")) {
1923
+ const bucket = error.rateLimitBucket && budgets.includes(error.rateLimitBucket) ? error.rateLimitBucket : record(body) && (body.limit_scope === "account" || body.limit_scope === "ip") && !error.rateLimitBucket ? "*" : route;
1924
+ cooldowns.set(bucket, { until: Date.now() + retryAfter, error });
1925
+ }
1926
+ throw error;
1893
1927
  }
1894
1928
  return await response.json();
1895
1929
  } catch (error) {
package/dist/index.mjs CHANGED
@@ -1623,11 +1623,12 @@ function parseRetryAfterMs(header) {
1623
1623
 
1624
1624
  // src/lib/memory/store/remotePersistence.ts
1625
1625
  var RemoteMemoryError = class extends Error {
1626
- constructor(message, status, code, retryAfterMs) {
1626
+ constructor(message, status, code, retryAfterMs, rateLimitBucket) {
1627
1627
  super(message);
1628
1628
  this.status = status;
1629
1629
  this.code = code;
1630
1630
  this.retryAfterMs = retryAfterMs;
1631
+ this.rateLimitBucket = rateLimitBucket;
1631
1632
  this.name = "RemoteMemoryError";
1632
1633
  }
1633
1634
  };
@@ -1646,6 +1647,14 @@ function createNearbyRequest(options, apiPath = "/api/private-memories") {
1646
1647
  throw new Error("timeoutMs must be a positive number");
1647
1648
  const root = base.href.replace(/\/$/, "") + apiPath;
1648
1649
  const fetcher = options.fetch ?? globalThis.fetch;
1650
+ const cooldowns = /* @__PURE__ */ new Map();
1651
+ const memoryBudget = (path, method) => {
1652
+ if (method === "PUT")
1653
+ return path === "/topics" ? "private-memory-import" : "private-memory-write";
1654
+ if (method === "POST" && ["/import", "/memories/batch", "/topics/import"].includes(path))
1655
+ return "private-memory-import";
1656
+ return "private-memory-read";
1657
+ };
1649
1658
  const request = async (path, init = {}, signal) => {
1650
1659
  const controller = new AbortController();
1651
1660
  let timedOut = false;
@@ -1669,6 +1678,25 @@ function createNearbyRequest(options, apiPath = "/api/private-memories") {
1669
1678
  const token = await Promise.race([options.getToken(), aborted]);
1670
1679
  if (controller.signal.aborted) await aborted;
1671
1680
  if (!token) throw new RemoteMemoryError("Authentication required", 401);
1681
+ const pathname = path.split("?")[0];
1682
+ const route = `${init.method ?? "GET"} ${pathname}`;
1683
+ const budgets = ["*", route];
1684
+ if (apiPath === "/api/private-memories")
1685
+ budgets.push("private-memory-ip", memoryBudget(pathname, init.method ?? "GET"));
1686
+ for (const bucket of budgets) {
1687
+ const cooldown = cooldowns.get(bucket);
1688
+ if (!cooldown) continue;
1689
+ const remaining = cooldown.until - Date.now();
1690
+ if (remaining > 0)
1691
+ throw new RemoteMemoryError(
1692
+ cooldown.error.message,
1693
+ 429,
1694
+ cooldown.error.code,
1695
+ remaining,
1696
+ cooldown.error.rateLimitBucket
1697
+ );
1698
+ cooldowns.delete(bucket);
1699
+ }
1672
1700
  const response = await fetcher(root + path, {
1673
1701
  ...init,
1674
1702
  headers: {
@@ -1681,12 +1709,18 @@ function createNearbyRequest(options, apiPath = "/api/private-memories") {
1681
1709
  if (!response.ok) {
1682
1710
  const body = await response.json().catch(() => null);
1683
1711
  const retryAfter = parseRetryAfterMs(response.headers.get("Retry-After"));
1684
- throw new RemoteMemoryError(
1712
+ const error = new RemoteMemoryError(
1685
1713
  record(body) && typeof body.detail === "string" ? body.detail : `Nearby request failed (${response.status})`,
1686
1714
  response.status,
1687
1715
  record(body) && typeof body.code === "string" ? body.code : void 0,
1688
- retryAfter ?? void 0
1716
+ retryAfter ?? void 0,
1717
+ record(body) && typeof body.rate_limit_bucket === "string" ? body.rate_limit_bucket : void 0
1689
1718
  );
1719
+ if (response.status === 429 && retryAfter !== null && retryAfter > 0 && (!error.code || error.code === "rate_limited")) {
1720
+ const bucket = error.rateLimitBucket && budgets.includes(error.rateLimitBucket) ? error.rateLimitBucket : record(body) && (body.limit_scope === "account" || body.limit_scope === "ip") && !error.rateLimitBucket ? "*" : route;
1721
+ cooldowns.set(bucket, { until: Date.now() + retryAfter, error });
1722
+ }
1723
+ throw error;
1690
1724
  }
1691
1725
  return await response.json();
1692
1726
  } catch (error) {