UNPKG

@redwoodjs/sdk

Version:

A full-stack webapp toolkit designed for TypeScript, Vite, and React Server Components

78 lines (77 loc) 2.85 kB
"use client"; import { useRef, useCallback } from "react"; export function useEventStream({ onEvent, onError = console.error, }) { const onEventRef = useRef(onEvent); const onErrorRef = useRef(onError); onEventRef.current = onEvent; onErrorRef.current = onError; const createStream = useCallback(() => { const decoder = new TextDecoder(); let textBuffer = ""; const decodingStream = new TransformStream({ transform(chunk, controller) { textBuffer += decoder.decode(chunk, { stream: true }); controller.enqueue(textBuffer); textBuffer = ""; }, flush(controller) { textBuffer += decoder.decode(undefined, { stream: false }); if (textBuffer) { controller.enqueue(textBuffer); } }, }); const lineSplitter = new TransformStream({ transform(chunk, controller) { let buffer = chunk; let index; while ((index = buffer.indexOf("\n")) !== -1) { const line = buffer.slice(0, index).trim(); buffer = buffer.slice(index + 1); if (line) controller.enqueue(line); } // carry remaining fragment forward if (buffer.trim()) controller.enqueue(buffer.trim()); }, }); const { readable, writable } = new TransformStream(); readable.pipeTo(createLoggingStream("readable")); //readable // .pipeThrough(decodingStream) // .pipeThrough(lineSplitter) // .pipeThrough(new EventSourceParserStream()) // .pipeTo( // new WritableStream({ // write(event) { // onEventRef.current(event); // }, // abort(reason) { // onErrorRef.current(reason); // }, // }), // ) // .catch(onErrorRef.current); return writable; }, []); return createStream; } export function createLoggingStream(label = "chunk") { return new WritableStream({ write(chunk) { const hex = [...chunk] .map((b) => b.toString(16).padStart(2, "0")) .join(" "); const decoder = new TextDecoder(); const text = decoder.decode(chunk, { stream: true }); console.log(`\n🧱 [${label}] Received ${chunk.length} bytes`); console.log(`HEX: ${hex}`); console.log(`TEXT: "${text}"`); console.log(`LINES:`, text .split("\n") .map((l, i) => `[${i}] "${l}"`) .join("\n ")); }, }); }