@prsm/realtime 1.0.1 → 1.0.3

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.
@@ -28,45 +28,45 @@ export class InstanceManager {
28
28
  }
29
29
 
30
30
  async _registerInstance() {
31
- await this.redis.sadd("mesh:instances", this.instanceId)
31
+ await this.redis.sadd("rt:instances", this.instanceId)
32
32
  }
33
33
 
34
34
  async _deregisterInstance() {
35
- await this.redis.srem("mesh:instances", this.instanceId)
36
- await this.redis.del(`mesh:instance:${this.instanceId}:heartbeat`)
35
+ await this.redis.srem("rt:instances", this.instanceId)
36
+ await this.redis.del(`rt:instance:${this.instanceId}:heartbeat`)
37
37
  }
38
38
 
39
39
  async _updateHeartbeat() {
40
- await this.redis.set(`mesh:instance:${this.instanceId}:heartbeat`, Date.now().toString(), "EX", this.heartbeatTTL)
40
+ await this.redis.set(`rt:instance:${this.instanceId}:heartbeat`, Date.now().toString(), "EX", this.heartbeatTTL)
41
41
  }
42
42
 
43
43
  async _acquireCleanupLock() {
44
- const result = await this.redis.set("mesh:cleanup:lock", this.instanceId, "EX", this.cleanupLockTTL, "NX")
44
+ const result = await this.redis.set("rt:cleanup:lock", this.instanceId, "EX", this.cleanupLockTTL, "NX")
45
45
  return result === "OK"
46
46
  }
47
47
 
48
48
  async _releaseCleanupLock() {
49
49
  const script = 'if redis.call("get", KEYS[1]) == ARGV[1] then return redis.call("del", KEYS[1]) else return 0 end'
50
- await this.redis.eval(script, 1, "mesh:cleanup:lock", this.instanceId)
50
+ await this.redis.eval(script, 1, "rt:cleanup:lock", this.instanceId)
51
51
  }
52
52
 
53
53
  async _performCleanup() {
54
54
  try {
55
55
  const lockAcquired = await this._acquireCleanupLock()
56
56
  if (!lockAcquired) return
57
- const registeredInstances = await this.redis.smembers("mesh:instances")
58
- const allConnections = await this.redis.hgetall("mesh:connections")
57
+ const registeredInstances = await this.redis.smembers("rt:instances")
58
+ const allConnections = await this.redis.hgetall("rt:connections")
59
59
  const instanceIds = new Set([...registeredInstances, ...Object.values(allConnections)])
60
60
  for (const instanceId of instanceIds) {
61
61
  if (instanceId === this.instanceId) continue
62
- const heartbeat = await this.redis.get(`mesh:instance:${instanceId}:heartbeat`)
62
+ const heartbeat = await this.redis.get(`rt:instance:${instanceId}:heartbeat`)
63
63
  if (!heartbeat) {
64
- serverLogger.info(`Found dead instance: ${instanceId}`)
64
+ serverLogger.info("found dead instance", { instanceId })
65
65
  await this._cleanupDeadInstance(instanceId)
66
66
  }
67
67
  }
68
68
  } catch (error) {
69
- serverLogger.error("Error during cleanup:", error)
69
+ serverLogger.error("error during cleanup", { err: error })
70
70
  } finally {
71
71
  await this._releaseCleanupLock()
72
72
  }
@@ -74,20 +74,20 @@ export class InstanceManager {
74
74
 
75
75
  async _cleanupDeadInstance(instanceId) {
76
76
  try {
77
- const connectionsKey = `mesh:connections:${instanceId}`
77
+ const connectionsKey = `rt:connections:${instanceId}`
78
78
  const connections = await this.redis.smembers(connectionsKey)
79
79
  for (const connectionId of connections) {
80
80
  await this._cleanupConnection(connectionId)
81
81
  }
82
- const allConnections = await this.redis.hgetall("mesh:connections")
82
+ const allConnections = await this.redis.hgetall("rt:connections")
83
83
  for (const [connectionId, connInstanceId] of Object.entries(allConnections)) {
84
84
  if (connInstanceId === instanceId) await this._cleanupConnection(connectionId)
85
85
  }
86
- await this.redis.srem("mesh:instances", instanceId)
86
+ await this.redis.srem("rt:instances", instanceId)
87
87
  await this.redis.del(connectionsKey)
88
- serverLogger.info(`Cleaned up dead instance: ${instanceId}`)
88
+ serverLogger.info("cleaned up dead instance", { instanceId })
89
89
  } catch (error) {
90
- serverLogger.error(`Error cleaning up instance ${instanceId}:`, error)
90
+ serverLogger.error("error cleaning up instance", { instanceId, err: error })
91
91
  }
92
92
  }
93
93
 
@@ -103,23 +103,23 @@ export class InstanceManager {
103
103
 
104
104
  async _cleanupConnection(connectionId) {
105
105
  try {
106
- const roomsKey = `mesh:connection:${connectionId}:rooms`
106
+ const roomsKey = `rt:connection:${connectionId}:rooms`
107
107
  const rooms = await this.redis.smembers(roomsKey)
108
108
  const pipeline = this.redis.pipeline()
109
109
  for (const room of rooms) {
110
- pipeline.srem(`mesh:room:${room}`, connectionId)
111
- pipeline.srem(`mesh:presence:room:${room}`, connectionId)
112
- pipeline.del(`mesh:presence:room:${room}:conn:${connectionId}`)
113
- pipeline.del(`mesh:presence:state:${room}:conn:${connectionId}`)
110
+ pipeline.srem(`rt:room:${room}`, connectionId)
111
+ pipeline.srem(`rt:presence:room:${room}`, connectionId)
112
+ pipeline.del(`rt:presence:room:${room}:conn:${connectionId}`)
113
+ pipeline.del(`rt:presence:state:${room}:conn:${connectionId}`)
114
114
  }
115
115
  pipeline.del(roomsKey)
116
- pipeline.hdel("mesh:connections", connectionId)
117
- pipeline.hdel("mesh:connection-meta", connectionId)
118
- await this._deleteMatchingKeys(`mesh:collection:*:${connectionId}`)
116
+ pipeline.hdel("rt:connections", connectionId)
117
+ pipeline.hdel("rt:connection-meta", connectionId)
118
+ await this._deleteMatchingKeys(`rt:collection:*:${connectionId}`)
119
119
  await pipeline.exec()
120
- serverLogger.debug(`Cleaned up stale connection: ${connectionId}`)
120
+ serverLogger.debug("cleaned up stale connection", { connectionId })
121
121
  } catch (error) {
122
- serverLogger.error(`Error cleaning up connection ${connectionId}:`, error)
122
+ serverLogger.error("error cleaning up connection", { connectionId, err: error })
123
123
  }
124
124
  }
125
125
  }
@@ -34,7 +34,7 @@ export class PersistenceManager extends EventEmitter {
34
34
 
35
35
  async _processPendingRecordUpdates() {
36
36
  if (this.pendingRecordUpdates.length === 0) return
37
- serverLogger.info(`Processing ${this.pendingRecordUpdates.length} pending record updates`)
37
+ serverLogger.info("processing pending record updates", { count: this.pendingRecordUpdates.length })
38
38
  const updates = [...this.pendingRecordUpdates]
39
39
  this.pendingRecordUpdates = []
40
40
  for (const { recordId, value, version } of updates) {
@@ -54,25 +54,25 @@ export class PersistenceManager extends EventEmitter {
54
54
  await this._processPendingRecordUpdates()
55
55
  this.emit("initialized")
56
56
  } catch (err) {
57
- serverLogger.error("Failed to initialize persistence manager:", err)
57
+ serverLogger.error("failed to initialize persistence manager", { err })
58
58
  throw err
59
59
  }
60
60
  }
61
61
 
62
62
  async restorePersistedRecords() {
63
63
  if (!this.recordManager) {
64
- serverLogger.warn("Cannot restore persisted records: record manager not available")
64
+ serverLogger.warn("cannot restore persisted records: record manager not available")
65
65
  return
66
66
  }
67
67
  const redis = this.recordManager.getRedis()
68
68
  if (!redis) {
69
- serverLogger.warn("Cannot restore records: Redis not available")
69
+ serverLogger.warn("cannot restore records: redis not available")
70
70
  return
71
71
  }
72
72
  try {
73
- serverLogger.info("Restoring persisted records...")
73
+ serverLogger.info("restoring persisted records")
74
74
  if (this.recordPatterns.length === 0) {
75
- serverLogger.info("No record patterns to restore")
75
+ serverLogger.info("no record patterns to restore")
76
76
  return
77
77
  }
78
78
  for (const config of this.recordPatterns) {
@@ -93,7 +93,7 @@ export class PersistenceManager extends EventEmitter {
93
93
  }))
94
94
  }
95
95
  if (records.length > 0) {
96
- serverLogger.info(`Restoring ${records.length} records for pattern ${patternLabel}`)
96
+ serverLogger.info("restoring records for pattern", { count: records.length, pattern: patternLabel })
97
97
  for (const record of records) {
98
98
  try {
99
99
  const { recordId, value, version } = record
@@ -104,17 +104,17 @@ export class PersistenceManager extends EventEmitter {
104
104
  pipeline.set(versionKey, version.toString())
105
105
  await pipeline.exec()
106
106
  } catch (parseErr) {
107
- serverLogger.error(`Failed to restore record ${record.recordId}: ${parseErr}`)
107
+ serverLogger.error("failed to restore record", { recordId: record.recordId, err: parseErr })
108
108
  }
109
109
  }
110
110
  }
111
111
  } catch (patternErr) {
112
- serverLogger.error(`Error restoring records for pattern ${patternLabel}: ${patternErr}`)
112
+ serverLogger.error("error restoring records for pattern", { pattern: patternLabel, err: patternErr })
113
113
  }
114
114
  }
115
- serverLogger.info("Finished restoring persisted records")
115
+ serverLogger.info("finished restoring persisted records")
116
116
  } catch (err) {
117
- serverLogger.error("Failed to restore persisted records:", err)
117
+ serverLogger.error("failed to restore persisted records", { err })
118
118
  }
119
119
  }
120
120
 
@@ -133,7 +133,7 @@ export class PersistenceManager extends EventEmitter {
133
133
  }
134
134
  if (fullOptions.adapter !== this.defaultAdapter && !this.isShuttingDown) {
135
135
  fullOptions.adapter.initialize().catch((err) => {
136
- serverLogger.error(`Failed to initialize adapter for pattern ${pattern}:`, err)
136
+ serverLogger.error("failed to initialize adapter for pattern", { pattern, err })
137
137
  })
138
138
  }
139
139
  this.channelPatterns.push({ pattern, options: fullOptions })
@@ -148,7 +148,7 @@ export class PersistenceManager extends EventEmitter {
148
148
  resolvedAdapter = { adapter: adapterInstance, restorePattern: adapter.restorePattern }
149
149
  if (adapterInstance !== this.defaultAdapter && !this.isShuttingDown) {
150
150
  adapterInstance.initialize().catch((err) => {
151
- serverLogger.error(`Failed to initialize adapter for record pattern ${pattern}:`, err)
151
+ serverLogger.error("failed to initialize adapter for record pattern", { pattern, err })
152
152
  })
153
153
  }
154
154
  }
@@ -220,7 +220,7 @@ export class PersistenceManager extends EventEmitter {
220
220
  await options.adapter.storeMessages(messages)
221
221
  this.emit("flushed", { channel, count: messages.length })
222
222
  } catch (err) {
223
- serverLogger.error(`Failed to flush messages for channel ${channel}:`, err)
223
+ serverLogger.error("failed to flush messages for channel", { channel, err })
224
224
  if (!this.isShuttingDown) {
225
225
  const currentMessages = this.messageBuffer.get(channel) || []
226
226
  this.messageBuffer.set(channel, [...messages, ...currentMessages])
@@ -295,7 +295,7 @@ export class PersistenceManager extends EventEmitter {
295
295
  }
296
296
  }
297
297
  const handleFlushError = (failedRecords, err) => {
298
- serverLogger.error("Failed to flush records:", err)
298
+ serverLogger.error("failed to flush records", { err })
299
299
  if (!this.isShuttingDown) {
300
300
  for (const record of failedRecords) this.recordBuffer.set(record.recordId, record)
301
301
  if (!this.recordFlushTimer) {
@@ -337,7 +337,7 @@ export class PersistenceManager extends EventEmitter {
337
337
  return await this.defaultAdapter.getRecords(pattern)
338
338
  }
339
339
  } catch (err) {
340
- serverLogger.error(`Failed to get persisted records for pattern ${pattern}:`, err)
340
+ serverLogger.error("failed to get persisted records for pattern", { pattern, err })
341
341
  }
342
342
  return []
343
343
  }
@@ -364,7 +364,7 @@ export class PersistenceManager extends EventEmitter {
364
364
  }
365
365
  for (const adapter of adapters) {
366
366
  try { await adapter.close() }
367
- catch (err) { serverLogger.error("Error closing persistence adapter:", err) }
367
+ catch (err) { serverLogger.error("error closing persistence adapter", { err }) }
368
368
  }
369
369
  this.initialized = false
370
370
  }
@@ -7,8 +7,8 @@ export class PresenceManager {
7
7
  this.redisManager = redisManager
8
8
  this.presenceExpirationEventsEnabled = enableExpirationEvents
9
9
 
10
- this.PRESENCE_KEY_PATTERN = /^mesh:presence:room:(.+):conn:(.+)$/
11
- this.PRESENCE_STATE_KEY_PATTERN = /^mesh:presence:state:(.+):conn:(.+)$/
10
+ this.PRESENCE_KEY_PATTERN = /^rt:presence:room:(.+):conn:(.+)$/
11
+ this.PRESENCE_STATE_KEY_PATTERN = /^rt:presence:state:(.+):conn:(.+)$/
12
12
  this.trackedRooms = []
13
13
  this.roomGuards = new Map()
14
14
  this.roomTTLs = new Map()
@@ -47,7 +47,7 @@ export class PresenceManager {
47
47
  await this._publishPresenceStateUpdate(match[1], match[2], null)
48
48
  }
49
49
  } catch (err) {
50
- serverLogger.error("[PresenceManager] Failed to handle expired key:", err)
50
+ serverLogger.error("failed to handle expired key", { key, err })
51
51
  }
52
52
  }
53
53
 
@@ -89,9 +89,9 @@ export class PresenceManager {
89
89
  return this.defaultTTL
90
90
  }
91
91
 
92
- presenceRoomKey(roomName) { return `mesh:presence:room:${roomName}` }
93
- presenceConnectionKey(roomName, connectionId) { return `mesh:presence:room:${roomName}:conn:${connectionId}` }
94
- presenceStateKey(roomName, connectionId) { return `mesh:presence:state:${roomName}:conn:${connectionId}` }
92
+ presenceRoomKey(roomName) { return `rt:presence:room:${roomName}` }
93
+ presenceConnectionKey(roomName, connectionId) { return `rt:presence:room:${roomName}:conn:${connectionId}` }
94
+ presenceStateKey(roomName, connectionId) { return `rt:presence:state:${roomName}:conn:${connectionId}` }
95
95
 
96
96
  async markOnline(connectionId, roomName) {
97
97
  const roomKey = this.presenceRoomKey(roomName)
@@ -137,7 +137,7 @@ export class PresenceManager {
137
137
  }
138
138
 
139
139
  async _publishPresenceUpdate(roomName, connectionId, type) {
140
- const channel = `mesh:presence:updates:${roomName}`
140
+ const channel = `rt:presence:updates:${roomName}`
141
141
  const message = JSON.stringify({ type, connectionId, roomName, timestamp: Date.now() })
142
142
  await this.redis.publish(channel, message)
143
143
  }
@@ -167,7 +167,7 @@ export class PresenceManager {
167
167
  const value = await this.redis.get(key)
168
168
  if (!value) return null
169
169
  try { return JSON.parse(value) }
170
- catch (e) { serverLogger.error(`[PresenceManager] Failed to parse presence state: ${e}`); return null }
170
+ catch (e) { serverLogger.error("failed to parse presence state", { err: e }); return null }
171
171
  }
172
172
 
173
173
  async getAllPresenceStates(roomName) {
@@ -186,13 +186,13 @@ export class PresenceManager {
186
186
  const [err, value] = responses[i] || []
187
187
  if (err || !value) continue
188
188
  try { result.set(connectionId, JSON.parse(value)) }
189
- catch (e) { serverLogger.error(`[PresenceManager] Failed to parse presence state: ${e}`) }
189
+ catch (e) { serverLogger.error("failed to parse presence state", { err: e }) }
190
190
  }
191
191
  return result
192
192
  }
193
193
 
194
194
  async _publishPresenceStateUpdate(roomName, connectionId, state) {
195
- const channel = `mesh:presence:updates:${roomName}`
195
+ const channel = `rt:presence:updates:${roomName}`
196
196
  const message = JSON.stringify({ type: "state", connectionId, roomName, state, timestamp: Date.now() })
197
197
  await this.redis.publish(channel, message)
198
198
  }
@@ -23,8 +23,8 @@ export class PubSubManager {
23
23
  subscribeToInstanceChannel() {
24
24
  const channel = `${PUB_SUB_CHANNEL_PREFIX}${this.instanceId}`
25
25
  this._subscriptionPromise = new Promise((resolve, reject) => {
26
- this.subClient.subscribe(channel, RECORD_PUB_SUB_CHANNEL, "mesh:collection:record-change")
27
- this.subClient.psubscribe("mesh:presence:updates:*", (err) => {
26
+ this.subClient.subscribe(channel, RECORD_PUB_SUB_CHANNEL, "rt:collection:record-change")
27
+ this.subClient.psubscribe("rt:presence:updates:*", (err) => {
28
28
  if (err) {
29
29
  this.emitError(new Error(`Failed to subscribe to channels/patterns: ${JSON.stringify({ cause: err })}`))
30
30
  reject(err)
@@ -43,14 +43,14 @@ export class PubSubManager {
43
43
  this._handleInstancePubSubMessage(channel, message)
44
44
  } else if (channel === RECORD_PUB_SUB_CHANNEL) {
45
45
  this._handleRecordUpdatePubSubMessage(message)
46
- } else if (channel === "mesh:collection:record-change") {
46
+ } else if (channel === "rt:collection:record-change") {
47
47
  this._handleCollectionRecordChange(message)
48
48
  } else {
49
49
  const subscribers = this.getChannelSubscriptions(channel)
50
50
  if (subscribers) {
51
51
  for (const connection of subscribers) {
52
52
  if (!connection.isDead) {
53
- connection.send({ command: "mesh/subscription-message", payload: { channel, message } })
53
+ connection.send({ command: "rt/subscription-message", payload: { channel, message } })
54
54
  }
55
55
  }
56
56
  }
@@ -58,14 +58,14 @@ export class PubSubManager {
58
58
  })
59
59
 
60
60
  this.subClient.on("pmessage", async (pattern, channel, message) => {
61
- if (pattern === "mesh:presence:updates:*") {
61
+ if (pattern === "rt:presence:updates:*") {
62
62
  const subscribers = this.getChannelSubscriptions(channel)
63
63
  if (subscribers) {
64
64
  try {
65
65
  const payload = JSON.parse(message)
66
66
  subscribers.forEach((connection) => {
67
67
  if (!connection.isDead) {
68
- connection.send({ command: "mesh/presence-update", payload })
68
+ connection.send({ command: "rt/presence-update", payload })
69
69
  } else {
70
70
  subscribers.delete(connection)
71
71
  }
@@ -105,11 +105,11 @@ export class PubSubManager {
105
105
  const connection = this.connectionManager.getLocalConnection(connectionId)
106
106
  if (connection && !connection.isDead) {
107
107
  if (deleted) {
108
- connection.send({ command: "mesh/record-deleted", payload: { recordId, version } })
108
+ connection.send({ command: "rt/record-deleted", payload: { recordId, version } })
109
109
  } else if (mode === "patch" && patch) {
110
- connection.send({ command: "mesh/record-update", payload: { recordId, patch, version } })
110
+ connection.send({ command: "rt/record-update", payload: { recordId, patch, version } })
111
111
  } else if (mode === "full" && newValue !== undefined) {
112
- connection.send({ command: "mesh/record-update", payload: { recordId, full: newValue, version } })
112
+ connection.send({ command: "rt/record-update", payload: { recordId, full: newValue, version } })
113
113
  }
114
114
  } else if (!connection || connection.isDead) {
115
115
  subscribers.delete(connectionId)
@@ -168,7 +168,7 @@ export class PubSubManager {
168
168
 
169
169
  const newRecords = await this.collectionManager.resolveCollection(collectionId, connection)
170
170
  const newRecordIds = newRecords.map((record) => record.id)
171
- const previousRecordIdsKey = `mesh:collection:${collectionId}:${connectionId}`
171
+ const previousRecordIdsKey = `rt:collection:${collectionId}:${connectionId}`
172
172
  const previousRecordIdsStr = await this.pubClient.get(previousRecordIdsKey)
173
173
  const previousRecordIds = previousRecordIdsStr ? JSON.parse(previousRecordIdsStr) : []
174
174
 
@@ -199,7 +199,7 @@ export class PubSubManager {
199
199
  this.collectionManager.updateSubscriptionVersion(collectionId, connectionId, newCollectionVersion)
200
200
  await this.pubClient.set(previousRecordIdsKey, JSON.stringify(newRecordIds))
201
201
  connection.send({
202
- command: "mesh/collection-diff",
202
+ command: "rt/collection-diff",
203
203
  payload: { collectionId, added, removed, version: newCollectionVersion },
204
204
  })
205
205
  }
@@ -209,10 +209,10 @@ export class PubSubManager {
209
209
  try {
210
210
  const { record, version } = await this.recordManager.getRecordAndVersion(recordId)
211
211
  if (record) {
212
- connection.send({ command: "mesh/record-update", payload: { recordId, version, full: record } })
212
+ connection.send({ command: "rt/record-update", payload: { recordId, version, full: record } })
213
213
  }
214
214
  } catch (recordError) {
215
- serverLogger.info(`Record ${recordId} not found during collection update (likely deleted).`)
215
+ serverLogger.info("record not found during collection update, likely deleted", { recordId })
216
216
  }
217
217
  }
218
218
  }
@@ -234,8 +234,8 @@ export class PubSubManager {
234
234
  if (this.subClient && this.subClient.status !== "end") {
235
235
  const channel = `${PUB_SUB_CHANNEL_PREFIX}${this.instanceId}`
236
236
  await Promise.all([
237
- new Promise((resolve) => { this.subClient.unsubscribe(channel, RECORD_PUB_SUB_CHANNEL, "mesh:collection:record-change", () => resolve()) }),
238
- new Promise((resolve) => { this.subClient.punsubscribe("mesh:presence:updates:*", () => resolve()) }),
237
+ new Promise((resolve) => { this.subClient.unsubscribe(channel, RECORD_PUB_SUB_CHANNEL, "rt:collection:record-change", () => resolve()) }),
238
+ new Promise((resolve) => { this.subClient.punsubscribe("rt:presence:updates:*", () => resolve()) }),
239
239
  ])
240
240
  }
241
241
  }
@@ -65,10 +65,10 @@ export class RecordManager {
65
65
  Promise.all(
66
66
  this.recordUpdateCallbacks.map(async (callback) => {
67
67
  try { await callback({ recordId, value: finalValue }) }
68
- catch (error) { serverLogger.error(`Error in record update callback for ${recordId}:`, error) }
68
+ catch (error) { serverLogger.error("error in record update callback", { recordId, err: error }) }
69
69
  })
70
70
  ).catch((error) => {
71
- serverLogger.error(`Error in record update callbacks for ${recordId}:`, error)
71
+ serverLogger.error("error in record update callbacks", { recordId, err: error })
72
72
  })
73
73
  }
74
74
 
@@ -88,10 +88,10 @@ export class RecordManager {
88
88
  Promise.all(
89
89
  this.recordRemovedCallbacks.map(async (callback) => {
90
90
  try { await callback({ recordId, value: record }) }
91
- catch (error) { serverLogger.error(`Error in record removed callback for ${recordId}:`, error) }
91
+ catch (error) { serverLogger.error("error in record removed callback", { recordId, err: error }) }
92
92
  })
93
93
  ).catch((error) => {
94
- serverLogger.error(`Error in record removed callbacks for ${recordId}:`, error)
94
+ serverLogger.error("error in record removed callbacks", { recordId, err: error })
95
95
  })
96
96
  }
97
97
 
@@ -5,9 +5,9 @@ export class RoomManager {
5
5
  this.redis = redis
6
6
  }
7
7
 
8
- roomKey(roomName) { return `mesh:room:${roomName}` }
9
- connectionsRoomKey(connectionId) { return `mesh:connection:${connectionId}:rooms` }
10
- roomMetadataKey(roomName) { return `mesh:roommeta:${roomName}` }
8
+ roomKey(roomName) { return `rt:room:${roomName}` }
9
+ connectionsRoomKey(connectionId) { return `rt:connection:${connectionId}:rooms` }
10
+ roomMetadataKey(roomName) { return `rt:roommeta:${roomName}` }
11
11
 
12
12
  async getRoomConnectionIds(roomName) {
13
13
  return this.redis.smembers(this.roomKey(roomName))
@@ -30,8 +30,8 @@ export class RoomManager {
30
30
  }
31
31
 
32
32
  async getAllRooms() {
33
- const keys = await this.redis.keys("mesh:room:*")
34
- return keys.map((key) => key.replace("mesh:room:", ""))
33
+ const keys = await this.redis.keys("rt:room:*")
34
+ return keys.map((key) => key.replace("rt:room:", ""))
35
35
  }
36
36
 
37
37
  async removeFromRoom(roomName, connection) {
@@ -110,18 +110,18 @@ export class RoomManager {
110
110
  }
111
111
 
112
112
  async getAllMetadata() {
113
- const keys = await this.redis.keys("mesh:roommeta:*")
113
+ const keys = await this.redis.keys("rt:roommeta:*")
114
114
  const result = []
115
115
  if (keys.length === 0) return result
116
116
  const pipeline = this.redis.pipeline()
117
117
  keys.forEach((key) => pipeline.hget(key, "data"))
118
118
  const results = await pipeline.exec()
119
119
  keys.forEach((key, index) => {
120
- const roomName = key.replace("mesh:roommeta:", "")
120
+ const roomName = key.replace("rt:roommeta:", "")
121
121
  const data = results?.[index]?.[1]
122
122
  if (data) {
123
123
  try { result.push({ id: roomName, metadata: JSON.parse(data) }) }
124
- catch (e) { serverLogger.error(`Failed to parse metadata for room ${roomName}:`, e) }
124
+ catch (e) { serverLogger.error("failed to parse metadata for room", { roomName, err: e }) }
125
125
  }
126
126
  })
127
127
  return result