@metamesh/generator-sdk
v0.20.0
Published
Portable contracts and helpers for MetaMesh Generators.
Readme
@metamesh/generator-sdk
Turn a parametric model into a reusable MetaMesh Generator. Define its controls and presets once, then use that definition to infer parameter types, validate saved values, and connect the model to an editing interface.
Preview:
0.xminor releases may break compatibility. Patches remain compatible within the same minor line.
Installation
Install matching SDK and Modeling releases to build the Generator below:
pnpm add @metamesh/generator-sdk @metamesh/modelingThe package publishes ES modules only. Use Node.js 24 or newer. TypeScript consumers need
TypeScript 6.0 or newer, strict checking, and NodeNext or Bundler module resolution.
Browser hosts need an ES2023-compatible runtime; the SDK's data contracts require no WebAssembly.
You can also use the SDK on its own for definitions, parameter handling, and package validation.
The optional /modeling adapter connects it to Modeling; your application supplies the interface
and execution host.
Define controls
A Generator combines a definition with a synchronous model program. This example makes a sleeve with two diameter controls. Parameter types come from the definition, and an assertion checks that the bore fits inside the outer wall:
import { defineGenerator } from "@metamesh/generator-sdk";
import { defineGeneratorModel } from "@metamesh/generator-sdk/modeling";
import { tube } from "@metamesh/modeling";
export const definition = defineGenerator({
id: "sleeve",
version: "0.1.0",
title: "Sleeve",
groups: [],
parameters: [
{ id: "outerDiameter", label: "Outer diameter", type: "number", default: 20, min: 4 },
{ id: "boreDiameter", label: "Bore diameter", type: "number", default: 10, min: 1 },
],
});
export default defineGeneratorModel(definition, ({ params, assert, part }) => {
assert(params.boreDiameter < params.outerDiameter, "The bore must fit inside the sleeve.", {
parameterId: "boreDiameter",
});
return part(
"body",
tube({
outerRadius: params.outerDiameter / 2,
innerRadius: params.boreDiameter / 2,
height: 20,
})
);
});defineGeneratorModel binds the definition to the model and infers its parameters and services.
If you already have a program, use defineGeneratorModule({ definition, program }). The resulting
runtime is a Modeling program that an engine or model test can execute directly.
Add named starting configurations with definePresets(definition, presets); each preset supplies
a complete parameter map.
Definitions and presets contain serializable data, without callbacks. Hosts normalize parameters, prepare assets, and execute the model. They also own forms, viewing, persistence, and export. Generator modules use format 5, which carries the callback and identity in one object; nested format-4 runtimes are unsupported.
Generator capabilities
| Area | Capabilities | | ---------------------- | ---------------------------------------------------------------------------------------------------------------- | | Parameter values | Numbers, booleans, choices and choice sets, text, colors, arrays, fonts, SVG, side profiles, and cross-sections. | | Editing metadata | Labels, units, groups, descriptions, inline hints, sliders, paired controls, and conditional visibility. | | Parameters and presets | Inferred TypeScript types, defaults, recovering normalization, strict codecs, and complete serializable presets. | | Host integration | Validated package manifests, module execution, Worker messages, and incremental mesh delivery. |
Conditional visibility changes which controls appear. Hidden values remain saved and still require validation. Put constraints between parameters in the model's assertions.
Validate definitions and values
defineGenerator checks the definition as soon as you declare it. definePresets checks preset
metadata and complete canonical values. Invalid declarations throw
GeneratorPackageValidationError. These helpers retain the supplied object or array and its
inferred literal types; they don't execute geometry or model assertions.
Inline parameter, editor, choice, and preset objects receive TypeScript excess-property checks. Runtime validation also catches extra fields that structural typing can hide in variables or generic factories.
Use normalizeParameters to recover saved values: it drops unknown keys, restores defaults, and
clamps numbers. Use createParamCodec(definition) when inputs must already be complete and
canonical; it rejects missing or unknown fields and invalid values. The
parameter guide
covers controls, conditions, and validation.
Use the codec's parse() to throw on invalid input, or safeParse() for a result you can check
without catching an exception. A failed parse reports issues without substitute parameters. Each ParameterIssue names
a control with parameterId; an optional path addresses a field within that control's value.
Hosts can pass these issues directly to aggregateParameterIssues.
Execute and deliver a model
executeGenerator always validates its single parameters map against the current definition.
Hosts can validate before loading assets, but execution still checks the supplied values.
Modeling hosts use parseGeneratorModel(value, definition) from /modeling to validate a loaded
module and infer its executable GeneratorModel<typeof definition> type. Pass the default export
itself for local entries that also export their definition; packaged namespaces contain only the
default export. Use parseGeneratorModule from /runtime when you don't need the Modeling adapter.
Invalid module envelopes throw TypeError; package validation reports MetaMesh issues and errors.
For Worker hosts, /modeling supplies ModelDeliveryEncoder; /runtime supplies PartDeliveryDecoder.
Transfers carry local buffers under geometry, with placement beside them. Decode resource
references before application use or export. Receiving hosts own the buffers and keep them immutable
and attached.
Model statistics use signedVolume in mm³. generateMs measures the engine run;
timings.totalMs covers the host workflow, including stages outside the engine. Hosts report only
the timing stages they measure, using paramsMs for parameter processing and finalizeMs for
finalization. byteCount counts finalized world-space position and index buffer bytes, counting
shared buffers once; it doesn't measure the local buffers transferred by a Worker.
API entry points
Each public type and function has one import path. Import FontSelection and isFontSelection
from /fonts, and GeneratorPreset from the package root.
| Import | Responsibility |
| ------------------------------------ | ------------------------------------------------------------------- |
| @metamesh/generator-sdk | Definitions, presets, inferred types, and module authoring. |
| @metamesh/generator-sdk/modeling | Definition-inferred Modeling programs. |
| @metamesh/generator-sdk/parameters | Defaults, saved values, normalization, and strict codecs. |
| @metamesh/generator-sdk/runtime | Execution, generated geometry, and Worker protocols. |
| @metamesh/generator-sdk/packages | Package, catalog, installation, and definition-document validation. |
| @metamesh/generator-sdk/fonts | Immutable font selection values. |
@metamesh/generator-sdk/parameters.schema.json supports offline definition editing. The SDK
validates references, defaults, and cross-field rules in addition to the structural schema.
Documentation
Resolve @metamesh/generator-sdk/docs/manifest.json for exact-version Markdown guides and annotated
API references. With CLI installed:
pnpm exec metamesh docs search "parameters"
pnpm exec metamesh docs show sdk/guide/generator-modulesSee local authoring for the complete workflow and Contributing for package development.
