@bloodgpt/widgets 0.1.0-alpha.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.
@@ -0,0 +1,242 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+ import * as _tanstack_react_query from '@tanstack/react-query';
4
+ import { QueryClient, UseQueryOptions } from '@tanstack/react-query';
5
+ import { FollowUpSchedule, UrgentTest, OverviewData, BloodGPTParameter, ParameterTrendData } from '@repo/analysis-ui';
6
+ export { BloodGPTParameter, FollowUpSchedule, OverviewData, ParameterTrendData, UrgentTest } from '@repo/analysis-ui';
7
+
8
+ interface BloodGPTProviderProps {
9
+ /**
10
+ * Short-lived session token minted by your backend via
11
+ * `POST /api/v1/widget-sessions`. The token is bound to a specific
12
+ * external patient ID and is read-only.
13
+ */
14
+ sessionToken: string;
15
+ /**
16
+ * Base URL of the BloodGPT API. Defaults to the production endpoint.
17
+ * Override for staging or self-hosted deployments.
18
+ */
19
+ apiUrl?: string;
20
+ /**
21
+ * BCP-47 locale code. Defaults to "en". The widgets ship with English
22
+ * strings only — pass `messages` to provide additional locales.
23
+ */
24
+ locale?: string;
25
+ /**
26
+ * Override or extend the bundled messages. Shape mirrors the keys under
27
+ * the `analysis` namespace in apps/patient-portal/messages/<locale>.json.
28
+ * Customer-provided entries are deep-merged over the defaults, so a
29
+ * partial override (e.g. `{ analysis: { abnormal: "…" } }`) replaces only
30
+ * that key and keeps every other bundled string intact.
31
+ */
32
+ messages?: Record<string, unknown>;
33
+ /**
34
+ * Bring your own QueryClient (e.g. to share cache with the host app).
35
+ * If omitted, the provider creates an isolated one.
36
+ */
37
+ queryClient?: QueryClient;
38
+ /**
39
+ * Custom fetch implementation — useful for SSR with auth cookies or for
40
+ * test mocking. Defaults to `globalThis.fetch`.
41
+ */
42
+ fetch?: typeof globalThis.fetch;
43
+ children: ReactNode;
44
+ }
45
+ declare function BloodGPTProvider({ sessionToken, apiUrl, locale, messages, queryClient, fetch, children, }: BloodGPTProviderProps): react_jsx_runtime.JSX.Element;
46
+
47
+ /**
48
+ * API response DTOs for the widgets endpoints.
49
+ *
50
+ * These mirror the shapes the b2b-api returns at:
51
+ * GET /api/v1/widgets/patients/by-external/:externalId/tests
52
+ * GET /api/v1/widgets/tests/:testId/overview
53
+ * GET /api/v1/widgets/tests/:testId/parameters
54
+ * GET /api/v1/widgets/tests/:testId/follow-ups
55
+ * GET /api/v1/widgets/tests/:testId/trends?parameter=
56
+ *
57
+ * When the SDK publish pipeline grows an orval step we should switch to the
58
+ * generated types. Hand-maintained here for v0.1 — the public widget
59
+ * components only depend on these DTOs so the swap is contract-only.
60
+ */
61
+
62
+ interface ReportListItem {
63
+ test_id: string;
64
+ test_date: string | null;
65
+ created_at: string;
66
+ status: "processing" | "completed" | "failed";
67
+ total_count: number;
68
+ normal_count: number;
69
+ abnormal_count: number;
70
+ critical_count: number;
71
+ headline_summary?: string | null;
72
+ }
73
+ interface ReportsListResponse {
74
+ request_id: string;
75
+ patient: {
76
+ external_patient_id: string;
77
+ name?: string | null;
78
+ };
79
+ reports: ReportListItem[];
80
+ }
81
+ interface TestOverviewResponse {
82
+ request_id: string;
83
+ test_id: string;
84
+ test_date: string | null;
85
+ patient: {
86
+ name?: string | null;
87
+ birth_date?: string | null;
88
+ gender?: string | null;
89
+ weight?: number | null;
90
+ height?: number | null;
91
+ } | null;
92
+ metrics: {
93
+ total: number;
94
+ normal: number;
95
+ abnormal: number;
96
+ critical: number;
97
+ };
98
+ overview: OverviewData | null;
99
+ }
100
+ interface TestParametersResponse {
101
+ request_id: string;
102
+ test_id: string;
103
+ panels: Array<{
104
+ panel_name: string;
105
+ overview?: string | null;
106
+ parameters: BloodGPTParameter[];
107
+ /** Map of parameter_name → trend data for sparkline / trends chart. */
108
+ trend_data?: Record<string, ParameterTrendData>;
109
+ }>;
110
+ }
111
+ interface TestFollowUpsResponse {
112
+ request_id: string;
113
+ test_id: string;
114
+ schedule: FollowUpSchedule | null;
115
+ urgent_tests: UrgentTest[];
116
+ }
117
+ interface TestTrendsResponse {
118
+ request_id: string;
119
+ test_id: string;
120
+ /** The parameter the series was requested for (echoes the query param). */
121
+ parameter: string;
122
+ /**
123
+ * Value-over-time for `parameter` across the patient's whole history, or
124
+ * `null` if that parameter has never been measured. The `trend` map is
125
+ * keyed by ISO date → numeric value (qualitative points are `null`).
126
+ */
127
+ trend: ParameterTrendData | null;
128
+ }
129
+
130
+ interface ReportsListProps {
131
+ externalPatientId: string;
132
+ /** Called when a row is clicked. Receives the test id. */
133
+ onSelectReport?: (testId: string) => void;
134
+ /** Override the link target — useful for next/link integration. */
135
+ renderRow?: (item: ReportListItem) => React.ReactNode;
136
+ className?: string;
137
+ loadingFallback?: React.ReactNode;
138
+ errorFallback?: (error: Error) => React.ReactNode;
139
+ emptyFallback?: React.ReactNode;
140
+ }
141
+ declare function ReportsList({ externalPatientId, onSelectReport, renderRow, className, loadingFallback, errorFallback, emptyFallback, }: ReportsListProps): react_jsx_runtime.JSX.Element;
142
+
143
+ interface TestFollowUpsProps {
144
+ testId: string;
145
+ compact?: boolean;
146
+ className?: string;
147
+ loadingFallback?: React.ReactNode;
148
+ errorFallback?: (error: Error) => React.ReactNode;
149
+ }
150
+ declare function TestFollowUps({ testId, compact, className, loadingFallback, errorFallback, }: TestFollowUpsProps): react_jsx_runtime.JSX.Element | null;
151
+
152
+ interface TestOverviewProps {
153
+ /** BloodGPT internal test id (from a ReportsList row or your own records). */
154
+ testId: string;
155
+ /**
156
+ * Hide the patient demographics block. Defaults to false. Set to true
157
+ * when you embed the widget in a context that already shows patient info
158
+ * (e.g. a chart on a patient detail page) or for share links where PII
159
+ * has been stripped on the server.
160
+ */
161
+ hidePatientInfo?: boolean;
162
+ /**
163
+ * Optional className for the outer wrapper — lets you compose the widget
164
+ * inside your own layout without an extra wrapper div.
165
+ */
166
+ className?: string;
167
+ /** Slot rendered when the request is loading. Defaults to a simple placeholder. */
168
+ loadingFallback?: React.ReactNode;
169
+ /** Slot rendered on error. Receives the error message. */
170
+ errorFallback?: (error: Error) => React.ReactNode;
171
+ }
172
+ declare function TestOverview({ testId, hidePatientInfo, className, loadingFallback, errorFallback, }: TestOverviewProps): react_jsx_runtime.JSX.Element | null;
173
+
174
+ interface TestParametersProps {
175
+ testId: string;
176
+ variant?: "default" | "dashboard" | "report";
177
+ className?: string;
178
+ loadingFallback?: React.ReactNode;
179
+ errorFallback?: (error: Error) => React.ReactNode;
180
+ onParameterClick?: (parameterName: string) => void;
181
+ }
182
+ declare function TestParameters({ testId, variant, className, loadingFallback, errorFallback, onParameterClick, }: TestParametersProps): react_jsx_runtime.JSX.Element | null;
183
+
184
+ interface TestReportProps {
185
+ testId: string;
186
+ hidePatientInfo?: boolean;
187
+ className?: string;
188
+ sections?: {
189
+ overview?: boolean;
190
+ parameters?: boolean;
191
+ followUps?: boolean;
192
+ };
193
+ }
194
+ /**
195
+ * Composite widget — renders Overview + Parameters + FollowUps stacked.
196
+ * For most embedding use cases this is the only widget customers need.
197
+ */
198
+ declare function TestReport({ testId, hidePatientInfo, className, sections, }: TestReportProps): react_jsx_runtime.JSX.Element;
199
+
200
+ declare function useReports(externalPatientId: string | null | undefined, options?: Omit<UseQueryOptions<ReportsListResponse, Error>, "queryKey" | "queryFn">): _tanstack_react_query.UseQueryResult<ReportsListResponse, Error>;
201
+
202
+ declare function useTestFollowUps(testId: string | null | undefined, options?: Omit<UseQueryOptions<TestFollowUpsResponse, Error>, "queryKey" | "queryFn">): _tanstack_react_query.UseQueryResult<TestFollowUpsResponse, Error>;
203
+
204
+ declare function useTestOverview(testId: string | null | undefined, options?: Omit<UseQueryOptions<TestOverviewResponse, Error>, "queryKey" | "queryFn">): _tanstack_react_query.UseQueryResult<TestOverviewResponse, Error>;
205
+
206
+ declare function useTestParameters(testId: string | null | undefined, options?: Omit<UseQueryOptions<TestParametersResponse, Error>, "queryKey" | "queryFn">): _tanstack_react_query.UseQueryResult<TestParametersResponse, Error>;
207
+
208
+ /**
209
+ * Fetch the value-over-time series for a single parameter across the bound
210
+ * patient's history. Pair with `@repo/analysis-ui`'s `TrendsChart` (or your
211
+ * own chart) to render it — the widget package deliberately doesn't ship a
212
+ * standalone chart widget so `chart.js` stays out of the main bundle.
213
+ */
214
+ declare function useTestTrends(testId: string | null | undefined, parameter: string | null | undefined, options?: Omit<UseQueryOptions<TestTrendsResponse, Error>, "queryKey" | "queryFn">): _tanstack_react_query.UseQueryResult<TestTrendsResponse, Error>;
215
+
216
+ interface HttpClientOptions {
217
+ apiUrl: string;
218
+ sessionToken: string;
219
+ fetch?: typeof globalThis.fetch;
220
+ }
221
+ declare class BloodGPTApiError extends Error {
222
+ readonly status: number;
223
+ readonly code?: string;
224
+ readonly requestId?: string;
225
+ constructor(opts: {
226
+ status: number;
227
+ message: string;
228
+ code?: string;
229
+ requestId?: string;
230
+ });
231
+ }
232
+ declare class HttpClient {
233
+ private readonly apiUrl;
234
+ private readonly sessionToken;
235
+ private readonly fetchImpl;
236
+ constructor(opts: HttpClientOptions);
237
+ get<T>(path: string, signal?: AbortSignal): Promise<T>;
238
+ }
239
+
240
+ declare function useBloodGPTClient(): HttpClient;
241
+
242
+ export { BloodGPTApiError, BloodGPTProvider, type BloodGPTProviderProps, HttpClient, type ReportListItem, ReportsList, type ReportsListProps, type ReportsListResponse, TestFollowUps, type TestFollowUpsProps, type TestFollowUpsResponse, TestOverview, type TestOverviewProps, type TestOverviewResponse, TestParameters, type TestParametersProps, type TestParametersResponse, TestReport, type TestReportProps, type TestTrendsResponse, useBloodGPTClient, useReports, useTestFollowUps, useTestOverview, useTestParameters, useTestTrends };
@@ -0,0 +1,242 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+ import * as _tanstack_react_query from '@tanstack/react-query';
4
+ import { QueryClient, UseQueryOptions } from '@tanstack/react-query';
5
+ import { FollowUpSchedule, UrgentTest, OverviewData, BloodGPTParameter, ParameterTrendData } from '@repo/analysis-ui';
6
+ export { BloodGPTParameter, FollowUpSchedule, OverviewData, ParameterTrendData, UrgentTest } from '@repo/analysis-ui';
7
+
8
+ interface BloodGPTProviderProps {
9
+ /**
10
+ * Short-lived session token minted by your backend via
11
+ * `POST /api/v1/widget-sessions`. The token is bound to a specific
12
+ * external patient ID and is read-only.
13
+ */
14
+ sessionToken: string;
15
+ /**
16
+ * Base URL of the BloodGPT API. Defaults to the production endpoint.
17
+ * Override for staging or self-hosted deployments.
18
+ */
19
+ apiUrl?: string;
20
+ /**
21
+ * BCP-47 locale code. Defaults to "en". The widgets ship with English
22
+ * strings only — pass `messages` to provide additional locales.
23
+ */
24
+ locale?: string;
25
+ /**
26
+ * Override or extend the bundled messages. Shape mirrors the keys under
27
+ * the `analysis` namespace in apps/patient-portal/messages/<locale>.json.
28
+ * Customer-provided entries are deep-merged over the defaults, so a
29
+ * partial override (e.g. `{ analysis: { abnormal: "…" } }`) replaces only
30
+ * that key and keeps every other bundled string intact.
31
+ */
32
+ messages?: Record<string, unknown>;
33
+ /**
34
+ * Bring your own QueryClient (e.g. to share cache with the host app).
35
+ * If omitted, the provider creates an isolated one.
36
+ */
37
+ queryClient?: QueryClient;
38
+ /**
39
+ * Custom fetch implementation — useful for SSR with auth cookies or for
40
+ * test mocking. Defaults to `globalThis.fetch`.
41
+ */
42
+ fetch?: typeof globalThis.fetch;
43
+ children: ReactNode;
44
+ }
45
+ declare function BloodGPTProvider({ sessionToken, apiUrl, locale, messages, queryClient, fetch, children, }: BloodGPTProviderProps): react_jsx_runtime.JSX.Element;
46
+
47
+ /**
48
+ * API response DTOs for the widgets endpoints.
49
+ *
50
+ * These mirror the shapes the b2b-api returns at:
51
+ * GET /api/v1/widgets/patients/by-external/:externalId/tests
52
+ * GET /api/v1/widgets/tests/:testId/overview
53
+ * GET /api/v1/widgets/tests/:testId/parameters
54
+ * GET /api/v1/widgets/tests/:testId/follow-ups
55
+ * GET /api/v1/widgets/tests/:testId/trends?parameter=
56
+ *
57
+ * When the SDK publish pipeline grows an orval step we should switch to the
58
+ * generated types. Hand-maintained here for v0.1 — the public widget
59
+ * components only depend on these DTOs so the swap is contract-only.
60
+ */
61
+
62
+ interface ReportListItem {
63
+ test_id: string;
64
+ test_date: string | null;
65
+ created_at: string;
66
+ status: "processing" | "completed" | "failed";
67
+ total_count: number;
68
+ normal_count: number;
69
+ abnormal_count: number;
70
+ critical_count: number;
71
+ headline_summary?: string | null;
72
+ }
73
+ interface ReportsListResponse {
74
+ request_id: string;
75
+ patient: {
76
+ external_patient_id: string;
77
+ name?: string | null;
78
+ };
79
+ reports: ReportListItem[];
80
+ }
81
+ interface TestOverviewResponse {
82
+ request_id: string;
83
+ test_id: string;
84
+ test_date: string | null;
85
+ patient: {
86
+ name?: string | null;
87
+ birth_date?: string | null;
88
+ gender?: string | null;
89
+ weight?: number | null;
90
+ height?: number | null;
91
+ } | null;
92
+ metrics: {
93
+ total: number;
94
+ normal: number;
95
+ abnormal: number;
96
+ critical: number;
97
+ };
98
+ overview: OverviewData | null;
99
+ }
100
+ interface TestParametersResponse {
101
+ request_id: string;
102
+ test_id: string;
103
+ panels: Array<{
104
+ panel_name: string;
105
+ overview?: string | null;
106
+ parameters: BloodGPTParameter[];
107
+ /** Map of parameter_name → trend data for sparkline / trends chart. */
108
+ trend_data?: Record<string, ParameterTrendData>;
109
+ }>;
110
+ }
111
+ interface TestFollowUpsResponse {
112
+ request_id: string;
113
+ test_id: string;
114
+ schedule: FollowUpSchedule | null;
115
+ urgent_tests: UrgentTest[];
116
+ }
117
+ interface TestTrendsResponse {
118
+ request_id: string;
119
+ test_id: string;
120
+ /** The parameter the series was requested for (echoes the query param). */
121
+ parameter: string;
122
+ /**
123
+ * Value-over-time for `parameter` across the patient's whole history, or
124
+ * `null` if that parameter has never been measured. The `trend` map is
125
+ * keyed by ISO date → numeric value (qualitative points are `null`).
126
+ */
127
+ trend: ParameterTrendData | null;
128
+ }
129
+
130
+ interface ReportsListProps {
131
+ externalPatientId: string;
132
+ /** Called when a row is clicked. Receives the test id. */
133
+ onSelectReport?: (testId: string) => void;
134
+ /** Override the link target — useful for next/link integration. */
135
+ renderRow?: (item: ReportListItem) => React.ReactNode;
136
+ className?: string;
137
+ loadingFallback?: React.ReactNode;
138
+ errorFallback?: (error: Error) => React.ReactNode;
139
+ emptyFallback?: React.ReactNode;
140
+ }
141
+ declare function ReportsList({ externalPatientId, onSelectReport, renderRow, className, loadingFallback, errorFallback, emptyFallback, }: ReportsListProps): react_jsx_runtime.JSX.Element;
142
+
143
+ interface TestFollowUpsProps {
144
+ testId: string;
145
+ compact?: boolean;
146
+ className?: string;
147
+ loadingFallback?: React.ReactNode;
148
+ errorFallback?: (error: Error) => React.ReactNode;
149
+ }
150
+ declare function TestFollowUps({ testId, compact, className, loadingFallback, errorFallback, }: TestFollowUpsProps): react_jsx_runtime.JSX.Element | null;
151
+
152
+ interface TestOverviewProps {
153
+ /** BloodGPT internal test id (from a ReportsList row or your own records). */
154
+ testId: string;
155
+ /**
156
+ * Hide the patient demographics block. Defaults to false. Set to true
157
+ * when you embed the widget in a context that already shows patient info
158
+ * (e.g. a chart on a patient detail page) or for share links where PII
159
+ * has been stripped on the server.
160
+ */
161
+ hidePatientInfo?: boolean;
162
+ /**
163
+ * Optional className for the outer wrapper — lets you compose the widget
164
+ * inside your own layout without an extra wrapper div.
165
+ */
166
+ className?: string;
167
+ /** Slot rendered when the request is loading. Defaults to a simple placeholder. */
168
+ loadingFallback?: React.ReactNode;
169
+ /** Slot rendered on error. Receives the error message. */
170
+ errorFallback?: (error: Error) => React.ReactNode;
171
+ }
172
+ declare function TestOverview({ testId, hidePatientInfo, className, loadingFallback, errorFallback, }: TestOverviewProps): react_jsx_runtime.JSX.Element | null;
173
+
174
+ interface TestParametersProps {
175
+ testId: string;
176
+ variant?: "default" | "dashboard" | "report";
177
+ className?: string;
178
+ loadingFallback?: React.ReactNode;
179
+ errorFallback?: (error: Error) => React.ReactNode;
180
+ onParameterClick?: (parameterName: string) => void;
181
+ }
182
+ declare function TestParameters({ testId, variant, className, loadingFallback, errorFallback, onParameterClick, }: TestParametersProps): react_jsx_runtime.JSX.Element | null;
183
+
184
+ interface TestReportProps {
185
+ testId: string;
186
+ hidePatientInfo?: boolean;
187
+ className?: string;
188
+ sections?: {
189
+ overview?: boolean;
190
+ parameters?: boolean;
191
+ followUps?: boolean;
192
+ };
193
+ }
194
+ /**
195
+ * Composite widget — renders Overview + Parameters + FollowUps stacked.
196
+ * For most embedding use cases this is the only widget customers need.
197
+ */
198
+ declare function TestReport({ testId, hidePatientInfo, className, sections, }: TestReportProps): react_jsx_runtime.JSX.Element;
199
+
200
+ declare function useReports(externalPatientId: string | null | undefined, options?: Omit<UseQueryOptions<ReportsListResponse, Error>, "queryKey" | "queryFn">): _tanstack_react_query.UseQueryResult<ReportsListResponse, Error>;
201
+
202
+ declare function useTestFollowUps(testId: string | null | undefined, options?: Omit<UseQueryOptions<TestFollowUpsResponse, Error>, "queryKey" | "queryFn">): _tanstack_react_query.UseQueryResult<TestFollowUpsResponse, Error>;
203
+
204
+ declare function useTestOverview(testId: string | null | undefined, options?: Omit<UseQueryOptions<TestOverviewResponse, Error>, "queryKey" | "queryFn">): _tanstack_react_query.UseQueryResult<TestOverviewResponse, Error>;
205
+
206
+ declare function useTestParameters(testId: string | null | undefined, options?: Omit<UseQueryOptions<TestParametersResponse, Error>, "queryKey" | "queryFn">): _tanstack_react_query.UseQueryResult<TestParametersResponse, Error>;
207
+
208
+ /**
209
+ * Fetch the value-over-time series for a single parameter across the bound
210
+ * patient's history. Pair with `@repo/analysis-ui`'s `TrendsChart` (or your
211
+ * own chart) to render it — the widget package deliberately doesn't ship a
212
+ * standalone chart widget so `chart.js` stays out of the main bundle.
213
+ */
214
+ declare function useTestTrends(testId: string | null | undefined, parameter: string | null | undefined, options?: Omit<UseQueryOptions<TestTrendsResponse, Error>, "queryKey" | "queryFn">): _tanstack_react_query.UseQueryResult<TestTrendsResponse, Error>;
215
+
216
+ interface HttpClientOptions {
217
+ apiUrl: string;
218
+ sessionToken: string;
219
+ fetch?: typeof globalThis.fetch;
220
+ }
221
+ declare class BloodGPTApiError extends Error {
222
+ readonly status: number;
223
+ readonly code?: string;
224
+ readonly requestId?: string;
225
+ constructor(opts: {
226
+ status: number;
227
+ message: string;
228
+ code?: string;
229
+ requestId?: string;
230
+ });
231
+ }
232
+ declare class HttpClient {
233
+ private readonly apiUrl;
234
+ private readonly sessionToken;
235
+ private readonly fetchImpl;
236
+ constructor(opts: HttpClientOptions);
237
+ get<T>(path: string, signal?: AbortSignal): Promise<T>;
238
+ }
239
+
240
+ declare function useBloodGPTClient(): HttpClient;
241
+
242
+ export { BloodGPTApiError, BloodGPTProvider, type BloodGPTProviderProps, HttpClient, type ReportListItem, ReportsList, type ReportsListProps, type ReportsListResponse, TestFollowUps, type TestFollowUpsProps, type TestFollowUpsResponse, TestOverview, type TestOverviewProps, type TestOverviewResponse, TestParameters, type TestParametersProps, type TestParametersResponse, TestReport, type TestReportProps, type TestTrendsResponse, useBloodGPTClient, useReports, useTestFollowUps, useTestOverview, useTestParameters, useTestTrends };