@ntnyq/utils 0.1.2 → 0.2.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/dist/index.cjs CHANGED
@@ -24,11 +24,18 @@ __export(src_exports, {
24
24
  cAF: () => cAF,
25
25
  camelCase: () => camelCase,
26
26
  capitalize: () => capitalize,
27
+ chunk: () => chunk,
28
+ clamp: () => clamp,
27
29
  days: () => days,
30
+ debounce: () => debounce,
31
+ ensurePrefix: () => ensurePrefix,
32
+ ensureSuffix: () => ensureSuffix,
28
33
  flatCase: () => flatCase,
29
34
  getObjectType: () => getObjectType,
35
+ hasOwn: () => hasOwn,
30
36
  hours: () => hours,
31
37
  isArray: () => isArray,
38
+ isArrayEqual: () => isArrayEqual,
32
39
  isBoolean: () => isBoolean,
33
40
  isBrowser: () => isBrowser,
34
41
  isFunction: () => isFunction,
@@ -45,14 +52,20 @@ __export(src_exports, {
45
52
  lowerFirst: () => lowerFirst,
46
53
  minutes: () => minutes,
47
54
  noop: () => noop,
55
+ omit: () => omit,
56
+ once: () => once,
48
57
  pascalCase: () => pascalCase,
58
+ pick: () => pick,
49
59
  rAF: () => rAF,
50
60
  seconds: () => seconds,
61
+ slash: () => slash,
51
62
  snakeCase: () => snakeCase,
52
63
  splitByCase: () => splitByCase,
64
+ throttle: () => throttle,
53
65
  titleCase: () => titleCase,
54
66
  toArray: () => toArray,
55
67
  trainCase: () => trainCase,
68
+ unindent: () => unindent,
56
69
  unique: () => unique,
57
70
  uniqueBy: () => uniqueBy,
58
71
  upperFirst: () => upperFirst,
@@ -105,6 +118,19 @@ var noop = () => {
105
118
  };
106
119
  var NOOP = noop;
107
120
 
121
+ // src/fn/once.ts
122
+ function once(func) {
123
+ let called = false;
124
+ return function(...args) {
125
+ if (called) {
126
+ return false;
127
+ }
128
+ called = true;
129
+ func.apply(this, args);
130
+ return true;
131
+ };
132
+ }
133
+
108
134
  // src/env/isBrowser.ts
109
135
  var isBrowser = () => typeof document !== "undefined";
110
136
 
@@ -232,11 +258,63 @@ function weeks(count) {
232
258
  return count * ONE_WEEK;
233
259
  }
234
260
 
261
+ // src/misc/clamp.ts
262
+ function clamp(value, min = Number.NEGATIVE_INFINITY, max = Number.POSITIVE_INFINITY) {
263
+ return Math.min(Math.max(value, min), max);
264
+ }
265
+
235
266
  // src/misc/waitFor.ts
236
267
  function waitFor(ms) {
237
268
  return new Promise((resolve) => setTimeout(resolve, ms));
238
269
  }
239
270
 
271
+ // src/misc/throttle.ts
272
+ function throttle(delay, callback, options = {}) {
273
+ const { isDebounce } = options;
274
+ let lastExec = 0;
275
+ let cancelled = false;
276
+ let timeoutId;
277
+ function clearExistingTimeout() {
278
+ if (timeoutId) {
279
+ clearTimeout(timeoutId);
280
+ }
281
+ }
282
+ function cancel() {
283
+ clearExistingTimeout();
284
+ cancelled = true;
285
+ }
286
+ function wrapper(...args) {
287
+ if (cancelled) return;
288
+ const _this = this;
289
+ const now = Date.now();
290
+ const elapsed = now - lastExec;
291
+ function clear() {
292
+ timeoutId = void 0;
293
+ }
294
+ function exec(cur) {
295
+ lastExec = cur || Date.now();
296
+ callback.apply(_this, args);
297
+ }
298
+ if (isDebounce && !timeoutId) {
299
+ exec(now);
300
+ }
301
+ clearExistingTimeout();
302
+ if (!isDebounce && elapsed > delay) {
303
+ exec(now);
304
+ } else {
305
+ timeoutId = setTimeout(isDebounce ? clear : exec, isDebounce ? delay : delay - elapsed);
306
+ }
307
+ }
308
+ wrapper.cancel = cancel;
309
+ return wrapper;
310
+ }
311
+ function debounce(delay, callback, options = {}) {
312
+ return throttle(delay, callback, {
313
+ ...options,
314
+ isDebounce: true
315
+ });
316
+ }
317
+
240
318
  // src/misc/warnOnce.ts
241
319
  var warned = /* @__PURE__ */ new Set();
242
320
  var warnOnce = (message) => {
@@ -247,6 +325,15 @@ var warnOnce = (message) => {
247
325
  console.warn(message);
248
326
  };
249
327
 
328
+ // src/array/chunk.ts
329
+ function chunk(array, size) {
330
+ const result = [];
331
+ for (let i = 0; i < array.length; i += size) {
332
+ result.push(array.slice(i, i + size));
333
+ }
334
+ return result;
335
+ }
336
+
250
337
  // src/array/unique.ts
251
338
  function unique(array) {
252
339
  return Array.from(new Set(array));
@@ -267,23 +354,99 @@ function toArray(array) {
267
354
  return Array.isArray(array) ? array : [array];
268
355
  }
269
356
 
357
+ // src/array/isArrayEqual.ts
358
+ function isArrayEqual(array1, array2) {
359
+ if (array1.length !== array2.length) {
360
+ return false;
361
+ }
362
+ return array1.every((item, idx) => item === array2[idx]);
363
+ }
364
+
270
365
  // src/string/join.ts
271
366
  function join(array, options = {}) {
272
367
  const { separator = "" } = options;
273
368
  if (!Array.isArray(array) || !array.length) return "";
274
369
  return array.filter((v) => Boolean(v) || v === 0).join(separator);
275
370
  }
371
+
372
+ // src/string/slash.ts
373
+ function slash(input) {
374
+ return input.replace(/\\/g, "/");
375
+ }
376
+
377
+ // src/string/unindent.ts
378
+ var _RE_FULL_WS = /^\s*$/;
379
+ function unindent(input) {
380
+ const lines = (typeof input === "string" ? input : input[0]).split("\n");
381
+ const whitespaceLines = lines.map((line) => _RE_FULL_WS.test(line));
382
+ const commonIndent = lines.reduce((min, line, idx) => {
383
+ if (!whitespaceLines[idx]) {
384
+ return min;
385
+ }
386
+ const indent = line.match(/^\s/)?.[0].length;
387
+ return indent === void 0 ? min : Math.min(min, indent);
388
+ }, Number.POSITIVE_INFINITY);
389
+ let emptylinesHead = 0;
390
+ while (emptylinesHead < lines.length && whitespaceLines[emptylinesHead]) {
391
+ emptylinesHead++;
392
+ }
393
+ let emptylinesTail = 0;
394
+ while (emptylinesTail < lines.length && whitespaceLines[lines.length - emptylinesTail - 1]) {
395
+ emptylinesTail++;
396
+ }
397
+ return lines.slice(emptylinesHead, lines.length - emptylinesTail).map((line) => line.slice(commonIndent)).join("\n");
398
+ }
399
+
400
+ // src/string/ensurePrefix.ts
401
+ function ensurePrefix(input, prefix) {
402
+ return input.startsWith(prefix) ? input : `${prefix}${input}`;
403
+ }
404
+
405
+ // src/string/ensureSuffix.ts
406
+ function ensureSuffix(input, suffix) {
407
+ return input.endsWith(suffix) ? input : `${input}${suffix}`;
408
+ }
409
+
410
+ // src/object/omit.ts
411
+ function omit(object, ...keys) {
412
+ keys.forEach((key) => delete object[key]);
413
+ return object;
414
+ }
415
+
416
+ // src/object/hasOwn.ts
417
+ function hasOwn(object, key) {
418
+ return Object.prototype.hasOwnProperty.call(object, key);
419
+ }
420
+
421
+ // src/object/pick.ts
422
+ function pick(object, keys) {
423
+ return Object.assign(
424
+ {},
425
+ ...keys.map((key) => {
426
+ if (object && hasOwn(object, key)) {
427
+ return { [key]: object[key] };
428
+ }
429
+ })
430
+ );
431
+ }
276
432
  // Annotate the CommonJS export names for ESM import in node:
277
433
  0 && (module.exports = {
278
434
  NOOP,
279
435
  cAF,
280
436
  camelCase,
281
437
  capitalize,
438
+ chunk,
439
+ clamp,
282
440
  days,
441
+ debounce,
442
+ ensurePrefix,
443
+ ensureSuffix,
283
444
  flatCase,
284
445
  getObjectType,
446
+ hasOwn,
285
447
  hours,
286
448
  isArray,
449
+ isArrayEqual,
287
450
  isBoolean,
288
451
  isBrowser,
289
452
  isFunction,
@@ -300,14 +463,20 @@ function join(array, options = {}) {
300
463
  lowerFirst,
301
464
  minutes,
302
465
  noop,
466
+ omit,
467
+ once,
303
468
  pascalCase,
469
+ pick,
304
470
  rAF,
305
471
  seconds,
472
+ slash,
306
473
  snakeCase,
307
474
  splitByCase,
475
+ throttle,
308
476
  titleCase,
309
477
  toArray,
310
478
  trainCase,
479
+ unindent,
311
480
  unique,
312
481
  uniqueBy,
313
482
  upperFirst,
package/dist/index.d.cts CHANGED
@@ -27,6 +27,8 @@ declare const noop: () => void;
27
27
  */
28
28
  declare const NOOP: () => void;
29
29
 
30
+ declare function once<T extends unknown[]>(func: (...args: T) => void): (this: unknown, ...args: T) => boolean;
31
+
30
32
  /**
31
33
  * @file env.ts
32
34
  */
@@ -74,6 +76,15 @@ declare function hours(count: number): number;
74
76
  declare function days(count: number): number;
75
77
  declare function weeks(count: number): number;
76
78
 
79
+ /**
80
+ * Clamps a number between a minimum and maximum value
81
+ * @param value the value to clamp within the given range
82
+ * @param min the minimum value to clamp
83
+ * @param max the maximum value to clamp
84
+ * @returns the new value
85
+ */
86
+ declare function clamp(value: number, min?: number, max?: number): number;
87
+
77
88
  /**
78
89
  * Wait for a number of milliseconds
79
90
  *
@@ -89,8 +100,37 @@ declare function weeks(count: number): number;
89
100
  */
90
101
  declare function waitFor(ms: number): Promise<unknown>;
91
102
 
103
+ interface ThrottleDebounceOptions {
104
+ /**
105
+ * @default false
106
+ */
107
+ isDebounce?: boolean;
108
+ }
109
+ /**
110
+ * Throttle a function to limit its execution to a maximum of once per a specified time interval.
111
+ *
112
+ * @param delay - Zero or greater delay in milliseconds
113
+ * @param callback - A function to be throttled
114
+ * @param options - throttle options
115
+ * @returns A throttled function
116
+ */
117
+ declare function throttle<T extends ((...args: any[]) => undefined | void) | undefined | null>(delay: number, callback: Exclude<T, undefined | null>, options?: ThrottleDebounceOptions): T & {
118
+ cancel: () => void;
119
+ };
120
+ declare function debounce<T extends ((...args: any[]) => undefined | void) | undefined | null>(delay: number, callback: Exclude<T, undefined | null>, options?: ThrottleDebounceOptions): T & {
121
+ cancel: () => void;
122
+ };
123
+
92
124
  declare const warnOnce: (message: string) => void;
93
125
 
126
+ /**
127
+ * Splits an array into smaller chunks of a given size.
128
+ * @param array The array to split
129
+ * @param size The size of each chunk
130
+ * @returns An array of arrays, where each sub-array has `size` elements from the original array.
131
+ */
132
+ declare function chunk<T>(array: T[], size: number): T[][];
133
+
94
134
  /**
95
135
  * Returns a new array with unique values.
96
136
  * @param array - The array to process.
@@ -110,7 +150,11 @@ type MayBe<T> = T | undefined;
110
150
  type AnyFn<T = any, R = any> = (...args: T[]) => R;
111
151
  type Arrayable<T> = T | T[];
112
152
  type Awaitable<T> = T | Promise<T>;
113
- type Prettify<T> = Omit<T, never>;
153
+ type Prettify<T> = {
154
+ [K in keyof T]: T[K];
155
+ } & {};
156
+ type PrettifyV2<T> = Omit<T, never>;
157
+ type PrimitiveType = number | bigint | string | boolean | symbol | null | undefined;
114
158
 
115
159
  /**
116
160
  * Converts a value to an array.
@@ -119,10 +163,12 @@ type Prettify<T> = Omit<T, never>;
119
163
  */
120
164
  declare function toArray<T>(array?: Nullable<Arrayable<T>>): T[];
121
165
 
166
+ declare function isArrayEqual(array1: unknown[], array2: unknown[]): boolean;
167
+
122
168
  type JoinableValue = string | number | null | undefined;
123
169
  interface JoinOptions {
124
170
  /**
125
- * @default '''
171
+ * @default ''
126
172
  */
127
173
  separator?: string;
128
174
  }
@@ -134,4 +180,36 @@ interface JoinOptions {
134
180
  */
135
181
  declare function join(array: JoinableValue[], options?: JoinOptions): string;
136
182
 
137
- export { type AnyFn, type Arrayable, type Awaitable, type MayBe, NOOP, type Nullable, type Prettify, cAF, capitalize, days, getObjectType, hours, isArray, isBoolean, isBrowser, isFunction, isInteger, isNativePromise, isNull, isNumber, isPromise, isString, isUndefined, join, minutes, noop, rAF, seconds, toArray, unique, uniqueBy, waitFor, warnOnce, weeks };
183
+ /**
184
+ * Replace backslash to slash
185
+ */
186
+ declare function slash(input: string): string;
187
+
188
+ /**
189
+ * Remove leading whitespace from a template string
190
+ * Empty lines at the beginning and end of the template string are also removed.
191
+ * @param input template string
192
+ *
193
+ * @example
194
+ *
195
+ * ```ts
196
+ * const str = unindent`
197
+ * if (foo) {
198
+ * bar()
199
+ * }
200
+ * `
201
+ * ```
202
+ */
203
+ declare function unindent(input: TemplateStringsArray | string): string;
204
+
205
+ declare function ensurePrefix(input: string, prefix: string): string;
206
+
207
+ declare function ensureSuffix(input: string, suffix: string): string;
208
+
209
+ declare function omit<T, K extends keyof T>(object: T, ...keys: K[]): Omit<T, K>;
210
+
211
+ declare function pick<T, K extends keyof T>(object: T, keys: K[]): Pick<T, K>;
212
+
213
+ declare function hasOwn<T, K extends keyof T>(object: T, key: K): boolean;
214
+
215
+ export { type AnyFn, type Arrayable, type Awaitable, type MayBe, NOOP, type Nullable, type Prettify, type PrettifyV2, type PrimitiveType, type ThrottleDebounceOptions, cAF, capitalize, chunk, clamp, days, debounce, ensurePrefix, ensureSuffix, getObjectType, hasOwn, hours, isArray, isArrayEqual, isBoolean, isBrowser, isFunction, isInteger, isNativePromise, isNull, isNumber, isPromise, isString, isUndefined, join, minutes, noop, omit, once, pick, rAF, seconds, slash, throttle, toArray, unindent, unique, uniqueBy, waitFor, warnOnce, weeks };
package/dist/index.d.ts CHANGED
@@ -27,6 +27,8 @@ declare const noop: () => void;
27
27
  */
28
28
  declare const NOOP: () => void;
29
29
 
30
+ declare function once<T extends unknown[]>(func: (...args: T) => void): (this: unknown, ...args: T) => boolean;
31
+
30
32
  /**
31
33
  * @file env.ts
32
34
  */
@@ -74,6 +76,15 @@ declare function hours(count: number): number;
74
76
  declare function days(count: number): number;
75
77
  declare function weeks(count: number): number;
76
78
 
79
+ /**
80
+ * Clamps a number between a minimum and maximum value
81
+ * @param value the value to clamp within the given range
82
+ * @param min the minimum value to clamp
83
+ * @param max the maximum value to clamp
84
+ * @returns the new value
85
+ */
86
+ declare function clamp(value: number, min?: number, max?: number): number;
87
+
77
88
  /**
78
89
  * Wait for a number of milliseconds
79
90
  *
@@ -89,8 +100,37 @@ declare function weeks(count: number): number;
89
100
  */
90
101
  declare function waitFor(ms: number): Promise<unknown>;
91
102
 
103
+ interface ThrottleDebounceOptions {
104
+ /**
105
+ * @default false
106
+ */
107
+ isDebounce?: boolean;
108
+ }
109
+ /**
110
+ * Throttle a function to limit its execution to a maximum of once per a specified time interval.
111
+ *
112
+ * @param delay - Zero or greater delay in milliseconds
113
+ * @param callback - A function to be throttled
114
+ * @param options - throttle options
115
+ * @returns A throttled function
116
+ */
117
+ declare function throttle<T extends ((...args: any[]) => undefined | void) | undefined | null>(delay: number, callback: Exclude<T, undefined | null>, options?: ThrottleDebounceOptions): T & {
118
+ cancel: () => void;
119
+ };
120
+ declare function debounce<T extends ((...args: any[]) => undefined | void) | undefined | null>(delay: number, callback: Exclude<T, undefined | null>, options?: ThrottleDebounceOptions): T & {
121
+ cancel: () => void;
122
+ };
123
+
92
124
  declare const warnOnce: (message: string) => void;
93
125
 
126
+ /**
127
+ * Splits an array into smaller chunks of a given size.
128
+ * @param array The array to split
129
+ * @param size The size of each chunk
130
+ * @returns An array of arrays, where each sub-array has `size` elements from the original array.
131
+ */
132
+ declare function chunk<T>(array: T[], size: number): T[][];
133
+
94
134
  /**
95
135
  * Returns a new array with unique values.
96
136
  * @param array - The array to process.
@@ -110,7 +150,11 @@ type MayBe<T> = T | undefined;
110
150
  type AnyFn<T = any, R = any> = (...args: T[]) => R;
111
151
  type Arrayable<T> = T | T[];
112
152
  type Awaitable<T> = T | Promise<T>;
113
- type Prettify<T> = Omit<T, never>;
153
+ type Prettify<T> = {
154
+ [K in keyof T]: T[K];
155
+ } & {};
156
+ type PrettifyV2<T> = Omit<T, never>;
157
+ type PrimitiveType = number | bigint | string | boolean | symbol | null | undefined;
114
158
 
115
159
  /**
116
160
  * Converts a value to an array.
@@ -119,10 +163,12 @@ type Prettify<T> = Omit<T, never>;
119
163
  */
120
164
  declare function toArray<T>(array?: Nullable<Arrayable<T>>): T[];
121
165
 
166
+ declare function isArrayEqual(array1: unknown[], array2: unknown[]): boolean;
167
+
122
168
  type JoinableValue = string | number | null | undefined;
123
169
  interface JoinOptions {
124
170
  /**
125
- * @default '''
171
+ * @default ''
126
172
  */
127
173
  separator?: string;
128
174
  }
@@ -134,4 +180,36 @@ interface JoinOptions {
134
180
  */
135
181
  declare function join(array: JoinableValue[], options?: JoinOptions): string;
136
182
 
137
- export { type AnyFn, type Arrayable, type Awaitable, type MayBe, NOOP, type Nullable, type Prettify, cAF, capitalize, days, getObjectType, hours, isArray, isBoolean, isBrowser, isFunction, isInteger, isNativePromise, isNull, isNumber, isPromise, isString, isUndefined, join, minutes, noop, rAF, seconds, toArray, unique, uniqueBy, waitFor, warnOnce, weeks };
183
+ /**
184
+ * Replace backslash to slash
185
+ */
186
+ declare function slash(input: string): string;
187
+
188
+ /**
189
+ * Remove leading whitespace from a template string
190
+ * Empty lines at the beginning and end of the template string are also removed.
191
+ * @param input template string
192
+ *
193
+ * @example
194
+ *
195
+ * ```ts
196
+ * const str = unindent`
197
+ * if (foo) {
198
+ * bar()
199
+ * }
200
+ * `
201
+ * ```
202
+ */
203
+ declare function unindent(input: TemplateStringsArray | string): string;
204
+
205
+ declare function ensurePrefix(input: string, prefix: string): string;
206
+
207
+ declare function ensureSuffix(input: string, suffix: string): string;
208
+
209
+ declare function omit<T, K extends keyof T>(object: T, ...keys: K[]): Omit<T, K>;
210
+
211
+ declare function pick<T, K extends keyof T>(object: T, keys: K[]): Pick<T, K>;
212
+
213
+ declare function hasOwn<T, K extends keyof T>(object: T, key: K): boolean;
214
+
215
+ export { type AnyFn, type Arrayable, type Awaitable, type MayBe, NOOP, type Nullable, type Prettify, type PrettifyV2, type PrimitiveType, type ThrottleDebounceOptions, cAF, capitalize, chunk, clamp, days, debounce, ensurePrefix, ensureSuffix, getObjectType, hasOwn, hours, isArray, isArrayEqual, isBoolean, isBrowser, isFunction, isInteger, isNativePromise, isNull, isNumber, isPromise, isString, isUndefined, join, minutes, noop, omit, once, pick, rAF, seconds, slash, throttle, toArray, unindent, unique, uniqueBy, waitFor, warnOnce, weeks };
package/dist/index.js CHANGED
@@ -41,6 +41,19 @@ var noop = () => {
41
41
  };
42
42
  var NOOP = noop;
43
43
 
44
+ // src/fn/once.ts
45
+ function once(func) {
46
+ let called = false;
47
+ return function(...args) {
48
+ if (called) {
49
+ return false;
50
+ }
51
+ called = true;
52
+ func.apply(this, args);
53
+ return true;
54
+ };
55
+ }
56
+
44
57
  // src/env/isBrowser.ts
45
58
  var isBrowser = () => typeof document !== "undefined";
46
59
 
@@ -168,11 +181,63 @@ function weeks(count) {
168
181
  return count * ONE_WEEK;
169
182
  }
170
183
 
184
+ // src/misc/clamp.ts
185
+ function clamp(value, min = Number.NEGATIVE_INFINITY, max = Number.POSITIVE_INFINITY) {
186
+ return Math.min(Math.max(value, min), max);
187
+ }
188
+
171
189
  // src/misc/waitFor.ts
172
190
  function waitFor(ms) {
173
191
  return new Promise((resolve) => setTimeout(resolve, ms));
174
192
  }
175
193
 
194
+ // src/misc/throttle.ts
195
+ function throttle(delay, callback, options = {}) {
196
+ const { isDebounce } = options;
197
+ let lastExec = 0;
198
+ let cancelled = false;
199
+ let timeoutId;
200
+ function clearExistingTimeout() {
201
+ if (timeoutId) {
202
+ clearTimeout(timeoutId);
203
+ }
204
+ }
205
+ function cancel() {
206
+ clearExistingTimeout();
207
+ cancelled = true;
208
+ }
209
+ function wrapper(...args) {
210
+ if (cancelled) return;
211
+ const _this = this;
212
+ const now = Date.now();
213
+ const elapsed = now - lastExec;
214
+ function clear() {
215
+ timeoutId = void 0;
216
+ }
217
+ function exec(cur) {
218
+ lastExec = cur || Date.now();
219
+ callback.apply(_this, args);
220
+ }
221
+ if (isDebounce && !timeoutId) {
222
+ exec(now);
223
+ }
224
+ clearExistingTimeout();
225
+ if (!isDebounce && elapsed > delay) {
226
+ exec(now);
227
+ } else {
228
+ timeoutId = setTimeout(isDebounce ? clear : exec, isDebounce ? delay : delay - elapsed);
229
+ }
230
+ }
231
+ wrapper.cancel = cancel;
232
+ return wrapper;
233
+ }
234
+ function debounce(delay, callback, options = {}) {
235
+ return throttle(delay, callback, {
236
+ ...options,
237
+ isDebounce: true
238
+ });
239
+ }
240
+
176
241
  // src/misc/warnOnce.ts
177
242
  var warned = /* @__PURE__ */ new Set();
178
243
  var warnOnce = (message) => {
@@ -183,6 +248,15 @@ var warnOnce = (message) => {
183
248
  console.warn(message);
184
249
  };
185
250
 
251
+ // src/array/chunk.ts
252
+ function chunk(array, size) {
253
+ const result = [];
254
+ for (let i = 0; i < array.length; i += size) {
255
+ result.push(array.slice(i, i + size));
256
+ }
257
+ return result;
258
+ }
259
+
186
260
  // src/array/unique.ts
187
261
  function unique(array) {
188
262
  return Array.from(new Set(array));
@@ -203,22 +277,98 @@ function toArray(array) {
203
277
  return Array.isArray(array) ? array : [array];
204
278
  }
205
279
 
280
+ // src/array/isArrayEqual.ts
281
+ function isArrayEqual(array1, array2) {
282
+ if (array1.length !== array2.length) {
283
+ return false;
284
+ }
285
+ return array1.every((item, idx) => item === array2[idx]);
286
+ }
287
+
206
288
  // src/string/join.ts
207
289
  function join(array, options = {}) {
208
290
  const { separator = "" } = options;
209
291
  if (!Array.isArray(array) || !array.length) return "";
210
292
  return array.filter((v) => Boolean(v) || v === 0).join(separator);
211
293
  }
294
+
295
+ // src/string/slash.ts
296
+ function slash(input) {
297
+ return input.replace(/\\/g, "/");
298
+ }
299
+
300
+ // src/string/unindent.ts
301
+ var _RE_FULL_WS = /^\s*$/;
302
+ function unindent(input) {
303
+ const lines = (typeof input === "string" ? input : input[0]).split("\n");
304
+ const whitespaceLines = lines.map((line) => _RE_FULL_WS.test(line));
305
+ const commonIndent = lines.reduce((min, line, idx) => {
306
+ if (!whitespaceLines[idx]) {
307
+ return min;
308
+ }
309
+ const indent = line.match(/^\s/)?.[0].length;
310
+ return indent === void 0 ? min : Math.min(min, indent);
311
+ }, Number.POSITIVE_INFINITY);
312
+ let emptylinesHead = 0;
313
+ while (emptylinesHead < lines.length && whitespaceLines[emptylinesHead]) {
314
+ emptylinesHead++;
315
+ }
316
+ let emptylinesTail = 0;
317
+ while (emptylinesTail < lines.length && whitespaceLines[lines.length - emptylinesTail - 1]) {
318
+ emptylinesTail++;
319
+ }
320
+ return lines.slice(emptylinesHead, lines.length - emptylinesTail).map((line) => line.slice(commonIndent)).join("\n");
321
+ }
322
+
323
+ // src/string/ensurePrefix.ts
324
+ function ensurePrefix(input, prefix) {
325
+ return input.startsWith(prefix) ? input : `${prefix}${input}`;
326
+ }
327
+
328
+ // src/string/ensureSuffix.ts
329
+ function ensureSuffix(input, suffix) {
330
+ return input.endsWith(suffix) ? input : `${input}${suffix}`;
331
+ }
332
+
333
+ // src/object/omit.ts
334
+ function omit(object, ...keys) {
335
+ keys.forEach((key) => delete object[key]);
336
+ return object;
337
+ }
338
+
339
+ // src/object/hasOwn.ts
340
+ function hasOwn(object, key) {
341
+ return Object.prototype.hasOwnProperty.call(object, key);
342
+ }
343
+
344
+ // src/object/pick.ts
345
+ function pick(object, keys) {
346
+ return Object.assign(
347
+ {},
348
+ ...keys.map((key) => {
349
+ if (object && hasOwn(object, key)) {
350
+ return { [key]: object[key] };
351
+ }
352
+ })
353
+ );
354
+ }
212
355
  export {
213
356
  NOOP,
214
357
  cAF,
215
358
  camelCase,
216
359
  capitalize,
360
+ chunk,
361
+ clamp,
217
362
  days,
363
+ debounce,
364
+ ensurePrefix,
365
+ ensureSuffix,
218
366
  flatCase,
219
367
  getObjectType,
368
+ hasOwn,
220
369
  hours,
221
370
  isArray,
371
+ isArrayEqual,
222
372
  isBoolean,
223
373
  isBrowser,
224
374
  isFunction,
@@ -235,14 +385,20 @@ export {
235
385
  lowerFirst,
236
386
  minutes,
237
387
  noop,
388
+ omit,
389
+ once,
238
390
  pascalCase,
391
+ pick,
239
392
  rAF,
240
393
  seconds,
394
+ slash,
241
395
  snakeCase,
242
396
  splitByCase,
397
+ throttle,
243
398
  titleCase,
244
399
  toArray,
245
400
  trainCase,
401
+ unindent,
246
402
  unique,
247
403
  uniqueBy,
248
404
  upperFirst,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ntnyq/utils",
3
3
  "type": "module",
4
- "version": "0.1.2",
4
+ "version": "0.2.0",
5
5
  "description": "Common used utils.",
6
6
  "keywords": [
7
7
  "utils"
@@ -40,19 +40,19 @@
40
40
  "scule": "^1.3.0"
41
41
  },
42
42
  "devDependencies": {
43
- "@ntnyq/eslint-config": "^3.0.0-beta.17",
43
+ "@ntnyq/eslint-config": "^3.0.0-beta.20",
44
44
  "@ntnyq/prettier-config": "^1.21.3",
45
- "@vitest/coverage-v8": "^2.1.1",
46
- "bumpp": "^9.6.1",
47
- "eslint": "^9.11.1",
45
+ "@vitest/coverage-v8": "^2.1.2",
46
+ "bumpp": "^9.7.1",
47
+ "eslint": "^9.12.0",
48
48
  "husky": "^9.1.6",
49
49
  "nano-staged": "^0.8.0",
50
50
  "npm-run-all2": "^6.2.3",
51
- "pnpm": "^9.11.0",
51
+ "pnpm": "^9.12.1",
52
52
  "prettier": "^3.3.3",
53
53
  "tsup": "^8.3.0",
54
- "typescript": "^5.6.2",
55
- "vitest": "^2.1.1"
54
+ "typescript": "^5.6.3",
55
+ "vitest": "^2.1.2"
56
56
  },
57
57
  "engines": {
58
58
  "node": ">=18.18.0"