cobrowse-agent-ui 1.7.0-rc.13 → 1.7.0-rc.14
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/README.md +12 -0
- package/dist/cobrowse-agent-ui.d.ts +63 -0
- package/dist/cobrowse-agent-ui.js +65 -45
- package/dist/cobrowse-agent-ui.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -89,6 +89,18 @@ const { data: accounts, refetch, unshift } = useAccountsContext()
|
|
|
89
89
|
the list. A bare `{ license_key }` can be selected before the list has loaded, e.g. an account forced from the URL,
|
|
90
90
|
and is resolved against the list once it arrives. After that it has to be in the list, or `setActiveAccount` throws.
|
|
91
91
|
|
|
92
|
+
## JWT SSO keys (experimental)
|
|
93
|
+
|
|
94
|
+
`useListJwtSsoKeys` lists the public keys the account trusts to sign JWTs for single sign-on, newest first, as
|
|
95
|
+
`useCollection` returns them. `useCreateJwtSsoKey` adds one, `useUpdateJwtSsoKey(key)` retitles a listed key and
|
|
96
|
+
`useDestroyJwtSsoKey(key)` removes it, each as `useMutation` returns them. A created key is put first in the list with
|
|
97
|
+
`unshift()`, a retitled one re-renders where it is, and a destroyed one drops out:
|
|
98
|
+
|
|
99
|
+
```jsx
|
|
100
|
+
const { data: keys, unshift } = useListJwtSsoKeys()
|
|
101
|
+
const { mutateAsync: createKey } = useCreateJwtSsoKey()
|
|
102
|
+
unshift(await createKey({ key: publicKeyPem, title: 'Production' }))
|
|
103
|
+
|
|
92
104
|
## Policies (experimental)
|
|
93
105
|
|
|
94
106
|
`useCurrentPolicy` requests the policy of the signed-in user on the SDK's current license, as `useResource` returns
|
|
@@ -11,6 +11,8 @@ import { ForwardedRef } from 'react';
|
|
|
11
11
|
import { i18n as i18n_2 } from 'i18next';
|
|
12
12
|
import { InitOptions } from 'i18next';
|
|
13
13
|
import { JSX } from 'react/jsx-runtime';
|
|
14
|
+
import { JWTSSOKey } from 'cobrowse-agent-sdk';
|
|
15
|
+
import { JWTSSOKeysQuery } from 'cobrowse-agent-sdk';
|
|
14
16
|
import { Policy } from 'cobrowse-agent-sdk';
|
|
15
17
|
import { QueryParams } from 'cobrowse-agent-sdk';
|
|
16
18
|
import { QueryShape } from 'cobrowse-agent-sdk';
|
|
@@ -585,6 +587,23 @@ export declare function useCreateAccount(): {
|
|
|
585
587
|
mutateAsync: (resource: Pick< AccountResource, "organisation_name">, options?: RequestOptions<QueryParams> | undefined) => Promise< Account>;
|
|
586
588
|
};
|
|
587
589
|
|
|
590
|
+
/** Trusts a public key, as SPKI PEM, to sign JWTs for the account, with an optional title. */
|
|
591
|
+
export declare function useCreateJwtSsoKey(): {
|
|
592
|
+
data: JWTSSOKey | null;
|
|
593
|
+
error: Error | null;
|
|
594
|
+
isPending: boolean;
|
|
595
|
+
isSuccess: boolean;
|
|
596
|
+
isError: boolean;
|
|
597
|
+
mutate: (key: {
|
|
598
|
+
key: string;
|
|
599
|
+
title?: string;
|
|
600
|
+
}, options?: RequestOptions<QueryParams> | undefined) => void;
|
|
601
|
+
mutateAsync: (key: {
|
|
602
|
+
key: string;
|
|
603
|
+
title?: string;
|
|
604
|
+
}, options?: RequestOptions<QueryParams> | undefined) => Promise< JWTSSOKey>;
|
|
605
|
+
};
|
|
606
|
+
|
|
588
607
|
/**
|
|
589
608
|
* The policy of the signed-in user on the SDK's current license: what they may do on each resource, as
|
|
590
609
|
* `policy.hasPermission('sessions:create')` and `policy.get('sessions')` answer it.
|
|
@@ -618,6 +637,17 @@ export declare function useDestroyAccount(account: Account): {
|
|
|
618
637
|
}) => Promise<Account>;
|
|
619
638
|
};
|
|
620
639
|
|
|
640
|
+
/** Stops trusting a key, through the key itself, so it drops out of the lists showing it. */
|
|
641
|
+
export declare function useDestroyJwtSsoKey(key: JWTSSOKey): {
|
|
642
|
+
data: JWTSSOKey | null;
|
|
643
|
+
error: Error | null;
|
|
644
|
+
isPending: boolean;
|
|
645
|
+
isSuccess: boolean;
|
|
646
|
+
isError: boolean;
|
|
647
|
+
mutate: (options?: RequestOptions<QueryParams> | undefined) => void;
|
|
648
|
+
mutateAsync: (options?: RequestOptions<QueryParams> | undefined) => Promise<JWTSSOKey>;
|
|
649
|
+
};
|
|
650
|
+
|
|
621
651
|
export declare function useListAccounts(options?: QueryOptions): {
|
|
622
652
|
data: Account[] | null;
|
|
623
653
|
error: Error | null;
|
|
@@ -636,6 +666,28 @@ export declare function useListAccounts(options?: QueryOptions): {
|
|
|
636
666
|
refetch: (options?: QueryRequestOptions<AccountsQuery> | undefined) => Promise<void>;
|
|
637
667
|
};
|
|
638
668
|
|
|
669
|
+
/**
|
|
670
|
+
* The public keys the account trusts to sign JWTs for single sign-on, newest first, a page at a time, as
|
|
671
|
+
* `useCollection` returns them. A key just created is put first with `unshift()`, and a destroyed one drops out.
|
|
672
|
+
*/
|
|
673
|
+
export declare function useListJwtSsoKeys(options?: QueryOptions): {
|
|
674
|
+
data: JWTSSOKey[] | null;
|
|
675
|
+
error: Error | null;
|
|
676
|
+
isError: boolean;
|
|
677
|
+
cancel: () => void;
|
|
678
|
+
pages: JWTSSOKey[][] | null;
|
|
679
|
+
hasMore: boolean;
|
|
680
|
+
isLoadingMore: boolean;
|
|
681
|
+
isLoadMoreError: boolean;
|
|
682
|
+
loadMore: () => Promise<void>;
|
|
683
|
+
unshift: (...entities: JWTSSOKey[]) => void;
|
|
684
|
+
isPending: boolean;
|
|
685
|
+
isSuccess: boolean;
|
|
686
|
+
isLoading: boolean;
|
|
687
|
+
isRefetching: boolean;
|
|
688
|
+
refetch: (options?: QueryRequestOptions<JWTSSOKeysQuery> | undefined) => Promise<void>;
|
|
689
|
+
};
|
|
690
|
+
|
|
639
691
|
export declare function useMutation<Args extends unknown[], Entity extends ObservableEntity>(fn: (...args: Args) => Promise<Entity>): {
|
|
640
692
|
data: Entity | null;
|
|
641
693
|
error: Error | null;
|
|
@@ -732,4 +784,15 @@ export declare function useUpdateAccount(account: Account): {
|
|
|
732
784
|
mutateAsync: (state: Partial< ResourceData<string>>, options?: RequestOptions<QueryParams> | undefined) => Promise<Account>;
|
|
733
785
|
};
|
|
734
786
|
|
|
787
|
+
/** Retitles a key through the key itself, so every hook showing it re-renders. */
|
|
788
|
+
export declare function useUpdateJwtSsoKey(key: JWTSSOKey): {
|
|
789
|
+
data: JWTSSOKey | null;
|
|
790
|
+
error: Error | null;
|
|
791
|
+
isPending: boolean;
|
|
792
|
+
isSuccess: boolean;
|
|
793
|
+
isError: boolean;
|
|
794
|
+
mutate: (state: Partial< ResourceData<string>>, options?: RequestOptions<QueryParams> | undefined) => void;
|
|
795
|
+
mutateAsync: (state: Partial< ResourceData<string>>, options?: RequestOptions<QueryParams> | undefined) => Promise<JWTSSOKey>;
|
|
796
|
+
};
|
|
797
|
+
|
|
735
798
|
export { }
|
|
@@ -538,27 +538,27 @@ var H = (e) => {
|
|
|
538
538
|
}, e))
|
|
539
539
|
})]
|
|
540
540
|
});
|
|
541
|
-
},
|
|
541
|
+
}, Re = {
|
|
542
542
|
root: "Reason-module__root__bZyjn",
|
|
543
543
|
checkbox: "Reason-module__checkbox__RlZNx focus-module__focusRing__rvgPB"
|
|
544
|
-
},
|
|
544
|
+
}, ze = ({ value: e, label: t, className: n }) => {
|
|
545
545
|
let { feedback: r, toggleReason: i } = W();
|
|
546
546
|
return /* @__PURE__ */ A("label", {
|
|
547
|
-
className: D(
|
|
547
|
+
className: D(Re.root, n),
|
|
548
548
|
children: [/* @__PURE__ */ k("input", {
|
|
549
549
|
type: "checkbox",
|
|
550
550
|
value: e,
|
|
551
551
|
checked: r.includes(e),
|
|
552
|
-
className:
|
|
552
|
+
className: Re.checkbox,
|
|
553
553
|
onChange: () => {
|
|
554
554
|
i(e);
|
|
555
555
|
}
|
|
556
556
|
}), t]
|
|
557
557
|
});
|
|
558
|
-
},
|
|
558
|
+
}, Be = { root: "Comment-module__root__aKZAY focus-module__focusRing__rvgPB" }, Ve = ({ placeholder: e, className: t }) => {
|
|
559
559
|
let { comment: n, setComment: r } = W(), { t: i } = l(), a = e == null ? i("Please describe any issues you experienced") : e;
|
|
560
560
|
return /* @__PURE__ */ k("textarea", {
|
|
561
|
-
className: D(
|
|
561
|
+
className: D(Be.root, t),
|
|
562
562
|
"aria-label": a,
|
|
563
563
|
placeholder: a,
|
|
564
564
|
value: n,
|
|
@@ -566,7 +566,7 @@ var H = (e) => {
|
|
|
566
566
|
r(e.target.value);
|
|
567
567
|
}
|
|
568
568
|
});
|
|
569
|
-
},
|
|
569
|
+
}, K = {
|
|
570
570
|
root: "Feedback-module__root__kH-Yg",
|
|
571
571
|
reasons: "Feedback-module__reasons__uPVdU"
|
|
572
572
|
}, He = ({ reasons: e, placeholder: t, className: n, children: r }) => {
|
|
@@ -591,14 +591,14 @@ var H = (e) => {
|
|
|
591
591
|
}
|
|
592
592
|
];
|
|
593
593
|
return /* @__PURE__ */ k("div", {
|
|
594
|
-
className: D(
|
|
594
|
+
className: D(K.root, n),
|
|
595
595
|
children: r == null ? /* @__PURE__ */ A(O, { children: [/* @__PURE__ */ k("div", {
|
|
596
|
-
className:
|
|
597
|
-
children: (e == null ? c : e).map((e) => /* @__PURE__ */ k(
|
|
596
|
+
className: K.reasons,
|
|
597
|
+
children: (e == null ? c : e).map((e) => /* @__PURE__ */ k(ze, {
|
|
598
598
|
value: e.value,
|
|
599
599
|
label: e.label
|
|
600
600
|
}, e.value))
|
|
601
|
-
}), /* @__PURE__ */ k(
|
|
601
|
+
}), /* @__PURE__ */ k(Ve, { placeholder: t })] }) : r
|
|
602
602
|
});
|
|
603
603
|
}, Ue = { root: "Submit-module__root__Mldgp" }, We = ({ className: e, children: t }) => {
|
|
604
604
|
let { submit: n, complete: r } = W(), { t: i } = l();
|
|
@@ -647,8 +647,8 @@ var H = (e) => {
|
|
|
647
647
|
}, {
|
|
648
648
|
Stars: Le,
|
|
649
649
|
Feedback: He,
|
|
650
|
-
Reason:
|
|
651
|
-
Comment:
|
|
650
|
+
Reason: ze,
|
|
651
|
+
Comment: Ve,
|
|
652
652
|
Submit: We,
|
|
653
653
|
ThankYou: Ke
|
|
654
654
|
}), Ye = ({ onComplete: e, showThankYou: t = !1, className: n }) => /* @__PURE__ */ A(q, {
|
|
@@ -925,7 +925,7 @@ function gt(e) {
|
|
|
925
925
|
//#endregion
|
|
926
926
|
//#region lib/hooks/useCollection.ts
|
|
927
927
|
var _t = ["query"];
|
|
928
|
-
function
|
|
928
|
+
function $(e, t = {}, ...n) {
|
|
929
929
|
var r, a;
|
|
930
930
|
let { query: s } = t, c = h(t, _t), l = gt(s), u = Q(v(function() {
|
|
931
931
|
var t = i(function* (t) {
|
|
@@ -1025,22 +1025,22 @@ function vt(e, t = {}, ...n) {
|
|
|
1025
1025
|
}
|
|
1026
1026
|
//#endregion
|
|
1027
1027
|
//#region lib/hooks/useResource.ts
|
|
1028
|
-
function
|
|
1028
|
+
function vt(e, t, ...n) {
|
|
1029
1029
|
let r = Q(e, t, ...n), i = pt(r.data);
|
|
1030
1030
|
return C(() => o(o({}, r), {}, { data: i }), [r, i]);
|
|
1031
1031
|
}
|
|
1032
1032
|
//#endregion
|
|
1033
1033
|
//#region lib/hooks/usePageControls.ts
|
|
1034
|
-
var
|
|
1034
|
+
var yt = [
|
|
1035
1035
|
"pages",
|
|
1036
1036
|
"hasMore",
|
|
1037
1037
|
"isLoadingMore",
|
|
1038
1038
|
"isLoadMoreError",
|
|
1039
1039
|
"loadMore"
|
|
1040
1040
|
];
|
|
1041
|
-
function
|
|
1041
|
+
function bt(e) {
|
|
1042
1042
|
var t;
|
|
1043
|
-
let { pages: n, hasMore: r, isLoadingMore: a, isLoadMoreError: s, loadMore: c } = e, l = h(e,
|
|
1043
|
+
let { pages: n, hasMore: r, isLoadingMore: a, isLoadMoreError: s, loadMore: c } = e, l = h(e, yt), [u, d] = E(0), f = n === null ? 0 : n.length - +!a, p = Math.min(u, f);
|
|
1044
1044
|
u !== p && d(p);
|
|
1045
1045
|
let m = n !== null && p === n.length, g = m || (t = n == null ? void 0 : n[p]) == null ? null : t, _ = n !== null && !m && (p < n.length - 1 || r), y = p > 0, b = v(i(function* () {
|
|
1046
1046
|
if (n === null || m) return;
|
|
@@ -1081,50 +1081,50 @@ function xt(e) {
|
|
|
1081
1081
|
}
|
|
1082
1082
|
//#endregion
|
|
1083
1083
|
//#region lib/modules/accounts/useCreateAccount.ts
|
|
1084
|
-
function
|
|
1084
|
+
function xt() {
|
|
1085
1085
|
return Z(B().accounts.create);
|
|
1086
1086
|
}
|
|
1087
1087
|
//#endregion
|
|
1088
1088
|
//#region lib/modules/accounts/useDestroyAccount.ts
|
|
1089
|
-
function
|
|
1089
|
+
function St(e) {
|
|
1090
1090
|
return Z(e.destroy);
|
|
1091
1091
|
}
|
|
1092
1092
|
//#endregion
|
|
1093
1093
|
//#region lib/modules/accounts/useListAccounts.ts
|
|
1094
|
-
function
|
|
1095
|
-
return
|
|
1094
|
+
function Ct(e) {
|
|
1095
|
+
return $(B().accounts.list, e);
|
|
1096
1096
|
}
|
|
1097
1097
|
//#endregion
|
|
1098
1098
|
//#region lib/modules/accounts/useUpdateAccount.ts
|
|
1099
|
-
function
|
|
1099
|
+
function wt(e) {
|
|
1100
1100
|
return Z(e.update);
|
|
1101
1101
|
}
|
|
1102
1102
|
//#endregion
|
|
1103
1103
|
//#region lib/modules/accounts/AccountsContext.tsx
|
|
1104
|
-
var
|
|
1105
|
-
function
|
|
1104
|
+
var Tt = "cobrowse-account", Et = g(null), Dt = g(null);
|
|
1105
|
+
function Ot() {
|
|
1106
1106
|
try {
|
|
1107
|
-
return window.localStorage.getItem(
|
|
1107
|
+
return window.localStorage.getItem(Tt);
|
|
1108
1108
|
} catch (e) {
|
|
1109
1109
|
console.warn("Failed to retrieve the stored account.", e);
|
|
1110
1110
|
}
|
|
1111
1111
|
return null;
|
|
1112
1112
|
}
|
|
1113
|
-
function
|
|
1113
|
+
function kt(e) {
|
|
1114
1114
|
try {
|
|
1115
|
-
window.localStorage.setItem(
|
|
1115
|
+
window.localStorage.setItem(Tt, e);
|
|
1116
1116
|
} catch (e) {
|
|
1117
1117
|
console.warn("Failed to store the account.", e);
|
|
1118
1118
|
}
|
|
1119
1119
|
}
|
|
1120
|
-
function
|
|
1120
|
+
function At(e) {
|
|
1121
1121
|
return "on" in e && "off" in e;
|
|
1122
1122
|
}
|
|
1123
|
-
function
|
|
1123
|
+
function jt({ children: e }) {
|
|
1124
1124
|
var t;
|
|
1125
|
-
let n = B(), r =
|
|
1125
|
+
let n = B(), r = Ct(), [i, a] = E(() => {
|
|
1126
1126
|
var e;
|
|
1127
|
-
return (e =
|
|
1127
|
+
return (e = Ot()) == null ? n.license : e;
|
|
1128
1128
|
}), o = T(r.data);
|
|
1129
1129
|
S(() => {
|
|
1130
1130
|
o.current = r.data;
|
|
@@ -1132,10 +1132,10 @@ function Mt({ children: e }) {
|
|
|
1132
1132
|
let { unshift: s } = r, c = v((e) => {
|
|
1133
1133
|
let t = o.current;
|
|
1134
1134
|
if (t !== null && !t.some((t) => t.license_key === e.license_key)) {
|
|
1135
|
-
if (!
|
|
1135
|
+
if (!At(e)) throw Error(`Account ${e.license_key} isn't one of the user's accounts. Pass the SDK account to list it, or select one from the list.`);
|
|
1136
1136
|
s(e);
|
|
1137
1137
|
}
|
|
1138
|
-
n.license = e.license_key,
|
|
1138
|
+
n.license = e.license_key, kt(e.license_key), a(e.license_key);
|
|
1139
1139
|
}, [n, s]), l = C(() => {
|
|
1140
1140
|
var e, t, n;
|
|
1141
1141
|
let a = (e = r.data) == null ? [] : e;
|
|
@@ -1172,39 +1172,59 @@ function Mt({ children: e }) {
|
|
|
1172
1172
|
p,
|
|
1173
1173
|
c
|
|
1174
1174
|
]);
|
|
1175
|
-
return /* @__PURE__ */ k(
|
|
1175
|
+
return /* @__PURE__ */ k(Et.Provider, {
|
|
1176
1176
|
value: r,
|
|
1177
|
-
children: /* @__PURE__ */ k(
|
|
1177
|
+
children: /* @__PURE__ */ k(Dt.Provider, {
|
|
1178
1178
|
value: m,
|
|
1179
1179
|
children: e
|
|
1180
1180
|
})
|
|
1181
1181
|
});
|
|
1182
1182
|
}
|
|
1183
|
-
function
|
|
1184
|
-
let e = _(
|
|
1183
|
+
function Mt() {
|
|
1184
|
+
let e = _(Et);
|
|
1185
1185
|
if (!e) throw Error("useAccountsContext must be used inside AccountsProvider");
|
|
1186
1186
|
return e;
|
|
1187
1187
|
}
|
|
1188
|
-
function
|
|
1189
|
-
let e = _(
|
|
1188
|
+
function Nt() {
|
|
1189
|
+
let e = _(Dt);
|
|
1190
1190
|
if (!e) throw Error("useActiveAccountContext must be used inside AccountsProvider");
|
|
1191
1191
|
return e;
|
|
1192
1192
|
}
|
|
1193
1193
|
//#endregion
|
|
1194
1194
|
//#region lib/modules/accounts/useActiveAccount.ts
|
|
1195
1195
|
function Pt() {
|
|
1196
|
-
let { account: e, setActiveAccount: t } =
|
|
1196
|
+
let { account: e, setActiveAccount: t } = Nt();
|
|
1197
1197
|
return C(() => [e, t], [e, t]);
|
|
1198
1198
|
}
|
|
1199
1199
|
//#endregion
|
|
1200
|
+
//#region lib/modules/jwtsso/useCreateJwtSsoKey.ts
|
|
1201
|
+
function Ft() {
|
|
1202
|
+
return Z(B().jwtsso.keys.create);
|
|
1203
|
+
}
|
|
1204
|
+
//#endregion
|
|
1205
|
+
//#region lib/modules/jwtsso/useDestroyJwtSsoKey.ts
|
|
1206
|
+
function It(e) {
|
|
1207
|
+
return Z(e.destroy);
|
|
1208
|
+
}
|
|
1209
|
+
//#endregion
|
|
1210
|
+
//#region lib/modules/jwtsso/useListJwtSsoKeys.ts
|
|
1211
|
+
function Lt(e) {
|
|
1212
|
+
return $(B().jwtsso.keys.list, e);
|
|
1213
|
+
}
|
|
1214
|
+
//#endregion
|
|
1215
|
+
//#region lib/modules/jwtsso/useUpdateJwtSsoKey.ts
|
|
1216
|
+
function Rt(e) {
|
|
1217
|
+
return Z(e.update);
|
|
1218
|
+
}
|
|
1219
|
+
//#endregion
|
|
1200
1220
|
//#region lib/modules/policies/useCurrentPolicy.ts
|
|
1201
|
-
function
|
|
1202
|
-
return
|
|
1221
|
+
function zt(e) {
|
|
1222
|
+
return vt(B().policies.current, e);
|
|
1203
1223
|
}
|
|
1204
1224
|
//#endregion
|
|
1205
1225
|
//#region lib/main.ts
|
|
1206
|
-
var
|
|
1226
|
+
var Bt = r, Vt = c, Ht = ee, Ut = d, Wt = t, Gt = s, Kt = f, qt = I, Jt = u, Yt = ne, Xt = re, Zt = m, Qt = le, $t = de, en = Ce, tn = Ne, nn = q, rn = Ye, an = W, on = ae, sn = ct, cn = B, ln = V, un = ge, dn = fe, fn = U, pn = a, mn = e;
|
|
1207
1227
|
//#endregion
|
|
1208
|
-
export { J as ASCENDING,
|
|
1228
|
+
export { J as ASCENDING, jt as AccountsProvider, Xt as BlockingError, Vt as Button, Yt as CancelButton, on as CobrowseProvider, Bt as CodeEntry, tn as ConnectDevice, Xe as DESCENDING, Wt as Device, Ht as ExternalLink, Qt as Frame, Zt as Loader, Ut as PlatformIcon, nn as Rating, Jt as RefreshButton, $t as RemoteContextRelay, Gt as Session, en as SessionEmbed, rn as SessionRating, Kt as SmartConnectButton, sn as Table, qt as UserIcon, pn as bindI18n, p as describeUserAgent, mn as i18n, n as parseUserAgent, Mt as useAccountsContext, Pt as useActiveAccount, Nt as useActiveAccountContext, cn as useCobrowse, $ as useCollection, xt as useCreateAccount, Ft as useCreateJwtSsoKey, zt as useCurrentPolicy, St as useDestroyAccount, It as useDestroyJwtSsoKey, Ct as useListAccounts, Lt as useListJwtSsoKeys, Z as useMutation, bt as usePageControls, an as useRatingContext, ln as useRemoteContext, vt as useResource, un as useSession, dn as useSessionEvents, fn as useTrustedEmbeddingOrigins, wt as useUpdateAccount, Rt as useUpdateJwtSsoKey };
|
|
1209
1229
|
|
|
1210
1230
|
//# sourceMappingURL=cobrowse-agent-ui.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cobrowse-agent-ui.js","names":["root","ExternalLink","styles","IconExternalLink","root","UserIcon","styles","root","visuallyHidden","CancelButton","Button","styles","_Fragment","PhoneIcon","root","BlockingError","styles","CobrowseProvider","useCobrowse","RemoteContext","useRemoteContext","Frame","useRemoteContext","RemoteContextProvider","isAbortError","useTrustedEmbeddingOrigins","useCobrowse","RemoteContextRelay","useRemoteContext","useTrustedEmbeddingOrigins","useSessionEvents","useSession","root","useRemoteContext","useSession","styles","useCobrowse","root","useRemoteContext","styles","Frame","SessionEmbed","isAbortError","useCobrowse","root","styles","Loader","BaseLoader","ConnectDevice","useRatingContext","root","useRatingContext","styles","StarIcon","root","useRatingContext","styles","root","useRatingContext","styles","root","useRatingContext","styles","_Fragment","root","useRatingContext","Button","styles","root","useRatingContext","styles","styles","Rating","SessionRating","Rating","styles","Button","Table","useCobrowse","useCobrowse","useCobrowse","useCobrowse","CodeEntryComponent","ButtonComponent","ExternalLinkComponent","PlatformIconComponent","DeviceComponent","SessionComponent","SmartConnectButtonComponent","UserIconComponent","RefreshButtonComponent","CancelButtonComponent","BlockingErrorComponent","LoaderComponent","FrameComponent","RemoteContextRelayComponent","SessionEmbedComponent","ConnectDeviceComponent","RatingComponent","SessionRatingComponent","useRatingContextHook","CobrowseProviderComponent","TableComponent","useCobrowseHook","useRemoteContextHook","useSessionHook","useSessionEventsHook","useTrustedEmbeddingOriginsHook","bindI18nHelper","i18nInstance","i18n$1","Device$1","parseUserAgent","CodeEntry$1","_asyncToGenerator","bindI18n$1","_objectSpread2","Session$1","Button$1","useTranslation","RefreshButton$1","PlatformIcon$1","SmartConnectButton$1","describeUserAgent","Loader$2","_objectWithoutProperties","clsx","equal","SvgExternalLink","props","ExternalLink_module_default","ExternalLink$1","children","UserIcon_module_default","UserIcon$1","user","className","part","SvgPhone","CancelButton_module_default","_excluded$5","CancelButton$1","_ref","Fragment","t","BlockingError_module_default","BlockingError$1","heading","message","CobrowseContext","createContext","CobrowseProvider$1","cobrowse","useCobrowseValue","use","useCobrowse$1","RemoteContext$1","useRemoteContext$1","providedRemoteContext","remoteContext","setRemoteContext","useState","useEffect","target","cancelled","attachedContext","context","useStableCallback","callbackRef","useRef","callback","useCallback","args","_callbackRef$current","_excluded$4","Frame$1","iframe","setIframe","onErrorCallback","onError","handleIframeRef","element","handleError","error","style","isAbortError$2","useTrustedEmbeddingOrigins$1","origins","setOrigins","loading","setLoading","setError","abortController","trusted","RemoteContextRelay$1","resolvedRemoteContext","accountOrigins","resolvedOrigins","trustedOrigins","opener","resolvedDestination","destination","relay","useSessionEvents$1","onLoadedCallback","onLoaded","onUpdatedCallback","onUpdated","onActivatedCallback","onActivated","onEndedCallback","onEnded","sessionActivatedRef","sessionEndedRef","handleSessionLoaded","session","handleSessionUpdated","isRemoteContext","source","RemoteContext","hasSessionProperty","property","createReactiveSession","useSession$1","sessionSource","sessionState","setSessionState","handleSessionChange","Overlay_module_default","Overlay","state","useSessionUrl","useMemo","paramEntries","endAction","agentTools","deviceControls","sessionDetails","language","name","value","query","id","popout","messages","SessionEmbed_module_default","_excluded$3","SessionEventObserver","handlers","SessionEmbed$1","url","title","PUSH_RETRY_MS","ERROR_PUSH_ERROR","ERROR_PUSH_ATTEMPT_LIMIT_REACHED","ERROR_DEVICE_NOT_FOUND","ERROR_SESSION_NOT_FOUND","ERROR_SESSION_ERROR","isAbortError$1","useConnectDevice","deviceRef","sessionRef","sessionConnectedRef","pushTimerRef","onConnectAttemptCallback","onConnectAttempt","onConnectedCallback","onConnected","onCancelledCallback","onCancelled","stopPush","handleSessionEnded","_sessionRef$current","triggerPushError","sendPush","_send","attempt","maxPushAttempts","pushRetryMs","send","createSession","request","region","device","deviceId","cancel","_ref2","ConnectDevice_module_default","ConnectDevice$1","setAttempt","currentAttempt","RatingContext","useRatingContext$1","SvgStar","Stars_module_default","SCORES","Stars","promptId","useId","groupName","pointer","complete","prompt","label","scores","score","count","rating","setRating","Reason_module_default","Reason","feedback","Comment_module_default","Comment","placeholder","comment","event","Feedback_module_default","Feedback","feedbackThreshold","defaultReasons","reasons","reason","Submit_module_default","Submit","submit","ThankYou_module_default","ThankYou","Rating_module_default","DEFAULT_FEEDBACK_THRESHOLD","Rating$1","setRatingState","setFeedback","setComment","setComplete","finish","onComplete","commit","prev","v","SessionRating$1","showThankYou","ASCENDING","DESCENDING","nextSort","sort","key","firstDirection","Table_module_default","_excluded$2","_excluded2","_excluded3","_excluded4","_excluded5","_excluded6","_excluded7","_excluded8","TableContext","ColumnContext","useTableContext","table","useContext","Table$1","onSortChange","_ref3","_ref4","_ref5","direction","directionOf","column","_ref6","_ref7","headCellColumn","_ref8","createEntityProxy","entity","currentProxies","currentProxyOf","_currentProxies$get","useObservableEntities","version","bump","useReducer","entities","listeners","listener","_entities$map$filter","useObservableEntity","_useObservableEntitie","_useObservableEntitie2","useAsync","isPending","setIsPending","isSuccess","setIsSuccess","data","setData","callIdRef","executeAsync","callId","isCurrent","result","fn","err","reset","useMutation","mutateAsync","mutate","isError","isAbortError","useQuery","wrappedFn","options","isExecuting","isAsyncError","controllerRef","prevFn","setPrevFn","fetchOnMount","refetch","_controllerRef$curren","controller","requestOptions","_controllerRef$curren2","useStableValue","stable","setStable","_excluded$1","useCollection","_last$hasNextPage","_first$error","stableQuery","first","loaded","setLoaded","nextPages","firstPageRef","unshift","page","added","listed","loadedPages","last","hasMore","loadMoreError","isLoadingMore","refetchMore","cancelMore","_options$request","after","cancelFirst","loadMore","pageIndexById","index","pages","grouped","lastIndex","useResource","_excluded","usePageControls","_pages$pageIndex","list","rest","setIndex","pageIndex","isPendingPage","hasNextPage","hasPreviousPage","goToNextPage","needsLoading","goToPreviousPage","isLoadMoreError","useCreateAccount","useDestroyAccount","account","useListAccounts","useUpdateAccount","storageKey","AccountsContext","ActiveAccountContext","getStoredLicenseKey","storeLicenseKey","licenseKey","isAccount","AccountsProvider","_activeAccount$licens","accounts","setLicenseKey","_getStoredLicenseKey","listRef","setActiveAccount","activeAccount","_accounts$data","_list$find","previous","hasReconciled","activeLicenseKey","hasListLoaded","isResolved","activeAccountValue","useAccountsContext","useActiveAccountContext","useActiveAccount","useCurrentPolicy","CodeEntry","Button","ExternalLink","PlatformIcon","Device","Session","SmartConnectButton","UserIcon","RefreshButton","CancelButton","BlockingError","Loader","Frame","RemoteContextRelay","SessionEmbed","ConnectDevice","Rating","SessionRating","useRatingContext","CobrowseProvider","Table","useCobrowse","useRemoteContext","useSession","useSessionEvents","useTrustedEmbeddingOrigins","bindI18n","i18n"],"sources":["../lib/icons/external-link.svg?react","../lib/components/ExternalLink/ExternalLink.module.css","../lib/components/ExternalLink/index.tsx","../lib/components/UserIcon/UserIcon.module.css","../lib/components/UserIcon/index.tsx","../lib/icons/phone.svg?react","../lib/components/CancelButton/CancelButton.module.css","../lib/components/CancelButton/index.tsx","../lib/components/BlockingError/BlockingError.module.css","../lib/components/BlockingError/index.tsx","../lib/components/CobrowseProvider/index.tsx","../lib/components/Frame/RemoteContext.ts","../lib/hooks/useStableCallback.ts","../lib/components/Frame/index.tsx","../lib/hooks/useTrustedEmbeddingOrigins.ts","../lib/components/RemoteContextRelay/index.tsx","../lib/hooks/useSessionEvents.ts","../lib/hooks/useSession.ts","../lib/components/SessionEmbed/Overlay.module.css","../lib/components/SessionEmbed/Overlay.tsx","../lib/components/SessionEmbed/useSessionUrl.ts","../lib/components/SessionEmbed/SessionEmbed.module.css","../lib/components/SessionEmbed/index.tsx","../lib/components/ConnectDevice/useConnectDevice.ts","../lib/components/ConnectDevice/ConnectDevice.module.css","../lib/components/ConnectDevice/index.tsx","../lib/components/Rating/context.ts","../lib/icons/star.svg?react","../lib/components/Rating/Stars.module.css","../lib/components/Rating/Stars.tsx","../lib/components/Rating/Reason.module.css","../lib/components/Rating/Reason.tsx","../lib/components/Rating/Comment.module.css","../lib/components/Rating/Comment.tsx","../lib/components/Rating/Feedback.module.css","../lib/components/Rating/Feedback.tsx","../lib/components/Rating/Submit.module.css","../lib/components/Rating/Submit.tsx","../lib/components/Rating/ThankYou.module.css","../lib/components/Rating/ThankYou.tsx","../lib/components/Rating/Rating.module.css","../lib/components/Rating/index.tsx","../lib/components/Rating/SessionRating.tsx","../lib/components/Table/sort.ts","../lib/components/Table/Table.module.css","../lib/components/Table/index.tsx","../lib/hooks/useObservable.ts","../lib/hooks/useAsync.ts","../lib/hooks/useMutation.ts","../lib/hooks/useQuery.ts","../lib/hooks/useStableValue.ts","../lib/hooks/useCollection.ts","../lib/hooks/useResource.ts","../lib/hooks/usePageControls.ts","../lib/modules/accounts/useCreateAccount.ts","../lib/modules/accounts/useDestroyAccount.ts","../lib/modules/accounts/useListAccounts.ts","../lib/modules/accounts/useUpdateAccount.ts","../lib/modules/accounts/AccountsContext.tsx","../lib/modules/accounts/useActiveAccount.ts","../lib/modules/policies/useCurrentPolicy.ts","../lib/main.ts"],"sourcesContent":["import * as React from \"react\";\nimport { jsx as _jsx, jsxs as _jsxs } from \"react/jsx-runtime\";\nconst SvgExternalLink = (props) => /* @__PURE__ */ _jsxs(\"svg\", {\n\txmlns: \"http://www.w3.org/2000/svg\",\n\tviewBox: \"0 0 24 24\",\n\tfill: \"none\",\n\tstroke: \"currentColor\",\n\tstrokeWidth: 2,\n\tstrokeLinecap: \"round\",\n\tstrokeLinejoin: \"round\",\n\twidth: 14,\n\theight: 14,\n\t\"aria-hidden\": \"true\",\n\t...props,\n\tchildren: [\n\t\t/* @__PURE__ */ _jsx(\"path\", { d: \"M15 3h6v6\" }),\n\t\t/* @__PURE__ */ _jsx(\"path\", { d: \"M10 14 21 3\" }),\n\t\t/* @__PURE__ */ _jsx(\"path\", { d: \"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" })\n\t]\n});\nexport default SvgExternalLink;\n",".root {\n composes: focusRing from '@/styles/focus.module.css';\n position: absolute;\n right: 10px;\n display: flex;\n align-items: center;\n gap: 4px;\n text-decoration: none;\n color: var(--text-color-base);\n}\n\n.root:hover {\n text-decoration: underline;\n}\n\n.root:visited {\n color: #0e0c26;\n color: var(--text-color-base);\n}\n","import type { ReactNode } from 'react'\nimport IconExternalLink from '@/icons/external-link.svg?react'\nimport styles from './ExternalLink.module.css'\n\nexport interface ExternalLinkProps {\n href: string\n children?: ReactNode\n}\n\nconst ExternalLink = ({ href, children }: ExternalLinkProps) => (\n <a className={styles.root} href={href} target='_blank' rel='noopener noreferrer'>\n {children}\n <IconExternalLink />\n </a>\n)\n\nexport default ExternalLink\n",".root {\n color: #fff;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n text-align: center;\n background-size: cover;\n background-position: center;\n padding: 16px;\n border-radius: 50%;\n width: 1.5rem;\n height: 1.5rem;\n border: 1px solid #ddd;\n flex: 0 0 auto;\n white-space: nowrap;\n}\n","import clsx from 'clsx'\nimport styles from './UserIcon.module.css'\n\nexport interface UserIconUser {\n name?: string\n picture?: string\n colour?: string\n}\n\nexport interface UserIconProps {\n user?: UserIconUser\n className?: string\n}\n\nconst UserIcon = ({ user, className }: UserIconProps) => {\n const initials = (): string => {\n if (!user?.name || user.picture) return ''\n\n return user.name\n .trim()\n .split(/\\s+/)\n .map((part) => part.toUpperCase().charAt(0))\n .join('')\n .slice(0, 2)\n }\n\n if (!user) return null\n\n return (\n <div\n className={clsx(styles.root, className)}\n title={user.name}\n style={{\n backgroundImage: user.picture ? `url(${user.picture || ''})` : undefined,\n backgroundColor: user.colour,\n }}\n >\n <span>{initials()}</span>\n </div>\n )\n}\n\nexport default UserIcon\n","import * as React from \"react\";\nimport { jsx as _jsx, jsxs as _jsxs } from \"react/jsx-runtime\";\nconst SvgPhone = (props) => /* @__PURE__ */ _jsxs(\"svg\", {\n\twidth: 24,\n\theight: 24,\n\tviewBox: \"0 0 24 24\",\n\tfill: \"none\",\n\txmlns: \"http://www.w3.org/2000/svg\",\n\t...props,\n\tchildren: [/* @__PURE__ */ _jsx(\"g\", {\n\t\tclipPath: \"url(#clip0_60797_8824)\",\n\t\tchildren: /* @__PURE__ */ _jsx(\"path\", {\n\t\t\tfillRule: \"evenodd\",\n\t\t\tclipRule: \"evenodd\",\n\t\t\td: \"M20.9964 12.5895C21.1528 12.4331 21.2406 12.2211 21.2406 12C21.2406 11.7872 21.1593 11.5829 21.0138 11.4285C18.518 9.23023 15.3059 8.01707 11.9793 8.01707C8.65261 8.01707 5.44055 9.23023 2.94474 11.4285C2.7993 11.5829 2.71797 11.7872 2.71797 12C2.71797 12.2211 2.8058 12.4331 2.96214 12.5895L5.07653 14.7039L8.20945 13.3612L7.76772 11.5943C7.6415 11.0894 7.92363 10.5721 8.41645 10.4048C10.7269 9.62055 13.2316 9.62055 15.5421 10.4048C16.0349 10.5721 16.3171 11.0894 16.1908 11.5943L15.7491 13.3612L18.882 14.7039L20.9964 12.5895ZM23.2406 12C23.2406 12.7515 22.942 13.4723 22.4106 14.0037L19.8175 16.5968C19.5284 16.8859 19.0923 16.9699 18.7165 16.8088L14.1785 14.864C13.7274 14.6707 13.4832 14.1785 13.6023 13.7023L14.0159 12.0478C12.6758 11.7395 11.2828 11.7395 9.94266 12.0478L10.3563 13.7023C10.4753 14.1785 10.2312 14.6707 9.78006 14.864L5.24208 16.8088C4.86624 16.9699 4.43019 16.8859 4.14106 16.5968L1.54792 14.0037C1.01651 13.4723 0.717975 12.7515 0.717976 12C0.717975 11.2485 1.01651 10.5277 1.54792 9.99633C1.56223 9.98202 1.57697 9.96815 1.59212 9.95474C4.45744 7.41772 8.1522 6.01707 11.9793 6.01707C15.8064 6.01707 19.5011 7.41772 22.3664 9.95474C22.3816 9.96815 22.3963 9.98202 22.4106 9.99633C22.942 10.5277 23.2406 11.2485 23.2406 12Z\",\n\t\t\tfill: \"currentColor\"\n\t\t})\n\t}), /* @__PURE__ */ _jsx(\"defs\", { children: /* @__PURE__ */ _jsx(\"clipPath\", {\n\t\tid: \"clip0_60797_8824\",\n\t\tchildren: /* @__PURE__ */ _jsx(\"rect\", {\n\t\t\twidth: 24,\n\t\t\theight: 24,\n\t\t\tfill: \"white\"\n\t\t})\n\t}) })]\n});\nexport default SvgPhone;\n",".root {\n height: 40px;\n border-radius: 62px;\n background-color: #b91c1c;\n color: #ffffff;\n padding: 4px 20px;\n cursor: pointer;\n opacity: 1;\n}\n\n.root:hover {\n background-color: #dc2626;\n}\n\n.visuallyHidden {\n composes: visuallyHidden from '@/styles/visuallyHidden.module.css';\n}\n","import type { ComponentPropsWithoutRef } from 'react'\nimport clsx from 'clsx'\nimport Button from '@/components/Button'\nimport PhoneIcon from '@/icons/phone.svg?react'\nimport { useTranslation } from '@/i18n'\nimport styles from './CancelButton.module.css'\n\nexport interface CancelButtonProps extends ComponentPropsWithoutRef<'button'> {}\n\nconst CancelButton = ({ type = 'button', className, children, ...props }: CancelButtonProps) => {\n const { t } = useTranslation()\n\n return (\n <Button type={type} className={clsx(styles.root, className)} {...props}>\n {children ?? (\n <>\n <PhoneIcon />\n <span className={styles.visuallyHidden}>{t('Cancel')}</span>\n </>\n )}\n </Button>\n )\n}\n\nexport default CancelButton\n",".root {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 10px;\n padding: 10px;\n height: 100%;\n text-align: center;\n}\n\n.heading {\n font-size: 1.5rem;\n font-weight: 700;\n}\n\n.message {\n font-size: 1.2rem;\n}\n","import type { ReactNode } from 'react'\nimport { useTranslation } from '@/i18n'\nimport styles from './BlockingError.module.css'\n\nexport interface BlockingErrorProps {\n heading?: string\n message?: string\n children?: ReactNode\n}\n\nconst BlockingError = ({ heading, message, children }: BlockingErrorProps) => {\n const { t } = useTranslation()\n\n return (\n <div className={styles.root}>\n <p className={styles.heading}>{heading ?? t('Sorry, something went wrong.')}</p>\n {message && <p className={styles.message}>{message}</p>}\n {children}\n </div>\n )\n}\n\nexport default BlockingError\n","import { createContext, use, type ReactNode } from 'react'\nimport type CobrowseAPI from 'cobrowse-agent-sdk'\n\nconst CobrowseContext = createContext<CobrowseAPI | null>(null)\n\nexport interface CobrowseProviderProps {\n cobrowse: CobrowseAPI\n children?: ReactNode\n}\n\nexport const CobrowseProvider = ({ cobrowse, children }: CobrowseProviderProps) => (\n <CobrowseContext.Provider value={cobrowse}>{children}</CobrowseContext.Provider>\n)\n\nexport const useCobrowseValue = () => use(CobrowseContext)\n\nexport const useCobrowse = () => {\n const cobrowse = useCobrowseValue()\n\n if (!cobrowse) {\n throw new Error('CobrowseProvider is required to use this component.')\n }\n\n return cobrowse\n}\n\nexport default CobrowseProvider\n","import { createContext, use, useEffect, useState } from 'react'\nimport type { RemoteContext as CobrowseRemoteContext } from 'cobrowse-agent-sdk'\nimport { useCobrowseValue } from '@/components/CobrowseProvider'\n\nconst RemoteContext = createContext<CobrowseRemoteContext | null>(null)\n\nexport function useRemoteContext(\n target?: HTMLIFrameElement | Window | null,\n): CobrowseRemoteContext | null {\n const providedRemoteContext = use(RemoteContext)\n const cobrowse = useCobrowseValue()\n const [remoteContext, setRemoteContext] = useState<CobrowseRemoteContext | null>(null)\n\n useEffect(() => {\n if (target === undefined) {\n return\n }\n\n if (!target || !cobrowse) {\n return\n }\n\n let cancelled = false\n let attachedContext: CobrowseRemoteContext | null = null\n\n const attachContext = async () => {\n const context = await cobrowse.attachContext(target)\n\n if (!context) {\n setRemoteContext(null)\n\n return\n }\n\n attachedContext = context\n\n if (cancelled) {\n attachedContext.destroy()\n attachedContext = null\n\n return\n }\n\n setRemoteContext(attachedContext)\n }\n\n void attachContext()\n\n return () => {\n cancelled = true\n setRemoteContext(null)\n\n if (attachedContext) {\n attachedContext.destroy()\n attachedContext = null\n }\n }\n }, [cobrowse, target])\n\n if (target === undefined) {\n return providedRemoteContext\n }\n\n if (!target || !cobrowse) {\n return null\n }\n\n return remoteContext\n}\n\nexport default RemoteContext\n","import { useCallback, useEffect, useRef } from 'react'\n\nconst useStableCallback = <TArgs extends unknown[], TResult>(\n callback?: (...args: TArgs) => TResult,\n) => {\n const callbackRef = useRef(callback)\n\n useEffect(() => {\n callbackRef.current = callback\n }, [callback])\n\n return useCallback((...args: TArgs): TResult | undefined => callbackRef.current?.(...args), [])\n}\n\nexport default useStableCallback\n","import {\n useCallback,\n useEffect,\n useState,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from 'react'\nimport RemoteContextProvider, { useRemoteContext } from './RemoteContext'\nimport useStableCallback from '@/hooks/useStableCallback'\n\ntype IframeProps = Omit<ComponentPropsWithoutRef<'iframe'>, 'frameBorder' | 'onError' | 'src'>\n\nexport interface FrameProps extends IframeProps {\n src: string\n children?: ReactNode\n onError?: (error: unknown) => void\n}\n\nconst Frame = ({\n src,\n onError,\n title = 'Cobrowse',\n width = '100%',\n height = '100%',\n style,\n children,\n ...props\n}: FrameProps) => {\n const [iframe, setIframe] = useState<HTMLIFrameElement | null>(null)\n const onErrorCallback = useStableCallback(onError)\n const remoteContext = useRemoteContext(iframe)\n\n const handleIframeRef = useCallback((element: HTMLIFrameElement | null) => {\n setIframe(element)\n }, [])\n\n useEffect(() => {\n if (!remoteContext) {\n return\n }\n\n const handleError = (error: unknown) => {\n onErrorCallback(error)\n }\n\n remoteContext.on('error', handleError)\n\n return () => {\n remoteContext.off('error', handleError)\n }\n }, [remoteContext, onErrorCallback])\n\n return (\n <RemoteContextProvider.Provider value={remoteContext}>\n <iframe\n ref={handleIframeRef}\n title={title}\n width={width}\n height={height}\n src={src}\n style={{ border: 0, ...style }}\n {...props}\n />\n {children}\n </RemoteContextProvider.Provider>\n )\n}\n\nexport { useRemoteContext }\nexport default Frame\n","import { useEffect, useState } from 'react'\nimport { useCobrowse } from '@/components/CobrowseProvider'\n\nconst isAbortError = (error: unknown): boolean =>\n error instanceof Error && error.name === 'AbortError'\n\n/**\n * Provides the account's trusted embedding domains.\n * When the CobrowseProvider instance has no token the account settings cannot\n * be fetched, so the origins stay null.\n */\nconst useTrustedEmbeddingOrigins = () => {\n const cobrowse = useCobrowse()\n const [origins, setOrigins] = useState<string[] | null>(null)\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState<Error | null>(null)\n\n useEffect(() => {\n // oxlint-disable-next-line react/set-state-in-effect -- clears the previous instance's result before refetching\n setOrigins(null)\n setError(null)\n\n if (!cobrowse.token) {\n return\n }\n\n const abortController = new AbortController()\n\n const runEffect = async () => {\n setLoading(true)\n\n try {\n const trusted = await cobrowse.origins.trusted({\n request: { signal: abortController.signal },\n })\n\n setOrigins(trusted.origins)\n } catch (error) {\n if (isAbortError(error)) return\n\n setError(error instanceof Error ? error : new Error(String(error)))\n } finally {\n setLoading(false)\n }\n }\n\n void runEffect()\n\n return () => {\n abortController.abort()\n }\n }, [cobrowse])\n\n return {\n origins,\n loading,\n error,\n }\n}\n\nexport default useTrustedEmbeddingOrigins\n","import { useEffect } from 'react'\nimport type { RemoteContext, RemoteContextRelayOptions } from 'cobrowse-agent-sdk'\nimport { useRemoteContext } from '@/components/Frame'\nimport useTrustedEmbeddingOrigins from '@/hooks/useTrustedEmbeddingOrigins'\n\nexport interface RemoteContextRelayProps {\n /**\n * When provided, relays to the given context. Otherwise,\n * it's resolved from the RemoteContextProvider.\n */\n remoteContext?: RemoteContext\n /**\n * Origins allowed to communicate with the attached context via the relay.\n * Nothing is relayed to or from any other origin. Defaults to the account's\n * trusted embedding domains (see useTrustedEmbeddingOrigins), which requires\n * the CobrowseProvider instance to be authorized. Pass a reference-stable\n * array, a new identity recreates the relay.\n */\n trustedOrigins?: RemoteContextRelayOptions['trustedOrigins']\n /** The window to relay to. Defaults to the opener or parent of the current window. */\n destination?: Window\n}\n\n/**\n * Relays the enclosing Frame's remote context to a host window, so a page\n * embedding this application in an iframe can attach its own context to that\n * iframe and use the full RemoteContext API. Must be rendered inside a Frame.\n *\n * ```tsx\n * <Frame src={sessionUrl}>\n * <RemoteContextRelay trustedOrigins={['https://host.example.com']} />\n * </Frame>\n * ```\n */\nconst RemoteContextRelay = (props: RemoteContextRelayProps) => {\n const { remoteContext: providedRemoteContext, trustedOrigins, destination } = props\n const resolvedRemoteContext = useRemoteContext()\n const remoteContext = providedRemoteContext ?? resolvedRemoteContext\n const { origins: accountOrigins, error } = useTrustedEmbeddingOrigins()\n const resolvedOrigins = trustedOrigins ?? accountOrigins\n\n useEffect(() => {\n if (error && !trustedOrigins) {\n // oxlint-disable-next-line no-console -- without this the relay silently never starts; there is no UI to surface the misconfiguration\n console.warn(\n 'RemoteContextRelay: failed to load the account trusted embedding domains, nothing will be relayed',\n error,\n )\n }\n }, [error, trustedOrigins])\n\n useEffect(() => {\n if (!remoteContext) {\n return\n }\n\n if (!resolvedOrigins?.length) {\n return\n }\n\n // oxlint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- window.opener is typed as any but is a Window or null at runtime\n const opener = window.opener as Window | null\n const resolvedDestination = destination ?? opener ?? window.parent\n\n if (resolvedDestination === window) {\n return\n }\n\n const relay = remoteContext.relay(resolvedDestination, {\n trustedOrigins: resolvedOrigins,\n })\n\n return () => {\n relay.destroy()\n }\n }, [remoteContext, destination, resolvedOrigins])\n\n return null\n}\n\nexport default RemoteContextRelay\n","import { useEffect, useRef } from 'react'\nimport type { RemoteContext, Session } from 'cobrowse-agent-sdk'\nimport useStableCallback from '@/hooks/useStableCallback'\n\nexport interface SessionEventHandlers {\n /** Called when a session is loaded into the context. */\n onLoaded?: (session: Session) => void\n /** Called for every session update. */\n onUpdated?: (session: Session) => void\n /** Called once per session, when it becomes active. */\n onActivated?: (session: Session) => void\n /** Called once per session, when it ends. */\n onEnded?: (session: Session) => void\n}\n\n/**\n * Observes the sessions of a remote context, adding activated/ended edges on top\n * of the context's own load/update events. Both are raised at most once per\n * session: a session already active when it is first seen counts as activated\n * before this context saw it, so `onActivated` is not called for it.\n */\nconst useSessionEvents = (\n remoteContext: RemoteContext | null,\n { onLoaded, onUpdated, onActivated, onEnded }: SessionEventHandlers,\n) => {\n const onLoadedCallback = useStableCallback(onLoaded)\n const onUpdatedCallback = useStableCallback(onUpdated)\n const onActivatedCallback = useStableCallback(onActivated)\n const onEndedCallback = useStableCallback(onEnded)\n const sessionActivatedRef = useRef(false)\n const sessionEndedRef = useRef(false)\n\n useEffect(() => {\n if (!remoteContext) {\n sessionActivatedRef.current = false\n sessionEndedRef.current = false\n\n return\n }\n\n const handleSessionLoaded = (session: Session) => {\n sessionActivatedRef.current = session.isActive()\n sessionEndedRef.current = false\n onLoadedCallback(session)\n }\n\n const handleSessionUpdated = (session: Session) => {\n onUpdatedCallback(session)\n\n if (session.isActive() && !sessionActivatedRef.current) {\n sessionActivatedRef.current = true\n onActivatedCallback(session)\n }\n\n if (session.isEnded() && !sessionEndedRef.current) {\n sessionEndedRef.current = true\n onEndedCallback(session)\n }\n }\n\n remoteContext.on('session.loaded', handleSessionLoaded)\n remoteContext.on('session.updated', handleSessionUpdated)\n\n return () => {\n remoteContext.off('session.loaded', handleSessionLoaded)\n remoteContext.off('session.updated', handleSessionUpdated)\n sessionActivatedRef.current = false\n sessionEndedRef.current = false\n }\n }, [onActivatedCallback, onEndedCallback, onLoadedCallback, onUpdatedCallback, remoteContext])\n}\n\nexport default useSessionEvents\n","import { useEffect, useState } from 'react'\nimport { RemoteContext, type Session } from 'cobrowse-agent-sdk'\n\nconst isRemoteContext = (source: RemoteContext | Session): source is RemoteContext =>\n source instanceof RemoteContext\n\nconst hasSessionProperty = (target: Session, property: PropertyKey): property is keyof Session =>\n property in target\n\nconst createReactiveSession = (session: Session | null) => {\n if (!session) {\n return null\n }\n\n return new Proxy(session, {\n get: (target, property) =>\n hasSessionProperty(target, property) ? target[property] : undefined,\n })\n}\n\nconst useSession = (source: RemoteContext | Session | null) => {\n const remoteContext = source && isRemoteContext(source) ? source : null\n const sessionSource = source && !isRemoteContext(source) ? source : null\n const [sessionState, setSessionState] = useState(sessionSource)\n\n useEffect(() => {\n if (!remoteContext) {\n return\n }\n\n const handleSessionChange = (session: Session) => {\n setSessionState(createReactiveSession(session))\n }\n\n remoteContext.on('session.loaded', handleSessionChange)\n remoteContext.on('session.updated', handleSessionChange)\n\n return () => {\n remoteContext.off('session.loaded', handleSessionChange)\n remoteContext.off('session.updated', handleSessionChange)\n\n setSessionState(null)\n }\n }, [remoteContext])\n\n useEffect(() => {\n if (!sessionSource) {\n return\n }\n\n const handleSessionChange = () => {\n setSessionState(createReactiveSession(sessionSource))\n }\n\n sessionSource.on('updated', handleSessionChange)\n sessionSource.on('ended', handleSessionChange)\n\n return () => {\n sessionSource.off('updated', handleSessionChange)\n sessionSource.off('ended', handleSessionChange)\n\n setSessionState(null)\n }\n }, [sessionSource])\n\n return sessionState ?? sessionSource\n}\n\nexport default useSession\n",".root {\n position: absolute;\n inset: 0;\n z-index: 1;\n pointer-events: none;\n}\n\n.content {\n display: contents;\n pointer-events: auto;\n}\n","import { useRemoteContext } from '@/components/Frame'\nimport useSession from '@/hooks/useSession'\nimport styles from './Overlay.module.css'\nimport type { SessionEmbedOverlayProps } from './types'\n\nconst Overlay = ({ state, children }: SessionEmbedOverlayProps) => {\n const remoteContext = useRemoteContext()\n const session = useSession(remoteContext)\n const sessionState = session?.state\n\n const shouldRender = state === 'loading' ? sessionState === undefined : sessionState === state\n\n if (!shouldRender) {\n return null\n }\n\n return (\n <div className={styles.root}>\n <div className={styles.content}>{children}</div>\n </div>\n )\n}\n\nexport default Overlay\n","import { useMemo } from 'react'\nimport { useCobrowse } from '@/components/CobrowseProvider'\nimport type { SessionEmbedProps } from './types'\nimport { useTranslation } from '@/i18n'\n\ninterface UseSessionUrlProps {\n id: string\n endAction?: SessionEmbedProps['endAction']\n popout?: SessionEmbedProps['popout']\n agentTools?: SessionEmbedProps['agentTools']\n deviceControls?: SessionEmbedProps['deviceControls']\n sessionDetails?: SessionEmbedProps['sessionDetails']\n messages?: SessionEmbedProps['messages']\n}\n\nexport const useSessionUrl = ({\n id,\n endAction,\n popout,\n agentTools,\n deviceControls,\n sessionDetails,\n messages,\n}: UseSessionUrlProps) => {\n const cobrowse = useCobrowse()\n const {\n i18n: { language },\n } = useTranslation()\n\n return useMemo(() => {\n const paramEntries = Object.entries({\n end_action: endAction,\n popout,\n agent_tools: agentTools,\n device_controls: deviceControls,\n session_details: sessionDetails,\n messages,\n token_source: 'postMessage',\n lng: language,\n }).flatMap(([name, value]) => (value === undefined ? [] : [[name, value]]))\n\n const query = new URLSearchParams(paramEntries)\n\n return `${cobrowse.api}/session/${encodeURIComponent(id)}?${query.toString()}`\n }, [\n cobrowse.api,\n id,\n endAction,\n popout,\n agentTools,\n deviceControls,\n sessionDetails,\n messages,\n language,\n ])\n}\n",".root {\n position: relative;\n width: 100%;\n height: 100%;\n}\n","import Frame, { useRemoteContext } from '@/components/Frame'\nimport useSessionEvents from '@/hooks/useSessionEvents'\nimport { useTranslation } from '@/i18n'\nimport Overlay from './Overlay'\nimport type { SessionEmbedProps } from './types'\nimport { useSessionUrl } from './useSessionUrl'\nimport styles from './SessionEmbed.module.css'\n\nexport type {\n SessionEmbedOverlay,\n SessionEmbedOverlayProps,\n SessionEmbedOverlayState,\n SessionEmbedProps,\n} from './types'\n\ntype SessionEmbedComponent = typeof SessionEmbedBase & {\n Overlay: typeof Overlay\n}\n\nconst SessionEventObserver = (\n handlers: Pick<SessionEmbedProps, 'onLoaded' | 'onUpdated' | 'onActivated' | 'onEnded'>,\n) => {\n useSessionEvents(useRemoteContext(), handlers)\n return null\n}\n\nconst SessionEmbedBase = ({\n id,\n endAction,\n popout,\n agentTools,\n deviceControls,\n sessionDetails,\n messages,\n onError,\n onLoaded,\n onUpdated,\n onActivated,\n onEnded,\n title,\n className,\n children,\n ...props\n}: SessionEmbedProps) => {\n const { t } = useTranslation()\n const url = useSessionUrl({\n id,\n endAction,\n popout,\n agentTools,\n deviceControls,\n sessionDetails,\n messages,\n })\n\n return (\n <div className={styles.root}>\n <Frame\n src={url}\n title={title ?? t('Cobrowse session')}\n className={className}\n onError={onError}\n {...props}\n >\n <SessionEventObserver\n onLoaded={onLoaded}\n onUpdated={onUpdated}\n onActivated={onActivated}\n onEnded={onEnded}\n />\n {children}\n </Frame>\n </div>\n )\n}\n\nconst SessionEmbed: SessionEmbedComponent = Object.assign(SessionEmbedBase, {\n Overlay,\n})\nexport default SessionEmbed\n","import { useCallback, useEffect, useRef } from 'react'\nimport type { Device, Session } from 'cobrowse-agent-sdk'\nimport useStableCallback from '@/hooks/useStableCallback'\nimport { useCobrowse } from '@/components/CobrowseProvider'\n\nexport const MAX_PUSH_ATTEMPTS = 5\nexport const PUSH_RETRY_MS = 4000\nexport const ERROR_PUSH_ERROR = 'push_error'\nexport const ERROR_PUSH_ATTEMPT_LIMIT_REACHED = 'push_attempt_limit_reached'\nexport const ERROR_DEVICE_NOT_FOUND = 'device_not_found'\nexport const ERROR_SESSION_NOT_FOUND = 'session_not_found'\nexport const ERROR_SESSION_ERROR = 'session_error'\n\nconst isAbortError = (error: unknown): boolean => {\n if (!(error instanceof Error)) {\n return false\n }\n\n return error.name === 'AbortError'\n}\n\nexport interface UseConnectDeviceOptions {\n deviceId: string\n onConnectAttempt?: (attempt: number) => void\n onConnected?: (session: Session) => void\n onCancelled?: (session: Session) => void\n onEnded?: (session: Session) => void\n onError?: (error: unknown) => void\n maxPushAttempts?: number\n pushRetryMs?: number\n}\n\nconst useConnectDevice = ({\n deviceId,\n onConnectAttempt,\n onConnected,\n onCancelled,\n onEnded,\n onError,\n maxPushAttempts = MAX_PUSH_ATTEMPTS,\n pushRetryMs = PUSH_RETRY_MS,\n}: UseConnectDeviceOptions) => {\n const cobrowse = useCobrowse()\n const deviceRef = useRef<Device>(null)\n const sessionRef = useRef<Session>(null)\n const sessionConnectedRef = useRef(false)\n const sessionEndedRef = useRef(false)\n const pushTimerRef = useRef(0)\n const onConnectAttemptCallback = useStableCallback(onConnectAttempt)\n const onConnectedCallback = useStableCallback(onConnected)\n const onCancelledCallback = useStableCallback(onCancelled)\n const onEndedCallback = useStableCallback(onEnded)\n const onErrorCallback = useStableCallback(onError)\n\n const stopPush = useCallback(() => {\n clearTimeout(pushTimerRef.current)\n }, [])\n\n const handleSessionUpdated = useCallback(\n (session: Session) => {\n if (!['pending', 'ended'].includes(session.state) && !sessionConnectedRef.current) {\n stopPush()\n onConnectedCallback(session)\n sessionConnectedRef.current = true\n }\n },\n [onConnectedCallback, stopPush],\n )\n\n const handleSessionEnded = useCallback(\n (session: Session) => {\n if (!sessionEndedRef.current) {\n onEndedCallback(session)\n sessionEndedRef.current = true\n void sessionRef.current?.end()\n }\n },\n [onEndedCallback],\n )\n\n const triggerPushError = useCallback(\n (error: unknown) => {\n if (isAbortError(error)) {\n return\n }\n\n if (error instanceof Error) {\n onErrorCallback({ id: ERROR_PUSH_ERROR, message: error.message })\n } else {\n onErrorCallback(error)\n }\n },\n [onErrorCallback],\n )\n\n const sendPush = useCallback(\n async function send(attempt = 1, abortController: AbortController) {\n onConnectAttemptCallback(attempt)\n\n if (attempt >= maxPushAttempts) {\n triggerPushError({\n id: ERROR_PUSH_ATTEMPT_LIMIT_REACHED,\n message: 'Push attempt limit reached.',\n })\n\n return\n }\n\n if (!deviceRef.current) {\n triggerPushError({ id: ERROR_DEVICE_NOT_FOUND, message: 'Device not found.' })\n\n return\n }\n\n if (!sessionRef.current) {\n triggerPushError({ id: ERROR_SESSION_NOT_FOUND, message: 'Session not found.' })\n\n return\n }\n\n try {\n await deviceRef.current.notify(\n { session: sessionRef.current, attempt },\n { request: { signal: abortController.signal } },\n )\n } catch (error) {\n triggerPushError(error)\n }\n\n pushTimerRef.current = setTimeout(() => {\n void send(attempt + 1, abortController)\n }, pushRetryMs)\n },\n [maxPushAttempts, onConnectAttemptCallback, pushRetryMs, triggerPushError],\n )\n\n const createSession = useCallback(\n async (abortController: AbortController) => {\n const request = { signal: abortController.signal }\n\n try {\n deviceRef.current = null\n sessionRef.current = null\n sessionConnectedRef.current = false\n sessionEndedRef.current = false\n\n const [region, device] = await Promise.all([\n cobrowse.regions.closest({ request }),\n cobrowse.devices.get(deviceId, { request }),\n ])\n\n deviceRef.current = device\n\n const session = await cobrowse.sessions.create(\n {\n custom_data: device.custom_data,\n region: region.id,\n agent: 'me',\n },\n { request },\n )\n\n sessionRef.current = session\n\n session.on('updated', handleSessionUpdated)\n session.on('ended', handleSessionEnded)\n\n await session.subscribe()\n } catch (error) {\n if (isAbortError(error)) {\n return\n }\n\n if (error instanceof Error) {\n onErrorCallback({ id: ERROR_SESSION_ERROR, message: error.message })\n } else {\n onErrorCallback({ id: ERROR_SESSION_ERROR, message: 'The session could not be created.' })\n }\n }\n },\n [cobrowse, deviceId, handleSessionEnded, handleSessionUpdated, onErrorCallback],\n )\n\n const cancel = useCallback(async () => {\n stopPush()\n\n const session = sessionRef.current\n\n if (session) {\n await session.end()\n onCancelledCallback(session)\n }\n }, [onCancelledCallback, stopPush])\n\n useEffect(() => {\n const abortController = new AbortController()\n\n const runEffect = async () => {\n await createSession(abortController)\n\n if (abortController.signal.aborted) {\n return\n }\n\n await sendPush(1, abortController)\n }\n\n void runEffect()\n\n return () => {\n abortController.abort()\n stopPush()\n }\n }, [createSession, sendPush, stopPush])\n\n return { cancel }\n}\n\nexport default useConnectDevice\n",".root {\n display: flex;\n flex-direction: column;\n gap: 10px;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n background: #0e0c26;\n color: white;\n}\n\n.statusMessage {\n font-size: 1.2rem;\n}\n","import { useState, type ReactNode } from 'react'\nimport type { Session } from 'cobrowse-agent-sdk'\nimport clsx from 'clsx'\nimport BaseLoader from '@/components/Loader'\nimport CancelButton, { type CancelButtonProps } from '@/components/CancelButton'\nimport { useTranslation } from '@/i18n'\nimport useConnectDevice, {\n ERROR_DEVICE_NOT_FOUND,\n ERROR_PUSH_ATTEMPT_LIMIT_REACHED,\n ERROR_PUSH_ERROR,\n ERROR_SESSION_ERROR,\n ERROR_SESSION_NOT_FOUND,\n MAX_PUSH_ATTEMPTS,\n PUSH_RETRY_MS,\n} from './useConnectDevice'\nimport styles from './ConnectDevice.module.css'\n\nexport {\n ERROR_DEVICE_NOT_FOUND,\n ERROR_PUSH_ATTEMPT_LIMIT_REACHED,\n ERROR_PUSH_ERROR,\n ERROR_SESSION_ERROR,\n ERROR_SESSION_NOT_FOUND,\n MAX_PUSH_ATTEMPTS,\n PUSH_RETRY_MS,\n}\n\nexport interface ConnectDeviceStatusMessageProps {\n attempt: number\n maxPushAttempts?: number\n className?: string\n}\n\nexport interface ConnectDeviceLoaderProps {\n attempt: number\n maxPushAttempts?: number\n}\n\nexport interface ConnectDeviceProps {\n deviceId: string\n onConnectAttempt?: (attempt: number) => void\n onConnected?: (session: Session) => void\n onCancelled?: (session: Session) => void\n onEnded?: (session: Session) => void\n onError?: (error: unknown) => void\n maxPushAttempts?: number\n pushRetryMs?: number\n className?: string\n children: (attempt: number, cancel: () => void) => ReactNode\n}\n\nconst StatusMessage = ({\n attempt,\n maxPushAttempts = MAX_PUSH_ATTEMPTS,\n className,\n}: ConnectDeviceStatusMessageProps) => {\n const { t } = useTranslation()\n let message = t('Contacting device')\n\n if (attempt >= maxPushAttempts) {\n message = t('Device not responding')\n } else if (attempt >= maxPushAttempts - 1) {\n message = t('Trying once more')\n } else if (attempt > 2) {\n message = t('Retrying connection')\n }\n\n return <div className={clsx(styles.statusMessage, className)}>{message}</div>\n}\n\nconst Loader = ({ attempt, maxPushAttempts = MAX_PUSH_ATTEMPTS }: ConnectDeviceLoaderProps) => {\n if (attempt >= maxPushAttempts) {\n return null\n }\n\n return <BaseLoader />\n}\n\ntype ConnectDeviceComponent = ((props: ConnectDeviceProps) => ReactNode) & {\n StatusMessage: (props: ConnectDeviceStatusMessageProps) => ReactNode\n Loader: (props: ConnectDeviceLoaderProps) => ReactNode\n CancelButton: (props: CancelButtonProps) => ReactNode\n}\n\nconst ConnectDeviceBase = ({\n deviceId,\n onConnectAttempt,\n onConnected,\n onCancelled,\n onEnded,\n onError,\n maxPushAttempts = MAX_PUSH_ATTEMPTS,\n pushRetryMs = PUSH_RETRY_MS,\n className,\n children,\n}: ConnectDeviceProps) => {\n const [attempt, setAttempt] = useState(1)\n\n const handleConnectAttempt = (currentAttempt: number) => {\n setAttempt(currentAttempt)\n onConnectAttempt?.(currentAttempt)\n }\n\n const { cancel } = useConnectDevice({\n deviceId,\n onConnectAttempt: handleConnectAttempt,\n onConnected,\n onCancelled,\n onEnded,\n onError,\n maxPushAttempts,\n pushRetryMs,\n })\n\n const handleCancel = () => {\n void cancel()\n }\n\n return <div className={clsx(styles.root, className)}>{children(attempt, handleCancel)}</div>\n}\n\nconst ConnectDevice: ConnectDeviceComponent = Object.assign(ConnectDeviceBase, {\n StatusMessage,\n Loader,\n CancelButton,\n})\n\nexport default ConnectDevice\n","import { createContext, use } from 'react'\nimport type { RatingUpdate, RatingValue } from 'cobrowse-agent-sdk'\n\nexport type RatingResult = RatingUpdate\n\nexport interface RatingContextValue {\n rating: RatingValue | null\n feedback: string[]\n comment: string\n complete: boolean\n feedbackThreshold: number\n setRating: (score: RatingValue, commit?: boolean) => void\n toggleReason: (value: string) => void\n setComment: (value: string) => void\n submit: () => void\n}\n\nconst RatingContext = createContext<RatingContextValue | null>(null)\n\nexport const useRatingContext = (): RatingContextValue => {\n const context = use(RatingContext)\n\n if (!context) {\n throw new Error('Rating.* components must be rendered within a <Rating>.')\n }\n\n return context\n}\n\nexport default RatingContext\n","import * as React from \"react\";\nimport { jsx as _jsx, jsxs as _jsxs } from \"react/jsx-runtime\";\nconst SvgStar = (props) => /* @__PURE__ */ _jsxs(\"svg\", {\n\twidth: 24,\n\theight: 24,\n\tviewBox: \"0 0 24 24\",\n\tfill: \"none\",\n\txmlns: \"http://www.w3.org/2000/svg\",\n\t...props,\n\tchildren: [/* @__PURE__ */ _jsx(\"path\", {\n\t\td: \"M12.0001 17.748L5.82811 20.993L7.00711 14.12L2.00711 9.253L8.90711 8.253L11.9931 2L15.0791 8.253L21.9791 9.253L16.9791 14.12L18.1581 20.993L12.0001 17.748Z\",\n\t\tfill: \"currentColor\"\n\t}), /* @__PURE__ */ _jsx(\"path\", {\n\t\tclassName: \"rating-star-outline\",\n\t\tfillRule: \"evenodd\",\n\t\tclipRule: \"evenodd\",\n\t\td: \"M11.9931 1C12.3738 1 12.7214 1.2161 12.8898 1.55744L15.7431 7.33878L22.1225 8.26334C22.4994 8.31796 22.8126 8.58192 22.9302 8.94414C23.0478 9.30635 22.9495 9.70394 22.6766 9.96957L18.0537 14.4695L19.1437 20.8239C19.2081 21.1993 19.0537 21.5786 18.7455 21.8023C18.4373 22.026 18.0288 22.0552 17.6919 21.8777L11.9996 18.8781L6.29347 21.8781C5.95655 22.0553 5.54828 22.0258 5.24032 21.802C4.93237 21.5783 4.77815 21.1991 4.84251 20.8239L5.93254 14.4695L1.3096 9.96957C1.0367 9.70394 0.938377 9.30635 1.056 8.94414C1.17363 8.58192 1.48678 8.31796 1.86368 8.26334L8.24315 7.33878L11.0964 1.55744C11.2648 1.2161 11.6125 1 11.9931 1ZM11.9931 4.25957L9.80385 8.69556C9.65813 8.99083 9.3764 9.19543 9.05054 9.24266L4.15852 9.95165L7.70462 13.4034C7.94065 13.6332 8.0484 13.9644 7.99271 14.2891L7.15631 19.1649L11.5347 16.8629C11.8264 16.7096 12.1748 16.7097 12.4663 16.8633L16.8295 19.1625L15.9935 14.2891C15.9378 13.9644 16.0456 13.6332 16.2816 13.4034L19.8277 9.95165L14.9357 9.24266C14.6098 9.19543 14.3281 8.99083 14.1824 8.69556L11.9931 4.25957Z\",\n\t\tfill: \"currentColor\"\n\t})]\n});\nexport default SvgStar;\n",".root {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.prompt {\n margin: 0;\n text-align: center;\n font-size: 0.75rem;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n color: #040d3c;\n}\n\n.stars {\n display: flex;\n justify-content: center;\n}\n\n.visuallyHidden {\n composes: visuallyHidden from '@/styles/visuallyHidden.module.css';\n}\n\n.star {\n padding: 0 6px;\n line-height: 0;\n color: var(--rating-star-color, #9ca2be);\n cursor: pointer;\n border-radius: 4px;\n transition: color 0.2s ease;\n}\n\n.starInput {\n composes: visuallyHidden from '@/styles/visuallyHidden.module.css';\n}\n\n.star:has(.starInput:focus-visible) {\n outline: none;\n box-shadow: 0 0 0 var(--focus-ring-width, 3px) var(--focus-ring-color, rgba(4, 13, 60, 0.16));\n}\n\n.star svg {\n width: 30px;\n height: 30px;\n}\n\n.star svg path {\n fill: none;\n transition: fill 0.2s ease;\n}\n\n.star svg :global(.rating-star-outline) {\n fill: currentColor;\n}\n\n.star:hover,\n.star:has(~ .star:hover),\n.starActive {\n color: var(--rating-star-active-color, #040d3c);\n}\n\n.star:hover svg path,\n.star:has(~ .star:hover) svg path,\n.starActive svg path {\n fill: currentColor;\n}\n","import { useId, useRef, type ReactNode } from 'react'\nimport clsx from 'clsx'\nimport type { RatingValue } from 'cobrowse-agent-sdk'\nimport StarIcon from '@/icons/star.svg?react'\nimport { useTranslation } from '@/i18n'\nimport { useRatingContext } from './context'\nimport styles from './Stars.module.css'\n\nconst SCORES: RatingValue[] = [1, 2, 3, 4, 5]\n\nexport interface RatingStarsProps {\n label?: ReactNode\n count?: RatingValue\n className?: string\n}\n\nconst Stars = ({ label, count = 5, className }: RatingStarsProps) => {\n const { rating, setRating, complete } = useRatingContext()\n const { t } = useTranslation()\n const promptId = useId()\n const groupName = useId()\n const pointer = useRef(false)\n\n if (complete) {\n return null\n }\n\n const prompt = label === undefined ? t('Rate your experience') : label\n const scores = SCORES.filter((score) => score <= count)\n\n return (\n <div className={clsx(styles.root, className)}>\n {prompt && (\n <p id={promptId} className={styles.prompt}>\n {prompt}\n </p>\n )}\n <div\n className={styles.stars}\n role='radiogroup'\n aria-labelledby={prompt ? promptId : undefined}\n aria-label={prompt ? undefined : t('Rate your experience')}\n >\n {scores.map((score) => (\n <label\n key={score}\n className={clsx(styles.star, rating !== null && rating >= score && styles.starActive)}\n onPointerDown={() => {\n pointer.current = true\n }}\n >\n <input\n type='radio'\n name={groupName}\n value={score}\n checked={rating === score}\n className={styles.starInput}\n // Prevent submitting the value automatically for keyboard-driven users,\n // otherwise they wouldn't be able to move past the 4th star.\n onKeyDown={() => {\n pointer.current = false\n }}\n onChange={() => {\n setRating(score, pointer.current)\n pointer.current = false\n }}\n />\n <StarIcon />\n <span className={styles.visuallyHidden}>\n {t('Rate with a score of {{score}}', { score })}\n </span>\n </label>\n ))}\n </div>\n </div>\n )\n}\n\nexport default Stars\n",".root {\n display: flex;\n align-items: center;\n gap: 8px;\n cursor: pointer;\n}\n\n.checkbox {\n composes: focusRing from '@/styles/focus.module.css';\n appearance: none;\n width: 20px;\n height: 20px;\n flex-shrink: 0;\n border: 1px solid #bcc1d4;\n border-radius: 6px;\n background-repeat: no-repeat;\n background-position: center;\n cursor: pointer;\n transition:\n border-color 0.15s ease,\n background-color 0.15s ease;\n}\n\n.checkbox:hover {\n border-color: #9ca2be;\n}\n\n.checkbox:checked {\n border-color: #040d3c;\n background-color: #040d3c;\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"none\"><path d=\"M3.5 8.5l3 3 6-6\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>');\n}\n","import type { ReactNode } from 'react'\nimport clsx from 'clsx'\nimport { useRatingContext } from './context'\nimport styles from './Reason.module.css'\n\nexport interface RatingReasonProps {\n value: string\n label: ReactNode\n className?: string\n}\n\nconst Reason = ({ value, label, className }: RatingReasonProps) => {\n const { feedback, toggleReason } = useRatingContext()\n\n return (\n <label className={clsx(styles.root, className)}>\n <input\n type='checkbox'\n value={value}\n checked={feedback.includes(value)}\n className={styles.checkbox}\n onChange={() => {\n toggleReason(value)\n }}\n />\n {label}\n </label>\n )\n}\n\nexport default Reason\n",".root {\n composes: focusRing from '@/styles/focus.module.css';\n box-sizing: border-box;\n width: 100%;\n height: 72px;\n padding: 8px 12px;\n resize: none;\n border: 1px solid #d7dae9;\n border-radius: 4px;\n background: #f6f5f7;\n color: var(--text-color-base, #0e0c26);\n font-family: inherit;\n font-size: 0.875rem;\n outline: none;\n}\n\n.root::placeholder {\n color: #72749e;\n}\n","import clsx from 'clsx'\nimport { useTranslation } from '@/i18n'\nimport { useRatingContext } from './context'\nimport styles from './Comment.module.css'\n\nexport interface RatingCommentProps {\n placeholder?: string\n className?: string\n}\n\nconst Comment = ({ placeholder, className }: RatingCommentProps) => {\n const { comment, setComment } = useRatingContext()\n const { t } = useTranslation()\n\n const label = placeholder ?? t('Please describe any issues you experienced')\n\n return (\n <textarea\n className={clsx(styles.root, className)}\n aria-label={label}\n placeholder={label}\n value={comment}\n onChange={(event) => {\n setComment(event.target.value)\n }}\n />\n )\n}\n\nexport default Comment\n",".root {\n display: grid;\n gap: 24px;\n width: 100%;\n max-width: 400px;\n margin: 0 auto;\n}\n\n.reasons {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n","import type { ReactNode } from 'react'\nimport clsx from 'clsx'\nimport { useTranslation } from '@/i18n'\nimport { useRatingContext } from './context'\nimport Reason from './Reason'\nimport Comment from './Comment'\nimport styles from './Feedback.module.css'\n\nexport interface RatingReasonOption {\n value: string\n label: ReactNode\n}\n\nexport interface RatingFeedbackProps {\n reasons?: RatingReasonOption[]\n placeholder?: string\n className?: string\n children?: ReactNode\n}\n\nconst Feedback = ({ reasons, placeholder, className, children }: RatingFeedbackProps) => {\n const { rating, complete, feedbackThreshold } = useRatingContext()\n const { t } = useTranslation()\n\n if (complete || rating === null || rating > feedbackThreshold) {\n return null\n }\n\n const defaultReasons: RatingReasonOption[] = [\n {\n value: 'hard_to_start_session',\n label: t('It was too hard to start the session with the user'),\n },\n { value: 'screen_too_slow', label: t('The screen was too slow to load or update') },\n { value: 'screen_broken', label: t('Parts of the screen did not load correctly') },\n { value: 'tools_not_helpful', label: t('The tools were not helpful or too hard to use') },\n ]\n\n return (\n <div className={clsx(styles.root, className)}>\n {children ?? (\n <>\n <div className={styles.reasons}>\n {(reasons ?? defaultReasons).map((reason) => (\n <Reason key={reason.value} value={reason.value} label={reason.label} />\n ))}\n </div>\n <Comment placeholder={placeholder} />\n </>\n )}\n </div>\n )\n}\n\nexport default Feedback\n",".root {\n align-self: center;\n background: #040d3c;\n color: #ffffff;\n}\n\n.root:active {\n transform: translateY(1px);\n}\n","import type { ReactNode } from 'react'\nimport clsx from 'clsx'\nimport Button from '@/components/Button'\nimport { useTranslation } from '@/i18n'\nimport { useRatingContext } from './context'\nimport styles from './Submit.module.css'\n\nexport interface RatingSubmitProps {\n className?: string\n children?: ReactNode\n}\n\nconst Submit = ({ className, children }: RatingSubmitProps) => {\n const { submit, complete } = useRatingContext()\n const { t } = useTranslation()\n\n if (complete) {\n return null\n }\n\n return (\n <Button className={clsx(styles.root, className)} onClick={submit}>\n {children ?? t('Continue')}\n </Button>\n )\n}\n\nexport default Submit\n",".root {\n text-align: center;\n color: var(--text-color-base, #0e0c26);\n}\n","import type { ReactNode } from 'react'\nimport clsx from 'clsx'\nimport { useTranslation } from '@/i18n'\nimport { useRatingContext } from './context'\nimport styles from './ThankYou.module.css'\n\nexport interface RatingThankYouProps {\n className?: string\n children?: ReactNode\n}\n\nconst ThankYou = ({ className, children }: RatingThankYouProps) => {\n const { complete, rating } = useRatingContext()\n const { t } = useTranslation()\n\n if (!complete || rating === null) {\n return null\n }\n\n return (\n <div role='status' className={clsx(styles.root, className)}>\n {children ?? t('Thank you for your feedback.')}\n </div>\n )\n}\n\nexport default ThankYou\n",".root {\n display: flex;\n flex-direction: column;\n gap: 16px;\n color: var(--text-color-base, #0e0c26);\n}\n","import { useState, type ReactNode } from 'react'\nimport clsx from 'clsx'\nimport type { RatingValue } from 'cobrowse-agent-sdk'\nimport RatingContext, { type RatingContextValue, type RatingResult } from './context'\nimport Stars, { type RatingStarsProps } from './Stars'\nimport Feedback, { type RatingFeedbackProps } from './Feedback'\nimport Reason, { type RatingReasonProps } from './Reason'\nimport Comment, { type RatingCommentProps } from './Comment'\nimport Submit, { type RatingSubmitProps } from './Submit'\nimport ThankYou, { type RatingThankYouProps } from './ThankYou'\nimport styles from './Rating.module.css'\n\nexport type { RatingResult, RatingContextValue } from './context'\nexport type { RatingStarsProps } from './Stars'\nexport type { RatingFeedbackProps, RatingReasonOption } from './Feedback'\nexport type { RatingReasonProps } from './Reason'\nexport type { RatingCommentProps } from './Comment'\nexport type { RatingSubmitProps } from './Submit'\nexport type { RatingThankYouProps } from './ThankYou'\nexport { useRatingContext } from './context'\n\nconst DEFAULT_FEEDBACK_THRESHOLD = 3\n\nexport interface RatingProps {\n onComplete: (result?: RatingResult) => void\n feedbackThreshold?: number\n className?: string\n children: ReactNode\n}\n\ntype RatingComponent = ((props: RatingProps) => ReactNode) & {\n Stars: (props: RatingStarsProps) => ReactNode\n Feedback: (props: RatingFeedbackProps) => ReactNode\n Reason: (props: RatingReasonProps) => ReactNode\n Comment: (props: RatingCommentProps) => ReactNode\n Submit: (props: RatingSubmitProps) => ReactNode\n ThankYou: (props: RatingThankYouProps) => ReactNode\n}\n\nconst RatingBase = ({\n onComplete,\n feedbackThreshold = DEFAULT_FEEDBACK_THRESHOLD,\n className,\n children,\n}: RatingProps) => {\n const [rating, setRatingState] = useState<RatingValue | null>(null)\n const [feedback, setFeedback] = useState<string[]>([])\n const [comment, setComment] = useState('')\n const [complete, setComplete] = useState(false)\n\n const finish = (rating: RatingValue | null, feedback: string[], comment: string) => {\n setComplete(true)\n onComplete(\n rating === null ? undefined : { rating, feedback: [...feedback, comment].filter(Boolean) },\n )\n }\n\n const setRating = (score: RatingValue, commit = true) => {\n setRatingState(score)\n\n // Reset feedback values so that they are not submitted if the agent changes its initial low rating to 4/5 stars\n if (score > feedbackThreshold) {\n setFeedback([])\n setComment('')\n\n if (commit) {\n finish(score, [], '')\n }\n }\n }\n\n const toggleReason = (value: string) => {\n setFeedback((prev) =>\n prev.includes(value) ? prev.filter((v) => v !== value) : [...prev, value],\n )\n }\n\n const submit = () => {\n finish(rating, feedback, comment)\n }\n\n const value: RatingContextValue = {\n rating,\n feedback,\n comment,\n complete,\n feedbackThreshold,\n setRating,\n toggleReason,\n setComment,\n submit,\n }\n\n return (\n <RatingContext.Provider value={value}>\n <div className={clsx(styles.root, className)}>{children}</div>\n </RatingContext.Provider>\n )\n}\n\nconst Rating: RatingComponent = Object.assign(RatingBase, {\n Stars,\n Feedback,\n Reason,\n Comment,\n Submit,\n ThankYou,\n})\n\nexport default Rating\n","import Rating from './'\nimport type { RatingResult } from './context'\n\nexport type SessionRatingResult = RatingResult\n\nexport interface SessionRatingProps {\n onComplete: (result?: SessionRatingResult) => void\n showThankYou?: boolean\n className?: string\n}\n\nconst SessionRating = ({ onComplete, showThankYou = false, className }: SessionRatingProps) => (\n <Rating onComplete={onComplete} className={className}>\n <Rating.Stars />\n <Rating.Feedback />\n <Rating.Submit />\n {showThankYou && <Rating.ThankYou />}\n </Rating>\n)\n\nexport default SessionRating\n","export const ASCENDING = 'ascending'\nexport const DESCENDING = 'descending'\n\nexport type SortDirection = typeof ASCENDING | typeof DESCENDING\n\nexport interface TableSort {\n key: string\n direction: SortDirection\n}\n\n/** Reads a column off a row for sorting. Memoise a set of these - they are a dependency of the sort. */\nexport type TableSortValues<TRow> = Record<string, (row: TRow) => unknown>\n\n/**\n * What clicking a column asks for: the column already sorted by flips\n * direction, and any other takes `firstDirection`.\n */\nexport function nextSort(\n sort: TableSort | undefined,\n key: string,\n firstDirection: SortDirection = ASCENDING,\n): TableSort {\n if (sort?.key !== key) return { key, direction: firstDirection }\n\n return { key, direction: sort.direction === ASCENDING ? DESCENDING : ASCENDING }\n}\n",".table {\n width: 100%;\n border-collapse: collapse;\n font-size: 14px;\n color: #0e0c26;\n}\n\n.head {\n background: #f9fafb;\n}\n\n.headCell {\n padding: 12px 16px;\n text-align: start;\n font-size: 12px;\n font-weight: 500;\n color: #6f6d82;\n border-bottom: 1px solid rgba(4, 13, 60, 0.12);\n}\n\n.headCell[data-sorted='true'] {\n font-weight: 700;\n color: #0e0c26;\n}\n\n.sortButton {\n composes: focusRing from '../../styles/focus.module.css';\n display: flex;\n align-items: center;\n gap: 6px;\n width: 100%;\n padding: 0;\n border: none;\n border-radius: 2px;\n background: none;\n font: inherit;\n color: inherit;\n cursor: pointer;\n}\n\n.row {\n border-bottom: 1px solid rgba(4, 13, 60, 0.12);\n}\n\n.body .row:last-child {\n border-bottom: none;\n}\n\n.cell {\n padding: 12px 16px;\n}\n\n.emptyCell {\n padding: 40px 16px;\n text-align: center;\n color: #6f6d82;\n}\n","import {\n createContext,\n useContext,\n useMemo,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from 'react'\nimport clsx from 'clsx'\nimport { ASCENDING, nextSort, type SortDirection, type TableSort } from './sort'\nimport styles from './Table.module.css'\nimport Button from '../Button'\n\nexport { ASCENDING, DESCENDING } from './sort'\nexport type { SortDirection, TableSort, TableSortValues } from './sort'\n\ninterface TableContextValue {\n sortBy: (key: string, firstDirection?: SortDirection) => void\n directionOf: (key?: string) => SortDirection | undefined\n}\n\nconst TableContext = createContext<TableContextValue | null>(null)\nconst ColumnContext = createContext<string | undefined>(undefined)\n\nfunction useTableContext(part: string): TableContextValue {\n const table = useContext(TableContext)\n\n if (!table) throw new Error(`<Table.${part}> must be rendered inside <Table>`)\n\n return table\n}\n\nexport interface TableProps extends ComponentPropsWithoutRef<'table'> {\n /** The column the rows are in the order of, and which way. Always controlled. */\n sort?: TableSort\n /**\n * Called with the sort a SortButton click asks for, the column already\n * sorted by flipping direction. Ordering the rows to match is the caller's\n * responsibility.\n */\n onSortChange?: (sort: TableSort) => void\n}\n\nexport type TableHeadProps = ComponentPropsWithoutRef<'thead'>\nexport type TableBodyProps = ComponentPropsWithoutRef<'tbody'>\nexport type TableRowProps = ComponentPropsWithoutRef<'tr'>\n\nexport interface TableHeadCellProps extends ComponentPropsWithoutRef<'th'> {\n /** Marks this header as the one sorted by, and supplies the column to a nested SortButton */\n column?: string\n}\n\nexport interface TableCellProps extends ComponentPropsWithoutRef<'td'> {\n column?: string\n}\n\nexport interface TableSortButtonState {\n isSorted: boolean\n direction?: SortDirection\n}\n\nexport interface TableSortButtonProps extends Omit<ComponentPropsWithoutRef<'button'>, 'children'> {\n /** Defaults to the enclosing HeadCell's column */\n column?: string\n /** The direction applied when this column is first sorted by */\n firstDirection?: SortDirection\n /** Render the sort button contents. May be a function, which receives this column's sort state */\n children?: ReactNode | ((state: TableSortButtonState) => ReactNode)\n}\n\nexport interface TableEmptyProps extends ComponentPropsWithoutRef<'td'> {\n colSpan: number\n}\n\nconst TableBase = ({ sort, onSortChange, className, ...props }: TableProps) => {\n const context = useMemo<TableContextValue>(\n () => ({\n sortBy: (key, firstDirection) => {\n onSortChange?.(nextSort(sort, key, firstDirection))\n },\n directionOf: (key) => (key !== undefined && sort?.key === key ? sort.direction : undefined),\n }),\n [sort, onSortChange],\n )\n\n return (\n <TableContext.Provider value={context}>\n <table className={clsx(styles.table, className)} {...props} />\n </TableContext.Provider>\n )\n}\n\nconst Head = ({ className, ...props }: TableHeadProps) => (\n <thead className={clsx(styles.head, className)} {...props} />\n)\n\nconst Body = ({ className, ...props }: TableBodyProps) => (\n <tbody className={clsx(styles.body, className)} {...props} />\n)\n\nconst Row = ({ className, ...props }: TableRowProps) => (\n <tr className={clsx(styles.row, className)} {...props} />\n)\n\nconst HeadCell = ({ column, className, ...props }: TableHeadCellProps) => {\n const { directionOf } = useTableContext('HeadCell')\n const direction = directionOf(column)\n\n return (\n <ColumnContext.Provider value={column}>\n <th\n scope='col'\n aria-sort={direction}\n data-sorted={direction ? true : undefined}\n className={clsx(styles.headCell, className)}\n {...props}\n />\n </ColumnContext.Provider>\n )\n}\n\nconst Cell = ({ column, className, ...props }: TableCellProps) => {\n const { directionOf } = useTableContext('Cell')\n\n return (\n <td\n data-sorted={directionOf(column) ? true : undefined}\n className={clsx(styles.cell, className)}\n {...props}\n />\n )\n}\n\nconst SortButton = ({\n column,\n firstDirection = ASCENDING,\n className,\n children,\n ...props\n}: TableSortButtonProps) => {\n const { sortBy, directionOf } = useTableContext('SortButton')\n const headCellColumn = useContext(ColumnContext)\n const key = column ?? headCellColumn\n\n if (key === undefined)\n throw new Error(\"<Table.SortButton> needs a column, either its own or a HeadCell's\")\n\n const direction = directionOf(key)\n\n return (\n <Button\n className={clsx(styles.sortButton, className)}\n onClick={() => {\n sortBy(key, firstDirection)\n }}\n {...props}\n >\n {typeof children === 'function'\n ? children({ isSorted: direction !== undefined, direction })\n : children}\n </Button>\n )\n}\n\nconst Empty = ({ colSpan, className, ...props }: TableEmptyProps) => (\n <tr className={styles.row}>\n <td colSpan={colSpan} className={clsx(styles.cell, styles.emptyCell, className)} {...props} />\n </tr>\n)\n\ntype TableComponent = ((props: TableProps) => ReactNode) & {\n Head: typeof Head\n Body: typeof Body\n Row: typeof Row\n HeadCell: typeof HeadCell\n Cell: typeof Cell\n SortButton: typeof SortButton\n Empty: typeof Empty\n}\n\nconst Table: TableComponent = Object.assign(TableBase, {\n Head,\n Body,\n Row,\n HeadCell,\n Cell,\n SortButton,\n Empty,\n})\n\nexport { Table }\nexport default Table\n","import type { RESTResourceEventMap } from 'cobrowse-agent-sdk'\nimport { useEffect, useMemo, useReducer } from 'react'\n\nexport interface ObservableEntity {\n // The SDK types id as a string, but a destroyed resource is updated with an empty payload and loses it\n id?: string\n on: <Event extends keyof RESTResourceEventMap>(\n event: Event,\n listener: (...args: RESTResourceEventMap[Event]) => void,\n ) => unknown\n\n off: <Event extends keyof RESTResourceEventMap>(\n event: Event,\n listener: (...args: RESTResourceEventMap[Event]) => void,\n ) => unknown\n}\n\n// Getters read the SDK's private state through `this`, so they must run against the entity rather than the proxy.\n// Methods are bound by the SDK, so they keep their context and identity without any help here.\nexport function createEntityProxy<Entity extends object>(entity: Entity): Entity {\n return new Proxy(entity, {\n get: (target, property) => Reflect.get(target, property, target),\n })\n}\n\n// The latest proxy per entity. An entry only exists once the entity has been updated.\nconst currentProxies = new WeakMap<object, object>()\n\nfunction currentProxyOf<Entity extends object>(entity: Entity): Entity {\n // Entries are only ever set to createEntityProxy(entity), so the proxy has the entity's type.\n // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- see above\n return (currentProxies.get(entity) as Entity | undefined) ?? entity\n}\n\nexport function useObservableEntities<Entity extends ObservableEntity>(\n entities: readonly Entity[] | null,\n): Entity[] | null {\n const [version, bump] = useReducer((version: number) => version + 1, 0)\n\n useEffect(() => {\n if (!entities) return\n\n const listeners = entities.map((entity) => {\n const listener = () => {\n // A fresh proxy gives React a new identity for this entity only\n currentProxies.set(entity, createEntityProxy(entity))\n bump()\n }\n\n entity.on('updated', listener)\n\n return { entity, listener }\n })\n\n return () => {\n for (const { entity, listener } of listeners) {\n entity.off('updated', listener)\n }\n }\n }, [entities])\n\n return useMemo(\n () =>\n entities\n ?.map(currentProxyOf)\n // A destroyed resource is updated with an empty payload, which leaves it without an id. Drop it so\n // consumers don't see a dead entity, and so a single resource reads as null once destroyed.\n .filter((entity) => entity.id !== undefined) ?? null,\n // version isn't read, it's what invalidates the memo when an entity is updated\n // eslint-disable-next-line react-hooks/exhaustive-deps -- see above\n [entities, version],\n )\n}\n\nexport function useObservableEntity<Entity extends ObservableEntity>(\n entity: Entity | null,\n): Entity | null {\n const entities = useMemo(() => (entity === null ? null : [entity]), [entity])\n\n return useObservableEntities(entities)?.[0] ?? null\n}\n","import { useCallback, useMemo, useRef, useState } from 'react'\n\nexport function useAsync<Args extends unknown[], Result>(fn: (...args: Args) => Promise<Result>) {\n const [isPending, setIsPending] = useState(false)\n const [isSuccess, setIsSuccess] = useState(false)\n const [error, setError] = useState<Error | null>(null)\n const [data, setData] = useState<Result | null>(null)\n const callIdRef = useRef(0)\n\n const executeAsync = useCallback(\n async (...args: Args): Promise<Result> => {\n // Only the most recent call may write state. A superseded call still resolves or rejects for its own\n // caller, but its result, error and pending transitions are dropped so they can't clobber a newer call.\n callIdRef.current += 1\n const callId = callIdRef.current\n const isCurrent = () => callId === callIdRef.current\n\n setError(null)\n setIsPending(true)\n\n try {\n const result = await fn(...args)\n\n if (isCurrent()) {\n setData(result)\n setIsSuccess(true)\n }\n\n return result\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err))\n\n if (isCurrent()) setError(error)\n throw error\n } finally {\n if (isCurrent()) setIsPending(false)\n }\n },\n [fn],\n )\n\n const reset = useCallback(() => {\n setData(null)\n setError(null)\n setIsPending(false)\n setIsSuccess(false)\n }, [])\n\n return useMemo(\n () => ({\n data,\n error,\n isPending,\n // A later failure keeps this true, since the data from the earlier success is still held. Only a reset clears it.\n isSuccess,\n isError: error !== null,\n executeAsync,\n reset,\n }),\n [data, error, isPending, isSuccess, executeAsync, reset],\n )\n}\n","import { type ObservableEntity, useObservableEntity } from './useObservable'\nimport { useAsync } from './useAsync'\nimport { useCallback, useMemo } from 'react'\n\nexport function useMutation<Args extends unknown[], Entity extends ObservableEntity>(\n fn: (...args: Args) => Promise<Entity>,\n) {\n const {\n data: result,\n error,\n isPending,\n isSuccess,\n isError,\n executeAsync: mutateAsync,\n } = useAsync(fn)\n const data = useObservableEntity(result)\n\n const mutate = useCallback(\n (...args: Args): void => {\n void mutateAsync(...args).catch(() => undefined)\n },\n [mutateAsync],\n )\n\n return useMemo(\n () => ({\n data,\n error,\n isPending,\n isSuccess,\n isError,\n mutate,\n mutateAsync,\n }),\n [data, error, isPending, isSuccess, isError, mutate, mutateAsync],\n )\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { useAsync } from './useAsync'\nimport type { QueryParams, QueryShape, RequestOptions } from 'cobrowse-agent-sdk'\n\nexport interface QueryOptions {\n fetchOnMount?: boolean\n}\n\ntype QueryRequestInit = Omit<RequestInit, 'signal'>\n\nexport type QueryRequestOptions<TQuery extends QueryShape<TQuery> = QueryParams> = Omit<\n RequestOptions<TQuery>,\n 'request'\n> & {\n request?: QueryRequestInit\n}\n\nconst isAbortError = (error: unknown): boolean =>\n error instanceof Error && error.name === 'AbortError'\n\nexport function useQuery<Args extends unknown[], TQuery extends QueryShape<TQuery>, Result>(\n fn: (...args: [...Args, options?: RequestOptions<TQuery>]) => Promise<Result>,\n { fetchOnMount = true }: QueryOptions = {},\n ...args: Args\n) {\n // Each arg is a dependency so a change (e.g. a resource id) produces a new callback and triggers a refetch.\n // Call sites pass a fixed number of args, so the deps array length is stable across renders.\n const wrappedFn = useCallback(\n async (options?: RequestOptions<TQuery>) => await fn(...args, options),\n // eslint-disable-next-line react-hooks/exhaustive-deps -- rest args can't be listed statically, the spread is intentional\n [fn, ...args],\n )\n const {\n data,\n isPending: isExecuting,\n isSuccess,\n isError: isAsyncError,\n executeAsync,\n reset,\n } = useAsync(wrappedFn)\n\n const controllerRef = useRef<AbortController | null>(null)\n const [error, setError] = useState<Error | null>(null)\n\n // A new fn or args means a different resource, so drop the previous result rather than showing it under the\n // new identity. A refetch with the same args keeps the current data to avoid UI flashes. This runs during render\n // so there's no committed frame with stale data.\n const [prevFn, setPrevFn] = useState(() => wrappedFn)\n if (prevFn !== wrappedFn) {\n setPrevFn(() => wrappedFn)\n setError(null)\n reset()\n }\n\n // With fetchOnMount a request is guaranteed to follow, so a query with no outcome yet is pending even before the\n // effect starts it. This avoids a \"no data, not loading\" frame on mount and after a reset. The async error state\n // (unlike the query's, it includes aborts) counts as an outcome so a failed or cancelled request settles.\n const isPending = isExecuting || (fetchOnMount && !isSuccess && !isAsyncError)\n\n const refetch = useCallback(\n async (options?: QueryRequestOptions<TQuery>): Promise<void> => {\n controllerRef.current?.abort()\n setError(null)\n\n const controller = new AbortController()\n controllerRef.current = controller\n\n // A newer refetch replaces the controller, so this tells us whether this request is still the active one.\n const isCurrent = () => controllerRef.current === controller\n\n const requestOptions: RequestOptions<TQuery> = {\n ...options,\n request: {\n ...options?.request,\n signal: controller.signal,\n },\n }\n\n try {\n await executeAsync(requestOptions)\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err))\n\n // errors are handled through the state. Abort errors are intentionally swallowed, and a refetch that\n // has since been superseded must not surface its error over the newer request's state.\n if (isCurrent() && !isAbortError(error)) {\n setError(error)\n }\n } finally {\n if (isCurrent()) {\n controllerRef.current = null\n }\n }\n },\n [executeAsync],\n )\n\n const cancel = useCallback(() => {\n controllerRef.current?.abort()\n }, [])\n\n useEffect(() => {\n if (fetchOnMount) void refetch()\n\n return cancel\n }, [fetchOnMount, refetch, cancel])\n\n return useMemo(\n () => ({\n data,\n error,\n /** A request is in flight, whether the first load or a refetch. */\n isPending,\n /** A request has resolved since the query was mounted or its args changed. Stays true if a later refetch fails. */\n isSuccess,\n /** The first load is in flight and there's no data yet, e.g. to show a skeleton. */\n isLoading: isPending && !isSuccess,\n /** A refetch is in flight while previous data is shown, e.g. to show a subtle indicator. */\n isRefetching: isPending && isSuccess,\n refetch,\n cancel,\n isError: error !== null,\n }),\n [data, error, refetch, cancel, isPending, isSuccess],\n )\n}\n","import equal from 'fast-deep-equal'\nimport { useState } from 'react'\n\n// Keeps the previous value while a new one is equal to it by value, so a value rebuilt every render, such as an object\n// passed inline, keeps its identity for the hooks that depend on it\nexport function useStableValue<T>(value: T): T {\n const [stable, setStable] = useState(value)\n\n if (!equal(stable, value)) {\n setStable(() => value)\n }\n\n return stable\n}\n","import { useCallback, useLayoutEffect, useMemo, useReducer, useRef, useState } from 'react'\nimport { type ObservableEntity, useObservableEntities } from './useObservable'\nimport { type QueryOptions, useQuery } from './useQuery'\nimport { useStableValue } from './useStableValue'\nimport type { QueryShape, RequestOptions } from 'cobrowse-agent-sdk'\n\n/**\n * A page of a listing: an array of its results that knows how to load the page after it, such as the SDK's `Page`,\n * including one mapped with its `mapPage()`. Anything of this shape works, as long as it keeps paging, including\n * after its results are changed as an array's are, e.g. one put first with `unshift()`.\n */\nexport interface ListPage<Entity> extends Array<Entity> {\n readonly hasNextPage: boolean\n nextPage: (options?: Pick<RequestOptions, 'request'>) => Promise<ListPage<Entity>>\n}\n\nexport interface CollectionOptions<TQuery> extends QueryOptions {\n /** Params for the listing, such as filters. A change, compared by value, starts again from the first page. */\n query?: TQuery\n}\n\n/**\n * Lists a resource a page at a time. How each page after the first is requested is up to the pages `fn` resolves,\n * so the SDK's list methods page as their API does.\n *\n * `fn` should keep its identity across renders, e.g. an SDK list method or a function wrapped in `useCallback`, as a\n * new one starts the list again.\n *\n * `isPending`, `isLoading` and `isRefetching` describe the first page: a request for it, one with nothing shown yet, and\n * a refetch of it over what's shown. Loading more is reported by `isLoadingMore` alone.\n *\n * `unshift()` puts entities first in the results without a request, e.g. one just created, until the first page is next\n * loaded or refetched, which lists what the API does.\n *\n * @experimental\n * WARNING: This hook's API, behaviour, and name may change without notice.\n */\nexport function useCollection<\n Args extends unknown[],\n TQuery extends QueryShape<TQuery>,\n Entity extends ObservableEntity,\n>(\n fn: (...args: [...Args, options?: RequestOptions<TQuery>]) => Promise<ListPage<Entity>>,\n { query, ...options }: CollectionOptions<TQuery> = {},\n ...args: Args\n) {\n const stableQuery = useStableValue(query)\n\n const fetchFirstPage = useCallback(\n async (options?: RequestOptions<TQuery>) =>\n await fn(...args, {\n ...options,\n query: stableQuery === undefined ? options?.query : { ...stableQuery, ...options?.query },\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps -- rest args can't be listed statically, see useQuery\n [fn, stableQuery, ...args],\n )\n\n // The first page is a plain query, so mounting, resetting when the args or query change, refetching and\n // cancelling all behave as they do for useQuery\n const first = useQuery(fetchFirstPage, options)\n\n // The pages after the first, tagged with the first page they followed, so a new one (a load, a refetch, or new args\n // or query) starts the list again\n const [loaded, setLoaded] = useState<{\n after: ListPage<Entity> | null\n pages: Array<ListPage<Entity>>\n }>({ after: null, pages: [] })\n const nextPages = loaded.after === first.data ? loaded.pages : null\n\n // Entities put first are added to the first page in place, as its paging is fixed, so the pages after it stay\n // tagged with it. The page keeps its identity, so the version is what tells the results below that it changed.\n const [version, bump] = useReducer((version: number) => version + 1, 0)\n\n // The page is read through a ref so a call reaches the page being shown, not the one the caller's render had: a\n // handler is typically made in one render and calls after an await, by which time the first page may have loaded\n // or been refetched. The ref is set on commit, so a call never reaches a page that hasn't been shown yet.\n const firstPageRef = useRef(first.data)\n useLayoutEffect(() => {\n firstPageRef.current = first.data\n }, [first.data])\n\n const unshift = useCallback((...entities: Entity[]): void => {\n const page = firstPageRef.current\n if (page === null) return\n\n // One the page already has is left where it is, so putting an entity first is idempotent, e.g. a created account\n // put first by the app and again by selecting it\n const added = entities.filter(\n (entity) => entity.id === undefined || !page.some((listed) => listed.id === entity.id),\n )\n if (added.length === 0) return\n\n page.unshift(...added)\n bump()\n }, [])\n\n const loadedPages = useMemo(\n () => (first.data === null ? null : [first.data, ...(nextPages ?? [])]),\n // version isn't read, it's what recomputes the pages when the first is added to in place\n // eslint-disable-next-line react-hooks/exhaustive-deps -- see above\n [first.data, nextPages, version],\n )\n const last = loadedPages?.[loadedPages.length - 1]\n const hasMore = last?.hasNextPage ?? false\n\n // The page after the last is a query too, keyed on the last page, so a new first page resets it, cancelling a request\n // in flight and clearing its error. The page is added as its request completes, unless that was cancelled, and is\n // tagged with the first page it followed, so one that completes for an earlier list never shows in a newer one.\n const fetchMore = useCallback(\n async (options?: RequestOptions<TQuery>) => {\n if (last === undefined) throw new Error('There is no page to load the next one from')\n\n const after = first.data\n const page = await last.nextPage({ request: options?.request })\n\n if (options?.request?.signal?.aborted !== true) {\n setLoaded((loaded) => ({\n after,\n pages: loaded.after === after ? [...loaded.pages, page] : [page],\n }))\n }\n\n return page\n },\n [first.data, last],\n )\n const {\n error: loadMoreError,\n isPending: isLoadingMore,\n refetch: refetchMore,\n cancel: cancelMore,\n } = useQuery(fetchMore, { fetchOnMount: false })\n\n // Stops whichever page is in flight, the first or one loading more\n const { cancel: cancelFirst } = first\n const cancel = useCallback(() => {\n cancelFirst()\n cancelMore()\n }, [cancelFirst, cancelMore])\n\n const loadMore = useCallback(async (): Promise<void> => {\n if (!hasMore || first.isPending || isLoadingMore) return\n\n await refetchMore()\n }, [hasMore, first.isPending, isLoadingMore, refetchMore])\n\n // Offset paging repeats a result when one is added between pages, so only its first occurrence is kept. The page\n // it came from is noted so the live results can be grouped back into pages.\n const { entities, pageIndexById } = useMemo(() => {\n const pageIndexById = new Map<string, number>()\n if (loadedPages === null) return { entities: null, pageIndexById }\n\n const entities = loadedPages.flatMap((page, index) =>\n page.filter((entity) => {\n if (entity.id === undefined) return true\n if (pageIndexById.has(entity.id)) return false\n\n pageIndexById.set(entity.id, index)\n\n return true\n }),\n )\n\n return { entities, pageIndexById }\n }, [loadedPages])\n const data = useObservableEntities(entities)\n\n // The live results grouped by page, so they update and drop out just as they do in data. A last page that came back\n // empty only marks the end of the listing, so it's left out, while other pages keep their place even if emptied.\n const pages = useMemo(() => {\n if (loadedPages === null || data === null) return null\n\n const grouped = loadedPages.map((): Entity[] => [])\n for (const entity of data) {\n const index = entity.id === undefined ? undefined : pageIndexById.get(entity.id)\n if (index !== undefined) grouped[index].push(entity)\n }\n\n const lastIndex = loadedPages.length - 1\n return lastIndex > 0 && loadedPages[lastIndex].length === 0\n ? grouped.slice(0, lastIndex)\n : grouped\n }, [loadedPages, data, pageIndexById])\n\n const error = first.error ?? loadMoreError\n\n return useMemo(\n () => ({\n ...first,\n data,\n error,\n isError: error !== null,\n cancel,\n /**\n * The results of each page loaded, e.g. to show one at a time with page controls. They're the same live results\n * as `data`, so a result repeated on a later page only shows on the first. Null until the first page has loaded.\n */\n pages,\n /** More results may follow. False until the first page has loaded, and once a page comes back empty. */\n hasMore,\n /** More results are being loaded. */\n isLoadingMore,\n /** Loading more results failed. The results already loaded are kept. */\n isLoadMoreError: loadMoreError !== null,\n /** Loads the page after the last and adds its results, unless one is in flight or there are no more. */\n loadMore,\n /**\n * Puts entities first in the results without a request, e.g. one just created. They're kept until the first page\n * is next loaded or refetched, which lists what the API does. Nothing is added before the first page has loaded,\n * and one already listed is left where it is.\n */\n unshift,\n }),\n [first, data, pages, error, cancel, hasMore, isLoadingMore, loadMoreError, loadMore, unshift],\n )\n}\n","import { useMemo } from 'react'\nimport { type ObservableEntity, useObservableEntity } from './useObservable'\nimport { type QueryOptions, useQuery } from './useQuery'\nimport type { QueryShape, RequestOptions } from 'cobrowse-agent-sdk'\n\nexport function useResource<\n Args extends unknown[],\n TQuery extends QueryShape<TQuery>,\n Entity extends ObservableEntity,\n>(\n fn: (...args: [...Args, options?: RequestOptions<TQuery>]) => Promise<Entity>,\n options?: QueryOptions,\n ...args: Args\n) {\n const query = useQuery(fn, options, ...args)\n const data = useObservableEntity(query.data)\n\n return useMemo(\n () => ({\n ...query,\n data,\n }),\n [query, data],\n )\n}\n","import { useCallback, useMemo, useState } from 'react'\n\nexport interface PaginatedList<Entity> {\n pages: Entity[][] | null\n isPending: boolean\n isLoading: boolean\n hasMore: boolean\n isLoadingMore: boolean\n isLoadMoreError: boolean\n loadMore: () => Promise<void>\n}\n\n/**\n * Shows a paginated list a page at a time, moving between pages rather than adding each to the list. Moving to the\n * next page shows it straight away, loading if it isn't loaded yet, and every page visited stays loaded, so going\n * back never makes a request.\n *\n * ```ts\n * const sessions = useCollection(cobrowse.sessions.list, { query })\n * const page = usePageControls(sessions)\n * ```\n *\n * @experimental\n * WARNING: This hook's API, behaviour, and name may change without notice.\n */\nexport function usePageControls<List extends PaginatedList<unknown>>(list: List) {\n // Loading more is how the next page arrives, not something page controls offer, so it's kept out of the result\n const { pages, hasMore, isLoadingMore, isLoadMoreError, loadMore, ...rest } = list\n\n const [index, setIndex] = useState(0)\n const lastIndex = pages === null ? 0 : pages.length - (isLoadingMore ? 0 : 1)\n const pageIndex = Math.min(index, lastIndex)\n if (index !== pageIndex) setIndex(pageIndex)\n\n const isPendingPage = pages !== null && pageIndex === pages.length\n const data: NonNullable<List['pages']>[number] | null = isPendingPage\n ? null\n : (pages?.[pageIndex] ?? null)\n\n const hasNextPage = pages !== null && !isPendingPage && (pageIndex < pages.length - 1 || hasMore)\n const hasPreviousPage = pageIndex > 0\n\n const goToNextPage = useCallback(async (): Promise<void> => {\n if (pages === null || isPendingPage) return\n\n const needsLoading = pageIndex === pages.length - 1\n if (needsLoading && !hasMore) return\n\n // Shown first, then loaded if need be, with its results filling in when they land\n setIndex(pageIndex + 1)\n if (needsLoading) await loadMore()\n }, [pages, pageIndex, isPendingPage, hasMore, loadMore])\n\n const goToPreviousPage = useCallback(() => {\n setIndex(Math.max(pageIndex - 1, 0))\n }, [pageIndex])\n\n return useMemo(\n () => ({\n ...rest,\n /** The results of the current page. Null while it loads, whether the first page or one moved to. */\n data,\n /** The results of every page loaded. Null until the first page has loaded. */\n pages,\n /** The current page, from 0. One past the last loaded while the page moved to loads. */\n pageIndex,\n /** A request for the current page is in flight, whether its first load, a refetch, or the page moved to. */\n isPending: rest.isPending || isPendingPage,\n /** The current page is loading with nothing to show yet, whether the first page or one moved to. */\n isLoading: rest.isLoading || isPendingPage,\n /** There's a page after the current one, whether loaded already or still to load. */\n hasNextPage,\n hasPreviousPage,\n /** Loading the page moved to failed, so the one before it is shown again. Moving next again retries. */\n isNextPageError: isLoadMoreError,\n /** Moves to the page after the current one, loading it if needed. Back to this one if it comes back empty. */\n goToNextPage,\n /** Moves to the page before the current one, which is always loaded already. */\n goToPreviousPage,\n }),\n [\n rest,\n data,\n pages,\n pageIndex,\n isPendingPage,\n hasNextPage,\n hasPreviousPage,\n isLoadMoreError,\n goToNextPage,\n goToPreviousPage,\n ],\n )\n}\n","import { useCobrowse } from '@/components/CobrowseProvider'\nimport { useMutation } from '@/hooks/useMutation'\n\nexport function useCreateAccount() {\n const cobrowse = useCobrowse()\n\n return useMutation(cobrowse.accounts.create)\n}\n","import { useMutation } from '@/hooks/useMutation'\nimport type { Account } from 'cobrowse-agent-sdk'\n\nexport function useDestroyAccount(account: Account) {\n return useMutation(account.destroy)\n}\n","import { useCobrowse } from '@/components/CobrowseProvider'\nimport { useCollection } from '@/hooks/useCollection'\nimport type { QueryOptions } from '@/hooks/useQuery'\n\nexport function useListAccounts(options?: QueryOptions) {\n const cobrowse = useCobrowse()\n\n return useCollection(cobrowse.accounts.list, options)\n}\n","import { useMutation } from '@/hooks/useMutation'\nimport type { Account } from 'cobrowse-agent-sdk'\n\nexport function useUpdateAccount(account: Account) {\n // eslint-disable-next-line @typescript-eslint/unbound-method -- update is bound in RESTResource's constructor which is not visible to the type system\n return useMutation(account.update)\n}\n","import {\n createContext,\n use,\n useCallback,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react'\nimport type { Account } from 'cobrowse-agent-sdk'\nimport { useCobrowse } from '@/components/CobrowseProvider'\nimport { useListAccounts } from './useListAccounts'\n\nconst storageKey = 'cobrowse-account'\n\nexport type AccountsContextValue = ReturnType<typeof useListAccounts>\n\nexport interface ActiveAccountContextValue {\n /**\n * The selected account, resolved against the loaded list: the stored selection when the user still has it, else the\n * first account. Null until the list has loaded, and when the user has no accounts.\n */\n account: Account | null\n /**\n * The list has loaded, so the selection has been reconciled against it, or it failed to load, so the app can move\n * on rather than wait on an account forever.\n */\n isResolved: boolean\n /**\n * Selects an account, stores the selection for the next load, and sets the SDK's license right away, so a request\n * started straight after carries it. An SDK account the list doesn't contain yet, e.g. one just created, is put\n * first in the list, as its `unshift()` does. Before the list has loaded, any key can be selected, e.g. one forced\n * from the URL, and is resolved against the list once it arrives. After that, a key the list doesn't contain\n * throws.\n */\n setActiveAccount: (account: Pick<Account, 'license_key'>) => void\n}\n\nconst AccountsContext = createContext<AccountsContextValue | null>(null)\nconst ActiveAccountContext = createContext<ActiveAccountContextValue | null>(null)\n\nfunction getStoredLicenseKey(): string | null {\n try {\n return window.localStorage.getItem(storageKey)\n } catch (error) {\n console.warn('Failed to retrieve the stored account.', error)\n }\n\n return null\n}\n\nfunction storeLicenseKey(licenseKey: string): void {\n try {\n window.localStorage.setItem(storageKey, licenseKey)\n } catch (error) {\n console.warn('Failed to store the account.', error)\n }\n}\n\n// The list's entities are SDK accounts, so one can be put in the list, while a bare key can only be found in it\nfunction isAccount(account: Pick<Account, 'license_key'>): account is Account {\n return 'on' in account && 'off' in account\n}\n\nexport interface AccountsProviderProps {\n children?: ReactNode\n}\n\n/**\n * Lists the user's accounts and keeps one selected, with the selection stored in local storage so it survives a\n * reload. While mounted, the provider owns the SDK's license: once the list has loaded, it's kept on the account\n * resolved, so the account shown and the one requests are made against can't differ. On unmount, the SDK is given\n * back the license it had.\n *\n * @experimental\n * WARNING: This component's API, behaviour, and name may change without notice.\n */\nexport function AccountsProvider({ children }: AccountsProviderProps) {\n const cobrowse = useCobrowse()\n // A user's own accounts come back in one page, so the list is complete once loaded. A refetch keeps the list shown\n // until the new one lands, and a destroyed account drops out as it's destroyed.\n const accounts = useListAccounts()\n // The selection asked for: the one stored by a previous load, else a license the app set on the SDK before\n // mounting, e.g. a single-account host. What it resolves to is up to the list, below.\n const [licenseKey, setLicenseKey] = useState(() => getStoredLicenseKey() ?? cobrowse.license)\n\n // The list is read through a ref so a selection checks the list being shown, not the one the caller's render had,\n // e.g. a selection made after an await. The ref is set on commit, before the effects below run.\n const listRef = useRef(accounts.data)\n useLayoutEffect(() => {\n listRef.current = accounts.data\n }, [accounts.data])\n\n const { unshift } = accounts\n\n const setActiveAccount = useCallback(\n (account: Pick<Account, 'license_key'>) => {\n const list = listRef.current\n\n // Once the list has loaded, a selection has to resolve against it, so the account shown is the one selected\n // and nothing the user doesn't have is stored. A created account isn't listed until a refetch, so it's put\n // first, as the list's unshift() does. Before the list has loaded there's nothing to check against: the key is\n // resolved, and stored or dropped, by the reconcile below once the list arrives.\n if (list !== null && !list.some((listed) => listed.license_key === account.license_key)) {\n if (!isAccount(account)) {\n throw new Error(\n `Account ${account.license_key} isn't one of the user's accounts. Pass the SDK account to list it, or select one from the list.`,\n )\n }\n\n unshift(account)\n }\n\n // The SDK license is set synchronously so a request started straight after, or in the same effect phase (e.g.\n // the initial accounts list, after an account is forced before it has loaded), carries the header.\n // oxlint-disable-next-line react/immutability -- the SDK is an external system, and selecting an account is meant to change its license\n cobrowse.license = account.license_key\n storeLicenseKey(account.license_key)\n setLicenseKey(account.license_key)\n },\n [cobrowse, unshift],\n )\n\n const activeAccount = useMemo(() => {\n const list = accounts.data ?? []\n\n return list.find((account) => account.license_key === licenseKey) ?? list[0] ?? null\n }, [accounts.data, licenseKey])\n\n // The license is borrowed while mounted: on unmount, or when another SDK instance is provided, the one the SDK had\n // is given back, so a host that signs another user in on the same instance doesn't list their accounts with the\n // previous user's key. A layout effect, so it's recorded before a consumer's passive effect sets one, e.g. an\n // account forced from the URL.\n useLayoutEffect(() => {\n const previous = cobrowse.license\n\n return () => {\n // oxlint-disable-next-line react/immutability -- the SDK is an external system, and the provider gives back the license it borrowed\n cobrowse.license = previous\n }\n }, [cobrowse])\n\n // Once the list has first loaded, make the resolved account the selected one. This persists an auto-selected\n // fallback and drops a stored selection that is no longer available to the user. It runs once on purpose: later\n // selections are stored as they're made, and a refetch that drops the selected account shouldn't replace the\n // stored one with a fallback.\n const hasReconciled = useRef(false)\n\n useLayoutEffect(() => {\n if (!accounts.isSuccess || hasReconciled.current) return\n\n // oxlint-disable-next-line react/set-state-in-effect -- the loaded list is the external source the stored selection is reconciled against, once\n if (activeAccount !== null) setActiveAccount(activeAccount)\n hasReconciled.current = true\n }, [accounts.isSuccess, activeAccount, setActiveAccount])\n\n // The SDK's license mirrors the account shown, so the two can't differ: it follows the resolved account whenever\n // that changes (a refetch or a destroy drops it, a created one is listed, a new SDK instance is provided), and is\n // cleared when the loaded list has none, as the API rejects a key it can't resolve. Until the list has loaded\n // there's nothing to resolve against, so a key set through setActiveAccount, e.g. one forced from the URL, is left\n // in place for the list request to carry. A layout effect runs before any passive effect in the same commit, so a\n // request a consumer starts for the new account already carries it.\n const activeLicenseKey = activeAccount?.license_key ?? null\n const hasListLoaded = accounts.isSuccess\n\n useLayoutEffect(() => {\n if (!hasListLoaded) return\n\n // oxlint-disable-next-line react/immutability -- the SDK is an external system whose license mirrors the account shown\n cobrowse.license = activeLicenseKey\n }, [cobrowse, hasListLoaded, activeLicenseKey])\n\n // The list has loaded, possibly empty (the API answers a signed-out request with an empty list), so the selection\n // above is reconciled against it, or it failed to load. The query's args never change, so isSuccess stays true\n // from the first load on.\n const isResolved = accounts.isSuccess || accounts.isError\n\n const activeAccountValue = useMemo<ActiveAccountContextValue>(\n () => ({ account: activeAccount, isResolved, setActiveAccount }),\n [activeAccount, isResolved, setActiveAccount],\n )\n\n return (\n <AccountsContext.Provider value={accounts}>\n <ActiveAccountContext.Provider value={activeAccountValue}>\n {children}\n </ActiveAccountContext.Provider>\n </AccountsContext.Provider>\n )\n}\n\n/** The list of the user's accounts, as `useListAccounts` returns it, shared by every consumer of the provider. */\nexport function useAccountsContext(): AccountsContextValue {\n const context = use(AccountsContext)\n\n if (!context) {\n throw new Error('useAccountsContext must be used inside AccountsProvider')\n }\n\n return context\n}\n\n/** The selected account, whether it's been resolved, and the function to select another. */\nexport function useActiveAccountContext(): ActiveAccountContextValue {\n const context = use(ActiveAccountContext)\n\n if (!context) {\n throw new Error('useActiveAccountContext must be used inside AccountsProvider')\n }\n\n return context\n}\n\nexport default AccountsProvider\n","import { useMemo } from 'react'\nimport { type ActiveAccountContextValue, useActiveAccountContext } from './AccountsContext'\n\n/**\n * The selected account and the function to select another, as a pair:\n *\n * ```jsx\n * const [account, setActiveAccount] = useActiveAccount()\n * ```\n *\n * Must be used inside `AccountsProvider`.\n */\nexport function useActiveAccount(): readonly [\n ActiveAccountContextValue['account'],\n ActiveAccountContextValue['setActiveAccount'],\n] {\n const { account, setActiveAccount } = useActiveAccountContext()\n\n return useMemo(() => [account, setActiveAccount] as const, [account, setActiveAccount])\n}\n","import { useCobrowse } from '@/components/CobrowseProvider'\nimport { useResource } from '@/hooks/useResource'\nimport type { QueryOptions } from '@/hooks/useQuery'\n\n/**\n * The policy of the signed-in user on the SDK's current license: what they may do on each resource, as\n * `policy.hasPermission('sessions:create')` and `policy.get('sessions')` answer it.\n *\n * The policy is requested for the license the SDK has when the hook mounts. A license change, e.g. another account\n * selected, is the caller's to handle, by remounting or calling `refetch()`, as with the other hooks.\n */\nexport function useCurrentPolicy(options?: QueryOptions) {\n const cobrowse = useCobrowse()\n\n return useResource(cobrowse.policies.current, options)\n}\n","import CodeEntryComponent from '@/components/CodeEntry'\nimport ButtonComponent from '@/components/Button'\nimport ExternalLinkComponent from '@/components/ExternalLink'\nimport PlatformIconComponent from '@/components/PlatformIcon'\nimport DeviceComponent from '@/components/Device'\nimport SessionComponent from '@/components/Session'\nimport SmartConnectButtonComponent from '@/components/SmartConnectButton'\nimport UserIconComponent from '@/components/UserIcon'\nimport RefreshButtonComponent from '@/components/RefreshButton'\nimport CancelButtonComponent from '@/components/CancelButton'\nimport BlockingErrorComponent from '@/components/BlockingError'\nimport LoaderComponent from '@/components/Loader'\nimport FrameComponent, { useRemoteContext as useRemoteContextHook } from '@/components/Frame'\nimport RemoteContextRelayComponent from '@/components/RemoteContextRelay'\nimport SessionEmbedComponent from '@/components/SessionEmbed'\nimport ConnectDeviceComponent from '@/components/ConnectDevice'\nimport RatingComponent, { useRatingContext as useRatingContextHook } from '@/components/Rating'\nimport SessionRatingComponent from '@/components/Rating/SessionRating'\nimport CobrowseProviderComponent, {\n useCobrowse as useCobrowseHook,\n} from '@/components/CobrowseProvider'\nimport TableComponent from '@/components/Table'\nimport useSessionHook from '@/hooks/useSession'\nimport useSessionEventsHook from '@/hooks/useSessionEvents'\nimport useTrustedEmbeddingOriginsHook from '@/hooks/useTrustedEmbeddingOrigins'\nimport i18nInstance, { bindI18n as bindI18nHelper } from '@/i18n'\nexport { useMutation } from '@/hooks/useMutation'\nexport { useCollection } from '@/hooks/useCollection'\nexport { useResource } from '@/hooks/useResource'\nexport { usePageControls } from '@/hooks/usePageControls'\nexport { parseUserAgent, describeUserAgent } from '@/utils/userAgent'\nexport type { ListPage, CollectionOptions } from '@/hooks/useCollection'\nexport type { ParsedUserAgent } from '@/utils/userAgent'\nexport type { PaginatedList } from '@/hooks/usePageControls'\n\nexport type { CodeEntryProps } from '@/components/CodeEntry'\nexport type { ButtonProps } from '@/components/Button'\nexport type { ExternalLinkProps } from '@/components/ExternalLink'\nexport type { DeviceData, DeviceProps } from '@/components/Device'\nexport type { SessionData, SessionProps } from '@/components/Session'\nexport type { SmartConnectButtonProps } from '@/components/SmartConnectButton'\nexport type { RefreshButtonProps } from '@/components/RefreshButton'\nexport type { CancelButtonProps } from '@/components/CancelButton'\nexport type { BlockingErrorProps } from '@/components/BlockingError'\nexport type { LoaderProps } from '@/components/Loader'\nexport type { FrameProps } from '@/components/Frame'\nexport type { RemoteContextRelayProps } from '@/components/RemoteContextRelay'\nexport type { SessionEmbedProps } from '@/components/SessionEmbed'\nexport type { ConnectDeviceProps } from '@/components/ConnectDevice'\nexport type {\n RatingProps,\n RatingResult,\n RatingContextValue,\n RatingStarsProps,\n RatingFeedbackProps,\n RatingReasonOption,\n RatingReasonProps,\n RatingCommentProps,\n RatingSubmitProps,\n RatingThankYouProps,\n} from '@/components/Rating'\nexport type { SessionRatingProps, SessionRatingResult } from '@/components/Rating/SessionRating'\nexport type { CobrowseProviderProps } from '@/components/CobrowseProvider'\nexport type {\n TableProps,\n TableHeadProps,\n TableBodyProps,\n TableRowProps,\n TableHeadCellProps,\n TableCellProps,\n TableSortButtonProps,\n TableSortButtonState,\n TableEmptyProps,\n TableSort,\n TableSortValues,\n SortDirection,\n} from '@/components/Table'\nexport { ASCENDING, DESCENDING } from '@/components/Table'\nexport type { SessionEventHandlers } from '@/hooks/useSessionEvents'\n\nexport { useCreateAccount } from '@/modules/accounts/useCreateAccount'\nexport { useDestroyAccount } from '@/modules/accounts/useDestroyAccount'\nexport { useListAccounts } from '@/modules/accounts/useListAccounts'\nexport { useUpdateAccount } from '@/modules/accounts/useUpdateAccount'\nexport {\n AccountsProvider,\n useAccountsContext,\n useActiveAccountContext,\n} from '@/modules/accounts/AccountsContext'\nexport type {\n AccountsProviderProps,\n AccountsContextValue,\n ActiveAccountContextValue,\n} from '@/modules/accounts/AccountsContext'\nexport { useActiveAccount } from '@/modules/accounts/useActiveAccount'\nexport { useCurrentPolicy } from '@/modules/policies/useCurrentPolicy'\n\nexport const CodeEntry = CodeEntryComponent\nexport const Button = ButtonComponent\nexport const ExternalLink = ExternalLinkComponent\nexport const PlatformIcon = PlatformIconComponent\nexport const Device = DeviceComponent\nexport const Session = SessionComponent\nexport const SmartConnectButton = SmartConnectButtonComponent\nexport const UserIcon = UserIconComponent\nexport const RefreshButton = RefreshButtonComponent\nexport const CancelButton = CancelButtonComponent\nexport const BlockingError = BlockingErrorComponent\nexport const Loader = LoaderComponent\nexport const Frame = FrameComponent\nexport const RemoteContextRelay = RemoteContextRelayComponent\nexport const SessionEmbed = SessionEmbedComponent\nexport const ConnectDevice = ConnectDeviceComponent\nexport const Rating = RatingComponent\nexport const SessionRating = SessionRatingComponent\nexport const useRatingContext = useRatingContextHook\nexport const CobrowseProvider = CobrowseProviderComponent\nexport const Table = TableComponent\nexport const useCobrowse = useCobrowseHook\nexport const useRemoteContext = useRemoteContextHook\nexport const useSession = useSessionHook\nexport const useSessionEvents = useSessionEventsHook\nexport const useTrustedEmbeddingOrigins = useTrustedEmbeddingOriginsHook\nexport const bindI18n = bindI18nHelper\nexport const i18n = i18nInstance\n"],"mappings":"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AAIqU,EAAoB;CAExC,IAAI,CAACzT,GACH,MAAU,MAAM,8DAA8D;CAGhF,OAAOA;AACT;;;ACxMA,SAAgBgV,KAGd;CACA,IAAM,EAAE,YAAS,wBAAqBD,EAAwB;CAE9D,OAAO7Q,QAAc,CAACkP,GAASgB,CAAgB,GAAY,CAAChB,GAASgB,CAAgB,CAAC;AACxF;;;ACRA,SAAgBa,GAAiB,GAAwB;CAGvD,OAAO9C,GAFUxX,EAEE,CAAA,CAAS,SAAS,SAAS2U,CAAO;AACvD;;;ACkFA,IAAa4F,KAAYta,GACZua,KAASta,GACTua,KAAeta,IACfua,KAAeta,GACfua,KAASta,GACTua,KAAUta,GACVua,KAAqBta,GACrBua,KAAWta,GACXua,KAAgBta,GAChBua,KAAeta,IACfua,KAAgBta,IAChBua,KAASta,GACTua,KAAQta,IACRua,KAAqBta,IACrBua,KAAeta,IACfua,KAAgBta,IAChBua,KAASta,GACTua,KAAgBta,IAChBua,KAAmBta,GACnBua,KAAmBta,IACnBua,KAAQta,IACRua,KAActa,GACdua,KAAmBta,GACnBua,KAAata,IACbua,KAAmBta,IACnBua,KAA6Bta,GAC7Bua,KAAWta,GACXua,KAAOta"}
|
|
1
|
+
{"version":3,"file":"cobrowse-agent-ui.js","names":["root","ExternalLink","styles","IconExternalLink","root","UserIcon","styles","root","visuallyHidden","CancelButton","Button","styles","_Fragment","PhoneIcon","root","BlockingError","styles","CobrowseProvider","useCobrowse","RemoteContext","useRemoteContext","Frame","useRemoteContext","RemoteContextProvider","isAbortError","useTrustedEmbeddingOrigins","useCobrowse","RemoteContextRelay","useRemoteContext","useTrustedEmbeddingOrigins","useSessionEvents","useSession","root","useRemoteContext","useSession","styles","useCobrowse","root","useRemoteContext","styles","Frame","SessionEmbed","isAbortError","useCobrowse","root","styles","Loader","BaseLoader","ConnectDevice","useRatingContext","root","useRatingContext","styles","StarIcon","root","useRatingContext","styles","root","useRatingContext","styles","root","useRatingContext","styles","_Fragment","root","useRatingContext","Button","styles","root","useRatingContext","styles","styles","Rating","SessionRating","Rating","styles","Button","Table","useCobrowse","useCobrowse","useCobrowse","useCobrowse","useCobrowse","useCobrowse","CodeEntryComponent","ButtonComponent","ExternalLinkComponent","PlatformIconComponent","DeviceComponent","SessionComponent","SmartConnectButtonComponent","UserIconComponent","RefreshButtonComponent","CancelButtonComponent","BlockingErrorComponent","LoaderComponent","FrameComponent","RemoteContextRelayComponent","SessionEmbedComponent","ConnectDeviceComponent","RatingComponent","SessionRatingComponent","useRatingContextHook","CobrowseProviderComponent","TableComponent","useCobrowseHook","useRemoteContextHook","useSessionHook","useSessionEventsHook","useTrustedEmbeddingOriginsHook","bindI18nHelper","i18nInstance","i18n$1","Device$1","parseUserAgent","CodeEntry$1","_asyncToGenerator","bindI18n$1","_objectSpread2","Session$1","Button$1","useTranslation","RefreshButton$1","PlatformIcon$1","SmartConnectButton$1","describeUserAgent","Loader$2","_objectWithoutProperties","clsx","equal","SvgExternalLink","props","ExternalLink_module_default","ExternalLink$1","children","UserIcon_module_default","UserIcon$1","user","className","part","SvgPhone","CancelButton_module_default","_excluded$5","CancelButton$1","_ref","Fragment","t","BlockingError_module_default","BlockingError$1","heading","message","CobrowseContext","createContext","CobrowseProvider$1","cobrowse","useCobrowseValue","use","useCobrowse$1","RemoteContext$1","useRemoteContext$1","providedRemoteContext","remoteContext","setRemoteContext","useState","useEffect","target","cancelled","attachedContext","context","useStableCallback","callbackRef","useRef","callback","useCallback","args","_callbackRef$current","_excluded$4","Frame$1","iframe","setIframe","onErrorCallback","onError","handleIframeRef","element","handleError","error","style","isAbortError$2","useTrustedEmbeddingOrigins$1","origins","setOrigins","loading","setLoading","setError","abortController","trusted","RemoteContextRelay$1","resolvedRemoteContext","accountOrigins","resolvedOrigins","trustedOrigins","opener","resolvedDestination","destination","relay","useSessionEvents$1","onLoadedCallback","onLoaded","onUpdatedCallback","onUpdated","onActivatedCallback","onActivated","onEndedCallback","onEnded","sessionActivatedRef","sessionEndedRef","handleSessionLoaded","session","handleSessionUpdated","isRemoteContext","source","RemoteContext","hasSessionProperty","property","createReactiveSession","useSession$1","sessionSource","sessionState","setSessionState","handleSessionChange","Overlay_module_default","Overlay","state","useSessionUrl","useMemo","paramEntries","endAction","agentTools","deviceControls","sessionDetails","language","name","value","query","id","popout","messages","SessionEmbed_module_default","_excluded$3","SessionEventObserver","handlers","SessionEmbed$1","url","title","PUSH_RETRY_MS","ERROR_PUSH_ERROR","ERROR_PUSH_ATTEMPT_LIMIT_REACHED","ERROR_DEVICE_NOT_FOUND","ERROR_SESSION_NOT_FOUND","ERROR_SESSION_ERROR","isAbortError$1","useConnectDevice","deviceRef","sessionRef","sessionConnectedRef","pushTimerRef","onConnectAttemptCallback","onConnectAttempt","onConnectedCallback","onConnected","onCancelledCallback","onCancelled","stopPush","handleSessionEnded","_sessionRef$current","triggerPushError","sendPush","_send","attempt","maxPushAttempts","pushRetryMs","send","createSession","request","region","device","deviceId","cancel","_ref2","ConnectDevice_module_default","ConnectDevice$1","setAttempt","currentAttempt","RatingContext","useRatingContext$1","SvgStar","Stars_module_default","SCORES","Stars","promptId","useId","groupName","pointer","complete","prompt","label","scores","score","count","rating","setRating","Reason_module_default","Reason","feedback","Comment_module_default","Comment","placeholder","comment","event","Feedback_module_default","Feedback","feedbackThreshold","defaultReasons","reasons","reason","Submit_module_default","Submit","submit","ThankYou_module_default","ThankYou","Rating_module_default","DEFAULT_FEEDBACK_THRESHOLD","Rating$1","setRatingState","setFeedback","setComment","setComplete","finish","onComplete","commit","prev","v","SessionRating$1","showThankYou","ASCENDING","DESCENDING","nextSort","sort","key","firstDirection","Table_module_default","_excluded$2","_excluded2","_excluded3","_excluded4","_excluded5","_excluded6","_excluded7","_excluded8","TableContext","ColumnContext","useTableContext","table","useContext","Table$1","onSortChange","_ref3","_ref4","_ref5","direction","directionOf","column","_ref6","_ref7","headCellColumn","_ref8","createEntityProxy","entity","currentProxies","currentProxyOf","_currentProxies$get","useObservableEntities","version","bump","useReducer","entities","listeners","listener","_entities$map$filter","useObservableEntity","_useObservableEntitie","_useObservableEntitie2","useAsync","isPending","setIsPending","isSuccess","setIsSuccess","data","setData","callIdRef","executeAsync","callId","isCurrent","result","fn","err","reset","useMutation","mutateAsync","mutate","isError","isAbortError","useQuery","wrappedFn","options","isExecuting","isAsyncError","controllerRef","prevFn","setPrevFn","fetchOnMount","refetch","_controllerRef$curren","controller","requestOptions","_controllerRef$curren2","useStableValue","stable","setStable","_excluded$1","useCollection","_last$hasNextPage","_first$error","stableQuery","first","loaded","setLoaded","nextPages","firstPageRef","unshift","page","added","listed","loadedPages","last","hasMore","loadMoreError","isLoadingMore","refetchMore","cancelMore","_options$request","after","cancelFirst","loadMore","pageIndexById","index","pages","grouped","lastIndex","useResource","_excluded","usePageControls","_pages$pageIndex","list","rest","setIndex","pageIndex","isPendingPage","hasNextPage","hasPreviousPage","goToNextPage","needsLoading","goToPreviousPage","isLoadMoreError","useCreateAccount","useDestroyAccount","account","useListAccounts","useUpdateAccount","storageKey","AccountsContext","ActiveAccountContext","getStoredLicenseKey","storeLicenseKey","licenseKey","isAccount","AccountsProvider","_activeAccount$licens","accounts","setLicenseKey","_getStoredLicenseKey","listRef","setActiveAccount","activeAccount","_accounts$data","_list$find","previous","hasReconciled","activeLicenseKey","hasListLoaded","isResolved","activeAccountValue","useAccountsContext","useActiveAccountContext","useActiveAccount","useCreateJwtSsoKey","useDestroyJwtSsoKey","useListJwtSsoKeys","useUpdateJwtSsoKey","useCurrentPolicy","CodeEntry","Button","ExternalLink","PlatformIcon","Device","Session","SmartConnectButton","UserIcon","RefreshButton","CancelButton","BlockingError","Loader","Frame","RemoteContextRelay","SessionEmbed","ConnectDevice","Rating","SessionRating","useRatingContext","CobrowseProvider","Table","useCobrowse","useRemoteContext","useSession","useSessionEvents","useTrustedEmbeddingOrigins","bindI18n","i18n"],"sources":["../lib/icons/external-link.svg?react","../lib/components/ExternalLink/ExternalLink.module.css","../lib/components/ExternalLink/index.tsx","../lib/components/UserIcon/UserIcon.module.css","../lib/components/UserIcon/index.tsx","../lib/icons/phone.svg?react","../lib/components/CancelButton/CancelButton.module.css","../lib/components/CancelButton/index.tsx","../lib/components/BlockingError/BlockingError.module.css","../lib/components/BlockingError/index.tsx","../lib/components/CobrowseProvider/index.tsx","../lib/components/Frame/RemoteContext.ts","../lib/hooks/useStableCallback.ts","../lib/components/Frame/index.tsx","../lib/hooks/useTrustedEmbeddingOrigins.ts","../lib/components/RemoteContextRelay/index.tsx","../lib/hooks/useSessionEvents.ts","../lib/hooks/useSession.ts","../lib/components/SessionEmbed/Overlay.module.css","../lib/components/SessionEmbed/Overlay.tsx","../lib/components/SessionEmbed/useSessionUrl.ts","../lib/components/SessionEmbed/SessionEmbed.module.css","../lib/components/SessionEmbed/index.tsx","../lib/components/ConnectDevice/useConnectDevice.ts","../lib/components/ConnectDevice/ConnectDevice.module.css","../lib/components/ConnectDevice/index.tsx","../lib/components/Rating/context.ts","../lib/icons/star.svg?react","../lib/components/Rating/Stars.module.css","../lib/components/Rating/Stars.tsx","../lib/components/Rating/Reason.module.css","../lib/components/Rating/Reason.tsx","../lib/components/Rating/Comment.module.css","../lib/components/Rating/Comment.tsx","../lib/components/Rating/Feedback.module.css","../lib/components/Rating/Feedback.tsx","../lib/components/Rating/Submit.module.css","../lib/components/Rating/Submit.tsx","../lib/components/Rating/ThankYou.module.css","../lib/components/Rating/ThankYou.tsx","../lib/components/Rating/Rating.module.css","../lib/components/Rating/index.tsx","../lib/components/Rating/SessionRating.tsx","../lib/components/Table/sort.ts","../lib/components/Table/Table.module.css","../lib/components/Table/index.tsx","../lib/hooks/useObservable.ts","../lib/hooks/useAsync.ts","../lib/hooks/useMutation.ts","../lib/hooks/useQuery.ts","../lib/hooks/useStableValue.ts","../lib/hooks/useCollection.ts","../lib/hooks/useResource.ts","../lib/hooks/usePageControls.ts","../lib/modules/accounts/useCreateAccount.ts","../lib/modules/accounts/useDestroyAccount.ts","../lib/modules/accounts/useListAccounts.ts","../lib/modules/accounts/useUpdateAccount.ts","../lib/modules/accounts/AccountsContext.tsx","../lib/modules/accounts/useActiveAccount.ts","../lib/modules/jwtsso/useCreateJwtSsoKey.ts","../lib/modules/jwtsso/useDestroyJwtSsoKey.ts","../lib/modules/jwtsso/useListJwtSsoKeys.ts","../lib/modules/jwtsso/useUpdateJwtSsoKey.ts","../lib/modules/policies/useCurrentPolicy.ts","../lib/main.ts"],"sourcesContent":["import * as React from \"react\";\nimport { jsx as _jsx, jsxs as _jsxs } from \"react/jsx-runtime\";\nconst SvgExternalLink = (props) => /* @__PURE__ */ _jsxs(\"svg\", {\n\txmlns: \"http://www.w3.org/2000/svg\",\n\tviewBox: \"0 0 24 24\",\n\tfill: \"none\",\n\tstroke: \"currentColor\",\n\tstrokeWidth: 2,\n\tstrokeLinecap: \"round\",\n\tstrokeLinejoin: \"round\",\n\twidth: 14,\n\theight: 14,\n\t\"aria-hidden\": \"true\",\n\t...props,\n\tchildren: [\n\t\t/* @__PURE__ */ _jsx(\"path\", { d: \"M15 3h6v6\" }),\n\t\t/* @__PURE__ */ _jsx(\"path\", { d: \"M10 14 21 3\" }),\n\t\t/* @__PURE__ */ _jsx(\"path\", { d: \"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" })\n\t]\n});\nexport default SvgExternalLink;\n",".root {\n composes: focusRing from '@/styles/focus.module.css';\n position: absolute;\n right: 10px;\n display: flex;\n align-items: center;\n gap: 4px;\n text-decoration: none;\n color: var(--text-color-base);\n}\n\n.root:hover {\n text-decoration: underline;\n}\n\n.root:visited {\n color: #0e0c26;\n color: var(--text-color-base);\n}\n","import type { ReactNode } from 'react'\nimport IconExternalLink from '@/icons/external-link.svg?react'\nimport styles from './ExternalLink.module.css'\n\nexport interface ExternalLinkProps {\n href: string\n children?: ReactNode\n}\n\nconst ExternalLink = ({ href, children }: ExternalLinkProps) => (\n <a className={styles.root} href={href} target='_blank' rel='noopener noreferrer'>\n {children}\n <IconExternalLink />\n </a>\n)\n\nexport default ExternalLink\n",".root {\n color: #fff;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n text-align: center;\n background-size: cover;\n background-position: center;\n padding: 16px;\n border-radius: 50%;\n width: 1.5rem;\n height: 1.5rem;\n border: 1px solid #ddd;\n flex: 0 0 auto;\n white-space: nowrap;\n}\n","import clsx from 'clsx'\nimport styles from './UserIcon.module.css'\n\nexport interface UserIconUser {\n name?: string\n picture?: string\n colour?: string\n}\n\nexport interface UserIconProps {\n user?: UserIconUser\n className?: string\n}\n\nconst UserIcon = ({ user, className }: UserIconProps) => {\n const initials = (): string => {\n if (!user?.name || user.picture) return ''\n\n return user.name\n .trim()\n .split(/\\s+/)\n .map((part) => part.toUpperCase().charAt(0))\n .join('')\n .slice(0, 2)\n }\n\n if (!user) return null\n\n return (\n <div\n className={clsx(styles.root, className)}\n title={user.name}\n style={{\n backgroundImage: user.picture ? `url(${user.picture || ''})` : undefined,\n backgroundColor: user.colour,\n }}\n >\n <span>{initials()}</span>\n </div>\n )\n}\n\nexport default UserIcon\n","import * as React from \"react\";\nimport { jsx as _jsx, jsxs as _jsxs } from \"react/jsx-runtime\";\nconst SvgPhone = (props) => /* @__PURE__ */ _jsxs(\"svg\", {\n\twidth: 24,\n\theight: 24,\n\tviewBox: \"0 0 24 24\",\n\tfill: \"none\",\n\txmlns: \"http://www.w3.org/2000/svg\",\n\t...props,\n\tchildren: [/* @__PURE__ */ _jsx(\"g\", {\n\t\tclipPath: \"url(#clip0_60797_8824)\",\n\t\tchildren: /* @__PURE__ */ _jsx(\"path\", {\n\t\t\tfillRule: \"evenodd\",\n\t\t\tclipRule: \"evenodd\",\n\t\t\td: \"M20.9964 12.5895C21.1528 12.4331 21.2406 12.2211 21.2406 12C21.2406 11.7872 21.1593 11.5829 21.0138 11.4285C18.518 9.23023 15.3059 8.01707 11.9793 8.01707C8.65261 8.01707 5.44055 9.23023 2.94474 11.4285C2.7993 11.5829 2.71797 11.7872 2.71797 12C2.71797 12.2211 2.8058 12.4331 2.96214 12.5895L5.07653 14.7039L8.20945 13.3612L7.76772 11.5943C7.6415 11.0894 7.92363 10.5721 8.41645 10.4048C10.7269 9.62055 13.2316 9.62055 15.5421 10.4048C16.0349 10.5721 16.3171 11.0894 16.1908 11.5943L15.7491 13.3612L18.882 14.7039L20.9964 12.5895ZM23.2406 12C23.2406 12.7515 22.942 13.4723 22.4106 14.0037L19.8175 16.5968C19.5284 16.8859 19.0923 16.9699 18.7165 16.8088L14.1785 14.864C13.7274 14.6707 13.4832 14.1785 13.6023 13.7023L14.0159 12.0478C12.6758 11.7395 11.2828 11.7395 9.94266 12.0478L10.3563 13.7023C10.4753 14.1785 10.2312 14.6707 9.78006 14.864L5.24208 16.8088C4.86624 16.9699 4.43019 16.8859 4.14106 16.5968L1.54792 14.0037C1.01651 13.4723 0.717975 12.7515 0.717976 12C0.717975 11.2485 1.01651 10.5277 1.54792 9.99633C1.56223 9.98202 1.57697 9.96815 1.59212 9.95474C4.45744 7.41772 8.1522 6.01707 11.9793 6.01707C15.8064 6.01707 19.5011 7.41772 22.3664 9.95474C22.3816 9.96815 22.3963 9.98202 22.4106 9.99633C22.942 10.5277 23.2406 11.2485 23.2406 12Z\",\n\t\t\tfill: \"currentColor\"\n\t\t})\n\t}), /* @__PURE__ */ _jsx(\"defs\", { children: /* @__PURE__ */ _jsx(\"clipPath\", {\n\t\tid: \"clip0_60797_8824\",\n\t\tchildren: /* @__PURE__ */ _jsx(\"rect\", {\n\t\t\twidth: 24,\n\t\t\theight: 24,\n\t\t\tfill: \"white\"\n\t\t})\n\t}) })]\n});\nexport default SvgPhone;\n",".root {\n height: 40px;\n border-radius: 62px;\n background-color: #b91c1c;\n color: #ffffff;\n padding: 4px 20px;\n cursor: pointer;\n opacity: 1;\n}\n\n.root:hover {\n background-color: #dc2626;\n}\n\n.visuallyHidden {\n composes: visuallyHidden from '@/styles/visuallyHidden.module.css';\n}\n","import type { ComponentPropsWithoutRef } from 'react'\nimport clsx from 'clsx'\nimport Button from '@/components/Button'\nimport PhoneIcon from '@/icons/phone.svg?react'\nimport { useTranslation } from '@/i18n'\nimport styles from './CancelButton.module.css'\n\nexport interface CancelButtonProps extends ComponentPropsWithoutRef<'button'> {}\n\nconst CancelButton = ({ type = 'button', className, children, ...props }: CancelButtonProps) => {\n const { t } = useTranslation()\n\n return (\n <Button type={type} className={clsx(styles.root, className)} {...props}>\n {children ?? (\n <>\n <PhoneIcon />\n <span className={styles.visuallyHidden}>{t('Cancel')}</span>\n </>\n )}\n </Button>\n )\n}\n\nexport default CancelButton\n",".root {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 10px;\n padding: 10px;\n height: 100%;\n text-align: center;\n}\n\n.heading {\n font-size: 1.5rem;\n font-weight: 700;\n}\n\n.message {\n font-size: 1.2rem;\n}\n","import type { ReactNode } from 'react'\nimport { useTranslation } from '@/i18n'\nimport styles from './BlockingError.module.css'\n\nexport interface BlockingErrorProps {\n heading?: string\n message?: string\n children?: ReactNode\n}\n\nconst BlockingError = ({ heading, message, children }: BlockingErrorProps) => {\n const { t } = useTranslation()\n\n return (\n <div className={styles.root}>\n <p className={styles.heading}>{heading ?? t('Sorry, something went wrong.')}</p>\n {message && <p className={styles.message}>{message}</p>}\n {children}\n </div>\n )\n}\n\nexport default BlockingError\n","import { createContext, use, type ReactNode } from 'react'\nimport type CobrowseAPI from 'cobrowse-agent-sdk'\n\nconst CobrowseContext = createContext<CobrowseAPI | null>(null)\n\nexport interface CobrowseProviderProps {\n cobrowse: CobrowseAPI\n children?: ReactNode\n}\n\nexport const CobrowseProvider = ({ cobrowse, children }: CobrowseProviderProps) => (\n <CobrowseContext.Provider value={cobrowse}>{children}</CobrowseContext.Provider>\n)\n\nexport const useCobrowseValue = () => use(CobrowseContext)\n\nexport const useCobrowse = () => {\n const cobrowse = useCobrowseValue()\n\n if (!cobrowse) {\n throw new Error('CobrowseProvider is required to use this component.')\n }\n\n return cobrowse\n}\n\nexport default CobrowseProvider\n","import { createContext, use, useEffect, useState } from 'react'\nimport type { RemoteContext as CobrowseRemoteContext } from 'cobrowse-agent-sdk'\nimport { useCobrowseValue } from '@/components/CobrowseProvider'\n\nconst RemoteContext = createContext<CobrowseRemoteContext | null>(null)\n\nexport function useRemoteContext(\n target?: HTMLIFrameElement | Window | null,\n): CobrowseRemoteContext | null {\n const providedRemoteContext = use(RemoteContext)\n const cobrowse = useCobrowseValue()\n const [remoteContext, setRemoteContext] = useState<CobrowseRemoteContext | null>(null)\n\n useEffect(() => {\n if (target === undefined) {\n return\n }\n\n if (!target || !cobrowse) {\n return\n }\n\n let cancelled = false\n let attachedContext: CobrowseRemoteContext | null = null\n\n const attachContext = async () => {\n const context = await cobrowse.attachContext(target)\n\n if (!context) {\n setRemoteContext(null)\n\n return\n }\n\n attachedContext = context\n\n if (cancelled) {\n attachedContext.destroy()\n attachedContext = null\n\n return\n }\n\n setRemoteContext(attachedContext)\n }\n\n void attachContext()\n\n return () => {\n cancelled = true\n setRemoteContext(null)\n\n if (attachedContext) {\n attachedContext.destroy()\n attachedContext = null\n }\n }\n }, [cobrowse, target])\n\n if (target === undefined) {\n return providedRemoteContext\n }\n\n if (!target || !cobrowse) {\n return null\n }\n\n return remoteContext\n}\n\nexport default RemoteContext\n","import { useCallback, useEffect, useRef } from 'react'\n\nconst useStableCallback = <TArgs extends unknown[], TResult>(\n callback?: (...args: TArgs) => TResult,\n) => {\n const callbackRef = useRef(callback)\n\n useEffect(() => {\n callbackRef.current = callback\n }, [callback])\n\n return useCallback((...args: TArgs): TResult | undefined => callbackRef.current?.(...args), [])\n}\n\nexport default useStableCallback\n","import {\n useCallback,\n useEffect,\n useState,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from 'react'\nimport RemoteContextProvider, { useRemoteContext } from './RemoteContext'\nimport useStableCallback from '@/hooks/useStableCallback'\n\ntype IframeProps = Omit<ComponentPropsWithoutRef<'iframe'>, 'frameBorder' | 'onError' | 'src'>\n\nexport interface FrameProps extends IframeProps {\n src: string\n children?: ReactNode\n onError?: (error: unknown) => void\n}\n\nconst Frame = ({\n src,\n onError,\n title = 'Cobrowse',\n width = '100%',\n height = '100%',\n style,\n children,\n ...props\n}: FrameProps) => {\n const [iframe, setIframe] = useState<HTMLIFrameElement | null>(null)\n const onErrorCallback = useStableCallback(onError)\n const remoteContext = useRemoteContext(iframe)\n\n const handleIframeRef = useCallback((element: HTMLIFrameElement | null) => {\n setIframe(element)\n }, [])\n\n useEffect(() => {\n if (!remoteContext) {\n return\n }\n\n const handleError = (error: unknown) => {\n onErrorCallback(error)\n }\n\n remoteContext.on('error', handleError)\n\n return () => {\n remoteContext.off('error', handleError)\n }\n }, [remoteContext, onErrorCallback])\n\n return (\n <RemoteContextProvider.Provider value={remoteContext}>\n <iframe\n ref={handleIframeRef}\n title={title}\n width={width}\n height={height}\n src={src}\n style={{ border: 0, ...style }}\n {...props}\n />\n {children}\n </RemoteContextProvider.Provider>\n )\n}\n\nexport { useRemoteContext }\nexport default Frame\n","import { useEffect, useState } from 'react'\nimport { useCobrowse } from '@/components/CobrowseProvider'\n\nconst isAbortError = (error: unknown): boolean =>\n error instanceof Error && error.name === 'AbortError'\n\n/**\n * Provides the account's trusted embedding domains.\n * When the CobrowseProvider instance has no token the account settings cannot\n * be fetched, so the origins stay null.\n */\nconst useTrustedEmbeddingOrigins = () => {\n const cobrowse = useCobrowse()\n const [origins, setOrigins] = useState<string[] | null>(null)\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState<Error | null>(null)\n\n useEffect(() => {\n // oxlint-disable-next-line react/set-state-in-effect -- clears the previous instance's result before refetching\n setOrigins(null)\n setError(null)\n\n if (!cobrowse.token) {\n return\n }\n\n const abortController = new AbortController()\n\n const runEffect = async () => {\n setLoading(true)\n\n try {\n const trusted = await cobrowse.origins.trusted({\n request: { signal: abortController.signal },\n })\n\n setOrigins(trusted.origins)\n } catch (error) {\n if (isAbortError(error)) return\n\n setError(error instanceof Error ? error : new Error(String(error)))\n } finally {\n setLoading(false)\n }\n }\n\n void runEffect()\n\n return () => {\n abortController.abort()\n }\n }, [cobrowse])\n\n return {\n origins,\n loading,\n error,\n }\n}\n\nexport default useTrustedEmbeddingOrigins\n","import { useEffect } from 'react'\nimport type { RemoteContext, RemoteContextRelayOptions } from 'cobrowse-agent-sdk'\nimport { useRemoteContext } from '@/components/Frame'\nimport useTrustedEmbeddingOrigins from '@/hooks/useTrustedEmbeddingOrigins'\n\nexport interface RemoteContextRelayProps {\n /**\n * When provided, relays to the given context. Otherwise,\n * it's resolved from the RemoteContextProvider.\n */\n remoteContext?: RemoteContext\n /**\n * Origins allowed to communicate with the attached context via the relay.\n * Nothing is relayed to or from any other origin. Defaults to the account's\n * trusted embedding domains (see useTrustedEmbeddingOrigins), which requires\n * the CobrowseProvider instance to be authorized. Pass a reference-stable\n * array, a new identity recreates the relay.\n */\n trustedOrigins?: RemoteContextRelayOptions['trustedOrigins']\n /** The window to relay to. Defaults to the opener or parent of the current window. */\n destination?: Window\n}\n\n/**\n * Relays the enclosing Frame's remote context to a host window, so a page\n * embedding this application in an iframe can attach its own context to that\n * iframe and use the full RemoteContext API. Must be rendered inside a Frame.\n *\n * ```tsx\n * <Frame src={sessionUrl}>\n * <RemoteContextRelay trustedOrigins={['https://host.example.com']} />\n * </Frame>\n * ```\n */\nconst RemoteContextRelay = (props: RemoteContextRelayProps) => {\n const { remoteContext: providedRemoteContext, trustedOrigins, destination } = props\n const resolvedRemoteContext = useRemoteContext()\n const remoteContext = providedRemoteContext ?? resolvedRemoteContext\n const { origins: accountOrigins, error } = useTrustedEmbeddingOrigins()\n const resolvedOrigins = trustedOrigins ?? accountOrigins\n\n useEffect(() => {\n if (error && !trustedOrigins) {\n // oxlint-disable-next-line no-console -- without this the relay silently never starts; there is no UI to surface the misconfiguration\n console.warn(\n 'RemoteContextRelay: failed to load the account trusted embedding domains, nothing will be relayed',\n error,\n )\n }\n }, [error, trustedOrigins])\n\n useEffect(() => {\n if (!remoteContext) {\n return\n }\n\n if (!resolvedOrigins?.length) {\n return\n }\n\n // oxlint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- window.opener is typed as any but is a Window or null at runtime\n const opener = window.opener as Window | null\n const resolvedDestination = destination ?? opener ?? window.parent\n\n if (resolvedDestination === window) {\n return\n }\n\n const relay = remoteContext.relay(resolvedDestination, {\n trustedOrigins: resolvedOrigins,\n })\n\n return () => {\n relay.destroy()\n }\n }, [remoteContext, destination, resolvedOrigins])\n\n return null\n}\n\nexport default RemoteContextRelay\n","import { useEffect, useRef } from 'react'\nimport type { RemoteContext, Session } from 'cobrowse-agent-sdk'\nimport useStableCallback from '@/hooks/useStableCallback'\n\nexport interface SessionEventHandlers {\n /** Called when a session is loaded into the context. */\n onLoaded?: (session: Session) => void\n /** Called for every session update. */\n onUpdated?: (session: Session) => void\n /** Called once per session, when it becomes active. */\n onActivated?: (session: Session) => void\n /** Called once per session, when it ends. */\n onEnded?: (session: Session) => void\n}\n\n/**\n * Observes the sessions of a remote context, adding activated/ended edges on top\n * of the context's own load/update events. Both are raised at most once per\n * session: a session already active when it is first seen counts as activated\n * before this context saw it, so `onActivated` is not called for it.\n */\nconst useSessionEvents = (\n remoteContext: RemoteContext | null,\n { onLoaded, onUpdated, onActivated, onEnded }: SessionEventHandlers,\n) => {\n const onLoadedCallback = useStableCallback(onLoaded)\n const onUpdatedCallback = useStableCallback(onUpdated)\n const onActivatedCallback = useStableCallback(onActivated)\n const onEndedCallback = useStableCallback(onEnded)\n const sessionActivatedRef = useRef(false)\n const sessionEndedRef = useRef(false)\n\n useEffect(() => {\n if (!remoteContext) {\n sessionActivatedRef.current = false\n sessionEndedRef.current = false\n\n return\n }\n\n const handleSessionLoaded = (session: Session) => {\n sessionActivatedRef.current = session.isActive()\n sessionEndedRef.current = false\n onLoadedCallback(session)\n }\n\n const handleSessionUpdated = (session: Session) => {\n onUpdatedCallback(session)\n\n if (session.isActive() && !sessionActivatedRef.current) {\n sessionActivatedRef.current = true\n onActivatedCallback(session)\n }\n\n if (session.isEnded() && !sessionEndedRef.current) {\n sessionEndedRef.current = true\n onEndedCallback(session)\n }\n }\n\n remoteContext.on('session.loaded', handleSessionLoaded)\n remoteContext.on('session.updated', handleSessionUpdated)\n\n return () => {\n remoteContext.off('session.loaded', handleSessionLoaded)\n remoteContext.off('session.updated', handleSessionUpdated)\n sessionActivatedRef.current = false\n sessionEndedRef.current = false\n }\n }, [onActivatedCallback, onEndedCallback, onLoadedCallback, onUpdatedCallback, remoteContext])\n}\n\nexport default useSessionEvents\n","import { useEffect, useState } from 'react'\nimport { RemoteContext, type Session } from 'cobrowse-agent-sdk'\n\nconst isRemoteContext = (source: RemoteContext | Session): source is RemoteContext =>\n source instanceof RemoteContext\n\nconst hasSessionProperty = (target: Session, property: PropertyKey): property is keyof Session =>\n property in target\n\nconst createReactiveSession = (session: Session | null) => {\n if (!session) {\n return null\n }\n\n return new Proxy(session, {\n get: (target, property) =>\n hasSessionProperty(target, property) ? target[property] : undefined,\n })\n}\n\nconst useSession = (source: RemoteContext | Session | null) => {\n const remoteContext = source && isRemoteContext(source) ? source : null\n const sessionSource = source && !isRemoteContext(source) ? source : null\n const [sessionState, setSessionState] = useState(sessionSource)\n\n useEffect(() => {\n if (!remoteContext) {\n return\n }\n\n const handleSessionChange = (session: Session) => {\n setSessionState(createReactiveSession(session))\n }\n\n remoteContext.on('session.loaded', handleSessionChange)\n remoteContext.on('session.updated', handleSessionChange)\n\n return () => {\n remoteContext.off('session.loaded', handleSessionChange)\n remoteContext.off('session.updated', handleSessionChange)\n\n setSessionState(null)\n }\n }, [remoteContext])\n\n useEffect(() => {\n if (!sessionSource) {\n return\n }\n\n const handleSessionChange = () => {\n setSessionState(createReactiveSession(sessionSource))\n }\n\n sessionSource.on('updated', handleSessionChange)\n sessionSource.on('ended', handleSessionChange)\n\n return () => {\n sessionSource.off('updated', handleSessionChange)\n sessionSource.off('ended', handleSessionChange)\n\n setSessionState(null)\n }\n }, [sessionSource])\n\n return sessionState ?? sessionSource\n}\n\nexport default useSession\n",".root {\n position: absolute;\n inset: 0;\n z-index: 1;\n pointer-events: none;\n}\n\n.content {\n display: contents;\n pointer-events: auto;\n}\n","import { useRemoteContext } from '@/components/Frame'\nimport useSession from '@/hooks/useSession'\nimport styles from './Overlay.module.css'\nimport type { SessionEmbedOverlayProps } from './types'\n\nconst Overlay = ({ state, children }: SessionEmbedOverlayProps) => {\n const remoteContext = useRemoteContext()\n const session = useSession(remoteContext)\n const sessionState = session?.state\n\n const shouldRender = state === 'loading' ? sessionState === undefined : sessionState === state\n\n if (!shouldRender) {\n return null\n }\n\n return (\n <div className={styles.root}>\n <div className={styles.content}>{children}</div>\n </div>\n )\n}\n\nexport default Overlay\n","import { useMemo } from 'react'\nimport { useCobrowse } from '@/components/CobrowseProvider'\nimport type { SessionEmbedProps } from './types'\nimport { useTranslation } from '@/i18n'\n\ninterface UseSessionUrlProps {\n id: string\n endAction?: SessionEmbedProps['endAction']\n popout?: SessionEmbedProps['popout']\n agentTools?: SessionEmbedProps['agentTools']\n deviceControls?: SessionEmbedProps['deviceControls']\n sessionDetails?: SessionEmbedProps['sessionDetails']\n messages?: SessionEmbedProps['messages']\n}\n\nexport const useSessionUrl = ({\n id,\n endAction,\n popout,\n agentTools,\n deviceControls,\n sessionDetails,\n messages,\n}: UseSessionUrlProps) => {\n const cobrowse = useCobrowse()\n const {\n i18n: { language },\n } = useTranslation()\n\n return useMemo(() => {\n const paramEntries = Object.entries({\n end_action: endAction,\n popout,\n agent_tools: agentTools,\n device_controls: deviceControls,\n session_details: sessionDetails,\n messages,\n token_source: 'postMessage',\n lng: language,\n }).flatMap(([name, value]) => (value === undefined ? [] : [[name, value]]))\n\n const query = new URLSearchParams(paramEntries)\n\n return `${cobrowse.api}/session/${encodeURIComponent(id)}?${query.toString()}`\n }, [\n cobrowse.api,\n id,\n endAction,\n popout,\n agentTools,\n deviceControls,\n sessionDetails,\n messages,\n language,\n ])\n}\n",".root {\n position: relative;\n width: 100%;\n height: 100%;\n}\n","import Frame, { useRemoteContext } from '@/components/Frame'\nimport useSessionEvents from '@/hooks/useSessionEvents'\nimport { useTranslation } from '@/i18n'\nimport Overlay from './Overlay'\nimport type { SessionEmbedProps } from './types'\nimport { useSessionUrl } from './useSessionUrl'\nimport styles from './SessionEmbed.module.css'\n\nexport type {\n SessionEmbedOverlay,\n SessionEmbedOverlayProps,\n SessionEmbedOverlayState,\n SessionEmbedProps,\n} from './types'\n\ntype SessionEmbedComponent = typeof SessionEmbedBase & {\n Overlay: typeof Overlay\n}\n\nconst SessionEventObserver = (\n handlers: Pick<SessionEmbedProps, 'onLoaded' | 'onUpdated' | 'onActivated' | 'onEnded'>,\n) => {\n useSessionEvents(useRemoteContext(), handlers)\n return null\n}\n\nconst SessionEmbedBase = ({\n id,\n endAction,\n popout,\n agentTools,\n deviceControls,\n sessionDetails,\n messages,\n onError,\n onLoaded,\n onUpdated,\n onActivated,\n onEnded,\n title,\n className,\n children,\n ...props\n}: SessionEmbedProps) => {\n const { t } = useTranslation()\n const url = useSessionUrl({\n id,\n endAction,\n popout,\n agentTools,\n deviceControls,\n sessionDetails,\n messages,\n })\n\n return (\n <div className={styles.root}>\n <Frame\n src={url}\n title={title ?? t('Cobrowse session')}\n className={className}\n onError={onError}\n {...props}\n >\n <SessionEventObserver\n onLoaded={onLoaded}\n onUpdated={onUpdated}\n onActivated={onActivated}\n onEnded={onEnded}\n />\n {children}\n </Frame>\n </div>\n )\n}\n\nconst SessionEmbed: SessionEmbedComponent = Object.assign(SessionEmbedBase, {\n Overlay,\n})\nexport default SessionEmbed\n","import { useCallback, useEffect, useRef } from 'react'\nimport type { Device, Session } from 'cobrowse-agent-sdk'\nimport useStableCallback from '@/hooks/useStableCallback'\nimport { useCobrowse } from '@/components/CobrowseProvider'\n\nexport const MAX_PUSH_ATTEMPTS = 5\nexport const PUSH_RETRY_MS = 4000\nexport const ERROR_PUSH_ERROR = 'push_error'\nexport const ERROR_PUSH_ATTEMPT_LIMIT_REACHED = 'push_attempt_limit_reached'\nexport const ERROR_DEVICE_NOT_FOUND = 'device_not_found'\nexport const ERROR_SESSION_NOT_FOUND = 'session_not_found'\nexport const ERROR_SESSION_ERROR = 'session_error'\n\nconst isAbortError = (error: unknown): boolean => {\n if (!(error instanceof Error)) {\n return false\n }\n\n return error.name === 'AbortError'\n}\n\nexport interface UseConnectDeviceOptions {\n deviceId: string\n onConnectAttempt?: (attempt: number) => void\n onConnected?: (session: Session) => void\n onCancelled?: (session: Session) => void\n onEnded?: (session: Session) => void\n onError?: (error: unknown) => void\n maxPushAttempts?: number\n pushRetryMs?: number\n}\n\nconst useConnectDevice = ({\n deviceId,\n onConnectAttempt,\n onConnected,\n onCancelled,\n onEnded,\n onError,\n maxPushAttempts = MAX_PUSH_ATTEMPTS,\n pushRetryMs = PUSH_RETRY_MS,\n}: UseConnectDeviceOptions) => {\n const cobrowse = useCobrowse()\n const deviceRef = useRef<Device>(null)\n const sessionRef = useRef<Session>(null)\n const sessionConnectedRef = useRef(false)\n const sessionEndedRef = useRef(false)\n const pushTimerRef = useRef(0)\n const onConnectAttemptCallback = useStableCallback(onConnectAttempt)\n const onConnectedCallback = useStableCallback(onConnected)\n const onCancelledCallback = useStableCallback(onCancelled)\n const onEndedCallback = useStableCallback(onEnded)\n const onErrorCallback = useStableCallback(onError)\n\n const stopPush = useCallback(() => {\n clearTimeout(pushTimerRef.current)\n }, [])\n\n const handleSessionUpdated = useCallback(\n (session: Session) => {\n if (!['pending', 'ended'].includes(session.state) && !sessionConnectedRef.current) {\n stopPush()\n onConnectedCallback(session)\n sessionConnectedRef.current = true\n }\n },\n [onConnectedCallback, stopPush],\n )\n\n const handleSessionEnded = useCallback(\n (session: Session) => {\n if (!sessionEndedRef.current) {\n onEndedCallback(session)\n sessionEndedRef.current = true\n void sessionRef.current?.end()\n }\n },\n [onEndedCallback],\n )\n\n const triggerPushError = useCallback(\n (error: unknown) => {\n if (isAbortError(error)) {\n return\n }\n\n if (error instanceof Error) {\n onErrorCallback({ id: ERROR_PUSH_ERROR, message: error.message })\n } else {\n onErrorCallback(error)\n }\n },\n [onErrorCallback],\n )\n\n const sendPush = useCallback(\n async function send(attempt = 1, abortController: AbortController) {\n onConnectAttemptCallback(attempt)\n\n if (attempt >= maxPushAttempts) {\n triggerPushError({\n id: ERROR_PUSH_ATTEMPT_LIMIT_REACHED,\n message: 'Push attempt limit reached.',\n })\n\n return\n }\n\n if (!deviceRef.current) {\n triggerPushError({ id: ERROR_DEVICE_NOT_FOUND, message: 'Device not found.' })\n\n return\n }\n\n if (!sessionRef.current) {\n triggerPushError({ id: ERROR_SESSION_NOT_FOUND, message: 'Session not found.' })\n\n return\n }\n\n try {\n await deviceRef.current.notify(\n { session: sessionRef.current, attempt },\n { request: { signal: abortController.signal } },\n )\n } catch (error) {\n triggerPushError(error)\n }\n\n pushTimerRef.current = setTimeout(() => {\n void send(attempt + 1, abortController)\n }, pushRetryMs)\n },\n [maxPushAttempts, onConnectAttemptCallback, pushRetryMs, triggerPushError],\n )\n\n const createSession = useCallback(\n async (abortController: AbortController) => {\n const request = { signal: abortController.signal }\n\n try {\n deviceRef.current = null\n sessionRef.current = null\n sessionConnectedRef.current = false\n sessionEndedRef.current = false\n\n const [region, device] = await Promise.all([\n cobrowse.regions.closest({ request }),\n cobrowse.devices.get(deviceId, { request }),\n ])\n\n deviceRef.current = device\n\n const session = await cobrowse.sessions.create(\n {\n custom_data: device.custom_data,\n region: region.id,\n agent: 'me',\n },\n { request },\n )\n\n sessionRef.current = session\n\n session.on('updated', handleSessionUpdated)\n session.on('ended', handleSessionEnded)\n\n await session.subscribe()\n } catch (error) {\n if (isAbortError(error)) {\n return\n }\n\n if (error instanceof Error) {\n onErrorCallback({ id: ERROR_SESSION_ERROR, message: error.message })\n } else {\n onErrorCallback({ id: ERROR_SESSION_ERROR, message: 'The session could not be created.' })\n }\n }\n },\n [cobrowse, deviceId, handleSessionEnded, handleSessionUpdated, onErrorCallback],\n )\n\n const cancel = useCallback(async () => {\n stopPush()\n\n const session = sessionRef.current\n\n if (session) {\n await session.end()\n onCancelledCallback(session)\n }\n }, [onCancelledCallback, stopPush])\n\n useEffect(() => {\n const abortController = new AbortController()\n\n const runEffect = async () => {\n await createSession(abortController)\n\n if (abortController.signal.aborted) {\n return\n }\n\n await sendPush(1, abortController)\n }\n\n void runEffect()\n\n return () => {\n abortController.abort()\n stopPush()\n }\n }, [createSession, sendPush, stopPush])\n\n return { cancel }\n}\n\nexport default useConnectDevice\n",".root {\n display: flex;\n flex-direction: column;\n gap: 10px;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n background: #0e0c26;\n color: white;\n}\n\n.statusMessage {\n font-size: 1.2rem;\n}\n","import { useState, type ReactNode } from 'react'\nimport type { Session } from 'cobrowse-agent-sdk'\nimport clsx from 'clsx'\nimport BaseLoader from '@/components/Loader'\nimport CancelButton, { type CancelButtonProps } from '@/components/CancelButton'\nimport { useTranslation } from '@/i18n'\nimport useConnectDevice, {\n ERROR_DEVICE_NOT_FOUND,\n ERROR_PUSH_ATTEMPT_LIMIT_REACHED,\n ERROR_PUSH_ERROR,\n ERROR_SESSION_ERROR,\n ERROR_SESSION_NOT_FOUND,\n MAX_PUSH_ATTEMPTS,\n PUSH_RETRY_MS,\n} from './useConnectDevice'\nimport styles from './ConnectDevice.module.css'\n\nexport {\n ERROR_DEVICE_NOT_FOUND,\n ERROR_PUSH_ATTEMPT_LIMIT_REACHED,\n ERROR_PUSH_ERROR,\n ERROR_SESSION_ERROR,\n ERROR_SESSION_NOT_FOUND,\n MAX_PUSH_ATTEMPTS,\n PUSH_RETRY_MS,\n}\n\nexport interface ConnectDeviceStatusMessageProps {\n attempt: number\n maxPushAttempts?: number\n className?: string\n}\n\nexport interface ConnectDeviceLoaderProps {\n attempt: number\n maxPushAttempts?: number\n}\n\nexport interface ConnectDeviceProps {\n deviceId: string\n onConnectAttempt?: (attempt: number) => void\n onConnected?: (session: Session) => void\n onCancelled?: (session: Session) => void\n onEnded?: (session: Session) => void\n onError?: (error: unknown) => void\n maxPushAttempts?: number\n pushRetryMs?: number\n className?: string\n children: (attempt: number, cancel: () => void) => ReactNode\n}\n\nconst StatusMessage = ({\n attempt,\n maxPushAttempts = MAX_PUSH_ATTEMPTS,\n className,\n}: ConnectDeviceStatusMessageProps) => {\n const { t } = useTranslation()\n let message = t('Contacting device')\n\n if (attempt >= maxPushAttempts) {\n message = t('Device not responding')\n } else if (attempt >= maxPushAttempts - 1) {\n message = t('Trying once more')\n } else if (attempt > 2) {\n message = t('Retrying connection')\n }\n\n return <div className={clsx(styles.statusMessage, className)}>{message}</div>\n}\n\nconst Loader = ({ attempt, maxPushAttempts = MAX_PUSH_ATTEMPTS }: ConnectDeviceLoaderProps) => {\n if (attempt >= maxPushAttempts) {\n return null\n }\n\n return <BaseLoader />\n}\n\ntype ConnectDeviceComponent = ((props: ConnectDeviceProps) => ReactNode) & {\n StatusMessage: (props: ConnectDeviceStatusMessageProps) => ReactNode\n Loader: (props: ConnectDeviceLoaderProps) => ReactNode\n CancelButton: (props: CancelButtonProps) => ReactNode\n}\n\nconst ConnectDeviceBase = ({\n deviceId,\n onConnectAttempt,\n onConnected,\n onCancelled,\n onEnded,\n onError,\n maxPushAttempts = MAX_PUSH_ATTEMPTS,\n pushRetryMs = PUSH_RETRY_MS,\n className,\n children,\n}: ConnectDeviceProps) => {\n const [attempt, setAttempt] = useState(1)\n\n const handleConnectAttempt = (currentAttempt: number) => {\n setAttempt(currentAttempt)\n onConnectAttempt?.(currentAttempt)\n }\n\n const { cancel } = useConnectDevice({\n deviceId,\n onConnectAttempt: handleConnectAttempt,\n onConnected,\n onCancelled,\n onEnded,\n onError,\n maxPushAttempts,\n pushRetryMs,\n })\n\n const handleCancel = () => {\n void cancel()\n }\n\n return <div className={clsx(styles.root, className)}>{children(attempt, handleCancel)}</div>\n}\n\nconst ConnectDevice: ConnectDeviceComponent = Object.assign(ConnectDeviceBase, {\n StatusMessage,\n Loader,\n CancelButton,\n})\n\nexport default ConnectDevice\n","import { createContext, use } from 'react'\nimport type { RatingUpdate, RatingValue } from 'cobrowse-agent-sdk'\n\nexport type RatingResult = RatingUpdate\n\nexport interface RatingContextValue {\n rating: RatingValue | null\n feedback: string[]\n comment: string\n complete: boolean\n feedbackThreshold: number\n setRating: (score: RatingValue, commit?: boolean) => void\n toggleReason: (value: string) => void\n setComment: (value: string) => void\n submit: () => void\n}\n\nconst RatingContext = createContext<RatingContextValue | null>(null)\n\nexport const useRatingContext = (): RatingContextValue => {\n const context = use(RatingContext)\n\n if (!context) {\n throw new Error('Rating.* components must be rendered within a <Rating>.')\n }\n\n return context\n}\n\nexport default RatingContext\n","import * as React from \"react\";\nimport { jsx as _jsx, jsxs as _jsxs } from \"react/jsx-runtime\";\nconst SvgStar = (props) => /* @__PURE__ */ _jsxs(\"svg\", {\n\twidth: 24,\n\theight: 24,\n\tviewBox: \"0 0 24 24\",\n\tfill: \"none\",\n\txmlns: \"http://www.w3.org/2000/svg\",\n\t...props,\n\tchildren: [/* @__PURE__ */ _jsx(\"path\", {\n\t\td: \"M12.0001 17.748L5.82811 20.993L7.00711 14.12L2.00711 9.253L8.90711 8.253L11.9931 2L15.0791 8.253L21.9791 9.253L16.9791 14.12L18.1581 20.993L12.0001 17.748Z\",\n\t\tfill: \"currentColor\"\n\t}), /* @__PURE__ */ _jsx(\"path\", {\n\t\tclassName: \"rating-star-outline\",\n\t\tfillRule: \"evenodd\",\n\t\tclipRule: \"evenodd\",\n\t\td: \"M11.9931 1C12.3738 1 12.7214 1.2161 12.8898 1.55744L15.7431 7.33878L22.1225 8.26334C22.4994 8.31796 22.8126 8.58192 22.9302 8.94414C23.0478 9.30635 22.9495 9.70394 22.6766 9.96957L18.0537 14.4695L19.1437 20.8239C19.2081 21.1993 19.0537 21.5786 18.7455 21.8023C18.4373 22.026 18.0288 22.0552 17.6919 21.8777L11.9996 18.8781L6.29347 21.8781C5.95655 22.0553 5.54828 22.0258 5.24032 21.802C4.93237 21.5783 4.77815 21.1991 4.84251 20.8239L5.93254 14.4695L1.3096 9.96957C1.0367 9.70394 0.938377 9.30635 1.056 8.94414C1.17363 8.58192 1.48678 8.31796 1.86368 8.26334L8.24315 7.33878L11.0964 1.55744C11.2648 1.2161 11.6125 1 11.9931 1ZM11.9931 4.25957L9.80385 8.69556C9.65813 8.99083 9.3764 9.19543 9.05054 9.24266L4.15852 9.95165L7.70462 13.4034C7.94065 13.6332 8.0484 13.9644 7.99271 14.2891L7.15631 19.1649L11.5347 16.8629C11.8264 16.7096 12.1748 16.7097 12.4663 16.8633L16.8295 19.1625L15.9935 14.2891C15.9378 13.9644 16.0456 13.6332 16.2816 13.4034L19.8277 9.95165L14.9357 9.24266C14.6098 9.19543 14.3281 8.99083 14.1824 8.69556L11.9931 4.25957Z\",\n\t\tfill: \"currentColor\"\n\t})]\n});\nexport default SvgStar;\n",".root {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.prompt {\n margin: 0;\n text-align: center;\n font-size: 0.75rem;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n color: #040d3c;\n}\n\n.stars {\n display: flex;\n justify-content: center;\n}\n\n.visuallyHidden {\n composes: visuallyHidden from '@/styles/visuallyHidden.module.css';\n}\n\n.star {\n padding: 0 6px;\n line-height: 0;\n color: var(--rating-star-color, #9ca2be);\n cursor: pointer;\n border-radius: 4px;\n transition: color 0.2s ease;\n}\n\n.starInput {\n composes: visuallyHidden from '@/styles/visuallyHidden.module.css';\n}\n\n.star:has(.starInput:focus-visible) {\n outline: none;\n box-shadow: 0 0 0 var(--focus-ring-width, 3px) var(--focus-ring-color, rgba(4, 13, 60, 0.16));\n}\n\n.star svg {\n width: 30px;\n height: 30px;\n}\n\n.star svg path {\n fill: none;\n transition: fill 0.2s ease;\n}\n\n.star svg :global(.rating-star-outline) {\n fill: currentColor;\n}\n\n.star:hover,\n.star:has(~ .star:hover),\n.starActive {\n color: var(--rating-star-active-color, #040d3c);\n}\n\n.star:hover svg path,\n.star:has(~ .star:hover) svg path,\n.starActive svg path {\n fill: currentColor;\n}\n","import { useId, useRef, type ReactNode } from 'react'\nimport clsx from 'clsx'\nimport type { RatingValue } from 'cobrowse-agent-sdk'\nimport StarIcon from '@/icons/star.svg?react'\nimport { useTranslation } from '@/i18n'\nimport { useRatingContext } from './context'\nimport styles from './Stars.module.css'\n\nconst SCORES: RatingValue[] = [1, 2, 3, 4, 5]\n\nexport interface RatingStarsProps {\n label?: ReactNode\n count?: RatingValue\n className?: string\n}\n\nconst Stars = ({ label, count = 5, className }: RatingStarsProps) => {\n const { rating, setRating, complete } = useRatingContext()\n const { t } = useTranslation()\n const promptId = useId()\n const groupName = useId()\n const pointer = useRef(false)\n\n if (complete) {\n return null\n }\n\n const prompt = label === undefined ? t('Rate your experience') : label\n const scores = SCORES.filter((score) => score <= count)\n\n return (\n <div className={clsx(styles.root, className)}>\n {prompt && (\n <p id={promptId} className={styles.prompt}>\n {prompt}\n </p>\n )}\n <div\n className={styles.stars}\n role='radiogroup'\n aria-labelledby={prompt ? promptId : undefined}\n aria-label={prompt ? undefined : t('Rate your experience')}\n >\n {scores.map((score) => (\n <label\n key={score}\n className={clsx(styles.star, rating !== null && rating >= score && styles.starActive)}\n onPointerDown={() => {\n pointer.current = true\n }}\n >\n <input\n type='radio'\n name={groupName}\n value={score}\n checked={rating === score}\n className={styles.starInput}\n // Prevent submitting the value automatically for keyboard-driven users,\n // otherwise they wouldn't be able to move past the 4th star.\n onKeyDown={() => {\n pointer.current = false\n }}\n onChange={() => {\n setRating(score, pointer.current)\n pointer.current = false\n }}\n />\n <StarIcon />\n <span className={styles.visuallyHidden}>\n {t('Rate with a score of {{score}}', { score })}\n </span>\n </label>\n ))}\n </div>\n </div>\n )\n}\n\nexport default Stars\n",".root {\n display: flex;\n align-items: center;\n gap: 8px;\n cursor: pointer;\n}\n\n.checkbox {\n composes: focusRing from '@/styles/focus.module.css';\n appearance: none;\n width: 20px;\n height: 20px;\n flex-shrink: 0;\n border: 1px solid #bcc1d4;\n border-radius: 6px;\n background-repeat: no-repeat;\n background-position: center;\n cursor: pointer;\n transition:\n border-color 0.15s ease,\n background-color 0.15s ease;\n}\n\n.checkbox:hover {\n border-color: #9ca2be;\n}\n\n.checkbox:checked {\n border-color: #040d3c;\n background-color: #040d3c;\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"none\"><path d=\"M3.5 8.5l3 3 6-6\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>');\n}\n","import type { ReactNode } from 'react'\nimport clsx from 'clsx'\nimport { useRatingContext } from './context'\nimport styles from './Reason.module.css'\n\nexport interface RatingReasonProps {\n value: string\n label: ReactNode\n className?: string\n}\n\nconst Reason = ({ value, label, className }: RatingReasonProps) => {\n const { feedback, toggleReason } = useRatingContext()\n\n return (\n <label className={clsx(styles.root, className)}>\n <input\n type='checkbox'\n value={value}\n checked={feedback.includes(value)}\n className={styles.checkbox}\n onChange={() => {\n toggleReason(value)\n }}\n />\n {label}\n </label>\n )\n}\n\nexport default Reason\n",".root {\n composes: focusRing from '@/styles/focus.module.css';\n box-sizing: border-box;\n width: 100%;\n height: 72px;\n padding: 8px 12px;\n resize: none;\n border: 1px solid #d7dae9;\n border-radius: 4px;\n background: #f6f5f7;\n color: var(--text-color-base, #0e0c26);\n font-family: inherit;\n font-size: 0.875rem;\n outline: none;\n}\n\n.root::placeholder {\n color: #72749e;\n}\n","import clsx from 'clsx'\nimport { useTranslation } from '@/i18n'\nimport { useRatingContext } from './context'\nimport styles from './Comment.module.css'\n\nexport interface RatingCommentProps {\n placeholder?: string\n className?: string\n}\n\nconst Comment = ({ placeholder, className }: RatingCommentProps) => {\n const { comment, setComment } = useRatingContext()\n const { t } = useTranslation()\n\n const label = placeholder ?? t('Please describe any issues you experienced')\n\n return (\n <textarea\n className={clsx(styles.root, className)}\n aria-label={label}\n placeholder={label}\n value={comment}\n onChange={(event) => {\n setComment(event.target.value)\n }}\n />\n )\n}\n\nexport default Comment\n",".root {\n display: grid;\n gap: 24px;\n width: 100%;\n max-width: 400px;\n margin: 0 auto;\n}\n\n.reasons {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n","import type { ReactNode } from 'react'\nimport clsx from 'clsx'\nimport { useTranslation } from '@/i18n'\nimport { useRatingContext } from './context'\nimport Reason from './Reason'\nimport Comment from './Comment'\nimport styles from './Feedback.module.css'\n\nexport interface RatingReasonOption {\n value: string\n label: ReactNode\n}\n\nexport interface RatingFeedbackProps {\n reasons?: RatingReasonOption[]\n placeholder?: string\n className?: string\n children?: ReactNode\n}\n\nconst Feedback = ({ reasons, placeholder, className, children }: RatingFeedbackProps) => {\n const { rating, complete, feedbackThreshold } = useRatingContext()\n const { t } = useTranslation()\n\n if (complete || rating === null || rating > feedbackThreshold) {\n return null\n }\n\n const defaultReasons: RatingReasonOption[] = [\n {\n value: 'hard_to_start_session',\n label: t('It was too hard to start the session with the user'),\n },\n { value: 'screen_too_slow', label: t('The screen was too slow to load or update') },\n { value: 'screen_broken', label: t('Parts of the screen did not load correctly') },\n { value: 'tools_not_helpful', label: t('The tools were not helpful or too hard to use') },\n ]\n\n return (\n <div className={clsx(styles.root, className)}>\n {children ?? (\n <>\n <div className={styles.reasons}>\n {(reasons ?? defaultReasons).map((reason) => (\n <Reason key={reason.value} value={reason.value} label={reason.label} />\n ))}\n </div>\n <Comment placeholder={placeholder} />\n </>\n )}\n </div>\n )\n}\n\nexport default Feedback\n",".root {\n align-self: center;\n background: #040d3c;\n color: #ffffff;\n}\n\n.root:active {\n transform: translateY(1px);\n}\n","import type { ReactNode } from 'react'\nimport clsx from 'clsx'\nimport Button from '@/components/Button'\nimport { useTranslation } from '@/i18n'\nimport { useRatingContext } from './context'\nimport styles from './Submit.module.css'\n\nexport interface RatingSubmitProps {\n className?: string\n children?: ReactNode\n}\n\nconst Submit = ({ className, children }: RatingSubmitProps) => {\n const { submit, complete } = useRatingContext()\n const { t } = useTranslation()\n\n if (complete) {\n return null\n }\n\n return (\n <Button className={clsx(styles.root, className)} onClick={submit}>\n {children ?? t('Continue')}\n </Button>\n )\n}\n\nexport default Submit\n",".root {\n text-align: center;\n color: var(--text-color-base, #0e0c26);\n}\n","import type { ReactNode } from 'react'\nimport clsx from 'clsx'\nimport { useTranslation } from '@/i18n'\nimport { useRatingContext } from './context'\nimport styles from './ThankYou.module.css'\n\nexport interface RatingThankYouProps {\n className?: string\n children?: ReactNode\n}\n\nconst ThankYou = ({ className, children }: RatingThankYouProps) => {\n const { complete, rating } = useRatingContext()\n const { t } = useTranslation()\n\n if (!complete || rating === null) {\n return null\n }\n\n return (\n <div role='status' className={clsx(styles.root, className)}>\n {children ?? t('Thank you for your feedback.')}\n </div>\n )\n}\n\nexport default ThankYou\n",".root {\n display: flex;\n flex-direction: column;\n gap: 16px;\n color: var(--text-color-base, #0e0c26);\n}\n","import { useState, type ReactNode } from 'react'\nimport clsx from 'clsx'\nimport type { RatingValue } from 'cobrowse-agent-sdk'\nimport RatingContext, { type RatingContextValue, type RatingResult } from './context'\nimport Stars, { type RatingStarsProps } from './Stars'\nimport Feedback, { type RatingFeedbackProps } from './Feedback'\nimport Reason, { type RatingReasonProps } from './Reason'\nimport Comment, { type RatingCommentProps } from './Comment'\nimport Submit, { type RatingSubmitProps } from './Submit'\nimport ThankYou, { type RatingThankYouProps } from './ThankYou'\nimport styles from './Rating.module.css'\n\nexport type { RatingResult, RatingContextValue } from './context'\nexport type { RatingStarsProps } from './Stars'\nexport type { RatingFeedbackProps, RatingReasonOption } from './Feedback'\nexport type { RatingReasonProps } from './Reason'\nexport type { RatingCommentProps } from './Comment'\nexport type { RatingSubmitProps } from './Submit'\nexport type { RatingThankYouProps } from './ThankYou'\nexport { useRatingContext } from './context'\n\nconst DEFAULT_FEEDBACK_THRESHOLD = 3\n\nexport interface RatingProps {\n onComplete: (result?: RatingResult) => void\n feedbackThreshold?: number\n className?: string\n children: ReactNode\n}\n\ntype RatingComponent = ((props: RatingProps) => ReactNode) & {\n Stars: (props: RatingStarsProps) => ReactNode\n Feedback: (props: RatingFeedbackProps) => ReactNode\n Reason: (props: RatingReasonProps) => ReactNode\n Comment: (props: RatingCommentProps) => ReactNode\n Submit: (props: RatingSubmitProps) => ReactNode\n ThankYou: (props: RatingThankYouProps) => ReactNode\n}\n\nconst RatingBase = ({\n onComplete,\n feedbackThreshold = DEFAULT_FEEDBACK_THRESHOLD,\n className,\n children,\n}: RatingProps) => {\n const [rating, setRatingState] = useState<RatingValue | null>(null)\n const [feedback, setFeedback] = useState<string[]>([])\n const [comment, setComment] = useState('')\n const [complete, setComplete] = useState(false)\n\n const finish = (rating: RatingValue | null, feedback: string[], comment: string) => {\n setComplete(true)\n onComplete(\n rating === null ? undefined : { rating, feedback: [...feedback, comment].filter(Boolean) },\n )\n }\n\n const setRating = (score: RatingValue, commit = true) => {\n setRatingState(score)\n\n // Reset feedback values so that they are not submitted if the agent changes its initial low rating to 4/5 stars\n if (score > feedbackThreshold) {\n setFeedback([])\n setComment('')\n\n if (commit) {\n finish(score, [], '')\n }\n }\n }\n\n const toggleReason = (value: string) => {\n setFeedback((prev) =>\n prev.includes(value) ? prev.filter((v) => v !== value) : [...prev, value],\n )\n }\n\n const submit = () => {\n finish(rating, feedback, comment)\n }\n\n const value: RatingContextValue = {\n rating,\n feedback,\n comment,\n complete,\n feedbackThreshold,\n setRating,\n toggleReason,\n setComment,\n submit,\n }\n\n return (\n <RatingContext.Provider value={value}>\n <div className={clsx(styles.root, className)}>{children}</div>\n </RatingContext.Provider>\n )\n}\n\nconst Rating: RatingComponent = Object.assign(RatingBase, {\n Stars,\n Feedback,\n Reason,\n Comment,\n Submit,\n ThankYou,\n})\n\nexport default Rating\n","import Rating from './'\nimport type { RatingResult } from './context'\n\nexport type SessionRatingResult = RatingResult\n\nexport interface SessionRatingProps {\n onComplete: (result?: SessionRatingResult) => void\n showThankYou?: boolean\n className?: string\n}\n\nconst SessionRating = ({ onComplete, showThankYou = false, className }: SessionRatingProps) => (\n <Rating onComplete={onComplete} className={className}>\n <Rating.Stars />\n <Rating.Feedback />\n <Rating.Submit />\n {showThankYou && <Rating.ThankYou />}\n </Rating>\n)\n\nexport default SessionRating\n","export const ASCENDING = 'ascending'\nexport const DESCENDING = 'descending'\n\nexport type SortDirection = typeof ASCENDING | typeof DESCENDING\n\nexport interface TableSort {\n key: string\n direction: SortDirection\n}\n\n/** Reads a column off a row for sorting. Memoise a set of these - they are a dependency of the sort. */\nexport type TableSortValues<TRow> = Record<string, (row: TRow) => unknown>\n\n/**\n * What clicking a column asks for: the column already sorted by flips\n * direction, and any other takes `firstDirection`.\n */\nexport function nextSort(\n sort: TableSort | undefined,\n key: string,\n firstDirection: SortDirection = ASCENDING,\n): TableSort {\n if (sort?.key !== key) return { key, direction: firstDirection }\n\n return { key, direction: sort.direction === ASCENDING ? DESCENDING : ASCENDING }\n}\n",".table {\n width: 100%;\n border-collapse: collapse;\n font-size: 14px;\n color: #0e0c26;\n}\n\n.head {\n background: #f9fafb;\n}\n\n.headCell {\n padding: 12px 16px;\n text-align: start;\n font-size: 12px;\n font-weight: 500;\n color: #6f6d82;\n border-bottom: 1px solid rgba(4, 13, 60, 0.12);\n}\n\n.headCell[data-sorted='true'] {\n font-weight: 700;\n color: #0e0c26;\n}\n\n.sortButton {\n composes: focusRing from '../../styles/focus.module.css';\n display: flex;\n align-items: center;\n gap: 6px;\n width: 100%;\n padding: 0;\n border: none;\n border-radius: 2px;\n background: none;\n font: inherit;\n color: inherit;\n cursor: pointer;\n}\n\n.row {\n border-bottom: 1px solid rgba(4, 13, 60, 0.12);\n}\n\n.body .row:last-child {\n border-bottom: none;\n}\n\n.cell {\n padding: 12px 16px;\n}\n\n.emptyCell {\n padding: 40px 16px;\n text-align: center;\n color: #6f6d82;\n}\n","import {\n createContext,\n useContext,\n useMemo,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from 'react'\nimport clsx from 'clsx'\nimport { ASCENDING, nextSort, type SortDirection, type TableSort } from './sort'\nimport styles from './Table.module.css'\nimport Button from '../Button'\n\nexport { ASCENDING, DESCENDING } from './sort'\nexport type { SortDirection, TableSort, TableSortValues } from './sort'\n\ninterface TableContextValue {\n sortBy: (key: string, firstDirection?: SortDirection) => void\n directionOf: (key?: string) => SortDirection | undefined\n}\n\nconst TableContext = createContext<TableContextValue | null>(null)\nconst ColumnContext = createContext<string | undefined>(undefined)\n\nfunction useTableContext(part: string): TableContextValue {\n const table = useContext(TableContext)\n\n if (!table) throw new Error(`<Table.${part}> must be rendered inside <Table>`)\n\n return table\n}\n\nexport interface TableProps extends ComponentPropsWithoutRef<'table'> {\n /** The column the rows are in the order of, and which way. Always controlled. */\n sort?: TableSort\n /**\n * Called with the sort a SortButton click asks for, the column already\n * sorted by flipping direction. Ordering the rows to match is the caller's\n * responsibility.\n */\n onSortChange?: (sort: TableSort) => void\n}\n\nexport type TableHeadProps = ComponentPropsWithoutRef<'thead'>\nexport type TableBodyProps = ComponentPropsWithoutRef<'tbody'>\nexport type TableRowProps = ComponentPropsWithoutRef<'tr'>\n\nexport interface TableHeadCellProps extends ComponentPropsWithoutRef<'th'> {\n /** Marks this header as the one sorted by, and supplies the column to a nested SortButton */\n column?: string\n}\n\nexport interface TableCellProps extends ComponentPropsWithoutRef<'td'> {\n column?: string\n}\n\nexport interface TableSortButtonState {\n isSorted: boolean\n direction?: SortDirection\n}\n\nexport interface TableSortButtonProps extends Omit<ComponentPropsWithoutRef<'button'>, 'children'> {\n /** Defaults to the enclosing HeadCell's column */\n column?: string\n /** The direction applied when this column is first sorted by */\n firstDirection?: SortDirection\n /** Render the sort button contents. May be a function, which receives this column's sort state */\n children?: ReactNode | ((state: TableSortButtonState) => ReactNode)\n}\n\nexport interface TableEmptyProps extends ComponentPropsWithoutRef<'td'> {\n colSpan: number\n}\n\nconst TableBase = ({ sort, onSortChange, className, ...props }: TableProps) => {\n const context = useMemo<TableContextValue>(\n () => ({\n sortBy: (key, firstDirection) => {\n onSortChange?.(nextSort(sort, key, firstDirection))\n },\n directionOf: (key) => (key !== undefined && sort?.key === key ? sort.direction : undefined),\n }),\n [sort, onSortChange],\n )\n\n return (\n <TableContext.Provider value={context}>\n <table className={clsx(styles.table, className)} {...props} />\n </TableContext.Provider>\n )\n}\n\nconst Head = ({ className, ...props }: TableHeadProps) => (\n <thead className={clsx(styles.head, className)} {...props} />\n)\n\nconst Body = ({ className, ...props }: TableBodyProps) => (\n <tbody className={clsx(styles.body, className)} {...props} />\n)\n\nconst Row = ({ className, ...props }: TableRowProps) => (\n <tr className={clsx(styles.row, className)} {...props} />\n)\n\nconst HeadCell = ({ column, className, ...props }: TableHeadCellProps) => {\n const { directionOf } = useTableContext('HeadCell')\n const direction = directionOf(column)\n\n return (\n <ColumnContext.Provider value={column}>\n <th\n scope='col'\n aria-sort={direction}\n data-sorted={direction ? true : undefined}\n className={clsx(styles.headCell, className)}\n {...props}\n />\n </ColumnContext.Provider>\n )\n}\n\nconst Cell = ({ column, className, ...props }: TableCellProps) => {\n const { directionOf } = useTableContext('Cell')\n\n return (\n <td\n data-sorted={directionOf(column) ? true : undefined}\n className={clsx(styles.cell, className)}\n {...props}\n />\n )\n}\n\nconst SortButton = ({\n column,\n firstDirection = ASCENDING,\n className,\n children,\n ...props\n}: TableSortButtonProps) => {\n const { sortBy, directionOf } = useTableContext('SortButton')\n const headCellColumn = useContext(ColumnContext)\n const key = column ?? headCellColumn\n\n if (key === undefined)\n throw new Error(\"<Table.SortButton> needs a column, either its own or a HeadCell's\")\n\n const direction = directionOf(key)\n\n return (\n <Button\n className={clsx(styles.sortButton, className)}\n onClick={() => {\n sortBy(key, firstDirection)\n }}\n {...props}\n >\n {typeof children === 'function'\n ? children({ isSorted: direction !== undefined, direction })\n : children}\n </Button>\n )\n}\n\nconst Empty = ({ colSpan, className, ...props }: TableEmptyProps) => (\n <tr className={styles.row}>\n <td colSpan={colSpan} className={clsx(styles.cell, styles.emptyCell, className)} {...props} />\n </tr>\n)\n\ntype TableComponent = ((props: TableProps) => ReactNode) & {\n Head: typeof Head\n Body: typeof Body\n Row: typeof Row\n HeadCell: typeof HeadCell\n Cell: typeof Cell\n SortButton: typeof SortButton\n Empty: typeof Empty\n}\n\nconst Table: TableComponent = Object.assign(TableBase, {\n Head,\n Body,\n Row,\n HeadCell,\n Cell,\n SortButton,\n Empty,\n})\n\nexport { Table }\nexport default Table\n","import type { RESTResourceEventMap } from 'cobrowse-agent-sdk'\nimport { useEffect, useMemo, useReducer } from 'react'\n\nexport interface ObservableEntity {\n // The SDK types id as a string, but a destroyed resource is updated with an empty payload and loses it\n id?: string\n on: <Event extends keyof RESTResourceEventMap>(\n event: Event,\n listener: (...args: RESTResourceEventMap[Event]) => void,\n ) => unknown\n\n off: <Event extends keyof RESTResourceEventMap>(\n event: Event,\n listener: (...args: RESTResourceEventMap[Event]) => void,\n ) => unknown\n}\n\n// Getters read the SDK's private state through `this`, so they must run against the entity rather than the proxy.\n// Methods are bound by the SDK, so they keep their context and identity without any help here.\nexport function createEntityProxy<Entity extends object>(entity: Entity): Entity {\n return new Proxy(entity, {\n get: (target, property) => Reflect.get(target, property, target),\n })\n}\n\n// The latest proxy per entity. An entry only exists once the entity has been updated.\nconst currentProxies = new WeakMap<object, object>()\n\nfunction currentProxyOf<Entity extends object>(entity: Entity): Entity {\n // Entries are only ever set to createEntityProxy(entity), so the proxy has the entity's type.\n // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- see above\n return (currentProxies.get(entity) as Entity | undefined) ?? entity\n}\n\nexport function useObservableEntities<Entity extends ObservableEntity>(\n entities: readonly Entity[] | null,\n): Entity[] | null {\n const [version, bump] = useReducer((version: number) => version + 1, 0)\n\n useEffect(() => {\n if (!entities) return\n\n const listeners = entities.map((entity) => {\n const listener = () => {\n // A fresh proxy gives React a new identity for this entity only\n currentProxies.set(entity, createEntityProxy(entity))\n bump()\n }\n\n entity.on('updated', listener)\n\n return { entity, listener }\n })\n\n return () => {\n for (const { entity, listener } of listeners) {\n entity.off('updated', listener)\n }\n }\n }, [entities])\n\n return useMemo(\n () =>\n entities\n ?.map(currentProxyOf)\n // A destroyed resource is updated with an empty payload, which leaves it without an id. Drop it so\n // consumers don't see a dead entity, and so a single resource reads as null once destroyed.\n .filter((entity) => entity.id !== undefined) ?? null,\n // version isn't read, it's what invalidates the memo when an entity is updated\n // eslint-disable-next-line react-hooks/exhaustive-deps -- see above\n [entities, version],\n )\n}\n\nexport function useObservableEntity<Entity extends ObservableEntity>(\n entity: Entity | null,\n): Entity | null {\n const entities = useMemo(() => (entity === null ? null : [entity]), [entity])\n\n return useObservableEntities(entities)?.[0] ?? null\n}\n","import { useCallback, useMemo, useRef, useState } from 'react'\n\nexport function useAsync<Args extends unknown[], Result>(fn: (...args: Args) => Promise<Result>) {\n const [isPending, setIsPending] = useState(false)\n const [isSuccess, setIsSuccess] = useState(false)\n const [error, setError] = useState<Error | null>(null)\n const [data, setData] = useState<Result | null>(null)\n const callIdRef = useRef(0)\n\n const executeAsync = useCallback(\n async (...args: Args): Promise<Result> => {\n // Only the most recent call may write state. A superseded call still resolves or rejects for its own\n // caller, but its result, error and pending transitions are dropped so they can't clobber a newer call.\n callIdRef.current += 1\n const callId = callIdRef.current\n const isCurrent = () => callId === callIdRef.current\n\n setError(null)\n setIsPending(true)\n\n try {\n const result = await fn(...args)\n\n if (isCurrent()) {\n setData(result)\n setIsSuccess(true)\n }\n\n return result\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err))\n\n if (isCurrent()) setError(error)\n throw error\n } finally {\n if (isCurrent()) setIsPending(false)\n }\n },\n [fn],\n )\n\n const reset = useCallback(() => {\n setData(null)\n setError(null)\n setIsPending(false)\n setIsSuccess(false)\n }, [])\n\n return useMemo(\n () => ({\n data,\n error,\n isPending,\n // A later failure keeps this true, since the data from the earlier success is still held. Only a reset clears it.\n isSuccess,\n isError: error !== null,\n executeAsync,\n reset,\n }),\n [data, error, isPending, isSuccess, executeAsync, reset],\n )\n}\n","import { type ObservableEntity, useObservableEntity } from './useObservable'\nimport { useAsync } from './useAsync'\nimport { useCallback, useMemo } from 'react'\n\nexport function useMutation<Args extends unknown[], Entity extends ObservableEntity>(\n fn: (...args: Args) => Promise<Entity>,\n) {\n const {\n data: result,\n error,\n isPending,\n isSuccess,\n isError,\n executeAsync: mutateAsync,\n } = useAsync(fn)\n const data = useObservableEntity(result)\n\n const mutate = useCallback(\n (...args: Args): void => {\n void mutateAsync(...args).catch(() => undefined)\n },\n [mutateAsync],\n )\n\n return useMemo(\n () => ({\n data,\n error,\n isPending,\n isSuccess,\n isError,\n mutate,\n mutateAsync,\n }),\n [data, error, isPending, isSuccess, isError, mutate, mutateAsync],\n )\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { useAsync } from './useAsync'\nimport type { QueryParams, QueryShape, RequestOptions } from 'cobrowse-agent-sdk'\n\nexport interface QueryOptions {\n fetchOnMount?: boolean\n}\n\ntype QueryRequestInit = Omit<RequestInit, 'signal'>\n\nexport type QueryRequestOptions<TQuery extends QueryShape<TQuery> = QueryParams> = Omit<\n RequestOptions<TQuery>,\n 'request'\n> & {\n request?: QueryRequestInit\n}\n\nconst isAbortError = (error: unknown): boolean =>\n error instanceof Error && error.name === 'AbortError'\n\nexport function useQuery<Args extends unknown[], TQuery extends QueryShape<TQuery>, Result>(\n fn: (...args: [...Args, options?: RequestOptions<TQuery>]) => Promise<Result>,\n { fetchOnMount = true }: QueryOptions = {},\n ...args: Args\n) {\n // Each arg is a dependency so a change (e.g. a resource id) produces a new callback and triggers a refetch.\n // Call sites pass a fixed number of args, so the deps array length is stable across renders.\n const wrappedFn = useCallback(\n async (options?: RequestOptions<TQuery>) => await fn(...args, options),\n // eslint-disable-next-line react-hooks/exhaustive-deps -- rest args can't be listed statically, the spread is intentional\n [fn, ...args],\n )\n const {\n data,\n isPending: isExecuting,\n isSuccess,\n isError: isAsyncError,\n executeAsync,\n reset,\n } = useAsync(wrappedFn)\n\n const controllerRef = useRef<AbortController | null>(null)\n const [error, setError] = useState<Error | null>(null)\n\n // A new fn or args means a different resource, so drop the previous result rather than showing it under the\n // new identity. A refetch with the same args keeps the current data to avoid UI flashes. This runs during render\n // so there's no committed frame with stale data.\n const [prevFn, setPrevFn] = useState(() => wrappedFn)\n if (prevFn !== wrappedFn) {\n setPrevFn(() => wrappedFn)\n setError(null)\n reset()\n }\n\n // With fetchOnMount a request is guaranteed to follow, so a query with no outcome yet is pending even before the\n // effect starts it. This avoids a \"no data, not loading\" frame on mount and after a reset. The async error state\n // (unlike the query's, it includes aborts) counts as an outcome so a failed or cancelled request settles.\n const isPending = isExecuting || (fetchOnMount && !isSuccess && !isAsyncError)\n\n const refetch = useCallback(\n async (options?: QueryRequestOptions<TQuery>): Promise<void> => {\n controllerRef.current?.abort()\n setError(null)\n\n const controller = new AbortController()\n controllerRef.current = controller\n\n // A newer refetch replaces the controller, so this tells us whether this request is still the active one.\n const isCurrent = () => controllerRef.current === controller\n\n const requestOptions: RequestOptions<TQuery> = {\n ...options,\n request: {\n ...options?.request,\n signal: controller.signal,\n },\n }\n\n try {\n await executeAsync(requestOptions)\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err))\n\n // errors are handled through the state. Abort errors are intentionally swallowed, and a refetch that\n // has since been superseded must not surface its error over the newer request's state.\n if (isCurrent() && !isAbortError(error)) {\n setError(error)\n }\n } finally {\n if (isCurrent()) {\n controllerRef.current = null\n }\n }\n },\n [executeAsync],\n )\n\n const cancel = useCallback(() => {\n controllerRef.current?.abort()\n }, [])\n\n useEffect(() => {\n if (fetchOnMount) void refetch()\n\n return cancel\n }, [fetchOnMount, refetch, cancel])\n\n return useMemo(\n () => ({\n data,\n error,\n /** A request is in flight, whether the first load or a refetch. */\n isPending,\n /** A request has resolved since the query was mounted or its args changed. Stays true if a later refetch fails. */\n isSuccess,\n /** The first load is in flight and there's no data yet, e.g. to show a skeleton. */\n isLoading: isPending && !isSuccess,\n /** A refetch is in flight while previous data is shown, e.g. to show a subtle indicator. */\n isRefetching: isPending && isSuccess,\n refetch,\n cancel,\n isError: error !== null,\n }),\n [data, error, refetch, cancel, isPending, isSuccess],\n )\n}\n","import equal from 'fast-deep-equal'\nimport { useState } from 'react'\n\n// Keeps the previous value while a new one is equal to it by value, so a value rebuilt every render, such as an object\n// passed inline, keeps its identity for the hooks that depend on it\nexport function useStableValue<T>(value: T): T {\n const [stable, setStable] = useState(value)\n\n if (!equal(stable, value)) {\n setStable(() => value)\n }\n\n return stable\n}\n","import { useCallback, useLayoutEffect, useMemo, useReducer, useRef, useState } from 'react'\nimport { type ObservableEntity, useObservableEntities } from './useObservable'\nimport { type QueryOptions, useQuery } from './useQuery'\nimport { useStableValue } from './useStableValue'\nimport type { QueryShape, RequestOptions } from 'cobrowse-agent-sdk'\n\n/**\n * A page of a listing: an array of its results that knows how to load the page after it, such as the SDK's `Page`,\n * including one mapped with its `mapPage()`. Anything of this shape works, as long as it keeps paging, including\n * after its results are changed as an array's are, e.g. one put first with `unshift()`.\n */\nexport interface ListPage<Entity> extends Array<Entity> {\n readonly hasNextPage: boolean\n nextPage: (options?: Pick<RequestOptions, 'request'>) => Promise<ListPage<Entity>>\n}\n\nexport interface CollectionOptions<TQuery> extends QueryOptions {\n /** Params for the listing, such as filters. A change, compared by value, starts again from the first page. */\n query?: TQuery\n}\n\n/**\n * Lists a resource a page at a time. How each page after the first is requested is up to the pages `fn` resolves,\n * so the SDK's list methods page as their API does.\n *\n * `fn` should keep its identity across renders, e.g. an SDK list method or a function wrapped in `useCallback`, as a\n * new one starts the list again.\n *\n * `isPending`, `isLoading` and `isRefetching` describe the first page: a request for it, one with nothing shown yet, and\n * a refetch of it over what's shown. Loading more is reported by `isLoadingMore` alone.\n *\n * `unshift()` puts entities first in the results without a request, e.g. one just created, until the first page is next\n * loaded or refetched, which lists what the API does.\n *\n * @experimental\n * WARNING: This hook's API, behaviour, and name may change without notice.\n */\nexport function useCollection<\n Args extends unknown[],\n TQuery extends QueryShape<TQuery>,\n Entity extends ObservableEntity,\n>(\n fn: (...args: [...Args, options?: RequestOptions<TQuery>]) => Promise<ListPage<Entity>>,\n { query, ...options }: CollectionOptions<TQuery> = {},\n ...args: Args\n) {\n const stableQuery = useStableValue(query)\n\n const fetchFirstPage = useCallback(\n async (options?: RequestOptions<TQuery>) =>\n await fn(...args, {\n ...options,\n query: stableQuery === undefined ? options?.query : { ...stableQuery, ...options?.query },\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps -- rest args can't be listed statically, see useQuery\n [fn, stableQuery, ...args],\n )\n\n // The first page is a plain query, so mounting, resetting when the args or query change, refetching and\n // cancelling all behave as they do for useQuery\n const first = useQuery(fetchFirstPage, options)\n\n // The pages after the first, tagged with the first page they followed, so a new one (a load, a refetch, or new args\n // or query) starts the list again\n const [loaded, setLoaded] = useState<{\n after: ListPage<Entity> | null\n pages: Array<ListPage<Entity>>\n }>({ after: null, pages: [] })\n const nextPages = loaded.after === first.data ? loaded.pages : null\n\n // Entities put first are added to the first page in place, as its paging is fixed, so the pages after it stay\n // tagged with it. The page keeps its identity, so the version is what tells the results below that it changed.\n const [version, bump] = useReducer((version: number) => version + 1, 0)\n\n // The page is read through a ref so a call reaches the page being shown, not the one the caller's render had: a\n // handler is typically made in one render and calls after an await, by which time the first page may have loaded\n // or been refetched. The ref is set on commit, so a call never reaches a page that hasn't been shown yet.\n const firstPageRef = useRef(first.data)\n useLayoutEffect(() => {\n firstPageRef.current = first.data\n }, [first.data])\n\n const unshift = useCallback((...entities: Entity[]): void => {\n const page = firstPageRef.current\n if (page === null) return\n\n // One the page already has is left where it is, so putting an entity first is idempotent, e.g. a created account\n // put first by the app and again by selecting it\n const added = entities.filter(\n (entity) => entity.id === undefined || !page.some((listed) => listed.id === entity.id),\n )\n if (added.length === 0) return\n\n page.unshift(...added)\n bump()\n }, [])\n\n const loadedPages = useMemo(\n () => (first.data === null ? null : [first.data, ...(nextPages ?? [])]),\n // version isn't read, it's what recomputes the pages when the first is added to in place\n // eslint-disable-next-line react-hooks/exhaustive-deps -- see above\n [first.data, nextPages, version],\n )\n const last = loadedPages?.[loadedPages.length - 1]\n const hasMore = last?.hasNextPage ?? false\n\n // The page after the last is a query too, keyed on the last page, so a new first page resets it, cancelling a request\n // in flight and clearing its error. The page is added as its request completes, unless that was cancelled, and is\n // tagged with the first page it followed, so one that completes for an earlier list never shows in a newer one.\n const fetchMore = useCallback(\n async (options?: RequestOptions<TQuery>) => {\n if (last === undefined) throw new Error('There is no page to load the next one from')\n\n const after = first.data\n const page = await last.nextPage({ request: options?.request })\n\n if (options?.request?.signal?.aborted !== true) {\n setLoaded((loaded) => ({\n after,\n pages: loaded.after === after ? [...loaded.pages, page] : [page],\n }))\n }\n\n return page\n },\n [first.data, last],\n )\n const {\n error: loadMoreError,\n isPending: isLoadingMore,\n refetch: refetchMore,\n cancel: cancelMore,\n } = useQuery(fetchMore, { fetchOnMount: false })\n\n // Stops whichever page is in flight, the first or one loading more\n const { cancel: cancelFirst } = first\n const cancel = useCallback(() => {\n cancelFirst()\n cancelMore()\n }, [cancelFirst, cancelMore])\n\n const loadMore = useCallback(async (): Promise<void> => {\n if (!hasMore || first.isPending || isLoadingMore) return\n\n await refetchMore()\n }, [hasMore, first.isPending, isLoadingMore, refetchMore])\n\n // Offset paging repeats a result when one is added between pages, so only its first occurrence is kept. The page\n // it came from is noted so the live results can be grouped back into pages.\n const { entities, pageIndexById } = useMemo(() => {\n const pageIndexById = new Map<string, number>()\n if (loadedPages === null) return { entities: null, pageIndexById }\n\n const entities = loadedPages.flatMap((page, index) =>\n page.filter((entity) => {\n if (entity.id === undefined) return true\n if (pageIndexById.has(entity.id)) return false\n\n pageIndexById.set(entity.id, index)\n\n return true\n }),\n )\n\n return { entities, pageIndexById }\n }, [loadedPages])\n const data = useObservableEntities(entities)\n\n // The live results grouped by page, so they update and drop out just as they do in data. A last page that came back\n // empty only marks the end of the listing, so it's left out, while other pages keep their place even if emptied.\n const pages = useMemo(() => {\n if (loadedPages === null || data === null) return null\n\n const grouped = loadedPages.map((): Entity[] => [])\n for (const entity of data) {\n const index = entity.id === undefined ? undefined : pageIndexById.get(entity.id)\n if (index !== undefined) grouped[index].push(entity)\n }\n\n const lastIndex = loadedPages.length - 1\n return lastIndex > 0 && loadedPages[lastIndex].length === 0\n ? grouped.slice(0, lastIndex)\n : grouped\n }, [loadedPages, data, pageIndexById])\n\n const error = first.error ?? loadMoreError\n\n return useMemo(\n () => ({\n ...first,\n data,\n error,\n isError: error !== null,\n cancel,\n /**\n * The results of each page loaded, e.g. to show one at a time with page controls. They're the same live results\n * as `data`, so a result repeated on a later page only shows on the first. Null until the first page has loaded.\n */\n pages,\n /** More results may follow. False until the first page has loaded, and once a page comes back empty. */\n hasMore,\n /** More results are being loaded. */\n isLoadingMore,\n /** Loading more results failed. The results already loaded are kept. */\n isLoadMoreError: loadMoreError !== null,\n /** Loads the page after the last and adds its results, unless one is in flight or there are no more. */\n loadMore,\n /**\n * Puts entities first in the results without a request, e.g. one just created. They're kept until the first page\n * is next loaded or refetched, which lists what the API does. Nothing is added before the first page has loaded,\n * and one already listed is left where it is.\n */\n unshift,\n }),\n [first, data, pages, error, cancel, hasMore, isLoadingMore, loadMoreError, loadMore, unshift],\n )\n}\n","import { useMemo } from 'react'\nimport { type ObservableEntity, useObservableEntity } from './useObservable'\nimport { type QueryOptions, useQuery } from './useQuery'\nimport type { QueryShape, RequestOptions } from 'cobrowse-agent-sdk'\n\nexport function useResource<\n Args extends unknown[],\n TQuery extends QueryShape<TQuery>,\n Entity extends ObservableEntity,\n>(\n fn: (...args: [...Args, options?: RequestOptions<TQuery>]) => Promise<Entity>,\n options?: QueryOptions,\n ...args: Args\n) {\n const query = useQuery(fn, options, ...args)\n const data = useObservableEntity(query.data)\n\n return useMemo(\n () => ({\n ...query,\n data,\n }),\n [query, data],\n )\n}\n","import { useCallback, useMemo, useState } from 'react'\n\nexport interface PaginatedList<Entity> {\n pages: Entity[][] | null\n isPending: boolean\n isLoading: boolean\n hasMore: boolean\n isLoadingMore: boolean\n isLoadMoreError: boolean\n loadMore: () => Promise<void>\n}\n\n/**\n * Shows a paginated list a page at a time, moving between pages rather than adding each to the list. Moving to the\n * next page shows it straight away, loading if it isn't loaded yet, and every page visited stays loaded, so going\n * back never makes a request.\n *\n * ```ts\n * const sessions = useCollection(cobrowse.sessions.list, { query })\n * const page = usePageControls(sessions)\n * ```\n *\n * @experimental\n * WARNING: This hook's API, behaviour, and name may change without notice.\n */\nexport function usePageControls<List extends PaginatedList<unknown>>(list: List) {\n // Loading more is how the next page arrives, not something page controls offer, so it's kept out of the result\n const { pages, hasMore, isLoadingMore, isLoadMoreError, loadMore, ...rest } = list\n\n const [index, setIndex] = useState(0)\n const lastIndex = pages === null ? 0 : pages.length - (isLoadingMore ? 0 : 1)\n const pageIndex = Math.min(index, lastIndex)\n if (index !== pageIndex) setIndex(pageIndex)\n\n const isPendingPage = pages !== null && pageIndex === pages.length\n const data: NonNullable<List['pages']>[number] | null = isPendingPage\n ? null\n : (pages?.[pageIndex] ?? null)\n\n const hasNextPage = pages !== null && !isPendingPage && (pageIndex < pages.length - 1 || hasMore)\n const hasPreviousPage = pageIndex > 0\n\n const goToNextPage = useCallback(async (): Promise<void> => {\n if (pages === null || isPendingPage) return\n\n const needsLoading = pageIndex === pages.length - 1\n if (needsLoading && !hasMore) return\n\n // Shown first, then loaded if need be, with its results filling in when they land\n setIndex(pageIndex + 1)\n if (needsLoading) await loadMore()\n }, [pages, pageIndex, isPendingPage, hasMore, loadMore])\n\n const goToPreviousPage = useCallback(() => {\n setIndex(Math.max(pageIndex - 1, 0))\n }, [pageIndex])\n\n return useMemo(\n () => ({\n ...rest,\n /** The results of the current page. Null while it loads, whether the first page or one moved to. */\n data,\n /** The results of every page loaded. Null until the first page has loaded. */\n pages,\n /** The current page, from 0. One past the last loaded while the page moved to loads. */\n pageIndex,\n /** A request for the current page is in flight, whether its first load, a refetch, or the page moved to. */\n isPending: rest.isPending || isPendingPage,\n /** The current page is loading with nothing to show yet, whether the first page or one moved to. */\n isLoading: rest.isLoading || isPendingPage,\n /** There's a page after the current one, whether loaded already or still to load. */\n hasNextPage,\n hasPreviousPage,\n /** Loading the page moved to failed, so the one before it is shown again. Moving next again retries. */\n isNextPageError: isLoadMoreError,\n /** Moves to the page after the current one, loading it if needed. Back to this one if it comes back empty. */\n goToNextPage,\n /** Moves to the page before the current one, which is always loaded already. */\n goToPreviousPage,\n }),\n [\n rest,\n data,\n pages,\n pageIndex,\n isPendingPage,\n hasNextPage,\n hasPreviousPage,\n isLoadMoreError,\n goToNextPage,\n goToPreviousPage,\n ],\n )\n}\n","import { useCobrowse } from '@/components/CobrowseProvider'\nimport { useMutation } from '@/hooks/useMutation'\n\nexport function useCreateAccount() {\n const cobrowse = useCobrowse()\n\n return useMutation(cobrowse.accounts.create)\n}\n","import { useMutation } from '@/hooks/useMutation'\nimport type { Account } from 'cobrowse-agent-sdk'\n\nexport function useDestroyAccount(account: Account) {\n return useMutation(account.destroy)\n}\n","import { useCobrowse } from '@/components/CobrowseProvider'\nimport { useCollection } from '@/hooks/useCollection'\nimport type { QueryOptions } from '@/hooks/useQuery'\n\nexport function useListAccounts(options?: QueryOptions) {\n const cobrowse = useCobrowse()\n\n return useCollection(cobrowse.accounts.list, options)\n}\n","import { useMutation } from '@/hooks/useMutation'\nimport type { Account } from 'cobrowse-agent-sdk'\n\nexport function useUpdateAccount(account: Account) {\n // eslint-disable-next-line @typescript-eslint/unbound-method -- update is bound in RESTResource's constructor which is not visible to the type system\n return useMutation(account.update)\n}\n","import {\n createContext,\n use,\n useCallback,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react'\nimport type { Account } from 'cobrowse-agent-sdk'\nimport { useCobrowse } from '@/components/CobrowseProvider'\nimport { useListAccounts } from './useListAccounts'\n\nconst storageKey = 'cobrowse-account'\n\nexport type AccountsContextValue = ReturnType<typeof useListAccounts>\n\nexport interface ActiveAccountContextValue {\n /**\n * The selected account, resolved against the loaded list: the stored selection when the user still has it, else the\n * first account. Null until the list has loaded, and when the user has no accounts.\n */\n account: Account | null\n /**\n * The list has loaded, so the selection has been reconciled against it, or it failed to load, so the app can move\n * on rather than wait on an account forever.\n */\n isResolved: boolean\n /**\n * Selects an account, stores the selection for the next load, and sets the SDK's license right away, so a request\n * started straight after carries it. An SDK account the list doesn't contain yet, e.g. one just created, is put\n * first in the list, as its `unshift()` does. Before the list has loaded, any key can be selected, e.g. one forced\n * from the URL, and is resolved against the list once it arrives. After that, a key the list doesn't contain\n * throws.\n */\n setActiveAccount: (account: Pick<Account, 'license_key'>) => void\n}\n\nconst AccountsContext = createContext<AccountsContextValue | null>(null)\nconst ActiveAccountContext = createContext<ActiveAccountContextValue | null>(null)\n\nfunction getStoredLicenseKey(): string | null {\n try {\n return window.localStorage.getItem(storageKey)\n } catch (error) {\n console.warn('Failed to retrieve the stored account.', error)\n }\n\n return null\n}\n\nfunction storeLicenseKey(licenseKey: string): void {\n try {\n window.localStorage.setItem(storageKey, licenseKey)\n } catch (error) {\n console.warn('Failed to store the account.', error)\n }\n}\n\n// The list's entities are SDK accounts, so one can be put in the list, while a bare key can only be found in it\nfunction isAccount(account: Pick<Account, 'license_key'>): account is Account {\n return 'on' in account && 'off' in account\n}\n\nexport interface AccountsProviderProps {\n children?: ReactNode\n}\n\n/**\n * Lists the user's accounts and keeps one selected, with the selection stored in local storage so it survives a\n * reload. While mounted, the provider owns the SDK's license: once the list has loaded, it's kept on the account\n * resolved, so the account shown and the one requests are made against can't differ. On unmount, the SDK is given\n * back the license it had.\n *\n * @experimental\n * WARNING: This component's API, behaviour, and name may change without notice.\n */\nexport function AccountsProvider({ children }: AccountsProviderProps) {\n const cobrowse = useCobrowse()\n // A user's own accounts come back in one page, so the list is complete once loaded. A refetch keeps the list shown\n // until the new one lands, and a destroyed account drops out as it's destroyed.\n const accounts = useListAccounts()\n // The selection asked for: the one stored by a previous load, else a license the app set on the SDK before\n // mounting, e.g. a single-account host. What it resolves to is up to the list, below.\n const [licenseKey, setLicenseKey] = useState(() => getStoredLicenseKey() ?? cobrowse.license)\n\n // The list is read through a ref so a selection checks the list being shown, not the one the caller's render had,\n // e.g. a selection made after an await. The ref is set on commit, before the effects below run.\n const listRef = useRef(accounts.data)\n useLayoutEffect(() => {\n listRef.current = accounts.data\n }, [accounts.data])\n\n const { unshift } = accounts\n\n const setActiveAccount = useCallback(\n (account: Pick<Account, 'license_key'>) => {\n const list = listRef.current\n\n // Once the list has loaded, a selection has to resolve against it, so the account shown is the one selected\n // and nothing the user doesn't have is stored. A created account isn't listed until a refetch, so it's put\n // first, as the list's unshift() does. Before the list has loaded there's nothing to check against: the key is\n // resolved, and stored or dropped, by the reconcile below once the list arrives.\n if (list !== null && !list.some((listed) => listed.license_key === account.license_key)) {\n if (!isAccount(account)) {\n throw new Error(\n `Account ${account.license_key} isn't one of the user's accounts. Pass the SDK account to list it, or select one from the list.`,\n )\n }\n\n unshift(account)\n }\n\n // The SDK license is set synchronously so a request started straight after, or in the same effect phase (e.g.\n // the initial accounts list, after an account is forced before it has loaded), carries the header.\n // oxlint-disable-next-line react/immutability -- the SDK is an external system, and selecting an account is meant to change its license\n cobrowse.license = account.license_key\n storeLicenseKey(account.license_key)\n setLicenseKey(account.license_key)\n },\n [cobrowse, unshift],\n )\n\n const activeAccount = useMemo(() => {\n const list = accounts.data ?? []\n\n return list.find((account) => account.license_key === licenseKey) ?? list[0] ?? null\n }, [accounts.data, licenseKey])\n\n // The license is borrowed while mounted: on unmount, or when another SDK instance is provided, the one the SDK had\n // is given back, so a host that signs another user in on the same instance doesn't list their accounts with the\n // previous user's key. A layout effect, so it's recorded before a consumer's passive effect sets one, e.g. an\n // account forced from the URL.\n useLayoutEffect(() => {\n const previous = cobrowse.license\n\n return () => {\n // oxlint-disable-next-line react/immutability -- the SDK is an external system, and the provider gives back the license it borrowed\n cobrowse.license = previous\n }\n }, [cobrowse])\n\n // Once the list has first loaded, make the resolved account the selected one. This persists an auto-selected\n // fallback and drops a stored selection that is no longer available to the user. It runs once on purpose: later\n // selections are stored as they're made, and a refetch that drops the selected account shouldn't replace the\n // stored one with a fallback.\n const hasReconciled = useRef(false)\n\n useLayoutEffect(() => {\n if (!accounts.isSuccess || hasReconciled.current) return\n\n // oxlint-disable-next-line react/set-state-in-effect -- the loaded list is the external source the stored selection is reconciled against, once\n if (activeAccount !== null) setActiveAccount(activeAccount)\n hasReconciled.current = true\n }, [accounts.isSuccess, activeAccount, setActiveAccount])\n\n // The SDK's license mirrors the account shown, so the two can't differ: it follows the resolved account whenever\n // that changes (a refetch or a destroy drops it, a created one is listed, a new SDK instance is provided), and is\n // cleared when the loaded list has none, as the API rejects a key it can't resolve. Until the list has loaded\n // there's nothing to resolve against, so a key set through setActiveAccount, e.g. one forced from the URL, is left\n // in place for the list request to carry. A layout effect runs before any passive effect in the same commit, so a\n // request a consumer starts for the new account already carries it.\n const activeLicenseKey = activeAccount?.license_key ?? null\n const hasListLoaded = accounts.isSuccess\n\n useLayoutEffect(() => {\n if (!hasListLoaded) return\n\n // oxlint-disable-next-line react/immutability -- the SDK is an external system whose license mirrors the account shown\n cobrowse.license = activeLicenseKey\n }, [cobrowse, hasListLoaded, activeLicenseKey])\n\n // The list has loaded, possibly empty (the API answers a signed-out request with an empty list), so the selection\n // above is reconciled against it, or it failed to load. The query's args never change, so isSuccess stays true\n // from the first load on.\n const isResolved = accounts.isSuccess || accounts.isError\n\n const activeAccountValue = useMemo<ActiveAccountContextValue>(\n () => ({ account: activeAccount, isResolved, setActiveAccount }),\n [activeAccount, isResolved, setActiveAccount],\n )\n\n return (\n <AccountsContext.Provider value={accounts}>\n <ActiveAccountContext.Provider value={activeAccountValue}>\n {children}\n </ActiveAccountContext.Provider>\n </AccountsContext.Provider>\n )\n}\n\n/** The list of the user's accounts, as `useListAccounts` returns it, shared by every consumer of the provider. */\nexport function useAccountsContext(): AccountsContextValue {\n const context = use(AccountsContext)\n\n if (!context) {\n throw new Error('useAccountsContext must be used inside AccountsProvider')\n }\n\n return context\n}\n\n/** The selected account, whether it's been resolved, and the function to select another. */\nexport function useActiveAccountContext(): ActiveAccountContextValue {\n const context = use(ActiveAccountContext)\n\n if (!context) {\n throw new Error('useActiveAccountContext must be used inside AccountsProvider')\n }\n\n return context\n}\n\nexport default AccountsProvider\n","import { useMemo } from 'react'\nimport { type ActiveAccountContextValue, useActiveAccountContext } from './AccountsContext'\n\n/**\n * The selected account and the function to select another, as a pair:\n *\n * ```jsx\n * const [account, setActiveAccount] = useActiveAccount()\n * ```\n *\n * Must be used inside `AccountsProvider`.\n */\nexport function useActiveAccount(): readonly [\n ActiveAccountContextValue['account'],\n ActiveAccountContextValue['setActiveAccount'],\n] {\n const { account, setActiveAccount } = useActiveAccountContext()\n\n return useMemo(() => [account, setActiveAccount] as const, [account, setActiveAccount])\n}\n","import { useCobrowse } from '@/components/CobrowseProvider'\nimport { useMutation } from '@/hooks/useMutation'\n\n/** Trusts a public key, as SPKI PEM, to sign JWTs for the account, with an optional title. */\nexport function useCreateJwtSsoKey() {\n const cobrowse = useCobrowse()\n\n return useMutation(cobrowse.jwtsso.keys.create)\n}\n","import { useMutation } from '@/hooks/useMutation'\nimport type { JWTSSOKey } from 'cobrowse-agent-sdk'\n\n/** Stops trusting a key, through the key itself, so it drops out of the lists showing it. */\nexport function useDestroyJwtSsoKey(key: JWTSSOKey) {\n // eslint-disable-next-line @typescript-eslint/unbound-method -- destroy is bound in RESTResource's constructor which is not visible to the type system\n return useMutation(key.destroy)\n}\n","import { useCobrowse } from '@/components/CobrowseProvider'\nimport { useCollection } from '@/hooks/useCollection'\nimport type { QueryOptions } from '@/hooks/useQuery'\nimport type { JWTSSOKey, JWTSSOKeysQuery } from 'cobrowse-agent-sdk'\n\n/**\n * The public keys the account trusts to sign JWTs for single sign-on, newest first, a page at a time, as\n * `useCollection` returns them. A key just created is put first with `unshift()`, and a destroyed one drops out.\n */\nexport function useListJwtSsoKeys(options?: QueryOptions) {\n const cobrowse = useCobrowse()\n\n return useCollection<[], JWTSSOKeysQuery, JWTSSOKey>(cobrowse.jwtsso.keys.list, options)\n}\n","import { useMutation } from '@/hooks/useMutation'\nimport type { JWTSSOKey } from 'cobrowse-agent-sdk'\n\n/** Retitles a key through the key itself, so every hook showing it re-renders. */\nexport function useUpdateJwtSsoKey(key: JWTSSOKey) {\n // eslint-disable-next-line @typescript-eslint/unbound-method -- update is bound in RESTResource's constructor which is not visible to the type system\n return useMutation(key.update)\n}\n","import { useCobrowse } from '@/components/CobrowseProvider'\nimport { useResource } from '@/hooks/useResource'\nimport type { QueryOptions } from '@/hooks/useQuery'\n\n/**\n * The policy of the signed-in user on the SDK's current license: what they may do on each resource, as\n * `policy.hasPermission('sessions:create')` and `policy.get('sessions')` answer it.\n *\n * The policy is requested for the license the SDK has when the hook mounts. A license change, e.g. another account\n * selected, is the caller's to handle, by remounting or calling `refetch()`, as with the other hooks.\n */\nexport function useCurrentPolicy(options?: QueryOptions) {\n const cobrowse = useCobrowse()\n\n return useResource(cobrowse.policies.current, options)\n}\n","import CodeEntryComponent from '@/components/CodeEntry'\nimport ButtonComponent from '@/components/Button'\nimport ExternalLinkComponent from '@/components/ExternalLink'\nimport PlatformIconComponent from '@/components/PlatformIcon'\nimport DeviceComponent from '@/components/Device'\nimport SessionComponent from '@/components/Session'\nimport SmartConnectButtonComponent from '@/components/SmartConnectButton'\nimport UserIconComponent from '@/components/UserIcon'\nimport RefreshButtonComponent from '@/components/RefreshButton'\nimport CancelButtonComponent from '@/components/CancelButton'\nimport BlockingErrorComponent from '@/components/BlockingError'\nimport LoaderComponent from '@/components/Loader'\nimport FrameComponent, { useRemoteContext as useRemoteContextHook } from '@/components/Frame'\nimport RemoteContextRelayComponent from '@/components/RemoteContextRelay'\nimport SessionEmbedComponent from '@/components/SessionEmbed'\nimport ConnectDeviceComponent from '@/components/ConnectDevice'\nimport RatingComponent, { useRatingContext as useRatingContextHook } from '@/components/Rating'\nimport SessionRatingComponent from '@/components/Rating/SessionRating'\nimport CobrowseProviderComponent, {\n useCobrowse as useCobrowseHook,\n} from '@/components/CobrowseProvider'\nimport TableComponent from '@/components/Table'\nimport useSessionHook from '@/hooks/useSession'\nimport useSessionEventsHook from '@/hooks/useSessionEvents'\nimport useTrustedEmbeddingOriginsHook from '@/hooks/useTrustedEmbeddingOrigins'\nimport i18nInstance, { bindI18n as bindI18nHelper } from '@/i18n'\nexport { useMutation } from '@/hooks/useMutation'\nexport { useCollection } from '@/hooks/useCollection'\nexport { useResource } from '@/hooks/useResource'\nexport { usePageControls } from '@/hooks/usePageControls'\nexport { parseUserAgent, describeUserAgent } from '@/utils/userAgent'\nexport type { ListPage, CollectionOptions } from '@/hooks/useCollection'\nexport type { ParsedUserAgent } from '@/utils/userAgent'\nexport type { PaginatedList } from '@/hooks/usePageControls'\n\nexport type { CodeEntryProps } from '@/components/CodeEntry'\nexport type { ButtonProps } from '@/components/Button'\nexport type { ExternalLinkProps } from '@/components/ExternalLink'\nexport type { DeviceData, DeviceProps } from '@/components/Device'\nexport type { SessionData, SessionProps } from '@/components/Session'\nexport type { SmartConnectButtonProps } from '@/components/SmartConnectButton'\nexport type { RefreshButtonProps } from '@/components/RefreshButton'\nexport type { CancelButtonProps } from '@/components/CancelButton'\nexport type { BlockingErrorProps } from '@/components/BlockingError'\nexport type { LoaderProps } from '@/components/Loader'\nexport type { FrameProps } from '@/components/Frame'\nexport type { RemoteContextRelayProps } from '@/components/RemoteContextRelay'\nexport type { SessionEmbedProps } from '@/components/SessionEmbed'\nexport type { ConnectDeviceProps } from '@/components/ConnectDevice'\nexport type {\n RatingProps,\n RatingResult,\n RatingContextValue,\n RatingStarsProps,\n RatingFeedbackProps,\n RatingReasonOption,\n RatingReasonProps,\n RatingCommentProps,\n RatingSubmitProps,\n RatingThankYouProps,\n} from '@/components/Rating'\nexport type { SessionRatingProps, SessionRatingResult } from '@/components/Rating/SessionRating'\nexport type { CobrowseProviderProps } from '@/components/CobrowseProvider'\nexport type {\n TableProps,\n TableHeadProps,\n TableBodyProps,\n TableRowProps,\n TableHeadCellProps,\n TableCellProps,\n TableSortButtonProps,\n TableSortButtonState,\n TableEmptyProps,\n TableSort,\n TableSortValues,\n SortDirection,\n} from '@/components/Table'\nexport { ASCENDING, DESCENDING } from '@/components/Table'\nexport type { SessionEventHandlers } from '@/hooks/useSessionEvents'\n\nexport { useCreateAccount } from '@/modules/accounts/useCreateAccount'\nexport { useDestroyAccount } from '@/modules/accounts/useDestroyAccount'\nexport { useListAccounts } from '@/modules/accounts/useListAccounts'\nexport { useUpdateAccount } from '@/modules/accounts/useUpdateAccount'\nexport {\n AccountsProvider,\n useAccountsContext,\n useActiveAccountContext,\n} from '@/modules/accounts/AccountsContext'\nexport type {\n AccountsProviderProps,\n AccountsContextValue,\n ActiveAccountContextValue,\n} from '@/modules/accounts/AccountsContext'\nexport { useActiveAccount } from '@/modules/accounts/useActiveAccount'\nexport { useCreateJwtSsoKey } from '@/modules/jwtsso/useCreateJwtSsoKey'\nexport { useDestroyJwtSsoKey } from '@/modules/jwtsso/useDestroyJwtSsoKey'\nexport { useListJwtSsoKeys } from '@/modules/jwtsso/useListJwtSsoKeys'\nexport { useUpdateJwtSsoKey } from '@/modules/jwtsso/useUpdateJwtSsoKey'\nexport { useCurrentPolicy } from '@/modules/policies/useCurrentPolicy'\n\nexport const CodeEntry = CodeEntryComponent\nexport const Button = ButtonComponent\nexport const ExternalLink = ExternalLinkComponent\nexport const PlatformIcon = PlatformIconComponent\nexport const Device = DeviceComponent\nexport const Session = SessionComponent\nexport const SmartConnectButton = SmartConnectButtonComponent\nexport const UserIcon = UserIconComponent\nexport const RefreshButton = RefreshButtonComponent\nexport const CancelButton = CancelButtonComponent\nexport const BlockingError = BlockingErrorComponent\nexport const Loader = LoaderComponent\nexport const Frame = FrameComponent\nexport const RemoteContextRelay = RemoteContextRelayComponent\nexport const SessionEmbed = SessionEmbedComponent\nexport const ConnectDevice = ConnectDeviceComponent\nexport const Rating = RatingComponent\nexport const SessionRating = SessionRatingComponent\nexport const useRatingContext = useRatingContextHook\nexport const CobrowseProvider = CobrowseProviderComponent\nexport const Table = TableComponent\nexport const useCobrowse = useCobrowseHook\nexport const useRemoteContext = useRemoteContextHook\nexport const useSession = useSessionHook\nexport const useSessionEvents = useSessionEventsHook\nexport const useTrustedEmbeddingOrigins = useTrustedEmbeddingOriginsHook\nexport const bindI18n = bindI18nHelper\nexport const i18n = i18nInstance\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cobrowse-agent-ui",
|
|
3
|
-
"version": "1.7.0-rc.
|
|
3
|
+
"version": "1.7.0-rc.14",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/cobrowseio/cobrowse-agent-ui.git"
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"@types/react": "^19.2.7",
|
|
47
47
|
"@types/react-dom": "^19.2.3",
|
|
48
48
|
"@vitejs/plugin-react": "^5.1.1",
|
|
49
|
-
"cobrowse-agent-sdk": "^3.0.
|
|
49
|
+
"cobrowse-agent-sdk": "^3.0.8",
|
|
50
50
|
"i18next-cli": "^1.42.9",
|
|
51
51
|
"react": "^19.0.0",
|
|
52
52
|
"react-dom": "^19.0.0",
|