@lotiai/composer 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build-config/index.d.ts +52 -0
- package/dist/build-config/index.d.ts.map +1 -0
- package/dist/build-config/index.js +66 -0
- package/dist/build-config/index.js.map +1 -0
- package/dist/build-config/loader.d.ts +80 -0
- package/dist/build-config/loader.d.ts.map +1 -0
- package/dist/build-config/loader.js +238 -0
- package/dist/build-config/loader.js.map +1 -0
- package/dist/build-config/schema.d.ts +101 -0
- package/dist/build-config/schema.d.ts.map +1 -0
- package/dist/build-config/schema.js +94 -0
- package/dist/build-config/schema.js.map +1 -0
- package/dist/cli/commands/dev-temporal.d.ts +15 -0
- package/dist/cli/commands/dev-temporal.d.ts.map +1 -0
- package/dist/cli/commands/dev-temporal.js +68 -0
- package/dist/cli/commands/dev-temporal.js.map +1 -0
- package/dist/cli/commands/dev.d.ts +21 -0
- package/dist/cli/commands/dev.d.ts.map +1 -0
- package/dist/cli/commands/dev.js +421 -0
- package/dist/cli/commands/dev.js.map +1 -0
- package/dist/cli/commands/profiles.d.ts +15 -0
- package/dist/cli/commands/profiles.d.ts.map +1 -0
- package/dist/cli/commands/profiles.js +69 -0
- package/dist/cli/commands/profiles.js.map +1 -0
- package/dist/cli/index.d.ts +21 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +44 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/async/build/workflow-factory.d.ts +212 -0
- package/dist/internal/async/build/workflow-factory.d.ts.map +1 -0
- package/dist/internal/async/build/workflow-factory.js +533 -0
- package/dist/internal/async/build/workflow-factory.js.map +1 -0
- package/dist/internal/async/build-scripts/utils/common.d.ts +28 -0
- package/dist/internal/async/build-scripts/utils/common.d.ts.map +1 -0
- package/dist/internal/async/build-scripts/utils/common.js +50 -0
- package/dist/internal/async/build-scripts/utils/common.js.map +1 -0
- package/dist/internal/async/build-scripts/utils/import-module.d.ts +19 -0
- package/dist/internal/async/build-scripts/utils/import-module.d.ts.map +1 -0
- package/dist/internal/async/build-scripts/utils/import-module.js +80 -0
- package/dist/internal/async/build-scripts/utils/import-module.js.map +1 -0
- package/dist/internal/async/build-scripts/utils/type-guards.d.ts +123 -0
- package/dist/internal/async/build-scripts/utils/type-guards.d.ts.map +1 -0
- package/dist/internal/async/build-scripts/utils/type-guards.js +145 -0
- package/dist/internal/async/build-scripts/utils/type-guards.js.map +1 -0
- package/dist/internal/async/config/cleanup-policy.d.ts +50 -0
- package/dist/internal/async/config/cleanup-policy.d.ts.map +1 -0
- package/dist/internal/async/config/cleanup-policy.js +20 -0
- package/dist/internal/async/config/cleanup-policy.js.map +1 -0
- package/dist/internal/async/config/worker-profiles.d.ts +172 -0
- package/dist/internal/async/config/worker-profiles.d.ts.map +1 -0
- package/dist/internal/async/config/worker-profiles.js +275 -0
- package/dist/internal/async/config/worker-profiles.js.map +1 -0
- package/dist/internal/async/execute/temporal-client.d.ts +182 -0
- package/dist/internal/async/execute/temporal-client.d.ts.map +1 -0
- package/dist/internal/async/execute/temporal-client.js +190 -0
- package/dist/internal/async/execute/temporal-client.js.map +1 -0
- package/dist/internal/async/execute/workflow-execution.d.ts +98 -0
- package/dist/internal/async/execute/workflow-execution.d.ts.map +1 -0
- package/dist/internal/async/execute/workflow-execution.js +191 -0
- package/dist/internal/async/execute/workflow-execution.js.map +1 -0
- package/dist/internal/async/metrics/task-queue-metrics.d.ts +74 -0
- package/dist/internal/async/metrics/task-queue-metrics.d.ts.map +1 -0
- package/dist/internal/async/metrics/task-queue-metrics.js +155 -0
- package/dist/internal/async/metrics/task-queue-metrics.js.map +1 -0
- package/dist/internal/async/register/activity-worker.d.ts +123 -0
- package/dist/internal/async/register/activity-worker.d.ts.map +1 -0
- package/dist/internal/async/register/activity-worker.js +355 -0
- package/dist/internal/async/register/activity-worker.js.map +1 -0
- package/dist/internal/async/register/generate-workflow-source.d.ts +43 -0
- package/dist/internal/async/register/generate-workflow-source.d.ts.map +1 -0
- package/dist/internal/async/register/generate-workflow-source.js +193 -0
- package/dist/internal/async/register/generate-workflow-source.js.map +1 -0
- package/dist/internal/async/register/workflow-worker.d.ts +125 -0
- package/dist/internal/async/register/workflow-worker.d.ts.map +1 -0
- package/dist/internal/async/register/workflow-worker.js +215 -0
- package/dist/internal/async/register/workflow-worker.js.map +1 -0
- package/dist/internal/async/register-scripts/start-activity-worker.d.ts +70 -0
- package/dist/internal/async/register-scripts/start-activity-worker.d.ts.map +1 -0
- package/dist/internal/async/register-scripts/start-activity-worker.js +75 -0
- package/dist/internal/async/register-scripts/start-activity-worker.js.map +1 -0
- package/dist/internal/async/register-scripts/start-all-workers.d.ts +81 -0
- package/dist/internal/async/register-scripts/start-all-workers.d.ts.map +1 -0
- package/dist/internal/async/register-scripts/start-all-workers.js +84 -0
- package/dist/internal/async/register-scripts/start-all-workers.js.map +1 -0
- package/dist/internal/async/register-scripts/start-workflow-worker.d.ts +69 -0
- package/dist/internal/async/register-scripts/start-workflow-worker.d.ts.map +1 -0
- package/dist/internal/async/register-scripts/start-workflow-worker.js +74 -0
- package/dist/internal/async/register-scripts/start-workflow-worker.js.map +1 -0
- package/dist/internal/async/register-scripts/sync-schedules-cli.d.ts +28 -0
- package/dist/internal/async/register-scripts/sync-schedules-cli.d.ts.map +1 -0
- package/dist/internal/async/register-scripts/sync-schedules-cli.js +124 -0
- package/dist/internal/async/register-scripts/sync-schedules-cli.js.map +1 -0
- package/dist/internal/async/register-scripts/sync-schedules-via-lambda.d.ts +55 -0
- package/dist/internal/async/register-scripts/sync-schedules-via-lambda.d.ts.map +1 -0
- package/dist/internal/async/register-scripts/sync-schedules-via-lambda.js +146 -0
- package/dist/internal/async/register-scripts/sync-schedules-via-lambda.js.map +1 -0
- package/dist/internal/async/register-scripts/sync-schedules.d.ts +68 -0
- package/dist/internal/async/register-scripts/sync-schedules.d.ts.map +1 -0
- package/dist/internal/async/register-scripts/sync-schedules.js +83 -0
- package/dist/internal/async/register-scripts/sync-schedules.js.map +1 -0
- package/dist/internal/async/schedule/constants.d.ts +10 -0
- package/dist/internal/async/schedule/constants.d.ts.map +1 -0
- package/dist/internal/async/schedule/constants.js +13 -0
- package/dist/internal/async/schedule/constants.js.map +1 -0
- package/dist/internal/async/schedule/define-schedule.d.ts +192 -0
- package/dist/internal/async/schedule/define-schedule.d.ts.map +1 -0
- package/dist/internal/async/schedule/define-schedule.js +79 -0
- package/dist/internal/async/schedule/define-schedule.js.map +1 -0
- package/dist/internal/async/schedule/index.d.ts +3 -0
- package/dist/internal/async/schedule/index.d.ts.map +1 -0
- package/dist/internal/async/schedule/index.js +9 -0
- package/dist/internal/async/schedule/index.js.map +1 -0
- package/dist/internal/async/schedule/schedule-definition-schema.d.ts +64 -0
- package/dist/internal/async/schedule/schedule-definition-schema.d.ts.map +1 -0
- package/dist/internal/async/schedule/schedule-definition-schema.js +77 -0
- package/dist/internal/async/schedule/schedule-definition-schema.js.map +1 -0
- package/dist/internal/async/schedule/sync-schedules.d.ts +71 -0
- package/dist/internal/async/schedule/sync-schedules.d.ts.map +1 -0
- package/dist/internal/async/schedule/sync-schedules.js +231 -0
- package/dist/internal/async/schedule/sync-schedules.js.map +1 -0
- package/dist/internal/async/utils/ensure-namespace.d.ts +16 -0
- package/dist/internal/async/utils/ensure-namespace.d.ts.map +1 -0
- package/dist/internal/async/utils/ensure-namespace.js +64 -0
- package/dist/internal/async/utils/ensure-namespace.js.map +1 -0
- package/dist/internal/async/utils/find-package-root.d.ts +9 -0
- package/dist/internal/async/utils/find-package-root.d.ts.map +1 -0
- package/dist/internal/async/utils/find-package-root.js +28 -0
- package/dist/internal/async/utils/find-package-root.js.map +1 -0
- package/dist/internal/async/utils/is-composer-error.d.ts +14 -0
- package/dist/internal/async/utils/is-composer-error.d.ts.map +1 -0
- package/dist/internal/async/utils/is-composer-error.js +17 -0
- package/dist/internal/async/utils/is-composer-error.js.map +1 -0
- package/dist/internal/context-provider.d.ts +316 -0
- package/dist/internal/context-provider.d.ts.map +1 -0
- package/dist/internal/context-provider.js +12 -0
- package/dist/internal/context-provider.js.map +1 -0
- package/dist/internal/create-composer.d.ts +57 -0
- package/dist/internal/create-composer.d.ts.map +1 -0
- package/dist/internal/create-composer.js +125 -0
- package/dist/internal/create-composer.js.map +1 -0
- package/dist/internal/dag-sync-fanout.d.ts +79 -0
- package/dist/internal/dag-sync-fanout.d.ts.map +1 -0
- package/dist/internal/dag-sync-fanout.js +59 -0
- package/dist/internal/dag-sync-fanout.js.map +1 -0
- package/dist/internal/dag-sync-step.d.ts +230 -0
- package/dist/internal/dag-sync-step.d.ts.map +1 -0
- package/dist/internal/dag-sync-step.js +159 -0
- package/dist/internal/dag-sync-step.js.map +1 -0
- package/dist/internal/dag-sync-workflow.d.ts +535 -0
- package/dist/internal/dag-sync-workflow.d.ts.map +1 -0
- package/dist/internal/dag-sync-workflow.js +843 -0
- package/dist/internal/dag-sync-workflow.js.map +1 -0
- package/dist/internal/defaults.d.ts +24 -0
- package/dist/internal/defaults.d.ts.map +1 -0
- package/dist/internal/defaults.js +102 -0
- package/dist/internal/defaults.js.map +1 -0
- package/dist/internal/errors.d.ts +109 -0
- package/dist/internal/errors.d.ts.map +1 -0
- package/dist/internal/errors.js +212 -0
- package/dist/internal/errors.js.map +1 -0
- package/dist/internal/index.d.ts +9 -0
- package/dist/internal/index.d.ts.map +1 -0
- package/dist/internal/index.js +22 -0
- package/dist/internal/index.js.map +1 -0
- package/dist/internal/observability.d.ts +63 -0
- package/dist/internal/observability.d.ts.map +1 -0
- package/dist/internal/observability.js +323 -0
- package/dist/internal/observability.js.map +1 -0
- package/dist/internal/types.d.ts +80 -0
- package/dist/internal/types.d.ts.map +1 -0
- package/dist/internal/types.js +9 -0
- package/dist/internal/types.js.map +1 -0
- package/dist/internal/workflow-planning.d.ts +107 -0
- package/dist/internal/workflow-planning.d.ts.map +1 -0
- package/dist/internal/workflow-planning.js +216 -0
- package/dist/internal/workflow-planning.js.map +1 -0
- package/dist/schedule-sync.d.ts +17 -0
- package/dist/schedule-sync.d.ts.map +1 -0
- package/dist/schedule-sync.js +22 -0
- package/dist/schedule-sync.js.map +1 -0
- package/dist/temporal-naming.d.ts +27 -0
- package/dist/temporal-naming.d.ts.map +1 -0
- package/dist/temporal-naming.js +33 -0
- package/dist/temporal-naming.js.map +1 -0
- package/package.json +29 -17
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// NOTE: This observability is only used for sync workflows.
|
|
3
|
+
// For async workflows, we will use Temporal's observability features.
|
|
4
|
+
// https://docs.temporal.io/docs/concepts/workflows/observability
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.startWorkflowObservability = startWorkflowObservability;
|
|
7
|
+
exports.endWorkflowObservability = endWorkflowObservability;
|
|
8
|
+
exports.startBatchObservability = startBatchObservability;
|
|
9
|
+
exports.endBatchObservability = endBatchObservability;
|
|
10
|
+
exports.startStepObservability = startStepObservability;
|
|
11
|
+
exports.endStepObservability = endStepObservability;
|
|
12
|
+
const api_1 = require("@opentelemetry/api");
|
|
13
|
+
const defaults_1 = require("./defaults");
|
|
14
|
+
const errors_1 = require("./errors");
|
|
15
|
+
// Module-level observability singletons for sync workflow execution.
|
|
16
|
+
// Tracing and metrics use @opentelemetry/api directly -- if the user has an OTel SDK
|
|
17
|
+
// configured, these automatically collect data. If not, they are safe no-ops.
|
|
18
|
+
const workflowTracer = api_1.trace.getTracer("composer-workflow");
|
|
19
|
+
const workflowMetrics = (0, defaults_1.createDefaultMetrics)("composer-workflow");
|
|
20
|
+
// Workflow observability functions
|
|
21
|
+
function startWorkflowObservability(workflowId, workflow, initialData, logger) {
|
|
22
|
+
// Create workflow-level span
|
|
23
|
+
const workflowSpan = workflowTracer.startSpan(`workflow.${workflow.name}`, {
|
|
24
|
+
attributes: {
|
|
25
|
+
"workflow.name": workflow.name,
|
|
26
|
+
"workflow.id": workflowId,
|
|
27
|
+
"workflow.steps.count": workflow.steps.length,
|
|
28
|
+
"workflow.initial.fields": initialData ? Object.keys(initialData).join(",") : "",
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
// Create context with this span as active for child spans
|
|
32
|
+
const workflowContext = api_1.trace.setSpan(api_1.context.active(), workflowSpan);
|
|
33
|
+
// Initialize metrics
|
|
34
|
+
const executionsCounter = workflowMetrics.counter("workflow_executions_total", "Total number of workflow executions");
|
|
35
|
+
const durationHistogram = workflowMetrics.histogram("workflow_duration_seconds", "Duration of workflow executions in seconds");
|
|
36
|
+
const stepExecutionsCounter = workflowMetrics.counter("step_executions_total", "Total number of step executions");
|
|
37
|
+
const stepDurationHistogram = workflowMetrics.histogram("step_duration_seconds", "Duration of step executions in seconds");
|
|
38
|
+
const batchSizeHistogram = workflowMetrics.histogram("batch_size", "Number of steps executed in parallel batches");
|
|
39
|
+
// Record workflow start time (counter incremented on completion only)
|
|
40
|
+
const workflowStartTime = Date.now();
|
|
41
|
+
return {
|
|
42
|
+
workflowId,
|
|
43
|
+
workflowSpan,
|
|
44
|
+
workflowContext,
|
|
45
|
+
workflowStartTime,
|
|
46
|
+
workflowName: workflow.name,
|
|
47
|
+
logger,
|
|
48
|
+
executionsCounter,
|
|
49
|
+
durationHistogram,
|
|
50
|
+
stepExecutionsCounter,
|
|
51
|
+
stepDurationHistogram,
|
|
52
|
+
batchSizeHistogram,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function endWorkflowObservability(handle, result, executionContext, bagState) {
|
|
56
|
+
const workflowDuration = (Date.now() - handle.workflowStartTime) / 1000; // Convert to seconds
|
|
57
|
+
if (result.success) {
|
|
58
|
+
// Record workflow success metrics
|
|
59
|
+
handle.durationHistogram.record(workflowDuration, {
|
|
60
|
+
"workflow.name": handle.workflowName,
|
|
61
|
+
"workflow.status": "success",
|
|
62
|
+
});
|
|
63
|
+
handle.executionsCounter.add(1, {
|
|
64
|
+
"workflow.name": handle.workflowName,
|
|
65
|
+
"workflow.status": "success",
|
|
66
|
+
});
|
|
67
|
+
// Log workflow success
|
|
68
|
+
handle.logger.info("Workflow completed successfully", {
|
|
69
|
+
workflowName: handle.workflowName,
|
|
70
|
+
workflowId: handle.workflowId,
|
|
71
|
+
duration: workflowDuration,
|
|
72
|
+
batchCount: result.batchCount || 0,
|
|
73
|
+
outputFields: result.outputFields,
|
|
74
|
+
});
|
|
75
|
+
// Add workflow success attributes
|
|
76
|
+
handle.workflowSpan.setAttributes({
|
|
77
|
+
"workflow.status": "success",
|
|
78
|
+
"workflow.batches.count": result.batchCount || 0,
|
|
79
|
+
"workflow.output.fields": result.outputFields?.join(",") || "",
|
|
80
|
+
});
|
|
81
|
+
// Set span status to OK
|
|
82
|
+
handle.workflowSpan.setStatus({ code: api_1.SpanStatusCode.OK });
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
// Record workflow error metrics
|
|
86
|
+
handle.durationHistogram.record(workflowDuration, {
|
|
87
|
+
"workflow.name": handle.workflowName,
|
|
88
|
+
"workflow.status": "error",
|
|
89
|
+
});
|
|
90
|
+
handle.executionsCounter.add(1, {
|
|
91
|
+
"workflow.name": handle.workflowName,
|
|
92
|
+
"workflow.status": "error",
|
|
93
|
+
});
|
|
94
|
+
// Log workflow error with enhanced context including execution state
|
|
95
|
+
const logContext = {
|
|
96
|
+
workflowName: handle.workflowName,
|
|
97
|
+
workflowId: handle.workflowId,
|
|
98
|
+
duration: workflowDuration,
|
|
99
|
+
error: {
|
|
100
|
+
name: result.error.name,
|
|
101
|
+
message: result.error.message,
|
|
102
|
+
stack: result.error.stack,
|
|
103
|
+
},
|
|
104
|
+
failureContext: {
|
|
105
|
+
stepName: executionContext.stepName,
|
|
106
|
+
stepNumber: executionContext.stepNumber,
|
|
107
|
+
totalSteps: executionContext.totalSteps,
|
|
108
|
+
batchNumber: executionContext.batchNumber,
|
|
109
|
+
...(executionContext.stepStartTime
|
|
110
|
+
? { stepDuration: (Date.now() - executionContext.stepStartTime) / 1000 }
|
|
111
|
+
: {}),
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
// Include bag state only if debug logging is enabled
|
|
115
|
+
if (errors_1.enableDebugLogging && bagState) {
|
|
116
|
+
logContext.bagState = bagState;
|
|
117
|
+
}
|
|
118
|
+
handle.logger.error("Workflow execution failed", logContext);
|
|
119
|
+
// Add workflow error attributes
|
|
120
|
+
handle.workflowSpan.setAttributes({
|
|
121
|
+
"workflow.status": "error",
|
|
122
|
+
"workflow.error.message": result.error.message,
|
|
123
|
+
});
|
|
124
|
+
handle.workflowSpan.recordException(result.error);
|
|
125
|
+
// Set span status to ERROR
|
|
126
|
+
handle.workflowSpan.setStatus({
|
|
127
|
+
code: api_1.SpanStatusCode.ERROR,
|
|
128
|
+
message: result.error.message,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
handle.workflowSpan.end();
|
|
132
|
+
}
|
|
133
|
+
// Batch observability functions
|
|
134
|
+
function startBatchObservability(workflowHandle, batchNumber, stepNames) {
|
|
135
|
+
// Create batch-level span as a child of the workflow span
|
|
136
|
+
const batchSpan = workflowTracer.startSpan(`workflow.${workflowHandle.workflowName}.batch.${batchNumber}`, {
|
|
137
|
+
attributes: {
|
|
138
|
+
"workflow.name": workflowHandle.workflowName,
|
|
139
|
+
"workflow.id": workflowHandle.workflowId,
|
|
140
|
+
"workflow.batch.number": batchNumber,
|
|
141
|
+
"workflow.batch.steps.count": stepNames.length,
|
|
142
|
+
"workflow.batch.steps.names": stepNames.join(","),
|
|
143
|
+
},
|
|
144
|
+
}, workflowHandle.workflowContext);
|
|
145
|
+
// Create context with this span as active for child spans (steps)
|
|
146
|
+
const batchContext = api_1.trace.setSpan(workflowHandle.workflowContext, batchSpan);
|
|
147
|
+
// Record batch size metric
|
|
148
|
+
workflowHandle.batchSizeHistogram.record(stepNames.length, {
|
|
149
|
+
"workflow.name": workflowHandle.workflowName,
|
|
150
|
+
"workflow.batch.number": batchNumber,
|
|
151
|
+
});
|
|
152
|
+
return {
|
|
153
|
+
batchSpan,
|
|
154
|
+
batchContext,
|
|
155
|
+
workflowName: workflowHandle.workflowName,
|
|
156
|
+
batchNumber,
|
|
157
|
+
batchSize: stepNames.length,
|
|
158
|
+
subworkflowSpans: new Map(),
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
function endBatchObservability(handle, result) {
|
|
162
|
+
if (result.success) {
|
|
163
|
+
// Add batch success attributes
|
|
164
|
+
handle.batchSpan.setAttributes({
|
|
165
|
+
"workflow.batch.status": "success",
|
|
166
|
+
"workflow.batch.output.fields": result.outputFields?.join(",") || "",
|
|
167
|
+
});
|
|
168
|
+
// Set span status to OK
|
|
169
|
+
handle.batchSpan.setStatus({ code: api_1.SpanStatusCode.OK });
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
// Add batch error attributes
|
|
173
|
+
handle.batchSpan.setAttributes({
|
|
174
|
+
"workflow.batch.status": "error",
|
|
175
|
+
"workflow.batch.error.message": result.error.message,
|
|
176
|
+
});
|
|
177
|
+
handle.batchSpan.recordException(result.error);
|
|
178
|
+
// Set span status to ERROR
|
|
179
|
+
handle.batchSpan.setStatus({
|
|
180
|
+
code: api_1.SpanStatusCode.ERROR,
|
|
181
|
+
message: result.error.message,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
// End all SubWorkflow spans before ending the batch span
|
|
185
|
+
for (const subworkflowHandle of handle.subworkflowSpans.values()) {
|
|
186
|
+
endSubWorkflowObservability(subworkflowHandle);
|
|
187
|
+
}
|
|
188
|
+
handle.batchSpan.end();
|
|
189
|
+
}
|
|
190
|
+
// SubWorkflow observability functions
|
|
191
|
+
/**
|
|
192
|
+
* Gets or creates a SubWorkflow span for a given workflow path.
|
|
193
|
+
* This creates a virtual span boundary for composed workflows even though execution is flat.
|
|
194
|
+
*/
|
|
195
|
+
function getOrCreateSubWorkflowSpan(workflowId, batchHandle, workflowPath) {
|
|
196
|
+
const pathKey = workflowPath.join(".");
|
|
197
|
+
// Check if we already have a span for this subworkflow path
|
|
198
|
+
const existing = batchHandle.subworkflowSpans.get(pathKey);
|
|
199
|
+
if (existing) {
|
|
200
|
+
existing.stepCount++;
|
|
201
|
+
return existing;
|
|
202
|
+
}
|
|
203
|
+
// Create new SubWorkflow span as child of batch
|
|
204
|
+
const subworkflowName = workflowPath[workflowPath.length - 1] || "unknown";
|
|
205
|
+
const subworkflowSpan = workflowTracer.startSpan(`workflow.${batchHandle.workflowName}.subworkflow.${subworkflowName}`, {
|
|
206
|
+
attributes: {
|
|
207
|
+
"workflow.name": batchHandle.workflowName,
|
|
208
|
+
"workflow.id": workflowId,
|
|
209
|
+
"workflow.batch.number": batchHandle.batchNumber,
|
|
210
|
+
"subworkflow.name": subworkflowName,
|
|
211
|
+
"subworkflow.path": workflowPath.join("."),
|
|
212
|
+
},
|
|
213
|
+
}, batchHandle.batchContext);
|
|
214
|
+
// Create context with SubWorkflow span as active
|
|
215
|
+
const subworkflowContext = api_1.trace.setSpan(batchHandle.batchContext, subworkflowSpan);
|
|
216
|
+
const handle = {
|
|
217
|
+
subworkflowSpan,
|
|
218
|
+
subworkflowContext,
|
|
219
|
+
subworkflowName,
|
|
220
|
+
workflowPath,
|
|
221
|
+
stepCount: 1,
|
|
222
|
+
};
|
|
223
|
+
// Cache for reuse by other steps from same subworkflow
|
|
224
|
+
batchHandle.subworkflowSpans.set(pathKey, handle);
|
|
225
|
+
return handle;
|
|
226
|
+
}
|
|
227
|
+
function endSubWorkflowObservability(handle) {
|
|
228
|
+
// Add SubWorkflow completion attributes
|
|
229
|
+
handle.subworkflowSpan.setAttributes({
|
|
230
|
+
"subworkflow.steps.count": handle.stepCount,
|
|
231
|
+
"subworkflow.status": "completed",
|
|
232
|
+
});
|
|
233
|
+
// Set span status to OK (errors are tracked at step level)
|
|
234
|
+
handle.subworkflowSpan.setStatus({ code: api_1.SpanStatusCode.OK });
|
|
235
|
+
handle.subworkflowSpan.end();
|
|
236
|
+
}
|
|
237
|
+
// Step observability functions
|
|
238
|
+
function startStepObservability(workflowHandle, batchHandle, step) {
|
|
239
|
+
// Determine parent context: SubWorkflow span if this step is from a composed workflow,
|
|
240
|
+
// otherwise the batch span directly
|
|
241
|
+
let parentContext = batchHandle.batchContext;
|
|
242
|
+
const attributes = {
|
|
243
|
+
"workflow.name": workflowHandle.workflowName,
|
|
244
|
+
"workflow.id": workflowHandle.workflowId,
|
|
245
|
+
"workflow.batch.number": batchHandle.batchNumber,
|
|
246
|
+
"batch.size": batchHandle.batchSize,
|
|
247
|
+
"step.name": step.name,
|
|
248
|
+
"step.needs": step.needs.join(","),
|
|
249
|
+
"step.provides": step.provides.join(","),
|
|
250
|
+
};
|
|
251
|
+
// If step has a workflow path, it's from a composed workflow
|
|
252
|
+
if (step.workflowPath && step.workflowPath.length > 0) {
|
|
253
|
+
const subworkflowHandle = getOrCreateSubWorkflowSpan(workflowHandle.workflowId, batchHandle, step.workflowPath);
|
|
254
|
+
parentContext = subworkflowHandle.subworkflowContext;
|
|
255
|
+
// Add subworkflow metadata to step attributes
|
|
256
|
+
attributes["subworkflow.name"] = subworkflowHandle.subworkflowName;
|
|
257
|
+
attributes["subworkflow.path"] = step.workflowPath.join(".");
|
|
258
|
+
}
|
|
259
|
+
// Create step-level span as a child of the appropriate parent (SubWorkflow or Batch)
|
|
260
|
+
const stepSpan = workflowTracer.startSpan(`workflow.${workflowHandle.workflowName}.step.${step.name}`, { attributes }, parentContext);
|
|
261
|
+
// Create context with step span active - used to wrap step execution
|
|
262
|
+
const stepContext = api_1.trace.setSpan(parentContext, stepSpan);
|
|
263
|
+
// Record step start time (counter incremented on completion only)
|
|
264
|
+
const stepStartTime = Date.now();
|
|
265
|
+
return {
|
|
266
|
+
stepSpan,
|
|
267
|
+
stepContext,
|
|
268
|
+
stepStartTime,
|
|
269
|
+
workflowName: workflowHandle.workflowName,
|
|
270
|
+
stepName: step.name,
|
|
271
|
+
stepDurationHistogram: workflowHandle.stepDurationHistogram,
|
|
272
|
+
stepExecutionsCounter: workflowHandle.stepExecutionsCounter,
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
function endStepObservability(handle, result) {
|
|
276
|
+
const stepDuration = (Date.now() - handle.stepStartTime) / 1000; // Convert to seconds
|
|
277
|
+
if (result.success) {
|
|
278
|
+
// Record step success metrics
|
|
279
|
+
handle.stepDurationHistogram.record(stepDuration, {
|
|
280
|
+
"workflow.name": handle.workflowName,
|
|
281
|
+
"step.name": handle.stepName,
|
|
282
|
+
"step.status": "success",
|
|
283
|
+
});
|
|
284
|
+
handle.stepExecutionsCounter.add(1, {
|
|
285
|
+
"workflow.name": handle.workflowName,
|
|
286
|
+
"step.name": handle.stepName,
|
|
287
|
+
"step.status": "success",
|
|
288
|
+
});
|
|
289
|
+
// Add step success attributes
|
|
290
|
+
handle.stepSpan.setAttributes({
|
|
291
|
+
"step.status": "success",
|
|
292
|
+
"step.output.fields": result.outputFields?.join(",") || "",
|
|
293
|
+
});
|
|
294
|
+
// Set span status to OK
|
|
295
|
+
handle.stepSpan.setStatus({ code: api_1.SpanStatusCode.OK });
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
// Record step error metrics
|
|
299
|
+
handle.stepDurationHistogram.record(stepDuration, {
|
|
300
|
+
"workflow.name": handle.workflowName,
|
|
301
|
+
"step.name": handle.stepName,
|
|
302
|
+
"step.status": "error",
|
|
303
|
+
});
|
|
304
|
+
handle.stepExecutionsCounter.add(1, {
|
|
305
|
+
"workflow.name": handle.workflowName,
|
|
306
|
+
"step.name": handle.stepName,
|
|
307
|
+
"step.status": "error",
|
|
308
|
+
});
|
|
309
|
+
// Add step error attributes
|
|
310
|
+
handle.stepSpan.setAttributes({
|
|
311
|
+
"step.status": "error",
|
|
312
|
+
"step.error.message": result.error.message,
|
|
313
|
+
});
|
|
314
|
+
handle.stepSpan.recordException(result.error);
|
|
315
|
+
// Set span status to ERROR
|
|
316
|
+
handle.stepSpan.setStatus({
|
|
317
|
+
code: api_1.SpanStatusCode.ERROR,
|
|
318
|
+
message: result.error.message,
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
handle.stepSpan.end();
|
|
322
|
+
}
|
|
323
|
+
//# sourceMappingURL=observability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observability.js","sourceRoot":"","sources":["../../src/internal/observability.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core types for the Composer framework.
|
|
3
|
+
*
|
|
4
|
+
* These types decouple the framework from any specific application or infrastructure
|
|
5
|
+
* packages, allowing the composer to be used as a standalone npm package.
|
|
6
|
+
*/
|
|
7
|
+
import type { Attributes, Context } from "@opentelemetry/api";
|
|
8
|
+
/**
|
|
9
|
+
* A UUIDv7 string type.
|
|
10
|
+
*
|
|
11
|
+
* UUIDv7 is a time-ordered UUID format that provides natural sorting by creation time.
|
|
12
|
+
* This branded type prevents accidental assignment of arbitrary strings.
|
|
13
|
+
*/
|
|
14
|
+
export type UUIDV7 = string & {
|
|
15
|
+
readonly __brand: "UUIDv7";
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Counter metric interface for tracking cumulative values.
|
|
19
|
+
*
|
|
20
|
+
* Wraps the OpenTelemetry Counter with a simplified interface.
|
|
21
|
+
*/
|
|
22
|
+
export interface Counter {
|
|
23
|
+
/** Increment the counter by the given value (default: 1) */
|
|
24
|
+
add(value?: number, attributes?: Attributes, context?: Context): void;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Histogram metric interface for tracking distributions of values.
|
|
28
|
+
*
|
|
29
|
+
* Wraps the OpenTelemetry Histogram with a simplified interface.
|
|
30
|
+
*/
|
|
31
|
+
export interface Histogram {
|
|
32
|
+
/** Record a value in the histogram */
|
|
33
|
+
record(value: number, attributes?: Attributes, context?: Context): void;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Metrics collector that provides access to Counter and Histogram instruments.
|
|
37
|
+
*
|
|
38
|
+
* The default implementation uses `@opentelemetry/api` directly. If the user has
|
|
39
|
+
* configured an OpenTelemetry SDK, metrics are automatically collected. If not,
|
|
40
|
+
* the OTel API provides safe no-op implementations.
|
|
41
|
+
*/
|
|
42
|
+
export interface MetricsCollector {
|
|
43
|
+
/** Create or get a counter metric */
|
|
44
|
+
counter(name: string, description?: string): Counter;
|
|
45
|
+
/** Create or get a histogram metric */
|
|
46
|
+
histogram(name: string, description?: string): Histogram;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Minimal logger interface for the Composer framework.
|
|
50
|
+
*
|
|
51
|
+
* Compatible with `console`, `pino`, `winston`, and most logging libraries.
|
|
52
|
+
* The default implementation logs to `console`. Users can inject their own
|
|
53
|
+
* logger via `createComposer({ logger: myLogger })`.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```typescript
|
|
57
|
+
* // Using console (default)
|
|
58
|
+
* const composer = createComposer({ contextProvider });
|
|
59
|
+
*
|
|
60
|
+
* // Using pino
|
|
61
|
+
* import pino from "pino";
|
|
62
|
+
* const logger = pino();
|
|
63
|
+
* const composer = createComposer({
|
|
64
|
+
* contextProvider,
|
|
65
|
+
* logger: {
|
|
66
|
+
* info: (msg, meta) => logger.info(meta, msg),
|
|
67
|
+
* warn: (msg, meta) => logger.warn(meta, msg),
|
|
68
|
+
* error: (msg, meta) => logger.error(meta, msg),
|
|
69
|
+
* debug: (msg, meta) => logger.debug(meta, msg),
|
|
70
|
+
* },
|
|
71
|
+
* });
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export interface ComposerLogger {
|
|
75
|
+
info(message: string, metadata?: Record<string, unknown>): void;
|
|
76
|
+
warn(message: string, metadata?: Record<string, unknown>): void;
|
|
77
|
+
error(message: string, metadata?: Record<string, unknown>): void;
|
|
78
|
+
debug(message: string, metadata?: Record<string, unknown>): void;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/internal/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAM9D;;;;;GAKG;AACH,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAA;CAAE,CAAC;AAM7D;;;;GAIG;AACH,MAAM,WAAW,OAAO;IACtB,4DAA4D;IAC5D,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CACvE;AAED;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,sCAAsC;IACtC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CACzE;AAED;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,qCAAqC;IACrC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACrD,uCAAuC;IACvC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1D;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAChE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAChE,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACjE,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAClE"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Core types for the Composer framework.
|
|
4
|
+
*
|
|
5
|
+
* These types decouple the framework from any specific application or infrastructure
|
|
6
|
+
* packages, allowing the composer to be used as a standalone npm package.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/internal/types.ts"],"names":[],"mappings":";AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow Planning Logic for DAG Execution
|
|
3
|
+
*
|
|
4
|
+
* This module extracts the topological sort and batch planning logic from the
|
|
5
|
+
* synchronous workflow engine, making it reusable for both sync and async (Temporal)
|
|
6
|
+
* execution strategies.
|
|
7
|
+
*
|
|
8
|
+
* ## Execution Model
|
|
9
|
+
*
|
|
10
|
+
* The planner performs dependency analysis to determine which steps can run in parallel:
|
|
11
|
+
*
|
|
12
|
+
* 1. **Dependency Analysis**: Build a directed acyclic graph (DAG) of step dependencies
|
|
13
|
+
* 2. **Topological Sort**: Use Kahn's algorithm to find valid execution order
|
|
14
|
+
* 3. **Batch Formation**: Group steps with no dependencies into parallel "batches"
|
|
15
|
+
* 4. **Validation**: Detect cycles, missing dependencies, and conflicts
|
|
16
|
+
*
|
|
17
|
+
* ## Example
|
|
18
|
+
*
|
|
19
|
+
* Given workflow:
|
|
20
|
+
* - stepA: needs [] → provides ["x"]
|
|
21
|
+
* - stepB: needs ["x"] → provides ["y"]
|
|
22
|
+
* - stepC: needs ["x"] → provides ["z"]
|
|
23
|
+
* - stepD: needs ["y", "z"] → provides ["result"]
|
|
24
|
+
*
|
|
25
|
+
* Planning output:
|
|
26
|
+
* ```
|
|
27
|
+
* [
|
|
28
|
+
* [stepA], // Batch 0: No dependencies
|
|
29
|
+
* [stepB, stepC], // Batch 1: Both need "x" (parallel)
|
|
30
|
+
* [stepD] // Batch 2: Needs both "y" and "z"
|
|
31
|
+
* ]
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* ## Usage
|
|
35
|
+
*
|
|
36
|
+
* For Temporal workflows:
|
|
37
|
+
* ```ts
|
|
38
|
+
* const plan = planWorkflowBatches(workflow.steps, initialFields);
|
|
39
|
+
* // Convert each batch to Temporal activities that can run in parallel
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* For synchronous workflows:
|
|
43
|
+
* ```ts
|
|
44
|
+
* const plan = planWorkflowBatches(workflow.steps, initialFields);
|
|
45
|
+
* for (const batch of plan.batches) {
|
|
46
|
+
* await Promise.all(batch.map(step => step.run(ctx, bag)));
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
import type { Step } from "./dag-sync-step";
|
|
51
|
+
/**
|
|
52
|
+
* Result of workflow planning - steps organized into parallel execution batches.
|
|
53
|
+
*/
|
|
54
|
+
export interface WorkflowPlan<Bag extends Record<string, any>> {
|
|
55
|
+
/** Steps organized by execution batch (each batch can execute in parallel) */
|
|
56
|
+
batches: Step<Bag, any, any, any, any>[][];
|
|
57
|
+
/** Map of field name to the step that produces it */
|
|
58
|
+
producers: Map<keyof Bag, string>;
|
|
59
|
+
/** All fields that will be available after workflow completion */
|
|
60
|
+
providedFields: Set<keyof Bag>;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Plans the execution of a workflow by performing topological sort with batch grouping.
|
|
64
|
+
*
|
|
65
|
+
* This function:
|
|
66
|
+
* 1. Validates that all dependencies can be satisfied
|
|
67
|
+
* 2. Detects duplicate providers and cycles
|
|
68
|
+
* 3. Groups steps into parallel execution batches using Kahn's algorithm
|
|
69
|
+
* 4. Returns an execution plan optimized for maximum parallelism
|
|
70
|
+
*
|
|
71
|
+
* @param steps - Array of steps in the workflow
|
|
72
|
+
* @param initialFields - Fields provided as initial data (satisfy dependencies without producers)
|
|
73
|
+
* @returns Workflow execution plan with steps organized into parallel batches
|
|
74
|
+
* @throws Error if dependencies cannot be satisfied, cycles exist, or duplicate providers found
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* const plan = planWorkflowBatches(
|
|
79
|
+
* [stepA, stepB, stepC, stepD],
|
|
80
|
+
* new Set(["userId"])
|
|
81
|
+
* );
|
|
82
|
+
*
|
|
83
|
+
* // Execute each batch in sequence, steps within a batch in parallel
|
|
84
|
+
* for (const batch of plan.batches) {
|
|
85
|
+
* await Promise.all(batch.map(step => executeStep(step)));
|
|
86
|
+
* }
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
export declare function planWorkflowBatches<Bag extends Record<string, any>>(steps: Step<Bag, any, any, any, any>[], initialFields?: Set<keyof Bag>): WorkflowPlan<Bag>;
|
|
90
|
+
/**
|
|
91
|
+
* Validates a workflow plan for common issues.
|
|
92
|
+
*
|
|
93
|
+
* This is a convenience function that runs the planner and returns
|
|
94
|
+
* validation errors without throwing.
|
|
95
|
+
*
|
|
96
|
+
* @param steps - Array of steps in the workflow
|
|
97
|
+
* @param initialFields - Fields provided as initial data
|
|
98
|
+
* @returns Validation result with success flag and optional error message
|
|
99
|
+
*/
|
|
100
|
+
export declare function validateWorkflowPlan<Bag extends Record<string, any>>(steps: Step<Bag, any, any, any, any>[], initialFields?: Set<keyof Bag>): {
|
|
101
|
+
success: true;
|
|
102
|
+
plan: WorkflowPlan<Bag>;
|
|
103
|
+
} | {
|
|
104
|
+
success: false;
|
|
105
|
+
error: string;
|
|
106
|
+
};
|
|
107
|
+
//# sourceMappingURL=workflow-planning.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-planning.d.ts","sourceRoot":"","sources":["../../src/internal/workflow-planning.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE5C;;GAEG;AACH,MAAM,WAAW,YAAY,CAAC,GAAG,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAC3D,8EAA8E;IAC9E,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC;IAE3C,qDAAqD;IACrD,SAAS,EAAE,GAAG,CAAC,MAAM,GAAG,EAAE,MAAM,CAAC,CAAC;IAElC,kEAAkE;IAClE,cAAc,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACjE,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,EACtC,aAAa,GAAE,GAAG,CAAC,MAAM,GAAG,CAAa,GACxC,YAAY,CAAC,GAAG,CAAC,CA0InB;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAClE,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,EACtC,aAAa,GAAE,GAAG,CAAC,MAAM,GAAG,CAAa,GACxC;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,YAAY,CAAC,GAAG,CAAC,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAUhF"}
|