-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Fix issues with rails/actioncable in the server sdk #14714
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎ 3 Skipped Deployments
|
WalkthroughThe changes introduce global function declarations for Changes
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Warning Rate limit exceeded@adolfo-pd has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 20 minutes and 43 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (2)
packages/sdk/src/server/async.ts (2)
Line range hint
26-28: Fix incorrect operator in WebSocket adapter assignmentThere's a critical bug in the WebSocket adapter assignment. The code uses
==(comparison) instead of=(assignment).if (typeof adapters.WebSocket === "undefined") - adapters.WebSocket == WS; + adapters.WebSocket = WS;
Line range hint
1-41: Please update the PR description with implementation detailsWhile the changes appear to address issues with rails/actioncable by:
- Adding necessary event listener polyfills
- Fixing WebSocket adapter assignment
- Correcting OAuth token access
It would be helpful to document these changes in the PR description under the "WHY" section to provide context for future reference.
🧰 Tools
🪛 eslint (1.23.1)
[error] 8-9: Missing semicolon.
(@typescript-eslint/semi)
[error] 9-10: Missing semicolon.
(@typescript-eslint/semi)
[error] 11-11: Unexpected empty arrow function.
(@typescript-eslint/no-empty-function)
[error] 11-12: Missing semicolon.
(@typescript-eslint/semi)
[error] 12-12: Unexpected empty arrow function.
(@typescript-eslint/no-empty-function)
[error] 12-13: Missing semicolon.
(@typescript-eslint/semi)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (1)
packages/sdk/src/server/async.ts(2 hunks)
🧰 Additional context used
🪛 eslint (1.23.1)
packages/sdk/src/server/async.ts
[error] 8-9: Missing semicolon.
(@typescript-eslint/semi)
[error] 9-10: Missing semicolon.
(@typescript-eslint/semi)
[error] 11-11: Unexpected empty arrow function.
(@typescript-eslint/no-empty-function)
[error] 11-12: Missing semicolon.
(@typescript-eslint/semi)
[error] 12-12: Unexpected empty arrow function.
(@typescript-eslint/no-empty-function)
[error] 12-13: Missing semicolon.
(@typescript-eslint/semi)
🔇 Additional comments (1)
packages/sdk/src/server/async.ts (1)
31-32: Verify OAuth token structure across all authentication flows
The token access path has been updated to match OAuth2 token structure. While this looks correct, please verify this works with all authentication flows.
✅ Verification successful
OAuth token structure is correctly implemented
The token access path oauthToken.token.access_token is consistent with:
- The imported
AccessTokentype fromsimple-oauth2 - The token usage in
ServerClientclass for Bearer authentication - The token refresh mechanism in
ensureValidOauthToken
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for other token access patterns to ensure consistency
rg -t typescript -t javascript "token\.access_token"
# Look for OAuth token type definitions
ast-grep --pattern 'type $name = { token: { access_token: $_ } }'
Length of output: 157
Script:
#!/bin/bash
# Search for token access patterns with ripgrep (using correct file extensions)
rg -t ts -t js "token\.access_token"
# Search for OAuth token related type definitions
ast-grep --pattern 'interface $_ { token: { access_token: $_ } }'
# Look for other token access patterns
rg -t ts -t js "access_token"
# Find files that might contain token handling
fd -e ts -e js | grep -i "token\|auth"
Length of output: 4475
Script:
#!/bin/bash
# Look for OAuth token type definitions in SDK
rg -t ts "interface.*Token" -A 5 packages/sdk/
rg -t ts "type.*Token" -A 5 packages/sdk/
# Check the context of token usage in server files
rg -t ts "oauthToken" -B 2 -A 2 packages/sdk/src/server/
Length of output: 4846
packages/sdk/src/server/async.ts
Outdated
| declare global { | ||
| function addEventListener(type: string, listener: () => void): void | ||
| function removeEventListener(type: string, listener: () => void): void | ||
| } | ||
| global.addEventListener = () => {} | ||
| global.removeEventListener = () => {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider a more robust approach for handling browser APIs in Node.js
The current implementation adds global no-op event listeners, which could mask potential issues by silently ignoring events. Consider using a proper polyfill or environment-specific implementation.
-declare global {
- function addEventListener(type: string, listener: () => void): void
- function removeEventListener(type: string, listener: () => void): void
-}
-global.addEventListener = () => {}
-global.removeEventListener = () => {}
+import { EventEmitter } from 'events';
+
+class NodeEventAdapter extends EventEmitter {
+ addEventListener(type: string, listener: () => void): void {
+ this.on(type, listener);
+ }
+
+ removeEventListener(type: string, listener: () => void): void {
+ this.off(type, listener);
+ }
+}
+
+const eventAdapter = new NodeEventAdapter();
+global.addEventListener = eventAdapter.addEventListener.bind(eventAdapter);
+global.removeEventListener = eventAdapter.removeEventListener.bind(eventAdapter);Also, fix the linting issues by adding semicolons:
declare global {
- function addEventListener(type: string, listener: () => void): void
- function removeEventListener(type: string, listener: () => void): void
+ function addEventListener(type: string, listener: () => void): void;
+ function removeEventListener(type: string, listener: () => void): void;
}
-global.addEventListener = () => {}
-global.removeEventListener = () => {}
+global.addEventListener = () => {};
+global.removeEventListener = () => {};📝 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.
| declare global { | |
| function addEventListener(type: string, listener: () => void): void | |
| function removeEventListener(type: string, listener: () => void): void | |
| } | |
| global.addEventListener = () => {} | |
| global.removeEventListener = () => {} | |
| declare global { | |
| function addEventListener(type: string, listener: () => void): void; | |
| function removeEventListener(type: string, listener: () => void): void; | |
| } | |
| global.addEventListener = () => {}; | |
| global.removeEventListener = () => {}; |
🧰 Tools
🪛 eslint (1.23.1)
[error] 8-9: Missing semicolon.
(@typescript-eslint/semi)
[error] 9-10: Missing semicolon.
(@typescript-eslint/semi)
[error] 11-11: Unexpected empty arrow function.
(@typescript-eslint/no-empty-function)
[error] 11-12: Missing semicolon.
(@typescript-eslint/semi)
[error] 12-12: Unexpected empty arrow function.
(@typescript-eslint/no-empty-function)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Outside diff range and nitpick comments (3)
packages/sdk/src/server/async.ts (1)
Line range hint
1-41: Consider a more robust server-side ActionCable implementationThe current implementation mixes browser and Node.js concepts in a way that could be fragile. Consider creating a proper server-side ActionCable adapter that:
- Doesn't rely on browser APIs (addEventListener/removeEventListener)
- Provides proper WebSocket error handling
- Has robust token validation
- Uses TypeScript's strict mode features for better type safety
This would make the code more maintainable and reliable.
🧰 Tools
🪛 eslint (1.23.1)
[error] 24-24: Unexpected empty arrow function.
(@typescript-eslint/no-empty-function)
[error] 24-25: Missing semicolon.
(@typescript-eslint/semi)
[error] 25-25: Unexpected empty arrow function.
(@typescript-eslint/no-empty-function)
[error] 25-26: Missing semicolon.
(@typescript-eslint/semi)
packages/sdk/src/server/cli.ts (2)
5-7: Consider logging the environment value for better debugging.While ENVIRONMENT has a default fallback to "development", it would be helpful to log which environment is being used when the CLI starts up.
const { CLIENT_ID, CLIENT_SECRET, PROJECT_ID, API_HOST, ENVIRONMENT, } = process.env; +console.log(`Using environment: ${ENVIRONMENT || 'development'}`);
20-20: Improve readability of environment configuration.The current ternary expression could be more readable.
- environment: ENVIRONMENT === "production" ? "production" : "development", + environment: getEnvironment(ENVIRONMENT),Add this helper function:
function getEnvironment(env: string | undefined): "production" | "development" { return env === "production" ? "production" : "development"; }🧰 Tools
🪛 eslint (1.23.1)
[error] 20-20: Expected newline between test and consequent of ternary expression.
(multiline-ternary)
[error] 20-20: Expected newline between consequent and alternate of ternary expression.
(multiline-ternary)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (2)
packages/sdk/src/server/async.ts(2 hunks)packages/sdk/src/server/cli.ts(2 hunks)
🧰 Additional context used
🪛 eslint (1.23.1)
packages/sdk/src/server/async.ts
[error] 8-9: Missing semicolon.
(@typescript-eslint/semi)
[error] 9-10: Missing semicolon.
(@typescript-eslint/semi)
[error] 24-24: Unexpected empty arrow function.
(@typescript-eslint/no-empty-function)
[error] 24-25: Missing semicolon.
(@typescript-eslint/semi)
[error] 25-25: Unexpected empty arrow function.
(@typescript-eslint/no-empty-function)
[error] 25-26: Missing semicolon.
(@typescript-eslint/semi)
packages/sdk/src/server/cli.ts
[error] 20-20: Expected newline between test and consequent of ternary expression.
(multiline-ternary)
[error] 20-20: Expected newline between consequent and alternate of ternary expression.
(multiline-ternary)
🔇 Additional comments (2)
packages/sdk/src/server/async.ts (1)
7-10: Consider TypeScript's DOM lib types instead of global declarations
If these declarations are needed for DOM compatibility, consider using TypeScript's DOM lib types by adding "dom" to your tsconfig's lib array instead of declaring them globally. This provides better type safety and maintainability.
Let's check if DOM types are already included:
✅ Verification successful
Global declarations are correctly used for server-side environment compatibility
The global declarations of addEventListener and removeEventListener in packages/sdk/src/server/async.ts are intentionally implemented as no-op functions to provide compatibility with ActionCable in a server environment. This is evidenced by:
- The file is specifically for server-side async response management (
server/async.ts) - The implementations are minimal no-op functions:
global.addEventListener = () => {} - They are used alongside WebSocket adapters for ActionCable compatibility
- The browser version in
packages/sdk/src/browser/index.tscorrectly uses the actual window-based event listeners
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check tsconfig.json for DOM lib inclusion
fd tsconfig.json --exec cat {} | jq -r '.compilerOptions.lib[]' 2>/dev/null
Length of output: 67
Script:
#!/bin/bash
# Let's try a different approach to check tsconfig files and their content
fd tsconfig.json --exec sh -c 'echo "=== {} ==="; cat {}'
# Also check if these global declarations are used elsewhere
rg -l "addEventListener|removeEventListener" --type ts
# Check package.json for any DOM-related dependencies
fd package.json --exec cat {} | jq -r '.dependencies,.devDependencies'
Length of output: 101841
Script:
#!/bin/bash
# Let's check if addEventListener/removeEventListener are used in browser context
rg -A 5 -B 5 'addEventListener|removeEventListener' --type ts
# Also check if there are any DOM-related imports or references
rg -l 'dom|DOM|window|document' --type ts
Length of output: 9501
🧰 Tools
🪛 eslint (1.23.1)
[error] 8-9: Missing semicolon.
(@typescript-eslint/semi)
[error] 9-10: Missing semicolon.
(@typescript-eslint/semi)
packages/sdk/src/server/cli.ts (1)
Line range hint 13-21: Verify the impact on actioncable functionality.
The PR title mentions fixing issues with rails/actioncable, but there are no visible changes related to actioncable in this file. Let's verify if any related changes are needed in the client configuration.
🧰 Tools
🪛 eslint (1.23.1)
[error] 20-20: Expected newline between test and consequent of ternary expression.
(multiline-ternary)
[error] 20-20: Expected newline between consequent and alternate of ternary expression.
(multiline-ternary)
packages/sdk/src/server/async.ts
Outdated
| global.addEventListener = () => {} | ||
| global.removeEventListener = () => {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix incorrect WebSocket adapter assignment
There's a potential bug in the WebSocket adapter assignment. The comparison operator == is used instead of the assignment operator =.
Apply this fix:
if (typeof adapters.WebSocket === "undefined")
- adapters.WebSocket == WS;
+ adapters.WebSocket = WS;Also applies to: 26-27
🧰 Tools
🪛 eslint (1.23.1)
[error] 24-24: Unexpected empty arrow function.
(@typescript-eslint/no-empty-function)
[error] 24-25: Missing semicolon.
(@typescript-eslint/semi)
[error] 25-25: Unexpected empty arrow function.
(@typescript-eslint/no-empty-function)
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (1)
packages/sdk/src/server/async.ts (1)
33-37: Enhance OAuth token validation and error handlingWhile the validation check is good, the error handling could be more specific and follow the project's style guidelines.
Consider these improvements:
const oauthToken = await this.serverOpts.getOauthToken(); - if (!oauthToken?.token?.access_token) { - throw new Error('Invalid OAuth token structure'); + if (!oauthToken?.token) { + throw new Error("OAuth token object is missing or invalid"); + } + if (typeof oauthToken.token.access_token !== "string") { + throw new Error("OAuth access token is missing or invalid"); } const token = oauthToken.token.access_token;🧰 Tools
🪛 eslint (1.23.1)
[error] 35-35: Strings must use doublequote.
(quotes)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (2)
packages/sdk/src/server/async.ts(2 hunks)packages/sdk/src/server/cli.ts(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/sdk/src/server/cli.ts
🧰 Additional context used
🪛 eslint (1.23.1)
packages/sdk/src/server/async.ts
[error] 35-35: Strings must use doublequote.
(quotes)
🔇 Additional comments (2)
packages/sdk/src/server/async.ts (2)
7-10: Skip comment - Past review is still valid
The previous review comment suggesting the use of EventEmitter for a more robust approach to handling browser APIs in Node.js is still applicable to these changes.
Also applies to: 24-27
33-37: Verify OAuth token usage across the codebase
Let's verify how the OAuth token is used in other parts of the codebase to ensure this change doesn't break existing functionality.
✅ Verification successful
OAuth token access pattern is consistent across the codebase
The changes to OAuth token access in packages/sdk/src/server/async.ts follow the same pattern used in other files:
- The
getOauthTokeninterface is defined consistently in both async and regular server implementations - Token access follows the same structure (
oauthToken.token.access_token) in bothserver/index.tsandserver/async.ts - The error handling for invalid token structure adds a safety check without disrupting the existing pattern
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for OAuth token access patterns
echo "Searching for OAuth token usage patterns..."
rg -t typescript -t javascript "getOauthToken|token\.access_token" --no-heading
# Search for WebSocket adapter usage
echo "Searching for WebSocket adapter usage..."
rg -t typescript -t javascript "adapters\.WebSocket" --no-heading
Length of output: 407
Script:
#!/bin/bash
# Search for OAuth token usage patterns with correct file extensions
echo "Searching for OAuth token usage patterns..."
rg "getOauthToken|token\.access_token" --type-add 'ts:*.ts' --type-add 'js:*.js' -t ts -t js
# Search for WebSocket adapter usage
echo "Searching for WebSocket adapter usage..."
rg "adapters\.WebSocket" --type-add 'ts:*.ts' --type-add 'js:*.js' -t ts -t js
# Look for files containing OAuth-related code
echo "Finding OAuth-related files..."
fd -e ts -e js | xargs rg -l "OAuth"
Length of output: 1440
🧰 Tools
🪛 eslint (1.23.1)
[error] 35-35: Strings must use doublequote.
(quotes)
| global.removeEventListener = () => {}; | ||
| if (typeof adapters.WebSocket === "undefined") | ||
| adapters.WebSocket == WS; | ||
| adapters.WebSocket = WS as unknown as WebSocket; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider implementing a proper WebSocket adapter
The current type cast as unknown as WebSocket bypasses TypeScript's type checking, which could hide potential incompatibilities between the 'ws' package and the browser's WebSocket interface.
Consider implementing a proper adapter class:
class NodeWebSocketAdapter implements WebSocket {
private ws: WS;
constructor(url: string, protocols?: string | string[]) {
this.ws = new WS(url, protocols);
}
// Implement necessary WebSocket interface methods
get readyState(): number {
return this.ws.readyState;
}
close(code?: number, reason?: string): void {
this.ws.close(code, reason);
}
// ... implement other required methods
}
// Usage
adapters.WebSocket = NodeWebSocketAdapter;There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (2)
packages/sdk/CHANGELOG.md (2)
8-9: Fix hyphenation in "long running"The term should be hyphenated when used as a compound modifier.
-The backend client now correctly uses asynchronous messaging to handle long running +The backend client now correctly uses asynchronous messaging to handle long-running operations.🧰 Tools
🪛 LanguageTool
[misspelling] ~8-~8: This word is normally spelled with a hyphen.
Context: ...y uses asynchronous messaging to handle long running operations. - Updated the backend com...(EN_COMPOUNDS_LONG_RUNNING)
6-11: Enhance changelog entries with technical detailsThe current entries are quite brief. Consider adding:
- Technical details about the asynchronous messaging implementation
- Impact of these changes on existing integrations
- Any breaking changes or required migration steps
- Examples of how the ENVIRONMENT variable affects the backend tool's behavior
This will help users better understand the changes and their implications.
🧰 Tools
🪛 LanguageTool
[misspelling] ~8-~8: This word is normally spelled with a hyphen.
Context: ...y uses asynchronous messaging to handle long running operations. - Updated the backend com...(EN_COMPOUNDS_LONG_RUNNING)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (3)
packages/sdk/CHANGELOG.md(1 hunks)packages/sdk/package.json(1 hunks)packages/sdk/src/server/async.ts(2 hunks)
✅ Files skipped from review due to trivial changes (1)
- packages/sdk/package.json
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/sdk/src/server/async.ts
🧰 Additional context used
🪛 LanguageTool
packages/sdk/CHANGELOG.md
[misspelling] ~8-~8: This word is normally spelled with a hyphen.
Context: ...y uses asynchronous messaging to handle long running operations. - Updated the backend com...
(EN_COMPOUNDS_LONG_RUNNING)
WHY
Summary by CodeRabbit
New Features
addEventListenerandremoveEventListener, allowing for smoother integration without errors.ENVIRONMENT, to configure backend client settings based on development or production environments.Improvements
ServerAsyncResponseManagerby renamingtokentooauthTokenand refining access token retrieval.oauthTokenstructures.Changelog Update
These changes enhance the overall functionality and clarity of the application, benefiting user interactions and experience.