@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.
- package/dist/Ryunix.esm.js +438 -364
- package/dist/Ryunix.esm.js.map +1 -1
- package/dist/Ryunix.umd.js +442 -363
- package/dist/Ryunix.umd.js.map +1 -1
- package/dist/Ryunix.umd.min.js +1 -1
- package/dist/Ryunix.umd.min.js.map +1 -1
- package/jsx/jsx-dev-runtime.js +6 -0
- package/jsx/jsx-runtime.js +56 -0
- package/package.json +14 -3
package/dist/Ryunix.esm.js
CHANGED
|
@@ -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
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
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
|
-
|
|
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
|
-
|
|
673
|
-
|
|
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
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
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
|
-
|
|
681
|
-
|
|
627
|
+
const useReducer = (reducer, initialState, init) => {
|
|
628
|
+
validateHookCall();
|
|
682
629
|
|
|
683
|
-
|
|
684
|
-
|
|
630
|
+
const state = getState();
|
|
631
|
+
const { wipFiber, hookIndex } = state;
|
|
632
|
+
const oldHook = wipFiber.alternate?.hooks?.[hookIndex];
|
|
685
633
|
|
|
686
|
-
|
|
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
|
-
|
|
689
|
-
|
|
690
|
-
|
|
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
|
-
|
|
710
|
-
if (
|
|
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
|
-
|
|
713
|
-
if (!stats) return
|
|
662
|
+
hook.queue.push(action);
|
|
714
663
|
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
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
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
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
|
-
|
|
735
|
-
|
|
736
|
-
this.measures.clear();
|
|
737
|
-
}
|
|
680
|
+
const useEffect = (callback, deps) => {
|
|
681
|
+
validateHookCall();
|
|
738
682
|
|
|
739
|
-
|
|
740
|
-
|
|
683
|
+
if (!is.function(callback)) {
|
|
684
|
+
throw new Error('useEffect callback must be a function')
|
|
741
685
|
}
|
|
742
|
-
|
|
743
|
-
|
|
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
|
-
|
|
749
|
-
const
|
|
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
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
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
|
-
|
|
758
|
-
|
|
759
|
-
profiler.recordRender(componentName, duration);
|
|
760
|
-
}
|
|
703
|
+
wipFiber.hooks[hookIndex] = hook;
|
|
704
|
+
state.hookIndex++;
|
|
761
705
|
};
|
|
762
706
|
|
|
763
|
-
|
|
764
|
-
|
|
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
|
-
|
|
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
|
-
|
|
786
|
-
|
|
787
|
-
|
|
714
|
+
const hook = {
|
|
715
|
+
hookID: hookIndex,
|
|
716
|
+
type: RYUNIX_TYPES.RYUNIX_REF,
|
|
717
|
+
value: oldHook ? oldHook.value : { current: initialValue },
|
|
718
|
+
};
|
|
788
719
|
|
|
789
|
-
|
|
720
|
+
wipFiber.hooks[hookIndex] = hook;
|
|
721
|
+
state.hookIndex++;
|
|
722
|
+
return hook.value
|
|
790
723
|
};
|
|
791
724
|
|
|
792
|
-
|
|
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
|