@interactive-inc/flume 0.1.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.
@@ -0,0 +1,280 @@
1
+ import { r as FlumeGitHubNotificationSchema, t as FlumeLogger } from "./logger-B9E8zvgj.js";
2
+ //#region lib/github/github-seen-cache.ts
3
+ var FlumeGitHubSeenCache = class {
4
+ props;
5
+ seen = /* @__PURE__ */ new Map();
6
+ constructor(props) {
7
+ this.props = props;
8
+ }
9
+ has(id, updatedAt) {
10
+ return this.seen.get(id) === updatedAt;
11
+ }
12
+ add(id, updatedAt) {
13
+ this.seen.set(id, updatedAt);
14
+ }
15
+ trim() {
16
+ if (this.seen.size <= this.props.maxSize) return;
17
+ const entries = [...this.seen.entries()];
18
+ this.seen = new Map(entries.slice(entries.length - this.props.maxSize));
19
+ }
20
+ get size() {
21
+ return this.seen.size;
22
+ }
23
+ };
24
+ //#endregion
25
+ //#region lib/github/github-poller.ts
26
+ var FlumeGitHubPoller = class {
27
+ props;
28
+ log;
29
+ cache = new FlumeGitHubSeenCache({ maxSize: 5e3 });
30
+ timer = null;
31
+ since = null;
32
+ bootstrapped = false;
33
+ stopped = false;
34
+ consecutiveErrors = 0;
35
+ constructor(props) {
36
+ this.props = props;
37
+ this.log = new FlumeLogger({
38
+ source: "github.poller",
39
+ handler: props.onLog,
40
+ deps: props.deps
41
+ });
42
+ }
43
+ async start() {
44
+ this.stopped = false;
45
+ this.log.info({
46
+ action: "start",
47
+ message: `polling every ${this.props.interval}s`
48
+ });
49
+ await this.poll();
50
+ this.timer = this.props.deps.setInterval(() => {
51
+ this.poll().catch((err) => {
52
+ this.log.error({
53
+ action: "poll.unhandled",
54
+ message: "unexpected error in poll loop",
55
+ error: err instanceof Error ? err : new Error(String(err))
56
+ });
57
+ });
58
+ }, this.props.interval * 1e3);
59
+ }
60
+ stop() {
61
+ this.log.info({
62
+ action: "stop",
63
+ message: "stopping poller"
64
+ });
65
+ this.stopped = true;
66
+ if (this.timer !== null) {
67
+ this.props.deps.clearInterval(this.timer);
68
+ this.timer = null;
69
+ }
70
+ }
71
+ async poll() {
72
+ const params = new URLSearchParams({ all: "false" });
73
+ if (this.since) params.set("since", this.since);
74
+ const url = `https://api.github.com/notifications?${params}`;
75
+ this.log.debug({
76
+ action: "http.request",
77
+ message: `GET ${url}`
78
+ });
79
+ const response = await this.safeFetch(url);
80
+ if (response instanceof Error) return;
81
+ this.log.debug({
82
+ action: "http.response",
83
+ message: `GET ${response.status}`,
84
+ detail: {
85
+ status: response.status,
86
+ url
87
+ }
88
+ });
89
+ if (!response.ok) {
90
+ this.consecutiveErrors++;
91
+ this.log.error({
92
+ action: "http.error",
93
+ message: `HTTP ${response.status} (consecutive=${this.consecutiveErrors})`
94
+ });
95
+ if (this.consecutiveErrors >= 3) this.props.onDisconnected(`HTTP ${response.status}`);
96
+ return;
97
+ }
98
+ this.consecutiveErrors = 0;
99
+ const body = await response.json();
100
+ if (!Array.isArray(body)) {
101
+ this.log.warn({
102
+ action: "http.body",
103
+ message: "response body is not an array, dropping",
104
+ detail: { bodyType: typeof body }
105
+ });
106
+ return;
107
+ }
108
+ this.processNotifications(body);
109
+ }
110
+ processNotifications(raw) {
111
+ let dropped = 0;
112
+ const notifications = raw.flatMap((item) => {
113
+ const parsed = FlumeGitHubNotificationSchema.safeParse(item);
114
+ if (!parsed.success) {
115
+ dropped++;
116
+ this.log.warn({
117
+ action: "parse.skip",
118
+ message: "notification did not match schema",
119
+ detail: { issues: parsed.error.issues.map((i) => ({
120
+ path: i.path,
121
+ message: i.message
122
+ })) }
123
+ });
124
+ return [];
125
+ }
126
+ return [parsed.data];
127
+ });
128
+ if (dropped > 0) this.log.warn({
129
+ action: "parse.summary",
130
+ message: `${dropped}/${raw.length} notifications dropped by schema`
131
+ });
132
+ if (!this.bootstrapped) {
133
+ this.bootstrapped = true;
134
+ for (const notification of notifications) this.cache.add(notification.id, notification.updated_at);
135
+ this.since = new Date(this.props.deps.now()).toISOString();
136
+ this.log.info({
137
+ action: "bootstrap",
138
+ message: `seeded ${notifications.length} existing notifications`
139
+ });
140
+ this.props.onConnected();
141
+ return;
142
+ }
143
+ const fresh = [];
144
+ for (const notification of notifications) {
145
+ if (this.cache.has(notification.id, notification.updated_at)) continue;
146
+ this.cache.add(notification.id, notification.updated_at);
147
+ fresh.push(notification);
148
+ }
149
+ this.cache.trim();
150
+ this.since = new Date(this.props.deps.now()).toISOString();
151
+ if (fresh.length > 0) {
152
+ this.log.info({
153
+ action: "poll.fresh",
154
+ message: `${fresh.length} new notifications`
155
+ });
156
+ this.props.onNotifications(fresh);
157
+ } else this.log.debug({
158
+ action: "poll.idle",
159
+ message: "0 new notifications"
160
+ });
161
+ }
162
+ async safeFetch(url) {
163
+ try {
164
+ return await this.props.deps.fetch(url, { headers: {
165
+ Authorization: `Bearer ${this.props.token}`,
166
+ Accept: "application/vnd.github+json",
167
+ "X-GitHub-Api-Version": "2022-11-28"
168
+ } });
169
+ } catch (error) {
170
+ this.consecutiveErrors++;
171
+ const err = error instanceof Error ? error : new Error(String(error));
172
+ this.log.error({
173
+ action: "http.error",
174
+ message: `network error (consecutive=${this.consecutiveErrors})`,
175
+ error: err
176
+ });
177
+ if (this.consecutiveErrors >= 3) this.props.onDisconnected("network error");
178
+ return err;
179
+ }
180
+ }
181
+ };
182
+ //#endregion
183
+ //#region lib/github/github-source.ts
184
+ var FlumeGitHubSource = class FlumeGitHubSource {
185
+ options;
186
+ poller = null;
187
+ currentStatus = "disconnected";
188
+ log;
189
+ deps;
190
+ constructor(options) {
191
+ this.options = options;
192
+ this.deps = options.deps;
193
+ this.log = new FlumeLogger({
194
+ source: "github",
195
+ handler: options.onLog,
196
+ deps: this.deps
197
+ });
198
+ }
199
+ async start(handler) {
200
+ if (this.options.signal?.aborted) return;
201
+ this.options.signal?.addEventListener("abort", () => this.stop(), { once: true });
202
+ this.log.info({
203
+ action: "start",
204
+ message: "starting GitHub source"
205
+ });
206
+ this.setStatus("connecting");
207
+ this.poller = new FlumeGitHubPoller({
208
+ token: this.options.token,
209
+ interval: this.options.pollInterval ?? 60,
210
+ onLog: this.options.onLog,
211
+ deps: this.deps,
212
+ onNotifications: (notifications) => this.handleNotifications(handler, notifications),
213
+ onConnected: () => this.setStatus("connected"),
214
+ onDisconnected: (detail) => this.setStatus("disconnected", detail)
215
+ });
216
+ try {
217
+ await this.poller.start();
218
+ } catch (error) {
219
+ const err = error instanceof Error ? error : new Error(String(error));
220
+ this.log.error({
221
+ action: "start.failed",
222
+ message: err.message,
223
+ error: err
224
+ });
225
+ this.setStatus("disconnected");
226
+ }
227
+ }
228
+ async stop() {
229
+ this.log.info({
230
+ action: "stop",
231
+ message: "stopping GitHub source"
232
+ });
233
+ this.poller?.stop();
234
+ this.poller = null;
235
+ this.setStatus("disconnected");
236
+ }
237
+ status() {
238
+ return this.currentStatus;
239
+ }
240
+ handleNotifications(handler, notifications) {
241
+ for (const notification of notifications) {
242
+ const event = {
243
+ source: "github",
244
+ type: "notification",
245
+ data: notification,
246
+ meta: FlumeGitHubSource.extractMeta(notification),
247
+ receivedAt: this.deps.now()
248
+ };
249
+ try {
250
+ handler(event);
251
+ } catch (err) {
252
+ this.log.error({
253
+ action: "handler.error",
254
+ message: "user handler threw",
255
+ error: err instanceof Error ? err : new Error(String(err))
256
+ });
257
+ }
258
+ }
259
+ }
260
+ setStatus(next, detail) {
261
+ if (this.currentStatus === next) return;
262
+ this.log.info({
263
+ action: "status",
264
+ message: `${this.currentStatus} → ${next}${detail ? ` (${detail})` : ""}`
265
+ });
266
+ this.currentStatus = next;
267
+ this.options.onStatus?.(next, detail);
268
+ }
269
+ static extractMeta(notification) {
270
+ return {
271
+ event_type: "notification",
272
+ reason: notification.reason,
273
+ subject_type: notification.subject.type,
274
+ repository: notification.repository.full_name,
275
+ thread_id: notification.id
276
+ };
277
+ }
278
+ };
279
+ //#endregion
280
+ export { FlumeGitHubPoller as n, FlumeGitHubSeenCache as r, FlumeGitHubSource as t };
@@ -0,0 +1,19 @@
1
+ import { a as FlumeGitHubSourceOptions, i as FlumeGitHubNotification, o as FlumeHandler, y as FlumeStatus } from "./types-BVQSU336.js";
2
+
3
+ //#region lib/github/github-source.d.ts
4
+ declare class FlumeGitHubSource {
5
+ private readonly options;
6
+ private poller;
7
+ private currentStatus;
8
+ private readonly log;
9
+ private readonly deps;
10
+ constructor(options: FlumeGitHubSourceOptions);
11
+ start(handler: FlumeHandler): Promise<void>;
12
+ stop(): Promise<void>;
13
+ status(): FlumeStatus;
14
+ private handleNotifications;
15
+ private setStatus;
16
+ static extractMeta(notification: FlumeGitHubNotification): Record<string, string>;
17
+ }
18
+ //#endregion
19
+ export { FlumeGitHubSource };
package/dist/github.js ADDED
@@ -0,0 +1,2 @@
1
+ import { t as FlumeGitHubSource } from "./github-source-D7Z1RUbe.js";
2
+ export { FlumeGitHubSource };
@@ -0,0 +1,278 @@
1
+ import { C as FlumeGitHubNotificationSchema, S as FlumeGatewayMessageSchema, T as FlumeSlackEnvelopeSchema, _ as FlumeSourceName, a as FlumeGitHubSourceOptions, b as FlumeStatusHandler, c as FlumeLogHandler, d as FlumeReconnectConfig, f as FlumeReconnectOptions, g as FlumeSlackSourceOptions, h as FlumeSlackEnvelope, i as FlumeGitHubNotification, l as FlumeLogInput, m as FlumeSlackConnectionResponse, n as FlumeEvent, o as FlumeHandler, p as FlumeRuntimeDeps, r as FlumeGatewayMessage, s as FlumeLog, t as FlumeDiscordSourceOptions, u as FlumeLogLevel, v as FlumeSourceOptions, w as FlumeSlackConnectionResponseSchema, x as FlumeTimerHandle, y as FlumeStatus } from "./types-BVQSU336.js";
2
+ import { FlumeDiscordSource } from "./discord.js";
3
+ import { FlumeGitHubSource } from "./github.js";
4
+ import { FlumeSlackSource } from "./slack.js";
5
+
6
+ //#region lib/deps.d.ts
7
+ declare function createFlumeDefaultDeps(): FlumeRuntimeDeps;
8
+ //#endregion
9
+ //#region lib/errors/connection-error.d.ts
10
+ declare class FlumeConnectionError extends Error {
11
+ constructor(message: string);
12
+ }
13
+ //#endregion
14
+ //#region lib/errors/http-error.d.ts
15
+ type Props$10 = {
16
+ message: string;
17
+ status: number;
18
+ };
19
+ declare class FlumeHttpError extends Error {
20
+ readonly status: number;
21
+ constructor(props: Props$10);
22
+ }
23
+ //#endregion
24
+ //#region lib/errors/parse-error.d.ts
25
+ declare class FlumeParseError extends Error {
26
+ constructor(message: string);
27
+ }
28
+ //#endregion
29
+ //#region lib/logger.d.ts
30
+ type Props$9 = {
31
+ source: string;
32
+ handler?: FlumeLogHandler;
33
+ deps: Pick<FlumeRuntimeDeps, "now">;
34
+ };
35
+ declare class FlumeLogger {
36
+ private readonly props;
37
+ constructor(props: Props$9);
38
+ debug(entry: FlumeLogInput): void;
39
+ info(entry: FlumeLogInput): void;
40
+ warn(entry: FlumeLogInput): void;
41
+ error(entry: FlumeLogInput): void;
42
+ private emit;
43
+ }
44
+ //#endregion
45
+ //#region lib/reconnect-config.d.ts
46
+ declare function resolveFlumeReconnectConfig(input: boolean | FlumeReconnectOptions | undefined): FlumeReconnectConfig | null;
47
+ //#endregion
48
+ //#region lib/reconnector.d.ts
49
+ type Props$8 = {
50
+ maxAttempts: number;
51
+ baseDelay: number;
52
+ maxDelay: number;
53
+ deps: Pick<FlumeRuntimeDeps, "setTimeout" | "clearTimeout" | "random">;
54
+ };
55
+ declare class FlumeReconnector {
56
+ private readonly props;
57
+ attempt: number;
58
+ aborted: boolean;
59
+ private timer;
60
+ constructor(props: Props$8);
61
+ schedule(fn: () => void): number;
62
+ reset(): void;
63
+ cancel(): void;
64
+ private nextDelay;
65
+ }
66
+ //#endregion
67
+ //#region lib/flume.d.ts
68
+ type Props$7 = {
69
+ onLog?: FlumeLogHandler;
70
+ onStatus?: FlumeStatusHandler;
71
+ reconnect?: boolean | FlumeReconnectOptions;
72
+ signal?: AbortSignal;
73
+ deps?: Partial<FlumeRuntimeDeps>;
74
+ };
75
+ /**
76
+ * 共有設定を持つ DI コンテナ。各 Source に共通の deps / logging / reconnect を注入する
77
+ */
78
+ declare class Flume {
79
+ private readonly props;
80
+ private readonly resolvedDeps;
81
+ constructor(props: Props$7);
82
+ discord(options: {
83
+ token: string;
84
+ intents?: number;
85
+ }): FlumeDiscordSource;
86
+ slack(options: {
87
+ appToken: string;
88
+ botToken?: string;
89
+ }): FlumeSlackSource;
90
+ github(options: {
91
+ token: string;
92
+ pollInterval?: number;
93
+ }): FlumeGitHubSource;
94
+ }
95
+ //#endregion
96
+ //#region lib/discord/discord-gateway-intents.d.ts
97
+ declare const FlumeDiscordGatewayIntents: {
98
+ readonly Guilds: number;
99
+ readonly GuildMembers: number;
100
+ readonly GuildModeration: number;
101
+ readonly GuildExpressions: number;
102
+ readonly GuildIntegrations: number;
103
+ readonly GuildWebhooks: number;
104
+ readonly GuildInvites: number;
105
+ readonly GuildVoiceStates: number;
106
+ readonly GuildPresences: number;
107
+ readonly GuildMessages: number;
108
+ readonly GuildMessageReactions: number;
109
+ readonly GuildMessageTyping: number;
110
+ readonly DirectMessages: number;
111
+ readonly DirectMessageReactions: number;
112
+ readonly DirectMessageTyping: number;
113
+ readonly MessageContent: number;
114
+ readonly GuildScheduledEvents: number;
115
+ readonly AutoModerationConfiguration: number;
116
+ readonly AutoModerationExecution: number;
117
+ readonly GuildMessagePolls: number;
118
+ readonly DirectMessagePolls: number;
119
+ };
120
+ //#endregion
121
+ //#region lib/discord/discord-gateway-session.d.ts
122
+ type Props$6 = {
123
+ sessionId: string | null;
124
+ resumeUrl: string | null;
125
+ seq: number | null;
126
+ };
127
+ declare class FlumeDiscordGatewaySession {
128
+ readonly sessionId: string | null;
129
+ readonly resumeUrl: string | null;
130
+ readonly seq: number | null;
131
+ constructor(props: Props$6);
132
+ static empty(): FlumeDiscordGatewaySession;
133
+ canResume(): boolean;
134
+ withSeq(seq: number): FlumeDiscordGatewaySession;
135
+ withReady(sessionId: string, resumeUrl: string): FlumeDiscordGatewaySession;
136
+ withReset(): FlumeDiscordGatewaySession;
137
+ }
138
+ //#endregion
139
+ //#region lib/discord/discord-gateway.d.ts
140
+ type Deps$2 = Pick<FlumeRuntimeDeps, "WebSocket" | "setInterval" | "clearInterval" | "setTimeout" | "random" | "now">;
141
+ type Props$5 = {
142
+ token: string;
143
+ intents: number;
144
+ onDispatch: (event: string, data: Record<string, unknown>) => void;
145
+ onStatus: (status: "connected" | "disconnected") => void;
146
+ onLog?: FlumeLogHandler;
147
+ deps: Deps$2;
148
+ };
149
+ declare class FlumeDiscordGateway {
150
+ private readonly props;
151
+ private readonly log;
152
+ private ws;
153
+ private heartbeat;
154
+ session: FlumeDiscordGatewaySession;
155
+ stopped: boolean;
156
+ private pendingResolve;
157
+ private pendingResolved;
158
+ constructor(props: Props$5);
159
+ connect(url?: string): Promise<FlumeConnectionError | null>;
160
+ disconnect(): void;
161
+ isConnected(): boolean;
162
+ private completeConnect;
163
+ private onMessage;
164
+ private onHello;
165
+ private onHeartbeatAck;
166
+ private onHeartbeatRequest;
167
+ private onReconnectRequest;
168
+ private onInvalidSession;
169
+ private onDispatch;
170
+ private onClose;
171
+ private onError;
172
+ private send;
173
+ private sendIdentify;
174
+ private sendResume;
175
+ }
176
+ //#endregion
177
+ //#region lib/discord/discord-heartbeat.d.ts
178
+ type Props$4 = {
179
+ onSend: () => void;
180
+ onZombie: () => void;
181
+ deps: Pick<FlumeRuntimeDeps, "setInterval" | "clearInterval">;
182
+ };
183
+ declare class FlumeDiscordHeartbeat {
184
+ private readonly props;
185
+ private timer;
186
+ private ackReceived;
187
+ constructor(props: Props$4);
188
+ start(intervalMs: number): void;
189
+ stop(): void;
190
+ ack(): void;
191
+ isRunning(): boolean;
192
+ }
193
+ //#endregion
194
+ //#region lib/discord/parse-discord-gateway-message.d.ts
195
+ declare function parseDiscordGatewayMessage(raw: string): FlumeGatewayMessage | FlumeParseError;
196
+ //#endregion
197
+ //#region lib/slack/slack-socket-mode.d.ts
198
+ type Deps$1 = Pick<FlumeRuntimeDeps, "WebSocket" | "fetch" | "now">;
199
+ type Props$3 = {
200
+ appToken: string;
201
+ onMessage: (envelope: FlumeSlackEnvelope) => void;
202
+ onConnected: () => void;
203
+ onDisconnected: () => void;
204
+ onLog?: FlumeLogHandler;
205
+ deps: Deps$1;
206
+ };
207
+ declare class FlumeSlackSocketMode {
208
+ private readonly props;
209
+ private readonly log;
210
+ private ws;
211
+ stopped: boolean;
212
+ private pendingResolve;
213
+ private pendingResolved;
214
+ constructor(props: Props$3);
215
+ connect(): Promise<FlumeConnectionError | FlumeHttpError | null>;
216
+ disconnect(): void;
217
+ isConnected(): boolean;
218
+ private openSocket;
219
+ private completeConnect;
220
+ private onMessage;
221
+ private onClose;
222
+ private onError;
223
+ }
224
+ //#endregion
225
+ //#region lib/slack/obtain-slack-url.d.ts
226
+ type Props$2 = {
227
+ appToken: string;
228
+ onLog?: FlumeLogHandler;
229
+ deps: Pick<FlumeRuntimeDeps, "fetch" | "now">;
230
+ };
231
+ declare function obtainSlackUrl(props: Props$2): Promise<string | FlumeHttpError>;
232
+ //#endregion
233
+ //#region lib/github/github-poller.d.ts
234
+ type Deps = Pick<FlumeRuntimeDeps, "fetch" | "setInterval" | "clearInterval" | "now">;
235
+ type Props$1 = {
236
+ token: string;
237
+ interval: number;
238
+ onNotifications: (notifications: FlumeGitHubNotification[]) => void;
239
+ onConnected: () => void;
240
+ onDisconnected: (detail: string) => void;
241
+ onLog?: FlumeLogHandler;
242
+ deps: Deps;
243
+ };
244
+ declare class FlumeGitHubPoller {
245
+ private readonly props;
246
+ private readonly log;
247
+ private readonly cache;
248
+ private timer;
249
+ private since;
250
+ private bootstrapped;
251
+ stopped: boolean;
252
+ private consecutiveErrors;
253
+ constructor(props: Props$1);
254
+ start(): Promise<void>;
255
+ stop(): void;
256
+ private poll;
257
+ private processNotifications;
258
+ private safeFetch;
259
+ }
260
+ //#endregion
261
+ //#region lib/github/github-seen-cache.d.ts
262
+ type Props = {
263
+ maxSize: number;
264
+ };
265
+ declare class FlumeGitHubSeenCache {
266
+ private readonly props;
267
+ private seen;
268
+ constructor(props: Props);
269
+ has(id: string, updatedAt: string): boolean;
270
+ add(id: string, updatedAt: string): void;
271
+ trim(): void;
272
+ get size(): number;
273
+ }
274
+ //#endregion
275
+ //#region lib/index.d.ts
276
+ type FlumeSource = FlumeDiscordSource | FlumeSlackSource | FlumeGitHubSource;
277
+ //#endregion
278
+ export { Flume, FlumeConnectionError, FlumeDiscordGateway, FlumeDiscordGatewayIntents, FlumeDiscordGatewaySession, FlumeDiscordHeartbeat, FlumeDiscordSource, type FlumeDiscordSourceOptions, type FlumeEvent, type FlumeGatewayMessage, FlumeGatewayMessageSchema, type FlumeGitHubNotification, FlumeGitHubNotificationSchema, FlumeGitHubPoller, FlumeGitHubSeenCache, FlumeGitHubSource, type FlumeGitHubSourceOptions, type FlumeHandler, FlumeHttpError, type FlumeLog, type FlumeLogHandler, type FlumeLogInput, type FlumeLogLevel, FlumeLogger, FlumeParseError, type FlumeReconnectConfig, type FlumeReconnectOptions, FlumeReconnector, type FlumeRuntimeDeps, type FlumeSlackConnectionResponse, FlumeSlackConnectionResponseSchema, type FlumeSlackEnvelope, FlumeSlackEnvelopeSchema, FlumeSlackSocketMode, FlumeSlackSource, type FlumeSlackSourceOptions, FlumeSource, type FlumeSourceName, type FlumeSourceOptions, type FlumeStatus, type FlumeStatusHandler, type FlumeTimerHandle, createFlumeDefaultDeps, obtainSlackUrl, parseDiscordGatewayMessage, resolveFlumeReconnectConfig };
package/dist/index.js ADDED
@@ -0,0 +1,66 @@
1
+ import { a as FlumeSlackEnvelopeSchema, i as FlumeSlackConnectionResponseSchema, n as FlumeGatewayMessageSchema, r as FlumeGitHubNotificationSchema, t as FlumeLogger } from "./logger-B9E8zvgj.js";
2
+ import { a as FlumeParseError, i as resolveFlumeReconnectConfig, o as FlumeConnectionError, r as FlumeReconnector } from "./safe-json-parse-D8t_4Vm_.js";
3
+ import { i as FlumeHttpError, n as FlumeSlackSocketMode, r as obtainSlackUrl, t as FlumeSlackSource } from "./slack-source-CszepStG.js";
4
+ import { a as FlumeDiscordGatewaySession, i as parseDiscordGatewayMessage, n as FlumeDiscordGatewayIntents, o as FlumeDiscordHeartbeat, r as FlumeDiscordGateway, t as FlumeDiscordSource } from "./discord-source-Q4JRIbNs.js";
5
+ import { n as FlumeGitHubPoller, r as FlumeGitHubSeenCache, t as FlumeGitHubSource } from "./github-source-D7Z1RUbe.js";
6
+ //#region lib/deps.ts
7
+ function createFlumeDefaultDeps() {
8
+ return {
9
+ fetch: (url, init) => globalThis.fetch(url, init),
10
+ WebSocket: globalThis.WebSocket,
11
+ now: () => Date.now(),
12
+ random: () => Math.random(),
13
+ setTimeout: (fn, ms) => globalThis.setTimeout(fn, ms),
14
+ clearTimeout: (id) => globalThis.clearTimeout(id),
15
+ setInterval: (fn, ms) => globalThis.setInterval(fn, ms),
16
+ clearInterval: (id) => globalThis.clearInterval(id)
17
+ };
18
+ }
19
+ //#endregion
20
+ //#region lib/flume.ts
21
+ /**
22
+ * 共有設定を持つ DI コンテナ。各 Source に共通の deps / logging / reconnect を注入する
23
+ */
24
+ var Flume = class {
25
+ props;
26
+ resolvedDeps;
27
+ constructor(props) {
28
+ this.props = props;
29
+ this.resolvedDeps = {
30
+ ...createFlumeDefaultDeps(),
31
+ ...props.deps
32
+ };
33
+ }
34
+ discord(options) {
35
+ return new FlumeDiscordSource({
36
+ onLog: this.props.onLog,
37
+ onStatus: this.props.onStatus,
38
+ reconnect: this.props.reconnect,
39
+ signal: this.props.signal,
40
+ deps: this.resolvedDeps,
41
+ ...options
42
+ });
43
+ }
44
+ slack(options) {
45
+ return new FlumeSlackSource({
46
+ onLog: this.props.onLog,
47
+ onStatus: this.props.onStatus,
48
+ reconnect: this.props.reconnect,
49
+ signal: this.props.signal,
50
+ deps: this.resolvedDeps,
51
+ ...options
52
+ });
53
+ }
54
+ github(options) {
55
+ return new FlumeGitHubSource({
56
+ onLog: this.props.onLog,
57
+ onStatus: this.props.onStatus,
58
+ reconnect: this.props.reconnect,
59
+ signal: this.props.signal,
60
+ deps: this.resolvedDeps,
61
+ ...options
62
+ });
63
+ }
64
+ };
65
+ //#endregion
66
+ export { Flume, FlumeConnectionError, FlumeDiscordGateway, FlumeDiscordGatewayIntents, FlumeDiscordGatewaySession, FlumeDiscordHeartbeat, FlumeDiscordSource, FlumeGatewayMessageSchema, FlumeGitHubNotificationSchema, FlumeGitHubPoller, FlumeGitHubSeenCache, FlumeGitHubSource, FlumeHttpError, FlumeLogger, FlumeParseError, FlumeReconnector, FlumeSlackConnectionResponseSchema, FlumeSlackEnvelopeSchema, FlumeSlackSocketMode, FlumeSlackSource, createFlumeDefaultDeps, obtainSlackUrl, parseDiscordGatewayMessage, resolveFlumeReconnectConfig };