@uplifted/react 0.22.6

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 (221) hide show
  1. package/dist/AddClientSheet.d.ts +39 -0
  2. package/dist/AddClientSheet.d.ts.map +1 -0
  3. package/dist/AddClientSheet.js +108 -0
  4. package/dist/AddClientSheet.js.map +1 -0
  5. package/dist/AiSettingsSheet.d.ts +20 -0
  6. package/dist/AiSettingsSheet.d.ts.map +1 -0
  7. package/dist/AiSettingsSheet.js +274 -0
  8. package/dist/AiSettingsSheet.js.map +1 -0
  9. package/dist/AssistantGrid.d.ts +30 -0
  10. package/dist/AssistantGrid.d.ts.map +1 -0
  11. package/dist/AssistantGrid.js +68 -0
  12. package/dist/AssistantGrid.js.map +1 -0
  13. package/dist/AttachmentPicker.d.ts +38 -0
  14. package/dist/AttachmentPicker.d.ts.map +1 -0
  15. package/dist/AttachmentPicker.js +173 -0
  16. package/dist/AttachmentPicker.js.map +1 -0
  17. package/dist/BulkGenerateSheet.d.ts +25 -0
  18. package/dist/BulkGenerateSheet.d.ts.map +1 -0
  19. package/dist/BulkGenerateSheet.js +65 -0
  20. package/dist/BulkGenerateSheet.js.map +1 -0
  21. package/dist/ChannelBadge.d.ts +16 -0
  22. package/dist/ChannelBadge.d.ts.map +1 -0
  23. package/dist/ChannelBadge.js +19 -0
  24. package/dist/ChannelBadge.js.map +1 -0
  25. package/dist/ChannelExplainer.d.ts +17 -0
  26. package/dist/ChannelExplainer.d.ts.map +1 -0
  27. package/dist/ChannelExplainer.js +25 -0
  28. package/dist/ChannelExplainer.js.map +1 -0
  29. package/dist/ClientList.d.ts +43 -0
  30. package/dist/ClientList.d.ts.map +1 -0
  31. package/dist/ClientList.js +76 -0
  32. package/dist/ClientList.js.map +1 -0
  33. package/dist/ClosedWindowBanner.d.ts +12 -0
  34. package/dist/ClosedWindowBanner.d.ts.map +1 -0
  35. package/dist/ClosedWindowBanner.js +15 -0
  36. package/dist/ClosedWindowBanner.js.map +1 -0
  37. package/dist/Composer.d.ts +49 -0
  38. package/dist/Composer.d.ts.map +1 -0
  39. package/dist/Composer.js +99 -0
  40. package/dist/Composer.js.map +1 -0
  41. package/dist/ComposerExtras.d.ts +15 -0
  42. package/dist/ComposerExtras.d.ts.map +1 -0
  43. package/dist/ComposerExtras.js +14 -0
  44. package/dist/ComposerExtras.js.map +1 -0
  45. package/dist/ConversationPane.d.ts +33 -0
  46. package/dist/ConversationPane.d.ts.map +1 -0
  47. package/dist/ConversationPane.js +126 -0
  48. package/dist/ConversationPane.js.map +1 -0
  49. package/dist/DeliveryReceipt.d.ts +7 -0
  50. package/dist/DeliveryReceipt.d.ts.map +1 -0
  51. package/dist/DeliveryReceipt.js +13 -0
  52. package/dist/DeliveryReceipt.js.map +1 -0
  53. package/dist/DraftGrid.d.ts +17 -0
  54. package/dist/DraftGrid.d.ts.map +1 -0
  55. package/dist/DraftGrid.js +43 -0
  56. package/dist/DraftGrid.js.map +1 -0
  57. package/dist/HostPreviewPane.d.ts +37 -0
  58. package/dist/HostPreviewPane.d.ts.map +1 -0
  59. package/dist/HostPreviewPane.js +106 -0
  60. package/dist/HostPreviewPane.js.map +1 -0
  61. package/dist/InlineDrafts.d.ts +14 -0
  62. package/dist/InlineDrafts.d.ts.map +1 -0
  63. package/dist/InlineDrafts.js +19 -0
  64. package/dist/InlineDrafts.js.map +1 -0
  65. package/dist/ItemActions.d.ts +23 -0
  66. package/dist/ItemActions.d.ts.map +1 -0
  67. package/dist/ItemActions.js +83 -0
  68. package/dist/ItemActions.js.map +1 -0
  69. package/dist/MediaAttachment.d.ts +7 -0
  70. package/dist/MediaAttachment.d.ts.map +1 -0
  71. package/dist/MediaAttachment.js +37 -0
  72. package/dist/MediaAttachment.js.map +1 -0
  73. package/dist/OfferSheet.d.ts +32 -0
  74. package/dist/OfferSheet.d.ts.map +1 -0
  75. package/dist/OfferSheet.js +84 -0
  76. package/dist/OfferSheet.js.map +1 -0
  77. package/dist/ProactiveOptionsSheet.d.ts +14 -0
  78. package/dist/ProactiveOptionsSheet.d.ts.map +1 -0
  79. package/dist/ProactiveOptionsSheet.js +58 -0
  80. package/dist/ProactiveOptionsSheet.js.map +1 -0
  81. package/dist/QuickSend.d.ts +15 -0
  82. package/dist/QuickSend.d.ts.map +1 -0
  83. package/dist/QuickSend.js +90 -0
  84. package/dist/QuickSend.js.map +1 -0
  85. package/dist/SegmentEditor.d.ts +25 -0
  86. package/dist/SegmentEditor.d.ts.map +1 -0
  87. package/dist/SegmentEditor.js +95 -0
  88. package/dist/SegmentEditor.js.map +1 -0
  89. package/dist/Sheet.d.ts +13 -0
  90. package/dist/Sheet.d.ts.map +1 -0
  91. package/dist/Sheet.js +64 -0
  92. package/dist/Sheet.js.map +1 -0
  93. package/dist/ThreadFeed.d.ts +27 -0
  94. package/dist/ThreadFeed.d.ts.map +1 -0
  95. package/dist/ThreadFeed.js +42 -0
  96. package/dist/ThreadFeed.js.map +1 -0
  97. package/dist/UpliftPanel.d.ts +40 -0
  98. package/dist/UpliftPanel.d.ts.map +1 -0
  99. package/dist/UpliftPanel.js +219 -0
  100. package/dist/UpliftPanel.js.map +1 -0
  101. package/dist/UpliftProvider.d.ts +15 -0
  102. package/dist/UpliftProvider.d.ts.map +1 -0
  103. package/dist/UpliftProvider.js +19 -0
  104. package/dist/UpliftProvider.js.map +1 -0
  105. package/dist/WaitingTemplateGhost.d.ts +12 -0
  106. package/dist/WaitingTemplateGhost.d.ts.map +1 -0
  107. package/dist/WaitingTemplateGhost.js +16 -0
  108. package/dist/WaitingTemplateGhost.js.map +1 -0
  109. package/dist/channels.d.ts +22 -0
  110. package/dist/channels.d.ts.map +1 -0
  111. package/dist/channels.js +31 -0
  112. package/dist/channels.js.map +1 -0
  113. package/dist/errors.d.ts +6 -0
  114. package/dist/errors.d.ts.map +1 -0
  115. package/dist/errors.js +20 -0
  116. package/dist/errors.js.map +1 -0
  117. package/dist/host.d.ts +45 -0
  118. package/dist/host.d.ts.map +1 -0
  119. package/dist/host.js +35 -0
  120. package/dist/host.js.map +1 -0
  121. package/dist/icons.d.ts +48 -0
  122. package/dist/icons.d.ts.map +1 -0
  123. package/dist/icons.js +71 -0
  124. package/dist/icons.js.map +1 -0
  125. package/dist/index.d.ts +58 -0
  126. package/dist/index.d.ts.map +1 -0
  127. package/dist/index.js +36 -0
  128. package/dist/index.js.map +1 -0
  129. package/dist/labels.d.ts +58 -0
  130. package/dist/labels.d.ts.map +1 -0
  131. package/dist/labels.js +86 -0
  132. package/dist/labels.js.map +1 -0
  133. package/dist/phone.d.ts +18 -0
  134. package/dist/phone.d.ts.map +1 -0
  135. package/dist/phone.js +27 -0
  136. package/dist/phone.js.map +1 -0
  137. package/dist/proactiveIcons.d.ts +6 -0
  138. package/dist/proactiveIcons.d.ts.map +1 -0
  139. package/dist/proactiveIcons.js +39 -0
  140. package/dist/proactiveIcons.js.map +1 -0
  141. package/dist/purposes.d.ts +19 -0
  142. package/dist/purposes.d.ts.map +1 -0
  143. package/dist/purposes.js +20 -0
  144. package/dist/purposes.js.map +1 -0
  145. package/dist/segments.d.ts +29 -0
  146. package/dist/segments.d.ts.map +1 -0
  147. package/dist/segments.js +75 -0
  148. package/dist/segments.js.map +1 -0
  149. package/dist/smsSegments.d.ts +28 -0
  150. package/dist/smsSegments.d.ts.map +1 -0
  151. package/dist/smsSegments.js +100 -0
  152. package/dist/smsSegments.js.map +1 -0
  153. package/dist/styles.d.ts +15 -0
  154. package/dist/styles.d.ts.map +1 -0
  155. package/dist/styles.js +545 -0
  156. package/dist/styles.js.map +1 -0
  157. package/dist/time.d.ts +14 -0
  158. package/dist/time.d.ts.map +1 -0
  159. package/dist/time.js +80 -0
  160. package/dist/time.js.map +1 -0
  161. package/dist/useAiSettings.d.ts +11 -0
  162. package/dist/useAiSettings.d.ts.map +1 -0
  163. package/dist/useAiSettings.js +21 -0
  164. package/dist/useAiSettings.js.map +1 -0
  165. package/dist/useBilling.d.ts +40 -0
  166. package/dist/useBilling.d.ts.map +1 -0
  167. package/dist/useBilling.js +155 -0
  168. package/dist/useBilling.js.map +1 -0
  169. package/dist/useBulkDrafts.d.ts +41 -0
  170. package/dist/useBulkDrafts.d.ts.map +1 -0
  171. package/dist/useBulkDrafts.js +112 -0
  172. package/dist/useBulkDrafts.js.map +1 -0
  173. package/dist/useClients.d.ts +16 -0
  174. package/dist/useClients.d.ts.map +1 -0
  175. package/dist/useClients.js +22 -0
  176. package/dist/useClients.js.map +1 -0
  177. package/dist/useDeliveryStatus.d.ts +7 -0
  178. package/dist/useDeliveryStatus.d.ts.map +1 -0
  179. package/dist/useDeliveryStatus.js +39 -0
  180. package/dist/useDeliveryStatus.js.map +1 -0
  181. package/dist/useDrafts.d.ts +19 -0
  182. package/dist/useDrafts.d.ts.map +1 -0
  183. package/dist/useDrafts.js +60 -0
  184. package/dist/useDrafts.js.map +1 -0
  185. package/dist/useInstructions.d.ts +9 -0
  186. package/dist/useInstructions.d.ts.map +1 -0
  187. package/dist/useInstructions.js +20 -0
  188. package/dist/useInstructions.js.map +1 -0
  189. package/dist/useLiveUpdates.d.ts +9 -0
  190. package/dist/useLiveUpdates.d.ts.map +1 -0
  191. package/dist/useLiveUpdates.js +48 -0
  192. package/dist/useLiveUpdates.js.map +1 -0
  193. package/dist/usePolling.d.ts +6 -0
  194. package/dist/usePolling.d.ts.map +1 -0
  195. package/dist/usePolling.js +31 -0
  196. package/dist/usePolling.js.map +1 -0
  197. package/dist/usePreviewDrafts.d.ts +15 -0
  198. package/dist/usePreviewDrafts.d.ts.map +1 -0
  199. package/dist/usePreviewDrafts.js +77 -0
  200. package/dist/usePreviewDrafts.js.map +1 -0
  201. package/dist/useProactiveOptions.d.ts +15 -0
  202. package/dist/useProactiveOptions.d.ts.map +1 -0
  203. package/dist/useProactiveOptions.js +39 -0
  204. package/dist/useProactiveOptions.js.map +1 -0
  205. package/dist/useSend.d.ts +16 -0
  206. package/dist/useSend.d.ts.map +1 -0
  207. package/dist/useSend.js +50 -0
  208. package/dist/useSend.js.map +1 -0
  209. package/dist/useStickToBottom.d.ts +12 -0
  210. package/dist/useStickToBottom.d.ts.map +1 -0
  211. package/dist/useStickToBottom.js +71 -0
  212. package/dist/useStickToBottom.js.map +1 -0
  213. package/dist/useThread.d.ts +26 -0
  214. package/dist/useThread.d.ts.map +1 -0
  215. package/dist/useThread.js +76 -0
  216. package/dist/useThread.js.map +1 -0
  217. package/dist/useWhatsAppWindow.d.ts +8 -0
  218. package/dist/useWhatsAppWindow.d.ts.map +1 -0
  219. package/dist/useWhatsAppWindow.js +22 -0
  220. package/dist/useWhatsAppWindow.js.map +1 -0
  221. package/package.json +36 -0
package/dist/time.js ADDED
@@ -0,0 +1,80 @@
1
+ /** Time labels for the panel. All functions take `now` so tests are deterministic. */
2
+ const DAY_MS = 86_400_000;
3
+ const WEEKDAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
4
+ const MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
5
+ function parse(iso) {
6
+ if (!iso)
7
+ return null;
8
+ const t = Date.parse(iso);
9
+ return Number.isNaN(t) ? null : new Date(t);
10
+ }
11
+ function startOfDay(d) {
12
+ return new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime();
13
+ }
14
+ export function isSameDay(a, b) {
15
+ return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
16
+ }
17
+ /** "5 Oct", or "5 Oct 2025" when the year differs from `now`. */
18
+ export function shortDate(d, now = new Date()) {
19
+ const base = `${d.getDate()} ${MONTHS[d.getMonth()]}`;
20
+ return d.getFullYear() === now.getFullYear() ? base : `${base} ${d.getFullYear()}`;
21
+ }
22
+ /** Compact age for list rows: "now", "35m", "2h", "4d", "3w", then a short date. Empty for null. */
23
+ export function relativeShort(iso, now = new Date()) {
24
+ const d = parse(iso);
25
+ if (!d)
26
+ return "";
27
+ const minutes = Math.floor(Math.max(0, now.getTime() - d.getTime()) / 60_000);
28
+ if (minutes < 1)
29
+ return "now";
30
+ if (minutes < 60)
31
+ return `${minutes}m`;
32
+ const hours = Math.floor(minutes / 60);
33
+ if (hours < 24)
34
+ return `${hours}h`;
35
+ const days = Math.floor(hours / 24);
36
+ if (days < 7)
37
+ return `${days}d`;
38
+ const weeks = Math.floor(days / 7);
39
+ if (weeks < 5)
40
+ return `${weeks}w`;
41
+ return shortDate(d, now);
42
+ }
43
+ /** Sentence-ready age: "just now", "35m ago", "4d ago", "3w ago", then "on 5 Oct". Empty for null. */
44
+ export function relativeAgo(iso, now = new Date()) {
45
+ const short = relativeShort(iso, now);
46
+ if (!short)
47
+ return "";
48
+ if (short === "now")
49
+ return "just now";
50
+ return /^\d+[mhdw]$/.test(short) ? `${short} ago` : `on ${short}`;
51
+ }
52
+ /** Day separator text: "Today", "Yesterday", a weekday inside the last week, else a short date. */
53
+ export function dayLabel(iso, now = new Date()) {
54
+ const d = parse(iso);
55
+ if (!d)
56
+ return "";
57
+ if (isSameDay(d, now))
58
+ return "Today";
59
+ const daysAgo = Math.round((startOfDay(now) - startOfDay(d)) / DAY_MS);
60
+ if (daysAgo === 1)
61
+ return "Yesterday";
62
+ if (daysAgo > 1 && daysAgo < 7)
63
+ return WEEKDAYS[d.getDay()] ?? "";
64
+ return shortDate(d, now);
65
+ }
66
+ /** Local 24-hour clock, "07:02". */
67
+ export function clockLabel(iso) {
68
+ const d = parse(iso);
69
+ if (!d)
70
+ return "";
71
+ return `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
72
+ }
73
+ /** Local calendar-day key for grouping, "2026-10-05". */
74
+ export function dayKey(iso) {
75
+ const d = parse(iso);
76
+ if (!d)
77
+ return "";
78
+ return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
79
+ }
80
+ //# sourceMappingURL=time.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time.js","sourceRoot":"","sources":["../src/time.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { AiSettings, UpliftError } from "@uplifted/sdk";
2
+ export interface AiSettingsState {
3
+ data: AiSettings | null;
4
+ error: UpliftError | null;
5
+ /** Patch the local copy after a successful write, so tabs stay in step without a reload. */
6
+ patch: (fn: (d: AiSettings) => AiSettings) => void;
7
+ reload: () => void;
8
+ }
9
+ /** The coach's AI Config menu (native Settings › AI Config), loaded when the sheet opens. */
10
+ export declare function useAiSettings(): AiSettingsState;
11
+ //# sourceMappingURL=useAiSettings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAiSettings.d.ts","sourceRoot":"","sources":["../src/useAiSettings.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG7D,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IACxB,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IAC1B,4FAA4F;IAC5F,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,UAAU,KAAK,IAAI,CAAC;IACnD,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,6FAA6F;AAC7F,wBAAgB,aAAa,IAAI,eAAe,CAc/C"}
@@ -0,0 +1,21 @@
1
+ import { useCallback, useEffect, useState } from "react";
2
+ import { useUplift } from "./UpliftProvider.js";
3
+ /** The coach's AI Config menu (native Settings › AI Config), loaded when the sheet opens. */
4
+ export function useAiSettings() {
5
+ const { client } = useUplift();
6
+ const [data, setData] = useState(null);
7
+ const [error, setError] = useState(null);
8
+ const [tick, setTick] = useState(0);
9
+ useEffect(() => {
10
+ let live = true;
11
+ setError(null);
12
+ client.getAiSettings().then((d) => { if (live)
13
+ setData(d); }, (e) => { if (live)
14
+ setError(e); });
15
+ return () => { live = false; };
16
+ }, [client, tick]);
17
+ const patch = useCallback((fn) => setData((d) => (d ? fn(d) : d)), []);
18
+ const reload = useCallback(() => setTick((t) => t + 1), []);
19
+ return { data, error, patch, reload };
20
+ }
21
+ //# sourceMappingURL=useAiSettings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAiSettings.js","sourceRoot":"","sources":["../src/useAiSettings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEzD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAUhD,6FAA6F;AAC7F,MAAM,UAAU,aAAa;IAC3B,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,CAAC;IAC/B,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAoB,IAAI,CAAC,CAAC;IAC1D,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAqB,IAAI,CAAC,CAAC;IAC7D,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACpC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,IAAI,GAAG,IAAI,CAAC;QAChB,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,MAAM,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,IAAI,IAAI;YAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAc,EAAE,EAAE,GAAG,IAAI,IAAI;YAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9G,OAAO,GAAG,EAAE,GAAG,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACjC,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IACnB,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,EAAiC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACtG,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC5D,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AACxC,CAAC"}
@@ -0,0 +1,40 @@
1
+ import type { BillingPlan, Coach } from "@uplifted/sdk";
2
+ export type CheckoutStatus = "idle" | "opening" | "waiting" | "active" | "error";
3
+ export interface BillingState {
4
+ /** The Stripe price, or null while loading / when billing is unavailable. */
5
+ plan: BillingPlan | null;
6
+ /** True when Uplift reports billing is not set up (no checkout possible). */
7
+ unavailable: boolean;
8
+ status: CheckoutStatus;
9
+ /** The Stripe Checkout url once created, for a "didn't open?" link. */
10
+ url: string | null;
11
+ error: string | null;
12
+ /** Call from the click handler: the tab is opened synchronously so popup blockers allow it. */
13
+ start: () => void;
14
+ /** Ask Uplift now whether the plan is active (also runs on a timer and on window focus). */
15
+ recheck: () => void;
16
+ reset: () => void;
17
+ }
18
+ /**
19
+ * Uplift bills the coach (docs/partner-api.md › Billing): read the plan price from Stripe, open
20
+ * Checkout in a new tab, then poll the coach until the webhook has switched the plan on.
21
+ */
22
+ export declare function useBilling({ pollMs, maxWaitMs }?: {
23
+ pollMs?: number;
24
+ maxWaitMs?: number;
25
+ }): BillingState;
26
+ /** "$29" and "month" from a Stripe price; whole amounts drop the cents. */
27
+ export declare function formatPlan(plan: BillingPlan): {
28
+ price: string;
29
+ per: string;
30
+ };
31
+ export interface PlanStatusState {
32
+ coach: Coach | null;
33
+ opening: boolean;
34
+ error: string | null;
35
+ /** Opens the Stripe Customer Portal in a new tab (call from the click handler). */
36
+ manage: () => void;
37
+ }
38
+ /** The coach's plan and dates (GET /accounts/me) plus the Stripe Customer Portal. */
39
+ export declare function usePlanStatus(): PlanStatusState;
40
+ //# sourceMappingURL=useBilling.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useBilling.d.ts","sourceRoot":"","sources":["../src/useBilling.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAIxD,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEjF,MAAM,WAAW,YAAY;IAC3B,6EAA6E;IAC7E,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IACzB,6EAA6E;IAC7E,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,cAAc,CAAC;IACvB,uEAAuE;IACvE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,+FAA+F;IAC/F,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,4FAA4F;IAC5F,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAID;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EAAE,MAAa,EAAE,SAAuB,EAAE,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,YAAY,CAoEjI;AAED,2EAA2E;AAC3E,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAW5E;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,mFAAmF;IACnF,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,qFAAqF;AACrF,wBAAgB,aAAa,IAAI,eAAe,CA6B/C"}
@@ -0,0 +1,155 @@
1
+ import { useCallback, useEffect, useRef, useState } from "react";
2
+ import { useUplift } from "./UpliftProvider.js";
3
+ import { asUpliftError } from "./errors.js";
4
+ const NOT_SET_UP = "Upgrading isn't available yet. Please try again later.";
5
+ /**
6
+ * Uplift bills the coach (docs/partner-api.md › Billing): read the plan price from Stripe, open
7
+ * Checkout in a new tab, then poll the coach until the webhook has switched the plan on.
8
+ */
9
+ export function useBilling({ pollMs = 3000, maxWaitMs = 20 * 60_000 } = {}) {
10
+ const { client } = useUplift();
11
+ const [plan, setPlan] = useState(null);
12
+ const [unavailable, setUnavailable] = useState(false);
13
+ const [status, setStatus] = useState("idle");
14
+ const [url, setUrl] = useState(null);
15
+ const [error, setError] = useState(null);
16
+ const startedAt = useRef(0);
17
+ const alive = useRef(true);
18
+ // Set on every mount: StrictMode mounts, unmounts and mounts again.
19
+ useEffect(() => { alive.current = true; return () => { alive.current = false; }; }, []);
20
+ useEffect(() => {
21
+ client.plan().then((p) => { if (alive.current)
22
+ setPlan(p); }, (err) => {
23
+ const e = asUpliftError(err);
24
+ // Not set up, or an Uplift server older than billing (no such route): no checkout to offer.
25
+ if (alive.current && (e.details?.["reason"] === "billing_not_configured" || e.code === "not_found"))
26
+ setUnavailable(true);
27
+ });
28
+ }, [client]);
29
+ const recheck = useCallback(() => {
30
+ client.me().then((c) => { if (alive.current && c.subscription === "active")
31
+ setStatus("active"); }, () => { });
32
+ }, [client]);
33
+ const start = useCallback(() => {
34
+ if (status === "opening")
35
+ return;
36
+ // Open now, inside the click: a window opened after an await is blocked as a popup.
37
+ let win = null;
38
+ try {
39
+ win = typeof window !== "undefined" ? window.open("", "_blank") : null;
40
+ }
41
+ catch {
42
+ win = null;
43
+ }
44
+ setStatus("opening");
45
+ setError(null);
46
+ client.startCheckout().then((s) => {
47
+ if (win && !win.closed) {
48
+ try {
49
+ win.opener = null;
50
+ win.location.href = s.url;
51
+ }
52
+ catch { /* the link below still works */ }
53
+ }
54
+ if (!alive.current)
55
+ return;
56
+ setUrl(s.url);
57
+ startedAt.current = Date.now();
58
+ setStatus("waiting");
59
+ }, (err) => {
60
+ try {
61
+ win?.close();
62
+ }
63
+ catch { /* ignore */ }
64
+ if (!alive.current)
65
+ return;
66
+ const e = asUpliftError(err);
67
+ if (e.code === "conflict" && e.details?.["reason"] === "already_active") {
68
+ setStatus("active");
69
+ return;
70
+ }
71
+ if (e.details?.["reason"] === "billing_not_configured")
72
+ setUnavailable(true);
73
+ setError(e.details?.["reason"] === "billing_not_configured" ? NOT_SET_UP : "Couldn't open checkout. Please try again.");
74
+ setStatus("error");
75
+ });
76
+ }, [client, status]);
77
+ useEffect(() => {
78
+ if (status !== "waiting")
79
+ return;
80
+ const t = setInterval(() => {
81
+ if (Date.now() - startedAt.current > maxWaitMs) {
82
+ clearInterval(t);
83
+ return;
84
+ }
85
+ recheck();
86
+ }, pollMs);
87
+ const onFocus = () => recheck();
88
+ window.addEventListener("focus", onFocus);
89
+ return () => { clearInterval(t); window.removeEventListener("focus", onFocus); };
90
+ }, [status, pollMs, maxWaitMs, recheck]);
91
+ const reset = useCallback(() => { setStatus("idle"); setError(null); }, []);
92
+ return { plan, unavailable, status, url, error, start, recheck, reset };
93
+ }
94
+ /** "$29" and "month" from a Stripe price; whole amounts drop the cents. */
95
+ export function formatPlan(plan) {
96
+ const major = plan.amount / 100;
97
+ let price;
98
+ try {
99
+ price = new Intl.NumberFormat("en-US", { style: "currency", currency: plan.currency.toUpperCase(), minimumFractionDigits: Number.isInteger(major) ? 0 : 2 }).format(major);
100
+ }
101
+ catch {
102
+ price = `${major} ${plan.currency.toUpperCase()}`;
103
+ }
104
+ const unit = plan.interval ?? "month";
105
+ const per = plan.intervalCount > 1 ? `${plan.intervalCount} ${unit}s` : unit;
106
+ return { price, per };
107
+ }
108
+ /** The coach's plan and dates (GET /accounts/me) plus the Stripe Customer Portal. */
109
+ export function usePlanStatus() {
110
+ const { client } = useUplift();
111
+ const [coach, setCoach] = useState(null);
112
+ const [opening, setOpening] = useState(false);
113
+ const [error, setError] = useState(null);
114
+ const alive = useRef(true);
115
+ useEffect(() => { alive.current = true; return () => { alive.current = false; }; }, []);
116
+ useEffect(() => { client.me().then((c) => { if (alive.current)
117
+ setCoach(c); }, () => { }); }, [client]);
118
+ const manage = useCallback(() => {
119
+ if (opening)
120
+ return;
121
+ let win = null;
122
+ try {
123
+ win = typeof window !== "undefined" ? window.open("", "_blank") : null;
124
+ }
125
+ catch {
126
+ win = null;
127
+ }
128
+ setOpening(true);
129
+ setError(null);
130
+ client.billingPortal().then(({ url }) => {
131
+ if (win && !win.closed) {
132
+ try {
133
+ win.opener = null;
134
+ win.location.href = url;
135
+ }
136
+ catch { /* ignore */ }
137
+ }
138
+ else if (typeof window !== "undefined")
139
+ window.open(url, "_blank", "noopener");
140
+ if (alive.current)
141
+ setOpening(false);
142
+ }, () => {
143
+ try {
144
+ win?.close();
145
+ }
146
+ catch { /* ignore */ }
147
+ if (alive.current) {
148
+ setOpening(false);
149
+ setError("Couldn't open billing. Please try again.");
150
+ }
151
+ });
152
+ }, [client, opening]);
153
+ return { coach, opening, error, manage };
154
+ }
155
+ //# sourceMappingURL=useBilling.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useBilling.js","sourceRoot":"","sources":["../src/useBilling.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import type { DraftSet } from "@uplifted/sdk";
2
+ import type { HostActivityLoader } from "./host.js";
3
+ /** One client to draft for: connected (Uplift drafts) or a host client not connected yet (preview drafts from host activity). */
4
+ export type BulkTarget = {
5
+ kind: "client";
6
+ id: string;
7
+ } | {
8
+ kind: "host";
9
+ id: string;
10
+ name: string;
11
+ };
12
+ /** Per-row state while a run is going, like native's bulk job status: Generating… / Generation failed. */
13
+ export type BulkRowStatus = "pending" | "error";
14
+ export interface BulkState {
15
+ running: boolean;
16
+ /** Row key -> pending/error. Keys: the Uplift client id, or `host:<host id>` for not-connected clients. */
17
+ status: Readonly<Record<string, BulkRowStatus>>;
18
+ /** Row key -> drafts from this session's runs. Lost on reload, cleared when the coach sends. */
19
+ results: Readonly<Record<string, DraftSet>>;
20
+ /** The run stopped because the coach's plan lapsed (plan_inactive); the rest would be refused too. */
21
+ blocked: boolean;
22
+ start: (targets: BulkTarget[], prompt: string) => void;
23
+ /** Forget one row's drafts (after they were used). */
24
+ forget: (key: string) => void;
25
+ }
26
+ /** How many clients are drafted at once (native runBulkGenerateJob). */
27
+ export declare const BULK_CONCURRENCY = 3;
28
+ /** A failed row shows "Generation failed" this long, then clears (native). */
29
+ export declare const BULK_ERROR_MS = 5000;
30
+ export declare const bulkKey: (t: BulkTarget) => string;
31
+ /**
32
+ * Native Uplift's Bulk generate: the coach's prompt drafted per client as a topic, three at a time,
33
+ * with the bulk AI instructions. Connected clients use their Uplift context; not-connected host
34
+ * clients draft from their host activity through the preview endpoint (sending them opens connect).
35
+ * A rate limit waits for the server's retryAfter and tries that client again once.
36
+ */
37
+ export declare function useBulkDrafts(opts?: {
38
+ hostActivity?: HostActivityLoader | undefined;
39
+ coachName?: string | undefined;
40
+ }): BulkState;
41
+ //# sourceMappingURL=useBulkDrafts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useBulkDrafts.d.ts","sourceRoot":"","sources":["../src/useBulkDrafts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAG9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAGpD,iIAAiI;AACjI,MAAM,MAAM,UAAU,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAErG,0GAA0G;AAC1G,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,OAAO,CAAC;AAEhD,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,2GAA2G;IAC3G,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;IAChD,gGAAgG;IAChG,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC5C,sGAAsG;IACtG,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvD,sDAAsD;IACtD,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B;AAED,wEAAwE;AACxE,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,8EAA8E;AAC9E,eAAO,MAAM,aAAa,OAAO,CAAC;AAElC,eAAO,MAAM,OAAO,GAAI,GAAG,UAAU,WAAkD,CAAC;AAExF;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,GAAE;IAAE,YAAY,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAO,GAAG,SAAS,CA6ErI"}
@@ -0,0 +1,112 @@
1
+ import { useCallback, useEffect, useRef, useState } from "react";
2
+ import { useUplift } from "./UpliftProvider.js";
3
+ import { asUpliftError, retryAfterSeconds } from "./errors.js";
4
+ import { toPreviewEvent } from "./usePreviewDrafts.js";
5
+ /** How many clients are drafted at once (native runBulkGenerateJob). */
6
+ export const BULK_CONCURRENCY = 3;
7
+ /** A failed row shows "Generation failed" this long, then clears (native). */
8
+ export const BULK_ERROR_MS = 5000;
9
+ export const bulkKey = (t) => (t.kind === "client" ? t.id : `host:${t.id}`);
10
+ /**
11
+ * Native Uplift's Bulk generate: the coach's prompt drafted per client as a topic, three at a time,
12
+ * with the bulk AI instructions. Connected clients use their Uplift context; not-connected host
13
+ * clients draft from their host activity through the preview endpoint (sending them opens connect).
14
+ * A rate limit waits for the server's retryAfter and tries that client again once.
15
+ */
16
+ export function useBulkDrafts(opts = {}) {
17
+ const { client } = useUplift();
18
+ const [running, setRunning] = useState(false);
19
+ const [status, setStatus] = useState({});
20
+ const [results, setResults] = useState({});
21
+ const [blocked, setBlocked] = useState(false);
22
+ const active = useRef(false);
23
+ const alive = useRef(true);
24
+ const timers = useRef(new Set());
25
+ const optsRef = useRef(opts);
26
+ optsRef.current = opts;
27
+ useEffect(() => {
28
+ alive.current = true;
29
+ const t = timers.current;
30
+ return () => { alive.current = false; t.forEach(clearTimeout); t.clear(); };
31
+ }, []);
32
+ const setRow = useCallback((key, s) => setStatus((m) => {
33
+ if (s === null) {
34
+ if (!(key in m))
35
+ return m;
36
+ const { [key]: _gone, ...rest } = m;
37
+ return rest;
38
+ }
39
+ return { ...m, [key]: s };
40
+ }), []);
41
+ const forget = useCallback((key) => setResults((r) => { if (!(key in r))
42
+ return r; const { [key]: _gone, ...rest } = r; return rest; }), []);
43
+ const draftOne = useCallback(async (t, prompt) => {
44
+ if (t.kind === "client")
45
+ return client.drafts(t.id, { purpose: prompt, purposeMode: "topic" });
46
+ const loaded = optsRef.current.hostActivity ? await optsRef.current.hostActivity(t.id) : { events: [] };
47
+ const events = [...(loaded?.events ?? [])].sort((a, b) => b.occurredAt.localeCompare(a.occurredAt)).slice(0, 10).map(toPreviewEvent);
48
+ const coachName = optsRef.current.coachName;
49
+ return client.previewDrafts({ clientName: t.name, ...(coachName ? { coachName } : {}), events, purpose: prompt });
50
+ }, [client]);
51
+ const start = useCallback((targets, prompt) => {
52
+ const p = prompt.trim();
53
+ if (active.current || targets.length === 0 || !p)
54
+ return;
55
+ active.current = true;
56
+ setRunning(true);
57
+ setBlocked(false);
58
+ setStatus((m) => { const next = { ...m }; for (const t of targets)
59
+ next[bulkKey(t)] = "pending"; return next; });
60
+ const queue = [...targets];
61
+ let stop = false;
62
+ const fail = (key) => {
63
+ setRow(key, "error");
64
+ const timer = setTimeout(() => { timers.current.delete(timer); if (alive.current)
65
+ setRow(key, null); }, BULK_ERROR_MS);
66
+ timers.current.add(timer);
67
+ };
68
+ const worker = async () => {
69
+ for (let t = queue.shift(); t; t = queue.shift()) {
70
+ const key = bulkKey(t);
71
+ if (stop) {
72
+ setRow(key, null);
73
+ continue;
74
+ }
75
+ for (let attempt = 0;; attempt++) {
76
+ try {
77
+ const set = await draftOne(t, p);
78
+ if (!alive.current)
79
+ return;
80
+ setResults((r) => ({ ...r, [key]: set }));
81
+ setRow(key, null);
82
+ }
83
+ catch (err) {
84
+ const e = asUpliftError(err);
85
+ if (e.code === "rate_limited" && attempt === 0) {
86
+ await new Promise((r) => setTimeout(r, retryAfterSeconds(e) * 1000));
87
+ continue;
88
+ }
89
+ if (!alive.current)
90
+ return;
91
+ if (e.code === "plan_inactive" || e.code === "unauthorized" || e.code === "forbidden") {
92
+ if (e.code === "plan_inactive")
93
+ setBlocked(true);
94
+ stop = true;
95
+ setRow(key, null);
96
+ }
97
+ else
98
+ fail(key);
99
+ }
100
+ break;
101
+ }
102
+ }
103
+ };
104
+ void Promise.all(Array.from({ length: Math.min(BULK_CONCURRENCY, targets.length) }, worker)).finally(() => {
105
+ active.current = false;
106
+ if (alive.current)
107
+ setRunning(false);
108
+ });
109
+ }, [draftOne, setRow]);
110
+ return { running, status, results, blocked, start, forget };
111
+ }
112
+ //# sourceMappingURL=useBulkDrafts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useBulkDrafts.js","sourceRoot":"","sources":["../src/useBulkDrafts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { Client, UpliftError } from "@uplifted/sdk";
2
+ export type LoadStatus = "loading" | "ready" | "error";
3
+ export interface ClientsState {
4
+ status: LoadStatus;
5
+ clients: Client[];
6
+ error: UpliftError | null;
7
+ /** Fetch again. Keeps the current rows on screen while loading. */
8
+ reload: () => void;
9
+ /** Quiet refetch for polling: no loading state, rows replaced in place. */
10
+ refresh: () => void;
11
+ /** Insert or replace one client locally (after add or send), no round trip. */
12
+ upsert: (client: Client) => void;
13
+ }
14
+ /** The coach's Uplift clients. Loads once per provider, re-fetches on reload(). */
15
+ export declare function useClients(): ClientsState;
16
+ //# sourceMappingURL=useClients.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useClients.d.ts","sourceRoot":"","sources":["../src/useClients.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAIzD,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAEvD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IAC1B,mEAAmE;IACnE,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,2EAA2E;IAC3E,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,+EAA+E;IAC/E,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;AAED,mFAAmF;AACnF,wBAAgB,UAAU,IAAI,YAAY,CAmBzC"}
@@ -0,0 +1,22 @@
1
+ import { useCallback, useEffect, useState } from "react";
2
+ import { useUplift } from "./UpliftProvider.js";
3
+ import { asUpliftError } from "./errors.js";
4
+ /** The coach's Uplift clients. Loads once per provider, re-fetches on reload(). */
5
+ export function useClients() {
6
+ const { client } = useUplift();
7
+ const [state, setState] = useState({ status: "loading", clients: [], error: null });
8
+ const [tick, setTick] = useState(0);
9
+ useEffect(() => {
10
+ let live = true;
11
+ setState((s) => ({ ...s, status: "loading", error: null }));
12
+ client.listClients().then((clients) => { if (live)
13
+ setState({ status: "ready", clients, error: null }); }, (err) => { if (live)
14
+ setState((s) => ({ ...s, status: "error", error: asUpliftError(err) })); });
15
+ return () => { live = false; };
16
+ }, [client, tick]);
17
+ const reload = useCallback(() => setTick((t) => t + 1), []);
18
+ const refresh = useCallback(() => { client.listClients().then((clients) => setState((s) => ({ ...s, clients })), () => { }); }, [client]);
19
+ const upsert = useCallback((c) => setState((s) => ({ ...s, clients: s.clients.some((x) => x.id === c.id) ? s.clients.map((x) => (x.id === c.id ? c : x)) : [...s.clients, c] })), []);
20
+ return { ...state, reload, refresh, upsert };
21
+ }
22
+ //# sourceMappingURL=useClients.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useClients.js","sourceRoot":"","sources":["../src/useClients.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { Message } from "@uplifted/sdk";
2
+ /**
3
+ * Keep outbound messages' delivery status fresh, like native useMessageDeliveryStatus: every outbound
4
+ * message whose status is not terminal is polled until it is, and the thread is patched in place.
5
+ */
6
+ export declare function useDeliveryStatus(clientId: string | null, messages: Message[], patch: (id: string, changes: Partial<Message>) => void): void;
7
+ //# sourceMappingURL=useDeliveryStatus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDeliveryStatus.d.ts","sourceRoot":"","sources":["../src/useDeliveryStatus.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAO7C;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,IAAI,QAwBrI"}
@@ -0,0 +1,39 @@
1
+ import { useEffect, useRef } from "react";
2
+ import { useUplift } from "./UpliftProvider.js";
3
+ const TERMINAL = new Set(["delivered", "read", "failed", "undelivered"]);
4
+ const POLL_MS = 5000;
5
+ const MAX_POLLS = 24; // 2 minutes, like native's non-terminal polling
6
+ /**
7
+ * Keep outbound messages' delivery status fresh, like native useMessageDeliveryStatus: every outbound
8
+ * message whose status is not terminal is polled until it is, and the thread is patched in place.
9
+ */
10
+ export function useDeliveryStatus(clientId, messages, patch) {
11
+ const { client } = useUplift();
12
+ const polls = useRef(new Map());
13
+ const pending = messages.filter((m) => m.kind === "message" && m.direction === "outbound" && m.deliveryStatus && !TERMINAL.has(m.deliveryStatus)).map((m) => m.id).join(",");
14
+ useEffect(() => {
15
+ if (!clientId || !pending)
16
+ return;
17
+ const ids = pending.split(",");
18
+ let live = true;
19
+ const tick = async () => {
20
+ for (const id of ids) {
21
+ const n = polls.current.get(id) ?? 0;
22
+ if (n >= MAX_POLLS)
23
+ continue;
24
+ polls.current.set(id, n + 1);
25
+ try {
26
+ const s = await client.messageStatus(clientId, id);
27
+ if (!live)
28
+ return;
29
+ patch(id, { deliveryStatus: s.status });
30
+ }
31
+ catch { /* keep the last known status */ }
32
+ }
33
+ };
34
+ void tick();
35
+ const t = setInterval(() => { void tick(); }, POLL_MS);
36
+ return () => { live = false; clearInterval(t); };
37
+ }, [client, clientId, pending, patch]);
38
+ }
39
+ //# sourceMappingURL=useDeliveryStatus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDeliveryStatus.js","sourceRoot":"","sources":["../src/useDeliveryStatus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC;AACzE,MAAM,OAAO,GAAG,IAAI,CAAC;AACrB,MAAM,SAAS,GAAG,EAAE,CAAC,CAAC,gDAAgD;AAEtE;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAuB,EAAE,QAAmB,EAAE,KAAsD;IACpI,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,MAAM,CAAsB,IAAI,GAAG,EAAE,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,CAAC,SAAS,KAAK,UAAU,IAAI,CAAC,CAAC,cAAc,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7K,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,QAAQ,IAAI,CAAC,OAAO;YAAE,OAAO;QAClC,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,IAAI,GAAG,IAAI,CAAC;QAChB,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE;YACtB,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;gBACrB,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;gBACrC,IAAI,CAAC,IAAI,SAAS;oBAAE,SAAS;gBAC7B,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC7B,IAAI,CAAC;oBACH,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;oBACnD,IAAI,CAAC,IAAI;wBAAE,OAAO;oBAClB,KAAK,CAAC,EAAE,EAAE,EAAE,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;gBAC1C,CAAC;gBAAC,MAAM,CAAC,CAAC,gCAAgC,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC,CAAC;QACF,KAAK,IAAI,EAAE,CAAC;QACZ,MAAM,CAAC,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QACvD,OAAO,GAAG,EAAE,GAAG,IAAI,GAAG,KAAK,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACnD,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;AACzC,CAAC"}