export type Normalization = 'relative' | 'softmax'; export type RngGenerator = () => number; export type TempModifier = { /** * - Function that modifies the item weights. */ fn: WeightsCallback; /** * - Number of draws this modifier remains active before being removed. */ uses: number; }; export type ItemDataTemplate | string[]> = { /** * - Unique identifier for the item. */ id: string; /** * - Human-readable name for the item. */ label: string; /** * - The base probability weight before modifiers. */ baseWeight: number; /** * - The groups the item belongs to (Set or string[]). */ groups: TGroups; /** * - Whether the item is currently locked (excluded from draws). */ locked: boolean; /** * - Arbitrary metadata associated with the item. */ meta: ItemMetadata; }; export type ExportedJson = { /** * - Array of item objects in their exported form. */ items: ItemDataGetter[]; /** * - Array of tuples where the first element is the item ID and the second is its associated Pity system state. */ pity: [string, Pity][]; /** * - List of item IDs excluded from the draw. */ exclusions: string[]; /** * - The normalization mode used in weight calculations. */ normalization: Normalization; /** * - The RNG seed used for reproducibility, or null if no seed is set. */ seed: number | null; }; export type ItemData = ItemDataTemplate>; export type ItemDataGetter = ItemDataTemplate; export type ItemMetadata = Record; export type ComputeEffectiveWeightsContext = { /** * - Metadata of the current raffle state or item. */ metadata?: ItemMetadata; /** * - History of previously drawn items. */ previousDraws?: DrawOne[]; }; export type Weights = Map; export type Pity = { /** * - Number of draws without a win before pity starts applying. */ threshold: number; /** * - Additional weight applied per pity step. */ increment: number; /** * - Maximum total pity weight allowed. */ cap: number; /** * - Current number of consecutive draws without a win. */ counter: number; /** * - Current pity weight being applied. */ currentAdd: number; }; export type WeightsCallback = (weights: Weights, context: ComputeEffectiveWeightsContext) => Weights | null; export type DrawOne = { /** * - Item ID. */ id: string; /** * - Human-readable label of the drawn item. */ label: string; /** * - Arbitrary metadata of the drawn item. */ meta: ItemMetadata; /** * - Final probability of the item at draw time. */ prob: number; }; export type handler = (payload: any, event: any) => any; export type TinyAdvancedRaffleEvents = { /** * - Emitted when an item is added. */ itemAdded: (item: ItemData) => void; /** * - Emitted when an item is removed. */ itemRemoved: (id: string) => void; /** * - Emitted when an item's base weight changes. */ weightChanged: (data: { id: string; weight: number; }) => void; /** * - Emitted after a successful draw. */ draw: (result: DrawOne) => void; }; /** * Defines the available normalization strategies for probability weight calculations. * @typedef {'relative' | 'softmax'} Normalization */ /** * Generates a pseudo-random number between 0 (inclusive) and 1 (exclusive). * @callback RngGenerator * @returns {number} - A floating-point number in the range [0, 1). */ /** * Represents a temporary weight modifier that is applied for a limited number of draws. * @typedef {Object} TempModifier * @property {WeightsCallback} fn - Function that modifies the item weights. * @property {number} uses - Number of draws this modifier remains active before being removed. */ /** * Represents the core data structure for an item in the raffle system. * @template {Set|string[]} TGroups * @typedef {Object} ItemDataTemplate * @property {string} id - Unique identifier for the item. * @property {string} label - Human-readable name for the item. * @property {number} baseWeight - The base probability weight before modifiers. * @property {TGroups} groups - The groups the item belongs to (Set or string[]). * @property {boolean} locked - Whether the item is currently locked (excluded from draws). * @property {ItemMetadata} meta - Arbitrary metadata associated with the item. */ /** * Represents the serialized state of the raffle system for export or persistence. * @typedef {Object} ExportedJson * @property {ItemDataGetter[]} items - Array of item objects in their exported form. * @property {[string, Pity][]} pity - Array of tuples where the first element is the item ID and the second is its associated Pity system state. * @property {string[]} exclusions - List of item IDs excluded from the draw. * @property {Normalization} normalization - The normalization mode used in weight calculations. * @property {number|null} seed - The RNG seed used for reproducibility, or null if no seed is set. */ /** * A concrete version of ItemDataTemplate where groups is Set. * @typedef {ItemDataTemplate>} ItemData */ /** * A concrete version of ItemDataTemplate where groups is string[]. * @typedef {ItemDataTemplate} ItemDataGetter */ /** * Arbitrary key-value metadata container for additional item information. * Keys can be strings, numbers, or symbols. * @typedef {Record} ItemMetadata */ /** * Context object passed to weight modification functions during draw calculations. * @typedef {Object} ComputeEffectiveWeightsContext * @property {ItemMetadata} [metadata] - Metadata of the current raffle state or item. * @property {DrawOne[]} [previousDraws] - History of previously drawn items. */ /** * Maps each item ID to its computed effective weight. * @typedef {Map} Weights */ /** * Pity system configuration and current state. * @typedef {Object} Pity * @property {number} threshold - Number of draws without a win before pity starts applying. * @property {number} increment - Additional weight applied per pity step. * @property {number} cap - Maximum total pity weight allowed. * @property {number} counter - Current number of consecutive draws without a win. * @property {number} currentAdd - Current pity weight being applied. */ /** * Function used to modify or override computed weights before a draw. * @callback WeightsCallback * @param {Weights} weights - Current computed item weights. * @param {ComputeEffectiveWeightsContext} context - Additional context data for calculation. * @returns {Weights|null} - Modified weights map, or null to skip modification. */ /** * Represents the result of a single draw. * @typedef {Object} DrawOne * @property {string} id - Item ID. * @property {string} label - Human-readable label of the drawn item. * @property {ItemMetadata} meta - Arbitrary metadata of the drawn item. * @property {number} prob - Final probability of the item at draw time. */ /** * Generic event handler function for message or signal reception. * @callback handler * @param {any} payload - The data sent by the emitter. * @param {any} event - Metadata about the emitted event. */ /** * Event map for {@link TinyAdvancedRaffle}. * @typedef {Object} TinyAdvancedRaffleEvents * @property {(item: ItemData) => void} itemAdded - Emitted when an item is added. * @property {(id: string) => void} itemRemoved - Emitted when an item is removed. * @property {(data: { id: string, weight: number }) => void} weightChanged - Emitted when an item's base weight changes. * @property {(result: DrawOne) => void} draw - Emitted after a successful draw. */ /** @type {new () => import('../../jsdoc/EventEmitter.mjs').ICustomEventEmitter} */ declare const TypedEventEmitter: new () => import('../../jsdoc/EventEmitter.mjs').ICustomEventEmitter; /** * TinyAdvancedRaffle — A high-performance, fully customizable raffle system. * * This class provides advanced item drawing capabilities with: * - Weighted probabilities and adjustable normalization modes (relative, softmax). * - Seedable RNG for reproducible results. * - Pity system support for fairness in repeated draws. * - Temporary and permanent weight modifiers. * - Item exclusions and group-based filtering. * - JSON import/export for persistence and sharing. * - Event-based architecture for monitoring and extending behaviors. * * @class */ declare class TinyAdvancedRaffle extends TypedEventEmitter { #private; /** * Indicates whether this instance has been destroyed. * @type {boolean} */ get isDestroyed(): boolean; /** * Returns a plain object representation of the draw frequency map. * The keys are item IDs and the values are the number of times each item was drawn. * @returns {Record} - Object with item IDs as keys and their respective draw counts. */ get freq(): Record; /** * Returns the total number of registered items in the raffle. * @returns {number} Total count of items. */ get size(): number; /** * Gets the current probability normalization strategy. * @returns {Normalization} Current normalization mode. */ get normalization(): Normalization; /** * Sets the probability normalization strategy. * @param {Normalization} value - Accepted values: `'relative'` or `'softmax'`. * @throws {TypeError} If value is not a non-empty string. */ set normalization(value: Normalization); /** * Gets the current RNG seed value, if any. * @returns {number|null} Current seed or `null` if RNG is not seeded. */ get seed(): number | null; /** * Sets the RNG seed for deterministic randomization. * @param {number|null} value - Finite number or `null` to disable seeding. * @throws {TypeError} If not `null` or a finite number. */ set seed(value: number | null); /** * Gets all global weight modifier callbacks. * @returns {WeightsCallback[]} Array of registered global modifier functions. */ get globalModifiers(): WeightsCallback[]; /** * Replaces all global weight modifier callbacks. * @param {WeightsCallback[]} value - Array of modifier functions. * @throws {TypeError} If not an array of functions. */ set globalModifiers(value: WeightsCallback[]); /** * Gets all temporary modifiers with usage counters. * @returns {TempModifier[]} Array of temporary modifier entries. */ get temporaryModifiers(): TempModifier[]; /** * Replaces all temporary modifiers. * @param {TempModifier[]} value - Each object must have a function and a positive integer usage count. * @throws {TypeError} If structure is invalid. */ set temporaryModifiers(value: TempModifier[]); /** * Gets all conditional rule callbacks. * @returns {WeightsCallback[]} Array of conditional rule functions. */ get conditionalRules(): WeightsCallback[]; /** * Replaces all conditional rule callbacks. * @param {WeightsCallback[]} value - Array of functions. * @throws {TypeError} If not an array of functions. */ set conditionalRules(value: WeightsCallback[]); /** * Gets a shallow copy of all configured pity systems. * @returns {Record} Object keyed by system name. */ get pitySystems(): Record; /** * Replaces all pity systems. * @param {Map} value - Map of pity systems with numeric fields. * @throws {TypeError} If structure is invalid. */ set pitySystems(value: Map); /** * Gets a copy of all exclusion IDs. * @returns {string[]} Array of item IDs excluded from draws. */ get exclusions(): string[]; /** * Replaces all exclusion IDs. * @param {Set} value - Set of excluded item IDs. * @throws {TypeError} If not a Set of strings. */ set exclusions(value: Set); /** * Gets all group definitions. * @returns {Record} Object where each key is a group name and value is an array of item IDs. */ get groups(): Record; /** * Replaces all group definitions. * @param {Map>} value - Map of group names to item ID sets. * @throws {TypeError} If not a valid Map>. */ set groups(value: Map>); /** * Gets the current RNG function. * @returns {RngGenerator} Function returning a floating-point number in [0, 1). */ get rng(): RngGenerator; /** * Sets the RNG function. * @param {RngGenerator} value - Function returning a number between 0 and 1. * @throws {TypeError} If not a valid function. */ set rng(value: RngGenerator); /** * Gets all item definitions with group names expanded to arrays. * @returns {Record} Object keyed by item ID. */ get items(): Record; /** * Replaces all items (**and CLEAR OLD LIST**). * @param {Map} value - Map of item IDs to definitions. * @throws {TypeError} If structure is invalid. */ set items(value: Map); /** * Creates a new AdvancedRaffle instance. * @param {Object} [opts] - Optional configuration. * @param {RngGenerator|null} [opts.rng=null] - Custom RNG function. If null, an internal seeded RNG is used when a seed is provided. * @param {number|null} [opts.seed=null] - Optional seed for deterministic results. * @param {Normalization} [opts.normalization='relative'] - Probability normalization mode. */ constructor(opts?: { rng?: RngGenerator | null; seed?: number | null; normalization?: Normalization; }); /** * Check if an item exists in the system. * @param {string} itemId - Item ID to check. * @returns {boolean} `true` if the item exists, otherwise `false`. * @throws {TypeError} If `itemId` is not a string. */ hasItem(itemId: string): boolean; /** * Add or update an item. * @param {string} id - Unique item identifier. * @param {Object} [opts={}] - Item configuration options. * @param {number} [opts.weight=1] - Base relative weight (must be >= 0). * @param {string} [opts.label] - Human-readable label for the item. * @param {ItemMetadata} [opts.meta={}] - Arbitrary metadata for the item. * @param {string[]|Set} [opts.groups=[]] - Group names to attach. * @returns {ItemData} * @throws {TypeError} If any parameter has an invalid type. */ addItem(id: string, opts?: { weight?: number; label?: string; meta?: ItemMetadata; groups?: string[] | Set; }): ItemData; /** * Remove an item from the system. * @param {string} id - The unique item identifier to remove. * @returns {boolean} True if the item was removed, false if it did not exist. * @throws {TypeError} If id is not a string. */ removeItem(id: string): boolean; /** * Set a new base weight for an item. * @param {string} id - The unique item identifier. * @param {number} weight - The new base weight (must be >= 0). * @throws {Error} If the item is not found. * @throws {TypeError} If weight is invalid. */ setBaseWeight(id: string, weight: number): void; /** * Get an item by its ID. * @param {string} id - The unique item identifier. * @returns {ItemData|null} The item data, or null if not found. * @throws {TypeError} If id is not a string. */ getItem(id: string): ItemData | null; /** * List all items as cloned objects. * @returns {ItemData[]} Array of cloned item objects. */ listItems(): ItemData[]; /** * Clear all items from the system. */ clearList(): void; /** * Check if a persistent global modifier exists. * @param {WeightsCallback} fn - Modifier callback function to check. * @returns {boolean} `true` if the modifier exists, otherwise `false`. * @throws {TypeError} If `fn` is not a function. */ hasGlobalModifier(fn: WeightsCallback): boolean; /** * Add a persistent modifier callback. * The callback receives `(weightsMap, context)` and must return a Map of overrides/additions or modifications. * @param {WeightsCallback} fn - Modifier callback function. * @throws {TypeError} If `fn` is not a function. */ addGlobalModifier(fn: WeightsCallback): void; /** * Remove a persistent modifier callback. * @param {WeightsCallback} fn - Modifier callback to remove. * @throws {TypeError} If `fn` is not a function. */ removeGlobalModifier(fn: WeightsCallback): void; /** * Check if a specific temporary modifier exists. * @param {WeightsCallback} fn - Temporary modifier callback to check. * @returns {boolean} `true` if the modifier exists, otherwise `false`. * @throws {TypeError} If `fn` is not a function. */ hasTemporaryModifier(fn: WeightsCallback): boolean; /** * Add a temporary modifier applied to the next `uses` draws (default 1). * The modifier returns the same structure as a global modifier. * @param {WeightsCallback} fn - Temporary modifier callback. * @param {number} [uses=1] - Number of draws the modifier will be active for. * @throws {TypeError} If `fn` is not a function. * @throws {TypeError} If `uses` is not a number. */ addTemporaryModifier(fn: WeightsCallback, uses?: number): void; /** * Remove a specific temporary modifier. * * @param {WeightsCallback} fn - The temporary modifier callback to remove. * @returns {boolean} `true` if a modifier was removed, `false` otherwise. * @throws {TypeError} If `fn` is not a function. */ removeTemporaryModifier(fn: WeightsCallback): boolean; /** * Check if a specific conditional rule exists. * @param {WeightsCallback} ruleFn - Conditional rule function to check. * @returns {boolean} `true` if the rule exists, otherwise `false`. * @throws {TypeError} If `ruleFn` is not a function. */ hasConditionalRule(ruleFn: WeightsCallback): boolean; /** * Add a conditional rule (applied each draw). * Receives context `{previousDraws, activeModifiers, metadata}`. * Should return a Map of `itemId => deltaWeight` (can be positive or negative). * @param {WeightsCallback} ruleFn - Conditional rule function. * @throws {TypeError} If `ruleFn` is not a function. */ addConditionalRule(ruleFn: WeightsCallback): void; /** * Remove a specific conditional rule. * * @param {WeightsCallback} ruleFn - The conditional rule function to remove. * @returns {boolean} `true` if a rule was removed, `false` otherwise. * @throws {TypeError} If `ruleFn` is not a function. */ removeConditionalRule(ruleFn: WeightsCallback): boolean; /** * Check if a pity configuration exists for a given item. * @param {string} itemId - Item ID to check. * @returns {boolean} `true` if pity is configured, otherwise `false`. * @throws {TypeError} If `itemId` is not a string. */ hasPity(itemId: string): boolean; /** * Configure pity for an item. * If the item fails to appear for `threshold` draws, add `increment` to its base weight each draw until `cap` is reached. * @param {string} itemId - ID of the item to configure. * @param {Object} cfg - Pity configuration. * @param {number} cfg.threshold - Number of failed draws before applying pity. * @param {number} cfg.increment - Additional weight to add each draw after threshold. * @param {number} [cfg.cap=Infinity] - Maximum additional weight allowed. * @throws {Error} If the item does not exist. * @throws {TypeError} If parameters are invalid. */ configurePity(itemId: string, cfg: { threshold: number; increment: number; cap?: number; }): void; /** * Reset pity counters for a given item. * @param {string} itemId - ID of the item. * @throws {TypeError} If itemId is not a string. */ resetPity(itemId: string): void; /** * Remove all pity configurations. */ clearPities(): void; /** * Check if an item is excluded from the raffle. * @param {string} itemId - Item ID to check. * @returns {boolean} `true` if excluded, otherwise `false`. * @throws {TypeError} If `itemId` is not a string. */ hasExclusion(itemId: string): boolean; /** * Exclude an item from the raffle. * @param {string} itemId - ID of the item. * @throws {TypeError} If `itemId` is not a string. */ excludeItem(itemId: string): void; /** * Re-include an item in the raffle. * @param {string} itemId - ID of the item. * @throws {TypeError} If `itemId` is not a string. */ includeItem(itemId: string): void; /** * Ensure a group exists, creating it if necessary. * @param {string} name - Group name. * @returns {Set} The group set. * @throws {TypeError} If `name` is not a string. * @private */ private _ensureGroup; /** * Check if an item is in a given group. * @param {string} itemId - ID of the item. * @param {string} groupName - Name of the group. * @returns {boolean} `true` if the item is in the group, otherwise `false`. * @throws {TypeError} If parameters are not strings. */ hasInGroup(itemId: string, groupName: string): boolean; /** * Add an item to a group. * @param {string} itemId - ID of the item. * @param {string} groupName - Name of the group. * @throws {Error} If the item does not exist. * @throws {TypeError} If parameters are not strings. */ addToGroup(itemId: string, groupName: string): void; /** * Remove an item from a group. * @param {string} itemId - ID of the item. * @param {string} groupName - Name of the group. * @throws {TypeError} If parameters are not strings. */ removeFromGroup(itemId: string, groupName: string): void; /** * Clears the draw frequency count for all items. * Effectively resets the internal frequency map to an empty state. */ clearFreqs(): void; /** * Removes the draw frequency entry for a specific item. * If the item ID does not exist in the frequency map, nothing happens. * * @param {string} itemId - Unique identifier of the item whose frequency should be reset. * @throws {TypeError} If `itemId` is not a string. */ resetFreq(itemId: string): void; /** * Compute effective weights after applying modifiers, rules, and pity adjustments. * Starts with base weights, then applies global, temporary, conditional modifiers, * pity increments, removes exclusions, and removes zero or negative weights. * * @param {ComputeEffectiveWeightsContext} [context={}] - Optional context with previous draws and metadata. * @returns {Map} A Map of itemId to effective weight. * @throws {TypeError} If `context` is provided but is not an object. */ computeEffectiveWeights(context?: ComputeEffectiveWeightsContext): Map; /** * Convert a map of weights into a probability distribution array, * normalized according to the current normalization method. * Returns array with each element containing id, weight, probability (p), * and cumulative probability (for sampling). * * @param {Map} weights - Map of item IDs to their weights. * @returns {Array<{id: string, weight: number, p: number, cumulative: number}>} Distribution array. * @throws {TypeError} If `weights` is not a Map. * @private */ private _weightsToDistribution; /** * Draw a single item from the raffle using current configuration. * Uses previous draws and metadata to influence conditional rules and pity. * * @param {Object} [opts={}] - Optional draw options. * @param {DrawOne[]} [opts.previousDraws=[]] - History of previous draws. * @param {ItemMetadata} [opts.metadata={}] - Arbitrary metadata for conditional rules. * @returns {DrawOne|null} The drawn item object or null if no items available. * @throws {TypeError} If `opts` is not an object. */ drawOne(opts?: { previousDraws?: DrawOne[]; metadata?: ItemMetadata; }): DrawOne | null; /** * Internal helper to decrement usage counts of temporary modifiers, * removing them when their uses reach zero. * @private */ private _consumeTemporaryModifiers; /** * Draw multiple items from the raffle with configurable options. * * @param {number} count - Number of items to draw. * @param {Object} [opts={}] - Optional parameters. * @param {ItemMetadata} [opts.metadata={}] - Metadata passed to conditional rules. * @param {boolean} [opts.withReplacement=true] - Whether to allow the same item multiple times. * @param {boolean} [opts.ensureUnique=false] - If true, attempts to ensure unique results in multi-draws. * @param {DrawOne[]} [opts.previousDraws=[]] - Previous draw history for context. * @returns {DrawOne[]} List of drawn items. * @throws {TypeError} If `count` is not a positive integer. * @throws {TypeError} If `opts` is not an object. */ drawMany(count?: number, opts?: { metadata?: ItemMetadata; withReplacement?: boolean; ensureUnique?: boolean; previousDraws?: DrawOne[]; }): DrawOne[]; /** * Export the current configuration to a JSON-serializable object. * Contains all items, pity systems, exclusions, normalization mode, and seed. * * @returns {ExportedJson} Exported configuration object. */ exportToJson(): ExportedJson; /** * Load configuration from JSON object produced by `exportToJson`. * Clears current items and state before loading. * * @param {ExportedJson} data - Data to load from. * @throws {TypeError} If `data` is not an object or missing required properties. * @throws {TypeError} If `data.seed` is not a number, null, or undefined. */ loadFromJson(data: ExportedJson): void; /** * Creates a deep clone of the current instance, including all internal state. * All Maps, Sets, and Arrays are fully duplicated to avoid shared references. * Functions are copied by reference since they are immutable in JavaScript. * @returns {TinyAdvancedRaffle} A new cloned instance, fully independent from the original. */ clone(): TinyAdvancedRaffle; /** * Create a deterministic pseudo-random number generator (PRNG) seeded with `seed`. * Uses the mulberry32 algorithm. * * @param {number} seed - Seed value for PRNG (integer). * @returns {RngGenerator} A function that returns a pseudo-random number in [0, 1). * @throws {TypeError} If `seed` is not a finite number. * @private */ private _makeSeededRng; /** * Completely destroys the raffle instance, clearing all data, * releasing references, and making the object unusable. * Once destroyed, any further method calls will throw errors. */ destroy(): void; } export default TinyAdvancedRaffle; //# sourceMappingURL=TinyAdvancedRaffle.d.mts.map