@frontera-sdk/chat-ui 1.50.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +348 -0
  3. package/dist/af-DK_CjRn6-OPBHDTNZ.js +197 -0
  4. package/dist/agent-picker.d.ts +38 -0
  5. package/dist/agent-picker.js +8 -0
  6. package/dist/as-BPtSu6VN-O4ZZEAJG.js +11 -0
  7. package/dist/be-CrQ0smca-5HIE5K27.js +11 -0
  8. package/dist/bg-CrQqGwni-3IRVPZQ7.js +11 -0
  9. package/dist/bn-NCLZcWHi-XOZJFNIB.js +11 -0
  10. package/dist/ca-SUf6Y2Om-V6F2EBCA.js +38 -0
  11. package/dist/capture-NO5ZIGP6.js +1652 -0
  12. package/dist/chat.css +3555 -0
  13. package/dist/chat.d.ts +161 -0
  14. package/dist/chat.js +60498 -0
  15. package/dist/chunk-2KEBRV3W.js +191 -0
  16. package/dist/chunk-6BPHEBCF.js +639 -0
  17. package/dist/chunk-6HYPVNVA.js +25 -0
  18. package/dist/chunk-7ADM3CKD.js +10 -0
  19. package/dist/chunk-AFVU5VT6.js +5601 -0
  20. package/dist/chunk-BEJ3HQG4.js +93 -0
  21. package/dist/chunk-CCVPZVFK.js +28 -0
  22. package/dist/chunk-DGDHKMDB.js +10 -0
  23. package/dist/chunk-FXKXDR5K.js +2166 -0
  24. package/dist/chunk-GTQH7MPF.js +129 -0
  25. package/dist/chunk-I7SXWUAN.js +1258 -0
  26. package/dist/chunk-IQRPGFLI.js +234 -0
  27. package/dist/chunk-IXDM5R55.js +23 -0
  28. package/dist/chunk-JD6ETTXC.js +178 -0
  29. package/dist/chunk-OP4MLJDA.js +215 -0
  30. package/dist/chunk-PQZ2CS26.js +2315 -0
  31. package/dist/chunk-PR4QN5HX.js +38 -0
  32. package/dist/chunk-PUIVKDV5.js +271 -0
  33. package/dist/chunk-QSSFBZAS.js +6914 -0
  34. package/dist/chunk-RAKKA3WU.js +5896 -0
  35. package/dist/chunk-RB2Y4NYC.js +681 -0
  36. package/dist/chunk-VDZH5Z3K.js +72 -0
  37. package/dist/chunk-WMN6BPPS.js +49 -0
  38. package/dist/chunk-WO6DJLFE.js +10857 -0
  39. package/dist/chunk-X5E2DJVO.js +47634 -0
  40. package/dist/chunk-XJFTVKLW.js +2687 -0
  41. package/dist/chunk-ZS6PXIZP.js +187 -0
  42. package/dist/client.d.ts +89 -0
  43. package/dist/client.js +20 -0
  44. package/dist/composer.d.ts +23 -0
  45. package/dist/composer.js +89 -0
  46. package/dist/cop-C3sk0IUo-CIZA2H43.js +11 -0
  47. package/dist/credential.d.ts +75 -0
  48. package/dist/credential.js +3 -0
  49. package/dist/cs-CmAteokq-HAKEQPB4.js +17 -0
  50. package/dist/cu-CBUlrW6Y-QTZ6ZLA4.js +32 -0
  51. package/dist/cy-BBPa6z2x-MX6DGDNW.js +11 -0
  52. package/dist/da-CCDXfXtG-5YEOHMG3.js +11 -0
  53. package/dist/de-1901-CWoAOigE-63QFSF2A.js +11 -0
  54. package/dist/de-1996-BL6awyxG-R2PHKMAB.js +11 -0
  55. package/dist/de-ch-1901-hVThVHVb-JSDB53OZ.js +11 -0
  56. package/dist/el-monoton-D3aKqTz2-2V4OOFBB.js +11 -0
  57. package/dist/el-polyton-ogVWcTzh-3U7NGQMT.js +11 -0
  58. package/dist/en-gb-B7Al27b_-UKCBQFSU.js +21 -0
  59. package/dist/es-DcaaHPU_-NOBXSOZK.js +11 -0
  60. package/dist/esm-MHF25KDL.js +3 -0
  61. package/dist/et-B_spaleu-5UAYIW62.js +11 -0
  62. package/dist/eu-Ctv_kq9Z-V5DREOPN.js +11 -0
  63. package/dist/fi-RW5VB8Yp-YSXBK7LW.js +11 -0
  64. package/dist/fr-BC2onEz9-7KH5T76G.js +11 -0
  65. package/dist/frame.d.ts +59 -0
  66. package/dist/frame.js +111 -0
  67. package/dist/fur-AC12wySk-4PD2Y72H.js +11 -0
  68. package/dist/ga-Cn6LkudM-RRAAJT3N.js +58 -0
  69. package/dist/gl-DZGc-K_G-KYSXXTCY.js +11 -0
  70. package/dist/grc-DOlGgO8T-2HXBZVJ5.js +11 -0
  71. package/dist/gu-Bjl0l-cf-4CFSVZHZ.js +11 -0
  72. package/dist/header.d.ts +78 -0
  73. package/dist/header.js +18 -0
  74. package/dist/hi-DsAaTPCC-KMCFBWK7.js +11 -0
  75. package/dist/hr-DT1SBBes-X2TIX6EI.js +11 -0
  76. package/dist/hsb-DC_ITc1e-PXLERA7R.js +46 -0
  77. package/dist/hu-DVk7Y_ka-PJPVU54B.js +11 -0
  78. package/dist/hy-e995ysyO-MZBRFX52.js +11 -0
  79. package/dist/ia-Cr4TJH0c-D3O2FHGP.js +22 -0
  80. package/dist/id-DifDyWg9-MZ2BGHWI.js +58 -0
  81. package/dist/is-BT8UVRze-CZZCKEFI.js +11 -0
  82. package/dist/it-Bt_Meacx-T4Y5JYV6.js +11 -0
  83. package/dist/ka-jyoLzyDE-ES6EXZLW.js +11 -0
  84. package/dist/kmr-Cfwhwuff-TSW2R2KS.js +11 -0
  85. package/dist/kn-C6Lov-DP-B4BL47CE.js +11 -0
  86. package/dist/la-DuvHjUWw-6K7TFU6X.js +11 -0
  87. package/dist/la-x-classic-yTyAOQEt-YWTKMM2L.js +11 -0
  88. package/dist/la-x-liturgic-CXeQb4FY-B772L5E7.js +11 -0
  89. package/dist/lib-3ZKX25RJ.js +4511 -0
  90. package/dist/lt-BBe8DlDF-4YINVOZR.js +11 -0
  91. package/dist/lv-Q2BBHnzp-TMVQ3MX2.js +11 -0
  92. package/dist/message.d.ts +64 -0
  93. package/dist/message.js +18 -0
  94. package/dist/ml-2xLVYkVY-NGZLAPIN.js +11 -0
  95. package/dist/mn-cyrl-lHM4n0oC-DGBYYUT3.js +11 -0
  96. package/dist/mn-cyrl-x-lmc-3aetruI8-QHJABMOO.js +11 -0
  97. package/dist/mr-CjWJPVmH-X5UHV65O.js +11 -0
  98. package/dist/mul-ethi-D_CMSMEq-H7UMQSOQ.js +11 -0
  99. package/dist/nb-DI8u59ch-J4CAVI4Y.js +122 -0
  100. package/dist/new-session-Dw7JOgzu.d.ts +141 -0
  101. package/dist/new-session.d.ts +4 -0
  102. package/dist/new-session.js +10 -0
  103. package/dist/nl-BHQJ6Gvn-7BH55RA7.js +52 -0
  104. package/dist/nn-ntZvarUK-KKNCHHJ4.js +122 -0
  105. package/dist/no-B8ItS0F3-3ZXIRJ6U.js +120 -0
  106. package/dist/oauth-callback.d.ts +35 -0
  107. package/dist/oauth-callback.js +18 -0
  108. package/dist/oc-P_i3-xLA-XZM6E5YZ.js +11 -0
  109. package/dist/or-50rxpoq4-5VELAFMJ.js +11 -0
  110. package/dist/pa-C54UG8eN-WEJPMZ6Z.js +11 -0
  111. package/dist/parts.d.ts +49 -0
  112. package/dist/parts.js +106 -0
  113. package/dist/pdf-cover-thumbnail-inner-4N2Q5AAG.js +36 -0
  114. package/dist/pdf-deck-view-inner-FZVLAEQR.js +575 -0
  115. package/dist/pdf-document-view-inner-6DF54JWK.js +585 -0
  116. package/dist/pdf-viewer-inner-GPES3KG2.js +256 -0
  117. package/dist/pending-cards.d.ts +26 -0
  118. package/dist/pending-cards.js +9 -0
  119. package/dist/pi-B9cgjyG1-GD5ASDDU.js +11 -0
  120. package/dist/pl-9fg-ESVt-UMX7MCJM.js +32 -0
  121. package/dist/platform.css +4013 -0
  122. package/dist/pms-BRGfm5gS-SSE3AUW5.js +11 -0
  123. package/dist/pt-Cum2_NUC-W35JYVR4.js +11 -0
  124. package/dist/rm-C0MIK9N4-IWL4YTNT.js +11 -0
  125. package/dist/ro-0fmdH0HA-46WUTOYH.js +11 -0
  126. package/dist/ru-v4l-ayaq-BUGK6XCN.js +196 -0
  127. package/dist/sa-CKY9c_Vq-4KIJOI5Y.js +11 -0
  128. package/dist/sh-cyrl-BpCRFOmq-DSLQ4UY2.js +128 -0
  129. package/dist/sh-latn-sRy4Tuaj-UNQOR63V.js +128 -0
  130. package/dist/sk-_iOeDNrQ-NCTQKH25.js +17 -0
  131. package/dist/sl-DpiklF-D-6GG5TDVN.js +11 -0
  132. package/dist/sr-cyrl-Dpzrbd0W-4Q5226YJ.js +142 -0
  133. package/dist/sv-CFm5y56M-VTWNPZ7I.js +11 -0
  134. package/dist/ta-BcghgTbD-NRT35DW6.js +11 -0
  135. package/dist/te-B5Spl2Jk-5VE6CLN4.js +11 -0
  136. package/dist/th-DWX5iPSo-N5GMOQOP.js +11 -0
  137. package/dist/theme.d.ts +49 -0
  138. package/dist/theme.js +3 -0
  139. package/dist/tk-BMbKB10q-HGWWY5L3.js +11 -0
  140. package/dist/tr-CIHIuzqc-6ISBNYLV.js +11 -0
  141. package/dist/types-BDqLaBfH.d.ts +60 -0
  142. package/dist/uk-Dir3oxLs-YQ3QZRI4.js +11 -0
  143. package/dist/univer-workbook-BSSUE5TG.css +3555 -0
  144. package/dist/univer-workbook-N5IIN7CH.js +290849 -0
  145. package/dist/vega-chart-block-NQADYNWQ.js +2857 -0
  146. package/dist/zh-latn-pinyin-BdYb-Ey_-RB542AHF.js +11 -0
  147. package/package.json +137 -0
  148. package/src/styles.css +996 -0
@@ -0,0 +1,187 @@
1
+ 'use client';
2
+ import { cn } from './chunk-DGDHKMDB.js';
3
+ import { CircleIcon, ChevronRightIcon } from './chunk-AFVU5VT6.js';
4
+ import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
5
+ import { jsx, jsxs } from 'react/jsx-runtime';
6
+
7
+ function DropdownMenu({
8
+ ...props
9
+ }) {
10
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
11
+ }
12
+ function DropdownMenuTrigger({
13
+ ...props
14
+ }) {
15
+ return /* @__PURE__ */ jsx(
16
+ DropdownMenuPrimitive.Trigger,
17
+ {
18
+ "data-slot": "dropdown-menu-trigger",
19
+ ...props
20
+ }
21
+ );
22
+ }
23
+ function DropdownMenuContent({
24
+ className,
25
+ sideOffset = 4,
26
+ ...props
27
+ }) {
28
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
29
+ DropdownMenuPrimitive.Content,
30
+ {
31
+ "data-slot": "dropdown-menu-content",
32
+ sideOffset,
33
+ className: cn(
34
+ // Fade only, 100ms, ease-out. The old 150ms stacked a fade with a
35
+ // zoom-95 and a 2px slide, on `ease` — which starts slow, so the frames
36
+ // that confirm the click were the slowest, and the movement made a menu
37
+ // read as ARRIVING rather than already being there.
38
+ "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 duration-100 ease-out bg-surface-overlay text-popover-foreground z-100 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md",
39
+ className
40
+ ),
41
+ ...props
42
+ }
43
+ ) });
44
+ }
45
+ function DropdownMenuItem({
46
+ className,
47
+ inset,
48
+ variant = "default",
49
+ ...props
50
+ }) {
51
+ return /* @__PURE__ */ jsx(
52
+ DropdownMenuPrimitive.Item,
53
+ {
54
+ "data-slot": "dropdown-menu-item",
55
+ "data-inset": inset,
56
+ "data-variant": variant,
57
+ className: cn(
58
+ "focus:bg-surface-overlay-hover focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:size-4 max-md:min-h-11 max-md:gap-3 max-md:px-3 max-md:text-[15px] max-md:[&_svg]:size-[18px]",
59
+ {
60
+ "cursor-pointer": !!props.onClick
61
+ },
62
+ className
63
+ ),
64
+ ...props
65
+ }
66
+ );
67
+ }
68
+ function DropdownMenuRadioGroup({
69
+ ...props
70
+ }) {
71
+ return /* @__PURE__ */ jsx(
72
+ DropdownMenuPrimitive.RadioGroup,
73
+ {
74
+ "data-slot": "dropdown-menu-radio-group",
75
+ ...props
76
+ }
77
+ );
78
+ }
79
+ function DropdownMenuRadioItem({
80
+ className,
81
+ children,
82
+ ...props
83
+ }) {
84
+ return /* @__PURE__ */ jsxs(
85
+ DropdownMenuPrimitive.RadioItem,
86
+ {
87
+ "data-slot": "dropdown-menu-radio-item",
88
+ className: cn(
89
+ "focus:bg-surface-overlay-hover focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm max-md:min-h-11 max-md:text-[15px] outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:size-4",
90
+ className
91
+ ),
92
+ ...props,
93
+ children: [
94
+ /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CircleIcon, { className: "size-1.5! fill-current" }) }) }),
95
+ children
96
+ ]
97
+ }
98
+ );
99
+ }
100
+ function DropdownMenuLabel({
101
+ className,
102
+ inset,
103
+ ...props
104
+ }) {
105
+ return /* @__PURE__ */ jsx(
106
+ DropdownMenuPrimitive.Label,
107
+ {
108
+ "data-slot": "dropdown-menu-label",
109
+ "data-inset": inset,
110
+ className: cn(
111
+ "px-2 py-1.5 text-sm font-medium data-[inset]:pl-8",
112
+ className
113
+ ),
114
+ ...props
115
+ }
116
+ );
117
+ }
118
+ function DropdownMenuSeparator({
119
+ className,
120
+ ...props
121
+ }) {
122
+ return /* @__PURE__ */ jsx(
123
+ DropdownMenuPrimitive.Separator,
124
+ {
125
+ "data-slot": "dropdown-menu-separator",
126
+ className: cn("bg-border -mx-1 my-1 h-px", className),
127
+ ...props
128
+ }
129
+ );
130
+ }
131
+ function DropdownMenuSub({
132
+ ...props
133
+ }) {
134
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Sub, { "data-slot": "dropdown-menu-sub", ...props });
135
+ }
136
+ function DropdownMenuSubTrigger({
137
+ className,
138
+ inset,
139
+ children,
140
+ ...props
141
+ }) {
142
+ return /* @__PURE__ */ jsxs(
143
+ DropdownMenuPrimitive.SubTrigger,
144
+ {
145
+ "data-slot": "dropdown-menu-sub-trigger",
146
+ "data-inset": inset,
147
+ className: cn(
148
+ "focus:bg-surface-overlay-hover focus:text-accent-foreground data-[state=open]:bg-surface-overlay-hover data-[state=open]:text-accent-foreground [&_svg]:text-muted-foreground flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm max-md:min-h-11 max-md:text-[15px] outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:size-4",
149
+ className
150
+ ),
151
+ ...props,
152
+ children: [
153
+ children,
154
+ /* @__PURE__ */ jsx(ChevronRightIcon, { className: "ml-auto size-4" })
155
+ ]
156
+ }
157
+ );
158
+ }
159
+ function DropdownMenuSubContent({
160
+ className,
161
+ ...props
162
+ }) {
163
+ return (
164
+ // Portaled: the parent DropdownMenuContent clips (`overflow-x-hidden`
165
+ // for its own scroll), so an inline submenu gets cut at the menu edge —
166
+ // visible on mobile where the submenu opens toward the viewport edge.
167
+ // The portal escapes the clip and lets collision detection flip sides.
168
+ /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
169
+ DropdownMenuPrimitive.SubContent,
170
+ {
171
+ "data-slot": "dropdown-menu-sub-content",
172
+ collisionPadding: 8,
173
+ className: cn(
174
+ // Fade only, 100ms, ease-out. The old 150ms stacked a fade with a
175
+ // zoom-95 and a 2px slide, on `ease` — which starts slow, so the frames
176
+ // that confirm the click were the slowest, and the movement made a menu
177
+ // read as ARRIVING rather than already being there.
178
+ "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 duration-100 ease-out bg-surface-overlay text-popover-foreground z-100 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg",
179
+ className
180
+ ),
181
+ ...props
182
+ }
183
+ ) })
184
+ );
185
+ }
186
+
187
+ export { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger };
@@ -0,0 +1,89 @@
1
+ import { ChatClient } from '@frontera-sdk/chat/chat-client';
2
+ export { ChatClient } from '@frontera-sdk/chat/chat-client';
3
+ import { FronteraClient } from '@frontera-sdk/core/client';
4
+ import { ChatCredentialProps } from './credential.js';
5
+ export { ResolvedCredential, useChatCredential } from './credential.js';
6
+ import * as react from 'react';
7
+ export { ArtifactVersionMeta, ChatAgent, ChatArtifact, ChatToken, PendingApproval, Session, SessionMessage, StartChatRequest } from '@frontera-sdk/chat/types';
8
+
9
+ /**
10
+ * The client the copied components reach for.
11
+ *
12
+ * Platform components fetch through hooks that assume a signed-in session.
13
+ * Those hooks are the one part of the surface that cannot be copied, so each
14
+ * is re-pointed at this client — supplied once by `FronteraChat` and read by
15
+ * the shims under `src/vendor/lib/services`.
16
+ *
17
+ * Optional by design: a consumer composing `Message` or `Composer` by hand
18
+ * need not provide it, and the features that depend on data simply stay quiet
19
+ * rather than throwing.
20
+ */
21
+ declare const ChatClientContext: react.Context<ChatClient | null>;
22
+ declare function useChatClientOptional(): ChatClient | null;
23
+
24
+ /**
25
+ * The `sub` claim of an end-user chat token, read without verifying it.
26
+ *
27
+ * Used for ONE thing: choosing which localStorage namespace this browser's
28
+ * side-panel records belong to. That is a scoping decision, not an
29
+ * authorization — the server verifies the same token on every call, and a
30
+ * forged one buys nothing here except a wrong namespace in its own browser.
31
+ *
32
+ * The token string itself would be the obvious key and is the wrong one: it
33
+ * rotates on every renewal, so the namespace would change hourly and each
34
+ * renewal would look like a different person. `sub` is the customer's own id
35
+ * for this user and survives renewal, which is exactly the lifetime the
36
+ * records need.
37
+ *
38
+ * Returns null for anything that is not a readable JWT — an API key, a
39
+ * malformed token, a payload without `sub`. Callers treat that as "no scope",
40
+ * which keeps records in the default namespace rather than inventing one.
41
+ */
42
+ declare function subjectOfChatToken(token: string): string | null;
43
+ /**
44
+ * The capabilities claim, read the same way and for the same kind of reason.
45
+ *
46
+ * Lets the composer offer only what the token can actually do — a
47
+ * "run without approval" option the service will refuse is worse than no
48
+ * option, because the reader discovers it by having their choice reverted.
49
+ *
50
+ * Not a security boundary, and not treated as one: every one of these is
51
+ * enforced server-side against the verified token. This just stops the UI
52
+ * promising something the server will decline.
53
+ */
54
+ declare function capabilitiesOfChatToken(token: string): string[];
55
+
56
+ /**
57
+ * A `ChatClient` for the same credential the chat component uses.
58
+ *
59
+ * `null` until the first token lands — the credential is fetched, so there is
60
+ * a render before it exists, and every call site has to handle that anyway.
61
+ * Returning null says so in the type instead of throwing on the first render
62
+ * or handing back a client whose requests would be unauthenticated.
63
+ *
64
+ * ```tsx
65
+ * const { client, ready, error } = useChatClient({ tokenEndpoint: '/api/chat-token' })
66
+ * useEffect(() => { client?.listSessions({ limit: 20 }).then(setHistory) }, [client])
67
+ * ```
68
+ *
69
+ * Pass the SAME credential props you pass to `<FronteraChat>`. Each call
70
+ * resolves its own credential, so a `tokenEndpoint` is hit once per hook —
71
+ * share one client through your own context if that matters to you.
72
+ */
73
+ declare function useChatClient(props: ChatCredentialProps): {
74
+ client: ChatClient | null;
75
+ /**
76
+ * The underlying API client, as a getter.
77
+ *
78
+ * Pass it straight to `<FronteraChat client={getClient} />` when this hook
79
+ * already resolved a credential: the component then shares this one rather
80
+ * than resolving its own, which is the difference between one token per
81
+ * person and two on every load.
82
+ */
83
+ getClient: () => FronteraClient | null;
84
+ ready: boolean;
85
+ error: Error | null;
86
+ refresh: () => Promise<unknown>;
87
+ };
88
+
89
+ export { ChatClientContext, ChatCredentialProps, capabilitiesOfChatToken, subjectOfChatToken, useChatClient, useChatClientOptional };
package/dist/client.js ADDED
@@ -0,0 +1,20 @@
1
+ 'use client';
2
+ export { capabilitiesOfChatToken, subjectOfChatToken } from './chunk-CCVPZVFK.js';
3
+ import { useChatCredential } from './chunk-BEJ3HQG4.js';
4
+ export { useChatCredential } from './chunk-BEJ3HQG4.js';
5
+ export { ChatClientContext, useChatClientOptional } from './chunk-7ADM3CKD.js';
6
+ import './chunk-PR4QN5HX.js';
7
+ import { useMemo } from 'react';
8
+ import { ChatClient } from '@frontera-sdk/chat/chat-client';
9
+ export { ChatClient } from '@frontera-sdk/chat/chat-client';
10
+
11
+ function useChatClient(props) {
12
+ const { getClient, ready, error, refresh } = useChatCredential(props);
13
+ const client = useMemo(() => {
14
+ const resolved = getClient();
15
+ return resolved ? new ChatClient(resolved) : null;
16
+ }, [getClient, ready]);
17
+ return { client, getClient, ready, error, refresh };
18
+ }
19
+
20
+ export { useChatClient };
@@ -0,0 +1,23 @@
1
+ import * as react from 'react';
2
+
3
+ interface ComposerProps {
4
+ onSubmit: (text: string) => void;
5
+ onStop?: () => void;
6
+ busy?: boolean;
7
+ placeholder?: string;
8
+ disabled?: boolean;
9
+ /** Text dropped in from elsewhere — a suggested action, say. */
10
+ seed?: string;
11
+ onSeedConsumed?: () => void;
12
+ }
13
+ /**
14
+ * The input.
15
+ *
16
+ * A textarea rather than an input, growing with its content: people paste
17
+ * paragraphs into agents, and a single-line field hides everything but the
18
+ * end of what they wrote. Enter sends, Shift+Enter breaks the line — the
19
+ * convention every chat surface shares, including the platform's own.
20
+ */
21
+ declare function Composer({ onSubmit, onStop, busy, placeholder, disabled, seed, onSeedConsumed, }: ComposerProps): react.JSX.Element;
22
+
23
+ export { Composer, type ComposerProps };
@@ -0,0 +1,89 @@
1
+ 'use client';
2
+ import './chunk-PR4QN5HX.js';
3
+ import { useState, useRef, useEffect } from 'react';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+
6
+ function Composer({
7
+ onSubmit,
8
+ onStop,
9
+ busy = false,
10
+ placeholder = "Ask anything\u2026",
11
+ disabled = false,
12
+ seed,
13
+ onSeedConsumed
14
+ }) {
15
+ const [text, setText] = useState("");
16
+ const area = useRef(null);
17
+ useEffect(() => {
18
+ if (!seed) return;
19
+ setText((current) => current ? `${current} ${seed}` : seed);
20
+ onSeedConsumed?.();
21
+ requestAnimationFrame(() => {
22
+ const el = area.current;
23
+ if (!el) return;
24
+ el.focus();
25
+ el.setSelectionRange(el.value.length, el.value.length);
26
+ el.style.height = "auto";
27
+ el.style.height = `${Math.min(el.scrollHeight, 200)}px`;
28
+ });
29
+ }, [seed, onSeedConsumed]);
30
+ function resize() {
31
+ const el = area.current;
32
+ if (!el) return;
33
+ el.style.height = "auto";
34
+ el.style.height = `${Math.min(el.scrollHeight, 200)}px`;
35
+ }
36
+ function send() {
37
+ const trimmed = text.trim();
38
+ if (!trimmed || busy || disabled) return;
39
+ onSubmit(trimmed);
40
+ setText("");
41
+ requestAnimationFrame(resize);
42
+ }
43
+ function onKeyDown(event) {
44
+ if (event.key === "Enter" && !event.shiftKey) {
45
+ event.preventDefault();
46
+ send();
47
+ }
48
+ }
49
+ function onFormSubmit(event) {
50
+ event.preventDefault();
51
+ send();
52
+ }
53
+ return /* @__PURE__ */ jsxs("form", { className: "fr-composer", onSubmit: onFormSubmit, children: [
54
+ /* @__PURE__ */ jsx(
55
+ "textarea",
56
+ {
57
+ ref: area,
58
+ className: "fr-composer-input",
59
+ rows: 1,
60
+ value: text,
61
+ placeholder,
62
+ disabled,
63
+ onChange: (e) => {
64
+ setText(e.target.value);
65
+ resize();
66
+ },
67
+ onKeyDown
68
+ }
69
+ ),
70
+ busy && onStop ? /* @__PURE__ */ jsx("button", { type: "button", className: "fr-btn fr-btn-stop", onClick: onStop, "aria-label": "Stop", children: /* @__PURE__ */ jsx(StopIcon, {}) }) : /* @__PURE__ */ jsx(
71
+ "button",
72
+ {
73
+ type: "submit",
74
+ className: "fr-btn fr-btn-send",
75
+ disabled: !text.trim() || disabled,
76
+ "aria-label": "Send",
77
+ children: /* @__PURE__ */ jsx(SendIcon, {})
78
+ }
79
+ )
80
+ ] });
81
+ }
82
+ function SendIcon() {
83
+ return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 16 16", className: "fr-icon", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M8 13V3M8 3 4 7M8 3l4 4", fill: "none", stroke: "currentColor", strokeWidth: "1.7", strokeLinecap: "round", strokeLinejoin: "round" }) });
84
+ }
85
+ function StopIcon() {
86
+ return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 16 16", className: "fr-icon", "aria-hidden": true, children: /* @__PURE__ */ jsx("rect", { x: "4.5", y: "4.5", width: "7", height: "7", rx: "1.5", fill: "currentColor" }) });
87
+ }
88
+
89
+ export { Composer };
@@ -0,0 +1,11 @@
1
+ 'use client';
2
+ import './chunk-PR4QN5HX.js';
3
+
4
+ // ../../node_modules/@univerjs/engine-render/lib/es/cop-C3sk0IUo.js
5
+ var Cop = [
6
+ "02,002,0002,1,2,21,12,,201,3,22,32,01,022",
7
+ '{"0":[{"\u2C99":[{"\u0300":[{"0":7}]}],"\u2C9B":[{"\u0300":[{"0":7}]}]}],".":[{"0":[{"\u2CAF":1,"\u2C91":1,"\u2C9D":1,"\u2CAB":1,"\u03E9":1,"\u03EB":1,"\u2C99":[{"\u0300":2}],"\u2C9B":[{"\u0300":2}],"\u2C93":[{"\u0308":2}],"\u03EF":1}],"\u2C83":0,"\u2CA5":0,"\u2C87":0,"\u03E5":0,"\u2C85":0,"\u03E7":0,"\u2C95":0,"\u2C97":0,"\u2C99":0,"\u2C9B":0,"\u2CA1":0,"\u03ED":0,"\u2CA3":0,"\u2CA7":0,"\u2CB1":[{"\u2C9F":[{"\u2CA9":0}]},0],"\u2CAD":0,"\u03E3":0,"\u2C8D":0,"\u2C8F":[{"\u2C93":0}]}],"\u2C83":[{"\u2C83":4,"\u2C85":4,"\u2C87":4,"\u2C8D":4,"\u03E7":4,"\u2C95":4,"\u2C97":0,"\u2C99":[{"\u0300":[{"0":6}]},4],"\u2C9B":[{"\u0300":[{"0":6}]},4],"\u2CAD":4,"\u2CA1":4,"\u2CA3":0,"\u2CA5":4,"\u2CA7":4,"\u03E5":4,"\u03ED":4,"\u03E3":4,".":4,"\u2CAF":[{"0":5}],"\u2C91":[{"0":5}],"\u2C9D":[{"0":5}],"\u2CAB":[{"0":5}],"\u03E9":[{"0":5}],"\u03EB":[{"0":5}],"\u2CC9":[{"0":5}],"\u03EF":[{"0":5}]},3],"\u2C85":[{"\u2C83":4,"\u2C85":4,"\u2C87":4,"\u2C8D":4,"\u03E7":4,"\u2C95":4,"\u2C97":0,"\u2C99":[{"\u0300":[{"0":6}]},4],"\u2C9B":[{"\u0300":[{"0":6}]},4],"\u2CAD":4,"\u2CA1":4,"\u2CA3":0,"\u2CA5":4,"\u2CA7":4,"\u03E5":4,"\u03ED":4,"\u03E3":4,".":4,"\u2CAF":[{"0":5}],"\u2C91":[{"0":5}],"\u2C9D":[{"0":5}],"\u2CAB":[{"0":5}],"\u03E9":[{"0":5}],"\u03EB":[{"0":5}],"\u2CC9":[{"0":5}],"\u03EF":[{"0":5}]},3],"\u2C87":[{"\u2C83":4,"\u2C85":4,"\u2C87":4,"\u2C8D":4,"\u03E7":0,"\u2C95":4,"\u2C97":4,"\u2C99":[{"\u0300":[{"0":6}]},4],"\u2C9B":[{"\u0300":[{"0":6}]},4],"\u2CAD":4,"\u2CA1":4,"\u2CA3":0,"\u2CA5":4,"\u2CA7":4,"\u03E5":4,"\u03ED":4,"\u03E3":4,".":4,"\u2CAF":[{"0":5}],"\u2C91":[{"0":5}],"\u2C9D":[{"0":5}],"\u2CAB":[{"0":5}],"\u03E9":[{"0":5}],"\u03EB":[{"0":5}],"\u2CC9":[{"0":5}],"\u03EF":[{"0":5}]},3],"\u2C8D":[{"\u2C83":4,"\u2C85":4,"\u2C87":4,"\u2C8D":4,"\u03E7":4,"\u2C95":4,"\u2C97":4,"\u2C99":[{"\u0300":[{"0":6}]},4],"\u2C9B":[{"\u0300":[{"0":6}]},4],"\u2CAD":4,"\u2CA1":4,"\u2CA3":4,"\u2CA5":4,"\u2CA7":4,"\u03E5":4,"\u03ED":4,"\u03E3":4,".":4,"\u2CAF":[{"0":5}],"\u2C91":[{"0":5}],"\u2C9D":[{"0":5}],"\u2CAB":[{"0":5}],"\u03E9":[{"0":5}],"\u03EB":[{"0":5}],"\u2CC9":[{"0":5}],"\u03EF":[{"0":5}]},3],"\u03E7":[{"\u2C83":4,"\u2C85":4,"\u2C87":4,"\u2C8D":4,"\u03E7":4,"\u2C95":4,"\u2C97":0,"\u2C99":[{"\u0300":[{"0":6}]},4],"\u2C9B":[{"\u0300":[{"0":6}]},0],"\u2CAD":4,"\u2CA1":4,"\u2CA3":4,"\u2CA5":4,"\u2CA7":4,"\u03E5":4,"\u03ED":4,"\u03E3":4,".":4,"\u2CAF":[{"0":5}],"\u2C91":[{"0":5}],"\u2C9D":[{"0":5}],"\u2CAB":[{"0":5}],"\u03E9":[{"0":5}],"\u03EB":[{"0":5}],"\u2CC9":[{"0":5}],"\u03EF":[{"0":5}]},3],"\u2C95":[{"\u2C83":4,"\u2C85":4,"\u2C87":4,"\u2C8D":4,"\u03E7":4,"\u2C95":4,"\u2C97":0,"\u2C99":[{"\u0300":[{"0":6}]},4],"\u2C9B":[{"\u0300":[{"0":6}]},4],"\u2CAD":4,"\u2CA1":4,"\u2CA3":0,"\u2CA5":4,"\u2CA7":0,"\u03E5":4,"\u03ED":4,"\u03E3":4,".":4,"\u2CAF":[{"0":5}],"\u2C91":[{"0":5}],"\u2C9D":[{"0":5}],"\u2CAB":[{"0":5}],"\u03E9":[{"0":5}],"\u03EB":[{"0":5}],"\u2CC9":[{"0":5}],"\u03EF":[{"0":5}]},3],"\u2C97":[{"\u2C83":4,"\u2C85":4,"\u2C87":4,"\u2C8D":4,"\u03E7":4,"\u2C95":4,"\u2C97":4,"\u2C99":[{"\u0300":[{"0":6}]},4],"\u2C9B":[{"\u0300":[{"0":6}]},4],"\u2CAD":4,"\u2CA1":4,"\u2CA3":4,"\u2CA5":4,"\u2CA7":4,"\u03E5":4,"\u03ED":4,"\u03E3":4,".":4,"\u2CAF":[{"0":5}],"\u2C91":[{"0":5}],"\u2C9D":[{"0":5}],"\u2CAB":[{"0":5}],"\u03E9":[{"0":5}],"\u03EB":[{"0":5}],"\u2CC9":[{"0":5}],"\u03EF":[{"0":5}]},3],"\u2C99":[{"\u2C83":4,"\u2C85":4,"\u2C87":4,"\u2C8D":4,"\u03E7":4,"\u2C95":4,"\u2C97":4,"\u2C99":[{"\u0300":[{"0":6}]},4],"\u2C9B":[{"\u0300":[{"0":6}]},4],"\u2CAD":4,"\u2CA1":4,"\u2CA3":4,"\u2CA5":4,"\u2CA7":4,"\u03E5":4,"\u03ED":4,"\u03E3":4,".":4,"\u2CAF":[{"0":5}],"\u2C91":[{"0":5}],"\u2C9D":[{"0":5}],"\u2CAB":[{"0":5}],"\u03E9":[{"0":5}],"\u03EB":[{"0":5}],"\u2CC9":[{"0":5}],"\u03EF":[{"0":5}],"\u0300":[{"0":[{".":4}],"\u2C83":8,"\u2C85":8,"\u2C87":8,"\u03E7":8,"\u2C95":8,"\u2C97":8,"\u2C99":8,"\u2C9B":8,"\u2CAD":8,"\u2CA1":8,"\u2CA3":8,"\u2CA5":8,"\u2CA7":8,"\u03E5":8,"\u03ED":8,"\u03E3":8}]},3],"\u2C9B":[{"\u2C83":4,"\u2C85":4,"\u2C87":4,"\u2C8D":4,"\u03E7":4,"\u2C95":4,"\u2C97":4,"\u2C99":[{"\u0300":[{"0":6}]},4],"\u2C9B":[{"\u0300":[{"0":6}]},4],"\u2CAD":4,"\u2CA1":4,"\u2CA3":4,"\u2CA5":4,"\u2CA7":4,"\u03E5":4,"\u03ED":4,"\u03E3":4,".":4,"\u2CAF":[{"0":5}],"\u2C91":[{"0":5}],"\u2C9D":[{"0":5}],"\u2CAB":[{"0":5}],"\u03E9":[{"0":5}],"\u03EB":[{"0":5}],"\u2CC9":[{"0":5}],"\u03EF":[{"0":5}],"\u0300":[{"0":[{".":4}],"\u2C83":8,"\u2C85":8,"\u2C87":8,"\u03E7":8,"\u2C95":8,"\u2C97":8,"\u2C99":8,"\u2C9B":8,"\u2CAD":8,"\u2CA1":8,"\u2CA3":8,"\u2CA5":8,"\u2CA7":8,"\u03E5":8,"\u03ED":8,"\u03E3":8}]},3],"\u2CAD":[{"\u2C83":4,"\u2C85":4,"\u2C87":4,"\u2C8D":4,"\u03E7":4,"\u2C95":4,"\u2C97":4,"\u2C99":[{"\u0300":[{"0":6}]},4],"\u2C9B":[{"\u0300":[{"0":6}]},4],"\u2CAD":4,"\u2CA1":4,"\u2CA3":4,"\u2CA5":4,"\u2CA7":4,"\u03E5":4,"\u03ED":4,"\u03E3":4,".":4,"\u2CAF":[{"0":5}],"\u2C91":[{"0":5}],"\u2C9D":[{"0":5}],"\u2CAB":[{"0":5}],"\u03E9":[{"0":5}],"\u03EB":[{"0":5}],"\u2CC9":[{"0":5}],"\u03EF":[{"0":5}]},3],"\u2CA1":[{"\u2C83":4,"\u2C85":4,"\u2C87":4,"\u2C8D":4,"\u03E7":4,"\u2C95":4,"\u2C97":0,"\u2C99":[{"\u0300":[{"0":6}]},4],"\u2C9B":[{"\u0300":[{"0":6}]},0],"\u2CAD":4,"\u2CA1":4,"\u2CA3":0,"\u2CA5":4,"\u2CA7":0,"\u03E5":4,"\u03ED":4,"\u03E3":4,".":4,"\u2CAF":[{"0":5}],"\u2C91":[{"0":5}],"\u2C9D":[{"0":5}],"\u2CAB":[{"0":5}],"\u03E9":[{"0":5}],"\u03EB":[{"0":5}],"\u2CC9":[{"0":5}],"\u03EF":[{"0":5}]},3],"\u2CA3":[{"\u2C83":4,"\u2C85":4,"\u2C87":4,"\u2C8D":4,"\u03E7":4,"\u2C95":4,"\u2C97":4,"\u2C99":[{"\u0300":[{"0":6}]},4],"\u2C9B":[{"\u0300":[{"0":6}]},4],"\u2CAD":4,"\u2CA1":4,"\u2CA3":4,"\u2CA5":4,"\u2CA7":4,"\u03E5":4,"\u03ED":4,"\u03E3":4,".":4,"\u2CAF":[{"0":5}],"\u2C91":[{"0":5}],"\u2C9D":[{"0":5}],"\u2CAB":[{"0":5}],"\u03E9":[{"0":5}],"\u03EB":[{"0":5}],"\u2CC9":[{"0":5}],"\u03EF":[{"0":5}]},3],"\u2CA5":[{"\u2C83":0,"\u2C85":0,"\u2C87":0,"\u2C8D":4,"\u03E7":4,"\u2C95":0,"\u2C97":0,"\u2C99":[{"\u0300":[{"0":6}]},0],"\u2C9B":[{"\u0300":[{"0":6}]},0],"\u2CAD":4,"\u2CA1":0,"\u2CA3":0,"\u2CA5":4,"\u2CA7":0,"\u03E5":0,"\u03ED":4,"\u03E3":4,".":4,"\u2CAF":[{"0":5}],"\u2C91":[{"0":5}],"\u2C9D":[{"0":5}],"\u2CAB":[{"0":5}],"\u03E9":[{"0":5}],"\u03EB":[{"0":5}],"\u2CC9":[{"0":5}],"\u03EF":[{"0":5}]},3],"\u2CA7":[{"\u2C83":4,"\u2C85":4,"\u2C87":4,"\u2C8D":0,"\u03E7":[{".":10},0],"\u2C95":4,"\u2C97":4,"\u2C99":[{"\u0300":[{"0":6}]},0],"\u2C9B":[{"\u0300":[{"0":6}]},4],"\u2CAD":4,"\u2CA1":4,"\u2CA3":0,"\u2CA5":0,"\u2CA7":4,"\u03E5":4,"\u03ED":4,"\u03E3":4,".":4,"\u2CAF":[{"0":5}],"\u2C91":[{"0":5}],"\u2C9D":[{"0":5}],"\u2CAB":[{"0":5}],"\u03E9":[{"0":5}],"\u03EB":[{"0":5}],"\u2CC9":[{"0":5}],"\u03EF":[{"0":5}]},3],"\u03E5":[{"\u2C83":4,"\u2C85":4,"\u2C87":4,"\u2C8D":4,"\u03E7":4,"\u2C95":4,"\u2C97":0,"\u2C99":[{"\u0300":[{"0":6}]},4],"\u2C9B":[{"\u0300":[{"0":6}]},4],"\u2CAD":4,"\u2CA1":4,"\u2CA3":0,"\u2CA5":4,"\u2CA7":0,"\u03E5":4,"\u03ED":4,"\u03E3":4,".":4,"\u2CAF":[{"0":5}],"\u2C91":[{"0":5}],"\u2C9D":[{"0":5}],"\u2CAB":[{"0":5}],"\u03E9":[{"0":5}],"\u03EB":[{"0":5}],"\u2CC9":[{"0":5}],"\u03EF":[{"0":5}]},3],"\u03ED":[{"\u2C83":4,"\u2C85":4,"\u2C87":4,"\u2C8D":4,"\u03E7":0,"\u2C95":4,"\u2C97":0,"\u2C99":[{"\u0300":[{"0":6}]},4],"\u2C9B":[{"\u0300":[{"0":6}]},0],"\u2CAD":4,"\u2CA1":4,"\u2CA3":0,"\u2CA5":4,"\u2CA7":0,"\u03E5":4,"\u03ED":4,"\u03E3":4,".":4,"\u2CAF":[{"0":5}],"\u2C91":[{"0":5}],"\u2C9D":[{"0":5}],"\u2CAB":[{"0":5}],"\u03E9":[{"0":5}],"\u03EB":[{"0":5}],"\u2CC9":[{"0":5}],"\u03EF":[{"0":5}]},3],"\u03E3":[{"\u2C83":4,"\u2C85":4,"\u2C87":4,"\u2C8D":4,"\u03E7":4,"\u2C95":4,"\u2C97":4,"\u2C99":[{"\u0300":[{"0":6}]},4],"\u2C9B":[{"\u0300":[{"0":6}]},4],"\u2CAD":4,"\u2CA1":4,"\u2CA3":4,"\u2CA5":4,"\u2CA7":4,"\u03E5":4,"\u03ED":4,"\u03E3":4,".":4,"\u2CAF":[{"0":5}],"\u2C91":[{"0":5}],"\u2C9D":[{"0":5}],"\u2CAB":[{"0":5}],"\u03E9":[{"0":5}],"\u03EB":[{"0":5}],"\u2CC9":[{"0":5}],"\u03EF":[{"0":5}]},3],"\u2C93":[{"\u0308":[{"0":[{".":3},3]}]}],"\u2CA9":[{"\u0308":[{"0":[{".":3},3]}]}],"\u03E9":[{"0":[{".":4},9],"\u2CA3":5}],"\u2CAB":[{"0":[{".":4},3]}],"\u2C9D":[{"0":[{".":4},3]}],"\u2C91":[{"0":[{".":4},3]}],"\u2CAF":[{"0":[{".":4},3]}],"\u03EB":[{"0":[{".":4},3]}],"\u2C8F":[{"\u03E7":[{"0":[{".":10},6]}],"\u2CC9":[{"0":[{".":10},11]}],"\u2C81":12,"\u2C89":12,"\u2C9F":[{"\u2CA9":12},12],"\u2CB1":12,"\u2C93":[{"\u2C81":12,"\u2C89":12,"\u2C9F":12,"\u2CB1":12}]}],"\u2CC9":[{"0":[{".":4},9]}],"\u03EF":[{"0":[{".":4},3]}],"\u2C81":[{"\u2C89":[{"\u2C93":13},12],"\u2C9F":[{"\u2CA9":0},12],"\u2C8F":12,"\u2CB1":12,"\u2C93":[{"\u2C81":12,"\u2C89":12,"\u2C9F":12,"\u2CB1":12}]}],"\u2C89":[{"\u2C81":12,"\u2C9F":[{"\u2CA9":0},12],"\u2C8F":12,"\u2CB1":12,"\u2C93":0}],"\u2C9F":[{"\u2C81":12,"\u2C89":12,"\u2C8F":12,"\u2CB1":12,"\u2C93":[{"\u2C81":12,"\u2C89":12,"\u2C9F":12,"\u2CB1":12}],"\u2C9F":[{"\u2CA9":0}],"\u2CA9":[{"\u2C81":1,"\u2C89":1,"\u2C8F":1,"\u2C9F":1,"\u2CA9":1,"\u2CB1":1,"\u2C93":1}]}],"\u2CB1":[{"\u2C9F":[{"\u2CA9":12}]}]}',
8
+ []
9
+ ];
10
+
11
+ export { Cop };
@@ -0,0 +1,75 @@
1
+ import { FronteraClient } from '@frontera-sdk/core/client';
2
+
3
+ /**
4
+ * How a component gets its credential.
5
+ *
6
+ * Four shapes, ordered by how much the caller wants to manage. Every chat
7
+ * component in this package accepts the same union, so moving between
8
+ * `FronteraChat`, `FronteraChatFrame` and the script embed is a change of
9
+ * component, not of plumbing.
10
+ */
11
+ type ChatCredentialProps = {
12
+ /**
13
+ * An endpoint on YOUR site returning `{ token, expiresAt }` for whoever
14
+ * is signed in. Called same-origin, so your session cookie identifies
15
+ * them, and refreshed automatically before expiry.
16
+ *
17
+ * The recommended shape: nothing to manage, and tokens stay short-lived
18
+ * without the caller having to think about it.
19
+ */
20
+ tokenEndpoint: string;
21
+ apiBaseUrl?: string;
22
+ token?: never;
23
+ getToken?: never;
24
+ client?: never;
25
+ } | {
26
+ /**
27
+ * A token you already hold. You then own replacing it before it expires
28
+ * — pass `tokenEndpoint` instead to be rid of that.
29
+ */
30
+ token: string;
31
+ apiBaseUrl: string;
32
+ tokenEndpoint?: never;
33
+ getToken?: never;
34
+ client?: never;
35
+ } | {
36
+ /** Fetch the token however you like; called again on refresh. */
37
+ getToken: () => Promise<{
38
+ token: string;
39
+ expiresAt: string;
40
+ apiBaseUrl?: string;
41
+ }>;
42
+ apiBaseUrl?: string;
43
+ tokenEndpoint?: never;
44
+ token?: never;
45
+ client?: never;
46
+ } | {
47
+ /**
48
+ * A client you built yourself. Pass a getter if you rotate tokens.
49
+ *
50
+ * The getter may return null: `useChatCredential` itself returns one that
51
+ * is null until the first token lands, and forcing callers to cast that
52
+ * away would push a lie into every app that shares one credential
53
+ * between the chat and its own sidebar.
54
+ */
55
+ client: FronteraClient | (() => FronteraClient | null);
56
+ tokenEndpoint?: never;
57
+ token?: never;
58
+ getToken?: never;
59
+ apiBaseUrl?: never;
60
+ };
61
+ interface ResolvedCredential {
62
+ /** The current client, or null until the first token arrives. */
63
+ getClient: () => FronteraClient | null;
64
+ ready: boolean;
65
+ error: Error | null;
66
+ /**
67
+ * Force a new credential now. Wired to the transport's 401 handler, so a
68
+ * token that expired while the tab slept costs a retry rather than a visible
69
+ * failure.
70
+ */
71
+ refresh: () => Promise<unknown>;
72
+ }
73
+ declare function useChatCredential(props: ChatCredentialProps): ResolvedCredential;
74
+
75
+ export { type ChatCredentialProps, type ResolvedCredential, useChatCredential };
@@ -0,0 +1,3 @@
1
+ 'use client';
2
+ export { useChatCredential } from './chunk-BEJ3HQG4.js';
3
+ import './chunk-PR4QN5HX.js';