@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.
Files changed (82) hide show
  1. package/.nvmrc +1 -1
  2. package/README.md +5 -5
  3. package/coverage/clover.xml +387 -106
  4. package/coverage/coverage-final.json +17 -12
  5. package/coverage/lcov-report/index.html +38 -38
  6. package/coverage/lcov-report/src/__tests__/helpers/index.html +1 -1
  7. package/coverage/lcov-report/src/__tests__/helpers/main.ts.html +1 -1
  8. package/coverage/lcov-report/src/async/arrays.ts.html +1 -1
  9. package/coverage/lcov-report/src/async/index.html +24 -9
  10. package/coverage/lcov-report/src/async/timeout.ts.html +230 -0
  11. package/coverage/lcov-report/src/cache.ts.html +623 -0
  12. package/coverage/lcov-report/src/dates/calc.ts.html +1 -1
  13. package/coverage/lcov-report/src/dates/convert.ts.html +1 -1
  14. package/coverage/lcov-report/src/dates/datex.ts.html +1 -1
  15. package/coverage/lcov-report/src/dates/format.ts.html +1 -1
  16. package/coverage/lcov-report/src/dates/index.html +1 -1
  17. package/coverage/lcov-report/src/dates/index.ts.html +1 -1
  18. package/coverage/lcov-report/src/dates/parse.ts.html +1 -1
  19. package/coverage/lcov-report/src/dates/period.ts.html +1 -1
  20. package/coverage/lcov-report/src/dates/shift.ts.html +1 -1
  21. package/coverage/lcov-report/src/dates/types.ts.html +1 -1
  22. package/coverage/lcov-report/src/dates/yearDate.ts.html +1 -1
  23. package/coverage/lcov-report/src/disposer.ts.html +332 -0
  24. package/coverage/lcov-report/src/enumHelper.ts.html +1 -1
  25. package/coverage/lcov-report/src/event.ts.html +1 -1
  26. package/coverage/lcov-report/src/fields/index.html +1 -1
  27. package/coverage/lcov-report/src/fields/update.ts.html +1 -1
  28. package/coverage/lcov-report/src/functions.ts.html +1 -1
  29. package/coverage/lcov-report/src/index.html +70 -10
  30. package/coverage/lcov-report/src/lazy.light.ts.html +1 -1
  31. package/coverage/lcov-report/src/logger/batch.ts.html +2 -2
  32. package/coverage/lcov-report/src/logger/console.ts.html +5 -5
  33. package/coverage/lcov-report/src/logger/index.html +1 -1
  34. package/coverage/lcov-report/src/logger/index.ts.html +22 -22
  35. package/coverage/lcov-report/src/logger/named.ts.html +13 -13
  36. package/coverage/lcov-report/src/logger/proxy.ts.html +7 -7
  37. package/coverage/lcov-report/src/math/arrays.ts.html +23 -23
  38. package/coverage/lcov-report/src/math/calc.ts.html +9 -9
  39. package/coverage/lcov-report/src/math/distribution.ts.html +2 -2
  40. package/coverage/lcov-report/src/math/index.html +1 -1
  41. package/coverage/lcov-report/src/math/index.ts.html +6 -6
  42. package/coverage/lcov-report/src/observers.ts.html +368 -0
  43. package/coverage/lcov-report/src/observersMap.ts.html +395 -0
  44. package/coverage/lcov-report/src/observingCache.ts.html +485 -0
  45. package/coverage/lcov-report/src/transitionObserver.ts.html +1 -1
  46. package/coverage/lcov-report/src/types.ts.html +5 -5
  47. package/coverage/lcov-report/src/validation/ValidationErrors.ts.html +1 -1
  48. package/coverage/lcov-report/src/validation/creditCard.ts.html +1 -1
  49. package/coverage/lcov-report/src/validation/helpers.ts.html +1 -1
  50. package/coverage/lcov-report/src/validation/index.html +1 -1
  51. package/coverage/lcov-report/src/validation/index.ts.html +1 -1
  52. package/coverage/lcov-report/src/validation/types.ts.html +1 -1
  53. package/coverage/lcov-report/src/validation/validators.ts.html +1 -1
  54. package/coverage/lcov-report/src/validation/wrappers.ts.html +1 -1
  55. package/coverage/lcov-report/src/viewModels/FlagModel.ts.html +1 -1
  56. package/coverage/lcov-report/src/viewModels/MultiSelectModel.ts.html +1 -1
  57. package/coverage/lcov-report/src/viewModels/NumberModel.ts.html +24 -24
  58. package/coverage/lcov-report/src/viewModels/SelectModel.ts.html +1 -1
  59. package/coverage/lcov-report/src/viewModels/Validatable.ts.html +1 -1
  60. package/coverage/lcov-report/src/viewModels/index.html +15 -15
  61. package/coverage/lcov-report/src/viewModels/wrappers.ts.html +1 -1
  62. package/coverage/lcov.info +724 -130
  63. package/lib/cache.d.ts +6 -2
  64. package/lib/cache.d.ts.map +1 -1
  65. package/lib/cache.js +20 -4
  66. package/lib/cache.js.map +1 -1
  67. package/lib/observersMap.d.ts +22 -0
  68. package/lib/observersMap.d.ts.map +1 -0
  69. package/lib/{observers.js → observersMap.js} +30 -11
  70. package/lib/observersMap.js.map +1 -0
  71. package/lib/observingCache.d.ts +29 -0
  72. package/lib/observingCache.d.ts.map +1 -0
  73. package/lib/observingCache.js +107 -0
  74. package/lib/observingCache.js.map +1 -0
  75. package/package.json +1 -1
  76. package/src/__tests__/observingCache.test.ts +127 -0
  77. package/src/cache.ts +25 -4
  78. package/src/{observers.ts → observersMap.ts} +32 -9
  79. package/src/observingCache.ts +135 -0
  80. package/lib/observers.d.ts +0 -16
  81. package/lib/observers.d.ts.map +0 -1
  82. 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 Observers implements IDisposable {
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[]>, readonly name?: string) {
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 async enable(key: string, enable: boolean, clearAfter: number = null) {
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
- const unsubs = await this.subscribe(key);
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 dispose() {
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
- for (const t of this._timeouts.values()) {
78
- clearTimeout(t);
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
+ }
@@ -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
@@ -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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"observers.js","sourceRoot":"","sources":["../src/observers.ts"],"names":[],"mappings":"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"}