@dbos-inc/dbos-sdk 1.29.4-preview → 1.29.11-preview

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. package/dbos-config.schema.json +7 -0
  2. package/dist/src/context.d.ts +36 -0
  3. package/dist/src/context.d.ts.map +1 -1
  4. package/dist/src/context.js +104 -1
  5. package/dist/src/context.js.map +1 -1
  6. package/dist/src/data_validation.d.ts.map +1 -1
  7. package/dist/src/data_validation.js +6 -2
  8. package/dist/src/data_validation.js.map +1 -1
  9. package/dist/src/dbos-executor.d.ts +36 -20
  10. package/dist/src/dbos-executor.d.ts.map +1 -1
  11. package/dist/src/dbos-executor.js +289 -22
  12. package/dist/src/dbos-executor.js.map +1 -1
  13. package/dist/src/dbos-runtime/cli.d.ts +2 -2
  14. package/dist/src/dbos-runtime/cli.d.ts.map +1 -1
  15. package/dist/src/dbos-runtime/cli.js +30 -5
  16. package/dist/src/dbos-runtime/cli.js.map +1 -1
  17. package/dist/src/dbos-runtime/config.d.ts.map +1 -1
  18. package/dist/src/dbos-runtime/config.js +3 -2
  19. package/dist/src/dbos-runtime/config.js.map +1 -1
  20. package/dist/src/dbos-runtime/runtime.d.ts +4 -8
  21. package/dist/src/dbos-runtime/runtime.d.ts.map +1 -1
  22. package/dist/src/dbos-runtime/runtime.js +8 -12
  23. package/dist/src/dbos-runtime/runtime.js.map +1 -1
  24. package/dist/src/dbos-runtime/start.d.ts +3 -0
  25. package/dist/src/dbos-runtime/start.d.ts.map +1 -0
  26. package/dist/src/dbos-runtime/start.js +46 -0
  27. package/dist/src/dbos-runtime/start.js.map +1 -0
  28. package/dist/src/dbos.d.ts +120 -0
  29. package/dist/src/dbos.d.ts.map +1 -0
  30. package/dist/src/dbos.js +660 -0
  31. package/dist/src/dbos.js.map +1 -0
  32. package/dist/src/debugger/debug_workflow.d.ts.map +1 -1
  33. package/dist/src/debugger/debug_workflow.js +5 -1
  34. package/dist/src/debugger/debug_workflow.js.map +1 -1
  35. package/dist/src/decorators.d.ts +11 -2
  36. package/dist/src/decorators.d.ts.map +1 -1
  37. package/dist/src/decorators.js +30 -8
  38. package/dist/src/decorators.js.map +1 -1
  39. package/dist/src/error.d.ts +6 -0
  40. package/dist/src/error.d.ts.map +1 -1
  41. package/dist/src/error.js +20 -2
  42. package/dist/src/error.js.map +1 -1
  43. package/dist/src/eventreceiver.d.ts +6 -2
  44. package/dist/src/eventreceiver.d.ts.map +1 -1
  45. package/dist/src/httpServer/handler.d.ts +0 -1
  46. package/dist/src/httpServer/handler.d.ts.map +1 -1
  47. package/dist/src/httpServer/handler.js +5 -13
  48. package/dist/src/httpServer/handler.js.map +1 -1
  49. package/dist/src/httpServer/middleware.d.ts +13 -2
  50. package/dist/src/httpServer/middleware.d.ts.map +1 -1
  51. package/dist/src/httpServer/middleware.js +101 -1
  52. package/dist/src/httpServer/middleware.js.map +1 -1
  53. package/dist/src/httpServer/server.d.ts +9 -5
  54. package/dist/src/httpServer/server.d.ts.map +1 -1
  55. package/dist/src/httpServer/server.js +58 -33
  56. package/dist/src/httpServer/server.js.map +1 -1
  57. package/dist/src/index.d.ts +2 -1
  58. package/dist/src/index.d.ts.map +1 -1
  59. package/dist/src/index.js +3 -3
  60. package/dist/src/index.js.map +1 -1
  61. package/dist/src/procedure.d.ts +1 -0
  62. package/dist/src/procedure.d.ts.map +1 -1
  63. package/dist/src/procedure.js.map +1 -1
  64. package/dist/src/scheduler/scheduler.d.ts.map +1 -1
  65. package/dist/src/scheduler/scheduler.js +3 -1
  66. package/dist/src/scheduler/scheduler.js.map +1 -1
  67. package/dist/src/telemetry/logs.d.ts +11 -5
  68. package/dist/src/telemetry/logs.d.ts.map +1 -1
  69. package/dist/src/telemetry/logs.js +8 -11
  70. package/dist/src/telemetry/logs.js.map +1 -1
  71. package/dist/src/testing/testing_runtime.js +3 -3
  72. package/dist/src/testing/testing_runtime.js.map +1 -1
  73. package/dist/src/user_database.d.ts +1 -1
  74. package/dist/src/user_database.d.ts.map +1 -1
  75. package/dist/src/workflow.d.ts +7 -6
  76. package/dist/src/workflow.d.ts.map +1 -1
  77. package/dist/src/workflow.js +10 -187
  78. package/dist/src/workflow.js.map +1 -1
  79. package/dist/tsconfig.build.tsbuildinfo +1 -1
  80. package/package.json +5 -1
@@ -0,0 +1,660 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DBOS = void 0;
4
+ const context_1 = require("./context");
5
+ const dbos_executor_1 = require("./dbos-executor");
6
+ const logs_1 = require("./telemetry/logs");
7
+ const error_1 = require("./error");
8
+ const config_1 = require("./dbos-runtime/config");
9
+ const scheduler_1 = require("./scheduler/scheduler");
10
+ const decorators_1 = require("./decorators");
11
+ const utils_1 = require("./utils");
12
+ const server_1 = require("./httpServer/server");
13
+ const middleware_1 = require("./httpServer/middleware");
14
+ const wfqueue_1 = require("./wfqueue");
15
+ const handlerTypes_1 = require("./httpServer/handlerTypes");
16
+ function httpApiDec(verb, url) {
17
+ return function apidec(target, propertyKey, inDescriptor) {
18
+ const { descriptor, registration } = (0, decorators_1.registerAndWrapContextFreeFunction)(target, propertyKey, inDescriptor);
19
+ const handlerRegistration = registration;
20
+ handlerRegistration.apiURL = url;
21
+ handlerRegistration.apiType = verb;
22
+ return descriptor;
23
+ };
24
+ }
25
+ class DBOS {
26
+ ///////
27
+ // Lifecycle
28
+ ///////
29
+ static adminServer = undefined;
30
+ static appServer = undefined;
31
+ static setConfig(config, runtimeConfig) {
32
+ DBOS.dbosConfig = config;
33
+ DBOS.runtimeConfig = runtimeConfig;
34
+ }
35
+ static async launch(httpApps) {
36
+ // Do nothing is DBOS is already initialized
37
+ if (dbos_executor_1.DBOSExecutor.globalInstance)
38
+ return;
39
+ // Initialize the DBOS executor
40
+ if (!DBOS.dbosConfig) {
41
+ const [dbosConfig, runtimeConfig] = (0, config_1.parseConfigFile)();
42
+ DBOS.dbosConfig = dbosConfig;
43
+ DBOS.runtimeConfig = runtimeConfig;
44
+ }
45
+ dbos_executor_1.DBOSExecutor.globalInstance = new dbos_executor_1.DBOSExecutor(DBOS.dbosConfig);
46
+ const executor = dbos_executor_1.DBOSExecutor.globalInstance;
47
+ await executor.init();
48
+ dbos_executor_1.DBOSExecutor.globalInstance.scheduler = new scheduler_1.DBOSScheduler(dbos_executor_1.DBOSExecutor.globalInstance);
49
+ dbos_executor_1.DBOSExecutor.globalInstance.scheduler.initScheduler();
50
+ dbos_executor_1.DBOSExecutor.globalInstance.wfqEnded = wfqueue_1.wfQueueRunner.dispatchLoop(dbos_executor_1.DBOSExecutor.globalInstance);
51
+ for (const evtRcvr of dbos_executor_1.DBOSExecutor.globalInstance.eventReceivers) {
52
+ await evtRcvr.initialize(dbos_executor_1.DBOSExecutor.globalInstance);
53
+ }
54
+ // Start the DBOS admin server
55
+ const logger = DBOS.logger;
56
+ if (DBOS.runtimeConfig) {
57
+ const adminApp = server_1.DBOSHttpServer.setupAdminApp(executor);
58
+ await server_1.DBOSHttpServer.checkPortAvailabilityIPv4Ipv6(DBOS.runtimeConfig.admin_port, logger);
59
+ DBOS.adminServer = adminApp.listen(DBOS.runtimeConfig.admin_port, () => {
60
+ this.logger.info(`DBOS Admin Server is running at http://localhost:${DBOS.runtimeConfig?.admin_port}`);
61
+ });
62
+ }
63
+ // Create the DBOS HTTP server
64
+ // This may be a no-op if there are no registered endpoints
65
+ const server = new server_1.DBOSHttpServer(dbos_executor_1.DBOSExecutor.globalInstance);
66
+ if (DBOS.runtimeConfig) {
67
+ // This will not listen if there's no decorated endpoint
68
+ DBOS.appServer = await server.appListen(DBOS.runtimeConfig.port);
69
+ }
70
+ if (httpApps) {
71
+ if (httpApps.koaApp) {
72
+ DBOS.logger.info("Setting up Koa tracing middleware");
73
+ httpApps.koaApp.use(middleware_1.koaTracingMiddleware);
74
+ }
75
+ if (httpApps.expressApp) {
76
+ DBOS.logger.info("Setting up Express tracing middleware");
77
+ httpApps.expressApp.use(middleware_1.expressTracingMiddleware);
78
+ }
79
+ if (httpApps.fastifyApp) {
80
+ // Fastify can use express or middie under the hood, for middlewares.
81
+ // Middie happens to have the same semantic than express.
82
+ // See https://fastify.dev/docs/latest/Reference/Middleware/
83
+ DBOS.logger.info("Setting up Fastify tracing middleware");
84
+ httpApps.fastifyApp.use(middleware_1.expressTracingMiddleware);
85
+ }
86
+ if (httpApps.nestApp) {
87
+ // Nest.kj can use express or fastify under the hood. With fastify, Nest.js uses middie.
88
+ DBOS.logger.info("Setting up NestJS tracing middleware");
89
+ httpApps.nestApp.use(middleware_1.expressTracingMiddleware);
90
+ }
91
+ }
92
+ }
93
+ static async shutdown() {
94
+ // Stop the app server
95
+ if (DBOS.appServer) {
96
+ DBOS.appServer.close();
97
+ DBOS.appServer = undefined;
98
+ }
99
+ // Stop the admin server
100
+ if (DBOS.adminServer) {
101
+ DBOS.adminServer.close();
102
+ DBOS.adminServer = undefined;
103
+ }
104
+ // Stop the executor
105
+ if (dbos_executor_1.DBOSExecutor.globalInstance) {
106
+ await dbos_executor_1.DBOSExecutor.globalInstance.deactivateEventReceivers();
107
+ await dbos_executor_1.DBOSExecutor.globalInstance.destroy();
108
+ dbos_executor_1.DBOSExecutor.globalInstance = undefined;
109
+ }
110
+ }
111
+ static get executor() {
112
+ if (!dbos_executor_1.DBOSExecutor.globalInstance) {
113
+ throw new error_1.DBOSExecutorNotInitializedError();
114
+ }
115
+ return dbos_executor_1.DBOSExecutor.globalInstance;
116
+ }
117
+ // This retrieves the HTTP handlers callback for DBOS HTTP.
118
+ // (This is the one that handles the @DBOS.getApi, etc., methods.)
119
+ // Useful for testing purposes, or to combine the DBOS service with routes.
120
+ // If you are using your own HTTP server, this won't return anything.
121
+ static getHTTPHandlersCallback() {
122
+ if (!server_1.DBOSHttpServer.instance)
123
+ return undefined;
124
+ return server_1.DBOSHttpServer.instance.app.callback();
125
+ }
126
+ //////
127
+ // Globals
128
+ //////
129
+ static globalLogger;
130
+ static dbosConfig;
131
+ static runtimeConfig = undefined;
132
+ static invokeWrappers = new Map();
133
+ //////
134
+ // Context
135
+ //////
136
+ static get logger() {
137
+ const ctx = (0, context_1.getCurrentDBOSContext)();
138
+ if (ctx)
139
+ return ctx.logger;
140
+ const executor = DBOS.executor;
141
+ if (executor)
142
+ return executor.logger;
143
+ return new logs_1.GlobalLogger();
144
+ }
145
+ static get span() {
146
+ const ctx = (0, context_1.getCurrentDBOSContext)();
147
+ if (ctx)
148
+ return ctx.span;
149
+ return undefined;
150
+ }
151
+ static get request() {
152
+ return (0, context_1.getCurrentDBOSContext)()?.request;
153
+ }
154
+ static get koaContext() {
155
+ return (0, context_1.getCurrentDBOSContext)()?.koaContext;
156
+ }
157
+ static get workflowID() {
158
+ return (0, context_1.getCurrentDBOSContext)()?.workflowUUID;
159
+ }
160
+ static get authenticatedUser() {
161
+ return (0, context_1.getCurrentDBOSContext)()?.authenticatedUser ?? "";
162
+ }
163
+ static get authenticatedRoles() {
164
+ return (0, context_1.getCurrentDBOSContext)()?.authenticatedRoles ?? [];
165
+ }
166
+ static get assumedRole() {
167
+ return (0, context_1.getCurrentDBOSContext)()?.assumedRole ?? "";
168
+ }
169
+ static isInTransaction() {
170
+ return (0, context_1.getCurrentContextStore)()?.curTxFunctionId !== undefined;
171
+ }
172
+ static isInStep() {
173
+ return (0, context_1.getCurrentContextStore)()?.curStepFunctionId !== undefined;
174
+ }
175
+ static isWithinWorkflow() {
176
+ return (0, context_1.getCurrentContextStore)()?.workflowId !== undefined;
177
+ }
178
+ static isInWorkflow() {
179
+ return DBOS.isWithinWorkflow() && !DBOS.isInTransaction() && !DBOS.isInStep();
180
+ }
181
+ // TODO CTX parent workflow ID
182
+ // sql session (various forms)
183
+ static get sqlClient() {
184
+ if (!DBOS.isInTransaction())
185
+ throw new error_1.DBOSInvalidWorkflowTransitionError();
186
+ const ctx = (0, context_1.assertCurrentDBOSContext)();
187
+ return ctx.client;
188
+ }
189
+ static get pgClient() {
190
+ const client = DBOS.sqlClient;
191
+ // TODO CTX check!
192
+ return client;
193
+ }
194
+ static get knexClient() {
195
+ const client = DBOS.sqlClient;
196
+ // TODO CTX check!
197
+ return client;
198
+ }
199
+ static get prismaClient() {
200
+ const client = DBOS.sqlClient;
201
+ // TODO CTX check!
202
+ return client;
203
+ }
204
+ static get typeORMClient() {
205
+ const client = DBOS.sqlClient;
206
+ // TODO CTX check!
207
+ return client;
208
+ }
209
+ static get drizzleClient() {
210
+ const client = DBOS.sqlClient;
211
+ // TODO CTX check!
212
+ return client;
213
+ }
214
+ static getConfig(key, defaultValue) {
215
+ const ctx = (0, context_1.getCurrentDBOSContext)();
216
+ if (ctx && defaultValue)
217
+ return ctx.getConfig(key, defaultValue);
218
+ if (ctx)
219
+ return ctx.getConfig(key);
220
+ if (DBOS.executor)
221
+ return DBOS.executor.getConfig(key, defaultValue);
222
+ return defaultValue;
223
+ }
224
+ //////
225
+ // Workflow and other operations
226
+ //////
227
+ static getWorkflowStatus(workflowID) {
228
+ return DBOS.executor.getWorkflowStatus(workflowID);
229
+ }
230
+ static retrieveWorkflow(workflowID) {
231
+ return DBOS.executor.retrieveWorkflow(workflowID);
232
+ }
233
+ static async getWorkflows(input) {
234
+ return await DBOS.executor.getWorkflows(input);
235
+ }
236
+ static async getWorkflowQueue(input) {
237
+ return await DBOS.executor.getWorkflowQueue(input);
238
+ }
239
+ static async sleepms(durationMS) {
240
+ if (DBOS.isWithinWorkflow()) {
241
+ if (DBOS.isInTransaction() || DBOS.isInStep()) {
242
+ throw new error_1.DBOSInvalidWorkflowTransitionError();
243
+ }
244
+ return (0, context_1.getCurrentDBOSContext)().sleepms(durationMS);
245
+ }
246
+ await (0, utils_1.sleepms)(durationMS);
247
+ }
248
+ static async sleep(durationSec) {
249
+ return this.sleepms(durationSec * 1000);
250
+ }
251
+ static async withNextWorkflowID(wfid, callback) {
252
+ const pctx = (0, context_1.getCurrentContextStore)();
253
+ if (pctx) {
254
+ const pcwfid = pctx.idAssignedForNextWorkflow;
255
+ try {
256
+ pctx.idAssignedForNextWorkflow = wfid;
257
+ return callback();
258
+ }
259
+ finally {
260
+ pctx.idAssignedForNextWorkflow = pcwfid;
261
+ }
262
+ }
263
+ else {
264
+ return (0, context_1.runWithTopContext)({ idAssignedForNextWorkflow: wfid }, callback);
265
+ }
266
+ }
267
+ static async withTracedContext(callerName, span, request, callback) {
268
+ const pctx = (0, context_1.getCurrentContextStore)();
269
+ if (pctx) {
270
+ pctx.operationCaller = callerName;
271
+ pctx.span = span;
272
+ pctx.request = request;
273
+ return callback();
274
+ }
275
+ else {
276
+ return (0, context_1.runWithTopContext)({ span, request }, callback);
277
+ }
278
+ }
279
+ static async withAuthedContext(authedUser, authedRoles, callback) {
280
+ const pctx = (0, context_1.getCurrentContextStore)();
281
+ if (pctx) {
282
+ pctx.authenticatedUser = authedUser;
283
+ pctx.authenticatedRoles = authedRoles;
284
+ return callback();
285
+ }
286
+ else {
287
+ return (0, context_1.runWithTopContext)({ authenticatedUser: authedUser, authenticatedRoles: authedRoles }, callback);
288
+ }
289
+ }
290
+ // This generic setter helps users calling DBOS operation to pass a name, later used in seeding a parent OTel span for the operation.
291
+ static async withNamedContext(callerName, callback) {
292
+ const pctx = (0, context_1.getCurrentContextStore)();
293
+ if (pctx) {
294
+ pctx.operationCaller = callerName;
295
+ return callback();
296
+ }
297
+ else {
298
+ return (0, context_1.runWithTopContext)({ operationCaller: callerName }, callback);
299
+ }
300
+ }
301
+ static async withWorkflowQueue(wfq, callback) {
302
+ const pctx = (0, context_1.getCurrentContextStore)();
303
+ if (pctx) {
304
+ const pcwfq = pctx.queueAssignedForWorkflows;
305
+ try {
306
+ pctx.queueAssignedForWorkflows = wfq;
307
+ return callback();
308
+ }
309
+ finally {
310
+ pctx.queueAssignedForWorkflows = pcwfq;
311
+ }
312
+ }
313
+ else {
314
+ return (0, context_1.runWithTopContext)({ queueAssignedForWorkflows: wfq }, callback);
315
+ }
316
+ }
317
+ static startWorkflow(target) {
318
+ if (typeof target === 'function') {
319
+ return DBOS.proxyInvokeWF(target, null);
320
+ }
321
+ else {
322
+ return DBOS.proxyInvokeWF(target, target);
323
+ }
324
+ }
325
+ static proxyInvokeWF(object, configuredInstance) {
326
+ const ops = (0, decorators_1.getRegisteredOperations)(object);
327
+ const proxy = {};
328
+ const pctx = (0, context_1.getCurrentContextStore)();
329
+ let wfId = pctx?.idAssignedForNextWorkflow;
330
+ // If this is called from within a workflow, this is a child workflow,
331
+ // For OAOO, we will need a consistent ID formed from the parent WF and call number
332
+ if (DBOS.isWithinWorkflow()) {
333
+ const wfctx = (0, context_1.assertCurrentWorkflowContext)();
334
+ const funcId = wfctx.functionIDGetIncrement();
335
+ wfId = wfId || (wfctx.workflowUUID + "-" + funcId);
336
+ const params = {
337
+ workflowUUID: wfId,
338
+ parentCtx: wfctx,
339
+ configuredInstance,
340
+ queueName: pctx?.queueAssignedForWorkflows
341
+ };
342
+ for (const op of ops) {
343
+ proxy[op.name] = op.workflowConfig
344
+ ? (...args) => dbos_executor_1.DBOSExecutor.globalInstance.internalWorkflow(op.registeredFunction, params, wfctx.workflowUUID, funcId, ...args)
345
+ : undefined;
346
+ }
347
+ return proxy;
348
+ }
349
+ // Else, we setup a parent context that includes all the potential metadata the application could have set in DBOSLocalCtx
350
+ let parentCtx = undefined;
351
+ if (pctx) {
352
+ // If pctx has no span, e.g., has not been setup through `withTracedContext`, set up a parent span for the workflow here.
353
+ let span = pctx.span;
354
+ if (!span) {
355
+ span = DBOS.executor.tracer.startSpan(pctx.operationCaller || "startWorkflow", {
356
+ operationUUID: wfId,
357
+ operationType: pctx.operationType,
358
+ authenticatedUser: pctx.authenticatedUser,
359
+ assumedRole: pctx.assumedRole,
360
+ authenticatedRoles: pctx.authenticatedRoles,
361
+ });
362
+ }
363
+ parentCtx = new context_1.DBOSContextImpl(pctx.operationCaller || "startWorkflow", span, DBOS.logger);
364
+ parentCtx.request = pctx.request || {};
365
+ parentCtx.authenticatedUser = pctx.authenticatedUser || "";
366
+ parentCtx.assumedRole = pctx.assumedRole || "";
367
+ parentCtx.authenticatedRoles = pctx.authenticatedRoles || [];
368
+ parentCtx.workflowUUID = wfId || "";
369
+ }
370
+ const wfParams = {
371
+ workflowUUID: wfId,
372
+ queueName: pctx?.queueAssignedForWorkflows,
373
+ configuredInstance,
374
+ parentCtx,
375
+ };
376
+ for (const op of ops) {
377
+ proxy[op.name] = op.workflowConfig
378
+ ? (...args) => DBOS.executor.workflow(op.registeredFunction, wfParams, ...args)
379
+ : undefined;
380
+ }
381
+ // TODO CTX - should we put helpful errors for any function that may have "compiled" but is not a workflow?
382
+ return proxy;
383
+ }
384
+ static invoke(object) {
385
+ const wfctx = (0, context_1.assertCurrentWorkflowContext)();
386
+ if (typeof object === 'function') {
387
+ const ops = (0, decorators_1.getRegisteredOperations)(object);
388
+ const proxy = {};
389
+ for (const op of ops) {
390
+ proxy[op.name] = op.txnConfig
391
+ ? (...args) => dbos_executor_1.DBOSExecutor.globalInstance.callTransactionFunction(op.registeredFunction, null, wfctx, ...args)
392
+ : op.commConfig
393
+ ? (...args) => dbos_executor_1.DBOSExecutor.globalInstance.callStepFunction(op.registeredFunction, null, wfctx, ...args)
394
+ : op.procConfig
395
+ ? (...args) => wfctx.procedure(op.registeredFunction, ...args)
396
+ : undefined;
397
+ }
398
+ return proxy;
399
+ }
400
+ else {
401
+ const targetInst = object;
402
+ const ops = (0, decorators_1.getRegisteredOperations)(targetInst);
403
+ const proxy = {};
404
+ for (const op of ops) {
405
+ proxy[op.name] = op.txnConfig
406
+ ? (...args) => dbos_executor_1.DBOSExecutor.globalInstance.callTransactionFunction(op.registeredFunction, targetInst, wfctx, ...args)
407
+ : op.commConfig
408
+ ? (...args) => dbos_executor_1.DBOSExecutor.globalInstance.callStepFunction(op.registeredFunction, targetInst, wfctx, ...args)
409
+ : undefined;
410
+ }
411
+ return proxy;
412
+ }
413
+ }
414
+ static async send(destinationID, message, topic) {
415
+ if (DBOS.isWithinWorkflow()) {
416
+ if (!DBOS.isInWorkflow()) {
417
+ throw new error_1.DBOSInvalidWorkflowTransitionError();
418
+ }
419
+ return (0, context_1.getCurrentDBOSContext)().send(destinationID, message, topic);
420
+ }
421
+ return DBOS.executor.send(destinationID, message, topic);
422
+ }
423
+ static async recv(topic, timeoutSeconds) {
424
+ if (DBOS.isWithinWorkflow()) {
425
+ if (!DBOS.isInWorkflow()) {
426
+ throw new error_1.DBOSInvalidWorkflowTransitionError();
427
+ }
428
+ return (0, context_1.getCurrentDBOSContext)().recv(topic, timeoutSeconds);
429
+ }
430
+ throw new error_1.DBOSInvalidWorkflowTransitionError(); // Only workflows can recv
431
+ }
432
+ static async setEvent(key, value) {
433
+ if (DBOS.isWithinWorkflow()) {
434
+ if (!DBOS.isInWorkflow()) {
435
+ throw new error_1.DBOSInvalidWorkflowTransitionError();
436
+ }
437
+ return (0, context_1.getCurrentDBOSContext)().setEvent(key, value);
438
+ }
439
+ throw new error_1.DBOSInvalidWorkflowTransitionError(); // Only workflows can set event
440
+ }
441
+ static async getEvent(workflowID, key, timeoutSeconds) {
442
+ if (DBOS.isWithinWorkflow()) {
443
+ if (!DBOS.isInWorkflow()) {
444
+ throw new error_1.DBOSInvalidWorkflowTransitionError();
445
+ }
446
+ return (0, context_1.getCurrentDBOSContext)().getEvent(workflowID, key, timeoutSeconds);
447
+ }
448
+ return DBOS.executor.getEvent(workflowID, key, timeoutSeconds);
449
+ }
450
+ //////
451
+ // Decorators
452
+ //////
453
+ static scheduled(schedulerConfig) {
454
+ function scheddec(target, propertyKey, inDescriptor) {
455
+ const { descriptor, registration } = (0, decorators_1.registerAndWrapContextFreeFunction)(target, propertyKey, inDescriptor);
456
+ const schedRegistration = registration;
457
+ schedRegistration.schedulerConfig = schedulerConfig;
458
+ return descriptor;
459
+ }
460
+ return scheddec;
461
+ }
462
+ static workflow(config = {}) {
463
+ function decorator(target, propertyKey, inDescriptor) {
464
+ const { descriptor, registration } = (0, decorators_1.registerAndWrapContextFreeFunction)(target, propertyKey, inDescriptor);
465
+ registration.workflowConfig = config;
466
+ const invokeWrapper = async function (...rawArgs) {
467
+ const pctx = (0, context_1.getCurrentContextStore)();
468
+ let inst = undefined;
469
+ if (typeof this === 'function') {
470
+ // This is static
471
+ }
472
+ else {
473
+ inst = this;
474
+ if (!("name" in inst)) {
475
+ throw new error_1.DBOSInvalidWorkflowTransitionError();
476
+ }
477
+ }
478
+ let wfId = pctx?.idAssignedForNextWorkflow;
479
+ // If this is called from within a workflow, this is a child workflow,
480
+ // For OAOO, we will need a consistent ID formed from the parent WF and call number
481
+ if (DBOS.isWithinWorkflow()) {
482
+ const wfctx = (0, context_1.assertCurrentWorkflowContext)();
483
+ const funcId = wfctx.functionIDGetIncrement();
484
+ wfId = wfId || (wfctx.workflowUUID + "-" + funcId);
485
+ const params = {
486
+ workflowUUID: wfId,
487
+ parentCtx: wfctx,
488
+ configuredInstance: inst,
489
+ queueName: pctx?.queueAssignedForWorkflows
490
+ };
491
+ const cwfh = await dbos_executor_1.DBOSExecutor.globalInstance.internalWorkflow(registration.registeredFunction, params, wfctx.workflowUUID, funcId, ...rawArgs);
492
+ return await cwfh.getResult();
493
+ }
494
+ // Else, we setup a parent context that includes all the potential metadata the application could have set in DBOSLocalCtx
495
+ let parentCtx = undefined;
496
+ if (pctx) {
497
+ // If pctx has no span, e.g., has not been setup through `withTracedContext`, set up a parent span for the workflow here.
498
+ let span = pctx.span;
499
+ if (!span) {
500
+ span = DBOS.executor.tracer.startSpan(pctx.operationCaller || "workflowCaller", {
501
+ operationUUID: wfId,
502
+ operationType: pctx.operationType,
503
+ authenticatedUser: pctx.authenticatedUser,
504
+ assumedRole: pctx.assumedRole,
505
+ authenticatedRoles: pctx.authenticatedRoles,
506
+ });
507
+ }
508
+ parentCtx = new context_1.DBOSContextImpl(pctx.operationCaller || "workflowCaller", span, DBOS.logger);
509
+ parentCtx.request = pctx.request || {};
510
+ parentCtx.authenticatedUser = pctx.authenticatedUser || "";
511
+ parentCtx.assumedRole = pctx.assumedRole || "";
512
+ parentCtx.authenticatedRoles = pctx.authenticatedRoles || [];
513
+ parentCtx.workflowUUID = wfId || "";
514
+ }
515
+ const wfParams = {
516
+ workflowUUID: wfId,
517
+ queueName: pctx?.queueAssignedForWorkflows,
518
+ configuredInstance: inst,
519
+ parentCtx,
520
+ };
521
+ if (pctx) {
522
+ pctx.idAssignedForNextWorkflow = undefined;
523
+ }
524
+ const handle = await DBOS.executor.workflow(registration.registeredFunction, wfParams, ...rawArgs);
525
+ return await handle.getResult();
526
+ };
527
+ descriptor.value = invokeWrapper;
528
+ registration.wrappedFunction = invokeWrapper;
529
+ Object.defineProperty(invokeWrapper, "name", {
530
+ value: registration.name,
531
+ });
532
+ (0, decorators_1.registerFunctionWrapper)(invokeWrapper, registration);
533
+ // TODO CTX this should not be in here already, or if it is we need to do something different...
534
+ DBOS.invokeWrappers.set(invokeWrapper, registration.registeredFunction);
535
+ return descriptor;
536
+ }
537
+ return decorator;
538
+ }
539
+ static transaction(config = {}) {
540
+ function decorator(target, propertyKey, inDescriptor) {
541
+ const { descriptor, registration } = (0, decorators_1.registerAndWrapContextFreeFunction)(target, propertyKey, inDescriptor);
542
+ registration.txnConfig = config;
543
+ const invokeWrapper = async function (...rawArgs) {
544
+ let inst = undefined;
545
+ if (typeof this === 'function') {
546
+ // This is static
547
+ }
548
+ else {
549
+ inst = this;
550
+ if (!("name" in inst)) {
551
+ throw new error_1.DBOSInvalidWorkflowTransitionError();
552
+ }
553
+ }
554
+ if (DBOS.isWithinWorkflow()) {
555
+ const wfctx = (0, context_1.assertCurrentWorkflowContext)();
556
+ return await dbos_executor_1.DBOSExecutor.globalInstance.callTransactionFunction(registration.registeredFunction, inst ?? null, wfctx, ...rawArgs);
557
+ }
558
+ const wfParams = {
559
+ configuredInstance: inst
560
+ };
561
+ return await DBOS.executor.transaction(registration.registeredFunction, wfParams, ...rawArgs);
562
+ };
563
+ descriptor.value = invokeWrapper;
564
+ registration.wrappedFunction = invokeWrapper;
565
+ Object.defineProperty(invokeWrapper, "name", {
566
+ value: registration.name,
567
+ });
568
+ return descriptor;
569
+ }
570
+ return decorator;
571
+ }
572
+ static step(config = {}) {
573
+ function decorator(target, propertyKey, inDescriptor) {
574
+ const { descriptor, registration } = (0, decorators_1.registerAndWrapContextFreeFunction)(target, propertyKey, inDescriptor);
575
+ registration.commConfig = config;
576
+ const invokeWrapper = async function (...rawArgs) {
577
+ let inst = undefined;
578
+ if (typeof this === 'function') {
579
+ // This is static
580
+ }
581
+ else {
582
+ inst = this;
583
+ if (!("name" in inst)) {
584
+ throw new error_1.DBOSInvalidWorkflowTransitionError();
585
+ }
586
+ }
587
+ if (DBOS.isWithinWorkflow()) {
588
+ const wfctx = (0, context_1.assertCurrentWorkflowContext)();
589
+ return await dbos_executor_1.DBOSExecutor.globalInstance.callStepFunction(registration.registeredFunction, inst ?? null, wfctx, ...rawArgs);
590
+ }
591
+ const wfParams = {
592
+ configuredInstance: inst
593
+ };
594
+ return await DBOS.executor.external(registration.registeredFunction, wfParams, ...rawArgs);
595
+ };
596
+ descriptor.value = invokeWrapper;
597
+ registration.wrappedFunction = invokeWrapper;
598
+ Object.defineProperty(invokeWrapper, "name", {
599
+ value: registration.name,
600
+ });
601
+ return descriptor;
602
+ }
603
+ return decorator;
604
+ }
605
+ static getApi(url) {
606
+ return httpApiDec(handlerTypes_1.APITypes.GET, url);
607
+ }
608
+ static postApi(url) {
609
+ return httpApiDec(handlerTypes_1.APITypes.POST, url);
610
+ }
611
+ static putApi(url) {
612
+ return httpApiDec(handlerTypes_1.APITypes.PUT, url);
613
+ }
614
+ static patchApi(url) {
615
+ return httpApiDec(handlerTypes_1.APITypes.PATCH, url);
616
+ }
617
+ static deleteApi(url) {
618
+ return httpApiDec(handlerTypes_1.APITypes.DELETE, url);
619
+ }
620
+ static defaultRequiredRole(anyOf) {
621
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
622
+ function clsdec(ctor) {
623
+ const clsreg = (0, decorators_1.getOrCreateClassRegistration)(ctor);
624
+ clsreg.requiredRole = anyOf;
625
+ }
626
+ return clsdec;
627
+ }
628
+ static requiredRole(anyOf) {
629
+ function apidec(target, propertyKey, inDescriptor) {
630
+ const { descriptor, registration } = (0, decorators_1.registerAndWrapContextFreeFunction)(target, propertyKey, inDescriptor);
631
+ registration.requiredRole = anyOf;
632
+ return descriptor;
633
+ }
634
+ return apidec;
635
+ }
636
+ /////
637
+ // Registration, etc
638
+ /////
639
+ static configureInstance(cls, name, ...args) {
640
+ return (0, decorators_1.configureInstance)(cls, name, ...args);
641
+ }
642
+ // Function registration
643
+ static registerAndWrapContextFreeFunction(target, propertyKey, descriptor) {
644
+ return (0, decorators_1.registerAndWrapContextFreeFunction)(target, propertyKey, descriptor);
645
+ }
646
+ static async executeWorkflowById(workflowId, startNewWorkflow = false) {
647
+ if (!dbos_executor_1.DBOSExecutor.globalInstance) {
648
+ throw new error_1.DBOSExecutorNotInitializedError();
649
+ }
650
+ return dbos_executor_1.DBOSExecutor.globalInstance.executeWorkflowUUID(workflowId, startNewWorkflow);
651
+ }
652
+ static async recoverPendingWorkflows(executorIDs = ["local"]) {
653
+ if (!dbos_executor_1.DBOSExecutor.globalInstance) {
654
+ throw new error_1.DBOSExecutorNotInitializedError();
655
+ }
656
+ return dbos_executor_1.DBOSExecutor.globalInstance.recoverPendingWorkflows(executorIDs);
657
+ }
658
+ }
659
+ exports.DBOS = DBOS;
660
+ //# sourceMappingURL=dbos.js.map