# directive-to-hof

> Transform directives into a higher order function

Latest version **0.0.3** (published 2025-10-25) · MIT license · 0 weekly downloads

## Install

```sh
npm install directive-to-hof
pnpm add directive-to-hof
yarn add directive-to-hof
bun add directive-to-hof
```

## Health

**Score 35/100 (D)** — status: maintenance-mode.

Positive: has types; no vulnerabilities; high quality score.

Warnings: low downloads; no esm support; pre 1.0.

Negative: stale; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.0.3 |
| Published | 2025-10-25 |
| First published | 2025-04-18 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 7 |
| Unpacked size | 35.2 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 1 |
| Author | Twilight <hello@twlite.dev> |
| Maintainers | snowflake7 |
| Keywords | hof, directive, compile-time, plugin |

## Links

- npm: https://www.npmjs.com/package/directive-to-hof
- Repository: https://github.com/neplextech/directive-to-hof
- Homepage: https://github.com/neplextech/directive-to-hof#readme
- Issues: https://github.com/neplextech/directive-to-hof/issues
- npm.io page: https://npm.io/package/directive-to-hof

## Dependencies (7)

- [@babel/core](https://npm.io/package/@babel/core.md) ^7.26.0
- [@babel/types](https://npm.io/package/@babel/types.md) ^7.26.3
- [@babel/parser](https://npm.io/package/@babel/parser.md) ^7.26.3
- [@babel/traverse](https://npm.io/package/@babel/traverse.md) ^7.26.4
- [@babel/generator](https://npm.io/package/@babel/generator.md) ^7.26.3
- [@types/babel__core](https://npm.io/package/@types/babel__core.md) ^7.20.5
- [@babel/preset-typescript](https://npm.io/package/@babel/preset-typescript.md) ^7.26.0

## Recent versions

- 0.0.3 (latest) — 2025-10-25
- 0.0.2 — 2025-04-22
- 0.0.1 — 2025-04-18

## README

[![npm version](https://img.shields.io/npm/v/directive-to-hof.svg)](https://www.npmjs.com/package/directive-to-hof)
[![Build Status](https://img.shields.io/badge/build-passing-brightgreen.svg)](https://github.com/your-username/directive-to-hof)
[![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)

# directive-to-hof

A build-time transformer that converts JavaScript/TypeScript directives into higher-order function calls. Transform your code's behavior declaratively using simple string directives.

## Overview

`directive-to-hof` enables you to use declarative directives in your functions that get transformed into higher-order function calls at build time. This approach provides compile-time optimization without runtime overhead.

## Key Features

- **Zero Runtime Overhead**: Directives are transformed at build time, not runtime
- **Multiple Directive Support**: Use multiple directives on the same function
- **Collision-Safe Imports**: Automatic import name collision resolution
- **TypeScript Support**: Full TypeScript compatibility with type safety
- **Build Tool Integration**: Works with Vite, Rollup, and esbuild
- **Flexible Configuration**: Support for async-only directives and custom import paths

## Installation

```bash
npm install directive-to-hof
```

```bash
yarn add directive-to-hof
```

```bash
pnpm add directive-to-hof
```

## Usage

### Basic Example

```javascript
// Before transformation
function expensiveCalculation(x, y) {
  'use once';
  'use memo';
  return x * y * Math.random();
}

// After transformation
import { useOnce } from './use-once-function.js';
import { useMemo } from './memo-function.js';

const expensiveCalculation = useOnce(
  useMemo((x, y) => {
    return x * y * Math.random();
  })
);
```

### Vite Plugin

```typescript
import { defineConfig } from 'vite';
import { vite } from 'directive-to-hof';

export default defineConfig({
  plugins: [
    vite({
      directive: 'use once',
      importPath: './use-once-function.js',
      importName: 'useOnce',
      asyncOnly: false,
    }),
  ],
});
```

### Rollup Plugin

```typescript
import { rollup } from 'directive-to-hof';

export default {
  plugins: [
    rollup({
      directive: 'use once',
      importPath: './use-once-function.js',
      importName: 'useOnce',
      asyncOnly: false,
    }),
  ],
};
```

### esbuild Plugin

```typescript
import { esbuild } from 'directive-to-hof';

const plugins = [
  esbuild({
    directive: 'use once',
    importPath: './use-once-function.js',
    importName: 'useOnce',
    asyncOnly: false,
  }),
];
```

## Configuration Options

### DirectiveTransformerOptions

```typescript
interface DirectiveTransformerOptions {
  /**
   * The directive string to look for in function bodies
   */
  directive: string;

  /**
   * Path to the module containing the higher-order function
   */
  importPath: string;

  /**
   * Name of the higher-order function to import
   */
  importName: string;

  /**
   * Whether the directive can only be used in async functions
   * @default true
   */
  asyncOnly?: boolean;
}
```

### Multiple Directives

You can configure multiple directives by passing an array of options:

```typescript
const transformer = createDirectiveTransformer([
  {
    directive: 'use once',
    importPath: './use-once-function.js',
    importName: 'useOnce',
    asyncOnly: false,
  },
  {
    directive: 'use memo',
    importPath: './memo-function.js',
    importName: 'useMemo',
    asyncOnly: false,
  },
  {
    directive: 'use cache',
    importPath: './cache-function.js',
    importName: 'useCache',
    asyncOnly: true,
  },
]);
```

## Programmatic API

### createDirectiveTransformer

```typescript
import { createDirectiveTransformer } from 'directive-to-hof';

const transformer = createDirectiveTransformer({
  directive: 'use once',
  importPath: './use-once-function.js',
  importName: 'useOnce',
  asyncOnly: false,
});

const code = `
let count = 0;
function increment() {
  'use once';
  return ++count;
}
`;

const { contents } = await transformer(code, { path: './example.js' });
console.log(contents);
```

## Higher-Order Function Examples

### useOnce Implementation

```javascript
// use-once-function.js
export function useOnce(fn) {
  let result;
  let called = false;

  return (...args) => {
    if (called) return result;
    called = true;
    return (result = fn(...args));
  };
}
```

### useMemo Implementation

```javascript
// memo-function.js
export function useMemo(fn) {
  const cache = new Map();

  return (...args) => {
    const key = JSON.stringify(args);
    if (cache.has(key)) {
      return cache.get(key);
    }
    const result = fn(...args);
    cache.set(key, result);
    return result;
  };
}
```

### useCache Implementation

```javascript
// cache-function.js
export function useCache(fn) {
  const cache = new Map();

  return async (...args) => {
    const key = JSON.stringify(args);
    if (cache.has(key)) {
      return cache.get(key);
    }
    const result = await fn(...args);
    cache.set(key, result);
    return result;
  };
}
```

## Advanced Usage

### Function Types Supported

- Function declarations
- Function expressions
- Arrow functions
- Object methods
- Class methods

### Multiple Directives on Same Function

```javascript
// Input
function complexFunction(x, y) {
  'use once';
  'use memo';
  return x * y * Math.random();
}

// Output
const complexFunction = useOnce(
  useMemo((x, y) => {
    return x * y * Math.random();
  })
);
```

### Import Collision Resolution

The transformer automatically handles import name collisions by generating unique aliases:

```javascript
// If 'useOnce' already exists in scope
const useOnce = 'existing variable';

// The transformer will generate a unique import alias
import { useOnce as useOnce_ABC123 } from './use-once-function.js';
```

## Contributing

Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## Changelog

See [CHANGELOG.md](CHANGELOG.md) for a list of changes and version history.

---
_Source: https://npm.io/package/directive-to-hof · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
