@viji-dev/core 0.5.6 → 0.5.7

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.
@@ -100,6 +100,13 @@ class IFrameManager {
100
100
  iframeReadyPromise = null;
101
101
  iframeReadyResolver = null;
102
102
  iframeReadyRejecter = null;
103
+ /**
104
+ * 5s safety timer that rejects `iframeReadyPromise` if the inline-script
105
+ * never emits `iframe-ready` (e.g. blob script error). Promoted from
106
+ * closure-captured local to instance state so `destroy()` can clear it
107
+ * on cancellation (docs/14 rule 5).
108
+ */
109
+ iframeReadyTimeoutId = null;
103
110
  lockedOrigin = null;
104
111
  // Window message dispatch
105
112
  hostMessageListener = null;
@@ -159,6 +166,8 @@ class IFrameManager {
159
166
  this.iframeReadyResolver = resolve;
160
167
  this.iframeReadyRejecter = reject;
161
168
  });
169
+ this.iframeReadyPromise.catch(() => {
170
+ });
162
171
  this.installHostMessageListener(iframe);
163
172
  const iframeContent = this.generateIFrameHTML();
164
173
  const blob = new Blob([iframeContent], { type: "text/html" });
@@ -184,7 +193,8 @@ class IFrameManager {
184
193
  iframe.style.cssText = `position:absolute;top:0;left:0;width:100%;height:100%;border:none;${visibility}`;
185
194
  this.hostContainer.appendChild(iframe);
186
195
  }
187
- const timeoutId = setTimeout(() => {
196
+ this.iframeReadyTimeoutId = setTimeout(() => {
197
+ this.iframeReadyTimeoutId = null;
188
198
  if (this.iframeReadyRejecter) {
189
199
  const r = this.iframeReadyRejecter;
190
200
  this.iframeReadyResolver = null;
@@ -192,11 +202,6 @@ class IFrameManager {
192
202
  r(new VijiCoreError("IFrame load timeout", "IFRAME_TIMEOUT"));
193
203
  }
194
204
  }, 5e3);
195
- const originalResolver = this.iframeReadyResolver;
196
- this.iframeReadyResolver = () => {
197
- clearTimeout(timeoutId);
198
- originalResolver();
199
- };
200
205
  iframe.onerror = () => {
201
206
  if (this.iframeReadyRejecter) {
202
207
  this.iframeReadyRejecter(
@@ -323,6 +328,10 @@ class IFrameManager {
323
328
  switch (msg.type) {
324
329
  case "iframe-ready": {
325
330
  this.lockedOrigin = OPAQUE_ORIGIN;
331
+ if (this.iframeReadyTimeoutId !== null) {
332
+ clearTimeout(this.iframeReadyTimeoutId);
333
+ this.iframeReadyTimeoutId = null;
334
+ }
326
335
  if (this.iframeReadyResolver) {
327
336
  const r = this.iframeReadyResolver;
328
337
  this.iframeReadyResolver = null;
@@ -463,6 +472,16 @@ class IFrameManager {
463
472
  */
464
473
  destroy() {
465
474
  try {
475
+ if (this.iframeReadyTimeoutId !== null) {
476
+ clearTimeout(this.iframeReadyTimeoutId);
477
+ this.iframeReadyTimeoutId = null;
478
+ }
479
+ if (this.iframeReadyRejecter) {
480
+ const r = this.iframeReadyRejecter;
481
+ this.iframeReadyResolver = null;
482
+ this.iframeReadyRejecter = null;
483
+ r(new VijiCoreError("Initialization cancelled", "INITIALIZATION_CANCELLED"));
484
+ }
466
485
  if (this.iframe?.contentWindow && this.lockedOrigin) {
467
486
  try {
468
487
  this.postEnvelope({ type: "viji-terminate" });
@@ -670,6 +689,20 @@ class WorkerManager {
670
689
  */
671
690
  controlPort = null;
672
691
  onControlPortMessageBound = null;
692
+ /**
693
+ * Bootstrap-window cancellation state. The 10s `viji-ready` timer and
694
+ * the in-flight `vijiReady` rejecter are tracked on the instance so
695
+ * `destroy()` can cancel an in-progress bootstrap synchronously
696
+ * (clearing the timer + rejecting the awaiter with
697
+ * `INITIALIZATION_CANCELLED`). `isDestroyed` is the synchronous flag
698
+ * the outer catch in `createWorker` consults to distinguish a
699
+ * destroy-mid-init from a genuine bootstrap failure (e.g. the
700
+ * `postEnvelope` synchronous throw path, where no cancellation error
701
+ * was rejected through the awaiter).
702
+ */
703
+ bootstrapTimeoutId = null;
704
+ bootstrapReject = null;
705
+ isDestroyed = false;
673
706
  /**
674
707
  * Bootstraps the worker inside the iframe.
675
708
  *
@@ -723,7 +756,9 @@ class WorkerManager {
723
756
  }
724
757
  };
725
758
  const vijiReady = new Promise((resolve, reject) => {
726
- const timeoutId = setTimeout(() => {
759
+ this.bootstrapReject = reject;
760
+ this.bootstrapTimeoutId = setTimeout(() => {
761
+ this.bootstrapTimeoutId = null;
727
762
  reject(
728
763
  new VijiCoreError(
729
764
  "viji-ready timeout",
@@ -732,15 +767,29 @@ class WorkerManager {
732
767
  );
733
768
  }, 1e4);
734
769
  this.iframeManager.onVijiReady(() => {
735
- clearTimeout(timeoutId);
770
+ if (this.bootstrapTimeoutId !== null) {
771
+ clearTimeout(this.bootstrapTimeoutId);
772
+ this.bootstrapTimeoutId = null;
773
+ }
774
+ this.bootstrapReject = null;
736
775
  resolve();
737
776
  });
738
777
  });
739
- this.iframeManager.postEnvelope(
740
- bootstrap,
741
- collectBootstrapTransferables(bootstrap)
742
- );
743
- await vijiReady;
778
+ vijiReady.catch(() => {
779
+ });
780
+ try {
781
+ this.iframeManager.postEnvelope(
782
+ bootstrap,
783
+ collectBootstrapTransferables(bootstrap)
784
+ );
785
+ await vijiReady;
786
+ } finally {
787
+ if (this.bootstrapTimeoutId !== null) {
788
+ clearTimeout(this.bootstrapTimeoutId);
789
+ this.bootstrapTimeoutId = null;
790
+ }
791
+ this.bootstrapReject = null;
792
+ }
744
793
  this.controlPort = this.iframeManager.getControlPort1();
745
794
  if (this.controlPort && this.onWorkerMessageBound) {
746
795
  const dispatcher = this.onWorkerMessageBound;
@@ -752,6 +801,15 @@ class WorkerManager {
752
801
  this.postMessage("set-scene-code", { sceneCode: this.sceneCode });
753
802
  this.isInitialized = true;
754
803
  } catch (error) {
804
+ if (error instanceof VijiCoreError && error.code === "INITIALIZATION_CANCELLED") {
805
+ throw error;
806
+ }
807
+ if (this.isDestroyed) {
808
+ throw new VijiCoreError(
809
+ "Initialization cancelled",
810
+ "INITIALIZATION_CANCELLED"
811
+ );
812
+ }
755
813
  throw new VijiCoreError(
756
814
  `Failed to create worker: ${error}`,
757
815
  "WORKER_CREATION_ERROR",
@@ -856,6 +914,16 @@ class WorkerManager {
856
914
  */
857
915
  destroy() {
858
916
  try {
917
+ this.isDestroyed = true;
918
+ if (this.bootstrapTimeoutId !== null) {
919
+ clearTimeout(this.bootstrapTimeoutId);
920
+ this.bootstrapTimeoutId = null;
921
+ }
922
+ if (this.bootstrapReject) {
923
+ const r = this.bootstrapReject;
924
+ this.bootstrapReject = null;
925
+ r(new VijiCoreError("Initialization cancelled", "INITIALIZATION_CANCELLED"));
926
+ }
859
927
  this.pendingMessages.forEach(({ timeout, reject }) => {
860
928
  clearTimeout(timeout);
861
929
  reject(new VijiCoreError("Worker destroyed", "WORKER_DESTROYED"));
@@ -1897,7 +1965,7 @@ class EssentiaOnsetDetection {
1897
1965
  this.initPromise = (async () => {
1898
1966
  try {
1899
1967
  const essentiaModule = await import("./essentia.js-core.es-DnrJE0uR.js");
1900
- const wasmModule = await import("./essentia-wasm.web-B2bIxnGE.js").then((n) => n.e);
1968
+ const wasmModule = await import("./essentia-wasm.web-htE1Skqw.js").then((n) => n.e);
1901
1969
  const EssentiaClass = essentiaModule.Essentia || essentiaModule.default?.Essentia || essentiaModule.default;
1902
1970
  let WASMModule = wasmModule.default || wasmModule.EssentiaWASM || wasmModule.default?.EssentiaWASM;
1903
1971
  if (!WASMModule) {
@@ -10048,6 +10116,9 @@ class VijiCore {
10048
10116
  } catch (error) {
10049
10117
  this.isInitializing = false;
10050
10118
  await this.cleanup();
10119
+ if (error instanceof VijiCoreError && (error.code === "INITIALIZATION_CANCELLED" || error.code === "INSTANCE_DESTROYED")) {
10120
+ throw error;
10121
+ }
10051
10122
  throw new VijiCoreError(
10052
10123
  `Failed to initialize VijiCore: ${error}`,
10053
10124
  "INITIALIZATION_ERROR",
@@ -11753,7 +11824,7 @@ function validateCoreStatePayload(state) {
11753
11824
  }
11754
11825
  return null;
11755
11826
  }
11756
- const VERSION = "0.5.6";
11827
+ const VERSION = "0.5.7";
11757
11828
  export {
11758
11829
  AudioSystem as A,
11759
11830
  VERSION as V,
@@ -11761,4 +11832,4 @@ export {
11761
11832
  VijiCoreError as b,
11762
11833
  getDefaultExportFromCjs as g
11763
11834
  };
11764
- //# sourceMappingURL=index-Yg6_UX8C.js.map
11835
+ //# sourceMappingURL=index-CwwVLcjs.js.map