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

@nuucognition/mesh-convex-component

v1.0.4-beta.0

Published

The standard Convex component for mesh storage. One component, mounted by every NUU app that hosts meshes.

Readme

@nuucognition/mesh-convex-component

The standard Convex component for mesh storage. One component, mounted by every NUU app that hosts meshes. Design: (Proposal) 001 Mesh Convex Component in the NUU Mesh Flint; extraction plan: (Plan) 014 Mesh Service Extraction and Relocation to NUU Docs.

What it stores

Five tables: meshes, documents, batches (the oplog), blobs, structuralLeases.

A document row is title + raw markdown content, stored unsplit, plus three derived identities: docId, contentHash (body-only, the previousHash target), and frontmatterHash. The component never stores parsed structure — mesh-core rebuilds tags, links, embeds, and all indexes client-side from raw content.

The ensure-id rule: a create whose content has no frontmatter id gets one minted and injected into the stored content. Identity is durable in the markdown itself; docId is a mirror.

What it guarantees

  • Batches apply atomically and in order. A rejection rolls back with zero partial writes.
  • previousHash optimistic concurrency; invalid dominates hash-conflict; rejection reaches the host as typed data.
  • Returned hashes are server-authoritative (server re-derives; client claims are recorded, never trusted).
  • Document ids are unique per mesh. A create or update whose id would collide with another document rejects as invalid.
  • The id invariant holds in the bytes: content whose frontmatter fails to parse rejects as invalid — the ensure-id rule cannot make an id durable in malformed frontmatter, so the stored content always carries a parseable id: block.
  • Blob bytes never ride a mutation. Clients pre-upload to component-scoped storage; every createBlob is validated against blobStorageIds in the same transaction. The oplog stores refs, never bytes.
  • Blob size and hash are server-derived from the validated storage object (hash as lowercase SHA-256 hex); client claims land on the drift tripwire, never in the row.
  • A storage object backs exactly one blob row in the whole component, plus that row's meshes.clone copies — createBlob with a storageId that ANY existing blob row already references rejects as invalid, whatever mesh that row belongs to. Cross-mesh sharing is the clone mechanism and nothing else, and a clone copy is verbatim. So deleteBlob (and mesh teardown) deletes the stored bytes only with the LAST blob row referencing them (blobs.by_storageId), and a mesh can never destroy another mesh's media.
  • Declared metadata bounds. meshId and blobKey cap at 1024 characters, blob name at 1024, blob type and mime at 256. createBlob and renameBlob refuse an oversized name, type or mime as invalid, naming the field and the cap. The blobKey cap is what renameBlob enforces, where the key rides inside the operations JSON. An oversized key never reaches createBlob: the key is an object FIELD NAME in blobStorageIds, and the platform refuses a field name over 64 characters before the component runs. meshes.create and meshes.clone refuse an oversized mesh id. The caps apply to the values as STORED, so a name or type derived from the blob key meets the same cap as a supplied one. They exist so the component's own arithmetic is static: every chunked sweep, and the blob-delete charge that pays for by_storageId probe reads it cannot see, is bounded by construction rather than by a Convex index-key limit the component never stated. The caps are far above real data — a file path, a file name, an extension, an IANA media type. Rows written by an older component version are out of contract (no backcompat): a deployment carrying old data audits or resets it before upgrading.
  • One batches row per applied non-empty batch, seq === version. Empty batches are explicit no-ops.
  • Structural leases gate multi-document gestures, with a 45s TTL crash backstop.
  • meshes.remove is paginated internally: bounded chunks per transaction, residue swept by self-scheduled continuations, the mesh row deleted last. Its FIRST transaction marks the mesh removing before it deletes anything, so nothing can mistake a half-emptied mesh for a whole one. Poll meshes.get for completion.
  • meshes.clone copies a mesh (row, documents, blob rows) into a new host-minted targetMeshId, paginated the same way — each chunk is bounded by BOTH a row count and the accumulated size of the WHOLE rows it carries (content, titles, keys, hashes, and a flat per-row allowance), so no shape of mesh can build an oversized transaction. The copy is born frozen and cloning. The oplog and leases are not copied.
  • meshes.clone refuses a source whose teardown has started, with a typed MESH_REMOVING ConvexError (isMeshRemovingError); a copy already in flight against such a source ends cloneFailed. Teardown outlives the mesh row, so a source under teardown holds residue, not a version.
  • The copy is a snapshot of one source version. Each continuation compares the captured source version against the live one; a source batch landing mid-copy makes the copy delete what it wrote and start again (bounded restarts). So a finished copy is a state the source really had, never a mix of two.
  • Completion contract: poll meshes.get until cloning === false, then read cloneFailed. cloning === false && cloneFailed === false means the copy is whole. cloneFailed === true is terminal: the copy stopped partial (the source was removed or entered teardown, or changed past the restart budget) and the target must be discarded with meshes.remove. updatedAt moves on every continuation, so a stalled copy shows as staleness.
  • A frozen mesh is immutable, permanently: operations.apply, leases.acquire, leases.extend, blobs.generateUploadUrl and meshes.rename refuse it with a typed MESH_FROZEN ConvexError. Reads are unaffected, leases.release still works (dropping a lock is not a write), and meshes.remove still works. This guarantee holds inside the component, so no host bug can mutate a published copy.

Direct component callers: operations.apply reports a rejection by THROWING a typed ConvexError — that throw is what rolls the component sub-transaction back. The MeshComponent client class catches it and returns the contract's rejection-as-data union; a host calling the component function directly must catch the typed error itself.

What it does NOT do

  • No auth. Components cannot read ctx.auth. The host authorizes and passes meshId (+ author / principal). Never re-export raw component functions.
  • No parsing, no indexes, no sync/session tier, no history projections — hosts and clients own those.

Mounting

// convex/convex.config.ts (host app)
import { defineApp } from "convex/server"
import mesh from "@nuucognition/mesh-convex-component/convex.config"

const app = defineApp()
app.use(mesh)
export default app
// convex/mesh.ts (host app) — authorized public surface
import { components } from "./_generated/api"
import { exposeMeshApi } from "@nuucognition/mesh-convex-component"

export const {
  getManifest, loadIndex, getContent, getContents, listBatches,
  applyOperations, generateUploadUrl, getBlobData,
  acquireLease, extendLease, releaseLease,
} = exposeMeshApi(components.mesh, {
  requireAccess: async (ctx, meshId, mode) => {
    // Host ACL check. Throw to deny.
    // return { author, principal } to bind identity into the write path.
  },
})

Host code with its own authorization can use the thin client directly:

import { MeshComponent } from "@nuucognition/mesh-convex-component"
const mesh = new MeshComponent(components.mesh)
const result = await mesh.applyOperations(ctx, { meshId, operationsJson, ... })

cloneMesh is deliberately absent from exposeMeshApi: cloning is a host-authorized operation (publish, fork), never a remote client capability. Call it through MeshComponent after the host's own check.

const clone = await mesh.cloneMesh(ctx, { sourceMeshId, targetMeshId, name })
// clone.done === false → the copy continues in the background.
// Poll mesh.getMesh(ctx, targetMeshId) until `cloning` is false, then:
//   cloneFailed === false → the version is complete and readable;
//   cloneFailed === true  → the copy stopped partial; report the failure and
//                           mesh.removeMesh(ctx, targetMeshId).

Codegen

# from any Convex app directory:
pnpm exec convex codegen --component-dir <path-to>/src/component