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

@manifesto-ai/host

v2.3.1

Published

Manifesto Host - Effect execution runtime for @manifesto-ai/core

Readme

@manifesto-ai/host

v2.0.2 — Event-loop execution runtime for Manifesto with snapshot ownership and deterministic context

npm version


What is Host?

Host is the effect execution runtime of Manifesto. It orchestrates the compute-effect-apply loop using an event-loop model with Mailbox + Runner + Job architecture.

In the Manifesto architecture:

World -> HOST -> Core
            |
   Executes effects, applies patches
   Runs the mailbox-based execution model

What's New in v2.0.2

v2.0.2 New Features

  • Snapshot Ownership Alignment (HOST-SNAP-1~4)
    • Host uses Core's canonical Snapshot type
    • Host-owned state moves to data.$host
    • Snapshot field ownership invariants (INV-SNAP-1~7)

v2.0.1 New Features

  • Context Determinism (CTX-1~5)

    • HostContext frozen at job start — same now value throughout job execution
    • randomSeed derived from intentId for deterministic randomness
  • Compiler/Translator Decoupling (FDR-H024)

    • Host no longer depends on @manifesto-ai/compiler
    • Host receives only concrete Patch[] values
    • Translator processing is now App layer responsibility

v2.0.0 Breaking Changes

  • Mailbox + Runner + Job Execution Model
    • ExecutionMailbox: Single-writer queue per ExecutionKey
    • Job types: StartIntent, ContinueCompute, FulfillEffect, ApplyPatches
    • Run-to-completion semantics (job handlers MUST NOT await)
    • Single-runner invariant with lost-wakeup prevention

Installation

npm install @manifesto-ai/host @manifesto-ai/core
# or
pnpm add @manifesto-ai/host @manifesto-ai/core

Quick Example

import { ManifestoHost, createIntent, type DomainSchema } from "@manifesto-ai/host";

// 1. Define schema
const schema: DomainSchema = {
  id: "example:counter",
  version: "1.0.0",
  hash: "example-hash",
  state: {
    count: { type: "number", default: 0 },
  },
  actions: {
    increment: {
      flow: {
        kind: "patch",
        op: "set",
        path: "count",
        value: { kind: "add", left: { kind: "get", path: "count" }, right: 1 },
      },
    },
  },
};

// 2. Create host
const host = new ManifestoHost(schema, {
  initialData: { count: 0 },
});

// 3. Register effect handlers
host.registerEffect("api.fetch", async (_type, params, context) => {
  const response = await fetch(params.url);
  const data = await response.json();
  return [{ op: "set", path: params.targetPath, value: data }];
});

// 4. Dispatch intent
const intent = createIntent("increment", "intent-1");
const result = await host.dispatch(intent);

console.log(result.status);        // -> "complete"
console.log(result.snapshot.data); // -> { count: 1 }

Execution Model (v2.0)

Host uses an event-loop execution model with three key components:

1. Mailbox

Per-ExecutionKey queue that serializes all state mutations:

interface ExecutionMailbox {
  readonly key: ExecutionKey;
  enqueue(job: Job): void;
  dequeue(): Job | undefined;
  isEmpty(): boolean;
}

2. Runner

Single-runner processes the mailbox with lost-wakeup prevention:

// Only ONE runner per ExecutionKey at any time
// Runner re-checks mailbox before releasing guard
await processMailbox(ctx, runnerState);

3. Jobs

Four job types for different operations:

| Job Type | Purpose | |----------|---------| | StartIntent | Begin processing a new intent | | ContinueCompute | Resume after effect fulfillment | | FulfillEffect | Apply effect results and clear requirement | | ApplyPatches | Apply patches from direct submission |


Context Determinism (v2.0.1)

Host guarantees deterministic context per job:

// Context is frozen at job start
const frozenContext: HostContext = {
  now: Date.now(),           // Captured ONCE
  randomSeed: job.intentId,  // Deterministic from intentId
  env: {},
};

// All Core operations use the same frozen context
Core.compute(schema, snapshot, intent, frozenContext);
Core.apply(schema, snapshot, patches, frozenContext);

Benefits:

  • Same input -> same output (determinism preserved)
  • Trace replay produces identical results
  • f(snapshot) = snapshot' philosophy maintained

API Reference

Main Exports

// Host class
class ManifestoHost {
  constructor(schema: DomainSchema, options?: HostOptions);

  // Effect handlers
  registerEffect(type: string, handler: EffectHandler, options?: EffectHandlerOptions): void;
  unregisterEffect(type: string): boolean;
  hasEffect(type: string): boolean;
  getEffectTypes(): string[];

  // Dispatch
  dispatch(intent: Intent): Promise<HostResult>;

  // Snapshot access
  getSnapshot(): Snapshot | null;
  getSchema(): DomainSchema;
  reset(initialData: unknown): void;
}

// Factory function
function createHost(schema: DomainSchema, options?: HostOptions): ManifestoHost;

Types

interface HostOptions {
  maxIterations?: number;     // Default: 100
  initialData?: unknown;
  runtime?: Runtime;          // For deterministic time/scheduling
  env?: Record<string, unknown>;
  onTrace?: (event: TraceEvent) => void;
  disableAutoEffect?: boolean; // For HCTS testing
}

interface HostResult {
  status: "complete" | "pending" | "error";
  snapshot: Snapshot;
  traces: TraceGraph[];
  error?: HostError;
}

// Effect handler signature
type EffectHandler = (
  type: string,
  params: Record<string, unknown>,
  context: EffectContext
) => Promise<Patch[]>;

Execution Model Types

// Opaque execution identifier
type ExecutionKey = string;

// Runtime abstraction for determinism
interface Runtime {
  now(): number;
  randomSeed(): string;
}

// Context provider
interface HostContextProvider {
  createFrozenContext(intentId: string): HostContext;
}

Effect Handler Contract

Effect handlers MUST:

  1. Return Patch[] (never throw)
  2. Express failures as patches to error state
  3. Be pure IO adapters (no domain logic)
// ✅ CORRECT: Errors as patches
host.registerEffect("api.get", async (type, params) => {
  try {
    const response = await fetch(params.url);
    if (!response.ok) {
      return [{ op: "set", path: "error", value: `HTTP ${response.status}` }];
    }
    const data = await response.json();
    return [
      { op: "set", path: params.target, value: data },
      { op: "set", path: "error", value: null },
    ];
  } catch (e) {
    return [{ op: "set", path: "error", value: e.message }];
  }
});

// ❌ WRONG: Throwing exceptions
host.registerEffect("api.get", async (type, params) => {
  const response = await fetch(params.url);
  if (!response.ok) throw new Error("Failed"); // WRONG!
  return [];
});

Relationship with Other Packages

App -> HOST (v2.0.2) -> Core

| Relationship | Package | How | |--------------|---------|-----| | Depends on | @manifesto-ai/core | Uses compute() and apply() | | Used by | @manifesto-ai/world | World uses Host to execute |


When to Use Host Directly

Most users don't need to use Host directly.

Use Host directly when:

  • Building a custom runtime without World governance
  • Testing effect handlers in isolation
  • Building CLI tools or scripts
  • Implementing custom execution policies

For typical usage with governance, see @manifesto-ai/world.


Documentation

| Document | Purpose | |----------|---------| | GUIDE.md | Step-by-step usage guide | | MIGRATION.md | v1.x -> v2.0.x migration guide | | host-SPEC-v2.0.2.md | Complete specification | | host-FDR-v2.0.2.md | Design rationale | | VERSION-INDEX.md | Version history |


Examples

See the examples/ directory for runnable examples:


License

MIT