@xiboplayer/xmr 0.1.3 → 0.3.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.
package/CHANGELOG.md CHANGED
@@ -159,7 +159,7 @@ await xmr.stop(); // Clean shutdown, no reconnection
159
159
 
160
160
  ## Support
161
161
 
162
- - **Documentation**: [docs/README.md](./docs/README.md)
162
+ - **Documentation**: [README.md](./README.md)
163
163
  - **GitHub Issues**: https://github.com/xibo/xibo-players/issues
164
164
  - **Community**: https://community.xibo.org.uk
165
165
 
package/README.md ADDED
@@ -0,0 +1,48 @@
1
+ # @xiboplayer/xmr
2
+
3
+ **XMR WebSocket client for real-time Xibo CMS commands.**
4
+
5
+ ## Overview
6
+
7
+ Listens for push commands from the CMS over WebSocket with automatic reconnection:
8
+
9
+ - **collectNow** — trigger an immediate collection cycle
10
+ - **screenshot** — request a display screenshot
11
+ - **changeLayout** — switch to a specific layout
12
+ - **overlayLayout** — show an overlay layout
13
+ - **revertToSchedule** — return to the scheduled playlist
14
+ - **purgeAll** — clear all cached content
15
+ - **dataUpdate** — notify of updated widget data
16
+ - **triggerWebhook** — fire a webhook action
17
+ - **commandAction** — execute a shell command
18
+ - **criteriaUpdate** — update geo/criteria filters
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ npm install @xiboplayer/xmr
24
+ ```
25
+
26
+ ## Usage
27
+
28
+ ```javascript
29
+ import { XmrClient } from '@xiboplayer/xmr';
30
+
31
+ const xmr = new XmrClient({
32
+ wsUrl: 'wss://your-cms.example.com/xmr',
33
+ channel: 'display-channel-key',
34
+ rsaKey: 'display-rsa-key',
35
+ });
36
+
37
+ xmr.on('collectNow', () => player.collect());
38
+ xmr.on('screenshot', () => captureScreenshot());
39
+ xmr.connect();
40
+ ```
41
+
42
+ ## Dependencies
43
+
44
+ - `@xiboplayer/utils` — logger, events
45
+
46
+ ---
47
+
48
+ **Part of the [XiboPlayer SDK](https://github.com/linuxnow/xiboplayer)**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xiboplayer/xmr",
3
- "version": "0.1.3",
3
+ "version": "0.3.0",
4
4
  "description": "XMR WebSocket client for real-time Xibo CMS commands",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -9,7 +9,7 @@
9
9
  },
10
10
  "dependencies": {
11
11
  "@xibosignage/xibo-communication-framework": "^0.0.6",
12
- "@xiboplayer/utils": "0.1.3"
12
+ "@xiboplayer/utils": "0.3.0"
13
13
  },
14
14
  "devDependencies": {
15
15
  "vitest": "^2.0.0"
package/src/index.js CHANGED
@@ -1,2 +1,4 @@
1
1
  // @xiboplayer/xmr - XMR WebSocket client
2
+ import pkg from '../package.json' with { type: 'json' };
3
+ export const VERSION = pkg.version;
2
4
  export { XmrWrapper } from './xmr-wrapper.js';
package/docs/README.md DELETED
@@ -1,360 +0,0 @@
1
- # @xiboplayer/xmr Documentation
2
-
3
- **XMR (Xibo Message Relay) WebSocket client for real-time CMS commands.**
4
-
5
- ## Overview
6
-
7
- The XMR package provides WebSocket integration with Xibo CMS, enabling real-time push commands from CMS to player without polling.
8
-
9
- ### Key Features
10
-
11
- - **Real-time commands**: Instant content updates via WebSocket
12
- - **Automatic reconnection**: Exponential backoff with max 10 attempts
13
- - **Connection management**: Handles disconnects, errors, and network issues
14
- - **7 CMS commands**: collectNow, screenShot, changeLayout, criteriaUpdate, and more
15
- - **Event-driven**: Clean event-based API for command handling
16
- - **Memory efficient**: Proper cleanup of timers and event listeners
17
- - **Production ready**: Comprehensive test suite with 48 test cases
18
-
19
- ## Installation
20
-
21
- ```bash
22
- npm install @xiboplayer/xmr
23
- ```
24
-
25
- ## Quick Start
26
-
27
- ```javascript
28
- import { XmrWrapper } from '@xiboplayer/xmr';
29
-
30
- // Create wrapper
31
- const config = {
32
- cmsAddress: 'https://cms.example.com',
33
- hardwareKey: 'player-hw-key-123',
34
- xmrChannel: 'player-channel' // Optional, defaults to player-{hardwareKey}
35
- };
36
-
37
- const player = {
38
- collect: async () => { /* ... */ },
39
- captureScreenshot: async () => { /* ... */ },
40
- changeLayout: async (layoutId) => { /* ... */ },
41
- reportGeoLocation: async (data) => { /* ... */ },
42
- updateStatus: (status) => { /* ... */ }
43
- };
44
-
45
- const xmr = new XmrWrapper(config, player);
46
-
47
- // Start connection
48
- const connected = await xmr.start('wss://cms.example.com:9505', 'cms-key-123');
49
-
50
- if (connected) {
51
- console.log('XMR connected');
52
- }
53
-
54
- // Check connection status
55
- if (xmr.isConnected()) {
56
- console.log('Currently connected');
57
- }
58
-
59
- // Stop connection
60
- await xmr.stop();
61
- ```
62
-
63
- ## Supported Commands
64
-
65
- ### Core Commands
66
-
67
- | Command | Description | Player Method |
68
- |---------|-------------|---------------|
69
- | `collectNow` | Force immediate XMDS sync | `player.collect()` |
70
- | `screenShot` | Capture screenshot | `player.captureScreenshot()` |
71
- | `changeLayout` | Switch to specific layout | `player.changeLayout(layoutId)` |
72
- | `licenceCheck` | Validate license (no-op for Linux) | None |
73
- | `rekey` | Rotate RSA keys | None (future) |
74
-
75
- ### New in v0.0.6
76
-
77
- | Command | Description | Player Method |
78
- |---------|-------------|---------------|
79
- | `criteriaUpdate` | Update display criteria | `player.collect()` |
80
- | `currentGeoLocation` | Report geo location | `player.reportGeoLocation(data)` |
81
-
82
- See [XMR_COMMANDS.md](./XMR_COMMANDS.md) for complete command reference.
83
-
84
- ## Connection Lifecycle
85
-
86
- ```
87
- ┌──────────┐
88
- │ start() │
89
- └─────┬────┘
90
-
91
-
92
- ┌──────────┐
93
- ┌─────│Connected │◄─────┐
94
- │ └─────┬────┘ │
95
- │ │ │
96
- Network │ │Commands │Auto
97
- Error │ │Flowing │Reconnect
98
- │ │ │
99
- ▼ ▼ │
100
- ┌──────────┐ ┌──────────┐
101
- │Disconnect│────────────│Reconnect │
102
- └─────┬────┘ Backoff └──────────┘
103
-
104
- │stop()
105
-
106
- ┌──────────┐
107
- │ Stopped │
108
- └──────────┘
109
- ```
110
-
111
- ### Reconnection Logic
112
-
113
- - **Exponential backoff**: 5s, 10s, 15s, 20s, 25s, 30s, 35s, 40s, 45s, 50s
114
- - **Max attempts**: 10 (then waits for next collection cycle)
115
- - **Intentional shutdown**: No reconnect when `stop()` is called
116
- - **Connection events**: `connected`, `disconnected`, `error`
117
-
118
- ## API Reference
119
-
120
- ### XmrWrapper
121
-
122
- #### Constructor
123
-
124
- ```javascript
125
- new XmrWrapper(config, player)
126
- ```
127
-
128
- **Parameters**:
129
- - `config` (Object): Player configuration
130
- - `hardwareKey` (string): Player hardware key
131
- - `xmrChannel` (string, optional): Custom channel ID
132
- - `player` (Object): Player instance with command handlers
133
-
134
- #### Methods
135
-
136
- ##### start(xmrUrl, cmsKey)
137
-
138
- Start XMR connection.
139
-
140
- ```javascript
141
- await xmr.start('wss://cms.example.com:9505', 'cms-key-123');
142
- ```
143
-
144
- **Returns**: `Promise<boolean>` - True if connected, false if failed
145
-
146
- ##### stop()
147
-
148
- Stop XMR connection and cancel reconnection.
149
-
150
- ```javascript
151
- await xmr.stop();
152
- ```
153
-
154
- ##### isConnected()
155
-
156
- Check connection status.
157
-
158
- ```javascript
159
- const connected = xmr.isConnected();
160
- ```
161
-
162
- **Returns**: `boolean`
163
-
164
- ##### send(action, data)
165
-
166
- Send message to CMS (for future features).
167
-
168
- ```javascript
169
- await xmr.send('customAction', { key: 'value' });
170
- ```
171
-
172
- **Returns**: `Promise<boolean>` - True if sent successfully
173
-
174
- ### Player Interface
175
-
176
- Your player object should implement these methods:
177
-
178
- ```javascript
179
- {
180
- // Required
181
- collect: async () => Promise<void>,
182
- captureScreenshot: async () => Promise<void>,
183
- changeLayout: async (layoutId) => Promise<void>,
184
-
185
- // Optional
186
- reportGeoLocation: async (data) => Promise<void>,
187
- updateStatus: (status) => void
188
- }
189
- ```
190
-
191
- ## Testing
192
-
193
- ### Run Tests
194
-
195
- ```bash
196
- # Run all tests
197
- npm test
198
-
199
- # Watch mode
200
- npm run test:watch
201
-
202
- # Coverage report
203
- npm run test:coverage
204
- ```
205
-
206
- ### Test Coverage
207
-
208
- - ✅ 48 test cases
209
- - ✅ Constructor and initialization
210
- - ✅ Connection lifecycle (start, stop, reconnect)
211
- - ✅ All 7 CMS commands
212
- - ✅ Error handling and edge cases
213
- - ✅ Memory management and cleanup
214
-
215
- See [XMR_TESTING.md](./XMR_TESTING.md) for comprehensive testing guide.
216
-
217
- ## Configuration
218
-
219
- ### From registerDisplay
220
-
221
- XMR settings are typically received from CMS `registerDisplay` response:
222
-
223
- ```json
224
- {
225
- "settings": {
226
- "xmrWebSocketAddress": "wss://cms.example.com:9505",
227
- "xmrCmsKey": "abcdef123456",
228
- "xmrChannel": "player-hw-key-123"
229
- }
230
- }
231
- ```
232
-
233
- Use these values with `start()`:
234
-
235
- ```javascript
236
- const { xmrWebSocketAddress, xmrCmsKey } = settings;
237
- await xmr.start(xmrWebSocketAddress, xmrCmsKey);
238
- ```
239
-
240
- ### Custom Channel
241
-
242
- Override default channel (player-{hardwareKey}):
243
-
244
- ```javascript
245
- const config = {
246
- hardwareKey: 'hw-123',
247
- xmrChannel: 'custom-channel-name' // Use this instead
248
- };
249
- ```
250
-
251
- ## Error Handling
252
-
253
- All command handlers include error handling:
254
-
255
- ```javascript
256
- this.xmr.on('collectNow', async () => {
257
- console.log('[XMR] Received collectNow command');
258
- try {
259
- await this.player.collect();
260
- console.log('[XMR] collectNow completed successfully');
261
- } catch (error) {
262
- console.error('[XMR] collectNow failed:', error);
263
- }
264
- });
265
- ```
266
-
267
- Errors don't:
268
- - ❌ Crash the player
269
- - ❌ Disconnect XMR
270
- - ❌ Prevent other commands
271
-
272
- They do:
273
- - ✅ Log to console
274
- - ✅ Preserve connection state
275
- - ✅ Continue processing other commands
276
-
277
- ## Troubleshooting
278
-
279
- ### Connection Issues
280
-
281
- **Problem**: XMR won't connect
282
-
283
- **Solution**:
284
- 1. Verify XMR enabled in CMS settings
285
- 2. Check firewall allows port 9505
286
- 3. Verify `xmrWebSocketAddress` from registerDisplay
287
- 4. Check browser console for errors
288
-
289
- ### Commands Not Executing
290
-
291
- **Problem**: collectNow sent but nothing happens
292
-
293
- **Solution**:
294
- 1. Check `xmr.isConnected()` returns true
295
- 2. Verify player methods exist (`player.collect`, etc.)
296
- 3. Check console for command reception logs
297
- 4. Look for errors in command handler
298
-
299
- ### Reconnection Loops
300
-
301
- **Problem**: Keeps reconnecting forever
302
-
303
- **Solution**:
304
- 1. Verify XMR server is running
305
- 2. Check cmsKey is correct
306
- 3. Monitor `reconnectAttempts` counter
307
- 4. Manually stop: `await xmr.stop()`
308
-
309
- See [XMR_TESTING.md](./XMR_TESTING.md#troubleshooting) for more.
310
-
311
- ## Dependencies
312
-
313
- - `@xibosignage/xibo-communication-framework@^0.0.6` - Official XMR library
314
- - `@xiboplayer/utils` - Logging and utilities
315
-
316
- ## Version History
317
-
318
- ### v0.9.0 (Current)
319
- - ✅ Upgraded to @xibosignage/xibo-communication-framework@0.0.6
320
- - ✅ Added `criteriaUpdate` command
321
- - ✅ Added `currentGeoLocation` command
322
- - ✅ Intentional shutdown flag (no reconnect on stop)
323
- - ✅ Comprehensive test suite (48 tests)
324
- - ✅ Complete documentation
325
-
326
- ### Previous Versions
327
- - Basic XMR integration
328
- - Core commands (collectNow, screenShot, changeLayout)
329
- - Automatic reconnection
330
-
331
- ## Contributing
332
-
333
- When adding new XMR commands:
334
-
335
- 1. Add event handler in `setupEventHandlers()`
336
- 2. Update [XMR_COMMANDS.md](./XMR_COMMANDS.md)
337
- 3. Add tests in `xmr-wrapper.test.js`
338
- 4. Implement player method if needed
339
-
340
- See [XMR_TESTING.md](./XMR_TESTING.md#adding-new-commands) for details.
341
-
342
- ## Related Packages
343
-
344
- - [@xiboplayer/core](../../core/docs/) - Player core orchestration
345
- - [@xiboplayer/xmds](../../xmds/docs/) - XMDS SOAP client
346
- - [@xiboplayer/schedule](../../schedule/docs/) - Schedule engine
347
-
348
- ## Support
349
-
350
- - **GitHub Issues**: https://github.com/xibo/xibo-players/issues
351
- - **Documentation**: [XMR_COMMANDS.md](./XMR_COMMANDS.md), [XMR_TESTING.md](./XMR_TESTING.md)
352
- - **Xibo Community**: https://community.xibo.org.uk
353
-
354
- ---
355
-
356
- **Package Version**: 0.9.0 | **XMR Library**: 0.0.6
357
-
358
- ## License
359
-
360
- AGPL-3.0-or-later