@pyreon/rocketstyle 0.12.15 → 0.13.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
@@ -504,20 +504,30 @@ const rocketComponent = (options) => {
504
504
  const EnhancedComponent = (props) => {
505
505
  const localCtx = useLocalContext(options.consumer);
506
506
  const themeAttrs = useThemeAttrs(options);
507
- const theme = themeAttrs.theme;
508
- const baseThemeHelper = ThemeManager$1.baseTheme;
509
- if (!baseThemeHelper.has(theme)) baseThemeHelper.set(theme, getThemeFromChain(options.theme, theme));
510
- const baseTheme = baseThemeHelper.get(theme);
511
- const dimHelper = ThemeManager$1.dimensionsThemes;
512
- if (!dimHelper.has(theme)) dimHelper.set(theme, getDimensionThemes(theme, options));
513
- const themes = dimHelper.get(theme);
507
+ const initialTheme = themeAttrs.theme;
508
+ (() => {
509
+ const helper = ThemeManager$1.baseTheme;
510
+ if (!helper.has(initialTheme)) helper.set(initialTheme, getThemeFromChain(options.theme, initialTheme));
511
+ return helper.get(initialTheme);
512
+ })();
514
513
  const { keysMap: dimensions, keywords: reservedPropNames } = getDimensionsMap({
515
- themes,
514
+ themes: (() => {
515
+ const helper = ThemeManager$1.dimensionsThemes;
516
+ if (!helper.has(initialTheme)) helper.set(initialTheme, getDimensionThemes(initialTheme, options));
517
+ return helper.get(initialTheme);
518
+ })(),
516
519
  useBooleans: options.useBooleans
517
520
  });
518
521
  const RESERVED_STYLING_PROPS_KEYS = Object.keys(reservedPropNames);
519
522
  const $rocketstyleAccessor = () => {
523
+ const theme = themeAttrs.theme;
520
524
  const mode = themeAttrs.mode;
525
+ const baseThemeHelper = ThemeManager$1.baseTheme;
526
+ if (!baseThemeHelper.has(theme)) baseThemeHelper.set(theme, getThemeFromChain(options.theme, theme));
527
+ const baseTheme = baseThemeHelper.get(theme);
528
+ const dimHelper = ThemeManager$1.dimensionsThemes;
529
+ if (!dimHelper.has(theme)) dimHelper.set(theme, getDimensionThemes(theme, options));
530
+ const themes = dimHelper.get(theme);
521
531
  const rocketstate = _calculateStylingAttrs({
522
532
  props: pickStyledAttrs(props, reservedPropNames),
523
533
  dimensions
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["CoreProvider","useTheme","ThemeManager","LocalThemeManager","rocketstyleAttrsHoc","useTheme","defaultDimensions"],"sources":["../src/constants/index.ts","../src/context/context.ts","../src/constants/defaultDimensions.ts","../src/cache/LocalThemeManager.ts","../src/context/localContext.ts","../src/context/createLocalProvider.ts","../src/hooks/useTheme.ts","../src/utils/attrs.ts","../src/hoc/rocketstyleAttrsHoc.ts","../src/utils/chaining.ts","../src/utils/compose.ts","../src/utils/dimensions.ts","../src/utils/statics.ts","../src/utils/styles.ts","../src/utils/collection.ts","../src/utils/theme.ts","../src/rocketstyle.ts","../src/init.ts","../src/isRocketComponent.ts","../src/index.ts"],"sourcesContent":["/** Default theme mode used when no mode is provided via context. */\nexport const MODE_DEFAULT = 'light'\n\n/** Pseudo-state interaction keys tracked for styling (hover, active, focus, pressed). */\nexport const PSEUDO_KEYS = ['hover', 'active', 'focus', 'pressed'] as const\n\n/** Meta pseudo-state keys representing non-interactive states (disabled, readOnly). */\nexport const PSEUDO_META_KEYS = ['disabled', 'readOnly'] as const\n\n/** Supported theme mode flags. */\nexport const THEME_MODES = {\n light: true,\n dark: true,\n} as const\n\n/** Maps each theme mode to its inverse (light -> dark, dark -> light). */\nexport const THEME_MODES_INVERSED = {\n dark: 'light',\n light: 'dark',\n} as const\n\n/** Reserved configuration keys accepted by the `.config()` chaining method. */\nexport const CONFIG_KEYS = [\n 'provider',\n 'consumer',\n 'DEBUG',\n 'name',\n 'component',\n 'inversed',\n 'passProps',\n 'styled',\n] as const\n\n/** Keys for theme and styles chaining methods. */\nexport const STYLING_KEYS = ['theme', 'styles'] as const\nexport const STATIC_KEYS = [...STYLING_KEYS, 'compose'] as const\n\n/** Union of all reserved keys that cannot be used as dimension names. */\nexport const ALL_RESERVED_KEYS = [\n ...Object.keys(THEME_MODES),\n ...CONFIG_KEYS,\n ...STATIC_KEYS,\n 'attrs',\n] as const\n","import type { VNodeChild } from '@pyreon/core'\nimport { useContext } from '@pyreon/core'\nimport { Provider as CoreProvider, context } from '@pyreon/ui-core'\nimport { MODE_DEFAULT, THEME_MODES_INVERSED } from '../constants'\n\ntype Theme = {\n rootSize: number\n breakpoints?: Record<string, number>\n} & Record<string, unknown>\n\nexport type TProvider = {\n children: VNodeChild\n theme?: Theme | undefined\n mode?: 'light' | 'dark' | undefined\n inversed?: boolean | undefined\n provider?: ((props: Record<string, unknown>) => VNodeChild) | undefined\n}\n\n/**\n * Top-level theme and mode provider for rocketstyle components.\n * Reads the parent context, merges incoming props, and resolves\n * the active mode (with optional inversion for nested dark/light switching).\n *\n * In Pyreon, context is provided via provide() instead of React.Provider.\n */\nconst Provider = ({ provider = CoreProvider, inversed, ...props }: TProvider): VNodeChild => {\n const getCtx = useContext(context)\n const ctx = getCtx()\n\n const merged = { ...ctx, ...props, provider } as unknown as TProvider & Record<string, unknown>\n const { theme, mode, provider: RocketstyleProvider, children } = merged\n\n let newMode = MODE_DEFAULT\n\n if (mode) {\n newMode = inversed ? THEME_MODES_INVERSED[mode] : mode\n }\n\n const FinalProvider = RocketstyleProvider ?? CoreProvider\n const result = FinalProvider({\n mode: newMode,\n isDark: newMode === 'dark',\n isLight: newMode === 'light',\n ...(theme !== undefined ? { theme } : {}),\n provider,\n children,\n })\n\n return result ?? null\n}\n\nexport { context }\n\nexport default Provider\n","/**\n * Default dimension configuration for rocketstyle components.\n * Defines four built-in dimensions: `states`, `sizes`, `variants`,\n * and `multiple` (a multi-select dimension).\n */\nconst DEFAULT_DIMENSIONS = {\n states: 'state',\n sizes: 'size',\n variants: 'variant',\n multiple: {\n propName: 'multiple',\n multi: true,\n },\n modifiers: {\n propName: 'modifier',\n multi: true,\n transform: true,\n },\n} as const\n\nexport type DefaultDimensions = typeof DEFAULT_DIMENSIONS\n\nexport default DEFAULT_DIMENSIONS\n","/**\n * WeakMap-based multi-tier cache for computed theme objects.\n * Maintains separate caches for base themes, dimension themes,\n * and their light/dark mode variants to avoid recalculation on re-renders.\n */\nexport default class ThemeManager {\n baseTheme = new WeakMap()\n\n dimensionsThemes = new WeakMap()\n\n modeBaseTheme = { light: new WeakMap(), dark: new WeakMap() }\n\n modeDimensionTheme = { light: new WeakMap(), dark: new WeakMap() }\n}\n","import { createContext, useContext } from '@pyreon/core'\nimport type { PseudoState } from '../types/pseudo'\n\ntype LocalContext = Partial<\n {\n pseudo: PseudoState\n } & Record<string, string>\n>\n\n/**\n * Local context for propagating pseudo-state (hover, focus, pressed)\n * and additional styling attributes from a parent provider component\n * to its rocketstyle children.\n */\nconst localContext = createContext<LocalContext>({})\n\nconst EMPTY_CTX = { pseudo: {} } as LocalContext\n\n/**\n * Retrieves the local pseudo-state context. When a consumer callback\n * is provided, it transforms the raw context; otherwise returns defaults.\n *\n * In Pyreon, components are plain functions that run once — no useMemo needed.\n */\ntype UseLocalContext = (consumer: any) => LocalContext\nexport const useLocalContext: UseLocalContext = (consumer) => {\n const ctx = useContext(localContext)\n\n if (!consumer) return EMPTY_CTX\n\n const result = consumer((callback: any) => callback(ctx))\n return { pseudo: {}, ...result }\n}\n\nexport { localContext }\n\nexport default localContext\n","import { provide } from '@pyreon/core'\nimport { signal } from '@pyreon/reactivity'\nimport type { PseudoProps } from '../types/pseudo'\nimport type { ComponentFn } from '../types/utils'\nimport { localContext } from './localContext'\n\ntype Props = PseudoProps & Record<string, any>\n\n/**\n * Higher-order component that wraps a component with a LocalProvider,\n * detecting pseudo-states (hover, focus, pressed) via mouse/focus events\n * and broadcasting them through local context to child rocketstyle components.\n *\n * In Pyreon, context is provided via provide(), and state is managed\n * with signals instead of useState.\n */\nconst createLocalProvider = (WrappedComponent: ComponentFn<any>) => {\n const HOCComponent: ComponentFn<Props> = ({\n onMouseEnter,\n onMouseLeave,\n onMouseUp,\n onMouseDown,\n onFocus,\n onBlur,\n $rocketstate,\n ...props\n }) => {\n const hover = signal(false)\n const focus = signal(false)\n const pressed = signal(false)\n\n const events = {\n onMouseEnter: (e: MouseEvent) => {\n hover.set(true)\n if (onMouseEnter) onMouseEnter(e)\n },\n onMouseLeave: (e: MouseEvent) => {\n hover.set(false)\n pressed.set(false)\n if (onMouseLeave) onMouseLeave(e)\n },\n onMouseDown: (e: MouseEvent) => {\n pressed.set(true)\n if (onMouseDown) onMouseDown(e)\n },\n onMouseUp: (e: MouseEvent) => {\n pressed.set(false)\n if (onMouseUp) onMouseUp(e)\n },\n onFocus: (e: FocusEvent) => {\n focus.set(true)\n if (onFocus) onFocus(e)\n },\n onBlur: (e: FocusEvent) => {\n focus.set(false)\n if (onBlur) onBlur(e)\n },\n }\n\n // Use getters so pseudo-state signals are read lazily by consumers\n // inside their own reactive scopes — NOT eagerly during parent setup.\n // Without getters, hover()/focus()/pressed() reads here would register\n // as dependencies of any parent effect, causing cascading re-renders\n // on every mouse event.\n // Resolve $rocketstate if it's a function accessor (from EnhancedComponent)\n const resolvedState =\n typeof $rocketstate === 'function' ? $rocketstate() : $rocketstate\n const updatedState = {\n ...resolvedState,\n pseudo: {\n ...resolvedState?.pseudo,\n get hover() {\n return hover()\n },\n get focus() {\n return focus()\n },\n get pressed() {\n return pressed()\n },\n },\n }\n\n // Provide local context for child rocketstyle components\n provide(localContext, updatedState)\n\n return WrappedComponent({\n ...props,\n ...events,\n $rocketstate: updatedState,\n })\n }\n\n return HOCComponent\n}\n\nexport default createLocalProvider\n","import { useContext } from '@pyreon/core'\nimport { THEME_MODES_INVERSED } from '../constants'\nimport { context } from '../context/context'\nimport type { ThemeModeKeys } from '../types/theme'\n\ntype Context = {\n theme: Record<string, unknown>\n mode: ThemeModeKeys\n isDark: boolean\n isLight: boolean\n}\n\ntype UseThemeAttrs = ({ inversed }: { inversed?: boolean | undefined }) => Context\n\n/**\n * Retrieves the current theme object and resolved mode from context.\n *\n * Returns an object with getter properties so that mode/isDark/isLight\n * are evaluated lazily on each access. The context is a ReactiveContext,\n * so useContext returns `() => CoreContextValue` — we call it inside\n * each getter to ensure reactive tracking.\n */\nconst useThemeAttrs: UseThemeAttrs = ({ inversed }) => {\n // ReactiveContext: useContext returns () => CoreContextValue.\n // Call the getter inside each property getter for reactive tracking.\n const getCtx = useContext(context)\n\n return {\n get theme() {\n return getCtx().theme ?? ({} as Record<string, unknown>)\n },\n get mode() {\n const ctxMode = getCtx().mode ?? 'light'\n return inversed ? THEME_MODES_INVERSED[ctxMode] : ctxMode\n },\n get isDark() {\n const ctxDark = getCtx().isDark ?? false\n return inversed ? !ctxDark : ctxDark\n },\n get isLight() {\n const ctxDark = getCtx().isDark ?? false\n const isDark = inversed ? !ctxDark : ctxDark\n return !isDark\n },\n }\n}\n\nexport default useThemeAttrs\n","import type { MultiKeys } from '../types/dimensions'\n\n// --------------------------------------------------------\n// remove undefined props\n// --------------------------------------------------------\n/** Strips keys with `undefined` values so they don't shadow default props during merging. */\ntype RemoveUndefinedProps = <T extends Record<string, any>>(props: T) => Partial<T>\n\nexport const removeUndefinedProps: RemoveUndefinedProps = (props) => {\n const result: Partial<typeof props> = {}\n for (const key in props) {\n if (props[key] !== undefined) result[key] = props[key]\n }\n return result\n}\n\n// --------------------------------------------------------\n// pick styled props\n// --------------------------------------------------------\n/** Picks only the props whose keys exist in the dimension keywords lookup and have truthy values. */\nexport const pickStyledAttrs = <\n T extends Record<string, any>,\n K extends Record<string, true | undefined>,\n>(\n props: T,\n keywords: K,\n): { [I in keyof K & keyof T]: T[I] } => {\n const result: Record<string, unknown> = {}\n for (const key of Object.keys(props)) {\n if (keywords[key] && props[key]) result[key] = props[key]\n }\n return result as { [I in keyof K & keyof T]: T[I] }\n}\n\n// --------------------------------------------------------\n// combine values\n// --------------------------------------------------------\n/**\n * Returns a curried function that evaluates an array of `.attrs()` callbacks,\n * spreading each result into a single merged props object via `Object.assign`.\n */\ntype OptionFunc<A> = (...arg: A[]) => Record<string, unknown>\ntype CalculateChainOptions = <A>(\n options?: OptionFunc<A>[],\n) => (args: A[]) => ReturnType<OptionFunc<A>>\n\nexport const calculateChainOptions: CalculateChainOptions = (options) => (args) => {\n if (!options || options.length === 0) return {}\n\n return options.reduce<Record<string, unknown>>(\n (acc, item) => Object.assign(acc, item(...args)),\n {},\n )\n}\n\n// --------------------------------------------------------\n// get style attributes\n// --------------------------------------------------------\n/**\n * Resolves the active value for each styling dimension from component props.\n * First checks for explicit prop values (string, number, or array for multi-keys),\n * then falls back to boolean shorthand props when `useBooleans` is enabled.\n */\ntype CalculateStylingAttrs = ({\n useBooleans,\n multiKeys,\n}: {\n useBooleans?: boolean\n multiKeys?: MultiKeys\n}) => ({\n props,\n dimensions,\n}: {\n props: Record<string, unknown>\n dimensions: Record<string, unknown>\n}) => Record<string, any>\nexport const calculateStylingAttrs: CalculateStylingAttrs =\n ({ useBooleans, multiKeys }) =>\n ({ props, dimensions }) => {\n const result: Record<string, any> = {}\n\n // (1) find dimension keys values & initialize\n // object with possible options\n Object.keys(dimensions).forEach((item) => {\n const pickedProp = props[item]\n const t = typeof pickedProp\n\n // if the property is multi key, allow assign array as well\n if (multiKeys?.[item] && Array.isArray(pickedProp)) {\n result[item] = pickedProp\n }\n // assign when it's only a string or number otherwise it's considered\n // as invalid param\n else if (t === 'string' || t === 'number') {\n result[item] = pickedProp\n } else {\n result[item] = undefined\n }\n })\n\n // (2) if booleans are being used let's find the rest\n if (useBooleans) {\n const propsKeys = Object.keys(props)\n\n Object.entries(result).forEach(([key, value]) => {\n const isMultiKey = multiKeys?.[key]\n\n // when value in result is not assigned yet\n if (!value) {\n let newDimensionValue: string | string[] | undefined\n const keywordSet = new Set(Object.keys(dimensions[key] as Record<string, unknown>))\n\n if (isMultiKey) {\n newDimensionValue = propsKeys.filter((propKey) => keywordSet.has(propKey))\n } else {\n // iterate backwards to guarantee the last one will have\n // a priority over previous ones\n for (let i = propsKeys.length - 1; i >= 0; i--) {\n const k = propsKeys[i] as string\n if (keywordSet.has(k) && props[k]) {\n newDimensionValue = k\n break\n }\n }\n }\n\n result[key] = newDimensionValue\n }\n })\n }\n\n return result\n }\n","import { render } from '@pyreon/ui-core'\nimport { useTheme } from '../hooks'\nimport type { Configuration } from '../types/configuration'\nimport type { ComponentFn } from '../types/utils'\nimport { calculateChainOptions, removeUndefinedProps } from '../utils/attrs'\n\nexport type RocketStyleHOC = ({\n inversed,\n attrs,\n priorityAttrs,\n}: Pick<Configuration, 'inversed' | 'attrs' | 'priorityAttrs'>) => (\n WrappedComponent: ComponentFn<any>,\n) => ComponentFn<any>\n\n/**\n * HOC that resolves the `.attrs()` chain before the inner component renders.\n * Evaluates both regular and priority attrs callbacks with the current theme\n * and mode, then merges the results with explicit props (priority attrs\n * are applied first, regular attrs can be overridden by direct props).\n *\n * In Pyreon, there is no forwardRef — ref flows as a normal prop.\n * Components are plain functions.\n */\nconst rocketStyleHOC: RocketStyleHOC = ({ inversed, attrs, priorityAttrs }) => {\n const calculateAttrs = calculateChainOptions(attrs)\n const calculatePriorityAttrs = calculateChainOptions(priorityAttrs)\n\n const Enhanced = (WrappedComponent: ComponentFn<any>) => {\n const HOCComponent: ComponentFn<any> = (props) => {\n // IMPORTANT: Do NOT destructure — useTheme returns getter properties.\n // Destructuring calls getters once and captures static values.\n // Keep the object reference so properties re-evaluate lazily.\n const themeAttrs = useTheme({ inversed })\n\n // Remove undefined props not to override potential default props\n const filteredProps = removeUndefinedProps(props)\n\n // Read theme attrs eagerly — .attrs() callbacks run once at mount.\n // Mode-dependent styling is handled reactively by the $rocketstyle\n // accessor in EnhancedComponent, not by re-running attrs.\n const callbackParams = [\n themeAttrs.theme,\n { render, mode: themeAttrs.mode, isDark: themeAttrs.isDark, isLight: themeAttrs.isLight },\n ]\n\n const prioritizedAttrs = calculatePriorityAttrs([filteredProps, ...callbackParams])\n\n const finalAttrs = calculateAttrs([\n {\n ...prioritizedAttrs,\n ...filteredProps,\n },\n ...callbackParams,\n ])\n\n const finalProps = {\n ...prioritizedAttrs,\n ...finalAttrs,\n ...filteredProps,\n }\n\n return WrappedComponent(finalProps)\n }\n return HOCComponent\n }\n\n return Enhanced\n}\n\nexport default rocketStyleHOC\n","type Func = (...args: any) => Record<string, unknown>\ntype Obj = Record<string, unknown>\n\n// --------------------------------------------------------\n// Chain Options\n// --------------------------------------------------------\n/**\n * Appends a new option (function or plain object) to an existing chain\n * of option callbacks. Objects are wrapped in a thunk for uniform handling.\n */\ntype ChainOptions = (opts: Obj | Func | undefined, defaultOpts: Func[]) => Func[]\n\nexport const chainOptions: ChainOptions = (opts, defaultOpts = []) => {\n const result = [...defaultOpts]\n\n if (typeof opts === 'function') result.push(opts)\n else if (typeof opts === 'object') result.push(() => opts)\n\n return result\n}\n\n// --------------------------------------------------------\n// Chain Or Options\n// --------------------------------------------------------\n/**\n * For each key, picks the new value if truthy, otherwise falls back\n * to the default. Used for config keys that replace rather than merge.\n */\ntype ChainOrOptions = (\n keys: readonly string[],\n opts: Obj,\n defaultOpts: Obj,\n) => Record<string, unknown>\n\nexport const chainOrOptions: ChainOrOptions = (keys, opts, defaultOpts) =>\n keys.reduce((acc, item) => ({ ...acc, [item]: opts[item] || defaultOpts[item] }), {})\n\n// --------------------------------------------------------\n// Chain Reserved Options\n// --------------------------------------------------------\n/**\n * Chains option callbacks for reserved dimension and styling keys,\n * delegating to `chainOptions` for each key individually.\n */\ntype ChainReservedKeyOptions = (\n keys: readonly string[],\n opts: Record<string, Obj | Func>,\n defaultOpts: Record<string, Func[]>,\n) => Record<string, ReturnType<typeof chainOptions>>\n\nexport const chainReservedKeyOptions: ChainReservedKeyOptions = (keys, opts, defaultOpts) =>\n keys.reduce(\n (acc, item) => ({\n ...acc,\n [item]: chainOptions(opts[item], defaultOpts[item] ?? []),\n }),\n {},\n )\n","/**\n * Extracts HOC functions from the compose configuration object,\n * filters out non-function entries, and reverses them so the\n * outermost HOC in the chain wraps first (inside-out composition).\n */\ntype CalculateHocsFuncs = (options: Record<string, any>) => ((arg: any) => any)[]\n\nexport const calculateHocsFuncs: CalculateHocsFuncs = (options = {}) =>\n Object.values(options)\n .filter((item) => typeof item === 'function')\n .reverse()\n","import { get, isEmpty, set } from '@pyreon/ui-core'\nimport type { Dimensions, DimensionValue, MultiKeys } from '../types/dimensions'\n\n// --------------------------------------------------------\n// Is value a valid key\n// --------------------------------------------------------\n/** Checks whether a dimension value is defined and not explicitly disabled (false). */\ntype IsValidKey = (value: any) => boolean\nexport const isValidKey: IsValidKey = (value) =>\n value !== undefined && value !== null && value !== false\n\n// --------------------------------------------------------\n// Is value a multi key\n// --------------------------------------------------------\n/** Determines if a dimension value is a multi-key config object, returning [isMulti, propName]. */\ntype IsMultiKey = (value: string | Record<string, unknown>) => [boolean, string]\nexport const isMultiKey: IsMultiKey = (value) => {\n if (typeof value === 'object' && value !== null) return [true, get(value, 'propName') as string]\n return [false, value]\n}\n\n// --------------------------------------------------------\n// calculate dimensions map\n// --------------------------------------------------------\n/**\n * Builds a two-level map (`keysMap`) of dimension -> option -> true,\n * and a flat `keywords` lookup of all prop names reserved by dimensions\n * (including boolean shorthand keys when `useBooleans` is enabled).\n */\ntype GetDimensionsMap = <T extends Record<string, any>>({\n themes,\n useBooleans,\n}: {\n themes: T\n useBooleans?: boolean\n}) => { keysMap: Record<string, any>; keywords: Record<string, any> }\n\nexport const getDimensionsMap: GetDimensionsMap = ({ themes, useBooleans }) => {\n const result = {\n keysMap: {} as Record<string, any>,\n keywords: {} as Record<string, any>,\n }\n\n if (isEmpty(themes)) return result\n\n return Object.entries(themes).reduce((accumulator, [key, value]) => {\n const { keysMap, keywords } = accumulator\n keywords[key] = true\n\n Object.entries(value).forEach(([itemKey, itemValue]) => {\n if (!isValidKey(itemValue)) return\n\n if (useBooleans) {\n keywords[itemKey] = true\n }\n\n set(keysMap, [key, itemKey], true)\n })\n\n return accumulator\n }, result)\n}\n\n// --------------------------------------------------------\n// simple object getters\n// --------------------------------------------------------\n/** Returns the keys of an object with proper typing. */\ntype GetKeys = <T extends Record<string, unknown>>(obj: T) => Array<keyof T>\nexport const getKeys: GetKeys = (obj) => Object.keys(obj)\n\ntype GetValues = <T extends Record<string, unknown>, K extends keyof T>(obj: T) => T[K][]\nexport const getValues = (<T extends Record<string, unknown>>(obj: T) =>\n Object.values(obj)) as GetValues\n\n// --------------------------------------------------------\n// get dimensions values array\n// --------------------------------------------------------\n/** Extracts the prop name from each dimension value, unwrapping multi-key config objects. */\ntype ValueType<T> = T extends string ? T : T[][0]\ntype GetDimensionsValues = <T extends Dimensions, K extends keyof T>(obj: T) => ValueType<T[K]>[]\n\nexport const getDimensionsValues = (<T extends Dimensions>(obj: T) =>\n getValues(obj).map((item: DimensionValue) => {\n if (typeof item === 'object') {\n return item.propName as string\n }\n\n return item\n })) as GetDimensionsValues\n\n// --------------------------------------------------------\n// get multiple dimensions map\n// --------------------------------------------------------\n/** Builds a lookup of dimension prop names that accept multiple simultaneous values. */\ntype GetMultipleDimensions = <T extends Dimensions>(obj: T) => MultiKeys<T>\n\nexport const getMultipleDimensions: GetMultipleDimensions = (obj) =>\n getValues(obj).reduce(\n (accumulator, value: DimensionValue) => {\n if (typeof value === 'object') {\n if (value.multi === true) accumulator[value.propName] = true\n }\n\n return accumulator\n },\n {} as Record<string, true>,\n )\n\n// --------------------------------------------------------\n// get transform dimensions map\n// --------------------------------------------------------\n/** Builds a lookup of dimension prop names that are transform dimensions (evaluated last with function values). */\ntype TransformKeys = Partial<Record<string, true>>\ntype GetTransformDimensions = <T extends Dimensions>(obj: T) => TransformKeys\n\nexport const getTransformDimensions: GetTransformDimensions = (obj) =>\n getValues(obj).reduce(\n (accumulator, value: DimensionValue) => {\n if (typeof value === 'object') {\n if (value.transform === true) accumulator[value.propName] = true\n }\n\n return accumulator\n },\n {} as Record<string, true>,\n )\n","import { isEmpty } from '@pyreon/ui-core'\nimport { STATIC_KEYS } from '../constants'\n\n// --------------------------------------------------------\n// helpers for create statics chaining methods on component\n// --------------------------------------------------------\n/**\n * Attaches chaining static methods (e.g. `.states()`, `.sizes()`, `.theme()`)\n * to a component. Each method calls `cloneAndEnhance` with the corresponding key.\n */\ntype CreateStaticsChainingEnhancers = <O extends Record<string, any>, DK extends string[]>(props: {\n context: Record<string, any>\n dimensionKeys: DK\n func: (defaultOpts: O, opts: any) => void\n options: O\n}) => void\n\nexport const createStaticsChainingEnhancers: CreateStaticsChainingEnhancers = ({\n context,\n dimensionKeys,\n func,\n options,\n}) => {\n const keys = [...dimensionKeys, ...STATIC_KEYS]\n\n keys.forEach((item) => {\n context[item] = (props: any) => func(options, { [item]: props })\n })\n}\n\n// --------------------------------------------------------\n// helpers for create statics on component\n// --------------------------------------------------------\n/** Copies user-defined static properties onto the component's `meta` object. */\ntype CreateStaticsEnhancers = (params: {\n context: Record<string, any>\n options: Record<string, any>\n}) => void\n\nexport const createStaticsEnhancers: CreateStaticsEnhancers = ({ context, options }) => {\n if (!isEmpty(options)) {\n Object.assign(context, options)\n }\n}\n","import { config } from '@pyreon/ui-core'\nimport type { StylesCbArray } from '../types/styles'\n\n// --------------------------------------------------------\n// Calculate styles\n// --------------------------------------------------------\n/**\n * Evaluates an array of style callback functions with the configured\n * `css` tagged-template helper, producing the final CSS interpolations\n * to be passed into the styled-component template literal.\n */\ntype CalculateStyles = (styles: StylesCbArray | undefined) => ReturnType<StylesCbArray[number]>[]\n\nexport const calculateStyles: CalculateStyles = (styles) => {\n if (!styles) return []\n\n return styles.map((item) => item(config.css as Parameters<typeof item>[0]))\n}\n","// --------------------------------------------------------\n// Remove Nullable values\n// --------------------------------------------------------\n/** Filters out entries with `null`, `undefined`, or `false` values from an object. */\ntype RemoveNullableValues = (obj: Record<string, any>) => Record<string, any>\nexport const removeNullableValues: RemoveNullableValues = (obj) =>\n Object.entries(obj)\n .filter(([, v]) => v != null && v !== false)\n .reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {})\n","import { config, isEmpty, merge } from '@pyreon/ui-core'\nimport type { ThemeModeCallback } from '../types/theme'\nimport { removeNullableValues } from './collection'\nimport { isMultiKey } from './dimensions'\n\n// --------------------------------------------------------\n// Theme Mode Callback\n// --------------------------------------------------------\nconst MODE_CALLBACK_BRAND = Symbol.for('pyreon.themeModeCallback')\n\n/** Creates a mode-switching function that returns the light or dark value based on the active mode. */\nexport const themeModeCallback: ThemeModeCallback = (light, dark) => {\n const fn = (mode: string) => {\n if (!mode || mode === 'light') return light\n return dark\n }\n ;(fn as unknown as Record<string, unknown>).__brand = MODE_CALLBACK_BRAND\n return fn\n}\n\n// --------------------------------------------------------\n// Theme Mode Callback Check\n// --------------------------------------------------------\n/** Detects whether a value is a `themeModeCallback` function via Symbol brand. */\ntype IsModeCallback = (value: unknown) => boolean\nconst isModeCallback: IsModeCallback = (value: unknown) =>\n typeof value === 'function' &&\n (value as unknown as Record<string, unknown>).__brand === MODE_CALLBACK_BRAND\n\n// --------------------------------------------------------\n// Get Theme From Chain\n// --------------------------------------------------------\n/** Reduces an array of chained `.theme()` callbacks into a single merged theme object. */\ntype OptionFunc = (...arg: any) => Record<string, unknown>\ntype GetThemeFromChain = (\n options: OptionFunc[] | undefined | null,\n theme: Record<string, any>,\n) => ReturnType<OptionFunc>\n\nexport const getThemeFromChain: GetThemeFromChain = (options, theme) => {\n const result = {}\n if (!options || isEmpty(options)) return result\n\n return options.reduce(\n (acc, item) => merge(acc, item(theme, themeModeCallback, config.css)),\n result,\n )\n}\n\n// --------------------------------------------------------\n// calculate dimension themes\n// --------------------------------------------------------\n/**\n * Computes the theme object for each dimension by evaluating its\n * chained callbacks against the global theme, then strips nullable values.\n */\ntype GetDimensionThemes = (\n theme: Record<string, any>,\n options: Record<string, any>,\n) => Record<string, any>\n\nexport const getDimensionThemes: GetDimensionThemes = (theme, options) => {\n const result = {}\n\n if (isEmpty(options.dimensions)) return result\n\n return Object.entries(options.dimensions).reduce(\n (acc, [key, value]) => {\n const [, dimension] = isMultiKey(value as string | Record<string, unknown>)\n\n const helper = options[key]\n\n if (Array.isArray(helper) && helper.length > 0) {\n const finalDimensionThemes = getThemeFromChain(helper, theme)\n\n acc[dimension] = removeNullableValues(finalDimensionThemes)\n }\n\n return acc\n },\n result as Record<string, any>,\n )\n}\n\n// --------------------------------------------------------\n// combine values\n// --------------------------------------------------------\n/** Reduces an array of option callbacks by calling each with the given args and deep-merging results. */\ntype CalculateChainOptions = (\n options: OptionFunc[] | undefined | null,\n args: any[],\n) => Record<string, any>\n\nexport const calculateChainOptions: CalculateChainOptions = (options, args) => {\n const result = {}\n if (!options || isEmpty(options)) return result\n\n return options.reduce((acc, item) => merge(acc, item(...args)), result)\n}\n\n// --------------------------------------------------------\n// generate theme\n// --------------------------------------------------------\n/**\n * Generates the final theme object by starting with the base theme\n * and merging in dimension-specific theme slices based on the current\n * rocketstate (active dimension values). Supports multi-key dimensions.\n *\n * Transform dimensions (marked with `transform: true`) are evaluated last.\n * Their values are functions that receive the fully accumulated theme and\n * return overrides — enabling derived styles like \"outlined\" or \"inversed\".\n */\nexport type GetTheme = (params: {\n rocketstate: Record<string, string | string[]>\n themes: Record<string, Record<string, any>>\n baseTheme: Record<string, any>\n transformKeys?: Partial<Record<string, true>>\n /** App theme from context — passed to transform dimension callbacks. */\n appTheme?: Record<string, any>\n}) => Record<string, unknown>\n\nexport const getTheme: GetTheme = ({ rocketstate, themes, baseTheme, transformKeys, appTheme }) => {\n let finalTheme = { ...baseTheme }\n const deferredTransforms: Array<\n (\n currentTheme: Record<string, any>,\n currentAppTheme: Record<string, any>,\n mode: typeof themeModeCallback,\n cssFn: typeof config.css,\n ) => Record<string, any>\n > = []\n\n Object.entries(rocketstate).forEach(([key, value]: [string, string | string[]]) => {\n const keyTheme: Record<string, any> = themes[key] ?? {}\n const isTransform = transformKeys?.[key]\n\n const mergeValue = (item: string) => {\n const val = keyTheme[item]\n if (isTransform && typeof val === 'function') {\n deferredTransforms.push(val)\n } else {\n finalTheme = merge({}, finalTheme, val)\n }\n }\n\n if (Array.isArray(value)) {\n value.forEach(mergeValue)\n } else {\n mergeValue(value)\n }\n })\n\n // Apply transform dimension values last with the fully accumulated theme\n for (const transform of deferredTransforms) {\n finalTheme = merge(\n {},\n finalTheme,\n transform(finalTheme, appTheme ?? {}, themeModeCallback, config.css),\n )\n }\n\n // Ensure pseudo-state keys always exist as objects so .styles() can\n // destructure without defaults: const { hover, focus, ... } = $rocketstyle\n finalTheme.hover ??= {}\n finalTheme.focus ??= {}\n finalTheme.active ??= {}\n finalTheme.disabled ??= {}\n finalTheme.pressed ??= {}\n finalTheme.readOnly ??= {}\n\n return finalTheme\n}\n\n// --------------------------------------------------------\n// resolve theme by mode\n// --------------------------------------------------------\n/**\n * Recursively traverses a theme object and resolves any `themeModeCallback`\n * functions to their concrete light or dark values for the given mode.\n */\nexport type GetThemeByMode = (\n object: Record<string, any>,\n mode: 'light' | 'dark',\n) => Partial<{\n baseTheme: Record<string, unknown>\n themes: Record<string, unknown>\n}>\n\nexport const getThemeByMode: GetThemeByMode = (object, mode) =>\n Object.keys(object).reduce(\n (acc, key) => {\n const value = object[key]\n\n if (typeof value === 'object' && value !== null) {\n acc[key] = getThemeByMode(value, mode)\n } else if (isModeCallback(value)) {\n acc[key] = value(mode)\n } else {\n acc[key] = value\n }\n\n return acc\n },\n {} as Record<string, any>,\n )\n","import { compose, config, hoistNonReactStatics, omit, pick, render } from '@pyreon/ui-core'\nimport { LocalThemeManager } from './cache'\nimport { CONFIG_KEYS, PSEUDO_KEYS, PSEUDO_META_KEYS, STYLING_KEYS } from './constants'\nimport createLocalProvider from './context/createLocalProvider'\nimport { useLocalContext } from './context/localContext'\nimport { rocketstyleAttrsHoc } from './hoc'\nimport { useTheme } from './hooks'\nimport type { Configuration, ExtendedConfiguration } from './types/configuration'\nimport type { RocketComponent } from './types/rocketComponent'\nimport type { InnerComponentProps, RocketStyleComponent } from './types/rocketstyle'\nimport type { ComponentFn } from './types/utils'\nimport { calculateChainOptions, calculateStylingAttrs, pickStyledAttrs } from './utils/attrs'\nimport { chainOptions, chainOrOptions, chainReservedKeyOptions } from './utils/chaining'\nimport { calculateHocsFuncs } from './utils/compose'\nimport { getDimensionsMap } from './utils/dimensions'\nimport { createStaticsChainingEnhancers, createStaticsEnhancers } from './utils/statics'\nimport { calculateStyles } from './utils/styles'\nimport { getDimensionThemes, getTheme, getThemeByMode, getThemeFromChain } from './utils/theme'\n\n/**\n * Core rocketstyle component factory. Creates a fully-featured Pyreon component\n * that integrates theme management (with light/dark mode support), multi-tier\n * WeakMap caching, dimension-based styling props, pseudo-state detection, and\n * chainable static methods (`.attrs()`, `.theme()`, `.styles()`, `.config()`, etc.).\n *\n * In Pyreon, components are plain functions that run once per mount.\n * No forwardRef, useMemo, useState — ref flows as a normal prop.\n */\n\n// --------------------------------------------------------\n// cloneAndEnhance\n// --------------------------------------------------------\ntype CloneAndEnhance = (\n defaultOpts: Configuration,\n opts: Partial<ExtendedConfiguration>,\n) => ReturnType<typeof rocketComponent>\n\n/** Clones the current configuration and merges new options, returning a fresh rocketComponent. */\nconst cloneAndEnhance: CloneAndEnhance = (defaultOpts, opts) =>\n rocketComponent({\n ...defaultOpts,\n attrs: chainOptions(opts.attrs, defaultOpts.attrs),\n filterAttrs: [...(defaultOpts.filterAttrs ?? []), ...(opts.filterAttrs ?? [])],\n priorityAttrs: chainOptions(opts.priorityAttrs, defaultOpts.priorityAttrs),\n statics: { ...defaultOpts.statics, ...opts.statics },\n compose: { ...defaultOpts.compose, ...opts.compose },\n ...chainOrOptions(CONFIG_KEYS, opts, defaultOpts),\n ...chainReservedKeyOptions([...defaultOpts.dimensionKeys, ...STYLING_KEYS], opts, defaultOpts),\n } as Parameters<typeof rocketComponent>[0])\n\n// --------------------------------------------------------\n// rocketComponent\n// --------------------------------------------------------\n// @ts-expect-error\nconst rocketComponent: RocketComponent = (options) => {\n const { component, styles } = options\n const { styled } = config\n\n const _calculateStylingAttrs = calculateStylingAttrs({\n multiKeys: options.multiKeys,\n useBooleans: options.useBooleans,\n })\n\n const componentName = options.name ?? options.component.displayName ?? options.component.name\n\n // Create styled component with all options.styles if available.\n // Rocketstyle CSS lives in `@layer rocketstyle`, which is declared\n // AFTER `@layer elements` in the cascade ordering (see sheet.ts).\n // This ensures rocketstyle theme styles always override element base\n // styles regardless of source order.\n const STYLED_COMPONENT =\n (component.IS_ROCKETSTYLE ?? options.styled !== true)\n ? component\n : styled(component, { layer: 'rocketstyle' })`\n ${calculateStyles(styles)};\n `\n\n // --------------------------------------------------------\n // COMPONENT - Final component to be rendered\n // --------------------------------------------------------\n const RenderComponent: ComponentFn<any> = options.provider\n ? createLocalProvider(STYLED_COMPONENT)\n : STYLED_COMPONENT\n\n // --------------------------------------------------------\n // THEME - Cached & Calculated theme(s)\n // --------------------------------------------------------\n const ThemeManager = new LocalThemeManager()\n\n // --------------------------------------------------------\n // COMPOSE - high-order components\n // --------------------------------------------------------\n const hocsFuncs = [rocketstyleAttrsHoc(options), ...calculateHocsFuncs(options.compose)]\n\n // --------------------------------------------------------\n // ENHANCED COMPONENT\n // --------------------------------------------------------\n // In Pyreon, components are plain functions — no forwardRef needed.\n // Ref flows as a normal prop through the chain.\n const EnhancedComponent: ComponentFn<InnerComponentProps> = (props) => {\n // --------------------------------------------------\n // hover - focus - pressed state passed via context from parent component\n // --------------------------------------------------\n const localCtx = useLocalContext(options.consumer)\n\n // --------------------------------------------------\n // general theme and theme mode dark / light passed in context\n // --------------------------------------------------\n // IMPORTANT: Do NOT destructure — useTheme returns getter properties.\n // Destructuring calls getters once and captures static values.\n // Keep the object reference so mode/isDark/isLight re-evaluate lazily.\n const themeAttrs = useTheme(options)\n\n // --------------------------------------------------\n // Theme structure — cached by theme object identity.\n // Theme object itself doesn't change (enrichTheme produces a stable ref),\n // only mode switches change which mode-variant is resolved.\n // --------------------------------------------------\n const theme = themeAttrs.theme\n\n const baseThemeHelper = ThemeManager.baseTheme\n if (!baseThemeHelper.has(theme)) {\n baseThemeHelper.set(theme, getThemeFromChain(options.theme, theme))\n }\n const baseTheme = baseThemeHelper.get(theme)\n\n const dimHelper = ThemeManager.dimensionsThemes\n if (!dimHelper.has(theme)) {\n dimHelper.set(theme, getDimensionThemes(theme, options))\n }\n const themes = dimHelper.get(theme)\n\n const { keysMap: dimensions, keywords: reservedPropNames } = getDimensionsMap({\n themes,\n useBooleans: options.useBooleans,\n })\n\n const RESERVED_STYLING_PROPS_KEYS = Object.keys(reservedPropNames)\n\n // --------------------------------------------------\n // $rocketstyle as a FUNCTION ACCESSOR — fully reactive.\n // Re-evaluates when mode OR dimension props change.\n // Props are resolved fresh each call so reactive prop accessors\n // (signals, getters) produce updated dimension values.\n // --------------------------------------------------\n const $rocketstyleAccessor = () => {\n // Only read mode and dimension props — NOT pseudo state.\n // Pseudo state (hover, focus, pressed) is read by .styles()\n // via $rocketstate inside runUntracked(). Reading pseudo signals\n // here would subscribe this accessor to hover/focus/pressed,\n // causing CSS recomputation on every mouse event.\n const mode = themeAttrs.mode // reactive: tracks mode signal\n\n // Resolve active dimensions from props (not localCtx which has pseudo getters)\n const rocketstate = _calculateStylingAttrs({\n props: pickStyledAttrs(props as Record<string, unknown>, reservedPropNames),\n dimensions,\n })\n\n // Resolve mode-specific theme\n const modeBaseHelper = ThemeManager.modeBaseTheme[mode]\n if (!modeBaseHelper.has(baseTheme)) {\n modeBaseHelper.set(baseTheme, getThemeByMode(baseTheme, mode))\n }\n const currentModeBaseTheme = modeBaseHelper.get(baseTheme)\n\n const modeDimHelper = ThemeManager.modeDimensionTheme[mode]\n if (!modeDimHelper.has(themes)) {\n modeDimHelper.set(themes, getThemeByMode(themes, mode))\n }\n const currentModeThemes = modeDimHelper.get(themes)\n\n return getTheme({\n rocketstate,\n themes: currentModeThemes,\n baseTheme: currentModeBaseTheme,\n transformKeys: options.transformKeys,\n appTheme: theme,\n })\n }\n\n // --------------------------------------------------\n // $rocketstate as a FUNCTION ACCESSOR — reactive on prop changes.\n // Re-evaluates active dimensions + pseudo state from current props.\n // --------------------------------------------------\n // Capture pseudo from localCtx once at setup — pseudo properties are\n // getters (from createLocalProvider) that read signals lazily.\n // Passing them through preserves reactivity without subscribing here.\n const localPseudo = localCtx?.pseudo\n\n const $rocketstateAccessor = () => {\n const rocketstate = _calculateStylingAttrs({\n props: pickStyledAttrs(props as Record<string, unknown>, reservedPropNames),\n dimensions,\n })\n\n // Read pseudo props fresh each call — props may have reactive getters\n // from _rp() wrapping. Reading inside the accessor (which runs in an\n // effect) ensures changes to pseudo props like active={isDark()} are tracked.\n const propPseudo = pick(props, [...PSEUDO_KEYS, ...PSEUDO_META_KEYS])\n\n return {\n ...rocketstate,\n pseudo: { ...localPseudo, ...propPseudo },\n }\n }\n\n // --------------------------------------------------\n // Static mergeProps for final prop filtering (non-dimension props)\n // --------------------------------------------------\n const { pseudo: _pseudo, ...mergeProps } = {\n ...localCtx,\n ...props,\n }\n\n // --------------------------------------------------\n // final props passed to WrappedComponent\n // --------------------------------------------------\n const finalProps: Record<string, any> = {\n ...omit(mergeProps, [\n ...RESERVED_STYLING_PROPS_KEYS,\n ...PSEUDO_KEYS,\n ...options.filterAttrs,\n ]),\n ...(options.passProps ? pick(mergeProps, options.passProps) : {}),\n ref: props.ref,\n // FUNCTION accessors — styled component resolves them reactively\n $rocketstyle: $rocketstyleAccessor,\n $rocketstate: $rocketstateAccessor,\n }\n\n // development debugging\n if (process.env.NODE_ENV !== 'production') {\n finalProps['data-rocketstyle'] = componentName\n\n if (options.DEBUG) {\n const debugPayload = {\n component: componentName,\n rocketstate: $rocketstateAccessor(),\n rocketstyle: $rocketstyleAccessor(),\n dimensions,\n mode: themeAttrs.mode,\n reservedPropNames: RESERVED_STYLING_PROPS_KEYS,\n filteredAttrs: options.filterAttrs,\n }\n\n // oxlint-disable-next-line no-console\n console.debug(`[rocketstyle] ${componentName} render:`, debugPayload)\n }\n }\n\n // STATIC VNode — created once, never remounted on mode change.\n // The styled component handles reactive class swaps internally.\n return RenderComponent(finalProps)\n }\n\n // ------------------------------------------------------\n // Compose HOC chain and create final component\n // ------------------------------------------------------\n const FinalComponent: RocketStyleComponent = compose(...hocsFuncs)(EnhancedComponent)\n FinalComponent.IS_ROCKETSTYLE = true\n FinalComponent.displayName = componentName\n\n hoistNonReactStatics(FinalComponent as Record<string, unknown>, options.component)\n\n // ------------------------------------------------------\n // enhance for chaining methods\n // ------------------------------------------------------\n createStaticsChainingEnhancers({\n context: FinalComponent,\n dimensionKeys: options.dimensionKeys,\n func: cloneAndEnhance,\n options,\n })\n\n FinalComponent.IS_ROCKETSTYLE = true\n FinalComponent.displayName = componentName\n FinalComponent.meta = {}\n\n // ------------------------------------------------------\n // enhance for statics\n // ------------------------------------------------------\n createStaticsEnhancers({\n context: FinalComponent.meta,\n options: options.statics,\n })\n\n // Also assign statics directly onto the component so they are\n // discoverable via `\"key\" in Component` checks (e.g. _documentType).\n createStaticsEnhancers({\n context: FinalComponent,\n options: options.statics,\n })\n\n Object.assign(FinalComponent, {\n attrs: (attrs: any, { priority, filter }: any = {}) => {\n const result: Record<string, any> = {}\n\n if (filter) {\n result.filterAttrs = filter\n }\n\n if (priority) {\n result.priorityAttrs = attrs as ExtendedConfiguration['priorityAttrs']\n\n return cloneAndEnhance(options, result)\n }\n\n result.attrs = attrs as ExtendedConfiguration['attrs']\n\n return cloneAndEnhance(options, result)\n },\n\n config: (opts: any = {}) => {\n const result = pick(opts, CONFIG_KEYS) as ExtendedConfiguration\n\n return cloneAndEnhance(options, result)\n },\n\n statics: (opts: any) => cloneAndEnhance(options, { statics: opts }),\n\n getStaticDimensions: (theme: any) => {\n const themes = getDimensionThemes(theme, options)\n\n const { keysMap, keywords } = getDimensionsMap({\n themes,\n useBooleans: options.useBooleans,\n })\n\n return {\n dimensions: keysMap,\n keywords,\n useBooleans: options.useBooleans,\n multiKeys: options.multiKeys,\n }\n },\n\n getDefaultAttrs: (props: any, theme: any, mode: any) =>\n calculateChainOptions(options.attrs)([\n props,\n theme,\n {\n render,\n mode,\n isDark: mode === 'light',\n isLight: mode === 'dark',\n },\n ]),\n })\n\n return FinalComponent\n}\n\nexport default rocketComponent\n","import { isEmpty } from '@pyreon/ui-core'\nimport { ALL_RESERVED_KEYS } from './constants'\nimport defaultDimensions from './constants/defaultDimensions'\nimport rocketComponent from './rocketstyle'\nimport type { DefaultDimensions, Dimensions } from './types/dimensions'\nimport type { RocketComponent } from './types/rocketComponent'\nimport type { ElementType } from './types/utils'\nimport {\n getDimensionsValues,\n getKeys,\n getMultipleDimensions,\n getTransformDimensions,\n} from './utils/dimensions'\n\nexport type Rocketstyle = <\n const D extends Dimensions = DefaultDimensions,\n UB extends boolean = false,\n>({\n dimensions,\n useBooleans,\n}?: {\n dimensions?: D\n useBooleans?: UB\n}) => <C extends ElementType>({\n name,\n component,\n}: {\n name: string\n component: C\n}) => ReturnType<RocketComponent<C, {}, {}, D, UB>>\n\n/**\n * Factory initializer for rocketstyle components. Validates dimension\n * configurations against reserved keys, then delegates to the core\n * `rocketComponent` builder with pre-computed dimension metadata.\n */\ntype InitErrors = Partial<{\n component: string\n name: string\n dimensions: string\n invalidDimensions: string\n}>\n\nconst validateInit = (name: string, component: unknown, dimensions: Dimensions) => {\n const errors: InitErrors = {}\n\n if (!component) {\n errors.component = 'Parameter `component` is missing in params!'\n }\n\n if (!name) {\n errors.name = 'Parameter `name` is missing in params!'\n }\n\n if (isEmpty(dimensions)) {\n errors.dimensions = 'Parameter `dimensions` is missing in params!'\n } else {\n const definedDimensions = getKeys(dimensions)\n const invalidDimension = ALL_RESERVED_KEYS.some((item) =>\n definedDimensions.some((d) => d === item),\n )\n\n if (invalidDimension) {\n errors.invalidDimensions = `Some of your \\`dimensions\\` is invalid and uses reserved static keys which are\n ${defaultDimensions.toString()}`\n }\n }\n\n if (!isEmpty(errors)) {\n throw Error(JSON.stringify(errors))\n }\n}\n\nconst rocketstyle = (({ dimensions = defaultDimensions, useBooleans = false } = {}) =>\n ({ name, component }: { name: string; component: any }) => {\n if (process.env.NODE_ENV !== 'production') {\n validateInit(name, component, dimensions)\n }\n\n return (rocketComponent as any)({\n name,\n component,\n useBooleans,\n dimensions,\n dimensionKeys: getKeys(dimensions),\n dimensionValues: getDimensionsValues(dimensions),\n multiKeys: getMultipleDimensions(dimensions),\n transformKeys: getTransformDimensions(dimensions),\n styled: true,\n })\n }) as unknown as Rocketstyle\n\nexport default rocketstyle\n","export type IsRocketComponent = <T>(component: T) => boolean\n\n/** Runtime type guard — checks if a component was created by `rocketstyle()`. */\nconst isRocketComponent: IsRocketComponent = (component) => {\n if (\n component &&\n (typeof component === 'object' || typeof component === 'function') &&\n Object.hasOwn(component as object, 'IS_ROCKETSTYLE')\n ) {\n return true\n }\n\n return false\n}\n\nexport default isRocketComponent\n","import type { TProvider } from './context/context'\nimport Provider, { context } from './context/context'\nimport type { Rocketstyle } from './init'\nimport rocketstyle from './init'\nimport type { IsRocketComponent } from './isRocketComponent'\nimport isRocketComponent from './isRocketComponent'\nimport type { AttrsCb } from './types/attrs'\nimport type {\n ConfigAttrs,\n ConsumerCb,\n ConsumerCtxCBValue,\n ConsumerCtxCb,\n RocketComponentType,\n RocketProviderState,\n} from './types/config'\nimport type { DefaultProps } from './types/configuration'\nimport type {\n DimensionCallbackParam,\n DimensionProps,\n Dimensions,\n DimensionValue,\n ExtractDimensionProps,\n ExtractDimensions,\n TDKP,\n} from './types/dimensions'\nimport type { ComposeParam, GenericHoc } from './types/hoc'\nimport type { IRocketStyleComponent, RocketStyleComponent } from './types/rocketstyle'\nimport type { RocketStyleInterpolationProps, StylesCb, StylesDefault } from './types/styles'\nimport type {\n ThemeCb,\n ThemeDefault,\n ThemeMode,\n ThemeModeCallback,\n ThemeModeKeys,\n} from './types/theme'\nimport type { ComponentFn, ElementType, ExtractProps, MergeTypes, TObj } from './types/utils'\n\nexport type {\n AttrsCb,\n ComponentFn,\n ComposeParam,\n ConfigAttrs,\n ConsumerCb,\n ConsumerCtxCBValue,\n ConsumerCtxCb,\n DefaultProps,\n DimensionCallbackParam,\n DimensionProps,\n Dimensions,\n DimensionValue,\n ElementType,\n ExtractDimensionProps,\n ExtractDimensions,\n ExtractProps,\n GenericHoc,\n IRocketStyleComponent,\n IsRocketComponent,\n MergeTypes,\n RocketComponentType,\n RocketProviderState,\n RocketStyleComponent,\n RocketStyleInterpolationProps,\n Rocketstyle,\n StylesCb,\n StylesDefault,\n TDKP,\n ThemeCb,\n ThemeDefault,\n ThemeMode,\n ThemeModeCallback,\n ThemeModeKeys,\n TObj,\n TProvider,\n}\n\n/**\n * Resolve a $rocketstyle value — handles both function accessor and plain object.\n * Use in styled() interpolation functions when $rocketstyle may be a reactive accessor.\n *\n * @example\n * ```ts\n * styled(Component)`\n * color: ${(props) => resolveTheme(props.$rocketstyle).color};\n * `\n * ```\n */\nexport function resolveTheme<T = Record<string, unknown>>(\n value: (() => T) | T,\n): T {\n return typeof value === 'function' ? (value as () => T)() : value\n}\n\nexport { context, isRocketComponent, Provider, rocketstyle }\nexport default rocketstyle\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["CoreProvider","useTheme","ThemeManager","LocalThemeManager","rocketstyleAttrsHoc","useTheme","defaultDimensions"],"sources":["../src/constants/index.ts","../src/context/context.ts","../src/constants/defaultDimensions.ts","../src/cache/LocalThemeManager.ts","../src/context/localContext.ts","../src/context/createLocalProvider.ts","../src/hooks/useTheme.ts","../src/utils/attrs.ts","../src/hoc/rocketstyleAttrsHoc.ts","../src/utils/chaining.ts","../src/utils/compose.ts","../src/utils/dimensions.ts","../src/utils/statics.ts","../src/utils/styles.ts","../src/utils/collection.ts","../src/utils/theme.ts","../src/rocketstyle.ts","../src/init.ts","../src/isRocketComponent.ts","../src/index.ts"],"sourcesContent":["/** Default theme mode used when no mode is provided via context. */\nexport const MODE_DEFAULT = 'light'\n\n/** Pseudo-state interaction keys tracked for styling (hover, active, focus, pressed). */\nexport const PSEUDO_KEYS = ['hover', 'active', 'focus', 'pressed'] as const\n\n/** Meta pseudo-state keys representing non-interactive states (disabled, readOnly). */\nexport const PSEUDO_META_KEYS = ['disabled', 'readOnly'] as const\n\n/** Supported theme mode flags. */\nexport const THEME_MODES = {\n light: true,\n dark: true,\n} as const\n\n/** Maps each theme mode to its inverse (light -> dark, dark -> light). */\nexport const THEME_MODES_INVERSED = {\n dark: 'light',\n light: 'dark',\n} as const\n\n/** Reserved configuration keys accepted by the `.config()` chaining method. */\nexport const CONFIG_KEYS = [\n 'provider',\n 'consumer',\n 'DEBUG',\n 'name',\n 'component',\n 'inversed',\n 'passProps',\n 'styled',\n] as const\n\n/** Keys for theme and styles chaining methods. */\nexport const STYLING_KEYS = ['theme', 'styles'] as const\nexport const STATIC_KEYS = [...STYLING_KEYS, 'compose'] as const\n\n/** Union of all reserved keys that cannot be used as dimension names. */\nexport const ALL_RESERVED_KEYS = [\n ...Object.keys(THEME_MODES),\n ...CONFIG_KEYS,\n ...STATIC_KEYS,\n 'attrs',\n] as const\n","import type { VNodeChild } from '@pyreon/core'\nimport { useContext } from '@pyreon/core'\nimport { Provider as CoreProvider, context } from '@pyreon/ui-core'\nimport { MODE_DEFAULT, THEME_MODES_INVERSED } from '../constants'\n\ntype Theme = {\n rootSize: number\n breakpoints?: Record<string, number>\n} & Record<string, unknown>\n\nexport type TProvider = {\n children: VNodeChild\n theme?: Theme | undefined\n mode?: 'light' | 'dark' | undefined\n inversed?: boolean | undefined\n provider?: ((props: Record<string, unknown>) => VNodeChild) | undefined\n}\n\n/**\n * Top-level theme and mode provider for rocketstyle components.\n * Reads the parent context, merges incoming props, and resolves\n * the active mode (with optional inversion for nested dark/light switching).\n *\n * In Pyreon, context is provided via provide() instead of React.Provider.\n */\nconst Provider = ({ provider = CoreProvider, inversed, ...props }: TProvider): VNodeChild => {\n const getCtx = useContext(context)\n const ctx = getCtx()\n\n const merged = { ...ctx, ...props, provider } as unknown as TProvider & Record<string, unknown>\n const { theme, mode, provider: RocketstyleProvider, children } = merged\n\n let newMode = MODE_DEFAULT\n\n if (mode) {\n newMode = inversed ? THEME_MODES_INVERSED[mode] : mode\n }\n\n const FinalProvider = RocketstyleProvider ?? CoreProvider\n const result = FinalProvider({\n mode: newMode,\n isDark: newMode === 'dark',\n isLight: newMode === 'light',\n ...(theme !== undefined ? { theme } : {}),\n provider,\n children,\n })\n\n return result ?? null\n}\n\nexport { context }\n\nexport default Provider\n","/**\n * Default dimension configuration for rocketstyle components.\n * Defines four built-in dimensions: `states`, `sizes`, `variants`,\n * and `multiple` (a multi-select dimension).\n */\nconst DEFAULT_DIMENSIONS = {\n states: 'state',\n sizes: 'size',\n variants: 'variant',\n multiple: {\n propName: 'multiple',\n multi: true,\n },\n modifiers: {\n propName: 'modifier',\n multi: true,\n transform: true,\n },\n} as const\n\nexport type DefaultDimensions = typeof DEFAULT_DIMENSIONS\n\nexport default DEFAULT_DIMENSIONS\n","/**\n * WeakMap-based multi-tier cache for computed theme objects.\n * Maintains separate caches for base themes, dimension themes,\n * and their light/dark mode variants to avoid recalculation on re-renders.\n */\nexport default class ThemeManager {\n baseTheme = new WeakMap()\n\n dimensionsThemes = new WeakMap()\n\n modeBaseTheme = { light: new WeakMap(), dark: new WeakMap() }\n\n modeDimensionTheme = { light: new WeakMap(), dark: new WeakMap() }\n}\n","import { createContext, useContext } from '@pyreon/core'\nimport type { PseudoState } from '../types/pseudo'\n\ntype LocalContext = Partial<\n {\n pseudo: PseudoState\n } & Record<string, string>\n>\n\n/**\n * Local context for propagating pseudo-state (hover, focus, pressed)\n * and additional styling attributes from a parent provider component\n * to its rocketstyle children.\n */\nconst localContext = createContext<LocalContext>({})\n\nconst EMPTY_CTX = { pseudo: {} } as LocalContext\n\n/**\n * Retrieves the local pseudo-state context. When a consumer callback\n * is provided, it transforms the raw context; otherwise returns defaults.\n *\n * In Pyreon, components are plain functions that run once — no useMemo needed.\n */\ntype UseLocalContext = (consumer: any) => LocalContext\nexport const useLocalContext: UseLocalContext = (consumer) => {\n const ctx = useContext(localContext)\n\n if (!consumer) return EMPTY_CTX\n\n const result = consumer((callback: any) => callback(ctx))\n return { pseudo: {}, ...result }\n}\n\nexport { localContext }\n\nexport default localContext\n","import { provide } from '@pyreon/core'\nimport { signal } from '@pyreon/reactivity'\nimport type { PseudoProps } from '../types/pseudo'\nimport type { ComponentFn } from '../types/utils'\nimport { localContext } from './localContext'\n\ntype Props = PseudoProps & Record<string, any>\n\n/**\n * Higher-order component that wraps a component with a LocalProvider,\n * detecting pseudo-states (hover, focus, pressed) via mouse/focus events\n * and broadcasting them through local context to child rocketstyle components.\n *\n * In Pyreon, context is provided via provide(), and state is managed\n * with signals instead of useState.\n */\nconst createLocalProvider = (WrappedComponent: ComponentFn<any>) => {\n const HOCComponent: ComponentFn<Props> = ({\n onMouseEnter,\n onMouseLeave,\n onMouseUp,\n onMouseDown,\n onFocus,\n onBlur,\n $rocketstate,\n ...props\n }) => {\n const hover = signal(false)\n const focus = signal(false)\n const pressed = signal(false)\n\n const events = {\n onMouseEnter: (e: MouseEvent) => {\n hover.set(true)\n if (onMouseEnter) onMouseEnter(e)\n },\n onMouseLeave: (e: MouseEvent) => {\n hover.set(false)\n pressed.set(false)\n if (onMouseLeave) onMouseLeave(e)\n },\n onMouseDown: (e: MouseEvent) => {\n pressed.set(true)\n if (onMouseDown) onMouseDown(e)\n },\n onMouseUp: (e: MouseEvent) => {\n pressed.set(false)\n if (onMouseUp) onMouseUp(e)\n },\n onFocus: (e: FocusEvent) => {\n focus.set(true)\n if (onFocus) onFocus(e)\n },\n onBlur: (e: FocusEvent) => {\n focus.set(false)\n if (onBlur) onBlur(e)\n },\n }\n\n // Use getters so pseudo-state signals are read lazily by consumers\n // inside their own reactive scopes — NOT eagerly during parent setup.\n // Without getters, hover()/focus()/pressed() reads here would register\n // as dependencies of any parent effect, causing cascading re-renders\n // on every mouse event.\n // Resolve $rocketstate if it's a function accessor (from EnhancedComponent)\n const resolvedState =\n typeof $rocketstate === 'function' ? $rocketstate() : $rocketstate\n const updatedState = {\n ...resolvedState,\n pseudo: {\n ...resolvedState?.pseudo,\n get hover() {\n return hover()\n },\n get focus() {\n return focus()\n },\n get pressed() {\n return pressed()\n },\n },\n }\n\n // Provide local context for child rocketstyle components\n provide(localContext, updatedState)\n\n return WrappedComponent({\n ...props,\n ...events,\n $rocketstate: updatedState,\n })\n }\n\n return HOCComponent\n}\n\nexport default createLocalProvider\n","import { useContext } from '@pyreon/core'\nimport { THEME_MODES_INVERSED } from '../constants'\nimport { context } from '../context/context'\nimport type { ThemeModeKeys } from '../types/theme'\n\ntype Context = {\n theme: Record<string, unknown>\n mode: ThemeModeKeys\n isDark: boolean\n isLight: boolean\n}\n\ntype UseThemeAttrs = ({ inversed }: { inversed?: boolean | undefined }) => Context\n\n/**\n * Retrieves the current theme object and resolved mode from context.\n *\n * Returns an object with getter properties so that mode/isDark/isLight\n * are evaluated lazily on each access. The context is a ReactiveContext,\n * so useContext returns `() => CoreContextValue` — we call it inside\n * each getter to ensure reactive tracking.\n */\nconst useThemeAttrs: UseThemeAttrs = ({ inversed }) => {\n // ReactiveContext: useContext returns () => CoreContextValue.\n // Call the getter inside each property getter for reactive tracking.\n const getCtx = useContext(context)\n\n return {\n get theme() {\n return getCtx().theme ?? ({} as Record<string, unknown>)\n },\n get mode() {\n const ctxMode = getCtx().mode ?? 'light'\n return inversed ? THEME_MODES_INVERSED[ctxMode] : ctxMode\n },\n get isDark() {\n const ctxDark = getCtx().isDark ?? false\n return inversed ? !ctxDark : ctxDark\n },\n get isLight() {\n const ctxDark = getCtx().isDark ?? false\n const isDark = inversed ? !ctxDark : ctxDark\n return !isDark\n },\n }\n}\n\nexport default useThemeAttrs\n","import type { MultiKeys } from '../types/dimensions'\n\n// --------------------------------------------------------\n// remove undefined props\n// --------------------------------------------------------\n/** Strips keys with `undefined` values so they don't shadow default props during merging. */\ntype RemoveUndefinedProps = <T extends Record<string, any>>(props: T) => Partial<T>\n\nexport const removeUndefinedProps: RemoveUndefinedProps = (props) => {\n const result: Partial<typeof props> = {}\n for (const key in props) {\n if (props[key] !== undefined) result[key] = props[key]\n }\n return result\n}\n\n// --------------------------------------------------------\n// pick styled props\n// --------------------------------------------------------\n/** Picks only the props whose keys exist in the dimension keywords lookup and have truthy values. */\nexport const pickStyledAttrs = <\n T extends Record<string, any>,\n K extends Record<string, true | undefined>,\n>(\n props: T,\n keywords: K,\n): { [I in keyof K & keyof T]: T[I] } => {\n const result: Record<string, unknown> = {}\n for (const key of Object.keys(props)) {\n if (keywords[key] && props[key]) result[key] = props[key]\n }\n return result as { [I in keyof K & keyof T]: T[I] }\n}\n\n// --------------------------------------------------------\n// combine values\n// --------------------------------------------------------\n/**\n * Returns a curried function that evaluates an array of `.attrs()` callbacks,\n * spreading each result into a single merged props object via `Object.assign`.\n */\ntype OptionFunc<A> = (...arg: A[]) => Record<string, unknown>\ntype CalculateChainOptions = <A>(\n options?: OptionFunc<A>[],\n) => (args: A[]) => ReturnType<OptionFunc<A>>\n\nexport const calculateChainOptions: CalculateChainOptions = (options) => (args) => {\n if (!options || options.length === 0) return {}\n\n return options.reduce<Record<string, unknown>>(\n (acc, item) => Object.assign(acc, item(...args)),\n {},\n )\n}\n\n// --------------------------------------------------------\n// get style attributes\n// --------------------------------------------------------\n/**\n * Resolves the active value for each styling dimension from component props.\n * First checks for explicit prop values (string, number, or array for multi-keys),\n * then falls back to boolean shorthand props when `useBooleans` is enabled.\n */\ntype CalculateStylingAttrs = ({\n useBooleans,\n multiKeys,\n}: {\n useBooleans?: boolean\n multiKeys?: MultiKeys\n}) => ({\n props,\n dimensions,\n}: {\n props: Record<string, unknown>\n dimensions: Record<string, unknown>\n}) => Record<string, any>\nexport const calculateStylingAttrs: CalculateStylingAttrs =\n ({ useBooleans, multiKeys }) =>\n ({ props, dimensions }) => {\n const result: Record<string, any> = {}\n\n // (1) find dimension keys values & initialize\n // object with possible options\n Object.keys(dimensions).forEach((item) => {\n const pickedProp = props[item]\n const t = typeof pickedProp\n\n // if the property is multi key, allow assign array as well\n if (multiKeys?.[item] && Array.isArray(pickedProp)) {\n result[item] = pickedProp\n }\n // assign when it's only a string or number otherwise it's considered\n // as invalid param\n else if (t === 'string' || t === 'number') {\n result[item] = pickedProp\n } else {\n result[item] = undefined\n }\n })\n\n // (2) if booleans are being used let's find the rest\n if (useBooleans) {\n const propsKeys = Object.keys(props)\n\n Object.entries(result).forEach(([key, value]) => {\n const isMultiKey = multiKeys?.[key]\n\n // when value in result is not assigned yet\n if (!value) {\n let newDimensionValue: string | string[] | undefined\n const keywordSet = new Set(Object.keys(dimensions[key] as Record<string, unknown>))\n\n if (isMultiKey) {\n newDimensionValue = propsKeys.filter((propKey) => keywordSet.has(propKey))\n } else {\n // iterate backwards to guarantee the last one will have\n // a priority over previous ones\n for (let i = propsKeys.length - 1; i >= 0; i--) {\n const k = propsKeys[i] as string\n if (keywordSet.has(k) && props[k]) {\n newDimensionValue = k\n break\n }\n }\n }\n\n result[key] = newDimensionValue\n }\n })\n }\n\n return result\n }\n","import { render } from '@pyreon/ui-core'\nimport { useTheme } from '../hooks'\nimport type { Configuration } from '../types/configuration'\nimport type { ComponentFn } from '../types/utils'\nimport { calculateChainOptions, removeUndefinedProps } from '../utils/attrs'\n\nexport type RocketStyleHOC = ({\n inversed,\n attrs,\n priorityAttrs,\n}: Pick<Configuration, 'inversed' | 'attrs' | 'priorityAttrs'>) => (\n WrappedComponent: ComponentFn<any>,\n) => ComponentFn<any>\n\n/**\n * HOC that resolves the `.attrs()` chain before the inner component renders.\n * Evaluates both regular and priority attrs callbacks with the current theme\n * and mode, then merges the results with explicit props (priority attrs\n * are applied first, regular attrs can be overridden by direct props).\n *\n * In Pyreon, there is no forwardRef — ref flows as a normal prop.\n * Components are plain functions.\n */\nconst rocketStyleHOC: RocketStyleHOC = ({ inversed, attrs, priorityAttrs }) => {\n const calculateAttrs = calculateChainOptions(attrs)\n const calculatePriorityAttrs = calculateChainOptions(priorityAttrs)\n\n const Enhanced = (WrappedComponent: ComponentFn<any>) => {\n const HOCComponent: ComponentFn<any> = (props) => {\n // IMPORTANT: Do NOT destructure — useTheme returns getter properties.\n // Destructuring calls getters once and captures static values.\n // Keep the object reference so properties re-evaluate lazily.\n const themeAttrs = useTheme({ inversed })\n\n // Remove undefined props not to override potential default props\n const filteredProps = removeUndefinedProps(props)\n\n // Read theme attrs eagerly — .attrs() callbacks run once at mount.\n // Mode-dependent styling is handled reactively by the $rocketstyle\n // accessor in EnhancedComponent, not by re-running attrs.\n const callbackParams = [\n themeAttrs.theme,\n { render, mode: themeAttrs.mode, isDark: themeAttrs.isDark, isLight: themeAttrs.isLight },\n ]\n\n const prioritizedAttrs = calculatePriorityAttrs([filteredProps, ...callbackParams])\n\n const finalAttrs = calculateAttrs([\n {\n ...prioritizedAttrs,\n ...filteredProps,\n },\n ...callbackParams,\n ])\n\n const finalProps = {\n ...prioritizedAttrs,\n ...finalAttrs,\n ...filteredProps,\n }\n\n return WrappedComponent(finalProps)\n }\n return HOCComponent\n }\n\n return Enhanced\n}\n\nexport default rocketStyleHOC\n","type Func = (...args: any) => Record<string, unknown>\ntype Obj = Record<string, unknown>\n\n// --------------------------------------------------------\n// Chain Options\n// --------------------------------------------------------\n/**\n * Appends a new option (function or plain object) to an existing chain\n * of option callbacks. Objects are wrapped in a thunk for uniform handling.\n */\ntype ChainOptions = (opts: Obj | Func | undefined, defaultOpts: Func[]) => Func[]\n\nexport const chainOptions: ChainOptions = (opts, defaultOpts = []) => {\n const result = [...defaultOpts]\n\n if (typeof opts === 'function') result.push(opts)\n else if (typeof opts === 'object') result.push(() => opts)\n\n return result\n}\n\n// --------------------------------------------------------\n// Chain Or Options\n// --------------------------------------------------------\n/**\n * For each key, picks the new value if truthy, otherwise falls back\n * to the default. Used for config keys that replace rather than merge.\n */\ntype ChainOrOptions = (\n keys: readonly string[],\n opts: Obj,\n defaultOpts: Obj,\n) => Record<string, unknown>\n\nexport const chainOrOptions: ChainOrOptions = (keys, opts, defaultOpts) =>\n keys.reduce((acc, item) => ({ ...acc, [item]: opts[item] || defaultOpts[item] }), {})\n\n// --------------------------------------------------------\n// Chain Reserved Options\n// --------------------------------------------------------\n/**\n * Chains option callbacks for reserved dimension and styling keys,\n * delegating to `chainOptions` for each key individually.\n */\ntype ChainReservedKeyOptions = (\n keys: readonly string[],\n opts: Record<string, Obj | Func>,\n defaultOpts: Record<string, Func[]>,\n) => Record<string, ReturnType<typeof chainOptions>>\n\nexport const chainReservedKeyOptions: ChainReservedKeyOptions = (keys, opts, defaultOpts) =>\n keys.reduce(\n (acc, item) => ({\n ...acc,\n [item]: chainOptions(opts[item], defaultOpts[item] ?? []),\n }),\n {},\n )\n","/**\n * Extracts HOC functions from the compose configuration object,\n * filters out non-function entries, and reverses them so the\n * outermost HOC in the chain wraps first (inside-out composition).\n */\ntype CalculateHocsFuncs = (options: Record<string, any>) => ((arg: any) => any)[]\n\nexport const calculateHocsFuncs: CalculateHocsFuncs = (options = {}) =>\n Object.values(options)\n .filter((item) => typeof item === 'function')\n .reverse()\n","import { get, isEmpty, set } from '@pyreon/ui-core'\nimport type { Dimensions, DimensionValue, MultiKeys } from '../types/dimensions'\n\n// --------------------------------------------------------\n// Is value a valid key\n// --------------------------------------------------------\n/** Checks whether a dimension value is defined and not explicitly disabled (false). */\ntype IsValidKey = (value: any) => boolean\nexport const isValidKey: IsValidKey = (value) =>\n value !== undefined && value !== null && value !== false\n\n// --------------------------------------------------------\n// Is value a multi key\n// --------------------------------------------------------\n/** Determines if a dimension value is a multi-key config object, returning [isMulti, propName]. */\ntype IsMultiKey = (value: string | Record<string, unknown>) => [boolean, string]\nexport const isMultiKey: IsMultiKey = (value) => {\n if (typeof value === 'object' && value !== null) return [true, get(value, 'propName') as string]\n return [false, value]\n}\n\n// --------------------------------------------------------\n// calculate dimensions map\n// --------------------------------------------------------\n/**\n * Builds a two-level map (`keysMap`) of dimension -> option -> true,\n * and a flat `keywords` lookup of all prop names reserved by dimensions\n * (including boolean shorthand keys when `useBooleans` is enabled).\n */\ntype GetDimensionsMap = <T extends Record<string, any>>({\n themes,\n useBooleans,\n}: {\n themes: T\n useBooleans?: boolean\n}) => { keysMap: Record<string, any>; keywords: Record<string, any> }\n\nexport const getDimensionsMap: GetDimensionsMap = ({ themes, useBooleans }) => {\n const result = {\n keysMap: {} as Record<string, any>,\n keywords: {} as Record<string, any>,\n }\n\n if (isEmpty(themes)) return result\n\n return Object.entries(themes).reduce((accumulator, [key, value]) => {\n const { keysMap, keywords } = accumulator\n keywords[key] = true\n\n Object.entries(value).forEach(([itemKey, itemValue]) => {\n if (!isValidKey(itemValue)) return\n\n if (useBooleans) {\n keywords[itemKey] = true\n }\n\n set(keysMap, [key, itemKey], true)\n })\n\n return accumulator\n }, result)\n}\n\n// --------------------------------------------------------\n// simple object getters\n// --------------------------------------------------------\n/** Returns the keys of an object with proper typing. */\ntype GetKeys = <T extends Record<string, unknown>>(obj: T) => Array<keyof T>\nexport const getKeys: GetKeys = (obj) => Object.keys(obj)\n\ntype GetValues = <T extends Record<string, unknown>, K extends keyof T>(obj: T) => T[K][]\nexport const getValues = (<T extends Record<string, unknown>>(obj: T) =>\n Object.values(obj)) as GetValues\n\n// --------------------------------------------------------\n// get dimensions values array\n// --------------------------------------------------------\n/** Extracts the prop name from each dimension value, unwrapping multi-key config objects. */\ntype ValueType<T> = T extends string ? T : T[][0]\ntype GetDimensionsValues = <T extends Dimensions, K extends keyof T>(obj: T) => ValueType<T[K]>[]\n\nexport const getDimensionsValues = (<T extends Dimensions>(obj: T) =>\n getValues(obj).map((item: DimensionValue) => {\n if (typeof item === 'object') {\n return item.propName as string\n }\n\n return item\n })) as GetDimensionsValues\n\n// --------------------------------------------------------\n// get multiple dimensions map\n// --------------------------------------------------------\n/** Builds a lookup of dimension prop names that accept multiple simultaneous values. */\ntype GetMultipleDimensions = <T extends Dimensions>(obj: T) => MultiKeys<T>\n\nexport const getMultipleDimensions: GetMultipleDimensions = (obj) =>\n getValues(obj).reduce(\n (accumulator, value: DimensionValue) => {\n if (typeof value === 'object') {\n if (value.multi === true) accumulator[value.propName] = true\n }\n\n return accumulator\n },\n {} as Record<string, true>,\n )\n\n// --------------------------------------------------------\n// get transform dimensions map\n// --------------------------------------------------------\n/** Builds a lookup of dimension prop names that are transform dimensions (evaluated last with function values). */\ntype TransformKeys = Partial<Record<string, true>>\ntype GetTransformDimensions = <T extends Dimensions>(obj: T) => TransformKeys\n\nexport const getTransformDimensions: GetTransformDimensions = (obj) =>\n getValues(obj).reduce(\n (accumulator, value: DimensionValue) => {\n if (typeof value === 'object') {\n if (value.transform === true) accumulator[value.propName] = true\n }\n\n return accumulator\n },\n {} as Record<string, true>,\n )\n","import { isEmpty } from '@pyreon/ui-core'\nimport { STATIC_KEYS } from '../constants'\n\n// --------------------------------------------------------\n// helpers for create statics chaining methods on component\n// --------------------------------------------------------\n/**\n * Attaches chaining static methods (e.g. `.states()`, `.sizes()`, `.theme()`)\n * to a component. Each method calls `cloneAndEnhance` with the corresponding key.\n */\ntype CreateStaticsChainingEnhancers = <O extends Record<string, any>, DK extends string[]>(props: {\n context: Record<string, any>\n dimensionKeys: DK\n func: (defaultOpts: O, opts: any) => void\n options: O\n}) => void\n\nexport const createStaticsChainingEnhancers: CreateStaticsChainingEnhancers = ({\n context,\n dimensionKeys,\n func,\n options,\n}) => {\n const keys = [...dimensionKeys, ...STATIC_KEYS]\n\n keys.forEach((item) => {\n context[item] = (props: any) => func(options, { [item]: props })\n })\n}\n\n// --------------------------------------------------------\n// helpers for create statics on component\n// --------------------------------------------------------\n/** Copies user-defined static properties onto the component's `meta` object. */\ntype CreateStaticsEnhancers = (params: {\n context: Record<string, any>\n options: Record<string, any>\n}) => void\n\nexport const createStaticsEnhancers: CreateStaticsEnhancers = ({ context, options }) => {\n if (!isEmpty(options)) {\n Object.assign(context, options)\n }\n}\n","import { config } from '@pyreon/ui-core'\nimport type { StylesCbArray } from '../types/styles'\n\n// --------------------------------------------------------\n// Calculate styles\n// --------------------------------------------------------\n/**\n * Evaluates an array of style callback functions with the configured\n * `css` tagged-template helper, producing the final CSS interpolations\n * to be passed into the styled-component template literal.\n */\ntype CalculateStyles = (styles: StylesCbArray | undefined) => ReturnType<StylesCbArray[number]>[]\n\nexport const calculateStyles: CalculateStyles = (styles) => {\n if (!styles) return []\n\n return styles.map((item) => item(config.css as Parameters<typeof item>[0]))\n}\n","// --------------------------------------------------------\n// Remove Nullable values\n// --------------------------------------------------------\n/** Filters out entries with `null`, `undefined`, or `false` values from an object. */\ntype RemoveNullableValues = (obj: Record<string, any>) => Record<string, any>\nexport const removeNullableValues: RemoveNullableValues = (obj) =>\n Object.entries(obj)\n .filter(([, v]) => v != null && v !== false)\n .reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {})\n","import { config, isEmpty, merge } from '@pyreon/ui-core'\nimport type { ThemeModeCallback } from '../types/theme'\nimport { removeNullableValues } from './collection'\nimport { isMultiKey } from './dimensions'\n\n// --------------------------------------------------------\n// Theme Mode Callback\n// --------------------------------------------------------\nconst MODE_CALLBACK_BRAND = Symbol.for('pyreon.themeModeCallback')\n\n/** Creates a mode-switching function that returns the light or dark value based on the active mode. */\nexport const themeModeCallback: ThemeModeCallback = (light, dark) => {\n const fn = (mode: string) => {\n if (!mode || mode === 'light') return light\n return dark\n }\n ;(fn as unknown as Record<string, unknown>).__brand = MODE_CALLBACK_BRAND\n return fn\n}\n\n// --------------------------------------------------------\n// Theme Mode Callback Check\n// --------------------------------------------------------\n/** Detects whether a value is a `themeModeCallback` function via Symbol brand. */\ntype IsModeCallback = (value: unknown) => boolean\nconst isModeCallback: IsModeCallback = (value: unknown) =>\n typeof value === 'function' &&\n (value as unknown as Record<string, unknown>).__brand === MODE_CALLBACK_BRAND\n\n// --------------------------------------------------------\n// Get Theme From Chain\n// --------------------------------------------------------\n/** Reduces an array of chained `.theme()` callbacks into a single merged theme object. */\ntype OptionFunc = (...arg: any) => Record<string, unknown>\ntype GetThemeFromChain = (\n options: OptionFunc[] | undefined | null,\n theme: Record<string, any>,\n) => ReturnType<OptionFunc>\n\nexport const getThemeFromChain: GetThemeFromChain = (options, theme) => {\n const result = {}\n if (!options || isEmpty(options)) return result\n\n return options.reduce(\n (acc, item) => merge(acc, item(theme, themeModeCallback, config.css)),\n result,\n )\n}\n\n// --------------------------------------------------------\n// calculate dimension themes\n// --------------------------------------------------------\n/**\n * Computes the theme object for each dimension by evaluating its\n * chained callbacks against the global theme, then strips nullable values.\n */\ntype GetDimensionThemes = (\n theme: Record<string, any>,\n options: Record<string, any>,\n) => Record<string, any>\n\nexport const getDimensionThemes: GetDimensionThemes = (theme, options) => {\n const result = {}\n\n if (isEmpty(options.dimensions)) return result\n\n return Object.entries(options.dimensions).reduce(\n (acc, [key, value]) => {\n const [, dimension] = isMultiKey(value as string | Record<string, unknown>)\n\n const helper = options[key]\n\n if (Array.isArray(helper) && helper.length > 0) {\n const finalDimensionThemes = getThemeFromChain(helper, theme)\n\n acc[dimension] = removeNullableValues(finalDimensionThemes)\n }\n\n return acc\n },\n result as Record<string, any>,\n )\n}\n\n// --------------------------------------------------------\n// combine values\n// --------------------------------------------------------\n/** Reduces an array of option callbacks by calling each with the given args and deep-merging results. */\ntype CalculateChainOptions = (\n options: OptionFunc[] | undefined | null,\n args: any[],\n) => Record<string, any>\n\nexport const calculateChainOptions: CalculateChainOptions = (options, args) => {\n const result = {}\n if (!options || isEmpty(options)) return result\n\n return options.reduce((acc, item) => merge(acc, item(...args)), result)\n}\n\n// --------------------------------------------------------\n// generate theme\n// --------------------------------------------------------\n/**\n * Generates the final theme object by starting with the base theme\n * and merging in dimension-specific theme slices based on the current\n * rocketstate (active dimension values). Supports multi-key dimensions.\n *\n * Transform dimensions (marked with `transform: true`) are evaluated last.\n * Their values are functions that receive the fully accumulated theme and\n * return overrides — enabling derived styles like \"outlined\" or \"inversed\".\n */\nexport type GetTheme = (params: {\n rocketstate: Record<string, string | string[]>\n themes: Record<string, Record<string, any>>\n baseTheme: Record<string, any>\n transformKeys?: Partial<Record<string, true>>\n /** App theme from context — passed to transform dimension callbacks. */\n appTheme?: Record<string, any>\n}) => Record<string, unknown>\n\nexport const getTheme: GetTheme = ({ rocketstate, themes, baseTheme, transformKeys, appTheme }) => {\n let finalTheme = { ...baseTheme }\n const deferredTransforms: Array<\n (\n currentTheme: Record<string, any>,\n currentAppTheme: Record<string, any>,\n mode: typeof themeModeCallback,\n cssFn: typeof config.css,\n ) => Record<string, any>\n > = []\n\n Object.entries(rocketstate).forEach(([key, value]: [string, string | string[]]) => {\n const keyTheme: Record<string, any> = themes[key] ?? {}\n const isTransform = transformKeys?.[key]\n\n const mergeValue = (item: string) => {\n const val = keyTheme[item]\n if (isTransform && typeof val === 'function') {\n deferredTransforms.push(val)\n } else {\n finalTheme = merge({}, finalTheme, val)\n }\n }\n\n if (Array.isArray(value)) {\n value.forEach(mergeValue)\n } else {\n mergeValue(value)\n }\n })\n\n // Apply transform dimension values last with the fully accumulated theme\n for (const transform of deferredTransforms) {\n finalTheme = merge(\n {},\n finalTheme,\n transform(finalTheme, appTheme ?? {}, themeModeCallback, config.css),\n )\n }\n\n // Ensure pseudo-state keys always exist as objects so .styles() can\n // destructure without defaults: const { hover, focus, ... } = $rocketstyle\n finalTheme.hover ??= {}\n finalTheme.focus ??= {}\n finalTheme.active ??= {}\n finalTheme.disabled ??= {}\n finalTheme.pressed ??= {}\n finalTheme.readOnly ??= {}\n\n return finalTheme\n}\n\n// --------------------------------------------------------\n// resolve theme by mode\n// --------------------------------------------------------\n/**\n * Recursively traverses a theme object and resolves any `themeModeCallback`\n * functions to their concrete light or dark values for the given mode.\n */\nexport type GetThemeByMode = (\n object: Record<string, any>,\n mode: 'light' | 'dark',\n) => Partial<{\n baseTheme: Record<string, unknown>\n themes: Record<string, unknown>\n}>\n\nexport const getThemeByMode: GetThemeByMode = (object, mode) =>\n Object.keys(object).reduce(\n (acc, key) => {\n const value = object[key]\n\n if (typeof value === 'object' && value !== null) {\n acc[key] = getThemeByMode(value, mode)\n } else if (isModeCallback(value)) {\n acc[key] = value(mode)\n } else {\n acc[key] = value\n }\n\n return acc\n },\n {} as Record<string, any>,\n )\n","import { compose, config, hoistNonReactStatics, omit, pick, render } from '@pyreon/ui-core'\nimport { LocalThemeManager } from './cache'\nimport { CONFIG_KEYS, PSEUDO_KEYS, PSEUDO_META_KEYS, STYLING_KEYS } from './constants'\nimport createLocalProvider from './context/createLocalProvider'\nimport { useLocalContext } from './context/localContext'\nimport { rocketstyleAttrsHoc } from './hoc'\nimport { useTheme } from './hooks'\nimport type { Configuration, ExtendedConfiguration } from './types/configuration'\nimport type { RocketComponent } from './types/rocketComponent'\nimport type { InnerComponentProps, RocketStyleComponent } from './types/rocketstyle'\nimport type { ComponentFn } from './types/utils'\nimport { calculateChainOptions, calculateStylingAttrs, pickStyledAttrs } from './utils/attrs'\nimport { chainOptions, chainOrOptions, chainReservedKeyOptions } from './utils/chaining'\nimport { calculateHocsFuncs } from './utils/compose'\nimport { getDimensionsMap } from './utils/dimensions'\nimport { createStaticsChainingEnhancers, createStaticsEnhancers } from './utils/statics'\nimport { calculateStyles } from './utils/styles'\nimport { getDimensionThemes, getTheme, getThemeByMode, getThemeFromChain } from './utils/theme'\n\n/**\n * Core rocketstyle component factory. Creates a fully-featured Pyreon component\n * that integrates theme management (with light/dark mode support), multi-tier\n * WeakMap caching, dimension-based styling props, pseudo-state detection, and\n * chainable static methods (`.attrs()`, `.theme()`, `.styles()`, `.config()`, etc.).\n *\n * In Pyreon, components are plain functions that run once per mount.\n * No forwardRef, useMemo, useState — ref flows as a normal prop.\n */\n\n// --------------------------------------------------------\n// cloneAndEnhance\n// --------------------------------------------------------\ntype CloneAndEnhance = (\n defaultOpts: Configuration,\n opts: Partial<ExtendedConfiguration>,\n) => ReturnType<typeof rocketComponent>\n\n/** Clones the current configuration and merges new options, returning a fresh rocketComponent. */\nconst cloneAndEnhance: CloneAndEnhance = (defaultOpts, opts) =>\n rocketComponent({\n ...defaultOpts,\n attrs: chainOptions(opts.attrs, defaultOpts.attrs),\n filterAttrs: [...(defaultOpts.filterAttrs ?? []), ...(opts.filterAttrs ?? [])],\n priorityAttrs: chainOptions(opts.priorityAttrs, defaultOpts.priorityAttrs),\n statics: { ...defaultOpts.statics, ...opts.statics },\n compose: { ...defaultOpts.compose, ...opts.compose },\n ...chainOrOptions(CONFIG_KEYS, opts, defaultOpts),\n ...chainReservedKeyOptions([...defaultOpts.dimensionKeys, ...STYLING_KEYS], opts, defaultOpts),\n } as Parameters<typeof rocketComponent>[0])\n\n// --------------------------------------------------------\n// rocketComponent\n// --------------------------------------------------------\n// @ts-expect-error\nconst rocketComponent: RocketComponent = (options) => {\n const { component, styles } = options\n const { styled } = config\n\n const _calculateStylingAttrs = calculateStylingAttrs({\n multiKeys: options.multiKeys,\n useBooleans: options.useBooleans,\n })\n\n const componentName = options.name ?? options.component.displayName ?? options.component.name\n\n // Create styled component with all options.styles if available.\n // Rocketstyle CSS lives in `@layer rocketstyle`, which is declared\n // AFTER `@layer elements` in the cascade ordering (see sheet.ts).\n // This ensures rocketstyle theme styles always override element base\n // styles regardless of source order.\n const STYLED_COMPONENT =\n (component.IS_ROCKETSTYLE ?? options.styled !== true)\n ? component\n : styled(component, { layer: 'rocketstyle' })`\n ${calculateStyles(styles)};\n `\n\n // --------------------------------------------------------\n // COMPONENT - Final component to be rendered\n // --------------------------------------------------------\n const RenderComponent: ComponentFn<any> = options.provider\n ? createLocalProvider(STYLED_COMPONENT)\n : STYLED_COMPONENT\n\n // --------------------------------------------------------\n // THEME - Cached & Calculated theme(s)\n // --------------------------------------------------------\n const ThemeManager = new LocalThemeManager()\n\n // --------------------------------------------------------\n // COMPOSE - high-order components\n // --------------------------------------------------------\n const hocsFuncs = [rocketstyleAttrsHoc(options), ...calculateHocsFuncs(options.compose)]\n\n // --------------------------------------------------------\n // ENHANCED COMPONENT\n // --------------------------------------------------------\n // In Pyreon, components are plain functions — no forwardRef needed.\n // Ref flows as a normal prop through the chain.\n const EnhancedComponent: ComponentFn<InnerComponentProps> = (props) => {\n // --------------------------------------------------\n // hover - focus - pressed state passed via context from parent component\n // --------------------------------------------------\n const localCtx = useLocalContext(options.consumer)\n\n // --------------------------------------------------\n // general theme and theme mode dark / light passed in context\n // --------------------------------------------------\n // IMPORTANT: Do NOT destructure — useTheme returns getter properties.\n // Destructuring calls getters once and captures static values.\n // Keep the object reference so mode/isDark/isLight re-evaluate lazily.\n const themeAttrs = useTheme(options)\n\n // --------------------------------------------------\n // Dimension KEY structure is theme-independent — dimension names (e.g.\n // `level3`, `primary`) come from the .sizes()/.states()/.variants()\n // callback structure at component-definition time, not from theme values.\n // Compute reservedPropNames + dimensions once using the initial theme;\n // they remain stable across theme swaps.\n //\n // Dimension VALUES (used in $rocketstyleAccessor) DO depend on theme and\n // are resolved inside the accessor on each tracked invocation — allowing\n // whole-theme swaps (user preference themes) to re-resolve CSS without\n // remounting. WeakMap caches in ThemeManager keep the common static-theme\n // case O(1).\n // --------------------------------------------------\n const initialTheme = themeAttrs.theme\n const initialBaseTheme = (() => {\n const helper = ThemeManager.baseTheme\n if (!helper.has(initialTheme)) {\n helper.set(initialTheme, getThemeFromChain(options.theme, initialTheme))\n }\n return helper.get(initialTheme)\n })()\n const initialDimensionThemes = (() => {\n const helper = ThemeManager.dimensionsThemes\n if (!helper.has(initialTheme)) {\n helper.set(initialTheme, getDimensionThemes(initialTheme, options))\n }\n return helper.get(initialTheme)\n })()\n\n const { keysMap: dimensions, keywords: reservedPropNames } = getDimensionsMap({\n themes: initialDimensionThemes,\n useBooleans: options.useBooleans,\n })\n\n const RESERVED_STYLING_PROPS_KEYS = Object.keys(reservedPropNames)\n\n // --------------------------------------------------\n // $rocketstyle as a FUNCTION ACCESSOR — fully reactive.\n // Re-evaluates when THEME, MODE, or dimension props change.\n // Props are resolved fresh each call so reactive prop accessors\n // (signals, getters) produce updated dimension values.\n // --------------------------------------------------\n const $rocketstyleAccessor = () => {\n // Read theme + mode LAZILY via the getter-backed themeAttrs object.\n // Both reads are tracked when this accessor runs inside a reactive\n // scope (styler's effect), so theme swap / mode toggle re-runs the\n // surrounding resolver and swaps the generated class.\n const theme = themeAttrs.theme // reactive: tracks theme signal\n const mode = themeAttrs.mode // reactive: tracks mode signal\n\n // Resolve base + dimension themes for the CURRENT theme. WeakMap\n // keyed on theme identity — stable-theme renders hit cache in O(1),\n // theme swaps fall through to recompute (once per new theme).\n const baseThemeHelper = ThemeManager.baseTheme\n if (!baseThemeHelper.has(theme)) {\n baseThemeHelper.set(theme, getThemeFromChain(options.theme, theme))\n }\n const baseTheme = baseThemeHelper.get(theme)\n\n const dimHelper = ThemeManager.dimensionsThemes\n if (!dimHelper.has(theme)) {\n dimHelper.set(theme, getDimensionThemes(theme, options))\n }\n const themes = dimHelper.get(theme)\n\n // Resolve active dimensions from props (not localCtx which has pseudo getters)\n const rocketstate = _calculateStylingAttrs({\n props: pickStyledAttrs(props as Record<string, unknown>, reservedPropNames),\n dimensions,\n })\n\n // Resolve mode-specific theme\n const modeBaseHelper = ThemeManager.modeBaseTheme[mode]\n if (!modeBaseHelper.has(baseTheme)) {\n modeBaseHelper.set(baseTheme, getThemeByMode(baseTheme, mode))\n }\n const currentModeBaseTheme = modeBaseHelper.get(baseTheme)\n\n const modeDimHelper = ThemeManager.modeDimensionTheme[mode]\n if (!modeDimHelper.has(themes)) {\n modeDimHelper.set(themes, getThemeByMode(themes, mode))\n }\n const currentModeThemes = modeDimHelper.get(themes)\n\n return getTheme({\n rocketstate,\n themes: currentModeThemes,\n baseTheme: currentModeBaseTheme,\n transformKeys: options.transformKeys,\n appTheme: theme,\n })\n }\n\n // Silence \"unused\" warnings for initialBaseTheme / initialDimensionThemes —\n // they're eagerly populated into ThemeManager caches so the first accessor\n // call hits cache, but not referenced directly.\n void initialBaseTheme\n void initialDimensionThemes\n\n // --------------------------------------------------\n // $rocketstate as a FUNCTION ACCESSOR — reactive on prop changes.\n // Re-evaluates active dimensions + pseudo state from current props.\n // --------------------------------------------------\n // Capture pseudo from localCtx once at setup — pseudo properties are\n // getters (from createLocalProvider) that read signals lazily.\n // Passing them through preserves reactivity without subscribing here.\n const localPseudo = localCtx?.pseudo\n\n const $rocketstateAccessor = () => {\n const rocketstate = _calculateStylingAttrs({\n props: pickStyledAttrs(props as Record<string, unknown>, reservedPropNames),\n dimensions,\n })\n\n // Read pseudo props fresh each call — props may have reactive getters\n // from _rp() wrapping. Reading inside the accessor (which runs in an\n // effect) ensures changes to pseudo props like active={isDark()} are tracked.\n const propPseudo = pick(props, [...PSEUDO_KEYS, ...PSEUDO_META_KEYS])\n\n return {\n ...rocketstate,\n pseudo: { ...localPseudo, ...propPseudo },\n }\n }\n\n // --------------------------------------------------\n // Static mergeProps for final prop filtering (non-dimension props)\n // --------------------------------------------------\n const { pseudo: _pseudo, ...mergeProps } = {\n ...localCtx,\n ...props,\n }\n\n // --------------------------------------------------\n // final props passed to WrappedComponent\n // --------------------------------------------------\n const finalProps: Record<string, any> = {\n ...omit(mergeProps, [\n ...RESERVED_STYLING_PROPS_KEYS,\n ...PSEUDO_KEYS,\n ...options.filterAttrs,\n ]),\n ...(options.passProps ? pick(mergeProps, options.passProps) : {}),\n ref: props.ref,\n // Function accessors — DynamicStyled wraps them in a computed() so\n // mode/dimension changes produce a new CSS class reactively. The\n // computed tracks only these two accessors; the resolve itself runs\n // untracked to prevent exponential cascade from theme deep-reads.\n $rocketstyle: $rocketstyleAccessor,\n $rocketstate: $rocketstateAccessor,\n }\n\n // development debugging\n if (process.env.NODE_ENV !== 'production') {\n finalProps['data-rocketstyle'] = componentName\n\n if (options.DEBUG) {\n const debugPayload = {\n component: componentName,\n rocketstate: $rocketstateAccessor(),\n rocketstyle: $rocketstyleAccessor(),\n dimensions,\n mode: themeAttrs.mode,\n reservedPropNames: RESERVED_STYLING_PROPS_KEYS,\n filteredAttrs: options.filterAttrs,\n }\n\n // oxlint-disable-next-line no-console\n console.debug(`[rocketstyle] ${componentName} render:`, debugPayload)\n }\n }\n\n // STATIC VNode — created once, never remounted on mode change.\n // The styled component handles reactive class swaps internally.\n return RenderComponent(finalProps)\n }\n\n // ------------------------------------------------------\n // Compose HOC chain and create final component\n // ------------------------------------------------------\n const FinalComponent: RocketStyleComponent = compose(...hocsFuncs)(EnhancedComponent)\n FinalComponent.IS_ROCKETSTYLE = true\n FinalComponent.displayName = componentName\n\n hoistNonReactStatics(FinalComponent as Record<string, unknown>, options.component)\n\n // ------------------------------------------------------\n // enhance for chaining methods\n // ------------------------------------------------------\n createStaticsChainingEnhancers({\n context: FinalComponent,\n dimensionKeys: options.dimensionKeys,\n func: cloneAndEnhance,\n options,\n })\n\n FinalComponent.IS_ROCKETSTYLE = true\n FinalComponent.displayName = componentName\n FinalComponent.meta = {}\n\n // ------------------------------------------------------\n // enhance for statics\n // ------------------------------------------------------\n createStaticsEnhancers({\n context: FinalComponent.meta,\n options: options.statics,\n })\n\n // Also assign statics directly onto the component so they are\n // discoverable via `\"key\" in Component` checks (e.g. _documentType).\n createStaticsEnhancers({\n context: FinalComponent,\n options: options.statics,\n })\n\n Object.assign(FinalComponent, {\n attrs: (attrs: any, { priority, filter }: any = {}) => {\n const result: Record<string, any> = {}\n\n if (filter) {\n result.filterAttrs = filter\n }\n\n if (priority) {\n result.priorityAttrs = attrs as ExtendedConfiguration['priorityAttrs']\n\n return cloneAndEnhance(options, result)\n }\n\n result.attrs = attrs as ExtendedConfiguration['attrs']\n\n return cloneAndEnhance(options, result)\n },\n\n config: (opts: any = {}) => {\n const result = pick(opts, CONFIG_KEYS) as ExtendedConfiguration\n\n return cloneAndEnhance(options, result)\n },\n\n statics: (opts: any) => cloneAndEnhance(options, { statics: opts }),\n\n getStaticDimensions: (theme: any) => {\n const themes = getDimensionThemes(theme, options)\n\n const { keysMap, keywords } = getDimensionsMap({\n themes,\n useBooleans: options.useBooleans,\n })\n\n return {\n dimensions: keysMap,\n keywords,\n useBooleans: options.useBooleans,\n multiKeys: options.multiKeys,\n }\n },\n\n getDefaultAttrs: (props: any, theme: any, mode: any) =>\n calculateChainOptions(options.attrs)([\n props,\n theme,\n {\n render,\n mode,\n isDark: mode === 'light',\n isLight: mode === 'dark',\n },\n ]),\n })\n\n return FinalComponent\n}\n\nexport default rocketComponent\n","import { isEmpty } from '@pyreon/ui-core'\nimport { ALL_RESERVED_KEYS } from './constants'\nimport defaultDimensions from './constants/defaultDimensions'\nimport rocketComponent from './rocketstyle'\nimport type { DefaultDimensions, Dimensions } from './types/dimensions'\nimport type { RocketComponent } from './types/rocketComponent'\nimport type { ElementType } from './types/utils'\nimport {\n getDimensionsValues,\n getKeys,\n getMultipleDimensions,\n getTransformDimensions,\n} from './utils/dimensions'\n\nexport type Rocketstyle = <\n const D extends Dimensions = DefaultDimensions,\n UB extends boolean = false,\n>({\n dimensions,\n useBooleans,\n}?: {\n dimensions?: D\n useBooleans?: UB\n}) => <C extends ElementType>({\n name,\n component,\n}: {\n name: string\n component: C\n}) => ReturnType<RocketComponent<C, {}, {}, D, UB>>\n\n/**\n * Factory initializer for rocketstyle components. Validates dimension\n * configurations against reserved keys, then delegates to the core\n * `rocketComponent` builder with pre-computed dimension metadata.\n */\ntype InitErrors = Partial<{\n component: string\n name: string\n dimensions: string\n invalidDimensions: string\n}>\n\nconst validateInit = (name: string, component: unknown, dimensions: Dimensions) => {\n const errors: InitErrors = {}\n\n if (!component) {\n errors.component = 'Parameter `component` is missing in params!'\n }\n\n if (!name) {\n errors.name = 'Parameter `name` is missing in params!'\n }\n\n if (isEmpty(dimensions)) {\n errors.dimensions = 'Parameter `dimensions` is missing in params!'\n } else {\n const definedDimensions = getKeys(dimensions)\n const invalidDimension = ALL_RESERVED_KEYS.some((item) =>\n definedDimensions.some((d) => d === item),\n )\n\n if (invalidDimension) {\n errors.invalidDimensions = `Some of your \\`dimensions\\` is invalid and uses reserved static keys which are\n ${defaultDimensions.toString()}`\n }\n }\n\n if (!isEmpty(errors)) {\n throw Error(JSON.stringify(errors))\n }\n}\n\nconst rocketstyle = (({ dimensions = defaultDimensions, useBooleans = false } = {}) =>\n ({ name, component }: { name: string; component: any }) => {\n if (process.env.NODE_ENV !== 'production') {\n validateInit(name, component, dimensions)\n }\n\n return (rocketComponent as any)({\n name,\n component,\n useBooleans,\n dimensions,\n dimensionKeys: getKeys(dimensions),\n dimensionValues: getDimensionsValues(dimensions),\n multiKeys: getMultipleDimensions(dimensions),\n transformKeys: getTransformDimensions(dimensions),\n styled: true,\n })\n }) as unknown as Rocketstyle\n\nexport default rocketstyle\n","export type IsRocketComponent = <T>(component: T) => boolean\n\n/** Runtime type guard — checks if a component was created by `rocketstyle()`. */\nconst isRocketComponent: IsRocketComponent = (component) => {\n if (\n component &&\n (typeof component === 'object' || typeof component === 'function') &&\n Object.hasOwn(component as object, 'IS_ROCKETSTYLE')\n ) {\n return true\n }\n\n return false\n}\n\nexport default isRocketComponent\n","import type { TProvider } from './context/context'\nimport Provider, { context } from './context/context'\nimport type { Rocketstyle } from './init'\nimport rocketstyle from './init'\nimport type { IsRocketComponent } from './isRocketComponent'\nimport isRocketComponent from './isRocketComponent'\nimport type { AttrsCb } from './types/attrs'\nimport type {\n ConfigAttrs,\n ConsumerCb,\n ConsumerCtxCBValue,\n ConsumerCtxCb,\n RocketComponentType,\n RocketProviderState,\n} from './types/config'\nimport type { DefaultProps } from './types/configuration'\nimport type {\n DimensionCallbackParam,\n DimensionProps,\n Dimensions,\n DimensionValue,\n ExtractDimensionProps,\n ExtractDimensions,\n TDKP,\n} from './types/dimensions'\nimport type { ComposeParam, GenericHoc } from './types/hoc'\nimport type { IRocketStyleComponent, RocketStyleComponent } from './types/rocketstyle'\nimport type { RocketStyleInterpolationProps, StylesCb, StylesDefault } from './types/styles'\nimport type {\n ThemeCb,\n ThemeDefault,\n ThemeMode,\n ThemeModeCallback,\n ThemeModeKeys,\n} from './types/theme'\nimport type { ComponentFn, ElementType, ExtractProps, MergeTypes, TObj } from './types/utils'\n\nexport type {\n AttrsCb,\n ComponentFn,\n ComposeParam,\n ConfigAttrs,\n ConsumerCb,\n ConsumerCtxCBValue,\n ConsumerCtxCb,\n DefaultProps,\n DimensionCallbackParam,\n DimensionProps,\n Dimensions,\n DimensionValue,\n ElementType,\n ExtractDimensionProps,\n ExtractDimensions,\n ExtractProps,\n GenericHoc,\n IRocketStyleComponent,\n IsRocketComponent,\n MergeTypes,\n RocketComponentType,\n RocketProviderState,\n RocketStyleComponent,\n RocketStyleInterpolationProps,\n Rocketstyle,\n StylesCb,\n StylesDefault,\n TDKP,\n ThemeCb,\n ThemeDefault,\n ThemeMode,\n ThemeModeCallback,\n ThemeModeKeys,\n TObj,\n TProvider,\n}\n\n/**\n * Resolve a $rocketstyle value — handles both function accessor and plain object.\n * Use in styled() interpolation functions when $rocketstyle may be a reactive accessor.\n *\n * @example\n * ```ts\n * styled(Component)`\n * color: ${(props) => resolveTheme(props.$rocketstyle).color};\n * `\n * ```\n */\nexport function resolveTheme<T = Record<string, unknown>>(\n value: (() => T) | T,\n): T {\n return typeof value === 'function' ? (value as () => T)() : value\n}\n\nexport { context, isRocketComponent, Provider, rocketstyle }\nexport default rocketstyle\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pyreon/rocketstyle",
3
- "version": "0.12.15",
3
+ "version": "0.13.1",
4
4
  "description": "Multi-dimensional style composition for Pyreon components",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -41,17 +41,17 @@
41
41
  "typecheck": "tsc --noEmit"
42
42
  },
43
43
  "devDependencies": {
44
- "@pyreon/test-utils": "^0.12.10",
45
- "@pyreon/typescript": "^0.12.15",
46
- "@pyreon/ui-core": "^0.12.15",
44
+ "@pyreon/test-utils": "^0.13.1",
45
+ "@pyreon/typescript": "^0.13.1",
46
+ "@pyreon/ui-core": "^0.13.1",
47
47
  "@vitest/browser-playwright": "^4.1.4",
48
48
  "@vitus-labs/tools-rolldown": "^1.15.3"
49
49
  },
50
50
  "peerDependencies": {
51
- "@pyreon/core": "^0.12.15",
52
- "@pyreon/reactivity": "^0.12.15",
53
- "@pyreon/styler": "^0.12.15",
54
- "@pyreon/ui-core": "^0.12.15"
51
+ "@pyreon/core": "^0.13.1",
52
+ "@pyreon/reactivity": "^0.13.1",
53
+ "@pyreon/styler": "^0.13.1",
54
+ "@pyreon/ui-core": "^0.13.1"
55
55
  },
56
56
  "engines": {
57
57
  "node": ">= 22"
@@ -64,20 +64,11 @@ describe('@pyreon/rocketstyle in real browser', () => {
64
64
  danger.unmount()
65
65
  })
66
66
 
67
- it('reactive mode swap: classList changes in place via styler `isReactiveRS` effect (no remount)', async () => {
68
- // Exercises the load-bearing `isReactiveRS` effect in
69
- // styler/src/styled.tsx when `$rocketstyle` is a function
70
- // accessor, an effect tracks it and swaps classList in place.
71
- // Mode switching is the canonical reactive path: PyreonUI
72
- // provides a signal-backed mode, rocketstyle's
73
- // `$rocketstyleAccessor` reads `themeAttrs.mode` (a getter on a
74
- // ReactiveContext), and the styler effect observes the change.
75
- //
76
- // (Reactive *dimension props* like `state={stateSig()}` are NOT
77
- // yet end-to-end reactive through rocketstyle's HOC chain — the
78
- // inner spread in `rocketstyleAttrsHoc` collapses getter props
79
- // to values. Mode is the only reactive axis that survives the
80
- // spread because it flows via ReactiveContext, not via props.)
67
+ it('reactive mode swap: computed class updates via renderEffect (no full effect)', async () => {
68
+ // Rocketstyle passes $rocketstyle as a function accessor. DynamicStyled
69
+ // wraps it in a computed() that tracks the mode signal. When mode changes,
70
+ // the computed re-evaluates new CSS class renderEffect updates DOM.
71
+ // No per-component effect() just one lightweight computed + renderEffect.
81
72
  const modeSig = signal<'light' | 'dark'>('light')
82
73
 
83
74
  const Box: any = rocketstyle()({ name: 'ModeSwapBox', component: Base })
@@ -94,19 +85,13 @@ describe('@pyreon/rocketstyle in real browser', () => {
94
85
  h(PyreonUI, { theme: {}, mode: modeSig }, h(Box, { id: 'rx' })),
95
86
  )
96
87
  const el = container.querySelector<HTMLElement>('#rx')!
97
- const classBefore = el.className
98
88
  expect(getComputedStyle(el).color).toBe('rgb(255, 0, 0)')
99
89
 
100
90
  modeSig.set('dark')
101
91
  await new Promise((r) => setTimeout(r, 0))
102
92
  await new Promise((r) => requestAnimationFrame(() => r(undefined)))
103
93
 
104
- const classAfter = el.className
105
94
  expect(getComputedStyle(el).color).toBe('rgb(0, 0, 255)')
106
- // Class swapped in place — not a remount (same element reference,
107
- // different class). This is the styler `isReactiveRS` effect
108
- // doing `el.classList.remove(old); el.classList.add(new)`.
109
- expect(classAfter).not.toBe(classBefore)
110
95
  unmount()
111
96
  })
112
97
 
@@ -112,26 +112,36 @@ const rocketComponent: RocketComponent = (options) => {
112
112
  const themeAttrs = useTheme(options)
113
113
 
114
114
  // --------------------------------------------------
115
- // Theme structure cached by theme object identity.
116
- // Theme object itself doesn't change (enrichTheme produces a stable ref),
117
- // only mode switches change which mode-variant is resolved.
115
+ // Dimension KEY structure is theme-independent dimension names (e.g.
116
+ // `level3`, `primary`) come from the .sizes()/.states()/.variants()
117
+ // callback structure at component-definition time, not from theme values.
118
+ // Compute reservedPropNames + dimensions once using the initial theme;
119
+ // they remain stable across theme swaps.
120
+ //
121
+ // Dimension VALUES (used in $rocketstyleAccessor) DO depend on theme and
122
+ // are resolved inside the accessor on each tracked invocation — allowing
123
+ // whole-theme swaps (user preference themes) to re-resolve CSS without
124
+ // remounting. WeakMap caches in ThemeManager keep the common static-theme
125
+ // case O(1).
118
126
  // --------------------------------------------------
119
- const theme = themeAttrs.theme
120
-
121
- const baseThemeHelper = ThemeManager.baseTheme
122
- if (!baseThemeHelper.has(theme)) {
123
- baseThemeHelper.set(theme, getThemeFromChain(options.theme, theme))
124
- }
125
- const baseTheme = baseThemeHelper.get(theme)
126
-
127
- const dimHelper = ThemeManager.dimensionsThemes
128
- if (!dimHelper.has(theme)) {
129
- dimHelper.set(theme, getDimensionThemes(theme, options))
130
- }
131
- const themes = dimHelper.get(theme)
127
+ const initialTheme = themeAttrs.theme
128
+ const initialBaseTheme = (() => {
129
+ const helper = ThemeManager.baseTheme
130
+ if (!helper.has(initialTheme)) {
131
+ helper.set(initialTheme, getThemeFromChain(options.theme, initialTheme))
132
+ }
133
+ return helper.get(initialTheme)
134
+ })()
135
+ const initialDimensionThemes = (() => {
136
+ const helper = ThemeManager.dimensionsThemes
137
+ if (!helper.has(initialTheme)) {
138
+ helper.set(initialTheme, getDimensionThemes(initialTheme, options))
139
+ }
140
+ return helper.get(initialTheme)
141
+ })()
132
142
 
133
143
  const { keysMap: dimensions, keywords: reservedPropNames } = getDimensionsMap({
134
- themes,
144
+ themes: initialDimensionThemes,
135
145
  useBooleans: options.useBooleans,
136
146
  })
137
147
 
@@ -139,18 +149,33 @@ const rocketComponent: RocketComponent = (options) => {
139
149
 
140
150
  // --------------------------------------------------
141
151
  // $rocketstyle as a FUNCTION ACCESSOR — fully reactive.
142
- // Re-evaluates when mode OR dimension props change.
152
+ // Re-evaluates when THEME, MODE, or dimension props change.
143
153
  // Props are resolved fresh each call so reactive prop accessors
144
154
  // (signals, getters) produce updated dimension values.
145
155
  // --------------------------------------------------
146
156
  const $rocketstyleAccessor = () => {
147
- // Only read mode and dimension props NOT pseudo state.
148
- // Pseudo state (hover, focus, pressed) is read by .styles()
149
- // via $rocketstate inside runUntracked(). Reading pseudo signals
150
- // here would subscribe this accessor to hover/focus/pressed,
151
- // causing CSS recomputation on every mouse event.
157
+ // Read theme + mode LAZILY via the getter-backed themeAttrs object.
158
+ // Both reads are tracked when this accessor runs inside a reactive
159
+ // scope (styler's effect), so theme swap / mode toggle re-runs the
160
+ // surrounding resolver and swaps the generated class.
161
+ const theme = themeAttrs.theme // reactive: tracks theme signal
152
162
  const mode = themeAttrs.mode // reactive: tracks mode signal
153
163
 
164
+ // Resolve base + dimension themes for the CURRENT theme. WeakMap
165
+ // keyed on theme identity — stable-theme renders hit cache in O(1),
166
+ // theme swaps fall through to recompute (once per new theme).
167
+ const baseThemeHelper = ThemeManager.baseTheme
168
+ if (!baseThemeHelper.has(theme)) {
169
+ baseThemeHelper.set(theme, getThemeFromChain(options.theme, theme))
170
+ }
171
+ const baseTheme = baseThemeHelper.get(theme)
172
+
173
+ const dimHelper = ThemeManager.dimensionsThemes
174
+ if (!dimHelper.has(theme)) {
175
+ dimHelper.set(theme, getDimensionThemes(theme, options))
176
+ }
177
+ const themes = dimHelper.get(theme)
178
+
154
179
  // Resolve active dimensions from props (not localCtx which has pseudo getters)
155
180
  const rocketstate = _calculateStylingAttrs({
156
181
  props: pickStyledAttrs(props as Record<string, unknown>, reservedPropNames),
@@ -179,6 +204,12 @@ const rocketComponent: RocketComponent = (options) => {
179
204
  })
180
205
  }
181
206
 
207
+ // Silence "unused" warnings for initialBaseTheme / initialDimensionThemes —
208
+ // they're eagerly populated into ThemeManager caches so the first accessor
209
+ // call hits cache, but not referenced directly.
210
+ void initialBaseTheme
211
+ void initialDimensionThemes
212
+
182
213
  // --------------------------------------------------
183
214
  // $rocketstate as a FUNCTION ACCESSOR — reactive on prop changes.
184
215
  // Re-evaluates active dimensions + pseudo state from current props.
@@ -224,7 +255,10 @@ const rocketComponent: RocketComponent = (options) => {
224
255
  ]),
225
256
  ...(options.passProps ? pick(mergeProps, options.passProps) : {}),
226
257
  ref: props.ref,
227
- // FUNCTION accessors — styled component resolves them reactively
258
+ // Function accessors — DynamicStyled wraps them in a computed() so
259
+ // mode/dimension changes produce a new CSS class reactively. The
260
+ // computed tracks only these two accessors; the resolve itself runs
261
+ // untracked to prevent exponential cascade from theme deep-reads.
228
262
  $rocketstyle: $rocketstyleAccessor,
229
263
  $rocketstate: $rocketstateAccessor,
230
264
  }