@etl-corestream/react
v0.2.29
Published
React UI components for ETLCoreStream — stream-oriented ETL building blocks.
Maintainers
Readme
ETL CoreStream React
React adapter for ETL CoreStream Core
Build fully reactive ETL interfaces in React using composable hooks, compound components, render props, context orchestration, and headless UI patterns.
@etl-corestream/react transforms the CoreStream orchestration engine into a complete React-first developer experience.
It provides:
- Reactive ETL hooks
- Compound context architecture
- Fully customizable UI components
- Headless render-prop APIs
- Context-driven orchestration
- Slot/asChild composition support
- Pagination-aware data views
- Editable ETL tables
- Recovery workflows
- Mapping interfaces
- Import/export triggers
- Metrics & progress subscriptions
The adapter is designed to work seamlessly with the reactive architecture exposed by @etl-corestream/core.
⚠️ Disclaimer — under active development
@etl-corestream/react is currently under heavy development and is not stable yet.
Until version 1.0.0, APIs, component contracts, behaviors, and internal architecture may change without notice.
Expect breaking changes while the ecosystem evolves.
📚 Table of Contents
- Features
- Philosophy
- Installation
- Quick Start
- Architecture Overview
- Compound Component Architecture
- Context System
- Render Props
- asChild / Slot Support
- Hooks
- Components
- DataView System
- Editable Tables
- Mapping System
- Recovery Workflows
- Reactive State Integration
- Headless UI Philosophy
- Advanced Composition
- Example Workflow
- Why This Architecture?
- Design Goals
- Official Packages
- License
✨ Features
- React-first ETL architecture
- Headless & composable APIs
- Compound component system
- Render prop support
- Slot/asChild composition
- Context-driven orchestration
- Reactive ETL state
- Pagination-aware data views
- Editable datasets
- Built-in mapping UI helpers
- Recovery flow helpers
- Reactive metrics & progress
- Framework-style component API
- Tailwind-friendly
- Fully customizable rendering
- Hooks + components interoperability
- RxJS + Signals integration
- Zero imposed styling
- Massive dataset visualization support
🧠 Philosophy
@etl-corestream/react is not a styled UI kit.
It is a headless orchestration layer for React applications built on top of ETL CoreStream.
The adapter focuses on:
- Composition over rigid components
- Context over prop drilling
- Headless APIs over opinionated UI
- Reactive state over imperative synchronization
- Reusable orchestration primitives
- Massive-scale workflows
You can:
- Use the included components directly
- Build your own UI entirely from hooks
- Mix both approaches freely
- Replace rendering at any level
🚀 Installation
Install the React adapter:
npm install @etl-corestream/react⚡ Quick Start
import { Etl } from "@etl-corestream/react";
export const App = () => {
return (
<Etl.Root>
<Etl.Layout.Root layouts={layouts}>
<Etl.Layout.Selector />
<Etl.Layout.Trigger>
Select Layout
</Etl.Layout.Trigger>
</Etl.Layout.Root>
<Etl.Importer.Root>
<Etl.Importer.Input />
<Etl.Importer.Trigger>
Select File
</Etl.Importer.Trigger>
</Etl.Importer.Root>
<Etl.Progress>
{({ totalProgress }) => (
<progress value={totalProgress} max={100} />
)}
</Etl.Progress>
<Etl.DataView.Root>
<Etl.DataView.Table.Root>
<Etl.DataView.Table.THead />
<Etl.DataView.Table.TBody />
</Etl.DataView.Table.Root>
</Etl.DataView.Root>
</Etl.Root>
);
};🏗️ Architecture Overview
The React adapter wraps the ETL CoreStream orchestrator with layered React contexts and composable hooks.
ETL CoreStream Orchestrator
↓
Reactive Hooks
↓
Context Providers
↓
Compound Components
↓
Custom UI RenderingThe system allows:
- Shared orchestration state
- Nested contextual behavior
- Localized state composition
- Headless rendering control
- Massive UI flexibility
🧩 Compound Component Architecture
The adapter uses a compound component architecture inspired by systems like:
- Radix UI
- Headless UI
- React Aria
Example:
<Etl.DataView.Root>
<Etl.DataView.Table.Root>
<Etl.DataView.Table.THead />
<Etl.DataView.Table.TBody />
</Etl.DataView.Table.Root>
<Etl.DataView.Pagination.Root>
<Etl.DataView.Pagination.PagePreviousButton />
<Etl.DataView.Pagination.PageNextButton />
</Etl.DataView.Pagination.Root>
</Etl.DataView.Root>Contexts automatically coordinate:
- Pagination
- Current rows
- Filtering
- Editing
- Metrics
- Viewer state
🌐 Context System
The adapter exposes multiple contextual layers.
Global ETL Context
<Etl.Root> creates and exposes the orchestrator instance to all descendants.
<Etl.Root>
<MyETLInterface />
</Etl.Root>Internally:
<EtlContext.Provider value={orchestrator}>This provides:
- State
- Metrics
- Logs
- Progress
- Steps
- Recovery state
- Viewer state
- Reactive signals
Compound Local Contexts
Certain systems create localized contextual state.
Example:
<Etl.DataView.Root>Provides:
- Pagination coordination
- Filtering state
- Current rows
- Editing state
- Data navigation helpers
This enables deeply nested composition without prop drilling.
🎨 Render Props
Most components support render props for full rendering control.
Example:
<Etl.Progress>
{({ totalProgress }) => (
<progress value={totalProgress} max={100} />
)}
</Etl.Progress>Example:
<Etl.DataView.Table.Cell>
{({ isError }) => (
<div>
{isError && <span>Error</span>}
</div>
)}
</Etl.DataView.Table.Cell>Render props expose internal contextual values while preserving orchestration behavior.
Render props — examples
Below are short examples (and references to the Storybook viewer) showing common render-prop patterns used across the library.
See the concrete implementation in the Storybook viewer:
For a full Storybook example, see: src/components/etl/storybook on GitHub
<Etl.DataView.Edit.Root className="fixed top-0 left-0 w-full h-full bg-white/50 backdrop-blur-sm z-50 flex items-center justify-center">
{
({ currentEditRow }) => {
if (!currentEditRow)
return null;
return <>
<div className="flex flex-col gap-2 p-4 bg-white rounded-md border border-gray-300">
<span className="text-lg font-semibold">Edit Cell</span>
<div className="flex gap-5 ">
<div className="flex flex-col gap-1">
<span className="text-gray-400 text-xs">Previous Value:</span>
<Etl.DataView.Edit.PreviusInput className="border border-gray-300 w-min text-nowrap bg-gray-100 text-gray-800 p-2 px-4 rounded-md hover:bg-gray-200 transition-colors duration-300 cursor-pointer" >
{
({ previusValue }) =>
previusValue
}
</Etl.DataView.Edit.PreviusInput>
</div>And a cell-level render-prop used for per-cell rendering/validation UI:
Object.keys(row.value).map((key) =>
<Etl.DataView.Table.Cell key={key} row={row} column={key} className="border-r border-gray-300 data-[is-error]:bg-red-200">
{
({ isError }) =>
<div className="flex items-center">
<div className="flex flex-col items-center gap-0 w-full px-1">
{isError ?
<span className="bottom-0 order-2 text-xs font-semibold text-red-500">
{ErrorDicc[isError] || isError}
</span> : nullMinimal usage examples:
// Progress (simple)
<Etl.Progress>
{({ totalProgress }) => <progress value={totalProgress} max={100} />}
</Etl.Progress>
// Edit overlay (previous / new value)
<Etl.DataView.Edit.Root>
{({ currentEditRow }) =>
currentEditRow ? (
<div>
<Etl.DataView.Edit.PreviusInput>
{({ previusValue }) => previusValue}
</Etl.DataView.Edit.PreviusInput>
<Etl.DataView.Edit.NewInput />
</div>
) : null
}
</Etl.DataView.Edit.Root>
// Table body + cell render-props
<Etl.DataView.Table.TBody>
{({ currentRows, setCurrentEditRow }) =>
currentRows.value?.map(row => (
<Etl.DataView.Table.Row key={row.__rowId} rowObject={row}>
{({ row }) => (
<>
<Etl.DataView.Table.Cell row={row} column="index">
{() => <span>{row.__rowId}</span>}
</Etl.DataView.Table.Cell>
<Etl.DataView.Table.Cell row={row} column="name">
{({ isError }) => <span className={isError ? 'text-red-500' : ''}>{row.value.name}</span>}
</Etl.DataView.Table.Cell>
</>
)}
</Etl.DataView.Table.Row>
))
}
</Etl.DataView.Table.TBody>These patterns let you access contextual state (current rows, edit state, validation flags, header helpers, etc.) while keeping the UI fully custom and headless.
🔌 asChild / Slot Support
All major interactive components support asChild.
This enables integration with:
- Radix UI Slot
- Custom buttons
- Design systems
- Tailwind components
- External UI libraries
Example:
<Etl.ResetButton asChild>
<button className="custom-button">
Reset
</button>
</Etl.ResetButton>The ETL behavior is preserved while rendering your own component.
🪝 Hooks
The adapter exposes hooks for building completely custom interfaces.
Core Hooks
useEtlOrchestrator()
Creates and exposes the orchestrator instance.
const orchestrator = useEtlOrchestrator();useEtlContext()
Access the global ETL context.
const { metrics, progress } = useEtlContext();useDataView()
Provides:
- Current rows
- Pagination
- Filtering
- Editing helpers
- Metrics
- View navigation
useImporter()
Importer helpers and state.
useExporter()
Export helpers and exporter triggers.
useMapper()
Header mapping orchestration.
useRecoveryView()
Recovery workflow helpers.
useLayoutView()
Layout selection orchestration.
useAbortButton()
Abort current workflow actions.
useResetButton()
Reset ETL sessions.
Reactive Hooks
useEtlState()useMetrics()useProgress()useLogs()useStepFlags()
🧱 Components
Main Namespace
<Etl.Root />
<Etl.Importer />
<Etl.StateView />
<Etl.Layout />
<Etl.LogView />
<Etl.DataView />
<Etl.ResetButton />
<Etl.Exporter />
<Etl.Mapper />
<Etl.Progress />
<Etl.Recover />
<Etl.AbortButton />📊 DataView System
The DataView system centralizes:
- Table rendering
- Pagination
- Editing
- Filtering
- Row removal
- Reactive dataset visualization
Table Components
<Etl.DataView.Table.Root />
<Etl.DataView.Table.THead />
<Etl.DataView.Table.TBody />
<Etl.DataView.Table.Row />
<Etl.DataView.Table.Cell />
<Etl.DataView.Table.HeaderCell />Pagination Components
<Etl.DataView.Pagination.Root />
<Etl.DataView.Pagination.PageNextButton />
<Etl.DataView.Pagination.PagePreviousButton />
<Etl.DataView.Pagination.PageFirstButton />
<Etl.DataView.Pagination.PageLastButton />✏️ Editable Tables
The adapter includes contextual editing workflows.
<Etl.DataView.Edit.Root>
<Etl.DataView.Edit.PreviusInput />
<Etl.DataView.Edit.NewInput />
<Etl.DataView.Edit.TriggerCancel />
<Etl.DataView.Edit.TriggerSubmit />
</Etl.DataView.Edit.Root>Rows can be edited while ETL processing continues in the background.
🧭 Mapping System
The mapping system helps users map incoming headers dynamically.
Example:
<Etl.Mapper.Root>
<Etl.Mapper.HeadersView />
<Etl.Mapper.TriggerConfirm>
Confirm
</Etl.Mapper.TriggerConfirm>
<Etl.Mapper.TriggerCancel>
Cancel
</Etl.Mapper.TriggerCancel>
</Etl.Mapper.Root>Useful for:
- CSV imports
- Alias mapping
- Flexible schemas
- User-driven remapping
💾 Recovery Workflows
The adapter exposes recovery flows directly to React interfaces.
Example:
const { recoveryPoint } = useRecoveryView();Recovery UI can be fully customized while maintaining orchestration behavior.
⚛️ Reactive State Integration
The adapter integrates with the reactive CoreStream architecture.
Supported internally:
- RxJS
- Preact Signals
React components automatically react to:
- Progress updates
- Metrics changes
- Validation updates
- Dataset changes
- Recovery state
- Viewer state
🎯 Headless UI Philosophy
The adapter intentionally avoids imposing:
- Styling systems
- CSS frameworks
- Component themes
- Layout opinions
You fully control:
- Rendering
- Styling
- Accessibility
- Animations
- Design systems
Tailwind, CSS Modules, Styled Components, Emotion, or custom systems all work naturally.
🧪 Example Workflow
A complete workflow may include:
Select Layout
↓
Select File
↓
Map Headers
↓
Process Stream
↓
Validate Rows
↓
Edit Invalid Data
↓
Filter Results
↓
Export DatasetAll while remaining:
- Reactive
- Recoverable
- Non-blocking
- Editable
🚀 Why This Architecture?
Massive ETL interfaces are difficult to build traditionally.
Most solutions suffer from:
- Prop drilling
- Tight coupling
- Non-reactive orchestration
- Inflexible rendering
- UI blocking
- Poor scalability
@etl-corestream/react solves this with:
- Layered contexts
- Reactive orchestration
- Compound composition
- Render-prop extensibility
- Hook-driven APIs
🧭 Design Goals
The adapter was designed around a few core principles:
- Composition over monolithic widgets
- Headless APIs over rigid UI
- Reactive orchestration over imperative sync
- Context coordination over prop drilling
- Massive dataset support
- Incremental rendering
- Flexible integration
📦 Official Packages
Core Engine
GitHub:
React Adapter
GitHub:
🤝 Open Source
The project is fully open source.
Contributions are welcome:
- Issues
- Discussions
- Documentation
- Adapters
- Custom modules
- Examples
- Performance improvements
📄 License
MIT License.
