@@ -76,6 +76,20 @@ export interface UseTock {
76
76
sseInitializing : boolean ;
77
77
}
78
78
79
+ /**
80
+ * Internal extensions for {@link UseTock}
81
+ */
82
+ interface UseTock0 extends UseTock {
83
+ /**
84
+ * Hook that initializes the SSE connection and returns {@link #sseInitPromise}
85
+ *
86
+ * If SSE is disabled by the settings, this method simply resolves the sseInitPromise.
87
+ *
88
+ * This method is idempotent.
89
+ */
90
+ useSseInit : ( ) => void ;
91
+ }
92
+
79
93
function mapButton ( button : BotConnectorButton ) : Button {
80
94
if ( button . type === 'postback' ) {
81
95
return new PostBackButton ( button . title , button . payload , button . imageUrl ) ;
@@ -126,7 +140,7 @@ export const useTock0: (
126
140
extraHeadersProvider ?: ( ) => Promise < Record < string , string > > ,
127
141
disableSse ?: boolean ,
128
142
localStorageHistory ?: TockLocalStorage ,
129
- ) => UseTock = (
143
+ ) => UseTock0 = (
130
144
tockEndPoint : string ,
131
145
{ locale, localStorage : localStorageSettings , network : networkSettings } ,
132
146
extraHeadersProvider ?: ( ) => Promise < Record < string , string > > ,
@@ -599,19 +613,20 @@ export const useTock0: (
599
613
sseSource . current . onResponse = handleSseBotResponse ;
600
614
} , [ handleSseBotResponse , onSseStateChange ] ) ;
601
615
602
- useEffect ( ( ) => {
603
- if ( disableSse || ! tockEndPoint . length ) {
604
- afterInit . current ( ) ;
605
- } else {
606
- // Trigger afterInit regardless of whether the SSE call succeeded or failed
607
- // (it is valid for the backend to refuse SSE connections, but we still attempt to connect by default)
608
- sseSource . current
609
- . open ( tockEndPoint , userId )
610
- . catch ( ( e ) => console . error ( e ) )
611
- . finally ( afterInit . current ) ;
612
- }
613
- return ( ) => sseSource . current . close ( ) ;
614
- } , [ disableSse , tockEndPoint ] ) ;
616
+ const useSseInit = ( ) =>
617
+ useEffect ( ( ) => {
618
+ if ( disableSse || ! tockEndPoint . length ) {
619
+ afterInit . current ( ) ;
620
+ } else {
621
+ // Trigger afterInit regardless of whether the SSE call succeeded or failed
622
+ // (it is valid for the backend to refuse SSE connections, but we still attempt to connect by default)
623
+ sseSource . current
624
+ . open ( tockEndPoint , userId )
625
+ . catch ( ( e ) => console . error ( e ) )
626
+ . finally ( afterInit . current ) ;
627
+ }
628
+ return ( ) => sseSource . current . close ( ) ;
629
+ } , [ disableSse , tockEndPoint ] ) ;
615
630
616
631
const addHistory : (
617
632
messageHistory : Array < Message > ,
@@ -698,36 +713,42 @@ export const useTock0: (
698
713
loadHistory,
699
714
sseInitPromise : afterInitPromise . current ,
700
715
sseInitializing,
716
+ useSseInit,
701
717
} ;
702
718
} ;
703
719
704
- export const UseTockContext = createContext < UseTock | undefined > ( undefined ) ;
720
+ export const UseTockContext = createContext < UseTock0 | undefined > ( undefined ) ;
705
721
706
722
export default (
707
723
tockEndPoint ?: string ,
708
724
extraHeadersProvider ?: ( ) => Promise < Record < string , string > > ,
709
725
disableSse ?: boolean ,
710
726
localStorageHistory ?: TockLocalStorage ,
711
- ) => {
727
+ ) : UseTock => {
712
728
const contextTock = useContext ( UseTockContext ) ;
713
729
const settings = useTockSettings ( ) ;
714
- if ( contextTock != null ) {
715
- return contextTock ;
716
- }
730
+
717
731
if ( settings . endpoint == null && tockEndPoint == null ) {
718
732
throw new Error ( 'TOCK endpoint must be provided in TockContext' ) ;
719
733
} else if ( settings . endpoint == null ) {
720
734
console . warn (
721
735
'Passing TOCK endpoint as argument to TockChat or useTock is deprecated; please set it in TockContext instead.' ,
722
736
) ;
723
737
}
724
- return contextTock
725
- ? contextTock
726
- : useTock0 (
727
- ( tockEndPoint ?? settings . endpoint ) ! ,
728
- settings ,
729
- extraHeadersProvider ,
730
- disableSse ,
731
- localStorageHistory ,
732
- ) ;
738
+
739
+ // the following conditional does not follow the rules of hooks,
740
+ // but in practice the endpoint setting should not appear or disappear in a live app
741
+ const ret =
742
+ contextTock ??
743
+ useTock0 (
744
+ ( tockEndPoint ?? settings . endpoint ) ! ,
745
+ settings ,
746
+ extraHeadersProvider ,
747
+ disableSse ,
748
+ localStorageHistory ,
749
+ ) ;
750
+
751
+ ret . useSseInit ( ) ;
752
+
753
+ return ret ;
733
754
} ;
0 commit comments