react-logviewer icon indicating copy to clipboard operation
react-logviewer copied to clipboard

if it possible to extract data provider out of component?

Open timzaak opened this issue 1 year ago • 5 comments

I use MQTT to get log line by line, it's not websocket nor http.

it would be nice if the api look like:


interface LazyLogController {
  newLine(lines:[]string) => void
  end() => void
  start() => void
  error() => void
}

const ref = userRef<LazyLogController>()

useEffect(() => {
   ref.current?.start()
   ref.current?.newLines(['test1','test2'])
   // ...
}, [])

<LazyLog ref={ref} follow>

timzaak avatar May 28 '24 05:05 timzaak

PR's are welcome @timzaak. I forked this library because it had gone dead and had a bunch of bugs.

melloware avatar May 28 '24 11:05 melloware

It looks like MQTT supports websocket?

https://www.hivemq.com/blog/mqtt-essentials-special-mqtt-over-websockets/

melloware avatar May 31 '24 01:05 melloware

Yes, but mqtt.js API has different API。

timzaak avatar May 31 '24 03:05 timzaak

@timzaak are you interested in creating a PR for this feature?

melloware avatar May 31 '24 12:05 melloware

@timzaak are you interested in creating a PR for this feature?

ihave tried,but this would break api compatible(move state manager outside of component,user solve fetch data themselves,provide method to render lines)

timzaak avatar Jun 07 '24 12:06 timzaak

@timzaak see the PR what about using EventSource instead of WebSockets?

melloware avatar Oct 31 '24 17:10 melloware

I need this too. Currently I maintain an EventSource built by third-party library (because the standard EventSource does not support custom Authorization header), so have to use the text prop to pass log content to <LazyLog />. But this affects performance:

  • Log data is maintained twice: I have lines stored in state, and I joins them into a string passed to text prop, and <LazyLog /> parses them again and stored a second copy of these identical lines. So memory usage doubles.
  • When new log lines get appended, <LazyLog /> is re-rendered, the UI would flash, because all log lines are processed again from the beginning, and follow handling has to start over.

Ideally there would be a pattern like this:

  • My component holds a ref to the <LazyLog /> child: const logViewer = useRef<LazyLog>();
  • Each time a new log line is received, I just call logViewer.current?.appendLine(line). My component does not need to store this new line, and <LazyLog /> only needs to render the new line.

JokerQyou avatar Dec 05 '24 08:12 JokerQyou

@JokerQyou you can't use the new event source code? https://github.com/melloware/react-logviewer/pull/51 ?

melloware avatar Dec 05 '24 12:12 melloware

No. EventSource in browser does not support customizing headers, that's a known limitation with both the current standard and implementations, see https://github.com/whatwg/html/issues/2177. Some libraries like SSE.js and fetch-event-source use XHR or fetch with keep-alive connections to simulate the native EventSource, but I don't think react-logviewer would support them.

JokerQyou avatar Dec 05 '24 12:12 JokerQyou

Understood. Well a PR is welcome if you can get it working but extracting some of this stuff out is not easy when I looked. I think even adding an logViewer.current?.appendLine(line) could be doable but will still trigger a re-render i think.

melloware avatar Dec 05 '24 13:12 melloware

I worked around by hacking with logViewer.current?.setState(...) since it's a class-based component 😂 . Should it be a function component it would not be possible. I'll look into adding appendLine support tomorrow. Hopefully it can be achieved.

JokerQyou avatar Dec 05 '24 13:12 JokerQyou

That would be awesome! Looking forward to it. Yeah this original component was written back in 2018 before Function Compoents and so I have tried to touch as little as possible when taking it over after the original project was abandoned!

Thanks in advance for the PR!

melloware avatar Dec 05 '24 13:12 melloware

See #72 .

JokerQyou avatar Dec 06 '24 05:12 JokerQyou