@burdenoff/website-sdk 2026.922.3 → 2026.922.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/components/explore.d.mts +70 -2
- package/dist/components/explore.d.ts +70 -2
- package/dist/components/explore.js +492 -8
- package/dist/components/explore.js.map +1 -1
- package/dist/components/explore.mjs +490 -10
- package/dist/components/explore.mjs.map +1 -1
- package/dist/{explore-types-CPF1QoMn.d.mts → explore-types-DvQPiL1t.d.mts} +58 -2
- package/dist/{explore-types-CPF1QoMn.d.ts → explore-types-DvQPiL1t.d.ts} +58 -2
- package/dist/hooks/index.d.mts +2 -2
- package/dist/hooks/index.d.ts +2 -2
- package/dist/hooks/index.js +61 -8
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +61 -8
- package/dist/hooks/index.mjs.map +1 -1
- package/dist/index.d.mts +36 -2
- package/dist/index.d.ts +36 -2
- package/dist/index.js +489 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +490 -10
- package/dist/index.mjs.map +1 -1
- package/dist/{use-explore-chat--CxNtkrJ.d.ts → use-explore-chat-CNEdKBc1.d.ts} +1 -1
- package/dist/{use-explore-chat-C6Y8JQMj.d.mts → use-explore-chat-Dgm-jf96.d.mts} +1 -1
- package/package.json +1 -1
|
@@ -142,6 +142,27 @@ interface ExploreLimits {
|
|
|
142
142
|
messagesPerDay: number;
|
|
143
143
|
historyTurns: number;
|
|
144
144
|
}
|
|
145
|
+
/**
|
|
146
|
+
* `type ExploreConceptHighlight` — one published concept illustration, offered
|
|
147
|
+
* as a way into the conversation before the visitor has typed anything.
|
|
148
|
+
*
|
|
149
|
+
* Every field is non-null on the wire: a highlight with no picture or no
|
|
150
|
+
* destination is not a highlight, so the server drops it rather than sending a
|
|
151
|
+
* half-built one. `product` is the slug, `productName` the display casing the
|
|
152
|
+
* product's own pages use.
|
|
153
|
+
*
|
|
154
|
+
* The pictures are the published concept mockups — illustrations of an idea,
|
|
155
|
+
* not screenshots of shipping software — which is why every surface that shows
|
|
156
|
+
* one also labels it (`ExploreStrings.conceptIllustration`).
|
|
157
|
+
*/
|
|
158
|
+
interface ExploreConceptHighlight {
|
|
159
|
+
product: string;
|
|
160
|
+
productName: string;
|
|
161
|
+
title: string;
|
|
162
|
+
url: string;
|
|
163
|
+
imageUrl: string;
|
|
164
|
+
alt: string;
|
|
165
|
+
}
|
|
145
166
|
/**
|
|
146
167
|
* `type ExploreCatalog` — everything the page needs before the first message.
|
|
147
168
|
*
|
|
@@ -157,6 +178,18 @@ interface ExploreCatalog {
|
|
|
157
178
|
limits: ExploreLimits;
|
|
158
179
|
captchaRequired: boolean;
|
|
159
180
|
recaptchaSiteKey?: string | null;
|
|
181
|
+
/**
|
|
182
|
+
* At most 8, the site's own product first. Non-null and non-nullable per the
|
|
183
|
+
* contract, so a gateway that knows the field always sends an array.
|
|
184
|
+
*
|
|
185
|
+
* A gateway that does NOT know it yet does not answer without it — it refuses
|
|
186
|
+
* the whole document (`GRAPHQL_VALIDATION_FAILED`), which is why the hook
|
|
187
|
+
* retries with `EXPLORE_CATALOG_QUERY_WITHOUT_HIGHLIGHTS` instead of falling
|
|
188
|
+
* back to the built-in catalog. That retry is the one response that reaches
|
|
189
|
+
* `normalizeCatalog` with this field absent, and the hardening there is what
|
|
190
|
+
* keeps `catalog.conceptHighlights.filter(...)` from throwing in render.
|
|
191
|
+
*/
|
|
192
|
+
conceptHighlights: ExploreConceptHighlight[];
|
|
160
193
|
}
|
|
161
194
|
/** `input SendExploreMessageInput`. */
|
|
162
195
|
interface SendExploreMessageInput {
|
|
@@ -202,7 +235,30 @@ interface SendExploreMessageResult {
|
|
|
202
235
|
remainingToday?: number | null;
|
|
203
236
|
}
|
|
204
237
|
/** Loaded once per page. Safe to serve from the SDK's 5-minute query cache. */
|
|
205
|
-
declare const EXPLORE_CATALOG_QUERY
|
|
238
|
+
declare const EXPLORE_CATALOG_QUERY: string;
|
|
239
|
+
/**
|
|
240
|
+
* The same catalog WITHOUT `conceptHighlights`, for a gateway whose supergraph
|
|
241
|
+
* predates the field.
|
|
242
|
+
*
|
|
243
|
+
* This is not belt-and-braces. GraphQL validation is all-or-nothing: a gateway
|
|
244
|
+
* that does not know the field rejects the ENTIRE document and returns no
|
|
245
|
+
* `data` at all, so selecting `conceptHighlights` against an older supergraph
|
|
246
|
+
* costs the whole catalog — `enabled`, `captchaRequired`, `recaptchaSiteKey`,
|
|
247
|
+
* the welcome copy and `limits` included — and not merely the strip. Measured
|
|
248
|
+
* against production:
|
|
249
|
+
*
|
|
250
|
+
* {"errors":[{"message":"Cannot query field \\"conceptHighlights\\" on type
|
|
251
|
+
* \\"ExploreCatalog\\".","extensions":{"code":"GRAPHQL_VALIDATION_FAILED"}}]}
|
|
252
|
+
*
|
|
253
|
+
* That window is guaranteed even with perfect deploy ordering, because the prod
|
|
254
|
+
* gateway's CDN edge serves a stale supergraph for ~30-40 minutes after the
|
|
255
|
+
* subgraph publishes. `useExploreChat` therefore retries with this document
|
|
256
|
+
* (see `catalogRejectedTheHighlightField`) rather than dropping to the built-in
|
|
257
|
+
* fallback, whose hardcoded `enabled: true` would ignore the server-side kill
|
|
258
|
+
* switch and whose `captchaRequired: false` would let every send be rejected
|
|
259
|
+
* server-side while the composer looked fine.
|
|
260
|
+
*/
|
|
261
|
+
declare const EXPLORE_CATALOG_QUERY_WITHOUT_HIGHLIGHTS: string;
|
|
206
262
|
/**
|
|
207
263
|
* The poll. MUST be issued with `client.query(..., { cache: false })` — the
|
|
208
264
|
* default 5-minute cache would return the first PENDING snapshot forever and
|
|
@@ -221,4 +277,4 @@ interface SendExploreMessageMutationData {
|
|
|
221
277
|
sendExploreMessage: SendExploreMessageResult;
|
|
222
278
|
}
|
|
223
279
|
|
|
224
|
-
export { type ExploreProduct as E, SEND_EXPLORE_MESSAGE_MUTATION as S, type
|
|
280
|
+
export { type ExploreProduct as E, SEND_EXPLORE_MESSAGE_MUTATION as S, type ExploreReference as a, type ExploreLimits as b, type ExploreCatalog as c, type ExploreMessage as d, type ExploreFeedbackRating as e, type ExploreFeedbackReason as f, EXPLORE_CATALOG_QUERY as g, EXPLORE_CATALOG_QUERY_WITHOUT_HIGHLIGHTS as h, EXPLORE_MESSAGE_QUERY as i, type ExploreCatalogQueryData as j, type ExploreConceptHighlight as k, type ExploreConversation as l, type ExploreCtaKind as m, type ExploreCtaLink as n, type ExploreErrorCode as o, type ExploreMessageQueryData as p, type ExploreMessageRole as q, type ExploreMessageStatus as r, type SendExploreMessageInput as s, type SendExploreMessageMutationData as t, type SendExploreMessageResult as u };
|
|
@@ -142,6 +142,27 @@ interface ExploreLimits {
|
|
|
142
142
|
messagesPerDay: number;
|
|
143
143
|
historyTurns: number;
|
|
144
144
|
}
|
|
145
|
+
/**
|
|
146
|
+
* `type ExploreConceptHighlight` — one published concept illustration, offered
|
|
147
|
+
* as a way into the conversation before the visitor has typed anything.
|
|
148
|
+
*
|
|
149
|
+
* Every field is non-null on the wire: a highlight with no picture or no
|
|
150
|
+
* destination is not a highlight, so the server drops it rather than sending a
|
|
151
|
+
* half-built one. `product` is the slug, `productName` the display casing the
|
|
152
|
+
* product's own pages use.
|
|
153
|
+
*
|
|
154
|
+
* The pictures are the published concept mockups — illustrations of an idea,
|
|
155
|
+
* not screenshots of shipping software — which is why every surface that shows
|
|
156
|
+
* one also labels it (`ExploreStrings.conceptIllustration`).
|
|
157
|
+
*/
|
|
158
|
+
interface ExploreConceptHighlight {
|
|
159
|
+
product: string;
|
|
160
|
+
productName: string;
|
|
161
|
+
title: string;
|
|
162
|
+
url: string;
|
|
163
|
+
imageUrl: string;
|
|
164
|
+
alt: string;
|
|
165
|
+
}
|
|
145
166
|
/**
|
|
146
167
|
* `type ExploreCatalog` — everything the page needs before the first message.
|
|
147
168
|
*
|
|
@@ -157,6 +178,18 @@ interface ExploreCatalog {
|
|
|
157
178
|
limits: ExploreLimits;
|
|
158
179
|
captchaRequired: boolean;
|
|
159
180
|
recaptchaSiteKey?: string | null;
|
|
181
|
+
/**
|
|
182
|
+
* At most 8, the site's own product first. Non-null and non-nullable per the
|
|
183
|
+
* contract, so a gateway that knows the field always sends an array.
|
|
184
|
+
*
|
|
185
|
+
* A gateway that does NOT know it yet does not answer without it — it refuses
|
|
186
|
+
* the whole document (`GRAPHQL_VALIDATION_FAILED`), which is why the hook
|
|
187
|
+
* retries with `EXPLORE_CATALOG_QUERY_WITHOUT_HIGHLIGHTS` instead of falling
|
|
188
|
+
* back to the built-in catalog. That retry is the one response that reaches
|
|
189
|
+
* `normalizeCatalog` with this field absent, and the hardening there is what
|
|
190
|
+
* keeps `catalog.conceptHighlights.filter(...)` from throwing in render.
|
|
191
|
+
*/
|
|
192
|
+
conceptHighlights: ExploreConceptHighlight[];
|
|
160
193
|
}
|
|
161
194
|
/** `input SendExploreMessageInput`. */
|
|
162
195
|
interface SendExploreMessageInput {
|
|
@@ -202,7 +235,30 @@ interface SendExploreMessageResult {
|
|
|
202
235
|
remainingToday?: number | null;
|
|
203
236
|
}
|
|
204
237
|
/** Loaded once per page. Safe to serve from the SDK's 5-minute query cache. */
|
|
205
|
-
declare const EXPLORE_CATALOG_QUERY
|
|
238
|
+
declare const EXPLORE_CATALOG_QUERY: string;
|
|
239
|
+
/**
|
|
240
|
+
* The same catalog WITHOUT `conceptHighlights`, for a gateway whose supergraph
|
|
241
|
+
* predates the field.
|
|
242
|
+
*
|
|
243
|
+
* This is not belt-and-braces. GraphQL validation is all-or-nothing: a gateway
|
|
244
|
+
* that does not know the field rejects the ENTIRE document and returns no
|
|
245
|
+
* `data` at all, so selecting `conceptHighlights` against an older supergraph
|
|
246
|
+
* costs the whole catalog — `enabled`, `captchaRequired`, `recaptchaSiteKey`,
|
|
247
|
+
* the welcome copy and `limits` included — and not merely the strip. Measured
|
|
248
|
+
* against production:
|
|
249
|
+
*
|
|
250
|
+
* {"errors":[{"message":"Cannot query field \\"conceptHighlights\\" on type
|
|
251
|
+
* \\"ExploreCatalog\\".","extensions":{"code":"GRAPHQL_VALIDATION_FAILED"}}]}
|
|
252
|
+
*
|
|
253
|
+
* That window is guaranteed even with perfect deploy ordering, because the prod
|
|
254
|
+
* gateway's CDN edge serves a stale supergraph for ~30-40 minutes after the
|
|
255
|
+
* subgraph publishes. `useExploreChat` therefore retries with this document
|
|
256
|
+
* (see `catalogRejectedTheHighlightField`) rather than dropping to the built-in
|
|
257
|
+
* fallback, whose hardcoded `enabled: true` would ignore the server-side kill
|
|
258
|
+
* switch and whose `captchaRequired: false` would let every send be rejected
|
|
259
|
+
* server-side while the composer looked fine.
|
|
260
|
+
*/
|
|
261
|
+
declare const EXPLORE_CATALOG_QUERY_WITHOUT_HIGHLIGHTS: string;
|
|
206
262
|
/**
|
|
207
263
|
* The poll. MUST be issued with `client.query(..., { cache: false })` — the
|
|
208
264
|
* default 5-minute cache would return the first PENDING snapshot forever and
|
|
@@ -221,4 +277,4 @@ interface SendExploreMessageMutationData {
|
|
|
221
277
|
sendExploreMessage: SendExploreMessageResult;
|
|
222
278
|
}
|
|
223
279
|
|
|
224
|
-
export { type ExploreProduct as E, SEND_EXPLORE_MESSAGE_MUTATION as S, type
|
|
280
|
+
export { type ExploreProduct as E, SEND_EXPLORE_MESSAGE_MUTATION as S, type ExploreReference as a, type ExploreLimits as b, type ExploreCatalog as c, type ExploreMessage as d, type ExploreFeedbackRating as e, type ExploreFeedbackReason as f, EXPLORE_CATALOG_QUERY as g, EXPLORE_CATALOG_QUERY_WITHOUT_HIGHLIGHTS as h, EXPLORE_MESSAGE_QUERY as i, type ExploreCatalogQueryData as j, type ExploreConceptHighlight as k, type ExploreConversation as l, type ExploreCtaKind as m, type ExploreCtaLink as n, type ExploreErrorCode as o, type ExploreMessageQueryData as p, type ExploreMessageRole as q, type ExploreMessageStatus as r, type SendExploreMessageInput as s, type SendExploreMessageMutationData as t, type SendExploreMessageResult as u };
|
package/dist/hooks/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { D as DEFAULT_EXPLORE_EXAMPLE_PROMPTS, E as ExploreChatError, a as ExploreChatErrorKind, b as ExploreChatPhase, F as FALLBACK_EXPLORE_LIMITS, U as UseExploreChatOptions, c as UseExploreChatResult, d as classifyExploreError, u as useExploreChat } from '../use-explore-chat-
|
|
2
|
-
import '../explore-types-
|
|
1
|
+
export { D as DEFAULT_EXPLORE_EXAMPLE_PROMPTS, E as ExploreChatError, a as ExploreChatErrorKind, b as ExploreChatPhase, F as FALLBACK_EXPLORE_LIMITS, U as UseExploreChatOptions, c as UseExploreChatResult, d as classifyExploreError, u as useExploreChat } from '../use-explore-chat-Dgm-jf96.mjs';
|
|
2
|
+
import '../explore-types-DvQPiL1t.mjs';
|
|
3
3
|
|
|
4
4
|
interface UseSpeechInputOptions {
|
|
5
5
|
/** Receives settled text as it is recognised. Append it to the draft. */
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { D as DEFAULT_EXPLORE_EXAMPLE_PROMPTS, E as ExploreChatError, a as ExploreChatErrorKind, b as ExploreChatPhase, F as FALLBACK_EXPLORE_LIMITS, U as UseExploreChatOptions, c as UseExploreChatResult, d as classifyExploreError, u as useExploreChat } from '../use-explore-chat
|
|
2
|
-
import '../explore-types-
|
|
1
|
+
export { D as DEFAULT_EXPLORE_EXAMPLE_PROMPTS, E as ExploreChatError, a as ExploreChatErrorKind, b as ExploreChatPhase, F as FALLBACK_EXPLORE_LIMITS, U as UseExploreChatOptions, c as UseExploreChatResult, d as classifyExploreError, u as useExploreChat } from '../use-explore-chat-CNEdKBc1.js';
|
|
2
|
+
import '../explore-types-DvQPiL1t.js';
|
|
3
3
|
|
|
4
4
|
interface UseSpeechInputOptions {
|
|
5
5
|
/** Receives settled text as it is recognised. Append it to the draft. */
|
package/dist/hooks/index.js
CHANGED
|
@@ -277,11 +277,9 @@ var EXPLORE_OWN_MESSAGE_FIELDS = (
|
|
|
277
277
|
}
|
|
278
278
|
`
|
|
279
279
|
);
|
|
280
|
-
var
|
|
280
|
+
var EXPLORE_CATALOG_ESTABLISHED_FIELDS = (
|
|
281
281
|
/* GraphQL */
|
|
282
282
|
`
|
|
283
|
-
query ExploreCatalog($productSlug: String) {
|
|
284
|
-
exploreCatalog(productSlug: $productSlug) {
|
|
285
283
|
enabled
|
|
286
284
|
products {
|
|
287
285
|
slug
|
|
@@ -299,11 +297,35 @@ var EXPLORE_CATALOG_QUERY = (
|
|
|
299
297
|
historyTurns
|
|
300
298
|
}
|
|
301
299
|
captchaRequired
|
|
302
|
-
recaptchaSiteKey
|
|
300
|
+
recaptchaSiteKey`
|
|
301
|
+
);
|
|
302
|
+
var EXPLORE_CATALOG_HIGHLIGHT_FIELD = (
|
|
303
|
+
/* GraphQL */
|
|
304
|
+
`
|
|
305
|
+
conceptHighlights {
|
|
306
|
+
product
|
|
307
|
+
productName
|
|
308
|
+
title
|
|
309
|
+
url
|
|
310
|
+
imageUrl
|
|
311
|
+
alt
|
|
312
|
+
}`
|
|
313
|
+
);
|
|
314
|
+
function exploreCatalogDocument(extraFields) {
|
|
315
|
+
return (
|
|
316
|
+
/* GraphQL */
|
|
317
|
+
`
|
|
318
|
+
query ExploreCatalog($productSlug: String) {
|
|
319
|
+
exploreCatalog(productSlug: $productSlug) {${EXPLORE_CATALOG_ESTABLISHED_FIELDS}${extraFields}
|
|
303
320
|
}
|
|
304
321
|
}
|
|
305
322
|
`
|
|
323
|
+
);
|
|
324
|
+
}
|
|
325
|
+
var EXPLORE_CATALOG_QUERY = exploreCatalogDocument(
|
|
326
|
+
EXPLORE_CATALOG_HIGHLIGHT_FIELD
|
|
306
327
|
);
|
|
328
|
+
var EXPLORE_CATALOG_QUERY_WITHOUT_HIGHLIGHTS = exploreCatalogDocument("");
|
|
307
329
|
var EXPLORE_MESSAGE_QUERY = (
|
|
308
330
|
/* GraphQL */
|
|
309
331
|
`
|
|
@@ -667,7 +689,12 @@ function buildFallbackCatalog(examplePrompts, welcome) {
|
|
|
667
689
|
welcomeBody: welcome?.body ?? FALLBACK_WELCOME_BODY,
|
|
668
690
|
limits: FALLBACK_EXPLORE_LIMITS,
|
|
669
691
|
captchaRequired: false,
|
|
670
|
-
recaptchaSiteKey: null
|
|
692
|
+
recaptchaSiteKey: null,
|
|
693
|
+
// Empty, and deliberately not synthesised from `ECOSYSTEM_PRODUCTS`: a concept highlight
|
|
694
|
+
// needs a real published illustration URL, and this SDK has no registry of them. An
|
|
695
|
+
// invented path would render 38 broken frames on the one screen every prerender captures.
|
|
696
|
+
// The strip renders nothing at all when the list is empty, which is the honest fallback.
|
|
697
|
+
conceptHighlights: []
|
|
671
698
|
};
|
|
672
699
|
}
|
|
673
700
|
function normalizeCatalog(raw, fallback) {
|
|
@@ -684,9 +711,27 @@ function normalizeCatalog(raw, fallback) {
|
|
|
684
711
|
historyTurns: raw.limits?.historyTurns || fallback.limits.historyTurns
|
|
685
712
|
},
|
|
686
713
|
captchaRequired: raw.captchaRequired === true,
|
|
687
|
-
recaptchaSiteKey: raw.recaptchaSiteKey ?? null
|
|
714
|
+
recaptchaSiteKey: raw.recaptchaSiteKey ?? null,
|
|
715
|
+
// `[ExploreConceptHighlight!]!` on the wire, so a gateway that KNOWS the field always
|
|
716
|
+
// sends an array. The one response that arrives without it is the retry against an older
|
|
717
|
+
// supergraph (`EXPLORE_CATALOG_QUERY_WITHOUT_HIGHLIGHTS`) — that gateway does not answer
|
|
718
|
+
// the full document at all, it refuses it. Either way
|
|
719
|
+
// `catalog.conceptHighlights.filter(...)` on `undefined` would throw inside render,
|
|
720
|
+
// blanking the welcome screen over a decorative strip.
|
|
721
|
+
conceptHighlights: raw.conceptHighlights?.length ? raw.conceptHighlights : fallback.conceptHighlights
|
|
688
722
|
};
|
|
689
723
|
}
|
|
724
|
+
var CATALOG_DOCUMENT_REJECTED_CODES = /* @__PURE__ */ new Set([
|
|
725
|
+
"GRAPHQL_VALIDATION_FAILED",
|
|
726
|
+
"HTTP_400"
|
|
727
|
+
]);
|
|
728
|
+
function catalogRejectedTheHighlightField(res) {
|
|
729
|
+
if (res.data?.exploreCatalog) return false;
|
|
730
|
+
return (res.errors ?? []).some((error) => {
|
|
731
|
+
const code = error.extensions?.code;
|
|
732
|
+
return typeof code === "string" && CATALOG_DOCUMENT_REJECTED_CODES.has(code) || error.message.includes("conceptHighlights");
|
|
733
|
+
});
|
|
734
|
+
}
|
|
690
735
|
var RATE_LIMIT_CODES = /* @__PURE__ */ new Set([
|
|
691
736
|
"RATE_LIMITED",
|
|
692
737
|
"HTTP_429",
|
|
@@ -1026,11 +1071,19 @@ function useExploreChat(options = {}) {
|
|
|
1026
1071
|
react.useEffect(() => {
|
|
1027
1072
|
let cancelled = false;
|
|
1028
1073
|
const load = async () => {
|
|
1029
|
-
const
|
|
1074
|
+
const variables = { productSlug: productSlug ?? null };
|
|
1075
|
+
let res = await client.query(
|
|
1030
1076
|
EXPLORE_CATALOG_QUERY,
|
|
1031
|
-
|
|
1077
|
+
variables
|
|
1032
1078
|
);
|
|
1033
1079
|
if (cancelled || !mountedRef.current) return;
|
|
1080
|
+
if (catalogRejectedTheHighlightField(res)) {
|
|
1081
|
+
res = await client.query(
|
|
1082
|
+
EXPLORE_CATALOG_QUERY_WITHOUT_HIGHLIGHTS,
|
|
1083
|
+
variables
|
|
1084
|
+
);
|
|
1085
|
+
if (cancelled || !mountedRef.current) return;
|
|
1086
|
+
}
|
|
1034
1087
|
const raw = res.data?.exploreCatalog;
|
|
1035
1088
|
if (res.errors?.length || !raw) {
|
|
1036
1089
|
console.warn(
|