@viji-dev/core 0.3.16 → 0.3.18

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.
@@ -7,9 +7,10 @@ class VijiCoreError extends Error {
7
7
  }
8
8
  }
9
9
  class IFrameManager {
10
- constructor(hostContainer, initialResolution) {
10
+ constructor(hostContainer, initialResolution, visible = true) {
11
11
  this.hostContainer = hostContainer;
12
12
  this.isHeadless = !hostContainer;
13
+ this.initiallyVisible = visible;
13
14
  if (typeof initialResolution === "object") {
14
15
  this.explicitResolution = initialResolution;
15
16
  } else if (typeof initialResolution === "number") {
@@ -49,6 +50,7 @@ class IFrameManager {
49
50
  activeTouchIds = /* @__PURE__ */ new Set();
50
51
  // Device sensor support
51
52
  deviceSensorCallback = null;
53
+ initiallyVisible;
52
54
  /**
53
55
  * Creates a secure IFrame with proper sandbox attributes
54
56
  */
@@ -71,7 +73,8 @@ class IFrameManager {
71
73
  document.body.appendChild(hiddenContainer);
72
74
  hiddenContainer.appendChild(iframe);
73
75
  } else {
74
- iframe.style.cssText = "width:100%;height:100%;border:none;display:block;";
76
+ const visibility = this.initiallyVisible ? "" : "visibility:hidden;";
77
+ iframe.style.cssText = `width:100%;height:100%;border:none;display:block;${visibility}`;
75
78
  this.hostContainer.appendChild(iframe);
76
79
  }
77
80
  const iframeContent = this.generateIFrameHTML();
@@ -286,6 +289,16 @@ class IFrameManager {
286
289
  get element() {
287
290
  return this.iframe;
288
291
  }
292
+ show() {
293
+ if (this.iframe && !this.isHeadless) {
294
+ this.iframe.style.visibility = "visible";
295
+ }
296
+ }
297
+ hide() {
298
+ if (this.iframe && !this.isHeadless) {
299
+ this.iframe.style.visibility = "hidden";
300
+ }
301
+ }
289
302
  /**
290
303
  * Generates the HTML content for the secure IFrame
291
304
  */
@@ -551,7 +564,7 @@ class IFrameManager {
551
564
  }
552
565
  function WorkerWrapper(options) {
553
566
  return new Worker(
554
- "" + new URL("assets/viji.worker-Cu6zt4AH.js", import.meta.url).href,
567
+ "" + new URL("assets/viji.worker-BnDb6mPh.js", import.meta.url).href,
555
568
  {
556
569
  type: "module",
557
570
  name: options?.name
@@ -1900,7 +1913,7 @@ class EssentiaOnsetDetection {
1900
1913
  this.initPromise = (async () => {
1901
1914
  try {
1902
1915
  const essentiaModule = await import("./essentia.js-core.es-DnrJE0uR.js");
1903
- const wasmModule = await import("./essentia-wasm.web-BfRYq8Vx.js").then((n) => n.e);
1916
+ const wasmModule = await import("./essentia-wasm.web-yEo8eq6n.js").then((n) => n.e);
1904
1917
  const EssentiaClass = essentiaModule.Essentia || essentiaModule.default?.Essentia || essentiaModule.default;
1905
1918
  let WASMModule = wasmModule.default || wasmModule.EssentiaWASM || wasmModule.default?.EssentiaWASM;
1906
1919
  if (!WASMModule) {
@@ -14636,7 +14649,6 @@ class VijiCore {
14636
14649
  * Enable auto-capture with optional format (internal, called by linkFrameSources)
14637
14650
  */
14638
14651
  enableAutoCapture(format) {
14639
- if (this.autoCaptureEnabled) return;
14640
14652
  this.autoCaptureEnabled = true;
14641
14653
  if (this.workerManager) {
14642
14654
  this.workerManager.postMessage("enable-auto-capture", {
@@ -14695,6 +14707,21 @@ class VijiCore {
14695
14707
  getDebugMode() {
14696
14708
  return this.debugMode;
14697
14709
  }
14710
+ /**
14711
+ * Show the core's iframe (make it visible in the host container).
14712
+ * No-op for headless cores.
14713
+ */
14714
+ show() {
14715
+ this.iframeManager?.show();
14716
+ }
14717
+ /**
14718
+ * Hide the core's iframe (keep rendering but invisible).
14719
+ * Useful for create-in-background, reveal-when-ready patterns.
14720
+ * No-op for headless cores.
14721
+ */
14722
+ hide() {
14723
+ this.iframeManager?.hide();
14724
+ }
14698
14725
  /**
14699
14726
  * Select audio analysis backend
14700
14727
  */
@@ -14725,7 +14752,8 @@ class VijiCore {
14725
14752
  }
14726
14753
  this.iframeManager = new IFrameManager(
14727
14754
  this.config.hostContainer || null,
14728
- this.config.resolution
14755
+ this.config.resolution,
14756
+ this.config.visible ?? true
14729
14757
  );
14730
14758
  await this.iframeManager.createSecureIFrame();
14731
14759
  const offscreenCanvas = await this.createCanvasWithRetry();
@@ -15181,26 +15209,59 @@ class VijiCore {
15181
15209
  timestamp: performance.now()
15182
15210
  });
15183
15211
  }
15212
+ // ═══════════════════════════════════════════════════════════════════════════
15213
+ // Direct Frame Injection API (Compositor Pipeline)
15214
+ // ═══════════════════════════════════════════════════════════════════════════
15184
15215
  /**
15185
- * Inject frames directly (compositor pipeline)
15216
+ * Worker-side stream index offset for direct frame slots.
15217
+ * Accounts for main video stream and additional media streams.
15186
15218
  */
15187
- injectFrames(bitmaps) {
15219
+ get directFrameStartIndex() {
15220
+ return (this.videoStream ? 1 : 0) + this.videoStreams.length;
15221
+ }
15222
+ /**
15223
+ * Ensure the worker has enough direct frame slots prepared.
15224
+ * Auto-grows as needed; skips if already sufficient.
15225
+ */
15226
+ ensureDirectFrameSlots(count) {
15227
+ if (count <= this.directFrameSlots) return;
15228
+ this.directFrameSlots = count;
15229
+ this.workerManager.postMessage("video-streams-prepare", {
15230
+ mainStream: !!this.videoStream,
15231
+ mediaStreamCount: this.videoStreams.length,
15232
+ directFrameCount: count
15233
+ });
15234
+ this.debugLog(`[Compositor] Prepared ${count} direct frame slot(s)`);
15235
+ }
15236
+ /**
15237
+ * Inject a single frame into a specific direct-frame stream slot.
15238
+ * Allows independent per-stream updates (e.g. during source hot-swap).
15239
+ * Auto-prepares slots as needed. Transfers ownership of the bitmap (zero-copy).
15240
+ */
15241
+ injectFrame(bitmap, streamIndex) {
15188
15242
  if (!this.workerManager?.ready) {
15189
15243
  throw new VijiCoreError("Core not ready", "NOT_READY");
15190
15244
  }
15191
- const directFrameStartIndex = (this.videoStream ? 1 : 0) + this.videoStreams.length;
15192
- if (this.directFrameSlots === 0) {
15193
- this.directFrameSlots = bitmaps.length;
15194
- this.workerManager.postMessage("video-streams-prepare", {
15195
- mainStream: !!this.videoStream,
15196
- mediaStreamCount: this.videoStreams.length,
15197
- directFrameCount: bitmaps.length
15198
- });
15245
+ this.ensureDirectFrameSlots(streamIndex + 1);
15246
+ this.workerManager.postMessage("video-frame-direct", {
15247
+ imageBitmap: bitmap,
15248
+ streamIndex: this.directFrameStartIndex + streamIndex,
15249
+ timestamp: performance.now()
15250
+ }, [bitmap]);
15251
+ }
15252
+ /**
15253
+ * Inject frames for all direct-frame stream slots at once (compositor pipeline).
15254
+ * Auto-prepares slots on first call. Transfers ownership of all bitmaps (zero-copy).
15255
+ */
15256
+ injectFrames(bitmaps) {
15257
+ if (!this.workerManager?.ready) {
15258
+ throw new VijiCoreError("Core not ready", "NOT_READY");
15199
15259
  }
15260
+ this.ensureDirectFrameSlots(bitmaps.length);
15200
15261
  bitmaps.forEach((bitmap, index) => {
15201
15262
  this.workerManager.postMessage("video-frame-direct", {
15202
15263
  imageBitmap: bitmap,
15203
- streamIndex: directFrameStartIndex + index,
15264
+ streamIndex: this.directFrameStartIndex + index,
15204
15265
  timestamp: performance.now()
15205
15266
  }, [bitmap]);
15206
15267
  });
@@ -16191,6 +16252,7 @@ class VijiCore {
16191
16252
  this.latestFrameBuffer.close();
16192
16253
  this.latestFrameBuffer = null;
16193
16254
  }
16255
+ this.directFrameSlots = 0;
16194
16256
  this.videoStream = null;
16195
16257
  this.videoStreams = [];
16196
16258
  await this.cleanup();
@@ -16258,4 +16320,4 @@ export {
16258
16320
  VijiCoreError as b,
16259
16321
  getDefaultExportFromCjs as g
16260
16322
  };
16261
- //# sourceMappingURL=index-CcPOjcNA.js.map
16323
+ //# sourceMappingURL=index-BSQyI1F-.js.map