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