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

@memberjunction/doc-utils

v5.15.0

Published

This library provides functionality for dynamically retreiving documentation from the official MemberJunction object model documentation site, parsing it, and caching elements in memory for performance. Use this whenever you need dynamic access to the MJ

Downloads

5,120

Readme

@memberjunction/doc-utils

A TypeScript library for dynamically retrieving, parsing, and caching MemberJunction library documentation from the official documentation website. Designed to support AI models, code generation tools, and other documentation-driven features that need structured access to MJ library metadata.

Overview

The @memberjunction/doc-utils package provides a singleton DocumentationEngine that loads library and library item metadata from the MemberJunction entity system, then fetches the corresponding HTML documentation pages from the official MJ documentation site (https://memberjunction.github.io/MJ/). Parsed content is cached in memory for efficient repeated access.

This package is particularly useful for:

  • Feeding structured library documentation to AI models for context-aware code generation
  • Building developer tools that reference MJ API documentation
  • Providing searchable documentation indexes for MJ packages and their exported items

Architecture

graph TB
    subgraph DocUtils["DocUtils Package"]
        DE["DocumentationEngine<br/>(Singleton)"]
        LEE["MJLibraryEntityExtended"]
        LIEE["MJLibraryItemEntityExtended"]
    end

    subgraph MJCore["@memberjunction/core"]
        BE["BaseEngine"]
        BEnt["BaseEntity"]
    end

    subgraph CoreEntities["@memberjunction/core-entities"]
        LE["LibraryEntity"]
        LIE["LibraryItemEntity"]
    end

    subgraph External["External Services"]
        DB[("MJ Database<br/>Libraries &<br/>Library Items")]
        DOCS["MJ Docs Site<br/>memberjunction.github.io"]
    end

    DE -->|extends| BE
    LEE -->|extends| LE
    LIEE -->|extends| LIE
    LE -->|extends| BEnt
    LIE -->|extends| BEnt

    DE -->|loads metadata| DB
    DE -->|fetches HTML| DOCS
    DE -->|manages| LEE
    DE -->|manages| LIEE
    LEE -->|contains| LIEE

    style DE fill:#2d6a9f,stroke:#1a4971,color:#fff
    style LEE fill:#2d8659,stroke:#1a5c3a,color:#fff
    style LIEE fill:#2d8659,stroke:#1a5c3a,color:#fff
    style BE fill:#7c5295,stroke:#563a6b,color:#fff
    style BEnt fill:#7c5295,stroke:#563a6b,color:#fff
    style LE fill:#7c5295,stroke:#563a6b,color:#fff
    style LIE fill:#7c5295,stroke:#563a6b,color:#fff
    style DB fill:#b8762f,stroke:#8a5722,color:#fff
    style DOCS fill:#b8762f,stroke:#8a5722,color:#fff

Data Flow

The engine follows a two-phase loading process: first it loads entity metadata from the database, then it fetches and parses HTML documentation for each library item.

sequenceDiagram
    participant App as Application
    participant DE as DocumentationEngine
    participant DB as MJ Database
    participant Site as Docs Website

    App->>DE: Config(forceRefresh, contextUser)
    DE->>DB: Load Libraries (entity metadata)
    DB-->>DE: MJLibraryEntityExtended[]
    DE->>DB: Load Library Items (entity metadata)
    DB-->>DE: MJLibraryItemEntityExtended[]

    Note over DE: AdditionalLoading phase

    loop For each Library
        loop For each Item in Library
            DE->>DE: Build URL from library name + item type
            DE->>Site: GET /{type}/{sanitized_name}.{ItemName}.html
            Site-->>DE: HTML response
            DE->>DE: Parse HTML via JSDOM (extract div.col-content)
            DE->>DE: Cache HTMLContent and URL on item
        end
    end

    DE-->>App: Config complete, data cached
    App->>DE: Access Libraries / LibraryItems
    DE-->>App: Cached entity data with HTML content

Class Hierarchy

classDiagram
    class BaseEngine {
        <<abstract>>
        +Load(configs, provider, forceRefresh, contextUser)
        #AdditionalLoading(contextUser)*
    }

    class DocumentationEngine {
        +Instance$ DocumentationEngine
        +Libraries MJLibraryEntityExtended[]
        +LibraryItems MJLibraryItemEntityExtended[]
        +Config(forceRefresh, contextUser, provider)
        #AdditionalLoading(contextUser)
        #GetContent(url, rootSelector) string
        #fetchDocumentation(url) string
        #parseDocumentation(html, rootSelector) string
    }

    class BaseEntity {
        <<abstract>>
        +Get(fieldName)
        +Set(fieldName, value)
        +Save()
    }

    class LibraryEntity {
        +ID string
        +Name string
        +Description string?
        +Status "Active" | "Disabled" | "Pending"
        +TypeDefinitions string?
        +SampleCode string?
    }

    class MJLibraryEntityExtended {
        +Items MJLibraryItemEntityExtended[]
    }

    class LibraryItemEntity {
        +ID string
        +Name string
        +LibraryID string
        +Type "Class"|"Function"|"Interface"|"Module"|"Type"|"Variable"
        +Library string
    }

    class MJLibraryItemEntityExtended {
        +URL string
        +HTMLContent string
        +TypeURLSegment string
    }

    BaseEngine <|-- DocumentationEngine
    BaseEntity <|-- LibraryEntity
    BaseEntity <|-- LibraryItemEntity
    LibraryEntity <|-- MJLibraryEntityExtended
    LibraryItemEntity <|-- MJLibraryItemEntityExtended
    DocumentationEngine o-- MJLibraryEntityExtended
    DocumentationEngine o-- MJLibraryItemEntityExtended
    MJLibraryEntityExtended o-- MJLibraryItemEntityExtended

    style DocumentationEngine fill:#2d6a9f,stroke:#1a4971,color:#fff
    style MJLibraryEntityExtended fill:#2d8659,stroke:#1a5c3a,color:#fff
    style MJLibraryItemEntityExtended fill:#2d8659,stroke:#1a5c3a,color:#fff
    style BaseEngine fill:#7c5295,stroke:#563a6b,color:#fff
    style BaseEntity fill:#7c5295,stroke:#563a6b,color:#fff
    style LibraryEntity fill:#7c5295,stroke:#563a6b,color:#fff
    style LibraryItemEntity fill:#7c5295,stroke:#563a6b,color:#fff

Installation

npm install @memberjunction/doc-utils

Dependencies

MemberJunction packages:

| Package | Purpose | |---------|---------| | @memberjunction/core | Base engine class, metadata provider, user context | | @memberjunction/core-entities | LibraryEntity and LibraryItemEntity base classes | | @memberjunction/global | @RegisterClass decorator for entity registration |

External packages:

| Package | Purpose | |---------|---------| | axios | HTTP requests to the documentation website | | jsdom | HTML parsing and DOM manipulation for content extraction |

Usage

Initializing the Engine

The DocumentationEngine uses the singleton pattern. Call Config() once to load metadata and documentation content before accessing data.

import { DocumentationEngine } from '@memberjunction/doc-utils';
import { UserInfo } from '@memberjunction/core';

// Get the singleton instance
const docEngine = DocumentationEngine.Instance;

// Server-side: pass contextUser for proper data isolation
const contextUser: UserInfo = /* from your authentication context */;
await docEngine.Config(false, contextUser);

// Client-side: contextUser is optional
await docEngine.Config();

Accessing Libraries and Items

After configuration, libraries and their items are available through cached properties.

const docEngine = DocumentationEngine.Instance;

// Get all libraries
const libraries = docEngine.Libraries;
console.log(`Loaded ${libraries.length} libraries`);

// Find a specific library
const coreLib = libraries.find(lib => lib.Name === '@memberjunction/core');
if (coreLib) {
    console.log(`${coreLib.Name} (${coreLib.Status})`);
    console.log(`Items: ${coreLib.Items.length}`);

    // Iterate through items in the library
    for (const item of coreLib.Items) {
        console.log(`  ${item.Type}: ${item.Name}`);
        console.log(`  URL: ${item.URL}`);
        console.log(`  Content length: ${item.HTMLContent.length} chars`);
    }
}

Accessing All Library Items

The flat LibraryItems array provides access to all items across all libraries.

const docEngine = DocumentationEngine.Instance;

// Get all library items regardless of library
const allItems = docEngine.LibraryItems;

// Filter by type
const allClasses = allItems.filter(item => item.Type === 'Class');
const allInterfaces = allItems.filter(item => item.Type === 'Interface');

// Find a specific item by name and library
const baseEntity = allItems.find(
    item => item.Name === 'BaseEntity' && item.Library === '@memberjunction/core'
);

if (baseEntity) {
    console.log(`Documentation URL: ${baseEntity.URL}`);
    console.log(`HTML Content: ${baseEntity.HTMLContent}`);
}

Force Refreshing Documentation

Pass true to Config() to reload all metadata from the database and re-fetch documentation content.

const docEngine = DocumentationEngine.Instance;

// Force a complete reload
await docEngine.Config(true);

API Reference

DocumentationEngine

The primary class providing access to MJ library documentation. Extends BaseEngine and uses the singleton pattern.

| Member | Type | Description | |--------|------|-------------| | Instance (static) | DocumentationEngine | Returns the singleton instance | | Libraries | MJLibraryEntityExtended[] | All loaded libraries with their items | | LibraryItems | MJLibraryItemEntityExtended[] | Flat list of all library items across all libraries | | Config(forceRefresh?, contextUser?, provider?) | Promise<void> | Initializes the engine: loads metadata, fetches and parses documentation |

MJLibraryEntityExtended

Extended entity class for libraries. Registered via @RegisterClass(BaseEntity, "Libraries").

| Member | Type | Description | |--------|------|-------------| | ID | string | Unique identifier | | Name | string | Library package name (e.g., @memberjunction/core) | | Description | string \| null | Human-readable description | | Status | 'Active' \| 'Disabled' \| 'Pending' | Library availability status | | TypeDefinitions | string \| null | Type/function definitions for reference by humans and AI | | SampleCode | string \| null | Usage examples for the library | | Items | MJLibraryItemEntityExtended[] | All items belonging to this library |

MJLibraryItemEntityExtended

Extended entity class for individual library items (classes, interfaces, functions, etc.). Registered via @RegisterClass(BaseEntity, "Library Items").

| Member | Type | Description | |--------|------|-------------| | ID | string | Unique identifier | | Name | string | Item name (e.g., BaseEntity, RunView) | | LibraryID | string | Foreign key to the parent library | | Library | string | Denormalized library name from the view | | Type | 'Class' \| 'Function' \| 'Interface' \| 'Module' \| 'Type' \| 'Variable' | The kind of exported item | | URL | string | Generated documentation URL for this item | | HTMLContent | string | Parsed HTML content from the documentation page | | TypeURLSegment | string (getter) | URL path segment derived from Type (e.g., classes, interfaces) |

URL Generation

Documentation URLs are constructed automatically using the pattern:

https://memberjunction.github.io/MJ/{typeSegment}/{sanitizedLibraryName}.{ItemName}.html

Where:

  • {typeSegment} is the pluralized, lowercase item type (classes, interfaces, functions, modules, types, variables)
  • {sanitizedLibraryName} is the library name with @, ., /, and \ characters replaced by _
  • {ItemName} is the exact name of the exported item

For example, BaseEntity (a Class) in @memberjunction/core resolves to:

https://memberjunction.github.io/MJ/classes/_memberjunction_core.BaseEntity.html

URL Routing by Item Type

graph LR
    Item["Library Item"]

    Item -->|Class| C["/classes/"]
    Item -->|Interface| I["/interfaces/"]
    Item -->|Function| F["/functions/"]
    Item -->|Module| M["/modules/"]
    Item -->|Type| T["/types/"]
    Item -->|Variable| V["/variables/"]

    style Item fill:#2d6a9f,stroke:#1a4971,color:#fff
    style C fill:#2d8659,stroke:#1a5c3a,color:#fff
    style I fill:#2d8659,stroke:#1a5c3a,color:#fff
    style F fill:#2d8659,stroke:#1a5c3a,color:#fff
    style M fill:#b8762f,stroke:#8a5722,color:#fff
    style T fill:#b8762f,stroke:#8a5722,color:#fff
    style V fill:#b8762f,stroke:#8a5722,color:#fff

Integration with MemberJunction

This package integrates with the broader MemberJunction ecosystem through several mechanisms:

  • Entity System: Uses @RegisterClass to register MJLibraryEntityExtended and MJLibraryItemEntityExtended as entity subclasses, ensuring the MJ class factory returns the extended types when loading Libraries and Library Items.
  • BaseEngine Pattern: Extends BaseEngine with the Config() / AdditionalLoading() lifecycle, allowing consistent initialization and caching across all MJ engine classes.
  • User Context: Supports contextUser for proper data isolation and security when running on the server side.
  • Metadata Provider: Accepts an optional IMetadataProvider for environments with custom metadata access patterns.

Build

# Build the package
cd packages/DocUtils
npm run build

# Development mode with file watching
npm start

Source Files

| File | Description | |------|-------------| | src/index.ts | Public API surface -- re-exports from Engine.ts | | src/Engine.ts | Core implementation: DocumentationEngine, MJLibraryEntityExtended, MJLibraryItemEntityExtended |

Notes

  • Documentation is fetched from https://memberjunction.github.io/MJ/ using axios HTTP GET requests.
  • HTML content is parsed with jsdom, extracting the inner HTML of the div.col-content element from each page.
  • All fetched content is cached in memory after the initial Config() call. Subsequent calls to Config() without forceRefresh=true return immediately.
  • Library names containing special characters (@, ., /, \) are sanitized by replacing them with underscores for URL compatibility.
  • If a documentation page cannot be fetched (network error, 404, etc.), the HTMLContent for that item is set to an error or placeholder string rather than throwing an exception.