@basmilius/apple-sdk 0.13.2 → 0.13.4

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.d.mts CHANGED
@@ -1327,11 +1327,21 @@ declare class AirPlayManager extends EventEmitter<EventMap$2> {
1327
1327
  */
1328
1328
  onClose(): void;
1329
1329
  /**
1330
- * Handles stream error events by logging them.
1330
+ * Handles control stream error events by logging them.
1331
+ * Control stream errors are non-fatal by themselves; the 'close' event
1332
+ * that follows will trigger disconnect.
1331
1333
  *
1332
1334
  * @param err - The error that occurred.
1333
1335
  */
1334
1336
  onError(err: Error): void;
1337
+ /**
1338
+ * Handles data/event stream error events by tearing down the connection.
1339
+ * These streams are critical for state tracking; if they fail, the device
1340
+ * is effectively unreachable and a full reconnect is needed.
1341
+ *
1342
+ * @param err - The error that occurred.
1343
+ */
1344
+ onStreamError(err: Error): void;
1335
1345
  /**
1336
1346
  * Handles now-playing changes to auto-fetch artwork on track changes.
1337
1347
  */
@@ -1779,6 +1789,18 @@ declare class CompanionLinkManager extends EventEmitter<EventMap> {
1779
1789
  * Stops the active Siri session on the device.
1780
1790
  */
1781
1791
  siriStop(): Promise<void>;
1792
+ /** @internal */
1793
+ onAttentionStateChanged(state: AttentionState$1): void;
1794
+ /** @internal */
1795
+ onMediaControlFlagsChanged(flags: number, capabilities: MediaCapabilities): void;
1796
+ /** @internal */
1797
+ onNowPlayingInfoChanged(info: Record<string, unknown> | null): void;
1798
+ /** @internal */
1799
+ onSupportedActionsChanged(actions: Record<string, unknown>): void;
1800
+ /** @internal */
1801
+ onTextInputChanged(state: TextInputState$1): void;
1802
+ /** @internal */
1803
+ onVolumeAvailabilityChanged(available: boolean): void;
1782
1804
  /**
1783
1805
  * Handles the stream close event. Emits 'disconnected' with unexpected=true if not intentional.
1784
1806
  */
package/dist/index.mjs CHANGED
@@ -3087,6 +3087,7 @@ var AirPlayManager = class extends EventEmitter {
3087
3087
  this.#state = new AirPlayState(this);
3088
3088
  this.onClose = this.onClose.bind(this);
3089
3089
  this.onError = this.onError.bind(this);
3090
+ this.onStreamError = this.onStreamError.bind(this);
3090
3091
  this.onNowPlayingChanged = this.onNowPlayingChanged.bind(this);
3091
3092
  this.onTimeout = this.onTimeout.bind(this);
3092
3093
  this.#volume = new AirPlayVolume(this);
@@ -3130,9 +3131,16 @@ var AirPlayManager = class extends EventEmitter {
3130
3131
  clearInterval(this.#feedbackInterval);
3131
3132
  this.#feedbackInterval = void 0;
3132
3133
  }
3134
+ this.#prevDataStream?.off("error", this.onStreamError);
3135
+ this.#prevDataStream?.off("timeout", this.onTimeout);
3136
+ this.#prevEventStream?.off("error", this.onStreamError);
3137
+ this.#prevEventStream?.off("timeout", this.onTimeout);
3138
+ this.#prevDataStream = void 0;
3139
+ this.#prevEventStream = void 0;
3133
3140
  this.#cleanupPlayUrl();
3134
3141
  this.#cleanupStream();
3135
3142
  this.#unsubscribe();
3143
+ this.#artwork.clear();
3136
3144
  this.#protocol.disconnect();
3137
3145
  this.emit("disconnected", false);
3138
3146
  }
@@ -3373,7 +3381,9 @@ var AirPlayManager = class extends EventEmitter {
3373
3381
  this.emit("disconnected", true);
3374
3382
  }
3375
3383
  /**
3376
- * Handles stream error events by logging them.
3384
+ * Handles control stream error events by logging them.
3385
+ * Control stream errors are non-fatal by themselves; the 'close' event
3386
+ * that follows will trigger disconnect.
3377
3387
  *
3378
3388
  * @param err - The error that occurred.
3379
3389
  */
@@ -3381,6 +3391,17 @@ var AirPlayManager = class extends EventEmitter {
3381
3391
  this.#protocol.context.logger.error("AirPlay error", err);
3382
3392
  }
3383
3393
  /**
3394
+ * Handles data/event stream error events by tearing down the connection.
3395
+ * These streams are critical for state tracking; if they fail, the device
3396
+ * is effectively unreachable and a full reconnect is needed.
3397
+ *
3398
+ * @param err - The error that occurred.
3399
+ */
3400
+ onStreamError(err) {
3401
+ this.#protocol.context.logger.error("AirPlay stream error", err);
3402
+ this.#protocol.controlStream.destroy();
3403
+ }
3404
+ /**
3384
3405
  * Handles now-playing changes to auto-fetch artwork on track changes.
3385
3406
  */
3386
3407
  onNowPlayingChanged(_client, player) {
@@ -3407,15 +3428,15 @@ var AirPlayManager = class extends EventEmitter {
3407
3428
  this.#unsubscribe();
3408
3429
  if (this.#timingServer) this.#protocol.useTimingServer(this.#timingServer);
3409
3430
  try {
3410
- this.#prevDataStream?.off("error", this.onError);
3431
+ this.#prevDataStream?.off("error", this.onStreamError);
3411
3432
  this.#prevDataStream?.off("timeout", this.onTimeout);
3412
- this.#prevEventStream?.off("error", this.onError);
3433
+ this.#prevEventStream?.off("error", this.onStreamError);
3413
3434
  this.#prevEventStream?.off("timeout", this.onTimeout);
3414
3435
  await this.#protocol.setupEventStream(keys.sharedSecret, keys.pairingId);
3415
3436
  await this.#protocol.setupDataStream(keys.sharedSecret, () => this.#subscribe());
3416
- this.#protocol.dataStream.on("error", this.onError);
3437
+ this.#protocol.dataStream.on("error", this.onStreamError);
3417
3438
  this.#protocol.dataStream.on("timeout", this.onTimeout);
3418
- this.#protocol.eventStream.on("error", this.onError);
3439
+ this.#protocol.eventStream.on("error", this.onStreamError);
3419
3440
  this.#protocol.eventStream.on("timeout", this.onTimeout);
3420
3441
  this.#prevDataStream = this.#protocol.dataStream;
3421
3442
  this.#prevEventStream = this.#protocol.eventStream;
@@ -3819,6 +3840,12 @@ var CompanionLinkManager = class extends EventEmitter {
3819
3840
  this.onClose = this.onClose.bind(this);
3820
3841
  this.onError = this.onError.bind(this);
3821
3842
  this.onTimeout = this.onTimeout.bind(this);
3843
+ this.onAttentionStateChanged = this.onAttentionStateChanged.bind(this);
3844
+ this.onMediaControlFlagsChanged = this.onMediaControlFlagsChanged.bind(this);
3845
+ this.onNowPlayingInfoChanged = this.onNowPlayingInfoChanged.bind(this);
3846
+ this.onSupportedActionsChanged = this.onSupportedActionsChanged.bind(this);
3847
+ this.onTextInputChanged = this.onTextInputChanged.bind(this);
3848
+ this.onVolumeAvailabilityChanged = this.onVolumeAvailabilityChanged.bind(this);
3822
3849
  }
3823
3850
  /**
3824
3851
  * Connects to the Companion Link device, performs pair-verify, and sets up
@@ -4151,14 +4178,21 @@ var CompanionLinkManager = class extends EventEmitter {
4151
4178
  this.#protocol.context.logger.error("Heartbeat failed", err);
4152
4179
  }
4153
4180
  }, 15e3);
4154
- if (this.#state) this.#state.removeAllListeners();
4181
+ if (this.#state) {
4182
+ this.#state.off("attentionStateChanged", this.onAttentionStateChanged);
4183
+ this.#state.off("mediaControlFlagsChanged", this.onMediaControlFlagsChanged);
4184
+ this.#state.off("nowPlayingInfoChanged", this.onNowPlayingInfoChanged);
4185
+ this.#state.off("supportedActionsChanged", this.onSupportedActionsChanged);
4186
+ this.#state.off("textInputChanged", this.onTextInputChanged);
4187
+ this.#state.off("volumeAvailabilityChanged", this.onVolumeAvailabilityChanged);
4188
+ }
4155
4189
  this.#state = new CompanionLinkState(this.#protocol);
4156
- this.#state.on("attentionStateChanged", (s) => this.emit("attentionStateChanged", s));
4157
- this.#state.on("mediaControlFlagsChanged", (f, c) => this.emit("mediaControlFlagsChanged", f, c));
4158
- this.#state.on("nowPlayingInfoChanged", (i) => this.emit("nowPlayingInfoChanged", i));
4159
- this.#state.on("supportedActionsChanged", (a) => this.emit("supportedActionsChanged", a));
4160
- this.#state.on("textInputChanged", (s) => this.emit("textInputChanged", s));
4161
- this.#state.on("volumeAvailabilityChanged", (a) => this.emit("volumeAvailabilityChanged", a));
4190
+ this.#state.on("attentionStateChanged", this.onAttentionStateChanged);
4191
+ this.#state.on("mediaControlFlagsChanged", this.onMediaControlFlagsChanged);
4192
+ this.#state.on("nowPlayingInfoChanged", this.onNowPlayingInfoChanged);
4193
+ this.#state.on("supportedActionsChanged", this.onSupportedActionsChanged);
4194
+ this.#state.on("textInputChanged", this.onTextInputChanged);
4195
+ this.#state.on("volumeAvailabilityChanged", this.onVolumeAvailabilityChanged);
4162
4196
  this.#state.subscribe();
4163
4197
  await this.#state.fetchInitialState();
4164
4198
  } catch (err) {
@@ -4167,6 +4201,30 @@ var CompanionLinkManager = class extends EventEmitter {
4167
4201
  throw err;
4168
4202
  }
4169
4203
  }
4204
+ /** @internal */
4205
+ onAttentionStateChanged(state) {
4206
+ this.emit("attentionStateChanged", state);
4207
+ }
4208
+ /** @internal */
4209
+ onMediaControlFlagsChanged(flags, capabilities) {
4210
+ this.emit("mediaControlFlagsChanged", flags, capabilities);
4211
+ }
4212
+ /** @internal */
4213
+ onNowPlayingInfoChanged(info) {
4214
+ this.emit("nowPlayingInfoChanged", info);
4215
+ }
4216
+ /** @internal */
4217
+ onSupportedActionsChanged(actions) {
4218
+ this.emit("supportedActionsChanged", actions);
4219
+ }
4220
+ /** @internal */
4221
+ onTextInputChanged(state) {
4222
+ this.emit("textInputChanged", state);
4223
+ }
4224
+ /** @internal */
4225
+ onVolumeAvailabilityChanged(available) {
4226
+ this.emit("volumeAvailabilityChanged", available);
4227
+ }
4170
4228
  /**
4171
4229
  * Handles the stream close event. Emits 'disconnected' with unexpected=true if not intentional.
4172
4230
  */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@basmilius/apple-sdk",
3
3
  "description": "High-level SDK for controlling Apple devices (Apple TV, HomePod) via AirPlay and Companion Link.",
4
- "version": "0.13.2",
4
+ "version": "0.13.4",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "author": {
@@ -45,11 +45,11 @@
45
45
  }
46
46
  },
47
47
  "dependencies": {
48
- "@basmilius/apple-airplay": "0.13.2",
49
- "@basmilius/apple-common": "0.13.2",
50
- "@basmilius/apple-companion-link": "0.13.2",
51
- "@basmilius/apple-encoding": "0.13.2",
52
- "@basmilius/apple-raop": "0.13.2"
48
+ "@basmilius/apple-airplay": "0.13.4",
49
+ "@basmilius/apple-common": "0.13.4",
50
+ "@basmilius/apple-companion-link": "0.13.4",
51
+ "@basmilius/apple-encoding": "0.13.4",
52
+ "@basmilius/apple-raop": "0.13.4"
53
53
  },
54
54
  "devDependencies": {
55
55
  "@types/bun": "^1.3.11",