rest-pipeline-js 1.3.11 → 1.3.12

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
@@ -84,7 +84,7 @@ npm install react@>=19 react-dom@>=19
84
84
 
85
85
  ## Demo
86
86
 
87
- A live interactive demo of the pipeline running against a real flight-search API 4 sequential stages: airport lookup, availability, ancillary services, and seat map.
87
+ A multi-scenario interactive demo showcasing the key features of `rest-pipeline-js`. All demos use real public REST APIs.
88
88
 
89
89
  ```bash
90
90
  git clone https://github.com/macrulezru/pipeline-js.git
@@ -93,7 +93,14 @@ npm install
93
93
  npm run demo:vue
94
94
  ```
95
95
 
96
- Opens at `http://localhost:3000` (or the next available port). Click **Run Pipeline** to execute all stages and watch results appear in real time. A boarding pass is rendered when all stages succeed.
96
+ Opens at `http://localhost:3000`. The demo app lives in the `demo/` directory.
97
+
98
+ | Demo | What it shows |
99
+ |---|---|
100
+ | ✈️ **Flight Pipeline** | 4-stage sequential pipeline with `sharedData`, `pauseBefore`/`pauseAfter`, middleware, boarding pass result |
101
+ | 🔀 **Parallel Loading** | `pipe()` fluent builder with `.parallel([])` — 3 sources queried simultaneously, timing breakdown |
102
+ | 🛡️ **Retry & Recovery** | Configurable flaky stage with exponential backoff, event log, `abort()`, pause/resume between stages |
103
+ | ⚡ **Cache & Rate Limit** | `createRestClient()` with cache TTL — see server vs cache timing; rate limiter burst visualization |
97
104
 
98
105
  ---
99
106
 
package/demo/App.vue ADDED
@@ -0,0 +1,122 @@
1
+ <script setup lang="ts">
2
+ import { ref, shallowRef, defineAsyncComponent } from "vue";
3
+
4
+ const FlightDemo = defineAsyncComponent(() => import("./views/FlightDemo.vue"));
5
+ const ParallelDemo = defineAsyncComponent(
6
+ () => import("./views/ParallelDemo.vue"),
7
+ );
8
+ const RetryDemo = defineAsyncComponent(() => import("./views/RetryDemo.vue"));
9
+ const CacheDemo = defineAsyncComponent(() => import("./views/CacheDemo.vue"));
10
+
11
+ const demos = [
12
+ {
13
+ id: "flight",
14
+ icon: "✈️",
15
+ title: "Flight Pipeline",
16
+ subtitle: "Sequential stages · sharedData",
17
+ component: FlightDemo,
18
+ },
19
+ {
20
+ id: "parallel",
21
+ icon: "🔀",
22
+ title: "Parallel Loading",
23
+ subtitle: "pipe() builder · concurrent",
24
+ component: ParallelDemo,
25
+ },
26
+ {
27
+ id: "retry",
28
+ icon: "🛡️",
29
+ title: "Retry & Recovery",
30
+ subtitle: "Backoff · abort · pause/resume",
31
+ component: RetryDemo,
32
+ },
33
+ {
34
+ id: "cache",
35
+ icon: "⚡",
36
+ title: "Cache & Rate Limit",
37
+ subtitle: "HTTP optimization · metrics",
38
+ component: CacheDemo,
39
+ },
40
+ ];
41
+
42
+ const activeId = ref("flight");
43
+ const ActiveComponent = shallowRef(FlightDemo);
44
+
45
+ function navigate(demo: (typeof demos)[number]) {
46
+ activeId.value = demo.id;
47
+ ActiveComponent.value = demo.component;
48
+ }
49
+ </script>
50
+
51
+ <template>
52
+ <div class="app-layout">
53
+ <!-- ── Sidebar ──────────────────────────────────────────── -->
54
+ <aside class="sidebar">
55
+ <div class="sidebar-logo">
56
+ <div class="sidebar-logo__icon">🚀</div>
57
+ <div class="sidebar-logo__text">
58
+ <div class="sidebar-logo__name">rest-pipeline-js</div>
59
+ <div class="sidebar-logo__sub">Interactive Demo</div>
60
+ </div>
61
+ </div>
62
+
63
+ <nav class="sidebar-nav">
64
+ <button
65
+ v-for="demo in demos"
66
+ :key="demo.id"
67
+ class="nav-item"
68
+ :class="{ 'nav-item--active': activeId === demo.id }"
69
+ @click="navigate(demo)"
70
+ >
71
+ <span class="nav-item__icon">{{ demo.icon }}</span>
72
+ <div class="nav-item__text">
73
+ <div class="nav-item__title">{{ demo.title }}</div>
74
+ <div class="nav-item__sub">{{ demo.subtitle }}</div>
75
+ </div>
76
+ </button>
77
+ </nav>
78
+
79
+ <div class="sidebar-links">
80
+ <a
81
+ href="https://github.com/macrulezru/pipeline-js"
82
+ target="_blank"
83
+ class="sidebar-link"
84
+ title="GitHub"
85
+ >
86
+ <svg width="15" height="15" viewBox="0 0 24 24" fill="currentColor">
87
+ <path
88
+ d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0 0 24 12c0-6.63-5.37-12-12-12z"
89
+ />
90
+ </svg>
91
+ GitHub
92
+ </a>
93
+ <a
94
+ href="https://www.npmjs.com/package/rest-pipeline-js"
95
+ target="_blank"
96
+ class="sidebar-link"
97
+ title="npm"
98
+ >
99
+ <svg width="15" height="15" viewBox="0 0 24 24" fill="currentColor">
100
+ <path
101
+ d="M0 0v24h24V0H0zm6.672 18.586H3.328V5.414h3.344v13.172zm7.656 0h-3.344v-9.83H7.656V5.414h10.004v13.172h-3.332v-9.83z"
102
+ />
103
+ </svg>
104
+ npm
105
+ </a>
106
+ </div>
107
+ </aside>
108
+
109
+ <!-- ── Main content ───────────────────────────────────── -->
110
+ <main class="content">
111
+ <Suspense>
112
+ <component :is="ActiveComponent" />
113
+ <template #fallback>
114
+ <div class="loading-placeholder">
115
+ <div class="loading-spinner"></div>
116
+ <span>Loading demo…</span>
117
+ </div>
118
+ </template>
119
+ </Suspense>
120
+ </main>
121
+ </div>
122
+ </template>
@@ -0,0 +1,22 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>rest-pipeline-js — Interactive Demo</title>
7
+ <link
8
+ rel="icon"
9
+ href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🚀</text></svg>"
10
+ />
11
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
12
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
13
+ <link
14
+ href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap"
15
+ rel="stylesheet"
16
+ />
17
+ </head>
18
+ <body>
19
+ <div id="app"></div>
20
+ <script type="module" src="./main.js"></script>
21
+ </body>
22
+ </html>
package/demo/main.js ADDED
@@ -0,0 +1,5 @@
1
+ import { createApp } from "vue";
2
+ import App from "./App.vue";
3
+ import "./style.css";
4
+
5
+ createApp(App).mount("#app");