feat: add SignalR reconnect provider#5153
Conversation
WalkthroughAdds a React ChangesSignalR provider
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 12
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@shesha-reactjs/src/providers/signalR/index.tsx`:
- Around line 38-40: Update the setConnection helper in the SignalR provider to
use useCallback with stable dependencies, or remove it and dispatch
setConnectionAction directly inside the connection-establishing useEffect;
ensure the effect’s dependency handling does not recreate the SignalR connection
on every render.
- Around line 38-40: Memoize the setConnection callback with useCallback so its
identity remains stable when referenced by the useEffect dependency array.
Preserve its existing dispatch(setConnectionAction(connection)) behavior and
include the appropriate dispatch dependency.
- Around line 38-40: Memoize the setConnection callback with React’s
useCallback, adding useCallback to the existing react imports and preserving its
dispatch behavior. Then include the stable setConnection reference in the
useEffect dependency array to satisfy exhaustive-deps without recreating the
SignalR connection on every render.
- Around line 38-40: Memoize the setConnection callback with React’s useCallback
and include the resulting stable callback in the relevant useEffect dependency
array. Update the React imports accordingly, preserving the existing
dispatch(setConnectionAction(connection)) behavior and preventing repeated
SignalR connection teardown and rebuilding.
- Around line 125-143: Set the require parameter default to true in both
useSignalRState and useSignalRActions, preserving their existing context
validation and return behavior while allowing callers to omit the argument.
- Around line 125-143: Set the require parameter default to true in both
useSignalRState and useSignalRActions, preserving their existing context
validation and return behavior while allowing callers to omit the argument.
- Around line 87-94: Update the startup completion handler in the SignalR
connection effect so that when `isActive` is false, it asynchronously invokes
`connection.stop()` before returning. Preserve the existing state update and
`onConnectedRef` callback only for active effects, and ensure the
cleanup/startup flow handles the stop promise without leaving an unhandled
rejection.
- Around line 87-94: Update the connection.start() completion handler in the
then callback to call connection.stop() and return when isActive is false,
before setConnection or onConnectedRef. Preserve the existing state publication
for active effects, ensuring a connection that finishes starting after unmount
is stopped rather than left open.
- Line 3: Update the React import in the SignalR provider to include
useCallback, so the provider can memoize its callback logic as required.
- Around line 80-83: Update the SignalR connection onclose handler to call
setConnection(undefined) when the connection is permanently closed, alongside
the existing onDisconnectedRef callback, so consumers no longer receive a stale
connection object.
- Around line 80-83: Update the SignalR connection.onclose handler to call
setConnection(undefined) when the connection is permanently closed, while
preserving the existing error logging and onDisconnectedRef callback.
- Around line 80-83: Update the SignalR connection.onclose handler to clear the
provider’s connection state by calling setConnection(undefined) before or
alongside onDisconnectedRef.current?.(), while preserving the existing close
logging and callback behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 5715d283-0da0-4f41-8043-c7fd37a0f164
📒 Files selected for processing (1)
shesha-reactjs/src/providers/signalR/index.tsx
| @@ -0,0 +1,159 @@ | |||
| import * as signalR from '@microsoft/signalr'; | |||
|
|
|||
| import React, { PropsWithChildren, useContext, useEffect, useReducer, useRef } from 'react'; | |||
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
Import useCallback for memoization.
📦 Proposed import
-import React, { PropsWithChildren, useContext, useEffect, useReducer, useRef } from 'react';
+import React, { PropsWithChildren, useContext, useEffect, useReducer, useRef, useCallback } from 'react';📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import React, { PropsWithChildren, useContext, useEffect, useReducer, useRef } from 'react'; | |
| import React, { PropsWithChildren, useContext, useEffect, useReducer, useRef, useCallback } from 'react'; |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@shesha-reactjs/src/providers/signalR/index.tsx` at line 3, Update the React
import in the SignalR provider to include useCallback, so the provider can
memoize its callback logic as required.
| const setConnection = (connection?: ISignalRConnection) => { | ||
| dispatch(setConnectionAction(connection)); | ||
| }; |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
Wrap setConnection in useCallback or call dispatch directly.
setConnection is defined on every render but is used inside the useEffect that establishes the SignalR connection. If your linter enforces exhaustive dependencies, this will trigger a warning for a missing dependency. If you add it to the dependency array without memoizing it, the effect will continuously tear down and rebuild the connection on every render.
Wrap it in useCallback, or simply call dispatch(setConnectionAction(...)) directly within the effect.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@shesha-reactjs/src/providers/signalR/index.tsx` around lines 38 - 40, Update
the setConnection helper in the SignalR provider to use useCallback with stable
dependencies, or remove it and dispatch setConnectionAction directly inside the
connection-establishing useEffect; ensure the effect’s dependency handling does
not recreate the SignalR connection on every render.
📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
Memoize setConnection to prevent dependency array warnings or infinite loops.
setConnection is re-created on every render but used inside the useEffect block. If added to the effect's dependency array, it will cause the connection to be continuously torn down and restarted on every render. If omitted, it will trigger an eslint-react-hooks/exhaustive-deps warning.
Wrap it in useCallback or replace its usages by directly calling dispatch(setConnectionAction(...)) inside the effect.
♻️ Proposed fix
- const setConnection = (connection?: ISignalRConnection) => {
- dispatch(setConnectionAction(connection));
- };
+ const setConnection = React.useCallback((connection?: ISignalRConnection) => {
+ dispatch(setConnectionAction(connection));
+ }, []);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@shesha-reactjs/src/providers/signalR/index.tsx` around lines 38 - 40, Memoize
the setConnection callback with useCallback so its identity remains stable when
referenced by the useEffect dependency array. Preserve its existing
dispatch(setConnectionAction(connection)) behavior and include the appropriate
dispatch dependency.
📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
Memoize setConnection to prevent dependency array warnings.
setConnection is re-created on every render but used inside the useEffect block. Omitting it from the dependency array violates eslint-react-hooks/exhaustive-deps, while including it without memoization will cause the connection to be repeatedly torn down and rebuilt on every render.
Wrap it in useCallback (remembering to add it to the imports from react).
♻️ Proposed fix
- const setConnection = (connection?: ISignalRConnection) => {
+ const setConnection = useCallback((connection?: ISignalRConnection) => {
dispatch(setConnectionAction(connection));
- };
+ }, []);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const setConnection = (connection?: ISignalRConnection) => { | |
| dispatch(setConnectionAction(connection)); | |
| }; | |
| const setConnection = useCallback((connection?: ISignalRConnection) => { | |
| dispatch(setConnectionAction(connection)); | |
| }, []); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@shesha-reactjs/src/providers/signalR/index.tsx` around lines 38 - 40, Memoize
the setConnection callback with React’s useCallback, adding useCallback to the
existing react imports and preserving its dispatch behavior. Then include the
stable setConnection reference in the useEffect dependency array to satisfy
exhaustive-deps without recreating the SignalR connection on every render.
📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
Memoize setConnection to prevent dependency array warnings.
setConnection is re-created on every render but used inside the useEffect block. Omitting it from the effect's dependency array violates the eslint-react-hooks/exhaustive-deps rule. Alternatively, including it without memoization will cause the connection to be repeatedly torn down and rebuilt on every render.
Wrap it in useCallback (remembering to add it to the imports from react) or replace its usages by directly calling dispatch inside the effect.
♻️ Proposed fix
- const setConnection = (connection?: ISignalRConnection) => {
+ const setConnection = useCallback((connection?: ISignalRConnection) => {
dispatch(setConnectionAction(connection));
- };
+ }, []);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const setConnection = (connection?: ISignalRConnection) => { | |
| dispatch(setConnectionAction(connection)); | |
| }; | |
| const setConnection = useCallback((connection?: ISignalRConnection) => { | |
| dispatch(setConnectionAction(connection)); | |
| }, []); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@shesha-reactjs/src/providers/signalR/index.tsx` around lines 38 - 40, Memoize
the setConnection callback with React’s useCallback and include the resulting
stable callback in the relevant useEffect dependency array. Update the React
imports accordingly, preserving the existing
dispatch(setConnectionAction(connection)) behavior and preventing repeated
SignalR connection teardown and rebuilding.
| connection.onclose((error) => { | ||
| console.error('SignalR connection closed', error); | ||
| onDisconnectedRef.current?.(); | ||
| }); |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Clear the connection from state when it is permanently closed.
The onclose event fires when the connection is permanently lost (e.g., if the server disconnects or all automatic reconnect attempts fail). Currently, it invokes the onDisconnected callback but leaves the stale connection object in the context state. Components relying on the provider will still see a connection and might attempt to invoke methods on it, resulting in runtime errors.
Call setConnection(undefined) within the onclose handler to ensure the context accurately reflects that there is no active connection.
🧹 Proposed fix
connection.onclose((error) => {
console.error('SignalR connection closed', error);
+ setConnection();
onDisconnectedRef.current?.();
});🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@shesha-reactjs/src/providers/signalR/index.tsx` around lines 80 - 83, Update
the SignalR connection onclose handler to call setConnection(undefined) when the
connection is permanently closed, alongside the existing onDisconnectedRef
callback, so consumers no longer receive a stale connection object.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Clear the connection from state when it is permanently closed.
The onclose event fires when the connection is permanently lost (e.g., if the server disconnects or all automatic reconnect attempts fail). Currently, it invokes the onDisconnected callback but leaves the stale connection object in the context state. Components relying on the provider will still see a connection and might attempt to invoke methods on it, resulting in runtime errors.
Call setConnection(undefined) within the onclose handler to ensure the context accurately reflects that there is no active connection.
🧹 Proposed fix
connection.onclose((error) => {
console.error('SignalR connection closed', error);
+ setConnection();
onDisconnectedRef.current?.();
});🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@shesha-reactjs/src/providers/signalR/index.tsx` around lines 80 - 83, Update
the SignalR connection.onclose handler to call setConnection(undefined) when the
connection is permanently closed, while preserving the existing error logging
and onDisconnectedRef callback.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Clear the connection from state when it permanently closes.
The onclose event fires when the connection is permanently lost (or if all automatic reconnect attempts fail). Currently, it invokes the onDisconnected callback but leaves the disconnected connection object in the context state. Components relying on the provider will still see a connection and might attempt to invoke methods on it, resulting in errors.
Call setConnection(undefined) (or setConnection()) within onclose to ensure the context accurately reflects the disconnected state.
🧹 Proposed fix
connection.onclose((error) => {
console.error('SignalR connection closed', error);
+ setConnection();
onDisconnectedRef.current?.();
});📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| connection.onclose((error) => { | |
| console.error('SignalR connection closed', error); | |
| onDisconnectedRef.current?.(); | |
| }); | |
| connection.onclose((error) => { | |
| console.error('SignalR connection closed', error); | |
| setConnection(); | |
| onDisconnectedRef.current?.(); | |
| }); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@shesha-reactjs/src/providers/signalR/index.tsx` around lines 80 - 83, Update
the SignalR connection.onclose handler to clear the provider’s connection state
by calling setConnection(undefined) before or alongside
onDisconnectedRef.current?.(), while preserving the existing close logging and
callback behavior.
| .then(() => { | ||
| // Only expose the connection once it has actually started successfully, | ||
| // and only if this effect instance is still active. | ||
| if (!isActive) return; | ||
| setConnection(connection); | ||
| onConnectedRef.current?.(connection); | ||
| }) | ||
| .catch((err) => console.error('SignalR start failed:', err)); |
There was a problem hiding this comment.
🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win
Prevent SignalR connection leaks when the component unmounts during startup.
If the component unmounts while connection.start() is still pending, the synchronous stop() call in the cleanup function will fail because SignalR throws an error if you attempt to stop a connection in the Connecting state. When start() eventually completes, the !isActive guard prevents it from being saved to state, but the connection remains permanently open in the background.
To prevent this resource leak, explicitly invoke connection.stop() inside the .then() block if the effect is no longer active.
🔌 Proposed fix
connection
.start()
.then(() => {
// Only expose the connection once it has actually started successfully,
// and only if this effect instance is still active.
- if (!isActive) return;
+ if (!isActive) {
+ connection.stop().catch((err) => console.error('SignalR stop on unmount failed:', err));
+ return;
+ }
setConnection(connection);
onConnectedRef.current?.(connection);
})📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| .then(() => { | |
| // Only expose the connection once it has actually started successfully, | |
| // and only if this effect instance is still active. | |
| if (!isActive) return; | |
| setConnection(connection); | |
| onConnectedRef.current?.(connection); | |
| }) | |
| .catch((err) => console.error('SignalR start failed:', err)); | |
| .then(() => { | |
| // Only expose the connection once it has actually started successfully, | |
| // and only if this effect instance is still active. | |
| if (!isActive) { | |
| connection.stop().catch((err) => console.error('SignalR stop on unmount failed:', err)); | |
| return; | |
| } | |
| setConnection(connection); | |
| onConnectedRef.current?.(connection); | |
| }) | |
| .catch((err) => console.error('SignalR start failed:', err)); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@shesha-reactjs/src/providers/signalR/index.tsx` around lines 87 - 94, Update
the startup completion handler in the SignalR connection effect so that when
`isActive` is false, it asynchronously invokes `connection.stop()` before
returning. Preserve the existing state update and `onConnectedRef` callback only
for active effects, and ensure the cleanup/startup flow handles the stop promise
without leaving an unhandled rejection.
🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win
Prevent SignalR connection leaks when the component unmounts during startup.
If the component unmounts while connection.start() is still pending, the synchronous stop() call in the cleanup function will fail because SignalR throws an error if you attempt to stop a connection in the Connecting state. When start() eventually completes, the !isActive guard prevents it from being saved to state, but the connection remains permanently open in the background.
To prevent this resource leak, invoke connection.stop() inside the .then() block if the effect is no longer active.
🔌 Proposed fix
connection
.start()
.then(() => {
// Only expose the connection once it has actually started successfully,
// and only if this effect instance is still active.
- if (!isActive) return;
+ if (!isActive) {
+ connection.stop().catch((err) => console.error('SignalR stop on unmount failed:', err));
+ return;
+ }
setConnection(connection);
onConnectedRef.current?.(connection);
})📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| .then(() => { | |
| // Only expose the connection once it has actually started successfully, | |
| // and only if this effect instance is still active. | |
| if (!isActive) return; | |
| setConnection(connection); | |
| onConnectedRef.current?.(connection); | |
| }) | |
| .catch((err) => console.error('SignalR start failed:', err)); | |
| .then(() => { | |
| // Only expose the connection once it has actually started successfully, | |
| // and only if this effect instance is still active. | |
| if (!isActive) { | |
| connection.stop().catch((err) => console.error('SignalR stop on unmount failed:', err)); | |
| return; | |
| } | |
| setConnection(connection); | |
| onConnectedRef.current?.(connection); | |
| }) | |
| .catch((err) => console.error('SignalR start failed:', err)); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@shesha-reactjs/src/providers/signalR/index.tsx` around lines 87 - 94, Update
the connection.start() completion handler in the then callback to call
connection.stop() and return when isActive is false, before setConnection or
onConnectedRef. Preserve the existing state publication for active effects,
ensuring a connection that finishes starting after unmount is stopped rather
than left open.
| function useSignalRState(require: boolean) { | ||
| const context = useContext(SignalRStateContext); | ||
|
|
||
| if (context === undefined && require) { | ||
| throw new Error('useSignalRState must be used within a SignalRProvider'); | ||
| } | ||
|
|
||
| return context; | ||
| } | ||
|
|
||
| function useSignalRActions(require: boolean) { | ||
| const context = useContext(SignalRActionsContext); | ||
|
|
||
| if (context === undefined && require) { | ||
| throw new Error('useSignalRActions must be used within a SignalRProvider'); | ||
| } | ||
|
|
||
| return context; | ||
| } |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
Set a default value for the require parameter.
For consistency with useSignalR and to improve developer ergonomics, provide a default value of true for the require parameter in both useSignalRState and useSignalRActions. This prevents TypeScript errors when consumers call these hooks without arguments.
🛠 Proposed fix
-function useSignalRState(require: boolean) {
+function useSignalRState(require: boolean = true) {
const context = useContext(SignalRStateContext);
if (context === undefined && require) {
throw new Error('useSignalRState must be used within a SignalRProvider');
}
return context;
}
-function useSignalRActions(require: boolean) {
+function useSignalRActions(require: boolean = true) {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| function useSignalRState(require: boolean) { | |
| const context = useContext(SignalRStateContext); | |
| if (context === undefined && require) { | |
| throw new Error('useSignalRState must be used within a SignalRProvider'); | |
| } | |
| return context; | |
| } | |
| function useSignalRActions(require: boolean) { | |
| const context = useContext(SignalRActionsContext); | |
| if (context === undefined && require) { | |
| throw new Error('useSignalRActions must be used within a SignalRProvider'); | |
| } | |
| return context; | |
| } | |
| function useSignalRState(require: boolean = true) { | |
| const context = useContext(SignalRStateContext); | |
| if (context === undefined && require) { | |
| throw new Error('useSignalRState must be used within a SignalRProvider'); | |
| } | |
| return context; | |
| } | |
| function useSignalRActions(require: boolean = true) { | |
| const context = useContext(SignalRActionsContext); | |
| if (context === undefined && require) { | |
| throw new Error('useSignalRActions must be used within a SignalRProvider'); | |
| } | |
| return context; | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@shesha-reactjs/src/providers/signalR/index.tsx` around lines 125 - 143, Set
the require parameter default to true in both useSignalRState and
useSignalRActions, preserving their existing context validation and return
behavior while allowing callers to omit the argument.
📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
Set a default value for the require parameter.
For consistency with useSignalR and to improve developer ergonomics, provide a default value of true for the require parameter in both useSignalRState and useSignalRActions. This prevents TypeScript errors when consumers call these hooks without arguments.
🛠 Proposed fix
-function useSignalRState(require: boolean) {
+function useSignalRState(require: boolean = true) {
const context = useContext(SignalRStateContext);
if (context === undefined && require) {
throw new Error('useSignalRState must be used within a SignalRProvider');
}
return context;
}
-function useSignalRActions(require: boolean) {
+function useSignalRActions(require: boolean = true) {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| function useSignalRState(require: boolean) { | |
| const context = useContext(SignalRStateContext); | |
| if (context === undefined && require) { | |
| throw new Error('useSignalRState must be used within a SignalRProvider'); | |
| } | |
| return context; | |
| } | |
| function useSignalRActions(require: boolean) { | |
| const context = useContext(SignalRActionsContext); | |
| if (context === undefined && require) { | |
| throw new Error('useSignalRActions must be used within a SignalRProvider'); | |
| } | |
| return context; | |
| } | |
| function useSignalRState(require: boolean = true) { | |
| const context = useContext(SignalRStateContext); | |
| if (context === undefined && require) { | |
| throw new Error('useSignalRState must be used within a SignalRProvider'); | |
| } | |
| return context; | |
| } | |
| function useSignalRActions(require: boolean = true) { | |
| const context = useContext(SignalRActionsContext); | |
| if (context === undefined && require) { | |
| throw new Error('useSignalRActions must be used within a SignalRProvider'); | |
| } | |
| return context; | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@shesha-reactjs/src/providers/signalR/index.tsx` around lines 125 - 143, Set
the require parameter default to true in both useSignalRState and
useSignalRActions, preserving their existing context validation and return
behavior while allowing callers to omit the argument.
Summary by CodeRabbit