Files
supabase/apps/studio/components/interfaces/Realtime/Inspector/RealtimeMessageColumnRenderer.tsx
Eduardo GurgelandAli Waseem 1984de70f1 feat(studio): add support to display realtime binary payloads (#46408)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

Add support to displaying binary payloads while displaying realtime
messages

<img width="2073" height="694"
alt="Realtime_Inspector___Realtime___29_APR___eduardo_gurgel_supabase_io_s_Org___Supabase"
src="https://github.com/user-attachments/assets/fcb5c3d2-f880-484b-97a9-b0ca3b939a3f"
/>

JSON payloads are untouched:

<img width="1744" height="625"
alt="Realtime_Inspector___Realtime___29_APR___eduardo_gurgel_supabase_io_s_Org___Supabase"
src="https://github.com/user-attachments/assets/8227d0af-21ee-4444-b8ca-4ebeeda11f75"
/>


How to test on staging:

```
   select
  realtime.send(
    '\x48656C6C6F2066726F6D205265616C74696D65'::bytea, -- Binary Payload
    'event', -- Event name
    'main', -- Topic
    false -- Public / Private flag
  );
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Binary payloads in real-time message inspection show compact
placeholders with byte counts instead of raw binary.
* Added an inline hexdump viewer to inspect binary payload contents with
offsets, grouped hex bytes, and ASCII gutter.
* Message list and details view now use the placeholder/hexdump behavior
for payload rendering.

* **Tests**
* Added comprehensive tests for binary detection, hexdump formatting,
and placeholder substitution.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46408?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Ali Waseem <waseema393@gmail.com>
2026-06-02 13:03:13 +12:00

45 lines
1.5 KiB
TypeScript

import { AlertTriangle } from 'lucide-react'
import { Column } from 'react-data-grid'
import { cn, IconBroadcast, IconDatabaseChanges, IconPresence } from 'ui'
import type { LogData, PreviewLogData } from './Messages.types'
import { RowLayout, withBinaryPayloadPlaceholder } from './MessagesFormatters'
import { isErrorLog } from './MessagesTable'
const ICONS = {
PRESENCE: <IconPresence size="xlarge" />,
BROADCAST: <IconBroadcast size="xlarge" />,
POSTGRES: <IconDatabaseChanges size="xlarge" />,
SYSTEM: <AlertTriangle size="20" strokeWidth={1} />,
}
export const ColumnRenderer: Column<LogData, unknown>[] = [
{
name: 'timestamp-with-truncated-text',
key: 'main-column',
renderHeaderCell: () => null,
renderCell: (data: { row: PreviewLogData }) => {
const type = data.row.message as keyof typeof ICONS
return (
<RowLayout>
<div
className={cn(
'flex justify-center items-center min-w-[24px]',
isErrorLog(data.row) ? 'text-warning' : 'text-green-900'
)}
>
{ICONS[type]}
</div>
<span className={cn('font-mono', isErrorLog(data.row) ? 'text-warning!' : '')}>
{new Date(data.row.timestamp).toISOString()}
</span>
<span className={cn('truncate font-mono', isErrorLog(data.row) ? 'text-warning!' : '')}>
{JSON.stringify(withBinaryPayloadPlaceholder(data.row.metadata))}
</span>
</RowLayout>
)
},
},
]