@samitouri / QOS-React-2 / commits / fdfadef928

Refactored bridge to support transferrables (e.g. typed array buffers) and added transferable param to postMessage for op codes

Brian Vaughn committed Jan 29, 2019 at 13:17 UTC fdfadef9289f2c69e02bbfbcc78db4dca11ce45a
10 files changed +30 -41
shells/browser/chrome/test.js
+1 -1
@@ -3,7 +3,7 @@
3 const chromeLaunch = require('chrome-launch'); // eslint-disable-line import/no-extraneous-dependencies
4 const { resolve } = require('path');
5
6 -const EXTENSION_PATH = resolve('shells/chrome/build/unpacked');
6 +const EXTENSION_PATH = resolve('shells/browser/chrome/build/unpacked');
7 const START_URL = 'https://facebook.github.io/react/';
8
9 chromeLaunch(START_URL, {
shells/browser/firefox/test.js
+1 -1
@@ -4,7 +4,7 @@ const { exec } = require('child-process-promise');
4 const { Finder } = require('firefox-profile');
5 const { resolve } = require('path');
6
7 -const EXTENSION_PATH = resolve('shells/firefox/build/unpacked');
7 +const EXTENSION_PATH = resolve('shells/browser/firefox/build/unpacked');
8 const START_URL = 'https://facebook.github.io/react/';
9
10 const main = async () => {
shells/browser/shared/src/backend.js
+4 -3
@@ -42,13 +42,14 @@ function setup(hook) {
42 listeners.push(listener);
43 window.addEventListener('message', listener);
44 },
45 - send(data) {
45 + send(event: string, payload: any, transferable?: Array<any>) {
46 window.postMessage(
47 {
48 source: 'react-devtools-bridge',
49 - payload: data,
49 + payload: { event, payload },
50 },
51 - '*'
51 + '*',
52 + transferable
53 );
54 },
55 });
shells/browser/shared/src/panel.js
+2 -2
@@ -50,11 +50,11 @@ inject(chrome.runtime.getURL('build/backend.js'), () => {
50 listen(fn) {
51 port.onMessage.addListener(message => fn(message));
52 },
53 - send(data) {
53 + send(event: string, payload: any, transferable?: Array<any>) {
54 if (disconnected) {
55 return;
56 }
57 - port.postMessage(data);
57 + port.postMessage({ event, payload }, transferable);
58 },
59 });
60
shells/dev/src/backend.js
+2 -2
@@ -10,8 +10,8 @@ const bridge = new Bridge({
10 fn(event.data);
11 });
12 },
13 - send(data) {
14 - window.parent.postMessage(data, '*');
13 + send(event: string, payload: any, transferable?: Array<any>) {
14 + window.parent.postMessage({ event, payload }, '*', transferable);
15 },
16 });
17
shells/dev/src/devtools.js
+2 -2
@@ -46,8 +46,8 @@ initDevTools({
46 fn(data);
47 });
48 },
49 - send(data) {
50 - contentWindow.postMessage(data, '*');
49 + send(event: string, payload: any, transferable?: Array<any>) {
50 + contentWindow.postMessage({ event, payload }, '*', transferable);
51 },
52 });
53
src/backend/agent.js
+1 -1
@@ -44,7 +44,7 @@ export default class Agent extends EventEmitter {
44
45 onHookOperations = (operations: Uint32Array) => {
46 debug('onHookOperations', operations);
47 - this._bridge.send('operations', operations);
47 + this._bridge.send('operations', operations, [operations.buffer]);
48 };
49
50 onHookRootCommitted = (rootID: string) => {
src/bridge.js
+11 -28
@@ -12,7 +12,7 @@ type Message = {|
12 |};
13
14 export default class Bridge extends EventEmitter {
15 - _messageQueue: Array<Message> = [];
15 + _messageQueue: Array<any> = [];
16 _time: number | null = null;
17 _timeoutID: TimeoutID | null = null;
18
@@ -22,33 +22,20 @@ export default class Bridge extends EventEmitter {
22 super();
23
24 this.wall = wall;
25 - wall.listen(messages => {
26 - if (Array.isArray(messages)) {
27 - messages.forEach(message => this._emit(message));
28 - } else {
29 - this._emit(messages);
30 - }
25 +
26 + wall.listen((message: Message) => {
27 + this._emit(message);
28 });
29 }
30
34 - /**
35 - * Send an event.
36 - *
37 - * @param {String} event
38 - * @param {*} payload
39 - */
40 -
41 - send(event: string, payload: any) {
31 + send(event: string, payload: any, transferable?: Array<any>) {
32 const time = this._time;
33
34 if (time === null) {
45 - this.wall.send([{ event, payload }]);
35 + this.wall.send(event, payload, transferable);
36 this._time = Date.now();
37 } else {
48 - this._messageQueue.push({
49 - event,
50 - payload,
51 - });
38 + this._messageQueue.push(event, payload, transferable);
39
40 const now = Date.now();
41 if (now - time > BATCH_DURATION) {
@@ -59,24 +46,20 @@ export default class Bridge extends EventEmitter {
46 }
47 }
48
62 - /**
63 - * Log a message to the devtools background page.
64 - *
65 - * @param {String} message
66 - */
67 -
49 log(message: string): void {
50 this.send('log', message);
51 }
52
53 _flush() {
73 - if (this._messageQueue.length) {
74 - this.wall.send(this._messageQueue);
54 + while (this._messageQueue.length) {
55 + this.wall.send.apply(this.wall, this._messageQueue.splice(0, 3));
56 }
57 +
58 if (this._timeoutID !== null) {
59 clearTimeout(this._timeoutID);
60 this._timeoutID = null;
61 }
62 +
63 this._messageQueue = [];
64 this._time = null;
65 }
src/devtools/store.js
+5
@@ -102,6 +102,11 @@ export default class Store extends EventEmitter {
102 }
103
104 onBridgeOperations = (operations: Uint32Array) => {
105 + if (!(operations instanceof Uint32Array)) {
106 + // $FlowFixMe TODO HACK Temporary workaround for the fact that Chrome is not transferring the typed array.
107 + operations = Uint32Array.from(Object.values(operations));
108 + }
109 +
110 debug('onBridgeOperations', operations);
111
112 let haveRootsChanged = false;
src/types.js
+1 -1
@@ -8,5 +8,5 @@ export type Hook = any;
8
9 export type Wall = {|
10 listen: (fn: Function) => void,
11 - send: (data: any) => void,
11 + send: (event: string, payload: any, transferable?: Array<any>) => void,
12 |};