@xiboplayer/sync 0.3.6 → 0.4.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.
Files changed (2) hide show
  1. package/package.json +4 -2
  2. package/src/sync-manager.js +21 -18
package/package.json CHANGED
@@ -1,13 +1,15 @@
1
1
  {
2
2
  "name": "@xiboplayer/sync",
3
- "version": "0.3.6",
3
+ "version": "0.4.0",
4
4
  "description": "Multi-display synchronization for Xibo Player",
5
5
  "type": "module",
6
6
  "main": "src/sync-manager.js",
7
7
  "exports": {
8
8
  ".": "./src/sync-manager.js"
9
9
  },
10
- "dependencies": {},
10
+ "dependencies": {
11
+ "@xiboplayer/utils": "0.4.0"
12
+ },
11
13
  "devDependencies": {
12
14
  "vitest": "^2.0.0"
13
15
  },
@@ -29,6 +29,8 @@
29
29
  * @property {boolean} isLead - Whether this display is the leader
30
30
  */
31
31
 
32
+ import { createLogger } from '@xiboplayer/utils';
33
+
32
34
  const CHANNEL_NAME = 'xibo-sync';
33
35
  const HEARTBEAT_INTERVAL = 5000; // Send heartbeat every 5s
34
36
  const FOLLOWER_TIMEOUT = 15000; // Consider follower offline after 15s silence
@@ -64,8 +66,9 @@ export class SyncManager {
64
66
  this._pendingLayoutId = null; // Layout we're waiting for readiness on
65
67
  this._started = false;
66
68
 
67
- // Log prefix for clarity in multi-tab console
69
+ // Logger with role prefix for clarity in multi-tab console
68
70
  this._tag = this.isLead ? '[Sync:LEAD]' : '[Sync:FOLLOW]';
71
+ this._log = createLogger(this.isLead ? 'Sync:LEAD' : 'Sync:FOLLOW');
69
72
  }
70
73
 
71
74
  /**
@@ -76,7 +79,7 @@ export class SyncManager {
76
79
  this._started = true;
77
80
 
78
81
  if (typeof BroadcastChannel === 'undefined') {
79
- console.warn(this._tag, 'BroadcastChannel not available — sync disabled');
82
+ this._log.warn( 'BroadcastChannel not available — sync disabled');
80
83
  return;
81
84
  }
82
85
 
@@ -92,7 +95,7 @@ export class SyncManager {
92
95
  this._cleanupTimer = setInterval(() => this._cleanupStaleFollowers(), HEARTBEAT_INTERVAL);
93
96
  }
94
97
 
95
- console.log(this._tag, 'Started. DisplayId:', this.displayId);
98
+ this._log.info( 'Started. DisplayId:', this.displayId);
96
99
  }
97
100
 
98
101
  /**
@@ -116,7 +119,7 @@ export class SyncManager {
116
119
  }
117
120
 
118
121
  this.followers.clear();
119
- console.log(this._tag, 'Stopped');
122
+ this._log.info( 'Stopped');
120
123
  }
121
124
 
122
125
  // ── Lead API ──────────────────────────────────────────────────────
@@ -130,7 +133,7 @@ export class SyncManager {
130
133
  */
131
134
  async requestLayoutChange(layoutId) {
132
135
  if (!this.isLead) {
133
- console.warn(this._tag, 'requestLayoutChange called on follower — ignoring');
136
+ this._log.warn( 'requestLayoutChange called on follower — ignoring');
134
137
  return;
135
138
  }
136
139
 
@@ -145,7 +148,7 @@ export class SyncManager {
145
148
 
146
149
  const showAt = Date.now() + this.switchDelay;
147
150
 
148
- console.log(this._tag, `Requesting layout change: ${layoutId} (show at ${new Date(showAt).toISOString()}, ${this.followers.size} followers)`);
151
+ this._log.info( `Requesting layout change: ${layoutId} (show at ${new Date(showAt).toISOString()}, ${this.followers.size} followers)`);
149
152
 
150
153
  // Broadcast layout-change to all followers
151
154
  this._send({
@@ -167,7 +170,7 @@ export class SyncManager {
167
170
  }
168
171
 
169
172
  // Send show signal
170
- console.log(this._tag, `Sending layout-show: ${layoutId}`);
173
+ this._log.info( `Sending layout-show: ${layoutId}`);
171
174
  this._send({
172
175
  type: 'layout-show',
173
176
  layoutId,
@@ -214,7 +217,7 @@ export class SyncManager {
214
217
  reportReady(layoutId) {
215
218
  layoutId = String(layoutId);
216
219
 
217
- console.log(this._tag, `Reporting ready for layout ${layoutId}`);
220
+ this._log.info( `Reporting ready for layout ${layoutId}`);
218
221
 
219
222
  this._send({
220
223
  type: 'layout-ready',
@@ -238,7 +241,7 @@ export class SyncManager {
238
241
  case 'layout-change':
239
242
  // Follower: lead is requesting a layout change
240
243
  if (!this.isLead) {
241
- console.log(this._tag, `Layout change requested: ${msg.layoutId}`);
244
+ this._log.info( `Layout change requested: ${msg.layoutId}`);
242
245
  this.onLayoutChange(msg.layoutId, msg.showAt);
243
246
  }
244
247
  break;
@@ -253,7 +256,7 @@ export class SyncManager {
253
256
  case 'layout-show':
254
257
  // Follower: lead says show now
255
258
  if (!this.isLead) {
256
- console.log(this._tag, `Layout show signal: ${msg.layoutId}`);
259
+ this._log.info( `Layout show signal: ${msg.layoutId}`);
257
260
  this.onLayoutShow(msg.layoutId);
258
261
  }
259
262
  break;
@@ -261,13 +264,13 @@ export class SyncManager {
261
264
  case 'video-start':
262
265
  // Follower: lead says start video
263
266
  if (!this.isLead) {
264
- console.log(this._tag, `Video start signal: ${msg.layoutId} region ${msg.regionId}`);
267
+ this._log.info( `Video start signal: ${msg.layoutId} region ${msg.regionId}`);
265
268
  this.onVideoStart(msg.layoutId, msg.regionId);
266
269
  }
267
270
  break;
268
271
 
269
272
  default:
270
- console.warn(this._tag, 'Unknown message type:', msg.type);
273
+ this._log.warn( 'Unknown message type:', msg.type);
271
274
  }
272
275
  }
273
276
 
@@ -284,7 +287,7 @@ export class SyncManager {
284
287
  readyLayoutId: null,
285
288
  role: msg.role || 'unknown',
286
289
  });
287
- console.log(this._tag, `Follower joined: ${msg.displayId} (${this.followers.size} total)`);
290
+ this._log.info( `Follower joined: ${msg.displayId} (${this.followers.size} total)`);
288
291
  }
289
292
  }
290
293
 
@@ -304,12 +307,12 @@ export class SyncManager {
304
307
  follower.lastSeen = Date.now();
305
308
  }
306
309
 
307
- console.log(this._tag, `Follower ${msg.displayId} ready for layout ${msg.layoutId}`);
310
+ this._log.info( `Follower ${msg.displayId} ready for layout ${msg.layoutId}`);
308
311
 
309
312
  // Check if all followers are now ready
310
313
  if (this._pendingLayoutId === msg.layoutId && this._readyResolve) {
311
314
  if (this._allFollowersReady(msg.layoutId)) {
312
- console.log(this._tag, 'All followers ready');
315
+ this._log.info( 'All followers ready');
313
316
  this._readyResolve();
314
317
  this._readyResolve = null;
315
318
  }
@@ -348,7 +351,7 @@ export class SyncManager {
348
351
  notReady.push(id);
349
352
  }
350
353
  }
351
- console.warn(this._tag, `Ready timeout — proceeding without: ${notReady.join(', ')}`);
354
+ this._log.warn( `Ready timeout — proceeding without: ${notReady.join(', ')}`);
352
355
  this._readyResolve = null;
353
356
  resolve();
354
357
  }
@@ -373,7 +376,7 @@ export class SyncManager {
373
376
  const now = Date.now();
374
377
  for (const [id, follower] of this.followers) {
375
378
  if (now - follower.lastSeen > FOLLOWER_TIMEOUT) {
376
- console.log(this._tag, `Removing stale follower: ${id} (last seen ${Math.round((now - follower.lastSeen) / 1000)}s ago)`);
379
+ this._log.info( `Removing stale follower: ${id} (last seen ${Math.round((now - follower.lastSeen) / 1000)}s ago)`);
377
380
  this.followers.delete(id);
378
381
  }
379
382
  }
@@ -385,7 +388,7 @@ export class SyncManager {
385
388
  try {
386
389
  this.channel.postMessage(msg);
387
390
  } catch (e) {
388
- console.error(this._tag, 'Failed to send:', e);
391
+ this._log.error( 'Failed to send:', e);
389
392
  }
390
393
  }
391
394