@interactive-inc/flume 0.4.0 → 0.6.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 +129 -86
- package/dist/discord.d.ts +5 -13
- package/dist/discord.js +46 -107
- package/dist/flume-source-DUvt9aJt.js +341 -0
- package/dist/flume-source-DuUFPhSe.d.ts +228 -0
- package/dist/github.d.ts +4 -12
- package/dist/github.js +24 -84
- package/dist/index.d.ts +26 -38
- package/dist/index.js +92 -18
- package/dist/safe-json-parse-CfJjt-RY.js +11 -0
- package/dist/{safe-read-text-DgrJ4Uhl.js → safe-read-text-JQd_5vbd.js} +1 -1
- package/dist/{safe-stringify-BWS-uXZP.js → safe-stringify-DbWQw9qe.js} +2 -17
- package/dist/slack.d.ts +5 -13
- package/dist/slack.js +56 -114
- package/package.json +2 -1
- package/dist/safe-invoke-callback-EpWXwfwp.js +0 -170
- package/dist/serial-queue-B9LoBc64.js +0 -162
- package/dist/types-D-tO-Mh2.d.ts +0 -154
package/dist/github.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { c as safeNormalizeError, i as safeNow, l as safeErrorMessage, o as FlumeParseError, r as FlumeLogger, s as attempt, t as FlumeSource } from "./flume-source-DUvt9aJt.js";
|
|
2
2
|
import { t as FlumeHttpError } from "./http-error-CPSKoSie.js";
|
|
3
|
-
import {
|
|
4
|
-
import { t as safeReadText } from "./safe-read-text-
|
|
3
|
+
import { t as safeJsonParse } from "./safe-json-parse-CfJjt-RY.js";
|
|
4
|
+
import { t as safeReadText } from "./safe-read-text-JQd_5vbd.js";
|
|
5
5
|
import { z } from "zod/v4";
|
|
6
6
|
//#region lib/github/extract-github-meta.ts
|
|
7
7
|
function flumeExtractGitHubMeta(notification) {
|
|
@@ -447,115 +447,55 @@ var FlumeGitHubPoller = class {
|
|
|
447
447
|
};
|
|
448
448
|
//#endregion
|
|
449
449
|
//#region lib/github/github-source.ts
|
|
450
|
-
var FlumeGitHubSource = class {
|
|
450
|
+
var FlumeGitHubSource = class extends FlumeSource {
|
|
451
451
|
options;
|
|
452
452
|
name = "github";
|
|
453
453
|
poller = null;
|
|
454
|
-
handler = null;
|
|
455
|
-
log;
|
|
456
|
-
deps;
|
|
457
|
-
queue = new FlumeSerialQueue();
|
|
458
|
-
signals;
|
|
459
|
-
statusEmitter;
|
|
460
|
-
onSignalAbort = () => {
|
|
461
|
-
safeInvokeCallback({
|
|
462
|
-
fn: () => this.stop(),
|
|
463
|
-
onError: (error) => {
|
|
464
|
-
this.log.error({
|
|
465
|
-
action: "signal.abort.stop.failed",
|
|
466
|
-
message: safeErrorMessage({ error }),
|
|
467
|
-
error
|
|
468
|
-
});
|
|
469
|
-
}
|
|
470
|
-
});
|
|
471
|
-
};
|
|
472
454
|
constructor(options) {
|
|
455
|
+
super();
|
|
473
456
|
this.options = options;
|
|
474
|
-
this.deps = options.deps ?? createFlumeDefaultDeps();
|
|
475
|
-
this.log = new FlumeLogger({
|
|
476
|
-
source: "github",
|
|
477
|
-
handler: options.onLog,
|
|
478
|
-
deps: this.deps
|
|
479
|
-
});
|
|
480
|
-
this.signals = new FlumeSignalRegistry({
|
|
481
|
-
log: this.log,
|
|
482
|
-
onAbort: this.onSignalAbort
|
|
483
|
-
});
|
|
484
|
-
this.statusEmitter = new FlumeStatusEmitter({
|
|
485
|
-
log: this.log,
|
|
486
|
-
onStatus: options.onStatus
|
|
487
|
-
});
|
|
488
457
|
}
|
|
489
|
-
async
|
|
490
|
-
|
|
491
|
-
this.signals.register(this.options.signal);
|
|
492
|
-
this.signals.register(options?.signal);
|
|
493
|
-
this.handler = handler;
|
|
494
|
-
this.log.info({
|
|
495
|
-
action: "source.start",
|
|
496
|
-
message: "starting GitHub source"
|
|
497
|
-
});
|
|
498
|
-
this.statusEmitter.set("connecting");
|
|
458
|
+
async connect(ctx) {
|
|
459
|
+
this.setStatus("connecting");
|
|
499
460
|
this.poller = new FlumeGitHubPoller({
|
|
500
461
|
token: this.options.token,
|
|
501
462
|
interval: this.options.pollInterval ?? 60,
|
|
502
|
-
onLog:
|
|
503
|
-
deps:
|
|
504
|
-
onNotifications: (notifications) => this.handleNotifications(notifications),
|
|
505
|
-
onConnected: () => this.
|
|
506
|
-
onDisconnected: (detail) => this.
|
|
463
|
+
onLog: ctx.log.handler,
|
|
464
|
+
deps: ctx.deps,
|
|
465
|
+
onNotifications: (notifications) => this.handleNotifications(ctx, notifications),
|
|
466
|
+
onConnected: () => this.setStatus("connected"),
|
|
467
|
+
onDisconnected: (detail) => this.setStatus("disconnected", detail)
|
|
507
468
|
});
|
|
508
469
|
const result = await this.poller.start();
|
|
509
470
|
if (result instanceof Error) {
|
|
510
|
-
|
|
471
|
+
ctx.log.error({
|
|
511
472
|
action: "source.start.failed",
|
|
512
473
|
message: safeErrorMessage({ error: result }),
|
|
513
474
|
error: result
|
|
514
475
|
});
|
|
515
|
-
this.
|
|
476
|
+
this.setStatus("disconnected", result.message);
|
|
516
477
|
return result;
|
|
517
478
|
}
|
|
518
479
|
return null;
|
|
519
480
|
}
|
|
520
|
-
|
|
521
|
-
this.signals.unregisterAll();
|
|
522
|
-
this.log.info({
|
|
523
|
-
action: "source.stop",
|
|
524
|
-
message: "stopping GitHub source"
|
|
525
|
-
});
|
|
481
|
+
disconnect() {
|
|
526
482
|
this.poller?.stop();
|
|
527
|
-
await this.queue.drain();
|
|
528
483
|
this.poller = null;
|
|
529
|
-
this.handler = null;
|
|
530
|
-
this.statusEmitter.set("disconnected");
|
|
531
|
-
}
|
|
532
|
-
status() {
|
|
533
|
-
return this.statusEmitter.value;
|
|
534
484
|
}
|
|
535
|
-
handleNotifications(notifications) {
|
|
536
|
-
const
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
data: notification,
|
|
543
|
-
meta: this.safeExtractMeta(notification),
|
|
544
|
-
receivedAt: safeNow({ deps: this.deps })
|
|
545
|
-
};
|
|
546
|
-
const r = await attempt(() => Promise.resolve(handler(event)));
|
|
547
|
-
if (r instanceof Error) this.log.error({
|
|
548
|
-
action: "handler.error",
|
|
549
|
-
message: safeErrorMessage({ error: r }),
|
|
550
|
-
error: r
|
|
551
|
-
});
|
|
485
|
+
handleNotifications(ctx, notifications) {
|
|
486
|
+
for (const notification of notifications) this.emit({
|
|
487
|
+
source: "github",
|
|
488
|
+
type: "notification",
|
|
489
|
+
data: notification,
|
|
490
|
+
meta: this.safeExtractMeta(ctx, notification),
|
|
491
|
+
receivedAt: safeNow({ deps: ctx.deps })
|
|
552
492
|
});
|
|
553
493
|
}
|
|
554
|
-
safeExtractMeta(notification) {
|
|
494
|
+
safeExtractMeta(ctx, notification) {
|
|
555
495
|
const result = attempt(() => flumeExtractGitHubMeta(notification));
|
|
556
496
|
if (result instanceof Error) {
|
|
557
497
|
const error = safeNormalizeError({ value: result });
|
|
558
|
-
|
|
498
|
+
ctx.log.warn({
|
|
559
499
|
action: "meta.extract.error",
|
|
560
500
|
message: safeErrorMessage({ error }),
|
|
561
501
|
error,
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as
|
|
1
|
+
import { C as FlumeSourceStartContext, D as FlumeStatusHandler, E as FlumeStatusEvent, O as FlumeTimerHandle, S as FlumeSourceName, T as FlumeStatus, _ as FlumeSlackConnectionResponse, a as FlumeEventHandler, b as FlumeSlackSourceOptions, c as FlumeGitHubNotification, d as FlumeLogHandler, f as FlumeLogInput, g as FlumeRuntimeDeps, h as FlumeReconnectOptions, i as FlumeEvent, k as FlumeLogger, l as FlumeGitHubSourceOptions, m as FlumeReconnectConfig, n as FlumeDiscordEvent, o as FlumeGatewayMessage, p as FlumeLogLevel, r as FlumeDiscordSourceOptions, s as FlumeGitHubEvent, t as FlumeSource, u as FlumeLog, v as FlumeSlackEnvelope, w as FlumeSourceStatus, x as FlumeSourceLocalStatusHandler, y as FlumeSlackEvent } from "./flume-source-DuUFPhSe.js";
|
|
2
2
|
|
|
3
3
|
//#region lib/deps.d.ts
|
|
4
4
|
/**
|
|
@@ -9,7 +9,7 @@ import { C as FlumeSourceStartOptions, D as FlumeTimerHandle, E as FlumeStatusHa
|
|
|
9
9
|
declare function createFlumeDefaultDeps(): FlumeRuntimeDeps;
|
|
10
10
|
//#endregion
|
|
11
11
|
//#region lib/errors/connection-error.d.ts
|
|
12
|
-
type Options$
|
|
12
|
+
type Options$3 = {
|
|
13
13
|
cause?: unknown;
|
|
14
14
|
code?: number;
|
|
15
15
|
};
|
|
@@ -19,57 +19,38 @@ type Options$2 = {
|
|
|
19
19
|
*/
|
|
20
20
|
declare class FlumeConnectionError extends Error {
|
|
21
21
|
readonly code: number | null;
|
|
22
|
-
constructor(message: string, options?: Options$
|
|
22
|
+
constructor(message: string, options?: Options$3);
|
|
23
23
|
}
|
|
24
24
|
//#endregion
|
|
25
25
|
//#region lib/errors/http-error.d.ts
|
|
26
|
-
type Props$
|
|
26
|
+
type Props$2 = {
|
|
27
27
|
message: string;
|
|
28
28
|
status: number;
|
|
29
29
|
cause?: unknown;
|
|
30
30
|
};
|
|
31
31
|
declare class FlumeHttpError extends Error {
|
|
32
32
|
readonly status: number;
|
|
33
|
-
constructor(props: Props$
|
|
33
|
+
constructor(props: Props$2);
|
|
34
34
|
}
|
|
35
35
|
//#endregion
|
|
36
36
|
//#region lib/errors/parse-error.d.ts
|
|
37
|
-
type Options$
|
|
37
|
+
type Options$2 = {
|
|
38
38
|
cause?: unknown;
|
|
39
39
|
};
|
|
40
40
|
declare class FlumeParseError extends Error {
|
|
41
|
-
constructor(message: string, options?: Options$
|
|
41
|
+
constructor(message: string, options?: Options$2);
|
|
42
42
|
}
|
|
43
43
|
//#endregion
|
|
44
44
|
//#region lib/errors/start-error.d.ts
|
|
45
|
-
type Options = {
|
|
45
|
+
type Options$1 = {
|
|
46
46
|
cause?: unknown;
|
|
47
47
|
};
|
|
48
48
|
declare class FlumeStartError extends Error {
|
|
49
|
-
constructor(message: string, options?: Options);
|
|
50
|
-
}
|
|
51
|
-
//#endregion
|
|
52
|
-
//#region lib/logger.d.ts
|
|
53
|
-
type Props$3 = {
|
|
54
|
-
source: string;
|
|
55
|
-
handler?: FlumeLogHandler;
|
|
56
|
-
deps: Pick<FlumeRuntimeDeps, "now">;
|
|
57
|
-
};
|
|
58
|
-
/**
|
|
59
|
-
* 構造化ログを onLog に流す。handler が throw / reject してもループは継続する
|
|
60
|
-
*/
|
|
61
|
-
declare class FlumeLogger {
|
|
62
|
-
private readonly props;
|
|
63
|
-
constructor(props: Props$3);
|
|
64
|
-
debug(entry: FlumeLogInput): void;
|
|
65
|
-
info(entry: FlumeLogInput): void;
|
|
66
|
-
warn(entry: FlumeLogInput): void;
|
|
67
|
-
error(entry: FlumeLogInput): void;
|
|
68
|
-
private emit;
|
|
49
|
+
constructor(message: string, options?: Options$1);
|
|
69
50
|
}
|
|
70
51
|
//#endregion
|
|
71
52
|
//#region lib/flume-stopped.d.ts
|
|
72
|
-
type Props$
|
|
53
|
+
type Props$1 = {
|
|
73
54
|
finalStatuses: ReadonlyArray<FlumeSourceStatus>;
|
|
74
55
|
};
|
|
75
56
|
/**
|
|
@@ -78,12 +59,12 @@ type Props$2 = {
|
|
|
78
59
|
declare class FlumeStopped {
|
|
79
60
|
private readonly props;
|
|
80
61
|
readonly kind: "stopped";
|
|
81
|
-
constructor(props: Props$
|
|
62
|
+
constructor(props: Props$1);
|
|
82
63
|
statuses(): ReadonlyArray<FlumeSourceStatus>;
|
|
83
64
|
}
|
|
84
65
|
//#endregion
|
|
85
66
|
//#region lib/flume-running.d.ts
|
|
86
|
-
type Props
|
|
67
|
+
type Props = {
|
|
87
68
|
sources: ReadonlyArray<FlumeSource>;
|
|
88
69
|
signal?: AbortSignal;
|
|
89
70
|
log: FlumeLogger;
|
|
@@ -98,7 +79,7 @@ declare class FlumeRunning {
|
|
|
98
79
|
readonly kind: "running";
|
|
99
80
|
private stopPromise;
|
|
100
81
|
private readonly onAbort;
|
|
101
|
-
constructor(props: Props
|
|
82
|
+
constructor(props: Props);
|
|
102
83
|
stop(): Promise<FlumeStopped>;
|
|
103
84
|
statuses(): ReadonlyArray<FlumeSourceStatus>;
|
|
104
85
|
private runStop;
|
|
@@ -107,31 +88,38 @@ declare class FlumeRunning {
|
|
|
107
88
|
}
|
|
108
89
|
//#endregion
|
|
109
90
|
//#region lib/flume.d.ts
|
|
110
|
-
type
|
|
111
|
-
|
|
91
|
+
type Options = {
|
|
92
|
+
onEvent?: FlumeEventHandler;
|
|
112
93
|
signal?: AbortSignal;
|
|
113
94
|
onLog?: FlumeLogHandler;
|
|
95
|
+
onStatus?: FlumeStatusHandler;
|
|
114
96
|
deps?: FlumeRuntimeDeps;
|
|
97
|
+
reconnect?: FlumeReconnectOptions;
|
|
115
98
|
};
|
|
116
99
|
/**
|
|
117
100
|
* 起動前の Flume。`start()` で `FlumeRunning` へ遷移する。
|
|
101
|
+
* 第一引数は sources、第二引数は cross-cutting options (全て optional)。
|
|
102
|
+
* `onEvent` を省略するとイベントは黙って捨てられる (接続観測専用モード)。
|
|
118
103
|
* いずれかの source 失敗時は既に成功した source を全て `stop()` してロールバックし
|
|
119
104
|
* `FlumeStartError` を返す。
|
|
120
105
|
* `source.start()` / `source.stop()` の sync throw も `Promise.resolve().then` 経由で
|
|
121
106
|
* Promise rejection に正規化して `allSettled` で捕捉する (`start()` は決して reject しない)
|
|
122
107
|
*/
|
|
123
108
|
declare class Flume {
|
|
124
|
-
private readonly
|
|
109
|
+
private readonly sources;
|
|
110
|
+
private readonly options;
|
|
125
111
|
private consumed;
|
|
126
112
|
private readonly log;
|
|
127
113
|
private readonly deps;
|
|
128
|
-
|
|
129
|
-
|
|
114
|
+
private readonly onEvent;
|
|
115
|
+
constructor(sources: ReadonlyArray<FlumeSource>, options?: Options);
|
|
116
|
+
start(): Promise<FlumeRunning | FlumeStartError>;
|
|
130
117
|
private guardStart;
|
|
131
118
|
private isSignalAborted;
|
|
132
119
|
private sourceName;
|
|
133
120
|
private safeStart;
|
|
121
|
+
private notifyStatus;
|
|
134
122
|
private rollback;
|
|
135
123
|
}
|
|
136
124
|
//#endregion
|
|
137
|
-
export { Flume, FlumeConnectionError, type FlumeDiscordEvent, type FlumeDiscordSourceOptions, type FlumeEvent, type FlumeGatewayMessage, type FlumeGitHubEvent, type FlumeGitHubNotification, type FlumeGitHubSourceOptions,
|
|
125
|
+
export { Flume, FlumeConnectionError, type FlumeDiscordEvent, type FlumeDiscordSourceOptions, type FlumeEvent, type FlumeEventHandler, type FlumeGatewayMessage, type FlumeGitHubEvent, type FlumeGitHubNotification, type FlumeGitHubSourceOptions, FlumeHttpError, type FlumeLog, type FlumeLogHandler, type FlumeLogInput, type FlumeLogLevel, FlumeParseError, type FlumeReconnectConfig, type FlumeReconnectOptions, FlumeRunning, type FlumeRuntimeDeps, type FlumeSlackConnectionResponse, type FlumeSlackEnvelope, type FlumeSlackEvent, type FlumeSlackSourceOptions, FlumeSource, type FlumeSourceLocalStatusHandler, type FlumeSourceName, type FlumeSourceStartContext, type FlumeSourceStatus, FlumeStartError, type FlumeStatus, type FlumeStatusEvent, type FlumeStatusHandler, FlumeStopped, type FlumeTimerHandle, createFlumeDefaultDeps };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,27 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as FlumeStartError, c as safeNormalizeError, l as safeErrorMessage, n as safeInvokeCallback, o as FlumeParseError, r as FlumeLogger, s as attempt, t as FlumeSource } from "./flume-source-DUvt9aJt.js";
|
|
2
2
|
import { t as FlumeConnectionError } from "./connection-error-HUO3PC3G.js";
|
|
3
3
|
import { t as FlumeHttpError } from "./http-error-CPSKoSie.js";
|
|
4
|
+
//#region lib/deps.ts
|
|
5
|
+
const wsCandidate = attempt(() => globalThis.WebSocket);
|
|
6
|
+
const cachedWebSocket = wsCandidate instanceof Error || typeof wsCandidate !== "function" ? null : wsCandidate;
|
|
7
|
+
/**
|
|
8
|
+
* platform 既定の IO を束ねた `FlumeRuntimeDeps`。
|
|
9
|
+
* `FlumeTimerHandle` は不透明型 (`unknown`) のため、setTimeout / clearTimeout の戻り値・引数を
|
|
10
|
+
* platform 型と橋渡しする際に境界で `as unknown as` を使う (IO 境界の最終手段)
|
|
11
|
+
*/
|
|
12
|
+
function createFlumeDefaultDeps() {
|
|
13
|
+
return {
|
|
14
|
+
fetch: (url, init) => globalThis.fetch(url, init),
|
|
15
|
+
WebSocket: cachedWebSocket,
|
|
16
|
+
now: () => Date.now(),
|
|
17
|
+
random: () => Math.random(),
|
|
18
|
+
setTimeout: (fn, ms) => globalThis.setTimeout(fn, ms),
|
|
19
|
+
clearTimeout: (id) => globalThis.clearTimeout(id),
|
|
20
|
+
setInterval: (fn, ms) => globalThis.setInterval(fn, ms),
|
|
21
|
+
clearInterval: (id) => globalThis.clearInterval(id)
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
4
25
|
//#region lib/flume-stopped.ts
|
|
5
26
|
/**
|
|
6
27
|
* 停止済みの終端状態。最終ステータスのスナップショットのみ観測できる
|
|
@@ -143,42 +164,65 @@ var FlumeRunning = class {
|
|
|
143
164
|
}
|
|
144
165
|
};
|
|
145
166
|
//#endregion
|
|
167
|
+
//#region lib/reconnect-config.ts
|
|
168
|
+
const DEFAULTS = {
|
|
169
|
+
maxAttempts: Infinity,
|
|
170
|
+
baseDelay: 1e3,
|
|
171
|
+
maxDelay: 3e4
|
|
172
|
+
};
|
|
173
|
+
function resolveFlumeReconnectConfig(input) {
|
|
174
|
+
if (input === false || input === void 0) return null;
|
|
175
|
+
if (input === true) return { ...DEFAULTS };
|
|
176
|
+
return {
|
|
177
|
+
...DEFAULTS,
|
|
178
|
+
...input
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
//#endregion
|
|
146
182
|
//#region lib/flume.ts
|
|
183
|
+
const noopOnEvent = () => {};
|
|
147
184
|
/**
|
|
148
185
|
* 起動前の Flume。`start()` で `FlumeRunning` へ遷移する。
|
|
186
|
+
* 第一引数は sources、第二引数は cross-cutting options (全て optional)。
|
|
187
|
+
* `onEvent` を省略するとイベントは黙って捨てられる (接続観測専用モード)。
|
|
149
188
|
* いずれかの source 失敗時は既に成功した source を全て `stop()` してロールバックし
|
|
150
189
|
* `FlumeStartError` を返す。
|
|
151
190
|
* `source.start()` / `source.stop()` の sync throw も `Promise.resolve().then` 経由で
|
|
152
191
|
* Promise rejection に正規化して `allSettled` で捕捉する (`start()` は決して reject しない)
|
|
153
192
|
*/
|
|
154
193
|
var Flume = class {
|
|
155
|
-
|
|
194
|
+
sources;
|
|
195
|
+
options;
|
|
156
196
|
consumed = false;
|
|
157
197
|
log;
|
|
158
198
|
deps;
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
this.
|
|
199
|
+
onEvent;
|
|
200
|
+
constructor(sources, options = {}) {
|
|
201
|
+
this.sources = sources;
|
|
202
|
+
this.options = options;
|
|
203
|
+
this.deps = options.deps ?? createFlumeDefaultDeps();
|
|
162
204
|
this.log = new FlumeLogger({
|
|
163
205
|
source: "flume",
|
|
164
|
-
handler:
|
|
206
|
+
handler: options.onLog,
|
|
165
207
|
deps: this.deps
|
|
166
208
|
});
|
|
209
|
+
this.onEvent = options.onEvent ?? noopOnEvent;
|
|
167
210
|
}
|
|
168
|
-
async start(
|
|
211
|
+
async start() {
|
|
169
212
|
const guard = this.guardStart();
|
|
170
213
|
if (guard) return guard;
|
|
171
214
|
this.consumed = true;
|
|
172
215
|
this.log.info({
|
|
173
216
|
action: "flume.start",
|
|
174
|
-
message: `starting ${this.
|
|
175
|
-
detail: { count: this.
|
|
217
|
+
message: `starting ${this.sources.length} source(s)`,
|
|
218
|
+
detail: { count: this.sources.length }
|
|
176
219
|
});
|
|
177
|
-
const
|
|
220
|
+
const reconnect = resolveFlumeReconnectConfig(this.options.reconnect);
|
|
221
|
+
const settled = await Promise.allSettled(this.sources.map((source) => this.safeStart(source, reconnect)));
|
|
178
222
|
const failures = [];
|
|
179
223
|
const started = [];
|
|
180
224
|
for (const [index, result] of settled.entries()) {
|
|
181
|
-
const source = this.
|
|
225
|
+
const source = this.sources[index];
|
|
182
226
|
if (source === void 0) continue;
|
|
183
227
|
const name = this.sourceName(source);
|
|
184
228
|
if (result.status === "rejected") {
|
|
@@ -215,7 +259,7 @@ var Flume = class {
|
|
|
215
259
|
return error;
|
|
216
260
|
}
|
|
217
261
|
if (this.isSignalAborted()) {
|
|
218
|
-
await this.rollback(this.
|
|
262
|
+
await this.rollback(this.sources);
|
|
219
263
|
const error = new FlumeStartError("Flume.start: aborted during start");
|
|
220
264
|
this.log.warn({
|
|
221
265
|
action: "flume.start.aborted",
|
|
@@ -229,8 +273,8 @@ var Flume = class {
|
|
|
229
273
|
message: "all sources started"
|
|
230
274
|
});
|
|
231
275
|
return new FlumeRunning({
|
|
232
|
-
sources: this.
|
|
233
|
-
signal: this.
|
|
276
|
+
sources: this.sources,
|
|
277
|
+
signal: this.options.signal,
|
|
234
278
|
log: this.log
|
|
235
279
|
});
|
|
236
280
|
}
|
|
@@ -256,7 +300,7 @@ var Flume = class {
|
|
|
256
300
|
return null;
|
|
257
301
|
}
|
|
258
302
|
isSignalAborted() {
|
|
259
|
-
const signal = this.
|
|
303
|
+
const signal = this.options.signal;
|
|
260
304
|
if (!signal) return false;
|
|
261
305
|
const result = attempt(() => signal.aborted === true);
|
|
262
306
|
return result instanceof Error ? true : result;
|
|
@@ -267,8 +311,38 @@ var Flume = class {
|
|
|
267
311
|
if (typeof result !== "string") return "?";
|
|
268
312
|
return result;
|
|
269
313
|
}
|
|
270
|
-
safeStart(source,
|
|
271
|
-
|
|
314
|
+
safeStart(source, reconnect) {
|
|
315
|
+
const name = this.sourceName(source);
|
|
316
|
+
const ctx = {
|
|
317
|
+
onEvent: this.onEvent,
|
|
318
|
+
log: this.log.child(name),
|
|
319
|
+
deps: this.deps,
|
|
320
|
+
onStatus: (status, detail) => this.notifyStatus(name, status, detail),
|
|
321
|
+
reconnect
|
|
322
|
+
};
|
|
323
|
+
return Promise.resolve().then(() => source.start(ctx));
|
|
324
|
+
}
|
|
325
|
+
notifyStatus(name, status, detail) {
|
|
326
|
+
const handler = this.options.onStatus;
|
|
327
|
+
if (!handler) return;
|
|
328
|
+
const event = detail !== void 0 ? {
|
|
329
|
+
source: name,
|
|
330
|
+
status,
|
|
331
|
+
detail
|
|
332
|
+
} : {
|
|
333
|
+
source: name,
|
|
334
|
+
status
|
|
335
|
+
};
|
|
336
|
+
safeInvokeCallback({
|
|
337
|
+
fn: () => handler(event),
|
|
338
|
+
onError: (error) => {
|
|
339
|
+
this.log.error({
|
|
340
|
+
action: "onStatus.error",
|
|
341
|
+
message: safeErrorMessage({ error }),
|
|
342
|
+
error
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
});
|
|
272
346
|
}
|
|
273
347
|
async rollback(sources) {
|
|
274
348
|
const settled = await Promise.allSettled(sources.map((source) => Promise.resolve().then(() => source.stop())));
|
|
@@ -286,4 +360,4 @@ var Flume = class {
|
|
|
286
360
|
}
|
|
287
361
|
};
|
|
288
362
|
//#endregion
|
|
289
|
-
export { Flume, FlumeConnectionError, FlumeHttpError, FlumeParseError, FlumeRunning, FlumeStartError, FlumeStopped, createFlumeDefaultDeps };
|
|
363
|
+
export { Flume, FlumeConnectionError, FlumeHttpError, FlumeParseError, FlumeRunning, FlumeSource, FlumeStartError, FlumeStopped, createFlumeDefaultDeps };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { o as FlumeParseError } from "./flume-source-DUvt9aJt.js";
|
|
2
|
+
//#region lib/utils/safe-json-parse.ts
|
|
3
|
+
function safeJsonParse(raw) {
|
|
4
|
+
try {
|
|
5
|
+
return JSON.parse(raw);
|
|
6
|
+
} catch (error) {
|
|
7
|
+
return new FlumeParseError(error instanceof Error ? `invalid JSON: ${error.message}` : "invalid JSON", { cause: error });
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
export { safeJsonParse as t };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { l as safeErrorMessage,
|
|
1
|
+
import { l as safeErrorMessage, n as safeInvokeCallback, s as attempt } from "./flume-source-DUvt9aJt.js";
|
|
2
2
|
import { t as FlumeConnectionError } from "./connection-error-HUO3PC3G.js";
|
|
3
3
|
//#region lib/utils/safe-random.ts
|
|
4
4
|
/**
|
|
@@ -92,21 +92,6 @@ var FlumeReconnector = class {
|
|
|
92
92
|
}
|
|
93
93
|
};
|
|
94
94
|
//#endregion
|
|
95
|
-
//#region lib/reconnect-config.ts
|
|
96
|
-
const DEFAULTS = {
|
|
97
|
-
maxAttempts: Infinity,
|
|
98
|
-
baseDelay: 1e3,
|
|
99
|
-
maxDelay: 3e4
|
|
100
|
-
};
|
|
101
|
-
function resolveFlumeReconnectConfig(input) {
|
|
102
|
-
if (input === false || input === void 0) return null;
|
|
103
|
-
if (input === true) return { ...DEFAULTS };
|
|
104
|
-
return {
|
|
105
|
-
...DEFAULTS,
|
|
106
|
-
...input
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
//#endregion
|
|
110
95
|
//#region lib/schedule-reconnect.ts
|
|
111
96
|
/**
|
|
112
97
|
* 接続が落ちた際の共通再接続スケジューラ。
|
|
@@ -169,4 +154,4 @@ function safeStringify(value) {
|
|
|
169
154
|
return attempt(() => JSON.stringify(value));
|
|
170
155
|
}
|
|
171
156
|
//#endregion
|
|
172
|
-
export {
|
|
157
|
+
export { safeRandom as a, FlumeReconnector as i, isRecord as n, scheduleFlumeReconnect as r, safeStringify as t };
|
package/dist/slack.d.ts
CHANGED
|
@@ -1,24 +1,16 @@
|
|
|
1
|
-
import { C as
|
|
1
|
+
import { C as FlumeSourceStartContext, b as FlumeSlackSourceOptions, t as FlumeSource, v as FlumeSlackEnvelope } from "./flume-source-DuUFPhSe.js";
|
|
2
2
|
|
|
3
3
|
//#region lib/slack/slack-source.d.ts
|
|
4
|
-
declare class FlumeSlackSource {
|
|
4
|
+
declare class FlumeSlackSource extends FlumeSource {
|
|
5
5
|
private readonly options;
|
|
6
6
|
readonly name: "slack";
|
|
7
7
|
private socket;
|
|
8
8
|
private reconnector;
|
|
9
|
-
private handler;
|
|
10
9
|
private internalController;
|
|
11
|
-
private
|
|
12
|
-
private readonly deps;
|
|
13
|
-
private readonly queue;
|
|
14
|
-
private readonly seen;
|
|
15
|
-
private readonly signals;
|
|
16
|
-
private readonly statusEmitter;
|
|
17
|
-
private readonly onSignalAbort;
|
|
10
|
+
private seen;
|
|
18
11
|
constructor(options: FlumeSlackSourceOptions);
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
status(): FlumeStatus;
|
|
12
|
+
protected connect(ctx: FlumeSourceStartContext): Promise<Error | null>;
|
|
13
|
+
protected disconnect(): void;
|
|
22
14
|
private hasWebSocket;
|
|
23
15
|
private connectInternal;
|
|
24
16
|
private handleMessage;
|