Обновление rest-pipeline-js до версии 1.2.5

rest-pipeline-js: что изменилось в последних версиях и как теперь правильно подключать Core / Vue / React
Я обновил rest-pipeline-js и заодно поправил одну вещь, которая давно назревала: разделил точки входа пакета на “ядро” и интеграции под фреймворки. В результате сборки стали чище (без лишних зависимостей), а импорты — более явными.
Ниже — что именно изменилось, почему, как мигрировать существующие проекты, и примеры использования core, а также “плагинов” (интеграций) для Vue 3 и React.
Зачем вообще это было менять
Раньше было слишком легко случайно сделать так, чтобы сборщик/IDE “видели” Vue/React-хелперы там, где они не нужны. Это приводило к двум неприятным эффектам:
- Лишний код/лишние зависимости могли подтягиваться в сборку даже если вы используете только core.
- В проектах появлялись хрупкие алиасы (например, на
dist-файлы), которые ломались при изменениях структуры сборки пакета.
Я хотел, чтобы было ровно так:
- Если вам нужно только ядро — вы импортируете только ядро.
- Если вы в Vue — вы импортируете Vue-точку входа.
- Если вы в React — вы импортируете React-точку входа.
- И при этом bundler не тянет React, если вы в Vue, и наоборот.
Главное изменение: новые точки входа (entry points)
Начиная с актуальных версий (в моём репозитории это оформлено коммитом “restructure package exports for Vue and React”), в пакете есть 3 официальные точки входа:
| Точка входа | Для чего | Что внутри |
|---|---|---|
rest-pipeline-js |
core only | PipelineOrchestrator, createRestClient, типы и базовые утилиты. Без Vue/React. |
rest-pipeline-js/vue |
Vue 3 | Всё из core + Vue composition-функции (usePipelineRunVue, usePipelineProgressVue, логи, события, rerun и т.д.) |
rest-pipeline-js/react |
React | Всё из core + React hooks (usePipelineRunReact, usePipelineProgressReact, логи, события, rerun и т.д.) |
Технически это сделано через package.json#exports (чтобы резолв был корректный и предсказуемый), а React entry point использует peerDependencies для react/react-dom, чтобы они не были обязательными для core/Vue пользователей.
Breaking change (важно): Vue/React-хелперы больше не из корня
Если раньше вы делали так:
ts
import { PipelineOrchestrator, usePipelineRunVue } from "rest-pipeline-js";
то теперь это неправильно. Vue-хелперы нужно импортировать так:
ts
import { PipelineOrchestrator } from "rest-pipeline-js";
import { usePipelineRunVue } from "rest-pipeline-js/vue";
А для React — так:
ts
import { PipelineOrchestrator } from "rest-pipeline-js";
import { usePipelineRunReact } from "rest-pipeline-js/react";
Миграция существующих проектов (коротко и по делу)
1) Исправить импорты
- Было:
ts
import { usePipelineRunVue } from "rest-pipeline-js";
- Стало:
ts
import { usePipelineRunVue } from "rest-pipeline-js/vue";
И аналогично для остальных Vue/React-хелперов.
2) Удалить ручные alias на dist (если они были)
Если вы добавляли алиасы вроде “rest-pipeline-js/vue → ./node_modules/.../dist/...”, уберите их.
Теперь правильный путь — всегда импортировать через официальные entry points, а резолв сделает Node/bundler по exports.
На практике это важно: такие алиасы часто ломаются при любом рефакторинге сборки пакета (переименования файлов/директорий и т.д.).
Пример 1: базовый функционал (Core)
Ниже пример “ядра”: создаём orchestrator, описываем шаги, запускаем pipeline, подписываемся на прогресс и события.
ts
import { PipelineOrchestrator } from "rest-pipeline-js";
type Shared = {
token: string;
requestUrl?: string;
};
const pipelineConfig = {
stages: [
{
key: "profile",
request: async ({ sharedData }: { sharedData: Shared }) => {
sharedData.requestUrl = "/profile";
return sharedData.requestUrl;
},
after: ({ result, sharedData }: { result: any; sharedData: Shared }) => {
// можно нормализовать ответ и прокинуть requestUrl дальше
return { ...result, requestUrl: sharedData.requestUrl };
},
pauseBefore: 250,
},
{
key: "settings",
request: async ({ sharedData }: { sharedData: Shared }) => {
sharedData.requestUrl = "/settings";
return sharedData.requestUrl;
},
pauseBefore: 250,
},
],
};
const orchestrator = new PipelineOrchestrator({
config: pipelineConfig,
httpConfig: {
baseURL: "https://api.example.com",
timeout: 10_000,
headers: {
Authorization: "Bearer TOKEN",
},
retry: { attempts: 2, delayMs: 500 },
cache: { enabled: true, ttlMs: 60_000 },
rateLimit: { maxConcurrent: 2 },
},
sharedData: {
token: "TOKEN",
},
});
// Прогресс
orchestrator.subscribeProgress(progress => {
console.log("currentStage:", progress.currentStage);
console.log("stageStatuses:", progress.stageStatuses);
});
// События
orchestrator.on("step:profile:success", payload => {
console.log("profile ok:", payload.data);
});
orchestrator.on("step:settings:error", payload => {
console.error("settings failed:", payload.error);
});
// Запуск
const result = await orchestrator.run({ anyInput: true });
console.log("pipeline success:", result.success);
console.log("stageResults:", result.stageResults);
Ключевая мысль: core остаётся универсальным — его можно использовать хоть в Node, хоть в браузере, хоть внутри любого UI-фреймворка.
Пример 2: “плагин” для Vue 3 (composition functions)
Во Vue теперь надо импортировать из rest-pipeline-js/vue.
vue
<script setup lang="ts">
import { computed } from "vue";
import { PipelineOrchestrator } from "rest-pipeline-js";
import {
usePipelineProgressVue,
usePipelineRunVue,
usePipelineLogsVue,
useRerunPipelineStepVue,
} from "rest-pipeline-js/vue";
const pipelineConfig = {
stages: [
{ key: "step1", command: "/step1", method: "GET" },
{ key: "step2", command: "/step2", method: "GET", dependsOn: ["step1"] },
],
};
const orchestrator = new PipelineOrchestrator({
config: pipelineConfig,
httpConfig: { baseURL: "https://api.example.com", timeout: 8000 },
});
const progress = usePipelineProgressVue(orchestrator);
const logs = usePipelineLogsVue(orchestrator);
const rerun = useRerunPipelineStepVue(orchestrator);
const { run, running, stageResults, error } = usePipelineRunVue(orchestrator);
const currentStage = computed(() => progress.value.currentStage);
</script>
<template>
<div>
<div>Current stage: {{ currentStage }}</div>
<button :disabled="running" @click="run()">
Run pipeline
</button>
<button :disabled="running" @click="rerun('step2')">
Rerun step2
</button>
<pre v-if="error">Error: {{ error.message }}</pre>
<pre>{{ stageResults }}</pre>
<pre>{{ logs }}</pre>
</div>
</template>
Что мне нравится в таком разделении: Vue-проект импортирует Vue-точку входа, и это явно. Никаких “магических” импортов из корня, которые потом случайно ломаются при апдейте.
Пример 3: “плагин” для React (hooks)
В React импорт — из rest-pipeline-js/react.
tsx
import { useMemo } from "react";
import { PipelineOrchestrator } from "rest-pipeline-js";
import {
usePipelineProgressReact,
usePipelineRunReact,
usePipelineLogsReact,
} from "rest-pipeline-js/react";
export function DemoPipeline() {
const orchestrator = useMemo(() => {
const pipelineConfig = {
stages: [
{ key: "step1", command: "/step1", method: "GET" },
{ key: "step2", command: "/step2", method: "GET", dependsOn: ["step1"] },
],
};
return new PipelineOrchestrator({
config: pipelineConfig,
httpConfig: { baseURL: "https://api.example.com", timeout: 8000 },
});
}, []);
const progress = usePipelineProgressReact(orchestrator);
const logs = usePipelineLogsReact(orchestrator);
const [run, { running, result, error, stageResults }] = usePipelineRunReact(orchestrator);
return (
<div>
<div>Current stage: {progress.currentStage}</div>
<button onClick={() => run()} disabled={running}>
Run pipeline
</button>
{error && <pre>Error: {error.message}</pre>}
{result && <pre>Result: {JSON.stringify(result, null, 2)}</pre>}
<pre>Stage results: {JSON.stringify(stageResults, null, 2)}</pre>
<pre>Logs: {JSON.stringify(logs, null, 2)}</pre>
</div>
);
}
Итог
Если коротко, то изменение одно, но очень практичное:
- core теперь живёт в
rest-pipeline-js - Vue-интеграция — в
rest-pipeline-js/vue - React-интеграция — в
rest-pipeline-js/react
Это делает сборки предсказуемее, убирает лишние зависимости и упрощает миграции: никаких alias на dist, только импорты по официальным entry points.
Если захотите — я отдельно напишу пост с реальными кейсами из проектов (например, как я использую metrics, rateLimit, cache и rerunStep в продовой интеграции).
Ссылка на пакет - https://www.npmjs.com/package/rest-pipeline-js