@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
package/lib/cache.d.ts CHANGED
@@ -10,21 +10,25 @@ export declare class PromiseCache<T, K = string> {
10
10
  readonly fetcher: (id: K) => Promise<T>;
11
11
  readonly keyAdapter?: K extends string ? null : (k: K) => string;
12
12
  readonly keyParser?: K extends string ? null : (id: string) => K;
13
- readonly observeItems: boolean;
14
13
  private readonly _itemsCache;
15
14
  private readonly _itemsStatus;
16
15
  private readonly _fetchCache;
17
16
  private _logger;
17
+ private _observeItems;
18
+ private readonly _busyCount;
18
19
  constructor(fetcher: (id: K) => Promise<T>, keyAdapter?: K extends string ? null : (k: K) => string, keyParser?: K extends string ? null : (id: string) => K, observeItems?: boolean);
20
+ get busyCount(): number;
21
+ useObserveItems(observeItems: boolean): this;
19
22
  private _pk;
20
23
  useLogger(name?: string): this;
21
24
  getDeferred(key: K): DeferredGetter<T>;
22
25
  getIsBusy(id: K): boolean;
23
- getCurrent(id: K): T;
26
+ getCurrent(id: K, initiateFetch?: boolean): T;
24
27
  get(id: K): Promise<T>;
25
28
  private _doFetchAsync;
26
29
  invalidate(id: K): void;
27
30
  updateValueDirectly(id: K, value: T): void;
31
+ hasKey(id: K): boolean;
28
32
  keys(): string[];
29
33
  keysParsed(): K[];
30
34
  private _set;
@@ -1 +1 @@
1
- {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAGA,oBAAY,cAAc,CAAC,CAAC,IAAI;IAC5B,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,yBAAiB,cAAc,CAAC;IAErB,MAAM,KAAK,sBAKO,CAAC;CAC7B;AAED,qBAAa,YAAY,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM;IAa/B,QAAQ,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC;IACvC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM;IAChE,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,IAAI,GAAG,CAAC,EAAE,EAAE,MAAM,KAAK,CAAC;IAChE,QAAQ,CAAC,YAAY;IAbzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA0B;IAGtD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgC;IAE7D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAmC;IAE/D,OAAO,CAAC,OAAO,CAAiB;gBAGnB,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,EAC9B,UAAU,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,EACvD,SAAS,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,IAAI,GAAG,CAAC,EAAE,EAAE,MAAM,KAAK,CAAC,EACvD,YAAY,UAAQ;IAKjC,OAAO,CAAC,GAAG;IAgBX,SAAS,CAAC,IAAI,CAAC,EAAE,MAAM;IAKvB,WAAW,CAAC,GAAG,EAAE,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC;IAStC,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,OAAO;IAKzB,UAAU,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC;IAQpB,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAqBtB,OAAO,CAAC,aAAa,CAiBnB;IAEF,UAAU,CAAC,EAAE,EAAE,CAAC;IAKhB,mBAAmB,CAAC,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC;IAKnC,IAAI;IAIJ,UAAU;IASV,OAAO,CAAC,IAAI;CAKf"}
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAIA,oBAAY,cAAc,CAAC,CAAC,IAAI;IAC5B,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,yBAAiB,cAAc,CAAC;IAErB,MAAM,KAAK,sBAKO,CAAC;CAC7B;AAED,qBAAa,YAAY,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM;IAgB/B,QAAQ,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC;IACvC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM;IAChE,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,IAAI,GAAG,CAAC,EAAE,EAAE,MAAM,KAAK,CAAC;IAfpE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA0B;IAGtD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgC;IAE7D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAmC;IAE/D,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,aAAa,CAAS;IAE9B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAsB;gBAGpC,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,EAC9B,UAAU,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,EACvD,SAAS,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,IAAI,GAAG,CAAC,EAAE,EAAE,MAAM,KAAK,CAAC,EAChE,YAAY,UAAQ;IAMxB,IAAW,SAAS,WAAoC;IAExD,eAAe,CAAC,YAAY,EAAE,OAAO;IAKrC,OAAO,CAAC,GAAG;IAgBX,SAAS,CAAC,IAAI,CAAC,EAAE,MAAM;IAKvB,WAAW,CAAC,GAAG,EAAE,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC;IAStC,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,OAAO;IAKzB,UAAU,CAAC,EAAE,EAAE,CAAC,EAAE,aAAa,UAAO,GAAG,CAAC;IAU1C,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAqBtB,OAAO,CAAC,aAAa,CAmBnB;IAEF,UAAU,CAAC,EAAE,EAAE,CAAC;IAKhB,mBAAmB,CAAC,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC;IAKnC,MAAM,CAAC,EAAE,EAAE,CAAC;IAKZ,IAAI;IAIJ,UAAU;IASV,OAAO,CAAC,IAAI;CAKf"}
package/lib/cache.js CHANGED
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PromiseCache = exports.DeferredGetter = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const mobx_1 = require("mobx");
6
+ const NumberModel_1 = require("./viewModels/NumberModel");
6
7
  const logger_1 = require("./logger");
7
8
  var DeferredGetter;
8
9
  (function (DeferredGetter) {
@@ -19,19 +20,21 @@ class PromiseCache {
19
20
  this.fetcher = fetcher;
20
21
  this.keyAdapter = keyAdapter;
21
22
  this.keyParser = keyParser;
22
- this.observeItems = observeItems;
23
23
  this._itemsCache = {};
24
24
  this._itemsStatus = {};
25
25
  this._fetchCache = {};
26
26
  this._logger = null;
27
+ this._observeItems = false;
28
+ this._busyCount = new NumberModel_1.NumberModel(0);
27
29
  this._doFetchAsync = async (id, key) => {
28
30
  var _a;
29
31
  try {
32
+ this._busyCount.increment();
30
33
  const res = await this.fetcher(id);
31
34
  if (this._fetchCache[key]) {
32
35
  (_a = this._logger) === null || _a === void 0 ? void 0 : _a.log(key, 'item\'s <promise> resolved to', res);
33
36
  const result = res
34
- ? (this.observeItems ? mobx_1.observable.object(res) : res)
37
+ ? (this._observeItems ? mobx_1.observable.object(res) : res)
35
38
  : null;
36
39
  mobx_1.runInAction(() => this._itemsCache[key] = result);
37
40
  }
@@ -39,12 +42,19 @@ class PromiseCache {
39
42
  }
40
43
  finally {
41
44
  mobx_1.runInAction(() => {
45
+ this._busyCount.decrement();
42
46
  delete this._fetchCache[key];
43
47
  this._itemsStatus[key] = false;
44
48
  });
45
49
  }
46
50
  };
47
51
  mobx_1.makeObservable(this);
52
+ this._observeItems = observeItems;
53
+ }
54
+ get busyCount() { return this._busyCount.value; }
55
+ useObserveItems(observeItems) {
56
+ this._observeItems = observeItems;
57
+ return this;
48
58
  }
49
59
  _pk(k) {
50
60
  if (k == null) {
@@ -74,11 +84,13 @@ class PromiseCache {
74
84
  const key = this._pk(id);
75
85
  return this._itemsStatus[key];
76
86
  }
77
- getCurrent(id) {
87
+ getCurrent(id, initiateFetch = true) {
78
88
  var _a;
79
89
  const key = this._pk(id);
80
90
  const item = this._itemsCache[key];
81
- this.get(id);
91
+ if (initiateFetch) {
92
+ this.get(id);
93
+ }
82
94
  (_a = this._logger) === null || _a === void 0 ? void 0 : _a.log(key, 'getCurrent returns', item);
83
95
  return item;
84
96
  }
@@ -108,6 +120,10 @@ class PromiseCache {
108
120
  const key = this._pk(id);
109
121
  this._set(key, value, undefined, undefined);
110
122
  }
123
+ hasKey(id) {
124
+ const key = this._pk(id);
125
+ return this._itemsCache[key] !== undefined || this._itemsStatus[key] !== undefined;
126
+ }
111
127
  keys() {
112
128
  return Object.keys(this._itemsCache);
113
129
  }
package/lib/cache.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":";;;;AAAA,+BAAuE;AACvE,qCAAiD;AAQjD,IAAiB,cAAc,CAQ9B;AARD,WAAiB,cAAc;IAC3B,MAAM,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAY,SAAS,CAAC,CAAC;IAClD,oBAAK,GAAG;QACjB,IAAI,OAAO,KAAgB,OAAO,SAAS,CAAC,CAAC,CAAC;QAC9C,IAAI,OAAO,KAAyB,OAAO,gBAAgB,CAAC,CAAC,CAAC;QAC9D,IAAI,IAAI,KAAK,OAAO,SAAS,CAAC,CAAC,CAAC;QAChC,OAAO,EAAE,IAAI;KACQ,CAAC;AAC9B,CAAC,EARgB,cAAc,GAAd,sBAAc,KAAd,sBAAc,QAQ9B;AAED,MAAa,YAAY;IAYrB,YACa,OAA8B,EAC9B,UAAuD,EACvD,SAAuD,EACvD,eAAe,KAAK;QAHpB,YAAO,GAAP,OAAO,CAAuB;QAC9B,eAAU,GAAV,UAAU,CAA6C;QACvD,cAAS,GAAT,SAAS,CAA8C;QACvD,iBAAY,GAAZ,YAAY,CAAQ;QAbhB,gBAAW,GAAsB,EAAG,CAAC;QAGrC,iBAAY,GAA4B,EAAG,CAAC;QAE5C,gBAAW,GAA+B,EAAG,CAAC;QAEvD,YAAO,GAAY,IAAI,CAAC;QA2ExB,kBAAa,GAAG,KAAK,EAAE,EAAK,EAAE,GAAW,EAAE,EAAE;;YACjD,IAAI;gBACA,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBACnC,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE;oBACvB,MAAA,IAAI,CAAC,OAAO,0CAAE,GAAG,CAAC,GAAG,EAAE,+BAA+B,EAAE,GAAG,EAAE;oBAC7D,MAAM,MAAM,GAAG,GAAG;wBACd,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,iBAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;wBACpD,CAAC,CAAC,IAAI,CAAC;oBACX,kBAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;iBACrD;gBACD,OAAO,GAAG,CAAC;aACd;oBAAS;gBACN,kBAAW,CAAC,GAAG,EAAE;oBACb,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;oBAC7B,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;gBACnC,CAAC,CAAC,CAAC;aACN;QACL,CAAC,CAAC;QApFE,qBAAc,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC;IAEO,GAAG,CAAC,CAAI;QACZ,IAAI,CAAC,IAAI,IAAI,EAAE;YACX,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;SAChE;QAED,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE;YACvB,OAAO,CAAC,CAAC;SACZ;QAED,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;YAClB,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;SAC9D;QAED,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAC9B,CAAC;IAED,SAAS,CAAC,IAAa;QACnB,IAAI,CAAC,OAAO,GAAG,qBAAY,CAAC,iBAAiB,IAAI,IAAI,GAAG,GAAG,CAAC,CAAC;QAC7D,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,WAAW,CAAC,GAAM;QACd,MAAM,IAAI,GAAG,IAAI,CAAC;QAClB,OAAO;YACH,IAAI,OAAO,KAAK,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC9C,IAAI,OAAO,KAAK,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACvC,IAAI,IAAI,KAAK,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;SAC7C,CAAC;IACN,CAAC;IAED,SAAS,CAAC,EAAK;QACX,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACzB,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IAED,UAAU,CAAC,EAAK;;QACZ,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,MAAA,IAAI,CAAC,OAAO,0CAAE,GAAG,CAAC,GAAG,EAAE,oBAAoB,EAAE,IAAI,EAAE;QACnD,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,GAAG,CAAC,EAAK;;QACL,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,IAAI,KAAK,SAAS,EAAE;YACpB,MAAA,IAAI,CAAC,OAAO,0CAAE,GAAG,CAAC,GAAG,EAAE,kBAAkB,EAAE,IAAI,EAAE;YACjD,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;SAChC;QAED,IAAI,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,OAAO,EAAE;YACT,MAAA,IAAI,CAAC,OAAO,0CAAE,GAAG,CAAC,GAAG,EAAE,4BAA4B,EAAE;YACrD,OAAO,OAAO,CAAC;SAClB;QAED,kBAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;QACjD,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QAEtC,kBAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;QACnD,OAAO,OAAO,CAAC;IACnB,CAAC;IAqBD,UAAU,CAAC,EAAK;QACZ,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IACpD,CAAC;IAED,mBAAmB,CAAC,EAAK,EAAE,KAAQ;QAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IAChD,CAAC;IAED,IAAI;QACA,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACzC,CAAC;IAED,UAAU;QACN,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACjB,OAAO,IAAI,CAAC;SACf;QAED,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC3C,CAAC;IAGO,IAAI,CAAC,GAAW,EAAE,IAAO,EAAE,OAAmB,EAAE,IAAa;QACjE,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACtC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;QACpC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IACvC,CAAC;CACJ;AAjIG;IADC,iBAAU,CAAC,OAAO;;iDACmC;AAGtD;IADC,iBAAU;;kDACkD;AAyH7D;IADC,aAAM;;;;wCAKN;AAnIL,oCAoIC;AAED,SAAS,KAAK,CAAI,GAAW,EAAE,GAAsB,EAAE,GAAM;IACzD,IAAI,GAAG,KAAK,SAAS,EAAE;QACnB,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC;KACnB;SAAM;QACH,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;KAClB;AACL,CAAC"}
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { IDisposable } from './disposer';
2
+ declare type Unsub = () => void;
3
+ export declare class ObserversMap implements IDisposable {
4
+ readonly subscribe: null | ((key: string) => Promise<Unsub[]>);
5
+ readonly name?: string;
6
+ /** Unsusbcrobers map: key => unsub fn */
7
+ private readonly _map;
8
+ /** Timeouts map: key => timeout handle */
9
+ private readonly _timeouts;
10
+ private readonly _logger;
11
+ private readonly _count;
12
+ constructor(subscribe: null | ((key: string) => Promise<Unsub[]>), name?: string);
13
+ get count(): number;
14
+ getIsObserving(key: string): boolean;
15
+ getHasObserveTimeout(key: string): boolean;
16
+ enable(key: string, enable: boolean, clearAfter?: number, existingUnsubs?: Unsub[]): Promise<void>;
17
+ private refreshTimeout;
18
+ clear(): void;
19
+ dispose(): void;
20
+ }
21
+ export {};
22
+ //# sourceMappingURL=observersMap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observersMap.d.ts","sourceRoot":"","sources":["../src/observersMap.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,WAAW,EAAE,MAAM,YAAY,CAAC;AAG3D,aAAK,KAAK,GAAG,MAAM,IAAI,CAAC;AAExB,qBAAa,YAAa,YAAW,WAAW;IAShC,QAAQ,CAAC,SAAS,EAAE,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM;IARlG,yCAAyC;IACzC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiC;IACtD,0CAA0C;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0B;IAEpD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;gBAEvB,SAAS,EAAE,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,EAAW,IAAI,CAAC,EAAE,MAAM;IAIlG,IAAW,KAAK,WAAgC;IAEzC,cAAc,CAAC,GAAG,EAAE,MAAM;IAI1B,oBAAoB,CAAC,GAAG,EAAE,MAAM;IAI1B,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAE,MAAa,EAAE,cAAc,GAAE,KAAK,EAAS;IAuC3G,OAAO,CAAC,cAAc;IAkBf,KAAK;IAeL,OAAO;CAGjB"}
@@ -1,21 +1,29 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Observers = void 0;
3
+ exports.ObserversMap = void 0;
4
4
  const logger_1 = require("./logger");
5
5
  const disposer_1 = require("./disposer");
6
- class Observers {
6
+ const NumberModel_1 = require("./viewModels/NumberModel");
7
+ class ObserversMap {
7
8
  constructor(subscribe, name) {
8
9
  this.subscribe = subscribe;
9
10
  this.name = name;
11
+ /** Unsusbcrobers map: key => unsub fn */
10
12
  this._map = new Map();
13
+ /** Timeouts map: key => timeout handle */
11
14
  this._timeouts = new Map();
12
15
  this._logger = null;
16
+ this._count = new NumberModel_1.NumberModel();
13
17
  this._logger = logger_1.createLogger(`[Observers:${this.name || '?'}]`);
14
18
  }
19
+ get count() { return this._count.value; }
15
20
  getIsObserving(key) {
16
21
  return this._map.has(key);
17
22
  }
18
- async enable(key, enable, clearAfter = null) {
23
+ getHasObserveTimeout(key) {
24
+ return this.getIsObserving(key) && this._timeouts.has(key);
25
+ }
26
+ async enable(key, enable, clearAfter = null, existingUnsubs = null) {
19
27
  if (enable === this.getIsObserving(key)) {
20
28
  this.refreshTimeout(key, enable, clearAfter, true);
21
29
  return;
@@ -26,13 +34,17 @@ class Observers {
26
34
  let disabed = false;
27
35
  const marker = () => { disabed = true; };
28
36
  this._map.set(key, marker);
29
- const unsubs = await this.subscribe(key);
37
+ if (!this.subscribe && !existingUnsubs) {
38
+ throw new Error('Neither subscribe function nor existingUnsubs has been configured');
39
+ }
40
+ const unsubs = existingUnsubs || await this.subscribe(key);
30
41
  const result = disposer_1.combineDisposers(...unsubs);
31
42
  if (disabed) { // unsubscribe was requested
32
43
  result();
33
44
  }
34
45
  else {
35
46
  this._map.set(key, result);
47
+ this._count.increment();
36
48
  this.refreshTimeout(key, true, clearAfter);
37
49
  }
38
50
  }
@@ -42,6 +54,7 @@ class Observers {
42
54
  const unsub = this._map.get(key);
43
55
  this._map.delete(key);
44
56
  unsub();
57
+ this._count.decrement();
45
58
  }
46
59
  }
47
60
  refreshTimeout(key, enable, timeout, refresh = false) {
@@ -59,16 +72,22 @@ class Observers {
59
72
  this._timeouts.set(key, t);
60
73
  }
61
74
  }
62
- dispose() {
63
- for (const u of this._map.values()) {
64
- u();
65
- }
66
- this._map.clear();
75
+ clear() {
76
+ // Clear timeouts
67
77
  for (const t of this._timeouts.values()) {
68
78
  clearTimeout(t);
69
79
  }
70
80
  this._timeouts.clear();
81
+ // Invoke unsubscribers
82
+ for (const u of this._map.values()) {
83
+ u();
84
+ }
85
+ this._map.clear();
86
+ this._count.setValue(0);
87
+ }
88
+ dispose() {
89
+ this.clear();
71
90
  }
72
91
  }
73
- exports.Observers = Observers;
74
- //# sourceMappingURL=observers.js.map
92
+ exports.ObserversMap = ObserversMap;
93
+ //# sourceMappingURL=observersMap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observersMap.js","sourceRoot":"","sources":["../src/observersMap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { Disposable } from './disposer';
2
+ import { DeferredGetter } from './cache';
3
+ import { Fields } from './fields';
4
+ export declare type Unsub = () => void;
5
+ export declare type Fetcher<T> = (key: string, cb: (val: T) => Promise<void> | void) => Unsub | Promise<Unsub>;
6
+ declare type ObserveStrategy = boolean | 'short' | number;
7
+ export interface IObservingCache<T> {
8
+ get(key: string): DeferredGetter<T>;
9
+ }
10
+ export declare class ObservingCache<T> extends Disposable implements IObservingCache<T> {
11
+ readonly fetcher: Fetcher<T>;
12
+ private readonly _cache;
13
+ private readonly _observers;
14
+ private _observeStrategy;
15
+ private readonly _observeStrategyOverrides;
16
+ private _updater;
17
+ constructor(fetcher: Fetcher<T>);
18
+ get loadingCount(): number;
19
+ get observersCount(): number;
20
+ useObservingStrategy(observe: ObserveStrategy): this;
21
+ useUpdater(updater: Fields.Updater<T>): this;
22
+ get(key: string, overrideStrategy?: ObserveStrategy): DeferredGetter<T>;
23
+ populate: (key: string, item: T) => void;
24
+ private _fetch;
25
+ private _subscribe;
26
+ private _updateItem;
27
+ }
28
+ export {};
29
+ //# sourceMappingURL=observingCache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observingCache.d.ts","sourceRoot":"","sources":["../src/observingCache.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAgB,cAAc,EAAE,MAAM,SAAS,CAAC;AAEvD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,oBAAY,KAAK,GAAG,MAAM,IAAI,CAAC;AAC/B,oBAAY,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,KAAK,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;AAEvG,aAAK,eAAe,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;AAElD,MAAM,WAAW,eAAe,CAAC,CAAC;IAC9B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;CACvC;AAED,qBAAa,cAAc,CAAC,CAAC,CAAE,SAAQ,UAAW,YAAW,eAAe,CAAC,CAAC,CAAC;IAU/D,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IARxC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAe;IAE1C,OAAO,CAAC,gBAAgB,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAwC;IAElF,OAAO,CAAC,QAAQ,CAA2B;gBAEtB,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IASxC,IAAW,YAAY,WAAoC;IAC3D,IAAW,cAAc,WAAoC;IAE7D,oBAAoB,CAAC,OAAO,EAAE,eAAe;IAa7C,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAMrC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,eAAe,GAAG,cAAc,CAAC,CAAC,CAAC;IAgBvE,QAAQ,QAAS,MAAM,QAAQ,CAAC,UAE9B;IAEF,OAAO,CAAC,MAAM,CAwBZ;IAEF,OAAO,CAAC,UAAU,CAIhB;IAEF,OAAO,CAAC,WAAW,CAYhB;CACN"}
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ObservingCache = void 0;
4
+ const mobx_1 = require("mobx");
5
+ const disposer_1 = require("./disposer");
6
+ const cache_1 = require("./cache");
7
+ const observersMap_1 = require("./observersMap");
8
+ class ObservingCache extends disposer_1.Disposable {
9
+ constructor(fetcher) {
10
+ super();
11
+ this.fetcher = fetcher;
12
+ this._observeStrategy = null;
13
+ this._observeStrategyOverrides = {};
14
+ this._updater = null;
15
+ this.populate = (key, item) => {
16
+ this._updateItem(key, item);
17
+ };
18
+ this._fetch = async (key) => {
19
+ let firstLoad = true;
20
+ return new Promise((resolve) => {
21
+ Promise.resolve(this.fetcher(key, item => {
22
+ if (firstLoad) {
23
+ resolve(item);
24
+ firstLoad = false;
25
+ }
26
+ else {
27
+ this._updateItem(key, item);
28
+ }
29
+ })).then(unsub => {
30
+ const strategy = this._observeStrategyOverrides[key] || this._observeStrategy;
31
+ if (!strategy) {
32
+ // immediate unsub in case no observing strategy has been set
33
+ unsub();
34
+ }
35
+ else {
36
+ const timeout = getObserveTimeout(strategy);
37
+ this._observers.enable(key, true, timeout, [unsub]);
38
+ }
39
+ });
40
+ });
41
+ };
42
+ this._subscribe = (key) => {
43
+ return Promise.all([
44
+ this.fetcher(key, item => this._updateItem(key, item)),
45
+ ]);
46
+ };
47
+ this._updateItem = mobx_1.action((key, item) => {
48
+ if (this._updater != null) {
49
+ const current = this._cache.getCurrent(key, false);
50
+ if (current != null) {
51
+ const result = this._updater(current, item);
52
+ // re-set existing item but with updated contents
53
+ this._cache.updateValueDirectly(key, result);
54
+ return;
55
+ }
56
+ }
57
+ this._cache.updateValueDirectly(key, item);
58
+ });
59
+ this._cache = new cache_1.PromiseCache(this._fetch);
60
+ this._observers = new observersMap_1.ObserversMap(this._subscribe);
61
+ this.disposer.add(this._observers);
62
+ }
63
+ get loadingCount() { return this._cache.busyCount; }
64
+ get observersCount() { return this._observers.count; }
65
+ useObservingStrategy(observe) {
66
+ this._observeStrategy = observe;
67
+ if (!this._observeStrategy) {
68
+ this._observers.clear();
69
+ }
70
+ else {
71
+ const currentKeys = this._cache.keys();
72
+ const timeout = getObserveTimeout(this._observeStrategy);
73
+ currentKeys.forEach(key => this._observers.enable(key, true, timeout));
74
+ }
75
+ return this;
76
+ }
77
+ useUpdater(updater) {
78
+ this._updater = updater;
79
+ this._cache.useObserveItems(updater != null);
80
+ return this;
81
+ }
82
+ get(key, overrideStrategy) {
83
+ this._observeStrategyOverrides[key] = overrideStrategy;
84
+ const strategy = overrideStrategy || this._observeStrategy;
85
+ if (strategy && !this._observers.getIsObserving(key)) {
86
+ // ensure observe
87
+ if (this._cache.hasKey(key)) {
88
+ // the request has been initiated already
89
+ const timeout = getObserveTimeout(strategy);
90
+ this._observers.enable(key, true, timeout);
91
+ }
92
+ }
93
+ return this._cache.getDeferred(key);
94
+ }
95
+ }
96
+ exports.ObservingCache = ObservingCache;
97
+ function getObserveTimeout(s) {
98
+ if (!s) {
99
+ return undefined;
100
+ }
101
+ return typeof s === 'number'
102
+ ? s
103
+ : (s === 'short'
104
+ ? 5 * 60 * 1000
105
+ : null);
106
+ }
107
+ //# sourceMappingURL=observingCache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observingCache.js","sourceRoot":"","sources":["../src/observingCache.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zajno/common",
3
- "version": "1.4.4",
3
+ "version": "1.4.5",
4
4
  "description": "Zajno's re-usable utilities for JS/TS projects",
5
5
  "repository": {
6
6
  "type": "git",
@@ -0,0 +1,127 @@
1
+ import { observable, reaction, runInAction, toJS } from 'mobx';
2
+ import { ObservingCache } from '../observingCache';
3
+ import { setTimeoutAsync } from '../async/timeout';
4
+
5
+ type TestItem = {
6
+ hello: string,
7
+ };
8
+
9
+ function createData() {
10
+ const Database: Record<string, TestItem> = observable({
11
+ '123': { hello: 'Hi, 123' },
12
+ });
13
+
14
+ const Repository = {
15
+ fetch: (key: string, cb: (value: TestItem) => void) => {
16
+ return reaction(() => Database[key], async item => {
17
+ await setTimeoutAsync(100);
18
+ cb(item);
19
+ }, { fireImmediately: true, delay: 100 });
20
+ },
21
+ };
22
+
23
+ const subscribeFn = jest.fn().mockImplementation(null);
24
+ const unsubFn = jest.fn().mockImplementation(null);
25
+
26
+ const Cache = new ObservingCache((key, cb) => {
27
+ subscribeFn(key);
28
+ const unsub = Repository.fetch(key, cb);
29
+ return () => {
30
+ unsubFn();
31
+ unsub();
32
+ };
33
+ });
34
+
35
+ return {
36
+ Database,
37
+ Repository,
38
+ Cache,
39
+ subscribeFn,
40
+ unsubFn,
41
+ };
42
+ }
43
+
44
+
45
+ describe('ObservingCache works with', () => {
46
+ it('no observing', async () => {
47
+ const { Database, Cache, subscribeFn, unsubFn } = createData();
48
+ try {
49
+ expect(Cache).not.toBeNull();
50
+ expect(subscribeFn).not.toHaveBeenCalled();
51
+ expect(unsubFn).not.toHaveBeenCalled();
52
+
53
+ const KEY = '123';
54
+
55
+ const deferred = Cache.get(KEY);
56
+
57
+ expect(deferred.busy).toBeUndefined();
58
+ expect(deferred.current).toBeUndefined();
59
+ expect(deferred.busy).toBeTruthy();
60
+
61
+ const expectedItem = toJS(Database[KEY]);
62
+
63
+ await expect(deferred.promise).resolves.toStrictEqual(expectedItem);
64
+
65
+ expect(deferred.current).toStrictEqual(expectedItem);
66
+ expect(deferred.busy).toBeFalsy();
67
+
68
+ expect(unsubFn).toHaveBeenCalledTimes(1);
69
+
70
+ expect(subscribeFn).toHaveBeenCalledTimes(1);
71
+ expect(subscribeFn).toHaveBeenCalledWith(KEY);
72
+
73
+ subscribeFn.mockClear();
74
+ unsubFn.mockClear();
75
+
76
+ Database[KEY] = { hello: 'bye' };
77
+
78
+ expect(subscribeFn).not.toHaveBeenCalled();
79
+ } finally {
80
+ Cache.dispose();
81
+ }
82
+ });
83
+
84
+ it('infinite observing', async () => {
85
+ const { Database, Cache, subscribeFn, unsubFn } = createData();
86
+ try {
87
+ Cache.useObservingStrategy(true);
88
+
89
+ const KEY = '123';
90
+
91
+ const deferred = Cache.get(KEY);
92
+
93
+ expect(deferred.busy).toBeUndefined();
94
+ expect(deferred.current).toBeUndefined();
95
+ expect(deferred.busy).toBeTruthy();
96
+
97
+ const expectedItem = toJS(Database[KEY]);
98
+
99
+ await expect(deferred.promise).resolves.toStrictEqual(expectedItem);
100
+
101
+ expect(deferred.current).toStrictEqual(expectedItem);
102
+ expect(deferred.busy).toBeFalsy();
103
+
104
+ expect(unsubFn).not.toHaveBeenCalled();
105
+
106
+ expect(subscribeFn).toHaveBeenCalledTimes(1);
107
+ expect(subscribeFn).toHaveBeenCalledWith(KEY);
108
+
109
+ subscribeFn.mockClear();
110
+ unsubFn.mockClear();
111
+
112
+ const replaceItem: TestItem = { hello: 'bye' };
113
+ runInAction(() => {
114
+ Database[KEY] = replaceItem;
115
+ });
116
+
117
+ expect(subscribeFn).not.toHaveBeenCalled();
118
+
119
+ await setTimeoutAsync(300);
120
+
121
+ expect(deferred.current).toStrictEqual(replaceItem);
122
+ } finally {
123
+ Cache.dispose();
124
+ expect(unsubFn).toHaveBeenCalledTimes(1);
125
+ }
126
+ });
127
+ });
package/src/cache.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { observable, makeObservable, runInAction, action } from 'mobx';
2
+ import { NumberModel } from './viewModels/NumberModel';
2
3
  import { createLogger, ILogger } from './logger';
3
4
 
4
5
  export type DeferredGetter<T> = {
@@ -28,14 +29,25 @@ export class PromiseCache<T, K = string> {
28
29
  private readonly _fetchCache: Record<string, Promise<T>> = { };
29
30
 
30
31
  private _logger: ILogger = null;
32
+ private _observeItems = false;
33
+
34
+ private readonly _busyCount = new NumberModel(0);
31
35
 
32
36
  constructor(
33
37
  readonly fetcher: (id: K) => Promise<T>,
34
38
  readonly keyAdapter?: K extends string ? null : (k: K) => string,
35
39
  readonly keyParser?: K extends string ? null : (id: string) => K,
36
- readonly observeItems = false,
40
+ observeItems = false,
37
41
  ) {
38
42
  makeObservable(this);
43
+ this._observeItems = observeItems;
44
+ }
45
+
46
+ public get busyCount() { return this._busyCount.value; }
47
+
48
+ useObserveItems(observeItems: boolean) {
49
+ this._observeItems = observeItems;
50
+ return this;
39
51
  }
40
52
 
41
53
  private _pk(k: K): string {
@@ -73,10 +85,12 @@ export class PromiseCache<T, K = string> {
73
85
  return this._itemsStatus[key];
74
86
  }
75
87
 
76
- getCurrent(id: K): T {
88
+ getCurrent(id: K, initiateFetch = true): T {
77
89
  const key = this._pk(id);
78
90
  const item = this._itemsCache[key];
79
- this.get(id);
91
+ if (initiateFetch) {
92
+ this.get(id);
93
+ }
80
94
  this._logger?.log(key, 'getCurrent returns', item);
81
95
  return item;
82
96
  }
@@ -104,17 +118,19 @@ export class PromiseCache<T, K = string> {
104
118
 
105
119
  private _doFetchAsync = async (id: K, key: string) => {
106
120
  try {
121
+ this._busyCount.increment();
107
122
  const res = await this.fetcher(id);
108
123
  if (this._fetchCache[key]) {
109
124
  this._logger?.log(key, 'item\'s <promise> resolved to', res);
110
125
  const result = res
111
- ? (this.observeItems ? observable.object(res) : res)
126
+ ? (this._observeItems ? observable.object(res) : res)
112
127
  : null;
113
128
  runInAction(() => this._itemsCache[key] = result);
114
129
  }
115
130
  return res;
116
131
  } finally {
117
132
  runInAction(() => {
133
+ this._busyCount.decrement();
118
134
  delete this._fetchCache[key];
119
135
  this._itemsStatus[key] = false;
120
136
  });
@@ -131,6 +147,11 @@ export class PromiseCache<T, K = string> {
131
147
  this._set(key, value, undefined, undefined);
132
148
  }
133
149
 
150
+ hasKey(id: K) {
151
+ const key = this._pk(id);
152
+ return this._itemsCache[key] !== undefined || this._itemsStatus[key] !== undefined;
153
+ }
154
+
134
155
  keys() {
135
156
  return Object.keys(this._itemsCache);
136
157
  }