@meonode/ui 0.4.14 → 1.0.0

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.
Files changed (39) hide show
  1. package/CHANGELOG.md +52 -2
  2. package/README.md +233 -87
  3. package/dist/cjs/components/meonode-unmounter.client.js +1 -1
  4. package/dist/cjs/components/theme-provider.client.js +1 -1
  5. package/dist/cjs/core.node.js +1 -1
  6. package/dist/cjs/helper/common.helper.js +1 -1
  7. package/dist/cjs/util/mount-tracker.util.js +1 -1
  8. package/dist/cjs/util/navigation-cache-manager.util.js +1 -1
  9. package/dist/cjs/util/node.util.js +1 -1
  10. package/dist/cjs/util/theme.util.js +1 -1
  11. package/dist/esm/components/meonode-unmounter.client.d.ts.map +1 -1
  12. package/dist/esm/components/meonode-unmounter.client.js +1 -1
  13. package/dist/esm/components/theme-provider.client.d.ts +1 -2
  14. package/dist/esm/components/theme-provider.client.d.ts.map +1 -1
  15. package/dist/esm/components/theme-provider.client.js +1 -1
  16. package/dist/esm/core.node.d.ts +8 -10
  17. package/dist/esm/core.node.d.ts.map +1 -1
  18. package/dist/esm/core.node.js +1 -1
  19. package/dist/esm/helper/common.helper.d.ts +9 -0
  20. package/dist/esm/helper/common.helper.d.ts.map +1 -1
  21. package/dist/esm/helper/common.helper.js +1 -1
  22. package/dist/esm/types/node.type.d.ts +2 -9
  23. package/dist/esm/types/node.type.d.ts.map +1 -1
  24. package/dist/esm/util/mount-tracker.util.d.ts +9 -5
  25. package/dist/esm/util/mount-tracker.util.d.ts.map +1 -1
  26. package/dist/esm/util/mount-tracker.util.js +1 -1
  27. package/dist/esm/util/navigation-cache-manager.util.d.ts.map +1 -1
  28. package/dist/esm/util/navigation-cache-manager.util.js +1 -1
  29. package/dist/esm/util/node.util.d.ts +15 -32
  30. package/dist/esm/util/node.util.d.ts.map +1 -1
  31. package/dist/esm/util/node.util.js +1 -1
  32. package/dist/esm/util/theme.util.d.ts +0 -2
  33. package/dist/esm/util/theme.util.d.ts.map +1 -1
  34. package/dist/esm/util/theme.util.js +1 -1
  35. package/package.json +7 -3
  36. package/dist/cjs/helper/obj.helper.js +0 -1
  37. package/dist/esm/helper/obj.helper.d.ts +0 -16
  38. package/dist/esm/helper/obj.helper.d.ts.map +0 -1
  39. package/dist/esm/helper/obj.helper.js +0 -1
package/CHANGELOG.md CHANGED
@@ -2,12 +2,62 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [1.0.0] - 2025-11-28
6
+
7
+ ### Perf
8
+
9
+ - **cache**: Remove props, CSS, and theme caching to improve performance and reduce overhead. ([`206361d`](https://github.com/l7aromeo/meonode-ui/commit/206361d)), ([`d7baa16`](https://github.com/l7aromeo/meonode-ui/commit/d7baa16))
10
+
11
+ ### Fix
12
+
13
+ - **theme-provider**: Allow `setTheme` to accept an updater function for more flexible state management. ([`be8d261`](https://github.com/l7aromeo/meonode-ui/commit/be8d261))
14
+ - **core**: Improve mount tracking for cached elements by ensuring `MeoNodeUnmounter` wraps all renderable nodes. ([`d0ca27e`](https://github.com/l7aromeo/meonode-ui/commit/d0ca27e))
15
+ - **theme-provider**: Remove incorrect `@private` JSDoc tag from `ThemeProvider` component. ([`816e398`](https://github.com/l7aromeo/meonode-ui/commit/816e398))
16
+
17
+ ### Test
18
+
19
+ - **performance**: Add controlled input performance tests to simulate human typing and measure `deps` memoization effectiveness. ([`bba48b8`](https://github.com/l7aromeo/meonode-ui/commit/bba48b8))
20
+
21
+ ### Docs
22
+
23
+ - **readme**: Update `README.md` to reflect the removal of automatic caching and emphasize `deps`-based memoization. ([`2600d9c`](https://github.com/l7aromeo/meonode-ui/commit/2600d9c))
24
+
25
+ ## [1.0.0-0] - 2025-11-27
26
+
27
+ ### Fix
28
+
29
+ - **core**: Overhaul mount tracking, caching, and fix stableKey generation to prevent memory leaks ([`af1b707`](https://github.com/l7aromeo/meonode-ui/commit/af1b707187b66cdbf9fe88f791aee30cfc7d2835))
30
+ - Replaced the simple `Set` in `MountTrackerUtil` with a reference-counting system (`Map`) to ensure a node is only considered unmounted when all its instances are gone.
31
+ - The root element of a render cycle is now wrapped with a `MeoNodeUnmounter` component before being cached to guarantee that the unmount logic is always present, even for cached elements.
32
+ - Improved `stableKey` generation in `NodeUtil.createPropSignature` to correctly differentiate function props by hashing their string representation, preventing cache collisions for components with different `onClick` or similar handlers.
33
+ - Added new test suites (`leak-repro.test.ts`, `props-caching-leak.test.ts`) to specifically target and verify the leak fixes.
34
+
35
+ ### Perf
36
+
37
+ - **cache**: Improve props cache eviction strategy ([`ce2f561`](https://github.com/l7aromeo/meonode-ui/commit/ce2f5616b21d68873dff0f1c4466bf9a2a40ce4d))
38
+ - Adjusted the `propProcessingCache` eviction logic in `NodeUtil` to be more aggressive, removing enough items to get back to the `CACHE_SIZE_LIMIT` plus an additional buffer batch, preventing unbounded growth under high load.
39
+
40
+ ### Feat
41
+
42
+ - **deps**: Add react-router-dom and test polyfills ([`29dcf13`](https://github.com/l7aromeo/meonode-ui/commit/29dcf137b5ebcba0e09e5acf13aadac6a0a0f513))
43
+ - Introduced `react-router-dom` as a new development dependency to enable integration testing with React Router.
44
+ - Added `whatwg-fetch` and Node.js `util` polyfills to `jest.setup.ts` for compatibility in the Jest environment.
45
+
46
+ ### Test
47
+
48
+ - **react-router**: Add integration tests for react-router-dom ([`8478623`](https://github.com/l7aromeo/meonode-ui/commit/8478623add6bc66b9805a3ec9c0661f4df223f63))
49
+ - Introduced a new test suite to verify the proper functioning and caching behavior of MeoNode components when used within a React Router environment.
50
+ - Includes tests for declarative and programmatic navigation, ensuring that component lifecycles and caching mechanisms interact correctly with React Router's dynamic rendering.
51
+
52
+ ### Chore
53
+ - **package**: Rename publish:pre script to publish:prerelease and add publish:premajor script in package.json ([`a98ba69`](https://github.com/l7aromeo/meonode-ui/commit/a98ba697a6e024126256a0e2517c839bbecd8058))
54
+
5
55
  ## [0.4.14] - 2025-11-23
6
56
 
7
57
  ### Perf
8
58
 
9
59
  - **cache**: enforce dependency-based caching with shouldCacheElement helper ([
10
- `0df9b3b`](https://github.com/l7aromeo/meonode-ui/commit/0df9b3b28c7874acbf33826ab7bb17f8b0464250))
60
+ `fab5525`](https://github.com/l7aromeo/meonode-ui/commit/fab55253093fbd2958ad84bcc98b1f0d1a07349c))
11
61
  - Introduces NodeUtil.shouldCacheElement() helper to centralize and enforce the opt-in caching strategy where only
12
62
  nodes with explicit dependencies are cached
13
63
  - Completes the memory optimization by closing loopholes where nodes without dependencies were still being cached
@@ -27,7 +77,7 @@ All notable changes to this project will be documented in this file.
27
77
 
28
78
  ### Chore
29
79
 
30
- - **type**: remove src/types/env.d.ts as it is no longer needed
80
+ - **type**: remove src/types/env.d.ts as it is no longer needed ([aab4299](https://github.com/l7aromeo/meonode-ui/commit/aab429944bf12269d5e6116d3460ff354a42f673))
31
81
 
32
82
  ## [0.4.13] - 2025-11-23
33
83
 
package/README.md CHANGED
@@ -4,75 +4,261 @@
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
5
  [![Bundle Size](https://img.shields.io/bundlephobia/minzip/@meonode/ui)](https://bundlephobia.com/package/@meonode/ui)
6
6
 
7
- **Build React UIs with Type-Safe Fluency Without JSX Syntax**
7
+ **Type-safe React components without JSX**
8
8
 
9
- A revolutionary approach to React component composition featuring function-based syntax, direct CSS-first prop styling, built-in theming system, and powerful portal capabilities.
9
+ A production-ready component library that replaces JSX with function-based composition, featuring direct CSS prop
10
+ styling, context-based theming, automatic memoization, and full React Server Components support—powered by
11
+ @emotion/react.
10
12
 
11
- ## Quick Start
13
+ ## Core Concept
14
+
15
+ MeoNode UI eliminates JSX while maintaining full React compatibility through functional composition. Style components
16
+ with CSS properties as props, leverage automatic theme resolution via React Context, and benefit from intelligent
17
+ caching without manual optimization.
18
+
19
+ **JSX Pattern:**
20
+
21
+ ```tsx
22
+ <div style={{ padding: '20px', borderRadius: '12px' }}>
23
+ <h2 style={{ fontSize: '1.5rem', marginBottom: '8px' }}>{title}</h2>
24
+ {children}
25
+ </div>
26
+ ```
12
27
 
13
- ```bash
14
- npm install @meonode/ui react
28
+ **MeoNode Pattern:**
29
+
30
+ ```typescript
31
+ Div({
32
+ padding: '20px',
33
+ borderRadius: '12px',
34
+ backgroundColor: 'theme.primary',
35
+ children: [H2(title, { fontSize: '1.5rem', marginBottom: '8px' }), ...children],
36
+ })
15
37
  ```
16
38
 
39
+ ## Features
40
+
41
+ ### Function-Based Composition
42
+
43
+ Plain JavaScript functions replace JSX—no build transforms, no syntax extensions. Compose UIs as first-class function
44
+ trees with full TypeScript inference.
45
+
46
+ ### Direct CSS-in-Props
47
+
48
+ Pass CSS properties directly to components. No separate styled-components declarations, no className juggling. All valid
49
+ CSS properties work as props with full type safety.
50
+
51
+ ```typescript
52
+ Button('Submit', {
53
+ padding: '12px 24px',
54
+ backgroundColor: 'theme.primary',
55
+ borderRadius: 8,
56
+ transition: 'all 0.2s ease',
57
+ css: {
58
+ ':hover': { transform: 'scale(1.05)' },
59
+ },
60
+ })
61
+ ```
62
+
63
+ ### Context-Based Theming
64
+
65
+ Theme values resolve automatically through React Context. Reference semantic tokens anywhere without prop drilling.
66
+ Supports nested themes and dynamic switching.
67
+
17
68
  ```typescript
18
- import {
19
- Component,
20
- ThemeProvider,
21
- Div,
22
- Center,
23
- Column,
24
- H1,
25
- Button,
26
- } from "@meonode/ui";
69
+ ThemeProvider({
70
+ theme: {
71
+ mode: 'dark',
72
+ system: {
73
+ primary: { default: '#FF6B6B', content: '#4A0000' },
74
+ spacing: { sm: 8, md: 16, lg: 24 },
75
+ },
76
+ },
77
+ children: [
78
+ /* your app */
79
+ ],
80
+ })
81
+ ```
82
+
83
+ ### Surgical Memoization
84
+
85
+ Memoize at node-level granularity—not just entire components. Control re-renders with precision by specifying dependency
86
+ arrays directly on individual nodes.
87
+
88
+ **Node-Level Memoization:**
89
+
90
+ ```typescript
91
+ const UserCard = ({ user }) =>
92
+ Div(
93
+ {
94
+ padding: 16,
95
+ children: [
96
+ H2(user.name), // Re-renders on any prop change
97
+ Text(user.bio),
98
+ ],
99
+ },
100
+ [user.id],
101
+ ).render() // Only re-render when user.id changes
102
+ ```
103
+
104
+ **Component-Level Memoization:**
105
+
106
+ ```typescript
107
+ Node(ExpensiveComponent, { data }, [data.id]).render()
108
+ ```
109
+
110
+ ### React Server Components Compatible
111
+
112
+ Full RSC support with proper client/server component boundaries. Use in Next.js App Router, Remix, or any RSC-enabled
113
+ environment without configuration.
114
+
115
+ ### Emotion-Powered Styling
116
+
117
+ Built on @emotion/react for:
118
+
119
+ - Automatic critical CSS extraction
120
+ - Vendor prefixing
121
+ - Dead code elimination
122
+ - Server-side rendering support
123
+ - Zero-runtime overhead in production
124
+
125
+ ### Smart Prop Differentiation
126
+
127
+ Automatically separates style props from DOM attributes. Pass `onClick`, `aria-*`, `data-*` alongside CSS props—MeoNode
128
+ routes them correctly.
129
+
130
+ ```typescript
131
+ Button('Click Me', {
132
+ padding: '12px', // → style
133
+ color: 'theme.primary', // → style
134
+ onClick: handleClick, // → DOM attribute
135
+ 'aria-label': 'Submit', // → DOM attribute
136
+ disabled: isLoading, // → DOM attribute
137
+ })
138
+ ```
139
+
140
+ ## Performance Benchmarks
141
+
142
+ MeoNode is built for high-performance applications, featuring an optimized caching system and iterative rendering
143
+ engine.
144
+
145
+ ### Layout Rendering
146
+
147
+ | Metric | Value | Description |
148
+ |:------------------------|:--------|:----------------------------------------------------|
149
+ | **Single-Page Layout** | ~9ms | Full SPA layout with header, hero, features, etc. |
150
+ | **10,000 Flat Nodes** | ~304ms | Rendering 10k nodes at the same level |
151
+ | **10,000 Nested Nodes** | ~1604ms | Deeply nested structure (single parent-child chain) |
152
+
153
+ ### Memory Management
154
+
155
+ | Metric | Value | Description |
156
+ |:---------------------------|:-------------|:-------------------------------------------------|
157
+ | **Navigation Memory Leak** | **-7.24 MB** | Memory is efficiently reclaimed after navigation |
158
+ | **Mount/Unmount Cycles** | Stable | No leaks detected over 200 cycles |
159
+ | **State Updates** | Efficient | Handles heavy state changes without bloating |
160
+
161
+ ### Form Input Performance
162
+
163
+ | Metric | Value | Description |
164
+ |:----------------------|:------------|:------------------------------------------------|
165
+ | **Avg Response Time** | **2.54 ms** | 100 controlled inputs with simulated typing |
166
+ | **Max Response Time** | 4.09 ms | Worst-case scenario remains instant |
167
+ | **Optimization** | `deps` | Granular updates prevent unnecessary re-renders |
168
+
169
+ ### React Comparison (10k Flat Nodes)
170
+
171
+ | Implementation | Time (ms) | Initial Mem |
172
+ |:------------------------|:----------|:------------|
173
+ | **React.createElement** | ~90ms | ~230 MB |
174
+ | **MeoNode** | ~186ms | ~344 MB |
175
+
176
+ > **Note**: While slightly slower in raw micro-benchmarks due to the feature-rich object syntax, MeoNode excels in
177
+ > real-world scenarios with its intelligent caching and memory management.
178
+
179
+ ## Quick Start
180
+
181
+ ```typescript
182
+ import { ThemeProvider, Center, Column, H1, Button, Text } from '@meonode/ui'
27
183
 
28
184
  const theme = {
29
- mode: "light",
185
+ mode: 'light',
30
186
  system: {
31
- primary: { default: '#FF6B6B', content: '#4A0000' },
187
+ primary: { default: '#FF6B6B', content: '#FFFFFF' },
32
188
  base: { default: '#F8F8F8', content: '#333333' },
33
- }
34
- };
189
+ },
190
+ }
35
191
 
36
- const App = Component(() =>
192
+ const App = () =>
37
193
  ThemeProvider({
38
194
  theme,
39
- children: Div({
40
- backgroundColor: "theme.base.default",
41
- children: Center({
195
+ children: [
196
+ Center({
42
197
  padding: 40,
198
+ backgroundColor: 'theme.base',
43
199
  children: Column({
44
200
  gap: 24,
45
- textAlign: "center",
46
201
  children: [
47
- H1("Welcome to MeoNode", {
48
- fontSize: "3rem",
49
- color: "theme.primary.default",
202
+ H1('MeoNode UI', {
203
+ fontSize: '3rem',
204
+ color: 'theme.primary',
205
+ }),
206
+ Text('Type-safe React without JSX', {
207
+ fontSize: '1.2rem',
208
+ color: 'theme.base.content',
50
209
  }),
51
- Button("Get Started", {
52
- backgroundColor: "theme.primary.default",
53
- color: "theme.primary.content",
54
- padding: "12px 24px",
210
+ Button('Get Started', {
211
+ backgroundColor: 'theme.primary',
212
+ color: 'theme.primary.content',
213
+ padding: '12px 24px',
55
214
  borderRadius: 8,
56
- cursor: "pointer",
57
- onClick: () => alert("Hello MeoNode!"),
215
+ cursor: 'pointer',
216
+ onClick: () => console.log('Started!'),
58
217
  }),
59
218
  ],
60
219
  }),
61
220
  }),
62
- }),
63
- })
64
- );
221
+ ],
222
+ }).render()
65
223
  ```
66
224
 
67
- ## Key Features
225
+ ## Architecture
226
+
227
+ **Component Factory System**
228
+ `Node` factory + `Component` wrapper + semantic elements (Div, Button, etc.) enable both rapid prototyping and
229
+ sophisticated component architectures.
230
+
231
+ **Theme Resolution Engine**
232
+ Context-based theme propagation with automatic value resolution. Nested theme objects inherit and override parent values
233
+ without explicit passing.
234
+
235
+ **CSS Engine**
236
+ @emotion/react provides CSS-in-JS with automatic optimization, critical CSS extraction for SSR, and zero-runtime
237
+ overhead in production builds.
238
+
239
+ ## Why MeoNode UI?
240
+
241
+ **For Teams Building Design Systems:**
242
+
243
+ - Context-based theme propagation
244
+ - Semantic token system ensures visual consistency
245
+ - Component composition patterns scale naturally
246
+ - Full TypeScript support catches design token errors
247
+
248
+ **For Performance-Critical Applications:**
68
249
 
69
- - **Function-based components** - No JSX required, pure TypeScript functions
70
- - **Built-in Theming System** - Use `ThemeProvider` to propagate theme through your app.
71
- - **Theme-aware styling** - Direct CSS props with automatic theme resolution
72
- - **Advanced CSS support** - Pseudo-classes, media queries, animations via `css` prop
73
- - **Portal system** - Context-aware modals and overlays
74
- - **TypeScript first** - Full type safety with intelligent autocomplete
75
- - **Performance optimized** - Powered by @emotion/react
250
+ - Emotion's CSS optimization and caching
251
+ - Surgical memoization at node granularity
252
+ - SSR-ready with critical CSS extraction
253
+ - RSC compatibility for modern React architectures
254
+
255
+ **For Developer Productivity:**
256
+
257
+ - No JSX compilation overhead
258
+ - Direct CSS-in-props reduces context switching
259
+ - Intelligent prop routing (style vs DOM attributes)
260
+ - Full autocomplete for all CSS properties
261
+ - Composable function trees with first-class JavaScript
76
262
 
77
263
  ## Documentation
78
264
 
@@ -80,51 +266,10 @@ const App = Component(() =>
80
266
 
81
267
  🎮 **[Interactive Playground](https://codesandbox.io/p/github/l7aromeo/nextjs-meonode/main?import=true)**
82
268
 
83
- ## Core API
84
-
85
- ```typescript
86
- // Create reusable components
87
- const Card = Component<{ title: string }>(({ title }) =>
88
- Div({
89
- padding: '20px',
90
- borderRadius: '8px',
91
- backgroundColor: 'white',
92
- children: H2(title)
93
- })
94
- );
95
-
96
- // Advanced styling with css prop
97
- const AnimatedBox = Div({
98
- padding: '20px',
99
- css: {
100
- '&:hover': { transform: 'scale(1.05)' },
101
- '@media (max-width: 768px)': { padding: '12px' }
102
- }
103
- });
104
-
105
- // Portal for modals/overlays
106
- const Modal = Portal(({ portal, message }) =>
107
- Center({
108
- position: 'fixed',
109
- top: 0, left: 0, right: 0, bottom: 0,
110
- backgroundColor: 'rgba(0,0,0,0.5)',
111
- onClick: portal.unmount,
112
- children: Div({
113
- backgroundColor: 'white',
114
- padding: '24px',
115
- borderRadius: '12px',
116
- children: [
117
- Text(message),
118
- Button('Close', { onClick: portal.unmount })
119
- ]
120
- })
121
- })
122
- );
123
- ```
124
-
125
269
  ## Contributing
126
270
 
127
- We welcome contributions! Please see our [contributing guidelines](https://github.com/l7aromeo/meonode-ui/blob/main/CONTRIBUTING.md).
271
+ We welcome contributions! Please see
272
+ our [contributing guidelines](https://github.com/l7aromeo/meonode-ui/blob/main/CONTRIBUTING.md).
128
273
 
129
274
  ## License
130
275
 
@@ -132,4 +277,5 @@ MIT © [Ukasyah Rahmatullah Zada](https://github.com/l7aromeo)
132
277
 
133
278
  ---
134
279
 
135
- **[📖 Full Documentation](https://ui.meonode.com)** • **[🐛 Issues](https://github.com/l7aromeo/meonode-ui/issues)** • **[💬 Discussions](https://github.com/l7aromeo/meonode-ui/discussions)**
280
+ **[📖 Full Documentation](https://ui.meonode.com)** • **[🐛 Issues](https://github.com/l7aromeo/meonode-ui/issues)** • *
281
+ *[💬 Discussions](https://github.com/l7aromeo/meonode-ui/discussions)**
@@ -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({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};
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,...a}){const{node:l,...s}=a,u=e.useEffectEvent(()=>{l.stableKey&&(r.BaseNode.elementCache.delete(l.stableKey),t.MountTrackerUtil.isMounted(l.stableKey)&&t.MountTrackerUtil.untrackMount(l.stableKey),r.BaseNode.cacheCleanupRegistry.unregister(l)),l.lastSignature=void 0});return e.useEffect(()=>(l.stableKey&&t.MountTrackerUtil.trackMount(l.stableKey),()=>u()),[]),e.isValidElement(n)&&Object.keys(s).length>0?e.cloneElement(n,s):n};
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),t=require("../core.node.js");const r=e.createContext(null);exports.ThemeContext=r,exports.default=function({children:o,theme:n}){const[c,d]=e.useState(n);if(!n)throw new Error("`theme` prop must be defined");const s={theme:c,setTheme:e=>{document.cookie=`theme=${e.mode}; path=/;`,d(e)}};return t.Node(r.Provider,{value:s,children:o}).render()};
2
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),t=require("../core.node.js");const r=e.createContext(null);exports.ThemeContext=r,exports.default=function({children:o,theme:n}){const[c,u]=e.useState(n);if(!n)throw new Error("`theme` prop must be defined");const d={theme:c,setTheme:e=>{"function"==typeof e&&(e=e(c)),document.cookie=`theme=${e.mode}; path=/;`,u(e)}};return t.Node(r.Provider,{value:d,children:o}).render()};
@@ -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.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
+ "use strict";var e=require("react"),t=require("./helper/react-is.helper.js"),n=require("./helper/common.helper.js"),r=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");const c=Symbol.for("@meonode/ui/BaseNode/elementCache"),d=Symbol.for("@meonode/ui/BaseNode/navigationStarted"),u=Symbol.for("@meonode/ui/BaseNode/renderContextPool"),h=Symbol.for("@meonode/ui/BaseNode/cacheCleanupRegistry"),p=Symbol.for("@meonode/ui/BaseNode/portalCleanupRegistry");class m{instanceId=Math.random().toString(36).slice(2)+Date.now().toString(36);element;rawProps={};isBaseNode=!0;_props;_deps;stableKey;lastPropsObj;lastSignature;static get elementCache(){return n.getGlobalState(c,()=>new Map)}static get _navigationStarted(){return n.getGlobalState(d,()=>({value:!1})).value}static set _navigationStarted(e){n.getGlobalState(d,()=>({value:!1})).value=e}static get renderContextPool(){return n.getGlobalState(u,()=>[])}static acquireRenderContext(){const e=m.renderContextPool;return e.length>0?e.pop():{workStack:new Array(512),renderedElements:new Map}}static releaseRenderContext(e){m.renderContextPool.length<50&&e.workStack.length<2048&&(e.workStack.length=0,e.renderedElements.clear(),m.renderContextPool.push(e))}constructor(e,r={},o){if(!t.isValidElementType(e)){const t=n.getComponentType(e);throw new Error(`Invalid element type: ${t} provided!`)}this.element=e,this.rawProps=r,this._deps=o;const{ref:s,children:a,...c}=r;this.stableKey=this._getStableKey(c),i.NodeUtil.isServer||m._navigationStarted||(l.NavigationCacheManagerUtil.getInstance().start(),m._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 r=Object.keys(t),s=r.length;if(s>100){const e=i.NodeUtil.extractCriticalProps(t,r);this.lastSignature=i.NodeUtil.createPropSignature(this.element,e),o.__DEBUG__&&s>200&&console.warn(`MeoNode: Large props (${s} keys) on "${n.getElementTypeName(this.element)}". Consider splitting.`)}else this.lastSignature=i.NodeUtil.createPropSignature(this.element,t);return null!=e?`${String(e)}:${this.lastSignature}`:this.lastSignature}static get cacheCleanupRegistry(){return n.getGlobalState(h,()=>new FinalizationRegistry(e=>{const{cacheKey:t,instanceId:n}=e,r=m.elementCache.get(t);r?.instanceId===n&&m.elementCache.delete(t),s.MountTrackerUtil.isMounted(t)&&s.MountTrackerUtil.untrackMount(t)}))}static get portalCleanupRegistry(){return n.getGlobalState(p,()=>new FinalizationRegistry(e=>{const{domElement:t,reactRoot:n}=e;o.__DEBUG__&&console.log("[MeoNode] FinalizationRegistry auto-cleaning portal");try{n&&"function"==typeof n.unmount&&n.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){const s=i.NodeUtil.shouldCacheElement(this)?m.elementCache.get(this.stableKey):void 0,l=i.NodeUtil.shouldNodeUpdate(s?.prevDeps,this._deps,o);if(!l&&s?.renderedElement)return s.accessCount+=1,s.renderedElement;const c=!l,d=m.acquireRenderContext();let{workStack:u}=d;const{renderedElements:h}=d;let p=0;try{const o=e=>{if(e>u.length){const t=Math.max(e,u.length<<1),n=new Array(t);for(let e=0;e<p;e++)n[e]=u[e];u=n}};for(u[p++]={node:this,isProcessed:!1,blocked:c};p>0;){const s=u[p-1];if(!s){p--;continue}const{node:a,isProcessed:l,blocked:c}=s;if(l){p--;const{children:o,key:s,css:l,nativeProps:c,disableEmotion:d,...u}=a.props;let g=[];if(o){const t=Array.isArray(o)?o:[o],n=t.length;g=new Array(n);for(let r=0;r<n;r++){const n=t[r];if(i.NodeUtil.isNodeInstance(n)){const e=h.get(n);if(!e)throw new Error(`[MeoNode] Missing rendered element for child node: ${n.stableKey}`);g[r]=e}else e.isValidElement(n),g[r]=n}}const _={...u,key:s,...c};let y;if(a.element===e.Fragment||t.isFragment(a.element))y=e.createElement(a.element,{key:s},...g);else{y=!d&&(l||!n.hasNoStyleTag(a.element))?e.createElement(r.default,{element:a.element,..._,css:l,suppressHydrationWarning:!0},...g):e.createElement(a.element,_,...g)}if(a!==this&&i.NodeUtil.shouldCacheElement(a)){const e=m.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};m.elementCache.set(a.stableKey,e),m.cacheCleanupRegistry.register(a,{cacheKey:a.stableKey,instanceId:a.instanceId},a)}}h.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(p+t.length);for(let e=t.length-1;e>=0;e--){const n=t[e],r=i.NodeUtil.shouldCacheElement(n)?m.elementCache.get(n.stableKey):void 0,o=i.NodeUtil.shouldNodeUpdate(r?.prevDeps,n._deps,c);if(!o&&r?.renderedElement){h.set(n,r.renderedElement);continue}const s=c||!o;u[p++]={node:n,isProcessed:!1,blocked:s}}}}}let s=h.get(this);if(!i.NodeUtil.isServer&&this.stableKey&&(s=e.createElement(a.default,{node:this},s)),i.NodeUtil.shouldCacheElement(this)){const e=m.elementCache.get(this.stableKey);if(e)e.prevDeps=this._deps,e.renderedElement=s,e.accessCount+=1;else{const e={prevDeps:this._deps,renderedElement:s,nodeRef:new WeakRef(this),createdAt:Date.now(),accessCount:1,instanceId:this.instanceId};m.elementCache.set(this.stableKey,e),m.cacheCleanupRegistry.register(this,{cacheKey:this.stableKey,instanceId:this.instanceId},this)}}return s}finally{for(let e=0;e<p;e++)u[e]=null;m.releaseRenderContext({workStack:u,renderedElements:h})}}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:n}=e;(()=>{try{n.render(this.render())}catch(e){o.__DEBUG__&&console.error("[MeoNode] Portal render error:",e)}})();let r=!1;const s=n.unmount.bind(n);return n.update=e=>{if(r)o.__DEBUG__&&console.warn("[MeoNode] Attempt to update already-unmounted portal");else try{const t=i.NodeUtil.isNodeInstance(e)?e.render():e;n.render(t)}catch(e){o.__DEBUG__&&console.error("[MeoNode] Portal update error:",e)}},n.unmount=()=>{if(r)o.__DEBUG__&&console.warn("[MeoNode] Portal already unmounted");else{r=!0;try{m.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)}}},n}static clearCaches(){const e=Array.from(m.elementCache.keys());o.__DEBUG__&&console.log(`[MeoNode] clearCaches: Clearing ${e.length} entries`);for(const t of e){const e=m.elementCache.get(t);if(e){const n=e.nodeRef?.deref();if(n)try{m.cacheCleanupRegistry.unregister(n),n.lastSignature=void 0,n.lastPropsObj=void 0}catch{o.__DEBUG__&&console.warn(`[MeoNode] Could not unregister ${t} from FinalizationRegistry`)}}}m.elementCache.clear(),s.MountTrackerUtil.cleanup(),o.__DEBUG__&&console.log("[MeoNode] All caches cleared")}}function g(e,t={},n){return new m(e,t,n)}g.clearCaches=m.clearCaches,exports.BaseNode=m,exports.Node=g,exports.createChildrenFirstNode=function(e,t){const n=(n,r,o)=>g(e,{...t,...r,children:n},o);return n.element=e,n},exports.createNode=function(e,t){const n=(n,r)=>g(e,{...t,...n},r);return n.element=e,n};
@@ -1 +1 @@
1
- "use strict";var e=require("./react-is.helper.js"),t=require("../constant/css-properties.const.js"),r=require("../constant/common.const.js");const n=t=>e.isForwardRef(t)?"forwardRef":e.isMemo(t)?"memo":e.isFragment(t)?"fragment":e.isPortal(t)?"portal":e.isProfiler(t)?"profiler":e.isStrictMode(t)?"strict-mode":e.isSuspense(t)?"suspense":e.isSuspenseList(t)?"suspense-list":e.isContextConsumer(t)?"context-consumer":e.isContextProvider(t)?"context-provider":e.isLazy(t)?"lazy":e.isElement(t)?"element":e.isReactClassComponent(t)?"class":typeof t;const o=new Set(t.default);exports.CSSPropertySet=o,exports.getCSSProps=function(e){const t={};for(const r in e)Object.prototype.hasOwnProperty.call(e,r)&&o.has(r)&&(t[r]=e[r]);return t},exports.getComponentType=n,exports.getDOMProps=function(e){const t={};for(const r in e)Object.prototype.hasOwnProperty.call(e,r)&&!o.has(r)&&(t[r]=e[r]);return t},exports.getElementTypeName=function e(t){function r(e,t){const r=e?.displayName||e?.name;return r&&"render"!==r?r:t}if(null==t)return"UnknownElementType";const o=t,s=n(o);switch(s){case"string":return t;case"class":return r(o,"ClassComponent");case"function":return r(o,"AnonymousFunctionComponent");case"forwardRef":return r(o,"")||r(o.render,"")||"ForwardRefComponent";case"memo":return r(o,"")||(o.type?e(o.type):"MemoComponent");case"element":return e(o.type);case"fragment":return"Fragment";case"portal":return"Portal";case"profiler":return r(o,"Profiler");case"strict-mode":return"StrictMode";case"suspense":return r(o,"Suspense");case"suspense-list":return"SuspenseList";case"context-consumer":return o._context?.displayName?`${o._context.displayName}.Consumer`:"ContextConsumer";case"context-provider":return o._context?.displayName?`${o._context.displayName}.Provider`:"ContextProvider";case"lazy":return r(o,"LazyComponent");case"object":return r(o,"")?r(o,""):"function"==typeof o.render?r(o.render,"ObjectWithRender"):o.type&&o.type!==t?`Wrapped<${e(o.type)}>`:r(o,"ObjectComponent");case"symbol":return"symbol"==typeof t?t.description?.replace(/^react\./,"").split(".").map(e=>e[0]?.toUpperCase()+e.slice(1)).join("")||t.toString():"SymbolComponent";case"unknown":return"UnknownElementType";default:return`UnsupportedType<${s}>`}},exports.getValueByPath=(e,t)=>t.split(".").reduce((e,t)=>e&&void 0!==e[t]?e[t]:void 0,e),exports.hasNoStyleTag=function(e){return!(!e||"string"!=typeof e)&&r.noStyleTagsSet.has(e.toLowerCase())},exports.omitUndefined=function(e){const t={};for(const r in e)Object.prototype.hasOwnProperty.call(e,r)&&void 0!==e[r]&&(t[r]=e[r]);return t};
1
+ "use strict";var e=require("./react-is.helper.js"),t=require("../constant/css-properties.const.js"),n=require("../constant/common.const.js");const r=t=>e.isForwardRef(t)?"forwardRef":e.isMemo(t)?"memo":e.isFragment(t)?"fragment":e.isPortal(t)?"portal":e.isProfiler(t)?"profiler":e.isStrictMode(t)?"strict-mode":e.isSuspense(t)?"suspense":e.isSuspenseList(t)?"suspense-list":e.isContextConsumer(t)?"context-consumer":e.isContextProvider(t)?"context-provider":e.isLazy(t)?"lazy":e.isElement(t)?"element":e.isReactClassComponent(t)?"class":typeof t;const o=new Set(t.default);exports.CSSPropertySet=o,exports.getCSSProps=function(e){const t={};for(const n in e)Object.prototype.hasOwnProperty.call(e,n)&&o.has(n)&&(t[n]=e[n]);return t},exports.getComponentType=r,exports.getDOMProps=function(e){const t={};for(const n in e)Object.prototype.hasOwnProperty.call(e,n)&&!o.has(n)&&(t[n]=e[n]);return t},exports.getElementTypeName=function e(t){function n(e,t){const n=e?.displayName||e?.name;return n&&"render"!==n?n:t}if(null==t)return"UnknownElementType";const o=t,s=r(o);switch(s){case"string":return t;case"class":return n(o,"ClassComponent");case"function":return n(o,"AnonymousFunctionComponent");case"forwardRef":return n(o,"")||n(o.render,"")||"ForwardRefComponent";case"memo":return n(o,"")||(o.type?e(o.type):"MemoComponent");case"element":return e(o.type);case"fragment":return"Fragment";case"portal":return"Portal";case"profiler":return n(o,"Profiler");case"strict-mode":return"StrictMode";case"suspense":return n(o,"Suspense");case"suspense-list":return"SuspenseList";case"context-consumer":return o._context?.displayName?`${o._context.displayName}.Consumer`:"ContextConsumer";case"context-provider":return o._context?.displayName?`${o._context.displayName}.Provider`:"ContextProvider";case"lazy":return n(o,"LazyComponent");case"object":return n(o,"")?n(o,""):"function"==typeof o.render?n(o.render,"ObjectWithRender"):o.type&&o.type!==t?`Wrapped<${e(o.type)}>`:n(o,"ObjectComponent");case"symbol":return"symbol"==typeof t?t.description?.replace(/^react\./,"").split(".").map(e=>e[0]?.toUpperCase()+e.slice(1)).join("")||t.toString():"SymbolComponent";case"unknown":return"UnknownElementType";default:return`UnsupportedType<${s}>`}},exports.getGlobalState=function(e,t){const n="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:{};return Object.prototype.hasOwnProperty.call(n,e)||(n[e]=t()),n[e]},exports.getValueByPath=(e,t)=>t.split(".").reduce((e,t)=>e&&void 0!==e[t]?e[t]:void 0,e),exports.hasNoStyleTag=function(e){return!(!e||"string"!=typeof e)&&n.noStyleTagsSet.has(e.toLowerCase())},exports.omitUndefined=function(e){const t={};for(const n in e)Object.prototype.hasOwnProperty.call(e,n)&&void 0!==e[n]&&(t[n]=e[n]);return t};
@@ -1 +1 @@
1
- "use strict";var t=require("../constant/common.const.js");class n{constructor(){}static mountedNodes=new Set;static _unmountCallCount=new Map;static trackMount(n){this.mountedNodes.add(n),t.__DEBUG__&&this._unmountCallCount.delete(n)}static untrackMount(n){const o=this.mountedNodes.delete(n);if(t.__DEBUG__&&!o){const t=(this._unmountCallCount.get(n)||0)+1;this._unmountCallCount.set(n,t),t>1&&console.warn(`[MeoNode] untrackMount called ${t} times for an already unmounted node: ${n}. This could indicate a memory leak or a bug in a component's lifecycle.`)}return o}static cleanup(){this.mountedNodes.clear(),t.__DEBUG__&&this._unmountCallCount.clear()}}exports.MountTrackerUtil=n;
1
+ "use strict";var t=require("../constant/common.const.js");class n{constructor(){}static _mountedCounts=new Map;static _unmountCallCount=new Map;static isMounted(t){return(this._mountedCounts.get(t)||0)>0}static trackMount(n){const o=this._mountedCounts.get(n)||0;this._mountedCounts.set(n,o+1),t.__DEBUG__&&this._unmountCallCount.delete(n)}static untrackMount(n){const o=this._mountedCounts.get(n)||0;if(o>0){const t=o-1;return 0===t?this._mountedCounts.delete(n):this._mountedCounts.set(n,t),t>0}if(t.__DEBUG__){const t=(this._unmountCallCount.get(n)||0)+1;this._unmountCallCount.set(n,t),t>1&&console.warn(`[MeoNode] untrackMount called ${t} times for an already unmounted node: ${n}. This could indicate a memory leak or a bug in a component's lifecycle.`)}return!1}static cleanup(){this._mountedCounts.clear(),t.__DEBUG__&&this._unmountCallCount.clear()}}exports.MountTrackerUtil=n;
@@ -1 +1 @@
1
- "use strict";var e=require("../constant/common.const.js"),t=require("../core.node.js"),i=require("./mount-tracker.util.js");class a{constructor(){}static _instance=null;static _originalPushState=null;static _originalReplaceState=null;static _isPatched=!1;_isListening=!1;_cleanupTimeout=null;static getInstance(){return this._instance||(this._instance=new a),this._instance}start(){this._isListening||"undefined"==typeof window||(this._isListening=!0,window.addEventListener("popstate",this._handleNavigation),this._patchHistoryMethods(),this._setupAutoCleanup(),e.__DEBUG__&&console.log("[MeoNode] NavigationCacheManagerUtil started"))}_stop(){this._isListening&&"undefined"!=typeof window&&(window.removeEventListener("popstate",this._handleNavigation),this._cleanupTimeout&&(clearTimeout(this._cleanupTimeout),this._cleanupTimeout=null),this._isListening=!1,e.__DEBUG__&&console.log("[MeoNode] NavigationCacheManagerUtil stopped"))}_handleNavigation=()=>{this._cleanupTimeout&&clearTimeout(this._cleanupTimeout);const a=t.BaseNode.elementCache.size,s=a<100?50:a<500?100:200;this._cleanupTimeout=setTimeout(()=>{const a=t.BaseNode.propProcessingCache.size;let s=0;t.BaseNode.elementCache.keys().forEach(e=>{i.MountTrackerUtil.mountedNodes.has(e)||(t.BaseNode.elementCache.delete(e),s++)}),a>200&&t.BaseNode.propProcessingCache.clear(),e.__DEBUG__&&console.log(`[MeoNode] Navigation: cleared ${s} unmounted elements, ${a} props entries`)},s)};_patchHistoryMethods(){a._isPatched||(a._originalPushState=history.pushState,a._originalReplaceState=history.replaceState,history.pushState=(...e)=>{a._originalPushState.apply(history,e),this._handleNavigation()},history.replaceState=(...e)=>{a._originalReplaceState.apply(history,e),this._handleNavigation()},a._isPatched=!0)}_setupAutoCleanup(){window.__MEONODE_CLEANUP_REGISTERED||(window.addEventListener("beforeunload",()=>{this._stop(),t.BaseNode.clearCaches()}),window.__MEONODE_CLEANUP_REGISTERED=!0)}}exports.NavigationCacheManagerUtil=a;
1
+ "use strict";var e=require("../constant/common.const.js"),t=require("../core.node.js"),i=require("./mount-tracker.util.js");class a{constructor(){}static _instance=null;static _originalPushState=null;static _originalReplaceState=null;static _isPatched=!1;_isListening=!1;_cleanupTimeout=null;static getInstance(){return this._instance||(this._instance=new a),this._instance}start(){this._isListening||"undefined"==typeof window||(this._isListening=!0,window.addEventListener("popstate",this._handleNavigation),this._patchHistoryMethods(),this._setupAutoCleanup(),e.__DEBUG__&&console.log("[MeoNode] NavigationCacheManagerUtil started"))}_stop(){this._isListening&&"undefined"!=typeof window&&(window.removeEventListener("popstate",this._handleNavigation),this._cleanupTimeout&&(clearTimeout(this._cleanupTimeout),this._cleanupTimeout=null),this._isListening=!1,e.__DEBUG__&&console.log("[MeoNode] NavigationCacheManagerUtil stopped"))}_handleNavigation=()=>{this._cleanupTimeout&&clearTimeout(this._cleanupTimeout);const a=t.BaseNode.elementCache.size,n=a<100?50:a<500?100:200;this._cleanupTimeout=setTimeout(()=>{let a=0;t.BaseNode.elementCache.keys().forEach(e=>{i.MountTrackerUtil.isMounted(e)||(t.BaseNode.elementCache.delete(e),a++)}),e.__DEBUG__&&console.log(`[MeoNode] Navigation: cleared ${a} unmounted elements`)},n)};_patchHistoryMethods(){a._isPatched||(a._originalPushState=history.pushState,a._originalReplaceState=history.replaceState,history.pushState=(...e)=>{a._originalPushState.apply(history,e),this._handleNavigation()},history.replaceState=(...e)=>{a._originalReplaceState.apply(history,e),this._handleNavigation()},a._isPatched=!0)}_setupAutoCleanup(){window.__MEONODE_CLEANUP_REGISTERED||(window.addEventListener("beforeunload",()=>{this._stop(),t.BaseNode.clearCaches()}),window.__MEONODE_CLEANUP_REGISTERED=!0)}}exports.NavigationCacheManagerUtil=a;
@@ -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 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;
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"),n=require("../core.node.js"),s=require("react-dom/client");const i=Symbol.for("@meonode/ui/NodeUtil/functionSignatureCache"),a=Symbol.for("@meonode/ui/NodeUtil/portalInfrastructure");class c{constructor(){}static isServer="undefined"==typeof window;static get _functionSignatureCache(){return o.getGlobalState(i,()=>new WeakMap)}static CRITICAL_PROPS=new Set(["css","className","disableEmotion","props"]);static get portalInfrastructure(){return o.getGlobalState(a,()=>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=c.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 n=e.charCodeAt(r);t^=n,t=Math.imul(t,16777619),o=33*o^n}return`${(t>>>0).toString(36)}_${(o>>>0).toString(36)}`}static hashCSS(e){const t=Object.keys(e);let o=t.length;for(let r=0;r<Math.min(t.length,10);r++){const n=t[r],s=e[n];o=(o<<5)-o+n.charCodeAt(0),o&=o,"string"==typeof s&&(o=(o<<5)-o+s.length)}return o.toString(36)}static createPropSignature(e,t){if(c.isServer)return;const r=o.getElementTypeName(e),n=Object.keys(t);n.length>1&&n.sort();const s=[`${r}:`];if("function"==typeof e){let t=c._functionSignatureCache.get(e);t||(t=c.hashString(e.toString()),c._functionSignatureCache.set(e,t)),s.push(t)}for(const e of n){const o=t[e];let r;const n=typeof o;if("string"===n||"number"===n||"boolean"===n)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 if("function"===n)r=`${e}:${c.hashString(o.toString())};`;else{r=`${e}:{${Object.keys(o).sort().join(",")}};`}s.push(r)}return c.hashString(s.join(","))}static extractCriticalProps(e,t){const o={_keyCount:t.length};let r=0;for(const n of t){if(r>=50)break;if(c.CRITICAL_PROPS.has(n)){o[n]=e[n],r++;continue}const s=n.charCodeAt(0);111!==s||110!==n.charCodeAt(1)?!(97===s&&114===n.charCodeAt(1)&&105===n.charCodeAt(2)&&97===n.charCodeAt(3)||100===s&&97===n.charCodeAt(1)&&116===n.charCodeAt(2)&&97===n.charCodeAt(3))?t.length<=100&&c.isStyleProp(n)&&(o[n]=e[n],r++):(o[n]=e[n],r++):(o[n]=e[n],r++)}return o}static processProps(e,t={},r){const{ref:n,key:s,children:i,css:a,props:d={},disableEmotion:l,...u}=t;if(0===Object.keys(u).length&&!a)return o.omitUndefined({ref:n,key:s,disableEmotion:l,nativeProps:o.omitUndefined(d),children:c._processChildren(i,l)});const p={},f={},m=Object.keys(u);for(let e=0;e<m.length;e++){const t=m[e],o=u[t],r=typeof o;"string"===r||"number"===r||"boolean"===r?p[t]=o:f[t]=o}const{cssProps:h}={cssProps:o.getCSSProps(p)},y=o.getCSSProps(f),g=o.getDOMProps(u),b={...h,...y,...a},C=c._processChildren(i,l,r);return o.omitUndefined({ref:n,key:s,css:b,...g,disableEmotion:l,nativeProps:o.omitUndefined(d),children:C})}static _processChildren(e,t,o){if(e)return"function"==typeof e?e:Array.isArray(e)?1===e.length?c.processRawNode(e[0],t,`${o}_0`):e.map((e,r)=>c.processRawNode(e,t,`${o}_${r}`)):c.processRawNode(e,t,o)}static shouldCacheElement(e){return!c.isServer&&!!e.stableKey&&!!e.dependencies}static shouldNodeUpdate(e,t,o){return!!c.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,s){if(null==o||"string"==typeof o||"number"==typeof o||"boolean"==typeof o)return o;if(c.isNodeInstance(o)){if(s||r&&!o.rawProps.disableEmotion){const e=new n.BaseNode(o.element,o.rawProps,o.dependencies);return e.stableKey=`${s}:${e.stableKey}`,r&&!e.rawProps.disableEmotion&&(e.rawProps.disableEmotion=!0),e}return o}if(c.isFunctionChild(o))return new n.BaseNode(c.functionRenderer,{props:{render:o,disableEmotion:r}},void 0);if(e.isValidElement(o)){const{style:e,...t}=o.props,s={...t,...e||{}};return new n.BaseNode(o.type,{...s,...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 n.BaseNode(o,{disableEmotion:r},void 0):o instanceof e.Component?c.processRawNode(o.render(),r,s):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:s}){let i;try{i=t()}catch(e){r.__DEBUG__&&console.error("MeoNode: Error executing function-as-a-child.",e),i=null}if(null==i)return i;if(c.isNodeInstance(i))return s&&!i.rawProps.disableEmotion?new n.BaseNode(i.element,{...i.rawProps,disableEmotion:!0}).render():i.render();if(Array.isArray(i)){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 i.map((t,o)=>c.renderProcessedNode({processedElement:c.processRawNode(t,s),passedKey:e(t,o),disableEmotion:s}))}if(i instanceof e.Component)return c.renderProcessedNode({processedElement:c.processRawNode(i.render(),s),disableEmotion:s});if("string"==typeof i||"number"==typeof i||"boolean"==typeof i)return i;const a=c.processRawNode(i,s);return a?c.renderProcessedNode({processedElement:a,disableEmotion:s}):i}static renderProcessedNode({processedElement:o,passedKey:r,disableEmotion:s}){const i={};if(void 0!==r&&(i.key=r),c.isNodeInstance(o)){const e=o.rawProps?.key;return o.rawProps.disableEmotion=s,e===r?o.render():new n.BaseNode(o.element,{...o.rawProps,...i}).render()}return t.isReactClassComponent(o)?new n.BaseNode(o,{...i,disableEmotion:s}).render():o instanceof e.Component?o.render():"function"==typeof o?e.createElement(o,{key:r}):o}static ensurePortalInfrastructure(e){if(c.isServer)return!1;let t=c.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)}c.cleanupPortalInfra(t),c.portalInfrastructure.delete(e),t=void 0}const o=document.createElement("div");document.body.appendChild(o);const i=s.createRoot(o),a={render:i.render.bind(i),unmount:i.unmount.bind(i),update:()=>{}};return t={domElement:o,reactRoot:a,instanceId:e.instanceId},c.portalInfrastructure.set(e,t),n.BaseNode.portalCleanupRegistry.register(e,{domElement:o,reactRoot:a},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)}}}exports.NodeUtil=c;
@@ -1 +1 @@
1
- "use strict";var e=require("../helper/obj.helper.js"),t=require("../helper/common.helper.js");class s{static _instance=null;CACHE_SIZE_LIMIT=500;CACHE_EVICTION_BATCH_SIZE=50;_resolutionCache=new Map;_pathLookupCache=new Map;_themeRegex=/theme\.([a-zA-Z0-9_.-]+)/g;static getInstance(){return s._instance||(s._instance=new s),s._instance}getResolution(e,t){const s=this._generateCacheKey(e,t),r=this._resolutionCache.get(s);return r&&(this._resolutionCache.delete(s),this._resolutionCache.set(s,r)),r||null}setResolution(e,t,s){const r=this._generateCacheKey(e,t);this._resolutionCache.set(r,s),this._resolutionCache.size>this.CACHE_SIZE_LIMIT&&this._evict(this._resolutionCache)}getPathLookup(t,s){const r=`${e.ObjHelper.stringify(t)}_${s}`,n=this._pathLookupCache.get(r);return n&&(this._pathLookupCache.delete(r),this._pathLookupCache.set(r,n)),n??null}setPathLookup(t,s,r){const n=`${e.ObjHelper.stringify(t)}_${s}`;this._pathLookupCache.set(n,r),this._pathLookupCache.size>this.CACHE_SIZE_LIMIT&&this._evict(this._pathLookupCache)}getThemeRegex(){return this._themeRegex.lastIndex=0,this._themeRegex}shouldCache(){return"undefined"==typeof window}clear(){this._resolutionCache.clear(),this._pathLookupCache.clear()}_generateCacheKey(t,s){return`${e.ObjHelper.stringify(t)}_${s.mode}_${e.ObjHelper.stringify(s.system)}`}_evict(e){const t=e.keys();for(let s=0;s<this.CACHE_EVICTION_BATCH_SIZE;s++){const s=t.next().value;if(!s)break;e.delete(s)}}}class r{static themeCache=s.getInstance();constructor(){}static parseFlexShorthand(e){if(null==e)return null;if("number"==typeof e)return{grow:e,shrink:1,basis:"0%"};if("string"!=typeof e)return null;const t=e.trim().toLowerCase();if(!t)return null;switch(t){case"none":return{grow:0,shrink:0,basis:"auto"};case"auto":return{grow:1,shrink:1,basis:"auto"};case"initial":return{grow:0,shrink:1,basis:"auto"};default:return null}}static isPlainObject=e=>{if("object"!=typeof e||null===e)return!1;const t=Object.getPrototypeOf(e);return null===t||t===Object.prototype};static resolveObjWithTheme=(e,s,n={})=>{const{processFunctions:i=!1}=n;if(!s||!s.system||"object"!=typeof s.system||0===Object.keys(s.system).length||!e||0===Object.keys(e).length)return e;const o=s.system;if(r.themeCache.shouldCache()){const t=r.themeCache.getResolution(e,s);if(null!==t)return t}const l=[{value:e,isProcessed:!1}],a=new Map,h=new Set,c=e=>{const s=r.themeCache.getThemeRegex();let n=!1;const i=e.replace(s,(e,s)=>{let i=r.themeCache.getPathLookup(o,s);if(null===i&&(i=t.getValueByPath(o,s),r.themeCache.setPathLookup(o,s,i)),null!=i){if(n=!0,"object"==typeof i){if(!Array.isArray(i)&&"default"in i)return i.default;throw new Error("The provided theme path is invalid!")}return i}return e});return n?i:e};for(;l.length>0;){const e=l[l.length-1],t=e.value;if(r.isPlainObject(t)||Array.isArray(t))if(a.has(t))l.pop();else if(e.isProcessed){l.pop(),h.delete(t);let e=t;if(Array.isArray(t)){let s=null;for(let e=0;e<t.length;e++){const r=t[e],n=a.get(r)??r;n!==r&&(null===s&&(s=[...t]),s[e]=n)}null!==s&&(e=s)}else{let r=null;for(const e in t)if(Object.prototype.hasOwnProperty.call(t,e)){const n=t[e];let o=a.get(n)??n;if("function"==typeof o&&i){const e=o(s);o="string"==typeof e&&e.includes("theme.")?c(e):e}else"string"==typeof o&&o.includes("theme.")&&(o=c(o));o!==n&&(null===r&&(r={...t}),r[e]=o)}null!==r&&(e=r)}a.set(t,e)}else{e.isProcessed=!0,h.add(t);const s=Array.isArray(t)?t:Object.values(t);for(let e=s.length-1;e>=0;e--){const t=s[e];!r.isPlainObject(t)&&!Array.isArray(t)||h.has(t)||l.push({value:t,isProcessed:!1})}}else l.pop()}const u=a.get(e)??e;return r.themeCache.shouldCache()&&r.themeCache.setResolution(e,s,u),u};static clearThemeCache=()=>{r.themeCache.clear()};static resolveDefaultStyle=e=>{if(null==e||"string"==typeof e||"number"==typeof e||"boolean"==typeof e)return{};const{flex:t,...s}=e,n="flex"===s.display||"inline-flex"===s.display,i=!!(s.overflow||s.overflowY||s.overflowX),o=s.flexFlow?.includes("wrap")||"wrap"===s.flexWrap||"wrap-reverse"===s.flexWrap,l="flexShrink"in e&&void 0!==e.flexShrink,a=t?r.parseFlexShorthand(t):null;let h;if(!l)if(a)h=a.shrink;else if(n){if(!i){const e="column"===s.flexDirection||"column-reverse"===s.flexDirection,t="row"===s.flexDirection||"row-reverse"===s.flexDirection||!s.flexDirection;(e&&!o||t&&!o)&&(h=0)}}else h=0;return{flex:t,flexShrink:h,minHeight:0,minWidth:0,...s}}}exports.ThemeUtil=r;
1
+ "use strict";var e=require("../helper/common.helper.js");class t{constructor(){}static parseFlexShorthand(e){if(null==e)return null;if("number"==typeof e)return{grow:e,shrink:1,basis:"0%"};if("string"!=typeof e)return null;const t=e.trim().toLowerCase();if(!t)return null;switch(t){case"none":return{grow:0,shrink:0,basis:"auto"};case"auto":return{grow:1,shrink:1,basis:"auto"};case"initial":return{grow:0,shrink:1,basis:"auto"};default:return null}}static isPlainObject=e=>{if("object"!=typeof e||null===e)return!1;const t=Object.getPrototypeOf(e);return null===t||t===Object.prototype};static resolveObjWithTheme=(r,l,s={})=>{const{processFunctions:n=!1}=s;if(!l||!l.system||"object"!=typeof l.system||0===Object.keys(l.system).length||!r||0===Object.keys(r).length)return r;const i=l.system,o=[{value:r,isProcessed:!1}],a=new Map,u=new Set,c=/theme\.([a-zA-Z0-9_.-]+)/g,f=t=>{c.lastIndex=0;let r=!1;const l=t.replace(c,(t,l)=>{const s=e.getValueByPath(i,l);if(null!=s){if(r=!0,"object"==typeof s){if(!Array.isArray(s)&&"default"in s)return s.default;throw new Error("The provided theme path is invalid!")}return s}return t});return r?l:t};for(;o.length>0;){const e=o[o.length-1],r=e.value;if(t.isPlainObject(r)||Array.isArray(r))if(a.has(r))o.pop();else if(e.isProcessed){o.pop(),u.delete(r);let e=r;if(Array.isArray(r)){let t=null;for(let e=0;e<r.length;e++){const l=r[e],s=a.get(l)??l;s!==l&&(null===t&&(t=[...r]),t[e]=s)}null!==t&&(e=t)}else{let t=null;for(const e in r)if(Object.prototype.hasOwnProperty.call(r,e)){const s=r[e];let i=a.get(s)??s;if("function"==typeof i&&n){const e=i(l);i="string"==typeof e&&e.includes("theme.")?f(e):e}else"string"==typeof i&&i.includes("theme.")&&(i=f(i));i!==s&&(null===t&&(t={...r}),t[e]=i)}null!==t&&(e=t)}a.set(r,e)}else{e.isProcessed=!0,u.add(r);const l=Array.isArray(r)?r:Object.values(r);for(let e=l.length-1;e>=0;e--){const r=l[e];!t.isPlainObject(r)&&!Array.isArray(r)||u.has(r)||o.push({value:r,isProcessed:!1})}}else o.pop()}return a.get(r)??r};static resolveDefaultStyle=e=>{if(null==e||"string"==typeof e||"number"==typeof e||"boolean"==typeof e)return{};const{flex:r,...l}=e,s="flex"===l.display||"inline-flex"===l.display,n=!!(l.overflow||l.overflowY||l.overflowX),i=l.flexFlow?.includes("wrap")||"wrap"===l.flexWrap||"wrap-reverse"===l.flexWrap,o="flexShrink"in e&&void 0!==e.flexShrink,a=r?t.parseFlexShorthand(r):null;let u;if(!o)if(a)u=a.shrink;else if(s){if(!n){const e="column"===l.flexDirection||"column-reverse"===l.flexDirection,t="row"===l.flexDirection||"row-reverse"===l.flexDirection||!l.flexDirection;(e&&!i||t&&!i)&&(u=0)}}else u=0;return{flex:r,flexShrink:u,minHeight:0,minWidth:0,...l}}}exports.ThemeUtil=t;
@@ -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,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,GAAG,SAAS,CAgCxH"}
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,CA0CxH"}
@@ -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 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};
2
+ import{useEffectEvent as e,useEffect as t,isValidElement as r,cloneElement as a}from"react";import{MountTrackerUtil as n}from"../util/mount-tracker.util.js";import{BaseNode as o}from"../core.node.js";function l({children:l,...s}){const{node:u,...c}=s,i=e(()=>{u.stableKey&&(o.elementCache.delete(u.stableKey),n.isMounted(u.stableKey)&&n.untrackMount(u.stableKey),o.cacheCleanupRegistry.unregister(u)),u.lastSignature=void 0});return t(()=>(u.stableKey&&n.trackMount(u.stableKey),()=>i()),[]),r(l)&&Object.keys(c).length>0?a(l,c):l}export{l as default};