@interactive-inc/claude-funnel 0.66.0 → 0.68.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/README.md +31 -6
- package/dist/bin.js +292 -383
- package/dist/channel.d.ts +76 -52
- package/dist/channel.js +82 -47
- package/dist/{channels-DR90RmUP.d.ts → channels-B0cifCfw.d.ts} +6 -6
- package/dist/claude.d.ts +11 -8
- package/dist/claude.js +31 -15
- package/dist/connector-descriptor-D4XtEsH8.d.ts +215 -0
- package/dist/{connector-diagnostics-recorder-COtNEmUp.js → connector-diagnostics-recorder-BmOijU1p.js} +1 -0
- package/dist/connectors/discord.d.ts +11 -8
- package/dist/connectors/discord.js +2 -2
- package/dist/connectors/gh.d.ts +7 -6
- package/dist/connectors/gh.js +2 -2
- package/dist/connectors/schedule.d.ts +21 -17
- package/dist/connectors/schedule.js +3 -3
- package/dist/connectors/slack.d.ts +15 -10
- package/dist/connectors/slack.js +3 -3
- package/dist/diagnostic-event-CxMM5Bl2.js +78 -0
- package/dist/diagnostic-log-BsAg5qZK.d.ts +186 -0
- package/dist/diagnostics.d.ts +2 -2
- package/dist/diagnostics.js +3 -2
- package/dist/{discord-connector-DXARcO6w.js → discord-connector-CAcWifJn.js} +6 -6
- package/dist/{discord-connector-schema-D1dyxhXk.d.ts → discord-connector-schema-BaBZYHxK.d.ts} +0 -1
- package/dist/docs.d.ts +1 -1
- package/dist/docs.js +1 -1
- package/dist/doctor.d.ts +1 -1
- package/dist/doctor.js +1 -1
- package/dist/event-log.d.ts +2 -0
- package/dist/event-log.js +3 -0
- package/dist/{file-process-guard-CiBwXjzm.d.ts → file-process-guard-D-QatrwL.d.ts} +22 -18
- package/dist/{file-system-DHgbuTFb.d.ts → file-system-BNtl997T.d.ts} +2 -1
- package/dist/{flume-source-listener-FzR5lGpL.d.ts → flume-source-listener-Ba8_1Mg-.d.ts} +9 -6
- package/dist/{funnel-diagnostics-Cvk6Sk4x.js → funnel-diagnostics-CAG7hJP0.js} +85 -141
- package/dist/{funnel-diagnostics-kbd27d7I.d.ts → funnel-diagnostics-CDrZznTB.d.ts} +18 -18
- package/dist/{funnel-docs-C-ge0MuB.js → funnel-docs-CI4hMkhq.js} +12 -3
- package/dist/{funnel-doctor-CVTNUtDn.d.ts → funnel-doctor-CY4S5cnz.d.ts} +20 -9
- package/dist/{funnel-doctor-XrI2GBH8.js → funnel-doctor-Csw5qjcH.js} +1 -0
- package/dist/{funnel-error-0t1MK1R6.js → funnel-error-DoSBCogD.js} +13 -0
- package/dist/{funnel-recovery-D8MkiTpk.d.ts → funnel-recovery-BwcSNNSN.d.ts} +1 -2
- package/dist/{funnel-recovery-DKnEutUS.js → funnel-recovery-DYbSYGWC.js} +1 -0
- package/dist/gateway/daemon.js +60 -139
- package/dist/gateway.d.ts +2 -3
- package/dist/gateway.js +2 -2
- package/dist/{gh-connector-BUGCOEWS.js → gh-connector-DMwI6zJA.js} +5 -5
- package/dist/{gh-connector-schema-BCHEqpUg.d.ts → gh-connector-schema-BrNsCl1T.d.ts} +0 -1
- package/dist/{index-BU1TtuFy.d.ts → index-fHrKn4jm.d.ts} +210 -40
- package/dist/index.d.ts +125 -115
- package/dist/index.js +242 -57
- package/dist/{local-config-json-schema-DexV8vX3.js → local-config-json-schema-_-YVHX4c.js} +4 -4
- package/dist/local-config.d.ts +2 -3
- package/dist/local-config.js +1 -1
- package/dist/logger.d.ts +17 -265
- package/dist/logger.js +6 -141
- package/dist/memory-event-log-BY8XjFzi.js +147 -0
- package/dist/{memory-token-prompter-D0kIdhar.d.ts → memory-token-prompter-B20tl_aU.d.ts} +2 -3
- package/dist/{node-file-system-BOXIHW_Q.js → node-file-system-xJx7dymE.js} +11 -3
- package/dist/{profiles-M24JrcOh.d.ts → profiles-CePRnv3F.d.ts} +3 -4
- package/dist/{profiles-ZHLONml4.js → profiles-KpN7_gBw.js} +19 -5
- package/dist/profiles.d.ts +1 -1
- package/dist/profiles.js +1 -1
- package/dist/recovery.d.ts +1 -1
- package/dist/recovery.js +1 -1
- package/dist/{schedule-connector-9k3gOIgl.js → schedule-connector-BXUOYgwZ.js} +63 -99
- package/dist/schedule-connector-schema-CNV8PgWX.js +137 -0
- package/dist/schedule-connector-schema-Tq5kJul-.d.ts +127 -0
- package/dist/{settings-reader-BnKIbmsD.d.ts → settings-reader-CyTpbAre.d.ts} +1 -2
- package/dist/{settings-schema-IShSMm5G.d.ts → settings-schema-B-CKLuST.d.ts} +0 -1
- package/dist/{settings-store-ccv291GV.js → settings-store-ZFWBhOnp.js} +12 -3
- package/dist/{slack-connector-CxpWagbT.js → slack-connector-CC3V2VXQ.js} +10 -9
- package/dist/{slack-event-processor-xFDG3US0.js → slack-event-processor-Cs_YuI3w.js} +2 -2
- package/dist/{slack-event-processor-BDTr62cN.d.ts → slack-event-processor-DmAlq4cV.d.ts} +0 -1
- package/dist/{slot-fields-D-pvMgTK.js → slot-fields-eCWizJqS.js} +4 -4
- package/dist/{sqlite-diagnostic-log-CwhXE9Qh.js → sqlite-diagnostic-log-Qs4cf9I_.js} +92 -100
- package/dist/sqlite-event-log-BYgCFMxC.d.ts +284 -0
- package/dist/{funnel-log-sqlite-sink-DLYkY0pZ.js → sqlite-event-log-eZuXKszJ.js} +53 -12
- package/dist/{yaml-render-DVEtYuF1.js → yaml-render-DxxRQT-V.js} +3 -3
- package/package.json +25 -10
- package/dist/broadcaster-DVNcw00K.d.ts +0 -138
- package/dist/connector-descriptor-CmyHlEiT.d.ts +0 -380
- package/dist/diagnostic-sql-reader-oXZnWFf_.js +0 -83
- package/dist/file-system-Wvzc2ePY.js +0 -9
- package/dist/logger-B6iyNbxM.js +0 -9
- package/dist/schedule-connector-schema-D7ZEKvit.d.ts +0 -49
- package/dist/schedule-connector-schema-DKEPZnVv.js +0 -31
- package/dist/settings-reader-9FcX3qS1.js +0 -11
- /package/dist/{connector-adapter-Dvs8N7ew.js → connector-adapter-BL2ehMej.js} +0 -0
- /package/dist/{connector-listener-mPGZYa8e.js → connector-listener-BcQMzY6Q.js} +0 -0
- /package/dist/{discord-connector-schema-B4YpWpR3.js → discord-connector-schema-saAGuPmJ.js} +0 -0
- /package/dist/{error-message-of-ColuYmAk.js → error-message-of-BG4ezZ_s.js} +0 -0
- /package/dist/{funnel-docs-Cd66sKyV.d.ts → funnel-docs-BJWawfWI.d.ts} +0 -0
- /package/dist/{gh-connector-schema-CAqIhzGr.js → gh-connector-schema-DmZTrzUu.js} +0 -0
- /package/dist/{logger-Bc_Ooypb.d.ts → logger-mMZvblTx.d.ts} +0 -0
- /package/dist/{loopback-fetch-CVNuN3YZ.js → loopback-fetch-HP-bo9Kv.js} +0 -0
- /package/dist/{node-http-client-u00atiKx.js → node-http-client-SX3xFh4h.js} +0 -0
- /package/dist/{node-process-runner-DxTvycoK.js → node-process-runner-D4rzPl8Q.js} +0 -0
- /package/dist/{resolve-connector-token-DxDG9mhf.js → resolve-connector-token-BwiJCu82.js} +0 -0
- /package/dist/{slack-connector-schema-Dem8to4P.js → slack-connector-schema-EGVuuqSX.js} +0 -0
package/dist/gateway.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { i as
|
|
2
|
-
import { C as
|
|
3
|
-
import { C as funnelEventSchema, D as FunnelListenerRegistry, E as GatewayRouteDeps, S as FunnelEventRecord, T as GatewayEmitInput, _ as channelWsUrl, a as SqliteFunnelEventLog, b as FunnelEvent, c as PublishResponse, d as publishResponseSchema, f as DEFAULT_GATEWAY_TOKEN_PATH, g as channelWsProtocols, h as ChannelWsUrlInput, i as MemoryFunnelEventLog, l as PublishResult, m as gatewayLoopbackUrl, n as MemoryConnectorDiagnosticLog, o as FunnelChannelPublisher, p as FunnelGatewayToken, r as SqliteConnectorDiagnosticLog, s as PublishRequest, t as GatewayApp, u as publishRequestSchema, v as FunnelGatewayServer, w as Env, x as FunnelEventLog, y as GatewayEventStore } from "./index-BU1TtuFy.js";
|
|
1
|
+
import { _ as connectorConnectionEventSchema, a as ConnectorConnectionStatus, c as ConnectorProcessedQuery, d as ConnectorRawEvent, f as ConnectorRawQuery, g as StoredRawEvent, h as StoredProcessedEvent, i as ConnectorConnectionRecord, l as ConnectorProcessedRecord, m as StoredConnectionEvent, n as ConnectorConnectionEvent, o as ConnectorDiagnosticLog, p as ConnectorRawRecord, r as ConnectorConnectionQuery, s as ConnectorProcessedEvent, t as CONNECTOR_CONNECTION_STATUSES, u as ConnectorQuery, v as connectorProcessedEventSchema, y as connectorRawEventSchema } from "./diagnostic-log-BsAg5qZK.js";
|
|
2
|
+
import { A as FunnelBroadcaster, C as funnelEventSchema, D as FunnelListenerRegistry, E as GatewayRouteDeps, O as BroadcastEvent, S as FunnelEventRecord, T as GatewayEmitInput, _ as channelWsUrl, a as SqliteFunnelEventLog, b as FunnelEvent, c as PublishResponse, d as publishResponseSchema, f as DEFAULT_GATEWAY_TOKEN_PATH, g as channelWsProtocols, h as ChannelWsUrlInput, i as MemoryFunnelEventLog, j as ReplayableEvent, k as BroadcastSubscriber, l as PublishResult, m as gatewayLoopbackUrl, n as MemoryConnectorDiagnosticLog, o as FunnelChannelPublisher, p as FunnelGatewayToken, r as SqliteConnectorDiagnosticLog, s as PublishRequest, t as GatewayApp, u as publishRequestSchema, v as FunnelGatewayServer, w as Env, x as FunnelEventLog, y as GatewayEventStore } from "./index-fHrKn4jm.js";
|
|
4
3
|
export { BroadcastEvent, BroadcastSubscriber, CONNECTOR_CONNECTION_STATUSES, ChannelWsUrlInput, ConnectorConnectionEvent, ConnectorConnectionQuery, ConnectorConnectionRecord, ConnectorConnectionStatus, ConnectorDiagnosticLog, ConnectorProcessedEvent, ConnectorProcessedQuery, ConnectorProcessedRecord, ConnectorQuery, ConnectorRawEvent, ConnectorRawQuery, ConnectorRawRecord, DEFAULT_GATEWAY_TOKEN_PATH, FunnelBroadcaster, FunnelChannelPublisher, FunnelEvent, FunnelEventLog, FunnelEventRecord, FunnelGatewayServer, FunnelGatewayToken, FunnelListenerRegistry, type GatewayApp, type GatewayEmitInput, GatewayEventStore, type GatewayRouteDeps, type Env as GatewayServerEnv, MemoryConnectorDiagnosticLog, MemoryFunnelEventLog, PublishRequest, PublishResponse, PublishResult, ReplayableEvent, SqliteConnectorDiagnosticLog, SqliteFunnelEventLog, StoredConnectionEvent, StoredProcessedEvent, StoredRawEvent, channelWsProtocols, channelWsUrl, connectorConnectionEventSchema, connectorProcessedEventSchema, connectorRawEventSchema, funnelEventSchema, gatewayLoopbackUrl, publishRequestSchema, publishResponseSchema };
|
package/dist/gateway.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as gatewayLoopbackUrl } from "./loopback-fetch-
|
|
2
|
-
import { S as connectorRawEventSchema, _ as MemoryConnectorDiagnosticLog, a as DEFAULT_GATEWAY_TOKEN_PATH, b as connectorConnectionEventSchema, c as FunnelListenerRegistry, d as funnelEventSchema, f as FunnelBroadcaster, g as publishResponseSchema, h as publishRequestSchema, i as channelWsUrl, l as SqliteFunnelEventLog, m as FunnelChannelPublisher, n as MemoryFunnelEventLog, o as FunnelGatewayToken, r as channelWsProtocols, s as FunnelGatewayServer, t as SqliteConnectorDiagnosticLog, u as FunnelEventLog, v as CONNECTOR_CONNECTION_STATUSES, x as connectorProcessedEventSchema, y as ConnectorDiagnosticLog } from "./sqlite-diagnostic-log-
|
|
1
|
+
import { n as gatewayLoopbackUrl } from "./loopback-fetch-HP-bo9Kv.js";
|
|
2
|
+
import { S as connectorRawEventSchema, _ as MemoryConnectorDiagnosticLog, a as DEFAULT_GATEWAY_TOKEN_PATH, b as connectorConnectionEventSchema, c as FunnelListenerRegistry, d as funnelEventSchema, f as FunnelBroadcaster, g as publishResponseSchema, h as publishRequestSchema, i as channelWsUrl, l as SqliteFunnelEventLog, m as FunnelChannelPublisher, n as MemoryFunnelEventLog, o as FunnelGatewayToken, r as channelWsProtocols, s as FunnelGatewayServer, t as SqliteConnectorDiagnosticLog, u as FunnelEventLog, v as CONNECTOR_CONNECTION_STATUSES, x as connectorProcessedEventSchema, y as ConnectorDiagnosticLog } from "./sqlite-diagnostic-log-Qs4cf9I_.js";
|
|
3
3
|
export { CONNECTOR_CONNECTION_STATUSES, ConnectorDiagnosticLog, DEFAULT_GATEWAY_TOKEN_PATH, FunnelBroadcaster, FunnelChannelPublisher, FunnelEventLog, FunnelGatewayServer, FunnelGatewayToken, FunnelListenerRegistry, MemoryConnectorDiagnosticLog, MemoryFunnelEventLog, SqliteConnectorDiagnosticLog, SqliteFunnelEventLog, channelWsProtocols, channelWsUrl, connectorConnectionEventSchema, connectorProcessedEventSchema, connectorRawEventSchema, funnelEventSchema, gatewayLoopbackUrl, publishRequestSchema, publishResponseSchema };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { t as NodeFunnelProcessRunner } from "./node-process-runner-
|
|
2
|
-
import { t as errorMessageOf } from "./error-message-of-
|
|
3
|
-
import { t as ghConnectorSchema } from "./gh-connector-schema-
|
|
4
|
-
import { t as FunnelConnectorAdapter } from "./connector-adapter-
|
|
5
|
-
import { i as resolveFlumeDeps, n as FunnelFlumeSourceListener, r as flumeLogHandler, t as slotFields } from "./slot-fields-
|
|
1
|
+
import { t as NodeFunnelProcessRunner } from "./node-process-runner-D4rzPl8Q.js";
|
|
2
|
+
import { t as errorMessageOf } from "./error-message-of-BG4ezZ_s.js";
|
|
3
|
+
import { t as ghConnectorSchema } from "./gh-connector-schema-DmZTrzUu.js";
|
|
4
|
+
import { t as FunnelConnectorAdapter } from "./connector-adapter-BL2ehMej.js";
|
|
5
|
+
import { i as resolveFlumeDeps, n as FunnelFlumeSourceListener, r as flumeLogHandler, t as slotFields } from "./slot-fields-eCWizJqS.js";
|
|
6
6
|
import { FlumeGitHubSource } from "@interactive-inc/flume/github";
|
|
7
7
|
//#region lib/engine/connectors/gh-adapter.ts
|
|
8
8
|
const defaultProcess$1 = new NodeFunnelProcessRunner();
|
|
@@ -1,14 +1,155 @@
|
|
|
1
|
-
import { n as FunnelClock, t as FunnelLogger } from "./logger-
|
|
2
|
-
import { n as FunnelFileSystem } from "./file-system-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { n as ChannelConnectorView, r as FunnelChannels } from "./channels-
|
|
1
|
+
import { n as FunnelClock, t as FunnelLogger } from "./logger-mMZvblTx.js";
|
|
2
|
+
import { n as FunnelFileSystem } from "./file-system-BNtl997T.js";
|
|
3
|
+
import { b as FunnelProcessRunner, d as FunnelConnectorListener, g as BaseConnectorConfig } from "./connector-descriptor-D4XtEsH8.js";
|
|
4
|
+
import { c as ConnectorProcessedQuery, f as ConnectorRawQuery, g as StoredRawEvent, h as StoredProcessedEvent, i as ConnectorConnectionRecord, l as ConnectorProcessedRecord, m as StoredConnectionEvent, o as ConnectorDiagnosticLog, p as ConnectorRawRecord, r as ConnectorConnectionQuery } from "./diagnostic-log-BsAg5qZK.js";
|
|
5
|
+
import { n as ChannelConnectorView, r as FunnelChannels } from "./channels-B0cifCfw.js";
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
import { Hono } from "hono";
|
|
8
|
-
import
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
import { ServerWebSocket } from "bun";
|
|
9
|
+
//#region lib/engine/error/on-funnel-error.d.ts
|
|
10
|
+
/**
|
|
11
|
+
* Host integration hook called when Funnel catches an exception that would
|
|
12
|
+
* otherwise be silently swallowed (subscriber throw, listener start failure,
|
|
13
|
+
* MCP forward failure, etc.). Pass `Sentry.captureException` from the host to
|
|
14
|
+
* pipe these into your error reporter. Defaults to a no-op when omitted.
|
|
15
|
+
*
|
|
16
|
+
* `context` carries the component name and any extra metadata the caller had
|
|
17
|
+
* at the catch site (channel / connector / subscriber id when available).
|
|
18
|
+
*/
|
|
19
|
+
type OnFunnelError = (error: Error, context?: Record<string, unknown>) => void;
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region lib/gateway/broadcaster.d.ts
|
|
22
|
+
type ClientData = {
|
|
23
|
+
/** Stable channel id (uuid) that the WS client subscribed to. */
|
|
24
|
+
channel: string;
|
|
25
|
+
/** Human-facing channel name resolved at upgrade time, kept for log readability. */
|
|
26
|
+
channelName?: string | null;
|
|
27
|
+
/** Connector names belonging to that channel. */
|
|
28
|
+
connectors: string[];
|
|
29
|
+
/** Routing mode resolved from channel config at upgrade time. Defaults to fanout. */
|
|
30
|
+
delivery?: "fanout" | "exclusive";
|
|
31
|
+
/**
|
|
32
|
+
* Opaque per-client id declared at upgrade time (`?id=<subscriberId>`). When an
|
|
33
|
+
* event carries `meta.target`, only the client whose `subscriberId` equals it
|
|
34
|
+
* receives the event among that channel's regular subscribers. Targeted delivery
|
|
35
|
+
* is how a publisher addresses one specific instance (e.g. a single agent
|
|
36
|
+
* session) without every subscriber having to receive and discard it.
|
|
37
|
+
*/
|
|
38
|
+
subscriberId?: string;
|
|
39
|
+
};
|
|
40
|
+
type BroadcastEvent = {
|
|
41
|
+
content: string;
|
|
42
|
+
meta?: Record<string, string>;
|
|
43
|
+
};
|
|
44
|
+
type ReplayableEvent = BroadcastEvent & {
|
|
45
|
+
offset: number;
|
|
46
|
+
};
|
|
47
|
+
type BroadcastSubscriber = (event: ReplayableEvent) => void;
|
|
48
|
+
/**
|
|
49
|
+
* Optional persistent replay source. Wired in by the gateway-server with a
|
|
50
|
+
* `FunnelEventLog` (SQLite-backed by default) so reconnects across daemon
|
|
51
|
+
* restarts can recover events older than the in-memory buffer via an indexed
|
|
52
|
+
* `seq > since` range scan.
|
|
53
|
+
*/
|
|
54
|
+
type ReplaySource = {
|
|
55
|
+
loadSince(since: number): ReplayableEvent[];
|
|
56
|
+
};
|
|
57
|
+
type Deps$4 = {
|
|
58
|
+
logger?: FunnelLogger;
|
|
59
|
+
/** Host hook for surfacing subscriber-throw exceptions. Defaults to no-op. */
|
|
60
|
+
onError?: OnFunnelError;
|
|
61
|
+
maxBufferedBytes?: number;
|
|
62
|
+
now?: () => number;
|
|
63
|
+
/** Number of recent events kept in the in-memory replay buffer. */
|
|
64
|
+
replayBufferSize?: number;
|
|
65
|
+
/** Hard byte cap on replay buffer payloads. Older events are evicted FIFO until under this cap. */
|
|
66
|
+
replayBufferMaxBytes?: number;
|
|
67
|
+
/** Persistent replay source consulted when the in-memory buffer cannot satisfy `since`. */
|
|
68
|
+
persistentReplay?: ReplaySource;
|
|
69
|
+
};
|
|
70
|
+
type BroadcasterMetrics = {
|
|
71
|
+
clients: number;
|
|
72
|
+
subscribers: number;
|
|
73
|
+
eventsBroadcast: number;
|
|
74
|
+
droppedSlowClients: number;
|
|
75
|
+
lastBroadcastAt: string | null;
|
|
76
|
+
/** Latest emitted offset. Clients can `?since=<offset>` to ask for events strictly after this point. */
|
|
77
|
+
latestOffset: number;
|
|
78
|
+
/** Oldest offset still held in the replay buffer. Older values cannot be replayed and trigger a full resync. */
|
|
79
|
+
oldestReplayableOffset: number | null;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* In-process pub/sub for connector events.
|
|
83
|
+
*
|
|
84
|
+
* Two outbound paths:
|
|
85
|
+
* - WS clients connected via the gateway's `/ws` endpoint, scoped per channel
|
|
86
|
+
* - In-process subscribers registered via `subscribe()` (programmable API)
|
|
87
|
+
*
|
|
88
|
+
* Backpressure: if a WS client's `bufferedAmount` exceeds `maxBufferedBytes`
|
|
89
|
+
* (default 1 MiB), the client is closed with code 1009 and dropped from the
|
|
90
|
+
* registry to keep one slow consumer from blocking the daemon.
|
|
91
|
+
*
|
|
92
|
+
* Replay: every emitted event gets a strictly increasing `offset`. The latest
|
|
93
|
+
* `replayBufferSize` events are kept in memory; reconnecting WS clients can
|
|
94
|
+
* pass `?since=<offset>` and the broadcaster resends matching events before
|
|
95
|
+
* resuming the live stream. The in-memory ring covers short reconnects;
|
|
96
|
+
* older history is served from the event log wired in as `persistentReplay`.
|
|
97
|
+
*/
|
|
98
|
+
declare class FunnelBroadcaster {
|
|
99
|
+
private readonly clients;
|
|
100
|
+
private readonly subscribers;
|
|
101
|
+
private readonly logger;
|
|
102
|
+
private readonly onError;
|
|
103
|
+
private readonly maxBufferedBytes;
|
|
104
|
+
private readonly now;
|
|
105
|
+
private readonly replayBufferSize;
|
|
106
|
+
private readonly replayBufferMaxBytes;
|
|
107
|
+
private readonly replayBuffer;
|
|
108
|
+
private readonly persistentReplay;
|
|
109
|
+
private readonly exclusiveCursor;
|
|
110
|
+
private replayBufferBytes;
|
|
111
|
+
private eventsBroadcast;
|
|
112
|
+
private droppedSlowClients;
|
|
113
|
+
private lastBroadcastAt;
|
|
114
|
+
private latestOffset;
|
|
115
|
+
constructor(deps?: Deps$4);
|
|
116
|
+
getMetrics(): BroadcasterMetrics;
|
|
117
|
+
/**
|
|
118
|
+
* Returns events with offset > since, filtered by the connector subscription
|
|
119
|
+
* rules of `data`. Used at WS upgrade time when the client passes `?since=<offset>`.
|
|
120
|
+
*
|
|
121
|
+
* Two-tier lookup:
|
|
122
|
+
* 1. The in-memory ring buffer (covers short reconnects, last `replayBufferSize` events).
|
|
123
|
+
* 2. If `since` predates the oldest in-memory entry and a persistent replay source
|
|
124
|
+
* is wired in (SQLite by default), the gap is filled from it. This covers reconnects
|
|
125
|
+
* across daemon restarts where the in-memory buffer was lost.
|
|
126
|
+
*
|
|
127
|
+
* Result is sorted ascending by offset and de-duplicated against the in-memory buffer.
|
|
128
|
+
*/
|
|
129
|
+
replaySince(since: number, data: ClientData): ReplayableEvent[];
|
|
130
|
+
private matchesClient;
|
|
131
|
+
/**
|
|
132
|
+
* Returns the list of WS clients that should receive `event`. For each per-channel group:
|
|
133
|
+
* - fanout → every matching client receives
|
|
134
|
+
* - exclusive → exactly one client receives, picked round-robin per channel
|
|
135
|
+
*
|
|
136
|
+
* `meta.target` narrows the recipient set via `matchesClient`: only the subscriber
|
|
137
|
+
* whose `subscriberId` equals `target` receives a targeted event.
|
|
138
|
+
*/
|
|
139
|
+
private pickRecipients;
|
|
140
|
+
addClient(ws: ServerWebSocket<unknown>, data: ClientData): void;
|
|
141
|
+
removeClient(ws: ServerWebSocket<unknown>): void;
|
|
142
|
+
getClientCount(): number;
|
|
143
|
+
listChannels(): {
|
|
144
|
+
channel: string;
|
|
145
|
+
connectors: string[];
|
|
146
|
+
}[];
|
|
147
|
+
subscribe(handler: BroadcastSubscriber): () => void;
|
|
148
|
+
broadcast(content: string, meta?: Record<string, string>): ReplayableEvent;
|
|
149
|
+
/** Forward-seed the offset counter (used at startup from the persisted event store). */
|
|
150
|
+
seedLatestOffset(offset: number): void;
|
|
151
|
+
}
|
|
152
|
+
//#endregion
|
|
12
153
|
//#region lib/gateway/listener-registry.d.ts
|
|
13
154
|
type ConnectorRegistry = {
|
|
14
155
|
listAllConnectors(): ChannelConnectorView[];
|
|
@@ -22,7 +163,8 @@ type ListenerRegistryNotify = (channelName: string, connectorName: string, conte
|
|
|
22
163
|
type Deps$3 = {
|
|
23
164
|
channels: ConnectorRegistry;
|
|
24
165
|
notify: ListenerRegistryNotify;
|
|
25
|
-
logger?: FunnelLogger;
|
|
166
|
+
logger?: FunnelLogger;
|
|
167
|
+
/** Host hook for surfacing listener lifecycle exceptions. Defaults to no-op. */
|
|
26
168
|
onError?: OnFunnelError;
|
|
27
169
|
healthCheckIntervalMs?: number;
|
|
28
170
|
maxBackoffMs?: number;
|
|
@@ -127,6 +269,7 @@ type GatewayRouteDeps = {
|
|
|
127
269
|
emit: (input: GatewayEmitInput) => {
|
|
128
270
|
offset: number;
|
|
129
271
|
};
|
|
272
|
+
diagnosticLog?: ConnectorDiagnosticLog;
|
|
130
273
|
};
|
|
131
274
|
//#endregion
|
|
132
275
|
//#region lib/gateway/factory.d.ts
|
|
@@ -190,7 +333,7 @@ declare abstract class FunnelEventLog {
|
|
|
190
333
|
* mutually exclusive — modeled as a union so you can't pass both (the old shape
|
|
191
334
|
* silently ignored `dbPath` when `eventLog` was also given).
|
|
192
335
|
*
|
|
193
|
-
* - omit both → SQLite
|
|
336
|
+
* - omit both → SQLite under `<tmpDir>/events/`, isolated by funnel dir + port
|
|
194
337
|
* - `dbPath` → SQLite at a custom path (parent dir created on demand)
|
|
195
338
|
* - `eventLog` → bring your own `FunnelEventLog` (e.g. `MemoryFunnelEventLog`)
|
|
196
339
|
*/
|
|
@@ -203,15 +346,21 @@ type GatewayEventStore = {
|
|
|
203
346
|
};
|
|
204
347
|
type Deps$2 = GatewayEventStore & {
|
|
205
348
|
channels: FunnelChannels;
|
|
206
|
-
port?: number;
|
|
349
|
+
port?: number;
|
|
350
|
+
/** Bind address for `Bun.serve`. Defaults to `127.0.0.1` (loopback only). Set to `0.0.0.0` to expose on the network. */
|
|
207
351
|
hostname?: string;
|
|
208
352
|
process?: FunnelProcessRunner;
|
|
209
353
|
clock?: FunnelClock;
|
|
210
|
-
logger?: FunnelLogger;
|
|
354
|
+
logger?: FunnelLogger;
|
|
355
|
+
/** Host hook for surfacing internal exceptions (broadcaster / supervisor). Defaults to no-op. */
|
|
211
356
|
onError?: OnFunnelError;
|
|
212
|
-
selfPid?: number;
|
|
357
|
+
selfPid?: number;
|
|
358
|
+
/** Funnel home dir, used to scope kill-competing to daemons rooted at the same dir. Defaults to FUNNEL_DIR. */
|
|
213
359
|
dir?: string;
|
|
214
|
-
|
|
360
|
+
/** Runtime directory used by the default replay database. Defaults to `funnelTmpDir()`. */
|
|
361
|
+
tmpDir?: string;
|
|
362
|
+
killCompetingSlack?: boolean;
|
|
363
|
+
/** Bearer token required for `/listeners*`, `/status`, and `/ws`. Empty string disables auth (tests only). */
|
|
215
364
|
token?: string;
|
|
216
365
|
/**
|
|
217
366
|
* Permit binding a non-loopback hostname without a token. Off by default:
|
|
@@ -227,6 +376,8 @@ type Deps$2 = GatewayEventStore & {
|
|
|
227
376
|
* `/channels`, `/health` are mounted after and take precedence on conflict.
|
|
228
377
|
*/
|
|
229
378
|
extraRoutes?: Hono<Env>;
|
|
379
|
+
/** Read-side diagnostic source exposed to the built-in debug route. */
|
|
380
|
+
diagnosticLog?: ConnectorDiagnosticLog;
|
|
230
381
|
};
|
|
231
382
|
/**
|
|
232
383
|
* In-process gateway: runs `Bun.serve` (HTTP + WebSocket /ws), boots connector
|
|
@@ -257,6 +408,7 @@ declare class FunnelGatewayServer {
|
|
|
257
408
|
private readonly nowMs;
|
|
258
409
|
private readonly extraRoutes;
|
|
259
410
|
private readonly ownsEventLog;
|
|
411
|
+
private readonly diagnosticLog;
|
|
260
412
|
private startedAt;
|
|
261
413
|
private server;
|
|
262
414
|
private disposed;
|
|
@@ -344,9 +496,13 @@ declare class FunnelGatewayServer {
|
|
|
344
496
|
* gateway requires a token.
|
|
345
497
|
*/
|
|
346
498
|
type ChannelWsUrlInput = {
|
|
347
|
-
/** Base WS endpoint, e.g. `ws://localhost:9743/ws`. Existing query is preserved. */
|
|
348
|
-
|
|
349
|
-
|
|
499
|
+
/** Base WS endpoint, e.g. `ws://localhost:9743/ws`. Existing query is preserved. */
|
|
500
|
+
base: string;
|
|
501
|
+
/** Channel name to subscribe to. Required — the broadcaster filters by it. */
|
|
502
|
+
channel: string;
|
|
503
|
+
/** Opaque subscriber id for targeted delivery (`meta.target=<id>`). Omit for fanout. */
|
|
504
|
+
subscriberId?: string;
|
|
505
|
+
/** Replay from this event offset (inclusive). Omit to receive only new events. */
|
|
350
506
|
since?: number;
|
|
351
507
|
};
|
|
352
508
|
declare function channelWsUrl(input: ChannelWsUrlInput): string;
|
|
@@ -436,7 +592,8 @@ type PublishResult = {
|
|
|
436
592
|
//#region lib/gateway/channel-publisher.d.ts
|
|
437
593
|
type Deps = {
|
|
438
594
|
port: number;
|
|
439
|
-
isDaemonRunning: () => boolean;
|
|
595
|
+
isDaemonRunning: () => boolean;
|
|
596
|
+
/** Returns the daemon's gateway token, or null if unavailable. Sent as `Authorization: Bearer`. */
|
|
440
597
|
getToken?: () => string | null;
|
|
441
598
|
};
|
|
442
599
|
/**
|
|
@@ -455,18 +612,25 @@ declare class FunnelChannelPublisher {
|
|
|
455
612
|
//#endregion
|
|
456
613
|
//#region lib/gateway/event-log/sqlite-event-log.d.ts
|
|
457
614
|
type Props$1 = {
|
|
458
|
-
/** SQLite database file path. Created on first write. ":memory:" for tests. */
|
|
459
|
-
|
|
615
|
+
/** SQLite database file path. Created on first write. ":memory:" for tests. */
|
|
616
|
+
path: string;
|
|
617
|
+
/** Override for tests. Defaults to `Date.now`. */
|
|
618
|
+
now?: () => number;
|
|
619
|
+
/** Surfaces a failed persist (PK collision, disk-full, locked WAL). Silent if absent. */
|
|
460
620
|
logger?: FunnelLogger;
|
|
461
621
|
/**
|
|
462
622
|
* Host-supplied error sink. Routed alongside the logger when a write
|
|
463
623
|
* fails, so Sentry / Datadog / a custom alert pipeline sees the durable
|
|
464
624
|
* replay loss too — not just the local log file. Silent if absent.
|
|
465
625
|
*/
|
|
466
|
-
onError?: OnFunnelError;
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
626
|
+
onError?: OnFunnelError;
|
|
627
|
+
/** Optional row cap. Pruned on every insert. */
|
|
628
|
+
maxRows?: number;
|
|
629
|
+
/** Optional age cap in ms. Pruned on every insert. */
|
|
630
|
+
maxAgeMs?: number;
|
|
631
|
+
/** Optional on-disk byte cap. Checked periodically; on overflow the oldest rows are dropped toward targetBytes and the file is VACUUMed. */
|
|
632
|
+
maxBytes?: number;
|
|
633
|
+
/** Shrink target when maxBytes is exceeded. Defaults to maxBytes/4. */
|
|
470
634
|
targetBytes?: number;
|
|
471
635
|
};
|
|
472
636
|
/**
|
|
@@ -540,18 +704,24 @@ declare class MemoryFunnelEventLog extends FunnelEventLog {
|
|
|
540
704
|
//#endregion
|
|
541
705
|
//#region lib/engine/diagnostic-log/sqlite-diagnostic-log.d.ts
|
|
542
706
|
type Props = {
|
|
543
|
-
/** SQLite file for the raw (pre-filter) table. ":memory:" for tests. */
|
|
544
|
-
|
|
707
|
+
/** SQLite file for the raw (pre-filter) table. ":memory:" for tests. */
|
|
708
|
+
rawPath: string;
|
|
709
|
+
/** SQLite file for the processed (verdict) table. ":memory:" for tests. */
|
|
710
|
+
processedPath: string;
|
|
711
|
+
/** SQLite file for the connection (lifecycle) table. ":memory:" for tests. */
|
|
545
712
|
connectionPath: string;
|
|
546
|
-
now?: () => number;
|
|
713
|
+
now?: () => number;
|
|
714
|
+
/** Row cap for the processed and connection tables. Pruned on every insert. */
|
|
547
715
|
maxRows?: number;
|
|
548
716
|
/**
|
|
549
717
|
* Row cap for the raw table specifically. Raw rows can each hold up to
|
|
550
718
|
* `RAW_PAYLOAD_CAP` bytes, so they want a tighter cap than the small
|
|
551
719
|
* processed/connection verdict rows. Defaults to `maxRows` when unset.
|
|
552
720
|
*/
|
|
553
|
-
rawMaxRows?: number;
|
|
554
|
-
|
|
721
|
+
rawMaxRows?: number;
|
|
722
|
+
/** Age cap in ms for all tables — bounds how long untouched payloads (with PII) live. Pruned on every insert. */
|
|
723
|
+
maxAgeMs?: number;
|
|
724
|
+
/** When set, `insert()` errors (disk full, WAL lock) are logged instead of silently dropped. */
|
|
555
725
|
logger?: FunnelLogger;
|
|
556
726
|
};
|
|
557
727
|
/**
|
|
@@ -621,7 +791,7 @@ declare class MemoryConnectorDiagnosticLog extends ConnectorDiagnosticLog {
|
|
|
621
791
|
* shape as CLI's `c.var.funnel`.
|
|
622
792
|
*/
|
|
623
793
|
type GatewayApp = ReturnType<typeof buildGatewayRoutes>;
|
|
624
|
-
declare function buildGatewayRoutes():
|
|
794
|
+
declare function buildGatewayRoutes(): import("hono/hono-base").HonoBase<Env, {
|
|
625
795
|
"/health": {
|
|
626
796
|
$get: {
|
|
627
797
|
input: {};
|
|
@@ -643,7 +813,7 @@ declare function buildGatewayRoutes(): _$hono_hono_base0.HonoBase<Env, {
|
|
|
643
813
|
}[];
|
|
644
814
|
};
|
|
645
815
|
outputFormat: "json";
|
|
646
|
-
status:
|
|
816
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
647
817
|
};
|
|
648
818
|
};
|
|
649
819
|
} & {
|
|
@@ -681,7 +851,7 @@ declare function buildGatewayRoutes(): _$hono_hono_base0.HonoBase<Env, {
|
|
|
681
851
|
};
|
|
682
852
|
};
|
|
683
853
|
outputFormat: "json";
|
|
684
|
-
status:
|
|
854
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
685
855
|
};
|
|
686
856
|
};
|
|
687
857
|
} & {
|
|
@@ -710,7 +880,7 @@ declare function buildGatewayRoutes(): _$hono_hono_base0.HonoBase<Env, {
|
|
|
710
880
|
outcome: string;
|
|
711
881
|
payload: string | null;
|
|
712
882
|
payloadParsed: {
|
|
713
|
-
[x: string]:
|
|
883
|
+
[x: string]: import("hono/utils/types").JSONValue;
|
|
714
884
|
} | null;
|
|
715
885
|
preview: string | null;
|
|
716
886
|
}[];
|
|
@@ -729,7 +899,7 @@ declare function buildGatewayRoutes(): _$hono_hono_base0.HonoBase<Env, {
|
|
|
729
899
|
}[];
|
|
730
900
|
};
|
|
731
901
|
outputFormat: "json";
|
|
732
|
-
status:
|
|
902
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
733
903
|
};
|
|
734
904
|
};
|
|
735
905
|
} & {
|
|
@@ -750,7 +920,7 @@ declare function buildGatewayRoutes(): _$hono_hono_base0.HonoBase<Env, {
|
|
|
750
920
|
}[];
|
|
751
921
|
};
|
|
752
922
|
outputFormat: "json";
|
|
753
|
-
status:
|
|
923
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
754
924
|
};
|
|
755
925
|
};
|
|
756
926
|
} & {
|
|
@@ -870,10 +1040,10 @@ declare function buildGatewayRoutes(): _$hono_hono_base0.HonoBase<Env, {
|
|
|
870
1040
|
};
|
|
871
1041
|
output: {
|
|
872
1042
|
ok: true;
|
|
873
|
-
result:
|
|
1043
|
+
result: import("hono/utils/types").JSONValue;
|
|
874
1044
|
};
|
|
875
1045
|
outputFormat: "json";
|
|
876
|
-
status:
|
|
1046
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
877
1047
|
};
|
|
878
1048
|
};
|
|
879
1049
|
} & {
|
|
@@ -934,9 +1104,9 @@ declare function buildGatewayRoutes(): _$hono_hono_base0.HonoBase<Env, {
|
|
|
934
1104
|
offset: number;
|
|
935
1105
|
};
|
|
936
1106
|
outputFormat: "json";
|
|
937
|
-
status:
|
|
1107
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
938
1108
|
};
|
|
939
1109
|
};
|
|
940
1110
|
}, "/", "/channels/:channel/publish">;
|
|
941
1111
|
//#endregion
|
|
942
|
-
export { funnelEventSchema as C, FunnelListenerRegistry as D, GatewayRouteDeps as E, FunnelEventRecord as S, GatewayEmitInput as T, channelWsUrl as _, SqliteFunnelEventLog as a, FunnelEvent as b, PublishResponse as c, publishResponseSchema as d, DEFAULT_GATEWAY_TOKEN_PATH as f, channelWsProtocols as g, ChannelWsUrlInput as h, MemoryFunnelEventLog as i, PublishResult as l, gatewayLoopbackUrl as m, MemoryConnectorDiagnosticLog as n, FunnelChannelPublisher as o, FunnelGatewayToken as p, SqliteConnectorDiagnosticLog as r, PublishRequest as s, GatewayApp as t, publishRequestSchema as u, FunnelGatewayServer as v, Env as w, FunnelEventLog as x, GatewayEventStore as y };
|
|
1112
|
+
export { FunnelBroadcaster as A, funnelEventSchema as C, FunnelListenerRegistry as D, GatewayRouteDeps as E, OnFunnelError as M, BroadcastEvent as O, FunnelEventRecord as S, GatewayEmitInput as T, channelWsUrl as _, SqliteFunnelEventLog as a, FunnelEvent as b, PublishResponse as c, publishResponseSchema as d, DEFAULT_GATEWAY_TOKEN_PATH as f, channelWsProtocols as g, ChannelWsUrlInput as h, MemoryFunnelEventLog as i, ReplayableEvent as j, BroadcastSubscriber as k, PublishResult as l, gatewayLoopbackUrl as m, MemoryConnectorDiagnosticLog as n, FunnelChannelPublisher as o, FunnelGatewayToken as p, SqliteConnectorDiagnosticLog as r, PublishRequest as s, GatewayApp as t, publishRequestSchema as u, FunnelGatewayServer as v, Env as w, FunnelEventLog as x, GatewayEventStore as y };
|