@interactive-inc/flume 0.10.0 → 0.10.1

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/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { A as FlumeStatus, B as FlumeTimerHandle, C as FlumeSlackEvent, D as FlumeSourceStartContext, E as FlumeSourceName, F as FlumeTimeEvent, I as FlumeTimeMessage, L as FlumeTimeSourceOptions, M as FlumeStreamItem, N as FlumeStreamOptions, O as FlumeSourceStatus, P as FlumeStreamOverflow, R as FlumeTimeSourceState, S as FlumeSlackEnvelope, T as FlumeSourceLocalStatusHandler, V as FlumeLogger, _ as FlumeLogLevel, a as FlumeDiscordEvent, b as FlumeRuntimeDeps, c as FlumeEvent, d as FlumeGitHubEvent, f as FlumeGitHubNotification, g as FlumeLogInput, h as FlumeLogHandler, i as FlumeConfluenceItemHandler, j as FlumeStreamHandler, k as FlumeStatePersister, l as FlumeEventHandler, m as FlumeLog, n as FlumeCatchupPolicy, o as FlumeDiscordSourceOptions, p as FlumeGitHubSourceOptions, r as FlumeConfluenceItem, s as FlumeErrorHandler, t as FlumeSource, u as FlumeGatewayMessage, v as FlumeReconnectConfig, w as FlumeSlackSourceOptions, x as FlumeSlackConnectionResponse, y as FlumeReconnectOptions, z as FlumeTimeTick } from "./flume-source.js";
2
- import { i as FlumeParseError, r as FlumeTimeSource, t as FlumeCron } from "./parse-cron.js";
1
+ import { A as FlumeStatePersister, B as FlumeTimeTick, C as FlumeSlackEnvelope, D as FlumeSourceName, E as FlumeSourceLocalStatusHandler, F as FlumeStreamOverflow, H as FlumeLogger, I as FlumeTimeEvent, L as FlumeTimeMessage, M as FlumeStreamHandler, N as FlumeStreamItem, O as FlumeSourceStartContext, P as FlumeStreamOptions, R as FlumeTimeSourceOptions, S as FlumeSlackConnectionResponse, T as FlumeSlackSourceOptions, V as FlumeTimerHandle, _ as FlumeLogInput, a as FlumeCustomEvent, b as FlumeReconnectOptions, c as FlumeErrorHandler, d as FlumeGatewayMessage, f as FlumeGitHubEvent, g as FlumeLogHandler, h as FlumeLog, i as FlumeConfluenceItemHandler, j as FlumeStatus, k as FlumeSourceStatus, l as FlumeEvent, m as FlumeGitHubSourceOptions, n as FlumeCatchupPolicy, o as FlumeDiscordEvent, p as FlumeGitHubNotification, r as FlumeConfluenceItem, s as FlumeDiscordSourceOptions, t as FlumeSource, u as FlumeEventHandler, v as FlumeLogLevel, w as FlumeSlackEvent, x as FlumeRuntimeDeps, y as FlumeReconnectConfig, z as FlumeTimeSourceState } from "./flume-source.js";
2
+ import { t as FlumeParseError } from "./parse-error.js";
3
3
 
4
4
  //#region lib/deps.d.ts
5
5
  /**
@@ -29,14 +29,18 @@ declare class FlumeConnectionError extends Error {
29
29
  }
30
30
  //#endregion
31
31
  //#region lib/errors/http-error.d.ts
32
- type Props$5 = {
32
+ type Props$6 = {
33
33
  message: string;
34
34
  status: number;
35
- cause?: unknown;
35
+ cause?: unknown; /** API 固有のエラーコード (Slack の `invalid_auth` 等)。呼び出し側が恒久/一時を分類するのに使う */
36
+ code?: string | null; /** サーバーが `Retry-After` 等で指示した再試行までの待機時間 (ms) */
37
+ retryAfterMs?: number | null;
36
38
  };
37
39
  declare class FlumeHttpError extends Error {
38
40
  readonly status: number;
39
- constructor(props: Props$5);
41
+ readonly code: string | null;
42
+ readonly retryAfterMs: number | null;
43
+ constructor(props: Props$6);
40
44
  }
41
45
  //#endregion
42
46
  //#region lib/errors/start-error.d.ts
@@ -48,37 +52,57 @@ declare class FlumeStartError extends Error {
48
52
  }
49
53
  //#endregion
50
54
  //#region lib/flume-stream.d.ts
51
- type Props$4 = {
55
+ type Props$5 = {
52
56
  buffer: number;
53
57
  onOverflow: FlumeStreamOverflow;
54
- onClose: () => void;
58
+ onClose: () => void; /** buffer 溢れで item を落とした時の通知 (この stream で最初の 1 回だけ発火する) */
59
+ onDrop?: (input: {
60
+ dropped: number;
61
+ }) => void;
55
62
  };
56
63
  /**
57
64
  * push (`FlumeStreamHub.publish`) を pull (`for await`) に変換する async iterator。
58
65
  * consumer が待っていれば即 resolve、いなければ buffer に積み、溢れたら onOverflow に従う。
59
- * `return()` (break / 例外) hub.close() のどちらでも自然に done へ落ちる
66
+ * hub.close() ではバッファ済み item を吐き切ってから done へ落ちる (graceful tail drain)。
67
+ * consumer 側の `return()` (break / 例外) はバッファを破棄して即 done になる (iterator 仕様)。
68
+ * drop の観測は onDrop 経由 — drop 通知自体が firehose に還流して再帰しないよう初回のみ発火
60
69
  */
61
70
  declare class FlumeStream implements AsyncIterableIterator<FlumeStreamItem> {
62
71
  private readonly props;
63
72
  private readonly items;
64
73
  private readonly resolvers;
65
74
  private closed;
66
- constructor(props: Props$4);
75
+ private droppedCount;
76
+ constructor(props: Props$5);
67
77
  push(item: FlumeStreamItem): void;
68
78
  close(): void;
79
+ get dropped(): number;
69
80
  next(): Promise<IteratorResult<FlumeStreamItem>>;
70
81
  return(): Promise<IteratorResult<FlumeStreamItem>>;
82
+ throw(error?: unknown): Promise<IteratorResult<FlumeStreamItem>>;
71
83
  [Symbol.asyncIterator](): AsyncIterableIterator<FlumeStreamItem>;
84
+ private recordDrop;
72
85
  }
73
86
  //#endregion
74
87
  //#region lib/flume-stream-hub.d.ts
88
+ type Props$4 = {
89
+ /** buffer 溢れ通知。Flume が warn ログへ橋渡しする */onDrop?: (input: {
90
+ dropped: number;
91
+ }) => void;
92
+ };
75
93
  /**
76
94
  * firehose (`onEvent` / `stream()`) の item を複数の pull consumer へ fan-out する内部ハブ。
77
95
  * subscriber が居なければ publish は実質 no-op。Flume 停止時に close() で全 stream を終端する
78
96
  */
79
97
  declare class FlumeStreamHub {
98
+ private readonly props;
80
99
  private readonly streams;
100
+ private readonly startupItems;
101
+ private startupDropNotified;
102
+ private hasSubscribed;
81
103
  private closed;
104
+ constructor(props?: Props$4);
105
+ get isClosed(): boolean;
82
106
  publish(item: FlumeStreamItem): void;
83
107
  subscribe(options?: FlumeStreamOptions): FlumeStream;
84
108
  close(): void;
@@ -99,8 +123,9 @@ type Props$3 = {
99
123
  * きれいに close したか / どれが失敗したか」を直接判定できる
100
124
  */
101
125
  declare class FlumeClosed {
102
- private readonly props;
103
126
  readonly kind: "closed";
127
+ private readonly finalStatuses;
128
+ private readonly closeErrors;
104
129
  constructor(props: Props$3);
105
130
  statuses(): ReadonlyArray<FlumeSourceStatus>;
106
131
  /**
@@ -111,12 +136,42 @@ declare class FlumeClosed {
111
136
  errors(): ReadonlyArray<FlumeCloseError>;
112
137
  }
113
138
  //#endregion
114
- //#region lib/flume-running.d.ts
139
+ //#region lib/utils/serial-queue.d.ts
140
+ type OverflowInput = {
141
+ dropped: number;
142
+ depth: number;
143
+ };
115
144
  type Props$2 = {
145
+ maxDepth?: number;
146
+ onOverflow?: (input: OverflowInput) => void;
147
+ };
148
+ /**
149
+ * 投入順を保ったまま task を直列実行する。各 task は前の完了を待ってから走る。
150
+ * task が throw しても後続には伝播しない (キュー自体は止まらない)。
151
+ * maxDepth を超えた場合は新規 task を drop し onOverflow に通知。
152
+ * cancel() 後は add() が no-op になり、既に積まれた未実行 task も実行せずに流れ落ちる。
153
+ * drain() は待機中に追加された task も含めてキューが空になるまで待つ
154
+ */
155
+ declare class FlumeSerialQueue {
156
+ private readonly props;
157
+ private chain;
158
+ private depth;
159
+ private cancelled;
160
+ constructor(props?: Props$2);
161
+ add(task: () => Promise<void>): Promise<void>;
162
+ drain(): Promise<void>;
163
+ cancel(): void;
164
+ size(): number;
165
+ isCancelled(): boolean;
166
+ }
167
+ //#endregion
168
+ //#region lib/flume-running.d.ts
169
+ type Props$1 = {
116
170
  sources: ReadonlyArray<FlumeSource>;
117
171
  signal?: AbortSignal;
118
172
  log: FlumeLogger;
119
173
  hub: FlumeStreamHub;
174
+ callbackQueue: FlumeSerialQueue;
120
175
  };
121
176
  /**
122
177
  * 稼働中の Flume。close() で FlumeClosed へ遷移する。signal が abort されると自動 close。
@@ -128,7 +183,7 @@ declare class FlumeRunning {
128
183
  readonly kind: "running";
129
184
  private closePromise;
130
185
  private readonly onAbort;
131
- constructor(props: Props$2);
186
+ constructor(props: Props$1);
132
187
  close(): Promise<FlumeClosed>;
133
188
  statuses(): ReadonlyArray<FlumeSourceStatus>;
134
189
  /**
@@ -139,9 +194,10 @@ declare class FlumeRunning {
139
194
  */
140
195
  stream(options?: FlumeStreamOptions): AsyncIterableIterator<FlumeStreamItem>;
141
196
  /**
142
- * Host が `Flume({ signal })` で渡した AbortSignal をそのまま公開する。
197
+ * `Flume({ signal })` に渡された AbortSignal をそのまま公開する。
143
198
  * 直接の controller を持っていない呼び出し元が `running.signal?.aborted`
144
- * で abort 状態を確認できる
199
+ * で abort 状態を確認できる。`FlumeConfluence` 経由で開かれたグループでは
200
+ * host の signal ではなく confluence 内部の timeout controller の signal になる点に注意
145
201
  */
146
202
  get signal(): AbortSignal | undefined;
147
203
  private runClose;
@@ -161,14 +217,19 @@ type FlumeOptions = {
161
217
  onError?: FlumeErrorHandler;
162
218
  signal?: AbortSignal;
163
219
  deps?: FlumeRuntimeDeps;
164
- reconnect?: FlumeReconnectOptions;
220
+ /**
221
+ * 再接続方針。未指定 / false は無効 (接続断で source は disconnected のまま)。
222
+ * true は既定値 (maxAttempts: Infinity / baseDelay: 1s / maxDelay: 30s)。
223
+ * 常駐リスナー用途では明示的に有効化を推奨
224
+ */
225
+ reconnect?: boolean | FlumeReconnectOptions;
165
226
  };
166
227
  /**
167
228
  * 起動前の Flume。`open()` で `FlumeRunning` へ遷移する。
168
229
  * コンストラクタは単一オブジェクト `{ sources, ...options }` を受け取る (`sources` のみ必須)。
169
230
  * events も全ログも 1 本の firehose (`onEvent` push / `stream()` pull) に流れ、購読側が filter する。
170
- * いずれかの source 失敗時は既に成功した source を全て `stop()` してロールバックし
171
- * `FlumeStartError` を返す。
231
+ * いずれかの source 失敗時は全 source `stop()` してロールバックし `FlumeStartError` を返す
232
+ * (失敗した source も半接続状態のリソースを持ち得るため、成功分だけでなく全数を stop する)。
172
233
  * `source.start()` / `source.stop()` の sync throw も `Promise.resolve().then` 経由で
173
234
  * Promise rejection に正規化して `allSettled` で捕捉する (`open()` は決して reject しない)
174
235
  */
@@ -180,25 +241,37 @@ declare class Flume {
180
241
  private readonly sources;
181
242
  private readonly sourceEventHandler;
182
243
  private readonly hub;
244
+ private readonly callbackQueue;
183
245
  constructor(options: FlumeOptions);
246
+ /**
247
+ * stream の buffer 溢れ通知 (stream ごとに初回 1 回)。
248
+ * firehose (hub) には流さない — 溢れている stream 自身に還流して実イベントを
249
+ * さらに追い出す自己破壊になるため、push の `onEvent` にだけ warn log として届ける
250
+ */
251
+ private notifyStreamOverflow;
184
252
  /** source が受信したログを firehose へ流す handler。error は onError にも分岐する */
185
253
  private buildLogHandler;
186
254
  /**
187
255
  * firehose の単一 sink: pull の hub と push の onEvent の両方へ item を配る。
256
+ * close 後の遅延 emit (stop 中の straggler) は push 側にも流さない (pull 側と対称にする)。
188
257
  * onEvent への転送は this.log を経由しない (経由すると log item 経路で再帰する) ため
189
258
  * 例外をここで握り潰す
190
259
  */
191
260
  private emitItem;
261
+ private enqueueCallback;
192
262
  open(): Promise<FlumeRunning | FlumeStartError>;
193
263
  private guardOpen;
264
+ /** reconnect オプションの解決。throwing getter を持つ hostile 入力でも open() を reject させない */
265
+ private resolveReconnect;
194
266
  private isSignalAborted;
195
267
  private sourceName;
196
268
  private safeStart;
197
269
  private rollback;
270
+ private logRollbackFailure;
198
271
  }
199
272
  //#endregion
200
273
  //#region lib/flume-confluence.d.ts
201
- type Props$1 = {
274
+ type Props = {
202
275
  /**
203
276
  * 配下の全 Flume の firehose をここへ合流させる単一 sink。
204
277
  * 各 item には発信元グループの id が `groupId` としてスタンプされる
@@ -206,7 +279,7 @@ type Props$1 = {
206
279
  onEvent?: FlumeConfluenceItemHandler; /** error レベル log だけ (全 Flume 共通) */
207
280
  onError?: FlumeErrorHandler;
208
281
  deps?: FlumeRuntimeDeps;
209
- reconnect?: FlumeReconnectOptions;
282
+ reconnect?: boolean | FlumeReconnectOptions;
210
283
  };
211
284
  /**
212
285
  * 複数の `Flume` を束ねて動的に増減させる上位レイヤー。各 Flume は immutable のまま、
@@ -217,14 +290,26 @@ type Props$1 = {
217
290
  * `replace(id, sources)` は同じ id のグループを差し替える。新グループを先に起動し、
218
291
  * 起動成功時にのみ旧グループを停止するので連続稼働を維持できる (token rotation 用途)。
219
292
  * 起動失敗時は旧グループはそのまま走り続ける。
293
+ * 注意: 失敗した replace / add に渡した source インスタンスは consumed になるため、
294
+ * リトライには新しいインスタンスを構築する必要がある。
295
+ *
296
+ * `closeAll()` は終端操作。以後の `add()` / `replace()` は拒否され、closeAll と並行して
297
+ * 起動中だったグループも abort して完了を待つ (シャットダウン後に誰にも止められない
298
+ * グループが残らない)。
220
299
  *
221
300
  * throw しない流儀に従い `add()` / `replace()` は `Error | null` を返す
222
301
  */
223
302
  declare class FlumeConfluence {
224
303
  private readonly props;
225
304
  private readonly running;
305
+ /** open() を await 中でまだ Map に commit されていないグループの id (add 重複と remove 追跡用) */
306
+ private readonly pendingIds;
307
+ private readonly removedWhilePending;
308
+ private readonly pendingOpens;
309
+ private isClosedFlag;
226
310
  private readonly deps;
227
- constructor(props?: Props$1);
311
+ constructor(props?: Props);
312
+ get isClosed(): boolean;
228
313
  /** sources を 1 グループとして起動。id 重複や起動失敗は `Error` で返す (throw しない) */
229
314
  add(id: string, sources: ReadonlyArray<FlumeSource>): Promise<Error | null>;
230
315
  /**
@@ -235,38 +320,24 @@ declare class FlumeConfluence {
235
320
  replace(id: string, sources: ReadonlyArray<FlumeSource>, options?: {
236
321
  readonly replaceTimeoutMs?: number;
237
322
  }): Promise<Error | null>;
238
- /** 指定グループだけ close。他グループは無停止。未知の id は no-op */
323
+ /**
324
+ * 指定グループだけ close。他グループは無停止。未知の id は no-op。
325
+ * 起動中 (add が open を await 中) の id は commit 時点で破棄されるよう予約する
326
+ */
239
327
  remove(id: string): Promise<void>;
328
+ /** 終端操作。全グループを close し、以後の add / replace を拒否する */
240
329
  closeAll(): Promise<void>;
241
330
  has(id: string): boolean;
242
331
  ids(): ReadonlyArray<string>;
243
332
  /**
244
- * 1 グループ分の Flume を開いて FlumeRunning を返す。timeoutMs を指定すると open()
245
- * AbortSignal でレース掛けし、超過時に新グループ起動を中止する。失敗時の rollback
246
- * Flume 本体に任せる
333
+ * 1 グループ分の Flume を開いて FlumeRunning を返す。timeoutMs を指定すると AbortSignal
334
+ * ctx.signal として各 source へ注入し、超過時に abort して進行中の connect ごと中止する
335
+ * (source 側は base クラスが signal を購読して stop() を発火する)。
336
+ * 失敗時の rollback は Flume 本体に任せる
247
337
  */
248
338
  private openGroup;
339
+ private createPendingOpen;
249
340
  private wrapOnEvent;
250
341
  }
251
342
  //#endregion
252
- //#region lib/time/time-catchup.d.ts
253
- type Props = {
254
- cron: FlumeCron;
255
- lastFiredAt: number;
256
- now: number;
257
- policy: FlumeCatchupPolicy;
258
- };
259
- /**
260
- * `lastFiredAt` から `now` までに過ぎ去った cron マッチを policy に従って列挙する。
261
- *
262
- * - policy.mode === "off" : 常に空配列
263
- * - policy.mode === "lastOnly" : 過ぎ去ったマッチの中で最も新しいもの 1 件
264
- * - policy.mode === "missed" : maxWindowMs (既定 24h) 以内に過ぎ去ったすべてのマッチ。
265
- * window の起点は `max(lastFiredAt, now - maxWindowMs)`
266
- *
267
- * 到達不能 cron や catastrophic な policy ミス指定の場合は FlumeParseError を返す
268
- * (catchup 列挙だけで失敗させる。source 本体の起動は別判断)
269
- */
270
- declare function flumeCollectCatchupMatches(props: Props): ReadonlyArray<number> | FlumeParseError;
271
- //#endregion
272
- export { Flume, type FlumeCatchupPolicy, type FlumeCloseError, FlumeClosed, FlumeConfluence, type FlumeConfluenceItem, type FlumeConfluenceItemHandler, FlumeConnectionError, type FlumeDiscordEvent, type FlumeDiscordSourceOptions, type FlumeErrorHandler, type FlumeEvent, type FlumeEventHandler, type FlumeGatewayMessage, type FlumeGitHubEvent, type FlumeGitHubNotification, type FlumeGitHubSourceOptions, FlumeHttpError, type FlumeLog, type FlumeLogHandler, type FlumeLogInput, type FlumeLogLevel, type FlumeOptions, 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 FlumeStatePersister, type FlumeStatus, type FlumeStreamHandler, type FlumeStreamItem, type FlumeStreamOptions, type FlumeStreamOverflow, type FlumeTimeEvent, type FlumeTimeMessage, FlumeTimeSource, type FlumeTimeSourceOptions, type FlumeTimeSourceState, type FlumeTimeTick, type FlumeTimerHandle, createFlumeDefaultDeps, flumeCollectCatchupMatches };
343
+ export { Flume, type FlumeCatchupPolicy, type FlumeCloseError, FlumeClosed, FlumeConfluence, type FlumeConfluenceItem, type FlumeConfluenceItemHandler, FlumeConnectionError, type FlumeCustomEvent, type FlumeDiscordEvent, type FlumeDiscordSourceOptions, type FlumeErrorHandler, type FlumeEvent, type FlumeEventHandler, type FlumeGatewayMessage, type FlumeGitHubEvent, type FlumeGitHubNotification, type FlumeGitHubSourceOptions, FlumeHttpError, type FlumeLog, type FlumeLogHandler, type FlumeLogInput, type FlumeLogLevel, type FlumeOptions, 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 FlumeStatePersister, type FlumeStatus, type FlumeStreamHandler, type FlumeStreamItem, type FlumeStreamOptions, type FlumeStreamOverflow, type FlumeTimeEvent, type FlumeTimeMessage, type FlumeTimeSourceOptions, type FlumeTimeSourceState, type FlumeTimeTick, type FlumeTimerHandle, createFlumeDefaultDeps };