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

@onda-lang/processor-abi

v0.8.29

Published

Shared Onda processor artifact schema, validation, and integrity helpers

Readme

Onda processor ABI helpers

@onda-lang/processor-abi is the small, compiler-free JavaScript contract for Onda processor artifacts. It validates current-format descriptors and complete core-WebAssembly modules, creates and loads integrity-associated .wasm/.onda.json pairs, and provides the shared TypeScript surface used by @onda-lang/wasm-compiler, @onda-lang/binaryen-web, and @onda-lang/webaudio.

See api.md for the complete public Web API shared with the released package.

import {
  createParamControl,
  loadProcessorArtifactFiles,
  validateProcessorArtifact,
} from "@onda-lang/processor-abi";

const cutoff = artifact.metadata.metadata.params.find(
  (param) => param.name === "cutoff",
);
const cutoffControl = createParamControl(cutoff);
const plain = cutoffControl.normalizedToPlain(0.5);
const normalized440 = cutoffControl.plainToNormalized(440);

This package does not compile Onda source or host Web Audio. It exists so loaders and hosts can validate artifacts without installing the compiler or duplicating the ABI schema. The detailed TypeScript records mirror onda_processor_abi::ProcessorDescriptor; both packages validate the same checked-in conformance fixture.

Structured event payloads

Every event and delegate descriptor carries a recursive schema. PayloadPlan validates that schema once and encodes or decodes logical values without exposing the flattened executable parameters. Top-level parameters may be supplied by position or name; nominal structs are objects with exactly their declared fields, and tuples, fixed arrays, and slices are sequences. An omitted top-level parameter is legal only when its schema declares a default.

import {
  PayloadPlan,
  writeEventInput,
} from "@onda-lang/processor-abi";

const event = artifact.metadata.metadata.events.find(({ name }) => name === "note_on");
const plan = new PayloadPlan(event.schema);
const payload = plan.encode({
  note: { frequency: 440, velocity: 0.8 },
});
const workspaceBytes = plan.requiredWorkspace(payload);

// Addresses come from the host's wasm32 linear-memory allocator. Workspace must be 8-byte aligned.
new Uint8Array(memory.buffer, payloadAddress, payload.byteLength).set(payload);
writeEventInput(
  memory,
  inputAddress,
  payloadAddress,
  payload.byteLength,
  workspaceAddress,
  workspaceBytes,
);
// Pass inputAddress as the first argument to instance.exports[event.export](...).

Wire payloads are packed little-endian in canonical structure-of-arrays leaf order. Use sizes(lengths) when only dynamic slice lengths are known, or requiredWorkspace(payload) to preflight encoded bytes. Allocate payload, workspace, and the 16-byte EventInput descriptor before realtime dispatch, and keep their memory regions disjoint from one another and processor storage. plan.tensorMetadata exposes the same flattened contract as immutable records containing the leaf path, primitive encoding, fixed shape, owning parameterIndex, isSlice, and fixedElementCount. It is suitable for generating typed host storage or diagnostics without walking the recursive schema again. PayloadPlan.encode() itself allocates and therefore belongs on a host/control thread, as does decoding published delegate records. An event result of PROCESSOR_EXECUTION_INPUT_REJECTED (2) means preflight failed after output was reset but before handler or processor-state mutation.

WebAssembly intentionally exposes only the packed checked event entry. JavaScript values cross a thread boundary and must enter Wasm linear memory, so the native synchronous borrowed-view contract cannot provide end-to-end zero-copy dispatch on the Web. Web hosts should prepare capacity ahead of time and reuse the payload and workspace regions.

Delegate batches

The package exports DELEGATE_RECORD_HEADER_SIZE_BYTES, DELEGATE_BATCH_SIZE_BYTES, writeDelegateBatch(), readDelegateBatch(), and decodeDelegateBatch() for call-scoped delegate collection. Batch preparation and generated publication are allocation-free; decodeDelegateRecords() remains available for an already-isolated storage region. Descriptor entries expose exact fixed payload sizes or dynamic minimum sizes. A complete fixed record occupies the twelve-byte header (index, payload size, and call-local output sequence) plus its payload; no exact whole-call capacity exists because occurrence counts and slice lengths may be runtime-dependent.

import {
  DELEGATE_RECORD_HEADER_SIZE_BYTES,
  writeDelegateBatch,
  writeExecutionOutput,
  resetExecutionOutput,
  decodeDelegateBatch,
} from "@onda-lang/processor-abi";

const delegates = artifact.metadata.metadata.delegates;
const fixedRecordBytes = delegates.map((delegate) =>
  delegate.payload_size_bytes == null
    ? null
    : DELEGATE_RECORD_HEADER_SIZE_BYTES + delegate.payload_size_bytes
);

writeDelegateBatch(memory, batchAddress, storageAddress, capacityBytes);
writeExecutionOutput(memory, outputAddress, batchAddress, 0);
// Before onda_process (or initialization):
resetExecutionOutput(memory, outputAddress);
// Pass outputAddress as the final entry argument. onda_event_N resets it before preflight.
const { occurrences, overflowCount } = decodeDelegateBatch(
  memory,
  batchAddress,
  artifact.metadata,
);
if (overflowCount) reportOverflow(overflowCount);

Allocate the descriptor and storage before realtime execution and consume records before the next call reuses them. Reset the execution output immediately before every generated entry call. See the internal delegate host integration reference for the complete lifecycle, capacity guidance, and APIs for other hosts.

Print batches

Print delivery uses an independent caller-owned batch with the same physical descriptor shape. writePrintBatch(), readPrintBatch(), and decodePrintRecords() preserve each site's concrete scalar types; formatPrintBatch() and formatPrintRecords() produce canonical newline-terminated text with exact i64 and width-correct floating-point formatting. Use writeExecutionOutput() to pass independently nullable delegate and print batch addresses to init, process, or event exports. See the internal print host integration reference for the complete lifecycle and metadata contract.

The current descriptor represents every bindable buffer-array slot as a physical metadata.buffers entry and records logical contiguous groups in metadata.buffer_arrays. At runtime all four descriptor tables are present when any buffer exists, but an individual sample pointer may be null. Null entries select the processor's neutral one-frame zero/discard storage; they are valid bindings, not an incomplete artifact.

createParamControl() validates and decodes one parameter descriptor into a reusable control with constrainPlain(), normalizedToPlain(), and plainToNormalized() methods. It preserves exact endpoints, clamps out-of-range values, applies linear, logarithmic, or SuperCollider-style curved mapping, and snaps stepped domains. The package also exports one-shot functions with the same behavior. Use createParamControl(param, index) for an array element or paramElementMetadata(param, index) to obtain its scalar descriptor. Numeric parameters without a control domain are rejected. These APIs are synchronous and do not require a compiler, WebAssembly instance, or AudioWorklet, so editors can prepare controls once and use them responsively. Boolean plain and normalized numeric inputs use the same value >= 0.5 threshold as the native runtime and generated processor-object helpers.

createParamDomain() prepares the same reusable control from an already-decoded domain. It is intended for products such as the native run view whose transport already provides numeric minimum, maximum, step, and stepCount values.

Controlled i64 domains are limited by the descriptor contract to the exact binary64 integer range; unranged i64 parameters retain their full width through typed storage.