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>
| 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>>(
action: MonitorAction<S, A>,
tabId?: string | number,
verbose?: boolean,
) {
Object.keys(connections.monitor).forEach((id) => {
connections.monitor[id].postMessage(
for (const monitorPort of Object.values(connections.monitor)) {
monitorPort.postMessage(
verbose || action.type === 'ERROR' || action.type === SET_PERSIST
? action
: { type: UPDATE_STATE },
);
});
Object.keys(connections.panel).forEach((id) => {
connections.panel[id].postMessage(action);
});
}
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),
],
},
});
}
}
panelPort.postMessage({ ...action, request: { split: 'end' } });
}
}
}
interface ImportMessage {

View File

@ -16,6 +16,7 @@ import {
DispatchAction as AppDispatchAction,
} from '@redux-devtools/app';
import { LiftedState } from '@redux-devtools/instrument';
const source = '@devtools-extension';
const pageSource = '@devtools-page';
// 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 { Provider } from 'react-redux';
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 configureStore from './store/panelStore';
@ -90,6 +94,8 @@ function renderNA() {
}, 3500);
}
let splitMessage;
function init(id: number) {
renderNA();
bgConnection = chrome.runtime.connect({
@ -102,7 +108,34 @@ function init(id: number) {
else store!.dispatch({ type: REMOVE_INSTANCE, id: message.id });
} else {
if (!rendered) renderDevTools();
store!.dispatch(message);
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);
}
}
},
);