@@ -5,7 +5,16 @@ import classNames from 'classnames';
55import './App.scss' ;
66import { ObjectInspector } from 'react-inspector' ;
77import { Frame } from 'rsocket-types' ;
8- import { deserializeFrame , deserializeFrameWithLength , FLAGS , FRAME_TYPES , printFrame , Utf8Encoders } from "rsocket-core" ;
8+ import {
9+ BufferEncoders ,
10+ deserializeFrame ,
11+ deserializeFrameWithLength ,
12+ FLAGS ,
13+ FRAME_TYPES ,
14+ printFrame ,
15+ Utf8Encoders
16+ } from "rsocket-core" ;
17+ import { Encoders } from "rsocket-core/RSocketEncoding" ;
918
1019function getRSocketType ( type ) {
1120 for ( const [ name , code ] of Object . entries ( FRAME_TYPES ) ) {
@@ -59,8 +68,8 @@ function base64ToArrayBuffer(base64: string) {
5968 return bytes ;
6069}
6170
62- const FrameEntry = ( { frame, selected, onClick} : { frame : WsFrame , selected : boolean , onClick : MouseEventHandler } ) => {
63- const rsocketFrame = tryDecodeFrame ( frame . payload )
71+ const FrameEntry = ( { frame, selected, onClick} : { frame : WsFrame , selected : boolean , onClick : MouseEventHandler } ) => {
72+ const rsocketFrame = tryDeserializeFrame ( frame . payload )
6473 const frameName = rsocketFrame
6574 ? < span className = "name" > { shortFrame ( rsocketFrame ) } </ span >
6675 : < span className = "name" > { frame . text != null ? "Text Frame" : "Binary Frame" } </ span >
@@ -120,10 +129,14 @@ class RSocketFrame extends React.Component<RSocketFrameProps, any> {
120129 jsonMeta = undefined ;
121130 }
122131 const dataField = jsonData
123- ? < div > < hr /> Data< br /> < ObjectInspector data = { jsonData } /> </ div >
132+ ? < div >
133+ < hr />
134+ Data< br /> < ObjectInspector data = { jsonData } /> </ div >
124135 : < div />
125136 const jsonField = jsonMeta
126- ? < div > < hr /> Metadata< br /> < ObjectInspector data = { jsonMeta } /> </ div >
137+ ? < div >
138+ < hr />
139+ Metadata< br /> < ObjectInspector data = { jsonMeta } /> </ div >
127140 : < div />
128141 return (
129142 < div >
@@ -180,19 +193,47 @@ const TextViewer = ({data}) => (
180193 </ div >
181194) ;
182195
183- function tryDecodeFrame ( data : string ) : Frame | undefined {
196+ // Could
197+ let cachedEncoders : Encoders < any > = Utf8Encoders
198+ let cachedLengthPrefixedFrames : boolean = false ;
199+
200+ function tryDeserializeFrameWith ( data : string , buffer : Buffer , lengthPrefixedFrames , encoders : Encoders < any > ) {
184201 try {
185- let lengthPrefixedFrames = false ;
186- const buffer = base64ToArrayBuffer ( data ) ;
187202 return lengthPrefixedFrames
188- ? deserializeFrameWithLength ( buffer , Utf8Encoders )
189- : deserializeFrame ( buffer , Utf8Encoders ) ;
203+ ? deserializeFrameWithLength ( buffer , encoders )
204+ : deserializeFrame ( buffer , encoders ) ;
190205 } catch ( e ) {
191206 // console.error("failed to decode frame", e)
192207 return undefined ;
193208 }
194209}
195210
211+ function tryDeserializeFrame ( data : string ) : Frame | undefined {
212+ const buffer = base64ToArrayBuffer ( data )
213+ let frame : Frame | undefined ;
214+ // fast path
215+ frame = tryDeserializeFrameWith ( data , buffer , cachedLengthPrefixedFrames , cachedEncoders ) ;
216+ if ( frame ) {
217+ return frame ;
218+ }
219+ // slow path
220+ let attempts : [ Encoders < any > , boolean ] [ ] = [
221+ [ Utf8Encoders , false ] ,
222+ [ Utf8Encoders , true ] ,
223+ [ BufferEncoders , false ] ,
224+ [ BufferEncoders , true ] ,
225+ ] ;
226+ for ( let [ encoders , lengthPrefixedFrames ] of attempts ) {
227+ frame = tryDeserializeFrameWith ( data , buffer , lengthPrefixedFrames , encoders ) ;
228+ if ( frame ) {
229+ cachedEncoders = encoders ;
230+ cachedLengthPrefixedFrames = lengthPrefixedFrames ;
231+ return frame ;
232+ }
233+ }
234+ return undefined ;
235+ }
236+
196237const RSocketViewer = ( { frame, data} ) => {
197238 try {
198239 return (
@@ -219,10 +260,12 @@ class FrameView extends React.Component<{ wsFrame: WsFrame }, { panel?: string }
219260
220261 render ( ) {
221262 const { wsFrame} = this . props ;
222- const rsocketFrame = tryDecodeFrame ( wsFrame . payload )
263+ const rsocketFrame = tryDeserializeFrame ( wsFrame . payload )
223264 const panel = rsocketFrame
224265 ? < RSocketViewer frame = { rsocketFrame } data = { wsFrame . payload } />
225- : < TextViewer data = { wsFrame . text } /> ;
266+ : wsFrame . text
267+ ? < TextViewer data = { wsFrame . text } />
268+ : < TextViewer data = { wsFrame . binary } /> ;
226269 return (
227270 < div className = "FrameView" >
228271 { panel }
0 commit comments