alphatheta-connect 0.21.9 → 0.22.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/lib/cli.js CHANGED
@@ -10795,6 +10795,58 @@ function udpClose(conn) {
10795
10795
  }
10796
10796
 
10797
10797
 
10798
+ /***/ },
10799
+
10800
+ /***/ "./src/virtualcdj/device-id.ts"
10801
+ /*!*************************************!*\
10802
+ !*** ./src/virtualcdj/device-id.ts ***!
10803
+ \*************************************/
10804
+ (__unused_webpack_module, exports) {
10805
+
10806
+ "use strict";
10807
+
10808
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
10809
+ exports.MAX_DEVICE_ID = exports.REMOTEDB_MAX_DEVICE_ID = void 0;
10810
+ exports.pickAvailableDeviceId = pickAvailableDeviceId;
10811
+ /**
10812
+ * The highest device ID a CDJ will answer remotedb queries from.
10813
+ *
10814
+ * CDJs ignore metadata requests from devices numbered above this, which is why
10815
+ * the 1-6 range is worth preferring even though real players live there too.
10816
+ */
10817
+ exports.REMOTEDB_MAX_DEVICE_ID = 6;
10818
+ /**
10819
+ * The highest device ID the prolink protocol allows.
10820
+ */
10821
+ exports.MAX_DEVICE_ID = 32;
10822
+ /**
10823
+ * Pick a device ID that no device on the network is currently using.
10824
+ *
10825
+ * Taking an ID a live player already holds knocks that player off the network
10826
+ * mid-set, so every caller that chooses its own ID should route through here
10827
+ * rather than hardcoding one.
10828
+ *
10829
+ * Returns null when every ID from 1 to 32 is occupied, in which case there is
10830
+ * no safe ID and the caller must not join the network.
10831
+ */
10832
+ function pickAvailableDeviceId(usedIds, { preferRemoteDb = false } = {}) {
10833
+ var _a;
10834
+ const used = new Set(usedIds);
10835
+ const remoteDbRange = [];
10836
+ for (let id = exports.REMOTEDB_MAX_DEVICE_ID; id >= 1; id--) {
10837
+ remoteDbRange.push(id);
10838
+ }
10839
+ const highRange = [];
10840
+ for (let id = exports.REMOTEDB_MAX_DEVICE_ID + 1; id <= exports.MAX_DEVICE_ID; id++) {
10841
+ highRange.push(id);
10842
+ }
10843
+ const search = preferRemoteDb
10844
+ ? [...remoteDbRange, ...highRange]
10845
+ : [...highRange, ...remoteDbRange];
10846
+ return (_a = search.find(id => !used.has(id))) !== null && _a !== void 0 ? _a : null;
10847
+ }
10848
+
10849
+
10798
10850
  /***/ },
10799
10851
 
10800
10852
  /***/ "./src/virtualcdj/index.ts"
@@ -10852,7 +10904,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10852
10904
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10853
10905
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
10854
10906
  };
10855
- var _Announcer_instances, _Announcer_announceSocket, _Announcer_deviceManager, _Announcer_vcdj, _Announcer_intervalHandle, _Announcer_fullStartup, _Announcer_announceToStagehand, _Announcer_currentStage, _Announcer_stageCounter, _Announcer_conflictListener, _Announcer_iface, _Announcer_logger, _Announcer_onStartupComplete, _Announcer_startFullStartup, _Announcer_handleConflict, _Announcer_sendPacket, _Announcer_sendStagePackets, _Announcer_advanceStage, _Announcer_startKeepAlive;
10907
+ var _Announcer_instances, _Announcer_announceSocket, _Announcer_deviceManager, _Announcer_vcdj, _Announcer_intervalHandle, _Announcer_fullStartup, _Announcer_announceToStagehand, _Announcer_currentStage, _Announcer_stageCounter, _Announcer_conflictListener, _Announcer_iface, _Announcer_logger, _Announcer_onStartupComplete, _Announcer_armConflictListener, _Announcer_startFullStartup, _Announcer_handleConflict, _Announcer_clearTimer, _Announcer_sendPacket, _Announcer_sendStagePackets, _Announcer_advanceStage, _Announcer_startKeepAlive;
10856
10908
  Object.defineProperty(exports, "__esModule", ({ value: true }));
10857
10909
  exports.Announcer = exports.getVirtualCDJ = void 0;
10858
10910
  exports.makeStatusPacket = makeStatusPacket;
@@ -10862,6 +10914,7 @@ const constants_1 = __webpack_require__(/*! src/constants */ "./src/constants.ts
10862
10914
  const logger_1 = __webpack_require__(/*! src/logger */ "./src/logger.ts");
10863
10915
  const types_1 = __webpack_require__(/*! src/types */ "./src/types.ts");
10864
10916
  const utils_1 = __webpack_require__(/*! src/utils */ "./src/utils/index.ts");
10917
+ const device_id_1 = __webpack_require__(/*! src/virtualcdj/device-id */ "./src/virtualcdj/device-id.ts");
10865
10918
  /**
10866
10919
  * Constructs a virtual CDJ Device.
10867
10920
  *
@@ -11183,6 +11236,7 @@ class Announcer {
11183
11236
  });
11184
11237
  }
11185
11238
  start() {
11239
+ __classPrivateFieldGet(this, _Announcer_instances, "m", _Announcer_armConflictListener).call(this);
11186
11240
  if (__classPrivateFieldGet(this, _Announcer_fullStartup, "f")) {
11187
11241
  __classPrivateFieldGet(this, _Announcer_instances, "m", _Announcer_startFullStartup).call(this);
11188
11242
  }
@@ -11191,11 +11245,7 @@ class Announcer {
11191
11245
  }
11192
11246
  }
11193
11247
  stop() {
11194
- if (__classPrivateFieldGet(this, _Announcer_intervalHandle, "f") !== undefined) {
11195
- clearInterval(__classPrivateFieldGet(this, _Announcer_intervalHandle, "f"));
11196
- clearTimeout(__classPrivateFieldGet(this, _Announcer_intervalHandle, "f"));
11197
- __classPrivateFieldSet(this, _Announcer_intervalHandle, undefined, "f");
11198
- }
11248
+ __classPrivateFieldGet(this, _Announcer_instances, "m", _Announcer_clearTimer).call(this);
11199
11249
  // Remove conflict listener if active
11200
11250
  if (__classPrivateFieldGet(this, _Announcer_conflictListener, "f")) {
11201
11251
  __classPrivateFieldGet(this, _Announcer_announceSocket, "f").off('message', __classPrivateFieldGet(this, _Announcer_conflictListener, "f"));
@@ -11204,10 +11254,10 @@ class Announcer {
11204
11254
  }
11205
11255
  }
11206
11256
  exports.Announcer = Announcer;
11207
- _Announcer_announceSocket = new WeakMap(), _Announcer_deviceManager = new WeakMap(), _Announcer_vcdj = new WeakMap(), _Announcer_intervalHandle = new WeakMap(), _Announcer_fullStartup = new WeakMap(), _Announcer_announceToStagehand = new WeakMap(), _Announcer_currentStage = new WeakMap(), _Announcer_stageCounter = new WeakMap(), _Announcer_conflictListener = new WeakMap(), _Announcer_iface = new WeakMap(), _Announcer_logger = new WeakMap(), _Announcer_onStartupComplete = new WeakMap(), _Announcer_instances = new WeakSet(), _Announcer_startFullStartup = function _Announcer_startFullStartup() {
11208
- __classPrivateFieldSet(this, _Announcer_currentStage, StartupStage.InitialAnnounce, "f");
11209
- __classPrivateFieldSet(this, _Announcer_stageCounter, 0, "f");
11210
- // Set up conflict detection listener
11257
+ _Announcer_announceSocket = new WeakMap(), _Announcer_deviceManager = new WeakMap(), _Announcer_vcdj = new WeakMap(), _Announcer_intervalHandle = new WeakMap(), _Announcer_fullStartup = new WeakMap(), _Announcer_announceToStagehand = new WeakMap(), _Announcer_currentStage = new WeakMap(), _Announcer_stageCounter = new WeakMap(), _Announcer_conflictListener = new WeakMap(), _Announcer_iface = new WeakMap(), _Announcer_logger = new WeakMap(), _Announcer_onStartupComplete = new WeakMap(), _Announcer_instances = new WeakSet(), _Announcer_armConflictListener = function _Announcer_armConflictListener() {
11258
+ if (__classPrivateFieldGet(this, _Announcer_conflictListener, "f")) {
11259
+ return;
11260
+ }
11211
11261
  __classPrivateFieldSet(this, _Announcer_conflictListener, (msg) => {
11212
11262
  const conflictDeviceId = parseConflictPacket(msg);
11213
11263
  if (conflictDeviceId === __classPrivateFieldGet(this, _Announcer_vcdj, "f").id) {
@@ -11216,43 +11266,47 @@ _Announcer_announceSocket = new WeakMap(), _Announcer_deviceManager = new WeakMa
11216
11266
  }
11217
11267
  }, "f");
11218
11268
  __classPrivateFieldGet(this, _Announcer_announceSocket, "f").on('message', __classPrivateFieldGet(this, _Announcer_conflictListener, "f"));
11269
+ }, _Announcer_startFullStartup = function _Announcer_startFullStartup() {
11270
+ __classPrivateFieldSet(this, _Announcer_currentStage, StartupStage.InitialAnnounce, "f");
11271
+ __classPrivateFieldSet(this, _Announcer_stageCounter, 0, "f");
11219
11272
  __classPrivateFieldGet(this, _Announcer_instances, "m", _Announcer_sendStagePackets).call(this);
11220
11273
  }, _Announcer_handleConflict = function _Announcer_handleConflict() {
11221
- // Stop current startup
11222
- if (__classPrivateFieldGet(this, _Announcer_intervalHandle, "f")) {
11223
- clearTimeout(__classPrivateFieldGet(this, _Announcer_intervalHandle, "f"));
11224
- __classPrivateFieldSet(this, _Announcer_intervalHandle, undefined, "f");
11225
- }
11226
- // Find an available device ID
11227
- const usedIds = new Set([...__classPrivateFieldGet(this, _Announcer_deviceManager, "f").devices.values()].map(d => d.id));
11228
- let newId = null;
11229
- // Try IDs from 7-32 first (recommended range), then 1-6 if needed
11230
- for (let id = 7; id <= 32; id++) {
11231
- if (!usedIds.has(id)) {
11232
- newId = id;
11233
- break;
11234
- }
11235
- }
11236
- if (newId === null) {
11237
- for (let id = 1; id <= 6; id++) {
11238
- if (!usedIds.has(id)) {
11239
- newId = id;
11240
- break;
11241
- }
11242
- }
11243
- }
11274
+ // Stop announcing under the contested ID
11275
+ __classPrivateFieldGet(this, _Announcer_instances, "m", _Announcer_clearTimer).call(this);
11276
+ // Stay in whichever range we were already in. Dropping out of 1-6 would
11277
+ // silently lose remotedb metadata for unanalyzed and streaming tracks, so
11278
+ // a conflict on player 5 looks for another free player number first.
11279
+ const usedIds = [...__classPrivateFieldGet(this, _Announcer_deviceManager, "f").devices.values()].map(d => d.id);
11280
+ const newId = (0, device_id_1.pickAvailableDeviceId)(usedIds, {
11281
+ preferRemoteDb: __classPrivateFieldGet(this, _Announcer_vcdj, "f").id <= device_id_1.REMOTEDB_MAX_DEVICE_ID,
11282
+ });
11244
11283
  if (newId === null) {
11245
11284
  __classPrivateFieldGet(this, _Announcer_logger, "f").error('No available device IDs. All 32 slots are occupied.');
11246
11285
  this.stop();
11247
11286
  return;
11248
11287
  }
11249
11288
  __classPrivateFieldGet(this, _Announcer_logger, "f").info(`Switching to device ID ${newId}`);
11250
- // Update virtual CDJ with new ID
11251
- __classPrivateFieldSet(this, _Announcer_vcdj, (0, exports.getVirtualCDJ)(__classPrivateFieldGet(this, _Announcer_iface, "f"), newId), "f");
11252
- // Restart startup sequence
11253
- __classPrivateFieldSet(this, _Announcer_currentStage, StartupStage.InitialAnnounce, "f");
11254
- __classPrivateFieldSet(this, _Announcer_stageCounter, 0, "f");
11255
- __classPrivateFieldGet(this, _Announcer_instances, "m", _Announcer_sendStagePackets).call(this);
11289
+ // Mutate in place rather than building a replacement device. The remotedb,
11290
+ // localdb and control services were all handed this same object when the
11291
+ // network connected and read `.id` when they build packets, so swapping
11292
+ // the reference here would leave us announcing as one ID and querying as
11293
+ // another.
11294
+ __classPrivateFieldGet(this, _Announcer_vcdj, "f").id = newId;
11295
+ // Re-announce under the new ID
11296
+ if (__classPrivateFieldGet(this, _Announcer_fullStartup, "f")) {
11297
+ __classPrivateFieldSet(this, _Announcer_currentStage, StartupStage.InitialAnnounce, "f");
11298
+ __classPrivateFieldSet(this, _Announcer_stageCounter, 0, "f");
11299
+ __classPrivateFieldGet(this, _Announcer_instances, "m", _Announcer_sendStagePackets).call(this);
11300
+ }
11301
+ else {
11302
+ __classPrivateFieldGet(this, _Announcer_instances, "m", _Announcer_startKeepAlive).call(this);
11303
+ }
11304
+ }, _Announcer_clearTimer = function _Announcer_clearTimer() {
11305
+ if (__classPrivateFieldGet(this, _Announcer_intervalHandle, "f") !== undefined) {
11306
+ clearTimeout(__classPrivateFieldGet(this, _Announcer_intervalHandle, "f"));
11307
+ clearInterval(__classPrivateFieldGet(this, _Announcer_intervalHandle, "f"));
11308
+ __classPrivateFieldSet(this, _Announcer_intervalHandle, undefined, "f");
11309
+ }
11256
11310
  }, _Announcer_sendPacket = function _Announcer_sendPacket(packet) {
11257
11311
  const devices = [...__classPrivateFieldGet(this, _Announcer_deviceManager, "f").devices.values()].filter(d => __classPrivateFieldGet(this, _Announcer_announceToStagehand, "f") || !d.name.toLowerCase().includes('stagehand'));
11258
11312
  devices.forEach(device => __classPrivateFieldGet(this, _Announcer_announceSocket, "f").send(packet, constants_1.ANNOUNCE_PORT, device.ip.address));
@@ -11312,15 +11366,7 @@ _Announcer_announceSocket = new WeakMap(), _Announcer_deviceManager = new WeakMa
11312
11366
  break;
11313
11367
  }
11314
11368
  }, _Announcer_startKeepAlive = function _Announcer_startKeepAlive() {
11315
- if (__classPrivateFieldGet(this, _Announcer_intervalHandle, "f")) {
11316
- clearTimeout(__classPrivateFieldGet(this, _Announcer_intervalHandle, "f"));
11317
- __classPrivateFieldSet(this, _Announcer_intervalHandle, undefined, "f");
11318
- }
11319
- // Remove conflict listener once we're in keep-alive mode
11320
- if (__classPrivateFieldGet(this, _Announcer_conflictListener, "f")) {
11321
- __classPrivateFieldGet(this, _Announcer_announceSocket, "f").off('message', __classPrivateFieldGet(this, _Announcer_conflictListener, "f"));
11322
- __classPrivateFieldSet(this, _Announcer_conflictListener, undefined, "f");
11323
- }
11369
+ __classPrivateFieldGet(this, _Announcer_instances, "m", _Announcer_clearTimer).call(this);
11324
11370
  const sendKeepAlive = () => {
11325
11371
  const peerCount = __classPrivateFieldGet(this, _Announcer_deviceManager, "f").devices.size + 1; // +1 for ourselves
11326
11372
  const packet = __classPrivateFieldGet(this, _Announcer_fullStartup, "f")
@@ -11333,6 +11379,7 @@ _Announcer_announceSocket = new WeakMap(), _Announcer_deviceManager = new WeakMa
11333
11379
  // Then schedule regular keep-alives
11334
11380
  __classPrivateFieldSet(this, _Announcer_intervalHandle, setInterval(sendKeepAlive, constants_1.ANNOUNCE_INTERVAL), "f");
11335
11381
  };
11382
+ __exportStar(__webpack_require__(/*! ./device-id */ "./src/virtualcdj/device-id.ts"), exports);
11336
11383
  __exportStar(__webpack_require__(/*! ./stagehand */ "./src/virtualcdj/stagehand.ts"), exports);
11337
11384
 
11338
11385