@cimplify/sdk 0.92.0 → 0.94.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.
Files changed (59) 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-OAHSF542.js → chunk-6Y7KC5YZ.js} +11 -0
  6. package/dist/{chunk-3MBMIEWT.js → chunk-AWNWP5J3.js} +4 -4
  7. package/dist/{chunk-3XD2FVP4.mjs → chunk-FKARGZK3.mjs} +195 -60
  8. package/dist/{chunk-DCRN67NO.js → chunk-QLGZIBRO.js} +237 -102
  9. package/dist/{chunk-54H2YYIW.mjs → chunk-QXWX7CD2.mjs} +2 -2
  10. package/dist/{chunk-IVJEUGWF.js → chunk-VEOAMBEX.js} +1 -3
  11. package/dist/{chunk-T7LDBZZZ.mjs → chunk-VUSHG3HA.mjs} +1 -3
  12. package/dist/{chunk-PYBFTMHI.mjs → chunk-X36FZZT6.mjs} +11 -0
  13. package/dist/{client-CeW3acve.d.ts → client-BTL9d_nN.d.mts} +29 -2
  14. package/dist/{client-BQbSKlHS.d.mts → client-BX30FAWZ.d.ts} +29 -2
  15. package/dist/{client-Bw4HtLP1.d.mts → client-Bhe2TnFW.d.mts} +2 -2
  16. package/dist/{client-Otzv_rgP.d.ts → client-DrkuEK_I.d.ts} +2 -2
  17. package/dist/{index-CmIboQjl.d.mts → index-BuNjyfaV.d.mts} +3 -3
  18. package/dist/{index-DgoRwz8l.d.ts → index-D-w5h82t.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 +11 -0
  24. package/dist/mock/library.js +11 -0
  25. package/dist/mock/library.mjs +11 -0
  26. package/dist/mock/msw.js +11 -0
  27. package/dist/mock/msw.mjs +11 -0
  28. package/dist/{payment-Cq8FT1B6.d.ts → payment-By0JidTe.d.ts} +1 -1
  29. package/dist/{payment-BFtLqiG2.d.mts → payment-pKPpaORI.d.mts} +1 -1
  30. package/dist/{price-DaFXT-Lr.d.ts → price-23RNXftz.d.ts} +1 -1
  31. package/dist/{price-DleDWk_s.d.mts → price-BvRtp6ak.d.mts} +1 -1
  32. package/dist/{product-bZ8G5Z8D.d.mts → product-O8-wcHSe.d.mts} +11 -0
  33. package/dist/{product-bZ8G5Z8D.d.ts → product-O8-wcHSe.d.ts} +11 -0
  34. package/dist/react.d.mts +20 -6
  35. package/dist/react.d.ts +20 -6
  36. package/dist/react.js +208 -76
  37. package/dist/react.mjs +190 -59
  38. package/dist/{server-D-iK-bNt.d.mts → server-BN9ZCAKT.d.mts} +5 -1
  39. package/dist/{server-DwsY9hlX.d.ts → server-DDGbfW_S.d.ts} +5 -1
  40. package/dist/server.d.mts +4 -4
  41. package/dist/server.d.ts +4 -4
  42. package/dist/server.js +7 -7
  43. package/dist/server.mjs +2 -2
  44. package/dist/testing/msw.d.mts +2 -2
  45. package/dist/testing/msw.d.ts +2 -2
  46. package/dist/testing/msw.js +2 -2
  47. package/dist/testing/msw.mjs +1 -1
  48. package/dist/testing/suite.d.mts +6 -6
  49. package/dist/testing/suite.d.ts +6 -6
  50. package/dist/testing/suite.js +23 -23
  51. package/dist/testing/suite.mjs +4 -4
  52. package/dist/testing.d.mts +5 -5
  53. package/dist/testing.d.ts +5 -5
  54. package/dist/testing.js +79 -79
  55. package/dist/testing.mjs +5 -5
  56. package/dist/utils.d.mts +4 -4
  57. package/dist/utils.d.ts +4 -4
  58. package/package.json +1 -1
  59. package/registry/chat-widget.json +1 -1
package/dist/react.mjs CHANGED
@@ -3,10 +3,10 @@ import { DURATION_UNIT, getVariantDisplayName, INPUT_FIELD_TYPE, isMultiDayServi
3
3
  export { getVariantDisplayName } from './chunk-RRBY35TJ.mjs';
4
4
  import { messagePreview } from './chunk-U4MW6PYU.mjs';
5
5
  export { messagePreview, splitGenUIContent } from './chunk-U4MW6PYU.mjs';
6
- import { SESSION_CLAIMED, SESSION_CLEARED, createCimplifyClient, MUTATION_ERROR } from './chunk-3XD2FVP4.mjs';
7
- import { ELEMENT_TYPES, EVENT_TYPES, startSignIn } from './chunk-T7LDBZZZ.mjs';
6
+ import { SESSION_CLAIMED, SESSION_CLEARED, createCimplifyClient, MUTATION_ERROR } from './chunk-FKARGZK3.mjs';
7
+ import { generateIdempotencyKey, ELEMENT_TYPES, EVENT_TYPES, startSignIn } from './chunk-VUSHG3HA.mjs';
8
8
  import { parsePrice, formatMoney, formatPrice, getProductCurrency, getUnitPriceAtQuantity, isOnSale, getDiscountPercentage, getBasePrice, getPriceRange, formatPriceRange } from './chunk-KFLGQGMC.mjs';
9
- import { isSupportedCurrency } from './chunk-K5EN2W2Q.mjs';
9
+ import { isSupportedCurrency, CimplifyError } from './chunk-K5EN2W2Q.mjs';
10
10
  import './chunk-3G6RQLXK.mjs';
11
11
  import React14, { createContext, lazy, memo, Suspense, useContext, useMemo, useRef, useState, useCallback, useEffect, useId, useSyncExternalStore } from 'react';
12
12
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
@@ -1113,6 +1113,37 @@ function preconnectOrigin(url, crossOrigin) {
1113
1113
  if (crossOrigin) link.crossOrigin = crossOrigin;
1114
1114
  document.head.appendChild(link);
1115
1115
  }
1116
+ function usePageViewTracking(client, enabled) {
1117
+ useEffect(() => {
1118
+ if (!enabled || typeof window === "undefined") return;
1119
+ let lastPath = null;
1120
+ const record = () => {
1121
+ const path = window.location.pathname;
1122
+ if (path === lastPath) return;
1123
+ lastPath = path;
1124
+ try {
1125
+ client.activity?.trackPageView({ pagePath: path });
1126
+ } catch {
1127
+ }
1128
+ };
1129
+ record();
1130
+ const { pushState, replaceState } = window.history;
1131
+ window.history.pushState = function(...args) {
1132
+ pushState.apply(this, args);
1133
+ record();
1134
+ };
1135
+ window.history.replaceState = function(...args) {
1136
+ replaceState.apply(this, args);
1137
+ record();
1138
+ };
1139
+ window.addEventListener("popstate", record);
1140
+ return () => {
1141
+ window.history.pushState = pushState;
1142
+ window.history.replaceState = replaceState;
1143
+ window.removeEventListener("popstate", record);
1144
+ };
1145
+ }, [client, enabled]);
1146
+ }
1116
1147
  var LOCATION_STORAGE_KEY = "cimplify_location_id";
1117
1148
  var DISPLAY_CURRENCY_STORAGE_KEY = "cimplify_display_currency";
1118
1149
  var FX_REFRESH_INTERVAL = 12e4;
@@ -1193,9 +1224,11 @@ function CimplifyProvider({
1193
1224
  initialLocations,
1194
1225
  optimistic = true,
1195
1226
  prefetch,
1196
- linkComponent
1227
+ linkComponent,
1228
+ trackPageViews = true
1197
1229
  }) {
1198
1230
  const resolvedClient = useMemo(() => client ?? createDefaultClient(), [client]);
1231
+ usePageViewTracking(resolvedClient, trackPageViews);
1199
1232
  const resolvedPrefetch = useMemo(
1200
1233
  () => ({
1201
1234
  mode: prefetch?.mode ?? DEFAULT_PREFETCH_OPTIONS.mode,
@@ -5889,6 +5922,20 @@ var IDLE_TIMEOUT_MS = 6e4;
5889
5922
  var WS_MAX_RECONNECT_ATTEMPTS = 10;
5890
5923
  var WS_PATH = "/api/v1/support/conversation/ws";
5891
5924
  var AWAIT_REPLY_TIMEOUT_MS = 3e4;
5925
+ function mergeMessages(prev, incoming) {
5926
+ const ids = new Set(prev.map((m) => m.id));
5927
+ const fresh = incoming.filter((m) => !ids.has(m.id));
5928
+ if (fresh.length === 0) return prev;
5929
+ const merged = [...prev, ...fresh].sort(
5930
+ (a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime()
5931
+ );
5932
+ const confirmed = new Set(
5933
+ merged.filter((m) => !m.id.startsWith("opt_") && m.client_id).map((m) => m.client_id)
5934
+ );
5935
+ return merged.filter(
5936
+ (m) => !(m.id.startsWith("opt_") && m.client_id && confirmed.has(m.client_id))
5937
+ );
5938
+ }
5892
5939
  function useChat(options = {}) {
5893
5940
  const context = useOptionalCimplifyClient();
5894
5941
  const client = options.client ?? context?.client;
@@ -5941,18 +5988,22 @@ function useChat(options = {}) {
5941
5988
  if (incoming.some((m) => m.sender_type === "bot" || m.sender_type === "agent")) {
5942
5989
  stopAwaitingReply();
5943
5990
  }
5944
- setMessages((prev) => {
5945
- const ids = new Set(prev.map((m) => m.id));
5946
- const fresh = incoming.filter((m) => !ids.has(m.id));
5947
- return fresh.length > 0 ? [...prev, ...fresh] : prev;
5948
- });
5991
+ if (incoming.length > 0) lastActivityRef.current = Date.now();
5992
+ setMessages((prev) => mergeMessages(prev, incoming));
5949
5993
  },
5950
5994
  [stopAwaitingReply]
5951
5995
  );
5996
+ const lastConfirmedMessage = useCallback(() => {
5997
+ const list = messagesRef.current;
5998
+ for (let i = list.length - 1; i >= 0; i--) {
5999
+ if (!list[i].id.startsWith("opt_")) return list[i];
6000
+ }
6001
+ return void 0;
6002
+ }, []);
5952
6003
  const fetchNewMessages = useCallback(async () => {
5953
6004
  const c = clientRef.current;
5954
6005
  if (!c) return;
5955
- const last = messagesRef.current[messagesRef.current.length - 1];
6006
+ const last = lastConfirmedMessage();
5956
6007
  const result = await c.support.getMessages({
5957
6008
  after: last?.created_at,
5958
6009
  limit: 50
@@ -5960,16 +6011,23 @@ function useChat(options = {}) {
5960
6011
  if (result.ok && result.value.length > 0) {
5961
6012
  appendMessages(result.value);
5962
6013
  }
5963
- }, [appendMessages]);
5964
- const pollMessages = useCallback(async () => {
5965
- if (Date.now() - lastActivityRef.current > IDLE_TIMEOUT_MS) return;
5966
- await fetchNewMessages();
5967
- }, [fetchNewMessages]);
6014
+ }, [appendMessages, lastConfirmedMessage]);
5968
6015
  const startPolling = useCallback(() => {
5969
6016
  if (pollRef.current) clearInterval(pollRef.current);
5970
- const interval = Date.now() - lastActivityRef.current > IDLE_TIMEOUT_MS ? pollIdleInterval : pollInterval;
5971
- pollRef.current = setInterval(pollMessages, interval);
5972
- }, [pollMessages, pollInterval, pollIdleInterval]);
6017
+ const idle = () => Date.now() - lastActivityRef.current > IDLE_TIMEOUT_MS;
6018
+ let current = idle() ? pollIdleInterval : pollInterval;
6019
+ const tick = () => {
6020
+ void fetchNewMessages().then(() => {
6021
+ const desired = idle() ? pollIdleInterval : pollInterval;
6022
+ if (desired !== current && pollRef.current) {
6023
+ current = desired;
6024
+ clearInterval(pollRef.current);
6025
+ pollRef.current = setInterval(tick, current);
6026
+ }
6027
+ });
6028
+ };
6029
+ pollRef.current = setInterval(tick, current);
6030
+ }, [fetchNewMessages, pollInterval, pollIdleInterval]);
5973
6031
  const stopPolling = useCallback(() => {
5974
6032
  if (pollRef.current) {
5975
6033
  clearInterval(pollRef.current);
@@ -5981,7 +6039,15 @@ function useChat(options = {}) {
5981
6039
  if (!c || !openedRef.current) return;
5982
6040
  const result = await c.support.openConversation();
5983
6041
  if (!result.ok) return;
5984
- setMessages(result.value.messages);
6042
+ const snapshot = result.value.messages;
6043
+ setMessages((prev) => {
6044
+ const snapshotIds = new Set(snapshot.map((m) => m.id));
6045
+ const tail = snapshot.length > 0 ? new Date(snapshot[snapshot.length - 1].created_at).getTime() : 0;
6046
+ const extras = prev.filter(
6047
+ (m) => !snapshotIds.has(m.id) && (m.id.startsWith("opt_") || new Date(m.created_at).getTime() > tail)
6048
+ );
6049
+ return mergeMessages(snapshot, extras);
6050
+ });
5985
6051
  aiEnabledRef.current = result.value.conversation.ai_enabled;
5986
6052
  setHumanRequested(result.value.conversation.needs_human_review ?? false);
5987
6053
  setSeenAt(result.value.conversation.team_read_at ?? null);
@@ -5993,7 +6059,13 @@ function useChat(options = {}) {
5993
6059
  startPolling();
5994
6060
  return;
5995
6061
  }
6062
+ if (wsReconnectTimerRef.current) {
6063
+ clearTimeout(wsReconnectTimerRef.current);
6064
+ wsReconnectTimerRef.current = null;
6065
+ }
5996
6066
  if (wsRef.current) {
6067
+ wsRef.current.onclose = null;
6068
+ wsRef.current.onmessage = null;
5997
6069
  wsRef.current.close();
5998
6070
  wsRef.current = null;
5999
6071
  }
@@ -6017,7 +6089,7 @@ function useChat(options = {}) {
6017
6089
  else stopAwaitingReply();
6018
6090
  } else if (envelope.type === "resync") {
6019
6091
  const latest = envelope.latest_message_at;
6020
- const last = messagesRef.current[messagesRef.current.length - 1];
6092
+ const last = lastConfirmedMessage();
6021
6093
  if (latest && (!last || new Date(last.created_at).getTime() < new Date(latest).getTime())) {
6022
6094
  fetchNewMessages();
6023
6095
  }
@@ -6034,6 +6106,7 @@ function useChat(options = {}) {
6034
6106
  if (wsReconnectAttemptRef.current < WS_MAX_RECONNECT_ATTEMPTS) {
6035
6107
  const attempt = wsReconnectAttemptRef.current++;
6036
6108
  const delay = Math.min(1e3 * Math.pow(2, attempt) + Math.random() * 500, 3e4);
6109
+ if (wsReconnectTimerRef.current) clearTimeout(wsReconnectTimerRef.current);
6037
6110
  wsReconnectTimerRef.current = setTimeout(connectWebSocket, delay);
6038
6111
  } else {
6039
6112
  startPolling();
@@ -6042,7 +6115,7 @@ function useChat(options = {}) {
6042
6115
  ws.onerror = () => {
6043
6116
  };
6044
6117
  wsRef.current = ws;
6045
- }, [appendMessages, startPolling, stopPolling, fetchNewMessages, resyncConversation]);
6118
+ }, [appendMessages, startPolling, stopPolling, fetchNewMessages, resyncConversation, lastConfirmedMessage]);
6046
6119
  const resetConversation = useCallback(() => {
6047
6120
  stopPolling();
6048
6121
  if (wsReconnectTimerRef.current) {
@@ -6065,12 +6138,42 @@ function useChat(options = {}) {
6065
6138
  setError(null);
6066
6139
  setClaimedAs(null);
6067
6140
  }, [stopPolling, stopAwaitingReply]);
6141
+ const hydrateConversation = useCallback(
6142
+ (value) => {
6143
+ const c = clientRef.current;
6144
+ setMessages(value.messages);
6145
+ setConversationOpened(true);
6146
+ aiEnabledRef.current = value.conversation.ai_enabled;
6147
+ setHumanRequested(value.conversation.needs_human_review ?? false);
6148
+ setSeenAt(value.conversation.team_read_at ?? null);
6149
+ setMayHaveOlder(value.messages.length >= 50);
6150
+ setClaimedAs(c?.support.claimedCustomerName ?? null);
6151
+ connectWebSocket();
6152
+ },
6153
+ [connectWebSocket]
6154
+ );
6155
+ const openIfExisting = useCallback(async () => {
6156
+ const c = clientRef.current;
6157
+ if (!c || openedRef.current) return;
6158
+ openedRef.current = true;
6159
+ setIsLoading(true);
6160
+ const result = await c.support.peekConversation();
6161
+ if (result.ok && result.value) {
6162
+ hydrateConversation(result.value);
6163
+ } else {
6164
+ openedRef.current = false;
6165
+ }
6166
+ setIsLoading(false);
6167
+ }, [hydrateConversation]);
6068
6168
  const watchSessionClaims = useCallback(() => {
6069
6169
  const c = clientRef.current;
6070
6170
  if (!c || claimUnsubRef.current) return;
6071
6171
  const unsubClaimed = c.events.on(SESSION_CLAIMED, (event) => {
6072
- setClaimedAs(event.customerName || null);
6073
- if (!openedRef.current) return;
6172
+ setClaimedAs(event.customerName || c.support.claimedCustomerName || null);
6173
+ if (!openedRef.current) {
6174
+ void openIfExisting();
6175
+ return;
6176
+ }
6074
6177
  connectWebSocket();
6075
6178
  void resyncConversation();
6076
6179
  });
@@ -6079,7 +6182,7 @@ function useChat(options = {}) {
6079
6182
  unsubClaimed();
6080
6183
  unsubCleared();
6081
6184
  };
6082
- }, [connectWebSocket, resyncConversation, resetConversation]);
6185
+ }, [connectWebSocket, resyncConversation, resetConversation, openIfExisting]);
6083
6186
  const signOut = useCallback(async () => {
6084
6187
  const c = clientRef.current;
6085
6188
  if (!c) return false;
@@ -6087,6 +6190,7 @@ function useChat(options = {}) {
6087
6190
  return result.ok;
6088
6191
  }, []);
6089
6192
  useEffect(() => {
6193
+ watchSessionClaims();
6090
6194
  return () => {
6091
6195
  if (pollRef.current) clearInterval(pollRef.current);
6092
6196
  if (wsReconnectTimerRef.current) clearTimeout(wsReconnectTimerRef.current);
@@ -6095,6 +6199,7 @@ function useChat(options = {}) {
6095
6199
  claimUnsubRef.current = null;
6096
6200
  if (wsRef.current) {
6097
6201
  wsRef.current.onclose = null;
6202
+ wsRef.current.onmessage = null;
6098
6203
  wsRef.current.close();
6099
6204
  }
6100
6205
  };
@@ -6106,21 +6211,13 @@ function useChat(options = {}) {
6106
6211
  setError(null);
6107
6212
  const result = await client.support.openConversation();
6108
6213
  if (result.ok) {
6109
- setMessages(result.value.messages);
6110
- setConversationOpened(true);
6111
- aiEnabledRef.current = result.value.conversation.ai_enabled;
6112
- setHumanRequested(result.value.conversation.needs_human_review ?? false);
6113
- setSeenAt(result.value.conversation.team_read_at ?? null);
6114
- setMayHaveOlder(result.value.messages.length >= 50);
6115
- setClaimedAs(client.support.claimedCustomerName);
6116
- connectWebSocket();
6117
- watchSessionClaims();
6214
+ hydrateConversation(result.value);
6118
6215
  } else {
6119
6216
  openedRef.current = false;
6120
6217
  setError(result.error);
6121
6218
  }
6122
6219
  setIsLoading(false);
6123
- }, [client, connectWebSocket, watchSessionClaims]);
6220
+ }, [client, hydrateConversation]);
6124
6221
  const send = useCallback(
6125
6222
  async (content, opts) => {
6126
6223
  const attachments = opts?.attachments ?? [];
@@ -6132,7 +6229,8 @@ function useChat(options = {}) {
6132
6229
  if (!openedRef.current) return false;
6133
6230
  }
6134
6231
  const replyTo = opts?.replyTo;
6135
- const optimisticId = `opt_${Date.now()}`;
6232
+ const clientId = generateIdempotencyKey();
6233
+ const optimisticId = `opt_${clientId}`;
6136
6234
  const optimistic = {
6137
6235
  id: optimisticId,
6138
6236
  sender_type: "customer",
@@ -6140,6 +6238,7 @@ function useChat(options = {}) {
6140
6238
  content_type: attachments.length > 0 ? "image" : "text",
6141
6239
  attachments,
6142
6240
  metadata: {},
6241
+ client_id: clientId,
6143
6242
  // Same shape the server echoes back, so the bubble doesn't reflow
6144
6243
  // when the confirmed message replaces it.
6145
6244
  reply_to: replyTo ? {
@@ -6152,6 +6251,7 @@ function useChat(options = {}) {
6152
6251
  setMessages((prev) => [...prev, optimistic]);
6153
6252
  setIsSending(true);
6154
6253
  const result = await client.support.sendMessage(content.trim(), {
6254
+ idempotencyKey: clientId,
6155
6255
  replyToMessageId: replyTo?.id,
6156
6256
  attachments: attachments.length > 0 ? attachments : void 0
6157
6257
  });
@@ -6222,11 +6322,7 @@ function useChat(options = {}) {
6222
6322
  const older = result.value;
6223
6323
  setMayHaveOlder(older.length >= 50);
6224
6324
  if (older.length === 0) return false;
6225
- setMessages((prev) => {
6226
- const ids = new Set(prev.map((m) => m.id));
6227
- const fresh = older.filter((m) => !ids.has(m.id));
6228
- return fresh.length > 0 ? [...fresh, ...prev] : prev;
6229
- });
6325
+ setMessages((prev) => mergeMessages(prev, older));
6230
6326
  return true;
6231
6327
  }, []);
6232
6328
  const agentArrived = messages.some((m) => m.sender_type === "agent");
@@ -6246,7 +6342,8 @@ function useChat(options = {}) {
6246
6342
  startConversation,
6247
6343
  react,
6248
6344
  requestHuman,
6249
- loadOlder
6345
+ loadOlder,
6346
+ openIfExisting
6250
6347
  };
6251
6348
  }
6252
6349
  var ElementsContext = createContext({
@@ -12414,6 +12511,9 @@ function ProductGrid({
12414
12511
 
12415
12512
  // src/react/utils/attachment.ts
12416
12513
  var IMAGE_EXTENSIONS = [".jpg", ".jpeg", ".png", ".webp", ".gif", ".bmp", ".svg"];
12514
+ function safeAttachmentUrl(url) {
12515
+ return /^https?:\/\//i.test(url) ? url : null;
12516
+ }
12417
12517
  function isImageAttachment(attachment) {
12418
12518
  if (attachment.mime_type?.startsWith("image/")) return true;
12419
12519
  if (attachment.mime_type) return false;
@@ -17060,6 +17160,7 @@ function partitionMessages(messages) {
17060
17160
  }
17061
17161
  return { bubbles, reactionsByTarget };
17062
17162
  }
17163
+ var MAX_ATTACHMENT_BYTES = 5 * 1024 * 1024;
17063
17164
  function ChatWidget({
17064
17165
  client: clientProp,
17065
17166
  businessName = "Support",
@@ -17076,7 +17177,8 @@ function ChatWidget({
17076
17177
  const context = useOptionalCimplifyClient();
17077
17178
  const client = clientProp ?? context?.client;
17078
17179
  const [open, setOpen] = useState(defaultOpen);
17079
- const [readCount, setReadCount] = useState(0);
17180
+ const [readAt, setReadAt] = useState(null);
17181
+ const [attachError, setAttachError] = useState(null);
17080
17182
  const {
17081
17183
  messages,
17082
17184
  isLoading,
@@ -17089,14 +17191,27 @@ function ChatWidget({
17089
17191
  signOut,
17090
17192
  send,
17091
17193
  react,
17092
- startConversation
17194
+ startConversation,
17195
+ openIfExisting
17093
17196
  } = useChat({ client, pollInterval });
17094
17197
  const showTyping = isSending || awaitingReply;
17095
17198
  const attachPhoto = useCallback(
17096
17199
  async (file) => {
17097
- if (!client || !file.type.startsWith("image/") || file.size > 5 * 1024 * 1024) return;
17200
+ if (!client) return;
17201
+ setAttachError(null);
17202
+ if (!file.type.startsWith("image/")) {
17203
+ setAttachError(new CimplifyError("invalid_attachment", "Only photos can be attached."));
17204
+ return;
17205
+ }
17206
+ if (file.size > MAX_ATTACHMENT_BYTES) {
17207
+ setAttachError(new CimplifyError("attachment_too_large", "Photos must be under 5MB."));
17208
+ return;
17209
+ }
17098
17210
  const uploaded = await client.uploads.upload(file);
17099
- if (!uploaded.ok) return;
17211
+ if (!uploaded.ok) {
17212
+ setAttachError(uploaded.error);
17213
+ return;
17214
+ }
17100
17215
  const attachment = {
17101
17216
  upload_id: uploaded.value.id,
17102
17217
  url: uploaded.value.url,
@@ -17108,14 +17223,28 @@ function ChatWidget({
17108
17223
  },
17109
17224
  [client, send]
17110
17225
  );
17111
- const unread = open ? 0 : messages.slice(readCount).filter((m) => m.sender_type !== "customer").length;
17226
+ const handleSend = useCallback(
17227
+ (content) => {
17228
+ setAttachError(null);
17229
+ return send(content);
17230
+ },
17231
+ [send]
17232
+ );
17233
+ const unread = open ? 0 : messages.filter(
17234
+ (m) => m.sender_type !== "customer" && (!readAt || m.created_at > readAt)
17235
+ ).length;
17236
+ useState(() => {
17237
+ if (defaultOpen) void openIfExisting();
17238
+ });
17112
17239
  const handleOpen = useCallback(() => {
17113
17240
  setOpen(true);
17114
- }, []);
17241
+ void openIfExisting();
17242
+ }, [openIfExisting]);
17115
17243
  const handleClose = useCallback(() => {
17116
- setReadCount(messages.length);
17244
+ const newest = messages[messages.length - 1];
17245
+ setReadAt(newest?.created_at ?? null);
17117
17246
  setOpen(false);
17118
- }, [messages.length]);
17247
+ }, [messages]);
17119
17248
  const isLeft = position === "bottom-left";
17120
17249
  return /* @__PURE__ */ jsxs(
17121
17250
  "div",
@@ -17148,13 +17277,13 @@ function ChatWidget({
17148
17277
  isSending,
17149
17278
  isTyping: showTyping,
17150
17279
  seenAt,
17151
- error,
17280
+ error: error ?? attachError,
17152
17281
  isActive,
17153
17282
  isLeft,
17154
17283
  claimedAs,
17155
17284
  onSignOut: () => void signOut(),
17156
17285
  onClose: handleClose,
17157
- onSend: send,
17286
+ onSend: handleSend,
17158
17287
  onReact: react,
17159
17288
  onAttach: attachPhoto,
17160
17289
  onStartConversation: startConversation,
@@ -17265,7 +17394,7 @@ function Panel({
17265
17394
  className: classNames?.messages
17266
17395
  }
17267
17396
  ),
17268
- error != null && /* @__PURE__ */ jsx("div", { className: "border-t border-red-200 bg-red-50 px-4 py-2 text-xs text-red-600", children: "Something went wrong. Please try again." }),
17397
+ error != null && /* @__PURE__ */ jsx("div", { className: "border-t border-red-200 bg-red-50 px-4 py-2 text-xs text-red-600", children: error.userMessage || "Something went wrong. Please try again." }),
17269
17398
  (isActive || isLoading) && /* @__PURE__ */ jsx(
17270
17399
  ChatInput,
17271
17400
  {
@@ -17475,11 +17604,13 @@ function MessageList({
17475
17604
  ]
17476
17605
  }
17477
17606
  ),
17478
- msg.attachments.length > 0 && /* @__PURE__ */ jsx("div", { className: cn("flex flex-wrap gap-1.5", msg.content && "mb-1.5"), children: msg.attachments.map(
17479
- (attachment, index) => attachment.mime_type?.startsWith("image/") ? /* @__PURE__ */ jsx("a", { href: attachment.url, target: "_blank", rel: "noreferrer", children: /* @__PURE__ */ jsx(
17607
+ msg.attachments.length > 0 && /* @__PURE__ */ jsx("div", { className: cn("flex flex-wrap gap-1.5", msg.content && "mb-1.5"), children: msg.attachments.map((attachment, index) => {
17608
+ const url = safeAttachmentUrl(attachment.url);
17609
+ if (!url) return null;
17610
+ return attachment.mime_type?.startsWith("image/") ? /* @__PURE__ */ jsx("a", { href: url, target: "_blank", rel: "noreferrer", children: /* @__PURE__ */ jsx(
17480
17611
  "img",
17481
17612
  {
17482
- src: attachment.url,
17613
+ src: url,
17483
17614
  alt: attachment.filename ?? "Photo",
17484
17615
  loading: "lazy",
17485
17616
  className: "max-h-48 max-w-full rounded-lg object-cover"
@@ -17487,15 +17618,15 @@ function MessageList({
17487
17618
  ) }, index) : /* @__PURE__ */ jsx(
17488
17619
  "a",
17489
17620
  {
17490
- href: attachment.url,
17621
+ href: url,
17491
17622
  target: "_blank",
17492
17623
  rel: "noreferrer",
17493
17624
  className: "truncate text-xs underline",
17494
17625
  children: attachment.filename ?? "Attachment"
17495
17626
  },
17496
17627
  index
17497
- )
17498
- ) }),
17628
+ );
17629
+ }) }),
17499
17630
  isCustomer ? msg.content && /* @__PURE__ */ jsx("div", { className: "whitespace-pre-wrap", children: msg.content }) : /* @__PURE__ */ jsx(
17500
17631
  ChatMarkdown,
17501
17632
  {
@@ -19576,4 +19707,4 @@ async function genUIFingerprint(manifest) {
19576
19707
  return Array.from(new Uint8Array(digest)).map((byte) => byte.toString(16).padStart(2, "0")).join("").slice(0, 16);
19577
19708
  }
19578
19709
 
19579
- export { AccommodationCard, AccountContent, AccountDashboardPage, AccountHero, AccountIdentityStrip, AccountLineItem, AccountLineItems, AccountNav, AccountOrderDetailPage, AccountOrderView, AccountOrdersPage, AccountShell, AccountSidebar, AccountSignedOutPrompt, AccountSubscriptionDetailPage, AccountSubscriptionsPage, Ad, AdProvider, AddOnSelector, AddressAutocomplete, AddressElement, AuthElement, AvailabilityBadge, BackLink, BillingPlanSelector, BookingCard, BookingList, BookingPage, BookingSummary, BookingsPage, BoxIcon24, BundleProductCard, BundleProductLayout, BundleSelector, Button, CIMPLIFY_GENUI_REGISTRY, CardImage, CardShell, CardVariant, CartDrawer, CartDrawerProvider, CartPage, CartSummary, CartTemplate, CatalogueCollectionLayout, CataloguePage, CatalogueTemplate, CategoryFilter, CategoryGrid, ChatMarkdown, ChatWidget, CheckIcon, CheckoutPage, CimplifyCheckout, CimplifyProvider, CimplifySignInButton, CimplifyUserButton, CollectionPage, CollectionTemplate, CompactCartLayout, CompactCatalogueLayout, CompactSearchLayout, CompactServiceCard, CompositeProductCard, CompositeProductLayout, CompositeSelector, ContextCard, ContinuityCard, CurrencySelector, CustomAttributesTable, CustomerInputFields, DashboardIcon, DashboardIcon20, DatePicker, DateSlotPicker, DealBanner, DealsPage, DefaultCartLayout, DefaultCatalogueLayout, DefaultCollectionLayout, DefaultProductLayout, DefaultSearchLayout, DeliveryEstimate, DeliveryTracker, DeliveryTruckIcon, DigitalProductCard, DigitalProductLayout, DiscountInput, ElementsProvider, EmptyState, ErrorState, FeaturedCollectionLayout, FilterTabs, FoodProductCard, FoodProductLayout, GenUIView, HappeningCard, IdentityIcon, IdentityOfframp, InventoryBadge, ItemsCard, LeaseServiceCard, LineItemDetails, LocationPicker, MediaGallery, MetadataStringList, MobileAccountShell, MobileBackButton, MobileMoreButton, MobileTabBar, NextDeliveryCard, OrderDetailHeader, OrderDetailMetaPipe, OrderDetailPage, OrderHistory, OrderHistoryPage, OrderList, OrderRow, OrderSummary, OrderTimeline, OrderTotals, OrdersIcon, OrdersIcon20, OvenIcon, PackageIcon, PaymentElement, Price, PriceRange, ProductCard, ProductCustomizer, ProductGrid, ProductImageGallery, ProductModel3D, ProductPage, ProductSheet, ProductTemplate, PropertiesTable, QuantitySelector, QuickAddButton, RecentlyViewed, RecommendationCarousel, RelatedProductsSection, RentalServiceCard, ResourcePicker, RetailProductCard, RichText, SaleBadge, SalePrice, SaleTeaser, ScheduleServiceCard, SearchInput, SearchPage, SearchTemplate, Section, SectionMore, ServiceProductLayout, SessionMessageBanner, SignOutIcon, Skeleton, SlotPicker, SoldOutOverlay, StaffPicker, StandardServiceCard, Status, StoreNav, StoreVideo, SubscriptionCard, SubscriptionList, SubscriptionRow, SubscriptionsIcon, SubscriptionsIcon20, TagPills, TimePicker, Toast, TwoColumnGrid, VariantSelector, VolumePricing, WelcomeCard, WholesaleProductCard, WholesaleProductLayout, WishlistButton, clearOrdersCache, cn, createPlacesSessionToken, defaultBoundaryKind, genUICatalog, genUIFingerprint, genUIManifest, genUIManifestJson, getBoundaryLabels, isImageAttachment, isTerminalOrderStatus, parse as parseGenUIProgram, partitionMessages, prefetchProduct, prefetchProducts, resolveBoundaryKind, roomToResource, sanitizeRichTextHtml, stripHtmlToText, toAccountLineItem, toAccountLineItems, toAccountOrderView, useActivityState, useAds, useAttributeDefinitions, useAvailableSlots, useBillingPlans, useBookings, useBootstrap, useBundles, useCart, useCartDrawer, useCategories, useChat, useCheckout, useCimplify, useCimplifyClient, useCimplifySession, useCollection, useCollections, useDeals, useDeliveryFee, useDeliveryOptions, useElements, useElementsReady, useFxRate, useGenUIProgram, useLocations, useOptionalCimplify, useOrder, useOrders, useProduct, useProductAvailability, useProductDeals, useProductPrice, useProductSchedules, useProducts, useProductsOnSale, usePropertyFacets, useQuote, useRecommendations, useSearch, useServiceAvailability, useServices, useStoreCredit, useSubscription, useSubscriptions, useTaxonomies, useTaxonomy, useTaxonomyPath, useValidateDiscount, useVariantSelector };
19710
+ export { AccommodationCard, AccountContent, AccountDashboardPage, AccountHero, AccountIdentityStrip, AccountLineItem, AccountLineItems, AccountNav, AccountOrderDetailPage, AccountOrderView, AccountOrdersPage, AccountShell, AccountSidebar, AccountSignedOutPrompt, AccountSubscriptionDetailPage, AccountSubscriptionsPage, Ad, AdProvider, AddOnSelector, AddressAutocomplete, AddressElement, AuthElement, AvailabilityBadge, BackLink, BillingPlanSelector, BookingCard, BookingList, BookingPage, BookingSummary, BookingsPage, BoxIcon24, BundleProductCard, BundleProductLayout, BundleSelector, Button, CIMPLIFY_GENUI_REGISTRY, CardImage, CardShell, CardVariant, CartDrawer, CartDrawerProvider, CartPage, CartSummary, CartTemplate, CatalogueCollectionLayout, CataloguePage, CatalogueTemplate, CategoryFilter, CategoryGrid, ChatMarkdown, ChatWidget, CheckIcon, CheckoutPage, CimplifyCheckout, CimplifyProvider, CimplifySignInButton, CimplifyUserButton, CollectionPage, CollectionTemplate, CompactCartLayout, CompactCatalogueLayout, CompactSearchLayout, CompactServiceCard, CompositeProductCard, CompositeProductLayout, CompositeSelector, ContextCard, ContinuityCard, CurrencySelector, CustomAttributesTable, CustomerInputFields, DashboardIcon, DashboardIcon20, DatePicker, DateSlotPicker, DealBanner, DealsPage, DefaultCartLayout, DefaultCatalogueLayout, DefaultCollectionLayout, DefaultProductLayout, DefaultSearchLayout, DeliveryEstimate, DeliveryTracker, DeliveryTruckIcon, DigitalProductCard, DigitalProductLayout, DiscountInput, ElementsProvider, EmptyState, ErrorState, FeaturedCollectionLayout, FilterTabs, FoodProductCard, FoodProductLayout, GenUIView, HappeningCard, IdentityIcon, IdentityOfframp, InventoryBadge, ItemsCard, LeaseServiceCard, LineItemDetails, LocationPicker, MediaGallery, MetadataStringList, MobileAccountShell, MobileBackButton, MobileMoreButton, MobileTabBar, NextDeliveryCard, OrderDetailHeader, OrderDetailMetaPipe, OrderDetailPage, OrderHistory, OrderHistoryPage, OrderList, OrderRow, OrderSummary, OrderTimeline, OrderTotals, OrdersIcon, OrdersIcon20, OvenIcon, PackageIcon, PaymentElement, Price, PriceRange, ProductCard, ProductCustomizer, ProductGrid, ProductImageGallery, ProductModel3D, ProductPage, ProductSheet, ProductTemplate, PropertiesTable, QuantitySelector, QuickAddButton, RecentlyViewed, RecommendationCarousel, RelatedProductsSection, RentalServiceCard, ResourcePicker, RetailProductCard, RichText, SaleBadge, SalePrice, SaleTeaser, ScheduleServiceCard, SearchInput, SearchPage, SearchTemplate, Section, SectionMore, ServiceProductLayout, SessionMessageBanner, SignOutIcon, Skeleton, SlotPicker, SoldOutOverlay, StaffPicker, StandardServiceCard, Status, StoreNav, StoreVideo, SubscriptionCard, SubscriptionList, SubscriptionRow, SubscriptionsIcon, SubscriptionsIcon20, TagPills, TimePicker, Toast, TwoColumnGrid, VariantSelector, VolumePricing, WelcomeCard, WholesaleProductCard, WholesaleProductLayout, WishlistButton, clearOrdersCache, cn, createPlacesSessionToken, defaultBoundaryKind, genUICatalog, genUIFingerprint, genUIManifest, genUIManifestJson, getBoundaryLabels, isImageAttachment, isTerminalOrderStatus, parse as parseGenUIProgram, partitionMessages, prefetchProduct, prefetchProducts, resolveBoundaryKind, roomToResource, safeAttachmentUrl, sanitizeRichTextHtml, stripHtmlToText, toAccountLineItem, toAccountLineItems, toAccountOrderView, useActivityState, useAds, useAttributeDefinitions, useAvailableSlots, useBillingPlans, useBookings, useBootstrap, useBundles, useCart, useCartDrawer, useCategories, useChat, useCheckout, useCimplify, useCimplifyClient, useCimplifySession, useCollection, useCollections, useDeals, useDeliveryFee, useDeliveryOptions, useElements, useElementsReady, useFxRate, useGenUIProgram, useLocations, useOptionalCimplify, useOrder, useOrders, useProduct, useProductAvailability, useProductDeals, useProductPrice, useProductSchedules, useProducts, useProductsOnSale, usePropertyFacets, useQuote, useRecommendations, useSearch, useServiceAvailability, useServices, useStoreCredit, useSubscription, useSubscriptions, useTaxonomies, useTaxonomy, useTaxonomyPath, useValidateDiscount, useVariantSelector };
@@ -1,5 +1,5 @@
1
1
  import { Hono } from 'hono';
2
- import { b3 as ProductInputField } from './product-bZ8G5Z8D.mjs';
2
+ import { b3 as ProductInputField } from './product-O8-wcHSe.mjs';
3
3
 
4
4
  interface Clock {
5
5
  now(): Date;
@@ -952,6 +952,10 @@ interface ActivityService {
952
952
 
953
953
  interface SupportService {
954
954
  openConversation(businessId: string, customerId?: string): MockConversation;
955
+ peekConversation(businessId: string, customerId?: string): {
956
+ conversation: MockConversation | null;
957
+ messages: MockChatMessage[];
958
+ };
955
959
  sendMessage(conversationId: string, body: {
956
960
  content: string;
957
961
  content_type?: string;
@@ -1,5 +1,5 @@
1
1
  import { Hono } from 'hono';
2
- import { b3 as ProductInputField } from './product-bZ8G5Z8D.js';
2
+ import { b3 as ProductInputField } from './product-O8-wcHSe.js';
3
3
 
4
4
  interface Clock {
5
5
  now(): Date;
@@ -952,6 +952,10 @@ interface ActivityService {
952
952
 
953
953
  interface SupportService {
954
954
  openConversation(businessId: string, customerId?: string): MockConversation;
955
+ peekConversation(businessId: string, customerId?: string): {
956
+ conversation: MockConversation | null;
957
+ messages: MockChatMessage[];
958
+ };
955
959
  sendMessage(conversationId: string, body: {
956
960
  content: string;
957
961
  content_type?: string;
package/dist/server.d.mts CHANGED
@@ -1,8 +1,8 @@
1
- import { af as CimplifyClient } from './client-BQbSKlHS.mjs';
2
- export { J as CacheOptions, cC as ReadRequestOptions, cZ as Result } from './client-BQbSKlHS.mjs';
3
- export { S as Category, V as CimplifyError, W as Collection, aZ as Product, bb as ProductWithDetails } from './product-bZ8G5Z8D.mjs';
1
+ import { af as CimplifyClient } from './client-BTL9d_nN.mjs';
2
+ export { J as CacheOptions, cC as ReadRequestOptions, cZ as Result } from './client-BTL9d_nN.mjs';
3
+ export { S as Category, V as CimplifyError, W as Collection, aZ as Product, bb as ProductWithDetails } from './product-O8-wcHSe.mjs';
4
4
  import { JWTVerifyResult } from 'jose';
5
- import './payment-BFtLqiG2.mjs';
5
+ import './payment-pKPpaORI.mjs';
6
6
 
7
7
  interface ServerClientOptions {
8
8
  /**
package/dist/server.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { af as CimplifyClient } from './client-CeW3acve.js';
2
- export { J as CacheOptions, cC as ReadRequestOptions, cZ as Result } from './client-CeW3acve.js';
3
- export { S as Category, V as CimplifyError, W as Collection, aZ as Product, bb as ProductWithDetails } from './product-bZ8G5Z8D.js';
1
+ import { af as CimplifyClient } from './client-BX30FAWZ.js';
2
+ export { J as CacheOptions, cC as ReadRequestOptions, cZ as Result } from './client-BX30FAWZ.js';
3
+ export { S as Category, V as CimplifyError, W as Collection, aZ as Product, bb as ProductWithDetails } from './product-O8-wcHSe.js';
4
4
  import { JWTVerifyResult } from 'jose';
5
- import './payment-Cq8FT1B6.js';
5
+ import './payment-By0JidTe.js';
6
6
 
7
7
  interface ServerClientOptions {
8
8
  /**
package/dist/server.js CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkDCRN67NO_js = require('./chunk-DCRN67NO.js');
4
- var chunkIVJEUGWF_js = require('./chunk-IVJEUGWF.js');
3
+ var chunkQLGZIBRO_js = require('./chunk-QLGZIBRO.js');
4
+ var chunkVEOAMBEX_js = require('./chunk-VEOAMBEX.js');
5
5
  require('./chunk-PTPOQVXS.js');
6
6
  var chunkAETVRBKI_js = require('./chunk-AETVRBKI.js');
7
7
  require('./chunk-OWW5GUSB.js');
@@ -26,7 +26,7 @@ function readEnv(...keys) {
26
26
  var getServerClient = react.cache((opts = {}) => {
27
27
  const baseUrl = opts.apiUrl ?? readEnv("CIMPLIFY_API_URL", "NEXT_PUBLIC_CIMPLIFY_API_URL") ?? defaultBaseUrl();
28
28
  const publicKey = opts.secretKey ?? readEnv("CIMPLIFY_SECRET_KEY", "NEXT_PUBLIC_CIMPLIFY_PUBLIC_KEY") ?? "mock-dev";
29
- const client = chunkDCRN67NO_js.createCimplifyClient({
29
+ const client = chunkQLGZIBRO_js.createCimplifyClient({
30
30
  baseUrl,
31
31
  publicKey,
32
32
  suppressPublicKeyWarning: true
@@ -250,7 +250,7 @@ var QUERY_AUTH_ERROR = "cimplify_auth_error";
250
250
  var discoveryCache = /* @__PURE__ */ new Map();
251
251
  var jwksCache = /* @__PURE__ */ new Map();
252
252
  function issuerBase(cfg) {
253
- return (cfg.issuer ?? cfg.authUrl ?? chunkIVJEUGWF_js.DEFAULT_ISSUER).replace(/\/$/, "");
253
+ return (cfg.issuer ?? cfg.authUrl ?? chunkVEOAMBEX_js.DEFAULT_ISSUER).replace(/\/$/, "");
254
254
  }
255
255
  function cookieName(cfg) {
256
256
  return cfg.cookieName ?? SESSION_COOKIE;
@@ -465,12 +465,12 @@ async function handleOidcCallback(req, opts) {
465
465
  }
466
466
  function readPkceCookie(cookieHeader) {
467
467
  if (!cookieHeader) return null;
468
- const match = cookieHeader.split(/;\s*/).find((p) => p.startsWith(`${chunkIVJEUGWF_js.PKCE_COOKIE}=`));
468
+ const match = cookieHeader.split(/;\s*/).find((p) => p.startsWith(`${chunkVEOAMBEX_js.PKCE_COOKIE}=`));
469
469
  if (!match) return null;
470
- return chunkIVJEUGWF_js.decodePkceState(match.slice(chunkIVJEUGWF_js.PKCE_COOKIE.length + 1));
470
+ return chunkVEOAMBEX_js.decodePkceState(match.slice(chunkVEOAMBEX_js.PKCE_COOKIE.length + 1));
471
471
  }
472
472
  function buildPkceClearCookie() {
473
- return `${chunkIVJEUGWF_js.PKCE_COOKIE}=; Path=${chunkIVJEUGWF_js.PKCE_COOKIE_PATH}; Max-Age=0; Secure; SameSite=Lax`;
473
+ return `${chunkVEOAMBEX_js.PKCE_COOKIE}=; Path=${chunkVEOAMBEX_js.PKCE_COOKIE_PATH}; Max-Age=0; Secure; SameSite=Lax`;
474
474
  }
475
475
  function safeReturnPath(returnTo, fallback) {
476
476
  if (returnTo && returnTo.startsWith("/") && !returnTo.startsWith("//")) return returnTo;
package/dist/server.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { createCimplifyClient } from './chunk-3XD2FVP4.mjs';
2
- import { PKCE_COOKIE, decodePkceState, PKCE_COOKIE_PATH, DEFAULT_ISSUER } from './chunk-T7LDBZZZ.mjs';
1
+ import { createCimplifyClient } from './chunk-FKARGZK3.mjs';
2
+ import { PKCE_COOKIE, decodePkceState, PKCE_COOKIE_PATH, DEFAULT_ISSUER } from './chunk-VUSHG3HA.mjs';
3
3
  import './chunk-KFLGQGMC.mjs';
4
4
  export { CimplifyError } from './chunk-K5EN2W2Q.mjs';
5
5
  import './chunk-3G6RQLXK.mjs';
@@ -1,6 +1,6 @@
1
- import { A as AppHandle, C as CreateAppOptions } from '../server-D-iK-bNt.mjs';
1
+ import { A as AppHandle, C as CreateAppOptions } from '../server-BN9ZCAKT.mjs';
2
2
  import 'hono';
3
- import '../product-bZ8G5Z8D.mjs';
3
+ import '../product-O8-wcHSe.mjs';
4
4
 
5
5
  interface MswHandlerSetup {
6
6
  handlers: unknown[];
@@ -1,6 +1,6 @@
1
- import { A as AppHandle, C as CreateAppOptions } from '../server-DwsY9hlX.js';
1
+ import { A as AppHandle, C as CreateAppOptions } from '../server-DDGbfW_S.js';
2
2
  import 'hono';
3
- import '../product-bZ8G5Z8D.js';
3
+ import '../product-O8-wcHSe.js';
4
4
 
5
5
  interface MswHandlerSetup {
6
6
  handlers: unknown[];