-
Notifications
You must be signed in to change notification settings - Fork 39
Expand file tree
/
Copy pathdeclarative.js
More file actions
44 lines (38 loc) · 1.15 KB
/
declarative.js
File metadata and controls
44 lines (38 loc) · 1.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
'use strict';
const PointDSL = {
[Symbol.for('tag')]: 'point',
create: ({ x, y }) => {
const errors = [];
if (!Number.isFinite(x)) errors.push(new TypeError(`Invalid x: ${x}`));
if (!Number.isFinite(y)) errors.push(new TypeError(`Invalid y: ${y}`));
if (errors.length > 0) {
const cause = new AggregateError(errors, 'Validation');
throw new RangeError('Bad coordinates', { cause });
}
return { x, y };
},
clone: ({ point }) => ({ x: point.x, y: point.y }),
move: ({ point, dx, dy }) => ({ x: point.x + dx, y: point.y + dy }),
toString: ({ point }) => `(${point.x}, ${point.y})`,
};
const execute = (dsl, steps) => {
const tag = dsl[Symbol.for('tag')];
let instance = null;
for (const step of steps) {
const op = Object.keys(step)[0];
const operation = dsl[op];
const args = { ...step[op], [tag]: instance };
instance = operation(args);
if (step.log) {
console.log(dsl.toString({ [tag]: instance }));
}
}
return instance;
};
// Usage
const steps = [
{ create: { x: 10, y: 20 }, log: true },
{ clone: {} },
{ move: { dx: -5, dy: 10 }, log: true },
];
execute(PointDSL, steps);