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

@onlyworlds/sdk

v2.2.1

Published

TypeScript SDK for the OnlyWorlds API - build world-building applications with type safety

Readme

OnlyWorlds TypeScript SDK

npm version License: MIT

A type-safe TypeScript SDK for building world-building applications with the OnlyWorlds API.

Installation

npm install @onlyworlds/sdk

Quick Start

import { OnlyWorldsClient } from '@onlyworlds/sdk';

const client = new OnlyWorldsClient({
  apiKey: 'your-api-key',
  apiPin: '1234',
  baseUrl: 'https://onlyworlds.com'
});

// Get your world (API keys are world-scoped)
const world = await client.worlds.get();

// Fetch characters (paginated)
const characters = await client.characters.list();

// Create a new location
const location = await client.locations.create({
  name: 'Dragon Peak',
  description: 'A treacherous mountain peak where dragons nest',
  supertype: 'mountain'
});

// Get a specific element
const character = await client.characters.get('element-id');

// Update an element
await client.characters.update('element-id', {
  name: 'Updated Name'
});

// Delete an element
await client.characters.delete('element-id');

Features

  • Full Type Safety - Complete TypeScript definitions for all 22 OnlyWorlds element types
  • Auto-Generated Types - Types synchronized with the latest OnlyWorlds schema
  • CRUD Operations - Create, read, update, and delete operations for all elements
  • Token Management - Built-in support for OnlyWorlds token rating system
  • Branded Types - Compile-time safety for element relationships
  • Zero Runtime Overhead - Type system has no runtime cost
  • Modern ESM/CJS - Supports both ES modules and CommonJS

API Reference

World Endpoint

The worlds resource is special because API keys are world-scoped (one key = one world). The endpoint returns a single World object directly, not a paginated list.

// Get your world
const world = await client.worlds.get();

// Update your world
const updated = await client.worlds.update({
  description: 'A dark fantasy realm'
});

Note: The worlds resource only has get() and update() methods (no list(), create(), or delete()) because API keys are world-scoped.

Element Endpoints

All other element types return paginated results:

// List with pagination
const response = await client.characters.list({
  limit: 10,
  offset: 0,
  ordering: '-created_at',
  search: 'dragon'
});

console.log(response.count);      // Total count
console.log(response.results);    // Array of Characters
console.log(response.next);       // URL for next page
console.log(response.previous);   // URL for previous page

Type-Safe Relationships

import { ElementId, Character, Location } from '@onlyworlds/sdk';

// Branded types ensure you can't mix up element IDs
const locationId: ElementId<'Location'> = 'some-location-id';
const character: Character = {
  name: 'Aragorn',
  location: locationId  // Type-safe!
};

Token Management

OnlyWorlds provides a token rating system for tracking API usage and enabling AI-powered features. Users get a daily token allowance (default: 10,000 tokens) that resets every day.

Working Reference Implementation

See base-tool/src/llm/token-service.ts for the complete working implementation that this SDK enables.

Check Token Status

// Get current token status
const status = await client.tokens.getStatus();

console.log(`Available: ${status.tokens_available_today}/${status.token_rating}`);
console.log(`Used today: ${status.tokens_used_today}`);
console.log(`Active sessions: ${status.sessions_active}`);
console.log(`Last reset: ${status.last_reset}`);

Consume Tokens

Report token consumption when your tool uses AI features or other token-tracked services:

// Report token usage
const result = await client.tokens.consume({
  amount: 500,
  service: 'my_worldbuilding_tool',
  metadata: {
    feature: 'character_generation',
    model: 'gpt-4',
    prompt_tokens: 300,
    completion_tokens: 200
  }
});

// Check if consumption succeeded
if (result.error) {
  console.warn('Token warning:', result.error);
}

console.log(`Consumed ${result.tokens_consumed} tokens`);
console.log(`${result.tokens_remaining} tokens remaining`);

Important: The API allows consumption even when exceeding available tokens (tracks as debt), but returns a warning in the error field.

Advanced: Encrypted API Key Access

For tools that need direct OpenAI API access using OnlyWorlds tokens:

// Get encrypted OpenAI key (requires 100+ tokens)
const access = await client.tokens.getAccessKey();

console.log('Session ID:', access.session_id);
console.log('Expires:', access.expires_at);
console.log('Available tokens:', access.tokens_available);

// Decrypt the key client-side (see base-tool for full implementation)
// 1. Derive decryption key from world ID using SHA-256
// 2. Use 'fernet' npm package to decrypt
// 3. Use decrypted OpenAI key for direct API calls
// 4. Report usage with session_id

// See base-tool/src/llm/token-service.ts:99-235 for complete example

Full decryption implementation (based on base-tool):

import { fernet } from 'fernet';

// Derive decryption key from world ID
async function deriveKey(worldId: string): Promise<string> {
  const salt = 'onlyworlds-token-api-2024-public-salt';
  const keyMaterial = `${worldId}:${salt}`;
  const encoder = new TextEncoder();
  const data = encoder.encode(keyMaterial);
  const hashBuffer = await crypto.subtle.digest('SHA-256', data);
  const hashArray = Array.from(new Uint8Array(hashBuffer));
  const base64 = btoa(String.fromCharCode(...hashArray));
  return base64.replace(/\+/g, '-').replace(/\//g, '_');
}

// Decrypt the API key
async function decryptApiKey(encryptedKey: string, worldId: string): Promise<string> {
  const derivedKey = await deriveKey(worldId);
  const secret = new fernet.Secret(derivedKey);
  const token = new fernet.Token({
    secret: secret,
    token: encryptedKey,
    ttl: 0  // Don't enforce TTL client-side
  });
  return token.decode();
}

// Usage
const world = await client.worlds.get();
const access = await client.tokens.getAccessKey();
const apiKey = await decryptApiKey(access.encrypted_key, world.id);

// Use apiKey for OpenAI API calls, then report usage:
await client.tokens.consume({
  amount: tokensUsed,
  sessionId: access.session_id,
  service: 'direct_openai',
  metadata: { model: 'gpt-4', /* ... */ }
});

Session Management

// Revoke a specific session
await client.tokens.revokeSession(sessionId);

// Revoke all sessions (emergency cleanup)
const result = await client.tokens.revokeAllSessions();
console.log(`Revoked ${result.sessions_revoked} sessions`);

Encryption Info

Get public encryption details (no auth required):

const info = await client.tokens.getEncryptionInfo();
console.log('Algorithm:', info.algorithm);
console.log('Key derivation:', info.key_derivation);
console.log('Public salt:', info.salt);
console.log(info.javascript_example);

License

MIT License - see LICENSE file for details

Links