@interactive-inc/flume 0.1.0 → 0.2.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 +98 -46
- package/dist/connection-error-BOk97djj.d.ts +6 -0
- package/dist/discord.d.ts +111 -4
- package/dist/discord.js +537 -2
- package/dist/github.d.ts +50 -4
- package/dist/github.js +307 -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 +48 -220
- package/dist/index.js +90 -52
- package/dist/logger-CpGB9WO_.js +49 -0
- package/dist/parse-error-BAiCLRmk.d.ts +6 -0
- package/dist/safe-fetch-30ZzOKHL.js +20 -0
- package/dist/safe-json-parse-WCg_x1JS.js +15 -0
- package/dist/{safe-json-parse-D8t_4Vm_.js → schedule-reconnect-DSxZJG3h.js} +24 -12
- package/dist/serial-queue-ExmlnpzQ.js +16 -0
- package/dist/slack.d.ts +65 -4
- package/dist/slack.js +443 -2
- package/dist/{types-BVQSU336.d.ts → types-tnOPBc1p.d.ts} +32 -16
- 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,307 @@
|
|
|
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 /* @__PURE__ */ new Error("GitHub source: signal already aborted");
|
|
233
|
+
this.options.signal?.addEventListener("abort", () => this.stop(), { once: true });
|
|
234
|
+
this.log.info({
|
|
235
|
+
action: "start",
|
|
236
|
+
message: "starting GitHub source"
|
|
237
|
+
});
|
|
238
|
+
this.setStatus("connecting");
|
|
239
|
+
this.poller = new FlumeGitHubPoller({
|
|
240
|
+
token: this.options.token,
|
|
241
|
+
interval: this.options.pollInterval ?? 60,
|
|
242
|
+
onLog: this.options.onLog,
|
|
243
|
+
deps: this.deps,
|
|
244
|
+
onNotifications: (notifications) => this.handleNotifications(handler, notifications),
|
|
245
|
+
onConnected: () => this.setStatus("connected"),
|
|
246
|
+
onDisconnected: (detail) => this.setStatus("disconnected", detail)
|
|
247
|
+
});
|
|
248
|
+
try {
|
|
249
|
+
await this.poller.start();
|
|
250
|
+
} catch (error) {
|
|
251
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
252
|
+
this.log.error({
|
|
253
|
+
action: "start.failed",
|
|
254
|
+
message: err.message,
|
|
255
|
+
error: err
|
|
256
|
+
});
|
|
257
|
+
this.setStatus("disconnected");
|
|
258
|
+
return err;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
async stop() {
|
|
262
|
+
this.log.info({
|
|
263
|
+
action: "stop",
|
|
264
|
+
message: "stopping GitHub source"
|
|
265
|
+
});
|
|
266
|
+
this.poller?.stop();
|
|
267
|
+
this.poller = null;
|
|
268
|
+
await this.queue.drain();
|
|
269
|
+
this.setStatus("disconnected");
|
|
270
|
+
}
|
|
271
|
+
status() {
|
|
272
|
+
return this.currentStatus;
|
|
273
|
+
}
|
|
274
|
+
handleNotifications(handler, notifications) {
|
|
275
|
+
for (const notification of notifications) {
|
|
276
|
+
const event = {
|
|
277
|
+
source: "github",
|
|
278
|
+
type: "notification",
|
|
279
|
+
data: notification,
|
|
280
|
+
meta: extractGitHubMeta(notification),
|
|
281
|
+
receivedAt: this.deps.now()
|
|
282
|
+
};
|
|
283
|
+
this.queue.add(async () => {
|
|
284
|
+
try {
|
|
285
|
+
await handler(event);
|
|
286
|
+
} catch (err) {
|
|
287
|
+
this.log.error({
|
|
288
|
+
action: "handler.error",
|
|
289
|
+
message: "user handler threw",
|
|
290
|
+
error: err instanceof Error ? err : new Error(String(err))
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
setStatus(next, detail) {
|
|
297
|
+
if (this.currentStatus === next) return;
|
|
298
|
+
this.log.info({
|
|
299
|
+
action: "status",
|
|
300
|
+
message: `${this.currentStatus} → ${next}${detail ? ` (${detail})` : ""}`
|
|
301
|
+
});
|
|
302
|
+
this.currentStatus = next;
|
|
303
|
+
this.options.onStatus?.(next, detail);
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
//#endregion
|
|
307
|
+
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 FlumeTimerHandle, S 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, x as FlumeStatus, y as FlumeSourceOptions } from "./types-tnOPBc1p.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$5 = {
|
|
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$5);
|
|
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$4 = {
|
|
50
30
|
maxAttempts: number;
|
|
51
31
|
baseDelay: number;
|
|
52
32
|
maxDelay: number;
|
|
@@ -57,222 +37,70 @@ declare class FlumeReconnector {
|
|
|
57
37
|
attempt: number;
|
|
58
38
|
aborted: boolean;
|
|
59
39
|
private timer;
|
|
60
|
-
constructor(props: Props$
|
|
40
|
+
constructor(props: Props$4);
|
|
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/
|
|
68
|
-
type Props$
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
deps?: Partial<FlumeRuntimeDeps>;
|
|
47
|
+
//#region lib/schedule-reconnect.d.ts
|
|
48
|
+
type Props$3 = {
|
|
49
|
+
reconnector: FlumeReconnector | null;
|
|
50
|
+
log: FlumeLogger;
|
|
51
|
+
setStatus: (status: FlumeStatus) => void;
|
|
52
|
+
retry: () => void;
|
|
74
53
|
};
|
|
75
54
|
/**
|
|
76
|
-
*
|
|
55
|
+
* 接続が落ちた際の共通再接続スケジューラ。reconnector の状態を見て次回試行を予約し、
|
|
56
|
+
* 試行回数が尽きていれば disconnected に落とす
|
|
77
57
|
*/
|
|
78
|
-
declare
|
|
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
|
-
}
|
|
58
|
+
declare function scheduleFlumeReconnect(props: Props$3): void;
|
|
95
59
|
//#endregion
|
|
96
|
-
//#region lib/
|
|
97
|
-
|
|
98
|
-
|
|
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;
|
|
60
|
+
//#region lib/flume-stopped.d.ts
|
|
61
|
+
type Props$2 = {
|
|
62
|
+
finalStatuses: ReadonlyArray<FlumeSourceStatus>;
|
|
206
63
|
};
|
|
207
|
-
|
|
64
|
+
/**
|
|
65
|
+
* 停止済みの終端状態。最終ステータスのスナップショットのみ観測できる
|
|
66
|
+
*/
|
|
67
|
+
declare class FlumeStopped {
|
|
208
68
|
private readonly props;
|
|
209
|
-
|
|
210
|
-
|
|
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;
|
|
69
|
+
constructor(props: Props$2);
|
|
70
|
+
statuses(): ReadonlyArray<FlumeSourceStatus>;
|
|
223
71
|
}
|
|
224
72
|
//#endregion
|
|
225
|
-
//#region lib/
|
|
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">;
|
|
73
|
+
//#region lib/flume-running.d.ts
|
|
235
74
|
type Props$1 = {
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
onNotifications: (notifications: FlumeGitHubNotification[]) => void;
|
|
239
|
-
onConnected: () => void;
|
|
240
|
-
onDisconnected: (detail: string) => void;
|
|
241
|
-
onLog?: FlumeLogHandler;
|
|
242
|
-
deps: Deps;
|
|
75
|
+
sources: ReadonlyArray<FlumeSource>;
|
|
76
|
+
signal?: AbortSignal;
|
|
243
77
|
};
|
|
244
|
-
|
|
78
|
+
/**
|
|
79
|
+
* 稼働中の Flume。stop() で FlumeStopped へ遷移する。signal が abort されると自動 stop
|
|
80
|
+
*/
|
|
81
|
+
declare class FlumeRunning {
|
|
245
82
|
private readonly props;
|
|
246
|
-
private
|
|
247
|
-
private readonly
|
|
248
|
-
private timer;
|
|
249
|
-
private since;
|
|
250
|
-
private bootstrapped;
|
|
251
|
-
stopped: boolean;
|
|
252
|
-
private consecutiveErrors;
|
|
83
|
+
private stopPromise;
|
|
84
|
+
private readonly onAbort;
|
|
253
85
|
constructor(props: Props$1);
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
private
|
|
257
|
-
private processNotifications;
|
|
258
|
-
private safeFetch;
|
|
86
|
+
stop(): Promise<FlumeStopped>;
|
|
87
|
+
statuses(): ReadonlyArray<FlumeSourceStatus>;
|
|
88
|
+
private runStop;
|
|
259
89
|
}
|
|
260
90
|
//#endregion
|
|
261
|
-
//#region lib/
|
|
91
|
+
//#region lib/flume.d.ts
|
|
262
92
|
type Props = {
|
|
263
|
-
|
|
93
|
+
sources: ReadonlyArray<FlumeSource>;
|
|
94
|
+
signal?: AbortSignal;
|
|
264
95
|
};
|
|
265
|
-
|
|
96
|
+
/**
|
|
97
|
+
* 起動前の Flume。start() で FlumeRunning へ遷移する
|
|
98
|
+
*/
|
|
99
|
+
declare class Flume {
|
|
266
100
|
private readonly props;
|
|
267
|
-
private
|
|
101
|
+
private consumed;
|
|
268
102
|
constructor(props: Props);
|
|
269
|
-
|
|
270
|
-
add(id: string, updatedAt: string): void;
|
|
271
|
-
trim(): void;
|
|
272
|
-
get size(): number;
|
|
103
|
+
start(handler: FlumeHandler): Promise<FlumeRunning | Error>;
|
|
273
104
|
}
|
|
274
105
|
//#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 };
|
|
106
|
+
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 FlumeStatus, type FlumeStatusHandler, FlumeStopped, type FlumeTimerHandle, createFlumeDefaultDeps, resolveFlumeReconnectConfig, scheduleFlumeReconnect };
|