main
js 111 lines 2.5 KB
Raw
1 let nextFiberID = 1;
2 const fiberIDMap = new WeakMap();
3
4 function getFiberUniqueID(fiber) {
5 if (!fiberIDMap.has(fiber)) {
6 fiberIDMap.set(fiber, nextFiberID++);
7 }
8 return fiberIDMap.get(fiber);
9 }
10
11 function getFriendlyTag(tag) {
12 switch (tag) {
13 case 0:
14 return '[indeterminate]';
15 case 1:
16 return '[fn]';
17 case 2:
18 return '[class]';
19 case 3:
20 return '[root]';
21 case 4:
22 return '[portal]';
23 case 5:
24 return '[host]';
25 case 6:
26 return '[text]';
27 case 7:
28 return '[coroutine]';
29 case 8:
30 return '[handler]';
31 case 9:
32 return '[yield]';
33 case 10:
34 return '[frag]';
35 default:
36 throw new Error('Unknown tag.');
37 }
38 }
39
40 function getFriendlyEffect(flags) {
41 const effects = {
42 1: 'Performed Work',
43 2: 'Placement',
44 4: 'Update',
45 8: 'Deletion',
46 16: 'Content reset',
47 32: 'Callback',
48 64: 'Err',
49 128: 'Ref',
50 };
51 return Object.keys(effects)
52 .filter(flag => flag & flags)
53 .map(flag => effects[flag])
54 .join(' & ');
55 }
56
57 export default function describeFibers(rootFiber, workInProgress) {
58 let descriptions = {};
59 function acknowledgeFiber(fiber) {
60 if (!fiber) {
61 return null;
62 }
63 if (!fiber.return && fiber.tag !== 3) {
64 return null;
65 }
66 const id = getFiberUniqueID(fiber);
67 if (descriptions[id]) {
68 return id;
69 }
70 descriptions[id] = {};
71 Object.assign(descriptions[id], {
72 ...fiber,
73 id: id,
74 tag: getFriendlyTag(fiber.tag),
75 flags: getFriendlyEffect(fiber.flags),
76 type: fiber.type && '<' + (fiber.type.name || fiber.type) + '>',
77 stateNode: `[${typeof fiber.stateNode}]`,
78 return: acknowledgeFiber(fiber.return),
79 child: acknowledgeFiber(fiber.child),
80 sibling: acknowledgeFiber(fiber.sibling),
81 nextEffect: acknowledgeFiber(fiber.nextEffect),
82 firstEffect: acknowledgeFiber(fiber.firstEffect),
83 lastEffect: acknowledgeFiber(fiber.lastEffect),
84 alternate: acknowledgeFiber(fiber.alternate),
85 });
86 return id;
87 }
88
89 const rootID = acknowledgeFiber(rootFiber);
90 const workInProgressID = acknowledgeFiber(workInProgress);
91
92 let currentIDs = new Set();
93 function markAsCurrent(id) {
94 currentIDs.add(id);
95 const fiber = descriptions[id];
96 if (fiber.sibling) {
97 markAsCurrent(fiber.sibling);
98 }
99 if (fiber.child) {
100 markAsCurrent(fiber.child);
101 }
102 }
103 markAsCurrent(rootID);
104
105 return {
106 descriptions,
107 rootID,
108 currentIDs: Array.from(currentIDs),
109 workInProgressID,
110 };
111 }