Skip to content

Commit f92bd8c

Browse files
committed
deletions
1 parent fa20b31 commit f92bd8c

7 files changed

+448
-14
lines changed

packages/react-reconciler/src/ReactFiber.new.js

+2
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,8 @@ export function createFiberFromTracingMarker(
771771
const tracingMarkerInstance: TracingMarkerInstance = {
772772
transitions: null,
773773
pendingBoundaries: null,
774+
deletions: null,
775+
name: pendingProps.name,
774776
};
775777
fiber.stateNode = tracingMarkerInstance;
776778
return fiber;

packages/react-reconciler/src/ReactFiberBeginWork.new.js

+1
Original file line numberDiff line numberDiff line change
@@ -979,6 +979,7 @@ function updateTracingMarkerComponent(
979979
transitions: new Set(currentTransitions),
980980
pendingBoundaries: new Map(),
981981
name: workInProgress.pendingProps.name,
982+
deletions: null,
982983
};
983984
workInProgress.stateNode = markerInstance;
984985
}

packages/react-reconciler/src/ReactFiberCommitWork.new.js

+49-12
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ import {
146146
addTransitionProgressCallbackToPendingTransition,
147147
addTransitionCompleteCallbackToPendingTransition,
148148
addMarkerProgressCallbackToPendingTransition,
149+
addMarkerIncompleteCallbackToPendingTransition,
149150
addMarkerCompleteCallbackToPendingTransition,
150151
setIsRunningInsertionEffect,
151152
} from './ReactFiberWorkLoop.new';
@@ -2979,7 +2980,9 @@ function commitPassiveMountOnFiber(
29792980
incompleteTransitions.forEach((markerInstance, transition) => {
29802981
const pendingBoundaries = markerInstance.pendingBoundaries;
29812982
if (pendingBoundaries === null || pendingBoundaries.size === 0) {
2982-
addTransitionCompleteCallbackToPendingTransition(transition);
2983+
if (markerInstance.deletions === null) {
2984+
addTransitionCompleteCallbackToPendingTransition(transition);
2985+
}
29832986
incompleteTransitions.delete(transition);
29842987
}
29852988
});
@@ -3101,17 +3104,51 @@ function commitPassiveMountOnFiber(
31013104
// Get the transitions that were initiatized during the render
31023105
// and add a start transition callback for each of them
31033106
const instance = finishedWork.stateNode;
3104-
if (
3105-
instance.transitions !== null &&
3106-
(instance.pendingBoundaries === null ||
3107-
instance.pendingBoundaries.size === 0)
3108-
) {
3109-
addMarkerCompleteCallbackToPendingTransition(
3110-
finishedWork.memoizedProps.name,
3111-
instance.transitions,
3112-
);
3113-
instance.transitions = null;
3114-
instance.pendingBoundaries = null;
3107+
if (instance.transitions !== null) {
3108+
if (finishedWork.alternate !== null) {
3109+
const prevName = finishedWork.alternate.memoizedProps.name;
3110+
const nextName = finishedWork.memoizedProps.name;
3111+
3112+
// The transition should be marked as incomplete if the name changed
3113+
if (prevName !== nextName) {
3114+
if (!instance.deletions) {
3115+
instance.deletions = [];
3116+
3117+
addMarkerIncompleteCallbackToPendingTransition(
3118+
prevName,
3119+
instance.transitions,
3120+
instance.deletions,
3121+
);
3122+
}
3123+
3124+
const deletion = {
3125+
type: 'marker',
3126+
name: prevName,
3127+
newName: nextName,
3128+
// we'll filter the transitions that need to have this deletion
3129+
// during the callback stage
3130+
transitions: instance.transitions,
3131+
};
3132+
3133+
instance.deletions.push(deletion);
3134+
}
3135+
}
3136+
3137+
if (
3138+
instance.transitions !== null &&
3139+
(instance.pendingBoundaries === null ||
3140+
instance.pendingBoundaries.size === 0)
3141+
) {
3142+
if (instance.deletions === null) {
3143+
addMarkerCompleteCallbackToPendingTransition(
3144+
finishedWork.memoizedProps.name,
3145+
instance.transitions,
3146+
);
3147+
}
3148+
instance.transitions = null;
3149+
instance.pendingBoundaries = null;
3150+
instance.deletions = null;
3151+
}
31153152
}
31163153
}
31173154
break;

packages/react-reconciler/src/ReactFiberCompleteWork.new.js

+3
Original file line numberDiff line numberDiff line change
@@ -1605,8 +1605,11 @@ function completeWork(
16051605
}
16061606
bubbleProperties(workInProgress);
16071607

1608+
const prevName = current !== null ? current.memoizedProps.name : null;
1609+
const nextName = workInProgress.memoizedProps.name;
16081610
if (
16091611
current === null ||
1612+
prevName !== nextName ||
16101613
(workInProgress.subtreeFlags & Visibility) !== NoFlags
16111614
) {
16121615
// If any of our suspense children toggle visibility, this means that

packages/react-reconciler/src/ReactFiberTracingMarkerComponent.new.js

+66-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,14 @@ export type PendingTransitionCallbacks = {
2121
transitionStart: Array<Transition> | null,
2222
transitionProgress: Map<Transition, PendingBoundaries> | null,
2323
transitionComplete: Array<Transition> | null,
24-
markerProgress: Map<string, TracingMarkerInstance> | null,
24+
markerProgress: Map<
25+
string,
26+
{pendingBoundaries: PendingBoundaries, transitions: Set<Transition>},
27+
> | null,
28+
markerIncomplete: Map<
29+
string,
30+
{deletions: Array<TransitionDeletion>, transitions: Set<Transition>},
31+
> | null,
2532
markerComplete: Map<string, Set<Transition>> | null,
2633
};
2734

@@ -39,7 +46,16 @@ export type BatchConfigTransition = {
3946
export type TracingMarkerInstance = {|
4047
pendingBoundaries: PendingBoundaries | null,
4148
transitions: Set<Transition> | null,
49+
deletions: Array<TransitionDeletion> | null,
50+
name: string | null,
51+
|};
52+
53+
export type TransitionDeletion = {|
54+
type: 'error' | 'unknown' | 'marker' | 'suspense',
4255
name?: string,
56+
newName?: string,
57+
endTime: number,
58+
transitions: Set<Transition>,
4359
|};
4460

4561
export type PendingBoundaries = Map<OffscreenInstance, SuspenseInfo>;
@@ -64,6 +80,7 @@ export function processTransitionCallbacks(
6480
if (onMarkerProgress != null && markerProgress !== null) {
6581
markerProgress.forEach((markerInstance, markerName) => {
6682
if (markerInstance.transitions !== null) {
83+
// TODO: Clone the suspense object so users can't modify it
6784
const pending =
6885
markerInstance.pendingBoundaries !== null
6986
? Array.from(markerInstance.pendingBoundaries.values())
@@ -96,6 +113,30 @@ export function processTransitionCallbacks(
96113
});
97114
}
98115

116+
const markerIncomplete = pendingTransitions.markerIncomplete;
117+
const onMarkerIncomplete = callbacks.onMarkerIncomplete;
118+
if (onMarkerIncomplete != null && markerIncomplete !== null) {
119+
markerIncomplete.forEach(({transitions, deletions}, markerName) => {
120+
transitions.forEach(transition => {
121+
const filteredDeletions = [];
122+
deletions.forEach(deletion => {
123+
if (deletion.transitions.has(transition)) {
124+
const filteredDeletion = getFilteredDeletion(deletion, endTime);
125+
if (filteredDeletion !== null) {
126+
filteredDeletions.push(filteredDeletion);
127+
}
128+
}
129+
});
130+
onMarkerIncomplete(
131+
transition.name,
132+
markerName,
133+
transition.startTime,
134+
filteredDeletions,
135+
);
136+
});
137+
});
138+
}
139+
99140
const transitionProgress = pendingTransitions.transitionProgress;
100141
const onTransitionProgress = callbacks.onTransitionProgress;
101142
if (onTransitionProgress != null && transitionProgress !== null) {
@@ -120,6 +161,28 @@ export function processTransitionCallbacks(
120161
}
121162
}
122163

164+
function getFilteredDeletion(deletion: TransitionDeletion, endTime: number) {
165+
switch (deletion.type) {
166+
case 'marker': {
167+
return deletion.newName
168+
? {
169+
type: deletion.type,
170+
name: deletion.name,
171+
newName: deletion.newName,
172+
endTime,
173+
}
174+
: {
175+
type: deletion.type,
176+
name: deletion.name,
177+
endTime,
178+
};
179+
}
180+
default: {
181+
return null;
182+
}
183+
}
184+
}
185+
123186
// For every tracing marker, store a pointer to it. We will later access it
124187
// to get the set of suspense boundaries that need to resolve before the
125188
// tracing marker can be logged as complete
@@ -148,6 +211,8 @@ export function pushRootMarkerInstance(workInProgress: Fiber): void {
148211
const markerInstance: TracingMarkerInstance = {
149212
transitions: new Set([transition]),
150213
pendingBoundaries: null,
214+
deletions: null,
215+
name: null,
151216
};
152217
root.incompleteTransitions.set(transition, markerInstance);
153218
}

packages/react-reconciler/src/ReactFiberWorkLoop.new.js

+35-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import type {
1818
PendingTransitionCallbacks,
1919
PendingBoundaries,
2020
Transition,
21+
TransitionDeletion,
2122
} from './ReactFiberTracingMarkerComponent.new';
2223
import type {OffscreenInstance} from './ReactFiberOffscreenComponent';
2324

@@ -342,6 +343,7 @@ export function addTransitionStartCallbackToPendingTransition(
342343
transitionProgress: null,
343344
transitionComplete: null,
344345
markerProgress: null,
346+
markerIncomplete: null,
345347
markerComplete: null,
346348
};
347349
}
@@ -357,7 +359,7 @@ export function addTransitionStartCallbackToPendingTransition(
357359
export function addMarkerProgressCallbackToPendingTransition(
358360
markerName: string,
359361
transitions: Set<Transition>,
360-
pendingBoundaries: PendingBoundaries | null,
362+
pendingBoundaries: PendingBoundaries,
361363
) {
362364
if (enableTransitionTracing) {
363365
if (currentPendingTransitionCallbacks === null) {
@@ -366,6 +368,7 @@ export function addMarkerProgressCallbackToPendingTransition(
366368
transitionProgress: null,
367369
transitionComplete: null,
368370
markerProgress: new Map(),
371+
markerIncomplete: null,
369372
markerComplete: null,
370373
};
371374
}
@@ -381,6 +384,34 @@ export function addMarkerProgressCallbackToPendingTransition(
381384
}
382385
}
383386

387+
export function addMarkerIncompleteCallbackToPendingTransition(
388+
markerName: string,
389+
transitions: Set<Transition>,
390+
deletions: Array<TransitionDeletion>,
391+
) {
392+
if (enableTransitionTracing) {
393+
if (currentPendingTransitionCallbacks === null) {
394+
currentPendingTransitionCallbacks = {
395+
transitionStart: null,
396+
transitionProgress: null,
397+
transitionComplete: null,
398+
markerProgress: null,
399+
markerIncomplete: new Map(),
400+
markerComplete: null,
401+
};
402+
}
403+
404+
if (currentPendingTransitionCallbacks.markerIncomplete === null) {
405+
currentPendingTransitionCallbacks.markerIncomplete = new Map();
406+
}
407+
408+
currentPendingTransitionCallbacks.markerIncomplete.set(markerName, {
409+
transitions,
410+
deletions,
411+
});
412+
}
413+
}
414+
384415
export function addMarkerCompleteCallbackToPendingTransition(
385416
markerName: string,
386417
transitions: Set<Transition>,
@@ -392,6 +423,7 @@ export function addMarkerCompleteCallbackToPendingTransition(
392423
transitionProgress: null,
393424
transitionComplete: null,
394425
markerProgress: null,
426+
markerIncomplete: null,
395427
markerComplete: new Map(),
396428
};
397429
}
@@ -418,6 +450,7 @@ export function addTransitionProgressCallbackToPendingTransition(
418450
transitionProgress: new Map(),
419451
transitionComplete: null,
420452
markerProgress: null,
453+
markerIncomplete: null,
421454
markerComplete: null,
422455
};
423456
}
@@ -443,6 +476,7 @@ export function addTransitionCompleteCallbackToPendingTransition(
443476
transitionProgress: null,
444477
transitionComplete: [],
445478
markerProgress: null,
479+
markerIncomplete: null,
446480
markerComplete: null,
447481
};
448482
}

0 commit comments

Comments
 (0)