@zajno/common 1.4.4 → 1.4.5
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/.nvmrc +1 -1
- package/README.md +5 -5
- package/coverage/clover.xml +387 -106
- package/coverage/coverage-final.json +17 -12
- package/coverage/lcov-report/index.html +38 -38
- package/coverage/lcov-report/src/__tests__/helpers/index.html +1 -1
- package/coverage/lcov-report/src/__tests__/helpers/main.ts.html +1 -1
- package/coverage/lcov-report/src/async/arrays.ts.html +1 -1
- package/coverage/lcov-report/src/async/index.html +24 -9
- package/coverage/lcov-report/src/async/timeout.ts.html +230 -0
- package/coverage/lcov-report/src/cache.ts.html +623 -0
- package/coverage/lcov-report/src/dates/calc.ts.html +1 -1
- package/coverage/lcov-report/src/dates/convert.ts.html +1 -1
- package/coverage/lcov-report/src/dates/datex.ts.html +1 -1
- package/coverage/lcov-report/src/dates/format.ts.html +1 -1
- package/coverage/lcov-report/src/dates/index.html +1 -1
- package/coverage/lcov-report/src/dates/index.ts.html +1 -1
- package/coverage/lcov-report/src/dates/parse.ts.html +1 -1
- package/coverage/lcov-report/src/dates/period.ts.html +1 -1
- package/coverage/lcov-report/src/dates/shift.ts.html +1 -1
- package/coverage/lcov-report/src/dates/types.ts.html +1 -1
- package/coverage/lcov-report/src/dates/yearDate.ts.html +1 -1
- package/coverage/lcov-report/src/disposer.ts.html +332 -0
- package/coverage/lcov-report/src/enumHelper.ts.html +1 -1
- package/coverage/lcov-report/src/event.ts.html +1 -1
- package/coverage/lcov-report/src/fields/index.html +1 -1
- package/coverage/lcov-report/src/fields/update.ts.html +1 -1
- package/coverage/lcov-report/src/functions.ts.html +1 -1
- package/coverage/lcov-report/src/index.html +70 -10
- package/coverage/lcov-report/src/lazy.light.ts.html +1 -1
- package/coverage/lcov-report/src/logger/batch.ts.html +2 -2
- package/coverage/lcov-report/src/logger/console.ts.html +5 -5
- package/coverage/lcov-report/src/logger/index.html +1 -1
- package/coverage/lcov-report/src/logger/index.ts.html +22 -22
- package/coverage/lcov-report/src/logger/named.ts.html +13 -13
- package/coverage/lcov-report/src/logger/proxy.ts.html +7 -7
- package/coverage/lcov-report/src/math/arrays.ts.html +23 -23
- package/coverage/lcov-report/src/math/calc.ts.html +9 -9
- package/coverage/lcov-report/src/math/distribution.ts.html +2 -2
- package/coverage/lcov-report/src/math/index.html +1 -1
- package/coverage/lcov-report/src/math/index.ts.html +6 -6
- package/coverage/lcov-report/src/observers.ts.html +368 -0
- package/coverage/lcov-report/src/observersMap.ts.html +395 -0
- package/coverage/lcov-report/src/observingCache.ts.html +485 -0
- package/coverage/lcov-report/src/transitionObserver.ts.html +1 -1
- package/coverage/lcov-report/src/types.ts.html +5 -5
- package/coverage/lcov-report/src/validation/ValidationErrors.ts.html +1 -1
- package/coverage/lcov-report/src/validation/creditCard.ts.html +1 -1
- package/coverage/lcov-report/src/validation/helpers.ts.html +1 -1
- package/coverage/lcov-report/src/validation/index.html +1 -1
- package/coverage/lcov-report/src/validation/index.ts.html +1 -1
- package/coverage/lcov-report/src/validation/types.ts.html +1 -1
- package/coverage/lcov-report/src/validation/validators.ts.html +1 -1
- package/coverage/lcov-report/src/validation/wrappers.ts.html +1 -1
- package/coverage/lcov-report/src/viewModels/FlagModel.ts.html +1 -1
- package/coverage/lcov-report/src/viewModels/MultiSelectModel.ts.html +1 -1
- package/coverage/lcov-report/src/viewModels/NumberModel.ts.html +24 -24
- package/coverage/lcov-report/src/viewModels/SelectModel.ts.html +1 -1
- package/coverage/lcov-report/src/viewModels/Validatable.ts.html +1 -1
- package/coverage/lcov-report/src/viewModels/index.html +15 -15
- package/coverage/lcov-report/src/viewModels/wrappers.ts.html +1 -1
- package/coverage/lcov.info +724 -130
- package/lib/cache.d.ts +6 -2
- package/lib/cache.d.ts.map +1 -1
- package/lib/cache.js +20 -4
- package/lib/cache.js.map +1 -1
- package/lib/observersMap.d.ts +22 -0
- package/lib/observersMap.d.ts.map +1 -0
- package/lib/{observers.js → observersMap.js} +30 -11
- package/lib/observersMap.js.map +1 -0
- package/lib/observingCache.d.ts +29 -0
- package/lib/observingCache.d.ts.map +1 -0
- package/lib/observingCache.js +107 -0
- package/lib/observingCache.js.map +1 -0
- package/package.json +1 -1
- package/src/__tests__/observingCache.test.ts +127 -0
- package/src/cache.ts +25 -4
- package/src/{observers.ts → observersMap.ts} +32 -9
- package/src/observingCache.ts +135 -0
- package/lib/observers.d.ts +0 -16
- package/lib/observers.d.ts.map +0 -1
- package/lib/observers.js.map +0 -1
|
@@ -1,23 +1,33 @@
|
|
|
1
1
|
import { createLogger, ILogger } from './logger';
|
|
2
2
|
import { combineDisposers, IDisposable } from './disposer';
|
|
3
|
+
import { NumberModel } from './viewModels/NumberModel';
|
|
3
4
|
|
|
4
5
|
type Unsub = () => void;
|
|
5
6
|
|
|
6
|
-
export class
|
|
7
|
+
export class ObserversMap implements IDisposable {
|
|
8
|
+
/** Unsusbcrobers map: key => unsub fn */
|
|
7
9
|
private readonly _map = new Map<string, () => void>();
|
|
10
|
+
/** Timeouts map: key => timeout handle */
|
|
8
11
|
private readonly _timeouts = new Map<string, any>();
|
|
9
12
|
|
|
10
13
|
private readonly _logger: ILogger = null;
|
|
14
|
+
private readonly _count = new NumberModel();
|
|
11
15
|
|
|
12
|
-
constructor(readonly subscribe: (key: string) => Promise<Unsub[]
|
|
16
|
+
constructor(readonly subscribe: null | ((key: string) => Promise<Unsub[]>), readonly name?: string) {
|
|
13
17
|
this._logger = createLogger(`[Observers:${this.name || '?'}]`);
|
|
14
18
|
}
|
|
15
19
|
|
|
20
|
+
public get count() { return this._count.value; }
|
|
21
|
+
|
|
16
22
|
public getIsObserving(key: string) {
|
|
17
23
|
return this._map.has(key);
|
|
18
24
|
}
|
|
19
25
|
|
|
20
|
-
public
|
|
26
|
+
public getHasObserveTimeout(key: string) {
|
|
27
|
+
return this.getIsObserving(key) && this._timeouts.has(key);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public async enable(key: string, enable: boolean, clearAfter: number = null, existingUnsubs: Unsub[] = null) {
|
|
21
31
|
if (enable === this.getIsObserving(key)) {
|
|
22
32
|
this.refreshTimeout(key, enable, clearAfter, true);
|
|
23
33
|
return;
|
|
@@ -32,13 +42,18 @@ export class Observers implements IDisposable {
|
|
|
32
42
|
|
|
33
43
|
this._map.set(key, marker);
|
|
34
44
|
|
|
35
|
-
|
|
45
|
+
if (!this.subscribe && !existingUnsubs) {
|
|
46
|
+
throw new Error('Neither subscribe function nor existingUnsubs has been configured');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const unsubs = existingUnsubs || await this.subscribe(key);
|
|
36
50
|
const result = combineDisposers(...unsubs);
|
|
37
51
|
|
|
38
52
|
if (disabed) { // unsubscribe was requested
|
|
39
53
|
result();
|
|
40
54
|
} else {
|
|
41
55
|
this._map.set(key, result);
|
|
56
|
+
this._count.increment();
|
|
42
57
|
this.refreshTimeout(key, true, clearAfter);
|
|
43
58
|
}
|
|
44
59
|
} else {
|
|
@@ -47,6 +62,7 @@ export class Observers implements IDisposable {
|
|
|
47
62
|
const unsub = this._map.get(key);
|
|
48
63
|
this._map.delete(key);
|
|
49
64
|
unsub();
|
|
65
|
+
this._count.decrement();
|
|
50
66
|
}
|
|
51
67
|
}
|
|
52
68
|
|
|
@@ -68,15 +84,22 @@ export class Observers implements IDisposable {
|
|
|
68
84
|
}
|
|
69
85
|
}
|
|
70
86
|
|
|
71
|
-
public
|
|
87
|
+
public clear() {
|
|
88
|
+
// Clear timeouts
|
|
89
|
+
for (const t of this._timeouts.values()) {
|
|
90
|
+
clearTimeout(t);
|
|
91
|
+
}
|
|
92
|
+
this._timeouts.clear();
|
|
93
|
+
|
|
94
|
+
// Invoke unsubscribers
|
|
72
95
|
for (const u of this._map.values()) {
|
|
73
96
|
u();
|
|
74
97
|
}
|
|
75
98
|
this._map.clear();
|
|
99
|
+
this._count.setValue(0);
|
|
100
|
+
}
|
|
76
101
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
this._timeouts.clear();
|
|
102
|
+
public dispose() {
|
|
103
|
+
this.clear();
|
|
81
104
|
}
|
|
82
105
|
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { action } from 'mobx';
|
|
2
|
+
import { Disposable } from './disposer';
|
|
3
|
+
import { PromiseCache, DeferredGetter } from './cache';
|
|
4
|
+
import { ObserversMap } from './observersMap';
|
|
5
|
+
import { Fields } from './fields';
|
|
6
|
+
|
|
7
|
+
export type Unsub = () => void;
|
|
8
|
+
export type Fetcher<T> = (key: string, cb: (val: T) => Promise<void> | void) => Unsub | Promise<Unsub>;
|
|
9
|
+
|
|
10
|
+
type ObserveStrategy = boolean | 'short' | number;
|
|
11
|
+
|
|
12
|
+
export interface IObservingCache<T> {
|
|
13
|
+
get(key: string): DeferredGetter<T>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export class ObservingCache<T> extends Disposable implements IObservingCache<T> {
|
|
17
|
+
|
|
18
|
+
private readonly _cache: PromiseCache<T>;
|
|
19
|
+
private readonly _observers: ObserversMap;
|
|
20
|
+
|
|
21
|
+
private _observeStrategy: ObserveStrategy = null;
|
|
22
|
+
private readonly _observeStrategyOverrides: Record<string, ObserveStrategy> = { };
|
|
23
|
+
|
|
24
|
+
private _updater: Fields.Updater<T> = null;
|
|
25
|
+
|
|
26
|
+
constructor(readonly fetcher: Fetcher<T>) {
|
|
27
|
+
super();
|
|
28
|
+
|
|
29
|
+
this._cache = new PromiseCache(this._fetch);
|
|
30
|
+
this._observers = new ObserversMap(this._subscribe);
|
|
31
|
+
|
|
32
|
+
this.disposer.add(this._observers);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public get loadingCount() { return this._cache.busyCount; }
|
|
36
|
+
public get observersCount() { return this._observers.count; }
|
|
37
|
+
|
|
38
|
+
useObservingStrategy(observe: ObserveStrategy) {
|
|
39
|
+
this._observeStrategy = observe;
|
|
40
|
+
if (!this._observeStrategy) {
|
|
41
|
+
this._observers.clear();
|
|
42
|
+
} else {
|
|
43
|
+
const currentKeys = this._cache.keys();
|
|
44
|
+
const timeout = getObserveTimeout(this._observeStrategy);
|
|
45
|
+
currentKeys.forEach(key => this._observers.enable(key, true, timeout));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
useUpdater(updater: Fields.Updater<T>) {
|
|
52
|
+
this._updater = updater;
|
|
53
|
+
this._cache.useObserveItems(updater != null);
|
|
54
|
+
return this;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
get(key: string, overrideStrategy?: ObserveStrategy): DeferredGetter<T> {
|
|
58
|
+
this._observeStrategyOverrides[key] = overrideStrategy;
|
|
59
|
+
|
|
60
|
+
const strategy = overrideStrategy || this._observeStrategy;
|
|
61
|
+
if (strategy && !this._observers.getIsObserving(key)) {
|
|
62
|
+
// ensure observe
|
|
63
|
+
if (this._cache.hasKey(key)) {
|
|
64
|
+
// the request has been initiated already
|
|
65
|
+
const timeout = getObserveTimeout(strategy);
|
|
66
|
+
this._observers.enable(key, true, timeout);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return this._cache.getDeferred(key);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
populate = (key: string, item: T) => {
|
|
74
|
+
this._updateItem(key, item);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
private _fetch = async (key: string): Promise<T> => {
|
|
78
|
+
let firstLoad = true;
|
|
79
|
+
|
|
80
|
+
return new Promise<T>((resolve) => {
|
|
81
|
+
Promise.resolve<Unsub>(
|
|
82
|
+
this.fetcher(key, item => {
|
|
83
|
+
if (firstLoad) {
|
|
84
|
+
resolve(item);
|
|
85
|
+
firstLoad = false;
|
|
86
|
+
} else {
|
|
87
|
+
this._updateItem(key, item);
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
).then(unsub => {
|
|
91
|
+
const strategy = this._observeStrategyOverrides[key] || this._observeStrategy;
|
|
92
|
+
if (!strategy) {
|
|
93
|
+
// immediate unsub in case no observing strategy has been set
|
|
94
|
+
unsub();
|
|
95
|
+
} else {
|
|
96
|
+
const timeout = getObserveTimeout(strategy);
|
|
97
|
+
this._observers.enable(key, true, timeout, [unsub]);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
private _subscribe = (key: string) => {
|
|
104
|
+
return Promise.all([
|
|
105
|
+
this.fetcher(key, item => this._updateItem(key, item)),
|
|
106
|
+
]);
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
private _updateItem = action((key: string, item: T) => {
|
|
110
|
+
if (this._updater != null) {
|
|
111
|
+
const current = this._cache.getCurrent(key, false);
|
|
112
|
+
if (current != null) {
|
|
113
|
+
const result = this._updater(current, item);
|
|
114
|
+
// re-set existing item but with updated contents
|
|
115
|
+
this._cache.updateValueDirectly(key, result);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
this._cache.updateValueDirectly(key, item);
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function getObserveTimeout(s: ObserveStrategy) {
|
|
125
|
+
if (!s) {
|
|
126
|
+
return undefined;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return typeof s === 'number'
|
|
130
|
+
? s
|
|
131
|
+
: (s === 'short'
|
|
132
|
+
? 5 * 60 * 1000
|
|
133
|
+
: null
|
|
134
|
+
);
|
|
135
|
+
}
|
package/lib/observers.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { IDisposable } from './disposer';
|
|
2
|
-
declare type Unsub = () => void;
|
|
3
|
-
export declare class Observers implements IDisposable {
|
|
4
|
-
readonly subscribe: (key: string) => Promise<Unsub[]>;
|
|
5
|
-
readonly name?: string;
|
|
6
|
-
private readonly _map;
|
|
7
|
-
private readonly _timeouts;
|
|
8
|
-
private readonly _logger;
|
|
9
|
-
constructor(subscribe: (key: string) => Promise<Unsub[]>, name?: string);
|
|
10
|
-
getIsObserving(key: string): boolean;
|
|
11
|
-
enable(key: string, enable: boolean, clearAfter?: number): Promise<void>;
|
|
12
|
-
private refreshTimeout;
|
|
13
|
-
dispose(): void;
|
|
14
|
-
}
|
|
15
|
-
export {};
|
|
16
|
-
//# sourceMappingURL=observers.d.ts.map
|
package/lib/observers.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"observers.d.ts","sourceRoot":"","sources":["../src/observers.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,WAAW,EAAE,MAAM,YAAY,CAAC;AAE3D,aAAK,KAAK,GAAG,MAAM,IAAI,CAAC;AAExB,qBAAa,SAAU,YAAW,WAAW;IAM7B,QAAQ,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,EAAE,CAAC;IAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM;IALzF,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiC;IACtD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0B;IAEpD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;gBAEpB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,EAAE,CAAC,EAAW,IAAI,CAAC,EAAE,MAAM;IAIlF,cAAc,CAAC,GAAG,EAAE,MAAM;IAIpB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAE,MAAa;IAiC3E,OAAO,CAAC,cAAc;IAkBf,OAAO;CAWjB"}
|
package/lib/observers.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"observers.js","sourceRoot":"","sources":["../src/observers.ts"],"names":[],"mappings":"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"}
|