@brandup/ui-helpers 1.0.43 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +134 -5
- package/dist/cjs/index.js +144 -24
- package/dist/cjs/index.js.map +1 -1
- package/dist/mjs/index.js +144 -24
- package/dist/mjs/index.js.map +1 -1
- package/dist/types.d.ts +153 -4
- package/package.json +1 -1
- package/tsconfig.json +3 -1
package/README.md
CHANGED
|
@@ -10,11 +10,47 @@ Install NPM package [@brandup/ui-helpers](https://www.npmjs.com/package/@brandup
|
|
|
10
10
|
npm i @brandup/ui-helpers@latest
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
+
## Helper groups
|
|
14
|
+
|
|
15
|
+
The package exposes the following named helper groups, plus a set of global prototype/static extensions:
|
|
16
|
+
|
|
17
|
+
| Import | Module |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| `ObjectHelper` | object property access by path |
|
|
20
|
+
| `TypeHelper` | runtime type checks |
|
|
21
|
+
| `FuncHelper` | timing / async helpers |
|
|
22
|
+
| `WordHelper` | word pluralization |
|
|
23
|
+
| `Guid` | GUID generation |
|
|
24
|
+
| (extensions) | `String.prototype.format`, `Object.prop`, `Object.hasProp` |
|
|
25
|
+
| (string) | `formatText` |
|
|
26
|
+
|
|
27
|
+
```TypeScript
|
|
28
|
+
import { ObjectHelper, TypeHelper, FuncHelper, WordHelper, Guid, formatText } from "@brandup/ui-helpers";
|
|
29
|
+
```
|
|
30
|
+
|
|
13
31
|
## String helpers
|
|
14
32
|
|
|
15
|
-
|
|
33
|
+
`formatText` substitutes `{...}` placeholders in a template.
|
|
34
|
+
|
|
35
|
+
Format with model values (placeholders are dot-separated property paths):
|
|
36
|
+
|
|
37
|
+
```TypeScript
|
|
38
|
+
import { formatText } from "@brandup/ui-helpers";
|
|
39
|
+
|
|
40
|
+
const result = formatText("Hello, {name}", { name: "Dmitry" }); // Hello, Dmitry
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Format with positional arguments (placeholders are zero-based indexes):
|
|
44
|
+
|
|
45
|
+
```TypeScript
|
|
46
|
+
const result = formatText("Hello, {0}", "Dmitry"); // Hello, Dmitry
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Extensions
|
|
16
50
|
|
|
17
|
-
|
|
51
|
+
Importing the package augments built-in prototypes with convenience methods.
|
|
52
|
+
|
|
53
|
+
### Format text
|
|
18
54
|
|
|
19
55
|
```TypeScript
|
|
20
56
|
const text = "Hello, {name}";
|
|
@@ -28,8 +64,6 @@ const text = "Hello, {0}";
|
|
|
28
64
|
const result = text.format("Dmitry"); // Hello, Dmitry
|
|
29
65
|
```
|
|
30
66
|
|
|
31
|
-
## Object helpers
|
|
32
|
-
|
|
33
67
|
### Get value by property path
|
|
34
68
|
|
|
35
69
|
```TypeScript
|
|
@@ -42,4 +76,99 @@ const model = {
|
|
|
42
76
|
const value = Object.prop(model, "header.value"); // return "Item"
|
|
43
77
|
|
|
44
78
|
const hasValue = Object.hasProp(model, "header.value"); // return true
|
|
45
|
-
```
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Object helpers
|
|
82
|
+
|
|
83
|
+
`ObjectHelper` reads nested values by a dot-separated path.
|
|
84
|
+
|
|
85
|
+
```TypeScript
|
|
86
|
+
import { ObjectHelper } from "@brandup/ui-helpers";
|
|
87
|
+
|
|
88
|
+
const model = { header: { value: "Item" } };
|
|
89
|
+
|
|
90
|
+
ObjectHelper.getProperty(model, "header.value"); // "Item"
|
|
91
|
+
ObjectHelper.hasProperty(model, "header.value"); // true
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
- `getProperty(obj, path)` — returns the resolved value; `null` when `obj` is falsy, `undefined` when any path segment is missing or a mid-path value is `null`/primitive.
|
|
95
|
+
- `hasProperty(obj, path)` — returns `true` if every segment of the path exists; safely returns `false` when a mid-path value is `null` or a primitive.
|
|
96
|
+
|
|
97
|
+
## Type helpers
|
|
98
|
+
|
|
99
|
+
`TypeHelper` provides runtime type checks.
|
|
100
|
+
|
|
101
|
+
```TypeScript
|
|
102
|
+
import { TypeHelper } from "@brandup/ui-helpers";
|
|
103
|
+
|
|
104
|
+
TypeHelper.isFunction(() => {}); // true
|
|
105
|
+
TypeHelper.isString("text"); // true
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
- `isFunction(value)` — `true` if the value is a function.
|
|
109
|
+
- `isString(value)` — `true` for string primitives and `String` instances.
|
|
110
|
+
|
|
111
|
+
## Word helpers
|
|
112
|
+
|
|
113
|
+
`WordHelper.getWordEnd` picks a grammatical ending that agrees with a count (Russian-style pluralization).
|
|
114
|
+
|
|
115
|
+
```TypeScript
|
|
116
|
+
import { WordHelper } from "@brandup/ui-helpers";
|
|
117
|
+
|
|
118
|
+
WordHelper.getWordEnd(1, "товар", "", "а", "ов"); // товар
|
|
119
|
+
WordHelper.getWordEnd(3, "товар", "", "а", "ов"); // товара
|
|
120
|
+
WordHelper.getWordEnd(5, "товар", "", "а", "ов"); // товаров
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
- `getWordEnd(count, word, one?, two?, five?)` — appends `one` for counts ending in 1, `two` for 2–4, and `five` for 0/5–9 and 11–20.
|
|
124
|
+
|
|
125
|
+
## Guid helpers
|
|
126
|
+
|
|
127
|
+
`Guid` generates and exposes UUID values.
|
|
128
|
+
|
|
129
|
+
```TypeScript
|
|
130
|
+
import { Guid } from "@brandup/ui-helpers";
|
|
131
|
+
|
|
132
|
+
const id = Guid.createGuid(); // e.g. "3f2a1b4c-9d8e-4a23-b123-456789abcdef"
|
|
133
|
+
Guid.empty; // "00000000-0000-0000-0000-000000000000"
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
- `createGuid()` — a new RFC 4122 UUID v4 string (lowercase, uses `crypto.randomUUID()`).
|
|
137
|
+
- `empty` — the all-zero UUID constant.
|
|
138
|
+
|
|
139
|
+
## Func helpers
|
|
140
|
+
|
|
141
|
+
`FuncHelper` contains timing and async utilities.
|
|
142
|
+
|
|
143
|
+
```TypeScript
|
|
144
|
+
import { FuncHelper } from "@brandup/ui-helpers";
|
|
145
|
+
|
|
146
|
+
// Resolve after 500ms (cancellable via AbortSignal)
|
|
147
|
+
await FuncHelper.delay(500);
|
|
148
|
+
|
|
149
|
+
// Keep a loading state visible for at least 1000ms
|
|
150
|
+
const data = await FuncHelper.minWaitAsync(() => loadData(), 1000);
|
|
151
|
+
|
|
152
|
+
// Reject with TimeoutError if the request takes longer than 5000ms
|
|
153
|
+
const result = await FuncHelper.timeout(fetch("/api"), 5000);
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Detect a timeout by checking the error type:
|
|
157
|
+
|
|
158
|
+
```TypeScript
|
|
159
|
+
import { FuncHelper } from "@brandup/ui-helpers";
|
|
160
|
+
|
|
161
|
+
try {
|
|
162
|
+
const result = await FuncHelper.timeout(fetch("/api"), 5000);
|
|
163
|
+
} catch (e) {
|
|
164
|
+
if (e instanceof FuncHelper.TimeoutError) {
|
|
165
|
+
console.log("Request timed out");
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
- `minWait(func, minTime?)` — wraps a callback so it runs no sooner than `minTime` ms after wrapping.
|
|
171
|
+
- `minWaitAsync(func, minTime?, abort?)` — awaits an async operation, padding so it settles no sooner than `minTime` ms.
|
|
172
|
+
- `delay(time, abort?)` — a promise resolved after `time` ms; rejects on abort.
|
|
173
|
+
- `timeout(promise, timeout, abort?)` — races `promise` against `timeout` ms; rejects with a `TimeoutError` on timeout. Throws synchronously if `timeout ≤ 0`.
|
|
174
|
+
- `TimeoutError` — error class thrown by `timeout` when the time limit is exceeded.
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,23 +1,46 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Reads a nested property value from an object by a dot-separated path.
|
|
5
|
+
*
|
|
6
|
+
* @param obj Source object to read from.
|
|
7
|
+
* @param path Dot-separated property path, e.g. `"header.value"`.
|
|
8
|
+
* @returns The resolved value; `null` when `obj` is falsy, or `undefined` when
|
|
9
|
+
* any segment of the path does not exist.
|
|
10
|
+
* @example
|
|
11
|
+
* getProperty({ header: { value: "Item" } }, "header.value"); // "Item"
|
|
12
|
+
*/
|
|
3
13
|
function getProperty(obj, path) {
|
|
4
14
|
if (!obj)
|
|
5
15
|
return null;
|
|
6
16
|
const props = path.split('.');
|
|
7
17
|
for (let i = 0; i < props.length; i++) {
|
|
8
18
|
const name = props[i];
|
|
19
|
+
if (obj == null || (typeof obj !== "object" && typeof obj !== "function"))
|
|
20
|
+
return undefined;
|
|
9
21
|
if (!(name in obj))
|
|
10
22
|
return undefined;
|
|
11
23
|
obj = obj[name];
|
|
12
24
|
}
|
|
13
25
|
return obj;
|
|
14
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Determines whether an object has a nested property at the given dot-separated path.
|
|
29
|
+
*
|
|
30
|
+
* @param obj Source object to inspect.
|
|
31
|
+
* @param path Dot-separated property path, e.g. `"header.value"`.
|
|
32
|
+
* @returns `true` if every segment of the path exists, otherwise `false`.
|
|
33
|
+
* @example
|
|
34
|
+
* hasProperty({ header: { value: "Item" } }, "header.value"); // true
|
|
35
|
+
*/
|
|
15
36
|
function hasProperty(obj, path) {
|
|
16
37
|
if (!obj)
|
|
17
38
|
return false;
|
|
18
39
|
const props = path.split('.');
|
|
19
40
|
for (let i = 0; i < props.length; i++) {
|
|
20
41
|
const name = props[i];
|
|
42
|
+
if (obj == null || (typeof obj !== "object" && typeof obj !== "function"))
|
|
43
|
+
return false;
|
|
21
44
|
if (!(name in obj))
|
|
22
45
|
return false;
|
|
23
46
|
obj = obj[name];
|
|
@@ -31,9 +54,23 @@ var object = /*#__PURE__*/Object.freeze({
|
|
|
31
54
|
hasProperty: hasProperty
|
|
32
55
|
});
|
|
33
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Determines whether the given value is a function.
|
|
59
|
+
*
|
|
60
|
+
* @param value Value to test.
|
|
61
|
+
* @returns `true` if the value is a function, otherwise `false`.
|
|
62
|
+
*/
|
|
34
63
|
function isFunction(value) {
|
|
35
64
|
return (typeof value === "function");
|
|
36
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Determines whether the given value is a string.
|
|
68
|
+
*
|
|
69
|
+
* Returns `true` for both string primitives and `String` object instances.
|
|
70
|
+
*
|
|
71
|
+
* @param value Value to test.
|
|
72
|
+
* @returns `true` if the value is a string, otherwise `false`.
|
|
73
|
+
*/
|
|
37
74
|
function isString(value) {
|
|
38
75
|
return (typeof value === "string" || value instanceof String);
|
|
39
76
|
}
|
|
@@ -44,6 +81,17 @@ var type = /*#__PURE__*/Object.freeze({
|
|
|
44
81
|
isString: isString
|
|
45
82
|
});
|
|
46
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Wraps a callback so that, when invoked, it runs no sooner than `minTime` milliseconds
|
|
86
|
+
* after this wrapper was created.
|
|
87
|
+
*
|
|
88
|
+
* The deadline is measured from the moment `minWait` is called. If `minTime` is omitted
|
|
89
|
+
* or falsy, the original function is returned unchanged.
|
|
90
|
+
*
|
|
91
|
+
* @param func Callback to defer.
|
|
92
|
+
* @param minTime Minimum delay in milliseconds before the callback may run.
|
|
93
|
+
* @returns A wrapped function with the same arguments as `func`.
|
|
94
|
+
*/
|
|
47
95
|
const minWait = (func, minTime) => {
|
|
48
96
|
if (!minTime)
|
|
49
97
|
return func;
|
|
@@ -51,12 +99,25 @@ const minWait = (func, minTime) => {
|
|
|
51
99
|
const ret = (...args) => {
|
|
52
100
|
const rightTime = getRightTime(beginTime, minTime);
|
|
53
101
|
if (rightTime)
|
|
54
|
-
|
|
102
|
+
setTimeout(() => func(...args), rightTime);
|
|
55
103
|
else
|
|
56
104
|
func(...args);
|
|
57
105
|
};
|
|
58
106
|
return ret;
|
|
59
107
|
};
|
|
108
|
+
/**
|
|
109
|
+
* Awaits an async operation and guarantees the returned promise settles no sooner than
|
|
110
|
+
* `minTime` milliseconds after invocation, padding with an extra delay when needed.
|
|
111
|
+
*
|
|
112
|
+
* Useful for keeping spinners/loading states visible for a minimum duration. If `minTime`
|
|
113
|
+
* is omitted or falsy, `func` is awaited and its result returned without padding.
|
|
114
|
+
*
|
|
115
|
+
* @typeParam TResult Result type produced by `func`.
|
|
116
|
+
* @param func Factory returning the promise to await.
|
|
117
|
+
* @param minTime Minimum total duration in milliseconds.
|
|
118
|
+
* @param abort Optional signal used to cancel the padding delay.
|
|
119
|
+
* @returns The result produced by `func`.
|
|
120
|
+
*/
|
|
60
121
|
async function minWaitAsync(func, minTime, abort) {
|
|
61
122
|
if (!minTime)
|
|
62
123
|
return func();
|
|
@@ -67,59 +128,107 @@ async function minWaitAsync(func, minTime, abort) {
|
|
|
67
128
|
await delay(rightTime, abort);
|
|
68
129
|
return result;
|
|
69
130
|
}
|
|
131
|
+
/** @internal */
|
|
70
132
|
const getRightTime = (start, minTime) => {
|
|
71
133
|
const finishTime = Date.now();
|
|
72
134
|
const w = minTime - (finishTime - start);
|
|
73
135
|
return w > minTime * 0.1 ? w : 0;
|
|
74
136
|
};
|
|
137
|
+
/**
|
|
138
|
+
* Returns a promise that resolves after the given number of milliseconds.
|
|
139
|
+
*
|
|
140
|
+
* If an already-aborted signal is supplied the promise rejects immediately; otherwise
|
|
141
|
+
* aborting before the delay elapses clears the timer and rejects with the abort reason.
|
|
142
|
+
*
|
|
143
|
+
* @param time Delay in milliseconds.
|
|
144
|
+
* @param abort Optional signal used to cancel the delay.
|
|
145
|
+
* @returns A promise that resolves when the delay elapses.
|
|
146
|
+
*/
|
|
75
147
|
function delay(time, abort) {
|
|
76
148
|
return new Promise((resolve, reject) => {
|
|
77
149
|
abort?.throwIfAborted();
|
|
78
150
|
const onAbort = () => {
|
|
79
|
-
|
|
151
|
+
clearTimeout(timer);
|
|
80
152
|
reject(abort?.reason);
|
|
81
153
|
};
|
|
82
|
-
const timer =
|
|
154
|
+
const timer = setTimeout(() => {
|
|
83
155
|
abort?.removeEventListener("abort", onAbort);
|
|
84
156
|
resolve();
|
|
85
157
|
}, time);
|
|
86
158
|
abort?.addEventListener("abort", onAbort, { once: true });
|
|
87
159
|
});
|
|
88
160
|
}
|
|
161
|
+
/**
|
|
162
|
+
* Races a promise against a timeout.
|
|
163
|
+
*
|
|
164
|
+
* Resolves/rejects with the original promise if it settles in time. If the timeout elapses
|
|
165
|
+
* first the returned promise rejects with a {@link TimeoutError}. Aborting via `abort`
|
|
166
|
+
* rejects with the signal's reason.
|
|
167
|
+
*
|
|
168
|
+
* @typeParam T Resolved value type of the wrapped promise.
|
|
169
|
+
* @param promise Promise to guard with a timeout.
|
|
170
|
+
* @param timeout Timeout in milliseconds; must be greater than `0`.
|
|
171
|
+
* @param abort Optional signal used to cancel the wait.
|
|
172
|
+
* @returns A promise mirroring `promise` unless the timeout or abort fires first.
|
|
173
|
+
* @throws {Error} When `timeout` is not greater than `0`.
|
|
174
|
+
*/
|
|
89
175
|
function timeout(promise, timeout, abort) {
|
|
176
|
+
if (timeout <= 0)
|
|
177
|
+
throw new Error("Invalid timeout value.");
|
|
90
178
|
return new Promise((resolve, reject) => {
|
|
91
|
-
if (timeout <= 0)
|
|
92
|
-
throw new Error("Invalid timeout value.");
|
|
93
179
|
abort?.throwIfAborted();
|
|
94
180
|
const onAbort = () => {
|
|
95
|
-
|
|
181
|
+
clearTimeout(timer);
|
|
96
182
|
reject(abort?.reason);
|
|
97
183
|
};
|
|
98
|
-
const timer =
|
|
184
|
+
const timer = setTimeout(() => {
|
|
99
185
|
abort?.removeEventListener("abort", onAbort);
|
|
100
|
-
reject(
|
|
186
|
+
reject(new TimeoutError());
|
|
101
187
|
}, timeout);
|
|
102
188
|
abort?.addEventListener("abort", onAbort, { once: true });
|
|
103
189
|
promise
|
|
104
190
|
.then(result => resolve(result))
|
|
105
191
|
.catch(reason => reject(reason))
|
|
106
192
|
.finally(() => {
|
|
107
|
-
|
|
193
|
+
clearTimeout(timer);
|
|
108
194
|
abort?.removeEventListener("abort", onAbort);
|
|
109
195
|
});
|
|
110
196
|
});
|
|
111
197
|
}
|
|
112
|
-
|
|
198
|
+
/** Thrown by {@link timeout} when the time limit is exceeded. */
|
|
199
|
+
class TimeoutError extends Error {
|
|
200
|
+
constructor() {
|
|
201
|
+
super("Timeout");
|
|
202
|
+
this.name = "TimeoutError";
|
|
203
|
+
}
|
|
204
|
+
}
|
|
113
205
|
|
|
114
206
|
var func = /*#__PURE__*/Object.freeze({
|
|
115
207
|
__proto__: null,
|
|
116
|
-
|
|
208
|
+
TimeoutError: TimeoutError,
|
|
117
209
|
delay: delay,
|
|
118
210
|
minWait: minWait,
|
|
119
211
|
minWaitAsync: minWaitAsync,
|
|
120
212
|
timeout: timeout
|
|
121
213
|
});
|
|
122
214
|
|
|
215
|
+
/**
|
|
216
|
+
* Returns a word combined with the grammatical ending that agrees with the given count.
|
|
217
|
+
*
|
|
218
|
+
* Implements Russian-style pluralization rules: the ending is chosen depending on
|
|
219
|
+
* whether the count ends in 1, in 2–4, or in 0/5–9 (with 11–14 treated as the "five" form).
|
|
220
|
+
*
|
|
221
|
+
* @param count Quantity that the word refers to.
|
|
222
|
+
* @param word Word stem to which the ending is appended.
|
|
223
|
+
* @param one Ending used for counts ending in 1 (but not 11).
|
|
224
|
+
* @param two Ending used for counts ending in 2–4 (but not 12–14).
|
|
225
|
+
* @param five Ending used for counts ending in 0, 5–9 and 11–20.
|
|
226
|
+
* @returns The word with the appropriate ending appended.
|
|
227
|
+
* @example
|
|
228
|
+
* getWordEnd(1, "товар", "", "а", "ов"); // "товар"
|
|
229
|
+
* getWordEnd(3, "товар", "", "а", "ов"); // "товара"
|
|
230
|
+
* getWordEnd(5, "товар", "", "а", "ов"); // "товаров"
|
|
231
|
+
*/
|
|
123
232
|
function getWordEnd(count, word, one, two, five) {
|
|
124
233
|
const tt = count % 100;
|
|
125
234
|
if (tt >= 5 && tt <= 20)
|
|
@@ -134,19 +243,15 @@ var word = /*#__PURE__*/Object.freeze({
|
|
|
134
243
|
getWordEnd: getWordEnd
|
|
135
244
|
});
|
|
136
245
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
result = result + i;
|
|
147
|
-
}
|
|
148
|
-
return result;
|
|
149
|
-
};
|
|
246
|
+
/**
|
|
247
|
+
* Generates a RFC 4122 UUID v4 string using `crypto.randomUUID()`.
|
|
248
|
+
*
|
|
249
|
+
* @returns A newly generated UUID string in `xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx` form.
|
|
250
|
+
* @example
|
|
251
|
+
* createGuid(); // e.g. "3f2a1b4c-9d8e-4a23-b123-456789abcdef"
|
|
252
|
+
*/
|
|
253
|
+
const createGuid = () => crypto.randomUUID();
|
|
254
|
+
/** The empty (all-zero) GUID value `"00000000-0000-0000-0000-000000000000"`. */
|
|
150
255
|
const empty = "00000000-0000-0000-0000-000000000000";
|
|
151
256
|
|
|
152
257
|
var guid = /*#__PURE__*/Object.freeze({
|
|
@@ -155,6 +260,21 @@ var guid = /*#__PURE__*/Object.freeze({
|
|
|
155
260
|
empty: empty
|
|
156
261
|
});
|
|
157
262
|
|
|
263
|
+
/**
|
|
264
|
+
* Formats a template string by substituting `{...}` placeholders.
|
|
265
|
+
*
|
|
266
|
+
* When the first argument is an object, placeholders are treated as dot-separated
|
|
267
|
+
* property paths resolved against that object (see {@link getProperty}). Otherwise
|
|
268
|
+
* placeholders are treated as zero-based indexes into the remaining arguments.
|
|
269
|
+
* Unresolved placeholders are replaced with an empty string.
|
|
270
|
+
*
|
|
271
|
+
* @param template Template containing `{name}` or `{0}` placeholders.
|
|
272
|
+
* @param args Either a single model object, or positional arguments.
|
|
273
|
+
* @returns The formatted string.
|
|
274
|
+
* @example
|
|
275
|
+
* formatText("Hello, {name}", { name: "Dmitry" }); // "Hello, Dmitry"
|
|
276
|
+
* formatText("Hello, {0}", "Dmitry"); // "Hello, Dmitry"
|
|
277
|
+
*/
|
|
158
278
|
function formatText(template, ...args) {
|
|
159
279
|
if (!args.length)
|
|
160
280
|
return template;
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../source/helpers/object.ts","../../source/helpers/type.ts","../../source/helpers/func.ts","../../source/helpers/word.ts","../../source/helpers/guid.ts","../../source/helpers/string.ts","../../source/helpers/ext.ts"],"sourcesContent":[null,null,null,null,null,null,null],"names":[],"mappings":";;AAAA,SAAS,WAAW,CAAC,GAAQ,EAAE,IAAY,EAAA;AAC1C,IAAA,IAAI,CAAC,GAAG;AACP,QAAA,OAAO,IAAI;IAEZ,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;AAE7B,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACtC,QAAA,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC;AACrB,QAAA,IAAI,EAAE,IAAI,IAAI,GAAG,CAAC;AACjB,YAAA,OAAO,SAAS;AAEjB,QAAA,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC;IAChB;AAEA,IAAA,OAAO,GAAG;AACX;AAEA,SAAS,WAAW,CAAC,GAAQ,EAAE,IAAY,EAAA;AAC1C,IAAA,IAAI,CAAC,GAAG;AACP,QAAA,OAAO,KAAK;IAEb,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;AAE7B,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACtC,QAAA,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC;AACrB,QAAA,IAAI,EAAE,IAAI,IAAI,GAAG,CAAC;AACjB,YAAA,OAAO,KAAK;AAEb,QAAA,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC;IAChB;AAEA,IAAA,OAAO,IAAI;AACZ;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../source/helpers/object.ts","../../source/helpers/type.ts","../../source/helpers/func.ts","../../source/helpers/word.ts","../../source/helpers/guid.ts","../../source/helpers/string.ts","../../source/helpers/ext.ts"],"sourcesContent":[null,null,null,null,null,null,null],"names":[],"mappings":";;AAAA;;;;;;;;;AASG;AACH,SAAS,WAAW,CAAC,GAAQ,EAAE,IAAY,EAAA;AAC1C,IAAA,IAAI,CAAC,GAAG;AACP,QAAA,OAAO,IAAI;IAEZ,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;AAE7B,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACtC,QAAA,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC;AACrB,QAAA,IAAI,GAAG,IAAI,IAAI,KAAK,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,GAAG,KAAK,UAAU,CAAC;AACxE,YAAA,OAAO,SAAS;AAEjB,QAAA,IAAI,EAAE,IAAI,IAAI,GAAG,CAAC;AACjB,YAAA,OAAO,SAAS;AAEjB,QAAA,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC;IAChB;AAEA,IAAA,OAAO,GAAG;AACX;AAEA;;;;;;;;AAQG;AACH,SAAS,WAAW,CAAC,GAAQ,EAAE,IAAY,EAAA;AAC1C,IAAA,IAAI,CAAC,GAAG;AACP,QAAA,OAAO,KAAK;IAEb,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;AAE7B,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACtC,QAAA,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC;AACrB,QAAA,IAAI,GAAG,IAAI,IAAI,KAAK,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,GAAG,KAAK,UAAU,CAAC;AACxE,YAAA,OAAO,KAAK;AAEb,QAAA,IAAI,EAAE,IAAI,IAAI,GAAG,CAAC;AACjB,YAAA,OAAO,KAAK;AAEb,QAAA,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC;IAChB;AAEA,IAAA,OAAO,IAAI;AACZ;;;;;;;;ACzDA;;;;;AAKG;AACH,SAAS,UAAU,CAAC,KAAU,EAAA;AAC7B,IAAA,QAAQ,OAAO,KAAK,KAAK,UAAU;AACpC;AAEA;;;;;;;AAOG;AACH,SAAS,QAAQ,CAAC,KAAU,EAAA;IAC3B,QAAQ,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,YAAY,MAAM;AAC7D;;;;;;;;ACpBA;;;;;;;;;;AAUG;AACH,MAAM,OAAO,GAAG,CAAC,IAA8B,EAAE,OAAgB,KAAI;AACpE,IAAA,IAAI,CAAC,OAAO;AACX,QAAA,OAAO,IAAI;AAEZ,IAAA,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE;AAE5B,IAAA,MAAM,GAAG,GAAG,CAAC,GAAG,IAAW,KAAI;QAC9B,MAAM,SAAS,GAAG,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC;AAClD,QAAA,IAAI,SAAS;AACZ,YAAA,UAAU,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,SAAS,CAAC;;AAE1C,YAAA,IAAI,CAAC,GAAG,IAAI,CAAC;AACf,IAAA,CAAC;AAED,IAAA,OAAO,GAAG;AACX,CAAC;AAED;;;;;;;;;;;;AAYG;AACH,eAAe,YAAY,CAAoB,IAA4B,EAAE,OAAgB,EAAE,KAAmB,EAAA;AACjH,IAAA,IAAI,CAAC,OAAO;QACX,OAAO,IAAI,EAAE;AAEd,IAAA,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE;AAC5B,IAAA,MAAM,MAAM,GAAG,MAAM,IAAI,EAAE;IAE3B,MAAM,SAAS,GAAG,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC;AAClD,IAAA,IAAI,SAAS;AACZ,QAAA,MAAM,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC;AAE9B,IAAA,OAAO,MAAM;AACd;AAEA;AACA,MAAM,YAAY,GAAG,CAAC,KAAa,EAAE,OAAe,KAAI;AACvD,IAAA,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE;IAC7B,MAAM,CAAC,GAAG,OAAO,IAAI,UAAU,GAAG,KAAK,CAAC;AAExC,IAAA,OAAO,CAAC,GAAG,OAAO,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC;AACjC,CAAC;AAED;;;;;;;;;AASG;AACH,SAAS,KAAK,CAAC,IAAY,EAAE,KAAmB,EAAA;IAC/C,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,KAAI;QAC5C,KAAK,EAAE,cAAc,EAAE;QAEvB,MAAM,OAAO,GAAG,MAAK;YACpB,YAAY,CAAC,KAAK,CAAC;AACnB,YAAA,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC;AACtB,QAAA,CAAC;AAED,QAAA,MAAM,KAAK,GAAG,UAAU,CAAC,MAAK;AAC7B,YAAA,KAAK,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC;AAC5C,YAAA,OAAO,EAAE;QACV,CAAC,EAAE,IAAI,CAAC;AAER,QAAA,KAAK,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAC1D,IAAA,CAAC,CAAC;AACH;AAEA;;;;;;;;;;;;;AAaG;AACH,SAAS,OAAO,CAAc,OAAmB,EAAE,OAAe,EAAE,KAAmB,EAAA;IACtF,IAAI,OAAO,IAAI,CAAC;AACf,QAAA,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC;IAE1C,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,KAAI;QACzC,KAAK,EAAE,cAAc,EAAE;QAEvB,MAAM,OAAO,GAAG,MAAK;YACpB,YAAY,CAAC,KAAK,CAAC;AACnB,YAAA,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC;AACtB,QAAA,CAAC;AAED,QAAA,MAAM,KAAK,GAAG,UAAU,CAAC,MAAK;AAC7B,YAAA,KAAK,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC;AAC5C,YAAA,MAAM,CAAC,IAAI,YAAY,EAAE,CAAC;QAC3B,CAAC,EAAE,OAAO,CAAC;AAEX,QAAA,KAAK,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QAEzD;aACE,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;aAC9B,KAAK,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC;aAC9B,OAAO,CAAC,MAAK;YACb,YAAY,CAAC,KAAK,CAAC;AACnB,YAAA,KAAK,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC;AAC7C,QAAA,CAAC,CAAC;AACJ,IAAA,CAAC,CAAC;AACH;AAEA;AACM,MAAO,YAAa,SAAQ,KAAK,CAAA;AACtC,IAAA,WAAA,GAAA;QACC,KAAK,CAAC,SAAS,CAAC;AAChB,QAAA,IAAI,CAAC,IAAI,GAAG,cAAc;IAC3B;AACA;;;;;;;;;;;AC5ID;;;;;;;;;;;;;;;;AAgBG;AACH,SAAS,UAAU,CAAC,KAAa,EAAE,IAAY,EAAE,GAAY,EAAE,GAAY,EAAE,IAAa,EAAA;AACzF,IAAA,MAAM,EAAE,GAAG,KAAK,GAAG,GAAG;AACtB,IAAA,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE;AACtB,QAAA,OAAO,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;AAE3B,IAAA,MAAM,CAAC,GAAG,KAAK,GAAG,EAAE;AAEpB,IAAA,QAAQ,CAAC,KAAK,CAAC;SACb,IAAI,IAAI,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE,CAAC,KAAK,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;AAE5F;;;;;;;AC3BA;;;;;;AAMG;AACH,MAAM,UAAU,GAAG,MAAc,MAAM,CAAC,UAAU,EAAE;AAEpD;AACA,MAAM,KAAK,GAAG,sCAAsC;;;;;;;;ACRpD;;;;;;;;;;;;;;AAcG;AACH,SAAS,UAAU,CAAC,QAAgB,EAAE,GAAG,IAAW,EAAA;IACnD,IAAI,CAAC,IAAI,CAAC,MAAM;AAAE,QAAA,OAAO,QAAQ;IAEjC,MAAM,GAAG,GAAG,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI;IAExD,OAAO,QAAQ,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,MAAM,EAAE,GAAG,KAAI;AACvD,QAAA,IAAI,GAAG;YAAE,OAAO,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE;aACtC;AACJ,YAAA,MAAM,UAAU,GAAG,QAAQ,CAAC,GAAG,CAAC;YAChC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,IAAI,CAAC,MAAM;AACjD,gBAAA,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE;QAC/B;AAEA,QAAA,OAAO,EAAE;AACV,IAAA,CAAC,CAAC;AACH;;ACOA,MAAM,CAAC,IAAI,GAAG,UAAU,GAAQ,EAAE,IAAY,EAAA;AAC7C,IAAA,OAAO,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC;AAC9B,CAAC;AAED,MAAM,CAAC,OAAO,GAAG,UAAU,GAAQ,EAAE,IAAY,EAAA;AAChD,IAAA,OAAO,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC;AAC9B,CAAC;AAED,MAAM,CAAC,SAAS,CAAC,MAAM,GAAG,UAAU,GAAG,IAAW,EAAA;IACjD,OAAO,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,GAAG,IAAI,CAAC;AAC5C,CAAC;;;;;;;;;"}
|
package/dist/mjs/index.js
CHANGED
|
@@ -1,21 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads a nested property value from an object by a dot-separated path.
|
|
3
|
+
*
|
|
4
|
+
* @param obj Source object to read from.
|
|
5
|
+
* @param path Dot-separated property path, e.g. `"header.value"`.
|
|
6
|
+
* @returns The resolved value; `null` when `obj` is falsy, or `undefined` when
|
|
7
|
+
* any segment of the path does not exist.
|
|
8
|
+
* @example
|
|
9
|
+
* getProperty({ header: { value: "Item" } }, "header.value"); // "Item"
|
|
10
|
+
*/
|
|
1
11
|
function getProperty(obj, path) {
|
|
2
12
|
if (!obj)
|
|
3
13
|
return null;
|
|
4
14
|
const props = path.split('.');
|
|
5
15
|
for (let i = 0; i < props.length; i++) {
|
|
6
16
|
const name = props[i];
|
|
17
|
+
if (obj == null || (typeof obj !== "object" && typeof obj !== "function"))
|
|
18
|
+
return undefined;
|
|
7
19
|
if (!(name in obj))
|
|
8
20
|
return undefined;
|
|
9
21
|
obj = obj[name];
|
|
10
22
|
}
|
|
11
23
|
return obj;
|
|
12
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Determines whether an object has a nested property at the given dot-separated path.
|
|
27
|
+
*
|
|
28
|
+
* @param obj Source object to inspect.
|
|
29
|
+
* @param path Dot-separated property path, e.g. `"header.value"`.
|
|
30
|
+
* @returns `true` if every segment of the path exists, otherwise `false`.
|
|
31
|
+
* @example
|
|
32
|
+
* hasProperty({ header: { value: "Item" } }, "header.value"); // true
|
|
33
|
+
*/
|
|
13
34
|
function hasProperty(obj, path) {
|
|
14
35
|
if (!obj)
|
|
15
36
|
return false;
|
|
16
37
|
const props = path.split('.');
|
|
17
38
|
for (let i = 0; i < props.length; i++) {
|
|
18
39
|
const name = props[i];
|
|
40
|
+
if (obj == null || (typeof obj !== "object" && typeof obj !== "function"))
|
|
41
|
+
return false;
|
|
19
42
|
if (!(name in obj))
|
|
20
43
|
return false;
|
|
21
44
|
obj = obj[name];
|
|
@@ -29,9 +52,23 @@ var object = /*#__PURE__*/Object.freeze({
|
|
|
29
52
|
hasProperty: hasProperty
|
|
30
53
|
});
|
|
31
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Determines whether the given value is a function.
|
|
57
|
+
*
|
|
58
|
+
* @param value Value to test.
|
|
59
|
+
* @returns `true` if the value is a function, otherwise `false`.
|
|
60
|
+
*/
|
|
32
61
|
function isFunction(value) {
|
|
33
62
|
return (typeof value === "function");
|
|
34
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Determines whether the given value is a string.
|
|
66
|
+
*
|
|
67
|
+
* Returns `true` for both string primitives and `String` object instances.
|
|
68
|
+
*
|
|
69
|
+
* @param value Value to test.
|
|
70
|
+
* @returns `true` if the value is a string, otherwise `false`.
|
|
71
|
+
*/
|
|
35
72
|
function isString(value) {
|
|
36
73
|
return (typeof value === "string" || value instanceof String);
|
|
37
74
|
}
|
|
@@ -42,6 +79,17 @@ var type = /*#__PURE__*/Object.freeze({
|
|
|
42
79
|
isString: isString
|
|
43
80
|
});
|
|
44
81
|
|
|
82
|
+
/**
|
|
83
|
+
* Wraps a callback so that, when invoked, it runs no sooner than `minTime` milliseconds
|
|
84
|
+
* after this wrapper was created.
|
|
85
|
+
*
|
|
86
|
+
* The deadline is measured from the moment `minWait` is called. If `minTime` is omitted
|
|
87
|
+
* or falsy, the original function is returned unchanged.
|
|
88
|
+
*
|
|
89
|
+
* @param func Callback to defer.
|
|
90
|
+
* @param minTime Minimum delay in milliseconds before the callback may run.
|
|
91
|
+
* @returns A wrapped function with the same arguments as `func`.
|
|
92
|
+
*/
|
|
45
93
|
const minWait = (func, minTime) => {
|
|
46
94
|
if (!minTime)
|
|
47
95
|
return func;
|
|
@@ -49,12 +97,25 @@ const minWait = (func, minTime) => {
|
|
|
49
97
|
const ret = (...args) => {
|
|
50
98
|
const rightTime = getRightTime(beginTime, minTime);
|
|
51
99
|
if (rightTime)
|
|
52
|
-
|
|
100
|
+
setTimeout(() => func(...args), rightTime);
|
|
53
101
|
else
|
|
54
102
|
func(...args);
|
|
55
103
|
};
|
|
56
104
|
return ret;
|
|
57
105
|
};
|
|
106
|
+
/**
|
|
107
|
+
* Awaits an async operation and guarantees the returned promise settles no sooner than
|
|
108
|
+
* `minTime` milliseconds after invocation, padding with an extra delay when needed.
|
|
109
|
+
*
|
|
110
|
+
* Useful for keeping spinners/loading states visible for a minimum duration. If `minTime`
|
|
111
|
+
* is omitted or falsy, `func` is awaited and its result returned without padding.
|
|
112
|
+
*
|
|
113
|
+
* @typeParam TResult Result type produced by `func`.
|
|
114
|
+
* @param func Factory returning the promise to await.
|
|
115
|
+
* @param minTime Minimum total duration in milliseconds.
|
|
116
|
+
* @param abort Optional signal used to cancel the padding delay.
|
|
117
|
+
* @returns The result produced by `func`.
|
|
118
|
+
*/
|
|
58
119
|
async function minWaitAsync(func, minTime, abort) {
|
|
59
120
|
if (!minTime)
|
|
60
121
|
return func();
|
|
@@ -65,59 +126,107 @@ async function minWaitAsync(func, minTime, abort) {
|
|
|
65
126
|
await delay(rightTime, abort);
|
|
66
127
|
return result;
|
|
67
128
|
}
|
|
129
|
+
/** @internal */
|
|
68
130
|
const getRightTime = (start, minTime) => {
|
|
69
131
|
const finishTime = Date.now();
|
|
70
132
|
const w = minTime - (finishTime - start);
|
|
71
133
|
return w > minTime * 0.1 ? w : 0;
|
|
72
134
|
};
|
|
135
|
+
/**
|
|
136
|
+
* Returns a promise that resolves after the given number of milliseconds.
|
|
137
|
+
*
|
|
138
|
+
* If an already-aborted signal is supplied the promise rejects immediately; otherwise
|
|
139
|
+
* aborting before the delay elapses clears the timer and rejects with the abort reason.
|
|
140
|
+
*
|
|
141
|
+
* @param time Delay in milliseconds.
|
|
142
|
+
* @param abort Optional signal used to cancel the delay.
|
|
143
|
+
* @returns A promise that resolves when the delay elapses.
|
|
144
|
+
*/
|
|
73
145
|
function delay(time, abort) {
|
|
74
146
|
return new Promise((resolve, reject) => {
|
|
75
147
|
abort?.throwIfAborted();
|
|
76
148
|
const onAbort = () => {
|
|
77
|
-
|
|
149
|
+
clearTimeout(timer);
|
|
78
150
|
reject(abort?.reason);
|
|
79
151
|
};
|
|
80
|
-
const timer =
|
|
152
|
+
const timer = setTimeout(() => {
|
|
81
153
|
abort?.removeEventListener("abort", onAbort);
|
|
82
154
|
resolve();
|
|
83
155
|
}, time);
|
|
84
156
|
abort?.addEventListener("abort", onAbort, { once: true });
|
|
85
157
|
});
|
|
86
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* Races a promise against a timeout.
|
|
161
|
+
*
|
|
162
|
+
* Resolves/rejects with the original promise if it settles in time. If the timeout elapses
|
|
163
|
+
* first the returned promise rejects with a {@link TimeoutError}. Aborting via `abort`
|
|
164
|
+
* rejects with the signal's reason.
|
|
165
|
+
*
|
|
166
|
+
* @typeParam T Resolved value type of the wrapped promise.
|
|
167
|
+
* @param promise Promise to guard with a timeout.
|
|
168
|
+
* @param timeout Timeout in milliseconds; must be greater than `0`.
|
|
169
|
+
* @param abort Optional signal used to cancel the wait.
|
|
170
|
+
* @returns A promise mirroring `promise` unless the timeout or abort fires first.
|
|
171
|
+
* @throws {Error} When `timeout` is not greater than `0`.
|
|
172
|
+
*/
|
|
87
173
|
function timeout(promise, timeout, abort) {
|
|
174
|
+
if (timeout <= 0)
|
|
175
|
+
throw new Error("Invalid timeout value.");
|
|
88
176
|
return new Promise((resolve, reject) => {
|
|
89
|
-
if (timeout <= 0)
|
|
90
|
-
throw new Error("Invalid timeout value.");
|
|
91
177
|
abort?.throwIfAborted();
|
|
92
178
|
const onAbort = () => {
|
|
93
|
-
|
|
179
|
+
clearTimeout(timer);
|
|
94
180
|
reject(abort?.reason);
|
|
95
181
|
};
|
|
96
|
-
const timer =
|
|
182
|
+
const timer = setTimeout(() => {
|
|
97
183
|
abort?.removeEventListener("abort", onAbort);
|
|
98
|
-
reject(
|
|
184
|
+
reject(new TimeoutError());
|
|
99
185
|
}, timeout);
|
|
100
186
|
abort?.addEventListener("abort", onAbort, { once: true });
|
|
101
187
|
promise
|
|
102
188
|
.then(result => resolve(result))
|
|
103
189
|
.catch(reason => reject(reason))
|
|
104
190
|
.finally(() => {
|
|
105
|
-
|
|
191
|
+
clearTimeout(timer);
|
|
106
192
|
abort?.removeEventListener("abort", onAbort);
|
|
107
193
|
});
|
|
108
194
|
});
|
|
109
195
|
}
|
|
110
|
-
|
|
196
|
+
/** Thrown by {@link timeout} when the time limit is exceeded. */
|
|
197
|
+
class TimeoutError extends Error {
|
|
198
|
+
constructor() {
|
|
199
|
+
super("Timeout");
|
|
200
|
+
this.name = "TimeoutError";
|
|
201
|
+
}
|
|
202
|
+
}
|
|
111
203
|
|
|
112
204
|
var func = /*#__PURE__*/Object.freeze({
|
|
113
205
|
__proto__: null,
|
|
114
|
-
|
|
206
|
+
TimeoutError: TimeoutError,
|
|
115
207
|
delay: delay,
|
|
116
208
|
minWait: minWait,
|
|
117
209
|
minWaitAsync: minWaitAsync,
|
|
118
210
|
timeout: timeout
|
|
119
211
|
});
|
|
120
212
|
|
|
213
|
+
/**
|
|
214
|
+
* Returns a word combined with the grammatical ending that agrees with the given count.
|
|
215
|
+
*
|
|
216
|
+
* Implements Russian-style pluralization rules: the ending is chosen depending on
|
|
217
|
+
* whether the count ends in 1, in 2–4, or in 0/5–9 (with 11–14 treated as the "five" form).
|
|
218
|
+
*
|
|
219
|
+
* @param count Quantity that the word refers to.
|
|
220
|
+
* @param word Word stem to which the ending is appended.
|
|
221
|
+
* @param one Ending used for counts ending in 1 (but not 11).
|
|
222
|
+
* @param two Ending used for counts ending in 2–4 (but not 12–14).
|
|
223
|
+
* @param five Ending used for counts ending in 0, 5–9 and 11–20.
|
|
224
|
+
* @returns The word with the appropriate ending appended.
|
|
225
|
+
* @example
|
|
226
|
+
* getWordEnd(1, "товар", "", "а", "ов"); // "товар"
|
|
227
|
+
* getWordEnd(3, "товар", "", "а", "ов"); // "товара"
|
|
228
|
+
* getWordEnd(5, "товар", "", "а", "ов"); // "товаров"
|
|
229
|
+
*/
|
|
121
230
|
function getWordEnd(count, word, one, two, five) {
|
|
122
231
|
const tt = count % 100;
|
|
123
232
|
if (tt >= 5 && tt <= 20)
|
|
@@ -132,19 +241,15 @@ var word = /*#__PURE__*/Object.freeze({
|
|
|
132
241
|
getWordEnd: getWordEnd
|
|
133
242
|
});
|
|
134
243
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
result = result + i;
|
|
145
|
-
}
|
|
146
|
-
return result;
|
|
147
|
-
};
|
|
244
|
+
/**
|
|
245
|
+
* Generates a RFC 4122 UUID v4 string using `crypto.randomUUID()`.
|
|
246
|
+
*
|
|
247
|
+
* @returns A newly generated UUID string in `xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx` form.
|
|
248
|
+
* @example
|
|
249
|
+
* createGuid(); // e.g. "3f2a1b4c-9d8e-4a23-b123-456789abcdef"
|
|
250
|
+
*/
|
|
251
|
+
const createGuid = () => crypto.randomUUID();
|
|
252
|
+
/** The empty (all-zero) GUID value `"00000000-0000-0000-0000-000000000000"`. */
|
|
148
253
|
const empty = "00000000-0000-0000-0000-000000000000";
|
|
149
254
|
|
|
150
255
|
var guid = /*#__PURE__*/Object.freeze({
|
|
@@ -153,6 +258,21 @@ var guid = /*#__PURE__*/Object.freeze({
|
|
|
153
258
|
empty: empty
|
|
154
259
|
});
|
|
155
260
|
|
|
261
|
+
/**
|
|
262
|
+
* Formats a template string by substituting `{...}` placeholders.
|
|
263
|
+
*
|
|
264
|
+
* When the first argument is an object, placeholders are treated as dot-separated
|
|
265
|
+
* property paths resolved against that object (see {@link getProperty}). Otherwise
|
|
266
|
+
* placeholders are treated as zero-based indexes into the remaining arguments.
|
|
267
|
+
* Unresolved placeholders are replaced with an empty string.
|
|
268
|
+
*
|
|
269
|
+
* @param template Template containing `{name}` or `{0}` placeholders.
|
|
270
|
+
* @param args Either a single model object, or positional arguments.
|
|
271
|
+
* @returns The formatted string.
|
|
272
|
+
* @example
|
|
273
|
+
* formatText("Hello, {name}", { name: "Dmitry" }); // "Hello, Dmitry"
|
|
274
|
+
* formatText("Hello, {0}", "Dmitry"); // "Hello, Dmitry"
|
|
275
|
+
*/
|
|
156
276
|
function formatText(template, ...args) {
|
|
157
277
|
if (!args.length)
|
|
158
278
|
return template;
|
package/dist/mjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../source/helpers/object.ts","../../source/helpers/type.ts","../../source/helpers/func.ts","../../source/helpers/word.ts","../../source/helpers/guid.ts","../../source/helpers/string.ts","../../source/helpers/ext.ts"],"sourcesContent":[null,null,null,null,null,null,null],"names":[],"mappings":"AAAA,SAAS,WAAW,CAAC,GAAQ,EAAE,IAAY,EAAA;AAC1C,IAAA,IAAI,CAAC,GAAG;AACP,QAAA,OAAO,IAAI;IAEZ,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;AAE7B,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACtC,QAAA,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC;AACrB,QAAA,IAAI,EAAE,IAAI,IAAI,GAAG,CAAC;AACjB,YAAA,OAAO,SAAS;AAEjB,QAAA,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC;IAChB;AAEA,IAAA,OAAO,GAAG;AACX;AAEA,SAAS,WAAW,CAAC,GAAQ,EAAE,IAAY,EAAA;AAC1C,IAAA,IAAI,CAAC,GAAG;AACP,QAAA,OAAO,KAAK;IAEb,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;AAE7B,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACtC,QAAA,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC;AACrB,QAAA,IAAI,EAAE,IAAI,IAAI,GAAG,CAAC;AACjB,YAAA,OAAO,KAAK;AAEb,QAAA,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC;IAChB;AAEA,IAAA,OAAO,IAAI;AACZ;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../source/helpers/object.ts","../../source/helpers/type.ts","../../source/helpers/func.ts","../../source/helpers/word.ts","../../source/helpers/guid.ts","../../source/helpers/string.ts","../../source/helpers/ext.ts"],"sourcesContent":[null,null,null,null,null,null,null],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads a nested property value from an object by a dot-separated path.
|
|
3
|
+
*
|
|
4
|
+
* @param obj Source object to read from.
|
|
5
|
+
* @param path Dot-separated property path, e.g. `"header.value"`.
|
|
6
|
+
* @returns The resolved value; `null` when `obj` is falsy, or `undefined` when
|
|
7
|
+
* any segment of the path does not exist.
|
|
8
|
+
* @example
|
|
9
|
+
* getProperty({ header: { value: "Item" } }, "header.value"); // "Item"
|
|
10
|
+
*/
|
|
1
11
|
declare function getProperty(obj: any, path: string): any;
|
|
12
|
+
/**
|
|
13
|
+
* Determines whether an object has a nested property at the given dot-separated path.
|
|
14
|
+
*
|
|
15
|
+
* @param obj Source object to inspect.
|
|
16
|
+
* @param path Dot-separated property path, e.g. `"header.value"`.
|
|
17
|
+
* @returns `true` if every segment of the path exists, otherwise `false`.
|
|
18
|
+
* @example
|
|
19
|
+
* hasProperty({ header: { value: "Item" } }, "header.value"); // true
|
|
20
|
+
*/
|
|
2
21
|
declare function hasProperty(obj: any, path: string): boolean;
|
|
3
22
|
|
|
4
23
|
declare const object_getProperty: typeof getProperty;
|
|
@@ -10,7 +29,21 @@ declare namespace object {
|
|
|
10
29
|
};
|
|
11
30
|
}
|
|
12
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Determines whether the given value is a function.
|
|
34
|
+
*
|
|
35
|
+
* @param value Value to test.
|
|
36
|
+
* @returns `true` if the value is a function, otherwise `false`.
|
|
37
|
+
*/
|
|
13
38
|
declare function isFunction(value: any): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Determines whether the given value is a string.
|
|
41
|
+
*
|
|
42
|
+
* Returns `true` for both string primitives and `String` object instances.
|
|
43
|
+
*
|
|
44
|
+
* @param value Value to test.
|
|
45
|
+
* @returns `true` if the value is a string, otherwise `false`.
|
|
46
|
+
*/
|
|
14
47
|
declare function isString(value: any): value is string | String;
|
|
15
48
|
|
|
16
49
|
declare const type_isFunction: typeof isFunction;
|
|
@@ -22,20 +55,72 @@ declare namespace type {
|
|
|
22
55
|
};
|
|
23
56
|
}
|
|
24
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Wraps a callback so that, when invoked, it runs no sooner than `minTime` milliseconds
|
|
60
|
+
* after this wrapper was created.
|
|
61
|
+
*
|
|
62
|
+
* The deadline is measured from the moment `minWait` is called. If `minTime` is omitted
|
|
63
|
+
* or falsy, the original function is returned unchanged.
|
|
64
|
+
*
|
|
65
|
+
* @param func Callback to defer.
|
|
66
|
+
* @param minTime Minimum delay in milliseconds before the callback may run.
|
|
67
|
+
* @returns A wrapped function with the same arguments as `func`.
|
|
68
|
+
*/
|
|
25
69
|
declare const minWait: (func: (...args: any[]) => void, minTime?: number) => (...args: any[]) => void;
|
|
70
|
+
/**
|
|
71
|
+
* Awaits an async operation and guarantees the returned promise settles no sooner than
|
|
72
|
+
* `minTime` milliseconds after invocation, padding with an extra delay when needed.
|
|
73
|
+
*
|
|
74
|
+
* Useful for keeping spinners/loading states visible for a minimum duration. If `minTime`
|
|
75
|
+
* is omitted or falsy, `func` is awaited and its result returned without padding.
|
|
76
|
+
*
|
|
77
|
+
* @typeParam TResult Result type produced by `func`.
|
|
78
|
+
* @param func Factory returning the promise to await.
|
|
79
|
+
* @param minTime Minimum total duration in milliseconds.
|
|
80
|
+
* @param abort Optional signal used to cancel the padding delay.
|
|
81
|
+
* @returns The result produced by `func`.
|
|
82
|
+
*/
|
|
26
83
|
declare function minWaitAsync<TResult = unknown>(func: () => Promise<TResult>, minTime?: number, abort?: AbortSignal): Promise<TResult>;
|
|
84
|
+
/**
|
|
85
|
+
* Returns a promise that resolves after the given number of milliseconds.
|
|
86
|
+
*
|
|
87
|
+
* If an already-aborted signal is supplied the promise rejects immediately; otherwise
|
|
88
|
+
* aborting before the delay elapses clears the timer and rejects with the abort reason.
|
|
89
|
+
*
|
|
90
|
+
* @param time Delay in milliseconds.
|
|
91
|
+
* @param abort Optional signal used to cancel the delay.
|
|
92
|
+
* @returns A promise that resolves when the delay elapses.
|
|
93
|
+
*/
|
|
27
94
|
declare function delay(time: number, abort?: AbortSignal): Promise<void>;
|
|
95
|
+
/**
|
|
96
|
+
* Races a promise against a timeout.
|
|
97
|
+
*
|
|
98
|
+
* Resolves/rejects with the original promise if it settles in time. If the timeout elapses
|
|
99
|
+
* first the returned promise rejects with a {@link TimeoutError}. Aborting via `abort`
|
|
100
|
+
* rejects with the signal's reason.
|
|
101
|
+
*
|
|
102
|
+
* @typeParam T Resolved value type of the wrapped promise.
|
|
103
|
+
* @param promise Promise to guard with a timeout.
|
|
104
|
+
* @param timeout Timeout in milliseconds; must be greater than `0`.
|
|
105
|
+
* @param abort Optional signal used to cancel the wait.
|
|
106
|
+
* @returns A promise mirroring `promise` unless the timeout or abort fires first.
|
|
107
|
+
* @throws {Error} When `timeout` is not greater than `0`.
|
|
108
|
+
*/
|
|
28
109
|
declare function timeout<T = unknown>(promise: Promise<T>, timeout: number, abort?: AbortSignal): Promise<T>;
|
|
29
|
-
|
|
110
|
+
/** Thrown by {@link timeout} when the time limit is exceeded. */
|
|
111
|
+
declare class TimeoutError extends Error {
|
|
112
|
+
constructor();
|
|
113
|
+
}
|
|
30
114
|
|
|
31
|
-
|
|
115
|
+
type func_TimeoutError = TimeoutError;
|
|
116
|
+
declare const func_TimeoutError: typeof TimeoutError;
|
|
32
117
|
declare const func_delay: typeof delay;
|
|
33
118
|
declare const func_minWait: typeof minWait;
|
|
34
119
|
declare const func_minWaitAsync: typeof minWaitAsync;
|
|
35
120
|
declare const func_timeout: typeof timeout;
|
|
36
121
|
declare namespace func {
|
|
37
122
|
export {
|
|
38
|
-
|
|
123
|
+
func_TimeoutError as TimeoutError,
|
|
39
124
|
func_delay as delay,
|
|
40
125
|
func_minWait as minWait,
|
|
41
126
|
func_minWaitAsync as minWaitAsync,
|
|
@@ -43,6 +128,23 @@ declare namespace func {
|
|
|
43
128
|
};
|
|
44
129
|
}
|
|
45
130
|
|
|
131
|
+
/**
|
|
132
|
+
* Returns a word combined with the grammatical ending that agrees with the given count.
|
|
133
|
+
*
|
|
134
|
+
* Implements Russian-style pluralization rules: the ending is chosen depending on
|
|
135
|
+
* whether the count ends in 1, in 2–4, or in 0/5–9 (with 11–14 treated as the "five" form).
|
|
136
|
+
*
|
|
137
|
+
* @param count Quantity that the word refers to.
|
|
138
|
+
* @param word Word stem to which the ending is appended.
|
|
139
|
+
* @param one Ending used for counts ending in 1 (but not 11).
|
|
140
|
+
* @param two Ending used for counts ending in 2–4 (but not 12–14).
|
|
141
|
+
* @param five Ending used for counts ending in 0, 5–9 and 11–20.
|
|
142
|
+
* @returns The word with the appropriate ending appended.
|
|
143
|
+
* @example
|
|
144
|
+
* getWordEnd(1, "товар", "", "а", "ов"); // "товар"
|
|
145
|
+
* getWordEnd(3, "товар", "", "а", "ов"); // "товара"
|
|
146
|
+
* getWordEnd(5, "товар", "", "а", "ов"); // "товаров"
|
|
147
|
+
*/
|
|
46
148
|
declare function getWordEnd(count: number, word: string, one?: string, two?: string, five?: string): string;
|
|
47
149
|
|
|
48
150
|
declare const word_getWordEnd: typeof getWordEnd;
|
|
@@ -52,7 +154,15 @@ declare namespace word {
|
|
|
52
154
|
};
|
|
53
155
|
}
|
|
54
156
|
|
|
157
|
+
/**
|
|
158
|
+
* Generates a RFC 4122 UUID v4 string using `crypto.randomUUID()`.
|
|
159
|
+
*
|
|
160
|
+
* @returns A newly generated UUID string in `xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx` form.
|
|
161
|
+
* @example
|
|
162
|
+
* createGuid(); // e.g. "3f2a1b4c-9d8e-4a23-b123-456789abcdef"
|
|
163
|
+
*/
|
|
55
164
|
declare const createGuid: () => string;
|
|
165
|
+
/** The empty (all-zero) GUID value `"00000000-0000-0000-0000-000000000000"`. */
|
|
56
166
|
declare const empty = "00000000-0000-0000-0000-000000000000";
|
|
57
167
|
|
|
58
168
|
declare const guid_createGuid: typeof createGuid;
|
|
@@ -66,14 +176,53 @@ declare namespace guid {
|
|
|
66
176
|
|
|
67
177
|
declare global {
|
|
68
178
|
interface String {
|
|
179
|
+
/**
|
|
180
|
+
* Formats this string by substituting `{...}` placeholders.
|
|
181
|
+
*
|
|
182
|
+
* @param args Either a single model object whose properties fill named placeholders,
|
|
183
|
+
* or positional arguments referenced by zero-based index. See {@link formatText}.
|
|
184
|
+
* @returns The formatted string.
|
|
185
|
+
* @example
|
|
186
|
+
* "Hello, {name}".format({ name: "Dmitry" }); // "Hello, Dmitry"
|
|
187
|
+
* "Hello, {0}".format("Dmitry"); // "Hello, Dmitry"
|
|
188
|
+
*/
|
|
69
189
|
format(...args: any[]): string;
|
|
70
190
|
}
|
|
71
191
|
interface ObjectConstructor {
|
|
192
|
+
/**
|
|
193
|
+
* Reads a nested property value by a dot-separated path. See {@link getProperty}.
|
|
194
|
+
*
|
|
195
|
+
* @param obj Source object.
|
|
196
|
+
* @param path Dot-separated property path, e.g. `"header.value"`.
|
|
197
|
+
* @returns The resolved value, or `undefined`/`null` when not found.
|
|
198
|
+
*/
|
|
72
199
|
prop(obj: any, path: string): any;
|
|
200
|
+
/**
|
|
201
|
+
* Determines whether a nested property exists at a dot-separated path. See {@link hasProperty}.
|
|
202
|
+
*
|
|
203
|
+
* @param obj Source object.
|
|
204
|
+
* @param path Dot-separated property path, e.g. `"header.value"`.
|
|
205
|
+
* @returns `true` if the property exists, otherwise `false`.
|
|
206
|
+
*/
|
|
73
207
|
hasProp(obj: any, path: string): boolean;
|
|
74
208
|
}
|
|
75
209
|
}
|
|
76
210
|
|
|
77
|
-
|
|
211
|
+
/**
|
|
212
|
+
* Formats a template string by substituting `{...}` placeholders.
|
|
213
|
+
*
|
|
214
|
+
* When the first argument is an object, placeholders are treated as dot-separated
|
|
215
|
+
* property paths resolved against that object (see {@link getProperty}). Otherwise
|
|
216
|
+
* placeholders are treated as zero-based indexes into the remaining arguments.
|
|
217
|
+
* Unresolved placeholders are replaced with an empty string.
|
|
218
|
+
*
|
|
219
|
+
* @param template Template containing `{name}` or `{0}` placeholders.
|
|
220
|
+
* @param args Either a single model object, or positional arguments.
|
|
221
|
+
* @returns The formatted string.
|
|
222
|
+
* @example
|
|
223
|
+
* formatText("Hello, {name}", { name: "Dmitry" }); // "Hello, Dmitry"
|
|
224
|
+
* formatText("Hello, {0}", "Dmitry"); // "Hello, Dmitry"
|
|
225
|
+
*/
|
|
226
|
+
declare function formatText(template: string, ...args: any[]): string;
|
|
78
227
|
|
|
79
228
|
export { func as FuncHelper, guid as Guid, object as ObjectHelper, type as TypeHelper, word as WordHelper, formatText };
|
package/package.json
CHANGED
package/tsconfig.json
CHANGED
|
@@ -24,7 +24,9 @@
|
|
|
24
24
|
"esModuleInterop": true,
|
|
25
25
|
"forceConsistentCasingInFileNames": true,
|
|
26
26
|
"skipLibCheck": true,
|
|
27
|
-
"allowSyntheticDefaultImports": true
|
|
27
|
+
"allowSyntheticDefaultImports": true,
|
|
28
|
+
"typeRoots": ["../../node_modules/@types", "./node_modules/@types"],
|
|
29
|
+
"types": ["jest"]
|
|
28
30
|
},
|
|
29
31
|
"include": [
|
|
30
32
|
"source",
|