@interactive-inc/flume 0.1.0 → 0.3.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 +107 -48
- package/dist/connection-error-BOk97djj.d.ts +6 -0
- package/dist/discord.d.ts +111 -4
- package/dist/discord.js +546 -2
- package/dist/github.d.ts +50 -4
- package/dist/github.js +314 -2
- package/dist/http-error-BtXonO-W.js +12 -0
- package/dist/http-error-K-Ym4lfK.d.ts +11 -0
- package/dist/index.d.ts +39 -222
- package/dist/index.js +107 -52
- package/dist/logger-CpGB9WO_.js +49 -0
- package/dist/parse-error-BAiCLRmk.d.ts +6 -0
- package/dist/{safe-json-parse-D8t_4Vm_.js → reconnector-BDoJ1xNX.js} +1 -15
- package/dist/safe-fetch-30ZzOKHL.js +20 -0
- package/dist/safe-json-parse-BWlzGOLl.js +41 -0
- package/dist/serial-queue-ExmlnpzQ.js +16 -0
- package/dist/slack.d.ts +65 -4
- package/dist/slack.js +452 -2
- package/dist/{types-BVQSU336.d.ts → types-Bm9uKUQz.d.ts} +48 -17
- package/package.json +1 -1
- package/dist/discord-source-Q4JRIbNs.js +0 -525
- package/dist/github-source-D7Z1RUbe.js +0 -280
- package/dist/logger-B9E8zvgj.js +0 -69
- package/dist/slack-source-CszepStG.js +0 -400
package/dist/github.js
CHANGED
|
@@ -1,2 +1,314 @@
|
|
|
1
|
-
import { t as
|
|
2
|
-
|
|
1
|
+
import { n as createFlumeDefaultDeps, t as FlumeLogger } from "./logger-CpGB9WO_.js";
|
|
2
|
+
import { t as FlumeSerialQueue } from "./serial-queue-ExmlnpzQ.js";
|
|
3
|
+
import { t as safeFetch } from "./safe-fetch-30ZzOKHL.js";
|
|
4
|
+
import { z } from "zod/v4";
|
|
5
|
+
//#region lib/github/extract-github-meta.ts
|
|
6
|
+
function extractGitHubMeta(notification) {
|
|
7
|
+
return {
|
|
8
|
+
event_type: "notification",
|
|
9
|
+
reason: notification.reason,
|
|
10
|
+
subject_type: notification.subject.type,
|
|
11
|
+
repository: notification.repository.full_name,
|
|
12
|
+
thread_id: notification.id
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region lib/github/github-notification-schema.ts
|
|
17
|
+
const FlumeGitHubNotificationSchema = z.object({
|
|
18
|
+
id: z.string(),
|
|
19
|
+
reason: z.string(),
|
|
20
|
+
unread: z.boolean(),
|
|
21
|
+
updated_at: z.string(),
|
|
22
|
+
subject: z.object({
|
|
23
|
+
title: z.string(),
|
|
24
|
+
url: z.string().nullable(),
|
|
25
|
+
type: z.string()
|
|
26
|
+
}),
|
|
27
|
+
repository: z.object({ full_name: z.string() })
|
|
28
|
+
});
|
|
29
|
+
//#endregion
|
|
30
|
+
//#region lib/github/github-seen-cache.ts
|
|
31
|
+
var FlumeGitHubSeenCache = class {
|
|
32
|
+
props;
|
|
33
|
+
seen = /* @__PURE__ */ new Map();
|
|
34
|
+
constructor(props) {
|
|
35
|
+
this.props = props;
|
|
36
|
+
}
|
|
37
|
+
has(id, updatedAt) {
|
|
38
|
+
return this.seen.get(id) === updatedAt;
|
|
39
|
+
}
|
|
40
|
+
add(id, updatedAt) {
|
|
41
|
+
this.seen.set(id, updatedAt);
|
|
42
|
+
}
|
|
43
|
+
trim() {
|
|
44
|
+
if (this.seen.size <= this.props.maxSize) return;
|
|
45
|
+
const entries = [...this.seen.entries()];
|
|
46
|
+
this.seen = new Map(entries.slice(entries.length - this.props.maxSize));
|
|
47
|
+
}
|
|
48
|
+
get size() {
|
|
49
|
+
return this.seen.size;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
//#endregion
|
|
53
|
+
//#region lib/github/github-poller.ts
|
|
54
|
+
var FlumeGitHubPoller = class {
|
|
55
|
+
props;
|
|
56
|
+
log;
|
|
57
|
+
cache = new FlumeGitHubSeenCache({ maxSize: 5e3 });
|
|
58
|
+
timer = null;
|
|
59
|
+
since = null;
|
|
60
|
+
bootstrapped = false;
|
|
61
|
+
stopped = false;
|
|
62
|
+
consecutiveErrors = 0;
|
|
63
|
+
constructor(props) {
|
|
64
|
+
this.props = props;
|
|
65
|
+
this.log = new FlumeLogger({
|
|
66
|
+
source: "github.poller",
|
|
67
|
+
handler: props.onLog,
|
|
68
|
+
deps: props.deps
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
async start() {
|
|
72
|
+
this.stopped = false;
|
|
73
|
+
this.log.info({
|
|
74
|
+
action: "start",
|
|
75
|
+
message: `polling every ${this.props.interval}s`
|
|
76
|
+
});
|
|
77
|
+
await this.poll();
|
|
78
|
+
this.timer = this.props.deps.setInterval(() => {
|
|
79
|
+
this.poll().catch((err) => {
|
|
80
|
+
this.log.error({
|
|
81
|
+
action: "poll.unhandled",
|
|
82
|
+
message: "unexpected error in poll loop",
|
|
83
|
+
error: err instanceof Error ? err : new Error(String(err))
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
}, this.props.interval * 1e3);
|
|
87
|
+
}
|
|
88
|
+
stop() {
|
|
89
|
+
this.log.info({
|
|
90
|
+
action: "stop",
|
|
91
|
+
message: "stopping poller"
|
|
92
|
+
});
|
|
93
|
+
this.stopped = true;
|
|
94
|
+
if (this.timer !== null) {
|
|
95
|
+
this.props.deps.clearInterval(this.timer);
|
|
96
|
+
this.timer = null;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
async poll() {
|
|
100
|
+
const params = new URLSearchParams({ all: "false" });
|
|
101
|
+
if (this.since) params.set("since", this.since);
|
|
102
|
+
const url = `https://api.github.com/notifications?${params}`;
|
|
103
|
+
this.log.debug({
|
|
104
|
+
action: "http.request",
|
|
105
|
+
message: `GET ${url}`
|
|
106
|
+
});
|
|
107
|
+
const response = await this.safeFetch(url);
|
|
108
|
+
if (response instanceof Error) return;
|
|
109
|
+
this.log.debug({
|
|
110
|
+
action: "http.response",
|
|
111
|
+
message: `GET ${response.status}`,
|
|
112
|
+
detail: {
|
|
113
|
+
status: response.status,
|
|
114
|
+
url
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
if (!response.ok) {
|
|
118
|
+
this.consecutiveErrors++;
|
|
119
|
+
this.log.error({
|
|
120
|
+
action: "http.error",
|
|
121
|
+
message: `HTTP ${response.status} (consecutive=${this.consecutiveErrors})`
|
|
122
|
+
});
|
|
123
|
+
if (this.consecutiveErrors >= 3) this.props.onDisconnected(`HTTP ${response.status}`);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
this.consecutiveErrors = 0;
|
|
127
|
+
const body = await response.json();
|
|
128
|
+
if (!Array.isArray(body)) {
|
|
129
|
+
this.log.warn({
|
|
130
|
+
action: "http.body",
|
|
131
|
+
message: "response body is not an array, dropping",
|
|
132
|
+
detail: { bodyType: typeof body }
|
|
133
|
+
});
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
this.processNotifications(body);
|
|
137
|
+
}
|
|
138
|
+
processNotifications(raw) {
|
|
139
|
+
let dropped = 0;
|
|
140
|
+
const notifications = raw.flatMap((item) => {
|
|
141
|
+
const parsed = FlumeGitHubNotificationSchema.safeParse(item);
|
|
142
|
+
if (!parsed.success) {
|
|
143
|
+
dropped++;
|
|
144
|
+
this.log.warn({
|
|
145
|
+
action: "parse.skip",
|
|
146
|
+
message: "notification did not match schema",
|
|
147
|
+
detail: { issues: parsed.error.issues.map((i) => ({
|
|
148
|
+
path: i.path,
|
|
149
|
+
message: i.message
|
|
150
|
+
})) }
|
|
151
|
+
});
|
|
152
|
+
return [];
|
|
153
|
+
}
|
|
154
|
+
return [parsed.data];
|
|
155
|
+
});
|
|
156
|
+
if (dropped > 0) this.log.warn({
|
|
157
|
+
action: "parse.summary",
|
|
158
|
+
message: `${dropped}/${raw.length} notifications dropped by schema`
|
|
159
|
+
});
|
|
160
|
+
if (!this.bootstrapped) {
|
|
161
|
+
this.bootstrapped = true;
|
|
162
|
+
for (const notification of notifications) this.cache.add(notification.id, notification.updated_at);
|
|
163
|
+
this.since = new Date(this.props.deps.now()).toISOString();
|
|
164
|
+
this.log.info({
|
|
165
|
+
action: "bootstrap",
|
|
166
|
+
message: `seeded ${notifications.length} existing notifications`
|
|
167
|
+
});
|
|
168
|
+
this.props.onConnected();
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const fresh = [];
|
|
172
|
+
for (const notification of notifications) {
|
|
173
|
+
if (this.cache.has(notification.id, notification.updated_at)) continue;
|
|
174
|
+
this.cache.add(notification.id, notification.updated_at);
|
|
175
|
+
fresh.push(notification);
|
|
176
|
+
}
|
|
177
|
+
this.cache.trim();
|
|
178
|
+
this.since = new Date(this.props.deps.now()).toISOString();
|
|
179
|
+
if (fresh.length > 0) {
|
|
180
|
+
this.log.info({
|
|
181
|
+
action: "poll.fresh",
|
|
182
|
+
message: `${fresh.length} new notifications`
|
|
183
|
+
});
|
|
184
|
+
this.props.onNotifications(fresh);
|
|
185
|
+
} else this.log.debug({
|
|
186
|
+
action: "poll.idle",
|
|
187
|
+
message: "0 new notifications"
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
async safeFetch(url) {
|
|
191
|
+
const result = await safeFetch({
|
|
192
|
+
fetch: this.props.deps.fetch,
|
|
193
|
+
url,
|
|
194
|
+
init: { headers: {
|
|
195
|
+
Authorization: `Bearer ${this.props.token}`,
|
|
196
|
+
Accept: "application/vnd.github+json",
|
|
197
|
+
"X-GitHub-Api-Version": "2022-11-28"
|
|
198
|
+
} },
|
|
199
|
+
log: this.log
|
|
200
|
+
});
|
|
201
|
+
if (result instanceof Error) {
|
|
202
|
+
this.consecutiveErrors++;
|
|
203
|
+
this.log.warn({
|
|
204
|
+
action: "http.error",
|
|
205
|
+
message: `consecutive=${this.consecutiveErrors}`
|
|
206
|
+
});
|
|
207
|
+
if (this.consecutiveErrors >= 3) this.props.onDisconnected("network error");
|
|
208
|
+
}
|
|
209
|
+
return result;
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
//#endregion
|
|
213
|
+
//#region lib/github/github-source.ts
|
|
214
|
+
var FlumeGitHubSource = class {
|
|
215
|
+
options;
|
|
216
|
+
name = "github";
|
|
217
|
+
poller = null;
|
|
218
|
+
currentStatus = "disconnected";
|
|
219
|
+
log;
|
|
220
|
+
deps;
|
|
221
|
+
queue = new FlumeSerialQueue();
|
|
222
|
+
constructor(options) {
|
|
223
|
+
this.options = options;
|
|
224
|
+
this.deps = options.deps ?? createFlumeDefaultDeps();
|
|
225
|
+
this.log = new FlumeLogger({
|
|
226
|
+
source: "github",
|
|
227
|
+
handler: options.onLog,
|
|
228
|
+
deps: this.deps
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
async start(handler) {
|
|
232
|
+
if (this.options.signal?.aborted) return {
|
|
233
|
+
ok: false,
|
|
234
|
+
error: /* @__PURE__ */ new Error("GitHub source: signal already aborted")
|
|
235
|
+
};
|
|
236
|
+
this.options.signal?.addEventListener("abort", () => this.stop(), { once: true });
|
|
237
|
+
this.log.info({
|
|
238
|
+
action: "start",
|
|
239
|
+
message: "starting GitHub source"
|
|
240
|
+
});
|
|
241
|
+
this.setStatus("connecting");
|
|
242
|
+
this.poller = new FlumeGitHubPoller({
|
|
243
|
+
token: this.options.token,
|
|
244
|
+
interval: this.options.pollInterval ?? 60,
|
|
245
|
+
onLog: this.options.onLog,
|
|
246
|
+
deps: this.deps,
|
|
247
|
+
onNotifications: (notifications) => this.handleNotifications(handler, notifications),
|
|
248
|
+
onConnected: () => this.setStatus("connected"),
|
|
249
|
+
onDisconnected: (detail) => this.setStatus("disconnected", detail)
|
|
250
|
+
});
|
|
251
|
+
try {
|
|
252
|
+
await this.poller.start();
|
|
253
|
+
} catch (error) {
|
|
254
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
255
|
+
this.log.error({
|
|
256
|
+
action: "start.failed",
|
|
257
|
+
message: err.message,
|
|
258
|
+
error: err
|
|
259
|
+
});
|
|
260
|
+
this.setStatus("disconnected");
|
|
261
|
+
return {
|
|
262
|
+
ok: false,
|
|
263
|
+
error: err
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
return { ok: true };
|
|
267
|
+
}
|
|
268
|
+
async stop() {
|
|
269
|
+
this.log.info({
|
|
270
|
+
action: "stop",
|
|
271
|
+
message: "stopping GitHub source"
|
|
272
|
+
});
|
|
273
|
+
this.poller?.stop();
|
|
274
|
+
this.poller = null;
|
|
275
|
+
await this.queue.drain();
|
|
276
|
+
this.setStatus("disconnected");
|
|
277
|
+
}
|
|
278
|
+
status() {
|
|
279
|
+
return this.currentStatus;
|
|
280
|
+
}
|
|
281
|
+
handleNotifications(handler, notifications) {
|
|
282
|
+
for (const notification of notifications) {
|
|
283
|
+
const event = {
|
|
284
|
+
source: "github",
|
|
285
|
+
type: "notification",
|
|
286
|
+
data: notification,
|
|
287
|
+
meta: extractGitHubMeta(notification),
|
|
288
|
+
receivedAt: this.deps.now()
|
|
289
|
+
};
|
|
290
|
+
this.queue.add(async () => {
|
|
291
|
+
try {
|
|
292
|
+
await handler(event);
|
|
293
|
+
} catch (err) {
|
|
294
|
+
this.log.error({
|
|
295
|
+
action: "handler.error",
|
|
296
|
+
message: "user handler threw",
|
|
297
|
+
error: err instanceof Error ? err : new Error(String(err))
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
setStatus(next, detail) {
|
|
304
|
+
if (this.currentStatus === next) return;
|
|
305
|
+
this.log.info({
|
|
306
|
+
action: "status",
|
|
307
|
+
message: `${this.currentStatus} → ${next}${detail ? ` (${detail})` : ""}`
|
|
308
|
+
});
|
|
309
|
+
this.currentStatus = next;
|
|
310
|
+
this.options.onStatus?.(next, detail);
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
//#endregion
|
|
314
|
+
export { FlumeGitHubNotificationSchema, FlumeGitHubPoller, FlumeGitHubSeenCache, FlumeGitHubSource, extractGitHubMeta };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region lib/errors/http-error.ts
|
|
2
|
+
var FlumeHttpError = class extends Error {
|
|
3
|
+
status;
|
|
4
|
+
constructor(props) {
|
|
5
|
+
super(props.message);
|
|
6
|
+
this.name = "FlumeHttpError";
|
|
7
|
+
this.status = props.status;
|
|
8
|
+
Object.freeze(this);
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
//#endregion
|
|
12
|
+
export { FlumeHttpError as t };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,40 +1,20 @@
|
|
|
1
|
-
import { C as
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { C as FlumeStartResult, E as FlumeTimerHandle, S as FlumeStartOk, T as FlumeStatusHandler, _ as FlumeSource, a as FlumeGitHubSourceOptions, b as FlumeSourceStatus, 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 FlumeSourceName, w as FlumeStatus, x as FlumeStartErr, y as FlumeSourceOptions } from "./types-Bm9uKUQz.js";
|
|
2
|
+
import { t as FlumeConnectionError } from "./connection-error-BOk97djj.js";
|
|
3
|
+
import { t as FlumeParseError } from "./parse-error-BAiCLRmk.js";
|
|
4
|
+
import { t as FlumeHttpError } from "./http-error-K-Ym4lfK.js";
|
|
5
5
|
|
|
6
6
|
//#region lib/deps.d.ts
|
|
7
7
|
declare function createFlumeDefaultDeps(): FlumeRuntimeDeps;
|
|
8
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
9
|
//#region lib/logger.d.ts
|
|
30
|
-
type Props$
|
|
10
|
+
type Props$4 = {
|
|
31
11
|
source: string;
|
|
32
12
|
handler?: FlumeLogHandler;
|
|
33
13
|
deps: Pick<FlumeRuntimeDeps, "now">;
|
|
34
14
|
};
|
|
35
15
|
declare class FlumeLogger {
|
|
36
16
|
private readonly props;
|
|
37
|
-
constructor(props: Props$
|
|
17
|
+
constructor(props: Props$4);
|
|
38
18
|
debug(entry: FlumeLogInput): void;
|
|
39
19
|
info(entry: FlumeLogInput): void;
|
|
40
20
|
warn(entry: FlumeLogInput): void;
|
|
@@ -46,7 +26,7 @@ declare class FlumeLogger {
|
|
|
46
26
|
declare function resolveFlumeReconnectConfig(input: boolean | FlumeReconnectOptions | undefined): FlumeReconnectConfig | null;
|
|
47
27
|
//#endregion
|
|
48
28
|
//#region lib/reconnector.d.ts
|
|
49
|
-
type Props$
|
|
29
|
+
type Props$3 = {
|
|
50
30
|
maxAttempts: number;
|
|
51
31
|
baseDelay: number;
|
|
52
32
|
maxDelay: number;
|
|
@@ -57,222 +37,59 @@ declare class FlumeReconnector {
|
|
|
57
37
|
attempt: number;
|
|
58
38
|
aborted: boolean;
|
|
59
39
|
private timer;
|
|
60
|
-
constructor(props: Props$
|
|
40
|
+
constructor(props: Props$3);
|
|
61
41
|
schedule(fn: () => void): number;
|
|
62
42
|
reset(): void;
|
|
63
43
|
cancel(): void;
|
|
64
44
|
private nextDelay;
|
|
65
45
|
}
|
|
66
46
|
//#endregion
|
|
67
|
-
//#region lib/flume.d.ts
|
|
68
|
-
type Props$
|
|
69
|
-
|
|
70
|
-
onStatus?: FlumeStatusHandler;
|
|
71
|
-
reconnect?: boolean | FlumeReconnectOptions;
|
|
72
|
-
signal?: AbortSignal;
|
|
73
|
-
deps?: Partial<FlumeRuntimeDeps>;
|
|
47
|
+
//#region lib/flume-stopped.d.ts
|
|
48
|
+
type Props$2 = {
|
|
49
|
+
finalStatuses: ReadonlyArray<FlumeSourceStatus>;
|
|
74
50
|
};
|
|
75
51
|
/**
|
|
76
|
-
*
|
|
52
|
+
* 停止済みの終端状態。最終ステータスのスナップショットのみ観測できる
|
|
77
53
|
*/
|
|
78
|
-
declare class
|
|
54
|
+
declare class FlumeStopped {
|
|
79
55
|
private readonly props;
|
|
80
|
-
|
|
81
|
-
|
|
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;
|
|
56
|
+
constructor(props: Props$2);
|
|
57
|
+
statuses(): ReadonlyArray<FlumeSourceStatus>;
|
|
137
58
|
}
|
|
138
59
|
//#endregion
|
|
139
|
-
//#region lib/
|
|
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">;
|
|
60
|
+
//#region lib/flume-running.d.ts
|
|
235
61
|
type Props$1 = {
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
onNotifications: (notifications: FlumeGitHubNotification[]) => void;
|
|
239
|
-
onConnected: () => void;
|
|
240
|
-
onDisconnected: (detail: string) => void;
|
|
241
|
-
onLog?: FlumeLogHandler;
|
|
242
|
-
deps: Deps;
|
|
62
|
+
sources: ReadonlyArray<FlumeSource>;
|
|
63
|
+
signal?: AbortSignal;
|
|
243
64
|
};
|
|
244
|
-
|
|
65
|
+
/**
|
|
66
|
+
* 稼働中の Flume。stop() で FlumeStopped へ遷移する。signal が abort されると自動 stop
|
|
67
|
+
*/
|
|
68
|
+
declare class FlumeRunning {
|
|
245
69
|
private readonly props;
|
|
246
|
-
private
|
|
247
|
-
private readonly
|
|
248
|
-
private timer;
|
|
249
|
-
private since;
|
|
250
|
-
private bootstrapped;
|
|
251
|
-
stopped: boolean;
|
|
252
|
-
private consecutiveErrors;
|
|
70
|
+
private stopPromise;
|
|
71
|
+
private readonly onAbort;
|
|
253
72
|
constructor(props: Props$1);
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
private
|
|
257
|
-
private processNotifications;
|
|
258
|
-
private safeFetch;
|
|
73
|
+
stop(): Promise<FlumeStopped>;
|
|
74
|
+
statuses(): ReadonlyArray<FlumeSourceStatus>;
|
|
75
|
+
private runStop;
|
|
259
76
|
}
|
|
260
77
|
//#endregion
|
|
261
|
-
//#region lib/
|
|
78
|
+
//#region lib/flume.d.ts
|
|
262
79
|
type Props = {
|
|
263
|
-
|
|
80
|
+
sources: ReadonlyArray<FlumeSource>;
|
|
81
|
+
signal?: AbortSignal;
|
|
264
82
|
};
|
|
265
|
-
|
|
83
|
+
/**
|
|
84
|
+
* 起動前の Flume。start() で FlumeRunning へ遷移する
|
|
85
|
+
*/
|
|
86
|
+
declare class Flume {
|
|
266
87
|
private readonly props;
|
|
267
|
-
private
|
|
88
|
+
private consumed;
|
|
268
89
|
constructor(props: Props);
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
get size(): number;
|
|
90
|
+
start(handler: FlumeHandler): Promise<FlumeStartResult>;
|
|
91
|
+
private running;
|
|
92
|
+
runningState(): FlumeRunning | null;
|
|
273
93
|
}
|
|
274
94
|
//#endregion
|
|
275
|
-
|
|
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 };
|
|
95
|
+
export { Flume, FlumeConnectionError, type FlumeDiscordSourceOptions, type FlumeEvent, type FlumeGatewayMessage, type FlumeGitHubNotification, type FlumeGitHubSourceOptions, type FlumeHandler, FlumeHttpError, type FlumeLog, type FlumeLogHandler, type FlumeLogInput, type FlumeLogLevel, FlumeLogger, FlumeParseError, type FlumeReconnectConfig, type FlumeReconnectOptions, FlumeReconnector, FlumeRunning, type FlumeRuntimeDeps, type FlumeSlackConnectionResponse, type FlumeSlackEnvelope, type FlumeSlackSourceOptions, type FlumeSource, type FlumeSourceName, type FlumeSourceOptions, type FlumeSourceStatus, type FlumeStartErr, type FlumeStartOk, type FlumeStartResult, type FlumeStatus, type FlumeStatusHandler, FlumeStopped, type FlumeTimerHandle, createFlumeDefaultDeps, resolveFlumeReconnectConfig };
|