@meonode/ui 0.4.2 → 0.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +41 -0
- package/dist/components/registry.client.js +1 -1
- package/dist/core.node.d.ts +50 -8
- package/dist/core.node.d.ts.map +1 -1
- package/dist/core.node.js +126 -27
- package/dist/helper/mount-tracker.helper.d.ts +16 -0
- package/dist/helper/mount-tracker.helper.d.ts.map +1 -0
- package/dist/helper/mount-tracker.helper.js +8 -0
- package/dist/helper/navigation-cache-manager.helper.d.ts +24 -0
- package/dist/helper/navigation-cache-manager.helper.d.ts.map +1 -0
- package/dist/helper/navigation-cache-manager.helper.js +18 -0
- package/dist/helper/safe-cache-manager.helper.d.ts +21 -0
- package/dist/helper/safe-cache-manager.helper.d.ts.map +1 -0
- package/dist/helper/safe-cache-manager.helper.js +33 -0
- package/dist/types/node.type.d.ts +17 -1
- package/dist/types/node.type.d.ts.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,47 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.4.4] - 2025-11-15
|
|
9
|
+
|
|
10
|
+
### Perf
|
|
11
|
+
- **core**: implement intelligent caching and memory management ([`0e5671b`](https://github.com/l7aromeo/meonode-ui/commit/0e5671b36189c964d66676ef633f3ccdbd9004e2))
|
|
12
|
+
Introduces a sophisticated caching and memory management system to prevent memory leaks and improve performance in Single Page Applications (SPAs).
|
|
13
|
+
|
|
14
|
+
This new system intelligently tracks mounted components and automatically cleans up caches of unmounted components during navigation events.
|
|
15
|
+
|
|
16
|
+
Key features and improvements include:
|
|
17
|
+
|
|
18
|
+
- **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.
|
|
19
|
+
|
|
20
|
+
- **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.
|
|
21
|
+
|
|
22
|
+
- **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.
|
|
23
|
+
|
|
24
|
+
- **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.
|
|
25
|
+
|
|
26
|
+
- **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.
|
|
27
|
+
|
|
28
|
+
- **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.
|
|
29
|
+
|
|
30
|
+
- **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.
|
|
31
|
+
|
|
32
|
+
### Fix
|
|
33
|
+
- **core**: simplify property assignment in common helper ([`312af57`](https://github.com/l7aromeo/meonode-ui/commit/312af574712202a25bdd62fab94441a937f159f2))
|
|
34
|
+
|
|
35
|
+
### Refactor
|
|
36
|
+
- **core**: add ElementCacheEntry interface for memoization and update css prop type ([`6a8381c`](https://github.com/l7aromeo/meonode-ui/commit/6a8381c4c85cb22df4ba398637401d420461e413))
|
|
37
|
+
|
|
38
|
+
## [0.4.3] - 2025-11-14
|
|
39
|
+
|
|
40
|
+
### Docs
|
|
41
|
+
- **core**: add detailed comments to rendering methods ([`731c83e`](https://github.com/l7aromeo/meonode-ui/commit/731c83e))
|
|
42
|
+
|
|
43
|
+
### Fix
|
|
44
|
+
- **core**: adjust isStyledComponent logic to improve style handling ([`ff7a59e`](https://github.com/l7aromeo/meonode-ui/commit/ff7a59e))
|
|
45
|
+
|
|
46
|
+
### Refactor
|
|
47
|
+
- **core**: simplify _processProps by removing style prop handling ([`b3570b4`](https://github.com/l7aromeo/meonode-ui/commit/b3570b4))
|
|
48
|
+
|
|
8
49
|
## [0.4.2] - 2025-11-14
|
|
9
50
|
|
|
10
51
|
### Fix
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";function _slicedToArray(a,b){return _arrayWithHoles(a)||_iterableToArrayLimit(a,b)||_unsupportedIterableToArray(a,b)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(b,c){if(b){if("string"==typeof b)return _arrayLikeToArray(b,c);var a={}.toString.call(b).slice(8,-1);return"Object"===a&&b.constructor&&(a=b.constructor.name),"Map"===a||"Set"===a?Array.from(b):"Arguments"===a||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(a)?_arrayLikeToArray(b,c):void 0}}function _arrayLikeToArray(b,c){(null==c||c>b.length)&&(c=b.length);for(var d=0,f=Array(c);d<c;d++)f[d]=b[d];return f}function _iterableToArrayLimit(b,c){var d=null==b?null:"undefined"!=typeof Symbol&&b[Symbol.iterator]||b["@@iterator"];if(null!=d){var g,h,j,k,l=[],a=!0,m=!1;try{if(j=(d=d.call(b)).next,0===c){if(Object(d)!==d)return;a=!1}else for(;!(a=(g=j.call(d)).done)&&(l.push(g.value),l.length!==c);a=!0);}catch(a){m=!0,h=a}finally{try{if(!a&&null!=d["return"]&&(k=d["return"](),Object(k)!==k))return}finally{if(m)throw h}}return l}}function _arrayWithHoles(a){if(Array.isArray(a))return a}import{createElement,useState}from"react";import{
|
|
1
|
+
"use client";function _slicedToArray(a,b){return _arrayWithHoles(a)||_iterableToArrayLimit(a,b)||_unsupportedIterableToArray(a,b)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(b,c){if(b){if("string"==typeof b)return _arrayLikeToArray(b,c);var a={}.toString.call(b).slice(8,-1);return"Object"===a&&b.constructor&&(a=b.constructor.name),"Map"===a||"Set"===a?Array.from(b):"Arguments"===a||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(a)?_arrayLikeToArray(b,c):void 0}}function _arrayLikeToArray(b,c){(null==c||c>b.length)&&(c=b.length);for(var d=0,f=Array(c);d<c;d++)f[d]=b[d];return f}function _iterableToArrayLimit(b,c){var d=null==b?null:"undefined"!=typeof Symbol&&b[Symbol.iterator]||b["@@iterator"];if(null!=d){var g,h,j,k,l=[],a=!0,m=!1;try{if(j=(d=d.call(b)).next,0===c){if(Object(d)!==d)return;a=!1}else for(;!(a=(g=j.call(d)).done)&&(l.push(g.value),l.length!==c);a=!0);}catch(a){m=!0,h=a}finally{try{if(!a&&null!=d["return"]&&(k=d["return"](),Object(k)!==k))return}finally{if(m)throw h}}return l}}function _arrayWithHoles(a){if(Array.isArray(a))return a}import{createElement,useState}from"react";import{CacheProvider}from"@emotion/react";import createCache from"@emotion/cache";import{Node}from"../core.node.js";import{useServerInsertedHTML}from"next/navigation.js";function createEmotionCache(){return createCache({key:"meonode-css"})}export default function StyleRegistry(a){var b=a.children,c=useState(function(){var a=createEmotionCache();return a.compat=!0,a}),d=_slicedToArray(c,1),e=d[0];return useServerInsertedHTML(function(){var a=Object.keys(e.inserted).sort(),b=a.map(function(a){return e.inserted[a]}).join(""),c=a.join(" ");return b?createElement("style",{"data-emotion":"".concat(e.key," ").concat(c),dangerouslySetInnerHTML:{__html:b}}):null}),Node(CacheProvider,{value:e,children:b}).render()}
|
package/dist/core.node.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ReactElement } from 'react';
|
|
2
|
-
import type { Children, FinalNodeProps, HasRequiredProps, MergedProps, NodeElementType, NodeInstance, NodePortal, NodeProps, PropsOf, DependencyList } from './types/node.type.js';
|
|
2
|
+
import type { Children, FinalNodeProps, HasRequiredProps, MergedProps, NodeElementType, NodeInstance, NodePortal, NodeProps, PropsOf, DependencyList, ElementCacheEntry } from './types/node.type.js';
|
|
3
3
|
/**
|
|
4
4
|
* The core abstraction of the MeoNode library. It wraps a React element or component,
|
|
5
5
|
* providing a unified interface for processing props, normalizing children, and handling styles.
|
|
@@ -13,19 +13,22 @@ export declare class BaseNode<E extends NodeElementType> implements NodeInstance
|
|
|
13
13
|
rawProps: Partial<NodeProps<E>>;
|
|
14
14
|
readonly isBaseNode: boolean;
|
|
15
15
|
private _props?;
|
|
16
|
-
private _portalDOMElement;
|
|
17
|
-
private _portalReactRoot;
|
|
18
|
-
private _stableKey;
|
|
19
16
|
private readonly _deps?;
|
|
17
|
+
_stableKey: string;
|
|
20
18
|
private static _isServer;
|
|
21
19
|
private static _propProcessingCache;
|
|
22
|
-
private static _elementCache;
|
|
23
20
|
private static _isValidElement;
|
|
24
21
|
private static _isStyleProp;
|
|
22
|
+
static _elementCache: Map<string, ElementCacheEntry>;
|
|
23
|
+
private static _portalInfrastructure;
|
|
25
24
|
private static readonly CACHE_SIZE_LIMIT = 500;
|
|
26
25
|
private static readonly CACHE_CLEANUP_BATCH = 50;
|
|
27
26
|
private _lastPropsRef;
|
|
28
27
|
private _lastSignature;
|
|
28
|
+
private static _elementIdMap;
|
|
29
|
+
private static _elementIdCounter;
|
|
30
|
+
private static _scheduledCleanup;
|
|
31
|
+
private static _navigationStarted;
|
|
29
32
|
constructor(element: E, rawProps?: Partial<NodeProps<E>>, deps?: DependencyList);
|
|
30
33
|
/**
|
|
31
34
|
* Lazily processes and retrieves the final, normalized props for the node.
|
|
@@ -57,6 +60,19 @@ export declare class BaseNode<E extends NodeElementType> implements NodeInstance
|
|
|
57
60
|
* @method _hashString
|
|
58
61
|
*/
|
|
59
62
|
private static _hashString;
|
|
63
|
+
/**
|
|
64
|
+
* Performs a shallow equality check between two objects.
|
|
65
|
+
* @method _shallowEqual
|
|
66
|
+
*/
|
|
67
|
+
private _shallowEqual;
|
|
68
|
+
/**
|
|
69
|
+
* Generates a stable identifier for the given element type.
|
|
70
|
+
* For primitive types (strings), it returns the string itself.
|
|
71
|
+
* For component types (functions, classes, exotic components), it generates
|
|
72
|
+
* and caches a unique ID using a WeakMap to ensure stability across calls.
|
|
73
|
+
* @method _getStableElementId
|
|
74
|
+
*/
|
|
75
|
+
private static _getStableElementId;
|
|
60
76
|
/**
|
|
61
77
|
* Generates or returns a cached signature representing the props shape and values.
|
|
62
78
|
* The signature is used as a stable key for caching prop-derived computations (e.g. CSS extraction).
|
|
@@ -119,12 +135,28 @@ export declare class BaseNode<E extends NodeElementType> implements NodeInstance
|
|
|
119
135
|
*/
|
|
120
136
|
private static _isFunctionChild;
|
|
121
137
|
/**
|
|
122
|
-
* A
|
|
138
|
+
* A special internal React component used to render "function-as-a-child" (render prop) patterns.
|
|
139
|
+
* When a `BaseNode` receives a function as its `children` prop, it wraps that function
|
|
140
|
+
* inside this `_functionRenderer` component. This component then executes the render function
|
|
141
|
+
* and processes its return value, normalizing it into a renderable ReactNode.
|
|
142
|
+
*
|
|
143
|
+
* This allows `BaseNode` to support render props while maintaining its internal processing
|
|
144
|
+
* and normalization logic for the dynamically generated content.
|
|
123
145
|
* @method _functionRenderer
|
|
146
|
+
* @param {Object} props The properties passed to the renderer.
|
|
147
|
+
* @param {Function} props.render The function-as-a-child to execute.
|
|
148
|
+
* @param {boolean} [props.disableEmotion] Inherited flag to disable Emotion styling for children.
|
|
149
|
+
* @returns {ReactNode | null | undefined} The processed and rendered output of the render function.
|
|
124
150
|
*/
|
|
125
151
|
private static _functionRenderer;
|
|
126
152
|
/**
|
|
127
|
-
*
|
|
153
|
+
* Renders a processed `NodeElement` into a ReactNode.
|
|
154
|
+
* This helper is primarily used by `_functionRenderer` to handle the output of render props,
|
|
155
|
+
* ensuring that `BaseNode` instances are correctly rendered and other React elements or primitives
|
|
156
|
+
* are passed through. It also applies `disableEmotion` and `key` props as needed.
|
|
157
|
+
*
|
|
158
|
+
* This method is part of the child processing pipeline, converting internal `NodeElement` representations
|
|
159
|
+
* into actual React elements that can be rendered by React.
|
|
128
160
|
* @method _renderProcessedNode
|
|
129
161
|
*/
|
|
130
162
|
private static _renderProcessedNode;
|
|
@@ -143,6 +175,12 @@ export declare class BaseNode<E extends NodeElementType> implements NodeInstance
|
|
|
143
175
|
* @method render
|
|
144
176
|
*/
|
|
145
177
|
render(parentBlocked?: boolean): ReactElement<FinalNodeProps>;
|
|
178
|
+
/**
|
|
179
|
+
* Registers a node instance with the MountTracker for unmount tracking.
|
|
180
|
+
* This is only executed on the client-side.
|
|
181
|
+
* @method registerUnmount
|
|
182
|
+
*/
|
|
183
|
+
static registerUnmount(node: BaseNode<any>): void;
|
|
146
184
|
/**
|
|
147
185
|
* Ensures that the necessary DOM element and React root are available for portal rendering.
|
|
148
186
|
* This is only executed on the client-side.
|
|
@@ -166,7 +204,11 @@ export declare class BaseNode<E extends NodeElementType> implements NodeInstance
|
|
|
166
204
|
* It's the simplest way to wrap a component or element.
|
|
167
205
|
* @function Node
|
|
168
206
|
*/
|
|
169
|
-
|
|
207
|
+
declare function Node<AdditionalProps extends Record<string, any>, E extends NodeElementType>(element: E, props?: MergedProps<E, AdditionalProps>, deps?: DependencyList): NodeInstance<E>;
|
|
208
|
+
declare namespace Node {
|
|
209
|
+
var clearCaches: typeof BaseNode.clearCaches;
|
|
210
|
+
}
|
|
211
|
+
export { Node };
|
|
170
212
|
/**
|
|
171
213
|
* Creates a curried node factory for a given React element or component type.
|
|
172
214
|
* This is useful for creating reusable, specialized factory functions (e.g., `const Div = createNode('div')`).
|
package/dist/core.node.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.node.d.ts","sourceRoot":"","sources":["../src/core.node.ts"],"names":[],"mappings":"AAAA,OAAc,EAKZ,KAAK,YAAY,
|
|
1
|
+
{"version":3,"file":"core.node.d.ts","sourceRoot":"","sources":["../src/core.node.ts"],"names":[],"mappings":"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"}
|
package/dist/core.node.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var _BaseNode,_excluded=["key","children","ref"],_excluded2=["ref","key","children","css","props","disableEmotion"],_excluded3=["style"],_excluded4=["children","key","css","nativeProps","disableEmotion"]
|
|
1
|
+
var _BaseNode,_excluded=["key","children","ref"],_excluded2=["ref","key","children","css","props","disableEmotion"],_excluded3=["style"],_excluded4=["children","key","css","nativeProps","disableEmotion"];function ownKeys(a,b){var c=Object.keys(a);if(Object.getOwnPropertySymbols){var d=Object.getOwnPropertySymbols(a);b&&(d=d.filter(function(b){return Object.getOwnPropertyDescriptor(a,b).enumerable})),c.push.apply(c,d)}return c}function _objectSpread(a){for(var b,c=1;c<arguments.length;c++)b=null==arguments[c]?{}:arguments[c],c%2?ownKeys(Object(b),!0).forEach(function(c){_defineProperty(a,c,b[c])}):Object.getOwnPropertyDescriptors?Object.defineProperties(a,Object.getOwnPropertyDescriptors(b)):ownKeys(Object(b)).forEach(function(c){Object.defineProperty(a,c,Object.getOwnPropertyDescriptor(b,c))});return a}function _slicedToArray(a,b){return _arrayWithHoles(a)||_iterableToArrayLimit(a,b)||_unsupportedIterableToArray(a,b)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _iterableToArrayLimit(b,c){var d=null==b?null:"undefined"!=typeof Symbol&&b[Symbol.iterator]||b["@@iterator"];if(null!=d){var g,h,j,k,l=[],a=!0,m=!1;try{if(j=(d=d.call(b)).next,0===c){if(Object(d)!==d)return;a=!1}else for(;!(a=(g=j.call(d)).done)&&(l.push(g.value),l.length!==c);a=!0);}catch(a){m=!0,h=a}finally{try{if(!a&&null!=d["return"]&&(k=d["return"](),Object(k)!==k))return}finally{if(m)throw h}}return l}}function _arrayWithHoles(a){if(Array.isArray(a))return a}function _typeof(a){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},_typeof(a)}function _createForOfIteratorHelper(b,c){var d="undefined"!=typeof Symbol&&b[Symbol.iterator]||b["@@iterator"];if(!d){if(Array.isArray(b)||(d=_unsupportedIterableToArray(b))||c&&b&&"number"==typeof b.length){d&&(b=d);var e=0,f=function F(){};return{s:f,n:function n(){return e>=b.length?{done:!0}:{done:!1,value:b[e++]}},e:function e(a){throw a},f:f}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var g,h=!0,i=!1;return{s:function s(){d=d.call(b)},n:function n(){var a=d.next();return h=a.done,a},e:function e(a){i=!0,g=a},f:function f(){try{h||null==d["return"]||d["return"]()}finally{if(i)throw g}}}}function _unsupportedIterableToArray(b,c){if(b){if("string"==typeof b)return _arrayLikeToArray(b,c);var a={}.toString.call(b).slice(8,-1);return"Object"===a&&b.constructor&&(a=b.constructor.name),"Map"===a||"Set"===a?Array.from(b):"Arguments"===a||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(a)?_arrayLikeToArray(b,c):void 0}}function _arrayLikeToArray(b,c){(null==c||c>b.length)&&(c=b.length);for(var d=0,f=Array(c);d<c;d++)f[d]=b[d];return f}function _objectWithoutProperties(a,b){if(null==a)return{};var c,d,e=_objectWithoutPropertiesLoose(a,b);if(Object.getOwnPropertySymbols){var f=Object.getOwnPropertySymbols(a);for(d=0;d<f.length;d++)c=f[d],-1===b.indexOf(c)&&{}.propertyIsEnumerable.call(a,c)&&(e[c]=a[c])}return e}function _objectWithoutPropertiesLoose(a,b){if(null==a)return{};var c={};for(var d in a)if({}.hasOwnProperty.call(a,d)){if(-1!==b.indexOf(d))continue;c[d]=a[d]}return c}function _defineProperty(a,b,c){return(b=_toPropertyKey(b))in a?Object.defineProperty(a,b,{value:c,enumerable:!0,configurable:!0,writable:!0}):a[b]=c,a}function _toPropertyKey(a){var b=_toPrimitive(a,"string");return"symbol"==_typeof(b)?b:b+""}function _toPrimitive(a,b){if("object"!=_typeof(a)||!a)return a;var c=a[Symbol.toPrimitive];if(void 0!==c){var d=c.call(a,b||"default");if("object"!=_typeof(d))return d;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===b?String:Number)(a)}import React,{createElement,isValidElement,Fragment,StrictMode}from"react";import{isNodeInstance}from"./helper/node.helper.js";import{isForwardRef,isFragment,isMemo,isReactClassComponent,isValidElementType}from"./helper/react-is.helper.js";import{createRoot}from"react-dom/client";import{getComponentType,getCSSProps,getDOMProps,getElementTypeName,hasNoStyleTag,omitUndefined}from"./helper/common.helper.js";import StyledRenderer from"./components/styled-renderer.client.js";import{__DEV__}from"./constants/common.const.js";import{MountTracker}from"./helper/mount-tracker.helper.js";import{NavigationCacheManager}from"./helper/navigation-cache-manager.helper.js";/**
|
|
2
2
|
* The core abstraction of the MeoNode library. It wraps a React element or component,
|
|
3
3
|
* providing a unified interface for processing props, normalizing children, and handling styles.
|
|
4
4
|
* This class is central to the library's ability to offer a JSX-free, fluent API for building UIs.
|
|
@@ -6,10 +6,10 @@ var _BaseNode,_excluded=["key","children","ref"],_excluded2=["ref","key","childr
|
|
|
6
6
|
* @class BaseNode
|
|
7
7
|
* @template E - The type of React element or component this node represents.
|
|
8
8
|
*/export class BaseNode{constructor(a){var b=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{},c=2<arguments.length?arguments[2]:void 0;// Element type validation is performed once at construction to prevent invalid nodes from being created.
|
|
9
|
-
if(_defineProperty(this,"rawProps",{}),_defineProperty(this,"isBaseNode",!0),_defineProperty(this,"
|
|
9
|
+
if(_defineProperty(this,"rawProps",{}),_defineProperty(this,"isBaseNode",!0),_defineProperty(this,"_lastPropsRef",null),_defineProperty(this,"_lastSignature",""),!BaseNode._isValidElement(a)){var d=getComponentType(a);throw new Error("Invalid element type: ".concat(d," provided!"))}this.element=a,this.rawProps=b,this._deps=c;// Generate an initial stable key used for internal caching.
|
|
10
10
|
// Exclude React's `key`, `ref`, and `children` from the signature so positional or ref changes
|
|
11
11
|
// do not unintentionally affect the component's cache identity.
|
|
12
|
-
var e=b.key,f=b.children,g=b.ref,h=_objectWithoutProperties(b,_excluded);this._stableKey=this._getCachedSignature(h),void 0!==e&&null!==e&&(this._stableKey="".concat(e+"",":").concat(this._stableKey))}/**
|
|
12
|
+
var e=b.key,f=b.children,g=b.ref,h=_objectWithoutProperties(b,_excluded);this._stableKey=this._getCachedSignature(h),void 0!==e&&null!==e&&(this._stableKey="".concat(e+"",":").concat(this._stableKey)),BaseNode._isServer||BaseNode._navigationStarted||(NavigationCacheManager.getInstance().start(),BaseNode._navigationStarted=!0)}/**
|
|
13
13
|
* Lazily processes and retrieves the final, normalized props for the node.
|
|
14
14
|
* The props are processed only once and then cached for subsequent accesses.
|
|
15
15
|
* @getter props
|
|
@@ -35,6 +35,18 @@ for(var b=Math.imul,c=2166136261,d=0;d<a.length;d++)c^=a.charCodeAt(d),c=b(c,167
|
|
|
35
35
|
* @method _hashString
|
|
36
36
|
*/static _hashString(a){var b=BaseNode._fnv1aHash(a),c=BaseNode._djb2Hash(a);return"".concat(b.toString(36),"_").concat(c.toString(36));// Combine and convert to base36
|
|
37
37
|
}/**
|
|
38
|
+
* Performs a shallow equality check between two objects.
|
|
39
|
+
* @method _shallowEqual
|
|
40
|
+
*/_shallowEqual(c,a){var b=Object.keys(c),d=Object.keys(a);return!(b.length!==d.length)&&b.every(function(b){return c[b]===a[b]})}/**
|
|
41
|
+
* Generates a stable identifier for the given element type.
|
|
42
|
+
* For primitive types (strings), it returns the string itself.
|
|
43
|
+
* For component types (functions, classes, exotic components), it generates
|
|
44
|
+
* and caches a unique ID using a WeakMap to ensure stability across calls.
|
|
45
|
+
* @method _getStableElementId
|
|
46
|
+
*/static _getStableElementId(a){if(a===StrictMode)return"StrictMode";if("string"==typeof a)return a;// On server, avoid WeakMap caching. Directly return a stable string identifier.
|
|
47
|
+
if(BaseNode._isServer)try{return getElementTypeName(a)}catch(a){// Fallback for components without a name
|
|
48
|
+
return"ServerComponentFallback_".concat(BaseNode._elementIdCounter++)}// Client-side: Use WeakMap to maintain stable IDs across calls
|
|
49
|
+
return BaseNode._elementIdMap.has(a)||BaseNode._elementIdMap.set(a,"Component_".concat(BaseNode._elementIdCounter++)),BaseNode._elementIdMap.get(a)}/**
|
|
38
50
|
* Generates or returns a cached signature representing the props shape and values.
|
|
39
51
|
* The signature is used as a stable key for caching prop-derived computations (e.g. CSS extraction).
|
|
40
52
|
* - Uses a fast reference check to return the previous signature if the same props object is passed.
|
|
@@ -44,21 +56,19 @@ for(var b=Math.imul,c=2166136261,d=0;d<a.length;d++)c^=a.charCodeAt(d),c=b(c,167
|
|
|
44
56
|
* - Stores the last props reference and computed signature to speed up repeated calls with the same object.
|
|
45
57
|
* @param props The props object to create a signature for.
|
|
46
58
|
* @returns A compact string signature suitable for use as a cache key.
|
|
47
|
-
*/_getCachedSignature(a){if(a===this._lastPropsRef)return this._lastSignature;var b=Object.keys(a),c=b.length;if(100<c){var d,e={_keyCount:c},f=_createForOfIteratorHelper(b);try{for(
|
|
59
|
+
*/_getCachedSignature(a){if(BaseNode._isServer)return BaseNode._createPropSignature(this.element,a);if(a===this._lastPropsRef)return this._lastSignature;if(this._lastPropsRef&&this._shallowEqual(a,this._lastPropsRef))return this._lastPropsRef=a,this._lastSignature;var b=Object.keys(a),c=b.length;if(100<c){var d,e={_keyCount:c},f=0,g=_createForOfIteratorHelper(b);try{for(g.s();!(d=g.n()).done;){var h=d.value;if(f>=50)break;(BaseNode._isStyleProp(h)||"css"===h||"className"===h||h.startsWith("on"))&&(e[h]=a[h],f++)}}catch(a){g.e(a)}finally{g.f()}this._lastSignature=BaseNode._createPropSignature(this.element,e),__DEV__&&200<c&&console.warn("MeoNode: Large props (".concat(c," keys) on \"").concat(getElementTypeName(this.element),"\". Consider splitting."))}else this._lastSignature=BaseNode._createPropSignature(this.element,a);return this._lastPropsRef=a,this._lastSignature}/**
|
|
48
60
|
* Creates a unique, stable signature from the element type and props.
|
|
49
61
|
* This signature includes the element's type to prevent collisions between different components
|
|
50
62
|
* and handles primitive values in arrays and objects for better caching.
|
|
51
63
|
* @method _createPropSignature
|
|
52
64
|
*/static _createPropSignature(a,b){// Safe element identification that works with Next.js Client Components
|
|
53
|
-
var c;try{c="
|
|
54
|
-
// Use a generic identifier - this is safe because we still have props in the signature
|
|
55
|
-
__DEV__&&console.error("MeoNode: Could not determine element name for signature.",a),c="ClientComponent"}var d,e=Object.keys(b).sort(),f="".concat(c,":"),g=_createForOfIteratorHelper(e);try{for(g.s();!(d=g.n()).done;){var h=d.value,i=b[h],j=void 0,k=_typeof(i);if("string"===k||"number"===k||"boolean"===k)j="".concat(h,":").concat(i,";");else if(null===i)j="".concat(h,":null;");else if(i===void 0)j="".concat(h,":undefined;");else if(Array.isArray(i)){// Hash primitive values in arrays for better cache hits
|
|
65
|
+
var c;if(BaseNode._isServer)c=BaseNode._getStableElementId(a);else try{c=getElementTypeName(a)}catch(b){__DEV__&&console.error("MeoNode: Could not determine element name for signature.",b),c=BaseNode._getStableElementId(a)}var d,e=Object.keys(b).sort(),f="".concat(c,":"),g=_createForOfIteratorHelper(e);try{for(g.s();!(d=g.n()).done;){var h=d.value,i=b[h],j=void 0,k=_typeof(i);if("string"===k||"number"===k||"boolean"===k)j="".concat(h,":").concat(i,";");else if(null===i)j="".concat(h,":null;");else if(i===void 0)j="".concat(h,":undefined;");else if(Array.isArray(i)){// Hash primitive values in arrays for better cache hits
|
|
56
66
|
var l=i.filter(function(a){var b=_typeof(a);return"string"===b||"number"===b||"boolean"===b||null===a});j=l.length===i.length?"".concat(h,":[").concat(l.join(","),"];"):"".concat(h,":[").concat(i.length,"];")}else{// Include sorted keys for object structure signature
|
|
57
67
|
var m=Object.keys(i).sort();j="".concat(h,":{").concat(m.join(","),"};")}f+=j}}catch(a){g.e(a)}finally{g.f()}return BaseNode._hashString(f)}/**
|
|
58
68
|
* Retrieves computed CSS props from the cache with LRU tracking.
|
|
59
69
|
* Access time and hit count are tracked for smarter eviction.
|
|
60
70
|
* @method _getCachedCssProps
|
|
61
|
-
*/static _getCachedCssProps(a,b){var c=BaseNode._propProcessingCache.get(b);if(c)return c.lastAccess=Date.now(),c.hitCount++,{cssProps:c.cssProps};var d=getCSSProps(a);return BaseNode._propProcessingCache.set(b,{cssProps:d,signature:b,lastAccess:Date.now(),hitCount:1}),BaseNode._propProcessingCache.size>BaseNode.CACHE_SIZE_LIMIT&&BaseNode._evictLRUEntries(),{cssProps:d}}/**
|
|
71
|
+
*/static _getCachedCssProps(a,b){if(BaseNode._isServer)return{cssProps:getCSSProps(a)};var c=BaseNode._propProcessingCache.get(b);if(c)return c.lastAccess=Date.now(),c.hitCount++,{cssProps:c.cssProps};var d=getCSSProps(a);return BaseNode._propProcessingCache.set(b,{cssProps:d,signature:b,lastAccess:Date.now(),hitCount:1}),BaseNode._propProcessingCache.size>BaseNode.CACHE_SIZE_LIMIT&&!BaseNode._scheduledCleanup&&(BaseNode._scheduledCleanup=!0,"undefined"==typeof requestIdleCallback?setTimeout(function(){BaseNode._evictLRUEntries(),BaseNode._scheduledCleanup=!1},100):requestIdleCallback(function(){BaseNode._evictLRUEntries(),BaseNode._scheduledCleanup=!1},{timeout:2e3})),{cssProps:d}}/**
|
|
62
72
|
* Implements an LRU eviction strategy that removes multiple entries at once.
|
|
63
73
|
* It uses a scoring system where older and less frequently used entries have a higher eviction priority.
|
|
64
74
|
* @method _evictLRUEntries
|
|
@@ -70,16 +80,16 @@ c.push({key:f,score:k})}// Sort by score (highest = most evictable)
|
|
|
70
80
|
for(var l=Math.min(BaseNode.CACHE_CLEANUP_BATCH,c.length),m=0;m<l;m++)BaseNode._propProcessingCache["delete"](c[m].key)}/**
|
|
71
81
|
* The main prop processing pipeline, which now passes the element type for improved caching.
|
|
72
82
|
* @method _processProps
|
|
73
|
-
*/_processProps(){var a=this.rawProps,b=a.ref,c=a.key,d=a.children,e=a.css,f=a.props,g=void 0===f?{}:f,h=a.disableEmotion,i=_objectWithoutProperties(a,_excluded2)
|
|
74
|
-
if(0===Object.keys(i).length&&!e)return omitUndefined({ref:b,key:c,
|
|
75
|
-
var
|
|
76
|
-
for(var
|
|
77
|
-
var
|
|
83
|
+
*/_processProps(){var a=this.rawProps,b=a.ref,c=a.key,d=a.children,e=a.css,f=a.props,g=void 0===f?{}:f,h=a.disableEmotion,i=_objectWithoutProperties(a,_excluded2);// --- Fast Path Optimization ---
|
|
84
|
+
if(0===Object.keys(i).length&&!e)return omitUndefined({ref:b,key:c,disableEmotion:h,nativeProps:omitUndefined(g),children:this._processChildren(d,h)});// --- Hybrid Caching Strategy ---
|
|
85
|
+
var j={},k={};// 1. Categorize props into cacheable (primitives) and non-cacheable (objects/functions).
|
|
86
|
+
for(var l in i)if(Object.prototype.hasOwnProperty.call(i,l)){var m=i[l],n=_typeof(m);"string"===n||"number"===n||"boolean"===n?j[l]=m:k[l]=m}// 2. Pass element type to signature generation
|
|
87
|
+
var o=BaseNode._createPropSignature(this.element,j),p=BaseNode._getCachedCssProps(j,o),q=p.cssProps,r=getCSSProps(k),s=getDOMProps(i),t=_objectSpread(_objectSpread(_objectSpread({},q),r),e),u=this._processChildren(d,h,this._stableKey);// 3. Process non-cacheable props on every render to ensure correctness for functions and objects.
|
|
78
88
|
// DOM props are always processed fresh.
|
|
79
89
|
// 4. Assemble the final CSS object.
|
|
80
90
|
// --- Child Normalization ---
|
|
81
91
|
// --- Final Assembly ---
|
|
82
|
-
return omitUndefined(_objectSpread(_objectSpread({ref:b,key:c,css:
|
|
92
|
+
return omitUndefined(_objectSpread(_objectSpread({ref:b,key:c,css:t},s),{},{disableEmotion:h,nativeProps:omitUndefined(g),children:u}))}/**
|
|
83
93
|
* Determines if a node should update based on its dependency array.
|
|
84
94
|
* Uses a shallow comparison, similar to React's `useMemo` and `useCallback`.
|
|
85
95
|
* @method _shouldNodeUpdate
|
|
@@ -113,12 +123,60 @@ return isReactClassComponent(a)||isMemo(a)||isForwardRef(a)?new BaseNode(a,{disa
|
|
|
113
123
|
* rather than a standard Function Component.
|
|
114
124
|
* @method _isFunctionChild
|
|
115
125
|
*/static _isFunctionChild(a){if("function"!=typeof a||isReactClassComponent(a)||isMemo(a)||isForwardRef(a))return!1;try{return!(a.prototype&&"function"==typeof a.prototype.render)}catch(a){return __DEV__&&console.error("MeoNode: Error checking if a node is a function child.",a),!0}}/**
|
|
116
|
-
* A
|
|
126
|
+
* A special internal React component used to render "function-as-a-child" (render prop) patterns.
|
|
127
|
+
* When a `BaseNode` receives a function as its `children` prop, it wraps that function
|
|
128
|
+
* inside this `_functionRenderer` component. This component then executes the render function
|
|
129
|
+
* and processes its return value, normalizing it into a renderable ReactNode.
|
|
130
|
+
*
|
|
131
|
+
* This allows `BaseNode` to support render props while maintaining its internal processing
|
|
132
|
+
* and normalization logic for the dynamically generated content.
|
|
117
133
|
* @method _functionRenderer
|
|
118
|
-
|
|
119
|
-
*
|
|
134
|
+
* @param {Object} props The properties passed to the renderer.
|
|
135
|
+
* @param {Function} props.render The function-as-a-child to execute.
|
|
136
|
+
* @param {boolean} [props.disableEmotion] Inherited flag to disable Emotion styling for children.
|
|
137
|
+
* @returns {ReactNode | null | undefined} The processed and rendered output of the render function.
|
|
138
|
+
*/static _functionRenderer(a){var b,c=a.render,d=a.disableEmotion;try{// Execute the render prop function to get its output.
|
|
139
|
+
b=c()}catch(a){// If the render function throws, treat its output as null to prevent crashes.
|
|
140
|
+
__DEV__&&console.error("MeoNode: Error executing function-as-a-child.",a),b=null}// Handle null or undefined results directly, as they are valid React render outputs.
|
|
141
|
+
if(null===b||b===void 0)return b;// If the result is already a BaseNode instance, process it.
|
|
142
|
+
if(isNodeInstance(b))// If emotion is disabled for the parent and not explicitly re-enabled on the child,
|
|
143
|
+
// create a new BaseNode with emotion disabled and render it.
|
|
144
|
+
return d&&!b.rawProps.disableEmotion?new BaseNode(b.element,_objectSpread(_objectSpread({},b.rawProps),{},{disableEmotion:!0})).render():b.render();// Otherwise, render the existing BaseNode directly.
|
|
145
|
+
// If the result is an array, it likely contains multiple children.
|
|
146
|
+
if(Array.isArray(b)){// Helper to generate a stable key for array items, crucial for React's reconciliation.
|
|
147
|
+
var e=function safeGetKey(a,b){try{// Attempt to get a meaningful name for the element type.
|
|
148
|
+
return"".concat(getElementTypeName(a),"-").concat(b)}catch(a){// Fallback to a generic key if type name cannot be determined.
|
|
149
|
+
return __DEV__&&console.error("MeoNode: Could not determine element type name for key in function-as-a-child.",a),"item-".concat(b)}};// Map over the array, processing each item and assigning a key.
|
|
150
|
+
return b.map(function(a,b){return BaseNode._renderProcessedNode({processedElement:BaseNode._processRawNode(a,d),passedKey:e(a,b)})})}if(b instanceof React.Component)return BaseNode._renderProcessedNode({processedElement:BaseNode._processRawNode(b.render(),d),disableEmotion:d});// Handle primitive types directly, as they are valid React children.
|
|
151
|
+
if("string"==typeof b||"number"==typeof b||"boolean"==typeof b)return b;// For any other non-primitive, non-array result, process it as a single NodeElement.
|
|
152
|
+
var f=BaseNode._processRawNode(b,d);// If processing yields a valid element, render it.
|
|
153
|
+
return f?BaseNode._renderProcessedNode({processedElement:f,disableEmotion:d}):b;// Fallback: return the original result if it couldn't be processed into a renderable node.
|
|
154
|
+
}/**
|
|
155
|
+
* Renders a processed `NodeElement` into a ReactNode.
|
|
156
|
+
* This helper is primarily used by `_functionRenderer` to handle the output of render props,
|
|
157
|
+
* ensuring that `BaseNode` instances are correctly rendered and other React elements or primitives
|
|
158
|
+
* are passed through. It also applies `disableEmotion` and `key` props as needed.
|
|
159
|
+
*
|
|
160
|
+
* This method is part of the child processing pipeline, converting internal `NodeElement` representations
|
|
161
|
+
* into actual React elements that can be rendered by React.
|
|
120
162
|
* @method _renderProcessedNode
|
|
121
|
-
*/static _renderProcessedNode(a){var b=a.processedElement,c=a.passedKey,d=a.disableEmotion,e={}
|
|
163
|
+
*/static _renderProcessedNode(a){var b=a.processedElement,c=a.passedKey,d=a.disableEmotion,e={};// Initialize an object to hold common props that might be applied to the new BaseNode.
|
|
164
|
+
// If a `passedKey` is provided, add it to `commonBaseNodeProps`.
|
|
165
|
+
// This key is typically used for React's reconciliation process.
|
|
166
|
+
// If the processed element is already a BaseNode instance.
|
|
167
|
+
if(void 0!==c&&(e.key=c),isNodeInstance(b)){var f,g=null===(f=b.rawProps)||void 0===f?void 0:f.key;// Get the existing key from the raw props of the BaseNode.
|
|
168
|
+
// Apply the `disableEmotion` flag to the raw props of the BaseNode.
|
|
169
|
+
// If the existing key is the same as the passed key, render the existing BaseNode directly.
|
|
170
|
+
// This avoids unnecessary re-creation of the BaseNode instance.
|
|
171
|
+
return b.rawProps.disableEmotion=d,g===c?b.render():new BaseNode(b.element,_objectSpread(_objectSpread({},b.rawProps),e)).render();// Otherwise, create a new BaseNode instance, merging existing raw props with common props, then render it.
|
|
172
|
+
}// If the processed element is a React class component (e.g., `class MyComponent extends React.Component`).
|
|
173
|
+
// Create a new BaseNode for it, applying common props and `disableEmotion`, then render.
|
|
174
|
+
return isReactClassComponent(b)?new BaseNode(b,_objectSpread(_objectSpread({},e),{},{disableEmotion:d})).render():b instanceof React.Component?b.render():"function"==typeof b?createElement(b,{key:c}):b;// If the processed element is an instance of a React component (e.g., `new MyComponent()`).
|
|
175
|
+
// Directly call its `render` method.
|
|
176
|
+
// If the processed element is a function (likely a functional component or a render prop that returned a component type).
|
|
177
|
+
// Create a React element directly using `createElement`, passing the `passedKey`.
|
|
178
|
+
// For any other type (primitives, null, undefined, etc.), return it as a ReactNode.
|
|
179
|
+
}// --- Iterative Renderer with Deps Support ---
|
|
122
180
|
/**
|
|
123
181
|
* Renders the `BaseNode` and its entire subtree into a ReactElement, with support for opt-in reactivity
|
|
124
182
|
* via dependency arrays and inherited blocking.
|
|
@@ -132,21 +190,48 @@ return isReactClassComponent(a)||isMemo(a)||isForwardRef(a)?new BaseNode(a,{disa
|
|
|
132
190
|
* 2. **Complete Phase:** After all of a node's descendants have been rendered, the loop returns to the node.
|
|
133
191
|
* It then collects the rendered children from a temporary map and creates its own React element.
|
|
134
192
|
* @method render
|
|
135
|
-
*/render(){var a=!!(0<arguments.length&&arguments[0]!==void 0)&&arguments[0]
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
193
|
+
*/render(){var a=!!(0<arguments.length&&arguments[0]!==void 0)&&arguments[0];BaseNode._isServer||MountTracker.trackMount(this);// A stable cache key derived from the element + important props signature.
|
|
194
|
+
var b=this._stableKey,c=BaseNode._isServer?void 0:BaseNode._elementCache.get(b),d=BaseNode._shouldNodeUpdate(null===c||void 0===c?void 0:c.prevDeps,this._deps,a);// On server we never reuse cached elements because that can cause hydration mismatches.
|
|
195
|
+
// Decide whether this node (and its subtree) should update given dependency arrays.
|
|
196
|
+
// Fast return: if nothing should update and we have a cached element, reuse it.
|
|
197
|
+
if(!d&&null!==c&&void 0!==c&&c.renderedElement)return c.accessCount+=1,c.renderedElement;// When this node doesn't need update, its children are considered "blocked" and may be skipped.
|
|
198
|
+
// Work stack for iterative, non-recursive traversal.
|
|
199
|
+
// Each entry tracks the BaseNode, whether its children were pushed (isProcessed) and whether it is blocked.
|
|
200
|
+
// Map to collect rendered React elements for processed BaseNode instances.
|
|
201
|
+
// Iterative depth-first traversal with explicit begin/complete phases to avoid recursion.
|
|
202
|
+
for(var e=[{node:this,isProcessed:!1,blocked:!d}],f=new Map,g=function _loop(){var a=e[e.length-1],b=a.node,c=a.isProcessed,d=a.blocked;if(!c){a.isProcessed=!0;var g=b.props.children;if(g)// Only consider BaseNode children for further traversal; primitives and React elements are terminal.
|
|
203
|
+
for(var h=(Array.isArray(g)?g:[g]).filter(isNodeInstance),j=h.length-1;0<=j;j--){var k=h[j],l=k._stableKey,m=BaseNode._isServer?void 0:BaseNode._elementCache.get(l),n=BaseNode._shouldNodeUpdate(null===m||void 0===m?void 0:m.prevDeps,k._deps,d);// Respect server/client differences for child cache lookup.
|
|
204
|
+
// Determine whether the child should update given its deps and the parent's blocked state.
|
|
205
|
+
// If child doesn't need update and has cached element, reuse it immediately (no push).
|
|
206
|
+
if(!n&&null!==m&&void 0!==m&&m.renderedElement){f.set(k,m.renderedElement);continue}// Otherwise push child for processing; childBlocked inherits parent's blocked state.
|
|
207
|
+
var o=d||!n;e.push({node:k,isProcessed:!1,blocked:o})}}else{e.pop();// Extract node props. Non-present props default to undefined via destructuring.
|
|
208
|
+
var p=b.props,q=p.children,r=p.key,s=p.css,t=p.nativeProps,u=p.disableEmotion,v=_objectWithoutProperties(p,_excluded4),w=[];q&&(w=(Array.isArray(q)?q:[q]).map(function(a){return isNodeInstance(a)?f.get(a):isValidElement(a)?a:a}));// Merge element props: explicit other props + DOM native props + React key.
|
|
209
|
+
var x,y=_objectSpread(_objectSpread({},v),{},{key:r},t);// Handle fragments specially: create fragment element with key and children.
|
|
210
|
+
if(b.element===Fragment||isFragment(b.element))x=createElement(b.element,{key:r},...w);else{// StyledRenderer for emotion-based styling unless explicitly disabled or no styles are present.
|
|
211
|
+
// StyledRenderer handles SSR hydration and emotion CSS injection when css prop exists or element has style tags.
|
|
212
|
+
var z=!u&&(s||!hasNoStyleTag(b.element));x=z?createElement(StyledRenderer,_objectSpread(_objectSpread({element:b.element},y),{},{css:s,suppressHydrationWarning:!0}),...w):createElement(b.element,y,...w)}// Cache the generated element on client-side to speed up future renders.
|
|
213
|
+
if(!BaseNode._isServer){var A={prevDeps:b._deps,renderedElement:x,onEvict:function onEvict(){return MountTracker.trackUnmount(b)},nodeRef:new WeakRef(b),createdAt:Date.now(),accessCount:1};BaseNode._elementCache.set(b._stableKey,A)}// Store the rendered element so parent nodes can reference it.
|
|
214
|
+
f.set(b,x)}};0<e.length;)g();// Return the ReactElement corresponding to the root node (this).
|
|
215
|
+
return f.get(this)}/**
|
|
216
|
+
* Registers a node instance with the MountTracker for unmount tracking.
|
|
217
|
+
* This is only executed on the client-side.
|
|
218
|
+
* @method registerUnmount
|
|
219
|
+
*/static registerUnmount(a){BaseNode._isServer||MountTracker.trackUnmount(a)}// --- Portal System ---
|
|
141
220
|
/**
|
|
142
221
|
* Ensures that the necessary DOM element and React root are available for portal rendering.
|
|
143
222
|
* This is only executed on the client-side.
|
|
144
223
|
* @method _ensurePortalInfrastructure
|
|
145
|
-
*/_ensurePortalInfrastructure(){if(BaseNode._isServer)return!1;
|
|
224
|
+
*/_ensurePortalInfrastructure(){var a,b;if(BaseNode._isServer)return!1;var c=BaseNode._portalInfrastructure.get(this);// Check if infrastructure exists and is still connected
|
|
225
|
+
if(null!==(a=c)&&void 0!==a&&null!==(a=a.domElement)&&void 0!==a&&a.isConnected)return!0;// Clean up disconnected infrastructure
|
|
226
|
+
if(null!==(b=c)&&void 0!==b&&b.domElement&&!c.domElement.isConnected){try{c.reactRoot.unmount()}catch(a){__DEV__&&console.error("MeoNode: Error unmounting disconnected portal root.",a)}BaseNode._portalInfrastructure["delete"](this),c=void 0}// Create new infrastructure
|
|
227
|
+
var d=document.createElement("div");document.body.appendChild(d);var e=createRoot(d),f={render:e.render.bind(e),unmount:e.unmount.bind(e),update:function update(){}// Placeholder, will be overridden
|
|
228
|
+
};return c={domElement:d,reactRoot:f},BaseNode._portalInfrastructure.set(this,c),!0}/**
|
|
146
229
|
* Renders the node into a React Portal, mounting it directly under `document.body`.
|
|
147
230
|
* Returns a handle with `update` and `unmount` methods to control the portal's lifecycle.
|
|
148
231
|
* @method toPortal
|
|
149
|
-
*/toPortal(){var a=this;if(!this._ensurePortalInfrastructure()
|
|
232
|
+
*/toPortal(){var a=this;if(!this._ensurePortalInfrastructure())throw new Error("toPortal() can only be called in a client-side environment where document.body is available.");var b=BaseNode._portalInfrastructure.get(this),c=b.domElement,d=b.reactRoot;(function renderCurrent(){try{d.render(a.render())}catch(a){__DEV__&&console.error("MeoNode: Error rendering initial portal content.",a)}})();try{var e=d.unmount.bind(d);// Override update method
|
|
233
|
+
return d.update=function(a){try{var b=isNodeInstance(a)?a.render():a;d.render(b)}catch(a){__DEV__&&console.error("MeoNode: Error updating portal content.",a)}},d.unmount=function(){try{e()}catch(a){__DEV__&&console.error("MeoNode: Error unmounting portal root.",a)}if(c.parentNode)try{c.parentNode.removeChild(c)}catch(a){__DEV__&&console.error("MeoNode: Error removing portal DOM element.",a)}// Clean up from WeakMap
|
|
234
|
+
BaseNode._portalInfrastructure["delete"](a)},d}catch(a){return __DEV__&&console.error("MeoNode: Error creating portal handle.",a),d}}/**
|
|
150
235
|
* A static method to clear all internal caches.
|
|
151
236
|
* @method clearCaches
|
|
152
237
|
*/static clearCaches(){BaseNode._propProcessingCache.clear(),BaseNode._elementCache.clear()}}// --- Factory Functions ---
|
|
@@ -154,7 +239,21 @@ BaseNode._isServer||BaseNode._elementCache.set(h._stableKey,{prevDeps:h._deps,ca
|
|
|
154
239
|
* The primary factory function for creating a `BaseNode` instance.
|
|
155
240
|
* It's the simplest way to wrap a component or element.
|
|
156
241
|
* @function Node
|
|
157
|
-
*/_BaseNode=BaseNode,_defineProperty(BaseNode,"_isServer","undefined"==typeof window),_defineProperty(BaseNode,"_propProcessingCache",new Map),_defineProperty(BaseNode,"
|
|
242
|
+
*/_BaseNode=BaseNode,_defineProperty(BaseNode,"_isServer","undefined"==typeof window),_defineProperty(BaseNode,"_propProcessingCache",new Map),_defineProperty(BaseNode,"_isValidElement",isValidElementType),_defineProperty(BaseNode,"_isStyleProp",_BaseNode._isServer||"undefined"==typeof document?function(){return!1}:function(a){return a in document.body.style}),_defineProperty(BaseNode,"_elementCache",new Map),_defineProperty(BaseNode,"_portalInfrastructure",new WeakMap),_defineProperty(BaseNode,"CACHE_SIZE_LIMIT",500),_defineProperty(BaseNode,"CACHE_CLEANUP_BATCH",50),_defineProperty(BaseNode,"_elementIdMap",new WeakMap),_defineProperty(BaseNode,"_elementIdCounter",0),_defineProperty(BaseNode,"_scheduledCleanup",!1),_defineProperty(BaseNode,"_navigationStarted",!1);function Node(a){var b=1<arguments.length&&arguments[1]!==void 0?arguments[1]:{},c=2<arguments.length?arguments[2]:void 0;return new BaseNode(a,b,c)}/**
|
|
243
|
+
* Static alias on the `Node` factory for clearing all internal caches used by `BaseNode`.
|
|
244
|
+
*
|
|
245
|
+
* Use cases include:
|
|
246
|
+
* - resetting state between tests,
|
|
247
|
+
* - hot-module-replacement (HMR) cycles,
|
|
248
|
+
* - manual resets in development,
|
|
249
|
+
* - or during SPA navigation to avoid stale cached elements/styles.
|
|
250
|
+
*
|
|
251
|
+
* Notes:
|
|
252
|
+
* - Clears only internal prop/element caches; does not touch portal infrastructure or external runtime state.
|
|
253
|
+
* - Safe to call on the server, but most useful on the client.
|
|
254
|
+
* @method Node.clearCaches
|
|
255
|
+
*/Node.clearCaches=BaseNode.clearCaches;// Export the Node factory as the main export
|
|
256
|
+
export{Node};/**
|
|
158
257
|
* Creates a curried node factory for a given React element or component type.
|
|
159
258
|
* This is useful for creating reusable, specialized factory functions (e.g., `const Div = createNode('div')`).
|
|
160
259
|
* @function createNode
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { BaseNode } from '../core.node.js';
|
|
2
|
+
/**
|
|
3
|
+
* MountTracker keeps track of which BaseNode instances are currently mounted in the DOM.
|
|
4
|
+
* It listens for navigation events to trigger cleanup of unmounted nodes from the cache.
|
|
5
|
+
*/
|
|
6
|
+
export declare class MountTracker {
|
|
7
|
+
private static _mountedNodes;
|
|
8
|
+
private static _navigationListener;
|
|
9
|
+
static trackMount(node: BaseNode<any>): void;
|
|
10
|
+
static trackUnmount(node: BaseNode<any>): void;
|
|
11
|
+
static isMounted(node: BaseNode<any>): boolean;
|
|
12
|
+
private static _ensureNavigationListener;
|
|
13
|
+
private static _onNavigation;
|
|
14
|
+
static cleanup(): void;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=mount-tracker.helper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mount-tracker.helper.d.ts","sourceRoot":"","sources":["../../src/helper/mount-tracker.helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAG5C;;;GAGG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,aAAa,CAAoB;IAChD,OAAO,CAAC,MAAM,CAAC,mBAAmB,CAA4B;IAE9D,OAAc,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,QAG3C;IAED,OAAc,YAAY,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,QAE7C;IAED,OAAc,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,OAAO,CAEpD;IAED,OAAO,CAAC,MAAM,CAAC,yBAAyB;IAuBxC,OAAO,CAAC,MAAM,CAAC,aAAa;IAoB5B,OAAc,OAAO,SAMpB;CACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
function _typeof(a){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},_typeof(a)}function _slicedToArray(a,b){return _arrayWithHoles(a)||_iterableToArrayLimit(a,b)||_unsupportedIterableToArray(a,b)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _iterableToArrayLimit(b,c){var d=null==b?null:"undefined"!=typeof Symbol&&b[Symbol.iterator]||b["@@iterator"];if(null!=d){var g,h,j,k,l=[],a=!0,m=!1;try{if(j=(d=d.call(b)).next,0===c){if(Object(d)!==d)return;a=!1}else for(;!(a=(g=j.call(d)).done)&&(l.push(g.value),l.length!==c);a=!0);}catch(a){m=!0,h=a}finally{try{if(!a&&null!=d["return"]&&(k=d["return"](),Object(k)!==k))return}finally{if(m)throw h}}return l}}function _arrayWithHoles(a){if(Array.isArray(a))return a}function _createForOfIteratorHelper(b,c){var d="undefined"!=typeof Symbol&&b[Symbol.iterator]||b["@@iterator"];if(!d){if(Array.isArray(b)||(d=_unsupportedIterableToArray(b))||c&&b&&"number"==typeof b.length){d&&(b=d);var e=0,f=function F(){};return{s:f,n:function n(){return e>=b.length?{done:!0}:{done:!1,value:b[e++]}},e:function e(a){throw a},f:f}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var g,h=!0,i=!1;return{s:function s(){d=d.call(b)},n:function n(){var a=d.next();return h=a.done,a},e:function e(a){i=!0,g=a},f:function f(){try{h||null==d["return"]||d["return"]()}finally{if(i)throw g}}}}function _unsupportedIterableToArray(b,c){if(b){if("string"==typeof b)return _arrayLikeToArray(b,c);var a={}.toString.call(b).slice(8,-1);return"Object"===a&&b.constructor&&(a=b.constructor.name),"Map"===a||"Set"===a?Array.from(b):"Arguments"===a||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(a)?_arrayLikeToArray(b,c):void 0}}function _arrayLikeToArray(b,c){(null==c||c>b.length)&&(c=b.length);for(var d=0,f=Array(c);d<c;d++)f[d]=b[d];return f}function _defineProperty(a,b,c){return(b=_toPropertyKey(b))in a?Object.defineProperty(a,b,{value:c,enumerable:!0,configurable:!0,writable:!0}):a[b]=c,a}function _toPropertyKey(a){var b=_toPrimitive(a,"string");return"symbol"==_typeof(b)?b:b+""}function _toPrimitive(a,b){if("object"!=_typeof(a)||!a)return a;var c=a[Symbol.toPrimitive];if(void 0!==c){var d=c.call(a,b||"default");if("object"!=_typeof(d))return d;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===b?String:Number)(a)}import{BaseNode}from"../core.node.js";import{__DEV__}from"../constants/common.const.js";/**
|
|
2
|
+
* MountTracker keeps track of which BaseNode instances are currently mounted in the DOM.
|
|
3
|
+
* It listens for navigation events to trigger cleanup of unmounted nodes from the cache.
|
|
4
|
+
*/export class MountTracker{static trackMount(a){this._mountedNodes.add(a._stableKey),this._ensureNavigationListener()}static trackUnmount(a){this._mountedNodes["delete"](a._stableKey)}static isMounted(a){return this._mountedNodes.has(a._stableKey)}static _ensureNavigationListener(){var a=this;if(!(this._navigationListener||"undefined"==typeof window)){this._navigationListener=function(){return a._onNavigation()},window.addEventListener("popstate",this._navigationListener);// Override pushState/replaceState
|
|
5
|
+
var b=history.pushState;history.pushState=function(){for(var a,c=arguments.length,d=Array(c),e=0;e<c;e++)d[e]=arguments[e];b.apply(this,d),null===(a=MountTracker._navigationListener)||void 0===a||a.call(MountTracker)};var c=history.replaceState;history.replaceState=function(){for(var a,b=arguments.length,d=Array(b),e=0;e<b;e++)d[e]=arguments[e];c.apply(this,d),null===(a=MountTracker._navigationListener)||void 0===a||a.call(MountTracker)}}// Single listener for all navigation events
|
|
6
|
+
}static _onNavigation(){// Only clear cache for UNMOUNTED nodes
|
|
7
|
+
var a,b=[],c=_createForOfIteratorHelper(BaseNode._elementCache.entries());try{for(c.s();!(a=c.n()).done;){var d=_slicedToArray(a.value,1),e=d[0];this._mountedNodes.has(e)||b.push(e)}// Clear only unmounted nodes
|
|
8
|
+
}catch(a){c.e(a)}finally{c.f()}b.forEach(function(a){return BaseNode._elementCache["delete"](a)}),__DEV__&&console.log("MeoNode: Cleared ".concat(b.length," unmounted elements on navigation"))}static cleanup(){this._navigationListener&&(window.removeEventListener("popstate",this._navigationListener),this._navigationListener=null),this._mountedNodes.clear()}}_defineProperty(MountTracker,"_mountedNodes",new Set),_defineProperty(MountTracker,"_navigationListener",null);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NavigationCacheManager listens for navigation events in the browser
|
|
3
|
+
* and triggers safe cleanup of the element cache to prevent memory leaks.
|
|
4
|
+
* It supports standard browser navigation as well as SPA routing changes.
|
|
5
|
+
*/
|
|
6
|
+
export declare class NavigationCacheManager {
|
|
7
|
+
private static _instance;
|
|
8
|
+
private _isListening;
|
|
9
|
+
private _cleanupTimeout;
|
|
10
|
+
static getInstance(): NavigationCacheManager;
|
|
11
|
+
/**
|
|
12
|
+
* Starts listening for navigation events to trigger cache cleanup.
|
|
13
|
+
* This method is idempotent and safe to call multiple times.
|
|
14
|
+
*/
|
|
15
|
+
start(): void;
|
|
16
|
+
/**
|
|
17
|
+
* Stops listening for navigation events.
|
|
18
|
+
*/
|
|
19
|
+
stop(): void;
|
|
20
|
+
private _handleNavigation;
|
|
21
|
+
private _patchHistoryMethods;
|
|
22
|
+
private _setupReactRouterIntegration;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=navigation-cache-manager.helper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation-cache-manager.helper.d.ts","sourceRoot":"","sources":["../../src/helper/navigation-cache-manager.helper.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAsC;IAC9D,OAAO,CAAC,YAAY,CAAQ;IAC5B,OAAO,CAAC,eAAe,CAAY;IAEnC,OAAc,WAAW,IAAI,sBAAsB,CAKlD;IAED;;;OAGG;IACI,KAAK,SAaX;IAED;;OAEG;IACI,IAAI,SAaV;IAED,OAAO,CAAC,iBAAiB,CAWxB;IAED,OAAO,CAAC,oBAAoB;IAe5B,OAAO,CAAC,4BAA4B;CAqBrC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
function _typeof(a){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},_typeof(a)}function _defineProperty(a,b,c){return(b=_toPropertyKey(b))in a?Object.defineProperty(a,b,{value:c,enumerable:!0,configurable:!0,writable:!0}):a[b]=c,a}function _toPropertyKey(a){var b=_toPrimitive(a,"string");return"symbol"==_typeof(b)?b:b+""}function _toPrimitive(a,b){if("object"!=_typeof(a)||!a)return a;var c=a[Symbol.toPrimitive];if(void 0!==c){var d=c.call(a,b||"default");if("object"!=_typeof(d))return d;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===b?String:Number)(a)}import{SafeCacheManager}from"./safe-cache-manager.helper.js";import{__DEV__}from"../constants/common.const.js";/**
|
|
2
|
+
* NavigationCacheManager listens for navigation events in the browser
|
|
3
|
+
* and triggers safe cleanup of the element cache to prevent memory leaks.
|
|
4
|
+
* It supports standard browser navigation as well as SPA routing changes.
|
|
5
|
+
*/export class NavigationCacheManager{constructor(){var a=this;_defineProperty(this,"_isListening",!1),_defineProperty(this,"_cleanupTimeout",null),_defineProperty(this,"_handleNavigation",function(){a._cleanupTimeout&&clearTimeout(a._cleanupTimeout),a._cleanupTimeout=setTimeout(function(){var a=SafeCacheManager.safeCleanup();__DEV__&&console.log("MeoNode: Navigation detected. Safely evicted ".concat(a," unmounted elements from cache."))},100)})}static getInstance(){return this._instance||(this._instance=new NavigationCacheManager),this._instance}/**
|
|
6
|
+
* Starts listening for navigation events to trigger cache cleanup.
|
|
7
|
+
* This method is idempotent and safe to call multiple times.
|
|
8
|
+
*/start(){this._isListening||"undefined"==typeof window||(// Listen for standard browser navigation event.
|
|
9
|
+
// Patch history methods to catch SPA routing changes.
|
|
10
|
+
// Attempt to integrate with React Router if present.
|
|
11
|
+
this._isListening=!0,window.addEventListener("popstate",this._handleNavigation),this._patchHistoryMethods(),this._setupReactRouterIntegration())}/**
|
|
12
|
+
* Stops listening for navigation events.
|
|
13
|
+
*/stop(){this._isListening&&"undefined"!=typeof window&&(window.removeEventListener("popstate",this._handleNavigation),this._cleanupTimeout&&clearTimeout(this._cleanupTimeout),this._isListening=!1)}_patchHistoryMethods(){var a=this,b=history.pushState,c=history.replaceState;history.pushState=function(){for(var c=arguments.length,d=Array(c),e=0;e<c;e++)d[e]=arguments[e];b.apply(history,d),a._handleNavigation()},history.replaceState=function(){for(var b=arguments.length,d=Array(b),e=0;e<b;e++)d[e]=arguments[e];c.apply(history,d),a._handleNavigation()}}_setupReactRouterIntegration(){// This is a speculative integration attempt for React Router.
|
|
14
|
+
// It relies on specific global objects that may not always be present.
|
|
15
|
+
// A more robust solution would involve context or direct history listening if available.
|
|
16
|
+
if(window.__REACT_ROUTER__){// The following is an example of how one might patch `useNavigate`.
|
|
17
|
+
// This is highly experimental and may not work with all versions of React Router.
|
|
18
|
+
var a=window.ReactRouter;if(a&&"function"==typeof a.useNavigate){var b=a.useNavigate;a.useNavigate=function(){for(var a=arguments.length,c=Array(a),d=0;d<a;d++)c[d]=arguments[d];var e=b.apply(this,c);return function(){var a=e(...arguments);return NavigationCacheManager.getInstance()._handleNavigation(),a}}}}}}_defineProperty(NavigationCacheManager,"_instance",null);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SafeCacheManager provides methods to clean up the element cache
|
|
3
|
+
* in a way that minimizes the risk of removing elements that are still in use.
|
|
4
|
+
* It uses various eviction policies to determine which entries can be safely removed.
|
|
5
|
+
*/
|
|
6
|
+
export declare class SafeCacheManager {
|
|
7
|
+
private static _evictionPolicies;
|
|
8
|
+
/**
|
|
9
|
+
* Performs a safe cleanup of the element cache.
|
|
10
|
+
* It applies standard eviction policies to remove unmounted and old entries.
|
|
11
|
+
* This is typically called after a navigation event.
|
|
12
|
+
*/
|
|
13
|
+
static safeCleanup(): number;
|
|
14
|
+
/**
|
|
15
|
+
* Performs an emergency cleanup of the element cache.
|
|
16
|
+
* This uses a more aggressive eviction policy and is intended to be called
|
|
17
|
+
* when memory pressure is detected.
|
|
18
|
+
*/
|
|
19
|
+
static emergencyCleanup(): number;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=safe-cache-manager.helper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safe-cache-manager.helper.d.ts","sourceRoot":"","sources":["../../src/helper/safe-cache-manager.helper.ts"],"names":[],"mappings":"AAwBA;;;;GAIG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAgD/B;IAED;;;;OAIG;IACH,OAAc,WAAW,IAAI,MAAM,CAclC;IAED;;;;OAIG;IACH,OAAc,gBAAgB,IAAI,MAAM,CAUvC;CACF"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
function _slicedToArray(a,b){return _arrayWithHoles(a)||_iterableToArrayLimit(a,b)||_unsupportedIterableToArray(a,b)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _iterableToArrayLimit(b,c){var d=null==b?null:"undefined"!=typeof Symbol&&b[Symbol.iterator]||b["@@iterator"];if(null!=d){var g,h,j,k,l=[],a=!0,m=!1;try{if(j=(d=d.call(b)).next,0===c){if(Object(d)!==d)return;a=!1}else for(;!(a=(g=j.call(d)).done)&&(l.push(g.value),l.length!==c);a=!0);}catch(a){m=!0,h=a}finally{try{if(!a&&null!=d["return"]&&(k=d["return"](),Object(k)!==k))return}finally{if(m)throw h}}return l}}function _arrayWithHoles(a){if(Array.isArray(a))return a}function _defineProperty(a,b,c){return(b=_toPropertyKey(b))in a?Object.defineProperty(a,b,{value:c,enumerable:!0,configurable:!0,writable:!0}):a[b]=c,a}function _toPropertyKey(a){var b=_toPrimitive(a,"string");return"symbol"==_typeof(b)?b:b+""}function _toPrimitive(a,b){if("object"!=_typeof(a)||!a)return a;var c=a[Symbol.toPrimitive];if(void 0!==c){var d=c.call(a,b||"default");if("object"!=_typeof(d))return d;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===b?String:Number)(a)}function _typeof(a){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},_typeof(a)}function _createForOfIteratorHelper(b,c){var d="undefined"!=typeof Symbol&&b[Symbol.iterator]||b["@@iterator"];if(!d){if(Array.isArray(b)||(d=_unsupportedIterableToArray(b))||c&&b&&"number"==typeof b.length){d&&(b=d);var e=0,f=function F(){};return{s:f,n:function n(){return e>=b.length?{done:!0}:{done:!1,value:b[e++]}},e:function e(a){throw a},f:f}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var g,h=!0,i=!1;return{s:function s(){d=d.call(b)},n:function n(){var a=d.next();return h=a.done,a},e:function e(a){i=!0,g=a},f:function f(){try{h||null==d["return"]||d["return"]()}finally{if(i)throw g}}}}function _unsupportedIterableToArray(b,c){if(b){if("string"==typeof b)return _arrayLikeToArray(b,c);var a={}.toString.call(b).slice(8,-1);return"Object"===a&&b.constructor&&(a=b.constructor.name),"Map"===a||"Set"===a?Array.from(b):"Arguments"===a||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(a)?_arrayLikeToArray(b,c):void 0}}function _arrayLikeToArray(b,c){(null==c||c>b.length)&&(c=b.length);for(var d=0,f=Array(c);d<c;d++)f[d]=b[d];return f}import{BaseNode}from"../core.node.js";import{MountTracker}from"./mount-tracker.helper.js";// Estimates the "size" of a React element based on its props and children.
|
|
2
|
+
// This is a heuristic to help with eviction decisions.
|
|
3
|
+
function _estimateElementSize(a){if(!a)return 0;var b=1;if(a.props&&(b+=Object.keys(a.props).length,a.props.children)){var c,d=Array.isArray(a.props.children)?a.props.children:[a.props.children],e=_createForOfIteratorHelper(d);try{for(e.s();!(c=e.n()).done;){var f=c.value;"object"===_typeof(f)&&null!==f&&"props"in f&&(b+=_estimateElementSize(f))}}catch(a){e.e(a)}finally{e.f()}}return b}/**
|
|
4
|
+
* SafeCacheManager provides methods to clean up the element cache
|
|
5
|
+
* in a way that minimizes the risk of removing elements that are still in use.
|
|
6
|
+
* It uses various eviction policies to determine which entries can be safely removed.
|
|
7
|
+
*/export class SafeCacheManager{/**
|
|
8
|
+
* Performs a safe cleanup of the element cache.
|
|
9
|
+
* It applies standard eviction policies to remove unmounted and old entries.
|
|
10
|
+
* This is typically called after a navigation event.
|
|
11
|
+
*/static safeCleanup(){var a,b=[this._evictionPolicies.evictUnmounted,this._evictionPolicies.evictOldUnmounted],c=0,d=_createForOfIteratorHelper(BaseNode._elementCache.entries());try{var e=function _loop(){var d=_slicedToArray(a.value,2),e=d[0],f=d[1];// An entry is evicted if ANY policy decides it should be.
|
|
12
|
+
if(b.some(function(a){return a(f)})){var g;// Trigger unmount tracking.
|
|
13
|
+
null===(g=f.onEvict)||void 0===g||g.call(f),BaseNode._elementCache["delete"](e),c++}};for(d.s();!(a=d.n()).done;)e()}catch(a){d.e(a)}finally{d.f()}return c}/**
|
|
14
|
+
* Performs an emergency cleanup of the element cache.
|
|
15
|
+
* This uses a more aggressive eviction policy and is intended to be called
|
|
16
|
+
* when memory pressure is detected.
|
|
17
|
+
*/static emergencyCleanup(){var a,b=0,c=_createForOfIteratorHelper(BaseNode._elementCache.entries());try{for(c.s();!(a=c.n()).done;){var d=_slicedToArray(a.value,2),e=d[0],f=d[1];if(this._evictionPolicies.emergencyEviction(f)){var g;null===(g=f.onEvict)||void 0===g||g.call(f),BaseNode._elementCache["delete"](e),b++}}}catch(a){c.e(a)}finally{c.f()}return b}}_defineProperty(SafeCacheManager,"_evictionPolicies",{/**
|
|
18
|
+
* Evicts entries that are either not mounted or whose node instance has been garbage-collected.
|
|
19
|
+
* This is the primary policy for preventing memory leaks from stale cache entries.
|
|
20
|
+
*/evictUnmounted:function evictUnmounted(a){var b=a.nodeRef.deref();return!b||!MountTracker.isMounted(b)},/**
|
|
21
|
+
* Evicts unmounted entries that are older than a specified threshold (e.g., 10 minutes).
|
|
22
|
+
* This is useful for cleaning up caches during long-running sessions.
|
|
23
|
+
*/evictOldUnmounted:function evictOldUnmounted(a){var b=a.nodeRef.deref();return!b||!MountTracker.isMounted(b)&&Date.now()-a.createdAt>600000;// 10 minutes
|
|
24
|
+
},/**
|
|
25
|
+
* An aggressive eviction policy for high memory pressure scenarios.
|
|
26
|
+
* It preserves mounted components but otherwise evicts based on a score
|
|
27
|
+
* calculated from element size and usage frequency.
|
|
28
|
+
*/emergencyEviction:function emergencyEviction(a){var b=a.nodeRef.deref();if(!b)return!0;// Evict if GC'd
|
|
29
|
+
if(MountTracker.isMounted(b))return!1;// Still preserve mounted components.
|
|
30
|
+
// Preferentially evict large, infrequently used components.
|
|
31
|
+
var c=_estimateElementSize(a.renderedElement),d=1e3/(a.accessCount+1);// Inversely proportional to access count.
|
|
32
|
+
return 1e3<c*d;// Eviction threshold.
|
|
33
|
+
}});
|
|
@@ -2,6 +2,7 @@ import React, { type CSSProperties, type ReactNode, type JSX, type ElementType,
|
|
|
2
2
|
import type { NO_STYLE_TAGS } from '../constants/common.const.js';
|
|
3
3
|
import type { ComponentNodeProps } from '../hoc/component.hoc.js';
|
|
4
4
|
import type { CSSObject, CSSInterpolation } from '@emotion/serialize';
|
|
5
|
+
import { BaseNode } from '../core.node.js';
|
|
5
6
|
type RequiredKeys<T> = {
|
|
6
7
|
[K in keyof T]-?: object extends Pick<T, K> ? never : K;
|
|
7
8
|
}[keyof T];
|
|
@@ -43,6 +44,18 @@ export interface PropProcessingCache {
|
|
|
43
44
|
lastAccess: number;
|
|
44
45
|
hitCount: number;
|
|
45
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Represents an entry in the element cache.
|
|
49
|
+
* Stores the rendered React element and its previous dependencies for memoization.
|
|
50
|
+
*/
|
|
51
|
+
export interface ElementCacheEntry {
|
|
52
|
+
renderedElement: ReactElement<FinalNodeProps>;
|
|
53
|
+
prevDeps?: DependencyList;
|
|
54
|
+
onEvict: () => void;
|
|
55
|
+
nodeRef: WeakRef<BaseNode<any>>;
|
|
56
|
+
createdAt: number;
|
|
57
|
+
accessCount: number;
|
|
58
|
+
}
|
|
46
59
|
/**
|
|
47
60
|
* Forward declaration of the BaseNode interface to avoid circular dependencies.
|
|
48
61
|
* Defines the core structure and capabilities of a BaseNode instance.
|
|
@@ -56,6 +69,8 @@ export interface NodeInstance<E extends NodeElement = NodeElement> {
|
|
|
56
69
|
readonly isBaseNode: true;
|
|
57
70
|
/** The dependency list for memoization */
|
|
58
71
|
readonly dependencies: DependencyList | undefined;
|
|
72
|
+
/** Lazily processed and retrieved final, normalized props for the node. */
|
|
73
|
+
readonly props: FinalNodeProps;
|
|
59
74
|
/** Converts this node instance into a renderable React element/tree */
|
|
60
75
|
render(): ReactElement;
|
|
61
76
|
/** Creates Portal-compatible React elements for rendering outside the DOM tree */
|
|
@@ -111,9 +126,10 @@ export type FinalNodeProps = ReactAttributes & Partial<{
|
|
|
111
126
|
nativeProps: Omit<Omit<PropsOf<NodeElement>, 'children'>, 'style'>;
|
|
112
127
|
ref: any | React.Ref<unknown> | undefined;
|
|
113
128
|
style: any;
|
|
114
|
-
css:
|
|
129
|
+
css: CssProp;
|
|
115
130
|
disableEmotion: boolean;
|
|
116
131
|
children: Children;
|
|
132
|
+
[key: string]: any;
|
|
117
133
|
}>;
|
|
118
134
|
/**
|
|
119
135
|
* A value that can be a direct value or a function of the theme.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.type.d.ts","sourceRoot":"","sources":["../../src/types/node.type.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EACZ,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,GAAG,EACR,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,aAAa,EACnB,MAAM,OAAO,CAAA;AACd,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AACnE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"node.type.d.ts","sourceRoot":"","sources":["../../src/types/node.type.ts"],"names":[],"mappings":"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"}
|
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.
|
|
4
|
+
"version": "0.4.4",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/main.js",
|
|
7
7
|
"types": "./dist/main.d.ts",
|