@interactive-inc/flume 0.10.1 → 0.11.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/index.d.ts CHANGED
@@ -29,7 +29,7 @@ declare class FlumeConnectionError extends Error {
29
29
  }
30
30
  //#endregion
31
31
  //#region lib/errors/http-error.d.ts
32
- type Props$6 = {
32
+ type Props$11 = {
33
33
  message: string;
34
34
  status: number;
35
35
  cause?: unknown; /** API 固有のエラーコード (Slack の `invalid_auth` 等)。呼び出し側が恒久/一時を分類するのに使う */
@@ -40,7 +40,7 @@ declare class FlumeHttpError extends Error {
40
40
  readonly status: number;
41
41
  readonly code: string | null;
42
42
  readonly retryAfterMs: number | null;
43
- constructor(props: Props$6);
43
+ constructor(props: Props$11);
44
44
  }
45
45
  //#endregion
46
46
  //#region lib/errors/start-error.d.ts
@@ -52,7 +52,7 @@ declare class FlumeStartError extends Error {
52
52
  }
53
53
  //#endregion
54
54
  //#region lib/flume-stream.d.ts
55
- type Props$5 = {
55
+ type Props$10 = {
56
56
  buffer: number;
57
57
  onOverflow: FlumeStreamOverflow;
58
58
  onClose: () => void; /** buffer 溢れで item を落とした時の通知 (この stream で最初の 1 回だけ発火する) */
@@ -73,10 +73,9 @@ declare class FlumeStream implements AsyncIterableIterator<FlumeStreamItem> {
73
73
  private readonly resolvers;
74
74
  private closed;
75
75
  private droppedCount;
76
- constructor(props: Props$5);
76
+ constructor(props: Props$10);
77
77
  push(item: FlumeStreamItem): void;
78
78
  close(): void;
79
- get dropped(): number;
80
79
  next(): Promise<IteratorResult<FlumeStreamItem>>;
81
80
  return(): Promise<IteratorResult<FlumeStreamItem>>;
82
81
  throw(error?: unknown): Promise<IteratorResult<FlumeStreamItem>>;
@@ -85,7 +84,7 @@ declare class FlumeStream implements AsyncIterableIterator<FlumeStreamItem> {
85
84
  }
86
85
  //#endregion
87
86
  //#region lib/flume-stream-hub.d.ts
88
- type Props$4 = {
87
+ type Props$9 = {
89
88
  /** buffer 溢れ通知。Flume が warn ログへ橋渡しする */onDrop?: (input: {
90
89
  dropped: number;
91
90
  }) => void;
@@ -101,7 +100,7 @@ declare class FlumeStreamHub {
101
100
  private startupDropNotified;
102
101
  private hasSubscribed;
103
102
  private closed;
104
- constructor(props?: Props$4);
103
+ constructor(props?: Props$9);
105
104
  get isClosed(): boolean;
106
105
  publish(item: FlumeStreamItem): void;
107
106
  subscribe(options?: FlumeStreamOptions): FlumeStream;
@@ -113,7 +112,7 @@ type FlumeCloseError = {
113
112
  source: string;
114
113
  error: Error;
115
114
  };
116
- type Props$3 = {
115
+ type Props$8 = {
117
116
  finalStatuses: ReadonlyArray<FlumeSourceStatus>;
118
117
  closeErrors: ReadonlyArray<FlumeCloseError>;
119
118
  };
@@ -126,7 +125,7 @@ declare class FlumeClosed {
126
125
  readonly kind: "closed";
127
126
  private readonly finalStatuses;
128
127
  private readonly closeErrors;
129
- constructor(props: Props$3);
128
+ constructor(props: Props$8);
130
129
  statuses(): ReadonlyArray<FlumeSourceStatus>;
131
130
  /**
132
131
  * `runClose` 中に `source.stop()` が rejected で settle した source の名前と
@@ -137,59 +136,50 @@ declare class FlumeClosed {
137
136
  }
138
137
  //#endregion
139
138
  //#region lib/utils/serial-queue.d.ts
140
- type OverflowInput = {
141
- dropped: number;
142
- depth: number;
143
- };
144
- type Props$2 = {
145
- maxDepth?: number;
146
- onOverflow?: (input: OverflowInput) => void;
147
- };
148
139
  /**
149
140
  * 投入順を保ったまま task を直列実行する。各 task は前の完了を待ってから走る。
150
141
  * task が throw しても後続には伝播しない (キュー自体は止まらない)。
151
- * maxDepth を超えた場合は新規 task を drop し onOverflow に通知。
152
- * cancel() 後は add() が no-op になり、既に積まれた未実行 task も実行せずに流れ落ちる。
153
142
  * drain() は待機中に追加された task も含めてキューが空になるまで待つ
154
143
  */
155
144
  declare class FlumeSerialQueue {
156
- private readonly props;
157
145
  private chain;
158
- private depth;
159
- private cancelled;
160
- constructor(props?: Props$2);
161
146
  add(task: () => Promise<void>): Promise<void>;
162
147
  drain(): Promise<void>;
163
- cancel(): void;
164
- size(): number;
165
- isCancelled(): boolean;
166
148
  }
167
149
  //#endregion
168
150
  //#region lib/flume-running.d.ts
169
- type Props$1 = {
151
+ type Props$7 = {
170
152
  sources: ReadonlyArray<FlumeSource>;
171
153
  signal?: AbortSignal;
172
154
  log: FlumeLogger;
173
155
  hub: FlumeStreamHub;
174
156
  callbackQueue: FlumeSerialQueue;
157
+ seal: () => void;
175
158
  };
176
159
  /**
177
160
  * 稼働中の Flume。close() で FlumeClosed へ遷移する。signal が abort されると自動 close。
178
161
  * 全ての source 呼び出し・signal 操作・status 読み取りを `attempt` 経由で扱い、
179
- * `runClose` の最外殻 try/catch で想定外の throw `FlumeClosed` の resolve に変換する
162
+ * `runClose` の最外殻でも `attempt` を通して想定外の throw `FlumeClosed` の resolve に変換する
180
163
  */
181
164
  declare class FlumeRunning {
182
165
  private readonly props;
183
166
  readonly kind: "running";
184
167
  private closePromise;
185
168
  private readonly onAbort;
186
- constructor(props: Props$1);
169
+ constructor(props: Props$7);
170
+ /** Source の停止まで待つ。callback の完了は callback 外から drain() で待つ。 */
187
171
  close(): Promise<FlumeClosed>;
172
+ /**
173
+ * 配送済み callback とその失敗診断が完了するまで待つ。通常は close() の後に呼ぶ。
174
+ * onEvent / onError 内では自身の完了待ちになるため呼ばない。
175
+ */
176
+ drain(): Promise<void>;
188
177
  statuses(): ReadonlyArray<FlumeSourceStatus>;
189
178
  /**
190
179
  * 統合 firehose を pull で受け取る async iterator。`for await (const item of running.stream())`。
191
180
  * item は events + 全ログの union (`FlumeStreamItem`)。`item.kind` で判別する。
192
- * close() / signal abort iterator は自然に終了し、`break` すると hub から自動 unsubscribe する。
181
+ * close() / signal abort 後、callback の失敗診断まで配送して終了する。
182
+ * `break` すると hub から自動 unsubscribe する。
193
183
  * consumer が遅れて buffer を超えたら `onOverflow` (既定 drop-oldest) に従う
194
184
  */
195
185
  stream(options?: FlumeStreamOptions): AsyncIterableIterator<FlumeStreamItem>;
@@ -201,6 +191,7 @@ declare class FlumeRunning {
201
191
  */
202
192
  get signal(): AbortSignal | undefined;
203
193
  private runClose;
194
+ private closeSources;
204
195
  private snapshotStatuses;
205
196
  private sourceName;
206
197
  }
@@ -228,14 +219,15 @@ type FlumeOptions = {
228
219
  * 起動前の Flume。`open()` で `FlumeRunning` へ遷移する。
229
220
  * コンストラクタは単一オブジェクト `{ sources, ...options }` を受け取る (`sources` のみ必須)。
230
221
  * events も全ログも 1 本の firehose (`onEvent` push / `stream()` pull) に流れ、購読側が filter する。
231
- * いずれかの source 失敗時は全 source を `stop()` してロールバックし `FlumeStartError` を返す
232
- * (失敗した source も半接続状態のリソースを持ち得るため、成功分だけでなく全数を stop する)。
222
+ * 起動失敗時はこの open が取得した source を `stop()` してロールバックする。
223
+ * 半接続状態で失敗した source も含むが、再利用を拒否した source は他の所有者のため停止しない。
233
224
  * `source.start()` / `source.stop()` の sync throw も `Promise.resolve().then` 経由で
234
225
  * Promise rejection に正規化して `allSettled` で捕捉する (`open()` は決して reject しない)
235
226
  */
236
227
  declare class Flume {
237
228
  private readonly options;
238
229
  private consumed;
230
+ private isAcceptingItems;
239
231
  private readonly log;
240
232
  private readonly deps;
241
233
  private readonly sources;
@@ -254,12 +246,24 @@ declare class Flume {
254
246
  /**
255
247
  * firehose の単一 sink: pull の hub と push の onEvent の両方へ item を配る。
256
248
  * close 後の遅延 emit (stop 中の straggler) は push 側にも流さない (pull 側と対称にする)。
257
- * onEvent への転送は this.log を経由しない (経由すると log item 経路で再帰する) ため
258
- * 例外をここで握り潰す
249
+ * onEvent への転送は this.log を経由しない (経由すると log item 経路で再帰する)
250
+ * callback failure は reportCallbackFailure が pull hub と peer callback へ直接診断する。
259
251
  */
260
252
  private emitItem;
261
253
  private enqueueCallback;
254
+ /**
255
+ * error log 専用 sink も callbackQueue に載せ、drain() が in-flight callback と
256
+ * その失敗診断まで drain できるようにする
257
+ */
258
+ private invokeOnError;
259
+ /**
260
+ * 観測 sink 自身の失敗は同じ sink へ戻すと再帰するため、まず pull stream へ直接 publish し、
261
+ * もう一方の callback にだけ転送する。peer も失敗した場合は hub-only の診断を残して終端する
262
+ */
263
+ private reportCallbackFailure;
262
264
  open(): Promise<FlumeRunning | FlumeStartError>;
265
+ /** 起動失敗の戻り値は callback を待たず、配送済み診断の完了後に hub を閉じる。 */
266
+ private finishFailedOpen;
263
267
  private guardOpen;
264
268
  /** reconnect オプションの解決。throwing getter を持つ hostile 入力でも open() を reject させない */
265
269
  private resolveReconnect;
@@ -271,7 +275,7 @@ declare class Flume {
271
275
  }
272
276
  //#endregion
273
277
  //#region lib/flume-confluence.d.ts
274
- type Props = {
278
+ type Props$6 = {
275
279
  /**
276
280
  * 配下の全 Flume の firehose をここへ合流させる単一 sink。
277
281
  * 各 item には発信元グループの id が `groupId` としてスタンプされる
@@ -308,7 +312,7 @@ declare class FlumeConfluence {
308
312
  private readonly pendingOpens;
309
313
  private isClosedFlag;
310
314
  private readonly deps;
311
- constructor(props?: Props);
315
+ constructor(props?: Props$6);
312
316
  get isClosed(): boolean;
313
317
  /** sources を 1 グループとして起動。id 重複や起動失敗は `Error` で返す (throw しない) */
314
318
  add(id: string, sources: ReadonlyArray<FlumeSource>): Promise<Error | null>;
@@ -338,6 +342,108 @@ declare class FlumeConfluence {
338
342
  private openGroup;
339
343
  private createPendingOpen;
340
344
  private wrapOnEvent;
345
+ private wrapOnError;
341
346
  }
342
347
  //#endregion
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 };
348
+ //#region lib/utils/attempt.d.ts
349
+ /**
350
+ * 関数を呼び出して throw / async reject を `T | Error` に変換する。
351
+ *
352
+ * - sync 関数を渡すと `T | Error` を返す
353
+ * - Promise を返す関数を渡すと `Promise<T | Error>` を返す (caller は `await` する)
354
+ * - `new X(...)` や `obj.method(...)` は `() => new X(...)` のようにアローで包む
355
+ *
356
+ * sync / async は arrow の戻り型から TS が推論する。
357
+ * native Promise でない thenable (DI モックや promise ライブラリ) の reject も
358
+ * `Promise.resolve` で吸収する — その代償として、`.then` メソッドを持つ純粋な値を
359
+ * sync overload で返すことはできない (Promise 扱いになる)
360
+ */
361
+ declare function attempt<T>(fn: () => Promise<T>): Promise<T | Error>;
362
+ declare function attempt<T>(fn: () => T): T | Error;
363
+ //#endregion
364
+ //#region lib/utils/is-record.d.ts
365
+ declare function isRecord(value: unknown): value is Record<string, unknown>;
366
+ //#endregion
367
+ //#region lib/utils/safe-error-message.d.ts
368
+ type Props$5 = {
369
+ error: unknown;
370
+ };
371
+ /**
372
+ * 任意の値から人が読めるメッセージ文字列を取り出す。
373
+ * `Error.message` getter / `Symbol.toPrimitive` / `toString` / `valueOf` が throw しても固定文字列に fallback。
374
+ * `instanceof` 自体が throw する値 (revoked Proxy 等) にも耐える。自身は決して throw しない
375
+ */
376
+ declare function safeErrorMessage(props: Props$5): string;
377
+ //#endregion
378
+ //#region lib/utils/safe-invoke-callback.d.ts
379
+ type Props$4 = {
380
+ fn: () => void;
381
+ onError: (error: Error) => void;
382
+ };
383
+ /**
384
+ * fire-and-forget でユーザーコールバックを呼び出す。sync throw と async reject のどちらも
385
+ * `onError(Error)` に正規化して通知。`onError` 自身が throw しても外に漏らさない。
386
+ * 戻り値を持たない fire-and-forget 専用のため log/出力先には依存しない (caller が onError で決める)
387
+ */
388
+ declare function safeInvokeCallback(props: Props$4): void;
389
+ //#endregion
390
+ //#region lib/utils/safe-json-parse.d.ts
391
+ declare function safeJsonParse(raw: string): unknown | FlumeParseError;
392
+ //#endregion
393
+ //#region lib/utils/safe-normalize-error.d.ts
394
+ type Props$3 = {
395
+ value: unknown;
396
+ };
397
+ /**
398
+ * 任意の値を `Error` インスタンスへ正規化する。すでに Error ならそのまま返し、
399
+ * それ以外は `safeErrorMessage` で安全な文字列化を経由して new Error する。
400
+ * `instanceof` 自体が throw する値 (revoked Proxy 等) や Error コンストラクタが throw する
401
+ * 病的環境でも fallback を返し、決して throw しない
402
+ */
403
+ declare function safeNormalizeError(props: Props$3): Error;
404
+ //#endregion
405
+ //#region lib/utils/safe-now.d.ts
406
+ type Props$2 = {
407
+ deps: Pick<FlumeRuntimeDeps, "now">;
408
+ };
409
+ /**
410
+ * `deps.now()` を保護する。throw / 非数値 / 非有限値が返った場合は `Date.now()` へ
411
+ * フォールバックする (0 を返すと epoch 1970 が TTL / cron / レート計算へ伝播するため)。
412
+ * `Date.now` 自体まで壊れている病的環境でのみ 0 を返す。
413
+ * IO 境界のため呼び出し側はこの戻り値を信頼できる
414
+ */
415
+ declare function safeNow(props: Props$2): number;
416
+ //#endregion
417
+ //#region lib/utils/safe-random.d.ts
418
+ type Props$1 = {
419
+ deps: Pick<FlumeRuntimeDeps, "random">;
420
+ };
421
+ /**
422
+ * `deps.random()` を保護する。throw / 範囲外値 / 非数値が返った場合は `Math.random()` へ
423
+ * フォールバックする。0 以上 1 未満 (Math.random と同等) の値のみそのまま透過。
424
+ * `Math.random` 自体まで壊れている病的環境でのみ 0.5 を返す
425
+ */
426
+ declare function safeRandom(props: Props$1): number;
427
+ //#endregion
428
+ //#region lib/utils/safe-read-text.d.ts
429
+ type Props = {
430
+ response: Response;
431
+ context: string;
432
+ };
433
+ /**
434
+ * `response.text()` を保護する。body 読み取り中の reject (接続切断 / 解凍失敗 / 二重消費) を
435
+ * `FlumeHttpError` (status / cause 保持) に変換する。DI モックの `status` getter が throw
436
+ * しても reject しない。log には書かない (呼び出し側で書く)
437
+ */
438
+ declare function safeReadText(props: Props): Promise<string | FlumeHttpError>;
439
+ //#endregion
440
+ //#region lib/utils/safe-stringify.d.ts
441
+ /**
442
+ * `JSON.stringify` を `string | Error` に変換するラッパ。
443
+ * cyclic / BigInt / throwing toJSON など標準が throw するケースを Error として返す。
444
+ * `undefined` / function / symbol は `JSON.stringify` が (型定義に反して) `undefined` を
445
+ * 返すため、これも Error に正規化して戻り値を必ず string にする
446
+ */
447
+ declare function safeStringify(value: unknown): string | Error;
448
+ //#endregion
449
+ 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, attempt, createFlumeDefaultDeps, isRecord, safeErrorMessage, safeInvokeCallback, safeJsonParse, safeNormalizeError, safeNow, safeRandom, safeReadText, safeStringify };