@workglow/task-graph 0.0.123 → 0.0.125

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/dist/browser.js CHANGED
@@ -948,7 +948,8 @@ class TaskRunner {
948
948
  this.task.setInput(overrides);
949
949
  const schema = this.task.constructor.inputSchema();
950
950
  this.task.runInputData = await resolveSchemaInputs(this.task.runInputData, schema, { registry: this.registry });
951
- const isValid = await this.task.validateInput(this.task.runInputData);
951
+ const inputs = this.task.runInputData;
952
+ const isValid = await this.task.validateInput(inputs);
952
953
  if (!isValid) {
953
954
  throw new TaskInvalidInputError("Invalid input data");
954
955
  }
@@ -956,7 +957,6 @@ class TaskRunner {
956
957
  await this.handleAbort();
957
958
  throw new TaskAbortedError("Promise for task created and aborted before run");
958
959
  }
959
- const inputs = this.task.runInputData;
960
960
  let outputs;
961
961
  const isStreamable = isTaskStreamable(this.task);
962
962
  if (this.task.cacheable) {
@@ -1001,11 +1001,12 @@ class TaskRunner {
1001
1001
  this.task.runInputData = await resolveSchemaInputs(this.task.runInputData, schema, { registry: this.registry });
1002
1002
  await this.handleStartReactive();
1003
1003
  try {
1004
- const isValid = await this.task.validateInput(this.task.runInputData);
1004
+ const inputs = this.task.runInputData;
1005
+ const isValid = await this.task.validateInput(inputs);
1005
1006
  if (!isValid) {
1006
1007
  throw new TaskInvalidInputError("Invalid input data");
1007
1008
  }
1008
- const resultReactive = await this.executeTaskReactive(this.task.runInputData, this.task.runOutputData);
1009
+ const resultReactive = await this.executeTaskReactive(inputs, this.task.runOutputData);
1009
1010
  this.task.runOutputData = resultReactive;
1010
1011
  await this.handleCompleteReactive();
1011
1012
  } catch (err) {
@@ -1198,7 +1199,7 @@ class TaskRunner {
1198
1199
  this.task.emit("start");
1199
1200
  this.task.emit("status", this.task.status);
1200
1201
  }
1201
- updateProgress = async (task, progress, message, ...args) => {};
1202
+ updateProgress = async (_task, _progress, _message, ..._args) => {};
1202
1203
  async handleStartReactive() {
1203
1204
  this.reactiveRunning = true;
1204
1205
  }
@@ -1306,11 +1307,7 @@ var init_TaskRunner = __esm(() => {
1306
1307
 
1307
1308
  // src/task/Task.ts
1308
1309
  import { compileSchema } from "@workglow/util/schema";
1309
- import {
1310
- deepEqual,
1311
- EventEmitter as EventEmitter3,
1312
- uuid4 as uuid42
1313
- } from "@workglow/util";
1310
+ import { deepEqual, EventEmitter as EventEmitter3, uuid4 as uuid42 } from "@workglow/util";
1314
1311
 
1315
1312
  class Task {
1316
1313
  static type = "Task";
@@ -1677,6 +1674,9 @@ class Task {
1677
1674
  return this.constructor.getInputSchemaNode();
1678
1675
  }
1679
1676
  async validateInput(input) {
1677
+ if (typeof input !== "object" || input === null) {
1678
+ throw new TaskInvalidInputError("Input must be an object");
1679
+ }
1680
1680
  const ctor = this.constructor;
1681
1681
  let schemaNode;
1682
1682
  if (ctor.hasDynamicSchemas) {
@@ -6791,6 +6791,645 @@ class TaskOutputTabularRepository extends TaskOutputRepository {
6791
6791
  this.emit("output_pruned");
6792
6792
  }
6793
6793
  }
6794
+ // src/debug/console/ConsoleFormatters.ts
6795
+ init_Dataflow();
6796
+ init_TaskGraph();
6797
+ import { DirectedAcyclicGraph as DirectedAcyclicGraph2 } from "@workglow/util/graph";
6798
+ init_Task();
6799
+ init_TaskTypes();
6800
+ function formatDuration(ms) {
6801
+ if (ms < 1)
6802
+ return `${(ms * 1000).toFixed(0)}µs`;
6803
+ if (ms < 1000)
6804
+ return `${ms.toFixed(1)}ms`;
6805
+ return `${(ms / 1000).toFixed(2)}s`;
6806
+ }
6807
+ function getSchemaProperties(schema) {
6808
+ if (typeof schema === "boolean") {
6809
+ return null;
6810
+ }
6811
+ return schema.properties;
6812
+ }
6813
+
6814
+ class ConsoleFormatter {
6815
+ }
6816
+ function isDarkMode() {
6817
+ return window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches;
6818
+ }
6819
+
6820
+ class WorkflowConsoleFormatter extends ConsoleFormatter {
6821
+ header(workflow, config) {
6822
+ if (workflow instanceof Workflow || workflow instanceof TaskGraph) {
6823
+ const graph = workflow instanceof TaskGraph ? workflow : workflow.graph;
6824
+ const error = workflow instanceof Workflow ? workflow.error : "";
6825
+ const title = workflow instanceof Workflow ? "Workflow" : "TaskGraph";
6826
+ const header = new JsonMLElement("div");
6827
+ header.sectionHeader(title);
6828
+ header.styledText(`(${graph.getTasks().length} tasks)`, "color: green; margin-left: 10px;");
6829
+ if (error) {
6830
+ header.styledText(error, "color: red; margin-left: 10px;");
6831
+ }
6832
+ return header.toJsonML();
6833
+ }
6834
+ return null;
6835
+ }
6836
+ hasBody(value, config) {
6837
+ return true;
6838
+ }
6839
+ body(obj, config) {
6840
+ const body = new JsonMLElement("div");
6841
+ const graph = obj instanceof TaskGraph ? obj : obj.graph;
6842
+ const nodes = body.createStyledList();
6843
+ const tasks = graph.getTasks();
6844
+ if (tasks.length) {
6845
+ nodes.createTextChild("Tasks:");
6846
+ for (const node of tasks) {
6847
+ const nodeTag = nodes.createListItem("", "list-style-type: none;");
6848
+ if (obj instanceof Workflow) {
6849
+ for (const df of graph.getSourceDataflows(node.config.id)) {
6850
+ const edgeTag = nodeTag.createChild("li").setStyle("padding-left: 20px;");
6851
+ if (df.sourceTaskPortId === df.targetTaskPortId)
6852
+ continue;
6853
+ const num = tasks.findIndex((t) => t.config.id === df.sourceTaskId) - tasks.findIndex((t) => t.config.id === node.config.id);
6854
+ edgeTag.highlightText("rename");
6855
+ edgeTag.functionCall((el) => {
6856
+ el.greyText('"');
6857
+ el.outputText(`${df.sourceTaskPortId}`);
6858
+ el.greyText('", "');
6859
+ el.inputText(`${df.targetTaskPortId}`);
6860
+ el.greyText('"');
6861
+ if (num !== -1)
6862
+ el.greyText(`, ${num}`);
6863
+ });
6864
+ }
6865
+ }
6866
+ nodeTag.createObjectTag(node, { graph, workflow: obj });
6867
+ }
6868
+ }
6869
+ if (obj instanceof TaskGraph) {
6870
+ const dfList = nodes.createTextChild("Dataflows:");
6871
+ for (const df of obj.getDataflows()) {
6872
+ const dfTag = dfList.createListItem("", "list-style-type: none;");
6873
+ dfTag.createObjectTag(df);
6874
+ }
6875
+ }
6876
+ let earliestStart;
6877
+ let latestEnd;
6878
+ for (const t of tasks) {
6879
+ if (t.startedAt && (!earliestStart || t.startedAt < earliestStart)) {
6880
+ earliestStart = t.startedAt;
6881
+ }
6882
+ if (t.completedAt && (!latestEnd || t.completedAt > latestEnd)) {
6883
+ latestEnd = t.completedAt;
6884
+ }
6885
+ }
6886
+ if (earliestStart && latestEnd) {
6887
+ const durationMs = latestEnd.getTime() - earliestStart.getTime();
6888
+ const timing = nodes.createListItem("", "list-style-type: none;");
6889
+ timing.highlightText("Total duration: ");
6890
+ timing.createTextChild(formatDuration(durationMs));
6891
+ }
6892
+ const dag = obj._dag ?? obj.graph._dag;
6893
+ if (dag && dag.getNodes().length > 0)
6894
+ body.createObjectTag(dag);
6895
+ return body.toJsonML();
6896
+ }
6897
+ }
6898
+
6899
+ class WorkflowAPIConsoleFormatter extends ConsoleFormatter {
6900
+ header(obj, config) {
6901
+ if (obj === Workflow.prototype || obj === Workflow) {
6902
+ const header = new JsonMLElement("div");
6903
+ header.sectionHeader("Workflow API");
6904
+ return header.toJsonML();
6905
+ }
6906
+ return null;
6907
+ }
6908
+ hasBody(value, config) {
6909
+ return true;
6910
+ }
6911
+ body() {
6912
+ const body = new JsonMLElement("div");
6913
+ const apiSection = body.createChild("div");
6914
+ const apiList = apiSection.createStyledList();
6915
+ const apiTag = apiList.createListItem("", "list-style-type: none;");
6916
+ apiTag.createHighlightedListItem(".reset()");
6917
+ apiTag.createHighlightedListItem(".rename(outputName, inputName)");
6918
+ apiTag.createHighlightedListItem(".run()");
6919
+ apiTag.createHighlightedListItem(".abort()");
6920
+ apiTag.createHighlightedListItem(".toJSON()");
6921
+ apiTag.createHighlightedListItem(".toDependencyJSON()");
6922
+ for (const [key, value] of Object.entries(Workflow.prototype)) {
6923
+ if (typeof value === "function" && key !== "constructor") {
6924
+ const item = apiTag.createListItem("");
6925
+ item.createChild("span").createObjectTag(value);
6926
+ }
6927
+ }
6928
+ return body.toJsonML();
6929
+ }
6930
+ }
6931
+
6932
+ class CreateWorkflowConsoleFormatter extends ConsoleFormatter {
6933
+ header(obj, config) {
6934
+ const workflowObj = obj;
6935
+ if (workflowObj.workflowCreate) {
6936
+ const header = new JsonMLElement("div");
6937
+ const name = workflowObj.constructor.runtype ?? workflowObj.constructor.type ?? workflowObj.type.replace(/Task$/, "");
6938
+ const inputSchema = workflowObj.inputSchema();
6939
+ const outputSchema = workflowObj.outputSchema();
6940
+ const inputProperties = getSchemaProperties(inputSchema);
6941
+ const outputProperties = getSchemaProperties(outputSchema);
6942
+ const inputs = inputProperties ? Object.keys(inputProperties).map((key) => `${key}: …`) : typeof inputSchema === "boolean" ? inputSchema ? ["…"] : ["never"] : [];
6943
+ const outputs = outputProperties ? Object.keys(outputProperties).map((key) => `${key}: …`) : typeof outputSchema === "boolean" ? outputSchema ? ["…"] : ["never"] : [];
6944
+ header.methodSignature(name);
6945
+ header.functionCall((el) => {
6946
+ el.objectBraces((innerObj) => {
6947
+ innerObj.inputText(`${inputs.join(", ")}`);
6948
+ });
6949
+ });
6950
+ header.greyText("): ");
6951
+ header.objectBraces((el) => {
6952
+ el.outputText(`${outputs.join(", ")}`);
6953
+ });
6954
+ return header.toJsonML();
6955
+ }
6956
+ return null;
6957
+ }
6958
+ hasBody(value, config) {
6959
+ return false;
6960
+ }
6961
+ body(obj, config) {
6962
+ return null;
6963
+ }
6964
+ }
6965
+
6966
+ class TaskConsoleFormatter extends ConsoleFormatter {
6967
+ header(task2, config) {
6968
+ if (!task2)
6969
+ return null;
6970
+ if (task2 instanceof Task && task2.inputSchema && task2.outputSchema && task2.runInputData && task2.runOutputData) {
6971
+ const header = new JsonMLElement("div");
6972
+ let name = task2.type ?? task2.constructor.name;
6973
+ if (config?.workflow)
6974
+ name = name.replace(/Task$/, "");
6975
+ const inputSchema = task2.inputSchema();
6976
+ const outputSchema = task2.outputSchema();
6977
+ const inputProperties = getSchemaProperties(inputSchema);
6978
+ const outputProperties = getSchemaProperties(outputSchema);
6979
+ const inputs = inputProperties ? Object.keys(inputProperties).filter((key) => task2.runInputData[key] !== undefined).map((key) => {
6980
+ const value = task2.runInputData[key];
6981
+ return { name: key, value };
6982
+ }) : typeof inputSchema === "boolean" && inputSchema ? Object.keys(task2.runInputData || {}).filter((key) => task2.runInputData[key] !== undefined).map((key) => {
6983
+ const value = task2.runInputData[key];
6984
+ return { name: key, value };
6985
+ }) : [];
6986
+ const outputs = outputProperties ? Object.keys(outputProperties).filter((key) => task2.runOutputData[key] !== undefined && task2.runOutputData[key] !== "").filter((key) => !(Array.isArray(task2.runOutputData[key]) && task2.runOutputData[key].length === 0)).map((key) => {
6987
+ return { name: key, value: task2.runOutputData[key] };
6988
+ }) : typeof outputSchema === "boolean" && outputSchema ? Object.keys(task2.runOutputData || {}).filter((key) => task2.runOutputData[key] !== undefined && task2.runOutputData[key] !== "").filter((key) => !(Array.isArray(task2.runOutputData[key]) && task2.runOutputData[key].length === 0)).map((key) => {
6989
+ return { name: key, value: task2.runOutputData[key] };
6990
+ }) : [];
6991
+ header.highlightText(name);
6992
+ header.functionCall((el) => {
6993
+ el.objectBraces((innerObj) => {
6994
+ innerObj.parameterList(inputs);
6995
+ });
6996
+ el.greyText(", ");
6997
+ el.objectBraces((innerObj) => {
6998
+ innerObj.parameterList([{ name: "id", value: task2.config.id }]);
6999
+ });
7000
+ });
7001
+ if (task2.status === TaskStatus.COMPLETED) {
7002
+ header.greyText(": ");
7003
+ header.objectBraces((el) => {
7004
+ el.parameterList(outputs, true);
7005
+ });
7006
+ }
7007
+ return header.toJsonML();
7008
+ }
7009
+ return null;
7010
+ }
7011
+ hasBody(task2, config) {
7012
+ return task2 instanceof Task;
7013
+ }
7014
+ body(task2, config) {
7015
+ if (!task2)
7016
+ return null;
7017
+ if (!(task2 instanceof Task))
7018
+ return null;
7019
+ const body = new JsonMLElement("div").setStyle("padding-left: 10px;");
7020
+ const inputs = body.createStyledList("Inputs:");
7021
+ const allInboundDataflows = config?.graph?.getSourceDataflows(task2.config.id);
7022
+ const inputSchema = task2.inputSchema();
7023
+ const inputProperties = getSchemaProperties(inputSchema);
7024
+ const schemaKeys = inputProperties !== null ? Object.keys(inputProperties) : inputSchema === true ? Object.keys(task2.runInputData || {}) : [];
7025
+ for (const key of schemaKeys) {
7026
+ const value = task2.runInputData[key];
7027
+ const li = inputs.createListItem("", "padding-left: 20px;");
7028
+ li.inputText(`${key}: `);
7029
+ const inputInboundDataflows = allInboundDataflows?.filter((e) => e.targetTaskPortId === key);
7030
+ if (inputInboundDataflows) {
7031
+ const sources = [];
7032
+ const sourceValues = [];
7033
+ inputInboundDataflows.forEach((df) => {
7034
+ const sourceTask = config?.graph?.getTask(df.sourceTaskId);
7035
+ sources.push(`${sourceTask?.type}->Output{${df.sourceTaskPortId}}`);
7036
+ if (df.status === TaskStatus.COMPLETED) {
7037
+ sourceValues.push(df.value);
7038
+ }
7039
+ });
7040
+ if (sources.length > 1) {
7041
+ if (sourceValues.length > 0) {
7042
+ li.createValueObject(sourceValues);
7043
+ li.createTextChild(" ");
7044
+ }
7045
+ li.createTextChild(`from [${sources.join(", ")}]`);
7046
+ } else if (sources.length === 1) {
7047
+ if (sourceValues.length > 0) {
7048
+ li.createValueObject(sourceValues[0]);
7049
+ li.createTextChild(" ");
7050
+ }
7051
+ li.createTextChild("from " + sources[0]);
7052
+ } else {
7053
+ li.createValueObject(value);
7054
+ }
7055
+ } else {
7056
+ li.createValueObject(value);
7057
+ }
7058
+ }
7059
+ const outputsList = body.createStyledList("Outputs:");
7060
+ const outputSchema = task2.outputSchema();
7061
+ const outputProperties = getSchemaProperties(outputSchema);
7062
+ const outputKeys = outputProperties !== null ? Object.keys(outputProperties) : outputSchema === true ? Object.keys(task2.runOutputData || {}) : [];
7063
+ for (const key of outputKeys) {
7064
+ const value = task2.runOutputData[key];
7065
+ const li = outputsList.createListItem("", "padding-left: 20px;");
7066
+ li.outputText(`${key}: `);
7067
+ li.createValueObject(value);
7068
+ }
7069
+ const taskConfig = body.createStyledList("Config:");
7070
+ for (const [key, value] of Object.entries(task2.config)) {
7071
+ if (value === undefined)
7072
+ continue;
7073
+ const li = taskConfig.createListItem("", "padding-left: 20px;");
7074
+ li.inputText(`${key}: `);
7075
+ li.createValueObject(value);
7076
+ }
7077
+ body.createStatusListItem(task2.status);
7078
+ if (task2.startedAt || task2.completedAt) {
7079
+ const timing = body.createStyledList("Timing:");
7080
+ if (task2.startedAt) {
7081
+ const li = timing.createListItem("", "padding-left: 20px;");
7082
+ li.inputText("startedAt: ");
7083
+ li.createTextChild(task2.startedAt.toISOString());
7084
+ }
7085
+ if (task2.completedAt) {
7086
+ const li = timing.createListItem("", "padding-left: 20px;");
7087
+ li.inputText("completedAt: ");
7088
+ li.createTextChild(task2.completedAt.toISOString());
7089
+ }
7090
+ if (task2.startedAt && task2.completedAt) {
7091
+ const durationMs = task2.completedAt.getTime() - task2.startedAt.getTime();
7092
+ const li = timing.createListItem("", "padding-left: 20px;");
7093
+ li.highlightText("duration: ");
7094
+ li.createTextChild(formatDuration(durationMs));
7095
+ }
7096
+ }
7097
+ const dag = task2.subGraph?._dag;
7098
+ if (dag && dag.getNodes().length > 0)
7099
+ body.createObjectTag(dag);
7100
+ return body.toJsonML();
7101
+ }
7102
+ }
7103
+
7104
+ class DAGConsoleFormatter extends ConsoleFormatter {
7105
+ header(obj, config) {
7106
+ if (obj instanceof DirectedAcyclicGraph2) {
7107
+ const header = new JsonMLElement("div");
7108
+ header.createTextChild("DAG");
7109
+ return header.toJsonML();
7110
+ }
7111
+ return null;
7112
+ }
7113
+ hasBody(value, config) {
7114
+ return true;
7115
+ }
7116
+ body(obj, config) {
7117
+ const body = new JsonMLElement("div");
7118
+ body.createStyledList();
7119
+ const dag = obj;
7120
+ if (dag.getNodes().length > 0) {
7121
+ const { dataURL, height } = generateGraphImage(dag);
7122
+ if (dataURL) {
7123
+ const imageTag = body.createChild("div");
7124
+ imageTag.addAttribute("style", `background-image: url(${dataURL}); background-size: cover; background-position: center; width: 800px; height: ${height}px;`);
7125
+ }
7126
+ }
7127
+ return body.toJsonML();
7128
+ }
7129
+ }
7130
+
7131
+ class DataflowConsoleFormatter extends ConsoleFormatter {
7132
+ header(obj, config) {
7133
+ if (obj instanceof Dataflow) {
7134
+ const header = new JsonMLElement("div");
7135
+ header.highlightText("Dataflow ");
7136
+ header.inputText(`${obj.sourceTaskId}.${obj.sourceTaskPortId}`);
7137
+ header.createTextChild(" -> ");
7138
+ header.outputText(`${obj.targetTaskId}.${obj.targetTaskPortId}`);
7139
+ if (obj.status === TaskStatus.COMPLETED) {
7140
+ header.greyText(" = ");
7141
+ header.createValueObject(obj.value);
7142
+ }
7143
+ return header.toJsonML();
7144
+ }
7145
+ return null;
7146
+ }
7147
+ hasBody(value, config) {
7148
+ return true;
7149
+ }
7150
+ body(obj, config) {
7151
+ return null;
7152
+ }
7153
+ }
7154
+
7155
+ class ReactElementConsoleFormatter extends ConsoleFormatter {
7156
+ header(obj, config) {
7157
+ const reactEl = obj;
7158
+ if (reactEl?.$$typeof?.toString() === "Symbol(react.transitional.element)" && !config?.parent) {
7159
+ const header = new JsonMLElement("div");
7160
+ const isMemo = reactEl.type?.$$typeof?.toString() === "Symbol(react.memo)";
7161
+ const name = !isMemo ? reactEl.displayName || reactEl.type?.displayName || reactEl.type?.name : reactEl.type?.type?.displayName || reactEl.type?.type?.name;
7162
+ header.greyText(`<`);
7163
+ header.sectionHeader(`${name}`);
7164
+ header.greyText(`/>`);
7165
+ if (reactEl.key) {
7166
+ header.createTextChild(" ");
7167
+ header.inputText(`key={${reactEl.key}}`);
7168
+ }
7169
+ if (isMemo) {
7170
+ header.createTextChild(" ");
7171
+ header.pill(`Memo`);
7172
+ }
7173
+ return header.toJsonML();
7174
+ }
7175
+ return null;
7176
+ }
7177
+ hasBody(value, config) {
7178
+ return true;
7179
+ }
7180
+ body(obj, config) {
7181
+ const body = new JsonMLElement("div");
7182
+ const props = body.createStyledList("Props:");
7183
+ const reactEl = obj;
7184
+ props.propertyBlock(reactEl.props ?? {});
7185
+ return body.toJsonML();
7186
+ }
7187
+ }
7188
+
7189
+ class JsonMLElement {
7190
+ _attributes;
7191
+ _jsonML;
7192
+ static getColors() {
7193
+ const dark = isDarkMode();
7194
+ return {
7195
+ grey: dark ? "#aaa" : "#333",
7196
+ inputColor: dark ? "#ada" : "#363",
7197
+ outputColor: dark ? "#caa" : "#633",
7198
+ yellow: dark ? "#f3ce49" : "#a68307",
7199
+ undefined: "#888"
7200
+ };
7201
+ }
7202
+ constructor(tagName) {
7203
+ this._attributes = {};
7204
+ this._jsonML = [tagName, this._attributes];
7205
+ }
7206
+ coloredText(text, color) {
7207
+ this.createChild("span").setStyle(`color:${color};`).createTextChild(text);
7208
+ return this;
7209
+ }
7210
+ styledText(text, style) {
7211
+ this.createChild("span").setStyle(style).createTextChild(text);
7212
+ return this;
7213
+ }
7214
+ inputText(text) {
7215
+ const colors = JsonMLElement.getColors();
7216
+ return this.coloredText(text, colors.inputColor);
7217
+ }
7218
+ outputText(text) {
7219
+ const colors = JsonMLElement.getColors();
7220
+ return this.coloredText(text, colors.outputColor);
7221
+ }
7222
+ greyText(text) {
7223
+ const colors = JsonMLElement.getColors();
7224
+ return this.coloredText(text, colors.grey);
7225
+ }
7226
+ highlightText(text) {
7227
+ const colors = JsonMLElement.getColors();
7228
+ return this.coloredText(text, colors.yellow);
7229
+ }
7230
+ sectionHeader(text) {
7231
+ return this.styledText(text, "font-weight: bold;");
7232
+ }
7233
+ pill(text) {
7234
+ return this.styledText(text, "color: #009; background-color: #ccf; padding: 2px 4px; border-radius: 4px; font-size: 0.7em;");
7235
+ }
7236
+ methodSignature(name, params = "") {
7237
+ const colors = JsonMLElement.getColors();
7238
+ this.styledText("." + name, `font-weight: bold;color:${colors.yellow}`);
7239
+ if (params)
7240
+ this.greyText(`(${params})`);
7241
+ return this;
7242
+ }
7243
+ parameterList(params, isOutput = false) {
7244
+ params.forEach((param, i) => {
7245
+ if (i > 0)
7246
+ this.greyText(`, `);
7247
+ if (isOutput) {
7248
+ this.outputText(param.name);
7249
+ } else {
7250
+ this.inputText(param.name);
7251
+ }
7252
+ this.greyText(`: `);
7253
+ this.createValueObject(param.value);
7254
+ });
7255
+ return this;
7256
+ }
7257
+ propertyBlock(params) {
7258
+ for (const [key, value] of Object.entries(params)) {
7259
+ const item = this.createListItem("");
7260
+ item.inputText(key);
7261
+ item.greyText(`: `);
7262
+ item.createValueObject(value);
7263
+ }
7264
+ return this;
7265
+ }
7266
+ createListItem(text, style) {
7267
+ const li = this.createChild("li").setStyle(`padding-left: 10px;${style ? " " + style : ""}`);
7268
+ if (text)
7269
+ li.createTextChild(text);
7270
+ return li;
7271
+ }
7272
+ createHighlightedListItem(text) {
7273
+ const colors = JsonMLElement.getColors();
7274
+ this.createChild("li").setStyle(`color:${colors.yellow}; padding-left: 10px;`).createTextChild(text);
7275
+ return this;
7276
+ }
7277
+ createStatusListItem(text) {
7278
+ this.createStyledList("Status: ");
7279
+ let color = "grey";
7280
+ switch (text) {
7281
+ case TaskStatus.COMPLETED:
7282
+ color = "green";
7283
+ break;
7284
+ case TaskStatus.ABORTING:
7285
+ case TaskStatus.FAILED:
7286
+ color = "red";
7287
+ break;
7288
+ default:
7289
+ color = "grey";
7290
+ }
7291
+ return this.createListItem(text, `padding-left: 30px;color: ${color};`);
7292
+ }
7293
+ createStyledList(title) {
7294
+ const list = this.createChild("ol").setStyle("list-style-type: none; padding-left: 10px;");
7295
+ if (title)
7296
+ list.createTextChild(title);
7297
+ return list;
7298
+ }
7299
+ objectBraces(content) {
7300
+ this.greyText("{ ");
7301
+ content(this);
7302
+ this.greyText(" }");
7303
+ return this;
7304
+ }
7305
+ functionCall(content) {
7306
+ this.greyText("(");
7307
+ content(this);
7308
+ this.greyText(")");
7309
+ return this;
7310
+ }
7311
+ createChild(tagName) {
7312
+ const c = new JsonMLElement(tagName);
7313
+ this._jsonML.push(c.toJsonML());
7314
+ return c;
7315
+ }
7316
+ createObjectTag(object, config) {
7317
+ const tag = this.createChild("object");
7318
+ tag.addAttribute("object", object);
7319
+ if (config) {
7320
+ tag.addAttribute("config", config);
7321
+ }
7322
+ return tag;
7323
+ }
7324
+ createValueObject(value, config) {
7325
+ if (Array.isArray(value))
7326
+ return this.createArrayChild(value, config);
7327
+ if (typeof value === "undefined") {
7328
+ const colors = JsonMLElement.getColors();
7329
+ return this.createChild("span").setStyle(`color:${colors.undefined};`).createTextChild("undefined");
7330
+ }
7331
+ return this.createObjectTag(value, config);
7332
+ }
7333
+ setStyle(style) {
7334
+ this._attributes["style"] = style;
7335
+ return this;
7336
+ }
7337
+ addAttribute(key, value) {
7338
+ this._attributes[key] = value;
7339
+ return this;
7340
+ }
7341
+ createTextChild(text) {
7342
+ this._jsonML.push(text + "");
7343
+ return this;
7344
+ }
7345
+ createArrayChild(array, config) {
7346
+ const j = new JsonMLElement("span");
7347
+ j.createTextChild("[");
7348
+ for (let i = 0;i < array.length; ++i) {
7349
+ if (i != 0)
7350
+ j.createTextChild(", ");
7351
+ j.createValueObject(array[i], config);
7352
+ }
7353
+ j.createTextChild("]");
7354
+ this._jsonML.push(j.toJsonML());
7355
+ return j;
7356
+ }
7357
+ toJsonML() {
7358
+ return this._jsonML;
7359
+ }
7360
+ }
7361
+ function computeLayout(graph, canvasWidth) {
7362
+ const positions = {};
7363
+ const layers = new Map;
7364
+ const depths = {};
7365
+ for (const node of graph.topologicallySortedNodes()) {
7366
+ const incomingEdges = graph.inEdges(node.config.id).map(([from]) => from);
7367
+ const depth = incomingEdges.length > 0 ? Math.max(...incomingEdges.map((from) => depths[from])) + 1 : 0;
7368
+ depths[node.config.id] = depth;
7369
+ if (!layers.has(depth))
7370
+ layers.set(depth, []);
7371
+ layers.get(depth).push(node.config.id);
7372
+ }
7373
+ const totalLayers = layers.size;
7374
+ const layerSpacing = totalLayers > 1 ? Math.max(canvasWidth / totalLayers, 150) : 150;
7375
+ const maxNodesInLayer = Math.max(...Array.from(layers.values()).map((layer) => layer.length));
7376
+ const nodeSpacing = 100;
7377
+ const requiredHeight = maxNodesInLayer * nodeSpacing + 100;
7378
+ layers.forEach((layerNodes, layerIndex) => {
7379
+ const yStart = (requiredHeight - layerNodes.length * nodeSpacing) / 2;
7380
+ layerNodes.forEach((nodeId, index) => {
7381
+ positions[nodeId] = {
7382
+ x: layerIndex * layerSpacing + layerSpacing / 2,
7383
+ y: yStart + index * nodeSpacing
7384
+ };
7385
+ });
7386
+ });
7387
+ return { positions, requiredHeight };
7388
+ }
7389
+ function generateGraphImage(graph, width = 800) {
7390
+ const ratio = window.devicePixelRatio || 1;
7391
+ const { positions, requiredHeight } = computeLayout(graph, width);
7392
+ const canvas = document.createElement("canvas");
7393
+ canvas.width = width * ratio;
7394
+ canvas.height = requiredHeight * ratio;
7395
+ const ctx = canvas.getContext("2d");
7396
+ if (!ctx) {
7397
+ console.error("Canvas context is not available.");
7398
+ return { dataURL: "", height: requiredHeight };
7399
+ }
7400
+ ctx.scale(ratio, ratio);
7401
+ ctx.clearRect(0, 0, width, requiredHeight);
7402
+ ctx.strokeStyle = "#aaa";
7403
+ ctx.lineWidth = 2;
7404
+ for (const [source, target] of graph.getEdges()) {
7405
+ const fromNode = positions[source];
7406
+ const toNode = positions[target];
7407
+ if (fromNode && toNode) {
7408
+ ctx.beginPath();
7409
+ ctx.moveTo(fromNode.x, fromNode.y);
7410
+ ctx.lineTo(toNode.x, toNode.y);
7411
+ ctx.stroke();
7412
+ }
7413
+ }
7414
+ ctx.fillStyle = "#3498db";
7415
+ for (const node of graph.getNodes()) {
7416
+ const pos = positions[node.config.id];
7417
+ ctx.beginPath();
7418
+ ctx.arc(pos.x, pos.y, 10, 0, Math.PI * 2);
7419
+ ctx.fill();
7420
+ ctx.fillStyle = "black";
7421
+ ctx.font = `12px Arial`;
7422
+ ctx.textAlign = "center";
7423
+ ctx.fillText(node.type ?? "", pos.x, pos.y - 15);
7424
+ ctx.fillStyle = "#3498db";
7425
+ }
7426
+ const dataURL = canvas.toDataURL("image/png");
7427
+ return { dataURL, height: requiredHeight };
7428
+ }
7429
+ function installDevToolsFormatters() {
7430
+ window.devtoolsFormatters = window.devtoolsFormatters || [];
7431
+ window.devtoolsFormatters.push(new WorkflowAPIConsoleFormatter, new CreateWorkflowConsoleFormatter, new WorkflowConsoleFormatter, new TaskConsoleFormatter, new ReactElementConsoleFormatter, new DataflowConsoleFormatter, new DAGConsoleFormatter);
7432
+ }
6794
7433
  export {
6795
7434
  wrapSchemaInArray,
6796
7435
  whileTaskConfigSchema,
@@ -6815,6 +7454,8 @@ export {
6815
7454
  isStrictArraySchema,
6816
7455
  isIterationProperty,
6817
7456
  isFlexibleSchema,
7457
+ isDarkMode,
7458
+ installDevToolsFormatters,
6818
7459
  hasVectorOutput,
6819
7460
  hasVectorLikeInput,
6820
7461
  hasStructuredOutput,
@@ -6916,4 +7557,4 @@ export {
6916
7557
  ConditionalTask
6917
7558
  };
6918
7559
 
6919
- //# debugId=B678F42D2E8DA54164756E2164756E21
7560
+ //# debugId=794A622164E9E85664756E2164756E21