@nexart/codemode-sdk 1.1.1 → 1.4.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/README.md +121 -238
- package/dist/engine.d.ts +1 -1
- package/dist/engine.js +1 -1
- package/dist/index.d.ts +19 -27
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -34
- package/dist/loop-engine.d.ts +1 -4
- package/dist/loop-engine.d.ts.map +1 -1
- package/dist/loop-engine.js +12 -17
- package/dist/p5-runtime.d.ts +4 -56
- package/dist/p5-runtime.d.ts.map +1 -1
- package/dist/p5-runtime.js +22 -348
- package/dist/static-engine.d.ts +1 -4
- package/dist/static-engine.d.ts.map +1 -1
- package/dist/static-engine.js +10 -14
- package/dist/types.d.ts +7 -7
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +3 -3
- package/package.json +17 -23
- package/CHANGELOG.md +0 -109
- package/CODE_MODE_PROTOCOL.md +0 -312
- package/dist/core-index.d.ts +0 -21
- package/dist/core-index.d.ts.map +0 -1
- package/dist/core-index.js +0 -26
- package/dist/execute.d.ts +0 -46
- package/dist/execute.d.ts.map +0 -1
- package/dist/execute.js +0 -268
- package/dist/noise-bridge.d.ts +0 -44
- package/dist/noise-bridge.d.ts.map +0 -1
- package/dist/noise-bridge.js +0 -68
- package/dist/noise-engine.d.ts +0 -74
- package/dist/noise-engine.d.ts.map +0 -1
- package/dist/noise-engine.js +0 -132
- package/dist/noise-sketches/fractalNoise.d.ts +0 -11
- package/dist/noise-sketches/fractalNoise.d.ts.map +0 -1
- package/dist/noise-sketches/fractalNoise.js +0 -121
- package/dist/noise-sketches/index.d.ts +0 -21
- package/dist/noise-sketches/index.d.ts.map +0 -1
- package/dist/noise-sketches/index.js +0 -28
- package/dist/sound-bridge.d.ts +0 -89
- package/dist/sound-bridge.d.ts.map +0 -1
- package/dist/sound-bridge.js +0 -128
- package/dist/soundart-engine.d.ts +0 -87
- package/dist/soundart-engine.d.ts.map +0 -1
- package/dist/soundart-engine.js +0 -173
- package/dist/soundart-sketches/chladniBloom.d.ts +0 -3
- package/dist/soundart-sketches/chladniBloom.d.ts.map +0 -1
- package/dist/soundart-sketches/chladniBloom.js +0 -53
- package/dist/soundart-sketches/dualVortex.d.ts +0 -3
- package/dist/soundart-sketches/dualVortex.d.ts.map +0 -1
- package/dist/soundart-sketches/dualVortex.js +0 -67
- package/dist/soundart-sketches/geometryIllusion.d.ts +0 -3
- package/dist/soundart-sketches/geometryIllusion.d.ts.map +0 -1
- package/dist/soundart-sketches/geometryIllusion.js +0 -89
- package/dist/soundart-sketches/index.d.ts +0 -39
- package/dist/soundart-sketches/index.d.ts.map +0 -1
- package/dist/soundart-sketches/index.js +0 -72
- package/dist/soundart-sketches/isoflow.d.ts +0 -3
- package/dist/soundart-sketches/isoflow.d.ts.map +0 -1
- package/dist/soundart-sketches/isoflow.js +0 -60
- package/dist/soundart-sketches/loomWeave.d.ts +0 -3
- package/dist/soundart-sketches/loomWeave.d.ts.map +0 -1
- package/dist/soundart-sketches/loomWeave.js +0 -59
- package/dist/soundart-sketches/noiseTerraces.d.ts +0 -3
- package/dist/soundart-sketches/noiseTerraces.d.ts.map +0 -1
- package/dist/soundart-sketches/noiseTerraces.js +0 -53
- package/dist/soundart-sketches/orb.d.ts +0 -3
- package/dist/soundart-sketches/orb.d.ts.map +0 -1
- package/dist/soundart-sketches/orb.js +0 -50
- package/dist/soundart-sketches/pixelGlyphs.d.ts +0 -3
- package/dist/soundart-sketches/pixelGlyphs.d.ts.map +0 -1
- package/dist/soundart-sketches/pixelGlyphs.js +0 -72
- package/dist/soundart-sketches/prismFlowFields.d.ts +0 -3
- package/dist/soundart-sketches/prismFlowFields.d.ts.map +0 -1
- package/dist/soundart-sketches/prismFlowFields.js +0 -51
- package/dist/soundart-sketches/radialBurst.d.ts +0 -3
- package/dist/soundart-sketches/radialBurst.d.ts.map +0 -1
- package/dist/soundart-sketches/radialBurst.js +0 -60
- package/dist/soundart-sketches/resonantSoundBodies.d.ts +0 -3
- package/dist/soundart-sketches/resonantSoundBodies.d.ts.map +0 -1
- package/dist/soundart-sketches/resonantSoundBodies.js +0 -89
- package/dist/soundart-sketches/rings.d.ts +0 -11
- package/dist/soundart-sketches/rings.d.ts.map +0 -1
- package/dist/soundart-sketches/rings.js +0 -89
- package/dist/soundart-sketches/squares.d.ts +0 -3
- package/dist/soundart-sketches/squares.d.ts.map +0 -1
- package/dist/soundart-sketches/squares.js +0 -52
- package/dist/soundart-sketches/waveStripes.d.ts +0 -3
- package/dist/soundart-sketches/waveStripes.d.ts.map +0 -1
- package/dist/soundart-sketches/waveStripes.js +0 -44
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* NexArt Code Mode Runtime SDK
|
|
3
|
-
* Version: 1.
|
|
3
|
+
* Version: 1.4.0 (Protocol v1.2.0)
|
|
4
4
|
*
|
|
5
5
|
* ╔══════════════════════════════════════════════════════════════════════════╗
|
|
6
6
|
* ║ @nexart/codemode-sdk — Canonical Code Mode Authority ║
|
|
@@ -10,46 +10,31 @@
|
|
|
10
10
|
* ║ ║
|
|
11
11
|
* ║ Protocol: nexart ║
|
|
12
12
|
* ║ Engine: codemode ║
|
|
13
|
-
* ║ SDK Version: 1.
|
|
14
|
-
* ║ Protocol Version: 1.
|
|
15
|
-
* ║ Phase:
|
|
13
|
+
* ║ SDK Version: 1.4.0 ║
|
|
14
|
+
* ║ Protocol Version: 1.2.0 ║
|
|
15
|
+
* ║ Phase: 3 ║
|
|
16
16
|
* ║ Enforcement: HARD ║
|
|
17
17
|
* ╚══════════════════════════════════════════════════════════════════════════╝
|
|
18
18
|
*
|
|
19
19
|
* @example
|
|
20
20
|
* ```typescript
|
|
21
|
-
* import {
|
|
21
|
+
* import { createEngine } from '@nexart/codemode-sdk';
|
|
22
22
|
*
|
|
23
|
-
* const
|
|
24
|
-
* source: `function setup() { background(255); ellipse(width/2, height/2, 100); }`,
|
|
25
|
-
* width: 1950,
|
|
26
|
-
* height: 2400,
|
|
27
|
-
* seed: 12345,
|
|
28
|
-
* vars: [50, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
29
|
-
* mode: 'static'
|
|
30
|
-
* });
|
|
23
|
+
* const engine = createEngine({ mode: 'static' });
|
|
31
24
|
*
|
|
32
|
-
*
|
|
25
|
+
* engine.run({
|
|
26
|
+
* code: `
|
|
27
|
+
* function setup() {
|
|
28
|
+
* background(255);
|
|
29
|
+
* fill(0);
|
|
30
|
+
* ellipse(width/2, height/2, 100);
|
|
31
|
+
* }
|
|
32
|
+
* `,
|
|
33
|
+
* onComplete: (result) => {
|
|
34
|
+
* console.log('Rendered:', result.type, result.blob.size, 'bytes');
|
|
35
|
+
* }
|
|
36
|
+
* });
|
|
33
37
|
* ```
|
|
34
38
|
*/
|
|
35
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
36
|
-
// CANONICAL EXECUTION ENTRY POINT
|
|
37
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
38
|
-
export { executeCodeMode, validateCodeModeSource } from './execute';
|
|
39
|
-
export { PROTOCOL_IDENTITY } from './types';
|
|
40
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
41
|
-
// LEGACY ENGINE API (use executeCodeMode for new implementations)
|
|
42
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
43
39
|
export { createEngine } from './engine';
|
|
44
|
-
export { DEFAULT_CONFIG } from './types';
|
|
45
|
-
// SoundArt → Code Mode integration
|
|
46
|
-
export { renderSoundArtViaCodeMode, canRenderViaCodeMode, getCodeModeAvailableStyles, } from './soundart-engine';
|
|
47
|
-
export { createSoundSnapshot, createEmptySoundSnapshot, freezeSoundSnapshot, } from '../../shared/soundSnapshot';
|
|
48
|
-
export { injectSoundGlobals, createSoundGlobals, createEmptySoundGlobals, generateSoundPalette, inferGenreProfile, createSoundHelpers, } from './sound-bridge';
|
|
49
|
-
export { getSoundArtSketch, getAvailableSoundArtSketches, isSoundArtSketchAvailable, } from './soundart-sketches';
|
|
50
|
-
export { createP5Runtime } from './p5-runtime';
|
|
51
|
-
// Noise → Code Mode integration
|
|
52
|
-
export { renderNoiseViaCodeMode, compileNoiseSystem, canRenderNoiseViaCodeMode, } from './noise-engine';
|
|
53
|
-
export { createNoiseSnapshot, validateNoiseSnapshot, } from '../../shared/noiseSnapshot';
|
|
54
|
-
export { createNoiseGlobals, injectNoiseGlobals, } from './noise-bridge';
|
|
55
|
-
export { getNoiseSketch, getAvailableNoiseSketchNames, isValidNoiseSketch, } from './noise-sketches';
|
|
40
|
+
export { DEFAULT_CONFIG, PROTOCOL_IDENTITY } from './types';
|
package/dist/loop-engine.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* NexArt Code Mode Runtime SDK - Loop Engine
|
|
3
|
-
*
|
|
3
|
+
* Version: 1.4.0 (Protocol v1.2.0)
|
|
4
4
|
*
|
|
5
5
|
* Loop mode renderer: frame-authoritative, stateless execution.
|
|
6
6
|
* - Executes setup() once
|
|
@@ -8,9 +8,6 @@
|
|
|
8
8
|
* - Clears canvas before each frame (transparent)
|
|
9
9
|
* - Injects normalized time variables
|
|
10
10
|
* - No canvas persistence between frames
|
|
11
|
-
*
|
|
12
|
-
* Determinism Guarantee:
|
|
13
|
-
* Same code + same seed + same VARs = identical frame sequence
|
|
14
11
|
*/
|
|
15
12
|
import type { EngineConfig, RunOptions } from './types';
|
|
16
13
|
export declare function cancelLoopMode(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loop-engine.d.ts","sourceRoot":"","sources":["../loop-engine.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"loop-engine.d.ts","sourceRoot":"","sources":["../loop-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAA+B,MAAM,SAAS,CAAC;AAMrF,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAED,wBAAsB,WAAW,CAC/B,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,IAAI,CAAC,CA4Lf"}
|
package/dist/loop-engine.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* NexArt Code Mode Runtime SDK - Loop Engine
|
|
3
|
-
*
|
|
3
|
+
* Version: 1.4.0 (Protocol v1.2.0)
|
|
4
4
|
*
|
|
5
5
|
* Loop mode renderer: frame-authoritative, stateless execution.
|
|
6
6
|
* - Executes setup() once
|
|
@@ -8,18 +8,15 @@
|
|
|
8
8
|
* - Clears canvas before each frame (transparent)
|
|
9
9
|
* - Injects normalized time variables
|
|
10
10
|
* - No canvas persistence between frames
|
|
11
|
-
*
|
|
12
|
-
* Determinism Guarantee:
|
|
13
|
-
* Same code + same seed + same VARs = identical frame sequence
|
|
14
11
|
*/
|
|
15
12
|
import { DEFAULT_CONFIG } from './types';
|
|
16
|
-
import { createP5Runtime
|
|
13
|
+
import { createP5Runtime } from './p5-runtime';
|
|
17
14
|
let isCancelled = false;
|
|
18
15
|
export function cancelLoopMode() {
|
|
19
16
|
isCancelled = true;
|
|
20
17
|
}
|
|
21
18
|
export async function runLoopMode(config, options) {
|
|
22
|
-
const { code,
|
|
19
|
+
const { code, onPreview, onProgress, onComplete, onError } = options;
|
|
23
20
|
const width = config.width ?? DEFAULT_CONFIG.width;
|
|
24
21
|
const height = config.height ?? DEFAULT_CONFIG.height;
|
|
25
22
|
const duration = Math.max(DEFAULT_CONFIG.minDuration, Math.min(DEFAULT_CONFIG.maxDuration, config.duration ?? DEFAULT_CONFIG.duration));
|
|
@@ -36,10 +33,8 @@ export async function runLoopMode(config, options) {
|
|
|
36
33
|
const canvas = document.createElement('canvas');
|
|
37
34
|
canvas.width = width;
|
|
38
35
|
canvas.height = height;
|
|
39
|
-
// Create p5 runtime
|
|
40
|
-
const p = createP5Runtime(canvas, width, height
|
|
41
|
-
// Inject protocol variables (VAR[0..9])
|
|
42
|
-
injectProtocolVariables(p, vars);
|
|
36
|
+
// Create p5 runtime
|
|
37
|
+
const p = createP5Runtime(canvas, width, height);
|
|
43
38
|
// Validate code
|
|
44
39
|
const hasDrawFunction = /function\s+draw\s*\(\s*\)/.test(code);
|
|
45
40
|
if (!hasDrawFunction) {
|
|
@@ -69,16 +64,16 @@ export async function runLoopMode(config, options) {
|
|
|
69
64
|
if (!drawCode) {
|
|
70
65
|
throw new Error('Loop Mode requires a draw() function with content.');
|
|
71
66
|
}
|
|
72
|
-
// Create wrapped functions with p5 context
|
|
73
|
-
const wrappedSetup = new Function('p', 'frameCount', 't', 'time', 'tGlobal',
|
|
74
|
-
const wrappedDraw = new Function('p', 'frameCount', 't', 'time', 'tGlobal',
|
|
67
|
+
// Create wrapped functions with p5 context and time variables
|
|
68
|
+
const wrappedSetup = new Function('p', 'frameCount', 't', 'time', 'tGlobal', `with(p) { ${setupCode} }`);
|
|
69
|
+
const wrappedDraw = new Function('p', 'frameCount', 't', 'time', 'tGlobal', `with(p) { ${drawCode} }`);
|
|
75
70
|
onProgress?.({
|
|
76
71
|
phase: 'setup',
|
|
77
72
|
percent: 10,
|
|
78
73
|
message: 'Executing setup()...',
|
|
79
74
|
});
|
|
80
|
-
// Execute setup() once with time = 0
|
|
81
|
-
wrappedSetup(p, 0, 0, 0, 0
|
|
75
|
+
// Execute setup() once with time = 0
|
|
76
|
+
wrappedSetup(p, 0, 0, 0, 0);
|
|
82
77
|
// Capture frames
|
|
83
78
|
const frames = [];
|
|
84
79
|
onProgress?.({
|
|
@@ -102,8 +97,8 @@ export async function runLoopMode(config, options) {
|
|
|
102
97
|
// This enforces stateless, frame-authoritative rendering
|
|
103
98
|
// Preserves artist-defined backgrounds (if they call background() in draw)
|
|
104
99
|
p.clear();
|
|
105
|
-
// Execute draw() with time variables
|
|
106
|
-
wrappedDraw(p, frame, t, time, t
|
|
100
|
+
// Execute draw() with time variables
|
|
101
|
+
wrappedDraw(p, frame, t, time, t);
|
|
107
102
|
// Capture frame as PNG blob
|
|
108
103
|
const blob = await new Promise((resolve, reject) => {
|
|
109
104
|
canvas.toBlob((b) => b ? resolve(b) : reject(new Error(`Failed to capture frame ${frame}`)), 'image/png');
|
package/dist/p5-runtime.d.ts
CHANGED
|
@@ -1,41 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* NexArt Code Mode Runtime SDK - p5-like Runtime
|
|
3
|
+
* Version: 1.4.0 (Protocol v1.2.0)
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* ║ ║
|
|
7
|
-
* ║ Status: HARD PROTOCOL ENFORCEMENT ║
|
|
8
|
-
* ║ This is the stable, canonical execution surface. ║
|
|
9
|
-
* ║ SDKs, ByX, and external builders can depend on this API. ║
|
|
10
|
-
* ║ ║
|
|
11
|
-
* ║ Phase 1 Surface: ║
|
|
12
|
-
* ║ - VAR[0..9]: 10 read-only protocol variables (0-100 range) ║
|
|
13
|
-
* ║ - Drawing: line, rect, ellipse, circle, triangle, quad, arc, etc. ║
|
|
14
|
-
* ║ - Style: fill, stroke, colorMode, strokeWeight ║
|
|
15
|
-
* ║ - Transform: push, pop, translate, rotate, scale ║
|
|
16
|
-
* ║ - Random: random(), randomSeed(), randomGaussian() (seeded) ║
|
|
17
|
-
* ║ - Noise: noise(), noiseSeed(), noiseDetail() (seeded) ║
|
|
18
|
-
* ║ - Math: map, constrain, lerp, lerpColor, dist, mag, norm ║
|
|
19
|
-
* ║ - Color: Full CSS format support, color extraction functions ║
|
|
20
|
-
* ║ - Time: frameCount, t, time, tGlobal ║
|
|
21
|
-
* ║ ║
|
|
22
|
-
* ║ Determinism Guarantees: ║
|
|
23
|
-
* ║ - Same code + same seed + same VARs = identical output ║
|
|
24
|
-
* ║ - No external state, no browser entropy, no time-based drift ║
|
|
25
|
-
* ║ - Randomness ONLY from: random(), noise() (both seeded) ║
|
|
26
|
-
* ║ ║
|
|
27
|
-
* ║ ⚠️ Future changes require Phase 2+ ║
|
|
28
|
-
* ╚══════════════════════════════════════════════════════════════════════════╝
|
|
5
|
+
* Minimal p5.js-like runtime for deterministic generative art execution.
|
|
6
|
+
* This is a headless runtime - no UI dependencies.
|
|
29
7
|
*/
|
|
30
8
|
import type { TimeVariables } from './types';
|
|
31
|
-
/**
|
|
32
|
-
* Code Mode Protocol Version
|
|
33
|
-
* This constant defines the locked protocol version.
|
|
34
|
-
* Changes to the execution surface require a version bump.
|
|
35
|
-
*/
|
|
36
|
-
export declare const CODE_MODE_PROTOCOL_VERSION = "1.0.0";
|
|
37
|
-
export declare const CODE_MODE_PROTOCOL_PHASE = 1;
|
|
38
|
-
export declare const CODE_MODE_ENFORCEMENT: "HARD";
|
|
39
9
|
export interface P5Runtime {
|
|
40
10
|
[key: string]: any;
|
|
41
11
|
width: number;
|
|
@@ -46,28 +16,6 @@ export interface P5Runtime {
|
|
|
46
16
|
HALF_PI: number;
|
|
47
17
|
QUARTER_PI: number;
|
|
48
18
|
}
|
|
49
|
-
export
|
|
50
|
-
seed?: number;
|
|
51
|
-
}
|
|
52
|
-
export declare function createP5Runtime(canvas: HTMLCanvasElement, width: number, height: number, config?: P5RuntimeConfig): P5Runtime;
|
|
19
|
+
export declare function createP5Runtime(canvas: HTMLCanvasElement, width: number, height: number): P5Runtime;
|
|
53
20
|
export declare function injectTimeVariables(p: P5Runtime, time: TimeVariables): void;
|
|
54
|
-
/**
|
|
55
|
-
* VAR Protocol Constants (Phase 1 — Protocol v1.0.0)
|
|
56
|
-
* SDK v1.0.2: VAR input is optional (0-10 elements), but runtime always has 10
|
|
57
|
-
*/
|
|
58
|
-
export declare const VAR_COUNT = 10;
|
|
59
|
-
export declare const VAR_MIN = 0;
|
|
60
|
-
export declare const VAR_MAX = 100;
|
|
61
|
-
/**
|
|
62
|
-
* Create a protected, read-only VAR array for protocol execution.
|
|
63
|
-
*
|
|
64
|
-
* SDK v1.0.2 Rules (Protocol v1.0.0):
|
|
65
|
-
* - Input accepts 0-10 elements
|
|
66
|
-
* - Runtime VAR is ALWAYS 10 elements (padded with zeros)
|
|
67
|
-
* - Values are numeric, must be in 0-100 range (validated upstream)
|
|
68
|
-
* - Read-only: writes throw descriptive errors
|
|
69
|
-
* - Available in both setup() and draw()
|
|
70
|
-
*/
|
|
71
|
-
export declare function createProtocolVAR(vars?: number[]): readonly number[];
|
|
72
|
-
export declare function injectProtocolVariables(p: P5Runtime, vars?: number[]): void;
|
|
73
21
|
//# sourceMappingURL=p5-runtime.d.ts.map
|
package/dist/p5-runtime.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"p5-runtime.d.ts","sourceRoot":"","sources":["../p5-runtime.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"p5-runtime.d.ts","sourceRoot":"","sources":["../p5-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,MAAM,WAAW,SAAS;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,iBAAiB,EACzB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,SAAS,CAqVX;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI,CAE3E"}
|
package/dist/p5-runtime.js
CHANGED
|
@@ -1,97 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* NexArt Code Mode Runtime SDK - p5-like Runtime
|
|
3
|
+
* Version: 1.4.0 (Protocol v1.2.0)
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* ║ ║
|
|
7
|
-
* ║ Status: HARD PROTOCOL ENFORCEMENT ║
|
|
8
|
-
* ║ This is the stable, canonical execution surface. ║
|
|
9
|
-
* ║ SDKs, ByX, and external builders can depend on this API. ║
|
|
10
|
-
* ║ ║
|
|
11
|
-
* ║ Phase 1 Surface: ║
|
|
12
|
-
* ║ - VAR[0..9]: 10 read-only protocol variables (0-100 range) ║
|
|
13
|
-
* ║ - Drawing: line, rect, ellipse, circle, triangle, quad, arc, etc. ║
|
|
14
|
-
* ║ - Style: fill, stroke, colorMode, strokeWeight ║
|
|
15
|
-
* ║ - Transform: push, pop, translate, rotate, scale ║
|
|
16
|
-
* ║ - Random: random(), randomSeed(), randomGaussian() (seeded) ║
|
|
17
|
-
* ║ - Noise: noise(), noiseSeed(), noiseDetail() (seeded) ║
|
|
18
|
-
* ║ - Math: map, constrain, lerp, lerpColor, dist, mag, norm ║
|
|
19
|
-
* ║ - Color: Full CSS format support, color extraction functions ║
|
|
20
|
-
* ║ - Time: frameCount, t, time, tGlobal ║
|
|
21
|
-
* ║ ║
|
|
22
|
-
* ║ Determinism Guarantees: ║
|
|
23
|
-
* ║ - Same code + same seed + same VARs = identical output ║
|
|
24
|
-
* ║ - No external state, no browser entropy, no time-based drift ║
|
|
25
|
-
* ║ - Randomness ONLY from: random(), noise() (both seeded) ║
|
|
26
|
-
* ║ ║
|
|
27
|
-
* ║ ⚠️ Future changes require Phase 2+ ║
|
|
28
|
-
* ╚══════════════════════════════════════════════════════════════════════════╝
|
|
5
|
+
* Minimal p5.js-like runtime for deterministic generative art execution.
|
|
6
|
+
* This is a headless runtime - no UI dependencies.
|
|
29
7
|
*/
|
|
30
|
-
|
|
31
|
-
* Code Mode Protocol Version
|
|
32
|
-
* This constant defines the locked protocol version.
|
|
33
|
-
* Changes to the execution surface require a version bump.
|
|
34
|
-
*/
|
|
35
|
-
export const CODE_MODE_PROTOCOL_VERSION = '1.0.0';
|
|
36
|
-
export const CODE_MODE_PROTOCOL_PHASE = 1;
|
|
37
|
-
export const CODE_MODE_ENFORCEMENT = 'HARD';
|
|
38
|
-
/**
|
|
39
|
-
* Create a seeded random number generator (Mulberry32)
|
|
40
|
-
* Same algorithm used in SoundArt for consistency
|
|
41
|
-
*/
|
|
42
|
-
function createSeededRNG(seed = 123456) {
|
|
43
|
-
let a = seed >>> 0;
|
|
44
|
-
return () => {
|
|
45
|
-
a += 0x6D2B79F5;
|
|
46
|
-
let t = Math.imul(a ^ (a >>> 15), a | 1);
|
|
47
|
-
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
|
|
48
|
-
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Create improved Perlin-like noise with seeding support
|
|
53
|
-
*/
|
|
54
|
-
function createSeededNoise(seed = 0) {
|
|
55
|
-
const permutation = [];
|
|
56
|
-
const rng = createSeededRNG(seed);
|
|
57
|
-
for (let i = 0; i < 256; i++) {
|
|
58
|
-
permutation[i] = i;
|
|
59
|
-
}
|
|
60
|
-
for (let i = 255; i > 0; i--) {
|
|
61
|
-
const j = Math.floor(rng() * (i + 1));
|
|
62
|
-
[permutation[i], permutation[j]] = [permutation[j], permutation[i]];
|
|
63
|
-
}
|
|
64
|
-
for (let i = 0; i < 256; i++) {
|
|
65
|
-
permutation[256 + i] = permutation[i];
|
|
66
|
-
}
|
|
67
|
-
const fade = (t) => t * t * t * (t * (t * 6 - 15) + 10);
|
|
68
|
-
const lerp = (a, b, t) => a + t * (b - a);
|
|
69
|
-
const grad = (hash, x, y, z) => {
|
|
70
|
-
const h = hash & 15;
|
|
71
|
-
const u = h < 8 ? x : y;
|
|
72
|
-
const v = h < 4 ? y : h === 12 || h === 14 ? x : z;
|
|
73
|
-
return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v);
|
|
74
|
-
};
|
|
75
|
-
return (x, y = 0, z = 0) => {
|
|
76
|
-
const X = Math.floor(x) & 255;
|
|
77
|
-
const Y = Math.floor(y) & 255;
|
|
78
|
-
const Z = Math.floor(z) & 255;
|
|
79
|
-
x -= Math.floor(x);
|
|
80
|
-
y -= Math.floor(y);
|
|
81
|
-
z -= Math.floor(z);
|
|
82
|
-
const u = fade(x);
|
|
83
|
-
const v = fade(y);
|
|
84
|
-
const w = fade(z);
|
|
85
|
-
const A = permutation[X] + Y;
|
|
86
|
-
const AA = permutation[A] + Z;
|
|
87
|
-
const AB = permutation[A + 1] + Z;
|
|
88
|
-
const B = permutation[X + 1] + Y;
|
|
89
|
-
const BA = permutation[B] + Z;
|
|
90
|
-
const BB = permutation[B + 1] + Z;
|
|
91
|
-
return (lerp(lerp(lerp(grad(permutation[AA], x, y, z), grad(permutation[BA], x - 1, y, z), u), lerp(grad(permutation[AB], x, y - 1, z), grad(permutation[BB], x - 1, y - 1, z), u), v), lerp(lerp(grad(permutation[AA + 1], x, y, z - 1), grad(permutation[BA + 1], x - 1, y, z - 1), u), lerp(grad(permutation[AB + 1], x, y - 1, z - 1), grad(permutation[BB + 1], x - 1, y - 1, z - 1), u), v), w) + 1) / 2;
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
export function createP5Runtime(canvas, width, height, config) {
|
|
8
|
+
export function createP5Runtime(canvas, width, height) {
|
|
95
9
|
const ctx = canvas.getContext('2d', { willReadFrequently: true });
|
|
96
10
|
let currentFill = 'rgba(255, 255, 255, 1)';
|
|
97
11
|
let currentStroke = 'rgba(0, 0, 0, 1)';
|
|
@@ -100,119 +14,14 @@ export function createP5Runtime(canvas, width, height, config) {
|
|
|
100
14
|
let currentStrokeWeight = 1;
|
|
101
15
|
let colorModeSettings = { mode: 'RGB', maxR: 255, maxG: 255, maxB: 255, maxA: 255 };
|
|
102
16
|
let shapeStarted = false;
|
|
103
|
-
// Seeded random state
|
|
104
|
-
let randomSeedValue = config?.seed ?? Math.floor(Math.random() * 2147483647);
|
|
105
|
-
let rng = createSeededRNG(randomSeedValue);
|
|
106
|
-
// Seeded noise state
|
|
107
|
-
let noiseSeedValue = config?.seed ?? 0;
|
|
108
|
-
let noiseFunc = createSeededNoise(noiseSeedValue);
|
|
109
|
-
let noiseOctaves = 4;
|
|
110
|
-
let noiseFalloff = 0.5;
|
|
111
|
-
/**
|
|
112
|
-
* Parse CSS color string to normalized RGBA values
|
|
113
|
-
* Supports: hex (#RGB, #RRGGBB, #RRGGBBAA), rgb(), rgba(), hsl(), hsla()
|
|
114
|
-
*/
|
|
115
|
-
const parseCssColor = (str) => {
|
|
116
|
-
const s = str.trim();
|
|
117
|
-
// Hex format: #RGB, #RRGGBB, #RRGGBBAA
|
|
118
|
-
if (s.startsWith('#')) {
|
|
119
|
-
const hex = s.slice(1);
|
|
120
|
-
if (hex.length === 3) {
|
|
121
|
-
const r = parseInt(hex[0] + hex[0], 16);
|
|
122
|
-
const g = parseInt(hex[1] + hex[1], 16);
|
|
123
|
-
const b = parseInt(hex[2] + hex[2], 16);
|
|
124
|
-
return { r, g, b, a: 1 };
|
|
125
|
-
}
|
|
126
|
-
else if (hex.length === 6) {
|
|
127
|
-
const r = parseInt(hex.slice(0, 2), 16);
|
|
128
|
-
const g = parseInt(hex.slice(2, 4), 16);
|
|
129
|
-
const b = parseInt(hex.slice(4, 6), 16);
|
|
130
|
-
return { r, g, b, a: 1 };
|
|
131
|
-
}
|
|
132
|
-
else if (hex.length === 8) {
|
|
133
|
-
const r = parseInt(hex.slice(0, 2), 16);
|
|
134
|
-
const g = parseInt(hex.slice(2, 4), 16);
|
|
135
|
-
const b = parseInt(hex.slice(4, 6), 16);
|
|
136
|
-
const a = parseInt(hex.slice(6, 8), 16) / 255;
|
|
137
|
-
return { r, g, b, a };
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
// rgb(r, g, b) or rgb(r g b)
|
|
141
|
-
const rgbMatch = s.match(/^rgb\s*\(\s*(\d+)\s*[,\s]\s*(\d+)\s*[,\s]\s*(\d+)\s*\)$/i);
|
|
142
|
-
if (rgbMatch) {
|
|
143
|
-
return {
|
|
144
|
-
r: parseInt(rgbMatch[1]),
|
|
145
|
-
g: parseInt(rgbMatch[2]),
|
|
146
|
-
b: parseInt(rgbMatch[3]),
|
|
147
|
-
a: 1
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
// rgba(r, g, b, a) or rgba(r g b / a)
|
|
151
|
-
const rgbaMatch = s.match(/^rgba\s*\(\s*(\d+)\s*[,\s]\s*(\d+)\s*[,\s]\s*(\d+)\s*[,\/\s]\s*([\d.]+)\s*\)$/i);
|
|
152
|
-
if (rgbaMatch) {
|
|
153
|
-
return {
|
|
154
|
-
r: parseInt(rgbaMatch[1]),
|
|
155
|
-
g: parseInt(rgbaMatch[2]),
|
|
156
|
-
b: parseInt(rgbaMatch[3]),
|
|
157
|
-
a: parseFloat(rgbaMatch[4])
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
// hsl(h, s%, l%) or hsla(h, s%, l%, a)
|
|
161
|
-
const hslMatch = s.match(/^hsla?\s*\(\s*([\d.]+)\s*[,\s]\s*([\d.]+)%?\s*[,\s]\s*([\d.]+)%?\s*(?:[,\/\s]\s*([\d.]+))?\s*\)$/i);
|
|
162
|
-
if (hslMatch) {
|
|
163
|
-
const h = parseFloat(hslMatch[1]) / 360;
|
|
164
|
-
const sat = parseFloat(hslMatch[2]) / 100;
|
|
165
|
-
const l = parseFloat(hslMatch[3]) / 100;
|
|
166
|
-
const a = hslMatch[4] ? parseFloat(hslMatch[4]) : 1;
|
|
167
|
-
// HSL to RGB conversion
|
|
168
|
-
let r, g, b;
|
|
169
|
-
if (sat === 0) {
|
|
170
|
-
r = g = b = l;
|
|
171
|
-
}
|
|
172
|
-
else {
|
|
173
|
-
const hue2rgb = (p, q, t) => {
|
|
174
|
-
if (t < 0)
|
|
175
|
-
t += 1;
|
|
176
|
-
if (t > 1)
|
|
177
|
-
t -= 1;
|
|
178
|
-
if (t < 1 / 6)
|
|
179
|
-
return p + (q - p) * 6 * t;
|
|
180
|
-
if (t < 1 / 2)
|
|
181
|
-
return q;
|
|
182
|
-
if (t < 2 / 3)
|
|
183
|
-
return p + (q - p) * (2 / 3 - t) * 6;
|
|
184
|
-
return p;
|
|
185
|
-
};
|
|
186
|
-
const q = l < 0.5 ? l * (1 + sat) : l + sat - l * sat;
|
|
187
|
-
const p = 2 * l - q;
|
|
188
|
-
r = hue2rgb(p, q, h + 1 / 3);
|
|
189
|
-
g = hue2rgb(p, q, h);
|
|
190
|
-
b = hue2rgb(p, q, h - 1 / 3);
|
|
191
|
-
}
|
|
192
|
-
return {
|
|
193
|
-
r: Math.round(r * 255),
|
|
194
|
-
g: Math.round(g * 255),
|
|
195
|
-
b: Math.round(b * 255),
|
|
196
|
-
a
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
return null;
|
|
200
|
-
};
|
|
201
17
|
const parseColor = (...args) => {
|
|
202
18
|
if (args.length === 0)
|
|
203
19
|
return 'rgba(0, 0, 0, 1)';
|
|
204
20
|
const { mode, maxR, maxG, maxB, maxA } = colorModeSettings;
|
|
205
21
|
if (args.length === 1) {
|
|
206
22
|
const val = args[0];
|
|
207
|
-
if (typeof val === 'string')
|
|
208
|
-
// Try to parse CSS color formats
|
|
209
|
-
const parsed = parseCssColor(val);
|
|
210
|
-
if (parsed) {
|
|
211
|
-
return `rgba(${parsed.r}, ${parsed.g}, ${parsed.b}, ${parsed.a})`;
|
|
212
|
-
}
|
|
213
|
-
// Return as-is for named colors (canvas handles them)
|
|
23
|
+
if (typeof val === 'string')
|
|
214
24
|
return val;
|
|
215
|
-
}
|
|
216
25
|
if (mode === 'HSB') {
|
|
217
26
|
return `hsla(${val}, 100%, 50%, 1)`;
|
|
218
27
|
}
|
|
@@ -303,71 +112,7 @@ export function createP5Runtime(canvas, width, height, config) {
|
|
|
303
112
|
},
|
|
304
113
|
color: (...args) => parseColor(...args),
|
|
305
114
|
lerpColor: (c1, c2, amt) => {
|
|
306
|
-
//
|
|
307
|
-
const color1 = parseCssColor(c1) || { r: 0, g: 0, b: 0, a: 1 };
|
|
308
|
-
const color2 = parseCssColor(c2) || { r: 255, g: 255, b: 255, a: 1 };
|
|
309
|
-
// Linearly interpolate each channel
|
|
310
|
-
const r = Math.round(color1.r + (color2.r - color1.r) * amt);
|
|
311
|
-
const g = Math.round(color1.g + (color2.g - color1.g) * amt);
|
|
312
|
-
const b = Math.round(color1.b + (color2.b - color1.b) * amt);
|
|
313
|
-
const a = color1.a + (color2.a - color1.a) * amt;
|
|
314
|
-
return `rgba(${r}, ${g}, ${b}, ${a})`;
|
|
315
|
-
},
|
|
316
|
-
red: (color) => {
|
|
317
|
-
const parsed = parseCssColor(color);
|
|
318
|
-
return parsed ? parsed.r : 0;
|
|
319
|
-
},
|
|
320
|
-
green: (color) => {
|
|
321
|
-
const parsed = parseCssColor(color);
|
|
322
|
-
return parsed ? parsed.g : 0;
|
|
323
|
-
},
|
|
324
|
-
blue: (color) => {
|
|
325
|
-
const parsed = parseCssColor(color);
|
|
326
|
-
return parsed ? parsed.b : 0;
|
|
327
|
-
},
|
|
328
|
-
alpha: (color) => {
|
|
329
|
-
const parsed = parseCssColor(color);
|
|
330
|
-
return parsed ? parsed.a * 255 : 255;
|
|
331
|
-
},
|
|
332
|
-
brightness: (color) => {
|
|
333
|
-
const parsed = parseCssColor(color);
|
|
334
|
-
if (!parsed)
|
|
335
|
-
return 0;
|
|
336
|
-
return Math.max(parsed.r, parsed.g, parsed.b) / 255 * 100;
|
|
337
|
-
},
|
|
338
|
-
saturation: (color) => {
|
|
339
|
-
const parsed = parseCssColor(color);
|
|
340
|
-
if (!parsed)
|
|
341
|
-
return 0;
|
|
342
|
-
const max = Math.max(parsed.r, parsed.g, parsed.b);
|
|
343
|
-
const min = Math.min(parsed.r, parsed.g, parsed.b);
|
|
344
|
-
if (max === 0)
|
|
345
|
-
return 0;
|
|
346
|
-
return ((max - min) / max) * 100;
|
|
347
|
-
},
|
|
348
|
-
hue: (color) => {
|
|
349
|
-
const parsed = parseCssColor(color);
|
|
350
|
-
if (!parsed)
|
|
351
|
-
return 0;
|
|
352
|
-
const { r, g, b } = parsed;
|
|
353
|
-
const max = Math.max(r, g, b);
|
|
354
|
-
const min = Math.min(r, g, b);
|
|
355
|
-
if (max === min)
|
|
356
|
-
return 0;
|
|
357
|
-
let h = 0;
|
|
358
|
-
const d = max - min;
|
|
359
|
-
switch (max) {
|
|
360
|
-
case r:
|
|
361
|
-
h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
|
|
362
|
-
break;
|
|
363
|
-
case g:
|
|
364
|
-
h = ((b - r) / d + 2) / 6;
|
|
365
|
-
break;
|
|
366
|
-
case b:
|
|
367
|
-
h = ((r - g) / d + 4) / 6;
|
|
368
|
-
break;
|
|
369
|
-
}
|
|
370
|
-
return h * 360;
|
|
115
|
+
return c1; // Simplified - full implementation would blend colors
|
|
371
116
|
},
|
|
372
117
|
// Shape functions
|
|
373
118
|
ellipse: (x, y, w, h) => {
|
|
@@ -497,53 +242,30 @@ export function createP5Runtime(canvas, width, height, config) {
|
|
|
497
242
|
resetMatrix: () => {
|
|
498
243
|
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
|
499
244
|
},
|
|
500
|
-
// Math functions
|
|
245
|
+
// Math functions
|
|
501
246
|
random: (min, max) => {
|
|
502
|
-
// Support random() with arrays
|
|
503
|
-
if (Array.isArray(min)) {
|
|
504
|
-
return min[Math.floor(rng() * min.length)];
|
|
505
|
-
}
|
|
506
247
|
if (min === undefined)
|
|
507
|
-
return
|
|
248
|
+
return Math.random();
|
|
508
249
|
if (max === undefined)
|
|
509
|
-
return
|
|
510
|
-
return min +
|
|
250
|
+
return Math.random() * min;
|
|
251
|
+
return min + Math.random() * (max - min);
|
|
511
252
|
},
|
|
512
253
|
randomSeed: (seed) => {
|
|
513
|
-
|
|
514
|
-
rng = createSeededRNG(seed);
|
|
515
|
-
},
|
|
516
|
-
randomGaussian: (mean = 0, sd = 1) => {
|
|
517
|
-
// Box-Muller transform for Gaussian distribution
|
|
518
|
-
const u1 = rng();
|
|
519
|
-
const u2 = rng();
|
|
520
|
-
const z0 = Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);
|
|
521
|
-
return z0 * sd + mean;
|
|
254
|
+
// Simplified - would need proper seeded random
|
|
522
255
|
},
|
|
523
256
|
noise: (x, y, z) => {
|
|
524
|
-
//
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
frequency *= 2;
|
|
534
|
-
}
|
|
535
|
-
return total / maxValue;
|
|
536
|
-
},
|
|
537
|
-
noiseSeed: (seed) => {
|
|
538
|
-
noiseSeedValue = seed;
|
|
539
|
-
noiseFunc = createSeededNoise(seed);
|
|
540
|
-
},
|
|
541
|
-
noiseDetail: (lod, falloff) => {
|
|
542
|
-
noiseOctaves = Math.max(1, Math.min(8, lod));
|
|
543
|
-
if (falloff !== undefined) {
|
|
544
|
-
noiseFalloff = Math.max(0, Math.min(1, falloff));
|
|
545
|
-
}
|
|
257
|
+
// Simplified Perlin-like noise
|
|
258
|
+
const hash = (n) => {
|
|
259
|
+
const s = Math.sin(n) * 43758.5453123;
|
|
260
|
+
return s - Math.floor(s);
|
|
261
|
+
};
|
|
262
|
+
const xVal = x ?? 0;
|
|
263
|
+
const yVal = y ?? 0;
|
|
264
|
+
const zVal = z ?? 0;
|
|
265
|
+
return hash(xVal * 12.9898 + yVal * 78.233 + zVal * 37.719);
|
|
546
266
|
},
|
|
267
|
+
noiseSeed: (seed) => { },
|
|
268
|
+
noiseDetail: (lod, falloff) => { },
|
|
547
269
|
map: (value, start1, stop1, start2, stop2) => {
|
|
548
270
|
return start2 + (stop2 - start2) * ((value - start1) / (stop1 - start1));
|
|
549
271
|
},
|
|
@@ -594,51 +316,3 @@ export function createP5Runtime(canvas, width, height, config) {
|
|
|
594
316
|
export function injectTimeVariables(p, time) {
|
|
595
317
|
p.frameCount = time.frameCount;
|
|
596
318
|
}
|
|
597
|
-
/**
|
|
598
|
-
* VAR Protocol Constants (Phase 1 — Protocol v1.0.0)
|
|
599
|
-
* SDK v1.0.2: VAR input is optional (0-10 elements), but runtime always has 10
|
|
600
|
-
*/
|
|
601
|
-
export const VAR_COUNT = 10; // Exactly 10 protocol variables: VAR[0..9]
|
|
602
|
-
export const VAR_MIN = 0; // Minimum value
|
|
603
|
-
export const VAR_MAX = 100; // Maximum value (normalized range)
|
|
604
|
-
/**
|
|
605
|
-
* Create a protected, read-only VAR array for protocol execution.
|
|
606
|
-
*
|
|
607
|
-
* SDK v1.0.2 Rules (Protocol v1.0.0):
|
|
608
|
-
* - Input accepts 0-10 elements
|
|
609
|
-
* - Runtime VAR is ALWAYS 10 elements (padded with zeros)
|
|
610
|
-
* - Values are numeric, must be in 0-100 range (validated upstream)
|
|
611
|
-
* - Read-only: writes throw descriptive errors
|
|
612
|
-
* - Available in both setup() and draw()
|
|
613
|
-
*/
|
|
614
|
-
export function createProtocolVAR(vars) {
|
|
615
|
-
// Create frozen 10-element array (upstream normalizeVars ensures this)
|
|
616
|
-
const normalizedVars = [];
|
|
617
|
-
for (let i = 0; i < VAR_COUNT; i++) {
|
|
618
|
-
normalizedVars[i] = vars?.[i] ?? 0;
|
|
619
|
-
}
|
|
620
|
-
// Freeze the array to prevent modifications
|
|
621
|
-
const frozenVars = Object.freeze(normalizedVars);
|
|
622
|
-
// Wrap in Proxy for descriptive error messages on write attempts
|
|
623
|
-
return new Proxy(frozenVars, {
|
|
624
|
-
set(_target, prop, _value) {
|
|
625
|
-
const propName = typeof prop === 'symbol' ? prop.toString() : prop;
|
|
626
|
-
throw new Error(`[Code Mode Protocol Error] VAR is read-only. ` +
|
|
627
|
-
`Cannot write to VAR[${propName}]. ` +
|
|
628
|
-
`VAR[0..9] are protocol inputs, not sketch state.`);
|
|
629
|
-
},
|
|
630
|
-
deleteProperty(_target, prop) {
|
|
631
|
-
const propName = typeof prop === 'symbol' ? prop.toString() : prop;
|
|
632
|
-
throw new Error(`[Code Mode Protocol Error] VAR is read-only. ` +
|
|
633
|
-
`Cannot delete VAR[${propName}].`);
|
|
634
|
-
},
|
|
635
|
-
defineProperty(_target, prop) {
|
|
636
|
-
const propName = typeof prop === 'symbol' ? prop.toString() : prop;
|
|
637
|
-
throw new Error(`[Code Mode Protocol Error] Cannot define new VAR properties. ` +
|
|
638
|
-
`VAR is fixed at 10 elements (VAR[0..9]). Attempted: ${propName}`);
|
|
639
|
-
},
|
|
640
|
-
});
|
|
641
|
-
}
|
|
642
|
-
export function injectProtocolVariables(p, vars) {
|
|
643
|
-
p.VAR = createProtocolVAR(vars);
|
|
644
|
-
}
|