jacdac-ts
Advanced tools
Comparing version 1.1.5 to 1.1.6
@@ -202,2 +202,3 @@ import { createContext } from 'react'; | ||
var RESTART = 'restart'; | ||
var CHANGE = 'change'; | ||
var DEVICE_CONNECT = 'deviceConnect'; | ||
@@ -207,2 +208,3 @@ var DEVICE_DISCONNECT = 'deviceDisconnect'; | ||
var DEVICE_RESTART = 'deviceRestart'; | ||
var DEVICE_CHANGE = 'deviceChange'; | ||
var PACKET_SEND = 'packetSend'; | ||
@@ -811,2 +813,3 @@ var PACKET_PROCESS = 'packetProcess'; | ||
}); | ||
//console.log(`${eventName}->${listeners.length}`) | ||
return this; | ||
@@ -821,9 +824,8 @@ }; | ||
var listener = listeners[i]; | ||
var handler_1 = listener.handler; | ||
if (handler_1 === handler_1) { | ||
listeners.splice(i, -1); | ||
if (handler === listener.handler) { | ||
listeners.splice(i, 1); | ||
--i; | ||
if (listeners.length == 0) | ||
delete this.listeners[eventName]; | ||
this.emit(REMOVE_LISTENER, eventName, handler_1); | ||
this.emit(REMOVE_LISTENER, eventName, handler); | ||
return this; | ||
@@ -854,3 +856,3 @@ } | ||
if (listener.once) { | ||
listeners.splice(i, -1); | ||
listeners.splice(i, 1); | ||
--i; | ||
@@ -883,4 +885,44 @@ } | ||
}; | ||
/** | ||
* Creates an observable from the given event | ||
* @param eventName | ||
*/ | ||
EventEmitter.prototype.observe = function (eventName) { | ||
return fromEvent(this, eventName); | ||
}; | ||
/** | ||
* Subscribbes to an event and returns the unsubscription handler | ||
* @param eventName | ||
* @param next | ||
*/ | ||
EventEmitter.prototype.subscribe = function (eventName, next) { | ||
var observer = this.observe(eventName); | ||
return observer.subscribe({ next: next }).unsubscribe; | ||
}; | ||
return EventEmitter; | ||
}()); | ||
var EventObservable = /** @class */ (function () { | ||
function EventObservable(eventEmitter, eventName) { | ||
this.eventEmitter = eventEmitter; | ||
this.eventName = eventName; | ||
} | ||
EventObservable.prototype.subscribe = function (observer) { | ||
var _this = this; | ||
//console.log(`on ${this.eventName}`) | ||
this.eventEmitter.on(this.eventName, observer.next); | ||
this.eventEmitter.on(ERROR, observer.error); | ||
// never completes | ||
return { | ||
unsubscribe: function () { | ||
//console.log(`off ${this.eventName}`) | ||
_this.eventEmitter.off(_this.eventName, observer.next); | ||
_this.eventEmitter.off(ERROR, observer.error); | ||
} | ||
}; | ||
}; | ||
return EventObservable; | ||
}()); | ||
function fromEvent(eventEmitter, eventName) { | ||
return new EventObservable(eventEmitter, eventName); | ||
} | ||
@@ -933,2 +975,5 @@ var Node = /** @class */ (function (_super) { | ||
}); | ||
Register.prototype.toString = function () { | ||
return this.id + " " + (this._data ? toHex(this._data) : ""); | ||
}; | ||
Register.prototype.processReport = function (pkt) { | ||
@@ -939,4 +984,6 @@ var updated = !bufferEq(this._data, pkt.data); | ||
this.emit(REPORT_RECEIVE, this); | ||
if (updated) | ||
if (updated) { | ||
this.emit(REPORT_UPDATE, this); | ||
this.emit(CHANGE); | ||
} | ||
}; | ||
@@ -975,2 +1022,5 @@ return Register; | ||
}); | ||
Service.prototype.toString = function () { | ||
return this.name + " " + this.id; | ||
}; | ||
Service.prototype.registerAt = function (address) { | ||
@@ -1132,2 +1182,3 @@ address = address | 0; | ||
Device.prototype.processAnnouncement = function (pkt) { | ||
var _a; | ||
var w0 = this.servicesData ? getNumber(this.servicesData, NumberFormat.UInt32LE, 0) : 0; | ||
@@ -1138,4 +1189,6 @@ var w1 = getNumber(pkt.data, NumberFormat.UInt32LE, 0); | ||
this.emit(RESTART); | ||
this.bus.emit(DEVICE_CHANGE, this); | ||
this.emit(CHANGE); | ||
} | ||
var servData = this.servicesData ? this.servicesData.slice(4) : null; | ||
var servData = (_a = this.servicesData) === null || _a === void 0 ? void 0 : _a.slice(4); | ||
if (!bufferEq(pkt.data.slice(4), servData)) { | ||
@@ -1150,2 +1203,4 @@ this.servicesData = pkt.data; | ||
this.emit(ANNOUNCE); | ||
this.bus.emit(DEVICE_CHANGE, this); | ||
this.emit(CHANGE); | ||
} | ||
@@ -1229,2 +1284,3 @@ }; | ||
} | ||
this.emit(CHANGE); | ||
} | ||
@@ -1239,2 +1295,5 @@ }; | ||
}); | ||
Bus.prototype.toString = function () { | ||
return this.id; | ||
}; | ||
Bus.prototype.node = function (id) { | ||
@@ -1255,2 +1314,3 @@ var _a, _b, _c; | ||
this._startTime = Date.now(); | ||
this.emit(CHANGE); | ||
}; | ||
@@ -1271,2 +1331,3 @@ Object.defineProperty(Bus.prototype, "timestamp", { | ||
this._minConsolePriority = priority; | ||
this.emit(CHANGE); | ||
} | ||
@@ -1284,5 +1345,5 @@ }, | ||
Bus.prototype.sendPacketAsync = function (p) { | ||
var _a; | ||
this.emit(PACKET_SEND, p); | ||
return ((_a = this.options) === null || _a === void 0 ? void 0 : _a.sendPacketAsync(p)) || Promise.resolve(); | ||
var spa = this.options.sendPacketAsync; | ||
return spa ? spa(p) : Promise.resolve(); | ||
}; | ||
@@ -1312,6 +1373,6 @@ Object.defineProperty(Bus.prototype, "connecting", { | ||
this.emit(ERROR, { context: context, exception: exception }); | ||
this.emit(CHANGE); | ||
}; | ||
Bus.prototype.connectAsync = function (userRequest) { | ||
Bus.prototype.connectAsync = function (background) { | ||
var _this = this; | ||
var _a; | ||
// already connected | ||
@@ -1329,3 +1390,3 @@ if (this.connectionState == BusState.Connected) | ||
this.setConnectionState(BusState.Connecting); | ||
var connectAsyncPromise = ((_a = this.options) === null || _a === void 0 ? void 0 : _a.connectAsync(userRequest)) || Promise.resolve(); | ||
var connectAsyncPromise = this.options.connectAsync ? this.options.connectAsync(background) : Promise.resolve(); | ||
this._connectPromise = connectAsyncPromise | ||
@@ -1357,13 +1418,7 @@ .then(function () { | ||
this.setConnectionState(BusState.Disconnecting); | ||
if (this._gcInterval) { | ||
clearInterval(this._gcInterval); | ||
this._gcInterval = undefined; | ||
} | ||
this._disconnectPromise = this._disconnectPromise | ||
.then(function () { var _a; return ((_a = _this.options) === null || _a === void 0 ? void 0 : _a.disconnectAsync()) || Promise.resolve(); }) | ||
.then(function () { return _this.options.disconnectAsync ? _this.options.disconnectAsync() : Promise.resolve(); }) | ||
.catch(function (e) { return _this.errorHandler(DISCONNECT, e); }) | ||
.finally(function () { | ||
_this._disconnectPromise = undefined; | ||
_this._devices.forEach(function (device) { return _this.disconnectDevice(device); }); | ||
_this._devices = []; | ||
_this.setConnectionState(BusState.Disconnected); | ||
@@ -1402,3 +1457,5 @@ }); | ||
this.emit(DEVICE_CONNECT, d); | ||
if (!this._gcInterval && this.connected) | ||
this.emit(DEVICE_CHANGE, d); | ||
this.emit(CHANGE); | ||
if (!this._gcInterval) | ||
this._gcInterval = setInterval(function () { return _this.gcDevices(); }, 2000); | ||
@@ -1418,2 +1475,9 @@ } | ||
} | ||
// stop cleanup if all gone | ||
if (!this._devices.length) { | ||
if (this._gcInterval) { | ||
clearInterval(this._gcInterval); | ||
this._gcInterval = undefined; | ||
} | ||
} | ||
}; | ||
@@ -1423,2 +1487,4 @@ Bus.prototype.disconnectDevice = function (dev) { | ||
this.emit(DEVICE_DISCONNECT, dev); | ||
this.emit(DEVICE_CHANGE, dev); | ||
this.emit(CHANGE); | ||
}; | ||
@@ -1425,0 +1491,0 @@ /** |
@@ -206,2 +206,3 @@ (function (global, factory) { | ||
var RESTART = 'restart'; | ||
var CHANGE = 'change'; | ||
var DEVICE_CONNECT = 'deviceConnect'; | ||
@@ -211,2 +212,3 @@ var DEVICE_DISCONNECT = 'deviceDisconnect'; | ||
var DEVICE_RESTART = 'deviceRestart'; | ||
var DEVICE_CHANGE = 'deviceChange'; | ||
var PACKET_SEND = 'packetSend'; | ||
@@ -815,2 +817,3 @@ var PACKET_PROCESS = 'packetProcess'; | ||
}); | ||
//console.log(`${eventName}->${listeners.length}`) | ||
return this; | ||
@@ -825,9 +828,8 @@ }; | ||
var listener = listeners[i]; | ||
var handler_1 = listener.handler; | ||
if (handler_1 === handler_1) { | ||
listeners.splice(i, -1); | ||
if (handler === listener.handler) { | ||
listeners.splice(i, 1); | ||
--i; | ||
if (listeners.length == 0) | ||
delete this.listeners[eventName]; | ||
this.emit(REMOVE_LISTENER, eventName, handler_1); | ||
this.emit(REMOVE_LISTENER, eventName, handler); | ||
return this; | ||
@@ -858,3 +860,3 @@ } | ||
if (listener.once) { | ||
listeners.splice(i, -1); | ||
listeners.splice(i, 1); | ||
--i; | ||
@@ -887,4 +889,44 @@ } | ||
}; | ||
/** | ||
* Creates an observable from the given event | ||
* @param eventName | ||
*/ | ||
EventEmitter.prototype.observe = function (eventName) { | ||
return fromEvent(this, eventName); | ||
}; | ||
/** | ||
* Subscribbes to an event and returns the unsubscription handler | ||
* @param eventName | ||
* @param next | ||
*/ | ||
EventEmitter.prototype.subscribe = function (eventName, next) { | ||
var observer = this.observe(eventName); | ||
return observer.subscribe({ next: next }).unsubscribe; | ||
}; | ||
return EventEmitter; | ||
}()); | ||
var EventObservable = /** @class */ (function () { | ||
function EventObservable(eventEmitter, eventName) { | ||
this.eventEmitter = eventEmitter; | ||
this.eventName = eventName; | ||
} | ||
EventObservable.prototype.subscribe = function (observer) { | ||
var _this = this; | ||
//console.log(`on ${this.eventName}`) | ||
this.eventEmitter.on(this.eventName, observer.next); | ||
this.eventEmitter.on(ERROR, observer.error); | ||
// never completes | ||
return { | ||
unsubscribe: function () { | ||
//console.log(`off ${this.eventName}`) | ||
_this.eventEmitter.off(_this.eventName, observer.next); | ||
_this.eventEmitter.off(ERROR, observer.error); | ||
} | ||
}; | ||
}; | ||
return EventObservable; | ||
}()); | ||
function fromEvent(eventEmitter, eventName) { | ||
return new EventObservable(eventEmitter, eventName); | ||
} | ||
@@ -937,2 +979,5 @@ var Node = /** @class */ (function (_super) { | ||
}); | ||
Register.prototype.toString = function () { | ||
return this.id + " " + (this._data ? toHex(this._data) : ""); | ||
}; | ||
Register.prototype.processReport = function (pkt) { | ||
@@ -943,4 +988,6 @@ var updated = !bufferEq(this._data, pkt.data); | ||
this.emit(REPORT_RECEIVE, this); | ||
if (updated) | ||
if (updated) { | ||
this.emit(REPORT_UPDATE, this); | ||
this.emit(CHANGE); | ||
} | ||
}; | ||
@@ -979,2 +1026,5 @@ return Register; | ||
}); | ||
Service.prototype.toString = function () { | ||
return this.name + " " + this.id; | ||
}; | ||
Service.prototype.registerAt = function (address) { | ||
@@ -1136,2 +1186,3 @@ address = address | 0; | ||
Device.prototype.processAnnouncement = function (pkt) { | ||
var _a; | ||
var w0 = this.servicesData ? getNumber(this.servicesData, NumberFormat.UInt32LE, 0) : 0; | ||
@@ -1142,4 +1193,6 @@ var w1 = getNumber(pkt.data, NumberFormat.UInt32LE, 0); | ||
this.emit(RESTART); | ||
this.bus.emit(DEVICE_CHANGE, this); | ||
this.emit(CHANGE); | ||
} | ||
var servData = this.servicesData ? this.servicesData.slice(4) : null; | ||
var servData = (_a = this.servicesData) === null || _a === void 0 ? void 0 : _a.slice(4); | ||
if (!bufferEq(pkt.data.slice(4), servData)) { | ||
@@ -1154,2 +1207,4 @@ this.servicesData = pkt.data; | ||
this.emit(ANNOUNCE); | ||
this.bus.emit(DEVICE_CHANGE, this); | ||
this.emit(CHANGE); | ||
} | ||
@@ -1233,2 +1288,3 @@ }; | ||
} | ||
this.emit(CHANGE); | ||
} | ||
@@ -1243,2 +1299,5 @@ }; | ||
}); | ||
Bus.prototype.toString = function () { | ||
return this.id; | ||
}; | ||
Bus.prototype.node = function (id) { | ||
@@ -1259,2 +1318,3 @@ var _a, _b, _c; | ||
this._startTime = Date.now(); | ||
this.emit(CHANGE); | ||
}; | ||
@@ -1275,2 +1335,3 @@ Object.defineProperty(Bus.prototype, "timestamp", { | ||
this._minConsolePriority = priority; | ||
this.emit(CHANGE); | ||
} | ||
@@ -1288,5 +1349,5 @@ }, | ||
Bus.prototype.sendPacketAsync = function (p) { | ||
var _a; | ||
this.emit(PACKET_SEND, p); | ||
return ((_a = this.options) === null || _a === void 0 ? void 0 : _a.sendPacketAsync(p)) || Promise.resolve(); | ||
var spa = this.options.sendPacketAsync; | ||
return spa ? spa(p) : Promise.resolve(); | ||
}; | ||
@@ -1316,6 +1377,6 @@ Object.defineProperty(Bus.prototype, "connecting", { | ||
this.emit(ERROR, { context: context, exception: exception }); | ||
this.emit(CHANGE); | ||
}; | ||
Bus.prototype.connectAsync = function (userRequest) { | ||
Bus.prototype.connectAsync = function (background) { | ||
var _this = this; | ||
var _a; | ||
// already connected | ||
@@ -1333,3 +1394,3 @@ if (this.connectionState == BusState.Connected) | ||
this.setConnectionState(BusState.Connecting); | ||
var connectAsyncPromise = ((_a = this.options) === null || _a === void 0 ? void 0 : _a.connectAsync(userRequest)) || Promise.resolve(); | ||
var connectAsyncPromise = this.options.connectAsync ? this.options.connectAsync(background) : Promise.resolve(); | ||
this._connectPromise = connectAsyncPromise | ||
@@ -1361,13 +1422,7 @@ .then(function () { | ||
this.setConnectionState(BusState.Disconnecting); | ||
if (this._gcInterval) { | ||
clearInterval(this._gcInterval); | ||
this._gcInterval = undefined; | ||
} | ||
this._disconnectPromise = this._disconnectPromise | ||
.then(function () { var _a; return ((_a = _this.options) === null || _a === void 0 ? void 0 : _a.disconnectAsync()) || Promise.resolve(); }) | ||
.then(function () { return _this.options.disconnectAsync ? _this.options.disconnectAsync() : Promise.resolve(); }) | ||
.catch(function (e) { return _this.errorHandler(DISCONNECT, e); }) | ||
.finally(function () { | ||
_this._disconnectPromise = undefined; | ||
_this._devices.forEach(function (device) { return _this.disconnectDevice(device); }); | ||
_this._devices = []; | ||
_this.setConnectionState(BusState.Disconnected); | ||
@@ -1406,3 +1461,5 @@ }); | ||
this.emit(DEVICE_CONNECT, d); | ||
if (!this._gcInterval && this.connected) | ||
this.emit(DEVICE_CHANGE, d); | ||
this.emit(CHANGE); | ||
if (!this._gcInterval) | ||
this._gcInterval = setInterval(function () { return _this.gcDevices(); }, 2000); | ||
@@ -1422,2 +1479,9 @@ } | ||
} | ||
// stop cleanup if all gone | ||
if (!this._devices.length) { | ||
if (this._gcInterval) { | ||
clearInterval(this._gcInterval); | ||
this._gcInterval = undefined; | ||
} | ||
} | ||
}; | ||
@@ -1427,2 +1491,4 @@ Bus.prototype.disconnectDevice = function (dev) { | ||
this.emit(DEVICE_DISCONNECT, dev); | ||
this.emit(DEVICE_CHANGE, dev); | ||
this.emit(CHANGE); | ||
}; | ||
@@ -1429,0 +1495,0 @@ /** |
@@ -7,3 +7,3 @@ import { Packet } from "./packet"; | ||
sendPacketAsync?: (p: Packet) => Promise<void>; | ||
connectAsync?: (userRequest?: boolean) => Promise<void>; | ||
connectAsync?: (background?: boolean) => Promise<void>; | ||
disconnectAsync?: () => Promise<void>; | ||
@@ -42,2 +42,3 @@ } | ||
get id(): string; | ||
toString(): string; | ||
node(id: string): this | Device | import("./service").Service | import("./register").Register; | ||
@@ -54,3 +55,3 @@ private resetTime; | ||
errorHandler(context: string, exception: any): void; | ||
connectAsync(userRequest?: boolean): Promise<void>; | ||
connectAsync(background?: boolean): Promise<void>; | ||
disconnectAsync(): Promise<void>; | ||
@@ -57,0 +58,0 @@ /** |
@@ -92,2 +92,3 @@ export declare const REG_INTENSITY = 1; | ||
export declare const RESTART = "restart"; | ||
export declare const CHANGE = "change"; | ||
export declare const DEVICE_CONNECT = "deviceConnect"; | ||
@@ -97,2 +98,3 @@ export declare const DEVICE_DISCONNECT = "deviceDisconnect"; | ||
export declare const DEVICE_RESTART = "deviceRestart"; | ||
export declare const DEVICE_CHANGE = "deviceChange"; | ||
export declare const PACKET_SEND = "packetSend"; | ||
@@ -99,0 +101,0 @@ export declare const PACKET_PROCESS = "packetProcess"; |
import { SMap } from "./utils"; | ||
import { Observable } from "./observable"; | ||
export declare type EventHandler = (...args: any[]) => void; | ||
@@ -27,3 +28,15 @@ interface Listener { | ||
eventNames(): string[]; | ||
/** | ||
* Creates an observable from the given event | ||
* @param eventName | ||
*/ | ||
observe<T>(eventName: string): Observable<T>; | ||
/** | ||
* Subscribbes to an event and returns the unsubscription handler | ||
* @param eventName | ||
* @param next | ||
*/ | ||
subscribe<T>(eventName: string, next: (value: T) => void): () => void; | ||
} | ||
export declare function fromEvent<T>(eventEmitter: EventEmitter, eventName: string): Observable<T>; | ||
export {}; |
@@ -53,3 +53,3 @@ /// <reference types="w3c-web-usb" /> | ||
private requestDeviceAsync; | ||
connectAsync(userInteraction: boolean): Promise<void>; | ||
connectAsync(background: boolean): Promise<void>; | ||
private openDeviceAsync; | ||
@@ -72,4 +72,4 @@ } | ||
onSerial(data: Uint8Array, iserr: boolean): void; | ||
connectAsync(userRequest?: boolean): Promise<void>; | ||
connectAsync(background?: boolean): Promise<void>; | ||
disconnectAsync(): Promise<void>; | ||
} |
@@ -6,2 +6,3 @@ export * from './constants'; | ||
export * from './struct'; | ||
export * from './observable'; | ||
export * from './eventemitter'; | ||
@@ -8,0 +9,0 @@ export * from './packet'; |
@@ -15,3 +15,4 @@ import { Packet } from "./packet"; | ||
get intValue(): number; | ||
toString(): string; | ||
processReport(pkt: Packet): void; | ||
} |
@@ -13,2 +13,3 @@ import { Device } from "./device"; | ||
get name(): string; | ||
toString(): string; | ||
registerAt(address: number): Register; | ||
@@ -15,0 +16,0 @@ register(options: { |
/// <reference types="w3c-web-usb" /> | ||
import { Bus } from "./bus"; | ||
export interface USBOptions { | ||
getDevices(): Promise<USBDevice[]>; | ||
requestDevice(options: USBDeviceRequestOptions): Promise<USBDevice>; | ||
addEventListener(type: "connect" | "disconnect", listener: (this: this, ev: USBConnectionEvent) => any, useCapture?: boolean): void; | ||
removeEventListener(type: "connect" | "disconnect", callback: (this: this, ev: USBConnectionEvent) => any, useCapture?: boolean): void; | ||
getDevices: () => Promise<USBDevice[]>; | ||
requestDevice: (options: USBDeviceRequestOptions) => Promise<USBDevice>; | ||
} | ||
export declare function isWebUSBSupported(): boolean; | ||
export declare function createUSBBus(options?: USBOptions): Bus; |
{ | ||
"name": "jacdac-ts", | ||
"version": "1.1.5", | ||
"version": "1.1.6", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "keywords": [], |
@@ -1,2 +0,2 @@ | ||
# JACDAC TypeScript | ||
# JACDAC ![Build](https://github.com/microsoft/jacdac-ts/workflows/Build/badge.svg) | ||
@@ -3,0 +3,0 @@ This repository contains a TypeScript/JavaScript client library for the [JACDAC](https://microsoft.github.io/jacdac) protocol. |
@@ -23,3 +23,5 @@ import { Packet } from "./packet"; | ||
CONNECTION_STATE, | ||
DISCONNECTING | ||
DISCONNECTING, | ||
DEVICE_CHANGE, | ||
CHANGE | ||
} from "./constants"; | ||
@@ -30,3 +32,3 @@ import { serviceClass } from "./pretty"; | ||
sendPacketAsync?: (p: Packet) => Promise<void>; | ||
connectAsync?: (userRequest?: boolean) => Promise<void>; | ||
connectAsync?: (background?: boolean) => Promise<void>; | ||
disconnectAsync?: () => Promise<void>; | ||
@@ -87,2 +89,3 @@ } | ||
} | ||
this.emit(CHANGE) | ||
} | ||
@@ -92,5 +95,9 @@ } | ||
get id() { | ||
return "bus"; | ||
return `bus`; | ||
} | ||
toString() { | ||
return this.id; | ||
} | ||
node(id: string) { | ||
@@ -113,2 +120,3 @@ const m = /^(?<type>bus|dev|srv|reg)(:(?<dev>\w+)(:(?<srv>\w+)(:(?<reg>\w+))?)?)?$/.exec(id) | ||
this._startTime = Date.now(); | ||
this.emit(CHANGE) | ||
} | ||
@@ -127,2 +135,3 @@ | ||
this._minConsolePriority = priority; | ||
this.emit(CHANGE) | ||
} | ||
@@ -140,3 +149,4 @@ } | ||
this.emit(PACKET_SEND, p); | ||
return this.options?.sendPacketAsync(p) || Promise.resolve(); | ||
const spa = this.options.sendPacketAsync; | ||
return spa ? spa(p) : Promise.resolve(); | ||
} | ||
@@ -158,5 +168,6 @@ | ||
this.emit(ERROR, { context, exception }) | ||
this.emit(CHANGE) | ||
} | ||
connectAsync(userRequest?: boolean): Promise<void> { | ||
connectAsync(background?: boolean): Promise<void> { | ||
// already connected | ||
@@ -175,3 +186,3 @@ if (this.connectionState == BusState.Connected) | ||
this.setConnectionState(BusState.Connecting) | ||
const connectAsyncPromise = this.options?.connectAsync(userRequest) || Promise.resolve(); | ||
const connectAsyncPromise = this.options.connectAsync ? this.options.connectAsync(background) : Promise.resolve(); | ||
this._connectPromise = connectAsyncPromise | ||
@@ -204,13 +215,7 @@ .then(() => { | ||
this.setConnectionState(BusState.Disconnecting) | ||
if (this._gcInterval) { | ||
clearInterval(this._gcInterval); | ||
this._gcInterval = undefined; | ||
} | ||
this._disconnectPromise = this._disconnectPromise | ||
.then(() => this.options?.disconnectAsync() || Promise.resolve()) | ||
.then(() => this.options.disconnectAsync ? this.options.disconnectAsync() : Promise.resolve()) | ||
.catch(e => this.errorHandler(DISCONNECT, e)) | ||
.finally(() => { | ||
this._disconnectPromise = undefined; | ||
this._devices.forEach(device => this.disconnectDevice(device)) | ||
this._devices = [] | ||
this.setConnectionState(BusState.Disconnected); | ||
@@ -232,3 +237,2 @@ }); | ||
if (sc === undefined) sc = -1; | ||
let r = this._devices.slice(); | ||
@@ -249,4 +253,6 @@ if (sc > -1) r = r.filter(s => s.hasService(sc)) | ||
this.emit(DEVICE_CONNECT, d); | ||
this.emit(DEVICE_CHANGE, d); | ||
this.emit(CHANGE) | ||
if (!this._gcInterval && this.connected) | ||
if (!this._gcInterval) | ||
this._gcInterval = setInterval(() => this.gcDevices(), 2000); | ||
@@ -267,2 +273,9 @@ } | ||
} | ||
// stop cleanup if all gone | ||
if (!this._devices.length) { | ||
if (this._gcInterval) { | ||
clearInterval(this._gcInterval) | ||
this._gcInterval = undefined; | ||
} | ||
} | ||
} | ||
@@ -273,2 +286,4 @@ | ||
this.emit(DEVICE_DISCONNECT, dev); | ||
this.emit(DEVICE_CHANGE, dev) | ||
this.emit(CHANGE) | ||
} | ||
@@ -291,3 +306,2 @@ | ||
dev.lastSeen = pkt.timestamp | ||
if (pkt.service_number == JD_SERVICE_NUMBER_CTRL) { | ||
@@ -299,3 +313,3 @@ if (pkt.service_command == CMD_ADVERTISEMENT_DATA) { | ||
} else | ||
pkt.dev.processPacket(pkt); | ||
pkt.dev.processPacket(pkt) | ||
} | ||
@@ -302,0 +316,0 @@ // don't spam with duplicate advertisement events |
@@ -138,2 +138,3 @@ | ||
export const RESTART = 'restart' | ||
export const CHANGE = 'change' | ||
@@ -144,2 +145,3 @@ export const DEVICE_CONNECT = 'deviceConnect' | ||
export const DEVICE_RESTART = 'deviceRestart' | ||
export const DEVICE_CHANGE = 'deviceChange' | ||
@@ -146,0 +148,0 @@ export const PACKET_SEND = 'packetSend' |
import { Packet } from "./packet" | ||
import { | ||
JD_SERVICE_NUMBER_CTRL, DEVICE_ANNOUNCE, ANNOUNCE, DISCONNECT, CONNECT, | ||
JD_ADVERTISEMENT_0_COUNTER_MASK, DEVICE_RESTART, RESTART | ||
JD_SERVICE_NUMBER_CTRL, DEVICE_ANNOUNCE, DEVICE_CHANGE, ANNOUNCE, DISCONNECT, CONNECT, | ||
JD_ADVERTISEMENT_0_COUNTER_MASK, DEVICE_RESTART, RESTART, CHANGE | ||
} from "./constants" | ||
@@ -129,5 +129,7 @@ import { hash, fromHex, idiv, read32, SMap, bufferEq, assert } from "./utils" | ||
this.emit(RESTART) | ||
this.bus.emit(DEVICE_CHANGE, this); | ||
this.emit(CHANGE) | ||
} | ||
const servData = this.servicesData ? this.servicesData.slice(4) : null | ||
const servData = this.servicesData?.slice(4) | ||
if (!bufferEq(pkt.data.slice(4), servData)) { | ||
@@ -142,2 +144,4 @@ this.servicesData = pkt.data | ||
this.emit(ANNOUNCE) | ||
this.bus.emit(DEVICE_CHANGE, this); | ||
this.emit(CHANGE) | ||
} | ||
@@ -144,0 +148,0 @@ } |
import { SMap } from "./utils"; | ||
import { NEW_LISTENER, REMOVE_LISTENER, ERROR } from "./constants"; | ||
import { Observable, Observer } from "./observable"; | ||
export type EventHandler = (...args) => void; | ||
@@ -47,2 +48,3 @@ | ||
}) | ||
//console.log(`${eventName}->${listeners.length}`) | ||
return this; | ||
@@ -58,5 +60,4 @@ } | ||
const listener = listeners[i]; | ||
const handler = listener.handler | ||
if (handler === handler) { | ||
listeners.splice(i, -1); | ||
if (handler === listener.handler) { | ||
listeners.splice(i, 1); | ||
--i; | ||
@@ -87,3 +88,3 @@ if (listeners.length == 0) | ||
if (listener.once) { | ||
listeners.splice(i, -1); | ||
listeners.splice(i, 1); | ||
--i; | ||
@@ -117,2 +118,43 @@ } | ||
} | ||
/** | ||
* Creates an observable from the given event | ||
* @param eventName | ||
*/ | ||
observe<T>(eventName: string): Observable<T> { | ||
return fromEvent<T>(this, eventName); | ||
} | ||
/** | ||
* Subscribbes to an event and returns the unsubscription handler | ||
* @param eventName | ||
* @param next | ||
*/ | ||
subscribe<T>(eventName: string, next: (value: T) => void): () => void { | ||
const observer = this.observe<T>(eventName); | ||
return observer.subscribe({ next }).unsubscribe | ||
} | ||
} | ||
class EventObservable<T> implements Observable<T> { | ||
constructor(public eventEmitter: EventEmitter, public eventName: string) { | ||
} | ||
subscribe(observer: Observer<T>) { | ||
//console.log(`on ${this.eventName}`) | ||
this.eventEmitter.on(this.eventName, observer.next) | ||
this.eventEmitter.on(ERROR, observer.error) | ||
// never completes | ||
return { | ||
unsubscribe: () => { | ||
//console.log(`off ${this.eventName}`) | ||
this.eventEmitter.off(this.eventName, observer.next); | ||
this.eventEmitter.off(ERROR, observer.error) | ||
} | ||
} | ||
} | ||
} | ||
export function fromEvent<T>(eventEmitter: EventEmitter, eventName: string): Observable<T> { | ||
return new EventObservable<T>(eventEmitter, eventName) | ||
} |
@@ -273,5 +273,5 @@ import * as U from "./utils" | ||
async connectAsync(userInteraction: boolean) { | ||
async connectAsync(background: boolean) { | ||
await this.tryReconnectAsync(); | ||
if (!this.dev && userInteraction) | ||
if (!this.dev && !background) | ||
await this.requestDeviceAsync(); | ||
@@ -447,4 +447,4 @@ await this.openDeviceAsync(); | ||
async connectAsync(userRequest?: boolean) { | ||
await this.io.connectAsync(userRequest) | ||
async connectAsync(background?: boolean) { | ||
await this.io.connectAsync(background) | ||
const buf = await this.talkAsync(HF2_CMD_INFO) | ||
@@ -451,0 +451,0 @@ this.io.log("Connected to: " + U.bufferToString(buf)) |
@@ -6,2 +6,3 @@ export * from './constants' | ||
export * from './struct' | ||
export * from './observable' | ||
export * from './eventemitter' | ||
@@ -8,0 +9,0 @@ export * from './packet' |
import { Packet } from "./packet"; | ||
import { CMD_SET_REG, REPORT_RECEIVE, REPORT_UPDATE } from "./constants"; | ||
import { CMD_SET_REG, REPORT_RECEIVE, REPORT_UPDATE, CHANGE } from "./constants"; | ||
import { Service } from "./service"; | ||
import { intOfBuffer } from "./buffer"; | ||
import { Node } from "./node"; | ||
import { bufferEq } from "./utils"; | ||
import { bufferEq, toHex } from "./utils"; | ||
import { bufferOfInt } from "./struct"; | ||
@@ -42,2 +42,6 @@ | ||
toString() { | ||
return `${this.id} ${this._data ? toHex(this._data) : ""}` | ||
} | ||
processReport(pkt: Packet) { | ||
@@ -48,5 +52,7 @@ const updated = !bufferEq(this._data, pkt.data) | ||
this.emit(REPORT_RECEIVE, this) | ||
if (updated) | ||
if (updated) { | ||
this.emit(REPORT_UPDATE, this) | ||
this.emit(CHANGE) | ||
} | ||
} | ||
} |
@@ -30,2 +30,6 @@ import { Device } from "./device"; | ||
toString() { | ||
return `${this.name} ${this.id}`; | ||
} | ||
registerAt(address: number) { | ||
@@ -32,0 +36,0 @@ address = address | 0; |
@@ -7,12 +7,10 @@ import { Transport, Proto } from "./hf2"; | ||
export interface USBOptions { | ||
getDevices(): Promise<USBDevice[]>; | ||
requestDevice(options: USBDeviceRequestOptions): Promise<USBDevice> | ||
addEventListener(type: "connect" | "disconnect", listener: (this: this, ev: USBConnectionEvent) => any, useCapture?: boolean): void; | ||
removeEventListener(type: "connect" | "disconnect", callback: (this: this, ev: USBConnectionEvent) => any, useCapture?: boolean): void; | ||
getDevices: () => Promise<USBDevice[]>; | ||
requestDevice: (options: USBDeviceRequestOptions) => Promise<USBDevice> | ||
} | ||
export function isWebUSBSupported() { | ||
return typeof navigator !== "undefined" && navigator.usb | ||
&& !!navigator.usb.requestDevice | ||
&& !!navigator.usb.getDevices; | ||
export function isWebUSBSupported(): boolean { | ||
return typeof navigator !== "undefined" | ||
&& !!navigator.usb | ||
&& !!navigator.usb.requestDevice; | ||
} | ||
@@ -23,9 +21,17 @@ | ||
if (isWebUSBSupported()) | ||
options = navigator.usb | ||
options = { | ||
getDevices: () => navigator.usb.getDevices(), | ||
requestDevice: (filters) => navigator.usb.requestDevice(filters) | ||
} | ||
} | ||
assert(!!options) | ||
// dummy impl | ||
if (!options) { | ||
options = { | ||
getDevices: () => Promise.resolve([]), | ||
requestDevice: (filters) => Promise.resolve(undefined) | ||
} | ||
} | ||
let hf2: Proto; | ||
const bus = new Bus({ | ||
connectAsync: (userRequest) => { | ||
connectAsync: (background) => { | ||
if (hf2) return Promise.resolve(); | ||
@@ -39,3 +45,3 @@ const transport = new Transport(options); | ||
} | ||
return hf2.connectAsync(userRequest) | ||
return hf2.connectAsync(background) | ||
.then(() => hf2.onJDMessage(onJDMessage)) | ||
@@ -42,0 +48,0 @@ }, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
4101927
3375
74
38419