zss-engine 1.2.2 → 2.1.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.
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.genBase36Hash = genBase36Hash;
4
+ const util_1 = require("util");
5
+ const { asUintN } = BigInt;
4
6
  function deepNormalize(obj) {
5
7
  if (obj === null)
6
8
  return 'null';
@@ -16,65 +18,103 @@ function deepNormalize(obj) {
16
18
  const pairs = keys.map(key => `"${key}":${deepNormalize(recordObj[key])}`);
17
19
  return '{' + pairs.join(',') + '}';
18
20
  }
19
- function murmurhash3_32(str, seed) {
20
- let h = seed;
21
- const len = str.length;
22
- const c1 = 0xcc9e2d51;
23
- const c2 = 0x1b873593;
24
- const r1 = 15;
25
- const r2 = 13;
26
- const m = 5;
27
- const n = 0xe6546b64;
28
- let i = 0;
29
- while (i < len - 3) {
30
- let k = (str.charCodeAt(i) & 0xff) | ((str.charCodeAt(i + 1) & 0xff) << 8) | ((str.charCodeAt(i + 2) & 0xff) << 16) | ((str.charCodeAt(i + 3) & 0xff) << 24);
31
- k = Math.imul(k, c1);
32
- k = (k << r1) | (k >>> (32 - r1));
33
- k = Math.imul(k, c2);
34
- h ^= k;
35
- h = (h << r2) | (h >>> (32 - r2));
36
- h = Math.imul(h, m) + n;
37
- i += 4;
21
+ function rotl64(x, r) {
22
+ const shift = BigInt(r);
23
+ return asUintN(64, (x << shift) | (x >> (64n - shift)));
24
+ }
25
+ function fmix64(k) {
26
+ k ^= k >> 33n;
27
+ k = asUintN(64, k * 0xff51afd7ed558ccdn);
28
+ k ^= k >> 33n;
29
+ k = asUintN(64, k * 0xc4ceb9fe1a85ec53n);
30
+ k ^= k >> 33n;
31
+ return k;
32
+ }
33
+ function murmurhash3_x64_128(str, seed) {
34
+ let h1 = asUintN(64, BigInt(seed));
35
+ let h2 = asUintN(64, BigInt(seed));
36
+ const c1 = 0x87c37b91114253d5n;
37
+ const c2 = 0x4cf5ad432745937fn;
38
+ const encoder = new util_1.TextEncoder();
39
+ const key = encoder.encode(str);
40
+ const len = key.length;
41
+ const nblocks = Math.floor(len / 16);
42
+ const view = new DataView(key.buffer, key.byteOffset, key.byteLength);
43
+ for (let i = 0; i < nblocks; i++) {
44
+ const i16 = i * 16;
45
+ let k1 = view.getBigUint64(i16, true);
46
+ let k2 = view.getBigUint64(i16 + 8, true);
47
+ k1 = asUintN(64, k1 * c1);
48
+ k1 = rotl64(k1, 31);
49
+ k1 = asUintN(64, k1 * c2);
50
+ h1 ^= k1;
51
+ h1 = rotl64(h1, 27);
52
+ h1 = asUintN(64, h1 + h2);
53
+ h1 = asUintN(64, h1 * 5n + 0x52dce729n);
54
+ k2 = asUintN(64, k2 * c2);
55
+ k2 = rotl64(k2, 33);
56
+ k2 = asUintN(64, k2 * c1);
57
+ h2 ^= k2;
58
+ h2 = rotl64(h2, 31);
59
+ h2 = asUintN(64, h2 + h1);
60
+ h2 = asUintN(64, h2 * 5n + 0x38495ab5n);
38
61
  }
39
- let k = 0;
40
- switch (len % 4) {
62
+ const tailIndex = nblocks * 16;
63
+ let k1 = 0n;
64
+ let k2 = 0n;
65
+ switch (len & 15) {
66
+ case 15:
67
+ k2 ^= BigInt(key[tailIndex + 14]) << 48n;
68
+ case 14:
69
+ k2 ^= BigInt(key[tailIndex + 13]) << 40n;
70
+ case 13:
71
+ k2 ^= BigInt(key[tailIndex + 12]) << 32n;
72
+ case 12:
73
+ k2 ^= BigInt(key[tailIndex + 11]) << 24n;
74
+ case 11:
75
+ k2 ^= BigInt(key[tailIndex + 10]) << 16n;
76
+ case 10:
77
+ k2 ^= BigInt(key[tailIndex + 9]) << 8n;
78
+ case 9:
79
+ k2 ^= BigInt(key[tailIndex + 8]);
80
+ k2 = asUintN(64, k2 * c2);
81
+ k2 = rotl64(k2, 33);
82
+ k2 = asUintN(64, k2 * c1);
83
+ h2 ^= k2;
84
+ case 8:
85
+ k1 ^= BigInt(key[tailIndex + 7]) << 56n;
86
+ case 7:
87
+ k1 ^= BigInt(key[tailIndex + 6]) << 48n;
88
+ case 6:
89
+ k1 ^= BigInt(key[tailIndex + 5]) << 40n;
90
+ case 5:
91
+ k1 ^= BigInt(key[tailIndex + 4]) << 32n;
92
+ case 4:
93
+ k1 ^= BigInt(key[tailIndex + 3]) << 24n;
41
94
  case 3:
42
- k ^= (str.charCodeAt(i + 2) & 0xff) << 16;
95
+ k1 ^= BigInt(key[tailIndex + 2]) << 16n;
43
96
  case 2:
44
- k ^= (str.charCodeAt(i + 1) & 0xff) << 8;
97
+ k1 ^= BigInt(key[tailIndex + 1]) << 8n;
45
98
  case 1:
46
- k ^= str.charCodeAt(i) & 0xff;
47
- k = Math.imul(k, c1);
48
- k = (k << r1) | (k >>> (32 - r1));
49
- k = Math.imul(k, c2);
50
- h ^= k;
99
+ k1 ^= BigInt(key[tailIndex + 0]);
100
+ k1 = asUintN(64, k1 * c1);
101
+ k1 = rotl64(k1, 31);
102
+ k1 = asUintN(64, k1 * c2);
103
+ h1 ^= k1;
51
104
  }
52
- h ^= len;
53
- h ^= h >>> 16;
54
- h = Math.imul(h, 0x85ebca6b);
55
- h ^= h >>> 13;
56
- h = Math.imul(h, 0xc2b2ae35);
57
- h ^= h >>> 16;
58
- return h >>> 0;
105
+ h1 ^= BigInt(len);
106
+ h2 ^= BigInt(len);
107
+ h1 = asUintN(64, h1 + h2);
108
+ h2 = asUintN(64, h2 + h1);
109
+ h1 = fmix64(h1);
110
+ h2 = fmix64(h2);
111
+ h1 = asUintN(64, h1 + h2);
112
+ h2 = asUintN(64, h2 + h1);
113
+ return asUintN(64, h1 ^ h2);
59
114
  }
60
115
  function genBase36Hash(obj, seed, length) {
61
116
  const normalized = deepNormalize(obj);
62
- const hashValue = murmurhash3_32(normalized, seed);
63
- const hashStr = hashValue.toString(36);
64
- const firstChar = 'x';
65
- let result = firstChar + hashStr;
66
- if (result.length > length) {
67
- result = result.slice(0, length);
68
- }
69
- else if (result.length < length) {
70
- const paddingNeeded = length - result.length;
71
- const paddingChars = '0123456789abcdefghijklmnopqrstuvwxyz';
72
- let paddingHash = hashValue;
73
- for (let i = 0; i < paddingNeeded; i++) {
74
- paddingHash = paddingHash * 1103515245 + 12345;
75
- const paddingChar = paddingChars[Math.abs(paddingHash) % 36];
76
- result += paddingChar;
77
- }
78
- }
79
- return result;
117
+ const hashValue = murmurhash3_x64_128(normalized, seed);
118
+ const hash = hashValue.toString(36);
119
+ return 'x' + hash.slice(-(length - 1));
80
120
  }
@@ -50,7 +50,9 @@ function transpile(object, base36Hash, core) {
50
50
  }
51
51
  else if (!property.startsWith('@')) {
52
52
  const kebabPseudoSelector = (0, helper_js_1.camelToKebabCase)(property.replace('&', ''));
53
- const styles = stringConverter(className + kebabPseudoSelector, value, indentLevel);
53
+ const isPseudo = property.startsWith(':') || property.startsWith('&');
54
+ const selector = isPseudo ? className + ':not(#\\#)' + kebabPseudoSelector : className + kebabPseudoSelector;
55
+ const styles = stringConverter(selector, value, indentLevel);
54
56
  Object.assign(classSelector, styles);
55
57
  }
56
58
  else if (property.startsWith('@media') || property.startsWith('@container')) {
@@ -64,6 +66,7 @@ function transpile(object, base36Hash, core) {
64
66
  const isAnd = mediaProp.startsWith('&');
65
67
  if (isColon || isAnd) {
66
68
  const kebabMediaProp = (0, helper_js_1.camelToKebabCase)(mediaProp.replace('&', ''));
69
+ const increaseKebabMediaProp = ':not(#\\#)' + kebabMediaProp;
67
70
  let pseudoClassRule = '';
68
71
  if (typeof mediaValue === 'object' && mediaValue !== null) {
69
72
  for (const pseudoProp in mediaValue) {
@@ -74,7 +77,7 @@ function transpile(object, base36Hash, core) {
74
77
  }
75
78
  }
76
79
  }
77
- nestedRules += `${innerIndent}${className}${kebabMediaProp} {\n${pseudoClassRule}${innerIndent}}\n`;
80
+ nestedRules += `${innerIndent}${className}${increaseKebabMediaProp} {\n${pseudoClassRule}${innerIndent}}\n`;
78
81
  }
79
82
  else {
80
83
  const CSSProp = (0, helper_js_1.camelToKebabCase)(mediaProp);
@@ -1,3 +1,5 @@
1
+ import { TextEncoder } from 'util';
2
+ const { asUintN } = BigInt;
1
3
  function deepNormalize(obj) {
2
4
  if (obj === null)
3
5
  return 'null';
@@ -13,65 +15,103 @@ function deepNormalize(obj) {
13
15
  const pairs = keys.map(key => `"${key}":${deepNormalize(recordObj[key])}`);
14
16
  return '{' + pairs.join(',') + '}';
15
17
  }
16
- function murmurhash3_32(str, seed) {
17
- let h = seed;
18
- const len = str.length;
19
- const c1 = 0xcc9e2d51;
20
- const c2 = 0x1b873593;
21
- const r1 = 15;
22
- const r2 = 13;
23
- const m = 5;
24
- const n = 0xe6546b64;
25
- let i = 0;
26
- while (i < len - 3) {
27
- let k = (str.charCodeAt(i) & 0xff) | ((str.charCodeAt(i + 1) & 0xff) << 8) | ((str.charCodeAt(i + 2) & 0xff) << 16) | ((str.charCodeAt(i + 3) & 0xff) << 24);
28
- k = Math.imul(k, c1);
29
- k = (k << r1) | (k >>> (32 - r1));
30
- k = Math.imul(k, c2);
31
- h ^= k;
32
- h = (h << r2) | (h >>> (32 - r2));
33
- h = Math.imul(h, m) + n;
34
- i += 4;
18
+ function rotl64(x, r) {
19
+ const shift = BigInt(r);
20
+ return asUintN(64, (x << shift) | (x >> (64n - shift)));
21
+ }
22
+ function fmix64(k) {
23
+ k ^= k >> 33n;
24
+ k = asUintN(64, k * 0xff51afd7ed558ccdn);
25
+ k ^= k >> 33n;
26
+ k = asUintN(64, k * 0xc4ceb9fe1a85ec53n);
27
+ k ^= k >> 33n;
28
+ return k;
29
+ }
30
+ function murmurhash3_x64_128(str, seed) {
31
+ let h1 = asUintN(64, BigInt(seed));
32
+ let h2 = asUintN(64, BigInt(seed));
33
+ const c1 = 0x87c37b91114253d5n;
34
+ const c2 = 0x4cf5ad432745937fn;
35
+ const encoder = new TextEncoder();
36
+ const key = encoder.encode(str);
37
+ const len = key.length;
38
+ const nblocks = Math.floor(len / 16);
39
+ const view = new DataView(key.buffer, key.byteOffset, key.byteLength);
40
+ for (let i = 0; i < nblocks; i++) {
41
+ const i16 = i * 16;
42
+ let k1 = view.getBigUint64(i16, true);
43
+ let k2 = view.getBigUint64(i16 + 8, true);
44
+ k1 = asUintN(64, k1 * c1);
45
+ k1 = rotl64(k1, 31);
46
+ k1 = asUintN(64, k1 * c2);
47
+ h1 ^= k1;
48
+ h1 = rotl64(h1, 27);
49
+ h1 = asUintN(64, h1 + h2);
50
+ h1 = asUintN(64, h1 * 5n + 0x52dce729n);
51
+ k2 = asUintN(64, k2 * c2);
52
+ k2 = rotl64(k2, 33);
53
+ k2 = asUintN(64, k2 * c1);
54
+ h2 ^= k2;
55
+ h2 = rotl64(h2, 31);
56
+ h2 = asUintN(64, h2 + h1);
57
+ h2 = asUintN(64, h2 * 5n + 0x38495ab5n);
35
58
  }
36
- let k = 0;
37
- switch (len % 4) {
59
+ const tailIndex = nblocks * 16;
60
+ let k1 = 0n;
61
+ let k2 = 0n;
62
+ switch (len & 15) {
63
+ case 15:
64
+ k2 ^= BigInt(key[tailIndex + 14]) << 48n;
65
+ case 14:
66
+ k2 ^= BigInt(key[tailIndex + 13]) << 40n;
67
+ case 13:
68
+ k2 ^= BigInt(key[tailIndex + 12]) << 32n;
69
+ case 12:
70
+ k2 ^= BigInt(key[tailIndex + 11]) << 24n;
71
+ case 11:
72
+ k2 ^= BigInt(key[tailIndex + 10]) << 16n;
73
+ case 10:
74
+ k2 ^= BigInt(key[tailIndex + 9]) << 8n;
75
+ case 9:
76
+ k2 ^= BigInt(key[tailIndex + 8]);
77
+ k2 = asUintN(64, k2 * c2);
78
+ k2 = rotl64(k2, 33);
79
+ k2 = asUintN(64, k2 * c1);
80
+ h2 ^= k2;
81
+ case 8:
82
+ k1 ^= BigInt(key[tailIndex + 7]) << 56n;
83
+ case 7:
84
+ k1 ^= BigInt(key[tailIndex + 6]) << 48n;
85
+ case 6:
86
+ k1 ^= BigInt(key[tailIndex + 5]) << 40n;
87
+ case 5:
88
+ k1 ^= BigInt(key[tailIndex + 4]) << 32n;
89
+ case 4:
90
+ k1 ^= BigInt(key[tailIndex + 3]) << 24n;
38
91
  case 3:
39
- k ^= (str.charCodeAt(i + 2) & 0xff) << 16;
92
+ k1 ^= BigInt(key[tailIndex + 2]) << 16n;
40
93
  case 2:
41
- k ^= (str.charCodeAt(i + 1) & 0xff) << 8;
94
+ k1 ^= BigInt(key[tailIndex + 1]) << 8n;
42
95
  case 1:
43
- k ^= str.charCodeAt(i) & 0xff;
44
- k = Math.imul(k, c1);
45
- k = (k << r1) | (k >>> (32 - r1));
46
- k = Math.imul(k, c2);
47
- h ^= k;
96
+ k1 ^= BigInt(key[tailIndex + 0]);
97
+ k1 = asUintN(64, k1 * c1);
98
+ k1 = rotl64(k1, 31);
99
+ k1 = asUintN(64, k1 * c2);
100
+ h1 ^= k1;
48
101
  }
49
- h ^= len;
50
- h ^= h >>> 16;
51
- h = Math.imul(h, 0x85ebca6b);
52
- h ^= h >>> 13;
53
- h = Math.imul(h, 0xc2b2ae35);
54
- h ^= h >>> 16;
55
- return h >>> 0;
102
+ h1 ^= BigInt(len);
103
+ h2 ^= BigInt(len);
104
+ h1 = asUintN(64, h1 + h2);
105
+ h2 = asUintN(64, h2 + h1);
106
+ h1 = fmix64(h1);
107
+ h2 = fmix64(h2);
108
+ h1 = asUintN(64, h1 + h2);
109
+ h2 = asUintN(64, h2 + h1);
110
+ return asUintN(64, h1 ^ h2);
56
111
  }
57
112
  export function genBase36Hash(obj, seed, length) {
58
113
  const normalized = deepNormalize(obj);
59
- const hashValue = murmurhash3_32(normalized, seed);
60
- const hashStr = hashValue.toString(36);
61
- const firstChar = 'x';
62
- let result = firstChar + hashStr;
63
- if (result.length > length) {
64
- result = result.slice(0, length);
65
- }
66
- else if (result.length < length) {
67
- const paddingNeeded = length - result.length;
68
- const paddingChars = '0123456789abcdefghijklmnopqrstuvwxyz';
69
- let paddingHash = hashValue;
70
- for (let i = 0; i < paddingNeeded; i++) {
71
- paddingHash = paddingHash * 1103515245 + 12345;
72
- const paddingChar = paddingChars[Math.abs(paddingHash) % 36];
73
- result += paddingChar;
74
- }
75
- }
76
- return result;
114
+ const hashValue = murmurhash3_x64_128(normalized, seed);
115
+ const hash = hashValue.toString(36);
116
+ return 'x' + hash.slice(-(length - 1));
77
117
  }
@@ -47,7 +47,9 @@ export function transpile(object, base36Hash, core) {
47
47
  }
48
48
  else if (!property.startsWith('@')) {
49
49
  const kebabPseudoSelector = camelToKebabCase(property.replace('&', ''));
50
- const styles = stringConverter(className + kebabPseudoSelector, value, indentLevel);
50
+ const isPseudo = property.startsWith(':') || property.startsWith('&');
51
+ const selector = isPseudo ? className + ':not(#\\#)' + kebabPseudoSelector : className + kebabPseudoSelector;
52
+ const styles = stringConverter(selector, value, indentLevel);
51
53
  Object.assign(classSelector, styles);
52
54
  }
53
55
  else if (property.startsWith('@media') || property.startsWith('@container')) {
@@ -61,6 +63,7 @@ export function transpile(object, base36Hash, core) {
61
63
  const isAnd = mediaProp.startsWith('&');
62
64
  if (isColon || isAnd) {
63
65
  const kebabMediaProp = camelToKebabCase(mediaProp.replace('&', ''));
66
+ const increaseKebabMediaProp = ':not(#\\#)' + kebabMediaProp;
64
67
  let pseudoClassRule = '';
65
68
  if (typeof mediaValue === 'object' && mediaValue !== null) {
66
69
  for (const pseudoProp in mediaValue) {
@@ -71,7 +74,7 @@ export function transpile(object, base36Hash, core) {
71
74
  }
72
75
  }
73
76
  }
74
- nestedRules += `${innerIndent}${className}${kebabMediaProp} {\n${pseudoClassRule}${innerIndent}}\n`;
77
+ nestedRules += `${innerIndent}${className}${increaseKebabMediaProp} {\n${pseudoClassRule}${innerIndent}}\n`;
75
78
  }
76
79
  else {
77
80
  const CSSProp = camelToKebabCase(mediaProp);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zss-engine",
3
- "version": "1.2.2",
3
+ "version": "2.1.0",
4
4
  "description": "Zero-runtime StyleSheet Engine",
5
5
  "funding": "https://github.com/sponsors/refirst11",
6
6
  "author": "Refirst 11",