@metamesh/generator-sdk 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/README.md +46 -320
- package/dist/contours.d.ts +36 -0
- package/dist/contours.d.ts.map +1 -0
- package/dist/{cross-sections.js → contours.js} +19 -61
- package/dist/contours.js.map +1 -0
- package/dist/contracts.d.ts +15 -11
- package/dist/contracts.d.ts.map +1 -1
- package/dist/curve-data.d.ts +11 -0
- package/dist/curve-data.d.ts.map +1 -0
- package/dist/curve-data.js +53 -0
- package/dist/curve-data.js.map +1 -0
- package/dist/generator-package/constants.d.ts +2 -2
- package/dist/generator-package/constants.js +2 -2
- package/dist/generator-package/errors.d.ts +19 -1
- package/dist/generator-package/errors.d.ts.map +1 -1
- package/dist/generator-package/errors.js +58 -11
- package/dist/generator-package/errors.js.map +1 -1
- package/dist/generator-package/index.d.ts +7 -2
- package/dist/generator-package/index.d.ts.map +1 -1
- package/dist/generator-package/index.js +52 -9
- package/dist/generator-package/index.js.map +1 -1
- package/dist/generator-package/portable-data.d.ts +12 -0
- package/dist/generator-package/portable-data.d.ts.map +1 -0
- package/dist/generator-package/portable-data.js +102 -0
- package/dist/generator-package/portable-data.js.map +1 -0
- package/dist/generator-package/schemas/common.schema.d.ts.map +1 -1
- package/dist/generator-package/schemas/common.schema.js +4 -2
- package/dist/generator-package/schemas/common.schema.js.map +1 -1
- package/dist/generator-package/schemas/definition.schema.d.ts +451 -57
- package/dist/generator-package/schemas/definition.schema.d.ts.map +1 -1
- package/dist/generator-package/schemas/definition.schema.js +5 -2
- package/dist/generator-package/schemas/definition.schema.js.map +1 -1
- package/dist/generator-package/schemas/manifest.schema.d.ts +178 -62
- package/dist/generator-package/schemas/manifest.schema.d.ts.map +1 -1
- package/dist/generator-package/schemas/manifest.schema.js.map +1 -1
- package/dist/generator-package/schemas/parameter-document-json-schema.d.ts +4 -0
- package/dist/generator-package/schemas/parameter-document-json-schema.d.ts.map +1 -0
- package/dist/generator-package/schemas/parameter-document-json-schema.js +17 -0
- package/dist/generator-package/schemas/parameter-document-json-schema.js.map +1 -0
- package/dist/generator-package/schemas/parameter.schema.d.ts +173 -275
- package/dist/generator-package/schemas/parameter.schema.d.ts.map +1 -1
- package/dist/generator-package/schemas/parameter.schema.js +169 -79
- package/dist/generator-package/schemas/parameter.schema.js.map +1 -1
- package/dist/generator-package/schemas/preset.schema.d.ts.map +1 -1
- package/dist/generator-package/schemas/preset.schema.js +4 -4
- package/dist/generator-package/schemas/preset.schema.js.map +1 -1
- package/dist/generator-package/validate-definition.d.ts +4 -7
- package/dist/generator-package/validate-definition.d.ts.map +1 -1
- package/dist/generator-package/validate-definition.js +210 -272
- package/dist/generator-package/validate-definition.js.map +1 -1
- package/dist/generator-package/validate-manifest.d.ts.map +1 -1
- package/dist/generator-package/validate-manifest.js +5 -10
- package/dist/generator-package/validate-manifest.js.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/parameter-contracts.d.ts +62 -39
- package/dist/parameter-contracts.d.ts.map +1 -1
- package/dist/parameters/issues.d.ts.map +1 -1
- package/dist/parameters/issues.js +9 -10
- package/dist/parameters/issues.js.map +1 -1
- package/dist/parameters/recovery.d.ts.map +1 -1
- package/dist/parameters/recovery.js +11 -12
- package/dist/parameters/recovery.js.map +1 -1
- package/dist/parameters/strict.d.ts.map +1 -1
- package/dist/parameters/strict.js +7 -10
- package/dist/parameters/strict.js.map +1 -1
- package/dist/parameters/values.d.ts +1 -0
- package/dist/parameters/values.d.ts.map +1 -1
- package/dist/parameters/values.js +7 -6
- package/dist/parameters/values.js.map +1 -1
- package/dist/parameters.schema.json +1757 -0
- package/dist/parse-generator-module.d.ts +1 -1
- package/dist/parse-generator-module.js +1 -1
- package/dist/side-profiles.d.ts +36 -0
- package/dist/side-profiles.d.ts.map +1 -0
- package/dist/{profiles.js → side-profiles.js} +21 -66
- package/dist/side-profiles.js.map +1 -0
- package/package.json +4 -3
- package/dist/cross-sections.d.ts +0 -41
- package/dist/cross-sections.d.ts.map +0 -1
- package/dist/cross-sections.js.map +0 -1
- package/dist/profiles.d.ts +0 -41
- package/dist/profiles.d.ts.map +0 -1
- package/dist/profiles.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @metamesh/generator-sdk
|
|
2
2
|
|
|
3
|
+
## 0.10.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 0eea1b4: Add one optional static `ui.hint` string per parameter with strict metadata validation. Short, essential instructions appear inline; descriptions provide supplementary help from the question-mark button. Control visibility remains conditional. Hints are part of the format 3/runtime 3 baseline.
|
|
8
|
+
- 9d7052c: Separate parameter values from local UI metadata, add strict parameter-document diagnostics and a generated JSON Schema, and rename the side-profile and contour APIs. Generator packages and modules now require format 3 and runtime 3.0.0.
|
|
9
|
+
- cf597bd: Add optional `ui.row` metadata for two adjacent number inputs, choice dropdowns, or text controls within a parameter group. Shared rows are part of the format 3/runtime 3 baseline.
|
|
10
|
+
|
|
3
11
|
## 0.9.0
|
|
4
12
|
|
|
5
13
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -1,43 +1,30 @@
|
|
|
1
1
|
# `@metamesh/generator-sdk`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Turn a parametric model into a MetaMesh Generator. Define its controls once, infer parameter
|
|
4
|
+
types, and use the same validation contract for forms, saved values, and execution.
|
|
4
5
|
|
|
5
6
|
> **Preview:** `0.x` minor releases may break compatibility. Patches remain compatible within the
|
|
6
7
|
> same minor line. Stable support requires an explicit `1.0.0` review.
|
|
7
8
|
|
|
8
|
-
Install a published release from npm:
|
|
9
|
-
|
|
10
9
|
```bash
|
|
11
10
|
pnpm add @metamesh/generator-sdk
|
|
12
11
|
```
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
|
19
|
-
|
|
|
20
|
-
|
|
|
21
|
-
| `/parameters` | Defaults, normalization, strict codecs, schema issues |
|
|
22
|
-
| `/runtime` | Evaluated module parsing, execution, mesh DTO parsing, Worker envelopes |
|
|
23
|
-
| `/packages` | Package, catalog and installation trust parsing |
|
|
24
|
-
| `/fonts` | Standalone font selection contract |
|
|
25
|
-
|
|
26
|
-
Definitions remain callback-free and serializable. Preparation/build state is local to execution;
|
|
27
|
-
Studio owns persistence and the Modeling engine owns modeling and manufacturing finalization.
|
|
28
|
-
|
|
29
|
-
## Parameter definitions
|
|
13
|
+
| Import | Use it for |
|
|
14
|
+
| ------------- | ---------------------------------------------------------- |
|
|
15
|
+
| Package root | Definitions, presets, and preparation/module authoring |
|
|
16
|
+
| `/parameters` | Defaults, recovering saved values, and strict codecs |
|
|
17
|
+
| `/runtime` | Module execution, generated mesh data, and Worker messages |
|
|
18
|
+
| `/packages` | Package, catalog, and installation parsing |
|
|
19
|
+
| `/fonts` | Font selection values |
|
|
30
20
|
|
|
31
|
-
|
|
32
|
-
`text`, `font`, `svg`, `profile`, `cross-section`, or homogeneous `array`. Sliders require `min`, `max`, and `step`;
|
|
33
|
-
numbers may omit them. Visibility uses serializable `ConditionExpression` values with `all`, `any`,
|
|
34
|
-
`not`, equality/inequality, numeric comparisons, and choice-set membership (`contains`).
|
|
21
|
+
## Define controls
|
|
35
22
|
|
|
36
|
-
|
|
23
|
+
A definition is serializable metadata. Capture its literal IDs and options to derive exact
|
|
24
|
+
parameter types:
|
|
37
25
|
|
|
38
26
|
```ts
|
|
39
27
|
import { defineGenerator, type GeneratorParams } from "@metamesh/generator-sdk";
|
|
40
|
-
import { createParamCodec, prepareParameters } from "@metamesh/generator-sdk/parameters";
|
|
41
28
|
|
|
42
29
|
const definition = defineGenerator({
|
|
43
30
|
id: "sleeve",
|
|
@@ -50,235 +37,28 @@ const definition = defineGenerator({
|
|
|
50
37
|
],
|
|
51
38
|
});
|
|
52
39
|
type Parameters = GeneratorParams<typeof definition>;
|
|
53
|
-
|
|
54
|
-
const persistedValues: Readonly<Record<string, unknown>> = { outerDiameter: 24 };
|
|
55
|
-
const { parameters, validation } = prepareParameters(definition, persistedValues);
|
|
56
|
-
const workerValues: unknown = { outerDiameter: 24, boreDiameter: 10 };
|
|
57
|
-
const strictParameters = createParamCodec(definition).parse(workerValues);
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
Normalization drops unknown keys, restores missing or invalid values from declared defaults,
|
|
61
|
-
clamps numbers, and returns a fresh frozen map. Strict codecs reject missing, unknown, invalid, or
|
|
62
|
-
noncanonical values and return cloned frozen structured values. `prepareParameters()` normalizes
|
|
63
|
-
once and returns the map with schema issues. Execution aggregates Generator preparation issues
|
|
64
|
-
separately. Definitions accept only
|
|
65
|
-
canonical types. SVG values are strings limited to 256 KiB each and 512 KiB per normalized Project.
|
|
66
|
-
The same byte limits apply to defaults and presets. Definition parsing rejects defaults that exceed
|
|
67
|
-
the aggregate Project budget; preset parsing uses each declared control's limits, so an SVG value
|
|
68
|
-
may exceed the separate 64 Ki-character text limit.
|
|
69
|
-
|
|
70
|
-
```ts
|
|
71
|
-
import { EMPTY_SVG_PARAMETER_DEFAULT } from "@metamesh/generator-sdk/parameters";
|
|
72
|
-
|
|
73
|
-
const profile = {
|
|
74
|
-
id: "profile",
|
|
75
|
-
label: "Profile",
|
|
76
|
-
type: "svg",
|
|
77
|
-
default: EMPTY_SVG_PARAMETER_DEFAULT,
|
|
78
|
-
} as const;
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
### Choice sets and arrays
|
|
82
|
-
|
|
83
|
-
Choice sets have uniquely valued options and a default selection array. `minSelections` and
|
|
84
|
-
`maxSelections` optionally bound its size. Normalization orders valid selections by option
|
|
85
|
-
declaration; duplicate or invalid selections recover to the canonical default. `{ param: "outputs", contains: "nut" }`
|
|
86
|
-
must reference a choice set and one of its declared options.
|
|
87
|
-
|
|
88
|
-
Array definitions declare `items.type` as `number` or `string`. They may constrain `minItems` and
|
|
89
|
-
`maxItems`; number items may also declare `min`, `max`, `step`, and `unit`. Array-valued controls are
|
|
90
|
-
cloned at normalization and persistence boundaries. Conditions may compare scalar controls or test
|
|
91
|
-
`choice-set` membership; arbitrary arrays cannot be condition operands.
|
|
92
|
-
|
|
93
|
-
```ts
|
|
94
|
-
const points = {
|
|
95
|
-
id: "points",
|
|
96
|
-
label: "Point sizes",
|
|
97
|
-
type: "array",
|
|
98
|
-
default: [4, 8],
|
|
99
|
-
minItems: 1,
|
|
100
|
-
items: { type: "number", min: 0, unit: "mm" },
|
|
101
|
-
} as const;
|
|
102
40
|
```
|
|
103
41
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
Font parameters use a `FontSelection` default with immutable `faceId`, SHA-256 `revision`, and
|
|
110
|
-
integer `weight`. Structural validation does not require the font to be available locally. Valid
|
|
111
|
-
unavailable references survive codecs, presets, and persistence. Studio prepares declared fonts before the Generator's `prepare(parameters, services)` callback.
|
|
112
|
-
`services.text.layout(text, { font, fontSize })` returns exact vector paths and measurements in
|
|
113
|
-
millimetres. Keep that layout in the preparation value when checks and construction both need it.
|
|
114
|
-
Imported `textSection(layout)` consumes it during build. No ambient font provider is bound.
|
|
115
|
-
|
|
116
|
-
Text layout can use `baseline: { kind: "arc", radius, centerAngleDegrees, direction }` for a single circular line. Radius is in millimetres, the angle is counterclockwise from +X (default 90°), and direction defaults to clockwise. Alignment defaults to center for arcs; use clockwise at 90° for upright top text or counterclockwise at 270° for upright bottom text. Glyphs and attached marks rotate without distortion. Arc layout requires baseline vertical alignment and less than one full revolution; Generator preparation owns lettering size and face-fit checks. Packages using circular text require runtime `2.1.0` or newer.
|
|
117
|
-
|
|
118
|
-
### Validation and bounds
|
|
119
|
-
|
|
120
|
-
`GeneratorDefinition` is callback-free, JSON-safe metadata for forms, manifests, persistence, and
|
|
121
|
-
normalization. `defineGenerator()` preserves literal IDs/options; `GeneratorParams` and
|
|
122
|
-
`GeneratorIssue` derive exact parameter types and issue IDs from that definition. Use
|
|
123
|
-
`definePresets(definition, presets)` to require complete definition-derived preset values.
|
|
42
|
+
For saved values, `/parameters` provides `normalizeParameters`: it drops unknown keys, restores
|
|
43
|
+
missing or invalid values from defaults, and clamps numbers. At a trust boundary,
|
|
44
|
+
`createParamCodec(definition)` rejects missing, unknown, invalid, or noncanonical values instead.
|
|
45
|
+
Both return fresh frozen parameter maps.
|
|
124
46
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
and prevents build and native shape construction.
|
|
47
|
+
Parameter types describe saved values. Optional local `ui` metadata owns group/row membership,
|
|
48
|
+
hints, visibility, editing increments, and physical editor scale bindings. Number inputs and
|
|
49
|
+
sliders both use `type: "number"`; sliders declare `ui.control: "slider"`, bounds, and `ui.step`.
|
|
50
|
+
Fixed choices use `choice`; geometric values use `side-profile` and `contour`.
|
|
130
51
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
52
|
+
The `/packages` entry point validates the editable `{ groups, parameters }` document with
|
|
53
|
+
`safeParseParameterDefinitionDocument`, returning structured issue paths and codes. Complete
|
|
54
|
+
Generator and package parsing uses the same rules. The package also ships
|
|
55
|
+
`@metamesh/generator-sdk/parameters.schema.json` for offline editor completion and structural
|
|
56
|
+
validation; the SDK additionally checks references, defaults, and cross-field invariants.
|
|
135
57
|
|
|
136
|
-
|
|
137
|
-
callback-free. Preparation receives normalized, frozen parameters; malformed issue output is a
|
|
138
|
-
runtime error. Combined validation retains at most 100 issues, prioritizing errors over warnings
|
|
139
|
-
and preserving retained order. The reporting limit cannot hide a blocking error.
|
|
58
|
+
## Prepare and build
|
|
140
59
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
`{ code: "invalid", path: ["segments", 0, "control1", "height"] }` for a profile control.
|
|
144
|
-
`ParameterIssueCode` defines the supported categories: `invalid`, `missing`, `type`, `unknown`,
|
|
145
|
-
`minimum`, `maximum`, `integer`, `choice`, `duplicate`, `length`, `bytes`, and `structure`.
|
|
146
|
-
Schema validation supplies codes and nested locations; strict decoder paths start with the
|
|
147
|
-
parameter ID. Authored issues retain their optional metadata through preparation and transfer.
|
|
148
|
-
Issue parsing clones and freezes paths, bounds them to 32 segments, accepts non-negative safe
|
|
149
|
-
integer indices and non-empty field names of at most 120 characters, and never evaluates accessors.
|
|
150
|
-
Both fields are optional; issues always retain their required severity and message.
|
|
151
|
-
|
|
152
|
-
Use `getDefaultParameters(definition)` for a fresh frozen defaults map. IDs are bounded safe keys.
|
|
153
|
-
Package manifests, definitions, descriptors, conditions, and nested parameter objects reject unknown fields.
|
|
154
|
-
Definitions are bounded to 64 groups and 256 parameters, arrays to 1,024 items, options to 512,
|
|
155
|
-
presets to 256, and condition composition to 8 levels with 32 children per node.
|
|
156
|
-
`validateGeneratorPresets()` from `/packages` applies the same strict metadata and list bounds as
|
|
157
|
-
manifest parsing before checking complete canonical parameter maps. Testkit and bundled registries
|
|
158
|
-
use that shared validator.
|
|
159
|
-
|
|
160
|
-
### Editable side profiles
|
|
161
|
-
|
|
162
|
-
A `profile` declares an open side outline as a versioned `ProfileValue`. Start/end anchors carry
|
|
163
|
-
normalized `radius` and upward `height` coordinates, plus editing `mode` (`auto`, `smooth`, or
|
|
164
|
-
`corner`). Segments are `line` or `cubic`, with cubic `control1` and `control2` points. Coordinates
|
|
165
|
-
define the shape; hosts must resolve automatic tangents into those control points.
|
|
166
|
-
|
|
167
|
-
```ts
|
|
168
|
-
const sideProfile = {
|
|
169
|
-
id: "sideProfile",
|
|
170
|
-
label: "Side profile",
|
|
171
|
-
type: "profile",
|
|
172
|
-
radiusScale: { parameterId: "diameter", factor: 0.5 },
|
|
173
|
-
heightScale: { parameterId: "height", factor: 1 },
|
|
174
|
-
default: {
|
|
175
|
-
version: 1,
|
|
176
|
-
start: { radius: 0.4, height: 0, mode: "corner" },
|
|
177
|
-
segments: [
|
|
178
|
-
{
|
|
179
|
-
type: "cubic",
|
|
180
|
-
control1: { radius: 0.4, height: 0.35 },
|
|
181
|
-
control2: { radius: 1, height: 0.75 },
|
|
182
|
-
end: { radius: 0.6, height: 1, mode: "auto" },
|
|
183
|
-
},
|
|
184
|
-
],
|
|
185
|
-
},
|
|
186
|
-
} as const;
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
Every coordinate is finite and lies in `[0, 1]`. The start height is `0`, the last height is `1`,
|
|
190
|
-
and anchor heights increase strictly. Cubic control heights satisfy
|
|
191
|
-
`start.height <= control1.height <= control2.height <= end.height`, keeping the curve upward.
|
|
192
|
-
A profile has 1–31 segments. It has no SVG markup, sampled polygon, arbitrary closed paths, or
|
|
193
|
-
holes; the Generator owns physical scaling, mounting features, closure, and manufacturing checks.
|
|
194
|
-
|
|
195
|
-
Optional `radiusScale` and `heightScale` bindings describe physical measurements for host controls:
|
|
196
|
-
each references a declared `number` or `slider` in millimetres with a positive default and explicit
|
|
197
|
-
positive minimum, multiplied by a positive finite `factor`. Bindings do not transform saved profile
|
|
198
|
-
values; Generators consume the same normalized outline when resolving their dimensions. Omitting
|
|
199
|
-
bindings leaves the editor in normalized coordinates.
|
|
200
|
-
|
|
201
|
-
`isProfileValue()` strictly checks the complete bounded shape without evaluating getters.
|
|
202
|
-
`cloneProfileValue()` returns a fresh deeply frozen value, and `profileValuesEqual()` compares both
|
|
203
|
-
shape and editing intent. Normalization, strict codecs, defaults, and presets clone every nested
|
|
204
|
-
profile object. Invalid saved profiles recover to the declared default; strict boundaries reject
|
|
205
|
-
them. Profiles cannot be condition operands. All executable packages use format `2` and runtime major `2`.
|
|
206
|
-
|
|
207
|
-
### Editable cross sections
|
|
208
|
-
|
|
209
|
-
A `cross-section` declares one closed planar contour as a versioned `CrossSectionValue`.
|
|
210
|
-
It uses normalized `x` and upward `y` coordinates in `[0, 1]`, with `corner` or `smooth` anchor
|
|
211
|
-
modes and explicit `line` or `cubic` segments. Cubic controls retain the authored geometry;
|
|
212
|
-
editing modes never change it during execution. The final segment's end repeats the start's
|
|
213
|
-
coordinates and mode so the seam is one editable point.
|
|
214
|
-
|
|
215
|
-
```ts
|
|
216
|
-
const crossSection = {
|
|
217
|
-
id: "crossSection",
|
|
218
|
-
label: "Cross section",
|
|
219
|
-
type: "cross-section",
|
|
220
|
-
widthScale: { parameterId: "width", factor: 1 },
|
|
221
|
-
heightScale: { parameterId: "height", factor: 1 },
|
|
222
|
-
default: {
|
|
223
|
-
version: 1,
|
|
224
|
-
start: { x: 0, y: 0, mode: "corner" },
|
|
225
|
-
segments: [
|
|
226
|
-
{ type: "line", end: { x: 1, y: 0, mode: "corner" } },
|
|
227
|
-
{ type: "line", end: { x: 1, y: 1, mode: "corner" } },
|
|
228
|
-
{ type: "line", end: { x: 0, y: 1, mode: "corner" } },
|
|
229
|
-
{ type: "line", end: { x: 0, y: 0, mode: "corner" } },
|
|
230
|
-
],
|
|
231
|
-
},
|
|
232
|
-
} as const;
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
Contours have 2–32 segments and can travel in any direction. They have no holes or multiple loops.
|
|
236
|
-
Structural validity establishes bounded serializable data and explicit closure; the Generator
|
|
237
|
-
owns physical scaling, nonzero area, intersections, winding, and operation-specific geometry checks.
|
|
238
|
-
Optional `widthScale` and `heightScale` use the same positive millimetre references as side profiles.
|
|
239
|
-
They describe the coordinate envelope and never transform saved values; omitting them leaves
|
|
240
|
-
normalized coordinates.
|
|
241
|
-
|
|
242
|
-
`isCrossSectionValue()`, `cloneCrossSectionValue()`, and `crossSectionValuesEqual()` apply the same
|
|
243
|
-
accessor-safe validation, deep cloning/freezing, and shape/editing equality guarantees as profiles.
|
|
244
|
-
Defaults, normalization, codecs, presets, and Worker parameter maps preserve those values.
|
|
245
|
-
Invalid saved data recovers to the declared default; strict boundaries reject it. Cross sections
|
|
246
|
-
cannot be condition operands. Packages declaring them require minimum runtime `2.2.0`; manifest
|
|
247
|
-
parsing rejects lower declared minima. Side profiles retain their existing representation and
|
|
248
|
-
compatibility.
|
|
249
|
-
|
|
250
|
-
### Curve resolution
|
|
251
|
-
|
|
252
|
-
A `number` or `slider` may declare `role: "curve-resolution"` to identify the model's maximum
|
|
253
|
-
sampled curve deviation in millimetres. Hosts may present this input in a dedicated curve fidelity
|
|
254
|
-
control. It remains an ordinary Generator parameter with the same saved values, presets,
|
|
255
|
-
normalization, validation, and manufacturing exports.
|
|
256
|
-
|
|
257
|
-
```ts
|
|
258
|
-
const curveDeviation = {
|
|
259
|
-
id: "curveDeviation",
|
|
260
|
-
label: "Curve deviation",
|
|
261
|
-
type: "number",
|
|
262
|
-
role: "curve-resolution",
|
|
263
|
-
unit: "mm",
|
|
264
|
-
default: 0.05,
|
|
265
|
-
min: 0.01,
|
|
266
|
-
max: 0.2,
|
|
267
|
-
step: 0.005,
|
|
268
|
-
} as const;
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
Multiple controls may have this role. Each requires `unit: "mm"`, a positive `default`, and an
|
|
272
|
-
explicit positive `min`; numeric bounds and step rules still apply. Lower values request closer
|
|
273
|
-
approximation through the Generator's `GeometryResolution` policy; exact counts remain available
|
|
274
|
-
for matched topology. Hosts show authored labels in definition order and edit the saved parameters
|
|
275
|
-
used by both preview and manufacturing. Generators determine affected curves and parts; Studio
|
|
276
|
-
does not infer overrides from mesh IDs. Requests beyond complexity limits must fail explicitly.
|
|
277
|
-
|
|
278
|
-
## Compiled module and output boundary
|
|
279
|
-
|
|
280
|
-
`defineGeneratorModule()` creates the five-field format-2 surface. Preparation resolves the model
|
|
281
|
-
once; build receives that exact value. Imported modeling helpers bind to the host's synchronous build:
|
|
60
|
+
With [Modeling](https://github.com/JasonKoolman/metamesh/blob/main/packages/modeling/README.md)
|
|
61
|
+
installed, validate related dimensions and pass the prepared result into construction:
|
|
282
62
|
|
|
283
63
|
```ts
|
|
284
64
|
import { defineGeneratorModule, definePreparation, prepared } from "@metamesh/generator-sdk";
|
|
@@ -301,83 +81,29 @@ const runtime = defineGeneratorModule({
|
|
|
301
81
|
export const { formatVersion, generatorId, version, prepare, build } = runtime;
|
|
302
82
|
```
|
|
303
83
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
produce failed preparation.
|
|
309
|
-
|
|
310
|
-
The helper returns a preparation wrapper that accepts parameters and optional host `GeneratorServices`.
|
|
311
|
-
Omitting services uses `UNPREPARED_GENERATOR_SERVICES` for parameter-only probes; requesting
|
|
312
|
-
text through that provider fails explicitly. Hosts pass their prepared services.
|
|
313
|
-
It adds the scoped helper for each callback invocation, preserving the exact callback result and
|
|
314
|
-
prepared value without traversal or freezing. The callback itself is not returned unchanged.
|
|
315
|
-
`prepared(value)` remains the successful-value helper. Standalone global `invalid` accepts literal
|
|
316
|
-
IDs or existing error issues; the host checks their IDs against the definition at the runtime
|
|
317
|
-
boundary.
|
|
318
|
-
|
|
319
|
-
The root helper has no decoder or Modeling runtime dependency. Modeling owns `ModelingContext`
|
|
320
|
-
and `BuildOutput`; SDK context/output generics preserve author typing without importing them.
|
|
321
|
-
Prepared values are opaque local data: the SDK does not traverse, clone, serialize or freeze them.
|
|
322
|
-
Preparation must not acquire live modeling resources. Prepared values are never persisted,
|
|
323
|
-
transferred to the UI, or reused between requests.
|
|
324
|
-
|
|
325
|
-
Hosts import `parseGeneratorModule`, `prepareGenerator` and `executeGenerator` from `/runtime`.
|
|
326
|
-
The parser requires exactly the five exports above and matching manifest identity. Evaluated
|
|
327
|
-
preparation captures an opaque value in a one-use build closure; there is no raw prepared-value
|
|
328
|
-
invocation lane. Callback results must be synchronous. The host checks the own-data preparation
|
|
329
|
-
wrapper and bounded structured issues while leaving the value opaque.
|
|
330
|
-
|
|
331
|
-
Studio's authored source surface accepts `build` and optional `prepare`. Its compiler supplies
|
|
332
|
-
identity and `prepareIdentity(definition)` when preparation is omitted, then passes the resulting
|
|
333
|
-
five-field module through this same parser and executor. Compiled packages always include `prepare`.
|
|
334
|
-
|
|
335
|
-
`prepareGenerator` normalizes once and either returns `invalid` or a prepared result containing
|
|
336
|
-
`build(context)`. Use that closure inside `engine.build()` so one engine owns modeling, mesh
|
|
337
|
-
validation, limits, measurements and cleanup. `executeGenerator` accepts a context directly and
|
|
338
|
-
returns abstract build output; it does not finalize geometry. Hosts preparing asynchronous services
|
|
339
|
-
first may supply their `/parameters` `PreparedParameters` result as `parameterState` to reuse it.
|
|
340
|
-
|
|
341
|
-
`parseGeneratedParts(parts, limits)` strictly checks the final transferable DTO. The host supplies
|
|
342
|
-
its complete limits; the SDK does not own a duplicate default resource policy. Canonical parts have
|
|
343
|
-
unique IDs, Float32 positions, Uint32 indices and optional six-digit colors. Normals belong to
|
|
344
|
-
viewport presentation. Geometric/manufacturing validation belongs to the shared engine.
|
|
345
|
-
|
|
346
|
-
Package format `1`, runtime major `1`, retired `validate/generate` module exports and extra exports
|
|
347
|
-
reject explicitly. No compatibility adapter or preparation cache remains.
|
|
348
|
-
|
|
349
|
-
Packages using the current modeling operations and Section overloads, `holeCutter()`, or optional
|
|
350
|
-
issue `code`/`path` metadata must declare minimum runtime `2.1.0`. Package format and execution
|
|
351
|
-
protocol major remain `2`. The manifest minimum must cover the host capabilities the package uses.
|
|
352
|
-
|
|
353
|
-
## Worker boundary
|
|
354
|
-
|
|
355
|
-
Worker requests/responses are `/runtime` contracts containing structured data and transferable
|
|
356
|
-
arrays, never live modeling handles. Validation issues are normal outcomes; callback, Worker and
|
|
357
|
-
exporter exceptions use error envelopes. Finalized previews carry revision identity, bounds,
|
|
358
|
-
warnings and optional statistics. Manufacturing exports serialize the requested finalized revision,
|
|
359
|
-
including appearance overrides, without running preparation/build again.
|
|
84
|
+
Both callbacks are synchronous. Load assets beforehand; preparation computes ordinary data, and
|
|
85
|
+
build runs inside the host's Modeling engine. Prepared values stay local to one execution and
|
|
86
|
+
are never persisted or transferred. Studio owns persistence and Worker lifecycle; Modeling owns
|
|
87
|
+
geometry, finalization, and resource cleanup.
|
|
360
88
|
|
|
361
|
-
|
|
362
|
-
captured immediately before transfer. Hosts use `/runtime` `parseGenerationSentAt()` to reject
|
|
363
|
-
missing, inherited, accessor, or nonfinite timestamps before measuring transfer latency. Worker
|
|
364
|
-
clock construction and receiver timings belong to the host.
|
|
89
|
+
## Documentation
|
|
365
90
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
are optional until the host records completion. First draw does not measure GPU completion.
|
|
370
|
-
`totalMs` is request-to-completion elapsed time, including scheduling between stages, rather than
|
|
371
|
-
the sum of stage timings. Studio reports request-to-delivery time until viewport completion.
|
|
91
|
+
Read the [parameters guide](https://github.com/JasonKoolman/metamesh/blob/main/apps/web/content/docs/develop/parameters-and-validation.mdx)
|
|
92
|
+
for controls and validation, or [local authoring](https://github.com/JasonKoolman/metamesh/blob/main/apps/web/content/docs/create/author-locally.mdx)
|
|
93
|
+
for the current Generator workflow. The public documentation site is planned for `metamesh.studio/docs`.
|
|
372
94
|
|
|
373
|
-
|
|
374
|
-
models use the same engine finalization and limits. Studio's runtime contract owns request lifecycle,
|
|
375
|
-
revision retention and export recovery.
|
|
95
|
+
Exact SDK contracts live with their code:
|
|
376
96
|
|
|
377
|
-
|
|
97
|
+
- [Parameter definitions](https://github.com/JasonKoolman/metamesh/blob/main/packages/generator-sdk/src/parameter-contracts.ts),
|
|
98
|
+
[side profiles](https://github.com/JasonKoolman/metamesh/blob/main/packages/generator-sdk/src/side-profiles.ts), and
|
|
99
|
+
[contours](https://github.com/JasonKoolman/metamesh/blob/main/packages/generator-sdk/src/contours.ts).
|
|
100
|
+
- [Authoring helpers](https://github.com/JasonKoolman/metamesh/blob/main/packages/generator-sdk/src/authoring.ts),
|
|
101
|
+
[module contract](https://github.com/JasonKoolman/metamesh/blob/main/packages/generator-sdk/src/generator-module.ts), and
|
|
102
|
+
[runtime execution](https://github.com/JasonKoolman/metamesh/blob/main/packages/generator-sdk/src/execute-generator.ts).
|
|
378
103
|
|
|
379
|
-
|
|
380
|
-
|
|
104
|
+
For maintainers, the [package contract](https://github.com/JasonKoolman/metamesh/blob/main/docs/generator-packages.md)
|
|
105
|
+
owns compatibility and trust; [workspace instructions](https://github.com/JasonKoolman/metamesh/blob/main/packages/generator-sdk/AGENTS.md)
|
|
106
|
+
own contract review and required checks.
|
|
381
107
|
|
|
382
108
|
## License
|
|
383
109
|
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type CurveValueProblem } from "./curve-data.js";
|
|
2
|
+
/** Maximum number of straight or cubic segments in an editable closed cross section. */
|
|
3
|
+
export declare const MAX_CONTOUR_SEGMENTS = 32;
|
|
4
|
+
/** Normalized planar coordinates, with X rightward and Y upward, in the unit square. */
|
|
5
|
+
export interface ContourPoint {
|
|
6
|
+
readonly x: number;
|
|
7
|
+
readonly y: number;
|
|
8
|
+
}
|
|
9
|
+
/** Editing intent accompanies the explicit curve controls; no tangent is inferred at runtime. */
|
|
10
|
+
export interface ContourAnchor extends ContourPoint {
|
|
11
|
+
readonly mode: "smooth" | "corner";
|
|
12
|
+
}
|
|
13
|
+
export type ContourSegment = {
|
|
14
|
+
readonly type: "line";
|
|
15
|
+
readonly end: ContourAnchor;
|
|
16
|
+
} | {
|
|
17
|
+
readonly type: "cubic";
|
|
18
|
+
readonly control1: ContourPoint;
|
|
19
|
+
readonly control2: ContourPoint;
|
|
20
|
+
readonly end: ContourAnchor;
|
|
21
|
+
};
|
|
22
|
+
/** One explicitly closed planar contour. Generators own physical scaling and topology checks. */
|
|
23
|
+
export interface ContourValue {
|
|
24
|
+
readonly version: 1;
|
|
25
|
+
readonly start: ContourAnchor;
|
|
26
|
+
readonly segments: readonly ContourSegment[];
|
|
27
|
+
}
|
|
28
|
+
/** Internal diagnostics share the accessor-safe reader used by predicates and cloning. */
|
|
29
|
+
export declare function contourValueProblem(value: unknown): CurveValueProblem | undefined;
|
|
30
|
+
/** Checks portable data and explicit closure without evaluating getters or inspecting topology. */
|
|
31
|
+
export declare function isContourValue(value: unknown): value is ContourValue;
|
|
32
|
+
/** Returns a fresh, deeply frozen closed contour, including its editing intent. */
|
|
33
|
+
export declare function cloneContourValue(value: ContourValue): ContourValue;
|
|
34
|
+
/** Compares the serialized shape and editing intent rather than object identity. */
|
|
35
|
+
export declare function contourValuesEqual(previous: ContourValue, next: ContourValue): boolean;
|
|
36
|
+
//# sourceMappingURL=contours.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contours.d.ts","sourceRoot":"","sources":["../src/contours.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,iBAAiB,EAEvB,MAAM,iBAAiB,CAAC;AAEzB,wFAAwF;AACxF,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC,wFAAwF;AACxF,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,iGAAiG;AACjG,MAAM,WAAW,aAAc,SAAQ,YAAY;IACjD,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;CACpC;AAED,MAAM,MAAM,cAAc,GACtB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,aAAa,CAAA;CAAE,GACtD;IACE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,GAAG,EAAE,aAAa,CAAC;CAC7B,CAAC;AAEN,iGAAiG;AACjG,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,CAAC;CAC9C;AAmGD,0FAA0F;AAC1F,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,iBAAiB,GAAG,SAAS,CAMjF;AAED,mGAAmG;AACnG,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAEpE;AAED,mFAAmF;AACnF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,GAAG,YAAY,CA0BnE;AAED,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CA4BtF"}
|
|
@@ -1,30 +1,8 @@
|
|
|
1
|
+
import { curveDataObject, curveSegmentCount, } from "./curve-data.js";
|
|
1
2
|
/** Maximum number of straight or cubic segments in an editable closed cross section. */
|
|
2
|
-
export const
|
|
3
|
-
function dataObject(value, expectedKeys, path, fail) {
|
|
4
|
-
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
5
|
-
return fail(path, "type");
|
|
6
|
-
const prototype = Object.getPrototypeOf(value);
|
|
7
|
-
if (prototype !== Object.prototype && prototype !== null)
|
|
8
|
-
return fail(path, "structure");
|
|
9
|
-
const unknown = Reflect.ownKeys(value).find((key) => typeof key !== "string" || !expectedKeys.includes(key));
|
|
10
|
-
if (unknown !== undefined) {
|
|
11
|
-
return fail(typeof unknown === "string" && unknown.length > 0 && unknown.length <= 120
|
|
12
|
-
? [...path, unknown]
|
|
13
|
-
: path, "unknown");
|
|
14
|
-
}
|
|
15
|
-
const entries = [];
|
|
16
|
-
for (const key of expectedKeys) {
|
|
17
|
-
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
18
|
-
if (descriptor === undefined)
|
|
19
|
-
return fail([...path, key], "missing");
|
|
20
|
-
if (!("value" in descriptor) || !descriptor.enumerable)
|
|
21
|
-
return fail([...path, key], "structure");
|
|
22
|
-
entries.push([key, descriptor.value]);
|
|
23
|
-
}
|
|
24
|
-
return Object.fromEntries(entries);
|
|
25
|
-
}
|
|
3
|
+
export const MAX_CONTOUR_SEGMENTS = 32;
|
|
26
4
|
function point(value, anchor, path, fail) {
|
|
27
|
-
const fields =
|
|
5
|
+
const fields = curveDataObject(value, anchor ? ["x", "y", "mode"] : ["x", "y"], path, fail);
|
|
28
6
|
if (fields === undefined)
|
|
29
7
|
return undefined;
|
|
30
8
|
for (const coordinate of ["x", "y"]) {
|
|
@@ -43,13 +21,13 @@ function point(value, anchor, path, fail) {
|
|
|
43
21
|
return fail([...path, "mode"], "choice");
|
|
44
22
|
return { ...coordinates, mode: fields.mode };
|
|
45
23
|
}
|
|
46
|
-
function
|
|
24
|
+
function readContourValue(value, report) {
|
|
47
25
|
const fail = (path, code) => {
|
|
48
26
|
report?.({ path, code });
|
|
49
27
|
return undefined;
|
|
50
28
|
};
|
|
51
29
|
try {
|
|
52
|
-
const fields =
|
|
30
|
+
const fields = curveDataObject(value, ["version", "start", "segments"], [], fail);
|
|
53
31
|
if (fields === undefined)
|
|
54
32
|
return undefined;
|
|
55
33
|
if (fields.version !== 1)
|
|
@@ -60,29 +38,9 @@ function readCrossSectionValue(value, report) {
|
|
|
60
38
|
if (!Array.isArray(fields.segments))
|
|
61
39
|
return fail(["segments"], "type");
|
|
62
40
|
const segments = fields.segments;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (lengthDescriptor === undefined || !("value" in lengthDescriptor))
|
|
67
|
-
return fail(["segments"], "structure");
|
|
68
|
-
const length = lengthDescriptor.value;
|
|
69
|
-
if (typeof length !== "number" ||
|
|
70
|
-
!Number.isInteger(length) ||
|
|
71
|
-
length < 2 ||
|
|
72
|
-
length > MAX_CROSS_SECTION_SEGMENTS)
|
|
73
|
-
return fail(["segments"], "length");
|
|
74
|
-
const keys = Reflect.ownKeys(segments);
|
|
75
|
-
if (keys.length !== length + 1 ||
|
|
76
|
-
!keys.every((key) => key === "length"
|
|
77
|
-
? true
|
|
78
|
-
: typeof key === "string" &&
|
|
79
|
-
Number.isSafeInteger(Number(key)) &&
|
|
80
|
-
Number(key) >= 0 &&
|
|
81
|
-
Number(key) < length &&
|
|
82
|
-
String(Number(key)) === key)) {
|
|
83
|
-
const missingIndex = Array.from({ length }, (_, index) => index).find((index) => !Object.hasOwn(segments, String(index)));
|
|
84
|
-
return fail(missingIndex === undefined ? ["segments"] : ["segments", missingIndex], missingIndex === undefined ? "structure" : "missing");
|
|
85
|
-
}
|
|
41
|
+
const length = curveSegmentCount(segments, 2, MAX_CONTOUR_SEGMENTS, fail);
|
|
42
|
+
if (length === undefined)
|
|
43
|
+
return undefined;
|
|
86
44
|
const parsedSegments = [];
|
|
87
45
|
for (let index = 0; index < length; index += 1) {
|
|
88
46
|
const segmentPath = ["segments", index];
|
|
@@ -100,7 +58,7 @@ function readCrossSectionValue(value, report) {
|
|
|
100
58
|
const type = typeDescriptor.value;
|
|
101
59
|
if (type !== "line" && type !== "cubic")
|
|
102
60
|
return fail([...segmentPath, "type"], "choice");
|
|
103
|
-
const segmentFields =
|
|
61
|
+
const segmentFields = curveDataObject(segment, type === "line" ? ["type", "end"] : ["type", "end", "control1", "control2"], segmentPath, fail);
|
|
104
62
|
if (segmentFields === undefined)
|
|
105
63
|
return undefined;
|
|
106
64
|
if (segmentFields.type !== type)
|
|
@@ -134,20 +92,20 @@ function readCrossSectionValue(value, report) {
|
|
|
134
92
|
}
|
|
135
93
|
}
|
|
136
94
|
/** Internal diagnostics share the accessor-safe reader used by predicates and cloning. */
|
|
137
|
-
export function
|
|
95
|
+
export function contourValueProblem(value) {
|
|
138
96
|
let problem;
|
|
139
|
-
const parsed =
|
|
97
|
+
const parsed = readContourValue(value, (entry) => {
|
|
140
98
|
problem = entry;
|
|
141
99
|
});
|
|
142
100
|
return parsed === undefined ? (problem ?? { code: "structure", path: [] }) : undefined;
|
|
143
101
|
}
|
|
144
102
|
/** Checks portable data and explicit closure without evaluating getters or inspecting topology. */
|
|
145
|
-
export function
|
|
146
|
-
return
|
|
103
|
+
export function isContourValue(value) {
|
|
104
|
+
return readContourValue(value) !== undefined;
|
|
147
105
|
}
|
|
148
106
|
/** Returns a fresh, deeply frozen closed contour, including its editing intent. */
|
|
149
|
-
export function
|
|
150
|
-
const canonical =
|
|
107
|
+
export function cloneContourValue(value) {
|
|
108
|
+
const canonical = readContourValue(value);
|
|
151
109
|
if (canonical === undefined)
|
|
152
110
|
throw new TypeError("Cross section must be a bounded, normalized closed contour.");
|
|
153
111
|
const clonePoint = (entry) => Object.freeze({ x: entry.x, y: entry.y });
|
|
@@ -166,11 +124,11 @@ export function cloneCrossSectionValue(value) {
|
|
|
166
124
|
});
|
|
167
125
|
}
|
|
168
126
|
/** Compares the serialized shape and editing intent rather than object identity. */
|
|
169
|
-
export function
|
|
127
|
+
export function contourValuesEqual(previous, next) {
|
|
170
128
|
if (Object.is(previous, next))
|
|
171
129
|
return true;
|
|
172
|
-
const previousData =
|
|
173
|
-
const nextData =
|
|
130
|
+
const previousData = readContourValue(previous);
|
|
131
|
+
const nextData = readContourValue(next);
|
|
174
132
|
if (previousData === undefined || nextData === undefined)
|
|
175
133
|
return false;
|
|
176
134
|
const pointsEqual = (left, right) => Object.is(left.x, right.x) && Object.is(left.y, right.y);
|
|
@@ -189,4 +147,4 @@ export function crossSectionValuesEqual(previous, next) {
|
|
|
189
147
|
pointsEqual(segment.control2, other.control2)));
|
|
190
148
|
}));
|
|
191
149
|
}
|
|
192
|
-
//# sourceMappingURL=
|
|
150
|
+
//# sourceMappingURL=contours.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contours.js","sourceRoot":"","sources":["../src/contours.ts"],"names":[],"mappings":"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"}
|