@cimplify/sdk 0.3.3 → 0.3.4

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.mts CHANGED
@@ -2849,6 +2849,8 @@ declare class CimplifyClient {
2849
2849
  private timeout;
2850
2850
  private maxRetries;
2851
2851
  private retryDelay;
2852
+ /** In-flight request deduplication map */
2853
+ private inflightRequests;
2852
2854
  private _catalogue?;
2853
2855
  private _cart?;
2854
2856
  private _checkout?;
@@ -2872,7 +2874,25 @@ declare class CimplifyClient {
2872
2874
  * Uses exponential backoff: 1s, 2s, 4s between retries.
2873
2875
  */
2874
2876
  private resilientFetch;
2877
+ /**
2878
+ * Generate a deduplication key for a request.
2879
+ * Same query + variables = same key = deduplicated.
2880
+ */
2881
+ private getDedupeKey;
2882
+ /**
2883
+ * Execute a request with deduplication.
2884
+ * If an identical request is already in-flight, return the same promise.
2885
+ * This prevents redundant network calls when multiple components request the same data.
2886
+ */
2887
+ private deduplicatedRequest;
2888
+ /**
2889
+ * Execute a query with deduplication.
2890
+ * Multiple identical queries made simultaneously will share a single network request.
2891
+ */
2875
2892
  query<T = unknown>(query: string, variables?: Record<string, unknown>): Promise<T>;
2893
+ /**
2894
+ * Execute a mutation. NOT deduplicated - mutations have side effects.
2895
+ */
2876
2896
  call<T = unknown>(method: string, args?: unknown): Promise<T>;
2877
2897
  get<T = unknown>(path: string): Promise<T>;
2878
2898
  post<T = unknown>(path: string, body?: unknown): Promise<T>;
package/dist/index.d.ts CHANGED
@@ -2849,6 +2849,8 @@ declare class CimplifyClient {
2849
2849
  private timeout;
2850
2850
  private maxRetries;
2851
2851
  private retryDelay;
2852
+ /** In-flight request deduplication map */
2853
+ private inflightRequests;
2852
2854
  private _catalogue?;
2853
2855
  private _cart?;
2854
2856
  private _checkout?;
@@ -2872,7 +2874,25 @@ declare class CimplifyClient {
2872
2874
  * Uses exponential backoff: 1s, 2s, 4s between retries.
2873
2875
  */
2874
2876
  private resilientFetch;
2877
+ /**
2878
+ * Generate a deduplication key for a request.
2879
+ * Same query + variables = same key = deduplicated.
2880
+ */
2881
+ private getDedupeKey;
2882
+ /**
2883
+ * Execute a request with deduplication.
2884
+ * If an identical request is already in-flight, return the same promise.
2885
+ * This prevents redundant network calls when multiple components request the same data.
2886
+ */
2887
+ private deduplicatedRequest;
2888
+ /**
2889
+ * Execute a query with deduplication.
2890
+ * Multiple identical queries made simultaneously will share a single network request.
2891
+ */
2875
2892
  query<T = unknown>(query: string, variables?: Record<string, unknown>): Promise<T>;
2893
+ /**
2894
+ * Execute a mutation. NOT deduplicated - mutations have side effects.
2895
+ */
2876
2896
  call<T = unknown>(method: string, args?: unknown): Promise<T>;
2877
2897
  get<T = unknown>(path: string): Promise<T>;
2878
2898
  post<T = unknown>(path: string, body?: unknown): Promise<T>;
package/dist/index.js CHANGED
@@ -1469,6 +1469,8 @@ function deriveUrls() {
1469
1469
  var CimplifyClient = class {
1470
1470
  constructor(config = {}) {
1471
1471
  this.sessionToken = null;
1472
+ /** In-flight request deduplication map */
1473
+ this.inflightRequests = /* @__PURE__ */ new Map();
1472
1474
  this.publicKey = config.publicKey || "";
1473
1475
  const urls = deriveUrls();
1474
1476
  this.baseUrl = urls.baseUrl;
@@ -1557,20 +1559,53 @@ var CimplifyClient = class {
1557
1559
  }
1558
1560
  throw toNetworkError(lastError);
1559
1561
  }
1562
+ /**
1563
+ * Generate a deduplication key for a request.
1564
+ * Same query + variables = same key = deduplicated.
1565
+ */
1566
+ getDedupeKey(type, payload) {
1567
+ return `${type}:${JSON.stringify(payload)}`;
1568
+ }
1569
+ /**
1570
+ * Execute a request with deduplication.
1571
+ * If an identical request is already in-flight, return the same promise.
1572
+ * This prevents redundant network calls when multiple components request the same data.
1573
+ */
1574
+ async deduplicatedRequest(key, requestFn) {
1575
+ const existing = this.inflightRequests.get(key);
1576
+ if (existing) {
1577
+ return existing;
1578
+ }
1579
+ const request = requestFn().finally(() => {
1580
+ this.inflightRequests.delete(key);
1581
+ });
1582
+ this.inflightRequests.set(key, request);
1583
+ return request;
1584
+ }
1585
+ /**
1586
+ * Execute a query with deduplication.
1587
+ * Multiple identical queries made simultaneously will share a single network request.
1588
+ */
1560
1589
  async query(query2, variables) {
1561
1590
  const body = { query: query2 };
1562
1591
  if (variables) {
1563
1592
  body.variables = variables;
1564
1593
  }
1565
- const response = await this.resilientFetch(`${this.baseUrl}/api/q`, {
1566
- method: "POST",
1567
- credentials: this.credentials,
1568
- headers: this.getHeaders(),
1569
- body: JSON.stringify(body)
1594
+ const key = this.getDedupeKey("query", body);
1595
+ return this.deduplicatedRequest(key, async () => {
1596
+ const response = await this.resilientFetch(`${this.baseUrl}/api/q`, {
1597
+ method: "POST",
1598
+ credentials: this.credentials,
1599
+ headers: this.getHeaders(),
1600
+ body: JSON.stringify(body)
1601
+ });
1602
+ this.updateSessionFromResponse(response);
1603
+ return this.handleResponse(response);
1570
1604
  });
1571
- this.updateSessionFromResponse(response);
1572
- return this.handleResponse(response);
1573
1605
  }
1606
+ /**
1607
+ * Execute a mutation. NOT deduplicated - mutations have side effects.
1608
+ */
1574
1609
  async call(method, args) {
1575
1610
  const body = {
1576
1611
  method,
@@ -1586,13 +1621,16 @@ var CimplifyClient = class {
1586
1621
  return this.handleResponse(response);
1587
1622
  }
1588
1623
  async get(path) {
1589
- const response = await this.resilientFetch(`${this.baseUrl}${path}`, {
1590
- method: "GET",
1591
- credentials: this.credentials,
1592
- headers: this.getHeaders()
1624
+ const key = this.getDedupeKey("get", path);
1625
+ return this.deduplicatedRequest(key, async () => {
1626
+ const response = await this.resilientFetch(`${this.baseUrl}${path}`, {
1627
+ method: "GET",
1628
+ credentials: this.credentials,
1629
+ headers: this.getHeaders()
1630
+ });
1631
+ this.updateSessionFromResponse(response);
1632
+ return this.handleRestResponse(response);
1593
1633
  });
1594
- this.updateSessionFromResponse(response);
1595
- return this.handleRestResponse(response);
1596
1634
  }
1597
1635
  async post(path, body) {
1598
1636
  const response = await this.resilientFetch(`${this.baseUrl}${path}`, {
@@ -1614,13 +1652,16 @@ var CimplifyClient = class {
1614
1652
  return this.handleRestResponse(response);
1615
1653
  }
1616
1654
  async linkGet(path) {
1617
- const response = await this.resilientFetch(`${this.linkApiUrl}${path}`, {
1618
- method: "GET",
1619
- credentials: this.credentials,
1620
- headers: this.getHeaders()
1655
+ const key = this.getDedupeKey("linkGet", path);
1656
+ return this.deduplicatedRequest(key, async () => {
1657
+ const response = await this.resilientFetch(`${this.linkApiUrl}${path}`, {
1658
+ method: "GET",
1659
+ credentials: this.credentials,
1660
+ headers: this.getHeaders()
1661
+ });
1662
+ this.updateSessionFromResponse(response);
1663
+ return this.handleRestResponse(response);
1621
1664
  });
1622
- this.updateSessionFromResponse(response);
1623
- return this.handleRestResponse(response);
1624
1665
  }
1625
1666
  async linkPost(path, body) {
1626
1667
  const response = await this.resilientFetch(`${this.linkApiUrl}${path}`, {
package/dist/index.mjs CHANGED
@@ -1467,6 +1467,8 @@ function deriveUrls() {
1467
1467
  var CimplifyClient = class {
1468
1468
  constructor(config = {}) {
1469
1469
  this.sessionToken = null;
1470
+ /** In-flight request deduplication map */
1471
+ this.inflightRequests = /* @__PURE__ */ new Map();
1470
1472
  this.publicKey = config.publicKey || "";
1471
1473
  const urls = deriveUrls();
1472
1474
  this.baseUrl = urls.baseUrl;
@@ -1555,20 +1557,53 @@ var CimplifyClient = class {
1555
1557
  }
1556
1558
  throw toNetworkError(lastError);
1557
1559
  }
1560
+ /**
1561
+ * Generate a deduplication key for a request.
1562
+ * Same query + variables = same key = deduplicated.
1563
+ */
1564
+ getDedupeKey(type, payload) {
1565
+ return `${type}:${JSON.stringify(payload)}`;
1566
+ }
1567
+ /**
1568
+ * Execute a request with deduplication.
1569
+ * If an identical request is already in-flight, return the same promise.
1570
+ * This prevents redundant network calls when multiple components request the same data.
1571
+ */
1572
+ async deduplicatedRequest(key, requestFn) {
1573
+ const existing = this.inflightRequests.get(key);
1574
+ if (existing) {
1575
+ return existing;
1576
+ }
1577
+ const request = requestFn().finally(() => {
1578
+ this.inflightRequests.delete(key);
1579
+ });
1580
+ this.inflightRequests.set(key, request);
1581
+ return request;
1582
+ }
1583
+ /**
1584
+ * Execute a query with deduplication.
1585
+ * Multiple identical queries made simultaneously will share a single network request.
1586
+ */
1558
1587
  async query(query2, variables) {
1559
1588
  const body = { query: query2 };
1560
1589
  if (variables) {
1561
1590
  body.variables = variables;
1562
1591
  }
1563
- const response = await this.resilientFetch(`${this.baseUrl}/api/q`, {
1564
- method: "POST",
1565
- credentials: this.credentials,
1566
- headers: this.getHeaders(),
1567
- body: JSON.stringify(body)
1592
+ const key = this.getDedupeKey("query", body);
1593
+ return this.deduplicatedRequest(key, async () => {
1594
+ const response = await this.resilientFetch(`${this.baseUrl}/api/q`, {
1595
+ method: "POST",
1596
+ credentials: this.credentials,
1597
+ headers: this.getHeaders(),
1598
+ body: JSON.stringify(body)
1599
+ });
1600
+ this.updateSessionFromResponse(response);
1601
+ return this.handleResponse(response);
1568
1602
  });
1569
- this.updateSessionFromResponse(response);
1570
- return this.handleResponse(response);
1571
1603
  }
1604
+ /**
1605
+ * Execute a mutation. NOT deduplicated - mutations have side effects.
1606
+ */
1572
1607
  async call(method, args) {
1573
1608
  const body = {
1574
1609
  method,
@@ -1584,13 +1619,16 @@ var CimplifyClient = class {
1584
1619
  return this.handleResponse(response);
1585
1620
  }
1586
1621
  async get(path) {
1587
- const response = await this.resilientFetch(`${this.baseUrl}${path}`, {
1588
- method: "GET",
1589
- credentials: this.credentials,
1590
- headers: this.getHeaders()
1622
+ const key = this.getDedupeKey("get", path);
1623
+ return this.deduplicatedRequest(key, async () => {
1624
+ const response = await this.resilientFetch(`${this.baseUrl}${path}`, {
1625
+ method: "GET",
1626
+ credentials: this.credentials,
1627
+ headers: this.getHeaders()
1628
+ });
1629
+ this.updateSessionFromResponse(response);
1630
+ return this.handleRestResponse(response);
1591
1631
  });
1592
- this.updateSessionFromResponse(response);
1593
- return this.handleRestResponse(response);
1594
1632
  }
1595
1633
  async post(path, body) {
1596
1634
  const response = await this.resilientFetch(`${this.baseUrl}${path}`, {
@@ -1612,13 +1650,16 @@ var CimplifyClient = class {
1612
1650
  return this.handleRestResponse(response);
1613
1651
  }
1614
1652
  async linkGet(path) {
1615
- const response = await this.resilientFetch(`${this.linkApiUrl}${path}`, {
1616
- method: "GET",
1617
- credentials: this.credentials,
1618
- headers: this.getHeaders()
1653
+ const key = this.getDedupeKey("linkGet", path);
1654
+ return this.deduplicatedRequest(key, async () => {
1655
+ const response = await this.resilientFetch(`${this.linkApiUrl}${path}`, {
1656
+ method: "GET",
1657
+ credentials: this.credentials,
1658
+ headers: this.getHeaders()
1659
+ });
1660
+ this.updateSessionFromResponse(response);
1661
+ return this.handleRestResponse(response);
1619
1662
  });
1620
- this.updateSessionFromResponse(response);
1621
- return this.handleRestResponse(response);
1622
1663
  }
1623
1664
  async linkPost(path, body) {
1624
1665
  const response = await this.resilientFetch(`${this.linkApiUrl}${path}`, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cimplify/sdk",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "description": "Cimplify Commerce SDK for storefronts",
5
5
  "keywords": [
6
6
  "cimplify",