├── src ├── packages │ ├── log │ │ ├── README.md │ │ ├── types.ts │ │ ├── package.json │ │ ├── index.ts │ │ ├── renderTip │ │ │ └── index.ts │ │ └── utils.ts │ ├── react-dom │ │ ├── server.js │ │ ├── test-utils.js │ │ ├── server.node.js │ │ ├── server.browser.js │ │ ├── README.md │ │ ├── LICENSE │ │ ├── index.js │ │ ├── profiling.js │ │ ├── package.json │ │ ├── cjs │ │ │ └── react-dom-test-utils.production.min.js │ │ └── umd │ │ │ └── react-dom-test-utils.production.min.js │ ├── react │ │ ├── index.js │ │ ├── jsx-runtime.js │ │ ├── jsx-dev-runtime.js │ │ ├── unstable-shared-subset.js │ │ ├── cjs │ │ │ ├── react-unstable-shared-subset.production.min.js │ │ │ ├── react-jsx-dev-runtime.profiling.min.js │ │ │ ├── react-jsx-dev-runtime.production.min.js │ │ │ ├── react-unstable-shared-subset.development.js │ │ │ ├── react-jsx-runtime.profiling.min.js │ │ │ ├── react-jsx-runtime.production.min.js │ │ │ └── react.production.min.js │ │ ├── README.md │ │ ├── LICENSE │ │ ├── package.json │ │ └── umd │ │ │ ├── react.production.min.js │ │ │ └── react.profiling.min.js │ ├── scheduler │ │ ├── index.js │ │ ├── unstable_mock.js │ │ ├── unstable_post_task.js │ │ ├── README.md │ │ ├── LICENSE │ │ ├── cjs │ │ │ ├── scheduler-unstable_post_task.production.min.js │ │ │ ├── scheduler.production.min.js │ │ │ ├── scheduler-unstable_mock.production.min.js │ │ │ └── scheduler-unstable_post_task.development.js │ │ ├── package.json │ │ └── umd │ │ │ ├── scheduler-unstable_mock.production.min.js │ │ │ ├── scheduler.production.min.js │ │ │ ├── scheduler.profiling.min.js │ │ │ └── scheduler.development.js │ └── react-cache │ │ ├── index.js │ │ ├── README.md │ │ ├── LICENSE │ │ ├── package.json │ │ ├── cjs │ │ ├── react-cache.production.min.js │ │ └── react-cache.development.js │ │ └── umd │ │ ├── react-cache.production.min.js │ │ └── react-cache.development.js ├── vite-env.d.ts ├── demo │ ├── MiniSchedulePhase │ │ ├── style.css │ │ └── index.ts │ ├── testDemo.tsx │ ├── MiniDiff │ │ ├── index.ts │ │ └── diff.ts │ ├── Performance │ │ ├── demo1.tsx │ │ ├── demo2.tsx │ │ ├── demo3.tsx │ │ └── demo4.tsx │ ├── BaseScheduleDemo.tsx │ ├── bailoutDemo.tsx │ ├── DiffDemo │ │ ├── v1.tsx │ │ ├── v3.tsx │ │ ├── v2.tsx │ │ └── v4.tsx │ ├── MiniEventSystem │ │ ├── index.tsx │ │ └── eventSystem.ts │ ├── SuspenseDemo │ │ ├── utils.ts │ │ ├── demo2.tsx │ │ └── demo1.tsx │ ├── TransitionDemo │ │ ├── demo1.tsx │ │ ├── demo3.tsx │ │ └── demo2.tsx │ ├── SSRDemo │ │ └── index.tsx │ ├── BailoutDemo │ │ ├── step1.tsx │ │ └── step2.tsx │ ├── ContextDemo.tsx │ ├── RenderPhaseDemo.tsx │ ├── batchDemo.tsx │ ├── longTaskDemo.tsx │ ├── UseEffectDemo │ │ └── index.tsx │ ├── CommitPhaseDemo.tsx │ ├── ErrorCatchDemo.tsx │ └── MiniUseState │ │ └── index.ts ├── main.tsx └── globalLog.ts ├── .gitignore ├── README.md ├── server ├── entry.js └── index.js ├── bin └── runDEV.js ├── index.html ├── package.json ├── tsconfig.json └── vite.config.ts /src/packages/log/README.md: -------------------------------------------------------------------------------- 1 | 这个包是为了打印React内部信息用的 -------------------------------------------------------------------------------- /src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /src/packages/log/types.ts: -------------------------------------------------------------------------------- 1 | export type TChoice = () => number; 2 | -------------------------------------------------------------------------------- /src/packages/react-dom/server.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('./server.node'); 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | launch.json 4 | dist 5 | dist-ssr 6 | *.local 7 | .history 8 | local_test -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react18-demo 2 | 便于调试源码的React18 DEMO 3 | 4 | 使用的`React`版本: 5 | "react": "^18.0.0-beta-96ca8d915-20211115", 6 | "react-dom": "^18.0.0-beta-96ca8d915-20211115" -------------------------------------------------------------------------------- /src/packages/log/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "这个包是为了打印React内部信息用的", 3 | "engines": { 4 | "node": ">=0.10.0" 5 | }, 6 | "license": "MIT", 7 | "main": "index.ts", 8 | "name": "log", 9 | "version": "0.0.1" 10 | } 11 | -------------------------------------------------------------------------------- /src/packages/react/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | if (process.env.NODE_ENV === 'production') { 4 | module.exports = require('./cjs/react.production.min.js'); 5 | } else { 6 | module.exports = require('./cjs/react.development.js'); 7 | } 8 | -------------------------------------------------------------------------------- /src/packages/scheduler/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | if (process.env.NODE_ENV === 'production') { 4 | module.exports = require('./cjs/scheduler.production.min.js'); 5 | } else { 6 | module.exports = require('./cjs/scheduler.development.js'); 7 | } 8 | -------------------------------------------------------------------------------- /src/packages/react-cache/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | if (process.env.NODE_ENV === 'production') { 4 | module.exports = require('./cjs/react-cache.production.min.js'); 5 | } else { 6 | module.exports = require('./cjs/react-cache.development.js'); 7 | } 8 | -------------------------------------------------------------------------------- /server/entry.js: -------------------------------------------------------------------------------- 1 | import ReactDOMServer from 'react-dom-server'; 2 | import App from '../src/demo/SSRDemo'; 3 | 4 | 5 | // console.log('ReactDOMServer::', ReactDOMServer); 6 | 7 | export const render = () => { 8 | return ReactDOMServer.renderToString(); 9 | } -------------------------------------------------------------------------------- /src/packages/react/jsx-runtime.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | if (process.env.NODE_ENV === 'production') { 4 | module.exports = require('./cjs/react-jsx-runtime.production.min.js'); 5 | } else { 6 | module.exports = require('./cjs/react-jsx-runtime.development.js'); 7 | } 8 | -------------------------------------------------------------------------------- /src/packages/react-dom/test-utils.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | if (process.env.NODE_ENV === 'production') { 4 | module.exports = require('./cjs/react-dom-test-utils.production.min.js'); 5 | } else { 6 | module.exports = require('./cjs/react-dom-test-utils.development.js'); 7 | } 8 | -------------------------------------------------------------------------------- /src/packages/react/jsx-dev-runtime.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | if (process.env.NODE_ENV === 'production') { 4 | module.exports = require('./cjs/react-jsx-dev-runtime.production.min.js'); 5 | } else { 6 | module.exports = require('./cjs/react-jsx-dev-runtime.development.js'); 7 | } 8 | -------------------------------------------------------------------------------- /src/packages/scheduler/unstable_mock.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | if (process.env.NODE_ENV === 'production') { 4 | module.exports = require('./cjs/scheduler-unstable_mock.production.min.js'); 5 | } else { 6 | module.exports = require('./cjs/scheduler-unstable_mock.development.js'); 7 | } 8 | -------------------------------------------------------------------------------- /src/packages/react/unstable-shared-subset.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | if (process.env.NODE_ENV === 'production') { 4 | module.exports = require('./cjs/react-unstable-shared-subset.production.min.js'); 5 | } else { 6 | module.exports = require('./cjs/react-unstable-shared-subset.development.js'); 7 | } 8 | -------------------------------------------------------------------------------- /src/packages/scheduler/unstable_post_task.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | if (process.env.NODE_ENV === 'production') { 4 | module.exports = require('./cjs/scheduler-unstable_post_task.production.min.js'); 5 | } else { 6 | module.exports = require('./cjs/scheduler-unstable_post_task.development.js'); 7 | } 8 | -------------------------------------------------------------------------------- /src/demo/MiniSchedulePhase/style.css: -------------------------------------------------------------------------------- 1 | button { 2 | margin: 10px; 3 | padding: 5px; 4 | } 5 | span { 6 | word-break: break-all; 7 | } 8 | 9 | .pri-1 { 10 | color: red; 11 | } 12 | .pri-2 { 13 | color: green; 14 | } 15 | .pri-3 { 16 | color: blue; 17 | } 18 | .pri-4 { 19 | color: pink; 20 | } 21 | .pri-5 { 22 | color: black; 23 | } -------------------------------------------------------------------------------- /bin/runDEV.js: -------------------------------------------------------------------------------- 1 | const {spawn} = require('child_process'); 2 | const killPort = require('kill-port'); 3 | 4 | // 应用使用的端口 5 | const DEFAULT_PORT = 3000; 6 | 7 | killPort(DEFAULT_PORT, 'tcp').then(() => { 8 | spawn('vite', ['--force'], {stdio: 'inherit', shell: process.platform === 'win32'}); 9 | }, (e) => { 10 | console.log(`关闭端口${PORT}报错\n`, e); 11 | }) -------------------------------------------------------------------------------- /src/demo/testDemo.tsx: -------------------------------------------------------------------------------- 1 | import React, {useState, useId} from 'react'; 2 | import {bindHook, utils} from 'log'; 3 | 4 | const {log, COLOR: {SCHEDULE_COLOR, RENDER_COLOR, COMMIT_COLOR}} = utils; 5 | 6 | 7 | // 用于调试 Reconciler 工作流程的Demo 8 | export default function App() { 9 | const Child = () =>
I am child.
; 10 | 11 | return ; 12 | } -------------------------------------------------------------------------------- /src/demo/MiniDiff/index.ts: -------------------------------------------------------------------------------- 1 | import diff from './diff'; 2 | 3 | const before = [ 4 | {key: 'a'}, 5 | {key: 'b'}, 6 | {key: 'c'}, 7 | {key: 'd'}, 8 | ] 9 | 10 | const after = [ 11 | // {key: 'c'}, 12 | // {key: 'b'}, 13 | // {key: 'a'} 14 | {key: 'a'}, 15 | {key: 'c'}, 16 | {key: 'b'}, 17 | {key: 'd'} 18 | ] 19 | 20 | console.log(diff(before, after)); -------------------------------------------------------------------------------- /src/demo/Performance/demo1.tsx: -------------------------------------------------------------------------------- 1 | import React, {useState, useEffect} from 'react'; 2 | import {bindHook, utils, getLibraryMethod} from 'log'; 3 | 4 | const {log, COLOR: {SCHEDULE_COLOR, RENDER_COLOR, COMMIT_COLOR}} = utils; 5 | 6 | // bindHook('beginWork', (current, wip) => { 7 | // log(RENDER_COLOR, `beginWork`, getLibraryMethod('getComponentNameFromFiber')?.(wip)); 8 | // }) 9 | 10 | -------------------------------------------------------------------------------- /src/demo/BaseScheduleDemo.tsx: -------------------------------------------------------------------------------- 1 | import React, { useRef, useState, useTransition } from "react"; 2 | 3 | export default () => { 4 | const [count, updateCount] = useState(0); 5 | // const [isPending, startTransition] = useTransition(); 6 | 7 | function onClick() { 8 | updateCount(count + 1); 9 | } 10 | 11 | return ( 12 |

13 | {count} 14 |

15 | ) 16 | } -------------------------------------------------------------------------------- /src/packages/scheduler/README.md: -------------------------------------------------------------------------------- 1 | # `scheduler` 2 | 3 | This is a package for cooperative scheduling in a browser environment. It is currently used internally by React, but we plan to make it more generic. 4 | 5 | The public API for this package is not yet finalized. 6 | 7 | ### Thanks 8 | 9 | The React team thanks [Anton Podviaznikov](https://podviaznikov.com/) for donating the `scheduler` package name. 10 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 调试React源码 8 | 9 | 10 |
11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/packages/react/cjs/react-unstable-shared-subset.production.min.js: -------------------------------------------------------------------------------- 1 | /** @license React vundefined 2 | * react-unstable-shared-subset.production.min.js 3 | * 4 | * Copyright (c) Facebook, Inc. and its affiliates. 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE file in the root directory of this source tree. 8 | */ 9 | 'use strict';throw Error("This entry point is not yet supported outside of experimental channels"); 10 | -------------------------------------------------------------------------------- /src/packages/react/cjs/react-jsx-dev-runtime.profiling.min.js: -------------------------------------------------------------------------------- 1 | /** @license React vundefined 2 | * react-jsx-dev-runtime.profiling.min.js 3 | * 4 | * Copyright (c) Facebook, Inc. and its affiliates. 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE file in the root directory of this source tree. 8 | */ 9 | 'use strict';require("object-assign");exports.Fragment=60107;if("function"===typeof Symbol&&Symbol.for){var a=Symbol.for;exports.Fragment=a("react.fragment")}exports.jsxDEV=void 0; 10 | -------------------------------------------------------------------------------- /src/packages/react/cjs/react-jsx-dev-runtime.production.min.js: -------------------------------------------------------------------------------- 1 | /** @license React vundefined 2 | * react-jsx-dev-runtime.production.min.js 3 | * 4 | * Copyright (c) Facebook, Inc. and its affiliates. 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE file in the root directory of this source tree. 8 | */ 9 | 'use strict';require("object-assign");exports.Fragment=60107;if("function"===typeof Symbol&&Symbol.for){var a=Symbol.for;exports.Fragment=a("react.fragment")}exports.jsxDEV=void 0; 10 | -------------------------------------------------------------------------------- /src/demo/bailoutDemo.tsx: -------------------------------------------------------------------------------- 1 | import React, {useState, useEffect} from 'react'; 2 | import {bindHook, utils} from 'log'; 3 | 4 | const {log, COLOR: {SCHEDULE_COLOR, RENDER_COLOR, COMMIT_COLOR}} = utils; 5 | 6 | 7 | export default function App() { 8 | const [num, updateNum] = useState(0); 9 | console.log("App render", num); 10 | 11 | return ( 12 |
updateNum(1)}> 13 | 14 |
15 | ); 16 | } 17 | 18 | function Child() { 19 | console.log("child render"); 20 | return child; 21 | } 22 | -------------------------------------------------------------------------------- /src/demo/Performance/demo2.tsx: -------------------------------------------------------------------------------- 1 | import React, {useState, useEffect, ReactNode} from 'react'; 2 | 3 | export default function App() { 4 | const [num, updateNum] = useState(0); 5 | return ( 6 |
7 | updateNum(+e.target.value)} /> 8 |

num is {num}

9 | 10 |
11 | ); 12 | } 13 | 14 | 15 | function ExpensiveCpn() { 16 | let now = performance.now(); 17 | while (performance.now() - now < 100) {} 18 | console.log('耗时的组件 render'); 19 | return

耗时的组件

; 20 | } 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react18-demo", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "dev": "chokidar src/packages --initial --silent -c \"node ./bin/runDEV.js\"", 6 | "ssr": "node server", 7 | "build": "tsc && vite build", 8 | "serve": "vite preview" 9 | }, 10 | "devDependencies": { 11 | "@types/react": "^17.0.0", 12 | "@types/react-dom": "^17.0.0", 13 | "@vitejs/plugin-react-refresh": "^1.3.1", 14 | "chokidar-cli": "^3.0.0", 15 | "kill-port": "^1.6.1", 16 | "object-assign": "^4.1.1", 17 | "typescript": "^4.3.2", 18 | "vite": "^2.5.1" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/packages/react-cache/README.md: -------------------------------------------------------------------------------- 1 | # react-cache 2 | 3 | A basic cache for React applications. It also serves as a reference for more 4 | advanced caching implementations. 5 | 6 | This package is meant to be used alongside yet-to-be-released, experimental 7 | React features. It's unlikely to be useful in any other context. 8 | 9 | **Do not use in a real application.** We're publishing this early for 10 | demonstration purposes. 11 | 12 | **Use it at your own risk.** 13 | 14 | # No, Really, It Is Unstable 15 | 16 | The API ~~may~~ will change wildly between versions. 17 | 18 | 卡颂:当前版本(@2.0.0-alpha.1)实际是不兼容`React18`的,有些许修改 19 | -------------------------------------------------------------------------------- /src/demo/DiffDemo/v1.tsx: -------------------------------------------------------------------------------- 1 | import React, {useState} from 'react'; 2 | import {bindHook, getLibraryMethod, utils} from 'log'; 3 | 4 | const {log, COLOR: {SCHEDULE_COLOR, RENDER_COLOR, COMMIT_COLOR}} = utils; 5 | 6 | 7 | bindHook('placeChild', (type, fiber, lastPlacedIndex) => { 8 | log(RENDER_COLOR, `${type} lastPlacedIndex: ${lastPlacedIndex}`, fiber); 9 | }) 10 | 11 | // 用于调试 Diff算法 的Demo 12 | export default function App() { 13 | const [num, updateNum] = useState(0); 14 | 15 | return ( 16 |
updateNum(1)}> 17 | { 18 | num === 0 ?

before

:

after

19 | } 20 |
21 | ) 22 | } -------------------------------------------------------------------------------- /src/packages/react/cjs/react-unstable-shared-subset.development.js: -------------------------------------------------------------------------------- 1 | /** @license React vundefined 2 | * react-unstable-shared-subset.development.js 3 | * 4 | * Copyright (c) Facebook, Inc. and its affiliates. 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE file in the root directory of this source tree. 8 | */ 9 | 10 | 'use strict'; 11 | 12 | if (process.env.NODE_ENV !== "production") { 13 | (function() { 14 | 'use strict'; 15 | 16 | // eslint-disable-next-line react-internal/prod-error-codes 17 | throw new Error('This entry point is not yet supported outside of experimental channels'); 18 | })(); 19 | } 20 | -------------------------------------------------------------------------------- /src/demo/MiniEventSystem/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { addEvent } from "./eventSystem"; 3 | 4 | const jsx = ( 5 |
{ 7 | console.log("click section"); 8 | }} 9 | > 10 |

你好

11 | 19 |
20 | ); 21 | 22 | /** 23 | * eventSystem的迷你实现 24 | * 在main.tsx执行如下代码 25 | * addEvent(rootEle, "click"); 26 | * ReactDOM.createRoot(rootEle).render(jsx); 27 | */ 28 | export default { 29 | jsx, 30 | addEvent 31 | } -------------------------------------------------------------------------------- /src/demo/SuspenseDemo/utils.ts: -------------------------------------------------------------------------------- 1 | export const sleep = (durationMs: number) => 2 | new Promise((resolve) => setTimeout(() => resolve(), durationMs)); 3 | 4 | export const wrapPromise = (promise: Promise) => { 5 | let result: {type: string, value: any}; 6 | promise.then( 7 | (value) => { 8 | result = { type: "success", value }; 9 | }, 10 | (value) => { 11 | result = { type: "error", value }; 12 | } 13 | ); 14 | return { 15 | read() { 16 | if (result === undefined) { 17 | throw promise; 18 | } 19 | if (result.type === "error") { 20 | throw result.value; 21 | } 22 | return result.value; 23 | } 24 | }; 25 | }; -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 5 | "allowJs": false, 6 | "skipLibCheck": false, 7 | "esModuleInterop": false, 8 | "allowSyntheticDefaultImports": true, 9 | "strict": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "module": "ESNext", 12 | "moduleResolution": "Node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "noEmit": true, 16 | "jsx": "react", 17 | "types": ["react/next", "react-dom/next"], 18 | "paths": { 19 | "log": ["./src/packages/log"], 20 | "react-cache": ["./src/packages/react-cache"] 21 | } 22 | }, 23 | "include": ["./src"] 24 | } 25 | -------------------------------------------------------------------------------- /src/packages/react-dom/server.node.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var l, s; 4 | if (process.env.NODE_ENV === 'production') { 5 | l = require('./cjs/react-dom-server-legacy.node.production.min.js'); 6 | s = require('./cjs/react-dom-server.node.production.min.js'); 7 | } else { 8 | l = require('./cjs/react-dom-server-legacy.node.development.js'); 9 | s = require('./cjs/react-dom-server.node.development.js'); 10 | } 11 | 12 | exports.version = l.version; 13 | exports.renderToString = l.renderToString; 14 | exports.renderToStaticMarkup = l.renderToStaticMarkup; 15 | exports.renderToNodeStream = l.renderToNodeStream; 16 | exports.renderToStaticNodeStream = l.renderToStaticNodeStream; 17 | exports.renderToPipeableStream = s.renderToPipeableStream; 18 | -------------------------------------------------------------------------------- /src/packages/react-dom/server.browser.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var l, s; 4 | if (process.env.NODE_ENV === 'production') { 5 | l = require('./cjs/react-dom-server-legacy.browser.production.min.js'); 6 | s = require('./cjs/react-dom-server.browser.production.min.js'); 7 | } else { 8 | l = require('./cjs/react-dom-server-legacy.browser.development.js'); 9 | s = require('./cjs/react-dom-server.browser.development.js'); 10 | } 11 | 12 | exports.version = l.version; 13 | exports.renderToString = l.renderToString; 14 | exports.renderToStaticMarkup = l.renderToStaticMarkup; 15 | exports.renderToNodeStream = l.renderToNodeStream; 16 | exports.renderToStaticNodeStream = l.renderToStaticNodeStream; 17 | exports.renderToReadableStream = s.renderToReadableStream; 18 | -------------------------------------------------------------------------------- /src/demo/TransitionDemo/demo1.tsx: -------------------------------------------------------------------------------- 1 | import React, {useState, useEffect, useTransition} from 'react'; 2 | import {bindHook, utils} from 'log'; 3 | 4 | const {log, lanes2Str, COLOR: {SCHEDULE_COLOR, RENDER_COLOR, COMMIT_COLOR}} = utils; 5 | 6 | bindHook('getNextLanes_entangledLanes', (lanes) => { 7 | log(SCHEDULE_COLOR, `纠缠的lane:`, lanes2Str(lanes)); 8 | }) 9 | 10 | // 快速点击后可以看到快速闪过的 999999999 11 | export default function App() { 12 | const [num, updateNum] = useState(0); 13 | const [isPending, startTransition] = useTransition(); 14 | 15 | return ( 16 |
{ 19 | updateNum(222222); 20 | startTransition(() => updateNum(4444)); 21 | }}>{num}
22 | ); 23 | } -------------------------------------------------------------------------------- /src/demo/DiffDemo/v3.tsx: -------------------------------------------------------------------------------- 1 | import React, {useState} from 'react'; 2 | import {bindHook, getLibraryMethod, utils} from 'log'; 3 | 4 | const {log, COLOR: {SCHEDULE_COLOR, RENDER_COLOR, COMMIT_COLOR}} = utils; 5 | 6 | bindHook('placeChild', (type, fiber, lastPlacedIndex) => { 7 | log(RENDER_COLOR, `${type} lastPlacedIndex: ${lastPlacedIndex}`, fiber); 8 | }) 9 | 10 | // 用于调试 Diff算法 的Demo 11 | export default function App() { 12 | const [num, updateNum] = useState(0); 13 | 14 | if (num === 0) { 15 | return ( 16 |
    updateNum(1)}> 17 |
  • a
  • 18 |
  • b
  • 19 |
20 | ) 21 | } 22 | 23 | return ( 24 |
    updateNum(1)}> 25 |
    a
    26 |
  • b
  • 27 |
28 | ) 29 | } -------------------------------------------------------------------------------- /src/packages/react/README.md: -------------------------------------------------------------------------------- 1 | # `react` 2 | 3 | React is a JavaScript library for creating user interfaces. 4 | 5 | The `react` package contains only the functionality necessary to define React components. It is typically used together with a React renderer like `react-dom` for the web, or `react-native` for the native environments. 6 | 7 | **Note:** by default, React will be in development mode. The development version includes extra warnings about common mistakes, whereas the production version includes extra performance optimizations and strips all error messages. Don't forget to use the [production build](https://reactjs.org/docs/optimizing-performance.html#use-the-production-build) when deploying your application. 8 | 9 | ## Example Usage 10 | 11 | ```js 12 | var React = require('react'); 13 | ``` 14 | -------------------------------------------------------------------------------- /src/demo/SSRDemo/index.tsx: -------------------------------------------------------------------------------- 1 | import React, {useState, useId, useRef} from 'react'; 2 | 3 | 4 | function App() { 5 | const idRef = useRef('id_' + (Math.random() * 1000).toFixed(0)); 6 | const [num, updateNum] = useState(0); 7 | const id = useId(); 8 | console.log('app id', id); 9 | 10 | return ( 11 |
updateNum(num + 1)}> 12 |
13 |

14 | Edit {num} 15 | {Array(33).fill(3).map((_, i) => number {i})} 16 |

17 |
18 |
19 | ); 20 | } 21 | 22 | function Child({children}) { 23 | const id = useId(); 24 | console.log('child id', id); 25 | return
i am child {children}
26 | } 27 | 28 | export default App; 29 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import reactRefresh from '@vitejs/plugin-react-refresh' 3 | import path from 'path' 4 | 5 | // https://vitejs.dev/config/ 6 | export default defineConfig({ 7 | plugins: [reactRefresh()], 8 | resolve: { 9 | alias: [ 10 | {find: 'react', replacement: path.resolve(__dirname, './src/packages/react')}, 11 | {find: 'react-dom', replacement: path.resolve(__dirname, './src/packages/react-dom')}, 12 | {find: 'scheduler', replacement: path.resolve(__dirname, './src/packages/scheduler')}, 13 | {find: 'react-cache', replacement: path.resolve(__dirname, './src/packages/react-cache')}, 14 | {find: 'log', replacement: path.resolve(__dirname, './src/packages/log')} 15 | ] 16 | }, 17 | optimizeDeps: { 18 | include: [ 19 | 'react', 'react-dom', 'scheduler', 'react-cache', 'log' 20 | ] 21 | } 22 | }) 23 | -------------------------------------------------------------------------------- /src/demo/DiffDemo/v2.tsx: -------------------------------------------------------------------------------- 1 | import React, {useState} from 'react'; 2 | import {bindHook, getLibraryMethod, utils} from 'log'; 3 | 4 | const {log, COLOR: {SCHEDULE_COLOR, RENDER_COLOR, COMMIT_COLOR}} = utils; 5 | 6 | bindHook('placeChild', (type, fiber, lastPlacedIndex) => { 7 | log(RENDER_COLOR, `${type} lastPlacedIndex: ${lastPlacedIndex}`, fiber); 8 | }) 9 | 10 | // 用于调试 Diff算法 的Demo 11 | export default function App() { 12 | const [num, updateNum] = useState(0); 13 | 14 | if (num === 0) { 15 | return ( 16 |
    updateNum(1)}> 17 |
  • a
  • 18 |
  • b
  • 19 |
  • c
  • 20 |
  • d
  • 21 |
22 | ) 23 | } 24 | 25 | return ( 26 |
    updateNum(1)}> 27 |
  • a
  • 28 |
  • c
  • 29 |
  • d
  • 30 |
  • b
  • 31 |
32 | ) 33 | } -------------------------------------------------------------------------------- /src/demo/DiffDemo/v4.tsx: -------------------------------------------------------------------------------- 1 | import React, {useState} from 'react'; 2 | import {bindHook, getLibraryMethod, utils} from 'log'; 3 | 4 | const {log, COLOR: {SCHEDULE_COLOR, RENDER_COLOR, COMMIT_COLOR}} = utils; 5 | 6 | bindHook('placeChild', (type, fiber, lastPlacedIndex) => { 7 | log(RENDER_COLOR, `${type} lastPlacedIndex: ${lastPlacedIndex}`, fiber); 8 | }) 9 | 10 | // 用于调试 Diff算法 的Demo 11 | export default function App() { 12 | const [num, updateNum] = useState(0); 13 | 14 | if (num === 0) { 15 | return ( 16 |
    updateNum(1)}> 17 |
  • a
  • 18 |
  • b
  • 19 |
  • c
  • 20 |
  • d
  • 21 |
22 | ) 23 | } 24 | 25 | return ( 26 |
    updateNum(1)}> 27 |
  • d
  • 28 |
  • a
  • 29 |
  • b
  • 30 |
  • c
  • 31 |
32 | ) 33 | } -------------------------------------------------------------------------------- /src/demo/BailoutDemo/step1.tsx: -------------------------------------------------------------------------------- 1 | import React, {useState, useEffect} from 'react'; 2 | import {bindHook, utils, getLibraryMethod} from 'log'; 3 | 4 | const {log, COLOR: {SCHEDULE_COLOR, RENDER_COLOR, COMMIT_COLOR}} = utils; 5 | 6 | bindHook('beginWork', (current, wip) => { 7 | log(RENDER_COLOR, `beginWork`, getLibraryMethod('getComponentNameFromFiber')?.(wip)); 8 | }) 9 | 10 | function Input() { 11 | const [num, updateNum] = useState(0); 12 | 13 | return ( 14 | <> 15 | updateNum(+e.target.value)} /> 16 |

num is {num}

17 | 18 | ) 19 | } 20 | 21 | export default function App() { 22 | 23 | return ( 24 | <> 25 | 26 | 27 | 28 | ); 29 | } 30 | 31 | 32 | function ExpensiveCpn() { 33 | console.log(3) 34 | let now = performance.now(); 35 | while (performance.now() - now < 100) {} 36 | return

耗时的组件

; 37 | } 38 | -------------------------------------------------------------------------------- /src/demo/ContextDemo.tsx: -------------------------------------------------------------------------------- 1 | import React, {useState, useId, useContext, ReactNode} from 'react'; 2 | import {bindHook, utils} from 'log'; 3 | 4 | const {log, COLOR: {SCHEDULE_COLOR, RENDER_COLOR, COMMIT_COLOR}} = utils; 5 | 6 | 7 | 8 | const Ctx = React.createContext(0); 9 | 10 | const NumProvider = ({children}: {children: ReactNode}) => { 11 | const [num, add] = useState(0); 12 | 13 | return ( 14 | 15 | 16 | {children} 17 | 18 | ) 19 | } 20 | 21 | export default () => { 22 | return ( 23 | 24 | 25 | 26 | ) 27 | } 28 | 29 | class Middle extends React.Component { 30 | shouldComponentUpdate() { 31 | return false; 32 | } 33 | render() { 34 | return ; 35 | } 36 | } 37 | 38 | function Child() { 39 | const num = useContext(Ctx); 40 | return

{num}

; 41 | } -------------------------------------------------------------------------------- /src/demo/Performance/demo3.tsx: -------------------------------------------------------------------------------- 1 | import React, {useState, useEffect, useContext} from 'react'; 2 | 3 | const numCtx = React.createContext(0); 4 | const updateNumCtx = React.createContext>(() => {}); 5 | 6 | 7 | export default function App() { 8 | const [num, updateNum] = useState(0); 9 | 10 | return ( 11 | 12 | 13 | 14 | 15 | 16 | ); 17 | } 18 | 19 | const Middle = () => { 20 | return ( 21 | <> 22 | 33 | ) 34 | } 35 | 36 | 37 | function Show() { 38 | const num = useContext(numCtx); 39 | return

num is: {num}

; 40 | } 41 | -------------------------------------------------------------------------------- /src/packages/react/cjs/react-jsx-runtime.profiling.min.js: -------------------------------------------------------------------------------- 1 | /** @license React vundefined 2 | * react-jsx-runtime.profiling.min.js 3 | * 4 | * Copyright (c) Facebook, Inc. and its affiliates. 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE file in the root directory of this source tree. 8 | */ 9 | 'use strict';require("object-assign");var f=require("react"),g=60103;exports.Fragment=60107;if("function"===typeof Symbol&&Symbol.for){var h=Symbol.for;g=h("react.element");exports.Fragment=h("react.fragment")}var m=Object.prototype.hasOwnProperty,n=f.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,p={key:!0,ref:!0,__self:!0,__source:!0}; 10 | function q(c,a,k){var b,d={},e=null,l=null;void 0!==k&&(e=""+k);void 0!==a.key&&(e=""+a.key);void 0!==a.ref&&(l=a.ref);for(b in a)m.call(a,b)&&!p.hasOwnProperty(b)&&(d[b]=a[b]);if(c&&c.defaultProps)for(b in a=c.defaultProps,a)void 0===d[b]&&(d[b]=a[b]);return{$$typeof:g,type:c,key:e,ref:l,props:d,_owner:n.current}}exports.jsx=q;exports.jsxs=q; 11 | -------------------------------------------------------------------------------- /src/packages/react/cjs/react-jsx-runtime.production.min.js: -------------------------------------------------------------------------------- 1 | /** @license React vundefined 2 | * react-jsx-runtime.production.min.js 3 | * 4 | * Copyright (c) Facebook, Inc. and its affiliates. 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE file in the root directory of this source tree. 8 | */ 9 | 'use strict';require("object-assign");var f=require("react"),g=60103;exports.Fragment=60107;if("function"===typeof Symbol&&Symbol.for){var h=Symbol.for;g=h("react.element");exports.Fragment=h("react.fragment")}var m=Object.prototype.hasOwnProperty,n=f.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,p={key:!0,ref:!0,__self:!0,__source:!0}; 10 | function q(c,a,k){var b,d={},e=null,l=null;void 0!==k&&(e=""+k);void 0!==a.key&&(e=""+a.key);void 0!==a.ref&&(l=a.ref);for(b in a)m.call(a,b)&&!p.hasOwnProperty(b)&&(d[b]=a[b]);if(c&&c.defaultProps)for(b in a=c.defaultProps,a)void 0===d[b]&&(d[b]=a[b]);return{$$typeof:g,type:c,key:e,ref:l,props:d,_owner:n.current}}exports.jsx=q;exports.jsxs=q; 11 | -------------------------------------------------------------------------------- /src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './globalLog'; 4 | // import App from './demo/SuspenseDemo/demo2' 5 | // import './demo/SchedulerDemo'; 6 | // import App from './demo/BaseScheduleDemo'; 7 | // import App from './demo/LongTaskDemo'; 8 | // import App from './demo/BaseScheduleDemo'; 9 | // import App from './demo/testDemo'; 10 | // import App from './demo/bailoutDemo'; 11 | // import App from './demo/ContextDemo'; 12 | // import App from './demo/BailoutDemo/step1'; 13 | // import App from './demo/DiffDemo/v4'; 14 | // import App from './demo/Performance/demo2'; 15 | import App from './demo/ErrorCatchDemo'; 16 | // import App from './demo/TransitionDemo/demo3'; 17 | 18 | 19 | const rootEle = document.getElementById('root'); 20 | 21 | // import './demo/MiniUpdate2State'; 22 | // import './demo/MiniDiff'; 23 | // import './demo/MiniUseState'; 24 | // import './demo/MiniSchedulePhase'; 25 | 26 | rootEle && ReactDOM.createRoot(rootEle).render(); 27 | // ReactDOM.render( , rootEle) 28 | 29 | -------------------------------------------------------------------------------- /src/demo/BailoutDemo/step2.tsx: -------------------------------------------------------------------------------- 1 | import React, {useState, useEffect} from 'react'; 2 | import {bindHook, utils, getLibraryMethod} from 'log'; 3 | 4 | const {log, COLOR: {SCHEDULE_COLOR, RENDER_COLOR, COMMIT_COLOR}} = utils; 5 | 6 | // bindHook('beginWork', (current, wip) => { 7 | // log(RENDER_COLOR, `beginWork`, getLibraryMethod('getComponentNameFromFiber')?.(wip)); 8 | // }) 9 | 10 | function InputWrapper({children}: {children: React.ReactNode}) { 11 | const [num, updateNum] = useState(0); 12 | 13 | return ( 14 |
15 | updateNum(+e.target.value)} /> 16 |

num is {num}

17 | {children} 18 |
19 | ) 20 | } 21 | 22 | export default function App() { 23 | 24 | return ( 25 | 26 | 27 | 28 | ); 29 | } 30 | 31 | 32 | function ExpensiveCpn() { 33 | let now = performance.now(); 34 | while (performance.now() - now < 100) {} 35 | console.log('耗时的组件 render'); 36 | return

耗时的组件

; 37 | } 38 | -------------------------------------------------------------------------------- /src/packages/react-dom/README.md: -------------------------------------------------------------------------------- 1 | # `react-dom` 2 | 3 | This package serves as the entry point to the DOM and server renderers for React. It is intended to be paired with the generic React package, which is shipped as `react` to npm. 4 | 5 | ## Installation 6 | 7 | ```sh 8 | npm install react react-dom 9 | ``` 10 | 11 | ## Usage 12 | 13 | ### In the browser 14 | 15 | ```js 16 | var React = require('react'); 17 | var ReactDOM = require('react-dom'); 18 | 19 | function MyComponent() { 20 | return
Hello World
; 21 | } 22 | 23 | ReactDOM.render(, node); 24 | ``` 25 | 26 | ### On the server 27 | 28 | ```js 29 | var React = require('react'); 30 | var ReactDOMServer = require('react-dom/server'); 31 | 32 | function MyComponent() { 33 | return
Hello World
; 34 | } 35 | 36 | ReactDOMServer.renderToString(); 37 | ``` 38 | 39 | ## API 40 | 41 | ### `react-dom` 42 | 43 | - `findDOMNode` 44 | - `render` 45 | - `unmountComponentAtNode` 46 | 47 | ### `react-dom/server` 48 | 49 | - `renderToString` 50 | - `renderToStaticMarkup` 51 | -------------------------------------------------------------------------------- /src/demo/TransitionDemo/demo3.tsx: -------------------------------------------------------------------------------- 1 | import React, {useState, useEffect, useDeferredValue} from 'react'; 2 | import {bindHook, utils} from 'log'; 3 | 4 | const {log, lanes2Str, COLOR: {SCHEDULE_COLOR, RENDER_COLOR, COMMIT_COLOR}} = utils; 5 | 6 | bindHook('getNextLanes_entangledLanes', (lanes) => { 7 | log(SCHEDULE_COLOR, `纠缠的lane:`, lanes2Str(lanes)); 8 | }) 9 | 10 | bindHook('expiredLanes', (lane) => { 11 | log(SCHEDULE_COLOR, `过期的lane:`, lanes2Str(lane)); 12 | }) 13 | 14 | export default function App() { 15 | const [ctn, updateCtn] = useState(''); 16 | const [num, updateNum] = useState(0); 17 | const deferredNum = useDeferredValue(num); 18 | 19 | return ( 20 |
21 | { 22 | updateCtn(value); 23 | updateNum(num + 1); 24 | }}/> 25 | 26 |
27 | ); 28 | } 29 | 30 | const BusyChild = React.memo(({num}: {num: number}) => { 31 | const cur = performance.now(); 32 | while (performance.now() - cur < 300) {} 33 | 34 | return
{num}
; 35 | }) -------------------------------------------------------------------------------- /src/demo/RenderPhaseDemo.tsx: -------------------------------------------------------------------------------- 1 | import React, {useState} from 'react'; 2 | import {bindHook, getLibraryMethod, utils} from 'log'; 3 | 4 | const {log, COLOR: {SCHEDULE_COLOR, RENDER_COLOR, COMMIT_COLOR}} = utils; 5 | 6 | bindHook('beginWork', (current, wip) => { 7 | log(RENDER_COLOR, `beginWork`, getLibraryMethod('getComponentNameFromFiber')?.(wip)); 8 | }) 9 | 10 | bindHook('changeLanes', (where, before, after) => { 11 | log(RENDER_COLOR, `change lanes:${where}`, `之前:${before} after:${after}`); 12 | }) 13 | 14 | bindHook('completeWork', (current, wip) => { 15 | log(RENDER_COLOR, `completeWork`, getLibraryMethod('getComponentNameFromFiber')?.(wip)); 16 | }) 17 | 18 | // 用于调试 Reconciler 工作流程的Demo 19 | const Cpn = () => { 20 | const [num, updateNum] = useState(0); 21 | 22 | return ( 23 |
{ 24 | updateNum(num + 1) 25 | setTimeout(() => updateNum(num + 1)); 26 | updateNum(num + 1) 27 | updateNum(num + 1) 28 | }} style={{color: `#${num}${num}${num}`}} title={num + ''}> 29 | Hello World {num} 30 |
31 | ) 32 | } 33 | 34 | export default () => { 35 | return ; 36 | } -------------------------------------------------------------------------------- /src/demo/TransitionDemo/demo2.tsx: -------------------------------------------------------------------------------- 1 | import React, {useState, useEffect, useTransition} from 'react'; 2 | import {bindHook, utils} from 'log'; 3 | 4 | const {log, lanes2Str, COLOR: {SCHEDULE_COLOR, RENDER_COLOR, COMMIT_COLOR}} = utils; 5 | 6 | bindHook('getNextLanes_entangledLanes', (lanes) => { 7 | log(SCHEDULE_COLOR, `纠缠的lane:`, lanes2Str(lanes)); 8 | }) 9 | 10 | bindHook('expiredLanes', (lane) => { 11 | log(SCHEDULE_COLOR, `过期的lane:`, lanes2Str(lane)); 12 | }) 13 | 14 | export default function App() { 15 | const [ctn, updateCtn] = useState(''); 16 | const [num, updateNum] = useState(0); 17 | const [isPending, startTransition] = useTransition(); 18 | 19 | return ( 20 |
21 | { 22 | updateCtn(value); 23 | startTransition(() => updateNum(num + 1)) 24 | // updateNum(num + 1) 25 | }}/> 26 | 27 |
28 | ); 29 | } 30 | 31 | const BusyChild = React.memo(({num}: {num: number}) => { 32 | const cur = performance.now(); 33 | while (performance.now() - cur < 300) {} 34 | 35 | return
{num}
; 36 | }) -------------------------------------------------------------------------------- /src/packages/react/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Facebook, Inc. and its affiliates. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/packages/react-dom/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Facebook, Inc. and its affiliates. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/packages/scheduler/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Facebook, Inc. and its affiliates. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/packages/react-cache/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Facebook, Inc. and its affiliates. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/globalLog.ts: -------------------------------------------------------------------------------- 1 | import {bindHook, utils} from 'log'; 2 | 3 | const {log, lanes2Str, lane2LaneName, exitStatus2Str, COLOR: {SCHEDULE_COLOR, RENDER_COLOR, COMMIT_COLOR}} = utils; 4 | 5 | /** 6 | * 所有Demo中会打印的log 7 | */ 8 | 9 | bindHook('shouldTimeSlice', (shouldTimeSlice) => { 10 | log(SCHEDULE_COLOR, `${shouldTimeSlice ? '启用' : '关闭'}时间切片`); 11 | }) 12 | 13 | bindHook('renderRootConcurrent', (root) => { 14 | log(RENDER_COLOR, 'render阶段开始,类型:Concurrent'); 15 | }) 16 | 17 | bindHook('renderRootSync', (root) => { 18 | log(RENDER_COLOR, 'render阶段开始,类型:Sync'); 19 | }) 20 | 21 | bindHook('performConcurrentWorkOnRoot-exitStatus', (exitStatus: number) => { 22 | log(RENDER_COLOR, 'perform Concurrent work 完成状态', exitStatus2Str(exitStatus)); 23 | }) 24 | 25 | bindHook('performSyncWorkOnRoot-exitStatus', (exitStatus: number) => { 26 | log(RENDER_COLOR, 'perform Sync work 完成状态', exitStatus2Str(exitStatus)); 27 | }) 28 | 29 | bindHook('commitBegin', (reason, lanes) => { 30 | log(COMMIT_COLOR, `commit阶段开始,由于:${reason}, lanes:${lanes2Str(lanes)}`); 31 | }) 32 | 33 | 34 | 35 | // bindHook('bubbleProperties', (didBailout, wip) => { 36 | // log(RENDER_COLOR, `bubbleProperties`, getType2Use(wip)); 37 | // }) -------------------------------------------------------------------------------- /src/packages/log/index.ts: -------------------------------------------------------------------------------- 1 | import * as u from './utils'; 2 | 3 | u.log('#127299', '卡颂:欢迎使用《React技术揭秘》配套调试项目,玩得开心'); 4 | 5 | type TLogCB = (...args: any) => void; 6 | 7 | type TLibrayMethod = (...args: any) => any; 8 | 9 | export type Phase = 'commit' | 'render' | 'schedule'; 10 | 11 | export const utils = u; 12 | 13 | type LibraryMethodName = 'getComponentNameFromFiber'; 14 | const librayMethodMap: { 15 | [name in LibraryMethodName]?: TLibrayMethod 16 | } = {}; 17 | 18 | export function bindHook(bindWhere: string, callback: TLogCB) { 19 | where2LogList[bindWhere] = where2LogList[bindWhere] || []; 20 | where2LogList[bindWhere].push(callback); 21 | } 22 | 23 | const where2LogList: {[where: string]: TLogCB[]} = {}; 24 | 25 | export function logHook(where: string, ...args: any) { 26 | const logList = where2LogList[where]; 27 | Array.isArray(logList) && logList.forEach(cb => cb(...args)); 28 | } 29 | 30 | // 从库里加载方法 31 | export function logLibraryMethod(libraryMethod: TLibrayMethod){ 32 | librayMethodMap[libraryMethod.name as LibraryMethodName] = libraryMethod; 33 | return librayMethodMap; 34 | } 35 | 36 | // 使用库里的方法 37 | export function getLibraryMethod(name: LibraryMethodName) { 38 | return librayMethodMap[name]; 39 | } -------------------------------------------------------------------------------- /src/demo/MiniDiff/diff.ts: -------------------------------------------------------------------------------- 1 | type NodeList = Node[]; 2 | type Flag = 'Placement' | 'Deletion'; 3 | 4 | interface Node { 5 | key: string; 6 | flag?: Flag; 7 | index?: number; 8 | } 9 | 10 | // 用于调试 Diff算法 的Demo 11 | export default function diff(before: NodeList, after: NodeList): NodeList { 12 | let lastPlacedIndex = 0; 13 | const result: NodeList = []; 14 | 15 | const beforeMap = new Map(); 16 | before.forEach((node, i) => { 17 | node.index = i; 18 | beforeMap.set(node.key, node); 19 | }) 20 | 21 | for (let i = 0; i < after.length; i++) { 22 | const afterNode = after[i]; 23 | afterNode.index = i; 24 | const beforeNode = beforeMap.get(afterNode.key); 25 | 26 | if (beforeNode) { 27 | // 复用老节点 28 | beforeMap.delete(beforeNode.key); 29 | 30 | const oldIndex = beforeNode.index as number; 31 | if (oldIndex < lastPlacedIndex) { 32 | afterNode.flag = 'Placement'; 33 | result.push(afterNode); 34 | continue; 35 | } else { 36 | lastPlacedIndex = oldIndex; 37 | } 38 | } else { 39 | // 创建新节点 40 | afterNode.flag = 'Placement'; 41 | result.push(afterNode); 42 | } 43 | } 44 | 45 | beforeMap.forEach(node => { 46 | node.flag = 'Deletion'; 47 | result.push(node); 48 | }); 49 | 50 | return result; 51 | } -------------------------------------------------------------------------------- /src/demo/batchDemo.tsx: -------------------------------------------------------------------------------- 1 | import React, { useRef, useState, useTransition } from "react"; 2 | import ReactDOM from "react-dom"; 3 | 4 | 5 | export default () => { 6 | const [count, updateCount] = useState(0); 7 | const [isPending, startTransition] = useTransition(); 8 | 9 | const domRef = useRef({}); 10 | 11 | const onClick = () => { 12 | // startTransition(() => { 13 | // updateCount(count => count + 1); 14 | // updateCount(count => count + 1); 15 | // updateCount(count => count + 1); 16 | 17 | // console.log("同步的结果:", domRef.current.innerText); 18 | // Promise.resolve().then(() => { 19 | // console.log("微任务的结果:", domRef.current.innerText); 20 | // }); 21 | // setTimeout(() => { 22 | // console.log("宏任务的结果:", domRef.current.innerText); 23 | // }); 24 | // }) 25 | updateCount(count => count + 1); 26 | updateCount(count => count + 1); 27 | updateCount(count => count + 1); 28 | 29 | console.log("同步的结果:", domRef.current.innerText); 30 | Promise.resolve().then(() => { 31 | console.log("微任务的结果:", domRef.current.innerText); 32 | }); 33 | setTimeout(() => { 34 | console.log("宏任务的结果:", domRef.current.innerText); 35 | }); 36 | }; 37 | 38 | 39 | return ( 40 |

41 | {count} 42 |

43 | ) 44 | } -------------------------------------------------------------------------------- /src/packages/log/renderTip/index.ts: -------------------------------------------------------------------------------- 1 | 2 | import './style.css'; 3 | 4 | interface TTipData { 5 | lession: number; 6 | title: string; 7 | mainUrl: string; 8 | } 9 | 10 | export default ({title, lession, mainUrl}: TTipData): void => { 11 | document.title = title; 12 | window.lession = lession; 13 | const ele = document.createElement('section'); 14 | ele.className = 'tip-zone'; 15 | ele.innerHTML = ` 16 | 34 | `; 35 | const target = document.querySelector('#root'); 36 | target?.parentNode?.insertBefore(ele, target); 37 | } -------------------------------------------------------------------------------- /src/demo/Performance/demo4.tsx: -------------------------------------------------------------------------------- 1 | import React, {useState, useEffect} from 'react'; 2 | import {bindHook, utils, getLibraryMethod} from 'log'; 3 | 4 | const {log, COLOR: {SCHEDULE_COLOR, RENDER_COLOR, COMMIT_COLOR}} = utils; 5 | 6 | bindHook('beginWork', (current, wip) => { 7 | log(RENDER_COLOR, `beginWork`, getLibraryMethod('getComponentNameFromFiber')?.(wip)); 8 | }) 9 | 10 | bindHook('completeWork', (current, wip) => { 11 | log(RENDER_COLOR, `completeWork`, getLibraryMethod('getComponentNameFromFiber')?.(wip)); 12 | }) 13 | 14 | export default function App() { 15 | 16 | return ( 17 |
18 | 19 | 20 |
21 | ); 22 | } 23 | 24 | function Input() { 25 | const [num, updateNum] = useState(0); 26 | 27 | return ( 28 | <> 29 | updateNum(+e.target.value)} /> 30 |

num is {num}

31 | 32 | ) 33 | } 34 | 35 | 36 | function ExpensiveCpn() { 37 | let now = performance.now(); 38 | while (performance.now() - now < 100) {} 39 | console.log('耗时的组件 render'); 40 | return ; 41 | } 42 | 43 | function ExpensiveChild() { 44 | let now = performance.now(); 45 | while (performance.now() - now < 100) {} 46 | console.log('耗时的子组件 render'); 47 | return ; 48 | } 49 | 50 | function ExpensiveGrandChild() { 51 | let now = performance.now(); 52 | while (performance.now() - now < 100) {} 53 | console.log('耗时的孙组件 render'); 54 | return

耗时的组件

; 55 | } -------------------------------------------------------------------------------- /src/packages/react-cache/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_from": "react-cache", 3 | "_id": "react-cache@2.0.0-alpha.1", 4 | "_inBundle": false, 5 | "_integrity": "sha512-dDJVVGvxAlZE/dMxDXaxU5ZfcE4fbaSmJVFrCTi6dYWXDp7YjCsnywkpEYG6IURVW+eJrCydAIDcW0FADw0/5w==", 6 | "_location": "/react-cache", 7 | "_phantomChildren": {}, 8 | "_requested": { 9 | "type": "tag", 10 | "registry": true, 11 | "raw": "react-cache", 12 | "name": "react-cache", 13 | "escapedName": "react-cache", 14 | "rawSpec": "", 15 | "saveSpec": null, 16 | "fetchSpec": "latest" 17 | }, 18 | "_requiredBy": [ 19 | "#DEV:/", 20 | "#USER" 21 | ], 22 | "_resolved": "https://registry.npmjs.org/react-cache/-/react-cache-2.0.0-alpha.1.tgz", 23 | "_shasum": "4c119188248bc988a61268458bc18bd845f2ec19", 24 | "_spec": "react-cache", 25 | "_where": "/Users/sc/Documents/react18-demo", 26 | "bugs": { 27 | "url": "https://github.com/facebook/react/issues" 28 | }, 29 | "bundleDependencies": false, 30 | "deprecated": false, 31 | "description": "A basic cache for React applications", 32 | "files": [ 33 | "LICENSE", 34 | "README.md", 35 | "index.js", 36 | "cjs/", 37 | "umd/" 38 | ], 39 | "homepage": "https://github.com/facebook/react#readme", 40 | "name": "react-cache", 41 | "peerDependencies": { 42 | "react": "^16.3.0-alpha.1" 43 | }, 44 | "repository": { 45 | "type": "git", 46 | "url": "git+https://github.com/facebook/react.git" 47 | }, 48 | "version": "2.0.0-alpha.1" 49 | } 50 | -------------------------------------------------------------------------------- /src/packages/react-dom/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function checkDCE() { 4 | /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */ 5 | if ( 6 | typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined' || 7 | typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE !== 'function' 8 | ) { 9 | return; 10 | } 11 | if (process.env.NODE_ENV !== 'production') { 12 | // This branch is unreachable because this function is only called 13 | // in production, but the condition is true only in development. 14 | // Therefore if the branch is still here, dead code elimination wasn't 15 | // properly applied. 16 | // Don't change the message. React DevTools relies on it. Also make sure 17 | // this message doesn't occur elsewhere in this function, or it will cause 18 | // a false positive. 19 | throw new Error('^_^'); 20 | } 21 | try { 22 | // Verify that the code above has been dead code eliminated (DCE'd). 23 | __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(checkDCE); 24 | } catch (err) { 25 | // DevTools shouldn't crash React, no matter what. 26 | // We should still report in case we break this code. 27 | console.error(err); 28 | } 29 | } 30 | 31 | if (process.env.NODE_ENV === 'production') { 32 | // DCE check should happen before ReactDOM bundle executes so that 33 | // DevTools can report bad minification during injection. 34 | checkDCE(); 35 | module.exports = require('./cjs/react-dom.production.min.js'); 36 | } else { 37 | module.exports = require('./cjs/react-dom.development.js'); 38 | } 39 | -------------------------------------------------------------------------------- /src/packages/react-dom/profiling.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function checkDCE() { 4 | /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */ 5 | if ( 6 | typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined' || 7 | typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE !== 'function' 8 | ) { 9 | return; 10 | } 11 | if (process.env.NODE_ENV !== 'production') { 12 | // This branch is unreachable because this function is only called 13 | // in production, but the condition is true only in development. 14 | // Therefore if the branch is still here, dead code elimination wasn't 15 | // properly applied. 16 | // Don't change the message. React DevTools relies on it. Also make sure 17 | // this message doesn't occur elsewhere in this function, or it will cause 18 | // a false positive. 19 | throw new Error('^_^'); 20 | } 21 | try { 22 | // Verify that the code above has been dead code eliminated (DCE'd). 23 | __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(checkDCE); 24 | } catch (err) { 25 | // DevTools shouldn't crash React, no matter what. 26 | // We should still report in case we break this code. 27 | console.error(err); 28 | } 29 | } 30 | 31 | if (process.env.NODE_ENV === 'production') { 32 | // DCE check should happen before ReactDOM bundle executes so that 33 | // DevTools can report bad minification during injection. 34 | checkDCE(); 35 | module.exports = require('./cjs/react-dom.profiling.min.js'); 36 | } else { 37 | module.exports = require('./cjs/react-dom.development.js'); 38 | } 39 | -------------------------------------------------------------------------------- /src/demo/longTaskDemo.tsx: -------------------------------------------------------------------------------- 1 | import React, {useEffect, useRef, useState, useTransition} from 'react'; 2 | import {flushSync} from 'react-dom'; 3 | import {bindHook, utils} from 'log'; 4 | 5 | const {log, lanes2Str, lane2LaneName, COLOR: {SCHEDULE_COLOR, RENDER_COLOR, COMMIT_COLOR}} = utils; 6 | 7 | bindHook('continuationCallback', (root) => { 8 | log(SCHEDULE_COLOR, `continuationCallback`); 9 | }) 10 | bindHook('priorityNotChange', (priority) => { 11 | log(SCHEDULE_COLOR, 'priority没变化,继续原callback', priority); 12 | }) 13 | 14 | bindHook('ensureRootIsScheduled', (lanes, lane) => { 15 | log(SCHEDULE_COLOR, `调度root,lanes:${lanes2Str(lanes)}`, `优先级:${lane2LaneName(lane)}`); 16 | }) 17 | 18 | bindHook('scheduleCallback', (type, cbName, lane) => { 19 | log(SCHEDULE_COLOR, `调度新callback,类型:${type},回调:`, cbName); 20 | }) 21 | 22 | export default function App() { 23 | const [count, updateCount] = useState(0); 24 | const btnRef = useRef(null); 25 | const [isPending, startTransition] = useTransition(); 26 | const len = 40000; 27 | 28 | const onClick = () => { 29 | console.log('click!'); 30 | updateCount(count => count + 1); 31 | } 32 | 33 | useEffect(() => { 34 | setTimeout(() => { 35 | console.log('not click'); 36 | updateCount(100); 37 | }, 1000); 38 | setTimeout(() => { 39 | btnRef.current?.click(); 40 | }, 1010); 41 | }, []) 42 | 43 | return ( 44 |
    45 | count is: {count} 46 | 47 | {Array(len).fill(0).map((_, i) =>
  • {i}
  • )} 48 |
49 | ); 50 | } 51 | -------------------------------------------------------------------------------- /src/demo/UseEffectDemo/index.tsx: -------------------------------------------------------------------------------- 1 | import React, { useCallback, useState, useMemo,useRef, useEffect, useLayoutEffect, useInsertionEffect } from "react"; 2 | 3 | function Effect1() { 4 | const [state,setState] = useState(0); 5 | 6 | useEffect(function create1 () { 7 | console.log('effect1 mount') 8 | return () => { 9 | // 清除订阅 10 | console.log('effect1 unmount') 11 | }; 12 | }); 13 | return (
setState(state+1)}>
) 14 | } 15 | function Effect2(){ 16 | const [state,setState] = useState(0); 17 | useEffect(function create21 () { 18 | console.log('effect21 mount') 19 | return () => { 20 | // 清除订阅 21 | console.log('effect21 unmount') 22 | }; 23 | }); 24 | 25 | useLayoutEffect(function create22 () { 26 | console.log('effect22 layout mount') 27 | // throw 1; 28 | return () => { 29 | // 清除订阅 30 | console.log('effect22 layout unmount') 31 | }; 32 | }); 33 | 34 | useInsertionEffect(function create23 () { 35 | console.log('effect23 insertion mount') 36 | return () => { 37 | // 清除订阅 38 | console.log('effect23 insertion unmount') 39 | }; 40 | }); 41 | 42 | 43 | return (
setState(state+1)}>click
) 44 | } 45 | 46 | function Effect3(){ 47 | const [state,setState] = useState(0); 48 | useEffect(function create3 () { 49 | console.log('effect3 mount') 50 | return () => { 51 | // 清除订阅 52 | console.log('effect3 unmount') 53 | }; 54 | }); 55 | return (
setState(state+1)}>click
) 56 | } 57 | 58 | 59 | export default Effect1; -------------------------------------------------------------------------------- /src/demo/MiniEventSystem/eventSystem.ts: -------------------------------------------------------------------------------- 1 | class SyntheticEvent { 2 | nativeEvent: Event; 3 | _stopPropagation: boolean; 4 | constructor(e: Event) { 5 | this.nativeEvent = e; 6 | this._stopPropagation = false; 7 | } 8 | stopPropagation() { 9 | this._stopPropagation = true; 10 | if (this.nativeEvent.stopPropagation) { 11 | this.nativeEvent.stopPropagation(); 12 | } 13 | } 14 | } 15 | 16 | const triggerEventFlow = (paths: any, type: string, se: SyntheticEvent) => { 17 | for (let i = paths.length; i--; ) { 18 | const pathNode = paths[i]; 19 | const callback = pathNode[type]; 20 | if (callback) { 21 | callback.call(null, se); 22 | } 23 | if (se._stopPropagation) { 24 | break; 25 | } 26 | } 27 | }; 28 | 29 | const dispatchEvent = (e: Event, type: string) => { 30 | const se = new SyntheticEvent(e); 31 | const ele = e.target; 32 | let fiber; 33 | if (!ele) { 34 | return; 35 | } 36 | for (let prop in ele) { 37 | if (prop.toLowerCase().includes("fiber")) { 38 | fiber = (ele as any)[prop]; 39 | } 40 | } 41 | const paths = collectPaths(type, fiber); 42 | triggerEventFlow(paths, type + "CAPTURE", se); 43 | if (!se._stopPropagation) { 44 | triggerEventFlow(paths.reverse(), type, se); 45 | } 46 | }; 47 | 48 | const collectPaths = (type: string, begin: any): any[] => { 49 | const paths = []; 50 | while (begin.tag !== 3) { 51 | const { memoizedProps, tag } = begin; 52 | if (tag === 5) { 53 | const eventName = ("on" + type).toUpperCase(); 54 | if (memoizedProps && Object.keys(memoizedProps).includes(eventName)) { 55 | const pathNode: any = {}; 56 | pathNode[type.toUpperCase()] = memoizedProps[eventName]; 57 | paths.push(pathNode); 58 | } 59 | } 60 | begin = begin.return; 61 | } 62 | return paths; 63 | }; 64 | 65 | export const addEvent = (container: HTMLElement, type: string) => { 66 | container.addEventListener(type, (e) => { 67 | dispatchEvent(e, type.toUpperCase()); 68 | }); 69 | }; 70 | -------------------------------------------------------------------------------- /src/packages/scheduler/cjs/scheduler-unstable_post_task.production.min.js: -------------------------------------------------------------------------------- 1 | /** @license React vundefined 2 | * scheduler-unstable_post_task.production.min.js 3 | * 4 | * Copyright (c) Facebook, Inc. and its affiliates. 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE file in the root directory of this source tree. 8 | */ 9 | 'use strict';var a=window.performance,g=window.setTimeout,h=global.scheduler,k=a.now.bind(a),l=0,m=3;function p(c,d,b,f){l=k()+5;try{m=c;var e=f(!1);if("function"===typeof e){var n=new TaskController,r={priority:d,signal:n.signal};b._controller=n;h.postTask(p.bind(null,c,d,b,e),r).catch(q)}}catch(t){g(function(){throw t;})}finally{m=3}}function q(){}exports.unstable_IdlePriority=5;exports.unstable_ImmediatePriority=1;exports.unstable_LowPriority=4;exports.unstable_NormalPriority=3; 10 | exports.unstable_Profiling=null;exports.unstable_UserBlockingPriority=2;exports.unstable_cancelCallback=function(c){c._controller.abort()};exports.unstable_continueExecution=function(){};exports.unstable_forceFrameRate=function(){};exports.unstable_getCurrentPriorityLevel=function(){return m};exports.unstable_getFirstCallbackNode=function(){return null};exports.unstable_next=function(c){switch(m){case 1:case 2:case 3:var d=3;break;default:d=m}var b=m;m=d;try{return c()}finally{m=b}}; 11 | exports.unstable_now=k;exports.unstable_pauseExecution=function(){};exports.unstable_requestPaint=function(){};exports.unstable_runWithPriority=function(c,d){var b=m;m=c;try{return d()}finally{m=b}}; 12 | exports.unstable_scheduleCallback=function(c,d,b){switch(c){case 1:case 2:var f="user-blocking";break;case 4:case 3:f="user-visible";break;case 5:f="background";break;default:f="user-visible"}var e=new TaskController;b={priority:f,delay:"object"===typeof b&&null!==b?b.delay:0,signal:e.signal};e={_controller:e};h.postTask(p.bind(null,c,f,e,d),b).catch(q);return e};exports.unstable_shouldYield=function(){return k()>=l}; 13 | exports.unstable_wrapCallback=function(c){var d=m;return function(){var b=m;m=d;try{return c()}finally{m=b}}}; 14 | -------------------------------------------------------------------------------- /src/packages/scheduler/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_from": "scheduler@0.21.0-beta-96ca8d915-20211115", 3 | "_id": "scheduler@0.21.0-beta-96ca8d915-20211115", 4 | "_inBundle": false, 5 | "_integrity": "sha512-gm2zVVyjuIHlcqdAv57Tk/lFBf7+RDhYvIEaOZiKf3/YpIZbsiMnfy6yP6+VR3pS//V2LY5Mv8bf6fS+4IOWbg==", 6 | "_location": "/scheduler", 7 | "_phantomChildren": {}, 8 | "_requested": { 9 | "type": "version", 10 | "registry": true, 11 | "raw": "scheduler@0.21.0-beta-96ca8d915-20211115", 12 | "name": "scheduler", 13 | "escapedName": "scheduler", 14 | "rawSpec": "0.21.0-beta-96ca8d915-20211115", 15 | "saveSpec": null, 16 | "fetchSpec": "0.21.0-beta-96ca8d915-20211115" 17 | }, 18 | "_requiredBy": [ 19 | "/react-dom" 20 | ], 21 | "_resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0-beta-96ca8d915-20211115.tgz", 22 | "_shasum": "b15758da1f33734ab1219aa5147ea79037a42013", 23 | "_spec": "scheduler@0.21.0-beta-96ca8d915-20211115", 24 | "_where": "/Users/sc/Documents/react18-demo/node_modules/react-dom", 25 | "browserify": { 26 | "transform": [ 27 | "loose-envify" 28 | ] 29 | }, 30 | "bugs": { 31 | "url": "https://github.com/facebook/react/issues" 32 | }, 33 | "bundleDependencies": false, 34 | "dependencies": { 35 | "loose-envify": "^1.1.0", 36 | "object-assign": "^4.1.1" 37 | }, 38 | "deprecated": false, 39 | "description": "Cooperative scheduler for the browser environment.", 40 | "files": [ 41 | "LICENSE", 42 | "README.md", 43 | "build-info.json", 44 | "index.js", 45 | "unstable_mock.js", 46 | "unstable_post_task.js", 47 | "cjs/", 48 | "umd/" 49 | ], 50 | "homepage": "https://reactjs.org/", 51 | "keywords": [ 52 | "react" 53 | ], 54 | "license": "MIT", 55 | "main": "index.js", 56 | "name": "scheduler", 57 | "repository": { 58 | "type": "git", 59 | "url": "git+https://github.com/facebook/react.git", 60 | "directory": "packages/scheduler" 61 | }, 62 | "version": "0.21.0-beta-96ca8d915-20211115" 63 | } 64 | -------------------------------------------------------------------------------- /server/index.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | const express = require('express') 4 | const { createServer: createViteServer } = require('vite') 5 | 6 | async function createServer() { 7 | const app = express() 8 | 9 | // 以中间件模式创建 Vite 应用,这将禁用 Vite 自身的 HTML 服务逻辑 10 | // 并让上级服务器接管控制 11 | // 12 | // 如果你想使用 Vite 自己的 HTML 服务逻辑(将 Vite 作为 13 | // 一个开发中间件来使用),那么这里请用 'html' 14 | const vite = await createViteServer({ 15 | server: { middlewareMode: 'ssr' } 16 | }) 17 | // 使用 vite 的 Connect 实例作为中间件 18 | app.use(vite.middlewares) 19 | 20 | app.use('*', async (req, res) => { 21 | const url = req.originalUrl 22 | 23 | try { 24 | // 1. 读取 index.html 25 | let template = fs.readFileSync( 26 | path.resolve(__dirname, '../index.html'), 27 | 'utf-8' 28 | ) 29 | 30 | // 2. 应用 Vite HTML 转换。这将会注入 Vite HMR 客户端, 31 | // 同时也会从 Vite 插件应用 HTML 转换。 32 | // 例如:@vitejs/plugin-react-refresh 中的 global preambles 33 | template = await vite.transformIndexHtml(url, template) 34 | 35 | // 3. 加载服务器入口。vite.ssrLoadModule 将自动转换 36 | // 你的 ESM 源码使之可以在 Node.js 中运行!无需打包 37 | // 并提供类似 HMR 的根据情况随时失效。 38 | 39 | const a = await vite.ssrLoadModule(path.resolve(__dirname, '../src/demo/SSRDemo')) 40 | 41 | console.log('aaa', a); 42 | 43 | // 4. 渲染应用的 HTML。这假设 entry-server.js 导出的 `render` 44 | // 函数调用了适当的 SSR 框架 API。 45 | // 例如 ReactDOMServer.renderToString() 46 | // const appHtml = await render(url) 47 | 48 | // const appHTML = ReactDOMServer.renderToString(); 49 | 50 | // 5. 注入渲染后的应用程序 HTML 到模板中。 51 | const html = template.replace(``, template) 52 | 53 | // 6. 返回渲染后的 HTML。 54 | res.status(200).set({ 'Content-Type': 'text/html' }).end(html) 55 | } catch (e) { 56 | // 如果捕获到了一个错误,让 Vite 来修复该堆栈,这样它就可以映射回 57 | // 你的实际源码中。 58 | vite.ssrFixStacktrace(e) 59 | console.error(e) 60 | res.status(500).end(e.message) 61 | } 62 | }) 63 | 64 | app.listen(3000) 65 | } 66 | 67 | createServer() -------------------------------------------------------------------------------- /src/demo/CommitPhaseDemo.tsx: -------------------------------------------------------------------------------- 1 | import React, {useState, Component, useLayoutEffect} from 'react'; 2 | import {bindHook, utils} from 'log'; 3 | 4 | const {log, COLOR: {SCHEDULE_COLOR, RENDER_COLOR, COMMIT_COLOR}} = utils; 5 | 6 | bindHook('commitBeforeMutationEffectsOnFiber', (fiber) => { 7 | log(COMMIT_COLOR, `commit BeforeMutationEffects`, fiber); 8 | }) 9 | 10 | bindHook('commitMutationEffectsOnFiber', (fiber) => { 11 | log(COMMIT_COLOR, `commit MutationEffects`, fiber); 12 | }) 13 | 14 | bindHook('commitLayoutEffectOnFiber', (fiber) => { 15 | log(COMMIT_COLOR, `commit LayoutEffect`, fiber); 16 | }) 17 | 18 | bindHook('commitUpdateQueue', (fiber, effects) => { 19 | log(COMMIT_COLOR, `commit UpdateQueue`, effects); 20 | }) 21 | 22 | bindHook('updateDOMProperties', (dom, type) => { 23 | log(COMMIT_COLOR, `更新DOM属性 ${type}`, dom); 24 | }) 25 | 26 | bindHook('updateDOM', (fiber, type) => { 27 | log(COMMIT_COLOR, `更新DOM ${type}`, fiber); 28 | }) 29 | 30 | 31 | // 用于调试 commit阶段 工作流程的Demo 32 | export default () => { 33 | const [num, updateNum] = useState(0); 34 | 35 | // 用于查看 删除DOM Element 的处理 36 | if (num % 2 !== 0) { 37 | return
noop
; 38 | } 39 | 40 | return ( 41 |
updateNum(num + 1)} style={{color: `#${num}${num}${num}`}} title={num + ''}> 42 | 43 |
44 | 45 |
46 |
47 | ) 48 | } 49 | 50 | class SomeClassComponent extends Component { 51 | state = { 52 | num: 0 53 | } 54 | componentWillUnmount() { 55 | console.log('SomeClassComponent will unmount'); 56 | } 57 | onClick = (e: React.MouseEvent) => { 58 | // 用于查看 updateQueue 的处理 59 | e.stopPropagation(); 60 | this.setState({ 61 | num: this.state.num + 1 62 | }, () => { 63 | console.log('class cpn callback!'); 64 | }) 65 | } 66 | render() { 67 | return

some class component {this.state.num}

; 68 | } 69 | } 70 | 71 | function SomeFunctionComponent() { 72 | useLayoutEffect(() => { 73 | return () => console.log('SomeFunctionComponent will unmount'); 74 | }, []) 75 | return

some function component

; 76 | } 77 | -------------------------------------------------------------------------------- /src/packages/react-dom/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_from": "react-dom@beta", 3 | "_id": "react-dom@18.0.0-beta-96ca8d915-20211115", 4 | "_inBundle": false, 5 | "_integrity": "sha512-ISFQGQ0lHt+fz/Ch9K9coggTWzp9ScfuvzdshGJ73z5AI7mi9i6mVjVekMDnx0wiECjHP1s87rxNDQGGj9XnHw==", 6 | "_location": "/react-dom", 7 | "_phantomChildren": {}, 8 | "_requested": { 9 | "type": "tag", 10 | "registry": true, 11 | "raw": "react-dom@beta", 12 | "name": "react-dom", 13 | "escapedName": "react-dom", 14 | "rawSpec": "beta", 15 | "saveSpec": null, 16 | "fetchSpec": "beta" 17 | }, 18 | "_requiredBy": [ 19 | "#USER", 20 | "/" 21 | ], 22 | "_resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.0.0-beta-96ca8d915-20211115.tgz", 23 | "_shasum": "511a754eddbb760c83d85251249fe9c52522326e", 24 | "_spec": "react-dom@beta", 25 | "_where": "/Users/sc/Documents/react18-demo", 26 | "browser": { 27 | "./server.js": "./server.browser.js" 28 | }, 29 | "browserify": { 30 | "transform": [ 31 | "loose-envify" 32 | ] 33 | }, 34 | "bugs": { 35 | "url": "https://github.com/facebook/react/issues" 36 | }, 37 | "bundleDependencies": false, 38 | "dependencies": { 39 | "loose-envify": "^1.1.0", 40 | "object-assign": "^4.1.1", 41 | "scheduler": "0.21.0-beta-96ca8d915-20211115" 42 | }, 43 | "deprecated": false, 44 | "description": "React package for working with the DOM.", 45 | "files": [ 46 | "LICENSE", 47 | "README.md", 48 | "build-info.json", 49 | "index.js", 50 | "profiling.js", 51 | "server.js", 52 | "server.browser.js", 53 | "server.node.js", 54 | "test-utils.js", 55 | "cjs/", 56 | "umd/" 57 | ], 58 | "homepage": "https://reactjs.org/", 59 | "keywords": [ 60 | "react" 61 | ], 62 | "license": "MIT", 63 | "main": "index.js", 64 | "name": "react-dom", 65 | "peerDependencies": { 66 | "react": "18.0.0-beta-96ca8d915-20211115" 67 | }, 68 | "repository": { 69 | "type": "git", 70 | "url": "git+https://github.com/facebook/react.git", 71 | "directory": "packages/react-dom" 72 | }, 73 | "scripts": { 74 | "start": "node server.js" 75 | }, 76 | "version": "18.0.0-beta-96ca8d915-20211115" 77 | } 78 | -------------------------------------------------------------------------------- /src/packages/react-cache/cjs/react-cache.production.min.js: -------------------------------------------------------------------------------- 1 | /** @license React v16.6.0 2 | * react-cache.production.min.js 3 | * 4 | * Copyright (c) Facebook, Inc. and its affiliates. 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE file in the root directory of this source tree. 8 | */ 9 | 10 | 'use strict';Object.defineProperty(exports,"__esModule",{value:!0});var l=require("react"),m=require("scheduler"),n=l.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner;function p(c,e){var f=n.currentDispatcher;if(null===f)throw Error("react-cache: read and preload may only be called from within a component's render. They are not supported in event handlers or lifecycle methods.");return f.readContext(c,e)}function q(c){return c} 11 | var r=function(c){function e(){!1===h&&k>g&&(h=!0,m.unstable_scheduleCallback(f))}function f(){h=!1;var d=g;if(null!==a)for(var b=a.previous;k>d&&null!==b;){var c=b.onDelete,e=b.previous;b.onDelete=null;b.previous=b.next=null;b===a?a=b=null:(a.previous=e,e.next=a,b=e);--k;c()}}var g=c,a=null,k=0,h=!1;return{add:function(d,b){d={value:d,onDelete:b,next:null,previous:null};null===a?d.previous=d.next=d:(b=a.previous,b.next=d,d.previous=b,a.previous=d,d.next=a);a=d;k+=1;return d},update:function(a,b){a.value= 12 | b},access:function(d){var b=d.next;if(null!==b){var c=a;if(a!==d){var f=d.previous;f.next=b;b.previous=f;b=c.previous;b.next=d;d.previous=b;c.previous=d;d.next=c;a=d}}e();return d.value},setLimit:function(a){g=a;e()}}}(500),t=new Map,u=l.createContext(null); 13 | function v(c,e,f,g){var a=t.get(c);void 0===a&&(a=new Map,t.set(c,a));var k=a.get(g);if(void 0===k){e=e(f);e.then(function(a){if(0===h.status){var b=h;b.status=1;b.value=a}},function(a){if(0===h.status){var b=h;b.status=2;b.value=a}});var h={status:0,value:e};c=r.add(h,w.bind(null,c,g));a.set(g,c);return h}return r.access(k)}function w(c,e){var f=t.get(c);void 0!==f&&(f.delete(e),0===f.size&&t.delete(c))} 14 | exports.unstable_createResource=function(c,e){var f=void 0!==e?e:q,g={read:function(a){p(u);var e=f(a);a=v(g,c,a,e);switch(a.status){case 0:throw a.value;case 1:return a.value;case 2:throw a.value;}},preload:function(a){p(u);var e=f(a);v(g,c,a,e)}};return g};exports.unstable_setGlobalCacheLimit=function(c){r.setLimit(c)}; 15 | -------------------------------------------------------------------------------- /src/packages/react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_from": "react@beta", 3 | "_id": "react@18.0.0-beta-96ca8d915-20211115", 4 | "_inBundle": false, 5 | "_integrity": "sha512-Io6qvToVSO1UWNWbJSH16gbgYTkseSbfpQvLaB7JPutt0QVvjpUlEE0nfmww77CFdawxGkyfm/x4zvNTlMkHsw==", 6 | "_location": "/react", 7 | "_phantomChildren": {}, 8 | "_requested": { 9 | "type": "tag", 10 | "registry": true, 11 | "raw": "react@beta", 12 | "name": "react", 13 | "escapedName": "react", 14 | "rawSpec": "beta", 15 | "saveSpec": null, 16 | "fetchSpec": "beta" 17 | }, 18 | "_requiredBy": [ 19 | "#USER", 20 | "/" 21 | ], 22 | "_resolved": "https://registry.npmjs.org/react/-/react-18.0.0-beta-96ca8d915-20211115.tgz", 23 | "_shasum": "0b2a0cd808b85fdce987a0c254e0fab979a3828d", 24 | "_spec": "react@beta", 25 | "_where": "/Users/sc/Documents/react18-demo", 26 | "browserify": { 27 | "transform": [ 28 | "loose-envify" 29 | ] 30 | }, 31 | "bugs": { 32 | "url": "https://github.com/facebook/react/issues" 33 | }, 34 | "bundleDependencies": false, 35 | "dependencies": { 36 | "loose-envify": "^1.1.0", 37 | "object-assign": "^4.1.1" 38 | }, 39 | "deprecated": false, 40 | "description": "React is a JavaScript library for building user interfaces.", 41 | "engines": { 42 | "node": ">=0.10.0" 43 | }, 44 | "exports": { 45 | ".": { 46 | "react-server": "./unstable-shared-subset.js", 47 | "default": "./index.js" 48 | }, 49 | "./index": { 50 | "react-server": "./unstable-shared-subset.js", 51 | "default": "./index.js" 52 | }, 53 | "./build-info.json": "./build-info.json", 54 | "./jsx-runtime": "./jsx-runtime.js", 55 | "./jsx-dev-runtime": "./jsx-dev-runtime.js", 56 | "./": "./" 57 | }, 58 | "files": [ 59 | "LICENSE", 60 | "README.md", 61 | "build-info.json", 62 | "index.js", 63 | "cjs/", 64 | "umd/", 65 | "jsx-runtime.js", 66 | "jsx-dev-runtime.js", 67 | "unstable-shared-subset.js" 68 | ], 69 | "homepage": "https://reactjs.org/", 70 | "keywords": [ 71 | "react" 72 | ], 73 | "license": "MIT", 74 | "main": "index.js", 75 | "name": "react", 76 | "repository": { 77 | "type": "git", 78 | "url": "git+https://github.com/facebook/react.git", 79 | "directory": "packages/react" 80 | }, 81 | "version": "18.0.0-beta-96ca8d915-20211115" 82 | } 83 | -------------------------------------------------------------------------------- /src/packages/react-cache/umd/react-cache.production.min.js: -------------------------------------------------------------------------------- 1 | /** @license React v16.6.0 2 | * react-cache.production.min.js 3 | * 4 | * Copyright (c) Facebook, Inc. and its affiliates. 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE file in the root directory of this source tree. 8 | */ 9 | 'use strict';(function(k,m){"object"===typeof exports&&"undefined"!==typeof module?m(exports,require("react"),require("scheduler")):"function"===typeof define&&define.amd?define(["exports","react","scheduler"],m):m(k.ReactCache={},k.React,k.Scheduler)})(this,function(k,m,u){function q(c,e){var f=v.currentDispatcher;if(null===f)throw Error("react-cache: read and preload may only be called from within a component's render. They are not supported in event handlers or lifecycle methods.");return f.readContext(c, 10 | e)}function w(c){return c}function r(c,e,f,g){var a=n.get(c);void 0===a&&(a=new Map,n.set(c,a));var l=a.get(g);if(void 0===l){e=e(f);e.then(function(a){if(0===h.status){var b=h;b.status=1;b.value=a}},function(a){if(0===h.status){var b=h;b.status=2;b.value=a}});var h={status:0,value:e};c=p.add(h,x.bind(null,c,g));a.set(g,c);return h}return p.access(l)}function x(c,e){var f=n.get(c);void 0!==f&&(f.delete(e),0===f.size&&n.delete(c))}var v=m.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner, 11 | p=function(c){function e(){!1===h&&l>g&&(h=!0,u.unstable_scheduleCallback(f))}function f(){h=!1;var b=g;if(null!==a)for(var d=a.previous;l>b&&null!==d;){var c=d.onDelete,e=d.previous;d.onDelete=null;d.previous=d.next=null;d===a?a=d=null:(a.previous=e,e.next=a,d=e);--l;c()}}var g=c,a=null,l=0,h=!1;return{add:function(b,d){b={value:b,onDelete:d,next:null,previous:null};null===a?b.previous=b.next=b:(d=a.previous,d.next=b,b.previous=d,a.previous=b,b.next=a);a=b;l+=1;return b},update:function(a,d){a.value= 12 | d},access:function(b){var d=b.next;if(null!==d){var c=a;if(a!==b){var f=b.previous;f.next=d;d.previous=f;d=c.previous;d.next=b;b.previous=d;c.previous=b;b.next=c;a=b}}e();return b.value},setLimit:function(a){g=a;e()}}}(500),n=new Map,t=m.createContext(null);k.unstable_createResource=function(c,e){var f=void 0!==e?e:w,g={read:function(a){q(t);var e=f(a);a=r(g,c,a,e);switch(a.status){case 0:throw a.value;case 1:return a.value;case 2:throw a.value;}},preload:function(a){q(t);var e=f(a);r(g,c,a,e)}}; 13 | return g};k.unstable_setGlobalCacheLimit=function(c){p.setLimit(c)};Object.defineProperty(k,"__esModule",{value:!0})}); 14 | -------------------------------------------------------------------------------- /src/demo/SuspenseDemo/demo2.tsx: -------------------------------------------------------------------------------- 1 | import React, { Suspense } from "react"; 2 | import {bindHook, getLibraryMethod, utils} from 'log'; 3 | import { wrapPromise } from "./utils"; 4 | const {log, lanes2Str, COLOR: {SCHEDULE_COLOR, RENDER_COLOR, COMMIT_COLOR}} = utils; 5 | 6 | bindHook('beginWork', (current, wip) => { 7 | log(RENDER_COLOR, `beginWork`, getLibraryMethod('getComponentNameFromFiber')?.(wip)); 8 | }) 9 | 10 | bindHook('markRootSuspended', (suspendedLanes, rootSuspendedLanes, rootPingedLanes) => { 11 | log(SCHEDULE_COLOR, 'mark Root Suspended', lanes2Str(suspendedLanes)); 12 | }) 13 | bindHook('markRootEntangled', (lanes) => { 14 | log(SCHEDULE_COLOR, 'mark Root Entangled', lanes2Str(lanes)); 15 | }) 16 | 17 | bindHook('attachWakeableListeners', (root, wakeable, lanes) => { 18 | log(RENDER_COLOR, `设置一个ping,优先级为${lanes2Str(lanes)}`, wakeable); 19 | }) 20 | bindHook('markRootPinged', (rootPingedLanes) => { 21 | log(RENDER_COLOR, 'Root Pinged,lanes:', lanes2Str(rootPingedLanes)); 22 | }) 23 | 24 | bindHook('retryTimedOutBoundary', (retryLane) => { 25 | log(RENDER_COLOR, 'Root retry,lane:', lanes2Str(retryLane)); 26 | }) 27 | 28 | bindHook('pushRenderLanes', (fiber, lanes) => { 29 | log(RENDER_COLOR, 'OffscreenComponent push Render Lanes:', lanes2Str(lanes)); 30 | }) 31 | 32 | bindHook('getNextLanes_entangledLanes', (lanes) => { 33 | log(RENDER_COLOR, 'getNextLanes entangledLanes', lanes2Str(lanes)); 34 | }) 35 | 36 | const cache = new Map(); 37 | 38 | function getPicNum(who: string) { 39 | switch (who) { 40 | case "kaSong": 41 | return 230; 42 | case "xiaoMing": 43 | return 122; 44 | default: 45 | return 0; 46 | } 47 | } 48 | 49 | function getTotalPicNum(u1: string, u2: string) { 50 | const cacheKey = `${u1} ${u2}`; 51 | const resourceCache = cache.get(cacheKey); 52 | 53 | if (resourceCache) { 54 | return resourceCache; 55 | } 56 | 57 | const picNumPromise = new Promise((resolve) => { 58 | setTimeout(() => { 59 | resolve(getPicNum(u1) + getPicNum(u2)); 60 | }, 4000); 61 | }); 62 | const resource = wrapPromise(picNumPromise); 63 | cache.set(cacheKey, resource); 64 | return resource; 65 | } 66 | 67 | export default function App() { 68 | return ( 69 | 加载中...}> 70 | 71 | 72 | ); 73 | } 74 | 75 | function TotalPicNum({ u1, u2 }: {u1: string; u2: string}) { 76 | const num = getTotalPicNum(u1, u2).read(); 77 | return
总数量为{num}
; 78 | } 79 | 80 | -------------------------------------------------------------------------------- /src/demo/ErrorCatchDemo.tsx: -------------------------------------------------------------------------------- 1 | import React, {useState, Component, useLayoutEffect} from 'react'; 2 | import {bindHook, utils, Phase} from 'log'; 3 | 4 | const {log, getPhaseFromExecutionContext, COLOR: {SCHEDULE_COLOR, RENDER_COLOR, COMMIT_COLOR, USERSPACE_COLOR}} = utils; 5 | 6 | const phaseName2Color = { 7 | commit: COMMIT_COLOR, 8 | schedule: SCHEDULE_COLOR, 9 | render: RENDER_COLOR, 10 | noop: USERSPACE_COLOR 11 | } 12 | 13 | bindHook('createClassErrorUpdate', (fnName, executionContext, fiber, update) => { 14 | log(phaseName2Color[getPhaseFromExecutionContext(executionContext)], `由于${fnName},在ClassComponent创建ErrorUpdate`, fiber); 15 | }) 16 | 17 | bindHook('createRootErrorUpdate', (executionContext, fiber, update) => { 18 | log(phaseName2Color[getPhaseFromExecutionContext(executionContext)], `render阶段在Root捕获错误`, fiber); 19 | }) 20 | 21 | bindHook('captureCommitPhaseErrorOnRoot', (errorInfo, update, root) => { 22 | log(COMMIT_COLOR, `commit阶段在Root捕获错误`, errorInfo); 23 | }) 24 | 25 | bindHook('ErrorUpdate on ClassComponent', (phase: Phase, update, fiber) => { 26 | log(phaseName2Color[phase], `${phase}阶段在ClassComponent调度ErrorUpdate`, fiber); 27 | }) 28 | 29 | bindHook('ErrorUpdate on Root', (phase: Phase, update, fiber) => { 30 | log(phaseName2Color[phase], `${phase}阶段在Root调度ErrorUpdate`, fiber); 31 | }) 32 | 33 | 34 | export default () => { 35 | const [num, updateNum] = useState(0); 36 | 37 | return ( 38 |
updateNum(num + 1)} style={{color: `#${num}${num}${num}`}} title={num + ''}> 39 | 40 | 41 | 42 |
43 | ) 44 | } 45 | 46 | class ErrorBoundary extends Component { 47 | state = { 48 | hasError: false 49 | } 50 | // static getDerivedStateFromError() { 51 | // console.log('in'); 52 | // return { 53 | // hasError: true 54 | // }; 55 | // } 56 | // 试试注释componentDidCatch,观察错误冒泡到Root处理的情况 57 | componentDidCatch() { 58 | console.warn('catch error in componentDidCatch'); 59 | } 60 | render() { 61 | 62 | if (this.state.hasError) { 63 | return
Error !
; 64 | } 65 | 66 | return
{this.props.children}
; 67 | } 68 | } 69 | 70 | function SomeFunctionComponent() { 71 | useLayoutEffect(() => { 72 | // commit阶段抛出错误 73 | throw new Error("Error!"); 74 | }, []) 75 | 76 | // render阶段抛出错误 77 | // throw new Error("Error!"); 78 | return

some function component

; 79 | } 80 | 81 | // 事件回调中的错误不会被catch 82 | // const SomeFunctionComponent = () => { 83 | // const handleClick = () => { 84 | // throw new Error("错误发生") 85 | // }; 86 | // return
Hello
; 87 | // } -------------------------------------------------------------------------------- /src/demo/SuspenseDemo/demo1.tsx: -------------------------------------------------------------------------------- 1 | import React, { Suspense, useState, useEffect, useTransition } from "react"; 2 | import {bindHook, getLibraryMethod, utils} from 'log'; 3 | import {sleep, wrapPromise} from './utils'; 4 | 5 | const {log, lanes2Str, COLOR: {SCHEDULE_COLOR, RENDER_COLOR, COMMIT_COLOR}} = utils; 6 | 7 | // bindHook('beginWork', (current, wip) => { 8 | // log(RENDER_COLOR, `beginWork`, getLibraryMethod('getComponentNameFromFiber')?.(wip)); 9 | // }) 10 | 11 | bindHook('markRootSuspended', (suspendedLanes, rootSuspendedLanes, rootPingedLanes) => { 12 | log(SCHEDULE_COLOR, 'mark Root Suspended', lanes2Str(suspendedLanes)); 13 | }) 14 | bindHook('markRootEntangled', (lanes) => { 15 | log(SCHEDULE_COLOR, 'mark Root Entangled', lanes2Str(lanes)); 16 | }) 17 | 18 | bindHook('attachWakeableListeners', (root, wakeable, lanes) => { 19 | log(RENDER_COLOR, `设置一个ping,优先级为${lanes2Str(lanes)}`, wakeable); 20 | }) 21 | bindHook('markRootPinged', (rootPingedLanes) => { 22 | log(RENDER_COLOR, 'Root Pinged,lanes:', lanes2Str(rootPingedLanes)); 23 | }) 24 | 25 | bindHook('retryTimedOutBoundary', (retryLane) => { 26 | log(RENDER_COLOR, 'Root retry,lane:', lanes2Str(retryLane)); 27 | }) 28 | 29 | bindHook('pushRenderLanes', (fiber, lanes) => { 30 | log(RENDER_COLOR, 'OffscreenComponent push Render Lanes:', lanes2Str(lanes)); 31 | }) 32 | 33 | bindHook('getNextLanes_entangledLanes', (lanes) => { 34 | log(RENDER_COLOR, 'getNextLanes entangledLanes', lanes2Str(lanes)); 35 | }) 36 | 37 | 38 | 39 | 40 | const createResource = (durationMs: number) => { 41 | return wrapPromise(sleep(durationMs).then(() => "FETCHED RESULT " + Math.ceil(Math.random() * 1000))); 42 | }; 43 | 44 | 45 | function Loading() { 46 | console.log("Loading"); 47 | return
loading...
; 48 | } 49 | 50 | const Sub = ({ count }: {count: number}) => { 51 | const [resource, setResource] = useState<{read: any}>(); 52 | const [isPending, startTransition] = useTransition(); 53 | 54 | return ( 55 |
56 | 65 |
{JSON.stringify({ count, isPending }, null, 2)}
66 | {resource === undefined ? "Initial state" : resource.read()} 67 |
68 | ); 69 | }; 70 | export default () => { 71 | const [count, setCount] = useState(0); 72 | useEffect(() => { 73 | const t = setInterval(() => { 74 | setCount(x => x + 1); 75 | }, 1000); 76 | return () => { 77 | clearInterval(t); 78 | }; 79 | }, []); 80 | return ( 81 | }> 82 | 83 | 84 | ); 85 | }; 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /src/demo/MiniUseState/index.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | interface Window { app: any; } 3 | } 4 | 5 | let callbackNode: number | undefined = undefined; 6 | 7 | let workInProgressHook: Hook | undefined; 8 | let isMount = true; 9 | 10 | type Action = (key: any) => void; 11 | 12 | interface Fiber { 13 | memoizedState?: Hook; 14 | stateNode: () => {click: () => void} 15 | } 16 | 17 | interface Hook { 18 | queue: Queue; 19 | memoizedState: any; 20 | next?: Hook; 21 | } 22 | 23 | interface Update { 24 | action: Action; 25 | next?: Update 26 | } 27 | 28 | interface Queue { 29 | pending?: Update 30 | } 31 | 32 | const fiber: Fiber = { 33 | memoizedState: undefined, 34 | stateNode: App 35 | }; 36 | 37 | function schedule() { 38 | if (callbackNode) { 39 | clearTimeout(callbackNode); 40 | } 41 | callbackNode = setTimeout(() => { 42 | workInProgressHook = fiber.memoizedState; 43 | window.app = fiber.stateNode(); 44 | isMount = false; 45 | }); 46 | } 47 | 48 | function dispatchSetState(queue: Queue, action: Action) { 49 | const update: Update = { 50 | action, 51 | next: undefined 52 | } 53 | if (!queue.pending) { 54 | update.next = update; 55 | } else { 56 | update.next = queue.pending.next; 57 | queue.pending.next = update; 58 | } 59 | queue.pending = update; 60 | 61 | schedule(); 62 | } 63 | 64 | function useState(initialState: any) { 65 | let hook; 66 | 67 | if (isMount) { 68 | hook = { 69 | queue: { 70 | pending: undefined 71 | }, 72 | memoizedState: initialState, 73 | next: undefined 74 | } 75 | if (!fiber.memoizedState) { 76 | fiber.memoizedState = hook; 77 | } else { 78 | (workInProgressHook as Hook).next = hook; 79 | } 80 | workInProgressHook = hook; 81 | } else { 82 | hook = workInProgressHook; 83 | workInProgressHook = (workInProgressHook as Hook).next; 84 | } 85 | 86 | if (!hook) { 87 | throw new Error("目标Hook不存在"); 88 | } 89 | 90 | let baseState = hook.memoizedState; 91 | if (hook.queue.pending) { 92 | let firstUpdate = hook.queue.pending.next as Update; 93 | 94 | do { 95 | const action = firstUpdate.action; 96 | baseState = action(baseState); 97 | firstUpdate = firstUpdate.next as Update; 98 | } while (firstUpdate !== hook.queue.pending.next) 99 | 100 | hook.queue.pending = undefined; 101 | } 102 | hook.memoizedState = baseState; 103 | 104 | return [baseState, dispatchSetState.bind(null, hook.queue)]; 105 | } 106 | 107 | function App() { 108 | const [num1, updateNum1] = useState(0); 109 | const [num2, updateNum2] = useState(100); 110 | 111 | console.log(`${isMount ? 'mount' : 'update'} `, num1, num2); 112 | 113 | return { 114 | click() { 115 | updateNum1((num: number) => num + 1); 116 | updateNum1((num: number) => num + 1); 117 | updateNum2((num: number) => num + 100); 118 | updateNum2((num: number) => num + 100); 119 | } 120 | } 121 | } 122 | 123 | schedule(); 124 | 125 | export {}; -------------------------------------------------------------------------------- /src/demo/MiniSchedulePhase/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | unstable_IdlePriority as IdlePriority, 3 | unstable_ImmediatePriority as ImmediatePriority, 4 | unstable_LowPriority as LowPriority, 5 | unstable_NormalPriority as NormalPriority, 6 | unstable_UserBlockingPriority as UserBlockingPriority, 7 | unstable_getFirstCallbackNode as getFirstCallbackNode, 8 | unstable_scheduleCallback as scheduleCallback, 9 | unstable_shouldYield as shouldYield, 10 | unstable_cancelCallback as cancelCallback, 11 | unstable_runWithPriority as runWithPriority, 12 | unstable_getCurrentPriorityLevel as getCurrentPriorityLevel, 13 | CallbackNode 14 | } from "scheduler"; 15 | 16 | import './style.css'; 17 | 18 | type Priority = typeof IdlePriority | typeof ImmediatePriority | typeof LowPriority | typeof NormalPriority | typeof UserBlockingPriority; 19 | 20 | interface Work { 21 | priority: Priority; 22 | count: number; 23 | } 24 | 25 | const priority2UseList: Priority[] = [ 26 | ImmediatePriority, 27 | UserBlockingPriority, 28 | NormalPriority, 29 | LowPriority 30 | ] 31 | 32 | const priority2Name = [ 33 | 'noop', 34 | 'ImmediatePriority', 35 | 'UserBlockingPriority', 36 | 'NormalPriority', 37 | 'LowPriority', 38 | 'IdlePriority', 39 | ] 40 | 41 | /** 42 | * schedule阶段的mini实现 43 | */ 44 | 45 | const root = document.querySelector('#root') as Element; 46 | const contentBox = document.querySelector('#content') as Element; 47 | 48 | const workList: Work[] = []; 49 | let prevPriority: Priority = IdlePriority; 50 | let curCallback: CallbackNode | null = null; 51 | 52 | 53 | // 初始化优先级对应按钮 54 | priority2UseList.forEach(priority => { 55 | const btn = document.createElement('button'); 56 | root.appendChild(btn); 57 | btn.innerText = priority2Name[priority]; 58 | btn.onclick = () => { 59 | // 插入work 60 | workList.push({ 61 | priority, 62 | count: 100 63 | }); 64 | schedule(); 65 | }; 66 | }) 67 | 68 | /** 69 | * 调度的逻辑 70 | */ 71 | function schedule() { 72 | // 当前可能存在正在调度的回调 73 | const cbNode = getFirstCallbackNode(); 74 | // 取出最高优先级的工作 75 | const curWork = workList.sort((w1, w2) => { 76 | return w1.priority - w2.priority; 77 | })[0]; 78 | 79 | if (!curWork) { 80 | // 没有工作需要执行,退出调度 81 | curCallback = null; 82 | cbNode && cancelCallback(cbNode); 83 | return; 84 | } 85 | 86 | const {priority: curPriority} = curWork; 87 | 88 | if (curPriority === prevPriority) { 89 | // 有工作在进行,比较该工作与正在进行的工作的优先级 90 | // 如果优先级相同,则不需要调度新的,退出调度 91 | return; 92 | } 93 | 94 | // 准备调度当前最高优先级的工作 95 | // 调度之前,如果有工作在进行,则中断他 96 | cbNode && cancelCallback(cbNode); 97 | 98 | // 调度当前最高优先级的工作 99 | curCallback = scheduleCallback(curPriority, perform.bind(null, curWork)); 100 | } 101 | 102 | // 执行具体的工作 103 | function perform(work: Work, didTimeout?: boolean): any { 104 | // 是否需要同步执行,满足1.工作是同步优先级 2.当前调度的任务过期了,需要同步执行 105 | const needSync = work.priority === ImmediatePriority || didTimeout; 106 | while ((needSync || !shouldYield()) && work.count) { 107 | work.count--; 108 | // 执行具体的工作 109 | insertItem(work.priority + ''); 110 | } 111 | prevPriority = work.priority; 112 | 113 | if (!work.count) { 114 | // 完成的work,从workList中删除 115 | const workIndex = workList.indexOf(work); 116 | workList.splice(workIndex, 1); 117 | // 重置优先级 118 | prevPriority = IdlePriority; 119 | } 120 | 121 | const prevCallback = curCallback; 122 | // 调度完后,如果callback变化,代表这是新的work 123 | schedule(); 124 | const newCallback = curCallback; 125 | 126 | if (newCallback && prevCallback === newCallback) { 127 | // callback没变,代表是同一个work,只不过时间切片时间用尽(5ms) 128 | // 返回的函数会被Scheduler继续调用 129 | return perform.bind(null, work); 130 | } 131 | } 132 | 133 | const insertItem = (content: string) => { 134 | const ele = document.createElement('span'); 135 | ele.innerText = `${content}`; 136 | ele.className = `pri-${content}`; 137 | doSomeBuzyWork(10000000); 138 | contentBox.appendChild(ele); 139 | }; 140 | 141 | const doSomeBuzyWork = (len: number) => { 142 | let result = 0; 143 | while(len--) { 144 | result +=len; 145 | } 146 | } -------------------------------------------------------------------------------- /src/packages/log/utils.ts: -------------------------------------------------------------------------------- 1 | interface TWIP { 2 | type: any; 3 | tag: number; 4 | memoizedProps: any; 5 | pendingProps: any; 6 | } 7 | 8 | let logIndex = 0; 9 | 10 | export const log = (color: string, label: string, message?: any) => { 11 | console.log( 12 | `${logIndex++} %c ${label} %c`, 13 | `background-color: ${color}; color: #FFFFFF`, 14 | `background-color: inherit; color: inherit` 15 | , exist(message) ? message : ''); 16 | } 17 | 18 | export const exist = (data: any) => data !== undefined && data !== null; 19 | 20 | export const getReadableAnswer = (count: number, answer: number) => { 21 | return `第${count + 1}题,答案:${answer}`; 22 | } 23 | 24 | export const createCounter = (initialCount = 0) => { 25 | let count = initialCount; 26 | return { 27 | add() { 28 | count++; 29 | }, 30 | reset() { 31 | count = initialCount; 32 | }, 33 | get() { 34 | return count; 35 | } 36 | } 37 | } 38 | 39 | // perform work 完成时的状态 40 | export const exitStatus2Str = (exitStatus: number) => { 41 | return [ 42 | 'RootIncomplete', 43 | 'RootFatalErrored', 44 | 'RootErrored', 45 | 'RootSuspended', 46 | 'RootSuspendedWithDelay', 47 | 'RootCompleted' 48 | ][exitStatus]; 49 | } 50 | 51 | export const lanes2Str = (lanes: number) => { 52 | const str = lanes.toString(2); 53 | return str.split('').reverse().reduce((prev, cur, i) => { 54 | let icon = cur; 55 | if (i !== 0 && i % 4 === 0) { 56 | icon += ' '; 57 | } 58 | return icon + prev; 59 | }, '') 60 | } 61 | 62 | export const lane2LaneName = (lane: number) => { 63 | return { 64 | 0b0000000000000000000000000000000: 'NoLane', 65 | 0b0000000000000000000000000000001: 'SyncLane', 66 | 0b0000000000000000000000000000010: 'InputContinuousHydrationLane', 67 | 0b0000000000000000000000000000100: 'InputContinuousLane', 68 | 0b0000000000000000000000000001000: 'DefaultHydrationLane', 69 | 0b0000000000000000000000000010000: 'DefaultLane', 70 | 0b0000000000000000000000000100000: 'TransitionHydrationLane', 71 | 0b0000000000000000000000001000000: 'TransitionLane1', 72 | 0b0000000000000000000000010000000: 'TransitionLane2', 73 | 0b0000000000000000000000100000000: 'TransitionLane3', 74 | 0b0000000000000000000001000000000: 'TransitionLane4', 75 | 0b0000000000000000000010000000000: 'TransitionLane5', 76 | 0b0000000000000000000100000000000: 'TransitionLane6', 77 | 0b0000000000000000001000000000000: 'TransitionLane7', 78 | 0b0000000000000000010000000000000: 'TransitionLane8', 79 | 0b0000000000000000100000000000000: 'TransitionLane9', 80 | 0b0000000000000001000000000000000: 'TransitionLane10', 81 | 0b0000000000000010000000000000000: 'TransitionLane11', 82 | 0b0000000000000100000000000000000: 'TransitionLane12', 83 | 0b0000000000001000000000000000000: 'TransitionLane13', 84 | 0b0000000000010000000000000000000: 'TransitionLane14', 85 | 0b0000000000100000000000000000000: 'TransitionLane15', 86 | 0b0000000001000000000000000000000: 'TransitionLane16', 87 | 0b0000000010000000000000000000000: 'RetryLane1', 88 | 0b0000000100000000000000000000000: 'RetryLane2', 89 | 0b0000001000000000000000000000000: 'RetryLane3', 90 | 0b0000010000000000000000000000000: 'RetryLane4', 91 | 0b0000100000000000000000000000000: 'RetryLane5', 92 | 0b0001000000000000000000000000000: 'SelectiveHydrationLane', 93 | 0b0010000000000000000000000000000: 'IdleHydrationLane', 94 | 0b0100000000000000000000000000000: 'IdleLane', 95 | 0b1000000000000000000000000000000: 'OffscreenLane' 96 | }[lane]; 97 | } 98 | 99 | export const getPhaseFromExecutionContext = (executionContext: number) => { 100 | if ((executionContext & 2) !== 0) { 101 | return 'render'; 102 | } 103 | if ((executionContext & 4) !== 0) { 104 | return 'commit'; 105 | } 106 | // 缺少schedule阶段的判断 107 | return 'noop'; 108 | } 109 | 110 | export const COLOR = { 111 | // 处于调度阶段 112 | SCHEDULE_COLOR: '#727999', 113 | // 处于render阶段 114 | RENDER_COLOR: '#327205', 115 | // 处于commit阶段 116 | COMMIT_COLOR: '#997205', 117 | // 不处于React某个阶段,而是用户代码中 118 | USERSPACE_COLOR: '#197205' 119 | } -------------------------------------------------------------------------------- /src/packages/scheduler/cjs/scheduler.production.min.js: -------------------------------------------------------------------------------- 1 | /** @license React vundefined 2 | * scheduler.production.min.js 3 | * 4 | * Copyright (c) Facebook, Inc. and its affiliates. 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE file in the root directory of this source tree. 8 | */ 9 | 'use strict';function f(a,b){var c=a.length;a.push(b);a:for(;0>>1,e=a[d];if(0>>1;dg(C,c))ng(x,C)?(a[d]=x,a[n]=c,d=n):(a[d]=C,a[m]=c,d=m);else if(ng(x,c))a[d]=x,a[n]=c,d=n;else break a}}return b} 10 | function g(a,b){var c=a.sortIndex-b.sortIndex;return 0!==c?c:a.id-b.id}if("object"===typeof performance&&"function"===typeof performance.now){var l=performance;exports.unstable_now=function(){return l.now()}}else{var p=Date,q=p.now();exports.unstable_now=function(){return p.now()-q}}var r=[],t=[],u=1,v=null,y=3,z=!1,A=!1,B=!1,D="function"===typeof setTimeout?setTimeout:null,E="function"===typeof clearTimeout?clearTimeout:null,F="undefined"!==typeof setImmediate?setImmediate:null; 11 | "undefined"!==typeof navigator&&void 0!==navigator.scheduling&&void 0!==navigator.scheduling.isInputPending&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function G(a){for(var b=h(t);null!==b;){if(null===b.callback)k(t);else if(b.startTime<=a)k(t),b.sortIndex=b.expirationTime,f(r,b);else break;b=h(t)}}function H(a){B=!1;G(a);if(!A)if(null!==h(r))A=!0,I(J);else{var b=h(t);null!==b&&K(H,b.startTime-a)}} 12 | function J(a,b){A=!1;B&&(B=!1,E(L),L=-1);z=!0;var c=y;try{G(b);for(v=h(r);null!==v&&(!(v.expirationTime>b)||a&&!M());){var d=v.callback;if("function"===typeof d){v.callback=null;y=v.priorityLevel;var e=d(v.expirationTime<=b);b=exports.unstable_now();"function"===typeof e?v.callback=e:v===h(r)&&k(r);G(b)}else k(r);v=h(r)}if(null!==v)var w=!0;else{var m=h(t);null!==m&&K(H,m.startTime-b);w=!1}return w}finally{v=null,y=c,z=!1}}var N=!1,O=null,L=-1,P=5,Q=-1; 13 | function M(){return exports.unstable_now()-Qa||125d?(a.sortIndex=c,f(t,a),null===h(r)&&a===h(t)&&(B?(E(L),L=-1):B=!0,K(H,c-d))):(a.sortIndex=e,f(r,a),A||z||(A=!0,I(J)));return a}; 18 | exports.unstable_shouldYield=M;exports.unstable_wrapCallback=function(a){var b=y;return function(){var c=y;y=b;try{return a.apply(this,arguments)}finally{y=c}}}; 19 | -------------------------------------------------------------------------------- /src/packages/scheduler/cjs/scheduler-unstable_mock.production.min.js: -------------------------------------------------------------------------------- 1 | /** @license React vundefined 2 | * scheduler-unstable_mock.production.min.js 3 | * 4 | * Copyright (c) Facebook, Inc. and its affiliates. 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE file in the root directory of this source tree. 8 | */ 9 | 'use strict';function f(a,b){var c=a.length;a.push(b);a:for(;0>>1,e=a[d];if(0>>1;dg(z,c))vg(E,z)?(a[d]=E,a[v]=c,d=v):(a[d]=z,a[u]=c,d=u);else if(vg(E,c))a[d]=E,a[v]=c,d=v;else break a}}return b} 10 | function g(a,b){var c=a.sortIndex-b.sortIndex;return 0!==c?c:a.id-b.id}var l=[],m=[],n=1,p=null,q=3,r=!1,t=!1,w=!1,x=0,y=null,A=null,B=-1,C=null,F=-1,G=!1,H=!1,I=!1,J=!1,K=!1;function L(a){for(var b=h(m);null!==b;){if(null===b.callback)k(m);else if(b.startTime<=a)k(m),b.sortIndex=b.expirationTime,f(l,b);else break;b=h(m)}}function M(a){w=!1;L(a);if(!t)if(null!==h(l))t=!0,y=N;else{var b=h(m);null!==b&&(a=b.startTime-a,A=M,B=x+a)}} 11 | function N(a,b){t=!1;w&&(w=!1,A=null,B=-1);r=!0;var c=q;try{L(b);for(p=h(l);null!==p&&(!(p.expirationTime>b)||a&&!O());){var d=p.callback;if("function"===typeof d){p.callback=null;q=p.priorityLevel;var e=d(p.expirationTime<=b);b=x;"function"===typeof e?p.callback=e:p===h(l)&&k(l);L(b)}else k(l);p=h(l)}if(null!==p)var D=!0;else{var u=h(m);if(null!==u){var z=u.startTime-b;A=M;B=x+z}D=!1}return D}finally{p=null,q=c,r=!1}} 12 | function O(){return 0===F&&null===C||-1!==F&&null!==C&&C.length>=F||J&&I?G=!0:!1}function P(){if(H)throw Error("Already flushing work.");if(null!==y){var a=y;H=!0;try{var b=!0;do b=a(!0,x);while(b);b||(y=null);return!0}finally{H=!1}}else return!1}exports.reset=function(){if(H)throw Error("Cannot reset while already flushing work.");x=0;A=y=null;B=-1;C=null;F=-1;I=H=G=!1};exports.unstable_IdlePriority=5;exports.unstable_ImmediatePriority=1;exports.unstable_LowPriority=4; 13 | exports.unstable_NormalPriority=3;exports.unstable_Profiling=null;exports.unstable_UserBlockingPriority=2;exports.unstable_advanceTime=function(a){"disabledLog"===console.log.name||K||(x+=a,null!==A&&B<=x&&(A(x),B=-1,A=null))};exports.unstable_cancelCallback=function(a){a.callback=null};exports.unstable_clearYields=function(){if(null===C)return[];var a=C;C=null;return a};exports.unstable_continueExecution=function(){t||r||(t=!0,y=N)}; 14 | exports.unstable_flushAll=function(){if(null!==C)throw Error("Log is not empty. Assert on the log of yielded values before flushing additional work.");P();if(null!==C)throw Error("While flushing work, something yielded a value. Use an assertion helper to assert on the log of yielded values, e.g. expect(Scheduler).toFlushAndYield([...])");};exports.unstable_flushAllWithoutAsserting=P; 15 | exports.unstable_flushExpired=function(){if(H)throw Error("Already flushing work.");if(null!==y){H=!0;try{y(!1,x)||(y=null)}finally{H=!1}}};exports.unstable_flushNumberOfYields=function(a){if(H)throw Error("Already flushing work.");if(null!==y){var b=y;F=a;H=!0;try{a=!0;do a=b(!0,x);while(a&&!G);a||(y=null)}finally{F=-1,H=G=!1}}}; 16 | exports.unstable_flushUntilNextPaint=function(){if(H)throw Error("Already flushing work.");if(null!==y){var a=y;J=!0;I=!1;H=!0;try{var b=!0;do b=a(!0,x);while(b&&!G);b||(y=null)}finally{H=G=J=!1}}};exports.unstable_forceFrameRate=function(){};exports.unstable_getCurrentPriorityLevel=function(){return q};exports.unstable_getFirstCallbackNode=function(){return h(l)};exports.unstable_next=function(a){switch(q){case 1:case 2:case 3:var b=3;break;default:b=q}var c=q;q=b;try{return a()}finally{q=c}}; 17 | exports.unstable_now=function(){return x};exports.unstable_pauseExecution=function(){};exports.unstable_requestPaint=function(){I=!0};exports.unstable_runWithPriority=function(a,b){switch(a){case 1:case 2:case 3:case 4:case 5:break;default:a=3}var c=q;q=a;try{return b()}finally{q=c}}; 18 | exports.unstable_scheduleCallback=function(a,b,c){var d=x;"object"===typeof c&&null!==c?(c=c.delay,c="number"===typeof c&&0d?(a.sortIndex=c,f(m,a),null===h(l)&&a===h(m)&&(w?(A=null,B=-1):w=!0,A=M,B=x+(c-d))):(a.sortIndex=e,f(l,a),t||r||(t=!0,y=N));return a}; 19 | exports.unstable_setDisableYieldValue=function(a){K=a};exports.unstable_shouldYield=O;exports.unstable_wrapCallback=function(a){var b=q;return function(){var c=q;q=b;try{return a.apply(this,arguments)}finally{q=c}}};exports.unstable_yieldValue=function(a){"disabledLog"===console.log.name||K||(null===C?C=[a]:C.push(a))}; 20 | -------------------------------------------------------------------------------- /src/packages/scheduler/umd/scheduler-unstable_mock.production.min.js: -------------------------------------------------------------------------------- 1 | /** @license React vundefined 2 | * scheduler-unstable_mock.production.min.js 3 | * 4 | * Copyright (c) Facebook, Inc. and its affiliates. 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE file in the root directory of this source tree. 8 | */ 9 | (function(){'use strict';(function(a,p){"object"===typeof exports&&"undefined"!==typeof module?p(exports):"function"===typeof define&&define.amd?define(["exports"],p):(a=a||self,p(a.SchedulerMock={}))})(this,function(a){function p(b,k){var c=b.length;b.push(k);a:for(;0>>1,v=b[a];if(0>>1;az(g,c))ez(h,g)?(b[a]=h,b[e]=c,a=e):(b[a]=g,b[d]=c,a=d);else if(ez(h,c))b[a]=h,b[e]=c,a=e;else break a}}return k}function z(b,a){var k=b.sortIndex-a.sortIndex;return 0!==k?k:b.id-a.id}function D(b){for(var a=m(r);null!==a;){if(null===a.callback)A(r);else if(a.startTime<=b)A(r),a.sortIndex=a.expirationTime,p(n,a);else break;a=m(r)}}function E(b){y=!1;D(b);if(!u)if(null!==m(n))u=!0,f=F;else{var a=m(r);null!==a&&(b=a.startTime-b,q=E,t=g+b)}}function F(b,a){u= 11 | !1;y&&(y=!1,q=null,t=-1);B=!0;var c=d;try{D(a);for(h=m(n);null!==h&&(!(h.expirationTime>a)||b&&!I());){var k=h.callback;if("function"===typeof k){h.callback=null;d=h.priorityLevel;var e=k(h.expirationTime<=a);a=g;"function"===typeof e?h.callback=e:h===m(n)&&A(n);D(a)}else A(n);h=m(n)}if(null!==h)var f=!0;else{var l=m(r);if(null!==l){var p=l.startTime-a;q=E;t=g+p}f=!1}return f}finally{h=null,d=c,B=!1}}function I(){return 0===w&&null===l||-1!==w&&null!==l&&l.length>=w||G&&C?x=!0:!1}function J(){if(e)throw Error("Already flushing work."); 12 | if(null!==f){var b=f;e=!0;try{var a=!0;do a=b(!0,g);while(a);a||(f=null);return!0}finally{e=!1}}else return!1}var n=[],r=[],K=1,h=null,d=3,B=!1,u=!1,y=!1,g=0,f=null,q=null,t=-1,l=null,w=-1,x=!1,e=!1,C=!1,G=!1,H=!1;a.reset=function(){if(e)throw Error("Cannot reset while already flushing work.");g=0;q=f=null;t=-1;l=null;w=-1;C=e=x=!1};a.unstable_IdlePriority=5;a.unstable_ImmediatePriority=1;a.unstable_LowPriority=4;a.unstable_NormalPriority=3;a.unstable_Profiling=null;a.unstable_UserBlockingPriority= 13 | 2;a.unstable_advanceTime=function(b){"disabledLog"===console.log.name||H||(g+=b,null!==q&&t<=g&&(q(g),t=-1,q=null))};a.unstable_cancelCallback=function(b){b.callback=null};a.unstable_clearYields=function(){if(null===l)return[];var b=l;l=null;return b};a.unstable_continueExecution=function(){u||B||(u=!0,f=F)};a.unstable_flushAll=function(){if(null!==l)throw Error("Log is not empty. Assert on the log of yielded values before flushing additional work.");J();if(null!==l)throw Error("While flushing work, something yielded a value. Use an assertion helper to assert on the log of yielded values, e.g. expect(Scheduler).toFlushAndYield([...])"); 14 | };a.unstable_flushAllWithoutAsserting=J;a.unstable_flushExpired=function(){if(e)throw Error("Already flushing work.");if(null!==f){e=!0;try{f(!1,g)||(f=null)}finally{e=!1}}};a.unstable_flushNumberOfYields=function(b){if(e)throw Error("Already flushing work.");if(null!==f){var a=f;w=b;e=!0;try{b=!0;do b=a(!0,g);while(b&&!x);b||(f=null)}finally{w=-1,e=x=!1}}};a.unstable_flushUntilNextPaint=function(){if(e)throw Error("Already flushing work.");if(null!==f){var a=f;G=!0;C=!1;e=!0;try{var k=!0;do k=a(!0, 15 | g);while(k&&!x);k||(f=null)}finally{e=x=G=!1}}};a.unstable_forceFrameRate=function(){};a.unstable_getCurrentPriorityLevel=function(){return d};a.unstable_getFirstCallbackNode=function(){return m(n)};a.unstable_next=function(a){switch(d){case 1:case 2:case 3:var b=3;break;default:b=d}var c=d;d=b;try{return a()}finally{d=c}};a.unstable_now=function(){return g};a.unstable_pauseExecution=function(){};a.unstable_requestPaint=function(){C=!0};a.unstable_runWithPriority=function(a,e){switch(a){case 1:case 2:case 3:case 4:case 5:break; 16 | default:a=3}var b=d;d=a;try{return e()}finally{d=b}};a.unstable_scheduleCallback=function(a,e,c){var b=g;"object"===typeof c&&null!==c?(c=c.delay,c="number"===typeof c&&0b?(a.sortIndex=c,p(r,a),null===m(n)&&a===m(r)&&(y?(q=null,t=-1):y=!0,q=E,t=g+(c-b))):(a.sortIndex=d,p(n,a),u||B||(u=!0, 17 | f=F));return a};a.unstable_setDisableYieldValue=function(a){H=a};a.unstable_shouldYield=I;a.unstable_wrapCallback=function(a){var b=d;return function(){var c=d;d=b;try{return a.apply(this,arguments)}finally{d=c}}};a.unstable_yieldValue=function(a){"disabledLog"===console.log.name||H||(null===l?l=[a]:l.push(a))}}); 18 | })(); 19 | -------------------------------------------------------------------------------- /src/packages/scheduler/umd/scheduler.production.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license React 3 | * 4 | * Copyright (c) Facebook, Inc. and its affiliates. 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE file in the root directory of this source tree. 8 | */ 9 | 10 | /* eslint-disable max-len */ 11 | 12 | 'use strict'; 13 | 14 | (function(global, factory) { 15 | // eslint-disable-next-line no-unused-expressions 16 | typeof exports === 'object' && typeof module !== 'undefined' 17 | ? (module.exports = factory(require('react'))) 18 | : typeof define === 'function' && define.amd // eslint-disable-line no-undef 19 | ? define(['react'], factory) // eslint-disable-line no-undef 20 | : (global.Scheduler = factory(global)); 21 | })(this, function(global) { 22 | function unstable_now() { 23 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_now.apply( 24 | this, 25 | arguments 26 | ); 27 | } 28 | 29 | function unstable_scheduleCallback() { 30 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_scheduleCallback.apply( 31 | this, 32 | arguments 33 | ); 34 | } 35 | 36 | function unstable_cancelCallback() { 37 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_cancelCallback.apply( 38 | this, 39 | arguments 40 | ); 41 | } 42 | 43 | function unstable_shouldYield() { 44 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_shouldYield.apply( 45 | this, 46 | arguments 47 | ); 48 | } 49 | 50 | function unstable_requestPaint() { 51 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_requestPaint.apply( 52 | this, 53 | arguments 54 | ); 55 | } 56 | 57 | function unstable_runWithPriority() { 58 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_runWithPriority.apply( 59 | this, 60 | arguments 61 | ); 62 | } 63 | 64 | function unstable_next() { 65 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_next.apply( 66 | this, 67 | arguments 68 | ); 69 | } 70 | 71 | function unstable_wrapCallback() { 72 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_wrapCallback.apply( 73 | this, 74 | arguments 75 | ); 76 | } 77 | 78 | function unstable_getCurrentPriorityLevel() { 79 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_getCurrentPriorityLevel.apply( 80 | this, 81 | arguments 82 | ); 83 | } 84 | 85 | function unstable_getFirstCallbackNode() { 86 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_getFirstCallbackNode.apply( 87 | this, 88 | arguments 89 | ); 90 | } 91 | 92 | function unstable_pauseExecution() { 93 | return undefined; 94 | } 95 | 96 | function unstable_continueExecution() { 97 | return undefined; 98 | } 99 | 100 | function unstable_forceFrameRate() { 101 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_forceFrameRate.apply( 102 | this, 103 | arguments 104 | ); 105 | } 106 | 107 | return Object.freeze({ 108 | unstable_now: unstable_now, 109 | unstable_scheduleCallback: unstable_scheduleCallback, 110 | unstable_cancelCallback: unstable_cancelCallback, 111 | unstable_shouldYield: unstable_shouldYield, 112 | unstable_requestPaint: unstable_requestPaint, 113 | unstable_runWithPriority: unstable_runWithPriority, 114 | unstable_next: unstable_next, 115 | unstable_wrapCallback: unstable_wrapCallback, 116 | unstable_getCurrentPriorityLevel: unstable_getCurrentPriorityLevel, 117 | unstable_continueExecution: unstable_continueExecution, 118 | unstable_pauseExecution: unstable_pauseExecution, 119 | unstable_getFirstCallbackNode: unstable_getFirstCallbackNode, 120 | unstable_forceFrameRate: unstable_forceFrameRate, 121 | get unstable_IdlePriority() { 122 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED 123 | .Scheduler.unstable_IdlePriority; 124 | }, 125 | get unstable_ImmediatePriority() { 126 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED 127 | .Scheduler.unstable_ImmediatePriority; 128 | }, 129 | get unstable_LowPriority() { 130 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED 131 | .Scheduler.unstable_LowPriority; 132 | }, 133 | get unstable_NormalPriority() { 134 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED 135 | .Scheduler.unstable_NormalPriority; 136 | }, 137 | get unstable_UserBlockingPriority() { 138 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED 139 | .Scheduler.unstable_UserBlockingPriority; 140 | }, 141 | get unstable_Profiling() { 142 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED 143 | .Scheduler.unstable_Profiling; 144 | }, 145 | }); 146 | }); 147 | -------------------------------------------------------------------------------- /src/packages/scheduler/umd/scheduler.profiling.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license React 3 | * 4 | * Copyright (c) Facebook, Inc. and its affiliates. 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE file in the root directory of this source tree. 8 | */ 9 | 10 | /* eslint-disable max-len */ 11 | 12 | 'use strict'; 13 | 14 | (function(global, factory) { 15 | // eslint-disable-next-line no-unused-expressions 16 | typeof exports === 'object' && typeof module !== 'undefined' 17 | ? (module.exports = factory(require('react'))) 18 | : typeof define === 'function' && define.amd // eslint-disable-line no-undef 19 | ? define(['react'], factory) // eslint-disable-line no-undef 20 | : (global.Scheduler = factory(global)); 21 | })(this, function(global) { 22 | function unstable_now() { 23 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_now.apply( 24 | this, 25 | arguments 26 | ); 27 | } 28 | 29 | function unstable_scheduleCallback() { 30 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_scheduleCallback.apply( 31 | this, 32 | arguments 33 | ); 34 | } 35 | 36 | function unstable_cancelCallback() { 37 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_cancelCallback.apply( 38 | this, 39 | arguments 40 | ); 41 | } 42 | 43 | function unstable_shouldYield() { 44 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_shouldYield.apply( 45 | this, 46 | arguments 47 | ); 48 | } 49 | 50 | function unstable_requestPaint() { 51 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_requestPaint.apply( 52 | this, 53 | arguments 54 | ); 55 | } 56 | 57 | function unstable_runWithPriority() { 58 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_runWithPriority.apply( 59 | this, 60 | arguments 61 | ); 62 | } 63 | 64 | function unstable_next() { 65 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_next.apply( 66 | this, 67 | arguments 68 | ); 69 | } 70 | 71 | function unstable_wrapCallback() { 72 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_wrapCallback.apply( 73 | this, 74 | arguments 75 | ); 76 | } 77 | 78 | function unstable_getCurrentPriorityLevel() { 79 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_getCurrentPriorityLevel.apply( 80 | this, 81 | arguments 82 | ); 83 | } 84 | 85 | function unstable_getFirstCallbackNode() { 86 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_getFirstCallbackNode.apply( 87 | this, 88 | arguments 89 | ); 90 | } 91 | 92 | function unstable_pauseExecution() { 93 | return undefined; 94 | } 95 | 96 | function unstable_continueExecution() { 97 | return undefined; 98 | } 99 | 100 | function unstable_forceFrameRate() { 101 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_forceFrameRate.apply( 102 | this, 103 | arguments 104 | ); 105 | } 106 | 107 | return Object.freeze({ 108 | unstable_now: unstable_now, 109 | unstable_scheduleCallback: unstable_scheduleCallback, 110 | unstable_cancelCallback: unstable_cancelCallback, 111 | unstable_shouldYield: unstable_shouldYield, 112 | unstable_requestPaint: unstable_requestPaint, 113 | unstable_runWithPriority: unstable_runWithPriority, 114 | unstable_next: unstable_next, 115 | unstable_wrapCallback: unstable_wrapCallback, 116 | unstable_getCurrentPriorityLevel: unstable_getCurrentPriorityLevel, 117 | unstable_continueExecution: unstable_continueExecution, 118 | unstable_pauseExecution: unstable_pauseExecution, 119 | unstable_getFirstCallbackNode: unstable_getFirstCallbackNode, 120 | unstable_forceFrameRate: unstable_forceFrameRate, 121 | get unstable_IdlePriority() { 122 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED 123 | .Scheduler.unstable_IdlePriority; 124 | }, 125 | get unstable_ImmediatePriority() { 126 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED 127 | .Scheduler.unstable_ImmediatePriority; 128 | }, 129 | get unstable_LowPriority() { 130 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED 131 | .Scheduler.unstable_LowPriority; 132 | }, 133 | get unstable_NormalPriority() { 134 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED 135 | .Scheduler.unstable_NormalPriority; 136 | }, 137 | get unstable_UserBlockingPriority() { 138 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED 139 | .Scheduler.unstable_UserBlockingPriority; 140 | }, 141 | get unstable_Profiling() { 142 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED 143 | .Scheduler.unstable_Profiling; 144 | }, 145 | }); 146 | }); 147 | -------------------------------------------------------------------------------- /src/packages/scheduler/umd/scheduler.development.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license React 3 | * 4 | * Copyright (c) Facebook, Inc. and its affiliates. 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE file in the root directory of this source tree. 8 | */ 9 | 10 | /* eslint-disable max-len */ 11 | 12 | 'use strict'; 13 | 14 | (function(global, factory) { 15 | // eslint-disable-next-line no-unused-expressions 16 | typeof exports === 'object' && typeof module !== 'undefined' 17 | ? (module.exports = factory(require('react'))) 18 | : typeof define === 'function' && define.amd // eslint-disable-line no-undef 19 | ? define(['react'], factory) // eslint-disable-line no-undef 20 | : (global.Scheduler = factory(global)); 21 | })(this, function(global) { 22 | function unstable_now() { 23 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_now.apply( 24 | this, 25 | arguments 26 | ); 27 | } 28 | 29 | function unstable_scheduleCallback() { 30 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_scheduleCallback.apply( 31 | this, 32 | arguments 33 | ); 34 | } 35 | 36 | function unstable_cancelCallback() { 37 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_cancelCallback.apply( 38 | this, 39 | arguments 40 | ); 41 | } 42 | 43 | function unstable_shouldYield() { 44 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_shouldYield.apply( 45 | this, 46 | arguments 47 | ); 48 | } 49 | 50 | function unstable_requestPaint() { 51 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_requestPaint.apply( 52 | this, 53 | arguments 54 | ); 55 | } 56 | 57 | function unstable_runWithPriority() { 58 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_runWithPriority.apply( 59 | this, 60 | arguments 61 | ); 62 | } 63 | 64 | function unstable_next() { 65 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_next.apply( 66 | this, 67 | arguments 68 | ); 69 | } 70 | 71 | function unstable_wrapCallback() { 72 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_wrapCallback.apply( 73 | this, 74 | arguments 75 | ); 76 | } 77 | 78 | function unstable_getCurrentPriorityLevel() { 79 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_getCurrentPriorityLevel.apply( 80 | this, 81 | arguments 82 | ); 83 | } 84 | 85 | function unstable_getFirstCallbackNode() { 86 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_getFirstCallbackNode.apply( 87 | this, 88 | arguments 89 | ); 90 | } 91 | 92 | function unstable_pauseExecution() { 93 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_pauseExecution.apply( 94 | this, 95 | arguments 96 | ); 97 | } 98 | 99 | function unstable_continueExecution() { 100 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_continueExecution.apply( 101 | this, 102 | arguments 103 | ); 104 | } 105 | 106 | function unstable_forceFrameRate() { 107 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Scheduler.unstable_forceFrameRate.apply( 108 | this, 109 | arguments 110 | ); 111 | } 112 | 113 | return Object.freeze({ 114 | unstable_now: unstable_now, 115 | unstable_scheduleCallback: unstable_scheduleCallback, 116 | unstable_cancelCallback: unstable_cancelCallback, 117 | unstable_shouldYield: unstable_shouldYield, 118 | unstable_requestPaint: unstable_requestPaint, 119 | unstable_runWithPriority: unstable_runWithPriority, 120 | unstable_next: unstable_next, 121 | unstable_wrapCallback: unstable_wrapCallback, 122 | unstable_getCurrentPriorityLevel: unstable_getCurrentPriorityLevel, 123 | unstable_continueExecution: unstable_continueExecution, 124 | unstable_pauseExecution: unstable_pauseExecution, 125 | unstable_getFirstCallbackNode: unstable_getFirstCallbackNode, 126 | unstable_forceFrameRate: unstable_forceFrameRate, 127 | get unstable_IdlePriority() { 128 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED 129 | .Scheduler.unstable_IdlePriority; 130 | }, 131 | get unstable_ImmediatePriority() { 132 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED 133 | .Scheduler.unstable_ImmediatePriority; 134 | }, 135 | get unstable_LowPriority() { 136 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED 137 | .Scheduler.unstable_LowPriority; 138 | }, 139 | get unstable_NormalPriority() { 140 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED 141 | .Scheduler.unstable_NormalPriority; 142 | }, 143 | get unstable_UserBlockingPriority() { 144 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED 145 | .Scheduler.unstable_UserBlockingPriority; 146 | }, 147 | get unstable_Profiling() { 148 | return global.React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED 149 | .Scheduler.unstable_Profiling; 150 | }, 151 | }); 152 | }); 153 | -------------------------------------------------------------------------------- /src/packages/react/cjs/react.production.min.js: -------------------------------------------------------------------------------- 1 | /** @license React vundefined 2 | * react.production.min.js 3 | * 4 | * Copyright (c) Facebook, Inc. and its affiliates. 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE file in the root directory of this source tree. 8 | */ 9 | 'use strict';var l=require("object-assign"),m=60103,p=60106;exports.Fragment=60107;exports.StrictMode=60108;exports.Profiler=60114;var q=60109,r=60110,t=60112;exports.Suspense=60113;var u=60115,v=60116; 10 | if("function"===typeof Symbol&&Symbol.for){var w=Symbol.for;m=w("react.element");p=w("react.portal");exports.Fragment=w("react.fragment");exports.StrictMode=w("react.strict_mode");exports.Profiler=w("react.profiler");q=w("react.provider");r=w("react.context");t=w("react.forward_ref");exports.Suspense=w("react.suspense");u=w("react.memo");v=w("react.lazy")}var x="function"===typeof Symbol&&Symbol.iterator; 11 | function y(a){if(null===a||"object"!==typeof a)return null;a=x&&a[x]||a["@@iterator"];return"function"===typeof a?a:null}var z={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},A={};function B(a,b,e){this.props=a;this.context=b;this.refs=A;this.updater=e||z}B.prototype.isReactComponent={}; 12 | B.prototype.setState=function(a,b){if("object"!==typeof a&&"function"!==typeof a&&null!=a)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,a,b,"setState")};B.prototype.forceUpdate=function(a){this.updater.enqueueForceUpdate(this,a,"forceUpdate")};function C(){}C.prototype=B.prototype;function D(a,b,e){this.props=a;this.context=b;this.refs=A;this.updater=e||z}var E=D.prototype=new C; 13 | E.constructor=D;l(E,B.prototype);E.isPureReactComponent=!0;var F=Array.isArray,G=Object.prototype.hasOwnProperty,H={current:null},I={key:!0,ref:!0,__self:!0,__source:!0}; 14 | function J(a,b,e){var d,c={},k=null,h=null;if(null!=b)for(d in void 0!==b.ref&&(h=b.ref),void 0!==b.key&&(k=""+b.key),b)G.call(b,d)&&!I.hasOwnProperty(d)&&(c[d]=b[d]);var g=arguments.length-2;if(1===g)c.children=e;else if(1= deadline; 40 | } 41 | function unstable_requestPaint() {// Since we yield every frame regardless, `requestPaint` has no effect. 42 | } 43 | function unstable_scheduleCallback(priorityLevel, callback, options) { 44 | var postTaskPriority; 45 | 46 | switch (priorityLevel) { 47 | case ImmediatePriority: 48 | case UserBlockingPriority: 49 | postTaskPriority = 'user-blocking'; 50 | break; 51 | 52 | case LowPriority: 53 | case NormalPriority: 54 | postTaskPriority = 'user-visible'; 55 | break; 56 | 57 | case IdlePriority: 58 | postTaskPriority = 'background'; 59 | break; 60 | 61 | default: 62 | postTaskPriority = 'user-visible'; 63 | break; 64 | } 65 | 66 | var controller = new TaskController(); 67 | var postTaskOptions = { 68 | priority: postTaskPriority, 69 | delay: typeof options === 'object' && options !== null ? options.delay : 0, 70 | signal: controller.signal 71 | }; 72 | var node = { 73 | _controller: controller 74 | }; 75 | scheduler.postTask(runTask.bind(null, priorityLevel, postTaskPriority, node, callback), postTaskOptions).catch(handleAbortError); 76 | return node; 77 | } 78 | 79 | function runTask(priorityLevel, postTaskPriority, node, callback) { 80 | deadline = getCurrentTime() + yieldInterval; 81 | 82 | try { 83 | currentPriorityLevel_DEPRECATED = priorityLevel; 84 | var _didTimeout_DEPRECATED = false; 85 | var result = callback(_didTimeout_DEPRECATED); 86 | 87 | if (typeof result === 'function') { 88 | // Assume this is a continuation 89 | var continuation = result; 90 | var continuationController = new TaskController(); 91 | var continuationOptions = { 92 | priority: postTaskPriority, 93 | signal: continuationController.signal 94 | }; // Update the original callback node's controller, since even though we're 95 | // posting a new task, conceptually it's the same one. 96 | 97 | node._controller = continuationController; 98 | scheduler.postTask(runTask.bind(null, priorityLevel, postTaskPriority, node, continuation), continuationOptions).catch(handleAbortError); 99 | } 100 | } catch (error) { 101 | // We're inside a `postTask` promise. If we don't handle this error, then it 102 | // will trigger an "Unhandled promise rejection" error. We don't want that, 103 | // but we do want the default error reporting behavior that normal 104 | // (non-Promise) tasks get for unhandled errors. 105 | // 106 | // So we'll re-throw the error inside a regular browser task. 107 | setTimeout(function () { 108 | throw error; 109 | }); 110 | } finally { 111 | currentPriorityLevel_DEPRECATED = NormalPriority; 112 | } 113 | } 114 | 115 | function handleAbortError(error) {// Abort errors are an implementation detail. We don't expose the 116 | // TaskController to the user, nor do we expose the promise that is returned 117 | // from `postTask`. So we should suppress them, since there's no way for the 118 | // user to handle them. 119 | } 120 | 121 | function unstable_cancelCallback(node) { 122 | var controller = node._controller; 123 | controller.abort(); 124 | } 125 | function unstable_runWithPriority(priorityLevel, callback) { 126 | var previousPriorityLevel = currentPriorityLevel_DEPRECATED; 127 | currentPriorityLevel_DEPRECATED = priorityLevel; 128 | 129 | try { 130 | return callback(); 131 | } finally { 132 | currentPriorityLevel_DEPRECATED = previousPriorityLevel; 133 | } 134 | } 135 | function unstable_getCurrentPriorityLevel() { 136 | return currentPriorityLevel_DEPRECATED; 137 | } 138 | function unstable_next(callback) { 139 | var priorityLevel; 140 | 141 | switch (currentPriorityLevel_DEPRECATED) { 142 | case ImmediatePriority: 143 | case UserBlockingPriority: 144 | case NormalPriority: 145 | // Shift down to normal priority 146 | priorityLevel = NormalPriority; 147 | break; 148 | 149 | default: 150 | // Anything lower than normal priority should remain at the current level. 151 | priorityLevel = currentPriorityLevel_DEPRECATED; 152 | break; 153 | } 154 | 155 | var previousPriorityLevel = currentPriorityLevel_DEPRECATED; 156 | currentPriorityLevel_DEPRECATED = priorityLevel; 157 | 158 | try { 159 | return callback(); 160 | } finally { 161 | currentPriorityLevel_DEPRECATED = previousPriorityLevel; 162 | } 163 | } 164 | function unstable_wrapCallback(callback) { 165 | var parentPriorityLevel = currentPriorityLevel_DEPRECATED; 166 | return function () { 167 | var previousPriorityLevel = currentPriorityLevel_DEPRECATED; 168 | currentPriorityLevel_DEPRECATED = parentPriorityLevel; 169 | 170 | try { 171 | return callback(); 172 | } finally { 173 | currentPriorityLevel_DEPRECATED = previousPriorityLevel; 174 | } 175 | }; 176 | } 177 | function unstable_forceFrameRate() {} 178 | function unstable_pauseExecution() {} 179 | function unstable_continueExecution() {} 180 | function unstable_getFirstCallbackNode() { 181 | return null; 182 | } // Currently no profiling build 183 | 184 | var unstable_Profiling = null; 185 | 186 | exports.unstable_IdlePriority = IdlePriority; 187 | exports.unstable_ImmediatePriority = ImmediatePriority; 188 | exports.unstable_LowPriority = LowPriority; 189 | exports.unstable_NormalPriority = NormalPriority; 190 | exports.unstable_Profiling = unstable_Profiling; 191 | exports.unstable_UserBlockingPriority = UserBlockingPriority; 192 | exports.unstable_cancelCallback = unstable_cancelCallback; 193 | exports.unstable_continueExecution = unstable_continueExecution; 194 | exports.unstable_forceFrameRate = unstable_forceFrameRate; 195 | exports.unstable_getCurrentPriorityLevel = unstable_getCurrentPriorityLevel; 196 | exports.unstable_getFirstCallbackNode = unstable_getFirstCallbackNode; 197 | exports.unstable_next = unstable_next; 198 | exports.unstable_now = unstable_now; 199 | exports.unstable_pauseExecution = unstable_pauseExecution; 200 | exports.unstable_requestPaint = unstable_requestPaint; 201 | exports.unstable_runWithPriority = unstable_runWithPriority; 202 | exports.unstable_scheduleCallback = unstable_scheduleCallback; 203 | exports.unstable_shouldYield = unstable_shouldYield; 204 | exports.unstable_wrapCallback = unstable_wrapCallback; 205 | })(); 206 | } 207 | -------------------------------------------------------------------------------- /src/packages/react/umd/react.production.min.js: -------------------------------------------------------------------------------- 1 | /** @license React vundefined 2 | * react.production.min.js 3 | * 4 | * Copyright (c) Facebook, Inc. and its affiliates. 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE file in the root directory of this source tree. 8 | */ 9 | (function(){'use strict';(function(c,y){"object"===typeof exports&&"undefined"!==typeof module?y(exports):"function"===typeof define&&define.amd?define(["exports"],y):(c=c||self,y(c.React={}))})(this,function(c){function y(a){if(null===a||"object"!==typeof a)return null;a=W&&a[W]||a["@@iterator"];return"function"===typeof a?a:null}function w(a,b,g){this.props=a;this.context=b;this.refs=X;this.updater=g||Y}function Z(){}function K(a,b,g){this.props=a;this.context=b;this.refs=X;this.updater=g||Y}function aa(a, 10 | b,g){var l,e={},c=null,k=null;if(null!=b)for(l in void 0!==b.ref&&(k=b.ref),void 0!==b.key&&(c=""+b.key),b)ba.call(b,l)&&!ca.hasOwnProperty(l)&&(e[l]=b[l]);var p=arguments.length-2;if(1===p)e.children=g;else if(1>>1,e=a[c];if(0>>1;cD(p,g))hD(f,p)?(a[c]=f,a[h]=g,c=h):(a[c]=p,a[k]=g,c=k);else if(hD(f,g))a[c]=f,a[h]=g,c=h;else break a}}return b} 15 | function D(a,b){var c=a.sortIndex-b.sortIndex;return 0!==c?c:a.id-b.id}function P(a){for(var b=q(t);null!==b;){if(null===b.callback)E(t);else if(b.startTime<=a)E(t),b.sortIndex=b.expirationTime,O(r,b);else break;b=q(t)}}function Q(a){z=!1;P(a);if(!u)if(null!==q(r))u=!0,R(S);else{var b=q(t);null!==b&&T(Q,b.startTime-a)}}function S(a,b){u=!1;z&&(z=!1,ha(A),A=-1);F=!0;var c=f;try{P(b);for(n=q(r);null!==n&&(!(n.expirationTime>b)||a&&!ia());){var l=n.callback;if("function"===typeof l){n.callback=null; 16 | f=n.priorityLevel;var e=l(n.expirationTime<=b);b=v();"function"===typeof e?n.callback=e:n===q(r)&&E(r);P(b)}else E(r);n=q(r)}if(null!==n)var d=!0;else{var k=q(t);null!==k&&T(Q,k.startTime-b);d=!1}return d}finally{n=null,f=c,F=!1}}function ia(){return v()-jad?(a.sortIndex=c,O(t,a),null===q(r)&&a===q(t)&&(z?(ha(A),A=-1):z=!0,T(Q,c-d))):(a.sortIndex=e,O(r,a),u||F||(u=!0,R(S)));return a},unstable_cancelCallback:function(a){a.callback=null},unstable_wrapCallback:function(a){var b=f;return function(){var c=f;f=b;try{return a.apply(this,arguments)}finally{f=c}}},unstable_getCurrentPriorityLevel:function(){return f},unstable_shouldYield:ia,unstable_requestPaint:function(){}, 24 | unstable_continueExecution:function(){u||F||(u=!0,R(S))},unstable_pauseExecution:function(){},unstable_getFirstCallbackNode:function(){return q(r)},get unstable_now(){return v},unstable_forceFrameRate:function(a){0>a||125>>1,e=a[c];if(0>>1;cD(p,g))hD(f,p)?(a[c]=f,a[h]=g,c=h):(a[c]=p,a[k]=g,c=k);else if(hD(f,g))a[c]=f,a[h]=g,c=h;else break a}}return b} 15 | function D(a,b){var c=a.sortIndex-b.sortIndex;return 0!==c?c:a.id-b.id}function P(a){for(var b=q(t);null!==b;){if(null===b.callback)E(t);else if(b.startTime<=a)E(t),b.sortIndex=b.expirationTime,O(r,b);else break;b=q(t)}}function Q(a){z=!1;P(a);if(!u)if(null!==q(r))u=!0,R(S);else{var b=q(t);null!==b&&T(Q,b.startTime-a)}}function S(a,b){u=!1;z&&(z=!1,ha(A),A=-1);F=!0;var c=f;try{P(b);for(n=q(r);null!==n&&(!(n.expirationTime>b)||a&&!ia());){var l=n.callback;if("function"===typeof l){n.callback=null; 16 | f=n.priorityLevel;var e=l(n.expirationTime<=b);b=v();"function"===typeof e?n.callback=e:n===q(r)&&E(r);P(b)}else E(r);n=q(r)}if(null!==n)var d=!0;else{var k=q(t);null!==k&&T(Q,k.startTime-b);d=!1}return d}finally{n=null,f=c,F=!1}}function ia(){return v()-jad?(a.sortIndex=c,O(t,a),null===q(r)&&a===q(t)&&(z?(ha(A),A=-1):z=!0,T(Q,c-d))):(a.sortIndex=e,O(r,a),u||F||(u=!0,R(S)));return a},unstable_cancelCallback:function(a){a.callback=null},unstable_wrapCallback:function(a){var b=f;return function(){var c=f;f=b;try{return a.apply(this,arguments)}finally{f=c}}},unstable_getCurrentPriorityLevel:function(){return f},unstable_shouldYield:ia,unstable_requestPaint:function(){}, 24 | unstable_continueExecution:function(){u||F||(u=!0,R(S))},unstable_pauseExecution:function(){},unstable_getFirstCallbackNode:function(){return q(r)},get unstable_now(){return v},unstable_forceFrameRate:function(a){0>a||125 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { 36 | args[_key - 2] = arguments[_key]; 37 | } 38 | 39 | if (format === undefined) { 40 | throw new Error('`warningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument'); 41 | } 42 | if (args.length > 8) { 43 | // Check before the condition to catch violations early. 44 | throw new Error('warningWithoutStack() currently supports at most 8 arguments.'); 45 | } 46 | if (condition) { 47 | return; 48 | } 49 | if (typeof console !== 'undefined') { 50 | var _args$map = args.map(function (item) { 51 | return '' + item; 52 | }), 53 | a = _args$map[0], 54 | b = _args$map[1], 55 | c = _args$map[2], 56 | d = _args$map[3], 57 | e = _args$map[4], 58 | f = _args$map[5], 59 | g = _args$map[6], 60 | h = _args$map[7]; 61 | 62 | var message = 'Warning: ' + format; 63 | 64 | // We intentionally don't use spread (or .apply) because it breaks IE9: 65 | // https://github.com/facebook/react/issues/13610 66 | switch (args.length) { 67 | case 0: 68 | console.error(message); 69 | break; 70 | case 1: 71 | console.error(message, a); 72 | break; 73 | case 2: 74 | console.error(message, a, b); 75 | break; 76 | case 3: 77 | console.error(message, a, b, c); 78 | break; 79 | case 4: 80 | console.error(message, a, b, c, d); 81 | break; 82 | case 5: 83 | console.error(message, a, b, c, d, e); 84 | break; 85 | case 6: 86 | console.error(message, a, b, c, d, e, f); 87 | break; 88 | case 7: 89 | console.error(message, a, b, c, d, e, f, g); 90 | break; 91 | case 8: 92 | console.error(message, a, b, c, d, e, f, g, h); 93 | break; 94 | default: 95 | throw new Error('warningWithoutStack() currently supports at most 8 arguments.'); 96 | } 97 | } 98 | try { 99 | // --- Welcome to debugging React --- 100 | // This error was thrown as a convenience so that you can use this stack 101 | // to find the callsite that caused this warning to fire. 102 | var argIndex = 0; 103 | var _message = 'Warning: ' + format.replace(/%s/g, function () { 104 | return args[argIndex++]; 105 | }); 106 | throw new Error(_message); 107 | } catch (x) {} 108 | }; 109 | } 110 | 111 | var warningWithoutStack$1 = warningWithoutStack; 112 | 113 | function createLRU(limit) { 114 | var LIMIT = limit; 115 | 116 | // Circular, doubly-linked list 117 | var first = null; 118 | var size = 0; 119 | 120 | var cleanUpIsScheduled = false; 121 | 122 | function scheduleCleanUp() { 123 | if (cleanUpIsScheduled === false && size > LIMIT) { 124 | // The cache size exceeds the limit. Schedule a callback to delete the 125 | // least recently used entries. 126 | cleanUpIsScheduled = true; 127 | // 由于Scheduler版本变动,这里之前没传优先级,改为使用 scheduler.unstable_NormalPriority 优先级 128 | scheduler.unstable_scheduleCallback(scheduler.unstable_NormalPriority, cleanUp); 129 | } 130 | } 131 | 132 | function cleanUp() { 133 | cleanUpIsScheduled = false; 134 | deleteLeastRecentlyUsedEntries(LIMIT); 135 | } 136 | 137 | function deleteLeastRecentlyUsedEntries(targetSize) { 138 | // Delete entries from the cache, starting from the end of the list. 139 | if (first !== null) { 140 | var resolvedFirst = first; 141 | var last = resolvedFirst.previous; 142 | while (size > targetSize && last !== null) { 143 | var _onDelete = last.onDelete; 144 | var _previous = last.previous; 145 | last.onDelete = null; 146 | 147 | // Remove from the list 148 | last.previous = last.next = null; 149 | if (last === first) { 150 | // Reached the head of the list. 151 | first = last = null; 152 | } else { 153 | first.previous = _previous; 154 | _previous.next = first; 155 | last = _previous; 156 | } 157 | 158 | size -= 1; 159 | 160 | // Call the destroy method after removing the entry from the list. If it 161 | // throws, the rest of cache will not be deleted, but it will be in a 162 | // valid state. 163 | _onDelete(); 164 | } 165 | } 166 | } 167 | 168 | function add(value, onDelete) { 169 | var entry = { 170 | value: value, 171 | onDelete: onDelete, 172 | next: null, 173 | previous: null 174 | }; 175 | if (first === null) { 176 | entry.previous = entry.next = entry; 177 | first = entry; 178 | } else { 179 | // Append to head 180 | var last = first.previous; 181 | last.next = entry; 182 | entry.previous = last; 183 | 184 | first.previous = entry; 185 | entry.next = first; 186 | 187 | first = entry; 188 | } 189 | size += 1; 190 | return entry; 191 | } 192 | 193 | function update(entry, newValue) { 194 | entry.value = newValue; 195 | } 196 | 197 | function access(entry) { 198 | var next = entry.next; 199 | if (next !== null) { 200 | // Entry already cached 201 | var resolvedFirst = first; 202 | if (first !== entry) { 203 | // Remove from current position 204 | var _previous2 = entry.previous; 205 | _previous2.next = next; 206 | next.previous = _previous2; 207 | 208 | // Append to head 209 | var last = resolvedFirst.previous; 210 | last.next = entry; 211 | entry.previous = last; 212 | 213 | resolvedFirst.previous = entry; 214 | entry.next = resolvedFirst; 215 | 216 | first = entry; 217 | } 218 | } else { 219 | // Cannot access a deleted entry 220 | // TODO: Error? Warning? 221 | } 222 | scheduleCleanUp(); 223 | return entry.value; 224 | } 225 | 226 | function setLimit(newLimit) { 227 | LIMIT = newLimit; 228 | scheduleCleanUp(); 229 | } 230 | 231 | return { 232 | add: add, 233 | update: update, 234 | access: access, 235 | setLimit: setLimit 236 | }; 237 | } 238 | 239 | var Pending = 0; 240 | var Resolved = 1; 241 | var Rejected = 2; 242 | 243 | var ReactCurrentDispatcher = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher; 244 | 245 | function readContext(Context, observedBits) { 246 | var dispatcher = ReactCurrentDispatcher.current; 247 | if (dispatcher === null) { 248 | throw new Error('react-cache: read and preload may only be called from within a ' + "component's render. They are not supported in event handlers or " + 'lifecycle methods.'); 249 | } 250 | return dispatcher.readContext(Context, observedBits); 251 | } 252 | 253 | function identityHashFn(input) { 254 | { 255 | !(typeof input === 'string' || typeof input === 'number' || typeof input === 'boolean' || input === undefined || input === null) ? warningWithoutStack$1(false, 'Invalid key type. Expected a string, number, symbol, or boolean, ' + 'but instead received: %s' + '\n\nTo use non-primitive values as keys, you must pass a hash ' + 'function as the second argument to createResource().', input) : void 0; 256 | } 257 | return input; 258 | } 259 | 260 | var CACHE_LIMIT = 500; 261 | var lru = createLRU(CACHE_LIMIT); 262 | 263 | var entries = new Map(); 264 | 265 | var CacheContext = React.createContext(null); 266 | 267 | function accessResult(resource, fetch, input, key) { 268 | var entriesForResource = entries.get(resource); 269 | if (entriesForResource === undefined) { 270 | entriesForResource = new Map(); 271 | entries.set(resource, entriesForResource); 272 | } 273 | var entry = entriesForResource.get(key); 274 | if (entry === undefined) { 275 | var thenable = fetch(input); 276 | thenable.then(function (value) { 277 | if (newResult.status === Pending) { 278 | var resolvedResult = newResult; 279 | resolvedResult.status = Resolved; 280 | resolvedResult.value = value; 281 | } 282 | }, function (error) { 283 | if (newResult.status === Pending) { 284 | var rejectedResult = newResult; 285 | rejectedResult.status = Rejected; 286 | rejectedResult.value = error; 287 | } 288 | }); 289 | var newResult = { 290 | status: Pending, 291 | value: thenable 292 | }; 293 | var newEntry = lru.add(newResult, deleteEntry.bind(null, resource, key)); 294 | entriesForResource.set(key, newEntry); 295 | return newResult; 296 | } else { 297 | return lru.access(entry); 298 | } 299 | } 300 | 301 | function deleteEntry(resource, key) { 302 | var entriesForResource = entries.get(resource); 303 | if (entriesForResource !== undefined) { 304 | entriesForResource.delete(key); 305 | if (entriesForResource.size === 0) { 306 | entries.delete(resource); 307 | } 308 | } 309 | } 310 | 311 | function unstable_createResource(fetch, maybeHashInput) { 312 | var hashInput = maybeHashInput !== undefined ? maybeHashInput : identityHashFn; 313 | 314 | var resource = { 315 | read: function (input) { 316 | // react-cache currently doesn't rely on context, but it may in the 317 | // future, so we read anyway to prevent access outside of render. 318 | readContext(CacheContext); 319 | var key = hashInput(input); 320 | var result = accessResult(resource, fetch, input, key); 321 | switch (result.status) { 322 | case Pending: 323 | { 324 | var suspender = result.value; 325 | throw suspender; 326 | } 327 | case Resolved: 328 | { 329 | var _value = result.value; 330 | return _value; 331 | } 332 | case Rejected: 333 | { 334 | var error = result.value; 335 | throw error; 336 | } 337 | default: 338 | // Should be unreachable 339 | return undefined; 340 | } 341 | }, 342 | preload: function (input) { 343 | // react-cache currently doesn't rely on context, but it may in the 344 | // future, so we read anyway to prevent access outside of render. 345 | readContext(CacheContext); 346 | var key = hashInput(input); 347 | accessResult(resource, fetch, input, key); 348 | } 349 | }; 350 | return resource; 351 | } 352 | 353 | function unstable_setGlobalCacheLimit(limit) { 354 | lru.setLimit(limit); 355 | } 356 | 357 | exports.unstable_createResource = unstable_createResource; 358 | exports.unstable_setGlobalCacheLimit = unstable_setGlobalCacheLimit; 359 | })(); 360 | } 361 | -------------------------------------------------------------------------------- /src/packages/react-cache/umd/react-cache.development.js: -------------------------------------------------------------------------------- 1 | /** @license React v16.6.0 2 | * react-cache.development.js 3 | * 4 | * Copyright (c) Facebook, Inc. and its affiliates. 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE file in the root directory of this source tree. 8 | */ 9 | 10 | 'use strict'; 11 | 12 | (function (global, factory) { 13 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('scheduler')) : 14 | typeof define === 'function' && define.amd ? define(['exports', 'react', 'scheduler'], factory) : 15 | (factory((global.ReactCache = {}),global.React,global.Scheduler)); 16 | }(this, (function (exports,React,scheduler) { 'use strict'; 17 | 18 | /** 19 | * Similar to invariant but only logs a warning if the condition is not met. 20 | * This can be used to log issues in development environments in critical 21 | * paths. Removing the logging code for production environments will keep the 22 | * same logic and follow the same code paths. 23 | */ 24 | 25 | var warningWithoutStack = function () {}; 26 | 27 | { 28 | warningWithoutStack = function (condition, format) { 29 | for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { 30 | args[_key - 2] = arguments[_key]; 31 | } 32 | 33 | if (format === undefined) { 34 | throw new Error('`warningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument'); 35 | } 36 | if (args.length > 8) { 37 | // Check before the condition to catch violations early. 38 | throw new Error('warningWithoutStack() currently supports at most 8 arguments.'); 39 | } 40 | if (condition) { 41 | return; 42 | } 43 | if (typeof console !== 'undefined') { 44 | var _args$map = args.map(function (item) { 45 | return '' + item; 46 | }), 47 | a = _args$map[0], 48 | b = _args$map[1], 49 | c = _args$map[2], 50 | d = _args$map[3], 51 | e = _args$map[4], 52 | f = _args$map[5], 53 | g = _args$map[6], 54 | h = _args$map[7]; 55 | 56 | var message = 'Warning: ' + format; 57 | 58 | // We intentionally don't use spread (or .apply) because it breaks IE9: 59 | // https://github.com/facebook/react/issues/13610 60 | switch (args.length) { 61 | case 0: 62 | console.error(message); 63 | break; 64 | case 1: 65 | console.error(message, a); 66 | break; 67 | case 2: 68 | console.error(message, a, b); 69 | break; 70 | case 3: 71 | console.error(message, a, b, c); 72 | break; 73 | case 4: 74 | console.error(message, a, b, c, d); 75 | break; 76 | case 5: 77 | console.error(message, a, b, c, d, e); 78 | break; 79 | case 6: 80 | console.error(message, a, b, c, d, e, f); 81 | break; 82 | case 7: 83 | console.error(message, a, b, c, d, e, f, g); 84 | break; 85 | case 8: 86 | console.error(message, a, b, c, d, e, f, g, h); 87 | break; 88 | default: 89 | throw new Error('warningWithoutStack() currently supports at most 8 arguments.'); 90 | } 91 | } 92 | try { 93 | // --- Welcome to debugging React --- 94 | // This error was thrown as a convenience so that you can use this stack 95 | // to find the callsite that caused this warning to fire. 96 | var argIndex = 0; 97 | var _message = 'Warning: ' + format.replace(/%s/g, function () { 98 | return args[argIndex++]; 99 | }); 100 | throw new Error(_message); 101 | } catch (x) {} 102 | }; 103 | } 104 | 105 | var warningWithoutStack$1 = warningWithoutStack; 106 | 107 | function createLRU(limit) { 108 | var LIMIT = limit; 109 | 110 | // Circular, doubly-linked list 111 | var first = null; 112 | var size = 0; 113 | 114 | var cleanUpIsScheduled = false; 115 | 116 | function scheduleCleanUp() { 117 | if (cleanUpIsScheduled === false && size > LIMIT) { 118 | // The cache size exceeds the limit. Schedule a callback to delete the 119 | // least recently used entries. 120 | cleanUpIsScheduled = true; 121 | scheduler.unstable_scheduleCallback(cleanUp); 122 | } 123 | } 124 | 125 | function cleanUp() { 126 | cleanUpIsScheduled = false; 127 | deleteLeastRecentlyUsedEntries(LIMIT); 128 | } 129 | 130 | function deleteLeastRecentlyUsedEntries(targetSize) { 131 | // Delete entries from the cache, starting from the end of the list. 132 | if (first !== null) { 133 | var resolvedFirst = first; 134 | var last = resolvedFirst.previous; 135 | while (size > targetSize && last !== null) { 136 | var _onDelete = last.onDelete; 137 | var _previous = last.previous; 138 | last.onDelete = null; 139 | 140 | // Remove from the list 141 | last.previous = last.next = null; 142 | if (last === first) { 143 | // Reached the head of the list. 144 | first = last = null; 145 | } else { 146 | first.previous = _previous; 147 | _previous.next = first; 148 | last = _previous; 149 | } 150 | 151 | size -= 1; 152 | 153 | // Call the destroy method after removing the entry from the list. If it 154 | // throws, the rest of cache will not be deleted, but it will be in a 155 | // valid state. 156 | _onDelete(); 157 | } 158 | } 159 | } 160 | 161 | function add(value, onDelete) { 162 | var entry = { 163 | value: value, 164 | onDelete: onDelete, 165 | next: null, 166 | previous: null 167 | }; 168 | if (first === null) { 169 | entry.previous = entry.next = entry; 170 | first = entry; 171 | } else { 172 | // Append to head 173 | var last = first.previous; 174 | last.next = entry; 175 | entry.previous = last; 176 | 177 | first.previous = entry; 178 | entry.next = first; 179 | 180 | first = entry; 181 | } 182 | size += 1; 183 | return entry; 184 | } 185 | 186 | function update(entry, newValue) { 187 | entry.value = newValue; 188 | } 189 | 190 | function access(entry) { 191 | var next = entry.next; 192 | if (next !== null) { 193 | // Entry already cached 194 | var resolvedFirst = first; 195 | if (first !== entry) { 196 | // Remove from current position 197 | var _previous2 = entry.previous; 198 | _previous2.next = next; 199 | next.previous = _previous2; 200 | 201 | // Append to head 202 | var last = resolvedFirst.previous; 203 | last.next = entry; 204 | entry.previous = last; 205 | 206 | resolvedFirst.previous = entry; 207 | entry.next = resolvedFirst; 208 | 209 | first = entry; 210 | } 211 | } else { 212 | // Cannot access a deleted entry 213 | // TODO: Error? Warning? 214 | } 215 | scheduleCleanUp(); 216 | return entry.value; 217 | } 218 | 219 | function setLimit(newLimit) { 220 | LIMIT = newLimit; 221 | scheduleCleanUp(); 222 | } 223 | 224 | return { 225 | add: add, 226 | update: update, 227 | access: access, 228 | setLimit: setLimit 229 | }; 230 | } 231 | 232 | var Pending = 0; 233 | var Resolved = 1; 234 | var Rejected = 2; 235 | 236 | var currentOwner = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner; 237 | 238 | function readContext(Context, observedBits) { 239 | var dispatcher = currentOwner.currentDispatcher; 240 | if (dispatcher === null) { 241 | throw new Error('react-cache: read and preload may only be called from within a ' + "component's render. They are not supported in event handlers or " + 'lifecycle methods.'); 242 | } 243 | return dispatcher.readContext(Context, observedBits); 244 | } 245 | 246 | function identityHashFn(input) { 247 | { 248 | !(typeof input === 'string' || typeof input === 'number' || typeof input === 'boolean' || input === undefined || input === null) ? warningWithoutStack$1(false, 'Invalid key type. Expected a string, number, symbol, or boolean, ' + 'but instead received: %s' + '\n\nTo use non-primitive values as keys, you must pass a hash ' + 'function as the second argument to createResource().', input) : void 0; 249 | } 250 | return input; 251 | } 252 | 253 | var CACHE_LIMIT = 500; 254 | var lru = createLRU(CACHE_LIMIT); 255 | 256 | var entries = new Map(); 257 | 258 | var CacheContext = React.createContext(null); 259 | 260 | function accessResult(resource, fetch, input, key) { 261 | var entriesForResource = entries.get(resource); 262 | if (entriesForResource === undefined) { 263 | entriesForResource = new Map(); 264 | entries.set(resource, entriesForResource); 265 | } 266 | var entry = entriesForResource.get(key); 267 | if (entry === undefined) { 268 | var thenable = fetch(input); 269 | thenable.then(function (value) { 270 | if (newResult.status === Pending) { 271 | var resolvedResult = newResult; 272 | resolvedResult.status = Resolved; 273 | resolvedResult.value = value; 274 | } 275 | }, function (error) { 276 | if (newResult.status === Pending) { 277 | var rejectedResult = newResult; 278 | rejectedResult.status = Rejected; 279 | rejectedResult.value = error; 280 | } 281 | }); 282 | var newResult = { 283 | status: Pending, 284 | value: thenable 285 | }; 286 | var newEntry = lru.add(newResult, deleteEntry.bind(null, resource, key)); 287 | entriesForResource.set(key, newEntry); 288 | return newResult; 289 | } else { 290 | return lru.access(entry); 291 | } 292 | } 293 | 294 | function deleteEntry(resource, key) { 295 | var entriesForResource = entries.get(resource); 296 | if (entriesForResource !== undefined) { 297 | entriesForResource.delete(key); 298 | if (entriesForResource.size === 0) { 299 | entries.delete(resource); 300 | } 301 | } 302 | } 303 | 304 | function unstable_createResource(fetch, maybeHashInput) { 305 | var hashInput = maybeHashInput !== undefined ? maybeHashInput : identityHashFn; 306 | 307 | var resource = { 308 | read: function (input) { 309 | // react-cache currently doesn't rely on context, but it may in the 310 | // future, so we read anyway to prevent access outside of render. 311 | readContext(CacheContext); 312 | var key = hashInput(input); 313 | var result = accessResult(resource, fetch, input, key); 314 | switch (result.status) { 315 | case Pending: 316 | { 317 | var suspender = result.value; 318 | throw suspender; 319 | } 320 | case Resolved: 321 | { 322 | var _value = result.value; 323 | return _value; 324 | } 325 | case Rejected: 326 | { 327 | var error = result.value; 328 | throw error; 329 | } 330 | default: 331 | // Should be unreachable 332 | return undefined; 333 | } 334 | }, 335 | preload: function (input) { 336 | // react-cache currently doesn't rely on context, but it may in the 337 | // future, so we read anyway to prevent access outside of render. 338 | readContext(CacheContext); 339 | var key = hashInput(input); 340 | accessResult(resource, fetch, input, key); 341 | } 342 | }; 343 | return resource; 344 | } 345 | 346 | function unstable_setGlobalCacheLimit(limit) { 347 | lru.setLimit(limit); 348 | } 349 | 350 | exports.unstable_createResource = unstable_createResource; 351 | exports.unstable_setGlobalCacheLimit = unstable_setGlobalCacheLimit; 352 | 353 | Object.defineProperty(exports, '__esModule', { value: true }); 354 | 355 | }))); 356 | -------------------------------------------------------------------------------- /src/packages/react-dom/cjs/react-dom-test-utils.production.min.js: -------------------------------------------------------------------------------- 1 | /** @license React vundefined 2 | * react-dom-test-utils.production.min.js 3 | * 4 | * Copyright (c) Facebook, Inc. and its affiliates. 5 | * 6 | * This source code is licensed under the MIT license found in the 7 | * LICENSE file in the root directory of this source tree. 8 | */ 9 | 'use strict';var h=require("object-assign"),l=require("react"),m=require("react-dom");function n(a){var b=a,c=a;if(a.alternate)for(;b.return;)b=b.return;else{a=b;do b=a,0!==(b.flags&4098)&&(c=b.return),a=b.return;while(a)}return 3===b.tag?c:null}function p(a){if(n(a)!==a)throw Error("Unable to find node on an unmounted component.");} 10 | function q(a){var b=a.alternate;if(!b){b=n(a);if(null===b)throw Error("Unable to find node on an unmounted component.");return b!==a?null:a}for(var c=a,d=b;;){var f=c.return;if(null===f)break;var g=f.alternate;if(null===g){d=f.return;if(null!==d){c=d;continue}break}if(f.child===g.child){for(g=f.child;g;){if(g===c)return p(f),a;if(g===d)return p(f),b;g=g.sibling}throw Error("Unable to find node on an unmounted component.");}if(c.return!==d.return)c=f,d=g;else{for(var e=!1,k=f.child;k;){if(k===c){e= 11 | !0;c=f;d=g;break}if(k===d){e=!0;d=f;c=g;break}k=k.sibling}if(!e){for(k=g.child;k;){if(k===c){e=!0;c=g;d=f;break}if(k===d){e=!0;d=g;c=f;break}k=k.sibling}if(!e)throw Error("Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue.");}}if(c.alternate!==d)throw Error("Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue.");}if(3!==c.tag)throw Error("Unable to find node on an unmounted component."); 12 | return c.stateNode.current===c?a:b}function r(a){var b=a.keyCode;"charCode"in a?(a=a.charCode,0===a&&13===b&&(a=13)):a=b;10===a&&(a=13);return 32<=a||13===a?a:0}function t(){return!0}function u(){return!1} 13 | function v(a){function b(c,b,f,g,e){this._reactName=c;this._targetInst=f;this.type=b;this.nativeEvent=g;this.target=e;this.currentTarget=null;for(var d in a)a.hasOwnProperty(d)&&(c=a[d],this[d]=c?c(g):g[d]);this.isDefaultPrevented=(null!=g.defaultPrevented?g.defaultPrevented:!1===g.returnValue)?t:u;this.isPropagationStopped=u;return this}h(b.prototype,{preventDefault:function(){this.defaultPrevented=!0;var a=this.nativeEvent;a&&(a.preventDefault?a.preventDefault():"unknown"!==typeof a.returnValue&& 14 | (a.returnValue=!1),this.isDefaultPrevented=t)},stopPropagation:function(){var a=this.nativeEvent;a&&(a.stopPropagation?a.stopPropagation():"unknown"!==typeof a.cancelBubble&&(a.cancelBubble=!0),this.isPropagationStopped=t)},persist:function(){},isPersistent:t});return b}var w={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(a){return a.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},x=v(w),y=h({},w,{view:0,detail:0});v(y); 15 | var z,A,B,D=h({},y,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:C,button:0,buttons:0,relatedTarget:function(a){return void 0===a.relatedTarget?a.fromElement===a.srcElement?a.toElement:a.fromElement:a.relatedTarget},movementX:function(a){if("movementX"in a)return a.movementX;a!==B&&(B&&"mousemove"===a.type?(z=a.screenX-B.screenX,A=a.screenY-B.screenY):A=z=0,B=a);return z},movementY:function(a){return"movementY"in a?a.movementY:A}}); 16 | v(D);var E=h({},D,{dataTransfer:0});v(E);var F=h({},y,{relatedTarget:0});v(F);var aa=h({},w,{animationName:0,elapsedTime:0,pseudoElement:0});v(aa);var ba=h({},w,{clipboardData:function(a){return"clipboardData"in a?a.clipboardData:window.clipboardData}});v(ba);var ca=h({},w,{data:0});v(ca); 17 | var da={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},ea={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4", 18 | 116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},fa={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function ha(a){var b=this.nativeEvent;return b.getModifierState?b.getModifierState(a):(a=fa[a])?!!b[a]:!1}function C(){return ha} 19 | var ia=h({},y,{key:function(a){if(a.key){var b=da[a.key]||a.key;if("Unidentified"!==b)return b}return"keypress"===a.type?(a=r(a),13===a?"Enter":String.fromCharCode(a)):"keydown"===a.type||"keyup"===a.type?ea[a.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:C,charCode:function(a){return"keypress"===a.type?r(a):0},keyCode:function(a){return"keydown"===a.type||"keyup"===a.type?a.keyCode:0},which:function(a){return"keypress"=== 20 | a.type?r(a):"keydown"===a.type||"keyup"===a.type?a.keyCode:0}});v(ia);var ja=h({},D,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0});v(ja);var ka=h({},y,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:C});v(ka);var la=h({},w,{propertyName:0,elapsedTime:0,pseudoElement:0});v(la); 21 | var ma=h({},D,{deltaX:function(a){return"deltaX"in a?a.deltaX:"wheelDeltaX"in a?-a.wheelDeltaX:0},deltaY:function(a){return"deltaY"in a?a.deltaY:"wheelDeltaY"in a?-a.wheelDeltaY:"wheelDelta"in a?-a.wheelDelta:0},deltaZ:0,deltaMode:0});v(ma);function na(a,b,c,d,f,g,e,k,N){var G=Array.prototype.slice.call(arguments,3);try{b.apply(c,G)}catch(oa){this.onError(oa)}}var H=!1,I=null,J=!1,K=null,pa={onError:function(a){H=!0;I=a}};function qa(a,b,c,d,f,g,e,k,N){H=!1;I=null;na.apply(pa,arguments)} 22 | function ra(a,b,c,d,f,g,e,k,N){qa.apply(this,arguments);if(H){if(H){var G=I;H=!1;I=null}else throw Error("clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue.");J||(J=!0,K=G)}}var L=Array.isArray,M=m.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Events,sa=M[0],ta=M[1],ua=M[2],va=M[3],wa=M[4],xa=l.unstable_act;function ya(){} 23 | function za(a,b){if(!a)return[];a=q(a);if(!a)return[];for(var c=a,d=[];;){if(5===c.tag||6===c.tag||1===c.tag||0===c.tag){var f=c.stateNode;b(f)&&d.push(f)}if(c.child)c.child.return=c,c=c.child;else{if(c===a)return d;for(;!c.sibling;){if(!c.return||c.return===a)return d;c=c.return}c.sibling.return=c.return;c=c.sibling}}} 24 | function O(a,b){if(a&&!a._reactInternals){var c=String(a);a=L(a)?"an array":a&&1===a.nodeType&&a.tagName?"a DOM node":"[object Object]"===c?"object with keys {"+Object.keys(a).join(", ")+"}":c;throw Error(b+"(...): the first argument must be a React class instance. Instead received: "+(a+"."));}}function P(a){return!(!a||1!==a.nodeType||!a.tagName)}function Q(a){return P(a)?!1:null!=a&&"function"===typeof a.render&&"function"===typeof a.setState} 25 | function R(a,b){return Q(a)?a._reactInternals.type===b:!1}function S(a,b){O(a,"findAllInRenderedTree");return a?za(a._reactInternals,b):[]} 26 | function T(a,b){O(a,"scryRenderedDOMComponentsWithClass");return S(a,function(a){if(P(a)){var c=a.className;"string"!==typeof c&&(c=a.getAttribute("class")||"");var f=c.split(/\s+/);if(!L(b)){if(void 0===b)throw Error("TestUtils.scryRenderedDOMComponentsWithClass expects a className as a second argument.");b=b.split(/\s+/)}return b.every(function(a){return-1!==f.indexOf(a)})}return!1})} 27 | function U(a,b){O(a,"scryRenderedDOMComponentsWithTag");return S(a,function(a){return P(a)&&a.tagName.toUpperCase()===b.toUpperCase()})}function V(a,b){O(a,"scryRenderedComponentsWithType");return S(a,function(a){return R(a,b)})}function W(a,b,c){var d=a.type||"unknown-event";a.currentTarget=ta(c);ra(d,b,void 0,a);a.currentTarget=null} 28 | function X(a,b,c){for(var d=[];a;){d.push(a);do a=a.return;while(a&&5!==a.tag);a=a?a:null}for(a=d.length;0