@u4/adbkit
Version:
A Typescript client for the Android Debug Bridge.
116 lines • 3.96 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const errors_1 = require("./errors");
const events_1 = __importDefault(require("events"));
/**
* emit event on Device status chage
*/
class Tracker extends events_1.default {
constructor(command) {
super();
this.command = command;
this.deviceMap = new Map();
this.stoped = false;
this.on = (event, listener) => {
// never miss past events
if (event === 'add') {
for (const device of this.deviceMap.values())
listener(device);
}
else if (event === 'online') {
for (const device of this.deviceMap.values())
if (device.type !== 'offline')
listener(device);
}
else if (event === 'offline') {
for (const device of this.deviceMap.values())
if (device.type === 'offline')
listener(device);
}
super.on(event, listener);
return this;
};
this.off = (event, listener) => super.off(event, listener);
this.once = (event, listener) => super.once(event, listener);
this.emit = (event, ...args) => super.emit(event, ...args);
this.readloop();
}
async readloop() {
try {
for (;;) {
const list = await this.command._readDevices();
this.update(list);
}
}
catch (err) {
if (!this.stoped) {
this.emit('error', err);
if (err instanceof errors_1.AdbPrematureEOFError) {
throw new Error('Connection closed');
}
}
}
finally {
this.command.parser.end().catch(() => { });
this.emit('end');
}
}
/**
* should be private but need public for testing
* @param newList updated Device list
* @returns this
*/
update(newList) {
let changeSet;
if (this.listenerCount('changeSet'))
changeSet = { removed: [], changed: [], added: [] };
const newMap = new Map();
for (const device of newList) {
newMap.set(device.id, device);
const oldDevice = this.deviceMap.get(device.id);
if (oldDevice) {
this.deviceMap.delete(device.id);
if (oldDevice.type !== device.type) {
if (changeSet)
changeSet.changed.push(device);
this.emit('change', device, oldDevice);
if (device.type === 'offline')
this.emit('offline', device);
else
this.emit('online', device);
}
}
else {
if (changeSet)
changeSet.added.push(device);
this.emit('add', device);
if (device.type === 'offline') {
this.emit('offline', device);
}
else {
this.emit('online', device);
}
}
}
for (const device of this.deviceMap.values()) {
if (changeSet)
changeSet.removed.push(device);
this.emit('remove', device);
if (device.type !== 'offline')
this.emit('offline', device);
}
if (changeSet)
this.emit('changeSet', changeSet);
this.deviceMap = newMap;
return this;
}
end() {
this.stoped = true;
this.command.parser.end().catch(() => { });
}
}
exports.default = Tracker;
//# sourceMappingURL=tracker.js.map