UNPKG

@yoyo-org/progressive-json

Version:

Stream and render JSON data as it arrives - perfect for AI responses, large datasets, and real-time updates

46 lines (45 loc) 1.92 kB
import { useState, useSyncExternalStore, useEffect, useCallback } from "react"; import { Processor } from "./processor"; import { filterPlaceholders } from "./utils/filter-placeholders"; export function useProgressiveJson(options) { const [processor] = useState(() => new Processor(options)); // Update processor options when they change useEffect(() => { processor.updateOptions(options); }, []); // Clean up processor on unmount useEffect(() => { return () => { processor.destroy(); }; }, []); // Get the selected/transformed store (main API) const store = filterPlaceholders(useSyncExternalStore(processor.subscribe.bind(processor), processor.getStore.bind(processor))); // Get raw store for debugging/advanced use cases const rawStore = useSyncExternalStore(processor.subscribe.bind(processor), processor.getRawStore.bind(processor)); // Get transformed store (after transform but before select) const transformedStore = useSyncExternalStore(processor.subscribe.bind(processor), processor.getTransformedStore.bind(processor)); // Get streaming state const isStreaming = useSyncExternalStore(processor.subscribe.bind(processor), processor.isCurrentlyStreaming.bind(processor)); // Get stream error const streamError = useSyncExternalStore(processor.subscribe.bind(processor), processor.getStreamError.bind(processor)); const startFetching = useCallback(() => { processor.startFetching(); }, [processor]); const stop = useCallback(() => { processor.stop(); }, [processor]); const updateOptions = useCallback((newOptions) => { processor.updateOptions(newOptions); }, [processor]); return { store, rawStore, transformedStore, isStreaming, streamError, startFetching, stop, updateOptions, }; }