@reckona/mreact-compat 0.0.139 → 0.0.141

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.
@@ -29,6 +29,9 @@ export function commitFiberRoot(
29
29
  });
30
30
  }
31
31
  commitHostFiberRoot(root, finishedWork, options);
32
+ if (hasRemovedAlternateChildren(finishedWork)) {
33
+ detachRemovedAlternateChildren(finishedWork);
34
+ }
32
35
  root.current = finishedWork;
33
36
  root.current.stateNode = root;
34
37
  markRootFinished(root, finishedWork.lanes);
@@ -44,6 +47,95 @@ export function detachFiberRefs(fiber: Fiber): void {
44
47
  }
45
48
  }
46
49
 
50
+ function detachRemovedAlternateChildren(fiber: Fiber | undefined): void {
51
+ let cursor: Fiber | undefined = fiber;
52
+
53
+ while (cursor !== undefined) {
54
+ const retained = collectRetainedAlternateChildren(cursor.child);
55
+ let alternateChild = cursor.alternate?.child;
56
+
57
+ while (alternateChild !== undefined) {
58
+ const nextAlternateChild = alternateChild.sibling;
59
+
60
+ if (!retained.has(alternateChild)) {
61
+ detachFiberSubtree(alternateChild, retained);
62
+ }
63
+
64
+ alternateChild = nextAlternateChild;
65
+ }
66
+
67
+ if (cursor.deletions !== undefined) {
68
+ for (const deleted of cursor.deletions) {
69
+ detachFiberSubtree(deleted, retained);
70
+ }
71
+ cursor.deletions = undefined;
72
+ }
73
+
74
+ detachRemovedAlternateChildren(cursor.child);
75
+ cursor = cursor.sibling;
76
+ }
77
+ }
78
+
79
+ function hasRemovedAlternateChildren(fiber: Fiber): boolean {
80
+ return (
81
+ fiber.childListChanged ||
82
+ fiber.subtreeChildListChanged ||
83
+ fiber.deletions !== undefined
84
+ );
85
+ }
86
+
87
+ function collectRetainedAlternateChildren(fiber: Fiber | undefined): Set<Fiber> {
88
+ const retained = new Set<Fiber>();
89
+ let cursor = fiber;
90
+
91
+ while (cursor !== undefined) {
92
+ retained.add(cursor);
93
+
94
+ if (cursor.alternate !== undefined) {
95
+ retained.add(cursor.alternate);
96
+ }
97
+
98
+ cursor = cursor.sibling;
99
+ }
100
+
101
+ return retained;
102
+ }
103
+
104
+ function detachFiberSubtree(fiber: Fiber, preserve: ReadonlySet<Fiber>): void {
105
+ const stack = [fiber];
106
+ const seen = new Set<Fiber>();
107
+
108
+ while (stack.length > 0) {
109
+ const current = stack.pop();
110
+
111
+ if (current === undefined || seen.has(current) || preserve.has(current)) {
112
+ continue;
113
+ }
114
+
115
+ seen.add(current);
116
+
117
+ let child = current.child;
118
+ while (child !== undefined) {
119
+ stack.push(child);
120
+ child = child.sibling;
121
+ }
122
+
123
+ if (current.alternate !== undefined) {
124
+ stack.push(current.alternate);
125
+ }
126
+
127
+ current.return = undefined;
128
+ current.child = undefined;
129
+ current.sibling = undefined;
130
+ current.alternate = undefined;
131
+ current.pendingProps = undefined;
132
+ current.memoizedProps = undefined;
133
+ current.memoizedState = undefined;
134
+ current.stateNode = undefined;
135
+ current.deletions = undefined;
136
+ }
137
+ }
138
+
47
139
  function cleanupDeletedRefs(previous: Fiber, next: Fiber): void {
48
140
  const nextRefs = new Set<unknown>();
49
141
 
@@ -7,6 +7,8 @@ export {
7
7
  } from "./event-listeners.js";
8
8
  export {
9
9
  ensureDelegatedEventListener,
10
+ ensureDelegatedEventListenersForProp,
11
+ forEachEventName,
10
12
  getEventPriority,
11
13
  setLogicalEventParent,
12
14
  toEventNames,
@@ -3,6 +3,7 @@ import {
3
3
  ERROR_BOUNDARY_TYPE,
4
4
  FORWARD_REF_TYPE,
5
5
  Fragment,
6
+ HOST_CHILDREN_ONLY_PROPS_META,
6
7
  HOST_OWN_PROPS_META,
7
8
  LAZY_TYPE,
8
9
  MEMO_TYPE,
@@ -1621,13 +1622,23 @@ function commitHostDirtyFiber(
1621
1622
 
1622
1623
  const props = fiber.pendingProps as Record<string, unknown>;
1623
1624
  const previousProps = fiber.memoizedProps as Record<string, unknown> | undefined;
1625
+ const directTextChild =
1626
+ fiber.child === undefined && fiber.hydrateExisting !== true
1627
+ ? getDirectHostTextChild(props.children)
1628
+ : undefined;
1629
+ const textOnlyChildrenUpdate =
1630
+ directTextChild !== undefined &&
1631
+ hostPropsAreKnownChildrenOnly(fiber.memoizedProps) &&
1632
+ hostPropsAreKnownChildrenOnly(props);
1624
1633
  const propsAreUnchanged =
1625
1634
  fiber.hydrateExisting !== true &&
1635
+ !textOnlyChildrenUpdate &&
1626
1636
  hostPropsEqual(fiber.memoizedProps, props);
1627
1637
  const propsAreChildrenOnly =
1628
- fiber.hydrateExisting !== true &&
1629
- hostPropsAreChildrenOnly(fiber.memoizedProps) &&
1630
- hostPropsAreChildrenOnly(props);
1638
+ textOnlyChildrenUpdate ||
1639
+ (fiber.hydrateExisting !== true &&
1640
+ hostPropsAreChildrenOnly(fiber.memoizedProps) &&
1641
+ hostPropsAreChildrenOnly(props));
1631
1642
  const textOnlyRowUpdate =
1632
1643
  fiber.hydrateExisting !== true &&
1633
1644
  isRowTextOnlyUpdate(fiber.memoizedProps, props);
@@ -1641,11 +1652,6 @@ function commitHostDirtyFiber(
1641
1652
  applyChangedRef(previousProps?.ref, props.ref, element);
1642
1653
  }
1643
1654
 
1644
- const directTextChild =
1645
- fiber.child === undefined && fiber.hydrateExisting !== true
1646
- ? getDirectHostTextChild(props.children)
1647
- : undefined;
1648
-
1649
1655
  if (directTextChild !== undefined) {
1650
1656
  syncDirectHostTextChild(element, directTextChild);
1651
1657
  } else if (fiber.subtreeFlags !== NoFlags) {
@@ -2007,13 +2013,23 @@ function commitHostFiber(
2007
2013
 
2008
2014
  const props = fiber.pendingProps as Record<string, unknown>;
2009
2015
  const previousProps = fiber.memoizedProps as Record<string, unknown> | undefined;
2016
+ const directTextChild =
2017
+ fiber.child === undefined && fiber.hydrateExisting !== true
2018
+ ? getDirectHostTextChild(props.children)
2019
+ : undefined;
2020
+ const textOnlyChildrenUpdate =
2021
+ directTextChild !== undefined &&
2022
+ hostPropsAreKnownChildrenOnly(fiber.memoizedProps) &&
2023
+ hostPropsAreKnownChildrenOnly(props);
2010
2024
  const propsAreUnchanged =
2011
2025
  fiber.hydrateExisting !== true &&
2026
+ !textOnlyChildrenUpdate &&
2012
2027
  hostPropsEqual(fiber.memoizedProps, props);
2013
2028
  const propsAreChildrenOnly =
2014
- fiber.hydrateExisting !== true &&
2015
- hostPropsAreChildrenOnly(fiber.memoizedProps) &&
2016
- hostPropsAreChildrenOnly(props);
2029
+ textOnlyChildrenUpdate ||
2030
+ (fiber.hydrateExisting !== true &&
2031
+ hostPropsAreChildrenOnly(fiber.memoizedProps) &&
2032
+ hostPropsAreChildrenOnly(props));
2017
2033
  const textOnlyRowUpdate =
2018
2034
  fiber.hydrateExisting !== true &&
2019
2035
  isRowTextOnlyUpdate(fiber.memoizedProps, props);
@@ -2026,11 +2042,6 @@ function commitHostFiber(
2026
2042
  });
2027
2043
  applyChangedRef(previousProps?.ref, props.ref, element);
2028
2044
  }
2029
- const directTextChild =
2030
- fiber.child === undefined && fiber.hydrateExisting !== true
2031
- ? getDirectHostTextChild(props.children)
2032
- : undefined;
2033
-
2034
2045
  if (directTextChild !== undefined) {
2035
2046
  syncDirectHostTextChild(element, directTextChild);
2036
2047
  } else if (
@@ -2352,6 +2363,16 @@ function hostPropsAreChildrenOnly(props: unknown): boolean {
2352
2363
  return true;
2353
2364
  }
2354
2365
 
2366
+ function hostPropsAreKnownChildrenOnly(props: unknown): boolean {
2367
+ return (
2368
+ typeof props === "object" &&
2369
+ props !== null &&
2370
+ (props as { [HOST_CHILDREN_ONLY_PROPS_META]?: true })[
2371
+ HOST_CHILDREN_ONLY_PROPS_META
2372
+ ] === true
2373
+ );
2374
+ }
2375
+
2355
2376
  function isRowTextOnlyUpdate(previous: unknown, next: Record<string, unknown>): boolean {
2356
2377
  if (typeof previous !== "object" || previous === null) {
2357
2378
  return false;