Skip to content

Commit

Permalink
Update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
MQuy committed Jan 30, 2019
1 parent 9b94390 commit c6a3e58
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 75 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
### QReact

The dead simple implementation of React for the learning purpose on how React works internally. Currently, it is based on the old React architecture.
The dead simple implementation of React for the learning purpose on how React works internally.

There are two qreact's version:
- [qReact](https://github.com/MQuy/qreact/releases/tag/qreact) is similar to React-15.6
- [qReact Fiber](https://github.com/MQuy/qreact/releases/tag/qreact-fiber) is based on the React fiber

### Todo List

Expand Down
4 changes: 0 additions & 4 deletions demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,5 @@
"webpack": "4.28.4",
"webpack-cli": "3.2.1",
"webpack-dev-server": "3.1.14"
},
"dependencies": {
"react": "16.8.0-alpha.1",
"react-dom": "16.8.0-alpha.1"
}
}
47 changes: 2 additions & 45 deletions demo/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2796,7 +2796,7 @@ js-tokens@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"

"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
Expand Down Expand Up @@ -2927,13 +2927,6 @@ loose-envify@^1.0.0:
dependencies:
js-tokens "^3.0.0"

loose-envify@^1.1.0, loose-envify@^1.3.1:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
dependencies:
js-tokens "^3.0.0 || ^4.0.0"

lower-case@^1.1.1:
version "1.1.4"
resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac"
Expand Down Expand Up @@ -3326,7 +3319,7 @@ number-is-nan@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"

object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
object-assign@^4.0.1, object-assign@^4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"

Expand Down Expand Up @@ -3635,14 +3628,6 @@ promise-inflight@^1.0.1:
resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM=

prop-types@^15.6.2:
version "15.6.2"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102"
integrity sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ==
dependencies:
loose-envify "^1.3.1"
object-assign "^4.1.1"

proxy-addr@~2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93"
Expand Down Expand Up @@ -3759,26 +3744,6 @@ rc@^1.2.7:
minimist "^1.2.0"
strip-json-comments "~2.0.1"

react-dom@16.8.0-alpha.1:
version "16.8.0-alpha.1"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.8.0-alpha.1.tgz#dab73b8354ba2e498e3127d18e29d4546cea889e"
integrity sha512-tZCUM8BpnwUHJmLnUWP9c3vVZxnCqYotj7s4tx7umojG6BKv745KIBtuPTzt0EI0q50GMLEpmT/CPQ8iA61TwQ==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
prop-types "^15.6.2"
scheduler "^0.13.0-alpha.1"

react@16.8.0-alpha.1:
version "16.8.0-alpha.1"
resolved "https://registry.yarnpkg.com/react/-/react-16.8.0-alpha.1.tgz#c2b32689f3b466d3ce85a634dd9035f789d2cd97"
integrity sha512-vLwwnhM2dXrCsiQmcSxF2UdZVV5xsiXjK5Yetmy8dVqngJhQ3aw3YJhZN/YmyonxwdimH40wVqFQfsl4gSu2RA==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
prop-types "^15.6.2"
scheduler "^0.13.0-alpha.1"

"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@~2.3.6:
version "2.3.6"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
Expand Down Expand Up @@ -4017,14 +3982,6 @@ sax@^1.2.4:
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==

scheduler@^0.13.0-alpha.1:
version "0.13.0-alpha.1"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.0-alpha.1.tgz#753977fb4fb35d8cdd559868a11e46b640955556"
integrity sha512-W0sH0848sVuPKg+I18vTYQyzVtA4X1lrVgSeXK6KnOPUltFdJcY5nkbTkjGUeS/E0x+eBsNYfSdhJtGjT95njw==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"

schema-utils@^0.4.4:
version "0.4.7"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187"
Expand Down
2 changes: 1 addition & 1 deletion src/Component.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export class Component {
scheduleWork(fiber, expirationTime);
}

isReactComponent = {};
isReactComponent() {}
}

export const ReactInstanceMap = {
Expand Down
145 changes: 121 additions & 24 deletions src/FiberScheduler.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ import { getUpdateExpirationTime } from "./UpdateQueue";
import { AsyncMode } from "./TypeOfMode";

const timeHeuristicForUnitOfWork = 1;
let nextFlushedExpirationTime = NoWork;
let nextFlushedRoot = null;
let firstScheduledRoot = null;
let lastScheduledRoot = null;
let nextUnitOfWork = null;
let nextEffect = null;
Expand Down Expand Up @@ -66,18 +68,7 @@ export function scheduleWork(fiber, expirationTime) {
}

function requestWork(root, expirationTime) {
if (!nextFlushedRoot) {
lastScheduledRoot = nextFlushedRoot = root;
root.remainingExpirationTime = expirationTime;
} else {
const remainingExpirationTime = root.remainingExpirationTime;
if (
remainingExpirationTime === NoWork ||
expirationTime < remainingExpirationTime
) {
root.remainingExpirationTime = expirationTime;
}
}
addRootToSchedule(root, expirationTime);

if (isBatchingUpdates || isRendering) {
return;
Expand All @@ -89,6 +80,33 @@ function requestWork(root, expirationTime) {
}
}

function addRootToSchedule(root, expirationTime) {
// Add the root to the schedule.
// Check if this root is already part of the schedule.
if (root.nextScheduledRoot == null) {
// This root is not already scheduled. Add it.
root.remainingExpirationTime = expirationTime;
if (lastScheduledRoot == null) {
firstScheduledRoot = lastScheduledRoot = root;
root.nextScheduledRoot = root;
} else {
lastScheduledRoot.nextScheduledRoot = root;
lastScheduledRoot = root;
lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
}
} else {
// This root is already scheduled, but its priority may have increased.
var remainingExpirationTime = root.remainingExpirationTime;
if (
remainingExpirationTime === NoWork ||
expirationTime < remainingExpirationTime
) {
// Update the priority.
root.remainingExpirationTime = expirationTime;
}
}
}

function performAsyncWork(deadline) {
performWork(NoWork, deadline);
}
Expand All @@ -97,22 +115,101 @@ function performSyncWork() {
performWork(Sync, null);
}

export function performWork(minExpirationTime, deadline) {
function findHighestPriorityRoot() {
var highestPriorityWork = NoWork;
var highestPriorityRoot = null;
if (lastScheduledRoot != null) {
nextFlushedRoot = lastScheduledRoot;
var previousScheduledRoot = lastScheduledRoot;
var root = firstScheduledRoot;
while (root != null) {
var remainingExpirationTime = root.remainingExpirationTime;
if (remainingExpirationTime === NoWork) {
// This root no longer has work. Remove it from the scheduler.

// TODO: This check is redudant, but Flow is confused by the branch
// below where we set lastScheduledRoot to null, even though we break
// from the loop right after.
!(previousScheduledRoot != null && lastScheduledRoot != null)
? invariant(
false,
"Should have a previous and last root. This error is likely caused by a bug in React. Please file an issue.",
)
: void 0;
if (root === root.nextScheduledRoot) {
// This is the only root in the list.
root.nextScheduledRoot = null;
firstScheduledRoot = lastScheduledRoot = null;
break;
} else if (root === firstScheduledRoot) {
// This is the first root in the list.
var next = root.nextScheduledRoot;
firstScheduledRoot = next;
lastScheduledRoot.nextScheduledRoot = next;
root.nextScheduledRoot = null;
} else if (root === lastScheduledRoot) {
// This is the last root in the list.
lastScheduledRoot = previousScheduledRoot;
lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
root.nextScheduledRoot = null;
break;
} else {
previousScheduledRoot.nextScheduledRoot = root.nextScheduledRoot;
root.nextScheduledRoot = null;
}
root = previousScheduledRoot.nextScheduledRoot;
} else {
if (
highestPriorityWork === NoWork ||
remainingExpirationTime < highestPriorityWork
) {
// Update the priority, if it's higher
highestPriorityWork = remainingExpirationTime;
highestPriorityRoot = root;
}
if (root === lastScheduledRoot) {
break;
}
previousScheduledRoot = root;
root = root.nextScheduledRoot;
}
}
}
if (
minExpirationTime === NoWork ||
nextFlushedRoot.remainingExpirationTime <= minExpirationTime
) {
performWorkOnRoot(
nextFlushedRoot,
nextFlushedRoot.remainingExpirationTime,
deadline,
);

// If the next root is the same as the previous root, this is a nested
// update. To prevent an infinite loop, increment the nested update count.
nextFlushedRoot = highestPriorityRoot;
nextFlushedExpirationTime = highestPriorityWork;
}
export function performWork(minExpirationTime, deadline) {
// Keep working on roots until there's no more work, or until the we reach
// the deadline.
findHighestPriorityRoot();

if (deadline) {
while (
nextFlushedRoot != null &&
nextFlushedExpirationTime !== NoWork &&
(minExpirationTime === NoWork ||
minExpirationTime >= nextFlushedExpirationTime) &&
(deadline.timeRemaining() > timeHeuristicForUnitOfWork ||
recalculateCurrentTime() >= nextFlushedExpirationTime)
) {
performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, deadline);
findHighestPriorityRoot();
}
} else {
while (
nextFlushedRoot != null &&
nextFlushedExpirationTime !== NoWork &&
(minExpirationTime === NoWork ||
minExpirationTime >= nextFlushedExpirationTime)
) {
performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, false);
findHighestPriorityRoot();
}
}

if (nextFlushedRoot.remainingExpirationTime == NoWork) {
if (nextFlushedExpirationTime === NoWork) {
nextFlushedRoot = null;
} else {
requestIdleCallback(performAsyncWork);
Expand Down

0 comments on commit c6a3e58

Please sign in to comment.