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 🙏

© 2025 – Pkg Stats / Ryan Hefner

hataori

v1.1.1

Published

HATAORI - TypeScript Merkle Lambda Linker SWC Plugin

Downloads

20

Readme

HATAORI - TypeScript Merkle Lambda Linker SWC Plugin

npm version GitHub License: Apache-2.0

HATAORI is a SWC plugin that implements a content-addressed function management system similar to Unison in the TypeScript/JavaScript ecosystem.

Features

  • 🚀 Content Addressing: Manage functions by hash IDs (Unison-style approach)
  • 🛡️ Capability-Based Side Effect Control: Pure functional programming with explicit capabilities
  • 🔗 Merkle Linking: Deterministic hash generation including dependencies
  • SWC Integration: High-performance TypeScript transformation
  • 🌐 Distributed Execution: Hash-based function distribution and execution

Installation

npm install hataori

Quick Start

1. SWC Configuration

Create a .swcrc file:

{
  "jsc": {
    "experimental": {
      "plugins": [
        ["hataori", {
          "enableCapabilities": true,
          "hashAlgorithm": "blake3",
          "storeBackend": "memory"
        }]
      ]
    }
  }
}

2. Example Code

// Pure function - automatically content-addressed
export const add = (a: number, b: number): number => a + b;

// Function using capabilities
type Capabilities = { clock: { now(): number } };

export const getTimestamp = (A: Capabilities) => () =>
  A.clock.now();

3. Execution

import { RuntimeExecutor } from 'hata';

// Execute function by hash address
const executor = new RuntimeExecutor(context);
const result = await executor.execute('u#abc123...', [1, 2]);

Architecture

HATAORI consists of the following process network:

Source Code → AST Parse → Function Extract → Normalize → Dependency Analysis
    ↓              ↓            ↓            ↓            ↓
   Hash Gen → CAS Store → Name Resolve → Linker → Runtime Execute

Content Addressed Store (CAS)

CAS is a hash-based storage system that operates within the SWC plugin:

  • Session-based: Independent CAS instance per compilation session
  • In-memory: Default memory storage (discarded after compilation)
  • Persistence options: File/IPFS-based persistent storage available
  • Function management: Store/retrieve function definitions by hash and resolve dependencies
// CAS operation within plugin
const cas = new MemoryCAS(); // Created per file compilation

// Store function by hash
await cas.store(functionHash, functionDefinition);

// Retrieve dependency from CAS
const dependency = await cas.retrieve(dependencyHash);

CAS Operation Flow

CAS operation within SWC plugin:

// 1. Create new CAS for each file compilation
Program(program) {
  const cas = new MemoryCAS(); // Per-session

  // 2. Store functions in CAS during processing
  const functions = extractFunctions(program);
  for (const func of functions) {
    const hash = generateHash(func);
    await cas.store(hash, func); // Store by hash
  }

  // 3. Retrieve dependencies from CAS
  const dependencies = await resolveDependencies(func.dependencies, cas);

  // 4. CAS discarded after compilation (in-memory)
}

Process Nodes

  • source_parser: Parse TypeScript to AST using SWC
  • function_extractor: Extract top-level functions/constants
  • ast_normalizer: Normalize AST (remove comments/whitespace)
  • dependency_analyzer: Analyze function dependencies
  • hash_generator: Generate Merkle hashes
  • cas_store: Store in CAS (operates within plugin)
  • name_resolver: Resolve names to hashes
  • linker: Generate manifest and link
  • capability_checker: Validate side effect control
  • runtime_executor: Function execution runtime

Capabilities System

HATAORI controls side effects through explicit "capabilities":

// Predefined capabilities
interface Clock { now(): number; sleep(ms: number): Promise<void> }
interface Random { generate(): number; seed(s: number): void }
interface Http { get(url: string): Promise<string> }
interface Console { log(...args: any[]): void }

// Usage example
export const logTime = (A: { clock: Clock; console: Console }) => () => {
  const time = A.clock.now();
  A.console.log(`Current time: ${time}`);
};

CAS Operation within SWC Plugin

Per-Compilation Session CAS

CAS operates within the SWC plugin runtime and provides independent storage for each compilation session:

// .swcrc
{
  "jsc": {
    "experimental": {
      "plugins": [
        ["hataori", {
          "storeBackend": "memory"  // Create new CAS per file
        }]
      ]
    }
  }
}

// For each .ts file compilation:
// 1. Create new CAS instance
// 2. Store functions in CAS
// 3. Resolve dependencies from CAS
// 4. Discard CAS after compilation

Cross-File CAS Sharing

Using persistence options allows CAS sharing across compilation sessions:

const plugin = hata({
  storeBackend: 'file'  // or 'ipfs'
});

// In this case, CAS is shared across multiple .ts files,
// enabling function definition reuse and dependency resolution

Development Experience

Safe Renaming

// Original function
export const oldName = (x: number) => x * 2;

// After renaming, hash remains unchanged, references auto-resolved
export const newName = (x: number) => x * 2;

Deterministic Testing

// Test with mock abilities
const testExecutor = executor.createTestContext();
const result = await testExecutor.execute(address, args);

API Reference

Main Function

import { hata } from 'hataori';

// Use as SWC plugin
const plugin = hata({
  enableCapabilities: true,
  hashAlgorithm: 'blake3',
  storeBackend: 'memory'  // 'memory' | 'file' | 'ipfs'
});

// CAS Backend Options:
// - 'memory': Temporary storage per compilation session (default)
// - 'file': File system-based persistent storage
// - 'ipfs': Distributed storage (IPFS)

CAS Jsonnet Export

CAS content can be exported as programmable Jsonnet format:

// Export CAS content as Jsonnet
const jsonnetOutput = await cas.exportToJsonnet({
  includeMetadata: true,
  includeComments: true,
  compactAST: true,
  version: '1.0.0',
});

// Save as Jsonnet file
fs.writeFileSync('cas-export.jsonnet', jsonnetOutput);

Jsonnet Utility Functions

Generated Jsonnet files include the following utility functions:

// Search by function name
local cas = import "cas-export.jsonnet";
local addFunc = cas.getFunctionByName("add");

// Get all function names
local allNames = cas.getAllFunctionNames();  // ["add", "multiply", ...]

// Get exported functions only
local exports = cas.getExportedFunctions();

// Get dependency graph
local deps = cas.getDependencyGraph();  // { "add": [], "compute": ["add", "multiply"] }

Export Options

await cas.exportToJsonnet({
  includeMetadata: true,     // Include version and timestamp
  includeComments: true,     // Include comments
  compactAST: true,          // Compact AST for size reduction
  version: '1.0.0',          // Version information
  filterFunctions: (func) => func.isExported  // Specific functions only
});

Usage Examples

# Export CAS content as Jsonnet
npm run generate-examples

# Manipulate generated Jsonnet files
jsonnet -e 'local cas = import "examples/cas-compact-export.jsonnet"; cas.getFunctionByName("add")'

# Display dependency graph
jsonnet -e 'local cas = import "examples/cas-compact-export.jsonnet"; cas.getDependencyGraph()'

Runtime Execution

import { RuntimeExecutor } from 'hata';

const executor = new RuntimeExecutor(context);

// Execute function
const result = await executor.execute('u#hash...', args);

// Create test context
const testExecutor = executor.createTestContext();

Roadmap

  • [x] Core architecture and process network
  • [x] SWC plugin implementation
  • [x] AST processing and function extraction
  • [x] Merkle hash generation
  • [x] Linking and manifest generation
  • [x] Capabilities system
  • [x] Runtime execution engine
  • [ ] IPFS backend integration
  • [ ] VS Code extension
  • [ ] Distributed execution runtime
  • [ ] Performance optimizations

Contributing

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

License

Distributed under the Apache License, Version 2.0. See LICENSE for more information.

Related Projects


CAS Design Principles

Importance of SWC Plugin Operation

CAS functions as part of the compilation process with the following characteristics:

  1. Session Isolation: Independent CAS instance per compilation session
  2. Memory Efficiency: In-memory operation by default (auto-discarded after compilation)
  3. Extensibility: File/IPFS-based persistent storage options
  4. Function-Centric: Hash-based function management and dependency resolution
// CAS Lifecycle
Program(program) {
  // 1. Create CAS when plugin execution starts
  const cas = new CAS();

  // 2. Use CAS during compilation
  processFunctions(program, cas);

  // 3. Discard CAS when plugin execution ends
  // (auto-discarded for in-memory, saved for persistent)
}

HATAORI - Functions by hash, purity by capabilities, distribution by network.