@emanuelepifani/nexo-client 0.2.0 → 0.3.9

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.
Files changed (2) hide show
  1. package/README.md +10 -172
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # Nexo Client SDK
2
2
 
3
- High-performance TypeScript client for [Nexo](https://github.com/emanuel-epifani/nexo).
3
+ High-performance TypeScript client for [Nexo](https://nexo-docs-hub.vercel.app/).
4
+
5
+
4
6
 
5
7
  ## Quick Start
6
8
 
@@ -49,94 +51,6 @@ await mailQ.subscribe((msg) => console.log(msg));
49
51
  await mailQ.delete();
50
52
  ```
51
53
 
52
- <details>
53
- <summary><strong>Advanced Features (Persistence, Retry, Delay, Priority, DLQ)</strong></summary>
54
-
55
- ```typescript
56
- // -------------------------------------------------------------
57
- // 1. CREATION (Default behavior for all messages in this queue)
58
- // -------------------------------------------------------------
59
- interface CriticalTask { type: string; payload: any; }
60
-
61
- const criticalQueue = await client.queue<CriticalTask>('critical-tasks').create({
62
- // RELIABILITY:
63
- visibilityTimeoutMs: 10000, // Retry delivery if not ACKed within 10s (default=30s)
64
- maxRetries: 5, // Move to DLQ after 5 failures (default=5)
65
- ttlMs: 60000, // Message expires if not consumed in 60s (default=7days)
66
-
67
- // PERSISTENCE:
68
- // - 'file_sync': Save every message (Safest, Slowest)
69
- // - 'file_async': Flush periodically (Fast & Durable) -
70
- // DEFAULT: 'file_async': Flush every 50ms or 5000 msgs
71
- persistence: 'file_sync',
72
- });
73
-
74
-
75
- // ---------------------------------------------------------
76
- // 2. PRODUCING (Override specific behaviors per message)
77
- // ---------------------------------------------------------
78
-
79
- // PRIORITY: Higher value (255) delivered before lower values (0)
80
- // This message jumps ahead of all priority < 255 messages sent previously and still not consumed.
81
- await criticalQueue.push({ type: 'urgent' }, { priority: 255 });
82
-
83
- // SCHEDULING: Delay visibility
84
- // This message is hidden for 1 hour (default delayMs: 0, instant)
85
- await criticalQueue.push({ type: 'scheduled' }, { delayMs: 3600000 });
86
-
87
-
88
-
89
- // ---------------------------------------------------------
90
- // 3. CONSUMING (Worker Tuning to optimize throughput and latency)
91
- // ---------------------------------------------------------
92
- await criticalQueue.subscribe(
93
- async (task) => { await processTask(task); },
94
- {
95
- batchSize: 100, // Network: Fetch 100 messages in one request
96
- concurrency: 10, // Local: Process 10 messages concurrently (useful for I/O tasks)
97
- waitMs: 5000 // Polling: If empty, wait 5s for new messages before retrying
98
- }
99
- );
100
-
101
- // ---------------------------------------------------------
102
- // 4. DEAD LETTER QUEUE (DLQ) - Failed Message Management
103
- // ---------------------------------------------------------
104
-
105
- // DLQ is automatically available for every main queue.
106
- // When messages exceed maxRetries, they're moved to DLQ automatically
107
-
108
- // Inspect failed messages
109
- const failedMessages = await criticalQueue.dlq.peek(10);
110
- console.log(`Found ${failedMessages.total} failed messages`);
111
-
112
- for (const msg of failedMessages.items) {
113
- console.log(`Message ${msg.id}: attempts=${msg.attempts}, reason=${msg.failureReason}`);
114
- console.log(`Payload:`, msg.data);
115
-
116
- // Decision logic based on failure reason
117
- if (shouldRetry(msg.data)) {
118
- // Replay: Move back to main queue (resets attempts to 0)
119
- // The message will be immediately available for consumption
120
- const moved = await criticalQueue.dlq.moveToQueue(msg.id);
121
- console.log(`Replayed message ${msg.id}: ${moved}`);
122
- } else {
123
- // Discard: Permanently delete from DLQ
124
- const deleted = await criticalQueue.dlq.delete(msg.id);
125
- console.log(`Deleted message ${msg.id}: ${deleted}`);
126
- }
127
- }
128
-
129
- // Bulk operations
130
- const purgedCount = await criticalQueue.dlq.purge(); // Clear all DLQ messages
131
- console.log(`Purged ${purgedCount} messages from DLQ`);
132
-
133
- // DLQ API:
134
- // - peek(limit, offset): Inspect messages without removing them. Returns { total, items: [] }
135
- // - moveToQueue(messageId): Replay a specific message (returns false if not found)
136
- // - delete(messageId): Permanently remove a specific message (returns false if not found)
137
- // - purge(): Remove all messages (returns count)
138
- ```
139
- </details>
140
54
 
141
55
  ### 3. PUB/SUB
142
56
 
@@ -149,35 +63,6 @@ await alerts.subscribe((msg) => console.log(msg));
149
63
  await alerts.publish({ level: "high" });
150
64
  ```
151
65
 
152
- <details>
153
- <summary><strong>Wildcards & Retained Messages</strong></summary>
154
-
155
- ```typescript
156
- // WILDCARD SUBSCRIPTIONS
157
- // ----------------------
158
-
159
- // 1. Single-Level Wildcard (+)
160
- // Matches: 'home/kitchen/light', 'home/garage/light'
161
- const roomLights = client.pubsub<LightStatus>('home/+/light');
162
- await roomLights.subscribe((status) => console.log('Light is:', status.state));
163
-
164
- // 2. Multi-Level Wildcard (#)
165
- // Matches all topics under 'sensors/'
166
- const allSensors = client.pubsub<SensorData>('sensors/#');
167
- await allSensors.subscribe((data) => console.log('Sensor value:', data.value));
168
-
169
- // PUBLISHING (No wildcards allowed!)
170
- // ---------------------------------
171
- // You must publish to concrete topics with matching types
172
- await client.pubsub<LightStatus>('home/kitchen/light').publish({ state: 'ON' });
173
- await client.pubsub<SensorData>('sensors/kitchen/temp').publish({ value: 22.5, unit: 'C' });
174
-
175
- // RETAINED MESSAGES
176
- // -----------------
177
- // Last value is stored and immediately sent to new subscribers
178
- await client.pubsub<string>('config/theme').publish('dark', { retain: true });
179
- ```
180
- </details>
181
66
 
182
67
  ### 4. STREAM
183
68
 
@@ -192,56 +77,11 @@ await stream.subscribe('analytics', (msg) => {console.log(`User ${msg.userId} pe
192
77
  await stream.delete();
193
78
  ```
194
79
 
195
- <details>
196
- <summary><strong>Advanced Features (Consumer Groups, Persistence, Retention)</strong></summary>
197
-
198
- ```typescript
199
- // ---------------------------------------------------------
200
- // 1. STREAM CREATION & POLICY
201
- // ---------------------------------------------------------
202
- const orders = await client.stream<Order>('orders').create({
203
- // SCALING
204
- partitions: 4, // Max concurrent consumers per group on same topic (default=8)
205
-
206
- // PERSISTENCE:
207
- // - 'file_sync': Save every message (Safest, Slowest)
208
- // - 'file_async': Flush periodically (Fast & Durable) -
209
- // DEFAULT: 'file_async': Flush every 50ms or 5000 msgs
210
- persistence: 'file_sync',
211
-
212
- // RETENTION (Cleanup Policy)
213
- // --------------------------
214
- // Delete old data when EITHER limit is reached:
215
- retention: {
216
- maxAgeMs: 86400000, // 1 Day (Default: 7 Days)
217
- maxBytes: 536870912 // 512 MB (Default: 1 GB)
218
- },
219
- });
220
-
221
- // ---------------------------------------------------------
222
- // 2. CONSUMING (Scaling & Broadcast patterns)
223
- // ---------------------------------------------------------
224
-
225
- // SCALING (Microservices Replicas / K8s Pods)
226
- // Same Group ('workers') -> Automatic Load Balancing & Rebalancing
227
- // Partitions are distributed among workers.
228
- await orders.subscribe('workers', (order) => process(order));
229
- await orders.subscribe('workers', (order) => process(order));
230
-
231
-
232
- // BROADCAST (Independent Domains)
233
- // Different Groups -> Each group gets a full copy of the stream.
234
- // Useful for independent services reacting to the same event.
235
- await orders.subscribe('analytics', (order) => trackMetrics(order));
236
- await orders.subscribe('audit-log', (order) => saveAudit(order));
237
- ```
238
- </details>
239
-
240
80
 
241
81
 
242
82
  ---
243
83
 
244
- ### Binary Payloads (Zero-Overhead)
84
+ ### Binary Payloads
245
85
 
246
86
  All Nexo brokers (**Store, Queue, Stream, PubSub**) natively support raw binary data (`Buffer`).
247
87
  Bypassing JSON serialization drastically reduces Latency, increases Throughput, and saves Bandwidth.
@@ -252,13 +92,13 @@ Bypassing JSON serialization drastically reduces Latency, increases Throughput,
252
92
  // Send 1MB raw buffer (30% smaller than JSON/Base64)
253
93
  const heavyPayload = Buffer.alloc(1024 * 1024);
254
94
 
255
- // 1. STREAM: Replayable Data (e.g. CCTV Recording, Event Sourcing)
95
+ // 1. STREAM
256
96
  await client.stream('cctv-archive').publish(heavyPayload);
257
- // 2. PUBSUB: Ephemeral Live Data (e.g. VoIP, Real-time Sensor)
97
+ // 2. PUBSUB
258
98
  await client.pubsub('live-audio-call').publish(heavyPayload);
259
- // 3. STORE (Cache Images)
99
+ // 3. STORE
260
100
  await client.store.map.set('user:avatar:1', heavyPayload);
261
- // 4. QUEUE (Process Files)
101
+ // 4. QUEUE
262
102
  await client.queue('pdf-processing').push(heavyPayload);
263
103
  ```
264
104
 
@@ -271,10 +111,8 @@ MIT
271
111
 
272
112
  ## Links
273
113
 
274
- - **Nexo Broker (Server):** [GitHub Repository](https://github.com/emanuel-epifani/nexo)
275
- - **Server Docs:** [Nexo Internals & Architecture](https://github.com/emanuel-epifani/nexo/tree/main/docs)
276
- - **SDK Source:** [sdk/ts](https://github.com/emanuel-epifani/nexo/tree/main/sdk/ts)
277
- - **Docker Image:** [emanuelepifani/nexo](https://hub.docker.com/r/emanuelepifani/nexo)
114
+ - **📚 Full Documentation:** [Nexo Docs](https://nexo-docs-hub.vercel.app/)
115
+ - **🐳 Docker Image:** [emanuelepifani/nexo](https://hub.docker.com/r/emanuelepifani/nexo)
278
116
 
279
117
  ## Author
280
118
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@emanuelepifani/nexo-client",
3
- "version": "0.2.0",
3
+ "version": "0.3.9",
4
4
  "description": "High-performance TypeScript Client for Nexo Broker",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",