@aiquants/daily-report 0.8.0 → 0.9.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.
Files changed (56) hide show
  1. package/dist/client.d.mts +76 -6
  2. package/dist/client.d.ts +76 -6
  3. package/dist/client.js +5 -5
  4. package/dist/client.js.map +1 -1
  5. package/dist/client.mjs +5 -5
  6. package/dist/client.mjs.map +1 -1
  7. package/dist/index.d.mts +40 -2
  8. package/dist/index.d.ts +40 -2
  9. package/dist/index.js +1 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/index.mjs +1 -1
  12. package/dist/index.mjs.map +1 -1
  13. package/dist/server.d.mts +13 -0
  14. package/dist/server.d.ts +13 -0
  15. package/dist/server.js +8 -7
  16. package/dist/server.js.map +1 -1
  17. package/dist/server.mjs +8 -7
  18. package/dist/server.mjs.map +1 -1
  19. package/dist/{sse-schema-Df49KA7B.d.mts → sse-schema-BiUnufrI.d.mts} +12 -0
  20. package/dist/{sse-schema-RHckD7TS.d.ts → sse-schema-YZh7Pz7i.d.ts} +12 -0
  21. package/dist/styles/daily-report.standalone.css +1 -1
  22. package/package.json +1 -1
  23. package/src/client/components/daily-report-comment-item.tsx +6 -1
  24. package/src/client/components/daily-report-detail-list.tsx +65 -34
  25. package/src/client/components/daily-report-edit-form.tsx +6 -0
  26. package/src/client/components/daily-report-list.tsx +88 -55
  27. package/src/client/components/daily-report-page.tsx +8 -3
  28. package/src/client/components/daily-report-resolved-content.tsx +5 -3
  29. package/src/client/components/report-views.spec.tsx +37 -2
  30. package/src/client/config-context.tsx +18 -0
  31. package/src/client/contexts/daily-report-action-context.spec.tsx +16 -0
  32. package/src/client/contexts/daily-report-action-context.tsx +75 -34
  33. package/src/client/contexts/daily-report-error-context.spec.tsx +66 -0
  34. package/src/client/contexts/daily-report-error-context.tsx +98 -0
  35. package/src/client/hooks/use-daily-report.spec.ts +50 -2
  36. package/src/client/hooks/use-daily-report.ts +30 -1
  37. package/src/client/streaming/daily-report-ids-stream-client.spec.ts +64 -1
  38. package/src/client/streaming/daily-report-ids-stream-client.ts +80 -2
  39. package/src/client.ts +1 -0
  40. package/src/server/handlers.action.spec.ts +44 -0
  41. package/src/server/handlers.ids-stream.spec.ts +53 -1
  42. package/src/server/handlers.ts +81 -5
  43. package/src/server/service.spec.ts +83 -7
  44. package/src/server/service.ts +60 -3
  45. package/src/server/test-helpers/handlers-config.ts +9 -1
  46. package/src/server.spec.ts +49 -0
  47. package/src/server.ts +7 -0
  48. package/src/shared/business-date.spec.ts +22 -1
  49. package/src/shared/business-date.ts +20 -0
  50. package/src/shared/comment-adapter.spec.ts +38 -0
  51. package/src/shared/comment-adapter.ts +9 -7
  52. package/src/shared/ids-stream.spec.ts +65 -0
  53. package/src/shared/ids-stream.ts +47 -0
  54. package/src/shared/sse-schema.ts +5 -0
  55. package/src/shared/text-utils.spec.ts +42 -0
  56. package/src/shared/text-utils.ts +8 -0
package/dist/client.d.mts CHANGED
@@ -2,7 +2,7 @@ import * as react from 'react';
2
2
  import { ReactNode, Context, RefObject } from 'react';
3
3
  import { ScrollBarThumbOverlayRenderProps, ScrollPaneInertiaOptions, ScrollBarTapCircleOptions } from '@aiquants/virtualscroll';
4
4
  import { D as DailyReportAttachmentSummary, a as DailyReportItem, b as DailyReportDetail, c as DailyReportUser } from './types-Ct1ggzy-.mjs';
5
- import { U as UIComment, D as DailyReportSseMessage } from './sse-schema-Df49KA7B.mjs';
5
+ import { U as UIComment, D as DailyReportSseMessage } from './sse-schema-BiUnufrI.mjs';
6
6
  import { ShouldRevalidateFunction } from 'react-router';
7
7
  import 'zod';
8
8
 
@@ -115,8 +115,6 @@ declare const DailyReportIdsStreamStatus: () => react.JSX.Element | null;
115
115
 
116
116
  type DailyReportListProps = {
117
117
  dailyReportItems: DailyReportItem[];
118
- initialSelectedBusinessDate?: string | null;
119
- initialSelectedReportHubId?: number | null;
120
118
  autoMarkRead?: boolean;
121
119
  selectedReportHubId: number | null;
122
120
  onSelectItem: (reportHubId: number | null) => void;
@@ -128,7 +126,7 @@ type DailyReportListProps = {
128
126
  * Daily report list cards with key metadata and preview content via virtual scrolling.
129
127
  * 主なメタデータと内容プレビューを仮想スクロール表示する日報リスト。
130
128
  */
131
- declare const DailyReportList: ({ dailyReportItems, initialSelectedBusinessDate, initialSelectedReportHubId, autoMarkRead, selectedReportHubId, onSelectItem, userId, initialScrollOffset, onScrollOffsetChange }: DailyReportListProps) => react.JSX.Element;
129
+ declare const DailyReportList: ({ dailyReportItems, autoMarkRead, selectedReportHubId, onSelectItem, userId, initialScrollOffset, onScrollOffsetChange }: DailyReportListProps) => react.JSX.Element;
132
130
 
133
131
  /** ヘッダー描画スロットに渡される引数。 */
134
132
  type DailyReportHeaderProps = {
@@ -167,6 +165,18 @@ type DailyReportFieldLabels = {
167
165
  tabRelations: string;
168
166
  relationsEmpty: string;
169
167
  };
168
+ /**
169
+ * Mutation-failure notification payload (for a host-supplied error surface).
170
+ * ミューテーション失敗の通知情報 (ホストが独自の通知 UI を出すための口)。
171
+ */
172
+ type DailyReportErrorInfo = {
173
+ /** 失敗した操作の種別 (create / update / publish / delete / addComment / deleteComment / toggleStar / toggleRead)。 */
174
+ operation: string;
175
+ /** 表示用のメッセージ (パッケージ内蔵バナー用)。 */
176
+ message: string;
177
+ /** 元例外 (診断用)。 */
178
+ cause?: unknown;
179
+ };
170
180
  /** データソースごとのバッジ表示設定。 */
171
181
  type SourceTypeConfig = {
172
182
  label: string;
@@ -192,6 +202,11 @@ type DailyReportClientConfig = {
192
202
  renderHeader: (props: DailyReportHeaderProps) => ReactNode;
193
203
  /** 開発向けコントロール (SSE 購読トグル等) を表示するか。 */
194
204
  showDevControls: boolean;
205
+ /**
206
+ * ミューテーション失敗時の通知ポート。未指定ならパッケージ内蔵の role="alert"
207
+ * バナーで表示する。ホストが独自トースト等を持つ場合はここへ委譲する。
208
+ */
209
+ onError?: (info: DailyReportErrorInfo) => void;
195
210
  };
196
211
  /**
197
212
  * Partial client-config override. `fieldLabels` may itself be partially overridden.
@@ -350,6 +365,25 @@ declare const DailyReportActionProvider: ({ children, user, initialItems, userId
350
365
  userId?: string | null;
351
366
  }) => react.JSX.Element;
352
367
 
368
+ type DailyReportErrorSurface = {
369
+ /** ミューテーション失敗を通知する。 */
370
+ notifyError: (info: DailyReportErrorInfo) => void;
371
+ };
372
+ /**
373
+ * Returns the error-surface API (safe no-op outside the provider).
374
+ * 通知 API を返す処理 (Provider 外では no-op)。
375
+ */
376
+ declare const useDailyReportErrorSurface: () => DailyReportErrorSurface;
377
+ /**
378
+ * Provides the mutation error surface and renders the default alert banner.
379
+ * ミューテーション通知シームを供給し、既定のアラートバナーを描画するプロバイダー。
380
+ *
381
+ * `config.onError` があればホストへ委譲し、内蔵バナーは描画しない (二重表示防止)。
382
+ */
383
+ declare const DailyReportErrorProvider: ({ children }: {
384
+ children: ReactNode;
385
+ }) => react.JSX.Element;
386
+
353
387
  /**
354
388
  * Animates numeric changes with ease-out cubic.
355
389
  * 数値変化をイーズアウト 3 次で補間するフック。
@@ -468,7 +502,21 @@ declare const registerRecentDeletion: (cId: number) => Map<number, number>;
468
502
  * 解除関数を返す。
469
503
  */
470
504
  declare const subscribeCacheReady: (reportHubId: number, callback: () => void) => (() => void);
471
- declare const applyDailyReportServerUpdates: (_reportHubIdd: number, report: DailyReportDetail) => void;
505
+ declare const applyDailyReportServerUpdates: (_reportHubId: number, report: DailyReportDetail) => void;
506
+ /**
507
+ * Applies a broadcast (cross-user SSE) report while preserving the viewer's own per-viewer state.
508
+ * 全ユーザー放送 (SSE) の report を、受信者自身の per-viewer 状態を保持したまま反映する処理。
509
+ *
510
+ * SSE の report-create/update/publish が運ぶ isRead/isStarred は**操作した本人の状態**。
511
+ * そのまま書くと受信者の既読/スター表示が他人の状態で上書きされる。共有フィールドだけを
512
+ * 取り込み、per-viewer フィールドは受信者のキャッシュ値を保持する。ローカルに無い日報は
513
+ * 種まきしない (送信者の per-viewer 値で汚すより、次のフェッチが受信者視点の正しい値を
514
+ * 取るのに任せるほうが安全)。
515
+ *
516
+ * ❗ 信頼できる経路 (自分の HTTP 応答・recipient フィルタ済みの自分宛 status-update) は
517
+ * {@link applyDailyReportServerUpdates} を使うこと — そちらは値をそのまま書く。
518
+ */
519
+ declare const applyBroadcastReportUpdate: (report: DailyReportDetail) => void;
472
520
  type DailyReportDetailResource = {
473
521
  report: DailyReportDetail | null;
474
522
  error: Error | null;
@@ -616,6 +664,13 @@ type DailyReportIdsStreamClientOptions = {
616
664
  /** タイマー実装 (既定 setTimeout / clearTimeout)。 */
617
665
  setTimeoutFn?: (handler: () => void, ms: number) => ReturnType<typeof setTimeout>;
618
666
  clearTimeoutFn?: (id: ReturnType<typeof setTimeout>) => void;
667
+ /**
668
+ * 1 回の read が無音でいられる上限 (ms)。0 以下で無効。
669
+ * これを超えたら接続を half-open とみなして中断し、retryable として
670
+ * カーソル再開へ倒す。サーバーのハートビート間隔より必ず長く取る
671
+ * (生きているが遅いだけの全量クエリ待ちを誤って切らないため)。
672
+ */
673
+ readStallTimeoutMs?: number;
619
674
  /** 警告ロガー (既定 console.warn)。 */
620
675
  warn?: (...args: unknown[]) => void;
621
676
  /**
@@ -636,6 +691,8 @@ declare class DailyReportIdsStreamClient {
636
691
  private readonly setTimeoutFn;
637
692
  private readonly clearTimeoutFn;
638
693
  private readonly warn;
694
+ /** 1 回の read が無音でいられる上限 (ms)。0 以下で無効。 */
695
+ private readonly readStallTimeoutMs;
639
696
  /** reportHubId → アイテム。挿入順を保ち、再開の重複到着を吸収する。 */
640
697
  private readonly itemMap;
641
698
  private readonly listeners;
@@ -755,6 +812,19 @@ declare class DailyReportIdsStreamClient {
755
812
  * 1 回のストリーミング試行を実行し、結末を分類する処理。
756
813
  */
757
814
  private streamOnce;
815
+ /**
816
+ * Reads one chunk, racing the read against a stall watchdog.
817
+ * 1 チャンクを読む処理。読み取りを stall ウォッチドッグと競争させる。
818
+ *
819
+ * サーバーが無音のまま接続を half-open で放置しても (NAT/プロキシのアイドル切断・
820
+ * VPN 断・スリープ)、`reader.read()` は永久に保留したままになる。これを検知するため
821
+ * read とタイマーを競争させ、無音が上限を超えたら番兵を返す。生きているが遅いだけの
822
+ * 全量クエリ待ちはサーバーのハートビート (空行) が read を解決するので誤検知しない。
823
+ * `readStallTimeoutMs <= 0` のときは素の read (タイマーを張らない・テスト用)。
824
+ *
825
+ * @returns 読み取り結果、または stall を表す番兵。read の reject はそのまま伝播する。
826
+ */
827
+ private readWithStallGuard;
758
828
  /**
759
829
  * Merges chunk items into the dedupe map.
760
830
  * チャンクのアイテム群を重複排除 Map へ取り込む処理。
@@ -964,4 +1034,4 @@ declare const TAP_SCROLL_CIRCLE_OPTIONS: ScrollBarTapCircleOptions;
964
1034
  */
965
1035
  declare const CONTENT_DRAG_POINTER_INPUTS: readonly ["pen", "touch"];
966
1036
 
967
- export { BusinessDayThumbOverlay, CONTENT_DRAG_POINTER_INPUTS, DAILY_REPORT_FETCH_DEBOUNCE_MS, DEFAULT_ITEM_HEIGHT, type DailyReportActionContextType, DailyReportActionProvider, DailyReportAttachmentIndicator, DailyReportAttachmentList, DailyReportCache, type DailyReportClientConfig, type DailyReportClientConfigInput, DailyReportCommentForm, DailyReportCommentItem, DailyReportCommentList, DailyReportConfigProvider, DailyReportDetailList, type DailyReportDetailResource, DailyReportEditForm, type DailyReportFieldLabels, type DailyReportHeaderProps, DailyReportIdsStreamClient, type DailyReportIdsStreamClientOptions, type DailyReportIdsStreamPhase, type DailyReportIdsStreamState, DailyReportIdsStreamStatus, DailyReportList, DailyReportLoadError, DailyReportLoading, DailyReportPage, type DailyReportPageProps, DailyReportResolvedContent, EMPTY_DETAIL, EMPTY_ITEM, FAST_SCROLL_INERTIA_OPTIONS, FAST_SCROLL_WHEEL_MULTIPLIER, ITEM_CONTAINER_HEIGHT, ITEM_VERTICAL_PADDING, MAX_PREVIEW_LINES, PREFETCH_LOOKAHEAD, PREFETCH_MAX_DATES, SCROLL_BAR_WIDTH, type SourceTypeConfig, TAP_SCROLL_CIRCLE_OPTIONS, UnreadIndicator, VIRTUAL_SCROLL_OVERSCAN_COUNT, WHEEL_RESET_TIMEOUT_MS, acquireMutationLock, applyDailyReportServerUpdates, bootstrapDailyReportIdsStreamSession, clearDailyReportCache, createDailyReportClientLoader, dailyReportShouldRevalidate, defaultDailyReportClientConfig, defaultDailyReportFieldLabels, deleteDailyReportCache, ensureDailyReportIdsStreamSession, getCachedReport, getDailyReportIdsStreamSessionUserKey, primeDailyReportIdsStreamSession, refreshDailyReportIdsStream, registerRecentDeletion, releaseMutationLock, reloadDocument, removeDailyReportIdsStreamItem, resetDailyReportIdsStreamSessionForTesting, resolveSourceTypeConfig, retryDailyReportIdsStream, subscribeCacheReady, updateDailyReportCache, upsertDailyReportIdsStreamItem, useAnimatedNumber, useDailyReportActionContext, useDailyReportComments, useDailyReportConfig, useDailyReportDetail, useDailyReportIdsStream, useDailyReportPrefetch, useDailyReportSseConnection, useDynamicViewportHeight, writeCache };
1037
+ export { BusinessDayThumbOverlay, CONTENT_DRAG_POINTER_INPUTS, DAILY_REPORT_FETCH_DEBOUNCE_MS, DEFAULT_ITEM_HEIGHT, type DailyReportActionContextType, DailyReportActionProvider, DailyReportAttachmentIndicator, DailyReportAttachmentList, DailyReportCache, type DailyReportClientConfig, type DailyReportClientConfigInput, DailyReportCommentForm, DailyReportCommentItem, DailyReportCommentList, DailyReportConfigProvider, DailyReportDetailList, type DailyReportDetailResource, DailyReportEditForm, type DailyReportErrorInfo, DailyReportErrorProvider, type DailyReportFieldLabels, type DailyReportHeaderProps, DailyReportIdsStreamClient, type DailyReportIdsStreamClientOptions, type DailyReportIdsStreamPhase, type DailyReportIdsStreamState, DailyReportIdsStreamStatus, DailyReportList, DailyReportLoadError, DailyReportLoading, DailyReportPage, type DailyReportPageProps, DailyReportResolvedContent, EMPTY_DETAIL, EMPTY_ITEM, FAST_SCROLL_INERTIA_OPTIONS, FAST_SCROLL_WHEEL_MULTIPLIER, ITEM_CONTAINER_HEIGHT, ITEM_VERTICAL_PADDING, MAX_PREVIEW_LINES, PREFETCH_LOOKAHEAD, PREFETCH_MAX_DATES, SCROLL_BAR_WIDTH, type SourceTypeConfig, TAP_SCROLL_CIRCLE_OPTIONS, UnreadIndicator, VIRTUAL_SCROLL_OVERSCAN_COUNT, WHEEL_RESET_TIMEOUT_MS, acquireMutationLock, applyBroadcastReportUpdate, applyDailyReportServerUpdates, bootstrapDailyReportIdsStreamSession, clearDailyReportCache, createDailyReportClientLoader, dailyReportShouldRevalidate, defaultDailyReportClientConfig, defaultDailyReportFieldLabels, deleteDailyReportCache, ensureDailyReportIdsStreamSession, getCachedReport, getDailyReportIdsStreamSessionUserKey, primeDailyReportIdsStreamSession, refreshDailyReportIdsStream, registerRecentDeletion, releaseMutationLock, reloadDocument, removeDailyReportIdsStreamItem, resetDailyReportIdsStreamSessionForTesting, resolveSourceTypeConfig, retryDailyReportIdsStream, subscribeCacheReady, updateDailyReportCache, upsertDailyReportIdsStreamItem, useAnimatedNumber, useDailyReportActionContext, useDailyReportComments, useDailyReportConfig, useDailyReportDetail, useDailyReportErrorSurface, useDailyReportIdsStream, useDailyReportPrefetch, useDailyReportSseConnection, useDynamicViewportHeight, writeCache };
package/dist/client.d.ts CHANGED
@@ -2,7 +2,7 @@ import * as react from 'react';
2
2
  import { ReactNode, Context, RefObject } from 'react';
3
3
  import { ScrollBarThumbOverlayRenderProps, ScrollPaneInertiaOptions, ScrollBarTapCircleOptions } from '@aiquants/virtualscroll';
4
4
  import { D as DailyReportAttachmentSummary, a as DailyReportItem, b as DailyReportDetail, c as DailyReportUser } from './types-Ct1ggzy-.js';
5
- import { U as UIComment, D as DailyReportSseMessage } from './sse-schema-RHckD7TS.js';
5
+ import { U as UIComment, D as DailyReportSseMessage } from './sse-schema-YZh7Pz7i.js';
6
6
  import { ShouldRevalidateFunction } from 'react-router';
7
7
  import 'zod';
8
8
 
@@ -115,8 +115,6 @@ declare const DailyReportIdsStreamStatus: () => react.JSX.Element | null;
115
115
 
116
116
  type DailyReportListProps = {
117
117
  dailyReportItems: DailyReportItem[];
118
- initialSelectedBusinessDate?: string | null;
119
- initialSelectedReportHubId?: number | null;
120
118
  autoMarkRead?: boolean;
121
119
  selectedReportHubId: number | null;
122
120
  onSelectItem: (reportHubId: number | null) => void;
@@ -128,7 +126,7 @@ type DailyReportListProps = {
128
126
  * Daily report list cards with key metadata and preview content via virtual scrolling.
129
127
  * 主なメタデータと内容プレビューを仮想スクロール表示する日報リスト。
130
128
  */
131
- declare const DailyReportList: ({ dailyReportItems, initialSelectedBusinessDate, initialSelectedReportHubId, autoMarkRead, selectedReportHubId, onSelectItem, userId, initialScrollOffset, onScrollOffsetChange }: DailyReportListProps) => react.JSX.Element;
129
+ declare const DailyReportList: ({ dailyReportItems, autoMarkRead, selectedReportHubId, onSelectItem, userId, initialScrollOffset, onScrollOffsetChange }: DailyReportListProps) => react.JSX.Element;
132
130
 
133
131
  /** ヘッダー描画スロットに渡される引数。 */
134
132
  type DailyReportHeaderProps = {
@@ -167,6 +165,18 @@ type DailyReportFieldLabels = {
167
165
  tabRelations: string;
168
166
  relationsEmpty: string;
169
167
  };
168
+ /**
169
+ * Mutation-failure notification payload (for a host-supplied error surface).
170
+ * ミューテーション失敗の通知情報 (ホストが独自の通知 UI を出すための口)。
171
+ */
172
+ type DailyReportErrorInfo = {
173
+ /** 失敗した操作の種別 (create / update / publish / delete / addComment / deleteComment / toggleStar / toggleRead)。 */
174
+ operation: string;
175
+ /** 表示用のメッセージ (パッケージ内蔵バナー用)。 */
176
+ message: string;
177
+ /** 元例外 (診断用)。 */
178
+ cause?: unknown;
179
+ };
170
180
  /** データソースごとのバッジ表示設定。 */
171
181
  type SourceTypeConfig = {
172
182
  label: string;
@@ -192,6 +202,11 @@ type DailyReportClientConfig = {
192
202
  renderHeader: (props: DailyReportHeaderProps) => ReactNode;
193
203
  /** 開発向けコントロール (SSE 購読トグル等) を表示するか。 */
194
204
  showDevControls: boolean;
205
+ /**
206
+ * ミューテーション失敗時の通知ポート。未指定ならパッケージ内蔵の role="alert"
207
+ * バナーで表示する。ホストが独自トースト等を持つ場合はここへ委譲する。
208
+ */
209
+ onError?: (info: DailyReportErrorInfo) => void;
195
210
  };
196
211
  /**
197
212
  * Partial client-config override. `fieldLabels` may itself be partially overridden.
@@ -350,6 +365,25 @@ declare const DailyReportActionProvider: ({ children, user, initialItems, userId
350
365
  userId?: string | null;
351
366
  }) => react.JSX.Element;
352
367
 
368
+ type DailyReportErrorSurface = {
369
+ /** ミューテーション失敗を通知する。 */
370
+ notifyError: (info: DailyReportErrorInfo) => void;
371
+ };
372
+ /**
373
+ * Returns the error-surface API (safe no-op outside the provider).
374
+ * 通知 API を返す処理 (Provider 外では no-op)。
375
+ */
376
+ declare const useDailyReportErrorSurface: () => DailyReportErrorSurface;
377
+ /**
378
+ * Provides the mutation error surface and renders the default alert banner.
379
+ * ミューテーション通知シームを供給し、既定のアラートバナーを描画するプロバイダー。
380
+ *
381
+ * `config.onError` があればホストへ委譲し、内蔵バナーは描画しない (二重表示防止)。
382
+ */
383
+ declare const DailyReportErrorProvider: ({ children }: {
384
+ children: ReactNode;
385
+ }) => react.JSX.Element;
386
+
353
387
  /**
354
388
  * Animates numeric changes with ease-out cubic.
355
389
  * 数値変化をイーズアウト 3 次で補間するフック。
@@ -468,7 +502,21 @@ declare const registerRecentDeletion: (cId: number) => Map<number, number>;
468
502
  * 解除関数を返す。
469
503
  */
470
504
  declare const subscribeCacheReady: (reportHubId: number, callback: () => void) => (() => void);
471
- declare const applyDailyReportServerUpdates: (_reportHubIdd: number, report: DailyReportDetail) => void;
505
+ declare const applyDailyReportServerUpdates: (_reportHubId: number, report: DailyReportDetail) => void;
506
+ /**
507
+ * Applies a broadcast (cross-user SSE) report while preserving the viewer's own per-viewer state.
508
+ * 全ユーザー放送 (SSE) の report を、受信者自身の per-viewer 状態を保持したまま反映する処理。
509
+ *
510
+ * SSE の report-create/update/publish が運ぶ isRead/isStarred は**操作した本人の状態**。
511
+ * そのまま書くと受信者の既読/スター表示が他人の状態で上書きされる。共有フィールドだけを
512
+ * 取り込み、per-viewer フィールドは受信者のキャッシュ値を保持する。ローカルに無い日報は
513
+ * 種まきしない (送信者の per-viewer 値で汚すより、次のフェッチが受信者視点の正しい値を
514
+ * 取るのに任せるほうが安全)。
515
+ *
516
+ * ❗ 信頼できる経路 (自分の HTTP 応答・recipient フィルタ済みの自分宛 status-update) は
517
+ * {@link applyDailyReportServerUpdates} を使うこと — そちらは値をそのまま書く。
518
+ */
519
+ declare const applyBroadcastReportUpdate: (report: DailyReportDetail) => void;
472
520
  type DailyReportDetailResource = {
473
521
  report: DailyReportDetail | null;
474
522
  error: Error | null;
@@ -616,6 +664,13 @@ type DailyReportIdsStreamClientOptions = {
616
664
  /** タイマー実装 (既定 setTimeout / clearTimeout)。 */
617
665
  setTimeoutFn?: (handler: () => void, ms: number) => ReturnType<typeof setTimeout>;
618
666
  clearTimeoutFn?: (id: ReturnType<typeof setTimeout>) => void;
667
+ /**
668
+ * 1 回の read が無音でいられる上限 (ms)。0 以下で無効。
669
+ * これを超えたら接続を half-open とみなして中断し、retryable として
670
+ * カーソル再開へ倒す。サーバーのハートビート間隔より必ず長く取る
671
+ * (生きているが遅いだけの全量クエリ待ちを誤って切らないため)。
672
+ */
673
+ readStallTimeoutMs?: number;
619
674
  /** 警告ロガー (既定 console.warn)。 */
620
675
  warn?: (...args: unknown[]) => void;
621
676
  /**
@@ -636,6 +691,8 @@ declare class DailyReportIdsStreamClient {
636
691
  private readonly setTimeoutFn;
637
692
  private readonly clearTimeoutFn;
638
693
  private readonly warn;
694
+ /** 1 回の read が無音でいられる上限 (ms)。0 以下で無効。 */
695
+ private readonly readStallTimeoutMs;
639
696
  /** reportHubId → アイテム。挿入順を保ち、再開の重複到着を吸収する。 */
640
697
  private readonly itemMap;
641
698
  private readonly listeners;
@@ -755,6 +812,19 @@ declare class DailyReportIdsStreamClient {
755
812
  * 1 回のストリーミング試行を実行し、結末を分類する処理。
756
813
  */
757
814
  private streamOnce;
815
+ /**
816
+ * Reads one chunk, racing the read against a stall watchdog.
817
+ * 1 チャンクを読む処理。読み取りを stall ウォッチドッグと競争させる。
818
+ *
819
+ * サーバーが無音のまま接続を half-open で放置しても (NAT/プロキシのアイドル切断・
820
+ * VPN 断・スリープ)、`reader.read()` は永久に保留したままになる。これを検知するため
821
+ * read とタイマーを競争させ、無音が上限を超えたら番兵を返す。生きているが遅いだけの
822
+ * 全量クエリ待ちはサーバーのハートビート (空行) が read を解決するので誤検知しない。
823
+ * `readStallTimeoutMs <= 0` のときは素の read (タイマーを張らない・テスト用)。
824
+ *
825
+ * @returns 読み取り結果、または stall を表す番兵。read の reject はそのまま伝播する。
826
+ */
827
+ private readWithStallGuard;
758
828
  /**
759
829
  * Merges chunk items into the dedupe map.
760
830
  * チャンクのアイテム群を重複排除 Map へ取り込む処理。
@@ -964,4 +1034,4 @@ declare const TAP_SCROLL_CIRCLE_OPTIONS: ScrollBarTapCircleOptions;
964
1034
  */
965
1035
  declare const CONTENT_DRAG_POINTER_INPUTS: readonly ["pen", "touch"];
966
1036
 
967
- export { BusinessDayThumbOverlay, CONTENT_DRAG_POINTER_INPUTS, DAILY_REPORT_FETCH_DEBOUNCE_MS, DEFAULT_ITEM_HEIGHT, type DailyReportActionContextType, DailyReportActionProvider, DailyReportAttachmentIndicator, DailyReportAttachmentList, DailyReportCache, type DailyReportClientConfig, type DailyReportClientConfigInput, DailyReportCommentForm, DailyReportCommentItem, DailyReportCommentList, DailyReportConfigProvider, DailyReportDetailList, type DailyReportDetailResource, DailyReportEditForm, type DailyReportFieldLabels, type DailyReportHeaderProps, DailyReportIdsStreamClient, type DailyReportIdsStreamClientOptions, type DailyReportIdsStreamPhase, type DailyReportIdsStreamState, DailyReportIdsStreamStatus, DailyReportList, DailyReportLoadError, DailyReportLoading, DailyReportPage, type DailyReportPageProps, DailyReportResolvedContent, EMPTY_DETAIL, EMPTY_ITEM, FAST_SCROLL_INERTIA_OPTIONS, FAST_SCROLL_WHEEL_MULTIPLIER, ITEM_CONTAINER_HEIGHT, ITEM_VERTICAL_PADDING, MAX_PREVIEW_LINES, PREFETCH_LOOKAHEAD, PREFETCH_MAX_DATES, SCROLL_BAR_WIDTH, type SourceTypeConfig, TAP_SCROLL_CIRCLE_OPTIONS, UnreadIndicator, VIRTUAL_SCROLL_OVERSCAN_COUNT, WHEEL_RESET_TIMEOUT_MS, acquireMutationLock, applyDailyReportServerUpdates, bootstrapDailyReportIdsStreamSession, clearDailyReportCache, createDailyReportClientLoader, dailyReportShouldRevalidate, defaultDailyReportClientConfig, defaultDailyReportFieldLabels, deleteDailyReportCache, ensureDailyReportIdsStreamSession, getCachedReport, getDailyReportIdsStreamSessionUserKey, primeDailyReportIdsStreamSession, refreshDailyReportIdsStream, registerRecentDeletion, releaseMutationLock, reloadDocument, removeDailyReportIdsStreamItem, resetDailyReportIdsStreamSessionForTesting, resolveSourceTypeConfig, retryDailyReportIdsStream, subscribeCacheReady, updateDailyReportCache, upsertDailyReportIdsStreamItem, useAnimatedNumber, useDailyReportActionContext, useDailyReportComments, useDailyReportConfig, useDailyReportDetail, useDailyReportIdsStream, useDailyReportPrefetch, useDailyReportSseConnection, useDynamicViewportHeight, writeCache };
1037
+ export { BusinessDayThumbOverlay, CONTENT_DRAG_POINTER_INPUTS, DAILY_REPORT_FETCH_DEBOUNCE_MS, DEFAULT_ITEM_HEIGHT, type DailyReportActionContextType, DailyReportActionProvider, DailyReportAttachmentIndicator, DailyReportAttachmentList, DailyReportCache, type DailyReportClientConfig, type DailyReportClientConfigInput, DailyReportCommentForm, DailyReportCommentItem, DailyReportCommentList, DailyReportConfigProvider, DailyReportDetailList, type DailyReportDetailResource, DailyReportEditForm, type DailyReportErrorInfo, DailyReportErrorProvider, type DailyReportFieldLabels, type DailyReportHeaderProps, DailyReportIdsStreamClient, type DailyReportIdsStreamClientOptions, type DailyReportIdsStreamPhase, type DailyReportIdsStreamState, DailyReportIdsStreamStatus, DailyReportList, DailyReportLoadError, DailyReportLoading, DailyReportPage, type DailyReportPageProps, DailyReportResolvedContent, EMPTY_DETAIL, EMPTY_ITEM, FAST_SCROLL_INERTIA_OPTIONS, FAST_SCROLL_WHEEL_MULTIPLIER, ITEM_CONTAINER_HEIGHT, ITEM_VERTICAL_PADDING, MAX_PREVIEW_LINES, PREFETCH_LOOKAHEAD, PREFETCH_MAX_DATES, SCROLL_BAR_WIDTH, type SourceTypeConfig, TAP_SCROLL_CIRCLE_OPTIONS, UnreadIndicator, VIRTUAL_SCROLL_OVERSCAN_COUNT, WHEEL_RESET_TIMEOUT_MS, acquireMutationLock, applyBroadcastReportUpdate, applyDailyReportServerUpdates, bootstrapDailyReportIdsStreamSession, clearDailyReportCache, createDailyReportClientLoader, dailyReportShouldRevalidate, defaultDailyReportClientConfig, defaultDailyReportFieldLabels, deleteDailyReportCache, ensureDailyReportIdsStreamSession, getCachedReport, getDailyReportIdsStreamSessionUserKey, primeDailyReportIdsStreamSession, refreshDailyReportIdsStream, registerRecentDeletion, releaseMutationLock, reloadDocument, removeDailyReportIdsStreamItem, resetDailyReportIdsStreamSessionForTesting, resolveSourceTypeConfig, retryDailyReportIdsStream, subscribeCacheReady, updateDailyReportCache, upsertDailyReportIdsStreamItem, useAnimatedNumber, useDailyReportActionContext, useDailyReportComments, useDailyReportConfig, useDailyReportDetail, useDailyReportErrorSurface, useDailyReportIdsStream, useDailyReportPrefetch, useDailyReportSseConnection, useDynamicViewportHeight, writeCache };