conductor/src/blitz.js

145 lines
2.9 KiB
JavaScript

class EventEmitter {
constructor() {
this.events = {};
}
on(event, listener) {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(listener);
}
emit(event, ...args) {
if (this.events[event]) {
this.events[event].forEach((listener) => listener(...args));
}
}
removeAllListeners() {
this.events = {};
}
}
// Convert Node.js module system to ES6 module system
export class NotConnectedError extends Error {
constructor(client) {
super("Client not connected");
this.client = client;
}
}
export const Polarity = {
Negative: 0,
Positive: 1,
};
export const Region = {
Unknown: 0,
Europe: 1,
Oceania: 2,
NorthAmerica: 3,
Asia: 4,
SouthAmerica: 5,
};
export class Client extends EventEmitter {
constructor(socketFactory) {
super();
this.socketFactory = socketFactory;
}
getSocket() {
return this.socket;
}
connect(url = this.generateRandomConnectionUrl()) {
const socket = (this.socket = this.socketFactory.make(url));
socket.onmessage = (event) => {
const rawData = this.decode(event.data);
this.emit("data", this.buildStrikeData(JSON.parse(rawData)));
};
socket.onopen = () => {
this.sendJSON({ a: 111 });
this.emit("connect", socket);
};
socket.onerror = (err) => this.emit("error", err);
}
close() {
if (!this.socket) {
throw new NotConnectedError(this);
}
this.socket.close();
this.removeAllListeners();
}
processRawLocation(location) {
return {
latitude: location.lat,
longitude: location.lon,
altitude: location.alt,
};
}
buildStrikeData(strike) {
return {
location: this.processRawLocation(strike),
deviation: strike.mds,
delay: strike.delay,
time: new Date(Math.floor(strike.time / 1e6)),
detectors: strike.sig.map((rawDec) => ({
id: rawDec.sta,
location: this.processRawLocation(rawDec),
status: rawDec.status,
delay: rawDec.time,
})),
polarity: strike.pol > 0 ? Polarity.Positive : Polarity.Negative,
maxDeviation: strike.mds,
maxCircularGap: strike.mcg,
region: strike.region,
};
}
decode(b) {
let a,
e = {},
d = b.split(""),
c = d[0],
f = c,
g = [c],
h = 256,
o = h;
for (let i = 1; i < d.length; i++) {
let charCode = d[i].charCodeAt(0);
a = h > charCode ? d[i] : e[charCode] ? e[charCode] : f + c;
g.push(a);
c = a.charAt(0);
e[o] = f + c;
o++;
f = a;
}
return g.join("");
}
sendJSON(data) {
this.socket.send(JSON.stringify(data));
}
generateRandomConnectionUrl() {
const knownServerIds = [1, 7, 8];
return `wss://ws${
knownServerIds[Math.floor(Math.random() * knownServerIds.length)]
}.blitzortung.org:443/`;
}
}
export class BrowserSocketFactory {
make(url) {
return new WebSocket(url);
}
}