scats
Version:
Useful scala classes in typescript
110 lines (109 loc) • 3.42 kB
JavaScript
import { none, some } from './option.js';
export function identity(x) {
return x;
}
export function toErrorConversion(x) {
if (x instanceof Error) {
return x;
}
else {
return new Error(`${x}`);
}
}
export class StepWithFilter {
name;
f;
filter;
constructor(name, f, filter) {
this.name = name;
this.f = f;
this.filter = filter;
}
if(condition) {
return new StepWithFilter(this.name, this.f, some(condition));
}
invokeStep(state) {
const result = this.f(state);
return this.filter.filter(() => 'filter' in result).map(filter => {
return result.filter(x => {
this.name.foreach(name => state[name] = x);
return filter(state);
});
}).getOrElseValue(result);
}
}
export class TaskWithFilter {
name;
f;
filter;
constructor(name, f, filter) {
this.name = name;
this.f = f;
this.filter = filter;
}
if(condition) {
return new TaskWithFilter(this.name, this.f, some(condition));
}
async invokeStep(state) {
const result = await this.f(state);
return this.filter.filter(() => 'filter' in result).map(filter => {
return result.filter(x => {
this.name.foreach(name => state[name] = x);
return filter(state);
});
}).getOrElseValue(result);
}
}
export function step(name, f) {
return new StepWithFilter(some(name), f, none);
}
export function task(name, f) {
return new TaskWithFilter(some(name), f, none);
}
export function forComprehension(...steps) {
return {
yield: function (final) {
function processStep(stepIdx, acc) {
const result = steps[stepIdx].invokeStep(acc);
if (stepIdx < steps.length - 1) {
return result.flatMap(x => {
steps[stepIdx].name.foreach(name => acc[name] = x);
return processStep(stepIdx + 1, acc);
});
}
else {
return result.map(x => {
steps[stepIdx].name.foreach(name => acc[name] = x);
return final(acc);
});
}
}
return processStep(0, {});
}
};
}
(function (forComprehension) {
function promise(...steps) {
return {
yield: function (final) {
async function processStep(stepIdx, acc) {
const result = await steps[stepIdx].invokeStep(acc);
if (stepIdx < steps.length - 1) {
return await result.flatMapPromise(x => {
steps[stepIdx].name.foreach(name => acc[name] = x);
return processStep(stepIdx + 1, acc);
});
}
else {
return result.map(x => {
steps[stepIdx].name.foreach(name => acc[name] = x);
return final(acc);
});
}
}
return processStep(0, {});
}
};
}
forComprehension.promise = promise;
})(forComprehension || (forComprehension = {}));