@dbos-inc/dbos-enterprise 0.0.0-stage → 5.3.0
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/LICENSE +5 -0
- package/README.md +12 -2
- package/dist/src/conductor/conductor.d.ts +39 -0
- package/dist/src/conductor/conductor.d.ts.map +1 -0
- package/dist/src/conductor/conductor.js +948 -0
- package/dist/src/conductor/conductor.js.map +1 -0
- package/dist/src/conductor/protocol.d.ts +594 -0
- package/dist/src/conductor/protocol.d.ts.map +1 -0
- package/dist/src/conductor/protocol.js +447 -0
- package/dist/src/conductor/protocol.js.map +1 -0
- package/dist/src/export.d.ts +12 -0
- package/dist/src/export.d.ts.map +1 -0
- package/dist/src/export.js +190 -0
- package/dist/src/export.js.map +1 -0
- package/dist/src/fork.d.ts +11 -0
- package/dist/src/fork.d.ts.map +1 -0
- package/dist/src/fork.js +63 -0
- package/dist/src/fork.js.map +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +6 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/observability.d.ts +82 -0
- package/dist/src/observability.d.ts.map +1 -0
- package/dist/src/observability.js +378 -0
- package/dist/src/observability.js.map +1 -0
- package/dist/src/retention.d.ts +49 -0
- package/dist/src/retention.d.ts.map +1 -0
- package/dist/src/retention.js +448 -0
- package/dist/src/retention.js.map +1 -0
- package/package.json +64 -4
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Workflow export and import: a workflow and its children, with every row they own, as one portable value.
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.importWorkflow = exports.exportWorkflow = void 0;
|
|
5
|
+
const error_1 = require("@dbos-inc/dbos-sdk/internal/error");
|
|
6
|
+
async function exportWorkflow(sysdb, workflowID, exportChildren = false) {
|
|
7
|
+
const workflowIDs = [workflowID];
|
|
8
|
+
if (exportChildren) {
|
|
9
|
+
workflowIDs.push(...(await sysdb.getWorkflowChildren(workflowID)));
|
|
10
|
+
}
|
|
11
|
+
const exportedWorkflows = [];
|
|
12
|
+
const client = await sysdb.connect();
|
|
13
|
+
try {
|
|
14
|
+
for (const wfID of workflowIDs) {
|
|
15
|
+
// Export workflow_status
|
|
16
|
+
const statusResult = await client.query(
|
|
17
|
+
// creator_xid and owner_xid are intentionally omitted: they are transient
|
|
18
|
+
// tokens, not logical workflow state, and a source database's
|
|
19
|
+
// tokens are meaningless in the target.
|
|
20
|
+
`SELECT
|
|
21
|
+
ws.workflow_uuid, ws.status, ws.name, ws.authenticated_user, ws.assumed_role,
|
|
22
|
+
ws.authenticated_roles,
|
|
23
|
+
COALESCE(wo.output, ws.output) AS output, COALESCE(wo.error, ws.error) AS error,
|
|
24
|
+
ws.executor_id,
|
|
25
|
+
ws.created_at, ws.updated_at, ws.application_version, ws.application_id,
|
|
26
|
+
ws.class_name, ws.config_name, ws.recovery_attempts, ws.queue_name,
|
|
27
|
+
ws.workflow_timeout_ms, ws.workflow_deadline_epoch_ms, ws.started_at_epoch_ms,
|
|
28
|
+
ws.deduplication_id, COALESCE(wi.inputs, ws.inputs) AS inputs,
|
|
29
|
+
ws.priority, ws.queue_partition_key, ws.forked_from,
|
|
30
|
+
ws.parent_workflow_id, ws.serialization, ws.delay_until_epoch_ms,
|
|
31
|
+
ws.was_forked_from, ws.rate_limited, ws.completed_at, ws.attributes, ws.schedule_name,
|
|
32
|
+
ws.debounce_deadline_epoch_ms, ws.is_debounced, ws.application_name
|
|
33
|
+
FROM "${sysdb.schemaName}".workflow_status ws
|
|
34
|
+
LEFT JOIN "${sysdb.schemaName}".workflow_input wi ON wi.workflow_uuid = ws.workflow_uuid
|
|
35
|
+
LEFT JOIN "${sysdb.schemaName}".workflow_output wo ON wo.workflow_uuid = ws.workflow_uuid
|
|
36
|
+
WHERE ws.workflow_uuid = $1`, [wfID]);
|
|
37
|
+
if (statusResult.rows.length === 0) {
|
|
38
|
+
throw new error_1.DBOSNonExistentWorkflowError(`Workflow ${wfID} does not exist`);
|
|
39
|
+
}
|
|
40
|
+
const workflowStatus = statusResult.rows[0];
|
|
41
|
+
// Export operation_outputs
|
|
42
|
+
const outputsResult = await client.query(`SELECT
|
|
43
|
+
workflow_uuid, function_id, function_name, output, error,
|
|
44
|
+
child_workflow_id, started_at_epoch_ms, completed_at_epoch_ms,
|
|
45
|
+
serialization, application_name
|
|
46
|
+
FROM "${sysdb.schemaName}".operation_outputs
|
|
47
|
+
WHERE workflow_uuid = $1`, [wfID]);
|
|
48
|
+
// Export workflow_events
|
|
49
|
+
const eventsResult = await client.query(`SELECT workflow_uuid, key, value, serialization
|
|
50
|
+
FROM "${sysdb.schemaName}".workflow_events
|
|
51
|
+
WHERE workflow_uuid = $1`, [wfID]);
|
|
52
|
+
// Export workflow_events_history
|
|
53
|
+
const historyResult = await client.query(`SELECT workflow_uuid, function_id, key, value, serialization
|
|
54
|
+
FROM "${sysdb.schemaName}".workflow_events_history
|
|
55
|
+
WHERE workflow_uuid = $1`, [wfID]);
|
|
56
|
+
// Export streams
|
|
57
|
+
const streamsResult = await client.query(`SELECT workflow_uuid, key, value, "offset", function_id, serialization
|
|
58
|
+
FROM "${sysdb.schemaName}".streams
|
|
59
|
+
WHERE workflow_uuid = $1`, [wfID]);
|
|
60
|
+
exportedWorkflows.push({
|
|
61
|
+
workflow_status: workflowStatus,
|
|
62
|
+
operation_outputs: outputsResult.rows,
|
|
63
|
+
workflow_events: eventsResult.rows,
|
|
64
|
+
workflow_events_history: historyResult.rows,
|
|
65
|
+
streams: streamsResult.rows,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
client.release();
|
|
71
|
+
}
|
|
72
|
+
return exportedWorkflows;
|
|
73
|
+
}
|
|
74
|
+
exports.exportWorkflow = exportWorkflow;
|
|
75
|
+
async function importWorkflow(sysdb, workflows) {
|
|
76
|
+
const client = await sysdb.connect();
|
|
77
|
+
try {
|
|
78
|
+
await client.query('BEGIN');
|
|
79
|
+
for (const workflow of workflows) {
|
|
80
|
+
const status = workflow.workflow_status;
|
|
81
|
+
// Import workflow_status
|
|
82
|
+
await client.query(`INSERT INTO "${sysdb.schemaName}".workflow_status (
|
|
83
|
+
workflow_uuid, status, name, authenticated_user, assumed_role,
|
|
84
|
+
authenticated_roles, output, error, executor_id,
|
|
85
|
+
created_at, updated_at, application_version, application_id,
|
|
86
|
+
class_name, config_name, recovery_attempts, queue_name,
|
|
87
|
+
workflow_timeout_ms, workflow_deadline_epoch_ms, started_at_epoch_ms,
|
|
88
|
+
deduplication_id, inputs, priority, queue_partition_key, forked_from,
|
|
89
|
+
parent_workflow_id, serialization, delay_until_epoch_ms,
|
|
90
|
+
was_forked_from, rate_limited, completed_at, attributes, schedule_name,
|
|
91
|
+
debounce_deadline_epoch_ms, is_debounced, application_name
|
|
92
|
+
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31, $32, $33, $34, $35, $36)`, [
|
|
93
|
+
status.workflow_uuid,
|
|
94
|
+
status.status,
|
|
95
|
+
status.name,
|
|
96
|
+
status.authenticated_user,
|
|
97
|
+
status.assumed_role,
|
|
98
|
+
status.authenticated_roles,
|
|
99
|
+
// Legacy columns: the payloads live in their own tables.
|
|
100
|
+
null,
|
|
101
|
+
null,
|
|
102
|
+
status.executor_id,
|
|
103
|
+
status.created_at,
|
|
104
|
+
status.updated_at,
|
|
105
|
+
status.application_version,
|
|
106
|
+
status.application_id,
|
|
107
|
+
status.class_name,
|
|
108
|
+
status.config_name,
|
|
109
|
+
status.recovery_attempts,
|
|
110
|
+
status.queue_name,
|
|
111
|
+
status.workflow_timeout_ms,
|
|
112
|
+
status.workflow_deadline_epoch_ms,
|
|
113
|
+
status.started_at_epoch_ms,
|
|
114
|
+
status.deduplication_id,
|
|
115
|
+
null,
|
|
116
|
+
status.priority,
|
|
117
|
+
status.queue_partition_key,
|
|
118
|
+
status.forked_from,
|
|
119
|
+
status.parent_workflow_id,
|
|
120
|
+
status.serialization,
|
|
121
|
+
status.delay_until_epoch_ms ?? null,
|
|
122
|
+
// NOT NULL columns: fall back to FALSE for payloads exported before
|
|
123
|
+
// these fields were included.
|
|
124
|
+
status.was_forked_from ?? false,
|
|
125
|
+
status.rate_limited ?? false,
|
|
126
|
+
status.completed_at ?? null,
|
|
127
|
+
status.attributes ? JSON.stringify(status.attributes) : null,
|
|
128
|
+
status.schedule_name ?? null,
|
|
129
|
+
status.debounce_deadline_epoch_ms ?? null,
|
|
130
|
+
status.is_debounced ?? false,
|
|
131
|
+
status.application_name ?? null,
|
|
132
|
+
]);
|
|
133
|
+
// Retention starts at import: the original timestamps are long past the cutoff
|
|
134
|
+
// and would be collected immediately.
|
|
135
|
+
await client.query(`INSERT INTO "${sysdb.schemaName}".workflow_input (workflow_uuid, inputs, retention_timestamp)
|
|
136
|
+
VALUES ($1, $2, (EXTRACT(EPOCH FROM now()) * 1000)::bigint)`, [status.workflow_uuid, status.inputs]);
|
|
137
|
+
if (status.output !== null || status.error !== null) {
|
|
138
|
+
await client.query(`INSERT INTO "${sysdb.schemaName}".workflow_output (workflow_uuid, output, error, retention_timestamp)
|
|
139
|
+
VALUES ($1, $2, $3, (EXTRACT(EPOCH FROM now()) * 1000)::bigint)`, [status.workflow_uuid, status.output, status.error]);
|
|
140
|
+
}
|
|
141
|
+
// Import operation_outputs
|
|
142
|
+
for (const output of workflow.operation_outputs) {
|
|
143
|
+
await client.query(`INSERT INTO "${sysdb.schemaName}".operation_outputs (
|
|
144
|
+
workflow_uuid, function_id, function_name, output, error,
|
|
145
|
+
child_workflow_id, started_at_epoch_ms, completed_at_epoch_ms,
|
|
146
|
+
serialization, application_name, retention_timestamp
|
|
147
|
+
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, (EXTRACT(EPOCH FROM now()) * 1000)::bigint)`, [
|
|
148
|
+
output.workflow_uuid,
|
|
149
|
+
output.function_id,
|
|
150
|
+
output.function_name,
|
|
151
|
+
output.output,
|
|
152
|
+
output.error,
|
|
153
|
+
output.child_workflow_id,
|
|
154
|
+
output.started_at_epoch_ms,
|
|
155
|
+
output.completed_at_epoch_ms,
|
|
156
|
+
output.serialization,
|
|
157
|
+
output.application_name ?? null,
|
|
158
|
+
]);
|
|
159
|
+
}
|
|
160
|
+
// Import workflow_events
|
|
161
|
+
for (const event of workflow.workflow_events) {
|
|
162
|
+
await client.query(`INSERT INTO "${sysdb.schemaName}".workflow_events (
|
|
163
|
+
workflow_uuid, key, value, serialization
|
|
164
|
+
) VALUES ($1, $2, $3, $4)`, [event.workflow_uuid, event.key, event.value, event.serialization]);
|
|
165
|
+
}
|
|
166
|
+
// Import workflow_events_history
|
|
167
|
+
for (const history of workflow.workflow_events_history) {
|
|
168
|
+
await client.query(`INSERT INTO "${sysdb.schemaName}".workflow_events_history (
|
|
169
|
+
workflow_uuid, function_id, key, value, serialization
|
|
170
|
+
) VALUES ($1, $2, $3, $4, $5)`, [history.workflow_uuid, history.function_id, history.key, history.value, history.serialization]);
|
|
171
|
+
}
|
|
172
|
+
// Import streams
|
|
173
|
+
for (const stream of workflow.streams) {
|
|
174
|
+
await client.query(`INSERT INTO "${sysdb.schemaName}".streams (
|
|
175
|
+
workflow_uuid, key, value, "offset", function_id, serialization
|
|
176
|
+
) VALUES ($1, $2, $3, $4, $5, $6)`, [stream.workflow_uuid, stream.key, stream.value, stream.offset, stream.function_id, stream.serialization]);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
await client.query('COMMIT');
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
await client.query('ROLLBACK');
|
|
183
|
+
throw error;
|
|
184
|
+
}
|
|
185
|
+
finally {
|
|
186
|
+
client.release();
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
exports.importWorkflow = importWorkflow;
|
|
190
|
+
//# sourceMappingURL=export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/export.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SystemDatabase } from '@dbos-inc/dbos-sdk/internal/system_database';
|
|
2
|
+
export declare function forkFromFailure(sysdb: SystemDatabase, workflowIDs: string[], options?: {
|
|
3
|
+
applicationVersion?: string;
|
|
4
|
+
queueName?: string;
|
|
5
|
+
queuePartitionKey?: string;
|
|
6
|
+
fromLastFailure?: boolean;
|
|
7
|
+
fromLastStep?: boolean;
|
|
8
|
+
fromStep?: number;
|
|
9
|
+
fromStepName?: string;
|
|
10
|
+
}): Promise<string[]>;
|
|
11
|
+
//# sourceMappingURL=fork.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fork.d.ts","sourceRoot":"","sources":["../../src/fork.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6CAA6C,CAAC;AAElF,wBAAsB,eAAe,CACnC,KAAK,EAAE,cAAc,EACrB,WAAW,EAAE,MAAM,EAAE,EACrB,OAAO,GAAE;IACP,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CAClB,GACL,OAAO,CAAC,MAAM,EAAE,CAAC,CAyDnB"}
|
package/dist/src/fork.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Fork workflows at a chosen step, or just before their last failure.
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.forkFromFailure = void 0;
|
|
5
|
+
const node_crypto_1 = require("node:crypto");
|
|
6
|
+
async function forkFromFailure(sysdb, workflowIDs, options = {}) {
|
|
7
|
+
const modes = [
|
|
8
|
+
options.fromLastFailure ?? false,
|
|
9
|
+
options.fromLastStep ?? false,
|
|
10
|
+
options.fromStep !== undefined,
|
|
11
|
+
options.fromStepName !== undefined,
|
|
12
|
+
].filter(Boolean).length;
|
|
13
|
+
if (modes !== 1) {
|
|
14
|
+
throw new Error('Exactly one of fromLastFailure, fromLastStep, fromStep, or fromStepName must be specified');
|
|
15
|
+
}
|
|
16
|
+
let startSteps;
|
|
17
|
+
if (options.fromStep !== undefined) {
|
|
18
|
+
startSteps = Array(workflowIDs.length).fill(options.fromStep);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
let query;
|
|
22
|
+
const params = [workflowIDs];
|
|
23
|
+
if (options.fromLastFailure) {
|
|
24
|
+
query = `SELECT workflow_uuid,
|
|
25
|
+
COALESCE(
|
|
26
|
+
MAX(function_id) FILTER (WHERE error IS NOT NULL),
|
|
27
|
+
MAX(function_id)
|
|
28
|
+
) AS start_step
|
|
29
|
+
FROM "${sysdb.schemaName}".operation_outputs
|
|
30
|
+
WHERE workflow_uuid = ANY($1)
|
|
31
|
+
GROUP BY workflow_uuid`;
|
|
32
|
+
}
|
|
33
|
+
else if (options.fromLastStep) {
|
|
34
|
+
query = `SELECT workflow_uuid, MAX(function_id) AS start_step
|
|
35
|
+
FROM "${sysdb.schemaName}".operation_outputs
|
|
36
|
+
WHERE workflow_uuid = ANY($1)
|
|
37
|
+
GROUP BY workflow_uuid`;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
// fromStepName
|
|
41
|
+
query = `SELECT workflow_uuid, MAX(function_id) AS start_step
|
|
42
|
+
FROM "${sysdb.schemaName}".operation_outputs
|
|
43
|
+
WHERE workflow_uuid = ANY($1) AND function_name = $2
|
|
44
|
+
GROUP BY workflow_uuid`;
|
|
45
|
+
params.push(options.fromStepName);
|
|
46
|
+
}
|
|
47
|
+
const result = await sysdb.pool.query(query, params);
|
|
48
|
+
const startStepByID = new Map(result.rows.map((r) => [r.workflow_uuid, Number(r.start_step)]));
|
|
49
|
+
if (options.fromStepName !== undefined) {
|
|
50
|
+
for (const wid of workflowIDs) {
|
|
51
|
+
if (!startStepByID.has(wid)) {
|
|
52
|
+
throw new Error(`Workflow ${wid} has no step named '${options.fromStepName}'`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// A workflow with no recorded steps has nothing to resume from, so restart it from the beginning.
|
|
57
|
+
startSteps = workflowIDs.map((wid) => startStepByID.get(wid) ?? 0);
|
|
58
|
+
}
|
|
59
|
+
const forkedIDs = workflowIDs.map(() => (0, node_crypto_1.randomUUID)());
|
|
60
|
+
return sysdb.bulkForkWorkflows(workflowIDs, forkedIDs, startSteps, options);
|
|
61
|
+
}
|
|
62
|
+
exports.forkFromFailure = forkFromFailure;
|
|
63
|
+
//# sourceMappingURL=fork.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fork.js","sourceRoot":"","sources":["../../src/fork.ts"],"names":[],"mappings":";AAAA,sEAAsE;;;AAEtE,6CAAyC;AAGlC,KAAK,UAAU,eAAe,CACnC,KAAqB,EACrB,WAAqB,EACrB,UAQI,EAAE;IAEN,MAAM,KAAK,GAAG;QACZ,OAAO,CAAC,eAAe,IAAI,KAAK;QAChC,OAAO,CAAC,YAAY,IAAI,KAAK;QAC7B,OAAO,CAAC,QAAQ,KAAK,SAAS;QAC9B,OAAO,CAAC,YAAY,KAAK,SAAS;KACnC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IACzB,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,2FAA2F,CAAC,CAAC;IAC/G,CAAC;IAED,IAAI,UAAoB,CAAC;IAEzB,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACnC,UAAU,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAa,CAAC;IAC5E,CAAC;SAAM,CAAC;QACN,IAAI,KAAa,CAAC;QAClB,MAAM,MAAM,GAAc,CAAC,WAAW,CAAC,CAAC;QAExC,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;YAC5B,KAAK,GAAG;;;;;uBAKS,KAAK,CAAC,UAAU;;sCAED,CAAC;QACnC,CAAC;aAAM,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;YAChC,KAAK,GAAG;uBACS,KAAK,CAAC,UAAU;;sCAED,CAAC;QACnC,CAAC;aAAM,CAAC;YACN,eAAe;YACf,KAAK,GAAG;uBACS,KAAK,CAAC,UAAU;;sCAED,CAAC;YACjC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QACpC,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAgD,KAAK,EAAE,MAAM,CAAC,CAAC;QACpG,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/F,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;YACvC,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;gBAC9B,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC5B,MAAM,IAAI,KAAK,CAAC,YAAY,GAAG,uBAAuB,OAAO,CAAC,YAAY,GAAG,CAAC,CAAC;gBACjF,CAAC;YACH,CAAC;QACH,CAAC;QACD,kGAAkG;QAClG,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IACrE,CAAC;IAED,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAA,wBAAU,GAAE,CAAC,CAAC;IACtD,OAAO,KAAK,CAAC,iBAAiB,CAAC,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;AAC9E,CAAC;AArED,0CAqEC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ConductorWebsocket = void 0;
|
|
4
|
+
var conductor_1 = require("./conductor/conductor");
|
|
5
|
+
Object.defineProperty(exports, "ConductorWebsocket", { enumerable: true, get: function () { return conductor_1.ConductorWebsocket; } });
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,mDAA2D;AAAlD,+GAAA,kBAAkB,OAAA"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { type SystemDatabase } from '@dbos-inc/dbos-sdk/internal/system_database';
|
|
2
|
+
export interface MetricData {
|
|
3
|
+
metricType: string;
|
|
4
|
+
metricName: string;
|
|
5
|
+
value: number;
|
|
6
|
+
}
|
|
7
|
+
export interface GetStepAggregatesInput {
|
|
8
|
+
groupByFunctionName?: boolean;
|
|
9
|
+
groupByStatus?: boolean;
|
|
10
|
+
selectCount?: boolean;
|
|
11
|
+
selectMaxDurationMs?: boolean;
|
|
12
|
+
timeBucketSizeMs?: number;
|
|
13
|
+
status?: string[];
|
|
14
|
+
functionName?: string[];
|
|
15
|
+
workflowIdPrefix?: string[];
|
|
16
|
+
completedAfter?: string;
|
|
17
|
+
completedBefore?: string;
|
|
18
|
+
applicationName?: string[];
|
|
19
|
+
}
|
|
20
|
+
export interface GetWorkflowAggregatesInput {
|
|
21
|
+
groupByStatus?: boolean;
|
|
22
|
+
groupByName?: boolean;
|
|
23
|
+
groupByQueueName?: boolean;
|
|
24
|
+
groupByExecutorId?: boolean;
|
|
25
|
+
groupByApplicationVersion?: boolean;
|
|
26
|
+
groupByApplicationName?: boolean;
|
|
27
|
+
selectCount?: boolean;
|
|
28
|
+
selectMinCreatedAt?: boolean;
|
|
29
|
+
selectMaxQueueWaitMs?: boolean;
|
|
30
|
+
selectMaxTotalLatencyMs?: boolean;
|
|
31
|
+
timeBucketSizeMs?: number;
|
|
32
|
+
status?: string[];
|
|
33
|
+
startTime?: string;
|
|
34
|
+
endTime?: string;
|
|
35
|
+
completedAfter?: string;
|
|
36
|
+
completedBefore?: string;
|
|
37
|
+
dequeuedAfter?: string;
|
|
38
|
+
dequeuedBefore?: string;
|
|
39
|
+
name?: string[];
|
|
40
|
+
appVersion?: string[];
|
|
41
|
+
executorId?: string[];
|
|
42
|
+
queueName?: string[];
|
|
43
|
+
workflowIdPrefix?: string[];
|
|
44
|
+
workflowIDs?: string[];
|
|
45
|
+
authenticatedUser?: string[];
|
|
46
|
+
forkedFrom?: string[];
|
|
47
|
+
wasForkedFrom?: boolean;
|
|
48
|
+
isFork?: boolean;
|
|
49
|
+
parentWorkflowID?: string[];
|
|
50
|
+
hasParent?: boolean;
|
|
51
|
+
attributes?: Record<string, unknown>;
|
|
52
|
+
scheduleName?: string[];
|
|
53
|
+
applicationName?: string[];
|
|
54
|
+
}
|
|
55
|
+
export interface StepAggregateRow {
|
|
56
|
+
group: Record<string, string | null>;
|
|
57
|
+
count: number | null;
|
|
58
|
+
maxDurationMs: number | null;
|
|
59
|
+
}
|
|
60
|
+
export interface WorkflowAggregateRow {
|
|
61
|
+
group: Record<string, string | null>;
|
|
62
|
+
count: number | null;
|
|
63
|
+
minCreatedAt: number | null;
|
|
64
|
+
maxQueueWaitMs: number | null;
|
|
65
|
+
maxTotalLatencyMs: number | null;
|
|
66
|
+
}
|
|
67
|
+
export interface GetPendingWorkflowsOutput {
|
|
68
|
+
workflowUUID: string;
|
|
69
|
+
}
|
|
70
|
+
export declare function getPendingWorkflows(sysdb: SystemDatabase, executorID: string, appVersion: string): Promise<GetPendingWorkflowsOutput[]>;
|
|
71
|
+
export declare function getAllEvents(sysdb: SystemDatabase, workflowID: string): Promise<Record<string, unknown>>;
|
|
72
|
+
export declare function getAllNotifications(sysdb: SystemDatabase, workflowID: string): Promise<{
|
|
73
|
+
topic: string | null;
|
|
74
|
+
message: unknown;
|
|
75
|
+
createdAtEpochMs: number;
|
|
76
|
+
consumed: boolean;
|
|
77
|
+
}[]>;
|
|
78
|
+
export declare function getAllStreamEntries(sysdb: SystemDatabase, workflowID: string): Promise<Record<string, unknown[]>>;
|
|
79
|
+
export declare function getWorkflowAggregates(sysdb: SystemDatabase, input: GetWorkflowAggregatesInput): Promise<WorkflowAggregateRow[]>;
|
|
80
|
+
export declare function getStepAggregates(sysdb: SystemDatabase, input: GetStepAggregatesInput): Promise<StepAggregateRow[]>;
|
|
81
|
+
export declare function getMetrics(sysdb: SystemDatabase, startTime: string, endTime: string, applicationName?: string[]): Promise<MetricData[]>;
|
|
82
|
+
//# sourceMappingURL=observability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observability.d.ts","sourceRoot":"","sources":["../../src/observability.ts"],"names":[],"mappings":"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"}
|