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

@snow-tzu/audit

v0.0.3

Published

Transparent audit tracking for object field changes in TypeScript applications

Downloads

14

Readme

@snow-tzu/audit

Transparent audit tracking for object field changes in TypeScript applications. Non-intrusive proxy-based tracking that preserves original object behavior while passively collecting audit information.

npm License: MIT build.yml

Table of Contents

Features

Field-level tracking - @AuditField() decorator for selective field monitoring
🎯 Class-level tracking - @Auditable() decorator for comprehensive audit coverage
🚫 Field exclusion - @AuditIgnore() decorator to exclude sensitive fields
🔍 Non-intrusive proxies - Preserve original object behavior and method context
🛡️ Type safety - Full TypeScript support with strong typing
📊 Change history - Retrieve all tracked changes with changes()
🔄 Reset functionality - Clear audit history without affecting object state
Robust error handling - Never disrupts business logic execution
🐛 Optional logging - Built-in debugging utilities

Installation

yarn add @snow-tzu/audit
# or
npm install @snow-tzu/audit

Quick Start

1. Field-Level Tracking

import { Audit, AuditField } from '@snow-tzu/audit';

class User {
  @AuditField()
  email: string = '';
  
  name: string = ''; // Not tracked
}

const user = new User();
const audited = Audit(user);

audited.email = '[email protected]';
audited.name = 'John Doe';

console.log(audited.changes());
// [{ field: 'email', oldValue: '', newValue: '[email protected]' }]

2. Class-Level Tracking

import { Audit, Auditable, AuditIgnore } from '@snow-tzu/audit';

@Auditable()
class Product {
  id: number = 0;
  name: string = '';
  
  @AuditIgnore()
  internalCode: string = ''; // Excluded from tracking
}

const product = new Product();
const audited = Audit(product);

audited.id = 123;
audited.name = 'Widget';
audited.internalCode = 'X123';

console.log(audited.changes());
// [
//   { field: 'id', oldValue: 0, newValue: 123 },
//   { field: 'name', oldValue: '', newValue: 'Widget' }
// ]

3. Reset Audit History

const audited = Audit(new User());
audited.email = '[email protected]';

console.log(audited.changes().length); // 1

audited.resetAudit?.();
console.log(audited.changes().length); // 0

API Reference

Main Function

Audit<T>(target: T): T & AuditHandle

Wraps an object for audit tracking while preserving all original behavior.

Parameters:

  • target - The object to wrap with audit tracking

Returns: A wrapped object that behaves identically to the original while tracking changes

Decorators

@AuditField()

Property decorator that marks individual fields for audit tracking.

class Example {
  @AuditField()
  trackedField: string = '';
}

@Auditable()

Class decorator that marks all fields in a class for audit tracking.

@Auditable()
class Example {
  field1: string = ''; // Tracked
  field2: number = 0;  // Tracked
}

@AuditIgnore()

Property decorator that excludes specific fields from tracking when used with @Auditable().

@Auditable()
class Example {
  tracked: string = '';
  
  @AuditIgnore()
  ignored: string = ''; // Not tracked
}

Interfaces

AuditHandle

interface AuditHandle {
  changes(): ChangeRecord[];
  resetAudit?(): void;
}

ChangeRecord

interface ChangeRecord {
  readonly field: string;
  readonly oldValue: unknown;
  readonly newValue: unknown;
}

Utilities

enableAuditLogging(level?: LogLevel)

Enable debug logging for audit operations.

disableAuditLogging()

Disable audit logging.

LogLevel

enum LogLevel {
  ERROR = 'ERROR',
  WARN = 'WARN',
  DEBUG = 'DEBUG'
}

Examples

👉 NestJS + TypeORM Example - Complete audit tracking with PostgreSQL

Complex Object Tracking

@Auditable()
class Order {
  id: number = 0;
  items: string[] = [];
  
  @AuditIgnore()
  internalNotes: string = '';
  
  calculateTotal(): number {
    return this.items.length * 10;
  }
}

const order = new Order();
const audited = Audit(order);

// Method calls work normally
console.log(audited.calculateTotal()); // 0

// Field changes are tracked
audited.id = 123;
audited.items = ['item1', 'item2'];
audited.internalNotes = 'secret'; // Not tracked

console.log(audited.changes());
// [
//   { field: 'id', oldValue: 0, newValue: 123 },
//   { field: 'items', oldValue: [], newValue: ['item1', 'item2'] }
// ]

Inheritance Support

@Auditable()
class BaseEntity {
  id: number = 0;
  createdAt: Date = new Date();
}

class User extends BaseEntity {
  @AuditField()
  email: string = '';
  
  name: string = ''; // Tracked via inheritance
}

const user = new User();
const audited = Audit(user);

audited.id = 1;
audited.email = '[email protected]';
audited.name = 'John';

console.log(audited.changes().length); // 3 changes tracked

Performance

@snow-tzu/audit is designed for production use with minimal overhead:

  • Fast proxy creation - Efficient object wrapping
  • 🚀 Negligible field access overhead - Transparent property access
  • 📊 Efficient change detection - Smart change tracking and collapsing
  • 🔋 Minimal memory footprint - ~0.2KB per tracked object

Benchmarks

The library includes comprehensive benchmarks to measure real-world performance impact:

Latest Results (Node.js v24.5.0, macOS ARM64)

| Metric | Unwrapped | Wrapped | Overhead | |--------|-----------|---------|----------| | Assignment Performance | 1.34M ops/sec | 0.59M ops/sec | +56.1% | | Memory Usage | ~0 KB | 0.21 KB | +0.21 KB per object |

The optimized implementation provides excellent performance with minimal memory overhead.

Why @snow-tzu/audit?

vs. Manual Change Tracking

| Feature | @snow-tzu/audit | Manual Tracking | |---------|-----------------|-----------------| | Setup complexity | ✅ Decorator-based | ❌ Boilerplate code | | Type safety | ✅ Full TypeScript | ⚠️ Manual typing | | Non-intrusive | ✅ Transparent proxies | ❌ Code modification | | Error handling | ✅ Built-in resilience | ❌ Manual implementation | | Performance | ✅ Optimized proxies | ⚠️ Varies |

vs. Object.observe() (Deprecated)

| Feature | @snow-tzu/audit | Object.observe | |---------|-----------------|----------------| | Browser support | ✅ All modern browsers | ❌ Deprecated | | Selective tracking | ✅ Decorator-based | ❌ All properties | | TypeScript support | ✅ Native | ❌ No types | | Change collapsing | ✅ Smart merging | ❌ Raw events |

Requirements

  • Node.js 16+ or modern browsers
  • TypeScript 4.5+ (for decorator support)
  • experimentalDecorators: true in tsconfig.json

Contributing

We welcome contributions!

License

MIT © Ganesan Arunachalam

Complete Examples

Check out the examples directory for fully working projects:

Each example includes:

  • 🚀 Ready-to-run setup with Docker
  • 📊 Database schema and migrations
  • 🔄 Transaction-based audit logging
  • 🎯 Real-world usage patterns
  • 📝 API examples and documentation

Support