@opentui/core 0.4.2 → 0.4.4

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/Renderable.d.ts CHANGED
@@ -10,8 +10,6 @@ import type { RenderContext } from "./types.js";
10
10
  declare const BrandedRenderable: unique symbol;
11
11
  export declare enum LayoutEvents {
12
12
  LAYOUT_CHANGED = "layout-changed",
13
- ADDED = "added",
14
- REMOVED = "removed",
15
13
  RESIZED = "resized"
16
14
  }
17
15
  export declare enum RenderableEvents {
@@ -98,7 +96,7 @@ export declare abstract class BaseRenderable extends EventEmitter {
98
96
  protected _visible: boolean;
99
97
  constructor(options: BaseRenderableOptions);
100
98
  abstract add(obj: BaseRenderable | unknown, index?: number): number;
101
- abstract remove(id: string): void;
99
+ abstract remove(child: BaseRenderable): void;
102
100
  abstract insertBefore(obj: BaseRenderable | unknown, anchor: BaseRenderable | unknown): void;
103
101
  abstract getChildren(): BaseRenderable[];
104
102
  abstract getChildrenCount(): number;
@@ -151,7 +149,6 @@ export declare abstract class Renderable extends BaseRenderable {
151
149
  protected _position: Position;
152
150
  protected _opacity: number;
153
151
  private _flexShrink;
154
- private renderableMapById;
155
152
  protected _childrenInLayoutOrder: Renderable[];
156
153
  protected _childrenInZIndexOrder: Renderable[];
157
154
  private needsZIndexSort;
@@ -164,8 +161,6 @@ export declare abstract class Renderable extends BaseRenderable {
164
161
  renderBefore?: (this: Renderable, buffer: OptimizedBuffer, deltaTime: number) => void;
165
162
  renderAfter?: (this: Renderable, buffer: OptimizedBuffer, deltaTime: number) => void;
166
163
  constructor(ctx: RenderContext, options: RenderableOptions<any>);
167
- get id(): string;
168
- set id(value: string);
169
164
  get focusable(): boolean;
170
165
  set focusable(value: boolean);
171
166
  get ctx(): RenderContext;
@@ -267,7 +262,7 @@ export declare abstract class Renderable extends BaseRenderable {
267
262
  add(obj: Renderable | VNode<any, any[]> | unknown, index?: number): number;
268
263
  insertBefore(obj: Renderable | VNode<any, any[]> | unknown, anchor?: Renderable | unknown): number;
269
264
  getRenderable(id: string): Renderable | undefined;
270
- remove(id: string): void;
265
+ remove(child: BaseRenderable): void;
271
266
  protected onRemove(): void;
272
267
  getChildren(): Renderable[];
273
268
  getChildrenCount(): number;
@@ -0,0 +1,19 @@
1
+ import type { AudioStreamMetadata } from "../audio.js";
2
+ export type AudioStreamDemuxOutput<M> = {
3
+ type: "audio";
4
+ data: Uint8Array;
5
+ } | {
6
+ type: "metadata";
7
+ metadata: M | null;
8
+ };
9
+ export interface AudioStreamDemuxer<M> {
10
+ readonly initialMetadata: M | null;
11
+ push(chunk: Uint8Array): Iterable<AudioStreamDemuxOutput<M>>;
12
+ flush(): Iterable<AudioStreamDemuxOutput<M>>;
13
+ abort?(reason: unknown): void;
14
+ }
15
+ export type AudioStreamDemuxerFactory<M> = () => AudioStreamDemuxer<M>;
16
+ export declare function selectAudioStreamDemuxer(options: {
17
+ headers: Headers;
18
+ metadataEncoding: string;
19
+ }): AudioStreamDemuxer<AudioStreamMetadata> | null;
@@ -0,0 +1,21 @@
1
+ import type { AudioStreamMetadata } from "../../audio.js";
2
+ import type { AudioStreamDemuxer, AudioStreamDemuxOutput } from "../demuxer.js";
3
+ export interface IcyStreamDemuxerOptions {
4
+ metadataInterval: number;
5
+ metadataEncoding?: string;
6
+ headers?: Readonly<Record<string, string>>;
7
+ }
8
+ export declare class IcyStreamDemuxer implements AudioStreamDemuxer<AudioStreamMetadata> {
9
+ readonly initialMetadata: AudioStreamMetadata;
10
+ private audioRemaining;
11
+ private metadata;
12
+ private metadataOffset;
13
+ private fields;
14
+ private readonly interval;
15
+ private readonly decoder;
16
+ private readonly headers;
17
+ constructor(options: IcyStreamDemuxerOptions);
18
+ push(chunk: Uint8Array): IterableIterator<AudioStreamDemuxOutput<AudioStreamMetadata>>;
19
+ flush(): IterableIterator<AudioStreamDemuxOutput<AudioStreamMetadata>>;
20
+ }
21
+ export declare function createIcyStreamDemuxer(options: IcyStreamDemuxerOptions): AudioStreamDemuxer<AudioStreamMetadata>;
@@ -0,0 +1 @@
1
+ export declare function parseIcyMetadata(bytes: Uint8Array, decoder: TextDecoder): Readonly<Record<string, string>> | null;
package/audio.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { EventEmitter } from "events";
2
- import type { AudioStats } from "./zig-structs.js";
2
+ import { type AudioStreamDemuxer, type AudioStreamDemuxerFactory } from "./audio-stream/demuxer.js";
3
+ import { type AudioStats } from "./zig-structs.js";
3
4
  export interface AudioSetupOptions {
4
5
  autoStart?: boolean;
5
6
  sampleRate?: number;
@@ -29,6 +30,119 @@ export interface AudioPlayOptions {
29
30
  loop?: boolean;
30
31
  groupId?: number;
31
32
  }
33
+ export type AudioStreamBody = ReadableStream<Uint8Array> | AsyncIterable<Uint8Array>;
34
+ export type AudioStreamFormat = "mp3" | "flac";
35
+ export interface AudioStreamContentTypeContext {
36
+ readonly format: AudioStreamFormat;
37
+ readonly contentType: string | null;
38
+ readonly status: number;
39
+ readonly url: string;
40
+ }
41
+ export type AudioStreamContentTypePolicy = "validate" | "ignore" | ((context: AudioStreamContentTypeContext) => boolean);
42
+ export interface AudioStreamConnectContext {
43
+ readonly signal: AbortSignal;
44
+ readonly attempt: number;
45
+ }
46
+ export interface AudioStreamConnection<I = unknown> {
47
+ readonly body: AudioStreamBody;
48
+ readonly info: I;
49
+ close?(): void | Promise<void>;
50
+ }
51
+ export type AudioStreamRetryPhase = "connect" | "read";
52
+ export interface AudioStreamRetryContext {
53
+ readonly attempt: number;
54
+ readonly maxRetries: number;
55
+ readonly phase: AudioStreamRetryPhase;
56
+ }
57
+ export type AudioStreamRetryDecision = false | {
58
+ readonly delayMs?: number;
59
+ };
60
+ export interface AudioStreamConnector<I = unknown> {
61
+ connect(context: AudioStreamConnectContext): Promise<AudioStreamConnection<I>>;
62
+ }
63
+ export interface AudioStreamBufferOptions {
64
+ capacityMs?: number;
65
+ startupMs?: number;
66
+ resumeMs?: number;
67
+ }
68
+ export interface AudioStreamReconnectOptions {
69
+ maxRetries?: number;
70
+ initialDelayMs?: number;
71
+ maxDelayMs?: number;
72
+ backoffFactor?: number;
73
+ retryOnEnd?: boolean;
74
+ retry?(error: AudioStreamError, context: AudioStreamRetryContext): AudioStreamRetryDecision;
75
+ }
76
+ export interface AudioStreamOptions {
77
+ format?: AudioStreamFormat;
78
+ volume?: number;
79
+ pan?: number;
80
+ groupId?: number;
81
+ maxProbeBytes?: number;
82
+ buffer?: AudioStreamBufferOptions;
83
+ signal?: AbortSignal;
84
+ }
85
+ export interface AudioStreamBodyOptions<M = AudioStreamMetadata> extends AudioStreamOptions {
86
+ demuxer?: AudioStreamDemuxerFactory<M>;
87
+ contentTypePolicy?: never;
88
+ request?: never;
89
+ reconnect?: never;
90
+ metadataEncoding?: never;
91
+ }
92
+ export interface AudioStreamSourceOptions<I = unknown, M = AudioStreamMetadata> extends AudioStreamOptions {
93
+ demuxer?: (info: I) => AudioStreamDemuxer<M> | null;
94
+ reconnect?: AudioStreamReconnectOptions;
95
+ contentTypePolicy?: never;
96
+ request?: never;
97
+ metadataEncoding?: never;
98
+ }
99
+ export interface AudioStreamUrlOptions extends AudioStreamOptions {
100
+ request?: Omit<RequestInit, "body" | "signal">;
101
+ reconnect?: AudioStreamReconnectOptions;
102
+ metadataEncoding?: string;
103
+ contentTypePolicy?: AudioStreamContentTypePolicy;
104
+ demuxer?: never;
105
+ }
106
+ export type AudioStreamState = "initializing" | "buffering" | "playing" | "reconnecting" | "ended" | "errored" | "disposed";
107
+ export interface AudioStreamStats {
108
+ state: AudioStreamState;
109
+ sampleRate: number;
110
+ channels: number;
111
+ bufferedFrames: number;
112
+ capacityFrames: number;
113
+ bufferedDurationMs: number;
114
+ bytesReceived: bigint;
115
+ framesDecoded: bigint;
116
+ framesPlayed: bigint;
117
+ underruns: number;
118
+ reconnectAttempts: number;
119
+ }
120
+ export type AudioStreamMetadataFormat = "icy";
121
+ export interface AudioStreamMetadata {
122
+ readonly format: AudioStreamMetadataFormat;
123
+ readonly headers: Readonly<Record<string, string>>;
124
+ readonly fields: Readonly<Record<string, string>>;
125
+ }
126
+ export type AudioStreamAction = "fetch" | "response" | "source" | "demuxer" | "create" | "write" | "end" | "restart" | "stats" | "decoder" | "destroy" | "setVolume" | "setPan" | "setGroup";
127
+ export interface AudioStreamErrorContext {
128
+ action: AudioStreamAction;
129
+ status?: number;
130
+ errorCode?: number;
131
+ attempt?: number;
132
+ }
133
+ export interface AudioStreamReconnectEvent {
134
+ attempt: number;
135
+ delayMs: number;
136
+ maxRetries: number;
137
+ error: AudioStreamError;
138
+ }
139
+ export interface AudioStreamEvents<M = AudioStreamMetadata> {
140
+ metadata: [metadata: M | null];
141
+ reconnecting: [event: AudioStreamReconnectEvent];
142
+ ended: [];
143
+ error: [error: Error, context: AudioStreamErrorContext];
144
+ disposed: [];
145
+ }
32
146
  export type AudioGroup = number;
33
147
  export type AudioVoice = number;
34
148
  export type AudioSound = number;
@@ -49,15 +163,97 @@ export interface AudioEvents {
49
163
  stopped: [];
50
164
  disposed: [];
51
165
  }
166
+ export type AudioInitializationAction = "resolveRenderLib" | "createAudioEngine" | "start";
167
+ export declare class AudioInitializationError extends Error {
168
+ readonly action: AudioInitializationAction;
169
+ readonly status?: number;
170
+ constructor(action: AudioInitializationAction, message: string, status?: number, cause?: unknown);
171
+ }
172
+ export declare class AudioStreamError extends Error {
173
+ readonly context: AudioStreamErrorContext;
174
+ constructor(message: string, context: AudioStreamErrorContext, cause?: unknown);
175
+ }
176
+ export declare class AudioStream<M = AudioStreamMetadata> extends EventEmitter<AudioStreamEvents<M>> {
177
+ readonly closed: Promise<void>;
178
+ readonly format: AudioStreamFormat;
179
+ private readonly lib;
180
+ private readonly engine;
181
+ private readonly connector;
182
+ private readonly demuxerFactory?;
183
+ private readonly readAction;
184
+ private readonly options;
185
+ private readonly removeFromOwner;
186
+ private readonly lifecycleController;
187
+ private nativeStreamId;
188
+ private nativeStats;
189
+ private activeAttempt;
190
+ private pendingCleanup;
191
+ private reconnectAttempts;
192
+ private consecutiveReconnectAttempts;
193
+ private disposed;
194
+ private exposed;
195
+ private terminalError;
196
+ private metadata;
197
+ private pendingMetadataEvent;
198
+ private metadataEventScheduled;
199
+ private terminalEventScheduled;
200
+ private setupResolve;
201
+ private setupReject;
202
+ private closedResolve;
203
+ private readonly setupPromise;
204
+ private readonly overallAbortListener;
205
+ private constructor();
206
+ get state(): AudioStreamState;
207
+ private open;
208
+ getStats(): AudioStreamStats;
209
+ getMetadata(): M | null;
210
+ setVolume(volume: number): boolean;
211
+ setPan(pan: number): boolean;
212
+ setGroup(groupId: number): boolean;
213
+ private control;
214
+ dispose(): void;
215
+ private runLifecycle;
216
+ private createNativeStream;
217
+ private consumeSource;
218
+ private pumpSource;
219
+ private processDemuxOutput;
220
+ private writeStreamChunk;
221
+ private resolveConnection;
222
+ private beginResourceAcquisition;
223
+ private cleanupAttempt;
224
+ private performAttemptCleanup;
225
+ private runBoundedAttemptCleanup;
226
+ private retry;
227
+ private awaitReady;
228
+ private observeReady;
229
+ private awaitEnded;
230
+ private pollNativeSnapshot;
231
+ private snapshotError;
232
+ private finish;
233
+ private publishMetadata;
234
+ private emitMetadata;
235
+ private emitAsync;
236
+ private emitTerminal;
237
+ private isAttemptActive;
238
+ private stopSource;
239
+ private closeNativeStream;
240
+ private readNativeStats;
241
+ private toPublicStats;
242
+ private removeOwner;
243
+ }
52
244
  export declare class Audio extends EventEmitter<AudioEvents> {
53
245
  static create(options?: AudioSetupOptions): Audio;
246
+ readonly sampleRate: number;
54
247
  private readonly lib;
55
248
  private readonly defaultStartOptions;
56
249
  private engine;
57
250
  private readonly groups;
251
+ private readonly streams;
58
252
  private playbackStarted;
59
253
  private mixerStarted;
254
+ private disposing;
60
255
  private constructor();
256
+ private throwAfterInitializationCleanup;
61
257
  private emitError;
62
258
  start(options?: AudioStartOptions): boolean;
63
259
  startMixer(): boolean;
@@ -69,6 +265,10 @@ export declare class Audio extends EventEmitter<AudioEvents> {
69
265
  unloadSound(sound: AudioSound): boolean;
70
266
  group(name: string): AudioGroup | null;
71
267
  play(sound: AudioSound, options?: AudioPlayOptions): AudioVoice | null;
268
+ playStream<M = AudioStreamMetadata>(source: AudioStreamBody, options?: AudioStreamBodyOptions<M>): Promise<AudioStream<M>>;
269
+ playStreamUrl(source: string | URL, options?: AudioStreamUrlOptions): Promise<AudioStream<AudioStreamMetadata>>;
270
+ playStreamSource<I, M = AudioStreamMetadata>(connector: AudioStreamConnector<I>, options?: AudioStreamSourceOptions<I, M>): Promise<AudioStream<M>>;
271
+ private openStream;
72
272
  stopVoice(voice: AudioVoice): boolean;
73
273
  setVoiceGroup(voice: AudioVoice, group: AudioGroup): boolean;
74
274
  setGroupVolume(group: AudioGroup, volume: number): boolean;