mirror of
https://github.com/zebrajr/react.git
synced 2026-01-15 12:15:22 +00:00
Remove experimental RT/CS renderers (#12032)
Will follow up with adding a new one.
This commit is contained in:
committed by
GitHub
parent
d8d797645c
commit
d3647583b3
16
packages/react-cs-renderer/index.js
vendored
16
packages/react-cs-renderer/index.js
vendored
@@ -1,16 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const ReactNativeCS = require('./src/ReactNativeCS');
|
||||
|
||||
// TODO: decide on the top-level export form.
|
||||
// This is hacky but makes it work with both Rollup and Jest.
|
||||
module.exports = ReactNativeCS.default ? ReactNativeCS.default : ReactNativeCS;
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"name": "react-cs-renderer",
|
||||
"version": "16.0.0",
|
||||
"private": true,
|
||||
"repository": "facebook/react",
|
||||
"dependencies": {
|
||||
"fbjs": "^0.8.16",
|
||||
"object-assign": "^4.1.1",
|
||||
"prop-types": "^15.6.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.0.0"
|
||||
}
|
||||
}
|
||||
306
packages/react-cs-renderer/src/ReactNativeCS.js
vendored
306
packages/react-cs-renderer/src/ReactNativeCS.js
vendored
@@ -1,306 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import type {ReactNodeList} from 'shared/ReactTypes';
|
||||
import type {ReactNativeCSType} from './ReactNativeCSTypes';
|
||||
|
||||
// Provided by CS:
|
||||
import {CSStatefulComponent} from 'CSStatefulComponent';
|
||||
|
||||
import ReactFiberReconciler from 'react-reconciler';
|
||||
import ReactVersion from 'shared/ReactVersion';
|
||||
|
||||
const emptyObject = {};
|
||||
|
||||
type Container = {
|
||||
pendingChild: null | Instance | TextInstance,
|
||||
};
|
||||
type InstanceProps = Props & {children: Array<Instance>};
|
||||
type Instance = {
|
||||
props: InstanceProps,
|
||||
options: {key: string, ref: null},
|
||||
data: {type: 'NATIVE', name: string},
|
||||
};
|
||||
type Props = Object;
|
||||
type TextInstance = Instance;
|
||||
|
||||
// We currently don't actually return a new state. We only use state updaters to trigger a
|
||||
// rerender. Therefore our state updater is the identity functions. When we later deal
|
||||
// with sync scheduling and aborted renders, we will need to update the state in render.
|
||||
const identityUpdater = state => state;
|
||||
// We currently don't have a hook for aborting render. Will add one once it is in place
|
||||
// in React Native proper.
|
||||
const infiniteDeadline = {
|
||||
timeRemaining: function() {
|
||||
return Infinity;
|
||||
},
|
||||
};
|
||||
|
||||
const arePropsEqual = (oldProps: Props, newProps: Props): boolean => {
|
||||
let key;
|
||||
for (key in newProps) {
|
||||
if (key === 'children') {
|
||||
// Skip special case.
|
||||
continue;
|
||||
}
|
||||
if (newProps[key] !== oldProps[key]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (key in oldProps) {
|
||||
if (key === 'children') {
|
||||
// Skip special case.
|
||||
continue;
|
||||
}
|
||||
if (!(key in newProps)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
// React doesn't expose its full keypath. To manage lifetime of instances, we instead use IDs.
|
||||
let nextComponentKey = 0;
|
||||
|
||||
// Callback. Currently this is global. TODO: This should be per root.
|
||||
let scheduledCallback = null;
|
||||
// Updater. This is the CS updater we use to trigger the update. TODO: This should be per root.
|
||||
let scheduleUpdate = null;
|
||||
|
||||
const ReactNativeCSFiberRenderer = ReactFiberReconciler({
|
||||
appendInitialChild(
|
||||
parentInstance: Instance,
|
||||
child: Instance | TextInstance,
|
||||
): void {
|
||||
if (parentInstance.props) {
|
||||
parentInstance.props.children.push(child);
|
||||
} else {
|
||||
// CSCustom
|
||||
(parentInstance: any).children.push(child);
|
||||
}
|
||||
},
|
||||
|
||||
createInstance(
|
||||
type: string,
|
||||
props: Props,
|
||||
rootContainerInstance: Container,
|
||||
hostContext: {},
|
||||
internalInstanceHandle: Object,
|
||||
): Instance {
|
||||
let key = '' + nextComponentKey++;
|
||||
let ref = null; // TODO: Always create Ref object so that getPublicInstance can use it.
|
||||
// We need a new props object so that we can represent flattened children.
|
||||
let newProps = Object.assign({}, props);
|
||||
newProps.children = [];
|
||||
if (type === 'CSCustom') {
|
||||
// Special cased type that treats the props as the object.
|
||||
// Useful for custom children types like FlexItem.
|
||||
return newProps;
|
||||
}
|
||||
return {
|
||||
props: newProps,
|
||||
options: {key, ref},
|
||||
data: {type: 'NATIVE', name: type},
|
||||
};
|
||||
},
|
||||
|
||||
createTextInstance(
|
||||
text: string,
|
||||
rootContainerInstance: Container,
|
||||
hostContext: {},
|
||||
internalInstanceHandle: Object,
|
||||
): TextInstance {
|
||||
// Could auto-translate to CSText with some host context defined attributes.
|
||||
throw new Error('Not yet implemented.');
|
||||
},
|
||||
|
||||
finalizeInitialChildren(
|
||||
parentInstance: Instance,
|
||||
type: string,
|
||||
props: Props,
|
||||
rootContainerInstance: Container,
|
||||
): boolean {
|
||||
return false;
|
||||
},
|
||||
|
||||
getRootHostContext(): {} {
|
||||
return emptyObject;
|
||||
},
|
||||
|
||||
getChildHostContext(): {} {
|
||||
return emptyObject;
|
||||
},
|
||||
|
||||
getPublicInstance(instance: Instance) {
|
||||
return instance.options.ref;
|
||||
},
|
||||
|
||||
prepareForCommit(): void {},
|
||||
|
||||
prepareUpdate(
|
||||
instance: Instance,
|
||||
type: string,
|
||||
oldProps: Props,
|
||||
newProps: Props,
|
||||
rootContainerInstance: Container,
|
||||
hostContext: {},
|
||||
): null | InstanceProps {
|
||||
if (arePropsEqual(oldProps, newProps)) {
|
||||
return null;
|
||||
}
|
||||
return Object.assign({}, newProps);
|
||||
},
|
||||
|
||||
resetAfterCommit(): void {},
|
||||
|
||||
shouldDeprioritizeSubtree(type: string, props: Props): boolean {
|
||||
return false;
|
||||
},
|
||||
|
||||
scheduleDeferredCallback(callback) {
|
||||
scheduledCallback = callback;
|
||||
if (scheduleUpdate !== null) {
|
||||
scheduleUpdate(identityUpdater);
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
|
||||
cancelDeferredCallback() {
|
||||
// Noop. This is always called right before scheduling a new update, so
|
||||
// should be fine. This renderer won't use requestIdleCallback, anyway.
|
||||
// Will switch to use shouldYield() API instead.
|
||||
},
|
||||
|
||||
shouldSetTextContent(type: string, props: Props): boolean {
|
||||
// TODO: Figure out when we should allow text content.
|
||||
return false;
|
||||
},
|
||||
|
||||
now(): number {
|
||||
// TODO: Enable expiration by implementing this method.
|
||||
return 0;
|
||||
},
|
||||
|
||||
persistence: {
|
||||
cloneInstance(
|
||||
instance: Instance,
|
||||
updatePayload: null | InstanceProps,
|
||||
type: string,
|
||||
oldProps: Props,
|
||||
newProps: Props,
|
||||
internalInstanceHandle: Object,
|
||||
keepChildren: boolean,
|
||||
recyclableInstance: null | Instance,
|
||||
): Instance {
|
||||
let newInstanceProps = updatePayload;
|
||||
if (newInstanceProps === null) {
|
||||
newInstanceProps = Object.assign({}, newProps);
|
||||
}
|
||||
// We need a new props object so that we can represent flattened children.
|
||||
newInstanceProps.children = keepChildren ? instance.props.children : [];
|
||||
if (type === 'CSCustom') {
|
||||
return newInstanceProps;
|
||||
}
|
||||
return {
|
||||
props: newInstanceProps,
|
||||
options: instance.options,
|
||||
data: instance.data,
|
||||
};
|
||||
},
|
||||
|
||||
createContainerChildSet(container: Container): Container {
|
||||
// We'll only ever have one instance in the container.
|
||||
container.pendingChild = null;
|
||||
return container;
|
||||
},
|
||||
|
||||
appendChildToContainerChildSet(
|
||||
childSet: Container,
|
||||
child: Instance | TextInstance,
|
||||
): void {
|
||||
if (childSet.pendingChild !== null) {
|
||||
throw new Error(
|
||||
'CSReact does not support top level fragments. Wrap it in a primitve.',
|
||||
);
|
||||
}
|
||||
childSet.pendingChild = child;
|
||||
},
|
||||
|
||||
finalizeContainerChildren(
|
||||
container: Container,
|
||||
newChildren: Container,
|
||||
): void {},
|
||||
|
||||
replaceContainerChildren(
|
||||
container: Container,
|
||||
newChildren: Container,
|
||||
): void {},
|
||||
},
|
||||
});
|
||||
|
||||
ReactNativeCSFiberRenderer.injectIntoDevTools({
|
||||
bundleType: __DEV__ ? 1 : 0,
|
||||
version: ReactVersion,
|
||||
rendererPackageName: 'react-cs-renderer',
|
||||
});
|
||||
|
||||
type ReactCSProps = {children: ReactNodeList};
|
||||
type ReactCSState = {
|
||||
root: Object,
|
||||
container: {
|
||||
pendingChild: null | Instance | TextInstance,
|
||||
},
|
||||
};
|
||||
|
||||
const ReactCS = CSStatefulComponent({
|
||||
getInitialState({props}: {props: ReactCSProps}): ReactCSState {
|
||||
let container = {
|
||||
pendingChild: null,
|
||||
};
|
||||
let root = ReactNativeCSFiberRenderer.createContainer(
|
||||
container,
|
||||
false,
|
||||
false,
|
||||
);
|
||||
return {root, container};
|
||||
},
|
||||
render({
|
||||
props,
|
||||
state,
|
||||
stateUpdater,
|
||||
}: {
|
||||
props: ReactCSProps,
|
||||
state: ReactCSState,
|
||||
stateUpdater: (update: (oldState: ReactCSState) => ReactCSState) => void,
|
||||
}) {
|
||||
scheduleUpdate = stateUpdater;
|
||||
// TODO: For a props rerender updateContainer will schedule an additional state
|
||||
// update even though it is not necessary since we're already rendering.
|
||||
// We should only call scheduleUpdate for a React setState, not a top level
|
||||
// props update.
|
||||
ReactNativeCSFiberRenderer.updateContainer(
|
||||
props.children,
|
||||
state.root,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
if (scheduledCallback) {
|
||||
const callback = scheduledCallback;
|
||||
scheduledCallback = null;
|
||||
callback(infiniteDeadline);
|
||||
}
|
||||
return state.container.pendingChild;
|
||||
},
|
||||
getInstance({state}: {state: ReactCSState}) {
|
||||
return ReactNativeCSFiberRenderer.getPublicRootInstance(state.root);
|
||||
},
|
||||
// TODO: Unmount hook. E.g. finalizer.
|
||||
});
|
||||
|
||||
export default (ReactCS: ReactNativeCSType);
|
||||
@@ -1,29 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @providesModule ReactNativeCSTypes
|
||||
*/
|
||||
|
||||
/**
|
||||
* Flat CS renderer bundles are too big for Flow to parse efficiently.
|
||||
* Provide minimal Flow typing for the high-level API and call it a day.
|
||||
*/
|
||||
|
||||
import type {Options, Element} from 'CSComponent';
|
||||
|
||||
export type Children<ChildType> = {|
|
||||
+children: $ReadOnlyArray<React$Element<ChildType>>,
|
||||
|};
|
||||
|
||||
type StatelessComponent<Props> = React$StatelessFunctionalComponent<Props>;
|
||||
|
||||
type ClassComponent<Props, Instance> = Class<React$Component<Props> & Instance>;
|
||||
|
||||
export type ReactNativeCSType = <Props, Instance>(
|
||||
props: Children<ClassComponent<Props, Instance> | StatelessComponent<Props>>,
|
||||
options: Options<Instance> | void,
|
||||
) => Element;
|
||||
@@ -1,14 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
// Mock of the CS Hooks
|
||||
|
||||
export const CSStatefulComponent = function(spec) {
|
||||
return spec;
|
||||
};
|
||||
@@ -1,35 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @emails react-core
|
||||
* @jest-environment node
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
let React;
|
||||
let ReactNativeCS;
|
||||
|
||||
jest.mock('shared/ReactFeatureFlags', () =>
|
||||
require('shared/forks/ReactFeatureFlags.native-cs'),
|
||||
);
|
||||
|
||||
describe('ReactNativeCS', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
|
||||
React = require('react');
|
||||
ReactNativeCS = require('react-cs-renderer');
|
||||
});
|
||||
|
||||
it('should be able to create and render a native component', () => {
|
||||
const CSView = 'View';
|
||||
const props = <CSView foo="test" />;
|
||||
const state = ReactNativeCS.getInitialState({});
|
||||
const stateUpdater = function() {};
|
||||
ReactNativeCS.render({props, state, stateUpdater});
|
||||
});
|
||||
});
|
||||
@@ -1,26 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
// Mock of the Native Hooks
|
||||
|
||||
const RCTRTManager = {
|
||||
createNode: jest.fn(function createView(tag, classType, props) {}),
|
||||
beginUpdates: jest.fn(function beginUpdates() {}),
|
||||
appendChildToContext: jest.fn(function appendChildToContext(
|
||||
contextTag,
|
||||
childTag,
|
||||
) {}),
|
||||
appendChild: jest.fn(function appendChild(parentTag, childTag) {}),
|
||||
prependChild: jest.fn(function prependChild(childTag, beforeTag) {}),
|
||||
deleteChild: jest.fn(function deleteChild(childTag) {}),
|
||||
updateNode: jest.fn(function updateNode(tag, props) {}),
|
||||
completeUpdates: jest.fn(function completeUpdates() {}),
|
||||
};
|
||||
|
||||
module.exports = RCTRTManager;
|
||||
14
packages/react-rt-renderer/index.js
vendored
14
packages/react-rt-renderer/index.js
vendored
@@ -1,14 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
const ReactNativeRT = require('./src/ReactNativeRT');
|
||||
|
||||
// TODO: decide on the top-level export form.
|
||||
// This is hacky but makes it work with both Rollup and Jest.
|
||||
module.exports = ReactNativeRT.default ? ReactNativeRT.default : ReactNativeRT;
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"name": "react-rt-renderer",
|
||||
"version": "16.0.0",
|
||||
"private": true,
|
||||
"repository": "facebook/react",
|
||||
"dependencies": {
|
||||
"fbjs": "^0.8.16",
|
||||
"object-assign": "^4.1.1",
|
||||
"prop-types": "^15.6.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.0.0"
|
||||
}
|
||||
}
|
||||
87
packages/react-rt-renderer/src/ReactNativeRT.js
vendored
87
packages/react-rt-renderer/src/ReactNativeRT.js
vendored
@@ -1,87 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import type {ReactNativeRTType} from './ReactNativeRTTypes';
|
||||
import type {ReactNodeList} from 'shared/ReactTypes';
|
||||
|
||||
/**
|
||||
* Make sure essential globals are available and are patched correctly. Please don't remove this
|
||||
* line. Bundles created by react-packager `require` it before executing any application code. This
|
||||
* ensures it exists in the dependency graph and can be `require`d.
|
||||
* TODO: require this in packager, not in React #10932517
|
||||
*/
|
||||
import 'InitializeCore';
|
||||
import './ReactNativeRTEventEmitter';
|
||||
|
||||
import * as ReactPortal from 'shared/ReactPortal';
|
||||
import * as ReactGenericBatching from 'events/ReactGenericBatching';
|
||||
import ReactVersion from 'shared/ReactVersion';
|
||||
|
||||
import {getFiberFromTag} from './ReactNativeRTComponentTree';
|
||||
import ReactNativeRTFiberRenderer from './ReactNativeRTFiberRenderer';
|
||||
import ReactNativeRTFiberInspector from './ReactNativeRTFiberInspector';
|
||||
|
||||
ReactGenericBatching.injection.injectFiberBatchedUpdates(
|
||||
ReactNativeRTFiberRenderer.batchedUpdates,
|
||||
);
|
||||
|
||||
const roots = new Map();
|
||||
|
||||
const ReactNativeRTFiber: ReactNativeRTType = {
|
||||
render(element: React$Element<any>, containerTag: any, callback: ?Function) {
|
||||
let root = roots.get(containerTag);
|
||||
|
||||
if (!root) {
|
||||
// TODO (bvaughn): If we decide to keep the wrapper component,
|
||||
// We could create a wrapper for containerTag as well to reduce special casing.
|
||||
root = ReactNativeRTFiberRenderer.createContainer(
|
||||
containerTag,
|
||||
false,
|
||||
false,
|
||||
);
|
||||
roots.set(containerTag, root);
|
||||
}
|
||||
ReactNativeRTFiberRenderer.updateContainer(element, root, null, callback);
|
||||
|
||||
return ReactNativeRTFiberRenderer.getPublicRootInstance(root);
|
||||
},
|
||||
|
||||
unmountComponentAtNode(containerTag: number) {
|
||||
const root = roots.get(containerTag);
|
||||
if (root) {
|
||||
// TODO: Is it safe to reset this now or should I wait since this unmount could be deferred?
|
||||
ReactNativeRTFiberRenderer.updateContainer(null, root, null, () => {
|
||||
roots.delete(containerTag);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
createPortal(
|
||||
children: ReactNodeList,
|
||||
containerTag: number,
|
||||
key: ?string = null,
|
||||
) {
|
||||
return ReactPortal.createPortal(children, containerTag, null, key);
|
||||
},
|
||||
|
||||
unstable_batchedUpdates: ReactGenericBatching.batchedUpdates,
|
||||
|
||||
flushSync: ReactNativeRTFiberRenderer.flushSync,
|
||||
};
|
||||
|
||||
ReactNativeRTFiberRenderer.injectIntoDevTools({
|
||||
findFiberByHostInstance: getFiberFromTag,
|
||||
getInspectorDataForViewTag:
|
||||
ReactNativeRTFiberInspector.getInspectorDataForViewTag,
|
||||
bundleType: __DEV__ ? 1 : 0,
|
||||
version: ReactVersion,
|
||||
rendererPackageName: 'react-rt-renderer',
|
||||
});
|
||||
|
||||
export default ReactNativeRTFiber;
|
||||
@@ -1,34 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import type {Fiber} from 'react-reconciler/src/ReactFiber';
|
||||
|
||||
const instanceCache: {[key: number]: Fiber} = {};
|
||||
const instanceProps: {[key: number]: Object} = {};
|
||||
|
||||
export function precacheFiberNode(fiber: Fiber, tag: number): void {
|
||||
instanceCache[tag] = fiber;
|
||||
}
|
||||
|
||||
export function getFiberFromTag(tag: number): null | Fiber {
|
||||
return instanceCache[tag] || null;
|
||||
}
|
||||
|
||||
export function uncacheFiberNode(tag: number): void {
|
||||
delete instanceCache[tag];
|
||||
delete instanceProps[tag];
|
||||
}
|
||||
|
||||
export function getFiberCurrentPropsFromTag(tag: number): null | Object {
|
||||
return instanceProps[tag] || null;
|
||||
}
|
||||
|
||||
export function updateFiberProps(tag: number, props: Object): void {
|
||||
instanceProps[tag] = props;
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import {batchedUpdates} from 'events/ReactGenericBatching';
|
||||
// Module provided by RN:
|
||||
import BatchedBridge from 'BatchedBridge';
|
||||
|
||||
import {getFiberCurrentPropsFromTag} from './ReactNativeRTComponentTree';
|
||||
|
||||
const ReactNativeRTEventEmitter = {
|
||||
/**
|
||||
* Publicly exposed method on module for native objc to invoke when a top
|
||||
* level event is extracted.
|
||||
* @param {rootNodeID} rootNodeID React root node ID that event occurred on.
|
||||
* @param {TopLevelType} topLevelType Top level type of event.
|
||||
* @param {object} nativeEventParam Object passed from native.
|
||||
*/
|
||||
receiveEvent: function(
|
||||
tag: number,
|
||||
topLevelType: string,
|
||||
nativeEventParam: Object,
|
||||
) {
|
||||
const nativeEvent = nativeEventParam;
|
||||
const props = getFiberCurrentPropsFromTag(tag);
|
||||
if (props == null) {
|
||||
return;
|
||||
}
|
||||
const eventHandler = props[topLevelType];
|
||||
if (typeof eventHandler !== 'function') {
|
||||
return;
|
||||
}
|
||||
batchedUpdates(function() {
|
||||
eventHandler(nativeEvent);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
BatchedBridge.registerCallableModule(
|
||||
'RTEventEmitter',
|
||||
ReactNativeRTEventEmitter,
|
||||
);
|
||||
@@ -1,106 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import {
|
||||
findCurrentFiberUsingSlowPath,
|
||||
findCurrentHostFiber,
|
||||
} from 'react-reconciler/reflection';
|
||||
import getComponentName from 'shared/getComponentName';
|
||||
import {HostComponent} from 'shared/ReactTypeOfWork';
|
||||
import emptyObject from 'fbjs/lib/emptyObject';
|
||||
import invariant from 'fbjs/lib/invariant';
|
||||
|
||||
import {getFiberFromTag} from './ReactNativeRTComponentTree';
|
||||
|
||||
let getInspectorDataForViewTag;
|
||||
|
||||
if (__DEV__) {
|
||||
const traverseOwnerTreeUp = function(hierarchy, instance: any) {
|
||||
if (instance) {
|
||||
hierarchy.unshift(instance);
|
||||
traverseOwnerTreeUp(hierarchy, instance._debugOwner);
|
||||
}
|
||||
};
|
||||
|
||||
const getOwnerHierarchy = function(instance: any) {
|
||||
const hierarchy = [];
|
||||
traverseOwnerTreeUp(hierarchy, instance);
|
||||
return hierarchy;
|
||||
};
|
||||
|
||||
const lastNonHostInstance = function(hierarchy) {
|
||||
for (let i = hierarchy.length - 1; i > 1; i--) {
|
||||
const instance = hierarchy[i];
|
||||
|
||||
if (instance.tag !== HostComponent) {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
return hierarchy[0];
|
||||
};
|
||||
|
||||
const getHostProps = function(fiber) {
|
||||
const host = findCurrentHostFiber(fiber);
|
||||
if (host) {
|
||||
return host.memoizedProps || emptyObject;
|
||||
}
|
||||
return emptyObject;
|
||||
};
|
||||
|
||||
const createHierarchy = function(fiberHierarchy) {
|
||||
return fiberHierarchy.map(fiber => ({
|
||||
name: getComponentName(fiber),
|
||||
getInspectorData: findNodeHandle => ({
|
||||
measure: callback => invariant(false, 'Measure not implemented yet'),
|
||||
props: getHostProps(fiber),
|
||||
source: fiber._debugSource,
|
||||
}),
|
||||
}));
|
||||
};
|
||||
|
||||
getInspectorDataForViewTag = function(viewTag: number): Object {
|
||||
const closestInstance = getFiberFromTag(viewTag);
|
||||
|
||||
// Handle case where user clicks outside of ReactNative
|
||||
if (!closestInstance) {
|
||||
return {
|
||||
hierarchy: [],
|
||||
props: emptyObject,
|
||||
selection: null,
|
||||
source: null,
|
||||
};
|
||||
}
|
||||
|
||||
const fiber = findCurrentFiberUsingSlowPath(closestInstance);
|
||||
const fiberHierarchy = getOwnerHierarchy(fiber);
|
||||
const instance = lastNonHostInstance(fiberHierarchy);
|
||||
const hierarchy = createHierarchy(fiberHierarchy);
|
||||
const props = getHostProps(instance);
|
||||
const source = instance._debugSource;
|
||||
const selection = fiberHierarchy.indexOf(instance);
|
||||
|
||||
return {
|
||||
hierarchy,
|
||||
props,
|
||||
selection,
|
||||
source,
|
||||
};
|
||||
};
|
||||
} else {
|
||||
getInspectorDataForViewTag = () => {
|
||||
invariant(
|
||||
false,
|
||||
'getInspectorDataForViewTag() is not available in production',
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default {
|
||||
getInspectorDataForViewTag,
|
||||
};
|
||||
@@ -1,243 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import ReactFiberReconciler from 'react-reconciler';
|
||||
import emptyObject from 'fbjs/lib/emptyObject';
|
||||
import invariant from 'fbjs/lib/invariant';
|
||||
// Module provided by RN:
|
||||
import RTManager from 'RTManager';
|
||||
|
||||
import {
|
||||
precacheFiberNode,
|
||||
updateFiberProps,
|
||||
} from './ReactNativeRTComponentTree';
|
||||
import ReactNativeRTTagHandles from './ReactNativeRTTagHandles';
|
||||
|
||||
export type Container = number;
|
||||
export type Instance = number;
|
||||
export type Props = Object;
|
||||
export type TextInstance = number;
|
||||
|
||||
function processProps(instance: number, props: Props): Object {
|
||||
const propsPayload = {};
|
||||
for (const key in props) {
|
||||
if (key === 'children') {
|
||||
// Skip special case.
|
||||
continue;
|
||||
}
|
||||
let value = props[key];
|
||||
if (typeof value === 'function') {
|
||||
value = {
|
||||
style: 'rt-event',
|
||||
event: key,
|
||||
tag: instance,
|
||||
};
|
||||
}
|
||||
propsPayload[key] = value;
|
||||
}
|
||||
return propsPayload;
|
||||
}
|
||||
|
||||
function arePropsEqual(oldProps: Props, newProps: Props): boolean {
|
||||
let key;
|
||||
for (key in newProps) {
|
||||
if (key === 'children') {
|
||||
// Skip special case.
|
||||
continue;
|
||||
}
|
||||
if (newProps[key] !== oldProps[key]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (key in oldProps) {
|
||||
if (key === 'children') {
|
||||
// Skip special case.
|
||||
continue;
|
||||
}
|
||||
if (!(key in newProps)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const NativeRTRenderer = ReactFiberReconciler({
|
||||
appendInitialChild(
|
||||
parentInstance: Instance,
|
||||
child: Instance | TextInstance,
|
||||
): void {
|
||||
RTManager.appendChild(parentInstance, child);
|
||||
},
|
||||
|
||||
createInstance(
|
||||
type: string,
|
||||
props: Props,
|
||||
rootContainerInstance: Container,
|
||||
hostContext: {},
|
||||
internalInstanceHandle: Object,
|
||||
): Instance {
|
||||
const tag = ReactNativeRTTagHandles.allocateTag();
|
||||
precacheFiberNode(internalInstanceHandle, tag);
|
||||
updateFiberProps(tag, props);
|
||||
RTManager.createNode(tag, type, processProps(tag, props));
|
||||
return tag;
|
||||
},
|
||||
|
||||
createTextInstance(
|
||||
text: string,
|
||||
rootContainerInstance: Container,
|
||||
hostContext: {},
|
||||
internalInstanceHandle: Object,
|
||||
): TextInstance {
|
||||
invariant(false, 'Text components are not supported for now.');
|
||||
},
|
||||
|
||||
finalizeInitialChildren(
|
||||
parentInstance: Instance,
|
||||
type: string,
|
||||
props: Props,
|
||||
rootContainerInstance: Container,
|
||||
): boolean {
|
||||
return false;
|
||||
},
|
||||
|
||||
getRootHostContext(): {} {
|
||||
return emptyObject;
|
||||
},
|
||||
|
||||
getChildHostContext(): {} {
|
||||
return emptyObject;
|
||||
},
|
||||
|
||||
getPublicInstance(instance) {
|
||||
return instance;
|
||||
},
|
||||
|
||||
prepareForCommit(): void {
|
||||
RTManager.beginUpdates();
|
||||
},
|
||||
|
||||
prepareUpdate(
|
||||
instance: Instance,
|
||||
type: string,
|
||||
oldProps: Props,
|
||||
newProps: Props,
|
||||
rootContainerInstance: Container,
|
||||
hostContext: {},
|
||||
): null | Object {
|
||||
if (arePropsEqual(oldProps, newProps)) {
|
||||
return null;
|
||||
}
|
||||
return processProps(instance, newProps);
|
||||
},
|
||||
|
||||
resetAfterCommit(): void {
|
||||
RTManager.completeUpdates();
|
||||
},
|
||||
|
||||
shouldDeprioritizeSubtree(type: string, props: Props): boolean {
|
||||
return false;
|
||||
},
|
||||
|
||||
scheduleDeferredCallback: global.requestIdleCallback,
|
||||
cancelDeferredCallback: global.cancelIdleCallback,
|
||||
|
||||
shouldSetTextContent(type: string, props: Props): boolean {
|
||||
// TODO: Figure out when we should allow text content.
|
||||
return false;
|
||||
},
|
||||
|
||||
now(): number {
|
||||
// TODO: Enable expiration by implementing this method.
|
||||
return 0;
|
||||
},
|
||||
|
||||
mutation: {
|
||||
appendChild(
|
||||
parentInstance: Instance,
|
||||
child: Instance | TextInstance,
|
||||
): void {
|
||||
RTManager.appendChild(parentInstance, child);
|
||||
},
|
||||
|
||||
appendChildToContainer(
|
||||
parentInstance: Container,
|
||||
child: Instance | TextInstance,
|
||||
): void {
|
||||
RTManager.appendChildToContext(parentInstance, child);
|
||||
},
|
||||
|
||||
commitTextUpdate(
|
||||
textInstance: TextInstance,
|
||||
oldText: string,
|
||||
newText: string,
|
||||
): void {
|
||||
invariant(false, 'Text components are not yet supported.');
|
||||
},
|
||||
|
||||
commitMount(
|
||||
instance: Instance,
|
||||
type: string,
|
||||
newProps: Props,
|
||||
internalInstanceHandle: Object,
|
||||
): void {
|
||||
// Noop
|
||||
},
|
||||
|
||||
commitUpdate(
|
||||
instance: Instance,
|
||||
updatePayload: Object,
|
||||
type: string,
|
||||
oldProps: Props,
|
||||
newProps: Props,
|
||||
internalInstanceHandle: Object,
|
||||
): void {
|
||||
updateFiberProps(instance, newProps);
|
||||
RTManager.updateNode(instance, updatePayload);
|
||||
},
|
||||
|
||||
insertBefore(
|
||||
parentInstance: Instance,
|
||||
child: Instance | TextInstance,
|
||||
beforeChild: Instance | TextInstance,
|
||||
): void {
|
||||
RTManager.prependChild(child, beforeChild);
|
||||
},
|
||||
|
||||
insertInContainerBefore(
|
||||
parentInstance: Container,
|
||||
child: Instance | TextInstance,
|
||||
beforeChild: Instance | TextInstance,
|
||||
): void {
|
||||
RTManager.prependChild(child, beforeChild);
|
||||
},
|
||||
|
||||
removeChild(
|
||||
parentInstance: Instance,
|
||||
child: Instance | TextInstance,
|
||||
): void {
|
||||
// TODO: recursively uncache, by traversing fibers, this will currently leak
|
||||
RTManager.deleteChild(child);
|
||||
},
|
||||
|
||||
removeChildFromContainer(
|
||||
parentInstance: Container,
|
||||
child: Instance | TextInstance,
|
||||
): void {
|
||||
// TODO: recursively uncache, by traversing fibers, this will currently leak
|
||||
RTManager.deleteChild(child);
|
||||
},
|
||||
|
||||
resetTextContent(instance: Instance): void {
|
||||
// Noop
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export default NativeRTRenderer;
|
||||
@@ -1,51 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import invariant from 'fbjs/lib/invariant';
|
||||
|
||||
/**
|
||||
* Keeps track of allocating and associating native "tags" which are numeric,
|
||||
* unique view IDs. All the native tags are negative numbers, to avoid
|
||||
* collisions, but in the JS we keep track of them as positive integers to store
|
||||
* them effectively in Arrays. So we must refer to them as "inverses" of the
|
||||
* native tags (that are * normally negative).
|
||||
*
|
||||
* It *must* be the case that every `rootNodeID` always maps to the exact same
|
||||
* `tag` forever. The easiest way to accomplish this is to never delete
|
||||
* anything from this table.
|
||||
* Why: Because `dangerouslyReplaceNodeWithMarkupByID` relies on being able to
|
||||
* unmount a component with a `rootNodeID`, then mount a new one in its place,
|
||||
*/
|
||||
const INITIAL_TAG_COUNT = 1;
|
||||
const ReactNativeRTTagHandles = {
|
||||
tagsStartAt: INITIAL_TAG_COUNT,
|
||||
tagCount: INITIAL_TAG_COUNT,
|
||||
|
||||
allocateTag: function(): number {
|
||||
// Skip over root IDs as those are reserved for native
|
||||
const tag = ReactNativeRTTagHandles.tagCount;
|
||||
ReactNativeRTTagHandles.tagCount++;
|
||||
return tag;
|
||||
},
|
||||
|
||||
assertRootTag: function(tag: number): void {
|
||||
invariant(
|
||||
ReactNativeRTTagHandles.reactTagIsNativeID(tag),
|
||||
'Expect a native root tag, instead got %s',
|
||||
tag,
|
||||
);
|
||||
},
|
||||
|
||||
reactTagIsNativeID: function(reactTag: number): boolean {
|
||||
// We reserve all tags that are 1 mod 10 for native view creation
|
||||
return reactTag % 10 === 1;
|
||||
},
|
||||
};
|
||||
|
||||
export default ReactNativeRTTagHandles;
|
||||
@@ -1,23 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @providesModule ReactNativeRTTypes
|
||||
*/
|
||||
|
||||
/**
|
||||
* Flat RT renderer bundles are too big for Flow to parse efficiently.
|
||||
* Provide minimal Flow typing for the high-level RN API and call it a day.
|
||||
*/
|
||||
export type ReactNativeRTType = {
|
||||
render(
|
||||
element: React$Element<any>,
|
||||
containerTag: any,
|
||||
callback: ?Function,
|
||||
): any,
|
||||
unmountComponentAtNode(containerTag: number): any,
|
||||
unstable_batchedUpdates: any, // TODO (bvaughn) Add types
|
||||
};
|
||||
@@ -1,62 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @emails react-core
|
||||
* @jest-environment node
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
let React;
|
||||
let ReactNativeRT;
|
||||
let RTManager;
|
||||
|
||||
describe('ReactNativeRT', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
|
||||
React = require('react');
|
||||
ReactNativeRT = require('react-rt-renderer');
|
||||
RTManager = require('RTManager');
|
||||
});
|
||||
|
||||
it('should be able to create and render a native component', () => {
|
||||
ReactNativeRT.render(<rt-box foo="test" />, 1);
|
||||
expect(RTManager.createNode).toBeCalled();
|
||||
expect(RTManager.appendChildToContext).toBeCalled();
|
||||
expect(RTManager.appendChild).not.toBeCalled();
|
||||
expect(RTManager.updateNode).not.toBeCalled();
|
||||
});
|
||||
|
||||
it('should be able to create and update a native component', () => {
|
||||
ReactNativeRT.render(<rt-box foo="foo" />, 11);
|
||||
|
||||
expect(RTManager.createNode.mock.calls.length).toBe(1);
|
||||
expect(RTManager.createNode).toBeCalledWith(1, 'rt-box', {foo: 'foo'});
|
||||
expect(RTManager.appendChildToContext.mock.calls.length).toBe(1);
|
||||
expect(RTManager.appendChild).not.toBeCalled();
|
||||
expect(RTManager.updateNode).not.toBeCalled();
|
||||
|
||||
ReactNativeRT.render(<rt-box foo="bar" />, 11);
|
||||
|
||||
expect(RTManager.createNode.mock.calls.length).toBe(1);
|
||||
expect(RTManager.appendChildToContext.mock.calls.length).toBe(1);
|
||||
expect(RTManager.appendChild).not.toBeCalled();
|
||||
expect(RTManager.updateNode).toBeCalledWith(1, {foo: 'bar'});
|
||||
|
||||
ReactNativeRT.render(
|
||||
<rt-box foo="bar">
|
||||
<rt-box />
|
||||
</rt-box>,
|
||||
11,
|
||||
);
|
||||
|
||||
expect(RTManager.createNode.mock.calls.length).toBe(2);
|
||||
expect(RTManager.appendChildToContext.mock.calls.length).toBe(1);
|
||||
expect(RTManager.appendChildToContext.mock.calls.length).toBe(1);
|
||||
expect(RTManager.updateNode.mock.calls.length).toBe(1);
|
||||
});
|
||||
});
|
||||
@@ -3,9 +3,7 @@
|
||||
set -e
|
||||
|
||||
# Make sure we don't introduce accidental @providesModule annotations.
|
||||
EXPECTED='packages/react-cs-renderer/src/ReactNativeCSTypes.js
|
||||
packages/react-native-renderer/src/ReactNativeTypes.js
|
||||
packages/react-rt-renderer/src/ReactNativeRTTypes.js
|
||||
EXPECTED='packages/react-native-renderer/src/ReactNativeTypes.js
|
||||
packages/shared/ReactTypes.js
|
||||
scripts/rollup/wrappers.js'
|
||||
ACTUAL=$(git grep -l @providesModule -- './*.js' ':!scripts/rollup/shims/*.js')
|
||||
|
||||
@@ -131,32 +131,6 @@ const bundles = [
|
||||
],
|
||||
},
|
||||
|
||||
/******* React Native RT *******/
|
||||
{
|
||||
label: 'native-rt',
|
||||
bundleTypes: [RN_DEV, RN_PROD],
|
||||
moduleType: RENDERER,
|
||||
entry: 'react-rt-renderer',
|
||||
global: 'ReactRTRenderer',
|
||||
externals: [
|
||||
'ExceptionsManager',
|
||||
'InitializeCore',
|
||||
'Platform',
|
||||
'BatchedBridge',
|
||||
'RTManager',
|
||||
],
|
||||
},
|
||||
|
||||
/******* React Native CS *******/
|
||||
{
|
||||
label: 'native-cs',
|
||||
bundleTypes: [RN_DEV, RN_PROD],
|
||||
moduleType: RENDERER,
|
||||
entry: 'react-cs-renderer',
|
||||
global: 'ReactCSRenderer',
|
||||
externals: ['CSStatefulComponent'],
|
||||
},
|
||||
|
||||
/******* React Test Renderer *******/
|
||||
{
|
||||
label: 'test',
|
||||
|
||||
@@ -34,8 +34,6 @@ const forks = Object.freeze({
|
||||
switch (entry) {
|
||||
case 'react-native-renderer':
|
||||
return 'shared/forks/ReactFeatureFlags.native.js';
|
||||
case 'react-cs-renderer':
|
||||
return 'shared/forks/ReactFeatureFlags.native-cs.js';
|
||||
default:
|
||||
switch (bundleType) {
|
||||
case FB_DEV:
|
||||
@@ -91,7 +89,6 @@ const forks = Object.freeze({
|
||||
case RN_PROD:
|
||||
switch (entry) {
|
||||
case 'react-native-renderer':
|
||||
case 'react-rt-renderer':
|
||||
// Use the RN fork which plays well with redbox.
|
||||
return 'react-reconciler/src/forks/ReactFiberErrorDialog.native.js';
|
||||
default:
|
||||
|
||||
@@ -44,10 +44,6 @@ function getBundleOutputPaths(bundleType, filename, packageName) {
|
||||
case RN_DEV:
|
||||
case RN_PROD:
|
||||
switch (packageName) {
|
||||
case 'react-rt-renderer':
|
||||
return [`build/react-rt/${filename}`];
|
||||
case 'react-cs-renderer':
|
||||
return [`build/react-cs/${filename}`];
|
||||
case 'react-native-renderer':
|
||||
return [`build/react-native/${filename}`];
|
||||
default:
|
||||
@@ -77,16 +73,6 @@ async function copyRNShims() {
|
||||
require.resolve('react-native-renderer/src/ReactNativeTypes.js'),
|
||||
'build/react-native/shims/ReactNativeTypes.js'
|
||||
),
|
||||
// React Native CS
|
||||
asyncCopyTo(
|
||||
require.resolve('react-cs-renderer/src/ReactNativeCSTypes.js'),
|
||||
'build/react-cs/shims/ReactNativeCSTypes.js'
|
||||
),
|
||||
// React Native RT
|
||||
asyncCopyTo(
|
||||
require.resolve('react-rt-renderer/src/ReactNativeRTTypes.js'),
|
||||
'build/react-rt/shims/ReactNativeRTTypes.js'
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -273,34 +273,6 @@
|
||||
"size": 196483,
|
||||
"gzip": 34394
|
||||
},
|
||||
{
|
||||
"filename": "ReactRTRenderer-dev.js",
|
||||
"bundleType": "RN_DEV",
|
||||
"packageName": "react-rt-renderer",
|
||||
"size": 286506,
|
||||
"gzip": 61843
|
||||
},
|
||||
{
|
||||
"filename": "ReactRTRenderer-prod.js",
|
||||
"bundleType": "RN_PROD",
|
||||
"packageName": "react-rt-renderer",
|
||||
"size": 133702,
|
||||
"gzip": 23039
|
||||
},
|
||||
{
|
||||
"filename": "ReactCSRenderer-dev.js",
|
||||
"bundleType": "RN_DEV",
|
||||
"packageName": "react-cs-renderer",
|
||||
"size": 277130,
|
||||
"gzip": 58953
|
||||
},
|
||||
{
|
||||
"filename": "ReactCSRenderer-prod.js",
|
||||
"bundleType": "RN_PROD",
|
||||
"packageName": "react-cs-renderer",
|
||||
"size": 126142,
|
||||
"gzip": 21682
|
||||
},
|
||||
{
|
||||
"filename": "react-test-renderer.development.js",
|
||||
"bundleType": "NODE_DEV",
|
||||
|
||||
@@ -7,8 +7,6 @@ const resolvePath = require('./utils').resolvePath;
|
||||
const DEFAULT_FB_SOURCE_PATH = '~/fbsource/';
|
||||
const DEFAULT_WWW_PATH = '~/www/';
|
||||
const RELATIVE_RN_PATH = 'xplat/js/react-native-github/Libraries/Renderer/';
|
||||
const RELATIVE_RN_CS_PATH = 'xplat/js/RKJSModules/Libraries/CS/downstream/';
|
||||
const RELATIVE_RN_RT_PATH = 'xplat/js/RKJSModules/Libraries/RT/downstream/';
|
||||
const RELATIVE_WWW_PATH = 'html/shared/react/';
|
||||
|
||||
async function doSync(buildPath, destPath) {
|
||||
@@ -49,17 +47,7 @@ async function syncReactNative(buildPath, fbSourcePath) {
|
||||
await syncReactNativeHelper(buildPath, fbSourcePath, RELATIVE_RN_PATH);
|
||||
}
|
||||
|
||||
async function syncReactNativeCS(buildPath, fbSourcePath) {
|
||||
await syncReactNativeHelper(buildPath, fbSourcePath, RELATIVE_RN_CS_PATH);
|
||||
}
|
||||
|
||||
async function syncReactNativeRT(buildPath, fbSourcePath) {
|
||||
await syncReactNativeHelper(buildPath, fbSourcePath, RELATIVE_RN_RT_PATH);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
syncReactDom,
|
||||
syncReactNative,
|
||||
syncReactNativeCS,
|
||||
syncReactNativeRT,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user