Skip to content

Commit f38073c

Browse files
Upgrade to React 19, Storybook 8, and Node 22 (#1291)
* chore: upgrade to React 19, Storybook 8, Node 22, and fix LoginForm state * bug fixes * login bug fix * fix: improve variable names in LoginForm and relax Node version check * ci: upgrade Node.js from 16/18 to 22 in all workflows * style: fix Prettier formatting in react package * fix(e2e): bind Vite to 127.0.0.1 to fix Playwright webServer timeout in CI * fix: use semver package for Node version check * chore: add semver as root devDependency * chore: update lockfile * fix(docs): pin webpack to 5.96.1 and update Node/React versions in READMEs
1 parent e1a4d84 commit f38073c

36 files changed

Lines changed: 3775 additions & 3600 deletions

File tree

.github/workflows/build-and-lint.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ jobs:
1717
- name: Set up Node.js
1818
uses: actions/setup-node@v4
1919
with:
20-
node-version: 16.19.0
20+
node-version: 22
2121

2222
- name: Set up Yarn
2323
uses: actions/setup-node@v4
2424
with:
25-
node-version: 16.19.0
25+
node-version: 22
2626
cache: "yarn"
2727

2828
- name: Cache dependencies

.github/workflows/build-pr.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
- name: Setup Node.js
2626
uses: actions/setup-node@v4
2727
with:
28-
node-version: "16.19.0"
28+
node-version: "22"
2929

3030
- name: Install Dependencies
3131
run: yarn install
@@ -36,7 +36,7 @@ jobs:
3636
- name: Setup Node.js for Docs
3737
uses: actions/setup-node@v4
3838
with:
39-
node-version: "18.x"
39+
node-version: "22"
4040

4141
- name: "Install dependencies for docs"
4242
run: yarn install

.github/workflows/deploy.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
- name: Setup Node.js
2828
uses: actions/setup-node@v4
2929
with:
30-
node-version: "16.19.0"
30+
node-version: "22"
3131

3232
- name: Install Dependencies
3333
run: yarn install
@@ -38,7 +38,7 @@ jobs:
3838
- name: Setup Node.js for Docs
3939
uses: actions/setup-node@v4
4040
with:
41-
node-version: "18.x"
41+
node-version: "22"
4242

4343
- name: "Install dependencies for docs"
4444
run: yarn install

.github/workflows/playwright.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
- name: Setup Node.js environment
1818
uses: actions/setup-node@v4
1919
with:
20-
node-version: 16.19.0
20+
node-version: 22
2121

2222
- name: Cache dependencies
2323
uses: actions/cache@v4

.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v16.19.0
1+
v22.16.0

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Ensure that the "Enable CORS" option is turned on in your Rocket.Chat server. Yo
3737

3838
#### Prerequisites
3939

40-
- **Node.js**: Version 16.19.0 is required. Use [Node Version Manager (NVM)](https://github.com/nvm-sh/nvm) for easy switching between Node.js versions.
40+
- **Node.js**: Version 22 (LTS) is required. Use [Node Version Manager (NVM)](https://github.com/nvm-sh/nvm) for easy switching between Node.js versions.
4141

4242
To install and use the correct Node.js version, execute the following commands with the specific version number:
4343

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,15 @@
2222
"esbuild": "^0.17.19",
2323
"husky": "^9.0.11",
2424
"lerna": "^6.6.2",
25+
"semver": "^7.6.0",
2526
"typescript": "^5.1.3"
2627
},
2728
"dependencies": {
2829
"dompurify": "^3.1.6",
2930
"validator": "^13.15.15"
31+
},
32+
"resolutions": {
33+
"react": "^19.0.0",
34+
"react-dom": "^19.0.0"
3035
}
3136
}

packages/api/src/EmbeddedChatApi.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export default class EmbeddedChatApi {
2020
onUiInteractionCallbacks: ((data: any) => void)[];
2121
typingUsers: string[];
2222
auth: RocketChatAuth;
23+
private _connectPromise: Promise<void> | null = null;
2324

2425
constructor(
2526
host: string,
@@ -186,6 +187,17 @@ export default class EmbeddedChatApi {
186187
* TODO: Add logic to call thread message event listeners. To be done after thread implementation
187188
*/
188189
async connect() {
190+
// Guard against concurrent connect() calls (e.g. React StrictMode double-invoke)
191+
if (this._connectPromise) {
192+
return this._connectPromise;
193+
}
194+
this._connectPromise = this._doConnect().finally(() => {
195+
this._connectPromise = null;
196+
});
197+
return this._connectPromise;
198+
}
199+
200+
private async _doConnect() {
189201
try {
190202
await this.close(); // before connection, all previous subscriptions should be cancelled
191203
await this.rcClient.connect({});
@@ -198,7 +210,6 @@ export default class EmbeddedChatApi {
198210
}
199211
const message = JSON.parse(JSON.stringify(data));
200212
if (message.ts?.$date) {
201-
console.log(message.ts?.$date);
202213
message.ts = message.ts.$date;
203214
}
204215
if (!message.ts) {
@@ -683,14 +694,14 @@ export default class EmbeddedChatApi {
683694

684695
async sendTypingStatus(username: string, typing: boolean) {
685696
try {
686-
this.rcClient.methodCall(
697+
await this.rcClient.methodCall(
687698
"stream-notify-room",
688699
`${this.rid}/user-activity`,
689700
username,
690701
typing ? ["user-typing"] : []
691702
);
692703
} catch (err) {
693-
console.error(err);
704+
// DDP typing indicator fails when connection is temporarily down — expected, safe to ignore
694705
}
695706
}
696707

packages/auth/src/Api.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ export class Api {
4444
if (!response.ok) {
4545
throw new ApiError(response, "Failed Api Request for " + endpoint);
4646
}
47-
const jsonData = await response.json();
47+
const text = await response.text();
48+
const jsonData = text.length ? JSON.parse(text) : {};
4849
return { data: jsonData };
4950
}
5051

packages/auth/src/RocketChatAuth.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ class RocketChatAuth {
3636
async onAuthChange(callback: (user: object | null) => void) {
3737
this.authListeners.push(callback);
3838
const user = await this.getCurrentUser();
39-
callback(user);
39+
if (this.authListeners.includes(callback)) {
40+
callback(user);
41+
}
4042
}
4143

4244
async removeAuthListener(callback: (user: object | null) => void) {
@@ -72,6 +74,7 @@ class RocketChatAuth {
7274
}
7375
);
7476
this.setUser(response.data);
77+
this.notifyAuthListeners();
7578
return this.currentUser;
7679
}
7780

@@ -92,6 +95,7 @@ class RocketChatAuth {
9295
credentials
9396
);
9497
this.setUser(response.data);
98+
this.notifyAuthListeners();
9599
return this.currentUser;
96100
}
97101

@@ -107,6 +111,7 @@ class RocketChatAuth {
107111
api: this.api,
108112
});
109113
this.setUser(response.data);
114+
this.notifyAuthListeners();
110115
return this.currentUser;
111116
}
112117

@@ -190,10 +195,10 @@ class RocketChatAuth {
190195
try {
191196
const token = await this.getToken();
192197
if (token) {
193-
const user = await this.loginWithResumeToken(token); // will notifyAuthListeners on successful login
198+
const user = await this.loginWithResumeToken(token);
194199
if (user) {
195200
this.lastFetched = new Date();
196-
await this.getCurrentUser(); // refresh the token if needed
201+
await this.getCurrentUser();
197202
}
198203
}
199204
} catch (e) {

0 commit comments

Comments
 (0)