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

@x12i/graphenix-core

v2.17.0

Published

Graphenix core tier: format 2.1.0 JSON schema, validation, and CRUD helpers.

Readme

@x12i/graphenix-core

Core tier of the Graphenix ecosystem — Format 2.1.0 JSON wire layout (@x12i/graphenix-core@^2.3.0 on npm).

Execution-neutral graph description: JSON schema, TypeScript types, validation, and CRUD helpers. Profile packages build strict subtypes on top of this core via generic metadata, typed parameters, and validateGraphWithProfile().

Install

npm install @x12i/graphenix-core

Validate a graph document

import {
  validateGraph,
  GRAPHENIX_FORMAT_VERSION,
  type GraphDocument
} from "@x12i/graphenix-core";

const doc: GraphDocument = {
  formatVersion: GRAPHENIX_FORMAT_VERSION,
  id: "graph:auth/user-signup",
  graph: {
    nodes: [],
    edges: [],
    inputs: [],
    outputs: []
  }
};

const result = validateGraph(doc);
if (!result.valid) {
  console.error(result.errors);
}

Each error is a GraphValidationError:

  • message — human-readable message
  • path — JSON Pointer to the failing instance
  • keyword / params — from AJV when applicable
  • source'graphenix' or 'profile'
  • code — optional profile-specific error code

Document fields

| Field | Required | Description | | ----- | -------- | ----------- | | formatVersion | yes | Must be "2.1.0" — export GRAPHENIX_FORMAT_VERSION. Persist validators reject 2.0.0, 2.1.1, and other drift (AUTHORING_FORMAT_VERSION_UNSUPPORTED); use legacy import adapters for uplift, not silent migration. | | id | yes | Globally unique graph identifier | | revision | no | Version of this graph document (not the format version) | | graph | yes | Structural graph (nodes, edges, inputs, outputs) | | metadata | no | Document metadata, extensions, summary contracts | | types | no | Custom type definitions | | subgraphs | no | Inlined reusable graphs |


Graph metadata (format 2.1.0)

Executable-profile graphs use first-class graph metadata fields. Core validates object shape; profile packages validate semantics.

graph.metadata
├── graphEntry      entry contract, execution schema
├── graphResponse   response shape, final output schema
├── modelConfig     graph-wide AI model cases (profile packages validate)
└── data            optional client keys (variables, presets, …)
{
  "graph": {
    "metadata": {
      "modelConfig": { "cases": [] },
      "data": { "variables": {} }
    }
  }
}

Do not emit metadata.extensions on new authoring graphs. Migration from 2.0.0 layout: docs/guides/migration-tier-1-authoring.md.


Generic types for profile subtypes

import type { GraphDocument, GraphMetadata, GraphenixMetadata } from "@x12i/graphenix-core";

interface X12iGraphMetadata extends GraphMetadata {
  modelConfig: { cases: unknown[] };
  data?: { variables?: Record<string, unknown> };
}

type X12iNodeParameters = { skillKey: string };

type X12iExecutableGraphDocument = GraphDocument<
  GraphenixMetadata,
  X12iGraphMetadata,
  X12iNodeParameters,
  GraphenixMetadata
>;

Aliases: GraphNode, GraphEdge, GraphPort, GraphType, Subgraph.


Profile validation

import {
  validateGraphWithProfile,
  type GraphProfileValidator,
  type GraphValidationError
} from "@x12i/graphenix-core";

const validateX12iProfile: GraphProfileValidator = (doc) => {
  const errors: GraphValidationError[] = [];
  const modelConfig = doc.graph.metadata?.modelConfig;
  if (!modelConfig || typeof modelConfig !== "object") {
    errors.push({
      source: "profile",
      code: "GRAPHENIX_MODEL_CONFIG_MISSING",
      message: "Executable profile is missing modelConfig.",
      path: "/graph/metadata/modelConfig"
    });
  }
  return { valid: errors.length === 0, errors };
};

validateGraphWithProfile(doc, validateX12iProfile);

Base validation runs first; profile validation runs only when base validation passes.


Input and output contracts

Per-port input contractgraph.inputs[].contract:

{
  "id": "rawRecord",
  "type": "object",
  "target": { "nodeId": "q1", "portId": "record" },
  "contract": {
    "semanticKind": "record",
    "required": true,
    "schema": { "type": "object" }
  }
}

Per-port output contractgraph.outputs[].contract:

{
  "id": "graph-output:final",
  "type": "builtin:object",
  "source": { "nodeId": "node:finalizer", "portId": "out:final" },
  "contract": {
    "semanticKind": "final-output",
    "required": true,
    "schema": { "type": "object" }
  }
}

Graph-level summary contracts — complement per-port contracts:

| Layer | Purpose | | ----- | ------- | | graph.inputs[].contract | Contract for a specific graph input port | | metadata.graphEntry | Summary contract for graph invocation | | graph.outputs[].contract | Contract for a specific graph output port | | metadata.graphResponse | Summary contract for final graph result |

Optional AJV checks against executionSchema / finalOutputSchema:

import {
  validateExecutionAgainstContract,
  validateFinalOutputAgainstContract
} from "@x12i/graphenix-core";

See docs/interop-worox-graph.md for worox-graph interop notes.


CRUD helpers

Immutable by default; pass { mutate: true } to modify in place.

import { addNode, updateNode, removeNode, addEdge } from "@x12i/graphenix-core";
  • Nodes: getNode, addNode, updateNode, removeNode
  • Edges: getEdge, addEdge, updateEdge, removeEdge
  • Types: getType, addType, updateType, removeType
  • Subgraphs: getSubgraph, addSubgraph, updateSubgraph, removeSubgraph

Test Utilities (Golden Fixtures)

The core package provides utilities for maintaining "golden" fixtures. This is particularly useful during the authoring stage to ensure the generated documents match a stable reference, helping the user understand the structure of what they have.

import { assertGoldenFixture } from "@x12i/graphenix-core/test-utils";

const actual = { /* ... your generated graph ... */ };
const fixturePath = "./fixtures/my-graph.json";

// Asserts that 'actual' matches the JSON in 'fixturePath'.
// If the file is missing or differs, it throws an error.
// Set UPDATE_FIXTURES=true to create or update the fixture automatically.
assertGoldenFixture(actual, fixturePath, {
  graphenixMasks: true // Automatically mask dynamic fields like planId, createdAt, etc.
});

| Option | Purpose | | --- | --- | | update | If true, creates/updates the fixture file. | | graphenixMasks | If true, masks common dynamic fields (planId, createdAt, *Hash, etc.). | | mask | Array of additional keys to mask recursively. | | scrub | Custom function to transform data before comparison. |

| API | Purpose | | --- | --- | | matchGoldenFixture | Returns a structured result (pass, wrote, actual, expected, message) | | assertGoldenFixture | Throws an AssertionError if the match fails (and update is not enabled) | | maskKeys | Recursive helper to replace keys with placeholders |


JSON Schema

Published at schema/graphenix-format-2.1.0.schema.json ($id: https://graphenix.dev/schema/graphenix-format-2.1.0.json). Legacy 2.0.0 schema retained for reference only.

Full field reference: GRAPHENIX-FORMAT.md.


Development

From the monorepo root:

npm install
npm run build
npm test

Or from this package:

npm run build
npm test

Notes

  • Execution-agnostic — core defines structure only.
  • Profile packages enforce execution semantics via metadata.modelConfig, typed node parameters, and profile validators.
  • Client-specific fields live in metadata.data; core validates object type only.
  • Task-node field names and phase vocabulary: GLOSSARY.md (monorepo root).