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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "canvasengine",
3
- "version": "2.0.0-beta.54",
3
+ "version": "2.0.0-beta.56",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -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(async (c) => {
721
+ components.forEach((c) => {
673
722
  const index = parent.props.children.indexOf(prev.props.key);
674
- if (c instanceof Observable) {
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(async (component) => {
686
- if (!Array.isArray(component)) {
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);