@verdant-web/server 4.1.1 → 4.2.1

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.
@@ -11,8 +11,8 @@ export function createNodeWebsocketHandler(core) {
11
11
  const data = JSON.parse(message.toString());
12
12
  await microserver.handleMessage(key, info, data);
13
13
  });
14
- ws.on('close', () => {
15
- microserver.clientConnections.remove(key);
14
+ ws.on('close', async () => {
15
+ await microserver.clientConnections.remove(key);
16
16
  core.log('debug', 'Connection closed', { key, userId: info.userId });
17
17
  });
18
18
  });
@@ -1 +1 @@
1
- {"version":3,"file":"websocketHandler.js","sourceRoot":"","sources":["../../../../src/adapters/node/websocketHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,YAAY,EACZ,MAAM,EACN,UAAU,GACV,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EAAa,eAAe,EAAE,MAAM,IAAI,CAAC;AAIhD,MAAM,UAAU,0BAA0B,CAAC,IAA8B;IACxE,MAAM,GAAG,GAAG,IAAI,eAAe,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,GAAG,CAAC,EAAE,CACL,YAAY,EACZ,KAAK,EAAE,EAAa,EAAE,GAAoB,EAAE,IAAe,EAAE,EAAE;QAC9D,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;QAEzB,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAEnD,WAAW,CAAC,iBAAiB,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;QAEvD,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,OAAY,EAAE,EAAE;YACvC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAkB,CAAC;YAC7D,MAAM,WAAW,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACnB,WAAW,CAAC,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC1C,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,mBAAmB,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACtE,CAAC,CAAC,CAAC;IACJ,CAAC,CACD,CAAC;IAEF,SAAS,eAAe,CAAC,GAAoB;QAC5C,IAAI,GAAG,CAAC,OAAO,CAAC,wBAAwB,CAAC,EAAE,CAAC;YAC3C,0DAA0D;YAC1D,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACvE,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACvB,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;YACrB,CAAC;QACF,CAAC;QAED,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,yBAAyB,CAAC,CAAC;QAC3C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;QACjD,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC5C,IAAI,CAAC,KAAK,EAAE,CAAC;YACZ,MAAM,IAAI,YAAY,CACrB,YAAY,CAAC,IAAI,CAAC,OAAO,EACzB,SAAS,EACT,mCAAmC,CACnC,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC;IACd,CAAC;IAED,OAAO,CAAC,GAAoB,EAAE,MAAuB,EAAE,IAAY,EAAE,EAAE;QACtE,IAAI,CAAC;YACJ,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;YACnC,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YACnD,GAAG,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE;gBAC3C,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;YACvC,CAAC,CAAC,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,IAAI,GAAG,YAAY,YAAY,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;gBAC3D,MAAM,CAAC,KAAK,CACX,+BAA+B;oBAC9B,uBAAuB;oBACvB,uBAAuB;oBACvB,MAAM,CACP,CAAC;YACH,CAAC;YACD,MAAM,CAAC,OAAO,EAAE,CAAC;QAClB,CAAC;IACF,CAAC,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"websocketHandler.js","sourceRoot":"","sources":["../../../../src/adapters/node/websocketHandler.ts"],"names":[],"mappings":"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"}
@@ -1,26 +1,38 @@
1
- import { ServerMessage } from '@verdant-web/common';
1
+ import { EventSubscriber, ServerMessage } from '@verdant-web/common';
2
2
  import { IncomingMessage, ServerResponse } from 'http';
3
3
  import { WebSocket as WSWebSocket } from 'ws';
4
4
  import { Logger } from '../logger.js';
5
5
  import { UserProfileLoader } from '../Profiles.js';
6
6
  import { TokenInfo } from '../TokenVerifier.js';
7
7
  import { MessageSender } from './MessageSender.js';
8
- import { Presence } from './Presence.js';
9
- export declare class ClientConnectionManager implements MessageSender {
8
+ import { Presence, PresenceStorage } from './Presence.js';
9
+ export type ClientConnectionsManagerEvents = {
10
+ replicaLost: (replicaId: string, connectionKey: string) => void;
11
+ };
12
+ export declare class ClientConnectionManager extends EventSubscriber<ClientConnectionsManagerEvents> implements MessageSender {
10
13
  private readonly connections;
14
+ private connectionToUser;
15
+ private userToConnections;
11
16
  readonly presence: Presence;
12
17
  private readonly log?;
13
- constructor({ profiles, log, }: {
18
+ constructor({ profiles, presenceStorage, log, }: {
14
19
  profiles: UserProfileLoader<any>;
20
+ presenceStorage?: PresenceStorage;
15
21
  log?: Logger;
16
22
  });
23
+ private addMappings;
24
+ /**
25
+ * Removes back-mappings and, if all are deleted,
26
+ * also removes user presence.
27
+ */
28
+ private removeMappings;
17
29
  addSocket: (key: string, socket: WebSocket | WSWebSocket, info: TokenInfo, options?: {
18
30
  disableAutoRemoveOnClose?: boolean;
19
31
  }) => void;
20
32
  addRequest: (key: string, request: IncomingMessage, response: ServerResponse, info: TokenInfo) => () => void;
21
33
  addFetch: (key: string, req: Request, info: TokenInfo) => (() => Response);
22
- remove: (key: string) => void;
23
- respond: (key: string, message: ServerMessage) => void;
34
+ remove: (key: string) => Promise<void>;
35
+ respond: (key: string, message: ServerMessage) => boolean;
24
36
  /**
25
37
  * Broadcasts a message to all live-connected clients in a library.
26
38
  * This does not reach push/pull clients.
@@ -1,4 +1,4 @@
1
- import { authz } from '@verdant-web/common';
1
+ import { authz, EventSubscriber } from '@verdant-web/common';
2
2
  import { Presence } from './Presence.js';
3
3
  class ClientConnection {
4
4
  constructor(key, info) {
@@ -96,31 +96,45 @@ class WebSocketClientConnection extends ClientConnection {
96
96
  };
97
97
  }
98
98
  }
99
- export class ClientConnectionManager {
100
- constructor({ profiles, log, }) {
99
+ export class ClientConnectionManager extends EventSubscriber {
100
+ constructor({ profiles, presenceStorage, log, }) {
101
+ super();
101
102
  this.connections = new Map();
103
+ this.connectionToUser = new Map();
104
+ this.userToConnections = new Map();
102
105
  this.addSocket = (key, socket, info, options) => {
103
106
  const connection = new WebSocketClientConnection(key, socket, info);
104
107
  this.connections.set(key, connection);
108
+ this.addMappings(info.userId, key);
105
109
  const unsubscribes = [];
106
- if (!(options === null || options === void 0 ? void 0 : options.disableAutoRemoveOnClose)) {
107
- unsubscribes.push(subscribeToSocketEvent(socket, 'close', () => {
108
- var _a;
109
- (_a = this.log) === null || _a === void 0 ? void 0 : _a.call(this, 'info', `Socket closed: ${key}`);
110
- this.connections.delete(key);
111
- this.presence.removeConnection(key);
112
- unsubscribes.forEach((u) => u());
113
- }));
114
- }
110
+ /**
111
+ * Listen for websocket close and remove connection and mappings.
112
+ * If not disabled, also broadcast presence offline for the final
113
+ * connection per user.
114
+ *
115
+ * This may be disabled for environments where a closed connection
116
+ * doesn't necessarily indicate offline - Cloudflare is like this
117
+ * since it "hibernates" sockets but keeps them connected to the
118
+ * client side.
119
+ */
120
+ unsubscribes.push(subscribeToSocketEvent(socket, 'close', async () => {
121
+ var _a;
122
+ (_a = this.log) === null || _a === void 0 ? void 0 : _a.call(this, 'info', `Socket closed: ${key}`);
123
+ if (!(options === null || options === void 0 ? void 0 : options.disableAutoRemoveOnClose)) {
124
+ await this.remove(key);
125
+ }
126
+ unsubscribes.forEach((u) => u());
127
+ }));
115
128
  unsubscribes.push(subscribeToSocketEvent(socket, 'messsage', () => {
116
129
  // sockets get a long keepalive for message activity
117
130
  // since they have a reliable close event
118
- this.presence.keepAlive(key, 60 * 1000);
131
+ this.presence.keepAlive(info.userId, 60 * 1000);
119
132
  }));
120
133
  };
121
134
  this.addRequest = (key, request, response, info) => {
122
135
  const connection = new RequestClientConnection(key, request, response, info);
123
136
  this.connections.set(key, connection);
137
+ this.addMappings(info.userId, key);
124
138
  return () => {
125
139
  connection.end();
126
140
  this.connections.delete(key);
@@ -129,23 +143,27 @@ export class ClientConnectionManager {
129
143
  this.addFetch = (key, req, info) => {
130
144
  const connection = new FetchClientConnection(key, req, info);
131
145
  this.connections.set(key, connection);
146
+ this.addMappings(info.userId, key);
132
147
  return () => {
133
148
  connection.end();
134
149
  this.connections.delete(key);
135
150
  return connection.res;
136
151
  };
137
152
  };
138
- this.remove = (key) => {
153
+ this.remove = async (key) => {
139
154
  this.connections.delete(key);
140
- this.presence.removeConnection(key);
155
+ await this.removeMappings(key);
141
156
  };
142
157
  this.respond = (key, message) => {
158
+ var _a;
143
159
  const connection = this.connections.get(key);
144
160
  if (connection) {
145
161
  connection.respond(message);
162
+ return true;
146
163
  }
147
164
  else {
148
- throw new Error(`No connection found for key ${key}`);
165
+ (_a = this.log) === null || _a === void 0 ? void 0 : _a.call(this, 'warn', `Could not respond: no connection found for key: ${key}`);
166
+ return false;
149
167
  }
150
168
  };
151
169
  /**
@@ -167,8 +185,35 @@ export class ClientConnectionManager {
167
185
  }
168
186
  this.connections.clear();
169
187
  };
170
- this.presence = new Presence(profiles);
188
+ this.presence = new Presence(profiles, presenceStorage);
171
189
  this.log = log;
172
190
  }
191
+ addMappings(userId, connectionKey) {
192
+ this.connectionToUser.set(connectionKey, userId);
193
+ if (!this.userToConnections.has(userId)) {
194
+ this.userToConnections.set(userId, new Set());
195
+ }
196
+ this.userToConnections.get(userId).add(connectionKey);
197
+ }
198
+ /**
199
+ * Removes back-mappings and, if all are deleted,
200
+ * also removes user presence.
201
+ */
202
+ removeMappings(connectionKey, autoRemoveOnEmpty = true) {
203
+ const userId = this.connectionToUser.get(connectionKey);
204
+ if (userId) {
205
+ this.connectionToUser.delete(connectionKey);
206
+ const connections = this.userToConnections.get(userId);
207
+ if (connections) {
208
+ connections.delete(connectionKey);
209
+ if (connections.size === 0) {
210
+ this.userToConnections.delete(userId);
211
+ if (autoRemoveOnEmpty) {
212
+ return this.presence.remove(userId);
213
+ }
214
+ }
215
+ }
216
+ }
217
+ }
173
218
  }
174
219
  //# sourceMappingURL=ClientConnection.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ClientConnection.js","sourceRoot":"","sources":["../../../src/connections/ClientConnection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ClientConnection.js","sourceRoot":"","sources":["../../../src/connections/ClientConnection.ts"],"names":[],"mappings":"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"}
@@ -1,23 +1,40 @@
1
1
  import { EventSubscriber, UserInfo, UserInfoUpdate } from '@verdant-web/common';
2
2
  import { UserProfiles } from '../Profiles.js';
3
3
  export type PresenceEvents = {
4
- lost: (connectionKey: string, userId: string) => void;
4
+ lost: (userId: string) => void;
5
5
  };
6
+ export type PresenceStorageItem = UserInfo<any, any> & {
7
+ expiresAt: number;
8
+ };
9
+ export interface PresenceStorage {
10
+ set: (userId: string, userInfo: UserInfoUpdate, profile: any, expiresAt: number) => Promise<UserInfo<any, any>>;
11
+ setExpiresAt: (userId: string, expiresAt: number) => Promise<void>;
12
+ get: (userId: string, time: number) => Promise<UserInfo<any, any> | undefined>;
13
+ remove: (userId: string) => Promise<void>;
14
+ all: () => Promise<Record<string, UserInfo<any, any>>>;
15
+ clear: () => Promise<void>;
16
+ }
17
+ export declare class PresenceMemoryStorage implements PresenceStorage {
18
+ private presences;
19
+ set: (userId: string, userInfo: UserInfoUpdate, profile: any, expiresAt: number) => Promise<PresenceStorageItem>;
20
+ setExpiresAt: (userId: string, expiresAt: number) => Promise<void>;
21
+ get: (userId: string, time: number) => Promise<PresenceStorageItem | undefined>;
22
+ remove: (userId: string) => Promise<void>;
23
+ all: () => Promise<Record<string, PresenceStorageItem>>;
24
+ clear: () => Promise<void>;
25
+ }
6
26
  /**
7
- * Stores client presence in-memory for connected
27
+ * Stores client presence for connected
8
28
  * clients
9
29
  */
10
30
  export declare class Presence extends EventSubscriber<PresenceEvents> {
11
31
  readonly profiles: UserProfiles<any>;
12
- private presences;
13
- private connectionToUser;
14
- private userToConnection;
15
- private keepalives;
16
- constructor(profiles: UserProfiles<any>);
17
- set: (connectionKey: string, userId: string, userInfo: UserInfoUpdate) => Promise<UserInfo<any, any>>;
18
- keepAlive: (connectionKey: string, duration?: number) => void;
19
- get: (userId: string) => UserInfo<any, any>;
20
- removeConnection: (connectionKey: string) => void;
21
- all: () => Record<string, UserInfo<any, any>>;
32
+ readonly storage: PresenceStorage;
33
+ constructor(profiles: UserProfiles<any>, storage?: PresenceStorage);
34
+ set: (userId: string, userInfo: UserInfoUpdate) => Promise<UserInfo<any, any>>;
35
+ keepAlive: (userId: string, duration?: number) => void;
36
+ get: (userId: string) => Promise<UserInfo<any, any> | undefined>;
37
+ remove: (userId: string) => Promise<void>;
38
+ all: () => Promise<Record<string, UserInfo<any, any>>>;
22
39
  clear: () => void;
23
40
  }
@@ -1,64 +1,74 @@
1
1
  import { EventSubscriber, initialInternalPresence, } from '@verdant-web/common';
2
- /**
3
- * Stores client presence in-memory for connected
4
- * clients
5
- */
6
- export class Presence extends EventSubscriber {
7
- constructor(profiles) {
8
- super();
9
- this.profiles = profiles;
2
+ const DEFAULT_EXPIRATION_TIME = 60 * 1000;
3
+ export class PresenceMemoryStorage {
4
+ constructor() {
10
5
  this.presences = {};
11
- this.connectionToUser = {};
12
- this.userToConnection = {};
13
- this.keepalives = new Map();
14
- this.set = async (connectionKey, userId, userInfo) => {
6
+ this.set = async (userId, userInfo, profile, expiresAt) => {
15
7
  if (!this.presences[userId]) {
16
- this.presences[userId] = Object.assign(Object.assign({}, userInfo), { profile: await this.profiles.get(userId), internal: userInfo.internal || initialInternalPresence });
8
+ this.presences[userId] = Object.assign(Object.assign({}, userInfo), { expiresAt,
9
+ profile, internal: userInfo.internal || initialInternalPresence });
17
10
  }
18
11
  else {
19
12
  Object.assign(this.presences[userId], userInfo);
20
13
  }
21
- this.connectionToUser[connectionKey] = userId;
22
- this.userToConnection[userId] =
23
- this.userToConnection[userId] || new Set();
24
- this.userToConnection[userId].add(connectionKey);
25
- this.keepAlive(connectionKey);
26
14
  return this.presences[userId];
27
15
  };
28
- this.keepAlive = (connectionKey, duration = 60 * 1000) => {
29
- const existing = this.keepalives.get(connectionKey);
30
- if (existing) {
31
- clearTimeout(existing);
16
+ this.setExpiresAt = async (userId, expiresAt) => {
17
+ const presence = this.presences[userId];
18
+ if (presence) {
19
+ presence.expiresAt = expiresAt;
32
20
  }
33
- this.keepalives.set(connectionKey, setTimeout(() => {
34
- this.removeConnection(connectionKey);
35
- this.keepalives.delete(connectionKey);
36
- }, duration));
37
21
  };
38
- this.get = (userId) => {
39
- return this.presences[userId];
22
+ this.get = async (userId, time) => {
23
+ const value = this.presences[userId];
24
+ if (value && value.expiresAt > time) {
25
+ return value;
26
+ }
27
+ return undefined;
40
28
  };
41
- this.removeConnection = (connectionKey) => {
42
- const userId = this.connectionToUser[connectionKey];
43
- if (!userId)
44
- return;
45
- this.userToConnection[userId].delete(connectionKey);
46
- if (this.userToConnection[userId].size === 0) {
47
- delete this.presences[userId];
48
- this.emit('lost', connectionKey, userId);
49
- // memory cleanup
50
- if (Object.keys(this.presences).length === 0) {
51
- this.clear();
52
- }
29
+ this.remove = async (userId) => {
30
+ delete this.presences[userId];
31
+ if (Object.keys(this.presences).length === 0) {
32
+ this.clear();
53
33
  }
54
34
  };
55
- this.all = () => {
35
+ this.all = async () => {
56
36
  return this.presences;
57
37
  };
58
- this.clear = () => {
38
+ this.clear = async () => {
59
39
  this.presences = {};
60
- this.connectionToUser = {};
61
- this.userToConnection = {};
40
+ };
41
+ }
42
+ }
43
+ /**
44
+ * Stores client presence for connected
45
+ * clients
46
+ */
47
+ export class Presence extends EventSubscriber {
48
+ constructor(profiles, storage = new PresenceMemoryStorage()) {
49
+ super();
50
+ this.profiles = profiles;
51
+ this.storage = storage;
52
+ this.set = async (userId, userInfo) => {
53
+ const value = await this.storage.set(userId, userInfo, await this.profiles.get(userId), Date.now() + DEFAULT_EXPIRATION_TIME);
54
+ return value;
55
+ };
56
+ this.keepAlive = (userId, duration = DEFAULT_EXPIRATION_TIME) => {
57
+ const time = Date.now() + duration;
58
+ this.storage.setExpiresAt(userId, time);
59
+ };
60
+ this.get = (userId) => {
61
+ return this.storage.get(userId, Date.now());
62
+ };
63
+ this.remove = async (userId) => {
64
+ await this.storage.remove(userId);
65
+ this.emit('lost', userId);
66
+ };
67
+ this.all = () => {
68
+ return this.storage.all();
69
+ };
70
+ this.clear = () => {
71
+ this.storage.clear();
62
72
  };
63
73
  }
64
74
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Presence.js","sourceRoot":"","sources":["../../../src/connections/Presence.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Presence.js","sourceRoot":"","sources":["../../../src/connections/Presence.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ export { errorHandler } from './adapters/node/errorHandler.js';
2
2
  export { createHttpRouter as createHonoRouter } from './adapters/node/httpRouter.js';
3
3
  export { tokenMiddleware } from './adapters/node/tokenMiddleware.js';
4
4
  export { ClientConnectionManager } from './connections/ClientConnection.js';
5
+ export type * from './connections/Presence.js';
5
6
  export { FileStorageLibraryDelegate } from './files/FileStorage.js';
6
7
  export type * from './libraries/generic.js';
7
8
  export { Library, type LibraryEvents } from './libraries/Library.js';
@@ -1 +1 @@
1
- {"version":3,"file":"internals.js","sourceRoot":"","sources":["../../src/internals.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EAAE,gBAAgB,IAAI,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACrF,OAAO,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AAC5E,OAAO,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAEpE,OAAO,EAAE,OAAO,EAAsB,MAAM,wBAAwB,CAAC;AAErE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAExE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"internals.js","sourceRoot":"","sources":["../../src/internals.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EAAE,gBAAgB,IAAI,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACrF,OAAO,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AAE5E,OAAO,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAEpE,OAAO,EAAE,OAAO,EAAsB,MAAM,wBAAwB,CAAC;AAErE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAExE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
@@ -1,7 +1,6 @@
1
1
  import { ClientMessage, DocumentBaseline, EventSubscriber, Operation } from '@verdant-web/common';
2
- import { MessageSender } from '../connections/MessageSender.js';
3
- import { Presence } from '../connections/Presence.js';
4
2
  import { FileInfo, FileStorageLibraryDelegate } from '../files/FileStorage.js';
3
+ import { ClientConnectionManager } from '../internals.js';
5
4
  import { Logger } from '../logger.js';
6
5
  import { Storage } from '../storage/Storage.js';
7
6
  import { TokenInfo } from '../TokenVerifier.js';
@@ -18,22 +17,22 @@ export interface LibraryFileInfo {
18
17
  }
19
18
  export declare class Library {
20
19
  private storage;
21
- private sender;
22
20
  private disableRebasing;
23
21
  private fileStorage;
24
22
  private events;
25
23
  readonly id: string;
26
- private presence;
24
+ private clientConnections;
25
+ private get presence();
26
+ private get sender();
27
27
  private log;
28
- constructor({ storage, sender, log, disableRebasing, fileStorage, events, id, presence, }: {
28
+ constructor({ storage, log, disableRebasing, fileStorage, events, id, clientConnections, }: {
29
29
  storage: Storage;
30
- sender: MessageSender;
31
30
  log?: Logger;
32
31
  disableRebasing?: boolean;
33
32
  fileStorage?: FileStorageLibraryDelegate;
34
33
  events?: EventSubscriber<LibraryEvents>;
35
34
  id: string;
36
- presence: Presence;
35
+ clientConnections: ClientConnectionManager;
37
36
  });
38
37
  private validateReplicaAccess;
39
38
  private hasWriteAccess;
@@ -1,6 +1,12 @@
1
1
  import { applyOperations, isFileRef, isObjectRef, ReplicaType, rewriteAuthzOriginator, } from '@verdant-web/common';
2
2
  export class Library {
3
- constructor({ storage, sender, log = () => { }, disableRebasing, fileStorage, events, id, presence, }) {
3
+ get presence() {
4
+ return this.clientConnections.presence;
5
+ }
6
+ get sender() {
7
+ return this.clientConnections;
8
+ }
9
+ constructor({ storage, log = () => { }, disableRebasing, fileStorage, events, id, clientConnections, }) {
4
10
  this.validateReplicaAccess = async (replicaId, clientKey, info) => {
5
11
  const replica = await this.storage.replicas.get(replicaId);
6
12
  if (replica && replica.clientId !== info.userId) {
@@ -229,7 +235,12 @@ export class Library {
229
235
  ? this.createAckNonce(serverOrderToAck)
230
236
  : undefined;
231
237
  // respond to client
232
- this.log('info', 'Sending sync response with', ops.length, 'operations and', baselines.length, 'baselines', 'to client key', clientKey);
238
+ const peerPresence = await this.presence.all();
239
+ this.log('info', 'Sending sync response with', {
240
+ ops: ops.length,
241
+ baselines: baselines.length,
242
+ peers: Object.keys(peerPresence),
243
+ }, 'to client key', clientKey);
233
244
  // mutating baselines/operations to remove extra data -
234
245
  // mutating just to save on allocations here.
235
246
  try {
@@ -238,7 +249,7 @@ export class Library {
238
249
  operations: this.removeOperationExtras(ops),
239
250
  baselines: this.removeBaselineExtras(baselines),
240
251
  globalAckTimestamp: (_b = (await this.storage.replicas.getGlobalAck())) !== null && _b !== void 0 ? _b : undefined,
241
- peerPresence: this.presence.all(),
252
+ peerPresence,
242
253
  // only request the client to overwrite local data if a reset is requested
243
254
  // and there is data to overwrite it. otherwise the client may still
244
255
  // send its own history to us.
@@ -278,7 +289,7 @@ export class Library {
278
289
  }
279
290
  };
280
291
  this.handleDisconnecting = async (_message, clientKey, _info) => {
281
- this.presence.removeConnection(clientKey);
292
+ await this.clientConnections.remove(clientKey);
282
293
  };
283
294
  this.updateHighwater = async (replicaId, timestamp, info, ignoreClientKeys = []) => {
284
295
  await this.storage.replicas.updateAcknowledgedLogicalTime(replicaId, timestamp);
@@ -317,7 +328,7 @@ export class Library {
317
328
  // for global ack, to determine consensus, also allow
318
329
  // for all actively connected replicas to ack regardless of their
319
330
  // type.
320
- const activeReplicaIds = Object.values(this.presence.all()).map((p) => p.replicaId);
331
+ const activeReplicaIds = Object.values(await this.presence.all()).map((p) => p.replicaId);
321
332
  const globalAck = await this.storage.replicas.getGlobalAck(activeReplicaIds);
322
333
  const globalServerOrder = await this.storage.replicas.getEarliestAckedServerOrder();
323
334
  if (!globalAck) {
@@ -367,7 +378,7 @@ export class Library {
367
378
  });
368
379
  };
369
380
  this.handlePresenceUpdate = async (message, clientKey, info) => {
370
- const updated = await this.presence.set(clientKey, info.userId, {
381
+ const updated = await this.presence.set(info.userId, {
371
382
  presence: message.presence,
372
383
  internal: message.internal,
373
384
  replicaId: message.replicaId,
@@ -381,14 +392,13 @@ export class Library {
381
392
  // mirror back to the replica which sent it so it has profile
382
393
  []);
383
394
  };
384
- this.onPresenceLost = async (replicaId, userId) => {
385
- this.log('info', 'User disconnected from all replicas:', userId, 'replica:', replicaId);
395
+ this.onPresenceLost = async (userId) => {
396
+ this.log('info', 'User disconnected from all replicas:', userId);
386
397
  this.sender.broadcast({
387
398
  type: 'presence-offline',
388
- replicaId,
389
399
  userId,
390
400
  });
391
- if (Object.keys(this.presence.all()).length === 0) {
401
+ if (Object.keys(await this.presence.all()).length === 0) {
392
402
  this.log('info', `All users have disconnected`);
393
403
  // could happen - if the server is shutting down manually
394
404
  if (!this.storage.open) {
@@ -441,7 +451,7 @@ export class Library {
441
451
  }
442
452
  };
443
453
  this.getPresence = () => {
444
- return Promise.resolve(this.presence.all());
454
+ return this.presence.all();
445
455
  };
446
456
  this.getInfo = async () => {
447
457
  var _a;
@@ -576,12 +586,11 @@ export class Library {
576
586
  };
577
587
  this.id = id;
578
588
  this.storage = storage;
579
- this.sender = sender;
580
589
  this.log = log;
581
590
  this.disableRebasing = !!disableRebasing;
582
591
  this.fileStorage = fileStorage;
583
592
  this.events = events;
584
- this.presence = presence;
593
+ this.clientConnections = clientConnections;
585
594
  this.presence.subscribe('lost', this.onPresenceLost);
586
595
  }
587
596
  }