@basmilius/apple-devices 0.1.3 → 0.2.1

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.
@@ -18,7 +18,7 @@ export default class extends EventEmitter<EventMap> {
18
18
  get volume(): Volume;
19
19
  get timingServer(): TimingServer | undefined;
20
20
  set timingServer(timingServer: TimingServer | undefined);
21
- constructor(discoveryResult: DiscoveryResult);
21
+ constructor(deviceId: string, discoveryResult: DiscoveryResult);
22
22
  connect(): Promise<void>;
23
23
  disconnect(): Promise<void>;
24
24
  disconnectSafely(): Promise<void>;
@@ -34,23 +34,23 @@ export default class extends EventEmitter<EventMap> {
34
34
  get volumeCapabilities(): Proto.VolumeCapabilities_Enum;
35
35
  constructor(device: Device);
36
36
  clear(): void;
37
- onDeviceInfo(message: Proto.DeviceInfoMessage): Promise<void>;
38
- onDeviceInfoUpdate(message: Proto.DeviceInfoMessage): Promise<void>;
39
- onOriginClientProperties(message: Proto.OriginClientPropertiesMessage): Promise<void>;
40
- onPlayerClientProperties(message: Proto.PlayerClientPropertiesMessage): Promise<void>;
41
- onRemoveClient(message: Proto.RemoveClientMessage): Promise<void>;
42
- onSendCommandResult(message: Proto.SendCommandResultMessage): Promise<void>;
43
- onSetArtwork(message: Proto.SetArtworkMessage): Promise<void>;
44
- onSetDefaultSupportedCommands(message: Proto.SetDefaultSupportedCommandsMessage): Promise<void>;
45
- onSetNowPlayingClient(message: Proto.SetNowPlayingClientMessage): Promise<void>;
46
- onSetNowPlayingPlayer(message: Proto.SetNowPlayingPlayerMessage): Promise<void>;
47
- onSetState(message: Proto.SetStateMessage): Promise<void>;
48
- onUpdateContentItem(message: Proto.UpdateContentItemMessage): Promise<void>;
49
- onUpdateContentItemArtwork(message: Proto.UpdateContentItemArtworkMessage): Promise<void>;
50
- onUpdatePlayer(message: Proto.UpdatePlayerMessage): Promise<void>;
51
- onUpdateClient(message: Proto.UpdateClientMessage): Promise<void>;
52
- onUpdateOutputDevice(message: Proto.UpdateOutputDeviceMessage): Promise<void>;
53
- onVolumeControlAvailability(message: Proto.VolumeControlAvailabilityMessage): Promise<void>;
54
- onVolumeControlCapabilitiesDidChange(message: Proto.VolumeControlCapabilitiesDidChangeMessage): Promise<void>;
55
- onVolumeDidChange(message: Proto.VolumeDidChangeMessage): Promise<void>;
37
+ onDeviceInfo(message: Proto.DeviceInfoMessage): void;
38
+ onDeviceInfoUpdate(message: Proto.DeviceInfoMessage): void;
39
+ onOriginClientProperties(message: Proto.OriginClientPropertiesMessage): void;
40
+ onPlayerClientProperties(message: Proto.PlayerClientPropertiesMessage): void;
41
+ onRemoveClient(message: Proto.RemoveClientMessage): void;
42
+ onSendCommandResult(message: Proto.SendCommandResultMessage): void;
43
+ onSetArtwork(message: Proto.SetArtworkMessage): void;
44
+ onSetDefaultSupportedCommands(message: Proto.SetDefaultSupportedCommandsMessage): void;
45
+ onSetNowPlayingClient(message: Proto.SetNowPlayingClientMessage): void;
46
+ onSetNowPlayingPlayer(message: Proto.SetNowPlayingPlayerMessage): void;
47
+ onSetState(message: Proto.SetStateMessage): void;
48
+ onUpdateContentItem(message: Proto.UpdateContentItemMessage): void;
49
+ onUpdateContentItemArtwork(message: Proto.UpdateContentItemArtworkMessage): void;
50
+ onUpdatePlayer(message: Proto.UpdatePlayerMessage): void;
51
+ onUpdateClient(message: Proto.UpdateClientMessage): void;
52
+ onUpdateOutputDevice(message: Proto.UpdateOutputDeviceMessage): void;
53
+ onVolumeControlAvailability(message: Proto.VolumeControlAvailabilityMessage): void;
54
+ onVolumeControlCapabilitiesDidChange(message: Proto.VolumeControlCapabilitiesDidChangeMessage): void;
55
+ onVolumeDidChange(message: Proto.VolumeDidChangeMessage): void;
56
56
  }
@@ -1,6 +1,6 @@
1
1
  import { EventEmitter } from "node:events";
2
2
  import type { AccessoryCredentials, DiscoveryResult } from "@basmilius/apple-common";
3
- import type { AttentionState, ButtonPressType, HidCommandKey, LaunchableApp, MediaControlCommandKey, UserAccount } from "@basmilius/apple-companion-link";
3
+ import { type AttentionState, type ButtonPressType, type HidCommandKey, type LaunchableApp, type MediaControlCommandKey, type UserAccount } from "@basmilius/apple-companion-link";
4
4
  type EventMap = {
5
5
  connected: [];
6
6
  disconnected: [unexpected: boolean];
@@ -11,7 +11,7 @@ export default class extends EventEmitter<EventMap> {
11
11
  get discoveryResult(): DiscoveryResult;
12
12
  set discoveryResult(discoveryResult: DiscoveryResult);
13
13
  get isConnected(): boolean;
14
- constructor(discoveryResult: DiscoveryResult);
14
+ constructor(deviceId: string, discoveryResult: DiscoveryResult);
15
15
  connect(): Promise<void>;
16
16
  disconnect(): Promise<void>;
17
17
  disconnectSafely(): Promise<void>;
package/dist/index.js CHANGED
@@ -16,12 +16,11 @@ var STATE_SUBSCRIBE_SYMBOL = Symbol("com.basmilius.airplay:subscribe");
16
16
  var STATE_UNSUBSCRIBE_SYMBOL = Symbol("com.basmilius.airplay:unsubscribe");
17
17
  // src/airplay/device.ts
18
18
  import { EventEmitter as EventEmitter2 } from "node:events";
19
- import { AirPlay as AirPlay2, DataStreamMessage as DataStreamMessage3, Proto as Proto5 } from "@basmilius/apple-airplay";
20
- import { reporter as reporter2, waitFor as waitFor2 } from "@basmilius/apple-common";
19
+ import { DataStreamMessage as DataStreamMessage3, Proto as Proto5, Protocol } from "@basmilius/apple-airplay";
20
+ import { waitFor as waitFor2 } from "@basmilius/apple-common";
21
21
 
22
22
  // src/airplay/remote.ts
23
- import { DataStreamMessage } from "@basmilius/apple-airplay";
24
- import { Proto } from "@basmilius/apple-airplay";
23
+ import { DataStreamMessage, Proto } from "@basmilius/apple-airplay";
25
24
  import { waitFor } from "@basmilius/apple-common";
26
25
  class remote_default {
27
26
  get #dataStream() {
@@ -1270,7 +1269,7 @@ class state_default extends EventEmitter {
1270
1269
  this.onVolumeControlCapabilitiesDidChange = this.onVolumeControlCapabilitiesDidChange.bind(this);
1271
1270
  this.onVolumeDidChange = this.onVolumeDidChange.bind(this);
1272
1271
  }
1273
- async[STATE_SUBSCRIBE_SYMBOL]() {
1272
+ [STATE_SUBSCRIBE_SYMBOL]() {
1274
1273
  this.#dataStream.on("deviceInfo", this.onDeviceInfo);
1275
1274
  this.#dataStream.on("deviceInfoUpdate", this.onDeviceInfoUpdate);
1276
1275
  this.#dataStream.on("originClientProperties", this.onOriginClientProperties);
@@ -1291,7 +1290,7 @@ class state_default extends EventEmitter {
1291
1290
  this.#dataStream.on("volumeControlCapabilitiesDidChange", this.onVolumeControlCapabilitiesDidChange);
1292
1291
  this.#dataStream.on("volumeDidChange", this.onVolumeDidChange);
1293
1292
  }
1294
- async[STATE_UNSUBSCRIBE_SYMBOL]() {
1293
+ [STATE_UNSUBSCRIBE_SYMBOL]() {
1295
1294
  const dataStream = this.#dataStream;
1296
1295
  if (!dataStream) {
1297
1296
  return;
@@ -1324,7 +1323,7 @@ class state_default extends EventEmitter {
1324
1323
  this.#volumeAvailable = false;
1325
1324
  this.#volumeCapabilities = Proto3.VolumeCapabilities_Enum.None;
1326
1325
  }
1327
- async onDeviceInfo(message) {
1326
+ onDeviceInfo(message) {
1328
1327
  if (message.clusterID) {
1329
1328
  this.#outputDeviceUID = message.clusterID;
1330
1329
  } else if (message.deviceUID) {
@@ -1334,7 +1333,7 @@ class state_default extends EventEmitter {
1334
1333
  }
1335
1334
  this.emit("deviceInfo", message);
1336
1335
  }
1337
- async onDeviceInfoUpdate(message) {
1336
+ onDeviceInfoUpdate(message) {
1338
1337
  if (message.clusterID) {
1339
1338
  this.#outputDeviceUID = message.clusterID;
1340
1339
  } else if (message.deviceUID) {
@@ -1344,36 +1343,36 @@ class state_default extends EventEmitter {
1344
1343
  }
1345
1344
  this.emit("deviceInfoUpdate", message);
1346
1345
  }
1347
- async onOriginClientProperties(message) {
1346
+ onOriginClientProperties(message) {
1348
1347
  this.emit("originClientProperties", message);
1349
1348
  }
1350
- async onPlayerClientProperties(message) {
1349
+ onPlayerClientProperties(message) {
1351
1350
  this.emit("playerClientProperties", message);
1352
1351
  }
1353
- async onRemoveClient(message) {
1352
+ onRemoveClient(message) {
1354
1353
  if (!(message.client.bundleIdentifier in this.#clients)) {
1355
1354
  return;
1356
1355
  }
1357
1356
  delete this.#clients[message.client.bundleIdentifier];
1358
1357
  this.emit("clients", this.#clients);
1359
1358
  }
1360
- async onSendCommandResult(message) {
1359
+ onSendCommandResult(message) {
1361
1360
  this.emit("sendCommandResult", message);
1362
1361
  }
1363
- async onSetArtwork(message) {
1362
+ onSetArtwork(message) {
1364
1363
  this.emit("setArtwork", message);
1365
1364
  }
1366
- async onSetDefaultSupportedCommands(message) {
1365
+ onSetDefaultSupportedCommands(message) {
1367
1366
  this.emit("setDefaultSupportedCommands", message);
1368
1367
  }
1369
- async onSetNowPlayingClient(message) {
1368
+ onSetNowPlayingClient(message) {
1370
1369
  this.#nowPlayingClientBundleIdentifier = message.client?.bundleIdentifier ?? null;
1371
1370
  this.emit("setNowPlayingClient", message);
1372
1371
  }
1373
- async onSetNowPlayingPlayer(message) {
1372
+ onSetNowPlayingPlayer(message) {
1374
1373
  this.emit("setNowPlayingPlayer", message);
1375
1374
  }
1376
- async onSetState(message) {
1375
+ onSetState(message) {
1377
1376
  const client = this.#client(message.playerPath.client.bundleIdentifier, message.displayName);
1378
1377
  if (message.playbackState) {
1379
1378
  client.setPlaybackState(message.playbackState, message.playbackStateTimestamp);
@@ -1386,7 +1385,7 @@ class state_default extends EventEmitter {
1386
1385
  }
1387
1386
  this.emit("setState", message);
1388
1387
  }
1389
- async onUpdateContentItem(message) {
1388
+ onUpdateContentItem(message) {
1390
1389
  const client = this.#client(message.playerPath.client.bundleIdentifier, message.playerPath.client.displayName);
1391
1390
  if (!client) {
1392
1391
  return;
@@ -1396,30 +1395,30 @@ class state_default extends EventEmitter {
1396
1395
  }
1397
1396
  this.emit("updateContentItem", message);
1398
1397
  }
1399
- async onUpdateContentItemArtwork(message) {
1398
+ onUpdateContentItemArtwork(message) {
1400
1399
  this.emit("updateContentItemArtwork", message);
1401
1400
  }
1402
- async onUpdatePlayer(message) {
1401
+ onUpdatePlayer(message) {
1403
1402
  this.emit("updatePlayer", message);
1404
1403
  }
1405
- async onUpdateClient(message) {
1404
+ onUpdateClient(message) {
1406
1405
  this.#client(message.client.bundleIdentifier, message.client.displayName);
1407
1406
  this.emit("clients", this.#clients);
1408
1407
  }
1409
- async onUpdateOutputDevice(message) {
1408
+ onUpdateOutputDevice(message) {
1410
1409
  this.emit("updateOutputDevice", message);
1411
1410
  }
1412
- async onVolumeControlAvailability(message) {
1411
+ onVolumeControlAvailability(message) {
1413
1412
  this.#volumeAvailable = message.volumeControlAvailable;
1414
1413
  this.#volumeCapabilities = message.volumeCapabilities;
1415
1414
  this.emit("volumeControlAvailability", message.volumeControlAvailable, message.volumeCapabilities);
1416
1415
  }
1417
- async onVolumeControlCapabilitiesDidChange(message) {
1416
+ onVolumeControlCapabilitiesDidChange(message) {
1418
1417
  this.#volumeAvailable = message.capabilities.volumeControlAvailable;
1419
1418
  this.#volumeCapabilities = message.capabilities.volumeCapabilities;
1420
1419
  this.emit("volumeControlCapabilitiesDidChange", message.capabilities.volumeControlAvailable, message.capabilities.volumeCapabilities);
1421
1420
  }
1422
- async onVolumeDidChange(message) {
1421
+ onVolumeDidChange(message) {
1423
1422
  this.#volume = message.volume;
1424
1423
  this.emit("volumeDidChange", message.volume);
1425
1424
  }
@@ -1437,11 +1436,10 @@ class state_default extends EventEmitter {
1437
1436
 
1438
1437
  // src/airplay/volume.ts
1439
1438
  import { DataStreamMessage as DataStreamMessage2, Proto as Proto4 } from "@basmilius/apple-airplay";
1440
- import { reporter } from "@basmilius/apple-common";
1441
1439
  var VOLUME_STEP = 0.05;
1442
1440
 
1443
1441
  class volume_default {
1444
- get #airplay() {
1442
+ get #protocol() {
1445
1443
  return this.#device[PROTOCOL];
1446
1444
  }
1447
1445
  get #state() {
@@ -1483,7 +1481,7 @@ class volume_default {
1483
1481
  if (!this.#state.outputDeviceUID) {
1484
1482
  throw new Error("No output device active.");
1485
1483
  }
1486
- const response = await this.#airplay.dataStream.exchange(DataStreamMessage2.getVolume(this.#state.outputDeviceUID));
1484
+ const response = await this.#protocol.dataStream.exchange(DataStreamMessage2.getVolume(this.#state.outputDeviceUID));
1487
1485
  if (response.type === Proto4.ProtocolMessage_Type.GET_VOLUME_RESULT_MESSAGE) {
1488
1486
  const message = DataStreamMessage2.getExtension(response, Proto4.getVolumeResultMessage);
1489
1487
  return message.volume;
@@ -1498,8 +1496,8 @@ class volume_default {
1498
1496
  throw new Error("Absolute volume control is not available.");
1499
1497
  }
1500
1498
  volume = Math.min(1, Math.max(0, volume));
1501
- reporter.info(`Setting volume to ${volume} for device ${this.#state.outputDeviceUID}`);
1502
- await this.#airplay.dataStream.exchange(DataStreamMessage2.setVolume(this.#state.outputDeviceUID, volume));
1499
+ this.#protocol.context.logger.info(`Setting volume to ${volume} for device ${this.#state.outputDeviceUID}`);
1500
+ await this.#protocol.dataStream.exchange(DataStreamMessage2.setVolume(this.#state.outputDeviceUID, volume));
1503
1501
  }
1504
1502
  }
1505
1503
 
@@ -1515,7 +1513,7 @@ class device_default extends EventEmitter2 {
1515
1513
  this.#discoveryResult = discoveryResult;
1516
1514
  }
1517
1515
  get isConnected() {
1518
- return this.#protocol?.rtsp?.isConnected ?? false;
1516
+ return this.#protocol?.controlStream?.isConnected ?? false;
1519
1517
  }
1520
1518
  get remote() {
1521
1519
  return this.#remote;
@@ -1532,6 +1530,7 @@ class device_default extends EventEmitter2 {
1532
1530
  set timingServer(timingServer) {
1533
1531
  this.#timingServer = timingServer;
1534
1532
  }
1533
+ #deviceId;
1535
1534
  #remote;
1536
1535
  #state;
1537
1536
  #volume;
@@ -1542,8 +1541,9 @@ class device_default extends EventEmitter2 {
1542
1541
  #keys;
1543
1542
  #protocol;
1544
1543
  #timingServer;
1545
- constructor(discoveryResult) {
1544
+ constructor(deviceId, discoveryResult) {
1546
1545
  super();
1546
+ this.#deviceId = deviceId;
1547
1547
  this.#discoveryResult = discoveryResult;
1548
1548
  this.#remote = new remote_default(this);
1549
1549
  this.#state = new state_default(this);
@@ -1552,10 +1552,10 @@ class device_default extends EventEmitter2 {
1552
1552
  async connect() {
1553
1553
  this.#disconnect = false;
1554
1554
  this.#state.clear();
1555
- this.#protocol = new AirPlay2(this.#discoveryResult);
1556
- this.#protocol.rtsp.on("close", async () => this.#onClose());
1557
- this.#protocol.rtsp.on("error", async (err) => this.#onError(err));
1558
- this.#protocol.rtsp.on("timeout", async () => this.#onTimeout());
1555
+ this.#protocol = new Protocol(this.#deviceId, this.#discoveryResult);
1556
+ this.#protocol.controlStream.on("close", async () => this.#onClose());
1557
+ this.#protocol.controlStream.on("error", async (err) => this.#onError(err));
1558
+ this.#protocol.controlStream.on("timeout", async () => this.#onTimeout());
1559
1559
  await this.#protocol.connect();
1560
1560
  if (this.#credentials) {
1561
1561
  this.#keys = await this.#protocol.verify.start(this.#credentials);
@@ -1591,11 +1591,11 @@ class device_default extends EventEmitter2 {
1591
1591
  await this.#protocol.feedback();
1592
1592
  await this.#protocol.dataStream.exchange(DataStreamMessage3.setConnectionState(Proto5.SetConnectionStateMessage_ConnectionState.Connected));
1593
1593
  } catch (err) {
1594
- reporter2.error("Feedback error", err);
1594
+ this.#protocol.context.logger.error("Feedback error", err);
1595
1595
  }
1596
1596
  }
1597
1597
  async#onClose() {
1598
- reporter2.net("#onClose() called on airplay device.");
1598
+ this.#protocol.context.logger.net("#onClose() called on airplay device.");
1599
1599
  if (!this.#disconnect) {
1600
1600
  await this.disconnectSafely();
1601
1601
  this.emit("disconnected", true);
@@ -1604,21 +1604,21 @@ class device_default extends EventEmitter2 {
1604
1604
  }
1605
1605
  }
1606
1606
  async#onError(err) {
1607
- reporter2.error("AirPlay error", err);
1607
+ this.#protocol.context.logger.error("AirPlay error", err);
1608
1608
  }
1609
1609
  async#onTimeout() {
1610
- reporter2.error("AirPlay timeout");
1611
- await this.#protocol.rtsp.destroy();
1610
+ this.#protocol.context.logger.error("AirPlay timeout");
1611
+ await this.#protocol.controlStream.destroy();
1612
1612
  }
1613
1613
  async#setup() {
1614
1614
  const keys = this.#keys;
1615
- await this.#protocol.rtsp.enableEncryption(keys.accessoryToControllerKey, keys.controllerToAccessoryKey);
1616
- await this.#unsubscribe();
1615
+ this.#protocol.controlStream.enableEncryption(keys.accessoryToControllerKey, keys.controllerToAccessoryKey);
1616
+ this.#unsubscribe();
1617
1617
  if (this.#timingServer) {
1618
- await this.#protocol.setupTimingServer(this.#timingServer);
1618
+ this.#protocol.useTimingServer(this.#timingServer);
1619
1619
  }
1620
- await this.#protocol.setupEventStream(keys.pairingId, keys.sharedSecret);
1621
- await this.#protocol.setupDataStream(keys.sharedSecret, async () => await this.#subscribe());
1620
+ await this.#protocol.setupEventStream(keys.sharedSecret, keys.pairingId);
1621
+ await this.#protocol.setupDataStream(keys.sharedSecret, () => this.#subscribe());
1622
1622
  this.#protocol.dataStream.on("error", async (err) => this.#onError(err));
1623
1623
  this.#protocol.dataStream.on("timeout", async () => this.#onTimeout());
1624
1624
  this.#protocol.eventStream.on("error", async (err) => this.#onError(err));
@@ -1647,17 +1647,17 @@ class device_default extends EventEmitter2 {
1647
1647
  if (!result) {
1648
1648
  await this.#onError(new Error("Device did not respond in time with its info."));
1649
1649
  } else {
1650
- reporter2.info("Device info received successfully, protocol should be ready.");
1650
+ this.#protocol.context.logger.info("Device info received successfully, protocol should be ready.");
1651
1651
  }
1652
1652
  }
1653
- async#subscribe() {
1654
- await this.#state[STATE_SUBSCRIBE_SYMBOL]();
1653
+ #subscribe() {
1654
+ this.#state[STATE_SUBSCRIBE_SYMBOL]();
1655
1655
  }
1656
- async#unsubscribe() {
1656
+ #unsubscribe() {
1657
1657
  try {
1658
- await this.#state[STATE_UNSUBSCRIBE_SYMBOL]();
1658
+ this.#state[STATE_UNSUBSCRIBE_SYMBOL]();
1659
1659
  } catch (err) {
1660
- reporter2.error("State unsubscribe error", err);
1660
+ this.#protocol.context.logger.error("State unsubscribe error", err);
1661
1661
  }
1662
1662
  }
1663
1663
  }
@@ -1665,8 +1665,7 @@ class device_default extends EventEmitter2 {
1665
1665
  var PROTOCOL2 = Symbol("com.basmilius.companion-link:protocol");
1666
1666
  // src/companion-link/device.ts
1667
1667
  import { EventEmitter as EventEmitter3 } from "node:events";
1668
- import { reporter as reporter3 } from "@basmilius/apple-common";
1669
- import { CompanionLink, convertAttentionState } from "@basmilius/apple-companion-link";
1668
+ import { convertAttentionState, Protocol as Protocol2 } from "@basmilius/apple-companion-link";
1670
1669
  class device_default2 extends EventEmitter3 {
1671
1670
  get [PROTOCOL2]() {
1672
1671
  return this.#protocol;
@@ -1678,16 +1677,18 @@ class device_default2 extends EventEmitter3 {
1678
1677
  this.#discoveryResult = discoveryResult;
1679
1678
  }
1680
1679
  get isConnected() {
1681
- return this.#protocol?.socket?.isConnected ?? false;
1680
+ return this.#protocol?.stream?.isConnected ?? false;
1682
1681
  }
1682
+ #deviceId;
1683
1683
  #credentials;
1684
1684
  #disconnect = false;
1685
1685
  #discoveryResult;
1686
1686
  #heartbeatInterval;
1687
1687
  #keys;
1688
1688
  #protocol;
1689
- constructor(discoveryResult) {
1689
+ constructor(deviceId, discoveryResult) {
1690
1690
  super();
1691
+ this.#deviceId = deviceId;
1691
1692
  this.#discoveryResult = discoveryResult;
1692
1693
  this.onSystemStatus = this.onSystemStatus.bind(this);
1693
1694
  this.onTVSystemStatus = this.onTVSystemStatus.bind(this);
@@ -1697,10 +1698,10 @@ class device_default2 extends EventEmitter3 {
1697
1698
  throw new Error("Credentials are required to connect to a Companion Link device.");
1698
1699
  }
1699
1700
  this.#disconnect = false;
1700
- this.#protocol = new CompanionLink(this.#discoveryResult);
1701
- this.#protocol.socket.on("close", async () => this.#onClose());
1702
- this.#protocol.socket.on("error", async (err) => this.#onError(err));
1703
- this.#protocol.socket.on("timeout", async () => this.#onTimeout());
1701
+ this.#protocol = new Protocol2(this.#deviceId, this.#discoveryResult);
1702
+ this.#protocol.stream.on("close", async () => this.#onClose());
1703
+ this.#protocol.stream.on("error", async (err) => this.#onError(err));
1704
+ this.#protocol.stream.on("timeout", async () => this.#onTimeout());
1704
1705
  await this.#protocol.connect();
1705
1706
  this.#keys = await this.#protocol.verify.start(this.#credentials);
1706
1707
  await this.#setup();
@@ -1748,11 +1749,11 @@ class device_default2 extends EventEmitter3 {
1748
1749
  try {
1749
1750
  await this.#protocol._systemInfo(this.#credentials.pairingId);
1750
1751
  } catch (err) {
1751
- reporter3.error("Heartbeat error", err);
1752
+ this.#protocol.context.logger.error("Heartbeat error", err);
1752
1753
  }
1753
1754
  }
1754
1755
  async#onClose() {
1755
- reporter3.net("#onClose() called on companion link device.");
1756
+ this.#protocol.context.logger.net("#onClose() called on companion link device.");
1756
1757
  if (!this.#disconnect) {
1757
1758
  await this.disconnectSafely();
1758
1759
  this.emit("disconnected", true);
@@ -1761,15 +1762,15 @@ class device_default2 extends EventEmitter3 {
1761
1762
  }
1762
1763
  }
1763
1764
  async#onError(err) {
1764
- reporter3.error("Companion Link error", err);
1765
+ this.#protocol.context.logger.error("Companion Link error", err);
1765
1766
  }
1766
1767
  async#onTimeout() {
1767
- reporter3.error("Companion Link timeout");
1768
- await this.#protocol.socket.destroy();
1768
+ this.#protocol.context.logger.error("Companion Link timeout");
1769
+ await this.#protocol.stream.destroy();
1769
1770
  }
1770
1771
  async#setup() {
1771
1772
  const keys = this.#keys;
1772
- await this.#protocol.socket.enableEncryption(keys.accessoryToControllerKey, keys.controllerToAccessoryKey);
1773
+ this.#protocol.stream.enableEncryption(keys.accessoryToControllerKey, keys.controllerToAccessoryKey);
1773
1774
  await this.#protocol._systemInfo(this.#credentials.pairingId);
1774
1775
  await this.#protocol._sessionStart();
1775
1776
  await this.#protocol._tvrcSessionStart();
@@ -1792,17 +1793,17 @@ class device_default2 extends EventEmitter3 {
1792
1793
  } catch (_) {}
1793
1794
  }
1794
1795
  async onSystemStatus(data) {
1795
- reporter3.info("System Status", data);
1796
+ this.#protocol.context.logger.info("System Status", data);
1796
1797
  this.emit("power", convertAttentionState(data.state));
1797
1798
  }
1798
1799
  async onTVSystemStatus(data) {
1799
- reporter3.info("TV System Status", data);
1800
+ this.#protocol.context.logger.info("TV System Status", data);
1800
1801
  this.emit("power", convertAttentionState(data.state));
1801
1802
  }
1802
1803
  }
1803
1804
  // src/model/apple-tv.ts
1804
1805
  import { EventEmitter as EventEmitter4 } from "node:events";
1805
- import { Proto as Proto6 } from "@basmilius/apple-airplay";
1806
+ import * as AirPlay from "@basmilius/apple-airplay";
1806
1807
  class apple_tv_default extends EventEmitter4 {
1807
1808
  get airplay() {
1808
1809
  return this.#airplay;
@@ -1813,6 +1814,9 @@ class apple_tv_default extends EventEmitter4 {
1813
1814
  get bundleIdentifier() {
1814
1815
  return this.#airplay.state.nowPlayingClient?.bundleIdentifier ?? null;
1815
1816
  }
1817
+ get deviceId() {
1818
+ return this.#deviceId;
1819
+ }
1816
1820
  get displayName() {
1817
1821
  return this.#airplay.state.nowPlayingClient?.displayName ?? null;
1818
1822
  }
@@ -1820,24 +1824,26 @@ class apple_tv_default extends EventEmitter4 {
1820
1824
  return this.#airplay.isConnected && this.#companionLink.isConnected;
1821
1825
  }
1822
1826
  get isPlaying() {
1823
- return this.playbackState === Proto6.PlaybackState_Enum.Playing;
1827
+ return this.playbackState === AirPlay.Proto.PlaybackState_Enum.Playing;
1824
1828
  }
1825
1829
  get playbackQueue() {
1826
1830
  return this.#airplay.state.nowPlayingClient?.playbackQueue ?? null;
1827
1831
  }
1828
1832
  get playbackState() {
1829
- return this.#airplay.state.nowPlayingClient?.playbackState ?? Proto6.PlaybackState_Enum.Unknown;
1833
+ return this.#airplay.state.nowPlayingClient?.playbackState ?? AirPlay.Proto.PlaybackState_Enum.Unknown;
1830
1834
  }
1831
1835
  get playbackStateTimestamp() {
1832
1836
  return this.#airplay.state.nowPlayingClient?.playbackStateTimestamp ?? -1;
1833
1837
  }
1834
1838
  #airplay;
1835
1839
  #companionLink;
1840
+ #deviceId;
1836
1841
  #disconnect = false;
1837
- constructor(airplayDiscoveryResult, companionLinkDiscoveryResult) {
1842
+ constructor(deviceId, airplayDiscoveryResult, companionLinkDiscoveryResult) {
1838
1843
  super();
1839
- this.#airplay = new device_default(airplayDiscoveryResult);
1840
- this.#companionLink = new device_default2(companionLinkDiscoveryResult);
1844
+ this.#deviceId = deviceId;
1845
+ this.#airplay = new device_default(this.#deviceId, airplayDiscoveryResult);
1846
+ this.#companionLink = new device_default2(this.#deviceId, companionLinkDiscoveryResult);
1841
1847
  this.#airplay.on("connected", () => this.#onConnected());
1842
1848
  this.#airplay.on("disconnected", (unexpected) => this.#onDisconnected(unexpected));
1843
1849
  this.#companionLink.on("connected", () => this.#onConnected());
@@ -1861,22 +1867,22 @@ class apple_tv_default extends EventEmitter4 {
1861
1867
  await this.#airplay.remote.wake();
1862
1868
  }
1863
1869
  async pause() {
1864
- await this.#airplay.sendCommand(Proto6.Command.Pause);
1870
+ await this.#airplay.sendCommand(AirPlay.Proto.Command.Pause);
1865
1871
  }
1866
1872
  async playPause() {
1867
- await this.#airplay.sendCommand(Proto6.Command.TogglePlayPause);
1873
+ await this.#airplay.sendCommand(AirPlay.Proto.Command.TogglePlayPause);
1868
1874
  }
1869
1875
  async play() {
1870
- await this.#airplay.sendCommand(Proto6.Command.Play);
1876
+ await this.#airplay.sendCommand(AirPlay.Proto.Command.Play);
1871
1877
  }
1872
1878
  async stop() {
1873
- await this.#airplay.sendCommand(Proto6.Command.Stop);
1879
+ await this.#airplay.sendCommand(AirPlay.Proto.Command.Stop);
1874
1880
  }
1875
1881
  async next() {
1876
- await this.#airplay.sendCommand(Proto6.Command.NextInContext);
1882
+ await this.#airplay.sendCommand(AirPlay.Proto.Command.NextInContext);
1877
1883
  }
1878
1884
  async previous() {
1879
- await this.#airplay.sendCommand(Proto6.Command.PreviousInContext);
1885
+ await this.#airplay.sendCommand(AirPlay.Proto.Command.PreviousInContext);
1880
1886
  }
1881
1887
  async volumeDown() {
1882
1888
  await this.#airplay.remote.volumeDown();
@@ -1918,7 +1924,7 @@ class apple_tv_default extends EventEmitter4 {
1918
1924
  }
1919
1925
  // src/model/homepod-base.ts
1920
1926
  import { EventEmitter as EventEmitter5 } from "node:events";
1921
- import { Proto as Proto7 } from "@basmilius/apple-airplay";
1927
+ import * as AirPlay2 from "@basmilius/apple-airplay";
1922
1928
  class homepod_base_default extends EventEmitter5 {
1923
1929
  get airplay() {
1924
1930
  return this.#airplay;
@@ -1926,6 +1932,9 @@ class homepod_base_default extends EventEmitter5 {
1926
1932
  get bundleIdentifier() {
1927
1933
  return this.#airplay.state.nowPlayingClient?.bundleIdentifier ?? null;
1928
1934
  }
1935
+ get deviceId() {
1936
+ return this.#deviceId;
1937
+ }
1929
1938
  get displayName() {
1930
1939
  return this.#airplay.state.nowPlayingClient?.displayName ?? null;
1931
1940
  }
@@ -1933,13 +1942,13 @@ class homepod_base_default extends EventEmitter5 {
1933
1942
  return this.#airplay.isConnected;
1934
1943
  }
1935
1944
  get isPlaying() {
1936
- return this.playbackState === Proto7.PlaybackState_Enum.Playing;
1945
+ return this.playbackState === AirPlay2.Proto.PlaybackState_Enum.Playing;
1937
1946
  }
1938
1947
  get playbackQueue() {
1939
1948
  return this.#airplay.state.nowPlayingClient?.playbackQueue ?? null;
1940
1949
  }
1941
1950
  get playbackState() {
1942
- return this.#airplay.state.nowPlayingClient?.playbackState ?? Proto7.PlaybackState_Enum.Unknown;
1951
+ return this.#airplay.state.nowPlayingClient?.playbackState ?? AirPlay2.Proto.PlaybackState_Enum.Unknown;
1943
1952
  }
1944
1953
  get playbackStateTimestamp() {
1945
1954
  return this.#airplay.state.nowPlayingClient?.playbackStateTimestamp ?? -1;
@@ -1948,10 +1957,12 @@ class homepod_base_default extends EventEmitter5 {
1948
1957
  return this.#airplay.state.volume ?? 0;
1949
1958
  }
1950
1959
  #airplay;
1960
+ #deviceId;
1951
1961
  #disconnect = false;
1952
- constructor(discoveryResult) {
1962
+ constructor(deviceId, discoveryResult) {
1953
1963
  super();
1954
- this.#airplay = new device_default(discoveryResult);
1964
+ this.#deviceId = deviceId;
1965
+ this.#airplay = new device_default(this.#deviceId, discoveryResult);
1955
1966
  this.#airplay.on("connected", () => this.#onConnected());
1956
1967
  this.#airplay.on("disconnected", (unexpected) => this.#onDisconnected(unexpected));
1957
1968
  }
@@ -1963,22 +1974,22 @@ class homepod_base_default extends EventEmitter5 {
1963
1974
  await this.#airplay.disconnect();
1964
1975
  }
1965
1976
  async pause() {
1966
- await this.#airplay.sendCommand(Proto7.Command.Pause);
1977
+ await this.#airplay.sendCommand(AirPlay2.Proto.Command.Pause);
1967
1978
  }
1968
1979
  async playPause() {
1969
- await this.#airplay.sendCommand(Proto7.Command.TogglePlayPause);
1980
+ await this.#airplay.sendCommand(AirPlay2.Proto.Command.TogglePlayPause);
1970
1981
  }
1971
1982
  async play() {
1972
- await this.#airplay.sendCommand(Proto7.Command.Play);
1983
+ await this.#airplay.sendCommand(AirPlay2.Proto.Command.Play);
1973
1984
  }
1974
1985
  async stop() {
1975
- await this.#airplay.sendCommand(Proto7.Command.Stop);
1986
+ await this.#airplay.sendCommand(AirPlay2.Proto.Command.Stop);
1976
1987
  }
1977
1988
  async next() {
1978
- await this.#airplay.sendCommand(Proto7.Command.NextInContext);
1989
+ await this.#airplay.sendCommand(AirPlay2.Proto.Command.NextInContext);
1979
1990
  }
1980
1991
  async previous() {
1981
- await this.#airplay.sendCommand(Proto7.Command.PreviousInContext);
1992
+ await this.#airplay.sendCommand(AirPlay2.Proto.Command.PreviousInContext);
1982
1993
  }
1983
1994
  async getCommandInfo(command) {
1984
1995
  const client = this.#airplay.state.nowPlayingClient;
@@ -1,6 +1,6 @@
1
1
  import { EventEmitter } from "node:events";
2
- import { Proto } from "@basmilius/apple-airplay";
3
2
  import type { AccessoryCredentials, DiscoveryResult } from "@basmilius/apple-common";
3
+ import * as AirPlay from "@basmilius/apple-airplay";
4
4
  import { AirPlayDevice } from "../airplay";
5
5
  import { CompanionLinkDevice } from "../companion-link";
6
6
  type EventMap = {
@@ -12,13 +12,14 @@ export default class extends EventEmitter<EventMap> {
12
12
  get airplay(): AirPlayDevice;
13
13
  get companionLink(): CompanionLinkDevice;
14
14
  get bundleIdentifier(): string | null;
15
+ get deviceId(): string;
15
16
  get displayName(): string | null;
16
17
  get isConnected(): boolean;
17
18
  get isPlaying(): boolean;
18
- get playbackQueue(): Proto.PlaybackQueue | null;
19
- get playbackState(): Proto.PlaybackState_Enum;
19
+ get playbackQueue(): AirPlay.Proto.PlaybackQueue | null;
20
+ get playbackState(): AirPlay.Proto.PlaybackState_Enum;
20
21
  get playbackStateTimestamp(): number;
21
- constructor(airplayDiscoveryResult: DiscoveryResult, companionLinkDiscoveryResult: DiscoveryResult);
22
+ constructor(deviceId: string, airplayDiscoveryResult: DiscoveryResult, companionLinkDiscoveryResult: DiscoveryResult);
22
23
  connect(credentials: AccessoryCredentials): Promise<void>;
23
24
  disconnect(): Promise<void>;
24
25
  turnOff(): Promise<void>;
@@ -32,6 +33,6 @@ export default class extends EventEmitter<EventMap> {
32
33
  volumeDown(): Promise<void>;
33
34
  volumeMute(): Promise<void>;
34
35
  volumeUp(): Promise<void>;
35
- getCommandInfo(command: Proto.Command): Promise<Proto.CommandInfo | null>;
36
- isCommandSupported(command: Proto.Command): Promise<boolean>;
36
+ getCommandInfo(command: AirPlay.Proto.Command): Promise<AirPlay.Proto.CommandInfo | null>;
37
+ isCommandSupported(command: AirPlay.Proto.Command): Promise<boolean>;
37
38
  }
@@ -1,6 +1,6 @@
1
1
  import { EventEmitter } from "node:events";
2
- import { Proto } from "@basmilius/apple-airplay";
3
2
  import type { DiscoveryResult } from "@basmilius/apple-common";
3
+ import * as AirPlay from "@basmilius/apple-airplay";
4
4
  import { AirPlayDevice } from "../airplay";
5
5
  type EventMap = {
6
6
  connected: [];
@@ -10,14 +10,15 @@ export default abstract class extends EventEmitter<EventMap> {
10
10
  #private;
11
11
  get airplay(): AirPlayDevice;
12
12
  get bundleIdentifier(): string | null;
13
+ get deviceId(): string;
13
14
  get displayName(): string | null;
14
15
  get isConnected(): boolean;
15
16
  get isPlaying(): boolean;
16
- get playbackQueue(): Proto.PlaybackQueue | null;
17
- get playbackState(): Proto.PlaybackState_Enum;
17
+ get playbackQueue(): AirPlay.Proto.PlaybackQueue | null;
18
+ get playbackState(): AirPlay.Proto.PlaybackState_Enum;
18
19
  get playbackStateTimestamp(): number;
19
20
  get volume(): number;
20
- constructor(discoveryResult: DiscoveryResult);
21
+ constructor(deviceId: string, discoveryResult: DiscoveryResult);
21
22
  connect(): Promise<void>;
22
23
  disconnect(): Promise<void>;
23
24
  pause(): Promise<void>;
@@ -26,6 +27,6 @@ export default abstract class extends EventEmitter<EventMap> {
26
27
  stop(): Promise<void>;
27
28
  next(): Promise<void>;
28
29
  previous(): Promise<void>;
29
- getCommandInfo(command: Proto.Command): Promise<Proto.CommandInfo | null>;
30
- isCommandSupported(command: Proto.Command): Promise<boolean>;
30
+ getCommandInfo(command: AirPlay.Proto.Command): Promise<AirPlay.Proto.CommandInfo | null>;
31
+ isCommandSupported(command: AirPlay.Proto.Command): Promise<boolean>;
31
32
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@basmilius/apple-devices",
3
3
  "description": "Exposes various Apple devices to connect with either AirPlay or Companion Link.",
4
- "version": "0.1.3",
4
+ "version": "0.2.1",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "author": {
@@ -43,10 +43,10 @@
43
43
  }
44
44
  },
45
45
  "dependencies": {
46
- "@basmilius/apple-airplay": "0.1.3",
47
- "@basmilius/apple-common": "0.1.3",
48
- "@basmilius/apple-companion-link": "0.1.3",
49
- "@basmilius/apple-encoding": "0.1.3"
46
+ "@basmilius/apple-airplay": "0.2.1",
47
+ "@basmilius/apple-common": "0.2.1",
48
+ "@basmilius/apple-companion-link": "0.2.1",
49
+ "@basmilius/apple-encoding": "0.2.1"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@basmilius/tools": "^2.23.0",