@tomorrowos/sdk 0.6.9 → 0.7.1

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.
@@ -33,7 +33,7 @@ export declare class PlaylistCatalog {
33
33
  /** Remove every playlist assignment from a device (CMS catalog + empty policy). */
34
34
  clearAllAssignmentsFromDevice(deviceId: string): Promise<BuiltDevicePolicy>;
35
35
  /**
36
- * If the device has this playlist assigned, refresh its snapshot/version to latest
36
+ * If the device has this playlist assigned, refresh its snapshot to latest
37
37
  * and return a rebuilt snapshot policy for immediate push.
38
38
  */
39
39
  refreshPlaylistSnapshotOnDevice(deviceId: string, playlistId: string, options?: PolicyBuildOptions): Promise<{
@@ -1 +1 @@
1
- {"version":3,"file":"playlist-catalog.d.ts","sourceRoot":"","sources":["../src/playlist-catalog.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,wBAAwB,EACxB,kBAAkB,EAClB,gBAAgB,EAChB,yBAAyB,EACzB,cAAc,EACd,eAAe,EAChB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,iBAAiB;IAChC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,KAAK,EAAE,kBAAkB,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE;QACN,SAAS,EAAE,yBAAyB,EAAE,CAAC;QACvC,QAAQ,EAAE;YAAE,IAAI,EAAE,OAAO,CAAA;SAAE,CAAC;QAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;KAClC,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA+CD,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,eAAe;IAE7C,aAAa,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IAK1C,6BAA6B,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IAI1D,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;IAI5D,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC;IAgC/D,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAcnD,oBAAoB,CACxB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,wBAAwB,EAAE,CAAC;IAIhC,wBAAwB,CAC5B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EAAE,EACrB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,iBAAiB,CAAC;IA2CvB,wBAAwB,CAC5B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,iBAAiB,CAAC;IAO7B,mFAAmF;IAC7E,6BAA6B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAKjF;;;OAGG;IACG,+BAA+B,CACnC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,iBAAiB,CAAA;KAAE,CAAC;IA6BrD,oBAAoB,CACxB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,iBAAiB,CAAC;YAKf,0BAA0B;IAgCxC,6BAA6B,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAGpE"}
1
+ {"version":3,"file":"playlist-catalog.d.ts","sourceRoot":"","sources":["../src/playlist-catalog.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,wBAAwB,EACxB,kBAAkB,EAClB,gBAAgB,EAChB,yBAAyB,EACzB,cAAc,EACd,eAAe,EAChB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,iBAAiB;IAChC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,KAAK,EAAE,kBAAkB,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE;QACN,SAAS,EAAE,yBAAyB,EAAE,CAAC;QACvC,QAAQ,EAAE;YAAE,IAAI,EAAE,OAAO,CAAA;SAAE,CAAC;QAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;KAClC,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA8CD,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,eAAe;IAE7C,aAAa,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IAK1C,6BAA6B,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IAI1D,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;IAI5D,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC;IA8B/D,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAcnD,oBAAoB,CACxB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,wBAAwB,EAAE,CAAC;IAIhC,wBAAwB,CAC5B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EAAE,EACrB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,iBAAiB,CAAC;IA0CvB,wBAAwB,CAC5B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,iBAAiB,CAAC;IAO7B,mFAAmF;IAC7E,6BAA6B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAKjF;;;OAGG;IACG,+BAA+B,CACnC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,iBAAiB,CAAA;KAAE,CAAC;IA4BrD,oBAAoB,CACxB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,iBAAiB,CAAC;YAKf,0BAA0B;IAgCxC,6BAA6B,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAGpE"}
@@ -36,7 +36,6 @@ function cloneSnapshot(playlist, mediaBaseUrl) {
36
36
  return {
37
37
  id: playlist.id,
38
38
  name: playlist.name,
39
- version: playlist.version,
40
39
  schedule: playlist.schedule ? { ...playlist.schedule } : undefined,
41
40
  items: absolutizePlaylistItems(playlist.items, mediaBaseUrl)
42
41
  };
@@ -70,14 +69,12 @@ export class PlaylistCatalog {
70
69
  code: "PLAYLIST_NAME_CONFLICT"
71
70
  });
72
71
  }
73
- const existing = await this.store.getPlaylist(id);
74
72
  const now = new Date().toISOString();
75
73
  const record = {
76
74
  id,
77
75
  name,
78
76
  schedule: input.schedule,
79
77
  items: Array.isArray(input.items) ? input.items : [],
80
- version: (existing?.version ?? 0) + 1,
81
78
  updatedAt: now,
82
79
  retired: false
83
80
  };
@@ -126,7 +123,6 @@ export class PlaylistCatalog {
126
123
  }
127
124
  assignments.push({
128
125
  playlistId,
129
- publishedVersion: playlist.version,
130
126
  publishedAt: new Date().toISOString(),
131
127
  snapshot: cloneSnapshot(playlist, options.mediaBaseUrl)
132
128
  });
@@ -149,7 +145,7 @@ export class PlaylistCatalog {
149
145
  return this.buildPolicyFromAssignments([], { useLatest: false });
150
146
  }
151
147
  /**
152
- * If the device has this playlist assigned, refresh its snapshot/version to latest
148
+ * If the device has this playlist assigned, refresh its snapshot to latest
153
149
  * and return a rebuilt snapshot policy for immediate push.
154
150
  */
155
151
  async refreshPlaylistSnapshotOnDevice(deviceId, playlistId, options = {}) {
@@ -165,7 +161,6 @@ export class PlaylistCatalog {
165
161
  ? a
166
162
  : {
167
163
  playlistId,
168
- publishedVersion: playlist.version,
169
164
  publishedAt: new Date().toISOString(),
170
165
  snapshot: cloneSnapshot(playlist, options.mediaBaseUrl)
171
166
  });
@@ -13,6 +13,7 @@ export declare class PostgresStore implements TomorrowOSMigratableStore {
13
13
  private ready?;
14
14
  constructor(options: PostgresStoreOptions | string);
15
15
  init(): Promise<void>;
16
+ private migrateDropPlaylistVersionColumns;
16
17
  close(): Promise<void>;
17
18
  private ensureReady;
18
19
  setPendingCode(code: string, record: PendingCodeRecord): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"postgres-store.d.ts","sourceRoot":"","sources":["../../src/store/postgres-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"postgres-store.d.ts","sourceRoot":"","sources":["../../src/store/postgres-store.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { Pool } from "pg";
2
+ import { normalizePublishedPlaylistSnapshot } from "./snapshot-utils.js";
2
3
  function optionalString(value) {
3
4
  return value ?? undefined;
4
5
  }
@@ -59,6 +60,7 @@ export class PostgresStore {
59
60
  platform TEXT,
60
61
  system TEXT,
61
62
  player_version TEXT,
63
+ system_version TEXT,
62
64
  last_boot_at TEXT,
63
65
  last_online_at TEXT,
64
66
  last_offline_at TEXT,
@@ -70,7 +72,6 @@ export class PostgresStore {
70
72
  name TEXT NOT NULL,
71
73
  schedule_json TEXT,
72
74
  items_json TEXT NOT NULL DEFAULT '[]',
73
- version INTEGER NOT NULL,
74
75
  updated_at TEXT NOT NULL,
75
76
  retired BOOLEAN NOT NULL DEFAULT false,
76
77
  retired_at TEXT
@@ -84,7 +85,6 @@ export class PostgresStore {
84
85
  device_id TEXT NOT NULL,
85
86
  playlist_id TEXT NOT NULL,
86
87
  sort_order INTEGER NOT NULL,
87
- published_version INTEGER NOT NULL,
88
88
  published_at TEXT NOT NULL,
89
89
  snapshot_json TEXT NOT NULL,
90
90
  PRIMARY KEY (device_id, playlist_id)
@@ -117,6 +117,49 @@ export class PostgresStore {
117
117
 
118
118
  ALTER TABLE paired_devices
119
119
  ADD COLUMN IF NOT EXISTS player_version TEXT;
120
+
121
+ ALTER TABLE paired_devices
122
+ ADD COLUMN IF NOT EXISTS system_version TEXT;
123
+ `);
124
+ await this.migrateDropPlaylistVersionColumns();
125
+ }
126
+ async migrateDropPlaylistVersionColumns() {
127
+ const applied = await this.pool.query(`
128
+ SELECT 1 AS exists
129
+ FROM schema_migrations
130
+ WHERE name = 'drop_playlist_version'
131
+ LIMIT 1
132
+ `);
133
+ if (applied.rows.length > 0)
134
+ return;
135
+ await this.pool.query(`
136
+ ALTER TABLE playlists
137
+ DROP COLUMN IF EXISTS version;
138
+ `);
139
+ await this.pool.query(`
140
+ ALTER TABLE device_assignments
141
+ DROP COLUMN IF EXISTS published_version;
142
+ `);
143
+ const assignmentRows = await this.pool.query(`
144
+ SELECT device_id, playlist_id, snapshot_json
145
+ FROM device_assignments
146
+ `);
147
+ for (const row of assignmentRows.rows) {
148
+ const snapshot = normalizePublishedPlaylistSnapshot(parseJson(row.snapshot_json, {
149
+ id: row.playlist_id,
150
+ name: row.playlist_id,
151
+ items: []
152
+ }));
153
+ await this.pool.query(`
154
+ UPDATE device_assignments
155
+ SET snapshot_json = $1
156
+ WHERE device_id = $2 AND playlist_id = $3
157
+ `, [JSON.stringify(snapshot), row.device_id, row.playlist_id]);
158
+ }
159
+ await this.pool.query(`
160
+ INSERT INTO schema_migrations (id, name)
161
+ VALUES (2, 'drop_playlist_version')
162
+ ON CONFLICT (id) DO NOTHING
120
163
  `);
121
164
  }
122
165
  async close() {
@@ -239,12 +282,13 @@ export class PostgresStore {
239
282
  platform,
240
283
  system,
241
284
  player_version,
285
+ system_version,
242
286
  last_boot_at,
243
287
  last_online_at,
244
288
  last_offline_at,
245
289
  last_policy_push_at
246
290
  )
247
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
291
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
248
292
  ON CONFLICT (device_id) DO UPDATE SET
249
293
  pairing_token = EXCLUDED.pairing_token,
250
294
  paired_at = EXCLUDED.paired_at,
@@ -252,6 +296,7 @@ export class PostgresStore {
252
296
  platform = EXCLUDED.platform,
253
297
  system = EXCLUDED.system,
254
298
  player_version = EXCLUDED.player_version,
299
+ system_version = EXCLUDED.system_version,
255
300
  last_boot_at = EXCLUDED.last_boot_at,
256
301
  last_online_at = EXCLUDED.last_online_at,
257
302
  last_offline_at = EXCLUDED.last_offline_at,
@@ -264,6 +309,7 @@ export class PostgresStore {
264
309
  record.platform ?? null,
265
310
  record.system ?? null,
266
311
  record.playerVersion ?? null,
312
+ record.systemVersion ?? null,
267
313
  record.lastBootAt ?? null,
268
314
  record.lastOnlineAt ?? null,
269
315
  record.lastOfflineAt ?? null,
@@ -325,17 +371,15 @@ export class PostgresStore {
325
371
  name,
326
372
  schedule_json,
327
373
  items_json,
328
- version,
329
374
  updated_at,
330
375
  retired,
331
376
  retired_at
332
377
  )
333
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
378
+ VALUES ($1, $2, $3, $4, $5, $6, $7)
334
379
  ON CONFLICT (id) DO UPDATE SET
335
380
  name = EXCLUDED.name,
336
381
  schedule_json = EXCLUDED.schedule_json,
337
382
  items_json = EXCLUDED.items_json,
338
- version = EXCLUDED.version,
339
383
  updated_at = EXCLUDED.updated_at,
340
384
  retired = EXCLUDED.retired,
341
385
  retired_at = EXCLUDED.retired_at
@@ -344,7 +388,6 @@ export class PostgresStore {
344
388
  record.name,
345
389
  record.schedule ? JSON.stringify(record.schedule) : null,
346
390
  JSON.stringify(record.items ?? []),
347
- record.version,
348
391
  record.updatedAt,
349
392
  record.retired === true,
350
393
  record.retiredAt ?? null
@@ -444,21 +487,19 @@ export class PostgresStore {
444
487
  async getDeviceAssignments(deviceId) {
445
488
  await this.ensureReady();
446
489
  const result = await this.pool.query(`
447
- SELECT playlist_id, published_version, published_at, snapshot_json
490
+ SELECT playlist_id, published_at, snapshot_json
448
491
  FROM device_assignments
449
492
  WHERE device_id = $1
450
493
  ORDER BY sort_order ASC
451
494
  `, [deviceId]);
452
495
  return result.rows.map((row) => ({
453
496
  playlistId: row.playlist_id,
454
- publishedVersion: row.published_version,
455
497
  publishedAt: row.published_at,
456
- snapshot: parseJson(row.snapshot_json, {
498
+ snapshot: normalizePublishedPlaylistSnapshot(parseJson(row.snapshot_json, {
457
499
  id: row.playlist_id,
458
500
  name: row.playlist_id,
459
- version: row.published_version,
460
501
  items: []
461
- })
502
+ }))
462
503
  }));
463
504
  }
464
505
  async setDeviceAssignments(deviceId, assignments) {
@@ -475,16 +516,14 @@ export class PostgresStore {
475
516
  device_id,
476
517
  playlist_id,
477
518
  sort_order,
478
- published_version,
479
519
  published_at,
480
520
  snapshot_json
481
521
  )
482
- VALUES ($1, $2, $3, $4, $5, $6)
522
+ VALUES ($1, $2, $3, $4, $5)
483
523
  `, [
484
524
  deviceId,
485
525
  assignment.playlistId,
486
526
  index,
487
- assignment.publishedVersion,
488
527
  assignment.publishedAt,
489
528
  JSON.stringify(assignment.snapshot)
490
529
  ]);
@@ -516,6 +555,7 @@ export class PostgresStore {
516
555
  platform: optionalString(row.platform),
517
556
  system: optionalString(row.system),
518
557
  playerVersion: optionalString(row.player_version),
558
+ systemVersion: optionalString(row.system_version),
519
559
  lastBootAt: optionalString(row.last_boot_at),
520
560
  lastOnlineAt: optionalString(row.last_online_at),
521
561
  lastOfflineAt: optionalString(row.last_offline_at),
@@ -528,7 +568,6 @@ export class PostgresStore {
528
568
  name: row.name,
529
569
  schedule: parseJson(row.schedule_json, undefined),
530
570
  items: parseJson(row.items_json, []),
531
- version: row.version,
532
571
  updatedAt: row.updated_at,
533
572
  retired: row.retired,
534
573
  retiredAt: optionalString(row.retired_at)
@@ -0,0 +1,6 @@
1
+ import type { PublishedPlaylistSnapshot } from "./types.js";
2
+ /** Drop legacy playlist `version` fields from stored assignment snapshots. */
3
+ export declare function normalizePublishedPlaylistSnapshot(value: PublishedPlaylistSnapshot & {
4
+ version?: unknown;
5
+ }): PublishedPlaylistSnapshot;
6
+ //# sourceMappingURL=snapshot-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-utils.d.ts","sourceRoot":"","sources":["../../src/store/snapshot-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAE5D,8EAA8E;AAC9E,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,yBAAyB,GAAG;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GACvD,yBAAyB,CAG3B"}
@@ -0,0 +1,5 @@
1
+ /** Drop legacy playlist `version` fields from stored assignment snapshots. */
2
+ export function normalizePublishedPlaylistSnapshot(value) {
3
+ const { version: _legacyVersion, ...rest } = value;
4
+ return rest;
5
+ }
@@ -11,6 +11,8 @@ export declare class SQLiteStore implements TomorrowOSMigratableStore {
11
11
  private readonly db;
12
12
  constructor(options?: SQLiteStoreOptions | string);
13
13
  init(): void;
14
+ private tableHasColumn;
15
+ private migrateDropPlaylistVersionColumns;
14
16
  private addColumnIfMissing;
15
17
  close(): void;
16
18
  setPendingCode(code: string, record: PendingCodeRecord): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite-store.d.ts","sourceRoot":"","sources":["../../src/store/sqlite-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sqlite-store.d.ts","sourceRoot":"","sources":["../../src/store/sqlite-store.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import fs from "fs";
2
2
  import path from "path";
3
3
  import Database from "better-sqlite3";
4
+ import { normalizePublishedPlaylistSnapshot } from "./snapshot-utils.js";
4
5
  const DEFAULT_SQLITE_PATH = path.join(process.cwd(), "data", "tomorrowos.db");
5
6
  function optionalString(value) {
6
7
  return value ?? undefined;
@@ -65,6 +66,7 @@ export class SQLiteStore {
65
66
  platform TEXT,
66
67
  system TEXT,
67
68
  player_version TEXT,
69
+ system_version TEXT,
68
70
  last_boot_at TEXT,
69
71
  last_online_at TEXT,
70
72
  last_offline_at TEXT,
@@ -76,7 +78,6 @@ export class SQLiteStore {
76
78
  name TEXT NOT NULL,
77
79
  schedule_json TEXT,
78
80
  items_json TEXT NOT NULL DEFAULT '[]',
79
- version INTEGER NOT NULL,
80
81
  updated_at TEXT NOT NULL,
81
82
  retired INTEGER NOT NULL DEFAULT 0,
82
83
  retired_at TEXT
@@ -90,7 +91,6 @@ export class SQLiteStore {
90
91
  device_id TEXT NOT NULL,
91
92
  playlist_id TEXT NOT NULL,
92
93
  sort_order INTEGER NOT NULL,
93
- published_version INTEGER NOT NULL,
94
94
  published_at TEXT NOT NULL,
95
95
  snapshot_json TEXT NOT NULL,
96
96
  PRIMARY KEY (device_id, playlist_id)
@@ -121,6 +121,96 @@ export class SQLiteStore {
121
121
  VALUES (1, 'initial_tomorrowos_store');
122
122
  `);
123
123
  this.addColumnIfMissing("paired_devices", "player_version TEXT");
124
+ this.addColumnIfMissing("paired_devices", "system_version TEXT");
125
+ this.migrateDropPlaylistVersionColumns();
126
+ }
127
+ tableHasColumn(table, column) {
128
+ const rows = this.db.pragma(`table_info(${table})`);
129
+ return rows.some((row) => row.name === column);
130
+ }
131
+ migrateDropPlaylistVersionColumns() {
132
+ const alreadyApplied = this.db.prepare(`
133
+ SELECT 1
134
+ FROM schema_migrations
135
+ WHERE name = 'drop_playlist_version'
136
+ LIMIT 1
137
+ `).get();
138
+ if (alreadyApplied)
139
+ return;
140
+ if (this.tableHasColumn("playlists", "version")) {
141
+ this.db.exec(`
142
+ CREATE TABLE playlists_new (
143
+ id TEXT PRIMARY KEY,
144
+ name TEXT NOT NULL,
145
+ schedule_json TEXT,
146
+ items_json TEXT NOT NULL DEFAULT '[]',
147
+ updated_at TEXT NOT NULL,
148
+ retired INTEGER NOT NULL DEFAULT 0,
149
+ retired_at TEXT
150
+ );
151
+
152
+ INSERT INTO playlists_new (
153
+ id, name, schedule_json, items_json, updated_at, retired, retired_at
154
+ )
155
+ SELECT id, name, schedule_json, items_json, updated_at, retired, retired_at
156
+ FROM playlists;
157
+
158
+ DROP TABLE playlists;
159
+ ALTER TABLE playlists_new RENAME TO playlists;
160
+
161
+ CREATE UNIQUE INDEX IF NOT EXISTS playlists_active_name_unique
162
+ ON playlists (lower(trim(name)))
163
+ WHERE retired = 0;
164
+ `);
165
+ }
166
+ if (this.tableHasColumn("device_assignments", "published_version")) {
167
+ const rows = this.db.prepare(`
168
+ SELECT device_id, playlist_id, sort_order, published_at, snapshot_json
169
+ FROM device_assignments
170
+ ORDER BY device_id ASC, sort_order ASC
171
+ `).all();
172
+ this.db.exec(`
173
+ CREATE TABLE device_assignments_new (
174
+ device_id TEXT NOT NULL,
175
+ playlist_id TEXT NOT NULL,
176
+ sort_order INTEGER NOT NULL,
177
+ published_at TEXT NOT NULL,
178
+ snapshot_json TEXT NOT NULL,
179
+ PRIMARY KEY (device_id, playlist_id)
180
+ );
181
+ `);
182
+ const insert = this.db.prepare(`
183
+ INSERT INTO device_assignments_new (
184
+ device_id,
185
+ playlist_id,
186
+ sort_order,
187
+ published_at,
188
+ snapshot_json
189
+ )
190
+ VALUES (?, ?, ?, ?, ?)
191
+ `);
192
+ const replaceAssignments = this.db.transaction(() => {
193
+ for (const row of rows) {
194
+ const snapshot = normalizePublishedPlaylistSnapshot(parseJson(row.snapshot_json, {
195
+ id: row.playlist_id,
196
+ name: row.playlist_id,
197
+ items: []
198
+ }));
199
+ insert.run(row.device_id, row.playlist_id, row.sort_order, row.published_at, JSON.stringify(snapshot));
200
+ }
201
+ this.db.exec("DROP TABLE device_assignments");
202
+ this.db.exec("ALTER TABLE device_assignments_new RENAME TO device_assignments");
203
+ this.db.exec(`
204
+ CREATE INDEX IF NOT EXISTS device_assignments_device_order_idx
205
+ ON device_assignments (device_id, sort_order)
206
+ `);
207
+ });
208
+ replaceAssignments();
209
+ }
210
+ this.db.prepare(`
211
+ INSERT OR IGNORE INTO schema_migrations (id, name)
212
+ VALUES (2, 'drop_playlist_version')
213
+ `).run();
124
214
  }
125
215
  addColumnIfMissing(table, columnDefinition) {
126
216
  try {
@@ -229,12 +319,13 @@ export class SQLiteStore {
229
319
  platform,
230
320
  system,
231
321
  player_version,
322
+ system_version,
232
323
  last_boot_at,
233
324
  last_online_at,
234
325
  last_offline_at,
235
326
  last_policy_push_at
236
327
  )
237
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
328
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
238
329
  ON CONFLICT(device_id) DO UPDATE SET
239
330
  pairing_token = excluded.pairing_token,
240
331
  paired_at = excluded.paired_at,
@@ -242,11 +333,12 @@ export class SQLiteStore {
242
333
  platform = excluded.platform,
243
334
  system = excluded.system,
244
335
  player_version = excluded.player_version,
336
+ system_version = excluded.system_version,
245
337
  last_boot_at = excluded.last_boot_at,
246
338
  last_online_at = excluded.last_online_at,
247
339
  last_offline_at = excluded.last_offline_at,
248
340
  last_policy_push_at = excluded.last_policy_push_at
249
- `).run(deviceId, record.pairingToken, record.pairedAt, record.deviceName ?? null, record.platform ?? null, record.system ?? null, record.playerVersion ?? null, record.lastBootAt ?? null, record.lastOnlineAt ?? null, record.lastOfflineAt ?? null, record.lastPolicyPushAt ?? null);
341
+ `).run(deviceId, record.pairingToken, record.pairedAt, record.deviceName ?? null, record.platform ?? null, record.system ?? null, record.playerVersion ?? null, record.systemVersion ?? null, record.lastBootAt ?? null, record.lastOnlineAt ?? null, record.lastOfflineAt ?? null, record.lastPolicyPushAt ?? null);
250
342
  }
251
343
  async getPairedDevice(deviceId) {
252
344
  const row = this.db.prepare(`
@@ -293,21 +385,19 @@ export class SQLiteStore {
293
385
  name,
294
386
  schedule_json,
295
387
  items_json,
296
- version,
297
388
  updated_at,
298
389
  retired,
299
390
  retired_at
300
391
  )
301
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)
392
+ VALUES (?, ?, ?, ?, ?, ?, ?)
302
393
  ON CONFLICT(id) DO UPDATE SET
303
394
  name = excluded.name,
304
395
  schedule_json = excluded.schedule_json,
305
396
  items_json = excluded.items_json,
306
- version = excluded.version,
307
397
  updated_at = excluded.updated_at,
308
398
  retired = excluded.retired,
309
399
  retired_at = excluded.retired_at
310
- `).run(record.id, record.name, record.schedule ? JSON.stringify(record.schedule) : null, JSON.stringify(record.items ?? []), record.version, record.updatedAt, record.retired ? 1 : 0, record.retiredAt ?? null);
400
+ `).run(record.id, record.name, record.schedule ? JSON.stringify(record.schedule) : null, JSON.stringify(record.items ?? []), record.updatedAt, record.retired ? 1 : 0, record.retiredAt ?? null);
311
401
  }
312
402
  async isPlaylistNameTaken(name, excludeId) {
313
403
  const target = name.trim().toLowerCase();
@@ -382,21 +472,19 @@ export class SQLiteStore {
382
472
  }
383
473
  async getDeviceAssignments(deviceId) {
384
474
  const rows = this.db.prepare(`
385
- SELECT playlist_id, published_version, published_at, snapshot_json
475
+ SELECT playlist_id, published_at, snapshot_json
386
476
  FROM device_assignments
387
477
  WHERE device_id = ?
388
478
  ORDER BY sort_order ASC
389
479
  `).all(deviceId);
390
480
  return rows.map((row) => ({
391
481
  playlistId: row.playlist_id,
392
- publishedVersion: row.published_version,
393
482
  publishedAt: row.published_at,
394
- snapshot: parseJson(row.snapshot_json, {
483
+ snapshot: normalizePublishedPlaylistSnapshot(parseJson(row.snapshot_json, {
395
484
  id: row.playlist_id,
396
485
  name: row.playlist_id,
397
- version: row.published_version,
398
486
  items: []
399
- })
487
+ }))
400
488
  }));
401
489
  }
402
490
  async setDeviceAssignments(deviceId, assignments) {
@@ -407,14 +495,13 @@ export class SQLiteStore {
407
495
  device_id,
408
496
  playlist_id,
409
497
  sort_order,
410
- published_version,
411
498
  published_at,
412
499
  snapshot_json
413
500
  )
414
- VALUES (?, ?, ?, ?, ?, ?)
501
+ VALUES (?, ?, ?, ?, ?)
415
502
  `);
416
503
  assignments.forEach((assignment, index) => {
417
- insert.run(deviceId, assignment.playlistId, index, assignment.publishedVersion, assignment.publishedAt, JSON.stringify(assignment.snapshot));
504
+ insert.run(deviceId, assignment.playlistId, index, assignment.publishedAt, JSON.stringify(assignment.snapshot));
418
505
  });
419
506
  });
420
507
  replaceAssignments();
@@ -436,6 +523,7 @@ export class SQLiteStore {
436
523
  platform: optionalString(row.platform),
437
524
  system: optionalString(row.system),
438
525
  playerVersion: optionalString(row.player_version),
526
+ systemVersion: optionalString(row.system_version),
439
527
  lastBootAt: optionalString(row.last_boot_at),
440
528
  lastOnlineAt: optionalString(row.last_online_at),
441
529
  lastOfflineAt: optionalString(row.last_offline_at),
@@ -448,7 +536,6 @@ export class SQLiteStore {
448
536
  name: row.name,
449
537
  schedule: parseJson(row.schedule_json, undefined),
450
538
  items: parseJson(row.items_json, []),
451
- version: row.version,
452
539
  updatedAt: row.updated_at,
453
540
  retired: row.retired === 1,
454
541
  retiredAt: optionalString(row.retired_at)
@@ -21,6 +21,7 @@ export interface PairedDeviceRecord {
21
21
  platform?: string;
22
22
  system?: string;
23
23
  playerVersion?: string;
24
+ systemVersion?: string;
24
25
  lastBootAt?: string;
25
26
  lastOnlineAt?: string;
26
27
  lastOfflineAt?: string;
@@ -74,7 +75,6 @@ export interface StoredPlaylist {
74
75
  name: string;
75
76
  schedule?: PlaylistSchedule;
76
77
  items: PlaylistItemRecord[];
77
- version: number;
78
78
  updatedAt: string;
79
79
  retired?: boolean;
80
80
  retiredAt?: string;
@@ -82,13 +82,11 @@ export interface StoredPlaylist {
82
82
  export interface PublishedPlaylistSnapshot {
83
83
  id: string;
84
84
  name: string;
85
- version: number;
86
85
  schedule?: PlaylistSchedule;
87
86
  items: PlaylistItemRecord[];
88
87
  }
89
88
  export interface DevicePlaylistAssignment {
90
89
  playlistId: string;
91
- publishedVersion: number;
92
90
  publishedAt: string;
93
91
  snapshot: PublishedPlaylistSnapshot;
94
92
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/store/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wFAAwF;AACxF,MAAM,WAAW,oBAAoB;IACnC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,iBAAiB,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,oBAAoB,CAAC;CAC9B;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,4BAA4B,GAAG,OAAO,GAAG,YAAY,CAAC;AAElE,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,4BAA4B,CAAC;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wGAAwG;AACxG,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qFAAqF;IACrF,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,yBAAyB;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,KAAK,EAAE,kBAAkB,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,wBAAwB;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,yBAAyB,CAAC;CACrC;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAAC;IACrE,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,CAAC;IAC/E,iBAAiB,CACf,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,uBAAuB,CACrB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,oBAAoB,CAAA;KAAE,GAAG,SAAS,CAAC,CAAC;IAC3E,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7E,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAAC;IAC3E,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,iBAAiB,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAClD,aAAa,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAC3C,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;IAC7D,WAAW,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACxE,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAAC;IACvE,wBAAwB,CACtB,MAAM,EAAE,MAAM,EACd,eAAe,CAAC,EAAE,4BAA4B,GAC7C,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAAC;IAC5C,gBAAgB,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,EAAE,CAAC,CAAC;IAC5E,oBAAoB,CAClB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,wBAAwB,EAAE,GACtC,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACrC,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,cAAc,EAAE,mBAAmB,EAAE,CAAC;IACtC,aAAa,EAAE,iBAAiB,EAAE,CAAC;IACnC,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,cAAc,EAAE,mBAAmB,EAAE,CAAC;IACtC,iBAAiB,EAAE,KAAK,CAAC;QACvB,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,wBAAwB,EAAE,CAAC;KACzC,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,yBAA0B,SAAQ,eAAe;IAChE,gBAAgB,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAChD,kBAAkB,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;IACrD,kBAAkB,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;CACtD"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/store/types.ts"],"names":[],"mappings":"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"}
@@ -37,6 +37,7 @@ export interface DeviceListItem {
37
37
  platform: string | null;
38
38
  system: string | null;
39
39
  playerVersion: string | null;
40
+ systemVersion: string | null;
40
41
  serialNumber: string | null;
41
42
  pairedAt: string;
42
43
  lastBootAt: string | null;
@@ -50,7 +51,6 @@ export interface DeviceListItem {
50
51
  publishedPlaylists: Array<{
51
52
  playlistId: string;
52
53
  name: string;
53
- version: number;
54
54
  publishedAt: string;
55
55
  schedule?: {
56
56
  startDate?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"tomorrowos.d.ts","sourceRoot":"","sources":["../src/tomorrowos.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tomorrowos.d.ts","sourceRoot":"","sources":["../src/tomorrowos.ts"],"names":[],"mappings":"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"}
@@ -256,6 +256,7 @@ export class TomorrowOS extends EventEmitter {
256
256
  platform: meta?.platform,
257
257
  system: meta?.system,
258
258
  playerVersion: meta?.playerVersion,
259
+ systemVersion: meta?.systemVersion,
259
260
  ...(lastBootAt ? { lastBootAt } : {}),
260
261
  lastOnlineAt: this.isDeviceConnected(deviceId) ? now : undefined,
261
262
  lastOfflineAt: this.isDeviceConnected(deviceId) ? undefined : now
@@ -330,7 +331,6 @@ export class TomorrowOS extends EventEmitter {
330
331
  publishedPlaylists: assignments.map((a) => ({
331
332
  playlistId: a.playlistId,
332
333
  name: a.snapshot.name,
333
- version: a.publishedVersion,
334
334
  publishedAt: a.publishedAt,
335
335
  schedule: a.snapshot.schedule
336
336
  })),
@@ -339,6 +339,7 @@ export class TomorrowOS extends EventEmitter {
339
339
  platform: record.platform ?? null,
340
340
  system: record.system ?? null,
341
341
  playerVersion: record.playerVersion ?? null,
342
+ systemVersion: record.systemVersion ?? null,
342
343
  serialNumber: reg?.serialNumber ?? deviceId,
343
344
  pairedAt: record.pairedAt,
344
345
  lastBootAt: record.lastBootAt ?? null,
@@ -403,6 +404,7 @@ export class TomorrowOS extends EventEmitter {
403
404
  bootedAt: typeof msg.bootedAt === "string" ? msg.bootedAt : undefined,
404
405
  bootUptimeSec: bootUptimeSec ?? undefined,
405
406
  playerVersion: typeof msg.playerVersion === "string" ? msg.playerVersion : undefined,
407
+ systemVersion: typeof msg.systemVersion === "string" ? msg.systemVersion : undefined,
406
408
  serialNumber: typeof msg.serialNumber === "string" ? msg.serialNumber : deviceId
407
409
  });
408
410
  }
@@ -455,6 +457,8 @@ export class TomorrowOS extends EventEmitter {
455
457
  const system = normalizeDeviceSystemLabel(platform, typeof msg.system === "string" ? msg.system : existing.system) ?? existing.system;
456
458
  const playerVersion = (typeof msg.playerVersion === "string" ? msg.playerVersion : undefined) ??
457
459
  existing.playerVersion;
460
+ const systemVersion = (typeof msg.systemVersion === "string" ? msg.systemVersion : undefined) ??
461
+ existing.systemVersion;
458
462
  await this.store.setPairedDevice(deviceId, {
459
463
  ...existing,
460
464
  deviceName: (typeof msg.deviceName === "string" ? msg.deviceName : undefined) ??
@@ -462,6 +466,7 @@ export class TomorrowOS extends EventEmitter {
462
466
  platform,
463
467
  system,
464
468
  playerVersion,
469
+ systemVersion,
465
470
  ...(lastBootAt ? { lastBootAt } : {}),
466
471
  lastOnlineAt: now,
467
472
  lastOfflineAt: existing.lastOfflineAt
@@ -517,12 +522,16 @@ export class TomorrowOS extends EventEmitter {
517
522
  const firmware = typeof result.data.firmware === "string"
518
523
  ? result.data.firmware
519
524
  : undefined;
525
+ const systemVersion = typeof result.data.systemVersion === "string"
526
+ ? result.data.systemVersion
527
+ : undefined;
520
528
  const platform = normalizeDevicePlatform(existing.platform, existing.system);
521
529
  await this.store.setPairedDevice(deviceId, {
522
530
  ...existing,
523
531
  deviceName: model ?? existing.deviceName,
524
532
  system: formatDeviceSystemForFirmware(platform, firmware, existing.system),
525
- platform: platform ?? existing.platform
533
+ platform: platform ?? existing.platform,
534
+ systemVersion: systemVersion ?? existing.systemVersion
526
535
  });
527
536
  }
528
537
  catch {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tomorrowos/sdk",
3
- "version": "0.6.9",
3
+ "version": "0.7.1",
4
4
  "description": "TomorrowOS CMS server SDK - WebSocket transport, pairing, device commands, optional static CMS UI. Includes CLI (tomorrowos init / build) and starter templates.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "my-cms",
3
- "version": "0.6.9",
3
+ "version": "0.7.1",
4
4
  "description": "CMS server on @tomorrowos/sdk. Add your UI (React, static files, etc.) alongside this server.",
5
5
  "private": true,
6
6
  "type": "module",
@@ -10,7 +10,7 @@
10
10
  "build-player": "tomorrowos build --platform tizen"
11
11
  },
12
12
  "dependencies": {
13
- "@tomorrowos/sdk": "^0.6.9",
13
+ "@tomorrowos/sdk": "^0.7.1",
14
14
  "dotenv": "^17.2.3"
15
15
  },
16
16
  "devDependencies": {
@@ -988,6 +988,7 @@ function renderDeviceCards() {
988
988
  const rows = [
989
989
  ["Device ID", device.deviceId],
990
990
  ["System", device.system || device.platform || "—"],
991
+ ["System version", device.systemVersion || "—"],
991
992
  ["Player version", device.playerVersion || "—"],
992
993
  ["Device online", formatDeviceOnlineLabel(device)],
993
994
  ["Last boot", formatDateTimeSeconds(device.lastBootAt)],