@codady/utils 0.0.39 → 0.0.40
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/CHANGELOG.md +21 -2
- package/dist/utils.cjs.js +110 -7
- package/dist/utils.cjs.min.js +3 -3
- package/dist/utils.esm.js +110 -7
- package/dist/utils.esm.min.js +3 -3
- package/dist/utils.umd.js +110 -7
- package/dist/utils.umd.min.js +3 -3
- package/dist.zip +0 -0
- package/examples/ajax-download.html +94 -0
- package/examples/ajax-hook.html +2 -2
- package/examples/ajax-signal.html +91 -0
- package/examples/ajax-timeout.html +85 -0
- package/examples/stringToEncodings-collision-test-registry.html +117 -0
- package/examples/stringToEncodings-collision-test.html +71 -0
- package/examples/stringToEncodings.html +138 -0
- package/examples/unicodeToEncodings.html +195 -0
- package/modules.js +5 -1
- package/modules.ts +5 -1
- package/package.json +1 -1
- package/src/ajax.js +23 -6
- package/src/ajax.ts +30 -10
- package/src/stringToEncodings.js +56 -0
- package/src/stringToEncodings.ts +110 -0
- package/src/unicodeToEncodings.js +51 -0
- package/src/unicodeToEncodings.ts +55 -0
- package/src/arrayMutableMethods - /345/211/257/346/234/254.js" +0 -5
- package/src/capitalize - /345/211/257/346/234/254.js" +0 -19
- package/src/comma - /345/211/257/346/234/254.js" +0 -2
- package/src/deepCloneToJSON - /345/211/257/346/234/254.js" +0 -47
- package/src/deepMergeMaps - /345/211/257/346/234/254.js" +0 -78
- package/src/escapeHTML - /345/211/257/346/234/254.js" +0 -29
- package/src/getDataType - /345/211/257/346/234/254.js" +0 -38
- package/src/isEmpty - /345/211/257/346/234/254.js" +0 -45
- package/src/mapMutableMethods - /345/211/257/346/234/254.js" +0 -5
- package/src/setMutableMethods - /345/211/257/346/234/254.js" +0 -5
- package/src/wrapMap - /345/211/257/346/234/254.js" +0 -119
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @since Last modified: 2025/12/24 17:05:22
|
|
3
|
-
* @function deepMergeMaps
|
|
4
|
-
* Deeply merges two Maps, with flexible options to replace, concatenate, or merge entries.
|
|
5
|
-
* @param target The target Map to merge into
|
|
6
|
-
* @param source The source Map to merge from
|
|
7
|
-
* @param options Configuration options for merging
|
|
8
|
-
* @returns The deeply merged Map
|
|
9
|
-
*/
|
|
10
|
-
'use strict';
|
|
11
|
-
import getDataType from './getDataType';
|
|
12
|
-
import deepMergeObjects from './deepMergeObjects';
|
|
13
|
-
import deepMergeArrays from './deepMergeArrays';
|
|
14
|
-
import deepMergeSets from './deepMergeSets';
|
|
15
|
-
const deepMergeMaps = (target, source, options = { itemMode: 'merge', propAppend: true, targetClone: false, useEnable: true }) => {
|
|
16
|
-
// Ensure both target and source are Maps
|
|
17
|
-
if (!(target instanceof Map) || !(source instanceof Map))
|
|
18
|
-
return target;
|
|
19
|
-
// Merge options, with default values
|
|
20
|
-
const opts = Object.assign({ itemMode: 'merge', propAppend: true, targetClone: false, useEnable: true }, options),
|
|
21
|
-
// If cloning is enabled, create a deep copy of the target Map
|
|
22
|
-
result = opts.targetClone ? new Map(target) : target;
|
|
23
|
-
// Handle different merge strategies based on itemMode
|
|
24
|
-
if (opts.itemMode === 'replace') {
|
|
25
|
-
// Replace mode: clear the target Map and add all entries from the source Map
|
|
26
|
-
result.clear();
|
|
27
|
-
source.forEach((value, key) => result.set(key, value));
|
|
28
|
-
return result;
|
|
29
|
-
}
|
|
30
|
-
else if (opts.itemMode === 'concat') {
|
|
31
|
-
// Concatenate mode: add all entries from the source Map to the target Map
|
|
32
|
-
source.forEach((value, key) => result.set(key, value));
|
|
33
|
-
return result;
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
// Default "merge" mode: recursively merge entries in the Maps
|
|
37
|
-
source.forEach((value, key) => {
|
|
38
|
-
// Check if the key already exists in the target Map
|
|
39
|
-
if (result.has(key)) {
|
|
40
|
-
const targetValue = result.get(key), sourceValue = value;
|
|
41
|
-
const targetType = getDataType(targetValue), sourceType = getDataType(sourceValue);
|
|
42
|
-
// If both target and source values are of the same type, merge them
|
|
43
|
-
if (targetType === sourceType) {
|
|
44
|
-
if (targetType === 'Object') {
|
|
45
|
-
// If both target and source are objects, merge them recursively
|
|
46
|
-
result.set(key, deepMergeObjects(targetValue, sourceValue, opts));
|
|
47
|
-
}
|
|
48
|
-
else if (targetType === 'Array') {
|
|
49
|
-
// If both target and source are arrays, merge them recursively
|
|
50
|
-
deepMergeArrays(targetValue, sourceValue, opts);
|
|
51
|
-
}
|
|
52
|
-
else if (targetType === 'Map') {
|
|
53
|
-
// If both target and source are Maps, merge them recursively
|
|
54
|
-
deepMergeMaps(targetValue, sourceValue, opts);
|
|
55
|
-
}
|
|
56
|
-
else if (targetType === 'Set') {
|
|
57
|
-
// If both target and source are Sets, merge them recursively
|
|
58
|
-
deepMergeSets(targetValue, sourceValue, opts);
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
// For simple values, overwrite the target value with the source value
|
|
62
|
-
result.set(key, sourceValue);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
// If types don't match, overwrite the target value with the source value
|
|
67
|
-
result.set(key, sourceValue);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
// If the key doesn't exist in the target, add the entry from the source Map
|
|
72
|
-
result.set(key, value);
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
return result;
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
export default deepMergeMaps;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @function escapeHTML
|
|
3
|
-
* @description Escapes HTML characters in a string to prevent XSS attacks.
|
|
4
|
-
* This function replaces special characters such as <, >, &, ", ', etc. with their corresponding HTML entities.
|
|
5
|
-
*
|
|
6
|
-
* @param {string} str - The input string to be escaped.
|
|
7
|
-
* @returns {string} - The escaped string with special HTML characters replaced by HTML entities.
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* escapeHTML("<div>Hello & 'world'</div>");
|
|
11
|
-
* // returns "<div>Hello & 'world'</div>"
|
|
12
|
-
*/
|
|
13
|
-
export const escapeHTML = (str) => {
|
|
14
|
-
// Mapping of HTML special characters to their corresponding HTML entities
|
|
15
|
-
const escapes = {
|
|
16
|
-
'&': '&',
|
|
17
|
-
'<': '<',
|
|
18
|
-
'>': '>',
|
|
19
|
-
'"': '"',
|
|
20
|
-
"'": ''',
|
|
21
|
-
'`': '`',
|
|
22
|
-
'=': '=',
|
|
23
|
-
'/': '/'
|
|
24
|
-
};
|
|
25
|
-
// Replace each special character in the input string with its corresponding HTML entity
|
|
26
|
-
return str.replace(/[&<>"'`=\/]/g, (match) => {
|
|
27
|
-
return escapes[match];
|
|
28
|
-
});
|
|
29
|
-
};
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @since Last modified: 2025/12/16 09:00:41
|
|
3
|
-
* @function getDataType
|
|
4
|
-
* @description Get object type.Can detect object types such as Array, Object, Function,
|
|
5
|
-
* Window,Location,History,Navigator,XMLHttpRequest, WebSocket,FileReader,MediaStream
|
|
6
|
-
* Class , String, Number, Boolean, Date, Symbol ,File ,Blob,
|
|
7
|
-
* Error,Promise,ArrayBuffer,TypedArray, Set, weakSet, Map, weakMap, Null, Undefined,
|
|
8
|
-
* Text, DocumentFragment,Comment, XMLDocument, ProcessingInstruction, Range, TreeWalker,
|
|
9
|
-
* NodeIterator,SVGSVGElement,MathMLElement, HTMLxxxElement (Dom nodes all contain HTML),Promise,AsyncFunction and Instance.
|
|
10
|
-
* @param {*} obj - Can be any object
|
|
11
|
-
* @returns {string} - Returns the name of the data type.
|
|
12
|
-
*/
|
|
13
|
-
'use strict';
|
|
14
|
-
const getDataType = (obj) => {
|
|
15
|
-
let tmp = Object.prototype.toString.call(obj).slice(8, -1), result;
|
|
16
|
-
if (tmp === 'Function' && /^\s*class\s+/.test(obj.toString())) {
|
|
17
|
-
result = 'Class';
|
|
18
|
-
}
|
|
19
|
-
else if (tmp === 'Object' && Object.getPrototypeOf(obj) !== Object.prototype) {
|
|
20
|
-
result = 'Instance';
|
|
21
|
-
}
|
|
22
|
-
else {
|
|
23
|
-
result = tmp;
|
|
24
|
-
}
|
|
25
|
-
return result;
|
|
26
|
-
//document.createElement -> HTMLxxxElement
|
|
27
|
-
//document.createDocumentFragment() -> DocumentFragment
|
|
28
|
-
//document.createComment() -> Comment
|
|
29
|
-
//document.createTextNode -> Text
|
|
30
|
-
//document.createCDATASection() -> XMLDocument
|
|
31
|
-
//document.createProcessingInstruction() -> ProcessingInstruction
|
|
32
|
-
//document.createRange() -> Range
|
|
33
|
-
//document.createTreeWalker() -> TreeWalker
|
|
34
|
-
//document.createNodeIterator() -> NodeIterator
|
|
35
|
-
//document.createElementNS('http://www.w3.org/2000/svg', 'svg'); -> SVGSVGElement
|
|
36
|
-
//document.createElementNS('http://www.w3.org/1998/Math/MathML', 'math'); -> MathMLElement
|
|
37
|
-
};
|
|
38
|
-
export default getDataType;
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @since Last modified: 2025/12/25 14:22:26
|
|
3
|
-
* @function isEmpty
|
|
4
|
-
* @description Determine whether it is empty data.The data itself is empty data: 0| ''|false|undefined|null; <br>empty function: function () {}|() => {}; <br>empty array and empty objects: []|{}| [null]| [ undefined]| ['']| [""];<br> empty symbol object: symbol()|symbol.For(), will be judged as empty.
|
|
5
|
-
* @param {*} data - Can be any data
|
|
6
|
-
* @returns {boolean} - Return true or false
|
|
7
|
-
* @example
|
|
8
|
-
* ax.isEmpty([null]);
|
|
9
|
-
* <!--return true-->
|
|
10
|
-
*/
|
|
11
|
-
//简介:判断是否为空数据。本身为空的数据:0|''|false|undefined|null;空函数:function(){}|()=>{};空数组和空对象:[]|{}|[null]|[undefined]|['']|[""];空Symbol对象:Symbol()|Symbol.for(),都将判断为空。
|
|
12
|
-
//返回:true或false
|
|
13
|
-
'use strict';
|
|
14
|
-
import getDataType from './getDataType';
|
|
15
|
-
const isEmpty = (data) => {
|
|
16
|
-
let type = getDataType(data), flag;
|
|
17
|
-
if (!data) {
|
|
18
|
-
//0,'',false,undefined,null
|
|
19
|
-
flag = true;
|
|
20
|
-
}
|
|
21
|
-
else {
|
|
22
|
-
//function(){}|()=>{}
|
|
23
|
-
//[null]|[undefined]|['']|[""]
|
|
24
|
-
//[]|{}
|
|
25
|
-
//Symbol()|Symbol.for()
|
|
26
|
-
//Set,Map
|
|
27
|
-
//Date/Regex
|
|
28
|
-
flag = (type === 'Object') ? (Object.keys(data).length === 0) :
|
|
29
|
-
(type === 'Array') ? data.join('') === '' :
|
|
30
|
-
(type === 'Function') ? (data.toString().replace(/\s+/g, '').match(/{.*}/g)[0] === '{}') :
|
|
31
|
-
(type === 'Symbol') ? (data.toString().replace(/\s+/g, '').match(/\(.*\)/g)[0] === '()') :
|
|
32
|
-
(type === 'Set' || type === 'Map') ? data.size === 0 :
|
|
33
|
-
type === 'Date' ? isNaN(data.getTime()) :
|
|
34
|
-
type === 'RegExp' ? data.source === '' :
|
|
35
|
-
type === 'ArrayBuffer' ? data.byteLength === 0 :
|
|
36
|
-
(type === 'NodeList' || type === 'HTMLCollection') ? data.length === 0 :
|
|
37
|
-
('length' in data && typeof data.length === 'number') ? data.length === 0 :
|
|
38
|
-
('size' in data && typeof data.size === 'number') ? data.size === 0 :
|
|
39
|
-
(type === 'Error' || data instanceof Error) ? data.message === '' :
|
|
40
|
-
(type.includes('Array') && (['Uint8Array', 'Int8Array', 'Uint16Array', 'Int16Array', 'Uint32Array', 'Int32Array', 'Float32Array', 'Float64Array'].includes(type))) ? data.length === 0 :
|
|
41
|
-
false;
|
|
42
|
-
}
|
|
43
|
-
return flag;
|
|
44
|
-
};
|
|
45
|
-
export default isEmpty;
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @since Last modified: 2025/12/22 16:37:23
|
|
3
|
-
* Wraps Map objects with mutation tracking capabilities.
|
|
4
|
-
* Provides hooks for before/after mutation events and captures detailed context
|
|
5
|
-
* for undo/redo or change tracking purposes.
|
|
6
|
-
*
|
|
7
|
-
* @template K - Map key type
|
|
8
|
-
* @template V - Map value type
|
|
9
|
-
* @param {MapMutationOptions<K, V>} options - Configuration object containing target Map and callbacks
|
|
10
|
-
* @returns {MapMutationMethods<K, V>} - Object containing wrapped Map mutation methods
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* // Basic usage with tracking
|
|
14
|
-
* const map = new Map([['key1', 'value1']]);
|
|
15
|
-
* const methods = wrapMap({
|
|
16
|
-
* target: map,
|
|
17
|
-
* onAfterMutate: (patch) => {
|
|
18
|
-
* console.log(`Map ${patch.method} called`, patch.context);
|
|
19
|
-
* }
|
|
20
|
-
* });
|
|
21
|
-
*
|
|
22
|
-
* methods.set('key2', 'value2'); // Tracked
|
|
23
|
-
* methods.delete('key1'); // Tracked
|
|
24
|
-
* methods.clear(); // Tracked
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* // With undo/redo support
|
|
28
|
-
* const history: MapMutationPatch<any, any>[] = [];
|
|
29
|
-
* const map = new Map<string, number>();
|
|
30
|
-
*
|
|
31
|
-
* const methods = wrapMap({
|
|
32
|
-
* target: map,
|
|
33
|
-
* onBeforeMutate: (context) => {
|
|
34
|
-
* console.log('Before mutation:', context);
|
|
35
|
-
* },
|
|
36
|
-
* onAfterMutate: (patch) => {
|
|
37
|
-
* history.push(patch);
|
|
38
|
-
* console.log('Mutation recorded:', patch.method, 'History size:', history.length);
|
|
39
|
-
* }
|
|
40
|
-
* });
|
|
41
|
-
*/
|
|
42
|
-
'use strict';
|
|
43
|
-
/**
|
|
44
|
-
* Available Map mutation methods
|
|
45
|
-
*/
|
|
46
|
-
export const mapMutableMethods = ['set', 'delete', 'clear'];
|
|
47
|
-
/**
|
|
48
|
-
* Creates wrapped mutation methods for Map with tracking capabilities
|
|
49
|
-
*
|
|
50
|
-
* @param options Configuration options
|
|
51
|
-
* @returns Object containing wrapped Map mutation methods
|
|
52
|
-
* @throws TypeError if target is not a Map
|
|
53
|
-
*/
|
|
54
|
-
const wrapMap = ({ target, onBeforeMutate = () => { }, onAfterMutate = () => { }, allowList = mapMutableMethods, props = {}, }) => {
|
|
55
|
-
// Validation: Ensure target is a Map
|
|
56
|
-
if (!(target instanceof Map)) {
|
|
57
|
-
throw new TypeError("The 'target' parameter must be a Map.");
|
|
58
|
-
}
|
|
59
|
-
// Create method wrappers
|
|
60
|
-
const methods = {};
|
|
61
|
-
// Helper to create wrapped method
|
|
62
|
-
const createWrappedMethod = (method) => {
|
|
63
|
-
return function (...args) {
|
|
64
|
-
const context = {};
|
|
65
|
-
// Capture pre-mutation context based on method
|
|
66
|
-
switch (method) {
|
|
67
|
-
case 'set': {
|
|
68
|
-
const [key, newValue] = args;
|
|
69
|
-
context.key = key;
|
|
70
|
-
context.newValue = newValue;
|
|
71
|
-
context.hadKey = target.has(key);
|
|
72
|
-
context.oldValue = context.hadKey ? target.get(key) : undefined;
|
|
73
|
-
break;
|
|
74
|
-
}
|
|
75
|
-
case 'delete': {
|
|
76
|
-
const [key] = args;
|
|
77
|
-
context.key = key;
|
|
78
|
-
context.existed = target.has(key);
|
|
79
|
-
break;
|
|
80
|
-
}
|
|
81
|
-
case 'clear': {
|
|
82
|
-
context.clearedEntries = Array.from(target.entries());
|
|
83
|
-
context.previousSize = target.size;
|
|
84
|
-
break;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
// Execute before mutation callback
|
|
88
|
-
onBeforeMutate(context);
|
|
89
|
-
// Execute the native Map method
|
|
90
|
-
const result = target[method].apply(target, args);
|
|
91
|
-
// Construct patch object
|
|
92
|
-
const patch = {
|
|
93
|
-
method,
|
|
94
|
-
result,
|
|
95
|
-
args,
|
|
96
|
-
context,
|
|
97
|
-
target,
|
|
98
|
-
...props
|
|
99
|
-
};
|
|
100
|
-
// Execute after mutation callback
|
|
101
|
-
onAfterMutate(patch);
|
|
102
|
-
return result;
|
|
103
|
-
};
|
|
104
|
-
};
|
|
105
|
-
// Wrap allowed methods
|
|
106
|
-
for (const method of allowList) {
|
|
107
|
-
if (mapMutableMethods.includes(method)) {
|
|
108
|
-
methods[method] = createWrappedMethod(method);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
// Add target reference
|
|
112
|
-
Object.defineProperty(methods, 'target', {
|
|
113
|
-
get: () => target,
|
|
114
|
-
enumerable: false,
|
|
115
|
-
configurable: false
|
|
116
|
-
});
|
|
117
|
-
return methods;
|
|
118
|
-
};
|
|
119
|
-
export default wrapMap;
|