@nexart/ui-renderer 0.8.7 → 0.9.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 +458 -0
- package/README.md +196 -269
- package/dist/capabilities.d.ts +1 -1
- package/dist/capabilities.js +2 -2
- package/dist/index.d.ts +36 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +40 -21
- package/dist/preview/code-renderer.d.ts +2 -2
- package/dist/preview/code-renderer.d.ts.map +1 -1
- package/dist/preview/code-renderer.js +9 -17
- package/dist/preview/preview-engine.d.ts +13 -10
- package/dist/preview/preview-engine.d.ts.map +1 -1
- package/dist/preview/preview-engine.js +178 -39
- package/dist/preview/preview-types.d.ts +81 -2
- package/dist/preview/preview-types.d.ts.map +1 -1
- package/dist/preview/preview-types.js +13 -0
- package/examples/basic-preview.ts +92 -0
- package/examples/budget-demo.ts +161 -0
- package/package.json +14 -6
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @nexart/ui-renderer
|
|
2
2
|
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.0
|
|
4
4
|
|
|
5
5
|
**Lightweight Preview Runtime for NexArt Protocol**
|
|
6
6
|
|
|
@@ -19,124 +19,191 @@ Version: 0.8.7
|
|
|
19
19
|
|
|
20
20
|
---
|
|
21
21
|
|
|
22
|
-
##
|
|
23
|
-
|
|
24
|
-
Fixed critical bug where time-varying properties were frozen in loop mode.
|
|
25
|
-
|
|
26
|
-
- **Live binding**: `frameCount`, `t`, `time`, `tGlobal`, `totalFrames` now update every frame
|
|
27
|
-
- **Proxy + with pattern**: Uses a Proxy scope with `with()` for live property access
|
|
28
|
-
- **Animations work**: Sketches see correct values on every frame
|
|
29
|
-
|
|
30
|
-
**Animation Semantics:**
|
|
31
|
-
In loop mode, all time variables update every frame:
|
|
32
|
-
- `frameCount`: Increments each frame
|
|
33
|
-
- `t`: Normalized time `(frameCount % totalFrames) / totalFrames` (range [0,1))
|
|
34
|
-
- `time`: Alias for `t`
|
|
35
|
-
- `tGlobal`: Alias for `t`
|
|
36
|
-
- `totalFrames`: Total frames in the loop (default 120)
|
|
37
|
-
|
|
38
|
-
**Test Sketch:**
|
|
39
|
-
```javascript
|
|
40
|
-
function draw() {
|
|
41
|
-
background(0);
|
|
42
|
-
fill(255);
|
|
43
|
-
circle(
|
|
44
|
-
width / 2 + sin(frameCount * 0.1) * 300,
|
|
45
|
-
height / 2,
|
|
46
|
-
120
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
```
|
|
50
|
-
Expected: Circle moves horizontally, motion is continuous.
|
|
22
|
+
## For AI Coding Agents (Replit / Lovable / Claude Code)
|
|
51
23
|
|
|
52
|
-
|
|
24
|
+
### 20-Second Quickstart
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { createPreviewRuntime } from '@nexart/ui-renderer';
|
|
28
|
+
|
|
29
|
+
const runtime = createPreviewRuntime({
|
|
30
|
+
canvas: document.getElementById('canvas'),
|
|
31
|
+
source: `
|
|
32
|
+
function draw() {
|
|
33
|
+
background(30);
|
|
34
|
+
circle(width/2 + sin(t * TWO_PI) * 200, height/2, 100);
|
|
35
|
+
}
|
|
36
|
+
`,
|
|
37
|
+
mode: 'loop',
|
|
38
|
+
width: 1950,
|
|
39
|
+
height: 2400,
|
|
40
|
+
seed: 12345,
|
|
41
|
+
vars: [50, 75, 25],
|
|
42
|
+
totalFrames: 120,
|
|
43
|
+
onBudgetExceeded: (info) => console.warn('Budget exceeded:', info),
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
runtime.startLoop();
|
|
47
|
+
```
|
|
53
48
|
|
|
54
|
-
|
|
49
|
+
Preview mode may visually differ due to scaling/budgets. For canonical output and verification, run the same code with `@nexart/codemode-sdk`.
|
|
55
50
|
|
|
56
|
-
|
|
51
|
+
### Detecting Preview Mode
|
|
57
52
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
- **Continuous animation**: Loop runs forever until explicitly stopped
|
|
53
|
+
```typescript
|
|
54
|
+
const stats = runtime.getPreviewStats();
|
|
61
55
|
|
|
62
|
-
|
|
56
|
+
if (stats.mode === 'preview') {
|
|
57
|
+
console.log('Running in preview mode');
|
|
58
|
+
console.log('Scale:', stats.scale);
|
|
59
|
+
console.log('Frames:', stats.frames);
|
|
60
|
+
}
|
|
63
61
|
```
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
|
|
63
|
+
### Handling Budget Exceeded
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
const stats = runtime.getPreviewStats();
|
|
67
|
+
|
|
68
|
+
if (stats.budgetExceeded) {
|
|
69
|
+
console.log('Exceeded:', stats.budgetExceeded.reason);
|
|
70
|
+
// Options:
|
|
71
|
+
// 1. Reduce sketch complexity (fewer iterations, simpler shapes)
|
|
72
|
+
// 2. Increase maxFrames or maxTimeMs in config
|
|
73
|
+
// 3. Use @nexart/codemode-sdk for canonical execution
|
|
74
|
+
}
|
|
66
75
|
```
|
|
67
76
|
|
|
68
77
|
---
|
|
69
78
|
|
|
70
|
-
##
|
|
79
|
+
## Preview vs Canonical
|
|
71
80
|
|
|
72
|
-
|
|
81
|
+
| Aspect | Preview (@nexart/ui-renderer) | Canonical (@nexart/codemode-sdk) |
|
|
82
|
+
|--------|-------------------------------|----------------------------------|
|
|
83
|
+
| **Purpose** | Fast browser previews | Authoritative rendering |
|
|
84
|
+
| **Determinism** | Approximate | Guaranteed |
|
|
85
|
+
| **Resolution** | Max 900px | Full resolution (1950×2400) |
|
|
86
|
+
| **FPS** | Native RAF (~60 FPS) | Full frame rate |
|
|
87
|
+
| **Budget** | 1800 frames / 5 min | Unlimited |
|
|
88
|
+
| **Use for** | Editor, dashboard, prototyping | Minting, export, archival |
|
|
73
89
|
|
|
74
|
-
|
|
75
|
-
- **
|
|
76
|
-
- **
|
|
77
|
-
|
|
78
|
-
**Key rule enforced:** Preview scaling is a rendering concern, not a semantic one.
|
|
90
|
+
**Rule of thumb:**
|
|
91
|
+
- Use **ui-renderer** for quick visual feedback during development
|
|
92
|
+
- Use **codemode-sdk** for final output, minting, or any permanent storage
|
|
79
93
|
|
|
80
94
|
---
|
|
81
95
|
|
|
82
|
-
## v0.
|
|
96
|
+
## v0.9.0 — Budget Callbacks + Observability
|
|
83
97
|
|
|
84
|
-
|
|
98
|
+
### New Features
|
|
85
99
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
100
|
+
1. **No more silent stops** — Budget exceeded now triggers callbacks and optional overlay
|
|
101
|
+
2. **getPreviewStats()** — Full observability into runtime state
|
|
102
|
+
3. **createPreviewRuntime()** — Recommended entrypoint for agents
|
|
103
|
+
4. **toCanonicalRequest()** — Handoff helper for @nexart/codemode-sdk
|
|
89
104
|
|
|
90
|
-
|
|
105
|
+
### Budget Configuration
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
const runtime = createPreviewRuntime({
|
|
109
|
+
canvas,
|
|
110
|
+
source: sketchCode,
|
|
111
|
+
mode: 'loop',
|
|
112
|
+
width: 1950,
|
|
113
|
+
height: 2400,
|
|
114
|
+
|
|
115
|
+
// Budget options (all optional)
|
|
116
|
+
maxFrames: 1800, // Max frames before budget exceeded
|
|
117
|
+
maxTimeMs: 300000, // Max time (5 min default)
|
|
118
|
+
budgetBehavior: 'stop', // 'stop' (with overlay) or 'degrade' (skip frames)
|
|
119
|
+
showOverlay: true, // Show overlay when stopped
|
|
120
|
+
|
|
121
|
+
onBudgetExceeded: (info) => {
|
|
122
|
+
console.log('Budget exceeded:', info.reason);
|
|
123
|
+
console.log('Frames:', info.framesRendered);
|
|
124
|
+
console.log('Time:', info.totalTimeMs);
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Preview Stats
|
|
91
130
|
|
|
92
|
-
|
|
131
|
+
```typescript
|
|
132
|
+
const stats = runtime.getPreviewStats();
|
|
133
|
+
// {
|
|
134
|
+
// mode: 'preview',
|
|
135
|
+
// scale: 0.46, // Canvas scale factor
|
|
136
|
+
// semanticWidth: 1950, // Original width (for sketch math)
|
|
137
|
+
// semanticHeight: 2400, // Original height
|
|
138
|
+
// bufferWidth: 897, // Actual canvas width
|
|
139
|
+
// bufferHeight: 900, // Actual canvas height
|
|
140
|
+
// frames: 150, // Frames rendered
|
|
141
|
+
// stride: 1, // Current stride (1 = every frame)
|
|
142
|
+
// totalTimeMs: 18750, // Total time
|
|
143
|
+
// budgetExceeded?: { reason: 'frame_limit' | 'time_limit' }
|
|
144
|
+
// }
|
|
145
|
+
```
|
|
93
146
|
|
|
94
|
-
|
|
147
|
+
### Canonical Handoff
|
|
95
148
|
|
|
96
|
-
|
|
149
|
+
```typescript
|
|
150
|
+
import { toCanonicalRequest } from '@nexart/ui-renderer';
|
|
97
151
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
152
|
+
const config = { canvas, source, mode: 'loop', width: 1950, height: 2400, seed: 12345 };
|
|
153
|
+
const req = toCanonicalRequest(config);
|
|
154
|
+
|
|
155
|
+
// Pass to backend for canonical rendering:
|
|
156
|
+
// await fetch('/api/render', { body: JSON.stringify(req) });
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
---
|
|
103
160
|
|
|
104
|
-
|
|
161
|
+
## Troubleshooting
|
|
105
162
|
|
|
106
|
-
|
|
163
|
+
### "My sketch stops animating"
|
|
164
|
+
|
|
165
|
+
Check `getPreviewStats().budgetExceeded`:
|
|
107
166
|
|
|
108
167
|
```typescript
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
};
|
|
168
|
+
const stats = runtime.getPreviewStats();
|
|
169
|
+
if (stats.budgetExceeded) {
|
|
170
|
+
console.log('Stopped because:', stats.budgetExceeded.reason);
|
|
171
|
+
}
|
|
114
172
|
```
|
|
115
173
|
|
|
116
|
-
|
|
174
|
+
**Solutions:**
|
|
175
|
+
1. Reduce sketch complexity (fewer loop iterations, simpler shapes)
|
|
176
|
+
2. Increase budget: `maxFrames: 3600` or `maxTimeMs: 600000`
|
|
177
|
+
3. Use `budgetBehavior: 'degrade'` to continue at reduced frame rate
|
|
178
|
+
4. For long-running animations, use `@nexart/codemode-sdk`
|
|
117
179
|
|
|
118
|
-
### Canvas
|
|
180
|
+
### "Canvas is too small"
|
|
119
181
|
|
|
120
|
-
Preview
|
|
182
|
+
Preview scales canvases to max 900px for performance:
|
|
121
183
|
|
|
122
184
|
```typescript
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
};
|
|
185
|
+
const stats = runtime.getPreviewStats();
|
|
186
|
+
console.log('Buffer size:', stats.bufferWidth, 'x', stats.bufferHeight);
|
|
187
|
+
console.log('Semantic size:', stats.semanticWidth, 'x', stats.semanticHeight);
|
|
127
188
|
```
|
|
128
189
|
|
|
129
|
-
|
|
190
|
+
Your sketch code sees `width` and `height` as the original values (1950×2400).
|
|
191
|
+
The canvas buffer is scaled down, but your geometry math stays correct.
|
|
130
192
|
|
|
131
|
-
###
|
|
193
|
+
### "Animation looks choppy"
|
|
132
194
|
|
|
133
|
-
|
|
195
|
+
Preview runs at native RAF cadence (~60 FPS). If animations appear choppy:
|
|
134
196
|
|
|
197
|
+
1. Check if budget exceeded (degrade mode skips frames):
|
|
135
198
|
```typescript
|
|
136
|
-
runtime.
|
|
199
|
+
const stats = runtime.getPreviewStats();
|
|
200
|
+
if (stats.budgetExceeded && stats.stride > 1) {
|
|
201
|
+
console.log('Running in degraded mode, skipping frames');
|
|
202
|
+
}
|
|
137
203
|
```
|
|
138
204
|
|
|
139
|
-
|
|
205
|
+
2. Reduce sketch complexity (heavy draw() calls)
|
|
206
|
+
3. Check browser performance (GPU acceleration, tab throttling)
|
|
140
207
|
|
|
141
208
|
---
|
|
142
209
|
|
|
@@ -149,243 +216,103 @@ npm install @nexart/ui-renderer
|
|
|
149
216
|
Or use directly in HTML:
|
|
150
217
|
```html
|
|
151
218
|
<script type="module">
|
|
152
|
-
import {
|
|
219
|
+
import { createPreviewRuntime } from 'https://unpkg.com/@nexart/ui-renderer/dist/index.js';
|
|
153
220
|
</script>
|
|
154
221
|
```
|
|
155
222
|
|
|
156
223
|
---
|
|
157
224
|
|
|
158
|
-
## Quick Start
|
|
159
|
-
|
|
160
|
-
### Code Mode Preview
|
|
161
|
-
|
|
162
|
-
```typescript
|
|
163
|
-
import { createSystem, previewSystem } from '@nexart/ui-renderer';
|
|
164
|
-
|
|
165
|
-
const system = createSystem({
|
|
166
|
-
type: 'code',
|
|
167
|
-
mode: 'loop',
|
|
168
|
-
width: 1950,
|
|
169
|
-
height: 2400,
|
|
170
|
-
totalFrames: 120,
|
|
171
|
-
seed: 12345,
|
|
172
|
-
vars: [50, 75, 25], // VAR[0..9] — values 0-100, padded with zeros
|
|
173
|
-
source: `
|
|
174
|
-
function setup() {
|
|
175
|
-
noFill();
|
|
176
|
-
stroke(0);
|
|
177
|
-
}
|
|
178
|
-
function draw() {
|
|
179
|
-
background(246, 245, 242);
|
|
180
|
-
var count = int(map(VAR[0], 0, 100, 5, 30));
|
|
181
|
-
for (var i = 0; i < count; i++) {
|
|
182
|
-
var x = width / 2 + cos(t * TWO_PI + i * 0.5) * map(VAR[1], 0, 100, 50, 400);
|
|
183
|
-
var y = height / 2 + sin(t * TWO_PI + i * 0.3) * 200;
|
|
184
|
-
ellipse(x, y, 50);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
`
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
const canvas = document.getElementById('canvas');
|
|
191
|
-
const renderer = previewSystem(system, canvas);
|
|
192
|
-
renderer.start();
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
### Static Mode (single frame)
|
|
196
|
-
|
|
197
|
-
```typescript
|
|
198
|
-
const staticSystem = createSystem({
|
|
199
|
-
type: 'code',
|
|
200
|
-
mode: 'static',
|
|
201
|
-
width: 1950,
|
|
202
|
-
height: 2400,
|
|
203
|
-
seed: 12345,
|
|
204
|
-
vars: [50, 50, 50],
|
|
205
|
-
source: `
|
|
206
|
-
function setup() {
|
|
207
|
-
background(246, 245, 242);
|
|
208
|
-
fill(0);
|
|
209
|
-
var count = int(map(VAR[0], 0, 100, 10, 200));
|
|
210
|
-
for (var i = 0; i < count; i++) {
|
|
211
|
-
ellipse(random(width), random(height), random(10, 50));
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
`
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
previewSystem(staticSystem, canvas).render();
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
---
|
|
221
|
-
|
|
222
225
|
## API Reference
|
|
223
226
|
|
|
224
|
-
### `
|
|
227
|
+
### `createPreviewRuntime(config)` ⭐ Recommended
|
|
225
228
|
|
|
226
|
-
Create a
|
|
229
|
+
Create a preview renderer. This is the recommended entrypoint.
|
|
227
230
|
|
|
228
231
|
```typescript
|
|
229
|
-
const
|
|
230
|
-
|
|
232
|
+
const runtime = createPreviewRuntime({
|
|
233
|
+
canvas: HTMLCanvasElement,
|
|
234
|
+
source: string, // p5-like sketch code
|
|
231
235
|
mode: 'static' | 'loop',
|
|
232
236
|
width: number,
|
|
233
237
|
height: number,
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
totalFrames?: number,
|
|
237
|
-
|
|
238
|
+
seed?: number, // PRNG seed
|
|
239
|
+
vars?: number[], // VAR[0..9] (0-100 range)
|
|
240
|
+
totalFrames?: number, // For loop mode (default: 120)
|
|
241
|
+
|
|
242
|
+
// v0.9.0 budget options
|
|
243
|
+
onBudgetExceeded?: (info: BudgetExceededInfo) => void,
|
|
244
|
+
budgetBehavior?: 'stop' | 'degrade',
|
|
245
|
+
showOverlay?: boolean,
|
|
246
|
+
maxFrames?: number,
|
|
247
|
+
maxTimeMs?: number,
|
|
238
248
|
});
|
|
249
|
+
|
|
250
|
+
runtime.startLoop(); // Start animation
|
|
251
|
+
runtime.stopLoop(); // Stop animation
|
|
252
|
+
runtime.renderStatic(); // Render single frame
|
|
253
|
+
runtime.getPreviewStats(); // Get current stats
|
|
254
|
+
runtime.previewScale; // Canvas scale factor
|
|
255
|
+
runtime.destroy(); // Clean up
|
|
239
256
|
```
|
|
240
257
|
|
|
241
|
-
### `previewSystem(system, canvas
|
|
258
|
+
### `createSystem(input)` + `previewSystem(system, canvas)`
|
|
242
259
|
|
|
243
|
-
|
|
260
|
+
Legacy API for declarative systems. Still supported:
|
|
244
261
|
|
|
245
262
|
```typescript
|
|
246
|
-
|
|
247
|
-
|
|
263
|
+
import { createSystem, previewSystem } from '@nexart/ui-renderer';
|
|
264
|
+
|
|
265
|
+
const system = createSystem({
|
|
266
|
+
type: 'code',
|
|
267
|
+
mode: 'loop',
|
|
268
|
+
width: 1950,
|
|
269
|
+
height: 2400,
|
|
270
|
+
source: sketchCode,
|
|
271
|
+
seed: 12345,
|
|
272
|
+
vars: [50, 75, 25],
|
|
248
273
|
});
|
|
249
274
|
|
|
250
|
-
renderer
|
|
251
|
-
renderer.start();
|
|
252
|
-
renderer.stop(); // Stop loop
|
|
253
|
-
renderer.destroy(); // Cleanup
|
|
275
|
+
const renderer = previewSystem(system, canvas);
|
|
276
|
+
renderer.start();
|
|
254
277
|
```
|
|
255
278
|
|
|
256
|
-
### `
|
|
279
|
+
### `toCanonicalRequest(config)`
|
|
257
280
|
|
|
258
|
-
|
|
281
|
+
Generate a request object for handoff to `@nexart/codemode-sdk`:
|
|
259
282
|
|
|
260
283
|
```typescript
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
}
|
|
284
|
+
import { toCanonicalRequest } from '@nexart/ui-renderer';
|
|
285
|
+
|
|
286
|
+
const req = toCanonicalRequest(config);
|
|
287
|
+
// { seed, vars, code, settings, renderer: 'preview', uiRendererVersion }
|
|
265
288
|
```
|
|
266
289
|
|
|
267
290
|
### `getCapabilities()`
|
|
268
291
|
|
|
269
|
-
Discover SDK capabilities
|
|
292
|
+
Discover SDK capabilities:
|
|
270
293
|
|
|
271
294
|
```typescript
|
|
272
295
|
import { getCapabilities } from '@nexart/ui-renderer';
|
|
273
296
|
|
|
274
297
|
const caps = getCapabilities();
|
|
275
|
-
// {
|
|
276
|
-
// version: '0.8.7',
|
|
277
|
-
// isCanonical: false,
|
|
278
|
-
// isArchival: false,
|
|
279
|
-
// previewBudget: { MAX_FRAMES: 30, MAX_TOTAL_TIME_MS: 500, FRAME_STRIDE: 3 },
|
|
280
|
-
// canvasLimits: { MAX_DIMENSION: 900 },
|
|
281
|
-
// ...
|
|
282
|
-
// }
|
|
298
|
+
// { version, isCanonical, previewBudget, canvasLimits, ... }
|
|
283
299
|
```
|
|
284
300
|
|
|
285
301
|
---
|
|
286
302
|
|
|
287
303
|
## Available Helpers
|
|
288
304
|
|
|
289
|
-
The preview runtime includes all standard p5-like functions
|
|
305
|
+
The preview runtime includes all standard p5-like functions:
|
|
290
306
|
|
|
291
307
|
| Helper | Description |
|
|
292
308
|
|--------|-------------|
|
|
293
|
-
| `int(n)` | Convert to integer
|
|
294
|
-
| `fract(n)` | Fractional part
|
|
295
|
-
| `sign(n)` | Sign of number |
|
|
309
|
+
| `int(n)` | Convert to integer |
|
|
310
|
+
| `fract(n)` | Fractional part |
|
|
296
311
|
| `vec(x, y)` | Create 2D vector |
|
|
297
312
|
| `polygon(x, y, r, n)` | Draw n-sided polygon |
|
|
298
313
|
| `star(x, y, r1, r2, n)` | Draw n-pointed star |
|
|
299
314
|
| `fbm(x, y, z, octaves)` | Fractal Brownian motion |
|
|
300
|
-
| `easeIn(t)`, `easeOut(t)
|
|
301
|
-
|
|
302
|
-
### Control Functions
|
|
303
|
-
|
|
304
|
-
| Function | Preview Behavior |
|
|
305
|
-
|----------|------------------|
|
|
306
|
-
| `noLoop()` | Stops preview loop (soft control) |
|
|
307
|
-
| `loop()` | No-op in preview |
|
|
308
|
-
|
|
309
|
-
---
|
|
310
|
-
|
|
311
|
-
## Supported Element Types
|
|
312
|
-
|
|
313
|
-
### `background`
|
|
314
|
-
|
|
315
|
-
Opinionated presets with guardrails.
|
|
316
|
-
|
|
317
|
-
```typescript
|
|
318
|
-
{
|
|
319
|
-
type: 'background',
|
|
320
|
-
style: 'gradient', // gradient, solid, noise, grain
|
|
321
|
-
palette: 'warm' // warm, cool, neutral, vibrant
|
|
322
|
-
}
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
### `primitive`
|
|
326
|
-
|
|
327
|
-
Declarative generative components. **30 primitives available:**
|
|
328
|
-
|
|
329
|
-
**Categories:**
|
|
330
|
-
- `basic` — dots, lines, waves, stripes, circles, grid
|
|
331
|
-
- `geometric` — polygons, diamonds, hexgrid, stars, concentricSquares
|
|
332
|
-
- `radial` — spirals, rays, orbits, rings, arcs, radialLines, petals
|
|
333
|
-
- `flow` — flow, particles, bubbles
|
|
334
|
-
- `patterns` — crosshatch, chevrons, zigzag, weave, moire
|
|
335
|
-
- `organic` — curves, noise, mesh, branches
|
|
336
|
-
|
|
337
|
-
```typescript
|
|
338
|
-
{
|
|
339
|
-
type: 'primitive',
|
|
340
|
-
name: 'spirals',
|
|
341
|
-
count: 12,
|
|
342
|
-
color: '#ffffff',
|
|
343
|
-
motion: 'medium',
|
|
344
|
-
strokeWeight: 'thin',
|
|
345
|
-
opacity: 0.8
|
|
346
|
-
}
|
|
347
|
-
```
|
|
348
|
-
|
|
349
|
-
### `sketch`
|
|
350
|
-
|
|
351
|
-
Raw Code Mode execution.
|
|
352
|
-
|
|
353
|
-
```typescript
|
|
354
|
-
{
|
|
355
|
-
type: 'sketch',
|
|
356
|
-
code: `
|
|
357
|
-
function setup() { background(0); }
|
|
358
|
-
function draw() { ellipse(width/2, height/2, 100); }
|
|
359
|
-
`,
|
|
360
|
-
normalize: true
|
|
361
|
-
}
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
---
|
|
365
|
-
|
|
366
|
-
## VAR Handling (Soft)
|
|
367
|
-
|
|
368
|
-
VAR[0..9] is an array of 10 protocol variables.
|
|
369
|
-
|
|
370
|
-
**Preview behavior (permissive):**
|
|
371
|
-
- Input: 0-10 elements accepted (extras ignored with warning)
|
|
372
|
-
- Values: Clamped to 0-100 (not rejected)
|
|
373
|
-
- Invalid types: Replaced with 0 (not rejected)
|
|
374
|
-
- Runtime: Always 10 elements (padded with zeros)
|
|
375
|
-
- Access: Read-only
|
|
376
|
-
|
|
377
|
-
```typescript
|
|
378
|
-
// Works in preview (clamped to 100)
|
|
379
|
-
vars: [150, 50, 50] // VAR[0] becomes 100
|
|
380
|
-
|
|
381
|
-
// Works in preview (non-numbers become 0)
|
|
382
|
-
vars: ['bad', 50, 50] // VAR[0] becomes 0
|
|
383
|
-
|
|
384
|
-
// Works in preview (extras ignored)
|
|
385
|
-
vars: [1,2,3,4,5,6,7,8,9,10,11,12] // Uses first 10
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
For strict validation, use `@nexart/codemode-sdk`.
|
|
315
|
+
| `easeIn(t)`, `easeOut(t)` | Easing functions |
|
|
389
316
|
|
|
390
317
|
---
|
|
391
318
|
|
|
@@ -396,7 +323,7 @@ For strict validation, use `@nexart/codemode-sdk`.
|
|
|
396
323
|
| Protocol enforcement | No pattern checking or validation errors |
|
|
397
324
|
| Canonical output | Use @nexart/codemode-sdk for minting |
|
|
398
325
|
| Determinism guarantee | Preview may vary slightly |
|
|
399
|
-
| Full frame count | Limited
|
|
326
|
+
| Full frame count | Limited by budget (default 1800 frames) |
|
|
400
327
|
| Full resolution | Limited to 900px max dimension |
|
|
401
328
|
|
|
402
329
|
---
|
package/dist/capabilities.d.ts
CHANGED
package/dist/capabilities.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @nexart/ui-renderer v0.
|
|
2
|
+
* @nexart/ui-renderer v0.9.0 - Capabilities Discovery
|
|
3
3
|
*
|
|
4
4
|
* Exposes SDK capabilities for AI tools and builders.
|
|
5
5
|
* Lightweight preview runtime — no protocol enforcement.
|
|
@@ -58,7 +58,7 @@ function createPrimitive(name, category, description) {
|
|
|
58
58
|
}
|
|
59
59
|
export function getCapabilities() {
|
|
60
60
|
return {
|
|
61
|
-
version: '0.
|
|
61
|
+
version: '0.9.0',
|
|
62
62
|
isCanonical: false,
|
|
63
63
|
isArchival: false,
|
|
64
64
|
renderer: '@nexart/ui-renderer',
|