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/lattix

v0.2.0

Published

KnowX living knowledge graph Web Component (static Explorer + live memorix-service)

Downloads

62

Readme

@x12i/lattix

KnowX-native living-knowledge graph. A single interactive graph plus a smart sidebar for consuming and managing a KnowX knowledge graph — search, inspect evidence, and review pending claims.

It is a framework-neutral Web Component. It does not read fixture files, hard-code demo records, or depend on a particular frontend framework. Object model, evidence, and relationships are fetched through Memorix — either static (@x12i/static-memorix Explorer API) or live (memorix-service /api/data, /api/metadata, /api/relationships) — and rendered as memorix-record/2 + KnowX content, per Memorix Format for Dummies and Building KnowX as a Native Memorix Content Type.

The object model

Every subject on the graph — an employee, a work item, a claim between the two — is a memorix-record/2 envelope. Business subjects (employees, work-items) carry a snapshots instance (the product view) and a knowx instance (the epistemic NODE facet: provenance + status). Claims between subjects (assertions) are first-class subjects of their own, carrying a knowx EDGE facet, a workflow instance (assignment/review state), and a confirmations instance (the human accept/reject decision). Accepted claims materialize as lightweight four-field relationship links for fast graph traversal — see @x12i/memorix-format's v2 module and src/api/knowledge-repository.ts for the read/write contracts this component implements.

Package contents

src/
  api/
    knowledge-api.ts             Backend port (static Explorer vs live memorix-service)
    explorer-api-client.ts       Typed Explorer API HTTP client
    explorer-knowledge-api.ts    Static adapter
    memorix-service-client.ts    Live memorix-service HTTP client
    knowledge-repository.ts      KnowledgeGraphRepository: compose, search, review
  component/
    lattix.ts                    <lattix-explorer> Web Component
    styles.ts                    Shadow-DOM styles
  renderers/
    graph-renderers.ts           The one graph layout (focus + depth-1 neighborhood)
  types.ts                       KnowX .data shapes, RelationshipLink, ComposedSubject
mocks/
  metadata/                      Object types, list/write descriptors
  data/                          Fieldstone ops fixtures (employees, work-items, assertions, relationships)
examples/                        Runnable Vite example
index.html                       Built-package HTML

Data flow

<lattix-explorer mode="static|live">
   │
   ▼
KnowledgeGraphRepository
   │
   ├─ static → ExplorerKnowledgeApi → /api/explorer/* → @x12i/static-memorix (:5100)
   └─ live   → MemorixServiceClient → /api/data|metadata|relationships → memorix-service (:5000)

mode="static" (default) uses the Explorer mock. mode="live" talks to a running memorix-service with org-id / agent-ids scope headers.

Run the complete example

1. Install dependencies

npm install

2. Start the static Memorix API

npm run dev (step 3) already starts this for you via dev:mock. To run it standalone instead:

@x12i/static-memorix@^3.5.1 is a devDependency of this package (installed by step 1). From this package directory, point it at Lattix's fixtures:

MOCKS_DIR="$PWD/mocks" static-memorix --port 5100

Port 5100 is the static mock band (5000–5099 is reserved for live memorix-service). It speaks content types natively (knowx, workflow, confirmations, …) and enforces the write contract's revision preconditions — see mocks/README.md for the fixture domain and @x12i/static-memorix's own README for the general API contract.

After npm run build, index.html is also a direct replacement for the original all-in-one page. It imports dist/index.js and contains no embedded knowledge records. Serve the package directory through any static HTTP server; do not open it with file://, because the browser must call the API.

3. Start the example UI

In another terminal:

npm run dev

The example uses the included Vite proxy, so the browser calls /api on the same origin and Vite forwards requests to port 5100 (the port npm run dev:mock listens on).

Use the component

npm install @x12i/lattix
<!-- static (default) — @x12i/static-memorix Explorer API -->
<lattix-explorer
  mode="static"
  api-base-url="http://localhost:5100"
  initial-record-id="wi-100"
></lattix-explorer>

<!-- live — memorix-service -->
<lattix-explorer
  mode="live"
  api-base-url="http://localhost:5000"
  org-id="g12opsdemo"
  agent-ids="ops"
  initial-record-id="wi-100"
></lattix-explorer>

<script type="module">
  import "@x12i/lattix";
</script>

For a same-origin static deployment, omit api-base-url or set it to an empty string (Vite proxy / reverse proxy). Live mode always needs org-id and agent-ids.

Attributes

| Attribute | Default | Meaning | | --- | --- | --- | | mode | static | static → Explorer/static-memorix · livememorix-service | | api-base-url | http://localhost:5100 (static) / http://localhost:5000 (live) | API origin; empty means same origin | | org-id | — | Live only → x-memorix-org-id | | agent-ids | — | Live only → x-memorix-agent-ids (comma-separated) | | initial-record-id | first KnowX search result | recordId the graph opens focused on | | poll-interval | 0 | Refresh interval in milliseconds; 0 disables polling | | edit-mode | review | read-only (browse only, Review/Propose never render, even for pending claims) · review (today's Accept/Reject/Propose) · manage (same as review, plus unlocks the editableFields metadata hook for a future inline-editing UI) |

Public methods

const explorer = document.querySelector("lattix-explorer");

await explorer.refresh();
await explorer.selectSubject("wi-101");

The narrate hook — explaining a connection in plain English

Opening a claim's Evidence tab shows a Story section. Lattix will not call an LLM itself — it's a portable, embeddable package, and it must not ship a vendor API key to every consumer. Instead it exposes an extension point:

const explorer = document.querySelector("lattix-explorer");

explorer.narrate = async ({ focus, other, link, assertion }) => {
  // focus/other are the two connected ComposedSubjects, link is the
  // GraphLink (direction + epistemic status), assertion is the claim's own
  // ComposedSubject (knowx + workflow + confirmations) when resolvable.
  // Call whatever LLM/proxy your host application controls -- the key
  // stays server-side, on your infrastructure, never in this bundle.
  const response = await fetch("/my-app/narrate-connection", {
    method: "POST",
    body: JSON.stringify({ focus, other, link, assertion })
  });
  return response.text();
};

Leave narrate unset and the Story section instead shows a clearly labeled, honest structured summary composed from the same evidence (not claiming to be AI-generated) — useful out of the box, and a legible fallback if your narrator throws.

Events

| Event | Detail | | --- | --- | | lattix-ready | { apiBaseUrl } | | lattix-error | { error } | | lattix-focus-change | { recordId, objectType } | | lattix-selection-change | { recordId, objectType, selection: ComposedSubject \| RelationshipLink \| null } | | lattix-confirm-request | { recordId, decision } — fired before a review write | | lattix-confirmed | { recordId, decision, subject: ComposedSubject } — fired after a successful review write | | lattix-proposed | { recordId, fromRecordId, toRecordId, subject: ComposedSubject } — fired after successfully proposing a new claim | | lattix-share-request | { recordId, objectType } |

Accept/Reject in the Review tab, and "+ Propose new claim" in the Connections tab, perform real writes against the configured Memorix backend (KnowledgeGraphRepository.confirmAssertion / .proposeAssertion) — that is this component's actual "manage the graph" surface. Sharing a view stays an emitted intent event for the host application to fulfill, per the original design philosophy: the component does not decide how sharing works.

API mapping

Static (mode="static") — Explorer / @x12i/static-memorix

| UI requirement | Explorer resource | | --- | --- | | Compose a subject's snapshot + knowx + workflow + confirmations | GET /api/explorer/records/full?entityName=…&recordId=… | | Resolve a bare recordId to its objectType | GET /api/explorer/records/content?contentType=knowx&recordId=… | | Search / browse KnowX subjects | GET /api/explorer/lists/{…}-knowx/records | | Assertions pending review | list filter data.epistemic.confirmation:eq:pending | | Relationship neighborhood | relationships-default list | | Accept/reject a claim | POST /api/explorer/records/write (+ relationships upsert on accept) | | Propose a new claim | POST /api/explorer/records/write × 2 (absent precondition) |

Live (mode="live") — memorix-service

| UI requirement | Service resource | | --- | --- | | Scope | headers x-memorix-org-id + x-memorix-agent-ids (always win over custom headers) | | Object-type / knowx config | GET /api/metadata/effectiveeffective[] entries with kind: "object-types"; each definition must carry a Lattix knowx block | | Compose | POST /api/data/compose { recordId, explicit: true } | | List knowx / pending | GET /api/data/content?objectType&contentType=knowx&filter=… | | Resolve knowx | GET /api/data/abstract?abstractType=KnowXEntity&id=… (projection → concrete content get) | | Writes | POST /api/data/content with required precondition (no silent absent default on patch/upsert) | | Relationship neighborhood | GET /api/relationships/query | | Materialize on accept | POST /api/relationships/discover { definitionId, confirm: true }definition-wide, not a single-link upsert; never PUT /api/relationships/links |

Live agent packs must declare the same knowx participation block Lattix reads on static fixtures (at minimum role: "node"|"edge"). Stock platform packs that only expose KnowXEntity as an abstract, without per-type knowx blocks, will load zero graph subjects until those definitions are extended.

src/api/knowledge-repository.ts is the read/write contract; adapters live in explorer-knowledge-api.ts and memorix-service-client.ts. The low-level Explorer client remains exported at @x12i/lattix/client.

Fixture model

See mocks/README.md for the full fixture domain (Fieldstone ops: employees, work-items, assertions, relationships) and how it maps onto memorix-record/2 + KnowX. In short:

  • employees / work-itemssnapshots (product view) + knowx (NODE facet: provenance + epistemic status).
  • assertionsknowx (EDGE facet: refs.from/refs.to, provenance, epistemic status), workflow (assignment + review state), confirmations (the accept/reject decision, once reviewed).
  • relationships — the four-field navigation links materialized once a claim's epistemic status is accepted as fact.

The graph is metadata-driven, not hardcoded

Lattix does not know the names "employees", "work-items", or "assertions" — those are this package's demo domain, not something baked into the component. Whether an object type shows up on the graph at all, whether it behaves as a node or an edge (a claim/relationship type), which list serves its knowx-tier content, which write descriptors handle its writes, and which .data fields manage edit mode may touch, are all read from that object type's own metadata document at runtime (KnowledgeGraphRepository.loadMetadata(), src/api/knowledge-repository.ts). Object types already carry an arbitrary metadata bucket ({name, summary?, catalogRelations?, [key: string]: unknown}), so this is a convention layered on an existing platform primitive — no changes to memorix-metadata/memorix-metadata-runtime were needed to build it.

To add a new object type to the graph, give its metadata document a knowx block:

{
  "name": "vendors",
  "knowx": {
    "role": "node",
    "knowxListId": "vendors-knowx",
    "editableFields": ["tier"]
  }
}
{
  "name": "disputes",
  "knowx": {
    "role": "edge",
    "knowxListId": "disputes-knowx",
    "knowxWriteDescriptorId": "disputes-knowx-write",
    "workflowWriteDescriptorId": "disputes-workflow-write",
    "confirmationsWriteDescriptorId": "disputes-confirmations-write"
  }
}

Then add the matching list descriptor(s), write descriptor(s), and fixture data under mocks/, and restart the static API — it loads fixtures once at startup. No lattix source change, and no renderer change: the single graph layout, the sidebar, and the review/propose flow all work off role, not a name. role: "edge" is what makes an object type eligible for Review and for proposeAssertion's edgeObjectType (it's picked automatically when exactly one edge type is configured; pass it explicitly once you have more than one).

If you want knowx.role to become a standard, documented, first-class part of the Memorix object-type schema — not just a convention this package happens to read — that's a real feature request against memorix-metadata/memorix-metadata-runtime, not a lattix change.

Live packs: the same knowx block must appear on object-type definitions returned by GET /api/metadata/effective (kind: "object-types"). Without it, lattix reports that object types loaded but none participate in the graph.

Build and verify

npm run typecheck
npm test
npm run pack:check

npm test builds the package and runs node --test against the real @x12i/static-memorix server (via MOCKS_DIR): it validates every fixture against the real @x12i/memorix-format validator, exercises the Explorer API client contract, and drives the full Web Component end to end — including searching, focusing a subject, and running the Accept/Reject review flow against real revision-safe writes.