@informedai/react 0.4.29 → 0.4.30

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/index.js CHANGED
@@ -316,6 +316,7 @@ function InformedAIProvider({ config, children }) {
316
316
  const initRef = (0, import_react.useRef)(false);
317
317
  const heartbeatIntervalRef = (0, import_react.useRef)(null);
318
318
  const sessionIdRef = (0, import_react.useRef)(null);
319
+ const operationInFlightRef = (0, import_react.useRef)(false);
319
320
  const shouldPersist = config.persistSession ?? true;
320
321
  const storageKey = getStorageKey(config.documentTypeId, config.externalId);
321
322
  (0, import_react.useEffect)(() => {
@@ -532,6 +533,10 @@ function InformedAIProvider({ config, children }) {
532
533
  if (window.document.hidden) {
533
534
  stopHeartbeat();
534
535
  } else if (session?.id && clientRef.current) {
536
+ if (operationInFlightRef.current) {
537
+ startHeartbeat(session.id);
538
+ return;
539
+ }
535
540
  try {
536
541
  const refreshedSession = await clientRef.current.getSession(session.id);
537
542
  if (refreshedSession.status === "abandoned") {
@@ -588,6 +593,7 @@ function InformedAIProvider({ config, children }) {
588
593
  const sendMessage = (0, import_react.useCallback)(async (message) => {
589
594
  if (!clientRef.current || !session) return;
590
595
  try {
596
+ operationInFlightRef.current = true;
591
597
  const optimisticMessage = {
592
598
  id: `temp-${Date.now()}`,
593
599
  role: "user",
@@ -613,12 +619,14 @@ function InformedAIProvider({ config, children }) {
613
619
  setError(error2);
614
620
  config.onError?.(error2);
615
621
  } finally {
622
+ operationInFlightRef.current = false;
616
623
  setIsStreaming(false);
617
624
  }
618
625
  }, [session, handleSSEEvent, handleSessionDeleted, config]);
619
626
  const sendQuickAction = (0, import_react.useCallback)(async (action) => {
620
627
  if (!clientRef.current || !session) return;
621
628
  try {
629
+ operationInFlightRef.current = true;
622
630
  setIsStreaming(true);
623
631
  setStreamingContent("");
624
632
  setError(null);
@@ -641,12 +649,14 @@ function InformedAIProvider({ config, children }) {
641
649
  setError(error2);
642
650
  config.onError?.(error2);
643
651
  } finally {
652
+ operationInFlightRef.current = false;
644
653
  setIsStreaming(false);
645
654
  }
646
655
  }, [session, handleSSEEvent, handleSessionDeleted, config]);
647
656
  const applyPendingValue = (0, import_react.useCallback)(async () => {
648
657
  if (!clientRef.current || !session) return;
649
658
  try {
659
+ operationInFlightRef.current = true;
650
660
  setError(null);
651
661
  const result = await clientRef.current.applyPendingValue(session.id);
652
662
  setSession(result.session);
@@ -660,11 +670,14 @@ function InformedAIProvider({ config, children }) {
660
670
  const error2 = err instanceof Error ? err : new Error("Failed to apply value");
661
671
  setError(error2);
662
672
  config.onError?.(error2);
673
+ } finally {
674
+ operationInFlightRef.current = false;
663
675
  }
664
676
  }, [session, handleSessionDeleted, config]);
665
677
  const skipTask = (0, import_react.useCallback)(async () => {
666
678
  if (!clientRef.current || !session) return;
667
679
  try {
680
+ operationInFlightRef.current = true;
668
681
  setError(null);
669
682
  const newSession = await clientRef.current.skipTask(session.id);
670
683
  setSession(newSession);
@@ -677,6 +690,8 @@ function InformedAIProvider({ config, children }) {
677
690
  const error2 = err instanceof Error ? err : new Error("Failed to skip task");
678
691
  setError(error2);
679
692
  config.onError?.(error2);
693
+ } finally {
694
+ operationInFlightRef.current = false;
680
695
  }
681
696
  }, [session, handleSessionDeleted, config]);
682
697
  const startNewSession = (0, import_react.useCallback)(async () => {
package/dist/index.mjs CHANGED
@@ -283,6 +283,7 @@ function InformedAIProvider({ config, children }) {
283
283
  const initRef = useRef(false);
284
284
  const heartbeatIntervalRef = useRef(null);
285
285
  const sessionIdRef = useRef(null);
286
+ const operationInFlightRef = useRef(false);
286
287
  const shouldPersist = config.persistSession ?? true;
287
288
  const storageKey = getStorageKey(config.documentTypeId, config.externalId);
288
289
  useEffect(() => {
@@ -499,6 +500,10 @@ function InformedAIProvider({ config, children }) {
499
500
  if (window.document.hidden) {
500
501
  stopHeartbeat();
501
502
  } else if (session?.id && clientRef.current) {
503
+ if (operationInFlightRef.current) {
504
+ startHeartbeat(session.id);
505
+ return;
506
+ }
502
507
  try {
503
508
  const refreshedSession = await clientRef.current.getSession(session.id);
504
509
  if (refreshedSession.status === "abandoned") {
@@ -555,6 +560,7 @@ function InformedAIProvider({ config, children }) {
555
560
  const sendMessage = useCallback(async (message) => {
556
561
  if (!clientRef.current || !session) return;
557
562
  try {
563
+ operationInFlightRef.current = true;
558
564
  const optimisticMessage = {
559
565
  id: `temp-${Date.now()}`,
560
566
  role: "user",
@@ -580,12 +586,14 @@ function InformedAIProvider({ config, children }) {
580
586
  setError(error2);
581
587
  config.onError?.(error2);
582
588
  } finally {
589
+ operationInFlightRef.current = false;
583
590
  setIsStreaming(false);
584
591
  }
585
592
  }, [session, handleSSEEvent, handleSessionDeleted, config]);
586
593
  const sendQuickAction = useCallback(async (action) => {
587
594
  if (!clientRef.current || !session) return;
588
595
  try {
596
+ operationInFlightRef.current = true;
589
597
  setIsStreaming(true);
590
598
  setStreamingContent("");
591
599
  setError(null);
@@ -608,12 +616,14 @@ function InformedAIProvider({ config, children }) {
608
616
  setError(error2);
609
617
  config.onError?.(error2);
610
618
  } finally {
619
+ operationInFlightRef.current = false;
611
620
  setIsStreaming(false);
612
621
  }
613
622
  }, [session, handleSSEEvent, handleSessionDeleted, config]);
614
623
  const applyPendingValue = useCallback(async () => {
615
624
  if (!clientRef.current || !session) return;
616
625
  try {
626
+ operationInFlightRef.current = true;
617
627
  setError(null);
618
628
  const result = await clientRef.current.applyPendingValue(session.id);
619
629
  setSession(result.session);
@@ -627,11 +637,14 @@ function InformedAIProvider({ config, children }) {
627
637
  const error2 = err instanceof Error ? err : new Error("Failed to apply value");
628
638
  setError(error2);
629
639
  config.onError?.(error2);
640
+ } finally {
641
+ operationInFlightRef.current = false;
630
642
  }
631
643
  }, [session, handleSessionDeleted, config]);
632
644
  const skipTask = useCallback(async () => {
633
645
  if (!clientRef.current || !session) return;
634
646
  try {
647
+ operationInFlightRef.current = true;
635
648
  setError(null);
636
649
  const newSession = await clientRef.current.skipTask(session.id);
637
650
  setSession(newSession);
@@ -644,6 +657,8 @@ function InformedAIProvider({ config, children }) {
644
657
  const error2 = err instanceof Error ? err : new Error("Failed to skip task");
645
658
  setError(error2);
646
659
  config.onError?.(error2);
660
+ } finally {
661
+ operationInFlightRef.current = false;
647
662
  }
648
663
  }, [session, handleSessionDeleted, config]);
649
664
  const startNewSession = useCallback(async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@informedai/react",
3
- "version": "0.4.29",
3
+ "version": "0.4.30",
4
4
  "description": "React SDK for InformedAI Assistant - AI-powered content creation widget",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",