@essentialai/cogent-server 2.0.0 → 3.0.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.
- package/CHANGELOG.md +24 -0
- package/dist/__tests__/helpers.d.ts +4 -0
- package/dist/__tests__/helpers.d.ts.map +1 -1
- package/dist/__tests__/helpers.js +14 -0
- package/dist/__tests__/helpers.js.map +1 -1
- package/dist/app.d.ts +4 -0
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +29 -3
- package/dist/app.js.map +1 -1
- package/dist/index.js +12 -1
- package/dist/index.js.map +1 -1
- package/dist/middleware/ws-auth.d.ts +11 -0
- package/dist/middleware/ws-auth.d.ts.map +1 -1
- package/dist/middleware/ws-auth.js +46 -0
- package/dist/middleware/ws-auth.js.map +1 -1
- package/dist/routes/adapter.d.ts +17 -0
- package/dist/routes/adapter.d.ts.map +1 -0
- package/dist/routes/adapter.js +119 -0
- package/dist/routes/adapter.js.map +1 -0
- package/dist/routes/channel-mappings.d.ts +17 -0
- package/dist/routes/channel-mappings.d.ts.map +1 -0
- package/dist/routes/channel-mappings.js +120 -0
- package/dist/routes/channel-mappings.js.map +1 -0
- package/dist/routes/messages.d.ts +2 -1
- package/dist/routes/messages.d.ts.map +1 -1
- package/dist/routes/messages.js +19 -3
- package/dist/routes/messages.js.map +1 -1
- package/dist/routes/peers.d.ts.map +1 -1
- package/dist/routes/peers.js +5 -1
- package/dist/routes/peers.js.map +1 -1
- package/dist/services/adapter-registry.d.ts +45 -0
- package/dist/services/adapter-registry.d.ts.map +1 -0
- package/dist/services/adapter-registry.js +121 -0
- package/dist/services/adapter-registry.js.map +1 -0
- package/dist/services/channel-index.d.ts +29 -0
- package/dist/services/channel-index.d.ts.map +1 -0
- package/dist/services/channel-index.js +53 -0
- package/dist/services/channel-index.js.map +1 -0
- package/dist/services/connection-manager.d.ts +10 -0
- package/dist/services/connection-manager.d.ts.map +1 -1
- package/dist/services/connection-manager.js +23 -0
- package/dist/services/connection-manager.js.map +1 -1
- package/dist/types.d.ts +17 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/pages/HowToPage.d.ts.map +1 -1
- package/dist/ui/pages/HowToPage.js +3 -3
- package/dist/ui/pages/HowToPage.js.map +1 -1
- package/dist/ui/pages/LandingPage.d.ts.map +1 -1
- package/dist/ui/pages/LandingPage.js +1 -1
- package/dist/ui/pages/LandingPage.js.map +1 -1
- package/dist/ws/adapter-handler.d.ts +30 -0
- package/dist/ws/adapter-handler.d.ts.map +1 -0
- package/dist/ws/adapter-handler.js +81 -0
- package/dist/ws/adapter-handler.js.map +1 -0
- package/dist/ws/frames.d.ts +49 -1
- package/dist/ws/frames.d.ts.map +1 -1
- package/dist/ws/frames.js +24 -0
- package/dist/ws/frames.js.map +1 -1
- package/dist/ws/handler.d.ts.map +1 -1
- package/dist/ws/handler.js +30 -5
- package/dist/ws/handler.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import { zValidator } from "@hono/zod-validator";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { BridgeError, ErrorCode } from "@essentialai/cogent";
|
|
5
|
+
import { createAuthMiddleware } from "../middleware/auth.js";
|
|
6
|
+
import { validationHook } from "./validation-hook.js";
|
|
7
|
+
/**
|
|
8
|
+
* Zod schema for PUT channel mapping request body.
|
|
9
|
+
*/
|
|
10
|
+
const ChannelMappingBodySchema = z.object({
|
|
11
|
+
channelId: z.string().min(1),
|
|
12
|
+
channelName: z.string().optional(),
|
|
13
|
+
});
|
|
14
|
+
/**
|
|
15
|
+
* Create channel mapping CRUD routes sub-router.
|
|
16
|
+
*
|
|
17
|
+
* PUT /:sessionId/channel-mappings/:platform -> Create or update a channel mapping
|
|
18
|
+
* GET /:sessionId/channel-mappings -> List all channel mappings for a session
|
|
19
|
+
* GET /:sessionId/channel-mappings/:platform -> Get a specific channel mapping
|
|
20
|
+
* DELETE /:sessionId/channel-mappings/:platform -> Delete a channel mapping
|
|
21
|
+
*
|
|
22
|
+
* All routes require bearer token auth.
|
|
23
|
+
*/
|
|
24
|
+
export function createChannelMappingRoutes(sessionStore, authService, channelIndex) {
|
|
25
|
+
const routes = new Hono();
|
|
26
|
+
const auth = createAuthMiddleware(sessionStore, authService);
|
|
27
|
+
// PUT /:sessionId/channel-mappings/:platform -- create or update
|
|
28
|
+
routes.put("/:sessionId/channel-mappings/:platform", auth, zValidator("json", ChannelMappingBodySchema, validationHook), async (c) => {
|
|
29
|
+
const authSessionId = c.get("sessionId");
|
|
30
|
+
const pathSessionId = c.req.param("sessionId");
|
|
31
|
+
const platform = c.req.param("platform");
|
|
32
|
+
if (pathSessionId !== authSessionId) {
|
|
33
|
+
throw new BridgeError(ErrorCode.AUTH_INVALID_TOKEN, "Token does not belong to this session");
|
|
34
|
+
}
|
|
35
|
+
const validPlatforms = ["slack", "gchat", "teams"];
|
|
36
|
+
if (!validPlatforms.includes(platform)) {
|
|
37
|
+
throw new BridgeError(ErrorCode.INVALID_INPUT, `Invalid platform: ${platform}. Must be one of: ${validPlatforms.join(", ")}`);
|
|
38
|
+
}
|
|
39
|
+
const { channelId, channelName } = c.req.valid("json");
|
|
40
|
+
await sessionStore.updateSession(authSessionId, (state) => {
|
|
41
|
+
if (!state.channelMappings)
|
|
42
|
+
state.channelMappings = {};
|
|
43
|
+
// If there was a previous mapping for this platform with a different channelId, clean up
|
|
44
|
+
const existing = state.channelMappings[platform];
|
|
45
|
+
if (existing && existing.channelId !== channelId) {
|
|
46
|
+
channelIndex.delete(existing.channelId);
|
|
47
|
+
}
|
|
48
|
+
state.channelMappings[platform] = {
|
|
49
|
+
platform: platform,
|
|
50
|
+
channelId,
|
|
51
|
+
channelName,
|
|
52
|
+
mappedAt: new Date().toISOString(),
|
|
53
|
+
};
|
|
54
|
+
return state;
|
|
55
|
+
});
|
|
56
|
+
// Update in-memory reverse index
|
|
57
|
+
channelIndex.set(channelId, authSessionId);
|
|
58
|
+
return c.json({ success: true }, 200);
|
|
59
|
+
});
|
|
60
|
+
// GET /:sessionId/channel-mappings -- list all
|
|
61
|
+
routes.get("/:sessionId/channel-mappings", auth, async (c) => {
|
|
62
|
+
const authSessionId = c.get("sessionId");
|
|
63
|
+
const pathSessionId = c.req.param("sessionId");
|
|
64
|
+
if (pathSessionId !== authSessionId) {
|
|
65
|
+
throw new BridgeError(ErrorCode.AUTH_INVALID_TOKEN, "Token does not belong to this session");
|
|
66
|
+
}
|
|
67
|
+
const session = await sessionStore.getSession(authSessionId);
|
|
68
|
+
if (!session) {
|
|
69
|
+
throw new BridgeError(ErrorCode.SESSION_NOT_FOUND, `Session ${authSessionId} not found`);
|
|
70
|
+
}
|
|
71
|
+
return c.json({ channelMappings: session.channelMappings ?? {} });
|
|
72
|
+
});
|
|
73
|
+
// GET /:sessionId/channel-mappings/:platform -- get specific
|
|
74
|
+
routes.get("/:sessionId/channel-mappings/:platform", auth, async (c) => {
|
|
75
|
+
const authSessionId = c.get("sessionId");
|
|
76
|
+
const pathSessionId = c.req.param("sessionId");
|
|
77
|
+
const platform = c.req.param("platform");
|
|
78
|
+
if (pathSessionId !== authSessionId) {
|
|
79
|
+
throw new BridgeError(ErrorCode.AUTH_INVALID_TOKEN, "Token does not belong to this session");
|
|
80
|
+
}
|
|
81
|
+
const session = await sessionStore.getSession(authSessionId);
|
|
82
|
+
if (!session) {
|
|
83
|
+
throw new BridgeError(ErrorCode.SESSION_NOT_FOUND, `Session ${authSessionId} not found`);
|
|
84
|
+
}
|
|
85
|
+
const mapping = session.channelMappings?.[platform];
|
|
86
|
+
if (!mapping) {
|
|
87
|
+
throw new BridgeError(ErrorCode.SESSION_NOT_FOUND, `No channel mapping for platform '${platform}' in this session`);
|
|
88
|
+
}
|
|
89
|
+
return c.json({ channelMapping: mapping });
|
|
90
|
+
});
|
|
91
|
+
// DELETE /:sessionId/channel-mappings/:platform -- delete
|
|
92
|
+
routes.delete("/:sessionId/channel-mappings/:platform", auth, async (c) => {
|
|
93
|
+
const authSessionId = c.get("sessionId");
|
|
94
|
+
const pathSessionId = c.req.param("sessionId");
|
|
95
|
+
const platform = c.req.param("platform");
|
|
96
|
+
if (pathSessionId !== authSessionId) {
|
|
97
|
+
throw new BridgeError(ErrorCode.AUTH_INVALID_TOKEN, "Token does not belong to this session");
|
|
98
|
+
}
|
|
99
|
+
let deletedChannelId;
|
|
100
|
+
await sessionStore.updateSession(authSessionId, (state) => {
|
|
101
|
+
if (!state.channelMappings?.[platform]) {
|
|
102
|
+
throw new BridgeError(ErrorCode.SESSION_NOT_FOUND, `No channel mapping for platform '${platform}' to delete`);
|
|
103
|
+
}
|
|
104
|
+
deletedChannelId = state.channelMappings[platform].channelId;
|
|
105
|
+
delete state.channelMappings[platform];
|
|
106
|
+
// Clean up empty object
|
|
107
|
+
if (Object.keys(state.channelMappings).length === 0) {
|
|
108
|
+
delete state.channelMappings;
|
|
109
|
+
}
|
|
110
|
+
return state;
|
|
111
|
+
});
|
|
112
|
+
// Remove from in-memory reverse index
|
|
113
|
+
if (deletedChannelId) {
|
|
114
|
+
channelIndex.delete(deletedChannelId);
|
|
115
|
+
}
|
|
116
|
+
return c.json({ success: true }, 200);
|
|
117
|
+
});
|
|
118
|
+
return routes;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=channel-mappings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channel-mappings.js","sourceRoot":"","sources":["../../src/routes/channel-mappings.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,7 @@ import type { SessionStore } from "../services/session-store.js";
|
|
|
3
3
|
import type { AuthService } from "../services/auth-service.js";
|
|
4
4
|
import type { ConnectionManager } from "../services/connection-manager.js";
|
|
5
5
|
import type { MessageQueueService } from "../services/message-queue.js";
|
|
6
|
+
import type { AdapterRegistry } from "../services/adapter-registry.js";
|
|
6
7
|
import type { ServerEnv } from "../types.js";
|
|
7
8
|
/**
|
|
8
9
|
* Create message routes sub-router.
|
|
@@ -15,5 +16,5 @@ import type { ServerEnv } from "../types.js";
|
|
|
15
16
|
*
|
|
16
17
|
* @param maxMessages - Maximum messages to retain per session (oldest trimmed on write)
|
|
17
18
|
*/
|
|
18
|
-
export declare function createMessageRoutes(sessionStore: SessionStore, authService: AuthService, maxMessages: number, connectionManager?: ConnectionManager, messageQueue?: MessageQueueService): Hono<ServerEnv>;
|
|
19
|
+
export declare function createMessageRoutes(sessionStore: SessionStore, authService: AuthService, maxMessages: number, connectionManager?: ConnectionManager, messageQueue?: MessageQueueService, adapterRegistry?: AdapterRegistry): Hono<ServerEnv>;
|
|
19
20
|
//# sourceMappingURL=messages.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/routes/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAU5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAK7C;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,WAAW,EACxB,WAAW,EAAE,MAAM,EACnB,iBAAiB,CAAC,EAAE,iBAAiB,EACrC,YAAY,CAAC,EAAE,mBAAmB,
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/routes/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAU5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAK7C;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,WAAW,EACxB,WAAW,EAAE,MAAM,EACnB,iBAAiB,CAAC,EAAE,iBAAiB,EACrC,YAAY,CAAC,EAAE,mBAAmB,EAClC,eAAe,CAAC,EAAE,eAAe,GAChC,IAAI,CAAC,SAAS,CAAC,CAgNjB"}
|
package/dist/routes/messages.js
CHANGED
|
@@ -15,7 +15,7 @@ import { createMessageFrame } from "../ws/frames.js";
|
|
|
15
15
|
*
|
|
16
16
|
* @param maxMessages - Maximum messages to retain per session (oldest trimmed on write)
|
|
17
17
|
*/
|
|
18
|
-
export function createMessageRoutes(sessionStore, authService, maxMessages, connectionManager, messageQueue) {
|
|
18
|
+
export function createMessageRoutes(sessionStore, authService, maxMessages, connectionManager, messageQueue, adapterRegistry) {
|
|
19
19
|
const messages = new Hono();
|
|
20
20
|
// Auth middleware applied per-route (not wildcard) to avoid intercepting
|
|
21
21
|
// unauthenticated session routes mounted at the same /api/sessions prefix.
|
|
@@ -36,7 +36,7 @@ export function createMessageRoutes(sessionStore, authService, maxMessages, conn
|
|
|
36
36
|
if (pathSessionId !== authSessionId) {
|
|
37
37
|
throw new BridgeError(ErrorCode.AUTH_INVALID_TOKEN, "Token does not belong to this session");
|
|
38
38
|
}
|
|
39
|
-
const { fromPeerId, toPeerId, message } = c.req.valid("json");
|
|
39
|
+
const { fromPeerId, toPeerId, message, originPlatform } = c.req.valid("json");
|
|
40
40
|
// Variables to capture for the response (set inside updateSession callback)
|
|
41
41
|
let messageId;
|
|
42
42
|
let timestamp;
|
|
@@ -66,6 +66,7 @@ export function createMessageRoutes(sessionStore, authService, maxMessages, conn
|
|
|
66
66
|
durationMs: null,
|
|
67
67
|
success: true,
|
|
68
68
|
error: null,
|
|
69
|
+
originPlatform: originPlatform ?? "cc",
|
|
69
70
|
};
|
|
70
71
|
state.messages.push(record);
|
|
71
72
|
// Enforce message cap (session store also does this, belt-and-suspenders)
|
|
@@ -79,9 +80,14 @@ export function createMessageRoutes(sessionStore, authService, maxMessages, conn
|
|
|
79
80
|
try {
|
|
80
81
|
const frame = createMessageFrame(record);
|
|
81
82
|
const data = JSON.stringify(frame);
|
|
83
|
+
const senderPlatform = originPlatform ?? "cc";
|
|
82
84
|
if (toPeerId === "*") {
|
|
83
|
-
// Broadcast
|
|
85
|
+
// Broadcast to all CC peers (CC peers always receive all messages)
|
|
84
86
|
connectionManager.broadcastToSession(authSessionId, data, fromPeerId);
|
|
87
|
+
// Broadcast to adapters on OTHER platforms (echo suppression)
|
|
88
|
+
if (adapterRegistry) {
|
|
89
|
+
adapterRegistry.broadcastToAdapters(authSessionId, data, senderPlatform);
|
|
90
|
+
}
|
|
85
91
|
}
|
|
86
92
|
else {
|
|
87
93
|
// Direct message: push to recipient if connected, else queue for offline
|
|
@@ -91,6 +97,16 @@ export function createMessageRoutes(sessionStore, authService, maxMessages, conn
|
|
|
91
97
|
else if (messageQueue) {
|
|
92
98
|
await messageQueue.enqueue(authSessionId, toPeerId, record);
|
|
93
99
|
}
|
|
100
|
+
// Also deliver to relevant adapter if recipient is on external platform
|
|
101
|
+
// (adapter routes handle their own delivery; this is for CC-originated
|
|
102
|
+
// messages targeting Slack users who are registered as peers)
|
|
103
|
+
if (adapterRegistry) {
|
|
104
|
+
const session = await sessionStore.getSession(authSessionId);
|
|
105
|
+
const recipientPlatform = session?.peers[toPeerId]?.platform;
|
|
106
|
+
if (recipientPlatform && recipientPlatform !== "cc" && recipientPlatform !== senderPlatform) {
|
|
107
|
+
adapterRegistry.sendToAdapter(authSessionId, recipientPlatform, data);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
94
110
|
}
|
|
95
111
|
}
|
|
96
112
|
catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/routes/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EACL,WAAW,EACX,SAAS,EACT,wBAAwB,EACxB,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/routes/messages.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"peers.d.ts","sourceRoot":"","sources":["../../src/routes/peers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAS5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAsB7C;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,WAAW,EACxB,iBAAiB,CAAC,EAAE,iBAAiB,GACpC,IAAI,CAAC,SAAS,CAAC,
|
|
1
|
+
{"version":3,"file":"peers.d.ts","sourceRoot":"","sources":["../../src/routes/peers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAS5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAsB7C;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,WAAW,EACxB,iBAAiB,CAAC,EAAE,iBAAiB,GACpC,IAAI,CAAC,SAAS,CAAC,CAiMjB"}
|
package/dist/routes/peers.js
CHANGED
|
@@ -41,7 +41,7 @@ export function createPeerRoutes(sessionStore, authService, connectionManager) {
|
|
|
41
41
|
const pathSessionId = c.req.param("sessionId");
|
|
42
42
|
const authSessionId = c.get("sessionId");
|
|
43
43
|
verifySessionMatch(pathSessionId, authSessionId);
|
|
44
|
-
const { peerId, cwd, label } = c.req.valid("json");
|
|
44
|
+
const { peerId, cwd, label, platform, type: peerType, transport, platformIdentity } = c.req.valid("json");
|
|
45
45
|
const now = new Date().toISOString();
|
|
46
46
|
const peerInfo = {
|
|
47
47
|
peerId,
|
|
@@ -50,6 +50,10 @@ export function createPeerRoutes(sessionStore, authService, connectionManager) {
|
|
|
50
50
|
label,
|
|
51
51
|
registeredAt: now,
|
|
52
52
|
lastSeenAt: now,
|
|
53
|
+
platform,
|
|
54
|
+
type: peerType,
|
|
55
|
+
transport,
|
|
56
|
+
platformIdentity,
|
|
53
57
|
};
|
|
54
58
|
await sessionStore.updateSession(authSessionId, (state) => {
|
|
55
59
|
// Add peer to session
|
package/dist/routes/peers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"peers.js","sourceRoot":"","sources":["../../src/routes/peers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EACL,WAAW,EACX,SAAS,EACT,yBAAyB,EACzB,2BAA2B,GAC5B,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EACL,wBAAwB,EACxB,2BAA2B,GAC5B,MAAM,iBAAiB,CAAC;AAEzB;;;GAGG;AACH,SAAS,kBAAkB,CAAC,aAAqB,EAAE,aAAqB;IACtE,IAAI,aAAa,KAAK,aAAa,EAAE,CAAC;QACpC,MAAM,IAAI,WAAW,CACnB,SAAS,CAAC,kBAAkB,EAC5B,uCAAuC,EACvC,qCAAqC,CACtC,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAC9B,YAA0B,EAC1B,WAAwB,EACxB,iBAAqC;IAErC,MAAM,KAAK,GAAG,IAAI,IAAI,EAAa,CAAC;IAEpC,yEAAyE;IACzE,2EAA2E;IAC3E,MAAM,IAAI,GAAG,oBAAoB,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;IAE7D;;;;;;;;OAQG;IACH,KAAK,CAAC,IAAI,CACR,mBAAmB,EACnB,IAAI,EACJ,UAAU,CAAC,MAAM,EAAE,yBAAyB,EAAE,cAAc,CAAC,EAC7D,KAAK,EAAE,CAAC,EAAE,EAAE;QACV,MAAM,aAAa,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC/C,MAAM,aAAa,GAAG,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACzC,kBAAkB,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;QAEjD,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"peers.js","sourceRoot":"","sources":["../../src/routes/peers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { WSContext } from "hono/ws";
|
|
2
|
+
import type WebSocket from "ws";
|
|
3
|
+
/**
|
|
4
|
+
* Represents a single WebSocket connection from an external platform adapter.
|
|
5
|
+
* Adapters are infrastructure -- they do NOT appear in peer lists.
|
|
6
|
+
*/
|
|
7
|
+
export interface AdapterConnection {
|
|
8
|
+
ws: WSContext;
|
|
9
|
+
rawWs: WebSocket;
|
|
10
|
+
sessionId: string;
|
|
11
|
+
platform: string;
|
|
12
|
+
connectedAt: number;
|
|
13
|
+
heartbeatInterval: ReturnType<typeof setInterval>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* In-memory tracker for adapter WebSocket connections.
|
|
17
|
+
* Separate from ConnectionManager to prevent adapters from appearing in peer counts,
|
|
18
|
+
* broadcast targets, or grace timer behavior.
|
|
19
|
+
*
|
|
20
|
+
* Structure: sessionId -> platform -> AdapterConnection[]
|
|
21
|
+
* (supports multiple connections per platform per session for redundancy)
|
|
22
|
+
*/
|
|
23
|
+
export declare class AdapterRegistry {
|
|
24
|
+
private readonly connections;
|
|
25
|
+
/** Add a new adapter WebSocket connection. */
|
|
26
|
+
addConnection(conn: AdapterConnection): void;
|
|
27
|
+
/** Remove a specific adapter connection by WS reference. Clears heartbeat interval. */
|
|
28
|
+
removeConnection(sessionId: string, platform: string, ws: WSContext): void;
|
|
29
|
+
/** Send data to all adapter connections for a specific platform in a session. */
|
|
30
|
+
sendToAdapter(sessionId: string, platform: string, data: string): void;
|
|
31
|
+
/**
|
|
32
|
+
* Broadcast data to all adapter connections in a session.
|
|
33
|
+
* Optionally excludes adapters on a specific platform (for echo suppression).
|
|
34
|
+
*/
|
|
35
|
+
broadcastToAdapters(sessionId: string, data: string, excludePlatform?: string): void;
|
|
36
|
+
/** Check whether any adapter of a specific platform is connected in a session. */
|
|
37
|
+
isAdapterConnected(sessionId: string, platform: string): boolean;
|
|
38
|
+
/** Get all connected platform names for a session. */
|
|
39
|
+
getConnectedPlatforms(sessionId: string): string[];
|
|
40
|
+
/** Get all adapter connections for a session (flat array). */
|
|
41
|
+
getAllSessionConnections(sessionId: string): AdapterConnection[];
|
|
42
|
+
/** Close all adapter connections across all sessions. Used during shutdown. */
|
|
43
|
+
closeAll(code: number, reason: string): void;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=adapter-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-registry.d.ts","sourceRoot":"","sources":["../../src/services/adapter-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,KAAK,SAAS,MAAM,IAAI,CAAC;AAEhC;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,SAAS,CAAC;IACd,KAAK,EAAE,SAAS,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;CACnD;AAED;;;;;;;GAOG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuD;IAEnF,8CAA8C;IAC9C,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI;IAc5C,uFAAuF;IACvF,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,GAAG,IAAI;IAoB1E,iFAAiF;IACjF,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAYtE;;;OAGG;IACH,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI;IAapF,kFAAkF;IAClF,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IAOhE,sDAAsD;IACtD,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE;IAMlD,8DAA8D;IAC9D,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,EAAE;IAUhE,+EAA+E;IAC/E,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;CAe7C"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory tracker for adapter WebSocket connections.
|
|
3
|
+
* Separate from ConnectionManager to prevent adapters from appearing in peer counts,
|
|
4
|
+
* broadcast targets, or grace timer behavior.
|
|
5
|
+
*
|
|
6
|
+
* Structure: sessionId -> platform -> AdapterConnection[]
|
|
7
|
+
* (supports multiple connections per platform per session for redundancy)
|
|
8
|
+
*/
|
|
9
|
+
export class AdapterRegistry {
|
|
10
|
+
connections = new Map();
|
|
11
|
+
/** Add a new adapter WebSocket connection. */
|
|
12
|
+
addConnection(conn) {
|
|
13
|
+
let sessionMap = this.connections.get(conn.sessionId);
|
|
14
|
+
if (!sessionMap) {
|
|
15
|
+
sessionMap = new Map();
|
|
16
|
+
this.connections.set(conn.sessionId, sessionMap);
|
|
17
|
+
}
|
|
18
|
+
let platformConns = sessionMap.get(conn.platform);
|
|
19
|
+
if (!platformConns) {
|
|
20
|
+
platformConns = [];
|
|
21
|
+
sessionMap.set(conn.platform, platformConns);
|
|
22
|
+
}
|
|
23
|
+
platformConns.push(conn);
|
|
24
|
+
}
|
|
25
|
+
/** Remove a specific adapter connection by WS reference. Clears heartbeat interval. */
|
|
26
|
+
removeConnection(sessionId, platform, ws) {
|
|
27
|
+
const sessionMap = this.connections.get(sessionId);
|
|
28
|
+
if (!sessionMap)
|
|
29
|
+
return;
|
|
30
|
+
const platformConns = sessionMap.get(platform);
|
|
31
|
+
if (!platformConns)
|
|
32
|
+
return;
|
|
33
|
+
const idx = platformConns.findIndex((c) => c.ws === ws);
|
|
34
|
+
if (idx === -1)
|
|
35
|
+
return;
|
|
36
|
+
clearInterval(platformConns[idx].heartbeatInterval);
|
|
37
|
+
platformConns.splice(idx, 1);
|
|
38
|
+
if (platformConns.length === 0) {
|
|
39
|
+
sessionMap.delete(platform);
|
|
40
|
+
if (sessionMap.size === 0) {
|
|
41
|
+
this.connections.delete(sessionId);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/** Send data to all adapter connections for a specific platform in a session. */
|
|
46
|
+
sendToAdapter(sessionId, platform, data) {
|
|
47
|
+
const sessionMap = this.connections.get(sessionId);
|
|
48
|
+
if (!sessionMap)
|
|
49
|
+
return;
|
|
50
|
+
const platformConns = sessionMap.get(platform);
|
|
51
|
+
if (!platformConns)
|
|
52
|
+
return;
|
|
53
|
+
for (const conn of platformConns) {
|
|
54
|
+
if (conn.ws.readyState === 1) {
|
|
55
|
+
conn.ws.send(data);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Broadcast data to all adapter connections in a session.
|
|
61
|
+
* Optionally excludes adapters on a specific platform (for echo suppression).
|
|
62
|
+
*/
|
|
63
|
+
broadcastToAdapters(sessionId, data, excludePlatform) {
|
|
64
|
+
const sessionMap = this.connections.get(sessionId);
|
|
65
|
+
if (!sessionMap)
|
|
66
|
+
return;
|
|
67
|
+
for (const [platform, conns] of sessionMap) {
|
|
68
|
+
if (platform === excludePlatform)
|
|
69
|
+
continue;
|
|
70
|
+
for (const conn of conns) {
|
|
71
|
+
if (conn.ws.readyState === 1) {
|
|
72
|
+
conn.ws.send(data);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/** Check whether any adapter of a specific platform is connected in a session. */
|
|
78
|
+
isAdapterConnected(sessionId, platform) {
|
|
79
|
+
const sessionMap = this.connections.get(sessionId);
|
|
80
|
+
if (!sessionMap)
|
|
81
|
+
return false;
|
|
82
|
+
const platformConns = sessionMap.get(platform);
|
|
83
|
+
return platformConns !== undefined && platformConns.length > 0;
|
|
84
|
+
}
|
|
85
|
+
/** Get all connected platform names for a session. */
|
|
86
|
+
getConnectedPlatforms(sessionId) {
|
|
87
|
+
const sessionMap = this.connections.get(sessionId);
|
|
88
|
+
if (!sessionMap)
|
|
89
|
+
return [];
|
|
90
|
+
return Array.from(sessionMap.keys());
|
|
91
|
+
}
|
|
92
|
+
/** Get all adapter connections for a session (flat array). */
|
|
93
|
+
getAllSessionConnections(sessionId) {
|
|
94
|
+
const sessionMap = this.connections.get(sessionId);
|
|
95
|
+
if (!sessionMap)
|
|
96
|
+
return [];
|
|
97
|
+
const result = [];
|
|
98
|
+
for (const conns of sessionMap.values()) {
|
|
99
|
+
result.push(...conns);
|
|
100
|
+
}
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
/** Close all adapter connections across all sessions. Used during shutdown. */
|
|
104
|
+
closeAll(code, reason) {
|
|
105
|
+
for (const sessionMap of this.connections.values()) {
|
|
106
|
+
for (const conns of sessionMap.values()) {
|
|
107
|
+
for (const conn of conns) {
|
|
108
|
+
clearInterval(conn.heartbeatInterval);
|
|
109
|
+
try {
|
|
110
|
+
conn.ws.close(code, reason);
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
// Ignore errors from already-closed sockets during shutdown
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
this.connections.clear();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=adapter-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-registry.js","sourceRoot":"","sources":["../../src/services/adapter-registry.ts"],"names":[],"mappings":"AAgBA;;;;;;;GAOG;AACH,MAAM,OAAO,eAAe;IACT,WAAW,GAAG,IAAI,GAAG,EAA4C,CAAC;IAEnF,8CAA8C;IAC9C,aAAa,CAAC,IAAuB;QACnC,IAAI,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACtD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,UAAU,GAAG,IAAI,GAAG,EAA+B,CAAC;YACpD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QACnD,CAAC;QACD,IAAI,aAAa,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAClD,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,aAAa,GAAG,EAAE,CAAC;YACnB,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;QAC/C,CAAC;QACD,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IAED,uFAAuF;IACvF,gBAAgB,CAAC,SAAiB,EAAE,QAAgB,EAAE,EAAa;QACjE,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACnD,IAAI,CAAC,UAAU;YAAE,OAAO;QACxB,MAAM,aAAa,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC/C,IAAI,CAAC,aAAa;YAAE,OAAO;QAE3B,MAAM,GAAG,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QACxD,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,OAAO;QAEvB,aAAa,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAC,CAAC;QACpD,aAAa,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAE7B,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC5B,IAAI,UAAU,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBAC1B,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACrC,CAAC;QACH,CAAC;IACH,CAAC;IAED,iFAAiF;IACjF,aAAa,CAAC,SAAiB,EAAE,QAAgB,EAAE,IAAY;QAC7D,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACnD,IAAI,CAAC,UAAU;YAAE,OAAO;QACxB,MAAM,aAAa,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC/C,IAAI,CAAC,aAAa;YAAE,OAAO;QAC3B,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;YACjC,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;gBAC7B,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,mBAAmB,CAAC,SAAiB,EAAE,IAAY,EAAE,eAAwB;QAC3E,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACnD,IAAI,CAAC,UAAU;YAAE,OAAO;QACxB,KAAK,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,UAAU,EAAE,CAAC;YAC3C,IAAI,QAAQ,KAAK,eAAe;gBAAE,SAAS;YAC3C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;oBAC7B,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACrB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,kFAAkF;IAClF,kBAAkB,CAAC,SAAiB,EAAE,QAAgB;QACpD,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACnD,IAAI,CAAC,UAAU;YAAE,OAAO,KAAK,CAAC;QAC9B,MAAM,aAAa,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC/C,OAAO,aAAa,KAAK,SAAS,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC;IACjE,CAAC;IAED,sDAAsD;IACtD,qBAAqB,CAAC,SAAiB;QACrC,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACnD,IAAI,CAAC,UAAU;YAAE,OAAO,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,8DAA8D;IAC9D,wBAAwB,CAAC,SAAiB;QACxC,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACnD,IAAI,CAAC,UAAU;YAAE,OAAO,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAwB,EAAE,CAAC;QACvC,KAAK,MAAM,KAAK,IAAI,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;YACxC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;QACxB,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,+EAA+E;IAC/E,QAAQ,CAAC,IAAY,EAAE,MAAc;QACnC,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;YACnD,KAAK,MAAM,KAAK,IAAI,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;gBACxC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,aAAa,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;oBACtC,IAAI,CAAC;wBACH,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;oBAC9B,CAAC;oBAAC,MAAM,CAAC;wBACP,4DAA4D;oBAC9D,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QACD,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;CACF"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { SessionStore } from "./session-store.js";
|
|
2
|
+
/**
|
|
3
|
+
* In-memory reverse index: channelId -> sessionId.
|
|
4
|
+
*
|
|
5
|
+
* Rebuilt from SessionStore at startup (same pattern as tokenIndex/labelIndex
|
|
6
|
+
* in SessionStore). Updated incrementally on channel mapping CRUD operations.
|
|
7
|
+
*
|
|
8
|
+
* Enables O(1) lookup when an adapter needs to find which session a Slack
|
|
9
|
+
* channel belongs to.
|
|
10
|
+
*/
|
|
11
|
+
export declare class ChannelIndex {
|
|
12
|
+
private readonly index;
|
|
13
|
+
/** Set a channelId -> sessionId mapping. Overwrites any existing mapping for this channelId. */
|
|
14
|
+
set(channelId: string, sessionId: string): void;
|
|
15
|
+
/** Look up the sessionId for a channelId. Returns undefined if not mapped. */
|
|
16
|
+
get(channelId: string): string | undefined;
|
|
17
|
+
/** Remove a channelId mapping. */
|
|
18
|
+
delete(channelId: string): void;
|
|
19
|
+
/** Remove all mappings for a specific sessionId (e.g., on session deletion). */
|
|
20
|
+
deleteBySession(sessionId: string): void;
|
|
21
|
+
/** Get the total number of channel mappings. */
|
|
22
|
+
get size(): number;
|
|
23
|
+
/**
|
|
24
|
+
* Rebuild the entire index from SessionStore.
|
|
25
|
+
* Called once at server startup. Iterates all sessions and extracts channelMappings.
|
|
26
|
+
*/
|
|
27
|
+
rebuild(sessionStore: SessionStore): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=channel-index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channel-index.d.ts","sourceRoot":"","sources":["../../src/services/channel-index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;;;;;;;GAQG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6B;IAEnD,gGAAgG;IAChG,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAI/C,8EAA8E;IAC9E,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI1C,kCAAkC;IAClC,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAI/B,gFAAgF;IAChF,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAQxC,gDAAgD;IAChD,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;;OAGG;IACG,OAAO,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;CAWzD"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory reverse index: channelId -> sessionId.
|
|
3
|
+
*
|
|
4
|
+
* Rebuilt from SessionStore at startup (same pattern as tokenIndex/labelIndex
|
|
5
|
+
* in SessionStore). Updated incrementally on channel mapping CRUD operations.
|
|
6
|
+
*
|
|
7
|
+
* Enables O(1) lookup when an adapter needs to find which session a Slack
|
|
8
|
+
* channel belongs to.
|
|
9
|
+
*/
|
|
10
|
+
export class ChannelIndex {
|
|
11
|
+
index = new Map();
|
|
12
|
+
/** Set a channelId -> sessionId mapping. Overwrites any existing mapping for this channelId. */
|
|
13
|
+
set(channelId, sessionId) {
|
|
14
|
+
this.index.set(channelId, sessionId);
|
|
15
|
+
}
|
|
16
|
+
/** Look up the sessionId for a channelId. Returns undefined if not mapped. */
|
|
17
|
+
get(channelId) {
|
|
18
|
+
return this.index.get(channelId);
|
|
19
|
+
}
|
|
20
|
+
/** Remove a channelId mapping. */
|
|
21
|
+
delete(channelId) {
|
|
22
|
+
this.index.delete(channelId);
|
|
23
|
+
}
|
|
24
|
+
/** Remove all mappings for a specific sessionId (e.g., on session deletion). */
|
|
25
|
+
deleteBySession(sessionId) {
|
|
26
|
+
for (const [channelId, sid] of this.index) {
|
|
27
|
+
if (sid === sessionId) {
|
|
28
|
+
this.index.delete(channelId);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/** Get the total number of channel mappings. */
|
|
33
|
+
get size() {
|
|
34
|
+
return this.index.size;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Rebuild the entire index from SessionStore.
|
|
38
|
+
* Called once at server startup. Iterates all sessions and extracts channelMappings.
|
|
39
|
+
*/
|
|
40
|
+
async rebuild(sessionStore) {
|
|
41
|
+
this.index.clear();
|
|
42
|
+
const sessionIds = await sessionStore.listSessions();
|
|
43
|
+
for (const sessionId of sessionIds) {
|
|
44
|
+
const session = await sessionStore.getSession(sessionId);
|
|
45
|
+
if (!session?.channelMappings)
|
|
46
|
+
continue;
|
|
47
|
+
for (const mapping of Object.values(session.channelMappings)) {
|
|
48
|
+
this.index.set(mapping.channelId, sessionId);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=channel-index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channel-index.js","sourceRoot":"","sources":["../../src/services/channel-index.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,OAAO,YAAY;IACN,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IAEnD,gGAAgG;IAChG,GAAG,CAAC,SAAiB,EAAE,SAAiB;QACtC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IACvC,CAAC;IAED,8EAA8E;IAC9E,GAAG,CAAC,SAAiB;QACnB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACnC,CAAC;IAED,kCAAkC;IAClC,MAAM,CAAC,SAAiB;QACtB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC/B,CAAC;IAED,gFAAgF;IAChF,eAAe,CAAC,SAAiB;QAC/B,KAAK,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC1C,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;gBACtB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;IACH,CAAC;IAED,gDAAgD;IAChD,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,OAAO,CAAC,YAA0B;QACtC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC,YAAY,EAAE,CAAC;QACrD,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;YACzD,IAAI,CAAC,OAAO,EAAE,eAAe;gBAAE,SAAS;YACxC,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;gBAC7D,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
|
|
@@ -83,6 +83,16 @@ export declare class ConnectionManager {
|
|
|
83
83
|
* Optionally excludes a specific peer (e.g., the message sender).
|
|
84
84
|
*/
|
|
85
85
|
broadcastToSession(sessionId: string, data: string, excludePeerId?: string): void;
|
|
86
|
+
/**
|
|
87
|
+
* Broadcast data to connections in a session, filtered by a predicate.
|
|
88
|
+
* Only sends to peers where filterFn(peerId) returns true.
|
|
89
|
+
*
|
|
90
|
+
* Used for platform-aware routing where echo suppression requires
|
|
91
|
+
* skipping certain peers based on metadata (not just exclusion by ID).
|
|
92
|
+
*
|
|
93
|
+
* Does NOT replace broadcastToSession -- that method remains for existing callers.
|
|
94
|
+
*/
|
|
95
|
+
broadcastToSessionWithFilter(sessionId: string, data: string, filterFn: (peerId: string) => boolean): void;
|
|
86
96
|
/**
|
|
87
97
|
* Check whether a peer has at least one active connection.
|
|
88
98
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection-manager.d.ts","sourceRoot":"","sources":["../../src/services/connection-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,KAAK,SAAS,MAAM,IAAI,CAAC;AAEhC;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,qEAAqE;IACrE,EAAE,EAAE,SAAS,CAAC;IACd,qEAAqE;IACrE,KAAK,EAAE,SAAS,CAAC;IACjB,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,WAAW,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,iBAAiB,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;CACnD;AAED;;;;;;;GAOG;AACH,qBAAa,iBAAiB;IAC5B;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,WAAW,CAGxB;IAEJ;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,WAAW,CAGxB;IAEJ,iFAAiF;IACjF,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAExC,uEAAuE;IACvE,OAAO,CAAC,aAAa,CAAC,CAA8C;gBAExD,cAAc,GAAE,MAAe;IAI3C;;;OAGG;IACH,gBAAgB,CACd,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,GACpD,IAAI;IAIP;;;OAGG;IACH,aAAa,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IA4BzC;;;;OAIG;IACH,gBAAgB,CACd,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,SAAS,GACZ,IAAI;IA4BP;;;OAGG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,cAAc,EAAE;IAMnE;;OAEG;IACH,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,EAAE;IAW7D;;OAEG;IACH,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE;IAMhD;;;;OAIG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IASjE;;;OAGG;IACH,kBAAkB,CAChB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,aAAa,CAAC,EAAE,MAAM,GACrB,IAAI;IAcP;;OAEG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAOvD;;;OAGG;IACH,sBAAsB,IAAI,MAAM;IAQhC;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAwB5C;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;CAUzB"}
|
|
1
|
+
{"version":3,"file":"connection-manager.d.ts","sourceRoot":"","sources":["../../src/services/connection-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,KAAK,SAAS,MAAM,IAAI,CAAC;AAEhC;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,qEAAqE;IACrE,EAAE,EAAE,SAAS,CAAC;IACd,qEAAqE;IACrE,KAAK,EAAE,SAAS,CAAC;IACjB,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,WAAW,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,iBAAiB,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;CACnD;AAED;;;;;;;GAOG;AACH,qBAAa,iBAAiB;IAC5B;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,WAAW,CAGxB;IAEJ;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,WAAW,CAGxB;IAEJ,iFAAiF;IACjF,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAExC,uEAAuE;IACvE,OAAO,CAAC,aAAa,CAAC,CAA8C;gBAExD,cAAc,GAAE,MAAe;IAI3C;;;OAGG;IACH,gBAAgB,CACd,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,GACpD,IAAI;IAIP;;;OAGG;IACH,aAAa,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IA4BzC;;;;OAIG;IACH,gBAAgB,CACd,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,SAAS,GACZ,IAAI;IA4BP;;;OAGG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,cAAc,EAAE;IAMnE;;OAEG;IACH,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,EAAE;IAW7D;;OAEG;IACH,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE;IAMhD;;;;OAIG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IASjE;;;OAGG;IACH,kBAAkB,CAChB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,aAAa,CAAC,EAAE,MAAM,GACrB,IAAI;IAcP;;;;;;;;OAQG;IACH,4BAA4B,CAC1B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,GACpC,IAAI;IAcP;;OAEG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAOvD;;;OAGG;IACH,sBAAsB,IAAI,MAAM;IAQhC;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAwB5C;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;CAUzB"}
|
|
@@ -151,6 +151,29 @@ export class ConnectionManager {
|
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
153
|
}
|
|
154
|
+
/**
|
|
155
|
+
* Broadcast data to connections in a session, filtered by a predicate.
|
|
156
|
+
* Only sends to peers where filterFn(peerId) returns true.
|
|
157
|
+
*
|
|
158
|
+
* Used for platform-aware routing where echo suppression requires
|
|
159
|
+
* skipping certain peers based on metadata (not just exclusion by ID).
|
|
160
|
+
*
|
|
161
|
+
* Does NOT replace broadcastToSession -- that method remains for existing callers.
|
|
162
|
+
*/
|
|
163
|
+
broadcastToSessionWithFilter(sessionId, data, filterFn) {
|
|
164
|
+
const sessionMap = this.connections.get(sessionId);
|
|
165
|
+
if (!sessionMap)
|
|
166
|
+
return;
|
|
167
|
+
for (const [peerId, conns] of sessionMap) {
|
|
168
|
+
if (!filterFn(peerId))
|
|
169
|
+
continue;
|
|
170
|
+
for (const conn of conns) {
|
|
171
|
+
if (conn.ws.readyState === 1) {
|
|
172
|
+
conn.ws.send(data);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
154
177
|
/**
|
|
155
178
|
* Check whether a peer has at least one active connection.
|
|
156
179
|
*/
|