@meonode/ui 0.4.12 → 0.4.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,218 +2,354 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [0.4.14] - 2025-11-23
6
+
7
+ ### Perf
8
+
9
+ - **cache**: enforce dependency-based caching with shouldCacheElement helper ([
10
+ `0df9b3b`](https://github.com/l7aromeo/meonode-ui/commit/0df9b3b28c7874acbf33826ab7bb17f8b0464250))
11
+ - Introduces NodeUtil.shouldCacheElement() helper to centralize and enforce the opt-in caching strategy where only
12
+ nodes with explicit dependencies are cached
13
+ - Completes the memory optimization by closing loopholes where nodes without dependencies were still being cached
14
+ based on stableKey alone
15
+ - Replaces 4 inconsistent cache eligibility checks in BaseNode.render():
16
+ - Cache lookup for parent nodes
17
+ - Cache lookup for child nodes
18
+ - Cache storage during rendering
19
+ - MeoNodeUnmounter wrapping decision
20
+ - Impact: Reduces memory usage, ensures mount tracking and cache operations stay in sync, improves code
21
+ maintainability
22
+
23
+ ### Test
24
+
25
+ - **memoization**: refine test to assert precise cache size after rendering components ([
26
+ `8ded697`](https://github.com/l7aromeo/meonode-ui/commit/8ded6974cc1565c384abe1a3ca54e1f7bc8a9619))
27
+
28
+ ### Chore
29
+
30
+ - **type**: remove src/types/env.d.ts as it is no longer needed
31
+
32
+ ## [0.4.13] - 2025-11-23
33
+
34
+ ### Fix
35
+
36
+ - **props**: improve prop handling and prevent leakage ([
37
+ `73cc696`](https://github.com/l7aromeo/meonode-ui/commit/73cc696b3df8c1bd2ddef789de58febc6cd2f1c5))
38
+ - This commit refactors prop handling within the MeoNode ecosystem to ensure that internal processing props are not
39
+ leaked to the DOM.
40
+ - Key changes:
41
+ - The `MeoNodeUnmounter` is updated to correctly isolate and pass through props intended for the underlying DOM
42
+ element, improving compatibility with libraries like MUI.
43
+ - Internal props such as `node`, `css`, and `disableEmotion` are now explicitly prevented from being rendered as
44
+ HTML attributes.
45
+ - Added comprehensive tests to verify that standard HTML attributes are passed through while internal props are
46
+ successfully filtered out.
47
+ - This improves the robustness and predictability of component rendering.
48
+
49
+ ### Test
50
+
51
+ - **props**: add tests for prop handling and leakage ([
52
+ `a508e10`](https://github.com/l7aromeo/meonode-ui/commit/a508e107539d9ce84e8d99b63a0af329b28f3249))
53
+ - Added new tests to verify that component props are correctly passed as HTML attributes, handle createNode and
54
+ Node() correctly, and crucially, that internal MeoNode props are not leaked to the DOM.
55
+
56
+ ### Chore
57
+
58
+ - **core**: remove unnecessary type assertion from finalChildren assignment ([
59
+ `827b3ef`](https://github.com/l7aromeo/meonode-ui/commit/827b3ef4490bca08d58ef5fe1fd885aadbbb1524))
60
+
5
61
  ## [0.4.12] - 2025-11-21
6
62
 
7
63
  ### Feat
8
- - **build**: migrate from Babel to Rollup with ESM and CJS support ([`70326a1`](https://github.com/l7aromeo/meonode-ui/commit/70326a107259c095d571b838dda15ffbf845af1d))
9
- - Replace Babel build system with Rollup configuration to prevent output legacy javascript code
10
- - Add support for both ESM and CJS output formats
11
- - Update package.json exports to point to new build outputs
12
- - Add Rollup plugins for TypeScript, commonjs, minification, and preserve directives
13
- - Remove Babel-related dependencies and configuration files
14
- - Update tsconfig.json to use 'preserve' module setting and bundler resolution
15
- - Configure build to output to separate ESM and CJS directories
64
+
65
+ - **build**: migrate from Babel to Rollup with ESM and CJS support ([
66
+ `70326a1`](https://github.com/l7aromeo/meonode-ui/commit/70326a107259c095d571b838dda15ffbf845af1d))
67
+ - Replace Babel build system with Rollup configuration to prevent output legacy javascript code
68
+ - Add support for both ESM and CJS output formats
69
+ - Update package.json exports to point to new build outputs
70
+ - Add Rollup plugins for TypeScript, commonjs, minification, and preserve directives
71
+ - Remove Babel-related dependencies and configuration files
72
+ - Update tsconfig.json to use 'preserve' module setting and bundler resolution
73
+ - Configure build to output to separate ESM and CJS directories
16
74
 
17
75
  ## [0.4.11] - 2025-11-21
18
76
 
19
77
  ### Fix
20
- - **core**: enhance MeoNodeUnmounter cleanup logic and support additional props cloning ([`02c17f7`](https://github.com/l7aromeo/meonode-ui/commit/02c17f7))
21
- - Refactor MeoNodeUnmounter to use useEffectEvent for stable cleanup on unmount
22
- - Cleanup removes node from BaseNode.elementCache, untracks mount via MountTrackerUtil, unregisters from BaseNode.cacheCleanupRegistry, and clears lastSignature to prevent memory leaks
23
- - Support cloning and forwarding additional props to valid React children elements
78
+
79
+ - **core**: enhance MeoNodeUnmounter cleanup logic and support additional props cloning ([
80
+ `02c17f7`](https://github.com/l7aromeo/meonode-ui/commit/02c17f7))
81
+ - Refactor MeoNodeUnmounter to use useEffectEvent for stable cleanup on unmount
82
+ - Cleanup removes node from BaseNode.elementCache, untracks mount via MountTrackerUtil, unregisters from
83
+ BaseNode.cacheCleanupRegistry, and clears lastSignature to prevent memory leaks
84
+ - Support cloning and forwarding additional props to valid React children elements
24
85
 
25
86
  ### Refactor
26
- - **node.util**: enhance documentation for utility methods and improve clarity ([`ee42c24`](https://github.com/l7aromeo/meonode-ui/commit/ee42c24))
27
- - **theme**: reorder ThemeResolverCache methods for clarity ([`cb842c8`](https://github.com/l7aromeo/meonode-ui/commit/cb842c8))
28
- - Moved `_generateCacheKey` and `_evict` methods below the main logic in `ThemeResolverCache` for better readability and organization
29
- - Removed duplicate declaration of `_instance` property
30
- - Kept functionality unchanged, improving code structure and maintainability
87
+
88
+ - **node.util**: enhance documentation for utility methods and improve clarity ([
89
+ `ee42c24`](https://github.com/l7aromeo/meonode-ui/commit/ee42c24))
90
+ - **theme**: reorder ThemeResolverCache methods for clarity ([
91
+ `cb842c8`](https://github.com/l7aromeo/meonode-ui/commit/cb842c8))
92
+ - Moved `_generateCacheKey` and `_evict` methods below the main logic in `ThemeResolverCache` for better readability
93
+ and organization
94
+ - Removed duplicate declaration of `_instance` property
95
+ - Kept functionality unchanged, improving code structure and maintainability
31
96
 
32
97
  ### Test
33
- - **perf**: add memory leak detection test for navigation cycles and improve formatMemory function ([`ba139fc`](https://github.com/l7aromeo/meonode-ui/commit/ba139fc))
34
- - Added a new performance test to detect memory leaks during repeated navigation cycles between pages
35
- - The test measures heap memory usage before, during, and after navigation, ensuring memory growth stays within acceptable limits
36
- - Enhanced the formatMemory utility to correctly handle negative byte values and added JSDoc comments for clarity
37
- - Removed an obsolete shallowly equal props performance test to streamline the test suite
38
- - **unmounter**: add regression test for MeoNodeUnmounter to forward implicit props in MUI RadioGroup integration ([`2ecaabd`](https://github.com/l7aromeo/meonode-ui/commit/2ecaabd))
39
- - Added a test to ensure MeoNodeUnmounter correctly forwards props injected via React.cloneElement, addressing issues with libraries like MUI where RadioGroup injects 'checked' and 'onChange' into Radio components
40
- - This prevents swallowing of props and verifies proper behavior of controlled radio inputs
41
- - Also updated an existing cache size assertion to allow equality, reflecting improved mount tracking
42
- - **perf**: update react-createelement comparison tests with 5000 nested nodes and fix typings ([`b345ec0`](https://github.com/l7aromeo/meonode-ui/commit/b345ec0))
43
- - Changed rerender to use React.cloneElement<any> for proper typing
44
- - Updated NUM_NODES constant to 5000 for nested structure tests
45
- - Removed redundant comments about node count reduction to prevent stack overflow
98
+
99
+ - **perf**: add memory leak detection test for navigation cycles and improve formatMemory function ([
100
+ `ba139fc`](https://github.com/l7aromeo/meonode-ui/commit/ba139fc))
101
+ - Added a new performance test to detect memory leaks during repeated navigation cycles between pages
102
+ - The test measures heap memory usage before, during, and after navigation, ensuring memory growth stays within
103
+ acceptable limits
104
+ - Enhanced the formatMemory utility to correctly handle negative byte values and added JSDoc comments for clarity
105
+ - Removed an obsolete shallowly equal props performance test to streamline the test suite
106
+ - **unmounter**: add regression test for MeoNodeUnmounter to forward implicit props in MUI RadioGroup integration ([
107
+ `2ecaabd`](https://github.com/l7aromeo/meonode-ui/commit/2ecaabd))
108
+ - Added a test to ensure MeoNodeUnmounter correctly forwards props injected via React.cloneElement, addressing
109
+ issues with libraries like MUI where RadioGroup injects 'checked' and 'onChange' into Radio components
110
+ - This prevents swallowing of props and verifies proper behavior of controlled radio inputs
111
+ - Also updated an existing cache size assertion to allow equality, reflecting improved mount tracking
112
+ - **perf**: update react-createelement comparison tests with 5000 nested nodes and fix typings ([
113
+ `b345ec0`](https://github.com/l7aromeo/meonode-ui/commit/b345ec0))
114
+ - Changed rerender to use React.cloneElement<any> for proper typing
115
+ - Updated NUM_NODES constant to 5000 for nested structure tests
116
+ - Removed redundant comments about node count reduction to prevent stack overflow
46
117
 
47
118
  ### Chore
48
- - **deps**: upgrade devDependencies and update test scripts ([`2ea128e`](https://github.com/l7aromeo/meonode-ui/commit/2ea128e))
49
- - add new devDependencies: @emotion/is-prop-valid@1.4.0, @emotion/styled@11.14.1, @mui/material@7.3.5, and related packages
50
- - update yarn to version 4.11.0
51
- - update test scripts to increase max-old-space-size to 8192 and include react-createelement-comparison.test.ts in test and perf runs
52
- - update various package resolutions in yarn.lock to align with new versions and dependencies
53
- - **babel**: add "builtIns": false to minify plugin configuration ([`e16cdfb`](https://github.com/l7aromeo/meonode-ui/commit/e16cdfb))
119
+
120
+ - **deps**: upgrade devDependencies and update test scripts ([
121
+ `2ea128e`](https://github.com/l7aromeo/meonode-ui/commit/2ea128e))
122
+ - add new devDependencies: @emotion/is-prop-valid@1.4.0, @emotion/styled@11.14.1, @mui/material@7.3.5, and related
123
+ packages
124
+ - update yarn to version 4.11.0
125
+ - update test scripts to increase max-old-space-size to 8192 and include react-createelement-comparison.test.ts in
126
+ test and perf runs
127
+ - update various package resolutions in yarn.lock to align with new versions and dependencies
128
+ - **babel**: add "builtIns": false to minify plugin configuration ([
129
+ `e16cdfb`](https://github.com/l7aromeo/meonode-ui/commit/e16cdfb))
54
130
  - **yarn**: update yarnPath to version 4.11.0 ([`ecb6c68`](https://github.com/l7aromeo/meonode-ui/commit/ecb6c68))
55
131
 
56
132
  ### Docs
57
- - **CONTRIBUTING**: improve formatting and readability of contribution guidelines ([`a7462ed`](https://github.com/l7aromeo/meonode-ui/commit/a7462ed))
133
+
134
+ - **CONTRIBUTING**: improve formatting and readability of contribution guidelines ([
135
+ `a7462ed`](https://github.com/l7aromeo/meonode-ui/commit/a7462ed))
58
136
 
59
137
  ## [0.4.10] - 2025-11-20
60
138
 
61
139
  ### Fix
62
- - **unmounter**: prevent redundant FinalizationRegistry callbacks ([`59f5adf`](https://github.com/l7aromeo/meonode-ui/commit/59f5adf2f553aa49a88d1b44366b004d829ca107))
63
- - Explicitly unregister node from cacheCleanupRegistry on unmount
64
- - Prevents double cleanup when node is both unmounted and GC'd
65
- - Improves cleanup efficiency and reduces unnecessary registry callbacks
140
+
141
+ - **unmounter**: prevent redundant FinalizationRegistry callbacks ([
142
+ `59f5adf`](https://github.com/l7aromeo/meonode-ui/commit/59f5adf2f553aa49a88d1b44366b004d829ca107))
143
+ - Explicitly unregister node from cacheCleanupRegistry on unmount
144
+ - Prevents double cleanup when node is both unmounted and GC'd
145
+ - Improves cleanup efficiency and reduces unnecessary registry callbacks
66
146
 
67
147
  ### Perf
68
- - **util**: optimize prop processing and child handling ([`be26488`](https://github.com/l7aromeo/meonode-ui/commit/be26488e304629dd13851dfcaa7fedf43ad8b5c3))
69
- - Conditional sort: only sort keys if length > 1 (eliminates unnecessary sorts)
70
- - Replace for...in with Object.keys() iteration for better performance and safety
71
- - Add fast path for single child processing (non-array or 1-element array)
72
- - Avoid unnecessary array operations for common single-child case
73
- - Performance impact:
74
- - Reduced CPU overhead for small prop objects
75
- - Faster iteration with Object.keys() vs for...in
76
- - Eliminates array map() call for single child components
77
-
78
- - **core**: add exception safety and optimize render method ([`5aad000`](https://github.com/l7aromeo/meonode-ui/commit/5aad000335ff29f078a9d40192d5a70fe9b61d12))
79
- - Wrap render logic in try-finally to ensure renderContext is always released
80
- - Null out workStack slots before releasing to help GC
81
- - Pre-allocate finalChildren array to avoid resizing during iteration
82
- - Replace non-null assertion with explicit error handling for better debugging
83
- - Add object pooling for workStack and renderedElements (reduces GC pressure)
84
- - Pool capped at 50 contexts with 2048-item limit to prevent memory issues
85
- - Exception safety ensures cleanup even if rendering throws
148
+
149
+ - **util**: optimize prop processing and child handling ([
150
+ `be26488`](https://github.com/l7aromeo/meonode-ui/commit/be26488e304629dd13851dfcaa7fedf43ad8b5c3))
151
+ - Conditional sort: only sort keys if length > 1 (eliminates unnecessary sorts)
152
+ - Replace for...in with Object.keys() iteration for better performance and safety
153
+ - Add fast path for single child processing (non-array or 1-element array)
154
+ - Avoid unnecessary array operations for common single-child case
155
+ - Performance impact:
156
+ - Reduced CPU overhead for small prop objects
157
+ - Faster iteration with Object.keys() vs for...in
158
+ - Eliminates array map() call for single child components
159
+
160
+ - **core**: add exception safety and optimize render method ([
161
+ `5aad000`](https://github.com/l7aromeo/meonode-ui/commit/5aad000335ff29f078a9d40192d5a70fe9b61d12))
162
+ - Wrap render logic in try-finally to ensure renderContext is always released
163
+ - Null out workStack slots before releasing to help GC
164
+ - Pre-allocate finalChildren array to avoid resizing during iteration
165
+ - Replace non-null assertion with explicit error handling for better debugging
166
+ - Add object pooling for workStack and renderedElements (reduces GC pressure)
167
+ - Pool capped at 50 contexts with 2048-item limit to prevent memory issues
168
+ - Exception safety ensures cleanup even if rendering throws
86
169
 
87
170
  ### Test
88
- - **perf**: add React comparison tests with memory tracking ([`bc66d54`](https://github.com/l7aromeo/meonode-ui/commit/bc66d540c4ffa4ad083322dbdbc201f652ea5314))
89
- - Add comprehensive performance comparison between React.createElement and MeoNode
90
- - Test both flat (10k nodes) and nested (5k nodes) structures
91
- - Include memory usage measurements (initial + after 100 updates)
92
- - Reduce nested nodes from 10k to 5k to prevent stack overflow with StyledRenderer
93
- - Add table output with time and memory columns for clear comparison
94
- - Add GC availability warning for accurate measurements
95
- - Provides detailed performance and memory behavior insights during re-renders
96
- - Avoids stack overflow in deeply nested test scenarios
97
-
98
- - **performance**: enhance performance metrics report formatting and adjust thresholds ([`6f3abe4`](https://github.com/l7aromeo/meonode-ui/commit/6f3abe4442938aa6cd414341fdf2aba25a9ece58))
99
- - Improve table formatting for performance metrics
100
- - Adjust test thresholds based on optimization results
101
- - Enhanced reporting for better visibility into performance characteristics
171
+
172
+ - **perf**: add React comparison tests with memory tracking ([
173
+ `bc66d54`](https://github.com/l7aromeo/meonode-ui/commit/bc66d540c4ffa4ad083322dbdbc201f652ea5314))
174
+ - Add comprehensive performance comparison between React.createElement and MeoNode
175
+ - Test both flat (10k nodes) and nested (5k nodes) structures
176
+ - Include memory usage measurements (initial + after 100 updates)
177
+ - Reduce nested nodes from 10k to 5k to prevent stack overflow with StyledRenderer
178
+ - Add table output with time and memory columns for clear comparison
179
+ - Add GC availability warning for accurate measurements
180
+ - Provides detailed performance and memory behavior insights during re-renders
181
+ - Avoids stack overflow in deeply nested test scenarios
182
+
183
+ - **performance**: enhance performance metrics report formatting and adjust thresholds ([
184
+ `6f3abe4`](https://github.com/l7aromeo/meonode-ui/commit/6f3abe4442938aa6cd414341fdf2aba25a9ece58))
185
+ - Improve table formatting for performance metrics
186
+ - Adjust test thresholds based on optimization results
187
+ - Enhanced reporting for better visibility into performance characteristics
102
188
 
103
189
  ## [0.4.9] - 2025-11-19
104
190
 
105
191
  ### Feat
106
- - **build**: add support for @tests alias and include tests folder in build and test configs ([`4dfd165`](https://github.com/l7aromeo/meonode-ui/commit/4dfd165fa52f93fe63ac7338344b91dfa5622c4b))
192
+
193
+ - **build**: add support for @tests alias and include tests folder in build and test configs ([
194
+ `4dfd165`](https://github.com/l7aromeo/meonode-ui/commit/4dfd165fa52f93fe63ac7338344b91dfa5622c4b))
107
195
 
108
196
  ### Perf
109
- - **core**: optimize rendering, caching, and memory management ([`4f599be`](https://github.com/l7aromeo/meonode-ui/commit/4f599be44458fef208a30849545606b060c4ec6b))
110
- - Reworks the core rendering loop to use a more efficient, manually-managed work stack with exponential growth, reducing reallocations and improving performance for deep and wide node trees.
111
- - Optimizes stable key generation by removing expensive shallow equality checks in favor of strict reference equality, significantly speeding up prop processing for cached components.
112
- - Implements a high-performance MinHeap-based LRU cache eviction strategy for prop processing, replacing a slower sort-based method. This ensures that the most relevant props are kept in the cache with minimal overhead.
113
- - Introduces CSS object hashing to accelerate prop signature generation, avoiding costly serialization of large style objects.
114
- - Fixes several memory leaks by ensuring proper cleanup of node properties (lastSignature, lastPropsObj) and unregistering nodes from the cache cleanup registry upon eviction.
115
- - Decouples element cache deletion from mount tracking to prevent race conditions and ensure reliable cleanup during component unmounting.
197
+
198
+ - **core**: optimize rendering, caching, and memory management ([
199
+ `4f599be`](https://github.com/l7aromeo/meonode-ui/commit/4f599be44458fef208a30849545606b060c4ec6b))
200
+ - Reworks the core rendering loop to use a more efficient, manually-managed work stack with exponential growth,
201
+ reducing reallocations and improving performance for deep and wide node trees.
202
+ - Optimizes stable key generation by removing expensive shallow equality checks in favor of strict reference
203
+ equality, significantly speeding up prop processing for cached components.
204
+ - Implements a high-performance MinHeap-based LRU cache eviction strategy for prop processing, replacing a slower
205
+ sort-based method. This ensures that the most relevant props are kept in the cache with minimal overhead.
206
+ - Introduces CSS object hashing to accelerate prop signature generation, avoiding costly serialization of large
207
+ style objects.
208
+ - Fixes several memory leaks by ensuring proper cleanup of node properties (lastSignature, lastPropsObj) and
209
+ unregistering nodes from the cache cleanup registry upon eviction.
210
+ - Decouples element cache deletion from mount tracking to prevent race conditions and ensure reliable cleanup during
211
+ component unmounting.
116
212
 
117
213
  ### Refactor
118
- - **build**: rename constants directory from constants to constant and update imports accordingly ([`9531947`](https://github.com/l7aromeo/meonode-ui/commit/9531947af9b304c11c0865e8deafa1a633220753))
214
+
215
+ - **build**: rename constants directory from constants to constant and update imports accordingly ([
216
+ `9531947`](https://github.com/l7aromeo/meonode-ui/commit/9531947af9b304c11c0865e8deafa1a633220753))
119
217
 
120
218
  ### Test
121
- - **perf**: overhaul performance test suite ([`e3bd6ac`](https://github.com/l7aromeo/meonode-ui/commit/e3bd6ac6ceca474f935da644ff0c23b2f1de7692))
122
- - Introduces a new, structured performance reporting system using cli-table3 for clear, grouped metrics.
123
- - Refactors the entire performance test suite into logical groups: Layout Rendering, Memory Management, and Prop Processing.
124
- - Adds comprehensive memory leak detection tests for heavy state changes and repeated mount/unmount cycles, using forced garbage collection for more accurate heap analysis.
125
- - Extracts the large, complex CSS object into a dedicated test constant for better separation of concerns.
126
- - Updates memoization tests to align with the new, weighted LRU cache eviction scoring.
219
+
220
+ - **perf**: overhaul performance test suite ([
221
+ `e3bd6ac`](https://github.com/l7aromeo/meonode-ui/commit/e3bd6ac6ceca474f935da644ff0c23b2f1de7692))
222
+ - Introduces a new, structured performance reporting system using cli-table3 for clear, grouped metrics.
223
+ - Refactors the entire performance test suite into logical groups: Layout Rendering, Memory Management, and Prop
224
+ Processing.
225
+ - Adds comprehensive memory leak detection tests for heavy state changes and repeated mount/unmount cycles, using
226
+ forced garbage collection for more accurate heap analysis.
227
+ - Extracts the large, complex CSS object into a dedicated test constant for better separation of concerns.
228
+ - Updates memoization tests to align with the new, weighted LRU cache eviction scoring.
127
229
 
128
230
  ### Chore
129
- - **deps**: update dependencies including typescript-eslint to 8.47.0 and add cli-table3 0.6.5 ([`6064555`](https://github.com/l7aromeo/meonode-ui/commit/6064555f0108ed47f9b31e98c4758f7449a67ff2))
231
+
232
+ - **deps**: update dependencies including typescript-eslint to 8.47.0 and add cli-table3 0.6.5 ([
233
+ `6064555`](https://github.com/l7aromeo/meonode-ui/commit/6064555f0108ed47f9b31e98c4758f7449a67ff2))
130
234
 
131
235
  ## [0.4.8] - 2025-11-18
132
236
 
133
237
  ### Feat
134
- - **client**: add generic type parameter to render function for stronger type safety ([`90a770e`](https://github.com/l7aromeo/meonode-ui/commit/90a770e))
135
- - **core**: improve BaseNode rendering with iterative traversal and memory optimizations ([`1d5330a`](https://github.com/l7aromeo/meonode-ui/commit/1d5330a))
136
- - Introduce WorkItem interface to represent nodes in the iterative work stack during BaseNode rendering.
137
- - Replace recursive render traversal with an iterative depth-first approach using a preallocated workStack array for better performance and reduced call stack usage.
138
- - Implement dynamic resizing of workStack array to handle arbitrary tree sizes efficiently.
139
- - Update BaseNode’s internal caching fields (`lastPropsRef` and `lastSignature`) to be public and consistently used for stable key generation.
140
- - Modify MeoNodeUnmounter component to accept BaseNode instance and clear its `lastPropsRef` and `lastSignature` on unmount to prevent memory leaks.
141
- - Refine type annotations across node utilities and factory functions for stronger type safety (`Record<string, unknown>` instead of `any`).
142
- - Optimize critical prop extraction logic by replacing Set and startsWith checks with faster inline charCode comparisons.
143
- - Clean up and clarify utility methods related to prop signature creation, shallow equality, and portal management.
144
- - Improve node.util.ts by adjusting caching strategies, prop categorization, and React element handling for better robustness and maintainability.
238
+
239
+ - **client**: add generic type parameter to render function for stronger type safety ([
240
+ `90a770e`](https://github.com/l7aromeo/meonode-ui/commit/90a770e))
241
+ - **core**: improve BaseNode rendering with iterative traversal and memory optimizations ([
242
+ `1d5330a`](https://github.com/l7aromeo/meonode-ui/commit/1d5330a))
243
+ - Introduce WorkItem interface to represent nodes in the iterative work stack during BaseNode rendering.
244
+ - Replace recursive render traversal with an iterative depth-first approach using a preallocated workStack array for
245
+ better performance and reduced call stack usage.
246
+ - Implement dynamic resizing of workStack array to handle arbitrary tree sizes efficiently.
247
+ - Update BaseNode’s internal caching fields (`lastPropsRef` and `lastSignature`) to be public and consistently used
248
+ for stable key generation.
249
+ - Modify MeoNodeUnmounter component to accept BaseNode instance and clear its `lastPropsRef` and `lastSignature` on
250
+ unmount to prevent memory leaks.
251
+ - Refine type annotations across node utilities and factory functions for stronger type safety (
252
+ `Record<string, unknown>` instead of `any`).
253
+ - Optimize critical prop extraction logic by replacing Set and startsWith checks with faster inline charCode
254
+ comparisons.
255
+ - Clean up and clarify utility methods related to prop signature creation, shallow equality, and portal management.
256
+ - Improve node.util.ts by adjusting caching strategies, prop categorization, and React element handling for better
257
+ robustness and maintainability.
145
258
 
146
259
  ### Fixes
147
- - **navigation-cache-manager**: add proper typing and global window declaration for cleanup flag ([`6180d40`](https://github.com/l7aromeo/meonode-ui/commit/6180d40))
260
+
261
+ - **navigation-cache-manager**: add proper typing and global window declaration for cleanup flag ([
262
+ `6180d40`](https://github.com/l7aromeo/meonode-ui/commit/6180d40))
148
263
 
149
264
  ### Refactor
150
- - improve typings and type safety in theme util and styled renderer ([`dbe1f33`](https://github.com/l7aromeo/meonode-ui/commit/dbe1f33))
151
- - Added explicit TypeScript types (e.g., CssProp, Record<string, unknown>) for variables and function signatures in `styled-renderer.client.ts` and `theme.util.ts`.
152
- - Updated cache maps to use more precise generic types for better type inference and safety.
153
- - Enhanced `resolveObjWithTheme` and related theme resolution logic with stronger typing and nullish coalescing.
154
- - Improved error handling for invalid theme path values.
155
- - Applied copy-on-write pattern with properly typed arrays and objects during theme resolution.
156
- - Strengthened type guards, e.g., `isPlainObject` type predicate.
157
- - Minor fixes to variable declarations with explicit types for clarity and consistency.
265
+
266
+ - improve typings and type safety in theme util and styled renderer ([
267
+ `dbe1f33`](https://github.com/l7aromeo/meonode-ui/commit/dbe1f33))
268
+ - Added explicit TypeScript types (e.g., CssProp, Record<string, unknown>) for variables and function signatures in
269
+ `styled-renderer.client.ts` and `theme.util.ts`.
270
+ - Updated cache maps to use more precise generic types for better type inference and safety.
271
+ - Enhanced `resolveObjWithTheme` and related theme resolution logic with stronger typing and nullish coalescing.
272
+ - Improved error handling for invalid theme path values.
273
+ - Applied copy-on-write pattern with properly typed arrays and objects during theme resolution.
274
+ - Strengthened type guards, e.g., `isPlainObject` type predicate.
275
+ - Minor fixes to variable declarations with explicit types for clarity and consistency.
158
276
 
159
277
  ### Chore
160
- - **babel**: update preset-env targets and expand plugin exclusions ([`f38cd24`](https://github.com/l7aromeo/meonode-ui/commit/f38cd24))
161
- - Set preset-env targets to support ES modules
162
- - Enable bugfixes option
163
- - Add multiple plugins to exclude list for better optimization
164
- - Clean up formatting of root, alias, extensions, and exclude fields
278
+
279
+ - **babel**: update preset-env targets and expand plugin exclusions ([
280
+ `f38cd24`](https://github.com/l7aromeo/meonode-ui/commit/f38cd24))
281
+ - Set preset-env targets to support ES modules
282
+ - Enable bugfixes option
283
+ - Add multiple plugins to exclude list for better optimization
284
+ - Clean up formatting of root, alias, extensions, and exclude fields
165
285
 
166
286
  ### Test
167
- - **performance**: add comprehensive performance tests and metrics reporting ([`c3d7a81`](https://github.com/l7aromeo/meonode-ui/commit/c3d7a81))
168
- - Add detailed performance tests measuring render times for realistic layouts, 10,000 flat nodes, and 10,000 deeply nested nodes.
169
- - Introduce a heavy state changes test to detect memory leaks and ensure responsiveness under frequent updates.
170
- - Collect and log performance metrics including median render times and memory usage for analysis.
171
- - Add tests for stableKey generation performance with identical, shallowly equal, unique, large, and complex CSS props.
172
- - Enhance test suite with CSS styling for better visualization and interaction during tests.
173
- - Improve cleanup and reporting to avoid resource leaks and provide clearer performance insights.
287
+
288
+ - **performance**: add comprehensive performance tests and metrics reporting ([
289
+ `c3d7a81`](https://github.com/l7aromeo/meonode-ui/commit/c3d7a81))
290
+ - Add detailed performance tests measuring render times for realistic layouts, 10,000 flat nodes, and 10,000 deeply
291
+ nested nodes.
292
+ - Introduce a heavy state changes test to detect memory leaks and ensure responsiveness under frequent updates.
293
+ - Collect and log performance metrics including median render times and memory usage for analysis.
294
+ - Add tests for stableKey generation performance with identical, shallowly equal, unique, large, and complex CSS
295
+ props.
296
+ - Enhance test suite with CSS styling for better visualization and interaction during tests.
297
+ - Improve cleanup and reporting to avoid resource leaks and provide clearer performance insights.
174
298
 
175
299
  ## [0.4.7] - 2025-11-17
176
300
 
177
301
  ### Fixes
178
- - **core/cache:** optimize navigation cache debounce timing and enhance stableKey handling ([`fff6f207`](https://github.com/l7aromeo/meonode-ui/commit/fff6f2070a06cc5ad461a2f992b111fb957fae6f))
179
- - Adjust navigation cleanup debounce duration dynamically based on cache size for better performance.
180
- - Change stableKey and _lastSignature to be optional to better represent their possible undefined state.
181
- - Refactor _getStableKey to return undefined on server instead of empty string.
182
- - Optimize critical props extraction by introducing NodeUtil.extractCriticalProps helper.
183
- - Improve client-side caching logic to avoid lookups when stableKey is absent.
184
- - Remove unused imports and redundant code in node.util.ts; improve shallowEqual implementation.
185
- - Update createPropSignature to return undefined on server and use getElementTypeName directly.
186
- - Add detailed comments and refine hashString combining FNV-1a and djb2 hashes for robustness.
302
+
303
+ - **core/cache:** optimize navigation cache debounce timing and enhance stableKey handling ([
304
+ `fff6f207`](https://github.com/l7aromeo/meonode-ui/commit/fff6f2070a06cc5ad461a2f992b111fb957fae6f))
305
+ - Adjust navigation cleanup debounce duration dynamically based on cache size for better performance.
306
+ - Change stableKey and _lastSignature to be optional to better represent their possible undefined state.
307
+ - Refactor _getStableKey to return undefined on server instead of empty string.
308
+ - Optimize critical props extraction by introducing NodeUtil.extractCriticalProps helper.
309
+ - Improve client-side caching logic to avoid lookups when stableKey is absent.
310
+ - Remove unused imports and redundant code in node.util.ts; improve shallowEqual implementation.
311
+ - Update createPropSignature to return undefined on server and use getElementTypeName directly.
312
+ - Add detailed comments and refine hashString combining FNV-1a and djb2 hashes for robustness.
187
313
 
188
314
  ## [0.4.6] - 2025-11-17
189
315
 
190
316
  ### Fixes
191
- - **core/cache:** enhance memoization & caching system to prevent memory leaks and ensure safe lifecycle management ([`253d7d00`](https://github.com/l7aromeo/meonode-ui/commit/253d7d006121dc588a51580d5120c7123a5f8777))
317
+
318
+ - **core/cache:** enhance memoization & caching system to prevent memory leaks and ensure safe lifecycle management ([
319
+ `253d7d00`](https://github.com/l7aromeo/meonode-ui/commit/253d7d006121dc588a51580d5120c7123a5f8777))
192
320
  This introduces a robust, three-layered cleanup strategy to ensure cache integrity:
193
- 1. An immediate, lifecycle-driven cleanup via the new `MeoNodeUnmounter` component.
194
- 2. A debounced, event-driven cleanup for SPA navigations via `NavigationCacheManagerUtil`.
195
- 3. A final, GC-driven safety net using the `FinalizationRegistry` API.
321
+ 1. An immediate, lifecycle-driven cleanup via the new `MeoNodeUnmounter` component.
322
+ 2. A debounced, event-driven cleanup for SPA navigations via `NavigationCacheManagerUtil`.
323
+ 3. A final, GC-driven safety net using the `FinalizationRegistry` API.
196
324
 
197
325
  ### Refactor
326
+
198
327
  - **core:** migrate core logic from `src/helper/` to a new `src/util/` directory for better separation of concerns.
199
328
  - **core:** extract internal utility functions from `core.node.ts` into `node.util.ts`.
200
329
  - **core:** make internal caches on `BaseNode` public to support the new externalized management architecture.
201
330
 
202
331
  ### Chore
332
+
203
333
  - **tooling:** enable TypeScript's `strict: true` mode and update codebase to be fully compliant.
204
334
  - **tooling:** add CommonJS (`require`) exports to `package.json` for improved module compatibility.
205
- - **tooling:** add `NODE_OPTIONS='--expose-gc'` to the test script to allow for explicit garbage collection during tests.
206
- - **tests:** refine test suite by standardizing `afterEach` hooks and updating memoization tests to directly validate internal caching.
335
+ - **tooling:** add `NODE_OPTIONS='--expose-gc'` to the test script to allow for explicit garbage collection during
336
+ tests.
337
+ - **tests:** refine test suite by standardizing `afterEach` hooks and updating memoization tests to directly validate
338
+ internal caching.
207
339
 
208
340
  ## [0.4.5] - 2025-11-15
209
341
 
210
342
  ### Feat
211
- - **cache**: implement robust cache management and theme caching ([`9ed749f6`](https://github.com/l7aromeo/meonode-ui/commit/9ed749f6d877fdc8b6a736788add13225b07dd63))
343
+
344
+ - **cache**: implement robust cache management and theme caching ([
345
+ `9ed749f6`](https://github.com/l7aromeo/meonode-ui/commit/9ed749f6d877fdc8b6a736788add13225b07dd63))
212
346
  Refactor NavigationCacheManager for robustness, add memory monitoring and auto-cleanup.
213
347
  Implement LRU eviction for ThemeResolverCache and integrate with BaseNode cache clearing.
214
348
 
215
349
  ### Refactor
216
- - **test**: split node.test.ts into smaller, more focused test files ([`930f998e`](https://github.com/l7aromeo/meonode-ui/commit/930f998e5f91faef3ff42fcafc6b02fc23f422ff))
350
+
351
+ - **test**: split node.test.ts into smaller, more focused test files ([
352
+ `930f998e`](https://github.com/l7aromeo/meonode-ui/commit/930f998e5f91faef3ff42fcafc6b02fc23f422ff))
217
353
  This commit refactors the test suite by splitting the monolithic `node.test.ts`
218
354
  file into several smaller, more focused test files, each covering a specific
219
355
  aspect of the BaseNode functionality.
@@ -225,152 +361,241 @@ All notable changes to this project will be documented in this file.
225
361
  preserving the test's original intent of verifying cache collision prevention.
226
362
 
227
363
  ### Fix
228
- - **core**: pass disableEmotion flag to _renderProcessedNode for improved processing ([`b68e3d4`](https://github.com/l7aromeo/meonode-ui/commit/b68e3d49a732ee590805a0298f733b800a9b172d))
364
+
365
+ - **core**: pass disableEmotion flag to _renderProcessedNode for improved processing ([
366
+ `b68e3d4`](https://github.com/l7aromeo/meonode-ui/commit/b68e3d49a732ee590805a0298f733b800a9b172d))
229
367
 
230
368
  ### Chore
231
- - **test**: adjust performance test cleanup by removing cache clearing from afterEach ([`f72cea5e`](https://github.com/l7aromeo/meonode-ui/commit/f72cea5ef983fdaba012a7d446b58c7da06f5e1a))
369
+
370
+ - **test**: adjust performance test cleanup by removing cache clearing from afterEach ([
371
+ `f72cea5e`](https://github.com/l7aromeo/meonode-ui/commit/f72cea5ef983fdaba012a7d446b58c7da06f5e1a))
232
372
 
233
373
  ## [0.4.4] - 2025-11-15
234
374
 
235
375
  ### Perf
236
- - **core**: implement intelligent caching and memory management ([`0e5671b`](https://github.com/l7aromeo/meonode-ui/commit/0e5671b36189c964d66676ef633f3ccdbd9004e2))
237
- Introduces a sophisticated caching and memory management system to prevent memory leaks and improve performance in Single Page Applications (SPAs).
238
376
 
239
- This new system intelligently tracks mounted components and automatically cleans up caches of unmounted components during navigation events.
377
+ - **core**: implement intelligent caching and memory management ([
378
+ `0e5671b`](https://github.com/l7aromeo/meonode-ui/commit/0e5671b36189c964d66676ef633f3ccdbd9004e2))
379
+ Introduces a sophisticated caching and memory management system to prevent memory leaks and improve performance in
380
+ Single Page Applications (SPAs).
381
+
382
+ This new system intelligently tracks mounted components and automatically cleans up caches of unmounted components
383
+ during navigation events.
240
384
 
241
385
  Key features and improvements include:
242
386
 
243
- - **Navigation-aware Cache Eviction:** A new `NavigationCacheManager` listens for browser navigation events (popstate, pushState, etc.) and triggers a safe cleanup of the element cache. This prevents the cache from growing indefinitely with stale entries from previous pages.
387
+ - **Navigation-aware Cache Eviction:** A new `NavigationCacheManager` listens for browser navigation events (
388
+ popstate, pushState, etc.) and triggers a safe cleanup of the element cache. This prevents the cache from growing
389
+ indefinitely with stale entries from previous pages.
244
390
 
245
- - **Mount Tracking:** A `MountTracker` class now keeps a record of all mounted `BaseNode` instances. This allows the cache eviction logic to accurately determine which components are safe to remove from the cache.
391
+ - **Mount Tracking:** A `MountTracker` class now keeps a record of all mounted `BaseNode` instances. This allows the
392
+ cache eviction logic to accurately determine which components are safe to remove from the cache.
246
393
 
247
- - **Advanced Eviction Policies:** The `SafeCacheManager` implements several eviction policies, including evicting unmounted components, old unmounted components, and an emergency eviction policy for high memory pressure scenarios.
394
+ - **Advanced Eviction Policies:** The `SafeCacheManager` implements several eviction policies, including evicting
395
+ unmounted components, old unmounted components, and an emergency eviction policy for high memory pressure
396
+ scenarios.
248
397
 
249
- - **Memory-Safe Portal System:** The portal implementation has been refactored to use a `WeakMap`. This ensures that portal-related DOM elements and React roots are automatically garbage collected when the corresponding `BaseNode` instance is no longer in use, preventing a common source of memory leaks.
398
+ - **Memory-Safe Portal System:** The portal implementation has been refactored to use a `WeakMap`. This ensures that
399
+ portal-related DOM elements and React roots are automatically garbage collected when the corresponding `BaseNode`
400
+ instance is no longer in use, preventing a common source of memory leaks.
250
401
 
251
- - **Improved Cache Entry Metadata:** The element cache entries now store additional metadata, such as creation timestamp, access count, and a `WeakRef` to the node instance, enabling more intelligent eviction decisions.
402
+ - **Improved Cache Entry Metadata:** The element cache entries now store additional metadata, such as creation
403
+ timestamp, access count, and a `WeakRef` to the node instance, enabling more intelligent eviction decisions.
252
404
 
253
- - **Enhanced Stability:** Component identifiers for caching are now generated using a `WeakMap`, providing more stable and reliable keys than relying on component names, which can be affected by minification.
405
+ - **Enhanced Stability:** Component identifiers for caching are now generated using a `WeakMap`, providing more
406
+ stable and reliable keys than relying on component names, which can be affected by minification.
254
407
 
255
- - **Comprehensive Test Coverage:** Added a suite of new integration tests to validate the caching and memory management system. These tests cover key scenarios including cache collision, rapid navigation, React 18 Strict Mode compatibility, large prop object fingerprinting, and LRU eviction logic.
408
+ - **Comprehensive Test Coverage:** Added a suite of new integration tests to validate the caching and memory
409
+ management system. These tests cover key scenarios including cache collision, rapid navigation, React 18 Strict
410
+ Mode compatibility, large prop object fingerprinting, and LRU eviction logic.
256
411
 
257
412
  ### Fix
258
- - **core**: simplify property assignment in common helper ([`312af57`](https://github.com/l7aromeo/meonode-ui/commit/312af574712202a25bdd62fab94441a937f159f2))
413
+
414
+ - **core**: simplify property assignment in common helper ([
415
+ `312af57`](https://github.com/l7aromeo/meonode-ui/commit/312af574712202a25bdd62fab94441a937f159f2))
259
416
 
260
417
  ### Refactor
261
- - **core**: add ElementCacheEntry interface for memoization and update css prop type ([`6a8381c`](https://github.com/l7aromeo/meonode-ui/commit/6a8381c4c85cb22df4ba398637401d420461e413))
418
+
419
+ - **core**: add ElementCacheEntry interface for memoization and update css prop type ([
420
+ `6a8381c`](https://github.com/l7aromeo/meonode-ui/commit/6a8381c4c85cb22df4ba398637401d420461e413))
262
421
 
263
422
  ## [0.4.3] - 2025-11-14
264
423
 
265
424
  ### Docs
266
- - **core**: add detailed comments to rendering methods ([`731c83e`](https://github.com/l7aromeo/meonode-ui/commit/731c83e))
425
+
426
+ - **core**: add detailed comments to rendering methods ([
427
+ `731c83e`](https://github.com/l7aromeo/meonode-ui/commit/731c83e))
267
428
 
268
429
  ### Fix
269
- - **core**: adjust isStyledComponent logic to improve style handling ([`ff7a59e`](https://github.com/l7aromeo/meonode-ui/commit/ff7a59e))
430
+
431
+ - **core**: adjust isStyledComponent logic to improve style handling ([
432
+ `ff7a59e`](https://github.com/l7aromeo/meonode-ui/commit/ff7a59e))
270
433
 
271
434
  ### Refactor
272
- - **core**: simplify _processProps by removing style prop handling ([`b3570b4`](https://github.com/l7aromeo/meonode-ui/commit/b3570b4))
435
+
436
+ - **core**: simplify _processProps by removing style prop handling ([
437
+ `b3570b4`](https://github.com/l7aromeo/meonode-ui/commit/b3570b4))
273
438
 
274
439
  ## [0.4.2] - 2025-11-14
275
440
 
276
441
  ### Fix
277
- - **core**: remove deps property from props since it should not be passed to element attribute ([`6b01cbe`](https://github.com/l7aromeo/meonode-ui/commit/6b01cbe))
442
+
443
+ - **core**: remove deps property from props since it should not be passed to element attribute ([
444
+ `6b01cbe`](https://github.com/l7aromeo/meonode-ui/commit/6b01cbe))
278
445
 
279
446
  ## [0.4.1] - 2025-11-14
280
447
 
281
448
  ### Test
282
- - **node**: enhance dependency and memoization tests with real-world scenarios ([`d7452fa`](https://github.com/l7aromeo/meonode-ui/commit/d7452fae9b3ef22a82dc83210851849d82de479f))
449
+
450
+ - **node**: enhance dependency and memoization tests with real-world scenarios ([
451
+ `d7452fa`](https://github.com/l7aromeo/meonode-ui/commit/d7452fae9b3ef22a82dc83210851849d82de479f))
283
452
 
284
453
  ### Fix
285
- - **core**: enhance error handling and improve style property detection ([`ca79c27`](https://github.com/l7aromeo/meonode-ui/commit/ca79c277cdfea5b62b54779ec2492518681639d1))
454
+
455
+ - **core**: enhance error handling and improve style property detection ([
456
+ `ca79c27`](https://github.com/l7aromeo/meonode-ui/commit/ca79c277cdfea5b62b54779ec2492518681639d1))
286
457
 
287
458
  ### Chore
288
- - **deps**: update dependencies in package.json for improved stability and performance ([`eba2108`](https://github.com/l7aromeo/meonode-ui/commit/eba21080c953b1c6b6c1bbb6a401257845116f09))
459
+
460
+ - **deps**: update dependencies in package.json for improved stability and performance ([
461
+ `eba2108`](https://github.com/l7aromeo/meonode-ui/commit/eba21080c953b1c6b6c1bbb6a401257845116f09))
289
462
 
290
463
  ### Perf
291
- - **core**: Optimize prop processing and caching with new signature generation ([`8cf0319`](https://github.com/l7aromeo/meonode-ui/commit/8cf0319fd99c3c8496b6e63207cb378b6c521ae2))
464
+
465
+ - **core**: Optimize prop processing and caching with new signature generation ([
466
+ `8cf0319`](https://github.com/l7aromeo/meonode-ui/commit/8cf0319fd99c3c8496b6e63207cb378b6c521ae2))
292
467
 
293
468
  ### Refactor
294
- - **types**: move node.type.ts to types directory and update imports ([`ccf769a`](https://github.com/l7aromeo/meonode-ui/commit/ccf769a2670e4546bfa776034a4fa8925ca2d27d))
469
+
470
+ - **types**: move node.type.ts to types directory and update imports ([
471
+ `ccf769a`](https://github.com/l7aromeo/meonode-ui/commit/ccf769a2670e4546bfa776034a4fa8925ca2d27d))
295
472
 
296
473
  ## [0.4.0] - 2025-11-13
297
474
 
298
475
  ### Feature
476
+
299
477
  - **core**: Implemented an advanced memoization and caching system to optimize rendering performance. This includes:
300
- - **Dependency-Based Memoization**: Nodes can now be created with a dependency array, similar to React's `useMemo`, to prevent unnecessary re-renders of the node and its entire subtree if dependencies have not changed. ([`3b0a110`](https://github.com/l7aromeo/meonode-ui/commit/3b0a110eb3db25862476d020182be9f0dba663e4))
301
- - **Enhanced Prop Caching**: The prop signature generation is now more robust, and the cache uses an advanced LRU eviction strategy to remain efficient. ([`3b0a110`](https://github.com/l7aromeo/meonode-ui/commit/3b0a110eb3db25862476d020182be9f0dba663e4))
302
- - **API Updates**: The `Node`, `createNode`, `createChildrenFirstNode`, and `Component` HOCs have been updated to accept an optional `deps` array to enable memoization. ([`3b0a110`](https://github.com/l7aromeo/meonode-ui/commit/3b0a110eb3db25862476d020182be9f0dba663e4))
478
+ - **Dependency-Based Memoization**: Nodes can now be created with a dependency array, similar to React's `useMemo`,
479
+ to prevent unnecessary re-renders of the node and its entire subtree if dependencies have not changed. ([
480
+ `3b0a110`](https://github.com/l7aromeo/meonode-ui/commit/3b0a110eb3db25862476d020182be9f0dba663e4))
481
+ - **Enhanced Prop Caching**: The prop signature generation is now more robust, and the cache uses an advanced LRU
482
+ eviction strategy to remain efficient. ([
483
+ `3b0a110`](https://github.com/l7aromeo/meonode-ui/commit/3b0a110eb3db25862476d020182be9f0dba663e4))
484
+ - **API Updates**: The `Node`, `createNode`, `createChildrenFirstNode`, and `Component` HOCs have been updated to
485
+ accept an optional `deps` array to enable memoization. ([
486
+ `3b0a110`](https://github.com/l7aromeo/meonode-ui/commit/3b0a110eb3db25862476d020182be9f0dba663e4))
303
487
 
304
488
  ### Test
305
- - **core**: Added a comprehensive suite of tests for the new memoization and caching system, covering dependency-based memoization, reactive and non-reactive children, complex state updates, and memoization of Higher-Order Components (HOCs). ([`6bcd1b1`](https://github.com/l7aromeo/meonode-ui/commit/6bcd1b1bc6b2450c3d4296cb4af326f61cfee401))
489
+
490
+ - **core**: Added a comprehensive suite of tests for the new memoization and caching system, covering dependency-based
491
+ memoization, reactive and non-reactive children, complex state updates, and memoization of Higher-Order Components (
492
+ HOCs). ([`6bcd1b1`](https://github.com/l7aromeo/meonode-ui/commit/6bcd1b1bc6b2450c3d4296cb4af326f61cfee401))
306
493
 
307
494
  ## [0.3.18] - 2025-11-12
308
495
 
309
496
  ### Fixed
310
- - **core**: refine prop caching to handle dynamic props correctly ([`4c0641e`](https://github.com/l7aromeo/meonode-ui/commit/4c0641e892f934551f100629cac72fc3f4649ab0))
497
+
498
+ - **core**: refine prop caching to handle dynamic props correctly ([
499
+ `4c0641e`](https://github.com/l7aromeo/meonode-ui/commit/4c0641e892f934551f100629cac72fc3f4649ab0))
311
500
 
312
501
  ## [0.3.17] - 2025-11-12
313
502
 
314
503
  ### Perf
315
- - **core**: implement iterative renderer and prop caching ([`8a3a264`](https://github.com/l7aromeo/meonode-ui/commit/8a3a264be68bd041b6340636f5f7ee2b0caa63ff))
316
- - **helper**: refactor theme resolution logic for improved performance and cache correctness ([`9614cb8`](https://github.com/l7aromeo/meonode-ui/commit/9614cb8d2aeae0d9bd2f9cf3edd51c022cd93273))
504
+
505
+ - **core**: implement iterative renderer and prop caching ([
506
+ `8a3a264`](https://github.com/l7aromeo/meonode-ui/commit/8a3a264be68bd041b6340636f5f7ee2b0caa63ff))
507
+ - **helper**: refactor theme resolution logic for improved performance and cache correctness ([
508
+ `9614cb8`](https://github.com/l7aromeo/meonode-ui/commit/9614cb8d2aeae0d9bd2f9cf3edd51c022cd93273))
317
509
 
318
510
  ### Chore
319
- - fix typo in JSDoc comment for useTheme hook ([`de0ddd9`](https://github.com/l7aromeo/meonode-ui/commit/de0ddd9a6308f4a76b6ad843a6139d42bd3fcf53))
320
- - add deprecation notice to usePortal hook for future removal ([`f8a2923`](https://github.com/l7aromeo/meonode-ui/commit/f8a29230cad3962addb8cf28ed3538e6de236181))
321
- - update PortalProps type definition to provide a default type parameter ([`de73ba5`](https://github.com/l7aromeo/meonode-ui/commit/de73ba5b9d9dd51637b24b0309d681309d9338ae))
322
- - update isNodeInstance type guard to use BaseNode instead of NodeInstance ([`2c69d05`](https://github.com/l7aromeo/meonode-ui/commit/2c69d05b3d1593a976e439ca7404696b781e5012))
323
- - rename jest.config.mjs to jest.config.ts and update configuration for TypeScript support ([`a3213eb`](https://github.com/l7aromeo/meonode-ui/commit/a3213eb5b91a55364cb4f5362005bc2a46934de5))
324
- - **scripts**: increase stack size for jest test and fix build commands ([`e046cdf`](https://github.com/l7aromeo/meonode-ui/commit/e046cdf397e2cf418e09e149a9e0cf1e48f3d926))
325
- - update tsconfig.json to exclude dist and node_modules directories ([`eeb9577`](https://github.com/l7aromeo/meonode-ui/commit/eeb957722ab7a26cbe59047c068f9955b082502e))
326
- - update tsconfig.json with enhanced compiler options and path mappings for better development experience ([`89bc1a4`](https://github.com/l7aromeo/meonode-ui/commit/89bc1a42c23f015acfed1bcb860ebb6a4c684fc1))
511
+
512
+ - fix typo in JSDoc comment for useTheme hook ([
513
+ `de0ddd9`](https://github.com/l7aromeo/meonode-ui/commit/de0ddd9a6308f4a76b6ad843a6139d42bd3fcf53))
514
+ - add deprecation notice to usePortal hook for future removal ([
515
+ `f8a2923`](https://github.com/l7aromeo/meonode-ui/commit/f8a29230cad3962addb8cf28ed3538e6de236181))
516
+ - update PortalProps type definition to provide a default type parameter ([
517
+ `de73ba5`](https://github.com/l7aromeo/meonode-ui/commit/de73ba5b9d9dd51637b24b0309d681309d9338ae))
518
+ - update isNodeInstance type guard to use BaseNode instead of NodeInstance ([
519
+ `2c69d05`](https://github.com/l7aromeo/meonode-ui/commit/2c69d05b3d1593a976e439ca7404696b781e5012))
520
+ - rename jest.config.mjs to jest.config.ts and update configuration for TypeScript support ([
521
+ `a3213eb`](https://github.com/l7aromeo/meonode-ui/commit/a3213eb5b91a55364cb4f5362005bc2a46934de5))
522
+ - **scripts**: increase stack size for jest test and fix build commands ([
523
+ `e046cdf`](https://github.com/l7aromeo/meonode-ui/commit/e046cdf397e2cf418e09e149a9e0cf1e48f3d926))
524
+ - update tsconfig.json to exclude dist and node_modules directories ([
525
+ `eeb9577`](https://github.com/l7aromeo/meonode-ui/commit/eeb957722ab7a26cbe59047c068f9955b082502e))
526
+ - update tsconfig.json with enhanced compiler options and path mappings for better development experience ([
527
+ `89bc1a4`](https://github.com/l7aromeo/meonode-ui/commit/89bc1a42c23f015acfed1bcb860ebb6a4c684fc1))
327
528
 
328
529
  ## [0.3.16] - 2025-11-05
329
530
 
330
531
  ### Added
331
- - **tests**: add tests for Fragment, Suspense, and Activity components to verify styling prop handling ([`2af386f`](https://github.com/l7aromeo/meonode-ui/commit/2af386f))
332
- - **core**: enhance NodeProps type to conditionally include built-in React components ([`3b8a4cb`](https://github.com/l7aromeo/meonode-ui/commit/3b8a4cb))
333
- - **react**: add REACT_ACTIVITY_TYPE to react-is helper ([`e91e48f`](https://github.com/l7aromeo/meonode-ui/commit/e91e48f))
334
- - **core**: export NO_STYLE_TAGS type for better type inference ([`a6db6e8`](https://github.com/l7aromeo/meonode-ui/commit/a6db6e8))
335
- - **react**: add Fragment component to create a container without extra DOM elements ([`d5e376a`](https://github.com/l7aromeo/meonode-ui/commit/d5e376a))
532
+
533
+ - **tests**: add tests for Fragment, Suspense, and Activity components to verify styling prop handling ([
534
+ `2af386f`](https://github.com/l7aromeo/meonode-ui/commit/2af386f))
535
+ - **core**: enhance NodeProps type to conditionally include built-in React components ([
536
+ `3b8a4cb`](https://github.com/l7aromeo/meonode-ui/commit/3b8a4cb))
537
+ - **react**: add REACT_ACTIVITY_TYPE to react-is helper ([
538
+ `e91e48f`](https://github.com/l7aromeo/meonode-ui/commit/e91e48f))
539
+ - **core**: export NO_STYLE_TAGS type for better type inference ([
540
+ `a6db6e8`](https://github.com/l7aromeo/meonode-ui/commit/a6db6e8))
541
+ - **react**: add Fragment component to create a container without extra DOM elements ([
542
+ `d5e376a`](https://github.com/l7aromeo/meonode-ui/commit/d5e376a))
336
543
 
337
544
  ## [0.3.15] - 2025-11-04
338
545
 
339
546
  ### Added
340
- - **core**: add disableEmotion prop to disable emotion styling and propagate to children ([`377a9e9`](https://github.com/l7aromeo/meonode-ui/commit/377a9e9d4844ba7869155e686c9b31f0f9ce2329))
341
- - **react**: enhance isContextProvider and isReactClassComponent checks ([`e8839e4`](https://github.com/l7aromeo/meonode-ui/commit/e8839e4c231bdd66686f7b43d9889a18cd9fc791))
547
+
548
+ - **core**: add disableEmotion prop to disable emotion styling and propagate to children ([
549
+ `377a9e9`](https://github.com/l7aromeo/meonode-ui/commit/377a9e9d4844ba7869155e686c9b31f0f9ce2329))
550
+ - **react**: enhance isContextProvider and isReactClassComponent checks ([
551
+ `e8839e4`](https://github.com/l7aromeo/meonode-ui/commit/e8839e4c231bdd66686f7b43d9889a18cd9fc791))
342
552
 
343
553
  ## [0.3.14] - 2025-10-30
344
554
 
345
555
  ### Added
346
- - **core**: Add handling for Suspense and Activity components ([`0f9fcb1`](https://github.com/l7aromeo/meonode-ui/commit/0f9fcb171fdce28b5a880e69e2d591543e3af817))
556
+
557
+ - **core**: Add handling for Suspense and Activity components ([
558
+ `0f9fcb1`](https://github.com/l7aromeo/meonode-ui/commit/0f9fcb171fdce28b5a880e69e2d591543e3af817))
347
559
 
348
560
  ## [0.3.13] - 2025-10-30
349
561
 
350
562
  ### Fixed
351
- - **theme.helper**: process theme strings returned from functions ([`286fd89`](https://github.com/l7aromeo/meonode-ui/commit/286fd89e28cc10b467a208be4cdf1b7508d0be8c))
563
+
564
+ - **theme.helper**: process theme strings returned from functions ([
565
+ `286fd89`](https://github.com/l7aromeo/meonode-ui/commit/286fd89e28cc10b467a208be4cdf1b7508d0be8c))
352
566
 
353
567
  ## [0.3.12] - 2025-10-23
354
568
 
355
569
  ### Added
356
- - **react**: add Suspense component and JSDoc for Activity and Suspense ([`c1760fd`](https://github.com/l7aromeo/meonode-ui/commit/c1760fd))
357
570
 
571
+ - **react**: add Suspense component and JSDoc for Activity and Suspense ([
572
+ `c1760fd`](https://github.com/l7aromeo/meonode-ui/commit/c1760fd))
358
573
 
359
574
  ## [0.3.11] - 2025-10-19
360
575
 
361
576
  ### Added
362
- - **components**: add react activity node and export it in main ([`aadbc2d`](https://github.com/l7aromeo/meonode-ui/commit/aadbc2d08a928f1ba88bd4572b45eed8cb100a87))
363
- - **theme.helper**: update resolveObjWithTheme to improve object type checking ([`da1ce4c`](https://github.com/l7aromeo/meonode-ui/commit/da1ce4cd53ccbe2d2a562a49730151434177dc59))
577
+
578
+ - **components**: add react activity node and export it in main ([
579
+ `aadbc2d`](https://github.com/l7aromeo/meonode-ui/commit/aadbc2d08a928f1ba88bd4572b45eed8cb100a87))
580
+ - **theme.helper**: update resolveObjWithTheme to improve object type checking ([
581
+ `da1ce4c`](https://github.com/l7aromeo/meonode-ui/commit/da1ce4cd53ccbe2d2a562a49730151434177dc59))
364
582
 
365
583
  ### Changed
366
- - **chore**: update dependencies in package.json and yarn.lock ([`0c0ced6`](https://github.com/l7aromeo/meonode-ui/commit/0c0ced68662bb701634d49dc79da86e4ddce5392))
367
- - **chore**: remove \'use strict\' directive from multiple files ([`17d79dc`](https://github.com/l7aromeo/meonode-ui/commit/17d79dcb105a8c2062695071c3f587f6db9a5711))
584
+
585
+ - **chore**: update dependencies in package.json and yarn.lock ([
586
+ `0c0ced6`](https://github.com/l7aromeo/meonode-ui/commit/0c0ced68662bb701634d49dc79da86e4ddce5392))
587
+ - **chore**: remove \'use strict\' directive from multiple files ([
588
+ `17d79dc`](https://github.com/l7aromeo/meonode-ui/commit/17d79dcb105a8c2062695071c3f587f6db9a5711))
368
589
 
369
590
  ### Docs
370
- - **docs**: update Node.js version requirement in CONTRIBUTING.md ([`4c577c3`](https://github.com/l7aromeo/meonode-ui/commit/4c577c3e23294bdc188cda5b14375af1cb967888))
591
+
592
+ - **docs**: update Node.js version requirement in CONTRIBUTING.md ([
593
+ `4c577c3`](https://github.com/l7aromeo/meonode-ui/commit/4c577c3e23294bdc188cda5b14375af1cb967888))
371
594
 
372
595
  ### Test
373
- - **node**: add test case for preserving Node instances passed through props and theme resolution ([`f4d1344`](https://github.com/l7aromeo/meonode-ui/commit/f4d1344355f2a4631ccdf04998bcf618d4ce1dc6))
596
+
597
+ - **node**: add test case for preserving Node instances passed through props and theme resolution ([
598
+ `f4d1344`](https://github.com/l7aromeo/meonode-ui/commit/f4d1344355f2a4631ccdf04998bcf618d4ce1dc6))
374
599
 
375
600
  ## [0.3.10] - 2025-10-09
376
601
 
@@ -392,11 +617,14 @@ All notable changes to this project will be documented in this file.
392
617
 
393
618
  ### Added
394
619
 
395
- - **styling**: Enabled theme-aware functions for css props, allowing for more dynamic styling (e.g., `color: theme => theme.system.colors.primary`).
620
+ - **styling**: Enabled theme-aware functions for css props, allowing for more dynamic styling (e.g.,
621
+ `color: theme => theme.system.colors.primary`).
396
622
 
397
623
  ### Refactor
398
624
 
399
- - **core**: Refactored the style resolution logic (`resolveObjWithTheme` and `StyledRenderer`) to selectively process the `css` prop. This enables the new theme-function feature while ensuring that other props (like `children`) are not processed, maintaining compatibility with Next.js Server Components.
625
+ - **core**: Refactored the style resolution logic (`resolveObjWithTheme` and `StyledRenderer`) to selectively process
626
+ the `css` prop. This enables the new theme-function feature while ensuring that other props (like `children`) are not
627
+ processed, maintaining compatibility with Next.js Server Components.
400
628
 
401
629
  ## [0.3.7] - 2025-09-27
402
630
 
@@ -512,7 +740,8 @@ All notable changes to this project will be documented in this file.
512
740
 
513
741
  ### Added
514
742
 
515
- - **feat:** update NodeFunction type to improve dynamic node content generation and update FunctionRendererProps interface to use NodeFunction
743
+ - **feat:** update NodeFunction type to improve dynamic node content generation and update FunctionRendererProps
744
+ interface to use NodeFunction
516
745
 
517
746
  ### Fixed
518
747
 
@@ -520,6 +749,7 @@ All notable changes to this project will be documented in this file.
520
749
  - **fix(node.type.ts):** remove unused processRawNode property from Node type
521
750
 
522
751
  ### Changed
752
+
523
753
  - **package:** update dependencies to latest versions
524
754
 
525
755
  ## [0.2.20] - 2025-09-22
@@ -607,7 +837,8 @@ All notable changes to this project will be documented in this file.
607
837
 
608
838
  ### Added
609
839
 
610
- - **feat(common.helper)**: add omit and omitUndefined utility functions to create object copies without specified keys or undefined values
840
+ - **feat(common.helper)**: add omit and omitUndefined utility functions to create object copies without specified keys
841
+ or undefined values
611
842
  - **feat**: integrate omit and omitUndefined functions to manage finalProps for standard HTML tags and custom components
612
843
 
613
844
  ### Refactor
@@ -623,14 +854,16 @@ All notable changes to this project will be documented in this file.
623
854
 
624
855
  ### Removed
625
856
 
626
- - **types**: removed redundant `key` prop from `FinalNodeProps` and default `key` from `NodeProps` types for cleaner type definitions
857
+ - **types**: removed redundant `key` prop from `FinalNodeProps` and default `key` from `NodeProps` types for cleaner
858
+ type definitions
627
859
 
628
860
  ## [0.2.16] - 2025-09-13
629
861
 
630
862
  ### Added
631
863
 
632
864
  - **feat(core)**: introduce static _isServer property to optimize server-side checks in caching methods
633
- - **feat(core)**: remove passedKey from _functionRenderer and simplify function-as-child wrapper; augment toPortal unmount to clean portal container
865
+ - **feat(core)**: remove passedKey from _functionRenderer and simplify function-as-child wrapper; augment toPortal
866
+ unmount to clean portal container
634
867
 
635
868
  ### Refactor
636
869
 
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),t=require("../util/mount-tracker.util.js"),r=require("../core.node.js");exports.default=function({node:n,children:s,...u}){const a=e.useEffectEvent(()=>{n.stableKey&&(r.BaseNode.elementCache.delete(n.stableKey),t.MountTrackerUtil.mountedNodes.has(n.stableKey)&&t.MountTrackerUtil.untrackMount(n.stableKey),r.BaseNode.cacheCleanupRegistry.unregister(n)),n.lastSignature=void 0});return e.useEffect(()=>()=>a(),[]),e.isValidElement(s)?e.cloneElement(s,u):s};
2
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),t=require("../util/mount-tracker.util.js"),r=require("../core.node.js");exports.default=function({children:n,...s}){const{node:u,...a}=s,l=e.useEffectEvent(()=>{u.stableKey&&(r.BaseNode.elementCache.delete(u.stableKey),t.MountTrackerUtil.mountedNodes.has(u.stableKey)&&t.MountTrackerUtil.untrackMount(u.stableKey),r.BaseNode.cacheCleanupRegistry.unregister(u)),u.lastSignature=void 0});return e.useEffect(()=>()=>l(),[]),e.isValidElement(n)&&Object.keys(a).length>0?e.cloneElement(n,a):n};
@@ -1 +1 @@
1
- "use strict";var e=require("react"),t=require("./helper/react-is.helper.js"),r=require("./helper/common.helper.js"),n=require("./components/styled-renderer.client.js"),o=require("./constant/common.const.js"),s=require("./util/mount-tracker.util.js"),a=require("./components/meonode-unmounter.client.js"),l=require("./util/navigation-cache-manager.util.js"),i=require("./util/node.util.js"),c=require("./util/theme.util.js");class d{instanceId=Math.random().toString(36).slice(2)+Date.now().toString(36);element;rawProps={};isBaseNode=!0;_props;_deps;stableKey;lastPropsObj;lastSignature;static elementCache=new Map;static propProcessingCache=new Map;static scheduledCleanup=!1;static _navigationStarted=!1;static renderContextPool=[];static acquireRenderContext(){const e=d.renderContextPool;return e.length>0?e.pop():{workStack:new Array(512),renderedElements:new Map}}static releaseRenderContext(e){d.renderContextPool.length<50&&e.workStack.length<2048&&(e.workStack.length=0,e.renderedElements.clear(),d.renderContextPool.push(e))}constructor(e,n={},o){if(!t.isValidElementType(e)){const t=r.getComponentType(e);throw new Error(`Invalid element type: ${t} provided!`)}this.element=e,this.rawProps=n,this._deps=o;const{ref:s,children:a,...c}=n;this.stableKey=this._getStableKey(c),i.NodeUtil.isServer||d._navigationStarted||(l.NavigationCacheManagerUtil.getInstance().start(),d._navigationStarted=!0)}get props(){return this._props||(this._props=i.NodeUtil.processProps(this.element,this.rawProps,this.stableKey)),this._props}get dependencies(){return this._deps}_getStableKey({key:e,...t}){if(i.NodeUtil.isServer)return;if(this.lastPropsObj===t)return this.lastSignature;this.lastPropsObj=t;const n=Object.keys(t),s=n.length;if(s>100){const e=i.NodeUtil.extractCriticalProps(t,n);this.lastSignature=i.NodeUtil.createPropSignature(this.element,e),o.__DEBUG__&&s>200&&console.warn(`MeoNode: Large props (${s} keys) on "${r.getElementTypeName(this.element)}". Consider splitting.`)}else this.lastSignature=i.NodeUtil.createPropSignature(this.element,t);return null!=e?`${String(e)}:${this.lastSignature}`:this.lastSignature}static cacheCleanupRegistry=new FinalizationRegistry(e=>{const{cacheKey:t,instanceId:r}=e,n=d.elementCache.get(t);n?.instanceId===r&&d.elementCache.delete(t),s.MountTrackerUtil.mountedNodes.has(t)&&s.MountTrackerUtil.untrackMount(t)});static portalCleanupRegistry=new FinalizationRegistry(e=>{const{domElement:t,reactRoot:r}=e;o.__DEBUG__&&console.log("[MeoNode] FinalizationRegistry auto-cleaning portal");try{r&&"function"==typeof r.unmount&&r.unmount()}catch(e){o.__DEBUG__&&console.error("[MeoNode] Portal auto-cleanup unmount error:",e)}try{t?.isConnected&&t.remove()}catch(e){o.__DEBUG__&&console.error("[MeoNode] Portal auto-cleanup DOM removal error:",e)}});render(o=!1){!i.NodeUtil.isServer&&this.stableKey&&s.MountTrackerUtil.trackMount(this.stableKey);const l=i.NodeUtil.isServer||!this.stableKey?void 0:d.elementCache.get(this.stableKey),c=i.NodeUtil.shouldNodeUpdate(l?.prevDeps,this._deps,o);if(!c&&l?.renderedElement)return l.accessCount+=1,l.renderedElement;const u=!c,h=d.acquireRenderContext();let{workStack:p}=h;const{renderedElements:m}=h;let g=0;try{const o=e=>{if(e>p.length){const t=Math.max(e,p.length<<1),r=new Array(t);for(let e=0;e<g;e++)r[e]=p[e];p=r}};for(p[g++]={node:this,isProcessed:!1,blocked:u};g>0;){const s=p[g-1];if(!s){g--;continue}const{node:a,isProcessed:l,blocked:c}=s;if(l){g--;const{children:o,key:s,css:l,nativeProps:c,disableEmotion:u,...h}=a.props;let p=[];if(o){const t=Array.isArray(o)?o:[o],r=t.length;p=new Array(r);for(let n=0;n<r;n++){const r=t[n];if(i.NodeUtil.isNodeInstance(r)){const e=m.get(r);if(!e)throw new Error(`[MeoNode] Missing rendered element for child node: ${r.stableKey}`);p[n]=e}else e.isValidElement(r),p[n]=r}}const _={...h,key:s,...c};let y;if(a.element===e.Fragment||t.isFragment(a.element))y=e.createElement(a.element,{key:s},...p);else{y=!u&&(l||!r.hasNoStyleTag(a.element))?e.createElement(n.default,{element:a.element,..._,css:l,suppressHydrationWarning:!0},...p):e.createElement(a.element,_,...p)}if(!i.NodeUtil.isServer&&a.stableKey){const e=d.elementCache.get(a.stableKey);if(e)e.prevDeps=a._deps,e.renderedElement=y,e.accessCount+=1;else{const e={prevDeps:a._deps,renderedElement:y,nodeRef:new WeakRef(a),createdAt:Date.now(),accessCount:1,instanceId:a.instanceId};d.elementCache.set(a.stableKey,e),d.cacheCleanupRegistry.register(a,{cacheKey:a.stableKey,instanceId:a.instanceId},a)}}m.set(a,y)}else{s.isProcessed=!0;const e=a.props.children;if(e){const t=(Array.isArray(e)?e:[e]).filter(i.NodeUtil.isNodeInstance);o(g+t.length);for(let e=t.length-1;e>=0;e--){const r=t[e],n=i.NodeUtil.isServer||!r.stableKey?void 0:d.elementCache.get(r.stableKey),o=i.NodeUtil.shouldNodeUpdate(n?.prevDeps,r._deps,c);if(!o&&n?.renderedElement){m.set(r,n.renderedElement);continue}const s=c||!o;p[g++]={node:r,isProcessed:!1,blocked:s}}}}}const s=m.get(this);return!i.NodeUtil.isServer&&this.stableKey?e.createElement(a.default,{node:this},s):s}finally{for(let e=0;e<g;e++)p[e]=null;d.releaseRenderContext({workStack:p,renderedElements:m})}}toPortal(){if(!i.NodeUtil.ensurePortalInfrastructure(this))throw new Error("toPortal() can only be called in a client-side environment");const e=i.NodeUtil.portalInfrastructure.get(this),{domElement:t,reactRoot:r}=e;(()=>{try{r.render(this.render())}catch(e){o.__DEBUG__&&console.error("[MeoNode] Portal render error:",e)}})();let n=!1;const s=r.unmount.bind(r);return r.update=e=>{if(n)o.__DEBUG__&&console.warn("[MeoNode] Attempt to update already-unmounted portal");else try{const t=i.NodeUtil.isNodeInstance(e)?e.render():e;r.render(t)}catch(e){o.__DEBUG__&&console.error("[MeoNode] Portal update error:",e)}},r.unmount=()=>{if(n)o.__DEBUG__&&console.warn("[MeoNode] Portal already unmounted");else{n=!0;try{d.portalCleanupRegistry.unregister(this)}catch(e){o.__DEBUG__&&console.warn("[MeoNode] Portal unregister warning:",e)}i.NodeUtil.portalInfrastructure.delete(this);try{t?.isConnected&&s()}catch(e){o.__DEBUG__&&console.error("[MeoNode] Portal unmount error:",e)}try{t?.isConnected&&t.remove()}catch(e){o.__DEBUG__&&console.error("[MeoNode] Portal DOM cleanup error:",e)}}},r}static clearCaches(){const e=Array.from(d.elementCache.keys());o.__DEBUG__&&console.log(`[MeoNode] clearCaches: Clearing ${e.length} entries`);for(const t of e){const e=d.elementCache.get(t);if(e){const r=e.nodeRef?.deref();if(r)try{d.cacheCleanupRegistry.unregister(r),r.lastSignature=void 0,r.lastPropsObj=void 0}catch{o.__DEBUG__&&console.warn(`[MeoNode] Could not unregister ${t} from FinalizationRegistry`)}}}d.propProcessingCache.clear(),d.elementCache.clear(),c.ThemeUtil.clearThemeCache(),s.MountTrackerUtil.cleanup(),o.__DEBUG__&&console.log("[MeoNode] All caches cleared")}}function u(e,t={},r){return new d(e,t,r)}u.clearCaches=d.clearCaches,exports.BaseNode=d,exports.Node=u,exports.createChildrenFirstNode=function(e,t){const r=(r,n,o)=>u(e,{...t,...n,children:r},o);return r.element=e,r},exports.createNode=function(e,t){const r=(r,n)=>u(e,{...t,...r},n);return r.element=e,r};
1
+ "use strict";var e=require("react"),t=require("./helper/react-is.helper.js"),r=require("./helper/common.helper.js"),n=require("./components/styled-renderer.client.js"),o=require("./constant/common.const.js"),s=require("./util/mount-tracker.util.js"),a=require("./components/meonode-unmounter.client.js"),l=require("./util/navigation-cache-manager.util.js"),i=require("./util/node.util.js"),c=require("./util/theme.util.js");class d{instanceId=Math.random().toString(36).slice(2)+Date.now().toString(36);element;rawProps={};isBaseNode=!0;_props;_deps;stableKey;lastPropsObj;lastSignature;static elementCache=new Map;static propProcessingCache=new Map;static scheduledCleanup=!1;static _navigationStarted=!1;static renderContextPool=[];static acquireRenderContext(){const e=d.renderContextPool;return e.length>0?e.pop():{workStack:new Array(512),renderedElements:new Map}}static releaseRenderContext(e){d.renderContextPool.length<50&&e.workStack.length<2048&&(e.workStack.length=0,e.renderedElements.clear(),d.renderContextPool.push(e))}constructor(e,n={},o){if(!t.isValidElementType(e)){const t=r.getComponentType(e);throw new Error(`Invalid element type: ${t} provided!`)}this.element=e,this.rawProps=n,this._deps=o;const{ref:s,children:a,...c}=n;this.stableKey=this._getStableKey(c),i.NodeUtil.isServer||d._navigationStarted||(l.NavigationCacheManagerUtil.getInstance().start(),d._navigationStarted=!0)}get props(){return this._props||(this._props=i.NodeUtil.processProps(this.element,this.rawProps,this.stableKey)),this._props}get dependencies(){return this._deps}_getStableKey({key:e,...t}){if(i.NodeUtil.isServer)return;if(this.lastPropsObj===t)return this.lastSignature;this.lastPropsObj=t;const n=Object.keys(t),s=n.length;if(s>100){const e=i.NodeUtil.extractCriticalProps(t,n);this.lastSignature=i.NodeUtil.createPropSignature(this.element,e),o.__DEBUG__&&s>200&&console.warn(`MeoNode: Large props (${s} keys) on "${r.getElementTypeName(this.element)}". Consider splitting.`)}else this.lastSignature=i.NodeUtil.createPropSignature(this.element,t);return null!=e?`${String(e)}:${this.lastSignature}`:this.lastSignature}static cacheCleanupRegistry=new FinalizationRegistry(e=>{const{cacheKey:t,instanceId:r}=e,n=d.elementCache.get(t);n?.instanceId===r&&d.elementCache.delete(t),s.MountTrackerUtil.mountedNodes.has(t)&&s.MountTrackerUtil.untrackMount(t)});static portalCleanupRegistry=new FinalizationRegistry(e=>{const{domElement:t,reactRoot:r}=e;o.__DEBUG__&&console.log("[MeoNode] FinalizationRegistry auto-cleaning portal");try{r&&"function"==typeof r.unmount&&r.unmount()}catch(e){o.__DEBUG__&&console.error("[MeoNode] Portal auto-cleanup unmount error:",e)}try{t?.isConnected&&t.remove()}catch(e){o.__DEBUG__&&console.error("[MeoNode] Portal auto-cleanup DOM removal error:",e)}});render(o=!1){!i.NodeUtil.isServer&&this.stableKey&&s.MountTrackerUtil.trackMount(this.stableKey);const l=i.NodeUtil.shouldCacheElement(this)?d.elementCache.get(this.stableKey):void 0,c=i.NodeUtil.shouldNodeUpdate(l?.prevDeps,this._deps,o);if(!c&&l?.renderedElement)return l.accessCount+=1,l.renderedElement;const u=!c,h=d.acquireRenderContext();let{workStack:p}=h;const{renderedElements:m}=h;let g=0;try{const o=e=>{if(e>p.length){const t=Math.max(e,p.length<<1),r=new Array(t);for(let e=0;e<g;e++)r[e]=p[e];p=r}};for(p[g++]={node:this,isProcessed:!1,blocked:u};g>0;){const s=p[g-1];if(!s){g--;continue}const{node:a,isProcessed:l,blocked:c}=s;if(l){g--;const{children:o,key:s,css:l,nativeProps:c,disableEmotion:u,...h}=a.props;let p=[];if(o){const t=Array.isArray(o)?o:[o],r=t.length;p=new Array(r);for(let n=0;n<r;n++){const r=t[n];if(i.NodeUtil.isNodeInstance(r)){const e=m.get(r);if(!e)throw new Error(`[MeoNode] Missing rendered element for child node: ${r.stableKey}`);p[n]=e}else e.isValidElement(r),p[n]=r}}const _={...h,key:s,...c};let y;if(a.element===e.Fragment||t.isFragment(a.element))y=e.createElement(a.element,{key:s},...p);else{y=!u&&(l||!r.hasNoStyleTag(a.element))?e.createElement(n.default,{element:a.element,..._,css:l,suppressHydrationWarning:!0},...p):e.createElement(a.element,_,...p)}if(i.NodeUtil.shouldCacheElement(a)){const e=d.elementCache.get(a.stableKey);if(e)e.prevDeps=a._deps,e.renderedElement=y,e.accessCount+=1;else{const e={prevDeps:a._deps,renderedElement:y,nodeRef:new WeakRef(a),createdAt:Date.now(),accessCount:1,instanceId:a.instanceId};d.elementCache.set(a.stableKey,e),d.cacheCleanupRegistry.register(a,{cacheKey:a.stableKey,instanceId:a.instanceId},a)}}m.set(a,y)}else{s.isProcessed=!0;const e=a.props.children;if(e){const t=(Array.isArray(e)?e:[e]).filter(i.NodeUtil.isNodeInstance);o(g+t.length);for(let e=t.length-1;e>=0;e--){const r=t[e],n=i.NodeUtil.shouldCacheElement(r)?d.elementCache.get(r.stableKey):void 0,o=i.NodeUtil.shouldNodeUpdate(n?.prevDeps,r._deps,c);if(!o&&n?.renderedElement){m.set(r,n.renderedElement);continue}const s=c||!o;p[g++]={node:r,isProcessed:!1,blocked:s}}}}}const s=m.get(this);return i.NodeUtil.shouldCacheElement(this)?e.createElement(a.default,{node:this},s):s}finally{for(let e=0;e<g;e++)p[e]=null;d.releaseRenderContext({workStack:p,renderedElements:m})}}toPortal(){if(!i.NodeUtil.ensurePortalInfrastructure(this))throw new Error("toPortal() can only be called in a client-side environment");const e=i.NodeUtil.portalInfrastructure.get(this),{domElement:t,reactRoot:r}=e;(()=>{try{r.render(this.render())}catch(e){o.__DEBUG__&&console.error("[MeoNode] Portal render error:",e)}})();let n=!1;const s=r.unmount.bind(r);return r.update=e=>{if(n)o.__DEBUG__&&console.warn("[MeoNode] Attempt to update already-unmounted portal");else try{const t=i.NodeUtil.isNodeInstance(e)?e.render():e;r.render(t)}catch(e){o.__DEBUG__&&console.error("[MeoNode] Portal update error:",e)}},r.unmount=()=>{if(n)o.__DEBUG__&&console.warn("[MeoNode] Portal already unmounted");else{n=!0;try{d.portalCleanupRegistry.unregister(this)}catch(e){o.__DEBUG__&&console.warn("[MeoNode] Portal unregister warning:",e)}i.NodeUtil.portalInfrastructure.delete(this);try{t?.isConnected&&s()}catch(e){o.__DEBUG__&&console.error("[MeoNode] Portal unmount error:",e)}try{t?.isConnected&&t.remove()}catch(e){o.__DEBUG__&&console.error("[MeoNode] Portal DOM cleanup error:",e)}}},r}static clearCaches(){const e=Array.from(d.elementCache.keys());o.__DEBUG__&&console.log(`[MeoNode] clearCaches: Clearing ${e.length} entries`);for(const t of e){const e=d.elementCache.get(t);if(e){const r=e.nodeRef?.deref();if(r)try{d.cacheCleanupRegistry.unregister(r),r.lastSignature=void 0,r.lastPropsObj=void 0}catch{o.__DEBUG__&&console.warn(`[MeoNode] Could not unregister ${t} from FinalizationRegistry`)}}}d.propProcessingCache.clear(),d.elementCache.clear(),c.ThemeUtil.clearThemeCache(),s.MountTrackerUtil.cleanup(),o.__DEBUG__&&console.log("[MeoNode] All caches cleared")}}function u(e,t={},r){return new d(e,t,r)}u.clearCaches=d.clearCaches,exports.BaseNode=d,exports.Node=u,exports.createChildrenFirstNode=function(e,t){const r=(r,n,o)=>u(e,{...t,...n,children:r},o);return r.element=e,r},exports.createNode=function(e,t){const r=(r,n)=>u(e,{...t,...r},n);return r.element=e,r};
@@ -1 +1 @@
1
- "use strict";var e=require("react"),t=require("../helper/react-is.helper.js"),o=require("../helper/common.helper.js"),r=require("../constant/common.const.js"),s=require("../core.node.js"),n=require("react-dom/client");class i{constructor(){}static isServer="undefined"==typeof window;static _functionSignatureCache=new WeakMap;static CACHE_SIZE_LIMIT=500;static CACHE_CLEANUP_BATCH=50;static _cssCache=new WeakMap;static CRITICAL_PROPS=new Set(["css","className","disableEmotion","props"]);static portalInfrastructure=new WeakMap;static isNodeInstance=e=>"object"==typeof e&&null!==e&&"element"in e&&"function"==typeof e.render&&"function"==typeof e.toPortal&&"isBaseNode"in e;static isStyleProp=i.isServer||"undefined"==typeof document?()=>!1:e=>e in document.body.style;static hashString(e){let t=2166136261,o=5381;for(let r=0;r<e.length;r++){const s=e.charCodeAt(r);t^=s,t=Math.imul(t,16777619),o=33*o^s}return`${(t>>>0).toString(36)}_${(o>>>0).toString(36)}`}static hashCSS(e){const t=this._cssCache.get(e);if(t)return t;const o=Object.keys(e);let r=o.length;for(let t=0;t<Math.min(o.length,10);t++){const s=o[t],n=e[s];r=(r<<5)-r+s.charCodeAt(0),r&=r,"string"==typeof n&&(r=(r<<5)-r+n.length)}const s=r.toString(36);return this._cssCache.set(e,s),s}static createPropSignature(e,t){if(i.isServer)return;const r=o.getElementTypeName(e),s=Object.keys(t);s.length>1&&s.sort();const n=[`${r}:`];if("function"==typeof e){let t=i._functionSignatureCache.get(e);t||(t=i.hashString(e.toString()),i._functionSignatureCache.set(e,t)),n.push(t)}for(const e of s){const o=t[e];let r;const s=typeof o;if("string"===s||"number"===s||"boolean"===s)r=`${e}:${o};`;else if(null===o)r=`${e}:null;`;else if(void 0===o)r=`${e}:undefined;`;else if("css"===e&&"object"==typeof o)r=`css:${this.hashCSS(o)};`;else if(Array.isArray(o)){const t=o.filter(e=>{const t=typeof e;return"string"===t||"number"===t||"boolean"===t||null===e});r=t.length===o.length?`${e}:[${t.join(",")}];`:`${e}:[${o.length}];`}else if(o&&o.isBaseNode)r=`${e}:${o.stableKey};`;else{r=`${e}:{${Object.keys(o).sort().join(",")}};`}n.push(r)}return i.hashString(n.join(","))}static extractCriticalProps(e,t){const o={_keyCount:t.length};let r=0;for(const s of t){if(r>=50)break;if(i.CRITICAL_PROPS.has(s)){o[s]=e[s],r++;continue}const n=s.charCodeAt(0);111!==n||110!==s.charCodeAt(1)?!(97===n&&114===s.charCodeAt(1)&&105===s.charCodeAt(2)&&97===s.charCodeAt(3)||100===n&&97===s.charCodeAt(1)&&116===s.charCodeAt(2)&&97===s.charCodeAt(3))?t.length<=100&&i.isStyleProp(s)&&(o[s]=e[s],r++):(o[s]=e[s],r++):(o[s]=e[s],r++)}return o}static getCachedCssProps(e,t){if(i.isServer||!t)return{cssProps:o.getCSSProps(e)};const r=s.BaseNode.propProcessingCache.get(t);if(r)return r.lastAccess=Date.now(),r.hitCount++,{cssProps:r.cssProps};const n=o.getCSSProps(e);return s.BaseNode.propProcessingCache.set(t,{cssProps:n,signature:t,lastAccess:Date.now(),hitCount:1}),s.BaseNode.propProcessingCache.size>i.CACHE_SIZE_LIMIT&&!s.BaseNode.scheduledCleanup&&(s.BaseNode.scheduledCleanup=!0,"undefined"!=typeof requestIdleCallback?requestIdleCallback(()=>{i._evictLRUEntries(),s.BaseNode.scheduledCleanup=!1},{timeout:2e3}):setTimeout(()=>{i._evictLRUEntries(),s.BaseNode.scheduledCleanup=!1},100)),{cssProps:n}}static _evictLRUEntries(){const e=Date.now(),t=new a((e,t)=>t.score-e.score);for(const[o,r]of s.BaseNode.propProcessingCache.entries()){const s=this._calculateEvictionScore(r,e);t.push({key:o,score:s})}for(let e=0;e<i.CACHE_CLEANUP_BATCH;e++){const e=t.pop();if(!e)break;s.BaseNode.propProcessingCache.delete(e.key)}}static _calculateEvictionScore(e,t){return(t-e.lastAccess)/1e3*.3+1e3/(e.hitCount+1)*.7}static processProps(e,t={},r){const{ref:s,key:n,children:a,css:c,props:d={},disableEmotion:l,...p}=t;if(0===Object.keys(p).length&&!c)return o.omitUndefined({ref:s,key:n,disableEmotion:l,nativeProps:o.omitUndefined(d),children:i._processChildren(a,l)});const u={},h={},f=Object.keys(p);for(let e=0;e<f.length;e++){const t=f[e],o=p[t],r=typeof o;"string"===r||"number"===r||"boolean"===r?u[t]=o:h[t]=o}const m=i.createPropSignature(e,u),{cssProps:C}=i.getCachedCssProps(u,m),y=o.getCSSProps(h),b=o.getDOMProps(p),E={...C,...y,...c},g=i._processChildren(a,l,r);return o.omitUndefined({ref:s,key:n,css:E,...b,disableEmotion:l,nativeProps:o.omitUndefined(d),children:g})}static _processChildren(e,t,o){if(e)return"function"==typeof e?e:Array.isArray(e)?1===e.length?i.processRawNode(e[0],t,`${o}_0`):e.map((e,r)=>i.processRawNode(e,t,`${o}_${r}`)):i.processRawNode(e,t,o)}static shouldNodeUpdate(e,t,o){return!!i.isServer||!o&&(void 0===t||(void 0===e||(t.length!==e.length||!!t.some((t,o)=>!Object.is(t,e[o])))))}static processRawNode(o,r,n){if(null==o||"string"==typeof o||"number"==typeof o||"boolean"==typeof o)return o;if(i.isNodeInstance(o)){if(n||r&&!o.rawProps.disableEmotion){const e=new s.BaseNode(o.element,o.rawProps,o.dependencies);return e.stableKey=`${n}:${e.stableKey}`,r&&!e.rawProps.disableEmotion&&(e.rawProps.disableEmotion=!0),e}return o}if(i.isFunctionChild(o))return new s.BaseNode(i.functionRenderer,{props:{render:o,disableEmotion:r}},void 0);if(e.isValidElement(o)){const{style:e,...t}=o.props,n={...t,...e||{}};return new s.BaseNode(o.type,{...n,...null!==o.key&&void 0!==o.key?{key:o.key}:{},disableEmotion:r},void 0)}return t.isReactClassComponent(o)||t.isMemo(o)||t.isForwardRef(o)?new s.BaseNode(o,{disableEmotion:r},void 0):o instanceof e.Component?i.processRawNode(o.render(),r,n):o}static isFunctionChild(e){if("function"!=typeof e||t.isReactClassComponent(e)||t.isMemo(e)||t.isForwardRef(e))return!1;try{return!(e.prototype&&"function"==typeof e.prototype.render)}catch(e){return r.__DEBUG__&&console.error("MeoNode: Error checking if a node is a function child.",e),!0}}static functionRenderer({render:t,disableEmotion:n}){let a;try{a=t()}catch(e){r.__DEBUG__&&console.error("MeoNode: Error executing function-as-a-child.",e),a=null}if(null==a)return a;if(i.isNodeInstance(a))return n&&!a.rawProps.disableEmotion?new s.BaseNode(a.element,{...a.rawProps,disableEmotion:!0}).render():a.render();if(Array.isArray(a)){const e=(e,t)=>{try{return`${o.getElementTypeName(e)}-${t}`}catch(e){return r.__DEBUG__&&console.error("MeoNode: Could not determine element type name for key in function-as-a-child.",e),`item-${t}`}};return a.map((t,o)=>i.renderProcessedNode({processedElement:i.processRawNode(t,n),passedKey:e(t,o),disableEmotion:n}))}if(a instanceof e.Component)return i.renderProcessedNode({processedElement:i.processRawNode(a.render(),n),disableEmotion:n});if("string"==typeof a||"number"==typeof a||"boolean"==typeof a)return a;const c=i.processRawNode(a,n);return c?i.renderProcessedNode({processedElement:c,disableEmotion:n}):a}static renderProcessedNode({processedElement:o,passedKey:r,disableEmotion:n}){const a={};if(void 0!==r&&(a.key=r),i.isNodeInstance(o)){const e=o.rawProps?.key;return o.rawProps.disableEmotion=n,e===r?o.render():new s.BaseNode(o.element,{...o.rawProps,...a}).render()}return t.isReactClassComponent(o)?new s.BaseNode(o,{...a,disableEmotion:n}).render():o instanceof e.Component?o.render():"function"==typeof o?e.createElement(o,{key:r}):o}static ensurePortalInfrastructure(e){if(i.isServer)return!1;let t=i.portalInfrastructure.get(e);if(t?.domElement?.isConnected&&t?.reactRoot)return!0;if(t&&(!t.domElement?.isConnected||!t.reactRoot)){try{t.reactRoot?.unmount?.()}catch(e){r.__DEBUG__&&console.error("MeoNode: Error unmounting stale portal root.",e)}i.cleanupPortalInfra(t),i.portalInfrastructure.delete(e),t=void 0}const o=document.createElement("div");document.body.appendChild(o);const a=n.createRoot(o),c={render:a.render.bind(a),unmount:a.unmount.bind(a),update:()=>{}};return t={domElement:o,reactRoot:c},i.portalInfrastructure.set(e,t),s.BaseNode.portalCleanupRegistry.register(e,{domElement:o,reactRoot:c},e),!0}static cleanupPortalInfra(e){try{e.reactRoot?.unmount&&e.reactRoot.unmount()}catch(e){r.__DEBUG__&&console.error("Portal cleanup error:",e)}try{e.domElement?.isConnected&&e.domElement.remove()}catch(e){r.__DEBUG__&&console.error("DOM removal error:",e)}}}class a{heap=[];comparator;constructor(e){this.comparator=e}size(){return this.heap.length}isEmpty(){return 0===this.size()}push(e){this.heap.push(e),this.bubbleUp()}pop(){if(this.isEmpty())return;this.swap(0,this.size()-1);const e=this.heap.pop();return this.bubbleDown(),e}bubbleUp(e=this.size()-1){for(;e>0;){const t=Math.floor((e-1)/2);if(this.comparator(this.heap[t],this.heap[e])<=0)break;this.swap(t,e),e=t}}bubbleDown(e=0){const t=this.size()-1;for(;;){const o=2*e+1,r=2*e+2;let s=e;if(o<=t&&this.comparator(this.heap[o],this.heap[s])<0&&(s=o),r<=t&&this.comparator(this.heap[r],this.heap[s])<0&&(s=r),s===e)break;this.swap(e,s),e=s}}swap(e,t){[this.heap[e],this.heap[t]]=[this.heap[t],this.heap[e]]}}exports.NodeUtil=i;
1
+ "use strict";var e=require("react"),t=require("../helper/react-is.helper.js"),o=require("../helper/common.helper.js"),r=require("../constant/common.const.js"),s=require("../core.node.js"),n=require("react-dom/client");class i{constructor(){}static isServer="undefined"==typeof window;static _functionSignatureCache=new WeakMap;static CACHE_SIZE_LIMIT=500;static CACHE_CLEANUP_BATCH=50;static _cssCache=new WeakMap;static CRITICAL_PROPS=new Set(["css","className","disableEmotion","props"]);static portalInfrastructure=new WeakMap;static isNodeInstance=e=>"object"==typeof e&&null!==e&&"element"in e&&"function"==typeof e.render&&"function"==typeof e.toPortal&&"isBaseNode"in e;static isStyleProp=i.isServer||"undefined"==typeof document?()=>!1:e=>e in document.body.style;static hashString(e){let t=2166136261,o=5381;for(let r=0;r<e.length;r++){const s=e.charCodeAt(r);t^=s,t=Math.imul(t,16777619),o=33*o^s}return`${(t>>>0).toString(36)}_${(o>>>0).toString(36)}`}static hashCSS(e){const t=this._cssCache.get(e);if(t)return t;const o=Object.keys(e);let r=o.length;for(let t=0;t<Math.min(o.length,10);t++){const s=o[t],n=e[s];r=(r<<5)-r+s.charCodeAt(0),r&=r,"string"==typeof n&&(r=(r<<5)-r+n.length)}const s=r.toString(36);return this._cssCache.set(e,s),s}static createPropSignature(e,t){if(i.isServer)return;const r=o.getElementTypeName(e),s=Object.keys(t);s.length>1&&s.sort();const n=[`${r}:`];if("function"==typeof e){let t=i._functionSignatureCache.get(e);t||(t=i.hashString(e.toString()),i._functionSignatureCache.set(e,t)),n.push(t)}for(const e of s){const o=t[e];let r;const s=typeof o;if("string"===s||"number"===s||"boolean"===s)r=`${e}:${o};`;else if(null===o)r=`${e}:null;`;else if(void 0===o)r=`${e}:undefined;`;else if("css"===e&&"object"==typeof o)r=`css:${this.hashCSS(o)};`;else if(Array.isArray(o)){const t=o.filter(e=>{const t=typeof e;return"string"===t||"number"===t||"boolean"===t||null===e});r=t.length===o.length?`${e}:[${t.join(",")}];`:`${e}:[${o.length}];`}else if(o&&o.isBaseNode)r=`${e}:${o.stableKey};`;else{r=`${e}:{${Object.keys(o).sort().join(",")}};`}n.push(r)}return i.hashString(n.join(","))}static extractCriticalProps(e,t){const o={_keyCount:t.length};let r=0;for(const s of t){if(r>=50)break;if(i.CRITICAL_PROPS.has(s)){o[s]=e[s],r++;continue}const n=s.charCodeAt(0);111!==n||110!==s.charCodeAt(1)?!(97===n&&114===s.charCodeAt(1)&&105===s.charCodeAt(2)&&97===s.charCodeAt(3)||100===n&&97===s.charCodeAt(1)&&116===s.charCodeAt(2)&&97===s.charCodeAt(3))?t.length<=100&&i.isStyleProp(s)&&(o[s]=e[s],r++):(o[s]=e[s],r++):(o[s]=e[s],r++)}return o}static getCachedCssProps(e,t){if(i.isServer||!t)return{cssProps:o.getCSSProps(e)};const r=s.BaseNode.propProcessingCache.get(t);if(r)return r.lastAccess=Date.now(),r.hitCount++,{cssProps:r.cssProps};const n=o.getCSSProps(e);return s.BaseNode.propProcessingCache.set(t,{cssProps:n,signature:t,lastAccess:Date.now(),hitCount:1}),s.BaseNode.propProcessingCache.size>i.CACHE_SIZE_LIMIT&&!s.BaseNode.scheduledCleanup&&(s.BaseNode.scheduledCleanup=!0,"undefined"!=typeof requestIdleCallback?requestIdleCallback(()=>{i._evictLRUEntries(),s.BaseNode.scheduledCleanup=!1},{timeout:2e3}):setTimeout(()=>{i._evictLRUEntries(),s.BaseNode.scheduledCleanup=!1},100)),{cssProps:n}}static _evictLRUEntries(){const e=Date.now(),t=new a((e,t)=>t.score-e.score);for(const[o,r]of s.BaseNode.propProcessingCache.entries()){const s=this._calculateEvictionScore(r,e);t.push({key:o,score:s})}for(let e=0;e<i.CACHE_CLEANUP_BATCH;e++){const e=t.pop();if(!e)break;s.BaseNode.propProcessingCache.delete(e.key)}}static _calculateEvictionScore(e,t){return(t-e.lastAccess)/1e3*.3+1e3/(e.hitCount+1)*.7}static processProps(e,t={},r){const{ref:s,key:n,children:a,css:c,props:d={},disableEmotion:l,...p}=t;if(0===Object.keys(p).length&&!c)return o.omitUndefined({ref:s,key:n,disableEmotion:l,nativeProps:o.omitUndefined(d),children:i._processChildren(a,l)});const u={},h={},f=Object.keys(p);for(let e=0;e<f.length;e++){const t=f[e],o=p[t],r=typeof o;"string"===r||"number"===r||"boolean"===r?u[t]=o:h[t]=o}const m=i.createPropSignature(e,u),{cssProps:C}=i.getCachedCssProps(u,m),y=o.getCSSProps(h),b=o.getDOMProps(p),E={...C,...y,...c},g=i._processChildren(a,l,r);return o.omitUndefined({ref:s,key:n,css:E,...b,disableEmotion:l,nativeProps:o.omitUndefined(d),children:g})}static _processChildren(e,t,o){if(e)return"function"==typeof e?e:Array.isArray(e)?1===e.length?i.processRawNode(e[0],t,`${o}_0`):e.map((e,r)=>i.processRawNode(e,t,`${o}_${r}`)):i.processRawNode(e,t,o)}static shouldCacheElement(e){return!i.isServer&&!!e.stableKey&&!!e.dependencies}static shouldNodeUpdate(e,t,o){return!!i.isServer||!o&&(void 0===t||(void 0===e||(t.length!==e.length||!!t.some((t,o)=>!Object.is(t,e[o])))))}static processRawNode(o,r,n){if(null==o||"string"==typeof o||"number"==typeof o||"boolean"==typeof o)return o;if(i.isNodeInstance(o)){if(n||r&&!o.rawProps.disableEmotion){const e=new s.BaseNode(o.element,o.rawProps,o.dependencies);return e.stableKey=`${n}:${e.stableKey}`,r&&!e.rawProps.disableEmotion&&(e.rawProps.disableEmotion=!0),e}return o}if(i.isFunctionChild(o))return new s.BaseNode(i.functionRenderer,{props:{render:o,disableEmotion:r}},void 0);if(e.isValidElement(o)){const{style:e,...t}=o.props,n={...t,...e||{}};return new s.BaseNode(o.type,{...n,...null!==o.key&&void 0!==o.key?{key:o.key}:{},disableEmotion:r},void 0)}return t.isReactClassComponent(o)||t.isMemo(o)||t.isForwardRef(o)?new s.BaseNode(o,{disableEmotion:r},void 0):o instanceof e.Component?i.processRawNode(o.render(),r,n):o}static isFunctionChild(e){if("function"!=typeof e||t.isReactClassComponent(e)||t.isMemo(e)||t.isForwardRef(e))return!1;try{return!(e.prototype&&"function"==typeof e.prototype.render)}catch(e){return r.__DEBUG__&&console.error("MeoNode: Error checking if a node is a function child.",e),!0}}static functionRenderer({render:t,disableEmotion:n}){let a;try{a=t()}catch(e){r.__DEBUG__&&console.error("MeoNode: Error executing function-as-a-child.",e),a=null}if(null==a)return a;if(i.isNodeInstance(a))return n&&!a.rawProps.disableEmotion?new s.BaseNode(a.element,{...a.rawProps,disableEmotion:!0}).render():a.render();if(Array.isArray(a)){const e=(e,t)=>{try{return`${o.getElementTypeName(e)}-${t}`}catch(e){return r.__DEBUG__&&console.error("MeoNode: Could not determine element type name for key in function-as-a-child.",e),`item-${t}`}};return a.map((t,o)=>i.renderProcessedNode({processedElement:i.processRawNode(t,n),passedKey:e(t,o),disableEmotion:n}))}if(a instanceof e.Component)return i.renderProcessedNode({processedElement:i.processRawNode(a.render(),n),disableEmotion:n});if("string"==typeof a||"number"==typeof a||"boolean"==typeof a)return a;const c=i.processRawNode(a,n);return c?i.renderProcessedNode({processedElement:c,disableEmotion:n}):a}static renderProcessedNode({processedElement:o,passedKey:r,disableEmotion:n}){const a={};if(void 0!==r&&(a.key=r),i.isNodeInstance(o)){const e=o.rawProps?.key;return o.rawProps.disableEmotion=n,e===r?o.render():new s.BaseNode(o.element,{...o.rawProps,...a}).render()}return t.isReactClassComponent(o)?new s.BaseNode(o,{...a,disableEmotion:n}).render():o instanceof e.Component?o.render():"function"==typeof o?e.createElement(o,{key:r}):o}static ensurePortalInfrastructure(e){if(i.isServer)return!1;let t=i.portalInfrastructure.get(e);if(t?.domElement?.isConnected&&t?.reactRoot)return!0;if(t&&(!t.domElement?.isConnected||!t.reactRoot)){try{t.reactRoot?.unmount?.()}catch(e){r.__DEBUG__&&console.error("MeoNode: Error unmounting stale portal root.",e)}i.cleanupPortalInfra(t),i.portalInfrastructure.delete(e),t=void 0}const o=document.createElement("div");document.body.appendChild(o);const a=n.createRoot(o),c={render:a.render.bind(a),unmount:a.unmount.bind(a),update:()=>{}};return t={domElement:o,reactRoot:c},i.portalInfrastructure.set(e,t),s.BaseNode.portalCleanupRegistry.register(e,{domElement:o,reactRoot:c},e),!0}static cleanupPortalInfra(e){try{e.reactRoot?.unmount&&e.reactRoot.unmount()}catch(e){r.__DEBUG__&&console.error("Portal cleanup error:",e)}try{e.domElement?.isConnected&&e.domElement.remove()}catch(e){r.__DEBUG__&&console.error("DOM removal error:",e)}}}class a{heap=[];comparator;constructor(e){this.comparator=e}size(){return this.heap.length}isEmpty(){return 0===this.size()}push(e){this.heap.push(e),this.bubbleUp()}pop(){if(this.isEmpty())return;this.swap(0,this.size()-1);const e=this.heap.pop();return this.bubbleDown(),e}bubbleUp(e=this.size()-1){for(;e>0;){const t=Math.floor((e-1)/2);if(this.comparator(this.heap[t],this.heap[e])<=0)break;this.swap(t,e),e=t}}bubbleDown(e=0){const t=this.size()-1;for(;;){const o=2*e+1,r=2*e+2;let s=e;if(o<=t&&this.comparator(this.heap[o],this.heap[s])<0&&(s=o),r<=t&&this.comparator(this.heap[r],this.heap[s])<0&&(s=r),s===e)break;this.swap(e,s),e=s}}swap(e,t){[this.heap[e],this.heap[t]]=[this.heap[t],this.heap[e]]}}exports.NodeUtil=i;
@@ -17,7 +17,7 @@ import type { NodeInstance } from '../types/node.type.js';
17
17
  * @param {ReactNode} [props.children] The children to be rendered by this component.
18
18
  * @returns {ReactNode} The `children` passed to the component.
19
19
  */
20
- export default function MeoNodeUnmounter({ node, children, ...rest }: {
20
+ export default function MeoNodeUnmounter({ children, ...props }: {
21
21
  node: NodeInstance;
22
22
  children?: ReactNode;
23
23
  }): ReactNode;
@@ -1 +1 @@
1
- {"version":3,"file":"meonode-unmounter.client.d.ts","sourceRoot":"","sources":["../../../src/components/meonode-unmounter.client.ts"],"names":[],"mappings":"AACA,OAAO,EAAgC,KAAK,SAAS,EAA6B,MAAM,OAAO,CAAA;AAG/F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAE3D;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,GAAG,SAAS,CA0B7H"}
1
+ {"version":3,"file":"meonode-unmounter.client.d.ts","sourceRoot":"","sources":["../../../src/components/meonode-unmounter.client.ts"],"names":[],"mappings":"AACA,OAAO,EAAgC,KAAK,SAAS,EAA6B,MAAM,OAAO,CAAA;AAG/F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAE3D;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,GAAG,SAAS,CAgCxH"}
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{useEffectEvent as e,useEffect as t,isValidElement as r,cloneElement as o}from"react";import{MountTrackerUtil as a}from"../util/mount-tracker.util.js";import{BaseNode as n}from"../core.node.js";function s({node:s,children:l,...u}){const i=e(()=>{s.stableKey&&(n.elementCache.delete(s.stableKey),a.mountedNodes.has(s.stableKey)&&a.untrackMount(s.stableKey),n.cacheCleanupRegistry.unregister(s)),s.lastSignature=void 0});return t(()=>()=>i(),[]),r(l)?o(l,u):l}export{s as default};
2
+ import{useEffectEvent as e,useEffect as t,isValidElement as r,cloneElement as o}from"react";import{MountTrackerUtil as n}from"../util/mount-tracker.util.js";import{BaseNode as a}from"../core.node.js";function s({children:s,...l}){const{node:u,...c}=l,i=e(()=>{u.stableKey&&(a.elementCache.delete(u.stableKey),n.mountedNodes.has(u.stableKey)&&n.untrackMount(u.stableKey),a.cacheCleanupRegistry.unregister(u)),u.lastSignature=void 0});return t(()=>()=>i(),[]),r(s)&&Object.keys(c).length>0?o(s,c):s}export{s as default};
@@ -1 +1 @@
1
- {"version":3,"file":"core.node.d.ts","sourceRoot":"","sources":["../../src/core.node.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"core.node.d.ts","sourceRoot":"","sources":["../../src/core.node.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,KAAK,YAAY,EAElB,MAAM,OAAO,CAAA;AACd,OAAO,KAAK,EACV,QAAQ,EACR,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,WAAW,EAEX,eAAe,EACf,YAAY,EACZ,UAAU,EACV,SAAS,EACT,mBAAmB,EACnB,OAAO,EAER,MAAM,yBAAyB,CAAA;AAWhC;;;;;;;GAOG;AACH,qBAAa,QAAQ,CAAC,CAAC,SAAS,eAAe,GAAG,eAAe;IACxD,UAAU,EAAE,MAAM,CAAgE;IAElF,OAAO,EAAE,CAAC,CAAA;IACV,QAAQ,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAK;IAC3C,SAAgB,UAAU,UAAO;IAEjC,OAAO,CAAC,MAAM,CAAC,CAAgB;IAC/B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAgB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAA;IAGzB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAEtC,aAAa,CAAC,EAAE,MAAM,CAAA;IAEtB,OAAc,YAAY,iCAAuC;IACjE,OAAc,mBAAmB,mCAAyC;IAG1E,OAAc,gBAAgB,UAAQ;IAGtC,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAQ;IAGzC,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAiF;IAEjH,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAWnC,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAcnC,YAAY,OAAO,EAAE,CAAC,EAAE,QAAQ,GAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAM,EAAE,IAAI,CAAC,EAAE,cAAc,EAoBlF;IAED;;;;OAIG;IACH,IAAW,KAAK,IAAI,cAAc,CAKjC;IAED;;;;;;;OAOG;IACH,IAAW,YAAY,IAAI,cAAc,GAAG,SAAS,CAEpD;IAED;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,aAAa;IA2BrB;;;;;;;;OAQG;IACH,OAAc,oBAAoB;;;OAchC;IAEF;;;;;;;;;;;;;;OAcG;IACH,OAAc,qBAAqB;;;;;OAiCjC;IAEF;;;;;;;;;;;;;OAaG;IACI,MAAM,CAAC,aAAa,GAAE,OAAe,GAAG,YAAY,CAAC,cAAc,CAAC,CAqM1E;IAED;;;;OAIG;IACI,QAAQ,IAAI,UAAU,CA0F5B;IAED;;;;;;;;OAQG;IACH,OAAc,WAAW,SAyCxB;CAGF;AAID;;;;GAIG;AACH,iBAAS,IAAI,CAAC,eAAe,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,SAAS,eAAe,EACtF,OAAO,EAAE,CAAC,EACV,KAAK,GAAE,WAAW,CAAC,CAAC,EAAE,eAAe,CAAyC,EAC9E,IAAI,CAAC,EAAE,cAAc,GACpB,YAAY,CAAC,CAAC,CAAC,CAEjB;;;;AAmBD,OAAO,EAAE,IAAI,EAAE,CAAA;AAEf;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,sBAAsB,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,SAAS,eAAe,EAC1G,OAAO,EAAE,CAAC,EACV,YAAY,CAAC,EAAE,WAAW,CAAC,CAAC,EAAE,sBAAsB,CAAC,GACpD,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,GACxC,CAAC,CAAC,eAAe,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzE,KAAK,EAAE,WAAW,CAAC,CAAC,EAAE,eAAe,CAAC,EACtC,IAAI,CAAC,EAAE,cAAc,KAClB,YAAY,CAAC,CAAC,CAAC,CAAC,GAAG;IACtB,OAAO,EAAE,CAAC,CAAA;CACX,GACD,CAAC,CAAC,eAAe,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzE,KAAK,CAAC,EAAE,WAAW,CAAC,CAAC,EAAE,eAAe,CAAC,EACvC,IAAI,CAAC,EAAE,cAAc,KAClB,YAAY,CAAC,CAAC,CAAC,CAAC,GAAG;IACtB,OAAO,EAAE,CAAC,CAAA;CACX,CAOJ;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,sBAAsB,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,SAAS,eAAe,EACvH,OAAO,EAAE,CAAC,EACV,YAAY,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,sBAAsB,GAAG,UAAU,CAAC,GAAG,sBAAsB,GACpG,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,GACxC,CAAC,CAAC,eAAe,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzE,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,EAAE,eAAe,CAAC,EAAE,UAAU,CAAC,EACxD,IAAI,CAAC,EAAE,cAAc,KAClB,YAAY,CAAC,CAAC,CAAC,CAAC,GAAG;IAAE,OAAO,EAAE,CAAC,CAAA;CAAE,GACtC,CAAC,CAAC,eAAe,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzE,QAAQ,CAAC,EAAE,QAAQ,EACnB,KAAK,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,EAAE,eAAe,CAAC,EAAE,UAAU,CAAC,EACzD,IAAI,CAAC,EAAE,cAAc,KAClB,YAAY,CAAC,CAAC,CAAC,CAAC,GAAG;IAAE,OAAO,EAAE,CAAC,CAAA;CAAE,CAQzC"}
@@ -1 +1 @@
1
- import{isValidElement as e,Fragment as t,createElement as r}from"react";import{isValidElementType as n,isFragment as o}from"./helper/react-is.helper.js";import{getComponentType as s,hasNoStyleTag as a,getElementTypeName as l}from"./helper/common.helper.js";import i from"./components/styled-renderer.client.js";import{__DEBUG__ as c}from"./constant/common.const.js";import{MountTrackerUtil as d}from"./util/mount-tracker.util.js";import h from"./components/meonode-unmounter.client.js";import{NavigationCacheManagerUtil as p}from"./util/navigation-cache-manager.util.js";import{NodeUtil as u}from"./util/node.util.js";import{ThemeUtil as m}from"./util/theme.util.js";class g{instanceId=Math.random().toString(36).slice(2)+Date.now().toString(36);element;rawProps={};isBaseNode=!0;_props;_deps;stableKey;lastPropsObj;lastSignature;static elementCache=new Map;static propProcessingCache=new Map;static scheduledCleanup=!1;static _navigationStarted=!1;static renderContextPool=[];static acquireRenderContext(){const e=g.renderContextPool;return e.length>0?e.pop():{workStack:new Array(512),renderedElements:new Map}}static releaseRenderContext(e){g.renderContextPool.length<50&&e.workStack.length<2048&&(e.workStack.length=0,e.renderedElements.clear(),g.renderContextPool.push(e))}constructor(e,t={},r){if(!n(e)){const t=s(e);throw new Error(`Invalid element type: ${t} provided!`)}this.element=e,this.rawProps=t,this._deps=r;const{ref:o,children:a,...l}=t;this.stableKey=this._getStableKey(l),u.isServer||g._navigationStarted||(p.getInstance().start(),g._navigationStarted=!0)}get props(){return this._props||(this._props=u.processProps(this.element,this.rawProps,this.stableKey)),this._props}get dependencies(){return this._deps}_getStableKey({key:e,...t}){if(u.isServer)return;if(this.lastPropsObj===t)return this.lastSignature;this.lastPropsObj=t;const r=Object.keys(t),n=r.length;if(n>100){const e=u.extractCriticalProps(t,r);this.lastSignature=u.createPropSignature(this.element,e),c&&n>200&&console.warn(`MeoNode: Large props (${n} keys) on "${l(this.element)}". Consider splitting.`)}else this.lastSignature=u.createPropSignature(this.element,t);return null!=e?`${String(e)}:${this.lastSignature}`:this.lastSignature}static cacheCleanupRegistry=new FinalizationRegistry(e=>{const{cacheKey:t,instanceId:r}=e,n=g.elementCache.get(t);n?.instanceId===r&&g.elementCache.delete(t),d.mountedNodes.has(t)&&d.untrackMount(t)});static portalCleanupRegistry=new FinalizationRegistry(e=>{const{domElement:t,reactRoot:r}=e;c&&console.log("[MeoNode] FinalizationRegistry auto-cleaning portal");try{r&&"function"==typeof r.unmount&&r.unmount()}catch(e){c&&console.error("[MeoNode] Portal auto-cleanup unmount error:",e)}try{t?.isConnected&&t.remove()}catch(e){c&&console.error("[MeoNode] Portal auto-cleanup DOM removal error:",e)}});render(n=!1){!u.isServer&&this.stableKey&&d.trackMount(this.stableKey);const s=u.isServer||!this.stableKey?void 0:g.elementCache.get(this.stableKey),l=u.shouldNodeUpdate(s?.prevDeps,this._deps,n);if(!l&&s?.renderedElement)return s.accessCount+=1,s.renderedElement;const c=!l,p=g.acquireRenderContext();let{workStack:m}=p;const{renderedElements:y}=p;let f=0;try{const n=e=>{if(e>m.length){const t=Math.max(e,m.length<<1),r=new Array(t);for(let e=0;e<f;e++)r[e]=m[e];m=r}};for(m[f++]={node:this,isProcessed:!1,blocked:c};f>0;){const s=m[f-1];if(!s){f--;continue}const{node:l,isProcessed:c,blocked:d}=s;if(c){f--;const{children:n,key:s,css:c,nativeProps:d,disableEmotion:h,...p}=l.props;let m=[];if(n){const t=Array.isArray(n)?n:[n],r=t.length;m=new Array(r);for(let n=0;n<r;n++){const r=t[n];if(u.isNodeInstance(r)){const e=y.get(r);if(!e)throw new Error(`[MeoNode] Missing rendered element for child node: ${r.stableKey}`);m[n]=e}else e(r),m[n]=r}}const C={...p,key:s,...d};let P;if(l.element===t||o(l.element))P=r(l.element,{key:s},...m);else{P=!h&&(c||!a(l.element))?r(i,{element:l.element,...C,css:c,suppressHydrationWarning:!0},...m):r(l.element,C,...m)}if(!u.isServer&&l.stableKey){const e=g.elementCache.get(l.stableKey);if(e)e.prevDeps=l._deps,e.renderedElement=P,e.accessCount+=1;else{const e={prevDeps:l._deps,renderedElement:P,nodeRef:new WeakRef(l),createdAt:Date.now(),accessCount:1,instanceId:l.instanceId};g.elementCache.set(l.stableKey,e),g.cacheCleanupRegistry.register(l,{cacheKey:l.stableKey,instanceId:l.instanceId},l)}}y.set(l,P)}else{s.isProcessed=!0;const e=l.props.children;if(e){const t=(Array.isArray(e)?e:[e]).filter(u.isNodeInstance);n(f+t.length);for(let e=t.length-1;e>=0;e--){const r=t[e],n=u.isServer||!r.stableKey?void 0:g.elementCache.get(r.stableKey),o=u.shouldNodeUpdate(n?.prevDeps,r._deps,d);if(!o&&n?.renderedElement){y.set(r,n.renderedElement);continue}const s=d||!o;m[f++]={node:r,isProcessed:!1,blocked:s}}}}}const s=y.get(this);return!u.isServer&&this.stableKey?r(h,{node:this},s):s}finally{for(let e=0;e<f;e++)m[e]=null;g.releaseRenderContext({workStack:m,renderedElements:y})}}toPortal(){if(!u.ensurePortalInfrastructure(this))throw new Error("toPortal() can only be called in a client-side environment");const e=u.portalInfrastructure.get(this),{domElement:t,reactRoot:r}=e;(()=>{try{r.render(this.render())}catch(e){c&&console.error("[MeoNode] Portal render error:",e)}})();let n=!1;const o=r.unmount.bind(r);return r.update=e=>{if(n)c&&console.warn("[MeoNode] Attempt to update already-unmounted portal");else try{const t=u.isNodeInstance(e)?e.render():e;r.render(t)}catch(e){c&&console.error("[MeoNode] Portal update error:",e)}},r.unmount=()=>{if(n)c&&console.warn("[MeoNode] Portal already unmounted");else{n=!0;try{g.portalCleanupRegistry.unregister(this)}catch(e){c&&console.warn("[MeoNode] Portal unregister warning:",e)}u.portalInfrastructure.delete(this);try{t?.isConnected&&o()}catch(e){c&&console.error("[MeoNode] Portal unmount error:",e)}try{t?.isConnected&&t.remove()}catch(e){c&&console.error("[MeoNode] Portal DOM cleanup error:",e)}}},r}static clearCaches(){const e=Array.from(g.elementCache.keys());c&&console.log(`[MeoNode] clearCaches: Clearing ${e.length} entries`);for(const t of e){const e=g.elementCache.get(t);if(e){const r=e.nodeRef?.deref();if(r)try{g.cacheCleanupRegistry.unregister(r),r.lastSignature=void 0,r.lastPropsObj=void 0}catch{c&&console.warn(`[MeoNode] Could not unregister ${t} from FinalizationRegistry`)}}}g.propProcessingCache.clear(),g.elementCache.clear(),m.clearThemeCache(),d.cleanup(),c&&console.log("[MeoNode] All caches cleared")}}function y(e,t={},r){return new g(e,t,r)}function f(e,t){const r=(r,n)=>y(e,{...t,...r},n);return r.element=e,r}function C(e,t){const r=(r,n,o)=>y(e,{...t,...n,children:r},o);return r.element=e,r}y.clearCaches=g.clearCaches;export{g as BaseNode,y as Node,C as createChildrenFirstNode,f as createNode};
1
+ import{isValidElement as e,Fragment as t,createElement as r}from"react";import{isValidElementType as n,isFragment as o}from"./helper/react-is.helper.js";import{getComponentType as s,hasNoStyleTag as a,getElementTypeName as l}from"./helper/common.helper.js";import c from"./components/styled-renderer.client.js";import{__DEBUG__ as i}from"./constant/common.const.js";import{MountTrackerUtil as d}from"./util/mount-tracker.util.js";import h from"./components/meonode-unmounter.client.js";import{NavigationCacheManagerUtil as u}from"./util/navigation-cache-manager.util.js";import{NodeUtil as p}from"./util/node.util.js";import{ThemeUtil as m}from"./util/theme.util.js";class g{instanceId=Math.random().toString(36).slice(2)+Date.now().toString(36);element;rawProps={};isBaseNode=!0;_props;_deps;stableKey;lastPropsObj;lastSignature;static elementCache=new Map;static propProcessingCache=new Map;static scheduledCleanup=!1;static _navigationStarted=!1;static renderContextPool=[];static acquireRenderContext(){const e=g.renderContextPool;return e.length>0?e.pop():{workStack:new Array(512),renderedElements:new Map}}static releaseRenderContext(e){g.renderContextPool.length<50&&e.workStack.length<2048&&(e.workStack.length=0,e.renderedElements.clear(),g.renderContextPool.push(e))}constructor(e,t={},r){if(!n(e)){const t=s(e);throw new Error(`Invalid element type: ${t} provided!`)}this.element=e,this.rawProps=t,this._deps=r;const{ref:o,children:a,...l}=t;this.stableKey=this._getStableKey(l),p.isServer||g._navigationStarted||(u.getInstance().start(),g._navigationStarted=!0)}get props(){return this._props||(this._props=p.processProps(this.element,this.rawProps,this.stableKey)),this._props}get dependencies(){return this._deps}_getStableKey({key:e,...t}){if(p.isServer)return;if(this.lastPropsObj===t)return this.lastSignature;this.lastPropsObj=t;const r=Object.keys(t),n=r.length;if(n>100){const e=p.extractCriticalProps(t,r);this.lastSignature=p.createPropSignature(this.element,e),i&&n>200&&console.warn(`MeoNode: Large props (${n} keys) on "${l(this.element)}". Consider splitting.`)}else this.lastSignature=p.createPropSignature(this.element,t);return null!=e?`${String(e)}:${this.lastSignature}`:this.lastSignature}static cacheCleanupRegistry=new FinalizationRegistry(e=>{const{cacheKey:t,instanceId:r}=e,n=g.elementCache.get(t);n?.instanceId===r&&g.elementCache.delete(t),d.mountedNodes.has(t)&&d.untrackMount(t)});static portalCleanupRegistry=new FinalizationRegistry(e=>{const{domElement:t,reactRoot:r}=e;i&&console.log("[MeoNode] FinalizationRegistry auto-cleaning portal");try{r&&"function"==typeof r.unmount&&r.unmount()}catch(e){i&&console.error("[MeoNode] Portal auto-cleanup unmount error:",e)}try{t?.isConnected&&t.remove()}catch(e){i&&console.error("[MeoNode] Portal auto-cleanup DOM removal error:",e)}});render(n=!1){!p.isServer&&this.stableKey&&d.trackMount(this.stableKey);const s=p.shouldCacheElement(this)?g.elementCache.get(this.stableKey):void 0,l=p.shouldNodeUpdate(s?.prevDeps,this._deps,n);if(!l&&s?.renderedElement)return s.accessCount+=1,s.renderedElement;const i=!l,u=g.acquireRenderContext();let{workStack:m}=u;const{renderedElements:f}=u;let y=0;try{const n=e=>{if(e>m.length){const t=Math.max(e,m.length<<1),r=new Array(t);for(let e=0;e<y;e++)r[e]=m[e];m=r}};for(m[y++]={node:this,isProcessed:!1,blocked:i};y>0;){const s=m[y-1];if(!s){y--;continue}const{node:l,isProcessed:i,blocked:d}=s;if(i){y--;const{children:n,key:s,css:i,nativeProps:d,disableEmotion:h,...u}=l.props;let m=[];if(n){const t=Array.isArray(n)?n:[n],r=t.length;m=new Array(r);for(let n=0;n<r;n++){const r=t[n];if(p.isNodeInstance(r)){const e=f.get(r);if(!e)throw new Error(`[MeoNode] Missing rendered element for child node: ${r.stableKey}`);m[n]=e}else e(r),m[n]=r}}const C={...u,key:s,...d};let P;if(l.element===t||o(l.element))P=r(l.element,{key:s},...m);else{P=!h&&(i||!a(l.element))?r(c,{element:l.element,...C,css:i,suppressHydrationWarning:!0},...m):r(l.element,C,...m)}if(p.shouldCacheElement(l)){const e=g.elementCache.get(l.stableKey);if(e)e.prevDeps=l._deps,e.renderedElement=P,e.accessCount+=1;else{const e={prevDeps:l._deps,renderedElement:P,nodeRef:new WeakRef(l),createdAt:Date.now(),accessCount:1,instanceId:l.instanceId};g.elementCache.set(l.stableKey,e),g.cacheCleanupRegistry.register(l,{cacheKey:l.stableKey,instanceId:l.instanceId},l)}}f.set(l,P)}else{s.isProcessed=!0;const e=l.props.children;if(e){const t=(Array.isArray(e)?e:[e]).filter(p.isNodeInstance);n(y+t.length);for(let e=t.length-1;e>=0;e--){const r=t[e],n=p.shouldCacheElement(r)?g.elementCache.get(r.stableKey):void 0,o=p.shouldNodeUpdate(n?.prevDeps,r._deps,d);if(!o&&n?.renderedElement){f.set(r,n.renderedElement);continue}const s=d||!o;m[y++]={node:r,isProcessed:!1,blocked:s}}}}}const s=f.get(this);return p.shouldCacheElement(this)?r(h,{node:this},s):s}finally{for(let e=0;e<y;e++)m[e]=null;g.releaseRenderContext({workStack:m,renderedElements:f})}}toPortal(){if(!p.ensurePortalInfrastructure(this))throw new Error("toPortal() can only be called in a client-side environment");const e=p.portalInfrastructure.get(this),{domElement:t,reactRoot:r}=e;(()=>{try{r.render(this.render())}catch(e){i&&console.error("[MeoNode] Portal render error:",e)}})();let n=!1;const o=r.unmount.bind(r);return r.update=e=>{if(n)i&&console.warn("[MeoNode] Attempt to update already-unmounted portal");else try{const t=p.isNodeInstance(e)?e.render():e;r.render(t)}catch(e){i&&console.error("[MeoNode] Portal update error:",e)}},r.unmount=()=>{if(n)i&&console.warn("[MeoNode] Portal already unmounted");else{n=!0;try{g.portalCleanupRegistry.unregister(this)}catch(e){i&&console.warn("[MeoNode] Portal unregister warning:",e)}p.portalInfrastructure.delete(this);try{t?.isConnected&&o()}catch(e){i&&console.error("[MeoNode] Portal unmount error:",e)}try{t?.isConnected&&t.remove()}catch(e){i&&console.error("[MeoNode] Portal DOM cleanup error:",e)}}},r}static clearCaches(){const e=Array.from(g.elementCache.keys());i&&console.log(`[MeoNode] clearCaches: Clearing ${e.length} entries`);for(const t of e){const e=g.elementCache.get(t);if(e){const r=e.nodeRef?.deref();if(r)try{g.cacheCleanupRegistry.unregister(r),r.lastSignature=void 0,r.lastPropsObj=void 0}catch{i&&console.warn(`[MeoNode] Could not unregister ${t} from FinalizationRegistry`)}}}g.propProcessingCache.clear(),g.elementCache.clear(),m.clearThemeCache(),d.cleanup(),i&&console.log("[MeoNode] All caches cleared")}}function f(e,t={},r){return new g(e,t,r)}function y(e,t){const r=(r,n)=>f(e,{...t,...r},n);return r.element=e,r}function C(e,t){const r=(r,n,o)=>f(e,{...t,...n,children:r},o);return r.element=e,r}f.clearCaches=g.clearCaches;export{g as BaseNode,f as Node,C as createChildrenFirstNode,y as createNode};
@@ -122,6 +122,18 @@ export declare class NodeUtil {
122
122
  * @returns The processed children in normalized format.
123
123
  */
124
124
  private static _processChildren;
125
+ /**
126
+ * Determines if a given `NodeInstance` should be cached.
127
+ * Caching is enabled only on the client-side and if the node has both a `stableKey`
128
+ * (indicating it's a stable, identifiable element) and `dependencies` (suggesting its render
129
+ * output might be stable across re-renders if dependencies don't change).
130
+ * @param node The `NodeInstance` to check for cacheability.
131
+ * @returns `true` if the node should be cached, `false` otherwise.
132
+ */
133
+ static shouldCacheElement<E extends NodeInstance>(node: E): node is E & {
134
+ stableKey: string;
135
+ dependencies: DependencyList;
136
+ };
125
137
  /**
126
138
  * Determines if a node should update based on its dependency array.
127
139
  * Uses a shallow comparison, similar to React's `useMemo` and `useCallback`.
@@ -1 +1 @@
1
- {"version":3,"file":"node.util.d.ts","sourceRoot":"","sources":["../../../src/util/node.util.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"node.util.d.ts","sourceRoot":"","sources":["../../../src/util/node.util.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- import e,{isValidElement as t,createElement as r}from"react";import{isReactClassComponent as o,isMemo as s,isForwardRef as n}from"../helper/react-is.helper.js";import{getElementTypeName as i,getCSSProps as c,omitUndefined as a,getDOMProps as l}from"../helper/common.helper.js";import{__DEBUG__ as p}from"../constant/common.const.js";import{BaseNode as d}from"../core.node.js";import{createRoot as u}from"react-dom/client";class h{constructor(){}static isServer="undefined"==typeof window;static _functionSignatureCache=new WeakMap;static CACHE_SIZE_LIMIT=500;static CACHE_CLEANUP_BATCH=50;static _cssCache=new WeakMap;static CRITICAL_PROPS=new Set(["css","className","disableEmotion","props"]);static portalInfrastructure=new WeakMap;static isNodeInstance=e=>"object"==typeof e&&null!==e&&"element"in e&&"function"==typeof e.render&&"function"==typeof e.toPortal&&"isBaseNode"in e;static isStyleProp=h.isServer||"undefined"==typeof document?()=>!1:e=>e in document.body.style;static hashString(e){let t=2166136261,r=5381;for(let o=0;o<e.length;o++){const s=e.charCodeAt(o);t^=s,t=Math.imul(t,16777619),r=33*r^s}return`${(t>>>0).toString(36)}_${(r>>>0).toString(36)}`}static hashCSS(e){const t=this._cssCache.get(e);if(t)return t;const r=Object.keys(e);let o=r.length;for(let t=0;t<Math.min(r.length,10);t++){const s=r[t],n=e[s];o=(o<<5)-o+s.charCodeAt(0),o&=o,"string"==typeof n&&(o=(o<<5)-o+n.length)}const s=o.toString(36);return this._cssCache.set(e,s),s}static createPropSignature(e,t){if(h.isServer)return;const r=i(e),o=Object.keys(t);o.length>1&&o.sort();const s=[`${r}:`];if("function"==typeof e){let t=h._functionSignatureCache.get(e);t||(t=h.hashString(e.toString()),h._functionSignatureCache.set(e,t)),s.push(t)}for(const e of o){const r=t[e];let o;const n=typeof r;if("string"===n||"number"===n||"boolean"===n)o=`${e}:${r};`;else if(null===r)o=`${e}:null;`;else if(void 0===r)o=`${e}:undefined;`;else if("css"===e&&"object"==typeof r)o=`css:${this.hashCSS(r)};`;else if(Array.isArray(r)){const t=r.filter(e=>{const t=typeof e;return"string"===t||"number"===t||"boolean"===t||null===e});o=t.length===r.length?`${e}:[${t.join(",")}];`:`${e}:[${r.length}];`}else if(r&&r.isBaseNode)o=`${e}:${r.stableKey};`;else{o=`${e}:{${Object.keys(r).sort().join(",")}};`}s.push(o)}return h.hashString(s.join(","))}static extractCriticalProps(e,t){const r={_keyCount:t.length};let o=0;for(const s of t){if(o>=50)break;if(h.CRITICAL_PROPS.has(s)){r[s]=e[s],o++;continue}const n=s.charCodeAt(0);111!==n||110!==s.charCodeAt(1)?!(97===n&&114===s.charCodeAt(1)&&105===s.charCodeAt(2)&&97===s.charCodeAt(3)||100===n&&97===s.charCodeAt(1)&&116===s.charCodeAt(2)&&97===s.charCodeAt(3))?t.length<=100&&h.isStyleProp(s)&&(r[s]=e[s],o++):(r[s]=e[s],o++):(r[s]=e[s],o++)}return r}static getCachedCssProps(e,t){if(h.isServer||!t)return{cssProps:c(e)};const r=d.propProcessingCache.get(t);if(r)return r.lastAccess=Date.now(),r.hitCount++,{cssProps:r.cssProps};const o=c(e);return d.propProcessingCache.set(t,{cssProps:o,signature:t,lastAccess:Date.now(),hitCount:1}),d.propProcessingCache.size>h.CACHE_SIZE_LIMIT&&!d.scheduledCleanup&&(d.scheduledCleanup=!0,"undefined"!=typeof requestIdleCallback?requestIdleCallback(()=>{h._evictLRUEntries(),d.scheduledCleanup=!1},{timeout:2e3}):setTimeout(()=>{h._evictLRUEntries(),d.scheduledCleanup=!1},100)),{cssProps:o}}static _evictLRUEntries(){const e=Date.now(),t=new f((e,t)=>t.score-e.score);for(const[r,o]of d.propProcessingCache.entries()){const s=this._calculateEvictionScore(o,e);t.push({key:r,score:s})}for(let e=0;e<h.CACHE_CLEANUP_BATCH;e++){const e=t.pop();if(!e)break;d.propProcessingCache.delete(e.key)}}static _calculateEvictionScore(e,t){return(t-e.lastAccess)/1e3*.3+1e3/(e.hitCount+1)*.7}static processProps(e,t={},r){const{ref:o,key:s,children:n,css:i,props:p={},disableEmotion:d,...u}=t;if(0===Object.keys(u).length&&!i)return a({ref:o,key:s,disableEmotion:d,nativeProps:a(p),children:h._processChildren(n,d)});const f={},m={},y=Object.keys(u);for(let e=0;e<y.length;e++){const t=y[e],r=u[t],o=typeof r;"string"===o||"number"===o||"boolean"===o?f[t]=r:m[t]=r}const C=h.createPropSignature(e,f),{cssProps:b}=h.getCachedCssProps(f,C),g=c(m),E=l(u),P={...b,...g,...i},w=h._processChildren(n,d,r);return a({ref:o,key:s,css:P,...E,disableEmotion:d,nativeProps:a(p),children:w})}static _processChildren(e,t,r){if(e)return"function"==typeof e?e:Array.isArray(e)?1===e.length?h.processRawNode(e[0],t,`${r}_0`):e.map((e,o)=>h.processRawNode(e,t,`${r}_${o}`)):h.processRawNode(e,t,r)}static shouldNodeUpdate(e,t,r){return!!h.isServer||!r&&(void 0===t||(void 0===e||(t.length!==e.length||!!t.some((t,r)=>!Object.is(t,e[r])))))}static processRawNode(r,i,c){if(null==r||"string"==typeof r||"number"==typeof r||"boolean"==typeof r)return r;if(h.isNodeInstance(r)){if(c||i&&!r.rawProps.disableEmotion){const e=new d(r.element,r.rawProps,r.dependencies);return e.stableKey=`${c}:${e.stableKey}`,i&&!e.rawProps.disableEmotion&&(e.rawProps.disableEmotion=!0),e}return r}if(h.isFunctionChild(r))return new d(h.functionRenderer,{props:{render:r,disableEmotion:i}},void 0);if(t(r)){const{style:e,...t}=r.props,o={...t,...e||{}};return new d(r.type,{...o,...null!==r.key&&void 0!==r.key?{key:r.key}:{},disableEmotion:i},void 0)}return o(r)||s(r)||n(r)?new d(r,{disableEmotion:i},void 0):r instanceof e.Component?h.processRawNode(r.render(),i,c):r}static isFunctionChild(e){if("function"!=typeof e||o(e)||s(e)||n(e))return!1;try{return!(e.prototype&&"function"==typeof e.prototype.render)}catch(e){return p&&console.error("MeoNode: Error checking if a node is a function child.",e),!0}}static functionRenderer({render:t,disableEmotion:r}){let o;try{o=t()}catch(e){p&&console.error("MeoNode: Error executing function-as-a-child.",e),o=null}if(null==o)return o;if(h.isNodeInstance(o))return r&&!o.rawProps.disableEmotion?new d(o.element,{...o.rawProps,disableEmotion:!0}).render():o.render();if(Array.isArray(o)){const e=(e,t)=>{try{return`${i(e)}-${t}`}catch(e){return p&&console.error("MeoNode: Could not determine element type name for key in function-as-a-child.",e),`item-${t}`}};return o.map((t,o)=>h.renderProcessedNode({processedElement:h.processRawNode(t,r),passedKey:e(t,o),disableEmotion:r}))}if(o instanceof e.Component)return h.renderProcessedNode({processedElement:h.processRawNode(o.render(),r),disableEmotion:r});if("string"==typeof o||"number"==typeof o||"boolean"==typeof o)return o;const s=h.processRawNode(o,r);return s?h.renderProcessedNode({processedElement:s,disableEmotion:r}):o}static renderProcessedNode({processedElement:t,passedKey:s,disableEmotion:n}){const i={};if(void 0!==s&&(i.key=s),h.isNodeInstance(t)){const e=t.rawProps?.key;return t.rawProps.disableEmotion=n,e===s?t.render():new d(t.element,{...t.rawProps,...i}).render()}return o(t)?new d(t,{...i,disableEmotion:n}).render():t instanceof e.Component?t.render():"function"==typeof t?r(t,{key:s}):t}static ensurePortalInfrastructure(e){if(h.isServer)return!1;let t=h.portalInfrastructure.get(e);if(t?.domElement?.isConnected&&t?.reactRoot)return!0;if(t&&(!t.domElement?.isConnected||!t.reactRoot)){try{t.reactRoot?.unmount?.()}catch(e){p&&console.error("MeoNode: Error unmounting stale portal root.",e)}h.cleanupPortalInfra(t),h.portalInfrastructure.delete(e),t=void 0}const r=document.createElement("div");document.body.appendChild(r);const o=u(r),s={render:o.render.bind(o),unmount:o.unmount.bind(o),update:()=>{}};return t={domElement:r,reactRoot:s},h.portalInfrastructure.set(e,t),d.portalCleanupRegistry.register(e,{domElement:r,reactRoot:s},e),!0}static cleanupPortalInfra(e){try{e.reactRoot?.unmount&&e.reactRoot.unmount()}catch(e){p&&console.error("Portal cleanup error:",e)}try{e.domElement?.isConnected&&e.domElement.remove()}catch(e){p&&console.error("DOM removal error:",e)}}}class f{heap=[];comparator;constructor(e){this.comparator=e}size(){return this.heap.length}isEmpty(){return 0===this.size()}push(e){this.heap.push(e),this.bubbleUp()}pop(){if(this.isEmpty())return;this.swap(0,this.size()-1);const e=this.heap.pop();return this.bubbleDown(),e}bubbleUp(e=this.size()-1){for(;e>0;){const t=Math.floor((e-1)/2);if(this.comparator(this.heap[t],this.heap[e])<=0)break;this.swap(t,e),e=t}}bubbleDown(e=0){const t=this.size()-1;for(;;){const r=2*e+1,o=2*e+2;let s=e;if(r<=t&&this.comparator(this.heap[r],this.heap[s])<0&&(s=r),o<=t&&this.comparator(this.heap[o],this.heap[s])<0&&(s=o),s===e)break;this.swap(e,s),e=s}}swap(e,t){[this.heap[e],this.heap[t]]=[this.heap[t],this.heap[e]]}}export{h as NodeUtil};
1
+ import e,{isValidElement as t,createElement as r}from"react";import{isReactClassComponent as o,isMemo as s,isForwardRef as n}from"../helper/react-is.helper.js";import{getElementTypeName as i,getCSSProps as c,omitUndefined as a,getDOMProps as l}from"../helper/common.helper.js";import{__DEBUG__ as p}from"../constant/common.const.js";import{BaseNode as d}from"../core.node.js";import{createRoot as u}from"react-dom/client";class h{constructor(){}static isServer="undefined"==typeof window;static _functionSignatureCache=new WeakMap;static CACHE_SIZE_LIMIT=500;static CACHE_CLEANUP_BATCH=50;static _cssCache=new WeakMap;static CRITICAL_PROPS=new Set(["css","className","disableEmotion","props"]);static portalInfrastructure=new WeakMap;static isNodeInstance=e=>"object"==typeof e&&null!==e&&"element"in e&&"function"==typeof e.render&&"function"==typeof e.toPortal&&"isBaseNode"in e;static isStyleProp=h.isServer||"undefined"==typeof document?()=>!1:e=>e in document.body.style;static hashString(e){let t=2166136261,r=5381;for(let o=0;o<e.length;o++){const s=e.charCodeAt(o);t^=s,t=Math.imul(t,16777619),r=33*r^s}return`${(t>>>0).toString(36)}_${(r>>>0).toString(36)}`}static hashCSS(e){const t=this._cssCache.get(e);if(t)return t;const r=Object.keys(e);let o=r.length;for(let t=0;t<Math.min(r.length,10);t++){const s=r[t],n=e[s];o=(o<<5)-o+s.charCodeAt(0),o&=o,"string"==typeof n&&(o=(o<<5)-o+n.length)}const s=o.toString(36);return this._cssCache.set(e,s),s}static createPropSignature(e,t){if(h.isServer)return;const r=i(e),o=Object.keys(t);o.length>1&&o.sort();const s=[`${r}:`];if("function"==typeof e){let t=h._functionSignatureCache.get(e);t||(t=h.hashString(e.toString()),h._functionSignatureCache.set(e,t)),s.push(t)}for(const e of o){const r=t[e];let o;const n=typeof r;if("string"===n||"number"===n||"boolean"===n)o=`${e}:${r};`;else if(null===r)o=`${e}:null;`;else if(void 0===r)o=`${e}:undefined;`;else if("css"===e&&"object"==typeof r)o=`css:${this.hashCSS(r)};`;else if(Array.isArray(r)){const t=r.filter(e=>{const t=typeof e;return"string"===t||"number"===t||"boolean"===t||null===e});o=t.length===r.length?`${e}:[${t.join(",")}];`:`${e}:[${r.length}];`}else if(r&&r.isBaseNode)o=`${e}:${r.stableKey};`;else{o=`${e}:{${Object.keys(r).sort().join(",")}};`}s.push(o)}return h.hashString(s.join(","))}static extractCriticalProps(e,t){const r={_keyCount:t.length};let o=0;for(const s of t){if(o>=50)break;if(h.CRITICAL_PROPS.has(s)){r[s]=e[s],o++;continue}const n=s.charCodeAt(0);111!==n||110!==s.charCodeAt(1)?!(97===n&&114===s.charCodeAt(1)&&105===s.charCodeAt(2)&&97===s.charCodeAt(3)||100===n&&97===s.charCodeAt(1)&&116===s.charCodeAt(2)&&97===s.charCodeAt(3))?t.length<=100&&h.isStyleProp(s)&&(r[s]=e[s],o++):(r[s]=e[s],o++):(r[s]=e[s],o++)}return r}static getCachedCssProps(e,t){if(h.isServer||!t)return{cssProps:c(e)};const r=d.propProcessingCache.get(t);if(r)return r.lastAccess=Date.now(),r.hitCount++,{cssProps:r.cssProps};const o=c(e);return d.propProcessingCache.set(t,{cssProps:o,signature:t,lastAccess:Date.now(),hitCount:1}),d.propProcessingCache.size>h.CACHE_SIZE_LIMIT&&!d.scheduledCleanup&&(d.scheduledCleanup=!0,"undefined"!=typeof requestIdleCallback?requestIdleCallback(()=>{h._evictLRUEntries(),d.scheduledCleanup=!1},{timeout:2e3}):setTimeout(()=>{h._evictLRUEntries(),d.scheduledCleanup=!1},100)),{cssProps:o}}static _evictLRUEntries(){const e=Date.now(),t=new f((e,t)=>t.score-e.score);for(const[r,o]of d.propProcessingCache.entries()){const s=this._calculateEvictionScore(o,e);t.push({key:r,score:s})}for(let e=0;e<h.CACHE_CLEANUP_BATCH;e++){const e=t.pop();if(!e)break;d.propProcessingCache.delete(e.key)}}static _calculateEvictionScore(e,t){return(t-e.lastAccess)/1e3*.3+1e3/(e.hitCount+1)*.7}static processProps(e,t={},r){const{ref:o,key:s,children:n,css:i,props:p={},disableEmotion:d,...u}=t;if(0===Object.keys(u).length&&!i)return a({ref:o,key:s,disableEmotion:d,nativeProps:a(p),children:h._processChildren(n,d)});const f={},m={},y=Object.keys(u);for(let e=0;e<y.length;e++){const t=y[e],r=u[t],o=typeof r;"string"===o||"number"===o||"boolean"===o?f[t]=r:m[t]=r}const C=h.createPropSignature(e,f),{cssProps:b}=h.getCachedCssProps(f,C),g=c(m),E=l(u),P={...b,...g,...i},w=h._processChildren(n,d,r);return a({ref:o,key:s,css:P,...E,disableEmotion:d,nativeProps:a(p),children:w})}static _processChildren(e,t,r){if(e)return"function"==typeof e?e:Array.isArray(e)?1===e.length?h.processRawNode(e[0],t,`${r}_0`):e.map((e,o)=>h.processRawNode(e,t,`${r}_${o}`)):h.processRawNode(e,t,r)}static shouldCacheElement(e){return!h.isServer&&!!e.stableKey&&!!e.dependencies}static shouldNodeUpdate(e,t,r){return!!h.isServer||!r&&(void 0===t||(void 0===e||(t.length!==e.length||!!t.some((t,r)=>!Object.is(t,e[r])))))}static processRawNode(r,i,c){if(null==r||"string"==typeof r||"number"==typeof r||"boolean"==typeof r)return r;if(h.isNodeInstance(r)){if(c||i&&!r.rawProps.disableEmotion){const e=new d(r.element,r.rawProps,r.dependencies);return e.stableKey=`${c}:${e.stableKey}`,i&&!e.rawProps.disableEmotion&&(e.rawProps.disableEmotion=!0),e}return r}if(h.isFunctionChild(r))return new d(h.functionRenderer,{props:{render:r,disableEmotion:i}},void 0);if(t(r)){const{style:e,...t}=r.props,o={...t,...e||{}};return new d(r.type,{...o,...null!==r.key&&void 0!==r.key?{key:r.key}:{},disableEmotion:i},void 0)}return o(r)||s(r)||n(r)?new d(r,{disableEmotion:i},void 0):r instanceof e.Component?h.processRawNode(r.render(),i,c):r}static isFunctionChild(e){if("function"!=typeof e||o(e)||s(e)||n(e))return!1;try{return!(e.prototype&&"function"==typeof e.prototype.render)}catch(e){return p&&console.error("MeoNode: Error checking if a node is a function child.",e),!0}}static functionRenderer({render:t,disableEmotion:r}){let o;try{o=t()}catch(e){p&&console.error("MeoNode: Error executing function-as-a-child.",e),o=null}if(null==o)return o;if(h.isNodeInstance(o))return r&&!o.rawProps.disableEmotion?new d(o.element,{...o.rawProps,disableEmotion:!0}).render():o.render();if(Array.isArray(o)){const e=(e,t)=>{try{return`${i(e)}-${t}`}catch(e){return p&&console.error("MeoNode: Could not determine element type name for key in function-as-a-child.",e),`item-${t}`}};return o.map((t,o)=>h.renderProcessedNode({processedElement:h.processRawNode(t,r),passedKey:e(t,o),disableEmotion:r}))}if(o instanceof e.Component)return h.renderProcessedNode({processedElement:h.processRawNode(o.render(),r),disableEmotion:r});if("string"==typeof o||"number"==typeof o||"boolean"==typeof o)return o;const s=h.processRawNode(o,r);return s?h.renderProcessedNode({processedElement:s,disableEmotion:r}):o}static renderProcessedNode({processedElement:t,passedKey:s,disableEmotion:n}){const i={};if(void 0!==s&&(i.key=s),h.isNodeInstance(t)){const e=t.rawProps?.key;return t.rawProps.disableEmotion=n,e===s?t.render():new d(t.element,{...t.rawProps,...i}).render()}return o(t)?new d(t,{...i,disableEmotion:n}).render():t instanceof e.Component?t.render():"function"==typeof t?r(t,{key:s}):t}static ensurePortalInfrastructure(e){if(h.isServer)return!1;let t=h.portalInfrastructure.get(e);if(t?.domElement?.isConnected&&t?.reactRoot)return!0;if(t&&(!t.domElement?.isConnected||!t.reactRoot)){try{t.reactRoot?.unmount?.()}catch(e){p&&console.error("MeoNode: Error unmounting stale portal root.",e)}h.cleanupPortalInfra(t),h.portalInfrastructure.delete(e),t=void 0}const r=document.createElement("div");document.body.appendChild(r);const o=u(r),s={render:o.render.bind(o),unmount:o.unmount.bind(o),update:()=>{}};return t={domElement:r,reactRoot:s},h.portalInfrastructure.set(e,t),d.portalCleanupRegistry.register(e,{domElement:r,reactRoot:s},e),!0}static cleanupPortalInfra(e){try{e.reactRoot?.unmount&&e.reactRoot.unmount()}catch(e){p&&console.error("Portal cleanup error:",e)}try{e.domElement?.isConnected&&e.domElement.remove()}catch(e){p&&console.error("DOM removal error:",e)}}}class f{heap=[];comparator;constructor(e){this.comparator=e}size(){return this.heap.length}isEmpty(){return 0===this.size()}push(e){this.heap.push(e),this.bubbleUp()}pop(){if(this.isEmpty())return;this.swap(0,this.size()-1);const e=this.heap.pop();return this.bubbleDown(),e}bubbleUp(e=this.size()-1){for(;e>0;){const t=Math.floor((e-1)/2);if(this.comparator(this.heap[t],this.heap[e])<=0)break;this.swap(t,e),e=t}}bubbleDown(e=0){const t=this.size()-1;for(;;){const r=2*e+1,o=2*e+2;let s=e;if(r<=t&&this.comparator(this.heap[r],this.heap[s])<0&&(s=r),o<=t&&this.comparator(this.heap[o],this.heap[s])<0&&(s=o),s===e)break;this.swap(e,s),e=s}}swap(e,t){[this.heap[e],this.heap[t]]=[this.heap[t],this.heap[e]]}}export{h as NodeUtil};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@meonode/ui",
3
3
  "description": "A structured approach to component composition, direct CSS-first prop styling, built-in theming, smart prop handling (including raw property pass-through), and dynamic children.",
4
- "version": "0.4.12",
4
+ "version": "0.4.14",
5
5
  "type": "module",
6
6
  "main": "./dist/main.js",
7
7
  "types": "./dist/main.d.ts",