@redwoodjs/sdk
Version:
A full-stack webapp toolkit designed for TypeScript, Vite, and React Server Components
78 lines (77 loc) • 2.85 kB
JavaScript
"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 "));
},
});
}