Skip to content

Commit

Permalink
Start putting the fiber docs together (#24)
Browse files Browse the repository at this point in the history
  • Loading branch information
iamdustan authored Apr 19, 2017
1 parent a2ba412 commit 7e46ffa
Show file tree
Hide file tree
Showing 29 changed files with 1,505 additions and 58 deletions.
15 changes: 13 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
"description": "A tiny React renderer to demonstrate how to write a renderer.",
"main": "./index.js",
"scripts": {
"test": "node ./test"
"flow": "pushd src/fiber; flow; popd;",
"test-stack": "node ./test --stack",
"test-fiber": "node ./test --fiber",
"test": "node ./test && node ./test --fiber && npm run flow"
},
"repository": {
"type": "git",
Expand All @@ -26,9 +29,17 @@
"url": "https://github.com/iamdustan/tiny-render-renderer/issues"
},
"homepage": "https://github.com/iamdustan/tiny-render-renderer",
"babel": {
"plugins": [
"transform-flow-strip-types"
]
},
"dependencies": {
"babel-register": "^6.23.0",
"fbjs": "^0.8.4",
"react": "15.3.x"
},
"devDependencies": {}
"devDependencies": {
"babel-plugin-transform-flow-strip-types": "^6.22.0"
}
}
Empty file added src/fiber-types/.flowconfig
Empty file.
5 changes: 5 additions & 0 deletions src/fiber-types/React.js.flow
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/** @flow */

export type ReactComponent = typeof React$Component;
export type ReactElement = typeof React$Element;

20 changes: 20 additions & 0 deletions src/fiber-types/ReactCompositeComponentTypes.js.flow
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* Copyright 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule ReactCompositeComponentTypes
* @flow
*/

export type CompositeComponentTypes = 0 | 1 | 2;

module.exports = {
ImpureClass: 0,
PureClass: 1,
StatelessFunctional: 2,
};

34 changes: 34 additions & 0 deletions src/fiber-types/ReactCoroutine.js.flow
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* Copyright 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule ReactCoroutine
* @flow
*/

'use strict';

import type { ReactNodeList } from './ReactTypes';

type ReifiedYield = { continuation: Object, props: Object };
type CoroutineHandler<T> = (props: T, yields: Array<ReifiedYield>) => ReactNodeList;

export type ReactCoroutine = {
$$typeof: Symbol | number,
key: null | string,
children: any,
// This should be a more specific CoroutineHandler
handler: (props: any, yields: Array<ReifiedYield>) => ReactNodeList,
props: any,
};
export type ReactYield = {
$$typeof: Symbol | number,
key: null | string,
props: Object,
continuation: mixed
};

36 changes: 36 additions & 0 deletions src/fiber-types/ReactElementType.js.flow
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Copyright 2016-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @flow
* @providesModule ReactElementType
*/

'use strict';

export type Source = {
fileName: string,
lineNumber: number,
};

export type ReactElement = {
$$typeof: any,
type: any,
key: any,
ref: any,
props: any,
_owner: any, // ReactInstance or ReactFiber

// __DEV__
_store: {
validated: boolean,
},
_self: ReactElement,
_shadowChildren: any,
_source: Source,
};

124 changes: 124 additions & 0 deletions src/fiber-types/ReactFiber.js.flow
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/**
* Copyright 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule ReactFiber
* @flow
*/
import type { Source } from './ReactElementType';
import type { ReactInstance, DebugID } from './ReactInstanceType';
import type { TypeOfWork } from './ReactTypeOfWork';
import type { TypeOfSideEffect } from './ReactTypeOfSideEffect';
import type { PriorityLevel } from './ReactPriorityLevel';
import type { UpdateQueue } from './ReactFiberUpdateQueue';


// A Fiber is work on a Component that needs to be done or was done. There can
// be more than one per component.
export type Fiber = {
// __DEV__ only
_debugID ?: DebugID,
_debugSource ?: Source | null,
_debugOwner ?: Fiber | ReactInstance | null, // Stack compatible

// These first fields are conceptually members of an Instance. This used to
// be split into a separate type and intersected with the other Fiber fields,
// but until Flow fixes its intersection bugs, we've merged them into a
// single type.

// An Instance is shared between all versions of a component. We can easily
// break this out into a separate object to avoid copying so much to the
// alternate versions of the tree. We put this on a single object for now to
// minimize the number of objects created during the initial render.

// Tag identifying the type of fiber.
tag: TypeOfWork,

// Unique identifier of this child.
key: null | string,

// The function/class/module associated with this fiber.
type: any,

// The local state associated with this fiber.
stateNode: any,

// Conceptual aliases
// parent : Instance -> return The parent happens to be the same as the
// return fiber since we've merged the fiber and instance.

// Remaining fields belong to Fiber

// The Fiber to return to after finishing processing this one.
// This is effectively the parent, but there can be multiple parents (two)
// so this is only the parent of the thing we're currently processing.
// It is conceptually the same as the return address of a stack frame.
return: Fiber | null,

// Singly Linked List Tree Structure.
child: Fiber | null,
sibling: Fiber | null,
index: number,

// The ref last used to attach this node.
// I'll avoid adding an owner field for prod and model that as functions.
ref: null | (((handle : mixed) => void) & { _stringRef: ?string }),

// Input is the data coming into process this fiber. Arguments. Props.
pendingProps: any, // This type will be more specific once we overload the tag.
// TODO: I think that there is a way to merge pendingProps and memoizedProps.
memoizedProps: any, // The props used to create the output.

// A queue of state updates and callbacks.
updateQueue: UpdateQueue | null,

// The state used to create the output
memoizedState: any,

// Effect
effectTag: TypeOfSideEffect,

// Singly linked list fast path to the next fiber with side-effects.
nextEffect: Fiber | null,

// The first and last fiber with side-effect within this subtree. This allows
// us to reuse a slice of the linked list when we reuse the work done within
// this fiber.
firstEffect: Fiber | null,
lastEffect: Fiber | null,

// This will be used to quickly determine if a subtree has no pending changes.
pendingWorkPriority: PriorityLevel,

// This value represents the priority level that was last used to process this
// component. This indicates whether it is better to continue from the
// progressed work or if it is better to continue from the current state.
progressedPriority: PriorityLevel,

// If work bails out on a Fiber that already had some work started at a lower
// priority, then we need to store the progressed work somewhere. This holds
// the started child set until we need to get back to working on it. It may
// or may not be the same as the "current" child.
progressedChild: Fiber | null,

// When we reconcile children onto progressedChild it is possible that we have
// to delete some child fibers. We need to keep track of this side-effects so
// that if we continue later on, we have to include those effects. Deletions
// are added in the reverse order from sibling pointers.
progressedFirstDeletion: Fiber | null,
progressedLastDeletion: Fiber | null,

// This is a pooled version of a Fiber. Every fiber that gets updated will
// eventually have a pair. There are cases when we can clean up pairs to save
// memory if we need to.
alternate: Fiber | null,

// Conceptual aliases
// workInProgress : Fiber -> alternate The alternate used for reuse happens
// to be the same as work in progress.

};
107 changes: 107 additions & 0 deletions src/fiber-types/ReactFiberReconciler.js.flow
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/**
* Copyright 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule ReactFiberReconciler
* @flow
*/

'use strict';

import type { ReactComponent } from './React';

import type { Fiber } from './ReactFiber';
import type { FiberRoot } from './ReactFiberRoot';
import type { PriorityLevel } from './ReactPriorityLevel';
import type { ReactNodeList } from './ReactTypes';

type Deadline = {
timeRemaining : () => number
};

type OpaqueHandle = Fiber;
type OpaqueRoot = FiberRoot;

export type HostConfig<T, P, I, TI, PI, C, CX, PL> = {

getRootHostContext(rootContainerInstance : C) : CX,
getChildHostContext(parentHostContext : CX, type : T) : CX,
getPublicInstance(instance : I | TI) : PI,

createInstance(
type : T,
props : P,
rootContainerInstance : C,
hostContext : CX,
internalInstanceHandle : OpaqueHandle
) : I,
appendInitialChild(parentInstance : I, child : I | TI) : void,
finalizeInitialChildren(parentInstance : I, type : T, props : P, rootContainerInstance : C) : boolean,

prepareUpdate(
instance : I,
type : T,
oldProps : P,
newProps : P,
rootContainerInstance : C,
hostContext : CX
) : null | PL,
commitUpdate(
instance : I,
updatePayload : PL,
type : T,
oldProps : P,
newProps : P,
internalInstanceHandle : OpaqueHandle
) : void,
commitMount(instance : I, type : T, newProps : P, internalInstanceHandle : OpaqueHandle) : void,

shouldSetTextContent(props : P) : boolean,
resetTextContent(instance : I) : void,

createTextInstance(
text : string,
rootContainerInstance : C,
hostContext : CX,
internalInstanceHandle : OpaqueHandle
) : TI,
commitTextUpdate(textInstance : TI, oldText : string, newText : string) : void,

appendChild(parentInstance : I | C, child : I | TI) : void,
insertBefore(parentInstance : I | C, child : I | TI, beforeChild : I | TI) : void,
removeChild(parentInstance : I | C, child : I | TI) : void,

scheduleAnimationCallback(callback : () => void) : number | void,
scheduleDeferredCallback(callback : (deadline : Deadline) => void) : number | void,

prepareForCommit() : void,
resetAfterCommit() : void,

useSyncScheduling ?: boolean,
};

export type Reconciler<C, I, TI> = {
createContainer(containerInfo : C) : OpaqueRoot,
updateContainer(
element : ReactNodeList,
container : OpaqueRoot,
parentComponent : ?ReactComponent<any, any, any>
) : void,
performWithPriority(priorityLevel : PriorityLevel, fn : Function) : void,
batchedUpdates<A>(fn : () => A) : A,
unbatchedUpdates<A>(fn : () => A) : A,
syncUpdates<A>(fn : () => A) : A,
deferredUpdates<A>(fn : () => A) : A,

// Used to extract the return value from the initial render. Legacy API.
getPublicRootInstance(container : OpaqueRoot) : (ReactComponent<any, any, any> | TI | I | null),

// Use for findDOMNode/findHostNode. Legacy API.
findHostInstance(component : Fiber) : I | TI | null,
};


30 changes: 30 additions & 0 deletions src/fiber-types/ReactFiberRoot.js.flow
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* Copyright 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule ReactFiberRoot
* @flow
*/

'use strict';

import type { Fiber } from './ReactFiber';
import type { UpdateQueue } from './ReactFiberUpdateQueue';

export type FiberRoot = {
// Any additional information from the host associated with this root.
containerInfo: any,
// The currently active root fiber. This is the mutable root of the tree.
current: Fiber,
// Determines if this root has already been added to the schedule for work.
isScheduled: boolean,
// The work schedule is a linked list.
nextScheduledRoot: ?FiberRoot,
// Linked list of callbacks to call after updates are committed.
callbackList: ?UpdateQueue,
};

Loading

0 comments on commit 7e46ffa

Please sign in to comment.