@react-text-game/core 0.4.1 → 0.5.0
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/README.md +389 -0
- package/dist/audio/audioTrack.d.ts +407 -0
- package/dist/audio/audioTrack.d.ts.map +1 -0
- package/dist/audio/audioTrack.js +656 -0
- package/dist/audio/audioTrack.js.map +1 -0
- package/dist/audio/constants.d.ts +19 -0
- package/dist/audio/constants.d.ts.map +1 -0
- package/dist/audio/constants.js +20 -0
- package/dist/audio/constants.js.map +1 -0
- package/dist/audio/fabric.d.ts +35 -0
- package/dist/audio/fabric.d.ts.map +1 -0
- package/dist/audio/fabric.js +36 -0
- package/dist/audio/fabric.js.map +1 -0
- package/dist/audio/index.d.ts +33 -0
- package/dist/audio/index.d.ts.map +1 -0
- package/dist/audio/index.js +32 -0
- package/dist/audio/index.js.map +1 -0
- package/dist/audio/types.d.ts +105 -0
- package/dist/audio/types.d.ts.map +1 -0
- package/dist/audio/types.js +2 -0
- package/dist/audio/types.js.map +1 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +2 -0
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/useAudio.d.ts +50 -0
- package/dist/hooks/useAudio.d.ts.map +1 -0
- package/dist/hooks/useAudio.js +42 -0
- package/dist/hooks/useAudio.js.map +1 -0
- package/dist/hooks/useAudioManager.d.ts +66 -0
- package/dist/hooks/useAudioManager.d.ts.map +1 -0
- package/dist/hooks/useAudioManager.js +70 -0
- package/dist/hooks/useAudioManager.js.map +1 -0
- package/dist/tests/audio.test.d.ts +2 -0
- package/dist/tests/audio.test.d.ts.map +1 -0
- package/dist/tests/audio.test.js +605 -0
- package/dist/tests/audio.test.js.map +1 -0
- package/package.json +5 -1
|
@@ -0,0 +1,605 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
2
|
+
import { AudioManager, AudioTrack, createAudio } from "../audio";
|
|
3
|
+
import { Storage } from "../storage";
|
|
4
|
+
// Mock HTMLAudioElement for testing
|
|
5
|
+
class MockAudioElement {
|
|
6
|
+
src = "";
|
|
7
|
+
volume = 1;
|
|
8
|
+
loop = false;
|
|
9
|
+
playbackRate = 1;
|
|
10
|
+
muted = false;
|
|
11
|
+
preload = "metadata";
|
|
12
|
+
currentTime = 0;
|
|
13
|
+
duration = 0;
|
|
14
|
+
paused = true;
|
|
15
|
+
listeners = new Map();
|
|
16
|
+
constructor(src) {
|
|
17
|
+
if (src) {
|
|
18
|
+
this.src = src;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
addEventListener(event, listener) {
|
|
22
|
+
if (!this.listeners.has(event)) {
|
|
23
|
+
this.listeners.set(event, []);
|
|
24
|
+
}
|
|
25
|
+
this.listeners.get(event)?.push(listener);
|
|
26
|
+
}
|
|
27
|
+
removeEventListener(event, listener) {
|
|
28
|
+
const listeners = this.listeners.get(event);
|
|
29
|
+
if (listeners) {
|
|
30
|
+
const index = listeners.indexOf(listener);
|
|
31
|
+
if (index > -1) {
|
|
32
|
+
listeners.splice(index, 1);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
dispatchEvent(event) {
|
|
37
|
+
const listeners = this.listeners.get(event.type);
|
|
38
|
+
if (listeners) {
|
|
39
|
+
listeners.forEach((listener) => listener(event));
|
|
40
|
+
}
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
async play() {
|
|
44
|
+
this.paused = false;
|
|
45
|
+
this.dispatchEvent(new Event("play"));
|
|
46
|
+
return Promise.resolve();
|
|
47
|
+
}
|
|
48
|
+
pause() {
|
|
49
|
+
this.paused = true;
|
|
50
|
+
this.dispatchEvent(new Event("pause"));
|
|
51
|
+
}
|
|
52
|
+
cloneNode() {
|
|
53
|
+
return new MockAudioElement(this.src);
|
|
54
|
+
}
|
|
55
|
+
// Helper methods for testing
|
|
56
|
+
_triggerLoadedMetadata() {
|
|
57
|
+
this.duration = 180; // 3 minutes
|
|
58
|
+
this.dispatchEvent(new Event("loadedmetadata"));
|
|
59
|
+
}
|
|
60
|
+
_triggerTimeUpdate(time) {
|
|
61
|
+
this.currentTime = time;
|
|
62
|
+
this.dispatchEvent(new Event("timeupdate"));
|
|
63
|
+
}
|
|
64
|
+
_triggerEnded() {
|
|
65
|
+
this.dispatchEvent(new Event("ended"));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// Replace global Audio with mock
|
|
69
|
+
global.Audio =
|
|
70
|
+
MockAudioElement;
|
|
71
|
+
// Mock requestAnimationFrame for fade tests
|
|
72
|
+
global.requestAnimationFrame = (callback) => {
|
|
73
|
+
return setTimeout(() => callback(Date.now()), 0);
|
|
74
|
+
};
|
|
75
|
+
describe("Audio System", () => {
|
|
76
|
+
beforeEach(() => {
|
|
77
|
+
// Clear storage before each test
|
|
78
|
+
Storage.setState({});
|
|
79
|
+
// Clear audio manager tracks
|
|
80
|
+
AudioManager.disposeAll();
|
|
81
|
+
});
|
|
82
|
+
afterEach(() => {
|
|
83
|
+
// Clean up after tests
|
|
84
|
+
AudioManager.disposeAll();
|
|
85
|
+
Storage.setState({});
|
|
86
|
+
});
|
|
87
|
+
describe("createAudio factory", () => {
|
|
88
|
+
test("creates an AudioTrack instance", () => {
|
|
89
|
+
const audio = createAudio("test.mp3");
|
|
90
|
+
expect(audio).toBeInstanceOf(AudioTrack);
|
|
91
|
+
});
|
|
92
|
+
test("creates audio with default options", () => {
|
|
93
|
+
const audio = createAudio("test.mp3");
|
|
94
|
+
const state = audio.getState();
|
|
95
|
+
expect(state.volume).toBe(1.0);
|
|
96
|
+
expect(state.loop).toBe(false);
|
|
97
|
+
expect(state.playbackRate).toBe(1.0);
|
|
98
|
+
expect(state.muted).toBe(false);
|
|
99
|
+
expect(state.isStopped).toBe(true);
|
|
100
|
+
expect(state.isPlaying).toBe(false);
|
|
101
|
+
expect(state.isPaused).toBe(false);
|
|
102
|
+
});
|
|
103
|
+
test("creates audio with custom options", () => {
|
|
104
|
+
const audio = createAudio("test.mp3", {
|
|
105
|
+
id: "test-audio",
|
|
106
|
+
volume: 0.5,
|
|
107
|
+
loop: true,
|
|
108
|
+
playbackRate: 1.5,
|
|
109
|
+
muted: true,
|
|
110
|
+
});
|
|
111
|
+
const state = audio.getState();
|
|
112
|
+
expect(state.volume).toBe(0.5);
|
|
113
|
+
expect(state.loop).toBe(true);
|
|
114
|
+
expect(state.playbackRate).toBe(1.5);
|
|
115
|
+
expect(state.muted).toBe(true);
|
|
116
|
+
});
|
|
117
|
+
test("generates unique ID if not provided", () => {
|
|
118
|
+
const audio1 = createAudio("test1.mp3");
|
|
119
|
+
const audio2 = createAudio("test2.mp3");
|
|
120
|
+
expect(audio1.id).toBeDefined();
|
|
121
|
+
expect(audio2.id).toBeDefined();
|
|
122
|
+
expect(audio1.id).not.toBe(audio2.id);
|
|
123
|
+
});
|
|
124
|
+
test("uses provided ID", () => {
|
|
125
|
+
const audio = createAudio("test.mp3", { id: "my-audio" });
|
|
126
|
+
expect(audio.id).toBe("my-audio");
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
describe("AudioTrack state management", () => {
|
|
130
|
+
test("initializes with correct state", () => {
|
|
131
|
+
const audio = createAudio("test.mp3", {
|
|
132
|
+
volume: 0.7,
|
|
133
|
+
loop: true,
|
|
134
|
+
});
|
|
135
|
+
const state = audio.getState();
|
|
136
|
+
expect(state.volume).toBe(0.7);
|
|
137
|
+
expect(state.loop).toBe(true);
|
|
138
|
+
expect(state.isPlaying).toBe(false);
|
|
139
|
+
expect(state.isPaused).toBe(false);
|
|
140
|
+
expect(state.isStopped).toBe(true);
|
|
141
|
+
expect(state.currentTime).toBe(0);
|
|
142
|
+
expect(state.duration).toBe(0);
|
|
143
|
+
});
|
|
144
|
+
test("updates state when playing", async () => {
|
|
145
|
+
const audio = createAudio("test.mp3");
|
|
146
|
+
await audio.play();
|
|
147
|
+
const state = audio.getState();
|
|
148
|
+
expect(state.isPlaying).toBe(true);
|
|
149
|
+
expect(state.isPaused).toBe(false);
|
|
150
|
+
expect(state.isStopped).toBe(false);
|
|
151
|
+
});
|
|
152
|
+
test("updates state when paused", async () => {
|
|
153
|
+
const audio = createAudio("test.mp3");
|
|
154
|
+
await audio.play();
|
|
155
|
+
audio.pause();
|
|
156
|
+
const state = audio.getState();
|
|
157
|
+
expect(state.isPlaying).toBe(false);
|
|
158
|
+
expect(state.isPaused).toBe(true);
|
|
159
|
+
expect(state.isStopped).toBe(false);
|
|
160
|
+
});
|
|
161
|
+
test("updates state when stopped", async () => {
|
|
162
|
+
const audio = createAudio("test.mp3");
|
|
163
|
+
await audio.play();
|
|
164
|
+
audio.stop();
|
|
165
|
+
const state = audio.getState();
|
|
166
|
+
expect(state.isPlaying).toBe(false);
|
|
167
|
+
expect(state.isPaused).toBe(false);
|
|
168
|
+
expect(state.isStopped).toBe(true);
|
|
169
|
+
});
|
|
170
|
+
test("resumes from paused state", async () => {
|
|
171
|
+
const audio = createAudio("test.mp3");
|
|
172
|
+
await audio.play();
|
|
173
|
+
audio.pause();
|
|
174
|
+
const pausedState = audio.getState();
|
|
175
|
+
expect(pausedState.isPaused).toBe(true);
|
|
176
|
+
audio.resume();
|
|
177
|
+
// Note: resume is async internally but doesn't return promise
|
|
178
|
+
// Give it a moment to process
|
|
179
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
180
|
+
const resumedState = audio.getState();
|
|
181
|
+
expect(resumedState.isPlaying).toBe(true);
|
|
182
|
+
expect(resumedState.isPaused).toBe(false);
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
describe("AudioTrack controls", () => {
|
|
186
|
+
test("sets volume within valid range", () => {
|
|
187
|
+
const audio = createAudio("test.mp3");
|
|
188
|
+
audio.setVolume(0.5);
|
|
189
|
+
expect(audio.getState().volume).toBe(0.5);
|
|
190
|
+
audio.setVolume(0);
|
|
191
|
+
expect(audio.getState().volume).toBe(0);
|
|
192
|
+
audio.setVolume(1);
|
|
193
|
+
expect(audio.getState().volume).toBe(1);
|
|
194
|
+
});
|
|
195
|
+
test("clamps volume to valid range", () => {
|
|
196
|
+
const audio = createAudio("test.mp3");
|
|
197
|
+
audio.setVolume(-0.5);
|
|
198
|
+
expect(audio.getState().volume).toBe(0);
|
|
199
|
+
audio.setVolume(1.5);
|
|
200
|
+
expect(audio.getState().volume).toBe(1);
|
|
201
|
+
});
|
|
202
|
+
test("toggles loop", () => {
|
|
203
|
+
const audio = createAudio("test.mp3");
|
|
204
|
+
audio.setLoop(true);
|
|
205
|
+
expect(audio.getState().loop).toBe(true);
|
|
206
|
+
audio.setLoop(false);
|
|
207
|
+
expect(audio.getState().loop).toBe(false);
|
|
208
|
+
});
|
|
209
|
+
test("sets playback rate", () => {
|
|
210
|
+
const audio = createAudio("test.mp3");
|
|
211
|
+
audio.setPlaybackRate(1.5);
|
|
212
|
+
expect(audio.getState().playbackRate).toBe(1.5);
|
|
213
|
+
audio.setPlaybackRate(0.5);
|
|
214
|
+
expect(audio.getState().playbackRate).toBe(0.5);
|
|
215
|
+
});
|
|
216
|
+
test("toggles muted", () => {
|
|
217
|
+
const audio = createAudio("test.mp3");
|
|
218
|
+
audio.setMuted(true);
|
|
219
|
+
expect(audio.getState().muted).toBe(true);
|
|
220
|
+
audio.setMuted(false);
|
|
221
|
+
expect(audio.getState().muted).toBe(false);
|
|
222
|
+
});
|
|
223
|
+
test("seeks to specific time", () => {
|
|
224
|
+
const audio = createAudio("test.mp3");
|
|
225
|
+
// Simulate loaded metadata
|
|
226
|
+
const audioEl = audio
|
|
227
|
+
.audioElement;
|
|
228
|
+
audioEl._triggerLoadedMetadata();
|
|
229
|
+
audio.seek(30);
|
|
230
|
+
expect(audioEl.currentTime).toBe(30);
|
|
231
|
+
});
|
|
232
|
+
test("clamps seek time to valid range", () => {
|
|
233
|
+
const audio = createAudio("test.mp3");
|
|
234
|
+
// Simulate loaded metadata (duration = 180s)
|
|
235
|
+
const audioEl = audio
|
|
236
|
+
.audioElement;
|
|
237
|
+
audioEl._triggerLoadedMetadata();
|
|
238
|
+
audio.seek(-10);
|
|
239
|
+
expect(audioEl.currentTime).toBe(0);
|
|
240
|
+
audio.seek(200);
|
|
241
|
+
expect(audioEl.currentTime).toBe(180);
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
describe("AudioTrack save/load", () => {
|
|
245
|
+
test("saves audio state to storage with ID", () => {
|
|
246
|
+
const audio = createAudio("test.mp3", {
|
|
247
|
+
id: "test-audio",
|
|
248
|
+
volume: 0.7,
|
|
249
|
+
loop: true,
|
|
250
|
+
});
|
|
251
|
+
audio.save();
|
|
252
|
+
const savedState = Storage.getValue("$._system.audio.test-audio");
|
|
253
|
+
expect(savedState.length).toBe(1);
|
|
254
|
+
expect(savedState[0]).toMatchObject({
|
|
255
|
+
id: "test-audio",
|
|
256
|
+
src: "test.mp3",
|
|
257
|
+
volume: 0.7,
|
|
258
|
+
loop: true,
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
test("loads audio state from storage", () => {
|
|
262
|
+
// First create and save audio
|
|
263
|
+
const audio1 = createAudio("test.mp3", {
|
|
264
|
+
id: "test-audio",
|
|
265
|
+
volume: 0.7,
|
|
266
|
+
loop: true,
|
|
267
|
+
});
|
|
268
|
+
// Manually set some values and save
|
|
269
|
+
audio1.setPlaybackRate(1.5);
|
|
270
|
+
audio1.save();
|
|
271
|
+
// Clear the saved state that gets overwritten by constructor
|
|
272
|
+
const savedState = Storage.getValue("$._system.audio.test-audio");
|
|
273
|
+
// Dispose audio1 to clean up
|
|
274
|
+
audio1.dispose();
|
|
275
|
+
// Restore the saved state
|
|
276
|
+
Storage.setValue("$._system.audio.test-audio", savedState[0], true);
|
|
277
|
+
// Create new audio with same ID and different settings
|
|
278
|
+
const audio2 = createAudio("test.mp3", {
|
|
279
|
+
id: "test-audio",
|
|
280
|
+
volume: 0.3,
|
|
281
|
+
loop: false,
|
|
282
|
+
});
|
|
283
|
+
// Load should restore the saved state
|
|
284
|
+
audio2.load();
|
|
285
|
+
const state = audio2.getState();
|
|
286
|
+
expect(state.volume).toBe(0.7);
|
|
287
|
+
expect(state.loop).toBe(true);
|
|
288
|
+
expect(state.playbackRate).toBe(1.5);
|
|
289
|
+
});
|
|
290
|
+
test("handles loading with no saved state gracefully", () => {
|
|
291
|
+
const audio = createAudio("test.mp3", { id: "new-audio" });
|
|
292
|
+
// Should not throw
|
|
293
|
+
expect(() => audio.load()).not.toThrow();
|
|
294
|
+
});
|
|
295
|
+
});
|
|
296
|
+
describe("AudioManager", () => {
|
|
297
|
+
test("registers tracks automatically", () => {
|
|
298
|
+
const audio1 = createAudio("test1.mp3", { id: "audio1" });
|
|
299
|
+
const audio2 = createAudio("test2.mp3", { id: "audio2" });
|
|
300
|
+
const tracks = AudioManager.getAllTracks();
|
|
301
|
+
expect(tracks.length).toBe(2);
|
|
302
|
+
expect(tracks).toContain(audio1);
|
|
303
|
+
expect(tracks).toContain(audio2);
|
|
304
|
+
});
|
|
305
|
+
test("retrieves track by ID", () => {
|
|
306
|
+
const audio = createAudio("test.mp3", { id: "my-audio" });
|
|
307
|
+
const retrieved = AudioManager.getTrackById("my-audio");
|
|
308
|
+
expect(retrieved).toBe(audio);
|
|
309
|
+
});
|
|
310
|
+
test("returns undefined for non-existent track ID", () => {
|
|
311
|
+
const retrieved = AudioManager.getTrackById("non-existent");
|
|
312
|
+
expect(retrieved).toBeUndefined();
|
|
313
|
+
});
|
|
314
|
+
test("sets master volume", () => {
|
|
315
|
+
AudioManager.setMasterVolume(0.5);
|
|
316
|
+
expect(AudioManager.getMasterVolume()).toBe(0.5);
|
|
317
|
+
});
|
|
318
|
+
test("clamps master volume to valid range", () => {
|
|
319
|
+
AudioManager.setMasterVolume(-0.5);
|
|
320
|
+
expect(AudioManager.getMasterVolume()).toBe(0);
|
|
321
|
+
AudioManager.setMasterVolume(1.5);
|
|
322
|
+
expect(AudioManager.getMasterVolume()).toBe(1);
|
|
323
|
+
});
|
|
324
|
+
test("master volume does not permanently modify track volumes", () => {
|
|
325
|
+
const audio = createAudio("test.mp3", { id: "test", volume: 0.8 });
|
|
326
|
+
// Access the audio element to verify effective volume
|
|
327
|
+
const audioEl = audio
|
|
328
|
+
.audioElement;
|
|
329
|
+
// Initial state: track volume 0.8, master volume 1.0
|
|
330
|
+
expect(audio.getState().volume).toBe(0.8);
|
|
331
|
+
expect(audioEl.volume).toBe(0.8);
|
|
332
|
+
// Set master volume to 0.5
|
|
333
|
+
AudioManager.setMasterVolume(0.5);
|
|
334
|
+
// Track's state volume should remain 0.8
|
|
335
|
+
expect(audio.getState().volume).toBe(0.8);
|
|
336
|
+
// But effective volume on audio element should be 0.8 * 0.5 = 0.4
|
|
337
|
+
expect(audioEl.volume).toBe(0.4);
|
|
338
|
+
// Set master volume back to 1.0
|
|
339
|
+
AudioManager.setMasterVolume(1.0);
|
|
340
|
+
// Track's state volume should still be 0.8
|
|
341
|
+
expect(audio.getState().volume).toBe(0.8);
|
|
342
|
+
// Effective volume should be back to 0.8
|
|
343
|
+
expect(audioEl.volume).toBe(0.8);
|
|
344
|
+
});
|
|
345
|
+
test("master volume applies to all tracks independently", () => {
|
|
346
|
+
const audio1 = createAudio("test1.mp3", { id: "test1", volume: 0.6 });
|
|
347
|
+
const audio2 = createAudio("test2.mp3", { id: "test2", volume: 0.9 });
|
|
348
|
+
const audio3 = createAudio("test3.mp3", { id: "test3", volume: 0.3 });
|
|
349
|
+
const audioEl1 = audio1
|
|
350
|
+
.audioElement;
|
|
351
|
+
const audioEl2 = audio2
|
|
352
|
+
.audioElement;
|
|
353
|
+
const audioEl3 = audio3
|
|
354
|
+
.audioElement;
|
|
355
|
+
// Set master volume to 0.5
|
|
356
|
+
AudioManager.setMasterVolume(0.5);
|
|
357
|
+
// All tracks should preserve their state volumes
|
|
358
|
+
expect(audio1.getState().volume).toBe(0.6);
|
|
359
|
+
expect(audio2.getState().volume).toBe(0.9);
|
|
360
|
+
expect(audio3.getState().volume).toBe(0.3);
|
|
361
|
+
// But effective volumes should be multiplied by master
|
|
362
|
+
expect(audioEl1.volume).toBe(0.3); // 0.6 * 0.5
|
|
363
|
+
expect(audioEl2.volume).toBe(0.45); // 0.9 * 0.5
|
|
364
|
+
expect(audioEl3.volume).toBe(0.15); // 0.3 * 0.5
|
|
365
|
+
});
|
|
366
|
+
test("changing track volume updates effective volume with current master volume", () => {
|
|
367
|
+
const audio = createAudio("test.mp3", { id: "test", volume: 0.5 });
|
|
368
|
+
const audioEl = audio
|
|
369
|
+
.audioElement;
|
|
370
|
+
// Set master volume to 0.5
|
|
371
|
+
AudioManager.setMasterVolume(0.5);
|
|
372
|
+
// Initial effective volume: 0.5 * 0.5 = 0.25
|
|
373
|
+
expect(audioEl.volume).toBe(0.25);
|
|
374
|
+
// Change track volume
|
|
375
|
+
audio.setVolume(0.8);
|
|
376
|
+
// State volume should be 0.8
|
|
377
|
+
expect(audio.getState().volume).toBe(0.8);
|
|
378
|
+
// Effective volume should be 0.8 * 0.5 = 0.4
|
|
379
|
+
expect(audioEl.volume).toBe(0.4);
|
|
380
|
+
});
|
|
381
|
+
test("master volume correctly applies when set to 0", () => {
|
|
382
|
+
const audio1 = createAudio("test1.mp3", { volume: 0.7 });
|
|
383
|
+
const audio2 = createAudio("test2.mp3", { volume: 0.5 });
|
|
384
|
+
const audioEl1 = audio1
|
|
385
|
+
.audioElement;
|
|
386
|
+
const audioEl2 = audio2
|
|
387
|
+
.audioElement;
|
|
388
|
+
// Set master volume to 0 (silence all)
|
|
389
|
+
AudioManager.setMasterVolume(0);
|
|
390
|
+
// Track volumes should be preserved
|
|
391
|
+
expect(audio1.getState().volume).toBe(0.7);
|
|
392
|
+
expect(audio2.getState().volume).toBe(0.5);
|
|
393
|
+
// But effective volumes should be 0
|
|
394
|
+
expect(audioEl1.volume).toBe(0);
|
|
395
|
+
expect(audioEl2.volume).toBe(0);
|
|
396
|
+
// Restore master volume
|
|
397
|
+
AudioManager.setMasterVolume(1.0);
|
|
398
|
+
// Effective volumes should be restored
|
|
399
|
+
expect(audioEl1.volume).toBe(0.7);
|
|
400
|
+
expect(audioEl2.volume).toBe(0.5);
|
|
401
|
+
});
|
|
402
|
+
test("master volume persists for newly created tracks", () => {
|
|
403
|
+
// Set master volume before creating tracks
|
|
404
|
+
AudioManager.setMasterVolume(0.5);
|
|
405
|
+
const audio = createAudio("test.mp3", { volume: 0.8 });
|
|
406
|
+
const audioEl = audio
|
|
407
|
+
.audioElement;
|
|
408
|
+
// New track should have master volume applied
|
|
409
|
+
expect(audio.getState().volume).toBe(0.8);
|
|
410
|
+
expect(audioEl.volume).toBe(0.4); // 0.8 * 0.5
|
|
411
|
+
// Reset master volume for other tests
|
|
412
|
+
AudioManager.setMasterVolume(1.0);
|
|
413
|
+
});
|
|
414
|
+
test("mutes all tracks", () => {
|
|
415
|
+
const audio1 = createAudio("test1.mp3");
|
|
416
|
+
const audio2 = createAudio("test2.mp3");
|
|
417
|
+
AudioManager.muteAll();
|
|
418
|
+
expect(audio1.getState().muted).toBe(true);
|
|
419
|
+
expect(audio2.getState().muted).toBe(true);
|
|
420
|
+
});
|
|
421
|
+
test("unmutes all tracks", () => {
|
|
422
|
+
const audio1 = createAudio("test1.mp3");
|
|
423
|
+
const audio2 = createAudio("test2.mp3");
|
|
424
|
+
AudioManager.muteAll();
|
|
425
|
+
AudioManager.unmuteAll();
|
|
426
|
+
expect(audio1.getState().muted).toBe(false);
|
|
427
|
+
expect(audio2.getState().muted).toBe(false);
|
|
428
|
+
});
|
|
429
|
+
test("pauses all playing tracks", async () => {
|
|
430
|
+
const audio1 = createAudio("test1.mp3");
|
|
431
|
+
const audio2 = createAudio("test2.mp3");
|
|
432
|
+
await audio1.play();
|
|
433
|
+
await audio2.play();
|
|
434
|
+
AudioManager.pauseAll();
|
|
435
|
+
expect(audio1.getState().isPaused).toBe(true);
|
|
436
|
+
expect(audio2.getState().isPaused).toBe(true);
|
|
437
|
+
});
|
|
438
|
+
test("resumes all paused tracks", async () => {
|
|
439
|
+
const audio1 = createAudio("test1.mp3");
|
|
440
|
+
const audio2 = createAudio("test2.mp3");
|
|
441
|
+
await audio1.play();
|
|
442
|
+
await audio2.play();
|
|
443
|
+
AudioManager.pauseAll();
|
|
444
|
+
AudioManager.resumeAll();
|
|
445
|
+
// Give resume time to process
|
|
446
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
447
|
+
expect(audio1.getState().isPlaying).toBe(true);
|
|
448
|
+
expect(audio2.getState().isPlaying).toBe(true);
|
|
449
|
+
});
|
|
450
|
+
test("stops all tracks", async () => {
|
|
451
|
+
const audio1 = createAudio("test1.mp3");
|
|
452
|
+
const audio2 = createAudio("test2.mp3");
|
|
453
|
+
await audio1.play();
|
|
454
|
+
await audio2.play();
|
|
455
|
+
AudioManager.stopAll();
|
|
456
|
+
expect(audio1.getState().isStopped).toBe(true);
|
|
457
|
+
expect(audio2.getState().isStopped).toBe(true);
|
|
458
|
+
});
|
|
459
|
+
test("disposes all tracks", () => {
|
|
460
|
+
createAudio("test1.mp3", { id: "audio1" });
|
|
461
|
+
createAudio("test2.mp3", { id: "audio2" });
|
|
462
|
+
expect(AudioManager.getAllTracks().length).toBe(2);
|
|
463
|
+
AudioManager.disposeAll();
|
|
464
|
+
expect(AudioManager.getAllTracks().length).toBe(0);
|
|
465
|
+
});
|
|
466
|
+
test("unregisters track on dispose", () => {
|
|
467
|
+
const audio = createAudio("test.mp3", { id: "test-audio" });
|
|
468
|
+
expect(AudioManager.getAllTracks().length).toBe(1);
|
|
469
|
+
audio.dispose();
|
|
470
|
+
expect(AudioManager.getAllTracks().length).toBe(0);
|
|
471
|
+
expect(AudioManager.getTrackById("test-audio")).toBeUndefined();
|
|
472
|
+
});
|
|
473
|
+
});
|
|
474
|
+
describe("AudioTrack fade effects", () => {
|
|
475
|
+
test("fadeIn starts from 0 volume", async () => {
|
|
476
|
+
const audio = createAudio("test.mp3", { volume: 0.5 });
|
|
477
|
+
// Start fade in (with short duration for test)
|
|
478
|
+
const fadePromise = audio.fadeIn(10);
|
|
479
|
+
// Volume should start at 0
|
|
480
|
+
const initialState = audio.getState();
|
|
481
|
+
expect(initialState.volume).toBeLessThanOrEqual(0.1);
|
|
482
|
+
await fadePromise;
|
|
483
|
+
// After fade, should be at target volume (0.5)
|
|
484
|
+
const finalState = audio.getState();
|
|
485
|
+
expect(finalState.volume).toBeGreaterThanOrEqual(0.4);
|
|
486
|
+
});
|
|
487
|
+
test("fadeOut ends at 0 volume and stops", async () => {
|
|
488
|
+
const audio = createAudio("test.mp3", { volume: 0.5 });
|
|
489
|
+
await audio.play();
|
|
490
|
+
await audio.fadeOut(10);
|
|
491
|
+
const state = audio.getState();
|
|
492
|
+
expect(state.volume).toBeLessThanOrEqual(0.1);
|
|
493
|
+
expect(state.isStopped).toBe(true);
|
|
494
|
+
});
|
|
495
|
+
});
|
|
496
|
+
describe("Integration tests", () => {
|
|
497
|
+
test("multiple audio tracks work independently", async () => {
|
|
498
|
+
const music = createAudio("music.mp3", {
|
|
499
|
+
id: "music",
|
|
500
|
+
volume: 0.7,
|
|
501
|
+
loop: true,
|
|
502
|
+
});
|
|
503
|
+
const sfx = createAudio("sfx.mp3", {
|
|
504
|
+
id: "sfx",
|
|
505
|
+
volume: 0.9,
|
|
506
|
+
loop: false,
|
|
507
|
+
});
|
|
508
|
+
await music.play();
|
|
509
|
+
await sfx.play();
|
|
510
|
+
expect(music.getState().isPlaying).toBe(true);
|
|
511
|
+
expect(sfx.getState().isPlaying).toBe(true);
|
|
512
|
+
music.pause();
|
|
513
|
+
expect(music.getState().isPaused).toBe(true);
|
|
514
|
+
expect(sfx.getState().isPlaying).toBe(true);
|
|
515
|
+
});
|
|
516
|
+
test("audio state persists across save/load cycle", () => {
|
|
517
|
+
// Create and configure audio
|
|
518
|
+
const audio1 = createAudio("test.mp3", {
|
|
519
|
+
id: "persistent-audio",
|
|
520
|
+
volume: 0.6,
|
|
521
|
+
loop: true,
|
|
522
|
+
});
|
|
523
|
+
audio1.setPlaybackRate(1.5);
|
|
524
|
+
audio1.save();
|
|
525
|
+
// Save the state before disposing
|
|
526
|
+
const savedState = Storage.getValue("$._system.audio.persistent-audio");
|
|
527
|
+
audio1.dispose();
|
|
528
|
+
// Restore the saved state (in case dispose cleared it)
|
|
529
|
+
Storage.setValue("$._system.audio.persistent-audio", savedState[0], true);
|
|
530
|
+
// Simulate restart by creating new instance
|
|
531
|
+
const audio2 = createAudio("test.mp3", {
|
|
532
|
+
id: "persistent-audio",
|
|
533
|
+
});
|
|
534
|
+
audio2.load();
|
|
535
|
+
const state = audio2.getState();
|
|
536
|
+
expect(state.volume).toBe(0.6);
|
|
537
|
+
expect(state.loop).toBe(true);
|
|
538
|
+
expect(state.playbackRate).toBe(1.5);
|
|
539
|
+
});
|
|
540
|
+
test("AudioManager operations affect all registered tracks", async () => {
|
|
541
|
+
const audio1 = createAudio("test1.mp3");
|
|
542
|
+
const audio2 = createAudio("test2.mp3");
|
|
543
|
+
const audio3 = createAudio("test3.mp3");
|
|
544
|
+
await audio1.play();
|
|
545
|
+
await audio2.play();
|
|
546
|
+
await audio3.play();
|
|
547
|
+
// Mute all
|
|
548
|
+
AudioManager.muteAll();
|
|
549
|
+
expect(audio1.getState().muted).toBe(true);
|
|
550
|
+
expect(audio2.getState().muted).toBe(true);
|
|
551
|
+
expect(audio3.getState().muted).toBe(true);
|
|
552
|
+
// Stop all
|
|
553
|
+
AudioManager.stopAll();
|
|
554
|
+
expect(audio1.getState().isStopped).toBe(true);
|
|
555
|
+
expect(audio2.getState().isStopped).toBe(true);
|
|
556
|
+
expect(audio3.getState().isStopped).toBe(true);
|
|
557
|
+
});
|
|
558
|
+
});
|
|
559
|
+
describe("Edge cases", () => {
|
|
560
|
+
test("handles empty string src", () => {
|
|
561
|
+
expect(() => createAudio("")).not.toThrow();
|
|
562
|
+
});
|
|
563
|
+
test("handles special characters in src", () => {
|
|
564
|
+
expect(() => createAudio("audio/music with spaces.mp3")).not.toThrow();
|
|
565
|
+
});
|
|
566
|
+
test("handles special characters in ID", () => {
|
|
567
|
+
expect(() => createAudio("test.mp3", { id: "audio-id_123" })).not.toThrow();
|
|
568
|
+
});
|
|
569
|
+
test("handles rapid state changes", async () => {
|
|
570
|
+
const audio = createAudio("test.mp3");
|
|
571
|
+
await audio.play();
|
|
572
|
+
audio.pause();
|
|
573
|
+
await audio.play();
|
|
574
|
+
audio.stop();
|
|
575
|
+
await audio.play();
|
|
576
|
+
// Should end up playing
|
|
577
|
+
expect(audio.getState().isPlaying).toBe(true);
|
|
578
|
+
});
|
|
579
|
+
test("dispose stops audio and cleans up", async () => {
|
|
580
|
+
const audio = createAudio("test.mp3", { id: "disposable" });
|
|
581
|
+
await audio.play();
|
|
582
|
+
audio.dispose();
|
|
583
|
+
const state = audio.getState();
|
|
584
|
+
expect(state.isStopped).toBe(true);
|
|
585
|
+
expect(AudioManager.getTrackById("disposable")).toBeUndefined();
|
|
586
|
+
});
|
|
587
|
+
test("handles volume changes during playback", async () => {
|
|
588
|
+
const audio = createAudio("test.mp3", { volume: 0.5 });
|
|
589
|
+
await audio.play();
|
|
590
|
+
audio.setVolume(0.8);
|
|
591
|
+
expect(audio.getState().volume).toBe(0.8);
|
|
592
|
+
audio.setVolume(0.2);
|
|
593
|
+
expect(audio.getState().volume).toBe(0.2);
|
|
594
|
+
});
|
|
595
|
+
test("handles loop changes during playback", async () => {
|
|
596
|
+
const audio = createAudio("test.mp3", { loop: false });
|
|
597
|
+
await audio.play();
|
|
598
|
+
audio.setLoop(true);
|
|
599
|
+
expect(audio.getState().loop).toBe(true);
|
|
600
|
+
audio.setLoop(false);
|
|
601
|
+
expect(audio.getState().loop).toBe(false);
|
|
602
|
+
});
|
|
603
|
+
});
|
|
604
|
+
});
|
|
605
|
+
//# sourceMappingURL=audio.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audio.test.js","sourceRoot":"","sources":["../../src/tests/audio.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-text-game/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "A powerful React-based text game engine with reactive state management, passage-based navigation, and persistent save system for building interactive narrative experiences",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -68,6 +68,10 @@
|
|
|
68
68
|
"./i18n": {
|
|
69
69
|
"types": "./dist/i18n/index.d.ts",
|
|
70
70
|
"import": "./dist/i18n/index.js"
|
|
71
|
+
},
|
|
72
|
+
"./audio": {
|
|
73
|
+
"types": "./dist/audio/index.d.ts",
|
|
74
|
+
"import": "./dist/audio/index.js"
|
|
71
75
|
}
|
|
72
76
|
}
|
|
73
77
|
}
|