All Projects → mgechev → Aspect.js

mgechev / Aspect.js

Licence: mit
JavaScript library for aspect-oriented programming using modern syntax.

Programming Languages

javascript
184084 projects - #8 most used programming language
typescript
32286 projects

Projects that are alternatives of or similar to Aspect.js

bind-observable
Provides a typescript decorator which binds class properties to observable companion properties.
Stars: ✭ 15 (-96.61%)
Mutual labels:  decorators
Nestcloud
A NodeJS micro-service solution, writing by Typescript language and NestJS framework.
Stars: ✭ 290 (-34.54%)
Mutual labels:  decorators
Ratelimit
API Rate Limit Decorator
Stars: ✭ 365 (-17.61%)
Mutual labels:  decorators
vue-decorator
Custom decorators to vue-class-component that fits Vue 3
Stars: ✭ 31 (-93%)
Mutual labels:  decorators
Decorator
Function decorators for Elixir
Stars: ✭ 278 (-37.25%)
Mutual labels:  decorators
Ngx Auto Unsubscribe
Class decorator that will automatically unsubscribe from observables
Stars: ✭ 337 (-23.93%)
Mutual labels:  decorators
elasticmock
Python Elasticsearch Mock for test purposes
Stars: ✭ 98 (-77.88%)
Mutual labels:  decorators
Typegql
Create GraphQL schema with TypeScript classes.
Stars: ✭ 415 (-6.32%)
Mutual labels:  decorators
Pebble
Multi threading and processing eye-candy.
Stars: ✭ 276 (-37.7%)
Mutual labels:  decorators
Ember Decorators
Useful decorators for Ember applications.
Stars: ✭ 360 (-18.74%)
Mutual labels:  decorators
giuseppe
A controller routing system for expressJS with TypeScript decorators and annotations
Stars: ✭ 49 (-88.94%)
Mutual labels:  decorators
Helpful Decorators
Helpful decorators for typescript projects
Stars: ✭ 263 (-40.63%)
Mutual labels:  decorators
Ng Metadata
Angular 2 decorators and utils for Angular 1.x
Stars: ✭ 356 (-19.64%)
Mutual labels:  decorators
validada
Another library for defensive data analysis.
Stars: ✭ 29 (-93.45%)
Mutual labels:  decorators
Ng2 Webstorage
Localstorage and sessionstorage manager - Angular service
Stars: ✭ 395 (-10.84%)
Mutual labels:  decorators
state inspector
State change & method call logger. A debugging tool for instance variables and method calls.
Stars: ✭ 24 (-94.58%)
Mutual labels:  decorators
Warthog
GraphQL API Framework with strong conventions and auto-generated schema
Stars: ✭ 316 (-28.67%)
Mutual labels:  decorators
Typescript Ioc
A Lightweight annotation-based dependency injection container for typescript.
Stars: ✭ 427 (-3.61%)
Mutual labels:  decorators
Timeout Decorator
Timeout decorator for Python
Stars: ✭ 401 (-9.48%)
Mutual labels:  decorators
Cachier
Persistent, stale-free, local and cross-machine caching for Python functions.
Stars: ✭ 359 (-18.96%)
Mutual labels:  decorators

Introduction

Build Status

Library for aspect-oriented programming with JavaScript, which takes advantage of ECMAScript 2016 decorators syntax.

NOTE: if you are using aspect.js in a plain JavaScript project that uses @babel/plugin-proposal-decorators, you must set its legacy property to true until #72 is fixed. See this migration note for more information. A sample project using JavaScript with Node >=10.12.0 (or >=8.12.0) & Babel 7.x can be found at https://github.com/matthewadams/aspect.js-babel7-poc. It's a good way to get going quickly with aspect.js in that environment.

For further reading on decorators, take a look at the spec.

Blog post, introduction to the AOP and the library could be found here.

Talk from AngularConnect.

Cutting Angular's Crosscuts

Sample usage

import {beforeMethod, Advised, Metadata} from 'aspect.js';

class LoggerAspect {
  @beforeMethod({
    classNamePattern: /^Article/,
    methodNamePattern: /^(get|set)/
  })
  invokeBeforeMethod(meta: Metadata) {
    // meta.advisedMetadata == { bar: 42 }
    console.log(`Inside of the logger. Called ${meta.className}.${meta.method.name} with args: ${meta.method.args.join(', ')}.`);
  }
}

class Article {
  id: number;
  title: string;
  content: string;
}

@Advised({ bar: 42 })
class ArticleCollection {
  articles: Article[] = [];
  getArticle(id: number) {
    console.log(`Getting article with id: ${id}.`);
    return this.articles.filter(a => {
      return a.id === id;
    }).pop();
  }
  setArticle(article: Article) {
    console.log(`Setting article with id: ${article.id}.`);
    this.articles.push(article);
  }
}

new ArticleCollection().getArticle(1);

// Result:
// Inside of the logger. Called ArticleCollection.getArticle with args: 1.
// Getting article with id: 1.

In case you're using aspect.js in a browser environment the minifier may break the annotated code because of the performed mangling. In order to handle this problem you can use:

class LoggerAspect {
  @beforeMethod({
    classes: [ArticleCollection],
    methods: [ArticleCollection.prototype.getArticle, ArticleCollection.prototype.setArticle]
  })
  invokeBeforeMethod(meta: Metadata) {
    // meta.advisedMetadata == { bar: 42 }
    console.log(`Inside of the logger. Called ${meta.className}.${meta.method.name} with args: ${meta.method.args.join(', ')}.`);
  }
}

class ArticleCollection {
  getArticle(id: number) {...}
  setArticle(article: Article) {...}
}

In this case you can omit the @Advised decorator.

This way, by explicitly listing the classes and methods which should be woven, you can prevent the unwanted effect of mangling.

Demo

git clone https://github.com/mgechev/aop.js --depth 1
npm install -g ts-node
ts-node demo/index.ts

API

The library offers the following combinations of advices and join points:

Method calls

  • beforeMethod(MethodSelector) - invoked before method call
  • afterMethod(MethodSelector) - invoked after method call
  • aroundMethod(MethodSelector) - invoked around method call
  • onThrowOfMethod(MethodSelector) - invoked on throw of method call
  • asyncOnThrowOfMethod(MethodSelector) - invoked on throw of async method call

Static method calls

  • beforeStaticMethod(MethodSelector) - invoked before static method call
  • afterStaticMethod(MethodSelector) - invoked after static method call
  • aroundStaticMethod(MethodSelector) - invoked around static method call
  • onThrowOfStaticMethod(MethodSelector) - invoked on throw of static method call
  • asyncOnThrowOfStaticMethod(MethodSelector) - invoked on throw of async static method call

Accessors

  • beforeSetter(PropertySelector) - invoked before setter call
  • afterSetter(PropertySelector) - invoked after setter call
  • aroundSetter(PropertySelector) - invoked around setter call
  • onThrowOfSetter(PropertySelector) - invoked on throw of setter call
  • asyncOnThrowOfSetter(PropertySelector) - invoked on throw of async setter call
  • beforeGetter(PropertySelector) - invoked before getter call
  • afterGetter(PropertySelector) - invoked after getter call
  • aroundGetter(PropertySelector) - invoked around getter call
  • onThrowOfGetter(PropertySelector) - invoked on throw of getter call
  • asyncOnThrowOfGetter(PropertySelector) - invoked on throw of async getter call

MethodSelector

export interface MethodSelector {
  classNamePattern?: RegExp;
  methodNamePattern?: RegExp;
  classes?: Function[];
  methods?: Function[];
}

PropertySelector

export interface PropertySelector {
  classNamePattern?: RegExp;
  propertyNamePattern?: RegExp;
  classes?: Function[];
  properties?: PropertyDescriptor[];
}

Metadata

export class Metadata {
  public method: MethodMetadata;
  public className: string;
  public advisedMetadata: any;
}

MethodMetadata

export class MethodMetadata {
  public proceed: boolean;
  public name: string;
  public args: any[];
  public context: any;
  public result: any;
  public exception: any;
  public invoke: (...args: any[]) => any;
}

Diagram

Here's a UML class diagram which shows the relations between the individual abstractions:

UML Diagram

Roadmap

  • [x] Tests
  • [x] Type annotations and DTS generation
  • [x] Aspect factories
    • [x] Generic aspects
  • [x] Implement the following advices:
    • [x] Before
    • [x] After
      • [x] Throwing
      • [x] Returning
    • [x] Around
  • [x] Implement the following join points:
    • [x] Method execution
    • [x] Static method execution
    • [x] Filed get
    • [x] Field set

License

MIT

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].