@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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prsm/realtime",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Distributed WebSocket framework with Redis-backed rooms, records, presence, channels, collections, and persistence",
5
5
  "type": "module",
6
6
  "license": "ISC",
@@ -20,6 +20,7 @@
20
20
  "node": ">=20"
21
21
  },
22
22
  "dependencies": {
23
+ "@prsm/log": "^1.0.1",
23
24
  "eventemitter3": "^5.0.1",
24
25
  "fast-json-patch": "^3.1.1",
25
26
  "ioredis": "^5.6.1",
@@ -5,9 +5,9 @@ export function createPostgresAdapter(options = {}) {
5
5
  const opts = {
6
6
  host: "localhost",
7
7
  port: 5432,
8
- database: "mesh_test",
9
- user: "mesh",
10
- password: "mesh_password",
8
+ database: "realtime_test",
9
+ user: "realtime",
10
+ password: "realtime_password",
11
11
  max: 10,
12
12
  ...options,
13
13
  }
@@ -49,7 +49,7 @@ export function createPostgresAdapter(options = {}) {
49
49
  await createTables()
50
50
  initialized = true
51
51
  } catch (err) {
52
- serverLogger.error("Error initializing PostgreSQL database:", err)
52
+ serverLogger.error("error initializing postgresql database", { err })
53
53
  throw err
54
54
  }
55
55
  },
@@ -1,6 +1,6 @@
1
1
  import { EventEmitter } from "eventemitter3"
2
2
  import { Connection } from "./connection.js"
3
- import { clientLogger, CodeError, LogLevel, Status } from "../shared/index.js"
3
+ import { clientLogger, configureLogLevel, CodeError, LogLevel, Status } from "../shared/index.js"
4
4
  import { createRecordSubscriptions } from "./subscriptions/records.js"
5
5
  import { createChannelSubscriptions } from "./subscriptions/channels.js"
6
6
  import { createPresenceSubscriptions } from "./subscriptions/presence.js"
@@ -43,7 +43,7 @@ export class RealtimeClient extends EventEmitter {
43
43
  logLevel: opts.logLevel ?? LogLevel.ERROR,
44
44
  }
45
45
 
46
- clientLogger.configure({ level: this.options.logLevel, styling: true })
46
+ configureLogLevel(this.options.logLevel)
47
47
 
48
48
  this.recordSubscriptions = new Map()
49
49
  this.collectionSubscriptions = new Map()
@@ -169,13 +169,13 @@ export class RealtimeClient extends EventEmitter {
169
169
  async getConnectionMetadata(connectionId) {
170
170
  try {
171
171
  if (connectionId) {
172
- const result = await this.command("mesh/get-connection-metadata", { connectionId })
172
+ const result = await this.command("rt/get-connection-metadata", { connectionId })
173
173
  return result.metadata
174
174
  }
175
- const result = await this.command("mesh/get-my-connection-metadata")
175
+ const result = await this.command("rt/get-my-connection-metadata")
176
176
  return result.metadata
177
177
  } catch (error) {
178
- clientLogger.error(`Failed to get metadata for connection:`, error)
178
+ clientLogger.error("failed to get metadata for connection", { err: error })
179
179
  return null
180
180
  }
181
181
  }
@@ -187,10 +187,10 @@ export class RealtimeClient extends EventEmitter {
187
187
  */
188
188
  async setConnectionMetadata(metadata, options) {
189
189
  try {
190
- const result = await this.command("mesh/set-my-connection-metadata", { metadata, options })
190
+ const result = await this.command("rt/set-my-connection-metadata", { metadata, options })
191
191
  return result.success
192
192
  } catch (error) {
193
- clientLogger.error(`Failed to set metadata for connection:`, error)
193
+ clientLogger.error("failed to set metadata for connection", { err: error })
194
194
  return false
195
195
  }
196
196
  }
@@ -199,11 +199,11 @@ export class RealtimeClient extends EventEmitter {
199
199
  this.connection.on("message", (data) => {
200
200
  this.emit("message", data)
201
201
 
202
- if (data.command === "mesh/record-update") this._records.handleUpdate(data.payload)
203
- else if (data.command === "mesh/record-deleted") this._records.handleDeleted(data.payload)
204
- else if (data.command === "mesh/presence-update") this._presence.handleUpdate(data.payload)
205
- else if (data.command === "mesh/subscription-message") this._channels.handleMessage(data.payload)
206
- else if (data.command === "mesh/collection-diff") this._collections.handleDiff(data.payload)
202
+ if (data.command === "rt/record-update") this._records.handleUpdate(data.payload)
203
+ else if (data.command === "rt/record-deleted") this._records.handleDeleted(data.payload)
204
+ else if (data.command === "rt/presence-update") this._presence.handleUpdate(data.payload)
205
+ else if (data.command === "rt/subscription-message") this._channels.handleMessage(data.payload)
206
+ else if (data.command === "rt/collection-diff") this._collections.handleDiff(data.payload)
207
207
  else {
208
208
  const systemCommands = ["ping", "pong", "latency", "latency:request", "latency:response"]
209
209
  if (data.command && !systemCommands.includes(data.command)) {
@@ -238,9 +238,9 @@ export class RealtimeClient extends EventEmitter {
238
238
  this._lastActivityTime = Date.now()
239
239
  if (eventName === "visibilitychange" && doc.visibilityState === "visible") {
240
240
  if (this._status === Status.OFFLINE) return
241
- this.command("mesh/noop", {}, 5000)
242
- .then(() => { clientLogger.info("Tab visible, connection ok"); this.emit("republish") })
243
- .catch(() => { clientLogger.info("Tab visible, forcing reconnect"); this._forceReconnect() })
241
+ this.command("rt/noop", {}, 5000)
242
+ .then(() => { clientLogger.info("tab visible, connection ok"); this.emit("republish") })
243
+ .catch(() => { clientLogger.info("tab visible, forcing reconnect"); this._forceReconnect() })
244
244
  }
245
245
  })
246
246
  })
@@ -253,8 +253,8 @@ export class RealtimeClient extends EventEmitter {
253
253
  const now = Date.now()
254
254
  const timeSinceActivity = now - this._lastActivityTime
255
255
  if (timeSinceActivity > this.options.pingTimeout && this._status === Status.ONLINE) {
256
- this.command("mesh/noop", {}, 5000).catch(() => {
257
- clientLogger.info(`No activity for ${timeSinceActivity}ms, forcing reconnect`)
256
+ this.command("rt/noop", {}, 5000).catch(() => {
257
+ clientLogger.info("no activity, forcing reconnect", { timeSinceActivity })
258
258
  this._forceReconnect()
259
259
  })
260
260
  }
@@ -325,7 +325,7 @@ export class RealtimeClient extends EventEmitter {
325
325
  this.missedPings++
326
326
  if (this.missedPings > this.options.maxMissedPings) {
327
327
  if (this.options.shouldReconnect) {
328
- clientLogger.warn(`Missed ${this.missedPings} pings, reconnecting...`)
328
+ clientLogger.warn("missed pings, reconnecting", { missedPings: this.missedPings })
329
329
  this.reconnect()
330
330
  }
331
331
  } else {
@@ -418,7 +418,7 @@ export class RealtimeClient extends EventEmitter {
418
418
  }
419
419
 
420
420
  async _resubscribeAll() {
421
- clientLogger.info("Resubscribing to all subscriptions after reconnect")
421
+ clientLogger.info("resubscribing to all subscriptions after reconnect")
422
422
  try {
423
423
  const successfulRooms = await this._rooms.resubscribe()
424
424
  await Promise.allSettled([
@@ -430,12 +430,12 @@ export class RealtimeClient extends EventEmitter {
430
430
  if (successfulRooms.length > 0) {
431
431
  for (const roomName of successfulRooms) {
432
432
  try { await this._presence.forceUpdate(roomName) }
433
- catch (err) { clientLogger.error(`Error refreshing presence for room ${roomName}:`, err) }
433
+ catch (err) { clientLogger.error("error refreshing presence for room", { roomName, err }) }
434
434
  await new Promise((resolve) => setTimeout(resolve, 50))
435
435
  }
436
436
  }
437
437
  } catch (error) {
438
- clientLogger.error("Error during resubscription:", error)
438
+ clientLogger.error("error during resubscription", { err: error })
439
439
  }
440
440
  }
441
441
  }
@@ -91,7 +91,7 @@ export class Connection extends EventEmitter {
91
91
 
92
92
  this.emit("message", data);
93
93
 
94
- if (data.command === "mesh/assign-id") {
94
+ if (data.command === "rt/assign-id") {
95
95
  this.connectionId = data.payload;
96
96
  this.emit("id-assigned", data.payload);
97
97
  } else if (data.command === "latency:request") {
@@ -10,7 +10,7 @@ export function createChannelSubscriptions(client) {
10
10
  try {
11
11
  await subscription.callback(message)
12
12
  } catch (error) {
13
- clientLogger.error(`Error in channel callback for ${channel}:`, error)
13
+ clientLogger.error("error in channel callback", { channel, err: error })
14
14
  }
15
15
  }
16
16
  }
@@ -23,7 +23,7 @@ export function createChannelSubscriptions(client) {
23
23
  */
24
24
  async function subscribe(channel, callback, options) {
25
25
  subscriptions.set(channel, { callback, historyLimit: options?.historyLimit })
26
- const result = await client.command("mesh/subscribe-channel", {
26
+ const result = await client.command("rt/subscribe-channel", {
27
27
  channel,
28
28
  historyLimit: options?.historyLimit,
29
29
  since: options?.since,
@@ -40,7 +40,7 @@ export function createChannelSubscriptions(client) {
40
40
  */
41
41
  function unsubscribe(channel) {
42
42
  subscriptions.delete(channel)
43
- return client.command("mesh/unsubscribe-channel", { channel })
43
+ return client.command("rt/unsubscribe-channel", { channel })
44
44
  }
45
45
 
46
46
  /**
@@ -50,14 +50,14 @@ export function createChannelSubscriptions(client) {
50
50
  */
51
51
  async function getHistory(channel, options) {
52
52
  try {
53
- const result = await client.command("mesh/get-channel-history", {
53
+ const result = await client.command("rt/get-channel-history", {
54
54
  channel,
55
55
  limit: options?.limit,
56
56
  since: options?.since,
57
57
  })
58
58
  return { success: result.success, history: result.history || [] }
59
59
  } catch (error) {
60
- clientLogger.error(`Failed to get history for channel ${channel}:`, error)
60
+ clientLogger.error("failed to get history for channel", { channel, err: error })
61
61
  return { success: false, history: [] }
62
62
  }
63
63
  }
@@ -68,7 +68,7 @@ export function createChannelSubscriptions(client) {
68
68
  await subscribe(channel, callback, { historyLimit })
69
69
  return true
70
70
  } catch (error) {
71
- clientLogger.error(`Failed to resubscribe to channel ${channel}:`, error)
71
+ clientLogger.error("failed to resubscribe to channel", { channel, err: error })
72
72
  return false
73
73
  }
74
74
  })
@@ -9,9 +9,7 @@ export function createCollectionSubscriptions(client) {
9
9
  if (!subscription) return
10
10
 
11
11
  if (version !== subscription.version + 1) {
12
- clientLogger.warn(
13
- `Desync detected for collection ${collectionId}. Expected version ${subscription.version + 1}, got ${version}. Resubscribing.`
14
- )
12
+ clientLogger.warn("desync detected for collection, resubscribing", { collectionId, expected: subscription.version + 1, got: version })
15
13
  await unsubscribe(collectionId)
16
14
  await subscribe(collectionId, { onDiff: subscription.onDiff })
17
15
  return
@@ -30,7 +28,7 @@ export function createCollectionSubscriptions(client) {
30
28
  version,
31
29
  })
32
30
  } catch (error) {
33
- clientLogger.error(`Error in collection diff callback for ${collectionId}:`, error)
31
+ clientLogger.error("error in collection diff callback", { collectionId, err: error })
34
32
  }
35
33
  }
36
34
  }
@@ -42,7 +40,7 @@ export function createCollectionSubscriptions(client) {
42
40
  */
43
41
  async function subscribe(collectionId, options = {}) {
44
42
  try {
45
- const result = await client.command("mesh/subscribe-collection", { collectionId })
43
+ const result = await client.command("rt/subscribe-collection", { collectionId })
46
44
  if (result.success) {
47
45
  subscriptions.set(collectionId, {
48
46
  ids: new Set(result.ids),
@@ -53,13 +51,13 @@ export function createCollectionSubscriptions(client) {
53
51
  try {
54
52
  await options.onDiff({ added: result.records, removed: [], changed: [], version: result.version })
55
53
  } catch (error) {
56
- clientLogger.error(`Error in initial collection diff callback for ${collectionId}:`, error)
54
+ clientLogger.error("error in initial collection diff callback", { collectionId, err: error })
57
55
  }
58
56
  }
59
57
  }
60
58
  return { success: result.success, ids: result.ids || [], records: result.records || [], version: result.version || 0 }
61
59
  } catch (error) {
62
- clientLogger.error(`Failed to subscribe to collection ${collectionId}:`, error)
60
+ clientLogger.error("failed to subscribe to collection", { collectionId, err: error })
63
61
  return { success: false, ids: [], records: [], version: 0 }
64
62
  }
65
63
  }
@@ -70,11 +68,11 @@ export function createCollectionSubscriptions(client) {
70
68
  */
71
69
  async function unsubscribe(collectionId) {
72
70
  try {
73
- const success = await client.command("mesh/unsubscribe-collection", { collectionId })
71
+ const success = await client.command("rt/unsubscribe-collection", { collectionId })
74
72
  if (success) subscriptions.delete(collectionId)
75
73
  return success
76
74
  } catch (error) {
77
- clientLogger.error(`Failed to unsubscribe from collection ${collectionId}:`, error)
75
+ clientLogger.error("failed to unsubscribe from collection", { collectionId, err: error })
78
76
  return false
79
77
  }
80
78
  }
@@ -85,7 +83,7 @@ export function createCollectionSubscriptions(client) {
85
83
  await subscribe(collectionId, { onDiff: subscription.onDiff })
86
84
  return true
87
85
  } catch (error) {
88
- clientLogger.error(`Failed to resubscribe to collection ${collectionId}:`, error)
86
+ clientLogger.error("failed to resubscribe to collection", { collectionId, err: error })
89
87
  return false
90
88
  }
91
89
  })
@@ -16,14 +16,14 @@ export function createPresenceSubscriptions(client) {
16
16
  */
17
17
  async function subscribe(roomName, callback) {
18
18
  try {
19
- const result = await client.command("mesh/subscribe-presence", { roomName })
19
+ const result = await client.command("rt/subscribe-presence", { roomName })
20
20
  if (result.success) {
21
21
  subscriptions.set(roomName, callback)
22
22
  if (result.present && result.present.length > 0) await callback(result)
23
23
  }
24
24
  return { success: result.success, present: result.present || [], states: result.states || {} }
25
25
  } catch (error) {
26
- clientLogger.error(`Failed to subscribe to presence for room ${roomName}:`, error)
26
+ clientLogger.error("failed to subscribe to presence for room", { roomName, err: error })
27
27
  return { success: false, present: [] }
28
28
  }
29
29
  }
@@ -34,11 +34,11 @@ export function createPresenceSubscriptions(client) {
34
34
  */
35
35
  async function unsubscribe(roomName) {
36
36
  try {
37
- const success = await client.command("mesh/unsubscribe-presence", { roomName })
37
+ const success = await client.command("rt/unsubscribe-presence", { roomName })
38
38
  if (success) subscriptions.delete(roomName)
39
39
  return success
40
40
  } catch (error) {
41
- clientLogger.error(`Failed to unsubscribe from presence for room ${roomName}:`, error)
41
+ clientLogger.error("failed to unsubscribe from presence for room", { roomName, err: error })
42
42
  return false
43
43
  }
44
44
  }
@@ -50,14 +50,14 @@ export function createPresenceSubscriptions(client) {
50
50
  */
51
51
  async function publishState(roomName, options) {
52
52
  try {
53
- return await client.command("mesh/publish-presence-state", {
53
+ return await client.command("rt/publish-presence-state", {
54
54
  roomName,
55
55
  state: options.state,
56
56
  expireAfter: options.expireAfter,
57
57
  silent: options.silent,
58
58
  })
59
59
  } catch (error) {
60
- clientLogger.error(`Failed to publish presence state for room ${roomName}:`, error)
60
+ clientLogger.error("failed to publish presence state for room", { roomName, err: error })
61
61
  return false
62
62
  }
63
63
  }
@@ -68,9 +68,9 @@ export function createPresenceSubscriptions(client) {
68
68
  */
69
69
  async function clearState(roomName) {
70
70
  try {
71
- return await client.command("mesh/clear-presence-state", { roomName })
71
+ return await client.command("rt/clear-presence-state", { roomName })
72
72
  } catch (error) {
73
- clientLogger.error(`Failed to clear presence state for room ${roomName}:`, error)
73
+ clientLogger.error("failed to clear presence state for room", { roomName, err: error })
74
74
  return false
75
75
  }
76
76
  }
@@ -79,8 +79,8 @@ export function createPresenceSubscriptions(client) {
79
79
  try {
80
80
  const handler = subscriptions.get(roomName)
81
81
  if (!handler) return false
82
- const result = await client.command("mesh/get-presence-state", { roomName }, 5000).catch((err) => {
83
- clientLogger.error(`Failed to get presence state for room ${roomName}:`, err)
82
+ const result = await client.command("rt/get-presence-state", { roomName }, 5000).catch((err) => {
83
+ clientLogger.error("failed to get presence state for room", { roomName, err })
84
84
  return { success: false }
85
85
  })
86
86
  if (!result.success) return false
@@ -89,7 +89,7 @@ export function createPresenceSubscriptions(client) {
89
89
  }
90
90
  return true
91
91
  } catch (error) {
92
- clientLogger.error(`Failed to force presence update for room ${roomName}:`, error)
92
+ clientLogger.error("failed to force presence update for room", { roomName, err: error })
93
93
  return false
94
94
  }
95
95
  }
@@ -16,7 +16,7 @@ export function createRecordSubscriptions(client) {
16
16
  version,
17
17
  })
18
18
  } catch (error) {
19
- clientLogger.error(`Error in collection record update callback for ${collectionId}:`, error)
19
+ clientLogger.error("error in collection record update callback", { collectionId, err: error })
20
20
  }
21
21
  }
22
22
  }
@@ -26,9 +26,7 @@ export function createRecordSubscriptions(client) {
26
26
 
27
27
  if (patch) {
28
28
  if (version !== subscription.localVersion + 1) {
29
- clientLogger.warn(
30
- `Desync detected for record ${recordId}. Expected version ${subscription.localVersion + 1}, got ${version}. Resubscribing to request full record.`
31
- )
29
+ clientLogger.warn("desync detected for record, resubscribing", { recordId, expected: subscription.localVersion + 1, got: version })
32
30
  await unsubscribe(recordId)
33
31
  await subscribe(recordId, subscription.callback, { mode: subscription.mode })
34
32
  return
@@ -48,7 +46,7 @@ export function createRecordSubscriptions(client) {
48
46
  try {
49
47
  await subscription.callback({ recordId, deleted: true, version })
50
48
  } catch (error) {
51
- clientLogger.error(`Error in record deletion callback for ${recordId}:`, error)
49
+ clientLogger.error("error in record deletion callback", { recordId, err: error })
52
50
  }
53
51
  }
54
52
  subscriptions.delete(recordId)
@@ -63,14 +61,14 @@ export function createRecordSubscriptions(client) {
63
61
  async function subscribe(recordId, callback, options) {
64
62
  const mode = options?.mode ?? "full"
65
63
  try {
66
- const result = await client.command("mesh/subscribe-record", { recordId, mode })
64
+ const result = await client.command("rt/subscribe-record", { recordId, mode })
67
65
  if (result.success) {
68
66
  subscriptions.set(recordId, { callback, localVersion: result.version, mode })
69
67
  if (callback) await callback({ recordId, full: result.record, version: result.version })
70
68
  }
71
69
  return { success: result.success, record: result.record ?? null, version: result.version ?? 0 }
72
70
  } catch (error) {
73
- clientLogger.error(`Failed to subscribe to record ${recordId}:`, error)
71
+ clientLogger.error("failed to subscribe to record", { recordId, err: error })
74
72
  return { success: false, record: null, version: 0 }
75
73
  }
76
74
  }
@@ -81,11 +79,11 @@ export function createRecordSubscriptions(client) {
81
79
  */
82
80
  async function unsubscribe(recordId) {
83
81
  try {
84
- const success = await client.command("mesh/unsubscribe-record", { recordId })
82
+ const success = await client.command("rt/unsubscribe-record", { recordId })
85
83
  if (success) subscriptions.delete(recordId)
86
84
  return success
87
85
  } catch (error) {
88
- clientLogger.error(`Failed to unsubscribe from record ${recordId}:`, error)
86
+ clientLogger.error("failed to unsubscribe from record", { recordId, err: error })
89
87
  return false
90
88
  }
91
89
  }
@@ -98,10 +96,10 @@ export function createRecordSubscriptions(client) {
98
96
  */
99
97
  async function write(recordId, newValue, options) {
100
98
  try {
101
- const result = await client.command("mesh/publish-record-update", { recordId, newValue, options })
99
+ const result = await client.command("rt/publish-record-update", { recordId, newValue, options })
102
100
  return result.success === true
103
101
  } catch (error) {
104
- clientLogger.error(`Failed to publish update for record ${recordId}:`, error)
102
+ clientLogger.error("failed to publish update for record", { recordId, err: error })
105
103
  return false
106
104
  }
107
105
  }
@@ -112,7 +110,7 @@ export function createRecordSubscriptions(client) {
112
110
  await subscribe(recordId, callback, { mode })
113
111
  return true
114
112
  } catch (error) {
115
- clientLogger.error(`Failed to resubscribe to record ${recordId}:`, error)
113
+ clientLogger.error("failed to resubscribe to record", { recordId, err: error })
116
114
  return false
117
115
  }
118
116
  })
@@ -9,7 +9,7 @@ export function createRoomSubscriptions(client, presence) {
9
9
  * @returns {Promise<{success: boolean, present: string[]}>}
10
10
  */
11
11
  async function join(roomName, onPresenceUpdate) {
12
- const joinResult = await client.command("mesh/join-room", { roomName })
12
+ const joinResult = await client.command("rt/join-room", { roomName })
13
13
  if (!joinResult.success) return { success: false, present: [] }
14
14
 
15
15
  joinedRooms.set(roomName, onPresenceUpdate)
@@ -25,7 +25,7 @@ export function createRoomSubscriptions(client, presence) {
25
25
  * @returns {Promise<{success: boolean}>}
26
26
  */
27
27
  async function leave(roomName) {
28
- const result = await client.command("mesh/leave-room", { roomName })
28
+ const result = await client.command("rt/leave-room", { roomName })
29
29
  if (result.success) {
30
30
  joinedRooms.delete(roomName)
31
31
  if (client.presenceSubscriptions.has(roomName)) {
@@ -41,10 +41,10 @@ export function createRoomSubscriptions(client, presence) {
41
41
  */
42
42
  async function getMetadata(roomName) {
43
43
  try {
44
- const result = await client.command("mesh/get-room-metadata", { roomName })
44
+ const result = await client.command("rt/get-room-metadata", { roomName })
45
45
  return result.metadata
46
46
  } catch (error) {
47
- clientLogger.error(`Failed to get metadata for room ${roomName}:`, error)
47
+ clientLogger.error("failed to get metadata for room", { roomName, err: error })
48
48
  return null
49
49
  }
50
50
  }
@@ -55,7 +55,7 @@ export function createRoomSubscriptions(client, presence) {
55
55
  await join(roomName, presenceCallback)
56
56
  return { roomName, success: true }
57
57
  } catch (error) {
58
- clientLogger.error(`Failed to rejoin room ${roomName}:`, error)
58
+ clientLogger.error("failed to rejoin room", { roomName, err: error })
59
59
  return { roomName, success: false }
60
60
  }
61
61
  })
@@ -39,7 +39,7 @@ export class Connection extends EventEmitter {
39
39
  this.missedPongs++
40
40
  const maxMissedPongs = this.connectionOptions.maxMissedPongs ?? 1
41
41
  if (this.missedPongs > maxMissedPongs) {
42
- serverLogger.info(`Closing connection (${this.id}) due to missed pongs`)
42
+ serverLogger.info("closing connection due to missed pongs", { connectionId: this.id })
43
43
  this.close()
44
44
  this.server.cleanupConnection(this)
45
45
  return
@@ -59,7 +59,7 @@ export class Connection extends EventEmitter {
59
59
 
60
60
  _applyListeners() {
61
61
  this.socket.on("close", () => {
62
- serverLogger.info("Client's socket closed:", this.id)
62
+ serverLogger.info("client socket closed", { connectionId: this.id })
63
63
  this.status = Status.OFFLINE
64
64
  this.emit("close")
65
65
  })
@@ -36,8 +36,8 @@ export class ChannelManager {
36
36
  const serialized = typeof message === "string" ? message : JSON.stringify(message)
37
37
  const parsedHistory = parseInt(history, 10)
38
38
  if (!isNaN(parsedHistory) && parsedHistory > 0) {
39
- await this.pubClient.rpush(`mesh:history:${channel}`, serialized)
40
- await this.pubClient.ltrim(`mesh:history:${channel}`, -parsedHistory, -1)
39
+ await this.pubClient.rpush(`rt:history:${channel}`, serialized)
40
+ await this.pubClient.ltrim(`rt:history:${channel}`, -parsedHistory, -1)
41
41
  }
42
42
  this.messageStream.publishMessage(channel, serialized, instanceId)
43
43
  await this.pubClient.publish(channel, serialized)
@@ -89,11 +89,11 @@ export class ChannelManager {
89
89
  const messages = await this.persistenceManager.getMessages(channel, since, limit)
90
90
  return messages.map((msg) => msg.message)
91
91
  } catch {
92
- const historyKey = `mesh:history:${channel}`
92
+ const historyKey = `rt:history:${channel}`
93
93
  return this.redis.lrange(historyKey, 0, limit - 1)
94
94
  }
95
95
  }
96
- const historyKey = `mesh:history:${channel}`
96
+ const historyKey = `rt:history:${channel}`
97
97
  return this.redis.lrange(historyKey, 0, limit - 1)
98
98
  }
99
99
 
@@ -38,7 +38,7 @@ export class CollectionManager {
38
38
  const ids = records.map((record) => record.id)
39
39
  const version = 1
40
40
  this.collectionSubscriptions.get(collectionId).set(connectionId, { version })
41
- await this.redis.set(`mesh:collection:${collectionId}:${connectionId}`, JSON.stringify(ids))
41
+ await this.redis.set(`rt:collection:${collectionId}:${connectionId}`, JSON.stringify(ids))
42
42
  return { ids, records, version }
43
43
  }
44
44
 
@@ -47,7 +47,7 @@ export class CollectionManager {
47
47
  if (collectionSubs?.has(connectionId)) {
48
48
  collectionSubs.delete(connectionId)
49
49
  if (collectionSubs.size === 0) this.collectionSubscriptions.delete(collectionId)
50
- await this.redis.del(`mesh:collection:${collectionId}:${connectionId}`)
50
+ await this.redis.del(`rt:collection:${collectionId}:${connectionId}`)
51
51
  return true
52
52
  }
53
53
  return false
@@ -55,7 +55,7 @@ export class CollectionManager {
55
55
 
56
56
  async publishRecordChange(recordId) {
57
57
  try {
58
- await this.redis.publish("mesh:collection:record-change", recordId)
58
+ await this.redis.publish("rt:collection:record-change", recordId)
59
59
  } catch (error) {
60
60
  this.emitError(new Error(`Failed to publish record change for ${recordId}: ${error}`))
61
61
  }
@@ -69,7 +69,7 @@ export class CollectionManager {
69
69
  subscribers.delete(connectionId)
70
70
  if (subscribers.size === 0) this.collectionSubscriptions.delete(collectionId)
71
71
  cleanupPromises.push(
72
- this.redis.del(`mesh:collection:${collectionId}:${connectionId}`).then(() => {}).catch((err) => {
72
+ this.redis.del(`rt:collection:${collectionId}:${connectionId}`).then(() => {}).catch((err) => {
73
73
  this.emitError(new Error(`Failed to clean up collection subscription for "${collectionId}": ${err}`))
74
74
  })
75
75
  )
@@ -79,7 +79,7 @@ export class CollectionManager {
79
79
 
80
80
  async listRecordsMatching(pattern, options) {
81
81
  try {
82
- const recordKeyPrefix = "mesh:record:"
82
+ const recordKeyPrefix = "rt:record:"
83
83
  const keys = []
84
84
  let cursor = "0"
85
85
  do {
@@ -1,8 +1,8 @@
1
1
  import { deepMerge, isObject } from "../../shared/index.js"
2
2
 
3
- const CONNECTIONS_HASH_KEY = "mesh:connections"
4
- const CONNECTIONS_META_HASH_KEY = "mesh:connection-meta"
5
- const INSTANCE_CONNECTIONS_KEY_PREFIX = "mesh:connections:"
3
+ const CONNECTIONS_HASH_KEY = "rt:connections"
4
+ const CONNECTIONS_META_HASH_KEY = "rt:connection-meta"
5
+ const INSTANCE_CONNECTIONS_KEY_PREFIX = "rt:connections:"
6
6
 
7
7
  export class ConnectionManager {
8
8
  constructor({ redis, instanceId, roomManager }) {