incyclist-services 1.4.8 → 1.4.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/devices/ride/service.d.ts +9 -3
- package/lib/devices/ride/service.js +141 -107
- package/lib/routes/list/cards/base.d.ts +1 -0
- package/lib/routes/list/cards/base.js +3 -0
- package/lib/routes/list/service.d.ts +17 -2
- package/lib/routes/list/service.js +52 -16
- package/lib/routes/list/types.d.ts +1 -0
- package/package.json +4 -4
|
@@ -6,6 +6,7 @@ import { IncyclistService } from "../../base/service";
|
|
|
6
6
|
export declare class DeviceRideService extends IncyclistService {
|
|
7
7
|
protected initizialized: boolean;
|
|
8
8
|
protected adapters: AdapterRideInfo[];
|
|
9
|
+
protected rideAdapters: AdapterRideInfo[];
|
|
9
10
|
protected startPromises: Promise<boolean>[];
|
|
10
11
|
protected data: DeviceData;
|
|
11
12
|
protected simulatorEnforced: boolean;
|
|
@@ -15,6 +16,7 @@ export declare class DeviceRideService extends IncyclistService {
|
|
|
15
16
|
protected deviceDataHandler: any;
|
|
16
17
|
protected lazyInitDone: boolean;
|
|
17
18
|
protected lastDataInfo: Record<string, number>;
|
|
19
|
+
protected reconnectBusy: boolean;
|
|
18
20
|
constructor();
|
|
19
21
|
protected waitForInit(): Promise<void>;
|
|
20
22
|
lazyInit(): Promise<void>;
|
|
@@ -33,6 +35,10 @@ export declare class DeviceRideService extends IncyclistService {
|
|
|
33
35
|
info: AdapterInfo;
|
|
34
36
|
}>;
|
|
35
37
|
startAdapters(adapters: AdapterRideInfo[], startType: 'start' | 'check' | 'pair', props?: RideServiceDeviceProperties): Promise<boolean>;
|
|
38
|
+
protected startSingleAdapter(ai: AdapterRideInfo, duplicates: any, props: any, startType: 'start' | 'check' | 'pair'): Promise<boolean>;
|
|
39
|
+
private initForStart;
|
|
40
|
+
private initForPairing;
|
|
41
|
+
private initCyclingMode;
|
|
36
42
|
private handleStartRejection;
|
|
37
43
|
private handleStartFailure;
|
|
38
44
|
private handleStartSuccess;
|
|
@@ -42,11 +48,11 @@ export declare class DeviceRideService extends IncyclistService {
|
|
|
42
48
|
stopHealthCheck(ai: AdapterRideInfo): void;
|
|
43
49
|
prepareReconnect(unhealthy: AdapterRideInfo): Promise<void>;
|
|
44
50
|
private reconnectInterface;
|
|
45
|
-
private finalizeAdaptersAfterRestart;
|
|
46
51
|
private performInterfaceReconnect;
|
|
52
|
+
protected stopAllAdaptersOnInterface(ifName: string): Promise<void>;
|
|
47
53
|
private stopAdapters;
|
|
48
54
|
private reconnectAdapters;
|
|
49
|
-
protected
|
|
55
|
+
protected stopDuringInterfaceRestart(unhealthy: AdapterRideInfo): Promise<void>;
|
|
50
56
|
private reconnectSingle;
|
|
51
57
|
start(props: RideServiceDeviceProperties): Promise<boolean>;
|
|
52
58
|
startRetry(props: RideServiceDeviceProperties): Promise<boolean>;
|
|
@@ -60,7 +66,7 @@ export declare class DeviceRideService extends IncyclistService {
|
|
|
60
66
|
onData(deviceSettings: DeviceSettings, data: DeviceData): void;
|
|
61
67
|
protected registerData(adapterInfo: AdapterRideInfo, data: DeviceData): void;
|
|
62
68
|
protected getLastDataTS(adapterInfo: AdapterRideInfo): number;
|
|
63
|
-
protected setLastDataTS(adapterInfo: AdapterRideInfo, ts: number):
|
|
69
|
+
protected setLastDataTS(adapterInfo: AdapterRideInfo, ts: number): void;
|
|
64
70
|
protected clearLastDataTS(adapterInfo: AdapterRideInfo): void;
|
|
65
71
|
private getEnabledCapabilities;
|
|
66
72
|
isUpdateBusy(): boolean;
|
|
@@ -123,11 +123,14 @@ let DeviceRideService = (() => {
|
|
|
123
123
|
return this.data;
|
|
124
124
|
}
|
|
125
125
|
getSelectedAdapters() {
|
|
126
|
-
|
|
126
|
+
if (this.rideAdapters)
|
|
127
|
+
return this.rideAdapters;
|
|
128
|
+
this.rideAdapters = this.adapters = this.getConfiguredAdapters(true);
|
|
127
129
|
if (!this.simulatorEnforced)
|
|
128
130
|
return this.adapters;
|
|
129
131
|
const adapter = incyclist_devices_1.AdapterFactory.create({ interface: 'simulator', name: 'Simulator' });
|
|
130
|
-
|
|
132
|
+
this.rideAdapters = [{ adapter, udid: 'Simulator' + Date.now(), capabilities: adapter.getCapabilities(), isStarted: false }];
|
|
133
|
+
return this.rideAdapters;
|
|
131
134
|
}
|
|
132
135
|
getAllAdapters() {
|
|
133
136
|
var _a;
|
|
@@ -147,7 +150,7 @@ let DeviceRideService = (() => {
|
|
|
147
150
|
}
|
|
148
151
|
prepareEppRoute(props) {
|
|
149
152
|
const { route, startPos, realityFactor, rideMode } = props;
|
|
150
|
-
if (!route ||
|
|
153
|
+
if (!(route === null || route === void 0 ? void 0 : route.get())) {
|
|
151
154
|
return null;
|
|
152
155
|
}
|
|
153
156
|
let res;
|
|
@@ -420,73 +423,10 @@ let DeviceRideService = (() => {
|
|
|
420
423
|
}
|
|
421
424
|
startAdapters(adapters, startType, props) {
|
|
422
425
|
return __awaiter(this, void 0, void 0, function* () {
|
|
423
|
-
|
|
426
|
+
var _a;
|
|
424
427
|
const duplicates = this.checkAntSameDeviceID(adapters);
|
|
425
|
-
|
|
426
|
-
this.startPromises
|
|
427
|
-
var _a, _b, _c;
|
|
428
|
-
if (duplicates.find(dai => dai.info.udid === ai.udid))
|
|
429
|
-
return;
|
|
430
|
-
const startProps = (0, clone_1.default)(props || {});
|
|
431
|
-
let mode, settings, bike;
|
|
432
|
-
if ((_a = ai.adapter) === null || _a === void 0 ? void 0 : _a.isControllable()) {
|
|
433
|
-
bike = ai.adapter;
|
|
434
|
-
const modeInfo = config.getModeSettings(ai.udid);
|
|
435
|
-
mode = modeInfo === null || modeInfo === void 0 ? void 0 : modeInfo.mode;
|
|
436
|
-
settings = (modeInfo === null || modeInfo === void 0 ? void 0 : modeInfo.settings) || {};
|
|
437
|
-
if (!this.simulatorEnforced && forceErgMode) {
|
|
438
|
-
const modes = bike.getSupportedCyclingModes().filter(C => C.supportsERGMode());
|
|
439
|
-
if (modes.length > 0) {
|
|
440
|
-
mode = new modes[0](bike);
|
|
441
|
-
const modeInfo = config.getModeSettings(ai.udid, mode);
|
|
442
|
-
settings = modeInfo.settings;
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
if (!mode)
|
|
446
|
-
mode = bike.getDefaultCyclingMode();
|
|
447
|
-
bike.setCyclingMode(mode, settings);
|
|
448
|
-
}
|
|
449
|
-
if (startType === 'check' || startType === 'pair') {
|
|
450
|
-
startProps.timeout = 10000;
|
|
451
|
-
if (ai.adapter.getSettings().interface === 'ble')
|
|
452
|
-
startProps.timeout = 30000;
|
|
453
|
-
}
|
|
454
|
-
if (startType === 'start') {
|
|
455
|
-
if ((_b = ai.adapter) === null || _b === void 0 ? void 0 : _b.isControllable()) {
|
|
456
|
-
if (bike.getCyclingMode().getModeProperty('eppSupport')) {
|
|
457
|
-
startProps.route = this.prepareEppRoute({ route, startPos, realityFactor, rideMode });
|
|
458
|
-
startProps.onStatusUpdate = (completed, total) => {
|
|
459
|
-
this.emit('start-update', this.getAdapterStateInfo(ai), completed, total);
|
|
460
|
-
};
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
const sType = ai.adapter.hasCapability(incyclist_devices_1.IncyclistCapability.Control) ? 'bike' : 'sensor';
|
|
465
|
-
const logProps = {};
|
|
466
|
-
logProps[sType] = ai.adapter.getUniqueName();
|
|
467
|
-
logProps.cability = ai.adapter.getCapabilities().join('/');
|
|
468
|
-
logProps.interface = (0, logging_1.getLegacyInterface)(ai.adapter);
|
|
469
|
-
if (sType === 'bike') {
|
|
470
|
-
const bike = ai.adapter;
|
|
471
|
-
logProps.cyclingMode = (_c = bike.getCyclingMode()) === null || _c === void 0 ? void 0 : _c.getName();
|
|
472
|
-
logProps.bikeType = bike.getCyclingMode().getSetting('bikeType');
|
|
473
|
-
}
|
|
474
|
-
this.logEvent(Object.assign({ message: `${startType} ${sType} request` }, logProps));
|
|
475
|
-
return ai.adapter.start(startProps)
|
|
476
|
-
.then((success) => __awaiter(this, void 0, void 0, function* () {
|
|
477
|
-
if (success) {
|
|
478
|
-
yield this.handleStartSuccess(startType, ai, duplicates, sType, logProps);
|
|
479
|
-
return true;
|
|
480
|
-
}
|
|
481
|
-
yield this.handleStartFailure(startType, ai, duplicates, sType, logProps);
|
|
482
|
-
return false;
|
|
483
|
-
}))
|
|
484
|
-
.catch((err) => __awaiter(this, void 0, void 0, function* () {
|
|
485
|
-
yield this.handleStartRejection(startType, sType, logProps, err, ai, duplicates);
|
|
486
|
-
return false;
|
|
487
|
-
}));
|
|
488
|
-
}));
|
|
489
|
-
if (!this.startPromises)
|
|
428
|
+
this.startPromises = adapters === null || adapters === void 0 ? void 0 : adapters.map((ai) => __awaiter(this, void 0, void 0, function* () { return this.startSingleAdapter(ai, duplicates, props, startType); }));
|
|
429
|
+
if (!((_a = this.startPromises) === null || _a === void 0 ? void 0 : _a.length))
|
|
490
430
|
return true;
|
|
491
431
|
const status = yield Promise.all(this.startPromises);
|
|
492
432
|
const allOK = status.find(s => s === false) === undefined;
|
|
@@ -498,6 +438,85 @@ let DeviceRideService = (() => {
|
|
|
498
438
|
return allOK;
|
|
499
439
|
});
|
|
500
440
|
}
|
|
441
|
+
startSingleAdapter(ai, duplicates, props, startType) {
|
|
442
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
443
|
+
var _a;
|
|
444
|
+
if (duplicates.find(dai => dai.info.udid === ai.udid))
|
|
445
|
+
return;
|
|
446
|
+
const startProps = (0, clone_1.default)(props || {});
|
|
447
|
+
const { forceErgMode, startPos, realityFactor, rideMode, route } = props || {};
|
|
448
|
+
this.initCyclingMode(ai, forceErgMode);
|
|
449
|
+
if (startType === 'check' || startType === 'pair') {
|
|
450
|
+
this.initForPairing(startProps, ai);
|
|
451
|
+
}
|
|
452
|
+
if (startType === 'start') {
|
|
453
|
+
this.initForStart(ai, startProps, route, startPos, realityFactor, rideMode);
|
|
454
|
+
}
|
|
455
|
+
const sType = ai.adapter.hasCapability(incyclist_devices_1.IncyclistCapability.Control) ? 'bike' : 'sensor';
|
|
456
|
+
const logProps = {};
|
|
457
|
+
logProps[sType] = ai.adapter.getUniqueName();
|
|
458
|
+
logProps.cability = ai.adapter.getCapabilities().join('/');
|
|
459
|
+
logProps.interface = (0, logging_1.getLegacyInterface)(ai.adapter);
|
|
460
|
+
if (sType === 'bike') {
|
|
461
|
+
const bike = ai.adapter;
|
|
462
|
+
logProps.cyclingMode = (_a = bike.getCyclingMode()) === null || _a === void 0 ? void 0 : _a.getName();
|
|
463
|
+
logProps.bikeType = bike.getCyclingMode().getSetting('bikeType');
|
|
464
|
+
}
|
|
465
|
+
this.logEvent(Object.assign({ message: `${startType} ${sType} request` }, logProps));
|
|
466
|
+
return ai.adapter.start(startProps)
|
|
467
|
+
.then((success) => __awaiter(this, void 0, void 0, function* () {
|
|
468
|
+
if (success) {
|
|
469
|
+
yield this.handleStartSuccess(startType, ai, duplicates, sType, logProps);
|
|
470
|
+
return true;
|
|
471
|
+
}
|
|
472
|
+
yield this.handleStartFailure(startType, ai, duplicates, sType, logProps);
|
|
473
|
+
return false;
|
|
474
|
+
}))
|
|
475
|
+
.catch((err) => __awaiter(this, void 0, void 0, function* () {
|
|
476
|
+
yield this.handleStartRejection(startType, sType, logProps, err, ai, duplicates);
|
|
477
|
+
return false;
|
|
478
|
+
}));
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
initForStart(ai, startProps, route, startPos, realityFactor, rideMode) {
|
|
482
|
+
var _a;
|
|
483
|
+
if ((_a = ai.adapter) === null || _a === void 0 ? void 0 : _a.isControllable()) {
|
|
484
|
+
const bike = ai.adapter;
|
|
485
|
+
if (bike.getCyclingMode().getModeProperty('eppSupport')) {
|
|
486
|
+
startProps.route = this.prepareEppRoute({ route, startPos, realityFactor, rideMode });
|
|
487
|
+
startProps.onStatusUpdate = (completed, total) => {
|
|
488
|
+
this.emit('start-update', this.getAdapterStateInfo(ai), completed, total);
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
initForPairing(startProps, ai) {
|
|
494
|
+
startProps.timeout = 10000;
|
|
495
|
+
if (ai.adapter.getSettings().interface === 'ble')
|
|
496
|
+
startProps.timeout = 30000;
|
|
497
|
+
}
|
|
498
|
+
initCyclingMode(ai, forceErgMode) {
|
|
499
|
+
var _a;
|
|
500
|
+
let bike, mode, settings;
|
|
501
|
+
if ((_a = ai.adapter) === null || _a === void 0 ? void 0 : _a.isControllable()) {
|
|
502
|
+
bike = ai.adapter;
|
|
503
|
+
const config = this.getDeviceConfiguration();
|
|
504
|
+
const modeInfo = config.getModeSettings(ai.udid);
|
|
505
|
+
mode = modeInfo === null || modeInfo === void 0 ? void 0 : modeInfo.mode;
|
|
506
|
+
settings = (modeInfo === null || modeInfo === void 0 ? void 0 : modeInfo.settings) || {};
|
|
507
|
+
if (!this.simulatorEnforced && forceErgMode) {
|
|
508
|
+
const modes = bike.getSupportedCyclingModes().filter(C => C.supportsERGMode());
|
|
509
|
+
if (modes.length > 0) {
|
|
510
|
+
mode = new modes[0](bike);
|
|
511
|
+
const modeInfo = config.getModeSettings(ai.udid, mode);
|
|
512
|
+
settings = modeInfo.settings;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
if (!mode)
|
|
516
|
+
mode = bike.getDefaultCyclingMode();
|
|
517
|
+
bike.setCyclingMode(mode, settings);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
501
520
|
handleStartRejection(startType, sType, logProps, err, ai, duplicates) {
|
|
502
521
|
return __awaiter(this, void 0, void 0, function* () {
|
|
503
522
|
this.logEvent(Object.assign(Object.assign({ message: `${startType} ${sType} request failed` }, logProps), { reason: err.message }));
|
|
@@ -582,6 +601,11 @@ let DeviceRideService = (() => {
|
|
|
582
601
|
return;
|
|
583
602
|
ai.ivToCheck = (0, timers_1.setInterval)(() => { check(); }, 1000);
|
|
584
603
|
ai.isHealthy = true;
|
|
604
|
+
if (ai.dataStatus !== undefined && ai.dataStatus !== 'green') {
|
|
605
|
+
ai.dataStatus = 'green';
|
|
606
|
+
const { enabledCapabilities } = this.getEnabledCapabilities(ai);
|
|
607
|
+
this.emit('health', ai.udid, ai.dataStatus, enabledCapabilities);
|
|
608
|
+
}
|
|
585
609
|
}
|
|
586
610
|
updateOnDatahandler(ai) {
|
|
587
611
|
this.logEvent({ message: 'init health check', device: ai.adapter.getName(), udid: ai.udid });
|
|
@@ -603,15 +627,20 @@ let DeviceRideService = (() => {
|
|
|
603
627
|
}
|
|
604
628
|
prepareReconnect(unhealthy) {
|
|
605
629
|
return __awaiter(this, void 0, void 0, function* () {
|
|
630
|
+
var _a;
|
|
606
631
|
this.logEvent({ message: 'prepareReconnect', device: unhealthy.adapter.getUniqueName(), udid: unhealthy.udid, noDataSince: (Date.now() - unhealthy.tsLastData), tsLastData: unhealthy.tsLastData });
|
|
632
|
+
this.reconnectBusy = true;
|
|
607
633
|
if (unhealthy.isRestarting)
|
|
608
634
|
return;
|
|
609
|
-
yield (0, sleep_1.sleep)(
|
|
610
|
-
if (unhealthy.isHealthy || unhealthy.isRestarting)
|
|
635
|
+
yield (0, sleep_1.sleep)(1000);
|
|
636
|
+
if (unhealthy.isHealthy || unhealthy.isRestarting) {
|
|
637
|
+
this.logEvent({ message: 'skipped reconnect', device: unhealthy.adapter.getUniqueName(), udid: unhealthy.udid, noDataSince: (Date.now() - unhealthy.tsLastData), tsLastData: unhealthy.tsLastData });
|
|
611
638
|
return;
|
|
639
|
+
}
|
|
640
|
+
this.logEvent({ message: 'reconnect confirmed', device: unhealthy.adapter.getUniqueName(), udid: unhealthy.udid, noDataSince: (Date.now() - unhealthy.tsLastData), tsLastData: unhealthy.tsLastData });
|
|
612
641
|
const ifName = unhealthy.adapter.getInterface();
|
|
613
|
-
const adapters = this.
|
|
614
|
-
if (!adapters.find(ai => ai.isHealthy)) {
|
|
642
|
+
const adapters = (_a = this.rideAdapters) === null || _a === void 0 ? void 0 : _a.filter(ai => ai.adapter.getInterface() === ifName);
|
|
643
|
+
if (!adapters.find(ai => ai.isHealthy) && adapters.length > 1) {
|
|
615
644
|
yield this.reconnectInterface(ifName, adapters);
|
|
616
645
|
}
|
|
617
646
|
else {
|
|
@@ -622,6 +651,10 @@ let DeviceRideService = (() => {
|
|
|
622
651
|
}
|
|
623
652
|
reconnectInterface(ifName, adapters) {
|
|
624
653
|
return __awaiter(this, void 0, void 0, function* () {
|
|
654
|
+
if (this.reconnectBusy) {
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
this.reconnectBusy = true;
|
|
625
658
|
if (ifName === 'simulator')
|
|
626
659
|
return;
|
|
627
660
|
if (ifName === 'ble') {
|
|
@@ -631,13 +664,14 @@ let DeviceRideService = (() => {
|
|
|
631
664
|
catch (err) {
|
|
632
665
|
this.logError(err, 'reconnectInterface');
|
|
633
666
|
}
|
|
667
|
+
this.reconnectBusy = false;
|
|
634
668
|
return;
|
|
635
669
|
}
|
|
636
670
|
this.logger.logEvent({ message: 'restart interface', interface: ifName });
|
|
637
671
|
let stopRequested = false;
|
|
638
672
|
this.once('stop-ride', () => { stopRequested = true; });
|
|
639
673
|
try {
|
|
640
|
-
yield this.
|
|
674
|
+
yield this.stopAllAdaptersOnInterface(ifName);
|
|
641
675
|
if (stopRequested)
|
|
642
676
|
return;
|
|
643
677
|
yield this.performInterfaceReconnect(ifName);
|
|
@@ -648,20 +682,7 @@ let DeviceRideService = (() => {
|
|
|
648
682
|
catch (err) {
|
|
649
683
|
this.logger.logEvent({ message: 'restart interface failed', interface: ifName, reason: err.message });
|
|
650
684
|
}
|
|
651
|
-
this.
|
|
652
|
-
});
|
|
653
|
-
}
|
|
654
|
-
finalizeAdaptersAfterRestart(adapters) {
|
|
655
|
-
adapters.forEach(ai => {
|
|
656
|
-
if (ai.adapter.isStarted()) {
|
|
657
|
-
ai.tsLastData = Date.now();
|
|
658
|
-
}
|
|
659
|
-
else {
|
|
660
|
-
ai.isRestarting = false;
|
|
661
|
-
this.prepareReconnect(ai);
|
|
662
|
-
}
|
|
663
|
-
ai.adapter.on('data', this.deviceDataHandler);
|
|
664
|
-
ai.isRestarting = false;
|
|
685
|
+
this.reconnectBusy = false;
|
|
665
686
|
});
|
|
666
687
|
}
|
|
667
688
|
performInterfaceReconnect(ifName) {
|
|
@@ -674,11 +695,15 @@ let DeviceRideService = (() => {
|
|
|
674
695
|
}
|
|
675
696
|
});
|
|
676
697
|
}
|
|
698
|
+
stopAllAdaptersOnInterface(ifName) {
|
|
699
|
+
const adapaters = this.getAllAdapters().filter(ai => ai.adapter.getInterface() === ifName);
|
|
700
|
+
return this.stopAdapters(adapaters);
|
|
701
|
+
}
|
|
677
702
|
stopAdapters(adapters) {
|
|
678
703
|
return __awaiter(this, void 0, void 0, function* () {
|
|
679
704
|
const promisesStop = [];
|
|
680
705
|
adapters.forEach(ai => {
|
|
681
|
-
promisesStop.push(this.
|
|
706
|
+
promisesStop.push(this.stopDuringInterfaceRestart(ai));
|
|
682
707
|
});
|
|
683
708
|
if (promisesStop.length > 0) {
|
|
684
709
|
yield Promise.race([(0, sleep_1.sleep)(66000), Promise.allSettled(promisesStop)]);
|
|
@@ -705,7 +730,7 @@ let DeviceRideService = (() => {
|
|
|
705
730
|
}
|
|
706
731
|
});
|
|
707
732
|
}
|
|
708
|
-
|
|
733
|
+
stopDuringInterfaceRestart(unhealthy) {
|
|
709
734
|
return __awaiter(this, void 0, void 0, function* () {
|
|
710
735
|
this.emit('stop-adapter', unhealthy.udid);
|
|
711
736
|
if (unhealthy.isRestarting) {
|
|
@@ -721,12 +746,18 @@ let DeviceRideService = (() => {
|
|
|
721
746
|
}
|
|
722
747
|
unhealthy.isRestarting = true;
|
|
723
748
|
unhealthy.adapter.off('data', this.deviceDataHandler);
|
|
724
|
-
|
|
749
|
+
try {
|
|
750
|
+
yield unhealthy.adapter.stop();
|
|
751
|
+
}
|
|
752
|
+
catch (err) {
|
|
753
|
+
this.logError(err, 'stopDuringInterfaceRestart');
|
|
754
|
+
}
|
|
725
755
|
});
|
|
726
756
|
}
|
|
727
757
|
reconnectSingle(unhealthy) {
|
|
728
758
|
return __awaiter(this, void 0, void 0, function* () {
|
|
729
759
|
unhealthy.isRestarting = true;
|
|
760
|
+
this.stopHealthCheck(unhealthy);
|
|
730
761
|
let stopRequested = false;
|
|
731
762
|
this.once('stop-ride', () => { stopRequested = true; });
|
|
732
763
|
this.once('stop-adapter', (udid) => {
|
|
@@ -736,7 +767,6 @@ let DeviceRideService = (() => {
|
|
|
736
767
|
let success = false;
|
|
737
768
|
do {
|
|
738
769
|
this.logger.logEvent({ message: 'restart adapter', device: unhealthy.udid });
|
|
739
|
-
unhealthy.adapter.off('data', this.deviceDataHandler);
|
|
740
770
|
const adapter = unhealthy.adapter;
|
|
741
771
|
try {
|
|
742
772
|
const started = yield adapter.restart();
|
|
@@ -747,10 +777,13 @@ let DeviceRideService = (() => {
|
|
|
747
777
|
}
|
|
748
778
|
catch (err) {
|
|
749
779
|
this.logger.logEvent({ message: 'restart adapter failed', device: unhealthy.udid, reason: err.message });
|
|
750
|
-
this.prepareReconnect(unhealthy);
|
|
751
780
|
}
|
|
752
|
-
|
|
753
|
-
|
|
781
|
+
if (success) {
|
|
782
|
+
this.startHealthCheck(unhealthy);
|
|
783
|
+
unhealthy.isRestarting = false;
|
|
784
|
+
unhealthy.isStarted = true;
|
|
785
|
+
}
|
|
786
|
+
else {
|
|
754
787
|
for (let i = 0; i < 60 && !stopRequested; i++)
|
|
755
788
|
yield (0, sleep_1.sleep)(1000);
|
|
756
789
|
}
|
|
@@ -762,6 +795,7 @@ let DeviceRideService = (() => {
|
|
|
762
795
|
return __awaiter(this, void 0, void 0, function* () {
|
|
763
796
|
yield this.lazyInit();
|
|
764
797
|
const adapters = this.getSelectedAdapters();
|
|
798
|
+
this.rideAdapters = adapters;
|
|
765
799
|
this.emit('start-request', adapters === null || adapters === void 0 ? void 0 : adapters.map(this.getAdapterStateInfo.bind(this)));
|
|
766
800
|
const goodToGo = yield this.waitForPreviousStartToFinish();
|
|
767
801
|
if (!goodToGo)
|
|
@@ -773,8 +807,8 @@ let DeviceRideService = (() => {
|
|
|
773
807
|
startRetry(props) {
|
|
774
808
|
return __awaiter(this, void 0, void 0, function* () {
|
|
775
809
|
yield this.lazyInit();
|
|
776
|
-
const
|
|
777
|
-
this.emit('start-request',
|
|
810
|
+
const selected = this.getSelectedAdapters();
|
|
811
|
+
this.emit('start-request', selected === null || selected === void 0 ? void 0 : selected.map(this.getAdapterStateInfo));
|
|
778
812
|
const adapters = this.getSelectedAdapters().filter(ai => !ai.adapter.isStarted());
|
|
779
813
|
const goodToGo = yield this.waitForPreviousStartToFinish();
|
|
780
814
|
if (!goodToGo)
|
|
@@ -802,6 +836,7 @@ let DeviceRideService = (() => {
|
|
|
802
836
|
});
|
|
803
837
|
yield Promise.allSettled(promises);
|
|
804
838
|
this.startPromises = null;
|
|
839
|
+
delete this.rideAdapters;
|
|
805
840
|
return true;
|
|
806
841
|
});
|
|
807
842
|
}
|
|
@@ -818,7 +853,7 @@ let DeviceRideService = (() => {
|
|
|
818
853
|
this.logEvent({ message: 'stop devices' });
|
|
819
854
|
else
|
|
820
855
|
this.logEvent({ message: 'stop device', udid });
|
|
821
|
-
const adapters = this.
|
|
856
|
+
const adapters = this.rideAdapters;
|
|
822
857
|
this.emit('stop-ride');
|
|
823
858
|
const promises = adapters === null || adapters === void 0 ? void 0 : adapters.filter(ai => udid ? ai.udid === udid : true).map(ai => {
|
|
824
859
|
this.stopHealthCheck(ai);
|
|
@@ -827,6 +862,7 @@ let DeviceRideService = (() => {
|
|
|
827
862
|
});
|
|
828
863
|
if (promises)
|
|
829
864
|
yield Promise.allSettled(promises);
|
|
865
|
+
delete this.rideAdapters;
|
|
830
866
|
return true;
|
|
831
867
|
});
|
|
832
868
|
}
|
|
@@ -855,7 +891,6 @@ let DeviceRideService = (() => {
|
|
|
855
891
|
adapters === null || adapters === void 0 ? void 0 : adapters.forEach(ai => {
|
|
856
892
|
ai.tsLastData = Date.now();
|
|
857
893
|
ai.adapter.resume();
|
|
858
|
-
ai.adapter.on('data', this.deviceDataHandler);
|
|
859
894
|
this.startHealthCheck(ai);
|
|
860
895
|
});
|
|
861
896
|
}
|
|
@@ -931,7 +966,7 @@ let DeviceRideService = (() => {
|
|
|
931
966
|
}
|
|
932
967
|
setLastDataTS(adapterInfo, ts) {
|
|
933
968
|
const udid = adapterInfo.udid;
|
|
934
|
-
|
|
969
|
+
this.lastDataInfo[udid] = ts;
|
|
935
970
|
}
|
|
936
971
|
clearLastDataTS(adapterInfo) {
|
|
937
972
|
const udid = adapterInfo.udid;
|
|
@@ -983,9 +1018,9 @@ let DeviceRideService = (() => {
|
|
|
983
1018
|
const adapters = this.getSelectedAdapters();
|
|
984
1019
|
this.promiseSendUpdate = [];
|
|
985
1020
|
adapters === null || adapters === void 0 ? void 0 : adapters.forEach(ai => {
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
this.promiseSendUpdate.push(
|
|
1021
|
+
var _a, _b, _c;
|
|
1022
|
+
if (((_a = ai === null || ai === void 0 ? void 0 : ai.adapter) === null || _a === void 0 ? void 0 : _a.isControllable()) && ((_b = ai === null || ai === void 0 ? void 0 : ai.adapter) === null || _b === void 0 ? void 0 : _b.isStarted()) && !((_c = ai.adapter) === null || _c === void 0 ? void 0 : _c.isStopped())) {
|
|
1023
|
+
this.promiseSendUpdate.push(ai.adapter.sendUpdate(request));
|
|
989
1024
|
}
|
|
990
1025
|
});
|
|
991
1026
|
yield this.waitForUpdateFinish();
|
|
@@ -1099,10 +1134,9 @@ let DeviceRideService = (() => {
|
|
|
1099
1134
|
if (!currentMode || currentMode.getName() !== mode) {
|
|
1100
1135
|
const adapters = this.getSelectedAdapters();
|
|
1101
1136
|
const adapter = (_a = adapters === null || adapters === void 0 ? void 0 : adapters.find(ai => ai.udid === udid)) === null || _a === void 0 ? void 0 : _a.adapter;
|
|
1102
|
-
if (adapter
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
yield device.sendInitCommands();
|
|
1137
|
+
if (adapter === null || adapter === void 0 ? void 0 : adapter.isControllable()) {
|
|
1138
|
+
adapter.setCyclingMode(mode, settings);
|
|
1139
|
+
yield adapter.sendInitCommands();
|
|
1106
1140
|
}
|
|
1107
1141
|
}
|
|
1108
1142
|
else {
|
|
@@ -8,7 +8,7 @@ import { RouteInfo } from "../base/types";
|
|
|
8
8
|
import { RoutesApiLoader } from "./loaders/api";
|
|
9
9
|
import { MyRoutes } from "./lists/myroutes";
|
|
10
10
|
import { RouteCard, SummaryCardDisplayProps } from "./cards/RouteCard";
|
|
11
|
-
import { RouteStartSettings, SearchFilter, SearchFilterOptions } from "./types";
|
|
11
|
+
import { DisplayType, RouteStartSettings, SearchFilter, SearchFilterOptions } from "./types";
|
|
12
12
|
import { RoutesDbLoader } from "./loaders/db";
|
|
13
13
|
import { RouteListObserver } from "./RouteListObserver";
|
|
14
14
|
import { ActiveImportCard } from "./cards/ActiveImportCard";
|
|
@@ -32,6 +32,8 @@ export declare class RouteListService extends IncyclistService {
|
|
|
32
32
|
}>;
|
|
33
33
|
protected previewProcessing: PromiseObserver<void>;
|
|
34
34
|
protected filters: SearchFilter;
|
|
35
|
+
protected listTop: Record<DisplayType, number>;
|
|
36
|
+
protected displayType: DisplayType;
|
|
35
37
|
constructor();
|
|
36
38
|
setLanguage(language: string): void;
|
|
37
39
|
getLanguage(): string;
|
|
@@ -49,11 +51,23 @@ export declare class RouteListService extends IncyclistService {
|
|
|
49
51
|
routes: SummaryCardDisplayProps[];
|
|
50
52
|
filters: SearchFilter;
|
|
51
53
|
observer: RouteListObserver;
|
|
54
|
+
cards?: undefined;
|
|
55
|
+
} | {
|
|
56
|
+
routes: SummaryCardDisplayProps[];
|
|
57
|
+
cards: RouteCard[];
|
|
58
|
+
filters: SearchFilter;
|
|
59
|
+
observer: RouteListObserver;
|
|
52
60
|
} | {
|
|
53
61
|
routes: any[];
|
|
54
62
|
filters: {};
|
|
55
63
|
observer?: undefined;
|
|
64
|
+
cards?: undefined;
|
|
56
65
|
};
|
|
66
|
+
setListTop(display: number | DisplayType, top?: number): void;
|
|
67
|
+
getListTop(display?: DisplayType): number;
|
|
68
|
+
setDisplayType(displayType: DisplayType): void;
|
|
69
|
+
getDisplayType(): DisplayType;
|
|
70
|
+
isStillLoading(): boolean;
|
|
57
71
|
private applyRouteTypeFilter;
|
|
58
72
|
private applyContentTypeFilter;
|
|
59
73
|
private applyCountryFilter;
|
|
@@ -102,7 +116,8 @@ export declare class RouteListService extends IncyclistService {
|
|
|
102
116
|
list: CardList<Route>;
|
|
103
117
|
};
|
|
104
118
|
protected resetCards(): void;
|
|
105
|
-
protected
|
|
119
|
+
protected getAllSearchCards(): RouteCard[];
|
|
120
|
+
protected getUserSettings(): import("../../settings").UserSettingsService;
|
|
106
121
|
}
|
|
107
122
|
export declare const useRouteList: () => RouteListService;
|
|
108
123
|
export declare const getRouteList: () => RouteListService;
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
3
|
+
var useValue = arguments.length > 2;
|
|
4
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
5
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
6
|
+
}
|
|
7
|
+
return useValue ? value : void 0;
|
|
8
|
+
};
|
|
2
9
|
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
3
10
|
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
4
11
|
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
@@ -26,13 +33,6 @@ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn,
|
|
|
26
33
|
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
27
34
|
done = true;
|
|
28
35
|
};
|
|
29
|
-
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
30
|
-
var useValue = arguments.length > 2;
|
|
31
|
-
for (var i = 0; i < initializers.length; i++) {
|
|
32
|
-
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
33
|
-
}
|
|
34
|
-
return useValue ? value : void 0;
|
|
35
|
-
};
|
|
36
36
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
37
37
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
38
38
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -72,15 +72,21 @@ const selected_1 = require("./lists/selected");
|
|
|
72
72
|
const alternatives_1 = require("./lists/alternatives");
|
|
73
73
|
const utils_1 = require("./utils");
|
|
74
74
|
const utils_2 = require("incyclist-devices/lib/utils/utils");
|
|
75
|
+
const settings_1 = require("../../settings");
|
|
76
|
+
const decorators_1 = require("../../base/decorators");
|
|
75
77
|
let RouteListService = (() => {
|
|
76
78
|
let _classDecorators = [types_1.Singleton];
|
|
77
79
|
let _classDescriptor;
|
|
78
80
|
let _classExtraInitializers = [];
|
|
79
81
|
let _classThis;
|
|
80
82
|
let _classSuper = service_1.IncyclistService;
|
|
83
|
+
let _instanceExtraInitializers = [];
|
|
84
|
+
let _getUserSettings_decorators;
|
|
81
85
|
var RouteListService = _classThis = class extends _classSuper {
|
|
82
86
|
constructor() {
|
|
83
87
|
super('RouteList');
|
|
88
|
+
this.myRoutes = __runInitializers(this, _instanceExtraInitializers);
|
|
89
|
+
this.listTop = { list: undefined, tiles: undefined };
|
|
84
90
|
this.myRoutes = new myroutes_1.MyRoutes('myRoutes', 'My Routes');
|
|
85
91
|
this.selectedRoutes = new selected_1.SelectedRoutes('selected', 'Selected For Me');
|
|
86
92
|
this.alternatives = new alternatives_1.AlternativeRoutes('alternaties', 'Alternatives');
|
|
@@ -130,8 +136,9 @@ let RouteListService = (() => {
|
|
|
130
136
|
this.observer = new RouteListObserver_1.RouteListObserver(this);
|
|
131
137
|
emitStartEvent();
|
|
132
138
|
}
|
|
133
|
-
if (
|
|
134
|
-
this.preload();
|
|
139
|
+
if (this.isStillLoading()) {
|
|
140
|
+
const preload = this.preload();
|
|
141
|
+
preload.start().then(emitLoadedEvent);
|
|
135
142
|
}
|
|
136
143
|
else if (this.initialized) {
|
|
137
144
|
this.unselect();
|
|
@@ -165,7 +172,7 @@ let RouteListService = (() => {
|
|
|
165
172
|
if (requestedFilters)
|
|
166
173
|
this.filters = requestedFilters;
|
|
167
174
|
const filters = requestedFilters || this.filters;
|
|
168
|
-
let routes = Array.from(this.
|
|
175
|
+
let routes = Array.from(this.getAllSearchCards().map(c => c.getDisplayProperties()));
|
|
169
176
|
routes.sort((a, b) => a.title > b.title ? 1 : -1);
|
|
170
177
|
if (!filters) {
|
|
171
178
|
return { routes, filters, observer: this.observer };
|
|
@@ -177,13 +184,33 @@ let RouteListService = (() => {
|
|
|
177
184
|
routes = this.applyCountryFilter(filters, routes);
|
|
178
185
|
routes = this.applyContentTypeFilter(filters, routes);
|
|
179
186
|
routes = this.applyRouteTypeFilter(filters, routes);
|
|
180
|
-
|
|
187
|
+
const cards = routes.map(r => this.getCard(r.id));
|
|
188
|
+
return { routes, cards, filters, observer: this.observer };
|
|
181
189
|
}
|
|
182
190
|
catch (err) {
|
|
183
191
|
this.logError(err, 'search');
|
|
184
192
|
return { routes: [], filters: {} };
|
|
185
193
|
}
|
|
186
194
|
}
|
|
195
|
+
setListTop(display, top) {
|
|
196
|
+
const displayType = typeof display === 'number' ? this.displayType : display;
|
|
197
|
+
const topValue = typeof display === 'number' ? display : top;
|
|
198
|
+
this.listTop[displayType] = topValue;
|
|
199
|
+
}
|
|
200
|
+
getListTop(display = this.displayType) {
|
|
201
|
+
return this.listTop[display];
|
|
202
|
+
}
|
|
203
|
+
setDisplayType(displayType) {
|
|
204
|
+
this.displayType = displayType;
|
|
205
|
+
this.getUserSettings().set('preferences.routeListDisplayType', displayType);
|
|
206
|
+
}
|
|
207
|
+
getDisplayType() {
|
|
208
|
+
var _a;
|
|
209
|
+
return (_a = this.displayType) !== null && _a !== void 0 ? _a : this.getUserSettings().get('preferences.routeListDisplayType', 'list');
|
|
210
|
+
}
|
|
211
|
+
isStillLoading() {
|
|
212
|
+
return !this.initialized && !this.preloadObserver;
|
|
213
|
+
}
|
|
187
214
|
applyRouteTypeFilter(filters, routes) {
|
|
188
215
|
if (filters.routeType) {
|
|
189
216
|
const loop = filters.routeType === undefined || filters.routeType === 'Loop';
|
|
@@ -264,9 +291,13 @@ let RouteListService = (() => {
|
|
|
264
291
|
try {
|
|
265
292
|
list.getCards().forEach((card, idx) => {
|
|
266
293
|
card.setInitialized(true);
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
294
|
+
});
|
|
295
|
+
process.nextTick(() => {
|
|
296
|
+
list.getCards().forEach((card, idx) => {
|
|
297
|
+
if (idx < item + itemsInSlide) {
|
|
298
|
+
card.setVisible(true);
|
|
299
|
+
}
|
|
300
|
+
});
|
|
270
301
|
});
|
|
271
302
|
setTimeout(() => { this.onCarouselUpdated(list, item, itemsInSlide); }, 1000);
|
|
272
303
|
}
|
|
@@ -751,23 +782,28 @@ let RouteListService = (() => {
|
|
|
751
782
|
});
|
|
752
783
|
});
|
|
753
784
|
}
|
|
754
|
-
|
|
785
|
+
getAllSearchCards() {
|
|
755
786
|
var _a;
|
|
756
787
|
const cards = [];
|
|
757
788
|
(_a = this.getLists(false)) === null || _a === void 0 ? void 0 : _a.forEach(list => {
|
|
758
789
|
list.getCards().forEach((card) => {
|
|
759
|
-
if (card.getCardType() === 'Import' || card.getCardType() === 'Free-Ride')
|
|
790
|
+
if (card.getCardType() === 'Import' || card.getCardType() === 'Free-Ride' || card.getCardType() === 'ActiveImport')
|
|
760
791
|
return;
|
|
761
792
|
cards.push(card);
|
|
762
793
|
});
|
|
763
794
|
});
|
|
764
795
|
return cards;
|
|
765
796
|
}
|
|
797
|
+
getUserSettings() {
|
|
798
|
+
return (0, settings_1.useUserSettings)();
|
|
799
|
+
}
|
|
766
800
|
};
|
|
767
801
|
__setFunctionName(_classThis, "RouteListService");
|
|
768
802
|
(() => {
|
|
769
803
|
var _a;
|
|
770
804
|
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create((_a = _classSuper[Symbol.metadata]) !== null && _a !== void 0 ? _a : null) : void 0;
|
|
805
|
+
_getUserSettings_decorators = [decorators_1.Injectable];
|
|
806
|
+
__esDecorate(_classThis, null, _getUserSettings_decorators, { kind: "method", name: "getUserSettings", static: false, private: false, access: { has: obj => "getUserSettings" in obj, get: obj => obj.getUserSettings }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
771
807
|
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
772
808
|
RouteListService = _classThis = _classDescriptor.value;
|
|
773
809
|
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "incyclist-services",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.10",
|
|
4
4
|
"peerDependencies": {
|
|
5
5
|
"gd-eventlog": "^0.1.26"
|
|
6
6
|
},
|
|
@@ -10,14 +10,14 @@
|
|
|
10
10
|
"@typescript-eslint/eslint-plugin": "^8.19.0",
|
|
11
11
|
"@typescript-eslint/parser": "^8.18.2",
|
|
12
12
|
"dotenv": "^16.4.7",
|
|
13
|
-
"eslint": "^9.
|
|
13
|
+
"eslint": "^9.18.0",
|
|
14
14
|
"formdata-node": "^6.0.3",
|
|
15
15
|
"jest": "^29.7.0",
|
|
16
16
|
"jsdoc": "^4.0.4",
|
|
17
17
|
"ts-jest": "^29.2.5",
|
|
18
18
|
"typedoc": "^0.27.4",
|
|
19
19
|
"typedoc-plugin-markdown": "^4.3.2",
|
|
20
|
-
"typedoc-plugin-no-inherit": "^1.
|
|
20
|
+
"typedoc-plugin-no-inherit": "^1.5.0",
|
|
21
21
|
"typescript": "^5.7.2"
|
|
22
22
|
},
|
|
23
23
|
"scripts": {
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"axios": "^1.7.7",
|
|
45
|
-
"incyclist-devices": "^2.3.
|
|
45
|
+
"incyclist-devices": "^2.3.8",
|
|
46
46
|
"promise.any": "^2.0.6",
|
|
47
47
|
"semver": "^7.6.3",
|
|
48
48
|
"tcx-builder": "^1.1.1",
|