Skip to content

Commit

Permalink
Adds experimental fundamental interface (#16049)
Browse files Browse the repository at this point in the history
  • Loading branch information
trueadm authored Jul 19, 2019
1 parent b4178af commit 2c4d61e
Show file tree
Hide file tree
Showing 35 changed files with 898 additions and 40 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
"debug-test": "cross-env NODE_ENV=development node --inspect-brk node_modules/.bin/jest --config ./scripts/jest/config.source.js --runInBand",
"test": "cross-env NODE_ENV=development jest --config ./scripts/jest/config.source.js",
"test-persistent": "cross-env NODE_ENV=development jest --config ./scripts/jest/config.source-persistent.js",
"debug-test-persistent": "cross-env NODE_ENV=development node --inspect-brk node_modules/.bin/jest --config ./scripts/jest/config.source-persistent.js --runInBand",
"test-prod": "cross-env NODE_ENV=production jest --config ./scripts/jest/config.source.js",
"test-prod-build": "yarn test-build-prod",
"test-build": "cross-env NODE_ENV=development jest --config ./scripts/jest/config.build.js",
Expand Down
20 changes: 20 additions & 0 deletions packages/react-art/src/ReactARTHostConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -444,3 +444,23 @@ export function unmountEventComponent(
): void {
throw new Error('Not yet implemented.');
}

export function getFundamentalComponentInstance(fundamentalInstance) {
throw new Error('Not yet implemented.');
}

export function mountFundamentalComponent(fundamentalInstance) {
throw new Error('Not yet implemented.');
}

export function shouldUpdateFundamentalComponent(fundamentalInstance) {
throw new Error('Not yet implemented.');
}

export function updateFundamentalComponent(fundamentalInstance) {
throw new Error('Not yet implemented.');
}

export function unmountFundamentalComponent(fundamentalInstance) {
throw new Error('Not yet implemented.');
}
64 changes: 64 additions & 0 deletions packages/react-dom/src/client/ReactDOMHostConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import type {DOMContainer} from './ReactDOM';
import type {
ReactDOMEventResponder,
ReactDOMEventComponentInstance,
ReactDOMFundamentalComponentInstance,
} from 'shared/ReactDOMTypes';
import {
addRootEventTypesForComponentInstance,
Expand Down Expand Up @@ -103,6 +104,7 @@ export type NoTimeout = -1;
import {
enableSuspenseServerRenderer,
enableFlareAPI,
enableFundamentalAPI,
} from 'shared/ReactFeatureFlags';
import warning from 'shared/warning';

Expand Down Expand Up @@ -882,3 +884,65 @@ export function unmountEventComponent(
unmountEventResponder(eventComponentInstance);
}
}

export function getFundamentalComponentInstance(
fundamentalInstance: ReactDOMFundamentalComponentInstance,
): Instance {
if (enableFundamentalAPI) {
const {currentFiber, impl, props, state} = fundamentalInstance;
const instance = impl.getInstance(null, props, state);
precacheFiberNode(currentFiber, instance);
return instance;
}
// Because of the flag above, this gets around the Flow error;
return (null: any);
}

export function mountFundamentalComponent(
fundamentalInstance: ReactDOMFundamentalComponentInstance,
): void {
if (enableFundamentalAPI) {
const {impl, instance, props, state} = fundamentalInstance;
const onMount = impl.onMount;
if (onMount !== undefined) {
onMount(null, instance, props, state);
}
}
}

export function shouldUpdateFundamentalComponent(
fundamentalInstance: ReactDOMFundamentalComponentInstance,
): boolean {
if (enableFundamentalAPI) {
const {impl, prevProps, props, state} = fundamentalInstance;
const shouldUpdate = impl.shouldUpdate;
if (shouldUpdate !== undefined) {
return shouldUpdate(null, prevProps, props, state);
}
}
return true;
}

export function updateFundamentalComponent(
fundamentalInstance: ReactDOMFundamentalComponentInstance,
): void {
if (enableFundamentalAPI) {
const {impl, instance, prevProps, props, state} = fundamentalInstance;
const onUpdate = impl.onUpdate;
if (onUpdate !== undefined) {
onUpdate(null, instance, prevProps, props, state);
}
}
}

export function unmountFundamentalComponent(
fundamentalInstance: ReactDOMFundamentalComponentInstance,
): void {
if (enableFundamentalAPI) {
const {impl, instance, props, state} = fundamentalInstance;
const onUnmount = impl.onUnmount;
if (onUnmount !== undefined) {
onUnmount(null, instance, props, state);
}
}
}
39 changes: 39 additions & 0 deletions packages/react-dom/src/server/ReactPartialRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
warnAboutDeprecatedLifecycles,
enableSuspenseServerRenderer,
enableFlareAPI,
enableFundamentalAPI,
} from 'shared/ReactFeatureFlags';

import {
Expand All @@ -39,6 +40,7 @@ import {
REACT_LAZY_TYPE,
REACT_MEMO_TYPE,
REACT_EVENT_COMPONENT_TYPE,
REACT_FUNDAMENTAL_TYPE,
} from 'shared/ReactSymbols';

import {
Expand Down Expand Up @@ -1190,6 +1192,43 @@ class ReactDOMServerRenderer {
);
}
// eslint-disable-next-line-no-fallthrough
case REACT_FUNDAMENTAL_TYPE: {
if (enableFundamentalAPI) {
const fundamentalImpl = elementType.impl;
const open = fundamentalImpl.getServerSideString(
null,
nextElement.props,
);
const getServerSideStringClose =
fundamentalImpl.getServerSideStringClose;
const close =
getServerSideStringClose !== undefined
? getServerSideStringClose(null, nextElement.props)
: '';
const nextChildren =
fundamentalImpl.reconcileChildren !== false
? toArray(((nextChild: any): ReactElement).props.children)
: [];
const frame: Frame = {
type: null,
domNamespace: parentNamespace,
children: nextChildren,
childIndex: 0,
context: context,
footer: close,
};
if (__DEV__) {
((frame: any): FrameDev).debugElementStack = [];
}
this.stack.push(frame);
return open;
}
invariant(
false,
'ReactDOMServer does not yet support the fundamental API.',
);
}
// eslint-disable-next-line-no-fallthrough
case REACT_LAZY_TYPE:
invariant(
false,
Expand Down
24 changes: 24 additions & 0 deletions packages/react-native-renderer/src/ReactFabricHostConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -472,3 +472,27 @@ export function unmountEventComponent(
unmountEventResponder(eventComponentInstance);
}
}

export function getFundamentalComponentInstance(fundamentalInstance) {
throw new Error('Not yet implemented.');
}

export function mountFundamentalComponent(fundamentalInstance) {
throw new Error('Not yet implemented.');
}

export function shouldUpdateFundamentalComponent(fundamentalInstance) {
throw new Error('Not yet implemented.');
}

export function updateFundamentalComponent(fundamentalInstance) {
throw new Error('Not yet implemented.');
}

export function unmountFundamentalComponent(fundamentalInstance) {
throw new Error('Not yet implemented.');
}

export function cloneFundamentalInstance(fundamentalInstance) {
throw new Error('Not yet implemented.');
}
20 changes: 20 additions & 0 deletions packages/react-native-renderer/src/ReactNativeHostConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -511,3 +511,23 @@ export function unmountEventComponent(
): void {
throw new Error('Not yet implemented.');
}

export function getFundamentalComponentInstance(fundamentalInstance) {
throw new Error('Not yet implemented.');
}

export function mountFundamentalComponent(fundamentalInstance) {
throw new Error('Not yet implemented.');
}

export function shouldUpdateFundamentalComponent(fundamentalInstance) {
throw new Error('Not yet implemented.');
}

export function updateFundamentalComponent(fundamentalInstance) {
throw new Error('Not yet implemented.');
}

export function unmountFundamentalComponent(fundamentalInstance) {
throw new Error('Not yet implemented.');
}
51 changes: 51 additions & 0 deletions packages/react-noop-renderer/src/createReactNoop.js
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,57 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
unmountEventComponent(): void {
// NO-OP
},

getFundamentalComponentInstance(fundamentalInstance): Instance {
const {impl, props, state} = fundamentalInstance;
return impl.getInstance(null, props, state);
},

mountFundamentalComponent(fundamentalInstance): void {
const {impl, instance, props, state} = fundamentalInstance;
const onMount = impl.onUpdate;
if (onMount !== undefined) {
onMount(null, instance, props, state);
}
},

shouldUpdateFundamentalComponent(fundamentalInstance): boolean {
const {impl, instance, prevProps, props, state} = fundamentalInstance;
const shouldUpdate = impl.shouldUpdate;
if (shouldUpdate !== undefined) {
return shouldUpdate(null, instance, prevProps, props, state);
}
return true;
},

updateFundamentalComponent(fundamentalInstance): void {
const {impl, instance, prevProps, props, state} = fundamentalInstance;
const onUpdate = impl.onUpdate;
if (onUpdate !== undefined) {
onUpdate(null, instance, prevProps, props, state);
}
},

unmountFundamentalComponent(fundamentalInstance): void {
const {impl, instance, props, state} = fundamentalInstance;
const onUnmount = impl.onUnmount;
if (onUnmount !== undefined) {
onUnmount(null, instance, props, state);
}
},

cloneFundamentalInstance(fundamentalInstance): Instance {
const instance = fundamentalInstance.instance;
return {
children: [],
text: instance.text,
type: instance.type,
prop: instance.prop,
id: instance.id,
context: instance.context,
hidden: instance.hidden,
};
},
};

const hostConfig = useMutation
Expand Down
36 changes: 34 additions & 2 deletions packages/react-reconciler/src/ReactFiber.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type {
ReactPortal,
RefObject,
ReactEventComponent,
ReactFundamentalComponent,
} from 'shared/ReactTypes';
import type {RootTag} from 'shared/ReactRootTags';
import type {WorkTag} from 'shared/ReactWorkTags';
Expand All @@ -26,7 +27,11 @@ import type {ReactEventComponentInstance} from 'shared/ReactTypes';

import invariant from 'shared/invariant';
import warningWithoutStack from 'shared/warningWithoutStack';
import {enableProfilerTimer, enableFlareAPI} from 'shared/ReactFeatureFlags';
import {
enableProfilerTimer,
enableFlareAPI,
enableFundamentalAPI,
} from 'shared/ReactFeatureFlags';
import {NoEffect, Placement} from 'shared/ReactSideEffectTags';
import {ConcurrentRoot, BatchedRoot} from 'shared/ReactRootTags';
import {
Expand All @@ -49,6 +54,7 @@ import {
SimpleMemoComponent,
LazyComponent,
EventComponent,
FundamentalComponent,
} from 'shared/ReactWorkTags';
import getComponentName from 'shared/getComponentName';

Expand Down Expand Up @@ -79,6 +85,7 @@ import {
REACT_MEMO_TYPE,
REACT_LAZY_TYPE,
REACT_EVENT_COMPONENT_TYPE,
REACT_FUNDAMENTAL_TYPE,
} from 'shared/ReactSymbols';

let hasBadMapPolyfill;
Expand Down Expand Up @@ -663,6 +670,17 @@ export function createFiberFromTypeAndProps(
);
}
break;
case REACT_FUNDAMENTAL_TYPE:
if (enableFundamentalAPI) {
return createFiberFromFundamental(
type,
pendingProps,
mode,
expirationTime,
key,
);
}
break;
}
}
let info = '';
Expand Down Expand Up @@ -742,7 +760,7 @@ export function createFiberFromFragment(
}

export function createFiberFromEventComponent(
eventComponent: ReactEventComponent<any>,
eventComponent: ReactEventComponent<any, any, any>,
pendingProps: any,
mode: TypeOfMode,
expirationTime: ExpirationTime,
Expand All @@ -755,6 +773,20 @@ export function createFiberFromEventComponent(
return fiber;
}

export function createFiberFromFundamental(
fundamentalComponent: ReactFundamentalComponent<any, any>,
pendingProps: any,
mode: TypeOfMode,
expirationTime: ExpirationTime,
key: null | string,
): Fiber {
const fiber = createFiber(FundamentalComponent, pendingProps, key, mode);
fiber.elementType = fundamentalComponent;
fiber.type = fundamentalComponent;
fiber.expirationTime = expirationTime;
return fiber;
}

function createFiberFromProfiler(
pendingProps: any,
mode: TypeOfMode,
Expand Down
Loading

0 comments on commit 2c4d61e

Please sign in to comment.