@cimplify/sdk 0.100.6 → 0.101.1

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 (68) hide show
  1. package/dist/advanced.d.mts +3 -3
  2. package/dist/advanced.d.ts +3 -3
  3. package/dist/advanced.js +20 -20
  4. package/dist/advanced.mjs +1 -1
  5. package/dist/{chunk-KLJLKT6C.mjs → chunk-7H6IL7CX.mjs} +2 -2
  6. package/dist/{chunk-BMFWQNYZ.mjs → chunk-DKLHCZ5M.mjs} +4 -1
  7. package/dist/{chunk-PNTINRAU.js → chunk-H5SSGN7W.js} +28 -0
  8. package/dist/{chunk-BSZJSR62.js → chunk-ICCCSVN3.js} +4 -4
  9. package/dist/{chunk-D3FWJB7Y.js → chunk-YDA46OZ6.js} +50 -47
  10. package/dist/{chunk-3HU5I5VG.js → chunk-YER7DIOM.js} +15 -0
  11. package/dist/{chunk-RQPXLXB2.mjs → chunk-YHPMFTMN.mjs} +28 -0
  12. package/dist/{chunk-Z7M6GAHS.mjs → chunk-Z3K2D3TE.mjs} +15 -0
  13. package/dist/{client-CrPglBBz.d.ts → client-CdTx7X_X.d.mts} +12 -2
  14. package/dist/{client-CPcZIrjC.d.ts → client-D40kI8z2.d.ts} +2 -2
  15. package/dist/{client-BwRAAk4y.d.mts → client-Db554902.d.ts} +12 -2
  16. package/dist/{client-DGrvLiJv.d.mts → client-WkUcvRvO.d.mts} +2 -2
  17. package/dist/{index-D-LUYk1Y.d.mts → index-BjWUkYgY.d.mts} +3 -3
  18. package/dist/{index-B_RYmvlF.d.ts → index-D3UXgAYl.d.ts} +3 -3
  19. package/dist/index.d.mts +7 -7
  20. package/dist/index.d.ts +7 -7
  21. package/dist/index.js +69 -69
  22. package/dist/index.mjs +3 -3
  23. package/dist/mock/cli.mjs +28 -0
  24. package/dist/mock/library.js +28 -0
  25. package/dist/mock/library.mjs +28 -0
  26. package/dist/mock/msw.js +28 -0
  27. package/dist/mock/msw.mjs +28 -0
  28. package/dist/{payment-BSzy7sly.d.mts → payment-CRqjGrx6.d.mts} +1 -1
  29. package/dist/{payment-jK8ztICx.d.ts → payment-DO1Z1Ip6.d.ts} +1 -1
  30. package/dist/{price-D96h6c6L.d.mts → price-CiQUd_XX.d.mts} +1 -1
  31. package/dist/{price-CJLfcYKd.d.ts → price-D9EOj8y8.d.ts} +1 -1
  32. package/dist/{product-CeV8euw4.d.mts → product-DwKdC_to.d.mts} +727 -625
  33. package/dist/{product-CeV8euw4.d.ts → product-DwKdC_to.d.ts} +727 -625
  34. package/dist/react.d.mts +7 -4
  35. package/dist/react.d.ts +7 -4
  36. package/dist/react.js +75 -34
  37. package/dist/react.mjs +52 -11
  38. package/dist/server/evict.d.mts +12 -8
  39. package/dist/server/evict.d.ts +12 -8
  40. package/dist/server/evict.js +53 -7
  41. package/dist/server/evict.mjs +53 -7
  42. package/dist/server/tanstack.d.mts +4 -2
  43. package/dist/server/tanstack.d.ts +4 -2
  44. package/dist/server/tanstack.js +53 -14
  45. package/dist/server/tanstack.mjs +53 -14
  46. package/dist/{server-zyrpzJVn.d.ts → server-CeDb93WA.d.ts} +13 -1
  47. package/dist/{server-DRAW2OOX.d.mts → server-D-nSkrUr.d.mts} +13 -1
  48. package/dist/server.d.mts +4 -4
  49. package/dist/server.d.ts +4 -4
  50. package/dist/server.js +7 -7
  51. package/dist/server.mjs +2 -2
  52. package/dist/testing/msw.d.mts +2 -2
  53. package/dist/testing/msw.d.ts +2 -2
  54. package/dist/testing/msw.js +2 -2
  55. package/dist/testing/msw.mjs +1 -1
  56. package/dist/testing/suite.d.mts +6 -6
  57. package/dist/testing/suite.d.ts +6 -6
  58. package/dist/testing/suite.js +23 -23
  59. package/dist/testing/suite.mjs +4 -4
  60. package/dist/testing.d.mts +5 -5
  61. package/dist/testing.d.ts +5 -5
  62. package/dist/testing.js +79 -79
  63. package/dist/testing.mjs +5 -5
  64. package/dist/utils.d.mts +4 -4
  65. package/dist/utils.d.ts +4 -4
  66. package/package.json +1 -1
  67. package/registry/cart-summary.json +1 -1
  68. package/registry/chat-widget.json +1 -1
package/dist/react.d.mts CHANGED
@@ -2,13 +2,13 @@ import * as React$1 from 'react';
2
2
  import React__default, { ReactNode, PointerEvent, MouseEvent } from 'react';
3
3
  import { d as AdSlot, c as AdPosition, a as AdContextValue, S as SignInOptions } from './sign-in-DQlIdqsi.mjs';
4
4
  export { A as AdConfig, g as getVariantDisplayName } from './sign-in-DQlIdqsi.mjs';
5
- import { af as CimplifyClient, cb as OrderType, cw as ProcessCheckoutResult, ac as CheckoutStatus, ad as CheckoutStatusContext, a$ as EnrichedOrderItem, a_ as EnrichedOrder, w as Business, bA as Location, cN as ReorderResult, c9 as OrderStatus, bQ as Order, cy as QuoteBundleSelectionInput, cz as QuoteCompositeSelectionInput, cs as PriceQuote, cC as QuoteUiMessage, d7 as Service, r as AvailableSlot, ay as DayAvailability, aq as CustomerBooking, L as CancelBookingResult, f as ActivityStateResponse, dg as SessionMessage, c as ActivityRecommendation, aA as DeliveryFeeResponse, aD as DeliveryOptionsResponse, bd as FxRateResponse, dq as StoreCreditBalance, ds as StorefrontBootstrap, _ as ChatWidgetStarter, W as ChatMessage, Z as ChatUploadAttachment, h as AddressInfo, n as AuthenticatedData, aZ as ElementsOptions, cm as PaymentMethodInfo, aX as ElementsCheckoutResult, cv as ProcessCheckoutOptions, ai as CimplifyElements, T as ChatAttachment, bp as LineItem, dj as Staff, d2 as Room, Y as ChatReplyContext } from './client-BwRAAk4y.mjs';
5
+ import { af as CimplifyClient, cb as OrderType, cw as ProcessCheckoutResult, ac as CheckoutStatus, ad as CheckoutStatusContext, a$ as EnrichedOrderItem, a_ as EnrichedOrder, w as Business, bA as Location, cN as ReorderResult, c9 as OrderStatus, bQ as Order, cy as QuoteBundleSelectionInput, cz as QuoteCompositeSelectionInput, cs as PriceQuote, cC as QuoteUiMessage, d7 as Service, r as AvailableSlot, ay as DayAvailability, aq as CustomerBooking, L as CancelBookingResult, f as ActivityStateResponse, dg as SessionMessage, c as ActivityRecommendation, aA as DeliveryFeeResponse, aD as DeliveryOptionsResponse, bd as FxRateResponse, dq as StoreCreditBalance, ds as StorefrontBootstrap, _ as ChatWidgetStarter, W as ChatMessage, Z as ChatUploadAttachment, h as AddressInfo, n as AuthenticatedData, aZ as ElementsOptions, cm as PaymentMethodInfo, aX as ElementsCheckoutResult, cv as ProcessCheckoutOptions, ai as CimplifyElements, T as ChatAttachment, bp as LineItem, dj as Staff, d2 as Room, Y as ChatReplyContext } from './client-CdTx7X_X.mjs';
6
6
  import * as react_jsx_runtime from 'react/jsx-runtime';
7
- import { ad as CurrencyCode, aZ as Product, aQ as Pagination, V as CimplifyError, bb as ProductWithDetails, S as Category, aO as Money, U as ChosenPrice, E as BundleSelectionInput, a1 as ComponentSelectionInput, D as BundleSelectionData, aa as CompositeSelectionData, W as Collection, b6 as ProductTaxonomy, bx as TaxonomyWithChildren, b7 as ProductTimeProfile, aj as Deal, b2 as ProductDealInfo, ap as DiscountValidation, G as BundleSummary, a8 as CompositePriceResult, bs as SubscriptionWithDetails, br as SubscriptionStatus, bo as Subscription, ae as CustomAttributeDefinition, bc as PropertyFacet, b1 as ProductBillingPlan, bQ as VariantView, bK as VariantAxisWithValues, f as AddOnWithOptions, y as BundleComponentView, z as BundlePriceType, a6 as CompositeGroupView, as as DisplayCart, b3 as ProductInputField, h as AddressValue, bi as SaleInfo, bD as UpcomingSale, av as DurationUnit, t as BoundaryKind, bk as SchedulingMode, al as DepositType, af as CustomAttributeValue, b4 as ProductProperty, be as QuantityPricingTier } from './product-CeV8euw4.mjs';
8
- import { P as ProductWithPrice } from './price-D96h6c6L.mjs';
7
+ import { ad as CurrencyCode, b0 as Product, aT as Pagination, V as CimplifyError, be as ProductWithDetails, S as Category, aR as Money, U as ChosenPrice, E as BundleSelectionInput, a1 as ComponentSelectionInput, D as BundleSelectionData, aa as CompositeSelectionData, W as Collection, b9 as ProductTaxonomy, bA as TaxonomyWithChildren, ba as ProductTimeProfile, aj as Deal, b5 as ProductDealInfo, as as DiscountValidation, G as BundleSummary, a8 as CompositePriceResult, bv as SubscriptionWithDetails, bu as SubscriptionStatus, br as Subscription, ae as CustomAttributeDefinition, bf as PropertyFacet, b4 as ProductBillingPlan, bT as VariantView, bN as VariantAxisWithValues, f as AddOnWithOptions, y as BundleComponentView, z as BundlePriceType, a6 as CompositeGroupView, av as DisplayCart, b6 as ProductInputField, h as AddressValue, bl as SaleInfo, bG as UpcomingSale, ay as DurationUnit, t as BoundaryKind, bn as SchedulingMode, al as DepositType, af as CustomAttributeValue, b7 as ProductProperty, bh as QuantityPricingTier } from './product-DwKdC_to.mjs';
8
+ import { P as ProductWithPrice } from './price-CiQUd_XX.mjs';
9
9
  import { ClassValue } from 'clsx';
10
10
  import { Matcher } from 'react-day-picker';
11
- import './payment-BSzy7sly.mjs';
11
+ import './payment-CRqjGrx6.mjs';
12
12
 
13
13
  interface UserIdentity {
14
14
  uid: string;
@@ -1005,6 +1005,9 @@ interface UseCartResult {
1005
1005
  itemCount: number;
1006
1006
  subtotal: number;
1007
1007
  tax: number;
1008
+ taxRate: number | null;
1009
+ taxInclusive: boolean;
1010
+ taxJurisdictionLabel: string | null;
1008
1011
  total: number;
1009
1012
  currency: string;
1010
1013
  isEmpty: boolean;
package/dist/react.d.ts CHANGED
@@ -2,13 +2,13 @@ import * as React$1 from 'react';
2
2
  import React__default, { ReactNode, PointerEvent, MouseEvent } from 'react';
3
3
  import { d as AdSlot, c as AdPosition, a as AdContextValue, S as SignInOptions } from './sign-in-DQlIdqsi.js';
4
4
  export { A as AdConfig, g as getVariantDisplayName } from './sign-in-DQlIdqsi.js';
5
- import { af as CimplifyClient, cb as OrderType, cw as ProcessCheckoutResult, ac as CheckoutStatus, ad as CheckoutStatusContext, a$ as EnrichedOrderItem, a_ as EnrichedOrder, w as Business, bA as Location, cN as ReorderResult, c9 as OrderStatus, bQ as Order, cy as QuoteBundleSelectionInput, cz as QuoteCompositeSelectionInput, cs as PriceQuote, cC as QuoteUiMessage, d7 as Service, r as AvailableSlot, ay as DayAvailability, aq as CustomerBooking, L as CancelBookingResult, f as ActivityStateResponse, dg as SessionMessage, c as ActivityRecommendation, aA as DeliveryFeeResponse, aD as DeliveryOptionsResponse, bd as FxRateResponse, dq as StoreCreditBalance, ds as StorefrontBootstrap, _ as ChatWidgetStarter, W as ChatMessage, Z as ChatUploadAttachment, h as AddressInfo, n as AuthenticatedData, aZ as ElementsOptions, cm as PaymentMethodInfo, aX as ElementsCheckoutResult, cv as ProcessCheckoutOptions, ai as CimplifyElements, T as ChatAttachment, bp as LineItem, dj as Staff, d2 as Room, Y as ChatReplyContext } from './client-CrPglBBz.js';
5
+ import { af as CimplifyClient, cb as OrderType, cw as ProcessCheckoutResult, ac as CheckoutStatus, ad as CheckoutStatusContext, a$ as EnrichedOrderItem, a_ as EnrichedOrder, w as Business, bA as Location, cN as ReorderResult, c9 as OrderStatus, bQ as Order, cy as QuoteBundleSelectionInput, cz as QuoteCompositeSelectionInput, cs as PriceQuote, cC as QuoteUiMessage, d7 as Service, r as AvailableSlot, ay as DayAvailability, aq as CustomerBooking, L as CancelBookingResult, f as ActivityStateResponse, dg as SessionMessage, c as ActivityRecommendation, aA as DeliveryFeeResponse, aD as DeliveryOptionsResponse, bd as FxRateResponse, dq as StoreCreditBalance, ds as StorefrontBootstrap, _ as ChatWidgetStarter, W as ChatMessage, Z as ChatUploadAttachment, h as AddressInfo, n as AuthenticatedData, aZ as ElementsOptions, cm as PaymentMethodInfo, aX as ElementsCheckoutResult, cv as ProcessCheckoutOptions, ai as CimplifyElements, T as ChatAttachment, bp as LineItem, dj as Staff, d2 as Room, Y as ChatReplyContext } from './client-Db554902.js';
6
6
  import * as react_jsx_runtime from 'react/jsx-runtime';
7
- import { ad as CurrencyCode, aZ as Product, aQ as Pagination, V as CimplifyError, bb as ProductWithDetails, S as Category, aO as Money, U as ChosenPrice, E as BundleSelectionInput, a1 as ComponentSelectionInput, D as BundleSelectionData, aa as CompositeSelectionData, W as Collection, b6 as ProductTaxonomy, bx as TaxonomyWithChildren, b7 as ProductTimeProfile, aj as Deal, b2 as ProductDealInfo, ap as DiscountValidation, G as BundleSummary, a8 as CompositePriceResult, bs as SubscriptionWithDetails, br as SubscriptionStatus, bo as Subscription, ae as CustomAttributeDefinition, bc as PropertyFacet, b1 as ProductBillingPlan, bQ as VariantView, bK as VariantAxisWithValues, f as AddOnWithOptions, y as BundleComponentView, z as BundlePriceType, a6 as CompositeGroupView, as as DisplayCart, b3 as ProductInputField, h as AddressValue, bi as SaleInfo, bD as UpcomingSale, av as DurationUnit, t as BoundaryKind, bk as SchedulingMode, al as DepositType, af as CustomAttributeValue, b4 as ProductProperty, be as QuantityPricingTier } from './product-CeV8euw4.js';
8
- import { P as ProductWithPrice } from './price-CJLfcYKd.js';
7
+ import { ad as CurrencyCode, b0 as Product, aT as Pagination, V as CimplifyError, be as ProductWithDetails, S as Category, aR as Money, U as ChosenPrice, E as BundleSelectionInput, a1 as ComponentSelectionInput, D as BundleSelectionData, aa as CompositeSelectionData, W as Collection, b9 as ProductTaxonomy, bA as TaxonomyWithChildren, ba as ProductTimeProfile, aj as Deal, b5 as ProductDealInfo, as as DiscountValidation, G as BundleSummary, a8 as CompositePriceResult, bv as SubscriptionWithDetails, bu as SubscriptionStatus, br as Subscription, ae as CustomAttributeDefinition, bf as PropertyFacet, b4 as ProductBillingPlan, bT as VariantView, bN as VariantAxisWithValues, f as AddOnWithOptions, y as BundleComponentView, z as BundlePriceType, a6 as CompositeGroupView, av as DisplayCart, b6 as ProductInputField, h as AddressValue, bl as SaleInfo, bG as UpcomingSale, ay as DurationUnit, t as BoundaryKind, bn as SchedulingMode, al as DepositType, af as CustomAttributeValue, b7 as ProductProperty, bh as QuantityPricingTier } from './product-DwKdC_to.js';
8
+ import { P as ProductWithPrice } from './price-D9EOj8y8.js';
9
9
  import { ClassValue } from 'clsx';
10
10
  import { Matcher } from 'react-day-picker';
11
- import './payment-jK8ztICx.js';
11
+ import './payment-DO1Z1Ip6.js';
12
12
 
13
13
  interface UserIdentity {
14
14
  uid: string;
@@ -1005,6 +1005,9 @@ interface UseCartResult {
1005
1005
  itemCount: number;
1006
1006
  subtotal: number;
1007
1007
  tax: number;
1008
+ taxRate: number | null;
1009
+ taxInclusive: boolean;
1010
+ taxJurisdictionLabel: string | null;
1008
1011
  total: number;
1009
1012
  currency: string;
1010
1013
  isEmpty: boolean;
package/dist/react.js CHANGED
@@ -3,8 +3,8 @@
3
3
 
4
4
  var chunkXREIZ56K_js = require('./chunk-XREIZ56K.js');
5
5
  var chunkQPRI2NII_js = require('./chunk-QPRI2NII.js');
6
- var chunkD3FWJB7Y_js = require('./chunk-D3FWJB7Y.js');
7
- var chunk3HU5I5VG_js = require('./chunk-3HU5I5VG.js');
6
+ var chunkYDA46OZ6_js = require('./chunk-YDA46OZ6.js');
7
+ var chunkYER7DIOM_js = require('./chunk-YER7DIOM.js');
8
8
  var chunkWMEC5JWN_js = require('./chunk-WMEC5JWN.js');
9
9
  var chunkNIOUSKQQ_js = require('./chunk-NIOUSKQQ.js');
10
10
  require('./chunk-OWW5GUSB.js');
@@ -454,6 +454,7 @@ function transformToCheckoutCart(cart, fx, checkout) {
454
454
  total: amt(cart.pricing.total_price),
455
455
  currency: fx?.displayCurrency ?? cart.pricing.currency,
456
456
  tax_inclusive: cart.pricing.tax_inclusive ?? false,
457
+ tax_rate: cart.pricing.tax_rate,
457
458
  deposit_required: cart.pricing.deposit_required ?? false,
458
459
  deposit_amount: cart.pricing.deposit_amount != null ? amt(cart.pricing.deposit_amount) : void 0,
459
460
  requires_delivery: cart.requires_delivery
@@ -706,7 +707,17 @@ function clearAllCartStores() {
706
707
  cartStores.clear();
707
708
  }
708
709
  function emptyBase(currency, isLoading = true) {
709
- return { items: [], subtotal: 0, tax: 0, total: 0, currency, isLoading };
710
+ return {
711
+ items: [],
712
+ subtotal: 0,
713
+ tax: 0,
714
+ taxRate: null,
715
+ taxInclusive: false,
716
+ taxJurisdictionLabel: null,
717
+ total: 0,
718
+ currency,
719
+ isLoading
720
+ };
710
721
  }
711
722
  function buildStoreKey(client, locationId) {
712
723
  return [client.getPublicKey() || "__no_public_key__", locationId || "__no_location__"].join(":");
@@ -799,6 +810,9 @@ function mapServerCart(serverCart, fallbackCurrency) {
799
810
  items,
800
811
  subtotal: roundMoney(toNumber(serverCart.pricing.subtotal)),
801
812
  tax: roundMoney(toNumber(serverCart.pricing.tax_amount)),
813
+ taxRate: serverCart.pricing.tax_rate != null ? toNumber(serverCart.pricing.tax_rate) : null,
814
+ taxInclusive: serverCart.pricing.tax_inclusive,
815
+ taxJurisdictionLabel: serverCart.pricing.tax_jurisdiction_label ?? null,
802
816
  total: roundMoney(toNumber(serverCart.pricing.total_price)),
803
817
  currency: serverCart.pricing.currency || fallbackCurrency,
804
818
  isLoading: false
@@ -845,7 +859,7 @@ async function syncFromServer(entry) {
845
859
  return next;
846
860
  }
847
861
  function emitMutationError(entry, operation, opId, idempotencyKey, error) {
848
- entry.client.events.emit(chunkD3FWJB7Y_js.MUTATION_ERROR, {
862
+ entry.client.events.emit(chunkYDA46OZ6_js.MUTATION_ERROR, {
849
863
  service: "cart",
850
864
  operation,
851
865
  opId,
@@ -885,10 +899,10 @@ function getOrCreateStore(params) {
885
899
  syncTail: Promise.resolve(),
886
900
  failedOpRemovers: /* @__PURE__ */ new Set()
887
901
  };
888
- client.events.on(chunkD3FWJB7Y_js.SESSION_CLAIMED, () => {
902
+ client.events.on(chunkYDA46OZ6_js.SESSION_CLAIMED, () => {
889
903
  if (entry.initialized) void syncFromServer(entry);
890
904
  });
891
- client.events.on(chunkD3FWJB7Y_js.SESSION_CLEARED, () => {
905
+ client.events.on(chunkYDA46OZ6_js.SESSION_CLEARED, () => {
892
906
  if (entry.initialized) void syncFromServer(entry);
893
907
  });
894
908
  cartStores.set(storeKey, entry);
@@ -1130,6 +1144,9 @@ function useCart(options = {}) {
1130
1144
  itemCount,
1131
1145
  subtotal: view.subtotal,
1132
1146
  tax: view.tax,
1147
+ taxRate: view.taxRate,
1148
+ taxInclusive: view.taxInclusive,
1149
+ taxJurisdictionLabel: view.taxJurisdictionLabel,
1133
1150
  total: view.total,
1134
1151
  currency: view.currency,
1135
1152
  isEmpty: itemCount === 0,
@@ -1192,7 +1209,7 @@ var DEFAULT_COUNTRY = "US";
1192
1209
  function createDefaultClient() {
1193
1210
  const processRef = globalThis.process;
1194
1211
  const envPublicKey = processRef?.env?.NEXT_PUBLIC_CIMPLIFY_PUBLIC_KEY || "";
1195
- return chunkD3FWJB7Y_js.createCimplifyClient({ publicKey: envPublicKey });
1212
+ return chunkYDA46OZ6_js.createCimplifyClient({ publicKey: envPublicKey });
1196
1213
  }
1197
1214
  function getStoredLocationId() {
1198
1215
  if (typeof window === "undefined" || !window.localStorage) {
@@ -3504,7 +3521,7 @@ function CimplifySignInButton({
3504
3521
  const onClick = async () => {
3505
3522
  if (busy || disabled || !signInOpts.clientId) return;
3506
3523
  setBusy(true);
3507
- await chunk3HU5I5VG_js.startSignIn({
3524
+ await chunkYER7DIOM_js.startSignIn({
3508
3525
  ...signInOpts,
3509
3526
  onSuccess: () => {
3510
3527
  setBusy(false);
@@ -4972,9 +4989,9 @@ function useClientSessionEpoch(client) {
4972
4989
  const subscribe = React14.useCallback(
4973
4990
  (notify) => {
4974
4991
  const unsubscribe = [
4975
- client.events.on(chunkD3FWJB7Y_js.AUTH_TOKEN_CHANGED, notify),
4976
- client.events.on(chunkD3FWJB7Y_js.SESSION_CLAIMED, notify),
4977
- client.events.on(chunkD3FWJB7Y_js.SESSION_CLEARED, notify)
4992
+ client.events.on(chunkYDA46OZ6_js.AUTH_TOKEN_CHANGED, notify),
4993
+ client.events.on(chunkYDA46OZ6_js.SESSION_CLAIMED, notify),
4994
+ client.events.on(chunkYDA46OZ6_js.SESSION_CLEARED, notify)
4978
4995
  ];
4979
4996
  return () => {
4980
4997
  for (const stopListening of unsubscribe) {
@@ -6304,7 +6321,7 @@ function useChat(options = {}) {
6304
6321
  const watchSessionClaims = React14.useCallback(() => {
6305
6322
  const c = clientRef.current;
6306
6323
  if (!c || claimUnsubRef.current) return;
6307
- const unsubClaimed = c.events.on(chunkD3FWJB7Y_js.SESSION_CLAIMED, (event) => {
6324
+ const unsubClaimed = c.events.on(chunkYDA46OZ6_js.SESSION_CLAIMED, (event) => {
6308
6325
  setClaimedAs(event.customerName || c.support.claimedCustomerName || null);
6309
6326
  if (!openedRef.current) {
6310
6327
  void openIfExisting();
@@ -6313,7 +6330,7 @@ function useChat(options = {}) {
6313
6330
  connectWebSocket();
6314
6331
  void resyncConversation();
6315
6332
  });
6316
- const unsubCleared = c.events.on(chunkD3FWJB7Y_js.SESSION_CLEARED, resetConversation);
6333
+ const unsubCleared = c.events.on(chunkYDA46OZ6_js.SESSION_CLEARED, resetConversation);
6317
6334
  claimUnsubRef.current = () => {
6318
6335
  unsubClaimed();
6319
6336
  unsubCleared();
@@ -6365,7 +6382,7 @@ function useChat(options = {}) {
6365
6382
  if (!openedRef.current) return false;
6366
6383
  }
6367
6384
  const replyTo = opts?.replyTo;
6368
- const clientId = chunk3HU5I5VG_js.generateIdempotencyKey();
6385
+ const clientId = chunkYER7DIOM_js.generateIdempotencyKey();
6369
6386
  const localId = optimisticId(clientId);
6370
6387
  const optimistic = {
6371
6388
  id: localId,
@@ -6554,15 +6571,15 @@ function AuthElement({
6554
6571
  }, [onReady, onAuthenticated, onError]);
6555
6572
  React14.useEffect(() => {
6556
6573
  if (!elements || !containerRef.current) return;
6557
- const element = elements.create(chunk3HU5I5VG_js.ELEMENT_TYPES.AUTH, { prefillEmail });
6574
+ const element = elements.create(chunkYER7DIOM_js.ELEMENT_TYPES.AUTH, { prefillEmail });
6558
6575
  elementRef.current = element;
6559
- element.on(chunk3HU5I5VG_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
6576
+ element.on(chunkYER7DIOM_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
6560
6577
  element.on(
6561
- chunk3HU5I5VG_js.EVENT_TYPES.AUTHENTICATED,
6578
+ chunkYER7DIOM_js.EVENT_TYPES.AUTHENTICATED,
6562
6579
  (data) => onAuthenticatedRef.current?.(data)
6563
6580
  );
6564
6581
  element.on(
6565
- chunk3HU5I5VG_js.EVENT_TYPES.ERROR,
6582
+ chunkYER7DIOM_js.EVENT_TYPES.ERROR,
6566
6583
  (data) => onErrorRef.current?.(data)
6567
6584
  );
6568
6585
  element.mount(containerRef.current);
@@ -6591,15 +6608,15 @@ function AddressElement({
6591
6608
  }, [onReady, onChange, onError]);
6592
6609
  React14.useEffect(() => {
6593
6610
  if (!elements || !containerRef.current) return;
6594
- const element = elements.create(chunk3HU5I5VG_js.ELEMENT_TYPES.ADDRESS, { mode });
6611
+ const element = elements.create(chunkYER7DIOM_js.ELEMENT_TYPES.ADDRESS, { mode });
6595
6612
  elementRef.current = element;
6596
- element.on(chunk3HU5I5VG_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
6613
+ element.on(chunkYER7DIOM_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
6597
6614
  element.on(
6598
- chunk3HU5I5VG_js.EVENT_TYPES.CHANGE,
6615
+ chunkYER7DIOM_js.EVENT_TYPES.CHANGE,
6599
6616
  (data) => onChangeRef.current?.(data)
6600
6617
  );
6601
6618
  element.on(
6602
- chunk3HU5I5VG_js.EVENT_TYPES.ERROR,
6619
+ chunkYER7DIOM_js.EVENT_TYPES.ERROR,
6603
6620
  (data) => onErrorRef.current?.(data)
6604
6621
  );
6605
6622
  element.mount(containerRef.current);
@@ -6629,15 +6646,15 @@ function PaymentElement({
6629
6646
  }, [onReady, onChange, onError]);
6630
6647
  React14.useEffect(() => {
6631
6648
  if (!elements || !containerRef.current) return;
6632
- const element = elements.create(chunk3HU5I5VG_js.ELEMENT_TYPES.PAYMENT, { amount, currency });
6649
+ const element = elements.create(chunkYER7DIOM_js.ELEMENT_TYPES.PAYMENT, { amount, currency });
6633
6650
  elementRef.current = element;
6634
- element.on(chunk3HU5I5VG_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
6651
+ element.on(chunkYER7DIOM_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
6635
6652
  element.on(
6636
- chunk3HU5I5VG_js.EVENT_TYPES.CHANGE,
6653
+ chunkYER7DIOM_js.EVENT_TYPES.CHANGE,
6637
6654
  (data) => onChangeRef.current?.(data)
6638
6655
  );
6639
6656
  element.on(
6640
- chunk3HU5I5VG_js.EVENT_TYPES.ERROR,
6657
+ chunkYER7DIOM_js.EVENT_TYPES.ERROR,
6641
6658
  (data) => onErrorRef.current?.(data)
6642
6659
  );
6643
6660
  element.mount(containerRef.current);
@@ -10985,6 +11002,9 @@ function CartSummary({
10985
11002
  itemCount,
10986
11003
  subtotal,
10987
11004
  tax,
11005
+ taxRate,
11006
+ taxInclusive,
11007
+ taxJurisdictionLabel,
10988
11008
  total,
10989
11009
  isEmpty,
10990
11010
  isOptimistic: isOptimistic2,
@@ -11117,7 +11137,13 @@ function CartSummary({
11117
11137
  "data-cimplify-cart-tax": true,
11118
11138
  className: cn("flex items-baseline justify-between", classNames?.tax),
11119
11139
  children: [
11120
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Tax" }),
11140
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-baseline gap-1.5 text-muted-foreground", children: [
11141
+ taxInclusive ? "Tax, included in prices" : taxJurisdictionLabel ? `Sales tax, ${taxJurisdictionLabel}` : "Sales tax",
11142
+ taxRate != null && taxRate > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "rounded-full bg-muted px-1.5 py-0.5 text-[11px] font-medium", children: [
11143
+ taxRate,
11144
+ "%"
11145
+ ] })
11146
+ ] }),
11121
11147
  /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: tax, currency: displayCurrency, className: "tabular-nums" })
11122
11148
  ]
11123
11149
  }
@@ -20258,7 +20284,20 @@ function ReplyCardView({
20258
20284
  }
20259
20285
  );
20260
20286
  }
20261
- var MAX_ATTACHMENT_BYTES = 5 * 1024 * 1024;
20287
+ var MAX_ATTACHMENT_BYTES = 25 * 1024 * 1024;
20288
+ var DOCUMENT_MIME_TYPES = /* @__PURE__ */ new Set([
20289
+ "application/pdf",
20290
+ "text/plain",
20291
+ "text/csv",
20292
+ "application/msword",
20293
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
20294
+ "application/vnd.ms-excel",
20295
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
20296
+ ]);
20297
+ var ATTACHMENT_ACCEPT = ["image/*", ...DOCUMENT_MIME_TYPES].join(",");
20298
+ function isAllowedAttachment(file) {
20299
+ return file.type.startsWith("image/") || DOCUMENT_MIME_TYPES.has(file.type);
20300
+ }
20262
20301
  var KEEP_DISMISSED_KEY = "cimplify_keep_chat_dismissed";
20263
20302
  var AT_BOTTOM_SLACK_PX = 48;
20264
20303
  function ChatWidget({
@@ -20304,16 +20343,18 @@ function ChatWidget({
20304
20343
  openIfExisting
20305
20344
  } = useChat({ client, pollInterval });
20306
20345
  const showTyping = isSending || awaitingReply;
20307
- const attachPhoto = React14.useCallback(
20346
+ const attachFile = React14.useCallback(
20308
20347
  async (file) => {
20309
20348
  if (!client) return;
20310
20349
  setAttachError(null);
20311
- if (!file.type.startsWith("image/")) {
20312
- setAttachError(new chunkNIOUSKQQ_js.CimplifyError("invalid_attachment", "Only photos can be attached."));
20350
+ if (!isAllowedAttachment(file)) {
20351
+ setAttachError(
20352
+ new chunkNIOUSKQQ_js.CimplifyError("invalid_attachment", "Only photos and documents can be attached.")
20353
+ );
20313
20354
  return;
20314
20355
  }
20315
20356
  if (file.size > MAX_ATTACHMENT_BYTES) {
20316
- setAttachError(new chunkNIOUSKQQ_js.CimplifyError("attachment_too_large", "Photos must be under 5MB."));
20357
+ setAttachError(new chunkNIOUSKQQ_js.CimplifyError("attachment_too_large", "Files must be under 25MB."));
20317
20358
  return;
20318
20359
  }
20319
20360
  const uploaded = await client.uploads.upload(file);
@@ -20405,7 +20446,7 @@ function ChatWidget({
20405
20446
  onCancelReply: () => setReplyTo(null),
20406
20447
  onRequestHuman: () => void requestHuman(),
20407
20448
  onLoadOlder: () => void loadOlder(),
20408
- onAttach: attachPhoto,
20449
+ onAttach: attachFile,
20409
20450
  onStartConversation: startConversation,
20410
20451
  currency,
20411
20452
  onGenUIAction,
@@ -21029,7 +21070,7 @@ function ChatInput({
21029
21070
  {
21030
21071
  ref: fileRef,
21031
21072
  type: "file",
21032
- accept: "image/*",
21073
+ accept: ATTACHMENT_ACCEPT,
21033
21074
  className: "hidden",
21034
21075
  "aria-hidden": "true",
21035
21076
  tabIndex: -1,
package/dist/react.mjs CHANGED
@@ -3,8 +3,8 @@ import { splitGenUIContent, messagePreview } from './chunk-U4MW6PYU.mjs';
3
3
  export { messagePreview, splitGenUIContent } from './chunk-U4MW6PYU.mjs';
4
4
  import { DURATION_UNIT, getVariantDisplayName, INPUT_FIELD_TYPE, isMultiDayService, serviceBillingMultiplier, PRODUCT_TYPE, BOUNDARY_KIND, resolveGallery, chatMessageCards, RENDER_HINT, DEFAULT_CDN_BASE_URL } from './chunk-4G5UWFC3.mjs';
5
5
  export { getVariantDisplayName } from './chunk-4G5UWFC3.mjs';
6
- import { SESSION_CLAIMED, SESSION_CLEARED, createCimplifyClient, AUTH_TOKEN_CHANGED, MUTATION_ERROR } from './chunk-BMFWQNYZ.mjs';
7
- import { generateIdempotencyKey, ELEMENT_TYPES, EVENT_TYPES, startSignIn } from './chunk-Z7M6GAHS.mjs';
6
+ import { SESSION_CLAIMED, SESSION_CLEARED, createCimplifyClient, AUTH_TOKEN_CHANGED, MUTATION_ERROR } from './chunk-DKLHCZ5M.mjs';
7
+ import { generateIdempotencyKey, ELEMENT_TYPES, EVENT_TYPES, startSignIn } from './chunk-Z3K2D3TE.mjs';
8
8
  import { parsePrice, formatMoney, formatPrice, getVariantUnitPrice, getProductCurrency, getUnitPriceAtQuantity, isOnSale, getDiscountPercentage, getBasePrice, getPriceRange, formatPriceRange } from './chunk-DLW3RWRK.mjs';
9
9
  import { isSupportedCurrency, currencyCode, CimplifyError } from './chunk-O3YUHLZL.mjs';
10
10
  import './chunk-3G6RQLXK.mjs';
@@ -430,6 +430,7 @@ function transformToCheckoutCart(cart, fx, checkout) {
430
430
  total: amt(cart.pricing.total_price),
431
431
  currency: fx?.displayCurrency ?? cart.pricing.currency,
432
432
  tax_inclusive: cart.pricing.tax_inclusive ?? false,
433
+ tax_rate: cart.pricing.tax_rate,
433
434
  deposit_required: cart.pricing.deposit_required ?? false,
434
435
  deposit_amount: cart.pricing.deposit_amount != null ? amt(cart.pricing.deposit_amount) : void 0,
435
436
  requires_delivery: cart.requires_delivery
@@ -682,7 +683,17 @@ function clearAllCartStores() {
682
683
  cartStores.clear();
683
684
  }
684
685
  function emptyBase(currency, isLoading = true) {
685
- return { items: [], subtotal: 0, tax: 0, total: 0, currency, isLoading };
686
+ return {
687
+ items: [],
688
+ subtotal: 0,
689
+ tax: 0,
690
+ taxRate: null,
691
+ taxInclusive: false,
692
+ taxJurisdictionLabel: null,
693
+ total: 0,
694
+ currency,
695
+ isLoading
696
+ };
686
697
  }
687
698
  function buildStoreKey(client, locationId) {
688
699
  return [client.getPublicKey() || "__no_public_key__", locationId || "__no_location__"].join(":");
@@ -775,6 +786,9 @@ function mapServerCart(serverCart, fallbackCurrency) {
775
786
  items,
776
787
  subtotal: roundMoney(toNumber(serverCart.pricing.subtotal)),
777
788
  tax: roundMoney(toNumber(serverCart.pricing.tax_amount)),
789
+ taxRate: serverCart.pricing.tax_rate != null ? toNumber(serverCart.pricing.tax_rate) : null,
790
+ taxInclusive: serverCart.pricing.tax_inclusive,
791
+ taxJurisdictionLabel: serverCart.pricing.tax_jurisdiction_label ?? null,
778
792
  total: roundMoney(toNumber(serverCart.pricing.total_price)),
779
793
  currency: serverCart.pricing.currency || fallbackCurrency,
780
794
  isLoading: false
@@ -1106,6 +1120,9 @@ function useCart(options = {}) {
1106
1120
  itemCount,
1107
1121
  subtotal: view.subtotal,
1108
1122
  tax: view.tax,
1123
+ taxRate: view.taxRate,
1124
+ taxInclusive: view.taxInclusive,
1125
+ taxJurisdictionLabel: view.taxJurisdictionLabel,
1109
1126
  total: view.total,
1110
1127
  currency: view.currency,
1111
1128
  isEmpty: itemCount === 0,
@@ -10961,6 +10978,9 @@ function CartSummary({
10961
10978
  itemCount,
10962
10979
  subtotal,
10963
10980
  tax,
10981
+ taxRate,
10982
+ taxInclusive,
10983
+ taxJurisdictionLabel,
10964
10984
  total,
10965
10985
  isEmpty,
10966
10986
  isOptimistic: isOptimistic2,
@@ -11093,7 +11113,13 @@ function CartSummary({
11093
11113
  "data-cimplify-cart-tax": true,
11094
11114
  className: cn("flex items-baseline justify-between", classNames?.tax),
11095
11115
  children: [
11096
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Tax" }),
11116
+ /* @__PURE__ */ jsxs("span", { className: "flex items-baseline gap-1.5 text-muted-foreground", children: [
11117
+ taxInclusive ? "Tax, included in prices" : taxJurisdictionLabel ? `Sales tax, ${taxJurisdictionLabel}` : "Sales tax",
11118
+ taxRate != null && taxRate > 0 && /* @__PURE__ */ jsxs("span", { className: "rounded-full bg-muted px-1.5 py-0.5 text-[11px] font-medium", children: [
11119
+ taxRate,
11120
+ "%"
11121
+ ] })
11122
+ ] }),
11097
11123
  /* @__PURE__ */ jsx(Price, { amount: tax, currency: displayCurrency, className: "tabular-nums" })
11098
11124
  ]
11099
11125
  }
@@ -20234,7 +20260,20 @@ function ReplyCardView({
20234
20260
  }
20235
20261
  );
20236
20262
  }
20237
- var MAX_ATTACHMENT_BYTES = 5 * 1024 * 1024;
20263
+ var MAX_ATTACHMENT_BYTES = 25 * 1024 * 1024;
20264
+ var DOCUMENT_MIME_TYPES = /* @__PURE__ */ new Set([
20265
+ "application/pdf",
20266
+ "text/plain",
20267
+ "text/csv",
20268
+ "application/msword",
20269
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
20270
+ "application/vnd.ms-excel",
20271
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
20272
+ ]);
20273
+ var ATTACHMENT_ACCEPT = ["image/*", ...DOCUMENT_MIME_TYPES].join(",");
20274
+ function isAllowedAttachment(file) {
20275
+ return file.type.startsWith("image/") || DOCUMENT_MIME_TYPES.has(file.type);
20276
+ }
20238
20277
  var KEEP_DISMISSED_KEY = "cimplify_keep_chat_dismissed";
20239
20278
  var AT_BOTTOM_SLACK_PX = 48;
20240
20279
  function ChatWidget({
@@ -20280,16 +20319,18 @@ function ChatWidget({
20280
20319
  openIfExisting
20281
20320
  } = useChat({ client, pollInterval });
20282
20321
  const showTyping = isSending || awaitingReply;
20283
- const attachPhoto = useCallback(
20322
+ const attachFile = useCallback(
20284
20323
  async (file) => {
20285
20324
  if (!client) return;
20286
20325
  setAttachError(null);
20287
- if (!file.type.startsWith("image/")) {
20288
- setAttachError(new CimplifyError("invalid_attachment", "Only photos can be attached."));
20326
+ if (!isAllowedAttachment(file)) {
20327
+ setAttachError(
20328
+ new CimplifyError("invalid_attachment", "Only photos and documents can be attached.")
20329
+ );
20289
20330
  return;
20290
20331
  }
20291
20332
  if (file.size > MAX_ATTACHMENT_BYTES) {
20292
- setAttachError(new CimplifyError("attachment_too_large", "Photos must be under 5MB."));
20333
+ setAttachError(new CimplifyError("attachment_too_large", "Files must be under 25MB."));
20293
20334
  return;
20294
20335
  }
20295
20336
  const uploaded = await client.uploads.upload(file);
@@ -20381,7 +20422,7 @@ function ChatWidget({
20381
20422
  onCancelReply: () => setReplyTo(null),
20382
20423
  onRequestHuman: () => void requestHuman(),
20383
20424
  onLoadOlder: () => void loadOlder(),
20384
- onAttach: attachPhoto,
20425
+ onAttach: attachFile,
20385
20426
  onStartConversation: startConversation,
20386
20427
  currency,
20387
20428
  onGenUIAction,
@@ -21005,7 +21046,7 @@ function ChatInput({
21005
21046
  {
21006
21047
  ref: fileRef,
21007
21048
  type: "file",
21008
- accept: "image/*",
21049
+ accept: ATTACHMENT_ACCEPT,
21009
21050
  className: "hidden",
21010
21051
  "aria-hidden": "true",
21011
21052
  tabIndex: -1,
@@ -7,17 +7,21 @@ import { IncrementalCache } from '@opennextjs/aws/types/overrides';
7
7
  * model that fits Cimplify's event-driven domain:
8
8
  *
9
9
  * - `get`: standard R2 fetch. Returns the cached value or null.
10
- * - `set`: writes to R2 AND emits a tag→cache_key index update to the shared
11
- * `CIMPLIFY_PATH_INDEX` Durable Object (hosted in cimplify-tag-cache).
10
+ * - `set`: reserves a tag→cache_key index update in the shared
11
+ * `CIMPLIFY_PATH_INDEX` Durable Object, writes the value to R2, then
12
+ * confirms that no eviction crossed the write. A tagged value is never
13
+ * cached unless its eviction index is durable and its reservation remains
14
+ * current.
12
15
  * - `delete`: standard R2 delete (called by opennext on explicit invalidate;
13
16
  * also called by us from the Rust EvictionDispatcher path on tag events).
14
17
  *
15
- * The Rust EvictionDispatcher reads the index on bus events, deletes the
16
- * matching R2 entries directly, and prunes the index — there is no SWR
17
- * "background refresh" path. opennext's queue and `isStale` checks become
18
- * no-ops; cached entries are by definition fresh (existed at write time and
19
- * haven't been evicted), and absence means the next request synchronously
20
- * re-renders.
18
+ * The Rust EvictionDispatcher signals the tag-cache worker on bus events. That
19
+ * worker fences new writes, reads the index, deletes matching R2 entries, and
20
+ * purges the dispatch worker's per-script HTML cache tag. A write whose
21
+ * reservation was crossed by that fence deletes its just-written R2 object.
22
+ * There is no SWR "background refresh" path: opennext's queue and `isStale`
23
+ * checks are no-ops, and an R2 miss makes the next request synchronously
24
+ * re-render.
21
25
  *
22
26
  * Why this exists: WfP user workers cannot have `WORKER_SELF_REFERENCE`,
23
27
  * which is the binding every built-in opennext queue requires. Rather than
@@ -7,17 +7,21 @@ import { IncrementalCache } from '@opennextjs/aws/types/overrides';
7
7
  * model that fits Cimplify's event-driven domain:
8
8
  *
9
9
  * - `get`: standard R2 fetch. Returns the cached value or null.
10
- * - `set`: writes to R2 AND emits a tag→cache_key index update to the shared
11
- * `CIMPLIFY_PATH_INDEX` Durable Object (hosted in cimplify-tag-cache).
10
+ * - `set`: reserves a tag→cache_key index update in the shared
11
+ * `CIMPLIFY_PATH_INDEX` Durable Object, writes the value to R2, then
12
+ * confirms that no eviction crossed the write. A tagged value is never
13
+ * cached unless its eviction index is durable and its reservation remains
14
+ * current.
12
15
  * - `delete`: standard R2 delete (called by opennext on explicit invalidate;
13
16
  * also called by us from the Rust EvictionDispatcher path on tag events).
14
17
  *
15
- * The Rust EvictionDispatcher reads the index on bus events, deletes the
16
- * matching R2 entries directly, and prunes the index — there is no SWR
17
- * "background refresh" path. opennext's queue and `isStale` checks become
18
- * no-ops; cached entries are by definition fresh (existed at write time and
19
- * haven't been evicted), and absence means the next request synchronously
20
- * re-renders.
18
+ * The Rust EvictionDispatcher signals the tag-cache worker on bus events. That
19
+ * worker fences new writes, reads the index, deletes matching R2 entries, and
20
+ * purges the dispatch worker's per-script HTML cache tag. A write whose
21
+ * reservation was crossed by that fence deletes its just-written R2 object.
22
+ * There is no SWR "background refresh" path: opennext's queue and `isStale`
23
+ * checks are no-ops, and an R2 miss makes the next request synchronously
24
+ * re-render.
21
25
  *
22
26
  * Why this exists: WfP user workers cannot have `WORKER_SELF_REFERENCE`,
23
27
  * which is the binding every built-in opennext queue requires. Rather than
@@ -24,6 +24,18 @@ function pathIndexFor(env) {
24
24
  if (!ns || !prefix) return null;
25
25
  return ns.get(ns.idFromName(prefix));
26
26
  }
27
+ function isAcceptedReservation(value) {
28
+ if (typeof value !== "object" || value === null) return false;
29
+ const reservation = value;
30
+ return reservation.accepted === true && typeof reservation.generation === "number" && Number.isSafeInteger(reservation.generation) && reservation.generation >= 0;
31
+ }
32
+ async function removeRejectedWrite(r2, key) {
33
+ try {
34
+ await r2.delete(key);
35
+ } catch {
36
+ reportRejectedTaggedWrite("r2-compensating-delete-failed");
37
+ }
38
+ }
27
39
  var evictIncrementalCache = {
28
40
  name: "cimplify-evict-r2-cache",
29
41
  async get(key, cacheType) {
@@ -46,18 +58,43 @@ var evictIncrementalCache = {
46
58
  const r2 = env[R2_BUCKET_BINDING];
47
59
  if (!r2) return;
48
60
  const k = r2Key(env, key, cacheType);
61
+ const tags = cimplifyTags(value);
62
+ let index = null;
63
+ let reservation = null;
64
+ if (tags.length > 0) {
65
+ index = pathIndexFor(env);
66
+ if (!index) {
67
+ reportRejectedTaggedWrite("path-index-not-configured");
68
+ return;
69
+ }
70
+ try {
71
+ const candidate = await index.indexAdd(key, k, tags, cacheType === "fetch");
72
+ if (!isAcceptedReservation(candidate)) {
73
+ const fenceActive = typeof candidate === "object" && candidate !== null && candidate.accepted === false;
74
+ reportRejectedTaggedWrite(
75
+ fenceActive ? "path-index-eviction-fence-active" : "path-index-invalid-reservation"
76
+ );
77
+ return;
78
+ }
79
+ reservation = candidate;
80
+ } catch {
81
+ reportRejectedTaggedWrite("path-index-write-failed");
82
+ return;
83
+ }
84
+ }
49
85
  try {
50
86
  await r2.put(k, JSON.stringify(value));
51
87
  } catch {
52
88
  return;
53
89
  }
54
- const tags = cimplifyTags(value);
55
- if (tags.length === 0) return;
56
- const index = pathIndexFor(env);
57
- if (!index) return;
58
- try {
59
- await index.indexAdd(key, k, tags, cacheType === "fetch");
60
- } catch {
90
+ if (index && reservation) {
91
+ try {
92
+ if (await index.indexConfirm(reservation.generation, tags)) return;
93
+ reportRejectedTaggedWrite("path-index-reservation-invalidated");
94
+ } catch {
95
+ reportRejectedTaggedWrite("path-index-confirm-failed");
96
+ }
97
+ await removeRejectedWrite(r2, k);
61
98
  }
62
99
  },
63
100
  async delete(key) {
@@ -70,6 +107,15 @@ var evictIncrementalCache = {
70
107
  }
71
108
  }
72
109
  };
110
+ function reportRejectedTaggedWrite(reason) {
111
+ console.error(
112
+ JSON.stringify({
113
+ level: "error",
114
+ event: "storefront_cache_write_rejected",
115
+ reason
116
+ })
117
+ );
118
+ }
73
119
  var evict_incremental_cache_default = evictIncrementalCache;
74
120
 
75
121
  exports.evictIncrementalCache = evict_incremental_cache_default;