@pyreon/rocketstyle 0.11.3 → 0.11.4

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
@@ -295,12 +295,12 @@ const rocketStyleHOC = ({ inversed, attrs, priorityAttrs }) => {
295
295
  const calculatePriorityAttrs = calculateChainOptions(priorityAttrs);
296
296
  const Enhanced = (WrappedComponent) => {
297
297
  const HOCComponent = (props) => {
298
- const { theme, mode, isDark, isLight } = useThemeAttrs({ inversed });
299
- const callbackParams = [theme, {
298
+ const themeAttrs = useThemeAttrs({ inversed });
299
+ const callbackParams = [themeAttrs.theme, {
300
300
  render,
301
- mode,
302
- isDark,
303
- isLight
301
+ mode: themeAttrs.mode,
302
+ isDark: themeAttrs.isDark,
303
+ isLight: themeAttrs.isLight
304
304
  }];
305
305
  const filteredProps = removeUndefinedProps(props);
306
306
  const prioritizedAttrs = calculatePriorityAttrs([filteredProps, ...callbackParams]);
@@ -496,24 +496,7 @@ const rocketComponent = (options) => {
496
496
  const hocsFuncs = [rocketStyleHOC(options), ...calculateHocsFuncs(options.compose)];
497
497
  const EnhancedComponent = (props) => {
498
498
  const localCtx = useLocalContext(options.consumer);
499
- const { theme, mode } = useThemeAttrs(options);
500
- const baseThemeHelper = ThemeManager$1.baseTheme;
501
- if (!baseThemeHelper.has(theme)) baseThemeHelper.set(theme, getThemeFromChain(options.theme, theme));
502
- const baseTheme = baseThemeHelper.get(theme);
503
- const dimHelper = ThemeManager$1.dimensionsThemes;
504
- if (!dimHelper.has(theme)) dimHelper.set(theme, getDimensionThemes(theme, options));
505
- const themes = dimHelper.get(theme);
506
- const modeBaseHelper = ThemeManager$1.modeBaseTheme[mode];
507
- if (!modeBaseHelper.has(baseTheme)) modeBaseHelper.set(baseTheme, getThemeByMode(baseTheme, mode));
508
- const currentModeBaseTheme = modeBaseHelper.get(baseTheme);
509
- const modeDimHelper = ThemeManager$1.modeDimensionTheme[mode];
510
- if (!modeDimHelper.has(themes)) modeDimHelper.set(themes, getThemeByMode(themes, mode));
511
- const currentModeThemes = modeDimHelper.get(themes);
512
- const { keysMap: dimensions, keywords: reservedPropNames } = getDimensionsMap({
513
- themes,
514
- useBooleans: options.useBooleans
515
- });
516
- const RESERVED_STYLING_PROPS_KEYS = Object.keys(reservedPropNames);
499
+ const themeAttrs = useThemeAttrs(options);
517
500
  const { pseudo, ...mergeProps } = {
518
501
  ...localCtx,
519
502
  ...props
@@ -522,48 +505,69 @@ const rocketComponent = (options) => {
522
505
  ...pseudo,
523
506
  ...pick(props, [...PSEUDO_KEYS, ...PSEUDO_META_KEYS])
524
507
  };
525
- const rocketstate = _calculateStylingAttrs({
526
- props: pickStyledAttrs(mergeProps, reservedPropNames),
527
- dimensions
528
- });
529
- const finalRocketstate = {
530
- ...rocketstate,
531
- pseudo: pseudoRocketstate
532
- };
533
- const computedRocketstyle = getTheme({
534
- rocketstate,
535
- themes: currentModeThemes,
536
- baseTheme: currentModeBaseTheme,
537
- transformKeys: options.transformKeys,
538
- appTheme: theme
539
- });
540
- const finalProps = {
541
- ...omit(mergeProps, [
542
- ...RESERVED_STYLING_PROPS_KEYS,
543
- ...PSEUDO_KEYS,
544
- ...options.filterAttrs
545
- ]),
546
- ...options.passProps ? pick(mergeProps, options.passProps) : {},
547
- ref: props.ref,
548
- $rocketstyle: computedRocketstyle,
549
- $rocketstate: finalRocketstate
550
- };
551
- if (process.env.NODE_ENV !== "production") {
552
- finalProps["data-rocketstyle"] = componentName;
553
- if (options.DEBUG) {
554
- const debugPayload = {
555
- component: componentName,
556
- rocketstate: finalRocketstate,
557
- rocketstyle: computedRocketstyle,
558
- dimensions,
559
- mode,
560
- reservedPropNames: RESERVED_STYLING_PROPS_KEYS,
561
- filteredAttrs: options.filterAttrs
562
- };
563
- console.debug(`[rocketstyle] ${componentName} render:`, debugPayload);
508
+ return (() => {
509
+ const theme = themeAttrs.theme;
510
+ const mode = themeAttrs.mode;
511
+ const baseThemeHelper = ThemeManager$1.baseTheme;
512
+ if (!baseThemeHelper.has(theme)) baseThemeHelper.set(theme, getThemeFromChain(options.theme, theme));
513
+ const baseTheme = baseThemeHelper.get(theme);
514
+ const dimHelper = ThemeManager$1.dimensionsThemes;
515
+ if (!dimHelper.has(theme)) dimHelper.set(theme, getDimensionThemes(theme, options));
516
+ const themes = dimHelper.get(theme);
517
+ const modeBaseHelper = ThemeManager$1.modeBaseTheme[mode];
518
+ if (!modeBaseHelper.has(baseTheme)) modeBaseHelper.set(baseTheme, getThemeByMode(baseTheme, mode));
519
+ const currentModeBaseTheme = modeBaseHelper.get(baseTheme);
520
+ const modeDimHelper = ThemeManager$1.modeDimensionTheme[mode];
521
+ if (!modeDimHelper.has(themes)) modeDimHelper.set(themes, getThemeByMode(themes, mode));
522
+ const currentModeThemes = modeDimHelper.get(themes);
523
+ const { keysMap: dimensions, keywords: reservedPropNames } = getDimensionsMap({
524
+ themes,
525
+ useBooleans: options.useBooleans
526
+ });
527
+ const RESERVED_STYLING_PROPS_KEYS = Object.keys(reservedPropNames);
528
+ const rocketstate = _calculateStylingAttrs({
529
+ props: pickStyledAttrs(mergeProps, reservedPropNames),
530
+ dimensions
531
+ });
532
+ const finalRocketstate = {
533
+ ...rocketstate,
534
+ pseudo: pseudoRocketstate
535
+ };
536
+ const computedRocketstyle = getTheme({
537
+ rocketstate,
538
+ themes: currentModeThemes,
539
+ baseTheme: currentModeBaseTheme,
540
+ transformKeys: options.transformKeys,
541
+ appTheme: theme
542
+ });
543
+ const finalProps = {
544
+ ...omit(mergeProps, [
545
+ ...RESERVED_STYLING_PROPS_KEYS,
546
+ ...PSEUDO_KEYS,
547
+ ...options.filterAttrs
548
+ ]),
549
+ ...options.passProps ? pick(mergeProps, options.passProps) : {},
550
+ ref: props.ref,
551
+ $rocketstyle: computedRocketstyle,
552
+ $rocketstate: finalRocketstate
553
+ };
554
+ if (process.env.NODE_ENV !== "production") {
555
+ finalProps["data-rocketstyle"] = componentName;
556
+ if (options.DEBUG) {
557
+ const debugPayload = {
558
+ component: componentName,
559
+ rocketstate: finalRocketstate,
560
+ rocketstyle: computedRocketstyle,
561
+ dimensions,
562
+ mode,
563
+ reservedPropNames: RESERVED_STYLING_PROPS_KEYS,
564
+ filteredAttrs: options.filterAttrs
565
+ };
566
+ console.debug(`[rocketstyle] ${componentName} render:`, debugPayload);
567
+ }
564
568
  }
565
- }
566
- return RenderComponent(finalProps);
569
+ return RenderComponent(finalProps);
570
+ });
567
571
  };
568
572
  const FinalComponent = compose(...hocsFuncs)(EnhancedComponent);
569
573
  FinalComponent.IS_ROCKETSTYLE = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pyreon/rocketstyle",
3
- "version": "0.11.3",
3
+ "version": "0.11.4",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/pyreon/pyreon",
@@ -44,13 +44,13 @@
44
44
  "typecheck": "tsc --noEmit"
45
45
  },
46
46
  "peerDependencies": {
47
- "@pyreon/core": "^0.11.3",
48
- "@pyreon/reactivity": "^0.11.3",
49
- "@pyreon/ui-core": "^0.11.3",
50
- "@pyreon/styler": "^0.11.3"
47
+ "@pyreon/core": "^0.11.4",
48
+ "@pyreon/reactivity": "^0.11.4",
49
+ "@pyreon/ui-core": "^0.11.4",
50
+ "@pyreon/styler": "^0.11.4"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@vitus-labs/tools-rolldown": "^1.15.3",
54
- "@pyreon/typescript": "^0.11.3"
54
+ "@pyreon/typescript": "^0.11.4"
55
55
  }
56
56
  }
@@ -64,7 +64,10 @@ const getComputedTheme = (Component: any, props: Record<string, any> = {}) => {
64
64
  ]),
65
65
  )
66
66
  try {
67
- const vnode = Component(props) as any
67
+ let vnode = Component(props) as any
68
+ // EnhancedComponent returns a reactive accessor (function) for mode switching.
69
+ // In tests we evaluate it directly to get the VNode.
70
+ while (typeof vnode === "function") vnode = vnode()
68
71
  return vnode.$rocketstyle
69
72
  } finally {
70
73
  popContext()
@@ -60,6 +60,13 @@ const ChildComponent: any = ({
60
60
  })
61
61
  ChildComponent.displayName = "ChildComponent"
62
62
 
63
+ /** Unwrap reactive accessors (EnhancedComponent returns a function for mode switching). */
64
+ const unwrap = (val: any): any => {
65
+ let result = val
66
+ while (typeof result === "function" && !result.IS_ROCKETSTYLE) result = result()
67
+ return result
68
+ }
69
+
63
70
  /** Push a theme context and run fn, then pop */
64
71
  const withThemeContext = (fn: () => any) => {
65
72
  pushContext(
@@ -103,7 +110,7 @@ describe("Provider/Consumer integration", () => {
103
110
  component: BaseComponent,
104
111
  }).config({ provider: true })
105
112
 
106
- const result = withThemeContext(() => ParentButton({ children: "Child" }))
113
+ const result = withThemeContext(() => unwrap(ParentButton({ children: "Child" })))
107
114
  // Provider wraps with createLocalProvider which injects pseudo state
108
115
  // Initial state should be false
109
116
  expect(result.props["data-hover"]).toBe("false")
@@ -131,9 +138,9 @@ describe("Provider/Consumer integration", () => {
131
138
 
132
139
  // Render parent, then render child within the same context
133
140
  withThemeContext(() => {
134
- const _parentResult = Parent({ children: null })
141
+ const _parentResult = unwrap(Parent({ children: null }))
135
142
  // The parent pushes local context — child should see it
136
- const childResult = Child({})
143
+ const childResult = unwrap(Child({}))
137
144
  expect(childResult).toBeDefined()
138
145
  const childProps = childResult?.props ?? childResult
139
146
  expect(childProps["data-parent-hover"]).toBe("no")
@@ -151,7 +158,7 @@ describe("Provider/Consumer integration", () => {
151
158
  })),
152
159
  })
153
160
 
154
- const result = withThemeContext(() => Child({}))
161
+ const result = withThemeContext(() => unwrap(Child({})))
155
162
  const props = result?.props ?? result
156
163
  expect(props["data-parent-hover"]).toBe("no")
157
164
  })
@@ -66,10 +66,17 @@ const withThemeContext = (fn: () => any) => {
66
66
  }
67
67
  }
68
68
 
69
+ /** Unwrap reactive accessors (EnhancedComponent returns a function for mode switching). */
70
+ const unwrap = (val: any): any => {
71
+ let result = val
72
+ while (typeof result === "function" && !result.IS_ROCKETSTYLE) result = result()
73
+ return result
74
+ }
75
+
69
76
  /** Helper: call the component and return its output for inspection. */
70
77
  const renderProps = (Component: any, props: Record<string, any> = {}) => {
71
78
  return withThemeContext(() => {
72
- const vnode = Component(props) as any
79
+ const vnode = unwrap(Component(props))
73
80
  return vnode?.props ?? vnode
74
81
  })
75
82
  }
@@ -584,7 +591,7 @@ describe("theme and state injection", () => {
584
591
  primary: { color: "red" },
585
592
  }))
586
593
 
587
- const vnode = withThemeContext(() => Button({ state: "primary" }))
594
+ const vnode = withThemeContext(() => unwrap(Button({ state: "primary" })))
588
595
  expect(vnode.$rocketstyle).toBeDefined()
589
596
  expect(vnode.$rocketstyle.color).toBe("red")
590
597
  expect(vnode.$rocketstyle.bg).toBe("white")
@@ -608,7 +615,7 @@ describe("theme and state injection", () => {
608
615
  primary: { color: "blue" },
609
616
  }))
610
617
 
611
- const vnode = withThemeContext(() => Button({ state: "primary" }))
618
+ const vnode = withThemeContext(() => unwrap(Button({ state: "primary" })))
612
619
  expect(vnode.$rocketstate).toBeDefined()
613
620
  expect(vnode.$rocketstate.state).toBe("primary")
614
621
  })
@@ -27,11 +27,15 @@ const rocketStyleHOC: RocketStyleHOC = ({ inversed, attrs, priorityAttrs }) => {
27
27
 
28
28
  const Enhanced = (WrappedComponent: ComponentFn<any>) => {
29
29
  const HOCComponent: ComponentFn<any> = (props) => {
30
- const { theme, mode, isDark, isLight } = useTheme({
31
- inversed,
32
- })
30
+ // IMPORTANT: Do NOT destructure useTheme returns getter properties.
31
+ // Destructuring calls getters once and captures static values.
32
+ // Keep the object reference so properties re-evaluate lazily.
33
+ const themeAttrs = useTheme({ inversed })
33
34
 
34
- const callbackParams = [theme, { render, mode, isDark, isLight }]
35
+ const callbackParams = [
36
+ themeAttrs.theme,
37
+ { render, mode: themeAttrs.mode, isDark: themeAttrs.isDark, isLight: themeAttrs.isLight },
38
+ ]
35
39
 
36
40
  // Remove undefined props not to override potential default props
37
41
  const filteredProps = removeUndefinedProps(props)
@@ -104,120 +104,138 @@ const rocketComponent: RocketComponent = (options) => {
104
104
  // --------------------------------------------------
105
105
  // general theme and theme mode dark / light passed in context
106
106
  // --------------------------------------------------
107
- const { theme, mode } = useTheme(options)
107
+ // IMPORTANT: Do NOT destructure useTheme returns getter properties.
108
+ // Destructuring calls getters once and captures static values.
109
+ // Keep the object reference so mode/isDark/isLight re-evaluate lazily.
110
+ const themeAttrs = useTheme(options)
108
111
 
109
112
  // --------------------------------------------------
110
- // calculate themes for all defined styling dimensions
111
- // --------------------------------------------------
112
-
113
- // BASE / DEFAULT THEME Object (cached by theme identity)
114
- const baseThemeHelper = ThemeManager.baseTheme
115
- if (!baseThemeHelper.has(theme)) {
116
- baseThemeHelper.set(theme, getThemeFromChain(options.theme, theme))
117
- }
118
- const baseTheme = baseThemeHelper.get(theme)
119
-
120
- // DIMENSION(S) THEMES Object (cached by theme identity)
121
- const dimHelper = ThemeManager.dimensionsThemes
122
- if (!dimHelper.has(theme)) {
123
- dimHelper.set(theme, getDimensionThemes(theme, options))
124
- }
125
- const themes = dimHelper.get(theme)
126
-
127
- // BASE / DEFAULT MODE THEME Object (cached by mode + baseTheme)
128
- const modeBaseHelper = ThemeManager.modeBaseTheme[mode]
129
- if (!modeBaseHelper.has(baseTheme)) {
130
- modeBaseHelper.set(baseTheme, getThemeByMode(baseTheme, mode))
131
- }
132
- const currentModeBaseTheme = modeBaseHelper.get(baseTheme)
133
-
134
- // DIMENSION(S) MODE THEMES Object (cached by mode + themes)
135
- const modeDimHelper = ThemeManager.modeDimensionTheme[mode]
136
- if (!modeDimHelper.has(themes)) {
137
- modeDimHelper.set(themes, getThemeByMode(themes, mode))
138
- }
139
- const currentModeThemes = modeDimHelper.get(themes)
140
-
141
- // --------------------------------------------------
142
- // dimension map & reserved prop names
143
- // --------------------------------------------------
144
- const { keysMap: dimensions, keywords: reservedPropNames } = getDimensionsMap({
145
- themes,
146
- useBooleans: options.useBooleans,
147
- })
148
-
149
- const RESERVED_STYLING_PROPS_KEYS = Object.keys(reservedPropNames)
150
-
151
- // --------------------------------------------------
152
- // get final props: merged styling from context + attrs + direct props
113
+ // Static setup runs once at component mount
153
114
  // --------------------------------------------------
154
115
  const { pseudo, ...mergeProps } = {
155
116
  ...localCtx,
156
117
  ...props,
157
118
  }
158
119
 
159
- // --------------------------------------------------
160
- // pseudo rocket state
161
- // --------------------------------------------------
162
120
  const pseudoRocketstate = {
163
121
  ...pseudo,
164
122
  ...pick(props, [...PSEUDO_KEYS, ...PSEUDO_META_KEYS]),
165
123
  }
166
124
 
167
125
  // --------------------------------------------------
168
- // rocketstateactive dimension values
126
+ // Reactive accessor re-evaluates when mode changes.
127
+ // When mounted, the runtime wraps this in an effect so
128
+ // reading themeAttrs.mode creates a reactive dependency.
129
+ // Mode switches are infrequent (user-initiated), so full
130
+ // re-render of the styled subtree is acceptable.
169
131
  // --------------------------------------------------
170
- const rocketstate = _calculateStylingAttrs({
171
- props: pickStyledAttrs(mergeProps, reservedPropNames),
172
- dimensions,
173
- })
132
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: theme resolution is inherently multi-step
133
+ return (() => {
134
+ // Read theme and mode lazily via getters — tracked by the effect
135
+ const theme = themeAttrs.theme
136
+ const mode = themeAttrs.mode
137
+
138
+ // --------------------------------------------------
139
+ // calculate themes for all defined styling dimensions
140
+ // --------------------------------------------------
141
+
142
+ // BASE / DEFAULT THEME Object (cached by theme identity)
143
+ const baseThemeHelper = ThemeManager.baseTheme
144
+ if (!baseThemeHelper.has(theme)) {
145
+ baseThemeHelper.set(theme, getThemeFromChain(options.theme, theme))
146
+ }
147
+ const baseTheme = baseThemeHelper.get(theme)
174
148
 
175
- const finalRocketstate = { ...rocketstate, pseudo: pseudoRocketstate }
149
+ // DIMENSION(S) THEMES Object (cached by theme identity)
150
+ const dimHelper = ThemeManager.dimensionsThemes
151
+ if (!dimHelper.has(theme)) {
152
+ dimHelper.set(theme, getDimensionThemes(theme, options))
153
+ }
154
+ const themes = dimHelper.get(theme)
176
155
 
177
- // --------------------------------------------------
178
- // rocketstyle computed theme based on active dimensions
179
- // --------------------------------------------------
180
- const computedRocketstyle = getTheme({
181
- rocketstate,
182
- themes: currentModeThemes,
183
- baseTheme: currentModeBaseTheme,
184
- transformKeys: options.transformKeys,
185
- appTheme: theme,
186
- })
156
+ // BASE / DEFAULT MODE THEME Object (cached by mode + baseTheme)
157
+ const modeBaseHelper = ThemeManager.modeBaseTheme[mode]
158
+ if (!modeBaseHelper.has(baseTheme)) {
159
+ modeBaseHelper.set(baseTheme, getThemeByMode(baseTheme, mode))
160
+ }
161
+ const currentModeBaseTheme = modeBaseHelper.get(baseTheme)
187
162
 
188
- // --------------------------------------------------
189
- // final props passed to WrappedComponent
190
- // --------------------------------------------------
191
- const finalProps: Record<string, any> = {
192
- ...omit(mergeProps, [...RESERVED_STYLING_PROPS_KEYS, ...PSEUDO_KEYS, ...options.filterAttrs]),
193
- ...(options.passProps ? pick(mergeProps, options.passProps) : {}),
194
- // ref flows as a normal prop in Pyreon
195
- ref: props.ref,
196
- $rocketstyle: computedRocketstyle,
197
- $rocketstate: finalRocketstate,
198
- }
163
+ // DIMENSION(S) MODE THEMES Object (cached by mode + themes)
164
+ const modeDimHelper = ThemeManager.modeDimensionTheme[mode]
165
+ if (!modeDimHelper.has(themes)) {
166
+ modeDimHelper.set(themes, getThemeByMode(themes, mode))
167
+ }
168
+ const currentModeThemes = modeDimHelper.get(themes)
199
169
 
200
- // development debugging
201
- if (process.env.NODE_ENV !== "production") {
202
- finalProps["data-rocketstyle"] = componentName
170
+ // --------------------------------------------------
171
+ // dimension map & reserved prop names
172
+ // --------------------------------------------------
173
+ const { keysMap: dimensions, keywords: reservedPropNames } = getDimensionsMap({
174
+ themes,
175
+ useBooleans: options.useBooleans,
176
+ })
203
177
 
204
- if (options.DEBUG) {
205
- const debugPayload = {
206
- component: componentName,
207
- rocketstate: finalRocketstate,
208
- rocketstyle: computedRocketstyle,
209
- dimensions,
210
- mode,
211
- reservedPropNames: RESERVED_STYLING_PROPS_KEYS,
212
- filteredAttrs: options.filterAttrs,
213
- }
178
+ const RESERVED_STYLING_PROPS_KEYS = Object.keys(reservedPropNames)
179
+
180
+ // --------------------------------------------------
181
+ // rocketstate — active dimension values
182
+ // --------------------------------------------------
183
+ const rocketstate = _calculateStylingAttrs({
184
+ props: pickStyledAttrs(mergeProps, reservedPropNames),
185
+ dimensions,
186
+ })
187
+
188
+ const finalRocketstate = { ...rocketstate, pseudo: pseudoRocketstate }
189
+
190
+ // --------------------------------------------------
191
+ // rocketstyle — computed theme based on active dimensions
192
+ // --------------------------------------------------
193
+ const computedRocketstyle = getTheme({
194
+ rocketstate,
195
+ themes: currentModeThemes,
196
+ baseTheme: currentModeBaseTheme,
197
+ transformKeys: options.transformKeys,
198
+ appTheme: theme,
199
+ })
214
200
 
215
- // biome-ignore lint/suspicious/noConsole: debug logging controlled by DEBUG option
216
- console.debug(`[rocketstyle] ${componentName} render:`, debugPayload)
201
+ // --------------------------------------------------
202
+ // final props passed to WrappedComponent
203
+ // --------------------------------------------------
204
+ const finalProps: Record<string, any> = {
205
+ ...omit(mergeProps, [
206
+ ...RESERVED_STYLING_PROPS_KEYS,
207
+ ...PSEUDO_KEYS,
208
+ ...options.filterAttrs,
209
+ ]),
210
+ ...(options.passProps ? pick(mergeProps, options.passProps) : {}),
211
+ // ref flows as a normal prop in Pyreon
212
+ ref: props.ref,
213
+ $rocketstyle: computedRocketstyle,
214
+ $rocketstate: finalRocketstate,
215
+ }
216
+
217
+ // development debugging
218
+ if (process.env.NODE_ENV !== "production") {
219
+ finalProps["data-rocketstyle"] = componentName
220
+
221
+ if (options.DEBUG) {
222
+ const debugPayload = {
223
+ component: componentName,
224
+ rocketstate: finalRocketstate,
225
+ rocketstyle: computedRocketstyle,
226
+ dimensions,
227
+ mode,
228
+ reservedPropNames: RESERVED_STYLING_PROPS_KEYS,
229
+ filteredAttrs: options.filterAttrs,
230
+ }
231
+
232
+ // biome-ignore lint/suspicious/noConsole: debug logging controlled by DEBUG option
233
+ console.debug(`[rocketstyle] ${componentName} render:`, debugPayload)
234
+ }
217
235
  }
218
- }
219
236
 
220
- return RenderComponent(finalProps)
237
+ return RenderComponent(finalProps)
238
+ }) as unknown as ReturnType<ComponentFn<InnerComponentProps>>
221
239
  }
222
240
 
223
241
  // ------------------------------------------------------