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

@graperank/tsm-graperank-library

v1.0.11

Published

GrapeRank TSM (Trust Service Machines) - a highly configurable TSM service for ranking Nostr users and content.

Readme

TSM GrapeRank:

Next-Generation Webs of Trust for Nostr

⚠️ This library supersedes and deprecates @Pretty-Good-Freedom-Tech/graperank-nodejs
If you're using the original GrapeRank library, please migrate to this TSM-compatible version for improved modularity, standardization, and interoperability.

TSM GrapeRank allows anyone to set up a sovereignty-respecting recommendation and discovery service for Nostr, powered by Trust Machines and grapes. This rewritten library implements the GrapeRank TSM NIP to allow for full user control and interoperability of algorithm configurations across service providers.

What's New in TSM GrapeRank

This library is a complete rewrite that adds:

  • 📋 Compliance with TSM Specification: Standardized service announcements (kind 37570), service requests (kind 37572), and ranking outputs (kind 37573)
  • 🔌 Full Interoperability: Works seamlessly with any TSM-compatible client or service
  • 🧩 Enhanced Modularity: Clean separation between TSM protocol layer, GrapeRank engine, and interpreter implementations
  • ✅ Comprehensive Testing: Full test coverage with unit, integration, and execution tests
  • 📦 Better TypeScript Support: Fully typed with improved DX and IDE support
  • 🎯 NIP Standardization: Native support for TSM-specific NIPs with extensible config system

What is TSM (Trust Service Machines)?

TSM is a specification for building interoperable trust and ranking services on Nostr. It standardizes:

  • Service Announcements (kind 37570): Declare available ranking services and their capabilities
  • Service Requests (kind 37572): Submit ranking requests with configurable parameters
  • Service Output (kind 37573): Deliver paginated ranking results with metadata
  • Feedback Events (kind 7000): Provide real-time status updates during calculation

This allows any TSM-compatible service to work with any TSM-compatible client, creating a decentralized ecosystem of trust services.

Why Webs of Trust?

Sovereignty is respected when users have the freedom to choose... and a variety of useful choices.

On Nostr, there's no central trust authority. Weeding out bots and bad actors while providing useful recommendations requires a decentralized approach. Webs of Trust solve this by defining "trustworthiness" relative to each end user, based on their own content and interactions.

GrapeRank respects sovereignty by:

  • ✅ Allowing users to choose their own recommendation service
  • ✅ Supporting multiple interpreters and contexts
  • ✅ Providing transparent, configurable calculations
  • ✅ Avoiding centralized "popularity contests"

Architecture

Core Components

🔍 Interpreters (src/nostr-interpreters/)

Pluggable modules that ingest and normalize ANY content to standardized interaction ratings (0-1 scale):

  • nostr-3: Follow lists (kind 3) - each follow = 1.0 trust
  • nostr-10000: Mute lists (kind 10000) - each mute = 0.0 trust
  • nostr-1984: Report events (kind 1984) - weighted by report type
  • nostr-1-t: Hashtag mentions in notes
  • nostr-9735: Zap receipts weighted by amount

Extensible: Add custom interpreters for any protocol or network!

⚙️ Calculator (src/graperank/calculation.ts)

The heart of GrapeRank - iteratively processes interactions to determine influence scores:

  • Weighted Average Algorithm: Fixed ceiling prevents influencer dominance
  • Configurable Parameters: attenuation, rigor, minimum, precision
  • Degree of Separation Tracking: Multi-iteration network expansion
  • Regular Users Shine: Avoids pure popularity contests

🎯 TSM Layer (src/tsm/)

Handles TSM protocol compliance:

  • Announcements (announcements.ts): Generate service announcement events
  • Requests (requests.ts): Parse and validate service request events
  • Output (output.ts): Generate ranking and feedback events with pagination

Installation

npm install @graperank/tsm-graperank-library

Usage

Basic Ranking Service

import { parseServiceRequest, executeServiceRequest } from 'graperank-tsm/tsm/output'
import { InterpreterFactory } from 'graperank-tsm/nostr-interpreters/factory'

// Parse incoming TSM request event (kind 37572)
const request = parseServiceRequest(requestEvent)

// Execute ranking with callbacks
await executeServiceRequest(request, requestEvent, {
  interpreterFactory: InterpreterFactory,
  
  // Receive feedback events during processing
  onFeedbackEvent: async (feedbackEvent) => {
    await publishEvent(feedbackEvent) // kind 7000
  },
  
  // Receive final ranking output
  onOutputEvent: async (rankingEvent) => {
    await publishEvent(rankingEvent) // kind 37573
  }
})

Generate Service Announcement

import { generateServiceAnnouncement } from 'graperank-tsm/tsm/announcements'
import { InterpreterFactory } from 'graperank-tsm/nostr-interpreters/factory'

const announcement = generateServiceAnnouncement({
  identifier: 'my-graperank-service',
  title: 'My GrapeRank Service',
  summary: 'Web of Trust rankings for Nostr',
  relays: ['wss://relay.example.com']
}, InterpreterFactory)

// Publish announcement (kind 37570)
await publishEvent(announcement)

Custom Configuration

Request events can specify custom parameters:

{
  "kind": 37572,
  "tags": [
    ["config", "type", "p"],
    ["config", "pov", "[\"npub1...\", \"npub2...\"]"],
    ["config", "interpreters", "[{\"id\":\"nostr-3\",\"iterate\":3}]"],
    ["config", "attenuation", "0.5"],
    ["config", "rigor", "0.5"],
    ["config", "minimum", "0.0"]
  ]
}

Project Structure

src/
├── tsm/                    # TSM protocol implementation
│   ├── announcements.ts    # Generate service announcements (kind 37570)
│   ├── requests.ts         # Parse service requests (kind 37572)
│   ├── output.ts           # Generate rankings & feedback (kind 37573, 7000)
│   └── types.ts            # TSM-specific types
├── graperank/              # Core GrapeRank engine
│   ├── interpretation.ts   # Orchestrates interpreters
│   ├── calculation.ts      # Weighted average algorithm
│   └── types.ts            # Core algorithm types
├── nostr-interpreters/     # Nostr-specific interpreters
│   ├── factory.ts          # Interpreter registry
│   ├── classes.ts          # Base interpreter class
│   ├── callbacks.ts        # Interpretation helpers
│   └── helpers.ts          # Event fetching & validation
└── __tests__/              # Comprehensive test suite
    ├── requests.test.ts
    ├── output.test.ts
    ├── integration.test.ts
    └── graperank-execution.test.ts

Testing

# Run all tests
npm test

# Run with coverage
npm run test:coverage

# Watch mode for development
npm run test:watch

Test Coverage: 36 tests across unit, integration, and full execution scenarios

Configuration Reference

Calculator Parameters

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | attenuation | number | 0.5 | How quickly influence decays with distance | | rigor | number | 0.5 | How strictly confidence affects final scores | | minimum | number | 0.0 | Minimum score threshold for results | | precision | number | 0.00001 | Convergence precision for iterative calculation |

Interpreter Requests

| Parameter | Type | Description | |-----------|------|-------------| | id | string | Interpreter ID (e.g., "nostr-3") | | iterate | number | Degrees of separation to traverse | | params | object | Custom interpreter parameters |

Migration from Original GrapeRank

If you're migrating from @graperank/graperank:

Key Differences

  1. TSM Compliance: Events now follow TSM specification (kinds 37570, 37572, 37573)
  2. Modular Structure: Cleaner separation of concerns
  3. Type Safety: Full TypeScript support with no implicit any
  4. Testing: Comprehensive test coverage included
  5. API Changes: New event-based API instead of class-based engine

Breaking Changes

  • GrapeRank.init() → ✅ Use executeServiceRequest()
  • .generate(), .scorecards() → ✅ TSM event-based workflow
  • ❌ S3 storage coupling → ✅ Storage is external to core library
  • ❌ Custom cache → ✅ Use relay caching or external solutions

Contributing

Contributions welcome! Please ensure:

  • ✅ All tests pass (npm test)
  • ✅ Code follows existing patterns
  • ✅ New features include tests

Credits

GrapeRank TSM Developed by: [email protected]
Algorithm Designed by: [email protected]

License

MIT


Related Projects: