@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/dist/github.js CHANGED
@@ -1,7 +1,7 @@
1
- import { a as FlumeParseError, c as safeNormalizeError, i as FlumeStartError, l as safeErrorMessage, n as FlumeLogger, o as createFlumeDefaultDeps, r as safeNow, s as attempt, t as safeInvokeCallback } from "./safe-invoke-callback-EpWXwfwp.js";
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 { i as safeJsonParse, n as FlumeStatusEmitter, r as FlumeSignalRegistry, t as FlumeSerialQueue } from "./serial-queue-B9LoBc64.js";
4
- import { t as safeReadText } from "./safe-read-text-DgrJ4Uhl.js";
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 start(handler, options) {
490
- if (this.signals.isAnyAborted(this.options.signal) || this.signals.isAnyAborted(options?.signal)) return new FlumeStartError("GitHub source: signal already aborted");
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: this.options.onLog,
503
- deps: this.deps,
504
- onNotifications: (notifications) => this.handleNotifications(notifications),
505
- onConnected: () => this.statusEmitter.set("connected"),
506
- onDisconnected: (detail) => this.statusEmitter.set("disconnected", detail)
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
- this.log.error({
471
+ ctx.log.error({
511
472
  action: "source.start.failed",
512
473
  message: safeErrorMessage({ error: result }),
513
474
  error: result
514
475
  });
515
- this.statusEmitter.set("disconnected", result.message);
476
+ this.setStatus("disconnected", result.message);
516
477
  return result;
517
478
  }
518
479
  return null;
519
480
  }
520
- async stop() {
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 handler = this.handler;
537
- if (!handler) return;
538
- for (const notification of notifications) this.queue.add(async () => {
539
- const event = {
540
- source: "github",
541
- type: "notification",
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
- this.log.warn({
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 FlumeSourceStartOptions, D as FlumeTimerHandle, E as FlumeStatusHandler, S as FlumeSourceOptions, T as FlumeStatus, _ as FlumeSlackEnvelope, a as FlumeGitHubEvent, b as FlumeSource, c as FlumeHandler, d as FlumeLogInput, f as FlumeLogLevel, g as FlumeSlackConnectionResponse, h as FlumeRuntimeDeps, i as FlumeGatewayMessage, l as FlumeLog, m as FlumeReconnectOptions, n as FlumeDiscordSourceOptions, o as FlumeGitHubNotification, p as FlumeReconnectConfig, r as FlumeEvent, s as FlumeGitHubSourceOptions, t as FlumeDiscordEvent, u as FlumeLogHandler, v as FlumeSlackEvent, w as FlumeSourceStatus, x as FlumeSourceName, y as FlumeSlackSourceOptions } from "./types-D-tO-Mh2.js";
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$2 = {
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$2);
22
+ constructor(message: string, options?: Options$3);
23
23
  }
24
24
  //#endregion
25
25
  //#region lib/errors/http-error.d.ts
26
- type Props$4 = {
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$4);
33
+ constructor(props: Props$2);
34
34
  }
35
35
  //#endregion
36
36
  //#region lib/errors/parse-error.d.ts
37
- type Options$1 = {
37
+ type Options$2 = {
38
38
  cause?: unknown;
39
39
  };
40
40
  declare class FlumeParseError extends Error {
41
- constructor(message: string, options?: Options$1);
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$2 = {
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$2);
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$1 = {
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$1);
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 Props = {
111
- sources: ReadonlyArray<FlumeSource>;
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 props;
109
+ private readonly sources;
110
+ private readonly options;
125
111
  private consumed;
126
112
  private readonly log;
127
113
  private readonly deps;
128
- constructor(props: Props);
129
- start(handler: FlumeHandler): Promise<FlumeRunning | FlumeStartError>;
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, type FlumeHandler, 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, type FlumeSource, type FlumeSourceName, type FlumeSourceOptions, type FlumeSourceStartOptions, type FlumeSourceStatus, FlumeStartError, type FlumeStatus, type FlumeStatusHandler, FlumeStopped, type FlumeTimerHandle, createFlumeDefaultDeps };
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 FlumeParseError, c as safeNormalizeError, i as FlumeStartError, l as safeErrorMessage, n as FlumeLogger, o as createFlumeDefaultDeps, s as attempt, t as safeInvokeCallback } from "./safe-invoke-callback-EpWXwfwp.js";
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
- props;
194
+ sources;
195
+ options;
156
196
  consumed = false;
157
197
  log;
158
198
  deps;
159
- constructor(props) {
160
- this.props = props;
161
- this.deps = props.deps ?? createFlumeDefaultDeps();
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: props.onLog,
206
+ handler: options.onLog,
165
207
  deps: this.deps
166
208
  });
209
+ this.onEvent = options.onEvent ?? noopOnEvent;
167
210
  }
168
- async start(handler) {
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.props.sources.length} source(s)`,
175
- detail: { count: this.props.sources.length }
217
+ message: `starting ${this.sources.length} source(s)`,
218
+ detail: { count: this.sources.length }
176
219
  });
177
- const settled = await Promise.allSettled(this.props.sources.map((source) => this.safeStart(source, handler)));
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.props.sources[index];
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.props.sources);
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.props.sources,
233
- signal: this.props.signal,
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.props.signal;
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, handler) {
271
- return Promise.resolve().then(() => source.start(handler, { signal: this.props.signal }));
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 } from "./safe-invoke-callback-EpWXwfwp.js";
1
+ import { l as safeErrorMessage } from "./flume-source-DUvt9aJt.js";
2
2
  import { t as FlumeHttpError } from "./http-error-CPSKoSie.js";
3
3
  //#region lib/utils/safe-read-text.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { l as safeErrorMessage, s as attempt, t as safeInvokeCallback } from "./safe-invoke-callback-EpWXwfwp.js";
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 { FlumeReconnector as a, resolveFlumeReconnectConfig as i, isRecord as n, safeRandom as o, scheduleFlumeReconnect as r, safeStringify as t };
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 FlumeSourceStartOptions, T as FlumeStatus, _ as FlumeSlackEnvelope, c as FlumeHandler, y as FlumeSlackSourceOptions } from "./types-D-tO-Mh2.js";
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 readonly log;
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
- start(handler: FlumeHandler, options?: FlumeSourceStartOptions): Promise<Error | null>;
20
- stop(): Promise<void>;
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;