@embed-ai/sdk 0.1.0
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/LICENSE +27 -0
- package/README.md +347 -0
- package/package.json +30 -0
- package/src/client.d.ts +165 -0
- package/src/client.d.ts.map +1 -0
- package/src/client.js +306 -0
- package/src/client.js.map +1 -0
- package/src/feed/feed.d.ts +6 -0
- package/src/feed/feed.d.ts.map +1 -0
- package/src/feed/feed.js +34 -0
- package/src/feed/feed.js.map +1 -0
- package/src/feed/index.d.ts +4 -0
- package/src/feed/index.d.ts.map +1 -0
- package/src/feed/index.js +39 -0
- package/src/feed/index.js.map +1 -0
- package/src/feed/management.d.ts +7 -0
- package/src/feed/management.d.ts.map +1 -0
- package/src/feed/management.js +79 -0
- package/src/feed/management.js.map +1 -0
- package/src/feed/namespace.d.ts +138 -0
- package/src/feed/namespace.d.ts.map +1 -0
- package/src/feed/namespace.js +164 -0
- package/src/feed/namespace.js.map +1 -0
- package/src/index.d.ts +5 -0
- package/src/index.d.ts.map +1 -0
- package/src/index.js +50 -0
- package/src/index.js.map +1 -0
- package/src/interfaces/http.d.ts +10 -0
- package/src/interfaces/http.d.ts.map +1 -0
- package/src/interfaces/http.js +6 -0
- package/src/interfaces/http.js.map +1 -0
- package/src/interfaces/index.d.ts +2 -0
- package/src/interfaces/index.d.ts.map +1 -0
- package/src/interfaces/index.js +17 -0
- package/src/interfaces/index.js.map +1 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.src.tsbuildinfo +1 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
Copyright (c) 2025-present ZKAI Labs Pte. Ltd.
|
|
2
|
+
|
|
3
|
+
All rights reserved.
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted
|
|
6
|
+
provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this list of
|
|
9
|
+
conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice, this list of
|
|
12
|
+
conditions and the following disclaimer in the documentation and/or other materials
|
|
13
|
+
provided with the distribution.
|
|
14
|
+
|
|
15
|
+
3. Neither the name of the copyright holder nor the names of its contributors may
|
|
16
|
+
be used to endorse or promote products derived from this software without specific prior
|
|
17
|
+
written permission.
|
|
18
|
+
|
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
|
20
|
+
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
21
|
+
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
22
|
+
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
23
|
+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
24
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
25
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
26
|
+
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
27
|
+
POSSIBILITY OF SUCH DAMAGE.
|
package/README.md
ADDED
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
# Embed TypeScript
|
|
2
|
+
|
|
3
|
+
The core TypeScript package for embed APIs, featuring an Effect-based HTTP client with robust error handling and configurable retry logic for mbd.xyz API.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🚀 **Effect-based HTTP client** with structured error handling
|
|
8
|
+
- 🔄 **Configurable retry logic** with exponential backoff
|
|
9
|
+
- 🛡️ **Type-safe error handling** with tagged error types
|
|
10
|
+
- ⏱️ **Request timeouts** with proper timeout handling
|
|
11
|
+
- 🔐 **Automatic authentication** with Bearer tokens
|
|
12
|
+
- 📝 **All required headers** set automatically
|
|
13
|
+
- 📊 **Built-in logging** of failed requests and retries
|
|
14
|
+
- 🎯 **Selective retry logic** for different error types
|
|
15
|
+
|
|
16
|
+
## Quick Start
|
|
17
|
+
|
|
18
|
+
### Basic Usage
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import { getClient } from "@embed-ai/sdk"
|
|
22
|
+
const client = getClient(process.env.API_KEY_EMBED)
|
|
23
|
+
const feed = await client.feed.byUserId("16085")
|
|
24
|
+
console.log("✅ Success we got:", feed.length, "items")
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Error Handling Guide
|
|
28
|
+
|
|
29
|
+
The @embed-ai/sdk package provides comprehensive error handling with typed errors and automatic retries. Here's everything you need to know.
|
|
30
|
+
|
|
31
|
+
### What Gets Retried Automatically
|
|
32
|
+
|
|
33
|
+
- ✅ **Network errors** (connection failures, DNS issues)
|
|
34
|
+
- ✅ **Timeout errors** (requests taking too long)
|
|
35
|
+
- ✅ **Server errors** (500, 502, 503, 504 by default)
|
|
36
|
+
- ✅ **Rate limiting** (429 when configured)
|
|
37
|
+
- ❌ **Parse errors** (malformed JSON responses)
|
|
38
|
+
- ❌ **Client errors** (4xx except when configured)
|
|
39
|
+
|
|
40
|
+
### Basic Error Handling
|
|
41
|
+
|
|
42
|
+
For simple applications, basic try/catch is sufficient:
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
import { getClient } from "@embed-ai/sdk"
|
|
46
|
+
|
|
47
|
+
const client = getClient(process.env.API_KEY_EMBED)
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
const feed = await client.feed.byUserId("16085")
|
|
51
|
+
return feed
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.error("API request failed:", error)
|
|
54
|
+
throw error // Re-throw or handle as needed
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Understanding Error Types
|
|
59
|
+
|
|
60
|
+
The package exports four specific error types for structured error handling:
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import {
|
|
64
|
+
HttpRequestError, // HTTP response errors (4xx, 5xx)
|
|
65
|
+
NetworkError, // Network connection issues
|
|
66
|
+
TimeoutError, // Request timeout errors
|
|
67
|
+
ParseError // JSON parsing errors
|
|
68
|
+
} from "@embed-ai/sdk"
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Each error type contains rich information to help you understand and handle the issue:
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
// HttpRequestError - HTTP response errors
|
|
75
|
+
{
|
|
76
|
+
status: 401, // HTTP status code
|
|
77
|
+
statusText: "Unauthorized", // Status text
|
|
78
|
+
url: "https://api.mbd.xyz/...", // Request URL
|
|
79
|
+
body: "Invalid API key" // Response body (if available)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// NetworkError - Connection issues
|
|
83
|
+
{
|
|
84
|
+
message: "Failed to fetch", // Error description
|
|
85
|
+
cause: Error // Original error
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// TimeoutError - Request timeouts
|
|
89
|
+
{
|
|
90
|
+
message: "Request timed out", // Error description
|
|
91
|
+
timeoutMs: 30000 // Timeout duration
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ParseError - JSON parsing issues
|
|
95
|
+
{
|
|
96
|
+
message: "Failed to parse JSON", // Error description
|
|
97
|
+
cause: SyntaxError // Original parsing error
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Basic Usage with Error Handling
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
import { getClient, HttpRequestError, NetworkError, TimeoutError } from "@embed-ai/sdk"
|
|
105
|
+
|
|
106
|
+
const client = getClient(process.env.API_KEY_EMBED)
|
|
107
|
+
|
|
108
|
+
try {
|
|
109
|
+
const feed = await client.feed.byUserId("16085")
|
|
110
|
+
console.log("✅ Success:", feed.length, "items")
|
|
111
|
+
} catch (error) {
|
|
112
|
+
console.error("❌ Error:", error)
|
|
113
|
+
|
|
114
|
+
// Handle specific error types
|
|
115
|
+
if (error instanceof HttpRequestError) {
|
|
116
|
+
console.error(`HTTP ${error.status}: ${error.statusText}`)
|
|
117
|
+
} else if (error instanceof NetworkError) {
|
|
118
|
+
console.error("Network connection failed")
|
|
119
|
+
} else if (error instanceof TimeoutError) {
|
|
120
|
+
console.error(`Request timed out after ${error.timeoutMs}ms`)
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Typed Error Handling
|
|
126
|
+
|
|
127
|
+
For production applications, use typed error handling for better control:
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
import {
|
|
131
|
+
getClient,
|
|
132
|
+
HttpRequestError,
|
|
133
|
+
NetworkError,
|
|
134
|
+
TimeoutError,
|
|
135
|
+
ParseError
|
|
136
|
+
} from "@embed-ai/sdk"
|
|
137
|
+
|
|
138
|
+
const client = getClient(process.env.API_KEY_EMBED)
|
|
139
|
+
|
|
140
|
+
async function getFeedWithErrorHandling(userId: string) {
|
|
141
|
+
try {
|
|
142
|
+
return await client.feed.byUserId(userId)
|
|
143
|
+
} catch (error) {
|
|
144
|
+
if (error instanceof HttpRequestError) {
|
|
145
|
+
switch (error.status) {
|
|
146
|
+
case 401:
|
|
147
|
+
throw new Error("Invalid API key - please check your credentials")
|
|
148
|
+
case 403:
|
|
149
|
+
throw new Error("Access denied - check your API permissions")
|
|
150
|
+
case 404:
|
|
151
|
+
throw new Error("User not found")
|
|
152
|
+
case 429:
|
|
153
|
+
throw new Error("Rate limit exceeded - please try again later")
|
|
154
|
+
case 500:
|
|
155
|
+
case 502:
|
|
156
|
+
case 503:
|
|
157
|
+
case 504:
|
|
158
|
+
throw new Error("Server error - please try again later")
|
|
159
|
+
default:
|
|
160
|
+
throw new Error(`HTTP error ${error.status}: ${error.statusText}`)
|
|
161
|
+
}
|
|
162
|
+
} else if (error instanceof NetworkError) {
|
|
163
|
+
throw new Error("Network connection failed - check your internet connection")
|
|
164
|
+
} else if (error instanceof TimeoutError) {
|
|
165
|
+
throw new Error(`Request timed out after ${error.timeoutMs}ms`)
|
|
166
|
+
} else if (error instanceof ParseError) {
|
|
167
|
+
throw new Error("Invalid response from server")
|
|
168
|
+
} else {
|
|
169
|
+
throw new Error("Unknown error occurred")
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Custom Retry Configuration
|
|
176
|
+
|
|
177
|
+
Configure retry behavior for your specific needs:
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
import { getClient } from "@embed-ai/sdk"
|
|
181
|
+
|
|
182
|
+
const client = getClient(process.env.API_KEY_EMBED, {
|
|
183
|
+
retry: {
|
|
184
|
+
maxRetries: 5, // Max retry attempts
|
|
185
|
+
initialDelay: 1000, // Initial delay in ms
|
|
186
|
+
exponentialBackoff: true, // Use exponential backoff
|
|
187
|
+
maxDelay: 15000, // Max delay between retries
|
|
188
|
+
retryableStatusCodes: [429, 500, 502, 503, 504], // HTTP codes to retry
|
|
189
|
+
timeoutMs: 60000 // Request timeout in ms
|
|
190
|
+
}
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
// Now all requests will use this retry configuration
|
|
194
|
+
const feed = await client.feed.byWalletAddress("0x123...")
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### What Happens When Retries Fail
|
|
198
|
+
|
|
199
|
+
When all retry attempts are exhausted, you receive the **last error that occurred** with full context:
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
try {
|
|
203
|
+
const feed = await client.feed.byUserId("16085")
|
|
204
|
+
} catch (error) {
|
|
205
|
+
// This error represents the final failure after all retries
|
|
206
|
+
if (error instanceof HttpRequestError) {
|
|
207
|
+
console.error(`Final HTTP error after retries: ${error.status}`)
|
|
208
|
+
console.error(`Request URL: ${error.url}`)
|
|
209
|
+
console.error(`Response body: ${error.body}`)
|
|
210
|
+
} else if (error instanceof NetworkError) {
|
|
211
|
+
console.error(`Final network error after retries: ${error.message}`)
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
**Error Flow:**
|
|
217
|
+
1. **Request made** → Network fails
|
|
218
|
+
2. **Retry 1** → Network fails
|
|
219
|
+
3. **Retry 2** → Network fails
|
|
220
|
+
4. **Retry 3** → Network fails
|
|
221
|
+
5. **Final error** → `NetworkError` with original failure details
|
|
222
|
+
|
|
223
|
+
### Error Handling Best Practices
|
|
224
|
+
|
|
225
|
+
#### 1. **Use Typed Error Handling in Production**
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
// ✅ Good - Specific error handling
|
|
229
|
+
try {
|
|
230
|
+
const feed = await client.feed.byUserId(userId)
|
|
231
|
+
} catch (error) {
|
|
232
|
+
if (error instanceof HttpRequestError) {
|
|
233
|
+
// Handle specific HTTP errors
|
|
234
|
+
} else if (error instanceof NetworkError) {
|
|
235
|
+
// Handle network issues
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// ❌ Avoid - Generic error handling
|
|
240
|
+
try {
|
|
241
|
+
const feed = await client.feed.byUserId(userId)
|
|
242
|
+
} catch (error) {
|
|
243
|
+
console.error("Something went wrong:", error) // Too generic
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
#### 2. **Provide User-Friendly Error Messages**
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
function getUserFriendlyError(error: unknown): string {
|
|
251
|
+
if (error instanceof HttpRequestError) {
|
|
252
|
+
switch (error.status) {
|
|
253
|
+
case 401: return "Please check your API key"
|
|
254
|
+
case 429: return "Too many requests - please wait a moment"
|
|
255
|
+
case 500: return "Server is temporarily unavailable"
|
|
256
|
+
default: return "Something went wrong with the request"
|
|
257
|
+
}
|
|
258
|
+
} else if (error instanceof NetworkError) {
|
|
259
|
+
return "Please check your internet connection"
|
|
260
|
+
} else if (error instanceof TimeoutError) {
|
|
261
|
+
return "Request took too long - please try again"
|
|
262
|
+
}
|
|
263
|
+
return "An unexpected error occurred"
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
#### 3. **Implement Fallback Strategies**
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
async function getFeedWithFallback(userId: string) {
|
|
271
|
+
try {
|
|
272
|
+
return await client.feed.byUserId(userId)
|
|
273
|
+
} catch (error) {
|
|
274
|
+
if (error instanceof HttpRequestError && error.status === 404) {
|
|
275
|
+
// User not found - return empty feed
|
|
276
|
+
return []
|
|
277
|
+
} else if (error instanceof NetworkError || error instanceof TimeoutError) {
|
|
278
|
+
// Network issues - return cached data if available
|
|
279
|
+
return getCachedFeed(userId) || []
|
|
280
|
+
}
|
|
281
|
+
throw error // Re-throw other errors
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
#### 4. **Log Errors for Monitoring**
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
import { getClient, HttpRequestError } from "@embed-ai/sdk"
|
|
290
|
+
|
|
291
|
+
const client = getClient(process.env.API_KEY_EMBED)
|
|
292
|
+
|
|
293
|
+
async function getFeedWithLogging(userId: string) {
|
|
294
|
+
try {
|
|
295
|
+
return await client.feed.byUserId(userId)
|
|
296
|
+
} catch (error) {
|
|
297
|
+
// Log error details for monitoring
|
|
298
|
+
if (error instanceof HttpRequestError) {
|
|
299
|
+
console.error("API Error:", {
|
|
300
|
+
status: error.status,
|
|
301
|
+
url: error.url,
|
|
302
|
+
userId,
|
|
303
|
+
timestamp: new Date().toISOString()
|
|
304
|
+
})
|
|
305
|
+
}
|
|
306
|
+
throw error
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
## API Methods
|
|
312
|
+
|
|
313
|
+
### Available Methods
|
|
314
|
+
|
|
315
|
+
```typescript
|
|
316
|
+
// Get personalized "For You" feed by user ID
|
|
317
|
+
await client.feed.byUserId(userId: string, options?: FeedOptions)
|
|
318
|
+
|
|
319
|
+
// Get personalized "For You" feed by wallet address
|
|
320
|
+
await client.feed.byWalletAddress(walletAddress: string, options?: FeedOptions)
|
|
321
|
+
|
|
322
|
+
// Feed management to create new feeds and manage these custom feeds e.g. as custom feed per user in your app, which can be built on top of base feeds
|
|
323
|
+
await client.feed.createConfig(options: CreateFeedOptions)
|
|
324
|
+
await client.feed.getConfig(configId: string)
|
|
325
|
+
await client.feed.listConfigs(visibility?: "private" | "public")
|
|
326
|
+
await client.feed.updateConfig(options: UpdateFeedOptions)
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### Factory Function
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
import { getClient } from "@embed-ai/sdk"
|
|
333
|
+
|
|
334
|
+
// Create client with factory function
|
|
335
|
+
const client = getClient(process.env.API_KEY_EMBED, {
|
|
336
|
+
retry: { maxRetries: 5 }
|
|
337
|
+
})
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
## Why Effect?
|
|
342
|
+
|
|
343
|
+
- **Structured Error Handling**: Type-safe error channels prevent runtime surprises
|
|
344
|
+
- **Composable**: Chain and combine operations with powerful combinators
|
|
345
|
+
- **Reliable**: Automatic retries handle transient failures gracefully
|
|
346
|
+
- **Observable**: Built-in logging and tracing for debugging
|
|
347
|
+
- **Type-Safe**: Full TypeScript support with inferred types
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@embed-ai/sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"license": "BSD-3-Clause",
|
|
6
|
+
"description": "The typescript sdk package for embed AI APIs.",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/ZKAI-Network/embed-sdk/",
|
|
10
|
+
"directory": "packages/sdk"
|
|
11
|
+
},
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public",
|
|
14
|
+
"directory": "dist"
|
|
15
|
+
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "bun run build-esm && bun run build-annotate && bun run build-cjs && cp package.json README.md LICENSE dist/ && bun run fix-deps",
|
|
18
|
+
"build-esm": "tsc --project tsconfig.build.json --noEmit && tsc --project tsconfig.src.json",
|
|
19
|
+
"build-cjs": "babel dist --plugins @babel/transform-export-namespace-from --plugins @babel/transform-modules-commonjs --out-dir dist --source-maps",
|
|
20
|
+
"build-annotate": "babel dist --plugins annotate-pure-calls --out-dir dist --source-maps",
|
|
21
|
+
"fix-deps": "bun scripts/fix-deps.js",
|
|
22
|
+
"check": "tsc -b tsconfig.json",
|
|
23
|
+
"test": "vitest",
|
|
24
|
+
"coverage": "vitest --coverage"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@embed-ai/types": "^0.1.0",
|
|
28
|
+
"effect": "latest"
|
|
29
|
+
}
|
|
30
|
+
}
|
package/src/client.d.ts
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { FeedNamespace } from "./feed/namespace.js";
|
|
2
|
+
declare const NetworkError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & {
|
|
3
|
+
readonly _tag: "NetworkError";
|
|
4
|
+
} & Readonly<A>;
|
|
5
|
+
/**
|
|
6
|
+
* Network-related errors (connection issues, DNS failures, etc.)
|
|
7
|
+
*/
|
|
8
|
+
export declare class NetworkError extends NetworkError_base<{
|
|
9
|
+
readonly message: string;
|
|
10
|
+
readonly cause?: unknown;
|
|
11
|
+
}> {
|
|
12
|
+
}
|
|
13
|
+
declare const HttpRequestError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & {
|
|
14
|
+
readonly _tag: "HttpRequestError";
|
|
15
|
+
} & Readonly<A>;
|
|
16
|
+
/**
|
|
17
|
+
* HTTP response errors (4xx, 5xx status codes)
|
|
18
|
+
*/
|
|
19
|
+
export declare class HttpRequestError extends HttpRequestError_base<{
|
|
20
|
+
readonly status: number;
|
|
21
|
+
readonly statusText: string;
|
|
22
|
+
readonly url: string;
|
|
23
|
+
readonly body?: string;
|
|
24
|
+
}> {
|
|
25
|
+
}
|
|
26
|
+
declare const ParseError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & {
|
|
27
|
+
readonly _tag: "ParseError";
|
|
28
|
+
} & Readonly<A>;
|
|
29
|
+
/**
|
|
30
|
+
* JSON parsing errors
|
|
31
|
+
*/
|
|
32
|
+
export declare class ParseError extends ParseError_base<{
|
|
33
|
+
readonly message: string;
|
|
34
|
+
readonly cause?: unknown;
|
|
35
|
+
}> {
|
|
36
|
+
}
|
|
37
|
+
declare const TimeoutError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => import("effect/Cause").YieldableError & {
|
|
38
|
+
readonly _tag: "TimeoutError";
|
|
39
|
+
} & Readonly<A>;
|
|
40
|
+
/**
|
|
41
|
+
* Timeout errors
|
|
42
|
+
*/
|
|
43
|
+
export declare class TimeoutError extends TimeoutError_base<{
|
|
44
|
+
readonly message: string;
|
|
45
|
+
readonly timeoutMs: number;
|
|
46
|
+
}> {
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Union of all possible HTTP client errors
|
|
50
|
+
*/
|
|
51
|
+
export type HttpClientError = NetworkError | HttpRequestError | ParseError | TimeoutError;
|
|
52
|
+
/**
|
|
53
|
+
* Configuration for retry behavior
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```typescript
|
|
57
|
+
* const client = getClient('your-api-key', {
|
|
58
|
+
* retry: {
|
|
59
|
+
* maxRetries: 5,
|
|
60
|
+
* initialDelay: 1000,
|
|
61
|
+
* exponentialBackoff: true,
|
|
62
|
+
* timeoutMs: 30000
|
|
63
|
+
* }
|
|
64
|
+
* })
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export interface RetryConfig {
|
|
68
|
+
/** Maximum number of retry attempts (default: 3) */
|
|
69
|
+
readonly maxRetries?: number;
|
|
70
|
+
/** Initial delay between retries in milliseconds (default: 1000) */
|
|
71
|
+
readonly initialDelay?: number;
|
|
72
|
+
/** Whether to use exponential backoff (default: true) */
|
|
73
|
+
readonly exponentialBackoff?: boolean;
|
|
74
|
+
/** Maximum delay between retries in milliseconds (default: 10000) */
|
|
75
|
+
readonly maxDelay?: number;
|
|
76
|
+
/** HTTP status codes that should trigger a retry (default: [500, 502, 503, 504]) */
|
|
77
|
+
readonly retryableStatusCodes?: ReadonlyArray<number>;
|
|
78
|
+
/** Request timeout in milliseconds (default: 30000) */
|
|
79
|
+
readonly timeoutMs?: number;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Configuration for the Embed API client
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* const client = getClient('your-api-key', {
|
|
87
|
+
* title: 'my-app',
|
|
88
|
+
* retry: {
|
|
89
|
+
* maxRetries: 3,
|
|
90
|
+
* timeoutMs: 30000
|
|
91
|
+
* }
|
|
92
|
+
* })
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
export interface mbdClientConfig {
|
|
96
|
+
/** Base URL for the API (default: https://api.mbd.xyz) */
|
|
97
|
+
readonly baseUrl?: string;
|
|
98
|
+
/** API token for authentication */
|
|
99
|
+
readonly token?: string;
|
|
100
|
+
/** HTTP referer header value */
|
|
101
|
+
readonly referer?: string;
|
|
102
|
+
/** Application title for tracking (default: embed_sdk_typescript) */
|
|
103
|
+
readonly title?: string;
|
|
104
|
+
/** Retry configuration */
|
|
105
|
+
readonly retry?: RetryConfig;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Main Embed API client providing access to personalized feeds and feed management
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```typescript
|
|
112
|
+
* import { getClient } from '@embed-ai/sdk'
|
|
113
|
+
*
|
|
114
|
+
* const client = getClient('your-api-key')
|
|
115
|
+
*
|
|
116
|
+
* // Get personalized feed
|
|
117
|
+
* const feed = await client.feed.byUserId('16085')
|
|
118
|
+
*
|
|
119
|
+
* // Create a custom feed
|
|
120
|
+
* const customFeed = await client.feed.createConfig({
|
|
121
|
+
* name: 'My Custom Feed',
|
|
122
|
+
* description: 'A feed for my app'
|
|
123
|
+
* })
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
126
|
+
export declare class mbdClient {
|
|
127
|
+
private http;
|
|
128
|
+
readonly feed: FeedNamespace;
|
|
129
|
+
constructor(token?: string, options?: mbdClientConfig);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Get a new Embed Client instance
|
|
133
|
+
*
|
|
134
|
+
* @param token - API token required for authentication
|
|
135
|
+
* @param options - Optional client configuration
|
|
136
|
+
* @returns Embed Client instance with namespaced methods
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```typescript
|
|
140
|
+
* import { getClient } from '@embed-ai/sdk'
|
|
141
|
+
*
|
|
142
|
+
* // Basic usage
|
|
143
|
+
* const client = getClient('your-api-key')
|
|
144
|
+
*
|
|
145
|
+
* // Get personalized feed
|
|
146
|
+
* const feed = await client.feed.byUserId('16085')
|
|
147
|
+
*
|
|
148
|
+
* // Create a custom feed
|
|
149
|
+
* const customFeed = await client.feed.createConfig({
|
|
150
|
+
* name: 'My Custom Feed',
|
|
151
|
+
* description: 'A feed for my app'
|
|
152
|
+
* })
|
|
153
|
+
*
|
|
154
|
+
* // With configuration
|
|
155
|
+
* const client = getClient('your-api-key', {
|
|
156
|
+
* retry: {
|
|
157
|
+
* maxRetries: 3,
|
|
158
|
+
* timeoutMs: 30000
|
|
159
|
+
* }
|
|
160
|
+
* })
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
export declare function getClient(token?: string, options?: mbdClientConfig): mbdClient;
|
|
164
|
+
export {};
|
|
165
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;;;;AAOnD;;GAEG;AACH,qBAAa,YAAa,SAAQ,kBAAiC;IACjE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CACzB,CAAC;CAAG;;;;AAEL;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,sBAAqC;IACzE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CACvB,CAAC;CAAG;;;;AAEL;;GAEG;AACH,qBAAa,UAAW,SAAQ,gBAA+B;IAC7D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CACzB,CAAC;CAAG;;;;AAEL;;GAEG;AACH,qBAAa,YAAa,SAAQ,kBAAiC;IACjE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC3B,CAAC;CAAG;AAEL;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,YAAY,GAAG,gBAAgB,GAAG,UAAU,GAAG,YAAY,CAAA;AAMzF;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,WAAW;IAC1B,oDAAoD;IACpD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,oEAAoE;IACpE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B,yDAAyD;IACzD,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAA;IACrC,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,oFAAoF;IACpF,QAAQ,CAAC,oBAAoB,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACrD,uDAAuD;IACvD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B;AAkBD;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,eAAe;IAC9B,0DAA0D;IAC1D,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,mCAAmC;IACnC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,gCAAgC;IAChC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,qEAAqE;IACrE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,0BAA0B;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAA;CAC7B;AA+PD;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,IAAI,CAAY;IACxB,SAAgB,IAAI,EAAE,aAAa,CAAA;gBAEvB,KAAK,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe;CAatD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAE9E"}
|