Skip to content

Reference

Entry points

Entry pointUse forContents
rest-pipeline-jsCore onlyPipelineOrchestrator, createRestClient, types, utilities. No Vue/React.
rest-pipeline-js/vueVue projectsCore + Vue composables
rest-pipeline-js/reactReact projectsCore + React hooks
rest-pipeline-js/testingTests (any framework)createMockAdapter() — see Testing
dist/umd/rest-pipeline.umd.min.jsCDN <script> tag, no bundlerCore, with axios bundled in — see CDN usage
js
// Core only
import { createRestClient, PipelineOrchestrator } from 'rest-pipeline-js'

// Vue
import { PipelineOrchestrator, usePipelineRunVue } from 'rest-pipeline-js/vue'

// React
import { PipelineOrchestrator, usePipelineRunReact } from 'rest-pipeline-js/react'

// Testing (any framework — not bundled into the core entry point)
import { createMockAdapter } from 'rest-pipeline-js/testing'

sideEffects: false — unused entry points are tree-shaken. react / react-dom are peerDependencies.

Architecture

rest-pipeline-js

├── createRestClient (HttpConfig) → RestClient
│     ├── RequestExecutor      — retry + backoff + Retry-After + AbortController timeout
│     ├── CacheManager         — in-memory TTL cache for GET responses
│     ├── RateLimiter          — concurrency + req/interval sliding window
│     ├── CircuitBreaker       — closed → open → half-open; rejects locally when open
│     ├── AuthProvider         — Bearer injection; 401 refresh + one retry; optional tokenTtlMs cache
│     ├── MetricsCollector     — onRequestStart / onRequestEnd callbacks
│     ├── HeaderSanitizer      — masks sensitive headers before metrics callbacks
│     ├── OfflineQueue         — queues mutating requests while offline, replays on reconnect
│     └── HttpAdapter          — pluggable transport (default: axios; swap for fetch / edge)

├── PipelineOrchestrator (config, httpConfig?, sharedData?, options?)
│     ├── StageRunner          — sequential execution loop; parallel via Promise.all
│     │     condition → pauseBefore → before → validateInput → request → after → validateOutput → pauseAfter
│     ├── MiddlewareRunner     — beforeEach / afterEach / onError across all stages
│     ├── EventBus             — on() / emit(); step:start|success|error|skipped|progress, log
│     ├── ProgressTracker      — subscribeProgress / subscribeStageResults / getProgress
│     ├── AbortController      — abort() cancels current HTTP request via AbortSignal
│     ├── PauseController      — pause() / resume() inter-stage checkpoints
│     ├── MetricsHooks         — onPipelineStart / onPipelineEnd / onStepDuration
│     ├── StateSerializer      — exportState() / importState() (stageResults + logs)
│     ├── PersistAdapter       — pluggable save/load; auto-save after each stage
│     └── PluginManager        — install() + destroy() lifecycle

├── PipelineBuilder (pipe())
│     .step() / .parallel() / .subPipeline() / .stream() / .websocket() → .build() / .toConfig()

├── createPipeline()           — short factory wrapping new PipelineOrchestrator()

├── validatePipelineConfig()   — duplicate keys, empty keys, type checks, recursive

├── /vue   (separate entry point)
│     usePipelineRunVue / usePipelineProgressVue / usePipelineLogsVue
│     usePipelineStepEventVue / useRestClientVue / usePipelineStageResultVue

├── /react (separate entry point)
│     usePipelineRunReact / usePipelineProgressReact / usePipelineLogsReact
│     usePipelineStepEventReact / useRestClientReact / usePipelineStageResultReact

└── /testing (separate entry point)
      createMockAdapter()   — HttpAdapter backed by route definitions, no network

Bundle size & peer dependencies

Entry pointPeer depsNotes
rest-pipeline-jsCore — orchestrator, HTTP client, utilities. Depends on axios.
rest-pipeline-js/vuevue ^3.3Core + Vue composables
rest-pipeline-js/reactreact ^19, react-dom ^19Core + React hooks
rest-pipeline-js/testingcreateMockAdapter() only — doesn't bundle the core client

The package ships as tree-shakeable ESM (dist/esm/) and CommonJS (dist/cjs/), each with its own package.json ({"type":"module"} / {"type":"commonjs"}) so Node's native ESM resolver can load it directly — not just bundlers. Every entry point is code-split — importing one does not bundle the others. Size is enforced in CI (see below); current brotli size is ~25 KB for the core//vue//react entry points (with all dependencies — axios for core; vue/react are peer deps, excluded) and well under 1 KB for /testing.

Development

bash
npm install
npm run build          # tsc → dist/esm + dist/cjs, then writes the dist/*/package.json type markers
npm run verify:esm     # loads every entry point with node's native ESM resolver (regression guard)
npm test                # vitest — unit tests
npm run test:types      # vitest --typecheck — type-level tests for pipe()'s TPrev threading
npm run test:coverage   # vitest run --coverage, enforces the thresholds in vitest.config.ts
npm run lint            # eslint .
npm run size             # rebuilds, then checks brotli size per entry point against .size-limit.json

.github/workflows/ci.yml runs all of the above (lint, build, ESM-load check, tests, type tests, coverage, bundle size) on Node 20/22/24 for every push and pull request. (The published package itself only requires Node 18+ — see engines in package.json — but the dev toolchain, Vite 7 / Vitest 4, needs Node 20.19+/22.12+ just to load their own config, so CI can't verify Node 18 anymore.)

License

MIT