sonamu 0.11.16 → 0.12.0

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.
Files changed (65) hide show
  1. package/dist/api/sonamu.d.ts.map +1 -1
  2. package/dist/api/sonamu.js +12 -7
  3. package/dist/index.d.ts +1 -0
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +4 -2
  6. package/dist/stream/__tests__/ws-test-helpers.d.ts +108 -0
  7. package/dist/stream/__tests__/ws-test-helpers.d.ts.map +1 -0
  8. package/dist/stream/__tests__/ws-test-helpers.js +260 -0
  9. package/dist/stream/index.d.ts +1 -0
  10. package/dist/stream/index.d.ts.map +1 -1
  11. package/dist/stream/index.js +4 -2
  12. package/dist/stream/ws-audience-resolver.d.ts +8 -5
  13. package/dist/stream/ws-audience-resolver.d.ts.map +1 -1
  14. package/dist/stream/ws-audience-resolver.js +16 -13
  15. package/dist/stream/ws-cluster-bus.d.ts +9 -4
  16. package/dist/stream/ws-cluster-bus.d.ts.map +1 -1
  17. package/dist/stream/ws-cluster-bus.js +1 -1
  18. package/dist/stream/ws-core.d.ts +10 -0
  19. package/dist/stream/ws-core.d.ts.map +1 -1
  20. package/dist/stream/ws-delivery.d.ts +30 -4
  21. package/dist/stream/ws-delivery.d.ts.map +1 -1
  22. package/dist/stream/ws-delivery.js +199 -52
  23. package/dist/stream/ws-frame.d.ts +15 -0
  24. package/dist/stream/ws-frame.d.ts.map +1 -0
  25. package/dist/stream/ws-frame.js +29 -0
  26. package/dist/stream/ws-local-connection-store.d.ts +4 -4
  27. package/dist/stream/ws-local-connection-store.d.ts.map +1 -1
  28. package/dist/stream/ws-local-connection-store.js +2 -2
  29. package/dist/stream/ws-presence-index.d.ts +36 -0
  30. package/dist/stream/ws-presence-index.d.ts.map +1 -0
  31. package/dist/stream/ws-presence-index.js +177 -0
  32. package/dist/stream/ws-presence-store.d.ts +39 -39
  33. package/dist/stream/ws-presence-store.d.ts.map +1 -1
  34. package/dist/stream/ws-presence-store.js +22 -152
  35. package/dist/stream/ws-registry.d.ts +45 -17
  36. package/dist/stream/ws-registry.d.ts.map +1 -1
  37. package/dist/stream/ws-registry.js +169 -60
  38. package/dist/stream/ws-session-id.d.ts +14 -0
  39. package/dist/stream/ws-session-id.d.ts.map +1 -0
  40. package/dist/stream/ws-session-id.js +37 -0
  41. package/dist/stream/ws.d.ts +20 -10
  42. package/dist/stream/ws.d.ts.map +1 -1
  43. package/dist/stream/ws.js +59 -36
  44. package/package.json +1 -1
  45. package/src/api/__tests__/sonamu.websocket-routes.test.ts +234 -0
  46. package/src/api/__tests__/sonamu.websocket.test.ts +241 -20
  47. package/src/api/sonamu.ts +20 -7
  48. package/src/index.ts +1 -0
  49. package/src/stream/__tests__/ws-contracts.test.ts +483 -265
  50. package/src/stream/__tests__/ws-multinode.test.ts +326 -0
  51. package/src/stream/__tests__/ws-registry-async.test.ts +855 -0
  52. package/src/stream/__tests__/ws-test-helpers.ts +360 -0
  53. package/src/stream/__tests__/ws.test.ts +342 -145
  54. package/src/stream/index.ts +1 -0
  55. package/src/stream/ws-audience-resolver.ts +21 -19
  56. package/src/stream/ws-cluster-bus.ts +12 -4
  57. package/src/stream/ws-core.ts +14 -0
  58. package/src/stream/ws-delivery.ts +321 -97
  59. package/src/stream/ws-frame.ts +39 -0
  60. package/src/stream/ws-local-connection-store.ts +10 -9
  61. package/src/stream/ws-presence-index.ts +273 -0
  62. package/src/stream/ws-presence-store.ts +64 -284
  63. package/src/stream/ws-registry.ts +272 -85
  64. package/src/stream/ws-session-id.ts +39 -0
  65. package/src/stream/ws.ts +91 -50
@@ -1,177 +1,47 @@
1
1
  import { __esmMin } from "../_virtual/_rolldown/runtime.js";
2
+ import { WebSocketPresenceIndex, init_ws_presence_index } from "./ws-presence-index.js";
2
3
  //#region src/stream/ws-presence-store.ts
3
- function getBindingKey(namespace, id) {
4
- return `${namespace}::${id}`;
5
- }
6
- function parseBindingKey(key) {
7
- const [namespace, ...rest] = key.split("::");
8
- return {
9
- namespace,
10
- id: rest.join("::")
11
- };
12
- }
13
4
  var InMemoryWebSocketPresenceStore;
14
5
  var init_ws_presence_store = __esmMin((() => {
6
+ init_ws_presence_index();
15
7
  InMemoryWebSocketPresenceStore = class {
16
- connections = /* @__PURE__ */ new Map();
17
- rooms = /* @__PURE__ */ new Map();
18
- users = /* @__PURE__ */ new Map();
8
+ index = new WebSocketPresenceIndex();
19
9
  register(input) {
20
- const meta = {
21
- sessionId: input.sessionId,
22
- nodeId: input.nodeId,
23
- namespace: input.namespace,
24
- active: input.active ?? true,
25
- rooms: /* @__PURE__ */ new Set(),
26
- connectedAt: /* @__PURE__ */ new Date(),
27
- lastSeenAt: /* @__PURE__ */ new Date()
28
- };
29
- this.connections.set(input.sessionId, meta);
30
- return meta;
10
+ this.index.register(input);
31
11
  }
32
12
  activate(sessionId) {
33
- const meta = this.connections.get(sessionId);
34
- if (!meta) return;
35
- meta.active = true;
13
+ this.index.activate(sessionId);
36
14
  }
37
15
  unregister(sessionId) {
38
- const meta = this.connections.get(sessionId);
39
- if (!meta) return;
40
- if (meta.userId !== void 0) this.removeUserBinding(meta.namespace, meta.userId, sessionId);
41
- for (const roomId of meta.rooms) this.removeRoomBinding(meta.namespace, roomId, sessionId);
42
- this.connections.delete(sessionId);
43
- return meta;
44
- }
45
- touch(sessionId) {
46
- const meta = this.connections.get(sessionId);
47
- if (!meta) return;
48
- meta.lastSeenAt = /* @__PURE__ */ new Date();
16
+ this.index.unregister(sessionId);
49
17
  }
50
18
  setUserId(sessionId, userId) {
51
- const meta = this.connections.get(sessionId);
52
- if (!meta) return;
53
- if (meta.userId !== void 0) this.removeUserBinding(meta.namespace, meta.userId, sessionId);
54
- meta.userId = userId;
55
- const key = getBindingKey(meta.namespace, String(userId));
56
- const bound = this.users.get(key) ?? /* @__PURE__ */ new Set();
57
- bound.add(sessionId);
58
- this.users.set(key, bound);
19
+ this.index.setUserId(sessionId, userId);
59
20
  }
60
21
  clearUserId(sessionId) {
61
- const meta = this.connections.get(sessionId);
62
- if (!meta || meta.userId === void 0) return;
63
- this.removeUserBinding(meta.namespace, meta.userId, sessionId);
64
- delete meta.userId;
22
+ this.index.clearUserId(sessionId);
65
23
  }
66
24
  join(sessionId, roomId) {
67
- const meta = this.connections.get(sessionId);
68
- if (!meta) return;
69
- meta.rooms.add(roomId);
70
- const key = getBindingKey(meta.namespace, roomId);
71
- const members = this.rooms.get(key) ?? /* @__PURE__ */ new Set();
72
- members.add(sessionId);
73
- this.rooms.set(key, members);
25
+ this.index.join(sessionId, roomId);
74
26
  }
75
27
  leave(sessionId, roomId) {
76
- const meta = this.connections.get(sessionId);
77
- if (!meta) return;
78
- meta.rooms.delete(roomId);
79
- this.removeRoomBinding(meta.namespace, roomId, sessionId);
80
- }
81
- getConnection(sessionId) {
82
- return this.connections.get(sessionId);
83
- }
84
- getConnectionCount(namespace) {
85
- let count = 0;
86
- for (const meta of this.connections.values()) {
87
- if (!meta.active || namespace && meta.namespace !== namespace) continue;
88
- count += 1;
89
- }
90
- return count;
28
+ this.index.leave(sessionId, roomId);
91
29
  }
92
- getRoomMembers(roomId, namespace) {
93
- return this.getBoundConnections(this.rooms, roomId, namespace);
94
- }
95
- getStats() {
96
- const byNamespace = {};
97
- for (const meta of this.connections.values()) {
98
- if (!meta.active) continue;
99
- byNamespace[meta.namespace] = (byNamespace[meta.namespace] ?? 0) + 1;
100
- }
30
+ resolveRoute(audience, nodeId) {
31
+ const localSessionIds = [];
32
+ const remoteNodeIds = /* @__PURE__ */ new Set();
33
+ for (const session of this.index.queryAudience(audience)) if (session.nodeId === nodeId) localSessionIds.push(session.sessionId);
34
+ else remoteNodeIds.add(session.nodeId);
101
35
  return {
102
- totalConnections: Object.values(byNamespace).reduce((sum, count) => sum + count, 0),
103
- totalRooms: this.rooms.size,
104
- byNamespace
36
+ localSessionIds,
37
+ remoteNodeIds: [...remoteNodeIds]
105
38
  };
106
39
  }
107
- queryAudience(audience) {
108
- switch (audience.type) {
109
- case "all": return this.getActiveConnections(audience.namespace);
110
- case "room": return this.getBoundConnections(this.rooms, audience.roomId, audience.namespace);
111
- case "user": return this.getBoundConnections(this.users, String(audience.userId), audience.namespace);
112
- case "connections": {
113
- const metas = [];
114
- for (const connectionId of audience.connectionIds) {
115
- const meta = this.connections.get(connectionId);
116
- if (!meta?.active) continue;
117
- if (audience.namespace && meta.namespace !== audience.namespace) continue;
118
- metas.push(meta);
119
- }
120
- return metas;
121
- }
122
- case "union": {
123
- const seen = /* @__PURE__ */ new Set();
124
- const metas = [];
125
- for (const item of audience.audiences) for (const meta of this.queryAudience(item)) {
126
- if (seen.has(meta.sessionId)) continue;
127
- seen.add(meta.sessionId);
128
- metas.push(meta);
129
- }
130
- return metas;
131
- }
132
- }
133
- }
134
- getActiveConnections(namespace) {
135
- const metas = [];
136
- for (const meta of this.connections.values()) {
137
- if (!meta.active || namespace && meta.namespace !== namespace) continue;
138
- metas.push(meta);
139
- }
140
- return metas;
141
- }
142
- getBoundConnections(bindings, id, namespace) {
143
- const metas = [];
144
- const seen = /* @__PURE__ */ new Set();
145
- for (const members of this.getScopedBindings(bindings, id, namespace)) for (const connectionId of members) {
146
- if (seen.has(connectionId)) continue;
147
- seen.add(connectionId);
148
- const meta = this.connections.get(connectionId);
149
- if (meta?.active) metas.push(meta);
150
- }
151
- return metas;
40
+ getRoomMemberCount(roomId, namespace) {
41
+ return this.index.getRoomMemberCount(roomId, namespace);
152
42
  }
153
- getScopedBindings(bindings, id, namespace) {
154
- if (namespace) {
155
- const exact = bindings.get(getBindingKey(namespace, id));
156
- return exact ? [exact] : [];
157
- }
158
- const matches = [];
159
- for (const [key, members] of bindings) if (parseBindingKey(key).id === id) matches.push(members);
160
- return matches;
161
- }
162
- removeRoomBinding(namespace, roomId, sessionId) {
163
- const key = getBindingKey(namespace, roomId);
164
- const members = this.rooms.get(key);
165
- if (!members) return;
166
- members.delete(sessionId);
167
- if (members.size === 0) this.rooms.delete(key);
168
- }
169
- removeUserBinding(namespace, userId, sessionId) {
170
- const key = getBindingKey(namespace, String(userId));
171
- const members = this.users.get(key);
172
- if (!members) return;
173
- members.delete(sessionId);
174
- if (members.size === 0) this.users.delete(key);
43
+ getConnection(sessionId) {
44
+ return this.index.getConnection(sessionId);
175
45
  }
176
46
  };
177
47
  }));
@@ -179,4 +49,4 @@ var init_ws_presence_store = __esmMin((() => {
179
49
  init_ws_presence_store();
180
50
  export { InMemoryWebSocketPresenceStore, init_ws_presence_store };
181
51
 
182
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid3MtcHJlc2VuY2Utc3RvcmUuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3N0cmVhbS93cy1wcmVzZW5jZS1zdG9yZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyB0eXBlIFdlYlNvY2tldEF1ZGllbmNlIH0gZnJvbSBcIi4vd3MtYXVkaWVuY2VcIjtcbmltcG9ydCB7IHR5cGUgV2ViU29ja2V0UmVnaXN0cnlTdGF0cywgdHlwZSBXZWJTb2NrZXRSb29tSWQsIHR5cGUgV2ViU29ja2V0VXNlcklkIH0gZnJvbSBcIi4vd3MtY29yZVwiO1xuXG5leHBvcnQgdHlwZSBXZWJTb2NrZXRTZXNzaW9uUHJlc2VuY2UgPSB7XG4gIHNlc3Npb25JZDogc3RyaW5nO1xuICBub2RlSWQ6IHN0cmluZztcbiAgbmFtZXNwYWNlOiBzdHJpbmc7XG4gIGFjdGl2ZTogYm9vbGVhbjtcbiAgcm9vbXM6IFNldDxXZWJTb2NrZXRSb29tSWQ+O1xuICBjb25uZWN0ZWRBdDogRGF0ZTtcbiAgbGFzdFNlZW5BdDogRGF0ZTtcbiAgdXNlcklkPzogV2ViU29ja2V0VXNlcklkO1xufTtcblxuZXhwb3J0IGludGVyZmFjZSBXZWJTb2NrZXRQcmVzZW5jZVN0b3JlIHtcbiAgcmVnaXN0ZXIoaW5wdXQ6IHtcbiAgICBzZXNzaW9uSWQ6IHN0cmluZztcbiAgICBub2RlSWQ6IHN0cmluZztcbiAgICBuYW1lc3BhY2U6IHN0cmluZztcbiAgICBhY3RpdmU/OiBib29sZWFuO1xuICB9KTogV2ViU29ja2V0U2Vzc2lvblByZXNlbmNlO1xuICBhY3RpdmF0ZShzZXNzaW9uSWQ6IHN0cmluZyk6IHZvaWQ7XG4gIHVucmVnaXN0ZXIoc2Vzc2lvbklkOiBzdHJpbmcpOiBXZWJTb2NrZXRTZXNzaW9uUHJlc2VuY2UgfCB1bmRlZmluZWQ7XG4gIHRvdWNoKHNlc3Npb25JZDogc3RyaW5nKTogdm9pZDtcbiAgc2V0VXNlcklkKHNlc3Npb25JZDogc3RyaW5nLCB1c2VySWQ6IFdlYlNvY2tldFVzZXJJZCk6IHZvaWQ7XG4gIGNsZWFyVXNlcklkKHNlc3Npb25JZDogc3RyaW5nKTogdm9pZDtcbiAgam9pbihzZXNzaW9uSWQ6IHN0cmluZywgcm9vbUlkOiBXZWJTb2NrZXRSb29tSWQpOiB2b2lkO1xuICBsZWF2ZShzZXNzaW9uSWQ6IHN0cmluZywgcm9vbUlkOiBXZWJTb2NrZXRSb29tSWQpOiB2b2lkO1xuICBnZXRDb25uZWN0aW9uKHNlc3Npb25JZDogc3RyaW5nKTogV2ViU29ja2V0U2Vzc2lvblByZXNlbmNlIHwgdW5kZWZpbmVkO1xuICBnZXRDb25uZWN0aW9uQ291bnQobmFtZXNwYWNlPzogc3RyaW5nKTogbnVtYmVyO1xuICBnZXRSb29tTWVtYmVycyhyb29tSWQ6IFdlYlNvY2tldFJvb21JZCwgbmFtZXNwYWNlPzogc3RyaW5nKTogV2ViU29ja2V0U2Vzc2lvblByZXNlbmNlW107XG4gIGdldFN0YXRzKCk6IFdlYlNvY2tldFJlZ2lzdHJ5U3RhdHM7XG4gIHF1ZXJ5QXVkaWVuY2UoYXVkaWVuY2U6IFdlYlNvY2tldEF1ZGllbmNlKTogV2ViU29ja2V0U2Vzc2lvblByZXNlbmNlW107XG59XG5cbmV4cG9ydCBjbGFzcyBJbk1lbW9yeVdlYlNvY2tldFByZXNlbmNlU3RvcmUgaW1wbGVtZW50cyBXZWJTb2NrZXRQcmVzZW5jZVN0b3JlIHtcbiAgcHJpdmF0ZSByZWFkb25seSBjb25uZWN0aW9ucyA9IG5ldyBNYXA8c3RyaW5nLCBXZWJTb2NrZXRTZXNzaW9uUHJlc2VuY2U+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgcm9vbXMgPSBuZXcgTWFwPHN0cmluZywgU2V0PHN0cmluZz4+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgdXNlcnMgPSBuZXcgTWFwPHN0cmluZywgU2V0PHN0cmluZz4+KCk7XG5cbiAgcmVnaXN0ZXIoaW5wdXQ6IHtcbiAgICBzZXNzaW9uSWQ6IHN0cmluZztcbiAgICBub2RlSWQ6IHN0cmluZztcbiAgICBuYW1lc3BhY2U6IHN0cmluZztcbiAgICBhY3RpdmU/OiBib29sZWFuO1xuICB9KTogV2ViU29ja2V0U2Vzc2lvblByZXNlbmNlIHtcbiAgICBjb25zdCBtZXRhOiBXZWJTb2NrZXRTZXNzaW9uUHJlc2VuY2UgPSB7XG4gICAgICBzZXNzaW9uSWQ6IGlucHV0LnNlc3Npb25JZCxcbiAgICAgIG5vZGVJZDogaW5wdXQubm9kZUlkLFxuICAgICAgbmFtZXNwYWNlOiBpbnB1dC5uYW1lc3BhY2UsXG4gICAgICBhY3RpdmU6IGlucHV0LmFjdGl2ZSA/PyB0cnVlLFxuICAgICAgcm9vbXM6IG5ldyBTZXQoKSxcbiAgICAgIGNvbm5lY3RlZEF0OiBuZXcgRGF0ZSgpLFxuICAgICAgbGFzdFNlZW5BdDogbmV3IERhdGUoKSxcbiAgICB9O1xuICAgIHRoaXMuY29ubmVjdGlvbnMuc2V0KGlucHV0LnNlc3Npb25JZCwgbWV0YSk7XG4gICAgcmV0dXJuIG1ldGE7XG4gIH1cblxuICBhY3RpdmF0ZShzZXNzaW9uSWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLmNvbm5lY3Rpb25zLmdldChzZXNzaW9uSWQpO1xuICAgIGlmICghbWV0YSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIG1ldGEuYWN0aXZlID0gdHJ1ZTtcbiAgfVxuXG4gIHVucmVnaXN0ZXIoc2Vzc2lvbklkOiBzdHJpbmcpOiBXZWJTb2NrZXRTZXNzaW9uUHJlc2VuY2UgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLmNvbm5lY3Rpb25zLmdldChzZXNzaW9uSWQpO1xuICAgIGlmICghbWV0YSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBpZiAobWV0YS51c2VySWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5yZW1vdmVVc2VyQmluZGluZyhtZXRhLm5hbWVzcGFjZSwgbWV0YS51c2VySWQsIHNlc3Npb25JZCk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCByb29tSWQgb2YgbWV0YS5yb29tcykge1xuICAgICAgdGhpcy5yZW1vdmVSb29tQmluZGluZyhtZXRhLm5hbWVzcGFjZSwgcm9vbUlkLCBzZXNzaW9uSWQpO1xuICAgIH1cblxuICAgIHRoaXMuY29ubmVjdGlvbnMuZGVsZXRlKHNlc3Npb25JZCk7XG4gICAgcmV0dXJuIG1ldGE7XG4gIH1cblxuICB0b3VjaChzZXNzaW9uSWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLmNvbm5lY3Rpb25zLmdldChzZXNzaW9uSWQpO1xuICAgIGlmICghbWV0YSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIG1ldGEubGFzdFNlZW5BdCA9IG5ldyBEYXRlKCk7XG4gIH1cblxuICBzZXRVc2VySWQoc2Vzc2lvbklkOiBzdHJpbmcsIHVzZXJJZDogV2ViU29ja2V0VXNlcklkKTogdm9pZCB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuY29ubmVjdGlvbnMuZ2V0KHNlc3Npb25JZCk7XG4gICAgaWYgKCFtZXRhKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKG1ldGEudXNlcklkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMucmVtb3ZlVXNlckJpbmRpbmcobWV0YS5uYW1lc3BhY2UsIG1ldGEudXNlcklkLCBzZXNzaW9uSWQpO1xuICAgIH1cblxuICAgIG1ldGEudXNlcklkID0gdXNlcklkO1xuICAgIGNvbnN0IGtleSA9IGdldEJpbmRpbmdLZXkobWV0YS5uYW1lc3BhY2UsIFN0cmluZyh1c2VySWQpKTtcbiAgICBjb25zdCBib3VuZCA9IHRoaXMudXNlcnMuZ2V0KGtleSkgPz8gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgYm91bmQuYWRkKHNlc3Npb25JZCk7XG4gICAgdGhpcy51c2Vycy5zZXQoa2V5LCBib3VuZCk7XG4gIH1cblxuICBjbGVhclVzZXJJZChzZXNzaW9uSWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLmNvbm5lY3Rpb25zLmdldChzZXNzaW9uSWQpO1xuICAgIGlmICghbWV0YSB8fCBtZXRhLnVzZXJJZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5yZW1vdmVVc2VyQmluZGluZyhtZXRhLm5hbWVzcGFjZSwgbWV0YS51c2VySWQsIHNlc3Npb25JZCk7XG4gICAgZGVsZXRlIG1ldGEudXNlcklkO1xuICB9XG5cbiAgam9pbihzZXNzaW9uSWQ6IHN0cmluZywgcm9vbUlkOiBXZWJTb2NrZXRSb29tSWQpOiB2b2lkIHtcbiAgICBjb25zdCBtZXRhID0gdGhpcy5jb25uZWN0aW9ucy5nZXQoc2Vzc2lvbklkKTtcbiAgICBpZiAoIW1ldGEpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBtZXRhLnJvb21zLmFkZChyb29tSWQpO1xuICAgIGNvbnN0IGtleSA9IGdldEJpbmRpbmdLZXkobWV0YS5uYW1lc3BhY2UsIHJvb21JZCk7XG4gICAgY29uc3QgbWVtYmVycyA9IHRoaXMucm9vbXMuZ2V0KGtleSkgPz8gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgbWVtYmVycy5hZGQoc2Vzc2lvbklkKTtcbiAgICB0aGlzLnJvb21zLnNldChrZXksIG1lbWJlcnMpO1xuICB9XG5cbiAgbGVhdmUoc2Vzc2lvbklkOiBzdHJpbmcsIHJvb21JZDogV2ViU29ja2V0Um9vbUlkKTogdm9pZCB7XG4gICAgY29uc3QgbWV0YSA9IHRoaXMuY29ubmVjdGlvbnMuZ2V0KHNlc3Npb25JZCk7XG4gICAgaWYgKCFtZXRhKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbWV0YS5yb29tcy5kZWxldGUocm9vbUlkKTtcbiAgICB0aGlzLnJlbW92ZVJvb21CaW5kaW5nKG1ldGEubmFtZXNwYWNlLCByb29tSWQsIHNlc3Npb25JZCk7XG4gIH1cblxuICBnZXRDb25uZWN0aW9uKHNlc3Npb25JZDogc3RyaW5nKTogV2ViU29ja2V0U2Vzc2lvblByZXNlbmNlIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5jb25uZWN0aW9ucy5nZXQoc2Vzc2lvbklkKTtcbiAgfVxuXG4gIGdldENvbm5lY3Rpb25Db3VudChuYW1lc3BhY2U/OiBzdHJpbmcpOiBudW1iZXIge1xuICAgIGxldCBjb3VudCA9IDA7XG5cbiAgICBmb3IgKGNvbnN0IG1ldGEgb2YgdGhpcy5jb25uZWN0aW9ucy52YWx1ZXMoKSkge1xuICAgICAgaWYgKCFtZXRhLmFjdGl2ZSB8fCAobmFtZXNwYWNlICYmIG1ldGEubmFtZXNwYWNlICE9PSBuYW1lc3BhY2UpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb3VudCArPSAxO1xuICAgIH1cblxuICAgIHJldHVybiBjb3VudDtcbiAgfVxuXG4gIGdldFJvb21NZW1iZXJzKHJvb21JZDogV2ViU29ja2V0Um9vbUlkLCBuYW1lc3BhY2U/OiBzdHJpbmcpOiBXZWJTb2NrZXRTZXNzaW9uUHJlc2VuY2VbXSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0Qm91bmRDb25uZWN0aW9ucyh0aGlzLnJvb21zLCByb29tSWQsIG5hbWVzcGFjZSk7XG4gIH1cblxuICBnZXRTdGF0cygpOiBXZWJTb2NrZXRSZWdpc3RyeVN0YXRzIHtcbiAgICBjb25zdCBieU5hbWVzcGFjZTogUmVjb3JkPHN0cmluZywgbnVtYmVyPiA9IHt9O1xuXG4gICAgZm9yIChjb25zdCBtZXRhIG9mIHRoaXMuY29ubmVjdGlvbnMudmFsdWVzKCkpIHtcbiAgICAgIGlmICghbWV0YS5hY3RpdmUpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBieU5hbWVzcGFjZVttZXRhLm5hbWVzcGFjZV0gPSAoYnlOYW1lc3BhY2VbbWV0YS5uYW1lc3BhY2VdID8/IDApICsgMTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgdG90YWxDb25uZWN0aW9uczogT2JqZWN0LnZhbHVlcyhieU5hbWVzcGFjZSkucmVkdWNlKChzdW0sIGNvdW50KSA9PiBzdW0gKyBjb3VudCwgMCksXG4gICAgICB0b3RhbFJvb21zOiB0aGlzLnJvb21zLnNpemUsXG4gICAgICBieU5hbWVzcGFjZSxcbiAgICB9O1xuICB9XG5cbiAgcXVlcnlBdWRpZW5jZShhdWRpZW5jZTogV2ViU29ja2V0QXVkaWVuY2UpOiBXZWJTb2NrZXRTZXNzaW9uUHJlc2VuY2VbXSB7XG4gICAgc3dpdGNoIChhdWRpZW5jZS50eXBlKSB7XG4gICAgICBjYXNlIFwiYWxsXCI6XG4gICAgICAgIHJldHVybiB0aGlzLmdldEFjdGl2ZUNvbm5lY3Rpb25zKGF1ZGllbmNlLm5hbWVzcGFjZSk7XG4gICAgICBjYXNlIFwicm9vbVwiOlxuICAgICAgICByZXR1cm4gdGhpcy5nZXRCb3VuZENvbm5lY3Rpb25zKHRoaXMucm9vbXMsIGF1ZGllbmNlLnJvb21JZCwgYXVkaWVuY2UubmFtZXNwYWNlKTtcbiAgICAgIGNhc2UgXCJ1c2VyXCI6XG4gICAgICAgIHJldHVybiB0aGlzLmdldEJvdW5kQ29ubmVjdGlvbnModGhpcy51c2VycywgU3RyaW5nKGF1ZGllbmNlLnVzZXJJZCksIGF1ZGllbmNlLm5hbWVzcGFjZSk7XG4gICAgICBjYXNlIFwiY29ubmVjdGlvbnNcIjoge1xuICAgICAgICBjb25zdCBtZXRhczogV2ViU29ja2V0U2Vzc2lvblByZXNlbmNlW10gPSBbXTtcblxuICAgICAgICBmb3IgKGNvbnN0IGNvbm5lY3Rpb25JZCBvZiBhdWRpZW5jZS5jb25uZWN0aW9uSWRzKSB7XG4gICAgICAgICAgY29uc3QgbWV0YSA9IHRoaXMuY29ubmVjdGlvbnMuZ2V0KGNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgaWYgKCFtZXRhPy5hY3RpdmUpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoYXVkaWVuY2UubmFtZXNwYWNlICYmIG1ldGEubmFtZXNwYWNlICE9PSBhdWRpZW5jZS5uYW1lc3BhY2UpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBtZXRhcy5wdXNoKG1ldGEpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG1ldGFzO1xuICAgICAgfVxuICAgICAgY2FzZSBcInVuaW9uXCI6IHtcbiAgICAgICAgY29uc3Qgc2VlbiA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgICAgICBjb25zdCBtZXRhczogV2ViU29ja2V0U2Vzc2lvblByZXNlbmNlW10gPSBbXTtcblxuICAgICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgYXVkaWVuY2UuYXVkaWVuY2VzKSB7XG4gICAgICAgICAgZm9yIChjb25zdCBtZXRhIG9mIHRoaXMucXVlcnlBdWRpZW5jZShpdGVtKSkge1xuICAgICAgICAgICAgaWYgKHNlZW4uaGFzKG1ldGEuc2Vzc2lvbklkKSkge1xuICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc2Vlbi5hZGQobWV0YS5zZXNzaW9uSWQpO1xuICAgICAgICAgICAgbWV0YXMucHVzaChtZXRhKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbWV0YXM7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRBY3RpdmVDb25uZWN0aW9ucyhuYW1lc3BhY2U/OiBzdHJpbmcpOiBXZWJTb2NrZXRTZXNzaW9uUHJlc2VuY2VbXSB7XG4gICAgY29uc3QgbWV0YXM6IFdlYlNvY2tldFNlc3Npb25QcmVzZW5jZVtdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IG1ldGEgb2YgdGhpcy5jb25uZWN0aW9ucy52YWx1ZXMoKSkge1xuICAgICAgaWYgKCFtZXRhLmFjdGl2ZSB8fCAobmFtZXNwYWNlICYmIG1ldGEubmFtZXNwYWNlICE9PSBuYW1lc3BhY2UpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBtZXRhcy5wdXNoKG1ldGEpO1xuICAgIH1cblxuICAgIHJldHVybiBtZXRhcztcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Qm91bmRDb25uZWN0aW9ucyhcbiAgICBiaW5kaW5nczogTWFwPHN0cmluZywgU2V0PHN0cmluZz4+LFxuICAgIGlkOiBzdHJpbmcsXG4gICAgbmFtZXNwYWNlPzogc3RyaW5nLFxuICApOiBXZWJTb2NrZXRTZXNzaW9uUHJlc2VuY2VbXSB7XG4gICAgY29uc3QgbWV0YXM6IFdlYlNvY2tldFNlc3Npb25QcmVzZW5jZVtdID0gW107XG4gICAgY29uc3Qgc2VlbiA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gICAgZm9yIChjb25zdCBtZW1iZXJzIG9mIHRoaXMuZ2V0U2NvcGVkQmluZGluZ3MoYmluZGluZ3MsIGlkLCBuYW1lc3BhY2UpKSB7XG4gICAgICBmb3IgKGNvbnN0IGNvbm5lY3Rpb25JZCBvZiBtZW1iZXJzKSB7XG4gICAgICAgIGlmIChzZWVuLmhhcyhjb25uZWN0aW9uSWQpKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgc2Vlbi5hZGQoY29ubmVjdGlvbklkKTtcblxuICAgICAgICBjb25zdCBtZXRhID0gdGhpcy5jb25uZWN0aW9ucy5nZXQoY29ubmVjdGlvbklkKTtcbiAgICAgICAgaWYgKG1ldGE/LmFjdGl2ZSkge1xuICAgICAgICAgIG1ldGFzLnB1c2gobWV0YSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbWV0YXM7XG4gIH1cblxuICBwcml2YXRlIGdldFNjb3BlZEJpbmRpbmdzKFxuICAgIGJpbmRpbmdzOiBNYXA8c3RyaW5nLCBTZXQ8c3RyaW5nPj4sXG4gICAgaWQ6IHN0cmluZyxcbiAgICBuYW1lc3BhY2U/OiBzdHJpbmcsXG4gICk6IFNldDxzdHJpbmc+W10ge1xuICAgIGlmIChuYW1lc3BhY2UpIHtcbiAgICAgIGNvbnN0IGV4YWN0ID0gYmluZGluZ3MuZ2V0KGdldEJpbmRpbmdLZXkobmFtZXNwYWNlLCBpZCkpO1xuICAgICAgcmV0dXJuIGV4YWN0ID8gW2V4YWN0XSA6IFtdO1xuICAgIH1cblxuICAgIGNvbnN0IG1hdGNoZXM6IFNldDxzdHJpbmc+W10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IFtrZXksIG1lbWJlcnNdIG9mIGJpbmRpbmdzKSB7XG4gICAgICBjb25zdCBwYXJzZWQgPSBwYXJzZUJpbmRpbmdLZXkoa2V5KTtcbiAgICAgIGlmIChwYXJzZWQuaWQgPT09IGlkKSB7XG4gICAgICAgIG1hdGNoZXMucHVzaChtZW1iZXJzKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbWF0Y2hlcztcbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlUm9vbUJpbmRpbmcobmFtZXNwYWNlOiBzdHJpbmcsIHJvb21JZDogV2ViU29ja2V0Um9vbUlkLCBzZXNzaW9uSWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IGtleSA9IGdldEJpbmRpbmdLZXkobmFtZXNwYWNlLCByb29tSWQpO1xuICAgIGNvbnN0IG1lbWJlcnMgPSB0aGlzLnJvb21zLmdldChrZXkpO1xuICAgIGlmICghbWVtYmVycykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIG1lbWJlcnMuZGVsZXRlKHNlc3Npb25JZCk7XG4gICAgaWYgKG1lbWJlcnMuc2l6ZSA9PT0gMCkge1xuICAgICAgdGhpcy5yb29tcy5kZWxldGUoa2V5KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlbW92ZVVzZXJCaW5kaW5nKG5hbWVzcGFjZTogc3RyaW5nLCB1c2VySWQ6IFdlYlNvY2tldFVzZXJJZCwgc2Vzc2lvbklkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBrZXkgPSBnZXRCaW5kaW5nS2V5KG5hbWVzcGFjZSwgU3RyaW5nKHVzZXJJZCkpO1xuICAgIGNvbnN0IG1lbWJlcnMgPSB0aGlzLnVzZXJzLmdldChrZXkpO1xuICAgIGlmICghbWVtYmVycykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIG1lbWJlcnMuZGVsZXRlKHNlc3Npb25JZCk7XG4gICAgaWYgKG1lbWJlcnMuc2l6ZSA9PT0gMCkge1xuICAgICAgdGhpcy51c2Vycy5kZWxldGUoa2V5KTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0QmluZGluZ0tleShuYW1lc3BhY2U6IHN0cmluZywgaWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgJHtuYW1lc3BhY2V9Ojoke2lkfWA7XG59XG5cbmludGVyZmFjZSBQcmVzZW5jZUJpbmRpbmcge1xuICBuYW1lc3BhY2U6IHN0cmluZztcbiAgaWQ6IHN0cmluZztcbn1cblxuZnVuY3Rpb24gcGFyc2VCaW5kaW5nS2V5KGtleTogc3RyaW5nKTogUHJlc2VuY2VCaW5kaW5nIHtcbiAgY29uc3QgW25hbWVzcGFjZSwgLi4ucmVzdF0gPSBrZXkuc3BsaXQoXCI6OlwiKTtcbiAgcmV0dXJuIHtcbiAgICBuYW1lc3BhY2UsXG4gICAgaWQ6IHJlc3Quam9pbihcIjo6XCIpLFxuICB9O1xufVxuIl0sIm1hcHBpbmdzIjoiOztBQTJUQSxTQUFTLGNBQWMsV0FBbUIsSUFBb0I7Q0FDNUQsT0FBTyxHQUFHLFVBQVUsSUFBSTtBQUMxQjtBQU9BLFNBQVMsZ0JBQWdCLEtBQThCO0NBQ3JELE1BQU0sQ0FBQyxXQUFXLEdBQUcsUUFBUSxJQUFJLE1BQU0sSUFBSTtDQUMzQyxPQUFPO0VBQ0w7RUFDQSxJQUFJLEtBQUssS0FBSyxJQUFJO0NBQ3BCO0FBQ0Y7OztDQXZTYSxpQ0FBYixNQUE4RTtFQUM1RSw4QkFBK0IsSUFBSSxJQUFzQztFQUN6RSx3QkFBeUIsSUFBSSxJQUF5QjtFQUN0RCx3QkFBeUIsSUFBSSxJQUF5QjtFQUV0RCxTQUFTLE9BS29CO0dBQzNCLE1BQU0sT0FBaUM7SUFDckMsV0FBVyxNQUFNO0lBQ2pCLFFBQVEsTUFBTTtJQUNkLFdBQVcsTUFBTTtJQUNqQixRQUFRLE1BQU0sVUFBVTtJQUN4Qix1QkFBTyxJQUFJLElBQUk7SUFDZiw2QkFBYSxJQUFJLEtBQUs7SUFDdEIsNEJBQVksSUFBSSxLQUFLO0dBQ3ZCO0dBQ0EsS0FBSyxZQUFZLElBQUksTUFBTSxXQUFXLElBQUk7R0FDMUMsT0FBTztFQUNUO0VBRUEsU0FBUyxXQUF5QjtHQUNoQyxNQUFNLE9BQU8sS0FBSyxZQUFZLElBQUksU0FBUztHQUMzQyxJQUFJLENBQUMsTUFDSDtHQUdGLEtBQUssU0FBUztFQUNoQjtFQUVBLFdBQVcsV0FBeUQ7R0FDbEUsTUFBTSxPQUFPLEtBQUssWUFBWSxJQUFJLFNBQVM7R0FDM0MsSUFBSSxDQUFDLE1BQ0g7R0FHRixJQUFJLEtBQUssV0FBVyxRQUNsQixLQUFLLGtCQUFrQixLQUFLLFdBQVcsS0FBSyxRQUFRLFNBQVM7R0FHL0QsS0FBSyxNQUFNLFVBQVUsS0FBSyxPQUN4QixLQUFLLGtCQUFrQixLQUFLLFdBQVcsUUFBUSxTQUFTO0dBRzFELEtBQUssWUFBWSxPQUFPLFNBQVM7R0FDakMsT0FBTztFQUNUO0VBRUEsTUFBTSxXQUF5QjtHQUM3QixNQUFNLE9BQU8sS0FBSyxZQUFZLElBQUksU0FBUztHQUMzQyxJQUFJLENBQUMsTUFDSDtHQUdGLEtBQUssNkJBQWEsSUFBSSxLQUFLO0VBQzdCO0VBRUEsVUFBVSxXQUFtQixRQUErQjtHQUMxRCxNQUFNLE9BQU8sS0FBSyxZQUFZLElBQUksU0FBUztHQUMzQyxJQUFJLENBQUMsTUFDSDtHQUdGLElBQUksS0FBSyxXQUFXLFFBQ2xCLEtBQUssa0JBQWtCLEtBQUssV0FBVyxLQUFLLFFBQVEsU0FBUztHQUcvRCxLQUFLLFNBQVM7R0FDZCxNQUFNLE1BQU0sY0FBYyxLQUFLLFdBQVcsT0FBTyxNQUFNLENBQUM7R0FDeEQsTUFBTSxRQUFRLEtBQUssTUFBTSxJQUFJLEdBQUcscUJBQUssSUFBSSxJQUFZO0dBQ3JELE1BQU0sSUFBSSxTQUFTO0dBQ25CLEtBQUssTUFBTSxJQUFJLEtBQUssS0FBSztFQUMzQjtFQUVBLFlBQVksV0FBeUI7R0FDbkMsTUFBTSxPQUFPLEtBQUssWUFBWSxJQUFJLFNBQVM7R0FDM0MsSUFBSSxDQUFDLFFBQVEsS0FBSyxXQUFXLFFBQzNCO0dBR0YsS0FBSyxrQkFBa0IsS0FBSyxXQUFXLEtBQUssUUFBUSxTQUFTO0dBQzdELE9BQU8sS0FBSztFQUNkO0VBRUEsS0FBSyxXQUFtQixRQUErQjtHQUNyRCxNQUFNLE9BQU8sS0FBSyxZQUFZLElBQUksU0FBUztHQUMzQyxJQUFJLENBQUMsTUFDSDtHQUdGLEtBQUssTUFBTSxJQUFJLE1BQU07R0FDckIsTUFBTSxNQUFNLGNBQWMsS0FBSyxXQUFXLE1BQU07R0FDaEQsTUFBTSxVQUFVLEtBQUssTUFBTSxJQUFJLEdBQUcscUJBQUssSUFBSSxJQUFZO0dBQ3ZELFFBQVEsSUFBSSxTQUFTO0dBQ3JCLEtBQUssTUFBTSxJQUFJLEtBQUssT0FBTztFQUM3QjtFQUVBLE1BQU0sV0FBbUIsUUFBK0I7R0FDdEQsTUFBTSxPQUFPLEtBQUssWUFBWSxJQUFJLFNBQVM7R0FDM0MsSUFBSSxDQUFDLE1BQ0g7R0FHRixLQUFLLE1BQU0sT0FBTyxNQUFNO0dBQ3hCLEtBQUssa0JBQWtCLEtBQUssV0FBVyxRQUFRLFNBQVM7RUFDMUQ7RUFFQSxjQUFjLFdBQXlEO0dBQ3JFLE9BQU8sS0FBSyxZQUFZLElBQUksU0FBUztFQUN2QztFQUVBLG1CQUFtQixXQUE0QjtHQUM3QyxJQUFJLFFBQVE7R0FFWixLQUFLLE1BQU0sUUFBUSxLQUFLLFlBQVksT0FBTyxHQUFHO0lBQzVDLElBQUksQ0FBQyxLQUFLLFVBQVcsYUFBYSxLQUFLLGNBQWMsV0FDbkQ7SUFHRixTQUFTO0dBQ1g7R0FFQSxPQUFPO0VBQ1Q7RUFFQSxlQUFlLFFBQXlCLFdBQWdEO0dBQ3RGLE9BQU8sS0FBSyxvQkFBb0IsS0FBSyxPQUFPLFFBQVEsU0FBUztFQUMvRDtFQUVBLFdBQW1DO0dBQ2pDLE1BQU0sY0FBc0MsQ0FBQztHQUU3QyxLQUFLLE1BQU0sUUFBUSxLQUFLLFlBQVksT0FBTyxHQUFHO0lBQzVDLElBQUksQ0FBQyxLQUFLLFFBQ1I7SUFFRixZQUFZLEtBQUssY0FBYyxZQUFZLEtBQUssY0FBYyxLQUFLO0dBQ3JFO0dBRUEsT0FBTztJQUNMLGtCQUFrQixPQUFPLE9BQU8sV0FBVyxDQUFDLENBQUMsUUFBUSxLQUFLLFVBQVUsTUFBTSxPQUFPLENBQUM7SUFDbEYsWUFBWSxLQUFLLE1BQU07SUFDdkI7R0FDRjtFQUNGO0VBRUEsY0FBYyxVQUF5RDtHQUNyRSxRQUFRLFNBQVMsTUFBakI7SUFDRSxLQUFLLE9BQ0gsT0FBTyxLQUFLLHFCQUFxQixTQUFTLFNBQVM7SUFDckQsS0FBSyxRQUNILE9BQU8sS0FBSyxvQkFBb0IsS0FBSyxPQUFPLFNBQVMsUUFBUSxTQUFTLFNBQVM7SUFDakYsS0FBSyxRQUNILE9BQU8sS0FBSyxvQkFBb0IsS0FBSyxPQUFPLE9BQU8sU0FBUyxNQUFNLEdBQUcsU0FBUyxTQUFTO0lBQ3pGLEtBQUssZUFBZTtLQUNsQixNQUFNLFFBQW9DLENBQUM7S0FFM0MsS0FBSyxNQUFNLGdCQUFnQixTQUFTLGVBQWU7TUFDakQsTUFBTSxPQUFPLEtBQUssWUFBWSxJQUFJLFlBQVk7TUFDOUMsSUFBSSxDQUFDLE1BQU0sUUFDVDtNQUVGLElBQUksU0FBUyxhQUFhLEtBQUssY0FBYyxTQUFTLFdBQ3BEO01BRUYsTUFBTSxLQUFLLElBQUk7S0FDakI7S0FFQSxPQUFPO0lBQ1Q7SUFDQSxLQUFLLFNBQVM7S0FDWixNQUFNLHVCQUFPLElBQUksSUFBWTtLQUM3QixNQUFNLFFBQW9DLENBQUM7S0FFM0MsS0FBSyxNQUFNLFFBQVEsU0FBUyxXQUMxQixLQUFLLE1BQU0sUUFBUSxLQUFLLGNBQWMsSUFBSSxHQUFHO01BQzNDLElBQUksS0FBSyxJQUFJLEtBQUssU0FBUyxHQUN6QjtNQUdGLEtBQUssSUFBSSxLQUFLLFNBQVM7TUFDdkIsTUFBTSxLQUFLLElBQUk7S0FDakI7S0FHRixPQUFPO0lBQ1Q7R0FDRjtFQUNGO0VBRUEscUJBQTZCLFdBQWdEO0dBQzNFLE1BQU0sUUFBb0MsQ0FBQztHQUUzQyxLQUFLLE1BQU0sUUFBUSxLQUFLLFlBQVksT0FBTyxHQUFHO0lBQzVDLElBQUksQ0FBQyxLQUFLLFVBQVcsYUFBYSxLQUFLLGNBQWMsV0FDbkQ7SUFHRixNQUFNLEtBQUssSUFBSTtHQUNqQjtHQUVBLE9BQU87RUFDVDtFQUVBLG9CQUNFLFVBQ0EsSUFDQSxXQUM0QjtHQUM1QixNQUFNLFFBQW9DLENBQUM7R0FDM0MsTUFBTSx1QkFBTyxJQUFJLElBQVk7R0FFN0IsS0FBSyxNQUFNLFdBQVcsS0FBSyxrQkFBa0IsVUFBVSxJQUFJLFNBQVMsR0FDbEUsS0FBSyxNQUFNLGdCQUFnQixTQUFTO0lBQ2xDLElBQUksS0FBSyxJQUFJLFlBQVksR0FDdkI7SUFFRixLQUFLLElBQUksWUFBWTtJQUVyQixNQUFNLE9BQU8sS0FBSyxZQUFZLElBQUksWUFBWTtJQUM5QyxJQUFJLE1BQU0sUUFDUixNQUFNLEtBQUssSUFBSTtHQUVuQjtHQUdGLE9BQU87RUFDVDtFQUVBLGtCQUNFLFVBQ0EsSUFDQSxXQUNlO0dBQ2YsSUFBSSxXQUFXO0lBQ2IsTUFBTSxRQUFRLFNBQVMsSUFBSSxjQUFjLFdBQVcsRUFBRSxDQUFDO0lBQ3ZELE9BQU8sUUFBUSxDQUFDLEtBQUssSUFBSSxDQUFDO0dBQzVCO0dBRUEsTUFBTSxVQUF5QixDQUFDO0dBQ2hDLEtBQUssTUFBTSxDQUFDLEtBQUssWUFBWSxVQUUzQixJQURlLGdCQUFnQixHQUMzQixDQUFBLENBQU8sT0FBTyxJQUNoQixRQUFRLEtBQUssT0FBTztHQUl4QixPQUFPO0VBQ1Q7RUFFQSxrQkFBMEIsV0FBbUIsUUFBeUIsV0FBeUI7R0FDN0YsTUFBTSxNQUFNLGNBQWMsV0FBVyxNQUFNO0dBQzNDLE1BQU0sVUFBVSxLQUFLLE1BQU0sSUFBSSxHQUFHO0dBQ2xDLElBQUksQ0FBQyxTQUNIO0dBR0YsUUFBUSxPQUFPLFNBQVM7R0FDeEIsSUFBSSxRQUFRLFNBQVMsR0FDbkIsS0FBSyxNQUFNLE9BQU8sR0FBRztFQUV6QjtFQUVBLGtCQUEwQixXQUFtQixRQUF5QixXQUF5QjtHQUM3RixNQUFNLE1BQU0sY0FBYyxXQUFXLE9BQU8sTUFBTSxDQUFDO0dBQ25ELE1BQU0sVUFBVSxLQUFLLE1BQU0sSUFBSSxHQUFHO0dBQ2xDLElBQUksQ0FBQyxTQUNIO0dBR0YsUUFBUSxPQUFPLFNBQVM7R0FDeEIsSUFBSSxRQUFRLFNBQVMsR0FDbkIsS0FBSyxNQUFNLE9BQU8sR0FBRztFQUV6QjtDQUNGIn0=
52
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid3MtcHJlc2VuY2Utc3RvcmUuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3N0cmVhbS93cy1wcmVzZW5jZS1zdG9yZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyB0eXBlIFdlYlNvY2tldEF1ZGllbmNlIH0gZnJvbSBcIi4vd3MtYXVkaWVuY2VcIjtcbmltcG9ydCB7IHR5cGUgTWF5YmVQcm9taXNlLCB0eXBlIFdlYlNvY2tldFJvb21JZCwgdHlwZSBXZWJTb2NrZXRVc2VySWQgfSBmcm9tIFwiLi93cy1jb3JlXCI7XG5pbXBvcnQgeyBXZWJTb2NrZXRQcmVzZW5jZUluZGV4IH0gZnJvbSBcIi4vd3MtcHJlc2VuY2UtaW5kZXhcIjtcblxuLyoqXG4gKiDshLjshZggcHJlc2VuY2Ugc25hcHNob3QuIGxpdmUg6rCd7LK06rCAIOyVhOuLiOuvgOuhnCDqsJLsnYQg67CU6r+U64+EIHJlZ2lzdHJ564KYIHN0b3JlIOyDge2DnOyXkCDsmIHtlqXsnYQg7KO87KeAIOyViuuKlOuLpC5cbiAqL1xuZXhwb3J0IHR5cGUgV2ViU29ja2V0U2Vzc2lvblByZXNlbmNlID0ge1xuICBzZXNzaW9uSWQ6IHN0cmluZztcbiAgbm9kZUlkOiBzdHJpbmc7XG4gIG5hbWVzcGFjZTogc3RyaW5nO1xuICBhY3RpdmU6IGJvb2xlYW47XG4gIHJvb21zOiBTZXQ8V2ViU29ja2V0Um9vbUlkPjtcbiAgY29ubmVjdGVkQXQ6IERhdGU7XG4gIGxhc3RTZWVuQXQ6IERhdGU7XG4gIHVzZXJJZD86IFdlYlNvY2tldFVzZXJJZDtcbn07XG5cbmV4cG9ydCB0eXBlIFdlYlNvY2tldFByZXNlbmNlUmVnaXN0cmF0aW9uID0ge1xuICBzZXNzaW9uSWQ6IHN0cmluZztcbiAgbm9kZUlkOiBzdHJpbmc7XG4gIG5hbWVzcGFjZTogc3RyaW5nO1xuICBhY3RpdmU6IGJvb2xlYW47XG4gIGNvbm5lY3RlZEF0OiBEYXRlO1xufTtcblxuZXhwb3J0IHR5cGUgV2ViU29ja2V0Um91dGluZ1BsYW4gPSB7XG4gIGxvY2FsU2Vzc2lvbklkczogc3RyaW5nW107XG4gIHJlbW90ZU5vZGVJZHM6IHN0cmluZ1tdO1xufTtcblxuLyoqXG4gKiDtgbTrn6zsiqTthLAgcHJlc2VuY2UgcmVwbGljYSDqs4Tslb0uIOqwgSDrhbjrk5zsnZggcmVnaXN0cnnqsIAg7J6Q6riwIOyEuOyFmOydmCBtdXRhdGlvbuydhCDshLjshZjrs4Qg7Zi47LacIOyInOyEnOuMgOuhnCDsoITri6ztlZzri6QuXG4gKiDrqqjrk6Ag66mU7ISc65Oc64qUIOqwkuydtOuCmCBwcm9taXNl66W8IOuwmO2ZmO2VoCDsiJgg7J6I6rOgLCByZWdpc3RyeeuKlCDrj5nquLAgdGhyb3frj4QgcmVqZWN0aW9u7Jy866GcIOuwlOq/lCDsspjrpqztlZzri6QuXG4gKiB1c2VySWTripQg7YOA7J6F6rmM7KeAIOydvOy5mO2VtOyVvCDrp6Tsua3rkJzri6QoMeqzvCBcIjFcIuydgCDri6TrpbTri6QpLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFdlYlNvY2tldFByZXNlbmNlU3RvcmUge1xuICAvLyDshKTsoJXtlZjrqbQgcnVudGltZSBub2RlSWTsmYAg6rCZ7JWE7JW8IO2VnOuLpC4g64uk66W066m0IHJ1bnRpbWUg7IOd7ISx7J20IOyLpO2MqO2VnOuLpFxuICByZWFkb25seSBub2RlSWQ/OiBzdHJpbmc7XG4gIHJlZ2lzdGVyKGlucHV0OiBXZWJTb2NrZXRQcmVzZW5jZVJlZ2lzdHJhdGlvbik6IE1heWJlUHJvbWlzZTx2b2lkPjtcbiAgYWN0aXZhdGUoc2Vzc2lvbklkOiBzdHJpbmcpOiBNYXliZVByb21pc2U8dm9pZD47XG4gIHVucmVnaXN0ZXIoc2Vzc2lvbklkOiBzdHJpbmcpOiBNYXliZVByb21pc2U8dm9pZD47XG4gIHNldFVzZXJJZChzZXNzaW9uSWQ6IHN0cmluZywgdXNlcklkOiBXZWJTb2NrZXRVc2VySWQpOiBNYXliZVByb21pc2U8dm9pZD47XG4gIGNsZWFyVXNlcklkKHNlc3Npb25JZDogc3RyaW5nKTogTWF5YmVQcm9taXNlPHZvaWQ+O1xuICBqb2luKHNlc3Npb25JZDogc3RyaW5nLCByb29tSWQ6IFdlYlNvY2tldFJvb21JZCk6IE1heWJlUHJvbWlzZTx2b2lkPjtcbiAgbGVhdmUoc2Vzc2lvbklkOiBzdHJpbmcsIHJvb21JZDogV2ViU29ja2V0Um9vbUlkKTogTWF5YmVQcm9taXNlPHZvaWQ+O1xuICAvLyBub2RlSWQg6rSA7KCQ7JeQ7IScIGF1ZGllbmNl66W8IOuhnOy7rCDshLjshZggSUTsmYAg7KSR67O1IOyXhuuKlCDsm5Dqsqkg64W465OcIElE66GcIOuCmOuIiOuLpC4g67mE7Zmc7ISxIOyEuOyFmOydgCDsoJzsmbjtlZzri6RcbiAgcmVzb2x2ZVJvdXRlKGF1ZGllbmNlOiBXZWJTb2NrZXRBdWRpZW5jZSwgbm9kZUlkOiBzdHJpbmcpOiBNYXliZVByb21pc2U8V2ViU29ja2V0Um91dGluZ1BsYW4+O1xuICAvLyDtgbTrn6zsiqTthLAg7KCE7LK07J2YIO2ZnOyEsSDrsKkg7J247JuQ7IiYXG4gIGdldFJvb21NZW1iZXJDb3VudChyb29tSWQ6IFdlYlNvY2tldFJvb21JZCwgbmFtZXNwYWNlPzogc3RyaW5nKTogTWF5YmVQcm9taXNlPG51bWJlcj47XG4gIHNodXRkb3duPygpOiBNYXliZVByb21pc2U8dm9pZD47XG59XG5cbi8qKlxuICog7ZSE66Gc7IS47IqkIOuplOuqqOumrOyXkCBwcmVzZW5jZeulvCDrkZDripQgc3RvcmUuIOuLqOydvCDrhbjrk5zsnZgg6riw67O46rCS7J2066mwLCDqsJnsnYAg7ZSE66Gc7IS47Iqk7J2YIOyXrOufrCBydW50aW1l7J20IOqzteycoO2VmOuptCDtgbTrn6zsiqTthLAgcmVwbGljYeuhnOuPhCDrj5nsnpHtlZzri6QuXG4gKi9cbmV4cG9ydCBjbGFzcyBJbk1lbW9yeVdlYlNvY2tldFByZXNlbmNlU3RvcmUgaW1wbGVtZW50cyBXZWJTb2NrZXRQcmVzZW5jZVN0b3JlIHtcbiAgcHJpdmF0ZSByZWFkb25seSBpbmRleCA9IG5ldyBXZWJTb2NrZXRQcmVzZW5jZUluZGV4KCk7XG5cbiAgcmVnaXN0ZXIoaW5wdXQ6IFdlYlNvY2tldFByZXNlbmNlUmVnaXN0cmF0aW9uKTogdm9pZCB7XG4gICAgdGhpcy5pbmRleC5yZWdpc3RlcihpbnB1dCk7XG4gIH1cblxuICBhY3RpdmF0ZShzZXNzaW9uSWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuaW5kZXguYWN0aXZhdGUoc2Vzc2lvbklkKTtcbiAgfVxuXG4gIHVucmVnaXN0ZXIoc2Vzc2lvbklkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmluZGV4LnVucmVnaXN0ZXIoc2Vzc2lvbklkKTtcbiAgfVxuXG4gIHNldFVzZXJJZChzZXNzaW9uSWQ6IHN0cmluZywgdXNlcklkOiBXZWJTb2NrZXRVc2VySWQpOiB2b2lkIHtcbiAgICB0aGlzLmluZGV4LnNldFVzZXJJZChzZXNzaW9uSWQsIHVzZXJJZCk7XG4gIH1cblxuICBjbGVhclVzZXJJZChzZXNzaW9uSWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuaW5kZXguY2xlYXJVc2VySWQoc2Vzc2lvbklkKTtcbiAgfVxuXG4gIGpvaW4oc2Vzc2lvbklkOiBzdHJpbmcsIHJvb21JZDogV2ViU29ja2V0Um9vbUlkKTogdm9pZCB7XG4gICAgdGhpcy5pbmRleC5qb2luKHNlc3Npb25JZCwgcm9vbUlkKTtcbiAgfVxuXG4gIGxlYXZlKHNlc3Npb25JZDogc3RyaW5nLCByb29tSWQ6IFdlYlNvY2tldFJvb21JZCk6IHZvaWQge1xuICAgIHRoaXMuaW5kZXgubGVhdmUoc2Vzc2lvbklkLCByb29tSWQpO1xuICB9XG5cbiAgcmVzb2x2ZVJvdXRlKGF1ZGllbmNlOiBXZWJTb2NrZXRBdWRpZW5jZSwgbm9kZUlkOiBzdHJpbmcpOiBXZWJTb2NrZXRSb3V0aW5nUGxhbiB7XG4gICAgY29uc3QgbG9jYWxTZXNzaW9uSWRzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGNvbnN0IHJlbW90ZU5vZGVJZHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICAgIGZvciAoY29uc3Qgc2Vzc2lvbiBvZiB0aGlzLmluZGV4LnF1ZXJ5QXVkaWVuY2UoYXVkaWVuY2UpKSB7XG4gICAgICBpZiAoc2Vzc2lvbi5ub2RlSWQgPT09IG5vZGVJZCkge1xuICAgICAgICBsb2NhbFNlc3Npb25JZHMucHVzaChzZXNzaW9uLnNlc3Npb25JZCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZW1vdGVOb2RlSWRzLmFkZChzZXNzaW9uLm5vZGVJZCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgbG9jYWxTZXNzaW9uSWRzLCByZW1vdGVOb2RlSWRzOiBbLi4ucmVtb3RlTm9kZUlkc10gfTtcbiAgfVxuXG4gIGdldFJvb21NZW1iZXJDb3VudChyb29tSWQ6IFdlYlNvY2tldFJvb21JZCwgbmFtZXNwYWNlPzogc3RyaW5nKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5pbmRleC5nZXRSb29tTWVtYmVyQ291bnQocm9vbUlkLCBuYW1lc3BhY2UpO1xuICB9XG5cbiAgLy8g67O17IKs67O47J2EIOuwmO2ZmO2VmOuvgOuhnCDtmLjstpzsnpDqsIAg6rCS7J2EIOuwlOq/lOuPhCBzdG9yZSDsg4Htg5zripQg6re464yA66Gc64ukXG4gIGdldENvbm5lY3Rpb24oc2Vzc2lvbklkOiBzdHJpbmcpOiBXZWJTb2NrZXRTZXNzaW9uUHJlc2VuY2UgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmluZGV4LmdldENvbm5lY3Rpb24oc2Vzc2lvbklkKTtcbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozt3QkFFNEQ7Q0FzRC9DLGlDQUFiLE1BQThFO0VBQzVFLFFBQXlCLElBQUksdUJBQXVCO0VBRXBELFNBQVMsT0FBNEM7R0FDbkQsS0FBSyxNQUFNLFNBQVMsS0FBSztFQUMzQjtFQUVBLFNBQVMsV0FBeUI7R0FDaEMsS0FBSyxNQUFNLFNBQVMsU0FBUztFQUMvQjtFQUVBLFdBQVcsV0FBeUI7R0FDbEMsS0FBSyxNQUFNLFdBQVcsU0FBUztFQUNqQztFQUVBLFVBQVUsV0FBbUIsUUFBK0I7R0FDMUQsS0FBSyxNQUFNLFVBQVUsV0FBVyxNQUFNO0VBQ3hDO0VBRUEsWUFBWSxXQUF5QjtHQUNuQyxLQUFLLE1BQU0sWUFBWSxTQUFTO0VBQ2xDO0VBRUEsS0FBSyxXQUFtQixRQUErQjtHQUNyRCxLQUFLLE1BQU0sS0FBSyxXQUFXLE1BQU07RUFDbkM7RUFFQSxNQUFNLFdBQW1CLFFBQStCO0dBQ3RELEtBQUssTUFBTSxNQUFNLFdBQVcsTUFBTTtFQUNwQztFQUVBLGFBQWEsVUFBNkIsUUFBc0M7R0FDOUUsTUFBTSxrQkFBNEIsQ0FBQztHQUNuQyxNQUFNLGdDQUFnQixJQUFJLElBQVk7R0FFdEMsS0FBSyxNQUFNLFdBQVcsS0FBSyxNQUFNLGNBQWMsUUFBUSxHQUNyRCxJQUFJLFFBQVEsV0FBVyxRQUNyQixnQkFBZ0IsS0FBSyxRQUFRLFNBQVM7UUFFdEMsY0FBYyxJQUFJLFFBQVEsTUFBTTtHQUlwQyxPQUFPO0lBQUU7SUFBaUIsZUFBZSxDQUFDLEdBQUcsYUFBYTtHQUFFO0VBQzlEO0VBRUEsbUJBQW1CLFFBQXlCLFdBQTRCO0dBQ3RFLE9BQU8sS0FBSyxNQUFNLG1CQUFtQixRQUFRLFNBQVM7RUFDeEQ7RUFHQSxjQUFjLFdBQXlEO0dBQ3JFLE9BQU8sS0FBSyxNQUFNLGNBQWMsU0FBUztFQUMzQztDQUNGIn0=
@@ -1,46 +1,74 @@
1
+ import { type z } from "zod";
1
2
  import { type WebSocketAudience as WebSocketAudienceSpec } from "./ws-audience";
2
- import { WebSocketAudienceResolver } from "./ws-audience-resolver";
3
3
  import { type WebSocketClusterBus } from "./ws-cluster-bus";
4
- import { type ManagedWebSocketConnection, type WebSocketRegistryStats, type WebSocketRoomId, type WebSocketUserId } from "./ws-core";
5
- import { WebSocketDeliveryEngine } from "./ws-delivery";
4
+ import { type ManagedWebSocketConnection, type WebSocketFrameConnection, type WebSocketRegistryStats, type WebSocketRoomId, type WebSocketUserId } from "./ws-core";
5
+ import { type WebSocketRouteDefinition } from "./ws-delivery";
6
6
  import { WebSocketLocalConnectionStore } from "./ws-local-connection-store";
7
7
  import { type WebSocketPresenceStore, type WebSocketSessionPresence } from "./ws-presence-store";
8
8
  import { type WebSocketTelemetryController } from "./ws-telemetry";
9
9
  export type { ManagedWebSocketConnection, WebSocketRegistryStats, WebSocketRoomId, WebSocketUserId, };
10
10
  export type WebSocketConnectionMeta = WebSocketSessionPresence;
11
+ export type WebSocketRoomMemberCount = {
12
+ count: number;
13
+ partial: boolean;
14
+ };
11
15
  export type WebSocketRegistryOptions = {
12
16
  nodeId: string;
13
17
  presenceStore?: WebSocketPresenceStore;
14
18
  clusterBus?: WebSocketClusterBus;
15
19
  telemetryController?: WebSocketTelemetryController;
20
+ drainTimeoutMs?: number;
16
21
  };
22
+ /**
23
+ * 노드 로컬 presence를 메모리에 소유하고, 설정된 store에는 세션별 순서대로 replica를 반영한다.
24
+ * mutation과 publish는 호출 시점에 메모리를 동기로 갱신하고, store 실패는 telemetry로만 기록하며 reject하지 않는다.
25
+ */
17
26
  export declare class WebSocketRegistry {
18
27
  readonly nodeId: string;
19
28
  readonly localConnections: WebSocketLocalConnectionStore;
20
29
  readonly presenceStore: WebSocketPresenceStore;
21
30
  readonly clusterBus: WebSocketClusterBus;
22
- readonly audienceResolver: WebSocketAudienceResolver;
23
- readonly deliveryEngine: WebSocketDeliveryEngine;
24
31
  readonly telemetryController: WebSocketTelemetryController;
32
+ private readonly memory;
33
+ private readonly deliveryEngine;
34
+ private readonly drainTimeoutMs;
35
+ private readonly mutationQueues;
25
36
  constructor(options: WebSocketRegistryOptions);
26
- register(connection: ManagedWebSocketConnection, active?: boolean): WebSocketConnectionMeta;
27
- activate(connectionId: string): void;
28
- unregister(connectionId: string): void;
37
+ registerRoute(routeKey: string, outEvents: z.ZodObject): void;
38
+ replaceRoutes(routes: WebSocketRouteDefinition[]): void;
39
+ /**
40
+ * 연결을 메모리에 즉시 등록하고 store.register가 끝나면 resolve한다.
41
+ * store가 실패해도 메모리 전용 등록으로 resolve한다.
42
+ */
43
+ register(connection: WebSocketFrameConnection, active?: boolean): Promise<WebSocketConnectionMeta>;
44
+ activate(connectionId: string): Promise<void>;
45
+ unregister(connectionId: string): Promise<void>;
29
46
  touch(connectionId: string): void;
30
- setUserId(connectionId: string, userId: WebSocketUserId): void;
31
- clearUserId(connectionId: string): void;
32
- join(connectionId: string, roomId: WebSocketRoomId): void;
33
- leave(connectionId: string, roomId: WebSocketRoomId): void;
34
- private emitMutationSkipped;
35
- broadcast<Data>(event: string, data: Data, namespace?: string): void;
36
- publishToRoom<Data>(roomId: WebSocketRoomId, event: string, data: Data, namespace?: string): void;
37
- publishToUser<Data>(userId: WebSocketUserId, event: string, data: Data, namespace?: string): void;
38
- publishToAudience<Data>(audience: WebSocketAudienceSpec, event: string, data: Data): void;
47
+ setUserId(connectionId: string, userId: WebSocketUserId): Promise<void>;
48
+ clearUserId(connectionId: string): Promise<void>;
49
+ join(connectionId: string, roomId: WebSocketRoomId): Promise<void>;
50
+ leave(connectionId: string, roomId: WebSocketRoomId): Promise<void>;
51
+ broadcast<Data>(event: string, data: Data, namespace?: string): Promise<void>;
52
+ publishToRoom<Data>(roomId: WebSocketRoomId, event: string, data: Data, namespace?: string): Promise<void>;
53
+ publishToUser<Data>(userId: WebSocketUserId, event: string, data: Data, namespace?: string): Promise<void>;
54
+ publishToAudience<Data>(audience: WebSocketAudienceSpec, event: string, data: Data): Promise<void>;
39
55
  getConnection(connectionId: string): WebSocketConnectionMeta | undefined;
40
56
  getConnectionCount(namespace?: string): number;
41
57
  getRoomMembers(roomId: WebSocketRoomId, namespace?: string): WebSocketConnectionMeta[];
42
58
  getStats(): WebSocketRegistryStats;
59
+ /**
60
+ * 클러스터 전체의 활성 방 인원수. store가 실패하면 노드 로컬 수에 partial: true를 붙여 반환하며 reject하지 않는다.
61
+ */
62
+ getRoomMemberCount(roomId: WebSocketRoomId, namespace?: string): Promise<WebSocketRoomMemberCount>;
43
63
  closeAll(code?: number, reason?: string): void;
64
+ /**
65
+ * 로컬 연결을 닫고, 진행 중인 store mutation과 publish를 drainTimeoutMs까지 기다린 뒤 store와 bus를 종료한다.
66
+ */
44
67
  shutdown(code?: number, reason?: string): Promise<void>;
68
+ /**
69
+ * 세션별 큐 뒤에 store 호출을 이어 붙인다. 실패는 telemetry로만 기록하고, 반환한 promise는 reject하지 않는다.
70
+ */
71
+ private enqueueStoreMutation;
72
+ private emitMutationSkipped;
45
73
  }
46
74
  //# sourceMappingURL=ws-registry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ws-registry.d.ts","sourceRoot":"","sources":["../../src/stream/ws-registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ws-registry.d.ts","sourceRoot":"","sources":["../../src/stream/ws-registry.ts"],"names":[],"mappings":"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"}