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/action-runtime-host

v5.35.0

Published

Host-side bridge that exposes MJ services (metadata, views, queries, entity CRUD, action invocation, agent run, AI prompt execution) to sandboxed Runtime-action code via `utilities.*`. Ships a default implementation of `RuntimeActionBridgeBuilder` that `@

Readme

@memberjunction/action-runtime-host

Host-side bridge that exposes MJ services (metadata, views, queries, entity CRUD, action invocation, agent run, AI prompt execution) to sandboxed Runtime-action code via the utilities.* namespace.

Ships the default concrete implementation of RuntimeActionBridgeBuilder from @memberjunction/actions-base. @memberjunction/actions resolves it at runtime through MJGlobal.ClassFactory.CreateInstance(...).

Why this package exists (the cycle)

Building the bridge handler map requires touching:

  • ActionEngineServer (from @memberjunction/actions) — for utilities.actions.Invoke
  • AgentRunner (from @memberjunction/ai-agents) — for utilities.agents.Run
  • AIEngine (from @memberjunction/aiengine) — for agent / prompt metadata
  • AIPromptRunner (from @memberjunction/ai-prompts) — for utilities.ai.ExecutePrompt

Those last three packages already depend on @memberjunction/actions. Putting the bridge source inside @memberjunction/actions (where it used to live) created a cycle that could only be hidden with await import(...) calls and as never casts — fragile, untyped, and easy to break silently.

This package sits at the top of the Actions stack, above every package it touches, so every import can be fully static and fully type-checked.

core · global · core-entities
              │
              ├── actions-base           ← contract: RuntimeActionBridgeBuilder abstract
              ├── code-execution         ← sandbox runner
              ├── action-runtime         ← RuntimeActionExecutor
              ├── aiengine · ai-prompts · ai-core-plus
              │
              ├── actions                ← ClassFactory lookup, no AI deps
              │     │
              │     └── ai-agents
              │           │
              │           └── action-runtime-host  ← THIS PACKAGE (default bridge)

How ActionEngine uses it

// Inside @memberjunction/actions (ActionEngine.RunRuntimeAction):
const builder = MJGlobal.Instance.ClassFactory.CreateInstance<RuntimeActionBridgeBuilder>(
  RuntimeActionBridgeBuilder
);
if (builder) {
  bridgeHandlers = builder.BuildHandlers({ action, config, contextUser, abortSignal });
  preamble = builder.GetPreamble();
}
// If no builder is registered, Runtime actions still run in pure-compute mode —
// they just can't call any utilities.* bridge namespaces.

Two things to notice:

  1. No static dependency on this package from Engine. Engine imports only the abstract from actions-base; the concrete is resolved by name at runtime.
  2. Graceful degradation. If no subclass is registered (e.g., this package was never loaded), pure-compute Runtime actions still work. That makes minimal builds possible.

Bootstrap wiring

For the default bridge to register itself, this package has to be imported somewhere so its @RegisterClass decorator fires. The standard MJ flow handles this for you:

  • @memberjunction/server-bootstrap lists action-runtime-host as a dependency
  • The bootstrap manifest (ServerBootstrap/src/generated/mj-class-registrations.ts) is regenerated by mj codegen manifest and statically imports DefaultRuntimeActionBridgeBuilder alongside every other @RegisterClass-decorated class
  • MJAPI's entry point imports @memberjunction/server-bootstrap/mj-class-registrations, which transitively triggers our registration

No manual wiring needed in consuming apps.

Overriding the default bridge

The default uses @RegisterClass(RuntimeActionBridgeBuilder) with no key so any subclass registered later wins automatically via MJ's auto-priority tiebreak. Subclass, register, done:

import { RegisterClass } from '@memberjunction/global';
import { RuntimeActionBridgeBuilder, BridgeContext } from '@memberjunction/actions-base';
import type { BridgeHandlerMap } from '@memberjunction/code-execution';

@RegisterClass(RuntimeActionBridgeBuilder)
export class MyCustomBridge extends RuntimeActionBridgeBuilder {
  protected constructor() { super(); }
  public static get Instance(): MyCustomBridge { return super.getInstance<MyCustomBridge>(); }

  public BuildHandlers(ctx: BridgeContext): BridgeHandlerMap {
    return {
      'md.GetEntity':    /* … your handler … */,
      'utilities.custom.Ping': async () => 'pong',
      // … whatever you want to expose or override
    };
  }

  public GetPreamble(): string {
    return `
      globalThis.utilities = {
        custom: { Ping: (...a) => __bridgeCall('utilities.custom.Ping', a[0]) },
        // … match the handler keys above
      };
    `;
  }
}

Import your custom package from MJAPI's entry point (or add it to the bootstrap manifest flow) so @RegisterClass fires at startup.

The default utilities.* surface

DefaultRuntimeActionBridgeBuilder.BuildHandlers(ctx) wires these handler keys to permissioned handlers that enforce RuntimeActionConfiguration.permissions and thread contextUser through every downstream call:

| Namespace | Names | Purpose | |---|---|---| | md.* | GetEntity, GetEntityFields, GetRelatedEntities, ListEntities | Metadata read-only | | rv.* | RunView, RunViews | View queries (batched form supported) | | rq.* | RunQuery | Named-query execution | | entity.* | Load, Create, Update, Save, Delete | Entity CRUD (subject to allowedEntities) | | actions.* | Invoke, InvokeAll | Invoke other actions (subject to allowedActions) | | agents.* | Run, GetAvailable | Run AI agents (subject to allowedAgents) | | ai.* | ExecutePrompt, GetEmbedding | Execute AI prompts by name / get embeddings |

Each handler checks:

  1. Caller's RuntimeActionConfiguration.permissions allowlist (or allowAny* flags)
  2. The context's abortSignal (for cancellation)
  3. User context is threaded through so MJ row-level security still applies

On permission denial, handlers throw; the sandbox re-throws inside the user's code as a runtime error.

Testing

cd packages/Actions/RuntimeHost
npm run test

Unit tests validate the architectural contract (ClassFactory resolution, handler map shape, preamble-to-handlers consistency) without spinning up isolated-vm or a database. The end-to-end regression is packages/Actions/Runtime/harness/run-demos.ts — runs all 5 demo Runtime actions through the real stack.

Related packages

  • @memberjunction/actions-base — abstract RuntimeActionBridgeBuilder contract
  • @memberjunction/actions — consumes the builder via ClassFactory
  • @memberjunction/action-runtime — sandbox executor (what the bridge handler map gets passed to)
  • @memberjunction/code-executionWorkerPool + CodeExecutionService (isolated-vm sandbox)