Skip to content

Commit 325e343

Browse files
author
Alice
authored
Merge pull request #8 from beforeyoubid/feature/fix-context
fixed context to store by stage name
2 parents 2cce7c3 + adf7b18 commit 325e343

File tree

2 files changed

+33
-35
lines changed

2 files changed

+33
-35
lines changed

src/index.ts

Lines changed: 32 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,9 @@ export default class StepFunctionsOfflinePlugin implements Plugin {
5151
private eventForParallelExecution?: Event;
5252
private currentStateName: Maybe<string>;
5353
private currentState: Maybe<State>;
54-
private contextObject: Maybe<ContextObject>;
55-
private subContextObject: Maybe<ContextObject>;
54+
private contexts: {
55+
[key: string]: Maybe<ContextObject>;
56+
};
5657
private subStates: StateMachine['States'] = {};
5758
private states: StateMachine['States'] = {};
5859
private parallelBranch: Maybe<Branch>;
@@ -77,6 +78,7 @@ export default class StepFunctionsOfflinePlugin implements Plugin {
7778
this.functions = this.serverless.service.functions;
7879
this.variables = this.serverless.service.custom?.stepFunctionsOffline;
7980
this.cliLog = this.serverless.cli.log.bind(this.serverless.cli);
81+
this.contexts = {};
8082
this.commands = {
8183
'step-functions-offline': {
8284
usage: 'Will run your step function locally',
@@ -293,36 +295,26 @@ export default class StepFunctionsOfflinePlugin implements Plugin {
293295
if (!this.stateDefinition?.StartAt) {
294296
throw new Error('Missing `startAt` in definition');
295297
}
296-
this.contextObject = this.createContextObject(
297-
this.stateDefinition.States,
298-
this.stateDefinition.StartAt,
299-
event,
300-
false
301-
);
298+
this.addContextObject(this.stateDefinition.States, this.stateDefinition.StartAt, event);
302299
this.states = this.stateDefinition.States;
303-
return this.process(this.states[this.stateDefinition.StartAt], this.stateDefinition.StartAt, event, false);
300+
return this.process(this.states[this.stateDefinition.StartAt], this.stateDefinition.StartAt, event);
304301
}
305302

306303
async buildSubStepWorkFlow(
307304
stateDefinition: StateMachine,
308305
event: Event
309306
): Promise<ReturnType<StepFunctionsOfflinePlugin['process']>> {
310307
this.cliLog('Building Iterator StepWorkFlow');
311-
this.subContextObject = this.createContextObject(stateDefinition.States, stateDefinition.StartAt, event, true);
308+
this.addContextObject(stateDefinition.States, stateDefinition.StartAt, event);
312309

313310
if (!stateDefinition.States) return;
314311
const state = stateDefinition.States[stateDefinition.StartAt];
315-
const result = await this.process(state, stateDefinition.StartAt, event, true);
316-
this.subContextObject = null;
312+
const result = await this.process(state, stateDefinition.StartAt, event);
313+
this.contexts[stateDefinition.StartAt] = null;
317314
return result;
318315
}
319316

320-
process(
321-
state: State,
322-
stateName: string,
323-
event: Event,
324-
isSubContext: boolean
325-
): void | Promise<void | Callback> | Callback {
317+
process(state: State, stateName: string, event: Event): void | Promise<void | Callback> | Callback {
326318
if (state && state.Type === 'Parallel') {
327319
this.eventForParallelExecution = event;
328320
}
@@ -338,7 +330,8 @@ export default class StepFunctionsOfflinePlugin implements Plugin {
338330
if (stateIsChoiceConditional(data) && data.choice) {
339331
return this._runChoice(data, event);
340332
} else if (!stateIsChoiceConditional(data)) {
341-
return this._run(data.f(event), event, isSubContext);
333+
const callback = data.f(event);
334+
return this._run(callback, event, stateName);
342335
}
343336
}
344337

@@ -357,12 +350,12 @@ export default class StepFunctionsOfflinePlugin implements Plugin {
357350
_run(
358351
func: Callback | Promise<void | AsyncCallback>,
359352
event: Event,
360-
isSubContext: boolean
353+
name: string
361354
): void | Promise<void | Callback> | Callback {
362355
if (!func) return; // end of states
363356
this.executionLog(`~~~~~~~~~~~~~~~~~~~~~~~~~~~ ${this.currentStateName} started ~~~~~~~~~~~~~~~~~~~~~~~~~~~`);
364357

365-
const contextObject = isSubContext ? this.subContextObject : this.contextObject;
358+
const contextObject = this.contexts[name];
366359
if (contextObject) {
367360
if (func instanceof Promise) {
368361
return func.then(async mod => {
@@ -434,7 +427,7 @@ export default class StepFunctionsOfflinePlugin implements Plugin {
434427
this.mapResults = [];
435428

436429
if (currentState.Next) {
437-
await this.process(this.states[currentState.Next], currentState.Next, event, true);
430+
await this.process(this.states[currentState.Next], currentState.Next, event);
438431
}
439432
return Promise.resolve();
440433
});
@@ -469,11 +462,11 @@ export default class StepFunctionsOfflinePlugin implements Plugin {
469462
_.forEach(currentState.Branches, branch => {
470463
this.parallelBranch = branch;
471464
return this.eventForParallelExecution
472-
? this.process(branch.States[branch.StartAt], branch.StartAt, this.eventForParallelExecution, true)
465+
? this.process(branch.States[branch.StartAt], branch.StartAt, this.eventForParallelExecution)
473466
: null;
474467
});
475468
if (currentState.Next) {
476-
this.process(this.states[currentState.Next], currentState.Next, this.eventParallelResult, false);
469+
this.process(this.states[currentState.Next], currentState.Next, this.eventParallelResult);
477470
}
478471
delete this.parallelBranch;
479472
this.eventParallelResult = [];
@@ -607,13 +600,13 @@ export default class StepFunctionsOfflinePlugin implements Plugin {
607600
const isConditionTrue = choice.checkFunction(functionResultValue, choice.compareWithValue);
608601
if (isConditionTrue && choice.choiceFunction) {
609602
existsAnyMatches = true;
610-
return this.process(this.states[choice.choiceFunction], choice.choiceFunction, result, true);
603+
return this.process(this.states[choice.choiceFunction], choice.choiceFunction, result);
611604
}
612605
}
613606
});
614607
if (!existsAnyMatches && data.defaultFunction) {
615608
const fName = data.defaultFunction;
616-
return this.process(this.states[fName], fName, result, false);
609+
return this.process(this.states[fName], fName, result);
617610
}
618611
}
619612

@@ -664,12 +657,13 @@ export default class StepFunctionsOfflinePlugin implements Plugin {
664657
return waitTimer;
665658
}
666659

667-
createContextObject(
668-
states: StateMachine['States'],
669-
name: string,
670-
originalEvent: Event,
671-
isSubContext: boolean
672-
): ContextObject {
660+
addContextObject(states: StateMachine['States'], name: string, event: Event): void {
661+
if (this.contexts[name]) return;
662+
const contextObject = this.createContextObject(states, name, event);
663+
this.contexts[name] = contextObject;
664+
}
665+
666+
createContextObject(states: StateMachine['States'], name: string, originalEvent: Event): ContextObject {
673667
let attempt = 0;
674668
const cb = (err: Maybe<Error>, result?: Event) => {
675669
if (!notEmpty(this.currentState)) return;
@@ -683,16 +677,17 @@ export default class StepFunctionsOfflinePlugin implements Plugin {
683677
if (!matchingError) throw `Error in function "${this.currentStateName}": ${JSON.stringify(err)}`;
684678
attempt += 1;
685679
if (attempt < (matchingError.MaxAttempts ?? 0)) {
680+
this.addContextObject(states, name, originalEvent);
686681
if (matchingError.IntervalSeconds !== undefined && matchingError.IntervalSeconds !== 0) {
687682
const backoffRate = matchingError?.BackoffRate ?? 2;
688683
const fullDelay =
689684
attempt === 1
690685
? matchingError.IntervalSeconds
691686
: matchingError.IntervalSeconds * (attempt - 1) * backoffRate;
692687
console.log(`Delaying ${fullDelay} seconds for execution #${attempt + 1} of state ${name}`);
693-
return delay(fullDelay).then(() => this.process(states[name], name, originalEvent, isSubContext));
688+
return delay(fullDelay).then(() => this.process(states[name], name, originalEvent));
694689
}
695-
return this.process(states[name], name, originalEvent, isSubContext);
690+
return this.process(states[name], name, originalEvent);
696691
}
697692
const newErr = `Error in function "${this.currentStateName}" after ${attempt} attempts: ${JSON.stringify(
698693
this.currentState
@@ -713,11 +708,13 @@ export default class StepFunctionsOfflinePlugin implements Plugin {
713708
this.mapResults.push(result);
714709
}
715710
if (this.currentState?.Next) {
716-
return this.process(state[this.currentState.Next], this.currentState.Next, result ?? {}, isSubContext);
711+
this.addContextObject(states, this.currentState.Next, originalEvent);
712+
return this.process(state[this.currentState.Next], this.currentState.Next, result ?? {});
717713
}
718714
};
719715

720716
return {
717+
name,
721718
attempt,
722719
cb,
723720
done: cb,

src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ export type StateHandler = {
7777
};
7878

7979
export type ContextObject = {
80+
name: string;
8081
attempt: number;
8182
cb: (err: Maybe<Error>, result?: Event) => void | Callback | Promise<void | Callback>;
8283
done: ContextObject['cb'];

0 commit comments

Comments
 (0)