@codady/utils 0.0.8 → 0.0.10

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/src/deepClone.js CHANGED
@@ -1,53 +1,178 @@
1
1
  /**
2
- * @since Last modified: 2025/12/16 13:33:46
3
- * Deep clone an array or object.
4
- * Supports Symbol keys. These types are returned directly:
5
- * Number, String, Boolean, Symbol, HTML*Element, Function, Date, RegExp.
2
+ * @since Last modified: 2025/12/22 20:20:47
3
+ * Deep clone an array, object, or other cloneable data types.
6
4
  *
7
- * @template T
8
- * @param {T} data - Array or object to clone
9
- * @returns {T} - New object with different memory address
5
+ * Features:
6
+ * - Handles nested objects and arrays recursively
7
+ * - Preserves Symbol properties
8
+ * - Customizable cloning behavior via options
9
+ * - Interceptor for custom cloning logic
10
+ * - Lifecycle callbacks for monitoring
11
+ *
12
+ * Default cloning behavior:
13
+ * - Objects and arrays: Deep cloned (enabled by default)
14
+ * - Maps and Sets: Deep cloned (enabled by default)
15
+ * - Dates: Returned directly (disabled by default, set cloneDate: true to clone)
16
+ * - RegExp: Returned directly (disabled by default, set cloneRegex: true to clone)
17
+ * - DOM elements: Returned directly (disabled by default, set cloneElement: true to clone)
18
+ * - DocumentFragment: Returned directly (disabled by default, set cloneFragment: true to clone)
19
+ *
20
+ * Types always returned directly (no cloning):
21
+ * - Primitive types: Number, String, Boolean, BigInt, undefined, null
22
+ * - Functions and Classes
23
+ * - Symbol instances
24
+ * - Errors and Promises
25
+ * - ArrayBuffer, Blob, File
26
+ * - WeakMap and WeakSet
27
+ *
28
+ * @template T - Type of the data to clone
29
+ * @param {T} data - The data to deep clone
30
+ * @param {DeepCloneOptions} [options={}] - Configuration options for cloning behavior
31
+ * @returns {T} - A deep clone of the input data (new memory reference)
10
32
  *
11
33
  * @example
12
- * const obj = { a: '', b: 0, c: [] };
34
+ * // Basic usage - clones objects and arrays
35
+ * const obj = { a: '', b: 0, c: [], d: new Map([['key', 'value']]) };
13
36
  * const cloned = deepClone(obj);
37
+ * console.log(cloned !== obj); // true
38
+ * console.log(cloned.c !== obj.c); // true
39
+ *
40
+ * @example
41
+ * // With Symbol properties
42
+ * const sym = Symbol('id');
43
+ * const objWithSymbol = { [sym]: 'value', normal: 'property' };
44
+ * const clonedWithSymbol = deepClone(objWithSymbol);
45
+ *
46
+ * @example
47
+ * // Custom options - clone Dates and RegExp
48
+ * const data = { date: new Date(), regex: /test/gi };
49
+ * const cloned = deepClone(data, {
50
+ * cloneDate: true,
51
+ * cloneRegex: true
52
+ * });
53
+ *
54
+ * @example
55
+ * // Using interceptor for custom types
56
+ * class CustomClass {
57
+ * constructor(public value: number) {}
58
+ * }
59
+ *
60
+ * const customData = new CustomClass(42);
61
+ * const cloned = deepClone(customData, {
62
+ * interceptor: (data, type) => {
63
+ * if (data instanceof CustomClass) {
64
+ * return new CustomClass(data.value);
65
+ * }
66
+ * return null;
67
+ * }
68
+ * });
14
69
  *
15
70
  * @example
16
- * const arr = [{}, {}, {}];
17
- * const cloned = deepClone(arr);
71
+ * // With lifecycle callbacks
72
+ * const trackedClone = deepClone(someData, {
73
+ * onBeforeClone: (data, type) => {
74
+ * console.log(`Starting to clone ${type}`);
75
+ * },
76
+ * onAfterClone: (result) => {
77
+ * console.log(`Cloned ${result.type}, success: ${result.cloned}`);
78
+ * }
79
+ * });
18
80
  */
19
81
  'use strict';
20
82
  import getDataType from './getDataType';
21
- const deepClone = (data) => {
22
- const dataType = getDataType(data);
23
- if (dataType === 'Object') {
24
- const newObj = {};
25
- const symbols = Object.getOwnPropertySymbols(data);
83
+ //支持原始值的复制,包括Number、String、Boolean、Null
84
+ //支持Date和Regex对象值复制(值转换)
85
+ //支持{},[],Set和Map的遍历
86
+ const deepClone = (data, options = {}) => {
87
+ const dataType = getDataType(data),
88
+ // Default options
89
+ opts = Object.assign({
90
+ cloneSet: true,
91
+ cloneMap: true,
92
+ cloneObject: true,
93
+ cloneArray: true,
94
+ //可重新构建
95
+ cloneDate: true,
96
+ cloneRegex: true,
97
+ //节点默认不复制
98
+ //cloneElement: false,
99
+ //cloneFragment: false,
100
+ }, options);
101
+ // Check interceptor - if it returns a value (not null/undefined), use it directly
102
+ if (opts.interceptor && typeof opts.interceptor === 'function') {
103
+ let result = opts.interceptor(data, dataType);
104
+ if ((result ?? false)) {
105
+ // Call onAfterClone if set
106
+ opts.onAfterClone?.({
107
+ output: result,
108
+ input: data,
109
+ type: dataType,
110
+ cloned: result !== data,
111
+ });
112
+ return result;
113
+ }
114
+ // If interceptor returns null/undefined, continue with normal cloning process
115
+ }
116
+ // Callback before cloning
117
+ opts.onBeforeClone?.(data, dataType);
118
+ let newData, cloned = true;
119
+ if (dataType === 'Object' && opts.cloneObject) {
120
+ const newObj = {}, symbols = Object.getOwnPropertySymbols(data);
26
121
  // Clone regular properties
27
122
  for (const key in data) {
28
- newObj[key] = deepClone(data[key]);
123
+ newObj[key] = deepClone(data[key], opts);
29
124
  }
30
125
  // Clone Symbol properties
31
126
  if (symbols.length > 0) {
32
127
  for (const symbol of symbols) {
33
- newObj[symbol] = deepClone(data[symbol]);
128
+ newObj[symbol] = deepClone(data[symbol], opts);
34
129
  }
35
130
  }
36
- return newObj;
131
+ newData = newObj;
37
132
  }
38
- else if (dataType === 'Array') {
39
- return data.map(item => deepClone(item));
133
+ else if (dataType === 'Array' && opts.cloneArray) {
134
+ newData = data.map(item => deepClone(item, opts));
135
+ }
136
+ else if (dataType === 'Map' && opts.cloneMap) {
137
+ const newMap = new Map();
138
+ for (const [key, value] of data) {
139
+ // Both Map keys and values need deep cloning
140
+ newMap.set(deepClone(key, opts), deepClone(value, opts));
141
+ }
142
+ newData = newMap;
143
+ }
144
+ else if (dataType === 'Set' && opts.cloneSet) {
145
+ const newSet = new Set();
146
+ for (const value of data) {
147
+ // Set values need deep cloning
148
+ newSet.add(deepClone(value, opts));
149
+ }
150
+ newData = newSet;
40
151
  }
41
- else if (dataType === 'Date') {
42
- return new Date(data.getTime());
152
+ else if (dataType === 'Date' && opts.cloneDate) {
153
+ newData = new Date(data.getTime());
43
154
  }
44
- else if (dataType === 'RegExp') {
155
+ else if (dataType === 'RegExp' && opts.cloneRegex) {
45
156
  const regex = data;
46
- return new RegExp(regex.source, regex.flags);
157
+ newData = new RegExp(regex.source, regex.flags);
158
+ // } else if ((dataType.includes('HTML') && opts.cloneElement) ||
159
+ // (dataType === 'DocumentFragment' && opts.cloneFragment)
160
+ //) {
161
+ //Text,Comment,HTML*Element,DocumentFragment,Attr
162
+ // newData = (data as any).cloneNode(true) as T;
47
163
  }
48
164
  else {
49
- // Number, String, Boolean, Symbol,Text,Comment,Set,Map, HTML*Element, Function,Error,Promise,ArrayBuffer,Blob,File, return directly
50
- return data;
165
+ // Number, String, Boolean, Symbol, Function,Error,Promise,ArrayBuffer,Blob,File, return directly
166
+ newData = data;
167
+ cloned = false;
51
168
  }
169
+ // Callback after cloning
170
+ opts.onAfterClone?.({
171
+ output: newData,
172
+ input: data,
173
+ type: dataType,
174
+ cloned,
175
+ });
176
+ return newData;
52
177
  };
53
178
  export default deepClone;
package/src/deepClone.ts CHANGED
@@ -1,59 +1,218 @@
1
1
  /**
2
- * @since Last modified: 2025/12/16 13:33:46
3
- * Deep clone an array or object.
4
- * Supports Symbol keys. These types are returned directly:
5
- * Number, String, Boolean, Symbol, HTML*Element, Function, Date, RegExp.
2
+ * @since Last modified: 2025/12/22 20:20:47
3
+ * Deep clone an array, object, or other cloneable data types.
6
4
  *
7
- * @template T
8
- * @param {T} data - Array or object to clone
9
- * @returns {T} - New object with different memory address
5
+ * Features:
6
+ * - Handles nested objects and arrays recursively
7
+ * - Preserves Symbol properties
8
+ * - Customizable cloning behavior via options
9
+ * - Interceptor for custom cloning logic
10
+ * - Lifecycle callbacks for monitoring
11
+ *
12
+ * Default cloning behavior:
13
+ * - Objects and arrays: Deep cloned (enabled by default)
14
+ * - Maps and Sets: Deep cloned (enabled by default)
15
+ * - Dates: Returned directly (disabled by default, set cloneDate: true to clone)
16
+ * - RegExp: Returned directly (disabled by default, set cloneRegex: true to clone)
17
+ * - DOM elements: Returned directly (disabled by default, set cloneElement: true to clone)
18
+ * - DocumentFragment: Returned directly (disabled by default, set cloneFragment: true to clone)
19
+ *
20
+ * Types always returned directly (no cloning):
21
+ * - Primitive types: Number, String, Boolean, BigInt, undefined, null
22
+ * - Functions and Classes
23
+ * - Symbol instances
24
+ * - Errors and Promises
25
+ * - ArrayBuffer, Blob, File
26
+ * - WeakMap and WeakSet
27
+ *
28
+ * @template T - Type of the data to clone
29
+ * @param {T} data - The data to deep clone
30
+ * @param {DeepCloneOptions} [options={}] - Configuration options for cloning behavior
31
+ * @returns {T} - A deep clone of the input data (new memory reference)
10
32
  *
11
33
  * @example
12
- * const obj = { a: '', b: 0, c: [] };
34
+ * // Basic usage - clones objects and arrays
35
+ * const obj = { a: '', b: 0, c: [], d: new Map([['key', 'value']]) };
13
36
  * const cloned = deepClone(obj);
37
+ * console.log(cloned !== obj); // true
38
+ * console.log(cloned.c !== obj.c); // true
39
+ *
40
+ * @example
41
+ * // With Symbol properties
42
+ * const sym = Symbol('id');
43
+ * const objWithSymbol = { [sym]: 'value', normal: 'property' };
44
+ * const clonedWithSymbol = deepClone(objWithSymbol);
45
+ *
46
+ * @example
47
+ * // Custom options - clone Dates and RegExp
48
+ * const data = { date: new Date(), regex: /test/gi };
49
+ * const cloned = deepClone(data, {
50
+ * cloneDate: true,
51
+ * cloneRegex: true
52
+ * });
53
+ *
54
+ * @example
55
+ * // Using interceptor for custom types
56
+ * class CustomClass {
57
+ * constructor(public value: number) {}
58
+ * }
14
59
  *
15
- * @example
16
- * const arr = [{}, {}, {}];
17
- * const cloned = deepClone(arr);
60
+ * const customData = new CustomClass(42);
61
+ * const cloned = deepClone(customData, {
62
+ * interceptor: (data, type) => {
63
+ * if (data instanceof CustomClass) {
64
+ * return new CustomClass(data.value);
65
+ * }
66
+ * return null;
67
+ * }
68
+ * });
69
+ *
70
+ * @example
71
+ * // With lifecycle callbacks
72
+ * const trackedClone = deepClone(someData, {
73
+ * onBeforeClone: (data, type) => {
74
+ * console.log(`Starting to clone ${type}`);
75
+ * },
76
+ * onAfterClone: (result) => {
77
+ * console.log(`Cloned ${result.type}, success: ${result.cloned}`);
78
+ * }
79
+ * });
18
80
  */
19
81
  'use strict';
20
82
  import getDataType from './getDataType';
21
83
 
22
- const deepClone = <T>(data: T): T => {
23
- const dataType = getDataType(data);
24
-
25
- if (dataType === 'Object') {
26
- const newObj: Record<string | symbol, any> = {};
27
- const symbols = Object.getOwnPropertySymbols(data);
28
-
84
+ export interface DeepCloneOptions {
85
+ cloneDate?: boolean;
86
+ cloneRegex?: boolean;
87
+ cloneSet?: boolean;
88
+ cloneMap?: boolean;
89
+ cloneObject?: boolean;
90
+ cloneArray?: boolean;
91
+ cloneElement?: boolean;
92
+ cloneFragment?: boolean;
93
+
94
+ /**
95
+ * Interceptor function. If returns a non-null value, use it as the cloning result.
96
+ */
97
+ interceptor?: <T>(data: T, dataType: string) => T | null | undefined;
98
+
99
+ /**
100
+ * Callback before cloning.
101
+ */
102
+ onBeforeClone?: (data: any, dataType: string) => void;
103
+
104
+ /**
105
+ * Callback after cloning.
106
+ * @param result Object containing cloning result.
107
+ */
108
+ onAfterClone?: (result: AfterCloneResult) => void;
109
+ }
110
+ export interface AfterCloneResult<T = any> {
111
+ // Cloned data
112
+ output: T;
113
+ // Original data
114
+ input: any;
115
+ // Data type
116
+ type: string;
117
+ // Whether cloning was performed
118
+ cloned: boolean;
119
+ }
120
+ //支持原始值的复制,包括Number、String、Boolean、Null
121
+ //支持Date和Regex对象值复制(值转换)
122
+ //支持{},[],Set和Map的遍历
123
+ const deepClone = <T>(data: T, options: DeepCloneOptions = {}): T => {
124
+ const dataType = getDataType(data),
125
+ // Default options
126
+ opts = Object.assign({
127
+ cloneSet: true,
128
+ cloneMap: true,
129
+ cloneObject: true,
130
+ cloneArray: true,
131
+ //可重新构建
132
+ cloneDate: true,
133
+ cloneRegex: true,
134
+ //节点默认不复制
135
+ //cloneElement: false,
136
+ //cloneFragment: false,
137
+ }, options);
138
+
139
+ // Check interceptor - if it returns a value (not null/undefined), use it directly
140
+ if (opts.interceptor && typeof opts.interceptor === 'function') {
141
+ let result = opts.interceptor(data, dataType);
142
+ if ((result ?? false)) {
143
+ // Call onAfterClone if set
144
+ opts.onAfterClone?.({
145
+ output: result,
146
+ input: data,
147
+ type: dataType,
148
+ cloned: result !== data,
149
+ });
150
+ return result as T;
151
+ }
152
+ // If interceptor returns null/undefined, continue with normal cloning process
153
+ }
154
+
155
+ // Callback before cloning
156
+ opts.onBeforeClone?.(data, dataType);
157
+
158
+ let newData,
159
+ cloned = true;
160
+
161
+ if (dataType === 'Object' && opts.cloneObject) {
162
+ const newObj: Record<string | symbol, any> = {},
163
+ symbols = Object.getOwnPropertySymbols(data);
164
+
29
165
  // Clone regular properties
30
166
  for (const key in data) {
31
- newObj[key] = deepClone((data as any)[key]);
167
+ newObj[key] = deepClone((data as any)[key],opts);
32
168
  }
33
-
169
+
34
170
  // Clone Symbol properties
35
171
  if (symbols.length > 0) {
36
172
  for (const symbol of symbols) {
37
- newObj[symbol] = deepClone((data as any)[symbol]);
173
+ newObj[symbol] = deepClone((data as any)[symbol],opts);
38
174
  }
39
175
  }
40
-
41
- return newObj as T;
42
-
43
- } else if (dataType === 'Array') {
44
- return (data as any[]).map(item => deepClone(item)) as T;
45
-
46
- } else if (dataType === 'Date') {
47
- return new Date((data as Date).getTime()) as T;
48
-
49
- } else if (dataType === 'RegExp') {
176
+ newData = newObj as T;
177
+ } else if (dataType === 'Array' && opts.cloneArray) {
178
+ newData = (data as any[]).map(item => deepClone(item,opts)) as T;
179
+ } else if (dataType === 'Map' && opts.cloneMap) {
180
+ const newMap = new Map();
181
+ for (const [key, value] of data as Map<any, any>) {
182
+ // Both Map keys and values need deep cloning
183
+ newMap.set(deepClone(key,opts), deepClone(value,opts));
184
+ }
185
+ newData = newMap as T;
186
+ } else if (dataType === 'Set' && opts.cloneSet) {
187
+ const newSet = new Set();
188
+ for (const value of data as Set<any>) {
189
+ // Set values need deep cloning
190
+ newSet.add(deepClone(value,opts));
191
+ }
192
+ newData = newSet as T;
193
+ } else if (dataType === 'Date' && opts.cloneDate) {
194
+ newData = new Date((data as Date).getTime()) as T;
195
+ } else if (dataType === 'RegExp' && opts.cloneRegex) {
50
196
  const regex = data as RegExp;
51
- return new RegExp(regex.source, regex.flags) as T;
52
-
197
+ newData = new RegExp(regex.source, regex.flags) as T;
198
+ // } else if ((dataType.includes('HTML') && opts.cloneElement) ||
199
+ // (dataType === 'DocumentFragment' && opts.cloneFragment)
200
+ //) {
201
+ //Text,Comment,HTML*Element,DocumentFragment,Attr
202
+ // newData = (data as any).cloneNode(true) as T;
53
203
  } else {
54
- // Number, String, Boolean, Symbol,Text,Comment,Set,Map, HTML*Element, Function,Error,Promise,ArrayBuffer,Blob,File, return directly
55
- return data;
204
+ // Number, String, Boolean, Symbol, Function,Error,Promise,ArrayBuffer,Blob,File, return directly
205
+ newData = data;
206
+ cloned = false;
56
207
  }
208
+ // Callback after cloning
209
+ opts.onAfterClone?.({
210
+ output: newData,
211
+ input: data,
212
+ type: dataType,
213
+ cloned,
214
+ });
215
+ return newData;
57
216
  };
58
217
 
59
218
  export default deepClone;
@@ -0,0 +1,47 @@
1
+ /**
2
+ * @since Last modified: 2025/12/16 14:43:51
3
+ * Deep clone an array or object to a JSON-compatible structure.
4
+ * Converts non-serializable types like functions, symbols, Date, RegExp to plain values.
5
+ *
6
+ * @template T
7
+ * @param {T} data - Array or object to clone
8
+ * @returns {T} - New object with different memory address, in a JSON-compatible structure
9
+ *
10
+ * @example
11
+ * const obj = { a: '', b: 0, c: [] };
12
+ * const cloned = deepCloneToJSON(obj);
13
+ *
14
+ * @example
15
+ * const arr = [{}, {}, {}];
16
+ * const cloned = deepCloneToJSON(arr);
17
+ */
18
+ 'use strict';
19
+ import getDataType from './getDataType';
20
+ const deepCloneToJSON = (data) => {
21
+ const dataType = getDataType(data);
22
+ // Handle objects
23
+ if (dataType === 'Object') {
24
+ const newObj = {};
25
+ // Clone regular properties
26
+ for (const key in data) {
27
+ newObj[key] = deepCloneToJSON(data[key]);
28
+ }
29
+ for (const key in newObj) {
30
+ newObj[key] === undefined && Reflect.deleteProperty(newObj, key);
31
+ }
32
+ return newObj;
33
+ // Handle arrays
34
+ }
35
+ else if (dataType === 'Array') {
36
+ let tmp = data.map((item, index) => deepCloneToJSON(item)).filter(item => item !== undefined);
37
+ return tmp;
38
+ // Handle Date objects
39
+ }
40
+ else if (!['Number', 'String', 'Boolean', 'Null'].includes(dataType)) {
41
+ return undefined;
42
+ }
43
+ else {
44
+ return data;
45
+ }
46
+ };
47
+ export default deepCloneToJSON;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @since Last modified: 2025/12/22 14:29:27
3
+ * Generates a unique identifier string
4
+ *
5
+ * The ID format is: `[prefix_]timestamp_randomBase36_extraRandom`
6
+ * Example outputs:
7
+ * - "1734597601234_abc123def4567"
8
+ * - "snax_1734597601235_ghi789jkl0123_8899"
9
+ *
10
+ * Features:
11
+ * 1. Millisecond timestamp ensures uniqueness across time
12
+ * 2. Base-36 random string (9 chars = ~3.5e13 possibilities)
13
+ * 3. Additional 4-digit random number for extra entropy
14
+ * 4. Optional prefix for categorization
15
+ *
16
+ * @param options.prefix - Optional prefix string for the ID (e.g., 'snax', 'user', 'doc')
17
+ * @param options.suffix - Optional suffix string for the ID (e.g., 'snax', 'user', 'doc')
18
+ * @param options.base10 - Optional 4-digit random number
19
+ * @param options.base36 - Optional 9-digit random charactor
20
+ * @returns A unique identifier string
21
+ */
22
+ export const getUniqueId = (options = {}) => {
23
+ const prefix = options.prefix, suffix = options.suffix, base10 = options.base10, base36 = options.base36;
24
+ // Current timestamp in milliseconds (since Unix epoch)
25
+ // This provides the primary uniqueness guarantee
26
+ const timestamp = Date.now(),
27
+ // Generate a base-36 random string (0-9, a-z)
28
+ // Math.random() returns a number in [0, 1), converting to base-36 gives a compact representation
29
+ // substring(2, 11) extracts 9 characters starting from index 2
30
+ //0.259854635->0.9crs03e8v2
31
+ base36Random = base36 ? '-' + Math.random().toString(36).substring(2, 11) : '',
32
+ // Additional 4-digit random number for extra randomness
33
+ // This helps avoid collisions in high-frequency generation scenarios
34
+ base10Random = base10 ? '-' + Math.floor(Math.random() * 10000).toString().padStart(4, '0') : '', prefixString = prefix ? prefix + '-' : '', suffixString = suffix ? '-' + suffix : '';
35
+ // Construct the final ID string
36
+ // Format: [prefix_]timestamp_randomBase36_extraRandom
37
+ return `${prefixString}${timestamp}${base36Random}${base10Random}${suffixString}`;
38
+ };
39
+ export default getUniqueId;
@@ -0,0 +1,47 @@
1
+ /**
2
+ * @since Last modified: 2025/12/22 14:29:27
3
+ * Generates a unique identifier string
4
+ *
5
+ * The ID format is: `[prefix_]timestamp_randomBase36_extraRandom`
6
+ * Example outputs:
7
+ * - "1734597601234_abc123def4567"
8
+ * - "snax_1734597601235_ghi789jkl0123_8899"
9
+ *
10
+ * Features:
11
+ * 1. Millisecond timestamp ensures uniqueness across time
12
+ * 2. Base-36 random string (9 chars = ~3.5e13 possibilities)
13
+ * 3. Additional 4-digit random number for extra entropy
14
+ * 4. Optional prefix for categorization
15
+ *
16
+ * @param options.prefix - Optional prefix string for the ID (e.g., 'snax', 'user', 'doc')
17
+ * @param options.suffix - Optional suffix string for the ID (e.g., 'snax', 'user', 'doc')
18
+ * @param options.base10 - Optional 4-digit random number
19
+ * @param options.base36 - Optional 9-digit random charactor
20
+ * @returns A unique identifier string
21
+ */
22
+ export const getUniqueId = (options: { prefix?: string, suffix?: string, base10?: boolean,base36?: boolean } = {}): string => {
23
+ const prefix = options.prefix,
24
+ suffix = options.suffix,
25
+ base10 = options.base10,
26
+ base36 = options.base36;
27
+ // Current timestamp in milliseconds (since Unix epoch)
28
+ // This provides the primary uniqueness guarantee
29
+ const timestamp = Date.now(),
30
+
31
+ // Generate a base-36 random string (0-9, a-z)
32
+ // Math.random() returns a number in [0, 1), converting to base-36 gives a compact representation
33
+ // substring(2, 11) extracts 9 characters starting from index 2
34
+ //0.259854635->0.9crs03e8v2
35
+ base36Random = base36?'-' +Math.random().toString(36).substring(2, 11):'',
36
+ // Additional 4-digit random number for extra randomness
37
+ // This helps avoid collisions in high-frequency generation scenarios
38
+ base10Random = base10 ? '-' + Math.floor(Math.random() * 10000).toString().padStart(4, '0') : '',
39
+ prefixString = prefix ? prefix + '-' : '',
40
+ suffixString = suffix ? '-' + suffix : '';
41
+
42
+ // Construct the final ID string
43
+ // Format: [prefix_]timestamp_randomBase36_extraRandom
44
+ return `${prefixString}${timestamp}${base36Random}${base10Random}${suffixString}`;
45
+ };
46
+
47
+ export default getUniqueId;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Available Map mutation methods
3
+ */
4
+ export const mapMutableMethods = ['set', 'delete', 'clear'];
5
+ export default mapMutableMethods;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @since Last modified: 2025/12/22 17:16:39
3
+ *
4
+ */
5
+ /**
6
+ * Available mutation methods for Map objects
7
+ */
8
+ export type MapMutationNames = 'set' | 'delete' | 'clear';
9
+
10
+ /**
11
+ * Available Map mutation methods
12
+ */
13
+ export const mapMutableMethods: MapMutationNames[] = ['set', 'delete', 'clear'];
14
+
15
+ export default mapMutableMethods;
@@ -1,5 +1,5 @@
1
- const mutableMethods = [
1
+ const arrayMutableMethods = [
2
2
  'push', 'pop', 'shift', 'unshift', 'splice',
3
3
  'sort', 'reverse', 'copyWithin', 'fill'
4
4
  ];
5
- export default mutableMethods;
5
+ export default arrayMutableMethods;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Available Set mutation methods
3
+ */
4
+ export const setMutableMethods = ['add', 'delete', 'clear'];
5
+ export default setMutableMethods;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Available Set mutation methods
3
+ */
4
+ export const setMutableMethods = ['add', 'delete', 'clear'];
5
+ export default setMutableMethods;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @since Last modified: 2025/12/22 17:15:21
3
+ *
4
+ */
5
+ /**
6
+ * Available mutation methods for Set objects
7
+ */
8
+ export type SetMutationNames = 'add' | 'delete' | 'clear';
9
+ /**
10
+ * Available Set mutation methods
11
+ */
12
+ export const setMutableMethods: SetMutationNames[] = ['add', 'delete', 'clear'];
13
+
14
+ export default setMutableMethods;