@principal-ai/control-tower-core 0.1.12 → 0.1.13
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/dist/abstractions/DefaultPresenceManager.d.ts +27 -4
- package/dist/abstractions/DefaultPresenceManager.d.ts.map +1 -1
- package/dist/abstractions/DefaultPresenceManager.js +145 -4
- package/dist/abstractions/PresenceExtension.d.ts +121 -0
- package/dist/abstractions/PresenceExtension.d.ts.map +1 -0
- package/dist/abstractions/PresenceExtension.js +14 -0
- package/dist/abstractions/index.d.ts +1 -0
- package/dist/abstractions/index.d.ts.map +1 -1
- package/dist/client/PresenceClient.d.ts +152 -0
- package/dist/client/PresenceClient.d.ts.map +1 -0
- package/dist/client/PresenceClient.js +193 -0
- package/dist/client/index.d.ts +1 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +3 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +7 -6
- package/dist/index.mjs +290 -9
- package/dist/index.mjs.map +7 -6
- package/dist/server/BaseServer.d.ts +27 -0
- package/dist/server/BaseServer.d.ts.map +1 -1
- package/dist/server/BaseServer.js +57 -4
- package/dist/server/ServerBuilder.d.ts +5 -0
- package/dist/server/ServerBuilder.d.ts.map +1 -1
- package/dist/server/ServerBuilder.js +50 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -3213,11 +3213,28 @@ class DefaultPresenceManager extends PresenceManager {
|
|
|
3213
3213
|
userPresences = new Map;
|
|
3214
3214
|
deviceToUser = new Map;
|
|
3215
3215
|
gracePeriodEntries = new Map;
|
|
3216
|
+
extensions = [];
|
|
3217
|
+
server;
|
|
3216
3218
|
constructor(config) {
|
|
3217
3219
|
super(config);
|
|
3220
|
+
this.extensions = config?.extensions || [];
|
|
3221
|
+
}
|
|
3222
|
+
setServer(server) {
|
|
3223
|
+
this.server = server;
|
|
3224
|
+
}
|
|
3225
|
+
async initializeExtensions() {
|
|
3226
|
+
for (const ext of this.extensions) {
|
|
3227
|
+
await ext.initialize?.();
|
|
3228
|
+
}
|
|
3229
|
+
}
|
|
3230
|
+
async destroyExtensions() {
|
|
3231
|
+
for (const ext of this.extensions) {
|
|
3232
|
+
await ext.destroy?.();
|
|
3233
|
+
}
|
|
3218
3234
|
}
|
|
3219
3235
|
async connectDevice(userId, deviceId, deviceInfo) {
|
|
3220
3236
|
const now = Date.now();
|
|
3237
|
+
const isFirstDevice = !this.userPresences.has(userId) && !this.gracePeriodEntries.has(userId);
|
|
3221
3238
|
const gracePeriodEntry = this.gracePeriodEntries.get(userId);
|
|
3222
3239
|
if (gracePeriodEntry) {
|
|
3223
3240
|
this.gracePeriodEntries.delete(userId);
|
|
@@ -3234,9 +3251,31 @@ class DefaultPresenceManager extends PresenceManager {
|
|
|
3234
3251
|
presence2.lastActivity = now;
|
|
3235
3252
|
this.userPresences.set(userId, presence2);
|
|
3236
3253
|
this.deviceToUser.set(deviceId, userId);
|
|
3254
|
+
if (isFirstDevice) {
|
|
3255
|
+
for (const ext of this.extensions) {
|
|
3256
|
+
await ext.onUserOnline?.(userId, deviceId, deviceInfo?.metadata || {});
|
|
3257
|
+
}
|
|
3258
|
+
} else {
|
|
3259
|
+
for (const ext of this.extensions) {
|
|
3260
|
+
await ext.onDeviceConnected?.(userId, deviceId, deviceInfo?.metadata || {});
|
|
3261
|
+
}
|
|
3262
|
+
}
|
|
3263
|
+
if (this.config.broadcastPresenceUpdates && this.server) {
|
|
3264
|
+
const experimental = this.server.experimental;
|
|
3265
|
+
await experimental?.broadcastAuthenticated({
|
|
3266
|
+
type: "presence:user_online",
|
|
3267
|
+
payload: {
|
|
3268
|
+
userId,
|
|
3269
|
+
deviceId,
|
|
3270
|
+
status: "online",
|
|
3271
|
+
timestamp: now
|
|
3272
|
+
}
|
|
3273
|
+
});
|
|
3274
|
+
}
|
|
3237
3275
|
return presence2;
|
|
3238
3276
|
}
|
|
3239
3277
|
let presence = this.userPresences.get(userId);
|
|
3278
|
+
const wasOnline = presence !== undefined;
|
|
3240
3279
|
if (!presence) {
|
|
3241
3280
|
presence = {
|
|
3242
3281
|
userId,
|
|
@@ -3259,6 +3298,27 @@ class DefaultPresenceManager extends PresenceManager {
|
|
|
3259
3298
|
presence.status = this.calculatePresenceStatus(presence.devices, now);
|
|
3260
3299
|
presence.lastActivity = now;
|
|
3261
3300
|
this.deviceToUser.set(deviceId, userId);
|
|
3301
|
+
if (!wasOnline) {
|
|
3302
|
+
for (const ext of this.extensions) {
|
|
3303
|
+
await ext.onUserOnline?.(userId, deviceId, deviceInfo?.metadata || {});
|
|
3304
|
+
}
|
|
3305
|
+
} else {
|
|
3306
|
+
for (const ext of this.extensions) {
|
|
3307
|
+
await ext.onDeviceConnected?.(userId, deviceId, deviceInfo?.metadata || {});
|
|
3308
|
+
}
|
|
3309
|
+
}
|
|
3310
|
+
if (!wasOnline && this.config.broadcastPresenceUpdates && this.server) {
|
|
3311
|
+
const experimental = this.server.experimental;
|
|
3312
|
+
await experimental?.broadcastAuthenticated({
|
|
3313
|
+
type: "presence:user_online",
|
|
3314
|
+
payload: {
|
|
3315
|
+
userId,
|
|
3316
|
+
deviceId,
|
|
3317
|
+
status: "online",
|
|
3318
|
+
timestamp: now
|
|
3319
|
+
}
|
|
3320
|
+
});
|
|
3321
|
+
}
|
|
3262
3322
|
return presence;
|
|
3263
3323
|
}
|
|
3264
3324
|
async disconnectDevice(userId, deviceId) {
|
|
@@ -3269,7 +3329,24 @@ class DefaultPresenceManager extends PresenceManager {
|
|
|
3269
3329
|
presence.devices.delete(deviceId);
|
|
3270
3330
|
this.deviceToUser.delete(deviceId);
|
|
3271
3331
|
const now = Date.now();
|
|
3272
|
-
|
|
3332
|
+
const isLastDevice = presence.devices.size === 0;
|
|
3333
|
+
if (isLastDevice) {
|
|
3334
|
+
for (const ext of this.extensions) {
|
|
3335
|
+
await ext.onUserOffline?.(userId, deviceId);
|
|
3336
|
+
}
|
|
3337
|
+
if (this.config.broadcastPresenceUpdates && this.server) {
|
|
3338
|
+
const experimental = this.server.experimental;
|
|
3339
|
+
await experimental?.broadcastAuthenticated({
|
|
3340
|
+
type: "presence:user_offline",
|
|
3341
|
+
payload: {
|
|
3342
|
+
userId,
|
|
3343
|
+
deviceId,
|
|
3344
|
+
status: "offline",
|
|
3345
|
+
timestamp: now,
|
|
3346
|
+
gracePeriod: this.config.gracePeriod
|
|
3347
|
+
}
|
|
3348
|
+
});
|
|
3349
|
+
}
|
|
3273
3350
|
if (this.config.gracePeriod > 0) {
|
|
3274
3351
|
this.gracePeriodEntries.set(userId, {
|
|
3275
3352
|
userId,
|
|
@@ -3283,6 +3360,9 @@ class DefaultPresenceManager extends PresenceManager {
|
|
|
3283
3360
|
return null;
|
|
3284
3361
|
}
|
|
3285
3362
|
}
|
|
3363
|
+
for (const ext of this.extensions) {
|
|
3364
|
+
await ext.onDeviceDisconnected?.(userId, deviceId);
|
|
3365
|
+
}
|
|
3286
3366
|
presence.status = this.calculatePresenceStatus(presence.devices, now);
|
|
3287
3367
|
let mostRecentActivity = 0;
|
|
3288
3368
|
for (const device of presence.devices.values()) {
|
|
@@ -3294,7 +3374,7 @@ class DefaultPresenceManager extends PresenceManager {
|
|
|
3294
3374
|
return presence;
|
|
3295
3375
|
}
|
|
3296
3376
|
async updateActivity(update) {
|
|
3297
|
-
const { userId, deviceId, timestamp } = update;
|
|
3377
|
+
const { userId, deviceId, timestamp, activityType } = update;
|
|
3298
3378
|
const presence = this.userPresences.get(userId);
|
|
3299
3379
|
if (!presence) {
|
|
3300
3380
|
throw new Error(`User ${userId} not found in presence system`);
|
|
@@ -3309,10 +3389,30 @@ class DefaultPresenceManager extends PresenceManager {
|
|
|
3309
3389
|
}
|
|
3310
3390
|
const previousStatus = presence.status;
|
|
3311
3391
|
presence.status = this.calculatePresenceStatus(presence.devices, timestamp);
|
|
3392
|
+
for (const ext of this.extensions) {
|
|
3393
|
+
await ext.onActivity?.(userId, deviceId, activityType || "heartbeat");
|
|
3394
|
+
}
|
|
3312
3395
|
return presence;
|
|
3313
3396
|
}
|
|
3314
3397
|
async getUserPresence(userId) {
|
|
3315
|
-
|
|
3398
|
+
const basePresence = this.userPresences.get(userId);
|
|
3399
|
+
if (!basePresence) {
|
|
3400
|
+
return null;
|
|
3401
|
+
}
|
|
3402
|
+
if (this.extensions.length > 0) {
|
|
3403
|
+
const extendedData = {};
|
|
3404
|
+
for (const ext of this.extensions) {
|
|
3405
|
+
const data = await ext.getExtendedData?.(userId);
|
|
3406
|
+
if (data) {
|
|
3407
|
+
Object.assign(extendedData, data);
|
|
3408
|
+
}
|
|
3409
|
+
}
|
|
3410
|
+
return {
|
|
3411
|
+
...basePresence,
|
|
3412
|
+
extended: extendedData
|
|
3413
|
+
};
|
|
3414
|
+
}
|
|
3415
|
+
return basePresence;
|
|
3316
3416
|
}
|
|
3317
3417
|
async getUsersPresence(userIds) {
|
|
3318
3418
|
const result = new Map;
|
|
@@ -3328,7 +3428,20 @@ class DefaultPresenceManager extends PresenceManager {
|
|
|
3328
3428
|
const online = [];
|
|
3329
3429
|
for (const presence of this.userPresences.values()) {
|
|
3330
3430
|
if (presence.status === "online") {
|
|
3331
|
-
|
|
3431
|
+
let visible = true;
|
|
3432
|
+
for (const ext of this.extensions) {
|
|
3433
|
+
const shouldShow = await ext.shouldBeVisible?.(presence.userId);
|
|
3434
|
+
if (shouldShow === false) {
|
|
3435
|
+
visible = false;
|
|
3436
|
+
break;
|
|
3437
|
+
}
|
|
3438
|
+
}
|
|
3439
|
+
if (visible) {
|
|
3440
|
+
const fullPresence = await this.getUserPresence(presence.userId);
|
|
3441
|
+
if (fullPresence) {
|
|
3442
|
+
online.push(fullPresence);
|
|
3443
|
+
}
|
|
3444
|
+
}
|
|
3332
3445
|
}
|
|
3333
3446
|
}
|
|
3334
3447
|
return online;
|
|
@@ -3405,6 +3518,7 @@ class DefaultPresenceManager extends PresenceManager {
|
|
|
3405
3518
|
return changes;
|
|
3406
3519
|
}
|
|
3407
3520
|
async clear() {
|
|
3521
|
+
await this.destroyExtensions();
|
|
3408
3522
|
this.userPresences.clear();
|
|
3409
3523
|
this.deviceToUser.clear();
|
|
3410
3524
|
this.gracePeriodEntries.clear();
|
|
@@ -4778,6 +4892,107 @@ class ClientBuilder {
|
|
|
4778
4892
|
return new BaseClient(config);
|
|
4779
4893
|
}
|
|
4780
4894
|
}
|
|
4895
|
+
// src/client/PresenceClient.ts
|
|
4896
|
+
class PresenceClient extends TypedEventEmitter {
|
|
4897
|
+
client;
|
|
4898
|
+
wsUrl;
|
|
4899
|
+
autoReconnectEnabled;
|
|
4900
|
+
globalRoomId;
|
|
4901
|
+
reconnectTimeout;
|
|
4902
|
+
constructor(config) {
|
|
4903
|
+
super();
|
|
4904
|
+
this.wsUrl = config.wsUrl;
|
|
4905
|
+
this.autoReconnectEnabled = config.autoReconnect ?? true;
|
|
4906
|
+
this.globalRoomId = config.globalRoomId ?? "__global_presence__";
|
|
4907
|
+
this.client = new BaseClient(config.clientConfig);
|
|
4908
|
+
this.setupEventForwarding();
|
|
4909
|
+
if (config.autoConnect) {
|
|
4910
|
+
this.connect();
|
|
4911
|
+
}
|
|
4912
|
+
}
|
|
4913
|
+
async connect() {
|
|
4914
|
+
try {
|
|
4915
|
+
await this.client.connect(this.wsUrl);
|
|
4916
|
+
await this.client.joinRoom(this.globalRoomId);
|
|
4917
|
+
await this.emit("connected", {});
|
|
4918
|
+
} catch (error) {
|
|
4919
|
+
await this.emit("error", { error });
|
|
4920
|
+
throw error;
|
|
4921
|
+
}
|
|
4922
|
+
}
|
|
4923
|
+
async disconnect() {
|
|
4924
|
+
this.autoReconnectEnabled = false;
|
|
4925
|
+
if (this.reconnectTimeout) {
|
|
4926
|
+
clearTimeout(this.reconnectTimeout);
|
|
4927
|
+
this.reconnectTimeout = undefined;
|
|
4928
|
+
}
|
|
4929
|
+
try {
|
|
4930
|
+
await this.client.leaveRoom();
|
|
4931
|
+
await this.client.disconnect();
|
|
4932
|
+
await this.emit("disconnected", {});
|
|
4933
|
+
} catch (error) {
|
|
4934
|
+
await this.emit("error", { error });
|
|
4935
|
+
}
|
|
4936
|
+
}
|
|
4937
|
+
async getOnlineUsers() {
|
|
4938
|
+
throw new Error("getOnlineUsers() requires a REST API endpoint. " + "Implement this method based on your server API.");
|
|
4939
|
+
}
|
|
4940
|
+
async setStatus(status, message) {
|
|
4941
|
+
throw new Error("setStatus() requires a REST API endpoint. " + "Implement this method based on your server API.");
|
|
4942
|
+
}
|
|
4943
|
+
async setVisibility(visible) {
|
|
4944
|
+
throw new Error("setVisibility() requires a REST API endpoint. " + "Implement this method based on your server API.");
|
|
4945
|
+
}
|
|
4946
|
+
getClient() {
|
|
4947
|
+
return this.client;
|
|
4948
|
+
}
|
|
4949
|
+
isConnected() {
|
|
4950
|
+
return this.client.connectionState === "connected";
|
|
4951
|
+
}
|
|
4952
|
+
setupEventForwarding() {
|
|
4953
|
+
this.client.on("presence:user_online", (data) => {
|
|
4954
|
+
if (data && typeof data === "object") {
|
|
4955
|
+
const payload = data;
|
|
4956
|
+
this.emit("userOnline", {
|
|
4957
|
+
userId: payload.userId,
|
|
4958
|
+
devices: payload.devices || []
|
|
4959
|
+
});
|
|
4960
|
+
}
|
|
4961
|
+
});
|
|
4962
|
+
this.client.on("presence:user_offline", (data) => {
|
|
4963
|
+
if (data && typeof data === "object") {
|
|
4964
|
+
const payload = data;
|
|
4965
|
+
this.emit("userOffline", { userId: payload.userId });
|
|
4966
|
+
}
|
|
4967
|
+
});
|
|
4968
|
+
this.client.on("presence:status_changed", (data) => {
|
|
4969
|
+
if (data && typeof data === "object") {
|
|
4970
|
+
const payload = data;
|
|
4971
|
+
this.emit("statusChanged", {
|
|
4972
|
+
userId: payload.userId,
|
|
4973
|
+
status: payload.status,
|
|
4974
|
+
statusMessage: payload.statusMessage
|
|
4975
|
+
});
|
|
4976
|
+
}
|
|
4977
|
+
});
|
|
4978
|
+
this.client.on("disconnected", () => {
|
|
4979
|
+
this.emit("disconnected", {});
|
|
4980
|
+
if (this.autoReconnectEnabled) {
|
|
4981
|
+
this.reconnectTimeout = setTimeout(() => {
|
|
4982
|
+
this.connect().catch((error) => {
|
|
4983
|
+
this.emit("error", { error });
|
|
4984
|
+
});
|
|
4985
|
+
}, 5000);
|
|
4986
|
+
}
|
|
4987
|
+
});
|
|
4988
|
+
this.client.on("error", (data) => {
|
|
4989
|
+
if (data && typeof data === "object" && "error" in data) {
|
|
4990
|
+
const payload = data;
|
|
4991
|
+
this.emit("error", { error: payload.error });
|
|
4992
|
+
}
|
|
4993
|
+
});
|
|
4994
|
+
}
|
|
4995
|
+
}
|
|
4781
4996
|
// src/server/ExperimentalAPI.ts
|
|
4782
4997
|
class ExperimentalAPI {
|
|
4783
4998
|
config;
|
|
@@ -4916,6 +5131,8 @@ class BaseServer extends TypedEventEmitter {
|
|
|
4916
5131
|
config;
|
|
4917
5132
|
clients = new Map;
|
|
4918
5133
|
clientMessageHandlers = new Map;
|
|
5134
|
+
clientUserMap = new Map;
|
|
5135
|
+
userClientMap = new Map;
|
|
4919
5136
|
running = false;
|
|
4920
5137
|
initialized = false;
|
|
4921
5138
|
mode;
|
|
@@ -5066,6 +5283,8 @@ class BaseServer extends TypedEventEmitter {
|
|
|
5066
5283
|
}
|
|
5067
5284
|
this.clients.clear();
|
|
5068
5285
|
this.clientMessageHandlers.clear();
|
|
5286
|
+
this.clientUserMap.clear();
|
|
5287
|
+
this.userClientMap.clear();
|
|
5069
5288
|
if (this.presenceManager) {
|
|
5070
5289
|
await this.presenceManager.clear();
|
|
5071
5290
|
}
|
|
@@ -5169,6 +5388,11 @@ class BaseServer extends TypedEventEmitter {
|
|
|
5169
5388
|
if (client) {
|
|
5170
5389
|
client.authenticated = true;
|
|
5171
5390
|
client.userId = payload.userId;
|
|
5391
|
+
this.clientUserMap.set(payload.clientId, payload.userId);
|
|
5392
|
+
if (!this.userClientMap.has(payload.userId)) {
|
|
5393
|
+
this.userClientMap.set(payload.userId, new Set);
|
|
5394
|
+
}
|
|
5395
|
+
this.userClientMap.get(payload.userId).add(payload.clientId);
|
|
5172
5396
|
await this.emit("client_authenticated", {
|
|
5173
5397
|
clientId: payload.clientId,
|
|
5174
5398
|
userId: payload.userId
|
|
@@ -5204,6 +5428,16 @@ class BaseServer extends TypedEventEmitter {
|
|
|
5204
5428
|
if (!client) {
|
|
5205
5429
|
return;
|
|
5206
5430
|
}
|
|
5431
|
+
if (client.userId) {
|
|
5432
|
+
this.clientUserMap.delete(clientId);
|
|
5433
|
+
const clientSet = this.userClientMap.get(client.userId);
|
|
5434
|
+
if (clientSet) {
|
|
5435
|
+
clientSet.delete(clientId);
|
|
5436
|
+
if (clientSet.size === 0) {
|
|
5437
|
+
this.userClientMap.delete(client.userId);
|
|
5438
|
+
}
|
|
5439
|
+
}
|
|
5440
|
+
}
|
|
5207
5441
|
if (this.presenceManager?.isEnabled() && client.userId) {
|
|
5208
5442
|
try {
|
|
5209
5443
|
const presence = await this.presenceManager.disconnectDevice(client.userId, clientId);
|
|
@@ -5247,6 +5481,9 @@ class BaseServer extends TypedEventEmitter {
|
|
|
5247
5481
|
if (!client) {
|
|
5248
5482
|
return;
|
|
5249
5483
|
}
|
|
5484
|
+
if (this.presenceManager?.isEnabled() && client.userId && client.authenticated) {
|
|
5485
|
+
await this.updatePresenceActivity(client.userId, clientId, "message");
|
|
5486
|
+
}
|
|
5250
5487
|
switch (message.type) {
|
|
5251
5488
|
case "authenticate":
|
|
5252
5489
|
await this.handleAuthenticate(clientId, message.payload);
|
|
@@ -5268,9 +5505,6 @@ class BaseServer extends TypedEventEmitter {
|
|
|
5268
5505
|
break;
|
|
5269
5506
|
case "ping":
|
|
5270
5507
|
await this.sendToClient(clientId, { type: "pong", timestamp: Date.now() });
|
|
5271
|
-
if (this.presenceManager?.isEnabled() && client.userId) {
|
|
5272
|
-
await this.updatePresenceActivity(client.userId, clientId, "heartbeat");
|
|
5273
|
-
}
|
|
5274
5508
|
break;
|
|
5275
5509
|
default:
|
|
5276
5510
|
await this.sendToClient(clientId, {
|
|
@@ -5510,6 +5744,15 @@ class BaseServer extends TypedEventEmitter {
|
|
|
5510
5744
|
getPresenceManager() {
|
|
5511
5745
|
return this.presenceManager;
|
|
5512
5746
|
}
|
|
5747
|
+
getUserIdFromClientId(clientId) {
|
|
5748
|
+
return this.clientUserMap.get(clientId);
|
|
5749
|
+
}
|
|
5750
|
+
getClientIdsForUser(userId) {
|
|
5751
|
+
return Array.from(this.userClientMap.get(userId) || []);
|
|
5752
|
+
}
|
|
5753
|
+
getDeviceIdFromClientId(clientId) {
|
|
5754
|
+
return clientId;
|
|
5755
|
+
}
|
|
5513
5756
|
}
|
|
5514
5757
|
// src/server/ServerBuilder.ts
|
|
5515
5758
|
class ServerBuilder {
|
|
@@ -5599,7 +5842,44 @@ class ServerBuilder {
|
|
|
5599
5842
|
trackUsageMetrics: false
|
|
5600
5843
|
}
|
|
5601
5844
|
};
|
|
5602
|
-
|
|
5845
|
+
const server = new BaseServer(config);
|
|
5846
|
+
if (this.presenceManager instanceof DefaultPresenceManager) {
|
|
5847
|
+
this.presenceManager.setServer(server);
|
|
5848
|
+
}
|
|
5849
|
+
if (this.presenceManager instanceof DefaultPresenceManager) {
|
|
5850
|
+
this.wirePresenceExtensionHooks(server, this.presenceManager);
|
|
5851
|
+
}
|
|
5852
|
+
return server;
|
|
5853
|
+
}
|
|
5854
|
+
wirePresenceExtensionHooks(server, presenceManager) {
|
|
5855
|
+
server.on("started", async () => {
|
|
5856
|
+
await presenceManager.initializeExtensions();
|
|
5857
|
+
});
|
|
5858
|
+
server.on("client_joined_room", async ({ clientId, roomId }) => {
|
|
5859
|
+
const userId = server.getUserIdFromClientId(clientId);
|
|
5860
|
+
if (userId && presenceManager.isEnabled()) {
|
|
5861
|
+
const extensions = presenceManager.extensions;
|
|
5862
|
+
if (extensions) {
|
|
5863
|
+
for (const ext of extensions) {
|
|
5864
|
+
await ext.onRoomJoined?.(userId, roomId, clientId);
|
|
5865
|
+
}
|
|
5866
|
+
}
|
|
5867
|
+
}
|
|
5868
|
+
});
|
|
5869
|
+
server.on("client_left_room", async ({ clientId, roomId }) => {
|
|
5870
|
+
const userId = server.getUserIdFromClientId(clientId);
|
|
5871
|
+
if (userId && presenceManager.isEnabled()) {
|
|
5872
|
+
const extensions = presenceManager.extensions;
|
|
5873
|
+
if (extensions) {
|
|
5874
|
+
for (const ext of extensions) {
|
|
5875
|
+
await ext.onRoomLeft?.(userId, roomId, clientId);
|
|
5876
|
+
}
|
|
5877
|
+
}
|
|
5878
|
+
}
|
|
5879
|
+
});
|
|
5880
|
+
server.on("stopped", async () => {
|
|
5881
|
+
await presenceManager.destroyExtensions();
|
|
5882
|
+
});
|
|
5603
5883
|
}
|
|
5604
5884
|
}
|
|
5605
5885
|
export {
|
|
@@ -5609,6 +5889,7 @@ export {
|
|
|
5609
5889
|
ServerBuilder,
|
|
5610
5890
|
RoomManager,
|
|
5611
5891
|
PresenceManager,
|
|
5892
|
+
PresenceClient,
|
|
5612
5893
|
MockTransportAdapter,
|
|
5613
5894
|
MockStorageAdapter,
|
|
5614
5895
|
MockAuthAdapter,
|
|
@@ -5623,4 +5904,4 @@ export {
|
|
|
5623
5904
|
BaseClient
|
|
5624
5905
|
};
|
|
5625
5906
|
|
|
5626
|
-
//# debugId=
|
|
5907
|
+
//# debugId=205D80A7D7E855D364756E2164756E21
|