@zhin.js/adapter-sandbox 3.0.1 → 3.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/README.md +16 -2
- package/client/Sandbox.tsx +111 -31
- package/client/sandboxTransport.ts +61 -0
- package/dist/index.js +7 -7
- package/lib/fetch-sse.d.ts +11 -0
- package/lib/fetch-sse.d.ts.map +1 -0
- package/lib/fetch-sse.js +76 -0
- package/lib/fetch-sse.js.map +1 -0
- package/lib/fetch-ws.d.ts +11 -0
- package/lib/fetch-ws.d.ts.map +1 -0
- package/lib/fetch-ws.js +13 -0
- package/lib/fetch-ws.js.map +1 -0
- package/lib/index.d.ts +16 -48
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +25 -132
- package/lib/index.js.map +1 -1
- package/lib/sandbox-sse-hub.d.ts +10 -0
- package/lib/sandbox-sse-hub.d.ts.map +1 -0
- package/lib/sandbox-sse-hub.js +101 -0
- package/lib/sandbox-sse-hub.js.map +1 -0
- package/lib/sandbox-ws.d.ts +91 -0
- package/lib/sandbox-ws.d.ts.map +1 -0
- package/lib/sandbox-ws.js +337 -0
- package/lib/sandbox-ws.js.map +1 -0
- package/package.json +14 -9
- package/src/fetch-sse.ts +87 -0
- package/src/fetch-ws.ts +23 -0
- package/src/index.ts +57 -181
- package/src/sandbox-sse-hub.ts +118 -0
- package/src/sandbox-ws.ts +462 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type RouteTable } from "@zhin.js/http-host/edge";
|
|
2
|
+
import type { SandboxWsHostAdapter } from "./sandbox-ws.js";
|
|
3
|
+
export type RegisterSandboxWsOptions = {
|
|
4
|
+
/** 兼容旧路径,默认 `/ws` */
|
|
5
|
+
legacyPaths?: string[];
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Deno / Edge:在 {@link RouteTable} 上注册 `/sandbox` WebSocket(http-host Fetch upgrade)。
|
|
9
|
+
*/
|
|
10
|
+
export declare function registerSandboxWebSocketRoutes(table: RouteTable, getAdapter: () => SandboxWsHostAdapter, options?: RegisterSandboxWsOptions): void;
|
|
11
|
+
//# sourceMappingURL=fetch-ws.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-ws.d.ts","sourceRoot":"","sources":["../src/fetch-ws.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,KAAK,EAAE,oBAAoB,EAAmB,MAAM,iBAAiB,CAAC;AAE7E,MAAM,MAAM,wBAAwB,GAAG;IACrC,qBAAqB;IACrB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AAEF;;GAEG;AACH,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,UAAU,EACjB,UAAU,EAAE,MAAM,oBAAoB,EACtC,OAAO,GAAE,wBAA6B,GACrC,IAAI,CAON"}
|
package/lib/fetch-ws.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { registerWebSocketRoute } from "@zhin.js/http-host/edge";
|
|
2
|
+
/**
|
|
3
|
+
* Deno / Edge:在 {@link RouteTable} 上注册 `/sandbox` WebSocket(http-host Fetch upgrade)。
|
|
4
|
+
*/
|
|
5
|
+
export function registerSandboxWebSocketRoutes(table, getAdapter, options = {}) {
|
|
6
|
+
const paths = ["/sandbox", ...(options.legacyPaths ?? ["/ws"])];
|
|
7
|
+
for (const path of paths) {
|
|
8
|
+
registerWebSocketRoute(table, path, (ws) => {
|
|
9
|
+
getAdapter().acceptWebSocket(ws);
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=fetch-ws.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-ws.js","sourceRoot":"","sources":["../src/fetch-ws.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAmB,MAAM,yBAAyB,CAAC;AAQlF;;GAEG;AACH,MAAM,UAAU,8BAA8B,CAC5C,KAAiB,EACjB,UAAsC,EACtC,UAAoC,EAAE;IAEtC,MAAM,KAAK,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,OAAO,CAAC,WAAW,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAChE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,sBAAsB,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,EAAW,EAAE,EAAE;YAClD,UAAU,EAAE,CAAC,eAAe,CAAC,EAAqB,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,56 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export interface SandboxConfig {
|
|
7
|
-
context: "sandbox";
|
|
8
|
-
ws: WebSocket;
|
|
9
|
-
name: string;
|
|
10
|
-
/** 发言者即为 owner(沙箱模式) */
|
|
11
|
-
owner?: string;
|
|
12
|
-
}
|
|
1
|
+
import { usePlugin } from "zhin.js";
|
|
2
|
+
import { SandboxWsHostAdapter } from "./sandbox-ws.js";
|
|
3
|
+
type SandboxRouter = {
|
|
4
|
+
ws: (path: string) => NonNullable<SandboxAdapter["wss"]>;
|
|
5
|
+
};
|
|
13
6
|
declare module "zhin.js" {
|
|
14
|
-
namespace Plugin {
|
|
15
|
-
interface Contexts {
|
|
16
|
-
router: Router;
|
|
17
|
-
web: PageManager;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
7
|
interface Adapters {
|
|
21
8
|
sandbox: SandboxAdapter;
|
|
22
9
|
}
|
|
23
10
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
get $id(): string;
|
|
32
|
-
private logger;
|
|
33
|
-
constructor(adapter: SandboxAdapter, $config: SandboxConfig);
|
|
34
|
-
$connect(): Promise<void>;
|
|
35
|
-
$disconnect(): Promise<void>;
|
|
36
|
-
$formatMessage({ content, type, id, ts }: {
|
|
37
|
-
content: MessageElement[];
|
|
38
|
-
id: string;
|
|
39
|
-
type: MessageType;
|
|
40
|
-
ts: number;
|
|
41
|
-
}): Message<{
|
|
42
|
-
content: MessageElement[];
|
|
43
|
-
ts: number;
|
|
44
|
-
}>;
|
|
45
|
-
$sendMessage(options: SendOptions): Promise<string>;
|
|
46
|
-
$recallMessage(id: string): Promise<void>;
|
|
47
|
-
}
|
|
48
|
-
declare class SandboxAdapter extends Adapter<SandboxBot> {
|
|
49
|
-
wss?: ReturnType<Router["ws"]>;
|
|
50
|
-
constructor(plugin: Plugin);
|
|
51
|
-
createBot(config: SandboxConfig): SandboxBot;
|
|
11
|
+
/** Node:`Router.ws`;Deno/Edge:`registerSandboxWebSocketRoutes`(http-host) */
|
|
12
|
+
export declare class SandboxAdapter extends SandboxWsHostAdapter {
|
|
13
|
+
wss?: {
|
|
14
|
+
on: (ev: string, fn: (...args: unknown[]) => void) => void;
|
|
15
|
+
close: () => void;
|
|
16
|
+
};
|
|
17
|
+
constructor(plugin: ReturnType<typeof usePlugin>);
|
|
52
18
|
start(): Promise<void>;
|
|
53
|
-
setupWebSocket(router:
|
|
19
|
+
setupWebSocket(router: SandboxRouter): Promise<void>;
|
|
54
20
|
}
|
|
55
|
-
export {};
|
|
21
|
+
export { registerSandboxWebSocketRoutes, type RegisterSandboxWsOptions, } from "./fetch-ws.js";
|
|
22
|
+
export { registerSandboxSseRoutes, type RegisterSandboxSseOptions, } from "./fetch-sse.js";
|
|
23
|
+
export { SandboxWsBot, SandboxWsHostAdapter, resolveSandboxBot, bindSandboxWsSocket, parseSandboxWsPayload, type ResolvedSandboxBot, type SandboxTransport, type SandboxWsConfig, type SandboxWsSocket, } from "./sandbox-ws.js";
|
|
56
24
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAe,MAAM,SAAS,CAAC;AAEjD,OAAO,EACL,oBAAoB,EAGrB,MAAM,iBAAiB,CAAC;AAGzB,KAAK,aAAa,GAAG;IACnB,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,WAAW,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;CAC1D,CAAC;AAEF,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,QAAQ;QAChB,OAAO,EAAE,cAAc,CAAC;KACzB;CACF;AAKD,6EAA6E;AAC7E,qBAAa,cAAe,SAAQ,oBAAoB;IACtD,GAAG,CAAC,EAAE;QAAE,EAAE,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,KAAK,IAAI,CAAC;QAAC,KAAK,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC;gBAE5E,MAAM,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC;IAKjC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ/B,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;CAsB3D;AAkCD,OAAO,EACL,8BAA8B,EAC9B,KAAK,wBAAwB,GAC9B,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,wBAAwB,EACxB,KAAK,yBAAyB,GAC/B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,YAAY,EACZ,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,qBAAqB,EACrB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,eAAe,GACrB,MAAM,iBAAiB,CAAC"}
|
package/lib/index.js
CHANGED
|
@@ -1,170 +1,60 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { usePlugin } from "zhin.js";
|
|
3
|
+
import { SandboxWsHostAdapter, resolveSandboxBot, } from "./sandbox-ws.js";
|
|
4
4
|
const plugin = usePlugin();
|
|
5
5
|
const logger = plugin.logger;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
$config;
|
|
9
|
-
$connected = false;
|
|
10
|
-
get $id() {
|
|
11
|
-
return this.$config.name;
|
|
12
|
-
}
|
|
13
|
-
logger = logger;
|
|
14
|
-
constructor(adapter, $config) {
|
|
15
|
-
super();
|
|
16
|
-
this.adapter = adapter;
|
|
17
|
-
this.$config = $config;
|
|
18
|
-
this.$config.ws.on("message", (data) => {
|
|
19
|
-
const message = JSON.parse(data.toString());
|
|
20
|
-
// 确保 content 是 MessageElement[] 格式
|
|
21
|
-
const content = typeof message.content === 'string'
|
|
22
|
-
? [{ type: 'text', data: { text: message.content } }]
|
|
23
|
-
: message.content;
|
|
24
|
-
this.logger.debug(`${this.$config.name} recv ${message.type}(${message.id}):${segment.raw(content)}`);
|
|
25
|
-
const formattedMessage = this.$formatMessage({ content: content, type: message.type, id: message.id, ts: message.timestamp });
|
|
26
|
-
this.adapter.emit("message.receive", formattedMessage);
|
|
27
|
-
});
|
|
28
|
-
this.$config.ws.on("close", () => {
|
|
29
|
-
this.logger.debug(`Sandbox bot ${this.$config.name} disconnected`);
|
|
30
|
-
this.$connected = false;
|
|
31
|
-
// 从 adapter 中移除 bot
|
|
32
|
-
this.adapter.bots.delete(this.$id);
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
async $connect() {
|
|
36
|
-
this.$connected = true;
|
|
37
|
-
}
|
|
38
|
-
async $disconnect() {
|
|
39
|
-
this.$config.ws.close();
|
|
40
|
-
this.$connected = false;
|
|
41
|
-
}
|
|
42
|
-
$formatMessage({ content, type, id, ts }) {
|
|
43
|
-
// 沙箱模式:发言者即为 owner
|
|
44
|
-
if (!this.$config.owner)
|
|
45
|
-
this.$config.owner = id;
|
|
46
|
-
const message = Message.from({ content, ts }, {
|
|
47
|
-
$id: `${ts}`,
|
|
48
|
-
$adapter: "sandbox",
|
|
49
|
-
$bot: `${this.$config.name}`,
|
|
50
|
-
$sender: {
|
|
51
|
-
id: `${id}`,
|
|
52
|
-
name: `mock`,
|
|
53
|
-
},
|
|
54
|
-
$channel: {
|
|
55
|
-
id: `${id}`,
|
|
56
|
-
type: type,
|
|
57
|
-
},
|
|
58
|
-
$content: content,
|
|
59
|
-
$raw: segment.raw(content),
|
|
60
|
-
$timestamp: ts,
|
|
61
|
-
$recall: async () => {
|
|
62
|
-
await this.$recallMessage(message.$id);
|
|
63
|
-
},
|
|
64
|
-
$reply: async (content, quote) => {
|
|
65
|
-
if (!Array.isArray(content))
|
|
66
|
-
content = [content];
|
|
67
|
-
if (quote)
|
|
68
|
-
content.unshift({ type: "reply", data: { id: typeof quote === "boolean" ? message.$id : quote } });
|
|
69
|
-
return await this.adapter.sendMessage({
|
|
70
|
-
...message.$channel,
|
|
71
|
-
context: "sandbox",
|
|
72
|
-
bot: `${this.$config.name}`,
|
|
73
|
-
content,
|
|
74
|
-
});
|
|
75
|
-
},
|
|
76
|
-
});
|
|
77
|
-
return message;
|
|
78
|
-
}
|
|
79
|
-
async $sendMessage(options) {
|
|
80
|
-
if (!this.$connected)
|
|
81
|
-
return "";
|
|
82
|
-
this.logger.debug(`${this.$config.name} send ${options.type}(${options.id}):${segment.raw(options.content)}`);
|
|
83
|
-
options.bot = this.$config.name;
|
|
84
|
-
options.context = "sandbox";
|
|
85
|
-
this.$config.ws.send(JSON.stringify({
|
|
86
|
-
...options,
|
|
87
|
-
content: options.content, // 发送消息段数组
|
|
88
|
-
timestamp: Date.now(),
|
|
89
|
-
}));
|
|
90
|
-
return "";
|
|
91
|
-
}
|
|
92
|
-
async $recallMessage(id) {
|
|
93
|
-
// 沙盒不支持撤回消息
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
class SandboxAdapter extends Adapter {
|
|
6
|
+
/** Node:`Router.ws`;Deno/Edge:`registerSandboxWebSocketRoutes`(http-host) */
|
|
7
|
+
export class SandboxAdapter extends SandboxWsHostAdapter {
|
|
97
8
|
wss;
|
|
98
9
|
constructor(plugin) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
createBot(config) {
|
|
102
|
-
const bot = new SandboxBot(this, config);
|
|
103
|
-
// 将 bot 添加到 bots Map 中
|
|
104
|
-
this.bots.set(bot.$id, bot);
|
|
105
|
-
return bot;
|
|
10
|
+
const appConfig = (plugin.inject("config")?.getPrimary() ?? {});
|
|
11
|
+
super(plugin, resolveSandboxBot(appConfig));
|
|
106
12
|
}
|
|
107
13
|
async start() {
|
|
108
|
-
|
|
109
|
-
|
|
14
|
+
await super.start();
|
|
15
|
+
this.registerConfiguredPlaceholder();
|
|
16
|
+
logger.debug(`Sandbox placeholder: ${this.defaults.name} (offline until /sandbox WS)`);
|
|
110
17
|
}
|
|
111
18
|
async setupWebSocket(router) {
|
|
112
19
|
if (this.wss)
|
|
113
|
-
return;
|
|
114
|
-
// 创建 WebSocket server
|
|
20
|
+
return;
|
|
115
21
|
this.wss = router.ws("/sandbox");
|
|
116
|
-
this.wss.on("connection", (
|
|
117
|
-
|
|
118
|
-
const
|
|
119
|
-
logger.debug(`New sandbox connection
|
|
120
|
-
|
|
121
|
-
const config = {
|
|
122
|
-
context: "sandbox",
|
|
123
|
-
ws,
|
|
124
|
-
name: botName,
|
|
125
|
-
};
|
|
126
|
-
// 创建并连接 bot
|
|
127
|
-
const bot = this.createBot(config);
|
|
128
|
-
bot.$connect();
|
|
129
|
-
// WebSocket 关闭时清理
|
|
22
|
+
this.wss.on("connection", (...args) => {
|
|
23
|
+
const ws = args[0];
|
|
24
|
+
const req = args[1];
|
|
25
|
+
logger.debug(`New sandbox connection from ${req.socket?.remoteAddress ?? "unknown"}`);
|
|
26
|
+
const bot = this.acceptWebSocket(ws);
|
|
130
27
|
ws.on("close", () => {
|
|
131
|
-
logger.debug(`Sandbox connection closed: ${
|
|
28
|
+
logger.debug(`Sandbox connection closed: ${bot.$config.name}`);
|
|
132
29
|
this.bots.delete(bot.$id);
|
|
133
30
|
});
|
|
134
31
|
ws.on("error", (error) => {
|
|
135
|
-
logger.error(`Sandbox WebSocket error for ${
|
|
32
|
+
logger.error(`Sandbox WebSocket error for ${bot.$config.name}:`, error);
|
|
136
33
|
});
|
|
137
34
|
});
|
|
138
|
-
logger.debug("Sandbox WebSocket server started at /sandbox");
|
|
35
|
+
logger.debug("Sandbox WebSocket server started at /sandbox (Node Router.ws)");
|
|
139
36
|
}
|
|
140
37
|
}
|
|
141
38
|
const { provide } = usePlugin();
|
|
142
39
|
provide({
|
|
143
40
|
name: "sandbox",
|
|
144
|
-
description: "Sandbox Adapter",
|
|
41
|
+
description: "Sandbox Adapter — Node Router.ws + Deno http-host WebSocket",
|
|
145
42
|
mounted: async (p) => {
|
|
146
43
|
const adapter = new SandboxAdapter(p);
|
|
147
44
|
await adapter.start();
|
|
148
45
|
return adapter;
|
|
149
46
|
},
|
|
150
47
|
dispose: async (adapter) => {
|
|
151
|
-
// 关闭所有 bot 连接
|
|
152
48
|
for (const bot of adapter.bots.values()) {
|
|
153
49
|
await bot.$disconnect();
|
|
154
50
|
}
|
|
155
|
-
// 关闭 WebSocket server
|
|
156
51
|
adapter.wss?.close();
|
|
157
52
|
await adapter.stop();
|
|
158
53
|
},
|
|
159
54
|
});
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
// 等待 sandbox adapter 就绪
|
|
163
|
-
plugin.useContext("sandbox", async (adapter) => {
|
|
164
|
-
await adapter.setupWebSocket(router);
|
|
165
|
-
});
|
|
55
|
+
plugin.useContext("router", 'sandbox', async (router, adapter) => {
|
|
56
|
+
await adapter.setupWebSocket(router);
|
|
166
57
|
});
|
|
167
|
-
// 使用 web 上下文注册客户端入口
|
|
168
58
|
plugin.useContext("web", (pageManager) => {
|
|
169
59
|
pageManager.addEntry({
|
|
170
60
|
id: "sandbox",
|
|
@@ -173,4 +63,7 @@ plugin.useContext("web", (pageManager) => {
|
|
|
173
63
|
meta: { name: "Sandbox" },
|
|
174
64
|
});
|
|
175
65
|
});
|
|
66
|
+
export { registerSandboxWebSocketRoutes, } from "./fetch-ws.js";
|
|
67
|
+
export { registerSandboxSseRoutes, } from "./fetch-sse.js";
|
|
68
|
+
export { SandboxWsBot, SandboxWsHostAdapter, resolveSandboxBot, bindSandboxWsSocket, parseSandboxWsPayload, } from "./sandbox-ws.js";
|
|
176
69
|
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 按 session 隔离的 Sandbox SSE 推送(Edge / Vercel 等无 WebSocket 入站时使用)。
|
|
3
|
+
* SSE `data` 字段为与 WebSocket 相同的 JSON 字符串。
|
|
4
|
+
*/
|
|
5
|
+
export declare function broadcastSandboxSse(sessionId: string, jsonPayload: string): void;
|
|
6
|
+
export declare function subscribeSandboxSse(sessionId: string, lastEventId?: string): ReadableStream<Uint8Array>;
|
|
7
|
+
export declare function closeSandboxSseSession(sessionId: string): void;
|
|
8
|
+
/** @internal */
|
|
9
|
+
export declare function resetSandboxSseHubForTests(): void;
|
|
10
|
+
//# sourceMappingURL=sandbox-sse-hub.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-sse-hub.d.ts","sourceRoot":"","sources":["../src/sandbox-sse-hub.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAqCH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAYhF;AAED,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,WAAW,CAAC,EAAE,MAAM,GACnB,cAAc,CAAC,UAAU,CAAC,CA8C5B;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAM9D;AAED,gBAAgB;AAChB,wBAAgB,0BAA0B,IAAI,IAAI,CAGjD"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 按 session 隔离的 Sandbox SSE 推送(Edge / Vercel 等无 WebSocket 入站时使用)。
|
|
3
|
+
* SSE `data` 字段为与 WebSocket 相同的 JSON 字符串。
|
|
4
|
+
*/
|
|
5
|
+
const MAX_REPLAY = 100;
|
|
6
|
+
const sessions = new Map();
|
|
7
|
+
function getSession(sessionId) {
|
|
8
|
+
let s = sessions.get(sessionId);
|
|
9
|
+
if (!s) {
|
|
10
|
+
s = { subscribers: new Map(), history: [], nextSubId: 0, nextEventId: 0 };
|
|
11
|
+
sessions.set(sessionId, s);
|
|
12
|
+
}
|
|
13
|
+
return s;
|
|
14
|
+
}
|
|
15
|
+
function formatSse(data, id) {
|
|
16
|
+
const lines = [];
|
|
17
|
+
if (id)
|
|
18
|
+
lines.push(`id: ${id}`);
|
|
19
|
+
lines.push(`data: ${data}`);
|
|
20
|
+
lines.push("");
|
|
21
|
+
return lines.join("\n") + "\n";
|
|
22
|
+
}
|
|
23
|
+
export function broadcastSandboxSse(sessionId, jsonPayload) {
|
|
24
|
+
const session = getSession(sessionId);
|
|
25
|
+
const stored = {
|
|
26
|
+
id: String(++session.nextEventId),
|
|
27
|
+
data: jsonPayload,
|
|
28
|
+
};
|
|
29
|
+
session.history.push(stored);
|
|
30
|
+
if (session.history.length > MAX_REPLAY)
|
|
31
|
+
session.history.shift();
|
|
32
|
+
const chunk = formatSse(stored.data, stored.id);
|
|
33
|
+
for (const sub of session.subscribers.values()) {
|
|
34
|
+
sub.enqueue(chunk);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export function subscribeSandboxSse(sessionId, lastEventId) {
|
|
38
|
+
const session = getSession(sessionId);
|
|
39
|
+
const encoder = new TextEncoder();
|
|
40
|
+
const replayFrom = lastEventId ? Number.parseInt(lastEventId, 10) : 0;
|
|
41
|
+
const subId = `sse-${++session.nextSubId}`;
|
|
42
|
+
return new ReadableStream({
|
|
43
|
+
start(controller) {
|
|
44
|
+
for (const ev of session.history) {
|
|
45
|
+
if (Number(ev.id) > replayFrom) {
|
|
46
|
+
controller.enqueue(encoder.encode(formatSse(ev.data, ev.id)));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const interval = setInterval(() => {
|
|
50
|
+
try {
|
|
51
|
+
controller.enqueue(encoder.encode(": heartbeat\n\n"));
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
clearInterval(interval);
|
|
55
|
+
}
|
|
56
|
+
}, 15000);
|
|
57
|
+
session.subscribers.set(subId, {
|
|
58
|
+
id: subId,
|
|
59
|
+
enqueue: (chunk) => {
|
|
60
|
+
try {
|
|
61
|
+
controller.enqueue(encoder.encode(chunk));
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
/* closed */
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
close: () => {
|
|
68
|
+
clearInterval(interval);
|
|
69
|
+
try {
|
|
70
|
+
controller.close();
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
/* */
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
},
|
|
78
|
+
cancel() {
|
|
79
|
+
const s = sessions.get(sessionId);
|
|
80
|
+
const sub = s?.subscribers.get(subId);
|
|
81
|
+
sub?.close();
|
|
82
|
+
s?.subscribers.delete(subId);
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
export function closeSandboxSseSession(sessionId) {
|
|
87
|
+
const session = sessions.get(sessionId);
|
|
88
|
+
if (!session)
|
|
89
|
+
return;
|
|
90
|
+
for (const sub of session.subscribers.values())
|
|
91
|
+
sub.close();
|
|
92
|
+
session.subscribers.clear();
|
|
93
|
+
sessions.delete(sessionId);
|
|
94
|
+
}
|
|
95
|
+
/** @internal */
|
|
96
|
+
export function resetSandboxSseHubForTests() {
|
|
97
|
+
for (const id of [...sessions.keys()])
|
|
98
|
+
closeSandboxSseSession(id);
|
|
99
|
+
sessions.clear();
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=sandbox-sse-hub.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-sse-hub.js","sourceRoot":"","sources":["../src/sandbox-sse-hub.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sandbox 传输 — Node WebSocket;Edge HTTP+SSE(见 sandbox-sse-hub / fetch-sse)。
|
|
3
|
+
*/
|
|
4
|
+
import { EventEmitter } from "node:events";
|
|
5
|
+
import { Adapter, Bot, Message, type MessageElement, type MessageType, type Plugin, type SendOptions } from "zhin.js";
|
|
6
|
+
export interface SandboxWsConfig {
|
|
7
|
+
context: "sandbox";
|
|
8
|
+
ws?: SandboxWsSocket;
|
|
9
|
+
name: string;
|
|
10
|
+
owner?: string;
|
|
11
|
+
/** yaml 预置名:启动时占位,WS 连接前在 bot:list 显示为离线 */
|
|
12
|
+
offline?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/** 无 WS 时的占位 socket(仅用于 bot:list,不可收发) */
|
|
15
|
+
export declare function createOfflineSandboxWs(): SandboxWsSocket;
|
|
16
|
+
export declare function createSandboxSseTransport(sessionId: string, onClose?: () => void): SandboxWsSocket & {
|
|
17
|
+
sessionId: string;
|
|
18
|
+
};
|
|
19
|
+
/** 兼容 `ws` 包与标准 WebSocket */
|
|
20
|
+
export type SandboxWsSocket = {
|
|
21
|
+
send(data: string): void;
|
|
22
|
+
close(code?: number, reason?: string): void;
|
|
23
|
+
on?(event: "message" | "close" | "error", listener: (...args: unknown[]) => void): void;
|
|
24
|
+
off?(event: "message" | "close" | "error", listener: (...args: unknown[]) => void): void;
|
|
25
|
+
addEventListener?(type: "message" | "close" | "error", listener: (ev: Event | MessageEvent | CloseEvent) => void): void;
|
|
26
|
+
removeEventListener?(type: "message" | "close" | "error", listener: (ev: Event | MessageEvent | CloseEvent) => void): void;
|
|
27
|
+
};
|
|
28
|
+
export type SandboxBotDefaults = {
|
|
29
|
+
name: string;
|
|
30
|
+
owner: string;
|
|
31
|
+
/** true:每连接随机 bot 名(Node 本地默认);false:固定 name(Edge 单实例) */
|
|
32
|
+
randomNamePerConnection?: boolean;
|
|
33
|
+
};
|
|
34
|
+
export type SandboxTransport = "websocket" | "http-sse";
|
|
35
|
+
export type ResolvedSandboxBot = {
|
|
36
|
+
context: "sandbox";
|
|
37
|
+
name: string;
|
|
38
|
+
owner: string;
|
|
39
|
+
randomNamePerConnection: boolean;
|
|
40
|
+
transport: SandboxTransport;
|
|
41
|
+
};
|
|
42
|
+
export declare function resolveSandboxBot(appConfig: Record<string, unknown>): ResolvedSandboxBot;
|
|
43
|
+
export declare function bindSandboxWsSocket(ws: SandboxWsSocket, handlers: {
|
|
44
|
+
onMessage: (raw: string) => void;
|
|
45
|
+
onClose: () => void;
|
|
46
|
+
onError?: (err: unknown) => void;
|
|
47
|
+
}): () => void;
|
|
48
|
+
export declare function parseSandboxWsPayload(raw: string): {
|
|
49
|
+
type: MessageType;
|
|
50
|
+
id: string;
|
|
51
|
+
content: MessageElement[];
|
|
52
|
+
timestamp: number;
|
|
53
|
+
};
|
|
54
|
+
type BotEvent = {
|
|
55
|
+
content: MessageElement[];
|
|
56
|
+
type: MessageType;
|
|
57
|
+
id: string;
|
|
58
|
+
ts: number;
|
|
59
|
+
};
|
|
60
|
+
export declare class SandboxWsBot extends EventEmitter implements Bot<SandboxWsConfig, BotEvent> {
|
|
61
|
+
#private;
|
|
62
|
+
adapter: SandboxWsHostAdapter;
|
|
63
|
+
$config: SandboxWsConfig;
|
|
64
|
+
$connected: boolean;
|
|
65
|
+
get $id(): string;
|
|
66
|
+
constructor(adapter: SandboxWsHostAdapter, $config: SandboxWsConfig);
|
|
67
|
+
$connect(): Promise<void>;
|
|
68
|
+
$disconnect(): Promise<void>;
|
|
69
|
+
$formatMessage({ content, type, id, ts }: BotEvent): Message<BotEvent>;
|
|
70
|
+
$sendMessage(options: SendOptions): Promise<string>;
|
|
71
|
+
$recallMessage(_id: string): Promise<void>;
|
|
72
|
+
}
|
|
73
|
+
export declare class SandboxWsHostAdapter extends Adapter<SandboxWsBot> {
|
|
74
|
+
#private;
|
|
75
|
+
protected readonly defaults: ResolvedSandboxBot;
|
|
76
|
+
constructor(plugin: Plugin, defaults: ResolvedSandboxBot);
|
|
77
|
+
get transport(): SandboxTransport;
|
|
78
|
+
hasSseSession(sessionId: string): boolean;
|
|
79
|
+
getBotBySseSession(sessionId: string): SandboxWsBot | undefined;
|
|
80
|
+
createBot(config: SandboxWsConfig): SandboxWsBot;
|
|
81
|
+
/** `zhin.config.yml` 中 `context: sandbox` + 固定 `name` 时,启动即出现在 bot:list(离线) */
|
|
82
|
+
registerConfiguredPlaceholder(): void;
|
|
83
|
+
/** Edge / 外部 upgrade:注入已建立的 WebSocket */
|
|
84
|
+
acceptWebSocket(ws: SandboxWsSocket, overrides?: Partial<Pick<SandboxWsConfig, "name" | "owner">>): SandboxWsBot;
|
|
85
|
+
/** Edge SSE:建立会话并绑定固定 bot */
|
|
86
|
+
acceptSseSession(sessionId: string, overrides?: Partial<Pick<SandboxWsConfig, "name" | "owner">>): SandboxWsBot;
|
|
87
|
+
/** POST /sandbox/message — 与 WebSocket 帧同格式的 JSON 字符串 */
|
|
88
|
+
ingestSseClientMessage(sessionId: string, raw: string): void;
|
|
89
|
+
}
|
|
90
|
+
export {};
|
|
91
|
+
//# sourceMappingURL=sandbox-ws.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-ws.d.ts","sourceRoot":"","sources":["../src/sandbox-ws.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EACL,OAAO,EACP,GAAG,EACH,OAAO,EAEP,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,MAAM,EAEX,KAAK,WAAW,EACjB,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,SAAS,CAAC;IACnB,EAAE,CAAC,EAAE,eAAe,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,0CAA0C;AAC1C,wBAAgB,sBAAsB,IAAI,eAAe,CAExD;AAED,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,IAAI,GACnB,eAAe,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAWzC;AAED,6BAA6B;AAC7B,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,EAAE,CAAC,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,GAAG,OAAO,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;IACxF,GAAG,CAAC,CACF,KAAK,EAAE,SAAS,GAAG,OAAO,GAAG,OAAO,EACpC,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GACrC,IAAI,CAAC;IACR,gBAAgB,CAAC,CACf,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,OAAO,EACnC,QAAQ,EAAE,CAAC,EAAE,EAAE,KAAK,GAAG,YAAY,GAAG,UAAU,KAAK,IAAI,GACxD,IAAI,CAAC;IACR,mBAAmB,CAAC,CAClB,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,OAAO,EACnC,QAAQ,EAAE,CAAC,EAAE,EAAE,KAAK,GAAG,YAAY,GAAG,UAAU,KAAK,IAAI,GACxD,IAAI,CAAC;CACT,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,UAAU,CAAC;AAExD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,SAAS,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,uBAAuB,EAAE,OAAO,CAAC;IACjC,SAAS,EAAE,gBAAgB,CAAC;CAC7B,CAAC;AAUF,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,kBAAkB,CAyBpB;AAgBD,wBAAgB,mBAAmB,CACjC,EAAE,EAAE,eAAe,EACnB,QAAQ,EAAE;IACR,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;CAClC,GACA,MAAM,IAAI,CAsCZ;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG;IAClD,IAAI,EAAE,WAAW,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB,CAqBA;AAED,KAAK,QAAQ,GAAG;IACd,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,IAAI,EAAE,WAAW,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAEF,qBAAa,YAAa,SAAQ,YAAa,YAAW,GAAG,CAAC,eAAe,EAAE,QAAQ,CAAC;;IAS7E,OAAO,EAAE,oBAAoB;IAC7B,OAAO,EAAE,eAAe;IATjC,UAAU,UAAS;IAGnB,IAAI,GAAG,WAEN;gBAGQ,OAAO,EAAE,oBAAoB,EAC7B,OAAO,EAAE,eAAe;IAK3B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IA8BzB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAOlC,cAAc,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,QAAQ;IAqC5C,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAcnD,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CACjD;AAED,qBAAa,oBAAqB,SAAQ,OAAO,CAAC,YAAY,CAAC;;IAK3D,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,kBAAkB;gBAD/C,MAAM,EAAE,MAAM,EACK,QAAQ,EAAE,kBAAkB;IAKjD,IAAI,SAAS,IAAI,gBAAgB,CAEhC;IAED,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAIzC,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAK/D,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,YAAY;IAMhD,+EAA+E;IAC/E,6BAA6B,IAAI,IAAI;IAYrC,yCAAyC;IACzC,eAAe,CACb,EAAE,EAAE,eAAe,EACnB,SAAS,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAC3D,YAAY;IAqCf,6BAA6B;IAC7B,gBAAgB,CACd,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAC3D,YAAY;IAuCf,yDAAyD;IACzD,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;CAW7D"}
|