@sensiblestats/widget-react 0.19.0 → 0.20.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.
- package/CHANGELOG.md +11 -0
- package/dist/index.cjs +43 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +43 -13
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -588,21 +588,42 @@ function reducer(state, action) {
|
|
|
588
588
|
}
|
|
589
589
|
|
|
590
590
|
// src/useChatStream.ts
|
|
591
|
+
var STREAM_FALLBACK_TIMEOUT_MS = 3e4;
|
|
591
592
|
function useChatStream(conversation, starterTexts, greetingMessage) {
|
|
592
593
|
const seed = useMemo(() => initialState(starterTexts.map(chipFromText)), []);
|
|
593
594
|
const [state, dispatch] = useReducer(reducer, seed);
|
|
594
595
|
const idRef = useRef(0);
|
|
595
596
|
const handleRef = useRef(null);
|
|
597
|
+
const fallbackTimerRef = useRef(null);
|
|
596
598
|
const stateRef = useRef(state);
|
|
597
599
|
stateRef.current = state;
|
|
598
600
|
const greetedRef = useRef(false);
|
|
599
601
|
const nextId = () => `m${idRef.current++}`;
|
|
602
|
+
const clearFallbackTimer = useCallback(() => {
|
|
603
|
+
if (fallbackTimerRef.current != null) {
|
|
604
|
+
clearTimeout(fallbackTimerRef.current);
|
|
605
|
+
fallbackTimerRef.current = null;
|
|
606
|
+
}
|
|
607
|
+
}, []);
|
|
608
|
+
const armFallbackTimer = useCallback((onFire) => {
|
|
609
|
+
clearFallbackTimer();
|
|
610
|
+
fallbackTimerRef.current = setTimeout(() => {
|
|
611
|
+
fallbackTimerRef.current = null;
|
|
612
|
+
handleRef.current?.cancel();
|
|
613
|
+
handleRef.current = null;
|
|
614
|
+
onFire();
|
|
615
|
+
}, STREAM_FALLBACK_TIMEOUT_MS);
|
|
616
|
+
}, [clearFallbackTimer]);
|
|
600
617
|
const consume = useCallback((handle, onError) => {
|
|
601
618
|
;
|
|
602
619
|
(async () => {
|
|
603
620
|
try {
|
|
604
|
-
for await (const event of handle)
|
|
621
|
+
for await (const event of handle) {
|
|
622
|
+
dispatch({ kind: "EVENT", event });
|
|
623
|
+
if (event.type === "turn_complete" || event.type === "error") clearFallbackTimer();
|
|
624
|
+
}
|
|
605
625
|
} catch (err) {
|
|
626
|
+
if (handleRef.current === handle) clearFallbackTimer();
|
|
606
627
|
if (err instanceof WidgetSdkError2) onError(err);
|
|
607
628
|
else if (err?.name === "AbortError") {
|
|
608
629
|
} else throw err;
|
|
@@ -610,18 +631,23 @@ function useChatStream(conversation, starterTexts, greetingMessage) {
|
|
|
610
631
|
if (handleRef.current === handle) handleRef.current = null;
|
|
611
632
|
}
|
|
612
633
|
})();
|
|
613
|
-
}, []);
|
|
634
|
+
}, [clearFallbackTimer]);
|
|
614
635
|
const run = useCallback((input, displayText) => {
|
|
615
636
|
handleRef.current?.cancel();
|
|
637
|
+
clearFallbackTimer();
|
|
616
638
|
dispatch({ kind: "USER_SENT", input, userId: nextId(), assistantId: nextId(), displayText });
|
|
617
639
|
const handle = conversation.send(input);
|
|
618
640
|
handleRef.current = handle;
|
|
641
|
+
armFallbackTimer(() => {
|
|
642
|
+
dispatch({ kind: "STOP" });
|
|
643
|
+
dispatch({ kind: "STREAM_ERROR", error: new WidgetSdkError2("No response received in time", "timeout") });
|
|
644
|
+
});
|
|
619
645
|
consume(handle, (err) => dispatch({ kind: "STREAM_ERROR", error: err }));
|
|
620
|
-
}, [conversation, consume]);
|
|
646
|
+
}, [conversation, consume, clearFallbackTimer, armFallbackTimer]);
|
|
621
647
|
const send = useCallback((text, opts) => {
|
|
622
648
|
const trimmed = text.trim();
|
|
623
649
|
if (!trimmed) return;
|
|
624
|
-
run({ message: trimmed, actionId: opts?.actionId,
|
|
650
|
+
run({ message: trimmed, actionId: opts?.actionId, actionRef: opts?.actionRef }, opts?.displayText);
|
|
625
651
|
}, [run]);
|
|
626
652
|
const retry = useCallback(() => {
|
|
627
653
|
const last = stateRef.current.lastUserInput;
|
|
@@ -633,25 +659,29 @@ function useChatStream(conversation, starterTexts, greetingMessage) {
|
|
|
633
659
|
greetedRef.current = true;
|
|
634
660
|
try {
|
|
635
661
|
handleRef.current?.cancel();
|
|
662
|
+
clearFallbackTimer();
|
|
636
663
|
dispatch({ kind: "GREETING_SENT", assistantId: nextId() });
|
|
637
664
|
const handle = conversation.send({ message });
|
|
638
665
|
handleRef.current = handle;
|
|
666
|
+
armFallbackTimer(() => dispatch({ kind: "STOP" }));
|
|
639
667
|
consume(handle, () => dispatch({ kind: "STOP" }));
|
|
640
668
|
} catch {
|
|
641
669
|
dispatch({ kind: "STOP" });
|
|
642
670
|
}
|
|
643
|
-
}, [greetingMessage, conversation, consume]);
|
|
671
|
+
}, [greetingMessage, conversation, consume, clearFallbackTimer, armFallbackTimer]);
|
|
644
672
|
const open = useCallback(() => dispatch({ kind: "OPEN" }), []);
|
|
645
673
|
const close = useCallback(() => {
|
|
646
674
|
handleRef.current?.cancel();
|
|
647
675
|
handleRef.current = null;
|
|
676
|
+
clearFallbackTimer();
|
|
648
677
|
dispatch({ kind: "CLOSE" });
|
|
649
|
-
}, []);
|
|
678
|
+
}, [clearFallbackTimer]);
|
|
650
679
|
const stop = useCallback(() => {
|
|
651
680
|
handleRef.current?.cancel();
|
|
652
681
|
handleRef.current = null;
|
|
682
|
+
clearFallbackTimer();
|
|
653
683
|
dispatch({ kind: "STOP" });
|
|
654
|
-
}, []);
|
|
684
|
+
}, [clearFallbackTimer]);
|
|
655
685
|
const toggle = useCallback(() => {
|
|
656
686
|
if (stateRef.current.isOpen) close();
|
|
657
687
|
else open();
|
|
@@ -1316,7 +1346,7 @@ function FixtureHeroBlock({
|
|
|
1316
1346
|
block.venue ? /* @__PURE__ */ jsx18("span", { className: "ss-w-cdash-venue", children: block.venue }) : null,
|
|
1317
1347
|
block.competition ? /* @__PURE__ */ jsx18("span", { className: "ss-w-cdash-comp", children: block.competition }) : null
|
|
1318
1348
|
] }),
|
|
1319
|
-
/* @__PURE__ */ jsx18("button", { type: "button", className: "ss-w-cdash-cta", onClick: () => onAction(block.
|
|
1349
|
+
/* @__PURE__ */ jsx18("button", { type: "button", className: "ss-w-cdash-cta", onClick: () => onAction(block.ctaLabel, { actionRef: block.ctaActionRef }), children: block.ctaLabel })
|
|
1320
1350
|
] });
|
|
1321
1351
|
}
|
|
1322
1352
|
|
|
@@ -1345,12 +1375,12 @@ function MatchPreviewBlock({
|
|
|
1345
1375
|
return /* @__PURE__ */ jsxs16("div", { className: "ss-w-cdash-lines", children: [
|
|
1346
1376
|
/* @__PURE__ */ jsx20("span", { className: "ss-w-cdash-lines-heading", children: heading }),
|
|
1347
1377
|
block.facts.map(
|
|
1348
|
-
(f, i) => f.
|
|
1378
|
+
(f, i) => f.actionRef ? /* @__PURE__ */ jsxs16(
|
|
1349
1379
|
"button",
|
|
1350
1380
|
{
|
|
1351
1381
|
type: "button",
|
|
1352
1382
|
className: "ss-w-cdash-fact",
|
|
1353
|
-
onClick: () => onAction(f.
|
|
1383
|
+
onClick: () => onAction(f.label ?? f.sentence, { actionRef: f.actionRef }),
|
|
1354
1384
|
children: [
|
|
1355
1385
|
f.sentence,
|
|
1356
1386
|
f.label ? /* @__PURE__ */ jsxs16("span", { className: "ss-w-cdash-fact-label", children: [
|
|
@@ -1377,12 +1407,12 @@ function TeamDnaBlock({
|
|
|
1377
1407
|
return /* @__PURE__ */ jsxs17("div", { className: "ss-w-cdash-lines", children: [
|
|
1378
1408
|
/* @__PURE__ */ jsx21("span", { className: "ss-w-cdash-lines-heading", children: heading }),
|
|
1379
1409
|
block.facts.map(
|
|
1380
|
-
(f, i) => f.
|
|
1410
|
+
(f, i) => f.actionRef ? /* @__PURE__ */ jsxs17(
|
|
1381
1411
|
"button",
|
|
1382
1412
|
{
|
|
1383
1413
|
type: "button",
|
|
1384
1414
|
className: "ss-w-cdash-fact",
|
|
1385
|
-
onClick: () => onAction(f.
|
|
1415
|
+
onClick: () => onAction(f.label ?? f.sentence, { actionRef: f.actionRef }),
|
|
1386
1416
|
children: [
|
|
1387
1417
|
f.sentence,
|
|
1388
1418
|
f.label ? /* @__PURE__ */ jsxs17("span", { className: "ss-w-cdash-fact-label", children: [
|
|
@@ -1528,7 +1558,7 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
|
|
|
1528
1558
|
send(tile.actionValue, { displayText: tile.title });
|
|
1529
1559
|
if (m.role === "assistant" && m.greetingDashboard) onDashboardTap?.(tile, index, m.greetingDashboard.layout);
|
|
1530
1560
|
},
|
|
1531
|
-
onClubAction: (
|
|
1561
|
+
onClubAction: (label, opts) => send(label, { actionRef: opts.actionRef }),
|
|
1532
1562
|
ui,
|
|
1533
1563
|
slip
|
|
1534
1564
|
},
|