shuttlepro-shared 1.1.74 → 1.1.76

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/config/socket.js CHANGED
@@ -1,48 +1,88 @@
1
1
  const { Server } = require("socket.io");
2
- const { publisher, subscriber, connectRedis } = require("./redis"); // Use separate Redis Pub/Sub clients
2
+ const { publisher, subscriber, connectRedis } = require("./redis");
3
3
  require("dotenv").config();
4
4
 
5
5
  let io;
6
6
  const namespaceSockets = {}; // Store different namespace sockets
7
7
 
8
+ /**
9
+ * Initialize Socket.IO server with namespaces
10
+ * @param {http.Server} server - HTTP server instance
11
+ * @param {string} namespaceParam - Socket namespace name (default: "conversation")
12
+ * @param {string} redisChannel - Redis channel for this namespace (default: "socket_events")
13
+ * @returns {SocketIO.Namespace} - The initialized namespace
14
+ */
8
15
  const initializeSocket = async (
9
16
  server,
10
17
  namespaceParam = "conversation",
11
18
  redisChannel = "socket_events"
12
19
  ) => {
20
+ // Initialize Socket.IO server if not already done
13
21
  if (!io) {
14
22
  io = new Server(server, {
15
- cors: { origin: "*" },
23
+ cors: {
24
+ origin: "*",
25
+ methods: ["GET", "POST"],
26
+ },
16
27
  });
28
+ console.log("✅ Socket.IO server initialized");
17
29
  }
18
30
 
19
31
  // Return existing namespace if already initialized
20
32
  if (namespaceSockets[namespaceParam]) {
33
+ console.log(`📢 Using existing namespace: /${namespaceParam}`);
21
34
  return namespaceSockets[namespaceParam];
22
35
  }
23
36
 
24
- // Create and store namespace
37
+ // Create and store new namespace
25
38
  const namespace = io.of(`/${namespaceParam}`);
26
39
  namespaceSockets[namespaceParam] = namespace;
40
+ console.log(`🚀 Created new namespace: /${namespaceParam}`);
27
41
 
28
42
  // Ensure Redis is connected
29
43
  await connectRedis();
30
44
 
45
+ // Create a unique Redis channel for this namespace
46
+ const nsRedisChannel = `${redisChannel}_${namespaceParam}`;
47
+
31
48
  // Subscribe to Redis events for this namespace
32
- await subscriber.subscribe(redisChannel, (message) => {
49
+ await subscriber.subscribe(nsRedisChannel, (messageStr) => {
33
50
  try {
34
- const { workspaceId, event, data } = JSON.parse(message);
35
- namespace.to(workspaceId).emit(event, data);
51
+ const message = JSON.parse(messageStr);
52
+ const { workspaceId, event, data } = message;
53
+
54
+ console.log(`📥 Redis message received on ${nsRedisChannel}:`, {
55
+ workspaceId,
56
+ event,
57
+ });
58
+
59
+ // Emit to specific workspace room in this namespace
60
+ if (workspaceId) {
61
+ namespace.to(workspaceId).emit(event, data);
62
+ console.log(
63
+ `📢 Event ${event} emitted to workspace ${workspaceId} in /${namespaceParam}`
64
+ );
65
+ } else {
66
+ // Broadcast to all clients in this namespace if no workspaceId specified
67
+ namespace.emit(event, data);
68
+ console.log(
69
+ `📢 Event ${event} broadcasted to all clients in /${namespaceParam}`
70
+ );
71
+ }
36
72
  } catch (err) {
37
- console.error("❌ Error parsing Redis message:", err);
73
+ console.error(
74
+ `❌ Error handling Redis message on ${nsRedisChannel}:`,
75
+ err
76
+ );
38
77
  }
39
78
  });
40
79
 
41
- // Handle new socket connections
80
+ // Handle new socket connections to this namespace
42
81
  namespace.on("connection", (socket) => {
43
82
  const { workspaceId } = socket.handshake.query;
44
83
 
45
84
  if (!workspaceId) {
85
+ console.warn(`⚠️ Connection rejected: No workspaceId provided`);
46
86
  socket.disconnect(true);
47
87
  return;
48
88
  }
@@ -51,43 +91,81 @@ const initializeSocket = async (
51
91
  `✅ Client connected: ${socket.id} (Workspace: ${workspaceId}) in /${namespaceParam}`
52
92
  );
53
93
 
54
- socket.join(workspaceId); // Join workspace room
94
+ // Join workspace room
95
+ socket.join(workspaceId);
96
+
97
+ // Send connection confirmation to client
98
+ socket.emit("connected", {
99
+ status: "connected",
100
+ socketId: socket.id,
101
+ namespace: namespaceParam,
102
+ workspaceId,
103
+ });
104
+
105
+ // Handle custom events from clients
106
+ socket.on("client_event", (data) => {
107
+ console.log(`📥 Client event from ${socket.id}:`, data);
108
+ // You can process client events here
109
+ });
55
110
 
56
- socket.on("disconnect", () => {
111
+ // Handle disconnect
112
+ socket.on("disconnect", (reason) => {
57
113
  console.log(
58
- `❌ Client disconnected: ${socket.id} (Workspace: ${workspaceId})`
114
+ `❌ Client disconnected: ${socket.id} (Workspace: ${workspaceId}, Reason: ${reason})`
59
115
  );
60
116
  socket.leave(workspaceId);
61
117
  });
118
+
119
+ // Handle errors
120
+ socket.on("error", (error) => {
121
+ console.error(`❌ Socket error for ${socket.id}:`, error);
122
+ });
62
123
  });
63
124
 
125
+ console.log(
126
+ `✅ Namespace /${namespaceParam} initialized and listening on Redis channel: ${nsRedisChannel}`
127
+ );
64
128
  return namespace;
65
129
  };
66
130
 
67
131
  /**
68
- * Publish Event to Redis Channel
69
- * @param {object} params - Event data
132
+ * Send event to clients via Redis pub/sub
133
+ * @param {object} params - Event parameters
70
134
  * @param {string} params.workspaceId - Target workspace ID
71
135
  * @param {string} params.event - Event name
72
- * @param {any} params.data - Event data
73
- * @param {string} [params.redisChannel="socket_events"] - Redis channel (optional)
136
+ * @param {any} params.data - Event data payload
137
+ * @param {string} [params.namespace="conversation"] - Target namespace
138
+ * @param {string} [params.redisChannel="socket_events"] - Base Redis channel
139
+ * @returns {Promise<void>}
74
140
  */
75
141
  const sendEventToServer = async ({
76
142
  workspaceId,
77
143
  event,
78
144
  data,
145
+ namespace = "conversation",
79
146
  redisChannel = "socket_events",
80
147
  }) => {
81
148
  try {
82
- await publisher.publish(
83
- redisChannel,
84
- JSON.stringify({ workspaceId, event, data })
85
- );
149
+ // Create namespace-specific Redis channel
150
+ const nsRedisChannel = `${redisChannel}_${namespace}`;
151
+
152
+ // Ensure Redis is connected
153
+ await connectRedis();
154
+
155
+ // Create message payload
156
+ const message = JSON.stringify({ workspaceId, event, data });
157
+
158
+ // Publish to Redis
159
+ await publisher.publish(nsRedisChannel, message);
160
+
86
161
  console.log(
87
- `📢 Event published to Redis: ${event} (Workspace: ${workspaceId})`
162
+ `📢 Event published to Redis channel ${nsRedisChannel}: ${event} (Workspace: ${workspaceId})`
88
163
  );
164
+
165
+ return true;
89
166
  } catch (err) {
90
167
  console.error("❌ Error publishing to Redis:", err);
168
+ throw err;
91
169
  }
92
170
  };
93
171
 
package/models/Profile.js CHANGED
@@ -89,7 +89,14 @@ const createProfile = async (obj) => {
89
89
  };
90
90
  const createUpdateProfileModified = async (filter, obj) => {
91
91
  try {
92
- let profile = await Profile.findOneAndUpdate(filter, obj, { new: true });
92
+ let profile = await Profile.findOneAndUpdate(
93
+ filter,
94
+ { ...obj, ...filter },
95
+ {
96
+ new: true,
97
+ upsert: true,
98
+ }
99
+ );
93
100
  await addOrUpdateProfilesInRedis(profile);
94
101
  return profile;
95
102
  } catch (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shuttlepro-shared",
3
- "version": "1.1.74",
3
+ "version": "1.1.76",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {