@beecode/msh-util 1.2.1 → 2.0.0

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 (145) hide show
  1. package/dist/array-util.d.ts +23 -0
  2. package/dist/array-util.d.ts.map +1 -0
  3. package/dist/array-util.js +27 -0
  4. package/{src/class-factory-pattern.ts → dist/class-factory-pattern.d.ts} +5 -9
  5. package/dist/class-factory-pattern.d.ts.map +1 -0
  6. package/dist/class-factory-pattern.js +26 -0
  7. package/{src/express/error-handler.ts → dist/express/error-handler.d.ts} +2 -10
  8. package/dist/express/error-handler.d.ts.map +1 -0
  9. package/dist/express/error-handler.js +26 -0
  10. package/dist/index.d.ts +17 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +14 -0
  13. package/dist/joi-util.d.ts +47 -0
  14. package/dist/joi-util.d.ts.map +1 -0
  15. package/dist/joi-util.js +62 -0
  16. package/{src/memoize-factory.ts → dist/memoize-factory.d.ts} +3 -14
  17. package/dist/memoize-factory.d.ts.map +1 -0
  18. package/dist/memoize-factory.js +24 -0
  19. package/dist/object-util.d.ts +72 -0
  20. package/dist/object-util.d.ts.map +1 -0
  21. package/dist/object-util.js +115 -0
  22. package/dist/regex-util.d.ts +12 -0
  23. package/dist/regex-util.d.ts.map +1 -0
  24. package/dist/regex-util.js +12 -0
  25. package/dist/single-threshold-promise.d.ts +31 -0
  26. package/dist/single-threshold-promise.d.ts.map +1 -0
  27. package/dist/single-threshold-promise.js +46 -0
  28. package/dist/singleton/async.d.ts +50 -0
  29. package/dist/singleton/async.d.ts.map +1 -0
  30. package/dist/singleton/async.js +75 -0
  31. package/{src/singleton/pattern.ts → dist/singleton/pattern.d.ts} +3 -13
  32. package/dist/singleton/pattern.d.ts.map +1 -0
  33. package/dist/singleton/pattern.js +41 -0
  34. package/dist/string-util.d.ts +10 -0
  35. package/dist/string-util.d.ts.map +1 -0
  36. package/dist/string-util.js +18 -0
  37. package/dist/time-util.d.ts +74 -0
  38. package/dist/time-util.d.ts.map +1 -0
  39. package/dist/time-util.js +90 -0
  40. package/dist/time-zone.d.ts +467 -0
  41. package/dist/time-zone.d.ts.map +1 -0
  42. package/dist/time-zone.js +468 -0
  43. package/{src/timeout.ts → dist/timeout.d.ts} +2 -3
  44. package/dist/timeout.d.ts.map +1 -0
  45. package/dist/timeout.js +17 -0
  46. package/dist/type-util.d.ts +50 -0
  47. package/dist/type-util.d.ts.map +1 -0
  48. package/dist/type-util.js +54 -0
  49. package/lib/array-util.d.ts.map +1 -1
  50. package/lib/array-util.js +30 -28
  51. package/lib/class-factory-pattern.d.ts.map +1 -1
  52. package/lib/class-factory-pattern.js +17 -8
  53. package/lib/express/error-handler.d.ts.map +1 -1
  54. package/lib/express/error-handler.js +15 -11
  55. package/lib/index.d.ts +16 -13
  56. package/lib/index.d.ts.map +1 -1
  57. package/lib/index.js +107 -29
  58. package/lib/joi-util.d.ts.map +1 -1
  59. package/lib/joi-util.js +66 -22
  60. package/lib/memoize-factory.d.ts +1 -1
  61. package/lib/memoize-factory.d.ts.map +1 -1
  62. package/lib/memoize-factory.js +19 -13
  63. package/lib/object-util.d.ts.map +1 -1
  64. package/lib/object-util.js +110 -55
  65. package/lib/package.json +1 -0
  66. package/lib/regex-util.js +15 -13
  67. package/lib/single-threshold-promise.d.ts +1 -1
  68. package/lib/single-threshold-promise.d.ts.map +1 -1
  69. package/lib/single-threshold-promise.js +74 -28
  70. package/lib/singleton/async.d.ts +1 -1
  71. package/lib/singleton/async.d.ts.map +1 -1
  72. package/lib/singleton/async.js +105 -45
  73. package/lib/singleton/pattern.d.ts +1 -1
  74. package/lib/singleton/pattern.d.ts.map +1 -1
  75. package/lib/singleton/pattern.js +13 -12
  76. package/lib/string-util.js +21 -19
  77. package/lib/time-util.js +69 -39
  78. package/lib/time-zone.d.ts +467 -0
  79. package/lib/time-zone.d.ts.map +1 -0
  80. package/lib/time-zone.js +473 -0
  81. package/lib/timeout.js +9 -6
  82. package/lib/type-util.js +57 -55
  83. package/lib/types/global.d.js +5 -0
  84. package/lib/types/types.d.js +3 -0
  85. package/package.json +188 -134
  86. package/lib/array-util.js.map +0 -1
  87. package/lib/class-factory-pattern.js.map +0 -1
  88. package/lib/express/error-handler.js.map +0 -1
  89. package/lib/index.js.map +0 -1
  90. package/lib/joi-util.js.map +0 -1
  91. package/lib/memoize-factory.js.map +0 -1
  92. package/lib/object-util.js.map +0 -1
  93. package/lib/regex-util.js.map +0 -1
  94. package/lib/single-threshold-promise.js.map +0 -1
  95. package/lib/singleton/async.js.map +0 -1
  96. package/lib/singleton/pattern.js.map +0 -1
  97. package/lib/string-util.js.map +0 -1
  98. package/lib/time-util.js.map +0 -1
  99. package/lib/timeout.js.map +0 -1
  100. package/lib/type-util.js.map +0 -1
  101. package/lib/types/any-function/index.d.ts +0 -2
  102. package/lib/types/any-function/index.d.ts.map +0 -1
  103. package/lib/types/any-function/index.js +0 -3
  104. package/lib/types/any-function/index.js.map +0 -1
  105. package/lib/types/any-function/no-params.d.ts +0 -2
  106. package/lib/types/any-function/no-params.d.ts.map +0 -1
  107. package/lib/types/any-function/no-params.js +0 -3
  108. package/lib/types/any-function/no-params.js.map +0 -1
  109. package/lib/types/any-function/promise-no-params.d.ts +0 -2
  110. package/lib/types/any-function/promise-no-params.d.ts.map +0 -1
  111. package/lib/types/any-function/promise-no-params.js +0 -3
  112. package/lib/types/any-function/promise-no-params.js.map +0 -1
  113. package/lib/types/any-function/promise.d.ts +0 -2
  114. package/lib/types/any-function/promise.d.ts.map +0 -1
  115. package/lib/types/any-function/promise.js +0 -3
  116. package/lib/types/any-function/promise.js.map +0 -1
  117. package/src/array-util.test.ts +0 -50
  118. package/src/array-util.ts +0 -26
  119. package/src/class-factory-pattern.test.ts +0 -39
  120. package/src/express/error-handler.test.ts +0 -44
  121. package/src/index.ts +0 -25
  122. package/src/joi-util.test.ts +0 -192
  123. package/src/joi-util.ts +0 -65
  124. package/src/memoize-factory.test.ts +0 -40
  125. package/src/object-util.test.ts +0 -360
  126. package/src/object-util.ts +0 -127
  127. package/src/regex-util.test.ts +0 -25
  128. package/src/regex-util.ts +0 -11
  129. package/src/single-threshold-promise.test.ts +0 -91
  130. package/src/single-threshold-promise.ts +0 -56
  131. package/src/singleton/async.test.ts +0 -122
  132. package/src/singleton/async.ts +0 -90
  133. package/src/singleton/pattern.test.ts +0 -16
  134. package/src/string-util.test.ts +0 -18
  135. package/src/string-util.ts +0 -18
  136. package/src/time-util.test.ts +0 -89
  137. package/src/time-util.ts +0 -98
  138. package/src/timeout.test.ts +0 -65
  139. package/src/type-util.test.ts +0 -20
  140. package/src/type-util.ts +0 -54
  141. package/src/types/any-function/index.ts +0 -1
  142. package/src/types/any-function/no-params.ts +0 -1
  143. package/src/types/any-function/promise-no-params.ts +0 -1
  144. package/src/types/any-function/promise.ts +0 -1
  145. package/src/types/types.d.ts +0 -2
@@ -0,0 +1,31 @@
1
+ export type AnyFunctionPromiseNoParams<T> = () => Promise<T>;
2
+ /**
3
+ * SingleThresholdPromise returns a single promise, and subsequent calls made before the promise resolves will return the same promise.
4
+ * @example
5
+ * export const refreshTokenSingleThreshold = new SingleThresholdPromise(async () => {
6
+ * const oldRefreshToken = await refreshTokenService.get()
7
+ * const { accessToken, refreshToken } = await authService.refreshToken({
8
+ * refreshToken: oldRefreshToken,
9
+ * })
10
+ * return { accessToken, refreshToken }
11
+ * })
12
+ *
13
+ * export const authService = {
14
+ * refreshToken: async (): Promise<{ accessToken: string; refreshToken:string }> => {
15
+ * return refreshTokenSingleThreshold.promise()
16
+ * }
17
+ * }
18
+ */
19
+ export declare class SingleThresholdPromise<T> {
20
+ protected _cache: {
21
+ promises?: {
22
+ resolve: (value: T | PromiseLike<T>) => void;
23
+ reject: (reason?: any) => void;
24
+ }[];
25
+ };
26
+ protected _factoryFn: AnyFunctionPromiseNoParams<T>;
27
+ constructor(factoryFn: AnyFunctionPromiseNoParams<T>);
28
+ protected _rejectPromises(): void;
29
+ promise(): Promise<T>;
30
+ }
31
+ //# sourceMappingURL=single-threshold-promise.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"single-threshold-promise.d.ts","sourceRoot":"","sources":["../src/single-threshold-promise.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,0BAA0B,CAAC,CAAC,IAAI,MAAM,OAAO,CAAC,CAAC,CAAC,CAAA;AAE5D;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,sBAAsB,CAAC,CAAC;IACpC,SAAS,CAAC,MAAM,EAAE;QAEjB,QAAQ,CAAC,EAAE;YAAE,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;YAAC,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,IAAI,CAAA;SAAE,EAAE,CAAA;KAC7F,CAAK;IAEN,SAAS,CAAC,UAAU,EAAE,0BAA0B,CAAC,CAAC,CAAC,CAAA;gBAEvC,SAAS,EAAE,0BAA0B,CAAC,CAAC,CAAC;IAIpD,SAAS,CAAC,eAAe,IAAI,IAAI;IAO3B,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC;CAkB3B"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * SingleThresholdPromise returns a single promise, and subsequent calls made before the promise resolves will return the same promise.
3
+ * @example
4
+ * export const refreshTokenSingleThreshold = new SingleThresholdPromise(async () => {
5
+ * const oldRefreshToken = await refreshTokenService.get()
6
+ * const { accessToken, refreshToken } = await authService.refreshToken({
7
+ * refreshToken: oldRefreshToken,
8
+ * })
9
+ * return { accessToken, refreshToken }
10
+ * })
11
+ *
12
+ * export const authService = {
13
+ * refreshToken: async (): Promise<{ accessToken: string; refreshToken:string }> => {
14
+ * return refreshTokenSingleThreshold.promise()
15
+ * }
16
+ * }
17
+ */
18
+ export class SingleThresholdPromise {
19
+ _cache = {};
20
+ _factoryFn;
21
+ constructor(factoryFn) {
22
+ this._factoryFn = factoryFn;
23
+ }
24
+ _rejectPromises() {
25
+ if (this._cache.promises) {
26
+ this._cache.promises.forEach((promise) => promise.reject(new Error('Cache was cleaned')));
27
+ }
28
+ delete this._cache.promises;
29
+ }
30
+ async promise() {
31
+ if ('promises' in this._cache) {
32
+ return new Promise((resolve, reject) => {
33
+ this._cache.promises.push({ reject, resolve });
34
+ });
35
+ }
36
+ this._cache.promises = [];
37
+ const result = await this._factoryFn().catch((err) => {
38
+ this._rejectPromises();
39
+ throw err;
40
+ });
41
+ this._cache.promises.forEach((promise) => promise.resolve(result));
42
+ delete this._cache.promises;
43
+ return result;
44
+ }
45
+ }
46
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2luZ2xlLXRocmVzaG9sZC1wcm9taXNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3NpbmdsZS10aHJlc2hvbGQtcHJvbWlzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQTs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQUNILE1BQU0sT0FBTyxzQkFBc0I7SUFDeEIsTUFBTSxHQUdaLEVBQUUsQ0FBQTtJQUVJLFVBQVUsQ0FBK0I7SUFFbkQsWUFBWSxTQUF3QztRQUNuRCxJQUFJLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQTtJQUM1QixDQUFDO0lBRVMsZUFBZTtRQUN4QixJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDMUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxDQUFBO1FBQzFGLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFBO0lBQzVCLENBQUM7SUFFRCxLQUFLLENBQUMsT0FBTztRQUNaLElBQUksVUFBVSxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUMvQixPQUFPLElBQUksT0FBTyxDQUFJLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO2dCQUN6QyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQTtZQUNoRCxDQUFDLENBQUMsQ0FBQTtRQUNILENBQUM7UUFFRCxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsR0FBRyxFQUFFLENBQUE7UUFDekIsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7WUFDcEQsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFBO1lBQ3RCLE1BQU0sR0FBRyxDQUFBO1FBQ1YsQ0FBQyxDQUFDLENBQUE7UUFFRixJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQTtRQUNsRSxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFBO1FBRTNCLE9BQU8sTUFBTSxDQUFBO0lBQ2QsQ0FBQztDQUNEIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHR5cGUgQW55RnVuY3Rpb25Qcm9taXNlTm9QYXJhbXM8VD4gPSAoKSA9PiBQcm9taXNlPFQ+XG5cbi8qKlxuICogU2luZ2xlVGhyZXNob2xkUHJvbWlzZSByZXR1cm5zIGEgc2luZ2xlIHByb21pc2UsIGFuZCBzdWJzZXF1ZW50IGNhbGxzIG1hZGUgYmVmb3JlIHRoZSBwcm9taXNlIHJlc29sdmVzIHdpbGwgcmV0dXJuIHRoZSBzYW1lIHByb21pc2UuXG4gKiBAZXhhbXBsZVxuICogZXhwb3J0IGNvbnN0IHJlZnJlc2hUb2tlblNpbmdsZVRocmVzaG9sZCA9IG5ldyBTaW5nbGVUaHJlc2hvbGRQcm9taXNlKGFzeW5jICgpID0+IHtcbiAqICAgY29uc3Qgb2xkUmVmcmVzaFRva2VuID0gYXdhaXQgcmVmcmVzaFRva2VuU2VydmljZS5nZXQoKVxuICogICBjb25zdCB7IGFjY2Vzc1Rva2VuLCByZWZyZXNoVG9rZW4gfSA9IGF3YWl0IGF1dGhTZXJ2aWNlLnJlZnJlc2hUb2tlbih7XG4gKiAgICAgcmVmcmVzaFRva2VuOiBvbGRSZWZyZXNoVG9rZW4sXG4gKiAgIH0pXG4gKiAgIHJldHVybiB7IGFjY2Vzc1Rva2VuLCByZWZyZXNoVG9rZW4gfVxuICogfSlcbiAqXG4gKiBleHBvcnQgY29uc3QgYXV0aFNlcnZpY2UgPSB7XG4gKiAgIHJlZnJlc2hUb2tlbjogYXN5bmMgKCk6IFByb21pc2U8eyBhY2Nlc3NUb2tlbjogc3RyaW5nOyByZWZyZXNoVG9rZW46c3RyaW5nIH0+ID0+IHtcbiAqICAgICByZXR1cm4gcmVmcmVzaFRva2VuU2luZ2xlVGhyZXNob2xkLnByb21pc2UoKVxuICogICB9XG4gKiB9XG4gKi9cbmV4cG9ydCBjbGFzcyBTaW5nbGVUaHJlc2hvbGRQcm9taXNlPFQ+IHtcblx0cHJvdGVjdGVkIF9jYWNoZToge1xuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG5cdFx0cHJvbWlzZXM/OiB7IHJlc29sdmU6ICh2YWx1ZTogVCB8IFByb21pc2VMaWtlPFQ+KSA9PiB2b2lkOyByZWplY3Q6IChyZWFzb24/OiBhbnkpID0+IHZvaWQgfVtdXG5cdH0gPSB7fVxuXG5cdHByb3RlY3RlZCBfZmFjdG9yeUZuOiBBbnlGdW5jdGlvblByb21pc2VOb1BhcmFtczxUPlxuXG5cdGNvbnN0cnVjdG9yKGZhY3RvcnlGbjogQW55RnVuY3Rpb25Qcm9taXNlTm9QYXJhbXM8VD4pIHtcblx0XHR0aGlzLl9mYWN0b3J5Rm4gPSBmYWN0b3J5Rm5cblx0fVxuXG5cdHByb3RlY3RlZCBfcmVqZWN0UHJvbWlzZXMoKTogdm9pZCB7XG5cdFx0aWYgKHRoaXMuX2NhY2hlLnByb21pc2VzKSB7XG5cdFx0XHR0aGlzLl9jYWNoZS5wcm9taXNlcy5mb3JFYWNoKChwcm9taXNlKSA9PiBwcm9taXNlLnJlamVjdChuZXcgRXJyb3IoJ0NhY2hlIHdhcyBjbGVhbmVkJykpKVxuXHRcdH1cblx0XHRkZWxldGUgdGhpcy5fY2FjaGUucHJvbWlzZXNcblx0fVxuXG5cdGFzeW5jIHByb21pc2UoKTogUHJvbWlzZTxUPiB7XG5cdFx0aWYgKCdwcm9taXNlcycgaW4gdGhpcy5fY2FjaGUpIHtcblx0XHRcdHJldHVybiBuZXcgUHJvbWlzZTxUPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cdFx0XHRcdHRoaXMuX2NhY2hlLnByb21pc2VzIS5wdXNoKHsgcmVqZWN0LCByZXNvbHZlIH0pXG5cdFx0XHR9KVxuXHRcdH1cblxuXHRcdHRoaXMuX2NhY2hlLnByb21pc2VzID0gW11cblx0XHRjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLl9mYWN0b3J5Rm4oKS5jYXRjaCgoZXJyKSA9PiB7XG5cdFx0XHR0aGlzLl9yZWplY3RQcm9taXNlcygpXG5cdFx0XHR0aHJvdyBlcnJcblx0XHR9KVxuXG5cdFx0dGhpcy5fY2FjaGUucHJvbWlzZXMuZm9yRWFjaCgocHJvbWlzZSkgPT4gcHJvbWlzZS5yZXNvbHZlKHJlc3VsdCkpXG5cdFx0ZGVsZXRlIHRoaXMuX2NhY2hlLnByb21pc2VzXG5cblx0XHRyZXR1cm4gcmVzdWx0XG5cdH1cbn1cbiJdfQ==
@@ -0,0 +1,50 @@
1
+ export type AnyFunctionPromiseNoParams<T> = () => Promise<T>;
2
+ /**
3
+ * This is a singleton wrapper that is used to wrap around async function. We have additional functionality to clear the cache
4
+ * and reject any subscriptions to initial promise. And we can also check if there is anything i cache
5
+ * @example
6
+ * export const configSingleton = new SingletonAsync(async () => {
7
+ * await timeout(3000)
8
+ * return {
9
+ * env: process.env.NODE_ENV
10
+ * } as const
11
+ * })
12
+ *
13
+ * // using
14
+ * // cache value before we call promise
15
+ * console.log(configSingleton().cache()) // undefined
16
+ * console.log('NODE_ENV: ', await configSingleton().promise().env) // NODE_ENV: prod
17
+ * // cache value after we call promise
18
+ * console.log(configSingleton().cache()) // { env: 'prod' }
19
+ */
20
+ export declare class SingletonAsync<T> {
21
+ protected _cache: {
22
+ singleton?: T;
23
+ promises?: {
24
+ resolve: (value: T | PromiseLike<T>) => void;
25
+ reject: (reason?: any) => void;
26
+ }[];
27
+ };
28
+ protected _factory: AnyFunctionPromiseNoParams<T>;
29
+ constructor(factory: AnyFunctionPromiseNoParams<T>);
30
+ /**
31
+ * Empty cached value and reject any subscribed promise that is waiting for the initial promise to be resolved.
32
+ */
33
+ cleanCache(): void;
34
+ protected _rejectPromises(params: {
35
+ error: Error;
36
+ }): void;
37
+ /**
38
+ * Return singleton value in a promise. If there is no cached value then try to get it from factory.
39
+ * @template T
40
+ * @returns {Promise<T>}
41
+ */
42
+ promise(): Promise<T>;
43
+ /**
44
+ * Return cached value, if there is no value cached return undefined.
45
+ * @template T
46
+ * @returns {T | undefined}
47
+ */
48
+ cached(): T | undefined;
49
+ }
50
+ //# sourceMappingURL=async.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async.d.ts","sourceRoot":"","sources":["../../src/singleton/async.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,0BAA0B,CAAC,CAAC,IAAI,MAAM,OAAO,CAAC,CAAC,CAAC,CAAA;AAE5D;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,cAAc,CAAC,CAAC;IAC5B,SAAS,CAAC,MAAM,EAAE;QACjB,SAAS,CAAC,EAAE,CAAC,CAAA;QAEb,QAAQ,CAAC,EAAE;YAAE,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;YAAC,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,IAAI,CAAA;SAAE,EAAE,CAAA;KAC7F,CAAK;IAEN,SAAS,CAAC,QAAQ,EAAE,0BAA0B,CAAC,CAAC,CAAC,CAAA;gBAErC,OAAO,EAAE,0BAA0B,CAAC,CAAC,CAAC;IAIlD;;OAEG;IACH,UAAU,IAAI,IAAI;IAKlB,SAAS,CAAC,eAAe,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,KAAK,CAAA;KAAE,GAAG,IAAI;IASzD;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC;IAuB3B;;;;OAIG;IACH,MAAM,IAAI,CAAC,GAAG,SAAS;CAOvB"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * This is a singleton wrapper that is used to wrap around async function. We have additional functionality to clear the cache
3
+ * and reject any subscriptions to initial promise. And we can also check if there is anything i cache
4
+ * @example
5
+ * export const configSingleton = new SingletonAsync(async () => {
6
+ * await timeout(3000)
7
+ * return {
8
+ * env: process.env.NODE_ENV
9
+ * } as const
10
+ * })
11
+ *
12
+ * // using
13
+ * // cache value before we call promise
14
+ * console.log(configSingleton().cache()) // undefined
15
+ * console.log('NODE_ENV: ', await configSingleton().promise().env) // NODE_ENV: prod
16
+ * // cache value after we call promise
17
+ * console.log(configSingleton().cache()) // { env: 'prod' }
18
+ */
19
+ export class SingletonAsync {
20
+ _cache = {};
21
+ _factory;
22
+ constructor(factory) {
23
+ this._factory = factory;
24
+ }
25
+ /**
26
+ * Empty cached value and reject any subscribed promise that is waiting for the initial promise to be resolved.
27
+ */
28
+ cleanCache() {
29
+ delete this._cache.singleton;
30
+ this._rejectPromises({ error: new Error('Cache was cleaned') });
31
+ }
32
+ _rejectPromises(params) {
33
+ const { error } = params;
34
+ if (this._cache.promises) {
35
+ this._cache.promises.forEach((promise) => promise.reject(error));
36
+ }
37
+ delete this._cache.promises;
38
+ }
39
+ /**
40
+ * Return singleton value in a promise. If there is no cached value then try to get it from factory.
41
+ * @template T
42
+ * @returns {Promise<T>}
43
+ */
44
+ async promise() {
45
+ if ('singleton' in this._cache) {
46
+ return this._cache.singleton;
47
+ }
48
+ if ('promises' in this._cache) {
49
+ return new Promise((resolve, reject) => {
50
+ this._cache.promises.push({ reject, resolve });
51
+ });
52
+ }
53
+ this._cache.promises = [];
54
+ const result = await this._factory().catch((error) => {
55
+ this._rejectPromises({ error });
56
+ throw error;
57
+ });
58
+ this._cache.singleton = result;
59
+ this._cache.promises.forEach((promise) => promise.resolve(result));
60
+ delete this._cache.promises;
61
+ return result;
62
+ }
63
+ /**
64
+ * Return cached value, if there is no value cached return undefined.
65
+ * @template T
66
+ * @returns {T | undefined}
67
+ */
68
+ cached() {
69
+ if ('singleton' in this._cache) {
70
+ return this._cache.singleton;
71
+ }
72
+ return undefined;
73
+ }
74
+ }
75
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXN5bmMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2luZ2xldG9uL2FzeW5jLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUNILE1BQU0sT0FBTyxjQUFjO0lBQ2hCLE1BQU0sR0FJWixFQUFFLENBQUE7SUFFSSxRQUFRLENBQStCO0lBRWpELFlBQVksT0FBc0M7UUFDakQsSUFBSSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUE7SUFDeEIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsVUFBVTtRQUNULE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUE7UUFDNUIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFLENBQUMsQ0FBQTtJQUNoRSxDQUFDO0lBRVMsZUFBZSxDQUFDLE1BQXdCO1FBQ2pELE1BQU0sRUFBRSxLQUFLLEVBQUUsR0FBRyxNQUFNLENBQUE7UUFFeEIsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQzFCLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFBO1FBQ2pFLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFBO0lBQzVCLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsS0FBSyxDQUFDLE9BQU87UUFDWixJQUFJLFdBQVcsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDaEMsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVUsQ0FBQTtRQUM5QixDQUFDO1FBQ0QsSUFBSSxVQUFVLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQy9CLE9BQU8sSUFBSSxPQUFPLENBQUksQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7Z0JBQ3pDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUyxDQUFDLElBQUksQ0FBQyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFBO1lBQ2hELENBQUMsQ0FBQyxDQUFBO1FBQ0gsQ0FBQztRQUVELElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxHQUFHLEVBQUUsQ0FBQTtRQUN6QixNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtZQUNwRCxJQUFJLENBQUMsZUFBZSxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQTtZQUMvQixNQUFNLEtBQUssQ0FBQTtRQUNaLENBQUMsQ0FBQyxDQUFBO1FBQ0YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFBO1FBRTlCLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFBO1FBQ2xFLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUE7UUFFM0IsT0FBTyxNQUFNLENBQUE7SUFDZCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILE1BQU07UUFDTCxJQUFJLFdBQVcsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDaEMsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVUsQ0FBQTtRQUM5QixDQUFDO1FBRUQsT0FBTyxTQUFTLENBQUE7SUFDakIsQ0FBQztDQUNEIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHR5cGUgQW55RnVuY3Rpb25Qcm9taXNlTm9QYXJhbXM8VD4gPSAoKSA9PiBQcm9taXNlPFQ+XG5cbi8qKlxuICogVGhpcyBpcyBhIHNpbmdsZXRvbiB3cmFwcGVyIHRoYXQgaXMgdXNlZCB0byB3cmFwIGFyb3VuZCBhc3luYyBmdW5jdGlvbi4gV2UgaGF2ZSBhZGRpdGlvbmFsIGZ1bmN0aW9uYWxpdHkgdG8gY2xlYXIgdGhlIGNhY2hlXG4gKiBhbmQgcmVqZWN0IGFueSBzdWJzY3JpcHRpb25zIHRvIGluaXRpYWwgcHJvbWlzZS4gQW5kIHdlIGNhbiBhbHNvIGNoZWNrIGlmIHRoZXJlIGlzIGFueXRoaW5nIGkgY2FjaGVcbiAqIEBleGFtcGxlXG4gKiBleHBvcnQgY29uc3QgY29uZmlnU2luZ2xldG9uID0gbmV3IFNpbmdsZXRvbkFzeW5jKGFzeW5jICgpID0+IHtcbiAqICAgYXdhaXQgdGltZW91dCgzMDAwKVxuICogICByZXR1cm4ge1xuICogICAgIGVudjogcHJvY2Vzcy5lbnYuTk9ERV9FTlZcbiAqICAgfSBhcyBjb25zdFxuICogfSlcbiAqXG4gKiAvLyB1c2luZ1xuICogLy8gY2FjaGUgdmFsdWUgYmVmb3JlIHdlIGNhbGwgcHJvbWlzZVxuICogY29uc29sZS5sb2coY29uZmlnU2luZ2xldG9uKCkuY2FjaGUoKSkgLy8gdW5kZWZpbmVkXG4gKiBjb25zb2xlLmxvZygnTk9ERV9FTlY6ICcsIGF3YWl0IGNvbmZpZ1NpbmdsZXRvbigpLnByb21pc2UoKS5lbnYpIC8vIE5PREVfRU5WOiBwcm9kXG4gKiAvLyBjYWNoZSB2YWx1ZSBhZnRlciB3ZSBjYWxsIHByb21pc2VcbiAqIGNvbnNvbGUubG9nKGNvbmZpZ1NpbmdsZXRvbigpLmNhY2hlKCkpIC8vIHsgZW52OiAncHJvZCcgfVxuICovXG5leHBvcnQgY2xhc3MgU2luZ2xldG9uQXN5bmM8VD4ge1xuXHRwcm90ZWN0ZWQgX2NhY2hlOiB7XG5cdFx0c2luZ2xldG9uPzogVFxuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG5cdFx0cHJvbWlzZXM/OiB7IHJlc29sdmU6ICh2YWx1ZTogVCB8IFByb21pc2VMaWtlPFQ+KSA9PiB2b2lkOyByZWplY3Q6IChyZWFzb24/OiBhbnkpID0+IHZvaWQgfVtdXG5cdH0gPSB7fVxuXG5cdHByb3RlY3RlZCBfZmFjdG9yeTogQW55RnVuY3Rpb25Qcm9taXNlTm9QYXJhbXM8VD5cblxuXHRjb25zdHJ1Y3RvcihmYWN0b3J5OiBBbnlGdW5jdGlvblByb21pc2VOb1BhcmFtczxUPikge1xuXHRcdHRoaXMuX2ZhY3RvcnkgPSBmYWN0b3J5XG5cdH1cblxuXHQvKipcblx0ICogRW1wdHkgY2FjaGVkIHZhbHVlIGFuZCByZWplY3QgYW55IHN1YnNjcmliZWQgcHJvbWlzZSB0aGF0IGlzIHdhaXRpbmcgZm9yIHRoZSBpbml0aWFsIHByb21pc2UgdG8gYmUgcmVzb2x2ZWQuXG5cdCAqL1xuXHRjbGVhbkNhY2hlKCk6IHZvaWQge1xuXHRcdGRlbGV0ZSB0aGlzLl9jYWNoZS5zaW5nbGV0b25cblx0XHR0aGlzLl9yZWplY3RQcm9taXNlcyh7IGVycm9yOiBuZXcgRXJyb3IoJ0NhY2hlIHdhcyBjbGVhbmVkJykgfSlcblx0fVxuXG5cdHByb3RlY3RlZCBfcmVqZWN0UHJvbWlzZXMocGFyYW1zOiB7IGVycm9yOiBFcnJvciB9KTogdm9pZCB7XG5cdFx0Y29uc3QgeyBlcnJvciB9ID0gcGFyYW1zXG5cblx0XHRpZiAodGhpcy5fY2FjaGUucHJvbWlzZXMpIHtcblx0XHRcdHRoaXMuX2NhY2hlLnByb21pc2VzLmZvckVhY2goKHByb21pc2UpID0+IHByb21pc2UucmVqZWN0KGVycm9yKSlcblx0XHR9XG5cdFx0ZGVsZXRlIHRoaXMuX2NhY2hlLnByb21pc2VzXG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJuIHNpbmdsZXRvbiB2YWx1ZSBpbiBhIHByb21pc2UuIElmIHRoZXJlIGlzIG5vIGNhY2hlZCB2YWx1ZSB0aGVuIHRyeSB0byBnZXQgaXQgZnJvbSBmYWN0b3J5LlxuXHQgKiBAdGVtcGxhdGUgVFxuXHQgKiBAcmV0dXJucyB7UHJvbWlzZTxUPn1cblx0ICovXG5cdGFzeW5jIHByb21pc2UoKTogUHJvbWlzZTxUPiB7XG5cdFx0aWYgKCdzaW5nbGV0b24nIGluIHRoaXMuX2NhY2hlKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5fY2FjaGUuc2luZ2xldG9uIVxuXHRcdH1cblx0XHRpZiAoJ3Byb21pc2VzJyBpbiB0aGlzLl9jYWNoZSkge1xuXHRcdFx0cmV0dXJuIG5ldyBQcm9taXNlPFQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcblx0XHRcdFx0dGhpcy5fY2FjaGUucHJvbWlzZXMhLnB1c2goeyByZWplY3QsIHJlc29sdmUgfSlcblx0XHRcdH0pXG5cdFx0fVxuXG5cdFx0dGhpcy5fY2FjaGUucHJvbWlzZXMgPSBbXVxuXHRcdGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuX2ZhY3RvcnkoKS5jYXRjaCgoZXJyb3IpID0+IHtcblx0XHRcdHRoaXMuX3JlamVjdFByb21pc2VzKHsgZXJyb3IgfSlcblx0XHRcdHRocm93IGVycm9yXG5cdFx0fSlcblx0XHR0aGlzLl9jYWNoZS5zaW5nbGV0b24gPSByZXN1bHRcblxuXHRcdHRoaXMuX2NhY2hlLnByb21pc2VzLmZvckVhY2goKHByb21pc2UpID0+IHByb21pc2UucmVzb2x2ZShyZXN1bHQpKVxuXHRcdGRlbGV0ZSB0aGlzLl9jYWNoZS5wcm9taXNlc1xuXG5cdFx0cmV0dXJuIHJlc3VsdFxuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybiBjYWNoZWQgdmFsdWUsIGlmIHRoZXJlIGlzIG5vIHZhbHVlIGNhY2hlZCByZXR1cm4gdW5kZWZpbmVkLlxuXHQgKiBAdGVtcGxhdGUgVFxuXHQgKiBAcmV0dXJucyB7VCB8IHVuZGVmaW5lZH1cblx0ICovXG5cdGNhY2hlZCgpOiBUIHwgdW5kZWZpbmVkIHtcblx0XHRpZiAoJ3NpbmdsZXRvbicgaW4gdGhpcy5fY2FjaGUpIHtcblx0XHRcdHJldHVybiB0aGlzLl9jYWNoZS5zaW5nbGV0b24hXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHVuZGVmaW5lZFxuXHR9XG59XG4iXX0=
@@ -1,5 +1,4 @@
1
- import { AnyFunctionNoParams } from 'src/types/any-function/no-params'
2
-
1
+ export type AnyFunctionNoParams<T> = () => T;
3
2
  /**
4
3
  * Singleton patter wrapper function
5
4
  * @param {AnyFunctionNoParams<R>} factoryFn Factory function that is used to generate value that is going to be cached and return by
@@ -31,14 +30,5 @@ import { AnyFunctionNoParams } from 'src/types/any-function/no-params'
31
30
  * // using
32
31
  * console.log('NODE_ENV: ', config().env) // NODE_ENV: prod
33
32
  */
34
- export const singletonPattern = <R>(factoryFn: AnyFunctionNoParams<R>): AnyFunctionNoParams<R> => {
35
- const cache: { singleton?: R } = {}
36
-
37
- return (): R => {
38
- if ('singleton' in cache) {
39
- return cache.singleton!
40
- }
41
-
42
- return (cache.singleton = factoryFn())
43
- }
44
- }
33
+ export declare const singletonPattern: <R>(factoryFn: AnyFunctionNoParams<R>) => AnyFunctionNoParams<R>;
34
+ //# sourceMappingURL=pattern.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern.d.ts","sourceRoot":"","sources":["../../src/singleton/pattern.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,mBAAmB,CAAC,CAAC,IAAI,MAAM,CAAC,CAAA;AAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,eAAO,MAAM,gBAAgB,iBAAkB,oBAAoB,CAAC,CAAC,KAAG,oBAAoB,CAAC,CAU5F,CAAA"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Singleton patter wrapper function
3
+ * @param {AnyFunctionNoParams<R>} factoryFn Factory function that is used to generate value that is going to be cached and return by
4
+ * singleton.
5
+ * @return {AnyFunctionNoParams<R>} Function result that returns cached value.
6
+ * @example
7
+ * export class SomeClass {
8
+ * constructor(protected _param: string){ }
9
+ * get param(): string {
10
+ * return this._param
11
+ * }
12
+ * }
13
+ * export const someClassSingleton = singletonPattern((): SomeClass => {
14
+ * return new SomeClass('some param value')
15
+ * })
16
+ *
17
+ * // using
18
+ * console.log('param: ', someClassSingleton().param) // param: some param value
19
+ *
20
+ * ///////////////////////////////////////////
21
+ * // Or we can use it with simple function //
22
+ * ///////////////////////////////////////////
23
+ * export const config = singletonPattern(() => {
24
+ * return {
25
+ * env: process.NODE_ENV,
26
+ * } as const
27
+ * })
28
+ *
29
+ * // using
30
+ * console.log('NODE_ENV: ', config().env) // NODE_ENV: prod
31
+ */
32
+ export const singletonPattern = (factoryFn) => {
33
+ const cache = {};
34
+ return () => {
35
+ if ('singleton' in cache) {
36
+ return cache.singleton;
37
+ }
38
+ return (cache.singleton = factoryFn());
39
+ };
40
+ };
41
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF0dGVybi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zaW5nbGV0b24vcGF0dGVybi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBOEJHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sZ0JBQWdCLEdBQUcsQ0FBSSxTQUFpQyxFQUEwQixFQUFFO0lBQ2hHLE1BQU0sS0FBSyxHQUFzQixFQUFFLENBQUE7SUFFbkMsT0FBTyxHQUFNLEVBQUU7UUFDZCxJQUFJLFdBQVcsSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUMxQixPQUFPLEtBQUssQ0FBQyxTQUFVLENBQUE7UUFDeEIsQ0FBQztRQUVELE9BQU8sQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLFNBQVMsRUFBRSxDQUFDLENBQUE7SUFDdkMsQ0FBQyxDQUFBO0FBQ0YsQ0FBQyxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHR5cGUgQW55RnVuY3Rpb25Ob1BhcmFtczxUPiA9ICgpID0+IFRcblxuLyoqXG4gKiBTaW5nbGV0b24gcGF0dGVyIHdyYXBwZXIgZnVuY3Rpb25cbiAqIEBwYXJhbSB7QW55RnVuY3Rpb25Ob1BhcmFtczxSPn0gZmFjdG9yeUZuIEZhY3RvcnkgZnVuY3Rpb24gdGhhdCBpcyB1c2VkIHRvIGdlbmVyYXRlIHZhbHVlIHRoYXQgaXMgZ29pbmcgdG8gYmUgY2FjaGVkIGFuZCByZXR1cm4gYnlcbiAqIHNpbmdsZXRvbi5cbiAqIEByZXR1cm4ge0FueUZ1bmN0aW9uTm9QYXJhbXM8Uj59IEZ1bmN0aW9uIHJlc3VsdCB0aGF0IHJldHVybnMgY2FjaGVkIHZhbHVlLlxuICogQGV4YW1wbGVcbiAqIGV4cG9ydCBjbGFzcyBTb21lQ2xhc3Mge1xuICogICBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgX3BhcmFtOiBzdHJpbmcpeyB9XG4gKiAgIGdldCBwYXJhbSgpOiBzdHJpbmcge1xuICogICAgIHJldHVybiB0aGlzLl9wYXJhbVxuICogICB9XG4gKiB9XG4gKiBleHBvcnQgY29uc3Qgc29tZUNsYXNzU2luZ2xldG9uID0gc2luZ2xldG9uUGF0dGVybigoKTogU29tZUNsYXNzID0+IHtcbiAqICAgcmV0dXJuIG5ldyBTb21lQ2xhc3MoJ3NvbWUgcGFyYW0gdmFsdWUnKVxuICogfSlcbiAqXG4gKiAvLyB1c2luZ1xuICogY29uc29sZS5sb2coJ3BhcmFtOiAnLCBzb21lQ2xhc3NTaW5nbGV0b24oKS5wYXJhbSkgLy8gcGFyYW06IHNvbWUgcGFyYW0gdmFsdWVcbiAqXG4gKiAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gKiAvLyBPciB3ZSBjYW4gdXNlIGl0IHdpdGggc2ltcGxlIGZ1bmN0aW9uIC8vXG4gKiAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gKiBleHBvcnQgY29uc3QgY29uZmlnID0gc2luZ2xldG9uUGF0dGVybigoKSA9PiB7XG4gKiAgIHJldHVybiB7XG4gKiAgICAgZW52OiBwcm9jZXNzLk5PREVfRU5WLFxuICogICB9IGFzIGNvbnN0XG4gKiB9KVxuICpcbiAqIC8vIHVzaW5nXG4gKiBjb25zb2xlLmxvZygnTk9ERV9FTlY6ICcsIGNvbmZpZygpLmVudikgLy8gTk9ERV9FTlY6IHByb2RcbiAqL1xuZXhwb3J0IGNvbnN0IHNpbmdsZXRvblBhdHRlcm4gPSA8Uj4oZmFjdG9yeUZuOiBBbnlGdW5jdGlvbk5vUGFyYW1zPFI+KTogQW55RnVuY3Rpb25Ob1BhcmFtczxSPiA9PiB7XG5cdGNvbnN0IGNhY2hlOiB7IHNpbmdsZXRvbj86IFIgfSA9IHt9XG5cblx0cmV0dXJuICgpOiBSID0+IHtcblx0XHRpZiAoJ3NpbmdsZXRvbicgaW4gY2FjaGUpIHtcblx0XHRcdHJldHVybiBjYWNoZS5zaW5nbGV0b24hXG5cdFx0fVxuXG5cdFx0cmV0dXJuIChjYWNoZS5zaW5nbGV0b24gPSBmYWN0b3J5Rm4oKSlcblx0fVxufVxuIl19
@@ -0,0 +1,10 @@
1
+ export declare const stringUtil: {
2
+ /**
3
+ * Generate random UUID
4
+ * @return {string}
5
+ * @example
6
+ * console.log(stringUtil.uuid()) // "69bfda25-df3f-46b4-8bbb-955cf5193426"
7
+ */
8
+ generateUUID: () => string;
9
+ };
10
+ //# sourceMappingURL=string-util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"string-util.d.ts","sourceRoot":"","sources":["../src/string-util.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU;IACtB;;;;;OAKG;wBACe,MAAM;CAUxB,CAAA"}
@@ -0,0 +1,18 @@
1
+ export const stringUtil = {
2
+ /**
3
+ * Generate random UUID
4
+ * @return {string}
5
+ * @example
6
+ * console.log(stringUtil.uuid()) // "69bfda25-df3f-46b4-8bbb-955cf5193426"
7
+ */
8
+ generateUUID: () => {
9
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
10
+ const r = (Math.random() * 16) | 0;
11
+ if (c == 'x') {
12
+ return r.toString(16);
13
+ }
14
+ return ((r & 0x3) | 0x8).toString(16);
15
+ });
16
+ },
17
+ };
18
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RyaW5nLXV0aWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc3RyaW5nLXV0aWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3pCOzs7OztPQUtHO0lBQ0gsWUFBWSxFQUFFLEdBQVcsRUFBRTtRQUMxQixPQUFPLHNDQUFzQyxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRTtZQUNwRSxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUE7WUFDbEMsSUFBSSxDQUFDLElBQUksR0FBRyxFQUFFLENBQUM7Z0JBQ2QsT0FBTyxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFBO1lBQ3RCLENBQUM7WUFFRCxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFBO1FBQ3RDLENBQUMsQ0FBQyxDQUFBO0lBQ0gsQ0FBQztDQUNELENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY29uc3Qgc3RyaW5nVXRpbCA9IHtcblx0LyoqXG5cdCAqIEdlbmVyYXRlIHJhbmRvbSBVVUlEXG5cdCAqIEByZXR1cm4ge3N0cmluZ31cblx0ICogQGV4YW1wbGVcblx0ICogY29uc29sZS5sb2coc3RyaW5nVXRpbC51dWlkKCkpIC8vIFwiNjliZmRhMjUtZGYzZi00NmI0LThiYmItOTU1Y2Y1MTkzNDI2XCJcblx0ICovXG5cdGdlbmVyYXRlVVVJRDogKCk6IHN0cmluZyA9PiB7XG5cdFx0cmV0dXJuICd4eHh4eHh4eC14eHh4LTR4eHgteXh4eC14eHh4eHh4eHh4eHgnLnJlcGxhY2UoL1t4eV0vZywgKGMpID0+IHtcblx0XHRcdGNvbnN0IHIgPSAoTWF0aC5yYW5kb20oKSAqIDE2KSB8IDBcblx0XHRcdGlmIChjID09ICd4Jykge1xuXHRcdFx0XHRyZXR1cm4gci50b1N0cmluZygxNilcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuICgociAmIDB4MykgfCAweDgpLnRvU3RyaW5nKDE2KVxuXHRcdH0pXG5cdH0sXG59XG4iXX0=
@@ -0,0 +1,74 @@
1
+ export declare enum DurationUnit {
2
+ MILLISECOND = "MILLISECOND",
3
+ SECOND = "SECOND",
4
+ MINUTE = "MINUTE",
5
+ HOUR = "HOUR",
6
+ DAY = "DAY",
7
+ WEEK = "WEEK",
8
+ MONTH = "MONTH",
9
+ YEAR = "YEAR"
10
+ }
11
+ export type DurationUnitType = `${DurationUnit}`;
12
+ export declare class TimeUtil {
13
+ /**
14
+ * return date object with the current time
15
+ * @return {Date}
16
+ * @example
17
+ * console.log(new TimeUtil().now().toISOString()) // 2023-03-08T19:45:01.991Z
18
+ */
19
+ now(): Date;
20
+ /**
21
+ * Convert date object to unix timestamp (milliseconds)
22
+ * @param {Date} date
23
+ * @return {number}
24
+ * @example
25
+ * // timeUtil.now().toISOString() === 2023-03-08T19:45:01.991Z
26
+ * const timeUtil = new TimeUtil()
27
+ * console.log(timeUtil.dateToUnix(timeUtil.now())) // 1678304701991
28
+ */
29
+ dateToUnix(date: Date): number;
30
+ /**
31
+ * Convert date object to unix timestamp (seconds)
32
+ * @param {Date} date
33
+ * @return {number}
34
+ * @example
35
+ * // timeUtil.now().toISOString() === 2023-03-08T19:45:01.991Z
36
+ * const timeUtil = new TimeUtil()
37
+ * console.log(timeUtil.dateToUnix(timeUtil.now())) // 1678304701
38
+ */
39
+ dateToUnixSec(date: Date): number;
40
+ /**
41
+ * Convert unix timestamp (milliseconds) to date object
42
+ * @param {number} unix
43
+ * @return {Date}
44
+ * @example
45
+ * const timeUtil = new TimeUtil()
46
+ * console.log(timeUtil.unixToDate(1678304701991).toISOString()) // 2023-03-08T19:45:01.991Z
47
+ */
48
+ unixToDate(unix: number): Date;
49
+ /**
50
+ * Convert unix timestamp (seconds) to date object
51
+ * @param {number} unix
52
+ * @return {Date}
53
+ * @example
54
+ * const timeUtil = new TimeUtil()
55
+ * console.log(timeUtil.unixToDate(1678304701).toISOString()) // 2023-03-08T19:45:01.000Z
56
+ */
57
+ unixSecToDate(unix: number): Date;
58
+ /**
59
+ * Change the value of date by unit/value pare.
60
+ * @param {{units: DurationUnitType, value: number, date: Date}} params
61
+ * @return {Date}
62
+ * @example
63
+ * // timeUtil.now().toISOString() === 2023-03-08T19:45:01.991Z
64
+ * const timeUtil = new TimeUtil()
65
+ * console.log(timeUtil.addToDate({date: timeUtil.now(), unit: 'DAY', value: 1 }).toISOString()) // 2023-03-09T19:45:01.991Z
66
+ * console.log(timeUtil.addToDate({date: timeUtil.now(), unit: DurationUnit.MONTH, value: -1 }).toISOString()) //2023-02-08T19:45:01.991Z
67
+ */
68
+ addToDate(params: {
69
+ unit: DurationUnitType | DurationUnit;
70
+ value: number;
71
+ date: Date;
72
+ }): Date;
73
+ }
74
+ //# sourceMappingURL=time-util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time-util.d.ts","sourceRoot":"","sources":["../src/time-util.ts"],"names":[],"mappings":"AAKA,oBAAY,YAAY;IACvB,WAAW,gBAAgB;IAC3B,MAAM,WAAW;IACjB,MAAM,WAAW;IACjB,IAAI,SAAS;IACb,GAAG,QAAQ;IACX,IAAI,SAAS;IACb,KAAK,UAAU;IACf,IAAI,SAAS;CACb;AAED,MAAM,MAAM,gBAAgB,GAAG,GAAG,YAAY,EAAE,CAAA;AAEhD,qBAAa,QAAQ;IACpB;;;;;OAKG;IACH,GAAG,IAAI,IAAI;IAIX;;;;;;;;OAQG;IACH,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM;IAI9B;;;;;;;;OAQG;IACH,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM;IAIjC;;;;;;;OAOG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI9B;;;;;;;OAOG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIjC;;;;;;;;;OASG;IACH,SAAS,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,gBAAgB,GAAG,YAAY,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,IAAI,CAAA;KAAE,GAAG,IAAI;CAQ7F"}
@@ -0,0 +1,90 @@
1
+ import add from 'date-fns/add/index.js';
2
+ import addMilliseconds from 'date-fns/addMilliseconds/index.js';
3
+ import format from 'date-fns/format/index.js';
4
+ import parse from 'date-fns/parse/index.js';
5
+ export var DurationUnit;
6
+ (function (DurationUnit) {
7
+ DurationUnit["MILLISECOND"] = "MILLISECOND";
8
+ DurationUnit["SECOND"] = "SECOND";
9
+ DurationUnit["MINUTE"] = "MINUTE";
10
+ DurationUnit["HOUR"] = "HOUR";
11
+ DurationUnit["DAY"] = "DAY";
12
+ DurationUnit["WEEK"] = "WEEK";
13
+ DurationUnit["MONTH"] = "MONTH";
14
+ DurationUnit["YEAR"] = "YEAR";
15
+ })(DurationUnit || (DurationUnit = {}));
16
+ export class TimeUtil {
17
+ /**
18
+ * return date object with the current time
19
+ * @return {Date}
20
+ * @example
21
+ * console.log(new TimeUtil().now().toISOString()) // 2023-03-08T19:45:01.991Z
22
+ */
23
+ now() {
24
+ return new Date();
25
+ }
26
+ /**
27
+ * Convert date object to unix timestamp (milliseconds)
28
+ * @param {Date} date
29
+ * @return {number}
30
+ * @example
31
+ * // timeUtil.now().toISOString() === 2023-03-08T19:45:01.991Z
32
+ * const timeUtil = new TimeUtil()
33
+ * console.log(timeUtil.dateToUnix(timeUtil.now())) // 1678304701991
34
+ */
35
+ dateToUnix(date) {
36
+ return +format(date, 'T');
37
+ }
38
+ /**
39
+ * Convert date object to unix timestamp (seconds)
40
+ * @param {Date} date
41
+ * @return {number}
42
+ * @example
43
+ * // timeUtil.now().toISOString() === 2023-03-08T19:45:01.991Z
44
+ * const timeUtil = new TimeUtil()
45
+ * console.log(timeUtil.dateToUnix(timeUtil.now())) // 1678304701
46
+ */
47
+ dateToUnixSec(date) {
48
+ return +format(date, 't');
49
+ }
50
+ /**
51
+ * Convert unix timestamp (milliseconds) to date object
52
+ * @param {number} unix
53
+ * @return {Date}
54
+ * @example
55
+ * const timeUtil = new TimeUtil()
56
+ * console.log(timeUtil.unixToDate(1678304701991).toISOString()) // 2023-03-08T19:45:01.991Z
57
+ */
58
+ unixToDate(unix) {
59
+ return parse(unix.toString(), 'T', this.now());
60
+ }
61
+ /**
62
+ * Convert unix timestamp (seconds) to date object
63
+ * @param {number} unix
64
+ * @return {Date}
65
+ * @example
66
+ * const timeUtil = new TimeUtil()
67
+ * console.log(timeUtil.unixToDate(1678304701).toISOString()) // 2023-03-08T19:45:01.000Z
68
+ */
69
+ unixSecToDate(unix) {
70
+ return parse(unix.toString(), 't', this.now());
71
+ }
72
+ /**
73
+ * Change the value of date by unit/value pare.
74
+ * @param {{units: DurationUnitType, value: number, date: Date}} params
75
+ * @return {Date}
76
+ * @example
77
+ * // timeUtil.now().toISOString() === 2023-03-08T19:45:01.991Z
78
+ * const timeUtil = new TimeUtil()
79
+ * console.log(timeUtil.addToDate({date: timeUtil.now(), unit: 'DAY', value: 1 }).toISOString()) // 2023-03-09T19:45:01.991Z
80
+ * console.log(timeUtil.addToDate({date: timeUtil.now(), unit: DurationUnit.MONTH, value: -1 }).toISOString()) //2023-02-08T19:45:01.991Z
81
+ */
82
+ addToDate(params) {
83
+ const { date, unit, value } = params;
84
+ if (`${unit}` === 'MILLISECOND') {
85
+ return addMilliseconds(date, value);
86
+ }
87
+ return add(date, { [`${unit.toLowerCase()}s`]: value });
88
+ }
89
+ }
90
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZS11dGlsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3RpbWUtdXRpbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEdBQUcsTUFBTSx1QkFBdUIsQ0FBQTtBQUN2QyxPQUFPLGVBQWUsTUFBTSxtQ0FBbUMsQ0FBQTtBQUMvRCxPQUFPLE1BQU0sTUFBTSwwQkFBMEIsQ0FBQTtBQUM3QyxPQUFPLEtBQUssTUFBTSx5QkFBeUIsQ0FBQTtBQUUzQyxNQUFNLENBQU4sSUFBWSxZQVNYO0FBVEQsV0FBWSxZQUFZO0lBQ3ZCLDJDQUEyQixDQUFBO0lBQzNCLGlDQUFpQixDQUFBO0lBQ2pCLGlDQUFpQixDQUFBO0lBQ2pCLDZCQUFhLENBQUE7SUFDYiwyQkFBVyxDQUFBO0lBQ1gsNkJBQWEsQ0FBQTtJQUNiLCtCQUFlLENBQUE7SUFDZiw2QkFBYSxDQUFBO0FBQ2QsQ0FBQyxFQVRXLFlBQVksS0FBWixZQUFZLFFBU3ZCO0FBSUQsTUFBTSxPQUFPLFFBQVE7SUFDcEI7Ozs7O09BS0c7SUFDSCxHQUFHO1FBQ0YsT0FBTyxJQUFJLElBQUksRUFBRSxDQUFBO0lBQ2xCLENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNILFVBQVUsQ0FBQyxJQUFVO1FBQ3BCLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFBO0lBQzFCLENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNILGFBQWEsQ0FBQyxJQUFVO1FBQ3ZCLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFBO0lBQzFCLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0gsVUFBVSxDQUFDLElBQVk7UUFDdEIsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQTtJQUMvQyxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILGFBQWEsQ0FBQyxJQUFZO1FBQ3pCLE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUE7SUFDL0MsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNILFNBQVMsQ0FBQyxNQUE0RTtRQUNyRixNQUFNLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsR0FBRyxNQUFNLENBQUE7UUFDcEMsSUFBSSxHQUFHLElBQUksRUFBRSxLQUFLLGFBQWEsRUFBRSxDQUFDO1lBQ2pDLE9BQU8sZUFBZSxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQTtRQUNwQyxDQUFDO1FBRUQsT0FBTyxHQUFHLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsR0FBRyxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQTtJQUN4RCxDQUFDO0NBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgYWRkIGZyb20gJ2RhdGUtZm5zL2FkZC9pbmRleC5qcydcbmltcG9ydCBhZGRNaWxsaXNlY29uZHMgZnJvbSAnZGF0ZS1mbnMvYWRkTWlsbGlzZWNvbmRzL2luZGV4LmpzJ1xuaW1wb3J0IGZvcm1hdCBmcm9tICdkYXRlLWZucy9mb3JtYXQvaW5kZXguanMnXG5pbXBvcnQgcGFyc2UgZnJvbSAnZGF0ZS1mbnMvcGFyc2UvaW5kZXguanMnXG5cbmV4cG9ydCBlbnVtIER1cmF0aW9uVW5pdCB7XG5cdE1JTExJU0VDT05EID0gJ01JTExJU0VDT05EJyxcblx0U0VDT05EID0gJ1NFQ09ORCcsXG5cdE1JTlVURSA9ICdNSU5VVEUnLFxuXHRIT1VSID0gJ0hPVVInLFxuXHREQVkgPSAnREFZJyxcblx0V0VFSyA9ICdXRUVLJyxcblx0TU9OVEggPSAnTU9OVEgnLFxuXHRZRUFSID0gJ1lFQVInLFxufVxuXG5leHBvcnQgdHlwZSBEdXJhdGlvblVuaXRUeXBlID0gYCR7RHVyYXRpb25Vbml0fWBcblxuZXhwb3J0IGNsYXNzIFRpbWVVdGlsIHtcblx0LyoqXG5cdCAqIHJldHVybiBkYXRlIG9iamVjdCB3aXRoIHRoZSBjdXJyZW50IHRpbWVcblx0ICogQHJldHVybiB7RGF0ZX1cblx0ICogQGV4YW1wbGVcblx0ICogY29uc29sZS5sb2cobmV3IFRpbWVVdGlsKCkubm93KCkudG9JU09TdHJpbmcoKSkgLy8gMjAyMy0wMy0wOFQxOTo0NTowMS45OTFaXG5cdCAqL1xuXHRub3coKTogRGF0ZSB7XG5cdFx0cmV0dXJuIG5ldyBEYXRlKClcblx0fVxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0IGRhdGUgb2JqZWN0IHRvIHVuaXggdGltZXN0YW1wIChtaWxsaXNlY29uZHMpXG5cdCAqIEBwYXJhbSB7RGF0ZX0gZGF0ZVxuXHQgKiBAcmV0dXJuIHtudW1iZXJ9XG5cdCAqIEBleGFtcGxlXG5cdCAqIC8vIHRpbWVVdGlsLm5vdygpLnRvSVNPU3RyaW5nKCkgPT09IDIwMjMtMDMtMDhUMTk6NDU6MDEuOTkxWlxuXHQgKiBjb25zdCB0aW1lVXRpbCA9IG5ldyBUaW1lVXRpbCgpXG5cdCAqIGNvbnNvbGUubG9nKHRpbWVVdGlsLmRhdGVUb1VuaXgodGltZVV0aWwubm93KCkpKSAvLyAxNjc4MzA0NzAxOTkxXG5cdCAqL1xuXHRkYXRlVG9Vbml4KGRhdGU6IERhdGUpOiBudW1iZXIge1xuXHRcdHJldHVybiArZm9ybWF0KGRhdGUsICdUJylcblx0fVxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0IGRhdGUgb2JqZWN0IHRvIHVuaXggdGltZXN0YW1wIChzZWNvbmRzKVxuXHQgKiBAcGFyYW0ge0RhdGV9IGRhdGVcblx0ICogQHJldHVybiB7bnVtYmVyfVxuXHQgKiBAZXhhbXBsZVxuXHQgKiAvLyB0aW1lVXRpbC5ub3coKS50b0lTT1N0cmluZygpID09PSAyMDIzLTAzLTA4VDE5OjQ1OjAxLjk5MVpcblx0ICogY29uc3QgdGltZVV0aWwgPSBuZXcgVGltZVV0aWwoKVxuXHQgKiBjb25zb2xlLmxvZyh0aW1lVXRpbC5kYXRlVG9Vbml4KHRpbWVVdGlsLm5vdygpKSkgLy8gMTY3ODMwNDcwMVxuXHQgKi9cblx0ZGF0ZVRvVW5peFNlYyhkYXRlOiBEYXRlKTogbnVtYmVyIHtcblx0XHRyZXR1cm4gK2Zvcm1hdChkYXRlLCAndCcpXG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydCB1bml4IHRpbWVzdGFtcCAobWlsbGlzZWNvbmRzKSB0byBkYXRlIG9iamVjdFxuXHQgKiBAcGFyYW0ge251bWJlcn0gdW5peFxuXHQgKiBAcmV0dXJuIHtEYXRlfVxuXHQgKiBAZXhhbXBsZVxuXHQgKiBjb25zdCB0aW1lVXRpbCA9IG5ldyBUaW1lVXRpbCgpXG5cdCAqIGNvbnNvbGUubG9nKHRpbWVVdGlsLnVuaXhUb0RhdGUoMTY3ODMwNDcwMTk5MSkudG9JU09TdHJpbmcoKSkgLy8gMjAyMy0wMy0wOFQxOTo0NTowMS45OTFaXG5cdCAqL1xuXHR1bml4VG9EYXRlKHVuaXg6IG51bWJlcik6IERhdGUge1xuXHRcdHJldHVybiBwYXJzZSh1bml4LnRvU3RyaW5nKCksICdUJywgdGhpcy5ub3coKSlcblx0fVxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0IHVuaXggdGltZXN0YW1wIChzZWNvbmRzKSB0byBkYXRlIG9iamVjdFxuXHQgKiBAcGFyYW0ge251bWJlcn0gdW5peFxuXHQgKiBAcmV0dXJuIHtEYXRlfVxuXHQgKiBAZXhhbXBsZVxuXHQgKiBjb25zdCB0aW1lVXRpbCA9IG5ldyBUaW1lVXRpbCgpXG5cdCAqIGNvbnNvbGUubG9nKHRpbWVVdGlsLnVuaXhUb0RhdGUoMTY3ODMwNDcwMSkudG9JU09TdHJpbmcoKSkgLy8gMjAyMy0wMy0wOFQxOTo0NTowMS4wMDBaXG5cdCAqL1xuXHR1bml4U2VjVG9EYXRlKHVuaXg6IG51bWJlcik6IERhdGUge1xuXHRcdHJldHVybiBwYXJzZSh1bml4LnRvU3RyaW5nKCksICd0JywgdGhpcy5ub3coKSlcblx0fVxuXG5cdC8qKlxuXHQgKiBDaGFuZ2UgdGhlIHZhbHVlIG9mIGRhdGUgYnkgdW5pdC92YWx1ZSBwYXJlLlxuXHQgKiBAcGFyYW0ge3t1bml0czogRHVyYXRpb25Vbml0VHlwZSwgdmFsdWU6IG51bWJlciwgZGF0ZTogRGF0ZX19IHBhcmFtc1xuXHQgKiBAcmV0dXJuIHtEYXRlfVxuXHQgKiBAZXhhbXBsZVxuXHQgKiAvLyB0aW1lVXRpbC5ub3coKS50b0lTT1N0cmluZygpID09PSAyMDIzLTAzLTA4VDE5OjQ1OjAxLjk5MVpcblx0ICogY29uc3QgdGltZVV0aWwgPSBuZXcgVGltZVV0aWwoKVxuXHQgKiBjb25zb2xlLmxvZyh0aW1lVXRpbC5hZGRUb0RhdGUoe2RhdGU6IHRpbWVVdGlsLm5vdygpLCB1bml0OiAnREFZJywgdmFsdWU6IDEgfSkudG9JU09TdHJpbmcoKSkgLy8gMjAyMy0wMy0wOVQxOTo0NTowMS45OTFaXG5cdCAqIGNvbnNvbGUubG9nKHRpbWVVdGlsLmFkZFRvRGF0ZSh7ZGF0ZTogdGltZVV0aWwubm93KCksIHVuaXQ6IER1cmF0aW9uVW5pdC5NT05USCwgdmFsdWU6IC0xIH0pLnRvSVNPU3RyaW5nKCkpIC8vMjAyMy0wMi0wOFQxOTo0NTowMS45OTFaXG5cdCAqL1xuXHRhZGRUb0RhdGUocGFyYW1zOiB7IHVuaXQ6IER1cmF0aW9uVW5pdFR5cGUgfCBEdXJhdGlvblVuaXQ7IHZhbHVlOiBudW1iZXI7IGRhdGU6IERhdGUgfSk6IERhdGUge1xuXHRcdGNvbnN0IHsgZGF0ZSwgdW5pdCwgdmFsdWUgfSA9IHBhcmFtc1xuXHRcdGlmIChgJHt1bml0fWAgPT09ICdNSUxMSVNFQ09ORCcpIHtcblx0XHRcdHJldHVybiBhZGRNaWxsaXNlY29uZHMoZGF0ZSwgdmFsdWUpXG5cdFx0fVxuXG5cdFx0cmV0dXJuIGFkZChkYXRlLCB7IFtgJHt1bml0LnRvTG93ZXJDYXNlKCl9c2BdOiB2YWx1ZSB9KVxuXHR9XG59XG4iXX0=