@cssxjs/runtime 0.2.30 → 0.2.31

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 CHANGED
@@ -3,6 +3,17 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [0.2.31](https://github.com/startupjs/startupjs/compare/v0.2.30...v0.2.31) (2026-01-23)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **runtime:** improve performance of substituting var() in css ([282cb46](https://github.com/startupjs/startupjs/commit/282cb461369cdb951cc873973a2d0da97a682b9b))
12
+
13
+
14
+
15
+
16
+
6
17
  ## [0.2.30](https://github.com/startupjs/startupjs/compare/v0.2.29...v0.2.30) (2026-01-18)
7
18
 
8
19
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cssxjs/runtime",
3
- "version": "0.2.30",
3
+ "version": "0.2.31",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -54,5 +54,5 @@
54
54
  "optional": true
55
55
  }
56
56
  },
57
- "gitHead": "2fd171f6da726008a2386471bd5be4b5291e49ab"
57
+ "gitHead": "989ab68dbc3ed81262ccc51946ddaa01b90416a5"
58
58
  }
package/process.js CHANGED
@@ -4,11 +4,7 @@ import singletonVariables, { defaultVariables } from './variables.js'
4
4
  import matcher from './matcher.js'
5
5
  import { isPureReact } from './platformHelpers/index.js'
6
6
 
7
- // TODO: Improve css variables performance. Instead of rerunning finding variables each time
8
- // it has to work as a pipeline and pass the variables from one step to the next.
9
-
10
7
  const VARS_REGEX = /"var\(\s*(--[A-Za-z0-9_-]+)\s*,?\s*(.*?)\s*\)"/g
11
- const HAS_VAR_REGEX = /"var\(/
12
8
  const SUPPORT_UNIT = true
13
9
 
14
10
  export function process (
@@ -65,26 +61,7 @@ export function process (
65
61
  return res
66
62
  }
67
63
 
68
- export function hasMedia (styles = {}) {
69
- for (const selector in styles) {
70
- if (/^@media/.test(selector)) {
71
- return true
72
- }
73
- }
74
- }
75
-
76
- export function hasVariables (...styleObjects) {
77
- for (const styleObject of styleObjects) {
78
- if (_hasVariables(styleObject)) return true
79
- }
80
- }
81
-
82
- function _hasVariables (styles = {}) {
83
- return HAS_VAR_REGEX.test(JSON.stringify(styles))
84
- }
85
-
86
- function replaceVariables (styles = {}) {
87
- let strStyles = JSON.stringify(styles)
64
+ function replaceVariables (strStyles) {
88
65
  strStyles = strStyles.replace(VARS_REGEX, (match, varName, varDefault) => {
89
66
  let res
90
67
  res = singletonVariables[varName] ?? defaultVariables[varName] ?? varDefault
@@ -104,24 +81,32 @@ function replaceVariables (styles = {}) {
104
81
  return JSON.parse(strStyles)
105
82
  }
106
83
 
84
+ const stringifiedStylesCache = new WeakMap()
107
85
  function transformStyles (styles) {
108
- if (styles) {
109
- // trigger rerender when cache is NOT used
110
- if (hasMedia(styles)) listenForDimensionsChange()
111
-
112
- // dynamically process @media queries and vh/vw units
113
- styles = dynamicProcess(styles)
86
+ if (!styles) return {}
114
87
 
115
- if (hasVariables(styles)) {
116
- // Dynamically process css variables.
117
- // This will also auto-trigger rerendering on variable change when cache is not used
118
- styles = replaceVariables(styles)
88
+ // IMPORTANT: this will use cached stringified styles from the original styles object
89
+ // which are singletons. That's why it must be first before other transformations take place
90
+ // which will modify the styles object.
91
+ if (styles.__vars) {
92
+ let strStyles = stringifiedStylesCache.get(styles)
93
+ if (!strStyles) {
94
+ strStyles = JSON.stringify(styles)
95
+ stringifiedStylesCache.set(styles, strStyles)
119
96
  }
120
97
 
121
- return styles
122
- } else {
123
- return {}
98
+ // Dynamically process css variables.
99
+ // This will also auto-trigger rerendering on variable change when cache is not used
100
+ styles = replaceVariables(strStyles)
124
101
  }
102
+
103
+ // trigger rerender when cache is NOT used
104
+ if (styles.__hasMedia) listenForDimensionsChange()
105
+
106
+ // dynamically process @media queries and vh/vw units
107
+ styles = dynamicProcess(styles)
108
+
109
+ return styles
125
110
  }
126
111
 
127
112
  // If @media is used, force trigger access to the observable value.
package/processCached.js CHANGED
@@ -1,9 +1,7 @@
1
1
  import { singletonMemoize } from 'teamplay/cache'
2
2
  import dimensions from './dimensions.js'
3
3
  import singletonVariables from './variables.js'
4
- import { process as _process, hasMedia, listenForDimensionsChange, hasVariables } from './process.js'
5
-
6
- const VAR_NAMES_REGEX = /"var\(\s*--[A-Za-z0-9_-]+/g
4
+ import { process as _process, listenForDimensionsChange } from './process.js'
7
5
 
8
6
  export const process = singletonMemoize(_process, {
9
7
  cacheName: 'styles',
@@ -18,7 +16,7 @@ export const process = singletonMemoize(_process, {
18
16
  // IMPORTANT: This should be the same as the ones which go into the singletonMemoize function
19
17
  forceUpdateWhenChanged: (styleName, fileStyles, globalStyles, localStyles, inlineStyleProps) => {
20
18
  const args = {}
21
- const watchWidthChange = hasMedia(fileStyles) || hasMedia(globalStyles) || hasMedia(localStyles)
19
+ const watchWidthChange = fileStyles?.__hasMedia || globalStyles?.__hasMedia || localStyles?.__hasMedia
22
20
  if (watchWidthChange) {
23
21
  // trigger rerender when cache is used
24
22
  listenForDimensionsChange()
@@ -26,7 +24,7 @@ export const process = singletonMemoize(_process, {
26
24
  // the affected cache to recalculate
27
25
  args.dimensionsWidth = dimensions.width
28
26
  }
29
- if (hasVariables(fileStyles, globalStyles, localStyles)) {
27
+ if (fileStyles?.__vars || globalStyles?.__vars || localStyles?.__vars) {
30
28
  const variableNames = getVariableNames(fileStyles, globalStyles, localStyles)
31
29
  // trigger rerender when cache is used
32
30
  listenForVariablesChange(variableNames)
@@ -41,18 +39,14 @@ export const process = singletonMemoize(_process, {
41
39
  })
42
40
 
43
41
  function getVariableNames (...styleObjects) {
44
- let res = []
42
+ const vars = []
45
43
  for (const styleObject of styleObjects) {
46
- res = res.concat(_getVariableNames(styleObject))
44
+ if (!styleObject?.__vars) continue
45
+ for (const varName of styleObject.__vars) {
46
+ if (!vars.includes(varName)) vars.push(varName)
47
+ }
47
48
  }
48
- res = [...new Set(res)].sort() // remove duplicates and sort
49
- return res
50
- }
51
-
52
- function _getVariableNames (styles = {}) {
53
- let res = JSON.stringify(styles).match(VAR_NAMES_REGEX) || []
54
- res = res.map(i => i.replace(/"var\(\s*/, ''))
55
- return res
49
+ return vars.sort()
56
50
  }
57
51
 
58
52
  // If var() is used, force trigger access to the observable value.