@zeroweight/react 0.2.30 → 0.2.32

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.
@@ -1,29 +1,29 @@
1
- import { useMemo as be, useRef as m, useState as x, useCallback as S, useEffect as h } from "react";
1
+ import { useMemo as be, useRef as k, useState as x, useCallback as S, useEffect as h } from "react";
2
2
  import { ZeroWeightRenderer as Se, ActionQueue as xe, VoiceActivityDetector as ke } from "@zeroweight/renderer";
3
- import { jsxs as k, jsx as r, Fragment as j } from "react/jsx-runtime";
4
- import { useVoiceAssistant as we, useLocalParticipant as Ae, useIsSpeaking as Te, useDataChannel as Ie, RoomAudioRenderer as Re, LiveKitRoom as Me } from "@livekit/components-react";
3
+ import { jsxs as w, jsx as r, Fragment as j } from "react/jsx-runtime";
4
+ import { useVoiceAssistant as we, useLocalParticipant as Ae, useIsSpeaking as Te, useDataChannel as Ie, RoomAudioRenderer as Ce, LiveKitRoom as Re } from "@livekit/components-react";
5
5
  import "@livekit/components-styles";
6
- import { Loader2 as q, MicOff as Ce, Mic as Ee, Power as Le, Activity as De } from "lucide-react";
6
+ import { Loader2 as J, MicOff as Me, Mic as Ee, Power as Le, Activity as De } from "lucide-react";
7
7
  const ze = 3e4, Pe = 120, Fe = "wss://prod-project-pazuyq69.livekit.cloud", ne = "https://api.zeroweight.ai";
8
8
  function Ue(v) {
9
9
  const {
10
10
  avatarId: a,
11
- apiKey: n = null,
11
+ apiKey: e = null,
12
12
  api: u,
13
13
  turnOffMicWhenAISpeaking: d = !0,
14
- livekitUrl: w = Fe,
14
+ livekitUrl: A = Fe,
15
15
  sessionDuration: p = Pe,
16
- inactivityTimeout: R = ze
17
- } = v, L = w, M = be(() => {
16
+ inactivityTimeout: C = ze
17
+ } = v, D = A, y = be(() => {
18
18
  if (u) return u;
19
- const e = n ? { "X-ZW-Api-Key": n } : void 0;
19
+ const t = e ? { "X-ZW-Api-Key": e } : void 0;
20
20
  return {
21
- getBundle: async (f) => {
21
+ getBundle: async (g) => {
22
22
  const T = await fetch(
23
23
  `${ne}/avatars/bundle/${encodeURIComponent(
24
- f
24
+ g
25
25
  )}`,
26
- { headers: e }
26
+ { headers: t }
27
27
  );
28
28
  if (!T.ok)
29
29
  throw new Error(
@@ -31,13 +31,13 @@ function Ue(v) {
31
31
  );
32
32
  return T.json();
33
33
  },
34
- getLiveKitToken: async (f) => {
34
+ getLiveKitToken: async (g) => {
35
35
  const T = new URLSearchParams({
36
- avatar_id: f,
36
+ avatar_id: g,
37
37
  name: "anonymuous"
38
38
  }), c = await fetch(
39
39
  `${ne}/livekit/token?${T.toString()}`,
40
- { headers: e }
40
+ { headers: t }
41
41
  );
42
42
  if (!c.ok)
43
43
  throw new Error(
@@ -46,133 +46,133 @@ function Ue(v) {
46
46
  return c.json();
47
47
  }
48
48
  };
49
- }, [u, n]), s = m(null), y = m(null), i = m(null), b = m(null), [g, C] = x("idle"), [o, z] = x(null), [A, t] = x(
49
+ }, [u, e]), m = k(null), E = k(null), i = k(null), l = k(null), [b, R] = x("idle"), [f, P] = x(null), [s, U] = x(
50
50
  /* @__PURE__ */ new Set(["listening"])
51
- ), [l, U] = x({
51
+ ), [n, o] = x({
52
52
  listening: { kind: "looped" },
53
53
  speaking: { kind: "looped" }
54
- }), [F, P] = x(!1), [$, J] = x(null), [K, O] = x(!1), [W, Z] = x(!1), [ae, N] = x(p), E = m(null), V = m(() => {
55
- }), [oe, X] = x(!1), [se, Y] = x(0.8), D = m(null), B = g === "ready", G = S(() => {
56
- const e = s.current;
57
- if (!e) return null;
58
- let f = e.querySelector("canvas");
59
- return f || (f = document.createElement("canvas"), f.style.width = "100%", f.style.height = "100%", f.style.display = "block", e.appendChild(f)), y.current = f, f;
54
+ }), [O, z] = x(!1), [F, $] = x(null), [W, K] = x(!1), [N, Z] = x(!1), [ae, V] = x(p), M = k(null), B = k(() => {
55
+ }), [oe, X] = x(!1), [se, Y] = x(0.8), L = k(null), H = b === "ready", G = S(() => {
56
+ const t = m.current;
57
+ if (!t) return null;
58
+ let g = t.querySelector("canvas");
59
+ return g || (g = document.createElement("canvas"), g.style.width = "100%", g.style.height = "100%", g.style.display = "block", t.appendChild(g)), E.current = g, g;
60
60
  }, []);
61
61
  h(() => {
62
- let e = !1;
62
+ let t = !1;
63
63
  return (async () => {
64
64
  const T = G();
65
65
  if (!T) return;
66
66
  const c = new Se();
67
67
  i.current = c;
68
- const Q = new xe((I, _) => {
68
+ const q = new xe((I, _) => {
69
69
  c.play(I, _);
70
70
  });
71
- b.current = Q, c.on("stateChanged", (I) => {
72
- e || C(I);
71
+ l.current = q, c.on("stateChanged", (I) => {
72
+ t || R(I);
73
73
  }), c.on("dimensions", (I, _) => {
74
- e || z({ width: I, height: _ });
74
+ t || P({ width: I, height: _ });
75
75
  }), c.on("actionLoaded", (I) => {
76
- e || t((_) => {
76
+ t || U((_) => {
77
77
  const te = new Set(_);
78
78
  return te.add(I), te;
79
79
  });
80
80
  }), c.on("allActionsLoaded", () => {
81
- e || P(!1);
81
+ t || z(!1);
82
82
  }), c.on("ready", () => {
83
- e || (U(c.getActionMetadata()), Q.setActionMetadata(c.getActionMetadata()));
83
+ t || (o(c.getActionMetadata()), q.setActionMetadata(c.getActionMetadata()));
84
84
  });
85
85
  try {
86
- P(!0);
87
- const I = await M.getBundle(a);
88
- if (e || (await c.init(T, { payload: I.payload }), e)) return;
89
- U(c.getActionMetadata()), Q.setActionMetadata(c.getActionMetadata());
86
+ z(!0);
87
+ const I = await y.getBundle(a);
88
+ if (t || (await c.init(T, { payload: I.payload }), t)) return;
89
+ o(c.getActionMetadata()), q.setActionMetadata(c.getActionMetadata());
90
90
  } catch (I) {
91
91
  console.error("[useAvatarSession] Init failed:", I);
92
92
  }
93
93
  })(), () => {
94
- e = !0, i.current?.destroy(), i.current = null, b.current = null;
94
+ t = !0, i.current?.destroy(), i.current = null, l.current = null;
95
95
  };
96
- }, [a, G, M]);
97
- const ee = m(!1);
96
+ }, [a, G, y]);
97
+ const ee = k(!1);
98
98
  h(() => {
99
- B && i.current && A.has("wave_hand") && !ee.current && (i.current.play("wave_hand", "listening"), ee.current = !0);
100
- }, [B, A]);
99
+ H && i.current && s.has("wave_hand") && !ee.current && (i.current.play("wave_hand", "listening"), ee.current = !0);
100
+ }, [H, s]);
101
101
  const ce = S(async () => {
102
- if (!(K || W)) {
103
- O(!0);
102
+ if (!(W || N)) {
103
+ K(!0);
104
104
  try {
105
105
  await navigator.mediaDevices.getUserMedia({ audio: !0 });
106
- const e = await M.getLiveKitToken(a);
107
- J(e.token);
108
- } catch (e) {
109
- console.error("[useAvatarSession] Failed to connect:", e), O(!1);
106
+ const t = await y.getLiveKitToken(a);
107
+ $(t.token);
108
+ } catch (t) {
109
+ console.error("[useAvatarSession] Failed to connect:", t), K(!1);
110
110
  }
111
111
  }
112
- }, [K, W, a, M]), H = S(() => {
113
- E.current && (clearInterval(E.current), E.current = null), N(p), D.current && (clearTimeout(D.current), D.current = null), J(null), Z(!1), O(!1), b.current?.forceListening();
112
+ }, [W, N, a, y]), Q = S(() => {
113
+ M.current && (clearInterval(M.current), M.current = null), V(p), L.current && (clearTimeout(L.current), L.current = null), $(null), Z(!1), K(!1), l.current?.forceListening();
114
114
  }, [p]);
115
115
  h(() => {
116
- V.current = H;
117
- }, [H]);
116
+ B.current = Q;
117
+ }, [Q]);
118
118
  const le = S(() => {
119
- Z(!0), O(!1);
119
+ Z(!0), K(!1);
120
120
  }, []), ue = S(() => {
121
- E.current && clearInterval(E.current), N(p), E.current = setInterval(() => {
122
- N((e) => e <= 1 ? (clearInterval(E.current), E.current = null, setTimeout(() => V.current(), 0), 0) : e - 1);
121
+ M.current && clearInterval(M.current), V(p), M.current = setInterval(() => {
122
+ V((t) => t <= 1 ? (clearInterval(M.current), M.current = null, setTimeout(() => B.current(), 0), 0) : t - 1);
123
123
  }, 1e3);
124
- }, [p]), de = S((e) => {
125
- const f = Math.floor(e / 60).toString().padStart(2, "0"), T = (e % 60).toString().padStart(2, "0");
126
- return `${f}:${T}`;
124
+ }, [p]), de = S((t) => {
125
+ const g = Math.floor(t / 60).toString().padStart(2, "0"), T = (t % 60).toString().padStart(2, "0");
126
+ return `${g}:${T}`;
127
127
  }, []);
128
128
  h(() => () => {
129
- E.current && clearInterval(E.current);
129
+ M.current && clearInterval(M.current);
130
130
  }, []);
131
131
  const pe = S(
132
- (e) => {
133
- if (!e) {
134
- D.current && (clearTimeout(D.current), D.current = null);
132
+ (t) => {
133
+ if (!t) {
134
+ L.current && (clearTimeout(L.current), L.current = null);
135
135
  return;
136
136
  }
137
- D.current || (D.current = setTimeout(() => {
138
- D.current = null, V.current();
139
- }, R));
137
+ L.current || (L.current = setTimeout(() => {
138
+ L.current = null, B.current();
139
+ }, C));
140
140
  },
141
- [R]
141
+ [C]
142
142
  ), fe = S(() => {
143
- X((e) => !e);
144
- }, []), ge = S((e) => {
145
- X(e);
146
- }, []), he = S((e) => {
147
- Y(e);
143
+ X((t) => !t);
144
+ }, []), ge = S((t) => {
145
+ X(t);
146
+ }, []), he = S((t) => {
147
+ Y(t);
148
148
  }, []), me = S(() => {
149
- Y((e) => e > 0 ? 0 : 1);
149
+ Y((t) => t > 0 ? 0 : 1);
150
150
  }, []), ve = S(() => {
151
151
  i.current?.interrupt();
152
- }, []), ye = S((e) => {
153
- i.current?.play(e, "listening");
152
+ }, []), ye = S((t) => {
153
+ i.current?.play(t, "listening");
154
154
  }, []);
155
155
  return {
156
- containerRef: s,
156
+ containerRef: m,
157
157
  renderer: i.current,
158
- actionQueue: b.current,
159
- rendererState: g,
160
- avatarDimensions: o,
161
- loadedActions: A,
162
- actionMetadata: l,
163
- isLoadingActions: F,
164
- isEngineReady: B,
165
- token: $,
166
- isConnecting: K,
167
- isConnected: W,
168
- livekitUrl: L,
158
+ actionQueue: l.current,
159
+ rendererState: b,
160
+ avatarDimensions: f,
161
+ loadedActions: s,
162
+ actionMetadata: n,
163
+ isLoadingActions: O,
164
+ isEngineReady: H,
165
+ token: F,
166
+ isConnecting: W,
167
+ isConnected: N,
168
+ livekitUrl: D,
169
169
  timeRemaining: ae,
170
170
  formatTime: de,
171
171
  micMuted: oe,
172
172
  volume: se,
173
173
  turnOffMicWhenAISpeaking: d,
174
174
  connect: ce,
175
- disconnect: H,
175
+ disconnect: Q,
176
176
  toggleMic: fe,
177
177
  setMicMuted: ge,
178
178
  setVolume: he,
@@ -187,8 +187,8 @@ function Ue(v) {
187
187
  const _e = ({
188
188
  session: v,
189
189
  style: a,
190
- loadingContent: n
191
- }) => /* @__PURE__ */ k(
190
+ loadingContent: e
191
+ }) => /* @__PURE__ */ w(
192
192
  "div",
193
193
  {
194
194
  style: {
@@ -238,7 +238,7 @@ const _e = ({
238
238
  backdropFilter: "blur(4px)",
239
239
  zIndex: 10
240
240
  },
241
- children: n || /* @__PURE__ */ k(
241
+ children: e || /* @__PURE__ */ w(
242
242
  "div",
243
243
  {
244
244
  style: {
@@ -249,7 +249,7 @@ const _e = ({
249
249
  },
250
250
  children: [
251
251
  /* @__PURE__ */ r(
252
- q,
252
+ J,
253
253
  {
254
254
  style: {
255
255
  width: 40,
@@ -312,26 +312,26 @@ const _e = ({
312
312
  style: a
313
313
  }) => {
314
314
  const {
315
- micMuted: n,
315
+ micMuted: e,
316
316
  toggleMic: u,
317
317
  isConnected: d,
318
- isConnecting: w,
318
+ isConnecting: A,
319
319
  isEngineReady: p,
320
- loadedActions: R,
321
- connect: L,
322
- disconnect: M
323
- } = v, [s, y] = x(!1), [i, b] = x(!1), g = p && R.has("listening") && R.has("speaking"), C = n ? {
320
+ loadedActions: C,
321
+ connect: D,
322
+ disconnect: y
323
+ } = v, [m, E] = x(!1), [i, l] = x(!1), b = p && C.has("listening") && C.has("speaking"), R = e ? {
324
324
  ...re,
325
325
  background: "rgba(239,68,68,0.1)",
326
326
  color: "#f87171",
327
327
  boxShadow: "inset 0 0 0 1px rgba(239,68,68,0.3)",
328
- ...s ? { background: "rgba(239,68,68,0.2)" } : {}
328
+ ...m ? { background: "rgba(239,68,68,0.2)" } : {}
329
329
  } : {
330
330
  ...re,
331
- background: s ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.4)",
331
+ background: m ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.4)",
332
332
  color: "#fff",
333
333
  boxShadow: "inset 0 0 0 1px rgba(255,255,255,0.1)"
334
- }, o = d ? {
334
+ }, f = d ? {
335
335
  ...ie,
336
336
  background: i ? "rgba(239,68,68,0.22)" : "rgba(239,68,68,0.14)",
337
337
  boxShadow: "inset 0 0 0 1px rgba(239,68,68,0.5), 0 0 20px rgba(239,68,68,0.2)"
@@ -341,7 +341,7 @@ const _e = ({
341
341
  boxShadow: "0 0 30px rgba(236,72,153,0.3)",
342
342
  opacity: i ? 0.9 : 1
343
343
  };
344
- return (w || !g) && (o.opacity = 0.5, o.cursor = "not-allowed"), /* @__PURE__ */ k(
344
+ return (A || !b) && (f.opacity = 0.5, f.cursor = "not-allowed"), /* @__PURE__ */ w(
345
345
  "div",
346
346
  {
347
347
  style: {
@@ -361,7 +361,7 @@ const _e = ({
361
361
  to { transform: rotate(360deg); }
362
362
  }
363
363
  ` }),
364
- /* @__PURE__ */ k(
364
+ /* @__PURE__ */ w(
365
365
  "div",
366
366
  {
367
367
  style: {
@@ -379,32 +379,32 @@ const _e = ({
379
379
  {
380
380
  type: "button",
381
381
  onClick: u,
382
- onMouseEnter: () => y(!0),
383
- onMouseLeave: () => y(!1),
384
- style: C,
385
- title: n ? "Unmute mic" : "Mute mic",
386
- children: n ? /* @__PURE__ */ r(Ce, { size: 24 }) : /* @__PURE__ */ r(Ee, { size: 24 })
382
+ onMouseEnter: () => E(!0),
383
+ onMouseLeave: () => E(!1),
384
+ style: R,
385
+ title: e ? "Unmute mic" : "Mute mic",
386
+ children: e ? /* @__PURE__ */ r(Me, { size: 24 }) : /* @__PURE__ */ r(Ee, { size: 24 })
387
387
  }
388
388
  ),
389
389
  /* @__PURE__ */ r(
390
390
  "button",
391
391
  {
392
392
  type: "button",
393
- onClick: d ? M : L,
394
- onMouseEnter: () => b(!0),
395
- onMouseLeave: () => b(!1),
396
- disabled: !d && (w || !g),
397
- style: o,
398
- children: w ? /* @__PURE__ */ k(j, { children: [
399
- /* @__PURE__ */ r(q, { size: 20, style: { animation: "zwr-spin 1s linear infinite" } }),
393
+ onClick: d ? y : D,
394
+ onMouseEnter: () => l(!0),
395
+ onMouseLeave: () => l(!1),
396
+ disabled: !d && (A || !b),
397
+ style: f,
398
+ children: A ? /* @__PURE__ */ w(j, { children: [
399
+ /* @__PURE__ */ r(J, { size: 20, style: { animation: "zwr-spin 1s linear infinite" } }),
400
400
  /* @__PURE__ */ r("span", { children: "Connecting..." })
401
- ] }) : !d && !g ? /* @__PURE__ */ k(j, { children: [
402
- /* @__PURE__ */ r(q, { size: 20, style: { animation: "zwr-spin 1s linear infinite" } }),
401
+ ] }) : !d && !b ? /* @__PURE__ */ w(j, { children: [
402
+ /* @__PURE__ */ r(J, { size: 20, style: { animation: "zwr-spin 1s linear infinite" } }),
403
403
  /* @__PURE__ */ r("span", { children: "Loading Avatar..." })
404
- ] }) : d ? /* @__PURE__ */ k(j, { children: [
404
+ ] }) : d ? /* @__PURE__ */ w(j, { children: [
405
405
  /* @__PURE__ */ r(Le, { size: 20 }),
406
406
  /* @__PURE__ */ r("span", { children: "End Session" })
407
- ] }) : /* @__PURE__ */ k(j, { children: [
407
+ ] }) : /* @__PURE__ */ w(j, { children: [
408
408
  /* @__PURE__ */ r(De, { size: 20 }),
409
409
  /* @__PURE__ */ r("span", { children: "Start Session" })
410
410
  ] })
@@ -419,7 +419,7 @@ const _e = ({
419
419
  }, Oe = ({
420
420
  session: v
421
421
  }) => {
422
- const { isConnected: a, timeRemaining: n, formatTime: u } = v, d = a && n <= 30, w = a && n > 30 && n <= 60, p = {
422
+ const { isConnected: a, timeRemaining: e, formatTime: u } = v, d = a && e <= 30, A = a && e > 30 && e <= 60, p = {
423
423
  display: "flex",
424
424
  alignItems: "center",
425
425
  gap: 8,
@@ -434,7 +434,7 @@ const _e = ({
434
434
  borderColor: "rgba(239,68,68,0.4)",
435
435
  boxShadow: "0 0 15px rgba(239,68,68,0.3)",
436
436
  animation: "zwr-pulse 2s ease-in-out infinite"
437
- } : w ? {
437
+ } : A ? {
438
438
  background: "rgba(249,115,22,0.2)",
439
439
  borderColor: "rgba(249,115,22,0.3)",
440
440
  boxShadow: "0 4px 12px rgba(0,0,0,0.3)"
@@ -444,14 +444,14 @@ const _e = ({
444
444
  boxShadow: "0 4px 12px rgba(0,0,0,0.3)"
445
445
  }
446
446
  };
447
- return /* @__PURE__ */ k(j, { children: [
447
+ return /* @__PURE__ */ w(j, { children: [
448
448
  /* @__PURE__ */ r("style", { children: `
449
449
  @keyframes zwr-pulse {
450
450
  0%, 100% { opacity: 1; }
451
451
  50% { opacity: 0.5; }
452
452
  }
453
453
  ` }),
454
- /* @__PURE__ */ k("div", { style: p, children: [
454
+ /* @__PURE__ */ w("div", { style: p, children: [
455
455
  /* @__PURE__ */ r(
456
456
  "div",
457
457
  {
@@ -478,7 +478,7 @@ const _e = ({
478
478
  color: "rgba(255,255,255,0.7)",
479
479
  textTransform: "uppercase"
480
480
  },
481
- children: a ? `Online ${u(n)}` : "Offline"
481
+ children: a ? `Online ${u(e)}` : "Offline"
482
482
  }
483
483
  )
484
484
  ] })
@@ -486,125 +486,146 @@ const _e = ({
486
486
  }, $e = ({
487
487
  session: v
488
488
  }) => {
489
- const { renderer: a, actionQueue: n, micMuted: u, volume: d, setInactivityActive: w, loadedActions: p } = v, { turnOffMicWhenAISpeaking: R, setMicMuted: L } = v, M = m(!1), { state: s, audioTrack: y } = we(), i = Ae(), b = Te(i.localParticipant), g = m(null), C = m(p);
489
+ const {
490
+ renderer: a,
491
+ actionQueue: e,
492
+ micMuted: u,
493
+ volume: d,
494
+ setInactivityActive: A,
495
+ loadedActions: p,
496
+ token: C,
497
+ isConnected: D
498
+ } = v, { turnOffMicWhenAISpeaking: y, setMicMuted: m } = v, E = k(!1), { state: i, audioTrack: l } = we(), b = Ae(), R = Te(b.localParticipant), f = k(null), P = k(p);
490
499
  h(() => {
491
- C.current = p;
500
+ P.current = p;
492
501
  }, [p]), h(() => {
493
- const t = i.localParticipant;
494
- if (!a || !t) return;
495
- const l = new TextEncoder();
496
- return a.onOneshotComplete((F) => {
497
- const P = l.encode(
502
+ const n = b.localParticipant;
503
+ if (!a || !n) return;
504
+ const o = new TextEncoder();
505
+ return a.onOneshotComplete((z) => {
506
+ const F = o.encode(
498
507
  JSON.stringify({
499
508
  type: "ACTION_FINISHED",
500
- action: F
509
+ action: z
501
510
  })
502
511
  );
503
- t.publishData(P, {
512
+ n.publishData(F, {
504
513
  reliable: !0
505
514
  }).catch(($) => {
506
515
  console.error("[LiveKitAvatarProvider] Failed to publish action completion:", $);
507
516
  });
508
517
  });
509
- }, [a, i.localParticipant]), h(() => {
510
- if (!n) return;
511
- const t = new ke({
518
+ }, [a, b.localParticipant]), h(() => {
519
+ if (!e) return;
520
+ const n = new ke({
512
521
  threshold: 8e-3,
513
522
  analyseIntervalMs: 30,
514
523
  speechStartFrames: 1,
515
524
  speechPauseFrames: 30,
516
525
  turnEndFrames: 50
517
526
  });
518
- return g.current = t, t.on("speechStart", () => {
519
- n.setTurnActive(!0), n.setSpeechState("speaking");
520
- }), t.on("turnEnd", () => {
521
- n.setTurnActive(!1);
527
+ return f.current = n, n.on("speechStart", () => {
528
+ e.setTurnActive(!0), e.setSpeechState("speaking");
529
+ }), n.on("turnEnd", () => {
530
+ e.setTurnActive(!1);
522
531
  }), () => {
523
- t.stop(), g.current = null;
532
+ n.stop(), f.current = null;
524
533
  };
525
- }, [n]), h(() => {
526
- const t = g.current;
527
- if (t)
528
- if (y?.publication?.track) {
529
- const l = y.publication.track.mediaStreamTrack;
530
- l && t.start(l);
534
+ }, [e]), h(() => {
535
+ const n = f.current;
536
+ if (n)
537
+ if (l?.publication?.track) {
538
+ const o = l.publication.track.mediaStreamTrack;
539
+ o && n.start(o);
531
540
  } else
532
- t.stop();
533
- }, [y?.publication?.track]);
534
- const o = m(null), z = m(!1), A = m(!1);
541
+ n.stop();
542
+ }, [l?.publication?.track]);
543
+ const s = k(null), U = k(!1);
535
544
  return h(() => {
536
- if (!n) return;
537
- const t = s;
538
- t === "speaking" ? (o.current && (clearTimeout(o.current), o.current = null), n.setTurnActive(!0), n.setSpeechState("speaking")) : t === "listening" || t === "idle" ? (o.current && (clearTimeout(o.current), o.current = null), g.current?.endTurn(), n.setTurnActive(!1)) : t === "thinking" && (o.current || (o.current = setTimeout(() => {
539
- o.current = null, g.current?.endTurn(), n.setTurnActive(!1);
545
+ if (!e) return;
546
+ const n = i;
547
+ if (!C || !D || n === "disconnected") {
548
+ s.current && (clearTimeout(s.current), s.current = null), f.current?.endTurn(), e.forceListening();
549
+ return;
550
+ }
551
+ n === "speaking" ? (s.current && (clearTimeout(s.current), s.current = null), e.setTurnActive(!0), e.setSpeechState("speaking")) : n === "listening" || n === "idle" ? (s.current && (clearTimeout(s.current), s.current = null), f.current?.endTurn(), e.setTurnActive(!1)) : n === "thinking" && (s.current || (s.current = setTimeout(() => {
552
+ s.current = null, f.current?.endTurn(), e.setTurnActive(!1);
540
553
  }, 500)));
541
- }, [s, n]), h(() => {
542
- const t = s === "speaking";
543
- if (!R) {
544
- z.current = t, A.current = !1;
554
+ }, [e, D, i, C]), h(() => {
555
+ const n = i === "speaking";
556
+ if (!y) {
557
+ U.current = n;
545
558
  return;
546
559
  }
547
- const l = z.current;
548
- !l && t ? u ? A.current = !1 : (L(!0), A.current = !0) : l && t ? A.current && !u && (A.current = !1) : l && !t && (A.current && L(!1), A.current = !1), z.current = t;
549
- }, [u, L, s, R]), h(() => () => {
550
- o.current && clearTimeout(o.current);
551
- }, []), Ie((t) => {
560
+ const o = U.current;
561
+ !o && n ? u || m(!0) : o && !n && u && m(!1), U.current = n;
562
+ }, [u, m, i, y]), h(() => {
563
+ if (!y || !e) return;
564
+ const n = (o) => {
565
+ o || m(!1);
566
+ };
567
+ return e.on("turnChanged", n), () => {
568
+ e.off("turnChanged", n);
569
+ };
570
+ }, [e, m, y]), h(() => () => {
571
+ s.current && clearTimeout(s.current);
572
+ }, []), Ie((n) => {
552
573
  try {
553
- const U = new TextDecoder().decode(t.payload), F = JSON.parse(U);
554
- if (F.type === "AVATAR_UPDATE") {
555
- const P = F.action;
556
- if (!C.current.has(P))
574
+ const O = new TextDecoder().decode(n.payload), z = JSON.parse(O);
575
+ if (z.type === "AVATAR_UPDATE") {
576
+ const F = z.action;
577
+ if (!P.current.has(F))
557
578
  return;
558
- n?.dispatch(P);
579
+ e?.dispatch(F);
559
580
  }
560
- } catch (l) {
561
- console.error("[LiveKitAvatarProvider] Failed to parse data message:", l);
581
+ } catch (o) {
582
+ console.error("[LiveKitAvatarProvider] Failed to parse data message:", o);
562
583
  }
563
584
  }), h(() => {
564
- w(!(s === "speaking") && !b);
565
- }, [b, w, s]), h(() => {
566
- if (!n) return;
567
- const t = !!y;
568
- (!t || s === "disconnected") && (g.current?.endTurn(), n.forceListening()), M.current = t;
569
- }, [y, s, n]), h(() => {
570
- const t = i.localParticipant;
571
- t && t.setMicrophoneEnabled(!u).catch((l) => {
572
- console.error("[LiveKitAvatarProvider] Failed to set mic state:", l);
585
+ A(!(i === "speaking") && !R);
586
+ }, [R, A, i]), h(() => {
587
+ if (!e) return;
588
+ const n = !!l;
589
+ (!n || i === "disconnected") && (f.current?.endTurn(), e.forceListening()), E.current = n;
590
+ }, [l, i, e]), h(() => {
591
+ const n = b.localParticipant;
592
+ n && n.setMicrophoneEnabled(!u).catch((o) => {
593
+ console.error("[LiveKitAvatarProvider] Failed to set mic state:", o);
573
594
  });
574
- }, [u, i.localParticipant]), /* @__PURE__ */ r("div", { style: { position: "absolute", bottom: 80, left: 8, right: 8, display: "flex", flexDirection: "column", gap: 8 }, children: /* @__PURE__ */ r(Re, { volume: d }) });
595
+ }, [u, b.localParticipant]), /* @__PURE__ */ r("div", { style: { position: "absolute", bottom: 80, left: 8, right: 8, display: "flex", flexDirection: "column", gap: 8 }, children: /* @__PURE__ */ r(Ce, { volume: d }) });
575
596
  }, Qe = ({
576
597
  avatarId: v,
577
598
  apiKey: a,
578
- api: n,
599
+ api: e,
579
600
  turnOffMicWhenAISpeaking: u,
580
601
  livekitUrl: d,
581
- sessionDuration: w,
602
+ sessionDuration: A,
582
603
  inactivityTimeout: p,
583
- style: R,
584
- className: L,
585
- loadingContent: M,
586
- customControls: s,
587
- customStatusBadge: y
604
+ style: C,
605
+ className: D,
606
+ loadingContent: y,
607
+ customControls: m,
608
+ customStatusBadge: E
588
609
  }) => {
589
610
  const i = Ue({
590
611
  avatarId: v,
591
612
  apiKey: a,
592
- api: n,
613
+ api: e,
593
614
  turnOffMicWhenAISpeaking: u,
594
615
  livekitUrl: d,
595
- sessionDuration: w,
616
+ sessionDuration: A,
596
617
  inactivityTimeout: p
597
618
  }), {
598
- token: b,
599
- isConnected: g,
600
- avatarDimensions: C,
601
- disconnect: o,
602
- startSessionTimer: z
619
+ token: l,
620
+ isConnected: b,
621
+ avatarDimensions: R,
622
+ disconnect: f,
623
+ startSessionTimer: P
603
624
  } = i;
604
- return /* @__PURE__ */ k(
625
+ return /* @__PURE__ */ w(
605
626
  "section",
606
627
  {
607
- className: L,
628
+ className: D,
608
629
  style: {
609
630
  position: "relative",
610
631
  display: "flex",
@@ -618,12 +639,12 @@ const _e = ({
618
639
  height: "80vh",
619
640
  width: "auto",
620
641
  maxWidth: "100%",
621
- aspectRatio: C ? `${C.width} / ${C.height}` : "3 / 4",
622
- ...R
642
+ aspectRatio: R ? `${R.width} / ${R.height}` : "3 / 4",
643
+ ...C
623
644
  },
624
645
  children: [
625
- /* @__PURE__ */ r(_e, { session: i, loadingContent: M }),
626
- /* @__PURE__ */ k(
646
+ /* @__PURE__ */ r(_e, { session: i, loadingContent: y }),
647
+ /* @__PURE__ */ w(
627
648
  "div",
628
649
  {
629
650
  style: {
@@ -637,7 +658,7 @@ const _e = ({
637
658
  padding: 16
638
659
  },
639
660
  children: [
640
- /* @__PURE__ */ k(
661
+ /* @__PURE__ */ w(
641
662
  "div",
642
663
  {
643
664
  style: {
@@ -647,27 +668,27 @@ const _e = ({
647
668
  justifyContent: "space-between"
648
669
  },
649
670
  children: [
650
- y ? y(i) : /* @__PURE__ */ r(Oe, { session: i }),
671
+ E ? E(i) : /* @__PURE__ */ r(Oe, { session: i }),
651
672
  /* @__PURE__ */ r("div", {})
652
673
  ]
653
674
  }
654
675
  ),
655
- s ? s(i) : /* @__PURE__ */ r(je, { session: i })
676
+ m ? m(i) : /* @__PURE__ */ r(je, { session: i })
656
677
  ]
657
678
  }
658
679
  ),
659
- /* @__PURE__ */ r("div", { style: { display: "none" }, children: b && d && /* @__PURE__ */ r(
660
- Me,
680
+ /* @__PURE__ */ r("div", { style: { display: "none" }, children: l && d && /* @__PURE__ */ r(
681
+ Re,
661
682
  {
662
683
  serverUrl: d,
663
- token: b,
684
+ token: l,
664
685
  connect: !0,
665
686
  video: !1,
666
687
  audio: !0,
667
688
  onConnected: () => {
668
- i.markConnected(), z();
689
+ i.markConnected(), P();
669
690
  },
670
- onDisconnected: o,
691
+ onDisconnected: f,
671
692
  children: /* @__PURE__ */ r($e, { session: i })
672
693
  }
673
694
  ) })