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

@fabricorg/platform

v0.3.1

Published

Generic, vertical-agnostic runtime for ontology-based business applications. Provides actions, modules, events, policies, state machines, adapters, displays, projections, privacy, and evidence contracts. Zero runtime dependencies; portable across any data

Readme

@fabricorg/platform

A portable runtime for ontology-based, agent-native business applications. Zero dependencies. Bring your own database client.

npm install @fabricorg/platform

Hello, action

import { z } from "zod";
import type { ActionDefinition, ActionContext } from "@fabricorg/platform/actions";

const greet: ActionDefinition<unknown> = {
  id: "demo.greet",
  schema: z.object({ name: z.string() }),
  handler: async (ctx: ActionContext<unknown>, params: { name: string }) => {
    return { greeting: `Hello, ${params.name}!` };
  },
};

That's the smallest unit. From here, you compose actions into a FabricModule<TDb>, register the module at startup, and call invokeAction("demo.greet", ...) from any of three call paths (authenticated user, signed token, or system/agent). Every call passes through the same pipeline: policy → state machine → handler → adapters → events → projections.

For a complete walkthrough see https://platform.fabric.pro/docs/getting-started/quickstart.

Why use this

You're building a governed business application — not a CRUD app. You need:

  • A single, auditable entry point for every mutation
  • Policies that gate every change before it happens
  • Events as evidence (not retrofitted logs)
  • Agents and humans treated identically by policy
  • A vertical-specific ontology layered on a portable runtime

That's what this package gives you. Nothing more.

What's in the box

| Subpath | What you get | |---|---| | @fabricorg/platform | Re-exports everything below | | @fabricorg/platform/actions | ActionDefinition, ActionContext, SagaImplementation | | @fabricorg/platform/policies | PolicyEvaluator, PolicyContext, code/data/hybrid evaluation | | @fabricorg/platform/state-machines | StateMachineDefinition, validateTransition | | @fabricorg/platform/events | AssetEventEnvelope, EventTypeRegistry | | @fabricorg/platform/projections | Replay/snapshot framework | | @fabricorg/platform/adapters | AdapterRegistry, retry + circuit-breaker | | @fabricorg/platform/modules | FabricModule<TDb>, registerFabricModules | | @fabricorg/platform/ids | createFabricId, FABRIC_ID_PREFIXES | | @fabricorg/platform/displays | DisplayRendererRegistration | | @fabricorg/platform/privacy | Redaction + data classification | | @fabricorg/platform/evidence | Compliance evidence packets | | @fabricorg/platform/objects | Shared object-type contracts | | @fabricorg/platform/testing | In-memory adapter registry, fake ActionContext, deterministic IDs |

Composing a vertical

Verticals declare a FabricModule<TDb> that registers their actions, policies, state machines, events, and adapters with the platform:

import type { FabricModule } from "@fabricorg/platform/modules";
import { registerFabricModules } from "@fabricorg/platform/modules";

const myModule: FabricModule<MyDbClient> = {
  namespace: "demo",
  version: "1.0.0",
  objectTypes: ["Widget"],
  actions: [greet, /* ... */],
  policies: [/* ... */],
  stateMachines: [/* ... */],
  displayRenderers: [],
};

// At app startup:
registerFabricModules([myModule]);

The platform never auto-loads a module. The host app composes them explicitly — no implicit defaults, no globals, no surprises.

The action lifecycle

Every invokeAction(id, params) call goes through:

  1. evaluatePolicies — every policy registered for the action runs (code/data/hybrid). A single block halts the invocation.
  2. State-machine validation — if the action's target entity is bound to a state machine, the requested transition is validated before the handler runs.
  3. HandleractionDef.handler(ctx, params) runs inside a single TDb transaction. Handler parses its own input via its schema (single source of truth).
  4. Adapters — for each actionDef.adapterSteps, the registered implementation runs via executeWithAdapterRetry (idempotent retry, exponential backoff, circuit breaker).
  5. Events — domain events are appended; projections derive read models on next replay.
  6. Completion — invocation status is marked, telemetry emitted.

validateActionParameters is also exposed for preview/dry-run paths but is not part of the execute pipeline.

Saga actions

Multi-step orchestrations declare kind: "saga" on the ActionDefinition and ship a SagaImplementation:

import type { SagaImplementation } from "@fabricorg/platform/actions";

export const ingestSaga: SagaImplementation = async (ctx, runChild) => {
  const step1 = await runChild({
    suffix: "step-1",
    actionId: "demo.receive_payload",
    parameters: { /* ... */ },
  });
  // orchestrate further child actions...
  return {
    resultData: { /* ... */ },
    event: { eventType: "...", subjectType: "...", subjectId: "...", payload: {} },
  };
};

Your worker maps action IDs to implementations. The platform dispatches generically — no platform code references vertical action IDs.

Portability boundary

The boundary.test.ts in this package fails CI if any of these leak in:

  • Concrete database/ORM imports — the literal Prisma, the field name prisma:, or the type default TDb = any
  • Vertical vocabulary (lending., borrower, lender, Vehicle, Party, Obligation, Offer, etc.)
  • "Register default" hooks (registerDefaultPolicies, etc.) — the platform never auto-loads anything

This is what keeps the platform portable across verticals and consumers. If you fork or add new patterns specific to your domain, extend the list in boundary.test.ts.

Compatibility

  • Runtime: Node 20+
  • Module formats: ESM and CommonJS (dual format from v0.2.0+)
  • TypeScript: 5.0+, moduleResolution: node or node16/nodenext

Versioning

0.x while contracts evolve. 1.0 only after at least two materially different verticals validate the API.

See CHANGELOG.md for release history.

Documentation

Full reference docs at https://platform.fabric.pro

License

MIT