probability-picker 1.1.0 → 1.2.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.
package/dist/index.cjs CHANGED
@@ -22,8 +22,16 @@ function prepareEntries(entries) {
22
22
  if (sum === 100) return sorted;
23
23
  return normalizeProbabilities(sorted, sum);
24
24
  }
25
+ function secureRandom() {
26
+ if (typeof globalThis.crypto === "undefined" || typeof globalThis.crypto.getRandomValues !== "function") {
27
+ return Math.random();
28
+ }
29
+ const array = new Uint32Array(1);
30
+ globalThis.crypto.getRandomValues(array);
31
+ return array[0] / 4294967296;
32
+ }
25
33
  function random(min, max) {
26
- return Math.random() * (max - min) + min;
34
+ return secureRandom() * (max - min) + min;
27
35
  }
28
36
  function chooseOne(entries) {
29
37
  const num = random(1, 100);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;AAGA,SAAS,cAAc,OAAA,EAAkB;AACrC,EAAA,OAAO,OAAA,CAAQ,MAAA,CAAO,CAAA,CAAA,KAAK,OAAO,EAAE,CAAC,CAAA,KAAM,QAAA,IAAY,CAAC,MAAA,CAAO,KAAA,CAAM,CAAA,CAAE,CAAC,CAAC,CAAC,CAAA;AAC9E;AAEA,SAAS,YAAY,OAAA,EAAkB;AACnC,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,CAAC,CAAA;AAC7C;AAEA,SAAS,iBAAiB,OAAA,EAAkB;AACxC,EAAA,OAAO,OAAA,CAAQ,OAAO,CAAC,GAAA,EAAK,MAAM,GAAA,GAAM,CAAA,CAAE,CAAC,CAAA,EAAG,CAAC,CAAA;AACnD;AAEA,SAAS,sBAAA,CAAuB,SAAkB,KAAA,EAAe;AAC7D,EAAA,OAAO,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAC,GAAG,CAAC,CAAA,KAAM,CAAC,CAAA,EAAG,KAAK,KAAA,CAAO,CAAA,GAAI,KAAA,GAAS,GAAG,CAAC,CAAU,CAAA;AAC9E;AAEA,SAAS,eAAe,OAAA,EAAkB;AACtC,EAAA,MAAM,QAAA,GAAW,cAAc,OAAO,CAAA;AACtC,EAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AAC3B,EAAA,MAAM,MAAA,GAAS,YAAY,QAAQ,CAAA;AACnC,EAAA,MAAM,GAAA,GAAM,iBAAiB,MAAM,CAAA;AACnC,EAAA,IAAI,QAAQ,CAAA,EAAG;AACf,EAAA,IAAI,GAAA,KAAQ,KAAK,OAAO,MAAA;AACxB,EAAA,OAAO,sBAAA,CAAuB,QAAQ,GAAG,CAAA;AAC7C;AAEA,SAAS,MAAA,CAAO,KAAa,GAAA,EAAa;AACtC,EAAA,OAAO,IAAA,CAAK,MAAA,EAAO,IAAK,GAAA,GAAM,GAAA,CAAA,GAAO,GAAA;AACzC;AAEA,SAAS,UAAU,OAAA,EAAkB;AACjC,EAAA,MAAM,GAAA,GAAM,MAAA,CAAO,CAAA,EAAG,GAAG,CAAA;AACzB,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AACzB,IAAA,KAAA,IAAS,MAAM,CAAC,CAAA;AAChB,IAAA,IAAI,GAAA,IAAO,KAAA,EAAO,OAAO,KAAA,CAAM,CAAC,CAAA;AAAA,EACpC;AACA,EAAA,OAAO,OAAA,CAAQ,OAAA,CAAQ,MAAA,GAAS,CAAC,EAAG,CAAC,CAAA;AACzC;AAEA,SAAS,kBAAkB,GAAA,EAAgD;AACvE,EAAA,IAAI,EAAE,GAAA,YAAe,MAAA,CAAA,EAAS,OAAO,IAAA;AACrC,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA;AAClC,EAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG,OAAO,MAAA;AACjC,EAAA,MAAM,KAAA,GAAQ,QAAQ,CAAC,CAAA;AACvB,EAAA,IAAI,SAAS,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG,OAAO,MAAM,CAAC,CAAA;AACjD,EAAA,MAAM,QAAA,GAAW,eAAe,OAAO,CAAA;AACvC,EAAA,IAAI,CAAC,UAAU,OAAO,MAAA;AACtB,EAAA,OAAO,UAAU,QAAQ,CAAA;AAC7B;AAEA,IAAO,aAAA,GAAQ","file":"index.cjs","sourcesContent":["type ProbabilityMap = Record<string, number>\r\ntype Entry = [string, number]\r\n\r\nfunction filterNumbers(entries: Entry[]) {\r\n return entries.filter(e => typeof e[1] === 'number' && !Number.isNaN(e[1]))\r\n}\r\n\r\nfunction sortEntries(entries: Entry[]) {\r\n return entries.sort((a, b) => a[1] - b[1])\r\n}\r\n\r\nfunction sumProbabilities(entries: Entry[]) {\r\n return entries.reduce((acc, e) => acc + e[1], 0)\r\n}\r\n\r\nfunction normalizeProbabilities(entries: Entry[], total: number) {\r\n return entries.map(([k, v]) => [k, Math.round((v / total) * 100)] as Entry)\r\n}\r\n\r\nfunction prepareEntries(entries: Entry[]) {\r\n const filtered = filterNumbers(entries)\r\n if (filtered.length === 0) return\r\n const sorted = sortEntries(filtered)\r\n const sum = sumProbabilities(sorted)\r\n if (sum === 0) return\r\n if (sum === 100) return sorted\r\n return normalizeProbabilities(sorted, sum)\r\n}\r\n\r\nfunction random(min: number, max: number) {\r\n return Math.random() * (max - min) + min\r\n}\r\n\r\nfunction chooseOne(entries: Entry[]) {\r\n const num = random(1, 100)\r\n let count = 0\r\n for (const entry of entries) {\r\n count += entry[1]\r\n if (num <= count) return entry[0]\r\n }\r\n return entries[entries.length - 1]![0]\r\n}\r\n\r\nfunction probabilityPicker(map: ProbabilityMap): string | null | undefined {\r\n if (!(map instanceof Object)) return null\r\n const entries = Object.entries(map) as Entry[]\r\n if (entries.length === 0) return undefined\r\n const first = entries[0]\r\n if (first && entries.length === 1) return first[0]\r\n const prepared = prepareEntries(entries)\r\n if (!prepared) return undefined\r\n return chooseOne(prepared)\r\n}\r\n\r\nexport default probabilityPicker;"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["type ProbabilityMap = Record<string, number>\r\ntype Entry = [string, number]\r\n\r\nfunction filterNumbers(entries: Entry[]) {\r\n return entries.filter(e => typeof e[1] === 'number' && !Number.isNaN(e[1]))\r\n}\r\n\r\nfunction sortEntries(entries: Entry[]) {\r\n return entries.sort((a, b) => a[1] - b[1])\r\n}\r\n\r\nfunction sumProbabilities(entries: Entry[]) {\r\n return entries.reduce((acc, e) => acc + e[1], 0)\r\n}\r\n\r\nfunction normalizeProbabilities(entries: Entry[], total: number) {\r\n return entries.map(([k, v]) => [k, Math.round((v / total) * 100)] as Entry)\r\n}\r\n\r\nfunction prepareEntries(entries: Entry[]) {\r\n const filtered = filterNumbers(entries)\r\n if (filtered.length === 0) return\r\n const sorted = sortEntries(filtered)\r\n const sum = sumProbabilities(sorted)\r\n if (sum === 0) return\r\n if (sum === 100) return sorted\r\n return normalizeProbabilities(sorted, sum)\r\n}\r\n\r\nfunction secureRandom(): number {\r\n if (typeof globalThis.crypto === 'undefined' || typeof globalThis.crypto.getRandomValues !== 'function') {\r\n return Math.random()\r\n }\r\n const array = new Uint32Array(1)\r\n globalThis.crypto.getRandomValues(array)\r\n return array[0]! / 0x100000000\r\n}\r\n\r\nfunction random(min: number, max: number) {\r\n return secureRandom() * (max - min) + min\r\n}\r\n\r\nfunction chooseOne(entries: Entry[]) {\r\n const num = random(1, 100)\r\n let count = 0\r\n for (const entry of entries) {\r\n count += entry[1]\r\n if (num <= count) return entry[0]\r\n }\r\n return entries[entries.length - 1]![0]\r\n}\r\n\r\nfunction probabilityPicker(map: ProbabilityMap): string | null | undefined {\r\n if (!(map instanceof Object)) return null\r\n const entries = Object.entries(map) as Entry[]\r\n if (entries.length === 0) return undefined\r\n const first = entries[0]\r\n if (first && entries.length === 1) return first[0]\r\n const prepared = prepareEntries(entries)\r\n if (!prepared) return undefined\r\n return chooseOne(prepared)\r\n}\r\n\r\nexport default probabilityPicker;"]}
package/dist/index.js CHANGED
@@ -20,8 +20,16 @@ function prepareEntries(entries) {
20
20
  if (sum === 100) return sorted;
21
21
  return normalizeProbabilities(sorted, sum);
22
22
  }
23
+ function secureRandom() {
24
+ if (typeof globalThis.crypto === "undefined" || typeof globalThis.crypto.getRandomValues !== "function") {
25
+ return Math.random();
26
+ }
27
+ const array = new Uint32Array(1);
28
+ globalThis.crypto.getRandomValues(array);
29
+ return array[0] / 4294967296;
30
+ }
23
31
  function random(min, max) {
24
- return Math.random() * (max - min) + min;
32
+ return secureRandom() * (max - min) + min;
25
33
  }
26
34
  function chooseOne(entries) {
27
35
  const num = random(1, 100);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";AAGA,SAAS,cAAc,OAAA,EAAkB;AACrC,EAAA,OAAO,OAAA,CAAQ,MAAA,CAAO,CAAA,CAAA,KAAK,OAAO,EAAE,CAAC,CAAA,KAAM,QAAA,IAAY,CAAC,MAAA,CAAO,KAAA,CAAM,CAAA,CAAE,CAAC,CAAC,CAAC,CAAA;AAC9E;AAEA,SAAS,YAAY,OAAA,EAAkB;AACnC,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,CAAC,CAAA;AAC7C;AAEA,SAAS,iBAAiB,OAAA,EAAkB;AACxC,EAAA,OAAO,OAAA,CAAQ,OAAO,CAAC,GAAA,EAAK,MAAM,GAAA,GAAM,CAAA,CAAE,CAAC,CAAA,EAAG,CAAC,CAAA;AACnD;AAEA,SAAS,sBAAA,CAAuB,SAAkB,KAAA,EAAe;AAC7D,EAAA,OAAO,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAC,GAAG,CAAC,CAAA,KAAM,CAAC,CAAA,EAAG,KAAK,KAAA,CAAO,CAAA,GAAI,KAAA,GAAS,GAAG,CAAC,CAAU,CAAA;AAC9E;AAEA,SAAS,eAAe,OAAA,EAAkB;AACtC,EAAA,MAAM,QAAA,GAAW,cAAc,OAAO,CAAA;AACtC,EAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AAC3B,EAAA,MAAM,MAAA,GAAS,YAAY,QAAQ,CAAA;AACnC,EAAA,MAAM,GAAA,GAAM,iBAAiB,MAAM,CAAA;AACnC,EAAA,IAAI,QAAQ,CAAA,EAAG;AACf,EAAA,IAAI,GAAA,KAAQ,KAAK,OAAO,MAAA;AACxB,EAAA,OAAO,sBAAA,CAAuB,QAAQ,GAAG,CAAA;AAC7C;AAEA,SAAS,MAAA,CAAO,KAAa,GAAA,EAAa;AACtC,EAAA,OAAO,IAAA,CAAK,MAAA,EAAO,IAAK,GAAA,GAAM,GAAA,CAAA,GAAO,GAAA;AACzC;AAEA,SAAS,UAAU,OAAA,EAAkB;AACjC,EAAA,MAAM,GAAA,GAAM,MAAA,CAAO,CAAA,EAAG,GAAG,CAAA;AACzB,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AACzB,IAAA,KAAA,IAAS,MAAM,CAAC,CAAA;AAChB,IAAA,IAAI,GAAA,IAAO,KAAA,EAAO,OAAO,KAAA,CAAM,CAAC,CAAA;AAAA,EACpC;AACA,EAAA,OAAO,OAAA,CAAQ,OAAA,CAAQ,MAAA,GAAS,CAAC,EAAG,CAAC,CAAA;AACzC;AAEA,SAAS,kBAAkB,GAAA,EAAgD;AACvE,EAAA,IAAI,EAAE,GAAA,YAAe,MAAA,CAAA,EAAS,OAAO,IAAA;AACrC,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA;AAClC,EAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG,OAAO,MAAA;AACjC,EAAA,MAAM,KAAA,GAAQ,QAAQ,CAAC,CAAA;AACvB,EAAA,IAAI,SAAS,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG,OAAO,MAAM,CAAC,CAAA;AACjD,EAAA,MAAM,QAAA,GAAW,eAAe,OAAO,CAAA;AACvC,EAAA,IAAI,CAAC,UAAU,OAAO,MAAA;AACtB,EAAA,OAAO,UAAU,QAAQ,CAAA;AAC7B;AAEA,IAAO,aAAA,GAAQ","file":"index.js","sourcesContent":["type ProbabilityMap = Record<string, number>\r\ntype Entry = [string, number]\r\n\r\nfunction filterNumbers(entries: Entry[]) {\r\n return entries.filter(e => typeof e[1] === 'number' && !Number.isNaN(e[1]))\r\n}\r\n\r\nfunction sortEntries(entries: Entry[]) {\r\n return entries.sort((a, b) => a[1] - b[1])\r\n}\r\n\r\nfunction sumProbabilities(entries: Entry[]) {\r\n return entries.reduce((acc, e) => acc + e[1], 0)\r\n}\r\n\r\nfunction normalizeProbabilities(entries: Entry[], total: number) {\r\n return entries.map(([k, v]) => [k, Math.round((v / total) * 100)] as Entry)\r\n}\r\n\r\nfunction prepareEntries(entries: Entry[]) {\r\n const filtered = filterNumbers(entries)\r\n if (filtered.length === 0) return\r\n const sorted = sortEntries(filtered)\r\n const sum = sumProbabilities(sorted)\r\n if (sum === 0) return\r\n if (sum === 100) return sorted\r\n return normalizeProbabilities(sorted, sum)\r\n}\r\n\r\nfunction random(min: number, max: number) {\r\n return Math.random() * (max - min) + min\r\n}\r\n\r\nfunction chooseOne(entries: Entry[]) {\r\n const num = random(1, 100)\r\n let count = 0\r\n for (const entry of entries) {\r\n count += entry[1]\r\n if (num <= count) return entry[0]\r\n }\r\n return entries[entries.length - 1]![0]\r\n}\r\n\r\nfunction probabilityPicker(map: ProbabilityMap): string | null | undefined {\r\n if (!(map instanceof Object)) return null\r\n const entries = Object.entries(map) as Entry[]\r\n if (entries.length === 0) return undefined\r\n const first = entries[0]\r\n if (first && entries.length === 1) return first[0]\r\n const prepared = prepareEntries(entries)\r\n if (!prepared) return undefined\r\n return chooseOne(prepared)\r\n}\r\n\r\nexport default probabilityPicker;"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["type ProbabilityMap = Record<string, number>\r\ntype Entry = [string, number]\r\n\r\nfunction filterNumbers(entries: Entry[]) {\r\n return entries.filter(e => typeof e[1] === 'number' && !Number.isNaN(e[1]))\r\n}\r\n\r\nfunction sortEntries(entries: Entry[]) {\r\n return entries.sort((a, b) => a[1] - b[1])\r\n}\r\n\r\nfunction sumProbabilities(entries: Entry[]) {\r\n return entries.reduce((acc, e) => acc + e[1], 0)\r\n}\r\n\r\nfunction normalizeProbabilities(entries: Entry[], total: number) {\r\n return entries.map(([k, v]) => [k, Math.round((v / total) * 100)] as Entry)\r\n}\r\n\r\nfunction prepareEntries(entries: Entry[]) {\r\n const filtered = filterNumbers(entries)\r\n if (filtered.length === 0) return\r\n const sorted = sortEntries(filtered)\r\n const sum = sumProbabilities(sorted)\r\n if (sum === 0) return\r\n if (sum === 100) return sorted\r\n return normalizeProbabilities(sorted, sum)\r\n}\r\n\r\nfunction secureRandom(): number {\r\n if (typeof globalThis.crypto === 'undefined' || typeof globalThis.crypto.getRandomValues !== 'function') {\r\n return Math.random()\r\n }\r\n const array = new Uint32Array(1)\r\n globalThis.crypto.getRandomValues(array)\r\n return array[0]! / 0x100000000\r\n}\r\n\r\nfunction random(min: number, max: number) {\r\n return secureRandom() * (max - min) + min\r\n}\r\n\r\nfunction chooseOne(entries: Entry[]) {\r\n const num = random(1, 100)\r\n let count = 0\r\n for (const entry of entries) {\r\n count += entry[1]\r\n if (num <= count) return entry[0]\r\n }\r\n return entries[entries.length - 1]![0]\r\n}\r\n\r\nfunction probabilityPicker(map: ProbabilityMap): string | null | undefined {\r\n if (!(map instanceof Object)) return null\r\n const entries = Object.entries(map) as Entry[]\r\n if (entries.length === 0) return undefined\r\n const first = entries[0]\r\n if (first && entries.length === 1) return first[0]\r\n const prepared = prepareEntries(entries)\r\n if (!prepared) return undefined\r\n return chooseOne(prepared)\r\n}\r\n\r\nexport default probabilityPicker;"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "probability-picker",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "A lightweight library for selecting random values based on weighted probabilities.",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",