@basmilius/apple-companion-link 0.3.2 → 0.4.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/dist/index.js +32 -17
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -189,33 +189,36 @@ import { randomInt } from "node:crypto";
|
|
|
189
189
|
import { Chacha20, ENCRYPTION, EncryptionAwareConnection } from "@basmilius/apple-common";
|
|
190
190
|
import { OPack } from "@basmilius/apple-encoding";
|
|
191
191
|
var HEADER_SIZE = 4;
|
|
192
|
+
var PAIRING_QUEUE_IDENTIFIER = -1;
|
|
192
193
|
|
|
193
194
|
class Stream extends EncryptionAwareConnection {
|
|
194
195
|
get #encryptionState() {
|
|
195
196
|
return this[ENCRYPTION];
|
|
196
197
|
}
|
|
197
|
-
#queue =
|
|
198
|
+
#queue = new Map;
|
|
198
199
|
#buffer = Buffer.alloc(0);
|
|
199
200
|
#xid;
|
|
200
201
|
constructor(context, address, port) {
|
|
201
202
|
super(context, address, port);
|
|
202
203
|
this.#xid = randomInt(0, 2 ** 16);
|
|
204
|
+
this.on("close", this.#onClose.bind(this));
|
|
203
205
|
this.on("data", this.#onData.bind(this));
|
|
206
|
+
this.on("error", this.#onError.bind(this));
|
|
204
207
|
}
|
|
205
208
|
async exchange(type, obj) {
|
|
206
209
|
const _x = this.#xid;
|
|
207
210
|
return new Promise((resolve, reject) => {
|
|
208
211
|
if (PairFrameTypes.includes(type)) {
|
|
209
|
-
this.#queue[
|
|
212
|
+
this.#queue.set(PAIRING_QUEUE_IDENTIFIER, [resolve, reject]);
|
|
210
213
|
} else {
|
|
211
|
-
this.#queue
|
|
214
|
+
this.#queue.set(_x, [resolve, reject]);
|
|
212
215
|
}
|
|
213
216
|
this.send(type, obj).catch(reject);
|
|
214
217
|
});
|
|
215
218
|
}
|
|
216
219
|
async send(type, obj) {
|
|
217
220
|
const _x = this.#xid++;
|
|
218
|
-
obj._x ??= OPack.
|
|
221
|
+
obj._x ??= OPack.sizedInteger(_x, 8);
|
|
219
222
|
let payload = Buffer.from(OPack.encode(obj));
|
|
220
223
|
let payloadLength = payload.byteLength;
|
|
221
224
|
if (this.isEncrypted && payloadLength > 0) {
|
|
@@ -241,6 +244,13 @@ class Stream extends EncryptionAwareConnection {
|
|
|
241
244
|
this.emit("error", err);
|
|
242
245
|
}
|
|
243
246
|
}
|
|
247
|
+
#onClose() {
|
|
248
|
+
const error = new Error("Connection closed while waiting for response");
|
|
249
|
+
for (const [, reject] of this.#queue.values()) {
|
|
250
|
+
reject(error);
|
|
251
|
+
}
|
|
252
|
+
this.#queue.clear();
|
|
253
|
+
}
|
|
244
254
|
async#onData(data) {
|
|
245
255
|
this.#buffer = Buffer.concat([this.#buffer, data]);
|
|
246
256
|
try {
|
|
@@ -267,6 +277,12 @@ class Stream extends EncryptionAwareConnection {
|
|
|
267
277
|
this.emit("error", err);
|
|
268
278
|
}
|
|
269
279
|
}
|
|
280
|
+
#onError(err) {
|
|
281
|
+
for (const [, reject] of this.#queue.values()) {
|
|
282
|
+
reject(err);
|
|
283
|
+
}
|
|
284
|
+
this.#queue.clear();
|
|
285
|
+
}
|
|
270
286
|
#decrypt(data) {
|
|
271
287
|
const header = data.subarray(0, 4);
|
|
272
288
|
const payloadLength = header.readUintBE(1, 3);
|
|
@@ -287,25 +303,24 @@ class Stream extends EncryptionAwareConnection {
|
|
|
287
303
|
payload = OPack.decode(payload);
|
|
288
304
|
this.context.logger.raw("[companion-link]", "Decoded OPACK", { header, payload });
|
|
289
305
|
if ("_x" in payload) {
|
|
290
|
-
const _x = payload
|
|
291
|
-
if (
|
|
292
|
-
const resolve = this.#queue
|
|
293
|
-
resolve
|
|
294
|
-
|
|
306
|
+
const _x = Number(payload["_x"]);
|
|
307
|
+
if (this.#queue.has(_x)) {
|
|
308
|
+
const [resolve] = this.#queue.get(_x);
|
|
309
|
+
resolve([header, payload]);
|
|
310
|
+
this.#queue.delete(_x);
|
|
295
311
|
} else if ("_i" in payload) {
|
|
296
312
|
this.emit(payload["_i"], payload["_c"]);
|
|
297
313
|
} else {
|
|
298
314
|
const content = payload["_c"];
|
|
299
|
-
const keys = Object.keys(content).map((k) => k.
|
|
315
|
+
const keys = Object.keys(content).map((k) => k.slice(0, -3));
|
|
300
316
|
for (const key of keys) {
|
|
301
317
|
this.emit(key, content[key]);
|
|
302
318
|
}
|
|
303
319
|
}
|
|
304
|
-
} else if (this.#queue
|
|
305
|
-
const
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
delete this.#queue[_x];
|
|
320
|
+
} else if (this.#queue.has(PAIRING_QUEUE_IDENTIFIER)) {
|
|
321
|
+
const [resolve] = this.#queue.get(PAIRING_QUEUE_IDENTIFIER);
|
|
322
|
+
resolve([header, payload]);
|
|
323
|
+
this.#queue.delete(PAIRING_QUEUE_IDENTIFIER);
|
|
309
324
|
} else {
|
|
310
325
|
this.context.logger.warn("[companion-link]", "No handler for message", [header, payload]);
|
|
311
326
|
}
|
|
@@ -601,10 +616,10 @@ class Protocol {
|
|
|
601
616
|
}
|
|
602
617
|
}
|
|
603
618
|
function objectOrFail(obj) {
|
|
604
|
-
if (typeof obj === "object") {
|
|
619
|
+
if (obj !== null && typeof obj === "object") {
|
|
605
620
|
return obj;
|
|
606
621
|
}
|
|
607
|
-
throw new
|
|
622
|
+
throw new TypeError("Expected an object.");
|
|
608
623
|
}
|
|
609
624
|
export {
|
|
610
625
|
convertAttentionState,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@basmilius/apple-companion-link",
|
|
3
3
|
"description": "Implementation of Apple's Companion Link in Node.js.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.4.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": {
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
}
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@basmilius/apple-common": "0.
|
|
44
|
-
"@basmilius/apple-encoding": "0.
|
|
43
|
+
"@basmilius/apple-common": "0.4.0",
|
|
44
|
+
"@basmilius/apple-encoding": "0.4.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@basmilius/tools": "^2.23.0",
|