@burdenoff/fe-libs 2026.1014.2 → 2026.1014.4

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.
@@ -3,29 +3,33 @@ import { SHELL_OVERLAY_LAYER_CLASS as t } from "../shellOverlayLayer.js";
3
3
  import { jsx as n, jsxs as r } from "react/jsx-runtime";
4
4
  import { createPortal as i } from "react-dom";
5
5
  //#region src/chrome/notificationCenter/NotificationPanel.tsx
6
- var a = ({ isMobile: a, onClose: o, children: s }) => a ? typeof document > "u" ? null : i(/* @__PURE__ */ n(e, {
7
- onDismiss: o,
6
+ var a = "calc(max(var(--safe-top, 0px), env(safe-area-inset-top, 0px)) + var(--native-topbar-height, 0px))", o = {
7
+ top: a,
8
+ maxHeight: `calc(100dvh - ${a} - max(var(--mobile-tabbar-height, 0px), var(--safe-bottom, 0px), env(safe-area-inset-bottom, 0px)))`
9
+ }, s = ({ isMobile: a, onClose: s, children: c }) => a ? typeof document > "u" ? null : i(/* @__PURE__ */ n(e, {
10
+ onDismiss: s,
8
11
  children: /* @__PURE__ */ r("div", {
9
12
  className: `fixed inset-0 ${t}`,
10
13
  role: "dialog",
11
14
  "aria-label": "Notifications panel",
12
15
  children: [/* @__PURE__ */ n("div", {
13
16
  className: "absolute inset-0 bg-bg-overlay backdrop-blur-sm",
14
- onClick: o,
17
+ onClick: s,
15
18
  "aria-hidden": "true"
16
19
  }), /* @__PURE__ */ n("div", {
17
- className: "absolute inset-0 bg-bg-elevated flex flex-col",
18
- children: s
20
+ className: "absolute inset-x-0 flex flex-col overflow-hidden bg-bg-elevated rounded-b-2xl shadow-[var(--shadow-elevation-4)]",
21
+ style: o,
22
+ children: c
19
23
  })]
20
24
  })
21
25
  }), document.body) : /* @__PURE__ */ n(e, {
22
- onDismiss: o,
26
+ onDismiss: s,
23
27
  children: /* @__PURE__ */ n("div", {
24
28
  className: "absolute right-0 top-full mt-2 w-[calc(100vw-1.5rem)] sm:w-[420px] max-h-[600px] bg-bg-elevated border border-border-subtle rounded-card shadow-[var(--shadow-elevation-4)] z-50 overflow-hidden flex flex-col",
25
29
  role: "dialog",
26
30
  "aria-label": "Notifications panel",
27
- children: s
31
+ children: c
28
32
  })
29
33
  });
30
34
  //#endregion
31
- export { a as NotificationPanel };
35
+ export { s as NotificationPanel };
@@ -6,10 +6,15 @@ export declare const AVATAR_API_PATH = "/api/avatar/v1";
6
6
  * credentials in it, or plain `http:` off a loopback host). A relative endpoint is resolved against `locationHref`.
7
7
  */
8
8
  export declare function avatarApiBaseFromTtsEndpoint(ttsEndpoint: string | null | undefined, locationHref?: string): string | null;
9
+ /**
10
+ * Why nothing is offered, coarse on purpose (§3.3). The server's: no verified workspace reached it, or the avatar is not enabled for this
11
+ * caller. The gateway's edge check (`assistant:use` in the workspace): not permitted, or it could not be checked (`unavailable`).
12
+ */
13
+ declare const AVAILABILITY_REASONS: readonly ["workspace_context_required", "not_enabled", "not_permitted", "unavailable"];
14
+ export type AvatarAvailabilityReason = (typeof AVAILABILITY_REASONS)[number];
9
15
  export interface AvatarAvailability {
10
16
  readonly available: boolean;
11
- /** Coarse on purpose (§3.3): no verified workspace reached the server, or the avatar is not enabled for this caller. */
12
- readonly reason: 'workspace_context_required' | 'not_enabled' | null;
17
+ readonly reason: AvatarAvailabilityReason | null;
13
18
  /** Approved and provider-ready ids; names and pictures are the client's. */
14
19
  readonly avatars: readonly string[];
15
20
  /** The disclosure version the client must show and echo back on create. */
@@ -55,15 +60,18 @@ export interface AvatarSessionClientOptions {
55
60
  readonly getAuthorization: () => string | null;
56
61
  /**
57
62
  * The workspace token as an `X-Workspace-Authorization` value (`Bearer …`), or null when none can be had. `fresh`: the gateway refused
58
- * the last one, mint it again instead of reusing a stored one.
63
+ * the last request (401), so not the token it carried: `refused`, as it was sent (absent when it carried none).
59
64
  */
60
65
  readonly getWorkspaceAuthorization: (options: {
61
66
  readonly fresh: boolean;
67
+ readonly refused?: string;
62
68
  }) => Promise<string | null>;
63
69
  readonly fetchImpl?: typeof fetch;
64
70
  /** Waits between the contract's retries; injectable for tests. */
65
71
  readonly sleep?: (ms: number) => Promise<void>;
66
- /** How long 409 `start_in_progress` may be retried with the same key before giving up. */
72
+ /** Wall-clock milliseconds, for the start budget; injectable for tests, with `sleep`. */
73
+ readonly now?: () => number;
74
+ /** How long 409 `start_in_progress` may be retried with the same key, its waits included, before giving up. */
67
75
  readonly startInProgressBudgetMs?: number;
68
76
  }
69
77
  export interface AvatarSessionClient {
@@ -85,12 +93,22 @@ export declare function avatarIdempotencyKey(random?: Crypto | undefined): strin
85
93
  export declare function createAvatarSessionClient(options: AvatarSessionClientOptions): AvatarSessionClient;
86
94
  /** What the avatar UI does with a refusal: what to tell the person, and whether to stop offering the toggle for this page. */
87
95
  export interface AvatarRefusal {
88
- readonly problem: AvatarProblem;
89
- /** The avatar is not offered here at all (404, 403 not allowed, no workspace): hide the toggle until the next page load. */
96
+ /** Null only with `showDisclosure`: the disclosure itself is what the person is shown. */
97
+ readonly problem: AvatarProblem | null;
98
+ /** Not offered here at all (404, 403 not allowed or not permitted, no workspace): hide the toggle until the next page load. */
90
99
  readonly hide: boolean;
100
+ /** The server's disclosure version changed (`consent_required`): ask availability again, show the disclosure to confirm again. */
101
+ readonly showDisclosure?: true;
91
102
  }
92
103
  /**
93
104
  * The person's side of every failure (§3.4): the normal voice always continues; this says what to show. 404 means "not here" (the module
94
- * or the route is off), 403 "not for you", 429/503 "not now".
105
+ * or the route is off), 403 "not for you", 429/503 "not now". Every code the avatar module (`errors.ts`) and the gateway's proxy
106
+ * (`avatar-proxy.ts`) answer is named below; anything else is a problem of ours, not the person's.
95
107
  */
96
108
  export declare function avatarRefusalFor(error: unknown): AvatarRefusal;
109
+ /**
110
+ * The person's side of an availability answer that offers nothing: not offered here, so the toggle goes (no verified workspace, not
111
+ * enabled, not permitted), or only not now when the gateway could not check the permission (`unavailable`): the toggle stays.
112
+ */
113
+ export declare function avatarAvailabilityRefusal(reason: AvatarAvailabilityReason | null): AvatarRefusal;
114
+ export {};
@@ -14,7 +14,12 @@ function a(n, r) {
14
14
  }
15
15
  return i.username !== "" || i.password !== "" || i.protocol === "http:" && !t.has(i.hostname.toLowerCase()) || i.protocol !== "https:" && i.protocol !== "http:" ? null : `${i.protocol}//${i.host}${e}`;
16
16
  }
17
- var o = class extends Error {
17
+ var o = [
18
+ "workspace_context_required",
19
+ "not_enabled",
20
+ "not_permitted",
21
+ "unavailable"
22
+ ], s = class extends Error {
18
23
  status;
19
24
  code;
20
25
  retryAfterSeconds;
@@ -22,7 +27,7 @@ var o = class extends Error {
22
27
  super(`avatar api ${e} ${t}`), this.status = e, this.code = t, this.retryAfterSeconds = n, this.name = "AvatarApiError";
23
28
  }
24
29
  };
25
- function s(e = globalThis.crypto) {
30
+ function c(e = globalThis.crypto) {
26
31
  if (e && typeof e.randomUUID == "function") return e.randomUUID();
27
32
  let t = new Uint8Array(16);
28
33
  if (e && typeof e.getRandomValues == "function") e.getRandomValues(t);
@@ -31,38 +36,38 @@ function s(e = globalThis.crypto) {
31
36
  let n = [...t].map((e) => e.toString(16).padStart(2, "0")).join("");
32
37
  return `${n.slice(0, 8)}-${n.slice(8, 12)}-${n.slice(12, 16)}-${n.slice(16, 20)}-${n.slice(20)}`;
33
38
  }
34
- function c(e) {
39
+ function l(e) {
35
40
  return typeof e == "object" && !!e && !Array.isArray(e);
36
41
  }
37
- function l(e, t) {
42
+ function u(e, t) {
38
43
  let n = e.headers.get("retry-after"), r = n === null || n.trim() === "" ? NaN : Number(n);
39
44
  if (Number.isFinite(r) && r >= 0) return r;
40
- let i = c(t) && c(t.error) ? Number(t.error.retryAfterSeconds) : NaN;
45
+ let i = l(t) && l(t.error) ? Number(t.error.retryAfterSeconds) : NaN;
41
46
  return Number.isFinite(i) && i >= 0 ? i : null;
42
47
  }
43
- async function u(e) {
48
+ async function d(e) {
44
49
  try {
45
50
  return await e.json();
46
51
  } catch {
47
52
  return null;
48
53
  }
49
54
  }
50
- async function d(e) {
51
- let t = await u(e), n = c(t) && c(t.error) && typeof t.error.code == "string" ? t.error.code : "http_error";
52
- return new o(e.status, n, l(e, t));
55
+ async function f(e) {
56
+ let t = await d(e), n = l(t) && l(t.error) && typeof t.error.code == "string" ? t.error.code : "http_error";
57
+ return new s(e.status, n, u(e, t));
53
58
  }
54
- function f(e) {
55
- if (!c(e) || typeof e.available != "boolean") throw new o(200, "invalid_response", null);
56
- let t = Array.isArray(e.avatars) ? e.avatars.flatMap((e) => c(e) && typeof e.id == "string" && r.test(e.id) ? [e.id] : []) : [], n = e.reason === "workspace_context_required" || e.reason === "not_enabled" ? e.reason : null, i = typeof e.consentVersion == "string" ? e.consentVersion : "", a = typeof e.maxSessionSeconds == "number" && Number.isFinite(e.maxSessionSeconds) ? e.maxSessionSeconds : 0, s = e.available && t.length > 0 && i !== "" && a > 0;
59
+ function p(e) {
60
+ if (!l(e) || typeof e.available != "boolean") throw new s(200, "invalid_response", null);
61
+ let t = Array.isArray(e.avatars) ? e.avatars.flatMap((e) => l(e) && typeof e.id == "string" && r.test(e.id) ? [e.id] : []) : [], n = o.find((t) => t === e.reason) ?? null, i = typeof e.consentVersion == "string" ? e.consentVersion : "", a = typeof e.maxSessionSeconds == "number" && Number.isFinite(e.maxSessionSeconds) ? e.maxSessionSeconds : 0, c = e.available && t.length > 0 && i !== "" && a > 0;
57
62
  return {
58
- available: s,
59
- reason: s ? null : n ?? "not_enabled",
63
+ available: c,
64
+ reason: c ? null : n ?? "not_enabled",
60
65
  avatars: t,
61
66
  consentVersion: i,
62
67
  maxSessionSeconds: a
63
68
  };
64
69
  }
65
- function p(e) {
70
+ function m(e) {
66
71
  try {
67
72
  let n = new URL(e);
68
73
  return n.protocol === "wss:" ? !0 : n.protocol === "ws:" && t.has(n.hostname.toLowerCase());
@@ -70,10 +75,10 @@ function p(e) {
70
75
  return !1;
71
76
  }
72
77
  }
73
- function m(e) {
74
- if (!c(e)) throw new o(201, "invalid_response", null);
75
- let { sessionId: t, livekitUrl: r, participantToken: i, avatarIdentity: a, connectBy: s, endsAt: l } = e, u = typeof s == "string" ? Date.parse(s) : NaN, d = typeof l == "string" ? Date.parse(l) : NaN;
76
- if (typeof t != "string" || !n.test(t) || typeof r != "string" || !p(r) || typeof i != "string" || i === "" || typeof a != "string" || a === "" || !Number.isFinite(u) || !Number.isFinite(d)) throw new o(201, "invalid_response", null);
78
+ function h(e) {
79
+ if (!l(e)) throw new s(201, "invalid_response", null);
80
+ let { sessionId: t, livekitUrl: r, participantToken: i, avatarIdentity: a, connectBy: o, endsAt: c } = e, u = typeof o == "string" ? Date.parse(o) : NaN, d = typeof c == "string" ? Date.parse(c) : NaN;
81
+ if (typeof t != "string" || !n.test(t) || typeof r != "string" || !m(r) || typeof i != "string" || i === "" || typeof a != "string" || a === "" || !Number.isFinite(u) || !Number.isFinite(d)) throw new s(201, "invalid_response", null);
77
82
  return {
78
83
  sessionId: t,
79
84
  livekitUrl: r,
@@ -83,7 +88,7 @@ function m(e) {
83
88
  endsAt: d
84
89
  };
85
90
  }
86
- var h = [
91
+ var g = [
87
92
  "starting",
88
93
  "ready",
89
94
  "ending",
@@ -91,62 +96,77 @@ var h = [
91
96
  "failed",
92
97
  "canceled"
93
98
  ];
94
- function g(e, t) {
95
- if (!c(e) || !h.includes(e.state)) throw new o(200, "invalid_response", null);
99
+ function _(e, t) {
100
+ if (!l(e) || !g.includes(e.state)) throw new s(200, "invalid_response", null);
96
101
  return {
97
102
  sessionId: t,
98
103
  state: e.state,
99
104
  endedReason: typeof e.endedReason == "string" ? e.endedReason : null
100
105
  };
101
106
  }
102
- var _ = (e) => new Promise((t) => {
107
+ var v = (e) => new Promise((t) => {
103
108
  setTimeout(t, e);
104
109
  });
105
- function v(e) {
106
- let t = e.fetchImpl ?? ((e, t) => fetch(e, t)), a = e.sleep ?? _, s = e.startInProgressBudgetMs ?? 15e3, c = e.baseUrl.replace(/\/+$/, "");
107
- async function l(t, n) {
110
+ function y(e) {
111
+ let t = e.fetchImpl ?? ((e, t) => fetch(e, t)), a = e.sleep ?? v, o = e.now ?? (() => Date.now()), c = e.startInProgressBudgetMs ?? 15e3, l = e.baseUrl.replace(/\/+$/, "");
112
+ async function u(t, n = null) {
108
113
  let r = e.getAuthorization();
109
- if (!r) throw new o(401, "unauthenticated", null);
114
+ if (!r) throw new s(401, "unauthenticated", null);
110
115
  let i = { authorization: r };
111
116
  if (t) {
112
- let t = await e.getWorkspaceAuthorization({ fresh: n });
117
+ let t = await e.getWorkspaceAuthorization(n === null ? { fresh: !1 } : {
118
+ fresh: !0,
119
+ ...n.workspace ? { refused: n.workspace } : {}
120
+ });
121
+ if (n !== null && (!t || t === n.workspace)) throw n.error;
113
122
  t && (i["x-workspace-authorization"] = t);
114
123
  }
115
124
  return i;
116
125
  }
117
- async function p(e, n) {
126
+ async function m(e, n) {
118
127
  try {
119
128
  return await t(e, {
120
129
  ...n,
121
- credentials: "omit",
122
- cache: "no-store"
130
+ credentials: "same-origin",
131
+ cache: "no-store",
132
+ redirect: "error"
123
133
  });
124
134
  } catch (e) {
125
- throw n.signal?.aborted ? e : new o(0, "network", null);
135
+ throw n.signal?.aborted ? e : new s(0, "network", null);
126
136
  }
127
137
  }
128
138
  return {
129
139
  async availability(e) {
130
- for (let t = 1;; t += 1) {
131
- let n = await l(!0, t > 1), r = await p(`${c}/availability`, {
140
+ let t = null;
141
+ for (;;) {
142
+ let n = await u(!0, t), r = await m(`${l}/availability`, {
132
143
  method: "GET",
133
144
  headers: n,
134
145
  signal: e
135
146
  });
136
- if (r.ok) return f(await u(r));
137
- if (!(r.status === 401 && t === 1)) throw await d(r);
147
+ if (r.ok) return p(await d(r));
148
+ let i = await f(r);
149
+ if (r.status === 401 && t === null) {
150
+ t = {
151
+ error: i,
152
+ workspace: n["x-workspace-authorization"]
153
+ };
154
+ continue;
155
+ }
156
+ throw i;
138
157
  }
139
158
  },
140
159
  async create(e, t) {
141
- if (!r.test(e.avatarId) || !i.test(e.idempotencyKey)) throw new o(400, "invalid_request", null);
160
+ if (!r.test(e.avatarId) || !i.test(e.idempotencyKey)) throw new s(400, "invalid_request", null);
142
161
  let n = JSON.stringify({
143
162
  avatarId: e.avatarId,
144
163
  consentVersion: e.consentVersion
145
- }), f = Date.now(), h = !1, g = !1;
164
+ }), p = o(), g = null, _ = !1, v = !1, y = null;
146
165
  for (;;) {
147
- let r = await l(!0, h);
148
- if (r["x-workspace-authorization"] === void 0) throw new o(403, "workspace_context_required", null);
149
- let i = await p(`${c}/sessions`, {
166
+ let r = await u(!0, g);
167
+ if (g = null, y !== null && o() - p > c) throw y;
168
+ if (r["x-workspace-authorization"] === void 0) throw new s(403, "workspace_context_required", null);
169
+ let i = await m(`${l}/sessions`, {
150
170
  method: "POST",
151
171
  headers: {
152
172
  ...r,
@@ -156,36 +176,41 @@ function v(e) {
156
176
  body: n,
157
177
  signal: t
158
178
  });
159
- if (i.status === 201) return m(await u(i));
160
- let _ = await d(i);
161
- if (i.status === 401 && !h) {
162
- h = !0;
179
+ if (i.status === 201) return h(await d(i));
180
+ let b = await f(i);
181
+ if (i.status === 401 && !_) {
182
+ _ = !0, g = {
183
+ error: b,
184
+ workspace: r["x-workspace-authorization"]
185
+ };
163
186
  continue;
164
187
  }
165
- if (i.status === 409 && _.code === "start_in_progress" && Date.now() - f < s) {
166
- if (await a(Math.max(250, (_.retryAfterSeconds ?? 1) * 1e3)), t?.aborted) throw _;
188
+ if (i.status === 409 && b.code === "start_in_progress") {
189
+ let e = Math.max(250, (b.retryAfterSeconds ?? 1) * 1e3);
190
+ if (o() - p + e > c || (await a(e), t?.aborted)) throw b;
191
+ y = b;
167
192
  continue;
168
193
  }
169
- if (i.status === 502 && !g) {
170
- g = !0;
194
+ if (i.status === 502 && !v) {
195
+ v = !0;
171
196
  continue;
172
197
  }
173
- throw _;
198
+ throw b;
174
199
  }
175
200
  },
176
201
  async status(e, t) {
177
- if (!n.test(e)) throw new o(400, "invalid_request", null);
178
- let r = await l(!1, !1), i = await p(`${c}/sessions/${e}`, {
202
+ if (!n.test(e)) throw new s(400, "invalid_request", null);
203
+ let r = await u(!1), i = await m(`${l}/sessions/${e}`, {
179
204
  method: "GET",
180
205
  headers: r,
181
206
  signal: t
182
207
  });
183
- if (!i.ok) throw await d(i);
184
- return g(await u(i), e);
208
+ if (!i.ok) throw await f(i);
209
+ return _(await d(i), e);
185
210
  },
186
211
  async end(e, { reason: t, keepalive: r = !1 }) {
187
- if (!n.test(e)) throw new o(400, "invalid_request", null);
188
- let i = await l(!1, !1), a = await p(`${c}/sessions/${e}/end`, {
212
+ if (!n.test(e)) throw new s(400, "invalid_request", null);
213
+ let i = await u(!1), a = await m(`${l}/sessions/${e}/end`, {
189
214
  method: "POST",
190
215
  headers: {
191
216
  ...i,
@@ -194,13 +219,13 @@ function v(e) {
194
219
  body: JSON.stringify({ reason: t }),
195
220
  keepalive: r
196
221
  });
197
- if (!a.ok) throw await d(a);
198
- return g(await u(a), e);
222
+ if (!a.ok) throw await f(a);
223
+ return _(await d(a), e);
199
224
  }
200
225
  };
201
226
  }
202
- function y(e) {
203
- if (!(e instanceof o) || e.status === 0) return {
227
+ function b(e) {
228
+ if (!(e instanceof s) || e.status === 0) return {
204
229
  problem: "connection",
205
230
  hide: !1
206
231
  };
@@ -210,10 +235,16 @@ function y(e) {
210
235
  };
211
236
  switch (e.code) {
212
237
  case "avatar_not_allowed":
238
+ case "avatar_not_permitted":
213
239
  case "workspace_context_required": return {
214
240
  problem: "unavailable",
215
241
  hide: !0
216
242
  };
243
+ case "consent_required": return {
244
+ problem: null,
245
+ hide: !1,
246
+ showDisclosure: !0
247
+ };
217
248
  case "avatar_not_approved":
218
249
  case "avatar_not_ready": return {
219
250
  problem: "not-ready",
@@ -228,6 +259,7 @@ function y(e) {
228
259
  case "provider_concurrency_limited":
229
260
  case "provider_no_capacity":
230
261
  case "counters_unavailable":
262
+ case "permission_check_unavailable":
231
263
  case "avatar_busy": return {
232
264
  problem: "capacity",
233
265
  hide: !1
@@ -237,6 +269,11 @@ function y(e) {
237
269
  problem: "rate-limited",
238
270
  hide: !1
239
271
  };
272
+ case "start_budget_exceeded":
273
+ case "start_in_progress": return {
274
+ problem: "start-timeout",
275
+ hide: !1
276
+ };
240
277
  case "avatar_paused":
241
278
  case "budget_exhausted": return {
242
279
  problem: "paused",
@@ -251,11 +288,35 @@ function y(e) {
251
288
  problem: "provider",
252
289
  hide: !1
253
290
  };
291
+ case "authentication_required":
292
+ case "unauthenticated":
293
+ case "untrusted_caller": return {
294
+ problem: "unavailable",
295
+ hide: !1
296
+ };
297
+ case "invalid_request":
298
+ case "method_not_allowed":
299
+ case "request_too_large":
300
+ case "idempotency_key_spent":
301
+ case "idempotency_key_mismatch":
302
+ case "upstream_unavailable": return {
303
+ problem: "provider",
304
+ hide: !1
305
+ };
254
306
  default: return {
255
307
  problem: e.status === 401 ? "unavailable" : "provider",
256
308
  hide: !1
257
309
  };
258
310
  }
259
311
  }
312
+ function x(e) {
313
+ return e === "unavailable" ? {
314
+ problem: "capacity",
315
+ hide: !1
316
+ } : {
317
+ problem: "unavailable",
318
+ hide: !0
319
+ };
320
+ }
260
321
  //#endregion
261
- export { e as AVATAR_API_PATH, o as AvatarApiError, a as avatarApiBaseFromTtsEndpoint, s as avatarIdempotencyKey, y as avatarRefusalFor, v as createAvatarSessionClient };
322
+ export { e as AVATAR_API_PATH, s as AvatarApiError, a as avatarApiBaseFromTtsEndpoint, x as avatarAvailabilityRefusal, c as avatarIdempotencyKey, b as avatarRefusalFor, y as createAvatarSessionClient };
@@ -36,9 +36,14 @@ export declare function liveAvatarAuthorization(): string | null;
36
36
  /**
37
37
  * The workspace token, as the assistant's own calls mint it (`ensureWorkspaceToken`, the workspace gateway): the stored one while it is
38
38
  * valid for the active context (workspace, organisation, project), else a new one. Null when there is no active workspace or no sign-in.
39
- * A retry after a 401 (`fresh`) asks again the same way: the client can see a token's expiry and context, not a revocation.
39
+ *
40
+ * ★ `fresh` (the gateway refused a request with a 401): never the token it carried (`refused`) again. A client sees a token's expiry and
41
+ * context, not its revocation, so it still looks valid here. The mint's issuance guard (the one `prepareWorkspaceRequest` uses) passes
42
+ * it over, keeps the new token to this workspace and this sign-in, and stores it for every other caller. A token another caller stored
43
+ * since the refusal is not the refused one, and is used as it is. Null when none can be had: no retry then.
40
44
  */
41
- export declare function liveAvatarWorkspaceAuthorization(_options: {
45
+ export declare function liveAvatarWorkspaceAuthorization(options: {
42
46
  readonly fresh: boolean;
47
+ readonly refused?: string;
43
48
  }): Promise<string | null>;
44
49
  export declare function createLiveAvatarSeam(options?: LiveAvatarSeamOptions): LiveAvatarSeamHandle;
@@ -28,15 +28,20 @@ function _() {
28
28
  return n ? `Bearer ${n}` : null;
29
29
  }
30
30
  async function v(t) {
31
- let i = n(), a = _()?.replace(/^Bearer\s+/i, "") ?? null;
32
- if (!i || !a) return null;
33
- let o = await e({
31
+ let i = n(), a = _(), o = a?.replace(/^Bearer\s+/i, "") ?? null;
32
+ if (!i || !o) return null;
33
+ let s = t.refused?.replace(/^Bearer\s+/i, ""), c = await e({
34
34
  url: r("workspace"),
35
- authToken: a,
35
+ authToken: o,
36
36
  workspaceId: i,
37
- currentQuery: "liveAvatarSession"
37
+ currentQuery: "liveAvatarSession",
38
+ ...t.fresh ? { issuanceGuard: {
39
+ identityKey: "liveAvatarSession",
40
+ isCurrent: () => n() === i && _() === a,
41
+ accepts: (e, t) => e !== s && t === i
42
+ } } : {}
38
43
  });
39
- return o ? `Bearer ${o}` : null;
44
+ return c ? `Bearer ${c}` : null;
40
45
  }
41
46
  function y() {
42
47
  let e = null;