payload-socket-plugin 1.1.4 → 1.1.5

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/README.md CHANGED
@@ -434,6 +434,43 @@ import type {
434
434
  - Check that your `tsconfig.json` includes the plugin's types
435
435
  - Verify Payload CMS version compatibility (>= 2.0.0)
436
436
 
437
+ ## Multi-Instance Deployments with Redis
438
+
439
+ When using Redis adapter for multi-instance deployments, user data is automatically synchronized across all server instances:
440
+
441
+ - **`socket.data.user`**: Automatically synchronized across servers via Redis adapter
442
+ - **`socket.user`**: Only available on the local server where the socket connected (backward compatibility)
443
+
444
+ ### Accessing User Data in Custom Handlers
445
+
446
+ ```typescript
447
+ socketPlugin({
448
+ onSocketConnection: (socket, io, payload) => {
449
+ socket.on("get-active-users", async (roomName) => {
450
+ const sockets = await io.in(roomName).fetchSockets();
451
+
452
+ const users = sockets.map((s) => {
453
+ // Use socket.data.user for Redis compatibility (works across all servers)
454
+ // Fallback to socket.user for local connections
455
+ const user = s.data.user || (s as any).user;
456
+ return {
457
+ id: user?.id,
458
+ email: user?.email,
459
+ };
460
+ });
461
+
462
+ socket.emit("active-users", users);
463
+ });
464
+ },
465
+ });
466
+ ```
467
+
468
+ **Important**: When using `io.in(room).fetchSockets()` with Redis adapter:
469
+
470
+ - Remote sockets (from other servers) will have `socket.data.user` populated
471
+ - Local sockets will have both `socket.data.user` and `socket.user` populated
472
+ - Always check `socket.data.user` first for Redis compatibility
473
+
437
474
  ## Performance Considerations
438
475
 
439
476
  - **Redis**: Highly recommended for production multi-instance deployments
@@ -100,13 +100,17 @@ class SocketIOManager {
100
100
  if (!userDoc) {
101
101
  return next(new Error("User not found"));
102
102
  }
103
- // Attach user info
104
- socket.user = {
103
+ const userInfo = {
105
104
  id: userDoc.id,
106
105
  email: userDoc.email,
107
106
  collection: decoded.collection || "users",
108
107
  role: userDoc.role,
109
108
  };
109
+ // Store in socket.data for Redis adapter compatibility
110
+ // socket.data is automatically synchronized across servers via Redis
111
+ socket.data.user = userInfo;
112
+ // Also attach to socket.user for backward compatibility
113
+ socket.user = userInfo;
110
114
  next();
111
115
  }
112
116
  catch (jwtError) {
@@ -190,8 +194,10 @@ class SocketIOManager {
190
194
  const sockets = await this.io.in(room).fetchSockets();
191
195
  for (const socket of sockets) {
192
196
  const authSocket = socket;
193
- if (authSocket.user) {
194
- const isAuthorized = await collectionHandler(authSocket.user, finalEvent);
197
+ // Use socket.data.user for remote sockets (Redis adapter), fallback to socket.user for local
198
+ const user = socket.data.user || authSocket.user;
199
+ if (user) {
200
+ const isAuthorized = await collectionHandler(user, finalEvent);
195
201
  if (isAuthorized) {
196
202
  socket.emit("payload:event", finalEvent);
197
203
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "payload-socket-plugin",
3
- "version": "1.1.4",
3
+ "version": "1.1.5",
4
4
  "description": "Real-time Socket.IO plugin for Payload CMS with Redis support",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",