Split messages sent to devpanel

This commit is contained in:
Nathan Bierema 2024-08-04 12:41:15 -04:00
parent 6cf528b4a0
commit 16576a566d
3 changed files with 93 additions and 8 deletions

View File

@ -229,21 +229,72 @@ type MonitorAction<S, A extends Action<string>> =
| UpdateStateAction<S, A> | UpdateStateAction<S, A>
| SetPersistAction; | SetPersistAction;
// Chrome message limit is 64 MB, but we're using 32 MB to include other object's parts
const maxChromeMsgSize = 32 * 1024 * 1024;
function toMonitors<S, A extends Action<string>>( function toMonitors<S, A extends Action<string>>(
action: MonitorAction<S, A>, action: MonitorAction<S, A>,
tabId?: string | number, tabId?: string | number,
verbose?: boolean, verbose?: boolean,
) { ) {
Object.keys(connections.monitor).forEach((id) => { for (const monitorPort of Object.values(connections.monitor)) {
connections.monitor[id].postMessage( monitorPort.postMessage(
verbose || action.type === 'ERROR' || action.type === SET_PERSIST verbose || action.type === 'ERROR' || action.type === SET_PERSIST
? action ? action
: { type: UPDATE_STATE }, : { type: UPDATE_STATE },
); );
}
for (const panelPort of Object.values(connections.panel)) {
try {
panelPort.postMessage(action);
} catch (err) {
if (
action.type !== UPDATE_STATE ||
err == null ||
(err as Error).message !==
'Message length exceeded maximum allowed length.'
) {
throw err;
}
const splitMessageStart = { split: 'start' };
const toSplit: [string, string][] = [];
let size = 0;
for (const [key, value] of Object.entries(
action.request as unknown as Record<string, unknown>,
)) {
if (typeof value === 'string') {
size += value.length;
if (size > maxChromeMsgSize) {
toSplit.push([key, value]);
continue;
}
}
splitMessageStart[key] = value;
}
panelPort.postMessage({ ...action, request: splitMessageStart });
for (let i = 0; i < toSplit.length; i++) {
for (let j = 0; j < toSplit[i][1].length; j += maxChromeMsgSize) {
panelPort.postMessage({
...action,
request: {
split: 'chunk',
chunk: [
toSplit[i][0],
toSplit[i][1].substring(j, j + maxChromeMsgSize),
],
},
}); });
Object.keys(connections.panel).forEach((id) => { }
connections.panel[id].postMessage(action); }
});
panelPort.postMessage({ ...action, request: { split: 'end' } });
}
}
} }
interface ImportMessage { interface ImportMessage {

View File

@ -16,6 +16,7 @@ import {
DispatchAction as AppDispatchAction, DispatchAction as AppDispatchAction,
} from '@redux-devtools/app'; } from '@redux-devtools/app';
import { LiftedState } from '@redux-devtools/instrument'; import { LiftedState } from '@redux-devtools/instrument';
const source = '@devtools-extension'; const source = '@devtools-extension';
const pageSource = '@devtools-page'; const pageSource = '@devtools-page';
// Chrome message limit is 64 MB, but we're using 32 MB to include other object's parts // Chrome message limit is 64 MB, but we're using 32 MB to include other object's parts

View File

@ -3,7 +3,11 @@ import React, { CSSProperties, ReactNode } from 'react';
import { createRoot, Root } from 'react-dom/client'; import { createRoot, Root } from 'react-dom/client';
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import { Persistor } from 'redux-persist'; import { Persistor } from 'redux-persist';
import { REMOVE_INSTANCE, StoreAction } from '@redux-devtools/app'; import {
REMOVE_INSTANCE,
StoreAction,
UPDATE_STATE,
} from '@redux-devtools/app';
import App from '../app/App'; import App from '../app/App';
import configureStore from './store/panelStore'; import configureStore from './store/panelStore';
@ -90,6 +94,8 @@ function renderNA() {
}, 3500); }, 3500);
} }
let splitMessage;
function init(id: number) { function init(id: number) {
renderNA(); renderNA();
bgConnection = chrome.runtime.connect({ bgConnection = chrome.runtime.connect({
@ -102,8 +108,35 @@ function init(id: number) {
else store!.dispatch({ type: REMOVE_INSTANCE, id: message.id }); else store!.dispatch({ type: REMOVE_INSTANCE, id: message.id });
} else { } else {
if (!rendered) renderDevTools(); if (!rendered) renderDevTools();
if (message.type === UPDATE_STATE && message.request.split) {
if (message.request.split === 'start') {
splitMessage = message.request;
return;
}
if (message.request.split === 'chunk') {
if (splitMessage[message.request.chunk[0]]) {
splitMessage[message.request.chunk[0]] +=
message.request.chunk[1];
} else {
splitMessage[message.request.chunk[0]] = message.request.chunk[1];
}
return;
}
if (message.request.split === 'end') {
store!.dispatch({ ...message, request: splitMessage });
return;
}
throw new Error(
`Unable to process split message with type: ${message.request.split}`,
);
} else {
store!.dispatch(message); store!.dispatch(message);
} }
}
}, },
); );
} }