const {createElement, Component, Placeholder} = React; const {unstable_createRoot: createRoot} = ReactDOM; const { unstable_subscribe: subscribe, unstable_trace: trace, unstable_wrap: wrap, } = SchedulerTracing; const createLogger = (backgroundColor, color, enabled) => ( message, ...args ) => { if (enabled === false) return; console.groupCollapsed( `%c${message}`, `background-color: ${backgroundColor}; color: ${color}; padding: 2px 4px;`, ...args ); console.log( new Error('stack').stack .split('\n') .slice(2) .join('\n') ); console.groupEnd(); }; window.log = { app: createLogger('#37474f', '#fff'), interaction: createLogger('#6a1b9a', '#fff'), react: createLogger('#ff5722', '#fff'), tracing: createLogger('#2962ff', '#fff'), work: createLogger('#e1bee7', '#000'), }; // Fake suspense const resolvedValues = {}; const read = key => { if (!resolvedValues[key]) { log.app(`Suspending for "${key}" ...`); throw new Promise( wrap(resolve => { setTimeout( wrap(() => { log.app(`Loaded "${key}" ...`); resolvedValues[key] = true; resolve(key); }), 1000 ); }) ); } return key; }; const TestApp = () => createElement( Placeholder, {delayMs: 100, fallback: createElement(PlaceholderText)}, createElement(SuspendingChild, {text: 'foo'}), createElement(SuspendingChild, {text: 'bar'}), createElement(SuspendingChild, {text: 'baz'}) ); const PlaceholderText = () => 'Loading ...'; const SuspendingChild = ({text}) => { const resolvedValue = read(text); return resolvedValue; }; subscribe({ onInteractionScheduledWorkCompleted: interaction => log.interaction( 'onInteractionScheduledWorkCompleted', JSON.stringify(interaction) ), onInteractionTraced: interaction => log.interaction('onInteractionTraced', JSON.stringify(interaction)), onWorkCanceled: interactions => log.work('onWorkCanceled', JSON.stringify(Array.from(interactions))), onWorkScheduled: interactions => log.work('onWorkScheduled', JSON.stringify(Array.from(interactions))), onWorkStarted: interactions => log.work('onWorkStarted', JSON.stringify(Array.from(interactions))), onWorkStopped: interactions => log.work('onWorkStopped', JSON.stringify(Array.from(interactions))), }); const element = document.getElementById('root'); trace('initial_render', performance.now(), () => { const root = createRoot(element); const batch = root.createBatch(); log.app('batch.render()'); batch.render(createElement(TestApp)); batch.then( wrap(() => { log.app('batch.commit()'); batch.commit(); }) ); });