@js-utils-kit/object 1.0.0 → 1.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
@@ -1 +1 @@
1
- function e(t=!1,...n){let r=e=>typeof e==`object`&&!!e,i={};for(let a of n)if(r(a))for(let n of Object.keys(a)){let o=a[n],s=i[n];Array.isArray(o)?i[n]=t&&Array.isArray(s)?[...s,...o]:[...o]:r(o)&&!Array.isArray(o)?i[n]=r(s)&&!Array.isArray(s)?e(t,s,o):e(t,{},o):i[n]=o}return i}exports.mergeObj=e;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`@js-utils-kit/valid`);function t(e,n=new WeakSet){if(e===null||typeof e!=`object`&&typeof e!=`function`)return e;let r=e;if(n.has(r))return e;n.add(r);let i=r;for(let e of Reflect.ownKeys(i)){let r=i[e];r!==null&&(typeof r==`object`||typeof r==`function`)&&t(r,n)}return Object.freeze(e)}const n=[`arrayStrategy`];function r(t){return(0,e.isObject)(t)?Object.keys(t).every(e=>n.includes(e)):!1}function i(...t){let n={};t.length>0&&r(t[t.length-1])&&(n=t.pop());let a={},{arrayStrategy:o=`replace`}=n;for(let n of t)if((0,e.isObject)(n))for(let t of Object.keys(n)){if(t===`__proto__`||t===`constructor`||t===`prototype`)continue;let r=n[t],s=a[t];if((0,e.isArray)(s)&&(0,e.isArray)(r)){switch(o){case`concat`:a[t]=[...s,...r];break;case`merge`:a[t]=[...new Set([...s,...r])];break;default:a[t]=[...r]}continue}if((0,e.isObject)(r)){a[t]=(0,e.isObject)(s)&&!Array.isArray(s)?i(s,r,{arrayStrategy:o}):i({},r,{arrayStrategy:o});continue}a[t]=r}return a}function a(e=!1,...t){let n=e=>typeof e==`object`&&!!e,r={};for(let i of t)if(n(i))for(let t of Object.keys(i)){let o=i[t],s=r[t];Array.isArray(o)?r[t]=e&&Array.isArray(s)?[...s,...o]:[...o]:n(o)&&!Array.isArray(o)?r[t]=n(s)&&!Array.isArray(s)?a(e,s,o):a(e,{},o):r[t]=o}return r}exports.deepFreeze=t,exports.deepMerge=i,exports.mergeObj=a;
package/dist/index.d.cts CHANGED
@@ -1,3 +1,201 @@
1
+ import { PlainObject } from "@js-utils-kit/types";
2
+
3
+ //#region src/deepFreeze.d.ts
4
+ /**
5
+ * Recursively freezes an object and all of its nested properties.
6
+ *
7
+ * @remarks
8
+ * This function performs a deep, immutable freeze:
9
+ * - Safely handles circular references
10
+ * - Freezes symbol and non-enumerable properties
11
+ * - Prevents repeated processing of shared references
12
+ * - Uses `WeakSet` internally to avoid memory leaks
13
+ *
14
+ * @typeParam T - The type of the value to freeze
15
+ *
16
+ * @returns The same value, deeply frozen and typed as `Readonly<T>`
17
+ *
18
+ * @example Basic usage
19
+ * ```ts
20
+ * const config = deepFreeze({
21
+ * api: {
22
+ * url: 'https://example.com',
23
+ * timeout: 5000
24
+ * }
25
+ * });
26
+ *
27
+ * // Compile-time error and runtime TypeError
28
+ * config.api.url = 'https://evil.com';
29
+ * ```
30
+ *
31
+ * @example Freezing arrays
32
+ * ```ts
33
+ * const list = deepFreeze([1, 2, { value: 3 }]);
34
+ *
35
+ * // Runtime TypeError
36
+ * list.push(4);
37
+ *
38
+ * // Runtime TypeError
39
+ * list[2].value = 10;
40
+ * ```
41
+ *
42
+ * @example Circular references
43
+ * ```ts
44
+ * const obj: any = { name: 'circle' };
45
+ * obj.self = obj;
46
+ *
47
+ * // Does not throw or recurse infinitely
48
+ * deepFreeze(obj);
49
+ *
50
+ * // Runtime TypeError
51
+ * obj.name = 'x';
52
+ * ```
53
+ *
54
+ * @example Shared references
55
+ * ```ts
56
+ * const shared = { count: 0 };
57
+ *
58
+ * const state = deepFreeze({
59
+ * a: shared,
60
+ * b: shared
61
+ * });
62
+ *
63
+ * // Runtime TypeError
64
+ * state.a.count = 1;
65
+ *
66
+ * // Runtime TypeError
67
+ * state.b.count = 2;
68
+ * ```
69
+ *
70
+ * @example Symbol and non-enumerable properties
71
+ * ```ts
72
+ * const secret = Symbol('secret');
73
+ *
74
+ * const obj = {};
75
+ * Object.defineProperty(obj, 'hidden', {
76
+ * value: { token: '123' },
77
+ * enumerable: false
78
+ * });
79
+ *
80
+ * (obj as any)[secret] = { enabled: true };
81
+ *
82
+ * deepFreeze(obj);
83
+ *
84
+ * // Runtime TypeError
85
+ * obj.hidden.token = '456';
86
+ *
87
+ * // Runtime TypeError
88
+ * (obj as any)[secret].enabled = false;
89
+ * ```
90
+ *
91
+ * @example Functions with properties
92
+ * ```ts
93
+ * function task() {}
94
+ * (task as any).meta = { active: true };
95
+ *
96
+ * deepFreeze(task);
97
+ *
98
+ * // Runtime TypeError
99
+ * (task as any).meta.active = false;
100
+ * ```
101
+ */
102
+ declare function deepFreeze<T>(
103
+ /**
104
+ * The value to deeply freeze.
105
+ */
106
+ obj: T,
107
+ /**
108
+ * Internal WeakSet used to track visited objects during recursion.
109
+ *
110
+ * @internal
111
+ */
112
+ visited?: WeakSet<object>): Readonly<T>;
113
+ //#endregion
114
+ //#region src/deepMerge.d.ts
115
+ /**
116
+ * Configuration options for {@link deepMerge}.
117
+ */
118
+ interface DeepMergeOptions {
119
+ /**
120
+ * Defines how arrays should be handled when merging.
121
+ *
122
+ * - `replace` - the incoming array replaces the existing array
123
+ * - `concat` - arrays are concatenated
124
+ * - `merge` - arrays are merged with duplicate values removed
125
+ *
126
+ * @defaultValue "replace"
127
+ */
128
+ arrayStrategy?: 'replace' | 'merge' | 'concat';
129
+ }
130
+ /**
131
+ * Deeply merges multiple objects into a new object.
132
+ *
133
+ * Later objects override properties from earlier ones.
134
+ *
135
+ * @remarks
136
+ * - The merge is **immutable** input objects are never modified.
137
+ * - Primitive values from later objects override earlier values.
138
+ * - Nested objects are merged recursively.
139
+ * - Arrays are handled based on {@link DeepMergeOptions.arrayStrategy | arrayStrategy}.
140
+ *
141
+ * @typeParam T - The object type being merged.
142
+ *
143
+ * @returns A new object containing the merged properties.
144
+ *
145
+ * @example Basic merge
146
+ * ```ts
147
+ * deepMerge(
148
+ * { a: 1 },
149
+ * { b: 2 }
150
+ * )
151
+ *
152
+ * // Result
153
+ * { a: 1, b: 2 }
154
+ * ```
155
+ *
156
+ * @example Nested object merge
157
+ * ```ts
158
+ * deepMerge(
159
+ * { config: { port: 3000 } },
160
+ * { config: { host: "localhost" } }
161
+ * )
162
+ *
163
+ * // Result
164
+ * { config: { port: 3000, host: "localhost" } }
165
+ * ```
166
+ *
167
+ * @example Array concatenation
168
+ * ```ts
169
+ * deepMerge(
170
+ * { items: [1, 2] },
171
+ * { items: [3] },
172
+ * { arrayStrategy: "concat" }
173
+ * )
174
+ *
175
+ * // Result
176
+ * { items: [1, 2, 3] }
177
+ * ```
178
+ *
179
+ * @example Array merge (deduplicated)
180
+ * ```ts
181
+ * deepMerge(
182
+ * { items: [1, 2] },
183
+ * { items: [2, 3] },
184
+ * { arrayStrategy: "merge" }
185
+ * )
186
+ *
187
+ * // Result
188
+ * { items: [1, 2, 3] }
189
+ * ```
190
+ */
191
+ declare function deepMerge<T extends PlainObject>(
192
+ /**
193
+ * Objects to merge.
194
+ *
195
+ * The last argument may optionally be a {@link DeepMergeOptions} object.
196
+ */
197
+ ...params: (T | DeepMergeOptions)[]): T;
198
+ //#endregion
1
199
  //#region src/mergeObj.d.ts
2
200
  /**
3
201
  * Deeply merges multiple source objects into one.
@@ -16,6 +214,7 @@
16
214
  *
17
215
  * @returns A new object containing deeply merged keys and values.
18
216
  *
217
+ * @deprecated Use {@link deepMerge} instead.
19
218
  *
20
219
  * @example
21
220
  * ```ts
@@ -43,7 +242,7 @@ declare function mergeObj(
43
242
  *
44
243
  * @default false
45
244
  */
46
- appendArray?: boolean, /** One or more objects to deeply merge */
47
- ...sources: object[]): object;
245
+
246
+ appendArray?: boolean, /** One or more objects to deeply merge */...sources: object[]): object;
48
247
  //#endregion
49
- export { mergeObj };
248
+ export { DeepMergeOptions, deepFreeze, deepMerge, mergeObj };
package/dist/index.d.mts CHANGED
@@ -1,3 +1,201 @@
1
+ import { PlainObject } from "@js-utils-kit/types";
2
+
3
+ //#region src/deepFreeze.d.ts
4
+ /**
5
+ * Recursively freezes an object and all of its nested properties.
6
+ *
7
+ * @remarks
8
+ * This function performs a deep, immutable freeze:
9
+ * - Safely handles circular references
10
+ * - Freezes symbol and non-enumerable properties
11
+ * - Prevents repeated processing of shared references
12
+ * - Uses `WeakSet` internally to avoid memory leaks
13
+ *
14
+ * @typeParam T - The type of the value to freeze
15
+ *
16
+ * @returns The same value, deeply frozen and typed as `Readonly<T>`
17
+ *
18
+ * @example Basic usage
19
+ * ```ts
20
+ * const config = deepFreeze({
21
+ * api: {
22
+ * url: 'https://example.com',
23
+ * timeout: 5000
24
+ * }
25
+ * });
26
+ *
27
+ * // Compile-time error and runtime TypeError
28
+ * config.api.url = 'https://evil.com';
29
+ * ```
30
+ *
31
+ * @example Freezing arrays
32
+ * ```ts
33
+ * const list = deepFreeze([1, 2, { value: 3 }]);
34
+ *
35
+ * // Runtime TypeError
36
+ * list.push(4);
37
+ *
38
+ * // Runtime TypeError
39
+ * list[2].value = 10;
40
+ * ```
41
+ *
42
+ * @example Circular references
43
+ * ```ts
44
+ * const obj: any = { name: 'circle' };
45
+ * obj.self = obj;
46
+ *
47
+ * // Does not throw or recurse infinitely
48
+ * deepFreeze(obj);
49
+ *
50
+ * // Runtime TypeError
51
+ * obj.name = 'x';
52
+ * ```
53
+ *
54
+ * @example Shared references
55
+ * ```ts
56
+ * const shared = { count: 0 };
57
+ *
58
+ * const state = deepFreeze({
59
+ * a: shared,
60
+ * b: shared
61
+ * });
62
+ *
63
+ * // Runtime TypeError
64
+ * state.a.count = 1;
65
+ *
66
+ * // Runtime TypeError
67
+ * state.b.count = 2;
68
+ * ```
69
+ *
70
+ * @example Symbol and non-enumerable properties
71
+ * ```ts
72
+ * const secret = Symbol('secret');
73
+ *
74
+ * const obj = {};
75
+ * Object.defineProperty(obj, 'hidden', {
76
+ * value: { token: '123' },
77
+ * enumerable: false
78
+ * });
79
+ *
80
+ * (obj as any)[secret] = { enabled: true };
81
+ *
82
+ * deepFreeze(obj);
83
+ *
84
+ * // Runtime TypeError
85
+ * obj.hidden.token = '456';
86
+ *
87
+ * // Runtime TypeError
88
+ * (obj as any)[secret].enabled = false;
89
+ * ```
90
+ *
91
+ * @example Functions with properties
92
+ * ```ts
93
+ * function task() {}
94
+ * (task as any).meta = { active: true };
95
+ *
96
+ * deepFreeze(task);
97
+ *
98
+ * // Runtime TypeError
99
+ * (task as any).meta.active = false;
100
+ * ```
101
+ */
102
+ declare function deepFreeze<T>(
103
+ /**
104
+ * The value to deeply freeze.
105
+ */
106
+ obj: T,
107
+ /**
108
+ * Internal WeakSet used to track visited objects during recursion.
109
+ *
110
+ * @internal
111
+ */
112
+ visited?: WeakSet<object>): Readonly<T>;
113
+ //#endregion
114
+ //#region src/deepMerge.d.ts
115
+ /**
116
+ * Configuration options for {@link deepMerge}.
117
+ */
118
+ interface DeepMergeOptions {
119
+ /**
120
+ * Defines how arrays should be handled when merging.
121
+ *
122
+ * - `replace` - the incoming array replaces the existing array
123
+ * - `concat` - arrays are concatenated
124
+ * - `merge` - arrays are merged with duplicate values removed
125
+ *
126
+ * @defaultValue "replace"
127
+ */
128
+ arrayStrategy?: 'replace' | 'merge' | 'concat';
129
+ }
130
+ /**
131
+ * Deeply merges multiple objects into a new object.
132
+ *
133
+ * Later objects override properties from earlier ones.
134
+ *
135
+ * @remarks
136
+ * - The merge is **immutable** input objects are never modified.
137
+ * - Primitive values from later objects override earlier values.
138
+ * - Nested objects are merged recursively.
139
+ * - Arrays are handled based on {@link DeepMergeOptions.arrayStrategy | arrayStrategy}.
140
+ *
141
+ * @typeParam T - The object type being merged.
142
+ *
143
+ * @returns A new object containing the merged properties.
144
+ *
145
+ * @example Basic merge
146
+ * ```ts
147
+ * deepMerge(
148
+ * { a: 1 },
149
+ * { b: 2 }
150
+ * )
151
+ *
152
+ * // Result
153
+ * { a: 1, b: 2 }
154
+ * ```
155
+ *
156
+ * @example Nested object merge
157
+ * ```ts
158
+ * deepMerge(
159
+ * { config: { port: 3000 } },
160
+ * { config: { host: "localhost" } }
161
+ * )
162
+ *
163
+ * // Result
164
+ * { config: { port: 3000, host: "localhost" } }
165
+ * ```
166
+ *
167
+ * @example Array concatenation
168
+ * ```ts
169
+ * deepMerge(
170
+ * { items: [1, 2] },
171
+ * { items: [3] },
172
+ * { arrayStrategy: "concat" }
173
+ * )
174
+ *
175
+ * // Result
176
+ * { items: [1, 2, 3] }
177
+ * ```
178
+ *
179
+ * @example Array merge (deduplicated)
180
+ * ```ts
181
+ * deepMerge(
182
+ * { items: [1, 2] },
183
+ * { items: [2, 3] },
184
+ * { arrayStrategy: "merge" }
185
+ * )
186
+ *
187
+ * // Result
188
+ * { items: [1, 2, 3] }
189
+ * ```
190
+ */
191
+ declare function deepMerge<T extends PlainObject>(
192
+ /**
193
+ * Objects to merge.
194
+ *
195
+ * The last argument may optionally be a {@link DeepMergeOptions} object.
196
+ */
197
+ ...params: (T | DeepMergeOptions)[]): T;
198
+ //#endregion
1
199
  //#region src/mergeObj.d.ts
2
200
  /**
3
201
  * Deeply merges multiple source objects into one.
@@ -16,6 +214,7 @@
16
214
  *
17
215
  * @returns A new object containing deeply merged keys and values.
18
216
  *
217
+ * @deprecated Use {@link deepMerge} instead.
19
218
  *
20
219
  * @example
21
220
  * ```ts
@@ -43,7 +242,7 @@ declare function mergeObj(
43
242
  *
44
243
  * @default false
45
244
  */
46
- appendArray?: boolean, /** One or more objects to deeply merge */
47
- ...sources: object[]): object;
245
+
246
+ appendArray?: boolean, /** One or more objects to deeply merge */...sources: object[]): object;
48
247
  //#endregion
49
- export { mergeObj };
248
+ export { DeepMergeOptions, deepFreeze, deepMerge, mergeObj };
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- function e(t=!1,...n){let r=e=>typeof e==`object`&&!!e,i={};for(let a of n)if(r(a))for(let n of Object.keys(a)){let o=a[n],s=i[n];Array.isArray(o)?i[n]=t&&Array.isArray(s)?[...s,...o]:[...o]:r(o)&&!Array.isArray(o)?i[n]=r(s)&&!Array.isArray(s)?e(t,s,o):e(t,{},o):i[n]=o}return i}export{e as mergeObj};
1
+ import{isArray as e,isObject as t}from"@js-utils-kit/valid";function n(e,t=new WeakSet){if(e===null||typeof e!=`object`&&typeof e!=`function`)return e;let r=e;if(t.has(r))return e;t.add(r);let i=r;for(let e of Reflect.ownKeys(i)){let r=i[e];r!==null&&(typeof r==`object`||typeof r==`function`)&&n(r,t)}return Object.freeze(e)}const r=[`arrayStrategy`];function i(e){return t(e)?Object.keys(e).every(e=>r.includes(e)):!1}function a(...n){let r={};n.length>0&&i(n[n.length-1])&&(r=n.pop());let o={},{arrayStrategy:s=`replace`}=r;for(let r of n)if(t(r))for(let n of Object.keys(r)){if(n===`__proto__`||n===`constructor`||n===`prototype`)continue;let i=r[n],c=o[n];if(e(c)&&e(i)){switch(s){case`concat`:o[n]=[...c,...i];break;case`merge`:o[n]=[...new Set([...c,...i])];break;default:o[n]=[...i]}continue}if(t(i)){o[n]=t(c)&&!Array.isArray(c)?a(c,i,{arrayStrategy:s}):a({},i,{arrayStrategy:s});continue}o[n]=i}return o}function o(e=!1,...t){let n=e=>typeof e==`object`&&!!e,r={};for(let i of t)if(n(i))for(let t of Object.keys(i)){let a=i[t],s=r[t];Array.isArray(a)?r[t]=e&&Array.isArray(s)?[...s,...a]:[...a]:n(a)&&!Array.isArray(a)?r[t]=n(s)&&!Array.isArray(s)?o(e,s,a):o(e,{},a):r[t]=a}return r}export{n as deepFreeze,a as deepMerge,o as mergeObj};
package/package.json CHANGED
@@ -1,14 +1,7 @@
1
1
  {
2
2
  "name": "@js-utils-kit/object",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "Object utilities",
5
- "private": false,
6
- "license": "MIT",
7
- "author": {
8
- "name": "Sriman",
9
- "email": "136729116+TenEplaysOfficial@users.noreply.github.com",
10
- "url": "https://tene.vercel.app"
11
- },
12
5
  "homepage": "https://js-utils.js.org",
13
6
  "repository": {
14
7
  "type": "git",
@@ -18,23 +11,33 @@
18
11
  "bugs": {
19
12
  "url": "https://github.com/teneplaysofficial/js-utils-kit/issues"
20
13
  },
14
+ "license": "MIT",
15
+ "author": {
16
+ "name": "Sriman",
17
+ "email": "136729116+TenEplaysOfficial@users.noreply.github.com",
18
+ "url": "https://tene.vercel.app"
19
+ },
20
+ "private": false,
21
21
  "files": [
22
22
  "dist"
23
23
  ],
24
- "engines": {
25
- "node": ">=22"
26
- },
27
24
  "type": "module",
28
25
  "main": "./dist/index.cjs",
29
26
  "module": "./dist/index.mjs",
30
- "types": "./dist/index.d.cts",
31
27
  "exports": {
32
28
  ".": {
33
29
  "import": "./dist/index.mjs",
34
30
  "require": "./dist/index.cjs"
35
31
  }
36
32
  },
37
- "dependencies": {},
33
+ "types": "./dist/index.d.cts",
34
+ "engines": {
35
+ "node": ">=22"
36
+ },
37
+ "dependencies": {
38
+ "@js-utils-kit/types": "1.5.0",
39
+ "@js-utils-kit/valid": "2.0.0"
40
+ },
38
41
  "scripts": {
39
42
  "build": "tsdown",
40
43
  "test": "vitest run"