npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@meshestra/nestjs-aspect

v0.0.1

Published

Aspect oriented programming module for NestJS

Downloads

15

Readme

@Meshcraft/aspect

npm License Build Status Coverage Downloads TypeScript Node.js

Powerful Aspect Oriented Programming (AOP) for JavaScript/TypeScript, inspired by Spring AOP

Features

  • ✂️ Clean Separation of Concerns - Isolate cross-cutting concerns from your business logic
  • 🔄 Method Interception - Before, After, Around, AfterReturning, AfterThrowing advice
  • 🎯 Pointcut Expressions - Target specific methods and classes with powerful expressions
  • 🧩 Composable Aspects - Create reusable aspects and combine them effortlessly
  • Performance Optimized - Minimal runtime overhead with smart caching
  • 📏 TypeScript First - Full type safety with excellent IDE support
  • 🔍 Transparent Proxies - Maintains original method signatures and stack traces

Installation

npm install @meshcraft/aspect
# OR
yarn add @meshcraft/aspect
# OR
pnpm add @meshcraft/aspect

Quick Start

import { createAspect, Around, Pointcut } from '@meshcraft/aspect';

// Create a simple logging aspect
const LoggingAspect = createAspect({
  // Define a pointcut that targets service methods
  @Pointcut('execution(*.service.*(..))')
  serviceMethod() {},

  // Apply "around" advice to all methods matching the pointcut
  @Around('serviceMethod()')
  async logMethodExecution(joinPoint) {
    const { method, args, proceed } = joinPoint;
    console.log(`Executing ${method} with arguments:`, args);

    const startTime = performance.now();
    try {
      // Proceed with the original method call
      const result = await proceed();
      console.log(`${method} returned:`, result);
      return result;
    } catch (error) {
      console.error(`${method} threw an error:`, error);
      throw error;
    } finally {
      const endTime = performance.now();
      console.log(`${method} execution time: ${endTime - startTime}ms`);
    }
  }
});

// Create a class with some business logic
class UserService {
  async findById(id: string) {
    // Database operations...
    return { id, name: 'John Doe' };
  }

  async createUser(userData: any) {
    // User creation logic...
    return { id: '123', ...userData };
  }
}

// Apply the aspect to the service
const userService = LoggingAspect.apply(new UserService());

// Use the proxied service - aspects will be applied automatically
await userService.findById('123');
// Console:
// Executing findById with arguments: ['123']
// findById returned: { id: '123', name: 'John Doe' }
// findById execution time: 5.23ms

Core Concepts

Aspects

Aspects are the core containers for cross-cutting concerns. They define pointcuts and advice that describe where and how to apply additional behavior.

Joinpoints

Joinpoints represent specific points in your application's execution where aspects can be applied. In @Meshcraft/aspect, joinpoints are typically method executions.

Pointcuts

Pointcuts are expressions that select specific joinpoints in your code. They determine which methods your aspects will target.

@Pointcut('execution(com.example.service.*.*(..))')
serviceLayer() {}

Advice

Advice defines the behavior to apply at selected joinpoints. @Meshcraft/aspect offers several types of advice:

  • @Before - Executes before the joinpoint
  • @After - Executes after the joinpoint (regardless of outcome)
  • @AfterReturning - Executes after successful completion
  • @AfterThrowing - Executes if the joinpoint throws an exception
  • @Around - Wraps the joinpoint with custom behavior

Advanced Examples

Transaction Management

const TransactionAspect = createAspect({
  @Pointcut('execution(@Transactional *.*(..))')
  transactionalMethod() {},

  @Around('transactionalMethod()')
  async manageTransaction(joinPoint) {
    const tx = await db.beginTransaction();
    try {
      const result = await joinPoint.proceed();
      await tx.commit();
      return result;
    } catch (error) {
      await tx.rollback();
      throw error;
    }
  }
});

// Usage with decorator
class OrderService {
  @Transactional()
  async createOrder(order) {
    // Order creation logic that will be automatically wrapped in a transaction
  }
}

Caching

const CachingAspect = createAspect({
  @Pointcut('execution(@Cacheable *.*(..))')
  cacheableMethod() {},

  @Around('cacheableMethod()')
  async cache(joinPoint) {
    const { target, method, args } = joinPoint;
    const cacheKey = `${target.constructor.name}.${method}(${JSON.stringify(args)})`;

    const cachedValue = await cacheManager.get(cacheKey);
    if (cachedValue) {
      return cachedValue;
    }

    const result = await joinPoint.proceed();
    await cacheManager.set(cacheKey, result);
    return result;
  }
});

Pointcut Expression Syntax

@Meshcraft/aspect provides a powerful expression language for defining pointcuts:

| Expression | Description | |------------|-------------| | execution(* *.*(..)) | All methods in all classes | | execution(com.example.service.*.*(..)) | All methods in service classes | | execution(* *.find*(..)) | All methods starting with "find" | | execution(@Transactional * *.*(..)) | Methods with @Transactional annotation | | execution(* *.*(String, ..)) | Methods with String as first parameter | | within(com.example.service.*) | All joinpoints within service package |

Performance Considerations

@Meshcraft/aspect is designed with performance in mind:

  • Pointcut expressions are parsed and optimized at load time
  • Proxies use minimal reflection to maintain performance
  • Advanced caching mechanisms reduce runtime overhead

For production environments, consider:

// Enable production mode to apply additional optimizations
import { configure } from '@meshcraft/aspect';

configure({
  production: process.env.NODE_ENV === 'production',
  cacheSize: 1000
});

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgements

  • Spring Framework - For the original AOP concepts and implementation
  • TypeScript team - For the amazing type system that makes this possible