djay-connect 2.2.1 → 2.2.3
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/djayConnect.d.ts +7 -0
- package/dist/djayConnect.js +66 -12
- package/dist/djayConnect.js.map +1 -1
- package/dist/tsaf.d.ts +25 -5
- package/dist/tsaf.js +28 -7
- package/dist/tsaf.js.map +1 -1
- package/package.json +1 -1
package/dist/djayConnect.d.ts
CHANGED
|
@@ -17,6 +17,8 @@ export declare class DjayConnect extends DjayConnect_base {
|
|
|
17
17
|
private databasePath;
|
|
18
18
|
private logger;
|
|
19
19
|
private db;
|
|
20
|
+
private locationStatement;
|
|
21
|
+
private mediaItemTitleStatement;
|
|
20
22
|
private pollTimer;
|
|
21
23
|
private lastRowId;
|
|
22
24
|
private isRunning;
|
|
@@ -38,6 +40,11 @@ export declare class DjayConnect extends DjayConnect_base {
|
|
|
38
40
|
private readMaxHistoryRowId;
|
|
39
41
|
private readLatestHistoryItem;
|
|
40
42
|
private toTrack;
|
|
43
|
+
/**
|
|
44
|
+
* Look up the `mediaItemTitleIDs` record for a titleID and return the title
|
|
45
|
+
* strings it carries, or null when djay has no such record.
|
|
46
|
+
*/
|
|
47
|
+
private readMediaItemTitle;
|
|
41
48
|
/**
|
|
42
49
|
* Look up the raw `sourceURIs` for a titleID. Local files live in
|
|
43
50
|
* `localMediaItemLocations`, streaming tracks in `globalMediaItemLocations`.
|
package/dist/djayConnect.js
CHANGED
|
@@ -14,6 +14,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
14
14
|
exports.DjayConnect = void 0;
|
|
15
15
|
const node_events_1 = __importDefault(require("node:events"));
|
|
16
16
|
const node_fs_1 = require("node:fs");
|
|
17
|
+
const node_path_1 = require("node:path");
|
|
17
18
|
const better_sqlite3_multiple_ciphers_1 = __importDefault(require("better-sqlite3-multiple-ciphers"));
|
|
18
19
|
const detect_js_1 = require("./detect.js");
|
|
19
20
|
const tsaf_js_1 = require("./tsaf.js");
|
|
@@ -44,6 +45,14 @@ function fileUriToPath(uri) {
|
|
|
44
45
|
}
|
|
45
46
|
return path;
|
|
46
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* The name djay Pro shows for a file that carries no title tag: its file name
|
|
50
|
+
* without the extension. Accepts both `/` and `\` separators so the decoded
|
|
51
|
+
* path resolves the same way whichever platform wrote the library.
|
|
52
|
+
*/
|
|
53
|
+
function fileNameTitle(filePath) {
|
|
54
|
+
return node_path_1.win32.parse(filePath).name;
|
|
55
|
+
}
|
|
47
56
|
const MIN_POLL_INTERVAL = 2000;
|
|
48
57
|
const DEFAULT_POLL_INTERVAL = 2000;
|
|
49
58
|
/**
|
|
@@ -54,6 +63,8 @@ class DjayConnect extends node_events_1.default {
|
|
|
54
63
|
constructor(options = {}) {
|
|
55
64
|
super();
|
|
56
65
|
this.db = null;
|
|
66
|
+
this.locationStatement = null;
|
|
67
|
+
this.mediaItemTitleStatement = null;
|
|
57
68
|
this.pollTimer = null;
|
|
58
69
|
this.lastRowId = 0;
|
|
59
70
|
this.isRunning = false;
|
|
@@ -110,6 +121,8 @@ class DjayConnect extends node_events_1.default {
|
|
|
110
121
|
this.logger.warn("Error closing database: %s", String(err));
|
|
111
122
|
}
|
|
112
123
|
this.db = null;
|
|
124
|
+
this.locationStatement = null;
|
|
125
|
+
this.mediaItemTitleStatement = null;
|
|
113
126
|
}
|
|
114
127
|
this.lastRowId = 0;
|
|
115
128
|
this.isRunning = false;
|
|
@@ -144,6 +157,15 @@ class DjayConnect extends node_events_1.default {
|
|
|
144
157
|
// read_uncommitted lets us observe writes that haven't been checkpointed
|
|
145
158
|
// yet, so new history rows appear in near real time.
|
|
146
159
|
this.db.pragma("read_uncommitted = true");
|
|
160
|
+
// Prepared once per open: both run for every history row we enrich.
|
|
161
|
+
this.locationStatement = this.db.prepare(`SELECT collection, data
|
|
162
|
+
FROM database2
|
|
163
|
+
WHERE collection IN ('localMediaItemLocations','globalMediaItemLocations')
|
|
164
|
+
AND key = ?`);
|
|
165
|
+
this.mediaItemTitleStatement = this.db.prepare(`SELECT data
|
|
166
|
+
FROM database2
|
|
167
|
+
WHERE collection = 'mediaItemTitleIDs'
|
|
168
|
+
AND key = ?`);
|
|
147
169
|
}
|
|
148
170
|
poll() {
|
|
149
171
|
if (!this.db)
|
|
@@ -165,8 +187,10 @@ class DjayConnect extends node_events_1.default {
|
|
|
165
187
|
continue;
|
|
166
188
|
}
|
|
167
189
|
const track = this.toTrack(fields);
|
|
168
|
-
if (!track)
|
|
190
|
+
if (!track) {
|
|
191
|
+
this.logger.warn(`historySessionItem ${row.key} names no title, and titleID ${fields.titleID} resolves to none either`);
|
|
169
192
|
continue;
|
|
193
|
+
}
|
|
170
194
|
this.logger.debug(`New track: ${track.artist} - ${track.title} [deck ${track.deckNumber}]`);
|
|
171
195
|
this.emit("track", { track });
|
|
172
196
|
}
|
|
@@ -211,8 +235,6 @@ class DjayConnect extends node_events_1.default {
|
|
|
211
235
|
return { rowid: row.rowid, fields };
|
|
212
236
|
}
|
|
213
237
|
toTrack(fields) {
|
|
214
|
-
if (!fields.title && !fields.artist)
|
|
215
|
-
return null;
|
|
216
238
|
const track = {
|
|
217
239
|
title: fields.title,
|
|
218
240
|
artist: fields.artist,
|
|
@@ -225,9 +247,20 @@ class DjayConnect extends node_events_1.default {
|
|
|
225
247
|
originSourceID: fields.originSourceID,
|
|
226
248
|
isrc: fields.isrc,
|
|
227
249
|
};
|
|
228
|
-
// Enrich with location data (file path or streaming URIs) when we can
|
|
229
|
-
// resolve the titleID against the *MediaItemLocations collections.
|
|
230
250
|
if (fields.titleID) {
|
|
251
|
+
// A history row with no strings at all still points at its media item,
|
|
252
|
+
// and that record carries the title djay displays for the file. djay Pro
|
|
253
|
+
// on macOS writes such rows for untagged files added via My Files.
|
|
254
|
+
if (!track.title && !track.artist) {
|
|
255
|
+
const named = this.readMediaItemTitle(fields.titleID);
|
|
256
|
+
if (named) {
|
|
257
|
+
track.title = named.title;
|
|
258
|
+
track.artist = named.artist;
|
|
259
|
+
this.logger.debug(`Resolved historySessionItem ${fields.uuid} via mediaItemTitleIDs ${fields.titleID}`);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
// Enrich with location data (file path or streaming URIs) when we can
|
|
263
|
+
// resolve the titleID against the *MediaItemLocations collections.
|
|
231
264
|
const uris = this.readSourceURIs(fields.titleID);
|
|
232
265
|
if (uris.length > 0) {
|
|
233
266
|
track.sourceURIs = uris;
|
|
@@ -241,24 +274,45 @@ class DjayConnect extends node_events_1.default {
|
|
|
241
274
|
}
|
|
242
275
|
}
|
|
243
276
|
}
|
|
277
|
+
// Last resort, and what djay itself shows for a file with no title tag.
|
|
278
|
+
if (!track.title && track.filePath) {
|
|
279
|
+
track.title = fileNameTitle(track.filePath);
|
|
280
|
+
this.logger.debug(`Resolved historySessionItem ${fields.uuid} from its file name: ${track.title}`);
|
|
281
|
+
}
|
|
244
282
|
}
|
|
283
|
+
if (!track.title && !track.artist)
|
|
284
|
+
return null;
|
|
245
285
|
return track;
|
|
246
286
|
}
|
|
287
|
+
/**
|
|
288
|
+
* Look up the `mediaItemTitleIDs` record for a titleID and return the title
|
|
289
|
+
* strings it carries, or null when djay has no such record.
|
|
290
|
+
*/
|
|
291
|
+
readMediaItemTitle(titleID) {
|
|
292
|
+
if (!this.mediaItemTitleStatement)
|
|
293
|
+
return null;
|
|
294
|
+
try {
|
|
295
|
+
const row = this.mediaItemTitleStatement.get(titleID);
|
|
296
|
+
if (!row)
|
|
297
|
+
return null;
|
|
298
|
+
const named = (0, tsaf_js_1.parseMediaItemTitle)(row.data);
|
|
299
|
+
return named.title || named.artist ? named : null;
|
|
300
|
+
}
|
|
301
|
+
catch (err) {
|
|
302
|
+
this.logger.warn(`Failed to resolve mediaItemTitleIDs ${titleID}: ${String(err)}`);
|
|
303
|
+
return null;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
247
306
|
/**
|
|
248
307
|
* Look up the raw `sourceURIs` for a titleID. Local files live in
|
|
249
308
|
* `localMediaItemLocations`, streaming tracks in `globalMediaItemLocations`.
|
|
250
309
|
* Returns every URI recorded for the track — can be empty, one, or many.
|
|
251
310
|
*/
|
|
252
311
|
readSourceURIs(titleID) {
|
|
253
|
-
if (!this.
|
|
312
|
+
if (!this.locationStatement)
|
|
254
313
|
return [];
|
|
255
314
|
try {
|
|
256
|
-
const row = this.
|
|
257
|
-
.prepare(`SELECT collection, data
|
|
258
|
-
FROM database2
|
|
259
|
-
WHERE collection IN ('localMediaItemLocations','globalMediaItemLocations')
|
|
260
|
-
AND key = ?`)
|
|
261
|
-
.get(titleID);
|
|
315
|
+
const row = this.locationStatement.get(titleID);
|
|
262
316
|
if (!row)
|
|
263
317
|
return [];
|
|
264
318
|
return (0, tsaf_js_1.extractSourceURIs)(row.data);
|
package/dist/djayConnect.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"djayConnect.js","sourceRoot":"","sources":["../src/djayConnect.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;;;;AAEH,8DAAuC;AACvC,qCAAqC;AACrC,
|
|
1
|
+
{"version":3,"file":"djayConnect.js","sourceRoot":"","sources":["../src/djayConnect.ts"],"names":[],"mappings":"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"}
|
package/dist/tsaf.d.ts
CHANGED
|
@@ -53,13 +53,33 @@ export interface DjayHistoryItemFields {
|
|
|
53
53
|
/**
|
|
54
54
|
* Parse a historySessionItems blob into a typed record.
|
|
55
55
|
*
|
|
56
|
-
* Returns `null` only when the item names neither a title
|
|
57
|
-
* there is nothing to report about
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
56
|
+
* Returns `null` only when the item names neither a title, an artist, nor a
|
|
57
|
+
* titleID, since there is nothing to report about — or look up for — such a
|
|
58
|
+
* row. An item carrying just one of title/artist is kept: a music video — or
|
|
59
|
+
* any file whose tags were never filled in — routinely has a title and no
|
|
60
|
+
* artist, and requiring both here silently dropped every one of those plays
|
|
61
|
+
* before it could reach the caller (NP3-381).
|
|
62
|
+
*
|
|
63
|
+
* An item with neither string but a titleID is kept too, with empty `title`
|
|
64
|
+
* and `artist`. djay Pro on macOS writes exactly that for an untagged file
|
|
65
|
+
* added via My Files (e.g. a downloaded music video): the strings live only in
|
|
66
|
+
* the `mediaItemTitleIDs` record the titleID points at, so the caller resolves
|
|
67
|
+
* them there (NP3-407).
|
|
61
68
|
*/
|
|
62
69
|
export declare function parseHistorySessionItem(blob: Buffer): DjayHistoryItemFields | null;
|
|
70
|
+
/** The title strings djay keeps in a `mediaItemTitleIDs` record. */
|
|
71
|
+
export interface DjayMediaItemTitleFields {
|
|
72
|
+
title: string;
|
|
73
|
+
artist: string;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Parse a `mediaItemTitleIDs` blob — the record a history item's titleID
|
|
77
|
+
* points at. It carries the same tagged `title` / `artist` strings as a
|
|
78
|
+
* history row (verified against djay Pro for macOS: an untagged file has a
|
|
79
|
+
* `title` and no `artist`, a tagged one has both). Absent strings come back
|
|
80
|
+
* empty.
|
|
81
|
+
*/
|
|
82
|
+
export declare function parseMediaItemTitle(blob: Buffer): DjayMediaItemTitleFields;
|
|
63
83
|
/**
|
|
64
84
|
* Extract the `sourceURIs` strings from a `localMediaItemLocations` or
|
|
65
85
|
* `globalMediaItemLocations` blob. A single location record can carry more
|
package/dist/tsaf.js
CHANGED
|
@@ -24,6 +24,7 @@ exports.extractDouble = extractDouble;
|
|
|
24
24
|
exports.extractDate = extractDate;
|
|
25
25
|
exports.extractTitleID = extractTitleID;
|
|
26
26
|
exports.parseHistorySessionItem = parseHistorySessionItem;
|
|
27
|
+
exports.parseMediaItemTitle = parseMediaItemTitle;
|
|
27
28
|
exports.extractSourceURIs = extractSourceURIs;
|
|
28
29
|
/** CFAbsoluteTime epoch: 2001-01-01 00:00:00 UTC in milliseconds since Unix epoch. */
|
|
29
30
|
const CF_EPOCH_MS = Date.UTC(2001, 0, 1, 0, 0, 0);
|
|
@@ -137,20 +138,27 @@ function extractTitleID(blob) {
|
|
|
137
138
|
/**
|
|
138
139
|
* Parse a historySessionItems blob into a typed record.
|
|
139
140
|
*
|
|
140
|
-
* Returns `null` only when the item names neither a title
|
|
141
|
-
* there is nothing to report about
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
141
|
+
* Returns `null` only when the item names neither a title, an artist, nor a
|
|
142
|
+
* titleID, since there is nothing to report about — or look up for — such a
|
|
143
|
+
* row. An item carrying just one of title/artist is kept: a music video — or
|
|
144
|
+
* any file whose tags were never filled in — routinely has a title and no
|
|
145
|
+
* artist, and requiring both here silently dropped every one of those plays
|
|
146
|
+
* before it could reach the caller (NP3-381).
|
|
147
|
+
*
|
|
148
|
+
* An item with neither string but a titleID is kept too, with empty `title`
|
|
149
|
+
* and `artist`. djay Pro on macOS writes exactly that for an untagged file
|
|
150
|
+
* added via My Files (e.g. a downloaded music video): the strings live only in
|
|
151
|
+
* the `mediaItemTitleIDs` record the titleID points at, so the caller resolves
|
|
152
|
+
* them there (NP3-407).
|
|
145
153
|
*/
|
|
146
154
|
function parseHistorySessionItem(blob) {
|
|
147
155
|
const title = extractString(blob, 'title');
|
|
148
156
|
const artist = extractString(blob, 'artist');
|
|
149
|
-
|
|
157
|
+
const titleID = extractTitleID(blob);
|
|
158
|
+
if (!title && !artist && !titleID)
|
|
150
159
|
return null;
|
|
151
160
|
const uuid = extractString(blob, 'uuid') ?? '';
|
|
152
161
|
const sessionUUID = extractString(blob, 'sessionUUID') ?? '';
|
|
153
|
-
const titleID = extractTitleID(blob);
|
|
154
162
|
const duration = extractDouble(blob, 'duration') ?? 0;
|
|
155
163
|
const deckRaw = extractDouble(blob, 'deckNumber') ?? 0;
|
|
156
164
|
const deckNumber = Number.isFinite(deckRaw) ? Math.round(deckRaw) : 0;
|
|
@@ -170,6 +178,19 @@ function parseHistorySessionItem(blob) {
|
|
|
170
178
|
isrc,
|
|
171
179
|
};
|
|
172
180
|
}
|
|
181
|
+
/**
|
|
182
|
+
* Parse a `mediaItemTitleIDs` blob — the record a history item's titleID
|
|
183
|
+
* points at. It carries the same tagged `title` / `artist` strings as a
|
|
184
|
+
* history row (verified against djay Pro for macOS: an untagged file has a
|
|
185
|
+
* `title` and no `artist`, a tagged one has both). Absent strings come back
|
|
186
|
+
* empty.
|
|
187
|
+
*/
|
|
188
|
+
function parseMediaItemTitle(blob) {
|
|
189
|
+
return {
|
|
190
|
+
title: extractString(blob, 'title') ?? '',
|
|
191
|
+
artist: extractString(blob, 'artist') ?? '',
|
|
192
|
+
};
|
|
193
|
+
}
|
|
173
194
|
/**
|
|
174
195
|
* Extract the `sourceURIs` strings from a `localMediaItemLocations` or
|
|
175
196
|
* `globalMediaItemLocations` blob. A single location record can carry more
|
package/dist/tsaf.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tsaf.js","sourceRoot":"","sources":["../src/tsaf.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;GAkBG;;AAwDH,sCAIC;AAED,sCAIC;AAED,kCAMC;AAcD,wCAiBC;
|
|
1
|
+
{"version":3,"file":"tsaf.js","sourceRoot":"","sources":["../src/tsaf.ts"],"names":[],"mappings":"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"}
|