@unsetsoft/ryunixjs 1.2.3-canary.10 → 1.2.3-canary.12

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.
@@ -587,34 +587,6 @@ const reconcileChildren = (wipFiber, elements) => {
587
587
  });
588
588
  };
589
589
 
590
- const updateFunctionComponent = (fiber) => {
591
- const state = getState();
592
- state.wipFiber = fiber;
593
- state.hookIndex = 0;
594
- state.wipFiber.hooks = [];
595
-
596
- const children = [fiber.type(fiber.props)];
597
-
598
- if (fiber.type._contextId && fiber.props.value !== undefined) {
599
- fiber._contextId = fiber.type._contextId;
600
- fiber._contextValue = fiber.props.value;
601
- }
602
-
603
- reconcileChildren(fiber, children);
604
- };
605
-
606
- const updateHostComponent = (fiber) => {
607
- if (!fiber.dom) {
608
- fiber.dom = createDom(fiber);
609
- }
610
- const children = fiber.props?.children || [];
611
- reconcileChildren(fiber, children);
612
- };
613
-
614
- const Image = ({ src, ...props }) => {
615
- return createElement('img', { ...props, src })
616
- };
617
-
618
590
  /**
619
591
  * Priority levels for updates
620
592
  */
@@ -628,371 +600,130 @@ const Priority = {
628
600
 
629
601
  Priority.NORMAL;
630
602
 
631
- /**
632
- * Performance profiler for Ryunix
633
- */
634
- class Profiler {
635
- constructor() {
636
- this.enabled = process.env.NODE_ENV !== 'production';
637
- this.measures = new Map();
638
- this.renderTimes = [];
639
- this.maxSamples = 100;
640
- }
641
-
642
- startMeasure(name) {
643
- if (!this.enabled) return
644
- this.measures.set(name, performance.now());
645
- }
646
-
647
- endMeasure(name) {
648
- if (!this.enabled) return
649
- const start = this.measures.get(name);
650
- if (!start) return
651
-
652
- const duration = performance.now() - start;
653
- this.measures.delete(name);
654
-
655
- return duration
603
+ const validateHookCall = () => {
604
+ const state = getState();
605
+ if (!state.wipFiber) {
606
+ throw new Error(
607
+ 'Hooks can only be called inside the body of a function component.',
608
+ )
656
609
  }
657
-
658
- recordRender(componentName, duration) {
659
- if (!this.enabled) return
660
-
661
- this.renderTimes.push({
662
- component: componentName,
663
- duration,
664
- timestamp: Date.now(),
665
- });
666
-
667
- if (this.renderTimes.length > this.maxSamples) {
668
- this.renderTimes.shift();
669
- }
610
+ if (!Array.isArray(state.wipFiber.hooks)) {
611
+ state.wipFiber.hooks = [];
670
612
  }
613
+ };
671
614
 
672
- getStats() {
673
- if (!this.enabled) return null
615
+ const haveDepsChanged = (oldDeps, newDeps) => {
616
+ if (!oldDeps || !newDeps) return true
617
+ if (oldDeps.length !== newDeps.length) return true
618
+ return oldDeps.some((dep, i) => !Object.is(dep, newDeps[i]))
619
+ };
674
620
 
675
- const total = this.renderTimes.reduce((sum, r) => sum + r.duration, 0);
676
- const avg = total / this.renderTimes.length;
677
- const max = Math.max(...this.renderTimes.map((r) => r.duration));
678
- const min = Math.min(...this.renderTimes.map((r) => r.duration));
621
+ const useStore = (initialState) => {
622
+ const reducer = (state, action) =>
623
+ is.function(action) ? action(state) : action;
624
+ return useReducer(reducer, initialState)
625
+ };
679
626
 
680
- return { total, avg, max, min, count: this.renderTimes.length }
681
- }
627
+ const useReducer = (reducer, initialState, init) => {
628
+ validateHookCall();
682
629
 
683
- getSlowestComponents(limit = 10) {
684
- if (!this.enabled) return []
630
+ const state = getState();
631
+ const { wipFiber, hookIndex } = state;
632
+ const oldHook = wipFiber.alternate?.hooks?.[hookIndex];
685
633
 
686
- const byComponent = new Map();
634
+ const hook = {
635
+ hookID: hookIndex,
636
+ type: RYUNIX_TYPES.RYUNIX_STORE,
637
+ state: oldHook ? oldHook.state : init ? init(initialState) : initialState,
638
+ queue: [], // Siempre nueva cola vacía
639
+ };
687
640
 
688
- this.renderTimes.forEach(({ component, duration }) => {
689
- if (!byComponent.has(component)) {
690
- byComponent.set(component, { total: 0, count: 0, max: 0 });
641
+ // Procesar acciones del render anterior
642
+ if (oldHook?.queue) {
643
+ oldHook.queue.forEach((action) => {
644
+ try {
645
+ hook.state = reducer(hook.state, action);
646
+ } catch (error) {
647
+ if (process.env.NODE_ENV !== 'production') {
648
+ console.error('Error in reducer:', error);
649
+ }
691
650
  }
692
- const stats = byComponent.get(component);
693
- stats.total += duration;
694
- stats.count++;
695
- stats.max = Math.max(stats.max, duration);
696
651
  });
697
-
698
- return Array.from(byComponent.entries())
699
- .map(([name, stats]) => ({
700
- name,
701
- avg: stats.total / stats.count,
702
- max: stats.max,
703
- count: stats.count,
704
- }))
705
- .sort((a, b) => b.avg - a.avg)
706
- .slice(0, limit)
707
652
  }
708
653
 
709
- logStats() {
710
- if (!this.enabled) return
654
+ const dispatch = (action) => {
655
+ if (action === undefined) {
656
+ if (process.env.NODE_ENV !== 'production') {
657
+ console.warn('dispatch called with undefined action');
658
+ }
659
+ return
660
+ }
711
661
 
712
- const stats = this.getStats();
713
- if (!stats) return
662
+ hook.queue.push(action);
714
663
 
715
- console.group('🔍 Ryunix Performance Stats');
716
- console.log(`Total renders: ${stats.count}`);
717
- console.log(`Avg render time: ${stats.avg.toFixed(2)}ms`);
718
- console.log(
719
- `Min: ${stats.min.toFixed(2)}ms | Max: ${stats.max.toFixed(2)}ms`,
720
- );
664
+ const currentState = getState();
665
+ currentState.wipRoot = {
666
+ dom: currentState.currentRoot.dom,
667
+ props: currentState.currentRoot.props,
668
+ alternate: currentState.currentRoot,
669
+ };
670
+ currentState.deletions = [];
671
+ currentState.hookIndex = 0;
672
+ scheduleWork(currentState.wipRoot);
673
+ };
721
674
 
722
- const slowest = this.getSlowestComponents(5);
723
- if (slowest.length > 0) {
724
- console.log('\n⚠️ Slowest components:');
725
- slowest.forEach((comp, i) => {
726
- console.log(
727
- `${i + 1}. ${comp.name}: ${comp.avg.toFixed(2)}ms avg (${comp.count} renders)`,
728
- );
729
- });
730
- }
731
- console.groupEnd();
732
- }
675
+ wipFiber.hooks[hookIndex] = hook;
676
+ state.hookIndex++;
677
+ return [hook.state, dispatch]
678
+ };
733
679
 
734
- clear() {
735
- this.renderTimes = [];
736
- this.measures.clear();
737
- }
680
+ const useEffect = (callback, deps) => {
681
+ validateHookCall();
738
682
 
739
- enable() {
740
- this.enabled = true;
683
+ if (!is.function(callback)) {
684
+ throw new Error('useEffect callback must be a function')
741
685
  }
742
-
743
- disable() {
744
- this.enabled = false;
686
+ if (deps !== undefined && !Array.isArray(deps)) {
687
+ throw new Error('useEffect dependencies must be an array or undefined')
745
688
  }
746
- }
747
689
 
748
- // Global profiler instance
749
- const profiler = new Profiler();
690
+ const state = getState();
691
+ const { wipFiber, hookIndex } = state;
692
+ const oldHook = wipFiber.alternate?.hooks?.[hookIndex];
693
+ const hasChanged = haveDepsChanged(oldHook?.deps, deps);
750
694
 
751
- /**
752
- * Hook to profile component render
753
- */
754
- const useProfiler = (componentName) => {
755
- const startTime = performance.now();
695
+ const hook = {
696
+ hookID: hookIndex,
697
+ type: RYUNIX_TYPES.RYUNIX_EFFECT,
698
+ deps,
699
+ effect: hasChanged ? callback : null,
700
+ cancel: oldHook?.cancel,
701
+ };
756
702
 
757
- return () => {
758
- const duration = performance.now() - startTime;
759
- profiler.recordRender(componentName, duration);
760
- }
703
+ wipFiber.hooks[hookIndex] = hook;
704
+ state.hookIndex++;
761
705
  };
762
706
 
763
- /**
764
- * HOC to profile component
765
- */
766
- const withProfiler = (Component, name) => {
767
- return (props) => {
768
- profiler.startMeasure(name);
769
- const result = Component(props);
770
- const duration = profiler.endMeasure(name);
771
- if (duration) profiler.recordRender(name, duration);
772
- return result
773
- }
774
- };
707
+ const useRef = (initialValue) => {
708
+ validateHookCall();
775
709
 
776
- const workLoop = (deadline) => {
777
710
  const state = getState();
778
- let shouldYield = false;
779
-
780
- while (state.nextUnitOfWork && !shouldYield) {
781
- state.nextUnitOfWork = performUnitOfWork(state.nextUnitOfWork);
782
- shouldYield = deadline.timeRemaining() < 1;
783
- }
711
+ const { wipFiber, hookIndex } = state;
712
+ const oldHook = wipFiber.alternate?.hooks?.[hookIndex];
784
713
 
785
- if (!state.nextUnitOfWork && state.wipRoot) {
786
- commitRoot();
787
- }
714
+ const hook = {
715
+ hookID: hookIndex,
716
+ type: RYUNIX_TYPES.RYUNIX_REF,
717
+ value: oldHook ? oldHook.value : { current: initialValue },
718
+ };
788
719
 
789
- requestIdleCallback(workLoop);
720
+ wipFiber.hooks[hookIndex] = hook;
721
+ state.hookIndex++;
722
+ return hook.value
790
723
  };
791
724
 
792
- requestIdleCallback(workLoop);
793
-
794
- const performUnitOfWork = (fiber) => {
795
- const componentName = fiber.type?.name || fiber.type?.displayName || 'Unknown';
796
-
797
- profiler.startMeasure(componentName);
798
-
799
- const isFunctionComponent = fiber.type instanceof Function;
800
- if (isFunctionComponent) {
801
- updateFunctionComponent(fiber);
802
- } else {
803
- updateHostComponent(fiber);
804
- }
805
-
806
- const duration = profiler.endMeasure(componentName);
807
- if (duration) profiler.recordRender(componentName, duration);
808
-
809
- if (fiber.child) {
810
- return fiber.child
811
- }
812
- let nextFiber = fiber;
813
- while (nextFiber) {
814
- if (nextFiber.sibling) {
815
- return nextFiber.sibling
816
- }
817
- nextFiber = nextFiber.parent;
818
- }
819
- };
820
-
821
- const scheduleWork = (root, priority = Priority.NORMAL) => {
822
- const state = getState();
823
- state.nextUnitOfWork = root;
824
- state.wipRoot = root;
825
- state.deletions = [];
826
- state.hookIndex = 0;
827
- state.effects = [];
828
-
829
- // Higher priority = faster scheduling
830
- if (priority <= Priority.USER_BLOCKING) {
831
- requestIdleCallback(workLoop);
832
- } else {
833
- setTimeout(() => requestIdleCallback(workLoop), 0);
834
- }
835
- };
836
-
837
- const render = (element, container) => {
838
- const state = getState();
839
- state.wipRoot = {
840
- dom: container,
841
- props: {
842
- children: [element],
843
- },
844
- alternate: state.currentRoot,
845
- };
846
-
847
- state.nextUnitOfWork = state.wipRoot;
848
- state.deletions = [];
849
- scheduleWork(state.wipRoot);
850
- return state.wipRoot
851
- };
852
-
853
- const init = (MainElement, root = '__ryunix') => {
854
- const state = getState();
855
- state.containerRoot = document.getElementById(root);
856
- const renderProcess = render(MainElement, state.containerRoot);
857
- return renderProcess
858
- };
859
-
860
- const safeRender = (component, props, onError) => {
861
- try {
862
- return component(props)
863
- } catch (error) {
864
- if (process.env.NODE_ENV !== 'production') {
865
- console.error('Component error:', error);
866
- }
867
- if (onError) onError(error);
868
- return null
869
- }
870
- };
871
-
872
- const validateHookCall = () => {
873
- const state = getState();
874
- if (!state.wipFiber) {
875
- throw new Error(
876
- 'Hooks can only be called inside the body of a function component.',
877
- )
878
- }
879
- if (!Array.isArray(state.wipFiber.hooks)) {
880
- state.wipFiber.hooks = [];
881
- }
882
- };
883
-
884
- const haveDepsChanged = (oldDeps, newDeps) => {
885
- if (!oldDeps || !newDeps) return true
886
- if (oldDeps.length !== newDeps.length) return true
887
- return oldDeps.some((dep, i) => !Object.is(dep, newDeps[i]))
888
- };
889
-
890
- const useStore = (initialState) => {
891
- const reducer = (state, action) =>
892
- is.function(action) ? action(state) : action;
893
- return useReducer(reducer, initialState)
894
- };
895
-
896
- const useReducer = (reducer, initialState, init) => {
897
- validateHookCall();
898
-
899
- const state = getState();
900
- const { wipFiber, hookIndex } = state;
901
- const oldHook = wipFiber.alternate?.hooks?.[hookIndex];
902
-
903
- const hook = {
904
- hookID: hookIndex,
905
- type: RYUNIX_TYPES.RYUNIX_STORE,
906
- state: oldHook ? oldHook.state : init ? init(initialState) : initialState,
907
- queue: [], // Siempre nueva cola vacía
908
- };
909
-
910
- // Procesar acciones del render anterior
911
- if (oldHook?.queue) {
912
- oldHook.queue.forEach((action) => {
913
- try {
914
- hook.state = reducer(hook.state, action);
915
- } catch (error) {
916
- if (process.env.NODE_ENV !== 'production') {
917
- console.error('Error in reducer:', error);
918
- }
919
- }
920
- });
921
- }
922
-
923
- const dispatch = (action) => {
924
- if (action === undefined) {
925
- if (process.env.NODE_ENV !== 'production') {
926
- console.warn('dispatch called with undefined action');
927
- }
928
- return
929
- }
930
-
931
- hook.queue.push(action);
932
-
933
- const currentState = getState();
934
- currentState.wipRoot = {
935
- dom: currentState.currentRoot.dom,
936
- props: currentState.currentRoot.props,
937
- alternate: currentState.currentRoot,
938
- };
939
- currentState.deletions = [];
940
- currentState.hookIndex = 0;
941
- scheduleWork(currentState.wipRoot);
942
- };
943
-
944
- wipFiber.hooks[hookIndex] = hook;
945
- state.hookIndex++;
946
- return [hook.state, dispatch]
947
- };
948
-
949
- const useEffect = (callback, deps) => {
950
- validateHookCall();
951
-
952
- if (!is.function(callback)) {
953
- throw new Error('useEffect callback must be a function')
954
- }
955
- if (deps !== undefined && !Array.isArray(deps)) {
956
- throw new Error('useEffect dependencies must be an array or undefined')
957
- }
958
-
959
- const state = getState();
960
- const { wipFiber, hookIndex } = state;
961
- const oldHook = wipFiber.alternate?.hooks?.[hookIndex];
962
- const hasChanged = haveDepsChanged(oldHook?.deps, deps);
963
-
964
- const hook = {
965
- hookID: hookIndex,
966
- type: RYUNIX_TYPES.RYUNIX_EFFECT,
967
- deps,
968
- effect: hasChanged ? callback : null,
969
- cancel: oldHook?.cancel,
970
- };
971
-
972
- wipFiber.hooks[hookIndex] = hook;
973
- state.hookIndex++;
974
- };
975
-
976
- const useRef = (initialValue) => {
977
- validateHookCall();
978
-
979
- const state = getState();
980
- const { wipFiber, hookIndex } = state;
981
- const oldHook = wipFiber.alternate?.hooks?.[hookIndex];
982
-
983
- const hook = {
984
- hookID: hookIndex,
985
- type: RYUNIX_TYPES.RYUNIX_REF,
986
- value: oldHook ? oldHook.value : { current: initialValue },
987
- };
988
-
989
- wipFiber.hooks[hookIndex] = hook;
990
- state.hookIndex++;
991
- return hook.value
992
- };
993
-
994
- const useMemo = (compute, deps) => {
995
- validateHookCall();
725
+ const useMemo = (compute, deps) => {
726
+ validateHookCall();
996
727
 
997
728
  if (!is.function(compute)) {
998
729
  throw new Error('useMemo callback must be a function')
@@ -1361,6 +1092,349 @@ var hooks = /*#__PURE__*/Object.freeze({
1361
1092
  useTransition: useTransition
1362
1093
  });
1363
1094
 
1095
+ const updateFunctionComponent = (fiber) => {
1096
+ const state = getState();
1097
+ state.wipFiber = fiber;
1098
+ state.hookIndex = 0;
1099
+ state.wipFiber.hooks = [];
1100
+
1101
+ const children = [fiber.type(fiber.props)];
1102
+
1103
+ if (fiber.type._contextId && fiber.props.value !== undefined) {
1104
+ fiber._contextId = fiber.type._contextId;
1105
+ fiber._contextValue = fiber.props.value;
1106
+ }
1107
+
1108
+ reconcileChildren(fiber, children);
1109
+ };
1110
+
1111
+ const updateHostComponent = (fiber) => {
1112
+ if (!fiber.dom) {
1113
+ fiber.dom = createDom(fiber);
1114
+ }
1115
+ const children = fiber.props?.children || [];
1116
+ reconcileChildren(fiber, children);
1117
+ };
1118
+
1119
+ /* Image component */
1120
+ const Image = ({ src, ...props }) => {
1121
+ return createElement('img', { ...props, src })
1122
+ };
1123
+
1124
+ const { Provider: MDXProvider, useContext: useMDXComponents } = createContext(
1125
+ 'ryunix.mdx',
1126
+ {},
1127
+ );
1128
+
1129
+ /**
1130
+ * Get merged MDX components from context and provided components
1131
+ * @param {Object} components - Additional components to merge
1132
+ * @returns {Object} Merged components object
1133
+ */
1134
+ const getMDXComponents = (components) => {
1135
+ const contextComponents = useMDXComponents();
1136
+ return {
1137
+ ...contextComponents,
1138
+ ...components,
1139
+ }
1140
+ };
1141
+
1142
+ /**
1143
+ * Default MDX components with Ryunix-optimized rendering
1144
+ */
1145
+ const defaultComponents = {
1146
+ // Headings
1147
+ h1: (props) => createElement('h1', { ...props }),
1148
+ h2: (props) => createElement('h2', { ...props }),
1149
+ h3: (props) => createElement('h3', { ...props }),
1150
+ h4: (props) => createElement('h4', { ...props }),
1151
+ h5: (props) => createElement('h5', { ...props }),
1152
+ h6: (props) => createElement('h6', { ...props }),
1153
+
1154
+ // Text
1155
+ p: (props) => createElement('p', { ...props }),
1156
+ a: (props) => createElement('a', { ...props }),
1157
+ strong: (props) => createElement('strong', { ...props }),
1158
+ em: (props) => createElement('em', { ...props }),
1159
+ code: (props) => createElement('code', { ...props }),
1160
+
1161
+ // Lists
1162
+ ul: (props) => createElement('ul', { ...props }),
1163
+ ol: (props) => createElement('ol', { ...props }),
1164
+ li: (props) => createElement('li', { ...props }),
1165
+
1166
+ // Blocks
1167
+ blockquote: (props) => createElement('blockquote', { ...props }),
1168
+ pre: (props) => createElement('pre', { ...props }),
1169
+ hr: (props) => createElement('hr', { ...props }),
1170
+
1171
+ // Tables
1172
+ table: (props) => createElement('table', { ...props }),
1173
+ thead: (props) => createElement('thead', { ...props }),
1174
+ tbody: (props) => createElement('tbody', { ...props }),
1175
+ tr: (props) => createElement('tr', { ...props }),
1176
+ th: (props) => createElement('th', { ...props }),
1177
+ td: (props) => createElement('td', { ...props }),
1178
+
1179
+ // Media
1180
+ img: (props) => createElement('img', { ...props }),
1181
+ };
1182
+
1183
+ /**
1184
+ * MDX Wrapper component
1185
+ * Provides default styling and components for MDX content
1186
+ */
1187
+ const MDXContent = ({ children, components = {} }) => {
1188
+ const mergedComponents = getMDXComponents(components);
1189
+
1190
+ return createElement(
1191
+ MDXProvider,
1192
+ { value: mergedComponents },
1193
+ createElement('div', null, children),
1194
+ )
1195
+ };
1196
+
1197
+ /**
1198
+ * Performance profiler for Ryunix
1199
+ */
1200
+ class Profiler {
1201
+ constructor() {
1202
+ this.enabled = process.env.NODE_ENV !== 'production';
1203
+ this.measures = new Map();
1204
+ this.renderTimes = [];
1205
+ this.maxSamples = 100;
1206
+ }
1207
+
1208
+ startMeasure(name) {
1209
+ if (!this.enabled) return
1210
+ this.measures.set(name, performance.now());
1211
+ }
1212
+
1213
+ endMeasure(name) {
1214
+ if (!this.enabled) return
1215
+ const start = this.measures.get(name);
1216
+ if (!start) return
1217
+
1218
+ const duration = performance.now() - start;
1219
+ this.measures.delete(name);
1220
+
1221
+ return duration
1222
+ }
1223
+
1224
+ recordRender(componentName, duration) {
1225
+ if (!this.enabled) return
1226
+
1227
+ this.renderTimes.push({
1228
+ component: componentName,
1229
+ duration,
1230
+ timestamp: Date.now(),
1231
+ });
1232
+
1233
+ if (this.renderTimes.length > this.maxSamples) {
1234
+ this.renderTimes.shift();
1235
+ }
1236
+ }
1237
+
1238
+ getStats() {
1239
+ if (!this.enabled) return null
1240
+
1241
+ const total = this.renderTimes.reduce((sum, r) => sum + r.duration, 0);
1242
+ const avg = total / this.renderTimes.length;
1243
+ const max = Math.max(...this.renderTimes.map((r) => r.duration));
1244
+ const min = Math.min(...this.renderTimes.map((r) => r.duration));
1245
+
1246
+ return { total, avg, max, min, count: this.renderTimes.length }
1247
+ }
1248
+
1249
+ getSlowestComponents(limit = 10) {
1250
+ if (!this.enabled) return []
1251
+
1252
+ const byComponent = new Map();
1253
+
1254
+ this.renderTimes.forEach(({ component, duration }) => {
1255
+ if (!byComponent.has(component)) {
1256
+ byComponent.set(component, { total: 0, count: 0, max: 0 });
1257
+ }
1258
+ const stats = byComponent.get(component);
1259
+ stats.total += duration;
1260
+ stats.count++;
1261
+ stats.max = Math.max(stats.max, duration);
1262
+ });
1263
+
1264
+ return Array.from(byComponent.entries())
1265
+ .map(([name, stats]) => ({
1266
+ name,
1267
+ avg: stats.total / stats.count,
1268
+ max: stats.max,
1269
+ count: stats.count,
1270
+ }))
1271
+ .sort((a, b) => b.avg - a.avg)
1272
+ .slice(0, limit)
1273
+ }
1274
+
1275
+ logStats() {
1276
+ if (!this.enabled) return
1277
+
1278
+ const stats = this.getStats();
1279
+ if (!stats) return
1280
+
1281
+ console.group('🔍 Ryunix Performance Stats');
1282
+ console.log(`Total renders: ${stats.count}`);
1283
+ console.log(`Avg render time: ${stats.avg.toFixed(2)}ms`);
1284
+ console.log(
1285
+ `Min: ${stats.min.toFixed(2)}ms | Max: ${stats.max.toFixed(2)}ms`,
1286
+ );
1287
+
1288
+ const slowest = this.getSlowestComponents(5);
1289
+ if (slowest.length > 0) {
1290
+ console.log('\n⚠️ Slowest components:');
1291
+ slowest.forEach((comp, i) => {
1292
+ console.log(
1293
+ `${i + 1}. ${comp.name}: ${comp.avg.toFixed(2)}ms avg (${comp.count} renders)`,
1294
+ );
1295
+ });
1296
+ }
1297
+ console.groupEnd();
1298
+ }
1299
+
1300
+ clear() {
1301
+ this.renderTimes = [];
1302
+ this.measures.clear();
1303
+ }
1304
+
1305
+ enable() {
1306
+ this.enabled = true;
1307
+ }
1308
+
1309
+ disable() {
1310
+ this.enabled = false;
1311
+ }
1312
+ }
1313
+
1314
+ // Global profiler instance
1315
+ const profiler = new Profiler();
1316
+
1317
+ /**
1318
+ * Hook to profile component render
1319
+ */
1320
+ const useProfiler = (componentName) => {
1321
+ const startTime = performance.now();
1322
+
1323
+ return () => {
1324
+ const duration = performance.now() - startTime;
1325
+ profiler.recordRender(componentName, duration);
1326
+ }
1327
+ };
1328
+
1329
+ /**
1330
+ * HOC to profile component
1331
+ */
1332
+ const withProfiler = (Component, name) => {
1333
+ return (props) => {
1334
+ profiler.startMeasure(name);
1335
+ const result = Component(props);
1336
+ const duration = profiler.endMeasure(name);
1337
+ if (duration) profiler.recordRender(name, duration);
1338
+ return result
1339
+ }
1340
+ };
1341
+
1342
+ const workLoop = (deadline) => {
1343
+ const state = getState();
1344
+ let shouldYield = false;
1345
+
1346
+ while (state.nextUnitOfWork && !shouldYield) {
1347
+ state.nextUnitOfWork = performUnitOfWork(state.nextUnitOfWork);
1348
+ shouldYield = deadline.timeRemaining() < 1;
1349
+ }
1350
+
1351
+ if (!state.nextUnitOfWork && state.wipRoot) {
1352
+ commitRoot();
1353
+ }
1354
+
1355
+ requestIdleCallback(workLoop);
1356
+ };
1357
+
1358
+ requestIdleCallback(workLoop);
1359
+
1360
+ const performUnitOfWork = (fiber) => {
1361
+ const componentName = fiber.type?.name || fiber.type?.displayName || 'Unknown';
1362
+
1363
+ profiler.startMeasure(componentName);
1364
+
1365
+ const isFunctionComponent = fiber.type instanceof Function;
1366
+ if (isFunctionComponent) {
1367
+ updateFunctionComponent(fiber);
1368
+ } else {
1369
+ updateHostComponent(fiber);
1370
+ }
1371
+
1372
+ const duration = profiler.endMeasure(componentName);
1373
+ if (duration) profiler.recordRender(componentName, duration);
1374
+
1375
+ if (fiber.child) {
1376
+ return fiber.child
1377
+ }
1378
+ let nextFiber = fiber;
1379
+ while (nextFiber) {
1380
+ if (nextFiber.sibling) {
1381
+ return nextFiber.sibling
1382
+ }
1383
+ nextFiber = nextFiber.parent;
1384
+ }
1385
+ };
1386
+
1387
+ const scheduleWork = (root, priority = Priority.NORMAL) => {
1388
+ const state = getState();
1389
+ state.nextUnitOfWork = root;
1390
+ state.wipRoot = root;
1391
+ state.deletions = [];
1392
+ state.hookIndex = 0;
1393
+ state.effects = [];
1394
+
1395
+ // Higher priority = faster scheduling
1396
+ if (priority <= Priority.USER_BLOCKING) {
1397
+ requestIdleCallback(workLoop);
1398
+ } else {
1399
+ setTimeout(() => requestIdleCallback(workLoop), 0);
1400
+ }
1401
+ };
1402
+
1403
+ const render = (element, container) => {
1404
+ const state = getState();
1405
+ state.wipRoot = {
1406
+ dom: container,
1407
+ props: {
1408
+ children: [element],
1409
+ },
1410
+ alternate: state.currentRoot,
1411
+ };
1412
+
1413
+ state.nextUnitOfWork = state.wipRoot;
1414
+ state.deletions = [];
1415
+ scheduleWork(state.wipRoot);
1416
+ return state.wipRoot
1417
+ };
1418
+
1419
+ const init = (MainElement, root = '__ryunix') => {
1420
+ const state = getState();
1421
+ state.containerRoot = document.getElementById(root);
1422
+ const renderProcess = render(MainElement, state.containerRoot);
1423
+ return renderProcess
1424
+ };
1425
+
1426
+ const safeRender = (component, props, onError) => {
1427
+ try {
1428
+ return component(props)
1429
+ } catch (error) {
1430
+ if (process.env.NODE_ENV !== 'production') {
1431
+ console.error('Component error:', error);
1432
+ }
1433
+ if (onError) onError(error);
1434
+ return null
1435
+ }
1436
+ };
1437
+
1364
1438
  /**
1365
1439
  * memo - Memoize component to prevent unnecessary re-renders
1366
1440
  */
@@ -1498,5 +1572,5 @@ var Ryunix = /*#__PURE__*/Object.freeze({
1498
1572
 
1499
1573
  window.Ryunix = Ryunix;
1500
1574
 
1501
- export { Children, Fragment, hooks as Hooks, Image, NavLink, Priority, RouterProvider, Suspense, batchUpdates, createContext, createElement, Ryunix as default, init, lazy, memo, profiler, render, safeRender, useCallback, useDeferredValue, useEffect, useHash, useMemo, useMetadata, useProfiler, useQuery, useReducer, useRef, useRouter, useStore, useStorePriority, useTransition, withProfiler };
1575
+ export { Children, Fragment, hooks as Hooks, Image, MDXContent, MDXProvider, NavLink, Priority, RouterProvider, Suspense, batchUpdates, createContext, createElement, Ryunix as default, defaultComponents, getMDXComponents, init, lazy, memo, profiler, render, safeRender, useCallback, useDeferredValue, useEffect, useHash, useMDXComponents, useMemo, useMetadata, useProfiler, useQuery, useReducer, useRef, useRouter, useStore, useStorePriority, useTransition, withProfiler };
1502
1576
  //# sourceMappingURL=Ryunix.esm.js.map