UNPKG

2.6 kBJavaScriptView Raw
1let PROTOCOL_6, PROTOCOL_7;
2exports.PROTOCOL_6 = (PROTOCOL_6 = 'http://livereload.com/protocols/official-6');
3exports.PROTOCOL_7 = (PROTOCOL_7 = 'http://livereload.com/protocols/official-7');
4
5class ProtocolError {
6 constructor (reason, data) {
7 this.message = `LiveReload protocol error (${reason}) after receiving data: "${data}".`;
8 }
9};
10
11class Parser {
12 constructor (handlers) {
13 this.handlers = handlers;
14 this.reset();
15 }
16
17 reset () {
18 this.protocol = null;
19 }
20
21 process (data) {
22 try {
23 let message;
24
25 if (!this.protocol) {
26 if (data.match(new RegExp('^!!ver:([\\d.]+)$'))) {
27 this.protocol = 6;
28 } else if ((message = this._parseMessage(data, ['hello']))) {
29 if (!message.protocols.length) {
30 throw new ProtocolError('no protocols specified in handshake message');
31 } else if (Array.from(message.protocols).includes(PROTOCOL_7)) {
32 this.protocol = 7;
33 } else if (Array.from(message.protocols).includes(PROTOCOL_6)) {
34 this.protocol = 6;
35 } else {
36 throw new ProtocolError('no supported protocols found');
37 }
38 }
39
40 return this.handlers.connected(this.protocol);
41 }
42
43 if (this.protocol === 6) {
44 message = JSON.parse(data);
45
46 if (!message.length) {
47 throw new ProtocolError('protocol 6 messages must be arrays');
48 }
49
50 const [command, options] = Array.from(message);
51
52 if (command !== 'refresh') {
53 throw new ProtocolError('unknown protocol 6 command');
54 }
55
56 return this.handlers.message({
57 command: 'reload',
58 path: options.path,
59 liveCSS: options.apply_css_live != null ? options.apply_css_live : true
60 });
61 }
62
63 message = this._parseMessage(data, ['reload', 'alert']);
64
65 return this.handlers.message(message);
66 } catch (e) {
67 if (e instanceof ProtocolError) {
68 return this.handlers.error(e);
69 }
70
71 throw e;
72 }
73 }
74
75 _parseMessage (data, validCommands) {
76 let message;
77
78 try {
79 message = JSON.parse(data);
80 } catch (e) {
81 throw new ProtocolError('unparsable JSON', data);
82 }
83
84 if (!message.command) {
85 throw new ProtocolError('missing "command" key', data);
86 }
87
88 if (!validCommands.includes(message.command)) {
89 throw new ProtocolError(`invalid command '${message.command}', only valid commands are: ${validCommands.join(', ')})`, data);
90 }
91
92 return message;
93 }
94};
95
96exports.ProtocolError = ProtocolError;
97exports.Parser = Parser;