@pollen-robotics/reachy-mini-sdk 1.13.0-dev.0.main.57898f1 → 1.13.0-dev.0.main.6037158
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/dist/lib/central-timeouts.test.d.ts +2 -0
- package/dist/lib/central-timeouts.test.d.ts.map +1 -0
- package/dist/lib/central-timeouts.test.js +101 -0
- package/dist/lib/central-timeouts.test.js.map +1 -0
- package/dist/lib/dial-races.test.d.ts +2 -0
- package/dist/lib/dial-races.test.d.ts.map +1 -0
- package/dist/lib/dial-races.test.js +215 -0
- package/dist/lib/dial-races.test.js.map +1 -0
- package/dist/lib/end-session-id.test.d.ts +2 -0
- package/dist/lib/end-session-id.test.d.ts.map +1 -0
- package/dist/lib/end-session-id.test.js +113 -0
- package/dist/lib/end-session-id.test.js.map +1 -0
- package/dist/lib/reachy-mini.d.ts +16 -0
- package/dist/lib/reachy-mini.d.ts.map +1 -1
- package/dist/lib/reachy-mini.js +199 -7
- package/dist/lib/reachy-mini.js.map +1 -1
- package/dist/lib/signaling-stall.test.d.ts +2 -0
- package/dist/lib/signaling-stall.test.d.ts.map +1 -0
- package/dist/lib/signaling-stall.test.js +64 -0
- package/dist/lib/signaling-stall.test.js.map +1 -0
- package/dist/lib/version.d.ts +1 -1
- package/dist/lib/version.js +1 -1
- package/host/dist/chunks/{centralRest-DP58F2yc.js → centralRest-DR0Wx46x.js} +557 -472
- package/host/dist/chunks/{index-BuWJ3EPU.js → index-B14lPGN5.js} +1 -1
- package/host/dist/chunks/{mountHost-C5yH3vnI.js → mountHost-CEY42tfj.js} +1 -1
- package/host/dist/entry/auto.js +2 -2
- package/host/dist/entry/embed.js +2 -2
- package/host/dist/index.js +3 -3
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"central-timeouts.test.d.ts","sourceRoot":"","sources":["../../lib/central-timeouts.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every call to central is bounded.
|
|
3
|
+
*
|
|
4
|
+
* A path that stalls without failing (lossy Wi-Fi, a half-dead connection)
|
|
5
|
+
* used to hang whatever awaited it: a re-dial waiting on connect(), a
|
|
6
|
+
* session start waiting for an offer that would never come, a stop waiting
|
|
7
|
+
* on its endSession. The properties that must hold:
|
|
8
|
+
* - a /send that never answers resolves null after CENTRAL_REQUEST_TIMEOUT_MS;
|
|
9
|
+
* - connect() rejects when /events never answers, or answers but never
|
|
10
|
+
* sends `welcome`, and leaves the instance disconnected;
|
|
11
|
+
* - a stream that is welcomed in time is not aborted afterwards;
|
|
12
|
+
* - a startSession that central did not take fails the dial at once.
|
|
13
|
+
*/
|
|
14
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
15
|
+
import { ReachyMini } from './reachy-mini.js';
|
|
16
|
+
const encoder = new TextEncoder();
|
|
17
|
+
/** A fetch that never settles on its own, only when aborted. */
|
|
18
|
+
function hangingFetch() {
|
|
19
|
+
vi.stubGlobal('fetch', vi.fn((_url, init) => new Promise((_resolve, reject) => {
|
|
20
|
+
init?.signal?.addEventListener('abort', () => reject(new DOMException('aborted', 'AbortError')));
|
|
21
|
+
})));
|
|
22
|
+
}
|
|
23
|
+
/** A /events stream that answers 200, then sends `firstLine` if given. */
|
|
24
|
+
function eventsStream(firstLine) {
|
|
25
|
+
vi.stubGlobal('fetch', vi.fn(async (_url, init) => {
|
|
26
|
+
const body = new ReadableStream({
|
|
27
|
+
start(c) {
|
|
28
|
+
if (firstLine)
|
|
29
|
+
c.enqueue(encoder.encode(firstLine));
|
|
30
|
+
init?.signal?.addEventListener('abort', () => c.error(new DOMException('aborted', 'AbortError')));
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
return new Response(body, { status: 200 });
|
|
34
|
+
}));
|
|
35
|
+
}
|
|
36
|
+
beforeEach(() => vi.useFakeTimers());
|
|
37
|
+
afterEach(() => {
|
|
38
|
+
vi.useRealTimers();
|
|
39
|
+
vi.unstubAllGlobals();
|
|
40
|
+
});
|
|
41
|
+
describe('central calls are bounded', () => {
|
|
42
|
+
it('a /send that never answers resolves null', async () => {
|
|
43
|
+
hangingFetch();
|
|
44
|
+
const r = new ReachyMini();
|
|
45
|
+
const s = r;
|
|
46
|
+
s._token = 'hf_test';
|
|
47
|
+
let result = 'pending';
|
|
48
|
+
void s._sendToServer({ type: 'endSession' }).then((v) => { result = v; });
|
|
49
|
+
await vi.advanceTimersByTimeAsync(9_000);
|
|
50
|
+
expect(result).toBe('pending');
|
|
51
|
+
await vi.advanceTimersByTimeAsync(2_000);
|
|
52
|
+
expect(result).toBeNull();
|
|
53
|
+
});
|
|
54
|
+
it('connect() rejects when /events never answers', async () => {
|
|
55
|
+
hangingFetch();
|
|
56
|
+
const r = new ReachyMini();
|
|
57
|
+
const outcome = r.connect('hf_test').then(() => 'resolved', (e) => e.message);
|
|
58
|
+
await vi.advanceTimersByTimeAsync(16_000);
|
|
59
|
+
expect(await outcome).toMatch(/no answer from central/);
|
|
60
|
+
expect(r.state).toBe('disconnected');
|
|
61
|
+
expect(r._sseAbortController).toBeNull();
|
|
62
|
+
});
|
|
63
|
+
it('connect() rejects when central answers but never welcomes', async () => {
|
|
64
|
+
eventsStream();
|
|
65
|
+
const r = new ReachyMini();
|
|
66
|
+
r._sendToServer = vi.fn().mockResolvedValue(null);
|
|
67
|
+
const outcome = r.connect('hf_test').then(() => 'resolved', (e) => e.message);
|
|
68
|
+
await vi.advanceTimersByTimeAsync(16_000);
|
|
69
|
+
expect(await outcome).toMatch(/no welcome from central/);
|
|
70
|
+
expect(r.state).toBe('disconnected');
|
|
71
|
+
});
|
|
72
|
+
it('keeps a stream welcomed in time', async () => {
|
|
73
|
+
eventsStream('data: {"type":"welcome","peerId":"me"}\n\n');
|
|
74
|
+
const r = new ReachyMini();
|
|
75
|
+
r._sendToServer = vi.fn().mockResolvedValue(null);
|
|
76
|
+
const disconnected = vi.fn();
|
|
77
|
+
r.addEventListener('disconnected', disconnected);
|
|
78
|
+
await r.connect('hf_test');
|
|
79
|
+
await vi.advanceTimersByTimeAsync(20_000);
|
|
80
|
+
expect(r.state).toBe('connected');
|
|
81
|
+
expect(disconnected).not.toHaveBeenCalled();
|
|
82
|
+
r.disconnect();
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
describe('a startSession central did not take', () => {
|
|
86
|
+
it('fails the dial at once instead of waiting for an offer', async () => {
|
|
87
|
+
vi.stubGlobal('RTCPeerConnection', class {
|
|
88
|
+
iceConnectionState = 'new';
|
|
89
|
+
close() { }
|
|
90
|
+
});
|
|
91
|
+
const r = new ReachyMini();
|
|
92
|
+
const s = r;
|
|
93
|
+
s._token = 'hf_test';
|
|
94
|
+
s._state = 'connected';
|
|
95
|
+
s._sendToServer = vi.fn().mockResolvedValue(null);
|
|
96
|
+
const outcome = r.startSession('robot-1').then(() => 'resolved', (e) => e.message);
|
|
97
|
+
await vi.advanceTimersByTimeAsync(0);
|
|
98
|
+
expect(await outcome).toMatch(/Could not reach central/);
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
//# sourceMappingURL=central-timeouts.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"central-timeouts.test.js","sourceRoot":"","sources":["../../lib/central-timeouts.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dial-races.test.d.ts","sourceRoot":"","sources":["../../lib/dial-races.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Races between dials, signaling opens and late replies.
|
|
3
|
+
*
|
|
4
|
+
* Found in review of the session-id and time-limit changes:
|
|
5
|
+
* - a startSession reply that lands after its dial was abandoned must not
|
|
6
|
+
* become the next dial's id (it would hide that dial's own rejection or
|
|
7
|
+
* its robot's end); it is retired and the robot told to end it;
|
|
8
|
+
* - two signaling opens at once share one stream instead of running two;
|
|
9
|
+
* - a stall timer that fires late because the page was frozen gives the
|
|
10
|
+
* buffered bytes a moment before aborting;
|
|
11
|
+
* - robot `peer` messages for a retired session are dropped;
|
|
12
|
+
* - the robot list fetch is bounded;
|
|
13
|
+
* - with a stale id kept after central's advisory end, an endSession for
|
|
14
|
+
* another id is still ignored.
|
|
15
|
+
*/
|
|
16
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
17
|
+
import { ReachyMini } from './reachy-mini.js';
|
|
18
|
+
const encoder = new TextEncoder();
|
|
19
|
+
const WELCOME = 'data: {"type":"welcome","peerId":"me"}\n\n';
|
|
20
|
+
function streamResponse(init, first) {
|
|
21
|
+
const body = new ReadableStream({
|
|
22
|
+
start(c) {
|
|
23
|
+
if (first)
|
|
24
|
+
c.enqueue(encoder.encode(first));
|
|
25
|
+
init?.signal?.addEventListener('abort', () => c.error(new DOMException('aborted', 'AbortError')));
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
return new Response(body, { status: 200 });
|
|
29
|
+
}
|
|
30
|
+
beforeEach(() => vi.useFakeTimers());
|
|
31
|
+
afterEach(() => {
|
|
32
|
+
vi.useRealTimers();
|
|
33
|
+
vi.unstubAllGlobals();
|
|
34
|
+
});
|
|
35
|
+
describe('late startSession replies', () => {
|
|
36
|
+
function redialing() {
|
|
37
|
+
vi.stubGlobal('RTCPeerConnection', class {
|
|
38
|
+
iceConnectionState = 'new';
|
|
39
|
+
close() { }
|
|
40
|
+
});
|
|
41
|
+
const r = new ReachyMini();
|
|
42
|
+
const s = r;
|
|
43
|
+
s._token = 'hf';
|
|
44
|
+
s._state = 'streaming';
|
|
45
|
+
s._selectedRobotId = 'robot-1';
|
|
46
|
+
s._sessionId = 'sess-0';
|
|
47
|
+
s._pc = { close: vi.fn(), iceConnectionState: 'connected' };
|
|
48
|
+
const replies = [];
|
|
49
|
+
const send = vi.fn((m) => m.type === 'startSession'
|
|
50
|
+
? new Promise((res) => replies.push(res))
|
|
51
|
+
: Promise.resolve(null));
|
|
52
|
+
s._sendToServer = send;
|
|
53
|
+
const sent = () => send.mock.calls.map((c) => c[0]);
|
|
54
|
+
return { r, s, replies, sent };
|
|
55
|
+
}
|
|
56
|
+
it("an abandoned dial's late reply does not hide the next dial's rejection", async () => {
|
|
57
|
+
const { r, s, replies, sent } = redialing();
|
|
58
|
+
s._supervisor.maybeBeginRedial('test');
|
|
59
|
+
await vi.advanceTimersByTimeAsync(0);
|
|
60
|
+
// Attempt 1 is rejected over SSE before its HTTP reply.
|
|
61
|
+
s._handleEndSession({ type: 'endSession', sessionId: 'X1', reason: 'robot_busy_local' });
|
|
62
|
+
await vi.advanceTimersByTimeAsync(2_100);
|
|
63
|
+
const starts = () => sent().filter((m) => m.type === 'startSession').length;
|
|
64
|
+
expect(starts()).toBe(2);
|
|
65
|
+
replies[0]({ type: 'sessionStarted', sessionId: 'X1' });
|
|
66
|
+
await vi.advanceTimersByTimeAsync(0);
|
|
67
|
+
expect(s._sessionId).toBeNull();
|
|
68
|
+
expect(s._retiredSessionIds.has('X1')).toBe(true);
|
|
69
|
+
// The robot is told to end the session it may have started for it.
|
|
70
|
+
expect(sent()).toContainEqual({ type: 'endSession', sessionId: 'X1', reason: 'client_stop' });
|
|
71
|
+
// Attempt 2's own rejection still applies: the loop moves on.
|
|
72
|
+
s._handleEndSession({ type: 'endSession', sessionId: 'Y2', reason: 'robot_busy_local' });
|
|
73
|
+
await vi.advanceTimersByTimeAsync(4_100);
|
|
74
|
+
expect(starts()).toBe(3);
|
|
75
|
+
r.disconnect();
|
|
76
|
+
});
|
|
77
|
+
it('a timed-out start central took anyway is ended on the robot', async () => {
|
|
78
|
+
const { r, s, replies, sent } = redialing();
|
|
79
|
+
s._state = 'connected';
|
|
80
|
+
s._pc = null;
|
|
81
|
+
const outcome = r.startSession('robot-1').then(() => 'resolved', () => 'rejected');
|
|
82
|
+
await vi.advanceTimersByTimeAsync(0);
|
|
83
|
+
// Central delivered the id over SSE, but the HTTP reply was lost.
|
|
84
|
+
s._sessionId = 'ghost-1';
|
|
85
|
+
replies[0](null);
|
|
86
|
+
await vi.advanceTimersByTimeAsync(0);
|
|
87
|
+
expect(await outcome).toBe('rejected');
|
|
88
|
+
expect(sent()).toContainEqual({ type: 'endSession', sessionId: 'ghost-1', reason: 'client_stop' });
|
|
89
|
+
r.disconnect();
|
|
90
|
+
});
|
|
91
|
+
it('a central refusal fails the dial at once', async () => {
|
|
92
|
+
const { r, s, replies } = redialing();
|
|
93
|
+
s._state = 'connected';
|
|
94
|
+
s._pc = null;
|
|
95
|
+
const outcome = r.startSession('robot-1').then(() => 'resolved', (e) => e.message);
|
|
96
|
+
await vi.advanceTimersByTimeAsync(0);
|
|
97
|
+
replies[0]({ type: 'error', message: 'Producer not found' });
|
|
98
|
+
await vi.advanceTimersByTimeAsync(0);
|
|
99
|
+
expect(await outcome).toMatch(/Central refused the session: Producer not found/);
|
|
100
|
+
r.disconnect();
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
describe('signaling opens', () => {
|
|
104
|
+
it('a second connect() joins the open in flight: one stream, both resolve', async () => {
|
|
105
|
+
let release;
|
|
106
|
+
const fetchMock = vi.fn((_u, init) => new Promise((res) => {
|
|
107
|
+
release = () => res(streamResponse(init, WELCOME));
|
|
108
|
+
}));
|
|
109
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
110
|
+
const r = new ReachyMini();
|
|
111
|
+
r._sendToServer = vi.fn().mockResolvedValue(null);
|
|
112
|
+
const a = r.connect('hf');
|
|
113
|
+
const b = r.connect('hf');
|
|
114
|
+
release();
|
|
115
|
+
await Promise.all([a, b]);
|
|
116
|
+
expect(fetchMock).toHaveBeenCalledTimes(1);
|
|
117
|
+
expect(r.state).toBe('connected');
|
|
118
|
+
r.disconnect();
|
|
119
|
+
});
|
|
120
|
+
it('connect() right after disconnect() opens a fresh stream', async () => {
|
|
121
|
+
const fetchMock = vi.fn(async (_u, init) => streamResponse(init, WELCOME));
|
|
122
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
123
|
+
const r = new ReachyMini();
|
|
124
|
+
r._sendToServer = vi.fn().mockResolvedValue(null);
|
|
125
|
+
const first = r.connect('hf').catch(() => 'aborted');
|
|
126
|
+
r.disconnect(); // aborts the open in flight
|
|
127
|
+
await r.connect('hf');
|
|
128
|
+
await first;
|
|
129
|
+
expect(fetchMock).toHaveBeenCalledTimes(2);
|
|
130
|
+
expect(r.state).toBe('connected');
|
|
131
|
+
r.disconnect();
|
|
132
|
+
});
|
|
133
|
+
it('a stall timer fired late by a frozen page re-judges after a grace', async () => {
|
|
134
|
+
let push;
|
|
135
|
+
vi.stubGlobal('fetch', vi.fn(async (_u, init) => {
|
|
136
|
+
const body = new ReadableStream({
|
|
137
|
+
start(c) {
|
|
138
|
+
push = (line) => c.enqueue(encoder.encode(line));
|
|
139
|
+
c.enqueue(encoder.encode(WELCOME));
|
|
140
|
+
init?.signal?.addEventListener('abort', () => c.error(new DOMException('aborted', 'AbortError')));
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
return new Response(body, { status: 200 });
|
|
144
|
+
}));
|
|
145
|
+
const r = new ReachyMini();
|
|
146
|
+
r._sendToServer = vi.fn().mockResolvedValue(null);
|
|
147
|
+
const disconnected = vi.fn();
|
|
148
|
+
r.addEventListener('disconnected', disconnected);
|
|
149
|
+
await r.connect('hf');
|
|
150
|
+
// The page freezes for 3 minutes: wall clock jumps, the timer fires late.
|
|
151
|
+
vi.setSystemTime(Date.now() + 180_000);
|
|
152
|
+
await vi.advanceTimersByTimeAsync(75_000);
|
|
153
|
+
expect(disconnected).not.toHaveBeenCalled();
|
|
154
|
+
// The bytes central buffered meanwhile are read within the grace.
|
|
155
|
+
push(': ping\n\n');
|
|
156
|
+
await vi.advanceTimersByTimeAsync(6_000);
|
|
157
|
+
expect(disconnected).not.toHaveBeenCalled();
|
|
158
|
+
expect(r.state).toBe('connected');
|
|
159
|
+
r.disconnect();
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
describe('retired sessions', () => {
|
|
163
|
+
it("drops a robot offer for a retired session", async () => {
|
|
164
|
+
// Real enough for the handler to reach setRemoteDescription.
|
|
165
|
+
vi.stubGlobal('RTCSessionDescription', class {
|
|
166
|
+
constructor(init) { Object.assign(this, init); }
|
|
167
|
+
});
|
|
168
|
+
const r = new ReachyMini();
|
|
169
|
+
const s = r;
|
|
170
|
+
const setRemoteDescription = vi.fn();
|
|
171
|
+
s._pc = { setRemoteDescription, close: vi.fn() };
|
|
172
|
+
s._retiredSessionIds.add('old');
|
|
173
|
+
await s._handlePeerMessage({ type: 'peer', sessionId: 'old', sdp: { type: 'answer', sdp: 'v=0' } });
|
|
174
|
+
expect(setRemoteDescription).not.toHaveBeenCalled();
|
|
175
|
+
// Control: the same message for a live session does reach the pc.
|
|
176
|
+
await s._handlePeerMessage({ type: 'peer', sessionId: 'live', sdp: { type: 'answer', sdp: 'v=0' } });
|
|
177
|
+
expect(setRemoteDescription).toHaveBeenCalledOnce();
|
|
178
|
+
});
|
|
179
|
+
it('with a stale id kept, an endSession for another id is ignored', () => {
|
|
180
|
+
const r = new ReachyMini();
|
|
181
|
+
const s = r;
|
|
182
|
+
s._token = 'hf';
|
|
183
|
+
s._state = 'streaming';
|
|
184
|
+
s._sessionId = 'central-1';
|
|
185
|
+
s._dcOpen = true;
|
|
186
|
+
s._dc = { readyState: 'open', close: vi.fn() };
|
|
187
|
+
s._pc = { iceConnectionState: 'connected', close: vi.fn() };
|
|
188
|
+
s._sendToServer = vi.fn().mockResolvedValue(null);
|
|
189
|
+
s._supervisor.stampDcInbound();
|
|
190
|
+
// Central's advisory end: the id becomes stale, the session lives on.
|
|
191
|
+
s._handleEndSession({ type: 'endSession', sessionId: 'central-1' });
|
|
192
|
+
expect(s._sessionId).toBeNull();
|
|
193
|
+
const stopped = vi.fn();
|
|
194
|
+
r.addEventListener('sessionStopped', stopped);
|
|
195
|
+
s._handleEndSession({ type: 'endSession', sessionId: 'someone-else', reason: 'robot_stopping' });
|
|
196
|
+
expect(stopped).not.toHaveBeenCalled();
|
|
197
|
+
expect(s._state).toBe('streaming');
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
describe('robot list fetch', () => {
|
|
201
|
+
it('falls back to the SSE list when /api/robot-status never answers', async () => {
|
|
202
|
+
vi.stubGlobal('fetch', vi.fn((_u, init) => new Promise((_res, rej) => init?.signal?.addEventListener('abort', () => rej(new DOMException('aborted', 'AbortError'))))));
|
|
203
|
+
const r = new ReachyMini();
|
|
204
|
+
const s = r;
|
|
205
|
+
s._token = 'hf';
|
|
206
|
+
s._robots = [{ id: 'robot-1', meta: { name: 'Reachy' } }];
|
|
207
|
+
let result = 'pending';
|
|
208
|
+
void s._fetchOwnedRobots().then((v) => { result = v; });
|
|
209
|
+
await vi.advanceTimersByTimeAsync(11_000);
|
|
210
|
+
expect(result).toEqual([
|
|
211
|
+
expect.objectContaining({ id: 'robot-1', name: 'Reachy' }),
|
|
212
|
+
]);
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
//# sourceMappingURL=dial-races.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dial-races.test.js","sourceRoot":"","sources":["../../lib/dial-races.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAEzE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;AAClC,MAAM,OAAO,GAAG,4CAA4C,CAAC;AAoB7D,SAAS,cAAc,CAAC,IAA6B,EAAE,KAAc;IACjE,MAAM,IAAI,GAAG,IAAI,cAAc,CAAa;QACxC,KAAK,CAAC,CAAC;YACH,IAAI,KAAK;gBAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAC5C,IAAI,EAAE,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CACzC,CAAC,CAAC,KAAK,CAAC,IAAI,YAAY,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,CACrD,CAAC;QACN,CAAC;KACJ,CAAC,CAAC;IACH,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;AAC/C,CAAC;AAED,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC,CAAC;AACrC,SAAS,CAAC,GAAG,EAAE;IACX,EAAE,CAAC,aAAa,EAAE,CAAC;IACnB,EAAE,CAAC,gBAAgB,EAAE,CAAC;AAC1B,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACvC,SAAS,SAAS;QAMd,EAAE,CAAC,UAAU,CACT,mBAAmB,EACnB;YACI,kBAAkB,GAAG,KAAK,CAAC;YAC3B,KAAK,KAAoC,CAAC;SAC7C,CACJ,CAAC;QACF,MAAM,CAAC,GAAG,IAAI,UAAU,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,CAAyB,CAAC;QACpC,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC;QAChB,CAAC,CAAC,MAAM,GAAG,WAAW,CAAC;QACvB,CAAC,CAAC,gBAAgB,GAAG,SAAS,CAAC;QAC/B,CAAC,CAAC,UAAU,GAAG,QAAQ,CAAC;QACxB,CAAC,CAAC,GAAG,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,kBAAkB,EAAE,WAAW,EAAE,CAAC;QAC5D,MAAM,OAAO,GAAgC,EAAE,CAAC;QAChD,MAAM,IAAI,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAA0B,EAAE,EAAE,CAC9C,CAAC,CAAC,IAAI,KAAK,cAAc;YACrB,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACzC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAC9B,CAAC;QACF,CAAC,CAAC,aAAa,GAAG,IAAI,CAAC;QACvB,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAA4B,CAAC,CAAC;QAC/E,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACnC,CAAC;IAED,EAAE,CAAC,wEAAwE,EAAE,KAAK,IAAI,EAAE;QACpF,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,SAAS,EAAE,CAAC;QAC5C,CAAC,CAAC,WAAW,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;QACvC,MAAM,EAAE,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC;QACrC,wDAAwD;QACxD,CAAC,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAAC;QACzF,MAAM,EAAE,CAAC,wBAAwB,CAAC,KAAK,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,cAAc,CAAC,CAAC,MAAM,CAAC;QAC5E,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAEzB,OAAO,CAAC,CAAC,CAAE,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzD,MAAM,EAAE,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC;QACrC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,QAAQ,EAAE,CAAC;QAChC,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClD,mEAAmE;QACnE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;QAE9F,8DAA8D;QAC9D,CAAC,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAAC;QACzF,MAAM,EAAE,CAAC,wBAAwB,CAAC,KAAK,CAAC,CAAC;QACzC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACzB,CAAC,CAAC,UAAU,EAAE,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6DAA6D,EAAE,KAAK,IAAI,EAAE;QACzE,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,SAAS,EAAE,CAAC;QAC5C,CAAC,CAAC,MAAM,GAAG,WAAW,CAAC;QACvB,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC;QACb,MAAM,OAAO,GAAG,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,UAAU,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,CAAC;QACnF,MAAM,EAAE,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC;QACrC,kEAAkE;QAClE,CAAC,CAAC,UAAU,GAAG,SAAS,CAAC;QACzB,OAAO,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC,CAAC;QAClB,MAAM,EAAE,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,OAAO,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACvC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;QACnG,CAAC,CAAC,UAAU,EAAE,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;QACtD,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,SAAS,EAAE,CAAC;QACtC,CAAC,CAAC,MAAM,GAAG,WAAW,CAAC;QACvB,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC;QACb,MAAM,OAAO,GAAG,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,UAAU,EAAE,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC1F,MAAM,EAAE,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC;QACrC,OAAO,CAAC,CAAC,CAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC,CAAC;QAC9D,MAAM,EAAE,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,OAAO,CAAC,CAAC,OAAO,CAAC,iDAAiD,CAAC,CAAC;QACjF,CAAC,CAAC,UAAU,EAAE,CAAC;IACnB,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC7B,EAAE,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;QACnF,IAAI,OAAoB,CAAC;QACzB,MAAM,SAAS,GAAG,EAAE,CAAC,EAAE,CACnB,CAAC,EAAU,EAAE,IAAkB,EAAE,EAAE,CAC/B,IAAI,OAAO,CAAW,CAAC,GAAG,EAAE,EAAE;YAC1B,OAAO,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;QACvD,CAAC,CAAC,CACT,CAAC;QACF,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAClC,MAAM,CAAC,GAAG,IAAI,UAAU,EAAE,CAAC;QAC1B,CAA0B,CAAC,aAAa,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAE5E,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1B,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1B,OAAO,EAAE,CAAC;QACV,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAE1B,MAAM,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAClC,CAAC,CAAC,UAAU,EAAE,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,SAAS,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,EAAU,EAAE,IAAkB,EAAE,EAAE,CAC7D,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;QACnC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAClC,MAAM,CAAC,GAAG,IAAI,UAAU,EAAE,CAAC;QAC1B,CAA0B,CAAC,aAAa,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAE5E,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACrD,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,4BAA4B;QAC5C,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACtB,MAAM,KAAK,CAAC;QAEZ,MAAM,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAClC,CAAC,CAAC,UAAU,EAAE,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;QAC/E,IAAI,IAA6B,CAAC;QAClC,EAAE,CAAC,UAAU,CACT,OAAO,EACP,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,EAAU,EAAE,IAAkB,EAAE,EAAE;YAC3C,MAAM,IAAI,GAAG,IAAI,cAAc,CAAa;gBACxC,KAAK,CAAC,CAAC;oBACH,IAAI,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;oBACjD,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;oBACnC,IAAI,EAAE,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CACzC,CAAC,CAAC,KAAK,CAAC,IAAI,YAAY,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,CACrD,CAAC;gBACN,CAAC;aACJ,CAAC,CAAC;YACH,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QAC/C,CAAC,CAAC,CACL,CAAC;QACF,MAAM,CAAC,GAAG,IAAI,UAAU,EAAE,CAAC;QAC1B,CAA0B,CAAC,aAAa,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAC5E,MAAM,YAAY,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7B,CAAC,CAAC,gBAAgB,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;QACjD,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAEtB,0EAA0E;QAC1E,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,CAAC;QACvC,MAAM,EAAE,CAAC,wBAAwB,CAAC,MAAM,CAAC,CAAC;QAC1C,MAAM,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAC5C,kEAAkE;QAClE,IAAI,CAAC,YAAY,CAAC,CAAC;QACnB,MAAM,EAAE,CAAC,wBAAwB,CAAC,KAAK,CAAC,CAAC;QACzC,MAAM,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAC5C,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAClC,CAAC,CAAC,UAAU,EAAE,CAAC;IACnB,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAC9B,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QACvD,6DAA6D;QAC7D,EAAE,CAAC,UAAU,CAAC,uBAAuB,EAAE;YACnC,YAAY,IAA+B,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;SAC9E,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,UAAU,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,CAAyB,CAAC;QACpC,MAAM,oBAAoB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,CAAC,CAAC,GAAG,GAAG,EAAE,oBAAoB,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;QACjD,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAChC,MAAM,CAAC,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QACpG,MAAM,CAAC,oBAAoB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACpD,kEAAkE;QAClE,MAAM,CAAC,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QACrG,MAAM,CAAC,oBAAoB,CAAC,CAAC,oBAAoB,EAAE,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;QACrE,MAAM,CAAC,GAAG,IAAI,UAAU,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,CAAyB,CAAC;QACpC,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC;QAChB,CAAC,CAAC,MAAM,GAAG,WAAW,CAAC;QACvB,CAAC,CAAC,UAAU,GAAG,WAAW,CAAC;QAC3B,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC,CAAC,GAAG,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;QAC/C,CAAC,CAAC,GAAG,GAAG,EAAE,kBAAkB,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;QAC5D,CAAC,CAAC,aAAa,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAClD,CAAC,CAAC,WAAW,CAAC,cAAc,EAAE,CAAC;QAC/B,sEAAsE;QACtE,CAAC,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,CAAC;QACpE,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,QAAQ,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QACxB,CAAC,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QAE9C,CAAC,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAC;QAEjG,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACvC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAC9B,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;QAC7E,EAAE,CAAC,UAAU,CACT,OAAO,EACP,EAAE,CAAC,EAAE,CACD,CAAC,EAAU,EAAE,IAAkB,EAAE,EAAE,CAC/B,IAAI,OAAO,CAAW,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAChC,IAAI,EAAE,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CACzC,GAAG,CAAC,IAAI,YAAY,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,CACjD,CACJ,CACR,CACJ,CAAC;QACF,MAAM,CAAC,GAAG,IAAI,UAAU,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,CAAyB,CAAC;QACpC,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC;QAChB,CAAC,CAAC,OAAO,GAAG,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC1D,IAAI,MAAM,GAAY,SAAS,CAAC;QAChC,KAAK,CAAC,CAAC,iBAAiB,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACxD,MAAM,EAAE,CAAC,wBAAwB,CAAC,MAAM,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;YACnB,MAAM,CAAC,gBAAgB,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;SAC7D,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"end-session-id.test.d.ts","sourceRoot":"","sources":["../../lib/end-session-id.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An endSession only ends the session it names.
|
|
3
|
+
*
|
|
4
|
+
* Central routes endSession by session id to the consumer peer, and a
|
|
5
|
+
* re-dial reuses that peer: a late endSession for the old session (the
|
|
6
|
+
* robot superseding its ghost after our client_redial got lost) must not
|
|
7
|
+
* end the new one. The properties that must hold:
|
|
8
|
+
* - an endSession for a session we already closed is ignored;
|
|
9
|
+
* - an endSession for another id than the current one is ignored;
|
|
10
|
+
* - with no id known yet (startSession in flight) it still applies, so
|
|
11
|
+
* rejections keep working;
|
|
12
|
+
* - after central dropped our session while the link lived on, the
|
|
13
|
+
* robot can still end it under its old id.
|
|
14
|
+
*/
|
|
15
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
16
|
+
import { ReachyMini } from './reachy-mini.js';
|
|
17
|
+
function streamOn(s, sessionId) {
|
|
18
|
+
s._state = 'streaming';
|
|
19
|
+
s._sessionId = sessionId;
|
|
20
|
+
s._dcOpen = true;
|
|
21
|
+
s._dc = { readyState: 'open', close: vi.fn() };
|
|
22
|
+
s._pc = { iceConnectionState: 'connected', close: vi.fn() };
|
|
23
|
+
s._supervisor.stampDcInbound();
|
|
24
|
+
}
|
|
25
|
+
function liveSession(sessionId = 'central-1') {
|
|
26
|
+
const r = new ReachyMini();
|
|
27
|
+
const s = r;
|
|
28
|
+
s._token = 'hf_test';
|
|
29
|
+
s._sendToServer = vi.fn().mockResolvedValue(null);
|
|
30
|
+
streamOn(s, sessionId);
|
|
31
|
+
return { r, s };
|
|
32
|
+
}
|
|
33
|
+
function stoppedEvents(r) {
|
|
34
|
+
const seen = [];
|
|
35
|
+
r.addEventListener('sessionStopped', (e) => seen.push(e.detail));
|
|
36
|
+
return seen;
|
|
37
|
+
}
|
|
38
|
+
beforeEach(() => {
|
|
39
|
+
vi.useFakeTimers();
|
|
40
|
+
});
|
|
41
|
+
afterEach(() => {
|
|
42
|
+
vi.useRealTimers();
|
|
43
|
+
});
|
|
44
|
+
describe('endSession is matched to the current session', () => {
|
|
45
|
+
it("ignores a late end for a re-dial's old session", () => {
|
|
46
|
+
const { r, s } = liveSession('central-1');
|
|
47
|
+
s._teardownForRedial(); // retires central-1
|
|
48
|
+
streamOn(s, 'central-2');
|
|
49
|
+
const stopped = stoppedEvents(r);
|
|
50
|
+
s._handleEndSession({ type: 'endSession', sessionId: 'central-1', reason: 'superseded' });
|
|
51
|
+
expect(stopped).toEqual([]);
|
|
52
|
+
expect(s._state).toBe('streaming');
|
|
53
|
+
expect(s._sessionId).toBe('central-2');
|
|
54
|
+
});
|
|
55
|
+
it('ignores an end for an id that is not ours', () => {
|
|
56
|
+
const { r, s } = liveSession('central-1');
|
|
57
|
+
const stopped = stoppedEvents(r);
|
|
58
|
+
s._handleEndSession({ type: 'endSession', sessionId: 'someone-else', reason: 'robot_stopping' });
|
|
59
|
+
expect(stopped).toEqual([]);
|
|
60
|
+
expect(s._state).toBe('streaming');
|
|
61
|
+
});
|
|
62
|
+
it('still ends the current session', () => {
|
|
63
|
+
const { r, s } = liveSession('central-1');
|
|
64
|
+
const stopped = stoppedEvents(r);
|
|
65
|
+
s._handleEndSession({ type: 'endSession', sessionId: 'central-1', reason: 'robot_stopping' });
|
|
66
|
+
expect(stopped).toEqual([{ reason: 'robot_stopping', message: null }]);
|
|
67
|
+
expect(s._state).toBe('connected');
|
|
68
|
+
});
|
|
69
|
+
it('applies while startSession is in flight, so rejections still land', () => {
|
|
70
|
+
const r = new ReachyMini();
|
|
71
|
+
const s = r;
|
|
72
|
+
s._state = 'connected';
|
|
73
|
+
s._sessionId = null; // the startSession reply has not come back yet
|
|
74
|
+
const reject = vi.fn();
|
|
75
|
+
s._sessionReject = reject;
|
|
76
|
+
s._handleEndSession({ type: 'endSession', sessionId: 'central-9', reason: 'robot_busy_local' });
|
|
77
|
+
expect(reject).toHaveBeenCalledOnce();
|
|
78
|
+
});
|
|
79
|
+
it("a rejected start leaves no id behind to hide the next start's rejection", () => {
|
|
80
|
+
const r = new ReachyMini();
|
|
81
|
+
const s = r;
|
|
82
|
+
s._state = 'connected';
|
|
83
|
+
// First dial: central gave it id X, then the robot refused it.
|
|
84
|
+
s._sessionId = 'central-X';
|
|
85
|
+
const firstReject = vi.fn();
|
|
86
|
+
s._sessionReject = firstReject;
|
|
87
|
+
s._handleEndSession({ type: 'endSession', sessionId: 'central-X', reason: 'robot_busy_local' });
|
|
88
|
+
expect(firstReject).toHaveBeenCalledOnce();
|
|
89
|
+
expect(s._sessionId).toBeNull();
|
|
90
|
+
// Second dial: its rejection (id Y) lands before the startSession
|
|
91
|
+
// reply has set the id. It must still reject this dial.
|
|
92
|
+
const secondReject = vi.fn();
|
|
93
|
+
s._sessionReject = secondReject;
|
|
94
|
+
s._handleEndSession({ type: 'endSession', sessionId: 'central-Y', reason: 'robot_busy_local' });
|
|
95
|
+
expect(secondReject).toHaveBeenCalledOnce();
|
|
96
|
+
// And a late repeat for X is ignored.
|
|
97
|
+
const thirdReject = vi.fn();
|
|
98
|
+
s._sessionReject = thirdReject;
|
|
99
|
+
s._handleEndSession({ type: 'endSession', sessionId: 'central-X', reason: 'robot_busy_local' });
|
|
100
|
+
expect(thirdReject).not.toHaveBeenCalled();
|
|
101
|
+
});
|
|
102
|
+
it('lets the robot end a session central already dropped', () => {
|
|
103
|
+
const { r, s } = liveSession('central-1');
|
|
104
|
+
const stopped = stoppedEvents(r);
|
|
105
|
+
// Central's own eviction: advisory, the link is live.
|
|
106
|
+
s._handleEndSession({ type: 'endSession', sessionId: 'central-1' });
|
|
107
|
+
expect(s._state).toBe('streaming');
|
|
108
|
+
expect(s._sessionId).toBeNull();
|
|
109
|
+
s._handleEndSession({ type: 'endSession', sessionId: 'central-1', reason: 'robot_stopping' });
|
|
110
|
+
expect(stopped).toEqual([{ reason: 'robot_stopping', message: null }]);
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
//# sourceMappingURL=end-session-id.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"end-session-id.test.js","sourceRoot":"","sources":["../../lib/end-session-id.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -23,9 +23,16 @@ export declare class ReachyMini extends EventTarget implements ReachyMiniInstanc
|
|
|
23
23
|
private _username;
|
|
24
24
|
private _tokenExpires;
|
|
25
25
|
private _sseAbortController;
|
|
26
|
+
/** The open in flight (fetch → welcome): a second open joins it. */
|
|
27
|
+
private _signalingOpening;
|
|
28
|
+
private _signalingOpeningController;
|
|
26
29
|
_pc: RTCPeerConnection | null;
|
|
27
30
|
private _dc;
|
|
28
31
|
private _sessionId;
|
|
32
|
+
/** Our session after central dropped it while the peer link lived on. */
|
|
33
|
+
private _staleSessionId;
|
|
34
|
+
/** Sessions we closed: a late endSession for one must not end the next. */
|
|
35
|
+
private _retiredSessionIds;
|
|
29
36
|
private _selectedRobotId;
|
|
30
37
|
private _pendingRemoteIce;
|
|
31
38
|
_micStream: MediaStream | null;
|
|
@@ -109,6 +116,7 @@ export declare class ReachyMini extends EventTarget implements ReachyMiniInstanc
|
|
|
109
116
|
* session keeps streaming without signaling (see `signalingLost`).
|
|
110
117
|
*/
|
|
111
118
|
private _openSignaling;
|
|
119
|
+
private _openSignalingOnce;
|
|
112
120
|
autoConnect(options?: AutoConnectOptions): Promise<AutoConnectResult>;
|
|
113
121
|
private _fetchOwnedRobots;
|
|
114
122
|
private _waitForRobotInList;
|
|
@@ -126,6 +134,14 @@ export declare class ReachyMini extends EventTarget implements ReachyMiniInstanc
|
|
|
126
134
|
* lands — stays with the callers.
|
|
127
135
|
*/
|
|
128
136
|
private _closeTransport;
|
|
137
|
+
private _retireSession;
|
|
138
|
+
/**
|
|
139
|
+
* Whether an endSession is about another session than ours: one we
|
|
140
|
+
* already closed (a re-dial's old session, ended late by the robot as
|
|
141
|
+
* superseded), or any id but the current one. With no id known yet
|
|
142
|
+
* (startSession in flight) it is ours: rejections arrive that way.
|
|
143
|
+
*/
|
|
144
|
+
private _isOtherSession;
|
|
129
145
|
private _failSessionRejected;
|
|
130
146
|
stopSession(): Promise<void>;
|
|
131
147
|
disconnect(): void;
|
|
@@ -1 +1 @@
|
|
|
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,EACV,eAAe,EAEf,wBAAwB,EACxB,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EACrB,MAAM,YAAY,CAAC;AASpB,YAAY,EAAE,mBAAmB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"reachy-mini.d.ts","sourceRoot":"","sources":["../../lib/reachy-mini.ts"],"names":[],"mappings":"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"}
|