obsbot-mcp 0.7.0 → 0.9.0
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/README.md +111 -20
- package/dist/build-info.json +5 -0
- package/dist/device/manager.d.ts +8 -0
- package/dist/device/manager.js +37 -4
- package/dist/device/manager.js.map +1 -1
- package/dist/geometry/aim.d.ts +24 -13
- package/dist/geometry/aim.js +26 -13
- package/dist/geometry/aim.js.map +1 -1
- package/dist/ipc/build-id.d.ts +25 -0
- package/dist/ipc/build-id.js +60 -0
- package/dist/ipc/build-id.js.map +1 -0
- package/dist/ipc/client.d.ts +36 -0
- package/dist/ipc/client.js +106 -4
- package/dist/ipc/client.js.map +1 -1
- package/dist/ipc/coordinator.d.ts +91 -12
- package/dist/ipc/coordinator.js +293 -57
- package/dist/ipc/coordinator.js.map +1 -1
- package/dist/ipc/gate.d.ts +14 -0
- package/dist/ipc/gate.js +45 -0
- package/dist/ipc/gate.js.map +1 -0
- package/dist/ipc/owner.d.ts +27 -1
- package/dist/ipc/owner.js +67 -4
- package/dist/ipc/owner.js.map +1 -1
- package/dist/ipc/protocol.d.ts +30 -0
- package/dist/ipc/protocol.js +40 -0
- package/dist/ipc/protocol.js.map +1 -1
- package/dist/ipc/rendezvous.d.ts +37 -11
- package/dist/ipc/rendezvous.js +143 -30
- package/dist/ipc/rendezvous.js.map +1 -1
- package/dist/mcp/server.js +40 -12
- package/dist/mcp/server.js.map +1 -1
- package/dist/tail2/api.d.ts +381 -0
- package/dist/tail2/api.js +547 -0
- package/dist/tail2/api.js.map +1 -0
- package/dist/tail2/mdns.d.ts +48 -0
- package/dist/tail2/mdns.js +216 -0
- package/dist/tail2/mdns.js.map +1 -0
- package/dist/tail2/move.d.ts +41 -0
- package/dist/tail2/move.js +79 -0
- package/dist/tail2/move.js.map +1 -0
- package/dist/tail2/registry.d.ts +100 -0
- package/dist/tail2/registry.js +200 -0
- package/dist/tail2/registry.js.map +1 -0
- package/dist/tail2/snapshot.d.ts +54 -0
- package/dist/tail2/snapshot.js +157 -0
- package/dist/tail2/snapshot.js.map +1 -0
- package/dist/tail2/tools.d.ts +7 -0
- package/dist/tail2/tools.js +772 -0
- package/dist/tail2/tools.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/native/prebuilt/darwin-arm64/obsbot-helper +0 -0
- package/native/prebuilt/darwin-x64/obsbot-helper +0 -0
- package/native/prebuilt/linux-x64/obsbot-helper +0 -0
- package/native/prebuilt/win32-x64/obsbot-helper.exe +0 -0
- package/package.json +4 -1
package/dist/ipc/coordinator.js
CHANGED
|
@@ -1,31 +1,49 @@
|
|
|
1
|
-
import { elect, rendezvousPath } from "./rendezvous.js";
|
|
1
|
+
import { elect as electEndpoint, rendezvousPath } from "./rendezvous.js";
|
|
2
2
|
import { OwnerServer } from "./owner.js";
|
|
3
3
|
import { OwnerClient } from "./client.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
};
|
|
17
|
-
}
|
|
4
|
+
import { CallGate, StepDownError } from "./gate.js";
|
|
5
|
+
import { buildLabel, compareBuilds, unstampedBuild } from "./build-id.js";
|
|
6
|
+
export const DEFAULT_TIMING = {
|
|
7
|
+
helloTimeoutMs: 2000,
|
|
8
|
+
stepDownGraceMs: 500,
|
|
9
|
+
electionJitterMs: 100,
|
|
10
|
+
stepDownTimeoutMs: 15000,
|
|
11
|
+
releaseTimeoutMs: 10000,
|
|
12
|
+
maxTakeoverRounds: 5,
|
|
13
|
+
};
|
|
14
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
15
|
+
const errText = (e) => (e instanceof Error ? e.message : String(e));
|
|
18
16
|
export class Coordinator {
|
|
19
17
|
runLocal;
|
|
20
|
-
path;
|
|
21
18
|
role = "none";
|
|
22
19
|
client;
|
|
23
20
|
ownerServer;
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
|
|
21
|
+
steppingDown = false;
|
|
22
|
+
/** Client of an owner that is older than us and could not be made to hand over. */
|
|
23
|
+
blocked = false;
|
|
24
|
+
/** Counts the owners this instance has been a client of. Tells one connection from the next. */
|
|
25
|
+
connection = 0;
|
|
26
|
+
closing = false;
|
|
27
|
+
/** A role change in progress — an election, or stepping down. Never rejects. */
|
|
28
|
+
pending;
|
|
29
|
+
/** THE single-camera lock: the owner's own calls and the ones forwarded to it. */
|
|
30
|
+
gate = new CallGate();
|
|
31
|
+
path;
|
|
32
|
+
build;
|
|
33
|
+
pid;
|
|
34
|
+
release;
|
|
35
|
+
log;
|
|
36
|
+
t;
|
|
37
|
+
elect;
|
|
38
|
+
constructor(runLocal, opts = {}) {
|
|
27
39
|
this.runLocal = runLocal;
|
|
28
|
-
this.path = path;
|
|
40
|
+
this.path = opts.path ?? rendezvousPath();
|
|
41
|
+
this.build = opts.build ?? unstampedBuild();
|
|
42
|
+
this.pid = opts.pid ?? process.pid;
|
|
43
|
+
this.release = opts.release ?? (async () => { });
|
|
44
|
+
this.log = opts.log ?? (() => { });
|
|
45
|
+
this.t = { ...DEFAULT_TIMING, ...opts.timing };
|
|
46
|
+
this.elect = opts.elect ?? electEndpoint;
|
|
29
47
|
}
|
|
30
48
|
/** Establish the initial role eagerly at startup. */
|
|
31
49
|
start() {
|
|
@@ -35,59 +53,277 @@ export class Coordinator {
|
|
|
35
53
|
return this.role;
|
|
36
54
|
}
|
|
37
55
|
async dispatch(tool, args) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
56
|
+
let failure;
|
|
57
|
+
// Twice at most: a call that lost its owner is retried exactly once.
|
|
58
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
59
|
+
const target = await this.settle();
|
|
60
|
+
try {
|
|
61
|
+
return target === "local"
|
|
62
|
+
? await this.gate.run(() => this.runLocal(tool, args))
|
|
63
|
+
: await target.request({ tool, args });
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
if (e instanceof StepDownError) {
|
|
67
|
+
// We were the owner and are handing over; this call had not started.
|
|
68
|
+
// settle() waits the handover out, and the retry forwards it.
|
|
69
|
+
failure = e;
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (target !== "local" && target.closed) {
|
|
73
|
+
failure = e;
|
|
74
|
+
this.ownerLost(target);
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
throw e; // a genuine owner-side error → surface it unchanged
|
|
48
78
|
}
|
|
49
|
-
throw e; // a genuine owner-side error → surface it unchanged
|
|
50
79
|
}
|
|
80
|
+
throw failure;
|
|
51
81
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
82
|
+
/**
|
|
83
|
+
* Wait until this instance has a role it may use, and say where a call goes:
|
|
84
|
+
* run here, or forward over this connection.
|
|
85
|
+
*
|
|
86
|
+
* The answer is taken in the same tick the decision is made and handed to the
|
|
87
|
+
* caller. Calls arrive in parallel, and one of them may be reconnecting while
|
|
88
|
+
* another resumes: a caller that re-read `this.client` after an await could
|
|
89
|
+
* find it gone, or pointing at an owner nobody has checked yet.
|
|
90
|
+
*/
|
|
91
|
+
async settle() {
|
|
92
|
+
let asked = false;
|
|
93
|
+
for (let round = 0; round < 8; round++) {
|
|
94
|
+
await this.ensureRole();
|
|
95
|
+
if (this.role === "owner")
|
|
96
|
+
return "local";
|
|
97
|
+
if (this.role !== "client" || !this.client)
|
|
98
|
+
continue; // a role change began while we waited
|
|
99
|
+
if (!this.blocked)
|
|
100
|
+
return this.client;
|
|
101
|
+
// An older owner that could not hand over. Ask once more, then give up:
|
|
102
|
+
// a call that succeeds on code the caller did not expect is worse than
|
|
103
|
+
// one that fails and says why.
|
|
104
|
+
if (asked)
|
|
105
|
+
throw new Error(this.blockedMessage());
|
|
106
|
+
asked = true;
|
|
107
|
+
await this.tryAgain(this.connection);
|
|
108
|
+
}
|
|
109
|
+
throw new Error(`obsbot-mcp: ipc role did not settle for ${this.path}`);
|
|
56
110
|
}
|
|
57
111
|
async close() {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
this.client
|
|
112
|
+
this.closing = true;
|
|
113
|
+
const server = this.ownerServer;
|
|
114
|
+
const client = this.client;
|
|
61
115
|
this.reset();
|
|
116
|
+
client?.close();
|
|
117
|
+
if (server)
|
|
118
|
+
await server.close();
|
|
119
|
+
// A role change that was under way sees `closing` and cleans up after itself.
|
|
120
|
+
while (this.pending)
|
|
121
|
+
await this.pending;
|
|
62
122
|
}
|
|
63
123
|
reset() {
|
|
64
124
|
this.role = "none";
|
|
65
125
|
this.client = undefined;
|
|
66
126
|
this.ownerServer = undefined;
|
|
127
|
+
this.steppingDown = false;
|
|
128
|
+
this.blocked = false;
|
|
129
|
+
}
|
|
130
|
+
jitter() {
|
|
131
|
+
return Math.floor(Math.random() * (this.t.electionJitterMs + 1));
|
|
67
132
|
}
|
|
68
|
-
|
|
133
|
+
/** Queue a role change behind any already under way. The result never rejects. */
|
|
134
|
+
begin(work) {
|
|
135
|
+
const prev = this.pending ?? Promise.resolve();
|
|
136
|
+
const p = prev
|
|
137
|
+
.then(work)
|
|
138
|
+
.catch((e) => this.log(`obsbot-mcp: ipc role change failed: ${errText(e)}`))
|
|
139
|
+
.finally(() => {
|
|
140
|
+
if (this.pending === p)
|
|
141
|
+
this.pending = undefined;
|
|
142
|
+
});
|
|
143
|
+
this.pending = p;
|
|
144
|
+
return p;
|
|
145
|
+
}
|
|
146
|
+
async ensureRole() {
|
|
147
|
+
while (this.pending)
|
|
148
|
+
await this.pending;
|
|
69
149
|
if (this.role !== "none")
|
|
70
|
-
return
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
150
|
+
return;
|
|
151
|
+
if (this.closing)
|
|
152
|
+
throw new Error("obsbot-mcp: ipc coordinator is closed");
|
|
153
|
+
let failed = false;
|
|
154
|
+
let failure;
|
|
155
|
+
await this.begin(async () => {
|
|
156
|
+
try {
|
|
157
|
+
await this.doElect();
|
|
158
|
+
}
|
|
159
|
+
catch (e) {
|
|
160
|
+
failed = true;
|
|
161
|
+
failure = e;
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
if (failed)
|
|
165
|
+
throw failure;
|
|
78
166
|
}
|
|
167
|
+
/**
|
|
168
|
+
* Settle on a role: bind the endpoint, or connect to whoever holds it and
|
|
169
|
+
* compare builds. If ours is newer, ask for the endpoint and go round again.
|
|
170
|
+
*/
|
|
79
171
|
async doElect() {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
this.
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
172
|
+
let takeovers = 0;
|
|
173
|
+
for (let attempt = 0; attempt < this.t.maxTakeoverRounds + 3; attempt++) {
|
|
174
|
+
if (this.closing || this.role !== "none")
|
|
175
|
+
return;
|
|
176
|
+
const r = await this.elect(this.path);
|
|
177
|
+
if (r.role === "owner")
|
|
178
|
+
return this.becomeOwner(r.server);
|
|
179
|
+
const client = OwnerClient.adopt(r.socket);
|
|
180
|
+
let peer;
|
|
181
|
+
try {
|
|
182
|
+
peer = await client.hello(this.build, this.pid, this.t.helloTimeoutMs);
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
client.close(); // the owner went away between connect and hello
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
// An owner that cannot take part in a handover is older than anything that can.
|
|
189
|
+
if (peer.kind !== "peer")
|
|
190
|
+
return this.becomeClient(client, peer, true);
|
|
191
|
+
if (compareBuilds(this.build, peer.build) <= 0)
|
|
192
|
+
return this.becomeClient(client, peer, false);
|
|
193
|
+
// From here on the owner is older than us, so settling as its client means refusing to use it.
|
|
194
|
+
if (takeovers >= this.t.maxTakeoverRounds)
|
|
195
|
+
return this.becomeClient(client, peer, true);
|
|
196
|
+
takeovers++;
|
|
197
|
+
this.log(`obsbot-mcp: ipc takeover requested from pid ${peer.pid}`);
|
|
198
|
+
let granted;
|
|
199
|
+
try {
|
|
200
|
+
granted = await client.takeover(this.build, this.pid, this.t.helloTimeoutMs);
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
granted = true; // closed before it could answer: the endpoint is free either way
|
|
204
|
+
}
|
|
205
|
+
if (!granted || !(await client.waitClosed(this.t.stepDownTimeoutMs))) {
|
|
206
|
+
return this.becomeClient(client, peer, true);
|
|
207
|
+
}
|
|
208
|
+
// The old owner has let go. Go round again and bind.
|
|
209
|
+
}
|
|
210
|
+
throw new Error(`obsbot-mcp: ipc could not settle on an owner for ${this.path}`);
|
|
211
|
+
}
|
|
212
|
+
becomeOwner(server) {
|
|
213
|
+
if (this.closing) {
|
|
214
|
+
server.close();
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
this.ownerServer = new OwnerServer(server, (body) => {
|
|
218
|
+
const { tool, args } = body;
|
|
219
|
+
return this.gate.run(() => this.runLocal(tool, args));
|
|
220
|
+
}, {
|
|
221
|
+
identity: () => ({ build: this.build, pid: this.pid }),
|
|
222
|
+
takeover: (build, pid) => this.onTakeover(build, pid),
|
|
223
|
+
});
|
|
224
|
+
this.role = "owner";
|
|
225
|
+
this.log("obsbot-mcp: ipc role=owner");
|
|
226
|
+
}
|
|
227
|
+
becomeClient(client, peer, blocked) {
|
|
228
|
+
if (this.closing) {
|
|
229
|
+
client.close();
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
this.client = client;
|
|
233
|
+
this.role = "client";
|
|
234
|
+
this.blocked = blocked;
|
|
235
|
+
this.connection++;
|
|
236
|
+
// Re-elect when the connection closes, not when we next have something to
|
|
237
|
+
// send: an idle newer build must not sit disconnected while an older one
|
|
238
|
+
// takes the endpoint and runs calls.
|
|
239
|
+
client.onClose(() => this.ownerLost(client));
|
|
240
|
+
const owner = peer.kind === "peer"
|
|
241
|
+
? `owner-pid=${peer.pid} owner-build=${buildLabel(peer.build)}`
|
|
242
|
+
: "owner-pid=unknown owner-build=legacy";
|
|
243
|
+
this.log(`obsbot-mcp: ipc role=client ${owner}`);
|
|
244
|
+
if (blocked) {
|
|
245
|
+
this.log("obsbot-mcp: ipc owner is older and cannot hand over; tool calls will fail until it exits");
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* The owner is older and still there. Try once more: a fresh connection,
|
|
250
|
+
* hello, takeover.
|
|
251
|
+
*
|
|
252
|
+
* Queued like any other role change, so calls that arrive together wait for
|
|
253
|
+
* it instead of finding the role half torn down. `seen` is the connection the
|
|
254
|
+
* caller was looking at: if that is no longer the current one, someone has
|
|
255
|
+
* asked again since, and asking a second time would tell us nothing new.
|
|
256
|
+
*/
|
|
257
|
+
tryAgain(seen) {
|
|
258
|
+
return this.begin(async () => {
|
|
259
|
+
if (this.role !== "client" || !this.blocked || this.connection !== seen)
|
|
260
|
+
return;
|
|
261
|
+
const client = this.client;
|
|
262
|
+
this.reset(); // first, so closing our own connection is not mistaken for losing the owner
|
|
263
|
+
client?.close();
|
|
264
|
+
await this.doElect();
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
blockedMessage() {
|
|
268
|
+
return ("obsbot-mcp: an older instance owns the camera endpoint and cannot hand it over. " +
|
|
269
|
+
"This instance will not run calls on older code. " +
|
|
270
|
+
`Stop the process listening on ${this.path}; the next call will take over.`);
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* The owner has gone. Re-elect — after the grace period if it stepped down
|
|
274
|
+
* for someone, so the successor binds first; after jitter alone if it simply
|
|
275
|
+
* went, so clients that all lost it at once do not stampede.
|
|
276
|
+
*/
|
|
277
|
+
ownerLost(client) {
|
|
278
|
+
if (this.client !== client || this.closing)
|
|
279
|
+
return;
|
|
280
|
+
const delay = (client.noticed ? this.t.stepDownGraceMs : 0) + this.jitter();
|
|
281
|
+
this.reset();
|
|
282
|
+
void this.begin(async () => {
|
|
283
|
+
await sleep(delay);
|
|
284
|
+
await this.doElect();
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
/** A client asks for the endpoint. Both sides run the same comparison, so this cannot disagree with it. */
|
|
288
|
+
onTakeover(build, pid) {
|
|
289
|
+
if (compareBuilds(build, this.build) <= 0) {
|
|
290
|
+
return { ipc: "takeover", granted: false, reason: "not-newer" };
|
|
291
|
+
}
|
|
292
|
+
this.stepDown(pid);
|
|
293
|
+
return { ipc: "takeover", granted: true };
|
|
294
|
+
}
|
|
295
|
+
stepDown(successorPid) {
|
|
296
|
+
if (this.steppingDown)
|
|
297
|
+
return; // a second request while stepping down needs nothing more
|
|
298
|
+
this.steppingDown = true;
|
|
299
|
+
const server = this.ownerServer;
|
|
300
|
+
this.log(`obsbot-mcp: ipc stepping down for pid ${successorPid}`);
|
|
301
|
+
void this.begin(async () => {
|
|
302
|
+
await this.gate.close(); // the call in flight finishes; nothing else starts
|
|
303
|
+
await server.idle(); // …and its reply has been written
|
|
304
|
+
await this.releaseBounded(); // the successor cannot open the camera until this is done
|
|
305
|
+
await server.stepDown({ ipc: "stepping-down", successorPid });
|
|
306
|
+
this.reset();
|
|
307
|
+
this.gate.open();
|
|
308
|
+
// Let the successor bind before we look for an owner to be a client of.
|
|
309
|
+
await sleep(this.t.stepDownGraceMs + this.jitter());
|
|
310
|
+
await this.doElect();
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
/** A release that throws or never settles must not stop the handover. */
|
|
314
|
+
async releaseBounded() {
|
|
315
|
+
let timer;
|
|
316
|
+
const timeout = new Promise((_, reject) => {
|
|
317
|
+
timer = setTimeout(() => reject(new Error(`release did not finish in ${this.t.releaseTimeoutMs} ms`)), this.t.releaseTimeoutMs);
|
|
318
|
+
});
|
|
319
|
+
try {
|
|
320
|
+
await Promise.race([this.release(), timeout]);
|
|
321
|
+
}
|
|
322
|
+
catch (e) {
|
|
323
|
+
this.log(`obsbot-mcp: ipc release failed while stepping down: ${errText(e)}`);
|
|
87
324
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
this.role = "client";
|
|
325
|
+
finally {
|
|
326
|
+
clearTimeout(timer);
|
|
91
327
|
}
|
|
92
328
|
}
|
|
93
329
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coordinator.js","sourceRoot":"","sources":["../../src/ipc/coordinator.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"coordinator.js","sourceRoot":"","sources":["../../src/ipc/coordinator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,IAAI,aAAa,EAAE,cAAc,EAAa,MAAM,iBAAiB,CAAC;AACpF,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,WAAW,EAAa,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAgB,MAAM,eAAe,CAAC;AAuCxF,MAAM,CAAC,MAAM,cAAc,GAAW;IACpC,cAAc,EAAE,IAAI;IACpB,eAAe,EAAE,GAAG;IACpB,gBAAgB,EAAE,GAAG;IACrB,iBAAiB,EAAE,KAAK;IACxB,gBAAgB,EAAE,KAAK;IACvB,iBAAiB,EAAE,CAAC;CACrB,CAAC;AAoBF,MAAM,KAAK,GAAG,CAAC,EAAU,EAAiB,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AACnF,MAAM,OAAO,GAAG,CAAC,CAAU,EAAU,EAAE,CAAC,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAErF,MAAM,OAAO,WAAW;IAwBH;IAvBX,IAAI,GAAa,MAAM,CAAC;IACxB,MAAM,CAAe;IACrB,WAAW,CAAe;IAC1B,YAAY,GAAG,KAAK,CAAC;IAC7B,mFAAmF;IAC3E,OAAO,GAAG,KAAK,CAAC;IACxB,gGAAgG;IACxF,UAAU,GAAG,CAAC,CAAC;IACf,OAAO,GAAG,KAAK,CAAC;IACxB,gFAAgF;IACxE,OAAO,CAAiB;IAChC,kFAAkF;IACjE,IAAI,GAAG,IAAI,QAAQ,EAAE,CAAC;IAEtB,IAAI,CAAS;IACb,KAAK,CAAU;IACf,GAAG,CAAS;IACZ,OAAO,CAAsB;IAC7B,GAAG,CAAyB;IAC5B,CAAC,CAAS;IACV,KAAK,CAAkC;IAExD,YACmB,QAAkB,EACnC,OAA2B,EAAE;QADZ,aAAQ,GAAR,QAAQ,CAAU;QAGnC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,cAAc,EAAE,CAAC;QAC1C,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,cAAc,EAAE,CAAC;QAC5C,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;QACnC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK,IAAmB,EAAE,GAAE,CAAC,CAAC,CAAC;QAC/D,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAS,EAAE,GAAE,CAAC,CAAC,CAAC;QACxC,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC/C,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,aAAa,CAAC;IAC3C,CAAC;IAED,qDAAqD;IACrD,KAAK;QACH,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;IAC3B,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,IAAY,EAAE,IAA6B;QACxD,IAAI,OAAgB,CAAC;QACrB,qEAAqE;QACrE,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;YAC7C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;YACnC,IAAI,CAAC;gBACH,OAAO,MAAM,KAAK,OAAO;oBACvB,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;oBACtD,CAAC,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3C,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,IAAI,CAAC,YAAY,aAAa,EAAE,CAAC;oBAC/B,qEAAqE;oBACrE,8DAA8D;oBAC9D,OAAO,GAAG,CAAC,CAAC;oBACZ,SAAS;gBACX,CAAC;gBACD,IAAI,MAAM,KAAK,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;oBACxC,OAAO,GAAG,CAAC,CAAC;oBACZ,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;oBACvB,SAAS;gBACX,CAAC;gBACD,MAAM,CAAC,CAAC,CAAC,oDAAoD;YAC/D,CAAC;QACH,CAAC;QACD,MAAM,OAAO,CAAC;IAChB,CAAC;IAED;;;;;;;;OAQG;IACK,KAAK,CAAC,MAAM;QAClB,IAAI,KAAK,GAAG,KAAK,CAAC;QAClB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;YACvC,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;YACxB,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO;gBAAE,OAAO,OAAO,CAAC;YAC1C,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM;gBAAE,SAAS,CAAC,sCAAsC;YAC5F,IAAI,CAAC,IAAI,CAAC,OAAO;gBAAE,OAAO,IAAI,CAAC,MAAM,CAAC;YACtC,wEAAwE;YACxE,uEAAuE;YACvE,+BAA+B;YAC/B,IAAI,KAAK;gBAAE,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;YAClD,KAAK,GAAG,IAAI,CAAC;YACb,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACvC,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,2CAA2C,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC;QAChC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3B,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,MAAM,EAAE,KAAK,EAAE,CAAC;QAChB,IAAI,MAAM;YAAE,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACjC,8EAA8E;QAC9E,OAAO,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,CAAC,OAAO,CAAC;IAC1C,CAAC;IAEO,KAAK;QACX,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;QACxB,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC;QAC7B,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;QAC1B,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;IACvB,CAAC;IAEO,MAAM;QACZ,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAgB,GAAG,CAAC,CAAC,CAAC,CAAC;IACnE,CAAC;IAED,kFAAkF;IAC1E,KAAK,CAAC,IAAyB;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QAC/C,MAAM,CAAC,GAAkB,IAAI;aAC1B,IAAI,CAAC,IAAI,CAAC;aACV,KAAK,CAAC,CAAC,CAAU,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,uCAAuC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;aACpF,OAAO,CAAC,GAAG,EAAE;YACZ,IAAI,IAAI,CAAC,OAAO,KAAK,CAAC;gBAAE,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;QACnD,CAAC,CAAC,CAAC;QACL,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACjB,OAAO,CAAC,CAAC;IACX,CAAC;IAEO,KAAK,CAAC,UAAU;QACtB,OAAO,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,CAAC,OAAO,CAAC;QACxC,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO;QACjC,IAAI,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC3E,IAAI,MAAM,GAAG,KAAK,CAAC;QACnB,IAAI,OAAgB,CAAC;QACrB,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE;YAC1B,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;YACvB,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,GAAG,IAAI,CAAC;gBACd,OAAO,GAAG,CAAC,CAAC;YACd,CAAC;QACH,CAAC,CAAC,CAAC;QACH,IAAI,MAAM;YAAE,MAAM,OAAO,CAAC;IAC5B,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,OAAO;QACnB,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,iBAAiB,GAAG,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;YACxE,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;gBAAE,OAAO;YACjD,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtC,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO;gBAAE,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAE1D,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAC3C,IAAI,IAAU,CAAC;YACf,IAAI,CAAC;gBACH,IAAI,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;YACzE,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,gDAAgD;gBAChE,SAAS;YACX,CAAC;YAED,gFAAgF;YAChF,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;gBAAE,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YACvE,IAAI,aAAa,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;gBAAE,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;YAC9F,+FAA+F;YAC/F,IAAI,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,iBAAiB;gBAAE,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YAExF,SAAS,EAAE,CAAC;YACZ,IAAI,CAAC,GAAG,CAAC,+CAA+C,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YACpE,IAAI,OAAgB,CAAC;YACrB,IAAI,CAAC;gBACH,OAAO,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;YAC/E,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,GAAG,IAAI,CAAC,CAAC,iEAAiE;YACnF,CAAC;YACD,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC;gBACrE,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YAC/C,CAAC;YACD,qDAAqD;QACvD,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,oDAAoD,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACnF,CAAC;IAEO,WAAW,CAAC,MAAkB;QACpC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,CAAC,KAAK,EAAE,CAAC;YACf,OAAO;QACT,CAAC;QACD,IAAI,CAAC,WAAW,GAAG,IAAI,WAAW,CAChC,MAAM,EACN,CAAC,IAAI,EAAE,EAAE;YACP,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,IAAuD,CAAC;YAC/E,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QACxD,CAAC,EACD;YACE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC;YACtD,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,GAAG,CAAC;SACtD,CACF,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC;QACpB,IAAI,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;IACzC,CAAC;IAEO,YAAY,CAAC,MAAmB,EAAE,IAAU,EAAE,OAAgB;QACpE,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,CAAC,KAAK,EAAE,CAAC;YACf,OAAO;QACT,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,0EAA0E;QAC1E,yEAAyE;QACzE,qCAAqC;QACrC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;QAC7C,MAAM,KAAK,GACT,IAAI,CAAC,IAAI,KAAK,MAAM;YAClB,CAAC,CAAC,aAAa,IAAI,CAAC,GAAG,gBAAgB,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;YAC/D,CAAC,CAAC,sCAAsC,CAAC;QAC7C,IAAI,CAAC,GAAG,CAAC,+BAA+B,KAAK,EAAE,CAAC,CAAC;QACjD,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,GAAG,CACN,0FAA0F,CAC3F,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;;;;;OAQG;IACK,QAAQ,CAAC,IAAY;QAC3B,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE;YAC3B,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI;gBAAE,OAAO;YAChF,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;YAC3B,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,4EAA4E;YAC1F,MAAM,EAAE,KAAK,EAAE,CAAC;YAChB,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACvB,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,cAAc;QACpB,OAAO,CACL,kFAAkF;YAClF,kDAAkD;YAClD,iCAAiC,IAAI,CAAC,IAAI,iCAAiC,CAC5E,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACK,SAAS,CAAC,MAAmB;QACnC,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QACnD,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC5E,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE;YACzB,MAAM,KAAK,CAAC,KAAK,CAAC,CAAC;YACnB,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACvB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,2GAA2G;IACnG,UAAU,CAAC,KAAc,EAAE,GAAW;QAC5C,IAAI,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1C,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;QAClE,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACnB,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC5C,CAAC;IAEO,QAAQ,CAAC,YAAoB;QACnC,IAAI,IAAI,CAAC,YAAY;YAAE,OAAO,CAAC,0DAA0D;QACzF,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,MAAM,MAAM,GAAG,IAAI,CAAC,WAAY,CAAC;QACjC,IAAI,CAAC,GAAG,CAAC,yCAAyC,YAAY,EAAE,CAAC,CAAC;QAClE,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE;YACzB,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,mDAAmD;YAC5E,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,kCAAkC;YACvD,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC,0DAA0D;YACvF,MAAM,MAAM,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC,CAAC;YAC9D,IAAI,CAAC,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACjB,wEAAwE;YACxE,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACpD,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACvB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,yEAAyE;IACjE,KAAK,CAAC,cAAc;QAC1B,IAAI,KAAiC,CAAC;QACtC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;YAC/C,KAAK,GAAG,UAAU,CAChB,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,6BAA6B,IAAI,CAAC,CAAC,CAAC,gBAAgB,KAAK,CAAC,CAAC,EAClF,IAAI,CAAC,CAAC,CAAC,gBAAgB,CACxB,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;QAChD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,CAAC,GAAG,CAAC,uDAAuD,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAChF,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Thrown to a call that had not started when the gate closed. */
|
|
2
|
+
export declare class StepDownError extends Error {
|
|
3
|
+
constructor();
|
|
4
|
+
}
|
|
5
|
+
export declare class CallGate {
|
|
6
|
+
private tail;
|
|
7
|
+
private closed;
|
|
8
|
+
/** Run `fn` after every call queued before it. Rejects with StepDownError if the gate closes first. */
|
|
9
|
+
run<T>(fn: () => Promise<T>): Promise<T>;
|
|
10
|
+
/** Refuse calls that have not started; resolve when the running one has finished. */
|
|
11
|
+
close(): Promise<void>;
|
|
12
|
+
/** Accept calls again. */
|
|
13
|
+
open(): void;
|
|
14
|
+
}
|
package/dist/ipc/gate.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// The single-camera lock, with a way to close it.
|
|
3
|
+
//
|
|
4
|
+
// Tool calls run strictly one at a time: the camera is one device and the XU
|
|
5
|
+
// selector-2 reply mailbox is a single shared slot, so two calls in flight at
|
|
6
|
+
// once would interleave on the wire. That part is unchanged from the old
|
|
7
|
+
// serialize() wrapper.
|
|
8
|
+
//
|
|
9
|
+
// What is new is close(). An owner that is handing the endpoint to a newer
|
|
10
|
+
// build must let the call that is RUNNING finish, and must stop every call that
|
|
11
|
+
// has not started — those belong to the new owner now. close() does both, and
|
|
12
|
+
// resolves once nothing is running.
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
/** Thrown to a call that had not started when the gate closed. */
|
|
15
|
+
export class StepDownError extends Error {
|
|
16
|
+
constructor() {
|
|
17
|
+
super("obsbot-mcp: this instance is handing the camera to a newer build");
|
|
18
|
+
this.name = "StepDownError";
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export class CallGate {
|
|
22
|
+
tail = Promise.resolve();
|
|
23
|
+
closed = false;
|
|
24
|
+
/** Run `fn` after every call queued before it. Rejects with StepDownError if the gate closes first. */
|
|
25
|
+
run(fn) {
|
|
26
|
+
const run = this.tail.then(() => {
|
|
27
|
+
if (this.closed)
|
|
28
|
+
throw new StepDownError();
|
|
29
|
+
return fn();
|
|
30
|
+
});
|
|
31
|
+
// Errors don't break the chain.
|
|
32
|
+
this.tail = run.then(() => undefined, () => undefined);
|
|
33
|
+
return run;
|
|
34
|
+
}
|
|
35
|
+
/** Refuse calls that have not started; resolve when the running one has finished. */
|
|
36
|
+
async close() {
|
|
37
|
+
this.closed = true;
|
|
38
|
+
await this.tail;
|
|
39
|
+
}
|
|
40
|
+
/** Accept calls again. */
|
|
41
|
+
open() {
|
|
42
|
+
this.closed = false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate.js","sourceRoot":"","sources":["../../src/ipc/gate.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,kDAAkD;AAClD,EAAE;AACF,6EAA6E;AAC7E,8EAA8E;AAC9E,yEAAyE;AACzE,uBAAuB;AACvB,EAAE;AACF,2EAA2E;AAC3E,gFAAgF;AAChF,8EAA8E;AAC9E,oCAAoC;AACpC,8EAA8E;AAE9E,kEAAkE;AAClE,MAAM,OAAO,aAAc,SAAQ,KAAK;IACtC;QACE,KAAK,CAAC,kEAAkE,CAAC,CAAC;QAC1E,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAED,MAAM,OAAO,QAAQ;IACX,IAAI,GAAqB,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3C,MAAM,GAAG,KAAK,CAAC;IAEvB,uGAAuG;IACvG,GAAG,CAAI,EAAoB;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;YAC9B,IAAI,IAAI,CAAC,MAAM;gBAAE,MAAM,IAAI,aAAa,EAAE,CAAC;YAC3C,OAAO,EAAE,EAAE,CAAC;QACd,CAAC,CAAC,CAAC;QACH,gCAAgC;QAChC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAClB,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,SAAS,CAChB,CAAC;QACF,OAAO,GAAG,CAAC;IACb,CAAC;IAED,qFAAqF;IACrF,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,MAAM,IAAI,CAAC,IAAI,CAAC;IAClB,CAAC;IAED,0BAA0B;IAC1B,IAAI;QACF,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;CACF"}
|
package/dist/ipc/owner.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import net from "node:net";
|
|
2
|
+
import type { BuildId } from "./build-id.js";
|
|
3
|
+
import { type SteppingDownBody, type TakeoverResult } from "./protocol.js";
|
|
2
4
|
export type Handler = (body: unknown) => Promise<unknown>;
|
|
3
5
|
export type ReplyBody = {
|
|
4
6
|
ok: true;
|
|
@@ -7,15 +9,39 @@ export type ReplyBody = {
|
|
|
7
9
|
ok: false;
|
|
8
10
|
error: string;
|
|
9
11
|
};
|
|
12
|
+
export interface ControlHandlers {
|
|
13
|
+
/** This instance's identity, for the hello reply. */
|
|
14
|
+
identity: () => {
|
|
15
|
+
build: BuildId;
|
|
16
|
+
pid: number;
|
|
17
|
+
};
|
|
18
|
+
/** A client asks for the endpoint. Decide; if granted, the caller starts stepping down. */
|
|
19
|
+
takeover: (build: BuildId, pid: number) => TakeoverResult;
|
|
20
|
+
}
|
|
10
21
|
export declare class OwnerServer {
|
|
11
22
|
private readonly server;
|
|
12
23
|
private readonly handle;
|
|
24
|
+
private readonly control;
|
|
13
25
|
/** Single promise chain → exactly one handler call runs at a time. */
|
|
14
26
|
private queue;
|
|
15
27
|
private readonly sockets;
|
|
16
|
-
constructor(server: net.Server, handle: Handler);
|
|
28
|
+
constructor(server: net.Server, handle: Handler, control: ControlHandlers);
|
|
17
29
|
private accept;
|
|
30
|
+
/** Answer a control message at once, outside the queue. False if `msg` is not one. */
|
|
31
|
+
private answerControl;
|
|
18
32
|
private enqueue;
|
|
33
|
+
/** The reply for a request, or undefined when the request must go unanswered. */
|
|
19
34
|
private run;
|
|
35
|
+
/** Resolves once every request received so far has been answered or dropped. */
|
|
36
|
+
idle(): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Give up the endpoint in an orderly way: free the name, tell every client
|
|
39
|
+
* why, and let what is already written reach them.
|
|
40
|
+
*
|
|
41
|
+
* end(), not destroy(): destroy() discards whatever is still buffered, which
|
|
42
|
+
* would lose the notice and could truncate the reply to the call that just
|
|
43
|
+
* finished — a snapshot is megabytes.
|
|
44
|
+
*/
|
|
45
|
+
stepDown(notice: SteppingDownBody): Promise<void>;
|
|
20
46
|
close(): Promise<void>;
|
|
21
47
|
}
|
package/dist/ipc/owner.js
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { StepDownError } from "./gate.js";
|
|
2
|
+
import { encodeFrame, FrameDecoder, NOTICE_ID, asHello, asTakeover, } from "./protocol.js";
|
|
3
|
+
/** How long a client gets to close its end after we have ended ours. */
|
|
4
|
+
const STRAGGLER_MS = 1000;
|
|
2
5
|
export class OwnerServer {
|
|
3
6
|
server;
|
|
4
7
|
handle;
|
|
8
|
+
control;
|
|
5
9
|
/** Single promise chain → exactly one handler call runs at a time. */
|
|
6
10
|
queue = Promise.resolve();
|
|
7
11
|
sockets = new Set();
|
|
8
|
-
constructor(server, handle) {
|
|
12
|
+
constructor(server, handle, control) {
|
|
9
13
|
this.server = server;
|
|
10
14
|
this.handle = handle;
|
|
15
|
+
this.control = control;
|
|
11
16
|
this.server.on("connection", (sock) => this.accept(sock));
|
|
12
17
|
}
|
|
13
18
|
accept(sock) {
|
|
@@ -22,8 +27,10 @@ export class OwnerServer {
|
|
|
22
27
|
sock.destroy(); // unrecoverable framing error → drop this client
|
|
23
28
|
return;
|
|
24
29
|
}
|
|
25
|
-
for (const msg of msgs)
|
|
26
|
-
this.
|
|
30
|
+
for (const msg of msgs) {
|
|
31
|
+
if (!this.answerControl(sock, msg))
|
|
32
|
+
this.enqueue(sock, msg);
|
|
33
|
+
}
|
|
27
34
|
});
|
|
28
35
|
const drop = () => {
|
|
29
36
|
this.sockets.delete(sock);
|
|
@@ -31,24 +38,80 @@ export class OwnerServer {
|
|
|
31
38
|
sock.on("close", drop);
|
|
32
39
|
sock.on("error", drop);
|
|
33
40
|
}
|
|
41
|
+
/** Answer a control message at once, outside the queue. False if `msg` is not one. */
|
|
42
|
+
answerControl(sock, msg) {
|
|
43
|
+
const reply = (result) => {
|
|
44
|
+
if (!sock.destroyed)
|
|
45
|
+
sock.write(encodeFrame({ id: msg.id, body: { ok: true, result } }));
|
|
46
|
+
};
|
|
47
|
+
if (asHello(msg.body)) {
|
|
48
|
+
reply({ ipc: "hello", ...this.control.identity() });
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
const takeover = asTakeover(msg.body);
|
|
52
|
+
if (takeover) {
|
|
53
|
+
// Written before anything the grant sets in motion can close this socket.
|
|
54
|
+
reply(this.control.takeover(takeover.build, takeover.pid));
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
34
59
|
enqueue(sock, msg) {
|
|
35
60
|
// Chain onto the shared queue so requests run one-at-a-time across all
|
|
36
61
|
// clients. The chain never rejects (errors become error replies), so one
|
|
37
62
|
// failing op can't stall the rest.
|
|
38
63
|
this.queue = this.queue.then(async () => {
|
|
39
64
|
const body = await this.run(msg.body);
|
|
65
|
+
if (body === undefined)
|
|
66
|
+
return;
|
|
40
67
|
if (!sock.destroyed)
|
|
41
68
|
sock.write(encodeFrame({ id: msg.id, body }));
|
|
42
69
|
});
|
|
43
70
|
}
|
|
71
|
+
/** The reply for a request, or undefined when the request must go unanswered. */
|
|
44
72
|
async run(reqBody) {
|
|
45
73
|
try {
|
|
46
74
|
return { ok: true, result: await this.handle(reqBody) };
|
|
47
75
|
}
|
|
48
76
|
catch (e) {
|
|
77
|
+
// The gate closed before this call started: it belongs to the next owner.
|
|
78
|
+
// An error reply would be wrong — the client would surface it. Left
|
|
79
|
+
// unanswered, the closing socket makes the client retry it there.
|
|
80
|
+
if (e instanceof StepDownError)
|
|
81
|
+
return undefined;
|
|
49
82
|
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
50
83
|
}
|
|
51
84
|
}
|
|
85
|
+
/** Resolves once every request received so far has been answered or dropped. */
|
|
86
|
+
idle() {
|
|
87
|
+
return this.queue;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Give up the endpoint in an orderly way: free the name, tell every client
|
|
91
|
+
* why, and let what is already written reach them.
|
|
92
|
+
*
|
|
93
|
+
* end(), not destroy(): destroy() discards whatever is still buffered, which
|
|
94
|
+
* would lose the notice and could truncate the reply to the call that just
|
|
95
|
+
* finished — a snapshot is megabytes.
|
|
96
|
+
*/
|
|
97
|
+
async stepDown(notice) {
|
|
98
|
+
// Stops listening now, which frees the endpoint for the successor; the
|
|
99
|
+
// callback waits for the connections below to finish closing.
|
|
100
|
+
const closed = new Promise((resolve) => this.server.close(() => resolve()));
|
|
101
|
+
for (const s of this.sockets) {
|
|
102
|
+
if (s.destroyed)
|
|
103
|
+
continue;
|
|
104
|
+
s.write(encodeFrame({ id: NOTICE_ID, body: notice }));
|
|
105
|
+
s.end();
|
|
106
|
+
}
|
|
107
|
+
const stragglers = setTimeout(() => {
|
|
108
|
+
for (const s of this.sockets)
|
|
109
|
+
s.destroy();
|
|
110
|
+
}, STRAGGLER_MS);
|
|
111
|
+
await closed;
|
|
112
|
+
clearTimeout(stragglers);
|
|
113
|
+
this.sockets.clear();
|
|
114
|
+
}
|
|
52
115
|
async close() {
|
|
53
116
|
for (const s of this.sockets)
|
|
54
117
|
s.destroy();
|
package/dist/ipc/owner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"owner.js","sourceRoot":"","sources":["../../src/ipc/owner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"owner.js","sourceRoot":"","sources":["../../src/ipc/owner.ts"],"names":[],"mappings":"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"}
|