Make flipper messages generally available, remove self inspection infra structure
Summary: Changelog: Flipper message debugging moved from a separate device to the console tab This makes message debugging easier accessible, and in production (recently requested at GH). Also it clears up a lot of infra that was created just to make flipper a self recursive inspection device + a separate plugin. While fun, a hardcoded setup is just a bit more simpler (no exception rules and better static verification) Reviewed By: nikoant Differential Revision: D29487811 fbshipit-source-id: b412adc3ef5bd831001333443b432b6c0f934a5e
This commit is contained in:
committed by
Facebook GitHub Bot
parent
8da7495a1a
commit
328ba9513c
@@ -1,161 +0,0 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import {TestUtils} from 'flipper-plugin';
|
||||
|
||||
import * as Plugin from '../';
|
||||
import {MessageRow} from '../';
|
||||
|
||||
const fixRowTimestamps = (r: MessageRow): MessageRow => ({
|
||||
...r,
|
||||
time: new Date(Date.UTC(0, 0, 0, 0, 0, 0)),
|
||||
});
|
||||
|
||||
test('It can store rows', () => {
|
||||
const {instance, ...plugin} = TestUtils.startPlugin(Plugin);
|
||||
|
||||
expect(instance.rows.records()).toEqual([]);
|
||||
expect(instance.highlightedRow.get()).toBeUndefined();
|
||||
|
||||
plugin.sendEvent('newMessage', {
|
||||
app: 'Flipper',
|
||||
direction: 'toFlipper',
|
||||
});
|
||||
|
||||
plugin.sendEvent('newMessage', {
|
||||
app: 'FB4A',
|
||||
direction: 'toClient',
|
||||
device: 'Android Phone',
|
||||
payload: {hello: 'world'},
|
||||
});
|
||||
|
||||
expect(instance.rows.records().map(fixRowTimestamps)).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
"app": "Flipper",
|
||||
"direction": "toFlipper",
|
||||
"time": 1899-12-31T00:00:00.000Z,
|
||||
},
|
||||
Object {
|
||||
"app": "FB4A",
|
||||
"device": "Android Phone",
|
||||
"direction": "toClient",
|
||||
"payload": Object {
|
||||
"hello": "world",
|
||||
},
|
||||
"time": 1899-12-31T00:00:00.000Z,
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
test('It can clear', () => {
|
||||
const {instance, ...plugin} = TestUtils.startPlugin(Plugin);
|
||||
|
||||
expect(instance.rows.records()).toEqual([]);
|
||||
expect(instance.highlightedRow.get()).toBeUndefined();
|
||||
|
||||
plugin.sendEvent('newMessage', {
|
||||
app: 'Flipper',
|
||||
direction: 'toFlipper',
|
||||
});
|
||||
|
||||
instance.clear();
|
||||
|
||||
const newRows = instance.rows.records().map(fixRowTimestamps);
|
||||
expect(newRows).toEqual([]);
|
||||
});
|
||||
|
||||
test('It can highlight a row', () => {
|
||||
const {instance, ...plugin} = TestUtils.startPlugin(Plugin);
|
||||
|
||||
plugin.sendEvent('newMessage', {
|
||||
app: 'Flipper',
|
||||
direction: 'toFlipper',
|
||||
});
|
||||
|
||||
instance.setHighlightedRow(instance.rows.records()[0]);
|
||||
|
||||
expect(instance.rows.records()).toHaveLength(1);
|
||||
expect(instance.highlightedRow.get()?.app).toEqual('Flipper');
|
||||
});
|
||||
|
||||
test('It can render empty', async () => {
|
||||
const {renderer} = TestUtils.renderPlugin(Plugin);
|
||||
|
||||
// Default message without any highlighted rows.
|
||||
expect(
|
||||
await renderer.findByText('Select a message to view details'),
|
||||
).not.toBeNull();
|
||||
});
|
||||
|
||||
test('It can render rows', async () => {
|
||||
const {renderer, ...plugin} = TestUtils.renderPlugin(Plugin);
|
||||
|
||||
plugin.sendEvent('newMessage', {
|
||||
time: new Date(0, 0, 0, 0, 0, 0),
|
||||
app: 'Flipper',
|
||||
direction: 'toFlipper',
|
||||
});
|
||||
|
||||
plugin.sendEvent('newMessage', {
|
||||
time: new Date(0, 0, 0, 0, 0, 0),
|
||||
app: 'FB4A',
|
||||
direction: 'toClient',
|
||||
device: 'Android Phone',
|
||||
flipperInternalMethod: 'unique-string',
|
||||
payload: {hello: 'world'},
|
||||
});
|
||||
|
||||
expect((await renderer.findByText('unique-string')).parentElement)
|
||||
.toMatchInlineSnapshot(`
|
||||
<div
|
||||
class="ant-dropdown-trigger css-1k3kr6b-TableBodyRowContainer e1luu51r1"
|
||||
>
|
||||
<div
|
||||
class="css-1vr131n-TableBodyColumnContainer e1luu51r0"
|
||||
width="14%"
|
||||
>
|
||||
00:00:00.000
|
||||
</div>
|
||||
<div
|
||||
class="css-1vr131n-TableBodyColumnContainer e1luu51r0"
|
||||
width="14%"
|
||||
>
|
||||
Android Phone
|
||||
</div>
|
||||
<div
|
||||
class="css-1vr131n-TableBodyColumnContainer e1luu51r0"
|
||||
width="14%"
|
||||
>
|
||||
FB4A
|
||||
</div>
|
||||
<div
|
||||
class="css-1vr131n-TableBodyColumnContainer e1luu51r0"
|
||||
width="14%"
|
||||
>
|
||||
unique-string
|
||||
</div>
|
||||
<div
|
||||
class="css-1vr131n-TableBodyColumnContainer e1luu51r0"
|
||||
width="14%"
|
||||
/>
|
||||
<div
|
||||
class="css-1vr131n-TableBodyColumnContainer e1luu51r0"
|
||||
width="14%"
|
||||
/>
|
||||
<div
|
||||
class="css-1vr131n-TableBodyColumnContainer e1luu51r0"
|
||||
width="14%"
|
||||
>
|
||||
toClient
|
||||
</div>
|
||||
</div>
|
||||
`);
|
||||
});
|
||||
@@ -1,163 +0,0 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import {
|
||||
DataInspector,
|
||||
DataTable,
|
||||
DataTableColumn,
|
||||
Layout,
|
||||
createState,
|
||||
PluginClient,
|
||||
usePlugin,
|
||||
useValue,
|
||||
createDataSource,
|
||||
DetailSidebar,
|
||||
Panel,
|
||||
theme,
|
||||
styled,
|
||||
} from 'flipper-plugin';
|
||||
import {Button} from 'antd';
|
||||
import {DeleteOutlined} from '@ant-design/icons';
|
||||
import React from 'react';
|
||||
|
||||
export interface MessageInfo {
|
||||
time?: Date;
|
||||
device?: string;
|
||||
app: string;
|
||||
flipperInternalMethod?: string;
|
||||
plugin?: string;
|
||||
pluginMethod?: string;
|
||||
payload?: any;
|
||||
direction: 'toClient' | 'toFlipper';
|
||||
}
|
||||
|
||||
export interface MessageRow extends MessageInfo {
|
||||
time: Date;
|
||||
}
|
||||
|
||||
const Placeholder = styled(Layout.Container)({
|
||||
center: true,
|
||||
color: theme.textColorPlaceholder,
|
||||
fontSize: 18,
|
||||
});
|
||||
|
||||
function createRow(message: MessageInfo): MessageRow {
|
||||
return {
|
||||
...message,
|
||||
time: message.time == null ? new Date() : message.time,
|
||||
};
|
||||
}
|
||||
|
||||
type Events = {
|
||||
newMessage: MessageInfo;
|
||||
};
|
||||
|
||||
const COLUMN_CONFIG: DataTableColumn<MessageRow>[] = [
|
||||
{
|
||||
key: 'time',
|
||||
title: 'Time',
|
||||
},
|
||||
{
|
||||
key: 'device',
|
||||
title: 'Device',
|
||||
},
|
||||
{
|
||||
key: 'app',
|
||||
title: 'App',
|
||||
},
|
||||
{
|
||||
key: 'flipperInternalMethod',
|
||||
title: 'Flipper Internal Method',
|
||||
},
|
||||
{
|
||||
key: 'plugin',
|
||||
title: 'Plugin',
|
||||
},
|
||||
{
|
||||
key: 'pluginMethod',
|
||||
title: 'Method',
|
||||
},
|
||||
{
|
||||
key: 'direction',
|
||||
title: 'Direction',
|
||||
},
|
||||
];
|
||||
|
||||
export function plugin(client: PluginClient<Events, {}>) {
|
||||
const highlightedRow = createState<MessageRow>();
|
||||
const rows = createDataSource<MessageRow>([], {
|
||||
limit: 1024 * 10,
|
||||
persist: 'messages',
|
||||
});
|
||||
|
||||
const setHighlightedRow = (record: MessageRow) => {
|
||||
highlightedRow.set(record);
|
||||
};
|
||||
|
||||
const clear = () => {
|
||||
highlightedRow.set(undefined);
|
||||
rows.clear();
|
||||
};
|
||||
|
||||
client.onMessage('newMessage', (payload) => {
|
||||
rows.append(createRow(payload));
|
||||
});
|
||||
|
||||
return {
|
||||
rows,
|
||||
highlightedRow,
|
||||
setHighlightedRow,
|
||||
clear,
|
||||
};
|
||||
}
|
||||
|
||||
function Sidebar() {
|
||||
const instance = usePlugin(plugin);
|
||||
const message = useValue(instance.highlightedRow);
|
||||
|
||||
const renderExtra = (extra: any) => (
|
||||
<Panel title={'Payload'} collapsible={false}>
|
||||
<DataInspector data={extra} expandRoot={false} />
|
||||
</Panel>
|
||||
);
|
||||
|
||||
return (
|
||||
<DetailSidebar>
|
||||
{message != null ? (
|
||||
renderExtra(message.payload)
|
||||
) : (
|
||||
<Placeholder grow pad="large">
|
||||
Select a message to view details
|
||||
</Placeholder>
|
||||
)}
|
||||
</DetailSidebar>
|
||||
);
|
||||
}
|
||||
|
||||
export function Component() {
|
||||
const instance = usePlugin(plugin);
|
||||
|
||||
const clearTableButton = (
|
||||
<Button title="Clear logs" onClick={instance.clear}>
|
||||
<DeleteOutlined />
|
||||
</Button>
|
||||
);
|
||||
|
||||
return (
|
||||
<Layout.Container grow>
|
||||
<DataTable<MessageRow>
|
||||
dataSource={instance.rows}
|
||||
columns={COLUMN_CONFIG}
|
||||
onSelect={instance.setHighlightedRow}
|
||||
extraActions={clearTableButton}
|
||||
/>
|
||||
<Sidebar />
|
||||
</Layout.Container>
|
||||
);
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
{
|
||||
"$schema": "https://fbflipper.com/schemas/plugin-package/v2.json",
|
||||
"name": "flipper-plugin-flipper-messages",
|
||||
"id": "flipper-messages",
|
||||
"title": "Flipper Messages",
|
||||
"icon": "bird",
|
||||
"version": "0.0.0",
|
||||
"description": "Flipper self inspection: Messages to and from client",
|
||||
"main": "dist/bundle.js",
|
||||
"flipperBundlerEntry": "index.tsx",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"flipper-plugin"
|
||||
],
|
||||
"bugs": {
|
||||
"url": "https://github.com/facebook/flipper/issues"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "flipper-pkg lint",
|
||||
"build": "flipper-pkg bundle",
|
||||
"watch": "flipper-pkg bundle --watch",
|
||||
"prepack": "flipper-pkg lint && flipper-pkg bundle --production"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"flipper": "*",
|
||||
"flipper-pkg": "*",
|
||||
"flipper-plugin": "*"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user