@pyreon/rocketstyle 0.24.0 → 0.24.1

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/index.js CHANGED
@@ -16,6 +16,13 @@ const PSEUDO_KEYS = [
16
16
  ];
17
17
  /** Meta pseudo-state keys representing non-interactive states (disabled, readOnly). */
18
18
  const PSEUDO_META_KEYS = ["disabled", "readOnly"];
19
+ /**
20
+ * Pre-merged interaction + meta keys. Hoisted from `rocketstyle.ts`'s
21
+ * `rocketComponent` definition scope to module scope so the merged
22
+ * 6-element array is allocated ONCE per process, not once per
23
+ * rocketstyle definition. Ported from vitus-labs `00fdadc2`.
24
+ */
25
+ const PSEUDO_AND_META_KEYS = [...PSEUDO_KEYS, ...PSEUDO_META_KEYS];
19
26
  /** Supported theme mode flags. */
20
27
  const THEME_MODES = {
21
28
  light: true,
@@ -269,7 +276,7 @@ const mergeDescriptors = (...sources) => {
269
276
  /** Picks only the props whose keys exist in the dimension keywords lookup and have truthy values. */
270
277
  const pickStyledAttrs = (props, keywords) => {
271
278
  const result = {};
272
- for (const key of Object.keys(props)) if (keywords[key] && props[key]) result[key] = props[key];
279
+ for (const key in props) if (keywords[key] && props[key]) result[key] = props[key];
273
280
  return result;
274
281
  };
275
282
  const calculateChainOptions = (options) => (args) => {
@@ -477,13 +484,16 @@ const getTheme = ({ rocketstate, themes, baseTheme, transformKeys, appTheme }) =
477
484
  finalTheme.readOnly ??= EMPTY_PSEUDO;
478
485
  return finalTheme;
479
486
  };
480
- const getThemeByMode = (object, mode) => Object.keys(object).reduce((acc, key) => {
481
- const value = object[key];
482
- if (typeof value === "object" && value !== null) acc[key] = getThemeByMode(value, mode);
483
- else if (isModeCallback(value)) acc[key] = value(mode);
484
- else acc[key] = value;
487
+ const getThemeByMode = (object, mode) => {
488
+ const acc = {};
489
+ for (const key in object) {
490
+ const value = object[key];
491
+ if (typeof value === "object" && value !== null) acc[key] = getThemeByMode(value, mode);
492
+ else if (isModeCallback(value)) acc[key] = value(mode);
493
+ else acc[key] = value;
494
+ }
485
495
  return acc;
486
- }, {});
496
+ };
487
497
 
488
498
  //#endregion
489
499
  //#region src/rocketstyle.ts
@@ -535,7 +545,7 @@ const rocketComponent = (options) => {
535
545
  const ThemeManager$1 = new ThemeManager();
536
546
  const _dimensionsCache = /* @__PURE__ */ new WeakMap();
537
547
  const _reservedKeysCache = /* @__PURE__ */ new WeakMap();
538
- const ALL_PSEUDO_KEYS = [...PSEUDO_KEYS, ...PSEUDO_META_KEYS];
548
+ const ALL_PSEUDO_KEYS = PSEUDO_AND_META_KEYS;
539
549
  const STATIC_OMIT_KEYS = [
540
550
  "pseudo",
541
551
  ...PSEUDO_KEYS,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pyreon/rocketstyle",
3
- "version": "0.24.0",
3
+ "version": "0.24.1",
4
4
  "description": "Multi-dimensional style composition for Pyreon components",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -43,8 +43,8 @@
43
43
  },
44
44
  "devDependencies": {
45
45
  "@pyreon/test-utils": "^0.13.11",
46
- "@pyreon/typescript": "^0.24.0",
47
- "@pyreon/ui-core": "^0.24.0",
46
+ "@pyreon/typescript": "^0.24.1",
47
+ "@pyreon/ui-core": "^0.24.1",
48
48
  "@vitest/browser-playwright": "^4.1.4",
49
49
  "@vitus-labs/tools-rolldown": "^2.4.0"
50
50
  },
@@ -52,9 +52,9 @@
52
52
  "node": ">= 22"
53
53
  },
54
54
  "dependencies": {
55
- "@pyreon/core": "^0.24.0",
56
- "@pyreon/reactivity": "^0.24.0",
57
- "@pyreon/styler": "^0.24.0",
58
- "@pyreon/ui-core": "^0.24.0"
55
+ "@pyreon/core": "^0.24.1",
56
+ "@pyreon/reactivity": "^0.24.1",
57
+ "@pyreon/styler": "^0.24.1",
58
+ "@pyreon/ui-core": "^0.24.1"
59
59
  }
60
60
  }
@@ -14,6 +14,14 @@ export const PSEUDO_KEYS = ['hover', 'active', 'focus', 'pressed'] as const
14
14
  /** Meta pseudo-state keys representing non-interactive states (disabled, readOnly). */
15
15
  export const PSEUDO_META_KEYS = ['disabled', 'readOnly'] as const
16
16
 
17
+ /**
18
+ * Pre-merged interaction + meta keys. Hoisted from `rocketstyle.ts`'s
19
+ * `rocketComponent` definition scope to module scope so the merged
20
+ * 6-element array is allocated ONCE per process, not once per
21
+ * rocketstyle definition. Ported from vitus-labs `00fdadc2`.
22
+ */
23
+ export const PSEUDO_AND_META_KEYS = [...PSEUDO_KEYS, ...PSEUDO_META_KEYS] as const
24
+
17
25
  /** Supported theme mode flags. */
18
26
  export const THEME_MODES = {
19
27
  light: true,
@@ -1,6 +1,6 @@
1
1
  import { compose, config, hoistNonReactStatics, omit, pick, render } from '@pyreon/ui-core'
2
2
  import { LocalThemeManager } from './cache'
3
- import { CONFIG_KEYS, PSEUDO_KEYS, PSEUDO_META_KEYS, STYLING_KEYS, __DEV__ } from './constants'
3
+ import { CONFIG_KEYS, PSEUDO_AND_META_KEYS, PSEUDO_KEYS, STYLING_KEYS, __DEV__ } from './constants'
4
4
  import createLocalProvider from './context/createLocalProvider'
5
5
  import { useLocalContext } from './context/localContext'
6
6
  import { rocketstyleAttrsHoc } from './hoc'
@@ -130,8 +130,11 @@ const rocketComponent: RocketComponent = (options) => {
130
130
  >()
131
131
  const _reservedKeysCache = new WeakMap<object, string[]>()
132
132
 
133
- // Pre-compute merged key arrays once per definition (not per mount)
134
- const ALL_PSEUDO_KEYS = [...PSEUDO_KEYS, ...PSEUDO_META_KEYS]
133
+ // Reuse the module-scope pre-merged constant. Cast away `readonly` for
134
+ // the downstream consumers that take a plain `string[]`. Saves the
135
+ // 6-element array allocation that fired once per `rocketstyle()`
136
+ // definition. Ported from vitus-labs `00fdadc2`.
137
+ const ALL_PSEUDO_KEYS = PSEUDO_AND_META_KEYS as unknown as string[]
135
138
  // Static portion of omit keys — PSEUDO_KEYS + filterAttrs + 'pseudo' are definition-scoped.
136
139
  // RESERVED_STYLING_PROPS_KEYS is dimension-dependent but also cached per definition.
137
140
  // 'pseudo' is included here so we can skip the destructuring spread of mergeProps.
@@ -72,8 +72,13 @@ export const pickStyledAttrs = <
72
72
  props: T,
73
73
  keywords: K,
74
74
  ): { [I in keyof K & keyof T]: T[I] } => {
75
+ // Direct `for...in` avoids the `Object.keys(props)` array allocation
76
+ // that `for (const key of Object.keys(props))` paid on every render.
77
+ // The hot path is rocketstyle's `EnhancedComponent` body — fires once
78
+ // per render of every rocketstyle-wrapped component. Ported from
79
+ // vitus-labs `00fdadc2`.
75
80
  const result: Record<string, unknown> = {}
76
- for (const key of Object.keys(props)) {
81
+ for (const key in props) {
77
82
  if (keywords[key] && props[key]) result[key] = props[key]
78
83
  }
79
84
  return result as { [I in keyof K & keyof T]: T[I] }
@@ -189,20 +189,23 @@ export type GetThemeByMode = (
189
189
  themes: Record<string, unknown>
190
190
  }>
191
191
 
192
- export const getThemeByMode: GetThemeByMode = (object, mode) =>
193
- Object.keys(object).reduce(
194
- (acc, key) => {
195
- const value = object[key]
196
-
197
- if (typeof value === 'object' && value !== null) {
198
- acc[key] = getThemeByMode(value, mode)
199
- } else if (isModeCallback(value)) {
200
- acc[key] = value(mode)
201
- } else {
202
- acc[key] = value
203
- }
204
-
205
- return acc
206
- },
207
- {} as Record<string, any>,
208
- )
192
+ export const getThemeByMode: GetThemeByMode = (object, mode) => {
193
+ // Recursive theme walker — `for...in` avoids the per-node
194
+ // `Object.keys` array allocation that the prior reduce paid. Called
195
+ // from inside cached `LocalThemeManager` WeakMap tiers (one per
196
+ // theme/mode transition), so the win is smaller than per-render
197
+ // helpers but the pattern is consistent. Ported from vitus-labs
198
+ // `00fdadc2`.
199
+ const acc: Record<string, any> = {}
200
+ for (const key in object) {
201
+ const value = object[key]
202
+ if (typeof value === 'object' && value !== null) {
203
+ acc[key] = getThemeByMode(value, mode)
204
+ } else if (isModeCallback(value)) {
205
+ acc[key] = value(mode)
206
+ } else {
207
+ acc[key] = value
208
+ }
209
+ }
210
+ return acc
211
+ }