@runware/sdk-js 1.1.12 → 1.1.13

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 (42) hide show
  1. package/dist/esm/Runware/Runware-base.d.ts +40 -0
  2. package/dist/esm/Runware/Runware-base.js +651 -0
  3. package/dist/esm/Runware/Runware-client.d.ts +5 -0
  4. package/dist/esm/Runware/Runware-client.js +18 -0
  5. package/dist/esm/Runware/Runware-server.d.ts +14 -0
  6. package/dist/esm/Runware/Runware-server.js +155 -0
  7. package/dist/esm/Runware/Runware.d.ts +4 -0
  8. package/dist/esm/Runware/Runware.js +13 -0
  9. package/dist/esm/Runware/async-retry.d.ts +5 -0
  10. package/dist/esm/Runware/async-retry.js +27 -0
  11. package/dist/esm/Runware/index.d.ts +4 -0
  12. package/dist/esm/Runware/index.js +20 -0
  13. package/dist/esm/Runware/reconnect.d.ts +11 -0
  14. package/dist/esm/Runware/reconnect.js +175 -0
  15. package/dist/esm/Runware/types.d.ts +244 -0
  16. package/dist/esm/Runware/types.js +84 -0
  17. package/dist/esm/Runware/utils.d.ts +45 -0
  18. package/dist/esm/Runware/utils.js +212 -0
  19. package/dist/esm/tests/Runware/enhance-prompt.test.d.ts +1 -0
  20. package/dist/esm/tests/Runware/enhance-prompt.test.js +58 -0
  21. package/dist/esm/tests/Runware/remove-image-background.test.d.ts +1 -0
  22. package/dist/esm/tests/Runware/remove-image-background.test.js +37 -0
  23. package/dist/esm/tests/Runware/request-image-to-text.test.d.ts +1 -0
  24. package/dist/esm/tests/Runware/request-image-to-text.test.js +37 -0
  25. package/dist/esm/tests/Runware/request-images.test.d.ts +1 -0
  26. package/dist/esm/tests/Runware/request-images.test.js +72 -0
  27. package/dist/esm/tests/Runware/runware-server.test.d.ts +1 -0
  28. package/dist/esm/tests/Runware/runware-server.test.js +26 -0
  29. package/dist/esm/tests/Runware/upload-image.test.d.ts +1 -0
  30. package/dist/esm/tests/Runware/upload-image.test.js +52 -0
  31. package/dist/esm/tests/Runware/upscale-gan.test.d.ts +1 -0
  32. package/dist/esm/tests/Runware/upscale-gan.test.js +41 -0
  33. package/dist/esm/tests/mockServer.d.ts +12 -0
  34. package/dist/esm/tests/mockServer.js +38 -0
  35. package/dist/esm/tests/test-utils.d.ts +39 -0
  36. package/dist/esm/tests/test-utils.js +44 -0
  37. package/dist/index.d.mts +1 -1
  38. package/dist/index.d.ts +1 -1
  39. package/dist/index.js +10 -30
  40. package/dist/index.mjs +10 -30
  41. package/package.json +1 -1
  42. package/readme.md +6 -0
@@ -0,0 +1,651 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RunwareBase = void 0;
4
+ // @ts-ignore
5
+ const async_retry_1 = require("./async-retry");
6
+ const types_1 = require("./types");
7
+ const utils_1 = require("./utils");
8
+ // let allImages: IImage[] = [];
9
+ class RunwareBase {
10
+ constructor({ apiKey, url = utils_1.BASE_RUNWARE_URLS.PRODUCTION }) {
11
+ this._listeners = [];
12
+ // _globalMessages: any[] = [];
13
+ this._globalMessages = {};
14
+ this._globalImages = [];
15
+ this.isWebsocketReadyState = () => { var _a; return ((_a = this._ws) === null || _a === void 0 ? void 0 : _a.readyState) === 1; };
16
+ // We moving to an array format, it make sense to consolidate all request to an array here
17
+ this.send = (msg) => {
18
+ this._ws.send(JSON.stringify([msg]));
19
+ };
20
+ this.uploadImage = async (file) => {
21
+ try {
22
+ return await (0, async_retry_1.asyncRetry)(async () => {
23
+ const taskUUID = (0, utils_1.getUUID)();
24
+ if (typeof file === "string" && (0, utils_1.isValidUUID)(file)) {
25
+ return {
26
+ imageURL: file,
27
+ imageUUID: file,
28
+ taskUUID,
29
+ taskType: types_1.ETaskType.IMAGE_UPLOAD,
30
+ };
31
+ }
32
+ const imageBase64 = typeof file === "string" ? file : await (0, utils_1.fileToBase64)(file);
33
+ this.send({
34
+ taskType: types_1.ETaskType.IMAGE_UPLOAD,
35
+ image: imageBase64,
36
+ taskUUID,
37
+ });
38
+ const lis = this.globalListener({
39
+ taskUUID,
40
+ });
41
+ const image = (await (0, utils_1.getIntervalWithPromise)(({ resolve, reject }) => {
42
+ const uploadedImage = this.getSingleMessage({
43
+ taskUUID,
44
+ });
45
+ if (!uploadedImage)
46
+ return;
47
+ if (uploadedImage === null || uploadedImage === void 0 ? void 0 : uploadedImage.error) {
48
+ reject(uploadedImage);
49
+ return true;
50
+ }
51
+ if (uploadedImage) {
52
+ delete this._globalMessages[taskUUID];
53
+ resolve(uploadedImage);
54
+ return true;
55
+ }
56
+ }, { debugKey: "upload-image" }));
57
+ lis.destroy();
58
+ return image;
59
+ });
60
+ }
61
+ catch (e) {
62
+ throw e;
63
+ }
64
+ };
65
+ this.controlNetPreProcess = async ({ inputImage, preProcessor, height, width, outputType, outputFormat, highThresholdCanny, lowThresholdCanny, includeHandsAndFaceOpenPose, includeCost, customTaskUUID, }) => {
66
+ try {
67
+ const image = await this.uploadImage(inputImage);
68
+ if (!(image === null || image === void 0 ? void 0 : image.imageUUID))
69
+ return null;
70
+ const taskUUID = customTaskUUID || (0, utils_1.getUUID)();
71
+ this.send(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ inputImage: image.imageUUID, taskType: types_1.ETaskType.IMAGE_CONTROL_NET_PRE_PROCESS, taskUUID,
72
+ preProcessor }, (0, utils_1.evaluateNonTrue)({ key: "height", value: height })), (0, utils_1.evaluateNonTrue)({ key: "width", value: width })), (0, utils_1.evaluateNonTrue)({ key: "outputType", value: outputType })), (0, utils_1.evaluateNonTrue)({ key: "outputFormat", value: outputFormat })), (0, utils_1.evaluateNonTrue)({ key: "includeCost", value: includeCost })), (0, utils_1.evaluateNonTrue)({
73
+ key: "highThresholdCanny",
74
+ value: highThresholdCanny,
75
+ })), (0, utils_1.evaluateNonTrue)({
76
+ key: "lowThresholdCanny",
77
+ value: lowThresholdCanny,
78
+ })), (0, utils_1.evaluateNonTrue)({
79
+ key: "includeHandsAndFaceOpenPose",
80
+ value: includeHandsAndFaceOpenPose,
81
+ })));
82
+ const lis = this.globalListener({
83
+ taskUUID,
84
+ });
85
+ const guideImage = (await (0, utils_1.getIntervalWithPromise)(({ resolve, reject }) => {
86
+ const uploadedImage = this.getSingleMessage({
87
+ taskUUID,
88
+ });
89
+ if (!uploadedImage)
90
+ return;
91
+ if (uploadedImage === null || uploadedImage === void 0 ? void 0 : uploadedImage.error) {
92
+ reject(uploadedImage);
93
+ return true;
94
+ }
95
+ if (uploadedImage) {
96
+ // delete this._globalMessages[taskUUID];
97
+ resolve(uploadedImage);
98
+ return true;
99
+ }
100
+ }, { debugKey: "unprocessed-image" }));
101
+ lis.destroy();
102
+ return guideImage;
103
+ }
104
+ catch (e) {
105
+ throw e;
106
+ }
107
+ };
108
+ this.requestImageToText = async ({ inputImage, includeCost, customTaskUUID, }) => {
109
+ try {
110
+ await this.ensureConnection();
111
+ return await (0, async_retry_1.asyncRetry)(async () => {
112
+ const imageUploaded = inputImage
113
+ ? await this.uploadImage(inputImage)
114
+ : null;
115
+ const taskUUID = customTaskUUID || (0, utils_1.getUUID)();
116
+ this.send(Object.assign({ taskUUID, taskType: types_1.ETaskType.IMAGE_CAPTION, inputImage: imageUploaded === null || imageUploaded === void 0 ? void 0 : imageUploaded.imageUUID }, (0, utils_1.evaluateNonTrue)({ key: "includeCost", value: includeCost })));
117
+ const lis = this.globalListener({
118
+ taskUUID,
119
+ });
120
+ const response = await (0, utils_1.getIntervalWithPromise)(({ resolve, reject }) => {
121
+ const newReverseClip = this.getSingleMessage({
122
+ taskUUID,
123
+ });
124
+ if (!newReverseClip)
125
+ return;
126
+ if (newReverseClip === null || newReverseClip === void 0 ? void 0 : newReverseClip.error) {
127
+ reject(newReverseClip);
128
+ return true;
129
+ }
130
+ if (newReverseClip) {
131
+ delete this._globalMessages[taskUUID];
132
+ resolve(newReverseClip);
133
+ return true;
134
+ }
135
+ }, { debugKey: "remove-image-background" });
136
+ lis.destroy();
137
+ return response;
138
+ });
139
+ }
140
+ catch (e) {
141
+ throw e;
142
+ }
143
+ };
144
+ this.removeImageBackground = async ({ inputImage, outputType, outputFormat, rgba, postProcessMask, returnOnlyMask, alphaMatting, alphaMattingForegroundThreshold, alphaMattingBackgroundThreshold, alphaMattingErodeSize, includeCost, customTaskUUID, }) => {
145
+ try {
146
+ await this.ensureConnection();
147
+ return await (0, async_retry_1.asyncRetry)(async () => {
148
+ const imageUploaded = inputImage
149
+ ? await this.uploadImage(inputImage)
150
+ : null;
151
+ const taskUUID = customTaskUUID || (0, utils_1.getUUID)();
152
+ this.send(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ taskType: types_1.ETaskType.IMAGE_BACKGROUND_REMOVAL, taskUUID, inputImage: imageUploaded === null || imageUploaded === void 0 ? void 0 : imageUploaded.imageUUID }, (0, utils_1.evaluateNonTrue)({ key: "rgba", value: rgba })), (0, utils_1.evaluateNonTrue)({
153
+ key: "postProcessMask",
154
+ value: postProcessMask,
155
+ })), (0, utils_1.evaluateNonTrue)({ key: "returnOnlyMask", value: returnOnlyMask })), (0, utils_1.evaluateNonTrue)({ key: "alphaMatting", value: alphaMatting })), (0, utils_1.evaluateNonTrue)({ key: "includeCost", value: includeCost })), (0, utils_1.evaluateNonTrue)({
156
+ key: "alphaMattingForegroundThreshold",
157
+ value: alphaMattingForegroundThreshold,
158
+ })), (0, utils_1.evaluateNonTrue)({
159
+ key: "alphaMattingBackgroundThreshold",
160
+ value: alphaMattingBackgroundThreshold,
161
+ })), (0, utils_1.evaluateNonTrue)({
162
+ key: "alphaMattingErodeSize",
163
+ value: alphaMattingErodeSize,
164
+ })), (0, utils_1.evaluateNonTrue)({ key: "outputType", value: outputType })), (0, utils_1.evaluateNonTrue)({ key: "outputFormat", value: outputFormat })));
165
+ const lis = this.globalListener({
166
+ taskUUID,
167
+ });
168
+ const response = await (0, utils_1.getIntervalWithPromise)(({ resolve, reject }) => {
169
+ const newRemoveBackground = this.getSingleMessage({ taskUUID });
170
+ if (!newRemoveBackground)
171
+ return;
172
+ if (newRemoveBackground === null || newRemoveBackground === void 0 ? void 0 : newRemoveBackground.error) {
173
+ reject(newRemoveBackground);
174
+ return true;
175
+ }
176
+ if (newRemoveBackground) {
177
+ delete this._globalMessages[taskUUID];
178
+ resolve(newRemoveBackground);
179
+ return true;
180
+ }
181
+ }, { debugKey: "remove-image-background" });
182
+ lis.destroy();
183
+ return response;
184
+ });
185
+ }
186
+ catch (e) {
187
+ throw e;
188
+ }
189
+ };
190
+ this.upscaleGan = async ({ inputImage, upscaleFactor, outputType, outputFormat, includeCost, customTaskUUID, }) => {
191
+ try {
192
+ await this.ensureConnection();
193
+ return await (0, async_retry_1.asyncRetry)(async () => {
194
+ let imageUploaded;
195
+ imageUploaded = await this.uploadImage(inputImage);
196
+ const taskUUID = customTaskUUID || (0, utils_1.getUUID)();
197
+ this.send(Object.assign(Object.assign(Object.assign({ taskUUID, inputImage: imageUploaded === null || imageUploaded === void 0 ? void 0 : imageUploaded.imageUUID, taskType: types_1.ETaskType.IMAGE_UPSCALE, upscaleFactor }, (0, utils_1.evaluateNonTrue)({ key: "includeCost", value: includeCost })), (outputType ? { outputType } : {})), (outputFormat ? { outputFormat } : {})));
198
+ const lis = this.globalListener({
199
+ taskUUID,
200
+ });
201
+ const response = await (0, utils_1.getIntervalWithPromise)(({ resolve, reject }) => {
202
+ const newUpscaleGan = this.getSingleMessage({ taskUUID });
203
+ if (!newUpscaleGan)
204
+ return;
205
+ if (newUpscaleGan === null || newUpscaleGan === void 0 ? void 0 : newUpscaleGan.error) {
206
+ reject(newUpscaleGan);
207
+ return true;
208
+ }
209
+ if (newUpscaleGan) {
210
+ delete this._globalMessages[taskUUID];
211
+ resolve(newUpscaleGan);
212
+ return true;
213
+ }
214
+ }, { debugKey: "upscale-gan" });
215
+ lis.destroy();
216
+ return response;
217
+ });
218
+ }
219
+ catch (e) {
220
+ throw e;
221
+ }
222
+ };
223
+ this.enhancePrompt = async ({ prompt, promptMaxLength = 380, promptVersions = 1, includeCost, customTaskUUID, }) => {
224
+ try {
225
+ await this.ensureConnection();
226
+ return await (0, async_retry_1.asyncRetry)(async () => {
227
+ const taskUUID = customTaskUUID || (0, utils_1.getUUID)();
228
+ this.send(Object.assign(Object.assign({ prompt,
229
+ taskUUID,
230
+ promptMaxLength,
231
+ promptVersions }, (0, utils_1.evaluateNonTrue)({ key: "includeCost", value: includeCost })), { taskType: types_1.ETaskType.PROMPT_ENHANCE }));
232
+ const lis = this.globalListener({
233
+ taskUUID,
234
+ });
235
+ const response = await (0, utils_1.getIntervalWithPromise)(({ resolve, reject }) => {
236
+ const reducedPrompt = this._globalMessages[taskUUID];
237
+ if (reducedPrompt === null || reducedPrompt === void 0 ? void 0 : reducedPrompt.error) {
238
+ reject(reducedPrompt);
239
+ return true;
240
+ }
241
+ if ((reducedPrompt === null || reducedPrompt === void 0 ? void 0 : reducedPrompt.length) >= promptVersions) {
242
+ delete this._globalMessages[taskUUID];
243
+ resolve(reducedPrompt);
244
+ return true;
245
+ }
246
+ }, { debugKey: "enhance-prompt" });
247
+ lis.destroy();
248
+ return response;
249
+ });
250
+ }
251
+ catch (e) {
252
+ throw e;
253
+ }
254
+ };
255
+ this.getSingleMessage = ({ taskUUID }) => {
256
+ var _a;
257
+ const value = this._globalMessages[taskUUID] || ((_a = this._globalMessages[taskUUID]) === null || _a === void 0 ? void 0 : _a[0]);
258
+ if (!value)
259
+ return null;
260
+ return value;
261
+ };
262
+ this.disconnect = async () => {
263
+ var _a, _b, _c, _d;
264
+ (_b = (_a = this._ws) === null || _a === void 0 ? void 0 : _a.terminate) === null || _b === void 0 ? void 0 : _b.call(_a);
265
+ (_d = (_c = this._ws) === null || _c === void 0 ? void 0 : _c.close) === null || _d === void 0 ? void 0 : _d.call(_c);
266
+ };
267
+ this.connected = () => this.isWebsocketReadyState() && !!this._connectionSessionUUID;
268
+ this._apiKey = apiKey;
269
+ this._url = url;
270
+ this._sdkType = types_1.SdkType.CLIENT;
271
+ }
272
+ // protected addListener({
273
+ // lis,
274
+ // check,
275
+ // }: {
276
+ // lis: (v: any) => any;
277
+ // check: (v: any) => any;
278
+ // groupKey?: string;
279
+ // }): { destroy: Function } {
280
+ // this._ws.onmessage = (e: any) => {
281
+ // const m = JSON.parse(e.data);
282
+ // if (m?.error) {
283
+ // lis(m);
284
+ // } else if (check(m)) {
285
+ // lis(m);
286
+ // }
287
+ // };
288
+ // return {
289
+ // destroy: () => {},
290
+ // };
291
+ // }
292
+ addListener({ lis,
293
+ // check,
294
+ groupKey, taskUUID, }) {
295
+ const listener = (msg) => {
296
+ var _a;
297
+ const arrayMessage = Array.isArray(msg === null || msg === void 0 ? void 0 : msg.data) ? msg.data : [msg.data];
298
+ const arrayErrors = Array.isArray(msg === null || msg === void 0 ? void 0 : msg.errors)
299
+ ? msg.errors
300
+ : [msg.errors];
301
+ // const filteredMessage = arrayMessage.filter(
302
+ // (v) => v?.taskType === check
303
+ // );
304
+ const filteredMessage = arrayMessage.filter((v) => ((v === null || v === void 0 ? void 0 : v.taskUUID) || (v === null || v === void 0 ? void 0 : v.taskType)) === taskUUID);
305
+ const filteredErrors = arrayErrors.filter((v) => ((v === null || v === void 0 ? void 0 : v.taskUUID) || (v === null || v === void 0 ? void 0 : v.taskType)) === taskUUID);
306
+ if (filteredErrors.length) {
307
+ lis({ error: Object.assign({}, ((_a = arrayErrors[0]) !== null && _a !== void 0 ? _a : {})) });
308
+ return;
309
+ }
310
+ if (filteredMessage.length) {
311
+ lis({ [taskUUID]: arrayMessage });
312
+ return;
313
+ }
314
+ };
315
+ const groupListener = { key: (0, utils_1.getUUID)(), listener, groupKey };
316
+ this._listeners.push(groupListener);
317
+ const destroy = () => {
318
+ this._listeners = (0, utils_1.removeListener)(this._listeners, groupListener);
319
+ };
320
+ return {
321
+ destroy,
322
+ };
323
+ }
324
+ connect() {
325
+ this._ws.onopen = (e) => {
326
+ if (this._connectionSessionUUID) {
327
+ this.send({
328
+ taskType: types_1.ETaskType.AUTHENTICATION,
329
+ apiKey: this._apiKey,
330
+ connectionSessionUUID: this._connectionSessionUUID,
331
+ });
332
+ }
333
+ else {
334
+ this.send({ apiKey: this._apiKey, taskType: types_1.ETaskType.AUTHENTICATION });
335
+ }
336
+ this.addListener({
337
+ taskUUID: types_1.ETaskType.AUTHENTICATION,
338
+ lis: (m) => {
339
+ var _a, _b;
340
+ if (m === null || m === void 0 ? void 0 : m.error) {
341
+ this._invalidAPIkey = "Invalid API key";
342
+ return;
343
+ }
344
+ this._connectionSessionUUID =
345
+ (_b = (_a = m === null || m === void 0 ? void 0 : m[types_1.ETaskType.AUTHENTICATION]) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.connectionSessionUUID;
346
+ this._invalidAPIkey = undefined;
347
+ },
348
+ });
349
+ };
350
+ this._ws.onmessage = (e) => {
351
+ var _a;
352
+ const data = JSON.parse(e.data);
353
+ for (const lis of this._listeners) {
354
+ const result = (_a = lis === null || lis === void 0 ? void 0 : lis.listener) === null || _a === void 0 ? void 0 : _a.call(lis, data);
355
+ if (result)
356
+ return;
357
+ }
358
+ };
359
+ this._ws.onclose = (e) => {
360
+ // console.log("closing");
361
+ // console.log("invalid", this._invalidAPIkey);
362
+ if (this._invalidAPIkey) {
363
+ console.error(this._invalidAPIkey);
364
+ return;
365
+ }
366
+ };
367
+ }
368
+ destroy(lis) {
369
+ (0, utils_1.removeFromAray)(this._listeners, lis);
370
+ }
371
+ listenToImages({ onPartialImages, taskUUID, groupKey, positivePrompt, negativePrompt, }) {
372
+ return this.addListener({
373
+ taskUUID: taskUUID,
374
+ lis: (m) => {
375
+ var _a, _b;
376
+ let images = (_a = m === null || m === void 0 ? void 0 : m[taskUUID]) === null || _a === void 0 ? void 0 : _a.filter((img) => img.taskUUID === taskUUID);
377
+ if (m.error) {
378
+ onPartialImages === null || onPartialImages === void 0 ? void 0 : onPartialImages(images, (m === null || m === void 0 ? void 0 : m.error) && m);
379
+ this._globalError = m;
380
+ }
381
+ else {
382
+ images = images.map((image) => (Object.assign(Object.assign({}, image), { positivePrompt,
383
+ negativePrompt })));
384
+ onPartialImages === null || onPartialImages === void 0 ? void 0 : onPartialImages(images, (m === null || m === void 0 ? void 0 : m.error) && m);
385
+ if (this._sdkType === types_1.SdkType.CLIENT) {
386
+ // this._globalImages = [...this._globalImages, ...m.images];
387
+ this._globalImages = [
388
+ ...this._globalImages,
389
+ ...((_b = m === null || m === void 0 ? void 0 : m[taskUUID]) !== null && _b !== void 0 ? _b : []).map((image) => (Object.assign(Object.assign({}, image), { positivePrompt,
390
+ negativePrompt }))),
391
+ ];
392
+ }
393
+ else {
394
+ this._globalImages = [...this._globalImages, ...images];
395
+ }
396
+ }
397
+ },
398
+ groupKey,
399
+ });
400
+ }
401
+ globalListener({ taskUUID }) {
402
+ return this.addListener({
403
+ // check: (m) => {
404
+ // const value = accessDeepObject({
405
+ // key: responseKey,
406
+ // data: m,
407
+ // useZero: false,
408
+ // });
409
+ // return !!value;
410
+ // },
411
+ // check: responseKey,
412
+ taskUUID: taskUUID,
413
+ lis: (m) => {
414
+ if (m.error) {
415
+ this._globalMessages[taskUUID] = m;
416
+ return;
417
+ }
418
+ const value = (0, utils_1.accessDeepObject)({
419
+ key: taskUUID,
420
+ data: m,
421
+ useZero: false,
422
+ });
423
+ if (Array.isArray(value)) {
424
+ value.forEach((v) => {
425
+ var _a;
426
+ this._globalMessages[v.taskUUID] = [
427
+ ...((_a = this._globalMessages[v.taskUUID]) !== null && _a !== void 0 ? _a : []),
428
+ v,
429
+ ];
430
+ });
431
+ }
432
+ else {
433
+ this._globalMessages[value.taskUUID] = value;
434
+ }
435
+ },
436
+ });
437
+ }
438
+ async requestImages({ outputType, outputFormat, uploadEndpoint, checkNsfw, positivePrompt, negativePrompt, seedImage, maskImage, strength, height, width, model, steps, scheduler, seed, CFGScale, clipSkip, usePromptWeighting, numberResults = 1, controlNet, lora, onPartialImages, includeCost, customTaskUUID, retry = 2, }) {
439
+ await this.ensureConnection();
440
+ let lis = undefined;
441
+ let requestObject = undefined;
442
+ let taskUUIDs = [];
443
+ let retryCount = 0;
444
+ try {
445
+ await this.ensureConnection();
446
+ let seedImageUUID = null;
447
+ let maskImageUUID = null;
448
+ let controlNetData = [];
449
+ if (seedImage) {
450
+ const uploadedImage = await this.uploadImage(seedImage);
451
+ if (!uploadedImage)
452
+ return [];
453
+ seedImageUUID = uploadedImage.imageUUID;
454
+ }
455
+ if (maskImage) {
456
+ const uploadedMaskInitiator = await this.uploadImage(maskImage);
457
+ if (!uploadedMaskInitiator)
458
+ return [];
459
+ maskImageUUID = uploadedMaskInitiator.imageUUID;
460
+ }
461
+ if (controlNet === null || controlNet === void 0 ? void 0 : controlNet.length) {
462
+ for (let i = 0; i < controlNet.length; i++) {
463
+ const controlData = controlNet[i];
464
+ const { endStep, startStep, weight, guideImage, controlMode, startStepPercentage, endStepPercentage, model: controlNetModel, } = controlData;
465
+ const imageUploaded = guideImage
466
+ ? await this.uploadImage(guideImage)
467
+ : null;
468
+ controlNetData.push(Object.assign(Object.assign(Object.assign({ guideImage: imageUploaded === null || imageUploaded === void 0 ? void 0 : imageUploaded.imageUUID, model: controlNetModel, endStep,
469
+ startStep,
470
+ weight }, (0, utils_1.evaluateNonTrue)({
471
+ key: "startStepPercentage",
472
+ value: startStepPercentage,
473
+ })), (0, utils_1.evaluateNonTrue)({
474
+ key: "endStepPercentage",
475
+ value: endStepPercentage,
476
+ })), { controlMode: controlMode || types_1.EControlMode.CONTROL_NET }));
477
+ }
478
+ }
479
+ requestObject = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ taskType: types_1.ETaskType.IMAGE_INFERENCE, model, positivePrompt: positivePrompt }, (negativePrompt ? { negativePrompt } : {})), (height ? { height } : {})), (width ? { width } : {})), { numberResults }), ((lora === null || lora === void 0 ? void 0 : lora.length) ? { lora: lora } : {})), (outputType ? { outputType } : {})), (outputFormat ? { outputFormat } : {})), (uploadEndpoint ? { uploadEndpoint } : {})), (0, utils_1.evaluateNonTrue)({ key: "checkNsfw", value: checkNsfw })), (0, utils_1.evaluateNonTrue)({ key: "strength", value: strength })), (0, utils_1.evaluateNonTrue)({ key: "CFGScale", value: CFGScale })), (0, utils_1.evaluateNonTrue)({ key: "clipSkip", value: clipSkip })), (0, utils_1.evaluateNonTrue)({
480
+ key: "usePromptWeighting",
481
+ value: usePromptWeighting,
482
+ })), (0, utils_1.evaluateNonTrue)({ key: "steps", value: steps })), (controlNetData.length ? { controlNet: controlNetData } : {})), (seed ? { seed: seed } : {})), (scheduler ? { scheduler } : {})), (0, utils_1.evaluateNonTrue)({ key: "includeCost", value: includeCost })), (seedImageUUID ? { seedImage: seedImageUUID } : {})), (maskImageUUID ? { maskImage: maskImageUUID } : {}));
483
+ return await (0, async_retry_1.asyncRetry)(async () => {
484
+ retryCount++;
485
+ lis === null || lis === void 0 ? void 0 : lis.destroy();
486
+ const imagesWithSimilarTask = this._globalImages.filter((img) => taskUUIDs.includes(img.taskUUID));
487
+ const taskUUID = customTaskUUID || (0, utils_1.getUUID)();
488
+ taskUUIDs.push(taskUUID);
489
+ const imageRemaining = numberResults - imagesWithSimilarTask.length;
490
+ const newRequestObject = Object.assign(Object.assign({}, requestObject), { taskUUID: taskUUID, numberResults: imageRemaining });
491
+ this.send(newRequestObject);
492
+ lis = this.listenToImages({
493
+ onPartialImages,
494
+ taskUUID: taskUUID,
495
+ groupKey: utils_1.LISTEN_TO_IMAGES_KEY.REQUEST_IMAGES,
496
+ positivePrompt,
497
+ negativePrompt,
498
+ });
499
+ const promise = await this.getSimilarImages({
500
+ taskUUID: taskUUIDs,
501
+ numberResults,
502
+ lis,
503
+ });
504
+ lis.destroy();
505
+ return promise;
506
+ }, {
507
+ maxRetries: retry,
508
+ callback: () => {
509
+ lis === null || lis === void 0 ? void 0 : lis.destroy();
510
+ },
511
+ });
512
+ }
513
+ catch (e) {
514
+ if (e.taskUUID) {
515
+ throw e;
516
+ }
517
+ if (retryCount >= retry) {
518
+ return this.handleIncompleteImages({ taskUUIDs, error: e });
519
+ }
520
+ }
521
+ }
522
+ async ensureConnection() {
523
+ var _a;
524
+ let isConnected = this.connected();
525
+ if (isConnected || this._url === utils_1.BASE_RUNWARE_URLS.TEST)
526
+ return;
527
+ const retryInterval = 2000;
528
+ const pollingInterval = 200;
529
+ // const pollingInterval = this._sdkType === SdkType.CLIENT ? 200 : 2000;
530
+ try {
531
+ if (this._invalidAPIkey)
532
+ throw this._invalidAPIkey;
533
+ return new Promise((resolve, reject) => {
534
+ // const isConnected =
535
+ let retry = 0;
536
+ const MAX_RETRY = 30;
537
+ let retryIntervalId;
538
+ let pollingIntervalId;
539
+ const clearAllIntervals = () => {
540
+ clearInterval(retryIntervalId);
541
+ clearInterval(pollingIntervalId);
542
+ };
543
+ if (this._sdkType === types_1.SdkType.SERVER) {
544
+ retryIntervalId = setInterval(async () => {
545
+ try {
546
+ const hasConnected = this.connected();
547
+ if (hasConnected) {
548
+ clearAllIntervals();
549
+ resolve(true);
550
+ }
551
+ else if (retry >= MAX_RETRY) {
552
+ clearAllIntervals();
553
+ reject(new Error("Retry timed out"));
554
+ }
555
+ else {
556
+ this.connect();
557
+ retry++;
558
+ }
559
+ }
560
+ catch (error) {
561
+ clearAllIntervals();
562
+ reject(error);
563
+ }
564
+ }, retryInterval);
565
+ }
566
+ pollingIntervalId = setInterval(async () => {
567
+ const hasConnected = this.connected();
568
+ if (hasConnected) {
569
+ clearAllIntervals();
570
+ resolve(true);
571
+ }
572
+ if (!!this._invalidAPIkey) {
573
+ clearAllIntervals();
574
+ reject(new Error("Invalid API key"));
575
+ return;
576
+ }
577
+ }, pollingInterval);
578
+ });
579
+ if (!isConnected) {
580
+ this.connect();
581
+ await (0, utils_1.delay)(2);
582
+ // const listenerTaskUID = getUUID();
583
+ // if (this._ws.readyState === 1) {
584
+ // this.send({
585
+ // newConnection: { apiKey: this._apiKey, taskUUID: listenerTaskUID },
586
+ // });
587
+ // }
588
+ // const lis = this.globalListener({
589
+ // responseKey: "newConnectionSessionUUID",
590
+ // taskType: "newConnectionSessionUUID.connectionSessionUUID",
591
+ // taskUUID: listenerTaskUID,
592
+ // });
593
+ // await getIntervalWithPromise(
594
+ // ({ resolve, reject }) => {
595
+ // const connectionId: string = this._globalMessages[listenerTaskUID];
596
+ // if ((connectionId as any)?.error) {
597
+ // reject(connectionId);
598
+ // return true;
599
+ // }
600
+ // if (connectionId) {
601
+ // delete this._globalMessages[listenerTaskUID];
602
+ // this._connectionSessionUUID = connectionId;
603
+ // resolve(connectionId);
604
+ // return true;
605
+ // }
606
+ // },
607
+ // { debugKey: "listen-to-connection" }
608
+ // );
609
+ // lis.destroy();
610
+ }
611
+ }
612
+ catch (e) {
613
+ throw ((_a = this._invalidAPIkey) !== null && _a !== void 0 ? _a : "Could not connect to server. Ensure your API key is correct");
614
+ }
615
+ }
616
+ async getSimilarImages({ taskUUID, numberResults, shouldThrowError, lis, }) {
617
+ return (await (0, utils_1.getIntervalWithPromise)(({ resolve, reject, intervalId }) => {
618
+ var _a;
619
+ const taskUUIDs = Array.isArray(taskUUID) ? taskUUID : [taskUUID];
620
+ const imagesWithSimilarTask = this._globalImages.filter((img) => taskUUIDs.includes(img.taskUUID));
621
+ if (this._globalError) {
622
+ const newData = this._globalError;
623
+ this._globalError = undefined;
624
+ // throw errorData[0]
625
+ clearInterval(intervalId);
626
+ (_a = (reject)) === null || _a === void 0 ? void 0 : _a(newData);
627
+ return true;
628
+ }
629
+ // onPartialImages?.(imagesWithSimilarTask)
630
+ else if (imagesWithSimilarTask.length >= numberResults) {
631
+ // lis?.destroy();
632
+ clearInterval(intervalId);
633
+ this._globalImages = this._globalImages.filter((img) => !taskUUIDs.includes(img.taskUUID));
634
+ resolve([...imagesWithSimilarTask].slice(0, numberResults));
635
+ return true;
636
+ // Resolve the promise with the data
637
+ }
638
+ }, { debugKey: "getting images", shouldThrowError }));
639
+ }
640
+ handleIncompleteImages({ taskUUIDs, error, }) {
641
+ const imagesWithSimilarTask = this._globalImages.filter((img) => taskUUIDs.includes(img.taskUUID));
642
+ if (imagesWithSimilarTask.length > 1) {
643
+ this._globalImages = this._globalImages.filter((img) => !taskUUIDs.includes(img.taskUUID));
644
+ return imagesWithSimilarTask;
645
+ }
646
+ else {
647
+ throw error;
648
+ }
649
+ }
650
+ }
651
+ exports.RunwareBase = RunwareBase;
@@ -0,0 +1,5 @@
1
+ import { RunwareBase } from "./Runware-base";
2
+ import { RunwareBaseType } from "./types";
3
+ export declare class RunwareClient extends RunwareBase {
4
+ constructor({ apiKey, url }: RunwareBaseType);
5
+ }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.RunwareClient = void 0;
7
+ const Runware_base_1 = require("./Runware-base");
8
+ const reconnect_1 = __importDefault(require("./reconnect"));
9
+ class RunwareClient extends Runware_base_1.RunwareBase {
10
+ constructor({ apiKey, url }) {
11
+ super({ apiKey, url });
12
+ if (apiKey) {
13
+ this._ws = new reconnect_1.default(this._url);
14
+ this.connect();
15
+ }
16
+ }
17
+ }
18
+ exports.RunwareClient = RunwareClient;