@iotize/ionic
Version:
Iotize specific building blocks on top of @ionic/angular.
139 lines • 17.1 kB
JavaScript
import { Injectable } from '@angular/core';
import { filter, first } from 'rxjs/operators';
import { UniqKeyQueue } from './uniq-key-queue';
import { toTapInfoKeyEquals, toTapInfoKeyObject } from './utility';
import { TapInfoCacheService } from './tap-info-cache.service';
import * as i0 from "@angular/core";
import * as i1 from "./tap-info-cache.service";
export class TapInfoRequestService {
constructor(tapInfoCacheService) {
this.tapInfoCacheService = tapInfoCacheService;
/**
* Tap info keys to load queue
*/
this.queue = new UniqKeyQueue(toTapInfoKeyEquals);
this.requestedTapInfoKeysChange = this.queue.queueChange;
}
removeKeys(keys) {
this.queue.remove(...keys);
}
getValue(key) {
return this.getInfoValue(key);
}
getValues(values) {
this.loadKeysIfNotInCache(values);
return Promise.all(values.map((key) => this.tapInfoCacheService.value(key)));
}
reset() {
this.queue.reset();
}
getLoadedKeyInfoChange(info) {
this.loadKeyIfNotInCache(info);
return this.tapInfoCacheService.infoChange(info).pipe(filter((info) => {
return info.error !== undefined || info.value !== undefined;
}));
}
/**
* Refresh all keys
*/
async refreshKeys(keysToRefresh) {
return this._refreshKeys(keysToRefresh, true);
}
async _refreshKeys(keysToRefresh, clearCache) {
// Append to refresh keys list. If we show dialog before nfc tap is done, it will
// append keys to the refresh list
if (clearCache) {
const keys = keysToRefresh.map((key) => toTapInfoKeyObject(key));
this.tapInfoCacheService.clearKeys(keys);
this.queue.add(...keys);
}
else {
this.loadKeysIfNotInCache(keysToRefresh);
}
return await this.waitForKeySync(keysToRefresh);
}
/**
* Refresh a single key
* Resolve when refresh has been done (with error or success)
*/
async refreshKey(keyOrString) {
let key = toTapInfoKeyObject(keyOrString);
const nextValue = this.tapInfoCacheService
.infoChange(key)
.pipe(filter((v) => !!v.loadDate), first())
.toPromise();
this.queue.add(key);
return await nextValue;
}
/**
* @warning do not call this method inside executeTapAction or it will hang forever...
* @param allKeys
* @returns
*/
async refreshKeysIfNeeded(allKeys) {
return this._refreshKeys(allKeys, false);
}
/**
* Load key only if it's not already loaded
* @param key key to load
* @returns the info value
*/
async loadKeyIfNotInCache(key) {
const snapshot = this.tapInfoCacheService.getInfoSnapshot(key);
if (!snapshot?.loadDate) {
return this.refreshKey(key);
}
return snapshot;
}
/**
* Load key only if it's not already loaded
* @param key keys to load
*/
loadKeysIfNotInCache(infos) {
const notInCacheKeys = infos.map(toTapInfoKeyObject).filter((key) => {
return !this.tapInfoCacheService.isValueLoaded(key);
});
this.queue.add(...notInCacheKeys);
}
/**
* Load key info
* If key has not been loaded for the device yet, it will to loaded it
* @param key
* @param params
* @returns
*/
loadKeyInfoChange(key) {
key = toTapInfoKeyObject(key);
const obs = this.tapInfoCacheService.infoChange(key);
this.loadKeyIfNotInCache(key);
return obs;
}
/**
*
* @param info: TapInfo
*/
async getInfoValue(info) {
await this.loadKeyIfNotInCache(info);
return this.tapInfoCacheService.value(info);
}
async waitForKeySync(keysToWait) {
if (keysToWait.length === 0) {
return;
}
await this.queue.queueChange
.pipe(filter((currentKeysToRefresh) => {
const remainingKeyToSync = currentKeysToRefresh.find((currentKey) => keysToWait.find((key) => toTapInfoKeyEquals(currentKey, toTapInfoKeyObject(key))));
return !remainingKeyToSync;
}), first())
.toPromise();
}
}
/** @nocollapse */ TapInfoRequestService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: TapInfoRequestService, deps: [{ token: i1.TapInfoCacheService }], target: i0.ɵɵFactoryTarget.Injectable });
/** @nocollapse */ TapInfoRequestService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: TapInfoRequestService, providedIn: 'root' });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: TapInfoRequestService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}], ctorParameters: function () { return [{ type: i1.TapInfoCacheService }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFwLWluZm8tcmVxdWVzdC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaW90aXplLWlvbmljL3NyYy9saWIvdGFwLWluZm8vdGFwLWluZm8tcmVxdWVzdC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHM0MsT0FBTyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQU0vQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLGtCQUFrQixFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRW5FLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDBCQUEwQixDQUFDOzs7QUFPL0QsTUFBTSxPQUFPLHFCQUFxQjtJQVFoQyxZQUFvQixtQkFBd0M7UUFBeEMsd0JBQW1CLEdBQW5CLG1CQUFtQixDQUFxQjtRQVA1RDs7V0FFRztRQUNjLFVBQUssR0FBRyxJQUFJLFlBQVksQ0FBYSxrQkFBa0IsQ0FBQyxDQUFDO1FBRWpFLCtCQUEwQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDO0lBRUUsQ0FBQztJQUVoRSxVQUFVLENBQUMsSUFBa0I7UUFDM0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQztJQUM3QixDQUFDO0lBRUQsUUFBUSxDQUFhLEdBQTZCO1FBQ2hELE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBSSxHQUFHLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQsU0FBUyxDQUNQLE1BQWtDO1FBRWxDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNsQyxPQUFPLE9BQU8sQ0FBQyxHQUFHLENBQ2hCLE1BQU0sQ0FBQyxHQUFHLENBQUMs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QztRQUM3QixDQUFDLENBQUMsRUFDRixLQUFLLEVBQUUsQ0FDUjthQUNBLFNBQVMsRUFBRSxDQUFDO0lBQ2pCLENBQUM7O3NJQWhLVSxxQkFBcUI7MElBQXJCLHFCQUFxQixjQUZwQixNQUFNOzRGQUVQLHFCQUFxQjtrQkFIakMsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBQcm9ncmVzc1N0YXRlIH0gZnJvbSAnQGlvdGl6ZS9jb21tb24vcHJvZ3Jlc3MvYXBpJztcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGZpbHRlciwgZmlyc3QgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQge1xuICBUYXBJbmZvSG9sZGVyLFxuICBUYXBJbmZvS2V5LFxuICBUYXBJbmZvS2V5T2JqZWN0T3JTdHJpbmcsXG59IGZyb20gJy4vZGVmaW5pdGlvbnMnO1xuaW1wb3J0IHsgVW5pcUtleVF1ZXVlIH0gZnJvbSAnLi91bmlxLWtleS1xdWV1ZSc7XG5pbXBvcnQgeyB0b1RhcEluZm9LZXlFcXVhbHMsIHRvVGFwSW5mb0tleU9iamVjdCB9IGZyb20gJy4vdXRpbGl0eSc7XG5cbmltcG9ydCB7IFRhcEluZm9DYWNoZVNlcnZpY2UgfSBmcm9tICcuL3RhcC1pbmZvLWNhY2hlLnNlcnZpY2UnO1xuXG5leHBvcnQgdHlwZSBSZWZyZXNoS2V5c1Byb2dyZXNzU3RhdGUgPSBQcm9ncmVzc1N0YXRlICYge307XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBUYXBJbmZvUmVxdWVzdFNlcnZpY2Uge1xuICAvKipcbiAgICogVGFwIGluZm8ga2V5cyB0byBsb2FkIHF1ZXVlXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHF1ZXVlID0gbmV3IFVuaXFLZXlRdWV1ZTxUYXBJbmZvS2V5Pih0b1RhcEluZm9LZXlFcXVhbHMpO1xuXG4gIHJlYWRvbmx5IHJlcXVlc3RlZFRhcEluZm9LZXlzQ2hhbmdlID0gdGhpcy5xdWV1ZS5xdWV1ZUNoYW5nZTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHRhcEluZm9DYWNoZVNlcnZpY2U6IFRhcEluZm9DYWNoZVNlcnZpY2UpIHt9XG5cbiAgcmVtb3ZlS2V5cyhrZXlzOiBUYXBJbmZvS2V5W10pIHtcbiAgICB0aGlzLnF1ZXVlLnJlbW92ZSguLi5rZXlzKTtcbiAgfVxuXG4gIGdldFZhbHVlPFQgPSBzdHJpbmc+KGtleTogVGFwSW5mb0tleU9iamVjdE9yU3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0SW5mb1ZhbHVlPFQ+KGtleSk7XG4gIH1cblxuICBnZXRWYWx1ZXM8VCBleHRlbmRzIGFueVtdID0gdW5rbm93bltdPihcbiAgICB2YWx1ZXM6IFRhcEluZm9LZXlPYmplY3RPclN0cmluZ1tdXG4gICk6IFByb21pc2U8VD4ge1xuICAgIHRoaXMubG9hZEtleXNJZk5vdEluQ2FjaGUodmFsdWVzKTtcbiAgICByZXR1cm4gUHJvbWlzZS5hbGwoXG4gICAgICB2YWx1ZXMubWFwKChrZXkpID0+IHRoaXMudGFwSW5mb0NhY2hlU2VydmljZS52YWx1ZShrZXkpKVxuICAgICkgYXMgUHJvbWlzZTxUPjtcbiAgfVxuXG4gIHJlc2V0KCkge1xuICAgIHRoaXMucXVldWUucmVzZXQoKTtcbiAgfVxuXG4gIGdldExvYWRlZEtleUluZm9DaGFuZ2U8VD4oXG4gICAgaW5mbzogVGFwSW5mb0tleU9iamVjdE9yU3RyaW5nXG4gICk6IE9ic2VydmFibGU8VGFwSW5mb0hvbGRlcjxUPj4ge1xuICAgIHRoaXMubG9hZEtleUlmTm90SW5DYWNoZShpbmZvKTtcbiAgICByZXR1cm4gdGhpcy50YXBJbmZvQ2FjaGVTZXJ2aWNlLmluZm9DaGFuZ2U8VD4oaW5mbykucGlwZShcbiAgICAgIGZpbHRlcigoaW5mbykgPT4ge1xuICAgICAgICByZXR1cm4gaW5mby5lcnJvciAhPT0gdW5kZWZpbmVkIHx8IGluZm8udmFsdWUgIT09IHVuZGVmaW5lZDtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWZyZXNoIGFsbCBrZXlzXG4gICAqL1xuICBhc3luYyByZWZyZXNoS2V5cyhrZXlzVG9SZWZyZXNoOiBUYXBJbmZvS2V5T2JqZWN0T3JTdHJpbmdbXSkge1xuICAgIHJldHVybiB0aGlzLl9yZWZyZXNoS2V5cyhrZXlzVG9SZWZyZXNoLCB0cnVlKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgX3JlZnJlc2hLZXlzKFxuICAgIGtleXNUb1JlZnJlc2g6IFRhcEluZm9LZXlPYmplY3RPclN0cmluZ1tdLFxuICAgIGNsZWFyQ2FjaGU6IGJvb2xlYW5cbiAgKSB7XG4gICAgLy8gQXBwZW5kIHRvIHJlZnJlc2gga2V5cyBsaXN0LiBJZiB3ZSBzaG93IGRpYWxvZyBiZWZvcmUgbmZjIHRhcCBpcyBkb25lLCBpdCB3aWxsXG4gICAgLy8gYXBwZW5kIGtleXMgdG8gdGhlIHJlZnJlc2ggbGlzdFxuICAgIGlmIChjbGVhckNhY2hlKSB7XG4gICAgICBjb25zdCBrZXlzID0ga2V5c1RvUmVmcmVzaC5tYXAoKGtleSkgPT4gdG9UYXBJbmZvS2V5T2JqZWN0KGtleSkpO1xuICAgICAgdGhpcy50YXBJbmZvQ2FjaGVTZXJ2aWNlLmNsZWFyS2V5cyhrZXlzKTtcbiAgICAgIHRoaXMucXVldWUuYWRkKC4uLmtleXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxvYWRLZXlzSWZOb3RJbkNhY2hlKGtleXNUb1JlZnJlc2gpO1xuICAgIH1cbiAgICByZXR1cm4gYXdhaXQgdGhpcy53YWl0Rm9yS2V5U3luYyhrZXlzVG9SZWZyZXNoKTtcbiAgfVxuICAvKipcbiAgICogUmVmcmVzaCBhIHNpbmdsZSBrZXlcbiAgICogUmVzb2x2ZSB3aGVuIHJlZnJlc2ggaGFzIGJlZW4gZG9uZSAod2l0aCBlcnJvciBvciBzdWNjZXNzKVxuICAgKi9cbiAgYXN5bmMgcmVmcmVzaEtleTxUPihcbiAgICBrZXlPclN0cmluZzogVGFwSW5mb0tleU9iamVjdE9yU3RyaW5nXG4gICk6IFByb21pc2U8VGFwSW5mb0hvbGRlcjxUPj4ge1xuICAgIGxldCBrZXkgPSB0b1RhcEluZm9LZXlPYmplY3Qoa2V5T3JTdHJpbmcpO1xuICAgIGNvbnN0IG5leHRWYWx1ZSA9IHRoaXMudGFwSW5mb0NhY2hlU2VydmljZVxuICAgICAgLmluZm9DaGFuZ2U8VD4oa2V5KVxuICAgICAgLnBpcGUoXG4gICAgICAgIGZpbHRlcigodikgPT4gISF2LmxvYWREYXRlKSxcbiAgICAgICAgZmlyc3QoKVxuICAgICAgKVxuICAgICAgLnRvUHJvbWlzZSgpIGFzIFByb21pc2U8VGFwSW5mb0hvbGRlcjxUPj47XG4gICAgdGhpcy5xdWV1ZS5hZGQoa2V5KTtcbiAgICByZXR1cm4gYXdhaXQgbmV4dFZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEB3YXJuaW5nIGRvIG5vdCBjYWxsIHRoaXMgbWV0aG9kIGluc2lkZSBleGVjdXRlVGFwQWN0aW9uIG9yIGl0IHdpbGwgaGFuZyBmb3JldmVyLi4uXG4gICAqIEBwYXJhbSBhbGxLZXlzXG4gICAqIEByZXR1cm5zXG4gICAqL1xuICBhc3luYyByZWZyZXNoS2V5c0lmTmVlZGVkKGFsbEtleXM6IFRhcEluZm9LZXlPYmplY3RPclN0cmluZ1tdKSB7XG4gICAgcmV0dXJuIHRoaXMuX3JlZnJlc2hLZXlzKGFsbEtleXMsIGZhbHNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkIGtleSBvbmx5IGlmIGl0J3Mgbm90IGFscmVhZHkgbG9hZGVkXG4gICAqIEBwYXJhbSBrZXkga2V5IHRvIGxvYWRcbiAgICogQHJldHVybnMgdGhlIGluZm8gdmFsdWVcbiAgICovXG4gIGFzeW5jIGxvYWRLZXlJZk5vdEluQ2FjaGU8VD4oXG4gICAga2V5OiBUYXBJbmZvS2V5T2JqZWN0T3JTdHJpbmdcbiAgKTogUHJvbWlzZTxUYXBJbmZvSG9sZGVyPFQ+PiB7XG4gICAgY29uc3Qgc25hcHNob3QgPSB0aGlzLnRhcEluZm9DYWNoZVNlcnZpY2UuZ2V0SW5mb1NuYXBzaG90PFQ+KGtleSk7XG4gICAgaWYgKCFzbmFwc2hvdD8ubG9hZERhdGUpIHtcbiAgICAgIHJldHVybiB0aGlzLnJlZnJlc2hLZXk8VD4oa2V5KTtcbiAgICB9XG4gICAgcmV0dXJuIHNuYXBzaG90O1xuICB9XG5cbiAgLyoqXG4gICAqIExvYWQga2V5IG9ubHkgaWYgaXQncyBub3QgYWxyZWFkeSBsb2FkZWRcbiAgICogQHBhcmFtIGtleSBrZXlzIHRvIGxvYWRcbiAgICovXG4gIGxvYWRLZXlzSWZOb3RJbkNhY2hlKGluZm9zOiBUYXBJbmZvS2V5T2JqZWN0T3JTdHJpbmdbXSkge1xuICAgIGNvbnN0IG5vdEluQ2FjaGVLZXlzID0gaW5mb3MubWFwKHRvVGFwSW5mb0tleU9iamVjdCkuZmlsdGVyKChrZXkpID0+IHtcbiAgICAgIHJldHVybiAhdGhpcy50YXBJbmZvQ2FjaGVTZXJ2aWNlLmlzVmFsdWVMb2FkZWQoa2V5KTtcbiAgICB9KTtcbiAgICB0aGlzLnF1ZXVlLmFkZCguLi5ub3RJbkNhY2hlS2V5cyk7XG4gIH1cblxuICAvKipcbiAgICogTG9hZCBrZXkgaW5mb1xuICAgKiBJZiBrZXkgaGFzIG5vdCBiZWVuIGxvYWRlZCBmb3IgdGhlIGRldmljZSB5ZXQsIGl0IHdpbGwgdG8gbG9hZGVkIGl0XG4gICAqIEBwYXJhbSBrZXlcbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKiBAcmV0dXJuc1xuICAgKi9cbiAgbG9hZEtleUluZm9DaGFuZ2U8VD4oXG4gICAga2V5OiBUYXBJbmZvS2V5T2JqZWN0T3JTdHJpbmdcbiAgKTogT2JzZXJ2YWJsZTxUYXBJbmZvSG9sZGVyPFQ+PiB7XG4gICAga2V5ID0gdG9UYXBJbmZvS2V5T2JqZWN0KGtleSk7XG4gICAgY29uc3Qgb2JzID0gdGhpcy50YXBJbmZvQ2FjaGVTZXJ2aWNlLmluZm9DaGFuZ2U8VD4oa2V5KTtcbiAgICB0aGlzLmxvYWRLZXlJZk5vdEluQ2FjaGUoa2V5KTtcbiAgICByZXR1cm4gb2JzO1xuICB9XG5cbiAgLyoqXG4gICAqXG4gICAqIEBwYXJhbSBpbmZvOiBUYXBJbmZvXG4gICAqL1xuICBhc3luYyBnZXRJbmZvVmFsdWU8VCA9IHN0cmluZz4oaW5mbzogVGFwSW5mb0tleU9iamVjdE9yU3RyaW5nKTogUHJvbWlzZTxUPiB7XG4gICAgYXdhaXQgdGhpcy5sb2FkS2V5SWZOb3RJbkNhY2hlPFQ+KGluZm8pO1xuICAgIHJldHVybiB0aGlzLnRhcEluZm9DYWNoZVNlcnZpY2UudmFsdWUoaW5mbyk7XG4gIH1cblxuICBhc3luYyB3YWl0Rm9yS2V5U3luYyhrZXlzVG9XYWl0OiBUYXBJbmZvS2V5T2JqZWN0T3JTdHJpbmdbXSkge1xuICAgIGlmIChrZXlzVG9XYWl0Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBhd2FpdCB0aGlzLnF1ZXVlLnF1ZXVlQ2hhbmdlXG4gICAgICAucGlwZShcbiAgICAgICAgZmlsdGVyKChjdXJyZW50S2V5c1RvUmVmcmVzaCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHJlbWFpbmluZ0tleVRvU3luYyA9IGN1cnJlbnRLZXlzVG9SZWZyZXNoLmZpbmQoKGN1cnJlbnRLZXkpID0+XG4gICAgICAgICAgICBrZXlzVG9XYWl0LmZpbmQoKGtleSkgPT5cbiAgICAgICAgICAgICAgdG9UYXBJbmZvS2V5RXF1YWxzKGN1cnJlbnRLZXksIHRvVGFwSW5mb0tleU9iamVjdChrZXkpKVxuICAgICAgICAgICAgKVxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuICFyZW1haW5pbmdLZXlUb1N5bmM7XG4gICAgICAgIH0pLFxuICAgICAgICBmaXJzdCgpXG4gICAgICApXG4gICAgICAudG9Qcm9taXNlKCk7XG4gIH1cbn1cbiJdfQ==