1.2.0 • Published 2 years ago

js-dsl v1.2.0

Weekly downloads
3
License
MIT
Repository
github
Last release
2 years ago

js-dsl

js-dsl is a nodejs framework for developing internal, builder-style domain specific languages (DSLs).

Examples of builder-style DSLs include mocha.

Examples

Arbitary Tree

This example builds an arbitrary forest of tree and tip nodes like the one shown below. Calls to tree translate to Tree objects (likewise for tip).

const forest = new TreeBuilder.build( () =>
 tree( 'a', () => {
    tree( 'b', () => {
      tip( 'c' )
    } )
    tip( 'd' )
    tree( 'e', () => {
      tree( 'f', () => {
        tree( 'g', () => {
          tip( 'd' )
        } )
        tip( 'h' )
      } )
    } )
  } ) )

js-dsl generates the approriate hierarchy from nested calls to tree and tip.

└─a
  ├─b
  │ └─c
  ├─d
  └─e
    └─f
      ├─g
      │ └─d
      └─h

js-dsl needs to know how to translate tree to Tree (and tip to Tip). We do this by registering a factory for tree and tip.

const { JsDsl, AbstractFactory } = require( 'js-dsl' );

class TreeBuilder extends JsDsl {
  constructor() {
    super();
    this.registerFactory( 'tree', new TreeFactory() );
    this.registerFactory( 'tip', new TipFactory() );
  }
}

Factories are how js-dsl creates new nodes and ensures that they are inserted in the proper location in the builder's object hierarchy:

The Tree factory:

class TreeFactory extends AbstractFactory {
  newInstance( builder, name, args ) {
    return new Tree( args );
  }

  setChild( builder, parent, child ) {
    parent.addChild( child );
  }
}

The Tip Factory:

class TipFactory extends AbstractFactory {
  isLeaf() {
    return true;
  }

  newInstance( builder, name, args ) {
    return new Tip( args );
  }
}

Finally, the 'data' nodes:

class Tree {
  constructor( name ) {
    this.name = name;
    this.children = []
  }

  addChild( child ) {
    this.children.push( child );
  }
}

class Tip {
  constructor( name ) {
    this.name = name;
  }
}

HTML builder

The tests include a builder for simple HTML which allows building markup directly in Javascript:

const page = () =>
  html( { lang: 'en' }, () => {
    head( () => {
      title( 'test' );
      meta( { charset: 'utf-8' } )
      link( { href: 'style.css', rel: 'stylesheet' } )
      style( `
body {
  color: red;
} ` )
    } )
    body( () => {
      h1( 'header 1' )
      p( 'This is a paragraph' )
      div( { class: 'some-style' }, () => {
        div()
        h2( 'header 2' )
        p( 'This is another paragraph' )
      } )
    } )
  } )
1.2.0

2 years ago

1.1.0

5 years ago

1.0.5

5 years ago

1.0.4

5 years ago

1.0.3

5 years ago

0.6.6

7 years ago

0.6.5

7 years ago

0.6.4

7 years ago

0.6.3

7 years ago

0.6.2

7 years ago

0.6.1

7 years ago

0.6.0

7 years ago

0.5.0

7 years ago

0.4.4

7 years ago

0.4.3

7 years ago

0.4.2

7 years ago