@cyberalien/svg-utils 0.0.1 → 0.0.2
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/lib/helpers/hash/css.d.ts +5 -0
- package/lib/helpers/hash/css.js +27 -0
- package/lib/helpers/hash/hash.d.ts +5 -0
- package/lib/helpers/hash/hash.js +18 -0
- package/lib/helpers/hash/unique.d.ts +5 -0
- package/lib/helpers/hash/unique.js +23 -0
- package/lib/helpers/misc/clone.d.ts +5 -0
- package/lib/helpers/misc/clone.js +8 -0
- package/lib/helpers/misc/compare.d.ts +9 -0
- package/lib/helpers/misc/compare.js +19 -0
- package/lib/helpers/misc/sort-object.d.ts +7 -0
- package/lib/helpers/misc/sort-object.js +21 -0
- package/lib/index.d.ts +5 -1
- package/lib/index.js +5 -1
- package/package.json +1 -1
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const firstChars = "abcdefghijklmnopqrstuvwxyz";
|
|
2
|
+
const chars = firstChars + "0123456789_-";
|
|
3
|
+
const firstLetterRadix = 26;
|
|
4
|
+
const letterRadix = 38;
|
|
5
|
+
/**
|
|
6
|
+
* Convert hash to a string, usable in CSS for class names and keyframes
|
|
7
|
+
*/
|
|
8
|
+
function hashToCSSString(value, limit = 8, hasPrefix = false) {
|
|
9
|
+
const result = [];
|
|
10
|
+
let num = value.shift() ?? 0;
|
|
11
|
+
if (!hasPrefix) {
|
|
12
|
+
result.push(firstChars[num % firstLetterRadix]);
|
|
13
|
+
num = Math.floor(num / firstLetterRadix);
|
|
14
|
+
}
|
|
15
|
+
while (true) {
|
|
16
|
+
while (num < 1) {
|
|
17
|
+
if (!value.length) return result.join("");
|
|
18
|
+
num = value.shift() ?? 0;
|
|
19
|
+
}
|
|
20
|
+
const isLastChar = result.length === limit - 1;
|
|
21
|
+
result.push(isLastChar ? firstChars[num % firstLetterRadix] : chars[num % letterRadix]);
|
|
22
|
+
if (result.length === limit) return result.join("");
|
|
23
|
+
num = Math.floor(num / letterRadix);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export { hashToCSSString };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple hashing function, based on https://gist.github.com/jlevy/c246006675becc446360a798e2b2d781
|
|
3
|
+
*/
|
|
4
|
+
function hashString(str, seed = 0) {
|
|
5
|
+
let h1 = 3735928559 ^ seed, h2 = 1103547991 ^ seed;
|
|
6
|
+
for (let i = 0, ch; i < str.length; i++) {
|
|
7
|
+
ch = str.charCodeAt(i);
|
|
8
|
+
h1 = Math.imul(h1 ^ ch, 2654435761);
|
|
9
|
+
h2 = Math.imul(h2 ^ ch, 1597334677);
|
|
10
|
+
}
|
|
11
|
+
h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507);
|
|
12
|
+
h1 ^= Math.imul(h2 ^ h2 >>> 13, 3266489909);
|
|
13
|
+
h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507);
|
|
14
|
+
h2 ^= Math.imul(h1 ^ h1 >>> 13, 3266489909);
|
|
15
|
+
return [h2 >>> 0, h1 >>> 0];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { hashString };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { sortObject } from "../misc/sort-object.js";
|
|
2
|
+
import { hashString } from "./hash.js";
|
|
3
|
+
import { hashToCSSString } from "./css.js";
|
|
4
|
+
|
|
5
|
+
const uniqueHashes = Object.create(null);
|
|
6
|
+
const uniqueWithPrefixHashes = Object.create(null);
|
|
7
|
+
/**
|
|
8
|
+
* Hash an object, make sure hash is unique
|
|
9
|
+
*/
|
|
10
|
+
function uniqueCSSHash(data, hasPrefix = false) {
|
|
11
|
+
const str = JSON.stringify(sortObject(data));
|
|
12
|
+
const hash = hashToCSSString(hashString(str), 6, hasPrefix);
|
|
13
|
+
const cache = hasPrefix ? uniqueWithPrefixHashes : uniqueHashes;
|
|
14
|
+
if (!cache[hash]) cache[hash] = str;
|
|
15
|
+
else if (cache[hash] !== str) {
|
|
16
|
+
console.warn("Data 1:", cache[hash]);
|
|
17
|
+
console.warn("Data 2:", str);
|
|
18
|
+
throw new Error(`Hash collision detected: ${hash}`);
|
|
19
|
+
}
|
|
20
|
+
return hash;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export { uniqueCSSHash };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compare sets, returns true if identical
|
|
3
|
+
*/
|
|
4
|
+
declare function compareSets<T>(set1: Set<T> | undefined, set2: Set<T> | undefined): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Compare two values, returns true if identical
|
|
7
|
+
*/
|
|
8
|
+
declare function compareValues<T>(value1: T, value2: T): boolean;
|
|
9
|
+
export { compareSets, compareValues };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { sortObject } from "./sort-object.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Compare sets, returns true if identical
|
|
5
|
+
*/
|
|
6
|
+
function compareSets(set1, set2) {
|
|
7
|
+
if (!set1 || !set2) return false;
|
|
8
|
+
if (set1.size !== set2.size) return false;
|
|
9
|
+
for (const value of set1) if (!set2.has(value)) return false;
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Compare two values, returns true if identical
|
|
14
|
+
*/
|
|
15
|
+
function compareValues(value1, value2) {
|
|
16
|
+
return value1 === value2 || JSON.stringify(sortObject(value1)) === JSON.stringify(sortObject(value2));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export { compareSets, compareValues };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sort object keys to generate consistend JSON output
|
|
3
|
+
*
|
|
4
|
+
* Used to hash objects
|
|
5
|
+
*/
|
|
6
|
+
function sortObject(data) {
|
|
7
|
+
if (typeof data !== "object" || data === null) return data;
|
|
8
|
+
if (Array.isArray(data)) return data.map(sortObject);
|
|
9
|
+
if (data instanceof Set) {
|
|
10
|
+
const values = Array.from(data).map(sortObject);
|
|
11
|
+
values.sort();
|
|
12
|
+
return new Set(values);
|
|
13
|
+
}
|
|
14
|
+
const keys = Object.keys(data);
|
|
15
|
+
keys.sort();
|
|
16
|
+
const newObject = Object.create(null);
|
|
17
|
+
for (const key of keys) newObject[key] = sortObject(data[key]);
|
|
18
|
+
return newObject;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { sortObject };
|
package/lib/index.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import { hashString } from "./helpers/hash/hash.js";
|
|
2
|
+
import { cloneObject } from "./helpers/misc/clone.js";
|
|
3
|
+
import { compareSets, compareValues } from "./helpers/misc/compare.js";
|
|
4
|
+
import { sortObject } from "./helpers/misc/sort-object.js";
|
|
1
5
|
import { ParsedXMLNode, ParsedXMLTagElement, ParsedXMLTextElement } from "./xml/types.js";
|
|
2
6
|
import { iterateXMLContent } from "./xml/iterate.js";
|
|
3
7
|
import { parseXMLContent } from "./xml/parse.js";
|
|
4
8
|
import { stringifyXMLContent } from "./xml/stringify.js";
|
|
5
|
-
export { ParsedXMLNode, ParsedXMLTagElement, ParsedXMLTextElement, iterateXMLContent, parseXMLContent, stringifyXMLContent };
|
|
9
|
+
export { ParsedXMLNode, ParsedXMLTagElement, ParsedXMLTextElement, cloneObject, compareSets, compareValues, hashString, iterateXMLContent, parseXMLContent, sortObject, stringifyXMLContent };
|
package/lib/index.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import { cloneObject } from "./helpers/misc/clone.js";
|
|
2
|
+
import { sortObject } from "./helpers/misc/sort-object.js";
|
|
3
|
+
import { compareSets, compareValues } from "./helpers/misc/compare.js";
|
|
4
|
+
import { hashString } from "./helpers/hash/hash.js";
|
|
1
5
|
import { iterateXMLContent } from "./xml/iterate.js";
|
|
2
6
|
import { parseXMLContent } from "./xml/parse.js";
|
|
3
7
|
import { stringifyXMLContent } from "./xml/stringify.js";
|
|
4
8
|
|
|
5
|
-
export { iterateXMLContent, parseXMLContent, stringifyXMLContent };
|
|
9
|
+
export { cloneObject, compareSets, compareValues, hashString, iterateXMLContent, parseXMLContent, sortObject, stringifyXMLContent };
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"type": "module",
|
|
4
4
|
"description": "Common functions for working with SVG used by various packages.",
|
|
5
5
|
"author": "Vjacheslav Trushkin",
|
|
6
|
-
"version": "0.0.
|
|
6
|
+
"version": "0.0.2",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"bugs": "https://github.com/cyberalien/svg-utils/issues",
|
|
9
9
|
"homepage": "https://cyberalien.dev/",
|