narraleaf-react 0.20.0 → 0.21.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.
@@ -98,9 +98,10 @@ export declare const SoundActionTypes: {
98
98
  readonly pause: "sound:pause";
99
99
  readonly resume: "sound:resume";
100
100
  readonly mute: "sound:mute";
101
+ readonly seek: "sound:seek";
101
102
  };
102
103
  export type SoundActionContentType = {
103
- [K in typeof SoundActionTypes[keyof typeof SoundActionTypes]]: K extends "sound:play" ? [FadeOptions] : K extends "sound:stop" ? [FadeOptions] : K extends "sound:setVolume" ? [volume: number, duration: number] : K extends "sound:setRate" ? [number] : K extends "sound:pause" ? [FadeOptions] : K extends "sound:resume" ? [FadeOptions] : K extends "sound:mute" ? [boolean] : any;
104
+ [K in typeof SoundActionTypes[keyof typeof SoundActionTypes]]: K extends "sound:play" ? [FadeOptions] : K extends "sound:stop" ? [FadeOptions] : K extends "sound:setVolume" ? [volume: number, duration: number] : K extends "sound:setRate" ? [number] : K extends "sound:pause" ? [FadeOptions] : K extends "sound:resume" ? [FadeOptions] : K extends "sound:mute" ? [boolean] : K extends "sound:seek" ? [time: number] : any;
104
105
  };
105
106
  export declare const ControlActionTypes: {
106
107
  readonly action: "control:action";
@@ -15,6 +15,7 @@ export declare class SoundAction<T extends typeof SoundActionTypes[keyof typeof
15
15
  readonly pause: "sound:pause";
16
16
  readonly resume: "sound:resume";
17
17
  readonly mute: "sound:mute";
18
+ readonly seek: "sound:seek";
18
19
  };
19
20
  executeAction(state: GameState, injection: ActionExecutionInjection): ExecutedActionResult;
20
21
  stringify(_story: Story, _seen: Set<LogicAction.Actions>, _strict: boolean): string;
@@ -40,10 +40,28 @@ export interface ISoundUserConfig {
40
40
  */
41
41
  streaming: boolean;
42
42
  /**
43
- * Initial position in seconds
43
+ * Initial position in seconds - the clip's **in point**.
44
+ *
45
+ * When {@link ISoundUserConfig.loop} is set together with {@link ISoundUserConfig.endTime},
46
+ * this is also where each repeat restarts from, so the two together describe a loop region
47
+ * rather than just a starting offset.
44
48
  * @default 0
45
49
  */
46
50
  seek: number;
51
+ /**
52
+ * Position in seconds where the clip ends - its **out point**. Omit (or `undefined`) to play
53
+ * through to the end of the file.
54
+ *
55
+ * Without `loop` the clip simply stops there. With `loop` it jumps back to
56
+ * {@link ISoundUserConfig.seek}, which is how a piece of background music with an intro loops
57
+ * only its body. The jump is sample-accurate (it is the Web Audio node's own loop), so there is
58
+ * no gap and no drift over long sessions.
59
+ *
60
+ * Ignored for a clip that is streamed rather than decoded: an `<audio>` element has no loop
61
+ * region, only a plain repeat.
62
+ * @default undefined
63
+ */
64
+ endTime?: number;
47
65
  /**
48
66
  * The type of the sound
49
67
  * @default SoundType.Sound
@@ -133,6 +151,20 @@ export declare class Sound extends Actionable<SoundDataRaw, Sound> {
133
151
  * @chainable
134
152
  */
135
153
  resume(duration?: number): ChainedSound;
154
+ /**
155
+ * Jump to a position in the clip, in seconds, and keep playing from there.
156
+ *
157
+ * A no-op on a sound that is not currently playing - there is nothing to move. The loop region
158
+ * (see {@link ISoundUserConfig.endTime}) survives the jump, so seeking inside a looping track
159
+ * does not turn it into a one-shot.
160
+ * @param time - Position in seconds, measured from the start of the file (not from the in point).
161
+ * @chainable
162
+ * @example
163
+ * ```ts
164
+ * sound.seek(30);
165
+ * ```
166
+ */
167
+ seek(time: number): ChainedSound;
136
168
  /**
137
169
  * Create a sound with the same configuration
138
170
  */
@@ -35,6 +35,21 @@ export declare class AudioManager {
35
35
  mute(sound: SoundElement, muted?: boolean): Awaitable<void>;
36
36
  pause(sound: SoundElement, duration?: number): Awaitable<void>;
37
37
  resume(sound: SoundElement, duration?: number): Awaitable<void>;
38
+ /**
39
+ * Move the play head of a sound that is currently playing. A sound this manager is not holding
40
+ * has no play head to move, so this is a no-op rather than an error - the same shape every other
41
+ * transport method here takes.
42
+ */
43
+ seek(sound: SoundElement, time: number): Awaitable<void>;
44
+ /**
45
+ * The in/out points of a clip as the sound backend's play options.
46
+ *
47
+ * `endTime` is left off entirely when the author set none: passing `undefined` explicitly is the
48
+ * same thing to the backend, but omitting it keeps `{...region}` spreads from writing a key that
49
+ * reads as "there is a region here" to anything inspecting the object.
50
+ */
51
+ private static clipRegionOf;
52
+ private static clampToRegion;
38
53
  setRate(sound: SoundElement, rate: number): Awaitable<void>;
39
54
  getPosition(sound: SoundElement): number;
40
55
  isPlaying(sound: SoundElement): boolean;