blob: 548e42b73b52694a0b420875524aafba428b2868 [file] [log] [blame]
Leo Repp58b9f112021-11-22 11:57:47 +01001import events from 'events';
2import WebSocket from 'faye-websocket';
3import objectAssign from 'object-assign';
4
5const debug = require('debug')('tinylr:client');
6
7let idCounter = 0;
8
9export default class Client extends events.EventEmitter {
10
11 constructor (req, socket, head, options = {}) {
12 super();
13 this.options = options;
14 this.ws = new WebSocket(req, socket, head);
15 this.ws.onmessage = this.message.bind(this);
16 this.ws.onclose = this.close.bind(this);
17 this.id = this.uniqueId('ws');
18 }
19
20 message (event) {
21 let data = this.data(event);
22 if (this[data.command]) return this[data.command](data);
23 }
24
25 close (event) {
26 if (this.ws) {
27 this.ws.close();
28 this.ws = null;
29 }
30
31 this.emit('end', event);
32 }
33
34 // Commands
35 hello () {
36 this.send({
37 command: 'hello',
38 protocols: [
39 'http://livereload.com/protocols/official-7'
40 ],
41 serverName: 'tiny-lr'
42 });
43 }
44
45 info (data) {
46 if (data) {
47 debug('Info', data);
48 this.emit('info', objectAssign({}, data, { id: this.id }));
49 this.plugins = data.plugins;
50 this.url = data.url;
51 }
52
53 return objectAssign({}, data || {}, { id: this.id, url: this.url });
54 }
55
56 // Server commands
57 reload (files) {
58 files.forEach(function (file) {
59 this.send({
60 command: 'reload',
61 path: file,
62 liveCSS: this.options.liveCSS !== false,
63 reloadMissingCSS: this.options.reloadMissingCSS !== false,
64 liveImg: this.options.liveImg !== false
65 });
66 }, this);
67 }
68
69 alert (message) {
70 this.send({
71 command: 'alert',
72 message: message
73 });
74 }
75
76 // Utilities
77 data (event) {
78 let data = {};
79 try {
80 data = JSON.parse(event.data);
81 } catch (e) {}
82 return data;
83 }
84
85 send (data) {
86 if (!this.ws) return;
87 this.ws.send(JSON.stringify(data));
88 }
89
90 uniqueId (prefix) {
91 let id = idCounter++;
92 return prefix ? prefix + id : id;
93 }
94}