@dbos-inc/dbos-sdk 2.9.9-preview → 2.9.17-preview

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 (47) hide show
  1. package/dist/src/client.d.ts +12 -1
  2. package/dist/src/client.d.ts.map +1 -1
  3. package/dist/src/client.js +28 -2
  4. package/dist/src/client.js.map +1 -1
  5. package/dist/src/conductor/conductor.d.ts.map +1 -1
  6. package/dist/src/conductor/conductor.js +26 -11
  7. package/dist/src/conductor/conductor.js.map +1 -1
  8. package/dist/src/conductor/protocol.d.ts +20 -4
  9. package/dist/src/conductor/protocol.d.ts.map +1 -1
  10. package/dist/src/conductor/protocol.js +23 -4
  11. package/dist/src/conductor/protocol.js.map +1 -1
  12. package/dist/src/dbos-executor.d.ts +14 -17
  13. package/dist/src/dbos-executor.d.ts.map +1 -1
  14. package/dist/src/dbos-executor.js +74 -174
  15. package/dist/src/dbos-executor.js.map +1 -1
  16. package/dist/src/dbos-runtime/cli.d.ts.map +1 -1
  17. package/dist/src/dbos-runtime/cli.js +87 -15
  18. package/dist/src/dbos-runtime/cli.js.map +1 -1
  19. package/dist/src/dbos-runtime/workflow_management.d.ts +13 -13
  20. package/dist/src/dbos-runtime/workflow_management.d.ts.map +1 -1
  21. package/dist/src/dbos-runtime/workflow_management.js +90 -108
  22. package/dist/src/dbos-runtime/workflow_management.js.map +1 -1
  23. package/dist/src/dbos.d.ts +29 -11
  24. package/dist/src/dbos.d.ts.map +1 -1
  25. package/dist/src/dbos.js +53 -36
  26. package/dist/src/dbos.js.map +1 -1
  27. package/dist/src/error.d.ts +11 -6
  28. package/dist/src/error.d.ts.map +1 -1
  29. package/dist/src/error.js +28 -17
  30. package/dist/src/error.js.map +1 -1
  31. package/dist/src/eventreceiver.d.ts +13 -8
  32. package/dist/src/eventreceiver.d.ts.map +1 -1
  33. package/dist/src/httpServer/server.d.ts.map +1 -1
  34. package/dist/src/httpServer/server.js +38 -12
  35. package/dist/src/httpServer/server.js.map +1 -1
  36. package/dist/src/scheduler/scheduler.js +1 -1
  37. package/dist/src/scheduler/scheduler.js.map +1 -1
  38. package/dist/src/system_database.d.ts +68 -59
  39. package/dist/src/system_database.d.ts.map +1 -1
  40. package/dist/src/system_database.js +715 -434
  41. package/dist/src/system_database.js.map +1 -1
  42. package/dist/src/workflow.d.ts +8 -0
  43. package/dist/src/workflow.d.ts.map +1 -1
  44. package/dist/src/workflow.js +7 -38
  45. package/dist/src/workflow.js.map +1 -1
  46. package/dist/tsconfig.tsbuildinfo +1 -1
  47. package/package.json +1 -1
@@ -53,6 +53,7 @@ const wfqueue_1 = require("./wfqueue");
53
53
  const debugpoint_1 = require("./debugpoint");
54
54
  const scheduler_1 = require("./scheduler/scheduler");
55
55
  const crypto = __importStar(require("crypto"));
56
+ const workflow_management_1 = require("./dbos-runtime/workflow_management");
56
57
  exports.dbosNull = {};
57
58
  function isDeprecatedDBOSConfig(config) {
58
59
  const isDeprecated = config.poolConfig !== undefined ||
@@ -114,8 +115,6 @@ class DBOSExecutor {
114
115
  stepInfoMap = new Map();
115
116
  procedureInfoMap = new Map();
116
117
  registeredOperations = [];
117
- pendingWorkflowMap = new Map(); // Map from workflowUUID to workflow promise
118
- workflowCancellationMap = new Map(); // Map from workflowUUID to its cancellation status.
119
118
  telemetryCollector;
120
119
  static defaultNotificationTimeoutSec = 60;
121
120
  debugMode;
@@ -398,10 +397,7 @@ class DBOSExecutor {
398
397
  }
399
398
  async destroy() {
400
399
  try {
401
- if (this.pendingWorkflowMap.size > 0) {
402
- this.logger.info('Waiting for pending workflows to finish.');
403
- await Promise.allSettled(this.pendingWorkflowMap.values());
404
- }
400
+ await this.systemDatabase.awaitRunningWorkflows();
405
401
  await this.systemDatabase.destroy();
406
402
  if (this.userDatabase) {
407
403
  await this.userDatabase.destroy();
@@ -522,11 +518,11 @@ class DBOSExecutor {
522
518
  }
523
519
  // TODO: getProcedureInfoByNames??
524
520
  static reviveResultOrError(r, success) {
525
- if (success === true || !r.err) {
526
- return utils_1.DBOSJSON.parse(r.res ?? null);
521
+ if (success === true || !r.error) {
522
+ return utils_1.DBOSJSON.parse(r.output ?? null);
527
523
  }
528
524
  else {
529
- throw (0, serialize_error_1.deserializeError)(utils_1.DBOSJSON.parse(r.err));
525
+ throw (0, serialize_error_1.deserializeError)(utils_1.DBOSJSON.parse(r.error));
530
526
  }
531
527
  }
532
528
  async workflow(wf, params, ...args) {
@@ -534,7 +530,7 @@ class DBOSExecutor {
534
530
  }
535
531
  // If callerUUID and functionID are set, it means the workflow is invoked from within a workflow.
536
532
  async internalWorkflow(wf, params, callerID, callerFunctionID, ...args) {
537
- const workflowID = params.workflowUUID ? params.workflowUUID : this.#generateUUID();
533
+ const workflowID = params.workflowUUID ? params.workflowUUID : (0, node_crypto_1.randomUUID)();
538
534
  const presetID = params.workflowUUID ? true : false;
539
535
  const wInfo = this.getWorkflowInfo(wf);
540
536
  if (wInfo === undefined) {
@@ -569,34 +565,31 @@ class DBOSExecutor {
569
565
  // Synchronously set the workflow's status to PENDING and record workflow inputs.
570
566
  // We have to do it for all types of workflows because operation_outputs table has a foreign key constraint on workflow status table.
571
567
  if (this.isDebugging) {
572
- // TODO: remove call to getWorkflowInputs after #871 is merged
573
568
  const wfStatus = await this.systemDatabase.getWorkflowStatus(workflowID);
574
- const wfInputs = await this.systemDatabase.getWorkflowInputs(workflowID);
575
- if (!wfStatus || !wfInputs) {
569
+ if (!wfStatus) {
576
570
  throw new error_1.DBOSDebuggerError(`Failed to find inputs for workflow UUID ${workflowID}`);
577
571
  }
578
572
  // Make sure we use the same input.
579
- if (utils_1.DBOSJSON.stringify(args) !== utils_1.DBOSJSON.stringify(wfInputs)) {
580
- throw new error_1.DBOSDebuggerError(`Detected different inputs for workflow UUID ${workflowID}.\n Received: ${utils_1.DBOSJSON.stringify(args)}\n Original: ${utils_1.DBOSJSON.stringify(wfInputs)}`);
573
+ if (utils_1.DBOSJSON.stringify(args) !== wfStatus.input) {
574
+ throw new error_1.DBOSDebuggerError(`Detected different inputs for workflow UUID ${workflowID}.\n Received: ${utils_1.DBOSJSON.stringify(args)}\n Original: ${wfStatus.input}`);
581
575
  }
582
576
  status = wfStatus.status;
583
577
  }
584
578
  else {
585
579
  // TODO: Make this transactional (and with the queue step below)
586
580
  if (callerFunctionID !== undefined && callerID !== undefined) {
587
- const cr = await this.systemDatabase.getOperationResult(callerID, callerFunctionID);
588
- if (cr.res !== undefined) {
589
- return new workflow_1.RetrievedHandle(this.systemDatabase, cr.res.child, callerID, callerFunctionID);
581
+ const result = await this.systemDatabase.getOperationResultAndThrowIfCancelled(callerID, callerFunctionID);
582
+ if (result) {
583
+ return new workflow_1.RetrievedHandle(this.systemDatabase, result.childWorkflowID, callerID, callerFunctionID);
590
584
  }
591
585
  }
592
- const ires = await this.systemDatabase.initWorkflowStatus(internalStatus, args, wCtxt.maxRecoveryAttempts);
586
+ const ires = await this.systemDatabase.initWorkflowStatus(internalStatus, utils_1.DBOSJSON.stringify(args), wCtxt.maxRecoveryAttempts);
593
587
  if (callerFunctionID !== undefined && callerID !== undefined) {
594
- await this.systemDatabase.recordOperationResult(callerID, callerFunctionID, {
595
- childWfId: workflowID,
596
- functionName: internalStatus.workflowName,
597
- }, true);
588
+ await this.systemDatabase.recordOperationResult(callerID, callerFunctionID, internalStatus.workflowName, true, {
589
+ childWorkflowID: workflowID,
590
+ });
598
591
  }
599
- args = ires.args;
592
+ args = utils_1.DBOSJSON.parse(ires.serializedInputs);
600
593
  status = ires.status;
601
594
  await (0, debugpoint_1.debugTriggerPoint)(debugpoint_1.DEBUG_TRIGGER_WORKFLOW_ENQUEUE);
602
595
  }
@@ -637,7 +630,7 @@ class DBOSExecutor {
637
630
  wCtxt.span.setStatus({ code: api_1.SpanStatusCode.OK });
638
631
  }
639
632
  catch (err) {
640
- if (err instanceof error_1.DBOSWorkflowConflictUUIDError) {
633
+ if (err instanceof error_1.DBOSWorkflowConflictError) {
641
634
  // Retrieve the handle and wait for the result.
642
635
  const retrievedHandle = this.retrieveWorkflow(workflowID);
643
636
  result = await retrievedHandle.getResult();
@@ -683,16 +676,7 @@ class DBOSExecutor {
683
676
  if (this.isDebugging ||
684
677
  (status !== 'SUCCESS' && status !== 'ERROR' && (params.queueName === undefined || params.executeWorkflow))) {
685
678
  const workflowPromise = runWorkflow();
686
- // Need to await for the workflow and capture errors.
687
- const awaitWorkflowPromise = workflowPromise
688
- .catch((error) => {
689
- this.logger.debug('Captured error in awaitWorkflowPromise: ' + error);
690
- })
691
- .finally(() => {
692
- // Remove itself from pending workflow map.
693
- this.pendingWorkflowMap.delete(workflowID);
694
- });
695
- this.pendingWorkflowMap.set(workflowID, awaitWorkflowPromise);
679
+ this.systemDatabase.registerRunningWorkflow(workflowID, workflowPromise);
696
680
  // Return the normal handle that doesn't capture errors.
697
681
  return new workflow_1.InvokedHandle(this.systemDatabase, workflowPromise, workflowID, wf.name, callerID, callerFunctionID);
698
682
  }
@@ -769,7 +753,7 @@ class DBOSExecutor {
769
753
  catch (error) {
770
754
  if (isKeyConflict(error)) {
771
755
  // Serialization and primary key conflict (Postgres).
772
- throw new error_1.DBOSWorkflowConflictUUIDError(workflowUUID);
756
+ throw new error_1.DBOSWorkflowConflictError(workflowUUID);
773
757
  }
774
758
  else {
775
759
  throw error;
@@ -790,7 +774,7 @@ class DBOSExecutor {
790
774
  catch (error) {
791
775
  if (isKeyConflict(error)) {
792
776
  // Serialization and primary key conflict (Postgres).
793
- throw new error_1.DBOSWorkflowConflictUUIDError(workflowUUID);
777
+ throw new error_1.DBOSWorkflowConflictError(workflowUUID);
794
778
  }
795
779
  else {
796
780
  throw error;
@@ -826,9 +810,7 @@ class DBOSExecutor {
826
810
  if (txnInfo === undefined) {
827
811
  throw new error_1.DBOSNotRegisteredError(txn.name);
828
812
  }
829
- if (this.workflowCancellationMap.get(wfCtx.workflowUUID) === true) {
830
- throw new error_1.DBOSWorkflowCancelledError(wfCtx.workflowUUID);
831
- }
813
+ await this.systemDatabase.checkIfCanceled(wfCtx.workflowUUID);
832
814
  let retryWaitMillis = 1;
833
815
  const backoffFactor = 1.5;
834
816
  const maxRetryWaitMs = 2000; // Maximum wait 2 seconds.
@@ -842,9 +824,7 @@ class DBOSExecutor {
842
824
  isolationLevel: txnInfo.config.isolationLevel,
843
825
  }, wfCtx.span);
844
826
  while (true) {
845
- if (this.workflowCancellationMap.get(wfCtx.workflowUUID) === true) {
846
- throw new error_1.DBOSWorkflowCancelledError(wfCtx.workflowUUID);
847
- }
827
+ await this.systemDatabase.checkIfCanceled(wfCtx.workflowUUID);
848
828
  let txn_snapshot = 'invalid';
849
829
  const workflowUUID = wfCtx.workflowUUID;
850
830
  const wrappedTransaction = async (client) => {
@@ -978,9 +958,7 @@ class DBOSExecutor {
978
958
  if (procInfo === undefined) {
979
959
  throw new error_1.DBOSNotRegisteredError(proc.name);
980
960
  }
981
- if (this.workflowCancellationMap.get(wfCtx.workflowUUID) === true) {
982
- throw new error_1.DBOSWorkflowCancelledError(wfCtx.workflowUUID);
983
- }
961
+ await this.systemDatabase.checkIfCanceled(wfCtx.workflowUUID);
984
962
  const executeLocally = this.isDebugging || (procInfo.config.executeLocally ?? false);
985
963
  const funcId = wfCtx.functionIDGetIncrement();
986
964
  const span = this.tracer.startSpan(proc.name, {
@@ -1013,9 +991,7 @@ class DBOSExecutor {
1013
991
  const backoffFactor = 1.5;
1014
992
  const maxRetryWaitMs = 2000; // Maximum wait 2 seconds.
1015
993
  while (true) {
1016
- if (this.workflowCancellationMap.get(wfCtx.workflowUUID) === true) {
1017
- throw new error_1.DBOSWorkflowCancelledError(wfCtx.workflowUUID);
1018
- }
994
+ await this.systemDatabase.checkIfCanceled(wfCtx.workflowUUID);
1019
995
  let txn_snapshot = 'invalid';
1020
996
  const wrappedProcedure = async (client) => {
1021
997
  const ctxt = new procedure_1.StoredProcedureContextImpl(client, wfCtx, span, this.logger, funcId, proc.name);
@@ -1124,9 +1100,7 @@ class DBOSExecutor {
1124
1100
  if (this.isDebugging) {
1125
1101
  throw new error_1.DBOSDebuggerError("Can't invoke stored procedure in debug mode.");
1126
1102
  }
1127
- if (this.workflowCancellationMap.get(wfCtx.workflowUUID) === true) {
1128
- throw new error_1.DBOSWorkflowCancelledError(wfCtx.workflowUUID);
1129
- }
1103
+ await this.systemDatabase.checkIfCanceled(wfCtx.workflowUUID);
1130
1104
  const $jsonCtx = {
1131
1105
  request: wfCtx.request,
1132
1106
  authenticatedUser: wfCtx.authenticatedUser,
@@ -1217,9 +1191,7 @@ class DBOSExecutor {
1217
1191
  if (commInfo === undefined) {
1218
1192
  throw new error_1.DBOSNotRegisteredError(stepFn.name);
1219
1193
  }
1220
- if (this.workflowCancellationMap.get(wfCtx.workflowUUID) === true) {
1221
- throw new error_1.DBOSWorkflowCancelledError(wfCtx.workflowUUID);
1222
- }
1194
+ await this.systemDatabase.checkIfCanceled(wfCtx.workflowUUID);
1223
1195
  const funcID = wfCtx.functionIDGetIncrement();
1224
1196
  const maxRetryIntervalSec = 3600; // Maximum retry interval: 1 hour
1225
1197
  const span = this.tracer.startSpan(stepFn.name, {
@@ -1235,12 +1207,12 @@ class DBOSExecutor {
1235
1207
  }, wfCtx.span);
1236
1208
  const ctxt = new step_1.StepContextImpl(wfCtx, funcID, span, this.logger, commInfo.config, stepFn.name);
1237
1209
  // Check if this execution previously happened, returning its original result if it did.
1238
- const checkr = await this.systemDatabase.getOperationResult(wfCtx.workflowUUID, ctxt.functionID);
1239
- if (checkr.res !== undefined) {
1240
- if (checkr.res.functionName !== ctxt.operationName) {
1241
- throw new error_1.DBOSUnexpectedStepError(ctxt.workflowUUID, ctxt.functionID, ctxt.operationName, checkr.res.functionName ?? '?');
1210
+ const checkr = await this.systemDatabase.getOperationResultAndThrowIfCancelled(wfCtx.workflowUUID, ctxt.functionID);
1211
+ if (checkr) {
1212
+ if (checkr.functionName !== ctxt.operationName) {
1213
+ throw new error_1.DBOSUnexpectedStepError(ctxt.workflowUUID, ctxt.functionID, ctxt.operationName, checkr.functionName ?? '?');
1242
1214
  }
1243
- const check = DBOSExecutor.reviveResultOrError(checkr.res);
1215
+ const check = DBOSExecutor.reviveResultOrError(checkr);
1244
1216
  ctxt.span.setAttribute('cached', true);
1245
1217
  ctxt.span.setStatus({ code: api_1.SpanStatusCode.OK });
1246
1218
  this.tracer.endSpan(ctxt.span);
@@ -1262,9 +1234,7 @@ class DBOSExecutor {
1262
1234
  }
1263
1235
  while (result === exports.dbosNull && numAttempts++ < ctxt.maxAttempts) {
1264
1236
  try {
1265
- if (this.workflowCancellationMap.get(wfCtx.workflowUUID) === true) {
1266
- throw new error_1.DBOSWorkflowCancelledError(wfCtx.workflowUUID);
1267
- }
1237
+ await this.systemDatabase.checkIfCanceled(wfCtx.workflowUUID);
1268
1238
  let cresult;
1269
1239
  if (commInfo.registration.passContext) {
1270
1240
  await (0, context_1.runWithStepContext)(ctxt, numAttempts, async () => {
@@ -1318,20 +1288,18 @@ class DBOSExecutor {
1318
1288
  if (result === exports.dbosNull) {
1319
1289
  // Record the error, then throw it.
1320
1290
  err = err === exports.dbosNull ? new error_1.DBOSMaxStepRetriesError(stepFn.name, ctxt.maxAttempts, errors) : err;
1321
- await this.systemDatabase.recordOperationResult(wfCtx.workflowUUID, ctxt.functionID, {
1322
- serialError: utils_1.DBOSJSON.stringify((0, serialize_error_1.serializeError)(err)),
1323
- functionName: ctxt.operationName,
1324
- }, true);
1291
+ await this.systemDatabase.recordOperationResult(wfCtx.workflowUUID, ctxt.functionID, ctxt.operationName, true, {
1292
+ error: utils_1.DBOSJSON.stringify((0, serialize_error_1.serializeError)(err)),
1293
+ });
1325
1294
  ctxt.span.setStatus({ code: api_1.SpanStatusCode.ERROR, message: err.message });
1326
1295
  this.tracer.endSpan(ctxt.span);
1327
1296
  throw err;
1328
1297
  }
1329
1298
  else {
1330
1299
  // Record the execution and return.
1331
- await this.systemDatabase.recordOperationResult(wfCtx.workflowUUID, ctxt.functionID, {
1332
- serialOutput: utils_1.DBOSJSON.stringify(result),
1333
- functionName: ctxt.operationName,
1334
- }, true);
1300
+ await this.systemDatabase.recordOperationResult(wfCtx.workflowUUID, ctxt.functionID, ctxt.operationName, true, {
1301
+ output: utils_1.DBOSJSON.stringify(result),
1302
+ });
1335
1303
  ctxt.span.setStatus({ code: api_1.SpanStatusCode.OK });
1336
1304
  this.tracer.endSpan(ctxt.span);
1337
1305
  return result;
@@ -1355,49 +1323,13 @@ class DBOSExecutor {
1355
1323
  async getEvent(workflowUUID, key, timeoutSeconds = DBOSExecutor.defaultNotificationTimeoutSec) {
1356
1324
  return utils_1.DBOSJSON.parse(await this.systemDatabase.getEvent(workflowUUID, key, timeoutSeconds));
1357
1325
  }
1358
- async getMaxFunctionID(workflowID) {
1359
- const rows = await this.userDatabase.query(`SELECT max(function_id) as max_function_id FROM ${DBOSExecutor.systemDBSchemaName}.transaction_outputs WHERE workflow_uuid=$1`, workflowID);
1360
- if (rows.length === 0) {
1361
- return 0;
1362
- }
1363
- else {
1364
- return rows[0].max_function_id;
1365
- }
1366
- }
1367
- async cloneWorkflowTransactions(workflowID, forkedWorkflowUUID, startStep) {
1368
- const query = `
1369
- INSERT INTO dbos.transaction_outputs
1370
- (workflow_uuid,
1371
- function_id,
1372
- output,
1373
- error,
1374
- txn_id,
1375
- txn_snapshot,
1376
- function_name)
1377
- SELECT $1 AS workflow_uuid,
1378
- function_id,
1379
- output,
1380
- error,
1381
- txn_id,
1382
- txn_snapshot,
1383
- function_name
1384
- FROM dbos.transaction_outputs WHERE workflow_uuid= $2 AND function_id < $3`;
1385
- await this.userDatabase.query(query, forkedWorkflowUUID, workflowID, startStep);
1386
- }
1387
- async getMaxStepID(workflowID) {
1388
- const maxAppFunctionID = await this.getMaxFunctionID(workflowID);
1389
- const maxSystemFunctionID = await this.systemDatabase.getMaxFunctionID(workflowID);
1390
- return Math.max(maxAppFunctionID, maxSystemFunctionID);
1391
- }
1392
1326
  /**
1393
1327
  * Fork a workflow.
1394
1328
  * The forked workflow will be assigned a new ID.
1395
1329
  */
1396
- async forkWorkflow(workflowID, startStep = 0) {
1397
- const forkedWorkflowID = this.#generateUUID();
1398
- await this.cloneWorkflowTransactions(workflowID, forkedWorkflowID, startStep);
1399
- await this.systemDatabase.forkWorkflow(workflowID, forkedWorkflowID, startStep);
1400
- return forkedWorkflowID;
1330
+ forkWorkflow(workflowID, startStep, options = {}) {
1331
+ const newWorkflowID = options.newWorkflowID ?? (0, context_1.getNextWFID)(undefined);
1332
+ return (0, workflow_management_1.forkWorkflow)(this.systemDatabase, this.userDatabase, workflowID, startStep, { ...options, newWorkflowID });
1401
1333
  }
1402
1334
  /**
1403
1335
  * Retrieve a handle for a workflow UUID.
@@ -1405,41 +1337,49 @@ class DBOSExecutor {
1405
1337
  retrieveWorkflow(workflowID) {
1406
1338
  return new workflow_1.RetrievedHandle(this.systemDatabase, workflowID);
1407
1339
  }
1408
- async runAsStep(callback, functionName, workflowID, functionID) {
1340
+ async runAsStep(callback, functionName, workflowID, functionID, childWfId) {
1409
1341
  if (workflowID !== undefined && functionID !== undefined) {
1410
- const res = await this.systemDatabase.getOperationResult(workflowID, functionID);
1411
- if (res.res !== undefined) {
1412
- if (res.res.functionName !== functionName) {
1413
- throw new error_1.DBOSUnexpectedStepError(workflowID, functionID, functionName, res.res.functionName);
1342
+ const result = await this.systemDatabase.getOperationResultAndThrowIfCancelled(workflowID, functionID);
1343
+ if (result) {
1344
+ if (result.functionName !== functionName) {
1345
+ throw new error_1.DBOSUnexpectedStepError(workflowID, functionID, functionName, result.functionName);
1414
1346
  }
1415
- return DBOSExecutor.reviveResultOrError(res.res);
1347
+ return DBOSExecutor.reviveResultOrError(result);
1416
1348
  }
1417
1349
  }
1418
1350
  try {
1419
1351
  const output = await callback();
1420
1352
  if (workflowID !== undefined && functionID !== undefined) {
1421
- await this.systemDatabase.recordOperationResult(workflowID, functionID, { serialOutput: utils_1.DBOSJSON.stringify(output), functionName }, true);
1353
+ await this.systemDatabase.recordOperationResult(workflowID, functionID, functionName, true, {
1354
+ output: utils_1.DBOSJSON.stringify(output),
1355
+ childWorkflowID: childWfId,
1356
+ });
1422
1357
  }
1423
1358
  return output;
1424
1359
  }
1425
1360
  catch (e) {
1426
1361
  if (workflowID !== undefined && functionID !== undefined) {
1427
- await this.systemDatabase.recordOperationResult(workflowID, functionID, { serialError: utils_1.DBOSJSON.stringify((0, serialize_error_1.serializeError)(e)), functionName }, false);
1362
+ await this.systemDatabase.recordOperationResult(workflowID, functionID, functionName, false, {
1363
+ error: utils_1.DBOSJSON.stringify((0, serialize_error_1.serializeError)(e)),
1364
+ childWorkflowID: childWfId,
1365
+ });
1428
1366
  }
1429
1367
  throw e;
1430
1368
  }
1431
1369
  }
1432
1370
  async getWorkflowStatus(workflowID, callerID, callerFN) {
1371
+ // use sysdb getWorkflowStatus directly in order to support caller ID/FN params
1433
1372
  const status = await this.systemDatabase.getWorkflowStatus(workflowID, callerID, callerFN);
1434
- return status ? DBOSExecutor.toWorkflowStatus(status, true) : null;
1373
+ return status ? (0, workflow_management_1.toWorkflowStatus)(status) : null;
1435
1374
  }
1436
1375
  async listWorkflows(input) {
1437
- const wfs = await this.systemDatabase.listWorkflows(input);
1438
- return wfs.map((wf) => DBOSExecutor.toWorkflowStatus(wf, true));
1376
+ return (0, workflow_management_1.listWorkflows)(this.systemDatabase, input);
1439
1377
  }
1440
1378
  async listQueuedWorkflows(input) {
1441
- const wfs = await this.systemDatabase.listQueuedWorkflows(input);
1442
- return wfs.map((wf) => DBOSExecutor.toWorkflowStatus(wf, true));
1379
+ return (0, workflow_management_1.listQueuedWorkflows)(this.systemDatabase, input);
1380
+ }
1381
+ async listWorkflowSteps(workflowID) {
1382
+ return (0, workflow_management_1.listWorkflowSteps)(this.systemDatabase, this.userDatabase, workflowID);
1443
1383
  }
1444
1384
  getWorkflowQueue(input) {
1445
1385
  return this.systemDatabase.getWorkflowQueue(input);
@@ -1473,9 +1413,6 @@ class DBOSExecutor {
1473
1413
  };
1474
1414
  }
1475
1415
  /* INTERNAL HELPERS */
1476
- #generateUUID() {
1477
- return (0, node_crypto_1.randomUUID)();
1478
- }
1479
1416
  /**
1480
1417
  * A recovery process that by default runs during executor init time.
1481
1418
  * It runs to completion all pending workflows that were executing when the previous executor failed.
@@ -1554,13 +1491,16 @@ class DBOSExecutor {
1554
1491
  }
1555
1492
  }
1556
1493
  async executeWorkflowUUID(workflowID, startNewWorkflow = false) {
1557
- // TODO: remove call to getWorkflowInputs after #871 is merged
1558
1494
  const wfStatus = await this.systemDatabase.getWorkflowStatus(workflowID);
1559
- const inputs = await this.systemDatabase.getWorkflowInputs(workflowID);
1560
- if (!inputs || !wfStatus) {
1495
+ if (!wfStatus) {
1496
+ this.logger.error(`Failed to find workflow status for workflowUUID: ${workflowID}`);
1497
+ throw new error_1.DBOSError(`Failed to find workflow status for workflow UUID: ${workflowID}`);
1498
+ }
1499
+ if (!wfStatus?.input) {
1561
1500
  this.logger.error(`Failed to find inputs for workflowUUID: ${workflowID}`);
1562
1501
  throw new error_1.DBOSError(`Failed to find inputs for workflow UUID: ${workflowID}`);
1563
1502
  }
1503
+ const inputs = utils_1.DBOSJSON.parse(wfStatus.input);
1564
1504
  const parentCtx = this.#getRecoveryContext(workflowID, wfStatus);
1565
1505
  const { wfInfo, configuredInst } = this.getWorkflowInfoByStatus(wfStatus);
1566
1506
  // If starting a new workflow, assign a new UUID. Otherwise, use the workflow's original UUID.
@@ -1572,9 +1512,7 @@ class DBOSExecutor {
1572
1512
  configuredInstance: configuredInst,
1573
1513
  queueName: wfStatus.queueName,
1574
1514
  executeWorkflow: true,
1575
- },
1576
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
1577
- ...inputs);
1515
+ }, ...inputs);
1578
1516
  }
1579
1517
  // Should be temporary workflows. Parse the name of the workflow.
1580
1518
  const wfName = wfStatus.workflowName;
@@ -1596,9 +1534,7 @@ class DBOSExecutor {
1596
1534
  configuredInstance: clsInst,
1597
1535
  queueName: wfStatus.queueName,
1598
1536
  executeWorkflow: true,
1599
- }, undefined, undefined,
1600
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
1601
- ...inputs);
1537
+ }, undefined, undefined, ...inputs);
1602
1538
  }
1603
1539
  else if (nameArr[1] === exports.TempWorkflowType.step) {
1604
1540
  const { commInfo, clsInst } = this.getStepInfoByNames(wfStatus.workflowClassName, nameArr[2], wfStatus.workflowConfigName);
@@ -1612,9 +1548,7 @@ class DBOSExecutor {
1612
1548
  configuredInstance: clsInst,
1613
1549
  queueName: wfStatus.queueName, // Probably null
1614
1550
  executeWorkflow: true,
1615
- }, undefined, undefined,
1616
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
1617
- ...inputs);
1551
+ }, undefined, undefined, ...inputs);
1618
1552
  }
1619
1553
  else if (nameArr[1] === exports.TempWorkflowType.send) {
1620
1554
  temp_workflow = async (ctxt, ...args) => {
@@ -1626,9 +1560,7 @@ class DBOSExecutor {
1626
1560
  tempWfType: exports.TempWorkflowType.send,
1627
1561
  queueName: wfStatus.queueName,
1628
1562
  executeWorkflow: true,
1629
- },
1630
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
1631
- ...inputs);
1563
+ }, ...inputs);
1632
1564
  }
1633
1565
  else {
1634
1566
  this.logger.error(`Unrecognized temporary workflow! UUID ${workflowID}, name ${wfName}`);
@@ -1654,7 +1586,6 @@ class DBOSExecutor {
1654
1586
  async cancelWorkflow(workflowID) {
1655
1587
  await this.systemDatabase.cancelWorkflow(workflowID);
1656
1588
  this.logger.info(`Cancelling workflow ${workflowID}`);
1657
- this.workflowCancellationMap.set(workflowID, true);
1658
1589
  }
1659
1590
  async getWorkflowSteps(workflowID) {
1660
1591
  const outputs = await this.systemDatabase.getAllOperationResults(workflowID);
@@ -1668,15 +1599,7 @@ class DBOSExecutor {
1668
1599
  };
1669
1600
  });
1670
1601
  }
1671
- async listWorkflowSteps(workflowID) {
1672
- const steps = await this.getWorkflowSteps(workflowID);
1673
- const transactions = await this.getTransactions(workflowID);
1674
- const merged = [...steps, ...transactions];
1675
- merged.sort((a, b) => a.function_id - b.function_id);
1676
- return merged;
1677
- }
1678
1602
  async resumeWorkflow(workflowID) {
1679
- this.workflowCancellationMap.delete(workflowID);
1680
1603
  await this.systemDatabase.resumeWorkflow(workflowID);
1681
1604
  }
1682
1605
  logRegisteredHTTPUrls() {
@@ -1722,30 +1645,7 @@ class DBOSExecutor {
1722
1645
  if (DBOSExecutor.internalQueue !== undefined) {
1723
1646
  return;
1724
1647
  }
1725
- DBOSExecutor.internalQueue = new wfqueue_1.WorkflowQueue(utils_1.INTERNAL_QUEUE_NAME);
1726
- }
1727
- static toWorkflowStatus(internal, getRequest = true) {
1728
- return {
1729
- workflowID: internal.workflowUUID,
1730
- status: internal.status,
1731
- workflowName: internal.workflowName,
1732
- workflowClassName: internal.workflowClassName,
1733
- workflowConfigName: internal.workflowConfigName,
1734
- queueName: internal.queueName,
1735
- authenticatedUser: internal.authenticatedUser,
1736
- assumedRole: internal.assumedRole,
1737
- authenticatedRoles: internal.authenticatedRoles,
1738
- input: internal.input ? utils_1.DBOSJSON.parse(internal.input) : undefined,
1739
- output: internal.output ? utils_1.DBOSJSON.parse(internal.output ?? null) : undefined,
1740
- error: internal.error ? (0, serialize_error_1.deserializeError)(utils_1.DBOSJSON.parse(internal.error)) : undefined,
1741
- request: getRequest ? internal.request : undefined,
1742
- executorId: internal.executorId,
1743
- applicationVersion: internal.applicationVersion,
1744
- applicationID: internal.applicationID,
1745
- recoveryAttempts: internal.recoveryAttempts,
1746
- createdAt: internal.createdAt,
1747
- updatedAt: internal.updatedAt,
1748
- };
1648
+ DBOSExecutor.internalQueue = new wfqueue_1.WorkflowQueue(utils_1.INTERNAL_QUEUE_NAME, {});
1749
1649
  }
1750
1650
  }
1751
1651
  exports.DBOSExecutor = DBOSExecutor;