@yushaw/sanqian-sdk 0.2.10 → 0.2.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,273 +1,293 @@
1
- // src/client.ts
2
- import WebSocket from "isomorphic-ws";
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __esm = (fn, res) => function __init() {
4
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
5
+ };
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
3
10
 
4
11
  // src/discovery.ts
12
+ var discovery_exports = {};
13
+ __export(discovery_exports, {
14
+ DiscoveryManager: () => DiscoveryManager
15
+ });
5
16
  import { existsSync, readFileSync, watch } from "fs";
6
17
  import { homedir, platform } from "os";
7
18
  import { join } from "path";
8
19
  import { spawn, execSync } from "child_process";
9
- var DiscoveryManager = class {
10
- connectionInfo = null;
11
- watcher = null;
12
- onChange = null;
13
- pollInterval = null;
14
- /**
15
- * Cached executable path from last successful connection.json read.
16
- * Persists even when Sanqian is not running, for use in auto-launch.
17
- */
18
- cachedExecutable = null;
19
- /**
20
- * Get the path to connection.json
21
- */
22
- getConnectionFilePath() {
23
- return join(homedir(), ".sanqian", "runtime", "connection.json");
24
- }
25
- /**
26
- * Read and validate connection info
27
- *
28
- * Returns null if:
29
- * - File doesn't exist
30
- * - File is invalid JSON
31
- * - Process is not running
32
- */
33
- read() {
34
- const filePath = this.getConnectionFilePath();
35
- if (!existsSync(filePath)) {
36
- return null;
37
- }
38
- try {
39
- const content = readFileSync(filePath, "utf-8");
40
- const info = JSON.parse(content);
41
- if (!info.port || !info.token || !info.pid) {
42
- return null;
20
+ var DiscoveryManager;
21
+ var init_discovery = __esm({
22
+ "src/discovery.ts"() {
23
+ "use strict";
24
+ DiscoveryManager = class {
25
+ connectionInfo = null;
26
+ watcher = null;
27
+ onChange = null;
28
+ pollInterval = null;
29
+ /**
30
+ * Cached executable path from last successful connection.json read.
31
+ * Persists even when Sanqian is not running, for use in auto-launch.
32
+ */
33
+ cachedExecutable = null;
34
+ /**
35
+ * Get the path to connection.json
36
+ */
37
+ getConnectionFilePath() {
38
+ return join(homedir(), ".sanqian", "runtime", "connection.json");
43
39
  }
44
- if (info.executable) {
45
- this.cachedExecutable = info.executable;
46
- }
47
- if (!this.isProcessRunning(info.pid)) {
48
- return null;
49
- }
50
- this.connectionInfo = info;
51
- return info;
52
- } catch {
53
- return null;
54
- }
55
- }
56
- /**
57
- * Start watching for connection file changes
58
- */
59
- startWatching(onChange) {
60
- this.onChange = onChange;
61
- const dir = join(homedir(), ".sanqian", "runtime");
62
- if (!existsSync(dir)) {
63
- this.pollInterval = setInterval(() => {
64
- if (existsSync(dir)) {
65
- if (this.pollInterval) {
66
- clearInterval(this.pollInterval);
67
- this.pollInterval = null;
40
+ /**
41
+ * Read and validate connection info
42
+ *
43
+ * Returns null if:
44
+ * - File doesn't exist
45
+ * - File is invalid JSON
46
+ * - Process is not running
47
+ */
48
+ read() {
49
+ const filePath = this.getConnectionFilePath();
50
+ if (!existsSync(filePath)) {
51
+ return null;
52
+ }
53
+ try {
54
+ const content = readFileSync(filePath, "utf-8");
55
+ const info = JSON.parse(content);
56
+ if (!info.port || !info.token || !info.pid) {
57
+ return null;
58
+ }
59
+ if (info.executable) {
60
+ this.cachedExecutable = info.executable;
61
+ }
62
+ if (!this.isProcessRunning(info.pid)) {
63
+ return null;
68
64
  }
69
- this.setupWatcher(dir);
65
+ this.connectionInfo = info;
66
+ return info;
67
+ } catch {
68
+ return null;
70
69
  }
71
- }, 2e3);
72
- return;
73
- }
74
- this.setupWatcher(dir);
75
- }
76
- setupWatcher(dir) {
77
- try {
78
- this.watcher = watch(dir, (event, filename) => {
79
- if (filename === "connection.json") {
80
- setTimeout(() => {
81
- const newInfo = this.read();
82
- const oldInfoStr = JSON.stringify(this.connectionInfo);
83
- const newInfoStr = JSON.stringify(newInfo);
84
- if (oldInfoStr !== newInfoStr) {
85
- this.connectionInfo = newInfo;
86
- this.onChange?.(newInfo);
70
+ }
71
+ /**
72
+ * Start watching for connection file changes
73
+ */
74
+ startWatching(onChange) {
75
+ this.onChange = onChange;
76
+ const dir = join(homedir(), ".sanqian", "runtime");
77
+ if (!existsSync(dir)) {
78
+ this.pollInterval = setInterval(() => {
79
+ if (existsSync(dir)) {
80
+ if (this.pollInterval) {
81
+ clearInterval(this.pollInterval);
82
+ this.pollInterval = null;
83
+ }
84
+ this.setupWatcher(dir);
87
85
  }
88
- }, 100);
86
+ }, 2e3);
87
+ return;
89
88
  }
90
- });
91
- } catch (e) {
92
- console.error("Failed to watch connection file:", e);
93
- }
94
- }
95
- /**
96
- * Stop watching
97
- */
98
- stopWatching() {
99
- if (this.pollInterval) {
100
- clearInterval(this.pollInterval);
101
- this.pollInterval = null;
102
- }
103
- this.watcher?.close();
104
- this.watcher = null;
105
- this.onChange = null;
106
- }
107
- /**
108
- * Check if a process is running by PID
109
- *
110
- * Cross-platform implementation:
111
- * - macOS/Linux: process.kill(pid, 0) works correctly
112
- * - Windows: process.kill(pid, 0) can give false positives due to PID reuse,
113
- * so we use tasklist command for reliable checking
114
- */
115
- isProcessRunning(pid) {
116
- try {
117
- if (platform() === "win32") {
89
+ this.setupWatcher(dir);
90
+ }
91
+ setupWatcher(dir) {
118
92
  try {
119
- const result = execSync(`tasklist /FI "PID eq ${pid}" /NH`, {
120
- encoding: "utf-8",
121
- stdio: ["pipe", "pipe", "pipe"]
93
+ this.watcher = watch(dir, (event, filename) => {
94
+ if (filename === "connection.json") {
95
+ setTimeout(() => {
96
+ const newInfo = this.read();
97
+ const oldInfoStr = JSON.stringify(this.connectionInfo);
98
+ const newInfoStr = JSON.stringify(newInfo);
99
+ if (oldInfoStr !== newInfoStr) {
100
+ this.connectionInfo = newInfo;
101
+ this.onChange?.(newInfo);
102
+ }
103
+ }, 100);
104
+ }
122
105
  });
123
- const trimmed = result.trim();
124
- if (!trimmed || trimmed.toUpperCase().startsWith("INFO")) {
125
- return false;
106
+ } catch (e) {
107
+ console.error("Failed to watch connection file:", e);
108
+ }
109
+ }
110
+ /**
111
+ * Stop watching
112
+ */
113
+ stopWatching() {
114
+ if (this.pollInterval) {
115
+ clearInterval(this.pollInterval);
116
+ this.pollInterval = null;
117
+ }
118
+ this.watcher?.close();
119
+ this.watcher = null;
120
+ this.onChange = null;
121
+ }
122
+ /**
123
+ * Check if a process is running by PID
124
+ *
125
+ * Cross-platform implementation:
126
+ * - macOS/Linux: process.kill(pid, 0) works correctly
127
+ * - Windows: process.kill(pid, 0) can give false positives due to PID reuse,
128
+ * so we use tasklist command for reliable checking
129
+ */
130
+ isProcessRunning(pid) {
131
+ try {
132
+ if (platform() === "win32") {
133
+ try {
134
+ const result = execSync(`tasklist /FI "PID eq ${pid}" /NH`, {
135
+ encoding: "utf-8",
136
+ stdio: ["pipe", "pipe", "pipe"]
137
+ });
138
+ const trimmed = result.trim();
139
+ if (!trimmed || trimmed.toUpperCase().startsWith("INFO")) {
140
+ return false;
141
+ }
142
+ return new RegExp(`\\b${pid}\\b`).test(trimmed);
143
+ } catch {
144
+ return false;
145
+ }
146
+ } else {
147
+ process.kill(pid, 0);
148
+ return true;
126
149
  }
127
- return new RegExp(`\\b${pid}\\b`).test(trimmed);
128
150
  } catch {
129
151
  return false;
130
152
  }
131
- } else {
132
- process.kill(pid, 0);
133
- return true;
134
153
  }
135
- } catch {
136
- return false;
137
- }
138
- }
139
- /**
140
- * Get cached connection info (may be stale)
141
- */
142
- getCached() {
143
- return this.connectionInfo;
144
- }
145
- /**
146
- * Build WebSocket URL from connection info
147
- */
148
- buildWebSocketUrl(info) {
149
- const wsPath = info.ws_path || "/ws/apps";
150
- return `ws://127.0.0.1:${info.port}${wsPath}?token=${info.token}`;
151
- }
152
- /**
153
- * Build HTTP base URL from connection info
154
- */
155
- buildHttpUrl(info) {
156
- return `http://127.0.0.1:${info.port}`;
157
- }
158
- /**
159
- * Find Sanqian executable path
160
- * Searches in standard installation locations for each platform
161
- */
162
- findSanqianPath(customPath) {
163
- if (customPath) {
164
- if (existsSync(customPath)) {
165
- return customPath;
154
+ /**
155
+ * Get cached connection info (may be stale)
156
+ */
157
+ getCached() {
158
+ return this.connectionInfo;
166
159
  }
167
- console.warn(`[SDK] Custom Sanqian path not found: ${customPath}`);
168
- return null;
169
- }
170
- const os = platform();
171
- const searchPaths = [];
172
- if (os === "darwin") {
173
- searchPaths.push(
174
- // Production: installed app
175
- "/Applications/Sanqian.app/Contents/MacOS/Sanqian",
176
- join(homedir(), "Applications/Sanqian.app/Contents/MacOS/Sanqian"),
177
- // Development: electron-builder output
178
- join(homedir(), "dev/sanqian/dist/mac-arm64/Sanqian.app/Contents/MacOS/Sanqian"),
179
- join(homedir(), "dev/sanqian/dist/mac/Sanqian.app/Contents/MacOS/Sanqian")
180
- );
181
- } else if (os === "win32") {
182
- const programFiles = process.env.PROGRAMFILES || "C:\\Program Files";
183
- const programFilesX86 = process.env["PROGRAMFILES(X86)"] || "C:\\Program Files (x86)";
184
- const localAppData = process.env.LOCALAPPDATA || join(homedir(), "AppData", "Local");
185
- searchPaths.push(
186
- // Production: NSIS installer uses lowercase directory name from package.json "name"
187
- join(localAppData, "Programs", "sanqian", "Sanqian.exe"),
188
- // Legacy/alternative paths with uppercase
189
- join(localAppData, "Programs", "Sanqian", "Sanqian.exe"),
190
- join(programFiles, "Sanqian", "Sanqian.exe"),
191
- join(programFilesX86, "Sanqian", "Sanqian.exe"),
192
- // Development: electron-builder output
193
- join(homedir(), "dev", "sanqian", "dist", "win-unpacked", "Sanqian.exe")
194
- );
195
- } else {
196
- searchPaths.push(
197
- "/usr/bin/sanqian",
198
- "/usr/local/bin/sanqian",
199
- join(homedir(), ".local/bin/sanqian"),
200
- "/opt/Sanqian/sanqian",
201
- // Development
202
- join(homedir(), "dev/sanqian/dist/linux-unpacked/sanqian")
203
- );
204
- }
205
- for (const path of searchPaths) {
206
- if (existsSync(path)) {
207
- return path;
160
+ /**
161
+ * Build WebSocket URL from connection info
162
+ */
163
+ buildWebSocketUrl(info) {
164
+ const wsPath = info.ws_path || "/ws/apps";
165
+ return `ws://127.0.0.1:${info.port}${wsPath}?token=${info.token}`;
208
166
  }
209
- }
210
- return null;
211
- }
212
- /**
213
- * Launch Sanqian in hidden/tray mode
214
- * Returns true if launch was initiated successfully
215
- *
216
- * Priority for finding Sanqian executable:
217
- * 1. customPath parameter (if provided)
218
- * 2. Cached executable from connection.json (most reliable)
219
- * 3. Search in standard installation locations (fallback)
220
- */
221
- launchSanqian(customPath) {
222
- let sanqianPath = null;
223
- if (customPath) {
224
- sanqianPath = this.findSanqianPath(customPath);
225
- } else if (this.cachedExecutable && existsSync(this.cachedExecutable)) {
226
- sanqianPath = this.cachedExecutable;
227
- console.log(`[SDK] Using cached executable: ${sanqianPath}`);
228
- } else {
229
- sanqianPath = this.findSanqianPath();
230
- }
231
- if (!sanqianPath) {
232
- console.error("[SDK] Sanqian executable not found");
233
- return false;
234
- }
235
- console.log(`[SDK] Launching Sanqian from: ${sanqianPath}`);
236
- try {
237
- const os = platform();
238
- if (os === "darwin") {
239
- const appPath = sanqianPath.replace(
240
- "/Contents/MacOS/Sanqian",
241
- ""
242
- );
243
- spawn("open", ["-g", "-a", appPath, "--args", "--hidden"], {
244
- detached: true,
245
- stdio: "ignore"
246
- }).unref();
247
- } else {
248
- spawn(sanqianPath, ["--hidden"], {
249
- detached: true,
250
- stdio: "ignore",
251
- // On Windows, hide the console window
252
- ...os === "win32" && {
253
- windowsHide: true,
254
- shell: false
167
+ /**
168
+ * Build HTTP base URL from connection info
169
+ */
170
+ buildHttpUrl(info) {
171
+ return `http://127.0.0.1:${info.port}`;
172
+ }
173
+ /**
174
+ * Find Sanqian executable path
175
+ * Searches in standard installation locations for each platform
176
+ */
177
+ findSanqianPath(customPath) {
178
+ if (customPath) {
179
+ if (existsSync(customPath)) {
180
+ return customPath;
255
181
  }
256
- }).unref();
182
+ console.warn(`[SDK] Custom Sanqian path not found: ${customPath}`);
183
+ return null;
184
+ }
185
+ const os = platform();
186
+ const searchPaths = [];
187
+ if (os === "darwin") {
188
+ searchPaths.push(
189
+ // Production: installed app
190
+ "/Applications/Sanqian.app/Contents/MacOS/Sanqian",
191
+ join(homedir(), "Applications/Sanqian.app/Contents/MacOS/Sanqian"),
192
+ // Development: electron-builder output
193
+ join(homedir(), "dev/sanqian/dist/mac-arm64/Sanqian.app/Contents/MacOS/Sanqian"),
194
+ join(homedir(), "dev/sanqian/dist/mac/Sanqian.app/Contents/MacOS/Sanqian")
195
+ );
196
+ } else if (os === "win32") {
197
+ const programFiles = process.env.PROGRAMFILES || "C:\\Program Files";
198
+ const programFilesX86 = process.env["PROGRAMFILES(X86)"] || "C:\\Program Files (x86)";
199
+ const localAppData = process.env.LOCALAPPDATA || join(homedir(), "AppData", "Local");
200
+ searchPaths.push(
201
+ // Production: NSIS installer uses lowercase directory name from package.json "name"
202
+ join(localAppData, "Programs", "sanqian", "Sanqian.exe"),
203
+ // Legacy/alternative paths with uppercase
204
+ join(localAppData, "Programs", "Sanqian", "Sanqian.exe"),
205
+ join(programFiles, "Sanqian", "Sanqian.exe"),
206
+ join(programFilesX86, "Sanqian", "Sanqian.exe"),
207
+ // Development: electron-builder output
208
+ join(homedir(), "dev", "sanqian", "dist", "win-unpacked", "Sanqian.exe")
209
+ );
210
+ } else {
211
+ searchPaths.push(
212
+ "/usr/bin/sanqian",
213
+ "/usr/local/bin/sanqian",
214
+ join(homedir(), ".local/bin/sanqian"),
215
+ "/opt/Sanqian/sanqian",
216
+ // Development
217
+ join(homedir(), "dev/sanqian/dist/linux-unpacked/sanqian")
218
+ );
219
+ }
220
+ for (const path of searchPaths) {
221
+ if (existsSync(path)) {
222
+ return path;
223
+ }
224
+ }
225
+ return null;
257
226
  }
258
- return true;
259
- } catch (e) {
260
- console.error("[SDK] Failed to launch Sanqian:", e);
261
- return false;
262
- }
263
- }
264
- /**
265
- * Check if Sanqian is running
266
- */
267
- isSanqianRunning() {
268
- return this.read() !== null;
227
+ /**
228
+ * Launch Sanqian in hidden/tray mode
229
+ * Returns true if launch was initiated successfully
230
+ *
231
+ * Priority for finding Sanqian executable:
232
+ * 1. customPath parameter (if provided)
233
+ * 2. Cached executable from connection.json (most reliable)
234
+ * 3. Search in standard installation locations (fallback)
235
+ */
236
+ launchSanqian(customPath) {
237
+ let sanqianPath = null;
238
+ if (customPath) {
239
+ sanqianPath = this.findSanqianPath(customPath);
240
+ } else if (this.cachedExecutable && existsSync(this.cachedExecutable)) {
241
+ sanqianPath = this.cachedExecutable;
242
+ console.log(`[SDK] Using cached executable: ${sanqianPath}`);
243
+ } else {
244
+ sanqianPath = this.findSanqianPath();
245
+ }
246
+ if (!sanqianPath) {
247
+ console.error("[SDK] Sanqian executable not found");
248
+ return false;
249
+ }
250
+ console.log(`[SDK] Launching Sanqian from: ${sanqianPath}`);
251
+ try {
252
+ const os = platform();
253
+ if (os === "darwin") {
254
+ const appPath = sanqianPath.replace(
255
+ "/Contents/MacOS/Sanqian",
256
+ ""
257
+ );
258
+ spawn("open", ["-g", "-a", appPath, "--args", "--hidden"], {
259
+ detached: true,
260
+ stdio: "ignore"
261
+ }).unref();
262
+ } else {
263
+ spawn(sanqianPath, ["--hidden"], {
264
+ detached: true,
265
+ stdio: "ignore",
266
+ // On Windows, hide the console window
267
+ ...os === "win32" && {
268
+ windowsHide: true,
269
+ shell: false
270
+ }
271
+ }).unref();
272
+ }
273
+ return true;
274
+ } catch (e) {
275
+ console.error("[SDK] Failed to launch Sanqian:", e);
276
+ return false;
277
+ }
278
+ }
279
+ /**
280
+ * Check if Sanqian is running
281
+ */
282
+ isSanqianRunning() {
283
+ return this.read() !== null;
284
+ }
285
+ };
269
286
  }
270
- };
287
+ });
288
+
289
+ // src/client.ts
290
+ import WebSocket from "isomorphic-ws";
271
291
 
272
292
  // src/errors.ts
273
293
  var SANQIAN_WEBSITE = "https://sanqian.io";
@@ -438,7 +458,8 @@ function createSDKError(code, details) {
438
458
  // src/client.ts
439
459
  var SanqianSDK = class _SanqianSDK {
440
460
  config;
441
- discovery;
461
+ // DiscoveryManager is only initialized in Node.js environments (when connectionInfo is not provided)
462
+ discovery = null;
442
463
  ws = null;
443
464
  connectionInfo = null;
444
465
  state = {
@@ -494,11 +515,10 @@ var SanqianSDK = class _SanqianSDK {
494
515
  autoLaunchSanqian: true,
495
516
  ...config
496
517
  };
497
- this.discovery = new DiscoveryManager();
498
518
  for (const tool of config.tools) {
499
519
  this.toolHandlers.set(tool.name, tool.handler);
500
520
  }
501
- this.launchedBySanqian = typeof process !== "undefined" && process.env?.SANQIAN_NO_RECONNECT === "1";
521
+ this.launchedBySanqian = typeof process !== "undefined" && (process.env?.SANQIAN_LAUNCHED === "1" || process.env?.SANQIAN_NO_RECONNECT === "1");
502
522
  if (this.launchedBySanqian) {
503
523
  this.log("Detected launch by Sanqian, will connect immediately without auto-reconnect");
504
524
  setTimeout(() => {
@@ -508,6 +528,26 @@ var SanqianSDK = class _SanqianSDK {
508
528
  }, 0);
509
529
  }
510
530
  }
531
+ /**
532
+ * Build WebSocket URL from connection info
533
+ * This is inlined to avoid importing DiscoveryManager in browser environments
534
+ */
535
+ buildWebSocketUrl(info) {
536
+ const wsPath = info.ws_path || "/ws/apps";
537
+ return `ws://127.0.0.1:${info.port}${wsPath}?token=${info.token}`;
538
+ }
539
+ /**
540
+ * Lazily initialize DiscoveryManager (only in Node.js environments)
541
+ * This uses dynamic import to avoid bundling Node.js APIs in browser builds
542
+ */
543
+ async getDiscovery() {
544
+ if (this.discovery) {
545
+ return this.discovery;
546
+ }
547
+ const { DiscoveryManager: DiscoveryManager2 } = await Promise.resolve().then(() => (init_discovery(), discovery_exports));
548
+ this.discovery = new DiscoveryManager2();
549
+ return this.discovery;
550
+ }
511
551
  // ============================================
512
552
  // Lifecycle
513
553
  // ============================================
@@ -531,7 +571,7 @@ var SanqianSDK = class _SanqianSDK {
531
571
  */
532
572
  async connectWithInfo(info) {
533
573
  this.connectionInfo = info;
534
- const url = this.discovery.buildWebSocketUrl(info);
574
+ const url = this.buildWebSocketUrl(info);
535
575
  return new Promise((resolve, reject) => {
536
576
  this.log(`Connecting to ${url}`);
537
577
  this.ws = new WebSocket(url);
@@ -581,7 +621,7 @@ var SanqianSDK = class _SanqianSDK {
581
621
  async disconnect() {
582
622
  this.stopHeartbeat();
583
623
  this.stopReconnect();
584
- this.discovery.stopWatching();
624
+ this.discovery?.stopWatching();
585
625
  if (this.ws) {
586
626
  this.ws.close(1e3, "Client disconnect");
587
627
  this.ws = null;
@@ -962,11 +1002,12 @@ var SanqianSDK = class _SanqianSDK {
962
1002
  this.log("Using pre-configured connection info (browser mode)");
963
1003
  info = this.config.connectionInfo;
964
1004
  } else {
965
- info = this.discovery.read();
1005
+ const discovery = await this.getDiscovery();
1006
+ info = discovery.read();
966
1007
  if (!info) {
967
1008
  if (this.config.autoLaunchSanqian) {
968
1009
  this.log("Sanqian not running, attempting to launch...");
969
- const launched = this.discovery.launchSanqian(this.config.sanqianPath);
1010
+ const launched = discovery.launchSanqian(this.config.sanqianPath);
970
1011
  if (!launched) {
971
1012
  throw createSDKError("NOT_INSTALLED" /* NOT_INSTALLED */);
972
1013
  }
@@ -985,8 +1026,9 @@ var SanqianSDK = class _SanqianSDK {
985
1026
  async waitForSanqianStartup(timeout = 12e4) {
986
1027
  const startTime = Date.now();
987
1028
  const pollInterval = 500;
1029
+ const discovery = await this.getDiscovery();
988
1030
  while (Date.now() - startTime < timeout) {
989
- const info = this.discovery.read();
1031
+ const info = discovery.read();
990
1032
  if (info) {
991
1033
  this.log("Sanqian started, connection info available");
992
1034
  return info;
@@ -1335,6 +1377,20 @@ var SanqianSDK = class _SanqianSDK {
1335
1377
  });
1336
1378
  return this.on(event, onceWrapper);
1337
1379
  }
1380
+ /**
1381
+ * Remove all event listeners
1382
+ *
1383
+ * Call this to prevent memory leaks when disposing the SDK instance.
1384
+ * If event is specified, only removes listeners for that event.
1385
+ */
1386
+ removeAllListeners(event) {
1387
+ if (event) {
1388
+ this.eventListeners.delete(event);
1389
+ } else {
1390
+ this.eventListeners.clear();
1391
+ }
1392
+ return this;
1393
+ }
1338
1394
  emit(event, ...args) {
1339
1395
  const listeners = this.eventListeners.get(event);
1340
1396
  if (listeners) {
@@ -1435,6 +1491,9 @@ var Conversation = class {
1435
1491
  });
1436
1492
  }
1437
1493
  };
1494
+
1495
+ // src/index.ts
1496
+ init_discovery();
1438
1497
  export {
1439
1498
  Conversation,
1440
1499
  DiscoveryManager,