tiny-essentials 1.12.2 → 1.13.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.
@@ -2886,6 +2886,7 @@ __webpack_require__.r(__webpack_exports__);
2886
2886
  // EXPORTS
2887
2887
  __webpack_require__.d(__webpack_exports__, {
2888
2888
  ColorSafeStringify: () => (/* reexport */ libs_ColorSafeStringify),
2889
+ TinyDomReadyManager: () => (/* reexport */ libs_TinyDomReadyManager),
2889
2890
  TinyDragDropDetector: () => (/* reexport */ libs_TinyDragDropDetector),
2890
2891
  TinyDragger: () => (/* reexport */ libs_TinyDragger),
2891
2892
  TinyLevelUp: () => (/* reexport */ userLevel),
@@ -2919,6 +2920,7 @@ __webpack_require__.d(__webpack_exports__, {
2919
2920
  formatCustomTimer: () => (/* reexport */ formatCustomTimer),
2920
2921
  formatDayTimer: () => (/* reexport */ formatDayTimer),
2921
2922
  formatTimer: () => (/* reexport */ formatTimer),
2923
+ genFibonacciSeq: () => (/* reexport */ genFibonacciSeq),
2922
2924
  getAge: () => (/* reexport */ getAge),
2923
2925
  getHtmlElBorders: () => (/* reexport */ getHtmlElBorders),
2924
2926
  getHtmlElBordersWidth: () => (/* reexport */ getHtmlElBordersWidth),
@@ -4131,6 +4133,43 @@ function formatBytes(bytes, decimals = null, maxUnit = null) {
4131
4133
  return { unit, value };
4132
4134
  }
4133
4135
 
4136
+ /**
4137
+ * Generates a Fibonacci-like sequence as an array of vectors.
4138
+ *
4139
+ * @param {Object} [settings={}]
4140
+ * @param {number[]} [settings.baseValues=[0, 1]] - An array of two starting numbers (e.g. [0, 1] or [1, 1]).
4141
+ * @param {number} [settings.length=10] - Total number of items to generate in the sequence.
4142
+ * @param {(a: number, b: number, index: number) => number} [settings.combiner=((a, b) => a + b)] - A custom function to combine previous two numbers.
4143
+ * @returns {number[]} The resulting Fibonacci sequence.
4144
+ *
4145
+ * FibonacciVectors2D
4146
+ * @example
4147
+ * generateFibonacciSequence({
4148
+ * baseValues: [[0, 1], [1, 1]],
4149
+ * length: 10,
4150
+ * combiner: ([x1, y1], [x2, y2]) => [x1 + x2, y1 + y2]
4151
+ * });
4152
+ *
4153
+ * @beta
4154
+ */
4155
+ function genFibonacciSeq({
4156
+ baseValues = [0, 1],
4157
+ length = 10,
4158
+ combiner = (a, b) => a + b,
4159
+ } = {}) {
4160
+ if (!Array.isArray(baseValues) || baseValues.length !== 2)
4161
+ throw new Error('baseValues must be an array of exactly two numbers');
4162
+
4163
+ const sequence = [...baseValues.slice(0, 2)];
4164
+
4165
+ for (let i = 2; i < length; i++) {
4166
+ const next = combiner(sequence[i - 2], sequence[i - 1], i);
4167
+ sequence.push(next);
4168
+ }
4169
+
4170
+ return sequence;
4171
+ }
4172
+
4134
4173
  ;// ./src/v1/basics/text.mjs
4135
4174
  /**
4136
4175
  * Converts a string to title case where the first letter of each word is capitalized.
@@ -8200,6 +8239,180 @@ class TinyDragger {
8200
8239
 
8201
8240
  /* harmony default export */ const libs_TinyDragger = (TinyDragger);
8202
8241
 
8242
+ ;// ./src/v1/libs/TinyDomReadyManager.mjs
8243
+ /**
8244
+ * A basic function that performs a task when the system is ready.
8245
+ * Used for handlers in the readiness queue.
8246
+ *
8247
+ * @typedef {() => void} Fn
8248
+ */
8249
+
8250
+ /**
8251
+ * A function that determines whether a specific handler should be executed.
8252
+ * Should return `true` to allow execution, or `false` to skip the handler.
8253
+ *
8254
+ * @typedef {() => boolean} FnFilter
8255
+ */
8256
+
8257
+ /**
8258
+ * @typedef {Object} Handler
8259
+ * @property {Fn} fn - Function to execute when ready.
8260
+ * @property {boolean} once - Whether to execute only once.
8261
+ * @property {number} priority - Execution order (higher priority runs first).
8262
+ * @property {FnFilter|null} filter - Optional filter function to determine execution.
8263
+ * @property {boolean} domOnly - Whether to run as soon as DOM is ready (before full readiness).
8264
+ */
8265
+
8266
+ class TinyDomReadyManager {
8267
+ /** @type {Handler[]} */
8268
+ #handlers = [];
8269
+
8270
+ /** @type {boolean} */
8271
+ #isDomReady = false;
8272
+
8273
+ /** @type {boolean} */
8274
+ #isFullyReady = false;
8275
+
8276
+ /** @type {Promise<any>[]} */
8277
+ #promises = [];
8278
+
8279
+ /**
8280
+ * Checks if the DOM is ready and if all Promises have been resolved.
8281
+ */
8282
+ #checkAllReady() {
8283
+ if (this.#isDomReady) {
8284
+ Promise.all(this.#promises)
8285
+ .then(() => {
8286
+ this.#isFullyReady = true;
8287
+ this.#runHandlers(false); // run non-domOnly
8288
+ })
8289
+ .catch((err) => {
8290
+ console.error('[TinyDomReadyManager] Promise rejected:', err);
8291
+ });
8292
+ }
8293
+ }
8294
+
8295
+ /**
8296
+ * Executes handlers by filtering them by `domOnly` flag and sorting by priority.
8297
+ * @param {boolean} domOnlyOnly - Whether to run only `domOnly` handlers.
8298
+ */
8299
+ #runHandlers(domOnlyOnly) {
8300
+ this.#handlers
8301
+ .filter((h) => h.domOnly === domOnlyOnly)
8302
+ .sort((a, b) => b.priority - a.priority)
8303
+ .forEach((handler) => this.#invokeHandler(handler));
8304
+
8305
+ this.#handlers = this.#handlers.filter((h) => !(h.once && (domOnlyOnly ? h.domOnly : true)));
8306
+ }
8307
+
8308
+ /**
8309
+ * Executes a handler if its filter passes.
8310
+ * @param {Handler} handler
8311
+ */
8312
+ #invokeHandler(handler) {
8313
+ if (typeof handler.filter === 'function') {
8314
+ try {
8315
+ if (!handler.filter()) return;
8316
+ } catch (err) {
8317
+ console.warn('[TinyDomReadyManager] Filter error:', err);
8318
+ return;
8319
+ }
8320
+ }
8321
+
8322
+ try {
8323
+ handler.fn();
8324
+ } catch (err) {
8325
+ console.error('[TinyDomReadyManager] Handler error:', err);
8326
+ }
8327
+ }
8328
+
8329
+ /**
8330
+ * Marks the system as DOM-ready and runs DOM-only handlers.
8331
+ * @private
8332
+ */
8333
+ _markDomReady() {
8334
+ this.#isDomReady = true;
8335
+ this.#runHandlers(true); // Run domOnly
8336
+ this.#checkAllReady(); // Then check for full readiness
8337
+ }
8338
+
8339
+ /**
8340
+ * Initializes the manager using `DOMContentLoaded`.
8341
+ */
8342
+ init() {
8343
+ if (this.#isDomReady) throw new Error('[TinyDomReadyManager] init() has already been called.');
8344
+
8345
+ if (document.readyState === 'interactive' || document.readyState === 'complete') {
8346
+ this._markDomReady();
8347
+ } else {
8348
+ document.addEventListener('DOMContentLoaded', () => this._markDomReady());
8349
+ }
8350
+ }
8351
+
8352
+ /**
8353
+ * Adds a Promise to delay full readiness.
8354
+ * @param {Promise<any>} promise
8355
+ * @throws {TypeError}
8356
+ */
8357
+ addPromise(promise) {
8358
+ if (!(promise instanceof Promise))
8359
+ throw new TypeError('[TinyDomReadyManager] promise must be a valid Promise.');
8360
+
8361
+ if (this.#isFullyReady) return;
8362
+ this.#promises.push(promise);
8363
+ if (this.#isDomReady) this.#checkAllReady();
8364
+ }
8365
+
8366
+ /**
8367
+ * Registers a handler to run either after DOM is ready or after full readiness.
8368
+ *
8369
+ * @param {Fn} fn - Function to execute.
8370
+ * @param {Object} [options]
8371
+ * @param {boolean} [options.once=true] - Execute only once.
8372
+ * @param {number} [options.priority=0] - Higher priority runs first.
8373
+ * @param {FnFilter|null} [options.filter=null] - Optional filter function.
8374
+ * @param {boolean} [options.domOnly=false] - If true, executes after DOM ready only.
8375
+ * @throws {TypeError} If fn is not a function.
8376
+ */
8377
+ onReady(fn, { once = true, priority = 0, filter = null, domOnly = false } = {}) {
8378
+ if (typeof fn !== 'function')
8379
+ throw new TypeError('[TinyDomReadyManager] fn must be a function.');
8380
+
8381
+ const handler = { fn, once, priority, filter, domOnly };
8382
+
8383
+ if (domOnly && this.#isDomReady) {
8384
+ this.#invokeHandler(handler);
8385
+ if (!once) this.#handlers.push(handler);
8386
+ return;
8387
+ }
8388
+
8389
+ if (!domOnly && this.#isFullyReady) {
8390
+ this.#invokeHandler(handler);
8391
+ } else {
8392
+ this.#handlers.push(handler);
8393
+ }
8394
+ }
8395
+
8396
+ /**
8397
+ * Returns whether the system is fully ready (DOM + Promises).
8398
+ * @returns {boolean}
8399
+ */
8400
+ isReady() {
8401
+ return this.#isFullyReady;
8402
+ }
8403
+
8404
+ /**
8405
+ * Returns whether the DOM is ready (DOMContentLoaded has fired).
8406
+ * Does not wait for promises.
8407
+ * @returns {boolean}
8408
+ */
8409
+ isDomReady() {
8410
+ return this.#isDomReady;
8411
+ }
8412
+ }
8413
+
8414
+ /* harmony default export */ const libs_TinyDomReadyManager = (TinyDomReadyManager);
8415
+
8203
8416
  ;// ./src/v1/index.mjs
8204
8417
 
8205
8418
 
@@ -8224,6 +8437,7 @@ class TinyDragger {
8224
8437
 
8225
8438
 
8226
8439
 
8440
+
8227
8441
 
8228
8442
 
8229
8443
  })();