@everfur/sdk 0.4.0 → 0.5.1

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 (177) hide show
  1. package/CHANGELOG.md +220 -0
  2. package/README.md +9 -8
  3. package/dist/{Chat-BZZ-Py5l.d.ts → Chat-Rzplrf5M.d.ts} +17 -3
  4. package/dist/{Chat-Dq4fffIO.d.cts → Chat-ypo6miKm.d.cts} +17 -3
  5. package/dist/{DepthViews-BG3E25MD.d.ts → DepthViews-CeTfPUBX.d.ts} +1 -1
  6. package/dist/{DepthViews-B_hIypI6.d.cts → DepthViews-ClykXOJj.d.cts} +1 -1
  7. package/dist/{DepthViews-CL75jyRA.d.cts → DepthViews-Cui3oonj.d.cts} +1 -1
  8. package/dist/{DepthViews-CkYri51q.d.ts → DepthViews-baYLMNQ-.d.ts} +1 -1
  9. package/dist/{ErrorPolicyPort-CwbfmxzJ.d.ts → ErrorPolicyPort-D22LUVrK.d.ts} +1 -1
  10. package/dist/{ErrorPolicyPort-CNf4uQZP.d.cts → ErrorPolicyPort-D6CybiqJ.d.cts} +1 -1
  11. package/dist/{EverfurResult-DN9pL2Ab.d.cts → EverfurError-DmELDpXp.d.cts} +1 -67
  12. package/dist/{EverfurResult-DN9pL2Ab.d.ts → EverfurError-DmELDpXp.d.ts} +1 -67
  13. package/dist/EverfurResult-SGvHKsCB.d.ts +69 -0
  14. package/dist/EverfurResult-ZtH-YV1h.d.cts +69 -0
  15. package/dist/animations/index.cjs +1 -1
  16. package/dist/animations/index.d.cts +6 -5
  17. package/dist/animations/index.d.ts +6 -5
  18. package/dist/animations/index.js +1 -1
  19. package/dist/{attachments-D_SECjr1.d.cts → attachments-CwsR-bPN.d.cts} +7 -6
  20. package/dist/{attachments-BrUWQYNK.d.ts → attachments-CzZ7in24.d.ts} +7 -6
  21. package/dist/{attachments-DpldrvIW.d.ts → attachments-D3HCBmOE.d.ts} +3 -3
  22. package/dist/{attachments-BorG422I.d.cts → attachments-Nk73Lll8.d.cts} +3 -3
  23. package/dist/{bookingCopy-SREvkG19.d.cts → bookingCopy-Dv8rKqyV.d.cts} +417 -14
  24. package/dist/{bookingCopy-CqtDYvCR.d.ts → bookingCopy-SDkXaxDf.d.ts} +417 -14
  25. package/dist/branding-Xb_wL8N1.d.cts +212 -0
  26. package/dist/branding-xpQ056sM.d.ts +212 -0
  27. package/dist/callCopy-rDH9JTFo.d.cts +45 -0
  28. package/dist/callCopy-rDH9JTFo.d.ts +45 -0
  29. package/dist/callRoom-7wrE3RP2.d.ts +62 -0
  30. package/dist/callRoom-B_EqaUzx.d.cts +62 -0
  31. package/dist/{casesRepository-v6QczS9N.d.ts → casesRepository-BTAecTnF.d.ts} +14 -2
  32. package/dist/{casesRepository-DwtZVsbj.d.cts → casesRepository-aryld7fJ.d.cts} +14 -2
  33. package/dist/chat/index.cjs +1 -1
  34. package/dist/chat/index.d.cts +12 -11
  35. package/dist/chat/index.d.ts +12 -11
  36. package/dist/chat/index.js +1 -1
  37. package/dist/client/index.cjs +5 -5
  38. package/dist/client/index.d.cts +14 -12
  39. package/dist/client/index.d.ts +14 -12
  40. package/dist/client/index.js +5 -5
  41. package/dist/{config-C7eb_IMD.d.ts → config-6qS7Sohy.d.cts} +3 -2
  42. package/dist/{config--Wu1Umhd.d.cts → config-X6BtwDwQ.d.ts} +3 -2
  43. package/dist/consent/index.cjs +1 -1
  44. package/dist/consent/index.d.cts +9 -8
  45. package/dist/consent/index.d.ts +9 -8
  46. package/dist/consent/index.js +1 -1
  47. package/dist/{context-CahAEha8.d.ts → context-7f3Nb_xE.d.ts} +9 -8
  48. package/dist/{context-CL3lyuy1.d.cts → context-CkqPM4Ml.d.cts} +9 -8
  49. package/dist/{copy-UeUJVk8X.d.cts → copy-Bd__Pw5s.d.cts} +5 -4
  50. package/dist/{copy-DdVFDL01.d.ts → copy-NgKgOOET.d.ts} +5 -4
  51. package/dist/core/index.cjs +9 -9
  52. package/dist/core/index.d.cts +19 -17
  53. package/dist/core/index.d.ts +19 -17
  54. package/dist/core/index.js +9 -9
  55. package/dist/{depth-DvPwPuT_.d.ts → depth-CYPH92jE.d.ts} +6 -5
  56. package/dist/{depth-D5HwcvKC.d.cts → depth-CyjaJJ6V.d.cts} +6 -5
  57. package/dist/{entitlementRepository-B7egEdW6.d.ts → entitlementRepository-DdeFuEKp.d.ts} +4 -4
  58. package/dist/{entitlementRepository-BpJ7tiwl.d.cts → entitlementRepository-Dl1qRLcJ.d.cts} +4 -4
  59. package/dist/{identity-C2-08BZW.d.cts → identity-DjqhDm5Z.d.cts} +2 -2
  60. package/dist/{identity-CEi9GRFZ.d.ts → identity-Dy_L7Yq4.d.ts} +2 -2
  61. package/dist/index.cjs +6 -6
  62. package/dist/index.d.cts +19 -17
  63. package/dist/index.d.ts +19 -17
  64. package/dist/index.js +6 -6
  65. package/dist/{models-D2EUxPZY.d.cts → models-Bn2z0NNo.d.cts} +1 -1
  66. package/dist/{models-B-Uh2LTf.d.ts → models-DSqA5Ahs.d.ts} +1 -1
  67. package/dist/notifications/index.cjs +2 -2
  68. package/dist/notifications/index.d.cts +5 -4
  69. package/dist/notifications/index.d.ts +5 -4
  70. package/dist/notifications/index.js +2 -2
  71. package/dist/{pets-JVCXgRgR.d.cts → pets-BSG2qbr_.d.cts} +2 -2
  72. package/dist/{pets-DJv2sj2H.d.ts → pets-D7cZutrX.d.ts} +2 -2
  73. package/dist/{petsRepository-B_gKbAzJ.d.cts → petsRepository-D1bnxDZg.d.cts} +2 -2
  74. package/dist/{petsRepository-Bk6GDwLs.d.ts → petsRepository-DhsX3GLw.d.ts} +2 -2
  75. package/dist/photo/index.cjs +1 -1
  76. package/dist/photo/index.d.cts +3 -2
  77. package/dist/photo/index.d.ts +3 -2
  78. package/dist/photo/index.js +1 -1
  79. package/dist/{ports-D7YW8qz9.d.ts → ports-C0m1G1fS.d.ts} +13 -6
  80. package/dist/{ports-BY2ph0_y.d.cts → ports-DNXyyzZF.d.cts} +13 -6
  81. package/dist/records/depth/index.cjs +2 -2
  82. package/dist/records/depth/index.d.cts +11 -10
  83. package/dist/records/depth/index.d.ts +11 -10
  84. package/dist/records/depth/index.js +2 -2
  85. package/dist/records/index.cjs +3 -3
  86. package/dist/records/index.d.cts +25 -14
  87. package/dist/records/index.d.ts +25 -14
  88. package/dist/records/index.js +3 -3
  89. package/dist/{requestFunnel-BjDpqqvm.d.cts → requestFunnel-Bqc1inM9.d.cts} +5 -4
  90. package/dist/{requestFunnel-DFMGcluw.d.ts → requestFunnel-FvE5yLDD.d.ts} +5 -4
  91. package/dist/{runtimeTypes-w5KqBMcs.d.ts → runtimeTypes-C0yPBz89.d.ts} +7 -7
  92. package/dist/{runtimeTypes-gZEJu-da.d.cts → runtimeTypes-RN-VXTFV.d.cts} +7 -7
  93. package/dist/server/events/index.cjs +1 -1
  94. package/dist/server/events/index.d.cts +4 -3
  95. package/dist/server/events/index.d.ts +4 -3
  96. package/dist/server/events/index.js +1 -1
  97. package/dist/server/index.cjs +1 -1
  98. package/dist/server/index.d.cts +5 -4
  99. package/dist/server/index.d.ts +5 -4
  100. package/dist/server/index.js +1 -1
  101. package/dist/televet/booking/index.cjs +1 -1
  102. package/dist/televet/booking/index.d.cts +310 -32
  103. package/dist/televet/booking/index.d.ts +310 -32
  104. package/dist/televet/booking/index.js +1 -1
  105. package/dist/televet/call/index.cjs +1 -1
  106. package/dist/televet/call/index.d.cts +25 -5
  107. package/dist/televet/call/index.d.ts +25 -5
  108. package/dist/televet/call/index.js +1 -1
  109. package/dist/televet/index.cjs +1 -1
  110. package/dist/televet/index.d.cts +41 -71
  111. package/dist/televet/index.d.ts +41 -71
  112. package/dist/televet/index.js +1 -1
  113. package/dist/televetGlobal-CEk0_cW9.d.cts +34 -0
  114. package/dist/televetGlobal-Cs9Wbqsy.d.ts +34 -0
  115. package/dist/testing/index.cjs +3 -3
  116. package/dist/testing/index.d.cts +3 -2
  117. package/dist/testing/index.d.ts +3 -2
  118. package/dist/testing/index.js +3 -3
  119. package/dist/testing/rn/index.cjs +1 -1
  120. package/dist/testing/rn/index.d.cts +13 -11
  121. package/dist/testing/rn/index.d.ts +13 -11
  122. package/dist/testing/rn/index.js +1 -1
  123. package/dist/testing/web/index.cjs +1 -1
  124. package/dist/testing/web/index.d.cts +14 -13
  125. package/dist/testing/web/index.d.ts +14 -13
  126. package/dist/testing/web/index.js +1 -1
  127. package/dist/{timelineRows-C15jxFFH.d.ts → timelineRows-D4U6A8zE.d.ts} +1 -1
  128. package/dist/{timelineRows-odO8g9r2.d.cts → timelineRows-DAB5dpjF.d.cts} +1 -1
  129. package/dist/{branding-CsRdeNwK.d.cts → tokens-CIngRkvt.d.cts} +7 -211
  130. package/dist/{branding-CsRdeNwK.d.ts → tokens-CIngRkvt.d.ts} +7 -211
  131. package/dist/{typeStyle-DmoyacDG.d.ts → typeStyle-DHJzDaUo.d.cts} +2 -1
  132. package/dist/{typeStyle-CKqVYD6L.d.cts → typeStyle-YPS_MXeI.d.ts} +2 -1
  133. package/dist/{useRecordsDepth-crhBllQK.d.ts → useRecordsDepth--ObtMyjH.d.ts} +24 -5
  134. package/dist/{useRecordsDepth-C6rjEaLn.d.cts → useRecordsDepth-B35y8bV-.d.cts} +24 -5
  135. package/dist/{useVetVisit-CjmMa896.d.ts → useVetVisit-BsjoDO-n.d.ts} +21 -6
  136. package/dist/{useVetVisit-Bc84hWUU.d.cts → useVetVisit-Ds8f1peV.d.cts} +21 -6
  137. package/dist/video/index.cjs +1 -1
  138. package/dist/video/index.d.cts +3 -2
  139. package/dist/video/index.d.ts +3 -2
  140. package/dist/video/index.js +1 -1
  141. package/dist/{view-DyitEO0m.d.cts → view-B-Toym_j.d.cts} +5 -4
  142. package/dist/{view-Bxwxp4xD.d.ts → view-D9JqNQai.d.ts} +5 -4
  143. package/dist/web/consent/index.cjs +1 -1
  144. package/dist/web/consent/index.d.cts +9 -8
  145. package/dist/web/consent/index.d.ts +9 -8
  146. package/dist/web/consent/index.js +1 -1
  147. package/dist/web/index.cjs +10 -10
  148. package/dist/web/index.d.cts +42 -19
  149. package/dist/web/index.d.ts +42 -19
  150. package/dist/web/index.js +10 -10
  151. package/dist/web/notifications/index.cjs +2 -2
  152. package/dist/web/notifications/index.d.cts +7 -6
  153. package/dist/web/notifications/index.d.ts +7 -6
  154. package/dist/web/notifications/index.js +2 -2
  155. package/dist/web/records/depth/index.cjs +2 -2
  156. package/dist/web/records/depth/index.d.cts +11 -10
  157. package/dist/web/records/depth/index.d.ts +11 -10
  158. package/dist/web/records/depth/index.js +2 -2
  159. package/dist/web/records/index.cjs +3 -3
  160. package/dist/web/records/index.d.cts +53 -35
  161. package/dist/web/records/index.d.ts +53 -35
  162. package/dist/web/records/index.js +3 -3
  163. package/dist/web/televet/booking/index.cjs +2 -1
  164. package/dist/web/televet/booking/index.d.cts +458 -33
  165. package/dist/web/televet/booking/index.d.ts +458 -33
  166. package/dist/web/televet/booking/index.js +2 -1
  167. package/dist/web/televet/call/index.cjs +1 -1
  168. package/dist/web/televet/call/index.d.cts +3 -1
  169. package/dist/web/televet/call/index.d.ts +3 -1
  170. package/dist/web/televet/call/index.js +1 -1
  171. package/dist/web/televet/index.cjs +1 -1
  172. package/dist/web/televet/index.d.cts +40 -74
  173. package/dist/web/televet/index.d.ts +40 -74
  174. package/dist/web/televet/index.js +1 -1
  175. package/package.json +3 -2
  176. package/dist/callCopy-DoQKG3-L.d.cts +0 -40
  177. package/dist/callCopy-DoQKG3-L.d.ts +0 -40
package/CHANGELOG.md CHANGED
@@ -8,6 +8,226 @@ The line is deliberately pre-1.0: the API is stable enough to build against and
8
8
  is guarded by api-extractor golden reports across all eleven subpaths, but 1.0.0 is a promise about breaking
9
9
  changes that has not been earned by any production integration yet.
10
10
 
11
+ ## [Unreleased]
12
+
13
+ ## [0.5.1] - 2026-09-23
14
+
15
+ Fixes from the partner end-to-end run of 2026-09-23 (a Vite React web app and an Expo app, built through the
16
+ MCP planner, against staging). No public signature changes.
17
+
18
+ ### Fixed
19
+
20
+ - **A partner member is told booking is paused, never that they need Pro.** On the partner plane the televet
21
+ entitlement read answers whether YOUR allowance is on, not whether the member has a plan. When it answered
22
+ `active: false` (allowance not set yet, suspended, set to 0 or used up) the booking flow opened, on both
23
+ platforms and from every vet entry, on "A Pro membership is needed to book a video visit.", with Close as the
24
+ only control. That state now renders what the unavailable branch renders: your `renderUnavailable` when you
25
+ pass one, else the paused card ("Booking is not available right now."). A 402 at Confirm joins the same state
26
+ instead of printing the membership sentence under Confirm. The test id `televet-booking-not-entitled` and the
27
+ optional "Check availability" escape are unchanged. The exported `TelevetEntitlementInterestState` draws the
28
+ paused card too. `confirmNotEntitled` stays in the copy deck and no screen renders it.
29
+ - **Close on an untouched booking leaves without asking.** The auto-matched vet counted as an answer, so every
30
+ booking with a non-empty roster asked "Leave without booking? Your answers will not be saved." of a member who
31
+ had entered nothing. Typed text and a held slot still ask. Both platforms.
32
+ - **A rate-limited televet read settles after one request.** The televet 429 names its wait as
33
+ `retry_after_seconds` in the body; the request funnel read only `resets_at`, so each such 429 was retried up to
34
+ the attempt ceiling against a window that could have minutes left. A numeric `retry_after_seconds` is now the
35
+ retry override, a wait past the retry budget settles on the first 429, and `televet_rate_limited` normalizes to
36
+ `rateLimited`. The visits list shows the server's own sentence for a rate limit instead of "Check your
37
+ connection and try again." (web), or under its title (React Native); no sentence is written by the SDK.
38
+ - The upload progress line no longer reads "Uploading 2 of 1..." while the last file is being confirmed; the
39
+ counter is held to the total, on the card and in the queue's live region.
40
+ - Web surfaces stop a host page's inherited `text-align` at their root. A stock Vite app's `#root` centers text,
41
+ which centered chat replies, the records timeline and the clinic request form. Chat, every records screen, the
42
+ clinic request composer, the booking flow, the visits list, the call and its lobby, the capability off-state
43
+ and the clinical disclaimer set `text-align: start` on their root; your `style` prop still wins.
44
+ - The web full record's two header actions draw the consumer's icons (Feather `send` and `share-2`, as the
45
+ React Native SDK already does) instead of a rotated square and an empty circle. Their accessible names are
46
+ unchanged.
47
+ - The web records entry's size line moves 90_300 -> 94_800 gzip bytes (measured 90_326, plus 5%): main held it
48
+ by 350 bytes and the icons (+290) with the text-align reset and the counter clamp (+86) crossed it by 26.
49
+ Every other entry holds its line on the same build.
50
+
51
+ ## [0.5.0] - 2026-09-23
52
+
53
+ 0.4.1 was tagged but never published to npm: its fixes (the five televet refusal screens and the rest
54
+ listed under 0.4.1 below) ship in this release instead.
55
+
56
+ ### Changed: records keep the member inside your app, and the web records page is complete on its own
57
+
58
+ **What an existing integration notices.** Nothing is removed and every signature still compiles, with the one
59
+ exception in the first bullet. What changes is which edges a host navigator receives and where a URL goes when
60
+ you pass no `onOpenUrl`.
61
+
62
+ - `RecordsScreen` gains `requests` (the request list) and `RecordsUrlKind` gains `request_document` (web, one
63
+ uploaded request document). A `switch` over either that ends in an exhaustive `assertNever` stops compiling
64
+ until it handles the new member.
65
+ - A host that routes the records screens itself (`onNavigate`) now receives edges it never received before:
66
+ `requests` from the React Native dashboard's new request-status card, and `clinicPicker` and `request` from
67
+ the web `EverfurRecordsPage` header and request rows. A router with no case for them leaves
68
+ those controls doing nothing, so add the cases (or pass no `onNavigate` on the web page, which then opens
69
+ every screen inside itself).
70
+ - With no `onOpenUrl`, nothing opens a browser or a tab any more. React Native shares a share link through the
71
+ OS share sheet, and the record PDF's short-lived link the same way. The web shares a link with
72
+ `navigator.share`, else copies it, and saves the record PDF and an uploaded document in place. The web save
73
+ needs the API to sign those links as attachments (`response-content-disposition=attachment`); against an API
74
+ that does not yet, the save does not happen and the control shows its existing failure line, and it never
75
+ falls back to a tab.
76
+ - The web `EverfurRecordsPage` is the default web records surface, and the hosted records frame serves it.
77
+ The React Native-shaped web `EverfurRecords` flow stays for existing embeds, and now moves focus to each new
78
+ screen's heading.
79
+ - Frame mode: the loader's sandbox adds `allow-downloads` and it delegates `clipboard-write; web-share` (this
80
+ applies to the chat frame as well). The records frame document's policy adds the consent-signature bucket to
81
+ `connect-src` and `img-src` and the media bucket to `frame-src`. Your page's `frame-src` stays
82
+ `https://sdk.everfur.com`.
83
+
84
+ ### Changed: a vet visit opens INSIDE your app by default, on both platforms
85
+
86
+ **The owner's decision of 2026-09-21: in-app is the default and the hosted redirect is an explicit opt-in.**
87
+ `VetVisitButton`, `useVetVisit().open()` and `openVisit()`, and every vet entry inside `EverfurChat` (the header,
88
+ the urgency pill, the vet-prep chip, the check-in) now resolve one destination, in order: the button's own
89
+ `onStartInApp`, a presenter registered with `registerEverfurTelevetFlow`, else the in-app visit Everfur provides,
90
+ rendered by the new `EverfurTelevetHost` (a full-screen `Modal` on React Native, a modal `<dialog>` in the SDK's own
91
+ DOM subtree on the web). `VetVisitButton` and `EverfurChat` mount that host themselves. Nothing opens the system
92
+ browser or a new tab unless the host passes `prefer="redirect"` (`prefer: 'redirect'` on the hook,
93
+ `vetPrefer="redirect"` on chat), which keeps the 0.4.x handoff byte for byte.
94
+
95
+ **Who is affected: every integration that registered nothing.** In 0.4.x a press with nothing registered minted a
96
+ handoff and opened the hosted page; it now opens the in-app visit. An existing visit (`visitRef`, a tapped push)
97
+ used to skip the registry and always go hosted; it now travels in the request (`request.visitRef`,
98
+ `request.intent`) to the same destinations. A presenter may return `false` to decline a request it does not handle.
99
+ `onStartInApp` now receives the request.
100
+
101
+ **The screens load on demand.** The booking flow is loaded through a dynamic import of
102
+ `@everfur/sdk/televet/booking` (`@everfur/sdk/web/televet/booking`) on the first press, and the call through
103
+ `@everfur/sdk/televet/call` (`@everfur/sdk/web/televet/call`) only when a visit is joined (ruling R11). On the web
104
+ the partner's bundler splits both into their own chunks. On React Native, Metro bundles what is reachable, so the
105
+ booking screens are now part of any app that renders `VetVisitButton` or `EverfurChat`.
106
+
107
+ ### Added
108
+
109
+ - `TelevetBookingController.listConsults`, `getConsult`, `joinConsult` and `cancelConsult`, the clients for the
110
+ served partner routes the SDK had none for (`GET /widget/v1/televet/consults`, `GET .../consults/{id}`,
111
+ `POST .../consults/{id}/join`, `POST .../consults/{id}/cancel`). The join answers the room credential
112
+ (`VetCallCredential`: room, token, `recordingNotice`, `callLimits`) with one attempt and no idempotency key.
113
+ - The `call` screen of `EverfurTelevet`, `TelevetJoinScreen`, `televetScreenForRequest`, `EverfurTelevetModal` /
114
+ `EverfurTelevetDialog`, `useTelevetJoin`.
115
+ - **The member's visits, in the app.** `EverfurTelevet` now lands on `home`: the member's visits when one is still
116
+ ahead, otherwise the booking. React Native ports the consumer mobile app's history and visit screens
117
+ (`TelevetVisitsScreen`, `TelevetConsultScreen`: the time, the vet, a Join that arms on the join window,
118
+ Reschedule, Cancel with the served terms and the server's receipt). The web ports the consumer web app's list
119
+ (`TelevetVisitsScreen`, `TelevetCancelVisitForm`), with Join, Reschedule and Cancel on each row. A reminder's
120
+ `visitRef` opens the visits. `TelevetConsult.hasRoom`; `splitTelevetVisits`, `televetJoinReadiness`,
121
+ `televetJoinDecision`, `canManageTelevetVisit`.
122
+ - **The emergency warning's ways out** (`TelevetEmergencyExits`), on both places the warning appears: the pet's
123
+ clinic (`primaryVet`) and the host's locator (`onFindEmergencyVet`, new). `primaryVet`, `onFindEmergencyVet`
124
+ and `onTriageReason` now pass through `EverfurTelevet`. The consumer web's ASPCA Animal Poison Control card is
125
+ built but not drawn until the owner approves its number and its "a fee may apply" line for partner pages; a
126
+ web warning with no card on screen reads the lede that points at no list.
127
+ - **React Native call controls are glyphs**, with Switch camera (the module's `cycleCamera`; the self-view is
128
+ mirrored only for the front lens) and the speaker route (`setNativeInCallAudioMode`), each drawn only when the
129
+ native module has the method.
130
+ - The recording notice (D8) in `EverfurVetCall` on both platforms, before the room, every mount, with no prop to
131
+ skip it: no call object or frame exists until the member continues.
132
+
133
+ ### Changed: the web booking is the consumer web app's funnel
134
+
135
+ The web booking was a DOM port of the React Native flow in the mobile deck's words. It now draws the consumer web
136
+ funnel: a text Back, a bar of eight segments and an x, a centred heading per step, a main-issues step before the
137
+ description (the reason the vet reads is the chips and the words), and the web app's own strings through a web
138
+ deck (`TELEVET_BOOKING_COPY_WEB`): "Type to the vet what you're seeing", "Which vet would you like to see?",
139
+ "Pick a date and time", "Does this look right?", "You're booked with {vet}", "Add to Calendar". React Native is
140
+ unchanged except that its describe heading takes the mobile app's current "Tell the vet what you are seeing".
141
+
142
+ ### Changed: chat citation sources stay in your app, and chat reads like Everfur's own apps
143
+
144
+ - **Citation sources no longer leave the app by default, on either platform.** Without a host opener a source card
145
+ is the read-only card (title, meta line, excerpt; no link). `EverfurChat` takes `onOpenUrl(url, 'citation')`,
146
+ the same shape as records, called through the host-callback guard. **Who is affected:** an integration that relied
147
+ on sources opening a browser or a new tab must now pass an opener, for example `(url) => Linking.openURL(url)` or
148
+ `(url) => { window.open(url, '_blank', 'noopener'); }`. The CDN frame draws the read-only card, since its sandbox
149
+ has no `allow-popups`.
150
+ - **The web chat lays out by its own box, not the viewport**, like the consumer web app: history is a brand rail at
151
+ 800px and wider, the web app's drawer below that (scrim, focus trap, Escape, focus return); the thread and
152
+ composer keep a centred 768px column; at 1024px and wider the conversation type steps from 15/22 to 17/28. New
153
+ optional `headingLevel` (web, default 2) for the empty-state title.
154
+ - **A keyboard focus ring the host page cannot remove:** drawn inline on keyboard focus in the theme's ink, so a
155
+ host `button:focus { outline: none }` reset no longer leaves chat controls without one.
156
+ - **React Native touch targets reach 44pt:** `PressScale` defaults to the consumer's 12pt hit slop; a caller's own
157
+ slop still wins.
158
+ - **Check-ins follow the consumer rule:** only the newest ask per case is live, and a re-ask after a SAME answer is
159
+ no longer locked behind the case's previous answer. `ChatCheckin.openedAt`, `WatchCase.checkinAskCount` and
160
+ `WatchCase.checkinAnswerCount` are new, optional and additive.
161
+ - **Theme:** the resolver guarantees `brandBorderStrong` reads 3:1 on every ground a control sits on, pushing a
162
+ partner brand that does not; the uploading wash and the starter chip edge now follow the partner's theme.
163
+ - The composer placeholder is the consumer apps' own `Ask me anything!`.
164
+ - Docs: brightness is light by default and `'auto'` opts in to the OS setting; the docs previously said the reverse.
165
+
166
+ ### Breaking
167
+
168
+ - `TelevetConsult` gained a REQUIRED `hasRoom` (from `meeting_url`). A host that builds a `TelevetConsult` by hand,
169
+ for example for `EverfurTelevetReschedule`'s `consult`, must now set it.
170
+ - The `TelevetScreen` and `TelevetBookingStep` unions widened (`home`, `visits`, `consult` on React Native, `call`,
171
+ `visit`; `issues` on the web booking). An exhaustive `switch` over either stops compiling until it handles them.
172
+ - `EverfurTelevet`'s default root moved from the booking to `home`: every opening reads `GET /consults` once, and
173
+ lands on the visits instead of the booking when one is ahead. Pass `initialScreen={{ name: 'booking' }}` for the
174
+ old behaviour.
175
+
176
+ ### Fixed
177
+
178
+ - The landing is held for the whole opening: Back from a visit the member cancelled, or out of a call that ended,
179
+ returns to the visits. It used to read the list again and drop the member into a new booking.
180
+ - On React Native, Android's back press during a call no longer reaches a partner's own navigator (the
181
+ `registerEverfurTelevetFlow` path), which popped the screen and hung up on the vet. Before the call runs it is
182
+ Leave, as it is inside the SDK's modal.
183
+ - A React Native visits list that fails to load still offers the booking beneath the retry, as the vet home does.
184
+ - The React Native speaker toggle asks the native module once per press; it used to ask from inside a state
185
+ updater, which StrictMode runs twice in development.
186
+ - Web a11y: a dark Join names its reason through `aria-describedby`, and the emergency primary-vet hint takes a
187
+ `useId` id, so two warnings on one page no longer share one.
188
+ - The React Native location card no longer tells the member to "Turn on location for Everfur" when the host gave
189
+ the booking no way to resolve one; the developer is told which prop is missing.
190
+ - The chat vet entries honour a registered flow in the PUBLISHED package: the registry lives on a `globalThis`
191
+ slot, so `@everfur/sdk/chat` and `@everfur/sdk/televet` (and their web twins) read one presenter instead of two
192
+ private copies.
193
+ - A dark booking plane (the partner booking routes answering 404) shows the paused state inside the app. It used to
194
+ read the entitlement 404 as "not entitled" and show "A Pro membership is needed to book a video visit." to a
195
+ member whose tenant pays, and its unavailable fallback rendered `VetVisitButton`, which re-presented the same flow
196
+ when one was registered and left the app when none was.
197
+ - The React Native lobby waits on the vet's PRESENCE, not their video track: a vet with the camera off no longer
198
+ leaves the member on "Your vet is joining", and turning the camera off mid-call no longer throws the member back
199
+ to the lobby. The self-view reads "Your camera is off" rather than the control's "Camera on".
200
+ - The route table and `MockTransport` treat the served booking routes, the join route, the pet profile and the
201
+ embed config as served.
202
+
203
+ ## [0.4.1] - 2026-09-23
204
+
205
+ ### Fixed
206
+
207
+ - Televet booking carries the five refusal screens the consumer mobile app has and this package did
208
+ not: the early-emergency interstitial, the empty clinician roster, the unentitled state, the
209
+ unserved-state action and the refused-attachment notice. The funnel matched already; the refusals
210
+ did not exist, so a partner's member who described something urgent, or whose state is not served,
211
+ saw something Everfur's own app does not show. Both platforms, with the triggers and the copy in
212
+ the shared react layer so the two cannot drift.
213
+ - The two televet booking size gates are re-measured on a clean tree, which both of their notes had asked
214
+ for: the previous lines were taken from a tree holding other lanes' uncommitted work. The web booking entry
215
+ moves 37_300 -> 42_600 (measured 40_560) and the React Native booking closure 35_600 -> 39_600 (measured
216
+ 37_694), each the measured size plus 5%. Only the booking lines moved: the visit-button entry, the call
217
+ entry, chat, records and every other closure hold their existing budgets on the same build, and the
218
+ structural checks still prove no foreign capability entered the closure.
219
+ - A televet parity guard now derives the mobile component set from the real everfur-mobile checkout
220
+ and fails by name when a screen is missing. Chat, records and the theme tokens each had such a
221
+ guard; televet did not, which is how five screens stayed absent while parity read as verified.
222
+ - `TelevetBookingFailure` is published as its real union again on both `televet/booking` and
223
+ `web/televet/booking`. It had degraded to an opaque alias (`TelevetBookingFailure_2`) with its seven
224
+ members and their per-member documentation stripped from the generated `.d.ts`, so a partner's editor
225
+ could not tell which failures exist or which of them a retry can fix. The containers now re-export the
226
+ declaration rather than aliasing it.
227
+ - Imports the five-refusal-screen change left behind are removed from the two booking containers, the two
228
+ step files and the two review steps. Nothing rendered changed: every symbol was already used at the file
229
+ the code moved into, which is why the screens themselves were unaffected.
230
+
11
231
  ## [0.4.0] - 2026-09-21
12
232
 
13
233
  ### Changed: a press of `VetVisitButton` opens the visit IN YOUR APP, not the system browser
package/README.md CHANGED
@@ -71,12 +71,13 @@ Two ways, one wire contract, documented in
71
71
 
72
72
  Chat and records are the web surfaces (records on its own subpath and its own frame document, available
73
73
  when Everfur enables records for your account); photo and video remain React Native for now. Vet visits (not yet enabled)
74
- have their own entry on both hosts, `@everfur/sdk/web/televet` and `@everfur/sdk/televet`, and the video call
75
- rendered inside your own app has an entry again beneath each, `@everfur/sdk/web/televet/call` and
76
- `@everfur/sdk/televet/call`, so a partner mounting only the visit button takes no WebRTC dependency. Booking
77
- the visit inside your own React Native app, rather than handing off to the hosted one, is a third entry,
78
- `@everfur/sdk/televet/booking`, split out for the same reason: a partner that mounts only the button never
79
- downloads a scheduler it does not render.
74
+ have their own entry on both hosts, `@everfur/sdk/web/televet` and `@everfur/sdk/televet`, and a visit opens
75
+ INSIDE your app by default: booking, the confirmation and the call run in an Everfur modal (React Native) or
76
+ dialog (web) that `VetVisitButton` and `EverfurChat` mount themselves; the hosted page is an explicit opt-in,
77
+ `prefer="redirect"`. The booking screens (`@everfur/sdk/televet/booking`, `@everfur/sdk/web/televet/booking`)
78
+ and the call (`@everfur/sdk/televet/call`, `@everfur/sdk/web/televet/call`) are their own entries, loaded on
79
+ demand, so a page where nobody opens a visit downloads neither and a page where nobody joins takes no WebRTC
80
+ dependency.
80
81
  [docs/partner-integration/16-TELEVET-VISITS.md](docs/partner-integration/16-TELEVET-VISITS.md).
81
82
 
82
83
  ## Quickstart
@@ -177,13 +178,13 @@ off-state, never a blank region.
177
178
  | Import | Contents |
178
179
  | --- | --- |
179
180
  | `@everfur/sdk` | `EverfurProvider`, `CapabilityGate`, `EverfurChat`, `useEverfurChat`, `CapabilityName`, error/result types, branded id helpers (`petRef`, `userRef`, `conversationId`) |
180
- | `@everfur/sdk/records` | `EverfurRecords`, `EverfurClinicRequest`, `EverfurClinicRequestBatch`, `SignaturePad`, records hooks + types |
181
+ | `@everfur/sdk/records` | `EverfurRecords` (the Everfur app's records flow), the named screens (`EverfurRecordsUpload`, `EverfurRecordsRequests`, `EverfurRecordsRequest`, `EverfurRecordDetail`, ...), `EverfurClinicRequest`, `EverfurClinicRequestBatch`, `SignaturePad`, records hooks + types |
181
182
  | `@everfur/sdk/records/depth`, `@everfur/sdk/web/records/depth` | record depth (the timeline, the withheld record sections, per-document contributions) on their own entries, dark until Everfur enables it per deployment; see [chapter 9](docs/partner-integration/09-GUIDE-RECORDS-AND-CONSENT.md#record-depth-behind-a-separate-switch) |
182
183
  | `@everfur/sdk/video` | gait / live-scan surface |
183
184
  | `@everfur/sdk/photo` | photo checkup surface |
184
185
  | `@everfur/sdk/animations` | server-driven pet-state media surface |
185
186
  | `@everfur/sdk/web` | the browser entry: `EverfurProvider`, `CapabilityGate`, `EverfurChat`, `useEverfurChat`, the theme hook, rendered with `react-dom`; withheld from React Native bundles the way `./server` is |
186
- | `@everfur/sdk/web/records` | records for a browser host: `EverfurRecords`, `useEverfurRecords`, `createWebRecordsUploadTransport`, `fileToHandle`; its own entry, withheld from React Native like `./web`; available when Everfur enables records for the account. Frame mode serves it with `surface: 'records'` (see [chapter 13](docs/partner-integration/13-WEB-INTEGRATION.md)) |
187
+ | `@everfur/sdk/web/records` | records for a browser host: `EverfurRecordsPage` (the Everfur web app's records page, complete on its own: request from a clinic, upload, request status, the full record with vaccinations, all inside your page), the named screens, `EverfurRecords` (the React Native-shaped flow), `useEverfurRecords`, `createWebRecordsUploadTransport`, `fileToHandle`; its own entry, withheld from React Native like `./web`; available when Everfur enables records for the account. Frame mode serves it with `surface: 'records'` (see [chapter 13](docs/partner-integration/13-WEB-INTEGRATION.md)) |
187
188
  | `@everfur/sdk/server` | **server-only** `mintPartnerSession` (no React Native resolution; never bundled on-device) |
188
189
  | `@everfur/sdk/server/events` | **server-only, Node only** partner events (preview): `constructEvent` to verify webhooks, `sendPartnerEvent`; see [chapter 15](docs/partner-integration/15-EVENTS-AND-WEBHOOKS.md) |
189
190
  | `@everfur/sdk/testing`, `@everfur/sdk/testing/rn`, `@everfur/sdk/testing/web` | test seams (`MockTransport`, `useEverfurTestEntitlements`, ...) for your own tests |
@@ -2,9 +2,9 @@ import { ReactNode } from 'react';
2
2
  import { StyleProp, ViewStyle } from 'react-native';
3
3
  import { P as PetRef, C as ConversationId } from './ids-B2GAAifq.js';
4
4
  import { F as FileHandle } from './ports-BN6RHF9W.js';
5
- import { a as ChatCheckinTarget } from './ports-D7YW8qz9.js';
6
- import { W as WidgetPet, P as PetProfileInput } from './petsRepository-Bk6GDwLs.js';
7
- import { U as UrgencyDisplayLevel, L as LifecyclePort, E as EverfurChatDraftStore } from './attachments-BrUWQYNK.js';
5
+ import { a as ChatCheckinTarget } from './ports-C0m1G1fS.js';
6
+ import { W as WidgetPet, P as PetProfileInput } from './petsRepository-DhsX3GLw.js';
7
+ import { U as UrgencyDisplayLevel, L as LifecyclePort, E as EverfurChatDraftStore } from './attachments-CzZ7in24.js';
8
8
 
9
9
  /** Where a picked image comes from: the host's photo library, or its camera. */
10
10
  type AttachmentSource = 'photo' | 'camera';
@@ -118,6 +118,20 @@ interface EverfurChatProps {
118
118
  * is available there, so it is never offered to someone who could not book.
119
119
  */
120
120
  readonly vetUsState?: string;
121
+ /**
122
+ * Where every vet entry inside chat takes the member. Defaults to `'in-app'`: your registered presenter
123
+ * (`registerEverfurTelevetFlow`), else the in-app visit Everfur provides, which this surface mounts itself.
124
+ * `'redirect'` is the explicit opt-in to the hosted Everfur visit in the browser.
125
+ */
126
+ readonly vetPrefer?: 'in-app' | 'redirect';
127
+ /**
128
+ * Your opener for a web page chat links to: today, the source page behind a card in an answer's sources
129
+ * deck (`kind` `'citation'`, always an https URL). Absent (the default), a source card is read-only: its
130
+ * title, meta line and excerpt show, and nothing takes the member out of your app. Given, the card is a link
131
+ * and a tap goes here, so you can show the page in your own in-app browser; pass
132
+ * `(url) => Linking.openURL(url)` for the Everfur app's system browser. A throw or a rejection is contained.
133
+ */
134
+ readonly onOpenUrl?: (url: string, kind: 'citation') => void | Promise<void>;
121
135
  }
122
136
  /**
123
137
  * Entitlement-gated, four-state chat surface. Entitlement-OFF renders the CapabilityGate OffState;
@@ -2,9 +2,9 @@ import { ReactNode } from 'react';
2
2
  import { StyleProp, ViewStyle } from 'react-native';
3
3
  import { P as PetRef, C as ConversationId } from './ids-B2GAAifq.cjs';
4
4
  import { F as FileHandle } from './ports-BN6RHF9W.cjs';
5
- import { a as ChatCheckinTarget } from './ports-BY2ph0_y.cjs';
6
- import { W as WidgetPet, P as PetProfileInput } from './petsRepository-B_gKbAzJ.cjs';
7
- import { U as UrgencyDisplayLevel, L as LifecyclePort, E as EverfurChatDraftStore } from './attachments-D_SECjr1.cjs';
5
+ import { a as ChatCheckinTarget } from './ports-DNXyyzZF.cjs';
6
+ import { W as WidgetPet, P as PetProfileInput } from './petsRepository-D1bnxDZg.cjs';
7
+ import { U as UrgencyDisplayLevel, L as LifecyclePort, E as EverfurChatDraftStore } from './attachments-CwsR-bPN.cjs';
8
8
 
9
9
  /** Where a picked image comes from: the host's photo library, or its camera. */
10
10
  type AttachmentSource = 'photo' | 'camera';
@@ -118,6 +118,20 @@ interface EverfurChatProps {
118
118
  * is available there, so it is never offered to someone who could not book.
119
119
  */
120
120
  readonly vetUsState?: string;
121
+ /**
122
+ * Where every vet entry inside chat takes the member. Defaults to `'in-app'`: your registered presenter
123
+ * (`registerEverfurTelevetFlow`), else the in-app visit Everfur provides, which this surface mounts itself.
124
+ * `'redirect'` is the explicit opt-in to the hosted Everfur visit in the browser.
125
+ */
126
+ readonly vetPrefer?: 'in-app' | 'redirect';
127
+ /**
128
+ * Your opener for a web page chat links to: today, the source page behind a card in an answer's sources
129
+ * deck (`kind` `'citation'`, always an https URL). Absent (the default), a source card is read-only: its
130
+ * title, meta line and excerpt show, and nothing takes the member out of your app. Given, the card is a link
131
+ * and a tap goes here, so you can show the page in your own in-app browser; pass
132
+ * `(url) => Linking.openURL(url)` for the Everfur app's system browser. A throw or a rejection is contained.
133
+ */
134
+ readonly onOpenUrl?: (url: string, kind: 'citation') => void | Promise<void>;
121
135
  }
122
136
  /**
123
137
  * Entitlement-gated, four-state chat surface. Entitlement-OFF renders the CapabilityGate OffState;
@@ -1,5 +1,5 @@
1
1
  import { CSSProperties, ReactNode } from 'react';
2
- import { f as RecordsScreenBaseProps } from './useRecordsDepth-crhBllQK.js';
2
+ import { f as RecordsScreenBaseProps } from './useRecordsDepth--ObtMyjH.js';
3
3
 
4
4
  interface EverfurRecordsDepthProps extends Pick<RecordsScreenBaseProps, 'petRef' | 'petName' | 'onNavigate' | 'onBack'> {
5
5
  readonly style?: CSSProperties;
@@ -1,6 +1,6 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { StyleProp, ViewStyle } from 'react-native';
3
- import { f as RecordsScreenBaseProps } from './useRecordsDepth-C6rjEaLn.cjs';
3
+ import { f as RecordsScreenBaseProps } from './useRecordsDepth-B35y8bV-.cjs';
4
4
 
5
5
  interface EverfurRecordsDepthProps extends Pick<RecordsScreenBaseProps, 'petRef' | 'petName' | 'onNavigate' | 'onBack'> {
6
6
  readonly style?: StyleProp<ViewStyle>;
@@ -1,5 +1,5 @@
1
1
  import { CSSProperties, ReactNode } from 'react';
2
- import { f as RecordsScreenBaseProps } from './useRecordsDepth-C6rjEaLn.cjs';
2
+ import { f as RecordsScreenBaseProps } from './useRecordsDepth-B35y8bV-.cjs';
3
3
 
4
4
  interface EverfurRecordsDepthProps extends Pick<RecordsScreenBaseProps, 'petRef' | 'petName' | 'onNavigate' | 'onBack'> {
5
5
  readonly style?: CSSProperties;
@@ -1,6 +1,6 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { StyleProp, ViewStyle } from 'react-native';
3
- import { f as RecordsScreenBaseProps } from './useRecordsDepth-crhBllQK.js';
3
+ import { f as RecordsScreenBaseProps } from './useRecordsDepth--ObtMyjH.js';
4
4
 
5
5
  interface EverfurRecordsDepthProps extends Pick<RecordsScreenBaseProps, 'petRef' | 'petName' | 'onNavigate' | 'onBack'> {
6
6
  readonly style?: StyleProp<ViewStyle>;
@@ -1,4 +1,4 @@
1
- import { b as EverfurErrorCode, E as EverfurError } from './EverfurResult-DN9pL2Ab.js';
1
+ import { b as EverfurErrorCode, E as EverfurError } from './EverfurError-DmELDpXp.js';
2
2
 
3
3
  /**
4
4
  * Recovery policy. A host may narrow retry ceilings (e.g. a metered plan) but can never widen the SDK's
@@ -1,4 +1,4 @@
1
- import { b as EverfurErrorCode, E as EverfurError } from './EverfurResult-DN9pL2Ab.cjs';
1
+ import { b as EverfurErrorCode, E as EverfurError } from './EverfurError-DmELDpXp.cjs';
2
2
 
3
3
  /**
4
4
  * Recovery policy. A host may narrow retry ceilings (e.g. a metered plan) but can never widen the SDK's
@@ -172,70 +172,4 @@ interface MakeEverfurErrorOptions {
172
172
  }
173
173
  declare function makeEverfurError(code: EverfurErrorCode, opts?: MakeEverfurErrorOptions): EverfurError;
174
174
 
175
- /**
176
- * The settle type. An async public operation returns this instead of throwing for an EXPECTED failure.
177
- * A successful result may carry a non-fatal `warning` (e.g. served-stale, degraded path).
178
- */
179
- type EverfurResult<T> = {
180
- readonly ok: true;
181
- readonly value: T;
182
- readonly warning?: EverfurError;
183
- } | {
184
- readonly ok: false;
185
- readonly error: EverfurError;
186
- };
187
- /** Construct a success result. Frozen, public state is immutable end to end. */
188
- declare function ok<T>(value: T, warning?: EverfurError): EverfurResult<T>;
189
- /** Construct a failure result. Frozen. */
190
- declare function err<T = never>(error: EverfurError): EverfurResult<T>;
191
- /** Narrowing guard: true iff the result is a success. */
192
- declare function isOk<T>(r: EverfurResult<T>): r is {
193
- readonly ok: true;
194
- readonly value: T;
195
- readonly warning?: EverfurError;
196
- };
197
- /** Narrowing guard: true iff the result is a failure. */
198
- declare function isErr<T>(r: EverfurResult<T>): r is {
199
- readonly ok: false;
200
- readonly error: EverfurError;
201
- };
202
- /**
203
- * The real `Error` subclass `unwrap` throws, so an imperative call site that lets the throw escape
204
- * produces a proper Error rather than a bare object (which a crash reporter files as
205
- * "Non-Error exception captured", with no stack and no grouping).
206
- *
207
- * `message` is built from the normalized `code` and the frozen, product-owned `displayMessage` ONLY.
208
- * The untrusted `wireMessage` is deliberately NOT in it: `message` is the one field every telemetry
209
- * vendor captures and indexes by default, so putting wire text there would make an untrusted,
210
- * healthcare-adjacent string flow automatically into a partner's third-party tooling. The full
211
- * `EverfurError` hangs off `.error`, where `wireMessage` and `raw` remain non-enumerable.
212
- */
213
- declare class EverfurThrownError extends Error {
214
- /** The settled error this was thrown from. Its `wireMessage` / `raw` stay non-enumerable. */
215
- readonly error: EverfurError;
216
- /** Mirror of `error.code`, so a catch block can branch without reaching through `.error`. */
217
- readonly code: EverfurError['code'];
218
- /** Mirror of `error.category`, the coarse branching axis. */
219
- readonly category: EverfurError['category'];
220
- constructor(error: EverfurError);
221
- }
222
- /**
223
- * Escape hatch for imperative callers: return the value or throw. The throw is an `EverfurThrownError`
224
- * (a real `Error`, safe message); the settled `EverfurError` is on its `.error`.
225
- * Prefer pattern-matching on `ok`; `unwrap` exists for call sites that want the throw.
226
- */
227
- declare function unwrap<T>(r: EverfurResult<T>): T;
228
- /**
229
- * Thrown SYNCHRONOUSLY for programmer error ONLY, never for a network or domain failure.
230
- * Mirrors Flutter `_requireInitialized` (a real guard, not an assert).
231
- *
232
- * - `not-initialized` , a capability used before EverfurProvider mounted / init ran.
233
- * - `invalid-argument` , a malformed id or option shape (e.g. a non-UUID conversation id).
234
- * - `missing-peer-dependency`, a capability subpath used without its required native peer dep.
235
- */
236
- declare class EverfurConfigError extends Error {
237
- readonly kind: 'not-initialized' | 'invalid-argument' | 'missing-peer-dependency';
238
- constructor(kind: 'not-initialized' | 'invalid-argument' | 'missing-peer-dependency', message: string);
239
- }
240
-
241
- export { AUTO_RETRYABLE_CODES as A, BACKOFF_BASE_MS as B, type EverfurError as E, MAX_RETRY_ATTEMPTS as M, RETRYABLE_CONTRACT_CODES as R, type EverfurErrorCategory as a, type EverfurErrorCode as b, type EverfurResult as c, EverfurConfigError as d, EverfurThrownError as e, categoryFor as f, isOk as g, isRetryableCode as h, isErr as i, userFacingError as j, BACKOFF_CAP_MS as k, EVERFUR_ERROR_CATEGORIES as l, EVERFUR_ERROR_CODES as m, type MakeEverfurErrorOptions as n, backoffDelayMs as o, canRecreateOnNotFound as p, err as q, fromHttpStatus as r, fromWire as s, isAutoRetryable as t, unwrap as u, makeEverfurError as v, ok as w, shouldRetry as x };
175
+ export { AUTO_RETRYABLE_CODES as A, BACKOFF_BASE_MS as B, type EverfurError as E, MAX_RETRY_ATTEMPTS as M, RETRYABLE_CONTRACT_CODES as R, type EverfurErrorCategory as a, type EverfurErrorCode as b, categoryFor as c, BACKOFF_CAP_MS as d, EVERFUR_ERROR_CATEGORIES as e, EVERFUR_ERROR_CODES as f, type MakeEverfurErrorOptions as g, backoffDelayMs as h, isRetryableCode as i, canRecreateOnNotFound as j, fromHttpStatus as k, fromWire as l, isAutoRetryable as m, makeEverfurError as n, shouldRetry as s, userFacingError as u };
@@ -172,70 +172,4 @@ interface MakeEverfurErrorOptions {
172
172
  }
173
173
  declare function makeEverfurError(code: EverfurErrorCode, opts?: MakeEverfurErrorOptions): EverfurError;
174
174
 
175
- /**
176
- * The settle type. An async public operation returns this instead of throwing for an EXPECTED failure.
177
- * A successful result may carry a non-fatal `warning` (e.g. served-stale, degraded path).
178
- */
179
- type EverfurResult<T> = {
180
- readonly ok: true;
181
- readonly value: T;
182
- readonly warning?: EverfurError;
183
- } | {
184
- readonly ok: false;
185
- readonly error: EverfurError;
186
- };
187
- /** Construct a success result. Frozen, public state is immutable end to end. */
188
- declare function ok<T>(value: T, warning?: EverfurError): EverfurResult<T>;
189
- /** Construct a failure result. Frozen. */
190
- declare function err<T = never>(error: EverfurError): EverfurResult<T>;
191
- /** Narrowing guard: true iff the result is a success. */
192
- declare function isOk<T>(r: EverfurResult<T>): r is {
193
- readonly ok: true;
194
- readonly value: T;
195
- readonly warning?: EverfurError;
196
- };
197
- /** Narrowing guard: true iff the result is a failure. */
198
- declare function isErr<T>(r: EverfurResult<T>): r is {
199
- readonly ok: false;
200
- readonly error: EverfurError;
201
- };
202
- /**
203
- * The real `Error` subclass `unwrap` throws, so an imperative call site that lets the throw escape
204
- * produces a proper Error rather than a bare object (which a crash reporter files as
205
- * "Non-Error exception captured", with no stack and no grouping).
206
- *
207
- * `message` is built from the normalized `code` and the frozen, product-owned `displayMessage` ONLY.
208
- * The untrusted `wireMessage` is deliberately NOT in it: `message` is the one field every telemetry
209
- * vendor captures and indexes by default, so putting wire text there would make an untrusted,
210
- * healthcare-adjacent string flow automatically into a partner's third-party tooling. The full
211
- * `EverfurError` hangs off `.error`, where `wireMessage` and `raw` remain non-enumerable.
212
- */
213
- declare class EverfurThrownError extends Error {
214
- /** The settled error this was thrown from. Its `wireMessage` / `raw` stay non-enumerable. */
215
- readonly error: EverfurError;
216
- /** Mirror of `error.code`, so a catch block can branch without reaching through `.error`. */
217
- readonly code: EverfurError['code'];
218
- /** Mirror of `error.category`, the coarse branching axis. */
219
- readonly category: EverfurError['category'];
220
- constructor(error: EverfurError);
221
- }
222
- /**
223
- * Escape hatch for imperative callers: return the value or throw. The throw is an `EverfurThrownError`
224
- * (a real `Error`, safe message); the settled `EverfurError` is on its `.error`.
225
- * Prefer pattern-matching on `ok`; `unwrap` exists for call sites that want the throw.
226
- */
227
- declare function unwrap<T>(r: EverfurResult<T>): T;
228
- /**
229
- * Thrown SYNCHRONOUSLY for programmer error ONLY, never for a network or domain failure.
230
- * Mirrors Flutter `_requireInitialized` (a real guard, not an assert).
231
- *
232
- * - `not-initialized` , a capability used before EverfurProvider mounted / init ran.
233
- * - `invalid-argument` , a malformed id or option shape (e.g. a non-UUID conversation id).
234
- * - `missing-peer-dependency`, a capability subpath used without its required native peer dep.
235
- */
236
- declare class EverfurConfigError extends Error {
237
- readonly kind: 'not-initialized' | 'invalid-argument' | 'missing-peer-dependency';
238
- constructor(kind: 'not-initialized' | 'invalid-argument' | 'missing-peer-dependency', message: string);
239
- }
240
-
241
- export { AUTO_RETRYABLE_CODES as A, BACKOFF_BASE_MS as B, type EverfurError as E, MAX_RETRY_ATTEMPTS as M, RETRYABLE_CONTRACT_CODES as R, type EverfurErrorCategory as a, type EverfurErrorCode as b, type EverfurResult as c, EverfurConfigError as d, EverfurThrownError as e, categoryFor as f, isOk as g, isRetryableCode as h, isErr as i, userFacingError as j, BACKOFF_CAP_MS as k, EVERFUR_ERROR_CATEGORIES as l, EVERFUR_ERROR_CODES as m, type MakeEverfurErrorOptions as n, backoffDelayMs as o, canRecreateOnNotFound as p, err as q, fromHttpStatus as r, fromWire as s, isAutoRetryable as t, unwrap as u, makeEverfurError as v, ok as w, shouldRetry as x };
175
+ export { AUTO_RETRYABLE_CODES as A, BACKOFF_BASE_MS as B, type EverfurError as E, MAX_RETRY_ATTEMPTS as M, RETRYABLE_CONTRACT_CODES as R, type EverfurErrorCategory as a, type EverfurErrorCode as b, categoryFor as c, BACKOFF_CAP_MS as d, EVERFUR_ERROR_CATEGORIES as e, EVERFUR_ERROR_CODES as f, type MakeEverfurErrorOptions as g, backoffDelayMs as h, isRetryableCode as i, canRecreateOnNotFound as j, fromHttpStatus as k, fromWire as l, isAutoRetryable as m, makeEverfurError as n, shouldRetry as s, userFacingError as u };
@@ -0,0 +1,69 @@
1
+ import { E as EverfurError } from './EverfurError-DmELDpXp.js';
2
+
3
+ /**
4
+ * The settle type. An async public operation returns this instead of throwing for an EXPECTED failure.
5
+ * A successful result may carry a non-fatal `warning` (e.g. served-stale, degraded path).
6
+ */
7
+ type EverfurResult<T> = {
8
+ readonly ok: true;
9
+ readonly value: T;
10
+ readonly warning?: EverfurError;
11
+ } | {
12
+ readonly ok: false;
13
+ readonly error: EverfurError;
14
+ };
15
+ /** Construct a success result. Frozen, public state is immutable end to end. */
16
+ declare function ok<T>(value: T, warning?: EverfurError): EverfurResult<T>;
17
+ /** Construct a failure result. Frozen. */
18
+ declare function err<T = never>(error: EverfurError): EverfurResult<T>;
19
+ /** Narrowing guard: true iff the result is a success. */
20
+ declare function isOk<T>(r: EverfurResult<T>): r is {
21
+ readonly ok: true;
22
+ readonly value: T;
23
+ readonly warning?: EverfurError;
24
+ };
25
+ /** Narrowing guard: true iff the result is a failure. */
26
+ declare function isErr<T>(r: EverfurResult<T>): r is {
27
+ readonly ok: false;
28
+ readonly error: EverfurError;
29
+ };
30
+ /**
31
+ * The real `Error` subclass `unwrap` throws, so an imperative call site that lets the throw escape
32
+ * produces a proper Error rather than a bare object (which a crash reporter files as
33
+ * "Non-Error exception captured", with no stack and no grouping).
34
+ *
35
+ * `message` is built from the normalized `code` and the frozen, product-owned `displayMessage` ONLY.
36
+ * The untrusted `wireMessage` is deliberately NOT in it: `message` is the one field every telemetry
37
+ * vendor captures and indexes by default, so putting wire text there would make an untrusted,
38
+ * healthcare-adjacent string flow automatically into a partner's third-party tooling. The full
39
+ * `EverfurError` hangs off `.error`, where `wireMessage` and `raw` remain non-enumerable.
40
+ */
41
+ declare class EverfurThrownError extends Error {
42
+ /** The settled error this was thrown from. Its `wireMessage` / `raw` stay non-enumerable. */
43
+ readonly error: EverfurError;
44
+ /** Mirror of `error.code`, so a catch block can branch without reaching through `.error`. */
45
+ readonly code: EverfurError['code'];
46
+ /** Mirror of `error.category`, the coarse branching axis. */
47
+ readonly category: EverfurError['category'];
48
+ constructor(error: EverfurError);
49
+ }
50
+ /**
51
+ * Escape hatch for imperative callers: return the value or throw. The throw is an `EverfurThrownError`
52
+ * (a real `Error`, safe message); the settled `EverfurError` is on its `.error`.
53
+ * Prefer pattern-matching on `ok`; `unwrap` exists for call sites that want the throw.
54
+ */
55
+ declare function unwrap<T>(r: EverfurResult<T>): T;
56
+ /**
57
+ * Thrown SYNCHRONOUSLY for programmer error ONLY, never for a network or domain failure.
58
+ * Mirrors Flutter `_requireInitialized` (a real guard, not an assert).
59
+ *
60
+ * - `not-initialized` , a capability used before EverfurProvider mounted / init ran.
61
+ * - `invalid-argument` , a malformed id or option shape (e.g. a non-UUID conversation id).
62
+ * - `missing-peer-dependency`, a capability subpath used without its required native peer dep.
63
+ */
64
+ declare class EverfurConfigError extends Error {
65
+ readonly kind: 'not-initialized' | 'invalid-argument' | 'missing-peer-dependency';
66
+ constructor(kind: 'not-initialized' | 'invalid-argument' | 'missing-peer-dependency', message: string);
67
+ }
68
+
69
+ export { type EverfurResult as E, EverfurConfigError as a, EverfurThrownError as b, isOk as c, err as e, isErr as i, ok as o, unwrap as u };