canvasengine 2.0.0-beta.54 → 2.0.0-beta.56
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/engine/reactive.d.ts.map +1 -1
- package/dist/index.global.js +3 -3
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +428 -426
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/engine/reactive.ts +55 -31
package/package.json
CHANGED
package/src/engine/reactive.ts
CHANGED
|
@@ -653,6 +653,54 @@ export function createComponent(tag: string, props?: Props): Element {
|
|
|
653
653
|
child = await child;
|
|
654
654
|
}
|
|
655
655
|
if (child instanceof Observable) {
|
|
656
|
+
const mountedFlowElements = new Map<Element, Element>();
|
|
657
|
+
|
|
658
|
+
const mountFlowElement = (element: Element, index?: number) => {
|
|
659
|
+
if (mountedFlowElements.has(element)) {
|
|
660
|
+
return;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
const routed = routeDomComponent(parent, element);
|
|
664
|
+
mountedFlowElements.set(element, routed);
|
|
665
|
+
onMount(parent, routed, index);
|
|
666
|
+
propagateContext(routed);
|
|
667
|
+
};
|
|
668
|
+
|
|
669
|
+
const syncFlowElements = (nextElements: Set<Element>) => {
|
|
670
|
+
mountedFlowElements.forEach((mounted, source) => {
|
|
671
|
+
if (nextElements.has(source)) {
|
|
672
|
+
return;
|
|
673
|
+
}
|
|
674
|
+
mountedFlowElements.delete(source);
|
|
675
|
+
if (mounted !== source) {
|
|
676
|
+
destroyElement(mounted);
|
|
677
|
+
}
|
|
678
|
+
});
|
|
679
|
+
};
|
|
680
|
+
|
|
681
|
+
const processFlowComponent = (
|
|
682
|
+
component: any,
|
|
683
|
+
nextElements: Set<Element>,
|
|
684
|
+
index?: number
|
|
685
|
+
) => {
|
|
686
|
+
if (component instanceof Observable) {
|
|
687
|
+
void createElement(parent, component);
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
690
|
+
if (Array.isArray(component)) {
|
|
691
|
+
component.forEach((comp) =>
|
|
692
|
+
processFlowComponent(comp, nextElements, index)
|
|
693
|
+
);
|
|
694
|
+
return;
|
|
695
|
+
}
|
|
696
|
+
if (!isElement(component)) {
|
|
697
|
+
return;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
nextElements.add(component);
|
|
701
|
+
mountFlowElement(component, index);
|
|
702
|
+
};
|
|
703
|
+
|
|
656
704
|
// Subscribe to the observable and handle the emitted values
|
|
657
705
|
const subscription = child.subscribe(
|
|
658
706
|
(value: any) => {
|
|
@@ -668,43 +716,19 @@ export function createComponent(tag: string, props?: Props): Element {
|
|
|
668
716
|
} = value;
|
|
669
717
|
|
|
670
718
|
const components = comp.filter((c) => c !== null);
|
|
719
|
+
const nextElements = new Set<Element>();
|
|
671
720
|
if (prev) {
|
|
672
|
-
components.forEach(
|
|
721
|
+
components.forEach((c) => {
|
|
673
722
|
const index = parent.props.children.indexOf(prev.props.key);
|
|
674
|
-
|
|
675
|
-
// Handle observable component recursively
|
|
676
|
-
await createElement(parent, c);
|
|
677
|
-
} else if (isElement(c)) {
|
|
678
|
-
const routed = routeDomComponent(parent, c);
|
|
679
|
-
onMount(parent, routed, index + 1);
|
|
680
|
-
propagateContext(routed);
|
|
681
|
-
}
|
|
723
|
+
processFlowComponent(c, nextElements, index + 1);
|
|
682
724
|
});
|
|
725
|
+
syncFlowElements(nextElements);
|
|
683
726
|
return;
|
|
684
727
|
}
|
|
685
|
-
components.forEach(
|
|
686
|
-
|
|
687
|
-
if (component instanceof Observable) {
|
|
688
|
-
// Handle observable component recursively
|
|
689
|
-
await createElement(parent, component);
|
|
690
|
-
} else if (isElement(component)) {
|
|
691
|
-
const routed = routeDomComponent(parent, component);
|
|
692
|
-
onMount(parent, routed);
|
|
693
|
-
propagateContext(routed);
|
|
694
|
-
}
|
|
695
|
-
} else {
|
|
696
|
-
component.forEach(async (comp) => {
|
|
697
|
-
if (comp instanceof Observable) {
|
|
698
|
-
// Handle observable component recursively
|
|
699
|
-
await createElement(parent, comp);
|
|
700
|
-
} else if (isElement(comp)) {
|
|
701
|
-
const routed = routeDomComponent(parent, comp);
|
|
702
|
-
onMount(parent, routed);
|
|
703
|
-
propagateContext(routed);
|
|
704
|
-
}
|
|
705
|
-
});
|
|
706
|
-
}
|
|
728
|
+
components.forEach((component, index) => {
|
|
729
|
+
processFlowComponent(component, nextElements, index);
|
|
707
730
|
});
|
|
731
|
+
syncFlowElements(nextElements);
|
|
708
732
|
} else if (isElement(value)) {
|
|
709
733
|
// Handle direct Element emission
|
|
710
734
|
const routed = routeDomComponent(parent, value);
|