publish react plugin

Summary:
Publishing React Dev tools plugin:
- migrate to TS
- move iOS and JS part to public folder (Android was already)

Reviewed By: passy

Differential Revision: D17164782

fbshipit-source-id: 20ccba71d807df2d33fe5348a62c6ee7f78ae8ba
This commit is contained in:
Daniel Büchele
2019-09-05 03:13:23 -07:00
committed by Facebook Github Bot
parent 7bb9ef4a37
commit b7933aef2e
8 changed files with 336 additions and 0 deletions

View File

@@ -0,0 +1,17 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
*/
#if FB_SONARKIT_ENABLED
#import <Foundation/Foundation.h>
#import <FlipperKit/FlipperPlugin.h>
@interface FlipperKitReactPlugin : NSObject<FlipperPlugin>
@end
#endif

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
*/
#if FB_SONARKIT_ENABLED
#import "FlipperKitReactPlugin.h"
#import <FlipperKit/FlipperClient.h>
#import <FlipperKit/FlipperConnection.h>
#import <FlipperKit/FlipperResponder.h>
#import "Plugins.h"
@implementation FlipperKitReactPlugin
- (NSString*)identifier {
return @"React";
}
- (void)didConnect:(id<FlipperConnection>)connection {
[connection receive:@"config"
withBlock:^(NSDictionary* params, id<FlipperResponder> responder){
// set received port and host to dev tools
}];
}
- (void)didDisconnect {
}
@end
void FlipperKitReactPluginInit(FlipperClient *client)
{
[client addPlugin:[FlipperKitReactPlugin new]];
}
#endif

View File

@@ -0,0 +1,37 @@
/**
* Copyright 2018-present Facebook.
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
* @format
*/
import proc from 'child_process';
function execADB(
command: string,
device: string | null,
...args: Array<string>
): Promise<string> {
const deviceSpecifier = device != null && device !== '' ? `-s ${device}` : '';
return new Promise((resolve, reject) => {
const adb = `adb ${deviceSpecifier} ${command} ${args.join(' ')}`;
proc.exec(adb, (error, stdout, _stderr) => {
if (error) {
reject(error);
} else {
resolve(stdout);
}
});
});
}
export async function reverse(
local: number,
remote: number,
device?: string,
): Promise<string> {
return await execADB(
`reverse tcp:${local} tcp:${remote}`,
device != null ? device : null,
);
}

View File

@@ -0,0 +1,14 @@
/**
* Copyright 2018-present Facebook.
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
* @format
*/
declare module 'get-port' {
const getPort: (options?: {
readonly port?: number;
readonly host?: string;
}) => Promise<number>;
export default getPort;
}

View File

@@ -0,0 +1,93 @@
/**
* Copyright 2018-present Facebook.
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
* @format
*/
import ReactDOM from 'react-dom';
import ReactDevToolsStandalone from 'react-devtools-core/standalone';
import {FlipperPlugin, AndroidDevice, styled} from 'flipper';
import React from 'react';
import getPort from 'get-port';
import address from 'address';
import {reverse} from './ADB';
const Container = styled('div')({
display: 'flex',
flex: '1 1 0%',
justifyContent: 'center',
alignItems: 'stretch',
});
const DEV_TOOLS_NODE_ID = 'reactdevtools-out-of-react-node';
function createDevToolsNode(): HTMLElement {
const div = document.createElement('div');
div.id = DEV_TOOLS_NODE_ID;
div.style.display = 'none';
div.style.width = '100%';
div.style.height = '100%';
div.style.flex = '1 1 0%';
div.style.justifyContent = 'center';
div.style.alignItems = 'stretch';
document.body && document.body.appendChild(div);
return div;
}
function findDevToolsNode(): HTMLElement | null {
return document.querySelector('#' + DEV_TOOLS_NODE_ID);
}
function attachDevTools(target: Element | Text, devToolsNode: HTMLElement) {
target.insertBefore(devToolsNode, target.childNodes[0]);
devToolsNode.style.display = 'flex';
}
function detachDevTools(devToolsNode: HTMLElement) {
devToolsNode.style.display = 'none';
document.body && document.body.appendChild(devToolsNode);
}
export default class extends FlipperPlugin<{}, any, {}> {
componentDidMount() {
let devToolsNode = findDevToolsNode();
if (!devToolsNode) {
devToolsNode = createDevToolsNode();
this.initializeDevTools(devToolsNode);
}
const currentComponentNode = ReactDOM.findDOMNode(this);
currentComponentNode && attachDevTools(currentComponentNode, devToolsNode);
}
componentWillUnmount() {
const devToolsNode = findDevToolsNode();
devToolsNode && detachDevTools(devToolsNode);
}
async initializeDevTools(devToolsNode: HTMLElement) {
const port = await getPort({port: 8097}); // default port for dev tools
ReactDevToolsStandalone.setContentDOMNode(devToolsNode).startServer(port);
const device = await this.getDevice();
if (device) {
const host =
device.deviceType === 'physical'
? address.ip()
: device instanceof AndroidDevice
? '10.0.2.2' // Host IP for Android emulator host system
: 'localhost';
this.client.call('config', {port, host});
if (['quest', 'go', 'pacific'].includes(device.title.toLowerCase())) {
reverse(port, port);
}
}
}
render() {
return <Container />;
}
}

View File

@@ -0,0 +1,17 @@
{
"name": "React",
"version": "1.0.1",
"main": "index.tsx",
"license": "MIT",
"dependencies": {
"address": "^1.1.2",
"get-port": "^4.0.0",
"react-devtools-core": "^4.0.6"
},
"title": "React Devtools",
"icon": "app-react",
"bugs": {
"email": "danielbuechele@fb.com"
},
"devDependencies": {}
}

View File

@@ -0,0 +1,15 @@
/**
* Copyright 2018-present Facebook.
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
* @format
*/
declare module 'react-devtools-core/standalone' {
interface DevTools {
setContentDOMNode(node: HTMLElement): DevTools;
startServer(port: number): DevTools;
}
const DevTools: DevTools;
export default DevTools;
}

View File

@@ -0,0 +1,103 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
address@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6"
integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==
array-filter@~0.0.0:
version "0.0.1"
resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec"
array-map@~0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662"
array-reduce@~0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b"
async-limiter@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8"
integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==
d@1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a"
integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==
dependencies:
es5-ext "^0.10.50"
type "^1.0.1"
es5-ext@^0.10.35, es5-ext@^0.10.50, es5-ext@~0.10.14:
version "0.10.50"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.50.tgz#6d0e23a0abdb27018e5ac4fd09b412bc5517a778"
integrity sha512-KMzZTPBkeQV/JcSQhI5/z6d9VWJ3EnQ194USTUwIYZ2ZbpN8+SGXQKt1h68EX44+qt+Fzr8DO17vnxrw7c3agw==
dependencies:
es6-iterator "~2.0.3"
es6-symbol "~3.1.1"
next-tick "^1.0.0"
es6-iterator@~2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7"
integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c=
dependencies:
d "1"
es5-ext "^0.10.35"
es6-symbol "^3.1.1"
es6-symbol@^3, es6-symbol@^3.1.1, es6-symbol@~3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77"
integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=
dependencies:
d "1"
es5-ext "~0.10.14"
get-port@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/get-port/-/get-port-4.0.0.tgz#373c85960138ee20027c070e3cb08019fea29816"
integrity sha512-Yy3yNI2oShgbaWg4cmPhWjkZfktEvpKI09aDX4PZzNtlU9obuYrX7x2mumQsrNxlF+Ls7OtMQW/u+X4s896bOQ==
jsonify@~0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
next-tick@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
integrity sha1-yobR/ogoFpsBICCOPchCS524NCw=
react-devtools-core@^4.0.6:
version "4.0.6"
resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.0.6.tgz#681c7349db618856d6df7d31a6a49edee9d9e428"
integrity sha512-IhAndVGmV74Bio1BRrlbsonH6bX3XFHgz2uixJFlNjg/Rm264mBveIMwM6+rV3yObSKVnggXRMtJuyWoPk2Smw==
dependencies:
es6-symbol "^3"
shell-quote "^1.6.1"
ws "^7"
shell-quote@^1.6.1:
version "1.6.1"
resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767"
dependencies:
array-filter "~0.0.0"
array-map "~0.0.0"
array-reduce "~0.0.0"
jsonify "~0.0.0"
type@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/type/-/type-1.0.3.tgz#16f5d39f27a2d28d86e48f8981859e9d3296c179"
integrity sha512-51IMtNfVcee8+9GJvj0spSuFcZHe9vSib6Xtgsny1Km9ugyz2mbS08I3rsUIRYgJohFRFU1160sgRodYz378Hg==
ws@^7:
version "7.1.1"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.1.1.tgz#f9942dc868b6dffb72c14fd8f2ba05f77a4d5983"
integrity sha512-o41D/WmDeca0BqYhsr3nJzQyg9NF5X8l/UdnFNux9cS3lwB+swm8qGWX5rn+aD6xfBU3rGmtHij7g7x6LxFU3A==
dependencies:
async-limiter "^1.0.0"