@codady/utils 0.0.38 → 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 +37 -0
- package/dist/utils.cjs.js +576 -24
- package/dist/utils.cjs.min.js +3 -3
- package/dist/utils.esm.js +576 -24
- package/dist/utils.esm.min.js +3 -3
- package/dist/utils.umd.js +576 -24
- package/dist/utils.umd.min.js +3 -3
- package/dist.zip +0 -0
- package/examples/ajax-download.html +94 -0
- package/examples/ajax-get.html +59 -0
- package/examples/ajax-hook.html +55 -0
- package/examples/ajax-method.html +36 -0
- package/examples/ajax-post.html +37 -0
- package/examples/ajax-signal.html +91 -0
- package/examples/ajax-timeout.html +85 -0
- package/examples/buildUrl.html +99 -0
- package/examples/getUrlHash.html +71 -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 +17 -1
- package/modules.ts +17 -1
- package/package.json +1 -1
- package/src/ajax.js +380 -0
- package/src/ajax.ts +470 -0
- package/src/buildUrl.js +64 -0
- package/src/buildUrl.ts +86 -0
- package/src/capitalize.js +19 -0
- package/src/capitalize.ts +20 -0
- package/src/cleanQueryString.js +19 -0
- package/src/cleanQueryString.ts +20 -0
- package/src/getBodyHTML.js +53 -0
- package/src/getBodyHTML.ts +61 -0
- package/src/getEl.js +1 -1
- package/src/getEl.ts +6 -5
- package/src/getEls.js +1 -1
- package/src/getEls.ts +5 -5
- package/src/getUrlHash.js +37 -0
- package/src/getUrlHash.ts +39 -0
- package/src/isEmpty.js +24 -23
- package/src/isEmpty.ts +26 -23
- package/src/sliceStrEnd.js +63 -0
- package/src/sliceStrEnd.ts +60 -0
- 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/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
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2026/02/05 15:12:33
|
|
3
|
+
* Generate a stable Unicode code point from a string.
|
|
4
|
+
* - Without registry: FNV-1a 64-bit hash mapping (fast, stateless)
|
|
5
|
+
* - With registry: Guaranteed zero-collision allocation
|
|
6
|
+
*/
|
|
7
|
+
export type StringEncodingResult = {
|
|
8
|
+
unicode: string;
|
|
9
|
+
htmlDec: string;
|
|
10
|
+
htmlHex: string;
|
|
11
|
+
hex: string;
|
|
12
|
+
codePoint: number;
|
|
13
|
+
hash: string;
|
|
14
|
+
name: string;
|
|
15
|
+
collision?: boolean;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type StringEncodingOptions = {
|
|
19
|
+
start?: number;
|
|
20
|
+
end?: number;
|
|
21
|
+
registryMap?: Map<string, number>; // optional
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
const stringToEncodings = (
|
|
26
|
+
name: string,
|
|
27
|
+
options: StringEncodingOptions = {}
|
|
28
|
+
): StringEncodingResult => {
|
|
29
|
+
|
|
30
|
+
// Default: Supplementary Private Use Area (Plane 15 and Plane 16)
|
|
31
|
+
//1,114,110 places,5000 strings => 0 collision
|
|
32
|
+
const start = options.start ?? 0xF0000,
|
|
33
|
+
end = options.end ?? 0x10FFFD,
|
|
34
|
+
range = BigInt(end - start + 1),
|
|
35
|
+
registry = options.registryMap,
|
|
36
|
+
/** Format result */
|
|
37
|
+
formatResult = (
|
|
38
|
+
name: string,
|
|
39
|
+
codePoint: number,
|
|
40
|
+
hash: string,
|
|
41
|
+
collision: boolean
|
|
42
|
+
): StringEncodingResult => {
|
|
43
|
+
const hex = codePoint.toString(16).toUpperCase();
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
name,
|
|
47
|
+
unicode: `U+${hex}`,
|
|
48
|
+
htmlDec: `&#${codePoint};`,
|
|
49
|
+
htmlHex: `&#x${hex};`,
|
|
50
|
+
hex,
|
|
51
|
+
codePoint,
|
|
52
|
+
hash,
|
|
53
|
+
collision,
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
// -----------------------------
|
|
59
|
+
// 1. Compute FNV-1a 64-bit hash
|
|
60
|
+
// -----------------------------
|
|
61
|
+
let hash = BigInt("0xcbf29ce484222325");
|
|
62
|
+
const prime = BigInt("0x100000001b3");
|
|
63
|
+
|
|
64
|
+
for (const ch of name) {
|
|
65
|
+
hash ^= BigInt(ch.codePointAt(0)!);
|
|
66
|
+
hash *= prime;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const hashHex = hash.toString(16).toUpperCase();
|
|
70
|
+
|
|
71
|
+
// -----------------------------
|
|
72
|
+
// 2. Stateless mode (no registry)
|
|
73
|
+
// -----------------------------
|
|
74
|
+
if (!registry) {
|
|
75
|
+
const offset = Number(hash % range),
|
|
76
|
+
codePoint = start + offset;
|
|
77
|
+
return formatResult(name, codePoint, hashHex, false);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// -----------------------------
|
|
81
|
+
// 3. Registry mode (0 collision)
|
|
82
|
+
// -----------------------------
|
|
83
|
+
|
|
84
|
+
// Already assigned → return stable mapping
|
|
85
|
+
if (registry.has(name)) {
|
|
86
|
+
return formatResult(name, registry.get(name)!, hashHex, false);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Initial candidate from hash
|
|
90
|
+
let offset = Number(hash % range),
|
|
91
|
+
codePoint = start + offset,
|
|
92
|
+
collision = false;
|
|
93
|
+
|
|
94
|
+
const used = new Set(registry.values());
|
|
95
|
+
|
|
96
|
+
// Linear probing to resolve collisions
|
|
97
|
+
while (used.has(codePoint)) {
|
|
98
|
+
collision = true;
|
|
99
|
+
offset = (offset + 1) % Number(range);
|
|
100
|
+
codePoint = start + offset;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Commit allocation
|
|
104
|
+
registry.set(name, codePoint);
|
|
105
|
+
|
|
106
|
+
return formatResult(name, codePoint, hashHex, collision);
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
export default stringToEncodings;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2026/02/05 17:06:59
|
|
3
|
+
* Parses a Unicode input (string or number) and converts it into
|
|
4
|
+
* multiple encoding formats including Unicode notation, HTML entities,
|
|
5
|
+
* hexadecimal code, and decimal code point.
|
|
6
|
+
*
|
|
7
|
+
* Supported input formats:
|
|
8
|
+
* - Unicode string: "U+F123"
|
|
9
|
+
* - Hex string: "F123", "0xF123"
|
|
10
|
+
* - Decimal string: "61731"
|
|
11
|
+
* - Numeric code point: 61731
|
|
12
|
+
*
|
|
13
|
+
* This utility is useful for:
|
|
14
|
+
* - Icon font Unicode decoding
|
|
15
|
+
* - HTML entity generation
|
|
16
|
+
* - Unicode debugging and inspection
|
|
17
|
+
* - Glyph mapping and font tooling
|
|
18
|
+
* - PUA (Private Use Area) management workflows
|
|
19
|
+
*
|
|
20
|
+
* @param input - Unicode input as a string or numeric code point
|
|
21
|
+
* @returns An object containing Unicode, hex, decimal, and HTML encodings
|
|
22
|
+
* @throws Error if the input cannot be parsed into a valid Unicode code point
|
|
23
|
+
*/
|
|
24
|
+
const unicodeToEncodings = (input) => {
|
|
25
|
+
let codePoint;
|
|
26
|
+
if (typeof input === "number") {
|
|
27
|
+
codePoint = input;
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
const cleaned = input.trim()
|
|
31
|
+
.replace(/^U\+/i, "")
|
|
32
|
+
.replace(/^0x/i, "");
|
|
33
|
+
codePoint = /^[0-9A-F]+$/i.test(cleaned)
|
|
34
|
+
? parseInt(cleaned, 16)
|
|
35
|
+
: parseInt(cleaned, 10);
|
|
36
|
+
}
|
|
37
|
+
// Validate parsed code point
|
|
38
|
+
if (!Number.isFinite(codePoint)) {
|
|
39
|
+
throw new Error("Invalid Unicode input");
|
|
40
|
+
}
|
|
41
|
+
// Convert code point to uppercase hexadecimal representation
|
|
42
|
+
const hex = codePoint.toString(16).toUpperCase();
|
|
43
|
+
return {
|
|
44
|
+
unicode: `U+${hex}`,
|
|
45
|
+
hex,
|
|
46
|
+
codePoint,
|
|
47
|
+
htmlDec: `&#${codePoint};`,
|
|
48
|
+
htmlHex: `&#x${hex};`,
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
export default unicodeToEncodings;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2026/02/05 17:06:59
|
|
3
|
+
* Parses a Unicode input (string or number) and converts it into
|
|
4
|
+
* multiple encoding formats including Unicode notation, HTML entities,
|
|
5
|
+
* hexadecimal code, and decimal code point.
|
|
6
|
+
*
|
|
7
|
+
* Supported input formats:
|
|
8
|
+
* - Unicode string: "U+F123"
|
|
9
|
+
* - Hex string: "F123", "0xF123"
|
|
10
|
+
* - Decimal string: "61731"
|
|
11
|
+
* - Numeric code point: 61731
|
|
12
|
+
*
|
|
13
|
+
* This utility is useful for:
|
|
14
|
+
* - Icon font Unicode decoding
|
|
15
|
+
* - HTML entity generation
|
|
16
|
+
* - Unicode debugging and inspection
|
|
17
|
+
* - Glyph mapping and font tooling
|
|
18
|
+
* - PUA (Private Use Area) management workflows
|
|
19
|
+
*
|
|
20
|
+
* @param input - Unicode input as a string or numeric code point
|
|
21
|
+
* @returns An object containing Unicode, hex, decimal, and HTML encodings
|
|
22
|
+
* @throws Error if the input cannot be parsed into a valid Unicode code point
|
|
23
|
+
*/
|
|
24
|
+
const unicodeToEncodings = (input: string | number) => {
|
|
25
|
+
let codePoint: number;
|
|
26
|
+
|
|
27
|
+
if (typeof input === "number") {
|
|
28
|
+
codePoint = input;
|
|
29
|
+
} else {
|
|
30
|
+
const cleaned = input.trim()
|
|
31
|
+
.replace(/^U\+/i, "")
|
|
32
|
+
.replace(/^0x/i, "");
|
|
33
|
+
|
|
34
|
+
codePoint = /^[0-9A-F]+$/i.test(cleaned)
|
|
35
|
+
? parseInt(cleaned, 16)
|
|
36
|
+
: parseInt(cleaned, 10);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Validate parsed code point
|
|
40
|
+
if (!Number.isFinite(codePoint)) {
|
|
41
|
+
throw new Error("Invalid Unicode input");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Convert code point to uppercase hexadecimal representation
|
|
45
|
+
const hex = codePoint.toString(16).toUpperCase();
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
unicode: `U+${hex}`,
|
|
49
|
+
hex,
|
|
50
|
+
codePoint,
|
|
51
|
+
htmlDec: `&#${codePoint};`,
|
|
52
|
+
htmlHex: `&#x${hex};`,
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
export default unicodeToEncodings;
|
|
@@ -1,47 +0,0 @@
|
|
|
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;
|
|
@@ -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;
|