rest-pipeline-js 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,253 +1,412 @@
1
+ ## Утсновка
1
2
 
2
- # pipeline-js
3
+ ```sh
4
+ npm i rest-pipeline-js
5
+ ```
3
6
 
4
- Модуль для работы с REST API, пайплайнами запросов и отслеживанием прогресса. Не зависит от Vue/React, но легко интегрируется в любые проекты.
7
+ ## Возможности и API
5
8
 
6
9
 
7
- ## Установка
10
+ ### Базовый модуль (rest-pipeline-js)
8
11
 
12
+ #### Пример: создание REST клиента и выполнение запроса
13
+
14
+ ```js
15
+ import { createRestClient } from 'rest-pipeline-js';
16
+
17
+ const client = createRestClient({
18
+ baseURL: 'https://api.example.com',
19
+ timeout: 5000,
20
+ headers: { Authorization: 'Bearer TOKEN' },
21
+ });
22
+
23
+ async function fetchUser(id) {
24
+ const res = await client.request(`/users/${id}`);
25
+ if (res.error) {
26
+ console.error(res.error);
27
+ } else {
28
+ console.log(res.data);
29
+ }
30
+ }
9
31
  ```
10
- npm i rest-pipeline-js
11
- ```
12
32
 
13
- ## Быстрый старт (чистый JS)
33
+
34
+ #### Пример: запуск pipeline, обработка ошибок, отслеживание выполнения и использование общего пула данных
14
35
 
15
36
  ```js
16
- const { createRestClient, PipelineOrchestrator } = require('rest-pipeline-js');
37
+ import { PipelineOrchestrator } from 'rest-pipeline-js';
17
38
 
18
- // Создание REST клиента
19
- const client = createRestClient({ baseURL: 'https://api.example.com' });
20
- client.get('/endpoint').then(response => {
21
- console.log(response.data);
39
+ const pipelineConfig = {
40
+ steps: [
41
+ {
42
+ key: 'step1',
43
+ command: '/api/step1',
44
+ method: 'POST',
45
+ // Можно добавить кастомные параметры шага
46
+ },
47
+ {
48
+ key: 'step2',
49
+ command: '/api/step2',
50
+ method: 'POST',
51
+ dependsOn: ['step1'], // step2 выполнится только после step1
52
+ },
53
+ ],
54
+ };
55
+
56
+ const httpConfig = {
57
+ baseURL: 'https://api.example.com',
58
+ timeout: 7000,
59
+ headers: { Authorization: 'Bearer TOKEN' },
60
+ retry: { attempts: 2, delayMs: 1000 },
61
+ cache: { enabled: true, ttlMs: 60000 },
62
+ rateLimit: { maxConcurrent: 2 },
63
+ metrics: {
64
+ onRequestStart: info => console.log('Start:', info),
65
+ onRequestEnd: info => console.log('End:', info),
66
+ },
67
+ };
68
+
69
+ // Общий пул данных между шагами
70
+ const sharedData = { sessionId: 'abc123' };
71
+
72
+ const orchestrator = new PipelineOrchestrator(pipelineConfig, httpConfig, sharedData, { autoReset: true });
73
+
74
+ // Отслеживание прогресса
75
+ orchestrator.subscribeProgress(progress => {
76
+ console.log('Текущий шаг:', progress.currentStage, 'Статусы:', progress.stageStatuses);
22
77
  });
23
78
 
24
- // Пример пайплайна
25
- const pipeline = new PipelineOrchestrator({
26
- stages: [
27
- {
28
- key: 'getUser',
29
- request: async () => client.get('/user'),
30
- },
31
- {
32
- key: 'getPosts',
33
- request: async (_, results) => client.get(`/posts?userId=${results[0].data.id}`),
34
- },
35
- ],
36
- }, { baseURL: 'https://api.example.com' });
37
-
38
- // Подписка на прогресс
39
- const unsubscribe = pipeline.subscribeProgress(progress => {
40
- console.log('Pipeline progress:', progress);
79
+ // Подписка на события успеха/ошибки шага
80
+ orchestrator.on('step:step1:success', payload => {
81
+ console.log('Step 1 завершён успешно:', payload.data);
82
+ });
83
+ orchestrator.on('step:step2:error', payload => {
84
+ console.error('Ошибка на step2:', payload.error);
41
85
  });
42
86
 
43
- // Получить текущий прогресс (snapshot)
44
- console.log(pipeline.getProgress());
87
+ // Подписка на все логи pipeline
88
+ orchestrator.on('log', () => {
89
+ console.log('Логи:', orchestrator.getLogs());
90
+ });
91
+
92
+ // Запуск pipeline с передачей параметров
93
+ orchestrator.run({ foo: 'bar' })
94
+ .then(result => {
95
+ console.log('Pipeline завершён. Итог:', result);
96
+ // Доступ к результатам всех шагов:
97
+ console.log('Результаты шагов:', result.stageResults);
98
+ })
99
+ .catch(err => {
100
+ // Глобальная обработка ошибок pipeline
101
+ console.error('Pipeline error:', err);
102
+ });
103
+
104
+ // Повторный запуск шага (например, после ошибки)
105
+ // orchestrator.rerunStep('step2');
45
106
  ```
46
107
 
108
+ ---
47
109
 
110
+ ---
48
111
 
49
- ## React: хуки для интеграции
112
+ Модуль предоставляет универсальный механизм для построения и управления REST API pipeline с поддержкой прогресса, обработки ошибок, подписки на события и расширяемости.
50
113
 
51
- ### usePipelineProgress
52
- ```jsx
53
- import { usePipelineProgress } from 'rest-pipeline-js/react';
54
- import { PipelineOrchestrator } from 'rest-pipeline-js';
55
114
 
56
- const pipeline = new PipelineOrchestrator({ stages: [...] }, { baseURL: '...' });
57
- const progress = usePipelineProgress(pipeline);
58
- ```
115
+ #### Основные классы и функции
59
116
 
60
- ### usePipelineRun
61
- ```jsx
62
- import { usePipelineRun } from 'rest-pipeline-js/react';
63
- const [run, { running, result, error }] = usePipelineRun(pipeline);
64
-
65
- // В компоненте:
66
- <button onClick={() => run()}>Старт</button>
67
- {running && <span>Выполняется...</span>}
68
- {result && <pre>{JSON.stringify(result)}</pre>}
69
- {error && <span style={{color:'red'}}>{String(error)}</span>}
70
- ```
117
+ ---
71
118
 
72
- ### useRestClient
73
- ```jsx
74
- import { useRestClient } from 'rest-pipeline-js/react';
75
- const api = useRestClient({ baseURL: '...' });
76
- ```
77
119
 
78
- ## Vue: composition-функции для интеграции
120
+ ### createRestClient(config: HttpConfig): RestClient
121
+ Создаёт REST-клиент с поддержкой расширенных возможностей для работы с HTTP API.
79
122
 
80
- ### usePipelineProgress
123
+ #### Пример
81
124
  ```js
82
- import { usePipelineProgress } from 'rest-pipeline-js/vue';
83
- import { PipelineOrchestrator } from 'rest-pipeline-js';
125
+ import { createRestClient } from 'rest-pipeline-js';
126
+
127
+ const client = createRestClient({
128
+ baseURL: 'https://api.example.com',
129
+ timeout: 5000,
130
+ headers: { Authorization: 'Bearer TOKEN' },
131
+ retry: { attempts: 2 },
132
+ cache: { enabled: true, ttlMs: 60000 },
133
+ });
84
134
 
85
- const pipeline = new PipelineOrchestrator({ stages: [...] }, { baseURL: '...' });
86
- const progress = usePipelineProgress(pipeline);
135
+ async function getUser(id) {
136
+ const res = await client.request(`/users/${id}`);
137
+ if (res.error) {
138
+ console.error('Ошибка:', res.error);
139
+ } else {
140
+ console.log('Пользователь:', res.data);
141
+ }
142
+ }
87
143
  ```
88
144
 
89
- ### usePipelineRun
145
+
146
+ ---
147
+
148
+
149
+ ### RequestExecutor
150
+ Обёртка для выполнения REST-запросов с поддержкой автоматического retry и таймаута.
151
+
152
+ #### Пример
90
153
  ```js
91
- import { usePipelineRun } from 'rest-pipeline-js/vue';
92
- const { run, running, result, error } = usePipelineRun(pipeline);
154
+ import { RequestExecutor } from 'rest-pipeline-js';
155
+
156
+ const executor = new RequestExecutor({ baseURL: 'https://api.example.com' });
157
+
158
+ async function fetchData() {
159
+ try {
160
+ const res = await executor.execute('/data', { method: 'GET' }, 3, 3000);
161
+ if (res.error) {
162
+ console.error('Ошибка:', res.error);
163
+ } else {
164
+ console.log('Данные:', res.data);
165
+ }
166
+ } catch (err) {
167
+ console.error('Критическая ошибка:', err);
168
+ }
169
+ }
93
170
  ```
94
171
 
95
- ### useRestClient
172
+
173
+ ---
174
+
175
+
176
+
177
+ ### PipelineOrchestrator
178
+ Основной класс для построения и управления конвейером (pipeline) из последовательных шагов.
179
+
180
+ #### Основные методы и параметры
181
+
182
+ - **constructor(pipelineConfig, httpConfig, sharedData?, options?)** — создание экземпляра:
183
+ - `pipelineConfig` — массив шагов (steps), их параметры, условия, обработчики
184
+ - `httpConfig` — настройки HTTP клиента
185
+ - `sharedData` — общий пул данных между шагами
186
+ - `options.autoReset` — сбрасывать ли состояние после завершения
187
+
188
+ - **run(onStepPause?, externalSignal?)** — запуск конвейера
189
+ - `onStepPause(stepIndex, stepResult, stageResults)` — callback для паузы/подтверждения/модификации результата между шагами (можно реализовать задержку, диалог, логику)
190
+ - `externalSignal` — внешний AbortSignal для отмены
191
+ - Возвращает: `{ stageResults, success }`
192
+
193
+ - **rerunStep(stepKey, options?)** — повторно выполнить один шаг
194
+ - `onStepPause` и `externalSignal` аналогично run
195
+ - Возвращает результат шага
196
+
197
+ - **subscribeProgress(listener)** — подписка на прогресс выполнения (listener получает PipelineProgress)
198
+ - **subscribeStageResults(listener)** — подписка на изменения результатов всех шагов
199
+ - **subscribeStepProgress(stepKey, listener)** — подписка на прогресс конкретного шага
200
+ - **on(eventName, handler)** — универсальная подписка на события:
201
+ - `step:<stepKey>:start|success|error|progress` — события по шагам
202
+ - `log` — новые логи
203
+ - любые кастомные события
204
+ - **onStepStart/Finish/Error(handler)** — подписка на начало/успех/ошибку шага (PipelineStepEvent)
205
+ - **getProgress()** — получить текущий прогресс (snapshot)
206
+ - **getProgressRef()** — получить ссылку на объект прогресса (для реактивности)
207
+ - **getLogs()** — получить массив логов pipeline
208
+ - **abort()** — отменить выполнение пайплайна
209
+ - **isAborted()** — проверить, был ли пайплайн отменён
210
+
211
+ #### Важные параметры шага (stage):
212
+ - `key` — уникальный ключ шага
213
+ - `command` — команда/endpoint для запроса
214
+ - `method` — HTTP-метод
215
+ - `dependsOn` — массив ключей шагов, от которых зависит этот шаг
216
+ - `condition(prev, allResults, sharedData)` — функция-условие для выполнения шага
217
+ - `request(prev, allResults)` — кастомная функция запроса (альтернатива command)
218
+ - `retryCount`, `timeoutMs` — индивидуальные настройки повтора и таймаута
219
+ - `errorHandler(error, key, sharedData)` — обработчик ошибок шага
220
+
221
+ #### Пример
96
222
  ```js
97
- import { useRestClient } from 'rest-pipeline-js/vue';
98
- const api = useRestClient({ baseURL: '...' });
223
+ import { PipelineOrchestrator } from 'rest-pipeline-js';
224
+
225
+ const pipelineConfig = {
226
+ steps: [
227
+ { key: 'first', command: '/api/first', method: 'POST' },
228
+ { key: 'second', command: '/api/second', method: 'POST', dependsOn: ['first'] },
229
+ ],
230
+ };
231
+ const httpConfig = { baseURL: 'https://api.example.com' };
232
+ const sharedData = { sessionId: 'abc' };
233
+ const orchestrator = new PipelineOrchestrator(pipelineConfig, httpConfig, sharedData);
234
+
235
+ orchestrator.subscribeProgress(progress => {
236
+ console.log('Прогресс:', progress);
237
+ });
238
+
239
+ orchestrator.on('step:first:success', payload => {
240
+ console.log('Первый шаг выполнен:', payload.data);
241
+ });
242
+
243
+ // Пауза 1 секунда между шагами
244
+ orchestrator.run(async (i, result) => { await new Promise(r => setTimeout(r, 1000)); return result; })
245
+ .then(result => console.log('Pipeline завершён:', result))
246
+ .catch(err => console.error('Ошибка pipeline:', err));
99
247
  ```
100
248
 
101
- ## Использование в Vue 3
102
249
 
250
+ ---
251
+
252
+
253
+ ### ProgressTracker
254
+ Внутренний класс для отслеживания прогресса pipeline.
255
+
256
+ #### Пример
103
257
  ```js
104
- import { createRestClient, PipelineOrchestrator } from 'rest-pipeline-js';
105
- import { ref, onUnmounted } from 'vue';
106
-
107
- const client = createRestClient({ baseURL: 'https://api.example.com' });
108
- const pipeline = new PipelineOrchestrator({
109
- stages: [
110
- // ...
111
- ],
112
- }, { baseURL: 'https://api.example.com' });
113
-
114
- const progress = ref(pipeline.getProgress());
115
- const unsubscribe = pipeline.subscribeProgress(p => {
116
- progress.value = p;
258
+ import { ProgressTracker } from 'rest-pipeline-js';
259
+
260
+ const tracker = new ProgressTracker(3); // 3 шага
261
+ tracker.subscribe(progress => {
262
+ console.log('Текущий прогресс:', progress);
117
263
  });
118
- onUnmounted(unsubscribe);
264
+ tracker.updateStage(1, 'success');
265
+ console.log(tracker.getProgress());
119
266
  ```
120
267
 
121
- ## Основные API
122
268
 
123
- ### RestClient
124
- - `createRestClient(config)` — создать клиента (axios-like API: get, post, request и др.)
269
+ ---
125
270
 
126
- ### PipelineOrchestrator
127
- - `new PipelineOrchestrator(pipelineConfig, httpConfig)` — создать пайплайн
128
- - `subscribeProgress(listener)` — подписка на прогресс, возвращает функцию отписки
129
- - `getProgress()` — получить текущий прогресс (snapshot)
130
-
131
- ### ProgressTracker (внутренний)
132
- - Реактивность реализована через подписки (observer pattern), не зависит от Vue/React
133
-
134
- ## Структура
135
- - src/rest-client.ts — основной REST клиент
136
- - src/types.ts — типы
137
- - src/request-executor.ts — выполнение запросов
138
- - src/error-handler.ts — обработка ошибок
139
- - src/progress-tracker.ts — отслеживание прогресса
140
- - src/pipeline-orchestrator.ts — оркестрация пайплайна
141
-
142
- ### POST запрос
143
-
144
- ```javascript
145
- api.post('/users', {
146
- name: 'John Doe',
147
- email: 'john@example.com'
148
- })
149
- .then(response => {
150
- console.log('User created:', response.data);
151
- })
152
- .catch(error => {
153
- console.error('Error:', error);
154
- });
155
- ```
156
271
 
157
- ### Использование с async/await
158
-
159
- ```javascript
160
- async function getUsers() {
161
- try {
162
- const response = await api.get('/users');
163
- return response.data;
164
- } catch (error) {
165
- console.error('Error fetching users:', error);
166
- throw error;
167
- }
168
- }
272
+ ### ErrorHandler
273
+ Класс для обработки ошибок шагов pipeline.
274
+
275
+ #### Пример
276
+ ```js
277
+ import { ErrorHandler } from 'rest-pipeline-js';
278
+
279
+ const handler = new ErrorHandler();
280
+ const error = handler.handle(new Error('fail'), 'step1');
281
+ console.log(error); // { type: 'unknown', error: [Error], stageKey: 'step1' }
169
282
  ```
170
283
 
171
- ## API
284
+ #### Типы и интерфейсы:
285
+
286
+ - **HttpConfig** — конфигурация REST клиента (baseURL, timeout, headers, retry, cache, rateLimit, metrics)
287
+ - **ApiError** — описание ошибки API
288
+ - **ApiResponse<T>** — ответ API (данные, ошибка, статус)
289
+ - **PipelineConfig, PipelineResult, PipelineStepEvent, PipelineStepStatus** — описание pipeline и шагов
290
+
291
+ ---
292
+
172
293
 
173
- ### Конструктор
294
+ ### Расширение для Vue
174
295
 
175
- ```javascript
176
- new Pipeline(config)
296
+ #### Пример: использование во Vue компоненте
297
+
298
+ ```js
299
+ <script setup>
300
+ import { ref } from 'vue';
301
+ import { PipelineOrchestrator } from 'rest-pipeline-js';
302
+ import { usePipelineProgress, usePipelineRun } from 'rest-pipeline-js/vue';
303
+
304
+ const pipelineConfig = { steps: [/* ... */] };
305
+ const httpConfig = { baseURL: 'https://api.example.com' };
306
+ const orchestrator = new PipelineOrchestrator(pipelineConfig, httpConfig);
307
+
308
+ const progress = usePipelineProgress(orchestrator);
309
+ const { run, running, result, error } = usePipelineRun(orchestrator);
310
+ </script>
311
+
312
+ <template>
313
+ <div>
314
+ <div>Текущий шаг: {{ progress.value.currentStage }}</div>
315
+ <button @click="run()" :disabled="running">Старт</button>
316
+ <div v-if="result">Готово: {{ result }}</div>
317
+ <div v-if="error">Ошибка: {{ error.message }}</div>
318
+ </div>
319
+ </template>
177
320
  ```
178
321
 
179
- **Параметры:**
180
- - `config` (Object) - Объект конфигурации
181
- - `baseURL` (String) - Базовый URL для всех запросов
182
- - `timeout` (Number) - Таймаут запроса в миллисекундах
183
- - `headers` (Object) - Заголовки по умолчанию
322
+ ---
323
+
324
+ Экспортируются composition-функции для интеграции rest-pipeline-js с Vue 3:
325
+
326
+ - **usePipelineProgress(orchestrator)** реактивный прогресс pipeline (Ref<PipelineProgress>)
327
+ - **usePipelineRun(orchestrator)** — запуск pipeline и реактивные статусы (run, running, result, error)
328
+ - **usePipelineStepEvent(orchestrator, stepKey, eventType)** — подписка на события шага (успех, ошибка, прогресс)
329
+ - **usePipelineLogs(orchestrator)** — реактивные логи pipeline
330
+ - **useRerunPipelineStep(orchestrator)** — функция для повторного запуска шага
331
+ - **useRestClient(config)** — реактивный REST клиент (computed)
184
332
 
185
- ### Методы
333
+ ---
186
334
 
187
- #### `get(url, config)`
188
- Выполняет GET запрос.
189
335
 
190
- #### `post(url, data, config)`
191
- Выполняет POST запрос.
336
+ ### Расширение для React
192
337
 
193
- #### `put(url, data, config)`
194
- Выполняет PUT запрос.
338
+ #### Пример: использование в React компоненте
339
+
340
+ ```jsx
341
+ import React from 'react';
342
+ import { PipelineOrchestrator } from 'rest-pipeline-js';
343
+ import { usePipelineProgress, usePipelineRun } from 'rest-pipeline-js/react';
344
+
345
+ const pipelineConfig = { steps: [/* ... */] };
346
+ const httpConfig = { baseURL: 'https://api.example.com' };
347
+ const orchestrator = new PipelineOrchestrator(pipelineConfig, httpConfig);
348
+
349
+ export function PipelineComponent() {
350
+ const progress = usePipelineProgress(orchestrator);
351
+ const [run, { running, result, error }] = usePipelineRun(orchestrator);
352
+
353
+ return (
354
+ <div>
355
+ <div>Текущий шаг: {progress.currentStage}</div>
356
+ <button onClick={() => run()} disabled={running}>Старт</button>
357
+ {result && <div>Готово: {JSON.stringify(result)}</div>}
358
+ {error && <div>Ошибка: {error.message}</div>}
359
+ </div>
360
+ );
361
+ }
362
+ ```
195
363
 
196
- #### `delete(url, config)`
197
- Выполняет DELETE запрос.
364
+ ---
198
365
 
199
- #### `patch(url, data, config)`
200
- Выполняет PATCH запрос.
366
+ Экспортируются хуки для интеграции rest-pipeline-js с React:
201
367
 
202
- ## Особенности
368
+ - **usePipelineProgress(orchestrator)** — подписка на прогресс pipeline (PipelineProgress)
369
+ - **usePipelineRun(orchestrator)** — запуск pipeline и статусы ([run, { running, result, error }])
370
+ - **usePipelineStepEvent(orchestrator, stepKey, eventType)** — подписка на события шага (success/error/progress)
371
+ - **usePipelineLogs(orchestrator)** — подписка на логи pipeline
372
+ - **useRerunPipelineStep(orchestrator)** — функция для повторного запуска шага
373
+ - **useRestClient(config)** — мемоизированный REST клиент
203
374
 
204
- - ✅ Поддержка Promise и async/await
205
- - ✅ Автоматическая обработка JSON
206
- - ✅ Настраиваемые заголовки
207
- - ✅ Обработка ошибок
208
- - ✅ Поддержка таймаутов
209
- - ✅ Легковесная библиотека без лишних зависимостей
375
+ ---
210
376
 
211
377
  ## Требования
212
378
 
213
- - Node.js >= 12.0.0
214
- - Современный браузер с поддержкой ES6
379
+ - Node.js >= 14.0.0
380
+ - Современный браузер с поддержкой ES2020
381
+
382
+ ---
215
383
 
216
- ## Разработка
384
+ ## Разработка и вклад
217
385
 
218
386
  ```bash
219
387
  # Клонировать репозиторий
220
388
  git clone https://github.com/macrulezru/pipeline-js.git
221
-
222
- # Установить зависимости
389
+ cd pipeline-js
223
390
  npm install
224
-
225
- # Запустить тесты
226
391
  npm test
227
-
228
- # Запустить линтер
229
392
  npm run lint
230
393
  ```
231
394
 
232
- ## Вклад в проект
233
-
234
- Мы приветствуем вклад в развитие проекта! Пожалуйста:
235
-
236
- 1. Форкните репозиторий
237
- 2. Создайте ветку для вашей функции (`git checkout -b feature/amazing-feature`)
238
- 3. Закоммитьте изменения (`git commit -m 'Add some amazing feature'`)
239
- 4. Запушьте ветку (`git push origin feature/amazing-feature`)
240
- 5. Откройте Pull Request
395
+ ---
241
396
 
242
397
  ## Лицензия
243
398
 
244
399
  MIT
245
400
 
401
+ ---
402
+
246
403
  ## Автор
247
404
 
248
- Git [macrulezru](https://github.com/macrulezru)
249
- Сайт [macrulez.ru](https://macrulez.ru/)
405
+ GitHub: [macrulezru](https://github.com/macrulezru)
406
+ Сайт: [macrulez.ru](https://macrulez.ru/)
407
+
408
+ ---
250
409
 
251
410
  ## Поддержка
252
411
 
253
- Если у вас возникли вопросы или проблемы, пожалуйста, создайте [issue](https://github.com/macrulezru/pipeline-js/issues) в репозитории.
412
+ Вопросы и баги через [issue](https://github.com/macrulezru/pipeline-js/issues)