drawlots
v1.1.0
Published
Gerador probabilístico com estado baseado no algoritmo Mulberry32
Downloads
210
Maintainers
Readme
🎲 Drawlots
Gerador probabilístico com estado baseado no algoritmo Mulberry32 para sorteios condicionais, seleção aleatória e embaralhamento. Ideal para simulações, jogos, testes A/B e qualquer cenário que exija decisões aleatórias com probabilidade controlada.
📦 Instalação
npm install drawlots
# ou
pnpm add drawlots
# ou
yarn add drawlots🚀 Uso Básico
import { Drawlots } from 'drawlots';
// Cria uma instância com semente fixa e probabilidade de 30%
const draw = new Drawlots({ seed: 42, prob: 0.3 });
// Itera 10 passos, executando o callback apenas quando random() < 0.3
draw.loop(10, index => {
console.log(`Índice ${index} foi sorteado!`);
});
// O estado interno pode ser salvo e restaurado
const snapshot = draw.state;
const restored = Drawlots.restore(snapshot);📘 API
new Drawlots(opts?: DrawlotsOptions)
| Parâmetro | Tipo | Padrão | Descrição |
| ---------------------- | --------------------------- | ----------- | ------------------------------------------------ |
| opts.seed | number (0 a 0xffffffff) | aleatório | Semente do gerador. |
| opts.prob | number (0, 1) | 0.5 | Probabilidade de sucesso. |
| opts.state | number (0 a 0xffffffff) | undefined | Estado interno inicial. |
| opts.logger | boolean \| DrawlotsLogger | console | Logger (ou false para silenciar log/warn). |
| opts.skipValidations | boolean | false | Desabilita validações (use com cautela). |
Exceção: Lança DrawlotsInitializeError se as validações falharem.
Métodos de Iteração
loop(steps, callback, opts?)
Itera steps vezes, executando callback(index) se random() < prob.
draw.loop(
100,
i => {
// i é sorteado com probabilidade prob
},
{ prob: 0.2 },
); // prob local opcionaleach(iterable, callback, opts?)
Itera sobre um Iterable, chamando callback(item, index) para cada elemento aprovado.
const items = ['A', 'B', 'C', 'D'];
draw.each(items, (item, idx) => {
console.log(`${item} foi sorteado!`);
});Métodos de Seleção e Embaralhamento
randomIndex(value)
Retorna um índice aleatório válido para um array ou string. Retorna -1 se o valor estiver vazio.
const arr = [10, 20, 30];
const idx = draw.randomIndex(arr); // 0, 1 ou 2randomItem(value)
Seleciona um elemento aleatório do array ou string sem modificar o original. Retorna undefined se vazio.
const item = draw.randomItem(['a', 'b', 'c']); // 'a', 'b' ou 'c'
const char = draw.randomItem('hello'); // 'h', 'e', etc.takeRandomItem(value)
Seleciona um elemento aleatório e remove do array/string original (modifica o valor passado). Retorna undefined se vazio.
const list = [1, 2, 3];
const taken = draw.takeRandomItem(list); // 2, por exemplo
console.log(list); // [1, 3]takeRandomItems(value, n, opts?)
Seleciona n elementos distintos e remove do original. Aceita opções de validação (skipValidations, logger). Retorna os itens ordenados.
const pool = ['x', 'y', 'z', 'w'];
const picked = draw.takeRandomItems(pool, 2);
console.log(picked); // ['y', 'z'] (exemplo)
console.log(pool); // ['x', 'w']randomItems(value, n, opts?)
Seleciona n elementos distintos sem modificar o original (opera sobre uma cópia). Mesmas opções e ordenação.
const original = [1, 2, 3, 4, 5];
const chosen = draw.randomItems(original, 3);
console.log(chosen); // [1, 3, 5] (exemplo)
console.log(original); // inalteradoshuffle(value)
Embaralha o array ou string usando o algoritmo Fisher‑Yates. Retorna uma nova cópia, sem modificar a entrada.
const numbers = [1, 2, 3, 4];
const shuffled = draw.shuffle(numbers);
console.log(shuffled); // [3, 1, 4, 2] (exemplo)
console.log(numbers); // [1, 2, 3, 4] (inalterado)
const word = draw.shuffle('abc'); // 'bca', 'cab', etc.Propriedades (Getters e Setters)
| Getter / Setter | Tipo | Descrição |
| --------------- | ---------------- | ------------------------------------------------------------------------------- |
| random | () => number | Função que gera o próximo número aleatório em [0, 1) e avança o estado. |
| peek | () => number | Retorna o próximo número sem avançar o estado. |
| state | DrawlotsState | Objeto imutável com seed, prob e state interno. |
| fork | Drawlots | Nova instância com o mesmo estado e logger. |
| reset | () => this | Reinicia o gerador para o estado inicial (semente). |
| logger (get) | DrawlotsLogger | Retorna uma versão congelada do logger atual. |
| logger (set) | DrawlotsLogger | Permite substituir o logger por um novo objeto que implemente DrawlotsLogger. |
Métodos Estáticos
Drawlots.restore(state, logger?)
Restaura uma instância a partir de um estado salvo.
const saved = draw.state;
const newDraw = Drawlots.restore(saved);🧩 Interfaces e Tipos
DrawlotsConfig
seed: number– semente (32 bits)prob: number– probabilidade em(0, 1)
DrawlotsOptions (extends Partial<DrawlotsConfig>)
state?: number– estado interno (32 bits)logger?: boolean | DrawlotsLogger– logger oufalseskipValidations?: boolean– desativa validações
DrawlotsState (extends Readonly<DrawlotsConfig>)
state?: number– estado interno (se inicializado)
DrawlotsLogger
log(...data: unknown[]): voidwarn(...data: unknown[]): voiderror(...data: unknown[]): void
DrawlotsMethodOptions
logger?: boolean | DrawlotsLogger– logger localskipValidations?: booleanprob?: number– probabilidade local (sobrescreve a da instância; ignorado nos métodos que não aceitamprob)
🔍 Exemplos Avançados
Logging Personalizado
import winston from 'winston';
const logger = winston.createLogger({/* ... */});
const draw = new Drawlots({
seed: 123,
prob: 0.4,
logger,
});
// O logger também pode ser alterado posteriormente
draw.logger = outroLogger;Desativar Logs Temporariamente
draw.loop(5, callback, { logger: false });Clonagem (Fork)
const clone = draw.fork;
// clone e draw compartilham o mesmo estado e sequênciaReiniciar o Gerador
draw.reset(); // volta ao estado inicial (semente)Seleção Aleatória com Remoção
const participantes = ['Bianca', 'Bruno', 'Indra', 'Sabrina'];
const sorteado = draw.takeRandomItem(participantes);
console.log(`${sorteado} foi removido da lista.`);
console.log(participantes); // agora contém apenas 3 nomesEmbaralhamento de Baralho
const naipes = ['♠', '♥', '♦', '♣'];
const baralho = naipes.flatMap(n =>
['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K'].map(
v => v + n,
),
);
const embaralhado = draw.shuffle(baralho);⚠️ Tratamento de Erros
A biblioteca lança erros específicos para facilitar o diagnóstico:
DrawlotsInitializeError– na construçãoDrawlotsLoopError– emloop()DrawlotsEachError– emeach()DrawlotsTakeRandomItemsError– emtakeRandomItems()(parâmetros inválidos)DrawlotsRandomItemsError– emrandomItems()(seleção mal sucedida)
Todos herdam de DrawlotsError e carregam dados estruturados sobre a falha.
try {
const draw = new Drawlots({ prob: 1.5 });
} catch (err) {
if (err instanceof DrawlotsInitializeError) {
console.error(err.data); // { prob: ['prob cannot be greater than or equal to 1.'] }
}
}🧠 Detalhes Técnicos
- Algoritmo: Mulberry32 – rápido, com bom espectro aleatório e estado de 32 bits.
- Probabilidade: restrita ao intervalo aberto
(0, 1)para evitar comportamentos triviais (nunca/sempre). - Validações: ativas por padrão; podem ser desligadas para maior desempenho em ambientes controlados.
- Estado: o gerador mantém um estado interno de 32 bits que evolui a cada chamada de
random(). - Logger: agora é uma propriedade completamente integrada à instância, podendo ser lida, substituída ou congelada.
📄 Licença
MIT © Bianca Maxine
