@pollen-robotics/reachy-mini-sdk 1.11.0 → 1.12.0-dev.0.main.3cd1a23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/APP_CREATION_GUIDE.md +100 -50
- package/README.md +1 -1
- package/dist/lib/message-chunks.d.ts +22 -0
- package/dist/lib/message-chunks.d.ts.map +1 -0
- package/dist/lib/message-chunks.js +51 -0
- package/dist/lib/message-chunks.js.map +1 -0
- package/dist/lib/message-chunks.test.d.ts +2 -0
- package/dist/lib/message-chunks.test.d.ts.map +1 -0
- package/dist/lib/message-chunks.test.js +53 -0
- package/dist/lib/message-chunks.test.js.map +1 -0
- package/dist/lib/reachy-mini.d.ts.map +1 -1
- package/dist/lib/reachy-mini.js +9 -1
- package/dist/lib/reachy-mini.js.map +1 -1
- package/dist/lib/version.d.ts +1 -1
- package/dist/lib/version.d.ts.map +1 -1
- package/dist/lib/version.js +1 -1
- package/dist/lib/version.js.map +1 -1
- package/host/README.md +7 -6
- package/host/dist/chunks/{centralRest-vcOOpQK6.js → centralRest-K3a9U_Sk.js} +104 -82
- package/host/dist/chunks/{index-BrKBhTE0.js → index-B79tSfbK.js} +1 -1
- package/host/dist/chunks/{mountHost-CNQYkWZ4.js → mountHost-CMP4uYnZ.js} +1480 -1482
- package/host/dist/entry/auto.js +2 -2
- package/host/dist/entry/embed.js +2 -2
- package/host/dist/index.js +3 -3
- package/host/dist/lib/protocol.js +2 -2
- package/package.json +1 -1
package/APP_CREATION_GUIDE.md
CHANGED
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
# App Creation Guide
|
|
2
2
|
|
|
3
|
-
> ### Use `@pollen-robotics/reachy-mini-sdk
|
|
3
|
+
> ### Use the latest `@pollen-robotics/reachy-mini-sdk` release
|
|
4
4
|
>
|
|
5
|
-
>
|
|
6
|
-
>
|
|
7
|
-
>
|
|
5
|
+
> Install the latest stable release from
|
|
6
|
+
> [npm](https://www.npmjs.com/package/@pollen-robotics/reachy-mini-sdk):
|
|
7
|
+
>
|
|
8
|
+
> ```bash
|
|
9
|
+
> npm install @pollen-robotics/reachy-mini-sdk@latest
|
|
10
|
+
> ```
|
|
11
|
+
>
|
|
12
|
+
> This pins the exact resolved version in your `package.json` (npm
|
|
13
|
+
> versions are immutable, so this is fully reproducible). The minimum
|
|
14
|
+
> supported version is **`1.8.0`** — anything older predates the host
|
|
15
|
+
> shell contract described here. Every
|
|
16
|
+
> reference app pins the same SDK release. The host shell, the embed
|
|
8
17
|
> adapter, the SDK runtime, and the daemon on the robot are validated
|
|
9
18
|
> end-to-end against that release. Mixing versions across these
|
|
10
19
|
> boundaries causes silent protocol drift - see
|
|
11
20
|
> [§10 SDK version pinning](#10-sdk-version-pinning).
|
|
12
|
-
>
|
|
13
|
-
> Add this to your `package.json`:
|
|
14
|
-
>
|
|
15
|
-
> ```json
|
|
16
|
-
> { "dependencies": { "@pollen-robotics/reachy-mini-sdk": "1.8.0" } }
|
|
17
|
-
> ```
|
|
18
21
|
|
|
19
22
|
**This is the single source of truth for building a Reachy Mini JS
|
|
20
23
|
app.** [`../AGENTS.md`](../AGENTS.md) at the repo root points here;
|
|
@@ -111,13 +114,14 @@ Pick the reference closest to your needs and clone its repo from Hugging Face:
|
|
|
111
114
|
|
|
112
115
|
| Reference app | Stack | Use it for |
|
|
113
116
|
|-------------------------------------|-----------------------------|---------------------------------------------|
|
|
114
|
-
| [`
|
|
115
|
-
| [`pollen-robotics/
|
|
116
|
-
| [`pollen-robotics/
|
|
117
|
+
| [`tfrere/minimal-conversation`](https://huggingface.co/spaces/tfrere/minimal-conversation) | **Vanilla TS + Vite** | Smallest bundled runtime, no framework |
|
|
118
|
+
| [`pollen-robotics/emotions`](https://huggingface.co/spaces/pollen-robotics/emotions) | React 19 + MUI 7 + Vite | UI-rich app with rich components / theming |
|
|
119
|
+
| [`pollen-robotics/telepresence`](https://huggingface.co/spaces/pollen-robotics/telepresence) | React 19 + MUI 7 + Vite | App with camera / media streams |
|
|
120
|
+
| [`pollen-robotics/sdk-js-demo-app`](https://huggingface.co/spaces/pollen-robotics/sdk-js-demo-app) | Vanilla TS + Vite | Tour of every SDK primitive |
|
|
117
121
|
|
|
118
122
|
```bash
|
|
119
123
|
# Example: start from the vanilla TS template
|
|
120
|
-
git clone https://huggingface.co/spaces/
|
|
124
|
+
git clone https://huggingface.co/spaces/tfrere/minimal-conversation my_new_app
|
|
121
125
|
cd my_new_app
|
|
122
126
|
# Edit package.json `name`, README frontmatter (`title`, `emoji`,
|
|
123
127
|
# `short_description`), public/icon.svg, and src/embed.ts to your app.
|
|
@@ -126,8 +130,9 @@ npm run dev
|
|
|
126
130
|
# → http://localhost:5173
|
|
127
131
|
```
|
|
128
132
|
|
|
129
|
-
All
|
|
130
|
-
the same
|
|
133
|
+
All reference apps pin `@pollen-robotics/reachy-mini-sdk` to
|
|
134
|
+
the same exact version (the latest npm release) in their
|
|
135
|
+
`package.json` - see [§10 SDK version pinning](#10-sdk-version-pinning).
|
|
131
136
|
|
|
132
137
|
> **Prefer a no-build path?** You can also ship the app as a single
|
|
133
138
|
> `index.html` with the SDK loaded from a CDN. No `package.json`, no
|
|
@@ -363,6 +368,7 @@ The resolved `handle` exposes:
|
|
|
363
368
|
interface ConnectedHandle<TConfig> {
|
|
364
369
|
// Live state at boot
|
|
365
370
|
reachy: ReachyMiniInstance; // SDK instance, session live, robot awake
|
|
371
|
+
media: RobotMedia; // WebRTC streams - see "Video: use `handle.media`"
|
|
366
372
|
theme: 'dark' | 'light';
|
|
367
373
|
config: TConfig | null;
|
|
368
374
|
appName: string;
|
|
@@ -385,6 +391,41 @@ The API is intentionally minimal. If you need a custom channel
|
|
|
385
391
|
between host and embed, file a feature request - we'll add it as
|
|
386
392
|
a typed message rather than expose a free-form sink.
|
|
387
393
|
|
|
394
|
+
### Video: use `handle.media`
|
|
395
|
+
|
|
396
|
+
`connectToHost()` resolves only *after* the WebRTC handshake is
|
|
397
|
+
complete. By the time your app mounts, the SDK's one-shot
|
|
398
|
+
`videoTrack` event and the underlying `pc.ontrack` have **already
|
|
399
|
+
fired**. So `reachy.attachVideo(el)` installs a listener that never
|
|
400
|
+
fires, and an embed never calls `startSession()` again: the element
|
|
401
|
+
stays black forever, with no error anywhere.
|
|
402
|
+
|
|
403
|
+
`handle.media` exists for exactly this. It replays the streams from a
|
|
404
|
+
synchronous snapshot of the peer connection's receivers, so a
|
|
405
|
+
late-mounting consumer sees the camera immediately:
|
|
406
|
+
|
|
407
|
+
```ts
|
|
408
|
+
interface RobotMedia {
|
|
409
|
+
attachVideo(el: HTMLVideoElement): () => void; // returns a detach fn
|
|
410
|
+
readonly robotStream: MediaStream | null; // robot video + audio
|
|
411
|
+
readonly micStream: MediaStream | null; // local mic, if enabled
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
const handle = await connectToHost();
|
|
415
|
+
const detach = handle.media.attachVideo(videoEl);
|
|
416
|
+
handle.onLeave(() => detach());
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
There is no equivalent race for the data channel, mute toggles, motor
|
|
420
|
+
commands or state updates: the bridge resolves only once ICE **and**
|
|
421
|
+
the data channel are connected, and state events keep arriving (every
|
|
422
|
+
~500 ms, or ~30 Hz after `subscribePose()`). Keep calling `reachy.setHeadRpyDeg(...)`,
|
|
423
|
+
`reachy.setMicMuted(...)` and `reachy.addEventListener('state', ...)`
|
|
424
|
+
directly.
|
|
425
|
+
|
|
426
|
+
`reachy.attachVideo()` remains correct in a **standalone** app
|
|
427
|
+
(`mountHost`), where your code runs before the session starts.
|
|
428
|
+
|
|
388
429
|
### Typing your config
|
|
389
430
|
|
|
390
431
|
`connectToHost<T>()` types the `config` field; runtime validation
|
|
@@ -645,30 +686,31 @@ Pin yours the same way - mixing versions across `@pollen-robotics/reachy-mini-sd
|
|
|
645
686
|
`@pollen-robotics/reachy-mini-sdk/host`, and the daemon on the robot
|
|
646
687
|
produces hard-to-debug protocol drift.
|
|
647
688
|
|
|
648
|
-
|
|
689
|
+
Install the latest stable release from
|
|
690
|
+
[npm](https://www.npmjs.com/package/@pollen-robotics/reachy-mini-sdk):
|
|
649
691
|
|
|
650
|
-
```
|
|
651
|
-
|
|
652
|
-
"dependencies": {
|
|
653
|
-
"@pollen-robotics/reachy-mini-sdk": "1.8.0"
|
|
654
|
-
}
|
|
655
|
-
}
|
|
692
|
+
```bash
|
|
693
|
+
npm install @pollen-robotics/reachy-mini-sdk@latest
|
|
656
694
|
```
|
|
657
695
|
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
the
|
|
662
|
-
tracking a newer
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
>
|
|
668
|
-
>
|
|
669
|
-
>
|
|
670
|
-
|
|
671
|
-
|
|
696
|
+
npm writes the exact resolved version into your `package.json`. npm
|
|
697
|
+
versions are immutable, so pinning the exact version is fully
|
|
698
|
+
reproducible — no commit suffix needed. The stable release is
|
|
699
|
+
validated end-to-end against the host shell + daemon. **Use the exact
|
|
700
|
+
version string npm writes** unless you're explicitly tracking a newer
|
|
701
|
+
release. In all cases the version must be **`>= 1.8.0`** — older
|
|
702
|
+
releases predate the host shell + protocol v1 contract and are not
|
|
703
|
+
supported.
|
|
704
|
+
|
|
705
|
+
> The source of truth for "what's current" is the
|
|
706
|
+
> [npm package page](https://www.npmjs.com/package/@pollen-robotics/reachy-mini-sdk)
|
|
707
|
+
> (`npm view @pollen-robotics/reachy-mini-sdk version` works too), and
|
|
708
|
+
> whichever string is currently shared by [`minimal-conversation`'s
|
|
709
|
+
> `package.json`](https://huggingface.co/spaces/tfrere/minimal-conversation/blob/main/package.json),
|
|
710
|
+
> [`emotions`'s `package.json`](https://huggingface.co/spaces/pollen-robotics/emotions/blob/main/package.json),
|
|
711
|
+
> and [`telepresence`'s `package.json`](https://huggingface.co/spaces/pollen-robotics/telepresence/blob/main/package.json).
|
|
712
|
+
|
|
713
|
+
### Why pin a specific build (not `^x.y.z` or a major like `@1`)?
|
|
672
714
|
|
|
673
715
|
The host shell, the embed adapter (`connectToHost`), the SDK, and the
|
|
674
716
|
robot daemon negotiate over a versioned WebRTC data-channel protocol.
|
|
@@ -920,16 +962,18 @@ my-bare-app/
|
|
|
920
962
|
|
|
921
963
|
**Importing the SDK from a CDN**
|
|
922
964
|
|
|
923
|
-
Pin to an exact
|
|
924
|
-
`package.json
|
|
925
|
-
|
|
926
|
-
|
|
965
|
+
Pin to an exact version - **the same string you would use in
|
|
966
|
+
`package.json`**, i.e. the latest release shown on
|
|
967
|
+
[npm](https://www.npmjs.com/package/@pollen-robotics/reachy-mini-sdk)
|
|
968
|
+
(see [§10 SDK version pinning](#10-sdk-version-pinning)). Substitute it
|
|
969
|
+
for `<version>` below. jsDelivr's `/+esm` suffix tells the CDN to bundle
|
|
970
|
+
the package to ESM at the edge:
|
|
927
971
|
|
|
928
972
|
```html
|
|
929
973
|
<script type="module">
|
|
930
|
-
import { ReachyMini } from "https://cdn.jsdelivr.net/npm/@pollen-robotics/reachy-mini-sdk
|
|
931
|
-
import { mountHost } from "https://cdn.jsdelivr.net/npm/@pollen-robotics/reachy-mini-sdk
|
|
932
|
-
import { connectToHost } from "https://cdn.jsdelivr.net/npm/@pollen-robotics/reachy-mini-sdk
|
|
974
|
+
import { ReachyMini } from "https://cdn.jsdelivr.net/npm/@pollen-robotics/reachy-mini-sdk@<version>/+esm";
|
|
975
|
+
import { mountHost } from "https://cdn.jsdelivr.net/npm/@pollen-robotics/reachy-mini-sdk@<version>/host/dist/entry/auto.js";
|
|
976
|
+
import { connectToHost } from "https://cdn.jsdelivr.net/npm/@pollen-robotics/reachy-mini-sdk@<version>/host/dist/entry/embed.js";
|
|
933
977
|
|
|
934
978
|
window.ReachyMini = ReachyMini;
|
|
935
979
|
window.dispatchEvent(new Event("reachymini:ready"));
|
|
@@ -993,9 +1037,10 @@ shell without touching your motion code. The four-step recipe:
|
|
|
993
1037
|
import { ReachyMini } from "https://cdn.jsdelivr.net/gh/pollen-robotics/reachy_mini@v1.7.2/js/reachy-mini.js";
|
|
994
1038
|
|
|
995
1039
|
// AFTER (modern host shell, same SDK runtime API)
|
|
996
|
-
|
|
997
|
-
import {
|
|
998
|
-
import {
|
|
1040
|
+
// <version> = latest release on npm (see §10 SDK version pinning)
|
|
1041
|
+
import { ReachyMini } from "https://cdn.jsdelivr.net/npm/@pollen-robotics/reachy-mini-sdk@<version>/+esm";
|
|
1042
|
+
import { mountHost } from "https://cdn.jsdelivr.net/npm/@pollen-robotics/reachy-mini-sdk@<version>/host/dist/entry/auto.js";
|
|
1043
|
+
import { connectToHost } from "https://cdn.jsdelivr.net/npm/@pollen-robotics/reachy-mini-sdk@<version>/host/dist/entry/embed.js";
|
|
999
1044
|
```
|
|
1000
1045
|
|
|
1001
1046
|
2. **Branch on `?embedded=1`.** Wrap your existing app boot in:
|
|
@@ -1030,8 +1075,11 @@ shell without touching your motion code. The four-step recipe:
|
|
|
1030
1075
|
only exists on the modern SDK; if you weren't using it, nothing
|
|
1031
1076
|
changes. If you reached into private fields like `robot._pc`
|
|
1032
1077
|
(RTCPeerConnection), prefer the public alternatives:
|
|
1033
|
-
`
|
|
1034
|
-
`mountHost` for bidirectional audio.
|
|
1078
|
+
`handle.media.attachVideo(videoEl)` for video, `enableMicrophone: true`
|
|
1079
|
+
on `mountHost` for bidirectional audio. Once embedded, use
|
|
1080
|
+
`handle.media.attachVideo()` and **not** `robot.attachVideo()`: the
|
|
1081
|
+
latter silently no-ops because the handshake completed before your
|
|
1082
|
+
app mounted (see [§5 Video](#video-use-handlemedia)).
|
|
1035
1083
|
|
|
1036
1084
|
Your `README.md` frontmatter doesn't need any changes: `sdk: static`
|
|
1037
1085
|
and `hf_oauth: true` work for both variants. You can still skip
|
|
@@ -1467,7 +1515,9 @@ rolled out by the SDK team, not by every app team.
|
|
|
1467
1515
|
- App bundles (`index-<hash>.js`): hashed by Vite, cache-busted
|
|
1468
1516
|
on deploy.
|
|
1469
1517
|
- `@pollen-robotics/reachy-mini-sdk` in `package.json`: pinned to
|
|
1470
|
-
an **exact version** (
|
|
1518
|
+
an **exact version** (the latest release on
|
|
1519
|
+
[npm](https://www.npmjs.com/package/@pollen-robotics/reachy-mini-sdk)),
|
|
1520
|
+
not a range. See
|
|
1471
1521
|
[§10 SDK version pinning](#10-sdk-version-pinning).
|
|
1472
1522
|
- `@pollen-robotics/reachy-mini-sdk/host` subpath imports: same
|
|
1473
1523
|
pin, same package.
|
package/README.md
CHANGED
|
@@ -98,7 +98,7 @@ See the JSDoc header in [`reachy-mini-sdk.js`](./reachy-mini-sdk.js) for the ful
|
|
|
98
98
|
|
|
99
99
|
For Hugging Face Spaces apps that need OAuth + a robot picker + iframe lifecycle management:
|
|
100
100
|
|
|
101
|
-
- **[`APP_CREATION_GUIDE.md`](./APP_CREATION_GUIDE.md)** — single source of truth for app authors (scaffold, `sdk: static` deploy, host ↔ embed contract, invariants).
|
|
101
|
+
- **[`APP_CREATION_GUIDE.md`](./APP_CREATION_GUIDE.md)** — single source of truth for app authors (scaffold, `sdk: static` deploy, host ↔ embed contract, invariants). SDK pin: the latest stable release on [npm](https://www.npmjs.com/package/@pollen-robotics/reachy-mini-sdk).
|
|
102
102
|
- [`host/README.md`](./host/README.md) — one-page tour of the host package layout
|
|
103
103
|
|
|
104
104
|
## Migration from `@pollen-robotics/reachy-mini-host`
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reassembly of daemon messages too large for one data channel frame.
|
|
3
|
+
*
|
|
4
|
+
* The data channel silently drops any message over 64 KiB, so the daemon
|
|
5
|
+
* splits larger ones into ordered `message_chunk` frames (see
|
|
6
|
+
* `split_for_data_channel` in `reachy_mini/media/webrtc_utils.py`). Each
|
|
7
|
+
* carries a slice of the original text in `data`; joined in order they are
|
|
8
|
+
* the message the daemon meant to send.
|
|
9
|
+
*
|
|
10
|
+
* One instance per control channel: the channel is ordered, and a new
|
|
11
|
+
* channel means a new session, so nothing survives across the two.
|
|
12
|
+
*/
|
|
13
|
+
export declare class MessageReassembler {
|
|
14
|
+
private readonly _partials;
|
|
15
|
+
/**
|
|
16
|
+
* Feed one parsed frame. Returns the message to handle: the frame itself
|
|
17
|
+
* when it is not a chunk, the reassembled message when this chunk
|
|
18
|
+
* completes one, or `null` while a message is still arriving.
|
|
19
|
+
*/
|
|
20
|
+
accept(frame: Record<string, unknown>): Record<string, unknown> | null;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=message-chunks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-chunks.d.ts","sourceRoot":"","sources":["../../lib/message-chunks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA+B;IAEzD;;;;OAIG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;CA+BzE"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reassembly of daemon messages too large for one data channel frame.
|
|
3
|
+
*
|
|
4
|
+
* The data channel silently drops any message over 64 KiB, so the daemon
|
|
5
|
+
* splits larger ones into ordered `message_chunk` frames (see
|
|
6
|
+
* `split_for_data_channel` in `reachy_mini/media/webrtc_utils.py`). Each
|
|
7
|
+
* carries a slice of the original text in `data`; joined in order they are
|
|
8
|
+
* the message the daemon meant to send.
|
|
9
|
+
*
|
|
10
|
+
* One instance per control channel: the channel is ordered, and a new
|
|
11
|
+
* channel means a new session, so nothing survives across the two.
|
|
12
|
+
*/
|
|
13
|
+
/** Upper bound on one reassembled message, against a runaway sender. */
|
|
14
|
+
const MAX_CHUNKS = 4096;
|
|
15
|
+
export class MessageReassembler {
|
|
16
|
+
_partials = new Map();
|
|
17
|
+
/**
|
|
18
|
+
* Feed one parsed frame. Returns the message to handle: the frame itself
|
|
19
|
+
* when it is not a chunk, the reassembled message when this chunk
|
|
20
|
+
* completes one, or `null` while a message is still arriving.
|
|
21
|
+
*/
|
|
22
|
+
accept(frame) {
|
|
23
|
+
if (frame.type !== 'message_chunk')
|
|
24
|
+
return frame;
|
|
25
|
+
const { id, index, count, data } = frame;
|
|
26
|
+
if (typeof id !== 'string' ||
|
|
27
|
+
typeof index !== 'number' ||
|
|
28
|
+
typeof count !== 'number' ||
|
|
29
|
+
typeof data !== 'string' ||
|
|
30
|
+
count < 1 ||
|
|
31
|
+
count > MAX_CHUNKS) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
let parts = this._partials.get(id);
|
|
35
|
+
if (index === 0) {
|
|
36
|
+
parts = [];
|
|
37
|
+
this._partials.set(id, parts);
|
|
38
|
+
}
|
|
39
|
+
// The channel is ordered, so a gap means the message is lost.
|
|
40
|
+
if (!parts || index !== parts.length) {
|
|
41
|
+
this._partials.delete(id);
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
parts.push(data);
|
|
45
|
+
if (parts.length < count)
|
|
46
|
+
return null;
|
|
47
|
+
this._partials.delete(id);
|
|
48
|
+
return JSON.parse(parts.join(''));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=message-chunks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-chunks.js","sourceRoot":"","sources":["../../lib/message-chunks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,wEAAwE;AACxE,MAAM,UAAU,GAAG,IAAI,CAAC;AAExB,MAAM,OAAO,kBAAkB;IACV,SAAS,GAAG,IAAI,GAAG,EAAoB,CAAC;IAEzD;;;;OAIG;IACH,MAAM,CAAC,KAA8B;QACjC,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe;YAAE,OAAO,KAAK,CAAC;QACjD,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;QACzC,IACI,OAAO,EAAE,KAAK,QAAQ;YACtB,OAAO,KAAK,KAAK,QAAQ;YACzB,OAAO,KAAK,KAAK,QAAQ;YACzB,OAAO,IAAI,KAAK,QAAQ;YACxB,KAAK,GAAG,CAAC;YACT,KAAK,GAAG,UAAU,EACpB,CAAC;YACC,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,IAAI,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACnC,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;YACd,KAAK,GAAG,EAAE,CAAC;YACX,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAClC,CAAC;QACD,8DAA8D;QAC9D,IAAI,CAAC,KAAK,IAAI,KAAK,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;YACnC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC1B,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjB,IAAI,KAAK,CAAC,MAAM,GAAG,KAAK;YAAE,OAAO,IAAI,CAAC;QAEtC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAA4B,CAAC;IACjE,CAAC;CACJ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-chunks.test.d.ts","sourceRoot":"","sources":["../../lib/message-chunks.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MessageReassembler tests.
|
|
3
|
+
*
|
|
4
|
+
* The frames are the ones the daemon's `split_for_data_channel` produces:
|
|
5
|
+
* ordered `message_chunk` frames whose `data` slices join back into the
|
|
6
|
+
* original JSON text.
|
|
7
|
+
*/
|
|
8
|
+
import { describe, expect, it } from 'vitest';
|
|
9
|
+
import { MessageReassembler } from './message-chunks.js';
|
|
10
|
+
/** Split like the daemon does, into `size`-character slices. */
|
|
11
|
+
function chunk(message, id, size) {
|
|
12
|
+
const text = JSON.stringify(message);
|
|
13
|
+
const parts = [];
|
|
14
|
+
for (let i = 0; i < text.length; i += size)
|
|
15
|
+
parts.push(text.slice(i, i + size));
|
|
16
|
+
return parts.map((data, index) => ({ type: 'message_chunk', id, index, count: parts.length, data }));
|
|
17
|
+
}
|
|
18
|
+
describe('MessageReassembler', () => {
|
|
19
|
+
it('passes a frame that is not a chunk straight through', () => {
|
|
20
|
+
const frame = { jsonrpc: '2.0', id: 1, result: 'ok' };
|
|
21
|
+
expect(new MessageReassembler().accept(frame)).toBe(frame);
|
|
22
|
+
});
|
|
23
|
+
it('returns the message once its last chunk lands', () => {
|
|
24
|
+
const reply = { jsonrpc: '2.0', id: 'sorry_bro', result: { svg: '<svg/>'.repeat(5000) } };
|
|
25
|
+
const frames = chunk(reply, 'a', 4096);
|
|
26
|
+
const reassembler = new MessageReassembler();
|
|
27
|
+
const results = frames.map((f) => reassembler.accept(f));
|
|
28
|
+
expect(results.slice(0, -1).every((r) => r === null)).toBe(true);
|
|
29
|
+
expect(results.at(-1)).toEqual(reply);
|
|
30
|
+
});
|
|
31
|
+
it('keeps two messages apart when their chunks interleave', () => {
|
|
32
|
+
const first = { jsonrpc: '2.0', id: 1, result: 'a'.repeat(9000) };
|
|
33
|
+
const second = { jsonrpc: '2.0', id: 2, result: 'b'.repeat(9000) };
|
|
34
|
+
const [a, b] = [chunk(first, 'one', 4096), chunk(second, 'two', 4096)];
|
|
35
|
+
const reassembler = new MessageReassembler();
|
|
36
|
+
const done = [0, 1, 2]
|
|
37
|
+
.flatMap((i) => [a[i], b[i]])
|
|
38
|
+
.map((f) => reassembler.accept(f))
|
|
39
|
+
.filter((r) => r !== null);
|
|
40
|
+
expect(done).toEqual([first, second]);
|
|
41
|
+
});
|
|
42
|
+
it('drops a message with a missing chunk instead of corrupting it', () => {
|
|
43
|
+
const frames = chunk({ jsonrpc: '2.0', id: 1, result: 'x'.repeat(9000) }, 'a', 4096);
|
|
44
|
+
const reassembler = new MessageReassembler();
|
|
45
|
+
expect(reassembler.accept(frames[0])).toBeNull();
|
|
46
|
+
expect(reassembler.accept(frames[2])).toBeNull();
|
|
47
|
+
// The next message still reassembles.
|
|
48
|
+
const next = { jsonrpc: '2.0', id: 2, result: 'ok' };
|
|
49
|
+
const again = chunk(next, 'b', 8);
|
|
50
|
+
expect(again.map((f) => reassembler.accept(f)).at(-1)).toEqual(next);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
//# sourceMappingURL=message-chunks.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-chunks.test.js","sourceRoot":"","sources":["../../lib/message-chunks.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,gEAAgE;AAChE,SAAS,KAAK,CAAC,OAAgC,EAAE,EAAU,EAAE,IAAY;IACrE,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAChF,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACzG,CAAC;AAED,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC3D,MAAM,KAAK,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QACtD,MAAM,CAAC,IAAI,kBAAkB,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACrD,MAAM,KAAK,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QAC1F,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACvC,MAAM,WAAW,GAAG,IAAI,kBAAkB,EAAE,CAAC;QAE7C,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAEzD,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC7D,MAAM,KAAK,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QAClE,MAAM,MAAM,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QACnE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;QACvE,MAAM,WAAW,GAAG,IAAI,kBAAkB,EAAE,CAAC;QAE7C,MAAM,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;aACjB,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC;aAC9B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;aACjC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QAE/B,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;QACrE,MAAM,MAAM,GAAG,KAAK,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACrF,MAAM,WAAW,GAAG,IAAI,kBAAkB,EAAE,CAAC;QAE7C,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;QAClD,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;QAClD,sCAAsC;QACtC,MAAM,IAAI,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QACrD,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QAClC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reachy-mini.d.ts","sourceRoot":"","sources":["../../lib/reachy-mini.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"reachy-mini.d.ts","sourceRoot":"","sources":["../../lib/reachy-mini.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAoCH,OAAO,KAAK,EACR,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EAEjB,UAAU,EACV,OAAO,EACP,YAAY,EACZ,kBAAkB,EAClB,QAAQ,EACR,eAAe,EACf,cAAc,EACd,wBAAwB,EAExB,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,SAAS,EACT,UAAU,EAEV,wBAAwB,EACxB,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EACrB,MAAM,YAAY,CAAC;AASpB,YAAY,EAAE,mBAAmB,EAAE,CAAC;AAyDpC,qBAAa,UAAW,SAAQ,WAAY,YAAW,kBAAkB;IAGrE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgB;IAC1C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAAS;IACpD,OAAO,CAAC,iBAAiB,CAAU;IACnC,OAAO,CAAC,mBAAmB,CAAU;IAGrC,OAAO,CAAC,MAAM,CAA8D;IAC5E,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,WAAW,CAAkB;IAIrC,OAAO,CAAC,YAAY,CAAuB;IAG3C,OAAO,CAAC,gBAAgB,CAAK;IAM7B,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAgB;IAGpD,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,aAAa,CAA8B;IAGnD,OAAO,CAAC,mBAAmB,CAAgC;IAG3D,GAAG,EAAE,iBAAiB,GAAG,IAAI,CAAQ;IACrC,OAAO,CAAC,GAAG,CAA+B;IAC1C,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,iBAAiB,CAA8C;IAGvE,UAAU,EAAE,WAAW,GAAG,IAAI,CAAQ;IACtC,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,aAAa,CAAS;IAG9B,OAAO,CAAC,iBAAiB,CAA+C;IACxE,OAAO,CAAC,qBAAqB,CAA+C;IAK5E,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;IAGjD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiC;IACjE,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAA0C;IAKrF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqE;IAGnG,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,oBAAoB,CAAuB;IAGnD,OAAO,CAAC,eAAe,CAA6B;IACpD,OAAO,CAAC,cAAc,CAAuC;IAC7D,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,OAAO,CAAS;IAOxB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoB;IAGhD,OAAO,CAAC,aAAa,CAAiC;gBAE1C,OAAO,GAAE,iBAAsB;IAyC3C,IAAI,KAAK,IAAI,cAAc,GAAG,WAAW,GAAG,WAAW,CAAwB;IAC/E,IAAI,MAAM,IAAI,SAAS,EAAE,CAAyB;IAClD,IAAI,UAAU,IAAI,UAAU,CAA6B;IACzD,IAAI,QAAQ,IAAI,MAAM,GAAG,IAAI,CAA2B;IACxD,IAAI,eAAe,IAAI,OAAO,CAA0B;IACxD,IAAI,YAAY,IAAI,OAAO,CAA+B;IAC1D,IAAI,QAAQ,IAAI,OAAO,CAA2B;IAClD,IAAI,UAAU,IAAI,OAAO,CAA6B;IACtD,IAAI,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAAqC;IAC5E,IAAI,UAAU,IAAI,OAAO,CAA8C;IACvE;;;;;OAKG;IACH,IAAI,cAAc,IAAI,iBAAiB,GAAG,IAAI,CAAqB;IAEnE;;;;;;OAMG;IACH,IAAI,UAAU,IAAI,MAAM,CAAwB;IAEhD;0CACsC;IACtC,MAAM,KAAK,OAAO,IAAI,MAAM,CAAwB;IAEpD;;;;;OAKG;IACH,eAAe,IAAI,IAAI;IAmBjB,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC;IA6ChC,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBlD,MAAM,IAAI,IAAI;IASR,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0EtC,WAAW,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC;YA8EjE,iBAAiB;IA+C/B,OAAO,CAAC,mBAAmB;IAkBrB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YASpC,qBAAqB;IAmKnC;;;;;;;;;;OAUG;IACH,OAAO,CAAC,eAAe;IA4BvB,OAAO,CAAC,oBAAoB;IAoBtB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBlC,UAAU,IAAI,IAAI;IAqBlB;;;;;;;;;;;;OAYG;IACH,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIxC;;;;;;;;;;OAUG;IACH,OAAO,CAAC,kBAAkB;IAc1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA0CG;IACH,SAAS,CACL,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAO,GAC/F,OAAO;IAiCV,UAAU,CACN,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAClC;QAAE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAClF,OAAO;IAuCV,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAIzE,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO;IAI1D,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAItC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIhC,gBAAgB,CACZ,QAAQ,EAAE,MAAM,EAChB,EACI,OAAO,EACP,mBAAmB,GACtB,GAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,mBAAmB,CAAC,EAAE,MAAM,CAAA;KAAO,GAC3D,OAAO;IAWV;;;;;OAKG;IACH,QAAQ,IAAI,OAAO;IAInB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAIxC;;;;;;;;;OASG;IACH,qBAAqB,CACjB,OAAO,EAAE,MAAM,EACf,EAAE,SAAkB,EAAE,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GACpD,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAmB1B,kBAAkB,IAAI,OAAO;IAI7B,iBAAiB,CAAC,MAAM,SAAM,GAAG,OAAO;IAYxC,gBAAgB,IAAI,OAAO;IAI3B,cAAc,IAAI,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAI5C;;;;;;;;;;;;;OAaG;IACH,iBAAiB,CACb,EAAE,UAAkB,EAAE,UAAU,EAAE,GAAE,wBAA6B,GAClE,OAAO;IAKV,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,UAAU,GAAG,sBAAsB,GAAG,OAAO;IAI5E,cAAc,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,GAAE,MAAM,EAAE,GAAG,IAAW,GAAG,OAAO;IAIjE,MAAM,CAAC,EAAE,SAAgB,EAAE,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAKpE,SAAS,CAAC,EAAE,SAAgB,EAAE,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvE,OAAO,CAAC,2BAA2B;IAUnC,OAAO,IAAI,OAAO;IAKZ,WAAW,CAAC,SAAS,SAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAkDrD;;;;OAIG;IACH,UAAU,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAIpC,aAAa,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAIvC;;;;OAIG;IACH,MAAM,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAIjC,SAAS,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAInC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAIjD,mBAAmB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAI7C,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAI3D;;;;;;OAMG;IACH,cAAc,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAOzC;;;OAGG;IACH,cAAc,CAAC,WAAW,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAK7D;;;;OAIG;IACH,YAAY,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAItC;;;;;;OAMG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAIlD;;;;;;;;;;;;;;;OAeG;IACH,OAAO,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAIlC,gBAAgB,CACZ,MAAM,EAAE,gBAAgB,EAAE,EAC1B,EAAE,MAAa,EAAE,GAAE,uBAA4B,GAChD,OAAO,CAAC,OAAO,CAAC;IAKnB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC;IAI1D;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO;IAI/B;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CACH,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnD,EAAE,SAAqC,EAAE,KAAK,EAAE,GAAE,cAAmB,GACtE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAoB1C,aAAa,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,oBAAoB,GAAG,MAAM,IAAI;IAoBpE,YAAY,IAAI,OAAO;IAIvB;;;;;;;;;;;OAWG;IACH,aAAa,IAAI,OAAO;IAKxB,8EAA8E;IAC9E,eAAe,IAAI,OAAO;IAQ1B,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAKnC,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IASjC,WAAW,CAAC,YAAY,EAAE,gBAAgB,GAAG,MAAM,IAAI;IA6BjD,QAAQ,CACV,MAAM,EAAE,QAAQ,EAChB,EACI,SAAgB,EAChB,WAAkB,EAClB,WAAoB,EACpB,QAAwB,EACxB,aAAmB,EACnB,mBAAuB,EACvB,cAAqB,EACrB,UAAkC,EAClC,SAAiC,GACpC,GAAE,eAAoB,GACxB,OAAO,CAAC,cAAc,CAAC;IAkJ1B,UAAU,CAAC,QAAQ,GAAE,MAAM,GAAG,IAAW,GAAG,OAAO;IAM7C,WAAW,CACb,SAAS,EAAE,IAAI,EACf,EAAE,WAAqB,EAAE,UAAkC,EAAE,GAAE,kBAAuB,GACvF,OAAO,CAAC,MAAM,CAAC;IAqCZ,iBAAiB,CACnB,QAAQ,EAAE,MAAM,EAChB,EAAE,SAAgB,EAAE,GAAE,wBAA6B,GACpD,OAAO,CAAC;QAAE,OAAO,EAAE,IAAI,CAAA;KAAE,CAAC;IAkB7B,WAAW,CAAC,QAAQ,GAAE,MAAM,GAAG,IAAW,GAAG,OAAO;IAWpD,OAAO,CAAC,KAAK;IAOb,OAAO,CAAC,iBAAiB;YAOX,sBAAsB;YAStB,aAAa;IA4B3B,OAAO,CAAC,YAAY;IAMpB;;;;;;OAMG;IACH,OAAO,CAAC,CAAC,GAAG,OAAO,EACf,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACpC,IAAI,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GAClC,OAAO,CAAC,CAAC,CAAC;IAOb;;;OAGG;IACH,cAAc,CACV,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,GAC9C,MAAM,IAAI;IAYb,OAAO,CAAC,iBAAiB;IAgBzB,OAAO,CAAC,kBAAkB;YA0BZ,uBAAuB;IAiCrC,OAAO,CAAC,iBAAiB;YA6CX,kBAAkB;IA2DhC;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAkK3B,sEAAsE;IACtE,OAAO,CAAC,oBAAoB;CAe/B"}
|
package/dist/lib/reachy-mini.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import { oauthHandleRedirectIfPresent, oauthLoginUrl, } from '@huggingface/hub';
|
|
7
7
|
import { createLogger } from './logger.js';
|
|
8
8
|
import { degToRad, rpyToMatrix } from './math.js';
|
|
9
|
+
import { MessageReassembler } from './message-chunks.js';
|
|
9
10
|
import { BroadcastTimeoutError, PendingReplies, SLOT_ROUNDTRIP_TIMEOUT_MS } from './pending-replies.js';
|
|
10
11
|
import { SessionSupervisor } from './session-supervisor.js';
|
|
11
12
|
import { SDK_VERSION } from './version.js';
|
|
@@ -626,7 +627,14 @@ export class ReachyMini extends EventTarget {
|
|
|
626
627
|
this._dcOpen = true;
|
|
627
628
|
this._checkSessionReady();
|
|
628
629
|
};
|
|
629
|
-
|
|
630
|
+
// Replies over 64 KiB arrive as ordered chunks; one
|
|
631
|
+
// reassembler per channel, so nothing leaks across sessions.
|
|
632
|
+
const reassembler = new MessageReassembler();
|
|
633
|
+
this._dc.onmessage = (ev) => {
|
|
634
|
+
const msg = reassembler.accept(JSON.parse(ev.data));
|
|
635
|
+
if (msg)
|
|
636
|
+
this._handleRobotMessage(msg);
|
|
637
|
+
};
|
|
630
638
|
};
|
|
631
639
|
this._sendToServer({ type: 'startSession', peerId: robotId }).then((r) => {
|
|
632
640
|
if (r?.type === 'sessionRejected') {
|