@viji-dev/core 0.8.6 → 0.8.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
- "coreVersion": "0.8.5",
4
- "generatedAt": "2026-06-03T09:18:41.915Z",
3
+ "coreVersion": "0.8.7",
4
+ "generatedAt": "2026-06-03T12:10:59.795Z",
5
5
  "navigation": [
6
6
  {
7
7
  "id": "getting-started",
@@ -1,4 +1,4 @@
1
- import { g as kn } from "./index-BQtrhfjg.js";
1
+ import { g as kn } from "./index-DSMvbzzU.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-CaXce3AA.js.map
3377
+ //# sourceMappingURL=essentia-wasm.web-BqymfxZb.js.map
@@ -536,7 +536,7 @@ class DB {
536
536
  }
537
537
  }
538
538
  }
539
- const hB = "" + new URL("assets/viji.worker-CydIeq-k.js", import.meta.url).href, RB = new URL("assets/wasm/vision_wasm_internal.js", import.meta.url).href, wB = new URL("assets/wasm/vision_wasm_internal.wasm", import.meta.url).href, sB = new URL("assets/wasm/vision_wasm_nosimd_internal.js", import.meta.url).href, FB = new URL("assets/wasm/vision_wasm_nosimd_internal.wasm", import.meta.url).href;
539
+ const hB = "" + new URL("assets/viji.worker-ChptZ-zo.js", import.meta.url).href, RB = new URL("assets/wasm/vision_wasm_internal.js", import.meta.url).href, wB = new URL("assets/wasm/vision_wasm_internal.wasm", import.meta.url).href, sB = new URL("assets/wasm/vision_wasm_nosimd_internal.js", import.meta.url).href, FB = new URL("assets/wasm/vision_wasm_nosimd_internal.wasm", import.meta.url).href;
540
540
  class kB {
541
541
  constructor(A, B, I) {
542
542
  this.iframeManager = A, this.sceneCode = B, this.init = I;
@@ -652,7 +652,10 @@ class kB {
652
652
  R(G.data);
653
653
  }, this.controlPort.onmessage = this.onControlPortMessageBound;
654
654
  }
655
- this.postMessage("set-scene-code", { sceneCode: this.sceneCode }), this.isInitialized = !0;
655
+ this.postMessage("set-scene-code", {
656
+ sceneCode: this.sceneCode,
657
+ ...this.init.initialParameters && { initialParameters: this.init.initialParameters }
658
+ }), this.isInitialized = !0;
656
659
  } catch (A) {
657
660
  throw A instanceof S && A.code === "INITIALIZATION_CANCELLED" ? A : this.isDestroyed ? new S(
658
661
  "Initialization cancelled",
@@ -1520,7 +1523,7 @@ class lB {
1520
1523
  if (!this.isInitialized)
1521
1524
  return this.initPromise ? this.initPromise : (this.initPromise = (async () => {
1522
1525
  try {
1523
- const A = await import("./essentia.js-core.es-CC_3Ap1i.js"), B = await import("./essentia-wasm.web-CaXce3AA.js").then((g) => g.e), I = A.Essentia || A.default?.Essentia || A.default;
1526
+ const A = await import("./essentia.js-core.es-CC_3Ap1i.js"), B = await import("./essentia-wasm.web-BqymfxZb.js").then((g) => g.e), I = A.Essentia || A.default?.Essentia || A.default;
1524
1527
  let Q = B.default || B.EssentiaWASM || B.default?.EssentiaWASM;
1525
1528
  if (!Q)
1526
1529
  throw new Error("WASM module not found - check essentia-wasm.web.js export");
@@ -6941,7 +6944,9 @@ class K {
6941
6944
  isInitializing = !1;
6942
6945
  instanceId;
6943
6946
  screenRefreshRate = 60;
6944
- // Will be detected
6947
+ // Sensible default (most common rate); refined asynchronously after init
6948
+ refreshRateRafId = null;
6949
+ // Handle for the non-blocking refresh-rate measurement loop
6945
6950
  debugMode = !1;
6946
6951
  // Debug logging control
6947
6952
  /**
@@ -7178,6 +7183,7 @@ class K {
7178
7183
  allowSensors: !!this.deviceSensorManager,
7179
7184
  sc: this.config._sc,
7180
7185
  rh: this.config._rh,
7186
+ ...this.config.initialParameters && { initialParameters: this.config.initialParameters },
7181
7187
  reporterConfig: oI(this.config)
7182
7188
  }
7183
7189
  ), this.setupCommunication(), await this.workerManager.createWorker(), this.isDestroyed)
@@ -7219,11 +7225,7 @@ class K {
7219
7225
  effectiveWidth: A.width,
7220
7226
  effectiveHeight: A.height,
7221
7227
  displayScale: this.iframeManager.getDisplayScale()
7222
- }), await this.detectScreenRefreshRate(), this.isDestroyed)
7223
- throw new S("Initialization cancelled", "INITIALIZATION_CANCELLED");
7224
- if (this.workerManager.postMessage("refresh-rate-update", {
7225
- screenRefreshRate: this.screenRefreshRate
7226
- }), this.config.audioStream && await this.setAudioStream(this.config.audioStream), this.isDestroyed)
7228
+ }), this.detectScreenRefreshRate(), this.config.audioStream && await this.setAudioStream(this.config.audioStream), this.isDestroyed)
7227
7229
  throw new S("Initialization cancelled", "INITIALIZATION_CANCELLED");
7228
7230
  for (let B = 0; B < this.audioStreams.length; B++) {
7229
7231
  const I = K.AUDIO_ADDITIONAL_BASE + B;
@@ -8503,19 +8505,30 @@ class K {
8503
8505
  }), this.stats.resolution = B, this.syncFrameSourceQuality(), this.debugLog(`Resolution: ${B.width}x${B.height}`);
8504
8506
  }
8505
8507
  /**
8506
- * Detects the screen refresh rate
8508
+ * Measures the screen refresh rate over 60 animation frames, off the init
8509
+ * critical path. Runs fire-and-forget: it does NOT gate `ready`, so the host
8510
+ * can control a visibly-rendering core immediately. On completion it pushes
8511
+ * the refined value to the worker (refresh-rate-update) and updates host
8512
+ * stats. Until then both sides use the 60 default. Measured once, never
8513
+ * re-run. Cancelled on `destroy()` via `refreshRateRafId`.
8507
8514
  */
8508
- async detectScreenRefreshRate() {
8509
- return new Promise((A) => {
8510
- let B = 0;
8511
- const I = performance.now(), Q = () => {
8512
- if (B++, B === 60) {
8513
- const g = performance.now() - I;
8514
- this.screenRefreshRate = Math.round(6e4 / g), this.debugLog("Detected screen refresh rate:", this.screenRefreshRate + "Hz"), A();
8515
- } else B < 60 && requestAnimationFrame(Q);
8516
- };
8517
- requestAnimationFrame(Q);
8518
- });
8515
+ detectScreenRefreshRate() {
8516
+ let A = 0;
8517
+ const B = performance.now(), I = () => {
8518
+ if (this.isDestroyed) {
8519
+ this.refreshRateRafId = null;
8520
+ return;
8521
+ }
8522
+ if (A++, A === 60) {
8523
+ this.refreshRateRafId = null;
8524
+ const Q = performance.now() - B;
8525
+ if (this.screenRefreshRate = Math.round(6e4 / Q), this.debugLog("Detected screen refresh rate:", this.screenRefreshRate + "Hz"), this.isDestroyed || !this.workerManager) return;
8526
+ this.workerManager.postMessage("refresh-rate-update", {
8527
+ screenRefreshRate: this.screenRefreshRate
8528
+ }), this.stats.frameRate.screenRefreshRate = this.screenRefreshRate;
8529
+ } else A < 60 && (this.refreshRateRafId = requestAnimationFrame(I));
8530
+ };
8531
+ this.refreshRateRafId = requestAnimationFrame(I);
8519
8532
  }
8520
8533
  /**
8521
8534
  * Updates frame rate statistics
@@ -8695,7 +8708,7 @@ class K {
8695
8708
  */
8696
8709
  async destroy() {
8697
8710
  if (!this.isDestroyed) {
8698
- this.isDestroyed = !0, this.parameterGroups.clear(), this.parameterValues.clear(), this.parameterListeners.clear(), this.parameterDefinedListeners.clear(), this.parameterErrorListeners.clear(), this.capabilitiesChangeListeners.clear(), this.stateImportErrorListeners.clear(), this.sceneRuntimeErrorListeners.clear(), this.sceneConsoleListeners.clear(), this.performanceSnapshotListeners.clear(), this.capabilityTransitionListeners.clear(), this.unlinkEventSource(), this.unlinkFrameSources();
8711
+ this.isDestroyed = !0, this.refreshRateRafId !== null && (cancelAnimationFrame(this.refreshRateRafId), this.refreshRateRafId = null), this.parameterGroups.clear(), this.parameterValues.clear(), this.parameterListeners.clear(), this.parameterDefinedListeners.clear(), this.parameterErrorListeners.clear(), this.capabilitiesChangeListeners.clear(), this.stateImportErrorListeners.clear(), this.sceneRuntimeErrorListeners.clear(), this.sceneConsoleListeners.clear(), this.performanceSnapshotListeners.clear(), this.capabilityTransitionListeners.clear(), this.unlinkEventSource(), this.unlinkFrameSources();
8699
8712
  for (const [A] of this.deviceVideoCoordinators)
8700
8713
  await this.clearDeviceVideo(A);
8701
8714
  this.deviceVideoCoordinators.clear(), this.deviceVideoStreamIndices.clear(), this.deviceSensorManager && (this.deviceSensorManager.destroy(), this.deviceSensorManager = null);
@@ -8754,7 +8767,7 @@ function DI(h) {
8754
8767
  expectedVersion: 1
8755
8768
  } : typeof A.senderTime != "number" ? { code: "invalid-field", details: "senderTime must be a number", field: "senderTime" } : null;
8756
8769
  }
8757
- const hI = "0.8.5";
8770
+ const hI = "0.8.7";
8758
8771
  export {
8759
8772
  yA as A,
8760
8773
  hI as V,
@@ -8762,4 +8775,4 @@ export {
8762
8775
  S as b,
8763
8776
  PB as g
8764
8777
  };
8765
- //# sourceMappingURL=index-BQtrhfjg.js.map
8778
+ //# sourceMappingURL=index-DSMvbzzU.js.map
package/dist/index.d.ts CHANGED
@@ -1273,14 +1273,16 @@ export declare interface FramePerfSample {
1273
1273
  declare interface FrameRateInfo {
1274
1274
  mode: FrameRateMode;
1275
1275
  /**
1276
- * Best-effort display refresh rate in Hz, detected once at init by averaging
1277
- * 60 `requestAnimationFrame` intervals.
1276
+ * Best-effort display refresh rate in Hz, measured once by averaging 60
1277
+ * `requestAnimationFrame` intervals. The measurement runs asynchronously and
1278
+ * does not block `initialize()`, so for the first few seconds after init this
1279
+ * reads the `60` default until the measured value lands.
1278
1280
  *
1279
1281
  * **Not reliable under load** — if the page is already GPU-stressed during
1280
1282
  * initialization, throttled rAFs inflate the interval and deflate the value
1281
1283
  * (e.g. 10 Hz on a 60 Hz monitor), and it is never re-measured. rAF cadence
1282
1284
  * cannot recover the true refresh post-load. **Do not derive performance
1283
- * thresholds from this** — prefer an absolute FPS target.
1285
+ * thresholds from this** — prefer an absolute FPS target or `effectiveRefreshRate`.
1284
1286
  */
1285
1287
  screenRefreshRate: number;
1286
1288
  effectiveRefreshRate: number;
@@ -2657,7 +2659,7 @@ declare type TrackingState = 'TRACKING' | 'LOCKED' | 'BREAKDOWN' | 'LOST';
2657
2659
  /** Returned by `on*` listener registration calls; invoke to unsubscribe. */
2658
2660
  export declare type Unsubscribe = () => void;
2659
2661
 
2660
- export declare const VERSION = "0.8.5";
2662
+ export declare const VERSION = "0.8.7";
2661
2663
 
2662
2664
  /**
2663
2665
  * Real-time video API: drawable frame, dimensions, and the source-side
@@ -3022,6 +3024,7 @@ export declare class VijiCore {
3022
3024
  private isInitializing;
3023
3025
  private instanceId;
3024
3026
  private screenRefreshRate;
3027
+ private refreshRateRafId;
3025
3028
  private debugMode;
3026
3029
  /**
3027
3030
  * Debug logging helper
@@ -3818,7 +3821,12 @@ export declare class VijiCore {
3818
3821
  height: number;
3819
3822
  }): void;
3820
3823
  /**
3821
- * Detects the screen refresh rate
3824
+ * Measures the screen refresh rate over 60 animation frames, off the init
3825
+ * critical path. Runs fire-and-forget: it does NOT gate `ready`, so the host
3826
+ * can control a visibly-rendering core immediately. On completion it pushes
3827
+ * the refined value to the worker (refresh-rate-update) and updates host
3828
+ * stats. Until then both sides use the 60 default. Measured once, never
3829
+ * re-run. Cancelled on `destroy()` via `refreshRateRafId`.
3822
3830
  */
3823
3831
  private detectScreenRefreshRate;
3824
3832
  /**
@@ -3954,6 +3962,16 @@ export declare interface VijiCoreConfig {
3954
3962
  hostContainer?: HTMLElement;
3955
3963
  /** Artist scene code to execute */
3956
3964
  sceneCode: string;
3965
+ /**
3966
+ * Parameter values to seed before the first frame, keyed by parameter name.
3967
+ * Applied in the worker right after the scene defines each parameter (at its
3968
+ * default) and before the first render, so the scene paints frame 1 with these
3969
+ * values instead of popping from defaults a round-trip later. Names the scene
3970
+ * does not define are silently ignored; values are validated against each
3971
+ * parameter's definition exactly like {@link VijiCore.setParameter}. File /
3972
+ * Blob / image-bitmap parameters are not seedable (serializable values only).
3973
+ */
3974
+ initialParameters?: Record<string, ParameterValue>;
3957
3975
  /** Frame rate mode - render every frame (`'full'`), every 2nd (`'half'`), every 4th (`'quarter'`), or every 8th (`'eighth'`). */
3958
3976
  frameRateMode?: FrameRateMode;
3959
3977
  /** Resolution: scale (number) or explicit dimensions (object). Required for headless, must be object form */
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-BQtrhfjg.js";
1
+ import { A as a, V as i, a as s, b as e } from "./index-DSMvbzzU.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.8.6",
3
+ "version": "0.8.8",
4
4
  "description": "Universal execution engine for Viji Creative scenes",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",