@pollen-robotics/reachy-mini-sdk 1.10.0-dev.0.main.b50d97e → 1.10.0-dev.0.main.c8367cd

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 (128) hide show
  1. package/APP_CREATION_GUIDE.md +98 -0
  2. package/dist/lib/central-listener.d.ts +71 -0
  3. package/dist/lib/central-listener.d.ts.map +1 -0
  4. package/dist/lib/central-listener.js +277 -0
  5. package/dist/lib/central-listener.js.map +1 -0
  6. package/dist/lib/central-listener.test.d.ts +2 -0
  7. package/dist/lib/central-listener.test.d.ts.map +1 -0
  8. package/dist/lib/central-listener.test.js +378 -0
  9. package/dist/lib/central-listener.test.js.map +1 -0
  10. package/dist/lib/dc-watchdog.test.d.ts +2 -0
  11. package/dist/lib/dc-watchdog.test.d.ts.map +1 -0
  12. package/dist/lib/dc-watchdog.test.js +154 -0
  13. package/dist/lib/dc-watchdog.test.js.map +1 -0
  14. package/dist/lib/ensure-awake.test.d.ts +2 -0
  15. package/dist/lib/ensure-awake.test.d.ts.map +1 -0
  16. package/dist/lib/ensure-awake.test.js +117 -0
  17. package/dist/lib/ensure-awake.test.js.map +1 -0
  18. package/dist/lib/ice-grace.test.d.ts +2 -0
  19. package/dist/lib/ice-grace.test.d.ts.map +1 -0
  20. package/dist/lib/ice-grace.test.js +211 -0
  21. package/dist/lib/ice-grace.test.js.map +1 -0
  22. package/dist/lib/imu.test.d.ts +2 -0
  23. package/dist/lib/imu.test.d.ts.map +1 -0
  24. package/dist/lib/imu.test.js +78 -0
  25. package/dist/lib/imu.test.js.map +1 -0
  26. package/dist/lib/logger.d.ts +38 -0
  27. package/dist/lib/logger.d.ts.map +1 -0
  28. package/dist/lib/logger.js +81 -0
  29. package/dist/lib/logger.js.map +1 -0
  30. package/dist/lib/pending-replies.d.ts +127 -0
  31. package/dist/lib/pending-replies.d.ts.map +1 -0
  32. package/dist/lib/pending-replies.js +255 -0
  33. package/dist/lib/pending-replies.js.map +1 -0
  34. package/dist/lib/pending-replies.test.d.ts +2 -0
  35. package/dist/lib/pending-replies.test.d.ts.map +1 -0
  36. package/dist/lib/pending-replies.test.js +217 -0
  37. package/dist/lib/pending-replies.test.js.map +1 -0
  38. package/dist/lib/reachy-mini.d.ts +202 -88
  39. package/dist/lib/reachy-mini.d.ts.map +1 -1
  40. package/dist/lib/reachy-mini.js +651 -566
  41. package/dist/lib/reachy-mini.js.map +1 -1
  42. package/dist/lib/redial.test.d.ts +2 -0
  43. package/dist/lib/redial.test.d.ts.map +1 -0
  44. package/dist/lib/redial.test.js +206 -0
  45. package/dist/lib/redial.test.js.map +1 -0
  46. package/dist/lib/request.test.d.ts +2 -0
  47. package/dist/lib/request.test.d.ts.map +1 -0
  48. package/dist/lib/request.test.js +90 -0
  49. package/dist/lib/request.test.js.map +1 -0
  50. package/dist/lib/session-supervisor.d.ts +201 -0
  51. package/dist/lib/session-supervisor.d.ts.map +1 -0
  52. package/dist/lib/session-supervisor.js +520 -0
  53. package/dist/lib/session-supervisor.js.map +1 -0
  54. package/dist/lib/token-store.d.ts +50 -0
  55. package/dist/lib/token-store.d.ts.map +1 -0
  56. package/dist/lib/token-store.js +120 -0
  57. package/dist/lib/token-store.js.map +1 -0
  58. package/dist/lib/token-store.test.d.ts +2 -0
  59. package/dist/lib/token-store.test.d.ts.map +1 -0
  60. package/dist/lib/token-store.test.js +82 -0
  61. package/dist/lib/token-store.test.js.map +1 -0
  62. package/dist/lib/types.d.ts +280 -6
  63. package/dist/lib/types.d.ts.map +1 -1
  64. package/dist/lib/url-helpers.d.ts.map +1 -1
  65. package/dist/lib/url-helpers.js +3 -1
  66. package/dist/lib/url-helpers.js.map +1 -1
  67. package/dist/lib/version.d.ts +2 -0
  68. package/dist/lib/version.d.ts.map +1 -0
  69. package/dist/lib/version.js +5 -0
  70. package/dist/lib/version.js.map +1 -0
  71. package/dist/reachy-mini-sdk.d.ts +15 -1
  72. package/dist/reachy-mini-sdk.d.ts.map +1 -1
  73. package/dist/reachy-mini-sdk.js +12 -0
  74. package/dist/reachy-mini-sdk.js.map +1 -1
  75. package/host/dist/ReachyHost.d.ts.map +1 -1
  76. package/host/dist/chunks/centralRest-uXNMidlL.js +2315 -0
  77. package/host/dist/chunks/index-Beu4GNzi.js +821 -0
  78. package/host/dist/chunks/{mountHost-DjE5zE9R.js → mountHost-BTTF4Uu9.js} +24933 -27488
  79. package/host/dist/components/ConnectingView.d.ts.map +1 -1
  80. package/host/dist/components/DaemonUpdateGate.d.ts +65 -0
  81. package/host/dist/components/DaemonUpdateGate.d.ts.map +1 -0
  82. package/host/dist/components/ErrorView.d.ts.map +1 -1
  83. package/host/dist/components/HostErrorBoundary.d.ts +30 -0
  84. package/host/dist/components/HostErrorBoundary.d.ts.map +1 -0
  85. package/host/dist/components/LeavingView.d.ts.map +1 -1
  86. package/host/dist/components/PickerView.d.ts +16 -14
  87. package/host/dist/components/PickerView.d.ts.map +1 -1
  88. package/host/dist/components/PostOAuthSplash.d.ts +14 -9
  89. package/host/dist/components/PostOAuthSplash.d.ts.map +1 -1
  90. package/host/dist/components/ReachyHostShell.d.ts.map +1 -1
  91. package/host/dist/components/SignInView.d.ts.map +1 -1
  92. package/host/dist/components/TopBar.d.ts +5 -6
  93. package/host/dist/components/TopBar.d.ts.map +1 -1
  94. package/host/dist/components/WelcomeBackOverlay.d.ts.map +1 -1
  95. package/host/dist/embed/index.d.ts +68 -5
  96. package/host/dist/embed/index.d.ts.map +1 -1
  97. package/host/dist/entry/auto.js +2 -2
  98. package/host/dist/entry/embed.d.ts +5 -4
  99. package/host/dist/entry/embed.d.ts.map +1 -1
  100. package/host/dist/entry/embed.js +5 -4
  101. package/host/dist/hooks/useHostBridge.d.ts +35 -1
  102. package/host/dist/hooks/useHostBridge.d.ts.map +1 -1
  103. package/host/dist/hooks/useLatestDaemonVersion.d.ts +7 -0
  104. package/host/dist/hooks/useLatestDaemonVersion.d.ts.map +1 -0
  105. package/host/dist/hooks/useOAuth.d.ts +18 -0
  106. package/host/dist/hooks/useOAuth.d.ts.map +1 -1
  107. package/host/dist/hooks/useRobots.d.ts +0 -2
  108. package/host/dist/hooks/useRobots.d.ts.map +1 -1
  109. package/host/dist/index.d.ts +2 -2
  110. package/host/dist/index.d.ts.map +1 -1
  111. package/host/dist/index.js +11 -10
  112. package/host/dist/lib/daemonRelease.d.ts +84 -0
  113. package/host/dist/lib/daemonRelease.d.ts.map +1 -0
  114. package/host/dist/lib/protocol.d.ts +141 -7
  115. package/host/dist/lib/protocol.d.ts.map +1 -1
  116. package/host/dist/lib/rebootWatch.d.ts +51 -0
  117. package/host/dist/lib/rebootWatch.d.ts.map +1 -0
  118. package/host/dist/lib/sdk-types.d.ts +1 -1
  119. package/host/dist/lib/sdk-types.d.ts.map +1 -1
  120. package/host/dist/lib/sdkStaleness.d.ts +78 -0
  121. package/host/dist/lib/sdkStaleness.d.ts.map +1 -0
  122. package/host/dist/lib/settings.d.ts +16 -5
  123. package/host/dist/lib/settings.d.ts.map +1 -1
  124. package/package.json +11 -4
  125. package/host/dist/chunks/index-lMs2sCXG.js +0 -439
  126. package/host/dist/chunks/reachy-mini-CdsdQLIU.js +0 -1523
  127. package/host/dist/lib/centralListener.d.ts +0 -73
  128. package/host/dist/lib/centralListener.d.ts.map +0 -1
@@ -0,0 +1,821 @@
1
+ import { decodeCredsFromHash as $, PROTOCOL_VERSION as y, PROTOCOL_SOURCE as b, isProtocolMessage as D } from "../lib/protocol.js";
2
+ import { p as L, a as J, c as G } from "./centralRest-uXNMidlL.js";
3
+ const Y = "@pollen-robotics/reachy-mini-sdk", Z = `https://registry.npmjs.org/${Y}/latest`, V = "reachy.sdkLatestRelease.v1", F = "reachy.sdkStalenessDismissed.v1", Q = 360 * 60 * 1e3, v = "reachy-sdk-outdated-overlay";
4
+ function X() {
5
+ try {
6
+ const e = localStorage.getItem(V);
7
+ if (!e) return null;
8
+ const t = JSON.parse(e);
9
+ return typeof t.at != "number" ? null : {
10
+ value: typeof t.value == "string" ? t.value : null,
11
+ at: t.at
12
+ };
13
+ } catch {
14
+ return null;
15
+ }
16
+ }
17
+ function ee(e) {
18
+ try {
19
+ localStorage.setItem(V, JSON.stringify(e));
20
+ } catch {
21
+ }
22
+ }
23
+ async function te() {
24
+ const e = X();
25
+ if (e && Date.now() - e.at < Q) return e.value;
26
+ try {
27
+ const t = await fetch(Z, {
28
+ headers: { Accept: "application/json" }
29
+ });
30
+ if (!t.ok) return e?.value ?? null;
31
+ const n = await t.json(), a = typeof n.version == "string" ? n.version : null;
32
+ return ee({ value: a, at: Date.now() }), a;
33
+ } catch {
34
+ return e?.value ?? null;
35
+ }
36
+ }
37
+ function ne(e, t) {
38
+ const n = L(e), a = L(t);
39
+ return !n || !a || n.major === 0 ? !1 : a.major > n.major;
40
+ }
41
+ function re(e) {
42
+ const t = L(e);
43
+ if (!t) return !1;
44
+ try {
45
+ const n = L(localStorage.getItem(F));
46
+ return n ? t.major <= n.major : !1;
47
+ } catch {
48
+ return !1;
49
+ }
50
+ }
51
+ function oe(e) {
52
+ try {
53
+ localStorage.setItem(F, e);
54
+ } catch {
55
+ }
56
+ }
57
+ async function ae(e) {
58
+ try {
59
+ const t = await te();
60
+ if (!ne(e, t) || re(t)) return;
61
+ se(e, t);
62
+ } catch {
63
+ }
64
+ }
65
+ function x(e) {
66
+ const t = L(e);
67
+ return t ? `${t.major}.${t.minor}.${t.patch}` : "?";
68
+ }
69
+ function se(e, t) {
70
+ if (typeof document > "u" || document.getElementById(v)) return;
71
+ const n = x(e), a = x(t);
72
+ document.body.insertAdjacentHTML(
73
+ "beforeend",
74
+ `<div id="${v}" role="alertdialog" aria-label="This app may be out of date">
75
+ <style>
76
+ #${v} {
77
+ position: fixed; inset: 0; z-index: 2147483000;
78
+ display: flex; align-items: center; justify-content: center;
79
+ padding: 16px; background: rgba(0, 0, 0, 0.55);
80
+ font-family: system-ui, -apple-system, sans-serif;
81
+ --card-bg: #fff; --card-fg: #1a1a1a; --card-muted: #555;
82
+ --btn-bg: #1a1a1a; --btn-fg: #fff;
83
+ }
84
+ @media (prefers-color-scheme: dark) {
85
+ #${v} {
86
+ --card-bg: #1e1e1e; --card-fg: #f0f0f0; --card-muted: #aaa;
87
+ --btn-bg: #f0f0f0; --btn-fg: #1a1a1a;
88
+ }
89
+ }
90
+ #${v} .card {
91
+ background: var(--card-bg); color: var(--card-fg);
92
+ border-radius: 12px; padding: 24px; max-width: 400px;
93
+ width: 100%; text-align: center;
94
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.35);
95
+ }
96
+ #${v} .icon { font-size: 32px; line-height: 1; margin-bottom: 12px; }
97
+ #${v} .title { font-size: 17px; font-weight: 700; margin-bottom: 8px; }
98
+ #${v} .body {
99
+ font-size: 13px; line-height: 1.6;
100
+ color: var(--card-muted); margin-bottom: 16px;
101
+ }
102
+ #${v} button {
103
+ width: 100%; padding: 10px 16px; border: none; border-radius: 8px;
104
+ background: var(--btn-bg); color: var(--btn-fg);
105
+ font-size: 13px; font-weight: 600; cursor: pointer;
106
+ }
107
+ </style>
108
+ <div class="card">
109
+ <div class="icon">⚠️</div>
110
+ <div class="title">This app may be out of date</div>
111
+ <div class="body">It was built with SDK v${n}, but v${a} is the latest generation. Some things may not behave as expected with your robot.</div>
112
+ <button type="button">I understand, continue</button>
113
+ </div>
114
+ </div>`
115
+ );
116
+ const o = document.getElementById(v), r = o?.querySelector("button");
117
+ r?.addEventListener("click", () => {
118
+ oe(t), o?.remove();
119
+ }), r?.focus();
120
+ }
121
+ const H = 8e3, W = 2e3, ie = 900 * 1e3, ce = 2500, de = 6e3, le = 6500, ue = 1e3;
122
+ async function fe(e) {
123
+ await e.ensureAwake();
124
+ }
125
+ async function pe(e) {
126
+ e.robotState.motor_mode !== "disabled" && await new Promise((t) => {
127
+ let n = !1, a = 0, o = 0;
128
+ const r = () => {
129
+ n || (n = !0, e.removeEventListener("state", i), window.clearInterval(a), window.clearTimeout(o), t());
130
+ };
131
+ function i() {
132
+ e.robotState.motor_mode === "disabled" && r();
133
+ }
134
+ e.addEventListener("state", i), o = window.setTimeout(r, ue), a = window.setInterval(() => e.requestState(), 120), e.requestState();
135
+ });
136
+ }
137
+ let P = null, M = null, T = "*";
138
+ function q() {
139
+ try {
140
+ if (typeof document < "u" && document.referrer)
141
+ return new URL(document.referrer).origin;
142
+ } catch {
143
+ }
144
+ return "*";
145
+ }
146
+ async function Me(e = {}) {
147
+ return P || (P = me(e)), await P;
148
+ }
149
+ async function Re(e = {}) {
150
+ return M || (M = he(e)), await M;
151
+ }
152
+ async function me(e) {
153
+ T = q();
154
+ const t = e.expectedOrigin ?? T, n = $(window.location.hash);
155
+ if (K(), !n)
156
+ throw new Error(
157
+ "[reachy-mini-sdk/host/embed] no creds bundle found in URL hash. Was the embed mounted directly without ?embedded=1#creds=...?"
158
+ );
159
+ if (!await ye(H))
160
+ throw new Error(
161
+ `[reachy-mini-sdk/host/embed] window.ReachyMini did not become available within ${H}ms - check the SDK CDN tag.`
162
+ );
163
+ const o = n.userName ?? n.username ?? null;
164
+ n.hfToken && o && we(n.hfToken, o);
165
+ const r = new window.ReachyMini({
166
+ appName: n.appName,
167
+ signalingUrl: n.signalingUrl,
168
+ ...e.sdkOptions
169
+ });
170
+ C = typeof r.sdkVersion == "string" ? r.sdkVersion : null;
171
+ const i = B(t, r);
172
+ S({
173
+ source: b,
174
+ type: "embed:ready",
175
+ version: y
176
+ }), i.start();
177
+ const s = await i.awaitHostInit(W, n);
178
+ I("connecting", "link"), p("boot:link:start", { robotPeerId: s.robotPeerId }), await r.authenticate(), p("boot:authenticate:ok", { state: r.state }), await r.connect(), p("boot:connect:ok", {
179
+ state: r.state,
180
+ robots: (r.robots ?? []).length
181
+ });
182
+ const d = await ge(s, n);
183
+ I("connecting", "session"), p("boot:session:start", {
184
+ robotPeerId: d,
185
+ handedPeerId: s.robotPeerId,
186
+ reresolved: d !== s.robotPeerId
187
+ }), Oe(r);
188
+ try {
189
+ await r.startSession(d), p("boot:session:ok");
190
+ } catch (c) {
191
+ throw p("boot:session:error", {
192
+ message: c?.message ?? String(c)
193
+ }), c;
194
+ }
195
+ return R = await ve(r), p("boot:daemon-version", { daemonVersion: R }), I("connecting", "wake"), p("boot:wake:start"), await fe(r), p("boot:wake:ok", { awake: r.isAwake() }), i.attachPageHide(r), I("live", null), _e(r), ae(C), Ee(r), i.buildHandle(r, s);
196
+ }
197
+ async function he(e) {
198
+ T = q();
199
+ const t = e.expectedOrigin ?? T, n = $(window.location.hash);
200
+ if (K(), !n)
201
+ throw new Error(
202
+ "[reachy-mini-sdk/host/embed] no creds bundle found in URL hash. Was the embed mounted directly without ?embedded=1#creds=...?"
203
+ );
204
+ const a = B(t, null);
205
+ S({
206
+ source: b,
207
+ type: "embed:ready",
208
+ version: y
209
+ }), a.start();
210
+ const o = await a.awaitHostInit(W, n);
211
+ return a.attachPageHideCredsOnly(), I("live", null), a.buildCredsOnlyHandle(o, n);
212
+ }
213
+ function U(e) {
214
+ return {
215
+ theme: e.theme,
216
+ config: e.config,
217
+ appName: e.appName,
218
+ hostName: e.hostName,
219
+ userName: e.userName ?? null,
220
+ robotPeerId: e.robotPeerId,
221
+ robotHardwareId: e.robotHardwareId ?? null
222
+ };
223
+ }
224
+ function j(e) {
225
+ return {
226
+ theme: e.theme,
227
+ config: e.config,
228
+ appName: e.appName,
229
+ hostName: e.hostName,
230
+ userName: e.userName ?? null,
231
+ robotPeerId: e.robotPeerId,
232
+ robotHardwareId: e.robotHardwareId ?? null
233
+ };
234
+ }
235
+ async function ge(e, t) {
236
+ const n = e.robotHardwareId, a = t.hfToken;
237
+ if (!n || !a) return e.robotPeerId;
238
+ try {
239
+ const o = await J({
240
+ signalingUrl: t.signalingUrl,
241
+ hfToken: a
242
+ });
243
+ return o.ok ? o.robots.find((i) => i.hardwareId === n)?.id ?? e.robotPeerId : e.robotPeerId;
244
+ } catch {
245
+ return e.robotPeerId;
246
+ }
247
+ }
248
+ function B(e, t) {
249
+ const n = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Set(), o = /* @__PURE__ */ new Set();
250
+ let r = null, i = !1, s = !1, d = !1, c = null;
251
+ function h(l) {
252
+ switch (l.type) {
253
+ case "host:init": {
254
+ r = j(l), a.forEach((f) => f(r.theme)), o.forEach((f) => f(r.config));
255
+ break;
256
+ }
257
+ case "host:theme-changed": {
258
+ r && (r.theme = l.theme), a.forEach((f) => f(l.theme));
259
+ break;
260
+ }
261
+ case "host:config-changed": {
262
+ r && (r.config = l.config), o.forEach((f) => f(l.config));
263
+ break;
264
+ }
265
+ case "host:leaving": {
266
+ E();
267
+ break;
268
+ }
269
+ case "host:start-update": {
270
+ t && be(t, l.preRelease === !0);
271
+ break;
272
+ }
273
+ case "host:cancel-update": {
274
+ k?.();
275
+ break;
276
+ }
277
+ }
278
+ }
279
+ function m() {
280
+ i || (i = !0, n.forEach((l) => {
281
+ try {
282
+ l();
283
+ } catch (f) {
284
+ _.warn("onLeave threw", f);
285
+ }
286
+ }));
287
+ }
288
+ async function E() {
289
+ if (!s) {
290
+ if (s = !0, p("leave:start"), m(), t) {
291
+ const l = Date.now();
292
+ let f = "ok";
293
+ try {
294
+ f = await Promise.race([
295
+ t.gotoSleep({ timeoutMs: de }).then(() => "ok"),
296
+ new Promise(
297
+ (w) => window.setTimeout(() => w("hard-timeout"), le)
298
+ )
299
+ ]);
300
+ } catch {
301
+ f = "error";
302
+ }
303
+ p("leave:sleep", { outcome: f, ms: Date.now() - l });
304
+ const g = Date.now();
305
+ let u = !1;
306
+ try {
307
+ t.setMotorMode("disabled"), await pe(t), u = !0;
308
+ } catch {
309
+ }
310
+ p("leave:motors-disabled", {
311
+ confirmed: u,
312
+ ms: Date.now() - g
313
+ });
314
+ }
315
+ p("leave:ack"), S({
316
+ source: b,
317
+ type: "embed:left",
318
+ version: y
319
+ });
320
+ }
321
+ }
322
+ return {
323
+ start() {
324
+ d || (d = !0, c = (l) => {
325
+ e !== "*" && l.origin !== e || D(l.data) && h(l.data);
326
+ }, window.addEventListener("message", c));
327
+ },
328
+ async awaitHostInit(l, f) {
329
+ return window.parent !== window ? r || new Promise((u) => {
330
+ const w = (N) => {
331
+ if (e !== "*" && N.origin !== e || !D(N.data)) return;
332
+ const A = N.data;
333
+ A.type === "host:init" && (window.removeEventListener("message", w), window.clearTimeout(O), r = j(A), u(r));
334
+ }, O = window.setTimeout(() => {
335
+ window.removeEventListener("message", w), r || (r = U(f)), u(r);
336
+ }, l);
337
+ window.addEventListener("message", w);
338
+ }) : (r = U(f), r);
339
+ },
340
+ attachPageHide(l) {
341
+ const f = () => {
342
+ m();
343
+ try {
344
+ l.stopSession();
345
+ } catch {
346
+ }
347
+ };
348
+ window.addEventListener("pagehide", f, { once: !0 });
349
+ },
350
+ /** Credentials-only variant — no SDK to stop; just fire onLeave. */
351
+ attachPageHideCredsOnly() {
352
+ window.addEventListener("pagehide", m, { once: !0 });
353
+ },
354
+ /**
355
+ * Build the credentials-only handle. Same lifecycle accessors as
356
+ * `buildHandle` but exposes `hfToken` / `robotPeerId` /
357
+ * `signalingUrl` (from the creds bundle) instead of a `reachy`
358
+ * SDK instance, so the embed app can forward those to its
359
+ * backend.
360
+ */
361
+ buildCredsOnlyHandle(l, f) {
362
+ if (r = l, !f.hfToken)
363
+ throw new Error(
364
+ "[reachy-mini-sdk/host/embed] creds-only handle requires hfToken; the host shell did not provide one (visitor logged out?)."
365
+ );
366
+ return {
367
+ hfToken: f.hfToken,
368
+ robotPeerId: l.robotPeerId,
369
+ signalingUrl: f.signalingUrl,
370
+ get theme() {
371
+ return r.theme;
372
+ },
373
+ get config() {
374
+ return r.config;
375
+ },
376
+ get appName() {
377
+ return r.appName;
378
+ },
379
+ get hostName() {
380
+ return r.hostName;
381
+ },
382
+ get userName() {
383
+ return r.userName;
384
+ },
385
+ onLeave(g) {
386
+ return n.add(g), () => n.delete(g);
387
+ },
388
+ onThemeChange(g) {
389
+ return a.add(g), () => a.delete(g);
390
+ },
391
+ onConfigChange(g) {
392
+ const u = (w) => g(w);
393
+ return o.add(u), () => o.delete(u);
394
+ },
395
+ setAppState(g) {
396
+ I(
397
+ g.phase,
398
+ g.connectingStep ?? null,
399
+ g.message ?? null
400
+ );
401
+ },
402
+ requestLeave() {
403
+ S({
404
+ source: b,
405
+ type: "embed:request-leave",
406
+ version: y
407
+ });
408
+ },
409
+ reportError(g, u) {
410
+ S({
411
+ source: b,
412
+ type: "embed:error",
413
+ version: y,
414
+ message: g,
415
+ fatal: u?.fatal === !0,
416
+ detail: u?.detail
417
+ });
418
+ }
419
+ };
420
+ },
421
+ buildHandle(l, f) {
422
+ r = f;
423
+ const g = ke(l);
424
+ return {
425
+ reachy: l,
426
+ media: g,
427
+ get theme() {
428
+ return r.theme;
429
+ },
430
+ get config() {
431
+ return r.config;
432
+ },
433
+ get appName() {
434
+ return r.appName;
435
+ },
436
+ get hostName() {
437
+ return r.hostName;
438
+ },
439
+ get userName() {
440
+ return r.userName;
441
+ },
442
+ onLeave(u) {
443
+ return n.add(u), () => n.delete(u);
444
+ },
445
+ onThemeChange(u) {
446
+ return a.add(u), () => a.delete(u);
447
+ },
448
+ onConfigChange(u) {
449
+ const w = (O) => u(O);
450
+ return o.add(w), () => o.delete(w);
451
+ },
452
+ setAppState(u) {
453
+ I(
454
+ u.phase,
455
+ u.connectingStep ?? null,
456
+ u.message ?? null
457
+ );
458
+ },
459
+ requestLeave() {
460
+ S({
461
+ source: b,
462
+ type: "embed:request-leave",
463
+ version: y
464
+ });
465
+ },
466
+ reportError(u, w) {
467
+ S({
468
+ source: b,
469
+ type: "embed:error",
470
+ version: y,
471
+ message: u,
472
+ fatal: w?.fatal === !0,
473
+ detail: w?.detail
474
+ });
475
+ }
476
+ };
477
+ }
478
+ };
479
+ }
480
+ function K() {
481
+ try {
482
+ const e = window.location.pathname + window.location.search;
483
+ history.replaceState(history.state, document.title, e);
484
+ } catch {
485
+ }
486
+ }
487
+ function we(e, t) {
488
+ try {
489
+ sessionStorage.setItem("hf_token", e), sessionStorage.setItem("hf_username", t), sessionStorage.setItem(
490
+ "hf_token_expires",
491
+ new Date(Date.now() + ie).toISOString()
492
+ );
493
+ } catch {
494
+ }
495
+ }
496
+ function ye(e) {
497
+ return new Promise((t) => {
498
+ if (typeof window > "u") {
499
+ t(!1);
500
+ return;
501
+ }
502
+ if (window.ReachyMini) {
503
+ t(!0);
504
+ return;
505
+ }
506
+ let n = !1;
507
+ const a = () => {
508
+ n || (n = !0, window.removeEventListener("reachymini:ready", a), window.clearTimeout(o), t(!!window.ReachyMini));
509
+ }, o = window.setTimeout(() => {
510
+ n || (n = !0, window.removeEventListener("reachymini:ready", a), t(!1));
511
+ }, e);
512
+ window.addEventListener("reachymini:ready", a);
513
+ });
514
+ }
515
+ function S(e) {
516
+ if (!(typeof window > "u"))
517
+ try {
518
+ window.parent.postMessage(e, T);
519
+ } catch (t) {
520
+ _.warn("postMessage to host failed", t);
521
+ }
522
+ }
523
+ let k = null;
524
+ function be(e, t) {
525
+ const n = (s) => {
526
+ S({
527
+ source: b,
528
+ type: "embed:update-progress",
529
+ version: y,
530
+ ...s
531
+ });
532
+ }, a = (s) => {
533
+ const d = e.setAutoReconnect;
534
+ if (typeof d == "function")
535
+ try {
536
+ d.call(e, s);
537
+ } catch {
538
+ }
539
+ };
540
+ a(!1);
541
+ const o = () => {
542
+ k = null, e.removeEventListener("sessionStopped", o), n({ status: "rebooting" });
543
+ }, r = () => {
544
+ k = null, e.removeEventListener("sessionStopped", o), a(!0);
545
+ };
546
+ let i;
547
+ try {
548
+ i = e.startDaemonUpdate({
549
+ preRelease: t,
550
+ onProgress: (s) => {
551
+ s.status === "failed" && r(), n({
552
+ status: s.status,
553
+ line: s.line ?? null,
554
+ error: s.error ?? null
555
+ });
556
+ }
557
+ });
558
+ } catch (s) {
559
+ r(), n({ status: "failed", error: s?.message ?? String(s) });
560
+ return;
561
+ }
562
+ if (!i) {
563
+ r(), n({ status: "failed", error: "Data channel not open" });
564
+ return;
565
+ }
566
+ e.addEventListener("sessionStopped", o), k = r;
567
+ }
568
+ let R = null, C = null;
569
+ async function ve(e) {
570
+ try {
571
+ const t = await Promise.race([
572
+ e.getVersion(),
573
+ new Promise(
574
+ (n) => setTimeout(() => n(null), ce)
575
+ )
576
+ ]);
577
+ return typeof t == "string" && t.length > 0 ? t : null;
578
+ } catch {
579
+ return null;
580
+ }
581
+ }
582
+ function I(e, t, n = null, a = null) {
583
+ S({
584
+ source: b,
585
+ type: "embed:app-state",
586
+ version: y,
587
+ phase: e,
588
+ connectingStep: t,
589
+ message: n,
590
+ rttMs: a,
591
+ daemonVersion: R,
592
+ sdkVersion: C
593
+ });
594
+ }
595
+ const Se = 1500, Ie = 6;
596
+ async function Te(e) {
597
+ try {
598
+ const t = await e.getStats();
599
+ let n = null;
600
+ return t.forEach((a) => {
601
+ const o = a;
602
+ o.type !== "candidate-pair" || !(o.selected === !0 || o.nominated === !0 && o.state === "succeeded") || typeof o.currentRoundTripTime == "number" && (n = o.currentRoundTripTime * 1e3);
603
+ }), n;
604
+ } catch {
605
+ return null;
606
+ }
607
+ }
608
+ function Ee(e) {
609
+ if (typeof window > "u") return;
610
+ const t = () => z(e);
611
+ if (!t()) return;
612
+ const n = [];
613
+ let a = !1;
614
+ const o = async () => {
615
+ if (a) return;
616
+ const s = t();
617
+ if (!s || s.connectionState === "closed") return;
618
+ const d = await Te(s);
619
+ d !== null && (n.push(d), n.length > Ie && n.shift(), I("live", null, null, Math.min(...n)));
620
+ }, r = window.setInterval(() => {
621
+ o();
622
+ }, Se);
623
+ window.setTimeout(() => {
624
+ o();
625
+ }, 600);
626
+ const i = () => {
627
+ a || (a = !0, window.clearInterval(r));
628
+ };
629
+ e.addEventListener("sessionStopped", i), window.addEventListener("pagehide", i, { once: !0 });
630
+ }
631
+ function z(e) {
632
+ const t = e;
633
+ return t.peerConnection ?? t._pc ?? null;
634
+ }
635
+ const _ = G("embed");
636
+ function Le(e) {
637
+ return e.startsWith("boot:") || e.startsWith("leave:");
638
+ }
639
+ function p(e, t = {}) {
640
+ if (!(typeof window > "u")) {
641
+ try {
642
+ window.parent.postMessage(
643
+ {
644
+ source: b,
645
+ type: "embed:debug",
646
+ version: y,
647
+ tag: e,
648
+ payload: t
649
+ },
650
+ T
651
+ );
652
+ } catch {
653
+ }
654
+ try {
655
+ let n = "";
656
+ try {
657
+ n = JSON.stringify(t);
658
+ } catch {
659
+ n = "<unserializable>";
660
+ }
661
+ const a = `${e} ${n}`;
662
+ Le(e) ? _.info(a) : _.debug(a);
663
+ } catch {
664
+ }
665
+ }
666
+ }
667
+ function ke(e) {
668
+ let t = null;
669
+ const n = e, a = () => {
670
+ const i = z(e);
671
+ if (!i) return null;
672
+ const s = i.getReceivers().map((d) => d.track).filter(
673
+ (d) => d !== null && d.kind !== "" && d.readyState === "live"
674
+ );
675
+ return s.length === 0 ? null : new MediaStream(s);
676
+ }, o = () => t || (t = a(), t && p("media:cache:init", {
677
+ videoTracks: t.getVideoTracks().length,
678
+ audioTracks: t.getAudioTracks().length
679
+ }), t), r = () => {
680
+ t && (t = null, p("media:cache:clear"));
681
+ };
682
+ return e.addEventListener("sessionStopped", r), e.addEventListener("sessionReconnecting", r), {
683
+ attachVideo(i) {
684
+ const s = e.attachVideo(i), d = o();
685
+ if (d && i.srcObject !== d)
686
+ try {
687
+ i.srcObject = d, i.play().catch(() => {
688
+ }), p("media:attach:replay", {
689
+ videoTracks: d.getVideoTracks().length,
690
+ audioTracks: d.getAudioTracks().length
691
+ });
692
+ } catch (c) {
693
+ p("media:attach:replay:error", {
694
+ message: c?.message ?? String(c)
695
+ });
696
+ }
697
+ return s;
698
+ },
699
+ get robotStream() {
700
+ return o();
701
+ },
702
+ get micStream() {
703
+ return n._micStream;
704
+ }
705
+ };
706
+ }
707
+ function _e(e) {
708
+ e.addEventListener("sessionReconnecting", (t) => {
709
+ const n = t.detail, a = Number(n?.attempt ?? 1), o = Number(n?.maxAttempts ?? 1);
710
+ I(
711
+ "connecting",
712
+ "session",
713
+ a > 1 ? `Reconnecting to the robot (attempt ${a}/${o})` : "Connection lost — reconnecting to the robot"
714
+ );
715
+ }), e.addEventListener("sessionReconnected", () => {
716
+ I("live", null);
717
+ }), e.addEventListener("sessionStopped", (t) => {
718
+ const n = t.detail;
719
+ n?.reason === "reconnect_failed" && S({
720
+ source: b,
721
+ type: "embed:error",
722
+ version: y,
723
+ message: "Lost the connection to the robot and could not reconnect.",
724
+ fatal: !0,
725
+ detail: typeof n?.message == "string" ? n.message : void 0
726
+ });
727
+ });
728
+ }
729
+ function Oe(e) {
730
+ const t = [
731
+ "connected",
732
+ "disconnected",
733
+ "streaming",
734
+ "sessionStopped",
735
+ "sessionRejected",
736
+ "sessionReconnecting",
737
+ "sessionReconnected",
738
+ "robotsChanged",
739
+ "error",
740
+ "state",
741
+ "log",
742
+ "message"
743
+ ];
744
+ for (const o of t)
745
+ try {
746
+ e.addEventListener(o, (r) => {
747
+ let i = {};
748
+ const s = r;
749
+ if (s && typeof s == "object" && "detail" in s)
750
+ try {
751
+ i = JSON.parse(JSON.stringify(s.detail ?? null));
752
+ } catch {
753
+ i = { _unserializable: !0 };
754
+ }
755
+ p(`sdk:${o}`, i);
756
+ });
757
+ } catch {
758
+ }
759
+ try {
760
+ const o = e, r = o._handleSignalingMessage;
761
+ if (typeof r == "function") {
762
+ const i = o._sendToServer;
763
+ typeof i == "function" && (o._sendToServer = async function(d) {
764
+ const c = d, h = { type: c?.type ?? "?" };
765
+ if (c && "peerId" in c && (h.peerId = String(c.peerId)), c && "sessionId" in c && (h.sessionId = String(c.sessionId)), c && "sdp" in c) {
766
+ const m = c.sdp;
767
+ h.sdpType = m?.type ?? "?", h.sdpLen = m?.sdp?.length ?? 0;
768
+ }
769
+ if (c && "ice" in c) {
770
+ const m = c.ice;
771
+ h.iceCand = (m?.candidate ?? "").slice(0, 60) || "<end-of-candidates>";
772
+ }
773
+ p("sdk:send", h);
774
+ try {
775
+ const m = await i.call(this, d), E = m;
776
+ return p("sdk:send:res", {
777
+ inFor: h.type,
778
+ resType: E?.type ?? null,
779
+ keys: E ? Object.keys(E) : []
780
+ }), m;
781
+ } catch (m) {
782
+ throw p("sdk:send:err", {
783
+ inFor: h.type,
784
+ msg: m?.message ?? String(m)
785
+ }), m;
786
+ }
787
+ }), o._handleSignalingMessage = function(d) {
788
+ const c = d, h = { type: c?.type ?? "?" };
789
+ if ("sessionId" in c && (h.sessionId = String(c.sessionId)), "peerId" in c && (h.peerId = String(c.peerId)), "sdp" in c) {
790
+ const m = c.sdp;
791
+ h.sdpType = m?.type ?? "?", h.sdpLen = m?.sdp?.length ?? 0;
792
+ }
793
+ if ("ice" in c) {
794
+ const m = c.ice;
795
+ h.iceCand = (m?.candidate ?? "").slice(0, 60) || "<end-of-candidates>";
796
+ }
797
+ return "reason" in c && (h.reason = String(c.reason)), p("sdk:sse", h), r.call(this, d);
798
+ };
799
+ }
800
+ } catch {
801
+ }
802
+ const n = Date.now(), a = window.setInterval(() => {
803
+ const o = e, r = o._pc, i = o._dc;
804
+ p("sdk:probe", {
805
+ elapsedMs: Date.now() - n,
806
+ myPeerId: o._peerId ?? null,
807
+ state: o._state ?? null,
808
+ sseAborted: o._sseAbortController?.signal?.aborted ?? null,
809
+ pcState: r?.connectionState ?? null,
810
+ iceState: r?.iceConnectionState ?? null,
811
+ iceGather: r?.iceGatheringState ?? null,
812
+ signalingState: r?.signalingState ?? null,
813
+ dcState: i?.readyState ?? null,
814
+ sessionId: o._sessionId ?? null
815
+ }), Date.now() - n > 3e4 && window.clearInterval(a);
816
+ }, 1500);
817
+ }
818
+ export {
819
+ Re as a,
820
+ Me as c
821
+ };