@metamesh/generator-sdk 0.9.0 → 0.11.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.
Files changed (120) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +71 -336
  3. package/dist/authoring.d.ts +1 -52
  4. package/dist/authoring.d.ts.map +1 -1
  5. package/dist/authoring.js +0 -24
  6. package/dist/authoring.js.map +1 -1
  7. package/dist/contours.d.ts +36 -0
  8. package/dist/contours.d.ts.map +1 -0
  9. package/dist/{cross-sections.js → contours.js} +19 -61
  10. package/dist/contours.js.map +1 -0
  11. package/dist/contracts.d.ts +30 -11
  12. package/dist/contracts.d.ts.map +1 -1
  13. package/dist/curve-data.d.ts +11 -0
  14. package/dist/curve-data.d.ts.map +1 -0
  15. package/dist/curve-data.js +53 -0
  16. package/dist/curve-data.js.map +1 -0
  17. package/dist/execute-generator.d.ts +14 -23
  18. package/dist/execute-generator.d.ts.map +1 -1
  19. package/dist/execute-generator.js +33 -32
  20. package/dist/execute-generator.js.map +1 -1
  21. package/dist/generated-parts.d.ts +16 -0
  22. package/dist/generated-parts.d.ts.map +1 -1
  23. package/dist/generated-parts.js +155 -67
  24. package/dist/generated-parts.js.map +1 -1
  25. package/dist/generator-module.d.ts +20 -17
  26. package/dist/generator-module.d.ts.map +1 -1
  27. package/dist/generator-module.js +3 -4
  28. package/dist/generator-module.js.map +1 -1
  29. package/dist/generator-package/constants.d.ts +2 -2
  30. package/dist/generator-package/constants.js +2 -2
  31. package/dist/generator-package/errors.d.ts +19 -1
  32. package/dist/generator-package/errors.d.ts.map +1 -1
  33. package/dist/generator-package/errors.js +58 -11
  34. package/dist/generator-package/errors.js.map +1 -1
  35. package/dist/generator-package/index.d.ts +7 -2
  36. package/dist/generator-package/index.d.ts.map +1 -1
  37. package/dist/generator-package/index.js +52 -9
  38. package/dist/generator-package/index.js.map +1 -1
  39. package/dist/generator-package/portable-data.d.ts +12 -0
  40. package/dist/generator-package/portable-data.d.ts.map +1 -0
  41. package/dist/generator-package/portable-data.js +102 -0
  42. package/dist/generator-package/portable-data.js.map +1 -0
  43. package/dist/generator-package/schemas/common.schema.d.ts.map +1 -1
  44. package/dist/generator-package/schemas/common.schema.js +4 -2
  45. package/dist/generator-package/schemas/common.schema.js.map +1 -1
  46. package/dist/generator-package/schemas/definition.schema.d.ts +451 -57
  47. package/dist/generator-package/schemas/definition.schema.d.ts.map +1 -1
  48. package/dist/generator-package/schemas/definition.schema.js +5 -2
  49. package/dist/generator-package/schemas/definition.schema.js.map +1 -1
  50. package/dist/generator-package/schemas/manifest.schema.d.ts +178 -62
  51. package/dist/generator-package/schemas/manifest.schema.d.ts.map +1 -1
  52. package/dist/generator-package/schemas/manifest.schema.js.map +1 -1
  53. package/dist/generator-package/schemas/parameter-document-json-schema.d.ts +4 -0
  54. package/dist/generator-package/schemas/parameter-document-json-schema.d.ts.map +1 -0
  55. package/dist/generator-package/schemas/parameter-document-json-schema.js +17 -0
  56. package/dist/generator-package/schemas/parameter-document-json-schema.js.map +1 -0
  57. package/dist/generator-package/schemas/parameter.schema.d.ts +173 -275
  58. package/dist/generator-package/schemas/parameter.schema.d.ts.map +1 -1
  59. package/dist/generator-package/schemas/parameter.schema.js +169 -79
  60. package/dist/generator-package/schemas/parameter.schema.js.map +1 -1
  61. package/dist/generator-package/schemas/preset.schema.d.ts.map +1 -1
  62. package/dist/generator-package/schemas/preset.schema.js +4 -4
  63. package/dist/generator-package/schemas/preset.schema.js.map +1 -1
  64. package/dist/generator-package/validate-definition.d.ts +4 -7
  65. package/dist/generator-package/validate-definition.d.ts.map +1 -1
  66. package/dist/generator-package/validate-definition.js +210 -272
  67. package/dist/generator-package/validate-definition.js.map +1 -1
  68. package/dist/generator-package/validate-manifest.d.ts.map +1 -1
  69. package/dist/generator-package/validate-manifest.js +5 -10
  70. package/dist/generator-package/validate-manifest.js.map +1 -1
  71. package/dist/index.d.ts +7 -8
  72. package/dist/index.d.ts.map +1 -1
  73. package/dist/index.js +3 -3
  74. package/dist/index.js.map +1 -1
  75. package/dist/parameter-contracts.d.ts +62 -39
  76. package/dist/parameter-contracts.d.ts.map +1 -1
  77. package/dist/parameters/issues.d.ts.map +1 -1
  78. package/dist/parameters/issues.js +9 -10
  79. package/dist/parameters/issues.js.map +1 -1
  80. package/dist/parameters/preparation.d.ts +8 -6
  81. package/dist/parameters/preparation.d.ts.map +1 -1
  82. package/dist/parameters/preparation.js +21 -10
  83. package/dist/parameters/preparation.js.map +1 -1
  84. package/dist/parameters/recovery.d.ts.map +1 -1
  85. package/dist/parameters/recovery.js +11 -12
  86. package/dist/parameters/recovery.js.map +1 -1
  87. package/dist/parameters/strict.d.ts.map +1 -1
  88. package/dist/parameters/strict.js +7 -10
  89. package/dist/parameters/strict.js.map +1 -1
  90. package/dist/parameters/values.d.ts +1 -0
  91. package/dist/parameters/values.d.ts.map +1 -1
  92. package/dist/parameters/values.js +7 -6
  93. package/dist/parameters/values.js.map +1 -1
  94. package/dist/parameters.d.ts +1 -1
  95. package/dist/parameters.d.ts.map +1 -1
  96. package/dist/parameters.js +1 -1
  97. package/dist/parameters.js.map +1 -1
  98. package/dist/parameters.schema.json +1757 -0
  99. package/dist/parse-generator-module.d.ts +5 -27
  100. package/dist/parse-generator-module.d.ts.map +1 -1
  101. package/dist/parse-generator-module.js +29 -96
  102. package/dist/parse-generator-module.js.map +1 -1
  103. package/dist/runtime.d.ts +6 -6
  104. package/dist/runtime.d.ts.map +1 -1
  105. package/dist/runtime.js +3 -3
  106. package/dist/runtime.js.map +1 -1
  107. package/dist/side-profiles.d.ts +36 -0
  108. package/dist/side-profiles.d.ts.map +1 -0
  109. package/dist/{profiles.js → side-profiles.js} +21 -66
  110. package/dist/side-profiles.js.map +1 -0
  111. package/dist/worker-contracts.d.ts +2 -2
  112. package/dist/worker-contracts.d.ts.map +1 -1
  113. package/dist/worker-contracts.js.map +1 -1
  114. package/package.json +7 -7
  115. package/dist/cross-sections.d.ts +0 -41
  116. package/dist/cross-sections.d.ts.map +0 -1
  117. package/dist/cross-sections.js.map +0 -1
  118. package/dist/profiles.d.ts +0 -41
  119. package/dist/profiles.d.ts.map +0 -1
  120. package/dist/profiles.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @metamesh/generator-sdk
2
2
 
3
+ ## 0.11.0
4
+
5
+ ### Minor Changes
6
+
7
+ - b5da778: Replace prepare/build with typed generation programs, optional computed values and authoritative
8
+ part placement. Add isolated session caches and deferred geometry with explicit snapshot ownership.
9
+ Expose immutable fluent Solid and Section methods for transforms, subtraction, finishing, and
10
+ Section-to-Solid construction, replacing the corresponding standalone operations and public
11
+ context facade. Generator packages require format 4 and runtime 4; previous executable contracts are unsupported.
12
+
13
+ ### Patch Changes
14
+
15
+ - d69836c: Update the Generator SDK's runtime validation dependency to Zod 4.6.7.
16
+ - bfb7a63: Keep computed dependencies correct after conditional removal and re-registration, and prevent
17
+ caught evaluation failures from returning earlier cached values. Reduce immutable data copying,
18
+ centralize geometry finalization, and validate newly delivered resources once while preserving
19
+ per-revision part and aggregate resource checks.
20
+
21
+ Replace transparent cached typed arrays with explicit immutableBuffer and immutableMesh capture
22
+ helpers. Cached numeric data exposes length, at(), and copy(); uncaptured typed arrays in computed
23
+ results or bindings now reject. Snapshot and Worker output buffers remain ordinary typed arrays.
24
+
25
+ ## 0.10.0
26
+
27
+ ### Minor Changes
28
+
29
+ - 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.
30
+ - 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.
31
+ - 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.
32
+
3
33
  ## 0.9.0
4
34
 
5
35
  ### Minor Changes
package/README.md CHANGED
@@ -1,43 +1,30 @@
1
1
  # `@metamesh/generator-sdk`
2
2
 
3
- Runtime-neutral contracts and helpers for Generators, hosts, and workers.
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
- The root provides lightweight authoring contracts and helpers with explicit TypeScript interfaces.
15
- It has no Zod, modeling, renderer, browser, or Worker dependencies.
16
- Use the supported subpaths for host responsibilities:
17
-
18
- | Entry | Responsibility |
19
- | ------------- | ------------------------------------------------------------------------------- |
20
- | Root | Definitions, presets, preparation/module authoring, parameter and service types |
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 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
- Parameters use a `type` discriminant: `number`, `slider`, `boolean`, `select`, `choice-set`, `color`,
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
- Define controls once, then normalize saved values or strictly parse boundary values:
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,334 +37,82 @@ 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
40
  ```
59
41
 
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";
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.
72
46
 
73
- const profile = {
74
- id: "profile",
75
- label: "Profile",
76
- type: "svg",
77
- default: EMPTY_SVG_PARAMETER_DEFAULT,
78
- } as const;
79
- ```
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`.
80
51
 
81
- ### Choice sets and arrays
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.
82
57
 
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.
58
+ ## Generate a model
87
59
 
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.
60
+ A Generator exports one format-4 default envelope containing its definition-bound program:
92
61
 
93
62
  ```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
- ```
103
-
104
- Groups are ordered sections with stable IDs, user-facing labels, optional descriptions, and an
105
- optional `collapsed` default. Parameters without a group render in Studio's General section.
106
-
107
- ### Fonts and text
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.
124
-
125
- Per-field constraints belong in the definition. Cross-parameter, warning, manufacturing and geometry
126
- constraints belong in `prepare`, alongside the dimensions and samples that `build` will consume.
127
- A successful result is `{ ok: true, value, issues }`; an invalid result is `{ ok: false, issues }`.
128
- Successful preparation may contain warnings but no errors. Invalid preparation requires an error,
129
- and prevents build and native shape construction.
130
-
131
- Numeric parameters and numeric array items may declare `integer: true`. Their defaults and supplied
132
- bounds must be integers. Strict codecs reject fractions; saved fractions recover to the declared
133
- default. Numeric array recovery replaces the invalid array with its default. `step` only describes
134
- the control increment and does not imply integer values.
135
-
136
- Schema editors receive only the definition and never rewrite validators. Manifests remain
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.
140
-
141
- Issues may include an optional stable `code` and `path` relative to the parameter value, such as
142
- `{ code: "minimum", path: [2] }` for an array item or
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:
282
-
283
- ```ts
284
- import { defineGeneratorModule, definePreparation, prepared } from "@metamesh/generator-sdk";
285
- import { tube } from "@metamesh/modeling";
286
-
287
- const prepareSleeve = definePreparation(definition, (parameters, { invalid }) => {
288
- if (parameters.boreDiameter >= parameters.outerDiameter)
289
- return invalid("boreDiameter", "The bore must be smaller than the outside diameter.");
290
- return prepared({
291
- outerRadius: parameters.outerDiameter / 2,
292
- innerRadius: parameters.boreDiameter / 2,
293
- });
294
- });
295
- const runtime = defineGeneratorModule({
296
- definition,
297
- prepare: prepareSleeve,
298
- build: (dimensions) => tube({ ...dimensions, height: 20 }),
63
+ import { defineGeneratorModule, type GeneratorParams } from "@metamesh/generator-sdk";
64
+ import { generate, tube } from "@metamesh/modeling";
65
+
66
+ const model = generate<GeneratorParams<typeof definition>>(({ params, assert, part }) => {
67
+ assert(
68
+ params.boreDiameter < params.outerDiameter,
69
+ "The bore must be smaller than the outside diameter.",
70
+ { parameterId: "boreDiameter" }
71
+ );
72
+ return [
73
+ part(
74
+ "body",
75
+ tube({
76
+ outerRadius: params.outerDiameter / 2,
77
+ innerRadius: params.boreDiameter / 2,
78
+ height: 20,
79
+ })
80
+ ),
81
+ ];
299
82
  });
300
-
301
- export const { formatVersion, generatorId, version, prepare, build } = runtime;
83
+ export default defineGeneratorModule({ definition, generate: model });
302
84
  ```
303
85
 
304
- `definePreparation(definition, callback)` infers readonly parameter values, prepared data and
305
- `PreparationServices<typeof definition>`. Its second callback argument retains `services.text`
306
- and adds `invalid(parameterId, message)` and `invalid(issue)`, with allowed IDs checked directly at
307
- each argument. Destructure `{ invalid }` or call `services.invalid(...)`. A warning alone cannot
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
86
+ The host normalizes parameters and resolves assets before synchronous generation. Modeling owns
87
+ optional computed caches, deferred recipes, sessions and immutable snapshots; the SDK stays
88
+ renderer-neutral and imports no engine. The [generation contract](https://github.com/JasonKoolman/metamesh/blob/main/docs/model-generation.md)
89
+ owns dependencies, assertions, placement and lifecycle. `/runtime` strictly checks the new default
90
+ envelope and maps engine diagnostics to definition-owned issues. Unsupported package formats are
91
+ rejected before executable bytes are evaluated.
354
92
 
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.
93
+ For incremental Worker deliveries, `/runtime` provides `GeneratedPartsDecoder`. It validates new
94
+ geometry buffers once and hydrates later resource references, while checking part metadata and
95
+ aggregate limits on every delivery. The receiving host keeps admitted buffers immutable and
96
+ attached, and calls `clear()` when replacing the delivery source.
360
97
 
361
- Successful generation envelopes include `sentAt`, the sender's high-resolution epoch milliseconds
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.
98
+ ## Documentation
365
99
 
366
- `ModelTimings.prepareMs` measures Generator preparation; `viewportPrepareMs` measures host viewport
367
- preparation. `firstDrawMs` starts when viewport preparation ends and measures elapsed time through
368
- every part's first draw submission, including render scheduling and buffer upload. Viewport fields
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.
100
+ Read the [parameters guide](https://github.com/JasonKoolman/metamesh/blob/main/apps/web/content/docs/develop/parameters-and-validation.mdx)
101
+ for controls and validation, or [local authoring](https://github.com/JasonKoolman/metamesh/blob/main/apps/web/content/docs/create/author-locally.mdx)
102
+ for the current Generator workflow. The public documentation site is planned for `metamesh.studio/docs`.
372
103
 
373
- `MeshTopologyMode` is host policy rather than a Generator parameter. Both compiled and authored
374
- models use the same engine finalization and limits. Studio's runtime contract owns request lifecycle,
375
- revision retention and export recovery.
104
+ Exact SDK contracts live with their code:
376
105
 
377
- ## Development
106
+ - [Parameter definitions](https://github.com/JasonKoolman/metamesh/blob/main/packages/generator-sdk/src/parameter-contracts.ts),
107
+ [side profiles](https://github.com/JasonKoolman/metamesh/blob/main/packages/generator-sdk/src/side-profiles.ts), and
108
+ [contours](https://github.com/JasonKoolman/metamesh/blob/main/packages/generator-sdk/src/contours.ts).
109
+ - [Authoring helpers](https://github.com/JasonKoolman/metamesh/blob/main/packages/generator-sdk/src/authoring.ts),
110
+ [module contract](https://github.com/JasonKoolman/metamesh/blob/main/packages/generator-sdk/src/generator-module.ts), and
111
+ [runtime execution](https://github.com/JasonKoolman/metamesh/blob/main/packages/generator-sdk/src/execute-generator.ts).
378
112
 
379
- Keep this package independent of React, Zustand, Three.js, Manifold, DOM, and Web Worker APIs.
380
- The [workspace instructions](https://github.com/JasonKoolman/metamesh/blob/main/packages/generator-sdk/AGENTS.md) own contract review and required checks.
113
+ For maintainers, the [package contract](https://github.com/JasonKoolman/metamesh/blob/main/docs/generator-packages.md)
114
+ owns compatibility and trust; [workspace instructions](https://github.com/JasonKoolman/metamesh/blob/main/packages/generator-sdk/AGENTS.md)
115
+ own contract review and required checks.
381
116
 
382
117
  ## License
383
118
 
@@ -1,57 +1,6 @@
1
- import type { GeneratorDefinition, GeneratorIssue, GeneratorParams, GeneratorPreset, ParameterIssue } from "./contracts.js";
2
- import type { Preparation } from "./generator-module.js";
3
- import { type GeneratorServices } from "./generator-services.js";
1
+ import type { GeneratorDefinition, GeneratorPreset } from "./contracts.js";
4
2
  /** Captures literal IDs and options; the host validates serializable metadata. */
5
3
  export declare function defineGenerator<const D extends GeneratorDefinition>(definition: D): D;
6
4
  /** Contextually types complete presets from the same definition as the controls. */
7
5
  export declare function definePresets<const D extends GeneratorDefinition, const Presets extends readonly GeneratorPreset<NoInfer<D>>[]>(_definition: D, presets: Presets): Presets;
8
- /** Successful worker-local preparation. The value is never cloned or inspected. */
9
- export declare function prepared<P>(value: P): {
10
- readonly ok: true;
11
- readonly value: P;
12
- readonly issues: readonly [];
13
- };
14
- /** Failed preparation attributed to a literal parameter ID or an existing error issue. */
15
- export declare function invalid<const Id extends string>(parameterId: Id, message: string): {
16
- readonly ok: false;
17
- readonly issues: readonly [
18
- {
19
- readonly severity: "error";
20
- readonly parameterId: Id;
21
- readonly message: string;
22
- }
23
- ];
24
- };
25
- export declare function invalid<const Issue extends ParameterIssue & {
26
- readonly severity: "error";
27
- }>(issue: Issue): {
28
- readonly ok: false;
29
- readonly issues: readonly [Issue];
30
- };
31
- /** Definition-bound error reporting plus the host's unchanged text service. */
32
- export interface PreparationServices<D extends GeneratorDefinition> extends GeneratorServices {
33
- /** Reports one error using a declared parameter ID or an existing definition-bound issue. */
34
- readonly invalid: {
35
- <const Id extends D["parameters"][number]["id"]>(parameterId: Id, message: string): {
36
- readonly ok: false;
37
- readonly issues: readonly [
38
- {
39
- readonly severity: "error";
40
- readonly parameterId: Id;
41
- readonly message: string;
42
- }
43
- ];
44
- };
45
- <const Issue extends GeneratorIssue<D> & {
46
- readonly severity: "error";
47
- }>(issue: Issue): {
48
- readonly ok: false;
49
- readonly issues: readonly [Issue];
50
- };
51
- };
52
- }
53
- /** Wraps preparation with definition-bound services while preserving its exact result and value. */
54
- export declare function definePreparation<const D extends GeneratorDefinition, Result extends Preparation<NoInfer<D>, unknown>>(_definition: D, callback: (parameters: GeneratorParams<NoInfer<D>>, services: PreparationServices<NoInfer<D>>) => Result): (parameters: GeneratorParams<D>, services?: GeneratorServices) => Result;
55
- /** Parameter-only preparation is useful for models with no derived dimensions. */
56
- export declare function prepareIdentity<const D extends GeneratorDefinition>(_definition: D): (parameters: GeneratorParams<D>) => ReturnType<typeof prepared<GeneratorParams<D>>>;
57
6
  //# sourceMappingURL=authoring.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"authoring.d.ts","sourceRoot":"","sources":["../src/authoring.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"authoring.d.ts","sourceRoot":"","sources":["../src/authoring.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAE3E,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,KAAK,CAAC,CAAC,SAAS,mBAAmB,EAAE,UAAU,EAAE,CAAC,GAAG,CAAC,CAErF;AAED,oFAAoF;AACpF,wBAAgB,aAAa,CAC3B,KAAK,CAAC,CAAC,SAAS,mBAAmB,EACnC,KAAK,CAAC,OAAO,SAAS,SAAS,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,EAC5D,WAAW,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAE3C"}
package/dist/authoring.js CHANGED
@@ -1,4 +1,3 @@
1
- import { UNPREPARED_GENERATOR_SERVICES } from "./generator-services.js";
2
1
  /** Captures literal IDs and options; the host validates serializable metadata. */
3
2
  export function defineGenerator(definition) {
4
3
  return definition;
@@ -7,27 +6,4 @@ export function defineGenerator(definition) {
7
6
  export function definePresets(_definition, presets) {
8
7
  return presets;
9
8
  }
10
- /** Successful worker-local preparation. The value is never cloned or inspected. */
11
- export function prepared(value) {
12
- return { ok: true, value, issues: [] };
13
- }
14
- export function invalid(issueOrId, message) {
15
- if (typeof issueOrId === "string") {
16
- if (typeof message !== "string")
17
- throw new TypeError("Invalid preparation needs an error message.");
18
- return { ok: false, issues: [{ severity: "error", parameterId: issueOrId, message }] };
19
- }
20
- if (issueOrId === null || typeof issueOrId !== "object" || issueOrId.severity !== "error")
21
- throw new TypeError("Invalid preparation requires an error issue.");
22
- return { ok: false, issues: [issueOrId] };
23
- }
24
- /** Wraps preparation with definition-bound services while preserving its exact result and value. */
25
- export function definePreparation(_definition, callback) {
26
- return (parameters, services = UNPREPARED_GENERATOR_SERVICES) => callback(parameters, { ...services, invalid });
27
- }
28
- /** Parameter-only preparation is useful for models with no derived dimensions. */
29
- export function prepareIdentity(_definition) {
30
- void _definition;
31
- return prepared;
32
- }
33
9
  //# sourceMappingURL=authoring.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"authoring.js","sourceRoot":"","sources":["../src/authoring.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,6BAA6B,EAA0B,MAAM,yBAAyB,CAAC;AAEhG,kFAAkF;AAClF,MAAM,UAAU,eAAe,CAAsC,UAAa;IAChF,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,aAAa,CAG3B,WAAc,EAAE,OAAgB;IAChC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,QAAQ,CAAI,KAAQ;IAKlC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;AACzC,CAAC;AAkBD,MAAM,UAAU,OAAO,CACrB,SAAqE,EACrE,OAAgB;IAKhB,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;QAClC,IAAI,OAAO,OAAO,KAAK,QAAQ;YAC7B,MAAM,IAAI,SAAS,CAAC,6CAA6C,CAAC,CAAC;QACrE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;IACzF,CAAC;IACD,IAAI,SAAS,KAAK,IAAI,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,CAAC,QAAQ,KAAK,OAAO;QACvF,MAAM,IAAI,SAAS,CAAC,8CAA8C,CAAC,CAAC;IACtE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC;AAC5C,CAAC;AAwBD,oGAAoG;AACpG,MAAM,UAAU,iBAAiB,CAI/B,WAAc,EACd,QAGW;IAEX,OAAO,CAAC,UAAU,EAAE,QAAQ,GAAG,6BAA6B,EAAE,EAAE,CAC9D,QAAQ,CAAC,UAAU,EAAE,EAAE,GAAG,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;AACnD,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,eAAe,CAC7B,WAAc;IAEd,KAAK,WAAW,CAAC;IACjB,OAAO,QAAQ,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"authoring.js","sourceRoot":"","sources":["../src/authoring.ts"],"names":[],"mappings":"AAEA,kFAAkF;AAClF,MAAM,UAAU,eAAe,CAAsC,UAAa;IAChF,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,aAAa,CAG3B,WAAc,EAAE,OAAgB;IAChC,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -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