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

dumling

v0.1.12

Published

TypeScript and Zod schemas, DTO types, operations, and stable IDs for learner-facing linguistic annotation.

Readme

dumling

The best parts of computational linguistics with a typesafe API

dumling provides types and Zod schemas for learner-facing meaning-focused segmentation.

This package ships working runtime surfaces for de, en, and he.

dumling keeps three linked DTOs separate:

  • Lemma: the dictionary or lemma-like entry
  • Surface: the normalized full form in context
  • Selection: the exact text the learner highlighted

Entrypoints

| Import path | Purpose | | ---------------- | ----------------------------------------------------------------------------------------------- | | dumling | Root runtime API: dumling.<language>, getLanguageApi, and supportedLanguages | | dumling/types | Public DTOs, feature helpers, descriptors, and API/result/error types | | dumling/schema | Concrete runtime schema registry: schemasFor and getSchemaTreeFor(language) |

Runtime API

Each concrete language namespace (dumling.de, dumling.en, dumling.he) exposes:

  • create: explicit constructors for lemma, surface.citation, surface.inflection, selection.standard, and selection.typo
  • convert: convenience projections from lemma -> surface, lemma -> selection, and surface -> selection
  • extract: entity accessors such as extract.lemma(...)
  • parse: safe parsing returning ApiResult<T, ParseError>
  • describe: descriptor helpers via describe.as.* and canonical descriptor CSV via describe.asCsv.*
  • id: stable ID encode/decode helpers for hydrated DTOs

The root runtime entrypoint also exposes:

  • supportedLanguages: the curated runtime language inventory
  • getLanguageApi(language): dynamic access to a language-bound workflow API

Public types

dumling/types exports:

  • DTOs: Lemma, Surface, Selection
  • Entity and ID helpers: EntityValue, EntityForKind, DumlingCsv, DumlingBase64Url, SelectionOptionsFor
  • Language-aware helper types: LemmaKindFor, LemmaSubKindFor, SurfaceKindFor, LemmaKindForSurfaceKind
  • Feature typing helpers: FeatureSet, FeatureName, FeatureValue, InherentFeaturesFor, InflectionalFeaturesFor
  • Descriptors and API shapes: Descriptor, DumlingApi, LanguageApi, DumlingDescriptorCsv
  • Result and error types: ApiResult, ParseError, IdDecodeError, IdDecodeSuccess

Core idea

Start with a German noun lemma, build the linked learner-facing entities explicitly, and then use the runtime helpers for parsing and IDs.

The Lemma is the dictionary or lemma-like entry:

const seeLemma = dumling.de.create.lemma({
	canonicalLemma: "see",
	lemmaKind: "Lexeme",
	lemmaSubKind: "NOUN",
	inherentFeatures: {
		gender: "Masc",
	},
	meaningInEmojis: "🌊",
}) satisfies Lemma<"de", "Lexeme", "NOUN">;

The Surface is the normalized full form that the note belongs to:

const seeSurface = dumling.de.create.surface.citation({
	lemma: seeLemma,
	normalizedFullSurface: "See",
}) satisfies Surface<
	"de",
	"Citation",
	"Lexeme",
	"NOUN"
>;

The Selection is the exact observed highlight in the learner's text:

const seeSelection = dumling.de.create.selection({
	spelledSelection: "See",
	surface: seeSurface,
}) satisfies Selection<"de", "Citation", "Lexeme", "NOUN">;

For that same Selection, the readable CSV ID and the tiny CSV payload inside the base64url ID are:

const seeSelectionReadableCsv =
	"Selection,See,Surface,Citation,see,Lemma,de,Lexeme,NOUN,see,🌊,gender=Masc";
const seeSelectionTinyCsv = "v1,x,See,s,c,see,l,de,l,n,see,🌊,g=m";

Quickstart

Install the package:

npm install dumling

Minimal end-to-end usage:

import { dumling as packageDumling } from "dumling";
import { schemasFor as packageSchemas } from "dumling/schema";
import type {
	DumlingDescriptorCsv as PackageDumlingDescriptorCsv,
	FeatureValue as PackageFeatureValue,
	Lemma as PackageLemma,
} from "dumling/types";

const lemma = packageDumling.de.create.lemma({
	canonicalLemma: "see",
	lemmaKind: "Lexeme",
	lemmaSubKind: "NOUN",
	inherentFeatures: {
		gender: "Masc",
	},
	meaningInEmojis: "🌊",
}) satisfies PackageLemma<"de", "Lexeme", "NOUN">;

const surface = packageDumling.de.create.surface.citation({
	lemma,
	normalizedFullSurface: "See",
});
const selection = packageDumling.de.convert.surface.toSelection(surface, {
	spelledSelection: "See",
});
const descriptor = packageDumling.de.describe.as.selection(surface);
const descriptorCsv = packageDumling.de.describe.asCsv.selection(surface);
const extractedLemma = packageDumling.de.extract.lemma(selection);
const gender: PackageFeatureValue<
	"de",
	"inherent",
	"Lexeme",
	"NOUN",
	"gender"
> = "Masc";

const parsed = packageDumling.de.parse.selection(selection);
if (!parsed.success) {
	throw new Error(parsed.error.message);
}

const id = packageDumling.de.id.encode.asBase64Url(parsed.data);
const decoded = packageDumling.de.id.decode.asSelection(id);
if (!decoded.success) {
	throw new Error(decoded.error?.message ?? "Failed to decode selection ID");
}

descriptor.surfaceKind satisfies "Citation";
descriptorCsv satisfies PackageDumlingDescriptorCsv<"de", "Selection">;
extractedLemma satisfies PackageLemma<"de">;
gender satisfies "Masc";

packageSchemas.de.entity.Selection.Citation.Lexeme.NOUN().parse(
	decoded.data.selection,
);

schemasFor.de.entity.*, schemasFor.en.entity.*, and schemasFor.he.entity.* expose concrete Zod schema getters. Leaf calls return Zod schemas for validators, LLM response-schema callers, and other schema-consuming APIs.

Concepts / Search Terms

People often look for this package using adjacent terms:

  • linguistic annotation
  • learner annotation
  • lemma and inflection modeling
  • surface form normalization
  • selection DTOs
  • Zod schema registries
  • stable linguistic IDs

Model notes

The public DTO model treats these as independent axes:

  • orthographicStatus: whether the observed spelling is standard or a typo
  • spellingRelation: whether a known spelling is canonical or an accepted variant
  • selectionCoverage: whether the learner highlighted the full surface or only part of it

Selections are always hydrated:

  • a Selection always contains a Surface
  • a Surface always contains a Lemma

Lemma kinds also include Construction for learner-facing patterned entries such as fused forms like German zum, zur, or beim, and paired frames like um_zu. Construction entries are citation-only today.

Scope

  • Runtime today: de, en, he
  • Runtime: Node >= 20
  • Package format: ESM

For repo development:

  • bun test
  • bun run test:package
  • bun run build
  • bun run generate:readme