@leanmcp/utils 0.1.4 → 0.1.5-alpha.3.0eaae8f
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 +55 -43
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
src="https://raw.githubusercontent.com/LeanMCP/leanmcp-sdk/refs/heads/main/assets/logo.png"
|
|
4
4
|
alt="LeanMCP Logo"
|
|
5
5
|
width="400"
|
|
6
|
+
|
|
6
7
|
/>
|
|
7
8
|
</p>
|
|
8
9
|
|
|
@@ -27,6 +28,10 @@
|
|
|
27
28
|
<a href="https://x.com/LeanMcp">
|
|
28
29
|
<img src="https://img.shields.io/badge/@LeanMCP-f5f5f5?logo=x&logoColor=000000" />
|
|
29
30
|
</a>
|
|
31
|
+
<a href="https://leanmcp.com/">
|
|
32
|
+
<img src="https://img.shields.io/badge/Website-leanmcp-0A66C2?" />
|
|
33
|
+
</a>
|
|
34
|
+
<a href="https://deepwiki.com/LeanMCP/leanmcp-sdk"><img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki"></a>
|
|
30
35
|
</p>
|
|
31
36
|
|
|
32
37
|
## Features
|
|
@@ -50,30 +55,34 @@ npm install @leanmcp/utils
|
|
|
50
55
|
|
|
51
56
|
Format data based on specified format type.
|
|
52
57
|
|
|
53
|
-
|
|
54
|
-
import { formatResponse } from
|
|
58
|
+
````typescript
|
|
59
|
+
import { formatResponse } from '@leanmcp/utils';
|
|
55
60
|
|
|
56
61
|
// JSON formatting
|
|
57
|
-
const json = formatResponse({ hello:
|
|
62
|
+
const json = formatResponse({ hello: 'world' }, 'json');
|
|
58
63
|
// Output: '{\n "hello": "world"\n}'
|
|
59
64
|
|
|
60
65
|
// Markdown formatting
|
|
61
|
-
const md = formatResponse({ hello:
|
|
66
|
+
const md = formatResponse({ hello: 'world' }, 'markdown');
|
|
62
67
|
// Output: '```json\n{\n "hello": "world"\n}\n```'
|
|
63
68
|
|
|
64
69
|
// HTML formatting
|
|
65
|
-
const html = formatResponse({ hello:
|
|
70
|
+
const html = formatResponse({ hello: 'world' }, 'html');
|
|
66
71
|
// Output: '<pre>{\n "hello": "world"\n}</pre>'
|
|
67
72
|
|
|
68
73
|
// Table formatting (for arrays)
|
|
69
|
-
const table = formatResponse(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
74
|
+
const table = formatResponse(
|
|
75
|
+
[
|
|
76
|
+
{ name: 'Alice', age: 30 },
|
|
77
|
+
{ name: 'Bob', age: 25 },
|
|
78
|
+
],
|
|
79
|
+
'table'
|
|
80
|
+
);
|
|
73
81
|
// Output: Markdown table format
|
|
74
|
-
|
|
82
|
+
````
|
|
75
83
|
|
|
76
84
|
**Supported formats:**
|
|
85
|
+
|
|
77
86
|
- `json` - Pretty-printed JSON
|
|
78
87
|
- `markdown` - JSON wrapped in markdown code block
|
|
79
88
|
- `html` - JSON wrapped in HTML pre tag
|
|
@@ -85,11 +94,11 @@ const table = formatResponse([
|
|
|
85
94
|
Format array of objects as a Markdown table.
|
|
86
95
|
|
|
87
96
|
```typescript
|
|
88
|
-
import { formatAsTable } from
|
|
97
|
+
import { formatAsTable } from '@leanmcp/utils';
|
|
89
98
|
|
|
90
99
|
const data = [
|
|
91
|
-
{ name:
|
|
92
|
-
{ name:
|
|
100
|
+
{ name: 'Alice', age: 30, city: 'NYC' },
|
|
101
|
+
{ name: 'Bob', age: 25, city: 'LA' },
|
|
93
102
|
];
|
|
94
103
|
|
|
95
104
|
const table = formatAsTable(data);
|
|
@@ -107,7 +116,7 @@ console.log(table);
|
|
|
107
116
|
Deep merge multiple objects.
|
|
108
117
|
|
|
109
118
|
```typescript
|
|
110
|
-
import { deepMerge } from
|
|
119
|
+
import { deepMerge } from '@leanmcp/utils';
|
|
111
120
|
|
|
112
121
|
const target = { a: 1, b: { c: 2 } };
|
|
113
122
|
const source1 = { b: { d: 3 } };
|
|
@@ -122,12 +131,12 @@ const result = deepMerge(target, source1, source2);
|
|
|
122
131
|
Check if value is a plain object.
|
|
123
132
|
|
|
124
133
|
```typescript
|
|
125
|
-
import { isObject } from
|
|
134
|
+
import { isObject } from '@leanmcp/utils';
|
|
126
135
|
|
|
127
|
-
isObject({});
|
|
128
|
-
isObject([]);
|
|
129
|
-
isObject(null);
|
|
130
|
-
isObject(
|
|
136
|
+
isObject({}); // true
|
|
137
|
+
isObject([]); // false
|
|
138
|
+
isObject(null); // false
|
|
139
|
+
isObject('string'); // false
|
|
131
140
|
```
|
|
132
141
|
|
|
133
142
|
### Async Utilities
|
|
@@ -137,7 +146,7 @@ isObject("string"); // false
|
|
|
137
146
|
Retry a function with exponential backoff.
|
|
138
147
|
|
|
139
148
|
```typescript
|
|
140
|
-
import { retry } from
|
|
149
|
+
import { retry } from '@leanmcp/utils';
|
|
141
150
|
|
|
142
151
|
// Retry API call up to 3 times
|
|
143
152
|
const result = await retry(
|
|
@@ -147,14 +156,15 @@ const result = await retry(
|
|
|
147
156
|
return response.json();
|
|
148
157
|
},
|
|
149
158
|
{
|
|
150
|
-
maxRetries: 3,
|
|
151
|
-
delayMs: 1000,
|
|
152
|
-
backoff: 2
|
|
159
|
+
maxRetries: 3, // Maximum number of retries
|
|
160
|
+
delayMs: 1000, // Initial delay in milliseconds
|
|
161
|
+
backoff: 2, // Backoff multiplier (2^n)
|
|
153
162
|
}
|
|
154
163
|
);
|
|
155
164
|
```
|
|
156
165
|
|
|
157
166
|
**Retry logic:**
|
|
167
|
+
|
|
158
168
|
- Attempt 1: Immediate
|
|
159
169
|
- Attempt 2: Wait 1000ms
|
|
160
170
|
- Attempt 3: Wait 2000ms
|
|
@@ -165,10 +175,10 @@ const result = await retry(
|
|
|
165
175
|
Async sleep function.
|
|
166
176
|
|
|
167
177
|
```typescript
|
|
168
|
-
import { sleep } from
|
|
178
|
+
import { sleep } from '@leanmcp/utils';
|
|
169
179
|
|
|
170
|
-
await sleep(1000);
|
|
171
|
-
console.log(
|
|
180
|
+
await sleep(1000); // Wait 1 second
|
|
181
|
+
console.log('1 second later');
|
|
172
182
|
```
|
|
173
183
|
|
|
174
184
|
#### timeout(promise, ms)
|
|
@@ -176,12 +186,12 @@ console.log("1 second later");
|
|
|
176
186
|
Add timeout to a promise.
|
|
177
187
|
|
|
178
188
|
```typescript
|
|
179
|
-
import { timeout } from
|
|
189
|
+
import { timeout } from '@leanmcp/utils';
|
|
180
190
|
|
|
181
191
|
try {
|
|
182
192
|
const result = await timeout(
|
|
183
193
|
fetch('https://slow-api.example.com'),
|
|
184
|
-
5000
|
|
194
|
+
5000 // 5 second timeout
|
|
185
195
|
);
|
|
186
196
|
} catch (error) {
|
|
187
197
|
console.log('Request timed out');
|
|
@@ -193,19 +203,21 @@ try {
|
|
|
193
203
|
### Formatting API Responses
|
|
194
204
|
|
|
195
205
|
```typescript
|
|
196
|
-
import { formatResponse } from
|
|
206
|
+
import { formatResponse } from '@leanmcp/utils';
|
|
197
207
|
|
|
198
208
|
class DataService {
|
|
199
209
|
@Tool({ description: 'Get user data' })
|
|
200
210
|
async getUsers() {
|
|
201
211
|
const users = await fetchUsers();
|
|
202
|
-
|
|
212
|
+
|
|
203
213
|
// Return as formatted table
|
|
204
214
|
return {
|
|
205
|
-
content: [
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
215
|
+
content: [
|
|
216
|
+
{
|
|
217
|
+
type: 'text',
|
|
218
|
+
text: formatResponse(users, 'table'),
|
|
219
|
+
},
|
|
220
|
+
],
|
|
209
221
|
};
|
|
210
222
|
}
|
|
211
223
|
}
|
|
@@ -214,17 +226,17 @@ class DataService {
|
|
|
214
226
|
### Resilient API Calls
|
|
215
227
|
|
|
216
228
|
```typescript
|
|
217
|
-
import { retry } from
|
|
229
|
+
import { retry } from '@leanmcp/utils';
|
|
218
230
|
|
|
219
231
|
class ExternalService {
|
|
220
232
|
@Tool({ description: 'Fetch external data' })
|
|
221
233
|
async fetchData(input: { url: string }) {
|
|
222
234
|
// Automatically retry failed requests
|
|
223
|
-
const data = await retry(
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
);
|
|
227
|
-
|
|
235
|
+
const data = await retry(() => fetch(input.url).then((r) => r.json()), {
|
|
236
|
+
maxRetries: 3,
|
|
237
|
+
delayMs: 1000,
|
|
238
|
+
});
|
|
239
|
+
|
|
228
240
|
return { data };
|
|
229
241
|
}
|
|
230
242
|
}
|
|
@@ -233,16 +245,16 @@ class ExternalService {
|
|
|
233
245
|
### Deep Configuration Merging
|
|
234
246
|
|
|
235
247
|
```typescript
|
|
236
|
-
import { deepMerge } from
|
|
248
|
+
import { deepMerge } from '@leanmcp/utils';
|
|
237
249
|
|
|
238
250
|
const defaultConfig = {
|
|
239
251
|
server: { port: 3000, host: 'localhost' },
|
|
240
|
-
logging: { level: 'info' }
|
|
252
|
+
logging: { level: 'info' },
|
|
241
253
|
};
|
|
242
254
|
|
|
243
255
|
const userConfig = {
|
|
244
256
|
server: { port: 4000 },
|
|
245
|
-
features: { auth: true }
|
|
257
|
+
features: { auth: true },
|
|
246
258
|
};
|
|
247
259
|
|
|
248
260
|
const config = deepMerge(defaultConfig, userConfig);
|