wavesurfer.js 7.12.7 → 7.12.9

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.
Files changed (72) hide show
  1. package/README.md +12 -6
  2. package/dist/__tests__/dom.test.js +17 -1
  3. package/dist/__tests__/drag-stream.test.d.ts +1 -0
  4. package/dist/__tests__/drag-stream.test.js +108 -0
  5. package/dist/__tests__/draggable.test.js +34 -0
  6. package/dist/__tests__/hover.test.js +35 -7
  7. package/dist/__tests__/regions.test.js +39 -0
  8. package/dist/__tests__/renderer.test.js +4 -0
  9. package/dist/__tests__/wavesurfer.test.js +13 -0
  10. package/dist/__tests__/webaudio.test.js +25 -0
  11. package/dist/dom.d.ts +5 -0
  12. package/dist/dom.js +12 -0
  13. package/dist/draggable.js +14 -4
  14. package/dist/fetcher.js +31 -10
  15. package/dist/fft.js +5 -1
  16. package/dist/player.d.ts +1 -0
  17. package/dist/player.js +13 -4
  18. package/dist/plugins/envelope.cjs +1 -1
  19. package/dist/plugins/envelope.esm.js +1 -1
  20. package/dist/plugins/envelope.js +1 -1
  21. package/dist/plugins/envelope.min.js +1 -1
  22. package/dist/plugins/hover.cjs +1 -1
  23. package/dist/plugins/hover.d.ts +2 -0
  24. package/dist/plugins/hover.esm.js +1 -1
  25. package/dist/plugins/hover.js +1 -1
  26. package/dist/plugins/hover.min.js +1 -1
  27. package/dist/plugins/minimap.cjs +1 -1
  28. package/dist/plugins/minimap.esm.js +1 -1
  29. package/dist/plugins/minimap.js +1 -1
  30. package/dist/plugins/minimap.min.js +1 -1
  31. package/dist/plugins/record.cjs +1 -1
  32. package/dist/plugins/record.esm.js +1 -1
  33. package/dist/plugins/record.js +1 -1
  34. package/dist/plugins/record.min.js +1 -1
  35. package/dist/plugins/regions.cjs +1 -1
  36. package/dist/plugins/regions.d.ts +1 -0
  37. package/dist/plugins/regions.esm.js +1 -1
  38. package/dist/plugins/regions.js +1 -1
  39. package/dist/plugins/regions.min.js +1 -1
  40. package/dist/plugins/spectrogram-windowed.cjs +1 -1
  41. package/dist/plugins/spectrogram-windowed.esm.js +1 -1
  42. package/dist/plugins/spectrogram-windowed.js +1 -1
  43. package/dist/plugins/spectrogram-windowed.min.js +1 -1
  44. package/dist/plugins/spectrogram.cjs +1 -1
  45. package/dist/plugins/spectrogram.d.ts +7 -0
  46. package/dist/plugins/spectrogram.esm.js +1 -1
  47. package/dist/plugins/spectrogram.js +1 -1
  48. package/dist/plugins/spectrogram.min.js +1 -1
  49. package/dist/plugins/timeline.cjs +1 -1
  50. package/dist/plugins/timeline.esm.js +1 -1
  51. package/dist/plugins/timeline.js +1 -1
  52. package/dist/plugins/timeline.min.js +1 -1
  53. package/dist/plugins/zoom.cjs +1 -1
  54. package/dist/plugins/zoom.d.ts +1 -0
  55. package/dist/plugins/zoom.esm.js +1 -1
  56. package/dist/plugins/zoom.js +1 -1
  57. package/dist/plugins/zoom.min.js +1 -1
  58. package/dist/reactive/drag-stream.js +14 -4
  59. package/dist/reactive/state-event-emitter.js +7 -0
  60. package/dist/renderer-utils.js +4 -2
  61. package/dist/renderer.d.ts +2 -0
  62. package/dist/renderer.js +23 -11
  63. package/dist/timer.js +1 -0
  64. package/dist/types.d.ts +18 -2
  65. package/dist/wavesurfer.cjs +1 -1
  66. package/dist/wavesurfer.d.ts +2 -0
  67. package/dist/wavesurfer.esm.js +1 -1
  68. package/dist/wavesurfer.js +35 -6
  69. package/dist/wavesurfer.min.js +1 -1
  70. package/dist/webaudio.d.ts +5 -0
  71. package/dist/webaudio.js +54 -3
  72. package/package.json +15 -14
package/dist/webaudio.js CHANGED
@@ -45,6 +45,7 @@ class WebAudioPlayer extends EventEmitter {
45
45
  this.addEventListener = this.on;
46
46
  /** Unsubscribe from an event */
47
47
  this.removeEventListener = this.un;
48
+ this._destroyed = false;
48
49
  setWebAudioSessionPlayback();
49
50
  this.audioContext = audioContext || new AudioContext();
50
51
  this.gainNode = this.audioContext.createGain();
@@ -55,6 +56,42 @@ class WebAudioPlayer extends EventEmitter {
55
56
  return;
56
57
  });
57
58
  }
59
+ /** For compatibility with HTMLMediaElement.remove(). Delegates to destroy(). */
60
+ remove() {
61
+ this.destroy();
62
+ }
63
+ /** Clean up all resources. Idempotent — safe to call multiple times. */
64
+ destroy() {
65
+ if (this._destroyed)
66
+ return;
67
+ this._destroyed = true;
68
+ // Clear currentSrc so any in-flight fetch/decode chains bail out
69
+ // via their existing `this.currentSrc !== value` guards
70
+ this.currentSrc = '';
71
+ // Stop and disconnect buffer node
72
+ if (this.bufferNode) {
73
+ this.bufferNode.onended = null;
74
+ try {
75
+ this.bufferNode.stop();
76
+ }
77
+ catch (_a) {
78
+ // Ignore InvalidStateError if node already stopped
79
+ }
80
+ this.bufferNode.disconnect();
81
+ this.bufferNode = null;
82
+ }
83
+ // Disconnect gain node
84
+ this.gainNode.disconnect();
85
+ // Close audio context (returns a promise, catch rejection if already closed)
86
+ // Guard with typeof check for mock environments where close may not exist
87
+ if (typeof this.audioContext.close === 'function') {
88
+ Promise.resolve(this.audioContext.close.call(this.audioContext)).catch(() => undefined);
89
+ }
90
+ // Clear buffer reference
91
+ this.buffer = null;
92
+ // Clear all event listeners
93
+ this.unAll();
94
+ }
58
95
  get src() {
59
96
  return this.currentSrc;
60
97
  }
@@ -122,9 +159,17 @@ class WebAudioPlayer extends EventEmitter {
122
159
  };
123
160
  }
124
161
  _pause() {
125
- var _a;
126
162
  this.paused = true;
127
- (_a = this.bufferNode) === null || _a === void 0 ? void 0 : _a.stop();
163
+ // Clear onended before stopping to prevent spurious 'ended' event
164
+ if (this.bufferNode) {
165
+ this.bufferNode.onended = null;
166
+ try {
167
+ this.bufferNode.stop();
168
+ }
169
+ catch (_a) {
170
+ // Ignore InvalidStateError if node already stopped
171
+ }
172
+ }
128
173
  this.playbackPosition += (this.audioContext.currentTime - this.playStartTime) * this._playbackRate;
129
174
  }
130
175
  play() {
@@ -142,13 +187,19 @@ class WebAudioPlayer extends EventEmitter {
142
187
  this.emit('pause');
143
188
  }
144
189
  stopAt(timeSeconds) {
145
- const delay = timeSeconds - this.currentTime;
190
+ // The stop is scheduled on the AudioContext clock, so convert the remaining
191
+ // media time to real time via the playback rate
192
+ const delay = (timeSeconds - this.currentTime) / this._playbackRate;
146
193
  const currentBufferNode = this.bufferNode;
147
194
  currentBufferNode === null || currentBufferNode === void 0 ? void 0 : currentBufferNode.stop(this.audioContext.currentTime + delay);
148
195
  currentBufferNode === null || currentBufferNode === void 0 ? void 0 : currentBufferNode.addEventListener('ended', () => {
149
196
  if (currentBufferNode === this.bufferNode) {
150
197
  this.bufferNode = null;
151
198
  this.pause();
199
+ // The 'ended' event fires with some latency, so clamp the reported
200
+ // position to the exact stop time
201
+ this.playbackPosition = Math.min(timeSeconds, this.duration);
202
+ this.emit('timeupdate');
152
203
  }
153
204
  }, { once: true });
154
205
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wavesurfer.js",
3
- "version": "7.12.7",
3
+ "version": "7.12.9",
4
4
  "license": "BSD-3-Clause",
5
5
  "author": "katspaugh",
6
6
  "description": "Audio waveform player",
@@ -64,32 +64,33 @@
64
64
  "make-plugin": "./scripts/plugin.sh",
65
65
  "cypress": "cypress open --e2e",
66
66
  "cypress:canary": "cypress open --e2e -b chrome:canary",
67
- "test": "cypress run --browser chrome",
67
+ "test": "cypress run --browser ${CYPRESS_BROWSER:-chromium}",
68
68
  "test:unit": "jest --coverage",
69
69
  "serve": "npx live-server --port=9090 --no-browser --ignore='.*,src,cypress,scripts'",
70
70
  "start": "npm run build:dev & npm run serve",
71
+ "dev": "npm run start",
71
72
  "prepare": "npm run build"
72
73
  },
73
74
  "packageManager": "yarn@1.22.22",
74
75
  "devDependencies": {
75
76
  "@rollup/plugin-terser": "^0.4.4",
76
- "@rollup/plugin-typescript": "^12.1.1",
77
+ "@rollup/plugin-typescript": "^12.3.0",
77
78
  "@types/jest": "^29.5.2",
78
- "@typescript-eslint/eslint-plugin": "^8.43.0",
79
- "@typescript-eslint/parser": "^8.43.0",
80
- "cypress": "^13.16.1",
79
+ "@typescript-eslint/eslint-plugin": "^8.60.1",
80
+ "@typescript-eslint/parser": "^8.60.1",
81
+ "cypress": "^13.17.0",
81
82
  "cypress-image-snapshot": "^4.0.1",
82
- "eslint": "^9.35.0",
83
+ "eslint": "^9.39.4",
83
84
  "eslint-config-prettier": "^9.1.0",
84
- "eslint-plugin-prettier": "^5.2.1",
85
- "glob": "^11.0.0",
85
+ "eslint-plugin-prettier": "^5.5.6",
86
+ "glob": "^11.1.0",
86
87
  "jest": "^29.7.0",
87
88
  "jest-environment-jsdom": "^29.7.0",
88
- "prettier": "^3.4.2",
89
- "rollup": "^4.50.1",
90
- "rollup-plugin-dts": "^6.1.0",
89
+ "prettier": "^3.8.3",
90
+ "rollup": "^4.61.1",
91
+ "rollup-plugin-dts": "^6.4.1",
91
92
  "rollup-plugin-web-worker-loader": "^1.7.0",
92
- "ts-jest": "^29.1.1",
93
- "typescript": "^5.9.2"
93
+ "ts-jest": "^29.4.11",
94
+ "typescript": "^5.9.3"
94
95
  }
95
96
  }