@yetter/client 0.0.11 → 0.0.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 +70 -15
- package/bowow2.jpeg +0 -0
- package/dist/api.d.ts +13 -1
- package/dist/api.js +40 -0
- package/dist/client.d.ts +53 -1
- package/dist/client.js +298 -44
- package/dist/index.d.ts +1 -0
- package/dist/types.d.ts +60 -0
- package/examples/submit.ts +1 -1
- package/examples/subscribe.ts +1 -1
- package/examples/upload-and-generate.ts +39 -0
- package/package.json +4 -2
- package/src/api.ts +54 -0
- package/src/client.ts +404 -45
- package/src/index.ts +10 -1
- package/src/types.ts +76 -0
package/README.md
CHANGED
|
@@ -44,7 +44,7 @@ This function submits an image generation request and long-polls for the result.
|
|
|
44
44
|
|
|
45
45
|
**Features:**
|
|
46
46
|
- Submits a generation request.
|
|
47
|
-
- Polls for status updates until the job is "COMPLETED" or "
|
|
47
|
+
- Polls for status updates until the job is "COMPLETED" or "ERROR".
|
|
48
48
|
- Timeout after 30 minutes, with an attempt to cancel the job.
|
|
49
49
|
- Optional `onQueueUpdate` callback for real-time feedback on queue position and status.
|
|
50
50
|
- Optional `logs` flag to include logs in status updates.
|
|
@@ -71,7 +71,7 @@ async function main() {
|
|
|
71
71
|
update.logs.map((log) => log.message).forEach(logMessage => console.log(` - ${logMessage}`));
|
|
72
72
|
} else if (update.status === "COMPLETED") {
|
|
73
73
|
console.log("Processing completed!");
|
|
74
|
-
} else if (update.status === "
|
|
74
|
+
} else if (update.status === "ERROR") {
|
|
75
75
|
console.error("Processing failed. Logs:", update.logs);
|
|
76
76
|
}
|
|
77
77
|
},
|
|
@@ -95,18 +95,18 @@ main();
|
|
|
95
95
|
This function submits an image generation request and returns an async iterable stream of events using Server-Sent Events (SSE). This allows for real-time updates on the job's progress, status, and logs.
|
|
96
96
|
|
|
97
97
|
**Features:**
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
98
|
+
|
|
99
|
+
* Initiates a request and establishes an SSE connection.
|
|
100
|
+
* Provides an `AsyncIterator` (`Symbol.asyncIterator`) to loop through status events (`StreamEvent`).
|
|
101
|
+
* A `done()` method: Returns a Promise that resolves with the final `GetResponseResponse` **after the server emits `event: done`** (successful completion), or rejects if the server emits `event: error` or the final response cannot be fetched.
|
|
102
|
+
* A `cancel()` method: Requests cancellation on the backend; the stream naturally ends when the server emits `data` (with `status: "CANCELLED"`) followed by `event: done`.
|
|
103
|
+
* A `getRequestId()` method: Returns the request ID for the stream.
|
|
103
104
|
|
|
104
105
|
**Events (`StreamEvent`):**
|
|
105
106
|
Each event pushed by the stream is an object typically including:
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
- Other model-specific data.
|
|
107
|
+
|
|
108
|
+
* `status`: Current status (e.g., `"IN_QUEUE"`, `"IN_PROGRESS"`, `"COMPLETED"`, `"CANCELLED"`, `"ERROR"`).
|
|
109
|
+
* Other model-specific data.
|
|
110
110
|
|
|
111
111
|
**Example (from `examples/stream.ts`):**
|
|
112
112
|
|
|
@@ -127,9 +127,11 @@ async function main() {
|
|
|
127
127
|
streamRequestId = streamInstance.getRequestId();
|
|
128
128
|
console.log(`Stream initiated for Request ID: ${streamRequestId}`);
|
|
129
129
|
|
|
130
|
-
// Iterate over stream events
|
|
130
|
+
// Iterate over stream events (informational; termination is driven by server 'done'/'error' events)
|
|
131
131
|
for await (const event of streamInstance) {
|
|
132
|
-
console.log(
|
|
132
|
+
console.log(
|
|
133
|
+
`[STREAM EVENT - ${streamRequestId}] Status: ${event.status}, QPos: ${event.queue_position}`
|
|
134
|
+
);
|
|
133
135
|
if (event.logs && event.logs.length > 0) {
|
|
134
136
|
console.log(` Logs for ${streamRequestId}:`);
|
|
135
137
|
event.logs.forEach(log => console.log(` - ${log.message}`));
|
|
@@ -137,7 +139,7 @@ async function main() {
|
|
|
137
139
|
}
|
|
138
140
|
console.log(`Stream for ${streamRequestId} finished iterating events.`);
|
|
139
141
|
|
|
140
|
-
//
|
|
142
|
+
// Final result becomes available after server emits `event: done`
|
|
141
143
|
const result = await streamInstance.done();
|
|
142
144
|
console.log("\n--- Stream Test Final Result ---");
|
|
143
145
|
console.log("Generated Images:", result.images);
|
|
@@ -215,7 +217,7 @@ async function main() {
|
|
|
215
217
|
console.log("Image Data:", finalResult.data.images);
|
|
216
218
|
success = true;
|
|
217
219
|
break;
|
|
218
|
-
} else if (currentStatus === "
|
|
220
|
+
} else if (currentStatus === "ERROR") {
|
|
219
221
|
console.error(`Request ${request_id} FAILED. Logs:`, statusResult.data.logs);
|
|
220
222
|
break;
|
|
221
223
|
}
|
|
@@ -231,6 +233,59 @@ async function main() {
|
|
|
231
233
|
main();
|
|
232
234
|
```
|
|
233
235
|
|
|
236
|
+
### 4. Uploading Input Images
|
|
237
|
+
|
|
238
|
+
For models that require an input image (e.g., image-to-image, style transfer), you can upload your image using `yetter.uploadFile()` (Node.js) or `yetter.uploadBlob()` (browser).
|
|
239
|
+
|
|
240
|
+
**Features:**
|
|
241
|
+
- Support for both Node.js filesystem paths and browser File/Blob objects
|
|
242
|
+
- Automatic single-part or multipart upload based on file size
|
|
243
|
+
- Progress tracking with optional callback
|
|
244
|
+
- Returns a public URL to use in generation requests
|
|
245
|
+
|
|
246
|
+
#### Node.js Example
|
|
247
|
+
|
|
248
|
+
```typescript
|
|
249
|
+
import { yetter } from "@yetter/client";
|
|
250
|
+
|
|
251
|
+
yetter.configure({ apiKey: process.env.YTR_API_KEY });
|
|
252
|
+
|
|
253
|
+
// Upload image
|
|
254
|
+
const uploadResult = await yetter.uploadFile("./input-image.jpg", {
|
|
255
|
+
onProgress: (percent) => console.log(`Upload: ${percent}%`),
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
// Use in generation
|
|
259
|
+
const result = await yetter.subscribe("ytr-ai/model/i2i", {
|
|
260
|
+
input: {
|
|
261
|
+
prompt: "Transform to anime style",
|
|
262
|
+
input_image_url: uploadResult.url,
|
|
263
|
+
},
|
|
264
|
+
});
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
#### Browser Example
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
// HTML: <input type="file" id="imageInput" accept="image/*">
|
|
271
|
+
|
|
272
|
+
const fileInput = document.getElementById('imageInput') as HTMLInputElement;
|
|
273
|
+
fileInput.addEventListener('change', async () => {
|
|
274
|
+
const file = fileInput.files![0];
|
|
275
|
+
|
|
276
|
+
const uploadResult = await yetter.uploadBlob(file, {
|
|
277
|
+
onProgress: (pct) => updateProgressBar(pct),
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
console.log("Uploaded:", uploadResult.url);
|
|
281
|
+
});
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
**Upload Options:**
|
|
285
|
+
- `onProgress?: (progress: number) => void` - Progress callback (0-100)
|
|
286
|
+
- `timeout?: number` - Timeout in milliseconds (default: 5 minutes)
|
|
287
|
+
- `filename?: string` - Custom filename (browser uploads)
|
|
288
|
+
|
|
234
289
|
## Error Handling
|
|
235
290
|
|
|
236
291
|
The client functions generally throw errors for API issues, network problems, or failed generation requests. Ensure you wrap API calls in `try...catch` blocks to handle potential errors gracefully. Specific error messages or details (like logs for failed jobs) are often included in the thrown error object or the final status response.
|
package/bowow2.jpeg
ADDED
|
Binary file
|
package/dist/api.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ClientOptions, GenerateRequest, GenerateResponse, GetStatusRequest, GetStatusResponse, CancelRequest, CancelResponse, GetResponseRequest, GetResponseResponse } from "./types";
|
|
1
|
+
import { ClientOptions, GenerateRequest, GenerateResponse, GetStatusRequest, GetStatusResponse, CancelRequest, CancelResponse, GetResponseRequest, GetResponseResponse, GetUploadUrlRequest, GetUploadUrlResponse, UploadCompleteRequest, UploadCompleteResponse } from "./types";
|
|
2
2
|
export declare class YetterImageClient {
|
|
3
3
|
private apiKey;
|
|
4
4
|
private endpoint;
|
|
@@ -8,4 +8,16 @@ export declare class YetterImageClient {
|
|
|
8
8
|
getStatus(body: GetStatusRequest): Promise<GetStatusResponse>;
|
|
9
9
|
cancel(body: CancelRequest): Promise<CancelResponse>;
|
|
10
10
|
getResponse(body: GetResponseRequest): Promise<GetResponseResponse>;
|
|
11
|
+
/**
|
|
12
|
+
* Request presigned URL(s) for file upload
|
|
13
|
+
* @param body Upload request parameters
|
|
14
|
+
* @returns Presigned URL response with mode (single/multipart)
|
|
15
|
+
*/
|
|
16
|
+
getUploadUrl(body: GetUploadUrlRequest): Promise<GetUploadUrlResponse>;
|
|
17
|
+
/**
|
|
18
|
+
* Notify server that upload is complete
|
|
19
|
+
* @param body Completion request with S3 key
|
|
20
|
+
* @returns Uploaded file metadata with public URL
|
|
21
|
+
*/
|
|
22
|
+
uploadComplete(body: UploadCompleteRequest): Promise<UploadCompleteResponse>;
|
|
11
23
|
}
|
package/dist/api.js
CHANGED
|
@@ -72,4 +72,44 @@ export class YetterImageClient {
|
|
|
72
72
|
}
|
|
73
73
|
return (await res.json());
|
|
74
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Request presigned URL(s) for file upload
|
|
77
|
+
* @param body Upload request parameters
|
|
78
|
+
* @returns Presigned URL response with mode (single/multipart)
|
|
79
|
+
*/
|
|
80
|
+
async getUploadUrl(body) {
|
|
81
|
+
const res = await fetch(`${this.endpoint}/uploads`, {
|
|
82
|
+
method: "POST",
|
|
83
|
+
headers: {
|
|
84
|
+
"Content-Type": "application/json",
|
|
85
|
+
Authorization: this.apiKey,
|
|
86
|
+
},
|
|
87
|
+
body: JSON.stringify(body),
|
|
88
|
+
});
|
|
89
|
+
if (!res.ok) {
|
|
90
|
+
const errorText = await res.text();
|
|
91
|
+
throw new Error(`Upload URL request failed (${res.status}): ${errorText}`);
|
|
92
|
+
}
|
|
93
|
+
return (await res.json());
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Notify server that upload is complete
|
|
97
|
+
* @param body Completion request with S3 key
|
|
98
|
+
* @returns Uploaded file metadata with public URL
|
|
99
|
+
*/
|
|
100
|
+
async uploadComplete(body) {
|
|
101
|
+
const res = await fetch(`${this.endpoint}/uploads/complete`, {
|
|
102
|
+
method: "POST",
|
|
103
|
+
headers: {
|
|
104
|
+
"Content-Type": "application/json",
|
|
105
|
+
Authorization: this.apiKey,
|
|
106
|
+
},
|
|
107
|
+
body: JSON.stringify(body),
|
|
108
|
+
});
|
|
109
|
+
if (!res.ok) {
|
|
110
|
+
const errorText = await res.text();
|
|
111
|
+
throw new Error(`Upload completion failed (${res.status}): ${errorText}`);
|
|
112
|
+
}
|
|
113
|
+
return (await res.json());
|
|
114
|
+
}
|
|
75
115
|
}
|
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ClientOptions, GetResponseResponse, SubscribeOptions, GenerateResponse, SubmitQueueOptions, GetResultOptions, GetResultResponse, StatusOptions, StatusResponse, StreamOptions, YetterStream } from "./types.js";
|
|
1
|
+
import { ClientOptions, GetResponseResponse, SubscribeOptions, GenerateResponse, SubmitQueueOptions, GetResultOptions, GetResultResponse, StatusOptions, StatusResponse, StreamOptions, YetterStream, UploadOptions, UploadCompleteResponse } from "./types.js";
|
|
2
2
|
export declare class yetter {
|
|
3
3
|
private static apiKey;
|
|
4
4
|
private static endpoint;
|
|
@@ -10,4 +10,56 @@ export declare class yetter {
|
|
|
10
10
|
result: (model: string, options: GetResultOptions) => Promise<GetResultResponse>;
|
|
11
11
|
};
|
|
12
12
|
static stream(model: string, options: StreamOptions): Promise<YetterStream>;
|
|
13
|
+
/**
|
|
14
|
+
* Upload a file from the filesystem (Node.js) or File/Blob object (browser)
|
|
15
|
+
*
|
|
16
|
+
* @param fileOrPath File path (Node.js) or File/Blob object (browser)
|
|
17
|
+
* @param options Upload configuration options
|
|
18
|
+
* @returns Promise resolving to upload result with public URL
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* // Node.js
|
|
23
|
+
* const result = await yetter.uploadFile("/path/to/image.jpg", {
|
|
24
|
+
* onProgress: (pct) => console.log(`Upload: ${pct}%`)
|
|
25
|
+
* });
|
|
26
|
+
*
|
|
27
|
+
* // Browser
|
|
28
|
+
* const fileInput = document.querySelector('input[type="file"]');
|
|
29
|
+
* const file = fileInput.files[0];
|
|
30
|
+
* const result = await yetter.uploadFile(file, {
|
|
31
|
+
* onProgress: (pct) => updateProgressBar(pct)
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
static uploadFile(fileOrPath: string | File | Blob, options?: UploadOptions): Promise<UploadCompleteResponse>;
|
|
36
|
+
/**
|
|
37
|
+
* Upload a file from browser (File or Blob object)
|
|
38
|
+
* This is an alias for uploadFile for better clarity in browser contexts
|
|
39
|
+
*/
|
|
40
|
+
static uploadBlob(file: File | Blob, options?: UploadOptions): Promise<UploadCompleteResponse>;
|
|
41
|
+
/**
|
|
42
|
+
* Upload file from filesystem path (Node.js only)
|
|
43
|
+
*/
|
|
44
|
+
private static _uploadFromPath;
|
|
45
|
+
/**
|
|
46
|
+
* Upload file from Blob/File object (browser)
|
|
47
|
+
*/
|
|
48
|
+
private static _uploadFromBlob;
|
|
49
|
+
/**
|
|
50
|
+
* Upload file using single PUT request (Node.js, private helper)
|
|
51
|
+
*/
|
|
52
|
+
private static _uploadFileSingle;
|
|
53
|
+
/**
|
|
54
|
+
* Upload file using multipart upload (Node.js, private helper)
|
|
55
|
+
*/
|
|
56
|
+
private static _uploadFileMultipart;
|
|
57
|
+
/**
|
|
58
|
+
* Upload blob using single PUT request (browser, private helper)
|
|
59
|
+
*/
|
|
60
|
+
private static _uploadBlobSingle;
|
|
61
|
+
/**
|
|
62
|
+
* Upload blob using multipart upload (browser, private helper)
|
|
63
|
+
*/
|
|
64
|
+
private static _uploadBlobMultipart;
|
|
13
65
|
}
|