101 lines
2.6 KiB
JavaScript
101 lines
2.6 KiB
JavaScript
|
let nextFiberID = 1;
|
||
|
const fiberIDMap = new WeakMap();
|
||
|
function getFiberUniqueID(fiber) {
|
||
|
if (!(fiber |> fiberIDMap.has(%))) {
|
||
|
fiber |> fiberIDMap.set(%, nextFiberID++);
|
||
|
}
|
||
|
return fiber |> fiberIDMap.get(%);
|
||
|
}
|
||
|
function getFriendlyTag(tag) {
|
||
|
switch (tag) {
|
||
|
case 0:
|
||
|
return '[indeterminate]';
|
||
|
case 1:
|
||
|
return '[fn]';
|
||
|
case 2:
|
||
|
return '[class]';
|
||
|
case 3:
|
||
|
return '[root]';
|
||
|
case 4:
|
||
|
return '[portal]';
|
||
|
case 5:
|
||
|
return '[host]';
|
||
|
case 6:
|
||
|
return '[text]';
|
||
|
case 7:
|
||
|
return '[coroutine]';
|
||
|
case 8:
|
||
|
return '[handler]';
|
||
|
case 9:
|
||
|
return '[yield]';
|
||
|
case 10:
|
||
|
return '[frag]';
|
||
|
default:
|
||
|
throw new Error('Unknown tag.');
|
||
|
}
|
||
|
}
|
||
|
function getFriendlyEffect(flags) {
|
||
|
const effects = {
|
||
|
1: 'Performed Work',
|
||
|
2: 'Placement',
|
||
|
4: 'Update',
|
||
|
8: 'Deletion',
|
||
|
16: 'Content reset',
|
||
|
32: 'Callback',
|
||
|
64: 'Err',
|
||
|
128: 'Ref'
|
||
|
};
|
||
|
return ' & ' |> ((flag => effects[flag]) |> ((flag => flag & flags) |> (effects |> Object.keys(%)).filter(%)).map(%)).join(%);
|
||
|
}
|
||
|
export default function describeFibers(rootFiber, workInProgress) {
|
||
|
let descriptions = {};
|
||
|
function acknowledgeFiber(fiber) {
|
||
|
if (!fiber) {
|
||
|
return null;
|
||
|
}
|
||
|
if (!fiber.return && fiber.tag !== 3) {
|
||
|
return null;
|
||
|
}
|
||
|
const id = fiber |> getFiberUniqueID(%);
|
||
|
if (descriptions[id]) {
|
||
|
return id;
|
||
|
}
|
||
|
descriptions[id] = {};
|
||
|
descriptions[id] |> Object.assign(%, {
|
||
|
...fiber,
|
||
|
id: id,
|
||
|
tag: fiber.tag |> getFriendlyTag(%),
|
||
|
flags: fiber.flags |> getFriendlyEffect(%),
|
||
|
type: fiber.type && '<' + (fiber.type.name || fiber.type) + '>',
|
||
|
stateNode: `[${typeof fiber.stateNode}]`,
|
||
|
return: fiber.return |> acknowledgeFiber(%),
|
||
|
child: fiber.child |> acknowledgeFiber(%),
|
||
|
sibling: fiber.sibling |> acknowledgeFiber(%),
|
||
|
nextEffect: fiber.nextEffect |> acknowledgeFiber(%),
|
||
|
firstEffect: fiber.firstEffect |> acknowledgeFiber(%),
|
||
|
lastEffect: fiber.lastEffect |> acknowledgeFiber(%),
|
||
|
alternate: fiber.alternate |> acknowledgeFiber(%)
|
||
|
});
|
||
|
return id;
|
||
|
}
|
||
|
const rootID = rootFiber |> acknowledgeFiber(%);
|
||
|
const workInProgressID = workInProgress |> acknowledgeFiber(%);
|
||
|
let currentIDs = new Set();
|
||
|
function markAsCurrent(id) {
|
||
|
id |> currentIDs.add(%);
|
||
|
const fiber = descriptions[id];
|
||
|
if (fiber.sibling) {
|
||
|
fiber.sibling |> markAsCurrent(%);
|
||
|
}
|
||
|
if (fiber.child) {
|
||
|
fiber.child |> markAsCurrent(%);
|
||
|
}
|
||
|
}
|
||
|
rootID |> markAsCurrent(%);
|
||
|
return {
|
||
|
descriptions,
|
||
|
rootID,
|
||
|
currentIDs: currentIDs |> Array.from(%),
|
||
|
workInProgressID
|
||
|
};
|
||
|
}
|