@ductape/sdk 0.1.144 → 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 +121 -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/resilience/fallback.service.d.ts +4 -0
- package/dist/resilience/fallback.service.js +7 -0
- package/dist/resilience/fallback.service.js.map +1 -1
- 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,
|
|
@@ -388,6 +390,9 @@ class FeatureExecutor {
|
|
|
388
390
|
token: this.config.token,
|
|
389
391
|
env_type: this.config.env_type,
|
|
390
392
|
private_key: this._privateKey,
|
|
393
|
+
access_key: this.config.access_key,
|
|
394
|
+
redis_client: this.config.redis_client,
|
|
395
|
+
preInitializedProductBuilder: this.productBuilder,
|
|
391
396
|
});
|
|
392
397
|
}
|
|
393
398
|
return this._fallbackService;
|
|
@@ -417,8 +422,18 @@ class FeatureExecutor {
|
|
|
417
422
|
const inputStr = stringifyProcessorValue(inputPayload);
|
|
418
423
|
const encKey = this.getProcessorResultEncryptionKey();
|
|
419
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
|
+
});
|
|
420
435
|
this.trace('execution.persistence.sent', { status, payload: resultData });
|
|
421
|
-
await this.processorApiService.saveResultsBatch([...this.pendingProcessorResults.splice(0), processorResult], this.getAuthPayload());
|
|
436
|
+
await this.processorApiService.saveResultsBatch([...this.pendingProcessorResults.splice(0), ...assetResults, processorResult], this.getAuthPayload());
|
|
422
437
|
this.trace('execution.persistence.acknowledged', { status, process_id: this.state.feature_id });
|
|
423
438
|
debugLog('[FeatureExecutor] persistExecutionResult SUCCESS', { feature_id: this.state.feature_id, status });
|
|
424
439
|
}
|
|
@@ -455,7 +470,7 @@ class FeatureExecutor {
|
|
|
455
470
|
* Processor results for steps always have component: 'feature_step' and step_type set to the step kind.
|
|
456
471
|
*/
|
|
457
472
|
async persistStepResult(step, status, output, error, duration, input) {
|
|
458
|
-
var _a;
|
|
473
|
+
var _a, _b;
|
|
459
474
|
const resolvedInput = input !== null && input !== void 0 ? input : step.input;
|
|
460
475
|
const stepType = this.getStepTypeForResult(step);
|
|
461
476
|
debugLog('[FeatureExecutor] persistStepResult ENTRY', {
|
|
@@ -476,8 +491,8 @@ class FeatureExecutor {
|
|
|
476
491
|
const resultStr = stringifyProcessorValue(value);
|
|
477
492
|
const inputStr = stringifyProcessorValue(resolvedInput);
|
|
478
493
|
const encKey = this.getProcessorResultEncryptionKey();
|
|
479
|
-
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
|
|
480
|
-
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 : {}));
|
|
481
496
|
this.trace('step.persistence.sent', {
|
|
482
497
|
step_tag: step.tag,
|
|
483
498
|
step_type: stepType,
|
|
@@ -554,6 +569,7 @@ class FeatureExecutor {
|
|
|
554
569
|
session_id: this.sessionLogFields.session_id,
|
|
555
570
|
session_tag: this.sessionLogFields.session_tag,
|
|
556
571
|
session_user_id: this.sessionLogFields.session_user_id,
|
|
572
|
+
asset_span_sink: this.assetSpans,
|
|
557
573
|
});
|
|
558
574
|
return (0, context_1.runWithExecutionContext)(context, () => this.executeInContext());
|
|
559
575
|
}
|
|
@@ -822,6 +838,12 @@ class FeatureExecutor {
|
|
|
822
838
|
process_id: `${this.state.feature_id}:${step.tag}`,
|
|
823
839
|
parent_process_id: this.state.feature_id,
|
|
824
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
|
+
});
|
|
825
847
|
return (0, context_1.runWithExecutionContext)(context, () => this.executeStepInContext(step));
|
|
826
848
|
}
|
|
827
849
|
async executeStepInContext(step) {
|
|
@@ -842,62 +864,67 @@ class FeatureExecutor {
|
|
|
842
864
|
step_tag: step.tag,
|
|
843
865
|
input: sanitizeForLog(resolvedInput),
|
|
844
866
|
});
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
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
|
-
|
|
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();
|
|
901
928
|
// For action steps with no app: if step.output is a template with $ refs (e.g. $Sequence{main}{step-a}{value}-b),
|
|
902
929
|
// resolve it so downstream steps get the correct value (checkpoint / closure-style steps).
|
|
903
930
|
if (step.type === types_1.FeatureStepType.ACTION &&
|
|
@@ -951,9 +978,40 @@ class FeatureExecutor {
|
|
|
951
978
|
};
|
|
952
979
|
}
|
|
953
980
|
}
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
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. */
|
|
957
1015
|
async executeActionStep(step, input) {
|
|
958
1016
|
var _a, _b;
|
|
959
1017
|
debugLog('[FeatureExecutor] executeActionStep', { feature_id: this.state.feature_id, step_tag: step.tag, app: step.app });
|