Skip to content

0.2.0. #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## 0.2.0

* Added the `forEachChildren` method to the `DefinitionWalker` class.

### Breaking Changes

* The `forEach` method doesn't accept a sequence anymore. To foreach over a sequence, use the `forEachSequence` method.

## 0.1.4

* Added the `forEach()` method to the `DefinitionWalker` class.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "sequential-workflow-model",
"description": "Extendable data model of sequential workflow.",
"version": "0.1.4",
"version": "0.2.0",
"homepage": "https://nocode-js.com/",
"author": {
"name": "NoCode JS",
Expand Down
47 changes: 38 additions & 9 deletions src/definition-walker/definition-walker.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,25 @@ describe('DefinitionWalker', () => {
expect(count).toEqual(6);
});

it('stops when callback returns false', () => {
let count = 0;

walker.forEach(definition, () => {
count++;
if (count === 2) {
return false;
}
});

expect(count).toEqual(2);
});
});

describe('forEachSequence', () => {
it('iterates over sequence', () => {
const steps: Step[] = [];

walker.forEach(loop.sequence, step => {
walker.forEachSequence(loop.sequence, step => {
steps.push(step);
});

Expand All @@ -176,18 +191,32 @@ describe('DefinitionWalker', () => {
expect(steps[1]).toBe(ifAlfa);
expect(steps[2]).toBe(taskFoo);
});
});

it('stops when callback returns false', () => {
let count = 0;
describe('forEachChildren', () => {
it('iterates when sequential step is passed', () => {
const steps: Step[] = [];

walker.forEach(definition, () => {
count++;
if (count === 2) {
return false;
}
walker.forEachChildren(loop, step => {
steps.push(step);
});

expect(count).toEqual(2);
expect(steps.length).toEqual(3);
expect(steps[0]).toBe(ifBeta);
expect(steps[1]).toBe(ifAlfa);
expect(steps[2]).toBe(taskFoo);
});

it('iterates when branched step is passed', () => {
const steps: Step[] = [];

walker.forEachChildren(ifBeta, step => {
steps.push(step);
});

expect(steps.length).toEqual(2);
expect(steps[0]).toBe(ifAlfa);
expect(steps[1]).toBe(taskFoo);
});
});
});
71 changes: 39 additions & 32 deletions src/definition-walker/definition-walker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,16 @@ export class DefinitionWalker {
return this.getParentSequence(definition, stepId).step;
}

public forEach(sequenceOrDefinition: Sequence | Definition, callback: StepForEachCallback) {
const sequence = Array.isArray(sequenceOrDefinition) ? sequenceOrDefinition : sequenceOrDefinition.sequence;
this.iterate(sequence, callback);
public forEach(definition: Definition, callback: StepForEachCallback) {
this.iterateSequence(definition.sequence, callback);
}

public forEachSequence(sequence: Sequence, callback: StepForEachCallback) {
this.iterateSequence(sequence, callback);
}

public forEachChildren(step: Step, callback: StepForEachCallback) {
this.iterateStep(step, callback);
}

private find(
Expand Down Expand Up @@ -138,7 +145,6 @@ export class DefinitionWalker {
}
}
break;

case StepChildrenType.branches:
{
const branches = children.items as Branches;
Expand All @@ -153,51 +159,52 @@ export class DefinitionWalker {
}
}
break;

default:
throw new Error(`Step children type ${children.type} is not supported`);
throw new Error(`Not supported step children type: ${children.type}`);
}
}
}
return false;
}

private iterate(sequence: Sequence, callback: StepForEachCallback): boolean {
private iterateSequence(sequence: Sequence, callback: StepForEachCallback): boolean {
const count = sequence.length;
for (let index = 0; index < count; index++) {
const step = sequence[index];
if (callback(step, index, sequence) === false) {
return false;
}
if (!this.iterateStep(step, callback)) {
return false;
}
}
return true;
}

const children = this.getChildren(step);
if (children) {
switch (children.type) {
case StepChildrenType.sequence:
{
const childSequence = children.items as Sequence;
if (this.iterate(childSequence, callback) === false) {
return false;
}
private iterateStep(step: Step, callback: StepForEachCallback): boolean {
const children = this.getChildren(step);
if (children) {
switch (children.type) {
case StepChildrenType.sequence:
{
const sequence = children.items as Sequence;
if (!this.iterateSequence(sequence, callback)) {
return false;
}
break;

case StepChildrenType.branches:
{
const branches = children.items as Branches;
const branchNames = Object.keys(branches);
for (const branchName of branchNames) {
const parentSequence = branches[branchName];
if (this.iterate(parentSequence, callback) === false) {
return false;
}
}
break;
case StepChildrenType.branches:
{
const sequences = Object.values(children.items as Branches);
for (const sequence of sequences) {
if (!this.iterateSequence(sequence, callback)) {
return false;
}
}
break;

default:
throw new Error(`Step children type ${children.type} is not supported`);
}
}
break;
default:
throw new Error(`Not supported step children type: ${children.type}`);
}
}
return true;
Expand Down