@yume-chan/adb
Version:
TypeScript implementation of Android Debug Bridge (ADB) protocol.
128 lines • 4.27 kB
JavaScript
import { EventEmitter, StickyEventEmitter } from "@yume-chan/event";
import { Ref } from "../utils/index.js";
import { AdbServerClient } from "./client.js";
export function unorderedRemove(array, index) {
if (index < 0 || index >= array.length) {
return;
}
array[index] = array[array.length - 1];
array.length -= 1;
}
export class AdbServerDeviceObserverOwner {
current = [];
constructor(client) {
this.
}
async
const response = await stream.readString();
const next = AdbServerClient.parseDeviceList(response);
const removed = this.current.slice();
const added = [];
for (const nextDevice of next) {
const index = removed.findIndex((device) => device.transportId === nextDevice.transportId);
if (index === -1) {
added.push(nextDevice);
continue;
}
unorderedRemove(removed, index);
}
this.current = next;
if (added.length) {
for (const observer of this.
observer.onDeviceAdd.fire(added);
}
}
if (removed.length) {
for (const observer of this.
observer.onDeviceRemove.fire(removed);
}
}
for (const observer of this.
observer.onListChange.fire(this.current);
}
}
async
try {
while (true) {
await this.
}
}
catch (e) {
this.
for (const observer of this.
observer.onError.fire(e);
}
}
}
async
const stream = await this.
// Each individual observer will ref depending on their options
{ unref: true });
// Set `current` and `onListChange` value before returning
await this.
// Then start receive loop
void this.
return stream;
}
async
if (this.
this.
await stream.dispose();
}
}
async createObserver(options) {
options?.signal?.throwIfAborted();
const onDeviceAdd = new EventEmitter();
const onDeviceRemove = new EventEmitter();
const onListChange = new StickyEventEmitter();
const onError = new StickyEventEmitter();
const observer = { onDeviceAdd, onDeviceRemove, onListChange, onError };
// Register `observer` before `#connect`.
// So `#handleObserverStop` knows if there is any observer.
this.
let stream;
if (!this.
this.
try {
stream = await this.
}
catch (e) {
this.
throw e;
}
}
else {
stream = await this.
onListChange.fire(this.current);
}
const ref = new Ref(options);
const stop = async () => {
unorderedRemove(this.
await this.
ref.unref();
};
if (options?.signal) {
if (options.signal.aborted) {
await stop();
throw options.signal.reason;
}
options.signal.addEventListener("abort", () => void stop());
}
// eslint-disable-next-line @typescript-eslint/no-this-alias
const _this = this;
return {
onDeviceAdd: onDeviceAdd.event,
onDeviceRemove: onDeviceRemove.event,
onListChange: onListChange.event,
onError: onError.event,
get current() {
return _this.current;
},
stop,
};
}
}
//# sourceMappingURL=observer.js.map