tiny-essentials 1.27.1 → 1.28.1
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/README.md +1 -0
- package/changelog/1/28/0.md +16 -0
- package/changelog/1/28/1.md +23 -0
- package/dist/v1/TinyAdvancedRaffle.min.js +1 -1
- package/dist/v1/TinyAfterScrollWatcher.min.js +1 -1
- package/dist/v1/TinyAnalogClock.min.js +1 -1
- package/dist/v1/TinyBasicsEs.min.js +1 -2
- package/dist/v1/TinyDayNightCycle.min.js +1 -1
- package/dist/v1/TinyDragDropDetector.min.js +1 -1
- package/dist/v1/TinyDragger.min.js +1 -1
- package/dist/v1/TinyElementObserver.min.js +1 -1
- package/dist/v1/TinyEssentials.min.js +1 -2
- package/dist/v1/TinyGamepad.min.js +1 -1
- package/dist/v1/TinyHtml.min.js +1 -1
- package/dist/v1/TinyI18.min.js +1 -1
- package/dist/v1/TinyIframeEvents.min.js +1 -1
- package/dist/v1/TinyLocalStorage.min.js +1 -1
- package/dist/v1/TinyMediaPlayer.min.js +1 -1
- package/dist/v1/TinyNewWinEvents.min.js +1 -1
- package/dist/v1/TinyNotifyCenter.min.js +1 -1
- package/dist/v1/TinyRadioFm.min.js +1 -1
- package/dist/v1/TinyRateLimiter.min.js +1 -1
- package/dist/v1/TinySmartScroller.min.js +1 -1
- package/dist/v1/TinyTextDiffer.min.js +1 -1
- package/dist/v1/TinyTextarea.min.js +1 -1
- package/dist/v1/TinyTimeout.min.js +1 -1
- package/dist/v1/TinyToastNotify.min.js +1 -1
- package/dist/v1/TinyUploadClicker.min.js +1 -2
- package/dist/v1/UltraRandomMsgGen.min.js +1 -1
- package/dist/v1/basics/array.cjs +57 -9
- package/dist/v1/basics/array.d.mts +27 -11
- package/dist/v1/basics/array.mjs +51 -9
- package/dist/v1/basics/clock.cjs +94 -42
- package/dist/v1/basics/clock.d.mts +10 -10
- package/dist/v1/basics/clock.mjs +91 -54
- package/dist/v1/basics/deprecated/html.cjs +246 -0
- package/dist/v1/basics/deprecated/html.d.mts +63 -0
- package/dist/v1/basics/deprecated/html.mjs +190 -0
- package/dist/v1/basics/extendObjType/Buffer.cjs +13 -0
- package/dist/v1/basics/extendObjType/Buffer.d.mts +4 -0
- package/dist/v1/basics/extendObjType/Buffer.mjs +8 -0
- package/dist/v1/basics/html.cjs +149 -130
- package/dist/v1/basics/html.d.mts +26 -61
- package/dist/v1/basics/html.mjs +113 -105
- package/dist/v1/basics/index.cjs +2 -0
- package/dist/v1/basics/index.d.mts +3 -1
- package/dist/v1/basics/index.mjs +3 -3
- package/dist/v1/basics/mediaContent.cjs +51 -9
- package/dist/v1/basics/mediaContent.d.mts +0 -87
- package/dist/v1/basics/mediaContent.mjs +40 -10
- package/dist/v1/basics/objChecker.cjs +7 -5
- package/dist/v1/basics/objChecker.d.mts +3 -2
- package/dist/v1/basics/objChecker.mjs +6 -6
- package/dist/v1/basics/objFilter.cjs +40 -18
- package/dist/v1/basics/objFilter.d.mts +6 -6
- package/dist/v1/basics/objFilter.mjs +32 -17
- package/dist/v1/basics/simpleMath.cjs +81 -25
- package/dist/v1/basics/simpleMath.d.mts +2 -2
- package/dist/v1/basics/simpleMath.mjs +70 -27
- package/dist/v1/basics/text.cjs +76 -31
- package/dist/v1/basics/text.d.mts +69 -7
- package/dist/v1/basics/text.mjs +62 -31
- package/dist/v1/index.cjs +4 -2
- package/dist/v1/index.d.mts +4 -2
- package/dist/v1/index.mjs +4 -4
- package/dist/v1/libs/TinyAdvancedRaffle.cjs +71 -255
- package/dist/v1/libs/TinyAdvancedRaffle.d.mts +6 -134
- package/dist/v1/libs/TinyAdvancedRaffle.mjs +69 -228
- package/dist/v1/libs/TinyAfterScrollWatcher.cjs +17 -1
- package/dist/v1/libs/TinyAfterScrollWatcher.d.mts +4 -1
- package/dist/v1/libs/TinyAfterScrollWatcher.mjs +15 -1
- package/dist/v1/libs/TinyAnalogClock.cjs +60 -0
- package/dist/v1/libs/TinyAnalogClock.d.mts +6 -0
- package/dist/v1/libs/TinyAnalogClock.mjs +57 -0
- package/dist/v1/libs/TinyClipboard.cjs +2 -0
- package/dist/v1/libs/TinyClipboard.d.mts +4 -2
- package/dist/v1/libs/TinyClipboard.mjs +2 -0
- package/dist/v1/libs/TinyColorConverter.cjs +1 -0
- package/dist/v1/libs/TinyColorConverter.d.mts +2 -1
- package/dist/v1/libs/TinyColorConverter.mjs +1 -0
- package/dist/v1/libs/TinyDayNightCycle.cjs +67 -42
- package/dist/v1/libs/TinyDayNightCycle.d.mts +2 -7
- package/dist/v1/libs/TinyDayNightCycle.mjs +65 -41
- package/dist/v1/libs/TinyDragDropDetector.cjs +25 -0
- package/dist/v1/libs/TinyDragDropDetector.d.mts +6 -0
- package/dist/v1/libs/TinyDragDropDetector.mjs +22 -0
- package/dist/v1/libs/TinyDragger.cjs +46 -19
- package/dist/v1/libs/TinyDragger.mjs +45 -18
- package/dist/v1/libs/TinyElementObserver.cjs +39 -0
- package/dist/v1/libs/TinyElementObserver.d.mts +6 -0
- package/dist/v1/libs/TinyElementObserver.mjs +36 -0
- package/dist/v1/libs/TinyGamepad.cjs +131 -1
- package/dist/v1/libs/TinyGamepad.mjs +129 -1
- package/dist/v1/libs/TinyHtml.cjs +1 -1
- package/dist/v1/libs/TinyHtml.mjs +2 -2
- package/dist/v1/libs/TinyI18.cjs +61 -0
- package/dist/v1/libs/TinyI18.d.mts +14 -0
- package/dist/v1/libs/TinyI18.mjs +55 -0
- package/dist/v1/libs/TinyIframeEvents.cjs +26 -196
- package/dist/v1/libs/TinyIframeEvents.d.mts +3 -122
- package/dist/v1/libs/TinyIframeEvents.mjs +26 -171
- package/dist/v1/libs/TinyLocalStorage.cjs +53 -205
- package/dist/v1/libs/TinyLocalStorage.d.mts +6 -127
- package/dist/v1/libs/TinyLocalStorage.mjs +50 -178
- package/dist/v1/libs/TinyMediaPlayer.cjs +74 -2
- package/dist/v1/libs/TinyMediaPlayer.d.mts +12 -2
- package/dist/v1/libs/TinyMediaPlayer.mjs +68 -2
- package/dist/v1/libs/TinyNewWinEvents.cjs +39 -197
- package/dist/v1/libs/TinyNewWinEvents.d.mts +6 -119
- package/dist/v1/libs/TinyNewWinEvents.mjs +36 -172
- package/dist/v1/libs/TinyNotifyCenter.cjs +36 -0
- package/dist/v1/libs/TinyNotifyCenter.d.mts +6 -0
- package/dist/v1/libs/TinyNotifyCenter.mjs +32 -0
- package/dist/v1/libs/TinyRadioFm.cjs +40 -3
- package/dist/v1/libs/TinyRadioFm.d.mts +3 -3
- package/dist/v1/libs/TinyRadioFm.mjs +37 -3
- package/dist/v1/libs/TinyRateLimiter.cjs +52 -0
- package/dist/v1/libs/TinyRateLimiter.d.mts +6 -0
- package/dist/v1/libs/TinyRateLimiter.mjs +48 -0
- package/dist/v1/libs/TinySmartScroller.cjs +56 -205
- package/dist/v1/libs/TinySmartScroller.d.mts +19 -152
- package/dist/v1/libs/TinySmartScroller.mjs +55 -181
- package/dist/v1/libs/TinyTextDiffer.cjs +19 -18
- package/dist/v1/libs/TinyTextDiffer.d.mts +1 -0
- package/dist/v1/libs/TinyTextDiffer.mjs +16 -17
- package/dist/v1/libs/TinyTextarea.cjs +19 -0
- package/dist/v1/libs/TinyTextarea.d.mts +6 -0
- package/dist/v1/libs/TinyTextarea.mjs +17 -0
- package/dist/v1/libs/TinyTimeout.cjs +11 -1
- package/dist/v1/libs/TinyTimeout.mjs +9 -1
- package/dist/v1/libs/TinyToastNotify.cjs +35 -0
- package/dist/v1/libs/TinyToastNotify.d.mts +6 -0
- package/dist/v1/libs/TinyToastNotify.mjs +31 -0
- package/dist/v1/libs/TinyUploadClicker.cjs +20 -0
- package/dist/v1/libs/TinyUploadClicker.d.mts +6 -0
- package/dist/v1/libs/TinyUploadClicker.mjs +17 -0
- package/dist/v1/libs/UltraRandomMsgGen.cjs +148 -35
- package/dist/v1/libs/UltraRandomMsgGen.d.mts +17 -3
- package/dist/v1/libs/UltraRandomMsgGen.mjs +133 -34
- package/dist/v1/libs/utils.cjs +21 -0
- package/dist/v1/libs/utils.d.mts +2 -0
- package/dist/v1/libs/utils.mjs +16 -0
- package/docs/v1/Exports.md +0 -1
- package/docs/v1/README.md +1 -1
- package/docs/v1/basics/array.md +2 -2
- package/docs/v1/basics/deprecated/html.md +17 -0
- package/docs/v1/basics/fullScreen.md +1 -1
- package/docs/v1/basics/html.md +12 -26
- package/docs/v1/basics/mediaContent.md +1 -1
- package/docs/v1/basics/objChecker.md +1 -1
- package/docs/v1/basics/objFilter.md +1 -1
- package/docs/v1/basics/text.md +2 -2
- package/docs/v1/fileManager/main.md +1 -1
- package/docs/v1/libs/ColorSafeStringify.md +1 -1
- package/docs/v1/libs/TinyAfterScrollWatcher.md +1 -1
- package/docs/v1/libs/TinyAnalogClock.md +1 -1
- package/docs/v1/libs/TinyArrayComparator.md +1 -1
- package/docs/v1/libs/TinyArrayPaginator.md +1 -1
- package/docs/v1/libs/TinyClassManager/TinyPluginInliner.md +2 -2
- package/docs/v1/libs/TinyClassManager.md +1 -1
- package/docs/v1/libs/TinyClipboard.md +1 -1
- package/docs/v1/libs/TinyCookieConsent.md +1 -1
- package/docs/v1/libs/TinyDomReadyManager.md +1 -1
- package/docs/v1/libs/TinyDragDropDetector.md +1 -1
- package/docs/v1/libs/TinyDragger.md +1 -1
- package/docs/v1/libs/TinyElementObserver.md +1 -1
- package/docs/v1/libs/TinyHtml.md +1 -1
- package/docs/v1/libs/TinyIframeEvents.md +10 -10
- package/docs/v1/libs/TinyLevelUp.md +1 -1
- package/docs/v1/libs/TinyLoadingScreen.md +1 -1
- package/docs/v1/libs/TinyLocalStorage.md +3 -3
- package/docs/v1/libs/TinyNewWinEvents.md +10 -11
- package/docs/v1/libs/TinyNotifications.md +1 -1
- package/docs/v1/libs/TinyPromiseQueue.md +2 -2
- package/docs/v1/libs/TinyTextDiffer.md +1 -1
- package/docs/v1/libs/TinyTextarea.md +1 -1
- package/package.json +15 -5
- package/dist/v1/TinyBasicsEs.min.js.LICENSE.txt +0 -8
- package/dist/v1/TinyEssentials.min.js.LICENSE.txt +0 -8
- package/dist/v1/TinyEvents.min.js +0 -1
- package/dist/v1/TinyUploadClicker.min.js.LICENSE.txt +0 -8
- package/dist/v1/build/TinyEvents.cjs +0 -7
- package/dist/v1/build/TinyEvents.d.mts +0 -3
- package/dist/v1/build/TinyEvents.mjs +0 -2
- package/dist/v1/libs/TinyEvents.cjs +0 -395
- package/dist/v1/libs/TinyEvents.d.mts +0 -164
- package/dist/v1/libs/TinyEvents.mjs +0 -360
- package/docs/v1/libs/TinyEvents.md +0 -187
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import { createCheckDestroyed } from './utils.mjs';
|
|
3
|
+
const checkDestroy = createCheckDestroyed('TinyAdvancedRaffle');
|
|
2
4
|
/**
|
|
3
5
|
* Defines the available normalization strategies for probability weight calculations.
|
|
4
6
|
* @typedef {'relative' | 'softmax'} Normalization
|
|
@@ -101,180 +103,7 @@ import TinyEvents from './TinyEvents.mjs';
|
|
|
101
103
|
*
|
|
102
104
|
* @class
|
|
103
105
|
*/
|
|
104
|
-
class TinyAdvancedRaffle {
|
|
105
|
-
#events = new TinyEvents();
|
|
106
|
-
/**
|
|
107
|
-
* Emits an event, triggering all registered handlers for that event.
|
|
108
|
-
*
|
|
109
|
-
* @param {string|string[]} event - The event name to emit.
|
|
110
|
-
* @param {...any} payload - Optional data to pass to each handler.
|
|
111
|
-
* @returns {boolean[]} True if any listeners were called, false otherwise.
|
|
112
|
-
*/
|
|
113
|
-
#emit(event, ...payload) {
|
|
114
|
-
return this.#events.emit(event, ...payload);
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Enables or disables throwing an error when the maximum number of listeners is exceeded.
|
|
118
|
-
*
|
|
119
|
-
* @param {boolean} shouldThrow - If true, an error will be thrown when the max is exceeded.
|
|
120
|
-
*/
|
|
121
|
-
setThrowOnMaxListeners(shouldThrow) {
|
|
122
|
-
return this.#events.setThrowOnMaxListeners(shouldThrow);
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Checks whether an error will be thrown when the max listener limit is exceeded.
|
|
126
|
-
*
|
|
127
|
-
* @returns {boolean} True if an error will be thrown, false if only a warning is shown.
|
|
128
|
-
*/
|
|
129
|
-
getThrowOnMaxListeners() {
|
|
130
|
-
return this.#events.getThrowOnMaxListeners();
|
|
131
|
-
}
|
|
132
|
-
/////////////////////////////////////////////////////////////
|
|
133
|
-
/**
|
|
134
|
-
* Adds a listener to the beginning of the listeners array for the specified event.
|
|
135
|
-
*
|
|
136
|
-
* @param {string|string[]} event - Event name.
|
|
137
|
-
* @param {handler} handler - The callback function.
|
|
138
|
-
*/
|
|
139
|
-
prependListener(event, handler) {
|
|
140
|
-
return this.#events.prependListener(event, handler);
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Adds a one-time listener to the beginning of the listeners array for the specified event.
|
|
144
|
-
*
|
|
145
|
-
* @param {string|string[]} event - Event name.
|
|
146
|
-
* @param {handler} handler - The callback function.
|
|
147
|
-
* @returns {handler[]} - The wrapped handler used internally.
|
|
148
|
-
*/
|
|
149
|
-
prependListenerOnce(event, handler) {
|
|
150
|
-
return this.#events.prependListenerOnce(event, handler);
|
|
151
|
-
}
|
|
152
|
-
//////////////////////////////////////////////////////////////////////
|
|
153
|
-
/**
|
|
154
|
-
* Adds a event listener.
|
|
155
|
-
*
|
|
156
|
-
* @param {string|string[]} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
|
|
157
|
-
* @param {handler} handler - Callback function to be called when event fires.
|
|
158
|
-
*/
|
|
159
|
-
appendListener(event, handler) {
|
|
160
|
-
return this.#events.appendListener(event, handler);
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Registers an event listener that runs only once, then is removed.
|
|
164
|
-
*
|
|
165
|
-
* @param {string|string[]} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
|
|
166
|
-
* @param {handler} handler - The callback function to run on event.
|
|
167
|
-
* @returns {handler[]} - The wrapped version of the handler.
|
|
168
|
-
*/
|
|
169
|
-
appendListenerOnce(event, handler) {
|
|
170
|
-
return this.#events.appendListenerOnce(event, handler);
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* Adds a event listener.
|
|
174
|
-
*
|
|
175
|
-
* @param {string|string[]} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
|
|
176
|
-
* @param {handler} handler - Callback function to be called when event fires.
|
|
177
|
-
*/
|
|
178
|
-
on(event, handler) {
|
|
179
|
-
return this.#events.on(event, handler);
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Registers an event listener that runs only once, then is removed.
|
|
183
|
-
*
|
|
184
|
-
* @param {string|string[]} event - Event name, such as 'onScrollBoundary' or 'onAutoScroll'.
|
|
185
|
-
* @param {handler} handler - The callback function to run on event.
|
|
186
|
-
* @returns {handler[]} - The wrapped version of the handler.
|
|
187
|
-
*/
|
|
188
|
-
once(event, handler) {
|
|
189
|
-
return this.#events.once(event, handler);
|
|
190
|
-
}
|
|
191
|
-
////////////////////////////////////////////////////////////////////
|
|
192
|
-
/**
|
|
193
|
-
* Removes a previously registered event listener.
|
|
194
|
-
*
|
|
195
|
-
* @param {string|string[]} event - The name of the event to remove the handler from.
|
|
196
|
-
* @param {handler} handler - The specific callback function to remove.
|
|
197
|
-
*/
|
|
198
|
-
off(event, handler) {
|
|
199
|
-
return this.#events.off(event, handler);
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* Removes all event listeners of a specific type from the element.
|
|
203
|
-
*
|
|
204
|
-
* @param {string|string[]} event - The event type to remove (e.g. 'onScrollBoundary').
|
|
205
|
-
*/
|
|
206
|
-
offAll(event) {
|
|
207
|
-
return this.#events.offAll(event);
|
|
208
|
-
}
|
|
209
|
-
/**
|
|
210
|
-
* Removes all event listeners of all types from the element.
|
|
211
|
-
*/
|
|
212
|
-
offAllTypes() {
|
|
213
|
-
return this.#events.offAllTypes();
|
|
214
|
-
}
|
|
215
|
-
////////////////////////////////////////////////////////////
|
|
216
|
-
/**
|
|
217
|
-
* Returns the number of listeners for a given event.
|
|
218
|
-
*
|
|
219
|
-
* @param {string} event - The name of the event.
|
|
220
|
-
* @returns {number} Number of listeners for the event.
|
|
221
|
-
*/
|
|
222
|
-
listenerCount(event) {
|
|
223
|
-
return this.#events.listenerCount(event);
|
|
224
|
-
}
|
|
225
|
-
/**
|
|
226
|
-
* Returns a copy of the array of listeners for the specified event.
|
|
227
|
-
*
|
|
228
|
-
* @param {string} event - The name of the event.
|
|
229
|
-
* @returns {handler[]} Array of listener functions.
|
|
230
|
-
*/
|
|
231
|
-
listeners(event) {
|
|
232
|
-
return this.#events.listeners(event);
|
|
233
|
-
}
|
|
234
|
-
/**
|
|
235
|
-
* Returns a copy of the array of listeners for the specified event.
|
|
236
|
-
*
|
|
237
|
-
* @param {string} event - The name of the event.
|
|
238
|
-
* @returns {handler[]} Array of listener functions.
|
|
239
|
-
*/
|
|
240
|
-
onceListeners(event) {
|
|
241
|
-
return this.#events.onceListeners(event);
|
|
242
|
-
}
|
|
243
|
-
/**
|
|
244
|
-
* Returns a copy of the internal listeners array for the specified event,
|
|
245
|
-
* including wrapper functions like those used by `.once()`.
|
|
246
|
-
* @param {string | symbol} event - The event name.
|
|
247
|
-
* @returns {handler[]} An array of raw listener functions.
|
|
248
|
-
*/
|
|
249
|
-
allListeners(event) {
|
|
250
|
-
return this.#events.allListeners(event);
|
|
251
|
-
}
|
|
252
|
-
/**
|
|
253
|
-
* Returns an array of event names for which there are registered listeners.
|
|
254
|
-
*
|
|
255
|
-
* @returns {string[]} Array of registered event names.
|
|
256
|
-
*/
|
|
257
|
-
eventNames() {
|
|
258
|
-
return this.#events.eventNames();
|
|
259
|
-
}
|
|
260
|
-
//////////////////////////////////////////////////////
|
|
261
|
-
/**
|
|
262
|
-
* Sets the maximum number of listeners per event before a warning is shown.
|
|
263
|
-
*
|
|
264
|
-
* @param {number} n - The maximum number of listeners.
|
|
265
|
-
*/
|
|
266
|
-
setMaxListeners(n) {
|
|
267
|
-
return this.#events.setMaxListeners(n);
|
|
268
|
-
}
|
|
269
|
-
/**
|
|
270
|
-
* Gets the maximum number of listeners allowed per event.
|
|
271
|
-
*
|
|
272
|
-
* @returns {number} The maximum number of listeners.
|
|
273
|
-
*/
|
|
274
|
-
getMaxListeners() {
|
|
275
|
-
return this.#events.getMaxListeners();
|
|
276
|
-
}
|
|
277
|
-
///////////////////////////////////////////////////
|
|
106
|
+
class TinyAdvancedRaffle extends EventEmitter {
|
|
278
107
|
/**
|
|
279
108
|
* Whether this instance has been destroyed.
|
|
280
109
|
* @type {boolean}
|
|
@@ -358,6 +187,7 @@ class TinyAdvancedRaffle {
|
|
|
358
187
|
* @returns {Record<string, number>} - Object with item IDs as keys and their respective draw counts.
|
|
359
188
|
*/
|
|
360
189
|
get freq() {
|
|
190
|
+
checkDestroy(this.#isDestroyed);
|
|
361
191
|
return Object.fromEntries(this.#freq);
|
|
362
192
|
}
|
|
363
193
|
/**
|
|
@@ -365,6 +195,7 @@ class TinyAdvancedRaffle {
|
|
|
365
195
|
* @returns {number} Total count of items.
|
|
366
196
|
*/
|
|
367
197
|
get size() {
|
|
198
|
+
checkDestroy(this.#isDestroyed);
|
|
368
199
|
return this.#items.size;
|
|
369
200
|
}
|
|
370
201
|
/**
|
|
@@ -372,6 +203,7 @@ class TinyAdvancedRaffle {
|
|
|
372
203
|
* @returns {Normalization} Current normalization mode.
|
|
373
204
|
*/
|
|
374
205
|
get normalization() {
|
|
206
|
+
checkDestroy(this.#isDestroyed);
|
|
375
207
|
return this.#normalization;
|
|
376
208
|
}
|
|
377
209
|
/**
|
|
@@ -380,7 +212,7 @@ class TinyAdvancedRaffle {
|
|
|
380
212
|
* @throws {TypeError} If value is not a non-empty string.
|
|
381
213
|
*/
|
|
382
214
|
set normalization(value) {
|
|
383
|
-
this
|
|
215
|
+
checkDestroy(this.#isDestroyed);
|
|
384
216
|
if (typeof value !== 'string' || !value.trim()) {
|
|
385
217
|
throw new TypeError("normalization must be a non-empty string (e.g., 'relative', 'softmax').");
|
|
386
218
|
}
|
|
@@ -391,6 +223,7 @@ class TinyAdvancedRaffle {
|
|
|
391
223
|
* @returns {number|null} Current seed or `null` if RNG is not seeded.
|
|
392
224
|
*/
|
|
393
225
|
get seed() {
|
|
226
|
+
checkDestroy(this.#isDestroyed);
|
|
394
227
|
return this.#seed;
|
|
395
228
|
}
|
|
396
229
|
/**
|
|
@@ -399,7 +232,7 @@ class TinyAdvancedRaffle {
|
|
|
399
232
|
* @throws {TypeError} If not `null` or a finite number.
|
|
400
233
|
*/
|
|
401
234
|
set seed(value) {
|
|
402
|
-
this
|
|
235
|
+
checkDestroy(this.#isDestroyed);
|
|
403
236
|
if (value !== null && (typeof value !== 'number' || !Number.isFinite(value)))
|
|
404
237
|
throw new TypeError('seed must be a finite number or null.');
|
|
405
238
|
this.#seed = value;
|
|
@@ -411,6 +244,7 @@ class TinyAdvancedRaffle {
|
|
|
411
244
|
* @returns {WeightsCallback[]} Array of registered global modifier functions.
|
|
412
245
|
*/
|
|
413
246
|
get globalModifiers() {
|
|
247
|
+
checkDestroy(this.#isDestroyed);
|
|
414
248
|
return [...this.#globalModifiers];
|
|
415
249
|
}
|
|
416
250
|
/**
|
|
@@ -419,7 +253,7 @@ class TinyAdvancedRaffle {
|
|
|
419
253
|
* @throws {TypeError} If not an array of functions.
|
|
420
254
|
*/
|
|
421
255
|
set globalModifiers(value) {
|
|
422
|
-
this
|
|
256
|
+
checkDestroy(this.#isDestroyed);
|
|
423
257
|
if (!Array.isArray(value) || !value.every((fn) => typeof fn === 'function'))
|
|
424
258
|
throw new TypeError('globalModifiers must be an array of functions (WeightsCallback).');
|
|
425
259
|
this.#globalModifiers = value;
|
|
@@ -429,6 +263,7 @@ class TinyAdvancedRaffle {
|
|
|
429
263
|
* @returns {TempModifier[]} Array of temporary modifier entries.
|
|
430
264
|
*/
|
|
431
265
|
get temporaryModifiers() {
|
|
266
|
+
checkDestroy(this.#isDestroyed);
|
|
432
267
|
return [...this.#temporaryModifiers];
|
|
433
268
|
}
|
|
434
269
|
/**
|
|
@@ -437,7 +272,7 @@ class TinyAdvancedRaffle {
|
|
|
437
272
|
* @throws {TypeError} If structure is invalid.
|
|
438
273
|
*/
|
|
439
274
|
set temporaryModifiers(value) {
|
|
440
|
-
this
|
|
275
|
+
checkDestroy(this.#isDestroyed);
|
|
441
276
|
if (!Array.isArray(value) ||
|
|
442
277
|
!value.every((obj) => obj && typeof obj.fn === 'function' && Number.isInteger(obj.uses) && obj.uses > 0))
|
|
443
278
|
throw new TypeError('temporaryModifiers must be an array of objects { fn: function, uses: positive integer }.');
|
|
@@ -448,6 +283,7 @@ class TinyAdvancedRaffle {
|
|
|
448
283
|
* @returns {WeightsCallback[]} Array of conditional rule functions.
|
|
449
284
|
*/
|
|
450
285
|
get conditionalRules() {
|
|
286
|
+
checkDestroy(this.#isDestroyed);
|
|
451
287
|
return [...this.#conditionalRules];
|
|
452
288
|
}
|
|
453
289
|
/**
|
|
@@ -456,7 +292,7 @@ class TinyAdvancedRaffle {
|
|
|
456
292
|
* @throws {TypeError} If not an array of functions.
|
|
457
293
|
*/
|
|
458
294
|
set conditionalRules(value) {
|
|
459
|
-
this
|
|
295
|
+
checkDestroy(this.#isDestroyed);
|
|
460
296
|
if (!Array.isArray(value) || !value.every((fn) => typeof fn === 'function'))
|
|
461
297
|
throw new TypeError('conditionalRules must be an array of functions (WeightsCallback).');
|
|
462
298
|
this.#conditionalRules = value;
|
|
@@ -466,6 +302,7 @@ class TinyAdvancedRaffle {
|
|
|
466
302
|
* @returns {Record<string, Pity>} Object keyed by system name.
|
|
467
303
|
*/
|
|
468
304
|
get pitySystems() {
|
|
305
|
+
checkDestroy(this.#isDestroyed);
|
|
469
306
|
return Object.fromEntries(this.#pitySystems);
|
|
470
307
|
}
|
|
471
308
|
/**
|
|
@@ -474,7 +311,7 @@ class TinyAdvancedRaffle {
|
|
|
474
311
|
* @throws {TypeError} If structure is invalid.
|
|
475
312
|
*/
|
|
476
313
|
set pitySystems(value) {
|
|
477
|
-
this
|
|
314
|
+
checkDestroy(this.#isDestroyed);
|
|
478
315
|
if (!(value instanceof Map) ||
|
|
479
316
|
![...value.values()].every((p) => p &&
|
|
480
317
|
typeof p.threshold === 'number' &&
|
|
@@ -490,6 +327,7 @@ class TinyAdvancedRaffle {
|
|
|
490
327
|
* @returns {string[]} Array of item IDs excluded from draws.
|
|
491
328
|
*/
|
|
492
329
|
get exclusions() {
|
|
330
|
+
checkDestroy(this.#isDestroyed);
|
|
493
331
|
return Array.from(this.#exclusions);
|
|
494
332
|
}
|
|
495
333
|
/**
|
|
@@ -498,7 +336,7 @@ class TinyAdvancedRaffle {
|
|
|
498
336
|
* @throws {TypeError} If not a Set of strings.
|
|
499
337
|
*/
|
|
500
338
|
set exclusions(value) {
|
|
501
|
-
this
|
|
339
|
+
checkDestroy(this.#isDestroyed);
|
|
502
340
|
if (!(value instanceof Set) || ![...value].every((v) => typeof v === 'string'))
|
|
503
341
|
throw new TypeError('exclusions must be a Set<string>.');
|
|
504
342
|
this.#exclusions = value;
|
|
@@ -508,6 +346,7 @@ class TinyAdvancedRaffle {
|
|
|
508
346
|
* @returns {Record<string, string[]>} Object where each key is a group name and value is an array of item IDs.
|
|
509
347
|
*/
|
|
510
348
|
get groups() {
|
|
349
|
+
checkDestroy(this.#isDestroyed);
|
|
511
350
|
/** @type {Record<string, string[]>} */
|
|
512
351
|
const groups = {};
|
|
513
352
|
this.#groups.forEach((value, key) => (groups[key] = Array.from(value)));
|
|
@@ -519,7 +358,7 @@ class TinyAdvancedRaffle {
|
|
|
519
358
|
* @throws {TypeError} If not a valid Map<string, Set<string>>.
|
|
520
359
|
*/
|
|
521
360
|
set groups(value) {
|
|
522
|
-
this
|
|
361
|
+
checkDestroy(this.#isDestroyed);
|
|
523
362
|
if (!(value instanceof Map) ||
|
|
524
363
|
![...value.values()].every((v) => v instanceof Set && [...v].every((i) => typeof i === 'string')))
|
|
525
364
|
throw new TypeError('groups must be a Map<string, Set<string>>.');
|
|
@@ -530,6 +369,7 @@ class TinyAdvancedRaffle {
|
|
|
530
369
|
* @returns {RngGenerator} Function returning a floating-point number in [0, 1).
|
|
531
370
|
*/
|
|
532
371
|
get rng() {
|
|
372
|
+
checkDestroy(this.#isDestroyed);
|
|
533
373
|
return this.#rng;
|
|
534
374
|
}
|
|
535
375
|
/**
|
|
@@ -538,7 +378,7 @@ class TinyAdvancedRaffle {
|
|
|
538
378
|
* @throws {TypeError} If not a valid function.
|
|
539
379
|
*/
|
|
540
380
|
set rng(value) {
|
|
541
|
-
this
|
|
381
|
+
checkDestroy(this.#isDestroyed);
|
|
542
382
|
if (typeof value !== 'function' || typeof value() !== 'number')
|
|
543
383
|
throw new TypeError('rng must be a function returning a number (RngGenerator).');
|
|
544
384
|
this.#rng = value;
|
|
@@ -548,6 +388,7 @@ class TinyAdvancedRaffle {
|
|
|
548
388
|
* @returns {Record<string, ItemDataGetter>} Object keyed by item ID.
|
|
549
389
|
*/
|
|
550
390
|
get items() {
|
|
391
|
+
checkDestroy(this.#isDestroyed);
|
|
551
392
|
/** @type {Record<string, ItemDataGetter>} */
|
|
552
393
|
const items = {};
|
|
553
394
|
this.#items.forEach((value, key) => {
|
|
@@ -561,7 +402,7 @@ class TinyAdvancedRaffle {
|
|
|
561
402
|
* @throws {TypeError} If structure is invalid.
|
|
562
403
|
*/
|
|
563
404
|
set items(value) {
|
|
564
|
-
this
|
|
405
|
+
checkDestroy(this.#isDestroyed);
|
|
565
406
|
if (!(value instanceof Map) ||
|
|
566
407
|
![...value.values()].every((item) => item &&
|
|
567
408
|
typeof item.id === 'string' &&
|
|
@@ -582,6 +423,7 @@ class TinyAdvancedRaffle {
|
|
|
582
423
|
* @param {Normalization} [opts.normalization='relative'] - Probability normalization mode.
|
|
583
424
|
*/
|
|
584
425
|
constructor(opts = {}) {
|
|
426
|
+
super();
|
|
585
427
|
const { rng = null, seed = null, normalization = 'relative' } = opts;
|
|
586
428
|
this.#normalization = normalization;
|
|
587
429
|
this.#seed = seed;
|
|
@@ -593,15 +435,6 @@ class TinyAdvancedRaffle {
|
|
|
593
435
|
this.#rng = Math.random;
|
|
594
436
|
this.#seed = seed ?? null;
|
|
595
437
|
}
|
|
596
|
-
/**
|
|
597
|
-
* Checks if the instance has been destroyed and throws an error if so.
|
|
598
|
-
* @private
|
|
599
|
-
* @throws {Error} If the instance has already been destroyed.
|
|
600
|
-
*/
|
|
601
|
-
_checkDestroyed() {
|
|
602
|
-
if (this.#isDestroyed)
|
|
603
|
-
throw new Error('This instance has been destroyed and can no longer be used.');
|
|
604
|
-
}
|
|
605
438
|
/* ===========================
|
|
606
439
|
Public: Item management
|
|
607
440
|
=========================== */
|
|
@@ -612,6 +445,7 @@ class TinyAdvancedRaffle {
|
|
|
612
445
|
* @throws {TypeError} If `itemId` is not a string.
|
|
613
446
|
*/
|
|
614
447
|
hasItem(itemId) {
|
|
448
|
+
checkDestroy(this.#isDestroyed);
|
|
615
449
|
if (typeof itemId !== 'string')
|
|
616
450
|
throw new TypeError('itemId must be a string');
|
|
617
451
|
return this.#items.has(itemId);
|
|
@@ -628,7 +462,7 @@ class TinyAdvancedRaffle {
|
|
|
628
462
|
* @throws {TypeError} If any parameter has an invalid type.
|
|
629
463
|
*/
|
|
630
464
|
addItem(id, opts = {}) {
|
|
631
|
-
this
|
|
465
|
+
checkDestroy(this.#isDestroyed);
|
|
632
466
|
if (typeof id !== 'string' || !id.trim())
|
|
633
467
|
throw new TypeError('id must be a non-empty string');
|
|
634
468
|
if (typeof opts !== 'object' || opts === null)
|
|
@@ -661,7 +495,7 @@ class TinyAdvancedRaffle {
|
|
|
661
495
|
// Register in groups map
|
|
662
496
|
for (const g of groups)
|
|
663
497
|
this._ensureGroup(g).add(id);
|
|
664
|
-
this
|
|
498
|
+
this.emit('itemAdded', entry);
|
|
665
499
|
return entry;
|
|
666
500
|
}
|
|
667
501
|
/**
|
|
@@ -671,7 +505,7 @@ class TinyAdvancedRaffle {
|
|
|
671
505
|
* @throws {TypeError} If id is not a string.
|
|
672
506
|
*/
|
|
673
507
|
removeItem(id) {
|
|
674
|
-
this
|
|
508
|
+
checkDestroy(this.#isDestroyed);
|
|
675
509
|
if (typeof id !== 'string' || !id.trim())
|
|
676
510
|
throw new TypeError('id must be a non-empty string');
|
|
677
511
|
const it = this.#items.get(id);
|
|
@@ -683,7 +517,7 @@ class TinyAdvancedRaffle {
|
|
|
683
517
|
s.delete(id);
|
|
684
518
|
}
|
|
685
519
|
this.#items.delete(id);
|
|
686
|
-
this
|
|
520
|
+
this.emit('itemRemoved', id);
|
|
687
521
|
this.resetFreq(id);
|
|
688
522
|
this.resetPity(id);
|
|
689
523
|
return true;
|
|
@@ -696,7 +530,7 @@ class TinyAdvancedRaffle {
|
|
|
696
530
|
* @throws {TypeError} If weight is invalid.
|
|
697
531
|
*/
|
|
698
532
|
setBaseWeight(id, weight) {
|
|
699
|
-
this
|
|
533
|
+
checkDestroy(this.#isDestroyed);
|
|
700
534
|
if (typeof id !== 'string' || !id.trim())
|
|
701
535
|
throw new TypeError('id must be a non-empty string');
|
|
702
536
|
if (typeof weight !== 'number' || !Number.isFinite(weight) || weight < 0)
|
|
@@ -705,7 +539,7 @@ class TinyAdvancedRaffle {
|
|
|
705
539
|
if (!it)
|
|
706
540
|
throw new Error('Item not found');
|
|
707
541
|
it.baseWeight = Math.max(0, Number(weight) || 0);
|
|
708
|
-
this
|
|
542
|
+
this.emit('weightChanged', { id, weight: it.baseWeight });
|
|
709
543
|
}
|
|
710
544
|
/**
|
|
711
545
|
* Get an item by its ID.
|
|
@@ -714,6 +548,7 @@ class TinyAdvancedRaffle {
|
|
|
714
548
|
* @throws {TypeError} If id is not a string.
|
|
715
549
|
*/
|
|
716
550
|
getItem(id) {
|
|
551
|
+
checkDestroy(this.#isDestroyed);
|
|
717
552
|
if (typeof id !== 'string' || !id.trim())
|
|
718
553
|
throw new TypeError('id must be a non-empty string');
|
|
719
554
|
return this.#items.get(id) ?? null;
|
|
@@ -723,13 +558,14 @@ class TinyAdvancedRaffle {
|
|
|
723
558
|
* @returns {ItemData[]} Array of cloned item objects.
|
|
724
559
|
*/
|
|
725
560
|
listItems() {
|
|
561
|
+
checkDestroy(this.#isDestroyed);
|
|
726
562
|
return Array.from(this.#items.values()).map((i) => ({ ...i }));
|
|
727
563
|
}
|
|
728
564
|
/**
|
|
729
565
|
* Clear all items from the system.
|
|
730
566
|
*/
|
|
731
567
|
clearList() {
|
|
732
|
-
this
|
|
568
|
+
checkDestroy(this.#isDestroyed);
|
|
733
569
|
this.#items.clear();
|
|
734
570
|
this.clearFreqs();
|
|
735
571
|
this.clearPities();
|
|
@@ -744,6 +580,7 @@ class TinyAdvancedRaffle {
|
|
|
744
580
|
* @throws {TypeError} If `fn` is not a function.
|
|
745
581
|
*/
|
|
746
582
|
hasGlobalModifier(fn) {
|
|
583
|
+
checkDestroy(this.#isDestroyed);
|
|
747
584
|
if (typeof fn !== 'function')
|
|
748
585
|
throw new TypeError('fn must be a function');
|
|
749
586
|
return this.#globalModifiers.includes(fn);
|
|
@@ -755,7 +592,7 @@ class TinyAdvancedRaffle {
|
|
|
755
592
|
* @throws {TypeError} If `fn` is not a function.
|
|
756
593
|
*/
|
|
757
594
|
addGlobalModifier(fn) {
|
|
758
|
-
this
|
|
595
|
+
checkDestroy(this.#isDestroyed);
|
|
759
596
|
if (typeof fn !== 'function')
|
|
760
597
|
throw new TypeError('fn must be a function');
|
|
761
598
|
this.#globalModifiers.push(fn);
|
|
@@ -766,7 +603,7 @@ class TinyAdvancedRaffle {
|
|
|
766
603
|
* @throws {TypeError} If `fn` is not a function.
|
|
767
604
|
*/
|
|
768
605
|
removeGlobalModifier(fn) {
|
|
769
|
-
this
|
|
606
|
+
checkDestroy(this.#isDestroyed);
|
|
770
607
|
if (typeof fn !== 'function')
|
|
771
608
|
throw new TypeError('fn must be a function');
|
|
772
609
|
this.#globalModifiers = this.#globalModifiers.filter((x) => x !== fn);
|
|
@@ -778,6 +615,7 @@ class TinyAdvancedRaffle {
|
|
|
778
615
|
* @throws {TypeError} If `fn` is not a function.
|
|
779
616
|
*/
|
|
780
617
|
hasTemporaryModifier(fn) {
|
|
618
|
+
checkDestroy(this.#isDestroyed);
|
|
781
619
|
if (typeof fn !== 'function')
|
|
782
620
|
throw new TypeError('fn must be a function');
|
|
783
621
|
return this.#temporaryModifiers.some((mod) => mod.fn === fn);
|
|
@@ -791,7 +629,7 @@ class TinyAdvancedRaffle {
|
|
|
791
629
|
* @throws {TypeError} If `uses` is not a number.
|
|
792
630
|
*/
|
|
793
631
|
addTemporaryModifier(fn, uses = 1) {
|
|
794
|
-
this
|
|
632
|
+
checkDestroy(this.#isDestroyed);
|
|
795
633
|
if (typeof fn !== 'function')
|
|
796
634
|
throw new TypeError('fn must be a function');
|
|
797
635
|
if (typeof uses !== 'number' || Number.isNaN(uses))
|
|
@@ -806,7 +644,7 @@ class TinyAdvancedRaffle {
|
|
|
806
644
|
* @throws {TypeError} If `fn` is not a function.
|
|
807
645
|
*/
|
|
808
646
|
removeTemporaryModifier(fn) {
|
|
809
|
-
this
|
|
647
|
+
checkDestroy(this.#isDestroyed);
|
|
810
648
|
if (typeof fn !== 'function')
|
|
811
649
|
throw new TypeError('fn must be a function');
|
|
812
650
|
const originalLength = this.#temporaryModifiers.length;
|
|
@@ -820,6 +658,7 @@ class TinyAdvancedRaffle {
|
|
|
820
658
|
* @throws {TypeError} If `ruleFn` is not a function.
|
|
821
659
|
*/
|
|
822
660
|
hasConditionalRule(ruleFn) {
|
|
661
|
+
checkDestroy(this.#isDestroyed);
|
|
823
662
|
if (typeof ruleFn !== 'function')
|
|
824
663
|
throw new TypeError('ruleFn must be a function');
|
|
825
664
|
return this.#conditionalRules.includes(ruleFn);
|
|
@@ -832,7 +671,7 @@ class TinyAdvancedRaffle {
|
|
|
832
671
|
* @throws {TypeError} If `ruleFn` is not a function.
|
|
833
672
|
*/
|
|
834
673
|
addConditionalRule(ruleFn) {
|
|
835
|
-
this
|
|
674
|
+
checkDestroy(this.#isDestroyed);
|
|
836
675
|
if (typeof ruleFn !== 'function')
|
|
837
676
|
throw new TypeError('ruleFn must be a function');
|
|
838
677
|
this.#conditionalRules.push(ruleFn);
|
|
@@ -845,7 +684,7 @@ class TinyAdvancedRaffle {
|
|
|
845
684
|
* @throws {TypeError} If `ruleFn` is not a function.
|
|
846
685
|
*/
|
|
847
686
|
removeConditionalRule(ruleFn) {
|
|
848
|
-
this
|
|
687
|
+
checkDestroy(this.#isDestroyed);
|
|
849
688
|
if (typeof ruleFn !== 'function')
|
|
850
689
|
throw new TypeError('ruleFn must be a function');
|
|
851
690
|
const originalLength = this.#conditionalRules.length;
|
|
@@ -862,6 +701,7 @@ class TinyAdvancedRaffle {
|
|
|
862
701
|
* @throws {TypeError} If `itemId` is not a string.
|
|
863
702
|
*/
|
|
864
703
|
hasPity(itemId) {
|
|
704
|
+
checkDestroy(this.#isDestroyed);
|
|
865
705
|
if (typeof itemId !== 'string')
|
|
866
706
|
throw new TypeError('itemId must be a string');
|
|
867
707
|
return this.#pitySystems.has(itemId);
|
|
@@ -878,7 +718,7 @@ class TinyAdvancedRaffle {
|
|
|
878
718
|
* @throws {TypeError} If parameters are invalid.
|
|
879
719
|
*/
|
|
880
720
|
configurePity(itemId, cfg) {
|
|
881
|
-
this
|
|
721
|
+
checkDestroy(this.#isDestroyed);
|
|
882
722
|
if (!this.#items.has(itemId))
|
|
883
723
|
throw new Error('Item not found');
|
|
884
724
|
if (typeof cfg !== 'object' || cfg === null)
|
|
@@ -904,7 +744,7 @@ class TinyAdvancedRaffle {
|
|
|
904
744
|
* @throws {TypeError} If itemId is not a string.
|
|
905
745
|
*/
|
|
906
746
|
resetPity(itemId) {
|
|
907
|
-
this
|
|
747
|
+
checkDestroy(this.#isDestroyed);
|
|
908
748
|
if (typeof itemId !== 'string' || !itemId.trim())
|
|
909
749
|
throw new TypeError('itemId must be a non-empty string');
|
|
910
750
|
const p = this.#pitySystems.get(itemId);
|
|
@@ -917,7 +757,7 @@ class TinyAdvancedRaffle {
|
|
|
917
757
|
* Remove all pity configurations.
|
|
918
758
|
*/
|
|
919
759
|
clearPities() {
|
|
920
|
-
this
|
|
760
|
+
checkDestroy(this.#isDestroyed);
|
|
921
761
|
this.#pitySystems.clear();
|
|
922
762
|
}
|
|
923
763
|
/* ===========================
|
|
@@ -930,6 +770,7 @@ class TinyAdvancedRaffle {
|
|
|
930
770
|
* @throws {TypeError} If `itemId` is not a string.
|
|
931
771
|
*/
|
|
932
772
|
hasExclusion(itemId) {
|
|
773
|
+
checkDestroy(this.#isDestroyed);
|
|
933
774
|
if (typeof itemId !== 'string')
|
|
934
775
|
throw new TypeError('itemId must be a string');
|
|
935
776
|
return this.#exclusions.has(itemId);
|
|
@@ -940,7 +781,7 @@ class TinyAdvancedRaffle {
|
|
|
940
781
|
* @throws {TypeError} If `itemId` is not a string.
|
|
941
782
|
*/
|
|
942
783
|
excludeItem(itemId) {
|
|
943
|
-
this
|
|
784
|
+
checkDestroy(this.#isDestroyed);
|
|
944
785
|
if (typeof itemId !== 'string')
|
|
945
786
|
throw new TypeError('itemId must be a string');
|
|
946
787
|
this.#exclusions.add(itemId);
|
|
@@ -951,7 +792,7 @@ class TinyAdvancedRaffle {
|
|
|
951
792
|
* @throws {TypeError} If `itemId` is not a string.
|
|
952
793
|
*/
|
|
953
794
|
includeItem(itemId) {
|
|
954
|
-
this
|
|
795
|
+
checkDestroy(this.#isDestroyed);
|
|
955
796
|
if (typeof itemId !== 'string')
|
|
956
797
|
throw new TypeError('itemId must be a string');
|
|
957
798
|
this.#exclusions.delete(itemId);
|
|
@@ -964,7 +805,7 @@ class TinyAdvancedRaffle {
|
|
|
964
805
|
* @private
|
|
965
806
|
*/
|
|
966
807
|
_ensureGroup(name) {
|
|
967
|
-
this
|
|
808
|
+
checkDestroy(this.#isDestroyed);
|
|
968
809
|
if (typeof name !== 'string')
|
|
969
810
|
throw new TypeError('name must be a string');
|
|
970
811
|
let group = this.#groups.get(name);
|
|
@@ -982,6 +823,7 @@ class TinyAdvancedRaffle {
|
|
|
982
823
|
* @throws {TypeError} If parameters are not strings.
|
|
983
824
|
*/
|
|
984
825
|
hasInGroup(itemId, groupName) {
|
|
826
|
+
checkDestroy(this.#isDestroyed);
|
|
985
827
|
if (typeof itemId !== 'string' || typeof groupName !== 'string')
|
|
986
828
|
throw new TypeError('itemId and groupName must be strings');
|
|
987
829
|
const group = this.#groups.get(groupName);
|
|
@@ -995,7 +837,7 @@ class TinyAdvancedRaffle {
|
|
|
995
837
|
* @throws {TypeError} If parameters are not strings.
|
|
996
838
|
*/
|
|
997
839
|
addToGroup(itemId, groupName) {
|
|
998
|
-
this
|
|
840
|
+
checkDestroy(this.#isDestroyed);
|
|
999
841
|
if (typeof itemId !== 'string' || typeof groupName !== 'string')
|
|
1000
842
|
throw new TypeError('itemId and groupName must be strings');
|
|
1001
843
|
const it = this.#items.get(itemId);
|
|
@@ -1011,7 +853,7 @@ class TinyAdvancedRaffle {
|
|
|
1011
853
|
* @throws {TypeError} If parameters are not strings.
|
|
1012
854
|
*/
|
|
1013
855
|
removeFromGroup(itemId, groupName) {
|
|
1014
|
-
this
|
|
856
|
+
checkDestroy(this.#isDestroyed);
|
|
1015
857
|
if (typeof itemId !== 'string' || typeof groupName !== 'string')
|
|
1016
858
|
throw new TypeError('itemId and groupName must be strings');
|
|
1017
859
|
const g = this.#groups.get(groupName);
|
|
@@ -1029,7 +871,7 @@ class TinyAdvancedRaffle {
|
|
|
1029
871
|
* Effectively resets the internal frequency map to an empty state.
|
|
1030
872
|
*/
|
|
1031
873
|
clearFreqs() {
|
|
1032
|
-
this
|
|
874
|
+
checkDestroy(this.#isDestroyed);
|
|
1033
875
|
this.#freq.clear();
|
|
1034
876
|
}
|
|
1035
877
|
/**
|
|
@@ -1040,7 +882,7 @@ class TinyAdvancedRaffle {
|
|
|
1040
882
|
* @throws {TypeError} If `itemId` is not a string.
|
|
1041
883
|
*/
|
|
1042
884
|
resetFreq(itemId) {
|
|
1043
|
-
this
|
|
885
|
+
checkDestroy(this.#isDestroyed);
|
|
1044
886
|
if (typeof itemId !== 'string')
|
|
1045
887
|
throw new TypeError('itemId must be a string');
|
|
1046
888
|
this.#freq.delete(itemId);
|
|
@@ -1055,7 +897,7 @@ class TinyAdvancedRaffle {
|
|
|
1055
897
|
* @throws {TypeError} If `context` is provided but is not an object.
|
|
1056
898
|
*/
|
|
1057
899
|
computeEffectiveWeights(context = {}) {
|
|
1058
|
-
this
|
|
900
|
+
checkDestroy(this.#isDestroyed);
|
|
1059
901
|
if (typeof context !== 'object' || context === null)
|
|
1060
902
|
throw new TypeError(`computeEffectiveWeights: parameter 'context' must be a non-null object, got ${typeof context}`);
|
|
1061
903
|
if ('previousDraws' in context && !Array.isArray(context.previousDraws))
|
|
@@ -1131,9 +973,9 @@ class TinyAdvancedRaffle {
|
|
|
1131
973
|
* @param {Map<string, number>} weights - Map of item IDs to their weights.
|
|
1132
974
|
* @returns {Array<{id: string, weight: number, p: number, cumulative: number}>} Distribution array.
|
|
1133
975
|
* @throws {TypeError} If `weights` is not a Map.
|
|
976
|
+
* @private
|
|
1134
977
|
*/
|
|
1135
978
|
_weightsToDistribution(weights) {
|
|
1136
|
-
this._checkDestroyed();
|
|
1137
979
|
if (!(weights instanceof Map))
|
|
1138
980
|
throw new TypeError(`_weightsToDistribution: parameter 'weights' must be a Map, got ${typeof weights}`);
|
|
1139
981
|
for (const [key, val] of weights) {
|
|
@@ -1179,7 +1021,7 @@ class TinyAdvancedRaffle {
|
|
|
1179
1021
|
* @throws {TypeError} If `opts` is not an object.
|
|
1180
1022
|
*/
|
|
1181
1023
|
drawOne(opts = {}) {
|
|
1182
|
-
this
|
|
1024
|
+
checkDestroy(this.#isDestroyed);
|
|
1183
1025
|
if (typeof opts !== 'object' || opts === null)
|
|
1184
1026
|
throw new TypeError(`drawOne: parameter 'opts' must be a non-null object, got ${typeof opts}`);
|
|
1185
1027
|
if ('previousDraws' in opts && !Array.isArray(opts.previousDraws))
|
|
@@ -1216,7 +1058,7 @@ class TinyAdvancedRaffle {
|
|
|
1216
1058
|
if (!item)
|
|
1217
1059
|
return null;
|
|
1218
1060
|
const result = { id: item.id, label: item.label, meta: { ...item.meta }, prob: chosen.p };
|
|
1219
|
-
this
|
|
1061
|
+
this.emit('draw', result);
|
|
1220
1062
|
// add frequence
|
|
1221
1063
|
if (result)
|
|
1222
1064
|
this.#freq.set(result.id, (this.#freq.get(result.id) || 0) + 1);
|
|
@@ -1229,7 +1071,6 @@ class TinyAdvancedRaffle {
|
|
|
1229
1071
|
* @private
|
|
1230
1072
|
*/
|
|
1231
1073
|
_consumeTemporaryModifiers() {
|
|
1232
|
-
this._checkDestroyed();
|
|
1233
1074
|
for (let i = this.#temporaryModifiers.length - 1; i >= 0; --i) {
|
|
1234
1075
|
const t = this.#temporaryModifiers[i];
|
|
1235
1076
|
t.uses -= 1;
|
|
@@ -1251,7 +1092,7 @@ class TinyAdvancedRaffle {
|
|
|
1251
1092
|
* @throws {TypeError} If `opts` is not an object.
|
|
1252
1093
|
*/
|
|
1253
1094
|
drawMany(count = 1, opts = {}) {
|
|
1254
|
-
this
|
|
1095
|
+
checkDestroy(this.#isDestroyed);
|
|
1255
1096
|
if (!Number.isInteger(count) || count <= 0)
|
|
1256
1097
|
throw new TypeError(`drawMany: parameter 'count' must be a positive integer, got ${count}`);
|
|
1257
1098
|
if (typeof opts !== 'object' || opts === null)
|
|
@@ -1319,7 +1160,7 @@ class TinyAdvancedRaffle {
|
|
|
1319
1160
|
* @returns {ExportedJson} Exported configuration object.
|
|
1320
1161
|
*/
|
|
1321
1162
|
exportToJson() {
|
|
1322
|
-
this
|
|
1163
|
+
checkDestroy(this.#isDestroyed);
|
|
1323
1164
|
const data = {
|
|
1324
1165
|
items: Array.from(this.#items.values()).map((it) => ({
|
|
1325
1166
|
id: it.id,
|
|
@@ -1345,7 +1186,7 @@ class TinyAdvancedRaffle {
|
|
|
1345
1186
|
* @throws {TypeError} If `data.seed` is not a number, null, or undefined.
|
|
1346
1187
|
*/
|
|
1347
1188
|
loadFromJson(data) {
|
|
1348
|
-
this
|
|
1189
|
+
checkDestroy(this.#isDestroyed);
|
|
1349
1190
|
if (typeof data !== 'object' || data === null)
|
|
1350
1191
|
throw new TypeError('data must be a non-null object');
|
|
1351
1192
|
if (!Array.isArray(data.items) || !Array.isArray(data.pity) || !Array.isArray(data.exclusions))
|
|
@@ -1394,7 +1235,7 @@ class TinyAdvancedRaffle {
|
|
|
1394
1235
|
* @returns {TinyAdvancedRaffle} A new cloned instance, fully independent from the original.
|
|
1395
1236
|
*/
|
|
1396
1237
|
clone() {
|
|
1397
|
-
this
|
|
1238
|
+
checkDestroy(this.#isDestroyed);
|
|
1398
1239
|
const cloneInstance = new TinyAdvancedRaffle();
|
|
1399
1240
|
// Primitive values
|
|
1400
1241
|
cloneInstance.#normalization = this.#normalization;
|
|
@@ -1437,9 +1278,9 @@ class TinyAdvancedRaffle {
|
|
|
1437
1278
|
* @param {number} seed - Seed value for PRNG (integer).
|
|
1438
1279
|
* @returns {RngGenerator} A function that returns a pseudo-random number in [0, 1).
|
|
1439
1280
|
* @throws {TypeError} If `seed` is not a finite number.
|
|
1281
|
+
* @private
|
|
1440
1282
|
*/
|
|
1441
1283
|
_makeSeededRng(seed) {
|
|
1442
|
-
this._checkDestroyed();
|
|
1443
1284
|
if (typeof seed !== 'number' || !Number.isFinite(seed))
|
|
1444
1285
|
throw new TypeError('seed must be a finite number');
|
|
1445
1286
|
// mulberry32
|
|
@@ -1459,7 +1300,6 @@ class TinyAdvancedRaffle {
|
|
|
1459
1300
|
destroy() {
|
|
1460
1301
|
if (this.#isDestroyed)
|
|
1461
1302
|
return;
|
|
1462
|
-
this.#isDestroyed = true;
|
|
1463
1303
|
// Clear all Maps and Sets
|
|
1464
1304
|
this.#pitySystems.clear();
|
|
1465
1305
|
this.#exclusions.clear();
|
|
@@ -1472,6 +1312,7 @@ class TinyAdvancedRaffle {
|
|
|
1472
1312
|
this.#conditionalRules = [];
|
|
1473
1313
|
// Nullify core references
|
|
1474
1314
|
this.#seed = null;
|
|
1315
|
+
this.#isDestroyed = true;
|
|
1475
1316
|
}
|
|
1476
1317
|
}
|
|
1477
1318
|
export default TinyAdvancedRaffle;
|