@viji-dev/core 0.2.10 → 0.2.12

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@viji-dev/core",
3
- "version": "0.2.10",
3
+ "version": "0.2.12",
4
4
  "description": "Universal execution engine for Viji Creative scenes",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,343 +0,0 @@
1
- class P5WorkerAdapter {
2
- constructor(offscreenCanvas, _vijiAPI, sceneCode) {
3
- this.offscreenCanvas = offscreenCanvas;
4
- this.setupFn = sceneCode.setup || null;
5
- this.renderFn = sceneCode.render;
6
- this.installMinimalShims();
7
- }
8
- p5Instance = null;
9
- setupFn = null;
10
- renderFn = null;
11
- p5InternalSetupComplete = false;
12
- artistSetupComplete = false;
13
- p5Class = null;
14
- // Cache for converted P5.Image objects
15
- imageParameterCache = /* @__PURE__ */ new Map();
16
- // Track if P5.js's main canvas has been created
17
- mainCanvasCreated = false;
18
- /**
19
- * Initialize P5 instance after P5.js library is loaded
20
- * This must be called after the P5 class is available
21
- */
22
- async init() {
23
- try {
24
- const p5Module = await import("https://esm.sh/p5@1.9.4");
25
- this.p5Class = p5Module.default || p5Module;
26
- const setupPromise = new Promise((resolve) => {
27
- new this.p5Class((p) => {
28
- this.p5Instance = p;
29
- p.setup = () => {
30
- p.createCanvas(this.offscreenCanvas.width, this.offscreenCanvas.height);
31
- p.noLoop();
32
- this.p5InternalSetupComplete = true;
33
- resolve();
34
- };
35
- p.draw = () => {
36
- };
37
- setTimeout(() => {
38
- if (p.setup && typeof p.setup === "function") {
39
- try {
40
- p.setup();
41
- } catch (setupError) {
42
- console.error("P5 setup failed:", setupError);
43
- resolve();
44
- }
45
- }
46
- }, 0);
47
- });
48
- });
49
- await setupPromise;
50
- } catch (error) {
51
- console.error("Failed to initialize P5.js:", error);
52
- throw error;
53
- }
54
- }
55
- /**
56
- * Install minimal DOM shims that P5.js needs for rendering
57
- */
58
- installMinimalShims() {
59
- const self = globalThis;
60
- if (typeof self.document === "undefined") {
61
- const createStyleProxy = () => new Proxy({}, {
62
- get: () => "",
63
- set: () => true
64
- });
65
- const bodyElement = {
66
- style: createStyleProxy(),
67
- appendChild: () => {
68
- },
69
- removeChild: () => {
70
- },
71
- children: [],
72
- childNodes: [],
73
- firstChild: null,
74
- lastChild: null,
75
- parentNode: null,
76
- ownerDocument: void 0,
77
- // Will be set after document is created
78
- setAttribute: () => {
79
- },
80
- getAttribute: () => null,
81
- addEventListener: () => {
82
- },
83
- removeEventListener: () => {
84
- },
85
- tagName: "BODY"
86
- };
87
- self.document = {
88
- createElement: (tag) => {
89
- if (tag === "canvas") {
90
- let canvas;
91
- if (!this.mainCanvasCreated) {
92
- canvas = this.offscreenCanvas;
93
- this.mainCanvasCreated = true;
94
- } else {
95
- canvas = new OffscreenCanvas(300, 300);
96
- }
97
- canvas.style = createStyleProxy();
98
- canvas.dataset = new Proxy({}, {
99
- get: () => void 0,
100
- set: () => true
101
- });
102
- canvas.classList = {
103
- add: () => {
104
- },
105
- remove: () => {
106
- },
107
- contains: () => false,
108
- toggle: () => false
109
- };
110
- canvas.getBoundingClientRect = () => ({
111
- left: 0,
112
- top: 0,
113
- width: canvas.width,
114
- height: canvas.height
115
- });
116
- return canvas;
117
- }
118
- return {
119
- style: createStyleProxy(),
120
- appendChild: () => {
121
- },
122
- removeChild: () => {
123
- },
124
- setAttribute: () => {
125
- },
126
- getAttribute: () => null,
127
- tagName: tag.toUpperCase(),
128
- addEventListener: () => {
129
- },
130
- removeEventListener: () => {
131
- }
132
- };
133
- },
134
- createElementNS: (_ns, tag) => {
135
- return self.document.createElement(tag);
136
- },
137
- body: bodyElement,
138
- documentElement: {
139
- style: createStyleProxy(),
140
- children: [],
141
- childNodes: []
142
- },
143
- getElementById: () => null,
144
- querySelector: () => null,
145
- querySelectorAll: () => [],
146
- getElementsByTagName: (tagName) => {
147
- if (tagName.toLowerCase() === "main") {
148
- return [bodyElement];
149
- }
150
- return [];
151
- },
152
- addEventListener: () => {
153
- },
154
- removeEventListener: () => {
155
- },
156
- hasFocus: () => true
157
- // P5.js checks this for accessibility features
158
- };
159
- bodyElement.ownerDocument = self.document;
160
- }
161
- if (typeof self.window === "undefined") {
162
- self.window = {
163
- devicePixelRatio: 1,
164
- innerWidth: this.offscreenCanvas.width,
165
- innerHeight: this.offscreenCanvas.height,
166
- addEventListener: () => {
167
- },
168
- removeEventListener: () => {
169
- },
170
- requestAnimationFrame: (_callback) => {
171
- return 0;
172
- },
173
- cancelAnimationFrame: () => {
174
- },
175
- setTimeout: self.setTimeout.bind(self),
176
- clearTimeout: self.clearTimeout.bind(self),
177
- setInterval: self.setInterval.bind(self),
178
- clearInterval: self.clearInterval.bind(self),
179
- performance: self.performance,
180
- console: self.console,
181
- Math: self.Math,
182
- Date: self.Date,
183
- Array: self.Array,
184
- Object: self.Object
185
- };
186
- }
187
- if (typeof self.navigator === "undefined") {
188
- self.navigator = {
189
- userAgent: "Viji-Worker-P5",
190
- platform: "Worker",
191
- language: "en-US"
192
- };
193
- }
194
- if (typeof self.screen === "undefined") {
195
- self.screen = {
196
- width: this.offscreenCanvas.width,
197
- height: this.offscreenCanvas.height,
198
- availWidth: this.offscreenCanvas.width,
199
- availHeight: this.offscreenCanvas.height,
200
- colorDepth: 24,
201
- pixelDepth: 24
202
- };
203
- }
204
- if (typeof self.HTMLCanvasElement === "undefined") {
205
- self.HTMLCanvasElement = function() {
206
- };
207
- Object.setPrototypeOf(OffscreenCanvas.prototype, self.HTMLCanvasElement.prototype);
208
- }
209
- }
210
- /**
211
- * Convert ImageBitmap to a P5.js-compatible image object (with caching)
212
- * Returns an object that mimics P5.Image structure for P5.js's image() function
213
- */
214
- getOrCreateP5Image(cacheKey, source) {
215
- if (!this.p5Instance) return null;
216
- const cached = this.imageParameterCache.get(cacheKey);
217
- if (cached && cached.source === source) {
218
- return cached.p5Image;
219
- }
220
- try {
221
- const offscreenCanvas = new OffscreenCanvas(source.width, source.height);
222
- const ctx = offscreenCanvas.getContext("2d");
223
- if (!ctx) {
224
- throw new Error("Failed to get 2d context from OffscreenCanvas");
225
- }
226
- ctx.drawImage(source, 0, 0);
227
- const p5ImageWrapper = {
228
- canvas: offscreenCanvas,
229
- // P5.js looks for img.canvas || img.elt
230
- elt: offscreenCanvas,
231
- // Fallback for compatibility
232
- width: source.width,
233
- // Logical width
234
- height: source.height
235
- // Logical height
236
- };
237
- this.imageParameterCache.set(cacheKey, { source, p5Image: p5ImageWrapper });
238
- return p5ImageWrapper;
239
- } catch (error) {
240
- console.warn("Failed to convert image to P5-compatible object:", error);
241
- return null;
242
- }
243
- }
244
- /**
245
- * Add .p5 property to image parameters for P5.js-specific rendering
246
- * This allows artists to use p5.image() while keeping .value for native canvas API
247
- * @param parameterObjects Map of parameter name to parameter object from ParameterSystem
248
- */
249
- addP5PropertyToImageParameters(parameterObjects) {
250
- if (!this.p5Instance) return;
251
- const isImageLike = (value) => {
252
- return value instanceof ImageBitmap || value instanceof OffscreenCanvas || value && typeof value === "object" && "width" in value && "height" in value;
253
- };
254
- for (const [name, param] of parameterObjects) {
255
- try {
256
- if (param && typeof param === "object" && "value" in param) {
257
- const value = param.value;
258
- if (value && isImageLike(value) && !("p5" in param)) {
259
- Object.defineProperty(param, "p5", {
260
- get: () => this.getOrCreateP5Image(name, param.value),
261
- enumerable: true,
262
- configurable: true
263
- });
264
- }
265
- }
266
- } catch (error) {
267
- console.warn(`Failed to add .p5 property to parameter '${name}':`, error);
268
- continue;
269
- }
270
- }
271
- }
272
- /**
273
- * Execute one frame of the P5 scene
274
- * Called by Viji's render loop
275
- * @param vijiAPI The Viji API object passed to artist code
276
- * @param parameterObjects Map of parameter objects from ParameterSystem
277
- */
278
- tick(vijiAPI, parameterObjects) {
279
- if (!this.p5Instance || !this.p5InternalSetupComplete) {
280
- return;
281
- }
282
- try {
283
- this.addP5PropertyToImageParameters(parameterObjects);
284
- if (!this.artistSetupComplete && this.setupFn) {
285
- this.setupFn(vijiAPI, this.p5Instance);
286
- this.artistSetupComplete = true;
287
- }
288
- if (this.p5Instance._setProperty) {
289
- this.p5Instance._setProperty("frameCount", this.p5Instance.frameCount + 1);
290
- }
291
- if (this.renderFn) {
292
- this.renderFn(vijiAPI, this.p5Instance);
293
- }
294
- } catch (error) {
295
- console.error("P5 render error:", error);
296
- throw error;
297
- }
298
- }
299
- /**
300
- * Handle canvas resize
301
- */
302
- resize(width, height) {
303
- if (!this.p5Instance) return;
304
- this.p5Instance._setProperty("width", width);
305
- this.p5Instance._setProperty("height", height);
306
- this.p5Instance._setProperty("_width", width);
307
- this.p5Instance._setProperty("_height", height);
308
- if (this.p5Instance._renderer) {
309
- this.p5Instance._renderer.width = width;
310
- this.p5Instance._renderer.height = height;
311
- }
312
- if (typeof this.p5Instance.resizeCanvas === "function") {
313
- try {
314
- this.p5Instance.resizeCanvas(width, height, true);
315
- } catch (error) {
316
- console.warn("P5 resize warning:", error);
317
- }
318
- }
319
- }
320
- /**
321
- * Cleanup P5 instance
322
- */
323
- destroy() {
324
- if (this.p5Instance) {
325
- try {
326
- if (typeof this.p5Instance.remove === "function") {
327
- this.p5Instance.remove();
328
- }
329
- } catch (error) {
330
- console.warn("P5 cleanup warning:", error);
331
- }
332
- this.p5Instance = null;
333
- }
334
- this.setupFn = null;
335
- this.renderFn = null;
336
- this.p5InternalSetupComplete = false;
337
- this.artistSetupComplete = false;
338
- }
339
- }
340
- export {
341
- P5WorkerAdapter
342
- };
343
- //# sourceMappingURL=P5WorkerAdapter-B4koBeZd.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"P5WorkerAdapter-B4koBeZd.js","sources":["../../src/worker/renderers/P5WorkerAdapter.ts"],"sourcesContent":["/**\n * P5.js Worker Adapter\n * \n * Integrates P5.js into Viji's worker-based rendering system.\n * Provides minimal DOM shimming and manages P5 instance lifecycle.\n */\n\n/**\n * Scene code structure for P5 mode\n */\ninterface P5SceneCode {\n setup?: ((viji: any, p5: any) => void) | null;\n render: (viji: any, p5: any) => void;\n}\n\nexport class P5WorkerAdapter {\n private p5Instance: any = null;\n private setupFn: ((viji: any, p5: any) => void) | null = null;\n private renderFn: ((viji: any, p5: any) => void) | null = null;\n private p5InternalSetupComplete = false;\n private artistSetupComplete = false;\n private p5Class: any = null;\n \n // Cache for converted P5.Image objects\n private imageParameterCache = new Map<string, { source: any, p5Image: any }>();\n \n // Track if P5.js's main canvas has been created\n private mainCanvasCreated = false;\n \n constructor(\n private offscreenCanvas: OffscreenCanvas,\n _vijiAPI: any,\n sceneCode: P5SceneCode\n ) {\n this.setupFn = sceneCode.setup || null;\n this.renderFn = sceneCode.render;\n \n // Install minimal DOM shims before loading P5\n this.installMinimalShims();\n \n // Note: P5 will be loaded dynamically when this adapter is created\n // We'll initialize it after P5 is imported\n }\n \n /**\n * Initialize P5 instance after P5.js library is loaded\n * This must be called after the P5 class is available\n */\n public async init(): Promise<void> {\n try {\n // Dynamically import P5.js from ESM-compatible CDN (lazy-loaded, not bundled)\n // esm.sh provides proper ES module versions of npm packages\n // @ts-expect-error - CDN URL import, types provided by @types/p5\n const p5Module = await import('https://esm.sh/p5@1.9.4');\n this.p5Class = p5Module.default || p5Module;\n \n // Create a promise that resolves when P5's setup completes\n const setupPromise = new Promise<void>((resolve) => {\n // Create P5 instance in instance mode\n new this.p5Class((p: any) => {\n // Capture the P5 instance from the callback parameter\n this.p5Instance = p;\n \n // P5 sketch setup\n p.setup = () => {\n // Initialize P5 renderer using our OffscreenCanvas via the shimmed document\n p.createCanvas(this.offscreenCanvas.width, this.offscreenCanvas.height);\n \n // Disable P5's automatic loop (Viji controls the render loop)\n p.noLoop();\n \n // Mark that P5's internal setup is complete\n this.p5InternalSetupComplete = true;\n \n // Resolve the promise\n resolve();\n };\n \n // Empty draw - we'll call the artist's render function manually\n p.draw = () => {};\n \n // IMPORTANT: In worker environment, P5 doesn't auto-call setup\n // We need to manually trigger it\n setTimeout(() => {\n if (p.setup && typeof p.setup === 'function') {\n try {\n p.setup();\n } catch (setupError) {\n console.error('P5 setup failed:', setupError);\n resolve(); // Resolve anyway to prevent hanging\n }\n }\n }, 0);\n });\n });\n \n // Wait for P5's setup to actually complete\n await setupPromise;\n } catch (error) {\n console.error('Failed to initialize P5.js:', error);\n throw error;\n }\n }\n \n /**\n * Install minimal DOM shims that P5.js needs for rendering\n */\n private installMinimalShims(): void {\n const self = globalThis as any;\n \n // Only install if not already present\n if (typeof self.document === 'undefined') {\n // Create flexible style proxy that accepts any property\n const createStyleProxy = () => new Proxy({}, {\n get: () => '',\n set: () => true\n });\n\n // Create body element first so canvas can reference it\n const bodyElement: any = {\n style: createStyleProxy(),\n appendChild: () => {},\n removeChild: () => {},\n children: [],\n childNodes: [],\n firstChild: null,\n lastChild: null,\n parentNode: null,\n ownerDocument: undefined, // Will be set after document is created\n setAttribute: () => {},\n getAttribute: () => null,\n addEventListener: () => {},\n removeEventListener: () => {},\n tagName: 'BODY'\n };\n\n // Minimal document shim\n self.document = {\n createElement: (tag: string) => {\n if (tag === 'canvas') {\n // For the FIRST canvas (P5.js's main canvas), return our provided OffscreenCanvas\n // For subsequent canvases (e.g., tint operations), create new ones\n let canvas: OffscreenCanvas;\n if (!this.mainCanvasCreated) {\n canvas = this.offscreenCanvas;\n this.mainCanvasCreated = true;\n } else {\n canvas = new OffscreenCanvas(300, 300); // Default size, P5.js will resize as needed\n }\n \n // Add DOM-like properties that P5.js may check for\n // @ts-ignore - Adding properties to OffscreenCanvas\n canvas.style = createStyleProxy();\n // @ts-ignore\n canvas.dataset = new Proxy({}, {\n get: () => undefined,\n set: () => true\n });\n // @ts-ignore\n canvas.classList = {\n add: () => {},\n remove: () => {},\n contains: () => false,\n toggle: () => false\n };\n // @ts-ignore\n canvas.getBoundingClientRect = () => ({ \n left: 0, \n top: 0, \n width: canvas.width, \n height: canvas.height \n });\n // Return the actual OffscreenCanvas (now with extra properties)\n // This allows it to be used directly with drawImage()\n return canvas;\n }\n // Return stub for other elements\n return {\n style: createStyleProxy(),\n appendChild: () => {},\n removeChild: () => {},\n setAttribute: () => {},\n getAttribute: () => null,\n tagName: tag.toUpperCase(),\n addEventListener: () => {},\n removeEventListener: () => {}\n };\n },\n createElementNS: (_ns: string, tag: string) => {\n return self.document.createElement(tag);\n },\n body: bodyElement,\n documentElement: {\n style: createStyleProxy(),\n children: [],\n childNodes: []\n },\n getElementById: () => null,\n querySelector: () => null,\n querySelectorAll: () => [],\n getElementsByTagName: (tagName: string) => {\n // P5.js looks for 'main' elements to append canvas\n if (tagName.toLowerCase() === 'main') {\n return [bodyElement]; // Return body as main container\n }\n return [];\n },\n addEventListener: () => {},\n removeEventListener: () => {},\n hasFocus: () => true // P5.js checks this for accessibility features\n };\n \n // Set bodyElement.ownerDocument now that document exists\n bodyElement.ownerDocument = self.document;\n }\n \n if (typeof self.window === 'undefined') {\n // Minimal window shim\n self.window = {\n devicePixelRatio: 1,\n innerWidth: this.offscreenCanvas.width,\n innerHeight: this.offscreenCanvas.height,\n addEventListener: () => {},\n removeEventListener: () => {},\n requestAnimationFrame: (_callback: Function) => {\n // We control the loop, so this should not be called\n return 0;\n },\n cancelAnimationFrame: () => {},\n setTimeout: self.setTimeout.bind(self),\n clearTimeout: self.clearTimeout.bind(self),\n setInterval: self.setInterval.bind(self),\n clearInterval: self.clearInterval.bind(self),\n performance: self.performance,\n console: self.console,\n Math: self.Math,\n Date: self.Date,\n Array: self.Array,\n Object: self.Object\n };\n }\n \n if (typeof self.navigator === 'undefined') {\n // Minimal navigator shim\n self.navigator = {\n userAgent: 'Viji-Worker-P5',\n platform: 'Worker',\n language: 'en-US'\n };\n }\n \n if (typeof self.screen === 'undefined') {\n // Minimal screen shim for P5.js display metrics\n self.screen = {\n width: this.offscreenCanvas.width,\n height: this.offscreenCanvas.height,\n availWidth: this.offscreenCanvas.width,\n availHeight: this.offscreenCanvas.height,\n colorDepth: 24,\n pixelDepth: 24\n };\n }\n \n if (typeof self.HTMLCanvasElement === 'undefined') {\n // P5.js checks instanceof HTMLCanvasElement\n // Create a minimal constructor that OffscreenCanvas \"instanceof\" will pass\n self.HTMLCanvasElement = function() {} as any;\n // Make OffscreenCanvas instances appear to be HTMLCanvasElement instances\n Object.setPrototypeOf(OffscreenCanvas.prototype, self.HTMLCanvasElement.prototype);\n }\n }\n \n /**\n * Convert ImageBitmap to a P5.js-compatible image object (with caching)\n * Returns an object that mimics P5.Image structure for P5.js's image() function\n */\n private getOrCreateP5Image(cacheKey: string, source: any): any {\n if (!this.p5Instance) return null;\n \n // Check cache first\n const cached = this.imageParameterCache.get(cacheKey);\n if (cached && cached.source === source) {\n return cached.p5Image;\n }\n \n try {\n // Create an OffscreenCanvas and draw the ImageBitmap to it\n const offscreenCanvas = new OffscreenCanvas(source.width, source.height);\n const ctx = offscreenCanvas.getContext('2d');\n if (!ctx) {\n throw new Error('Failed to get 2d context from OffscreenCanvas');\n }\n ctx.drawImage(source, 0, 0);\n \n // Wrap the OffscreenCanvas in a P5.Image-like object\n // P5.js expects: img.canvas or img.elt (the actual canvas), and img.width/img.height (logical dimensions)\n const p5ImageWrapper = {\n canvas: offscreenCanvas, // P5.js looks for img.canvas || img.elt\n elt: offscreenCanvas, // Fallback for compatibility\n width: source.width, // Logical width\n height: source.height // Logical height\n };\n \n // Cache the conversion\n this.imageParameterCache.set(cacheKey, { source, p5Image: p5ImageWrapper });\n \n return p5ImageWrapper;\n } catch (error) {\n console.warn('Failed to convert image to P5-compatible object:', error);\n return null;\n }\n }\n \n /**\n * Add .p5 property to image parameters for P5.js-specific rendering\n * This allows artists to use p5.image() while keeping .value for native canvas API\n * @param parameterObjects Map of parameter name to parameter object from ParameterSystem\n */\n private addP5PropertyToImageParameters(parameterObjects: Map<string, any>): void {\n if (!this.p5Instance) return;\n \n // Function to check if a value is an image-like object\n const isImageLike = (value: any): boolean => {\n return value instanceof ImageBitmap || \n value instanceof OffscreenCanvas ||\n (value && typeof value === 'object' && 'width' in value && 'height' in value);\n };\n \n // Iterate through parameter objects provided by ParameterSystem\n for (const [name, param] of parameterObjects) {\n try {\n // Check if this parameter has an image value\n if (param && typeof param === 'object' && 'value' in param) {\n const value = param.value;\n \n // If the value is an image-like object and doesn't have .p5 yet\n if (value && isImageLike(value) && !('p5' in param)) {\n // Add lazy .p5 getter that converts on-demand\n Object.defineProperty(param, 'p5', {\n get: () => this.getOrCreateP5Image(name, param.value),\n enumerable: true,\n configurable: true\n });\n }\n }\n } catch (error) {\n console.warn(`Failed to add .p5 property to parameter '${name}':`, error);\n continue;\n }\n }\n }\n \n /**\n * Execute one frame of the P5 scene\n * Called by Viji's render loop\n * @param vijiAPI The Viji API object passed to artist code\n * @param parameterObjects Map of parameter objects from ParameterSystem\n */\n public tick(vijiAPI: any, parameterObjects: Map<string, any>): void {\n if (!this.p5Instance || !this.p5InternalSetupComplete) {\n // P5 not ready yet, skip this frame\n return;\n }\n \n try {\n // Add .p5 property to image parameters (lazy, cached conversion)\n this.addP5PropertyToImageParameters(parameterObjects);\n \n // Run artist's setup once\n if (!this.artistSetupComplete && this.setupFn) {\n this.setupFn(vijiAPI, this.p5Instance);\n this.artistSetupComplete = true;\n }\n \n // Update P5's internal frame count\n if (this.p5Instance._setProperty) {\n this.p5Instance._setProperty('frameCount', this.p5Instance.frameCount + 1);\n }\n \n // Call artist's render function with both Viji and P5 APIs\n if (this.renderFn) {\n this.renderFn(vijiAPI, this.p5Instance);\n }\n } catch (error) {\n console.error('P5 render error:', error);\n throw error;\n }\n }\n \n /**\n * Handle canvas resize\n */\n public resize(width: number, height: number): void {\n if (!this.p5Instance) return;\n \n // Update P5's internal dimensions\n this.p5Instance._setProperty('width', width);\n this.p5Instance._setProperty('height', height);\n this.p5Instance._setProperty('_width', width);\n this.p5Instance._setProperty('_height', height);\n \n // Update renderer dimensions if available\n if (this.p5Instance._renderer) {\n this.p5Instance._renderer.width = width;\n this.p5Instance._renderer.height = height;\n }\n \n // Call P5's resizeCanvas if available\n if (typeof this.p5Instance.resizeCanvas === 'function') {\n try {\n this.p5Instance.resizeCanvas(width, height, true);\n } catch (error) {\n // Ignore resize errors, they're often not critical\n console.warn('P5 resize warning:', error);\n }\n }\n }\n \n /**\n * Cleanup P5 instance\n */\n public destroy(): void {\n if (this.p5Instance) {\n try {\n if (typeof this.p5Instance.remove === 'function') {\n this.p5Instance.remove();\n }\n } catch (error) {\n console.warn('P5 cleanup warning:', error);\n }\n this.p5Instance = null;\n }\n \n this.setupFn = null;\n this.renderFn = null;\n this.p5InternalSetupComplete = false;\n this.artistSetupComplete = false;\n }\n}\n\n"],"names":[],"mappings":"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"}