@burdenoff/website-sdk 2026.828.7 → 2026.829.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/explore.js +567 -200
- package/dist/components/explore.js.map +1 -1
- package/dist/components/explore.mjs +569 -202
- package/dist/components/explore.mjs.map +1 -1
- package/dist/hooks/index.d.mts +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.js +139 -69
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +139 -69
- package/dist/hooks/index.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +567 -200
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +567 -200
- package/dist/index.mjs.map +1 -1
- package/dist/{use-explore-chat-DhvZhH8f.d.mts → use-explore-chat-8eL7WdLc.d.mts} +16 -2
- package/dist/{use-explore-chat-DhvZhH8f.d.ts → use-explore-chat-8eL7WdLc.d.ts} +16 -2
- package/package.json +1 -1
package/dist/hooks/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
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-
|
|
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-8eL7WdLc.mjs';
|
|
2
2
|
|
|
3
3
|
interface UseSpeechInputOptions {
|
|
4
4
|
/** Receives settled text as it is recognised. Append it to the draft. */
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
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-
|
|
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-8eL7WdLc.js';
|
|
2
2
|
|
|
3
3
|
interface UseSpeechInputOptions {
|
|
4
4
|
/** Receives settled text as it is recognised. Append it to the draft. */
|
package/dist/hooks/index.js
CHANGED
|
@@ -244,6 +244,7 @@ var EXPLORE_MESSAGE_FIELDS = (
|
|
|
244
244
|
description
|
|
245
245
|
product
|
|
246
246
|
imageUrl
|
|
247
|
+
index
|
|
247
248
|
}
|
|
248
249
|
ctas {
|
|
249
250
|
kind
|
|
@@ -251,6 +252,8 @@ var EXPLORE_MESSAGE_FIELDS = (
|
|
|
251
252
|
url
|
|
252
253
|
product
|
|
253
254
|
}
|
|
255
|
+
followUps
|
|
256
|
+
answered
|
|
254
257
|
errorCode
|
|
255
258
|
createdAt
|
|
256
259
|
completedAt
|
|
@@ -316,6 +319,16 @@ var SEND_EXPLORE_MESSAGE_MUTATION = (
|
|
|
316
319
|
}
|
|
317
320
|
`
|
|
318
321
|
);
|
|
322
|
+
var RECORD_EXPLORE_CLICK_MUTATION = (
|
|
323
|
+
/* GraphQL */
|
|
324
|
+
`
|
|
325
|
+
mutation RecordExploreClick($input: RecordExploreClickInput!) {
|
|
326
|
+
recordExploreClick(input: $input) {
|
|
327
|
+
recorded
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
`
|
|
331
|
+
);
|
|
319
332
|
|
|
320
333
|
// src/data/products.ts
|
|
321
334
|
var ECOSYSTEM_PRODUCTS = [
|
|
@@ -1248,6 +1261,20 @@ function useExploreChat(options = {}) {
|
|
|
1248
1261
|
return null;
|
|
1249
1262
|
}, [messages]);
|
|
1250
1263
|
const canSend = (phase === "ready" || phase === "error") && catalog.enabled && turnCount < catalog.limits.maxTurnsPerConversation;
|
|
1264
|
+
const recordClick = react.useCallback(
|
|
1265
|
+
(messageId, kind, url) => {
|
|
1266
|
+
const token = conversationTokenRef.current;
|
|
1267
|
+
if (!token) return;
|
|
1268
|
+
try {
|
|
1269
|
+
void client.mutate(RECORD_EXPLORE_CLICK_MUTATION, {
|
|
1270
|
+
input: { conversationToken: token, messageId, kind, url }
|
|
1271
|
+
}).catch(() => {
|
|
1272
|
+
});
|
|
1273
|
+
} catch {
|
|
1274
|
+
}
|
|
1275
|
+
},
|
|
1276
|
+
[client]
|
|
1277
|
+
);
|
|
1251
1278
|
return {
|
|
1252
1279
|
phase,
|
|
1253
1280
|
catalog,
|
|
@@ -1265,7 +1292,8 @@ function useExploreChat(options = {}) {
|
|
|
1265
1292
|
history: archive,
|
|
1266
1293
|
openConversation,
|
|
1267
1294
|
deleteConversation,
|
|
1268
|
-
clearHistory
|
|
1295
|
+
clearHistory,
|
|
1296
|
+
recordClick
|
|
1269
1297
|
};
|
|
1270
1298
|
}
|
|
1271
1299
|
var optimisticCounter = 0;
|
|
@@ -1278,21 +1306,37 @@ function getRecognitionCtor() {
|
|
|
1278
1306
|
const w = window;
|
|
1279
1307
|
return w.SpeechRecognition ?? w.webkitSpeechRecognition ?? null;
|
|
1280
1308
|
}
|
|
1309
|
+
function isTouchDevice() {
|
|
1310
|
+
if (typeof window === "undefined" || !window.matchMedia) return false;
|
|
1311
|
+
try {
|
|
1312
|
+
return window.matchMedia("(pointer: coarse)").matches;
|
|
1313
|
+
} catch {
|
|
1314
|
+
return false;
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1281
1317
|
var MIC_DENIED_MESSAGE = "Microphone access was blocked. Allow it in your browser's site settings to dictate.";
|
|
1318
|
+
var MIC_UNAVAILABLE_MESSAGE = "Dictation isn't available in this browser. You can type instead.";
|
|
1319
|
+
var RELEASE_SETTLE_MS = 250;
|
|
1320
|
+
var RETRY_DELAY_MS = 350;
|
|
1321
|
+
var sleep = (ms) => new Promise((resolve) => {
|
|
1322
|
+
setTimeout(resolve, ms);
|
|
1323
|
+
});
|
|
1282
1324
|
async function ensureMicrophoneAccess() {
|
|
1283
1325
|
const media = typeof navigator === "undefined" ? void 0 : navigator.mediaDevices;
|
|
1284
|
-
if (!media?.getUserMedia)
|
|
1326
|
+
if (!media?.getUserMedia)
|
|
1327
|
+
return { ok: true, confirmed: false, primed: false };
|
|
1285
1328
|
try {
|
|
1286
1329
|
const status = await navigator.permissions?.query({
|
|
1287
1330
|
name: "microphone"
|
|
1288
1331
|
});
|
|
1289
|
-
if (status?.state === "granted")
|
|
1332
|
+
if (status?.state === "granted")
|
|
1333
|
+
return { ok: true, confirmed: true, primed: false };
|
|
1290
1334
|
} catch {
|
|
1291
1335
|
}
|
|
1292
1336
|
try {
|
|
1293
1337
|
const stream = await media.getUserMedia({ audio: true });
|
|
1294
1338
|
for (const track of stream.getTracks()) track.stop();
|
|
1295
|
-
return { ok: true, confirmed: true };
|
|
1339
|
+
return { ok: true, confirmed: true, primed: true };
|
|
1296
1340
|
} catch (error) {
|
|
1297
1341
|
const name = typeof error === "object" && error !== null && "name" in error ? String(error.name) : "";
|
|
1298
1342
|
if (name === "NotAllowedError" || name === "SecurityError") {
|
|
@@ -1336,19 +1380,17 @@ function useSpeechInput({
|
|
|
1336
1380
|
const recognitionRef = react.useRef(null);
|
|
1337
1381
|
const startTokenRef = react.useRef(0);
|
|
1338
1382
|
const micConfirmedRef = react.useRef(false);
|
|
1339
|
-
const
|
|
1340
|
-
const
|
|
1341
|
-
(Ctor, token) => {
|
|
1342
|
-
beginRecognitionRef.current?.(Ctor, token);
|
|
1343
|
-
},
|
|
1344
|
-
[]
|
|
1345
|
-
);
|
|
1383
|
+
const wantsListeningRef = react.useRef(false);
|
|
1384
|
+
const retriedRef = react.useRef(false);
|
|
1346
1385
|
const finalRef = react.useRef(onFinalTranscript);
|
|
1347
1386
|
const errorRef = react.useRef(onError);
|
|
1348
1387
|
finalRef.current = onFinalTranscript;
|
|
1349
1388
|
errorRef.current = onError;
|
|
1389
|
+
const langRef = react.useRef(lang);
|
|
1390
|
+
langRef.current = lang;
|
|
1350
1391
|
const stop = react.useCallback(() => {
|
|
1351
1392
|
startTokenRef.current += 1;
|
|
1393
|
+
wantsListeningRef.current = false;
|
|
1352
1394
|
setListening(false);
|
|
1353
1395
|
setInterim("");
|
|
1354
1396
|
const recognition = recognitionRef.current;
|
|
@@ -1357,83 +1399,111 @@ function useSpeechInput({
|
|
|
1357
1399
|
recognition.stop();
|
|
1358
1400
|
} catch {
|
|
1359
1401
|
}
|
|
1360
|
-
setListening(false);
|
|
1361
|
-
setInterim("");
|
|
1362
1402
|
}, []);
|
|
1363
|
-
const
|
|
1403
|
+
const openSession = react.useCallback((token) => {
|
|
1364
1404
|
const Ctor = getRecognitionCtor();
|
|
1365
|
-
if (!Ctor) return;
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1405
|
+
if (!Ctor || token !== startTokenRef.current) return;
|
|
1406
|
+
const recognition = new Ctor();
|
|
1407
|
+
recognition.lang = langRef.current ?? (typeof navigator === "undefined" ? "en-US" : navigator.language || "en-US");
|
|
1408
|
+
recognition.continuous = !isTouchDevice();
|
|
1409
|
+
recognition.interimResults = true;
|
|
1410
|
+
recognition.maxAlternatives = 1;
|
|
1411
|
+
recognition.onstart = () => {
|
|
1412
|
+
if (token !== startTokenRef.current) return;
|
|
1413
|
+
setError(null);
|
|
1414
|
+
setListening(true);
|
|
1415
|
+
};
|
|
1416
|
+
recognition.onresult = (event) => {
|
|
1417
|
+
if (token !== startTokenRef.current) return;
|
|
1418
|
+
let settled = "";
|
|
1419
|
+
let pending = "";
|
|
1420
|
+
for (let i = event.resultIndex; i < event.results.length; i += 1) {
|
|
1421
|
+
const result = event.results[i];
|
|
1422
|
+
if (!result) continue;
|
|
1423
|
+
const text = result[0]?.transcript ?? "";
|
|
1424
|
+
if (result.isFinal) settled += text;
|
|
1425
|
+
else pending += text;
|
|
1426
|
+
}
|
|
1427
|
+
setInterim(pending);
|
|
1428
|
+
if (settled.trim() !== "") finalRef.current(settled);
|
|
1429
|
+
};
|
|
1430
|
+
recognition.onerror = (event) => {
|
|
1431
|
+
if (token !== startTokenRef.current) return;
|
|
1432
|
+
if ((event.error === "not-allowed" || event.error === "service-not-allowed") && micConfirmedRef.current && !retriedRef.current) {
|
|
1433
|
+
retriedRef.current = true;
|
|
1434
|
+
void sleep(RETRY_DELAY_MS).then(() => {
|
|
1435
|
+
if (token !== startTokenRef.current || !wantsListeningRef.current)
|
|
1436
|
+
return;
|
|
1437
|
+
openSessionRef.current?.(token);
|
|
1438
|
+
});
|
|
1439
|
+
return;
|
|
1440
|
+
}
|
|
1441
|
+
const message = micConfirmedRef.current && (event.error === "not-allowed" || event.error === "service-not-allowed") ? MIC_UNAVAILABLE_MESSAGE : describeError(event.error);
|
|
1442
|
+
wantsListeningRef.current = false;
|
|
1443
|
+
setListening(false);
|
|
1444
|
+
setInterim("");
|
|
1445
|
+
if (message !== "") {
|
|
1446
|
+
setError(message);
|
|
1447
|
+
errorRef.current?.(message);
|
|
1448
|
+
}
|
|
1449
|
+
};
|
|
1450
|
+
recognition.onend = () => {
|
|
1451
|
+
if (token !== startTokenRef.current) return;
|
|
1452
|
+
setInterim("");
|
|
1453
|
+
if (wantsListeningRef.current && isTouchDevice()) {
|
|
1454
|
+
void sleep(120).then(() => {
|
|
1455
|
+
if (token !== startTokenRef.current || !wantsListeningRef.current)
|
|
1456
|
+
return;
|
|
1457
|
+
openSessionRef.current?.(token);
|
|
1458
|
+
});
|
|
1459
|
+
return;
|
|
1460
|
+
}
|
|
1461
|
+
setListening(false);
|
|
1462
|
+
};
|
|
1463
|
+
recognitionRef.current = recognition;
|
|
1464
|
+
try {
|
|
1465
|
+
recognition.start();
|
|
1466
|
+
} catch {
|
|
1467
|
+
wantsListeningRef.current = false;
|
|
1468
|
+
setListening(false);
|
|
1469
|
+
}
|
|
1470
|
+
}, []);
|
|
1471
|
+
const openSessionRef = react.useRef(null);
|
|
1472
|
+
openSessionRef.current = openSession;
|
|
1473
|
+
const start = react.useCallback(() => {
|
|
1474
|
+
if (!getRecognitionCtor()) return;
|
|
1369
1475
|
startTokenRef.current += 1;
|
|
1370
1476
|
const token = startTokenRef.current;
|
|
1371
|
-
|
|
1477
|
+
wantsListeningRef.current = true;
|
|
1478
|
+
retriedRef.current = false;
|
|
1479
|
+
micConfirmedRef.current = false;
|
|
1480
|
+
setError(null);
|
|
1481
|
+
setListening(true);
|
|
1482
|
+
void ensureMicrophoneAccess().then(async (access) => {
|
|
1372
1483
|
if (token !== startTokenRef.current) return;
|
|
1373
|
-
micConfirmedRef.current = access.ok && access.confirmed;
|
|
1374
1484
|
if (!access.ok) {
|
|
1485
|
+
wantsListeningRef.current = false;
|
|
1375
1486
|
setListening(false);
|
|
1376
1487
|
setError(access.message);
|
|
1377
1488
|
errorRef.current?.(access.message);
|
|
1378
1489
|
return;
|
|
1379
1490
|
}
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
const beginRecognitionImpl = react.useCallback(
|
|
1384
|
-
(Ctor, token) => {
|
|
1385
|
-
const recognition = new Ctor();
|
|
1386
|
-
recognition.lang = lang ?? (typeof navigator === "undefined" ? "en-US" : navigator.language || "en-US");
|
|
1387
|
-
recognition.continuous = true;
|
|
1388
|
-
recognition.interimResults = true;
|
|
1389
|
-
recognition.maxAlternatives = 1;
|
|
1390
|
-
recognition.onstart = () => {
|
|
1491
|
+
micConfirmedRef.current = access.confirmed;
|
|
1492
|
+
if (access.primed) {
|
|
1493
|
+
await sleep(RELEASE_SETTLE_MS);
|
|
1391
1494
|
if (token !== startTokenRef.current) return;
|
|
1392
|
-
setError(null);
|
|
1393
|
-
setListening(true);
|
|
1394
|
-
};
|
|
1395
|
-
recognition.onresult = (event) => {
|
|
1396
|
-
let settled = "";
|
|
1397
|
-
let pending = "";
|
|
1398
|
-
for (let i = event.resultIndex; i < event.results.length; i += 1) {
|
|
1399
|
-
const result = event.results[i];
|
|
1400
|
-
if (!result) continue;
|
|
1401
|
-
const text = result[0]?.transcript ?? "";
|
|
1402
|
-
if (result.isFinal) settled += text;
|
|
1403
|
-
else pending += text;
|
|
1404
|
-
}
|
|
1405
|
-
setInterim(pending);
|
|
1406
|
-
if (settled.trim() !== "") finalRef.current(settled);
|
|
1407
|
-
};
|
|
1408
|
-
recognition.onerror = (event) => {
|
|
1409
|
-
const message = micConfirmedRef.current && (event.error === "not-allowed" || event.error === "service-not-allowed") ? "Dictation isn't available in this browser. You can type instead." : describeError(event.error);
|
|
1410
|
-
setListening(false);
|
|
1411
|
-
setInterim("");
|
|
1412
|
-
if (message !== "") {
|
|
1413
|
-
setError(message);
|
|
1414
|
-
errorRef.current?.(message);
|
|
1415
|
-
}
|
|
1416
|
-
};
|
|
1417
|
-
recognition.onend = () => {
|
|
1418
|
-
setListening(false);
|
|
1419
|
-
setInterim("");
|
|
1420
|
-
};
|
|
1421
|
-
recognitionRef.current = recognition;
|
|
1422
|
-
try {
|
|
1423
|
-
recognition.start();
|
|
1424
|
-
} catch {
|
|
1425
|
-
setListening(false);
|
|
1426
1495
|
}
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
);
|
|
1430
|
-
beginRecognitionRef.current = beginRecognitionImpl;
|
|
1496
|
+
openSessionRef.current?.(token);
|
|
1497
|
+
});
|
|
1498
|
+
}, []);
|
|
1431
1499
|
const toggle = react.useCallback(() => {
|
|
1432
1500
|
if (listening) stop();
|
|
1433
1501
|
else start();
|
|
1434
1502
|
}, [listening, start, stop]);
|
|
1435
1503
|
react.useEffect(
|
|
1436
1504
|
() => () => {
|
|
1505
|
+
startTokenRef.current += 1;
|
|
1506
|
+
wantsListeningRef.current = false;
|
|
1437
1507
|
const recognition = recognitionRef.current;
|
|
1438
1508
|
if (!recognition) return;
|
|
1439
1509
|
recognition.onresult = null;
|