aisnitch 0.2.3 → 0.2.4
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/README.md +312 -669
- package/dist/cli/index.cjs +210 -71
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +210 -71
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +198 -73
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -1
- package/dist/index.d.ts +13 -1
- package/dist/index.js +198 -73
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -81,10 +81,10 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
81
81
|
}, z.core.$strict>>;
|
|
82
82
|
idleTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
83
83
|
logLevel: z.ZodDefault<z.ZodEnum<{
|
|
84
|
-
error: "error";
|
|
85
84
|
debug: "debug";
|
|
86
85
|
info: "info";
|
|
87
86
|
warn: "warn";
|
|
87
|
+
error: "error";
|
|
88
88
|
}>>;
|
|
89
89
|
}, z.core.$strict>;
|
|
90
90
|
/**
|
|
@@ -948,10 +948,14 @@ declare class AdapterRegistry {
|
|
|
948
948
|
getStatus(): AdapterStatus[];
|
|
949
949
|
/**
|
|
950
950
|
* Starts every adapter enabled in the current AISnitch config.
|
|
951
|
+
* 📖 Each adapter is started independently — one failure does not prevent
|
|
952
|
+
* the others from starting.
|
|
951
953
|
*/
|
|
952
954
|
startAll(config: AISnitchConfig): Promise<void>;
|
|
953
955
|
/**
|
|
954
956
|
* Stops every adapter in reverse registration order.
|
|
957
|
+
* 📖 Each adapter is stopped independently — one failure does not prevent
|
|
958
|
+
* the others from being stopped.
|
|
955
959
|
*/
|
|
956
960
|
stopAll(): Promise<void>;
|
|
957
961
|
}
|
|
@@ -1615,8 +1619,15 @@ declare class Pipeline {
|
|
|
1615
1619
|
* Registers a future adapter-specific hook handler for one tool.
|
|
1616
1620
|
*/
|
|
1617
1621
|
registerHookHandler(tool: ToolName, handler: HookHandler): void;
|
|
1622
|
+
/**
|
|
1623
|
+
* 📖 Rolls back any components that were successfully started before a
|
|
1624
|
+
* failure occurred, preventing orphaned servers or leaking resources.
|
|
1625
|
+
*/
|
|
1626
|
+
private rollbackPartialStart;
|
|
1618
1627
|
/**
|
|
1619
1628
|
* Publishes an event after best-effort context enrichment.
|
|
1629
|
+
* 📖 If enrichment fails, the original event is published un-enriched
|
|
1630
|
+
* rather than being dropped entirely.
|
|
1620
1631
|
*/
|
|
1621
1632
|
publishEvent(event: AISnitchEvent, context?: ProcessContext): Promise<boolean>;
|
|
1622
1633
|
/**
|
|
@@ -1629,6 +1640,7 @@ declare class Pipeline {
|
|
|
1629
1640
|
getEventBus(): EventBus;
|
|
1630
1641
|
private getHealthSnapshot;
|
|
1631
1642
|
private handleHook;
|
|
1643
|
+
private handleHookInner;
|
|
1632
1644
|
private isPlainRecord;
|
|
1633
1645
|
}
|
|
1634
1646
|
|
package/dist/index.d.ts
CHANGED
|
@@ -81,10 +81,10 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
81
81
|
}, z.core.$strict>>;
|
|
82
82
|
idleTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
83
83
|
logLevel: z.ZodDefault<z.ZodEnum<{
|
|
84
|
-
error: "error";
|
|
85
84
|
debug: "debug";
|
|
86
85
|
info: "info";
|
|
87
86
|
warn: "warn";
|
|
87
|
+
error: "error";
|
|
88
88
|
}>>;
|
|
89
89
|
}, z.core.$strict>;
|
|
90
90
|
/**
|
|
@@ -948,10 +948,14 @@ declare class AdapterRegistry {
|
|
|
948
948
|
getStatus(): AdapterStatus[];
|
|
949
949
|
/**
|
|
950
950
|
* Starts every adapter enabled in the current AISnitch config.
|
|
951
|
+
* 📖 Each adapter is started independently — one failure does not prevent
|
|
952
|
+
* the others from starting.
|
|
951
953
|
*/
|
|
952
954
|
startAll(config: AISnitchConfig): Promise<void>;
|
|
953
955
|
/**
|
|
954
956
|
* Stops every adapter in reverse registration order.
|
|
957
|
+
* 📖 Each adapter is stopped independently — one failure does not prevent
|
|
958
|
+
* the others from being stopped.
|
|
955
959
|
*/
|
|
956
960
|
stopAll(): Promise<void>;
|
|
957
961
|
}
|
|
@@ -1615,8 +1619,15 @@ declare class Pipeline {
|
|
|
1615
1619
|
* Registers a future adapter-specific hook handler for one tool.
|
|
1616
1620
|
*/
|
|
1617
1621
|
registerHookHandler(tool: ToolName, handler: HookHandler): void;
|
|
1622
|
+
/**
|
|
1623
|
+
* 📖 Rolls back any components that were successfully started before a
|
|
1624
|
+
* failure occurred, preventing orphaned servers or leaking resources.
|
|
1625
|
+
*/
|
|
1626
|
+
private rollbackPartialStart;
|
|
1618
1627
|
/**
|
|
1619
1628
|
* Publishes an event after best-effort context enrichment.
|
|
1629
|
+
* 📖 If enrichment fails, the original event is published un-enriched
|
|
1630
|
+
* rather than being dropped entirely.
|
|
1620
1631
|
*/
|
|
1621
1632
|
publishEvent(event: AISnitchEvent, context?: ProcessContext): Promise<boolean>;
|
|
1622
1633
|
/**
|
|
@@ -1629,6 +1640,7 @@ declare class Pipeline {
|
|
|
1629
1640
|
getEventBus(): EventBus;
|
|
1630
1641
|
private getHealthSnapshot;
|
|
1631
1642
|
private handleHook;
|
|
1643
|
+
private handleHookInner;
|
|
1632
1644
|
private isPlainRecord;
|
|
1633
1645
|
}
|
|
1634
1646
|
|
package/dist/index.js
CHANGED
|
@@ -346,15 +346,24 @@ var BaseAdapter = class {
|
|
|
346
346
|
cwd: data.cwd ?? context.cwd
|
|
347
347
|
}
|
|
348
348
|
});
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
349
|
+
let published;
|
|
350
|
+
try {
|
|
351
|
+
published = await this.publishEventImplementation(event, {
|
|
352
|
+
cwd: context.cwd,
|
|
353
|
+
env: context.env,
|
|
354
|
+
hookPayload: context.hookPayload,
|
|
355
|
+
pid: context.pid,
|
|
356
|
+
sessionId,
|
|
357
|
+
source: context.source,
|
|
358
|
+
transcriptPath: context.transcriptPath
|
|
359
|
+
});
|
|
360
|
+
} catch (error) {
|
|
361
|
+
logger.error(
|
|
362
|
+
{ error, eventType: type, adapter: this.name, sessionId },
|
|
363
|
+
"\u{1F4D6} Failed to publish event \u2014 swallowing to prevent daemon crash"
|
|
364
|
+
);
|
|
365
|
+
published = false;
|
|
366
|
+
}
|
|
358
367
|
if (published) {
|
|
359
368
|
this.eventsEmitted += 1;
|
|
360
369
|
}
|
|
@@ -5482,22 +5491,40 @@ var AdapterRegistry = class {
|
|
|
5482
5491
|
}
|
|
5483
5492
|
/**
|
|
5484
5493
|
* Starts every adapter enabled in the current AISnitch config.
|
|
5494
|
+
* 📖 Each adapter is started independently — one failure does not prevent
|
|
5495
|
+
* the others from starting.
|
|
5485
5496
|
*/
|
|
5486
5497
|
async startAll(config) {
|
|
5487
5498
|
for (const adapter of this.list()) {
|
|
5488
5499
|
if (config.adapters[adapter.name]?.enabled !== true) {
|
|
5489
5500
|
continue;
|
|
5490
5501
|
}
|
|
5491
|
-
|
|
5502
|
+
try {
|
|
5503
|
+
await adapter.start();
|
|
5504
|
+
} catch (error) {
|
|
5505
|
+
logger.error(
|
|
5506
|
+
{ error, adapter: adapter.name },
|
|
5507
|
+
`\u{1F4D6} Failed to start adapter "${adapter.name}" \u2014 skipping`
|
|
5508
|
+
);
|
|
5509
|
+
}
|
|
5492
5510
|
}
|
|
5493
5511
|
}
|
|
5494
5512
|
/**
|
|
5495
5513
|
* Stops every adapter in reverse registration order.
|
|
5514
|
+
* 📖 Each adapter is stopped independently — one failure does not prevent
|
|
5515
|
+
* the others from being stopped.
|
|
5496
5516
|
*/
|
|
5497
5517
|
async stopAll() {
|
|
5498
5518
|
const adapters = this.list().reverse();
|
|
5499
5519
|
for (const adapter of adapters) {
|
|
5500
|
-
|
|
5520
|
+
try {
|
|
5521
|
+
await adapter.stop();
|
|
5522
|
+
} catch (error) {
|
|
5523
|
+
logger.warn(
|
|
5524
|
+
{ error, adapter: adapter.name },
|
|
5525
|
+
`\u{1F4D6} Error stopping adapter "${adapter.name}" \u2014 continuing`
|
|
5526
|
+
);
|
|
5527
|
+
}
|
|
5501
5528
|
}
|
|
5502
5529
|
}
|
|
5503
5530
|
};
|
|
@@ -6460,8 +6487,16 @@ var EventBus = class {
|
|
|
6460
6487
|
},
|
|
6461
6488
|
"Published event"
|
|
6462
6489
|
);
|
|
6463
|
-
|
|
6464
|
-
|
|
6490
|
+
try {
|
|
6491
|
+
this.emitter.emit("event", parsedEvent.data);
|
|
6492
|
+
} catch (error) {
|
|
6493
|
+
logger.warn({ error, eventType: parsedEvent.data.type }, "\u{1F4D6} Error in EventBus global subscriber");
|
|
6494
|
+
}
|
|
6495
|
+
try {
|
|
6496
|
+
this.emitter.emit(`event:${parsedEvent.data.type}`, parsedEvent.data);
|
|
6497
|
+
} catch (error) {
|
|
6498
|
+
logger.warn({ error, eventType: parsedEvent.data.type }, "\u{1F4D6} Error in EventBus typed subscriber");
|
|
6499
|
+
}
|
|
6465
6500
|
return true;
|
|
6466
6501
|
}
|
|
6467
6502
|
/**
|
|
@@ -6742,6 +6777,7 @@ var WSServer = class {
|
|
|
6742
6777
|
});
|
|
6743
6778
|
socket.on("error", (error) => {
|
|
6744
6779
|
logger.warn({ error }, "WebSocket consumer error");
|
|
6780
|
+
this.consumers.delete(socket);
|
|
6745
6781
|
});
|
|
6746
6782
|
const welcomeMessage = {
|
|
6747
6783
|
type: "welcome",
|
|
@@ -6898,10 +6934,17 @@ var HTTPReceiver = class {
|
|
|
6898
6934
|
}
|
|
6899
6935
|
async handleRequest(request, response, options) {
|
|
6900
6936
|
this.requestCount += 1;
|
|
6901
|
-
|
|
6902
|
-
|
|
6903
|
-
|
|
6904
|
-
|
|
6937
|
+
let requestUrl;
|
|
6938
|
+
try {
|
|
6939
|
+
requestUrl = new URL(
|
|
6940
|
+
request.url ?? "/",
|
|
6941
|
+
`http://${this.host}:${this.port ?? options.port}`
|
|
6942
|
+
);
|
|
6943
|
+
} catch {
|
|
6944
|
+
this.invalidRequestCount += 1;
|
|
6945
|
+
this.sendJson(response, 400, { error: "malformed request url" });
|
|
6946
|
+
return;
|
|
6947
|
+
}
|
|
6905
6948
|
if (request.method === "GET" && requestUrl.pathname === "/health") {
|
|
6906
6949
|
this.sendJson(response, 200, options.getHealthSnapshot());
|
|
6907
6950
|
return;
|
|
@@ -7246,26 +7289,32 @@ var Pipeline = class {
|
|
|
7246
7289
|
await adapter.handleHook(payload);
|
|
7247
7290
|
});
|
|
7248
7291
|
}
|
|
7292
|
+
try {
|
|
7293
|
+
this.wsPort = await this.wsServer.start({
|
|
7294
|
+
port: resolvedWsPort,
|
|
7295
|
+
eventBus: this.eventBus,
|
|
7296
|
+
activeTools
|
|
7297
|
+
});
|
|
7298
|
+
this.httpPort = await this.httpReceiver.start({
|
|
7299
|
+
port: resolvedHttpPort,
|
|
7300
|
+
onHook: async (tool, payload) => {
|
|
7301
|
+
await this.handleHook(tool, payload);
|
|
7302
|
+
},
|
|
7303
|
+
getHealthSnapshot: () => this.getHealthSnapshot()
|
|
7304
|
+
});
|
|
7305
|
+
this.socketPath = await this.udsServer.start({
|
|
7306
|
+
socketPath,
|
|
7307
|
+
onEvent: async (event) => {
|
|
7308
|
+
await this.publishEvent(event);
|
|
7309
|
+
}
|
|
7310
|
+
});
|
|
7311
|
+
await this.adapterRegistry.startAll(config);
|
|
7312
|
+
} catch (error) {
|
|
7313
|
+
logger.error({ error }, "\u{1F4D6} Pipeline start failed \u2014 rolling back already-started components");
|
|
7314
|
+
await this.rollbackPartialStart();
|
|
7315
|
+
throw error;
|
|
7316
|
+
}
|
|
7249
7317
|
this.startedAt = Date.now();
|
|
7250
|
-
this.wsPort = await this.wsServer.start({
|
|
7251
|
-
port: resolvedWsPort,
|
|
7252
|
-
eventBus: this.eventBus,
|
|
7253
|
-
activeTools
|
|
7254
|
-
});
|
|
7255
|
-
this.httpPort = await this.httpReceiver.start({
|
|
7256
|
-
port: resolvedHttpPort,
|
|
7257
|
-
onHook: async (tool, payload) => {
|
|
7258
|
-
await this.handleHook(tool, payload);
|
|
7259
|
-
},
|
|
7260
|
-
getHealthSnapshot: () => this.getHealthSnapshot()
|
|
7261
|
-
});
|
|
7262
|
-
this.socketPath = await this.udsServer.start({
|
|
7263
|
-
socketPath,
|
|
7264
|
-
onEvent: async (event) => {
|
|
7265
|
-
await this.publishEvent(event);
|
|
7266
|
-
}
|
|
7267
|
-
});
|
|
7268
|
-
await this.adapterRegistry.startAll(config);
|
|
7269
7318
|
logger.info(this.getStatus(), "Core pipeline started");
|
|
7270
7319
|
return this.getStatus();
|
|
7271
7320
|
}
|
|
@@ -7273,10 +7322,25 @@ var Pipeline = class {
|
|
|
7273
7322
|
* Stops every pipeline component in reverse dependency order.
|
|
7274
7323
|
*/
|
|
7275
7324
|
async stop() {
|
|
7276
|
-
|
|
7277
|
-
|
|
7278
|
-
|
|
7279
|
-
|
|
7325
|
+
const stopSafely = async (label, fn) => {
|
|
7326
|
+
try {
|
|
7327
|
+
await fn();
|
|
7328
|
+
} catch (error) {
|
|
7329
|
+
logger.warn({ error }, `\u{1F4D6} Error while stopping ${label} \u2014 continuing shutdown`);
|
|
7330
|
+
}
|
|
7331
|
+
};
|
|
7332
|
+
await stopSafely("adapter registry", async () => {
|
|
7333
|
+
await this.adapterRegistry?.stopAll();
|
|
7334
|
+
});
|
|
7335
|
+
await stopSafely("HTTP receiver", async () => {
|
|
7336
|
+
await this.httpReceiver.stop();
|
|
7337
|
+
});
|
|
7338
|
+
await stopSafely("UDS server", async () => {
|
|
7339
|
+
await this.udsServer.stop();
|
|
7340
|
+
});
|
|
7341
|
+
await stopSafely("WebSocket server", async () => {
|
|
7342
|
+
await this.wsServer.stop();
|
|
7343
|
+
});
|
|
7280
7344
|
this.eventBus.unsubscribeAll();
|
|
7281
7345
|
this.adapterRegistry = null;
|
|
7282
7346
|
this.enabledTools.clear();
|
|
@@ -7293,11 +7357,50 @@ var Pipeline = class {
|
|
|
7293
7357
|
registerHookHandler(tool, handler) {
|
|
7294
7358
|
this.hookHandlers.set(tool, handler);
|
|
7295
7359
|
}
|
|
7360
|
+
/**
|
|
7361
|
+
* 📖 Rolls back any components that were successfully started before a
|
|
7362
|
+
* failure occurred, preventing orphaned servers or leaking resources.
|
|
7363
|
+
*/
|
|
7364
|
+
async rollbackPartialStart() {
|
|
7365
|
+
const stopSafe = async (label, fn) => {
|
|
7366
|
+
try {
|
|
7367
|
+
await fn();
|
|
7368
|
+
} catch (error) {
|
|
7369
|
+
logger.warn({ error }, `\u{1F4D6} Error rolling back ${label}`);
|
|
7370
|
+
}
|
|
7371
|
+
};
|
|
7372
|
+
await stopSafe("adapter registry", async () => {
|
|
7373
|
+
await this.adapterRegistry?.stopAll();
|
|
7374
|
+
});
|
|
7375
|
+
await stopSafe("UDS server", async () => {
|
|
7376
|
+
await this.udsServer.stop();
|
|
7377
|
+
});
|
|
7378
|
+
await stopSafe("HTTP receiver", async () => {
|
|
7379
|
+
await this.httpReceiver.stop();
|
|
7380
|
+
});
|
|
7381
|
+
await stopSafe("WebSocket server", async () => {
|
|
7382
|
+
await this.wsServer.stop();
|
|
7383
|
+
});
|
|
7384
|
+
this.adapterRegistry = null;
|
|
7385
|
+
this.enabledTools.clear();
|
|
7386
|
+
this.hookHandlers.clear();
|
|
7387
|
+
}
|
|
7296
7388
|
/**
|
|
7297
7389
|
* Publishes an event after best-effort context enrichment.
|
|
7390
|
+
* 📖 If enrichment fails, the original event is published un-enriched
|
|
7391
|
+
* rather than being dropped entirely.
|
|
7298
7392
|
*/
|
|
7299
7393
|
async publishEvent(event, context = {}) {
|
|
7300
|
-
|
|
7394
|
+
let enrichedEvent;
|
|
7395
|
+
try {
|
|
7396
|
+
enrichedEvent = await this.contextDetector.enrich(event, context);
|
|
7397
|
+
} catch (error) {
|
|
7398
|
+
logger.warn(
|
|
7399
|
+
{ error, eventId: event.id },
|
|
7400
|
+
"\u{1F4D6} Context enrichment failed \u2014 publishing un-enriched event"
|
|
7401
|
+
);
|
|
7402
|
+
enrichedEvent = event;
|
|
7403
|
+
}
|
|
7301
7404
|
return this.eventBus.publish(enrichedEvent);
|
|
7302
7405
|
}
|
|
7303
7406
|
/**
|
|
@@ -7333,6 +7436,16 @@ var Pipeline = class {
|
|
|
7333
7436
|
};
|
|
7334
7437
|
}
|
|
7335
7438
|
async handleHook(tool, payload) {
|
|
7439
|
+
try {
|
|
7440
|
+
await this.handleHookInner(tool, payload);
|
|
7441
|
+
} catch (error) {
|
|
7442
|
+
logger.error(
|
|
7443
|
+
{ error, tool },
|
|
7444
|
+
"\u{1F4D6} Unhandled error in hook handler \u2014 swallowing to prevent daemon crash"
|
|
7445
|
+
);
|
|
7446
|
+
}
|
|
7447
|
+
}
|
|
7448
|
+
async handleHookInner(tool, payload) {
|
|
7336
7449
|
if (!this.enabledTools.has(tool)) {
|
|
7337
7450
|
logger.debug({ tool }, "Ignoring hook for disabled tool");
|
|
7338
7451
|
return;
|
|
@@ -8508,18 +8621,22 @@ function parseSocketPayload(data) {
|
|
|
8508
8621
|
return parsedEvent.success ? parsedEvent.data : null;
|
|
8509
8622
|
}
|
|
8510
8623
|
function parseUnknownPayload(data) {
|
|
8511
|
-
|
|
8512
|
-
|
|
8513
|
-
|
|
8514
|
-
|
|
8515
|
-
|
|
8516
|
-
|
|
8517
|
-
|
|
8518
|
-
|
|
8519
|
-
|
|
8520
|
-
|
|
8624
|
+
try {
|
|
8625
|
+
if (typeof data === "string") {
|
|
8626
|
+
return JSON.parse(data);
|
|
8627
|
+
}
|
|
8628
|
+
if (Array.isArray(data)) {
|
|
8629
|
+
return JSON.parse(Buffer.concat(data).toString("utf8"));
|
|
8630
|
+
}
|
|
8631
|
+
if (data instanceof ArrayBuffer) {
|
|
8632
|
+
return JSON.parse(
|
|
8633
|
+
Buffer.from(new Uint8Array(data)).toString("utf8")
|
|
8634
|
+
);
|
|
8635
|
+
}
|
|
8636
|
+
return JSON.parse(Buffer.from(data).toString("utf8"));
|
|
8637
|
+
} catch {
|
|
8638
|
+
return null;
|
|
8521
8639
|
}
|
|
8522
|
-
return JSON.parse(Buffer.from(data).toString("utf8"));
|
|
8523
8640
|
}
|
|
8524
8641
|
|
|
8525
8642
|
// src/tui/hooks/useKeyBinds.ts
|
|
@@ -9247,16 +9364,20 @@ function ManagedDaemonApp({
|
|
|
9247
9364
|
}
|
|
9248
9365
|
function parseSocketPayload2(data) {
|
|
9249
9366
|
let parsedPayload;
|
|
9250
|
-
|
|
9251
|
-
|
|
9252
|
-
|
|
9253
|
-
|
|
9254
|
-
|
|
9255
|
-
|
|
9256
|
-
|
|
9257
|
-
|
|
9258
|
-
|
|
9259
|
-
|
|
9367
|
+
try {
|
|
9368
|
+
if (typeof data === "string") {
|
|
9369
|
+
parsedPayload = JSON.parse(data);
|
|
9370
|
+
} else if (Array.isArray(data)) {
|
|
9371
|
+
parsedPayload = JSON.parse(Buffer.concat(data).toString("utf8"));
|
|
9372
|
+
} else if (data instanceof ArrayBuffer) {
|
|
9373
|
+
parsedPayload = JSON.parse(
|
|
9374
|
+
Buffer.from(new Uint8Array(data)).toString("utf8")
|
|
9375
|
+
);
|
|
9376
|
+
} else {
|
|
9377
|
+
parsedPayload = JSON.parse(Buffer.from(data).toString("utf8"));
|
|
9378
|
+
}
|
|
9379
|
+
} catch {
|
|
9380
|
+
return null;
|
|
9260
9381
|
}
|
|
9261
9382
|
if (typeof parsedPayload === "object" && parsedPayload !== null && "type" in parsedPayload && parsedPayload.type === "welcome") {
|
|
9262
9383
|
return null;
|
|
@@ -9327,18 +9448,22 @@ async function attachWebSocketMonitor(url, output) {
|
|
|
9327
9448
|
};
|
|
9328
9449
|
}
|
|
9329
9450
|
function parseSocketMessage(data) {
|
|
9330
|
-
|
|
9331
|
-
|
|
9332
|
-
|
|
9333
|
-
|
|
9334
|
-
|
|
9335
|
-
|
|
9336
|
-
|
|
9337
|
-
|
|
9338
|
-
|
|
9339
|
-
|
|
9451
|
+
try {
|
|
9452
|
+
if (typeof data === "string") {
|
|
9453
|
+
return JSON.parse(data);
|
|
9454
|
+
}
|
|
9455
|
+
if (Array.isArray(data)) {
|
|
9456
|
+
return JSON.parse(Buffer.concat(data).toString("utf8"));
|
|
9457
|
+
}
|
|
9458
|
+
if (data instanceof ArrayBuffer) {
|
|
9459
|
+
return JSON.parse(
|
|
9460
|
+
Buffer.from(new Uint8Array(data)).toString("utf8")
|
|
9461
|
+
);
|
|
9462
|
+
}
|
|
9463
|
+
return JSON.parse(Buffer.from(data).toString("utf8"));
|
|
9464
|
+
} catch {
|
|
9465
|
+
return null;
|
|
9340
9466
|
}
|
|
9341
|
-
return JSON.parse(Buffer.from(data).toString("utf8"));
|
|
9342
9467
|
}
|
|
9343
9468
|
function isWelcomeMessage(payload) {
|
|
9344
9469
|
if (typeof payload !== "object" || payload === null) {
|