export type PictureDataType = import('../../basics/mediaContent.mjs').PictureDataType; export type MediaContentBase = import('../../basics/mediaContent.mjs').MediaContentBase; export type MediaContentMetadata = import('../../basics/mediaContent.mjs').MediaContentMetadata; export type MediaContent = import('../../basics/mediaContent.mjs').MediaContent; export type IPicture = import('../../basics/mediaContent.mjs').IPicture; export type MediaNumber = import('../../basics/mediaContent.mjs').MediaNumber; export type MediaLoadingError = import('../../basics/mediaContent.mjs').MediaLoadingError; export type MediaLoadingErrorData = import('../../basics/mediaContent.mjs').MediaLoadingErrorData; export type LoadingMediaProgress = import('../../basics/mediaContent.mjs').LoadingMediaProgress; export type ParseMediaContentMetadata = import('../../basics/mediaContent.mjs').ParseMediaContentMetadata; export type UnknownArtistGetter = import('../../basics/mediaContent.mjs').UnknownArtistGetter; export type CustomPosition = { /** * - The audio/music content. */ content: MediaContent; /** * - The absolute Date.now() target. */ intendedTimestamp: number; /** * - The timestamp preserved for intelligent repositioning. */ originalTimestamp: number; }; export type ScheduledMovePayload = { /** * - Content ID to move. */ id: string; /** * - The target index in the playlist. */ newIndex: number; }; export type ScheduledTaskPayload = MediaContent | string | ScheduledMovePayload; export type ScheduledTask = { /** * - The absolute time to execute the action. */ timestamp: number; /** * - The type of modification. */ action: 'add' | 'remove' | 'move'; /** * - Target playlist. */ type: 'music' | 'voice'; /** * - Data relative to the action. */ payload: ScheduledTaskPayload; }; export type RadioEvent = { /** * - Content ID. */ id: string; /** * - Content title. */ title: string; /** * - Content artist. */ artist: string; /** * - Source URL/Path. */ url: string; /** * - Total duration of the event. */ duration: number; /** * - Start timestamp within the absolute timeline. */ absoluteStart: number; /** * - End timestamp within the absolute timeline. */ absoluteEnd: number; /** * - How many ms have passed since the event started. */ elapsedTime: number; /** * - How many ms are left until the event ends. */ remainingTime: number; /** * - Percentage of completion (0 to 1). */ progress: number; /** * - Whether this is a user-defined custom position. */ isCustom: boolean; }; export type RadioModes = 'playlist' | 'random'; export type RadioConfig = { /** * - Sequence mode for music. */ mode: RadioModes; /** * - Sequence mode for voices. */ voiceMode: RadioModes; /** * - Gap in ms between tracks. */ silenceDuration: number; /** * - Safety lock for max items processed. */ queryLimit: number; /** * - Whether to play voice messages after music tracks. */ voiceAfterMusic: boolean; /** * - Weight used to calculate the probability of a voice block occurring. */ voiceWeight: number; /** * - Minimum amount of voice messages to play if voiceAfterMusic is true. */ voiceMin: number; /** * - Maximum amount of voice messages to play. */ voiceMax: number; /** * - Max times a music track can repeat consecutively (-1 = unlimited, 0 = strictly no repetition). */ musicMaxConsecutive: number; /** * - Min times a music track must repeat consecutively (1 = no mandatory repetition). */ musicMinConsecutive: number; /** * - Max times a voice track can repeat consecutively (-1 = unlimited, 0 = strictly no repetition). */ voiceMaxConsecutive: number; /** * - Min times a voice track can repeat consecutively (1 = no mandatory repetition). */ voiceMinConsecutive: number; }; export type CycleBlockData = MediaContent & { cycleStart: number; cycleEnd: number; }; export type CycleBlock = { /** * - Items belonging to this cycle. */ items: CycleBlockData[]; /** * - Total duration of the cycle block in ms. */ duration: number; /** * - ID of the last music played in this block. */ lastMusicId: string | null; /** * - Current consecutive count for music. */ musicConsecutiveCount: number; /** * - ID of the last voice played in this block. */ lastVoiceId: string | null; /** * - Current consecutive count for voice. */ voiceConsecutiveCount: number; }; export type CycleLocation = { /** * - The located cycle block. */ block: CycleBlock; /** * - The absolute start time of this cycle. */ startTimestamp: number; /** * - The specific loop iteration index. */ loopIndex: number; }; export type TinyRadioFmImport = { /** * - The music playlist. */ music: MediaContent[]; /** * - The voice playlist. */ voice: MediaContent[]; /** * - The custom position injections. */ custom: CustomPosition[]; /** * - The pending scheduled tasks. */ tasks: ScheduledTask[]; /** * - The randomness seed. */ seed: number; /** * - The timeline anchor timestamp. */ anchorDate: number; /** * - The engine configuration. */ config: RadioConfig; }; export type TinyRadioFmEvents = { /** * - Emitted when the seed changes. */ seedChanged: (data: { seed: number; }) => void; /** * - Emitted when the configuration changes. */ configChanged: (data: { config: RadioConfig; }) => void; /** * - Emitted when content is added. */ contentAdded: (data: { type: string; data: MediaContent; }) => void; /** * - Emitted when content is removed. */ contentRemoved: (data: { id: string; }) => void; /** * - Emitted when a task is scheduled. */ taskScheduled: (task: ScheduledTask) => void; /** * - Emitted when a scheduled task is executed. */ taskExecuted: (task: ScheduledTask) => void; /** * - Emitted when a custom position expires. */ customPositionExpired: (data: { contentId: string; }) => void; /** * - Emitted after a timeline query. */ timelineQueried: (data: { targetDate: number; limit: number; resultCount: number; }) => void; /** * - Emitted after a state import. */ stateImported: (data: { data: TinyRadioFmImport; }) => void; /** * - Emitted when the instance is destroyed. */ destroyed: (data: { timestamp: number; }) => void; }; /** * @typedef {import('../../basics/mediaContent.mjs').PictureDataType} PictureDataType * @typedef {import('../../basics/mediaContent.mjs').MediaContentBase} MediaContentBase * @typedef {import('../../basics/mediaContent.mjs').MediaContentMetadata} MediaContentMetadata * @typedef {import('../../basics/mediaContent.mjs').MediaContent} MediaContent * @typedef {import('../../basics/mediaContent.mjs').IPicture} IPicture * @typedef {import('../../basics/mediaContent.mjs').MediaNumber} MediaNumber * @typedef {import('../../basics/mediaContent.mjs').MediaLoadingError} MediaLoadingError * @typedef {import('../../basics/mediaContent.mjs').MediaLoadingErrorData} MediaLoadingErrorData * @typedef {import('../../basics/mediaContent.mjs').LoadingMediaProgress} LoadingMediaProgress * @typedef {import('../../basics/mediaContent.mjs').ParseMediaContentMetadata} ParseMediaContentMetadata * @typedef {import('../../basics/mediaContent.mjs').UnknownArtistGetter} UnknownArtistGetter */ /** * Represents a content item injected at a specific point in the absolute timeline. * @typedef {Object} CustomPosition * @property {MediaContent} content - The audio/music content. * @property {number} intendedTimestamp - The absolute Date.now() target. * @property {number} originalTimestamp - The timestamp preserved for intelligent repositioning. */ /** * Data required to relocate an existing item within a playlist. * @typedef {Object} ScheduledMovePayload * @property {string} id - Content ID to move. * @property {number} newIndex - The target index in the playlist. */ /** * A union type representing the various data formats a scheduled task payload can take. * @typedef {MediaContent | string | ScheduledMovePayload} ScheduledTaskPayload */ /** * A scheduled instruction to modify the radio state at a specific point in time. * @typedef {Object} ScheduledTask * @property {number} timestamp - The absolute time to execute the action. * @property {'add'|'remove'|'move'} action - The type of modification. * @property {'music'|'voice'} type - Target playlist. * @property {ScheduledTaskPayload} payload - Data relative to the action. */ /** * A standardized representation of an active or upcoming event in the radio timeline. * @typedef {Object} RadioEvent * @property {string} id - Content ID. * @property {string} title - Content title. * @property {string} artist - Content artist. * @property {string} url - Source URL/Path. * @property {number} duration - Total duration of the event. * @property {number} absoluteStart - Start timestamp within the absolute timeline. * @property {number} absoluteEnd - End timestamp within the absolute timeline. * @property {number} elapsedTime - How many ms have passed since the event started. * @property {number} remainingTime - How many ms are left until the event ends. * @property {number} progress - Percentage of completion (0 to 1). * @property {boolean} isCustom - Whether this is a user-defined custom position. */ /** * The available sequence logic modes for playlist playback. * @typedef {'playlist'|'random'} RadioModes */ /** * Global configuration settings for the radio engine behavior. * @typedef {Object} RadioConfig * @property {RadioModes} mode - Sequence mode for music. * @property {RadioModes} voiceMode - Sequence mode for voices. * @property {number} silenceDuration - Gap in ms between tracks. * @property {number} queryLimit - Safety lock for max items processed. * @property {boolean} voiceAfterMusic - Whether to play voice messages after music tracks. * @property {number} voiceWeight - Weight used to calculate the probability of a voice block occurring. * @property {number} voiceMin - Minimum amount of voice messages to play if voiceAfterMusic is true. * @property {number} voiceMax - Maximum amount of voice messages to play. * @property {number} musicMaxConsecutive - Max times a music track can repeat consecutively (-1 = unlimited, 0 = strictly no repetition). * @property {number} musicMinConsecutive - Min times a music track must repeat consecutively (1 = no mandatory repetition). * @property {number} voiceMaxConsecutive - Max times a voice track can repeat consecutively (-1 = unlimited, 0 = strictly no repetition). * @property {number} voiceMinConsecutive - Min times a voice track can repeat consecutively (1 = no mandatory repetition). */ /** * An extension of MediaContent that includes temporal boundaries within a generated cycle. * @typedef {MediaContent & { cycleStart: number; cycleEnd: number; }} CycleBlockData */ /** * A structural block representing a single full iteration of the radio sequence. * @typedef {Object} CycleBlock * @property {CycleBlockData[]} items - Items belonging to this cycle. * @property {number} duration - Total duration of the cycle block in ms. * @property {string|null} lastMusicId - ID of the last music played in this block. * @property {number} musicConsecutiveCount - Current consecutive count for music. * @property {string|null} lastVoiceId - ID of the last voice played in this block. * @property {number} voiceConsecutiveCount - Current consecutive count for voice. */ /** * Information about the location of a specific cycle within the absolute timeline. * @typedef {Object} CycleLocation * @property {CycleBlock} block - The located cycle block. * @property {number} startTimestamp - The absolute start time of this cycle. * @property {number} loopIndex - The specific loop iteration index. */ /** * The complete state object used for exporting and importing the radio system. * @typedef {Object} TinyRadioFmImport * @property {MediaContent[]} music - The music playlist. * @property {MediaContent[]} voice - The voice playlist. * @property {CustomPosition[]} custom - The custom position injections. * @property {ScheduledTask[]} tasks - The pending scheduled tasks. * @property {number} seed - The randomness seed. * @property {number} anchorDate - The timeline anchor timestamp. * @property {RadioConfig} config - The engine configuration. */ /** * Event map for {@link TinyRadioFm}. * @typedef {Object} TinyRadioFmEvents * @property {(data: { seed: number }) => void} seedChanged - Emitted when the seed changes. * @property {(data: { config: RadioConfig }) => void} configChanged - Emitted when the configuration changes. * @property {(data: { type: string, data: MediaContent }) => void} contentAdded - Emitted when content is added. * @property {(data: { id: string }) => void} contentRemoved - Emitted when content is removed. * @property {(task: ScheduledTask) => void} taskScheduled - Emitted when a task is scheduled. * @property {(task: ScheduledTask) => void} taskExecuted - Emitted when a scheduled task is executed. * @property {(data: { contentId: string }) => void} customPositionExpired - Emitted when a custom position expires. * @property {(data: { targetDate: number, limit: number, resultCount: number }) => void} timelineQueried - Emitted after a timeline query. * @property {(data: { data: TinyRadioFmImport }) => void} stateImported - Emitted after a state import. * @property {(data: { timestamp: number }) => void} destroyed - Emitted when the instance is destroyed. */ /** @type {new (initialData?: TinyRadioFmImport|null, seed?: number) => import('../../jsdoc/EventEmitter.mjs').ICustomEventEmitter} */ declare const TypedEventEmitter: new (initialData?: TinyRadioFmImport | null, seed?: number) => import('../../jsdoc/EventEmitter.mjs').ICustomEventEmitter; /** * A deterministic, seed-based radio management system with scheduled adaptations and weighted random generation. * @beta */ declare class TinyRadioFm extends TypedEventEmitter { #private; /** * A Static Factory Method that prepares a MediaContent object by * extracting metadata from an audio source. * * @param {string | HTMLMediaElement} source - A URL string or an existing Audio object. * @param {Partial & { id?: string; weight?: number }} [defaultMetadata={}] - Optional default metadata. * @param {Partial & { id?: string; weight?: number }} [metadata={}] - Optional manual metadata. * @param {ParseMediaContentMetadata} [parseFile] - Private helper to interface with parseFile. * @param {Object} [callbacks={}] - Callbacks for monitoring the loading process. * @param {(progress: LoadingMediaProgress) => void} [callbacks.onProgress] - Callback triggered on stage changes. * @param {(error: MediaLoadingErrorData) => void} [callbacks.onError] - Callback triggered when a non-fatal or fatal error occurs. * @param {boolean} [convertBase64toBlob=true] - If the image content needs to be converted directly into a high-performance Blob URL, use this method. * @returns {Promise} A promise that resolves to a valid MediaContent object. * @throws {MediaLoadingError} If the preparation process fails at any stage. */ static parseContent(source: string | HTMLMediaElement, defaultMetadata?: Partial & { id?: string; weight?: number; }, metadata?: Partial & { id?: string; weight?: number; }, parseFile?: ParseMediaContentMetadata, callbacks?: { onProgress?: (progress: LoadingMediaProgress) => void; onError?: (error: MediaLoadingErrorData) => void; }, convertBase64toBlob?: boolean): Promise; /** * Gets the current value used to represent unknown artists. * @returns {UnknownArtistGetter} */ static get unknownArtist(): UnknownArtistGetter; /** * Sets the value used to represent unknown artists. * @param {UnknownArtistGetter} value - A string or a function that returns a string. * @throws {TypeError} If the value is neither a string nor a function. */ static set unknownArtist(value: UnknownArtistGetter); get destroyed(): boolean; /** * Gets the total count of all content items (music and voice) in the system. * @returns {number} */ get size(): number; /** * Gets the total number of items in the music playlist. * @returns {number} */ get musicSize(): number; /** * Gets the total number of items in the voice playlist. * @returns {number} */ get voiceSize(): number; /** * Gets the number of active custom position injections. * @returns {number} */ get customPosSize(): number; /** * Gets the number of pending scheduled tasks. * @returns {number} */ get tasksSize(): number; /** * Gets the number of items currently stored in the cycle cache. * @returns {number} */ get cycleCacheSize(): number; /** * Gets a deep clone of the music playlist. * @returns {MediaContent[]} */ get musicList(): MediaContent[]; /** * Gets a deep clone of the voice playlist. * @returns {MediaContent[]} */ get voiceList(): MediaContent[]; /** * Gets a deep clone of the custom position injections. * @returns {CustomPosition[]} */ get customPositions(): CustomPosition[]; /** * Gets a deep clone of the scheduled tasks. * @returns {ScheduledTask[]} */ get scheduledTasks(): ScheduledTask[]; /** * Returns a deep clone of the internal all list cache. * @returns {MediaContent[]} A cloned object of the cache. */ get allList(): MediaContent[]; /** * Gets the current randomness seed. * @returns {number} */ get seed(): number; /** * Sets the core randomness seed and clears the current cycle cache. * @param {number} seed - The new seed. */ set seed(seed: number); /** * Gets the absolute timestamp used as the timeline anchor. * @returns {number} */ get anchorDate(): number; /** * Gets a deep clone of the current radio configuration. * @returns {RadioConfig} */ get config(): RadioConfig; /** * Performs a complete replacement of the configuration. * @param {RadioConfig} config - The new full configuration object. * @throws {TypeError|RangeError} If the new configuration is invalid. */ set config(config: RadioConfig); /** * Gets whether Blob URLs for media content * should be converted to Base64 during export and restored during import. * @returns {boolean} */ get optimizeMediaMemory(): boolean; /** * Sets whether Blob URLs should be converted to Base64 during export and restored during import. * @param {boolean} value * @throws {TypeError} If value is not a boolean. */ set optimizeMediaMemory(value: boolean); /** * Gets whether Blob URLs for pictures * should be converted to Base64 during export and restored during import. * @returns {boolean} */ get optimizePictureMemory(): boolean; /** * Sets whether Blob URLs should be converted to Base64 during export and restored during import. * @param {boolean} value * @throws {TypeError} If value is not a boolean. */ set optimizePictureMemory(value: boolean); /** * Initializes the radio system. * @param {TinyRadioFmImport|null} [initialData=null] - JSON object to hydrate the radio state. * @param {number} [seed=0] - Initial seed for deterministic randomness. * @throws {TypeError} If initialData is not an object or null, or if seed is not a number. */ constructor(initialData?: TinyRadioFmImport | null, seed?: number); /** * Converts new content base64 instantly to the blob url. * @param {MediaContent} data */ _ccBase64ToBlobUrl(data: MediaContent): void; /** * Restores the content blob instantly to the base64 url. * @param {MediaContent} data */ _rcblobUrlToBase64(data: MediaContent): Promise; /** * Adds new content instantly to the radio sequence. * @param {'music'|'voice'|'custom'} type - The category of the content. * @param {MediaContent & { timestamp?: number }} data - The content payload to insert. * @param {boolean} [smartQueue=true] - If true, delays insertion until the end of the content playing at that timestamp (only affects 'custom'). * @throws {TypeError} If the type is invalid or the data lacks a valid ID and numerical duration. */ add(type: 'music' | 'voice' | 'custom', data: MediaContent & { timestamp?: number; }, smartQueue?: boolean): void; /** * Schedules a modification to the base playlists, seamlessly breaking the timeline when activated. * @param {number} timestamp - Epoch timestamp in ms. * @param {'add'|'remove'|'move'} action - Action to perform. * @param {'music'|'voice'} type - Target list. * @param {ScheduledTaskPayload} payload - Data relative to the action. * @param {boolean} [smartQueue=true] - If true, delays the task execution until the end of the content playing at that timestamp. * @throws {TypeError} If arguments do not match the required types or action/type constraints. */ scheduleTask(timestamp: number, action: 'add' | 'remove' | 'move', type: 'music' | 'voice', payload: ScheduledTaskPayload, smartQueue?: boolean): void; /** * Removes content instantly by ID across all active lists, positions, and future tasks. * @param {string} id - The unique identifier of the content. * @throws {TypeError} If the id is not a string. */ remove(id: string): void; /** * Performs a partial update of the configuration. * @param {Partial} config - The configuration overrides. * @throws {TypeError|RangeError} If the provided values or the resulting state is invalid. */ setConfig(config: Partial): void; /** * Retrieves the exact event playing at the current system time. * @returns {RadioEvent|null} The current active event, or null if empty. */ getCurrentEvent(): RadioEvent | null; /** * Queries the timeline from a specific date forward to predict upcoming events. * Uses a virtual clone to predict scheduled tasks accurately without mutating current state. * @param {number} targetDate - The starting epoch timestamp. * @param {number} [limit=10] - Maximum number of upcoming events to resolve. * @returns {RadioEvent[]} Array of resolved upcoming events. * @throws {TypeError} If limit is not a number. * @throws {RangeError} If the limit exceeds the configured queryLimit or is <= 0. */ queryTimeline(targetDate: number, limit?: number): RadioEvent[]; /** * Returns all active custom positions currently injected into the timeline. * @returns {CustomPosition[]} Shallow copy of custom positions array. */ searchCustomPositions(): CustomPosition[]; /** * Process a content list, waiting to convert the images and content URLs from Blob URL to Base64. * @param {MediaContent[]} list * @returns {Promise} * @private */ private _processListForExport; /** * Exports the complete state of the radio, including caches and scheduled tasks. * @returns {string} Stringified JSON state. * @private */ private _exportState; /** * Exports the complete state of the radio, including caches and scheduled tasks. * @returns {Promise} Stringified JSON state. */ exportState(): Promise; /** * Imports a previously exported state, overwriting the current instance. * @param {string|TinyRadioFmImport} json - JSON state or object. * @throws {TypeError} If json is not a valid string or object. */ importState(json: string | TinyRadioFmImport): void; /** * Mulberry32 Pseudo-Random Number Generator. * @param {number} seed - The initialization seed. * @returns {() => number} PRNG function returning a float between 0 and 1. * @private */ private _prng; /** * Destroys the radio instance, releasing all allocated memory (including Blob URLs) * and permanently cleaning all caches, lists and tasks. * @param {boolean} [destroyThumbs=true] */ destroy(destroyThumbs?: boolean): void; } export default TinyRadioFm; //# sourceMappingURL=TinyRadioFm.d.mts.map