@xiboplayer/xmr 0.1.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 +170 -0
- package/docs/README.md +360 -0
- package/docs/XMR_COMMANDS.md +303 -0
- package/docs/XMR_TESTING.md +509 -0
- package/package.json +36 -0
- package/src/index.js +2 -0
- package/src/test-utils.js +132 -0
- package/src/xmr-wrapper.js +359 -0
- package/src/xmr-wrapper.test.js +737 -0
- package/vitest.config.js +35 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to @xiboplayer/xmr will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.9.0] - 2026-02-10
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Upgraded to @xibosignage/xibo-communication-framework@0.0.6**
|
|
13
|
+
- Latest XMR library with improved stability
|
|
14
|
+
- Better WebSocket connection handling
|
|
15
|
+
|
|
16
|
+
- **New Commands**
|
|
17
|
+
- `criteriaUpdate`: Updates display criteria and triggers re-collection
|
|
18
|
+
- `currentGeoLocation`: Reports geographic location to CMS
|
|
19
|
+
|
|
20
|
+
- **Intentional Shutdown Flag**
|
|
21
|
+
- Prevents automatic reconnection when `stop()` is called
|
|
22
|
+
- Distinguishes between network errors and intentional disconnects
|
|
23
|
+
- Cleaner shutdown behavior
|
|
24
|
+
|
|
25
|
+
- **Comprehensive Test Suite**
|
|
26
|
+
- 48 test cases covering all functionality
|
|
27
|
+
- Constructor and initialization tests
|
|
28
|
+
- Connection lifecycle tests (start, stop, reconnect)
|
|
29
|
+
- All 7 CMS command tests with error handling
|
|
30
|
+
- Reconnection logic with exponential backoff
|
|
31
|
+
- Memory management and cleanup tests
|
|
32
|
+
- Edge cases (simultaneous commands, rapid cycles)
|
|
33
|
+
|
|
34
|
+
- **Complete Documentation**
|
|
35
|
+
- Updated README.md with full API reference
|
|
36
|
+
- XMR_COMMANDS.md: Complete command reference
|
|
37
|
+
- XMR_TESTING.md: Comprehensive testing guide
|
|
38
|
+
- Usage examples and troubleshooting
|
|
39
|
+
|
|
40
|
+
- **Test Utilities**
|
|
41
|
+
- test-utils.js with mock helpers
|
|
42
|
+
- createSpy(), createMockPlayer(), createMockConfig()
|
|
43
|
+
- waitFor() and wait() async helpers
|
|
44
|
+
|
|
45
|
+
- **Vitest Configuration**
|
|
46
|
+
- vitest.config.js for package-specific settings
|
|
47
|
+
- Node environment (no DOM needed)
|
|
48
|
+
- Coverage thresholds (80% lines, functions, statements)
|
|
49
|
+
|
|
50
|
+
### Changed
|
|
51
|
+
|
|
52
|
+
- **Command Handler Documentation**
|
|
53
|
+
- Updated header comments with all supported commands
|
|
54
|
+
- Listed both `screenShot` and `screenshot` aliases
|
|
55
|
+
- Documented new v0.0.6 commands
|
|
56
|
+
|
|
57
|
+
- **Error Handling**
|
|
58
|
+
- All commands now have graceful error handling
|
|
59
|
+
- Errors logged but don't crash player
|
|
60
|
+
- Connection state preserved across command failures
|
|
61
|
+
|
|
62
|
+
### Fixed
|
|
63
|
+
|
|
64
|
+
- **Reconnection on Stop**
|
|
65
|
+
- Fixed issue where `stop()` would trigger reconnection
|
|
66
|
+
- Added `intentionalShutdown` flag to prevent unwanted reconnects
|
|
67
|
+
- Proper cleanup of reconnection timers on stop
|
|
68
|
+
|
|
69
|
+
- **Memory Leaks**
|
|
70
|
+
- Ensured timers are cleared on stop
|
|
71
|
+
- Proper event listener management
|
|
72
|
+
- Garbage collection-friendly shutdown
|
|
73
|
+
|
|
74
|
+
## [0.8.0] - 2025-XX-XX
|
|
75
|
+
|
|
76
|
+
### Initial Implementation
|
|
77
|
+
|
|
78
|
+
- Basic XMR wrapper for @xibosignage/xibo-communication-framework
|
|
79
|
+
- Core commands: collectNow, screenShot, changeLayout, licenceCheck, rekey
|
|
80
|
+
- Automatic reconnection with exponential backoff
|
|
81
|
+
- Connection lifecycle management
|
|
82
|
+
- Event-based command handling
|
|
83
|
+
|
|
84
|
+
## Upgrade Guide
|
|
85
|
+
|
|
86
|
+
### From 0.8.x to 0.9.0
|
|
87
|
+
|
|
88
|
+
**No breaking changes.** This is a feature release with new commands and improvements.
|
|
89
|
+
|
|
90
|
+
1. **Update dependency**:
|
|
91
|
+
```bash
|
|
92
|
+
npm install @xiboplayer/xmr@0.9.0
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
2. **Optional: Implement new commands**:
|
|
96
|
+
```javascript
|
|
97
|
+
// Add to your player class (optional)
|
|
98
|
+
async reportGeoLocation(data) {
|
|
99
|
+
// Your implementation
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
3. **Enjoy new features**:
|
|
104
|
+
- `criteriaUpdate` works automatically (triggers collect)
|
|
105
|
+
- `currentGeoLocation` logs warning if not implemented
|
|
106
|
+
- Better shutdown behavior (no reconnect loops)
|
|
107
|
+
|
|
108
|
+
## Testing
|
|
109
|
+
|
|
110
|
+
Run the test suite to verify the upgrade:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
cd packages/xmr
|
|
114
|
+
npm test
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
All 48 tests should pass.
|
|
118
|
+
|
|
119
|
+
## Migration Notes
|
|
120
|
+
|
|
121
|
+
### No Breaking Changes
|
|
122
|
+
|
|
123
|
+
The v0.9.0 release is fully backward compatible with v0.8.x. All existing code will continue to work without modification.
|
|
124
|
+
|
|
125
|
+
### New Optional Features
|
|
126
|
+
|
|
127
|
+
If you want to use the new commands:
|
|
128
|
+
|
|
129
|
+
1. **criteriaUpdate**: No action needed, works automatically
|
|
130
|
+
2. **currentGeoLocation**: Implement `player.reportGeoLocation(data)` method
|
|
131
|
+
|
|
132
|
+
### Improved Behavior
|
|
133
|
+
|
|
134
|
+
The intentional shutdown flag improves shutdown behavior:
|
|
135
|
+
|
|
136
|
+
**Before (v0.8.x)**:
|
|
137
|
+
```javascript
|
|
138
|
+
await xmr.stop(); // Would trigger reconnection!
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**After (v0.9.0)**:
|
|
142
|
+
```javascript
|
|
143
|
+
await xmr.stop(); // Clean shutdown, no reconnection
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Dependencies
|
|
147
|
+
|
|
148
|
+
### Updated
|
|
149
|
+
|
|
150
|
+
- `@xibosignage/xibo-communication-framework`: ^0.0.5 → ^0.0.6
|
|
151
|
+
|
|
152
|
+
### Added
|
|
153
|
+
|
|
154
|
+
- `vitest`: ^2.0.0 (dev dependency)
|
|
155
|
+
|
|
156
|
+
### Unchanged
|
|
157
|
+
|
|
158
|
+
- `@xiboplayer/utils`: file:../utils
|
|
159
|
+
|
|
160
|
+
## Support
|
|
161
|
+
|
|
162
|
+
- **Documentation**: [docs/README.md](./docs/README.md)
|
|
163
|
+
- **GitHub Issues**: https://github.com/xibo/xibo-players/issues
|
|
164
|
+
- **Community**: https://community.xibo.org.uk
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
[Unreleased]: https://github.com/xibo/xibo-players/compare/v0.9.0...HEAD
|
|
169
|
+
[0.9.0]: https://github.com/xibo/xibo-players/releases/tag/v0.9.0
|
|
170
|
+
[0.8.0]: https://github.com/xibo/xibo-players/releases/tag/v0.8.0
|
package/docs/README.md
ADDED
|
@@ -0,0 +1,360 @@
|
|
|
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
|