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

@semtalk/tbase

v1.0.38

Published

`tbase` is the in-memory model layer behind SemTalk. It gives you one object graph that holds:

Readme

@semtalk/tbase

tbase is the in-memory model layer behind SemTalk. It gives you one object graph that holds:

  • classes and instances
  • typed attributes and relations
  • business concepts like methods, states, and compositions
  • system-class metadata like labels and edit-dialog tab specs
  • diagrams, nodes, and JSON/XML persistence

This guide is meant to get a new engineer productive quickly.

Mental Model

There are three layers that matter most in day-to-day work:

  1. ObjectBase Holds the whole model and acts as the factory, registry, and lookup service.
  2. model objects SemTalkClass, SemTalkInstance, SemTalkAssociation, SemTalkAttribute, and the business/system variants.
  3. serializers and UI metadata OB2JSON, OB2XML, labels, and TabSpec definitions.

The most important rule is:

  • create everything from ObjectBase
  • navigate and mutate from the returned objects
  • persist with OB2JSON or OB2XML

Importing

import {
  ObjectBase,
  OB2JSON,
  SemTalkRelation,
  SemTalkValueType,
} from "@semtalk/tbase";

Quick Start

import { ObjectBase, OB2JSON } from "@semtalk/tbase";

const tb = new ObjectBase();
tb.SetModelAttribute("modname", "DemoModel");

const person = tb.MakeClass("Person");
const company = tb.MakeClass("Company");
const alice = person.MakeInstance("Alice");

alice.SetValue("firstName", "Alice");
alice.SetValue("isActive", true);
alice.MakeAssociation("worksFor", company);

const codec = new OB2JSON();
const json = codec.SaveJSON(tb);

const loaded = new ObjectBase();
codec.LoadJSON(loaded, json);

If you only remember one workflow, remember that one.

Core Concepts

ObjectBase

ObjectBase is the root container for the whole model.

Common things you do with it:

  • create objects: MakeClass, MakeBusinessClass, MakeSystemClass, MakeInstance
  • create reusable types: MakeAttributeType, MakeAssociationType, MakeMethodType, MakeStateType, MakeDiagramType
  • find objects: FindClass, FindInstance, FindAssociationType, FindObjectByID
  • enumerate: AllClasses, AllInstances, AllObjects, AllAssociationTypes
  • persist: pass it to OB2JSON or OB2XML

Typical setup:

const tb = new ObjectBase();
tb.SetModelAttribute("modname", "OrderModel");
tb.SetModelAttribute("currentnsp", "en");

Useful model attributes:

  • modname: model name
  • currentnsp: active language/namespace
  • showNamespace: whether captions show namespaces

Classes and Instances

Use classes for types and instances for concrete objects.

const person = tb.MakeClass("Person");
const alice = person.MakeInstance("Alice");

Important methods on classes:

  • MakeInstance(name?)
  • AddSubclassOf(superClass)
  • SuperClasses()
  • AllSuperClasses()
  • AllSubClasses()
  • IsParent(classOrSuperClass)

Important methods on instances:

  • ClassOf()
  • SetClass(newClass)
  • ToClass()

Attributes

The simplest way to work with attributes is through SetValue and GetValue.

alice.SetValue("priority", "high");
const value = alice.GetValue("priority");

Under the hood, tbase creates an attribute type if needed and then creates an attribute on the object.

If you need the real attribute object:

const attr = alice.MakeAttribute("isActive", false);
attr.ValueType = SemTalkValueType.Boolean;
attr.Min = 0;
attr.Max = 1;

Useful attribute APIs:

  • FindAttribute(nameOrType)
  • Attributes()
  • AllAttributes()
  • AllAttributeTypes()
  • GetAttributeOwner(nameOrType)

Inheritance behavior:

  • local attributes shadow inherited ones with the same attribute type name
  • AllAttributes() returns local attributes first, then inherited ones
  • GetAttributeOwner() returns the nearest class in the hierarchy that defines the attribute

Associations

Relations are first-class objects.

alice.MakeAssociation("worksFor", company);

Useful APIs:

  • MakeAssociation(nameOrType, toObject)
  • Associations()
  • InvAssociations()
  • HasDirectLink(nameOrType, target)
  • HasLink(nameOrType, target)
  • LinkedObjects(nameOrType, recursive?)
  • InvLinkedObjects(nameOrType, recursive?)
  • AllAssociations()

Notes:

  • MakeAssociation() reuses an existing link if the same source, relation type, and target already exist
  • HasLink() follows recursive paths and is cycle-safe
  • AllAssociations() includes inherited associations; in raw results it can also include the actual subClassOf_ inheritance link

Inheritance and Validity

Hierarchy lookup is a major part of tbase.

Examples:

const root = tb.MakeBusinessClass("Root");
const middle = tb.MakeBusinessClass("Middle");
const leaf = tb.MakeBusinessClass("Leaf");

middle.AddSubclassOf(root);
leaf.AddSubclassOf(middle);

root.SetValue("shared", "root");
middle.SetValue("shared", "middle");

leaf.GetAttributeOwner("shared"); // middle's attribute
leaf.AllAttributes();             // local first, inherited after

IsValid(dst, rel) is used when deciding whether a relation is allowed to connect to a target object.

In practice:

  • class relations can be inherited from superclasses
  • target subclasses are accepted when the relation points to a parent class
  • unrelated targets are rejected

Business Classes

SemTalkBusinessClass extends SemTalkClass with business semantics:

  • methods
  • states
  • compositions

Create one with:

const order = tb.MakeBusinessClass("Order");

Methods and States

order.MakeMethod("Approve");
order.MakeState("Ready");

Useful APIs:

  • methods: MakeMethod, FindMethod, FindAMethod, Methods, AllMethods, AllMethodTypes
  • states: MakeState, FindState, FindAState, States, AllStates, AllStateTypes

Inheritance behavior matches attributes:

  • local definition wins
  • inherited methods/states are visible via the All... and FindA... helpers

Composition

Compositions are business-specific constraints or conditions attached to an object.

Example:

const ownerClass = tb.MakeBusinessClass("OwnerBusiness");
const owner = ownerClass.MakeInstance("Owner");
const composed = tb.MakeBusinessClass("Order");
const methodType = tb.MakeMethodType("Approve");
const stateType = tb.MakeStateType("Ready");
const attributeType = tb.MakeAttributeType("Priority");

owner.MakeComposition(
  composed,
  methodType,
  stateType,
  attributeType,
  null,
  "=",
  false,
  "High",
);

Useful APIs:

  • MakeComposition(...)
  • Composition()
  • DeleteComposition()
  • inverse lists like InvCompositions()

System Classes

SemTalkSystemClass is where UI behavior and rendering metadata live.

Create one with:

const taskSystem = tb.MakeSystemClass("TaskSystem");

Typical use:

  • define labels for shapes
  • define edit-dialog tabs
  • hold UI flags like Hide, Composeable, Refineable

Business or normal classes often inherit from a system class, directly or indirectly:

const baseTask = tb.MakeClass("BaseTask");
const task = tb.MakeBusinessClass("Task");

baseTask.AddSubclassOf(taskSystem);
task.AddSubclassOf(baseTask);

When label resolution runs, tbase walks up the hierarchy to the actual system class.

Labels

Labels define how objects are rendered in diagrams.

Useful APIs on SemTalkSystemClass:

  • MakeLabel(text, master)
  • MakeClassLabel(text, master)
  • Labels(master?)
  • ClassLabels(master?)
  • FindLabelForMaster(master, text?)

Example:

const taskSystem = tb.MakeSystemClass("TaskSystem");
taskSystem.MakeLabel("Task: Name", "");
taskSystem.MakeClassLabel("Class: Name", "");

The label engine supports master-specific labels and the historic slot syntax used by the old Visio-based version.

Tab Specs for Edit Dialogs

Tab specs live on SemTalkSystemClass and define which tabs the UI should show for class and instance dialogs.

Get the definition object:

const system = tb.MakeSystemClass("TaskSystem");
const tabs = system.TabSpecDefinitions();

There are four main kinds:

1. Plain tab specs

Simple named tabs.

tabs.MakeTabSpec("General", false); // instance dialog
tabs.MakeTabSpec("Class Data", true); // class dialog

Key fields:

  • Text: visible title
  • IsClass: true for class dialogs, false for instance dialogs
  • Visible
  • Index: sort order

2. Generic relation tabs

Tabs backed by a relation.

tabs.MakeGenericTabSpec(
  "Related Orders",
  "worksFor",
  "Order",
  true,
  false,
  false,
  false,
);

Arguments:

  1. text: tab title
  2. relname: relation type name
  3. toobj: target class name
  4. isinst: include instances
  5. isinv: inverse direction
  6. isuni: treat as unidirectional
  7. isclass: class dialog or instance dialog

3. Generic attribute tabs

Tabs backed by a list of attributes.

tabs.MakeGenericAttributeTabSpec(
  "Audit",
  "Metadata",
  ["CreatedBy", "ChangedBy", "Created", "Changed"],
  false,
);

4. Tab-spec list tabs

Tabs that group other tabs.

tabs.MakeTabSpecListTabSpec(
  "Advanced",
  "Details",
  ["Audit", "Relations"],
  false,
);

Useful retrieval methods:

  • TabSpecs()
  • ClassTabSpecs()
  • InstanceTabSpecs()
  • GenericTabSpecs()
  • GenericAttributeTabSpecs()
  • FindTabSpec(name)

Persistence

JSON

OB2JSON is the most relevant serializer for current work.

import { ObjectBase, OB2JSON } from "@semtalk/tbase";

const codec = new OB2JSON();
const json = codec.SaveJSON(tb);

const loaded = new ObjectBase();
codec.LoadJSON(loaded, json);

Round-trip coverage in tests currently includes:

  • model attributes
  • classes and instances
  • inheritance links
  • attributes and falsy values like false and 0
  • associations
  • comments and color metadata

XML

OB2XML also exists, but use JSON first unless you specifically need XML compatibility.

Search and Lookup

Useful global lookup methods on ObjectBase:

  • FindClass(name)
  • FindBusinessClass(name)
  • FindSystemClass(name)
  • FindInstance(name)
  • FindObjectByID(id)
  • SearchObjects(text)
  • SearchNodes(text, pagingFrom?, pagingTo?)

Prefer ID-based lookup when objects may be renamed.

Events

ObjectBase emits many events internally through PostEvent, for example:

  • create/delete
  • rename
  • attribute changes
  • association changes
  • load/save

The current callback mechanism uses the internal _callbacks array and expects callback objects with a getMessage(...) method. It works, but it is closer to internal infrastructure than a polished public API, so treat it carefully.

Common Patterns

Create a reusable relation type first

tb.MakeAssociationType(SemTalkRelation.SemTalkProperty, "worksFor");
alice.MakeAssociation("worksFor", company);

This is not strictly required, but it can make model setup more explicit.

Start simple with SetValue

Prefer:

obj.SetValue("priority", "high");

Only drop down to MakeAttribute() when you need metadata such as:

  • ValueType
  • Min
  • Max
  • Weight

Use hierarchy helpers instead of manually walking associations

Prefer:

  • AllAttributes()
  • AllAssociations()
  • FindAMethod()
  • FindAState()
  • GetAttributeOwner()

They encode the shadowing and inheritance rules already.

Gotchas

  • MakeClass("Name") and similar factory methods return existing objects if the name already exists.
  • Anonymous instances are auto-named like ClassName.<id>.
  • Renaming a class updates anonymous instance names, but not explicitly named instances.
  • AllAssociations() is a raw association view and can include inheritance links like subClassOf_.
  • Inheritance shadowing is name-based for attributes, methods, states, and association types.
  • Prefer FindObjectByID() when identity matters more than caption or name.

Small Cookbook

Build a tiny hierarchy

const root = tb.MakeBusinessClass("Root");
const child = tb.MakeBusinessClass("Child");

child.AddSubclassOf(root);
root.SetValue("priority", "high");

console.log(child.GetValue("priority"));
console.log(child.GetAttributeOwner("priority")?.Owner.ObjectName);

Traverse a relation graph

const a = tb.MakeClass("A");
const b = tb.MakeClass("B");
const c = tb.MakeClass("C");

a.MakeAssociation("rel", b);
b.MakeAssociation("rel", c);

console.log(a.HasLink("rel", c));            // true
console.log(a.LinkedObjects("rel", true));   // [b, c]

Configure a system class for UI

const system = tb.MakeSystemClass("TaskSystem");
system.MakeLabel("Task: Name", "");
system.MakeClassLabel("Task Type: Name", "");

const tabs = system.TabSpecDefinitions();
tabs.MakeTabSpec("General", false);
tabs.MakeGenericAttributeTabSpec("Audit", "Metadata", ["CreatedBy", "ChangedBy"], false);

Where to Look Next

Good source files for learning the code:

Good examples in tests:

Package Maintenance

npm login
npm run build
npm publish --access=public