@ductape/sdk 0.1.145 → 0.1.147
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/context/execution-context.d.ts +29 -1
- package/dist/context/execution-context.js +57 -1
- package/dist/context/execution-context.js.map +1 -1
- package/dist/features/feature-executor.d.ts +4 -3
- package/dist/features/feature-executor.js +118 -63
- package/dist/features/feature-executor.js.map +1 -1
- package/dist/functions/functions.runtime.js +30 -6
- package/dist/functions/functions.runtime.js.map +1 -1
- package/dist/functions/http-handler.js +22 -4
- package/dist/functions/http-handler.js.map +1 -1
- package/dist/functions/types.d.ts +2 -0
- package/dist/functions/types.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +28 -9
- package/dist/index.js.map +1 -1
- package/dist/processor/services/processor.service.d.ts +2 -2
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/processor.types.d.ts +6 -0
- package/dist/types/processor.types.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,24 @@
|
|
|
1
|
-
export type DuctapeExecutionKind = 'feature' | 'step' | 'function' | 'primitive';
|
|
1
|
+
export type DuctapeExecutionKind = 'feature' | 'step' | 'function' | 'primitive' | 'asset';
|
|
2
|
+
export interface DuctapeAssetSpan {
|
|
3
|
+
trace_id: string;
|
|
4
|
+
span_id: string;
|
|
5
|
+
parent_span_id?: string;
|
|
6
|
+
feature_id?: string;
|
|
7
|
+
feature_tag?: string;
|
|
8
|
+
feature_run_id?: string;
|
|
9
|
+
step_tag?: string;
|
|
10
|
+
step_run_id?: string;
|
|
11
|
+
function_invocation_id?: string;
|
|
12
|
+
asset_type: string;
|
|
13
|
+
asset_tag: string;
|
|
14
|
+
asset_operation: string;
|
|
15
|
+
asset_action?: string;
|
|
16
|
+
status: 'success' | 'fail';
|
|
17
|
+
start: number;
|
|
18
|
+
end: number;
|
|
19
|
+
duration_ms: number;
|
|
20
|
+
error_message?: string;
|
|
21
|
+
}
|
|
2
22
|
export interface DuctapeExecutionContext {
|
|
3
23
|
workspace_id?: string;
|
|
4
24
|
product_id?: string;
|
|
@@ -28,6 +48,8 @@ export interface DuctapeExecutionContext {
|
|
|
28
48
|
idempotency_key?: string;
|
|
29
49
|
deadline_at?: number;
|
|
30
50
|
baggage?: Record<string, string>;
|
|
51
|
+
/** Internal per-run span sink. It is never serialized into logs or processor results. */
|
|
52
|
+
asset_span_sink?: DuctapeAssetSpan[];
|
|
31
53
|
kind: DuctapeExecutionKind;
|
|
32
54
|
}
|
|
33
55
|
export declare function currentExecutionContext(): DuctapeExecutionContext | undefined;
|
|
@@ -35,3 +57,9 @@ export declare function createExecutionContext(fields: Partial<DuctapeExecutionC
|
|
|
35
57
|
export declare function runWithExecutionContext<T>(context: DuctapeExecutionContext, fn: () => T): T;
|
|
36
58
|
/** Fields safe and useful on processor-result/log records. */
|
|
37
59
|
export declare function executionContextFields(context?: DuctapeExecutionContext): Record<string, unknown>;
|
|
60
|
+
export declare function withAssetSpan<T>(asset: {
|
|
61
|
+
type: string;
|
|
62
|
+
tag: string;
|
|
63
|
+
operation: string;
|
|
64
|
+
action?: string;
|
|
65
|
+
}, fn: () => Promise<T>): Promise<T>;
|
|
@@ -15,6 +15,7 @@ exports.currentExecutionContext = currentExecutionContext;
|
|
|
15
15
|
exports.createExecutionContext = createExecutionContext;
|
|
16
16
|
exports.runWithExecutionContext = runWithExecutionContext;
|
|
17
17
|
exports.executionContextFields = executionContextFields;
|
|
18
|
+
exports.withAssetSpan = withAssetSpan;
|
|
18
19
|
const async_hooks_1 = require("async_hooks");
|
|
19
20
|
const crypto_1 = require("crypto");
|
|
20
21
|
const storage = new async_hooks_1.AsyncLocalStorage();
|
|
@@ -32,7 +33,62 @@ function runWithExecutionContext(context, fn) {
|
|
|
32
33
|
function executionContextFields(context = currentExecutionContext()) {
|
|
33
34
|
if (!context)
|
|
34
35
|
return {};
|
|
35
|
-
const { session: _secretSession, baggage: _baggage, kind: execution_kind } = context, fields = __rest(context, ["session", "baggage", "kind"]);
|
|
36
|
+
const { session: _secretSession, baggage: _baggage, asset_span_sink: _assetSpanSink, kind: execution_kind } = context, fields = __rest(context, ["session", "baggage", "asset_span_sink", "kind"]);
|
|
36
37
|
return Object.assign(Object.assign({}, fields), { execution_kind });
|
|
37
38
|
}
|
|
39
|
+
async function withAssetSpan(asset, fn) {
|
|
40
|
+
const parent = currentExecutionContext();
|
|
41
|
+
if (!(parent === null || parent === void 0 ? void 0 : parent.asset_span_sink))
|
|
42
|
+
return fn();
|
|
43
|
+
const context = createExecutionContext({ kind: 'asset' }, parent);
|
|
44
|
+
const start = Date.now();
|
|
45
|
+
try {
|
|
46
|
+
const result = await runWithExecutionContext(context, fn);
|
|
47
|
+
const end = Date.now();
|
|
48
|
+
parent.asset_span_sink.push({
|
|
49
|
+
trace_id: context.trace_id,
|
|
50
|
+
span_id: context.span_id,
|
|
51
|
+
parent_span_id: context.parent_span_id,
|
|
52
|
+
feature_id: context.feature_id,
|
|
53
|
+
feature_tag: context.feature_tag,
|
|
54
|
+
feature_run_id: context.feature_run_id,
|
|
55
|
+
step_tag: context.step_tag,
|
|
56
|
+
step_run_id: context.step_run_id,
|
|
57
|
+
function_invocation_id: context.function_invocation_id,
|
|
58
|
+
asset_type: asset.type,
|
|
59
|
+
asset_tag: asset.tag,
|
|
60
|
+
asset_operation: asset.operation,
|
|
61
|
+
asset_action: asset.action,
|
|
62
|
+
status: 'success',
|
|
63
|
+
start,
|
|
64
|
+
end,
|
|
65
|
+
duration_ms: end - start,
|
|
66
|
+
});
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
const end = Date.now();
|
|
71
|
+
parent.asset_span_sink.push({
|
|
72
|
+
trace_id: context.trace_id,
|
|
73
|
+
span_id: context.span_id,
|
|
74
|
+
parent_span_id: context.parent_span_id,
|
|
75
|
+
feature_id: context.feature_id,
|
|
76
|
+
feature_tag: context.feature_tag,
|
|
77
|
+
feature_run_id: context.feature_run_id,
|
|
78
|
+
step_tag: context.step_tag,
|
|
79
|
+
step_run_id: context.step_run_id,
|
|
80
|
+
function_invocation_id: context.function_invocation_id,
|
|
81
|
+
asset_type: asset.type,
|
|
82
|
+
asset_tag: asset.tag,
|
|
83
|
+
asset_operation: asset.operation,
|
|
84
|
+
asset_action: asset.action,
|
|
85
|
+
status: 'fail',
|
|
86
|
+
start,
|
|
87
|
+
end,
|
|
88
|
+
duration_ms: end - start,
|
|
89
|
+
error_message: error instanceof Error ? error.message : String(error),
|
|
90
|
+
});
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
38
94
|
//# sourceMappingURL=execution-context.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution-context.js","sourceRoot":"","sources":["../../src/context/execution-context.ts"],"names":[],"mappings":";;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"execution-context.js","sourceRoot":"","sources":["../../src/context/execution-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -60,6 +60,8 @@ export declare class FeatureExecutor {
|
|
|
60
60
|
private functionInvocations;
|
|
61
61
|
/** Step telemetry is accumulated and persisted with the terminal feature record in one round trip. */
|
|
62
62
|
private pendingProcessorResults;
|
|
63
|
+
private assetSpans;
|
|
64
|
+
private stepContexts;
|
|
63
65
|
constructor(config: IFeatureServiceConfig & {
|
|
64
66
|
access_key: string;
|
|
65
67
|
}, feature: IProductFeature, options: IExecuteFeatureOptions, private_key: string, sessionLogFields?: {
|
|
@@ -127,9 +129,8 @@ export declare class FeatureExecutor {
|
|
|
127
129
|
*/
|
|
128
130
|
private executeStep;
|
|
129
131
|
private executeStepInContext;
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
*/
|
|
132
|
+
private describeStepAsset;
|
|
133
|
+
/** Execute an action step. */
|
|
133
134
|
private executeActionStep;
|
|
134
135
|
/**
|
|
135
136
|
* Execute a database step: use query/insert/update/delete/upsert for DB operations, execute() for named actions.
|
|
@@ -165,6 +165,8 @@ class FeatureExecutor {
|
|
|
165
165
|
this.functionInvocations = new Map();
|
|
166
166
|
/** Step telemetry is accumulated and persisted with the terminal feature record in one round trip. */
|
|
167
167
|
this.pendingProcessorResults = [];
|
|
168
|
+
this.assetSpans = [];
|
|
169
|
+
this.stepContexts = new Map();
|
|
168
170
|
debugLog('[FeatureExecutor] constructor ENTRY', {
|
|
169
171
|
feature_tag: feature.tag,
|
|
170
172
|
product: options.product,
|
|
@@ -420,8 +422,18 @@ class FeatureExecutor {
|
|
|
420
422
|
const inputStr = stringifyProcessorValue(inputPayload);
|
|
421
423
|
const encKey = this.getProcessorResultEncryptionKey();
|
|
422
424
|
const processorResult = Object.assign(Object.assign({}, (0, context_1.executionContextFields)()), { process_id: this.state.feature_id, product_id: this.productId || null, env: this.state.env, component: types_1.LogEventTypes.FEATURE, status, start: this.state.started_at, end: Date.now(), retryable: true, result: encKey ? (0, processor_utils_1.encrypt)(resultStr, encKey) : resultStr, input: encKey ? (0, processor_utils_1.encrypt)(inputStr, encKey) : inputStr, feature_id: this.state.feature_id, feature_tag: this.state.feature_tag, product_tag: this.state.product, workspace_id: this.config.workspace_id });
|
|
425
|
+
const assetResults = this.assetSpans.splice(0).map((span) => {
|
|
426
|
+
const spanResult = stringifyProcessorValue({
|
|
427
|
+
asset_type: span.asset_type,
|
|
428
|
+
asset_tag: span.asset_tag,
|
|
429
|
+
operation: span.asset_operation,
|
|
430
|
+
action: span.asset_action,
|
|
431
|
+
});
|
|
432
|
+
const spanInput = stringifyProcessorValue({});
|
|
433
|
+
return Object.assign(Object.assign({}, span), { process_id: span.span_id, product_id: this.productId || null, product_tag: this.state.product, workspace_id: this.config.workspace_id, env: this.state.env, component: 'asset_invocation', execution_kind: 'asset', retryable: true, result: encKey ? (0, processor_utils_1.encrypt)(spanResult, encKey) : spanResult, input: encKey ? (0, processor_utils_1.encrypt)(spanInput, encKey) : spanInput, asset_duration_ms: span.duration_ms, asset_error: span.error_message });
|
|
434
|
+
});
|
|
423
435
|
this.trace('execution.persistence.sent', { status, payload: resultData });
|
|
424
|
-
await this.processorApiService.saveResultsBatch([...this.pendingProcessorResults.splice(0), processorResult], this.getAuthPayload());
|
|
436
|
+
await this.processorApiService.saveResultsBatch([...this.pendingProcessorResults.splice(0), ...assetResults, processorResult], this.getAuthPayload());
|
|
425
437
|
this.trace('execution.persistence.acknowledged', { status, process_id: this.state.feature_id });
|
|
426
438
|
debugLog('[FeatureExecutor] persistExecutionResult SUCCESS', { feature_id: this.state.feature_id, status });
|
|
427
439
|
}
|
|
@@ -458,7 +470,7 @@ class FeatureExecutor {
|
|
|
458
470
|
* Processor results for steps always have component: 'feature_step' and step_type set to the step kind.
|
|
459
471
|
*/
|
|
460
472
|
async persistStepResult(step, status, output, error, duration, input) {
|
|
461
|
-
var _a;
|
|
473
|
+
var _a, _b;
|
|
462
474
|
const resolvedInput = input !== null && input !== void 0 ? input : step.input;
|
|
463
475
|
const stepType = this.getStepTypeForResult(step);
|
|
464
476
|
debugLog('[FeatureExecutor] persistStepResult ENTRY', {
|
|
@@ -479,8 +491,8 @@ class FeatureExecutor {
|
|
|
479
491
|
const resultStr = stringifyProcessorValue(value);
|
|
480
492
|
const inputStr = stringifyProcessorValue(resolvedInput);
|
|
481
493
|
const encKey = this.getProcessorResultEncryptionKey();
|
|
482
|
-
const stepResult = Object.assign(Object.assign(Object.assign({}, (0, context_1.executionContextFields)()), { process_id: stepProcessId, product_id: this.productId || null, env: this.state.env, component: types_1.LogEventTypes.FEATURE_STEP, // step results always feature_step
|
|
483
|
-
status, start: Date.now() - (duration || 0), end: Date.now(), retryable: true, result: encKey ? (0, processor_utils_1.encrypt)(resultStr, encKey) : resultStr, input: encKey ? (0, processor_utils_1.encrypt)(inputStr, encKey) : inputStr, feature_id: this.state.feature_id, feature_tag: this.state.feature_tag, product_tag: this.state.product, workspace_id: this.config.workspace_id, step_tag: step.tag, step_type: stepType, step_error: error, step_duration_ms: duration }), ((
|
|
494
|
+
const stepResult = Object.assign(Object.assign(Object.assign(Object.assign({}, (0, context_1.executionContextFields)()), ((_a = this.stepContexts.get(step.tag)) !== null && _a !== void 0 ? _a : {})), { process_id: stepProcessId, product_id: this.productId || null, env: this.state.env, component: types_1.LogEventTypes.FEATURE_STEP, // step results always feature_step
|
|
495
|
+
status, start: Date.now() - (duration || 0), end: Date.now(), retryable: true, result: encKey ? (0, processor_utils_1.encrypt)(resultStr, encKey) : resultStr, input: encKey ? (0, processor_utils_1.encrypt)(inputStr, encKey) : inputStr, feature_id: this.state.feature_id, feature_tag: this.state.feature_tag, product_tag: this.state.product, workspace_id: this.config.workspace_id, step_tag: step.tag, step_type: stepType, step_error: error, step_duration_ms: duration }), ((_b = this.functionInvocations.get(step.tag)) !== null && _b !== void 0 ? _b : {}));
|
|
484
496
|
this.trace('step.persistence.sent', {
|
|
485
497
|
step_tag: step.tag,
|
|
486
498
|
step_type: stepType,
|
|
@@ -557,6 +569,7 @@ class FeatureExecutor {
|
|
|
557
569
|
session_id: this.sessionLogFields.session_id,
|
|
558
570
|
session_tag: this.sessionLogFields.session_tag,
|
|
559
571
|
session_user_id: this.sessionLogFields.session_user_id,
|
|
572
|
+
asset_span_sink: this.assetSpans,
|
|
560
573
|
});
|
|
561
574
|
return (0, context_1.runWithExecutionContext)(context, () => this.executeInContext());
|
|
562
575
|
}
|
|
@@ -825,6 +838,12 @@ class FeatureExecutor {
|
|
|
825
838
|
process_id: `${this.state.feature_id}:${step.tag}`,
|
|
826
839
|
parent_process_id: this.state.feature_id,
|
|
827
840
|
}, parent);
|
|
841
|
+
this.stepContexts.set(step.tag, {
|
|
842
|
+
trace_id: context.trace_id,
|
|
843
|
+
span_id: context.span_id,
|
|
844
|
+
parent_span_id: context.parent_span_id,
|
|
845
|
+
step_run_id: context.step_run_id,
|
|
846
|
+
});
|
|
828
847
|
return (0, context_1.runWithExecutionContext)(context, () => this.executeStepInContext(step));
|
|
829
848
|
}
|
|
830
849
|
async executeStepInContext(step) {
|
|
@@ -845,62 +864,67 @@ class FeatureExecutor {
|
|
|
845
864
|
step_tag: step.tag,
|
|
846
865
|
input: sanitizeForLog(resolvedInput),
|
|
847
866
|
});
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
867
|
+
const asset = this.describeStepAsset(step);
|
|
868
|
+
const runOperation = async () => {
|
|
869
|
+
let value;
|
|
870
|
+
// Route steps to dedicated services; only action and notification use ProcessorService.
|
|
871
|
+
switch (step.type) {
|
|
872
|
+
case types_1.FeatureStepType.ACTION:
|
|
873
|
+
value = await this.executeActionStep(step, resolvedInput);
|
|
874
|
+
break;
|
|
875
|
+
case types_1.FeatureStepType.DATABASE_ACTION:
|
|
876
|
+
value = await this.executeDatabaseStep(step, resolvedInput);
|
|
877
|
+
break;
|
|
878
|
+
case types_1.FeatureStepType.NOTIFICATION:
|
|
879
|
+
value = await this.executeNotificationStep(step, resolvedInput);
|
|
880
|
+
break;
|
|
881
|
+
case types_1.FeatureStepType.STORAGE:
|
|
882
|
+
value = await this.executeStorageStep(step, resolvedInput);
|
|
883
|
+
break;
|
|
884
|
+
case types_1.FeatureStepType.PUBLISH:
|
|
885
|
+
case types_1.FeatureStepType.PRODUCE:
|
|
886
|
+
value = await this.executeProduceStep(step, resolvedInput);
|
|
887
|
+
break;
|
|
888
|
+
case types_1.FeatureStepType.GRAPH:
|
|
889
|
+
value = await this.executeGraphStep(step, resolvedInput);
|
|
890
|
+
break;
|
|
891
|
+
case types_1.FeatureStepType.VECTOR:
|
|
892
|
+
value = await this.executeVectorStep(step, resolvedInput);
|
|
893
|
+
break;
|
|
894
|
+
case types_1.FeatureStepType.SESSION:
|
|
895
|
+
value = await this.executeSessionStep(step, resolvedInput);
|
|
896
|
+
break;
|
|
897
|
+
case types_1.FeatureStepType.FUNCTION:
|
|
898
|
+
value = await this.executeFunctionStep(step, resolvedInput);
|
|
899
|
+
break;
|
|
900
|
+
case types_1.FeatureStepType.QUOTA:
|
|
901
|
+
value = await this.executeQuotaStep(step, resolvedInput);
|
|
902
|
+
break;
|
|
903
|
+
case types_1.FeatureStepType.FALLBACK:
|
|
904
|
+
value = await this.executeFallbackStep(step, resolvedInput);
|
|
905
|
+
break;
|
|
906
|
+
case types_1.FeatureStepType.CHILD_FEATURE:
|
|
907
|
+
value = await this.executeChildWorkflowStep(step, resolvedInput);
|
|
908
|
+
break;
|
|
909
|
+
case types_1.FeatureStepType.SLEEP:
|
|
910
|
+
await this.executeSleepStep(step, resolvedInput);
|
|
911
|
+
value = { slept: true };
|
|
912
|
+
break;
|
|
913
|
+
case types_1.FeatureStepType.WAIT_FOR_SIGNAL:
|
|
914
|
+
value = await this.executeWaitForSignalStep(step, resolvedInput);
|
|
915
|
+
break;
|
|
916
|
+
case types_1.FeatureStepType.CHECKPOINT:
|
|
917
|
+
await this.executeCheckpointStep(step, resolvedInput);
|
|
918
|
+
value = { checkpoint: step.tag };
|
|
919
|
+
break;
|
|
920
|
+
default:
|
|
921
|
+
stepLog('Step type not implemented (passthrough)', { tag: step.tag, type: step.type });
|
|
922
|
+
debugLog('[FeatureExecutor] executeStep unknown step type (passthrough)', { step_tag: step.tag, step_type: step.type });
|
|
923
|
+
value = resolvedInput;
|
|
924
|
+
}
|
|
925
|
+
return value;
|
|
926
|
+
};
|
|
927
|
+
let output = asset ? await (0, context_1.withAssetSpan)(asset, runOperation) : await runOperation();
|
|
904
928
|
// For action steps with no app: if step.output is a template with $ refs (e.g. $Sequence{main}{step-a}{value}-b),
|
|
905
929
|
// resolve it so downstream steps get the correct value (checkpoint / closure-style steps).
|
|
906
930
|
if (step.type === types_1.FeatureStepType.ACTION &&
|
|
@@ -954,9 +978,40 @@ class FeatureExecutor {
|
|
|
954
978
|
};
|
|
955
979
|
}
|
|
956
980
|
}
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
981
|
+
describeStepAsset(step) {
|
|
982
|
+
var _a, _b;
|
|
983
|
+
const operation = step.event || 'execute';
|
|
984
|
+
switch (step.type) {
|
|
985
|
+
case types_1.FeatureStepType.ACTION:
|
|
986
|
+
return step.app ? { type: 'app', tag: step.app, operation, action: step.event } : null;
|
|
987
|
+
case types_1.FeatureStepType.DATABASE_ACTION:
|
|
988
|
+
return { type: 'database', tag: step.database || 'database', operation, action: step.event };
|
|
989
|
+
case types_1.FeatureStepType.GRAPH:
|
|
990
|
+
return { type: 'graph', tag: step.graph || 'graph', operation, action: step.event };
|
|
991
|
+
case types_1.FeatureStepType.VECTOR:
|
|
992
|
+
return { type: 'vector', tag: step.vector || 'vector', operation, action: step.event };
|
|
993
|
+
case types_1.FeatureStepType.STORAGE:
|
|
994
|
+
return { type: 'storage', tag: step.storage || 'storage', operation, action: step.event };
|
|
995
|
+
case types_1.FeatureStepType.NOTIFICATION:
|
|
996
|
+
return { type: 'notification', tag: step.notification || 'notification', operation, action: step.event };
|
|
997
|
+
case types_1.FeatureStepType.PUBLISH:
|
|
998
|
+
case types_1.FeatureStepType.PRODUCE:
|
|
999
|
+
return { type: 'message_broker', tag: step.broker || 'message-broker', operation: 'produce', action: step.event };
|
|
1000
|
+
case types_1.FeatureStepType.SESSION:
|
|
1001
|
+
return { type: 'session', tag: step.session || 'session', operation, action: step.event };
|
|
1002
|
+
case types_1.FeatureStepType.QUOTA:
|
|
1003
|
+
return { type: 'quota', tag: step.quota || 'quota', operation: 'execute' };
|
|
1004
|
+
case types_1.FeatureStepType.FALLBACK:
|
|
1005
|
+
return { type: 'fallback', tag: step.fallback || 'fallback', operation: 'execute' };
|
|
1006
|
+
case types_1.FeatureStepType.CHILD_FEATURE:
|
|
1007
|
+
return { type: 'feature', tag: step.feature || 'feature', operation: 'execute' };
|
|
1008
|
+
case types_1.FeatureStepType.FUNCTION:
|
|
1009
|
+
return { type: 'function', tag: ((_a = step.function_ref) === null || _a === void 0 ? void 0 : _a.namespace) || 'function', operation: ((_b = step.function_ref) === null || _b === void 0 ? void 0 : _b.operation) || operation };
|
|
1010
|
+
default:
|
|
1011
|
+
return null;
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
/** Execute an action step. */
|
|
960
1015
|
async executeActionStep(step, input) {
|
|
961
1016
|
var _a, _b;
|
|
962
1017
|
debugLog('[FeatureExecutor] executeActionStep', { feature_id: this.state.feature_id, step_tag: step.tag, app: step.app });
|