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

@plasius/gpu-model-core

v0.4.4

Published

Canonical GPU model document, resource graph, diagnostics, and adapter contracts.

Readme

@plasius/gpu-model-core

Canonical model document, resource graph, diagnostics, and adapter contracts.

This repository is the dedicated package boundary defined by ADR 0094.

Diagnostics, repairs and conversion loss

evaluateGpuModelDiagnostics validates a format adapter's completed report. It defaults to strict mode, rejecting every standard violation. Tolerant and forensic modes accept only supported rules with repairApplied: true, which attests that the adapter performed and verified the exact action exposed by GPU_MODEL_REPAIR_RULES. It does not parse a model or perform repairs. Continue to validate the repaired document with validateGpuModelDocument.

import { evaluateGpuModelDiagnostics } from "@plasius/gpu-model-core";

const report = evaluateGpuModelDiagnostics({
  standard: "gltf-glb",
  mode: "tolerant",
  issues: [{
    kind: "violation",
    ruleId: "missing-normals",
    code: "NORMAL_REQUIRED",
    path: "/meshes/0/primitives/0/attributes/NORMAL",
    message: "Required normals were missing",
    originalValue: null,
    repairApplied: true, // Adapter already generated and validated normals.
  }],
});
// report.accepted === true; report.repairs contains the complete repair record.

Blocking errors, repairs, unsupported data, warnings and loss are separate kind variants. Unknown rules and unsupported data block every mode. Repairs preserve originalValue, action, severity, affectedPath, confidence, and ruleId. The supported profiles are gltf-glb, obj-mtl, fbx, and cad-bim; OBJ cannot use the skin-weight repair rule. The exported policy text records the upstream rule; executable contract actions deliberately narrow ambiguous fallbacks: invalid primitives are dropped (never clamped), unavailable textures remain unresolved, and malformed material references use the canonical default. These three fallbacks require a kind: "loss" issue at the same path. Each loss states effect: "dropped" | "approximated"; any loss blocks acceptance unless allowLoss: true is explicitly supplied, including in strict mode.

Forensic mode requires rawSource, a relevant, scrubbed JSON snapshot. Other modes reject that field to prevent unintended retention. Source evidence is separate from ordinary diagnostics and remains available even when conversion is rejected. Represent source NaN/Infinity as descriptive strings, not numbers. Never include credentials, signed URLs or unrelated personal data, and never log raw evidence or repair snapshots. The package performs no logging, I/O, persistence or credential detection. Use serialized JSON as the boundary for untrusted executable producers; JavaScript Proxies are not inert data.

GPU_MODEL_DIAGNOSTIC_LIMITS bounds the entire input to 1 MiB of JSON UTF-8, 4096 issues, 16384 JSON values, depth 12, 1024 members per evidence container and 65536 UTF-16 units per string. All ceilings apply together. Optional maxEvidenceBytes lowers the aggregate byte ceiling, including report fields and the limit itself. Overflow, unknown keys, getters, cycles, sparse arrays, exotic objects and malformed reports throw a static GpuModelDiagnosticsError without echoing caller data. Successful output is deeply frozen and owned by the package; caller objects remain mutable and unchanged.

The parent gpu.model.conversion.enabled flag governs adapter adoption. Keep it disabled until adapter-specific conformance tests pass; rollback disables the flag and restores strict mode. This API changes no stored flag and adds no UI capability. Synthetic contract fixtures cover glTF, OBJ, FBX and CAD reports; actual parsing and geometry verification belong to their format adapters. See ADR-0008.

Canonical conversion resource graph

createGpuModelResourceGraph projects a privately verified GpuModelDocument into a frozen dependency graph for resources, accessors, textures, materials, skeletons (including joints), skins, animations, provenance and conversion packages. It reuses the canonical values and immutable Blob payloads. Material bindings retain samplers and intended usage; texture values retain their hashes, MIME types, paths, colour spaces and export embedding policy.

import { createGpuModelResourceGraph, gpuModelResourceKey,
  type GpuModelDocument } from "@plasius/gpu-model-core";

declare const document: GpuModelDocument; // From the verification factory.
const graph = createGpuModelResourceGraph(document, {
  resources: document.resources.map(resource => ({
    resourceId: resource.id,
    location: { kind: "embedded" },
    exportEmbeddingPolicy: "inherit-source",
  })),
  packages: [{ id: "conversion", members: document.resources.map(resource => ({
    kind: "resource", id: resource.id,
  })) }],
});
const conversion = graph.nodes.find(node =>
  node.key === gpuModelResourceKey("package", "conversion"));

Supply exactly one binding per document resource. For external origins use location: { kind: "external", relativePath: "textures/albedo.png" }; the bytes must already have been resolved and verified. Paths use portable ASCII letters, digits, dots, underscores, hyphens and slash separators, with no absolute paths, traversal, URL syntax, device names or trailing dots. Components are at most 255 characters and paths at most 1024. Case-insensitive duplicate paths and file versus directory collisions fail. Descriptors do not authorize network/file access.

Resource export policies are inherit-source, prefer-embedded, prefer-external and forbid-embedding. The last requires an external origin. Exporters must satisfy resource and texture restrictions together, resolve preferences for the target, enforce destination-root confinement and validate their actual output. The graph neither writes packages nor proves export success. Asset catalogue admission and promotion remain owned by @plasius/asset-contracts.

gpuModelResourceKey(kind, id) encodes a JSON tuple, independent of declaration order and locale. Logical IDs are distinct from byte-content hashes. Nodes and dependency keys are sorted; joint/animation sample order stays intact. Package members are typed references, may include packages, and must form a DAG. Missing, repeated or cyclic references fail with fixed GpuModelResourceGraphError.code values. Canonical document validation still owns scene and semantic references. Animation target associations remain in canonical values, outside dependency edges. This is a resource dependency graph, not a replacement scene graph.

GPU_MODEL_RESOURCE_GRAPH_LIMITS caps 65536 nodes, 262144 dependency declarations (including repeated semantic dependencies before deduplication), and 256 packages. These ceilings may reject a large otherwise-valid canonical document. Construction performs no I/O, retries, logging or hashing; input accessors and malformed containers fail closed. Do not treat executable JavaScript Proxies as inert input. isGpuModelResourceGraph recognizes only locally constructed graphs. Structured clones must be rebuilt from a reverified document. The graph retains authored metadata and provenance: it is not a redaction boundary or a public logging format.

Adoption inherits the remotely evaluated gpu.model.conversion.enabled flag; rollback disables conversion adoption and pins the prior package release. No stored flag or UI capability changes here. See ADR-0009.

Implementation tracker

The canonical conversion architecture is defined by ADR 0094 in plasius-ltd-site. The package implementation work is split into Project-tracked Tasks:

The general package Tasks inherit gpu.model.conversion.enabled from Feature #1148 and remain independent of format-specific loaders and renderers. Task #13 is an additive dependent slice under Feature #2012 and also requires asset.pipeline.pvox-models.enabled before its compiler projection can run.

Canonical document v1

GpuModelDocument is the immutable, renderer-neutral hand-off between source format adapters, model processing, and render bridges. Raw resources cross an asynchronous verification boundary before document construction: an injected worker port streams every Blob through payload inspection and SHA-256 digest verification. Only privately attested resources are accepted by the synchronous factory. This prevents a shape-compatible object, forged digest string, or structured clone from claiming that bytes were verified.

import {
  CANONICAL_GPU_MODEL_COORDINATE_SYSTEM,
  GPU_MODEL_DOCUMENT_SCHEMA_VERSION,
  createAndVerifyGpuModelDocument,
  type GpuModelResourceVerificationPort,
} from "@plasius/gpu-model-core";

declare const untrustedAdapterOutput: unknown;
declare const verificationPort: GpuModelResourceVerificationPort;
const document = await createAndVerifyGpuModelDocument(
  untrustedAdapterOutput,
  verificationPort,
);

document.schemaVersion === GPU_MODEL_DOCUMENT_SCHEMA_VERSION; // true
document.coordinateSystem === CANONICAL_GPU_MODEL_COORDINATE_SYSTEM; // true

Adapter output includes roots, nodes, verified resources, accessors, meshes, materials, first-class texture fidelity nodes, distinct skeletons, joints and skins, blend shapes, animation clips, analytic geometry, bounds, provenance, diagnostics, and bounded JSON metadata. Material texture transforms, colour space, usage, extension payloads, authored rig weights, clip timing, and source metadata survive the canonical boundary.

Verification applies non-raiseable defaults of 100 MiB per resource, 164 MiB aggregate resources, 64 MiB aggregate images, and 4096 pixels per image axis. It verifies detected MIME and image dimensions before hashing that image, then constructs the returned Blob from the exact digest-verified byte snapshot. One internal deadline signal is propagated to both worker-port calls and every stream chunk. Re-verifying an attested resource or document is idempotent, but still honours cancellation and re-applies any tighter byte/image/aggregate limits using retained inspection evidence.

The document validator then reads only the private snapshot to reject non-finite accessor data, false min/max claims, out-of-range indices and skin joint indices, mismatched weights, texture bindings whose required TEXCOORD_n is absent from a material-using primitive, and bounds that do not match canonical POSITION bytes under affine world transforms. Payload, index, and instanced world-geometry work has aggregate ceilings; accessor evidence, mesh primitive/position indexes, and repeated position/index scans are cached within one validation. Scene ancestry uses one bounded interval index rather than per-joint parent walks. Blend-shape delta/accessor work is bounded across the document and reuses the verified payload evidence.

createGpuModelDocument remains available for trusted composition code that already holds privately verified resources. isGpuModelDocument narrows only values returned by a factory; canCreateGpuModelDocument is the non-narrowing probe. A structured clone deliberately loses private attestation and must pass through createAndVerifyGpuModelDocument again. Format parsing, renderer uploads, catalogue rights, promotion identity, tolerant repair, and target loss reporting stay outside this Task's package boundary.

Bounded static PVOX demo projection

Task #13 adds a deliberately narrower compiler hand-off without changing the general document owned by Task #3. Consumers first create a privately verified GpuModelDocument, evaluate the remote asset.pipeline.pvox-models.enabled flag, and then request a compiler-safe world-triangle projection:

import {
  createGpuModelStaticDemoCompilerInput,
  type GpuModelDocument,
} from "@plasius/gpu-model-core";

declare const verifiedDocument: GpuModelDocument;
declare const pvoxModelsEnabled: boolean; // remote flag evaluation

const compilerInput = await createGpuModelStaticDemoCompilerInput(
  verifiedDocument,
  { pvoxModelsEnabled },
);

compilerInput.canonicalDocumentHash; // SHA-256 of canonical document bytes
compilerInput.worldTriangles; // verified positions, normals, bounds and regions

The profile accepts at most 200,000 explicit world-space triangles, 4,096 nodes, 16,384 primitives, 4,096 fixed-factor materials, and 16 MiB of verified buffer resources. Every world-space coordinate additionally has a fixed, non-raiseable magnitude ceiling of 1,048,576 metres, with consistent axis extent and diagonal bounds. The compiler also checks every computed triangle coordinate against that ceiling; security bounds use tight absolute equality instead of coordinate-relative tolerance. It accepts only rigid triangles, opaque texture-free metallic-roughness or unlit materials, invertible transforms, and geometry whose verified bounds prove metre/Y-up/-Z-forward/floor-centred normalization. Skins, animation, morphs, analytic geometry, images, texture bindings, custom material workflows, strips, lines, and points fail closed.

encodeGpuModelDocumentCanonical sorts object keys while preserving semantic array order. Verified resource bytes are bound through their privately checked SHA-256 identities, so canonical encoding does not duplicate source payloads. hashGpuModelDocumentCanonical provides the stable whole-document identity. The projection retains safe source/converter hashes and material-region IDs, but deliberately excludes source URLs and arbitrary metadata from the PVOX compiler surface.

The dependency flow is:

strict source adapter
  -> createAndVerifyGpuModelDocument (Task #3 / Feature #1148)
  -> createGpuModelStaticDemoCompilerInput (Task #13 / Feature #2012)
  -> @plasius/gpu-model-voxel

This bounded demo contract does not implement provider acquisition, general source repair, native sparse GPU traversal, deformation, destruction, or the full production Partner-to-PVOX acceptance plan. See the static demo compiler-input design.

Rollout

  • Canonical-document feature flag: gpu.model.conversion.enabled
  • Static PVOX demo feature flag: asset.pipeline.pvox-models.enabled
  • Capability: none for this package-only layer
  • Rollback: disable asset.pipeline.pvox-models.enabled to stop new demo projections, disable gpu.model.conversion.enabled for the broader conversion boundary, and keep consumers pinned to the last validated package release

Development

Requires Node.js 24 and npm.

npm ci
npm run typecheck
npm test
npm run lint
npm run build
npm run pack:check

License

Apache-2.0. See LICENSE, SECURITY.md, and the files under legal/.

Release integrity

CI keeps the administrative contributor registry outside Git and npm package artifacts using normalized path checks and sealed-tar revalidation. The GitHub-hosted Node.js 24.18.0 release path follows the released @plasius/schema v1.4.2 template: release metadata lands through a protected pull request, exact-main CI must pass, and the immutable tarball is published through npm OIDC. Package-specific adaptations are limited to GitHub-hosted CI while the organisation runner is unavailable, current Node-24-compatible action majors with best-effort Codecov CLI upload, and a protected-merge retry when repository auto-merge is unavailable. Version 0.1.0 may use the explicit, time-limited bootstrap_first_publish production gate only while the package is absent; that credential is removed after the npm trusted publisher binding is active.

Adapter contracts and canonical conversion

ModelAdapter exposes metadata, inspect, load, validate and export. Register one explicit lowercase format ID per adapter using createModelConversionRegistry. Core has no concrete format parsers, IO resolvers, renderer dependencies, format sniffing, discovery or caches. Those belong to the dedicated format/runtime packages; inject adapters after a runtime has checked the remote gpu.model.conversion.enabled flag. Disable that flag and pin the prior public version to roll back adoption.

import {
  createModelConversionRegistry, type ModelAdapter,
  type ModelSource, type ModelTarget,
} from "@plasius/gpu-model-core";

// Applications supply installed, conformance-tested adapters.
async function convert(sourceAdapter: ModelAdapter, targetAdapter: ModelAdapter) {
  const registry = createModelConversionRegistry([sourceAdapter, targetAdapter]);
  const source: ModelSource = {
    kind: "uint8-array", bytes: new Uint8Array([1, 2, 3]),
    fileNameHint: "synthetic.input",
  };
  const target: ModelTarget = { kind: "array-buffer" };
  const result = await registry.convert({
    sourceFormat: sourceAdapter.metadata.formatId,
    targetFormat: targetAdapter.metadata.formatId,
    source, target,
  }, { mode: "strict", allowLoss: false, timeoutMs: 30_000 });
  if (!result.accepted) return result.diagnostics;
  return result.exported;
}

Conversion calls source load, checks the privately verified canonical document, records target capability losses, calls target validate(document), and finally calls target export. Same-format conversion follows the same route. It never calls inspect automatically, so a single-use stream is not consumed twice. registry.inspect, load, validate and export also enforce the boundary individually; direct export includes canonical capability/validation preflight. Unsupported formats or IO kinds are rejected before adapter work. There is no public direct-format converter hook, and extra registration keys are rejected. Use plain adapter objects with the four operations as own methods.

The following are the supported declarative forms. IO hints remain optional; paths, URLs and stream handles confer no authorization from core. The injected runtime must enforce filesystem roots, network allowlists, size limits while streaming, credentials, output overwrite policy, and atomic staging/commit. Never log headers or signed URLs; scrub adapter diagnostic/evidence text before calling the result factory. Core produces fixed error codes with no input or exception causes, but it cannot identify secrets embedded in arbitrary adapter messages.

import type { ModelSource, ModelTarget } from "@plasius/gpu-model-core";

const sources: ModelSource[] = [
  { kind: "file-path", path: "/models/synthetic.input" },
  { kind: "url", url: "https://example.invalid/model", headers: { Accept: "application/octet-stream" } },
  { kind: "blob-storage-url", url: "https://example.invalid/model", credentialMode: "runtime-resolved" },
  { kind: "blob", blob: new Blob(["synthetic"]), fileNameHint: "synthetic.input" },
  { kind: "array-buffer", bytes: new ArrayBuffer(4) },
  { kind: "uint8-array", bytes: new Uint8Array(4), mimeTypeHint: "application/octet-stream" },
  { kind: "stream", stream: new ReadableStream<Uint8Array>(), byteLengthHint: 4 },
];
const targets: ModelTarget[] = [
  { kind: "file-path", path: "/exports/synthetic.output", overwrite: false },
  { kind: "blob-storage-url", url: "https://example.invalid/output", contentType: "application/octet-stream", metadata: { purpose: "synthetic" } },
  { kind: "blob", mimeType: "application/octet-stream", fileName: "synthetic.output" },
  { kind: "array-buffer" },
  { kind: "uint8-array" },
  { kind: "stream", stream: new WritableStream<Uint8Array>() },
  { kind: "package", packageFormat: "zip", destinationHint: "synthetic.zip", includeSourcePayload: false },
];

HTTP(S) URLs with inline username/password are rejected. Storage descriptors support anonymous, signed and runtime-resolved credential modes; values are passed only to the injected adapter. Browser Web streams and Node AsyncIterable<Uint8Array> readable / structural write+end writable streams are supported without importing Node types into the public declarations. Memory input bytes are copied; Blob values are immutable, and streams remain opaque capabilities. Direct memory descriptors are capped at 64 MiB. Larger models should use streams with runtime-enforced budgets and worker isolation.

Adapters construct their shared envelope with createModelResultBase:

import { createModelResultBase, type ModelOperationOptions } from "@plasius/gpu-model-core";

function completedEvidence(options: ModelOperationOptions = {}) {
  const mode = options.mode ?? "strict";
  return createModelResultBase({
    standard: "gltf-glb", // Use the adapter's actual diagnostic profile.
    mode, allowLoss: options.allowLoss ?? false, issues: [],
    ...(mode === "forensic" ? { rawSource: { synthetic: true } } : {}),
  });
}
// load: { ...completedEvidence(options), document: verifiedDocument }
// inspect: { ...completedEvidence(options), capabilities: metadata, detectedFormat: metadata.formatId }
// validate: { ...completedEvidence(options), valid: true }
// export: { ...completedEvidence(options), target: target.kind, output: optionalMemoryPayload }

The factory reuses evaluateGpuModelDiagnostics; its immutable report is privately recorded. Spread the returned base unchanged into an operation result. Structural clones and invented report/projection arrays are rejected. warnings projects warning-severity diagnostics, repairs retains completed repair evidence, and lossReports retains dropped/approximated fidelity. The registry checks the caller's mode and loss consent independently, so an adapter cannot grant itself permission. Unknown/unsupported semantics remain blocking in all modes.

ModelLoadResult.document is optional only for refused operations; accepted loads require a privately verified document from this core module instance. ModelExportResult.output optionally carries Blob, ArrayBuffer or Uint8Array matching the selected memory target. A ResourcePackageManifest describes portable relative paths, roles and content types; duplicate identities/paths and unsafe paths are rejected. It is not proof of output bytes or promotion. Canonical resource identity remains in GpuModelDocument and the separately available resource graph. Cross-worker/module clones must be reverified and reports rebuilt before registry use.

Registry results retain per-stage diagnostic reports, preserving different source and target profiles, plus aggregate diagnostic/repair/loss arrays. The synthetic capabilities stage uses the core gltf-glb report profile solely as a container for format-neutral loss records; it applies no format-specific repair rules. It reports animation, rig/skin and analytic-geometry downgrade when the target's capability flags cannot preserve those values. Other prospective losses must be reported by target validation. Adapters must stage writes and reject unconsented loss before committing; core cannot undo an injected adapter's side effects. Always check accepted, including after export, and do not equate a manifest or adapter result with independently verified publication.

Each registry allows at most 128 adapters and eight concurrent operations (configurable downward with maxConcurrent). Each operation or whole conversion has a 30-second default deadline, configurable up to five minutes, and supports AbortSignal. No retries occur. Cancellation and timeouts stop subsequent stages; an unresponsive operation keeps its capacity slot until the underlying promise settles. Synchronous parser code cannot be preempted, so isolate untrusted code in runtime workers. Descriptor/report/manifest limits bound core work; raw JavaScript Proxies and injected adapter/stream implementations are trusted code, not a sandbox boundary.

The IO examples are covered by tests/adapter-registry.test.ts; all TypeScript blocks in this section are additionally compiled against the built public package during release verification. See ADR-0010 for compatibility with the initial site design and package ownership boundaries.