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

@m0saic/dsl-stdlib

v1.0.0

Published

Standard library of builders, transforms, and utilities for the m0 DSL

Readme

@m0saic/dsl-stdlib

Standard library for the m0saic DSL. Builders, transforms, queries, and construction helpers.

npm install @m0saic/dsl-stdlib

Depends on @m0saic/dsl only.


Where this fits

              @m0saic/dsl
        the language core (zero deps)
      grammar, parser, validator, types
                    |
      +-------------+-------------+
      |                           |
  @m0saic/dsl-         @m0saic/dsl-stdlib    <── you are here
  file-formats           builders, transforms
  .m0  .m0c              authoring toolkit
      |                           |
      +-------------+-------------+
                    |
            @m0saic/dictionary
         curated entries + generators

The stdlib is additive and optional. The core DSL defines the language; the stdlib provides tools for building and manipulating DSL strings programmatically. Nothing in stdlib changes language semantics.


API overview

  ┌──────────────────────────────────────────────────────────────────┐
  │                      @m0saic/dsl-stdlib                         │
  │                                                                  │
  │  CONSTRUCTORS         BUILDERS              TRANSFORMS           │
  │  ────────────         ────────              ──────────           │
  │  toM0String       container             split                │
  │  tryM0String      equalSplit            replace              │
  │                       weightedSplit         addOverlay           │
  │  QUERIES              weightedTokens        removeOverlay        │
  │  ───────              grid                  setTileType          │
  │  hasOverlayAtSpan     strip                 measureSplit         │
  │                       aspectFit             swapFrames           │
  │  NON-TARGETED         placeRect                                  │
  │  ────────────         aspectSafeGrid        All targeted ops     │
  │  addOverlayToAllFrames safeCanvas           accept a             │
  │  rewriteOverlayChains spotlight             TransformTarget      │
  │                       comparison                                 │
  │                       rankedList                                 │
  │                       bentoGrid                                  │
  └──────────────────────────────────────────────────────────────────┘

Constructors

toM0String(raw): M0String

Canonicalize, validate, and brand a raw string. Throws on invalid input.

import { toM0String } from "@m0saic/dsl-stdlib";

const layout = toM0String("2(F, F)");  // branded M0String: "2(1,1)"

tryM0String(raw): M0StringResult

Same pipeline, but returns a Result instead of throwing.

import { tryM0String } from "@m0saic/dsl-stdlib";

const result = tryM0String("2(1,1,1)");
if (result.ok) {
  console.log(result.value);  // M0String
} else {
  console.log(result.error.code);  // "TOKEN_COUNT"
}
  M0StringResult =
    | { ok: true;  value: M0String }
    | { ok: false; error: M0ValidationError }

Neither constructor performs overlay chain rewriting. If input may contain }{, call rewriteOverlayChains first.


Builders

Builders produce validated M0String values from structured parameters.

Primitives

import { container, equalSplit, weightedSplit } from "@m0saic/dsl-stdlib";

container(["1", "1", "1"], "col");         // "3(1,1,1)"
equalSplit(4, "row");                       // "4[1,1,1,1]"
weightedSplit([2, 1, 1], "col");           // "4(0,1,0,1)"  — 2:1:1 ratio
  container(tokens, axis)                    wrap tokens in counted split
  equalSplit(count, axis, claimant?)         N equal children
  weightedSplit(weights, axis, opts?)        proportional distribution
  weightedTokens(weights, claimant?)         weight tokens without wrapping
  strip(count, axis, opts)                   linear stack with gutter control

Layout builders

import { grid, aspectFit, spotlight, bentoGrid } from "@m0saic/dsl-stdlib";

grid(opts): GridResult

Rectangular grid with optional gutters.

const { m0, order } = grid({ rows: 3, cols: 4, gutter: 0.1 });
// 3 rows × 4 cols with 10% gutter

aspectFit(opts): AspectFitResult

Constrain content to an aspect ratio within a container.

const { m0, frameW, frameH } = aspectFit({
  rootW: 1920, rootH: 1080,
  target: { w: 1, h: 1 },   // square
  hAlign: "center",
  vAlign: "center",
});

placeRect(opts): PlaceRectResult

Position a rectangle of known size within a canvas.

const { m0 } = placeRect({
  rootW: 1920, rootH: 1080,
  rectW: 1280, rectH: 720,
  hAlign: "center", vAlign: "center",
});

spotlight(opts): SpotlightResult

Hero tile with supporting tiles. Four arrangements:

  "bottom"    hero on top, supports below
  "right"     hero on left, supports right
  "l-wrap"    hero top-left, supports in L around it
  "u-wrap"    hero top, supports in U below
const { m0 } = spotlight({ supportCount: 3, arrangement: "bottom" });

comparison(opts): ComparisonResult

Before/after comparison pairs.

const { m0 } = comparison({ pairs: 2, direction: "horizontal" });
// 4 tiles: 2 side-by-side pairs

rankedList(opts): RankedListResult

Ranked/priority list with size decay.

const { m0 } = rankedList({ count: 5, decay: "steep", direction: "vertical" });

bentoGrid(opts): BentoGridResult

Curated irregular grids (Apple marketing page aesthetic).

const { m0, tileCount } = bentoGrid({ base: "3x3", variant: 1 });
  Base sizes     Variants
  ──────────     ────────
  "3x3"          1, 2, 3
  "4x3"          1, 2
  "4x4"          1, 2

Other builders

  safeCanvas(opts)         canvas grid with feasibility constraints
  aspectSafeGrid(opts)     grid with aspect ratio preservation

Transforms

Structural edits on DSL strings. Each transform accepts a TransformTarget to identify which node to operate on:

type TransformTarget =
  | { by: "logicalIndex"; index: number }   // 0-based rendered frame index
  | { by: "span"; span: { start: number; end: number } }  // character span
  | { by: "stableKey"; key: string };       // structural identity path

split(m0, target, opts)

Split a tile into N children along an axis.

import { split } from "@m0saic/dsl-stdlib";

// Split the first frame into 3 columns
split(m0, { by: "logicalIndex", index: 0 }, { axis: "col", count: 3 });

// With weights
split(m0, { by: "span", span }, { axis: "row", count: 2, weights: [2, 1] });

replace(m0, target, replacement)

Replace a node with a new DSL fragment.

import { replace } from "@m0saic/dsl-stdlib";

replace(m0, { by: "stableKey", key: stableKey }, "3(1,1,1)");

addOverlay(m0, target) / removeOverlay(m0, target)

Add or remove an overlay {1} on a node. No-op if already present/absent.

import { addOverlay, removeOverlay } from "@m0saic/dsl-stdlib";

addOverlay(m0, { by: "span", span });
removeOverlay(m0, { by: "stableKey", key: stableKey });

setTileType(m0, target, type)

Change a leaf node's type ("1", "0", "-", "F", ">").

import { setTileType } from "@m0saic/dsl-stdlib";

setTileType(m0, { by: "logicalIndex", index: 2 }, "-");

measureSplit(m0, target, opts)

Replace a tile with a measure-mode split (kept regions within N slots).

import { measureSplit } from "@m0saic/dsl-stdlib";

measureSplit(m0, { by: "logicalIndex", index: 0 }, {
  axis: "col", count: 4,
  ranges: [{ start: 1, end: 3 }],
});

swapFrames(m0, indexA, indexB)

Atomically swap two rendered frames (including overlays). Addressed by logical index only.

import { swapFrames } from "@m0saic/dsl-stdlib";

swapFrames(m0, 0, 2);

Non-targeted transforms

import { addOverlayToAllFrames, rewriteOverlayChains } from "@m0saic/dsl-stdlib";

addOverlayToAllFrames(m0);         // overlay every rendered frame
rewriteOverlayChains("1{1}{1}");   // → "1{1{1}}"  (collapse chains)

Overlay Chain Rewriting

rewriteOverlayChains collapses overlay chains (}{) into nested form. The DSL validator rejects }{ — this helper is required preprocessing for generated/intermediate strings.

  Input                    Output
  ─────                    ──────
  X{A}{B}                  X{A{B}}
  X{A}{B}{C}               X{A{B{C}}}

Idempotent. Already-nested strings pass through unchanged. Not part of the DSL language — it is a preprocessing helper for composition/flattening pipelines.

import { rewriteOverlayChains, toM0String } from "@m0saic/dsl-stdlib";

const raw = rewriteOverlayChains("1{1}{1}");  // "1{1{1}}"
const branded = toM0String(raw);            // validated + branded

Queries

import { hasOverlayAtSpan } from "@m0saic/dsl-stdlib";

hasOverlayAtSpan("1{1}", { start: 0, end: 3 });  // true

Types

import type {
  // Constructors
  M0StringResult,

  // Transforms
  TransformTarget,       // { by: "logicalIndex" | "span" | "stableKey", ... }
  SplitOptions,
  MeasureSplitOptions,
  MeasureRange,

  // Builder primitives
  ContainerAxis,         // "col" | "row"
  WeightedSplitOptions,
  TileTypePrimitive,     // "F" | "1" | ">" | "0" | "-"

  // Builder options / results
  GridOptions,
  GridResult,
  StripOptions,
  AspectRatio,           // { w: number; h: number }
  AspectFitOptions,
  AspectFitResult,
  AspectFitHAlign,       // "left" | "center" | "right"
  AspectFitVAlign,       // "top" | "center" | "bottom"
} from "@m0saic/dsl-stdlib";

ContainerAxis is structurally identical to M0Axis from @m0saic/dsl ("col" | "row"). They are interchangeable via TypeScript structural typing.


Design principles

  • Additive only — stdlib never changes DSL semantics
  • All builders validate — every builder returns a branded M0String (validation overhead is < 25us)
  • No implicit rewrites — overlay chain rewriting is explicit, never automatic
  • One function, three addressing schemes — every transform takes a TransformTarget discriminated union: logicalIndex for arrays, span for text editors, stableKey for structural operations
  • Deterministic output — same params always produce the same DSL string

License

Licensed under the Apache License, Version 2.0. See LICENSE and NOTICE.