@pivanov/utils 0.0.3 โ 1.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.
- package/README.md +95 -340
- package/dist/cjs/assertion/index.js +7 -0
- package/dist/cjs/index.js +2 -2
- package/dist/cjs/object/index.js +7 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/promise/index.js +7 -0
- package/dist/cjs/string/index.js +7 -0
- package/dist/cjs/tools/index.js +7 -0
- package/dist/cjs/types/index.js +7 -0
- package/dist/esm/assertion/index.js +7 -0
- package/dist/esm/chunk-1rn730je.js +7 -0
- package/dist/esm/chunk-5nmphgya.js +8 -0
- package/dist/esm/chunk-bqewq152.js +8 -0
- package/dist/esm/chunk-f1nddzrj.js +6 -0
- package/dist/esm/chunk-hksj0qca.js +8 -0
- package/dist/esm/chunk-tdt3f0jc.js +8 -0
- package/dist/esm/index.js +2 -2
- package/dist/esm/object/index.js +7 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/promise/index.js +7 -0
- package/dist/esm/string/index.js +7 -0
- package/dist/esm/tools/index.js +7 -0
- package/dist/esm/types/index.js +7 -0
- package/dist/types/assertion/index.d.ts +145 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/object/index.d.ts +118 -0
- package/dist/types/promise/index.d.ts +81 -0
- package/dist/types/string/index.d.ts +127 -0
- package/dist/types/tools/cache-api/index.d.ts +75 -0
- package/dist/types/tools/deepClone.d.ts +2 -0
- package/dist/types/tools/dom.d.ts +82 -0
- package/dist/types/tools/eventBus/eventBus.d.ts +37 -0
- package/dist/types/tools/eventBus/index.d.ts +3 -0
- package/dist/types/tools/eventBus/types.d.ts +47 -0
- package/dist/types/tools/eventBus/useEventBus.d.ts +3 -0
- package/dist/types/tools/index.d.ts +5 -0
- package/dist/types/tools/isEqual.d.ts +21 -0
- package/dist/types/types/index.d.ts +61 -0
- package/package.json +65 -35
- package/dist/index.d.ts +0 -691
package/README.md
CHANGED
|
@@ -1,408 +1,163 @@
|
|
|
1
1
|
# @pivanov/utils
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
<i>A
|
|
5
|
-
<br />
|
|
6
|
-
<br />
|
|
4
|
+
<i>A focused collection of TypeScript utilities for modern web development.</i>
|
|
5
|
+
<br /><br />
|
|
7
6
|
<img src="https://img.shields.io/npm/v/@pivanov/utils?logo=npm" alt="NPM Version" />
|
|
8
|
-
 
|
|
9
|
-
<img src="https://img.shields.io/
|
|
10
|
-
 
|
|
7
|
+
|
|
8
|
+
<img src="https://img.shields.io/npm/dw/@pivanov/utils" alt="Weekly Downloads" />
|
|
9
|
+
|
|
11
10
|
<img src="https://github.com/pivanov/pivanov-utils/actions/workflows/ci.yml/badge.svg?branch=main" alt="CI Status" />
|
|
12
|
-
 
|
|
11
|
+
|
|
13
12
|
<img src="https://codecov.io/github/pivanov/pivanov-utils/graph/badge.svg?token=EPRKTP7D79" alt="Coverage Status" />
|
|
14
13
|
</p>
|
|
15
14
|
|
|
16
15
|
## Features
|
|
17
16
|
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
- ๐ฆ **Modular** - Organized into focused modules for easy navigation
|
|
23
|
-
- ๐ **Well Documented** - Detailed JSDoc comments and examples
|
|
17
|
+
- **Fully typed** - strict TypeScript across every module, literal-type preserving where it matters
|
|
18
|
+
- **Tree-shakeable** - ESM + CJS + per-module subpath exports, `"sideEffects": false`
|
|
19
|
+
- **Zero dependencies** - React is an optional peer dep only for the `useEventBus` hook
|
|
20
|
+
- **Well tested** - 200+ tests, real edge cases (circular refs, typed arrays, Buffers, symbols)
|
|
24
21
|
|
|
25
22
|
## Installation
|
|
26
23
|
|
|
27
24
|
```bash
|
|
28
|
-
|
|
29
|
-
# or
|
|
30
|
-
npm install @pivanov/utils
|
|
31
|
-
# or
|
|
32
|
-
yarn add @pivanov/utils
|
|
25
|
+
bun add @pivanov/utils
|
|
33
26
|
```
|
|
34
27
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
```typescript
|
|
38
|
-
import { camelCase } from '@pivanov/utils/string';
|
|
39
|
-
import { pick } from '@pivanov/utils/object';
|
|
40
|
-
import { isString } from '@pivanov/utils/assertion';
|
|
41
|
-
|
|
42
|
-
camelCase('foo-bar'); // 'fooBar'
|
|
43
|
-
pick({ name: 'John', age: 30 }, ['name']); // { name: 'John' }
|
|
44
|
-
isString('hello'); // true
|
|
28
|
+
```bash
|
|
29
|
+
npm install @pivanov/utils
|
|
45
30
|
```
|
|
46
31
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
### Type Guards & Assertions
|
|
50
|
-
|
|
51
|
-
Runtime type checking with TypeScript type narrowing.
|
|
52
|
-
|
|
53
|
-
```typescript
|
|
54
|
-
import {
|
|
55
|
-
isString,
|
|
56
|
-
isNumber,
|
|
57
|
-
isBoolean,
|
|
58
|
-
isObject,
|
|
59
|
-
isFunction,
|
|
60
|
-
isNull,
|
|
61
|
-
isUndefined,
|
|
62
|
-
} from '@pivanov/utils/assertion';
|
|
63
|
-
|
|
64
|
-
// Type guards automatically narrow TypeScript types
|
|
65
|
-
function processValue(value: unknown) {
|
|
66
|
-
if (isString(value)) {
|
|
67
|
-
return value.toUpperCase(); // TypeScript knows this is a string
|
|
68
|
-
}
|
|
69
|
-
if (isNumber(value)) {
|
|
70
|
-
return value.toFixed(2); // TypeScript knows this is a number
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Examples
|
|
75
|
-
isString('hello'); // true
|
|
76
|
-
isNumber(42); // true
|
|
77
|
-
isBoolean(true); // true
|
|
78
|
-
isObject({}); // true (plain objects only, not arrays)
|
|
79
|
-
isFunction(() => {}); // true
|
|
80
|
-
isNull(null); // true
|
|
81
|
-
isUndefined(undefined); // true
|
|
32
|
+
```bash
|
|
33
|
+
yarn add @pivanov/utils
|
|
82
34
|
```
|
|
83
35
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
Immutable object manipulation with full type safety.
|
|
87
|
-
|
|
88
|
-
```typescript
|
|
89
|
-
import { pick, omit, merge, deepMerge } from '@pivanov/utils/object';
|
|
90
|
-
|
|
91
|
-
// Pick specific properties
|
|
92
|
-
const user = { name: 'John', age: 30, email: 'john@example.com' };
|
|
93
|
-
pick(user, ['name', 'email']);
|
|
94
|
-
// { name: 'John', email: 'john@example.com' }
|
|
95
|
-
|
|
96
|
-
// Omit specific properties
|
|
97
|
-
omit(user, ['email']);
|
|
98
|
-
// { name: 'John', age: 30 }
|
|
99
|
-
|
|
100
|
-
// Shallow merge
|
|
101
|
-
merge({ a: 1, b: 2 }, { b: 3, c: 4 });
|
|
102
|
-
// { a: 1, b: 3, c: 4 }
|
|
103
|
-
|
|
104
|
-
// Deep merge with nested structures
|
|
105
|
-
deepMerge(
|
|
106
|
-
{ user: { name: 'John', settings: { theme: 'dark' } } },
|
|
107
|
-
{ user: { settings: { fontSize: 14 } } }
|
|
108
|
-
);
|
|
109
|
-
// { user: { name: 'John', settings: { theme: 'dark', fontSize: 14 } } }
|
|
36
|
+
```bash
|
|
37
|
+
pnpm add @pivanov/utils
|
|
110
38
|
```
|
|
111
39
|
|
|
112
|
-
|
|
40
|
+
## Quick start
|
|
113
41
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
import {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
kebabCase,
|
|
121
|
-
slugify,
|
|
122
|
-
capitalize,
|
|
123
|
-
uncapitalize,
|
|
124
|
-
capitalizeFirstLetter,
|
|
125
|
-
} from '@pivanov/utils/string';
|
|
126
|
-
|
|
127
|
-
// Case transformations
|
|
128
|
-
camelCase('foo-bar'); // 'fooBar'
|
|
129
|
-
camelCase('FOO_BAR'); // 'fooBar'
|
|
130
|
-
|
|
131
|
-
pascalCase('foo-bar'); // 'FooBar'
|
|
132
|
-
pascalCase('foo_bar_baz'); // 'FooBarBaz'
|
|
133
|
-
|
|
134
|
-
kebabCase('fooBar'); // 'foo-bar'
|
|
135
|
-
kebabCase('XMLHttpRequest'); // 'xml-http-request'
|
|
136
|
-
|
|
137
|
-
slugify('Hello World!'); // 'hello-world'
|
|
138
|
-
slugify('รber Cafรฉ'); // 'uber-cafe'
|
|
139
|
-
|
|
140
|
-
// Capitalization with TypeScript support
|
|
141
|
-
capitalize('hello'); // 'Hello' (type: Capitalize<'hello'>)
|
|
142
|
-
uncapitalize('Hello'); // 'hello' (type: Uncapitalize<'Hello'>)
|
|
143
|
-
capitalizeFirstLetter('hello world'); // 'Hello world'
|
|
42
|
+
```ts
|
|
43
|
+
import { camelCase, snakeCase, slugify } from '@pivanov/utils/string';
|
|
44
|
+
import { pick, groupBy, deepMerge } from '@pivanov/utils/object';
|
|
45
|
+
import { isString, isNil, isDefined } from '@pivanov/utils/assertion';
|
|
46
|
+
import { sleep, timeout, retry, parallelLimit } from '@pivanov/utils/promise';
|
|
47
|
+
import { deepClone, isEqual, busDispatch, useEventBus } from '@pivanov/utils/tools';
|
|
144
48
|
```
|
|
145
49
|
|
|
146
|
-
|
|
50
|
+
## What's inside
|
|
147
51
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
52
|
+
| Module | Surface |
|
|
53
|
+
|---|---|
|
|
54
|
+
| `assertion` | `isString`, `isNumber`, `isBoolean`, `isFunction`, `isObject`, `isRecord`, `isNull`, `isUndefined`, `isNil`, `isDefined`, `isArray`, `isDate`, `isRegExp`, `isError`, `isPromise`, `isMap`, `isSet`, `isPrimitive`, `isEmpty` |
|
|
55
|
+
| `object` | `pick`, `omit`, `pickBy`, `omitBy`, `merge`, `deepMerge`, `mapValues`, `mapKeys`, `groupBy`, `invert`, `hasOwn`, `keysOf`, `entriesOf`, `fromEntries` |
|
|
56
|
+
| `promise` | `sleep`, `timeout`, `retry`, `defer`, `parallelLimit` - all AbortSignal-aware where relevant |
|
|
57
|
+
| `string` | `camelCase`, `pascalCase`, `kebabCase`, `snakeCase`, `titleCase`, `slugify`, `capitalize`, `uncapitalize`, `capitalizeFirstLetter`, `truncate`, `escapeHtml`, `escapeRegExp`, `words`, `lines` |
|
|
58
|
+
| `tools/deepClone` | Rich deep clone (prototypes, getters/setters, symbols, Buffers, TypedArrays, circular refs) |
|
|
59
|
+
| `tools/isEqual` | Deep equality with cycle detection; compares RegExp, Error, TypedArrays, ArrayBuffer |
|
|
60
|
+
| `tools/dom` | `isBrowser`, `checkVisibility`, `isInViewport`, `setStyleProperties`, `calculateRenderedTextWidth` |
|
|
61
|
+
| `tools/cache-api` | Typed wrapper over the browser Cache API, with TTL support |
|
|
62
|
+
| `tools/eventBus` | `busDispatch`, `busSubscribe`, `busOnce`, `useEventBus` - typed topics, optional error handler |
|
|
63
|
+
| `types` | `TDict`, `TObjType`, `DeepPartial`, `DeepReadonly`, `Mutable`, `Prettify` |
|
|
152
64
|
|
|
153
|
-
|
|
65
|
+
See the full **[API documentation](https://pivanov.github.io/pivanov-utils/)**.
|
|
154
66
|
|
|
155
|
-
|
|
67
|
+
## Tree shaking
|
|
156
68
|
|
|
157
|
-
|
|
158
|
-
import { sleep } from '@pivanov/utils/promise';
|
|
69
|
+
Subpath imports give the smallest bundles:
|
|
159
70
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
console.log('Done');
|
|
164
|
-
}
|
|
71
|
+
```ts
|
|
72
|
+
import { camelCase } from '@pivanov/utils/string';
|
|
73
|
+
import { deepClone } from '@pivanov/utils/tools';
|
|
165
74
|
```
|
|
166
75
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
High-performance deep cloning and comparison with circular reference handling.
|
|
76
|
+
Top-level imports tree-shake fine in modern bundlers:
|
|
170
77
|
|
|
171
|
-
```
|
|
172
|
-
import {
|
|
173
|
-
|
|
174
|
-
// Deep clone complex structures
|
|
175
|
-
const original = {
|
|
176
|
-
nested: { array: [1, 2, { value: 3 }] },
|
|
177
|
-
date: new Date(),
|
|
178
|
-
map: new Map([['key', 'value']]),
|
|
179
|
-
set: new Set([1, 2, 3]),
|
|
180
|
-
circular: {} as any,
|
|
181
|
-
};
|
|
182
|
-
original.circular = original; // Circular reference
|
|
183
|
-
|
|
184
|
-
const cloned = deepClone(original);
|
|
185
|
-
// Fully independent copy with circular references preserved
|
|
186
|
-
|
|
187
|
-
// Deep equality comparison
|
|
188
|
-
isEqual({ a: [1, 2, 3] }, { a: [1, 2, 3] }); // true
|
|
189
|
-
isEqual(new Date('2024-01-01'), new Date('2024-01-01')); // true
|
|
190
|
-
isEqual([1, 2, [3, 4]], [1, 2, [3, 4]]); // true
|
|
191
|
-
isEqual(new Set([1, 2]), new Set([2, 1])); // false (Sets maintain order)
|
|
78
|
+
```ts
|
|
79
|
+
import { camelCase, deepClone } from '@pivanov/utils';
|
|
192
80
|
```
|
|
193
81
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
- Primitives (string, number, boolean, null, undefined, symbol, bigint)
|
|
197
|
-
- Arrays (including sparse arrays)
|
|
198
|
-
- Plain objects (with getters/setters)
|
|
199
|
-
- Date, RegExp, Map, Set
|
|
200
|
-
- TypedArrays, ArrayBuffer, Buffer
|
|
201
|
-
- Circular references
|
|
82
|
+
## A few highlights
|
|
202
83
|
|
|
203
|
-
###
|
|
84
|
+
### Async that cancels
|
|
204
85
|
|
|
205
|
-
|
|
86
|
+
```ts
|
|
87
|
+
import { sleep, timeout, retry } from '@pivanov/utils/promise';
|
|
206
88
|
|
|
207
|
-
|
|
208
|
-
|
|
89
|
+
const ctrl = new AbortController();
|
|
90
|
+
await sleep(1000, ctrl.signal); // cancellable
|
|
91
|
+
await timeout(fetch('/slow'), 3000); // race with timer
|
|
92
|
+
await retry(() => fetch('/api'), { attempts: 5, backoff: (n) => 100 * 2 ** n });
|
|
93
|
+
```
|
|
209
94
|
|
|
210
|
-
|
|
211
|
-
type AppEvents = {
|
|
212
|
-
'user-logged-in': { id: number; name: string };
|
|
213
|
-
'data-updated': { timestamp: number };
|
|
214
|
-
'notification': { message: string; type: 'info' | 'error' };
|
|
215
|
-
};
|
|
95
|
+
### Typed event bus
|
|
216
96
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
useEventBus<AppEvents>('user-logged-in', (data) => {
|
|
220
|
-
console.log(`Welcome ${data.name}!`);
|
|
221
|
-
});
|
|
97
|
+
```ts
|
|
98
|
+
import { busDispatch, useEventBus, type IEventBus } from '@pivanov/utils/tools';
|
|
222
99
|
|
|
223
|
-
|
|
100
|
+
interface UserLoggedIn extends IEventBus<{ id: number; name: string }> {
|
|
101
|
+
topic: 'user:logged-in';
|
|
224
102
|
}
|
|
225
103
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
console.log('Updated at:', data.timestamp);
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
// Later: cleanup
|
|
232
|
-
unsubscribe();
|
|
233
|
-
|
|
234
|
-
// Dispatch events anywhere in your app
|
|
235
|
-
busDispatch<AppEvents>('user-logged-in', { id: 1, name: 'John' });
|
|
236
|
-
busDispatch<AppEvents>('notification', {
|
|
237
|
-
message: 'Settings saved',
|
|
238
|
-
type: 'info',
|
|
239
|
-
});
|
|
104
|
+
useEventBus<UserLoggedIn>('user:logged-in', (user) => console.log(user.name));
|
|
105
|
+
busDispatch<UserLoggedIn>('user:logged-in', { id: 1, name: 'Ada' });
|
|
240
106
|
```
|
|
241
107
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
- Fully type-safe with TypeScript
|
|
245
|
-
- Works across React and vanilla JavaScript
|
|
246
|
-
- Automatic cleanup with React hook
|
|
247
|
-
- Uses hashed topic names to avoid collisions
|
|
248
|
-
- Zero dependencies
|
|
249
|
-
|
|
250
|
-
### Browser Cache API
|
|
108
|
+
See the [Typed Events guide](https://pivanov.github.io/pivanov-utils/guides/typed-events) for an event-map pattern at scale.
|
|
251
109
|
|
|
252
|
-
|
|
110
|
+
### Cache with TTL
|
|
253
111
|
|
|
254
|
-
```
|
|
112
|
+
```ts
|
|
255
113
|
import {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
storageRemoveItem,
|
|
259
|
-
storageExists,
|
|
260
|
-
storageClear,
|
|
261
|
-
storageClearByPrefixOrSuffix,
|
|
262
|
-
storageGetAllKeys,
|
|
263
|
-
storageCalculateSize,
|
|
114
|
+
storageSetItemWithTTL,
|
|
115
|
+
storageGetItemWithTTL,
|
|
264
116
|
} from '@pivanov/utils/tools';
|
|
265
117
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
// Store data
|
|
269
|
-
await storageSetItem(CACHE_NAME, 'user-data', {
|
|
270
|
-
id: 1,
|
|
271
|
-
name: 'John',
|
|
272
|
-
bigNumber: BigInt(9007199254740991), // BigInt support!
|
|
273
|
-
});
|
|
274
|
-
|
|
275
|
-
// Retrieve data
|
|
276
|
-
const userData = await storageGetItem<{ id: number; name: string }>(
|
|
277
|
-
CACHE_NAME,
|
|
278
|
-
'user-data'
|
|
279
|
-
);
|
|
280
|
-
|
|
281
|
-
// Check existence
|
|
282
|
-
const exists = await storageExists(CACHE_NAME, 'user-data');
|
|
283
|
-
|
|
284
|
-
// Remove specific item
|
|
285
|
-
await storageRemoveItem(CACHE_NAME, 'user-data');
|
|
118
|
+
await storageSetItemWithTTL('app', 'token', 'abc123', 10 * 60 * 1000);
|
|
286
119
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
// Clear items by prefix
|
|
291
|
-
await storageClearByPrefixOrSuffix(CACHE_NAME, 'temp-', true);
|
|
292
|
-
|
|
293
|
-
// Clear items by suffix
|
|
294
|
-
await storageClearByPrefixOrSuffix(CACHE_NAME, '-cache', false);
|
|
295
|
-
|
|
296
|
-
// Calculate cache size (in bytes)
|
|
297
|
-
const totalSize = await storageCalculateSize(CACHE_NAME);
|
|
298
|
-
const itemSize = await storageCalculateSize(CACHE_NAME, 'user-data');
|
|
299
|
-
|
|
300
|
-
// Clear all cache
|
|
301
|
-
await storageClear(CACHE_NAME);
|
|
120
|
+
const token = await storageGetItemWithTTL<string>('app', 'token');
|
|
121
|
+
// null if missing or expired; expired entries are deleted on read
|
|
302
122
|
```
|
|
303
123
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
- Automatic JSON serialization/deserialization
|
|
307
|
-
- BigInt support (automatically converted to strings)
|
|
308
|
-
- Type-safe with generics
|
|
309
|
-
- Works with absolute URLs as keys
|
|
310
|
-
- Size calculation utilities
|
|
311
|
-
|
|
312
|
-
### DOM Utilities
|
|
313
|
-
|
|
314
|
-
Browser-safe DOM manipulation helpers.
|
|
315
|
-
|
|
316
|
-
```typescript
|
|
317
|
-
import {
|
|
318
|
-
isBrowser,
|
|
319
|
-
checkVisibility,
|
|
320
|
-
setStyleProperties,
|
|
321
|
-
calculateRenderedTextWidth,
|
|
322
|
-
} from '@pivanov/utils/tools';
|
|
124
|
+
### Deep clone that actually preserves shape
|
|
323
125
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
// Browser-only code
|
|
327
|
-
window.addEventListener('scroll', handleScroll);
|
|
328
|
-
}
|
|
126
|
+
```ts
|
|
127
|
+
import { deepClone } from '@pivanov/utils/tools';
|
|
329
128
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
element.classList.add('visible');
|
|
129
|
+
class User {
|
|
130
|
+
constructor(public name: string) {}
|
|
131
|
+
greet() { return `hi ${this.name}`; }
|
|
334
132
|
}
|
|
335
133
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
'--spacing': '1rem',
|
|
340
|
-
'--border-radius': '8px',
|
|
341
|
-
});
|
|
342
|
-
|
|
343
|
-
// Calculate text width for dynamic layouts
|
|
344
|
-
const width = calculateRenderedTextWidth('Hello World', 16);
|
|
345
|
-
const widthUppercase = calculateRenderedTextWidth('Hello World', 16, true);
|
|
346
|
-
const widthCustomFont = calculateRenderedTextWidth(
|
|
347
|
-
'Hello World',
|
|
348
|
-
16,
|
|
349
|
-
false,
|
|
350
|
-
'Arial'
|
|
351
|
-
);
|
|
134
|
+
const clone = deepClone(new User('Ada'));
|
|
135
|
+
clone instanceof User; // true
|
|
136
|
+
clone.greet(); // 'hi Ada'
|
|
352
137
|
```
|
|
353
138
|
|
|
354
|
-
##
|
|
355
|
-
|
|
356
|
-
Import only what you need to minimize bundle size:
|
|
139
|
+
## Compatibility
|
|
357
140
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
// โ Avoid: Importing everything
|
|
364
|
-
import * as utils from '@pivanov/utils';
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
## TypeScript Support
|
|
368
|
-
|
|
369
|
-
All utilities provide excellent type inference:
|
|
370
|
-
|
|
371
|
-
```typescript
|
|
372
|
-
import { pick } from '@pivanov/utils/object';
|
|
373
|
-
import { capitalize } from '@pivanov/utils/string';
|
|
374
|
-
|
|
375
|
-
// TypeScript infers exact types
|
|
376
|
-
const user = { name: 'John', age: 30, email: 'john@example.com' } as const;
|
|
377
|
-
const picked = pick(user, ['name', 'email']);
|
|
378
|
-
// Type: { name: "John"; email: "john@example.com" }
|
|
141
|
+
- Modern browsers (ES2022)
|
|
142
|
+
- Bun, Node 18+ (ESM or CJS)
|
|
143
|
+
- Cache API requires browser support (Chrome 40+, Firefox 41+, Safari 11.1+)
|
|
144
|
+
- React hook requires React 18+
|
|
379
145
|
|
|
380
|
-
|
|
381
|
-
const capitalized = capitalize(str);
|
|
382
|
-
// Type: "Hello"
|
|
383
|
-
```
|
|
146
|
+
## Development
|
|
384
147
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
โโโ /tools - Various tools
|
|
394
|
-
โโโ deepClone
|
|
395
|
-
โโโ isEqual
|
|
396
|
-
โโโ DOM utilities (isBrowser, checkVisibility, etc.)
|
|
397
|
-
โโโ eventBus (busDispatch, busSubscribe, useEventBus)
|
|
398
|
-
โโโ Cache API (storageSetItem, storageGetItem, etc.)
|
|
148
|
+
```bash
|
|
149
|
+
bun install
|
|
150
|
+
bun test # run tests
|
|
151
|
+
bun run test:coverage # with coverage (lcov)
|
|
152
|
+
bun run typecheck
|
|
153
|
+
bun run lint
|
|
154
|
+
bun run build # ESM + CJS + .d.ts
|
|
155
|
+
bun run docs:dev # run VitePress docs site locally
|
|
399
156
|
```
|
|
400
157
|
|
|
401
|
-
##
|
|
158
|
+
## Sponsors
|
|
402
159
|
|
|
403
|
-
|
|
404
|
-
- Cache API requires browser support (Chrome 40+, Firefox 41+, Safari 11.1+)
|
|
405
|
-
- SSR-safe with browser environment detection
|
|
160
|
+
Supported by [LogicStar AI](https://logicstar.ai/)
|
|
406
161
|
|
|
407
162
|
## License
|
|
408
163
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* @pivanov/utils v1.0.0
|
|
3
|
+
* (c) 2024-present Pavel Ivanov
|
|
4
|
+
* Released under the MIT License.
|
|
5
|
+
* https://github.com/pivanov/utils
|
|
6
|
+
*/
|
|
7
|
+
var{defineProperty:G,getOwnPropertyNames:I,getOwnPropertyDescriptor:J}=Object,K=Object.prototype.hasOwnProperty;var H=new WeakMap,L=(q)=>{var B=H.get(q),D;if(B)return B;if(B=G({},"__esModule",{value:!0}),q&&typeof q==="object"||typeof q==="function")I(q).map((F)=>!K.call(B,F)&&G(B,F,{get:()=>q[F],enumerable:!(D=J(q,F))||D.enumerable}));return H.set(q,B),B};var N=(q,B)=>{for(var D in B)G(q,D,{get:B[D],enumerable:!0,configurable:!0,set:(F)=>B[D]=()=>F})};var d={};N(d,{isUndefined:()=>W,isString:()=>R,isSet:()=>C,isRegExp:()=>j,isRecord:()=>V,isPromise:()=>z,isPrimitive:()=>P,isObject:()=>U,isNumber:()=>Q,isNull:()=>X,isNil:()=>Y,isMap:()=>A,isFunction:()=>T,isError:()=>x,isEmpty:()=>b,isDefined:()=>Z,isDate:()=>$,isBoolean:()=>O,isArray:()=>_});module.exports=L(d);var O=(q)=>{return typeof q==="boolean"},Q=(q)=>{return typeof q==="number"},R=(q)=>{return typeof q==="string"},T=(q)=>{return typeof q==="function"},U=(q)=>{if(q===null||typeof q!=="object")return!1;let B=Object.getPrototypeOf(q);return B===Object.prototype||B===null},V=(q)=>{return typeof q==="object"&&q!==null},W=(q)=>{return q===void 0},X=(q)=>{return q===null},Y=(q)=>{return q===null||q===void 0},Z=(q)=>{return q!==void 0},_=(q)=>{return Array.isArray(q)},$=(q)=>{return q instanceof Date},j=(q)=>{return q instanceof RegExp},x=(q)=>{return q instanceof Error},z=(q)=>{return q!==null&&(typeof q==="object"||typeof q==="function")&&typeof q.then==="function"},A=(q)=>{return q instanceof Map},C=(q)=>{return q instanceof Set},P=(q)=>{if(q===null||q===void 0)return!0;let B=typeof q;return B==="string"||B==="number"||B==="boolean"||B==="bigint"||B==="symbol"},b=(q)=>{if(q===null||q===void 0)return!0;if(typeof q==="string"||Array.isArray(q))return q.length===0;if(q instanceof Map||q instanceof Set)return q.size===0;if(typeof q==="object")return Object.keys(q).length===0;return!1};
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @pivanov/utils
|
|
2
|
+
* @pivanov/utils v1.0.0
|
|
3
3
|
* (c) 2024-present Pavel Ivanov
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
* https://github.com/pivanov/utils
|
|
6
6
|
*/
|
|
7
|
-
"use strict";var e=require("react");const t=e=>{if(null===e||"object"!=typeof e)return!1;const t=Object.getPrototypeOf(e);return t===Object.prototype||null===t},r=(e,...n)=>{if(!n.length)return e;const s=n.shift();if(void 0===s)return e;if(t(e)&&t(s))for(const n of Object.keys(s)){const o=s[n];if(t(o)){e[n]||Object.assign(e,{[n]:{}});const s=e[n];t(s)&&r(s,o)}else Object.assign(e,{[n]:o})}return r(e,...n)},n=(e,t)=>"bigint"==typeof t?t.toString():t,s=e=>e.startsWith("http://")||e.startsWith("https://")?e:`https://cache.internal/${e}`,o=e=>`${((e,t="๐")=>{let r=0;const n=e+t;for(let e=0;e<n.length;e++)r=(r<<5)-r+n.charCodeAt(e),r|=0;return(r>>>0).toString(16)})(e)}::${e}`,i=(e,t)=>{if(!e||"function"!=typeof t)return()=>{};const r=(e=>t=>{if(t instanceof CustomEvent)try{e(t.detail)}catch(e){console.error("Event listener error:",e)}})(t),n=o(e);return window.addEventListener(n,r),()=>window.removeEventListener(n,r)},a=(e,t)=>{if(null===e||"object"!=typeof e)return e;const r=t.get(e);if(r)return r;if(Array.isArray(e)){const r=e.length;if(r<32){const n=new Array(r);t.set(e,n);for(let s=0;s<r;s++)s in e&&(n[s]=a(e[s],t));return n}const n=new Array(r);if(t.set(e,n),Object.keys(e).length===r){let s=0;const o=r-r%8;for(;s<o;)n[s]=a(e[s],t),n[s+1]=a(e[s+1],t),n[s+2]=a(e[s+2],t),n[s+3]=a(e[s+3],t),n[s+4]=a(e[s+4],t),n[s+5]=a(e[s+5],t),n[s+6]=a(e[s+6],t),n[s+7]=a(e[s+7],t),s+=8;for(;s<r;)n[s]=a(e[s],t),s++}else for(let s=0;s<r;s++)s in e&&(n[s]=a(e[s],t));return n}if(e instanceof Date||e instanceof RegExp){return new(0,e.constructor)(e)}if("undefined"!=typeof Buffer)try{if(Buffer.isBuffer(e))return Buffer.from(e)}catch(e){if(e instanceof Error)throw e}if(ArrayBuffer.isView(e)){const t=e.constructor;if("buffer"in e){const r=e;return new t(r.buffer.slice(r.byteOffset,r.byteOffset+r.byteLength))}return new t(new ArrayBuffer(e.byteLength))}if(e instanceof ArrayBuffer)return e.slice(0);if(e&&"object"==typeof e&&"buffer"in e&&"byteLength"in e){const t=e;if("undefined"==typeof Buffer){const e=new Uint8Array(t.buffer,t.byteOffset||0,t.byteLength),r=new Uint8Array(e.length);return r.set(e),r}return{buffer:t.buffer instanceof ArrayBuffer?t.buffer.slice(0):new ArrayBuffer(t.byteLength),byteLength:t.byteLength,byteOffset:t.byteOffset||0,length:t.length||t.byteLength,BYTES_PER_ELEMENT:t.BYTES_PER_ELEMENT||1}}if(e instanceof Set){const r=new Set;t.set(e,r);const n=Array.from(e),s=n.length;for(let e=0;e<s;e++)r.add(a(n[e],t));return r}if(e instanceof Map){const r=new Map;t.set(e,r);const n=Array.from(e),s=n.length;for(let e=0;e<s;e++){const[s,o]=n[e];r.set(s,a(o,t))}return r}if(Object.getPrototypeOf(e)===Object.prototype){const r={};t.set(e,r);const n=Object.getOwnPropertySymbols(e),s=n.length;if(s>0)for(let t=0;t<s;t++){const s=n[t],o=Object.getOwnPropertyDescriptor(e,s);o?.enumerable&&Object.defineProperty(r,s,o)}const o=Object.getOwnPropertyDescriptors(e),i=Object.keys(e),c=i.length;let f=!1;for(let e=0;e<c;e++){const t=o[i[e]];if(t.get||t.set){f=!0;break}}if(f)for(let e=0;e<c;e++){const n=i[e],s=o[n];if(s.enumerable)if(s.get||s.set)Object.defineProperty(r,n,s);else{const e=a(s.value,t);Object.defineProperty(r,n,{...s,value:e})}}else{let n=0;const s=c-c%8;for(;n<s;){const s=i[n],o=i[n+1],c=i[n+2],f=i[n+3],l=i[n+4],p=i[n+5],u=i[n+6],y=i[n+7],g=e;r[s]=a(g[s],t),r[o]=a(g[o],t),r[c]=a(g[c],t),r[f]=a(g[f],t),r[l]=a(g[l],t),r[p]=a(g[p],t),r[u]=a(g[u],t),r[y]=a(g[y],t),n+=8}for(;n<c;){const s=i[n++];r[s]=a(e[s],t)}}return r}const n=Object.getPrototypeOf(e),s=Object.create(n);t.set(e,s);const o=Object.getOwnPropertyDescriptors(e),i=Object.keys(o),c=i.length;for(let e=0;e<c;e++){const r=i[e],n=o[r];if(n.enumerable)if(n.get||n.set)Object.defineProperty(s,r,n);else{const e=a(n.value,t);Object.defineProperty(s,r,{...n,value:e})}}const f=Object.getOwnPropertySymbols(e),l=f.length;for(let t=0;t<l;t++){const r=f[t],n=Object.getOwnPropertyDescriptor(e,r);n?.enumerable&&Object.defineProperty(s,r,n)}return s},c=(e,t)=>{if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return!1;for(let r=0;r<e.length;r++)if(!c(e[r],t[r]))return!1;return!0}if(e instanceof Set&&t instanceof Set){if(e.size!==t.size)return!1;for(const r of e)if(!t.has(r))return!1;return!0}if(e instanceof Map&&t instanceof Map){if(e.size!==t.size)return!1;for(const[r,n]of e)if(!t.has(r)||!c(n,t.get(r)))return!1;return!0}if(null!==e&&"object"==typeof e&&!Array.isArray(e)&&null!==t&&"object"==typeof t&&!Array.isArray(t)){const r=Object.keys(e),n=Object.keys(t);if(r.length!==n.length)return!1;for(const n of r)if(!c(e[n],t[n]))return!1;return!0}return e===t};exports.busDispatch=(e,t)=>{if(!e)return;const r=o(e);window.dispatchEvent(new CustomEvent(r,{detail:t,bubbles:!0,cancelable:!1}))},exports.busSubscribe=i,exports.calculateRenderedTextWidth=(e,t,r=!1,n='Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"')=>{const s=r?e.toUpperCase():e,o=document.createElement("canvas").getContext("2d");return o.font=`${t}px ${n}`,o.measureText(s).width},exports.camelCase=e=>e.trim().toLowerCase().replace(/^[-_\s]+/,"").replace(/[-_\s]+(.)?/g,((e,t)=>t?t.toUpperCase():"")),exports.capitalize=e=>e.charAt(0).toUpperCase()+e.slice(1),exports.capitalizeFirstLetter=e=>e.charAt(0).toUpperCase()+e.slice(1),exports.checkVisibility=e=>{const t=e.getBoundingClientRect(),r=Math.max(document.documentElement.clientHeight,window.innerHeight);return!(t.bottom<0||t.top-r>=0)},exports.deepClone=e=>a(e,new WeakMap),exports.deepMerge=r,exports.isBoolean=e=>"boolean"==typeof e,exports.isBrowser=()=>"undefined"!=typeof window,exports.isEqual=c,exports.isFunction=e=>"function"==typeof e,exports.isNull=e=>null===e,exports.isNumber=e=>"number"==typeof e,exports.isObject=t,exports.isString=e=>"string"==typeof e,exports.isUndefined=e=>void 0===e,exports.kebabCase=e=>null==e?e:e.normalize("NFKD").replace(/\p{Diacritic}/gu,"").replace(/[^\w\s-]/g," ").replace(/([a-z0-9])([A-Z])/g,"$1-$2").replace(/([A-Z])([A-Z][a-z])/g,"$1-$2").replace(/[-_\s]+/g,"-").toLowerCase().replace(/^-+|-+$/g,"").trim(),exports.merge=(e,...t)=>Object.assign(e,...t),exports.omit=(e,t)=>t.reduce(((e,t)=>(delete e[t],e)),{...e}),exports.pascalCase=e=>e.split(/(?=[0-9])|(?<=[0-9])|[^a-zA-Z0-9]+/g).filter(Boolean).map((e=>e.toLowerCase())).map((e=>`${e.charAt(0).toUpperCase()}${e.slice(1)}`)).join(""),exports.pick=(e,t)=>{const r={};for(const n of t)n in e&&(r[n]=e[n]);return r},exports.setStyleProperties=(e,t)=>{if(e)for(const[r,n]of Object.entries(t))e.style.setProperty(r,n)},exports.sleep=e=>new Promise((t=>{setTimeout(t,e)})),exports.slugify=e=>e.normalize("NFKD").toLowerCase().trim().replace(/[^\w\s-]/g,"").replace(/[-\s_]+/g,"-").replace(/^-+|-+$/g,""),exports.storageCalculateSize=async(e,t)=>{const r=await caches.open(e);if(t){const e=s(t),n=await r.match(new Request(e));if(n){const e=n.clone();return(await e.arrayBuffer()).byteLength}return 0}const n=await r.keys();let o=0;for(const e of n){const t=await r.match(e);if(t){const e=t.clone();o+=(await e.arrayBuffer()).byteLength}}return o},exports.storageClear=async e=>{const t=await caches.open(e),r=await t.keys();for(const e of r)await t.delete(e)},exports.storageClearByPrefixOrSuffix=async(e,t,r=!0)=>{const n=await caches.open(e),s=await n.keys();for(const e of s){const s=e.url.split("/"),o=s[s.length-1]||"";(r&&o.startsWith(t)||!r&&o.endsWith(t))&&await n.delete(e)}},exports.storageExists=async(e,t)=>{const r=await caches.open(e),n=s(t);return void 0!==await r.match(new Request(n))},exports.storageGetAllKeys=async e=>{const t=await caches.open(e);return(await t.keys()).map((e=>{const t=e.url.split("/");return t[t.length-1]||""}))},exports.storageGetItem=async(e,t)=>{const r=await caches.open(e),n=s(t),o=await r.match(new Request(n));if(!o)return null;const i=await o.text();return JSON.parse(i)},exports.storageRemoveItem=async(e,t)=>{const r=await caches.open(e),n=s(t);return await r.delete(new Request(n))},exports.storageSetItem=async(e,t,r)=>{const o=await caches.open(e),i=JSON.stringify(r,n),a=new Response(i,{headers:{"Content-Type":"application/json"}}),c=s(t);await o.put(new Request(c),a)},exports.stringifyBigIntValues=n,exports.uncapitalize=e=>e.charAt(0).toLowerCase()+e.slice(1),exports.useEventBus=(t,r,n=[])=>{e.useEffect((()=>{if(t&&"function"==typeof r)return i(t,r)}),[t,r,...n])};
|
|
7
|
+
var{defineProperty:x,getOwnPropertyNames:WQ,getOwnPropertyDescriptor:BQ}=Object,HQ=Object.prototype.hasOwnProperty;var n=new WeakMap,K=(J)=>{var Q=n.get(J),X;if(Q)return Q;if(Q=x({},"__esModule",{value:!0}),J&&typeof J==="object"||typeof J==="function")WQ(J).map((Y)=>!HQ.call(Q,Y)&&x(Q,Y,{get:()=>J[Y],enumerable:!(X=BQ(J,Y))||X.enumerable}));return n.set(J,Q),Q};var P=(J,Q)=>{for(var X in Q)x(J,X,{get:Q[X],enumerable:!0,configurable:!0,set:(Y)=>Q[X]=()=>Y})};var OQ={};P(OQ,{isUndefined:()=>e,isString:()=>s,isSet:()=>FJ,isRegExp:()=>$J,isRecord:()=>t,isPromise:()=>UJ,isPrimitive:()=>WJ,isObject:()=>V,isNumber:()=>r,isNull:()=>JJ,isNil:()=>QJ,isMap:()=>_J,isFunction:()=>a,isError:()=>GJ,isEmpty:()=>BJ,isDefined:()=>XJ,isDate:()=>ZJ,isBoolean:()=>i,isArray:()=>YJ});module.exports=K(OQ);var i=(J)=>{return typeof J==="boolean"},r=(J)=>{return typeof J==="number"},s=(J)=>{return typeof J==="string"},a=(J)=>{return typeof J==="function"},V=(J)=>{if(J===null||typeof J!=="object")return!1;let Q=Object.getPrototypeOf(J);return Q===Object.prototype||Q===null},t=(J)=>{return typeof J==="object"&&J!==null},e=(J)=>{return J===void 0},JJ=(J)=>{return J===null},QJ=(J)=>{return J===null||J===void 0},XJ=(J)=>{return J!==void 0},YJ=(J)=>{return Array.isArray(J)},ZJ=(J)=>{return J instanceof Date},$J=(J)=>{return J instanceof RegExp},GJ=(J)=>{return J instanceof Error},UJ=(J)=>{return J!==null&&(typeof J==="object"||typeof J==="function")&&typeof J.then==="function"},_J=(J)=>{return J instanceof Map},FJ=(J)=>{return J instanceof Set},WJ=(J)=>{if(J===null||J===void 0)return!0;let Q=typeof J;return Q==="string"||Q==="number"||Q==="boolean"||Q==="bigint"||Q==="symbol"},BJ=(J)=>{if(J===null||J===void 0)return!0;if(typeof J==="string"||Array.isArray(J))return J.length===0;if(J instanceof Map||J instanceof Set)return J.size===0;if(typeof J==="object")return Object.keys(J).length===0;return!1};var RQ={};P(RQ,{pickBy:()=>f,pick:()=>OJ,omitBy:()=>RJ,omit:()=>HJ,merge:()=>PJ,mapValues:()=>IJ,mapKeys:()=>TJ,keysOf:()=>AJ,invert:()=>zJ,hasOwn:()=>MJ,groupBy:()=>qJ,fromEntries:()=>SJ,entriesOf:()=>KJ,deepMerge:()=>C});module.exports=K(RQ);var HJ=(J,Q)=>{let X={...J};for(let Y of Q)delete X[Y];return X},OJ=(J,Q)=>{let X={};for(let Y of Q)if(Y in J)X[Y]=J[Y];return X},f=(J,Q)=>{let X={};for(let Y of Object.keys(J))if(Q(J[Y],Y))X[Y]=J[Y];return X},RJ=(J,Q)=>{return f(J,(X,Y)=>!Q(X,Y))},IJ=(J,Q)=>{let X={};for(let Y of Object.keys(J))X[Y]=Q(J[Y],Y);return X},TJ=(J,Q)=>{let X={};for(let Y of Object.keys(J))X[Q(J[Y],Y)]=J[Y];return X},qJ=(J,Q)=>{let X={};return J.forEach((Y,Z)=>{let U=Q(Y,Z);if(X[U])X[U].push(Y);else X[U]=[Y]}),X},zJ=(J)=>{let Q={};for(let X of Object.keys(J))Q[J[X]]=X;return Q},MJ=(J,Q)=>{return Object.hasOwn(J,Q)},AJ=(J)=>{return Object.keys(J)},KJ=(J)=>{return Object.entries(J)},SJ=(J)=>{return Object.fromEntries(J)},PJ=(J,...Q)=>{return Object.assign({},J,...Q)},C=(J,...Q)=>{let X={...J};for(let Y of Q){if(Y===void 0)continue;for(let Z of Object.keys(Y)){let U=Y[Z],_=X[Z];if(V(U))X[Z]=C(V(_)?_:{},U);else X[Z]=U}}return X};var IQ={};P(IQ,{timeout:()=>EJ,sleep:()=>g,retry:()=>VJ,parallelLimit:()=>NJ,defer:()=>LJ});module.exports=K(IQ);var g=(J,Q)=>{return new Promise((X,Y)=>{if(Q?.aborted){Y(Q.reason);return}let Z=setTimeout(()=>{Q?.removeEventListener("abort",U),X()},J),U=()=>{clearTimeout(Z),Y(Q?.reason)};Q?.addEventListener("abort",U,{once:!0})})},EJ=(J,Q,X)=>{return new Promise((Y,Z)=>{let U=setTimeout(()=>{Z(X??Error(`Operation timed out after ${Q}ms`))},Q);J.then((_)=>{clearTimeout(U),Y(_)},(_)=>{clearTimeout(U),Z(_)})})},VJ=async(J,Q={})=>{let{attempts:X=3,backoff:Y=0,signal:Z,shouldRetry:U}=Q,_;for(let H=1;H<=X;H++){if(Z?.aborted)throw Z.reason;try{return await J(H)}catch(z){if(_=z,H>=X)break;if(U&&!U(z,H))break;let S=typeof Y==="function"?Y(H):Y;if(S>0)await g(S,Z)}}throw _},LJ=()=>{let J,Q;return{promise:new Promise((Y,Z)=>{J=Y,Q=Z}),resolve:J,reject:Q}},NJ=async(J,Q,X)=>{if(Q<1)throw Error("parallelLimit: concurrency must be >= 1");let Y=Array(J.length),Z=0,U=async()=>{while(!0){let H=Z++;if(H>=J.length)return;Y[H]=await X(J[H],H)}},_=Array.from({length:Math.min(Q,J.length)},U);return await Promise.all(_),Y};var qQ={};P(qQ,{words:()=>yJ,uncapitalize:()=>mJ,truncate:()=>hJ,titleCase:()=>gJ,snakeCase:()=>CJ,slugify:()=>dJ,pascalCase:()=>wJ,lines:()=>jJ,kebabCase:()=>fJ,escapeRegExp:()=>pJ,escapeHtml:()=>kJ,capitalizeFirstLetter:()=>xJ,capitalize:()=>vJ,camelCase:()=>DJ});module.exports=K(qQ);var DJ=(J)=>{return J.trim().toLowerCase().replace(/^[-_\s]+/,"").replace(/[-_\s]+(.)?/g,(Q,X)=>X?X.toUpperCase():"")},wJ=(J)=>{return J.split(/(?=[0-9])|(?<=[0-9])|[^a-zA-Z0-9]+/g).filter(Boolean).map((Q)=>Q.toLowerCase()).map((Q)=>`${Q.charAt(0).toUpperCase()}${Q.slice(1)}`).join("")},xJ=(J)=>J.charAt(0).toUpperCase()+J.slice(1),fJ=(J)=>{if(J==null)return J;return J.normalize("NFKD").replace(/\p{Diacritic}/gu,"").replace(/[^\w\s-]/g," ").replace(/([a-z0-9])([A-Z])/g,"$1-$2").replace(/([A-Z])([A-Z][a-z])/g,"$1-$2").replace(/[-_\s]+/g,"-").toLowerCase().replace(/^-+|-+$/g,"").trim()},CJ=(J)=>{if(J==null)return J;return J.normalize("NFKD").replace(/\p{Diacritic}/gu,"").replace(/[^\w\s-]/g," ").replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").replace(/[-_\s]+/g,"_").toLowerCase().replace(/^_+|_+$/g,"").trim()},gJ=(J)=>{return J.normalize("NFKD").replace(/[^\w\s-]/g," ").split(/[-_\s]+/).filter(Boolean).map((Q)=>Q.charAt(0).toUpperCase()+Q.slice(1).toLowerCase()).join(" ")},dJ=(J)=>{return J.normalize("NFKD").toLowerCase().trim().replace(/[^\w\s-]/g,"").replace(/[-\s_]+/g,"-").replace(/^-+|-+$/g,"")},vJ=(J)=>{return J.charAt(0).toUpperCase()+J.slice(1)},mJ=(J)=>{return J.charAt(0).toLowerCase()+J.slice(1)},hJ=(J,Q,X="โฆ")=>{if(J.length<=Q)return J;if(Q<=X.length)return X.slice(0,Q);return J.slice(0,Q-X.length)+X},TQ={"&":"&","<":"<",">":">",'"':""","'":"'"},kJ=(J)=>{return J.replace(/[&<>"']/g,(Q)=>TQ[Q])},pJ=(J)=>{return J.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")},yJ=(J)=>{return J.split(/[-_\s]+/).filter(Boolean)},jJ=(J)=>{return J.split(/\r\n|\r|\n/)};var SQ={};P(SQ,{useEventBus:()=>UQ,stringifyBigIntValues:()=>d,storageSetItemWithTTL:()=>uJ,storageSetItem:()=>v,storageRemoveItem:()=>h,storageGetItemWithTTL:()=>bJ,storageGetItem:()=>m,storageGetAllKeys:()=>iJ,storageExists:()=>nJ,storageClearBySuffix:()=>oJ,storageClearByPrefixOrSuffix:()=>w,storageClearByPrefix:()=>lJ,storageClear:()=>cJ,storageCalculateSize:()=>rJ,setStyleProperties:()=>tJ,isInViewport:()=>QQ,isEqual:()=>FQ,isBrowser:()=>aJ,deepClone:()=>sJ,checkVisibility:()=>eJ,calculateRenderedTextWidth:()=>XQ,busSubscribe:()=>N,busOnce:()=>$Q,busDispatch:()=>ZQ,__resetTextMeasurementCache:()=>JQ});module.exports=K(SQ);var d=(J,Q)=>{return typeof Q==="bigint"?Q.toString():Q},L=(J)=>{if(J.startsWith("http://")||J.startsWith("https://"))return J;return`https://cache.internal/${J}`},v=async(J,Q,X)=>{let Y=await caches.open(J),Z=JSON.stringify(X,d),U=new Response(Z,{headers:{"Content-Type":"application/json"}}),_=L(Q);await Y.put(new Request(_),U)},m=async(J,Q)=>{let X=await caches.open(J),Y=L(Q),Z=await X.match(new Request(Y));if(!Z)return null;let U=await Z.text();return JSON.parse(U)},zQ=(J)=>{return typeof J==="object"&&J!==null&&J.__ttl===!0&&typeof J.exp==="number"},uJ=async(J,Q,X,Y)=>{let Z={__ttl:!0,v:X,exp:Date.now()+Y};await v(J,Q,Z)},bJ=async(J,Q)=>{let X=await m(J,Q);if(!zQ(X))return null;if(Date.now()>=X.exp)return await h(J,Q),null;return X.v},h=async(J,Q)=>{let X=await caches.open(J),Y=L(Q);return X.delete(new Request(Y))},cJ=async(J)=>{let Q=await caches.open(J),X=await Q.keys();for(let Y of X)await Q.delete(Y)},w=async(J,Q,X=!0)=>{let Y=await caches.open(J),Z=await Y.keys();for(let U of Z){let _=U.url.split("/"),H=_[_.length-1]||"";if(X&&H.startsWith(Q)||!X&&H.endsWith(Q))await Y.delete(U)}},lJ=async(J,Q)=>{await w(J,Q,!0)},oJ=async(J,Q)=>{await w(J,Q,!1)},nJ=async(J,Q)=>{let X=await caches.open(J),Y=L(Q);return await X.match(new Request(Y))!==void 0},iJ=async(J)=>{return(await(await caches.open(J)).keys()).map((Y)=>{let Z=Y.url.split("/");return Z[Z.length-1]||""})},rJ=async(J,Q)=>{let X=await caches.open(J);if(Q){let U=L(Q),_=await X.match(new Request(U));if(_)return(await _.clone().arrayBuffer()).byteLength;return 0}let Y=await X.keys(),Z=0;for(let U of Y){let _=await X.match(U);if(_){let H=await _.clone().arrayBuffer();Z+=H.byteLength}}return Z};var sJ=(J)=>{return B(J,new WeakMap)},B=(J,Q)=>{if(J===null||typeof J!=="object")return J;let X=Q.get(J);if(X)return X;if(Array.isArray(J)){let $=J.length;if($<32){let G=Array($);Q.set(J,G);for(let W=0;W<$;W++)if(W in J)G[W]=B(J[W],Q);return G}let F=Array($);if(Q.set(J,F),Object.keys(J).length===$){let G=0,W=$%8,R=$-W;while(G<R)F[G]=B(J[G],Q),F[G+1]=B(J[G+1],Q),F[G+2]=B(J[G+2],Q),F[G+3]=B(J[G+3],Q),F[G+4]=B(J[G+4],Q),F[G+5]=B(J[G+5],Q),F[G+6]=B(J[G+6],Q),F[G+7]=B(J[G+7],Q),G+=8;while(G<$)F[G]=B(J[G],Q),G++}else for(let G=0;G<$;G++)if(G in J)F[G]=B(J[G],Q);return F}if(J instanceof Date||J instanceof RegExp)return new J.constructor(J);if(typeof Buffer<"u")try{if(Buffer.isBuffer(J))return Buffer.from(J)}catch($){if($ instanceof Error)throw $}if(ArrayBuffer.isView(J)){let $=J.constructor;if("buffer"in J){let G=J,W=G.buffer.slice(G.byteOffset,G.byteOffset+G.byteLength);return new $(W)}return new $(new ArrayBuffer(J.byteLength))}if(J instanceof ArrayBuffer)return J.slice(0);if(J&&typeof J==="object"&&"buffer"in J&&"byteLength"in J){let $=J;if(typeof Buffer>"u"){let G=new Uint8Array($.buffer,$.byteOffset||0,$.byteLength),W=new Uint8Array(G.length);return W.set(G),W}return{buffer:$.buffer instanceof ArrayBuffer?$.buffer.slice(0):new ArrayBuffer($.byteLength),byteLength:$.byteLength,byteOffset:$.byteOffset||0,length:$.length||$.byteLength,BYTES_PER_ELEMENT:$.BYTES_PER_ELEMENT||1}}if(J instanceof Set){let $=new Set;Q.set(J,$);let F=Array.from(J),G=F.length;for(let W=0;W<G;W++)$.add(B(F[W],Q));return $}if(J instanceof Map){let $=new Map;Q.set(J,$);let F=Array.from(J),G=F.length;for(let W=0;W<G;W++){let[R,M]=F[W];$.set(R,B(M,Q))}return $}if(Object.getPrototypeOf(J)===Object.prototype){let $={};Q.set(J,$);let F=Object.getOwnPropertySymbols(J),G=F.length;if(G>0)for(let O=0;O<G;O++){let I=F[O],T=Object.getOwnPropertyDescriptor(J,I);if(T?.enumerable)Object.defineProperty($,I,T)}let W=Object.getOwnPropertyDescriptors(J),R=Object.keys(J),M=R.length,p=!1;for(let O=0;O<M;O++){let I=W[R[O]];if(I.get||I.set){p=!0;break}}if(p)for(let O=0;O<M;O++){let I=R[O],T=W[I];if(T.enumerable)if(T.get||T.set)Object.defineProperty($,I,T);else{let A=B(T.value,Q);Object.defineProperty($,I,{...T,value:A})}}else{let O=0,I=M%8,T=M-I;while(O<T){let A=R[O],y=R[O+1],j=R[O+2],u=R[O+3],b=R[O+4],c=R[O+5],l=R[O+6],o=R[O+7],q=J;$[A]=B(q[A],Q),$[y]=B(q[y],Q),$[j]=B(q[j],Q),$[u]=B(q[u],Q),$[b]=B(q[b],Q),$[c]=B(q[c],Q),$[l]=B(q[l],Q),$[o]=B(q[o],Q),O+=8}while(O<M){let A=R[O++];$[A]=B(J[A],Q)}}return $}let Y=Object.getPrototypeOf(J),Z=Object.create(Y);Q.set(J,Z);let U=Object.getOwnPropertyDescriptors(J),_=Object.keys(U),H=_.length;for(let $=0;$<H;$++){let F=_[$],G=U[F];if(!G.enumerable)continue;if(G.get||G.set)Object.defineProperty(Z,F,G);else{let W=B(G.value,Q);Object.defineProperty(Z,F,{...G,value:W})}}let z=Object.getOwnPropertySymbols(J),S=z.length;for(let $=0;$<S;$++){let F=z[$],G=Object.getOwnPropertyDescriptor(J,F);if(!G?.enumerable)continue;Object.defineProperty(Z,F,G)}return Z};var aJ=()=>{return typeof window<"u"&&typeof document<"u"},tJ=(J,Q)=>{if(!J)return;for(let[X,Y]of Object.entries(Q))J.style.setProperty(X,Y)},eJ=(J,Q={})=>{let{checkViewport:X=!0,checkDisplay:Y=!0,checkVisibility:Z=!0,checkOpacity:U=!0}=Q;if(!J.isConnected)return!1;if(Y||Z||U){let _=window.getComputedStyle(J);if(Y&&_.display==="none")return!1;if(Z&&_.visibility!==""&&_.visibility!=="visible")return!1;if(U&&_.opacity!==""){let H=Number.parseFloat(_.opacity);if(!Number.isNaN(H)&&H===0)return!1}}if(X){let _=J.getBoundingClientRect();if(_.width!==0||_.height!==0){let H=window.innerHeight||document.documentElement.clientHeight,z=window.innerWidth||document.documentElement.clientWidth,S=_.bottom<=0||_.top>=H,$=_.right<=0||_.left>=z;if(S||$)return!1}}return!0};var k,E,MQ=()=>{if(E!==void 0)return E;if(typeof document>"u")return E=null,null;return k=document.createElement("canvas"),E=k.getContext("2d"),E},JQ=()=>{k=void 0,E=void 0},QQ=(J,Q={})=>{let{vertical:X=!0,horizontal:Y=!0}=Q,Z=J.getBoundingClientRect();if(Z.width===0&&Z.height===0)return!0;let U=window.innerHeight||document.documentElement.clientHeight,_=window.innerWidth||document.documentElement.clientWidth;if(X&&(Z.bottom<=0||Z.top>=U))return!1;if(Y&&(Z.right<=0||Z.left>=_))return!1;return!0},XQ=(J,Q,X=!1,Y='Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"')=>{let Z=MQ();if(!Z)return 0;let U=X?J.toUpperCase():J;return Z.font=`${Q}px ${Y}`,Z.measureText(U).width};var AQ=(J,Q="\uD83D\uDE80")=>{let X=0,Y=J+Q;for(let Z=0;Z<Y.length;Z++){let U=Y.charCodeAt(Z);X=(X<<5)-X+U,X|=0}return(X>>>0).toString(16)},YQ=(J)=>{return`${AQ(J)}::${J}`},KQ=(J,Q)=>{return(X)=>{if(!(X instanceof CustomEvent))return;try{J(X.detail)}catch(Y){if(Q)Q(Y);else console.error("Event listener error:",Y)}}},ZQ=(J,Q)=>{if(!J)return;let X=YQ(J);window.dispatchEvent(new CustomEvent(X,{detail:Q,bubbles:!0,cancelable:!1}))},N=(J,Q,X={})=>{if(!J||typeof Q!=="function")return()=>{};let Y=KQ(Q,X.onError),Z=YQ(J);return window.addEventListener(Z,Y),()=>window.removeEventListener(Z,Y)},$Q=(J,Q,X={})=>{if(!J||typeof Q!=="function")return()=>{};let Y=N(J,(Z)=>{Y(),Q(Z)},X);return Y};var GQ=require("react");var UQ=(J,Q,X=[])=>{GQ.useEffect(()=>{if(!J||typeof Q!=="function")return;return N(J,Q)},[J,Q,...X])};var FQ=(J,Q)=>{return D(J,Q,new WeakMap)},D=(J,Q,X)=>{if(Object.is(J,Q))return!0;if(J instanceof Date&&Q instanceof Date)return J.getTime()===Q.getTime();if(J instanceof RegExp&&Q instanceof RegExp)return J.source===Q.source&&J.flags===Q.flags;if(J instanceof Error&&Q instanceof Error)return J.name===Q.name&&J.message===Q.message;if(J instanceof ArrayBuffer&&Q instanceof ArrayBuffer){if(J.byteLength!==Q.byteLength)return!1;return _Q(new Uint8Array(J),new Uint8Array(Q))}if(ArrayBuffer.isView(J)&&ArrayBuffer.isView(Q)){if(J.constructor!==Q.constructor)return!1;if(J.byteLength!==Q.byteLength)return!1;let Y=new Uint8Array(J.buffer,J.byteOffset,J.byteLength),Z=new Uint8Array(Q.buffer,Q.byteOffset,Q.byteLength);return _Q(Y,Z)}if(typeof J==="object"&&J!==null&&typeof Q==="object"&&Q!==null){let Y=X.get(J);if(Y?.has(Q))return!0;if(Y)Y.add(Q);else X.set(J,new WeakSet([Q]))}if(Array.isArray(J)&&Array.isArray(Q)){if(J.length!==Q.length)return!1;for(let Y=0;Y<J.length;Y++)if(!D(J[Y],Q[Y],X))return!1;return!0}if(J instanceof Set&&Q instanceof Set){if(J.size!==Q.size)return!1;let Y=Array.from(Q);for(let Z of J){let U=Y.findIndex((_)=>D(Z,_,X));if(U===-1)return!1;Y.splice(U,1)}return!0}if(J instanceof Map&&Q instanceof Map){if(J.size!==Q.size)return!1;for(let[Y,Z]of J)if(!Q.has(Y)||!D(Z,Q.get(Y),X))return!1;return!0}if(J!==null&&typeof J==="object"&&Q!==null&&typeof Q==="object"){let Y=J,Z=Q,U=Object.keys(Y);if(U.length!==Object.keys(Z).length)return!1;for(let _ of U)if(!D(Y[_],Z[_],X))return!1;return!0}return!1},_Q=(J,Q)=>{for(let X=0;X<J.length;X++)if(J[X]!==Q[X])return!1;return!0};var PQ={};module.exports=K(PQ);var EQ={};P(EQ,{words:()=>yJ,useEventBus:()=>UQ,uncapitalize:()=>mJ,truncate:()=>hJ,titleCase:()=>gJ,timeout:()=>EJ,stringifyBigIntValues:()=>d,storageSetItemWithTTL:()=>uJ,storageSetItem:()=>v,storageRemoveItem:()=>h,storageGetItemWithTTL:()=>bJ,storageGetItem:()=>m,storageGetAllKeys:()=>iJ,storageExists:()=>nJ,storageClearBySuffix:()=>oJ,storageClearByPrefixOrSuffix:()=>w,storageClearByPrefix:()=>lJ,storageClear:()=>cJ,storageCalculateSize:()=>rJ,snakeCase:()=>CJ,slugify:()=>dJ,sleep:()=>g,setStyleProperties:()=>tJ,retry:()=>VJ,pickBy:()=>f,pick:()=>OJ,pascalCase:()=>wJ,parallelLimit:()=>NJ,omitBy:()=>RJ,omit:()=>HJ,merge:()=>PJ,mapValues:()=>IJ,mapKeys:()=>TJ,lines:()=>jJ,keysOf:()=>AJ,kebabCase:()=>fJ,isUndefined:()=>e,isString:()=>s,isSet:()=>FJ,isRegExp:()=>$J,isRecord:()=>t,isPromise:()=>UJ,isPrimitive:()=>WJ,isObject:()=>V,isNumber:()=>r,isNull:()=>JJ,isNil:()=>QJ,isMap:()=>_J,isInViewport:()=>QQ,isFunction:()=>a,isError:()=>GJ,isEqual:()=>FQ,isEmpty:()=>BJ,isDefined:()=>XJ,isDate:()=>ZJ,isBrowser:()=>aJ,isBoolean:()=>i,isArray:()=>YJ,invert:()=>zJ,hasOwn:()=>MJ,groupBy:()=>qJ,fromEntries:()=>SJ,escapeRegExp:()=>pJ,escapeHtml:()=>kJ,entriesOf:()=>KJ,defer:()=>LJ,deepMerge:()=>C,deepClone:()=>sJ,checkVisibility:()=>eJ,capitalizeFirstLetter:()=>xJ,capitalize:()=>vJ,camelCase:()=>DJ,calculateRenderedTextWidth:()=>XQ,busSubscribe:()=>N,busOnce:()=>$Q,busDispatch:()=>ZQ,__resetTextMeasurementCache:()=>JQ});module.exports=K(EQ);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* @pivanov/utils v1.0.0
|
|
3
|
+
* (c) 2024-present Pavel Ivanov
|
|
4
|
+
* Released under the MIT License.
|
|
5
|
+
* https://github.com/pivanov/utils
|
|
6
|
+
*/
|
|
7
|
+
var{defineProperty:L,getOwnPropertyNames:Z,getOwnPropertyDescriptor:_}=Object,$=Object.prototype.hasOwnProperty;var T=new WeakMap,U=(q)=>{var F=T.get(q),G;if(F)return F;if(F=L({},"__esModule",{value:!0}),q&&typeof q==="object"||typeof q==="function")Z(q).map((H)=>!$.call(F,H)&&L(F,H,{get:()=>q[H],enumerable:!(G=_(q,H))||G.enumerable}));return T.set(q,F),F};var W=(q,F)=>{for(var G in F)L(q,G,{get:F[G],enumerable:!0,configurable:!0,set:(H)=>F[G]=()=>H})};var g={};W(g,{isUndefined:()=>N,isString:()=>B,isSet:()=>V,isRegExp:()=>w,isRecord:()=>D,isPromise:()=>M,isPrimitive:()=>h,isObject:()=>K,isNumber:()=>A,isNull:()=>P,isNil:()=>R,isMap:()=>E,isFunction:()=>C,isError:()=>x,isEmpty:()=>d,isDefined:()=>f,isDate:()=>S,isBoolean:()=>z,isArray:()=>O});module.exports=U(g);var z=(q)=>{return typeof q==="boolean"},A=(q)=>{return typeof q==="number"},B=(q)=>{return typeof q==="string"},C=(q)=>{return typeof q==="function"},K=(q)=>{if(q===null||typeof q!=="object")return!1;let F=Object.getPrototypeOf(q);return F===Object.prototype||F===null},D=(q)=>{return typeof q==="object"&&q!==null},N=(q)=>{return q===void 0},P=(q)=>{return q===null},R=(q)=>{return q===null||q===void 0},f=(q)=>{return q!==void 0},O=(q)=>{return Array.isArray(q)},S=(q)=>{return q instanceof Date},w=(q)=>{return q instanceof RegExp},x=(q)=>{return q instanceof Error},M=(q)=>{return q!==null&&(typeof q==="object"||typeof q==="function")&&typeof q.then==="function"},E=(q)=>{return q instanceof Map},V=(q)=>{return q instanceof Set},h=(q)=>{if(q===null||q===void 0)return!0;let F=typeof q;return F==="string"||F==="number"||F==="boolean"||F==="bigint"||F==="symbol"},d=(q)=>{if(q===null||q===void 0)return!0;if(typeof q==="string"||Array.isArray(q))return q.length===0;if(q instanceof Map||q instanceof Set)return q.size===0;if(typeof q==="object")return Object.keys(q).length===0;return!1};var v={};W(v,{pickBy:()=>X,pick:()=>n,omitBy:()=>p,omit:()=>m,merge:()=>r,mapValues:()=>k,mapKeys:()=>i,keysOf:()=>c,invert:()=>y,hasOwn:()=>b,groupBy:()=>j,fromEntries:()=>s,entriesOf:()=>o,deepMerge:()=>Y});module.exports=U(v);var m=(q,F)=>{let G={...q};for(let H of F)delete G[H];return G},n=(q,F)=>{let G={};for(let H of F)if(H in q)G[H]=q[H];return G},X=(q,F)=>{let G={};for(let H of Object.keys(q))if(F(q[H],H))G[H]=q[H];return G},p=(q,F)=>{return X(q,(G,H)=>!F(G,H))},k=(q,F)=>{let G={};for(let H of Object.keys(q))G[H]=F(q[H],H);return G},i=(q,F)=>{let G={};for(let H of Object.keys(q))G[F(q[H],H)]=q[H];return G},j=(q,F)=>{let G={};return q.forEach((H,J)=>{let I=F(H,J);if(G[I])G[I].push(H);else G[I]=[H]}),G},y=(q)=>{let F={};for(let G of Object.keys(q))F[q[G]]=G;return F},b=(q,F)=>{return Object.hasOwn(q,F)},c=(q)=>{return Object.keys(q)},o=(q)=>{return Object.entries(q)},s=(q)=>{return Object.fromEntries(q)},r=(q,...F)=>{return Object.assign({},q,...F)},Y=(q,...F)=>{let G={...q};for(let H of F){if(H===void 0)continue;for(let J of Object.keys(H)){let I=H[J],Q=G[J];if(K(I))G[J]=Y(K(Q)?Q:{},I);else G[J]=I}}return G};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* @pivanov/utils v1.0.0
|
|
3
|
+
* (c) 2024-present Pavel Ivanov
|
|
4
|
+
* Released under the MIT License.
|
|
5
|
+
* https://github.com/pivanov/utils
|
|
6
|
+
*/
|
|
7
|
+
var{defineProperty:J,getOwnPropertyNames:Q,getOwnPropertyDescriptor:S}=Object,T=Object.prototype.hasOwnProperty;var O=new WeakMap,U=(z)=>{var q=O.get(z),C;if(q)return q;if(q=J({},"__esModule",{value:!0}),z&&typeof z==="object"||typeof z==="function")Q(z).map((B)=>!T.call(q,B)&&J(q,B,{get:()=>z[B],enumerable:!(C=S(z,B))||C.enumerable}));return O.set(z,q),q};var V=(z,q)=>{for(var C in q)J(z,C,{get:q[C],enumerable:!0,configurable:!0,set:(B)=>q[C]=()=>B})};var _={};V(_,{timeout:()=>W,sleep:()=>P,retry:()=>X,parallelLimit:()=>Z,defer:()=>Y});module.exports=U(_);var P=(z,q)=>{return new Promise((C,B)=>{if(q?.aborted){B(q.reason);return}let D=setTimeout(()=>{q?.removeEventListener("abort",G),C()},z),G=()=>{clearTimeout(D),B(q?.reason)};q?.addEventListener("abort",G,{once:!0})})},W=(z,q,C)=>{return new Promise((B,D)=>{let G=setTimeout(()=>{D(C??Error(`Operation timed out after ${q}ms`))},q);z.then((H)=>{clearTimeout(G),B(H)},(H)=>{clearTimeout(G),D(H)})})},X=async(z,q={})=>{let{attempts:C=3,backoff:B=0,signal:D,shouldRetry:G}=q,H;for(let F=1;F<=C;F++){if(D?.aborted)throw D.reason;try{return await z(F)}catch(K){if(H=K,F>=C)break;if(G&&!G(K,F))break;let N=typeof B==="function"?B(F):B;if(N>0)await P(N,D)}}throw H},Y=()=>{let z,q;return{promise:new Promise((B,D)=>{z=B,q=D}),resolve:z,reject:q}},Z=async(z,q,C)=>{if(q<1)throw Error("parallelLimit: concurrency must be >= 1");let B=Array(z.length),D=0,G=async()=>{while(!0){let F=D++;if(F>=z.length)return;B[F]=await C(z[F],F)}},H=Array.from({length:Math.min(q,z.length)},G);return await Promise.all(H),B};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* @pivanov/utils v1.0.0
|
|
3
|
+
* (c) 2024-present Pavel Ivanov
|
|
4
|
+
* Released under the MIT License.
|
|
5
|
+
* https://github.com/pivanov/utils
|
|
6
|
+
*/
|
|
7
|
+
var{defineProperty:u,getOwnPropertyNames:z,getOwnPropertyDescriptor:B}=Object,D=Object.prototype.hasOwnProperty;var v=new WeakMap,F=(d)=>{var f=v.get(d),j;if(f)return f;if(f=u({},"__esModule",{value:!0}),d&&typeof d==="object"||typeof d==="function")z(d).map((q)=>!D.call(f,q)&&u(f,q,{get:()=>d[q],enumerable:!(j=B(d,q))||j.enumerable}));return v.set(d,f),f};var G=(d,f)=>{for(var j in f)u(d,j,{get:f[j],enumerable:!0,configurable:!0,set:(q)=>f[j]=()=>q})};var o={};G(o,{words:()=>$,uncapitalize:()=>V,truncate:()=>W,titleCase:()=>Q,snakeCase:()=>O,slugify:()=>R,pascalCase:()=>J,lines:()=>k,kebabCase:()=>N,escapeRegExp:()=>Z,escapeHtml:()=>Y,capitalizeFirstLetter:()=>K,capitalize:()=>U,camelCase:()=>I});module.exports=F(o);var I=(d)=>{return d.trim().toLowerCase().replace(/^[-_\s]+/,"").replace(/[-_\s]+(.)?/g,(f,j)=>j?j.toUpperCase():"")},J=(d)=>{return d.split(/(?=[0-9])|(?<=[0-9])|[^a-zA-Z0-9]+/g).filter(Boolean).map((f)=>f.toLowerCase()).map((f)=>`${f.charAt(0).toUpperCase()}${f.slice(1)}`).join("")},K=(d)=>d.charAt(0).toUpperCase()+d.slice(1),N=(d)=>{if(d==null)return d;return d.normalize("NFKD").replace(/\p{Diacritic}/gu,"").replace(/[^\w\s-]/g," ").replace(/([a-z0-9])([A-Z])/g,"$1-$2").replace(/([A-Z])([A-Z][a-z])/g,"$1-$2").replace(/[-_\s]+/g,"-").toLowerCase().replace(/^-+|-+$/g,"").trim()},O=(d)=>{if(d==null)return d;return d.normalize("NFKD").replace(/\p{Diacritic}/gu,"").replace(/[^\w\s-]/g," ").replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").replace(/[-_\s]+/g,"_").toLowerCase().replace(/^_+|_+$/g,"").trim()},Q=(d)=>{return d.normalize("NFKD").replace(/[^\w\s-]/g," ").split(/[-_\s]+/).filter(Boolean).map((f)=>f.charAt(0).toUpperCase()+f.slice(1).toLowerCase()).join(" ")},R=(d)=>{return d.normalize("NFKD").toLowerCase().trim().replace(/[^\w\s-]/g,"").replace(/[-\s_]+/g,"-").replace(/^-+|-+$/g,"")},U=(d)=>{return d.charAt(0).toUpperCase()+d.slice(1)},V=(d)=>{return d.charAt(0).toLowerCase()+d.slice(1)},W=(d,f,j="โฆ")=>{if(d.length<=f)return d;if(f<=j.length)return j.slice(0,f);return d.slice(0,f-j.length)+j},X={"&":"&","<":"<",">":">",'"':""","'":"'"},Y=(d)=>{return d.replace(/[&<>"']/g,(f)=>X[f])},Z=(d)=>{return d.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")},$=(d)=>{return d.split(/[-_\s]+/).filter(Boolean)},k=(d)=>{return d.split(/\r\n|\r|\n/)};
|