# macroforge_ts

TypeScript macro expansion engine - write compile-time macros in Rust

[![Crates.io](https://img.shields.io/crates/v/macroforge_ts.svg)](https://crates.io/crates/macroforge_ts)
[![Documentation](https://docs.rs/macroforge_ts/badge.svg)](https://docs.rs/macroforge_ts)

This crate provides a TypeScript macro expansion engine that brings Rust-like derive macros
to TypeScript. It is designed to be used via NAPI bindings from Node.js, enabling compile-time
code generation for TypeScript projects.

## Overview

Macroforge processes TypeScript source files containing `@derive` decorators and expands them
into concrete implementations. For example, a class decorated with `@derive(Debug, Clone)`
will have `toString()` and `clone()` methods automatically generated.

## Architecture

The crate is organized into several key components:

- **NAPI Bindings** (`NativePlugin`, `expand_sync`, `transform_sync`): Entry points for Node.js
- **Position Mapping** (`NativePositionMapper`, `NativeMapper`): Bidirectional source mapping
  for IDE integration
- **Macro Host** (`host` module): Core expansion engine with registry and dispatcher
- **Built-in Macros** (`builtin` module): Standard derive macros (Debug, Clone, Serialize, etc.)

## Performance Considerations

- Uses a 32MB thread stack to prevent stack overflow during deep SWC AST recursion
- Implements early bailout for files without `@derive` decorators
- Caches expansion results keyed by filepath and version
- Uses binary search for O(log n) position mapping lookups

## Usage from Node.js

```javascript
const { NativePlugin, expand_sync } = require('macroforge-ts');

// Create a plugin instance with caching
const plugin = new NativePlugin();

// Process a file (uses cache if version matches)
const result = plugin.process_file(filepath, code, { version: '1.0' });

// Or use the sync function directly
const result = expand_sync(code, filepath, { keep_decorators: false });
```

## Re-exports for Macro Authors

This crate re-exports several dependencies for convenience when writing custom macros:
- `ts_syn`: TypeScript syntax types for AST manipulation
- `macros`: Macro attributes and quote templates
- `swc_core`, `swc_common`, `swc_ecma_ast`: SWC compiler infrastructure

## Installation

Add this to your `Cargo.toml`:

```toml
[dependencies]
macroforge_ts = "0.1.38"
```

## Key Exports

### Structs

- **`TransformResult`** - Result of transforming TypeScript code through the macro system.
- **`MacroDiagnostic`** - A diagnostic message produced during macro expansion.
- **`MappingSegmentResult`** - A segment mapping a range in the original source to a range in the expanded source.
- **`GeneratedRegionResult`** - A region in the expanded source that was generated by a macro.
- **`SourceMappingResult`** - Complete source mapping information for a macro expansion.
- **`ExpandResult`** - Result of expanding macros in TypeScript source code.
- **`ImportSourceResult`** - Information about an imported identifier from a TypeScript module.
- **`SyntaxCheckResult`** - Result of checking TypeScript syntax validity.
- **`SpanResult`** - A span (range) in source code, represented as start position and length.
- **`JsDiagnostic`** - A diagnostic from the TypeScript/JavaScript compiler or IDE.
- ... and 8 more

### Functions

- **`unchanged`** - Creates a no-op result with the original code unchanged.
- **`new`** - Creates a new position mapper from source mapping data.
- **`is_empty`** - Checks if this mapper has no mapping data.
- **`original_to_expanded`** - Converts a position in the original source to the corresponding position in expanded source.
- **`expanded_to_original`** - Converts a position in the expanded source back to the original source position.
- **`generated_by`** - Returns the name of the macro that generated code at the given position.
- **`map_span_to_original`** - Maps a span (start + length) from expanded source to original source.
- **`map_span_to_expanded`** - Maps a span (start + length) from original source to expanded source.
- **`is_in_generated`** - Checks if a position is inside macro-generated code.
- **`new`** - Creates a new mapper wrapping the given source mapping.
- ... and 23 more

## API Reference

See the [full API documentation](https://macroforge.dev/docs/api/reference/rust/macroforge_ts) on the Macroforge website.

## License

MIT
