Home Manual Reference Source Test

src/pipeline/step.js

  1. /**
  2. * Pipeline phase interface; subclass name "StepNSuffix" drives index/id/name.
  3. * @interface
  4. * @example
  5. * const step = new Step2Chords();
  6. * step.index; // 2
  7. * step.id; // "step2"
  8. * step.name; // "Step 2 (Chords)"
  9. */
  10. export class Step {
  11. /** @type {string} Step id "step{index}". */
  12. get id() {
  13. return `step${this.index}`;
  14. }
  15. /** @type {number} Step index from class name. */
  16. get index() {
  17. return Number(this.constructor.name.match(/^Step(\d+)/)[1]);
  18. }
  19. /** @type {string} Display name "Step {index} ({Suffix})". */
  20. get name() {
  21. const m = this.constructor.name.match(/^Step(\d+)([A-Z][a-zA-Z]*)$/);
  22. return `Step ${m[1]} (${m[2]})`;
  23. }
  24. /**
  25. * @abstract
  26. * @return {Object[]} UI parameter descriptors.
  27. * @throws {Error} When called on a Step subclass that did not override schema().
  28. */
  29. schema() {
  30. throw new Error("Not implemented: schema()");
  31. }
  32. }
  33. /**
  34. * Trait: adds abstract solve(parameters, solver) to a Step subclass.
  35. * Non-solvable steps (e.g. pure form definitions) just extend Step directly.
  36. * @typedef {Step} Solvable
  37. * @example
  38. * class Step9Foo extends Solvable(Step) {
  39. * schema() { return SCHEMA; }
  40. * async solve(parameters, solver) {
  41. * const { model } = modelFoo(parameters);
  42. * const solution = await solver(model);
  43. * return { textOutput: solution ? "ok" : "no solution", solution };
  44. * }
  45. * }
  46. */
  47. export const Solvable = (Base) =>
  48. class extends Base {
  49. /**
  50. * @abstract
  51. * Build a model from parameters, hand it to the solver, render a result.
  52. * @param {Object} parameters - Per-step form values; see the concrete step's schema().
  53. * @param {function(model: string): Promise<Object>} solver - Pre-bound solver callback.
  54. * @return {Promise<Object|null>} Per-step result containing the CSP solution (sigma); null reserved for skip cases.
  55. * @throws {Error} When called on a Solvable subclass that did not override solve().
  56. */
  57. solve(parameters, solver) {
  58. throw new Error(
  59. `Not implemented: solve(parameters=${typeof parameters}, solver=${typeof solver})`,
  60. );
  61. }
  62. };