@nexart/ui-renderer 0.8.8 → 0.9.1
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 +490 -0
- package/README.md +251 -285
- 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/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 +22 -11
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @nexart/ui-renderer - Preview Runtime Types
|
|
3
|
+
* Version: 0.9.0
|
|
3
4
|
*
|
|
4
5
|
* ╔══════════════════════════════════════════════════════════════════════════╗
|
|
5
6
|
* ║ PREVIEW RUNTIME — NON-AUTHORITATIVE ║
|
|
@@ -35,12 +36,42 @@ export declare const CANVAS_LIMITS: {
|
|
|
35
36
|
/** Minimum dimension */
|
|
36
37
|
readonly MIN_DIMENSION: 100;
|
|
37
38
|
};
|
|
39
|
+
/**
|
|
40
|
+
* Preview budget limits (v0.9.0)
|
|
41
|
+
* Enforced optionally to prevent runaway previews.
|
|
42
|
+
*/
|
|
43
|
+
export declare const PREVIEW_BUDGET: {
|
|
44
|
+
/** Maximum frames before budget exceeded (default: 1800) */
|
|
45
|
+
readonly MAX_FRAMES: 1800;
|
|
46
|
+
/** Maximum execution time in ms (default: 5 minutes) */
|
|
47
|
+
readonly MAX_TOTAL_TIME_MS: 300000;
|
|
48
|
+
/** Default stride when degrading (skip every N frames) */
|
|
49
|
+
readonly DEGRADE_STRIDE: 2;
|
|
50
|
+
};
|
|
38
51
|
/**
|
|
39
52
|
* Preview mode options
|
|
40
53
|
*/
|
|
41
54
|
export type PreviewMode = 'static' | 'loop';
|
|
42
55
|
/**
|
|
43
|
-
*
|
|
56
|
+
* Budget exceed reason
|
|
57
|
+
*/
|
|
58
|
+
export type BudgetExceedReason = 'frame_limit' | 'time_limit';
|
|
59
|
+
/**
|
|
60
|
+
* Budget exceeded info (passed to callbacks)
|
|
61
|
+
*/
|
|
62
|
+
export interface BudgetExceededInfo {
|
|
63
|
+
reason: BudgetExceedReason;
|
|
64
|
+
framesRendered: number;
|
|
65
|
+
totalTimeMs: number;
|
|
66
|
+
stride: number;
|
|
67
|
+
scale: number;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Budget behavior options
|
|
71
|
+
*/
|
|
72
|
+
export type BudgetBehavior = 'degrade' | 'stop';
|
|
73
|
+
/**
|
|
74
|
+
* Preview engine configuration (v0.9.0)
|
|
44
75
|
*/
|
|
45
76
|
export interface PreviewEngineConfig {
|
|
46
77
|
/** Canvas element to render to */
|
|
@@ -59,6 +90,34 @@ export interface PreviewEngineConfig {
|
|
|
59
90
|
vars?: number[];
|
|
60
91
|
/** Total frames for loop mode (for t calculation) */
|
|
61
92
|
totalFrames?: number;
|
|
93
|
+
/** Callback when budget is exceeded */
|
|
94
|
+
onBudgetExceeded?: (info: BudgetExceededInfo) => void;
|
|
95
|
+
/** Behavior when budget exceeded: 'degrade' (skip frames) or 'stop' (halt + overlay) */
|
|
96
|
+
budgetBehavior?: BudgetBehavior;
|
|
97
|
+
/** Show overlay when budget exceeded (default: true for 'stop' behavior) */
|
|
98
|
+
showOverlay?: boolean;
|
|
99
|
+
/** Maximum frames before budget exceeded (default: 1800) */
|
|
100
|
+
maxFrames?: number;
|
|
101
|
+
/** Maximum execution time in ms (default: 300000) */
|
|
102
|
+
maxTimeMs?: number;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Preview stats (v0.9.0)
|
|
106
|
+
* Exposes runtime state for observability.
|
|
107
|
+
*/
|
|
108
|
+
export interface PreviewStats {
|
|
109
|
+
mode: 'preview';
|
|
110
|
+
scale: number;
|
|
111
|
+
semanticWidth: number;
|
|
112
|
+
semanticHeight: number;
|
|
113
|
+
bufferWidth: number;
|
|
114
|
+
bufferHeight: number;
|
|
115
|
+
frames: number;
|
|
116
|
+
stride: number;
|
|
117
|
+
totalTimeMs: number;
|
|
118
|
+
budgetExceeded?: {
|
|
119
|
+
reason: BudgetExceedReason;
|
|
120
|
+
};
|
|
62
121
|
}
|
|
63
122
|
/**
|
|
64
123
|
* Preview render result
|
|
@@ -78,7 +137,7 @@ export interface PreviewRenderResult {
|
|
|
78
137
|
errorMessage?: string;
|
|
79
138
|
}
|
|
80
139
|
/**
|
|
81
|
-
* Preview renderer interface
|
|
140
|
+
* Preview renderer interface (v0.9.0)
|
|
82
141
|
*/
|
|
83
142
|
export interface PreviewRenderer {
|
|
84
143
|
/** Render a single frame (static mode) */
|
|
@@ -91,6 +150,10 @@ export interface PreviewRenderer {
|
|
|
91
150
|
destroy: () => void;
|
|
92
151
|
/** Check if currently rendering */
|
|
93
152
|
isRendering: () => boolean;
|
|
153
|
+
/** Get current preview stats (v0.9.0) */
|
|
154
|
+
getPreviewStats: () => PreviewStats;
|
|
155
|
+
/** Current scale factor (v0.9.0) */
|
|
156
|
+
readonly previewScale: number;
|
|
94
157
|
/** This renderer is NOT canonical */
|
|
95
158
|
readonly isCanonical: false;
|
|
96
159
|
/** This renderer is NOT archival */
|
|
@@ -103,4 +166,20 @@ export interface FpsThrottleState {
|
|
|
103
166
|
/** Timestamp of last rendered frame */
|
|
104
167
|
lastFrameTimeMs: number;
|
|
105
168
|
}
|
|
169
|
+
/**
|
|
170
|
+
* Canonical request for handoff to @nexart/codemode-sdk (v0.9.0)
|
|
171
|
+
*/
|
|
172
|
+
export interface CanonicalRequest {
|
|
173
|
+
seed: number;
|
|
174
|
+
vars: number[];
|
|
175
|
+
code: string;
|
|
176
|
+
settings?: {
|
|
177
|
+
width: number;
|
|
178
|
+
height: number;
|
|
179
|
+
mode: PreviewMode;
|
|
180
|
+
totalFrames?: number;
|
|
181
|
+
};
|
|
182
|
+
renderer: 'preview';
|
|
183
|
+
uiRendererVersion: string;
|
|
184
|
+
}
|
|
106
185
|
//# sourceMappingURL=preview-types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preview-types.d.ts","sourceRoot":"","sources":["../../src/preview/preview-types.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"preview-types.d.ts","sourceRoot":"","sources":["../../src/preview/preview-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @nexart/ui-renderer - Preview Runtime Types
|
|
3
|
+
* Version: 0.9.0
|
|
3
4
|
*
|
|
4
5
|
* ╔══════════════════════════════════════════════════════════════════════════╗
|
|
5
6
|
* ║ PREVIEW RUNTIME — NON-AUTHORITATIVE ║
|
|
@@ -30,3 +31,15 @@ export const CANVAS_LIMITS = {
|
|
|
30
31
|
/** Minimum dimension */
|
|
31
32
|
MIN_DIMENSION: 100,
|
|
32
33
|
};
|
|
34
|
+
/**
|
|
35
|
+
* Preview budget limits (v0.9.0)
|
|
36
|
+
* Enforced optionally to prevent runaway previews.
|
|
37
|
+
*/
|
|
38
|
+
export const PREVIEW_BUDGET = {
|
|
39
|
+
/** Maximum frames before budget exceeded (default: 1800) */
|
|
40
|
+
MAX_FRAMES: 1800, // ~30 seconds at 60 FPS
|
|
41
|
+
/** Maximum execution time in ms (default: 5 minutes) */
|
|
42
|
+
MAX_TOTAL_TIME_MS: 300000, // 5 minutes
|
|
43
|
+
/** Default stride when degrading (skip every N frames) */
|
|
44
|
+
DEGRADE_STRIDE: 2,
|
|
45
|
+
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nexart/ui-renderer - Basic Preview Example
|
|
3
|
+
*
|
|
4
|
+
* Demonstrates basic usage of createPreviewRuntime with stats logging.
|
|
5
|
+
*
|
|
6
|
+
* Run with: npm run example:basic
|
|
7
|
+
*
|
|
8
|
+
* Note: This example is designed for browser environments.
|
|
9
|
+
* In Node.js, it will print the expected usage pattern.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
console.log(`
|
|
13
|
+
╔══════════════════════════════════════════════════════════════════════════╗
|
|
14
|
+
║ @nexart/ui-renderer - Basic Preview Example ║
|
|
15
|
+
╚══════════════════════════════════════════════════════════════════════════╝
|
|
16
|
+
|
|
17
|
+
This example shows how to use createPreviewRuntime in a browser environment.
|
|
18
|
+
|
|
19
|
+
BROWSER CODE:
|
|
20
|
+
─────────────────────────────────────────────────────────────────────────────
|
|
21
|
+
|
|
22
|
+
import { createPreviewRuntime } from '@nexart/ui-renderer';
|
|
23
|
+
|
|
24
|
+
// Create a canvas element
|
|
25
|
+
const canvas = document.getElementById('preview-canvas');
|
|
26
|
+
|
|
27
|
+
// Create the preview runtime
|
|
28
|
+
const runtime = createPreviewRuntime({
|
|
29
|
+
canvas,
|
|
30
|
+
source: \`
|
|
31
|
+
function setup() {
|
|
32
|
+
noFill();
|
|
33
|
+
stroke(0);
|
|
34
|
+
}
|
|
35
|
+
function draw() {
|
|
36
|
+
background(246, 245, 242);
|
|
37
|
+
var count = int(map(VAR[0], 0, 100, 5, 30));
|
|
38
|
+
for (var i = 0; i < count; i++) {
|
|
39
|
+
var x = width / 2 + cos(t * TWO_PI + i * 0.5) * 300;
|
|
40
|
+
var y = height / 2 + sin(t * TWO_PI + i * 0.3) * 200;
|
|
41
|
+
ellipse(x, y, 50);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
\`,
|
|
45
|
+
mode: 'loop',
|
|
46
|
+
width: 1950,
|
|
47
|
+
height: 2400,
|
|
48
|
+
seed: 12345,
|
|
49
|
+
vars: [50, 75, 25],
|
|
50
|
+
totalFrames: 120,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Start the animation
|
|
54
|
+
runtime.startLoop();
|
|
55
|
+
|
|
56
|
+
// Log stats every second
|
|
57
|
+
setInterval(() => {
|
|
58
|
+
const stats = runtime.getPreviewStats();
|
|
59
|
+
console.log('Preview Stats:', {
|
|
60
|
+
mode: stats.mode,
|
|
61
|
+
scale: stats.scale.toFixed(2),
|
|
62
|
+
frames: stats.frames,
|
|
63
|
+
stride: stats.stride,
|
|
64
|
+
totalTimeMs: Math.round(stats.totalTimeMs),
|
|
65
|
+
budgetExceeded: stats.budgetExceeded ?? 'no',
|
|
66
|
+
});
|
|
67
|
+
}, 1000);
|
|
68
|
+
|
|
69
|
+
// Stop after 10 seconds
|
|
70
|
+
setTimeout(() => {
|
|
71
|
+
runtime.stopLoop();
|
|
72
|
+
console.log('Preview stopped');
|
|
73
|
+
}, 10000);
|
|
74
|
+
|
|
75
|
+
─────────────────────────────────────────────────────────────────────────────
|
|
76
|
+
|
|
77
|
+
KEY POINTS:
|
|
78
|
+
- Use createPreviewRuntime (recommended) or createPreviewEngine
|
|
79
|
+
- mode: 'loop' for animations, 'static' for single frame
|
|
80
|
+
- Check getPreviewStats() to monitor budget and performance
|
|
81
|
+
- Preview is NOT canonical — use @nexart/codemode-sdk for minting
|
|
82
|
+
`);
|
|
83
|
+
|
|
84
|
+
// Demonstrate API shape (Node.js compatible)
|
|
85
|
+
import { SDK_VERSION, PREVIEW_BUDGET, CANVAS_LIMITS } from '../src/index';
|
|
86
|
+
|
|
87
|
+
console.log('SDK Configuration:');
|
|
88
|
+
console.log(' Version:', SDK_VERSION);
|
|
89
|
+
console.log(' FPS: Native RAF (~60 FPS)');
|
|
90
|
+
console.log(' Max Dimension:', CANVAS_LIMITS.MAX_DIMENSION + 'px');
|
|
91
|
+
console.log(' Max Frames:', PREVIEW_BUDGET.MAX_FRAMES);
|
|
92
|
+
console.log(' Max Time:', PREVIEW_BUDGET.MAX_TOTAL_TIME_MS / 1000 + 's');
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nexart/ui-renderer - Budget Demo Example
|
|
3
|
+
*
|
|
4
|
+
* Demonstrates budget exceed handling with callbacks and overlay.
|
|
5
|
+
*
|
|
6
|
+
* Run with: npm run example:budget
|
|
7
|
+
*
|
|
8
|
+
* Note: This example is designed for browser environments.
|
|
9
|
+
* In Node.js, it will print the expected usage pattern.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
console.log(`
|
|
13
|
+
╔══════════════════════════════════════════════════════════════════════════╗
|
|
14
|
+
║ @nexart/ui-renderer - Budget Demo Example ║
|
|
15
|
+
╚══════════════════════════════════════════════════════════════════════════╝
|
|
16
|
+
|
|
17
|
+
This example shows how to handle budget exceeded events.
|
|
18
|
+
|
|
19
|
+
BROWSER CODE (with 'stop' behavior):
|
|
20
|
+
─────────────────────────────────────────────────────────────────────────────
|
|
21
|
+
|
|
22
|
+
import { createPreviewRuntime } from '@nexart/ui-renderer';
|
|
23
|
+
|
|
24
|
+
const canvas = document.getElementById('preview-canvas');
|
|
25
|
+
|
|
26
|
+
// Heavy sketch that will exceed budget quickly
|
|
27
|
+
const heavySketch = \`
|
|
28
|
+
function draw() {
|
|
29
|
+
background(30);
|
|
30
|
+
for (var i = 0; i < 10000; i++) {
|
|
31
|
+
var x = random(width);
|
|
32
|
+
var y = random(height);
|
|
33
|
+
stroke(random(255), random(255), random(255), 50);
|
|
34
|
+
point(x, y);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
\`;
|
|
38
|
+
|
|
39
|
+
const runtime = createPreviewRuntime({
|
|
40
|
+
canvas,
|
|
41
|
+
source: heavySketch,
|
|
42
|
+
mode: 'loop',
|
|
43
|
+
width: 1950,
|
|
44
|
+
height: 2400,
|
|
45
|
+
|
|
46
|
+
// Budget configuration
|
|
47
|
+
maxFrames: 100, // Low frame limit for demo
|
|
48
|
+
maxTimeMs: 10000, // 10 second time limit
|
|
49
|
+
budgetBehavior: 'stop', // 'stop' or 'degrade'
|
|
50
|
+
showOverlay: true, // Show overlay when stopped
|
|
51
|
+
|
|
52
|
+
// Callback when budget is exceeded
|
|
53
|
+
onBudgetExceeded: (info) => {
|
|
54
|
+
console.log('⚠️ Budget exceeded!');
|
|
55
|
+
console.log(' Reason:', info.reason);
|
|
56
|
+
console.log(' Frames rendered:', info.framesRendered);
|
|
57
|
+
console.log(' Total time:', Math.round(info.totalTimeMs) + 'ms');
|
|
58
|
+
console.log(' Scale:', info.scale.toFixed(2));
|
|
59
|
+
console.log(' Stride:', info.stride);
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
runtime.startLoop();
|
|
64
|
+
|
|
65
|
+
─────────────────────────────────────────────────────────────────────────────
|
|
66
|
+
|
|
67
|
+
BROWSER CODE (with 'degrade' behavior):
|
|
68
|
+
─────────────────────────────────────────────────────────────────────────────
|
|
69
|
+
|
|
70
|
+
const runtime = createPreviewRuntime({
|
|
71
|
+
canvas,
|
|
72
|
+
source: heavySketch,
|
|
73
|
+
mode: 'loop',
|
|
74
|
+
width: 1950,
|
|
75
|
+
height: 2400,
|
|
76
|
+
|
|
77
|
+
budgetBehavior: 'degrade', // Continue running but skip frames
|
|
78
|
+
maxFrames: 100,
|
|
79
|
+
|
|
80
|
+
onBudgetExceeded: (info) => {
|
|
81
|
+
console.log('Budget exceeded, now skipping every 2nd frame');
|
|
82
|
+
// Preview continues but at reduced frame rate
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
─────────────────────────────────────────────────────────────────────────────
|
|
87
|
+
|
|
88
|
+
CHECKING STATS:
|
|
89
|
+
─────────────────────────────────────────────────────────────────────────────
|
|
90
|
+
|
|
91
|
+
const stats = runtime.getPreviewStats();
|
|
92
|
+
|
|
93
|
+
if (stats.budgetExceeded) {
|
|
94
|
+
console.log('Preview was stopped due to:', stats.budgetExceeded.reason);
|
|
95
|
+
|
|
96
|
+
// Options:
|
|
97
|
+
// 1. Reduce sketch complexity
|
|
98
|
+
// 2. Increase budget limits
|
|
99
|
+
// 3. Use @nexart/codemode-sdk for canonical execution
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
─────────────────────────────────────────────────────────────────────────────
|
|
103
|
+
|
|
104
|
+
HANDOFF TO CANONICAL:
|
|
105
|
+
─────────────────────────────────────────────────────────────────────────────
|
|
106
|
+
|
|
107
|
+
import { toCanonicalRequest } from '@nexart/ui-renderer';
|
|
108
|
+
|
|
109
|
+
const config = {
|
|
110
|
+
canvas,
|
|
111
|
+
source: sketchCode,
|
|
112
|
+
mode: 'loop',
|
|
113
|
+
width: 1950,
|
|
114
|
+
height: 2400,
|
|
115
|
+
seed: 12345,
|
|
116
|
+
vars: [50, 75, 25],
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
// Get canonical request for @nexart/codemode-sdk
|
|
120
|
+
const canonicalReq = toCanonicalRequest(config);
|
|
121
|
+
console.log('Canonical request:', canonicalReq);
|
|
122
|
+
// {
|
|
123
|
+
// seed: 12345,
|
|
124
|
+
// vars: [50, 75, 25],
|
|
125
|
+
// code: "...",
|
|
126
|
+
// settings: { width: 1950, height: 2400, mode: 'loop' },
|
|
127
|
+
// renderer: 'preview',
|
|
128
|
+
// uiRendererVersion: '0.9.0'
|
|
129
|
+
// }
|
|
130
|
+
|
|
131
|
+
// Pass to backend or use @nexart/codemode-sdk directly:
|
|
132
|
+
// import { createRuntime } from '@nexart/codemode-sdk';
|
|
133
|
+
// const runtime = createRuntime({ seed, vars, mode });
|
|
134
|
+
|
|
135
|
+
─────────────────────────────────────────────────────────────────────────────
|
|
136
|
+
`);
|
|
137
|
+
|
|
138
|
+
// Demonstrate API shape (Node.js compatible)
|
|
139
|
+
import { SDK_VERSION, PREVIEW_BUDGET, toCanonicalRequest, type PreviewEngineConfig } from '../src/index';
|
|
140
|
+
|
|
141
|
+
console.log('Budget Configuration:');
|
|
142
|
+
console.log(' Max Frames:', PREVIEW_BUDGET.MAX_FRAMES);
|
|
143
|
+
console.log(' Max Time:', PREVIEW_BUDGET.MAX_TOTAL_TIME_MS / 1000 + 's');
|
|
144
|
+
console.log(' Degrade Stride:', PREVIEW_BUDGET.DEGRADE_STRIDE);
|
|
145
|
+
|
|
146
|
+
console.log('');
|
|
147
|
+
console.log('toCanonicalRequest example output:');
|
|
148
|
+
|
|
149
|
+
const mockConfig = {
|
|
150
|
+
canvas: null as any,
|
|
151
|
+
source: 'function draw() { circle(100, 100, 50); }',
|
|
152
|
+
mode: 'loop' as const,
|
|
153
|
+
width: 1950,
|
|
154
|
+
height: 2400,
|
|
155
|
+
seed: 12345,
|
|
156
|
+
vars: [50, 75, 25],
|
|
157
|
+
totalFrames: 120,
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const canonical = toCanonicalRequest(mockConfig);
|
|
161
|
+
console.log(JSON.stringify(canonical, null, 2));
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nexart/ui-renderer",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.9.1",
|
|
4
|
+
"description": "Browser-first bounded generative renderer for safe, fast, interactive visuals. Resolution scaling, frame budgets, observable state.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/index.js",
|
|
@@ -14,32 +14,43 @@
|
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
16
|
"files": [
|
|
17
|
-
"dist"
|
|
17
|
+
"dist",
|
|
18
|
+
"examples",
|
|
19
|
+
"README.md",
|
|
20
|
+
"CHANGELOG.md"
|
|
18
21
|
],
|
|
19
22
|
"scripts": {
|
|
20
23
|
"build": "tsc",
|
|
21
|
-
"prepublishOnly": "npm run build"
|
|
24
|
+
"prepublishOnly": "npm run build",
|
|
25
|
+
"example:basic": "npx tsx examples/basic-preview.ts",
|
|
26
|
+
"example:budget": "npx tsx examples/budget-demo.ts",
|
|
27
|
+
"test": "npm run build && node --test dist/*.test.js 2>/dev/null || echo 'No tests yet'"
|
|
22
28
|
},
|
|
23
29
|
"dependencies": {
|
|
24
|
-
"@nexart/codemode-sdk": "^1.
|
|
30
|
+
"@nexart/codemode-sdk": "^1.8.0"
|
|
25
31
|
},
|
|
26
32
|
"devDependencies": {
|
|
27
33
|
"typescript": "^5.0.0"
|
|
28
34
|
},
|
|
29
35
|
"keywords": [
|
|
30
|
-
"
|
|
31
|
-
"
|
|
36
|
+
"generative",
|
|
37
|
+
"renderer",
|
|
32
38
|
"canvas",
|
|
39
|
+
"creative-coding",
|
|
40
|
+
"preview",
|
|
41
|
+
"sandbox",
|
|
42
|
+
"bounded",
|
|
43
|
+
"runtime",
|
|
44
|
+
"miniapp",
|
|
33
45
|
"browser",
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"authoring",
|
|
37
|
-
"preview"
|
|
46
|
+
"deterministic",
|
|
47
|
+
"ai-agent"
|
|
38
48
|
],
|
|
39
49
|
"repository": {
|
|
40
50
|
"type": "git",
|
|
41
51
|
"url": "https://github.com/artnames/nexart-ui-renderer.git"
|
|
42
52
|
},
|
|
53
|
+
"homepage": "https://github.com/artnames/nexart-ui-renderer#readme",
|
|
43
54
|
"author": "NexArt",
|
|
44
55
|
"publishConfig": {
|
|
45
56
|
"access": "public"
|