@luxass/utils 2.2.2 → 2.4.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.
@@ -55,6 +55,5 @@ declare function isNotUndefined<T>(v: T): v is Exclude<T, undefined>;
55
55
  * ```
56
56
  */
57
57
  declare function isTruthy<T>(v: T): v is NonNullable<T>;
58
-
59
58
  //#endregion
60
- export { isNotNull as isNotNull$1, isNotNullish as isNotNullish$1, isNotUndefined as isNotUndefined$1, isTruthy as isTruthy$1 };
59
+ export { isNotNull, isNotNullish, isNotUndefined, isTruthy };
package/dist/guards.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { isNotNull$1 as isNotNull, isNotNullish$1 as isNotNullish, isNotUndefined$1 as isNotUndefined, isTruthy$1 as isTruthy } from "./guards-C19fJmlu.js";
1
+ import { isNotNull, isNotNullish, isNotUndefined, isTruthy } from "./guards-x9QZDUSt.js";
2
2
  export { isNotNull, isNotNullish, isNotUndefined, isTruthy };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,9 @@
1
- import { isNotNull$1 as isNotNull, isNotNullish$1 as isNotNullish, isNotUndefined$1 as isNotUndefined, isTruthy$1 as isTruthy } from "./guards-C19fJmlu.js";
2
- import { clamp$1 as clamp } from "./number-C2E_sOOy.js";
3
- import { capitalize$1 as capitalize, dedent$1 as dedent, dedentRaw$1 as dedentRaw, formatStr$1 as formatStr, sanitizeIdentifier$1 as sanitizeIdentifier, toCamelCase$1 as toCamelCase, toKebabCase$1 as toKebabCase, toPascalCase$1 as toPascalCase, toSnakeCase$1 as toSnakeCase } from "./string-CBWIJiC0.js";
4
- import { ElementOf, InferArguments, MaybeArray, MaybePromise, Nullable, Nullish, Prettify, RemoveIndexSignature } from "./types-QETho94V.js";
1
+ import { isNotNull, isNotNullish, isNotUndefined, isTruthy } from "./guards-x9QZDUSt.js";
2
+ import { clamp } from "./number-DzUC7V5F.js";
3
+ import { getChangedKeys, getOwnProperty, hasOwnProperty, omit } from "./object-BT3S70pM.js";
4
+ import { capitalize, dedent, dedentRaw, formatStr, sanitizeIdentifier, toCamelCase, toKebabCase, toPascalCase, toSnakeCase } from "./string-BjsgnDeW.js";
5
+ import { ElementOf, InferArguments, MaybeArray, MaybePromise, Nullable, Nullish, Prettify, RemoveIndexSignature } from "./types-DCrM3M9i.js";
6
+ import pRetry from "p-retry";
5
7
 
6
8
  //#region src/common.d.ts
7
9
  declare class InvariantError extends Error {
@@ -18,6 +20,5 @@ declare class InvariantError extends Error {
18
20
  * @throws {InvariantError} Throws when the predicate is falsy
19
21
  */
20
22
  declare function invariant(predicate: unknown, message: string, ...positionals: unknown[]): asserts predicate;
21
-
22
23
  //#endregion
23
- export { ElementOf, InferArguments, InvariantError, MaybeArray, MaybePromise, Nullable, Nullish, Prettify, RemoveIndexSignature, capitalize, clamp, dedent, dedentRaw, formatStr, invariant, isNotNull, isNotNullish, isNotUndefined, isTruthy, sanitizeIdentifier, toCamelCase, toKebabCase, toPascalCase, toSnakeCase };
24
+ export { ElementOf, InferArguments, InvariantError, MaybeArray, MaybePromise, Nullable, Nullish, Prettify, RemoveIndexSignature, capitalize, clamp, dedent, dedentRaw, formatStr, getChangedKeys, getOwnProperty, hasOwnProperty, invariant, isNotNull, isNotNullish, isNotUndefined, isTruthy, omit, pRetry as promiseRetry, sanitizeIdentifier, toCamelCase, toKebabCase, toPascalCase, toSnakeCase };
package/dist/index.js CHANGED
@@ -1,7 +1,34 @@
1
1
  import { isNotNull, isNotNullish, isNotUndefined, isTruthy } from "./guards-O1HGJraI.js";
2
2
  import { capitalize, dedent, dedentRaw, formatStr, sanitizeIdentifier, toCamelCase, toKebabCase, toPascalCase, toSnakeCase } from "./string-pQApOGKP.js";
3
3
  import { clamp } from "./number-BS9T5WGO.js";
4
+ import { getChangedKeys, getOwnProperty, hasOwnProperty, omit } from "./object-CyGLe77G.js";
4
5
 
6
+ //#region rolldown:runtime
7
+ var __create = Object.create;
8
+ var __defProp = Object.defineProperty;
9
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
10
+ var __getOwnPropNames = Object.getOwnPropertyNames;
11
+ var __getProtoOf = Object.getPrototypeOf;
12
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
13
+ var __commonJS = (cb, mod) => function() {
14
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
15
+ };
16
+ var __copyProps = (to, from, except, desc) => {
17
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
18
+ key = keys[i];
19
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
20
+ get: ((k) => from[k]).bind(null, key),
21
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
22
+ });
23
+ }
24
+ return to;
25
+ };
26
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
27
+ value: mod,
28
+ enumerable: true
29
+ }) : target, mod));
30
+
31
+ //#endregion
5
32
  //#region src/common.ts
6
33
  var InvariantError = class extends Error {
7
34
  constructor(message, ...positionals) {
@@ -24,4 +51,270 @@ function invariant(predicate, message, ...positionals) {
24
51
  }
25
52
 
26
53
  //#endregion
27
- export { InvariantError, capitalize, clamp, dedent, dedentRaw, formatStr, invariant, isNotNull, isNotNullish, isNotUndefined, isTruthy, sanitizeIdentifier, toCamelCase, toKebabCase, toPascalCase, toSnakeCase };
54
+ //#region node_modules/.pnpm/retry@0.13.1/node_modules/retry/lib/retry_operation.js
55
+ var require_retry_operation = __commonJS({ "node_modules/.pnpm/retry@0.13.1/node_modules/retry/lib/retry_operation.js"(exports, module) {
56
+ function RetryOperation$1(timeouts, options) {
57
+ if (typeof options === "boolean") options = { forever: options };
58
+ this._originalTimeouts = JSON.parse(JSON.stringify(timeouts));
59
+ this._timeouts = timeouts;
60
+ this._options = options || {};
61
+ this._maxRetryTime = options && options.maxRetryTime || Infinity;
62
+ this._fn = null;
63
+ this._errors = [];
64
+ this._attempts = 1;
65
+ this._operationTimeout = null;
66
+ this._operationTimeoutCb = null;
67
+ this._timeout = null;
68
+ this._operationStart = null;
69
+ this._timer = null;
70
+ if (this._options.forever) this._cachedTimeouts = this._timeouts.slice(0);
71
+ }
72
+ module.exports = RetryOperation$1;
73
+ RetryOperation$1.prototype.reset = function() {
74
+ this._attempts = 1;
75
+ this._timeouts = this._originalTimeouts.slice(0);
76
+ };
77
+ RetryOperation$1.prototype.stop = function() {
78
+ if (this._timeout) clearTimeout(this._timeout);
79
+ if (this._timer) clearTimeout(this._timer);
80
+ this._timeouts = [];
81
+ this._cachedTimeouts = null;
82
+ };
83
+ RetryOperation$1.prototype.retry = function(err) {
84
+ if (this._timeout) clearTimeout(this._timeout);
85
+ if (!err) return false;
86
+ var currentTime = (/* @__PURE__ */ new Date()).getTime();
87
+ if (err && currentTime - this._operationStart >= this._maxRetryTime) {
88
+ this._errors.push(err);
89
+ this._errors.unshift(/* @__PURE__ */ new Error("RetryOperation timeout occurred"));
90
+ return false;
91
+ }
92
+ this._errors.push(err);
93
+ var timeout = this._timeouts.shift();
94
+ if (timeout === void 0) if (this._cachedTimeouts) {
95
+ this._errors.splice(0, this._errors.length - 1);
96
+ timeout = this._cachedTimeouts.slice(-1);
97
+ } else return false;
98
+ var self = this;
99
+ this._timer = setTimeout(function() {
100
+ self._attempts++;
101
+ if (self._operationTimeoutCb) {
102
+ self._timeout = setTimeout(function() {
103
+ self._operationTimeoutCb(self._attempts);
104
+ }, self._operationTimeout);
105
+ if (self._options.unref) self._timeout.unref();
106
+ }
107
+ self._fn(self._attempts);
108
+ }, timeout);
109
+ if (this._options.unref) this._timer.unref();
110
+ return true;
111
+ };
112
+ RetryOperation$1.prototype.attempt = function(fn, timeoutOps) {
113
+ this._fn = fn;
114
+ if (timeoutOps) {
115
+ if (timeoutOps.timeout) this._operationTimeout = timeoutOps.timeout;
116
+ if (timeoutOps.cb) this._operationTimeoutCb = timeoutOps.cb;
117
+ }
118
+ var self = this;
119
+ if (this._operationTimeoutCb) this._timeout = setTimeout(function() {
120
+ self._operationTimeoutCb();
121
+ }, self._operationTimeout);
122
+ this._operationStart = (/* @__PURE__ */ new Date()).getTime();
123
+ this._fn(this._attempts);
124
+ };
125
+ RetryOperation$1.prototype.try = function(fn) {
126
+ console.log("Using RetryOperation.try() is deprecated");
127
+ this.attempt(fn);
128
+ };
129
+ RetryOperation$1.prototype.start = function(fn) {
130
+ console.log("Using RetryOperation.start() is deprecated");
131
+ this.attempt(fn);
132
+ };
133
+ RetryOperation$1.prototype.start = RetryOperation$1.prototype.try;
134
+ RetryOperation$1.prototype.errors = function() {
135
+ return this._errors;
136
+ };
137
+ RetryOperation$1.prototype.attempts = function() {
138
+ return this._attempts;
139
+ };
140
+ RetryOperation$1.prototype.mainError = function() {
141
+ if (this._errors.length === 0) return null;
142
+ var counts = {};
143
+ var mainError = null;
144
+ var mainErrorCount = 0;
145
+ for (var i = 0; i < this._errors.length; i++) {
146
+ var error = this._errors[i];
147
+ var message = error.message;
148
+ var count = (counts[message] || 0) + 1;
149
+ counts[message] = count;
150
+ if (count >= mainErrorCount) {
151
+ mainError = error;
152
+ mainErrorCount = count;
153
+ }
154
+ }
155
+ return mainError;
156
+ };
157
+ } });
158
+
159
+ //#endregion
160
+ //#region node_modules/.pnpm/retry@0.13.1/node_modules/retry/lib/retry.js
161
+ var require_retry$1 = __commonJS({ "node_modules/.pnpm/retry@0.13.1/node_modules/retry/lib/retry.js"(exports) {
162
+ var RetryOperation = require_retry_operation();
163
+ exports.operation = function(options) {
164
+ var timeouts = exports.timeouts(options);
165
+ return new RetryOperation(timeouts, {
166
+ forever: options && (options.forever || options.retries === Infinity),
167
+ unref: options && options.unref,
168
+ maxRetryTime: options && options.maxRetryTime
169
+ });
170
+ };
171
+ exports.timeouts = function(options) {
172
+ if (options instanceof Array) return [].concat(options);
173
+ var opts = {
174
+ retries: 10,
175
+ factor: 2,
176
+ minTimeout: 1 * 1e3,
177
+ maxTimeout: Infinity,
178
+ randomize: false
179
+ };
180
+ for (var key in options) opts[key] = options[key];
181
+ if (opts.minTimeout > opts.maxTimeout) throw new Error("minTimeout is greater than maxTimeout");
182
+ var timeouts = [];
183
+ for (var i = 0; i < opts.retries; i++) timeouts.push(this.createTimeout(i, opts));
184
+ if (options && options.forever && !timeouts.length) timeouts.push(this.createTimeout(i, opts));
185
+ timeouts.sort(function(a, b) {
186
+ return a - b;
187
+ });
188
+ return timeouts;
189
+ };
190
+ exports.createTimeout = function(attempt, opts) {
191
+ var random = opts.randomize ? Math.random() + 1 : 1;
192
+ var timeout = Math.round(random * Math.max(opts.minTimeout, 1) * Math.pow(opts.factor, attempt));
193
+ timeout = Math.min(timeout, opts.maxTimeout);
194
+ return timeout;
195
+ };
196
+ exports.wrap = function(obj, options, methods) {
197
+ if (options instanceof Array) {
198
+ methods = options;
199
+ options = null;
200
+ }
201
+ if (!methods) {
202
+ methods = [];
203
+ for (var key in obj) if (typeof obj[key] === "function") methods.push(key);
204
+ }
205
+ for (var i = 0; i < methods.length; i++) {
206
+ var method = methods[i];
207
+ var original = obj[method];
208
+ obj[method] = function retryWrapper(original$1) {
209
+ var op = exports.operation(options);
210
+ var args = Array.prototype.slice.call(arguments, 1);
211
+ var callback = args.pop();
212
+ args.push(function(err) {
213
+ if (op.retry(err)) return;
214
+ if (err) arguments[0] = op.mainError();
215
+ callback.apply(this, arguments);
216
+ });
217
+ op.attempt(function() {
218
+ original$1.apply(obj, args);
219
+ });
220
+ }.bind(obj, original);
221
+ obj[method].options = options;
222
+ }
223
+ };
224
+ } });
225
+
226
+ //#endregion
227
+ //#region node_modules/.pnpm/retry@0.13.1/node_modules/retry/index.js
228
+ var require_retry = __commonJS({ "node_modules/.pnpm/retry@0.13.1/node_modules/retry/index.js"(exports, module) {
229
+ module.exports = require_retry$1();
230
+ } });
231
+
232
+ //#endregion
233
+ //#region node_modules/.pnpm/is-network-error@1.1.0/node_modules/is-network-error/index.js
234
+ const objectToString = Object.prototype.toString;
235
+ const isError = (value) => objectToString.call(value) === "[object Error]";
236
+ const errorMessages = new Set([
237
+ "network error",
238
+ "Failed to fetch",
239
+ "NetworkError when attempting to fetch resource.",
240
+ "The Internet connection appears to be offline.",
241
+ "Load failed",
242
+ "Network request failed",
243
+ "fetch failed",
244
+ "terminated"
245
+ ]);
246
+ function isNetworkError(error) {
247
+ const isValid = error && isError(error) && error.name === "TypeError" && typeof error.message === "string";
248
+ if (!isValid) return false;
249
+ if (error.message === "Load failed") return error.stack === void 0;
250
+ return errorMessages.has(error.message);
251
+ }
252
+
253
+ //#endregion
254
+ //#region node_modules/.pnpm/p-retry@6.2.1/node_modules/p-retry/index.js
255
+ var import_retry = __toESM(require_retry(), 1);
256
+ var AbortError = class extends Error {
257
+ constructor(message) {
258
+ super();
259
+ if (message instanceof Error) {
260
+ this.originalError = message;
261
+ ({message} = message);
262
+ } else {
263
+ this.originalError = new Error(message);
264
+ this.originalError.stack = this.stack;
265
+ }
266
+ this.name = "AbortError";
267
+ this.message = message;
268
+ }
269
+ };
270
+ const decorateErrorWithCounts = (error, attemptNumber, options) => {
271
+ const retriesLeft = options.retries - (attemptNumber - 1);
272
+ error.attemptNumber = attemptNumber;
273
+ error.retriesLeft = retriesLeft;
274
+ return error;
275
+ };
276
+ async function pRetry(input, options) {
277
+ return new Promise((resolve, reject) => {
278
+ options = { ...options };
279
+ options.onFailedAttempt ??= () => {};
280
+ options.shouldRetry ??= () => true;
281
+ options.retries ??= 10;
282
+ const operation = import_retry.operation(options);
283
+ const abortHandler = () => {
284
+ operation.stop();
285
+ reject(options.signal?.reason);
286
+ };
287
+ if (options.signal && !options.signal.aborted) options.signal.addEventListener("abort", abortHandler, { once: true });
288
+ const cleanUp = () => {
289
+ options.signal?.removeEventListener("abort", abortHandler);
290
+ operation.stop();
291
+ };
292
+ operation.attempt(async (attemptNumber) => {
293
+ try {
294
+ const result = await input(attemptNumber);
295
+ cleanUp();
296
+ resolve(result);
297
+ } catch (error) {
298
+ try {
299
+ if (!(error instanceof Error)) throw new TypeError(`Non-error was thrown: "${error}". You should only throw errors.`);
300
+ if (error instanceof AbortError) throw error.originalError;
301
+ if (error instanceof TypeError && !isNetworkError(error)) throw error;
302
+ decorateErrorWithCounts(error, attemptNumber, options);
303
+ if (!await options.shouldRetry(error)) {
304
+ operation.stop();
305
+ reject(error);
306
+ }
307
+ await options.onFailedAttempt(error);
308
+ if (!operation.retry(error)) throw operation.mainError();
309
+ } catch (finalError) {
310
+ decorateErrorWithCounts(finalError, attemptNumber, options);
311
+ cleanUp();
312
+ reject(finalError);
313
+ }
314
+ }
315
+ });
316
+ });
317
+ }
318
+
319
+ //#endregion
320
+ export { InvariantError, capitalize, clamp, dedent, dedentRaw, formatStr, getChangedKeys, getOwnProperty, hasOwnProperty, invariant, isNotNull, isNotNullish, isNotUndefined, isTruthy, omit, pRetry as promiseRetry, sanitizeIdentifier, toCamelCase, toKebabCase, toPascalCase, toSnakeCase };
@@ -19,6 +19,5 @@
19
19
  * ```
20
20
  */
21
21
  declare function clamp(value: number, min: number, max: number): number;
22
-
23
22
  //#endregion
24
- export { clamp as clamp$1 };
23
+ export { clamp };
package/dist/number.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { clamp$1 as clamp } from "./number-C2E_sOOy.js";
1
+ import { clamp } from "./number-DzUC7V5F.js";
2
2
  export { clamp };
@@ -0,0 +1,84 @@
1
+ //#region src/object.d.ts
2
+ /**
3
+ * Checks if an object has a specific property as its own property (not inherited).
4
+ *
5
+ * @param {object} obj - The object to check
6
+ * @param {string} key - The property key to check for
7
+ * @returns {boolean} `true` if the object has the property as its own property, `false` otherwise
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { hasOwnProperty } from '@luxass/utils/object';
12
+ *
13
+ * const obj = { name: 'John' };
14
+ * hasOwnProperty(obj, 'name'); // true
15
+ * hasOwnProperty(obj, 'toString'); // false (inherited)
16
+ * ```
17
+ */
18
+ declare function hasOwnProperty(obj: object, key: string): boolean;
19
+ /**
20
+ * Safely gets an own property value from an object, returning undefined if the property doesn't exist.
21
+ *
22
+ * This function provides type-safe property access with multiple overloads:
23
+ * - For objects with known key-value types, returns the value type or undefined
24
+ * - For generic objects, returns the property value type or undefined
25
+ * - Fallback returns unknown type
26
+ *
27
+ * @param {object} obj - The object to get the property from
28
+ * @param {string} key - The property key to retrieve
29
+ * @returns {unknown} The property value if it exists as an own property, undefined otherwise
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * import { getOwnProperty } from '@luxass/utils/object';
34
+ *
35
+ * const obj = { name: 'John', age: 30 };
36
+ * getOwnProperty(obj, 'name'); // 'John'
37
+ * getOwnProperty(obj, 'missing'); // undefined
38
+ * ```
39
+ */
40
+ declare function getOwnProperty<K extends string, V>(obj: Partial<Record<K, V>>, key: K): V | undefined;
41
+ declare function getOwnProperty<O extends object>(obj: O, key: string): O[keyof O] | undefined;
42
+ declare function getOwnProperty(obj: object, key: string): unknown;
43
+ /**
44
+ * Compares two objects and returns an array of keys where the values differ.
45
+ *
46
+ * Uses Object.is() for comparison, which handles special cases like NaN and -0/+0 correctly.
47
+ * Only checks keys that exist in the first object.
48
+ *
49
+ * @template T - The type of objects being compared
50
+ * @param {T} obj1 - The first object to compare
51
+ * @param {T} obj2 - The second object to compare
52
+ * @returns {(keyof T)[]} An array of keys where the values differ between the two objects
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * import { getChangedKeys } from '@luxass/utils/object';
57
+ *
58
+ * const obj1 = { name: 'John', age: 30, city: 'NYC' };
59
+ * const obj2 = { name: 'John', age: 31, city: 'NYC' };
60
+ * getChangedKeys(obj1, obj2); // ['age']
61
+ * ```
62
+ */
63
+ declare function getChangedKeys<T extends object>(obj1: T, obj2: T): (keyof T)[];
64
+ /**
65
+ * Creates a new object with specified keys omitted from the original object.
66
+ *
67
+ * This function creates a shallow copy of the input object and removes the specified keys.
68
+ * The original object is not modified.
69
+ *
70
+ * @param {Record<string, unknown>} obj - The source object to omit keys from
71
+ * @param {ReadonlyArray<string>} keys - An array of key names to omit from the object
72
+ * @returns {Record<string, unknown>} A new object with the specified keys removed
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * import { omit } from '@luxass/utils/object';
77
+ *
78
+ * const obj = { name: 'John', age: 30, city: 'NYC', country: 'USA' };
79
+ * omit(obj, ['age', 'country']); // { name: 'John', city: 'NYC' }
80
+ * ```
81
+ */
82
+ declare function omit(obj: Record<string, unknown>, keys: ReadonlyArray<string>): Record<string, unknown>;
83
+ //#endregion
84
+ export { getChangedKeys, getOwnProperty, hasOwnProperty, omit };
@@ -0,0 +1,75 @@
1
+ //#region src/object.ts
2
+ /**
3
+ * Checks if an object has a specific property as its own property (not inherited).
4
+ *
5
+ * @param {object} obj - The object to check
6
+ * @param {string} key - The property key to check for
7
+ * @returns {boolean} `true` if the object has the property as its own property, `false` otherwise
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { hasOwnProperty } from '@luxass/utils/object';
12
+ *
13
+ * const obj = { name: 'John' };
14
+ * hasOwnProperty(obj, 'name'); // true
15
+ * hasOwnProperty(obj, 'toString'); // false (inherited)
16
+ * ```
17
+ */
18
+ function hasOwnProperty(obj, key) {
19
+ return Object.prototype.hasOwnProperty.call(obj, key);
20
+ }
21
+ function getOwnProperty(obj, key) {
22
+ if (!hasOwnProperty(obj, key)) return void 0;
23
+ return obj[key];
24
+ }
25
+ /**
26
+ * Compares two objects and returns an array of keys where the values differ.
27
+ *
28
+ * Uses Object.is() for comparison, which handles special cases like NaN and -0/+0 correctly.
29
+ * Only checks keys that exist in the first object.
30
+ *
31
+ * @template T - The type of objects being compared
32
+ * @param {T} obj1 - The first object to compare
33
+ * @param {T} obj2 - The second object to compare
34
+ * @returns {(keyof T)[]} An array of keys where the values differ between the two objects
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * import { getChangedKeys } from '@luxass/utils/object';
39
+ *
40
+ * const obj1 = { name: 'John', age: 30, city: 'NYC' };
41
+ * const obj2 = { name: 'John', age: 31, city: 'NYC' };
42
+ * getChangedKeys(obj1, obj2); // ['age']
43
+ * ```
44
+ */
45
+ function getChangedKeys(obj1, obj2) {
46
+ const result = [];
47
+ for (const key in obj1) if (!Object.is(obj1[key], obj2[key])) result.push(key);
48
+ return result;
49
+ }
50
+ /**
51
+ * Creates a new object with specified keys omitted from the original object.
52
+ *
53
+ * This function creates a shallow copy of the input object and removes the specified keys.
54
+ * The original object is not modified.
55
+ *
56
+ * @param {Record<string, unknown>} obj - The source object to omit keys from
57
+ * @param {ReadonlyArray<string>} keys - An array of key names to omit from the object
58
+ * @returns {Record<string, unknown>} A new object with the specified keys removed
59
+ *
60
+ * @example
61
+ * ```typescript
62
+ * import { omit } from '@luxass/utils/object';
63
+ *
64
+ * const obj = { name: 'John', age: 30, city: 'NYC', country: 'USA' };
65
+ * omit(obj, ['age', 'country']); // { name: 'John', city: 'NYC' }
66
+ * ```
67
+ */
68
+ function omit(obj, keys) {
69
+ const result = { ...obj };
70
+ for (const key of keys) delete result[key];
71
+ return result;
72
+ }
73
+
74
+ //#endregion
75
+ export { getChangedKeys, getOwnProperty, hasOwnProperty, omit };
@@ -0,0 +1,2 @@
1
+ import { getChangedKeys, getOwnProperty, hasOwnProperty, omit } from "./object-BT3S70pM.js";
2
+ export { getChangedKeys, getOwnProperty, hasOwnProperty, omit };
package/dist/object.js ADDED
@@ -0,0 +1,3 @@
1
+ import { getChangedKeys, getOwnProperty, hasOwnProperty, omit } from "./object-CyGLe77G.js";
2
+
3
+ export { getChangedKeys, getOwnProperty, hasOwnProperty, omit };
@@ -129,4 +129,4 @@ declare function sanitizeIdentifier(str: string): string;
129
129
  */
130
130
  declare function formatStr(message: string, ...positionals: unknown[]): string;
131
131
  //#endregion
132
- export { capitalize as capitalize$1, dedent as dedent$1, dedentRaw as dedentRaw$1, formatStr as formatStr$1, sanitizeIdentifier as sanitizeIdentifier$1, toCamelCase as toCamelCase$1, toKebabCase as toKebabCase$1, toPascalCase as toPascalCase$1, toSnakeCase as toSnakeCase$1 };
132
+ export { capitalize, dedent, dedentRaw, formatStr, sanitizeIdentifier, toCamelCase, toKebabCase, toPascalCase, toSnakeCase };
package/dist/string.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { capitalize$1 as capitalize, dedent$1 as dedent, dedentRaw$1 as dedentRaw, formatStr$1 as formatStr, sanitizeIdentifier$1 as sanitizeIdentifier, toCamelCase$1 as toCamelCase, toKebabCase$1 as toKebabCase, toPascalCase$1 as toPascalCase, toSnakeCase$1 as toSnakeCase } from "./string-CBWIJiC0.js";
1
+ import { capitalize, dedent, dedentRaw, formatStr, sanitizeIdentifier, toCamelCase, toKebabCase, toPascalCase, toSnakeCase } from "./string-BjsgnDeW.js";
2
2
  export { capitalize, dedent, dedentRaw, formatStr, sanitizeIdentifier, toCamelCase, toKebabCase, toPascalCase, toSnakeCase };
@@ -82,6 +82,5 @@ type Prettify<T> = { [K in keyof T]: T[K] } & {};
82
82
  * ```
83
83
  */
84
84
  type RemoveIndexSignature<T> = { [K in keyof T as {} extends Record<K, 1> ? never : K]: T[K] };
85
-
86
85
  //#endregion
87
86
  export { ElementOf, InferArguments, MaybeArray, MaybePromise, Nullable, Nullish, Prettify, RemoveIndexSignature };
package/dist/types.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { ElementOf, InferArguments, MaybeArray, MaybePromise, Nullable, Nullish, Prettify, RemoveIndexSignature } from "./types-QETho94V.js";
1
+ import { ElementOf, InferArguments, MaybeArray, MaybePromise, Nullable, Nullish, Prettify, RemoveIndexSignature } from "./types-DCrM3M9i.js";
2
2
  export { ElementOf, InferArguments, MaybeArray, MaybePromise, Nullable, Nullish, Prettify, RemoveIndexSignature };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luxass/utils",
3
- "version": "2.2.2",
3
+ "version": "2.4.0",
4
4
  "description": "A collection of utilities for JavaScript/TypeScript",
5
5
  "type": "module",
6
6
  "author": {
@@ -23,9 +23,10 @@
23
23
  "sideEffects": false,
24
24
  "exports": {
25
25
  ".": "./dist/index.js",
26
- "./string": "./dist/string.js",
27
26
  "./guards": "./dist/guards.js",
28
27
  "./number": "./dist/number.js",
28
+ "./object": "./dist/object.js",
29
+ "./string": "./dist/string.js",
29
30
  "./types": "./dist/types.js",
30
31
  "./package.json": "./package.json"
31
32
  },
@@ -38,6 +39,9 @@
38
39
  "engines": {
39
40
  "node": ">=20"
40
41
  },
42
+ "dependencies": {
43
+ "p-retry": "^6.2.1"
44
+ },
41
45
  "devDependencies": {
42
46
  "@luxass/eslint-config": "^4.18.1",
43
47
  "@types/node": "^22.15.2",
@@ -45,7 +49,7 @@
45
49
  "eslint": "^9.27.0",
46
50
  "eslint-plugin-format": "^1.0.1",
47
51
  "publint": "^0.3.12",
48
- "tsdown": "^0.11.12",
52
+ "tsdown": "^0.12.9",
49
53
  "typescript": "^5.8.3",
50
54
  "vitest": "^3.1.4",
51
55
  "vitest-package-exports": "^0.1.1"