@everfur/sdk 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/CHANGELOG.md +648 -1
  2. package/README.md +58 -23
  3. package/consent/package.json +8 -0
  4. package/dist/Chat-DPUD6dnc.d.cts +128 -0
  5. package/dist/Chat-DwAC2vhB.d.ts +128 -0
  6. package/dist/DepthViews-DNEM96Se.d.ts +16 -0
  7. package/dist/DepthViews-DP0R-DhB.d.cts +19 -0
  8. package/dist/DepthViews-D_3hl4xk.d.ts +19 -0
  9. package/dist/DepthViews-DbFhR4Du.d.cts +16 -0
  10. package/dist/ErrorPolicyPort-CNf4uQZP.d.cts +22 -0
  11. package/dist/ErrorPolicyPort-CwbfmxzJ.d.ts +22 -0
  12. package/dist/{EverfurResult-D92-uL82.d.cts → EverfurResult-DN9pL2Ab.d.cts} +11 -10
  13. package/dist/{EverfurResult-D92-uL82.d.ts → EverfurResult-DN9pL2Ab.d.ts} +11 -10
  14. package/dist/{PhotoController-BItt5M7u.d.cts → PhotoController-3l7MT9jA.d.cts} +1 -1
  15. package/dist/{PhotoController-D8zMTdcW.d.ts → PhotoController-vzY5bfY_.d.ts} +1 -1
  16. package/dist/animations/index.cjs +1 -1997
  17. package/dist/animations/index.d.cts +35 -35
  18. package/dist/animations/index.d.ts +35 -35
  19. package/dist/animations/index.js +1 -1972
  20. package/dist/attachments-5NeobOCd.d.ts +256 -0
  21. package/dist/attachments-Bw3iMQgu.d.ts +146 -0
  22. package/dist/attachments-CQgFrEQ7.d.cts +146 -0
  23. package/dist/attachments-D8T5re7e.d.cts +256 -0
  24. package/dist/casesRepository-ClLv6qMl.d.ts +188 -0
  25. package/dist/casesRepository-DHwtGRYY.d.cts +188 -0
  26. package/dist/chat/index.cjs +1 -1170
  27. package/dist/chat/index.d.cts +31 -53
  28. package/dist/chat/index.d.ts +31 -53
  29. package/dist/chat/index.js +1 -1167
  30. package/dist/client/index.cjs +9 -2315
  31. package/dist/client/index.d.cts +77 -15
  32. package/dist/client/index.d.ts +77 -15
  33. package/dist/client/index.js +9 -2215
  34. package/dist/{config-CiJ0PVBB.d.ts → config-CzTZGlfF.d.cts} +63 -25
  35. package/dist/{config-BSjBdxrZ.d.cts → config-DW60uRb9.d.ts} +63 -25
  36. package/dist/consent/index.cjs +1 -0
  37. package/dist/consent/index.d.cts +33 -0
  38. package/dist/consent/index.d.ts +33 -0
  39. package/dist/consent/index.js +1 -0
  40. package/dist/context-DXhqHlPU.d.ts +159 -0
  41. package/dist/context-XvTzq1tE.d.cts +159 -0
  42. package/dist/copy-Mjoo91aS.d.ts +198 -0
  43. package/dist/copy-bKDNigLb.d.cts +198 -0
  44. package/dist/core/index.cjs +13 -3175
  45. package/dist/core/index.d.cts +58 -12
  46. package/dist/core/index.d.ts +58 -12
  47. package/dist/core/index.js +13 -3163
  48. package/dist/depth-CErXCU8J.d.cts +502 -0
  49. package/dist/depth-DjDcJ6kH.d.ts +502 -0
  50. package/dist/entitlementRepository-DKdXFgTo.d.cts +698 -0
  51. package/dist/entitlementRepository-DSbzuyAW.d.ts +698 -0
  52. package/dist/{identity-DK9zORrG.d.ts → identity-BMx2SUOM.d.ts} +19 -6
  53. package/dist/{identity-Brl-lDd6.d.cts → identity-DI4eVx9S.d.cts} +19 -6
  54. package/dist/{ids-CJ1S6adf.d.cts → ids-B2GAAifq.d.cts} +1 -1
  55. package/dist/{ids-CJ1S6adf.d.ts → ids-B2GAAifq.d.ts} +1 -1
  56. package/dist/index.cjs +12 -4488
  57. package/dist/index.d.cts +29 -121
  58. package/dist/index.d.ts +29 -121
  59. package/dist/index.js +12 -4464
  60. package/dist/models-B-Uh2LTf.d.ts +214 -0
  61. package/dist/models-D2EUxPZY.d.cts +214 -0
  62. package/dist/notifications/index.cjs +2 -0
  63. package/dist/notifications/index.d.cts +17 -0
  64. package/dist/notifications/index.d.ts +17 -0
  65. package/dist/notifications/index.js +2 -0
  66. package/dist/pets-CtQdRpWo.d.ts +92 -0
  67. package/dist/pets-aB8q0JyX.d.cts +92 -0
  68. package/dist/photo/index.cjs +1 -2189
  69. package/dist/photo/index.d.cts +6 -6
  70. package/dist/photo/index.d.ts +6 -6
  71. package/dist/photo/index.js +1 -2186
  72. package/dist/ports-BN6RHF9W.d.cts +48 -0
  73. package/dist/ports-BN6RHF9W.d.ts +48 -0
  74. package/dist/ports-DEBzEhbp.d.cts +386 -0
  75. package/dist/ports-DMolTRzU.d.ts +386 -0
  76. package/dist/profile-CSs1wlXT.d.cts +93 -0
  77. package/dist/profile-CSs1wlXT.d.ts +93 -0
  78. package/dist/records/depth/index.cjs +2 -0
  79. package/dist/records/depth/index.d.cts +13 -0
  80. package/dist/records/depth/index.d.ts +13 -0
  81. package/dist/records/depth/index.js +2 -0
  82. package/dist/records/index.cjs +3 -2839
  83. package/dist/records/index.d.cts +137 -203
  84. package/dist/records/index.d.ts +137 -203
  85. package/dist/records/index.js +3 -2833
  86. package/dist/requestFunnel-CjW7uDuA.d.ts +87 -0
  87. package/dist/requestFunnel-L-BQfi0z.d.cts +87 -0
  88. package/dist/{resolve-Dq_4_agU.d.ts → resolve-D4Ywz5OS.d.cts} +10 -4
  89. package/dist/{resolve-Dq_4_agU.d.cts → resolve-D4Ywz5OS.d.ts} +10 -4
  90. package/dist/{runtime-BgQnA594.d.cts → runtime-B8s-_hv8.d.cts} +134 -59
  91. package/dist/{runtime-CBA-LvdM.d.ts → runtime-BR9ysG0J.d.ts} +134 -59
  92. package/dist/server/events/index.cjs +2 -0
  93. package/dist/server/events/index.d.cts +550 -0
  94. package/dist/server/events/index.d.ts +550 -0
  95. package/dist/server/events/index.js +2 -0
  96. package/dist/server/index.cjs +2 -533
  97. package/dist/server/index.d.cts +73 -18
  98. package/dist/server/index.d.ts +73 -18
  99. package/dist/server/index.js +2 -530
  100. package/dist/species-BXAIMh7I.d.cts +9 -0
  101. package/dist/species-BXAIMh7I.d.ts +9 -0
  102. package/dist/televet/index.cjs +1 -0
  103. package/dist/televet/index.d.cts +60 -0
  104. package/dist/televet/index.d.ts +60 -0
  105. package/dist/televet/index.js +1 -0
  106. package/dist/testing/index.cjs +5 -823
  107. package/dist/testing/index.d.cts +17 -3
  108. package/dist/testing/index.d.ts +17 -3
  109. package/dist/testing/index.js +5 -820
  110. package/dist/testing/rn/index.cjs +1 -449
  111. package/dist/testing/rn/index.d.cts +17 -29
  112. package/dist/testing/rn/index.d.ts +17 -29
  113. package/dist/testing/rn/index.js +1 -444
  114. package/dist/testing/web/index.cjs +1 -0
  115. package/dist/testing/web/index.d.cts +131 -0
  116. package/dist/testing/web/index.d.ts +131 -0
  117. package/dist/testing/web/index.js +1 -0
  118. package/dist/timelineRows-CaohZzXS.d.cts +19 -0
  119. package/dist/timelineRows-DZed6dAM.d.ts +19 -0
  120. package/dist/typeStyle-0TydiZ1w.d.cts +19 -0
  121. package/dist/typeStyle-CWMsoe6b.d.ts +19 -0
  122. package/dist/uploadTransport-D0M0T4hN.d.ts +38 -0
  123. package/dist/uploadTransport-DKJHs3Yj.d.cts +38 -0
  124. package/dist/useRecordsDepth-BHBzJ76R.d.cts +237 -0
  125. package/dist/useRecordsDepth-BU-OhzH6.d.ts +237 -0
  126. package/dist/useVetVisit-Bc84hWUU.d.cts +187 -0
  127. package/dist/useVetVisit-CjmMa896.d.ts +187 -0
  128. package/dist/video/index.cjs +1 -1941
  129. package/dist/video/index.d.cts +4 -4
  130. package/dist/video/index.d.ts +4 -4
  131. package/dist/video/index.js +1 -1938
  132. package/dist/view-C3qPIXGX.d.cts +310 -0
  133. package/dist/view-DtSPYpKa.d.ts +310 -0
  134. package/dist/visitIntent-D7_yVp1I.d.cts +8 -0
  135. package/dist/visitIntent-D7_yVp1I.d.ts +8 -0
  136. package/dist/web/consent/index.cjs +1 -0
  137. package/dist/web/consent/index.d.cts +34 -0
  138. package/dist/web/consent/index.d.ts +34 -0
  139. package/dist/web/consent/index.js +1 -0
  140. package/dist/web/index.cjs +14 -0
  141. package/dist/web/index.d.cts +217 -0
  142. package/dist/web/index.d.ts +217 -0
  143. package/dist/web/index.js +14 -0
  144. package/dist/web/notifications/index.cjs +2 -0
  145. package/dist/web/notifications/index.d.cts +213 -0
  146. package/dist/web/notifications/index.d.ts +213 -0
  147. package/dist/web/notifications/index.js +2 -0
  148. package/dist/web/records/depth/index.cjs +2 -0
  149. package/dist/web/records/depth/index.d.cts +12 -0
  150. package/dist/web/records/depth/index.d.ts +12 -0
  151. package/dist/web/records/depth/index.js +2 -0
  152. package/dist/web/records/index.cjs +4 -0
  153. package/dist/web/records/index.d.cts +194 -0
  154. package/dist/web/records/index.d.ts +194 -0
  155. package/dist/web/records/index.js +4 -0
  156. package/dist/web/televet/index.cjs +1 -0
  157. package/dist/web/televet/index.d.cts +50 -0
  158. package/dist/web/televet/index.d.ts +50 -0
  159. package/dist/web/televet/index.js +1 -0
  160. package/notifications/package.json +8 -0
  161. package/package.json +197 -9
  162. package/records/depth/package.json +8 -0
  163. package/server/events/device-blocked.cjs +15 -0
  164. package/server/events/package.json +9 -0
  165. package/televet/package.json +8 -0
  166. package/testing/web/native-blocked.cjs +12 -0
  167. package/testing/web/package.json +8 -0
  168. package/web/consent/native-blocked.cjs +12 -0
  169. package/web/consent/package.json +8 -0
  170. package/web/native-blocked.cjs +12 -0
  171. package/web/notifications/native-blocked.cjs +12 -0
  172. package/web/notifications/package.json +8 -0
  173. package/web/package.json +8 -0
  174. package/web/records/depth/native-blocked.cjs +12 -0
  175. package/web/records/depth/package.json +8 -0
  176. package/web/records/native-blocked.cjs +12 -0
  177. package/web/records/package.json +8 -0
  178. package/web/televet/native-blocked.cjs +12 -0
  179. package/web/televet/package.json +8 -0
  180. package/dist/ChatController-CKdBvPj2.d.ts +0 -146
  181. package/dist/ChatController-CpUMvvZf.d.cts +0 -146
  182. package/dist/FilePort-BabWrv7I.d.cts +0 -22
  183. package/dist/FilePort-BabWrv7I.d.ts +0 -22
  184. package/dist/petsRepository-BEGb97M9.d.cts +0 -326
  185. package/dist/petsRepository-Bu18r2kK.d.ts +0 -326
  186. package/dist/requestFunnel-DuUH-kAe.d.cts +0 -28
  187. package/dist/requestFunnel-dio5OmR9.d.ts +0 -28
@@ -0,0 +1,214 @@
1
+ import { E as EverfurError } from './EverfurResult-DN9pL2Ab.js';
2
+ import { R as RecordsRequestId, P as PetRef, D as DocumentId } from './ids-B2GAAifq.js';
3
+
4
+ /**
5
+ * The partner-scoped lifecycle, including clinic requests. The server's canonical simple status takes
6
+ * precedence when supplied; upload and review states retain their action-specific distinctions.
7
+ */
8
+ type RecordsRequestStatus = 'requested' | 'awaiting_clinic' | 'awaiting_upload' | 'received' | 'parsing' | 'in_review' | 'published' | 'failed' | 'revoked';
9
+ /** The backend's seven-state records lifecycle. Unknown future states are not guessed. */
10
+ type RecordsSimpleStatus = Exclude<RecordsRequestStatus, 'awaiting_upload' | 'in_review'>;
11
+ /** Terminal statuses: polling stops here. */
12
+ declare const RECORDS_TERMINAL: readonly RecordsRequestStatus[];
13
+ declare function isTerminalStatus(status: RecordsRequestStatus): boolean;
14
+ interface RecordsRequestView {
15
+ readonly id: RecordsRequestId;
16
+ readonly petRef: PetRef;
17
+ readonly status: RecordsRequestStatus;
18
+ readonly simpleStatus?: RecordsSimpleStatus | null;
19
+ /** Backend-authored machine detail; never used as user-facing copy. */
20
+ readonly simpleStatusDetail?: string | null;
21
+ /** BE-authored copy, rendered verbatim (dumb-renderer rule). */
22
+ readonly statusLabel: string;
23
+ /** Server-authorized actions; absent on older deployments means unavailable. */
24
+ readonly canRetrySend?: boolean;
25
+ readonly canUpdateClinicEmail?: boolean;
26
+ readonly canRevoke?: boolean;
27
+ readonly canConvertToUpload?: boolean;
28
+ readonly dispatchStatus?: string | null;
29
+ readonly reminderCount?: number;
30
+ readonly lastReminderAt?: string | null;
31
+ /** Existing backend-owned follow-up expectations, never reconstructed from raw statuses. */
32
+ readonly waitingExpectation?: string | null;
33
+ /**
34
+ * DEAD, measured 2026-08-22: no plane sends it and nothing in this SDK reads it. The widget
35
+ * `RecordsRequestResponse` omits it, the consumer `RecordsRequestSummary` has no such field either, and a
36
+ * grep of `src/` finds zero render consumers - so it is always the mapper's `0` default.
37
+ *
38
+ * Deliberately NOT deleted here: removing a non-optional public field is a breaking change that needs a
39
+ * major bump, which is a release decision. Documented so nobody reads a count off it.
40
+ */
41
+ readonly documentCount: number;
42
+ /** facts extracted but awaiting review (badge "N being reviewed"). */
43
+ readonly heldItemCount: number;
44
+ /** ISO; null before first upload. */
45
+ readonly receivedAt: string | null;
46
+ /** drives the timeline "reading your records" step. */
47
+ readonly parsingStartedAt: string | null;
48
+ /** non-null == a parse gap occurred (§5, honest, not silent). */
49
+ readonly reviewStartedAt: string | null;
50
+ readonly createdAt: string;
51
+ readonly updatedAt: string;
52
+ /**
53
+ * The server's own owner-facing status vocabulary (EFBackend `records_schemas.RecordsRequestStatus`:
54
+ * `submitted`, `sent`, `awaiting_response`, `awaiting_upload`, `clinic_responded_no_records`,
55
+ * `records_received`, `parsing`, `in_review`, `published`, `failed`, `revoked`, `clinic_declined`), kept
56
+ * beside the folded `status` because the step rail (`buildRequestTimeline`) is the consumer app's and reads
57
+ * that vocabulary. STRUCTURAL ONLY: never rendered as copy. Absent on a hand-built view.
58
+ */
59
+ readonly wireStatus?: string;
60
+ /** `clinic_request` or `owner_provided`; null when the wire did not say. */
61
+ readonly source?: string | null;
62
+ /** The consumer app's action-first sentence for a state that needs the member, BE-authored; null otherwise. */
63
+ readonly actionNeededLabel?: string | null;
64
+ /** BE-authored failure sentence for a failed request, rendered verbatim; null otherwise. */
65
+ readonly failureReason?: string | null;
66
+ /** The machine failure code (`no_response`, `hard_bounce`, `dispatch_failed`, `parse_timeout`, `parse_error`). */
67
+ readonly failureCode?: string | null;
68
+ readonly recoveryStage?: string | null;
69
+ /** True only when the server gates the tap-to-call affordance on for this request. */
70
+ readonly showClinicPhone?: boolean;
71
+ /** The clinic the request went to (directory name or the owner's free text); null for an owner upload. */
72
+ readonly clinicName?: string | null;
73
+ readonly clinicEmail?: string | null;
74
+ /** The clinic's verified phone, present only with `showClinicPhone`. */
75
+ readonly clinicPhone?: string | null;
76
+ /** ISO; set once the owner switched this clinic request to uploading their own records. */
77
+ readonly convertedToUploadAt?: string | null;
78
+ /** The multi-clinic group this request belongs to, or null. */
79
+ readonly requestGroupId?: string | null;
80
+ }
81
+ /** `GET /widget/v1/records/request-groups/{id}`: one pet's multi-clinic batch, with the BE-derived counts. */
82
+ interface RecordsRequestGroupView {
83
+ readonly requestGroupId: string;
84
+ readonly petRef: PetRef;
85
+ /** How many clinics the batch created requests for. */
86
+ readonly total: number;
87
+ /** How many of them the clinic has answered (records, a decline, a reply without records). */
88
+ readonly responded: number;
89
+ /** How many are still waiting on the clinic. */
90
+ readonly pending: number;
91
+ /** One request per clinic, in the server's order. */
92
+ readonly members: readonly RecordsRequestView[];
93
+ }
94
+ interface UploadedDocument {
95
+ readonly documentId: DocumentId;
96
+ readonly requestId: RecordsRequestId;
97
+ /** uploads NEVER auto-bind / auto-publish. */
98
+ readonly status: 'received';
99
+ }
100
+ /** One redacted identity row (name / species / breed / owner-safe field). Provenance absent. */
101
+ interface RecordIdentityField {
102
+ readonly label: string;
103
+ readonly value: string;
104
+ }
105
+ /**
106
+ * Who produced a reading. `owner_reported` is owner-entered (a home scale, typed into the pet profile);
107
+ * `clinic_document` is extracted from a vet document. The two now share one series, so a clinician reading a
108
+ * weight can tell them apart before dosing from it.
109
+ *
110
+ * A value this build does not know folds to `null` (unlabelled), never to a guess - see `normalizeOrigin`.
111
+ * `null` therefore means "the backend did not say", NOT "clinic".
112
+ */
113
+ type RecordOrigin = 'owner_reported' | 'clinic_document';
114
+ /**
115
+ * One extracted clinical fact. No `raw_value` / `source_span` / `source_bbox` / `source_page` /
116
+ * `source_doc_id` / `value_source` / `extraction_method` / `source_precedence` members - `origin` is the only
117
+ * provenance-adjacent field, and it is a display label (see `RecordOrigin`).
118
+ */
119
+ interface RecordEntity {
120
+ readonly key: string;
121
+ readonly category: string;
122
+ readonly label: string;
123
+ readonly value: string | null;
124
+ readonly unit: string | null;
125
+ readonly observedAt: string | null;
126
+ readonly status: string | null;
127
+ /** Who measured it. `null` when the backend did not label it (an older backend never does). */
128
+ readonly origin: RecordOrigin | null;
129
+ /**
130
+ * The server's stable fact key (`canonical_key`), the identity an owner correction or removal is keyed by
131
+ * (`facts.ts`). Absent or null on a row the backend gave no key: that row is view-only, never editable.
132
+ */
133
+ readonly canonicalKey?: string | null;
134
+ }
135
+ interface RecordSeriesPoint {
136
+ readonly at: string;
137
+ readonly value: number | null;
138
+ readonly display: string | null;
139
+ /** Who measured this reading. `null` when the backend did not label it - never assume `clinic_document`. */
140
+ readonly origin: RecordOrigin | null;
141
+ }
142
+ /** A time series of one entity (e.g. a weight trend). */
143
+ interface RecordSeries {
144
+ readonly key: string;
145
+ readonly label: string;
146
+ readonly points: readonly RecordSeriesPoint[];
147
+ }
148
+ /** A forward-looking item (a due vaccine / follow-up). */
149
+ interface RecordForwardItem {
150
+ readonly title: string;
151
+ readonly detail: string | null;
152
+ readonly dueAt: string | null;
153
+ }
154
+ /** Metadata for one source document, keyed by its id. No raw bytes / provenance. */
155
+ interface RecordDocumentMeta {
156
+ readonly docId: string;
157
+ readonly title: string | null;
158
+ readonly pageCount: number | null;
159
+ readonly receivedAt: string | null;
160
+ }
161
+ /**
162
+ * The parsed record, ALREADY partner-redacted server-side (§5). `isEmpty` is the normal pre-parse render;
163
+ * `withheld` is the §5 fail-closed suppression (redaction could not be proven safe) and renders the WITHHELD
164
+ * state, never empty, never raw.
165
+ */
166
+ interface RecordsView {
167
+ readonly petRef: PetRef;
168
+ readonly schemaVersion: string;
169
+ readonly isEmpty: boolean;
170
+ readonly withheld: boolean;
171
+ readonly generatedAt: string | null;
172
+ readonly identity: readonly RecordIdentityField[];
173
+ readonly entities: readonly RecordEntity[];
174
+ readonly entitySeries: readonly RecordSeries[];
175
+ readonly forwardLooking: readonly RecordForwardItem[];
176
+ readonly documents: Readonly<Record<string, RecordDocumentMeta>>;
177
+ /** BE-authored not-medical-advice notice, rendered verbatim. */
178
+ readonly disclaimer: string;
179
+ }
180
+ interface ConsentState {
181
+ readonly petRef: PetRef;
182
+ readonly granted: boolean;
183
+ /** consent-text version the user agreed to. */
184
+ readonly version: string | null;
185
+ readonly grantedAt: string | null;
186
+ }
187
+ interface CreateUploadRequestInput {
188
+ readonly petRef: PetRef;
189
+ /** /^[A-Za-z0-9._-]{8,128}$/ (§3.1). Idempotent: a replay returns the SAME request. */
190
+ readonly idempotencyKey: string;
191
+ }
192
+ interface GrantConsentInput {
193
+ readonly petRef: PetRef;
194
+ readonly consentVersion: string;
195
+ readonly idempotencyKey: string;
196
+ }
197
+ /**
198
+ * Why a records read/write was refused. The coarse reason selects the recovery affordance:
199
+ * `consent_required` -> consent CTA, `session_required` -> establish-session CTA, `entitlement` -> the
200
+ * CapabilityGate disabled surface, `pet_not_found` -> the pet the host asked about is not one this tenant
201
+ * holds.
202
+ *
203
+ * `pet_not_found` is NOT a variant of `entitlement`, and keeping them apart is the point. Both arrive as a
204
+ * 404 and both used to fold to the same `accessDenied` sentence, so "this surface is switched off for your
205
+ * tenant" and "the pet you named does not exist here" were one indistinguishable screen. They need different
206
+ * answers because they need different acts: the first is for the partner to have Everfur enable a surface,
207
+ * the second means the host sent a `pet_ref` the tenant does not have. The server already separates them
208
+ * (see `tagReason` in repository.ts for the measured wire shapes).
209
+ */
210
+ type RecordsDenialReason = 'consent_required' | 'session_required' | 'entitlement' | 'pet_not_found';
211
+ /** Read the records denial reason off any settled error, defensively (null when absent). */
212
+ declare function recordsDenialReasonOf(error: EverfurError | null): RecordsDenialReason | null;
213
+
214
+ export { type CreateUploadRequestInput as C, type GrantConsentInput as G, type RecordDocumentMeta as R, type UploadedDocument as U, type RecordEntity as a, type RecordOrigin as b, type RecordsRequestStatus as c, type RecordsRequestView as d, type RecordsSimpleStatus as e, type RecordsRequestGroupView as f, type RecordsView as g, type ConsentState as h, type RecordsDenialReason as i, RECORDS_TERMINAL as j, type RecordForwardItem as k, type RecordIdentityField as l, type RecordSeries as m, type RecordSeriesPoint as n, isTerminalStatus as o, recordsDenialReasonOf as r };
@@ -0,0 +1,214 @@
1
+ import { E as EverfurError } from './EverfurResult-DN9pL2Ab.cjs';
2
+ import { R as RecordsRequestId, P as PetRef, D as DocumentId } from './ids-B2GAAifq.cjs';
3
+
4
+ /**
5
+ * The partner-scoped lifecycle, including clinic requests. The server's canonical simple status takes
6
+ * precedence when supplied; upload and review states retain their action-specific distinctions.
7
+ */
8
+ type RecordsRequestStatus = 'requested' | 'awaiting_clinic' | 'awaiting_upload' | 'received' | 'parsing' | 'in_review' | 'published' | 'failed' | 'revoked';
9
+ /** The backend's seven-state records lifecycle. Unknown future states are not guessed. */
10
+ type RecordsSimpleStatus = Exclude<RecordsRequestStatus, 'awaiting_upload' | 'in_review'>;
11
+ /** Terminal statuses: polling stops here. */
12
+ declare const RECORDS_TERMINAL: readonly RecordsRequestStatus[];
13
+ declare function isTerminalStatus(status: RecordsRequestStatus): boolean;
14
+ interface RecordsRequestView {
15
+ readonly id: RecordsRequestId;
16
+ readonly petRef: PetRef;
17
+ readonly status: RecordsRequestStatus;
18
+ readonly simpleStatus?: RecordsSimpleStatus | null;
19
+ /** Backend-authored machine detail; never used as user-facing copy. */
20
+ readonly simpleStatusDetail?: string | null;
21
+ /** BE-authored copy, rendered verbatim (dumb-renderer rule). */
22
+ readonly statusLabel: string;
23
+ /** Server-authorized actions; absent on older deployments means unavailable. */
24
+ readonly canRetrySend?: boolean;
25
+ readonly canUpdateClinicEmail?: boolean;
26
+ readonly canRevoke?: boolean;
27
+ readonly canConvertToUpload?: boolean;
28
+ readonly dispatchStatus?: string | null;
29
+ readonly reminderCount?: number;
30
+ readonly lastReminderAt?: string | null;
31
+ /** Existing backend-owned follow-up expectations, never reconstructed from raw statuses. */
32
+ readonly waitingExpectation?: string | null;
33
+ /**
34
+ * DEAD, measured 2026-08-22: no plane sends it and nothing in this SDK reads it. The widget
35
+ * `RecordsRequestResponse` omits it, the consumer `RecordsRequestSummary` has no such field either, and a
36
+ * grep of `src/` finds zero render consumers - so it is always the mapper's `0` default.
37
+ *
38
+ * Deliberately NOT deleted here: removing a non-optional public field is a breaking change that needs a
39
+ * major bump, which is a release decision. Documented so nobody reads a count off it.
40
+ */
41
+ readonly documentCount: number;
42
+ /** facts extracted but awaiting review (badge "N being reviewed"). */
43
+ readonly heldItemCount: number;
44
+ /** ISO; null before first upload. */
45
+ readonly receivedAt: string | null;
46
+ /** drives the timeline "reading your records" step. */
47
+ readonly parsingStartedAt: string | null;
48
+ /** non-null == a parse gap occurred (§5, honest, not silent). */
49
+ readonly reviewStartedAt: string | null;
50
+ readonly createdAt: string;
51
+ readonly updatedAt: string;
52
+ /**
53
+ * The server's own owner-facing status vocabulary (EFBackend `records_schemas.RecordsRequestStatus`:
54
+ * `submitted`, `sent`, `awaiting_response`, `awaiting_upload`, `clinic_responded_no_records`,
55
+ * `records_received`, `parsing`, `in_review`, `published`, `failed`, `revoked`, `clinic_declined`), kept
56
+ * beside the folded `status` because the step rail (`buildRequestTimeline`) is the consumer app's and reads
57
+ * that vocabulary. STRUCTURAL ONLY: never rendered as copy. Absent on a hand-built view.
58
+ */
59
+ readonly wireStatus?: string;
60
+ /** `clinic_request` or `owner_provided`; null when the wire did not say. */
61
+ readonly source?: string | null;
62
+ /** The consumer app's action-first sentence for a state that needs the member, BE-authored; null otherwise. */
63
+ readonly actionNeededLabel?: string | null;
64
+ /** BE-authored failure sentence for a failed request, rendered verbatim; null otherwise. */
65
+ readonly failureReason?: string | null;
66
+ /** The machine failure code (`no_response`, `hard_bounce`, `dispatch_failed`, `parse_timeout`, `parse_error`). */
67
+ readonly failureCode?: string | null;
68
+ readonly recoveryStage?: string | null;
69
+ /** True only when the server gates the tap-to-call affordance on for this request. */
70
+ readonly showClinicPhone?: boolean;
71
+ /** The clinic the request went to (directory name or the owner's free text); null for an owner upload. */
72
+ readonly clinicName?: string | null;
73
+ readonly clinicEmail?: string | null;
74
+ /** The clinic's verified phone, present only with `showClinicPhone`. */
75
+ readonly clinicPhone?: string | null;
76
+ /** ISO; set once the owner switched this clinic request to uploading their own records. */
77
+ readonly convertedToUploadAt?: string | null;
78
+ /** The multi-clinic group this request belongs to, or null. */
79
+ readonly requestGroupId?: string | null;
80
+ }
81
+ /** `GET /widget/v1/records/request-groups/{id}`: one pet's multi-clinic batch, with the BE-derived counts. */
82
+ interface RecordsRequestGroupView {
83
+ readonly requestGroupId: string;
84
+ readonly petRef: PetRef;
85
+ /** How many clinics the batch created requests for. */
86
+ readonly total: number;
87
+ /** How many of them the clinic has answered (records, a decline, a reply without records). */
88
+ readonly responded: number;
89
+ /** How many are still waiting on the clinic. */
90
+ readonly pending: number;
91
+ /** One request per clinic, in the server's order. */
92
+ readonly members: readonly RecordsRequestView[];
93
+ }
94
+ interface UploadedDocument {
95
+ readonly documentId: DocumentId;
96
+ readonly requestId: RecordsRequestId;
97
+ /** uploads NEVER auto-bind / auto-publish. */
98
+ readonly status: 'received';
99
+ }
100
+ /** One redacted identity row (name / species / breed / owner-safe field). Provenance absent. */
101
+ interface RecordIdentityField {
102
+ readonly label: string;
103
+ readonly value: string;
104
+ }
105
+ /**
106
+ * Who produced a reading. `owner_reported` is owner-entered (a home scale, typed into the pet profile);
107
+ * `clinic_document` is extracted from a vet document. The two now share one series, so a clinician reading a
108
+ * weight can tell them apart before dosing from it.
109
+ *
110
+ * A value this build does not know folds to `null` (unlabelled), never to a guess - see `normalizeOrigin`.
111
+ * `null` therefore means "the backend did not say", NOT "clinic".
112
+ */
113
+ type RecordOrigin = 'owner_reported' | 'clinic_document';
114
+ /**
115
+ * One extracted clinical fact. No `raw_value` / `source_span` / `source_bbox` / `source_page` /
116
+ * `source_doc_id` / `value_source` / `extraction_method` / `source_precedence` members - `origin` is the only
117
+ * provenance-adjacent field, and it is a display label (see `RecordOrigin`).
118
+ */
119
+ interface RecordEntity {
120
+ readonly key: string;
121
+ readonly category: string;
122
+ readonly label: string;
123
+ readonly value: string | null;
124
+ readonly unit: string | null;
125
+ readonly observedAt: string | null;
126
+ readonly status: string | null;
127
+ /** Who measured it. `null` when the backend did not label it (an older backend never does). */
128
+ readonly origin: RecordOrigin | null;
129
+ /**
130
+ * The server's stable fact key (`canonical_key`), the identity an owner correction or removal is keyed by
131
+ * (`facts.ts`). Absent or null on a row the backend gave no key: that row is view-only, never editable.
132
+ */
133
+ readonly canonicalKey?: string | null;
134
+ }
135
+ interface RecordSeriesPoint {
136
+ readonly at: string;
137
+ readonly value: number | null;
138
+ readonly display: string | null;
139
+ /** Who measured this reading. `null` when the backend did not label it - never assume `clinic_document`. */
140
+ readonly origin: RecordOrigin | null;
141
+ }
142
+ /** A time series of one entity (e.g. a weight trend). */
143
+ interface RecordSeries {
144
+ readonly key: string;
145
+ readonly label: string;
146
+ readonly points: readonly RecordSeriesPoint[];
147
+ }
148
+ /** A forward-looking item (a due vaccine / follow-up). */
149
+ interface RecordForwardItem {
150
+ readonly title: string;
151
+ readonly detail: string | null;
152
+ readonly dueAt: string | null;
153
+ }
154
+ /** Metadata for one source document, keyed by its id. No raw bytes / provenance. */
155
+ interface RecordDocumentMeta {
156
+ readonly docId: string;
157
+ readonly title: string | null;
158
+ readonly pageCount: number | null;
159
+ readonly receivedAt: string | null;
160
+ }
161
+ /**
162
+ * The parsed record, ALREADY partner-redacted server-side (§5). `isEmpty` is the normal pre-parse render;
163
+ * `withheld` is the §5 fail-closed suppression (redaction could not be proven safe) and renders the WITHHELD
164
+ * state, never empty, never raw.
165
+ */
166
+ interface RecordsView {
167
+ readonly petRef: PetRef;
168
+ readonly schemaVersion: string;
169
+ readonly isEmpty: boolean;
170
+ readonly withheld: boolean;
171
+ readonly generatedAt: string | null;
172
+ readonly identity: readonly RecordIdentityField[];
173
+ readonly entities: readonly RecordEntity[];
174
+ readonly entitySeries: readonly RecordSeries[];
175
+ readonly forwardLooking: readonly RecordForwardItem[];
176
+ readonly documents: Readonly<Record<string, RecordDocumentMeta>>;
177
+ /** BE-authored not-medical-advice notice, rendered verbatim. */
178
+ readonly disclaimer: string;
179
+ }
180
+ interface ConsentState {
181
+ readonly petRef: PetRef;
182
+ readonly granted: boolean;
183
+ /** consent-text version the user agreed to. */
184
+ readonly version: string | null;
185
+ readonly grantedAt: string | null;
186
+ }
187
+ interface CreateUploadRequestInput {
188
+ readonly petRef: PetRef;
189
+ /** /^[A-Za-z0-9._-]{8,128}$/ (§3.1). Idempotent: a replay returns the SAME request. */
190
+ readonly idempotencyKey: string;
191
+ }
192
+ interface GrantConsentInput {
193
+ readonly petRef: PetRef;
194
+ readonly consentVersion: string;
195
+ readonly idempotencyKey: string;
196
+ }
197
+ /**
198
+ * Why a records read/write was refused. The coarse reason selects the recovery affordance:
199
+ * `consent_required` -> consent CTA, `session_required` -> establish-session CTA, `entitlement` -> the
200
+ * CapabilityGate disabled surface, `pet_not_found` -> the pet the host asked about is not one this tenant
201
+ * holds.
202
+ *
203
+ * `pet_not_found` is NOT a variant of `entitlement`, and keeping them apart is the point. Both arrive as a
204
+ * 404 and both used to fold to the same `accessDenied` sentence, so "this surface is switched off for your
205
+ * tenant" and "the pet you named does not exist here" were one indistinguishable screen. They need different
206
+ * answers because they need different acts: the first is for the partner to have Everfur enable a surface,
207
+ * the second means the host sent a `pet_ref` the tenant does not have. The server already separates them
208
+ * (see `tagReason` in repository.ts for the measured wire shapes).
209
+ */
210
+ type RecordsDenialReason = 'consent_required' | 'session_required' | 'entitlement' | 'pet_not_found';
211
+ /** Read the records denial reason off any settled error, defensively (null when absent). */
212
+ declare function recordsDenialReasonOf(error: EverfurError | null): RecordsDenialReason | null;
213
+
214
+ export { type CreateUploadRequestInput as C, type GrantConsentInput as G, type RecordDocumentMeta as R, type UploadedDocument as U, type RecordEntity as a, type RecordOrigin as b, type RecordsRequestStatus as c, type RecordsRequestView as d, type RecordsSimpleStatus as e, type RecordsRequestGroupView as f, type RecordsView as g, type ConsentState as h, type RecordsDenialReason as i, RECORDS_TERMINAL as j, type RecordForwardItem as k, type RecordIdentityField as l, type RecordSeries as m, type RecordSeriesPoint as n, isTerminalStatus as o, recordsDenialReasonOf as r };
@@ -0,0 +1,2 @@
1
+ 'use strict';var react=require('react'),reactNative=require('react-native');var Ke=Object.defineProperty;var n=(e,r)=>Ke(e,"name",{value:r,configurable:true});function T(e,r){return Object.freeze(r===void 0?{ok:true,value:e}:{ok:true,value:e,warning:r})}n(T,"ok");function u(e){return Object.freeze({ok:false,error:e})}n(u,"err");var A=class A extends Error{constructor(r,t){super(t),this.name="EverfurConfigError",this.kind=r,Object.setPrototypeOf(this,A.prototype);}};n(A,"EverfurConfigError");var x=A;var q=Object.freeze([Object.freeze({wireCode:"AccessDeniedException",envelope:"http_envelope",httpStatus:403,retryable:false}),Object.freeze({wireCode:"AuthorizationException",envelope:"http_envelope",httpStatus:401,retryable:false}),Object.freeze({wireCode:"ConflictException",envelope:"http_envelope",httpStatus:409,retryable:true}),Object.freeze({wireCode:"DAILY_QUOTA_EXCEEDED",envelope:"http_envelope",httpStatus:429,retryable:true}),Object.freeze({wireCode:"FILE_TOO_LARGE",envelope:"http_envelope",httpStatus:400,retryable:false}),Object.freeze({wireCode:"IDEMPOTENCY_KEY_IN_FLIGHT",envelope:"http_envelope",httpStatus:409,retryable:true}),Object.freeze({wireCode:"IDEMPOTENCY_KEY_REUSED_DIFFERENT_REQUEST",envelope:"http_envelope",httpStatus:409,retryable:false}),Object.freeze({wireCode:"INVALID_CONTENT_TYPE",envelope:"http_envelope",httpStatus:400,retryable:false}),Object.freeze({wireCode:"InternalFailureException",envelope:"http_envelope",httpStatus:500,retryable:true}),Object.freeze({wireCode:"MethodNotAllowedException",envelope:"http_envelope",httpStatus:405,retryable:false}),Object.freeze({wireCode:"NotImplementedException",envelope:"http_envelope",httpStatus:501,retryable:false}),Object.freeze({wireCode:"PaymentRequiredException",envelope:"http_envelope",httpStatus:402,retryable:false}),Object.freeze({wireCode:"ResourceNotFoundException",envelope:"http_envelope",httpStatus:404,retryable:false}),Object.freeze({wireCode:"ServiceUnavailableException",envelope:"http_envelope",httpStatus:503,retryable:true}),Object.freeze({wireCode:"TIER_UPGRADE_REQUIRED",envelope:"http_envelope",httpStatus:402,retryable:false}),Object.freeze({wireCode:"ThrottlingException",envelope:"http_envelope",httpStatus:429,retryable:true}),Object.freeze({wireCode:"ValidationException",envelope:"http_envelope",httpStatus:400,retryable:false}),Object.freeze({wireCode:"accessDenied",envelope:"http_envelope",httpStatus:403,retryable:false}),Object.freeze({wireCode:"access_denied",envelope:"oauth_error",httpStatus:302,retryable:false}),Object.freeze({wireCode:"attachment_unreadable",envelope:"http_envelope",httpStatus:400,retryable:false}),Object.freeze({wireCode:"authExpired",envelope:"http_envelope",httpStatus:401,retryable:true}),Object.freeze({wireCode:"authRejected",envelope:"http_envelope",httpStatus:401,retryable:false}),Object.freeze({wireCode:"consent_invalid",envelope:"http_envelope",httpStatus:422,retryable:false}),Object.freeze({wireCode:"consent_required",envelope:"http_envelope",httpStatus:422,retryable:false}),Object.freeze({wireCode:"consent_scope_wrong_route",envelope:"http_envelope",httpStatus:400,retryable:false}),Object.freeze({wireCode:"device_cipher_unavailable",envelope:"http_envelope",httpStatus:503,retryable:true}),Object.freeze({wireCode:"email_invalid",envelope:"http_envelope",httpStatus:422,retryable:false}),Object.freeze({wireCode:"event_cursor_invalid",envelope:"http_envelope",httpStatus:400,retryable:false}),Object.freeze({wireCode:"event_filter_invalid",envelope:"http_envelope",httpStatus:400,retryable:false}),Object.freeze({wireCode:"event_payload_invalid",envelope:"http_envelope",httpStatus:400,retryable:false}),Object.freeze({wireCode:"event_type_not_available",envelope:"http_envelope",httpStatus:400,retryable:false}),Object.freeze({wireCode:"event_type_unknown",envelope:"http_envelope",httpStatus:400,retryable:false}),Object.freeze({wireCode:"idempotency_key_invalid",envelope:"http_envelope",httpStatus:400,retryable:false}),Object.freeze({wireCode:"idempotency_key_required",envelope:"http_envelope",httpStatus:400,retryable:false}),Object.freeze({wireCode:"idempotency_key_reused",envelope:"http_envelope",httpStatus:409,retryable:false}),Object.freeze({wireCode:"insufficientCapability",envelope:"http_envelope",httpStatus:403,retryable:false}),Object.freeze({wireCode:"insufficient_scope",envelope:"http_envelope",httpStatus:403,retryable:false}),Object.freeze({wireCode:"internal_error",envelope:"sse_frame",httpStatus:200,retryable:false}),Object.freeze({wireCode:"invalidRequest",envelope:"http_envelope",httpStatus:400,retryable:false}),Object.freeze({wireCode:"invalid_client",envelope:"oauth_error",httpStatus:401,retryable:false}),Object.freeze({wireCode:"invalid_client_metadata",envelope:"oauth_error",httpStatus:400,retryable:false}),Object.freeze({wireCode:"invalid_grant",envelope:"oauth_error",httpStatus:400,retryable:false}),Object.freeze({wireCode:"invalid_redirect_uri",envelope:"oauth_error",httpStatus:400,retryable:false}),Object.freeze({wireCode:"invalid_request",envelope:"oauth_error",httpStatus:400,retryable:false}),Object.freeze({wireCode:"invalid_scope",envelope:"oauth_error",httpStatus:400,retryable:false}),Object.freeze({wireCode:"invalid_target",envelope:"oauth_error",httpStatus:400,retryable:false}),Object.freeze({wireCode:"mcp_connection_not_found",envelope:"http_envelope",httpStatus:404,retryable:false}),Object.freeze({wireCode:"mcp_request_conflict",envelope:"http_envelope",httpStatus:409,retryable:false}),Object.freeze({wireCode:"mcp_request_gone",envelope:"http_envelope",httpStatus:410,retryable:false}),Object.freeze({wireCode:"mcp_request_not_found",envelope:"http_envelope",httpStatus:404,retryable:false}),Object.freeze({wireCode:"not_found",envelope:"sse_frame",httpStatus:200,retryable:false}),Object.freeze({wireCode:"partner_visit_link_conflict",envelope:"http_envelope",httpStatus:409,retryable:false}),Object.freeze({wireCode:"partner_visit_owner_only",envelope:"http_envelope",httpStatus:403,retryable:false}),Object.freeze({wireCode:"partner_visit_pet_already_mapped",envelope:"http_envelope",httpStatus:409,retryable:false}),Object.freeze({wireCode:"payload_too_large",envelope:"http_envelope",httpStatus:413,retryable:false}),Object.freeze({wireCode:"petRefInUse",envelope:"http_envelope",httpStatus:409,retryable:false}),Object.freeze({wireCode:"pet_health_list_removals_unconfirmed",envelope:"http_envelope",httpStatus:422,retryable:false}),Object.freeze({wireCode:"pet_health_species_unsupported",envelope:"http_envelope",httpStatus:422,retryable:false}),Object.freeze({wireCode:"pet_not_registered",envelope:"http_envelope",httpStatus:404,retryable:false}),Object.freeze({wireCode:"provider_unsupported",envelope:"http_envelope",httpStatus:422,retryable:false}),Object.freeze({wireCode:"rateLimited",envelope:"http_envelope",httpStatus:429,retryable:true}),Object.freeze({wireCode:"record_species_unsupported",envelope:"http_envelope",httpStatus:422,retryable:false}),Object.freeze({wireCode:"record_subject_not_found",envelope:"http_envelope",httpStatus:404,retryable:false}),Object.freeze({wireCode:"record_upload_invalid",envelope:"http_envelope",httpStatus:400,retryable:false}),Object.freeze({wireCode:"records_consent_required",envelope:"http_envelope",httpStatus:409,retryable:false}),Object.freeze({wireCode:"sandbox_only",envelope:"http_envelope",httpStatus:403,retryable:false}),Object.freeze({wireCode:"session_required",envelope:"http_envelope",httpStatus:403,retryable:false}),Object.freeze({wireCode:"share_limit_reached",envelope:"http_envelope",httpStatus:429,retryable:false}),Object.freeze({wireCode:"slow_down",envelope:"oauth_error",httpStatus:429,retryable:true}),Object.freeze({wireCode:"species_unsupported",envelope:"http_envelope",httpStatus:422,retryable:false}),Object.freeze({wireCode:"tenant_filter_invalid",envelope:"http_envelope",httpStatus:400,retryable:false}),Object.freeze({wireCode:"tenant_has_no_capabilities",envelope:"http_envelope",httpStatus:409,retryable:false}),Object.freeze({wireCode:"tenant_resource_not_found",envelope:"http_envelope",httpStatus:404,retryable:false}),Object.freeze({wireCode:"tenant_surface_not_enabled",envelope:"http_envelope",httpStatus:409,retryable:false}),Object.freeze({wireCode:"timeout",envelope:"sse_frame",httpStatus:200,retryable:true}),Object.freeze({wireCode:"token_invalid",envelope:"http_envelope",httpStatus:422,retryable:false}),Object.freeze({wireCode:"unavailable",envelope:"sse_frame",httpStatus:200,retryable:true}),Object.freeze({wireCode:"unavailable",envelope:"http_envelope",httpStatus:503,retryable:true}),Object.freeze({wireCode:"unsupported_grant_type",envelope:"oauth_error",httpStatus:400,retryable:false}),Object.freeze({wireCode:"unsupported_response_type",envelope:"oauth_error",httpStatus:302,retryable:false}),Object.freeze({wireCode:"verify_mint_rate_limited",envelope:"http_envelope",httpStatus:429,retryable:true}),Object.freeze({wireCode:"verify_mint_refused",envelope:"http_envelope",httpStatus:403,retryable:false}),Object.freeze({wireCode:"verify_mint_unavailable",envelope:"http_envelope",httpStatus:503,retryable:true}),Object.freeze({wireCode:"verify_user_ref_invalid",envelope:"http_envelope",httpStatus:422,retryable:false}),Object.freeze({wireCode:"webhook_endpoint_update_empty",envelope:"http_envelope",httpStatus:400,retryable:false}),Object.freeze({wireCode:"webhook_endpoint_update_invalid",envelope:"http_envelope",httpStatus:400,retryable:false}),Object.freeze({wireCode:"webhook_url_rejected",envelope:"http_envelope",httpStatus:400,retryable:false})]);Object.freeze(q.map(e=>e.wireCode));var He=Object.freeze({ValidationException:"validationFailed",AuthorizationException:"authRejected",PaymentRequiredException:"paymentRequired",AccessDeniedException:"accessDenied",ResourceNotFoundException:"resourceNotFound",ConflictException:"conflict",ThrottlingException:"rateLimited",InternalFailureException:"internalError",NotImplementedException:"notImplemented",ServiceUnavailableException:"serviceUnavailable",MethodNotAllowedException:"validationFailed",authExpired:"authExpired",unavailable:"serviceUnavailable",session_required:"sessionRequired",accessDenied:"accessDenied",invalidRequest:"sdkUpdateRequired",authRejected:"authRejected",rateLimited:"rateLimited",insufficientCapability:"accessDenied",event_cursor_invalid:"validationFailed",event_filter_invalid:"validationFailed",event_payload_invalid:"validationFailed",event_type_unknown:"validationFailed",idempotency_key_invalid:"validationFailed",idempotency_key_required:"validationFailed",idempotency_key_reused:"idempotencyConflict",payload_too_large:"validationFailed",webhook_url_rejected:"validationFailed",webhook_endpoint_update_empty:"validationFailed",webhook_endpoint_update_invalid:"validationFailed",event_type_not_available:"conflict",record_subject_not_found:"resourceNotFound",records_consent_required:"conflict",record_species_unsupported:"validationFailed",record_upload_invalid:"validationFailed",FILE_TOO_LARGE:"validationFailed",INVALID_CONTENT_TYPE:"validationFailed",attachment_unreadable:"validationFailed",provider_unsupported:"validationFailed",token_invalid:"validationFailed",device_cipher_unavailable:"serviceUnavailable",email_invalid:"validationFailed",consent_required:"validationFailed",consent_invalid:"validationFailed",consent_scope_wrong_route:"validationFailed",IDEMPOTENCY_KEY_IN_FLIGHT:"idempotencyInFlight",IDEMPOTENCY_KEY_REUSED_DIFFERENT_REQUEST:"idempotencyConflict",DAILY_QUOTA_EXCEEDED:"quotaExceeded",TIER_UPGRADE_REQUIRED:"paymentRequired",not_found:"conversationNotFound",timeout:"streamTimeout",internal_error:"internalError",invalid_request:"validationFailed",invalid_client:"authRejected",invalid_grant:"authRejected",unsupported_grant_type:"validationFailed",invalid_scope:"validationFailed",invalid_target:"validationFailed",invalid_redirect_uri:"validationFailed",invalid_client_metadata:"validationFailed",unsupported_response_type:"validationFailed",access_denied:"accessDenied",slow_down:"rateLimited",mcp_request_not_found:"resourceNotFound",mcp_request_gone:"resourceNotFound",mcp_connection_not_found:"resourceNotFound",mcp_request_conflict:"conflict",sandbox_only:"accessDenied",tenant_has_no_capabilities:"conflict",verify_mint_refused:"accessDenied",verify_mint_rate_limited:"rateLimited",verify_mint_unavailable:"serviceUnavailable",verify_user_ref_invalid:"validationFailed",insufficient_scope:"accessDenied",tenant_filter_invalid:"validationFailed",tenant_resource_not_found:"resourceNotFound",tenant_surface_not_enabled:"conflict",pet_health_species_unsupported:"validationFailed",pet_health_list_removals_unconfirmed:"validationFailed",petRefInUse:"conflict",share_limit_reached:"conflict",pet_not_registered:"resourceNotFound",species_unsupported:"validationFailed",partner_visit_owner_only:"accessDenied",partner_visit_link_conflict:"conflict",partner_visit_pet_already_mapped:"conflict"}),ie=Object.freeze(q.map(e=>Object.freeze({wireCode:e.wireCode,envelope:e.envelope,retryable:e.retryable,normalized:He[e.wireCode]}))),We=new Map(ie.map(e=>[e.envelope+e.wireCode.toUpperCase(),e])),Ge=Object.freeze(["http_envelope",...[...new Set(ie.map(e=>e.envelope))].filter(e=>e!=="http_envelope").sort()]);function D(e,r){if(typeof e!="string")return;let t=e.trim().toUpperCase();if(t.length!==0)for(let o of [r??"http_envelope",...Ge]){let i=We.get(o+t);if(i)return i}}n(D,"contractErrorFor");function $e(e){return e.envelope==="sse_frame"?`/errors#sse-${e.wireCode}`:e.envelope==="oauth_error"?`/errors#oauth-${e.wireCode}`:`/errors#${e.wireCode}`}n($e,"contractDocUrl");function ae(e){return null}n(ae,"publishedDocUrl");var Qe=Object.freeze({authExpired:"authentication",authRejected:"authentication",sessionRequired:"authentication",accessDenied:"authorization",paymentRequired:"entitlement",quotaExceeded:"rateLimit",rateLimited:"rateLimit",validationFailed:"invalidRequest",sdkUpdateRequired:"invalidRequest",conversationNotFound:"notFound",petNotFound:"notFound",resourceNotFound:"notFound",conflict:"conflict",idempotencyConflict:"conflict",idempotencyInFlight:"conflict",streamTimeout:"connection",streamIncomplete:"connection",upstreamLlmTimeout:"connection",serviceUnavailable:"connection",internalError:"server",notImplemented:"server",mediaUploadFailed:"media",moderationBlocked:"policy",unknown:"unknown"});function se(e){return Qe[e]}n(se,"categoryFor");function le(e){let r=D(e);if(r)return r.normalized;let t=(e??"").trim().toUpperCase(),o=t.replace(/[^A-Z0-9]/g,"");if(o==="AUTHREJECTED")return "authRejected";if(t.startsWith("AUTH"))return "authExpired";switch(o){case "DAILYQUOTAEXCEEDED":case "QUOTAEXCEEDED":return "quotaExceeded";case "RATELIMITED":case "TOOMANYREQUESTS":return "rateLimited";case "IDEMPOTENCYKEYCONFLICT":case "IDEMPOTENCYCONFLICT":return "idempotencyConflict";case "ACCESSDENIED":case "FORBIDDEN":return "accessDenied";case "NOTFOUND":case "CONVERSATIONNOTFOUND":return "conversationNotFound";case "PETNOTFOUND":return "petNotFound";case "TIMEOUT":case "STREAMTIMEOUT":return "streamTimeout";case "MEDIAUPLOADFAILED":case "UNRECOGNIZEDVIDEOFORMAT":case "FILETOOSMALL":return "mediaUploadFailed";case "MODERATIONBLOCKED":return "moderationBlocked";case "UPSTREAMLLMTIMEOUT":return "upstreamLlmTimeout";case "INTERNALERROR":case "INTERNALSERVERERROR":return "internalError";case "STREAMINCOMPLETE":case "CHATSTREAMINCOMPLETE":return "streamIncomplete";case "INVALIDANALYSISTYPE":case "INVALIDUPLOADPURPOSE":return "unknown";default:return "unknown"}}n(le,"fromWire");var Xe=new Set(["streamTimeout","rateLimited","internalError","upstreamLlmTimeout","streamIncomplete"]);function V(e){return Xe.has(e)}n(V,"isAutoRetryable");var Je=new Set(["serviceUnavailable","conflict","idempotencyInFlight"]);function ue(e){return V(e)||Je.has(e)}n(ue,"isRetryableCode");var Ze=500,B=8e3,de=4;function ce(e,r=Math.random){let t=Math.max(0,e),o=Math.min(Ze*2**t,B);return Math.floor(r()*o)}n(ce,"backoffDelayMs");var er=Object.freeze({authExpired:"Please sign in again to continue.",authRejected:"Please sign in again to continue.",sessionRequired:"This app needs to be updated to keep using Everfur.",accessDenied:"This feature isn't available on your account right now.",paymentRequired:"This is part of a paid plan.",quotaExceeded:"You have used today's messages. This resets tomorrow.",rateLimited:"You are sending messages quickly. Try again in a few seconds.",validationFailed:"Something in that request was not right. Check the details and try again.",sdkUpdateRequired:"This app needs to be updated to keep using Everfur.",conflict:"That is already running. Wait for it to finish, then try again.",idempotencyConflict:"That message was already delivered.",idempotencyInFlight:"That is still processing. Give it a moment.",conversationNotFound:"This conversation is no longer available.",petNotFound:"We could not find that pet. Please pick a pet and try again.",resourceNotFound:"We could not find that.",streamTimeout:"The response timed out. Tap retry to try again.",mediaUploadFailed:"We could not upload that photo. Please attach it again.",moderationBlocked:"This request cannot be answered here.",upstreamLlmTimeout:"The response timed out. Tap retry to try again.",internalError:"We hit a snag on our end. Please try again.",notImplemented:"That is not available yet.",serviceUnavailable:"That service is briefly unavailable. Try again shortly.",streamIncomplete:"The connection dropped mid-answer. Tap retry to continue.",unknown:"Something went wrong. Please try again."});function rr(e){return er[e]}n(rr,"userFacingError");function fe(e,r,t){Object.defineProperty(e,r,{value:t,enumerable:false,writable:false,configurable:false});}n(fe,"defineHidden");var tr=/^[a-z][a-z0-9_]{0,63}$/;function _(e,r){let t=D(r?.wireCode,r?.wireEnvelope),o={code:e,category:se(e),retryable:r?.retryable??ue(e),displayMessage:rr(e)};if(r?.httpStatus!==void 0&&(o.httpStatus=r.httpStatus),r?.requestId&&(o.requestId=r.requestId),typeof r?.reasonCode=="string"&&tr.test(r.reasonCode)&&(o.reasonCode=r.reasonCode),t);return r?.wireMessage&&fe(o,"wireMessage",r.wireMessage),r?.raw!==void 0&&r.raw!==null&&fe(o,"raw",r.raw),Object.freeze(o)}n(_,"makeEverfurError");function pe(e){return Object.freeze({kind:"error",terminal:true,code:e.code,retryable:e.retryable,wireMessage:e.wireMessage,synthesized:e.synthesized,lastEventId:e.lastEventId,serverRequestId:e.serverRequestId??null})}n(pe,"errorFrame");function ir(e){let r={};return e.mode==="personalized"?r.authorization=`Bearer ${e.token}`:r["x-everfur-partner-key"]=e.publishableKey,e.userRef&&(r["x-everfur-user-ref"]=e.userRef),e.sessionId&&(r["x-everfur-session-id"]=e.sessionId),r}n(ir,"authHeaders");function F(e,r){return {...e,headers:{...ar(e.headers),...ir(r)}}}n(F,"withAuthHeaders");function ar(e){if(!e)return {};let r={};for(let[t,o]of Object.entries(e)){let i=t.toLowerCase();i==="authorization"||i==="x-everfur-partner-key"||(r[t]=o);}return r}n(ar,"stripAuthHeaders");async function ve(e,r){if(r.mode==="anonymous")return r.transport.request(F(e,{mode:"anonymous",publishableKey:r.publishableKey,userRef:r.userRef,...r.sessionId?{sessionId:r.sessionId}:{}}));let t;try{t=await r.identity.currentToken();}catch{return u(Y())}let o=await r.transport.request(F(e,{mode:"personalized",token:t,userRef:r.userRef,...r.sessionId?{sessionId:r.sessionId}:{}}));if(o.ok||o.error.httpStatus!==401)return o;let i;try{i=await r.identity.currentToken({forceRefresh:!0});}catch{return u(Y())}let a=await r.transport.request(F(e,{mode:"personalized",token:i,userRef:r.userRef,...r.sessionId?{sessionId:r.sessionId}:{}}));return !a.ok&&a.error.httpStatus===401?u(Y(a.error.httpStatus)):a}n(ve,"authedSend");function Y(e){return _("authRejected",{retryable:false,...e!==void 0?{httpStatus:e}:{}})}n(Y,"authRejectedError");function ye(e){return _("internalError",{retryable:true,wireMessage:sr(e)})}n(ye,"networkError");function sr(e){return e instanceof Error?e.message:typeof e=="string"?e:"network request failed"}n(sr,"describeCause");var lr=3e4,ur=B*2,dr="idempotency-key",cr=new Set(["POST","PUT","PATCH","DELETE"]),fr=Object.freeze({onEvent(){}}),pr=Object.freeze({setTimeout:n((e,r)=>setTimeout(e,r),"setTimeout"),clearTimeout:n(e=>clearTimeout(e),"clearTimeout"),now:n(()=>Date.now(),"now")});function j(e){let r=e.observer??fr,t=e.timers??pr,o=e.rng??Math.random,i=e.sleep??((v,c)=>Sr(v,t,c)),a=e.maxAttempts??de,s=e.unaryTimeoutMs??lr,l=e.newIdempotencyKey??yr(),d=n(v=>{try{r.onEvent(v);}catch{}},"emit");async function h(v,c,C){let S=C?.maxAttempts,P=Math.max(1,S??a),f=C?.idempotent??cr.has(c.method)?l():null,p=vr(c,f),y=0;for(;;){let E=n(L=>Object.freeze({call:v,method:c.method,path:c.path,attempt:y,...f?{idempotencyKey:f}:{},...L}),"stamp");d(E({phase:"attempt"}));let te=Cr(s,t),ne=Tr(te.signal,c.signal),k;try{k=await ve({...p,signal:ne.signal},e.auth);}catch(L){k=u(ye(L));}finally{ne.dispose(),te.cancel();}if(k.ok)return d(E({phase:"settled",ok:true,reason:"ok"})),k;let R=k.error,N=Er(R,y,{maxAttempts:P,rng:o,now:t.now(),aborted:c.signal?.aborted===true,...S!==void 0?{perCallMaxAttempts:S}:{},...e.errorPolicy!==void 0?{policy:e.errorPolicy}:{}}),U={ok:false,code:R.code,reason:N.reason,...R.httpStatus!==void 0?{httpStatus:R.httpStatus}:{},...R.requestId!==void 0?{requestId:R.requestId}:{}};if(!N.retry)return d(E({phase:"settled",...U})),u(R);if(d(E({phase:"retry",...U,delayMs:N.delayMs})),await i(N.delayMs,c.signal),c.signal?.aborted===true)return d(E({phase:"settled",...U,reason:"aborted"})),u(R);y+=1;}}n(h,"send");async function w(v){return F(v,await wr(e.auth))}n(w,"authorize");async function*g(v,c,C){d(Object.freeze({call:v,phase:"stream.open",method:c.method,path:c.path,attempt:0}));try{yield*e.auth.transport.stream(c,C);}catch{yield pe({code:"internal_error",retryable:true,wireMessage:null,synthesized:true,lastEventId:null,serverRequestId:null});}}return n(g,"stream"),Object.freeze({send:h,authorize:w,stream:g})}n(j,"createRequestFunnel");function vr(e,r){let t={};for(let[o,i]of Object.entries(e.headers??{}))o.toLowerCase()!==dr&&(t[o]=i);return r!==null&&(t["Idempotency-Key"]=r),{...e,headers:t}}n(vr,"assembleHeaders");function yr(){let e=0;return ()=>`efk_${Date.now().toString(36)}_${(e++).toString(36)}_${Math.random().toString(36).slice(2,12)}`}n(yr,"defaultIdempotencyKeyFactory");var mr=10;function Er(e,r,t){if(t.aborted)return {retry:false,reason:"aborted"};let o=_r(e);if(o==="quota")return {retry:false,reason:"daily-quota-exhausted"};if(o!=="burst"&&!V(e.code))return {retry:false,reason:"terminal-code"};let i=o==="burst"?"burst-throttle":"retryable-code";if(n(()=>{if(t.policy===void 0)return false;try{return !t.policy.shouldRetry(e.code,r)}catch{return false}},"policyVetoedRetry")())return {retry:false,reason:"terminal-code"};let s=n(()=>{if(t.policy===void 0)return null;let h;try{h=t.policy.maxAttempts(e.code);}catch{return null}return typeof h!="number"||!Number.isFinite(h)?null:Math.max(1,Math.min(mr,Math.floor(h)))},"policyCeiling"),l=t.perCallMaxAttempts??s()??t.maxAttempts;if(r+1>=l)return {retry:false,reason:"attempts-exhausted"};let d=gr(e,t.now);return d!==null?d>ur?{retry:false,reason:"server-reset-beyond-budget"}:{retry:true,reason:i,delayMs:d}:{retry:true,reason:i,delayMs:ce(r,t.rng)}}n(Er,"decideRetry");function _r(e){let r=e.code==="unknown"?le(Rr(e.raw)):e.code;return r==="quotaExceeded"?"quota":r==="rateLimited"||e.httpStatus===429?"burst":null}n(_r,"throttleKind");function gr(e,r){let t=hr(e.raw);if(t===null)return null;let o=t-r;return o>0?o:0}n(gr,"retryOverrideMs");function hr(e){for(let r of Ee(e)){let t=r.resets_at,o=br(t);if(o!==null)return o}return null}n(hr,"findResetsAt");function Ee(e){if(!me(e))return [];let r=[e];for(let t of ["error","detail"]){let o=e[t];me(o)&&r.push(o);}return r}n(Ee,"candidateScopes");function br(e){if(typeof e=="number"&&Number.isFinite(e))return e<1e11?Math.round(e*1e3):Math.round(e);if(typeof e=="string"&&e.trim().length>0){let r=Date.parse(e);return Number.isFinite(r)?r:null}return null}n(br,"parseInstantMs");function Rr(e){for(let r of Ee(e)){let t=r.code;if(typeof t=="string"&&t.length>0)return t}return null}n(Rr,"rawWireCode");function me(e){return typeof e=="object"&&e!==null}n(me,"isRecord");async function wr(e){return e.mode==="anonymous"?{mode:"anonymous",publishableKey:e.publishableKey,userRef:e.userRef,...e.sessionId?{sessionId:e.sessionId}:{}}:{mode:"personalized",token:await e.identity.currentToken(),userRef:e.userRef,...e.sessionId?{sessionId:e.sessionId}:{}}}n(wr,"resolveDeviceAuth");function Cr(e,r){let t=new AbortController,o=r.setTimeout(()=>t.abort(),e);return {signal:t.signal,cancel:n(()=>r.clearTimeout(o),"cancel")}}n(Cr,"boundedSignal");function Tr(e,r){let t=n(()=>{},"noop");if(!r)return {signal:e,dispose:t};let o=new AbortController;if(e.aborted||r.aborted)return o.abort(),{signal:o.signal,dispose:t};let i=n(()=>o.abort(),"onAbort");return e.addEventListener("abort",i,{once:true}),r.addEventListener("abort",i,{once:true}),{signal:o.signal,dispose:n(()=>{e.removeEventListener("abort",i),r.removeEventListener("abort",i);},"dispose")}}n(Tr,"mergeSignals");function Sr(e,r,t){return e<=0||t?.aborted===true?Promise.resolve():new Promise(o=>{let i=r.setTimeout(()=>{t?.removeEventListener("abort",a),o();},e),a=n(()=>{r.clearTimeout(i),o();},"onAbort");t?.addEventListener("abort",a,{once:true});})}n(Sr,"delayAbortable");function Ir(e){let r=e.raw;if(typeof r!="object"||r===null)return null;let t=r.code;return typeof t=="string"&&t.length>0?t:null}n(Ir,"wireCodeOf");function _e(e,r){let t=Ir(e);if(t===null)return e;let o=r[t];return o===void 0?e:_(o.code,{retryable:o.retryable,...e.httpStatus!==void 0?{httpStatus:e.httpStatus}:{},...e.requestId!==void 0?{requestId:e.requestId}:{},wireCode:t,reasonCode:t,...e.wireMessage!==void 0?{wireMessage:e.wireMessage}:{},raw:e.raw})}n(_e,"foldWireReason");var we=Object.freeze({provider_unsupported:"Everfur does not send through this push provider yet. Register an Expo push token (provider expo) or an FCM registration token (provider fcm); APNs direct is not available in this version.",token_invalid:"The token is not a push token of the given provider. Expo tokens look like ExponentPushToken[...]; FCM registration tokens are long opaque strings. Pass the token exactly as your notification library printed it.",device_cipher_unavailable:"Everfur could not seal the token at rest, so nothing was stored. Retry the registration later; the SDK retries it on the next launch and login.",credentials_missing:"Everfur holds no push credential for this provider on your tenant, so deliveries to it are skipped. Expo needs nothing unless you enabled push security (then your Expo access token). A bare app using FCM supplies its Firebase service-account JSON to Everfur; push credentials are set by Everfur on your tenant, never through the SDK."}),Or=new Set(["provider_unsupported","token_invalid","device_cipher_unavailable","credentials_missing"]);function kr(e){let r=e.reasonCode;return r!==void 0&&Or.has(r)?we[r]:null}n(kr,"explainNotificationsReason");var Ce=new Set(["expo","fcm","apns"]),Te=new Set(["ios","android"]),ge=4096,he=128,be=64,Se=/[- ]/;function b(e,r){return _("validationFailed",{retryable:false,wireMessage:e,...r?{reasonCode:r}:{}})}n(b,"invalid");function xr(e){if(typeof e!="object"||e===null)return b("registerDevice needs an input object");let{token:r,provider:t,platform:o,installationId:i}=e;return typeof t!="string"||!Ce.has(t)?b("provider must be expo, fcm or apns"):typeof o!="string"||!Te.has(o)?b("platform must be ios or android"):typeof r!="string"||r.trim().length===0||r.length>ge||Se.test(r)?b(`token must be a push token of 1..${ge} characters with no whitespace`,"token_invalid"):i!==void 0&&(typeof i!="string"||i.length===0||i.length>he)?b(`installationId must be 1..${he} characters`):null}n(xr,"validateRegister");function Fr(e){return typeof e!="string"||e.length===0||e.length>be?b(`deviceId must be 1..${be} characters`):Se.test(e)||e.includes("/")||e==="."||e===".."?b("deviceId is not a device id"):null}n(Fr,"validateDeviceId");function Pr(e){if(typeof e!="object"||e===null)return b("setPreferences needs an input object");let{pushEnabled:r,emailEnabled:t}=e;return typeof r!="boolean"||typeof t!="boolean"?b("pushEnabled and emailEnabled must both be booleans: the route replaces both switches"):null}n(Pr,"validatePreferences");function I(e){return typeof e=="string"&&e.length>0?e:null}n(I,"str");function Nr(e){if(typeof e!="object"||e===null)return null;let r=e,t=I(r.device_id),o=I(r.provider),i=I(r.platform),a=I(r.registered_at),s=I(r.last_seen_at);if(t===null||o===null||i===null||a===null||s===null||!Ce.has(o)||!Te.has(i))return null;let l=r.installation_id;return Object.freeze({deviceId:t,provider:o,platform:i,installationId:typeof l=="string"&&l.length>0?l:null,registeredAt:a,lastSeenAt:s})}n(Nr,"parseDevice");function Ar(e){if(typeof e!="object"||e===null)return null;let r=e,t=I(r.updated_at);return typeof r.push_enabled!="boolean"||typeof r.email_enabled!="boolean"||t===null?null:Object.freeze({pushEnabled:r.push_enabled,emailEnabled:r.email_enabled,updatedAt:t})}n(Ar,"parsePreferences");function Re(e){return _("internalError",{retryable:false,wireMessage:`${e}: the response was not the documented shape`})}n(Re,"malformed");var Dr=Object.freeze({provider_unsupported:{code:"validationFailed",retryable:false},token_invalid:{code:"validationFailed",retryable:false},device_cipher_unavailable:{code:"serviceUnavailable",retryable:true}});function K(e){return _e(e,Dr)}n(K,"refine");function H(e){return _("validationFailed",{retryable:false,wireMessage:`the Everfur runtime is disposed; ${e} was called after unmount`})}n(H,"disposed");function W(e){let r=n(()=>{let{services:t}=e.registry;return G({auth:t.authFor(null),...t.errorPolicy?{errorPolicy:t.errorPolicy}:{}})},"over");return {registerDevice:n((t,o)=>e.isDisposed?Promise.resolve(u(H("registerDevice"))):r().registerDevice(t,o),"registerDevice"),unregisterDevice:n((t,o)=>e.isDisposed?Promise.resolve(u(H("unregisterDevice"))):r().unregisterDevice(t,o),"unregisterDevice"),setPreferences:n((t,o)=>e.isDisposed?Promise.resolve(u(H("setPreferences"))):r().setPreferences(t,o),"setPreferences")}}n(W,"createNotificationsClient");function G(e){let r=e.funnel??j({auth:e.auth,...e.errorPolicy?{errorPolicy:e.errorPolicy}:{}}),t=n((o,i)=>i?{...o,signal:i}:o,"withSignal");return {async registerDevice(o,i){let a=xr(o);if(a!==null)return u(a);let s={token:o.token,provider:o.provider,platform:o.platform};o.installationId!==void 0&&(s.installation_id=o.installationId);let l=await r.send("notifications.registerDevice",t({method:"POST",path:"/widget/v1/me/devices",body:s},i?.signal));if(!l.ok)return u(K(l.error));let d=Nr(l.value);return d===null?u(Re("registerDevice")):T(d)},async unregisterDevice(o,i){let a=Fr(o);if(a!==null)return u(a);let s=await r.send("notifications.unregisterDevice",t({method:"DELETE",path:`/widget/v1/me/devices/${encodeURIComponent(o)}`},i?.signal));return s.ok?T(void 0):u(K(s.error))},async setPreferences(o,i){let a=Pr(o);if(a!==null)return u(a);let s=await r.send("notifications.setPreferences",t({method:"PUT",path:"/widget/v1/me/notification-preferences",body:{push_enabled:o.pushEnabled,email_enabled:o.emailEnabled}},i?.signal));if(!s.ok)return u(K(s.error));let l=Ar(s.value);return l===null?u(Re("setPreferences")):T(l)}}}n(G,"createNotificationsClientOver");var z="everfur.notifications.device";var Ie=Symbol.for("@everfur/sdk#EverfurContext@v1"),Oe=globalThis,ke=Oe[Ie]??(Oe[Ie]=react.createContext(null));ke.displayName??="EverfurContext";function $(){let e=react.useContext(ke);if(e===null)throw new x("not-initialized","Everfur hooks must be called inside <EverfurProvider>. Wrap your tree once, high.");return e}n($,"useEverfurContext");var De=1;async function X(e){try{let r=await e.getItem(z);if(r===null)return null;let t=JSON.parse(r);if(typeof t!="object"||t===null)return null;let{v:o,userRef:i,deviceId:a}=t;return o!==De||typeof i!="string"||typeof a!="string"||a.length===0?null:{userRef:i,deviceId:a}}catch{return null}}n(X,"readStored");async function Ur(e,r){try{await e.setItem(z,JSON.stringify({v:De,...r}));}catch{}}n(Ur,"writeStored");async function Fe(e){try{await e.removeItem(z);}catch{}}n(Fe,"clearStored");var Pe=Object.freeze({status:"signed_out",device:null,error:null}),Ne=Object.freeze({status:"no_token",device:null,error:null});function J(){return _("sessionRequired",{retryable:false,wireMessage:"notifications need a signed-in user on the provider"})}n(J,"noUser");function je(){let{runtime:e}=$();return react.useMemo(()=>W(e),[e])}n(je,"useEverfurNotificationsClient");function ze(e){let{runtime:r,userRef:t}=$(),{token:o,provider:i,platform:a,installationId:s}=e,l=r.registry.services.kv,d=je(),[h,w]=react.useState(t===null?Pe:Ne),g=react.useRef(null),v=react.useRef(0);react.useEffect(()=>{if(v.current+=1,g.current=null,w(t===null?Pe:Ne),t===null)return;let m=true;return X(l).then(f=>{if(!m||f===null||f.userRef!==t)return;let p=g.current;if(p===null){g.current=f;return}p.deviceId!==f.deviceId&&d.unregisterDevice(f.deviceId);}),()=>{m=false;}},[d,l,t]);let c=react.useCallback(async(m,f)=>{let p=v.current+=1;w({status:"registering",device:null,error:null});let y=await d.registerDevice({token:f,provider:i,platform:a,...s===void 0?{}:{installationId:s}});if(p!==v.current)return y;if(!y.ok)return w({status:y.error.httpStatus===404?"unavailable":"failed",device:null,error:y.error}),y;let E=g.current;return g.current={userRef:m,deviceId:y.value.deviceId},w({status:"registered",device:y.value,error:null}),await Ur(l,g.current),E!==null&&E.userRef===m&&E.deviceId!==y.value.deviceId&&d.unregisterDevice(E.deviceId),y},[d,l,i,a,s]);react.useEffect(()=>{t===null||o===null||c(t,o);},[c,t,o]),react.useEffect(()=>r.onBeforeLogout(async({userRef:m,auth:f})=>{let p=g.current??await X(l);if(p===null||p.userRef!==m)return;g.current=null;let y=j({auth:f,maxAttempts:1,unaryTimeoutMs:3e3,...r.registry.services.errorPolicy?{errorPolicy:r.registry.services.errorPolicy}:{}}),E=await G({auth:f,funnel:y}).unregisterDevice(p.deviceId);(E.ok||E.error.httpStatus===404)&&await Fe(l);}),[r,l]);let C=react.useCallback(async()=>t===null?u(J()):o===null?u(_("validationFailed",{retryable:false,reasonCode:"token_invalid",wireMessage:"no push token was given"})):c(t,o),[c,t,o]),S=react.useCallback(async()=>{if(t===null)return u(J());let m=g.current??await X(l);if(m===null||m.userRef!==t)return T(void 0);let f=v.current+=1,p=await d.unregisterDevice(m.deviceId);return p.ok||p.error.httpStatus===404?(g.current=null,await Fe(l),f===v.current&&w({status:"unregistered",device:null,error:null}),p.ok?p:T(void 0)):p},[d,l,t]),P=react.useCallback(m=>t===null?Promise.resolve(u(J())):d.setPreferences(m),[d,t]);return react.useMemo(()=>({status:h.status,device:h.device,error:h.error,register:C,unregister:S,setPreferences:P}),[h,C,S,P])}n(ze,"useEverfurNotifications");function Vr(e){let r=ze(e),{status:t,error:o,register:i}=r,a=t==="failed"&&o!==null&&o.retryable;return react.useEffect(()=>{if(!a)return;let s=reactNative.AppState.addEventListener("change",l=>{l==="active"&&i();});return ()=>{s.remove();}},[a,i]),r}n(Vr,"useEverfurNotifications");var Me=Object.freeze({"visit.booked":"visit","visit.reminder":"join","visit.rescheduled":"visit","visit.followup_sent":"messages","visit.message_received":"messages","visit.completed":"summary","visit.ended":"visit","visit.cancelled":null,"visit.no_show":null});function Ue(e){return Object.prototype.hasOwnProperty.call(Me,e)?Me[e]:"visit"}n(Ue,"vetVisitIntentForEvent");var qe=1,Ve=Object.freeze(["record_request","pet","visit","case"]),Be=Object.freeze(["record_request.updated","record.ready","pet.vaccination.due","visit.booked","visit.cancelled","visit.completed","visit.no_show","visit.rescheduled","visit.reminder","visit.followup_sent","visit.message_received","visit.ended","chat.follow_up_due","chat.reminder_due","record.activation"]),ee=["v","event_id","event_type","target"],Br=new Set(["kind","conversation_id","request_id","visit_ref","case_ref","pet_ref"]),Yr=new Set(Be),Kr=new Set(Ve),Hr=128,Wr=4096,Gr=/^evt_[A-Za-z0-9]{1,64}$/,$r=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,Qr=/[-]/;function O(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}n(O,"isRecord");function Ye(e){return Object.keys(e)}n(Ye,"keysOf");function Xr(e){if(O(e))return e;if(typeof e!="string"||e.length===0||e.length>Wr)return null;let r=JSON.parse(e);return O(r)?r:null}n(Xr,"decodeBlock");function Jr(e,r){let t=e;for(let o of r){if(!O(t))return;t=t[o];}return t}n(Jr,"at");var Zr=[[],["data"],["request","content","data"],["notification","request","content","data"]];function et(e){if(!O(e))return null;for(let r of Zr){let t=Jr(e,r);if(O(t)&&"everfur"in t)return t.everfur}return ee.every(r=>r in e)?e:null}n(et,"locateBlock");function re(e){return typeof e!="string"||e.length===0||e.length>Hr||Qr.test(e)||e.includes("://")||e.toLowerCase().startsWith("everfur")?null:e}n(re,"opaqueString");function Le(e,r){if(!(r in e))return {ok:true,value:null};let t=re(e[r]);return t===null?{ok:false}:{ok:true,value:t}}n(Le,"optional");function Z(e,r){return r in e?re(e[r]):null}n(Z,"required");function rt(e,r){if(!O(e))return null;let t=Ye(e);if(!t.includes("kind")||t.some(s=>!Br.has(s)))return null;let o=e.kind;if(typeof o!="string"||!Kr.has(o))return null;for(let s of t)if(s!=="kind"&&re(e[s])===null)return null;let i=Le(e,"pet_ref");if(!i.ok)return null;let a=i.value;switch(o){case "record_request":{let s=Z(e,"request_id");return s===null?null:Object.freeze({kind:"record_request",requestId:s,petRef:a})}case "pet":return a===null?null:Object.freeze({kind:"pet",petRef:a});case "visit":{let s=Z(e,"visit_ref");return s===null?null:Object.freeze({kind:"visit",visitRef:s,petRef:a,intent:Ue(r)})}case "case":{let s=Z(e,"case_ref");if(s===null)return null;let l=Le(e,"conversation_id");return !l.ok||l.value!==null&&!$r.test(l.value)?null:Object.freeze({kind:"case",caseRef:s,conversationId:l.value,petRef:a})}default:return null}}n(rt,"parseTarget");function tt(e){let r=Ye(e);if(r.length!==ee.length||ee.some(a=>!r.includes(a))||e.v!==qe)return null;let t=e.event_id;if(typeof t!="string"||!Gr.test(t))return null;let o=e.event_type;if(typeof o!="string"||!Yr.has(o))return null;let i=rt(e.target,o);return i===null?null:Object.freeze({eventId:t,eventType:o,target:i})}n(tt,"parseBlock");function nt(e){try{let r=Xr(et(e));return r===null?null:tt(r)}catch{return null}}n(nt,"parseEverfurNotification");
2
+ exports.EVERFUR_NOTIFICATION_EVENT_TYPES=Be;exports.EVERFUR_NOTIFICATION_TARGET_KINDS=Ve;exports.EVERFUR_NOTIFICATION_VERSION=qe;exports.NOTIFICATIONS_REASON_MESSAGES=we;exports.createNotificationsClient=W;exports.explainNotificationsReason=kr;exports.parseEverfurNotification=nt;exports.useEverfurNotifications=Vr;exports.useEverfurNotificationsClient=je;
@@ -0,0 +1,17 @@
1
+ import { EverfurNotificationsOptions, EverfurNotificationsState } from '../web/notifications/index.cjs';
2
+ export { DevicePlatform, EVERFUR_NOTIFICATION_EVENT_TYPES, EVERFUR_NOTIFICATION_TARGET_KINDS, EVERFUR_NOTIFICATION_VERSION, EverfurNotification, EverfurNotificationEventType, EverfurNotificationTarget, EverfurNotificationTargetKind, EverfurNotificationsStatus, NOTIFICATIONS_REASON_MESSAGES, NotificationPreferences, NotificationPreferencesInput, NotificationsClient, NotificationsReasonCode, NotificationsRuntime, PushProvider, RegisterDeviceInput, RegisteredDevice, createNotificationsClient, explainNotificationsReason, parseEverfurNotification, useEverfurNotificationsClient } from '../web/notifications/index.cjs';
3
+ export { V as VetVisitIntent } from '../visitIntent-D7_yVp1I.cjs';
4
+ export { A as AuthContext, I as IdentityProvider, M as MintedToken, T as TokenProvider } from '../identity-DI4eVx9S.cjs';
5
+ export { A as AcceptedFrame, a as AnalysisCompleteFrame, b as AnalysisStartedFrame, D as DeltaFrame, c as DoneFrame, E as ErrorFrame, d as EverfurRequest, e as EverfurRequestBase, F as Frame, f as FrameBase, g as FrameKind, H as HeartbeatFrame, h as HttpMethod, M as MultipartBody, T as TransportPort, U as UnknownFrame, i as UrgencyLevel } from '../config-CzTZGlfF.cjs';
6
+ export { B as Brand, C as ConversationId, P as PetRef, R as RecordsRequestId, U as UserRef, _ as __brand } from '../ids-B2GAAifq.cjs';
7
+ export { E as EverfurError, a as EverfurErrorCategory, b as EverfurErrorCode, c as EverfurResult } from '../EverfurResult-DN9pL2Ab.cjs';
8
+ export { E as ErrorPolicyPort } from '../ErrorPolicyPort-CNf4uQZP.cjs';
9
+
10
+ /**
11
+ * Register this install's push token for the signed-in member, keep it registered as the token and the user
12
+ * change, unregister it before sign-out, and retry a retryable failure on the next foreground. Call it once, high
13
+ * in the tree under `EverfurProvider`.
14
+ */
15
+ declare function useEverfurNotifications(options: EverfurNotificationsOptions): EverfurNotificationsState;
16
+
17
+ export { EverfurNotificationsOptions, EverfurNotificationsState, useEverfurNotifications };
@@ -0,0 +1,17 @@
1
+ import { EverfurNotificationsOptions, EverfurNotificationsState } from '../web/notifications/index.js';
2
+ export { DevicePlatform, EVERFUR_NOTIFICATION_EVENT_TYPES, EVERFUR_NOTIFICATION_TARGET_KINDS, EVERFUR_NOTIFICATION_VERSION, EverfurNotification, EverfurNotificationEventType, EverfurNotificationTarget, EverfurNotificationTargetKind, EverfurNotificationsStatus, NOTIFICATIONS_REASON_MESSAGES, NotificationPreferences, NotificationPreferencesInput, NotificationsClient, NotificationsReasonCode, NotificationsRuntime, PushProvider, RegisterDeviceInput, RegisteredDevice, createNotificationsClient, explainNotificationsReason, parseEverfurNotification, useEverfurNotificationsClient } from '../web/notifications/index.js';
3
+ export { V as VetVisitIntent } from '../visitIntent-D7_yVp1I.js';
4
+ export { A as AuthContext, I as IdentityProvider, M as MintedToken, T as TokenProvider } from '../identity-BMx2SUOM.js';
5
+ export { A as AcceptedFrame, a as AnalysisCompleteFrame, b as AnalysisStartedFrame, D as DeltaFrame, c as DoneFrame, E as ErrorFrame, d as EverfurRequest, e as EverfurRequestBase, F as Frame, f as FrameBase, g as FrameKind, H as HeartbeatFrame, h as HttpMethod, M as MultipartBody, T as TransportPort, U as UnknownFrame, i as UrgencyLevel } from '../config-DW60uRb9.js';
6
+ export { B as Brand, C as ConversationId, P as PetRef, R as RecordsRequestId, U as UserRef, _ as __brand } from '../ids-B2GAAifq.js';
7
+ export { E as EverfurError, a as EverfurErrorCategory, b as EverfurErrorCode, c as EverfurResult } from '../EverfurResult-DN9pL2Ab.js';
8
+ export { E as ErrorPolicyPort } from '../ErrorPolicyPort-CwbfmxzJ.js';
9
+
10
+ /**
11
+ * Register this install's push token for the signed-in member, keep it registered as the token and the user
12
+ * change, unregister it before sign-out, and retry a retryable failure on the next foreground. Call it once, high
13
+ * in the tree under `EverfurProvider`.
14
+ */
15
+ declare function useEverfurNotifications(options: EverfurNotificationsOptions): EverfurNotificationsState;
16
+
17
+ export { EverfurNotificationsOptions, EverfurNotificationsState, useEverfurNotifications };