@viji-dev/core 0.7.7 → 0.7.8

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/dist/docs-api.js CHANGED
@@ -1,7 +1,7 @@
1
1
  export const docsApi = {
2
2
  "version": "1.1.0",
3
3
  "coreVersion": "0.7.7",
4
- "generatedAt": "2026-05-27T11:22:47.838Z",
4
+ "generatedAt": "2026-05-27T16:04:46.762Z",
5
5
  "navigation": [
6
6
  {
7
7
  "id": "getting-started",
@@ -1,4 +1,4 @@
1
- import { g as kn } from "./index-DkwlRK6X.js";
1
+ import { g as kn } from "./index-CNBiAcmD.js";
2
2
  function jn(Oe, ot) {
3
3
  for (var ve = 0; ve < ot.length; ve++) {
4
4
  const Z = ot[ve];
@@ -3374,4 +3374,4 @@ const xn = /* @__PURE__ */ kn(yi), Ln = /* @__PURE__ */ jn({
3374
3374
  export {
3375
3375
  Ln as e
3376
3376
  };
3377
- //# sourceMappingURL=essentia-wasm.web-B9C3y5iZ.js.map
3377
+ //# sourceMappingURL=essentia-wasm.web-CeG0Fd_W.js.map
@@ -1520,7 +1520,7 @@ class YB {
1520
1520
  if (!this.isInitialized)
1521
1521
  return this.initPromise ? this.initPromise : (this.initPromise = (async () => {
1522
1522
  try {
1523
- const A = await import("./essentia.js-core.es-CC_3Ap1i.js"), B = await import("./essentia-wasm.web-B9C3y5iZ.js").then((g) => g.e), I = A.Essentia || A.default?.Essentia || A.default;
1523
+ const A = await import("./essentia.js-core.es-CC_3Ap1i.js"), B = await import("./essentia-wasm.web-CeG0Fd_W.js").then((g) => g.e), I = A.Essentia || A.default?.Essentia || A.default;
1524
1524
  let Q = B.default || B.EssentiaWASM || B.default?.EssentiaWASM;
1525
1525
  if (!Q)
1526
1526
  throw new Error("WASM module not found - check essentia-wasm.web.js export");
@@ -6210,12 +6210,29 @@ class iA {
6210
6210
  };
6211
6211
  // Track if OffscreenCanvas has been sent to worker
6212
6212
  hasTransferredCanvas = !1;
6213
+ // Handle for the 5s metadata-load watchdog armed in setVideoStream().
6214
+ // Stored on the instance so disconnectVideoStream() can cancel it when the
6215
+ // stream is swapped before the timer fires -- otherwise the orphaned timer
6216
+ // outlives a superseded coordinator and its reject path runs
6217
+ // disconnectVideoStream() ~5s later, sending a stale disconnect for this
6218
+ // streamIndex that clobbers the successor coordinator's worker-side
6219
+ // OffscreenCanvas. (Mirrors AudioSystem's ch.workletWatchdog.)
6220
+ metadataWatchdog = null;
6213
6221
  // Callback to send data to worker
6214
6222
  sendToWorker = null;
6215
6223
  // Stream identification for multi-stream support
6216
6224
  streamIndex = 0;
6217
6225
  // Debug logging control
6218
6226
  debugMode = !1;
6227
+ /**
6228
+ * One-way lifecycle flag flipped at the top of `resetVideoState()`.
6229
+ * Gates re-entry into the stream-mutation entry points and the metadata
6230
+ * watchdog callback so a late async caller or a future stored callback
6231
+ * cannot push canvas-setup / disconnect for this streamIndex after the
6232
+ * coordinator has been discarded and replaced. A VideoCoordinator is
6233
+ * single-use after reset. (Mirrors AudioSystem.destroyed.)
6234
+ */
6235
+ destroyed = !1;
6219
6236
  /**
6220
6237
  * Enable or disable debug logging
6221
6238
  */
@@ -6241,20 +6258,22 @@ class iA {
6241
6258
  * Handle video stream update (called from VijiCore)
6242
6259
  */
6243
6260
  handleVideoStreamUpdate(A) {
6244
- try {
6245
- A.streamIndex !== void 0 && (this.streamIndex = A.streamIndex), A.videoStream ? this.setVideoStream(A.videoStream) : this.disconnectVideoStream(), (A.targetFrameRate || A.cvConfig) && this.sendConfigurationToWorker({
6246
- ...A.targetFrameRate && { targetFrameRate: A.targetFrameRate },
6247
- ...A.cvConfig && { cvConfig: A.cvConfig },
6248
- timestamp: A.timestamp
6249
- });
6250
- } catch (B) {
6251
- console.error("Error handling video stream update:", B), this.coordinatorState.isConnected = !1, this.sendDisconnectionToWorker();
6252
- }
6261
+ if (!this.destroyed)
6262
+ try {
6263
+ A.streamIndex !== void 0 && (this.streamIndex = A.streamIndex), A.videoStream ? this.setVideoStream(A.videoStream) : this.disconnectVideoStream(), (A.targetFrameRate || A.cvConfig) && this.sendConfigurationToWorker({
6264
+ ...A.targetFrameRate && { targetFrameRate: A.targetFrameRate },
6265
+ ...A.cvConfig && { cvConfig: A.cvConfig },
6266
+ timestamp: A.timestamp
6267
+ });
6268
+ } catch (B) {
6269
+ console.error("Error handling video stream update:", B), this.coordinatorState.isConnected = !1, this.sendDisconnectionToWorker();
6270
+ }
6253
6271
  }
6254
6272
  /**
6255
6273
  * Set the video stream for processing
6256
6274
  */
6257
6275
  async setVideoStream(A) {
6276
+ if (this.destroyed) return;
6258
6277
  if (this.disconnectVideoStream(), A.getVideoTracks().length === 0) {
6259
6278
  console.warn("No video tracks in provided stream"), this.coordinatorState.isConnected = !1, this.sendDisconnectionToWorker();
6260
6279
  return;
@@ -6263,9 +6282,10 @@ class iA {
6263
6282
  if (this.videoElement = document.createElement("video"), this.videoElement.autoplay = !0, this.videoElement.muted = !0, this.videoElement.playsInline = !0, this.canvas = document.createElement("canvas"), this.ctx = this.canvas.getContext("2d"), !this.ctx)
6264
6283
  throw new Error("Failed to get 2D context from canvas");
6265
6284
  this.videoElement.srcObject = A, await new Promise((I, Q) => {
6266
- const g = setTimeout(() => Q(new Error("Video metadata load timeout")), 5e3);
6267
- this.videoElement.addEventListener("loadedmetadata", async () => {
6268
- clearTimeout(g);
6285
+ this.metadataWatchdog = setTimeout(() => {
6286
+ this.metadataWatchdog = null, !this.destroyed && Q(new Error("Video metadata load timeout"));
6287
+ }, 5e3), this.videoElement.addEventListener("loadedmetadata", async () => {
6288
+ this.clearMetadataWatchdog();
6269
6289
  try {
6270
6290
  await this.videoElement.play(), this.debugLog("✅ Video element is now playing:", {
6271
6291
  videoWidth: this.videoElement.videoWidth,
@@ -6273,11 +6293,11 @@ class iA {
6273
6293
  readyState: this.videoElement.readyState,
6274
6294
  paused: this.videoElement.paused
6275
6295
  }), I();
6276
- } catch (E) {
6277
- console.error("🔴 Failed to start video playback:", E), Q(E);
6296
+ } catch (g) {
6297
+ console.error("🔴 Failed to start video playback:", g), Q(g);
6278
6298
  }
6279
- }, { once: !0 }), this.videoElement.addEventListener("error", (E) => {
6280
- clearTimeout(g), Q(new Error(`Video load error: ${E}`));
6299
+ }, { once: !0 }), this.videoElement.addEventListener("error", (g) => {
6300
+ this.clearMetadataWatchdog(), Q(new Error(`Video load error: ${g}`));
6281
6301
  }, { once: !0 });
6282
6302
  }), this.canvas.width = this.videoElement.videoWidth, this.canvas.height = this.videoElement.videoHeight, this.coordinatorState.isConnected = !0, this.coordinatorState.frameWidth = this.videoElement.videoWidth, this.coordinatorState.frameHeight = this.videoElement.videoHeight, this.coordinatorState.sourceType = "MediaStream", await this.transferOffscreenCanvasToWorker(this.videoElement.videoWidth, this.videoElement.videoHeight), this.startTransferLoop(), this.debugLog("Video stream connected successfully (host-side coordinator)", {
6283
6303
  width: this.videoElement.videoWidth,
@@ -6323,7 +6343,7 @@ class iA {
6323
6343
  * Disconnect current video stream and clean up resources
6324
6344
  */
6325
6345
  disconnectVideoStream() {
6326
- this.stopTransferLoop(), this.videoElement && (this.videoElement.pause(), this.videoElement.srcObject = null, this.videoElement = null), this.canvas && (this.canvas = null, this.ctx = null), this.coordinatorState.isConnected = !1, this.coordinatorState.frameWidth = 0, this.coordinatorState.frameHeight = 0, this.coordinatorState.sourceType = "", this.hasTransferredCanvas = !1, this.sendDisconnectionToWorker(), this.debugLog("Video stream disconnected (host-side coordinator)");
6346
+ this.clearMetadataWatchdog(), this.stopTransferLoop(), this.videoElement && (this.videoElement.pause(), this.videoElement.srcObject = null, this.videoElement = null), this.canvas && (this.canvas = null, this.ctx = null), this.coordinatorState.isConnected = !1, this.coordinatorState.frameWidth = 0, this.coordinatorState.frameHeight = 0, this.coordinatorState.sourceType = "", this.hasTransferredCanvas = !1, this.sendDisconnectionToWorker(), this.debugLog("Video stream disconnected (host-side coordinator)");
6327
6347
  }
6328
6348
  /**
6329
6349
  * Start the video frame transfer loop
@@ -6431,29 +6451,36 @@ class iA {
6431
6451
  * Handle image file as video source
6432
6452
  */
6433
6453
  async setImageSource(A) {
6434
- try {
6435
- const B = new Image(), I = URL.createObjectURL(A);
6436
- await new Promise((g, E) => {
6437
- B.onload = () => {
6438
- URL.revokeObjectURL(I), g();
6439
- }, B.onerror = () => {
6440
- URL.revokeObjectURL(I), E(new Error("Failed to load image"));
6441
- }, B.src = I;
6442
- }), this.disconnectVideoStream(), this.coordinatorState.isConnected = !0, this.coordinatorState.frameWidth = B.width, this.coordinatorState.frameHeight = B.height, this.coordinatorState.sourceType = "Image", await this.transferOffscreenCanvasToWorker(B.width, B.height);
6443
- const Q = await createImageBitmap(B);
6444
- this.sendFrameToWorker(Q), this.debugLog("Image source set successfully (host-side coordinator)", {
6445
- width: B.width,
6446
- height: B.height
6447
- });
6448
- } catch (B) {
6449
- console.error("Failed to set image source:", B), this.coordinatorState.isConnected = !1, this.sendDisconnectionToWorker();
6450
- }
6454
+ if (!this.destroyed)
6455
+ try {
6456
+ const B = new Image(), I = URL.createObjectURL(A);
6457
+ await new Promise((g, E) => {
6458
+ B.onload = () => {
6459
+ URL.revokeObjectURL(I), g();
6460
+ }, B.onerror = () => {
6461
+ URL.revokeObjectURL(I), E(new Error("Failed to load image"));
6462
+ }, B.src = I;
6463
+ }), this.disconnectVideoStream(), this.coordinatorState.isConnected = !0, this.coordinatorState.frameWidth = B.width, this.coordinatorState.frameHeight = B.height, this.coordinatorState.sourceType = "Image", await this.transferOffscreenCanvasToWorker(B.width, B.height);
6464
+ const Q = await createImageBitmap(B);
6465
+ this.sendFrameToWorker(Q), this.debugLog("Image source set successfully (host-side coordinator)", {
6466
+ width: B.width,
6467
+ height: B.height
6468
+ });
6469
+ } catch (B) {
6470
+ console.error("Failed to set image source:", B), this.coordinatorState.isConnected = !1, this.sendDisconnectionToWorker();
6471
+ }
6451
6472
  }
6452
6473
  /**
6453
6474
  * Reset all video coordinator state (called when destroying)
6454
6475
  */
6455
6476
  resetVideoState() {
6456
- this.disconnectVideoStream();
6477
+ this.destroyed = !0, this.disconnectVideoStream();
6478
+ }
6479
+ /**
6480
+ * Cancel the pending metadata-load watchdog, if any.
6481
+ */
6482
+ clearMetadataWatchdog() {
6483
+ this.metadataWatchdog !== null && (clearTimeout(this.metadataWatchdog), this.metadataWatchdog = null);
6457
6484
  }
6458
6485
  /**
6459
6486
  * Get current coordinator configuration
@@ -8406,4 +8433,4 @@ export {
8406
8433
  S as b,
8407
8434
  vB as g
8408
8435
  };
8409
- //# sourceMappingURL=index-DkwlRK6X.js.map
8436
+ //# sourceMappingURL=index-CNBiAcmD.js.map
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { A as a, V as i, a as s, b as e } from "./index-DkwlRK6X.js";
1
+ import { A as a, V as i, a as s, b as e } from "./index-CNBiAcmD.js";
2
2
  export {
3
3
  a as AudioSystem,
4
4
  i as VERSION,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@viji-dev/core",
3
- "version": "0.7.7",
3
+ "version": "0.7.8",
4
4
  "description": "Universal execution engine for Viji Creative scenes",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",