alphatheta-connect 0.23.1 → 0.23.2

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
@@ -1383,11 +1383,11 @@ async function viaLocal(local, device, opts) {
1383
1383
  }
1384
1384
  const adapter = await local.get(deviceId, trackSlot);
1385
1385
  if (adapter === null) {
1386
- return null;
1386
+ return { track: null, miss: 'no-database' };
1387
1387
  }
1388
1388
  const dbTrack = adapter.findTrack(trackId);
1389
1389
  if (dbTrack === null) {
1390
- return null;
1390
+ return { track: null, miss: 'track-absent' };
1391
1391
  }
1392
1392
  const anlz = await (0, rekordbox_1.loadAnlz)(dbTrack, 'DAT', (0, utils_1.anlzLoader)({ device, slot: trackSlot }));
1393
1393
  const track = {
@@ -1395,7 +1395,7 @@ async function viaLocal(local, device, opts) {
1395
1395
  beatGrid: anlz.beatGrid,
1396
1396
  waveformHd: null,
1397
1397
  };
1398
- return track;
1398
+ return { track, miss: null };
1399
1399
  }
1400
1400
 
1401
1401
 
@@ -1645,8 +1645,10 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
1645
1645
  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");
1646
1646
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
1647
1647
  };
1648
- var _Database_deviceManager, _Database_localDatabase, _Database_remoteDatabase, _Database_getTrackLookupStrategy, _Database_getMediaLookupStrategy;
1648
+ var _Database_instances, _Database_deviceManager, _Database_localDatabase, _Database_remoteDatabase, _Database_logger, _Database_getTrackLookupStrategy, _Database_getMediaLookupStrategy, _Database_metadataViaRemoteFallback;
1649
1649
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1650
+ const constants_1 = __webpack_require__(/*! src/constants */ "./src/constants.ts");
1651
+ const logger_1 = __webpack_require__(/*! src/logger */ "./src/logger.ts");
1650
1652
  const types_1 = __webpack_require__(/*! src/types */ "./src/types.ts");
1651
1653
  const utils_1 = __webpack_require__(/*! src/utils */ "./src/utils/index.ts");
1652
1654
  const Telemetry = __importStar(__webpack_require__(/*! src/utils/telemetry */ "./src/utils/telemetry.ts"));
@@ -1669,7 +1671,8 @@ var LookupStrategy;
1669
1671
  * network for information from their databases.
1670
1672
  */
1671
1673
  class Database {
1672
- constructor(local, remote, deviceManager) {
1674
+ constructor(local, remote, deviceManager, logger = logger_1.noopLogger) {
1675
+ _Database_instances.add(this);
1673
1676
  _Database_deviceManager.set(this, void 0);
1674
1677
  /**
1675
1678
  * The local database service, used when querying media devices connected
@@ -1681,6 +1684,7 @@ class Database {
1681
1684
  * CDJ with an unanalyzed media device connected (when possible).
1682
1685
  */
1683
1686
  _Database_remoteDatabase.set(this, void 0);
1687
+ _Database_logger.set(this, void 0);
1684
1688
  _Database_getTrackLookupStrategy.set(this, (device, type) => {
1685
1689
  const isUnanalyzed = type === types_1.TrackType.AudioCD || type === types_1.TrackType.Unanalyzed;
1686
1690
  const isStreaming = type === types_1.TrackType.Streaming;
@@ -1703,6 +1707,7 @@ class Database {
1703
1707
  __classPrivateFieldSet(this, _Database_localDatabase, local, "f");
1704
1708
  __classPrivateFieldSet(this, _Database_remoteDatabase, remote, "f");
1705
1709
  __classPrivateFieldSet(this, _Database_deviceManager, deviceManager, "f");
1710
+ __classPrivateFieldSet(this, _Database_logger, logger, "f");
1706
1711
  }
1707
1712
  /**
1708
1713
  * Get the database type (oneLibrary or pdb) for a loaded device slot.
@@ -1733,7 +1738,18 @@ class Database {
1733
1738
  track = await GetMetadata.viaRemote(__classPrivateFieldGet(this, _Database_remoteDatabase, "f"), callOpts);
1734
1739
  }
1735
1740
  if (strategy === LookupStrategy.Local) {
1736
- track = await GetMetadata.viaLocal(__classPrivateFieldGet(this, _Database_localDatabase, "f"), device, callOpts);
1741
+ const local = await GetMetadata.viaLocal(__classPrivateFieldGet(this, _Database_localDatabase, "f"), device, callOpts);
1742
+ track = local.track;
1743
+ // A local miss used to end the lookup, so the DJ's track silently never
1744
+ // reached the overlay for the rest of the set (NP3-361). Say what was
1745
+ // missed, then give the CDJ's own database a chance to answer.
1746
+ if (local.miss !== null) {
1747
+ __classPrivateFieldGet(this, _Database_logger, "f").warn(`Local metadata lookup missed track ${opts.trackId} on device ${deviceId} ` +
1748
+ `${(0, utils_1.getSlotName)(trackSlot)}: ${local.miss === 'no-database'
1749
+ ? 'no rekordbox database is loaded for that slot'
1750
+ : 'the loaded database holds no track with that id'}`);
1751
+ track = await __classPrivateFieldGet(this, _Database_instances, "m", _Database_metadataViaRemoteFallback).call(this, callOpts);
1752
+ }
1737
1753
  }
1738
1754
  if (strategy === LookupStrategy.NoneAvailable) {
1739
1755
  tx.setStatus(telemetry_1.SpanStatus.Unavailable);
@@ -1927,7 +1943,40 @@ class Database {
1927
1943
  return contents;
1928
1944
  }
1929
1945
  }
1930
- _Database_deviceManager = new WeakMap(), _Database_localDatabase = new WeakMap(), _Database_remoteDatabase = new WeakMap(), _Database_getTrackLookupStrategy = new WeakMap(), _Database_getMediaLookupStrategy = new WeakMap();
1946
+ _Database_deviceManager = new WeakMap(), _Database_localDatabase = new WeakMap(), _Database_remoteDatabase = new WeakMap(), _Database_logger = new WeakMap(), _Database_getTrackLookupStrategy = new WeakMap(), _Database_getMediaLookupStrategy = new WeakMap(), _Database_instances = new WeakSet(), _Database_metadataViaRemoteFallback =
1947
+ /**
1948
+ * Second chance for a track the local database could not answer for.
1949
+ *
1950
+ * CDJs only answer remote database queries from a host announcing a device
1951
+ * ID in the 1-6 range, so this is unavailable whenever the virtual CDJ sits
1952
+ * outside it (the package default is 7). That is a real configuration, not
1953
+ * an error — log why the fallback was skipped rather than throwing, so the
1954
+ * next report says which of the two happened.
1955
+ */
1956
+ async function _Database_metadataViaRemoteFallback(opts) {
1957
+ const hostId = __classPrivateFieldGet(this, _Database_remoteDatabase, "f").hostDevice.id;
1958
+ if (hostId < constants_1.MIN_CDJ_DEVICE_ID || hostId > constants_1.MAX_CDJ_DEVICE_ID) {
1959
+ __classPrivateFieldGet(this, _Database_logger, "f").warn(`No remote fallback for track ${opts.trackId}: this player is device ` +
1960
+ `${hostId}, and CDJs only answer remote database queries from ` +
1961
+ `devices ${constants_1.MIN_CDJ_DEVICE_ID}-${constants_1.MAX_CDJ_DEVICE_ID}`);
1962
+ return null;
1963
+ }
1964
+ try {
1965
+ const track = await GetMetadata.viaRemote(__classPrivateFieldGet(this, _Database_remoteDatabase, "f"), opts);
1966
+ if (track === null) {
1967
+ __classPrivateFieldGet(this, _Database_logger, "f").warn(`Remote fallback found no track ${opts.trackId} on device ${opts.deviceId}`);
1968
+ return null;
1969
+ }
1970
+ __classPrivateFieldGet(this, _Database_logger, "f").info(`Remote fallback recovered track ${opts.trackId} from device ${opts.deviceId}`);
1971
+ return track;
1972
+ }
1973
+ catch (e) {
1974
+ const message = e instanceof Error ? e.message : String(e);
1975
+ __classPrivateFieldGet(this, _Database_logger, "f").warn(`Remote fallback failed for track ${opts.trackId} on device ` +
1976
+ `${opts.deviceId}: ${message}`);
1977
+ return null;
1978
+ }
1979
+ };
1931
1980
  exports["default"] = Database;
1932
1981
 
1933
1982
 
@@ -6975,7 +7024,7 @@ class ProlinkNetwork {
6975
7024
  const remotedb = new remotedb_1.default(__classPrivateFieldGet(this, _ProlinkNetwork_deviceManager, "f"), vcdj);
6976
7025
  const localdb = new localdb_1.default(vcdj, __classPrivateFieldGet(this, _ProlinkNetwork_deviceManager, "f"), __classPrivateFieldGet(this, _ProlinkNetwork_statusEmitter, "f"), (_f = __classPrivateFieldGet(this, _ProlinkNetwork_config, "f").databasePreference) !== null && _f !== void 0 ? _f : 'auto');
6977
7026
  // Create unified database
6978
- const database = new db_1.default(localdb, remotedb, __classPrivateFieldGet(this, _ProlinkNetwork_deviceManager, "f"));
7027
+ const database = new db_1.default(localdb, remotedb, __classPrivateFieldGet(this, _ProlinkNetwork_deviceManager, "f"), __classPrivateFieldGet(this, _ProlinkNetwork_logger, "f"));
6979
7028
  // Create controller service
6980
7029
  const control = new control_1.default(__classPrivateFieldGet(this, _ProlinkNetwork_beatSocket, "f"), vcdj);
6981
7030
  __classPrivateFieldSet(this, _ProlinkNetwork_state, types_1.NetworkState.Connected, "f");
@@ -8656,6 +8705,15 @@ class RemoteDatabase {
8656
8705
  __classPrivateFieldSet(this, _RemoteDatabase_deviceManager, deviceManager, "f");
8657
8706
  __classPrivateFieldSet(this, _RemoteDatabase_hostDevice, hostDevice, "f");
8658
8707
  }
8708
+ /**
8709
+ * The device we introduce ourselves as when opening a remote database
8710
+ * connection. CDJs only answer queries from a host announcing an ID in the
8711
+ * 1-6 range, so callers need to read this before deciding a remote lookup is
8712
+ * even possible.
8713
+ */
8714
+ get hostDevice() {
8715
+ return __classPrivateFieldGet(this, _RemoteDatabase_hostDevice, "f");
8716
+ }
8659
8717
  /**
8660
8718
  * Gets the remote database query interface for the given device.
8661
8719
  *