@tscomfy/client 0.0.0-stage → 0.1.2

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 (93) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +76 -2
  3. package/dist/channel.d.ts +54 -0
  4. package/dist/channel.d.ts.map +1 -0
  5. package/dist/channel.js +307 -0
  6. package/dist/channel.js.map +1 -0
  7. package/dist/client-error.d.ts +15 -0
  8. package/dist/client-error.d.ts.map +1 -0
  9. package/dist/client-error.js +16 -0
  10. package/dist/client-error.js.map +1 -0
  11. package/dist/connection.d.ts +33 -0
  12. package/dist/connection.d.ts.map +1 -0
  13. package/dist/connection.js +35 -0
  14. package/dist/connection.js.map +1 -0
  15. package/dist/event-queue.d.ts +16 -0
  16. package/dist/event-queue.d.ts.map +1 -0
  17. package/dist/event-queue.js +66 -0
  18. package/dist/event-queue.js.map +1 -0
  19. package/dist/events.d.ts +60 -0
  20. package/dist/events.d.ts.map +1 -0
  21. package/dist/events.js +2 -0
  22. package/dist/events.js.map +1 -0
  23. package/dist/files.d.ts +55 -0
  24. package/dist/files.d.ts.map +1 -0
  25. package/dist/files.js +69 -0
  26. package/dist/files.js.map +1 -0
  27. package/dist/frames.d.ts +24 -0
  28. package/dist/frames.d.ts.map +1 -0
  29. package/dist/frames.js +71 -0
  30. package/dist/frames.js.map +1 -0
  31. package/dist/http.d.ts +28 -0
  32. package/dist/http.d.ts.map +1 -0
  33. package/dist/http.js +96 -0
  34. package/dist/http.js.map +1 -0
  35. package/dist/index.d.ts +17 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +14 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/job.d.ts +59 -0
  40. package/dist/job.d.ts.map +1 -0
  41. package/dist/job.js +481 -0
  42. package/dist/job.js.map +1 -0
  43. package/dist/outcome.d.ts +47 -0
  44. package/dist/outcome.d.ts.map +1 -0
  45. package/dist/outcome.js +2 -0
  46. package/dist/outcome.js.map +1 -0
  47. package/dist/outputs.d.ts +53 -0
  48. package/dist/outputs.d.ts.map +1 -0
  49. package/dist/outputs.js +21 -0
  50. package/dist/outputs.js.map +1 -0
  51. package/dist/read-outputs.d.ts +11 -0
  52. package/dist/read-outputs.d.ts.map +1 -0
  53. package/dist/read-outputs.js +142 -0
  54. package/dist/read-outputs.js.map +1 -0
  55. package/dist/server-errors.d.ts +7 -0
  56. package/dist/server-errors.d.ts.map +1 -0
  57. package/dist/server-errors.js +46 -0
  58. package/dist/server-errors.js.map +1 -0
  59. package/dist/server.d.ts +30 -0
  60. package/dist/server.d.ts.map +1 -0
  61. package/dist/server.js +2 -0
  62. package/dist/server.js.map +1 -0
  63. package/dist/timers.d.ts +11 -0
  64. package/dist/timers.d.ts.map +1 -0
  65. package/dist/timers.js +38 -0
  66. package/dist/timers.js.map +1 -0
  67. package/dist/url.d.ts +14 -0
  68. package/dist/url.d.ts.map +1 -0
  69. package/dist/url.js +39 -0
  70. package/dist/url.js.map +1 -0
  71. package/dist/uuid.d.ts +7 -0
  72. package/dist/uuid.d.ts.map +1 -0
  73. package/dist/uuid.js +13 -0
  74. package/dist/uuid.js.map +1 -0
  75. package/package.json +46 -4
  76. package/src/channel.ts +334 -0
  77. package/src/client-error.ts +19 -0
  78. package/src/connection.ts +59 -0
  79. package/src/event-queue.ts +70 -0
  80. package/src/events.ts +76 -0
  81. package/src/files.ts +119 -0
  82. package/src/frames.ts +87 -0
  83. package/src/http.ts +113 -0
  84. package/src/index.ts +53 -0
  85. package/src/job.ts +562 -0
  86. package/src/outcome.ts +52 -0
  87. package/src/outputs.ts +69 -0
  88. package/src/read-outputs.ts +171 -0
  89. package/src/server-errors.ts +61 -0
  90. package/src/server.ts +29 -0
  91. package/src/timers.ts +35 -0
  92. package/src/url.ts +41 -0
  93. package/src/uuid.ts +12 -0
package/dist/job.js ADDED
@@ -0,0 +1,481 @@
1
+ import { createDiagnostic, stringify, toApi, } from "@tscomfy/core";
2
+ import { channelOf } from "./channel.js";
3
+ import { ClientError } from "./client-error.js";
4
+ import { EventQueue } from "./event-queue.js";
5
+ import { isList, isObject, readObject, send, unexpected } from "./http.js";
6
+ import { nodeIdOf, outputsInOrder, readNodeOutput } from "./read-outputs.js";
7
+ import { serverDiagnostics } from "./server-errors.js";
8
+ import { sleep } from "./timers.js";
9
+ import { randomUuid } from "./uuid.js";
10
+ /**
11
+ * Submits a workflow, or a prompt, to run on the server. A workflow is exported with `toApi`,
12
+ * which validates it and throws a `ValidationError` for errors (D21); a prompt is sent as given.
13
+ * The job is registered under a prompt id the client mints before anything is sent, so no event
14
+ * is missed. Throws a `TypeError` for invalid options or a closed connection.
15
+ */
16
+ export function submit(connection, input, options = {}) {
17
+ const channel = channelOf(connection);
18
+ if (channel.closed)
19
+ throw new TypeError("submit: the connection is closed");
20
+ const prompt = isWorkflow(input) ? toApi(input) : input;
21
+ const body = requestBody(channel.clientId, prompt, options);
22
+ const run = new JobRun(channel, body.id, Object.keys(prompt), options.signal);
23
+ run.start(body.text);
24
+ return run.job;
25
+ }
26
+ /** A workflow has a schema and a graph of nodes; a prompt's entries are nodes with a class. */
27
+ function isWorkflow(input) {
28
+ const graph = Reflect.get(input, "graph");
29
+ const nodes = typeof graph === "object" && graph !== null ? Reflect.get(graph, "nodes") : undefined;
30
+ return (Reflect.has(input, "schema") &&
31
+ typeof nodes === "object" &&
32
+ nodes !== null &&
33
+ typeof Reflect.get(nodes, "get") === "function");
34
+ }
35
+ const PREVIEW_METHODS = new Set(["auto", "latent2rgb", "taesd", "none"]);
36
+ const RESERVED_EXTRA_DATA = ["client_id", "preview_method"];
37
+ /** The body of `POST /prompt`, serialized losslessly, and the prompt id it carries. */
38
+ function requestBody(clientId, prompt, options) {
39
+ if (options.previews !== undefined && !PREVIEW_METHODS.has(options.previews)) {
40
+ throw new TypeError(`submit: unknown preview method ${options.previews}`);
41
+ }
42
+ const extra = options.extraData ?? {};
43
+ for (const key of RESERVED_EXTRA_DATA) {
44
+ if (Object.hasOwn(extra, key))
45
+ throw new TypeError(`submit: extraData can't set ${key}`);
46
+ }
47
+ const id = randomUuid();
48
+ const body = {
49
+ client_id: clientId,
50
+ prompt_id: id,
51
+ prompt,
52
+ extra_data: {
53
+ ...extra,
54
+ ...(options.previews === undefined ? {} : { preview_method: options.previews }),
55
+ },
56
+ ...(options.front === true ? { front: true } : {}),
57
+ ...(options.targets === undefined
58
+ ? {}
59
+ : { partial_execution_targets: options.targets.map(nodeIdOf) }),
60
+ };
61
+ return { id, text: stringify(body) };
62
+ }
63
+ /** How often to poll the job record after a reconnect, when events may be lost for good. */
64
+ const POLL_MS = [1000, 2000, 5000, 10_000];
65
+ /** At most one record read per this many milliseconds on queue changes. */
66
+ const QUEUE_CHECK_MS = 1000;
67
+ /** Retries of a record read that couldn't reach the server. */
68
+ const READ_RETRY_MS = [500, 1000, 2000, 4000, 8000];
69
+ /** One job: its events, its record reads and its outcome. */
70
+ class JobRun {
71
+ id;
72
+ job;
73
+ #channel;
74
+ #order;
75
+ #signal;
76
+ #events = new EventQueue();
77
+ #diagnostics = [];
78
+ #outputs = new Map();
79
+ /** The node a server node id is displayed as (they differ for nodes expanded at run time). */
80
+ #display = new Map();
81
+ #progress = new Map();
82
+ #accepted;
83
+ #accept = () => undefined;
84
+ #resolve = () => undefined;
85
+ #reject = () => undefined;
86
+ #settled = false;
87
+ #started = false;
88
+ #reading = false;
89
+ #readAgain = false;
90
+ #lastQueueCheck = 0;
91
+ #queueCheck;
92
+ #poll;
93
+ /** Aborted when the job settles: ends its waits, so no timer outlives it. */
94
+ #done = new AbortController();
95
+ #abort = () => {
96
+ this.#abandon(this.#signal?.reason);
97
+ };
98
+ constructor(channel, id, order, signal) {
99
+ this.#channel = channel;
100
+ this.id = id;
101
+ this.#order = order;
102
+ this.#signal = signal;
103
+ this.#accepted = new Promise((resolve) => {
104
+ this.#accept = resolve;
105
+ });
106
+ const outcome = new Promise((resolve, reject) => {
107
+ this.#resolve = resolve;
108
+ this.#reject = reject;
109
+ });
110
+ // Handled here so a rejection nobody awaits doesn't crash the process; awaiting still throws.
111
+ outcome.catch(() => undefined);
112
+ this.job = Object.freeze({
113
+ id,
114
+ events: this.#events,
115
+ outcome,
116
+ cancel: () => this.#cancel(),
117
+ });
118
+ }
119
+ start(body) {
120
+ if (this.#signal?.aborted === true) {
121
+ this.#abandon(this.#signal.reason);
122
+ return;
123
+ }
124
+ this.#signal?.addEventListener("abort", this.#abort, { once: true });
125
+ void this.#post(body);
126
+ }
127
+ async #post(body) {
128
+ try {
129
+ await this.#channel.ready(this.#signal);
130
+ if (this.#settled) {
131
+ this.#accept(false);
132
+ return;
133
+ }
134
+ this.#channel.register(this);
135
+ // Not abortable: once sent, the prompt may be queued, and only its answer says so. An
136
+ // abort meanwhile cancels the job after the answer (`#abandon`).
137
+ const response = await send(this.#channel.server, { method: "POST", path: "prompt", body });
138
+ if (response.status === 200) {
139
+ // Queued: from here on the job can be cancelled, whatever the body says.
140
+ this.#accept(true);
141
+ const answer = await readObject(response).catch(() => undefined);
142
+ const id = answer?.["prompt_id"];
143
+ if (typeof id === "string" && id !== this.id) {
144
+ // A server or proxy that ignores the client's id: the record would never be found.
145
+ void cancelJob(this.#channel.server, id);
146
+ throw new ClientError(`The server queued the prompt as ${id}, not as the id the client chose (${this.id})`);
147
+ }
148
+ this.#diagnostics.push(...serverDiagnostics(undefined, answer?.["node_errors"]));
149
+ return;
150
+ }
151
+ if (response.status === 400) {
152
+ const answer = await readObject(response);
153
+ this.#accept(false);
154
+ this.#settle({
155
+ status: "rejected",
156
+ diagnostics: serverDiagnostics(answer["error"] ?? "", answer["node_errors"]),
157
+ });
158
+ return;
159
+ }
160
+ throw await unexpected(response);
161
+ }
162
+ catch (error) {
163
+ this.#accept(false);
164
+ this.fail(error);
165
+ }
166
+ }
167
+ message(type, data) {
168
+ if (this.#settled)
169
+ return;
170
+ switch (type) {
171
+ case "execution_start":
172
+ this.#started = true;
173
+ this.#events.push({ type: "started" });
174
+ return;
175
+ case "execution_cached":
176
+ this.#started = true;
177
+ this.#events.push({ type: "cached", nodes: Object.freeze(strings(data["nodes"])) });
178
+ return;
179
+ case "executing": {
180
+ const node = data["display_node"] ?? data["node"];
181
+ if (node === null) {
182
+ this.#read();
183
+ }
184
+ else if (typeof node === "string") {
185
+ this.#events.push({ type: "executing", node });
186
+ }
187
+ return;
188
+ }
189
+ case "progress_state":
190
+ this.#progressState(data["nodes"]);
191
+ return;
192
+ case "executed":
193
+ this.#executed(data);
194
+ return;
195
+ case "execution_error":
196
+ this.#executionError(data);
197
+ return;
198
+ default:
199
+ // execution_success, execution_interrupted: the record decides, read on the final
200
+ // `executing`. Anything else isn't ours to interpret.
201
+ return;
202
+ }
203
+ }
204
+ frame(frame) {
205
+ if (this.#settled)
206
+ return;
207
+ const node = this.#display.get(frame.node) ?? frame.node;
208
+ if (frame.kind === "preview") {
209
+ this.#events.push({ type: "preview", node, mime: frame.mime, bytes: frame.bytes });
210
+ }
211
+ else {
212
+ this.#events.push({ type: "text", node, text: frame.text });
213
+ }
214
+ }
215
+ queueChanged() {
216
+ // A job cancelled while queued sends no event; the record shows it.
217
+ if (this.#started || this.#settled)
218
+ return;
219
+ // At most one read per interval; a change inside it is read at its end, not dropped.
220
+ if (this.#queueCheck !== undefined)
221
+ return;
222
+ const wait = this.#lastQueueCheck + QUEUE_CHECK_MS - Date.now();
223
+ this.#queueCheck = setTimeout(() => {
224
+ this.#queueCheck = undefined;
225
+ this.#lastQueueCheck = Date.now();
226
+ this.#read();
227
+ }, Math.max(0, wait));
228
+ }
229
+ reconnected() {
230
+ // Events sent while the socket was down are gone, and a reconnect can leave the server
231
+ // sending none (two sockets with one id): poll the record until the job settles.
232
+ this.#read();
233
+ if (this.#poll === undefined)
234
+ this.#schedulePoll(0);
235
+ }
236
+ fail(error) {
237
+ if (this.#settled)
238
+ return;
239
+ this.#finish();
240
+ this.#reject(error);
241
+ }
242
+ #progressState(nodes) {
243
+ if (!isObject(nodes))
244
+ return;
245
+ for (const [key, entry] of Object.entries(nodes)) {
246
+ if (!isObject(entry))
247
+ continue;
248
+ const { value, max } = entry;
249
+ const display = entry["display_node_id"] ?? entry["node_id"] ?? key;
250
+ if (typeof value !== "number" || typeof max !== "number" || typeof display !== "string") {
251
+ continue;
252
+ }
253
+ const seen = `${String(value)}/${String(max)}`;
254
+ if (this.#progress.get(display) === seen)
255
+ continue;
256
+ this.#progress.set(display, seen);
257
+ this.#events.push({ type: "progress", node: display, value, max });
258
+ }
259
+ }
260
+ #executed(data) {
261
+ const node = data["node"];
262
+ const display = data["display_node"] ?? node;
263
+ if (typeof node !== "string" || typeof display !== "string")
264
+ return;
265
+ this.#display.set(node, display);
266
+ // A cached node without UI output reports `null`.
267
+ if (!isObject(data["output"]))
268
+ return;
269
+ const output = readNodeOutput(display, data["output"]);
270
+ this.#outputs.set(display, output);
271
+ this.#events.push({ type: "output", node: display, output });
272
+ }
273
+ #executionError(data) {
274
+ // Only a blocked node is reported here; a real error ends the run, and the record has it.
275
+ if (data["exception_type"] !== "ExecutionBlocked")
276
+ return;
277
+ const node = data["node_id"];
278
+ if (typeof node !== "string")
279
+ return;
280
+ const reported = data["exception_message"];
281
+ const message = typeof reported === "string" ? reported : "Execution blocked";
282
+ this.#diagnostics.push(createDiagnostic("W_NODE_BLOCKED", [node], message));
283
+ this.#events.push({ type: "blocked", node, message });
284
+ }
285
+ /** Reads the job record and settles from it; one read at a time, again if asked meanwhile. */
286
+ #read() {
287
+ if (this.#settled)
288
+ return;
289
+ if (this.#reading) {
290
+ this.#readAgain = true;
291
+ return;
292
+ }
293
+ this.#reading = true;
294
+ void this.#readRecord()
295
+ .catch((error) => {
296
+ this.fail(error);
297
+ })
298
+ .finally(() => {
299
+ this.#reading = false;
300
+ if (this.#readAgain && !this.#settled) {
301
+ this.#readAgain = false;
302
+ this.#read();
303
+ }
304
+ });
305
+ }
306
+ async #readRecord() {
307
+ if (!(await this.#accepted) || this.#settled)
308
+ return;
309
+ const response = await this.#retried(() => send(this.#channel.server, { method: "GET", path: `api/jobs/${this.id}` }));
310
+ // Settled meanwhile (aborted, closed): the answer comes too late.
311
+ if (this.#isSettled())
312
+ return;
313
+ if (response.status === 404) {
314
+ // An unknown job: cancelled while it was queued. A server without the job API answers
315
+ // with a 404 that isn't JSON.
316
+ const answer = await readObject(response).catch(() => undefined);
317
+ if (answer === undefined)
318
+ throw await unexpected(response);
319
+ if (this.#started) {
320
+ // It ran, and its record is gone: the server restarted, or its history moved on.
321
+ throw new ClientError(`The server has no record of job ${this.id} any more (restarted?); its outcome is unknown`, { status: 404 });
322
+ }
323
+ this.#settle({ status: "cancelled", outputs: this.#liveOutputs(), diagnostics: [] });
324
+ return;
325
+ }
326
+ if (!response.ok)
327
+ throw await unexpected(response);
328
+ const record = await readObject(response);
329
+ const status = record["status"];
330
+ if (status === "pending" || status === "in_progress")
331
+ return;
332
+ if (status === "completed") {
333
+ this.#settle({ status: "success", outputs: this.#recordOutputs(record), diagnostics: [] });
334
+ }
335
+ else if (status === "failed") {
336
+ this.#settle({
337
+ status: "failed",
338
+ error: executionError(record["execution_error"]),
339
+ outputs: this.#recordOutputs(record),
340
+ diagnostics: [],
341
+ });
342
+ }
343
+ else if (status === "cancelled") {
344
+ this.#settle({ status: "cancelled", outputs: this.#recordOutputs(record), diagnostics: [] });
345
+ }
346
+ else {
347
+ throw new ClientError(`The server reported job status ${stringify(status ?? null)}`);
348
+ }
349
+ }
350
+ #isSettled() {
351
+ return this.#settled;
352
+ }
353
+ /** Retries a request that couldn't reach the server, a few times, with growing waits. */
354
+ async #retried(request) {
355
+ for (const delay of READ_RETRY_MS) {
356
+ try {
357
+ // oxlint-disable-next-line no-await-in-loop -- retries are sequential, with growing waits
358
+ return await request();
359
+ }
360
+ catch (error) {
361
+ if (!(error instanceof ClientError) || this.#settled)
362
+ throw error;
363
+ // oxlint-disable-next-line no-await-in-loop -- retries are sequential, with growing waits
364
+ await sleep(delay, this.#done.signal);
365
+ // Settled meanwhile: no more requests; the error goes nowhere.
366
+ if (this.#isSettled())
367
+ throw error;
368
+ }
369
+ }
370
+ return request();
371
+ }
372
+ /**
373
+ * The record's outputs, by the nodes they are displayed as, in prompt order. A node whose
374
+ * output the client saw live keeps that one: the record rewrites some entries (any string
375
+ * with a 3D file extension becomes a file, `text` included), the live output is as the node
376
+ * reported it.
377
+ */
378
+ #recordOutputs(record) {
379
+ const outputs = new Map();
380
+ const recorded = record["outputs"];
381
+ if (isObject(recorded)) {
382
+ for (const [id, ui] of Object.entries(recorded)) {
383
+ if (!isObject(ui))
384
+ continue;
385
+ const node = this.#display.get(id) ?? id;
386
+ outputs.set(node, this.#outputs.get(node) ?? readNodeOutput(node, ui));
387
+ }
388
+ }
389
+ return outputsInOrder(outputs, this.#order);
390
+ }
391
+ #liveOutputs() {
392
+ return outputsInOrder(this.#outputs, this.#order);
393
+ }
394
+ #settle(outcome) {
395
+ if (this.#settled)
396
+ return;
397
+ this.#finish();
398
+ const diagnostics = Object.freeze([...this.#diagnostics, ...outcome.diagnostics]);
399
+ this.#resolve(Object.freeze({ ...outcome, diagnostics }));
400
+ }
401
+ #finish() {
402
+ this.#settled = true;
403
+ this.#done.abort();
404
+ this.#signal?.removeEventListener("abort", this.#abort);
405
+ if (this.#poll !== undefined)
406
+ clearTimeout(this.#poll);
407
+ if (this.#queueCheck !== undefined)
408
+ clearTimeout(this.#queueCheck);
409
+ this.#channel.unregister(this);
410
+ this.#events.end();
411
+ }
412
+ #schedulePoll(step) {
413
+ if (this.#poll !== undefined)
414
+ clearTimeout(this.#poll);
415
+ if (this.#settled)
416
+ return;
417
+ const delay = POLL_MS[Math.min(step, POLL_MS.length - 1)] ?? 10_000;
418
+ this.#poll = setTimeout(() => {
419
+ this.#read();
420
+ this.#schedulePoll(step + 1);
421
+ }, delay);
422
+ }
423
+ async #cancel() {
424
+ if (this.#settled || !(await this.#accepted))
425
+ return;
426
+ const response = await send(this.#channel.server, {
427
+ method: "POST",
428
+ path: `api/jobs/${this.id}/cancel`,
429
+ body: "{}",
430
+ });
431
+ if (!response.ok)
432
+ throw await unexpected(response);
433
+ await response.body?.cancel();
434
+ this.#read();
435
+ }
436
+ /** The caller gave up: cancel on the server, best effort, and reject with the reason. */
437
+ #abandon(reason) {
438
+ if (this.#settled)
439
+ return;
440
+ const accepted = this.#accepted;
441
+ const server = this.#channel.server;
442
+ const id = this.id;
443
+ this.fail(reason);
444
+ void accepted.then((wasAccepted) => (wasAccepted ? cancelJob(server, id) : undefined));
445
+ }
446
+ }
447
+ /** Asks the server to cancel a job, best effort: for a caller who has already given up. */
448
+ async function cancelJob(server, id) {
449
+ try {
450
+ const response = await send(server, {
451
+ method: "POST",
452
+ path: `api/jobs/${id}/cancel`,
453
+ body: "{}",
454
+ });
455
+ await response.body?.cancel();
456
+ }
457
+ catch {
458
+ // Nobody is left to tell.
459
+ }
460
+ }
461
+ /** The strings of a JSON list. */
462
+ function strings(value) {
463
+ return isList(value) ? value.filter((item) => typeof item === "string") : [];
464
+ }
465
+ /** The record's `execution_error`, read leniently. */
466
+ function executionError(value) {
467
+ const error = isObject(value) ? value : {};
468
+ const text = (key) => {
469
+ const item = error[key];
470
+ return typeof item === "string" ? item : "";
471
+ };
472
+ return Object.freeze({
473
+ node: text("node_id"),
474
+ classType: text("node_type"),
475
+ exceptionType: text("exception_type"),
476
+ message: text("exception_message"),
477
+ traceback: Object.freeze(strings(error["traceback"])),
478
+ executed: Object.freeze(strings(error["executed"])),
479
+ });
480
+ }
481
+ //# sourceMappingURL=job.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"job.js","sourceRoot":"","sources":["../src/job.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import type { Diagnostic, NodeId } from "@tscomfy/core";
2
+ import type { Outputs } from "./outputs.ts";
3
+ /** The job ran to the end. Outputs left out by a partial acceptance are in `diagnostics`. */
4
+ export interface SuccessOutcome {
5
+ readonly status: "success";
6
+ readonly outputs: Outputs;
7
+ /**
8
+ * `E_SERVER_VALIDATION` for outputs the server refused while running the others, and
9
+ * `W_NODE_BLOCKED` for nodes that blocked execution.
10
+ */
11
+ readonly diagnostics: readonly Diagnostic[];
12
+ }
13
+ /** The server refused the prompt: nothing ran. */
14
+ export interface RejectedOutcome {
15
+ readonly status: "rejected";
16
+ /** `E_PROMPT_REJECTED` for the server's error, and `E_SERVER_VALIDATION` for each node error. */
17
+ readonly diagnostics: readonly Diagnostic[];
18
+ }
19
+ /** A node raised an error; the run stopped there. */
20
+ export interface FailedOutcome {
21
+ readonly status: "failed";
22
+ readonly error: ExecutionError;
23
+ /** What the nodes that finished before the error reported. */
24
+ readonly outputs: Outputs;
25
+ readonly diagnostics: readonly Diagnostic[];
26
+ }
27
+ /** The job was cancelled or interrupted, by this client or another. */
28
+ export interface CancelledOutcome {
29
+ readonly status: "cancelled";
30
+ /** What the nodes that finished before the cancel reported. */
31
+ readonly outputs: Outputs;
32
+ readonly diagnostics: readonly Diagnostic[];
33
+ }
34
+ /** How a job ended, as the server's record of it says. */
35
+ export type Outcome = SuccessOutcome | RejectedOutcome | FailedOutcome | CancelledOutcome;
36
+ /** The error a node raised. */
37
+ export interface ExecutionError {
38
+ readonly node: NodeId;
39
+ readonly classType: string;
40
+ /** The exception's class, qualified: `torch.OutOfMemoryError`, `ValueError`. */
41
+ readonly exceptionType: string;
42
+ readonly message: string;
43
+ readonly traceback: readonly string[];
44
+ /** The nodes that had finished. */
45
+ readonly executed: readonly NodeId[];
46
+ }
47
+ //# sourceMappingURL=outcome.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outcome.d.ts","sourceRoot":"","sources":["../src/outcome.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,6FAA6F;AAC7F,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,WAAW,EAAE,SAAS,UAAU,EAAE,CAAC;CAC7C;AAED,kDAAkD;AAClD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,iGAAiG;IACjG,QAAQ,CAAC,WAAW,EAAE,SAAS,UAAU,EAAE,CAAC;CAC7C;AAED,qDAAqD;AACrD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,8DAA8D;IAC9D,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,SAAS,UAAU,EAAE,CAAC;CAC7C;AAED,uEAAuE;AACvE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,SAAS,UAAU,EAAE,CAAC;CAC7C;AAED,0DAA0D;AAC1D,MAAM,MAAM,OAAO,GAAG,cAAc,GAAG,eAAe,GAAG,aAAa,GAAG,gBAAgB,CAAC;AAE1F,+BAA+B;AAC/B,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,gFAAgF;IAChF,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,mCAAmC;IACnC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=outcome.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outcome.js","sourceRoot":"","sources":["../src/outcome.ts"],"names":[],"mappings":""}
@@ -0,0 +1,53 @@
1
+ import type { NodeHandle, NodeId, JsonObject, Out } from "@tscomfy/core";
2
+ import type { Outcome } from "./outcome.ts";
3
+ /** Which of the server's folders a file is in. */
4
+ export type FolderType = "output" | "temp" | "input";
5
+ /** A file on the server, as outputs name it and `/view` serves it. */
6
+ export interface FileRef {
7
+ readonly filename: string;
8
+ /** The folder under {@link FileRef.type}'s directory; `""` for none. */
9
+ readonly subfolder: string;
10
+ readonly type: FolderType;
11
+ }
12
+ /** What a file holds, from the server's metadata, the file's extension, or its output key. */
13
+ export type FileKind = "image" | "video" | "audio" | "3d" | "file";
14
+ /** A file a node produced. */
15
+ export interface OutputFile extends FileRef {
16
+ readonly kind: FileKind;
17
+ /**
18
+ * The node marked its images animated. Animated WEBP and PNG stay `image`; core's video nodes
19
+ * report their files under `images` with this flag, and their kind is `video`.
20
+ */
21
+ readonly animated: boolean;
22
+ /** The key of the node's UI output it was listed under: `images`, `audio`, `3d`, `gifs`, … */
23
+ readonly key: string;
24
+ /** Pixels, when the server measured the file. */
25
+ readonly width?: number;
26
+ readonly height?: number;
27
+ }
28
+ /** What one node reported when it ran: its files, its text, and the raw record. */
29
+ export interface NodeOutput {
30
+ /** The node, by its id in the prompt (the builder's id for tscomfy workflows). */
31
+ readonly node: NodeId;
32
+ /** Every file entry under any key, in the order the node listed them. */
33
+ readonly files: readonly OutputFile[];
34
+ /** The strings under `text` (PreviewAny, text previews). */
35
+ readonly text: readonly string[];
36
+ /** The node's UI output as the server sent it: lists by key. */
37
+ readonly ui: JsonObject;
38
+ }
39
+ /** Every node's output, by node id, in prompt order. */
40
+ export type Outputs = ReadonlyMap<NodeId, NodeOutput>;
41
+ /** A node: its id, its handle (`n.SaveImage(…)`), or one of its outputs. */
42
+ export type NodeRef = NodeId | NodeHandle | Out<string>;
43
+ /**
44
+ * What a node (by id, handle or output) reported, or `undefined` when it reported nothing, didn't
45
+ * run, or the job was rejected.
46
+ */
47
+ export declare function outputOf(outcome: Outcome, node: NodeRef): NodeOutput | undefined;
48
+ /**
49
+ * The files of the given nodes (by id, handle or output), or of every node when none is given, in
50
+ * prompt order. Empty for a rejected job, which has no outputs.
51
+ */
52
+ export declare function outputFiles(outcome: Outcome, ...nodes: readonly NodeRef[]): readonly OutputFile[];
53
+ //# sourceMappingURL=outputs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outputs.d.ts","sourceRoot":"","sources":["../src/outputs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACzE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAG5C,kDAAkD;AAClD,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAErD,sEAAsE;AACtE,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,wEAAwE;IACxE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;CAC3B;AAED,8FAA8F;AAC9F,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,IAAI,GAAG,MAAM,CAAC;AAEnE,8BAA8B;AAC9B,MAAM,WAAW,UAAW,SAAQ,OAAO;IACzC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,8FAA8F;IAC9F,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,iDAAiD;IACjD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,mFAAmF;AACnF,MAAM,WAAW,UAAU;IACzB,kFAAkF;IAClF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IACtC,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,gEAAgE;IAChE,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC;CACzB;AAED,wDAAwD;AACxD,MAAM,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAEtD,4EAA4E;AAC5E,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,UAAU,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;AAExD;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAEhF;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,KAAK,EAAE,SAAS,OAAO,EAAE,GAAG,SAAS,UAAU,EAAE,CAKjG"}
@@ -0,0 +1,21 @@
1
+ import { nodeIdOf } from "./read-outputs.js";
2
+ /**
3
+ * What a node (by id, handle or output) reported, or `undefined` when it reported nothing, didn't
4
+ * run, or the job was rejected.
5
+ */
6
+ export function outputOf(outcome, node) {
7
+ return outcome.status === "rejected" ? undefined : outcome.outputs.get(nodeIdOf(node));
8
+ }
9
+ /**
10
+ * The files of the given nodes (by id, handle or output), or of every node when none is given, in
11
+ * prompt order. Empty for a rejected job, which has no outputs.
12
+ */
13
+ export function outputFiles(outcome, ...nodes) {
14
+ if (outcome.status === "rejected")
15
+ return [];
16
+ const outputs = outcome.outputs;
17
+ if (nodes.length === 0)
18
+ return [...outputs.values()].flatMap((output) => output.files);
19
+ return nodes.flatMap((node) => outputs.get(nodeIdOf(node))?.files ?? []);
20
+ }
21
+ //# sourceMappingURL=outputs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outputs.js","sourceRoot":"","sources":["../src/outputs.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAiD7C;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAgB,EAAE,IAAa;IACtD,OAAO,OAAO,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AACzF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,OAAgB,EAAE,GAAG,KAAyB;IACxE,IAAI,OAAO,CAAC,MAAM,KAAK,UAAU;QAAE,OAAO,EAAE,CAAC;IAC7C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAChC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvF,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;AAC3E,CAAC"}