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

26.02.2026
Обновление 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 Copy
import { PipelineOrchestrator, usePipelineRunVue } from "rest-pipeline-js";

то теперь это неправильно. Vue-хелперы нужно импортировать так:

ts Copy
import { PipelineOrchestrator } from "rest-pipeline-js";
import { usePipelineRunVue } from "rest-pipeline-js/vue";

А для React — так:

ts Copy
import { PipelineOrchestrator } from "rest-pipeline-js";
import { usePipelineRunReact } from "rest-pipeline-js/react";

Миграция существующих проектов (коротко и по делу)

1) Исправить импорты

  • Было:
ts Copy
import { usePipelineRunVue } from "rest-pipeline-js";
  • Стало:
ts Copy
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 Copy
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 Copy
<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 Copy
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

Читать далее

27.02.2026

macrulez.ru: переезд с «чистого» Vue на Nuxt и SSR

Переехал с «голого» Vue 3 и Vite на Nuxt с полноценным SSR для macrulez.ru — без переписывания проекта с нуля.

В посте показываю, как аккуратно натянуть Nuxt поверх существующей архитектуры, завести server API‑прокси, настроить метаданные и деплой через PM2.

Метки
VueNuxtSSRSEOрефактор
01.03.2026

Toolz - в помощь вебмастеру

Краткий обзор возможностей трёх инструментов на toolz.macrulez.ru — сжатие растровых картинок с разными кодеками и настройками, оптимизация SVG и конструктор CSS-градиентов. Что можно настроить, как смотреть результат и как обрабатывать файлы пачками.

Метки
toolzизображенияоптимизацияSVGградиентыCSS
03.03.2026

Toolz: редактируем очередь изображений в процессе работы

Теперь в Image Compressor и Tiny SVG можно не только сжимать изображения пачками, но и редактировать саму очередь на лету — добавлять новые файлы и удалять лишние без перезапуска всего процесса. В статье разбираем, как эта мелочь по интерфейсу заметно упрощает подготовку ассетов для веба.

Метки
toolzочередьизображения