yoto-nodejs-client 0.0.9 → 0.0.10

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.
@@ -230,6 +230,7 @@ async function main () {
230
230
  }
231
231
 
232
232
  if (showFullState) {
233
+ const cardDuration = playback.cardDurationSeconds === null ? null : `${playback.cardDurationSeconds}s`
233
234
  // Show full playback state
234
235
  console.log(`\n${playbackIcon} PLAYBACK UPDATE [${timestamp}]: (FULL STATE)`)
235
236
  console.log(` Status: ${playback.playbackStatus}`)
@@ -239,6 +240,12 @@ async function main () {
239
240
  console.log(` Chapter Key: ${playback.chapterKey}`)
240
241
  console.log(` Position: ${playback.position}/${playback.trackLength}s`)
241
242
  console.log(` Card ID: ${playback.cardId}`)
243
+ console.log(` Card Title: ${playback.cardTitle}`)
244
+ console.log(` Card Slug: ${playback.cardSlug}`)
245
+ console.log(` Card Cover Image: ${playback.cardCoverImageUrl}`)
246
+ console.log(` Card Author: ${playback.cardAuthor}`)
247
+ console.log(` Card Read By: ${playback.cardReadBy}`)
248
+ console.log(` Card Duration: ${cardDuration}`)
242
249
  console.log(` Source: ${playback.source}`)
243
250
  console.log(` Streaming: ${playback.streaming}`)
244
251
  console.log(` Sleep Timer Active: ${playback.sleepTimerActive}`)
@@ -257,6 +264,9 @@ async function main () {
257
264
  // Skip if we already printed this combo
258
265
  if (field === 'trackLength') continue
259
266
  } else {
267
+ if (field === 'cardDurationSeconds' && typeof value === 'number') {
268
+ value = `${value}s`
269
+ }
260
270
  console.log(` ${field}: ${value}`)
261
271
  }
262
272
  }
@@ -1 +1 @@
1
- {"version":3,"file":"device-model-test-helpers.d.ts","sourceRoot":"","sources":["device-model-test-helpers.js"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH,qCALW,OAAO,CAAC,OAAO,CAAC,aAChB,MAAM,SACN,MAAM,GACJ,OAAO,CAAC,OAAO,CAAC,CAS5B;AAED;;;GAGG;AACH,yCAHW,eAAe,GACb,OAAO,CAAC,IAAI,CAAC,CAUzB;AAED;;GAEG;AACH,0CAFW,qBAAqB,QAkD/B;AAED;;GAEG;AACH,8CAFW,iBAAiB,QAkB3B;AAED;;;GAGG;AACH,+BAHW,MAAM,GAAG,SAAS,GAChB,MAAM,CAIlB;qCAnH8E,mBAAmB;2CAAnB,mBAAmB;uCAAnB,mBAAmB"}
1
+ {"version":3,"file":"device-model-test-helpers.d.ts","sourceRoot":"","sources":["device-model-test-helpers.js"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH,qCALW,OAAO,CAAC,OAAO,CAAC,aAChB,MAAM,SACN,MAAM,GACJ,OAAO,CAAC,OAAO,CAAC,CAS5B;AAED;;;GAGG;AACH,yCAHW,eAAe,GACb,OAAO,CAAC,IAAI,CAAC,CAUzB;AAED;;GAEG;AACH,0CAFW,qBAAqB,QAkD/B;AAED;;GAEG;AACH,8CAFW,iBAAiB,QAwB3B;AAED;;;GAGG;AACH,+BAHW,MAAM,GAAG,SAAS,GAChB,MAAM,CAIlB;qCAzH8E,mBAAmB;2CAAnB,mBAAmB;uCAAnB,mBAAmB"}
@@ -94,6 +94,12 @@ export function assertPlaybackShape (playback) {
94
94
  assert.equal(typeof playback.updatedAt, 'string', 'playback.updatedAt should be string')
95
95
 
96
96
  assert.ok(playback.cardId === null || typeof playback.cardId === 'string', 'playback.cardId should be string or null')
97
+ assert.ok(playback.cardTitle === null || typeof playback.cardTitle === 'string', 'playback.cardTitle should be string or null')
98
+ assert.ok(playback.cardSlug === null || typeof playback.cardSlug === 'string', 'playback.cardSlug should be string or null')
99
+ assert.ok(playback.cardCoverImageUrl === null || typeof playback.cardCoverImageUrl === 'string', 'playback.cardCoverImageUrl should be string or null')
100
+ assert.ok(playback.cardAuthor === null || typeof playback.cardAuthor === 'string', 'playback.cardAuthor should be string or null')
101
+ assert.ok(playback.cardReadBy === null || typeof playback.cardReadBy === 'string', 'playback.cardReadBy should be string or null')
102
+ assert.ok(playback.cardDurationSeconds === null || typeof playback.cardDurationSeconds === 'number', 'playback.cardDurationSeconds should be number or null')
97
103
  assert.ok(playback.source === null || typeof playback.source === 'string', 'playback.source should be string or null')
98
104
  assert.ok(playback.playbackStatus === null || typeof playback.playbackStatus === 'string', 'playback.playbackStatus should be string or null')
99
105
  assert.ok(playback.trackTitle === null || typeof playback.trackTitle === 'string', 'playback.trackTitle should be string or null')
@@ -102,6 +102,12 @@ export const YotoDeviceModelConfigType: {};
102
102
  * Playback state from MQTT events
103
103
  * @typedef {Object} YotoPlaybackState
104
104
  * @property {string | null} cardId - Currently playing card ID TODO: Figure out name of card
105
+ * @property {string | null} cardTitle - Card title (from cached content)
106
+ * @property {string | null} cardSlug - Card slug (from cached content)
107
+ * @property {string | null} cardCoverImageUrl - Card cover image URL (from cached content)
108
+ * @property {string | null} cardAuthor - Card author (from cached content)
109
+ * @property {string | null} cardReadBy - Card narrator/reader (from cached content)
110
+ * @property {number | null} cardDurationSeconds - Total card duration in seconds (from cached content)
105
111
  * @property {string | null} source - Playback source (e.g., 'card', 'remote', 'MQTT') TODO: Figure out what 'mqtt' source means. Card means card, remote means remotly played card.
106
112
  * @property {PlaybackStatus | null} playbackStatus - Playback status
107
113
  * @property {string | null} trackTitle - Current track title
@@ -135,7 +141,12 @@ export const YotoPlaybackStateType: {};
135
141
  * Cached card metadata for playback enrichment.
136
142
  * @typedef {Object} YotoCardCacheEntry
137
143
  * @property {string} cardId
138
- * @property {string} title
144
+ * @property {string} cardTitle
145
+ * @property {string | null} cardSlug
146
+ * @property {string | null} cardCoverImageUrl
147
+ * @property {string | null} cardAuthor
148
+ * @property {string | null} cardReadBy
149
+ * @property {number | null} cardDurationSeconds
139
150
  * @property {Map<string, YotoCardCacheChapterInfo>} chaptersByKey
140
151
  * @property {Map<string, YotoCardCacheTrackInfo>} tracksByKey
141
152
  */
@@ -824,6 +835,30 @@ export type YotoPlaybackState = {
824
835
  * - Currently playing card ID TODO: Figure out name of card
825
836
  */
826
837
  cardId: string | null;
838
+ /**
839
+ * - Card title (from cached content)
840
+ */
841
+ cardTitle: string | null;
842
+ /**
843
+ * - Card slug (from cached content)
844
+ */
845
+ cardSlug: string | null;
846
+ /**
847
+ * - Card cover image URL (from cached content)
848
+ */
849
+ cardCoverImageUrl: string | null;
850
+ /**
851
+ * - Card author (from cached content)
852
+ */
853
+ cardAuthor: string | null;
854
+ /**
855
+ * - Card narrator/reader (from cached content)
856
+ */
857
+ cardReadBy: string | null;
858
+ /**
859
+ * - Total card duration in seconds (from cached content)
860
+ */
861
+ cardDurationSeconds: number | null;
827
862
  /**
828
863
  * - Playback source (e.g., 'card', 'remote', 'MQTT') TODO: Figure out what 'mqtt' source means. Card means card, remote means remotly played card.
829
864
  */
@@ -895,7 +930,12 @@ export type YotoCardCacheTrackInfo = {
895
930
  */
896
931
  export type YotoCardCacheEntry = {
897
932
  cardId: string;
898
- title: string;
933
+ cardTitle: string;
934
+ cardSlug: string | null;
935
+ cardCoverImageUrl: string | null;
936
+ cardAuthor: string | null;
937
+ cardReadBy: string | null;
938
+ cardDurationSeconds: number | null;
899
939
  chaptersByKey: Map<string, YotoCardCacheChapterInfo>;
900
940
  tracksByKey: Map<string, YotoCardCacheTrackInfo>;
901
941
  };
@@ -1 +1 @@
1
- {"version":3,"file":"yoto-device.d.ts","sourceRoot":"","sources":["yoto-device.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"yoto-device.d.ts","sourceRoot":"","sources":["yoto-device.js"],"names":[],"mappings":"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"}
@@ -399,6 +399,12 @@ export const YotoDeviceModelConfigType = {}
399
399
  * Playback state from MQTT events
400
400
  * @typedef {Object} YotoPlaybackState
401
401
  * @property {string | null} cardId - Currently playing card ID TODO: Figure out name of card
402
+ * @property {string | null} cardTitle - Card title (from cached content)
403
+ * @property {string | null} cardSlug - Card slug (from cached content)
404
+ * @property {string | null} cardCoverImageUrl - Card cover image URL (from cached content)
405
+ * @property {string | null} cardAuthor - Card author (from cached content)
406
+ * @property {string | null} cardReadBy - Card narrator/reader (from cached content)
407
+ * @property {number | null} cardDurationSeconds - Total card duration in seconds (from cached content)
402
408
  * @property {string | null} source - Playback source (e.g., 'card', 'remote', 'MQTT') TODO: Figure out what 'mqtt' source means. Card means card, remote means remotly played card.
403
409
  * @property {PlaybackStatus | null} playbackStatus - Playback status
404
410
  * @property {string | null} trackTitle - Current track title
@@ -439,7 +445,12 @@ export const YotoPlaybackStateType = {}
439
445
  * Cached card metadata for playback enrichment.
440
446
  * @typedef {Object} YotoCardCacheEntry
441
447
  * @property {string} cardId
442
- * @property {string} title
448
+ * @property {string} cardTitle
449
+ * @property {string | null} cardSlug
450
+ * @property {string | null} cardCoverImageUrl
451
+ * @property {string | null} cardAuthor
452
+ * @property {string | null} cardReadBy
453
+ * @property {number | null} cardDurationSeconds
443
454
  * @property {Map<string, YotoCardCacheChapterInfo>} chaptersByKey
444
455
  * @property {Map<string, YotoCardCacheTrackInfo>} tracksByKey
445
456
  */
@@ -3433,6 +3444,12 @@ export class YotoDeviceModel extends EventEmitter {
3433
3444
  function createEmptyPlaybackState () {
3434
3445
  return {
3435
3446
  cardId: null,
3447
+ cardTitle: null,
3448
+ cardSlug: null,
3449
+ cardCoverImageUrl: null,
3450
+ cardAuthor: null,
3451
+ cardReadBy: null,
3452
+ cardDurationSeconds: null,
3436
3453
  source: null,
3437
3454
  playbackStatus: null,
3438
3455
  trackTitle: null,
@@ -3481,9 +3498,20 @@ function buildCardCacheEntry (card) {
3481
3498
  }
3482
3499
  }
3483
3500
 
3501
+ const cardCoverImageUrl = card.metadata?.cover?.imageL ?? null
3502
+ const cardAuthor = card.metadata?.author ?? null
3503
+ const cardReadBy = card.metadata?.readBy ?? null
3504
+ const cardDurationSeconds = Number.isFinite(card.metadata?.media?.duration) ? card.metadata.media.duration : null
3505
+ const cardSlug = card.slug || null
3506
+
3484
3507
  return {
3485
3508
  cardId: card.cardId,
3486
- title: card.title,
3509
+ cardTitle: card.title,
3510
+ cardSlug,
3511
+ cardCoverImageUrl,
3512
+ cardAuthor,
3513
+ cardReadBy,
3514
+ cardDurationSeconds,
3487
3515
  chaptersByKey,
3488
3516
  tracksByKey
3489
3517
  }
@@ -3497,6 +3525,43 @@ function buildCardCacheEntry (card) {
3497
3525
  */
3498
3526
  function applyCardCacheToPlayback (entry, playback, changedFields) {
3499
3527
  let changed = false
3528
+
3529
+ if (playback.cardTitle !== entry.cardTitle) {
3530
+ playback.cardTitle = entry.cardTitle
3531
+ changedFields.add('cardTitle')
3532
+ changed = true
3533
+ }
3534
+
3535
+ if (playback.cardSlug !== entry.cardSlug) {
3536
+ playback.cardSlug = entry.cardSlug
3537
+ changedFields.add('cardSlug')
3538
+ changed = true
3539
+ }
3540
+
3541
+ if (playback.cardCoverImageUrl !== entry.cardCoverImageUrl) {
3542
+ playback.cardCoverImageUrl = entry.cardCoverImageUrl
3543
+ changedFields.add('cardCoverImageUrl')
3544
+ changed = true
3545
+ }
3546
+
3547
+ if (playback.cardAuthor !== entry.cardAuthor) {
3548
+ playback.cardAuthor = entry.cardAuthor
3549
+ changedFields.add('cardAuthor')
3550
+ changed = true
3551
+ }
3552
+
3553
+ if (playback.cardReadBy !== entry.cardReadBy) {
3554
+ playback.cardReadBy = entry.cardReadBy
3555
+ changedFields.add('cardReadBy')
3556
+ changed = true
3557
+ }
3558
+
3559
+ if (playback.cardDurationSeconds !== entry.cardDurationSeconds) {
3560
+ playback.cardDurationSeconds = entry.cardDurationSeconds
3561
+ changedFields.add('cardDurationSeconds')
3562
+ changed = true
3563
+ }
3564
+
3500
3565
  const { trackKey } = playback
3501
3566
 
3502
3567
  if (trackKey) {
@@ -21,6 +21,12 @@ const PLAYBACK_SAMPLE_SCAN_LIMIT = 5
21
21
  /**
22
22
  * @typedef {Object} PlaybackSample
23
23
  * @property {string} cardId
24
+ * @property {string} cardTitle
25
+ * @property {string | null} cardSlug
26
+ * @property {string | null} cardCoverImageUrl
27
+ * @property {string | null} cardAuthor
28
+ * @property {string | null} cardReadBy
29
+ * @property {number | null} cardDurationSeconds
24
30
  * @property {Map<string, { title: string, duration: number, chapterKey: string, chapterTitle: string }>} tracksByKey
25
31
  * @property {string} chapterKey
26
32
  * @property {string} chapterTitle
@@ -86,7 +92,14 @@ async function findPlaybackSample (client) {
86
92
 
87
93
  try {
88
94
  const contentResponse = await client.getContent({ cardId: card.cardId })
89
- const chapters = contentResponse.card.content.chapters
95
+ const contentCard = contentResponse.card
96
+ const metadata = contentCard.metadata
97
+ const cardCoverImageUrl = metadata?.cover?.imageL ?? null
98
+ const cardAuthor = metadata?.author ?? null
99
+ const cardReadBy = metadata?.readBy ?? null
100
+ const cardDurationSeconds = Number.isFinite(metadata?.media?.duration) ? metadata.media.duration : null
101
+ const cardSlug = contentCard.slug || null
102
+ const chapters = contentCard.content.chapters
90
103
  const firstChapter = chapters.find(candidate => candidate.tracks.length > 0)
91
104
 
92
105
  if (!firstChapter) {
@@ -117,7 +130,13 @@ async function findPlaybackSample (client) {
117
130
  }
118
131
 
119
132
  return {
120
- cardId: contentResponse.card.cardId,
133
+ cardId: contentCard.cardId,
134
+ cardTitle: contentCard.title,
135
+ cardSlug,
136
+ cardCoverImageUrl,
137
+ cardAuthor,
138
+ cardReadBy,
139
+ cardDurationSeconds,
121
140
  tracksByKey,
122
141
  chapterKey: firstChapter.key,
123
142
  chapterTitle: firstChapter.title,
@@ -284,6 +303,12 @@ test('YotoDeviceModel - playback normalization', async (t) => {
284
303
  assert.equal(cachePlayback.trackLength, trackInfo.duration)
285
304
  assert.equal(cachePlayback.chapterKey, trackInfo.chapterKey)
286
305
  assert.equal(cachePlayback.chapterTitle, trackInfo.chapterTitle)
306
+ assert.equal(cachePlayback.cardTitle, sample.cardTitle)
307
+ assert.equal(cachePlayback.cardSlug, sample.cardSlug)
308
+ assert.equal(cachePlayback.cardCoverImageUrl, sample.cardCoverImageUrl)
309
+ assert.equal(cachePlayback.cardAuthor, sample.cardAuthor)
310
+ assert.equal(cachePlayback.cardReadBy, sample.cardReadBy)
311
+ assert.equal(cachePlayback.cardDurationSeconds, sample.cardDurationSeconds)
287
312
  })
288
313
 
289
314
  await t.test('cardId none normalization', async () => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "yoto-nodejs-client",
3
3
  "description": "(Unofficial) Node.js client for the Yoto API with automatic token refresh, MQTT device communication, and TypeScript support",
4
- "version": "0.0.9",
4
+ "version": "0.0.10",
5
5
  "author": "Bret Comnes <bcomnes@gmail.com> (https://bret.io)",
6
6
  "bugs": {
7
7
  "url": "https://github.com/bcomnes/yoto-nodejs-client/issues"