npm.io
0.0.6 • Published yesterday

ng-aspect

Licence
Version
0.0.6
Deps
0
Size
202 kB
Vulns
0
Weekly
0

NgAspect 1.0

NPM Build Status

NgAspect is a little library of decorators that unlocks aspect-oriented programming features in JavaScript.

Aspect-oriented programming suggests separating cross-cutting concerns (logging, caching, monitoring, data validation, error detection and so on) from main business logic. In brief it introduces:

  • advice - code implementing a cross-cutting concern
  • pointcut - the place in your code where an advice is applied

NgAspect provides decorators @Before and @After that bind an advice to a pointcut, e.g. @Before( Class/Constructor, "methodName" ) or @Before([ [Class/Constructor, "methodName"], [Class/Constructor, "methodName"] ]). It also exports a @Pointcut decorator that marks a method as one advices can be attached to.

Contents

Requirements

  • TypeScript, with experimentalDecorators enabled in tsconfig.json (NgAspect is built on decorators, which are still an experimental TypeScript feature)
  • An environment with Map available, native or polyfilled (e.g. via es6-shim) if you target older browsers

Installation

npm install ng-aspect --save

How does it work?

import { Before, After, Pointcut } from "ng-aspect";

class Foo {
  @Pointcut
  bar(){
    console.log( "calling bar", arguments );
  }
}

class Advice {
  @Before( Foo, "bar" )
  preLog() {
    console.log( "calling pre-log", arguments );
  }

  @After( Foo, "bar" )
  postLog() {
    console.log( "calling post-log" );
  }
}

(new Foo()).bar( 1, 2, 3 );

Output:

calling pre-log 1,2,3
calling bar 1,2,3
calling post-log

The same goes for static methods:

import { Before, After, Pointcut } from "ng-aspect";

class Foo {
  @Pointcut
  static bar(){
    console.log( "calling bar" );
  }
}

class Advice {
  @Before( Foo, "bar" )
  @After( Foo, "bar" )
  static log() {
    console.log( "log" );
  }
}

Foo.bar();

Note that advices are resolved when the pointcut method runs, not when it's declared, so the Advice class only needs to be evaluated (imported) before Foo's method is first called, not necessarily before Foo itself is declared.

API

Setting a pointcut
@Pointcut
Setting a single target
@Before( Foo, "bar" )
@After( Foo, "bar" )

or

@Before([ Foo, "bar" ])
@After([ Foo, "bar" ])
Setting multiple targets
@Before([
  [ Foo, "bar" ],
  [ Baz, "quiz" ],
])

Changelog

See CHANGELIST.md for release notes.

License

MIT

Analytics

Keywords