react-semaphor 0.1.542 → 0.1.544

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 (66) hide show
  1. package/dist/activity/index.js +73 -0
  2. package/dist/assistant-context/index.js +1 -1
  3. package/dist/briefings/index.js +51 -50
  4. package/dist/chunks/{apply-dashboard-operations-Btbp2-6v.js → apply-dashboard-operations-Bz4n1Lq6.js} +44 -44
  5. package/dist/chunks/{assistant-chat-oHF5lTjA.js → assistant-chat-BNLkCDml.js} +288 -288
  6. package/dist/chunks/{comparison-window-caption-ChIyd_-L.js → comparison-window-caption-BTkrN3W4.js} +468 -463
  7. package/dist/chunks/dashboard-briefing-launcher-DQ_8O_e2.js +3725 -0
  8. package/dist/chunks/{dashboard-controls-CIn22Qgp.js → dashboard-controls-8RyBTQUO.js} +530 -525
  9. package/dist/chunks/dashboard-g5a4DKWq.js +14 -0
  10. package/dist/chunks/{dashboard-json-ZUYsIExq.js → dashboard-json-7qT9jmfL.js} +1 -1
  11. package/dist/chunks/{document-dashboard-inputs-C6MJVyoI.js → document-dashboard-inputs-BC6p-ESg.js} +4 -4
  12. package/dist/chunks/{document-sheet-utils-BsZUnHRl.js → document-sheet-utils-Duo9uLoH.js} +11 -11
  13. package/dist/chunks/{edit-dashboard-visual-DLdereA7.js → edit-dashboard-visual-BfJwnRIZ.js} +249 -248
  14. package/dist/chunks/export-file-format-C-tJsxsf.js +111 -0
  15. package/dist/chunks/{index-CV5rHq5D.js → index-DkAyQvC6.js} +59 -58
  16. package/dist/chunks/{matrix-formatter-BnsTX90d.js → matrix-formatter-CxJLkztA.js} +1 -1
  17. package/dist/chunks/{numeric-presentation-BSAqPpHt.js → numeric-presentation-DESvLiu9.js} +1 -1
  18. package/dist/chunks/{pivot-result-lifecycle-BBlAfBA0.js → pivot-result-lifecycle-DM4CyGKs.js} +287 -395
  19. package/dist/chunks/{raw-temporal-presentation-CZ2r0Vb_.js → raw-temporal-presentation-CLiVi90c.js} +2 -2
  20. package/dist/chunks/{report-preferences-dialog-MRUWpMcJ.js → report-preferences-dialog-Df7VpRVW.js} +195 -195
  21. package/dist/chunks/{saved-dashboard-context-DjPqgFly.js → saved-dashboard-context-B-mQ--nV.js} +3 -3
  22. package/dist/chunks/{semaphor-ready-indicator-BWSpRsPj.js → semaphor-ready-indicator-DDAxk8us.js} +39892 -39380
  23. package/dist/chunks/{shelf-drop-preview-context-CQbFLm3q.js → shelf-drop-preview-context-BSRPwaED.js} +414 -371
  24. package/dist/chunks/{table-export-sheet-BHSnuZHd.js → table-export-sheet-CPfGAQ9X.js} +1 -1
  25. package/dist/chunks/{use-create-flow-overlay-state-BJDNqdOh.js → use-create-flow-overlay-state-BxzFviM-.js} +67 -78
  26. package/dist/dashboard/index.js +1 -1
  27. package/dist/dashboard-authoring/index.js +72 -72
  28. package/dist/data-app-sdk/index.js +1 -1
  29. package/dist/format-utils/index.js +226 -223
  30. package/dist/index.js +266 -271
  31. package/dist/style.css +1 -1
  32. package/dist/surfboard/index.js +1 -1
  33. package/dist/types/activity.d.ts +2 -0
  34. package/dist/types/components/activity/activity-bell.d.ts +11 -0
  35. package/dist/types/components/activity/activity-instance.d.ts +50 -0
  36. package/dist/types/components/activity/activity-notices.d.ts +7 -0
  37. package/dist/types/components/activity/activity-provider.d.ts +21 -0
  38. package/dist/types/components/activity/activity-types.d.ts +177 -0
  39. package/dist/types/components/activity/index.d.ts +6 -0
  40. package/dist/types/components/activity/use-activity.d.ts +20 -0
  41. package/dist/types/components/briefings/briefing-author/run-model.d.ts +1 -2
  42. package/dist/types/components/briefings/briefing-author.d.ts +14 -12
  43. package/dist/types/components/briefings/dashboard-briefing-launcher.d.ts +5 -0
  44. package/dist/types/components/briefings/use-briefing-run-detail.d.ts +34 -0
  45. package/dist/types/components/index.d.ts +1 -4
  46. package/dist/types/lib/activity-identity.d.ts +21 -0
  47. package/dist/types/lib/api/exports-api.d.ts +4 -4
  48. package/dist/types/lib/hooks/index.d.ts +1 -3
  49. package/dist/types/lib/matrix-table/matrix-delivery.d.ts +4 -0
  50. package/dist/types/shared/activity/activity-contract.d.ts +84 -0
  51. package/dist/types/shared/activity/index.d.ts +5 -0
  52. package/dist/types/shared/dashboard-authoring/card-export-request.d.ts +6 -0
  53. package/dist/types/shared/format-utils/export-policy.d.ts +12 -0
  54. package/package.json +5 -1
  55. package/dist/chunks/dashboard-briefing-launcher-B-cm719R.js +0 -4248
  56. package/dist/chunks/dashboard-s5WJBcK8.js +0 -14
  57. package/dist/types/components/briefings/briefing-author/run-ui.d.ts +0 -81
  58. package/dist/types/components/briefings/use-briefing-run-polling.d.ts +0 -34
  59. package/dist/types/components/notifications/export-notification-item.d.ts +0 -24
  60. package/dist/types/components/notifications/export-notification-list.d.ts +0 -8
  61. package/dist/types/components/notifications/index.d.ts +0 -3
  62. package/dist/types/components/notifications/notification-bell.d.ts +0 -13
  63. package/dist/types/lib/exports/bounded-request.d.ts +0 -12
  64. package/dist/types/lib/hooks/use-export-polling.d.ts +0 -32
  65. package/dist/types/lib/hooks/use-export-recovery.d.ts +0 -11
  66. package/dist/types/lib/stores/export-store.d.ts +0 -62
@@ -1,4 +1,4 @@
1
- import { a, R as s, D as o } from "../chunks/report-preferences-dialog-MRUWpMcJ.js";
1
+ import { a, R as s, D as o } from "../chunks/report-preferences-dialog-Df7VpRVW.js";
2
2
  import { C as f, E as D } from "../chunks/table-settings-CLZocegs.js";
3
3
  export {
4
4
  f as CONTROL_CARD_DEFAULT_VALUE,
@@ -0,0 +1,2 @@
1
+ export * from './shared/activity/index.js'
2
+ export {}
@@ -0,0 +1,11 @@
1
+ import { default as React } from 'react';
2
+ /**
3
+ * The bell is a button over the nearest Activity provider (background-activity
4
+ * BA-D9): the package toolbar, the app's navbar and the Briefings page header.
5
+ * The badge counts running work, or shows a dot for finished work not seen yet.
6
+ */
7
+ export declare function ActivityBell({ variant }: {
8
+ variant?: 'outline' | 'ghost';
9
+ }): React.JSX.Element;
10
+ /** Every export and Briefing run the person started, running first (SPEC §2.5). Mounted only while open. */
11
+ export declare function ActivityTray(): React.JSX.Element;
@@ -0,0 +1,50 @@
1
+ import { QueryClient, Query } from '@tanstack/react-query';
2
+ import { StoreApi } from 'zustand/vanilla';
3
+ import { ActivityApi, ActivityData, ActivityLocalState, ActivitySnapshot, UserToken } from './activity-types.js';
4
+ /**
5
+ * One Activity instance per identity (background-activity SPEC §4.3, BA-D7):
6
+ * its own query client (passed to `useQuery`, never provided as context), its
7
+ * own local store, the watchers and the one clock. Everything that changes
8
+ * Activity state goes through here.
9
+ */
10
+ /** The page's user token Activity lists and cancels with. */
11
+ export type ActivityHost = UserToken;
12
+ export type ActivityClock = {
13
+ /** The current time, for decisions. */
14
+ now(): number;
15
+ /** The time of the last tick, stable between ticks, for rendering. */
16
+ tick(): number;
17
+ subscribe(listener: () => void): () => void;
18
+ };
19
+ /** The only interval in Activity code: one 1 s tick while anything subscribes (BA-INV-7). */
20
+ export declare function createActivityClock(): ActivityClock;
21
+ export type ActivityState = {
22
+ data: ActivityData | undefined;
23
+ local: ActivityLocalState;
24
+ };
25
+ export type ActivityInstance = {
26
+ readonly identityKey: string;
27
+ readonly queryKey: readonly ['activity', string];
28
+ readonly queryClient: QueryClient;
29
+ readonly store: StoreApi<ActivityLocalState>;
30
+ readonly clock: ActivityClock;
31
+ readonly api: ActivityApi;
32
+ getHost(): ActivityHost | null;
33
+ /** Same identity, new token (refresh, navigation): history stays; the next request uses it. */
34
+ setHost(host: ActivityHost | null): void;
35
+ /** False once the server rejected this user token, until a new one arrives. */
36
+ canList(): boolean;
37
+ setViewBriefingRun(view: ActivityApi['viewBriefingRun']): void;
38
+ setOnSessionExpired(callback: (() => void) | null): void;
39
+ /** Ends every live attempt (identity change or provider unmount). */
40
+ dispose(): void;
41
+ /** Holds a watch while mounted; returns the release. */
42
+ watch(watchId: string): () => void;
43
+ isWatched(id: string): boolean;
44
+ subscribe(listener: () => void): () => void;
45
+ getState(): ActivityState;
46
+ snapshotOf(state: ActivityState): ActivitySnapshot;
47
+ fetchActivity(signal: AbortSignal): Promise<ActivityData>;
48
+ pollInterval(query: Query<ActivityData, Error, ActivityData, readonly ['activity', string]>): number | false;
49
+ };
50
+ export declare function createActivityInstance(identityKey: string, host: ActivityHost | null): ActivityInstance;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The one completion message for work that finished while nobody watched it
3
+ * (background-activity BA-D8), rendered once per provider. A success notice
4
+ * hides after a few seconds by the Activity clock; a danger notice stays until
5
+ * dismissed. Never a toast (BA-INV-8).
6
+ */
7
+ export declare function ActivityNotices(): import("react").JSX.Element | null;
@@ -0,0 +1,21 @@
1
+ import { ReactNode } from 'react';
2
+ import { AuthToken } from '../../lib/types/common-types.js';
3
+ export declare function ActivityProvider({ children, authToken, onViewBriefingRun, }: {
4
+ children: ReactNode;
5
+ /** The page's user token, to list and cancel with. Null: Activity is inert. Omitted: read Surfboard's context. */
6
+ authToken?: AuthToken | null;
7
+ /** Opens a Briefing run where the host shows it (the app's run page). Omitted: Briefing rows offer no View. */
8
+ onViewBriefingRun?: (input: {
9
+ briefingId: string;
10
+ runId: string;
11
+ }) => void;
12
+ }): import("react").JSX.Element;
13
+ /**
14
+ * Reuses an outer provider of the same identity, so history is shared and one
15
+ * request lists it; otherwise mounts its own with `authToken` or Surfboard's
16
+ * context (an embed, a Briefing sheet outside the app).
17
+ */
18
+ export declare function ActivityScope({ children, authToken }: {
19
+ children: ReactNode;
20
+ authToken?: AuthToken | null;
21
+ }): import("react").JSX.Element;
@@ -0,0 +1,177 @@
1
+ import { ActivityItem, ExportActivityItem } from '../../shared/activity/index.js';
2
+ import { UserToken } from '../../lib/activity-identity.js';
3
+ /**
4
+ * The Activity client's shapes (background-activity SPEC §2.5, §4.3, §4.5).
5
+ * Server items live in the instance's query cache as merged records; the
6
+ * local store holds presentation state only.
7
+ */
8
+ export type { UserToken };
9
+ /** Reads the page's user token fresh for each request; nothing holds a copy. */
10
+ export type UserTokenReader = {
11
+ current(): UserToken | null;
12
+ };
13
+ /** One reconciled record per run; kept when a bounded response omits the run (BA-D15). */
14
+ export type ActivityRecord = {
15
+ item: ActivityItem;
16
+ /** Observed running here, or started here; first-sight finals are false. */
17
+ seenRunning: boolean;
18
+ notified: boolean;
19
+ /** When a response last included it. */
20
+ lastConfirmedAt: number;
21
+ };
22
+ export type ActivityData = {
23
+ records: ReadonlyMap<string, ActivityRecord>;
24
+ /** From the last response, newest first. */
25
+ activeIds: readonly string[];
26
+ recentIds: readonly string[];
27
+ activeTruncated: boolean;
28
+ };
29
+ /**
30
+ * A browser-only export (a direct file or a PDF) while it runs or its dialog
31
+ * shows it (BA-D5). Never a tray row: the server does not know it. Finishing
32
+ * after its dialog's line was shown and closed raises the one notice and
33
+ * removes it; finishing before the line first shows it (a synchronous file)
34
+ * or while it shows it raises none, and the line shows the result.
35
+ */
36
+ export type BrowserExport = {
37
+ /** 'browser:' + a random id; also the attempt's watch id. */
38
+ id: string;
39
+ title: string;
40
+ status: 'running' | 'ready' | 'failed' | 'cancelled';
41
+ /** 'starting' while a background start waits for the server's reply (M36). */
42
+ stage: 'preparing' | 'starting';
43
+ /** A line has watched it; until then the dialog that began it is about to show it. */
44
+ shown: boolean;
45
+ startedAt: string;
46
+ finishedAt: string | null;
47
+ failure: {
48
+ message: string;
49
+ } | null;
50
+ /** Rows and size of a finished file, for the line and the notice. */
51
+ details?: {
52
+ rows?: number;
53
+ fileSize?: number;
54
+ };
55
+ };
56
+ export type TrackInput = {
57
+ kind: 'export';
58
+ id: string;
59
+ exportRequestId: string;
60
+ title: string;
61
+ format: ExportActivityItem['format'];
62
+ deadlineAt: string | null;
63
+ } | {
64
+ kind: 'briefing';
65
+ id: string;
66
+ title: string;
67
+ briefingId: string;
68
+ };
69
+ export type ActivityRowAction = 'download' | 'view' | 'cancel';
70
+ export type ActivityNotice = {
71
+ id: string;
72
+ tone: 'success' | 'danger';
73
+ /** M25 or M26. */
74
+ title: string;
75
+ /** Rows and size, the failure message, or M31. */
76
+ body: string;
77
+ /** The run or browser export the notice is about; a run's action is derived from its row when shown. */
78
+ rowId: string;
79
+ shownAt: number;
80
+ };
81
+ export type ActivityLocalState = {
82
+ browser: ReadonlyMap<string, BrowserExport>;
83
+ /** Tracked or handed off, not yet in a response. */
84
+ pending: ReadonlyMap<string, TrackInput & {
85
+ trackedAt: number;
86
+ }>;
87
+ /** A handed-off browser export's watch id to its run id. */
88
+ aliases: ReadonlyMap<string, string>;
89
+ /** Known non-final ids the last response omitted. */
90
+ unresolved: ReadonlySet<string>;
91
+ /** Local give-up or missing (M17), with when it was decided. */
92
+ overrides: ReadonlyMap<string, {
93
+ message: string;
94
+ at: number;
95
+ }>;
96
+ cleared: ReadonlySet<string>;
97
+ notices: readonly ActivityNotice[];
98
+ lastSeenFinishedAt: number;
99
+ };
100
+ /** A tray row: work the server runs (an export job or a Briefing run). */
101
+ export type ActivityRow = ActivityRecord;
102
+ /** What a watch id shows where the work started: a browser-only export, or a run. */
103
+ export type WatchedWork = {
104
+ kind: 'browser';
105
+ work: BrowserExport;
106
+ } | {
107
+ kind: 'run';
108
+ row: ActivityRow;
109
+ };
110
+ export type ActivitySnapshot = {
111
+ /** Running first, then newest finishedAt; cleared rows excluded. */
112
+ rows: readonly ActivityRow[];
113
+ runningCount: number;
114
+ hasUnseenFinished: boolean;
115
+ /** Shows M34. */
116
+ activeTruncated: boolean;
117
+ notices: readonly ActivityNotice[];
118
+ };
119
+ /** A browser-only export's handle, for the code that runs it. */
120
+ export type BrowserExportWork = {
121
+ id: string;
122
+ /** A background start was sent; the line reads "Starting..." until the server replies. */
123
+ starting(): void;
124
+ succeed(details?: {
125
+ rows?: number;
126
+ fileSize?: number;
127
+ }): void;
128
+ fail(message: string): void;
129
+ /** Stopped by the person: no notice. */
130
+ cancel(): void;
131
+ /** The server replied with a run: the run is tracked and this watch id follows it (the one identity transition, H-06). */
132
+ handOff(input: TrackInput): void;
133
+ };
134
+ export type ActivityApi = {
135
+ track(input: TrackInput): void;
136
+ begin(input: {
137
+ title: string;
138
+ }): BrowserExportWork;
139
+ clearFinished(): void;
140
+ dismissNotice(id: string): void;
141
+ /** Marks finished rows seen (the tray was opened). */
142
+ markSeen(): void;
143
+ /** Lists again now (the tray's refresh, which also lets a denied download sign again, M18). */
144
+ refresh(): void;
145
+ /** Call it inside the click: it opens the tab before signing. 'blocked': the browser blocked the tab (M37); 'denied': the link could not be signed (M18). */
146
+ download(id: string): Promise<'opened' | 'denied' | 'blocked'>;
147
+ /** Cancels a run with the page's user token. */
148
+ cancelExport(runId: string): Promise<void>;
149
+ /** Opens a Briefing run where the host shows it; null when nothing can. */
150
+ viewBriefingRun: ((input: {
151
+ briefingId: string;
152
+ runId: string;
153
+ }) => void) | null;
154
+ /** A surface that can open a Briefing run (the dashboard's Briefings sheet) offers itself while mounted; the host's page wins. */
155
+ registerBriefingViewer(view: (input: {
156
+ briefingId: string;
157
+ runId: string;
158
+ }) => void): () => void;
159
+ /** For an export attempt: the run row an id resolves to now (a handed-off watch id resolves to its run). */
160
+ row(id: string): ActivityRow | null;
161
+ /** For an export attempt: called on every Activity change. */
162
+ subscribe(listener: () => void): () => void;
163
+ /** The instance owns a live attempt: an identity change disposes it (SPEC §4.3). Returns the release. */
164
+ adopt(attempt: {
165
+ dispose(): void;
166
+ }): () => void;
167
+ };
168
+ export declare function isFinalStatus(status: ActivityItem['status'] | BrowserExport['status']): boolean;
169
+ export declare function rowId(row: ActivityRow): string;
170
+ /**
171
+ * The one action a row offers (SPEC §2.5): a ready export downloads, a
172
+ * Briefing run opens, a running export can be cancelled.
173
+ */
174
+ export declare function activityRowAction(row: ActivityRow, options: {
175
+ canViewBriefing: boolean;
176
+ }): ActivityRowAction | null;
177
+ export type { ActivityItem, ExportActivityItem };
@@ -0,0 +1,6 @@
1
+ export { ActivityProvider, ActivityScope } from './activity-provider.js';
2
+ export { useActivity, useWatchActivity, useActivityClock } from './use-activity.js';
3
+ export { ActivityBell, ActivityTray } from './activity-bell.js';
4
+ export { ActivityNotices } from './activity-notices.js';
5
+ export { activityRowAction } from './activity-types.js';
6
+ export type { ActivityApi, ActivityNotice, ActivityRecord, ActivityRow, ActivityRowAction, ActivitySnapshot, BrowserExport, BrowserExportWork, TrackInput, UserToken, UserTokenReader, WatchedWork, } from './activity-types.js';
@@ -0,0 +1,20 @@
1
+ import { ActivityInstance } from './activity-instance.js';
2
+ import { ActivityApi, ActivitySnapshot, WatchedWork } from './activity-types.js';
3
+ /**
4
+ * Reading the nearest Activity instance (background-activity SPEC §4.3, §4.4).
5
+ * The provider and scope live in `activity-provider.tsx`.
6
+ */
7
+ export declare const ActivityInstanceContext: import('react').Context<ActivityInstance | null>;
8
+ export declare function useActivityInstance(): ActivityInstance | null;
9
+ /** The nearest Activity: its actions and what it shows. Outside a provider: throws in development, inert in production. */
10
+ export declare function useActivity(): ActivityApi & {
11
+ snapshot: ActivitySnapshot;
12
+ };
13
+ /**
14
+ * Holds the watch while mounted (BA-D10): watched work never notifies. The
15
+ * id shows its browser-only export, or the run it was handed off to.
16
+ * Watchers are keyed by the stable watch id, so a hand-off never moves a count.
17
+ */
18
+ export declare function useWatchActivity(watchId: string | null): WatchedWork | null;
19
+ /** The instance clock in ms, for elapsed times; one 1 s interval while anything subscribes. */
20
+ export declare function useActivityClock(): number;
@@ -1,5 +1,5 @@
1
1
  import { BriefingDeliveryChannel, BriefingRecipient, BriefingRun } from '../../../lib/types/briefing-types.js';
2
- import { isActiveBriefingRunStatus, isTerminalBriefingRunStatus } from '../use-briefing-run-polling.js';
2
+ import { isActiveBriefingRunStatus, isTerminalBriefingRunStatus } from '../use-briefing-run-detail.js';
3
3
  export declare const isTerminalRunStatus: typeof isTerminalBriefingRunStatus;
4
4
  export declare const isActiveRunStatus: typeof isActiveBriefingRunStatus;
5
5
  export declare function deliveryChannels(current: BriefingDeliveryChannel[], channel: BriefingDeliveryChannel, checked: boolean): BriefingDeliveryChannel[];
@@ -7,7 +7,6 @@ export declare function creatorEmailRecipient(currentUser: {
7
7
  email?: string | null;
8
8
  name?: string | null;
9
9
  } | null | undefined): BriefingRecipient | null;
10
- export declare function useElapsedSeconds(startedAt: string | null | undefined): number | null;
11
10
  export declare function formatElapsed(seconds: number): string;
12
11
  export type EmailPreviewRecipient = {
13
12
  label: string;
@@ -2,8 +2,7 @@ import { cancelBriefingPreviewRun, cancelBriefingRun, createBriefing, deleteBrie
2
2
  import { BriefingAttachment, BriefingDetail, BriefingRun, RunBriefingNowResponse } from '../../lib/types/briefing-types.js';
3
3
  import { TDashboard } from '../../lib/types/common-types.js';
4
4
  import { BriefingAuthorIntent, BriefingAuthorSourceContext } from './briefing-author/policy.js';
5
- export { formatElapsed, useElapsedSeconds } from './briefing-author/run-model.js';
6
- export { BackgroundRunPill, RunCompletionBanner } from './briefing-author/run-ui.js';
5
+ export { formatElapsed } from './briefing-author/run-model.js';
7
6
  export type BriefingAuthorClient = {
8
7
  createBriefing: typeof createBriefing;
9
8
  updateBriefing: typeof updateBriefing;
@@ -28,6 +27,8 @@ export type BriefingAuthorProps = {
28
27
  briefing?: BriefingDetail | null;
29
28
  intent?: BriefingAuthorIntent;
30
29
  initialAttachments?: BriefingAttachment[];
30
+ /** Opens the sheet at this saved run (Activity's View), whatever its status; otherwise the latest active run. */
31
+ initialRunId?: string;
31
32
  initialName?: string;
32
33
  initialMessage?: string;
33
34
  initialTimezone?: string;
@@ -47,15 +48,11 @@ export type BriefingAuthorProps = {
47
48
  onRunStarted?: (response: RunBriefingNowResponse) => void;
48
49
  onCancel?: () => void;
49
50
  /**
50
- * Fires when the user clicks "Run in background" on the active-run sticky
51
- * strip. The parent is expected to track the run, render a persistent
52
- * background-run UI (pill + completion banner), and close any modal/sheet
53
- * that hosts the author so the user can navigate freely while the run
54
- * continues server-side.
55
- *
56
- * Only ever called for *saved* runs — preview runs are short-lived
57
- * synthetic things with no notification path, so the sticky bar hides
58
- * the CTA in that case.
51
+ * Fires when the user clicks "Run in background" on the active-run strip:
52
+ * the parent closes the sheet. Activity already follows the run (it was
53
+ * tracked when it started) and shows one notice when it finishes
54
+ * (background-activity BA-D1, BA-D20). Saved runs only: previews never
55
+ * enter Activity.
59
56
  */
60
57
  onMinimizeRun?: (input: {
61
58
  briefing: BriefingDetail;
@@ -69,4 +66,9 @@ export type BriefingAuthorProps = {
69
66
  */
70
67
  onBack?: () => void;
71
68
  };
72
- export declare function BriefingAuthor({ apiServiceUrl, token, briefing, intent, initialAttachments, initialName, initialMessage, initialTimezone, availableDashboards, sourceContext, title, hideHeader, className, client, generateRequestId, onSaved, onDeleted, onRunStarted, onCancel, onBack, onMinimizeRun, }: BriefingAuthorProps): import("react").JSX.Element;
69
+ /**
70
+ * The Briefing sheet inside Activity (background-activity BA-D19): it reuses
71
+ * the host's provider of the same identity, or lists with the token it was
72
+ * given when it stands alone.
73
+ */
74
+ export declare function BriefingAuthor(props: BriefingAuthorProps): import("react").JSX.Element;
@@ -12,6 +12,11 @@ export type DashboardBriefingLauncherProps = {
12
12
  onOpenChange?: (open: boolean) => void;
13
13
  hideTrigger?: boolean;
14
14
  workflowIntent?: BriefingAuthorIntent;
15
+ /** Opens this run's Briefing at the run (Activity's View, in a host without a run page). */
16
+ openRun?: {
17
+ briefingId: string;
18
+ runId: string;
19
+ };
15
20
  client?: Partial<DashboardBriefingLauncherClient>;
16
21
  };
17
22
  export type DashboardBriefingLauncherClient = {
@@ -0,0 +1,34 @@
1
+ import { BriefingPreviewRun, BriefingRun } from '../../lib/types/briefing-types.js';
2
+ /**
3
+ * The Briefing panel reads its own run (background-activity BA-D20, SPEC
4
+ * §4.6): every 2 s while the panel is open and the run is active, whoever
5
+ * started it (a person's Run now, a schedule, a teammate's run). Activity
6
+ * lists the runs a person started for the tray; the two never coordinate.
7
+ * The server expires a stale run when it is read, so a saved run has no
8
+ * client timeout; a preview polls for at most `PREVIEW_RUN_POLL_TIMEOUT_MS`.
9
+ * The sheet that shows a run holds its Activity watch (it outlives this
10
+ * hook's target, which clears when the run is final).
11
+ */
12
+ export declare const BRIEFING_RUN_POLL_INTERVAL_MS = 2000;
13
+ export declare const PREVIEW_RUN_POLL_TIMEOUT_MS: number;
14
+ export type BriefingRunDetailTarget = {
15
+ kind: 'saved';
16
+ briefingId: string;
17
+ runId: string;
18
+ } | {
19
+ kind: 'preview';
20
+ previewRunId: string;
21
+ };
22
+ export type BriefingRunDetailStatus = 'idle' | 'loading' | 'active' | 'final' | 'timed_out' | 'error';
23
+ export declare function isActiveBriefingRunStatus(status: string | undefined): boolean;
24
+ export declare function isTerminalBriefingRunStatus(status: string | undefined): boolean;
25
+ export declare function useBriefingRunDetail<Run extends BriefingRun | BriefingPreviewRun>(input: {
26
+ run: BriefingRunDetailTarget | null;
27
+ /** The sheet's own fetchers (its API client), read on every fetch. */
28
+ fetchSaved: (briefingId: string, runId: string) => Promise<BriefingRun>;
29
+ fetchPreview: (previewRunId: string) => Promise<BriefingPreviewRun>;
30
+ }): {
31
+ run: Run | null;
32
+ status: BriefingRunDetailStatus;
33
+ error: unknown;
34
+ };
@@ -58,10 +58,7 @@ export { useCardSummary } from '../lib/hooks/use-card-summary.js';
58
58
  export type { SummaryResponse } from '../lib/types/summary-types.js';
59
59
  export { useDataColumns, useAddNewFrame } from '../lib/hooks/index.js';
60
60
  export { useExposePrintState, type PrintState, } from '../lib/print-state/use-expose-print-state.js';
61
- export { NotificationBell, ExportNotificationList, ExportNotificationItem, } from './notifications/index.js';
62
- export { useExportStore, useExportActions, useActiveExports, useInProgressExportsCount, type ActiveExport, } from '../lib/stores/export-store.js';
63
- export { useExportPolling } from '../lib/hooks/use-export-polling.js';
64
- export { useExportRecovery } from '../lib/hooks/use-export-recovery.js';
61
+ export { ActivityProvider, ActivityScope, ActivityBell, useActivity, type ActivityApi, type ActivitySnapshot, } from './activity/index.js';
65
62
  export { DashboardControlsSettings } from './surfboard/controls/dashboard-controls-settings.js';
66
63
  export { DocumentControlsSettings } from './document-sheet/document-controls-settings.js';
67
64
  export { DashboardFilterControlsButton } from './surfboard/controls/dashboard-filter-controls-button.js';
@@ -0,0 +1,21 @@
1
+ import { AuthToken } from './types/common-types.js';
2
+ /**
3
+ * Whose Activity history, and the page's user token as a request sends it
4
+ * (background-activity SPEC §4.2, §4.3). History follows the identity, so
5
+ * moving between a dashboard and the Briefings page keeps it. The browser
6
+ * trusts the token: the server decides what each request may do.
7
+ */
8
+ /** The page's user token, as a request sends it (SPEC §4.2). */
9
+ export type UserToken = {
10
+ token: string;
11
+ apiServiceUrl: string;
12
+ };
13
+ /** A decoded token: the typed `TokenProps` claims plus any the issuer adds. */
14
+ type Claims = Record<string, unknown>;
15
+ /** The identity the server lists by. Navigation, token type and presentation do not change it. */
16
+ export declare function activityIdentityKey(token: Claims): string;
17
+ /** The token's claims; empty when there is no token or it cannot be read. */
18
+ export declare function decodeActivityToken(authToken: AuthToken | null | undefined): Claims;
19
+ /** The one way the browser reads the user token for a request: the token and the server it names. */
20
+ export declare function userTokenFrom(authToken: AuthToken | null | undefined): UserToken | null;
21
+ export {};
@@ -10,9 +10,9 @@ export interface CreateExportResponse {
10
10
  totalChunks: number | null;
11
11
  chunkSize: number;
12
12
  estimatedRows: number | null;
13
- wasTruncated?: boolean;
14
- originalRows?: number;
15
- maxRows?: number;
13
+ /** False when the server returned the run an earlier start of this export made (BA-D17). */
14
+ created?: boolean;
15
+ deadlineAt?: string | null;
16
16
  }
17
17
  export type CardExportRequest = CreateExportRequest | MatrixFileExportRequest;
18
18
  /** Export job status response */
@@ -85,7 +85,7 @@ export type MatrixDirectExportResult = {
85
85
  * the response's content type. Errors carry the server's catalog reason in
86
86
  * `details.message` (an Excel limit answers 422 `excel_limit`).
87
87
  */
88
- export declare function createMatrixDirectExport(apiServiceUrl: string, token: string, params: MatrixFileExportRequest): Promise<MatrixDirectExportResult>;
88
+ export declare function createMatrixDirectExport(apiServiceUrl: string, token: string, params: MatrixFileExportRequest, signal?: AbortSignal): Promise<MatrixDirectExportResult>;
89
89
  /**
90
90
  * Get list of user's exports
91
91
  */
@@ -6,8 +6,6 @@ import { useDebounce } from './use-debounce.js';
6
6
  import { useDebouncedEditorValue } from './use-debounced-editor-value.js';
7
7
  import { useClickOutside } from './use-click-outside.js';
8
8
  import { useStableValue, rowsEqual } from './use-stable-value.js';
9
- import { useExportPolling } from './use-export-polling.js';
10
- import { useExportRecovery } from './use-export-recovery.js';
11
9
  import { useCalendarContext, useResolvedDateStyle, useResolvedDateTimeDateStyle, useResolvedDateTimeTimeStyle, useResolvedDefaultCurrency, useResolvedValueFormatLocale, useReportPreferenceSources, useResolvedValueFormatPreferences, useTimezone, useWeekStart } from './use-calendar-context.js';
12
10
  import { useValueFormatPreferences } from './use-value-format-preferences.js';
13
- export { useDashboard, useCard, useDataColumns, useAddNewFrame, useDebounce, useDebouncedEditorValue, useClickOutside, useStableValue, rowsEqual, useExportPolling, useExportRecovery, useCalendarContext, useResolvedDateStyle, useResolvedDateTimeDateStyle, useResolvedDateTimeTimeStyle, useResolvedDefaultCurrency, useResolvedValueFormatLocale, useReportPreferenceSources, useResolvedValueFormatPreferences, useTimezone, useWeekStart, useValueFormatPreferences, };
11
+ export { useDashboard, useCard, useDataColumns, useAddNewFrame, useDebounce, useDebouncedEditorValue, useClickOutside, useStableValue, rowsEqual, useCalendarContext, useResolvedDateStyle, useResolvedDateTimeDateStyle, useResolvedDateTimeTimeStyle, useResolvedDefaultCurrency, useResolvedValueFormatLocale, useReportPreferenceSources, useResolvedValueFormatPreferences, useTimezone, useWeekStart, useValueFormatPreferences, };
@@ -758,4 +758,8 @@ export declare function buildMatrixDeliveryPayload(input: {
758
758
  /** A Matrix data file request (CSV or Excel) for the direct path or a job. */
759
759
  export type MatrixFileExportRequest = ReturnType<typeof buildMatrixDeliveryPayload> & {
760
760
  format: ExportFileFormat;
761
+ /** One logical export (BA-D17): the direct attempt, its fallback and Run in background share it. */
762
+ exportRequestId: string;
763
+ /** 'background' skips the direct attempt (Run in background, BA-D11). */
764
+ delivery?: 'direct' | 'background';
761
765
  };
@@ -0,0 +1,84 @@
1
+ import { ExportFileFormat } from '../format-utils/exporters/export-file-format.js';
2
+ /**
3
+ * The Activity contract (background-activity SPEC §2.2): what
4
+ * `GET /api/v1/activity` answers about a person's exports and Briefing runs.
5
+ * React-free; the app builds it and the client reads it with
6
+ * `parseActivityListResponse`. It never carries a token, lease, file key,
7
+ * signed URL, config, filter, SQL or free-text error.
8
+ */
9
+ export declare const ACTIVITY_STATUSES: readonly ["running", "ready", "failed", "cancelled"];
10
+ export type ActivityStatus = (typeof ACTIVITY_STATUSES)[number];
11
+ /** Where a running export is, from signals the server already has (MX-D17). */
12
+ export type ExportActivityStage = {
13
+ kind: 'queued';
14
+ } | {
15
+ kind: 'preparing';
16
+ } | {
17
+ kind: 'fetching';
18
+ rowsProcessed: number;
19
+ } | {
20
+ kind: 'processing';
21
+ percent: number | null;
22
+ } | {
23
+ kind: 'finalizing';
24
+ };
25
+ /** `message` is catalog text; no free-text server error crosses this contract. */
26
+ export type ActivityFailure = {
27
+ kind: 'export';
28
+ reason: string;
29
+ message: string;
30
+ } | {
31
+ kind: 'briefing';
32
+ };
33
+ type ActivityItemBase = {
34
+ /** The AutomationRun id. */
35
+ id: string;
36
+ title: string;
37
+ status: ActivityStatus;
38
+ /** ISO timestamps. */
39
+ startedAt: string;
40
+ finishedAt: string | null;
41
+ failure: ActivityFailure | null;
42
+ };
43
+ export type ExportActivityItem = ActivityItemBase & {
44
+ kind: 'export';
45
+ /** The run's requestId: the client's id of the logical export (BA-D17). */
46
+ exportRequestId: string;
47
+ format: ExportFileFormat;
48
+ stage: ExportActivityStage | null;
49
+ totalRows: number | null;
50
+ fileSize: number | null;
51
+ /** When the server stops the export; the client gives up a grace period later (MX-D9). */
52
+ deadlineAt: string | null;
53
+ };
54
+ export type BriefingActivityItem = ActivityItemBase & {
55
+ kind: 'briefing';
56
+ briefingId: string;
57
+ /** The run's progress label while running, as the sheet shows it. */
58
+ stageLabel: string | null;
59
+ omittedAttachmentCount: number;
60
+ };
61
+ export type ActivityItem = ExportActivityItem | BriefingActivityItem;
62
+ export type ActivityListRequest = {
63
+ /** Known runs the previous responses omitted; answered explicitly (BA-D15). */
64
+ resolve: readonly string[];
65
+ };
66
+ export type ActivityListResponse = {
67
+ /** Every running item the person started, newest first, up to ACTIVITY_ACTIVE_LIMIT. */
68
+ active: ActivityItem[];
69
+ activeTruncated: boolean;
70
+ /** Finished items from the last ACTIVITY_RECENT_WINDOW_MS, newest finishedAt first. */
71
+ recent: ActivityItem[];
72
+ /** Each `resolve` id the person owns that is in neither list, whatever its age or status. */
73
+ resolved: ActivityItem[];
74
+ /** Each `resolve` id that does not exist or is not the person's: the only proof of "missing". */
75
+ missing: string[];
76
+ };
77
+ export declare const ACTIVITY_ACTIVE_LIMIT = 100;
78
+ export declare const ACTIVITY_RECENT_LIMIT = 50;
79
+ export declare const ACTIVITY_RECENT_WINDOW_MS: number;
80
+ /** The most `resolve` ids one request names. */
81
+ export declare const ACTIVITY_RESOLVE_LIMIT = 20;
82
+ /** Parses a response; throws on a shape it does not recognize (the client never guesses). */
83
+ export declare function parseActivityListResponse(value: unknown): ActivityListResponse;
84
+ export {};
@@ -0,0 +1,5 @@
1
+ /**
2
+ * `react-semaphor/activity`: the Activity contract (background-activity SPEC
3
+ * §2.2). Server-safe: no React, store or component module.
4
+ */
5
+ export * from './activity-contract.js';
@@ -56,6 +56,12 @@ export interface CreateExportRequest {
56
56
  /** The file the job writes: CSV, or Excel for Table and Detail Table. */
57
57
  format: ExportFileFormat;
58
58
  formatOptions: AuthoritativeExportFormattingConfig;
59
+ /**
60
+ * One logical export (background-activity BA-D17): every start of the same
61
+ * export sends the same id, so the server returns one run. Required by
62
+ * POST /api/v1/exports; a server-started attachment has none.
63
+ */
64
+ exportRequestId?: string;
59
65
  }
60
66
  /** The facts a result gives an export: a viewer's loaded result, or the server's sizing query. */
61
67
  export type CardResultFacts = {
@@ -17,3 +17,15 @@ export declare const MATRIX_EXPORT_MAX_ENCODED_BYTES: number;
17
17
  export declare const MATRIX_EXPORT_MAX_ARTIFACT_BYTES: number;
18
18
  /** Return true when a complete CSV must use the asynchronous chunked path. */
19
19
  export declare function requiresChunkedCsvExport(totalRows: number): boolean;
20
+ /** Where a data export (CSV or Excel) runs (background-activity BA-D2, SPEC §4.1). */
21
+ export type DataExportRoute = 'direct' | 'background' | 'try-direct' | 'blocked';
22
+ /**
23
+ * The one route rule for data exports in CSV and Excel (they share every
24
+ * limit): a Matrix tries the direct path first; a table routes on its loaded
25
+ * row count. The loaded count only routes; the server sizes the job (BA-D3).
26
+ */
27
+ export declare function dataExportRoute(input: {
28
+ cardType: 'table' | 'detailTable' | 'matrixTable';
29
+ /** The loaded row count of a server-paged table, else null. */
30
+ loadedRowCount: number | null;
31
+ }): DataExportRoute;
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "email": "support@semaphor.cloud"
6
6
  },
7
7
  "license": "MIT",
8
- "version": "0.1.542",
8
+ "version": "0.1.544",
9
9
  "description": "Fully interactive and customizable dashboards for your apps.",
10
10
  "keywords": [
11
11
  "react",
@@ -88,6 +88,10 @@
88
88
  "types": "./dist/types/brand-studio.d.ts",
89
89
  "import": "./dist/brand-studio/index.js"
90
90
  },
91
+ "./activity": {
92
+ "types": "./dist/types/activity.d.ts",
93
+ "import": "./dist/activity/index.js"
94
+ },
91
95
  "./briefings": {
92
96
  "types": "./dist/types/briefings.d.ts",
93
97
  "import": "./dist/briefings/index.js"