From b6e1b08e3f525632c07f11a9bfe50ea357500ab2 Mon Sep 17 00:00:00 2001 From: Brian Vaughn Date: Mon, 12 Apr 2021 17:07:14 -0400 Subject: [PATCH] Add createBridge and createStore exports to react-devtools-inline (for Replay integration) (#21032) --- packages/react-devtools-core/package.json | 2 +- .../chrome/manifest.json | 4 +- .../edge/manifest.json | 4 +- .../firefox/manifest.json | 2 +- packages/react-devtools-inline/README.md | 34 +++++++++++ packages/react-devtools-inline/package.json | 2 +- .../react-devtools-inline/src/frontend.js | 57 ++++++++++++++----- packages/react-devtools/CHANGELOG.md | 7 ++- packages/react-devtools/package.json | 4 +- 9 files changed, 91 insertions(+), 25 deletions(-) diff --git a/packages/react-devtools-core/package.json b/packages/react-devtools-core/package.json index 9a8fff2e8e2c3..39947c4177b9c 100644 --- a/packages/react-devtools-core/package.json +++ b/packages/react-devtools-core/package.json @@ -1,6 +1,6 @@ { "name": "react-devtools-core", - "version": "4.11.0", + "version": "4.12.0", "description": "Use react-devtools outside of the browser", "license": "MIT", "main": "./dist/backend.js", diff --git a/packages/react-devtools-extensions/chrome/manifest.json b/packages/react-devtools-extensions/chrome/manifest.json index 0ce9f5470ded6..64f3c0afe23e7 100644 --- a/packages/react-devtools-extensions/chrome/manifest.json +++ b/packages/react-devtools-extensions/chrome/manifest.json @@ -2,8 +2,8 @@ "manifest_version": 2, "name": "React Developer Tools", "description": "Adds React debugging tools to the Chrome Developer Tools.", - "version": "4.11.0", - "version_name": "4.11.0", + "version": "4.12.0", + "version_name": "4.12.0", "minimum_chrome_version": "60", diff --git a/packages/react-devtools-extensions/edge/manifest.json b/packages/react-devtools-extensions/edge/manifest.json index be01541b81596..d78048924e429 100644 --- a/packages/react-devtools-extensions/edge/manifest.json +++ b/packages/react-devtools-extensions/edge/manifest.json @@ -2,8 +2,8 @@ "manifest_version": 2, "name": "React Developer Tools", "description": "Adds React debugging tools to the Microsoft Edge Developer Tools.", - "version": "4.11.0", - "version_name": "4.11.0", + "version": "4.12.0", + "version_name": "4.12.0", "minimum_chrome_version": "60", diff --git a/packages/react-devtools-extensions/firefox/manifest.json b/packages/react-devtools-extensions/firefox/manifest.json index 9cb050fa8556e..fa8dc48ca413d 100644 --- a/packages/react-devtools-extensions/firefox/manifest.json +++ b/packages/react-devtools-extensions/firefox/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 2, "name": "React Developer Tools", "description": "Adds React debugging tools to the Firefox Developer Tools.", - "version": "4.11.0", + "version": "4.12.0", "applications": { "gecko": { diff --git a/packages/react-devtools-inline/README.md b/packages/react-devtools-inline/README.md index eecd3f99eba0f..c523ed3107ec7 100644 --- a/packages/react-devtools-inline/README.md +++ b/packages/react-devtools-inline/README.md @@ -153,6 +153,40 @@ iframe.onload = () => { }; ``` +### Advanced integration with custom "wall" + +Below is an example of an advanced integration with a website like [Replay.io](https://replay.io/). + +```js +import { + createBridge, + createStore, + initialize as createDevTools, +} from "react-devtools-inline/frontend"; + +// Custom Wall implementation enables serializing data +// using an API other than window.postMessage() +// For example... +const wall = { + emit() {}, + listen(listener) { + wall._listener = listener; + }, + async send(event, payload) { + const response = await fetch(...).json(); + wall._listener(response); + }, +}; + +// Create a Bridge and Store that use the custom Wall. +const bridge = createBridge(target, wall); +const store = createStore(bridge); +const DevTools = createDevTools(target, { bridge, store }); + +// Render DevTools with it. +; +``` + ## Local development You can also build and test this package from source. diff --git a/packages/react-devtools-inline/package.json b/packages/react-devtools-inline/package.json index a7a4525ccbca2..334c65e51eac1 100644 --- a/packages/react-devtools-inline/package.json +++ b/packages/react-devtools-inline/package.json @@ -1,6 +1,6 @@ { "name": "react-devtools-inline", - "version": "4.11.1", + "version": "4.12.0", "description": "Embed react-devtools within a website", "license": "MIT", "main": "./dist/backend.js", diff --git a/packages/react-devtools-inline/src/frontend.js b/packages/react-devtools-inline/src/frontend.js index 3972f1789ab74..ebd57022e6922 100644 --- a/packages/react-devtools-inline/src/frontend.js +++ b/packages/react-devtools-inline/src/frontend.js @@ -16,11 +16,47 @@ import { MESSAGE_TYPE_SAVED_PREFERENCES, } from './constants'; +import type {Wall} from 'react-devtools-shared/src/types'; import type {FrontendBridge} from 'react-devtools-shared/src/bridge'; import type {Props} from 'react-devtools-shared/src/devtools/views/DevTools'; +export function createStore(bridge: FrontendBridge): Store { + return new Store(bridge, {supportsTraceUpdates: true}); +} + +export function createBridge( + contentWindow: window, + wall?: Wall, +): FrontendBridge { + if (wall == null) { + wall = { + listen(fn) { + const onMessage = ({data}) => { + fn(data); + }; + window.addEventListener('message', onMessage); + return () => { + window.removeEventListener('message', onMessage); + }; + }, + send(event: string, payload: any, transferable?: Array) { + contentWindow.postMessage({event, payload}, '*', transferable); + }, + }; + } + + return (new Bridge(wall): FrontendBridge); +} + export function initialize( contentWindow: window, + { + bridge, + store, + }: {| + bridge?: FrontendBridge, + store?: Store, + |} = {}, ): React.AbstractComponent { const onGetSavedPreferencesMessage = ({data, source}) => { if (source === 'react-devtools-content-script') { @@ -54,22 +90,13 @@ export function initialize( window.addEventListener('message', onGetSavedPreferencesMessage); - const bridge: FrontendBridge = new Bridge({ - listen(fn) { - const onMessage = ({data}) => { - fn(data); - }; - window.addEventListener('message', onMessage); - return () => { - window.removeEventListener('message', onMessage); - }; - }, - send(event: string, payload: any, transferable?: Array) { - contentWindow.postMessage({event, payload}, '*', transferable); - }, - }); + if (bridge == null) { + bridge = createBridge(); + } - const store: Store = new Store(bridge, {supportsTraceUpdates: true}); + if (store == null) { + store = createStore(bridge); + } const ForwardRef = forwardRef((props, ref) => ( diff --git a/packages/react-devtools/CHANGELOG.md b/packages/react-devtools/CHANGELOG.md index 1e9df0db7c0dc..3d83a269dce29 100644 --- a/packages/react-devtools/CHANGELOG.md +++ b/packages/react-devtools/CHANGELOG.md @@ -9,9 +9,14 @@ +## 4.12.0 (April 12, 2021) +Although this release is being made for all NPM packages, only the `react-devtools-inline` package contains changes. +#### Feature +* Added `createBridge` and `createStore` exports to the `react-devtools-inline/frontend` entrypoint to support advanced use cases ([bvaughn](https://github.com/bvaughn) in [#21032](https://github.com/facebook/react/pull/21032)) + ## 4.11.1 (April 11, 2021) #### Bugfix -* Fixed broken import in `react-devtools-inline` for feature flags file ([bvaughn](https://github.com/bvaughn) in [#21235](https://github.com/facebook/react/issues/21235)) +* Fixed broken import in `react-devtools-inline` for feature flags file ([bvaughn](https://github.com/bvaughn) in [#21237](https://github.com/facebook/react/pull/21237)) ## 4.11.0 (April 9, 2021) #### Bugfix diff --git a/packages/react-devtools/package.json b/packages/react-devtools/package.json index 15e71cf7c38cc..593850e753de4 100644 --- a/packages/react-devtools/package.json +++ b/packages/react-devtools/package.json @@ -1,6 +1,6 @@ { "name": "react-devtools", - "version": "4.11.0", + "version": "4.12.0", "description": "Use react-devtools outside of the browser", "license": "MIT", "repository": { @@ -27,7 +27,7 @@ "electron": "^11.1.0", "ip": "^1.1.4", "minimist": "^1.2.3", - "react-devtools-core": "4.11.0", + "react-devtools-core": "4.12.0", "update-notifier": "^2.1.0" } }