@everfur/sdk 0.1.1 → 0.4.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.
- package/CHANGELOG.md +703 -4
- package/README.md +63 -23
- package/consent/package.json +8 -0
- package/dist/Chat-BZZ-Py5l.d.ts +128 -0
- package/dist/Chat-Dq4fffIO.d.cts +128 -0
- package/dist/DepthViews-BG3E25MD.d.ts +16 -0
- package/dist/DepthViews-B_hIypI6.d.cts +19 -0
- package/dist/DepthViews-CL75jyRA.d.cts +16 -0
- package/dist/DepthViews-CkYri51q.d.ts +19 -0
- package/dist/ErrorPolicyPort-CNf4uQZP.d.cts +22 -0
- package/dist/ErrorPolicyPort-CwbfmxzJ.d.ts +22 -0
- package/dist/{EverfurResult-D92-uL82.d.cts → EverfurResult-DN9pL2Ab.d.cts} +11 -10
- package/dist/{EverfurResult-D92-uL82.d.ts → EverfurResult-DN9pL2Ab.d.ts} +11 -10
- package/dist/{PhotoController-BItt5M7u.d.cts → PhotoController-3l7MT9jA.d.cts} +1 -1
- package/dist/{PhotoController-D8zMTdcW.d.ts → PhotoController-vzY5bfY_.d.ts} +1 -1
- package/dist/animations/index.cjs +1 -1997
- package/dist/animations/index.d.cts +35 -35
- package/dist/animations/index.d.ts +35 -35
- package/dist/animations/index.js +1 -1972
- package/dist/attachments-BorG422I.d.cts +146 -0
- package/dist/attachments-BrUWQYNK.d.ts +257 -0
- package/dist/attachments-D_SECjr1.d.cts +257 -0
- package/dist/attachments-DpldrvIW.d.ts +146 -0
- package/dist/bookingCopy-CqtDYvCR.d.ts +732 -0
- package/dist/bookingCopy-SREvkG19.d.cts +732 -0
- package/dist/branding-CsRdeNwK.d.cts +566 -0
- package/dist/branding-CsRdeNwK.d.ts +566 -0
- package/dist/callCopy-DoQKG3-L.d.cts +40 -0
- package/dist/callCopy-DoQKG3-L.d.ts +40 -0
- package/dist/casesRepository-DwtZVsbj.d.cts +51 -0
- package/dist/casesRepository-v6QczS9N.d.ts +51 -0
- package/dist/chat/index.cjs +1 -1170
- package/dist/chat/index.d.cts +32 -53
- package/dist/chat/index.d.ts +32 -53
- package/dist/chat/index.js +1 -1167
- package/dist/client/index.cjs +9 -2315
- package/dist/client/index.d.cts +80 -16
- package/dist/client/index.d.ts +80 -16
- package/dist/client/index.js +9 -2215
- package/dist/{config-CiJ0PVBB.d.ts → config--Wu1Umhd.d.cts} +64 -26
- package/dist/{config-BSjBdxrZ.d.cts → config-C7eb_IMD.d.ts} +64 -26
- package/dist/consent/index.cjs +1 -0
- package/dist/consent/index.d.cts +33 -0
- package/dist/consent/index.d.ts +33 -0
- package/dist/consent/index.js +1 -0
- package/dist/context-CL3lyuy1.d.cts +159 -0
- package/dist/context-CahAEha8.d.ts +159 -0
- package/dist/copy-DdVFDL01.d.ts +198 -0
- package/dist/copy-UeUJVk8X.d.cts +198 -0
- package/dist/core/index.cjs +13 -3178
- package/dist/core/index.d.cts +164 -29
- package/dist/core/index.d.ts +164 -29
- package/dist/core/index.js +13 -3166
- package/dist/depth-D5HwcvKC.d.cts +533 -0
- package/dist/depth-DvPwPuT_.d.ts +533 -0
- package/dist/entitlementRepository-B7egEdW6.d.ts +43 -0
- package/dist/entitlementRepository-BpJ7tiwl.d.cts +43 -0
- package/dist/{identity-Brl-lDd6.d.cts → identity-C2-08BZW.d.cts} +20 -7
- package/dist/{identity-DK9zORrG.d.ts → identity-CEi9GRFZ.d.ts} +20 -7
- package/dist/{ids-CJ1S6adf.d.cts → ids-B2GAAifq.d.cts} +1 -1
- package/dist/{ids-CJ1S6adf.d.ts → ids-B2GAAifq.d.ts} +1 -1
- package/dist/index.cjs +12 -4494
- package/dist/index.d.cts +30 -121
- package/dist/index.d.ts +30 -121
- package/dist/index.js +12 -4470
- package/dist/models-B-Uh2LTf.d.ts +214 -0
- package/dist/models-D2EUxPZY.d.cts +214 -0
- package/dist/notifications/index.cjs +2 -0
- package/dist/notifications/index.d.cts +17 -0
- package/dist/notifications/index.d.ts +17 -0
- package/dist/notifications/index.js +2 -0
- package/dist/optionalModule-DbJmsq5f.d.cts +21 -0
- package/dist/optionalModule-DbJmsq5f.d.ts +21 -0
- package/dist/pets-DJv2sj2H.d.ts +92 -0
- package/dist/pets-JVCXgRgR.d.cts +92 -0
- package/dist/petsRepository-B_gKbAzJ.d.cts +142 -0
- package/dist/petsRepository-Bk6GDwLs.d.ts +142 -0
- package/dist/photo/index.cjs +1 -2189
- package/dist/photo/index.d.cts +6 -6
- package/dist/photo/index.d.ts +6 -6
- package/dist/photo/index.js +1 -2186
- package/dist/ports-BN6RHF9W.d.cts +48 -0
- package/dist/ports-BN6RHF9W.d.ts +48 -0
- package/dist/ports-BY2ph0_y.d.cts +376 -0
- package/dist/ports-D7YW8qz9.d.ts +376 -0
- package/dist/profile-CSs1wlXT.d.cts +93 -0
- package/dist/profile-CSs1wlXT.d.ts +93 -0
- package/dist/records/depth/index.cjs +2 -0
- package/dist/records/depth/index.d.cts +13 -0
- package/dist/records/depth/index.d.ts +13 -0
- package/dist/records/depth/index.js +2 -0
- package/dist/records/index.cjs +3 -2839
- package/dist/records/index.d.cts +137 -203
- package/dist/records/index.d.ts +137 -203
- package/dist/records/index.js +3 -2833
- package/dist/requestFunnel-BjDpqqvm.d.cts +110 -0
- package/dist/requestFunnel-DFMGcluw.d.ts +110 -0
- package/dist/{resolve-Dq_4_agU.d.ts → resolve-D4Ywz5OS.d.cts} +10 -4
- package/dist/{resolve-Dq_4_agU.d.cts → resolve-D4Ywz5OS.d.ts} +10 -4
- package/dist/{runtime-Bvr8yqXm.d.cts → runtimeTypes-gZEJu-da.d.cts} +104 -132
- package/dist/{runtime-BIYzf9cK.d.ts → runtimeTypes-w5KqBMcs.d.ts} +104 -132
- package/dist/server/events/index.cjs +2 -0
- package/dist/server/events/index.d.cts +550 -0
- package/dist/server/events/index.d.ts +550 -0
- package/dist/server/events/index.js +2 -0
- package/dist/server/index.cjs +2 -533
- package/dist/server/index.d.cts +73 -18
- package/dist/server/index.d.ts +73 -18
- package/dist/server/index.js +2 -530
- package/dist/species-BXAIMh7I.d.cts +9 -0
- package/dist/species-BXAIMh7I.d.ts +9 -0
- package/dist/televet/booking/index.cjs +1 -0
- package/dist/televet/booking/index.d.cts +294 -0
- package/dist/televet/booking/index.d.ts +294 -0
- package/dist/televet/booking/index.js +1 -0
- package/dist/televet/call/index.cjs +1 -0
- package/dist/televet/call/index.d.cts +141 -0
- package/dist/televet/call/index.d.ts +141 -0
- package/dist/televet/call/index.js +1 -0
- package/dist/televet/index.cjs +1 -0
- package/dist/televet/index.d.cts +142 -0
- package/dist/televet/index.d.ts +142 -0
- package/dist/televet/index.js +1 -0
- package/dist/testing/index.cjs +5 -823
- package/dist/testing/index.d.cts +18 -4
- package/dist/testing/index.d.ts +18 -4
- package/dist/testing/index.js +5 -820
- package/dist/testing/rn/index.cjs +1 -449
- package/dist/testing/rn/index.d.cts +18 -29
- package/dist/testing/rn/index.d.ts +18 -29
- package/dist/testing/rn/index.js +1 -444
- package/dist/testing/web/index.cjs +1 -0
- package/dist/testing/web/index.d.cts +132 -0
- package/dist/testing/web/index.d.ts +132 -0
- package/dist/testing/web/index.js +1 -0
- package/dist/timelineRows-C15jxFFH.d.ts +19 -0
- package/dist/timelineRows-odO8g9r2.d.cts +19 -0
- package/dist/typeStyle-CKqVYD6L.d.cts +111 -0
- package/dist/typeStyle-DmoyacDG.d.ts +111 -0
- package/dist/uploadTransport-D0M0T4hN.d.ts +38 -0
- package/dist/uploadTransport-DKJHs3Yj.d.cts +38 -0
- package/dist/useRecordsDepth-C6rjEaLn.d.cts +237 -0
- package/dist/useRecordsDepth-crhBllQK.d.ts +237 -0
- package/dist/useVetVisit-Bc84hWUU.d.cts +187 -0
- package/dist/useVetVisit-CjmMa896.d.ts +187 -0
- package/dist/video/index.cjs +1 -1941
- package/dist/video/index.d.cts +4 -4
- package/dist/video/index.d.ts +4 -4
- package/dist/video/index.js +1 -1938
- package/dist/view-Bxwxp4xD.d.ts +310 -0
- package/dist/view-DyitEO0m.d.cts +310 -0
- package/dist/visitIntent-D7_yVp1I.d.cts +8 -0
- package/dist/visitIntent-D7_yVp1I.d.ts +8 -0
- package/dist/web/consent/index.cjs +1 -0
- package/dist/web/consent/index.d.cts +34 -0
- package/dist/web/consent/index.d.ts +34 -0
- package/dist/web/consent/index.js +1 -0
- package/dist/web/index.cjs +14 -0
- package/dist/web/index.d.cts +218 -0
- package/dist/web/index.d.ts +218 -0
- package/dist/web/index.js +14 -0
- package/dist/web/notifications/index.cjs +2 -0
- package/dist/web/notifications/index.d.cts +213 -0
- package/dist/web/notifications/index.d.ts +213 -0
- package/dist/web/notifications/index.js +2 -0
- package/dist/web/records/depth/index.cjs +2 -0
- package/dist/web/records/depth/index.d.cts +12 -0
- package/dist/web/records/depth/index.d.ts +12 -0
- package/dist/web/records/depth/index.js +2 -0
- package/dist/web/records/index.cjs +4 -0
- package/dist/web/records/index.d.cts +285 -0
- package/dist/web/records/index.d.ts +285 -0
- package/dist/web/records/index.js +4 -0
- package/dist/web/televet/booking/index.cjs +1 -0
- package/dist/web/televet/booking/index.d.cts +349 -0
- package/dist/web/televet/booking/index.d.ts +349 -0
- package/dist/web/televet/booking/index.js +1 -0
- package/dist/web/televet/call/index.cjs +1 -0
- package/dist/web/televet/call/index.d.cts +142 -0
- package/dist/web/televet/call/index.d.ts +142 -0
- package/dist/web/televet/call/index.js +1 -0
- package/dist/web/televet/index.cjs +1 -0
- package/dist/web/televet/index.d.cts +136 -0
- package/dist/web/televet/index.d.ts +136 -0
- package/dist/web/televet/index.js +1 -0
- package/notifications/package.json +8 -0
- package/package.json +266 -10
- package/records/depth/package.json +8 -0
- package/server/events/device-blocked.cjs +15 -0
- package/server/events/package.json +9 -0
- package/televet/booking/package.json +8 -0
- package/televet/call/package.json +8 -0
- package/televet/package.json +8 -0
- package/testing/web/native-blocked.cjs +12 -0
- package/testing/web/package.json +8 -0
- package/web/consent/native-blocked.cjs +12 -0
- package/web/consent/package.json +8 -0
- package/web/native-blocked.cjs +12 -0
- package/web/notifications/native-blocked.cjs +12 -0
- package/web/notifications/package.json +8 -0
- package/web/package.json +8 -0
- package/web/records/depth/native-blocked.cjs +12 -0
- package/web/records/depth/package.json +8 -0
- package/web/records/native-blocked.cjs +12 -0
- package/web/records/package.json +8 -0
- package/web/televet/booking/native-blocked.cjs +12 -0
- package/web/televet/booking/package.json +8 -0
- package/web/televet/call/native-blocked.cjs +12 -0
- package/web/televet/call/package.json +8 -0
- package/web/televet/native-blocked.cjs +12 -0
- package/web/televet/package.json +8 -0
- package/dist/ChatController-CKdBvPj2.d.ts +0 -146
- package/dist/ChatController-CpUMvvZf.d.cts +0 -146
- package/dist/FilePort-BabWrv7I.d.cts +0 -22
- package/dist/FilePort-BabWrv7I.d.ts +0 -22
- package/dist/petsRepository-BEGb97M9.d.cts +0 -326
- package/dist/petsRepository-Bu18r2kK.d.ts +0 -326
- package/dist/requestFunnel-DuUH-kAe.d.cts +0 -28
- package/dist/requestFunnel-dio5OmR9.d.ts +0 -28
|
@@ -1,1997 +1 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var react = require('react');
|
|
4
|
-
var reactNative = require('react-native');
|
|
5
|
-
require('react-native-safe-area-context');
|
|
6
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
7
|
-
var zod = require('zod');
|
|
8
|
-
|
|
9
|
-
// src/rn/animations/PetStateView.tsx
|
|
10
|
-
|
|
11
|
-
// src/client/protocol/frames.ts
|
|
12
|
-
function assertNever(x) {
|
|
13
|
-
throw new Error(
|
|
14
|
-
`assertNever: unhandled discriminated-union member ${JSON.stringify(x)}`
|
|
15
|
-
);
|
|
16
|
-
}
|
|
17
|
-
function errorFrame(fields) {
|
|
18
|
-
return Object.freeze({
|
|
19
|
-
kind: "error",
|
|
20
|
-
terminal: true,
|
|
21
|
-
code: fields.code,
|
|
22
|
-
retryable: fields.retryable,
|
|
23
|
-
wireMessage: fields.wireMessage,
|
|
24
|
-
synthesized: fields.synthesized,
|
|
25
|
-
lastEventId: fields.lastEventId,
|
|
26
|
-
serverRequestId: null
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// src/client/theme/tokens.ts
|
|
31
|
-
function deepFreeze(value) {
|
|
32
|
-
if (value !== null && typeof value === "object" && !Object.isFrozen(value)) {
|
|
33
|
-
Object.freeze(value);
|
|
34
|
-
for (const key of Object.keys(value)) {
|
|
35
|
-
deepFreeze(value[key]);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
return value;
|
|
39
|
-
}
|
|
40
|
-
var SPACE = { xs: 4, sm: 8, md: 12, lg: 16, xl: 24, xxl: 32 };
|
|
41
|
-
var RADIUS = { tile: 5, xs: 6, sm: 10, md: 14, lg: 20, xl: 28, pill: 500 };
|
|
42
|
-
var TYPE_SIZE = {
|
|
43
|
-
nano: 8,
|
|
44
|
-
small: 9,
|
|
45
|
-
micro: 10,
|
|
46
|
-
tiny: 11,
|
|
47
|
-
caption: 12,
|
|
48
|
-
bodyTight: 13,
|
|
49
|
-
body: 14,
|
|
50
|
-
subtitle: 16,
|
|
51
|
-
heading: 18,
|
|
52
|
-
verdict: 24
|
|
53
|
-
};
|
|
54
|
-
var LINE_HEIGHT = { tight: 1.15, snug: 1.3, normal: 1.4, relaxed: 1.55 };
|
|
55
|
-
var WEIGHT = { regular: "400", medium: "500", bold: "700" };
|
|
56
|
-
var LETTER_SPACING = {
|
|
57
|
-
eyebrow: 1,
|
|
58
|
-
monoWide: 0.9,
|
|
59
|
-
headerBrand: -0.42,
|
|
60
|
-
tight: -0.35
|
|
61
|
-
};
|
|
62
|
-
function baseType() {
|
|
63
|
-
return {
|
|
64
|
-
family: "System",
|
|
65
|
-
mono: "monospace",
|
|
66
|
-
fontUrl: null,
|
|
67
|
-
size: TYPE_SIZE,
|
|
68
|
-
lineHeight: LINE_HEIGHT,
|
|
69
|
-
weight: WEIGHT,
|
|
70
|
-
letterSpacing: LETTER_SPACING
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
var MOTION = {
|
|
74
|
-
duration: { instant: 80, fast: 140, normal: 220, slow: 320 },
|
|
75
|
-
spring: { gentle: { damping: 18, stiffness: 200 } },
|
|
76
|
-
easing: { standard: "cubic-bezier(0.4, 0, 0.2, 1)" },
|
|
77
|
-
reducedMotion: false
|
|
78
|
-
};
|
|
79
|
-
var LIGHT_COLOR = {
|
|
80
|
-
brand: "#10462E",
|
|
81
|
-
brandSoft: "rgba(16,70,46,0.10)",
|
|
82
|
-
brandSofter: "rgba(16,70,46,0.15)",
|
|
83
|
-
brandBorder: "rgba(16,70,46,0.18)",
|
|
84
|
-
borderHairlineGreen: "rgba(16,70,46,0.25)",
|
|
85
|
-
surface: "#FFFFFF",
|
|
86
|
-
surfaceCream: "#FDFBF8",
|
|
87
|
-
surfaceSubtle: "#EFE9E3",
|
|
88
|
-
background: "#FFFFFF",
|
|
89
|
-
borderRingCream: "#D8D2C8",
|
|
90
|
-
text: {
|
|
91
|
-
primary: "#111111",
|
|
92
|
-
secondary: "#0E462E",
|
|
93
|
-
muted: "#6E6660",
|
|
94
|
-
placeholder: "rgba(0,0,0,0.30)",
|
|
95
|
-
onBrand: "#FFFFFF",
|
|
96
|
-
metaCool: "#3D3D3D"
|
|
97
|
-
},
|
|
98
|
-
primary: "#10462E",
|
|
99
|
-
onPrimary: "#FFFFFF",
|
|
100
|
-
accent: "#10462E",
|
|
101
|
-
onAccent: "#FFFFFF",
|
|
102
|
-
accentEdge: "#07C168",
|
|
103
|
-
success: "#07C168",
|
|
104
|
-
danger: "#B91C1C",
|
|
105
|
-
errorRed: "#FF1B00",
|
|
106
|
-
warningStrong: "#A45610",
|
|
107
|
-
cautionAccent: "#D9821D",
|
|
108
|
-
riskConcern: "#EFA700",
|
|
109
|
-
badgeBgPositive: "rgba(7,193,104,0.12)",
|
|
110
|
-
badgeBgCaution: "rgba(217,130,29,0.14)",
|
|
111
|
-
badgeBgCritical: "rgba(185,28,28,0.12)",
|
|
112
|
-
badgeBgNeutral: "rgba(110,102,96,0.12)",
|
|
113
|
-
bubbleUser: "#10462E",
|
|
114
|
-
bubbleAssistant: "#FFFFFF",
|
|
115
|
-
skeleton: "#EFE9E3",
|
|
116
|
-
scanButtonPink: "#FFC3BC",
|
|
117
|
-
checkupCardLowRiskBg: "rgba(7,193,104,0.10)",
|
|
118
|
-
checkupCardConcernBg: "rgba(239,167,0,0.10)"
|
|
119
|
-
};
|
|
120
|
-
var EVERFUR_LIGHT = deepFreeze({
|
|
121
|
-
brightness: "light",
|
|
122
|
-
meta: { displayName: "Everfur", logoUrl: null, placeholder: null, hidePoweredBy: false },
|
|
123
|
-
color: LIGHT_COLOR,
|
|
124
|
-
space: SPACE,
|
|
125
|
-
radius: RADIUS,
|
|
126
|
-
type: baseType(),
|
|
127
|
-
motion: MOTION
|
|
128
|
-
});
|
|
129
|
-
var DARK_COLOR = {
|
|
130
|
-
brand: "#6BD39A",
|
|
131
|
-
brandSoft: "rgba(107,211,154,0.12)",
|
|
132
|
-
brandSofter: "rgba(107,211,154,0.18)",
|
|
133
|
-
brandBorder: "rgba(107,211,154,0.22)",
|
|
134
|
-
borderHairlineGreen: "rgba(107,211,154,0.28)",
|
|
135
|
-
surface: "#1C1F23",
|
|
136
|
-
surfaceCream: "#23272C",
|
|
137
|
-
surfaceSubtle: "#23272C",
|
|
138
|
-
background: "#15171A",
|
|
139
|
-
borderRingCream: "#3A3F45",
|
|
140
|
-
text: {
|
|
141
|
-
primary: "#F5F3F0",
|
|
142
|
-
secondary: "#A9E4C4",
|
|
143
|
-
muted: "#9A938C",
|
|
144
|
-
placeholder: "rgba(255,255,255,0.35)",
|
|
145
|
-
onBrand: "#0E1F17",
|
|
146
|
-
metaCool: "#C9C9C9"
|
|
147
|
-
},
|
|
148
|
-
primary: "#6BD39A",
|
|
149
|
-
onPrimary: "#0E1F17",
|
|
150
|
-
accent: "#6BD39A",
|
|
151
|
-
onAccent: "#0E1F17",
|
|
152
|
-
accentEdge: "#34D888",
|
|
153
|
-
success: "#07C168",
|
|
154
|
-
danger: "#B91C1C",
|
|
155
|
-
errorRed: "#FF1B00",
|
|
156
|
-
warningStrong: "#A45610",
|
|
157
|
-
cautionAccent: "#D9821D",
|
|
158
|
-
riskConcern: "#EFA700",
|
|
159
|
-
badgeBgPositive: "rgba(7,193,104,0.18)",
|
|
160
|
-
badgeBgCaution: "rgba(217,130,29,0.20)",
|
|
161
|
-
badgeBgCritical: "rgba(185,28,28,0.22)",
|
|
162
|
-
badgeBgNeutral: "rgba(255,255,255,0.10)",
|
|
163
|
-
bubbleUser: "#6BD39A",
|
|
164
|
-
bubbleAssistant: "#1C1F23",
|
|
165
|
-
skeleton: "#23272C",
|
|
166
|
-
scanButtonPink: "#FFC3BC",
|
|
167
|
-
checkupCardLowRiskBg: "rgba(7,193,104,0.16)",
|
|
168
|
-
checkupCardConcernBg: "rgba(239,167,0,0.16)"
|
|
169
|
-
};
|
|
170
|
-
deepFreeze({
|
|
171
|
-
brightness: "dark",
|
|
172
|
-
meta: { displayName: "Everfur", logoUrl: null, placeholder: null, hidePoweredBy: false },
|
|
173
|
-
color: DARK_COLOR,
|
|
174
|
-
space: SPACE,
|
|
175
|
-
radius: RADIUS,
|
|
176
|
-
type: baseType(),
|
|
177
|
-
motion: MOTION
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
// src/client/errors/EverfurResult.ts
|
|
181
|
-
function ok(value, warning) {
|
|
182
|
-
return Object.freeze(
|
|
183
|
-
{ ok: true, value }
|
|
184
|
-
);
|
|
185
|
-
}
|
|
186
|
-
function err(error) {
|
|
187
|
-
return Object.freeze({ ok: false, error });
|
|
188
|
-
}
|
|
189
|
-
var EverfurConfigError = class _EverfurConfigError extends Error {
|
|
190
|
-
constructor(kind, message) {
|
|
191
|
-
super(message);
|
|
192
|
-
this.name = "EverfurConfigError";
|
|
193
|
-
this.kind = kind;
|
|
194
|
-
Object.setPrototypeOf(this, _EverfurConfigError.prototype);
|
|
195
|
-
}
|
|
196
|
-
};
|
|
197
|
-
|
|
198
|
-
// src/core/ports/TelemetryPort.ts
|
|
199
|
-
var noopTelemetry = Object.freeze({
|
|
200
|
-
track() {
|
|
201
|
-
},
|
|
202
|
-
trackExpectedFailure() {
|
|
203
|
-
}
|
|
204
|
-
});
|
|
205
|
-
var CONTRACT_RETRYABILITY = Object.freeze([
|
|
206
|
-
Object.freeze({ wireCode: "AccessDeniedException", envelope: "http_envelope", httpStatus: 403, retryable: false }),
|
|
207
|
-
Object.freeze({ wireCode: "AuthorizationException", envelope: "http_envelope", httpStatus: 401, retryable: false }),
|
|
208
|
-
Object.freeze({ wireCode: "ConflictException", envelope: "http_envelope", httpStatus: 409, retryable: true }),
|
|
209
|
-
Object.freeze({ wireCode: "DAILY_QUOTA_EXCEEDED", envelope: "http_envelope", httpStatus: 429, retryable: true }),
|
|
210
|
-
Object.freeze({ wireCode: "IDEMPOTENCY_KEY_IN_FLIGHT", envelope: "http_envelope", httpStatus: 409, retryable: true }),
|
|
211
|
-
Object.freeze({ wireCode: "IDEMPOTENCY_KEY_REUSED_DIFFERENT_REQUEST", envelope: "http_envelope", httpStatus: 409, retryable: false }),
|
|
212
|
-
Object.freeze({ wireCode: "InternalFailureException", envelope: "http_envelope", httpStatus: 500, retryable: true }),
|
|
213
|
-
Object.freeze({ wireCode: "NotImplementedException", envelope: "http_envelope", httpStatus: 501, retryable: false }),
|
|
214
|
-
Object.freeze({ wireCode: "PaymentRequiredException", envelope: "http_envelope", httpStatus: 402, retryable: false }),
|
|
215
|
-
Object.freeze({ wireCode: "ResourceNotFoundException", envelope: "http_envelope", httpStatus: 404, retryable: false }),
|
|
216
|
-
Object.freeze({ wireCode: "ServiceUnavailableException", envelope: "http_envelope", httpStatus: 503, retryable: true }),
|
|
217
|
-
Object.freeze({ wireCode: "TIER_UPGRADE_REQUIRED", envelope: "http_envelope", httpStatus: 402, retryable: false }),
|
|
218
|
-
Object.freeze({ wireCode: "ThrottlingException", envelope: "http_envelope", httpStatus: 429, retryable: true }),
|
|
219
|
-
Object.freeze({ wireCode: "ValidationException", envelope: "http_envelope", httpStatus: 400, retryable: false }),
|
|
220
|
-
Object.freeze({ wireCode: "accessDenied", envelope: "http_envelope", httpStatus: 403, retryable: false }),
|
|
221
|
-
Object.freeze({ wireCode: "authExpired", envelope: "http_envelope", httpStatus: 401, retryable: true }),
|
|
222
|
-
Object.freeze({ wireCode: "internal_error", envelope: "sse_frame", httpStatus: 200, retryable: false }),
|
|
223
|
-
Object.freeze({ wireCode: "invalidRequest", envelope: "http_envelope", httpStatus: 400, retryable: false }),
|
|
224
|
-
Object.freeze({ wireCode: "not_found", envelope: "sse_frame", httpStatus: 200, retryable: false }),
|
|
225
|
-
Object.freeze({ wireCode: "session_required", envelope: "http_envelope", httpStatus: 403, retryable: false }),
|
|
226
|
-
Object.freeze({ wireCode: "timeout", envelope: "sse_frame", httpStatus: 200, retryable: true }),
|
|
227
|
-
Object.freeze({ wireCode: "unavailable", envelope: "http_envelope", httpStatus: 503, retryable: true })
|
|
228
|
-
]);
|
|
229
|
-
Object.freeze(
|
|
230
|
-
CONTRACT_RETRYABILITY.map((row) => row.wireCode)
|
|
231
|
-
);
|
|
232
|
-
|
|
233
|
-
// src/client/errors/contract.ts
|
|
234
|
-
var NORMALIZED_FOLD = Object.freeze({
|
|
235
|
-
// the default status-mapped envelope
|
|
236
|
-
ValidationException: "validationFailed",
|
|
237
|
-
AuthorizationException: "authRejected",
|
|
238
|
-
PaymentRequiredException: "paymentRequired",
|
|
239
|
-
AccessDeniedException: "accessDenied",
|
|
240
|
-
ResourceNotFoundException: "resourceNotFound",
|
|
241
|
-
ConflictException: "conflict",
|
|
242
|
-
ThrottlingException: "rateLimited",
|
|
243
|
-
InternalFailureException: "internalError",
|
|
244
|
-
NotImplementedException: "notImplemented",
|
|
245
|
-
ServiceUnavailableException: "serviceUnavailable",
|
|
246
|
-
// dict-detail codes on the widget surface
|
|
247
|
-
authExpired: "authExpired",
|
|
248
|
-
unavailable: "serviceUnavailable",
|
|
249
|
-
session_required: "sessionRequired",
|
|
250
|
-
accessDenied: "accessDenied",
|
|
251
|
-
invalidRequest: "sdkUpdateRequired",
|
|
252
|
-
// typed codes
|
|
253
|
-
IDEMPOTENCY_KEY_IN_FLIGHT: "idempotencyInFlight",
|
|
254
|
-
IDEMPOTENCY_KEY_REUSED_DIFFERENT_REQUEST: "idempotencyConflict",
|
|
255
|
-
DAILY_QUOTA_EXCEEDED: "quotaExceeded",
|
|
256
|
-
TIER_UPGRADE_REQUIRED: "paymentRequired",
|
|
257
|
-
// SSE error frames
|
|
258
|
-
not_found: "conversationNotFound",
|
|
259
|
-
timeout: "streamTimeout",
|
|
260
|
-
internal_error: "internalError"
|
|
261
|
-
});
|
|
262
|
-
var CONTRACT_ERROR_ROWS = Object.freeze(
|
|
263
|
-
CONTRACT_RETRYABILITY.map(
|
|
264
|
-
(generated) => Object.freeze({
|
|
265
|
-
wireCode: generated.wireCode,
|
|
266
|
-
envelope: generated.envelope,
|
|
267
|
-
retryable: generated.retryable,
|
|
268
|
-
normalized: NORMALIZED_FOLD[generated.wireCode]
|
|
269
|
-
})
|
|
270
|
-
)
|
|
271
|
-
);
|
|
272
|
-
var BY_UPPER = new Map(
|
|
273
|
-
CONTRACT_ERROR_ROWS.map((r) => [r.wireCode.toUpperCase(), r])
|
|
274
|
-
);
|
|
275
|
-
function contractErrorFor(wireCode) {
|
|
276
|
-
if (typeof wireCode !== "string") return void 0;
|
|
277
|
-
const key = wireCode.trim().toUpperCase();
|
|
278
|
-
return key.length > 0 ? BY_UPPER.get(key) : void 0;
|
|
279
|
-
}
|
|
280
|
-
var CATEGORY_OF = Object.freeze({
|
|
281
|
-
// the caller's sign-in state is wrong and a credential change is the remedy
|
|
282
|
-
authExpired: "authentication",
|
|
283
|
-
authRejected: "authentication",
|
|
284
|
-
sessionRequired: "authentication",
|
|
285
|
-
// signed in, correctly identified, and still not allowed
|
|
286
|
-
accessDenied: "authorization",
|
|
287
|
-
// a plan gate, not a permission failure: the remedy is commercial
|
|
288
|
-
paymentRequired: "entitlement",
|
|
289
|
-
// slow down / come back later
|
|
290
|
-
quotaExceeded: "rateLimit",
|
|
291
|
-
rateLimited: "rateLimit",
|
|
292
|
-
// the request itself was wrong; retrying it unchanged can never succeed
|
|
293
|
-
validationFailed: "invalidRequest",
|
|
294
|
-
sdkUpdateRequired: "invalidRequest",
|
|
295
|
-
// the target is gone, hidden, or was never visible to this caller
|
|
296
|
-
conversationNotFound: "notFound",
|
|
297
|
-
petNotFound: "notFound",
|
|
298
|
-
resourceNotFound: "notFound",
|
|
299
|
-
// something else already holds the thing
|
|
300
|
-
conflict: "conflict",
|
|
301
|
-
idempotencyConflict: "conflict",
|
|
302
|
-
idempotencyInFlight: "conflict",
|
|
303
|
-
// the pipe, not the request: timeouts, drops, a briefly unreachable dependency
|
|
304
|
-
streamTimeout: "connection",
|
|
305
|
-
streamIncomplete: "connection",
|
|
306
|
-
upstreamLlmTimeout: "connection",
|
|
307
|
-
serviceUnavailable: "connection",
|
|
308
|
-
// the server admits fault
|
|
309
|
-
internalError: "server",
|
|
310
|
-
notImplemented: "server",
|
|
311
|
-
mediaUploadFailed: "media",
|
|
312
|
-
moderationBlocked: "policy",
|
|
313
|
-
unknown: "unknown"
|
|
314
|
-
});
|
|
315
|
-
function categoryFor(code) {
|
|
316
|
-
return CATEGORY_OF[code];
|
|
317
|
-
}
|
|
318
|
-
function fromWire(wire) {
|
|
319
|
-
const contractRow = contractErrorFor(wire);
|
|
320
|
-
if (contractRow) return contractRow.normalized;
|
|
321
|
-
const upper = (wire ?? "").trim().toUpperCase();
|
|
322
|
-
const canonical = upper.replace(/[^A-Z0-9]/g, "");
|
|
323
|
-
if (canonical === "AUTHREJECTED") return "authRejected";
|
|
324
|
-
if (upper.startsWith("AUTH")) return "authExpired";
|
|
325
|
-
switch (canonical) {
|
|
326
|
-
case "DAILYQUOTAEXCEEDED":
|
|
327
|
-
case "QUOTAEXCEEDED":
|
|
328
|
-
return "quotaExceeded";
|
|
329
|
-
case "RATELIMITED":
|
|
330
|
-
case "TOOMANYREQUESTS":
|
|
331
|
-
return "rateLimited";
|
|
332
|
-
case "IDEMPOTENCYKEYCONFLICT":
|
|
333
|
-
case "IDEMPOTENCYCONFLICT":
|
|
334
|
-
return "idempotencyConflict";
|
|
335
|
-
case "ACCESSDENIED":
|
|
336
|
-
case "FORBIDDEN":
|
|
337
|
-
return "accessDenied";
|
|
338
|
-
case "NOTFOUND":
|
|
339
|
-
case "CONVERSATIONNOTFOUND":
|
|
340
|
-
return "conversationNotFound";
|
|
341
|
-
case "PETNOTFOUND":
|
|
342
|
-
return "petNotFound";
|
|
343
|
-
case "TIMEOUT":
|
|
344
|
-
case "STREAMTIMEOUT":
|
|
345
|
-
return "streamTimeout";
|
|
346
|
-
// Analysis-domain deterministic 400s (NON-retryable). Additive per SPEC-00 §3.1 / SPEC-11b §2.6:
|
|
347
|
-
// fold to a NON-retried target so the SDK never retries a permanently-failing bad-input request.
|
|
348
|
-
// (Comment above the group so the empty fall-through cases stay lint-clean under no-fallthrough.)
|
|
349
|
-
case "MEDIAUPLOADFAILED":
|
|
350
|
-
case "UNRECOGNIZEDVIDEOFORMAT":
|
|
351
|
-
case "FILETOOSMALL":
|
|
352
|
-
return "mediaUploadFailed";
|
|
353
|
-
case "MODERATIONBLOCKED":
|
|
354
|
-
return "moderationBlocked";
|
|
355
|
-
case "UPSTREAMLLMTIMEOUT":
|
|
356
|
-
return "upstreamLlmTimeout";
|
|
357
|
-
case "INTERNALERROR":
|
|
358
|
-
case "INTERNALSERVERERROR":
|
|
359
|
-
return "internalError";
|
|
360
|
-
case "STREAMINCOMPLETE":
|
|
361
|
-
case "CHATSTREAMINCOMPLETE":
|
|
362
|
-
return "streamIncomplete";
|
|
363
|
-
// Deterministic 400s that can only come from an SDK bug -> unknown (NON-retryable). NEVER internalError
|
|
364
|
-
// (which IS auto-retried): mapping a bad-input 400 to a retryable code retries a request that never succeeds.
|
|
365
|
-
case "INVALIDANALYSISTYPE":
|
|
366
|
-
case "INVALIDUPLOADPURPOSE":
|
|
367
|
-
return "unknown";
|
|
368
|
-
default:
|
|
369
|
-
return "unknown";
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
var AUTO_RETRYABLE_CODES = /* @__PURE__ */ new Set([
|
|
373
|
-
"streamTimeout",
|
|
374
|
-
"rateLimited",
|
|
375
|
-
"internalError",
|
|
376
|
-
"upstreamLlmTimeout",
|
|
377
|
-
"streamIncomplete"
|
|
378
|
-
]);
|
|
379
|
-
function isAutoRetryable(code) {
|
|
380
|
-
return AUTO_RETRYABLE_CODES.has(code);
|
|
381
|
-
}
|
|
382
|
-
var RETRYABLE_CONTRACT_CODES = /* @__PURE__ */ new Set([
|
|
383
|
-
"serviceUnavailable",
|
|
384
|
-
"conflict",
|
|
385
|
-
"idempotencyInFlight"
|
|
386
|
-
]);
|
|
387
|
-
function isRetryableCode(code) {
|
|
388
|
-
return isAutoRetryable(code) || RETRYABLE_CONTRACT_CODES.has(code);
|
|
389
|
-
}
|
|
390
|
-
var BACKOFF_BASE_MS = 500;
|
|
391
|
-
var BACKOFF_CAP_MS = 8e3;
|
|
392
|
-
var MAX_RETRY_ATTEMPTS = 4;
|
|
393
|
-
function backoffDelayMs(attempt, rng = Math.random) {
|
|
394
|
-
const bounded = Math.max(0, attempt);
|
|
395
|
-
const ceiling = Math.min(BACKOFF_BASE_MS * 2 ** bounded, BACKOFF_CAP_MS);
|
|
396
|
-
return Math.floor(rng() * ceiling);
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
// src/client/errors/EverfurError.ts
|
|
400
|
-
var USER_FACING_COPY = Object.freeze({
|
|
401
|
-
authExpired: "Please sign in again to continue.",
|
|
402
|
-
authRejected: "Please sign in again to continue.",
|
|
403
|
-
sessionRequired: "This app needs to be updated to keep using Everfur.",
|
|
404
|
-
accessDenied: "This feature isn't available on your account right now.",
|
|
405
|
-
paymentRequired: "This is part of a paid plan.",
|
|
406
|
-
quotaExceeded: "You have used today's messages. This resets tomorrow.",
|
|
407
|
-
rateLimited: "You are sending messages quickly. Try again in a few seconds.",
|
|
408
|
-
validationFailed: "Something in that request was not right. Check the details and try again.",
|
|
409
|
-
sdkUpdateRequired: "This app needs to be updated to keep using Everfur.",
|
|
410
|
-
conflict: "That is already running. Wait for it to finish, then try again.",
|
|
411
|
-
idempotencyConflict: "That message was already delivered.",
|
|
412
|
-
idempotencyInFlight: "That is still processing. Give it a moment.",
|
|
413
|
-
conversationNotFound: "This conversation is no longer available.",
|
|
414
|
-
petNotFound: "We could not find that pet. Please pick a pet and try again.",
|
|
415
|
-
resourceNotFound: "We could not find that.",
|
|
416
|
-
streamTimeout: "The response timed out. Tap retry to try again.",
|
|
417
|
-
mediaUploadFailed: "We could not upload that photo. Please attach it again.",
|
|
418
|
-
moderationBlocked: "This request cannot be answered here.",
|
|
419
|
-
upstreamLlmTimeout: "The response timed out. Tap retry to try again.",
|
|
420
|
-
internalError: "We hit a snag on our end. Please try again.",
|
|
421
|
-
notImplemented: "That is not available yet.",
|
|
422
|
-
serviceUnavailable: "That service is briefly unavailable. Try again shortly.",
|
|
423
|
-
streamIncomplete: "The connection dropped mid-answer. Tap retry to continue.",
|
|
424
|
-
unknown: "Something went wrong. Please try again."
|
|
425
|
-
});
|
|
426
|
-
function userFacingError(code) {
|
|
427
|
-
return USER_FACING_COPY[code];
|
|
428
|
-
}
|
|
429
|
-
function defineHidden(target, key, value) {
|
|
430
|
-
Object.defineProperty(target, key, {
|
|
431
|
-
value,
|
|
432
|
-
enumerable: false,
|
|
433
|
-
writable: false,
|
|
434
|
-
configurable: false
|
|
435
|
-
});
|
|
436
|
-
}
|
|
437
|
-
function makeEverfurError(code, opts) {
|
|
438
|
-
contractErrorFor(opts?.wireCode);
|
|
439
|
-
const error = {
|
|
440
|
-
code,
|
|
441
|
-
category: categoryFor(code),
|
|
442
|
-
retryable: opts?.retryable ?? isRetryableCode(code),
|
|
443
|
-
displayMessage: userFacingError(code)
|
|
444
|
-
};
|
|
445
|
-
if (opts?.httpStatus !== void 0) error.httpStatus = opts.httpStatus;
|
|
446
|
-
if (opts?.requestId) error.requestId = opts.requestId;
|
|
447
|
-
if (opts?.wireMessage) defineHidden(error, "wireMessage", opts.wireMessage);
|
|
448
|
-
if (opts?.raw !== void 0 && opts.raw !== null) defineHidden(error, "raw", opts.raw);
|
|
449
|
-
return Object.freeze(error);
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
// src/client/identity.ts
|
|
453
|
-
function newSessionId() {
|
|
454
|
-
const bytes = new Uint8Array(16);
|
|
455
|
-
const cryptoObj = globalThis.crypto;
|
|
456
|
-
if (typeof cryptoObj?.getRandomValues === "function") {
|
|
457
|
-
cryptoObj.getRandomValues(bytes);
|
|
458
|
-
} else {
|
|
459
|
-
for (let i = 0; i < bytes.length; i += 1) bytes[i] = Math.floor(Math.random() * 256);
|
|
460
|
-
}
|
|
461
|
-
bytes[6] = bytes[6] & 15 | 64;
|
|
462
|
-
bytes[8] = bytes[8] & 63 | 128;
|
|
463
|
-
const hex = [];
|
|
464
|
-
for (let i = 0; i < bytes.length; i += 1) hex.push(bytes[i].toString(16).padStart(2, "0"));
|
|
465
|
-
return hex.slice(0, 4).join("") + "-" + hex.slice(4, 6).join("") + "-" + hex.slice(6, 8).join("") + "-" + hex.slice(8, 10).join("") + "-" + hex.slice(10, 16).join("");
|
|
466
|
-
}
|
|
467
|
-
function authHeaders(auth) {
|
|
468
|
-
const headers = {};
|
|
469
|
-
if (auth.mode === "personalized") {
|
|
470
|
-
headers.authorization = `Bearer ${auth.token}`;
|
|
471
|
-
} else {
|
|
472
|
-
headers["x-everfur-partner-key"] = auth.publishableKey;
|
|
473
|
-
}
|
|
474
|
-
if (auth.userRef) headers["x-everfur-user-ref"] = auth.userRef;
|
|
475
|
-
if (auth.sessionId) headers["x-everfur-session-id"] = auth.sessionId;
|
|
476
|
-
return headers;
|
|
477
|
-
}
|
|
478
|
-
function withAuthHeaders(req, auth) {
|
|
479
|
-
return { ...req, headers: { ...stripAuthHeaders(req.headers), ...authHeaders(auth) } };
|
|
480
|
-
}
|
|
481
|
-
function stripAuthHeaders(headers) {
|
|
482
|
-
if (!headers) return {};
|
|
483
|
-
const out = {};
|
|
484
|
-
for (const [key, value] of Object.entries(headers)) {
|
|
485
|
-
const lower = key.toLowerCase();
|
|
486
|
-
if (lower === "authorization" || lower === "x-everfur-partner-key") continue;
|
|
487
|
-
out[key] = value;
|
|
488
|
-
}
|
|
489
|
-
return out;
|
|
490
|
-
}
|
|
491
|
-
async function authedSend(req, ctx) {
|
|
492
|
-
if (ctx.mode === "anonymous") {
|
|
493
|
-
return ctx.transport.request(
|
|
494
|
-
withAuthHeaders(req, {
|
|
495
|
-
mode: "anonymous",
|
|
496
|
-
publishableKey: ctx.publishableKey,
|
|
497
|
-
userRef: ctx.userRef,
|
|
498
|
-
...ctx.sessionId ? { sessionId: ctx.sessionId } : {}
|
|
499
|
-
})
|
|
500
|
-
);
|
|
501
|
-
}
|
|
502
|
-
let token;
|
|
503
|
-
try {
|
|
504
|
-
token = await ctx.identity.currentToken();
|
|
505
|
-
} catch {
|
|
506
|
-
return err(authRejectedError());
|
|
507
|
-
}
|
|
508
|
-
const first = await ctx.transport.request(
|
|
509
|
-
withAuthHeaders(req, {
|
|
510
|
-
mode: "personalized",
|
|
511
|
-
token,
|
|
512
|
-
userRef: ctx.userRef,
|
|
513
|
-
...ctx.sessionId ? { sessionId: ctx.sessionId } : {}
|
|
514
|
-
})
|
|
515
|
-
);
|
|
516
|
-
if (first.ok || first.error.httpStatus !== 401) return first;
|
|
517
|
-
let refreshed;
|
|
518
|
-
try {
|
|
519
|
-
refreshed = await ctx.identity.currentToken({ forceRefresh: true });
|
|
520
|
-
} catch {
|
|
521
|
-
return err(authRejectedError());
|
|
522
|
-
}
|
|
523
|
-
const retry = await ctx.transport.request(
|
|
524
|
-
withAuthHeaders(req, {
|
|
525
|
-
mode: "personalized",
|
|
526
|
-
token: refreshed,
|
|
527
|
-
userRef: ctx.userRef,
|
|
528
|
-
...ctx.sessionId ? { sessionId: ctx.sessionId } : {}
|
|
529
|
-
})
|
|
530
|
-
);
|
|
531
|
-
if (!retry.ok && retry.error.httpStatus === 401) {
|
|
532
|
-
return err(authRejectedError(retry.error.httpStatus));
|
|
533
|
-
}
|
|
534
|
-
return retry;
|
|
535
|
-
}
|
|
536
|
-
function authRejectedError(httpStatus) {
|
|
537
|
-
return makeEverfurError("authRejected", {
|
|
538
|
-
retryable: false,
|
|
539
|
-
...httpStatus !== void 0 ? { httpStatus } : {}
|
|
540
|
-
});
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
// src/client/transport.ts
|
|
544
|
-
function networkError(cause) {
|
|
545
|
-
return makeEverfurError("internalError", { retryable: true, wireMessage: describeCause(cause) });
|
|
546
|
-
}
|
|
547
|
-
function describeCause(cause) {
|
|
548
|
-
if (cause instanceof Error) return cause.message;
|
|
549
|
-
return typeof cause === "string" ? cause : "network request failed";
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
// src/client/funnel/requestFunnel.ts
|
|
553
|
-
var FUNNEL_UNARY_TIMEOUT_MS = 3e4;
|
|
554
|
-
var RETRY_OVERRIDE_MAX_MS = BACKOFF_CAP_MS * 2;
|
|
555
|
-
var IDEMPOTENCY_HEADER = "idempotency-key";
|
|
556
|
-
var MUTATING_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"]);
|
|
557
|
-
var NOOP_OBSERVER = Object.freeze({
|
|
558
|
-
onEvent() {
|
|
559
|
-
}
|
|
560
|
-
});
|
|
561
|
-
var defaultFunnelTimers = Object.freeze({
|
|
562
|
-
setTimeout: (handler, ms) => setTimeout(handler, ms),
|
|
563
|
-
clearTimeout: (handle) => clearTimeout(handle),
|
|
564
|
-
now: () => Date.now()
|
|
565
|
-
});
|
|
566
|
-
function createRequestFunnel(deps) {
|
|
567
|
-
const observer = deps.observer ?? NOOP_OBSERVER;
|
|
568
|
-
const timers = deps.timers ?? defaultFunnelTimers;
|
|
569
|
-
const rng = deps.rng ?? Math.random;
|
|
570
|
-
const sleep = deps.sleep ?? ((ms, signal) => delayAbortable(ms, timers, signal));
|
|
571
|
-
const ceiling = deps.maxAttempts ?? MAX_RETRY_ATTEMPTS;
|
|
572
|
-
const timeoutMs = deps.unaryTimeoutMs ?? FUNNEL_UNARY_TIMEOUT_MS;
|
|
573
|
-
const mintKey = deps.newIdempotencyKey ?? defaultIdempotencyKeyFactory();
|
|
574
|
-
const emit = (event) => {
|
|
575
|
-
try {
|
|
576
|
-
observer.onEvent(event);
|
|
577
|
-
} catch {
|
|
578
|
-
}
|
|
579
|
-
};
|
|
580
|
-
async function send(call, req, opts) {
|
|
581
|
-
const perCallMaxAttempts = opts?.maxAttempts;
|
|
582
|
-
const maxAttempts = Math.max(1, perCallMaxAttempts ?? ceiling);
|
|
583
|
-
const idempotent = opts?.idempotent ?? MUTATING_METHODS.has(req.method);
|
|
584
|
-
const idempotencyKey = idempotent ? mintKey() : null;
|
|
585
|
-
const base = assembleHeaders(req, idempotencyKey);
|
|
586
|
-
let attempt = 0;
|
|
587
|
-
for (; ; ) {
|
|
588
|
-
const stamp = (extra) => Object.freeze({
|
|
589
|
-
call,
|
|
590
|
-
method: req.method,
|
|
591
|
-
path: req.path,
|
|
592
|
-
attempt,
|
|
593
|
-
...idempotencyKey ? { idempotencyKey } : {},
|
|
594
|
-
...extra
|
|
595
|
-
});
|
|
596
|
-
emit(stamp({ phase: "attempt" }));
|
|
597
|
-
const deadline = boundedSignal(timeoutMs, timers);
|
|
598
|
-
const merged = mergeSignals(deadline.signal, req.signal);
|
|
599
|
-
let settled;
|
|
600
|
-
try {
|
|
601
|
-
settled = await authedSend({ ...base, signal: merged.signal }, deps.auth);
|
|
602
|
-
} catch (cause) {
|
|
603
|
-
settled = err(networkError(cause));
|
|
604
|
-
} finally {
|
|
605
|
-
merged.dispose();
|
|
606
|
-
deadline.cancel();
|
|
607
|
-
}
|
|
608
|
-
if (settled.ok) {
|
|
609
|
-
emit(stamp({ phase: "settled", ok: true, reason: "ok" }));
|
|
610
|
-
return settled;
|
|
611
|
-
}
|
|
612
|
-
const error = settled.error;
|
|
613
|
-
const decision = decideRetry(error, attempt, {
|
|
614
|
-
maxAttempts,
|
|
615
|
-
rng,
|
|
616
|
-
now: timers.now(),
|
|
617
|
-
aborted: req.signal?.aborted === true,
|
|
618
|
-
...perCallMaxAttempts !== void 0 ? { perCallMaxAttempts } : {},
|
|
619
|
-
...deps.errorPolicy !== void 0 ? { policy: deps.errorPolicy } : {}
|
|
620
|
-
});
|
|
621
|
-
const settledEvent = {
|
|
622
|
-
ok: false,
|
|
623
|
-
code: error.code,
|
|
624
|
-
reason: decision.reason,
|
|
625
|
-
...error.httpStatus !== void 0 ? { httpStatus: error.httpStatus } : {},
|
|
626
|
-
...error.requestId !== void 0 ? { requestId: error.requestId } : {}
|
|
627
|
-
};
|
|
628
|
-
if (!decision.retry) {
|
|
629
|
-
emit(stamp({ phase: "settled", ...settledEvent }));
|
|
630
|
-
return err(error);
|
|
631
|
-
}
|
|
632
|
-
emit(stamp({ phase: "retry", ...settledEvent, delayMs: decision.delayMs }));
|
|
633
|
-
await sleep(decision.delayMs, req.signal);
|
|
634
|
-
if (req.signal?.aborted === true) {
|
|
635
|
-
emit(stamp({ phase: "settled", ...settledEvent, reason: "aborted" }));
|
|
636
|
-
return err(error);
|
|
637
|
-
}
|
|
638
|
-
attempt += 1;
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
async function authorize(req) {
|
|
642
|
-
return withAuthHeaders(req, await resolveDeviceAuth(deps.auth));
|
|
643
|
-
}
|
|
644
|
-
async function* stream(call, req, signal) {
|
|
645
|
-
emit(
|
|
646
|
-
Object.freeze({
|
|
647
|
-
call,
|
|
648
|
-
phase: "stream.open",
|
|
649
|
-
method: req.method,
|
|
650
|
-
path: req.path,
|
|
651
|
-
attempt: 0
|
|
652
|
-
})
|
|
653
|
-
);
|
|
654
|
-
try {
|
|
655
|
-
yield* deps.auth.transport.stream(req, signal);
|
|
656
|
-
} catch {
|
|
657
|
-
yield errorFrame({
|
|
658
|
-
// The same wire spelling sse.ts synthesizes, so `fromWire` folds it to the retryable `internalError`
|
|
659
|
-
// like any other transport failure. wireMessage stays null: it is the SERVER's text, and a thrown
|
|
660
|
-
// host exception's `.message` is not that.
|
|
661
|
-
code: "internal_error",
|
|
662
|
-
retryable: true,
|
|
663
|
-
wireMessage: null,
|
|
664
|
-
synthesized: true,
|
|
665
|
-
lastEventId: null});
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
return Object.freeze({ send, authorize, stream });
|
|
669
|
-
}
|
|
670
|
-
function assembleHeaders(req, idempotencyKey) {
|
|
671
|
-
const headers = {};
|
|
672
|
-
for (const [key, value] of Object.entries(req.headers ?? {})) {
|
|
673
|
-
if (key.toLowerCase() === IDEMPOTENCY_HEADER) continue;
|
|
674
|
-
headers[key] = value;
|
|
675
|
-
}
|
|
676
|
-
if (idempotencyKey !== null) headers["Idempotency-Key"] = idempotencyKey;
|
|
677
|
-
return { ...req, headers };
|
|
678
|
-
}
|
|
679
|
-
function defaultIdempotencyKeyFactory() {
|
|
680
|
-
let counter = 0;
|
|
681
|
-
return () => `efk_${Date.now().toString(36)}_${(counter++).toString(36)}_${Math.random().toString(36).slice(2, 12)}`;
|
|
682
|
-
}
|
|
683
|
-
var POLICY_MAX_ATTEMPTS_CAP = 10;
|
|
684
|
-
function decideRetry(error, attempt, ctx) {
|
|
685
|
-
if (ctx.aborted) return { retry: false, reason: "aborted" };
|
|
686
|
-
const throttle = throttleKind(error);
|
|
687
|
-
if (throttle === "quota") {
|
|
688
|
-
return { retry: false, reason: "daily-quota-exhausted" };
|
|
689
|
-
}
|
|
690
|
-
if (throttle !== "burst" && !isAutoRetryable(error.code)) {
|
|
691
|
-
return { retry: false, reason: "terminal-code" };
|
|
692
|
-
}
|
|
693
|
-
const reason = throttle === "burst" ? "burst-throttle" : "retryable-code";
|
|
694
|
-
const policyVetoedRetry = () => {
|
|
695
|
-
if (ctx.policy === void 0) return false;
|
|
696
|
-
try {
|
|
697
|
-
return !ctx.policy.shouldRetry(error.code, attempt);
|
|
698
|
-
} catch {
|
|
699
|
-
return false;
|
|
700
|
-
}
|
|
701
|
-
};
|
|
702
|
-
if (policyVetoedRetry()) return { retry: false, reason: "terminal-code" };
|
|
703
|
-
const policyCeiling = () => {
|
|
704
|
-
if (ctx.policy === void 0) return null;
|
|
705
|
-
let raw;
|
|
706
|
-
try {
|
|
707
|
-
raw = ctx.policy.maxAttempts(error.code);
|
|
708
|
-
} catch {
|
|
709
|
-
return null;
|
|
710
|
-
}
|
|
711
|
-
if (typeof raw !== "number" || !Number.isFinite(raw)) return null;
|
|
712
|
-
return Math.max(1, Math.min(POLICY_MAX_ATTEMPTS_CAP, Math.floor(raw)));
|
|
713
|
-
};
|
|
714
|
-
const ceiling = ctx.perCallMaxAttempts ?? policyCeiling() ?? ctx.maxAttempts;
|
|
715
|
-
if (attempt + 1 >= ceiling) return { retry: false, reason: "attempts-exhausted" };
|
|
716
|
-
const override = retryOverrideMs(error, ctx.now);
|
|
717
|
-
if (override !== null) {
|
|
718
|
-
if (override > RETRY_OVERRIDE_MAX_MS) {
|
|
719
|
-
return { retry: false, reason: "server-reset-beyond-budget" };
|
|
720
|
-
}
|
|
721
|
-
return { retry: true, reason, delayMs: override };
|
|
722
|
-
}
|
|
723
|
-
return { retry: true, reason, delayMs: backoffDelayMs(attempt, ctx.rng) };
|
|
724
|
-
}
|
|
725
|
-
function throttleKind(error) {
|
|
726
|
-
const code = error.code === "unknown" ? fromWire(rawWireCode(error.raw)) : error.code;
|
|
727
|
-
if (code === "quotaExceeded") return "quota";
|
|
728
|
-
if (code === "rateLimited") return "burst";
|
|
729
|
-
if (error.httpStatus === 429) {
|
|
730
|
-
return "burst";
|
|
731
|
-
}
|
|
732
|
-
return null;
|
|
733
|
-
}
|
|
734
|
-
function retryOverrideMs(error, now) {
|
|
735
|
-
const at = findResetsAt(error.raw);
|
|
736
|
-
if (at === null) return null;
|
|
737
|
-
const delta = at - now;
|
|
738
|
-
return delta > 0 ? delta : 0;
|
|
739
|
-
}
|
|
740
|
-
function findResetsAt(raw) {
|
|
741
|
-
for (const scope of candidateScopes(raw)) {
|
|
742
|
-
const value = scope["resets_at"];
|
|
743
|
-
const parsed = parseInstantMs(value);
|
|
744
|
-
if (parsed !== null) return parsed;
|
|
745
|
-
}
|
|
746
|
-
return null;
|
|
747
|
-
}
|
|
748
|
-
function candidateScopes(raw) {
|
|
749
|
-
if (!isRecord(raw)) return [];
|
|
750
|
-
const out = [raw];
|
|
751
|
-
for (const nested of ["error", "detail"]) {
|
|
752
|
-
const value = raw[nested];
|
|
753
|
-
if (isRecord(value)) out.push(value);
|
|
754
|
-
}
|
|
755
|
-
return out;
|
|
756
|
-
}
|
|
757
|
-
function parseInstantMs(value) {
|
|
758
|
-
if (typeof value === "number" && Number.isFinite(value)) {
|
|
759
|
-
return value < 1e11 ? Math.round(value * 1e3) : Math.round(value);
|
|
760
|
-
}
|
|
761
|
-
if (typeof value === "string" && value.trim().length > 0) {
|
|
762
|
-
const parsed = Date.parse(value);
|
|
763
|
-
return Number.isFinite(parsed) ? parsed : null;
|
|
764
|
-
}
|
|
765
|
-
return null;
|
|
766
|
-
}
|
|
767
|
-
function rawWireCode(raw) {
|
|
768
|
-
for (const scope of candidateScopes(raw)) {
|
|
769
|
-
const code = scope["code"];
|
|
770
|
-
if (typeof code === "string" && code.length > 0) return code;
|
|
771
|
-
}
|
|
772
|
-
return null;
|
|
773
|
-
}
|
|
774
|
-
function isRecord(value) {
|
|
775
|
-
return typeof value === "object" && value !== null;
|
|
776
|
-
}
|
|
777
|
-
async function resolveDeviceAuth(auth) {
|
|
778
|
-
if (auth.mode === "anonymous") {
|
|
779
|
-
return {
|
|
780
|
-
mode: "anonymous",
|
|
781
|
-
publishableKey: auth.publishableKey,
|
|
782
|
-
userRef: auth.userRef,
|
|
783
|
-
...auth.sessionId ? { sessionId: auth.sessionId } : {}
|
|
784
|
-
};
|
|
785
|
-
}
|
|
786
|
-
return {
|
|
787
|
-
mode: "personalized",
|
|
788
|
-
token: await auth.identity.currentToken(),
|
|
789
|
-
userRef: auth.userRef,
|
|
790
|
-
...auth.sessionId ? { sessionId: auth.sessionId } : {}
|
|
791
|
-
};
|
|
792
|
-
}
|
|
793
|
-
function boundedSignal(ms, timers) {
|
|
794
|
-
const ctrl = new AbortController();
|
|
795
|
-
const handle = timers.setTimeout(() => ctrl.abort(), ms);
|
|
796
|
-
return { signal: ctrl.signal, cancel: () => timers.clearTimeout(handle) };
|
|
797
|
-
}
|
|
798
|
-
function mergeSignals(deadline, caller) {
|
|
799
|
-
const noop = () => void 0;
|
|
800
|
-
if (!caller) return { signal: deadline, dispose: noop };
|
|
801
|
-
const ctrl = new AbortController();
|
|
802
|
-
if (deadline.aborted || caller.aborted) {
|
|
803
|
-
ctrl.abort();
|
|
804
|
-
return { signal: ctrl.signal, dispose: noop };
|
|
805
|
-
}
|
|
806
|
-
const onAbort = () => ctrl.abort();
|
|
807
|
-
deadline.addEventListener("abort", onAbort, { once: true });
|
|
808
|
-
caller.addEventListener("abort", onAbort, { once: true });
|
|
809
|
-
return {
|
|
810
|
-
signal: ctrl.signal,
|
|
811
|
-
dispose: () => {
|
|
812
|
-
deadline.removeEventListener("abort", onAbort);
|
|
813
|
-
caller.removeEventListener("abort", onAbort);
|
|
814
|
-
}
|
|
815
|
-
};
|
|
816
|
-
}
|
|
817
|
-
function delayAbortable(ms, timers, signal) {
|
|
818
|
-
if (ms <= 0 || signal?.aborted === true) return Promise.resolve();
|
|
819
|
-
return new Promise((resolve) => {
|
|
820
|
-
const handle = timers.setTimeout(() => {
|
|
821
|
-
signal?.removeEventListener("abort", onAbort);
|
|
822
|
-
resolve();
|
|
823
|
-
}, ms);
|
|
824
|
-
const onAbort = () => {
|
|
825
|
-
timers.clearTimeout(handle);
|
|
826
|
-
resolve();
|
|
827
|
-
};
|
|
828
|
-
signal?.addEventListener("abort", onAbort, { once: true });
|
|
829
|
-
});
|
|
830
|
-
}
|
|
831
|
-
|
|
832
|
-
// src/client/text.ts
|
|
833
|
-
function hasLoneSurrogate(value) {
|
|
834
|
-
for (let i = 0; i < value.length; i += 1) {
|
|
835
|
-
const code = value.charCodeAt(i);
|
|
836
|
-
if (code >= 55296 && code <= 56319) {
|
|
837
|
-
const low = value.charCodeAt(i + 1);
|
|
838
|
-
if (!(low >= 56320 && low <= 57343)) return true;
|
|
839
|
-
i += 1;
|
|
840
|
-
} else if (code >= 56320 && code <= 57343) {
|
|
841
|
-
return true;
|
|
842
|
-
}
|
|
843
|
-
}
|
|
844
|
-
return false;
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
// src/client/entitlements/resolve.ts
|
|
848
|
-
var REQUIRES = Object.freeze({
|
|
849
|
-
chat: Object.freeze(["chat.message.create"]),
|
|
850
|
-
records: Object.freeze(["records.upload.create", "records.record.read"]),
|
|
851
|
-
video: Object.freeze(["video.gait.execute"]),
|
|
852
|
-
photo: Object.freeze(["photo.checkup.execute"]),
|
|
853
|
-
animations: Object.freeze(["animations.state.read"])
|
|
854
|
-
});
|
|
855
|
-
function requires(name) {
|
|
856
|
-
return REQUIRES[name];
|
|
857
|
-
}
|
|
858
|
-
function decideCapability(name, decisions, opts) {
|
|
859
|
-
if (opts?.isPending === true) {
|
|
860
|
-
return freezeDecision({ name, enabled: false, isPending: true, limits: {} });
|
|
861
|
-
}
|
|
862
|
-
const keys = requires(name);
|
|
863
|
-
const byResource = /* @__PURE__ */ new Map();
|
|
864
|
-
for (const decision of decisions) byResource.set(decision.resource, decision);
|
|
865
|
-
const limits = mergeLimits(keys, byResource);
|
|
866
|
-
const missing = keys.filter((key) => byResource.get(key)?.granted !== true);
|
|
867
|
-
if (missing.length === 0) {
|
|
868
|
-
return freezeDecision({ name, enabled: true, isPending: false, limits });
|
|
869
|
-
}
|
|
870
|
-
return freezeDecision({
|
|
871
|
-
name,
|
|
872
|
-
enabled: false,
|
|
873
|
-
isPending: false,
|
|
874
|
-
limits,
|
|
875
|
-
disabled: disabledFor(keys, byResource)
|
|
876
|
-
});
|
|
877
|
-
}
|
|
878
|
-
function mergeLimits(keys, byResource) {
|
|
879
|
-
const out = {};
|
|
880
|
-
for (const key of keys) {
|
|
881
|
-
const decisionLimits = byResource.get(key)?.limits;
|
|
882
|
-
if (!decisionLimits) continue;
|
|
883
|
-
for (const [limitKey, limitValue] of Object.entries(decisionLimits)) {
|
|
884
|
-
const existing = out[limitKey];
|
|
885
|
-
out[limitKey] = existing === void 0 ? limitValue : Math.min(existing, limitValue);
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
|
-
return out;
|
|
889
|
-
}
|
|
890
|
-
function disabledFor(keys, byResource) {
|
|
891
|
-
for (const key of keys) {
|
|
892
|
-
const explicit = byResource.get(key)?.disabled;
|
|
893
|
-
if (explicit) {
|
|
894
|
-
return Object.freeze({
|
|
895
|
-
reason: explicit.reason,
|
|
896
|
-
level: explicit.level,
|
|
897
|
-
recoverable: explicit.recoverable
|
|
898
|
-
});
|
|
899
|
-
}
|
|
900
|
-
}
|
|
901
|
-
return Object.freeze({
|
|
902
|
-
reason: userFacingError("accessDenied"),
|
|
903
|
-
level: "user_entitlement",
|
|
904
|
-
recoverable: false
|
|
905
|
-
});
|
|
906
|
-
}
|
|
907
|
-
function freezeDecision(d) {
|
|
908
|
-
const base = {
|
|
909
|
-
name: d.name,
|
|
910
|
-
enabled: d.enabled,
|
|
911
|
-
isPending: d.isPending,
|
|
912
|
-
limits: Object.freeze({ ...d.limits })
|
|
913
|
-
};
|
|
914
|
-
if (d.disabled !== void 0) base.disabled = d.disabled;
|
|
915
|
-
return Object.freeze(base);
|
|
916
|
-
}
|
|
917
|
-
|
|
918
|
-
// src/rn/facade.ts
|
|
919
|
-
var EVERFUR_CONTEXT_SYMBOL = /* @__PURE__ */ Symbol.for("@everfur/sdk#EverfurContext@v1");
|
|
920
|
-
var globalContextHost = globalThis;
|
|
921
|
-
var EverfurContext = globalContextHost[EVERFUR_CONTEXT_SYMBOL] ?? (globalContextHost[EVERFUR_CONTEXT_SYMBOL] = react.createContext(null));
|
|
922
|
-
EverfurContext.displayName ??= "EverfurContext";
|
|
923
|
-
function useEverfurContext() {
|
|
924
|
-
const ctx = react.useContext(EverfurContext);
|
|
925
|
-
if (ctx === null) {
|
|
926
|
-
throw new EverfurConfigError(
|
|
927
|
-
"not-initialized",
|
|
928
|
-
"Everfur hooks must be called inside <EverfurProvider>. Wrap your tree once, high."
|
|
929
|
-
);
|
|
930
|
-
}
|
|
931
|
-
return ctx;
|
|
932
|
-
}
|
|
933
|
-
var EVERFUR_THEME_CONTEXT_SYMBOL = /* @__PURE__ */ Symbol.for("@everfur/sdk#EverfurThemeContext@v1");
|
|
934
|
-
var globalThemeHost = globalThis;
|
|
935
|
-
var EverfurThemeContext = globalThemeHost[EVERFUR_THEME_CONTEXT_SYMBOL] ?? (globalThemeHost[EVERFUR_THEME_CONTEXT_SYMBOL] = react.createContext(EVERFUR_LIGHT));
|
|
936
|
-
EverfurThemeContext.displayName ??= "EverfurThemeContext";
|
|
937
|
-
function useEverfurTheme() {
|
|
938
|
-
return react.useContext(EverfurThemeContext);
|
|
939
|
-
}
|
|
940
|
-
function useCapability(name) {
|
|
941
|
-
const { runtime } = useEverfurContext();
|
|
942
|
-
const store = runtime.entitlements;
|
|
943
|
-
const snapshot = react.useSyncExternalStore(
|
|
944
|
-
store.subscribe,
|
|
945
|
-
store.getSnapshot,
|
|
946
|
-
store.getSnapshot
|
|
947
|
-
);
|
|
948
|
-
return react.useMemo(
|
|
949
|
-
() => decideCapability(name, snapshot.decisions, { isPending: snapshot.isPending }),
|
|
950
|
-
[name, snapshot]
|
|
951
|
-
);
|
|
952
|
-
}
|
|
953
|
-
var MIN_OFFSTATE_HEIGHT = 48;
|
|
954
|
-
function selectView(decision) {
|
|
955
|
-
if (decision.isPending) return "pending";
|
|
956
|
-
return decision.enabled ? "enabled" : "disabled";
|
|
957
|
-
}
|
|
958
|
-
function CapabilityGate(props) {
|
|
959
|
-
const { capability, children, renderDisabled, renderPending, style } = props;
|
|
960
|
-
const decision = useCapability(capability);
|
|
961
|
-
const view = react.useMemo(() => selectView(decision), [decision]);
|
|
962
|
-
switch (view) {
|
|
963
|
-
case "enabled":
|
|
964
|
-
return children;
|
|
965
|
-
case "pending":
|
|
966
|
-
return renderPending ? renderPending() : /* @__PURE__ */ jsxRuntime.jsx(PendingSkeleton, { capability, style });
|
|
967
|
-
case "disabled":
|
|
968
|
-
return renderDisabled ? renderDisabled(decision) : /* @__PURE__ */ jsxRuntime.jsx(OffState, { decision, style });
|
|
969
|
-
default:
|
|
970
|
-
return assertNever(view);
|
|
971
|
-
}
|
|
972
|
-
}
|
|
973
|
-
function PendingSkeleton({
|
|
974
|
-
capability,
|
|
975
|
-
style
|
|
976
|
-
}) {
|
|
977
|
-
const theme = useEverfurTheme();
|
|
978
|
-
const styles = react.useMemo(() => makeStyles(theme), [theme]);
|
|
979
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
980
|
-
reactNative.View,
|
|
981
|
-
{
|
|
982
|
-
style: [styles.offstate, style],
|
|
983
|
-
accessible: true,
|
|
984
|
-
accessibilityState: { busy: true },
|
|
985
|
-
accessibilityLabel: `Loading ${capability}`,
|
|
986
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles.skeletonBar })
|
|
987
|
-
}
|
|
988
|
-
);
|
|
989
|
-
}
|
|
990
|
-
function OffState({
|
|
991
|
-
decision,
|
|
992
|
-
style
|
|
993
|
-
}) {
|
|
994
|
-
const theme = useEverfurTheme();
|
|
995
|
-
const styles = react.useMemo(() => makeStyles(theme), [theme]);
|
|
996
|
-
const message = decision.disabled?.reason ?? "";
|
|
997
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
998
|
-
reactNative.View,
|
|
999
|
-
{
|
|
1000
|
-
style: [styles.offstate, style],
|
|
1001
|
-
accessible: true,
|
|
1002
|
-
accessibilityRole: "text",
|
|
1003
|
-
accessibilityLabel: message,
|
|
1004
|
-
children: message.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles.offstateText, children: message }) : null
|
|
1005
|
-
}
|
|
1006
|
-
);
|
|
1007
|
-
}
|
|
1008
|
-
function makeStyles(theme) {
|
|
1009
|
-
const { color, space, radius, type } = theme;
|
|
1010
|
-
return reactNative.StyleSheet.create({
|
|
1011
|
-
// A deliberate cream card with a soft brand hairline, never a bare grey slab.
|
|
1012
|
-
offstate: {
|
|
1013
|
-
minHeight: MIN_OFFSTATE_HEIGHT,
|
|
1014
|
-
justifyContent: "center",
|
|
1015
|
-
paddingHorizontal: space.lg,
|
|
1016
|
-
paddingVertical: space.md,
|
|
1017
|
-
backgroundColor: color.surfaceCream,
|
|
1018
|
-
borderRadius: radius.md,
|
|
1019
|
-
borderWidth: reactNative.StyleSheet.hairlineWidth,
|
|
1020
|
-
borderColor: color.brandBorder
|
|
1021
|
-
},
|
|
1022
|
-
offstateText: {
|
|
1023
|
-
fontFamily: type.family,
|
|
1024
|
-
fontSize: type.size.body,
|
|
1025
|
-
lineHeight: Math.round(type.size.body * type.lineHeight.normal),
|
|
1026
|
-
color: color.text.muted
|
|
1027
|
-
},
|
|
1028
|
-
// A soft green shimmer bar (brand wash) that stays legible on the cream card in both light and dark,
|
|
1029
|
-
// where the neutral `skeleton` token would collide with the dark cream surface.
|
|
1030
|
-
skeletonBar: {
|
|
1031
|
-
height: space.md,
|
|
1032
|
-
borderRadius: radius.xs,
|
|
1033
|
-
backgroundColor: color.brandSofter
|
|
1034
|
-
}
|
|
1035
|
-
});
|
|
1036
|
-
}
|
|
1037
|
-
|
|
1038
|
-
// src/client/animations/types.ts
|
|
1039
|
-
function mapTier(wire) {
|
|
1040
|
-
const tier = {
|
|
1041
|
-
url: wire.url,
|
|
1042
|
-
kind: wire.kind,
|
|
1043
|
-
expiresAt: wire.expires_at
|
|
1044
|
-
};
|
|
1045
|
-
if (typeof wire.loop_duration_ms === "number") tier.loopDurationMs = wire.loop_duration_ms;
|
|
1046
|
-
if (typeof wire.cache_key === "string" && wire.cache_key.length > 0) tier.cacheKey = wire.cache_key;
|
|
1047
|
-
return Object.freeze(tier);
|
|
1048
|
-
}
|
|
1049
|
-
function mapPetStateResponse(wire) {
|
|
1050
|
-
const tiers = {};
|
|
1051
|
-
if (wire.tiers.animation) tiers.animation = mapTier(wire.tiers.animation);
|
|
1052
|
-
if (wire.tiers.image) tiers.image = mapTier(wire.tiers.image);
|
|
1053
|
-
const overlays = {};
|
|
1054
|
-
if (wire.overlays.weather_alert) overlays.weatherAlert = mapTier(wire.overlays.weather_alert);
|
|
1055
|
-
const response = {
|
|
1056
|
-
category: wire.category,
|
|
1057
|
-
tiers: Object.freeze(tiers),
|
|
1058
|
-
overlays: Object.freeze(overlays),
|
|
1059
|
-
idle: "bundled",
|
|
1060
|
-
ttlSeconds: wire.ttl_seconds,
|
|
1061
|
-
degraded: wire.degraded
|
|
1062
|
-
};
|
|
1063
|
-
if (typeof wire.cache_epoch === "number") response.cacheEpoch = wire.cache_epoch;
|
|
1064
|
-
return Object.freeze(response);
|
|
1065
|
-
}
|
|
1066
|
-
var mediaKindWireSchema = zod.z.enum(["webp", "video"]);
|
|
1067
|
-
var categoryWireSchema = zod.z.enum(["health", "attention", "moment", "activity", "mood", "idle"]);
|
|
1068
|
-
var petStateTierWireSchema = zod.z.object({
|
|
1069
|
-
url: zod.z.string(),
|
|
1070
|
-
kind: mediaKindWireSchema.default("webp"),
|
|
1071
|
-
loop_duration_ms: zod.z.number().nullish(),
|
|
1072
|
-
expires_at: zod.z.string(),
|
|
1073
|
-
// SERVER-OWNED identity `{s3_key}@r{asset_revision}`; absent on an older backend (defaults to the
|
|
1074
|
-
// presign-stripped path downstream). Never derived from `url`.
|
|
1075
|
-
cache_key: zod.z.string().nullish()
|
|
1076
|
-
});
|
|
1077
|
-
var petStateResponseWireSchema = zod.z.object({
|
|
1078
|
-
category: categoryWireSchema,
|
|
1079
|
-
tiers: zod.z.object({
|
|
1080
|
-
animation: petStateTierWireSchema.optional(),
|
|
1081
|
-
image: petStateTierWireSchema.optional()
|
|
1082
|
-
}).default({}),
|
|
1083
|
-
overlays: zod.z.object({
|
|
1084
|
-
weather_alert: petStateTierWireSchema.optional()
|
|
1085
|
-
}).default({}),
|
|
1086
|
-
idle: zod.z.literal("bundled").default("bundled"),
|
|
1087
|
-
ttl_seconds: zod.z.number(),
|
|
1088
|
-
// TRANSIENT server idle (derive timeout / shed / IAM drift), NOT a dark pet.
|
|
1089
|
-
degraded: zod.z.boolean().default(false),
|
|
1090
|
-
// Monotonic fleet-wide purge counter; 0 / absent == never purged.
|
|
1091
|
-
cache_epoch: zod.z.number().default(0)
|
|
1092
|
-
});
|
|
1093
|
-
function parsePetStateWire(raw) {
|
|
1094
|
-
const parsed = petStateResponseWireSchema.safeParse(raw);
|
|
1095
|
-
return parsed.success ? parsed.data : null;
|
|
1096
|
-
}
|
|
1097
|
-
|
|
1098
|
-
// src/client/animations/petStateRepository.ts
|
|
1099
|
-
function createPetStateRepository(auth) {
|
|
1100
|
-
return createPetStateRepositoryOver(createRequestFunnel({ auth }));
|
|
1101
|
-
}
|
|
1102
|
-
function createPetStateRepositoryOver(funnel) {
|
|
1103
|
-
return {
|
|
1104
|
-
async getState(petRef, opts) {
|
|
1105
|
-
if (hasLoneSurrogate(petRef)) {
|
|
1106
|
-
return err(
|
|
1107
|
-
makeEverfurError("validationFailed", {
|
|
1108
|
-
retryable: false,
|
|
1109
|
-
wireMessage: "pet_ref contains an unpaired surrogate and cannot be encoded"
|
|
1110
|
-
})
|
|
1111
|
-
);
|
|
1112
|
-
}
|
|
1113
|
-
const path = `/widget/v1/pets/${encodeURIComponent(petRef)}/state`;
|
|
1114
|
-
const res = await funnel.send(
|
|
1115
|
-
"animations.getState",
|
|
1116
|
-
opts?.signal ? { method: "GET", path, signal: opts.signal } : { method: "GET", path }
|
|
1117
|
-
);
|
|
1118
|
-
if (res.ok) {
|
|
1119
|
-
const wire = parsePetStateWire(res.value);
|
|
1120
|
-
if (wire === null) {
|
|
1121
|
-
return err(makeEverfurError("internalError", { retryable: true }));
|
|
1122
|
-
}
|
|
1123
|
-
return ok(mapPetStateResponse(wire));
|
|
1124
|
-
}
|
|
1125
|
-
if (res.error.httpStatus === 404) return ok(null);
|
|
1126
|
-
return err(res.error);
|
|
1127
|
-
}
|
|
1128
|
-
};
|
|
1129
|
-
}
|
|
1130
|
-
|
|
1131
|
-
// src/client/animations/tier.ts
|
|
1132
|
-
function stableMediaKey(source) {
|
|
1133
|
-
if (source === void 0) return "bundled:none";
|
|
1134
|
-
if (typeof source === "number") return `bundled:${source}`;
|
|
1135
|
-
if ("kind" in source) return `bundled:${source.id}`;
|
|
1136
|
-
const uri = source.uri;
|
|
1137
|
-
const q = uri.indexOf("?");
|
|
1138
|
-
return q === -1 ? uri : uri.slice(0, q);
|
|
1139
|
-
}
|
|
1140
|
-
function selectTier(i) {
|
|
1141
|
-
if (i.hasPhoto && !i.photoFailed) return "photo";
|
|
1142
|
-
if (i.canAnimate && !i.animationFailed) return "animation";
|
|
1143
|
-
if (i.hasImage && !i.imageFailed) return "image";
|
|
1144
|
-
return "idle";
|
|
1145
|
-
}
|
|
1146
|
-
function retireTier(current, failed) {
|
|
1147
|
-
switch (current) {
|
|
1148
|
-
case "photo":
|
|
1149
|
-
return { failed: freezeFailed({ ...failed, photo: true }), reason: "network_error" };
|
|
1150
|
-
case "animation":
|
|
1151
|
-
return { failed: freezeFailed({ ...failed, animation: true }), reason: "network_error" };
|
|
1152
|
-
case "image":
|
|
1153
|
-
return { failed: freezeFailed({ ...failed, image: true }), reason: "network_error" };
|
|
1154
|
-
case "idle":
|
|
1155
|
-
return { failed: freezeFailed(failed), reason: "idle_asset_failed" };
|
|
1156
|
-
default:
|
|
1157
|
-
return { failed: freezeFailed(failed), reason: "network_error" };
|
|
1158
|
-
}
|
|
1159
|
-
}
|
|
1160
|
-
var NO_FAILURES = Object.freeze({ photo: false, animation: false, image: false });
|
|
1161
|
-
function freezeFailed(f) {
|
|
1162
|
-
return Object.freeze({ photo: f.photo, animation: f.animation, image: f.image });
|
|
1163
|
-
}
|
|
1164
|
-
function isLoaderSafeCategory(category) {
|
|
1165
|
-
switch (category) {
|
|
1166
|
-
case "activity":
|
|
1167
|
-
case "mood":
|
|
1168
|
-
case "moment":
|
|
1169
|
-
case "idle":
|
|
1170
|
-
return true;
|
|
1171
|
-
case "health":
|
|
1172
|
-
case "attention":
|
|
1173
|
-
return false;
|
|
1174
|
-
default:
|
|
1175
|
-
return false;
|
|
1176
|
-
}
|
|
1177
|
-
}
|
|
1178
|
-
|
|
1179
|
-
// src/core/animations/cacheEpoch.ts
|
|
1180
|
-
var CACHE_EPOCH_STORAGE_KEY = "everfur.petState.cacheEpoch";
|
|
1181
|
-
function createCacheEpochGuard(deps) {
|
|
1182
|
-
let lastActed = 0;
|
|
1183
|
-
let loaded = false;
|
|
1184
|
-
let inFlight = null;
|
|
1185
|
-
const run = async (serverEpoch) => {
|
|
1186
|
-
if (!loaded) {
|
|
1187
|
-
lastActed = await readStoredEpoch(deps.kv);
|
|
1188
|
-
loaded = true;
|
|
1189
|
-
}
|
|
1190
|
-
if (serverEpoch <= lastActed) return false;
|
|
1191
|
-
try {
|
|
1192
|
-
await deps.kv.setItem(CACHE_EPOCH_STORAGE_KEY, String(serverEpoch));
|
|
1193
|
-
} catch {
|
|
1194
|
-
}
|
|
1195
|
-
lastActed = serverEpoch;
|
|
1196
|
-
try {
|
|
1197
|
-
await deps.cache.clearMemoryCache();
|
|
1198
|
-
} catch {
|
|
1199
|
-
}
|
|
1200
|
-
try {
|
|
1201
|
-
await deps.cache.clearDiskCache();
|
|
1202
|
-
} catch {
|
|
1203
|
-
}
|
|
1204
|
-
return true;
|
|
1205
|
-
};
|
|
1206
|
-
return {
|
|
1207
|
-
async sync(serverEpoch) {
|
|
1208
|
-
if (typeof serverEpoch !== "number" || !Number.isFinite(serverEpoch) || serverEpoch <= 0) {
|
|
1209
|
-
return false;
|
|
1210
|
-
}
|
|
1211
|
-
if (loaded && serverEpoch <= lastActed) return false;
|
|
1212
|
-
if (inFlight) return inFlight;
|
|
1213
|
-
inFlight = run(serverEpoch).finally(() => {
|
|
1214
|
-
inFlight = null;
|
|
1215
|
-
});
|
|
1216
|
-
return inFlight;
|
|
1217
|
-
}
|
|
1218
|
-
};
|
|
1219
|
-
}
|
|
1220
|
-
async function readStoredEpoch(kv) {
|
|
1221
|
-
let raw;
|
|
1222
|
-
try {
|
|
1223
|
-
raw = await kv.getItem(CACHE_EPOCH_STORAGE_KEY);
|
|
1224
|
-
} catch {
|
|
1225
|
-
return 0;
|
|
1226
|
-
}
|
|
1227
|
-
if (raw === null) return 0;
|
|
1228
|
-
const parsed = Number(raw);
|
|
1229
|
-
return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
|
|
1230
|
-
}
|
|
1231
|
-
var SUPPORTED_SCHEMA_VERSION = 1;
|
|
1232
|
-
var MANIFEST_LKG_STORAGE_KEY = "everfur.manifest.lastKnownGood";
|
|
1233
|
-
var COMPILED_DEFAULT_IDLE = Object.freeze({ kind: "bundled", id: "everfur-idle" });
|
|
1234
|
-
var COMPILED_DEFAULT_MANIFEST = Object.freeze({
|
|
1235
|
-
schemaVersion: SUPPORTED_SCHEMA_VERSION,
|
|
1236
|
-
revision: "compiled-default",
|
|
1237
|
-
surfaces: Object.freeze({
|
|
1238
|
-
animations: Object.freeze({ enabled: true, idle: COMPILED_DEFAULT_IDLE })
|
|
1239
|
-
})
|
|
1240
|
-
});
|
|
1241
|
-
var bundledIdleSchema = zod.z.object({ kind: zod.z.literal("bundled"), id: zod.z.string().min(1) });
|
|
1242
|
-
var animationsSurfaceWireSchema = zod.z.object({
|
|
1243
|
-
enabled: zod.z.boolean().default(true),
|
|
1244
|
-
idle: bundledIdleSchema.optional()
|
|
1245
|
-
});
|
|
1246
|
-
var manifestWireSchema = zod.z.object({
|
|
1247
|
-
schema_version: zod.z.number().int(),
|
|
1248
|
-
revision: zod.z.string().default(""),
|
|
1249
|
-
surfaces: zod.z.object({ animations: animationsSurfaceWireSchema.optional() }).default({})
|
|
1250
|
-
});
|
|
1251
|
-
function parseManifest(raw) {
|
|
1252
|
-
const parsed = manifestWireSchema.safeParse(raw);
|
|
1253
|
-
if (!parsed.success) return { ok: false, reason: "unparseable" };
|
|
1254
|
-
if (parsed.data.schema_version > SUPPORTED_SCHEMA_VERSION) {
|
|
1255
|
-
return { ok: false, reason: "newer_schema" };
|
|
1256
|
-
}
|
|
1257
|
-
const animationsWire = parsed.data.surfaces.animations;
|
|
1258
|
-
const surfaces = {};
|
|
1259
|
-
if (animationsWire) {
|
|
1260
|
-
surfaces.animations = Object.freeze({
|
|
1261
|
-
enabled: animationsWire.enabled,
|
|
1262
|
-
idle: animationsWire.idle ? Object.freeze({ ...animationsWire.idle }) : COMPILED_DEFAULT_IDLE
|
|
1263
|
-
});
|
|
1264
|
-
}
|
|
1265
|
-
return {
|
|
1266
|
-
ok: true,
|
|
1267
|
-
manifest: Object.freeze({
|
|
1268
|
-
schemaVersion: parsed.data.schema_version,
|
|
1269
|
-
revision: parsed.data.revision,
|
|
1270
|
-
surfaces: Object.freeze(surfaces)
|
|
1271
|
-
})
|
|
1272
|
-
};
|
|
1273
|
-
}
|
|
1274
|
-
async function resolveManifest(liveRaw, kv, tel) {
|
|
1275
|
-
if (liveRaw !== null && liveRaw !== void 0) {
|
|
1276
|
-
const parsed = parseManifest(liveRaw);
|
|
1277
|
-
if (parsed.ok) {
|
|
1278
|
-
await writeLastKnownGood(kv, liveRaw);
|
|
1279
|
-
tel.track("manifest.fallback", { source: "live" });
|
|
1280
|
-
return Object.freeze({ manifest: parsed.manifest, source: "live" });
|
|
1281
|
-
}
|
|
1282
|
-
if (parsed.reason === "newer_schema") tel.track("manifest.refused_newer", {});
|
|
1283
|
-
}
|
|
1284
|
-
const lkg = await readLastKnownGood(kv);
|
|
1285
|
-
if (lkg) {
|
|
1286
|
-
tel.track("manifest.fallback", { source: "last-known-good" });
|
|
1287
|
-
return Object.freeze({ manifest: lkg, source: "last-known-good" });
|
|
1288
|
-
}
|
|
1289
|
-
tel.track("manifest.fallback", { source: "compiled-default" });
|
|
1290
|
-
return Object.freeze({ manifest: COMPILED_DEFAULT_MANIFEST, source: "compiled-default" });
|
|
1291
|
-
}
|
|
1292
|
-
function animationsSurfaceOf(manifest) {
|
|
1293
|
-
return manifest.surfaces.animations ?? COMPILED_DEFAULT_MANIFEST.surfaces.animations ?? {
|
|
1294
|
-
enabled: true,
|
|
1295
|
-
idle: COMPILED_DEFAULT_IDLE
|
|
1296
|
-
};
|
|
1297
|
-
}
|
|
1298
|
-
async function writeLastKnownGood(kv, raw) {
|
|
1299
|
-
try {
|
|
1300
|
-
await kv.setItem(MANIFEST_LKG_STORAGE_KEY, JSON.stringify(raw));
|
|
1301
|
-
} catch {
|
|
1302
|
-
}
|
|
1303
|
-
}
|
|
1304
|
-
async function readLastKnownGood(kv) {
|
|
1305
|
-
let stored;
|
|
1306
|
-
try {
|
|
1307
|
-
stored = await kv.getItem(MANIFEST_LKG_STORAGE_KEY);
|
|
1308
|
-
} catch {
|
|
1309
|
-
return null;
|
|
1310
|
-
}
|
|
1311
|
-
if (stored === null) return null;
|
|
1312
|
-
let json;
|
|
1313
|
-
try {
|
|
1314
|
-
json = JSON.parse(stored);
|
|
1315
|
-
} catch {
|
|
1316
|
-
return null;
|
|
1317
|
-
}
|
|
1318
|
-
const parsed = parseManifest(json);
|
|
1319
|
-
return parsed.ok ? parsed.manifest : null;
|
|
1320
|
-
}
|
|
1321
|
-
|
|
1322
|
-
// src/core/animations/petStateStore.ts
|
|
1323
|
-
var DEFAULT_STALE_MS = 6e4;
|
|
1324
|
-
var MAX_TRANSIENT_RETRIES = 2;
|
|
1325
|
-
var MAX_WARM_ENTRIES = 32;
|
|
1326
|
-
var EMPTY_SNAPSHOT = Object.freeze({
|
|
1327
|
-
data: null,
|
|
1328
|
-
isPending: false,
|
|
1329
|
-
isError: false,
|
|
1330
|
-
error: null,
|
|
1331
|
-
isDark: false
|
|
1332
|
-
});
|
|
1333
|
-
function createPetStateStore(deps) {
|
|
1334
|
-
const { repo, cacheEpoch, timers } = deps;
|
|
1335
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
1336
|
-
const warm = /* @__PURE__ */ new Map();
|
|
1337
|
-
let snapshot = EMPTY_SNAPSHOT;
|
|
1338
|
-
let currentPetRef = null;
|
|
1339
|
-
let dataPetRef = null;
|
|
1340
|
-
let isFocused = false;
|
|
1341
|
-
let terminatedPetRef = null;
|
|
1342
|
-
let remintHandle = null;
|
|
1343
|
-
let inFlight = null;
|
|
1344
|
-
let epoch = 0;
|
|
1345
|
-
const emit = () => {
|
|
1346
|
-
for (const listener of listeners) listener();
|
|
1347
|
-
};
|
|
1348
|
-
const patch = (partial) => {
|
|
1349
|
-
snapshot = Object.freeze({ ...snapshot, ...partial });
|
|
1350
|
-
emit();
|
|
1351
|
-
};
|
|
1352
|
-
const clearRemint = () => {
|
|
1353
|
-
if (remintHandle !== null) {
|
|
1354
|
-
timers.clearTimeout(remintHandle);
|
|
1355
|
-
remintHandle = null;
|
|
1356
|
-
}
|
|
1357
|
-
};
|
|
1358
|
-
const staleMs = (data) => data ? Math.max(1, data.ttlSeconds) * 1e3 : DEFAULT_STALE_MS;
|
|
1359
|
-
const touchWarm = (petRef) => {
|
|
1360
|
-
const entry = warm.get(petRef);
|
|
1361
|
-
if (entry === void 0) return;
|
|
1362
|
-
warm.delete(petRef);
|
|
1363
|
-
warm.set(petRef, entry);
|
|
1364
|
-
};
|
|
1365
|
-
const setWarm = (petRef, data) => {
|
|
1366
|
-
warm.delete(petRef);
|
|
1367
|
-
warm.set(petRef, Object.freeze({ data, fetchedAt: timers.now() }));
|
|
1368
|
-
while (warm.size > MAX_WARM_ENTRIES) {
|
|
1369
|
-
const oldest = warm.keys().next().value;
|
|
1370
|
-
if (oldest === void 0 || oldest === petRef) break;
|
|
1371
|
-
warm.delete(oldest);
|
|
1372
|
-
}
|
|
1373
|
-
};
|
|
1374
|
-
const hasGoodTiers = (petRef) => {
|
|
1375
|
-
const entry = warm.get(petRef);
|
|
1376
|
-
if (!entry) return false;
|
|
1377
|
-
return Boolean(entry.data.tiers.animation || entry.data.tiers.image);
|
|
1378
|
-
};
|
|
1379
|
-
const scheduleRemint = (petRef, ttlSeconds) => {
|
|
1380
|
-
clearRemint();
|
|
1381
|
-
if (!isFocused) return;
|
|
1382
|
-
const ms = Math.max(1, ttlSeconds) * 1e3;
|
|
1383
|
-
const scheduledEpoch = epoch;
|
|
1384
|
-
remintHandle = timers.setTimeout(() => {
|
|
1385
|
-
remintHandle = null;
|
|
1386
|
-
if (scheduledEpoch !== epoch || currentPetRef !== petRef || !isFocused) return;
|
|
1387
|
-
void fetchOnce(petRef, 0);
|
|
1388
|
-
}, ms);
|
|
1389
|
-
};
|
|
1390
|
-
const fetchOnce = async (petRef, attempt) => {
|
|
1391
|
-
if (currentPetRef !== petRef || terminatedPetRef === petRef || !isFocused) return;
|
|
1392
|
-
const myEpoch = epoch;
|
|
1393
|
-
inFlight?.abort();
|
|
1394
|
-
const ctrl = new AbortController();
|
|
1395
|
-
inFlight = ctrl;
|
|
1396
|
-
const res = await repo.getState(petRef, { signal: ctrl.signal });
|
|
1397
|
-
if (myEpoch !== epoch || currentPetRef !== petRef) return;
|
|
1398
|
-
if (res.ok) {
|
|
1399
|
-
const resp = res.value;
|
|
1400
|
-
if (resp === null) {
|
|
1401
|
-
onTerminalDark(petRef);
|
|
1402
|
-
return;
|
|
1403
|
-
}
|
|
1404
|
-
void cacheEpoch.sync(resp.cacheEpoch);
|
|
1405
|
-
const respHasTiers = Boolean(resp.tiers.animation || resp.tiers.image);
|
|
1406
|
-
if (resp.degraded && !respHasTiers && hasGoodTiers(petRef)) {
|
|
1407
|
-
patch({ isError: false, error: null, isPending: false, isDark: false });
|
|
1408
|
-
scheduleRemint(petRef, resp.ttlSeconds);
|
|
1409
|
-
return;
|
|
1410
|
-
}
|
|
1411
|
-
setWarm(petRef, resp);
|
|
1412
|
-
dataPetRef = petRef;
|
|
1413
|
-
patch({ data: resp, isPending: false, isError: false, error: null, isDark: false });
|
|
1414
|
-
scheduleRemint(petRef, resp.ttlSeconds);
|
|
1415
|
-
return;
|
|
1416
|
-
}
|
|
1417
|
-
if (isTerminalPetStateError(res.error)) {
|
|
1418
|
-
onTerminalDisabled(petRef, res.error);
|
|
1419
|
-
return;
|
|
1420
|
-
}
|
|
1421
|
-
patch({ isError: true, error: res.error, isPending: snapshot.data === null && dataPetRef !== petRef });
|
|
1422
|
-
if (attempt < MAX_TRANSIENT_RETRIES) {
|
|
1423
|
-
clearRemint();
|
|
1424
|
-
const backoff = 500 * (attempt + 1);
|
|
1425
|
-
const scheduledEpoch = epoch;
|
|
1426
|
-
remintHandle = timers.setTimeout(() => {
|
|
1427
|
-
remintHandle = null;
|
|
1428
|
-
if (scheduledEpoch !== epoch || currentPetRef !== petRef || !isFocused) return;
|
|
1429
|
-
void fetchOnce(petRef, attempt + 1);
|
|
1430
|
-
}, backoff);
|
|
1431
|
-
} else {
|
|
1432
|
-
scheduleRemint(petRef, 5);
|
|
1433
|
-
}
|
|
1434
|
-
};
|
|
1435
|
-
const onTerminalDark = (petRef) => {
|
|
1436
|
-
terminatedPetRef = petRef;
|
|
1437
|
-
warm.delete(petRef);
|
|
1438
|
-
clearRemint();
|
|
1439
|
-
dataPetRef = petRef;
|
|
1440
|
-
patch({ data: null, isPending: false, isError: false, error: null, isDark: true });
|
|
1441
|
-
};
|
|
1442
|
-
const onTerminalDisabled = (petRef, error) => {
|
|
1443
|
-
terminatedPetRef = petRef;
|
|
1444
|
-
warm.delete(petRef);
|
|
1445
|
-
clearRemint();
|
|
1446
|
-
dataPetRef = petRef;
|
|
1447
|
-
patch({ data: null, isPending: false, isError: false, error, isDark: true });
|
|
1448
|
-
};
|
|
1449
|
-
return {
|
|
1450
|
-
observe(petRef, opts) {
|
|
1451
|
-
const focusChanged = opts.isFocused !== isFocused;
|
|
1452
|
-
isFocused = opts.isFocused;
|
|
1453
|
-
if (petRef !== currentPetRef) {
|
|
1454
|
-
epoch += 1;
|
|
1455
|
-
inFlight?.abort();
|
|
1456
|
-
inFlight = null;
|
|
1457
|
-
clearRemint();
|
|
1458
|
-
terminatedPetRef = null;
|
|
1459
|
-
currentPetRef = petRef;
|
|
1460
|
-
if (petRef === null) {
|
|
1461
|
-
dataPetRef = null;
|
|
1462
|
-
snapshot = EMPTY_SNAPSHOT;
|
|
1463
|
-
emit();
|
|
1464
|
-
return;
|
|
1465
|
-
}
|
|
1466
|
-
const warmEntry = warm.get(petRef);
|
|
1467
|
-
const fresh = warmEntry && timers.now() - warmEntry.fetchedAt < staleMs(warmEntry.data) ? warmEntry : null;
|
|
1468
|
-
if (fresh) {
|
|
1469
|
-
touchWarm(petRef);
|
|
1470
|
-
dataPetRef = petRef;
|
|
1471
|
-
patch({ data: fresh.data, isPending: false, isError: false, error: null, isDark: false });
|
|
1472
|
-
} else {
|
|
1473
|
-
patch({ isPending: true, isError: false, error: null, isDark: false });
|
|
1474
|
-
}
|
|
1475
|
-
if (isFocused) void fetchOnce(petRef, 0);
|
|
1476
|
-
return;
|
|
1477
|
-
}
|
|
1478
|
-
if (!focusChanged || petRef === null) return;
|
|
1479
|
-
if (!isFocused) {
|
|
1480
|
-
clearRemint();
|
|
1481
|
-
return;
|
|
1482
|
-
}
|
|
1483
|
-
const entry = warm.get(petRef);
|
|
1484
|
-
if (!entry || timers.now() - entry.fetchedAt >= staleMs(entry.data)) {
|
|
1485
|
-
if (terminatedPetRef !== petRef) void fetchOnce(petRef, 0);
|
|
1486
|
-
} else {
|
|
1487
|
-
scheduleRemint(petRef, entry.data.ttlSeconds);
|
|
1488
|
-
}
|
|
1489
|
-
},
|
|
1490
|
-
getSnapshot() {
|
|
1491
|
-
return snapshot;
|
|
1492
|
-
},
|
|
1493
|
-
subscribe(listener) {
|
|
1494
|
-
listeners.add(listener);
|
|
1495
|
-
return () => {
|
|
1496
|
-
listeners.delete(listener);
|
|
1497
|
-
};
|
|
1498
|
-
},
|
|
1499
|
-
getCachedPetStateMedia(petRef) {
|
|
1500
|
-
const entry = warm.get(petRef);
|
|
1501
|
-
if (!entry) return null;
|
|
1502
|
-
if (timers.now() - entry.fetchedAt >= staleMs(entry.data)) return null;
|
|
1503
|
-
touchWarm(petRef);
|
|
1504
|
-
return entry.data;
|
|
1505
|
-
},
|
|
1506
|
-
dispose() {
|
|
1507
|
-
epoch += 1;
|
|
1508
|
-
inFlight?.abort();
|
|
1509
|
-
inFlight = null;
|
|
1510
|
-
clearRemint();
|
|
1511
|
-
listeners.clear();
|
|
1512
|
-
warm.clear();
|
|
1513
|
-
}
|
|
1514
|
-
};
|
|
1515
|
-
}
|
|
1516
|
-
function isTerminalPetStateError(error) {
|
|
1517
|
-
if (typeof error !== "object" || error === null) return false;
|
|
1518
|
-
const record = error;
|
|
1519
|
-
const status = typeof record.status === "number" ? record.status : record.httpStatus;
|
|
1520
|
-
return status === 403 || status === 404;
|
|
1521
|
-
}
|
|
1522
|
-
|
|
1523
|
-
// src/core/animations/AnimationController.ts
|
|
1524
|
-
function createAnimationController(deps) {
|
|
1525
|
-
const telemetry = deps.telemetry ?? noopTelemetry;
|
|
1526
|
-
const timers = deps.timers ?? defaultTimers(deps.now);
|
|
1527
|
-
const store = createPetStateStore({
|
|
1528
|
-
repo: deps.repo,
|
|
1529
|
-
cacheEpoch: createCacheEpochGuard({ kv: deps.kv, cache: deps.cache }),
|
|
1530
|
-
timers
|
|
1531
|
-
});
|
|
1532
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
1533
|
-
let failed = NO_FAILURES;
|
|
1534
|
-
let fallbackReason = "none";
|
|
1535
|
-
let paused = false;
|
|
1536
|
-
let photoUrl = null;
|
|
1537
|
-
let lastData = null;
|
|
1538
|
-
let lastDark = false;
|
|
1539
|
-
let lastShownKey = "";
|
|
1540
|
-
let view = pendingView(surface());
|
|
1541
|
-
let disposed = false;
|
|
1542
|
-
function surface() {
|
|
1543
|
-
const manifest = deps.manifest ? deps.manifest() : COMPILED_DEFAULT_MANIFEST;
|
|
1544
|
-
return animationsSurfaceOf(manifest);
|
|
1545
|
-
}
|
|
1546
|
-
const emit = () => {
|
|
1547
|
-
for (const listener of listeners) listener();
|
|
1548
|
-
};
|
|
1549
|
-
const unsubscribeStore = store.subscribe(() => {
|
|
1550
|
-
onStoreChange();
|
|
1551
|
-
});
|
|
1552
|
-
function onStoreChange() {
|
|
1553
|
-
const snap = store.getSnapshot();
|
|
1554
|
-
if (snap.data !== lastData || snap.isDark !== lastDark) {
|
|
1555
|
-
lastData = snap.data;
|
|
1556
|
-
lastDark = snap.isDark;
|
|
1557
|
-
failed = NO_FAILURES;
|
|
1558
|
-
fallbackReason = snap.isDark ? "dark_or_missing" : "none";
|
|
1559
|
-
}
|
|
1560
|
-
recompute(snap);
|
|
1561
|
-
}
|
|
1562
|
-
function recompute(snap = store.getSnapshot()) {
|
|
1563
|
-
const surf = surface();
|
|
1564
|
-
const next = buildView(surf, snap, {
|
|
1565
|
-
failed,
|
|
1566
|
-
fallbackReason,
|
|
1567
|
-
paused,
|
|
1568
|
-
photoUrl,
|
|
1569
|
-
reducedMotion: deps.reducedMotion()});
|
|
1570
|
-
view = next;
|
|
1571
|
-
maybeEmitShown(next);
|
|
1572
|
-
emit();
|
|
1573
|
-
}
|
|
1574
|
-
function maybeEmitShown(next) {
|
|
1575
|
-
if (next.kind !== "ready") return;
|
|
1576
|
-
const key = `${next.category}|${next.tier}|${next.fallbackReason}|${next.reducedMotion ? 1 : 0}`;
|
|
1577
|
-
if (key === lastShownKey) return;
|
|
1578
|
-
lastShownKey = key;
|
|
1579
|
-
telemetry.track("pet_state_shown", {
|
|
1580
|
-
category: next.category,
|
|
1581
|
-
// coarse only; privacy-safe (§5.5)
|
|
1582
|
-
tier: next.tier,
|
|
1583
|
-
fallback_reason: next.fallbackReason,
|
|
1584
|
-
reduced_motion: next.reducedMotion
|
|
1585
|
-
});
|
|
1586
|
-
if (next.fallbackReason === "idle_asset_failed") {
|
|
1587
|
-
telemetry.trackExpectedFailure("idle_asset_failed", { category: next.category });
|
|
1588
|
-
}
|
|
1589
|
-
}
|
|
1590
|
-
return {
|
|
1591
|
-
observe(petRef, opts) {
|
|
1592
|
-
if (disposed) return;
|
|
1593
|
-
photoUrl = opts.photoUrl ?? null;
|
|
1594
|
-
failed = NO_FAILURES;
|
|
1595
|
-
store.observe(petRef, { isFocused: opts.isFocused });
|
|
1596
|
-
onStoreChange();
|
|
1597
|
-
},
|
|
1598
|
-
getState() {
|
|
1599
|
-
return view;
|
|
1600
|
-
},
|
|
1601
|
-
subscribe(listener) {
|
|
1602
|
-
listeners.add(listener);
|
|
1603
|
-
return () => {
|
|
1604
|
-
listeners.delete(listener);
|
|
1605
|
-
};
|
|
1606
|
-
},
|
|
1607
|
-
onMediaError() {
|
|
1608
|
-
if (disposed || view.kind !== "ready") return;
|
|
1609
|
-
const retired = retireTier(view.tier, failed);
|
|
1610
|
-
failed = retired.failed;
|
|
1611
|
-
fallbackReason = retired.reason;
|
|
1612
|
-
recompute();
|
|
1613
|
-
},
|
|
1614
|
-
setPaused(next) {
|
|
1615
|
-
if (disposed || paused === next) return;
|
|
1616
|
-
paused = next;
|
|
1617
|
-
recompute();
|
|
1618
|
-
},
|
|
1619
|
-
dispose() {
|
|
1620
|
-
if (disposed) return;
|
|
1621
|
-
disposed = true;
|
|
1622
|
-
unsubscribeStore();
|
|
1623
|
-
store.dispose();
|
|
1624
|
-
listeners.clear();
|
|
1625
|
-
}
|
|
1626
|
-
};
|
|
1627
|
-
}
|
|
1628
|
-
function buildView(surf, snap, inputs) {
|
|
1629
|
-
const idleSource = surf.idle;
|
|
1630
|
-
if (!surf.enabled) {
|
|
1631
|
-
return Object.freeze({
|
|
1632
|
-
kind: "disabled",
|
|
1633
|
-
reason: userFacingError("accessDenied"),
|
|
1634
|
-
level: "partner_config",
|
|
1635
|
-
source: idleSource,
|
|
1636
|
-
idle: surf.idle
|
|
1637
|
-
});
|
|
1638
|
-
}
|
|
1639
|
-
if (snap.isPending && snap.data === null && !snap.isDark) {
|
|
1640
|
-
return Object.freeze({ kind: "pending", showSkeleton: true, source: idleSource });
|
|
1641
|
-
}
|
|
1642
|
-
const data = snap.data;
|
|
1643
|
-
const category = data?.category ?? "idle";
|
|
1644
|
-
const animation = data?.tiers.animation;
|
|
1645
|
-
const image = data?.tiers.image;
|
|
1646
|
-
const canAnimate = Boolean(animation) && animation?.kind === "webp" && !inputs.reducedMotion && !inputs.failed.animation;
|
|
1647
|
-
const tier = selectTier({
|
|
1648
|
-
hasPhoto: inputs.photoUrl !== null && inputs.photoUrl.length > 0,
|
|
1649
|
-
photoFailed: inputs.failed.photo,
|
|
1650
|
-
canAnimate,
|
|
1651
|
-
animationFailed: inputs.failed.animation,
|
|
1652
|
-
hasImage: Boolean(image),
|
|
1653
|
-
imageFailed: inputs.failed.image
|
|
1654
|
-
});
|
|
1655
|
-
let source = idleSource;
|
|
1656
|
-
let loopDurationMs = null;
|
|
1657
|
-
let cacheHit = false;
|
|
1658
|
-
if (tier === "photo" && inputs.photoUrl) {
|
|
1659
|
-
source = uriSource(inputs.photoUrl, void 0);
|
|
1660
|
-
} else if (tier === "animation" && animation) {
|
|
1661
|
-
source = uriSource(animation.url, animation.cacheKey);
|
|
1662
|
-
loopDurationMs = animation.loopDurationMs ?? null;
|
|
1663
|
-
cacheHit = animation.cacheKey !== void 0;
|
|
1664
|
-
} else if (tier === "image" && image) {
|
|
1665
|
-
source = uriSource(image.url, image.cacheKey);
|
|
1666
|
-
cacheHit = image.cacheKey !== void 0;
|
|
1667
|
-
}
|
|
1668
|
-
const recyclingKey = source.kind === "uri" ? source.cacheKey : `bundled:${source.id}`;
|
|
1669
|
-
return Object.freeze({
|
|
1670
|
-
kind: "ready",
|
|
1671
|
-
tier,
|
|
1672
|
-
source,
|
|
1673
|
-
recyclingKey,
|
|
1674
|
-
category,
|
|
1675
|
-
loopDurationMs,
|
|
1676
|
-
paused: inputs.paused,
|
|
1677
|
-
reducedMotion: inputs.reducedMotion,
|
|
1678
|
-
cacheHit,
|
|
1679
|
-
fallbackReason: inputs.fallbackReason,
|
|
1680
|
-
isDark: snap.isDark,
|
|
1681
|
-
isTransientError: snap.isError
|
|
1682
|
-
});
|
|
1683
|
-
}
|
|
1684
|
-
function uriSource(uri, serverCacheKey) {
|
|
1685
|
-
return Object.freeze({
|
|
1686
|
-
kind: "uri",
|
|
1687
|
-
uri,
|
|
1688
|
-
cacheKey: serverCacheKey ?? stableMediaKey({ uri })
|
|
1689
|
-
});
|
|
1690
|
-
}
|
|
1691
|
-
function pendingView(surf) {
|
|
1692
|
-
return Object.freeze({ kind: "pending", showSkeleton: true, source: surf.idle });
|
|
1693
|
-
}
|
|
1694
|
-
function defaultTimers(now) {
|
|
1695
|
-
return {
|
|
1696
|
-
setTimeout: (handler, ms) => setTimeout(handler, ms),
|
|
1697
|
-
clearTimeout: (handle) => clearTimeout(handle),
|
|
1698
|
-
now
|
|
1699
|
-
};
|
|
1700
|
-
}
|
|
1701
|
-
|
|
1702
|
-
// src/rn/animations/useAnimations.ts
|
|
1703
|
-
var PENDING_FALLBACK = Object.freeze({
|
|
1704
|
-
kind: "pending",
|
|
1705
|
-
showSkeleton: true,
|
|
1706
|
-
source: COMPILED_DEFAULT_IDLE
|
|
1707
|
-
});
|
|
1708
|
-
var NOOP_UNSUBSCRIBE = () => {
|
|
1709
|
-
};
|
|
1710
|
-
function useAnimations(params) {
|
|
1711
|
-
const {
|
|
1712
|
-
petRef,
|
|
1713
|
-
repo,
|
|
1714
|
-
cache,
|
|
1715
|
-
kv,
|
|
1716
|
-
isFocused = true,
|
|
1717
|
-
photoUrl = null,
|
|
1718
|
-
telemetry,
|
|
1719
|
-
reducedMotion,
|
|
1720
|
-
manifest,
|
|
1721
|
-
timers,
|
|
1722
|
-
now
|
|
1723
|
-
} = params;
|
|
1724
|
-
const { runtime, userRef } = useEverfurContext();
|
|
1725
|
-
const capability = useCapability("animations");
|
|
1726
|
-
const reducedMotionReader = useSystemReducedMotion(reducedMotion);
|
|
1727
|
-
const hasOverride = repo !== void 0 && cache !== void 0 && kv !== void 0;
|
|
1728
|
-
const seamKey = hasOverride ? "override" : `${userRef ?? ""}|${petRef ?? ""}`;
|
|
1729
|
-
const [controller, setController] = react.useState(null);
|
|
1730
|
-
react.useEffect(() => {
|
|
1731
|
-
if (repo !== void 0 && cache !== void 0 && kv !== void 0) {
|
|
1732
|
-
const deps = {
|
|
1733
|
-
repo,
|
|
1734
|
-
cache,
|
|
1735
|
-
kv,
|
|
1736
|
-
reducedMotion: reducedMotionReader,
|
|
1737
|
-
now: now ?? defaultNow,
|
|
1738
|
-
...telemetry ? { telemetry } : {},
|
|
1739
|
-
...manifest ? { manifest } : {},
|
|
1740
|
-
...timers ? { timers } : {}
|
|
1741
|
-
};
|
|
1742
|
-
const built = createAnimationController(deps);
|
|
1743
|
-
setController(built);
|
|
1744
|
-
return () => {
|
|
1745
|
-
setController((current) => current === built ? null : current);
|
|
1746
|
-
built.dispose();
|
|
1747
|
-
};
|
|
1748
|
-
}
|
|
1749
|
-
const { services } = runtime.registry;
|
|
1750
|
-
const acquired = runtime.registry.acquire(
|
|
1751
|
-
"animations",
|
|
1752
|
-
`${userRef ?? ""}|${petRef ?? ""}`,
|
|
1753
|
-
() => createAnimationController({
|
|
1754
|
-
repo: createPetStateRepository(services.authFor(userRef)),
|
|
1755
|
-
cache: services.imageCache,
|
|
1756
|
-
kv: services.kv,
|
|
1757
|
-
reducedMotion: reducedMotionReader,
|
|
1758
|
-
now: now ?? defaultNow,
|
|
1759
|
-
telemetry: services.telemetry,
|
|
1760
|
-
...manifest ? { manifest } : {},
|
|
1761
|
-
...timers ? { timers } : {}
|
|
1762
|
-
}),
|
|
1763
|
-
(controller2) => controller2.dispose()
|
|
1764
|
-
);
|
|
1765
|
-
setController(acquired);
|
|
1766
|
-
return () => {
|
|
1767
|
-
setController((current) => current === acquired ? null : current);
|
|
1768
|
-
runtime.registry.release(acquired);
|
|
1769
|
-
};
|
|
1770
|
-
}, [seamKey, repo, cache, kv, runtime]);
|
|
1771
|
-
react.useEffect(() => {
|
|
1772
|
-
controller?.observe(petRef, { isFocused, photoUrl });
|
|
1773
|
-
}, [controller, petRef, isFocused, photoUrl]);
|
|
1774
|
-
const subscribe = react.useCallback(
|
|
1775
|
-
(onChange) => controller ? controller.subscribe(onChange) : NOOP_UNSUBSCRIBE,
|
|
1776
|
-
[controller]
|
|
1777
|
-
);
|
|
1778
|
-
const getState = react.useCallback(
|
|
1779
|
-
() => controller ? controller.getState() : PENDING_FALLBACK,
|
|
1780
|
-
[controller]
|
|
1781
|
-
);
|
|
1782
|
-
const state = react.useSyncExternalStore(subscribe, getState, getState);
|
|
1783
|
-
const onMediaError = react.useCallback(() => {
|
|
1784
|
-
controller?.onMediaError();
|
|
1785
|
-
}, [controller]);
|
|
1786
|
-
const setPaused = react.useCallback(
|
|
1787
|
-
(paused) => {
|
|
1788
|
-
controller?.setPaused(paused);
|
|
1789
|
-
},
|
|
1790
|
-
[controller]
|
|
1791
|
-
);
|
|
1792
|
-
return react.useMemo(
|
|
1793
|
-
() => ({ capability, state, onMediaError, setPaused }),
|
|
1794
|
-
[capability, state, onMediaError, setPaused]
|
|
1795
|
-
);
|
|
1796
|
-
}
|
|
1797
|
-
function useSystemReducedMotion(provided) {
|
|
1798
|
-
const enabledRef = react.useRef(true);
|
|
1799
|
-
react.useEffect(() => {
|
|
1800
|
-
if (provided) return;
|
|
1801
|
-
let active = true;
|
|
1802
|
-
const probe = reactNative.AccessibilityInfo.isReduceMotionEnabled?.();
|
|
1803
|
-
if (probe && typeof probe.then === "function") {
|
|
1804
|
-
void probe.then((value) => {
|
|
1805
|
-
if (active) enabledRef.current = value;
|
|
1806
|
-
});
|
|
1807
|
-
}
|
|
1808
|
-
const subscription = reactNative.AccessibilityInfo.addEventListener?.("reduceMotionChanged", (value) => {
|
|
1809
|
-
enabledRef.current = value;
|
|
1810
|
-
});
|
|
1811
|
-
return () => {
|
|
1812
|
-
active = false;
|
|
1813
|
-
subscription?.remove?.();
|
|
1814
|
-
};
|
|
1815
|
-
}, [provided]);
|
|
1816
|
-
return react.useMemo(() => provided ?? (() => enabledRef.current), [provided]);
|
|
1817
|
-
}
|
|
1818
|
-
function defaultNow() {
|
|
1819
|
-
return Date.now();
|
|
1820
|
-
}
|
|
1821
|
-
var PET_STATE_CROSSFADE_MS = 200;
|
|
1822
|
-
var SPINNER_DELAY_MS = 300;
|
|
1823
|
-
var MIN_MEDIA_HEIGHT = 120;
|
|
1824
|
-
function PetStateView(props) {
|
|
1825
|
-
const { style, accessibilityLabel } = props;
|
|
1826
|
-
const a11y = { accessibilityLabel, decorative: isDecorative(props) };
|
|
1827
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1828
|
-
CapabilityGate,
|
|
1829
|
-
{
|
|
1830
|
-
capability: "animations",
|
|
1831
|
-
style,
|
|
1832
|
-
renderPending: () => /* @__PURE__ */ jsxRuntime.jsx(IdleRegion, { style, a11y, busy: true }),
|
|
1833
|
-
renderDisabled: (decision) => /* @__PURE__ */ jsxRuntime.jsx(IdleRegion, { style, a11y, reason: decision.disabled?.reason ?? "" }),
|
|
1834
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(PetStateBody, { ...props })
|
|
1835
|
-
}
|
|
1836
|
-
);
|
|
1837
|
-
}
|
|
1838
|
-
function isDecorative(props) {
|
|
1839
|
-
return props.decorative === true || props.accessibilityLabel === void 0;
|
|
1840
|
-
}
|
|
1841
|
-
function PetStateBody(props) {
|
|
1842
|
-
const styles = useStyles();
|
|
1843
|
-
const a11y = {
|
|
1844
|
-
accessibilityLabel: props.accessibilityLabel,
|
|
1845
|
-
decorative: isDecorative(props)
|
|
1846
|
-
};
|
|
1847
|
-
const state = useAnimations(buildParams(props));
|
|
1848
|
-
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles.container, props.style], children: renderState(state.state, state.onMediaError, a11y) });
|
|
1849
|
-
}
|
|
1850
|
-
function renderState(view, onMediaError, a11y) {
|
|
1851
|
-
switch (view.kind) {
|
|
1852
|
-
case "pending":
|
|
1853
|
-
return /* @__PURE__ */ jsxRuntime.jsx(MediaNode, { source: view.source, recyclingKey: "pending", reducedMotion: true, a11y, busy: true, onMediaError });
|
|
1854
|
-
case "disabled":
|
|
1855
|
-
return /* @__PURE__ */ jsxRuntime.jsx(IdleRegion, { a11y, reason: view.reason });
|
|
1856
|
-
case "ready":
|
|
1857
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1858
|
-
MediaNode,
|
|
1859
|
-
{
|
|
1860
|
-
source: view.source,
|
|
1861
|
-
recyclingKey: view.recyclingKey,
|
|
1862
|
-
reducedMotion: view.reducedMotion,
|
|
1863
|
-
a11y,
|
|
1864
|
-
onMediaError
|
|
1865
|
-
}
|
|
1866
|
-
);
|
|
1867
|
-
default:
|
|
1868
|
-
return assertNever(view);
|
|
1869
|
-
}
|
|
1870
|
-
}
|
|
1871
|
-
function MediaNode({
|
|
1872
|
-
source,
|
|
1873
|
-
recyclingKey,
|
|
1874
|
-
reducedMotion,
|
|
1875
|
-
a11y,
|
|
1876
|
-
busy,
|
|
1877
|
-
onMediaError
|
|
1878
|
-
}) {
|
|
1879
|
-
const styles = useStyles();
|
|
1880
|
-
if (source.kind === "uri") {
|
|
1881
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1882
|
-
reactNative.Image,
|
|
1883
|
-
{
|
|
1884
|
-
source: { uri: source.uri },
|
|
1885
|
-
onError: onMediaError,
|
|
1886
|
-
fadeDuration: reducedMotion ? 0 : PET_STATE_CROSSFADE_MS,
|
|
1887
|
-
style: styles.media,
|
|
1888
|
-
...a11yProps(a11y)
|
|
1889
|
-
},
|
|
1890
|
-
recyclingKey
|
|
1891
|
-
);
|
|
1892
|
-
}
|
|
1893
|
-
return /* @__PURE__ */ jsxRuntime.jsx(IdleRegion, { a11y, busy });
|
|
1894
|
-
}
|
|
1895
|
-
function IdleRegion({
|
|
1896
|
-
style,
|
|
1897
|
-
a11y,
|
|
1898
|
-
busy,
|
|
1899
|
-
reason
|
|
1900
|
-
}) {
|
|
1901
|
-
const styles = useStyles();
|
|
1902
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [styles.idlePlaceholder, style], ...a11yProps(a11y), children: [
|
|
1903
|
-
busy ? /* @__PURE__ */ jsxRuntime.jsx(DelayedSpinner, {}) : null,
|
|
1904
|
-
reason && reason.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles.reasonText, children: reason }) : null
|
|
1905
|
-
] });
|
|
1906
|
-
}
|
|
1907
|
-
function DelayedSpinner() {
|
|
1908
|
-
const theme = useEverfurTheme();
|
|
1909
|
-
const [visible, setVisible] = react.useState(false);
|
|
1910
|
-
react.useEffect(() => {
|
|
1911
|
-
const id = setTimeout(() => setVisible(true), SPINNER_DELAY_MS);
|
|
1912
|
-
return () => clearTimeout(id);
|
|
1913
|
-
}, []);
|
|
1914
|
-
return visible ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.ActivityIndicator, { color: theme.color.brand }) : null;
|
|
1915
|
-
}
|
|
1916
|
-
function a11yProps(a11y) {
|
|
1917
|
-
if (a11y.decorative) {
|
|
1918
|
-
return { accessible: false, accessibilityElementsHidden: true, importantForAccessibility: "no-hide-descendants" };
|
|
1919
|
-
}
|
|
1920
|
-
const label = a11y.accessibilityLabel;
|
|
1921
|
-
return label !== void 0 ? { accessible: true, accessibilityRole: "image", accessibilityLabel: label } : { accessible: true, accessibilityRole: "image" };
|
|
1922
|
-
}
|
|
1923
|
-
function buildParams(props) {
|
|
1924
|
-
const params = { petRef: props.petRef, repo: props.repo, cache: props.cache, kv: props.kv };
|
|
1925
|
-
if (props.isFocused !== void 0) params.isFocused = props.isFocused;
|
|
1926
|
-
if (props.photoUrl !== void 0) params.photoUrl = props.photoUrl;
|
|
1927
|
-
if (props.telemetry !== void 0) params.telemetry = props.telemetry;
|
|
1928
|
-
if (props.reducedMotion !== void 0) params.reducedMotion = props.reducedMotion;
|
|
1929
|
-
if (props.manifest !== void 0) params.manifest = props.manifest;
|
|
1930
|
-
if (props.timers !== void 0) params.timers = props.timers;
|
|
1931
|
-
if (props.now !== void 0) params.now = props.now;
|
|
1932
|
-
return params;
|
|
1933
|
-
}
|
|
1934
|
-
function useStyles() {
|
|
1935
|
-
const theme = useEverfurTheme();
|
|
1936
|
-
return react.useMemo(() => makeStyles2(theme), [theme]);
|
|
1937
|
-
}
|
|
1938
|
-
function makeStyles2(theme) {
|
|
1939
|
-
return reactNative.StyleSheet.create({
|
|
1940
|
-
// Cream ground + rounded frame so the media crossfade sits on a branded surface with clipped corners.
|
|
1941
|
-
container: {
|
|
1942
|
-
minHeight: MIN_MEDIA_HEIGHT,
|
|
1943
|
-
width: "100%",
|
|
1944
|
-
backgroundColor: theme.color.surfaceCream,
|
|
1945
|
-
borderRadius: theme.radius.lg,
|
|
1946
|
-
overflow: "hidden"
|
|
1947
|
-
},
|
|
1948
|
-
media: { minHeight: MIN_MEDIA_HEIGHT, width: "100%" },
|
|
1949
|
-
// Idle placeholder: an Everfur cream card with a hairline cream ring for subtle depth (never grey-on-blue).
|
|
1950
|
-
idlePlaceholder: {
|
|
1951
|
-
minHeight: MIN_MEDIA_HEIGHT,
|
|
1952
|
-
width: "100%",
|
|
1953
|
-
alignItems: "center",
|
|
1954
|
-
justifyContent: "center",
|
|
1955
|
-
backgroundColor: theme.color.surfaceCream,
|
|
1956
|
-
borderRadius: theme.radius.lg,
|
|
1957
|
-
borderWidth: reactNative.StyleSheet.hairlineWidth,
|
|
1958
|
-
borderColor: theme.color.borderRingCream,
|
|
1959
|
-
padding: theme.space.lg
|
|
1960
|
-
},
|
|
1961
|
-
// Safe disabled reason: the warm muted ramp, on-brand type scale, legible in both themes.
|
|
1962
|
-
reasonText: {
|
|
1963
|
-
marginTop: theme.space.sm,
|
|
1964
|
-
fontFamily: theme.type.family,
|
|
1965
|
-
fontSize: theme.type.size.bodyTight,
|
|
1966
|
-
lineHeight: Math.round(theme.type.size.bodyTight * theme.type.lineHeight.normal),
|
|
1967
|
-
fontWeight: theme.type.weight.medium,
|
|
1968
|
-
color: theme.color.text.muted,
|
|
1969
|
-
textAlign: "center"
|
|
1970
|
-
}
|
|
1971
|
-
});
|
|
1972
|
-
}
|
|
1973
|
-
|
|
1974
|
-
exports.CACHE_EPOCH_STORAGE_KEY = CACHE_EPOCH_STORAGE_KEY;
|
|
1975
|
-
exports.COMPILED_DEFAULT_IDLE = COMPILED_DEFAULT_IDLE;
|
|
1976
|
-
exports.COMPILED_DEFAULT_MANIFEST = COMPILED_DEFAULT_MANIFEST;
|
|
1977
|
-
exports.MANIFEST_LKG_STORAGE_KEY = MANIFEST_LKG_STORAGE_KEY;
|
|
1978
|
-
exports.NO_FAILURES = NO_FAILURES;
|
|
1979
|
-
exports.PetStateView = PetStateView;
|
|
1980
|
-
exports.SUPPORTED_SCHEMA_VERSION = SUPPORTED_SCHEMA_VERSION;
|
|
1981
|
-
exports.animationsSurfaceOf = animationsSurfaceOf;
|
|
1982
|
-
exports.createAnimationController = createAnimationController;
|
|
1983
|
-
exports.createCacheEpochGuard = createCacheEpochGuard;
|
|
1984
|
-
exports.createPetStateRepository = createPetStateRepository;
|
|
1985
|
-
exports.createPetStateStore = createPetStateStore;
|
|
1986
|
-
exports.isLoaderSafeCategory = isLoaderSafeCategory;
|
|
1987
|
-
exports.isTerminalPetStateError = isTerminalPetStateError;
|
|
1988
|
-
exports.mapPetStateResponse = mapPetStateResponse;
|
|
1989
|
-
exports.newSessionId = newSessionId;
|
|
1990
|
-
exports.parseManifest = parseManifest;
|
|
1991
|
-
exports.parsePetStateWire = parsePetStateWire;
|
|
1992
|
-
exports.petStateResponseWireSchema = petStateResponseWireSchema;
|
|
1993
|
-
exports.resolveManifest = resolveManifest;
|
|
1994
|
-
exports.retireTier = retireTier;
|
|
1995
|
-
exports.selectTier = selectTier;
|
|
1996
|
-
exports.stableMediaKey = stableMediaKey;
|
|
1997
|
-
exports.useAnimations = useAnimations;
|
|
1
|
+
'use strict';var react=require('react'),reactNative=require('react-native'),jsxRuntime=require('react/jsx-runtime'),zod=require('zod');var Mt=Object.defineProperty;var n=(e,t)=>Mt(e,"name",{value:t,configurable:true});function ie(e){if(e!==null&&typeof e=="object"&&!Object.isFrozen(e)){Object.freeze(e);for(let t of Object.keys(e))ie(e[t]);}return e}n(ie,"deepFreeze");var Dt=Object.freeze({content:0,heading:2,control:1.8,compact:1.5,badge:1.3}),Ue={xs:4,sm:8,md:12,lg:16,xl:24,xxl:32},Be={tile:5,xs:6,sm:10,md:14,lg:20,xl:28,pill:500},Le={nano:8,small:9,micro:10,tiny:11,caption:12,bodyTight:13,body:14,subtitle:16,heading:18,verdict:24},zt={tight:1.15,snug:1.3,normal:1.4,relaxed:1.55},jt={regular:"400",medium:"500",bold:"700"},Nt={eyebrow:1,monoWide:.9,headerBrand:-0.42,tight:-0.35},Lt=0,G="System",Y="monospace",Ut=["content","heading","control","compact","badge"];function Bt(e){let t={};for(let r of Ut)t[r]=e;return t}n(Bt,"authoredTierSizes");function Ke(){return {family:G,mono:Y,fontUrl:null,families:{regular:G,medium:G,bold:G,mono:Y,monoMedium:Y,monoBold:Y},namedFaces:{regular:false,medium:false,bold:false,mono:false,monoMedium:false,monoBold:false},fontUrls:{},size:Le,tierSizes:Bt(Le),lineHeight:zt,weight:jt,letterSpacing:Nt,scale:1,maxScale:Lt,scaleCaps:Dt}}n(Ke,"baseType");var qe={},oe=Object.freeze({standard:Object.freeze([.2,0,0,1]),emphasized:Object.freeze([.2,.8,.2,1]),exit:Object.freeze([.4,0,1,1])});function ae(e){return `cubic-bezier(${e.join(", ")})`}n(ae,"cssCubicBezier");var Ve={duration:{instant:80,fast:140,normal:220,slow:320},spring:{gentle:{damping:18,stiffness:200}},easing:{standard:ae(oe.standard),emphasized:ae(oe.emphasized),exit:ae(oe.exit)},reducedMotion:false},Kt={brand:"#10462E",brandSoft:"rgba(16,70,46,0.10)",brandSofter:"rgba(16,70,46,0.15)",brandBorder:"rgba(16,70,46,0.18)",borderHairlineGreen:"rgba(16,70,46,0.25)",brandBorderStrong:"rgba(16,70,46,0.55)",brandInk:"#10462E",linkInk:"#10462E",surface:"#FFFFFF",surfaceCream:"#FDFBF8",surfaceSubtle:"#EFE9E3",background:"#FFFFFF",borderRingCream:"#D8D2C8",chatGround:"#FFFFFF",composerFill:"#FDFBF8",composerBorder:"rgba(16,70,46,0.75)",shadow:"#0B3421",text:{primary:"#111111",secondary:"#0E462E",muted:"#6E6660",placeholder:"rgba(61,61,61,0.75)",onBrand:"#FFFFFF",metaCool:"#3D3D3D",timestamp:"rgba(61,61,61,0.75)"},primary:"#10462E",onPrimary:"#FFFFFF",accent:"#10462E",onAccent:"#FFFFFF",accentEdge:"#07C168",success:"#07C168",danger:"#B91C1C",errorRed:"#FF1B00",warningStrong:"#A45610",cautionAccent:"#D9821D",riskConcern:"#EFA700",sentiment:{up:"#07C168",neutral:"#FBC558",down:"#FF1B00"},badgeBgPositive:"rgba(7,193,104,0.12)",badgeBgCaution:"rgba(217,130,29,0.14)",badgeBgCritical:"rgba(185,28,28,0.12)",badgeBgNeutral:"rgba(110,102,96,0.12)",bubbleUser:"#10462E",bubbleAssistant:"#FFFFFF",skeleton:"#EFE9E3",scanButtonPink:"#FFC3BC",checkupCardLowRiskBg:"rgba(7,193,104,0.10)",checkupCardConcernBg:"rgba(239,167,0,0.10)"},He=ie({brightness:"light",highContrast:false,meta:{displayName:"Everfur",logoUrl:null,placeholder:null,hidePoweredBy:false},color:Kt,space:Ue,radius:Be,type:Ke(),motion:Ve,slots:qe}),qt={brand:"#6BD39A",brandSoft:"rgba(107,211,154,0.12)",brandSofter:"rgba(107,211,154,0.18)",brandBorder:"rgba(107,211,154,0.22)",borderHairlineGreen:"rgba(107,211,154,0.28)",brandBorderStrong:"rgba(107,211,154,0.55)",brandInk:"#6BD39A",linkInk:"#6BD39A",surface:"#1C1F23",surfaceCream:"#23272C",surfaceSubtle:"#23272C",background:"#15171A",borderRingCream:"#3A3F45",chatGround:"#1C1F23",composerFill:"#23272C",composerBorder:"rgba(107,211,154,0.75)",shadow:"#000000",text:{primary:"#F5F3F0",secondary:"#A9E4C4",muted:"#9A938C",placeholder:"rgba(255,255,255,0.55)",onBrand:"#0E1F17",metaCool:"#C9C9C9",timestamp:"rgba(245,243,240,0.7)"},primary:"#6BD39A",onPrimary:"#0E1F17",accent:"#6BD39A",onAccent:"#0E1F17",accentEdge:"#34D888",success:"#07C168",danger:"#F87171",errorRed:"#FF6B5B",warningStrong:"#F0A35E",cautionAccent:"#D9821D",riskConcern:"#EFA700",sentiment:{up:"#07C168",neutral:"#FBC558",down:"#FF1B00"},badgeBgPositive:"rgba(7,193,104,0.18)",badgeBgCaution:"rgba(217,130,29,0.20)",badgeBgCritical:"rgba(185,28,28,0.22)",badgeBgNeutral:"rgba(255,255,255,0.10)",bubbleUser:"#6BD39A",bubbleAssistant:"#1C1F23",skeleton:"#23272C",scanButtonPink:"#FFC3BC",checkupCardLowRiskBg:"rgba(7,193,104,0.16)",checkupCardConcernBg:"rgba(239,167,0,0.16)"};ie({brightness:"dark",highContrast:false,meta:{displayName:"Everfur",logoUrl:null,placeholder:null,hidePoweredBy:false},color:qt,space:Ue,radius:Be,type:Ke(),motion:Ve,slots:qe});var We=Symbol.for("@everfur/sdk#EverfurThemeContext@v1"),Ge=globalThis,se=Ge[We]??(Ge[We]=react.createContext(He));se.displayName??="EverfurThemeContext";function M(){return react.useContext(se)}n(M,"useEverfurTheme");function $t(e,t){let r=e.scaleCaps[t];return r>0?r:void 0}n($t,"tierMultiplier");function $({tier:e="content",...t}){let{type:r}=M(),o=$t(r,e);return react.createElement(reactNative.Text,o===void 0?t:{maxFontSizeMultiplier:o,...t})}n($,"Text");react.forwardRef(n(function(t,r){return react.createElement(reactNative.TextInput,{...t,...r===null?{}:{ref:r}})},"TextInput"));function Q(e){throw new Error(`assertNever: unhandled discriminated-union member ${JSON.stringify(e)}`)}n(Q,"assertNever");function $e(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($e,"errorFrame");var Jt=Object.freeze({regular:"regular",medium:"medium",bold:"bold",mono:"regular",monoMedium:"medium",monoBold:"bold"});function Qe(e,t){let r=e.type,o=r.families[t];return t==="mono"||r.namedFaces[t]?{fontFamily:o}:{fontFamily:o,fontWeight:r.weight[Jt[t]]}}n(Qe,"face");var ue=class ue extends react.Component{constructor(){super(...arguments);this.state={failed:false,key:this.props.resetKey};}static getDerivedStateFromError(){return {failed:true}}static getDerivedStateFromProps(r,o){return Object.is(r.resetKey,o.key)?null:{failed:false,key:r.resetKey}}render(){return this.state.failed?this.props.fallback:this.props.children}};n(ue,"HostRenderBoundary");var le=ue;function er({render:e}){return e()}n(er,"RenderHost");function de({render:e,fallback:t,resetKey:r}){return react.createElement(le,{fallback:t,resetKey:r,children:react.createElement(er,{render:e})})}n(de,"HostRender");var ce=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(ce.map(e=>e.wireCode));var tr=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"}),Ze=Object.freeze(ce.map(e=>Object.freeze({wireCode:e.wireCode,envelope:e.envelope,retryable:e.retryable,normalized:tr[e.wireCode]}))),rr=new Map(Ze.map(e=>[e.envelope+e.wireCode.toUpperCase(),e])),nr=Object.freeze(["http_envelope",...[...new Set(Ze.map(e=>e.envelope))].filter(e=>e!=="http_envelope").sort()]);function X(e,t){if(typeof e!="string")return;let r=e.trim().toUpperCase();if(r.length!==0)for(let o of [t??"http_envelope",...nr]){let a=rr.get(o+r);if(a)return a}}n(X,"contractErrorFor");function or(e){return e.envelope==="sse_frame"?`/errors#sse-${e.wireCode}`:e.envelope==="oauth_error"?`/errors#oauth-${e.wireCode}`:`/errors#${e.wireCode}`}n(or,"contractDocUrl");function et(e){return null}n(et,"publishedDocUrl");var ar=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 tt(e){return ar[e]}n(tt,"categoryFor");function rt(e){let t=X(e);if(t)return t.normalized;let r=(e??"").trim().toUpperCase(),o=r.replace(/[^A-Z0-9]/g,"");if(o==="AUTHREJECTED")return "authRejected";if(r.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(rt,"fromWire");var ir=new Set(["streamTimeout","rateLimited","internalError","upstreamLlmTimeout","streamIncomplete"]);function pe(e){return ir.has(e)}n(pe,"isAutoRetryable");var sr=new Set(["serviceUnavailable","conflict","idempotencyInFlight"]);function nt(e){return pe(e)||sr.has(e)}n(nt,"isRetryableCode");var lr=500,fe=8e3,ot=4;function at(e,t=Math.random){let r=Math.max(0,e),o=Math.min(lr*2**r,fe);return Math.floor(t()*o)}n(at,"backoffDelayMs");var dr=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 U(e){return dr[e]}n(U,"userFacingError");function it(e,t,r){Object.defineProperty(e,t,{value:r,enumerable:false,writable:false,configurable:false});}n(it,"defineHidden");var ur=/^[a-z][a-z0-9_]{0,63}$/;function N(e,t){let r=X(t?.wireCode,t?.wireEnvelope),o={code:e,category:tt(e),retryable:t?.retryable??nt(e),displayMessage:U(e)};if(t?.httpStatus!==void 0&&(o.httpStatus=t.httpStatus),t?.requestId&&(o.requestId=t.requestId),typeof t?.reasonCode=="string"&&ur.test(t.reasonCode)&&(o.reasonCode=t.reasonCode),r);return t?.wireMessage&&it(o,"wireMessage",t.wireMessage),t?.raw!==void 0&&t.raw!==null&&it(o,"raw",t.raw),Object.freeze(o)}n(N,"makeEverfurError");var cr=Object.freeze({chat:Object.freeze(["chat.message.create"]),records:Object.freeze(["records.upload.create","records.record.read"]),recordsClinic:Object.freeze(["records.clinic.create"]),video:Object.freeze(["video.gait.execute"]),photo:Object.freeze(["photo.checkup.execute"]),animations:Object.freeze(["animations.state.read"]),televet:Object.freeze(["televet.visit.create"])});function pr(e){return cr[e]}n(pr,"requires");function st(e,t,r){let o=pr(e),a=new Map;for(let c of t)a.set(c.resource,c);if(r?.isPending===true&&o.some(c=>!a.has(c)))return ye({name:e,enabled:false,isPending:true,limits:{}});let s=fr(o,a);return o.filter(c=>a.get(c)?.granted!==true).length===0?ye({name:e,enabled:true,isPending:false,limits:s}):ye({name:e,enabled:false,isPending:false,limits:s,disabled:yr(o,a)})}n(st,"decideCapability");function fr(e,t){let r={};for(let o of e){let a=t.get(o)?.limits;if(a)for(let[s,d]of Object.entries(a)){let c=r[s];r[s]=c===void 0?d:Math.min(c,d);}}return r}n(fr,"mergeLimits");function yr(e,t){for(let r of e){let o=t.get(r)?.disabled;if(o)return Object.freeze({reason:o.reason,level:o.level,recoverable:o.recoverable})}return Object.freeze({reason:U("accessDenied"),level:"user_entitlement",recoverable:false})}n(yr,"disabledFor");function ye(e){let t={name:e.name,enabled:e.enabled,isPending:e.isPending,limits:Object.freeze({...e.limits})};return e.disabled!==void 0&&(t.disabled=e.disabled),Object.freeze(t)}n(ye,"freezeDecision");function me(e,t){return Object.freeze(t===void 0?{ok:true,value:e}:{ok:true,value:e,warning:t})}n(me,"ok");function P(e){return Object.freeze({ok:false,error:e})}n(P,"err");var J=class J extends Error{constructor(t,r){super(r),this.name="EverfurConfigError",this.kind=t,Object.setPrototypeOf(this,J.prototype);}};n(J,"EverfurConfigError");var B=J;var lt=Symbol.for("@everfur/sdk#EverfurContext@v1"),dt=globalThis,ut=dt[lt]??(dt[lt]=react.createContext(null));ut.displayName??="EverfurContext";function Z(){let e=react.useContext(ut);if(e===null)throw new B("not-initialized","Everfur hooks must be called inside <EverfurProvider>. Wrap your tree once, high.");return e}n(Z,"useEverfurContext");function K(e){let{runtime:t}=Z(),r=t.entitlements,o=react.useSyncExternalStore(r.subscribe,r.getSnapshot,r.getSnapshot);return react.useMemo(()=>st(e,o.decisions,{isPending:o.isPending}),[e,o])}n(K,"useCapability");var hr=48;function Er(e){return e.isPending?"pending":e.enabled?"enabled":"disabled"}n(Er,"selectView");function yt(e){let{capability:t,children:r,renderDisabled:o,renderPending:a,style:s}=e,d=K(t),c=react.useMemo(()=>Er(d),[d]);switch(c){case "enabled":return r;case "pending":return a?jsxRuntime.jsx(de,{render:a,fallback:jsxRuntime.jsx(pt,{capability:t,style:s})}):jsxRuntime.jsx(pt,{capability:t,style:s});case "disabled":return o?jsxRuntime.jsx(de,{render:()=>o(d),fallback:jsxRuntime.jsx(ft,{decision:d,style:s}),resetKey:d}):jsxRuntime.jsx(ft,{decision:d,style:s});default:return Q(c)}}n(yt,"CapabilityGate");function pt({capability:e,style:t}){let r=M(),o=react.useMemo(()=>mt(r),[r]);return jsxRuntime.jsx(reactNative.View,{style:[o.offstate,t],accessible:true,accessibilityState:{busy:true},accessibilityLabel:`Loading ${e}`,children:jsxRuntime.jsx(reactNative.View,{style:o.skeletonBar})})}n(pt,"PendingSkeleton");function ft({decision:e,style:t}){let r=M(),o=react.useMemo(()=>mt(r),[r]),a=e.disabled?.reason??"";return jsxRuntime.jsx(reactNative.View,{style:[o.offstate,t],accessible:true,accessibilityRole:"text",accessibilityLabel:a,children:a.length>0?jsxRuntime.jsx($,{style:o.offstateText,children:a}):null})}n(ft,"OffState");function mt(e){let{color:t,space:r,radius:o,type:a}=e;return reactNative.StyleSheet.create({offstate:{minHeight:hr,justifyContent:"center",paddingHorizontal:r.lg,paddingVertical:r.md,backgroundColor:t.surfaceCream,borderRadius:o.md,borderWidth:reactNative.StyleSheet.hairlineWidth,borderColor:t.brandBorder},offstateText:{...Qe(e,"regular"),fontSize:a.size.body,lineHeight:Math.round(a.size.body*a.lineHeight.normal),color:t.text.muted},skeletonBar:{height:r.md,borderRadius:o.xs,backgroundColor:t.brandSofter}})}n(mt,"makeStyles");function _r(){let e=new Uint8Array(16),t=globalThis.crypto;if(typeof t?.getRandomValues=="function")t.getRandomValues(e);else for(let o=0;o<e.length;o+=1)e[o]=Math.floor(Math.random()*256);e[6]=e[6]&15|64,e[8]=e[8]&63|128;let r=[];for(let o=0;o<e.length;o+=1)r.push(e[o].toString(16).padStart(2,"0"));return r.slice(0,4).join("")+"-"+r.slice(4,6).join("")+"-"+r.slice(6,8).join("")+"-"+r.slice(8,10).join("")+"-"+r.slice(10,16).join("")}n(_r,"newSessionId");function Sr(e){let t={};return e.mode==="personalized"?t.authorization=`Bearer ${e.token}`:t["x-everfur-partner-key"]=e.publishableKey,e.userRef&&(t["x-everfur-user-ref"]=e.userRef),e.sessionId&&(t["x-everfur-session-id"]=e.sessionId),t}n(Sr,"authHeaders");function q(e,t){return {...e,headers:{...Rr(e.headers),...Sr(t)}}}n(q,"withAuthHeaders");function Rr(e){if(!e)return {};let t={};for(let[r,o]of Object.entries(e)){let a=r.toLowerCase();a==="authorization"||a==="x-everfur-partner-key"||(t[r]=o);}return t}n(Rr,"stripAuthHeaders");async function bt(e,t){if(t.mode==="anonymous")return t.transport.request(q(e,{mode:"anonymous",publishableKey:t.publishableKey,userRef:t.userRef,...t.sessionId?{sessionId:t.sessionId}:{}}));let r;try{r=await t.identity.currentToken();}catch{return P(ge())}let o=await t.transport.request(q(e,{mode:"personalized",token:r,userRef:t.userRef,...t.sessionId?{sessionId:t.sessionId}:{}}));if(o.ok||o.error.httpStatus!==401)return o;let a;try{a=await t.identity.currentToken({forceRefresh:!0});}catch{return P(ge())}let s=await t.transport.request(q(e,{mode:"personalized",token:a,userRef:t.userRef,...t.sessionId?{sessionId:t.sessionId}:{}}));return !s.ok&&s.error.httpStatus===401?P(ge(s.error.httpStatus)):s}n(bt,"authedSend");function ge(e){return N("authRejected",{retryable:false,...e!==void 0?{httpStatus:e}:{}})}n(ge,"authRejectedError");function vt(e){return N("internalError",{retryable:true,wireMessage:Tr(e)})}n(vt,"networkError");function Tr(e){return e instanceof Error?e.message:typeof e=="string"?e:"network request failed"}n(Tr,"describeCause");var Cr=3e4,wr=fe*2,kr="idempotency-key",xr=new Set(["POST","PUT","PATCH","DELETE"]),Fr=Object.freeze({onEvent(){}}),Pr=Object.freeze({setTimeout:n((e,t)=>setTimeout(e,t),"setTimeout"),clearTimeout:n(e=>clearTimeout(e),"clearTimeout"),now:n(()=>Date.now(),"now")});function Or(e){let t=e.trim().replace(/[^A-Za-z0-9_.:-]/g,"-");return t.length===0?null:`efs_${t}`.slice(0,128)}n(Or,"seededIdempotencyKey");function ht(e){let t=e.observer??Fr,r=e.timers??Pr,o=e.rng??Math.random,a=e.sleep??((y,p)=>Vr(y,r,p)),s=e.maxAttempts??ot,d=e.unaryTimeoutMs??Cr,c=e.newIdempotencyKey??Ir(),m=n(y=>{try{t.onEvent(y);}catch{}},"emit");async function f(y,p,_){let S=_?.maxAttempts,F=Math.max(1,S??s),I=_?.idempotent??xr.has(p.method),h=_?.idempotencyKey===void 0?null:Or(_.idempotencyKey),C=I?h??c():null,z=Ar(p,C),l=0;for(;;){let v=n(T=>Object.freeze({call:y,method:p.method,path:p.path,attempt:l,...C?{idempotencyKey:C}:{},...T}),"stamp");m(v({phase:"attempt"}));let O=Kr(d,r),j=qr(O.signal,p.signal),i;try{i=await bt({...z,signal:j.signal},e.auth);}catch(T){i=P(vt(T));}finally{j.dispose(),O.cancel();}if(i.ok)return m(v({phase:"settled",ok:true,reason:"ok"})),i;let u=i.error,g=Dr(u,l,{maxAttempts:F,rng:o,now:r.now(),aborted:p.signal?.aborted===true,...S!==void 0?{perCallMaxAttempts:S}:{},...e.errorPolicy!==void 0?{policy:e.errorPolicy}:{}}),R={ok:false,code:u.code,reason:g.reason,...u.httpStatus!==void 0?{httpStatus:u.httpStatus}:{},...u.requestId!==void 0?{requestId:u.requestId}:{}};if(!g.retry)return m(v({phase:"settled",...R})),P(u);if(m(v({phase:"retry",...R,delayMs:g.delayMs})),await a(g.delayMs,p.signal),p.signal?.aborted===true)return m(v({phase:"settled",...R,reason:"aborted"})),P(u);l+=1;}}n(f,"send");async function b(y){return q(y,await Br(e.auth))}n(b,"authorize");async function*E(y,p,_){m(Object.freeze({call:y,phase:"stream.open",method:p.method,path:p.path,attempt:0}));try{yield*e.auth.transport.stream(p,_);}catch{yield $e({code:"internal_error",retryable:true,wireMessage:null,synthesized:true,lastEventId:null,serverRequestId:null});}}return n(E,"stream"),Object.freeze({send:f,authorize:b,stream:E})}n(ht,"createRequestFunnel");function Ar(e,t){let r={};for(let[o,a]of Object.entries(e.headers??{}))o.toLowerCase()!==kr&&(r[o]=a);return t!==null&&(r["Idempotency-Key"]=t),{...e,headers:r}}n(Ar,"assembleHeaders");function Ir(){let e=0;return ()=>`efk_${Date.now().toString(36)}_${(e++).toString(36)}_${Math.random().toString(36).slice(2,12)}`}n(Ir,"defaultIdempotencyKeyFactory");var Mr=10;function Dr(e,t,r){if(r.aborted)return {retry:false,reason:"aborted"};let o=zr(e);if(o==="quota")return {retry:false,reason:"daily-quota-exhausted"};if(o!=="burst"&&!pe(e.code))return {retry:false,reason:"terminal-code"};let a=o==="burst"?"burst-throttle":"retryable-code";if(n(()=>{if(r.policy===void 0)return false;try{return !r.policy.shouldRetry(e.code,t)}catch{return false}},"policyVetoedRetry")())return {retry:false,reason:"terminal-code"};let d=n(()=>{if(r.policy===void 0)return null;let f;try{f=r.policy.maxAttempts(e.code);}catch{return null}return typeof f!="number"||!Number.isFinite(f)?null:Math.max(1,Math.min(Mr,Math.floor(f)))},"policyCeiling"),c=r.perCallMaxAttempts??d()??r.maxAttempts;if(t+1>=c)return {retry:false,reason:"attempts-exhausted"};let m=jr(e,r.now);return m!==null?m>wr?{retry:false,reason:"server-reset-beyond-budget"}:{retry:true,reason:a,delayMs:m}:{retry:true,reason:a,delayMs:at(t,r.rng)}}n(Dr,"decideRetry");function zr(e){let t=e.code==="unknown"?rt(Ur(e.raw)):e.code;return t==="quotaExceeded"?"quota":t==="rateLimited"||e.httpStatus===429?"burst":null}n(zr,"throttleKind");function jr(e,t){let r=Nr(e.raw);if(r===null)return null;let o=r-t;return o>0?o:0}n(jr,"retryOverrideMs");function Nr(e){for(let t of Et(e)){let r=t.resets_at,o=Lr(r);if(o!==null)return o}return null}n(Nr,"findResetsAt");function Et(e){if(!gt(e))return [];let t=[e];for(let r of ["error","detail"]){let o=e[r];gt(o)&&t.push(o);}return t}n(Et,"candidateScopes");function Lr(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 t=Date.parse(e);return Number.isFinite(t)?t:null}return null}n(Lr,"parseInstantMs");function Ur(e){for(let t of Et(e)){let r=t.code;if(typeof r=="string"&&r.length>0)return r}return null}n(Ur,"rawWireCode");function gt(e){return typeof e=="object"&&e!==null}n(gt,"isRecord");async function Br(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(Br,"resolveDeviceAuth");function Kr(e,t){let r=new AbortController,o=t.setTimeout(()=>r.abort(),e);return {signal:r.signal,cancel:n(()=>t.clearTimeout(o),"cancel")}}n(Kr,"boundedSignal");function qr(e,t){let r=n(()=>{},"noop");if(!t)return {signal:e,dispose:r};let o=new AbortController;if(e.aborted||t.aborted)return o.abort(),{signal:o.signal,dispose:r};let a=n(()=>o.abort(),"onAbort");return e.addEventListener("abort",a,{once:true}),t.addEventListener("abort",a,{once:true}),{signal:o.signal,dispose:n(()=>{e.removeEventListener("abort",a),t.removeEventListener("abort",a);},"dispose")}}n(qr,"mergeSignals");function Vr(e,t,r){return e<=0||r?.aborted===true?Promise.resolve():new Promise(o=>{let a=t.setTimeout(()=>{r?.removeEventListener("abort",s),o();},e),s=n(()=>{t.clearTimeout(a),o();},"onAbort");r?.addEventListener("abort",s,{once:true});})}n(Vr,"delayAbortable");function _t(e){for(let t=0;t<e.length;t+=1){let r=e.charCodeAt(t);if(r>=55296&&r<=56319){let o=e.charCodeAt(t+1);if(!(o>=56320&&o<=57343))return true;t+=1;}else if(r>=56320&&r<=57343)return true}return false}n(_t,"hasLoneSurrogate");function he(e){let t={url:e.url,kind:e.kind,expiresAt:e.expires_at};return typeof e.loop_duration_ms=="number"&&(t.loopDurationMs=e.loop_duration_ms),typeof e.cache_key=="string"&&e.cache_key.length>0&&(t.cacheKey=e.cache_key),Object.freeze(t)}n(he,"mapTier");function Ee(e){let t={};e.tiers.animation&&(t.animation=he(e.tiers.animation)),e.tiers.image&&(t.image=he(e.tiers.image));let r={};e.overlays.weather_alert&&(r.weatherAlert=he(e.overlays.weather_alert));let o={category:e.category,tiers:Object.freeze(t),overlays:Object.freeze(r),idle:"bundled",ttlSeconds:e.ttl_seconds,degraded:e.degraded};return typeof e.cache_epoch=="number"&&(o.cacheEpoch=e.cache_epoch),Object.freeze(o)}n(Ee,"mapPetStateResponse");var Hr=zod.z.enum(["webp","video"]),Wr=zod.z.enum(["health","attention","moment","activity","mood","idle"]),_e=zod.z.object({url:zod.z.string(),kind:Hr.default("webp"),loop_duration_ms:zod.z.number().nullish(),expires_at:zod.z.string(),cache_key:zod.z.string().nullish()}),St=zod.z.object({category:Wr,tiers:zod.z.object({animation:_e.optional(),image:_e.optional()}).default({}),overlays:zod.z.object({weather_alert:_e.optional()}).default({}),idle:zod.z.literal("bundled").default("bundled"),ttl_seconds:zod.z.number(),degraded:zod.z.boolean().default(false),cache_epoch:zod.z.number().default(0)});function Se(e){let t=St.safeParse(e);return t.success?t.data:null}n(Se,"parsePetStateWire");function Re(e){return Gr(ht({auth:e}))}n(Re,"createPetStateRepository");function Gr(e){return {async getState(t,r){if(_t(t))return P(N("validationFailed",{retryable:false,wireMessage:"pet_ref contains an unpaired surrogate and cannot be encoded"}));let o=`/widget/v1/pets/${encodeURIComponent(t)}/state`,a=await e.send("animations.getState",r?.signal?{method:"GET",path:o,signal:r.signal}:{method:"GET",path:o});if(a.ok){let s=Se(a.value);return s===null?P(N("internalError",{retryable:true})):me(Ee(s))}return a.error.httpStatus===404?me(null):P(a.error)}}}n(Gr,"createPetStateRepositoryOver");function Te(e){if(e===void 0)return "bundled:none";if(typeof e=="number")return `bundled:${e}`;if("kind"in e)return `bundled:${e.id}`;let t=e.uri,r=t.indexOf("?");return r===-1?t:t.slice(0,r)}n(Te,"stableMediaKey");function Ce(e){return e.hasPhoto&&!e.photoFailed?"photo":e.canAnimate&&!e.animationFailed?"animation":e.hasImage&&!e.imageFailed?"image":"idle"}n(Ce,"selectTier");function we(e,t){switch(e){case "photo":return {failed:V({...t,photo:true}),reason:"network_error"};case "animation":return {failed:V({...t,animation:true}),reason:"network_error"};case "image":return {failed:V({...t,image:true}),reason:"network_error"};case "idle":return {failed:V(t),reason:"idle_asset_failed"};default:return {failed:V(t),reason:"network_error"}}}n(we,"retireTier");var H=Object.freeze({photo:false,animation:false,image:false});function V(e){return Object.freeze({photo:e.photo,animation:e.animation,image:e.image})}n(V,"freezeFailed");function Yr(e){switch(e){case "activity":case "mood":case "moment":case "idle":return true;case "health":case "attention":return false;default:return false}}n(Yr,"isLoaderSafeCategory");var ke="everfur.petState.cacheEpoch";function xe(e){let t=0,r=false,o=null,a=n(async s=>{if(r||(t=await $r(e.kv),r=true),s<=t)return false;try{await e.kv.setItem(ke,String(s));}catch{}t=s;try{await e.cache.clearMemoryCache();}catch{}try{await e.cache.clearDiskCache();}catch{}return true},"run");return {async sync(s){return typeof s!="number"||!Number.isFinite(s)||s<=0||r&&s<=t?false:o||(o=a(s).finally(()=>{o=null;}),o)}}}n(xe,"createCacheEpochGuard");async function $r(e){let t;try{t=await e.getItem(ke);}catch{return 0}if(t===null)return 0;let r=Number(t);return Number.isFinite(r)&&r>0?r:0}n($r,"readStoredEpoch");var Fe=1,Pe="everfur.manifest.lastKnownGood",L=Object.freeze({kind:"bundled",id:"everfur-idle"}),W=Object.freeze({schemaVersion:Fe,revision:"compiled-default",surfaces:Object.freeze({animations:Object.freeze({enabled:true,idle:L})})}),Qr=zod.z.object({kind:zod.z.literal("bundled"),id:zod.z.string().min(1)}),Xr=zod.z.object({enabled:zod.z.boolean().default(true),idle:Qr.optional()}),Jr=zod.z.object({schema_version:zod.z.number().int(),revision:zod.z.string().default(""),surfaces:zod.z.object({animations:Xr.optional()}).default({})});function Oe(e){let t=Jr.safeParse(e);if(!t.success)return {ok:false,reason:"unparseable"};if(t.data.schema_version>Fe)return {ok:false,reason:"newer_schema"};let r=t.data.surfaces.animations,o={};return r&&(o.animations=Object.freeze({enabled:r.enabled,idle:r.idle?Object.freeze({...r.idle}):L})),{ok:true,manifest:Object.freeze({schemaVersion:t.data.schema_version,revision:t.data.revision,surfaces:Object.freeze(o)})}}n(Oe,"parseManifest");async function Zr(e,t,r){if(e!=null){let a=Oe(e);if(a.ok)return await en(t,e),r.track("manifest.fallback",{source:"live"}),Object.freeze({manifest:a.manifest,source:"live"});a.reason==="newer_schema"&&r.track("manifest.refused_newer",{});}let o=await tn(t);return o?(r.track("manifest.fallback",{source:"last-known-good"}),Object.freeze({manifest:o,source:"last-known-good"})):(r.track("manifest.fallback",{source:"compiled-default"}),Object.freeze({manifest:W,source:"compiled-default"}))}n(Zr,"resolveManifest");function Ae(e){return e.surfaces.animations??W.surfaces.animations??{enabled:true,idle:L}}n(Ae,"animationsSurfaceOf");async function en(e,t){try{await e.setItem(Pe,JSON.stringify(t));}catch{}}n(en,"writeLastKnownGood");async function tn(e){let t;try{t=await e.getItem(Pe);}catch{return null}if(t===null)return null;let r;try{r=JSON.parse(t);}catch{return null}let o=Oe(r);return o.ok?o.manifest:null}n(tn,"readLastKnownGood");var Rt=Object.freeze({data:null,isPending:false,isError:false,error:null,isDark:false});function Ie(e){let{repo:t,cacheEpoch:r,timers:o}=e,a=new Set,s=new Map,d=Rt,c=null,m=null,f=false,b=null,E=null,y=null,p=0,_=n(()=>{for(let i of a)i();},"emit"),S=n(i=>{d=Object.freeze({...d,...i}),_();},"patch"),F=n(()=>{E!==null&&(o.clearTimeout(E),E=null);},"clearRemint"),I=n(i=>i?Math.max(1,i.ttlSeconds)*1e3:6e4,"staleMs"),h=n(i=>{let u=s.get(i);u!==void 0&&(s.delete(i),s.set(i,u));},"touchWarm"),C=n((i,u)=>{for(s.delete(i),s.set(i,Object.freeze({data:u,fetchedAt:o.now()}));s.size>32;){let g=s.keys().next().value;if(g===void 0||g===i)break;s.delete(g);}},"setWarm"),z=n(i=>{let u=s.get(i);return u?!!(u.data.tiers.animation||u.data.tiers.image):false},"hasGoodTiers"),l=n((i,u)=>{if(F(),!f)return;let g=Math.max(1,u)*1e3,R=p;E=o.setTimeout(()=>{E=null,!(R!==p||c!==i||!f)&&v(i,0);},g);},"scheduleRemint"),v=n(async(i,u)=>{if(c!==i||b===i||!f)return;let g=p;y?.abort();let R=new AbortController;y=R;let T=await t.getState(i,{signal:R.signal});if(!(g!==p||c!==i)){if(T.ok){let w=T.value;if(w===null){O(i);return}r.sync(w.cacheEpoch);let ne=!!(w.tiers.animation||w.tiers.image);if(w.degraded&&!ne&&z(i)){S({isError:false,error:null,isPending:false,isDark:false}),l(i,w.ttlSeconds);return}C(i,w),m=i,S({data:w,isPending:false,isError:false,error:null,isDark:false}),l(i,w.ttlSeconds);return}if(Tt(T.error)){j(i,T.error);return}if(S({isError:true,error:T.error,isPending:d.data===null&&m!==i}),u<2){F();let w=500*(u+1),ne=p;E=o.setTimeout(()=>{E=null,!(ne!==p||c!==i||!f)&&v(i,u+1);},w);}else l(i,5);}},"fetchOnce"),O=n(i=>{b=i,s.delete(i),F(),m=i,S({data:null,isPending:false,isError:false,error:null,isDark:true});},"onTerminalDark"),j=n((i,u)=>{b=i,s.delete(i),F(),m=i,S({data:null,isPending:false,isError:false,error:u,isDark:true});},"onTerminalDisabled");return {observe(i,u){let g=u.isFocused!==f;if(f=u.isFocused,i!==c){if(p+=1,y?.abort(),y=null,F(),b=null,c=i,i===null){m=null,d=Rt,_();return}let T=s.get(i),w=T&&o.now()-T.fetchedAt<I(T.data)?T:null;w?(h(i),m=i,S({data:w.data,isPending:false,isError:false,error:null,isDark:false})):S({isPending:true,isError:false,error:null,isDark:false}),f&&v(i,0);return}if(!g||i===null)return;if(!f){F();return}let R=s.get(i);!R||o.now()-R.fetchedAt>=I(R.data)?b!==i&&v(i,0):l(i,R.data.ttlSeconds);},getSnapshot(){return d},subscribe(i){return a.add(i),()=>{a.delete(i);}},getCachedPetStateMedia(i){let u=s.get(i);return !u||o.now()-u.fetchedAt>=I(u.data)?null:(h(i),u.data)},dispose(){p+=1,y?.abort(),y=null,F(),a.clear(),s.clear();}}}n(Ie,"createPetStateStore");function Tt(e){if(typeof e!="object"||e===null)return false;let t=e,r=typeof t.status=="number"?t.status:t.httpStatus;return r===403||r===404}n(Tt,"isTerminalPetStateError");var Ct=Object.freeze({track(){},trackExpectedFailure(){}});function ee(e){let t=e.telemetry??Ct,r=e.timers??on(e.now),o=Ie({repo:e.repo,cacheEpoch:xe({kv:e.kv,cache:e.cache}),timers:r}),a=new Set,s=H,d="none",c=false,m=null,f=null,b=false,E=0,y="",p=nn(S()),_=false;function S(){let l=e.manifest?e.manifest():W;return Ae(l)}n(S,"surface");let F=n(()=>{for(let l of a)l();},"emit"),I=o.subscribe(()=>{h();});function h(){let l=o.getSnapshot();(l.data!==f||l.isDark!==b)&&(f=l.data,b=l.isDark,s=H,d=l.isDark?"dark_or_missing":"none",E+=1),C(l);}n(h,"onStoreChange");function C(l=o.getSnapshot()){let v=S(),O=rn(v,l,{failed:s,fallbackReason:d,paused:c,photoUrl:m,reducedMotion:e.reducedMotion()});p=O,z(O),F();}n(C,"recompute");function z(l){if(l.kind!=="ready")return;let v=`${l.category}|${l.tier}|${l.fallbackReason}|${l.reducedMotion?1:0}`;v!==y&&(y=v,t.track("pet_state_shown",{category:l.category,tier:l.tier,fallback_reason:l.fallbackReason,reduced_motion:l.reducedMotion}),l.fallbackReason==="idle_asset_failed"&&t.trackExpectedFailure("idle_asset_failed",{category:l.category}));}return n(z,"maybeEmitShown"),{observe(l,v){_||(m=v.photoUrl??null,s=H,o.observe(l,{isFocused:v.isFocused}),h());},getState(){return p},subscribe(l){return a.add(l),()=>{a.delete(l);}},onMediaError(){if(_||p.kind!=="ready")return;let l=we(p.tier,s);s=l.failed,d=l.reason,C();},setPaused(l){_||c===l||(c=l,C());},dispose(){_||(_=true,I(),o.dispose(),a.clear());}}}n(ee,"createAnimationController");function rn(e,t,r){let o=e.idle;if(!e.enabled)return Object.freeze({kind:"disabled",reason:U("accessDenied"),level:"partner_config",source:o,idle:e.idle});if(t.isPending&&t.data===null&&!t.isDark)return Object.freeze({kind:"pending",showSkeleton:true,source:o});let a=t.data,s=a?.category??"idle",d=a?.tiers.animation,c=a?.tiers.image,m=!!d&&d?.kind==="webp"&&!r.reducedMotion&&!r.failed.animation,f=Ce({hasPhoto:r.photoUrl!==null&&r.photoUrl.length>0,photoFailed:r.failed.photo,canAnimate:m,animationFailed:r.failed.animation,hasImage:!!c,imageFailed:r.failed.image}),b=o,E=null,y=false;f==="photo"&&r.photoUrl?b=Me(r.photoUrl,void 0):f==="animation"&&d?(b=Me(d.url,d.cacheKey),E=d.loopDurationMs??null,y=d.cacheKey!==void 0):f==="image"&&c&&(b=Me(c.url,c.cacheKey),y=c.cacheKey!==void 0);let p=b.kind==="uri"?b.cacheKey:`bundled:${b.id}`;return Object.freeze({kind:"ready",tier:f,source:b,recyclingKey:p,category:s,loopDurationMs:E,paused:r.paused,reducedMotion:r.reducedMotion,cacheHit:y,fallbackReason:r.fallbackReason,isDark:t.isDark,isTransientError:t.isError})}n(rn,"buildView");function Me(e,t){return Object.freeze({kind:"uri",uri:e,cacheKey:t??Te({uri:e})})}n(Me,"uriSource");function nn(e){return Object.freeze({kind:"pending",showSkeleton:true,source:e.idle})}n(nn,"pendingView");function on(e){return {setTimeout:n((t,r)=>setTimeout(t,r),"setTimeout"),clearTimeout:n(t=>clearTimeout(t),"clearTimeout"),now:e}}n(on,"defaultTimers");var dn=Object.freeze({kind:"pending",showSkeleton:true,source:L}),un=n(()=>{},"NOOP_UNSUBSCRIBE");function ze(e){let{petRef:t,repo:r,cache:o,kv:a,isFocused:s=true,photoUrl:d=null,telemetry:c,reducedMotion:m,manifest:f,timers:b,now:E}=e,{runtime:y,userRef:p}=Z(),_=K("animations"),S=cn(m),I=r!==void 0&&o!==void 0&&a!==void 0?"override":`${p??""}|${t??""}`,[h,C]=react.useState(null);react.useEffect(()=>{if(r!==void 0&&o!==void 0&&a!==void 0){let g={repo:r,cache:o,kv:a,reducedMotion:S,now:E??kt,...c?{telemetry:c}:{},...f?{manifest:f}:{},...b?{timers:b}:{}},R=ee(g);return C(R),()=>{C(T=>T===R?null:T),R.dispose();}}let{services:i}=y.registry,u=y.registry.acquire("animations",`${p??""}|${t??""}`,()=>ee({repo:Re(i.authFor(p)),cache:i.imageCache,kv:i.kv,reducedMotion:S,now:E??kt,telemetry:i.telemetry,...f?{manifest:f}:{},...b?{timers:b}:{}}),g=>g.dispose());return C(u),()=>{C(g=>g===u?null:g),y.registry.release(u);}},[I,r,o,a,y]),react.useEffect(()=>{h?.observe(t,{isFocused:s,photoUrl:d});},[h,t,s,d]);let z=react.useCallback(i=>h?h.subscribe(i):un,[h]),l=react.useCallback(()=>h?h.getState():dn,[h]),v=react.useSyncExternalStore(z,l,l),O=react.useCallback(()=>{h?.onMediaError();},[h]),j=react.useCallback(i=>{h?.setPaused(i);},[h]);return react.useMemo(()=>({capability:_,state:v,onMediaError:O,setPaused:j}),[_,v,O,j])}n(ze,"useAnimations");function cn(e){let t=react.useRef(true);return react.useEffect(()=>{if(e)return;let r=true,o=reactNative.AccessibilityInfo.isReduceMotionEnabled?.();o&&typeof o.then=="function"&&o.then(s=>{r&&(t.current=s);});let a=reactNative.AccessibilityInfo.addEventListener?.("reduceMotionChanged",s=>{t.current=s;});return ()=>{r=false,a?.remove?.();}},[e]),react.useMemo(()=>e??(()=>t.current),[e])}n(cn,"useSystemReducedMotion");function kt(){return Date.now()}n(kt,"defaultNow");var vn=200,gn=300,je=120;function hn(e){let{style:t,accessibilityLabel:r}=e,o={accessibilityLabel:r,decorative:At(e)};return jsxRuntime.jsx(yt,{capability:"animations",style:t,renderPending:()=>jsxRuntime.jsx(re,{style:t,a11y:o,busy:true}),renderDisabled:a=>jsxRuntime.jsx(re,{style:t,a11y:o,reason:a.disabled?.reason??""}),children:jsxRuntime.jsx(En,{...e})})}n(hn,"PetStateView");function At(e){return e.decorative===true||e.accessibilityLabel===void 0}n(At,"isDecorative");function En(e){let t=Ne(),r={accessibilityLabel:e.accessibilityLabel,decorative:At(e)},o=ze(Rn(e));return jsxRuntime.jsx(reactNative.View,{style:[t.container,e.style],children:_n(o.state,o.onMediaError,r)})}n(En,"PetStateBody");function _n(e,t,r){switch(e.kind){case "pending":return jsxRuntime.jsx(Pt,{source:e.source,recyclingKey:"pending",reducedMotion:true,a11y:r,busy:true,onMediaError:t});case "disabled":return jsxRuntime.jsx(re,{a11y:r,reason:e.reason});case "ready":return jsxRuntime.jsx(Pt,{source:e.source,recyclingKey:e.recyclingKey,reducedMotion:e.reducedMotion,a11y:r,onMediaError:t});default:return Q(e)}}n(_n,"renderState");function Pt({source:e,recyclingKey:t,reducedMotion:r,a11y:o,busy:a,onMediaError:s}){let d=Ne();return e.kind==="uri"?jsxRuntime.jsx(reactNative.Image,{source:{uri:e.uri},onError:s,fadeDuration:r?0:vn,style:d.media,...It(o)},t):jsxRuntime.jsx(re,{a11y:o,busy:a})}n(Pt,"MediaNode");function re({style:e,a11y:t,busy:r,reason:o}){let a=Ne();return jsxRuntime.jsxs(reactNative.View,{style:[a.idlePlaceholder,e],...It(t),children:[r?jsxRuntime.jsx(Sn,{}):null,o&&o.length>0?jsxRuntime.jsx($,{style:a.reasonText,children:o}):null]})}n(re,"IdleRegion");function Sn(){let e=M(),[t,r]=react.useState(false);return react.useEffect(()=>{let o=setTimeout(()=>r(true),gn);return ()=>clearTimeout(o)},[]),t?jsxRuntime.jsx(reactNative.ActivityIndicator,{color:e.color.brand}):null}n(Sn,"DelayedSpinner");function It(e){if(e.decorative)return {accessible:false,accessibilityElementsHidden:true,importantForAccessibility:"no-hide-descendants"};let t=e.accessibilityLabel;return t!==void 0?{accessible:true,accessibilityRole:"image",accessibilityLabel:t}:{accessible:true,accessibilityRole:"image"}}n(It,"a11yProps");function Rn(e){let t={petRef:e.petRef,repo:e.repo,cache:e.cache,kv:e.kv};return e.isFocused!==void 0&&(t.isFocused=e.isFocused),e.photoUrl!==void 0&&(t.photoUrl=e.photoUrl),e.telemetry!==void 0&&(t.telemetry=e.telemetry),e.reducedMotion!==void 0&&(t.reducedMotion=e.reducedMotion),e.manifest!==void 0&&(t.manifest=e.manifest),e.timers!==void 0&&(t.timers=e.timers),e.now!==void 0&&(t.now=e.now),t}n(Rn,"buildParams");function Ne(){let e=M();return react.useMemo(()=>Tn(e),[e])}n(Ne,"useStyles");function Tn(e){return reactNative.StyleSheet.create({container:{minHeight:je,width:"100%",backgroundColor:e.color.surfaceCream,borderRadius:e.radius.lg,overflow:"hidden"},media:{minHeight:je,width:"100%"},idlePlaceholder:{minHeight:je,width:"100%",alignItems:"center",justifyContent:"center",backgroundColor:e.color.surfaceCream,borderRadius:e.radius.lg,borderWidth:reactNative.StyleSheet.hairlineWidth,borderColor:e.color.borderRingCream,padding:e.space.lg},reasonText:{marginTop:e.space.sm,fontFamily:e.type.family,fontSize:e.type.size.bodyTight,lineHeight:Math.round(e.type.size.bodyTight*e.type.lineHeight.normal),fontWeight:e.type.weight.medium,color:e.color.text.muted,textAlign:"center"}})}n(Tn,"makeStyles");exports.CACHE_EPOCH_STORAGE_KEY=ke;exports.COMPILED_DEFAULT_IDLE=L;exports.COMPILED_DEFAULT_MANIFEST=W;exports.MANIFEST_LKG_STORAGE_KEY=Pe;exports.NO_FAILURES=H;exports.PetStateView=hn;exports.SUPPORTED_SCHEMA_VERSION=Fe;exports.animationsSurfaceOf=Ae;exports.createAnimationController=ee;exports.createCacheEpochGuard=xe;exports.createPetStateRepository=Re;exports.createPetStateStore=Ie;exports.isLoaderSafeCategory=Yr;exports.isTerminalPetStateError=Tt;exports.mapPetStateResponse=Ee;exports.newSessionId=_r;exports.parseManifest=Oe;exports.parsePetStateWire=Se;exports.petStateResponseWireSchema=St;exports.resolveManifest=Zr;exports.retireTier=we;exports.selectTier=Ce;exports.stableMediaKey=Te;exports.useAnimations=ze;
|