@andrew_l/toolkit 0.2.8 → 0.2.9

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
@@ -48,6 +48,7 @@ const isError = (val) => val instanceof Error || //@ts-expect-error
48
48
  isObject(val) && isString(val.message) && isString(val.stack);
49
49
  const isSymbol = (val) => typeof val == "symbol";
50
50
  const isSet = (val) => val instanceof Set;
51
+ const isRegExp = (val) => val instanceof RegExp;
51
52
  const isWeakSet = (val) => val instanceof WeakSet;
52
53
  const isMap = (val) => val instanceof Map;
53
54
  const isWeakMap = (val) => val instanceof WeakMap;
@@ -171,7 +172,7 @@ const isEmpty = (obj) => {
171
172
  return false;
172
173
  };
173
174
  function isPromise(value) {
174
- return value && typeof value === "object" && "then" in value && "catch" in value && typeof value.then === "function" && typeof value.catch === "function";
175
+ return value instanceof Promise || !!value && typeof value === "object" && "then" in value && "catch" in value && typeof value.then === "function" && typeof value.catch === "function";
175
176
  }
176
177
  const primitiveTypeofSet = Object.freeze(
177
178
  /* @__PURE__ */ new Set(["string", "number", "boolean", "bigint", "symbol", "undefined"])
@@ -404,9 +405,9 @@ function equal(actual, expected, message) {
404
405
  });
405
406
  }
406
407
  }
407
- function empty$1(value, message) {
408
- if (isEmpty(value)) {
409
- throw toError$1(empty$1, value, message, "Expected not empty value.");
408
+ function notEmpty(value, message) {
409
+ if (!isEmpty(value)) {
410
+ throw toError$1(notEmpty, value, message, "Expected not empty value.");
410
411
  }
411
412
  }
412
413
  function object(value, message) {
@@ -445,7 +446,7 @@ function date(value, message) {
445
446
  }
446
447
  }
447
448
  function fn(value, message) {
448
- if (!isNumber(value)) {
449
+ if (!isFunction(value)) {
449
450
  throw toError$1(fn, value, message, "Expected function value.");
450
451
  }
451
452
  }
@@ -503,11 +504,11 @@ const assert = {
503
504
  arrayStrings: arrayStrings,
504
505
  boolean: boolean,
505
506
  date: date,
506
- empty: empty$1,
507
507
  equal: equal,
508
508
  fn: fn,
509
509
  greaterThan: greaterThan,
510
510
  lessThan: lessThan,
511
+ notEmpty: notEmpty,
511
512
  notEmptyString: notEmptyString,
512
513
  number: number$1,
513
514
  object: object,
@@ -3264,28 +3265,84 @@ function parseDecimal(value, dights) {
3264
3265
  }
3265
3266
 
3266
3267
  const CODE_TO_MESSAGE = Object.freeze({
3268
+ 100: "Continue",
3267
3269
  101: "Switching Protocols",
3268
3270
  102: "Processing",
3269
- 200: "Ok",
3271
+ 103: "Early Hints",
3272
+ 200: "OK",
3270
3273
  201: "Created",
3274
+ 202: "Accepted",
3275
+ 203: "Non-Authoritative Information",
3271
3276
  204: "No Content",
3277
+ 205: "Reset Content",
3278
+ 206: "Partial Content",
3279
+ 300: "Multiple Choices",
3272
3280
  301: "Moved Permanently",
3281
+ 302: "Found",
3282
+ 303: "See Other",
3283
+ 304: "Not Modified",
3284
+ 305: "Use Proxy",
3285
+ 307: "Temporary Redirect",
3286
+ 308: "Permanent Redirect",
3273
3287
  400: "Bad Request",
3274
3288
  401: "Unauthorized",
3289
+ 402: "Payment Required",
3275
3290
  403: "Forbidden",
3276
3291
  404: "Not Found",
3277
- 409: "Already Exists",
3278
- 500: "Internal Server Error"
3292
+ 405: "Method Not Allowed",
3293
+ 406: "Not Acceptable",
3294
+ 407: "Proxy Authentication Required",
3295
+ 408: "Request Timeout",
3296
+ 409: "Conflict",
3297
+ 410: "Gone",
3298
+ 411: "Length Required",
3299
+ 412: "Precondition Failed",
3300
+ 413: "Payload Too Large",
3301
+ 414: "URI Too Long",
3302
+ 415: "Unsupported Media Type",
3303
+ 416: "Range Not Satisfiable",
3304
+ 417: "Expectation Failed",
3305
+ 418: "I'm a teapot",
3306
+ 422: "Unprocessable Entity",
3307
+ 425: "Too Early",
3308
+ 426: "Upgrade Required",
3309
+ 428: "Precondition Required",
3310
+ 429: "Too Many Requests",
3311
+ 431: "Request Header Fields Too Large",
3312
+ 500: "Internal Server Error",
3313
+ 501: "Not Implemented",
3314
+ 502: "Bad Gateway",
3315
+ 503: "Service Unavailable",
3316
+ 504: "Gateway Timeout",
3317
+ 505: "HTTP Version Not Supported",
3318
+ 506: "Variant Also Negotiates",
3319
+ 507: "Insufficient Storage",
3320
+ 508: "Loop Detected",
3321
+ 510: "Not Extended",
3322
+ 511: "Network Authentication Required"
3279
3323
  });
3280
3324
  class AppError extends Error {
3325
+ /**
3326
+ * HTTP valid status code
3327
+ */
3328
+ statusCode;
3329
+ /**
3330
+ * Custom error code
3331
+ */
3281
3332
  code;
3282
- constructor(messageOrCode, code = 500, options) {
3333
+ constructor(...args) {
3283
3334
  let message = "Unknown error";
3284
- if (isNumber(messageOrCode)) {
3285
- code = messageOrCode;
3286
- message = CODE_TO_MESSAGE[code] || "Unknown error";
3335
+ let statusCode = 500;
3336
+ let code = "ERR_UNKNOWN";
3337
+ let options;
3338
+ if (isNumber(args[0])) {
3339
+ statusCode = args[0];
3340
+ message = CODE_TO_MESSAGE[statusCode] || message;
3341
+ options = args[1];
3287
3342
  } else {
3288
- message = messageOrCode || CODE_TO_MESSAGE[code] || "Unknown error";
3343
+ message = args[0] || CODE_TO_MESSAGE[statusCode] || message;
3344
+ statusCode = isNumber(args[1]) ? args[1] : statusCode;
3345
+ options = args[2];
3289
3346
  }
3290
3347
  super(message, options);
3291
3348
  if (typeof Error.captureStackTrace !== "function") {
@@ -3293,13 +3350,8 @@ class AppError extends Error {
3293
3350
  } else {
3294
3351
  Error.captureStackTrace(this, AppError);
3295
3352
  }
3296
- this.code = code;
3297
- }
3298
- /**
3299
- * alias for `code` property
3300
- */
3301
- get statusCode() {
3302
- return this.code;
3353
+ this.statusCode = statusCode;
3354
+ this.code = options?.code ?? code;
3303
3355
  }
3304
3356
  get name() {
3305
3357
  return "AppError";
@@ -3345,13 +3397,6 @@ const BrowserAssertionError$1 = {
3345
3397
  BrowserAssertionError: BrowserAssertionError
3346
3398
  };
3347
3399
 
3348
- function isSuccess(value) {
3349
- return value.success === true;
3350
- }
3351
- function isSkip(value) {
3352
- return value.skip === true;
3353
- }
3354
-
3355
3400
  function getFileExtension(name, withDot = true) {
3356
3401
  if (!isString(name)) {
3357
3402
  return null;
@@ -3407,432 +3452,327 @@ function humanFileSize(bytes, digits = 1, withSpace = true) {
3407
3452
  return bytes.toFixed(digits) + (withSpace ? " " : "") + units[u];
3408
3453
  }
3409
3454
 
3410
- function sprintf(line, args, unusedArgs = []) {
3411
- let result = "";
3412
- const argsLen = args.length;
3413
- const lineLen = line.length;
3414
- let opened = false;
3415
- let currentChar = -1;
3416
- let lastPos = 0;
3417
- let argsIndex = 0;
3418
- for (let idx = 0; idx < lineLen; idx++) {
3419
- currentChar = line.charCodeAt(idx);
3420
- if (currentChar === 37) {
3421
- opened = true;
3422
- continue;
3423
- }
3424
- if (!opened) continue;
3425
- opened = false;
3426
- switch (currentChar) {
3427
- // 'd'
3428
- case 100:
3429
- // 'f'
3430
- case 102: {
3431
- result += line.slice(lastPos, idx - 1);
3432
- result += Number(args[argsIndex]);
3433
- lastPos = idx + 1;
3434
- argsIndex++;
3435
- break;
3436
- }
3437
- // 'i'
3438
- case 105: {
3439
- result += line.slice(lastPos, idx - 1);
3440
- result += Math.floor(Number(args[argsIndex]));
3441
- lastPos = idx + 1;
3442
- argsIndex++;
3443
- break;
3444
- }
3445
- // 'O'
3446
- case 79:
3447
- // 'o'
3448
- case 111:
3449
- // 'j'
3450
- case 106: {
3451
- result += line.slice(lastPos, idx - 1);
3452
- result += tryStringify(args[argsIndex]);
3453
- lastPos = idx + 1;
3454
- argsIndex++;
3455
- break;
3456
- }
3457
- // 's'
3458
- case 115: {
3459
- result += line.slice(lastPos, idx - 1);
3460
- result += String(args[argsIndex]);
3461
- lastPos = idx + 1;
3462
- argsIndex++;
3463
- break;
3464
- }
3465
- }
3466
- if (argsIndex >= argsLen) break;
3467
- }
3468
- if (lastPos < lineLen) {
3469
- result += line.slice(lastPos, lineLen);
3470
- }
3471
- if (argsIndex < argsLen) {
3472
- unusedArgs.push(...args.slice(argsIndex, argsLen));
3473
- }
3474
- return result;
3475
- }
3476
- function tryStringify(o) {
3477
- switch (typeof o) {
3478
- case "function": {
3479
- return o.name || "<anonymous>";
3480
- }
3481
- case "string": {
3482
- return "'" + o + "'";
3455
+ function debounce(func, debounceMs, { signal, edges } = {}) {
3456
+ let pendingThis = void 0;
3457
+ let pendingArgs = null;
3458
+ const leading = edges != null && edges.includes("leading");
3459
+ const trailing = edges == null || edges.includes("trailing");
3460
+ const invoke = () => {
3461
+ if (pendingArgs !== null) {
3462
+ func.apply(pendingThis, pendingArgs);
3463
+ pendingThis = void 0;
3464
+ pendingArgs = null;
3483
3465
  }
3484
- default: {
3485
- try {
3486
- return JSON.stringify(o);
3487
- } catch (e) {
3488
- return '"[Circular]"';
3489
- }
3490
- }
3491
- }
3492
- }
3493
-
3494
- const LEVEL_NUM = {
3495
- debug: 0,
3496
- log: 1,
3497
- info: 2,
3498
- warn: 3,
3499
- error: 4
3500
- };
3501
- let currentLogLevel = LEVEL_NUM.log;
3502
- const loggerSetLevel = (level) => {
3503
- number$1(LEVEL_NUM[level], `Invalid log level: ${level}`);
3504
- currentLogLevel = LEVEL_NUM[level];
3505
- };
3506
- const logger = (...baseArgs) => {
3507
- if (isString(baseArgs[0]?.url)) {
3508
- baseArgs[0] = baseArgs[0]?.url;
3509
- }
3510
- if (typeof baseArgs[0] === "string" && baseArgs[0][0] !== "[") {
3511
- baseArgs[0] = `[${baseArgs[0].split("/").at(-1).split("?", 1)[0]}]`;
3512
- }
3513
- const writeLog = (level, ...[pattern, ...args]) => {
3514
- const levelNum = LEVEL_NUM[level];
3515
- if (levelNum < currentLogLevel) {
3516
- return;
3466
+ };
3467
+ const onTimerEnd = () => {
3468
+ if (trailing) {
3469
+ invoke();
3517
3470
  }
3518
- if (!isString(pattern)) {
3519
- console[level](...baseArgs, pattern, ...args);
3520
- return;
3471
+ cancel();
3472
+ };
3473
+ let timeoutId = null;
3474
+ const schedule = () => {
3475
+ if (timeoutId != null) {
3476
+ clearTimeout(timeoutId);
3477
+ }
3478
+ timeoutId = setTimeout(() => {
3479
+ timeoutId = null;
3480
+ onTimerEnd();
3481
+ }, debounceMs);
3482
+ };
3483
+ const cancelTimer = () => {
3484
+ if (timeoutId !== null) {
3485
+ clearTimeout(timeoutId);
3486
+ timeoutId = null;
3521
3487
  }
3522
- const unusedArgs = [];
3523
- const formatted = sprintf(pattern, args, unusedArgs);
3524
- console[level](...baseArgs, formatted, ...unusedArgs);
3525
3488
  };
3526
- const log = writeLog.bind(null, "log");
3527
- const info = writeLog.bind(null, "info");
3528
- const warn = writeLog.bind(null, "warn");
3529
- const error = writeLog.bind(null, "error");
3530
- const debug = writeLog.bind(null, "debug");
3531
- const extend = (...args) => {
3532
- return logger(...baseArgs, ...args);
3489
+ const cancel = () => {
3490
+ cancelTimer();
3491
+ pendingThis = void 0;
3492
+ pendingArgs = null;
3533
3493
  };
3534
- const instance = {
3535
- log,
3536
- info,
3537
- warn,
3538
- error,
3539
- debug,
3540
- extend
3494
+ const flush = () => {
3495
+ cancelTimer();
3496
+ invoke();
3541
3497
  };
3542
- return instance;
3543
- };
3544
-
3545
- async function asyncFilter(array, predicate) {
3546
- const result = [];
3547
- const cooldown = nextTickIteration(10);
3548
- for (let idx = 0; idx < array.length; idx++) {
3549
- await cooldown();
3550
- const value = array[idx];
3551
- const valid = await predicate(value, idx, array);
3552
- if (valid) {
3553
- result.push(value);
3498
+ const debounced = function(...args) {
3499
+ if (signal?.aborted) {
3500
+ return;
3554
3501
  }
3555
- }
3556
- return result;
3502
+ pendingThis = this;
3503
+ pendingArgs = args;
3504
+ const isFirstCall = timeoutId == null;
3505
+ schedule();
3506
+ if (leading && isFirstCall) {
3507
+ invoke();
3508
+ }
3509
+ };
3510
+ debounced.schedule = schedule;
3511
+ debounced.cancel = cancel;
3512
+ debounced.flush = flush;
3513
+ signal?.addEventListener("abort", cancel, { once: true });
3514
+ return debounced;
3557
3515
  }
3558
3516
 
3559
- const defaultWindow$1 = globalThis?.window;
3560
- const idle = (() => {
3561
- if (defaultWindow$1?.requestIdleCallback) {
3562
- return defaultWindow$1.requestIdleCallback;
3563
- } else if (defaultWindow$1?.requestAnimationFrame) {
3564
- return defaultWindow$1.requestAnimationFrame;
3565
- } else if (isFunction(process?.nextTick)) {
3566
- return process.nextTick;
3567
- } else {
3568
- return (fn) => setTimeout(fn, 0);
3569
- }
3570
- })();
3571
- function fastIdle(callback) {
3572
- return idle(callback);
3517
+ function isSuccess(value) {
3518
+ return value.success === true;
3573
3519
  }
3574
- function fastIdlePromise() {
3575
- return new Promise((resolve) => idle(resolve));
3520
+ function isSkip(value) {
3521
+ return value.skip === true;
3576
3522
  }
3577
3523
 
3578
- function nextTickIteration(amount, delay = "tick") {
3579
- let counter = 0;
3580
- const tickInterval = delay === "tick";
3581
- return () => {
3582
- counter++;
3583
- if (counter >= amount) {
3584
- counter = 0;
3585
- return new Promise((resolve) => {
3586
- if (tickInterval) {
3587
- fastIdle(resolve);
3588
- } else {
3589
- setTimeout(resolve, delay);
3590
- }
3591
- });
3524
+ function typeOf(value) {
3525
+ const type = typeof value;
3526
+ switch (type) {
3527
+ case "number":
3528
+ return isNumber(value) ? "number" : "unknown";
3529
+ case "object": {
3530
+ if (value === null) return "null";
3531
+ if (Array.isArray(value)) return "array";
3532
+ if (isSet(value)) return "set";
3533
+ if (isWeakSet(value)) return "weakset";
3534
+ if (isMap(value)) return "map";
3535
+ if (isWeakMap(value)) return "weakmap";
3536
+ if (isDate(value)) return "date";
3537
+ if (isObject(value)) return "object";
3538
+ return "unknown";
3592
3539
  }
3593
- return Promise.resolve();
3594
- };
3595
- }
3596
-
3597
- async function asyncFind(array, callbackfn) {
3598
- const cooldown = nextTickIteration(10);
3599
- let i = 0;
3600
- while (i < array.length) {
3601
- await cooldown();
3602
- const result = await callbackfn(array[i], i, array);
3603
- if (Boolean(result)) {
3604
- return array[i];
3540
+ default: {
3541
+ return type;
3605
3542
  }
3606
- i++;
3607
- }
3608
- return void 0;
3609
- }
3610
-
3611
- async function asyncForEach(array, callbackfn, { concurrency = 1 } = {}) {
3612
- const cooldown = nextTickIteration(10);
3613
- let i = 0;
3614
- const handle = (value, index) => {
3615
- return callbackfn(value, i + index, array);
3616
- };
3617
- while (i < array.length) {
3618
- await cooldown();
3619
- const batch = await Promise.all(
3620
- array.slice(i, i + concurrency).map(handle)
3621
- );
3622
- i += batch.length;
3623
3543
  }
3624
3544
  }
3625
3545
 
3626
- function defer() {
3627
- let resolve;
3628
- let reject;
3629
- const promise = new Promise((_resolve, _reject) => {
3630
- resolve = _resolve;
3631
- reject = _reject;
3632
- });
3633
- return {
3634
- resolve,
3635
- reject,
3636
- promise
3637
- };
3638
- }
3639
-
3640
- const onError = (error) => {
3641
- console.error(error);
3546
+ const qs = {
3547
+ toParams,
3548
+ stringify,
3549
+ stringifyValue,
3550
+ parse,
3551
+ parseValue,
3552
+ merge
3642
3553
  };
3643
- class SimpleEventEmitter {
3644
- #listeners = /* @__PURE__ */ new Map();
3645
- constructor() {
3646
- this.on("error", onError);
3647
- }
3648
- static once(emitter, eventName) {
3649
- const q = defer();
3650
- emitter.once(eventName, (...args) => q.resolve(args));
3651
- return q.promise;
3652
- }
3653
- emit(eventName, ...args) {
3654
- const set = this.#listeners.get(eventName);
3655
- if (!set) return false;
3656
- set.forEach((fn) => {
3657
- try {
3658
- const result = fn();
3659
- if (isPromise(result)) {
3660
- result.catch((err) => {
3661
- this.emit("error", err);
3662
- });
3554
+ function merge(...values) {
3555
+ const result = {};
3556
+ for (const filter of values) {
3557
+ for (const [key, value] of Object.entries(filter)) {
3558
+ const currentValue = result[key];
3559
+ const currentType = typeOf(currentValue);
3560
+ const filterType = typeOf(value);
3561
+ if (currentType !== filterType) {
3562
+ result[key] = value;
3563
+ continue;
3564
+ }
3565
+ switch (currentType) {
3566
+ case "array": {
3567
+ result[key] = Array.from(/* @__PURE__ */ new Set([...currentValue, ...value]));
3568
+ break;
3569
+ }
3570
+ case "object": {
3571
+ result[key] = {};
3572
+ deepAssign(result[key], currentValue);
3573
+ deepAssign(result[key], value);
3574
+ break;
3575
+ }
3576
+ case "map": {
3577
+ result[key] = new Map([
3578
+ ...Array.from(currentValue.entries()),
3579
+ ...Array.from(value.entries())
3580
+ ]);
3581
+ break;
3582
+ }
3583
+ case "set": {
3584
+ result[key] = /* @__PURE__ */ new Set([
3585
+ ...Array.from(currentValue),
3586
+ ...Array.from(value)
3587
+ ]);
3588
+ break;
3589
+ }
3590
+ default: {
3591
+ result[key] = value;
3663
3592
  }
3664
- } catch (err) {
3665
- this.emit("error", err);
3666
3593
  }
3667
- });
3668
- return true;
3669
- }
3670
- on(eventName, listener) {
3671
- if (!this.#listeners.has(eventName)) {
3672
- this.#listeners.set(eventName, /* @__PURE__ */ new Set());
3673
3594
  }
3674
- const set = this.#listeners.get(eventName);
3675
- set.add(listener);
3676
- return this;
3677
- }
3678
- once(eventName, listener) {
3679
- const wrapped = (...args) => {
3680
- this.off(eventName, wrapped);
3681
- listener(...args);
3682
- };
3683
- this.on(eventName, wrapped);
3684
- return this;
3685
3595
  }
3686
- off(eventName, listener) {
3687
- const set = this.#listeners.get(eventName);
3688
- if (set) {
3689
- set.delete(listener);
3690
- if (set.size === 0) {
3691
- this.#listeners.delete(eventName);
3692
- }
3596
+ return result;
3597
+ }
3598
+ function stringify(obj, options) {
3599
+ return new URLSearchParams(toParams(obj, options)).toString();
3600
+ }
3601
+ function toParams(obj, options) {
3602
+ const result = {};
3603
+ const excludeEmpty = options?.excludeEmpty !== false;
3604
+ const excludeDefaults = options?.excludeDefaults;
3605
+ for (const [key, value] of Object.entries(obj)) {
3606
+ if (excludeEmpty && isEmpty(value)) continue;
3607
+ if (excludeDefaults && key in excludeDefaults) {
3608
+ const defValue = excludeDefaults[key];
3609
+ if (isEqual(value, defValue)) continue;
3693
3610
  }
3694
- return this;
3695
- }
3696
- removeAllListeners(eventName) {
3697
- if (eventName === void 0) {
3698
- this.#listeners.clear();
3699
- return this;
3611
+ const strValue = stringifyValue(value);
3612
+ if (excludeEmpty && strValue === "") {
3613
+ continue;
3700
3614
  }
3701
- this.#listeners.delete(eventName);
3702
- return this;
3615
+ result[key] = strValue;
3703
3616
  }
3617
+ return result;
3704
3618
  }
3705
-
3706
- class Queue {
3707
- items = [];
3708
- #limit;
3709
- #events = new SimpleEventEmitter();
3710
- constructor(limit) {
3711
- this.#limit = limit;
3712
- }
3713
- async get() {
3714
- if (this.items.length === 0) {
3715
- await SimpleEventEmitter.once(this.#events, "put");
3716
- }
3717
- const item = this.items.shift();
3718
- this.#events.emit("get");
3719
- return item;
3619
+ function parse(value, defaults) {
3620
+ const objValue = isString(value) ? Object.fromEntries(new URLSearchParams(value).entries()) : value;
3621
+ if (!defaults) {
3622
+ return { ...objValue };
3720
3623
  }
3721
- async put(item) {
3722
- if (this.#limit && this.items.length >= this.#limit) {
3723
- await SimpleEventEmitter.once(this.#events, "get");
3624
+ const result = {};
3625
+ for (const [key, defValue] of Object.entries(defaults)) {
3626
+ const defType = typeOf(defValue);
3627
+ let parsedValue = parseValue(objValue[key], defType);
3628
+ if (parsedValue !== void 0 || defType === "undefined") {
3629
+ if (defType === "array" && defValue[0] !== void 0) {
3630
+ const itemValue = typeOf(defValue[0]);
3631
+ parsedValue = parsedValue.map((v) => parseValue(v, itemValue));
3632
+ }
3633
+ result[key] = parsedValue;
3634
+ } else {
3635
+ result[key] = defValue;
3724
3636
  }
3725
- this.items.push(item);
3726
- this.#events.emit("put");
3727
3637
  }
3638
+ return result;
3728
3639
  }
3729
-
3730
- class AsyncIterableQueue {
3731
- _queue;
3732
- _closed = false;
3733
- static QUEUE_END_MARKER = Symbol("QUEUE_END_MARKER");
3734
- constructor() {
3735
- this._queue = new Queue();
3736
- }
3737
- get closed() {
3738
- return this._closed;
3739
- }
3740
- put(item) {
3741
- if (this._closed) {
3742
- throw new Error("Queue is closed");
3640
+ function stringifyValue(value) {
3641
+ const valueType = typeOf(value);
3642
+ switch (valueType) {
3643
+ case "undefined": {
3644
+ return "";
3743
3645
  }
3744
- this._queue.put(item);
3745
- }
3746
- close() {
3747
- if (this._closed) return;
3748
- this._closed = true;
3749
- this._queue.put(AsyncIterableQueue.QUEUE_END_MARKER);
3750
- }
3751
- [Symbol.asyncIterator]() {
3752
- return {
3753
- next: async () => {
3754
- if (this._closed && this._queue.items.length === 0) {
3755
- return { value: void 0, done: true };
3756
- }
3757
- const item = await this._queue.get();
3758
- if (item === AsyncIterableQueue.QUEUE_END_MARKER && this._closed) {
3759
- return { value: void 0, done: true };
3646
+ case "null": {
3647
+ return "";
3648
+ }
3649
+ case "array": {
3650
+ let result = "";
3651
+ let sep = "";
3652
+ for (const item of value) {
3653
+ if (item === void 0) continue;
3654
+ if (isObject(item) || Array.isArray(item) || isString(item) && item.includes(",")) {
3655
+ result = JSON.stringify(value);
3656
+ break;
3657
+ } else {
3658
+ result += sep + stringifyValue(item);
3659
+ sep = ",";
3760
3660
  }
3761
- return { value: item, done: false };
3762
3661
  }
3763
- };
3764
- }
3765
- }
3766
-
3767
- async function asyncMap(array, callbackfn, { concurrency = 1 } = {}) {
3768
- let result = [];
3769
- concurrency = Math.max(concurrency, 1);
3770
- const cooldown = nextTickIteration(10);
3771
- let i = 0;
3772
- const handle = (value, index) => {
3773
- return callbackfn(value, i + index, array);
3774
- };
3775
- while (i < array.length) {
3776
- await cooldown();
3777
- const batch = await Promise.all(
3778
- array.slice(i, i + concurrency).map(handle)
3779
- );
3780
- result = result.concat(batch);
3781
- i += batch.length;
3662
+ return result;
3663
+ }
3664
+ case "date": {
3665
+ return value.toISOString();
3666
+ }
3667
+ case "map": {
3668
+ return JSON.stringify(Array.from(value.entries()));
3669
+ }
3670
+ case "set": {
3671
+ return JSON.stringify(Array.from(value.values()));
3672
+ }
3673
+ case "boolean":
3674
+ case "number":
3675
+ case "string":
3676
+ case "bigint": {
3677
+ return String(value);
3678
+ }
3679
+ case "object": {
3680
+ return JSON.stringify(value);
3681
+ }
3682
+ case "unknown": {
3683
+ if (isFunction(value?.toString)) {
3684
+ return value.toString();
3685
+ }
3686
+ }
3687
+ default: {
3688
+ throw new Error("Attempt to stringify unsupported type: " + valueType);
3689
+ }
3782
3690
  }
3783
- return result;
3784
3691
  }
3785
-
3786
- class CancellablePromise {
3787
- #promise;
3788
- #cancelFns;
3789
- #isCancelled = false;
3790
- #error = null;
3791
- constructor(executor) {
3792
- this.#cancelFns = [];
3793
- this.#promise = new Promise((resolve, reject) => {
3794
- executor(
3795
- resolve,
3796
- (reason) => {
3797
- this.#error = toError(reason, "Unknown rejection reason.");
3798
- reject(reason);
3799
- },
3800
- (fn) => {
3801
- this.#cancelFns.push(fn);
3802
- }
3803
- );
3804
- });
3805
- }
3806
- get [Symbol.toStringTag]() {
3807
- return this.#promise[Symbol.toStringTag] + (this.isCancelled ? " (Cancelled)" : "");
3808
- }
3809
- get isCancelled() {
3810
- return this.#isCancelled;
3811
- }
3812
- get error() {
3813
- return this.#error;
3814
- }
3815
- then(onfulfilled, onrejected) {
3816
- return this.#promise.then(onfulfilled, onrejected);
3817
- }
3818
- catch(onrejected) {
3819
- return this.#promise.catch(onrejected);
3820
- }
3821
- finally(onfinally) {
3822
- return this.#promise.finally(onfinally);
3692
+ function parseValue(value, asType) {
3693
+ const type = typeOf(value);
3694
+ if (type === asType) {
3695
+ return value;
3696
+ } else if (type !== "string") {
3697
+ return void 0;
3823
3698
  }
3824
- cancel() {
3825
- if (this.#isCancelled) return;
3826
- this.#isCancelled = true;
3827
- for (const fn of this.#cancelFns) {
3828
- catchError(fn);
3699
+ try {
3700
+ switch (asType) {
3701
+ case "undefined": {
3702
+ return void 0;
3703
+ }
3704
+ case "array": {
3705
+ if (value.startsWith("[") && value.endsWith("]")) {
3706
+ return JSON.parse(value);
3707
+ }
3708
+ return value.split(",");
3709
+ }
3710
+ case "boolean": {
3711
+ return value === "true";
3712
+ }
3713
+ case "date": {
3714
+ const parsed = new Date(value);
3715
+ return isDate(parsed) ? parsed : void 0;
3716
+ }
3717
+ case "map": {
3718
+ return new Map(JSON.parse(value));
3719
+ }
3720
+ case "number": {
3721
+ const parsed = parseFloat(value);
3722
+ return isNumber(parsed) ? parsed : void 0;
3723
+ }
3724
+ case "object": {
3725
+ return JSON.parse(value);
3726
+ }
3727
+ case "set": {
3728
+ return new Set(JSON.parse(value));
3729
+ }
3730
+ case "null": {
3731
+ return value === "" || value === void 0 ? null : void 0;
3732
+ }
3733
+ case "string": {
3734
+ return value;
3735
+ }
3736
+ case "bigint": {
3737
+ return BigInt(value);
3738
+ }
3829
3739
  }
3740
+ } catch (_) {
3830
3741
  }
3831
- static from(promise) {
3832
- return new CancellablePromise((resolve, reject) => {
3833
- promise.then(resolve).catch(reject);
3834
- });
3742
+ return void 0;
3743
+ }
3744
+
3745
+ function defer() {
3746
+ let resolve;
3747
+ let reject;
3748
+ const promise = new Promise((_resolve, _reject) => {
3749
+ resolve = _resolve;
3750
+ reject = _reject;
3751
+ });
3752
+ return {
3753
+ resolve,
3754
+ reject,
3755
+ promise
3756
+ };
3757
+ }
3758
+
3759
+ const defaultWindow$1 = globalThis?.window;
3760
+ const idle = (() => {
3761
+ if (defaultWindow$1?.requestIdleCallback) {
3762
+ return defaultWindow$1.requestIdleCallback;
3763
+ } else if (defaultWindow$1?.requestAnimationFrame) {
3764
+ return defaultWindow$1.requestAnimationFrame;
3765
+ } else if (isFunction(process?.nextTick)) {
3766
+ return process.nextTick;
3767
+ } else {
3768
+ return (fn) => setTimeout(fn, 0);
3835
3769
  }
3770
+ })();
3771
+ function fastIdle(callback) {
3772
+ return idle(callback);
3773
+ }
3774
+ function fastIdlePromise() {
3775
+ return new Promise((resolve) => idle(resolve));
3836
3776
  }
3837
3777
 
3838
3778
  function delay(amount = "tick") {
@@ -3845,352 +3785,546 @@ function delay(amount = "tick") {
3845
3785
  return d.promise;
3846
3786
  }
3847
3787
 
3848
- const FAST_RAF_TIMEOUT_FALLBACK_MS = 300;
3849
- const defaultWindow = globalThis?.window;
3850
- const raf = defaultWindow?.requestAnimationFrame || ((cb) => setTimeout(cb, 0));
3851
- let fastRafCallbacks;
3852
- let fastRafFallbackCallbacks;
3853
- let fastRafFallbackTimeout;
3854
- function fastRaf(callback, withTimeoutFallback = false) {
3855
- if (!fastRafCallbacks) {
3856
- fastRafCallbacks = /* @__PURE__ */ new Set([callback]);
3857
- raf(() => {
3858
- const currentCallbacks = fastRafCallbacks;
3859
- fastRafCallbacks = void 0;
3860
- fastRafFallbackCallbacks = void 0;
3861
- if (fastRafFallbackTimeout) {
3862
- clearTimeout(fastRafFallbackTimeout);
3863
- fastRafFallbackTimeout = void 0;
3864
- }
3865
- currentCallbacks.forEach((cb) => cb());
3866
- });
3867
- } else {
3868
- fastRafCallbacks.add(callback);
3869
- }
3870
- if (withTimeoutFallback) {
3871
- if (!fastRafFallbackCallbacks) {
3872
- fastRafFallbackCallbacks = /* @__PURE__ */ new Set([callback]);
3873
- } else {
3874
- fastRafFallbackCallbacks.add(callback);
3788
+ const noopShouldRetryBasedOnError = () => true;
3789
+ function retryOnError({
3790
+ beforeRetryCallback,
3791
+ shouldRetryBasedOnError = noopShouldRetryBasedOnError,
3792
+ maxRetriesNumber,
3793
+ delayFactor = 0,
3794
+ delayMaxMs = 1e3,
3795
+ delayMinMs = 100
3796
+ }, fn) {
3797
+ let retryCount = maxRetriesNumber;
3798
+ let delayMs = 0;
3799
+ delayMinMs = Math.max(delayMinMs, 1);
3800
+ delayMaxMs = Math.max(delayMaxMs, 1);
3801
+ const run = async (...args) => {
3802
+ if (delayFactor >= 1 && delayMs > 0) {
3803
+ await delay(delayMs);
3875
3804
  }
3876
- if (!fastRafFallbackTimeout) {
3877
- fastRafFallbackTimeout = setTimeout(() => {
3878
- const currentTimeoutCallbacks = fastRafFallbackCallbacks;
3879
- if (fastRafCallbacks) {
3880
- currentTimeoutCallbacks.forEach(
3881
- fastRafCallbacks.delete,
3882
- fastRafCallbacks
3805
+ const currentAttempt = 1 + maxRetriesNumber - retryCount;
3806
+ try {
3807
+ const res = await fn(...args);
3808
+ return res;
3809
+ } catch (e) {
3810
+ if (retryCount > 1 && shouldRetryBasedOnError(e, currentAttempt)) {
3811
+ retryCount--;
3812
+ delayMs = Math.floor(
3813
+ Math.min(Math.max(delayMs, delayMinMs) * delayFactor, delayMaxMs)
3814
+ );
3815
+ if (beforeRetryCallback) {
3816
+ const newParams = await beforeRetryCallback(
3817
+ currentAttempt,
3818
+ retryCount === 0
3883
3819
  );
3820
+ if (newParams) {
3821
+ return run(newParams);
3822
+ }
3884
3823
  }
3885
- fastRafFallbackCallbacks = void 0;
3886
- if (fastRafFallbackTimeout) {
3887
- clearTimeout(fastRafFallbackTimeout);
3888
- fastRafFallbackTimeout = void 0;
3889
- }
3890
- currentTimeoutCallbacks.forEach((cb) => cb());
3891
- }, FAST_RAF_TIMEOUT_FALLBACK_MS);
3824
+ return run(...args);
3825
+ }
3826
+ throw e;
3892
3827
  }
3893
- }
3894
- }
3895
- function rafPromise() {
3896
- return new Promise((resolve) => {
3897
- fastRaf(resolve);
3898
- });
3828
+ };
3829
+ return run;
3899
3830
  }
3900
3831
 
3901
- function timeout(ms, promiseOrCallback, timeoutError = new Error("Timeout")) {
3902
- const abortController = new AbortController();
3903
- let taskResult;
3904
- if (isFunction(promiseOrCallback)) {
3905
- taskResult = promiseOrCallback(abortController.signal);
3906
- } else if (isPromise(promiseOrCallback)) {
3907
- taskResult = promiseOrCallback;
3908
- } else {
3909
- throw new TypeError(
3910
- "Expected promise or callback as second argument, received: " + String(promiseOrCallback)
3911
- );
3912
- }
3913
- if (!isPromise(taskResult)) {
3914
- return Promise.resolve(taskResult);
3915
- }
3916
- let timer;
3917
- return Promise.race([
3918
- taskResult,
3919
- new Promise((_, reject) => {
3920
- timer = setTimeout(() => {
3921
- abortController.abort();
3922
- reject(timeoutError);
3923
- }, ms);
3924
- })
3925
- ]).finally(() => {
3926
- timer && clearTimeout(timer);
3927
- timer = void 0;
3928
- });
3832
+ function throttle(func, throttleMs, { signal, edges = ["leading", "trailing"] } = {}) {
3833
+ let pendingAt = null;
3834
+ const debounced = debounce(func, throttleMs, { signal, edges });
3835
+ const throttled = function(...args) {
3836
+ if (pendingAt == null) {
3837
+ pendingAt = Date.now();
3838
+ } else {
3839
+ if (Date.now() - pendingAt >= throttleMs) {
3840
+ pendingAt = Date.now();
3841
+ debounced.cancel();
3842
+ debounced(...args);
3843
+ }
3844
+ }
3845
+ debounced(...args);
3846
+ };
3847
+ throttled.cancel = debounced.cancel;
3848
+ throttled.flush = debounced.flush;
3849
+ return throttled;
3929
3850
  }
3930
3851
 
3931
- function typeOf(value) {
3932
- const type = typeof value;
3933
- switch (type) {
3934
- case "number":
3935
- return isNumber(value) ? "number" : "unknown";
3936
- case "object": {
3937
- if (value === null) return "null";
3938
- if (Array.isArray(value)) return "array";
3939
- if (isSet(value)) return "set";
3940
- if (isWeakSet(value)) return "weakset";
3941
- if (isMap(value)) return "map";
3942
- if (isWeakMap(value)) return "weakmap";
3943
- if (isDate(value)) return "date";
3944
- if (isObject(value)) return "object";
3945
- return "unknown";
3946
- }
3947
- default: {
3948
- return type;
3852
+ function sprintf(line, args, unusedArgs = []) {
3853
+ let result = "";
3854
+ const argsLen = args.length;
3855
+ const lineLen = line.length;
3856
+ let opened = false;
3857
+ let currentChar = -1;
3858
+ let lastPos = 0;
3859
+ let argsIndex = 0;
3860
+ for (let idx = 0; idx < lineLen; idx++) {
3861
+ currentChar = line.charCodeAt(idx);
3862
+ if (currentChar === 37) {
3863
+ opened = true;
3864
+ continue;
3949
3865
  }
3950
- }
3951
- }
3952
-
3953
- const qs = {
3954
- toParams,
3955
- stringify,
3956
- stringifyValue,
3957
- parse,
3958
- parseValue,
3959
- merge
3960
- };
3961
- function merge(...values) {
3962
- const result = {};
3963
- for (const filter of values) {
3964
- for (const [key, value] of Object.entries(filter)) {
3965
- const currentValue = result[key];
3966
- const currentType = typeOf(currentValue);
3967
- const filterType = typeOf(value);
3968
- if (currentType !== filterType) {
3969
- result[key] = value;
3970
- continue;
3866
+ if (!opened) continue;
3867
+ opened = false;
3868
+ switch (currentChar) {
3869
+ // 'd'
3870
+ case 100:
3871
+ // 'f'
3872
+ case 102: {
3873
+ result += line.slice(lastPos, idx - 1);
3874
+ result += Number(args[argsIndex]);
3875
+ lastPos = idx + 1;
3876
+ argsIndex++;
3877
+ break;
3971
3878
  }
3972
- switch (currentType) {
3973
- case "array": {
3974
- result[key] = Array.from(/* @__PURE__ */ new Set([...currentValue, ...value]));
3975
- break;
3976
- }
3977
- case "object": {
3978
- result[key] = {};
3979
- deepAssign(result[key], currentValue);
3980
- deepAssign(result[key], value);
3981
- break;
3982
- }
3983
- case "map": {
3984
- result[key] = new Map([
3985
- ...Array.from(currentValue.entries()),
3986
- ...Array.from(value.entries())
3987
- ]);
3988
- break;
3989
- }
3990
- case "set": {
3991
- result[key] = /* @__PURE__ */ new Set([
3992
- ...Array.from(currentValue),
3993
- ...Array.from(value)
3994
- ]);
3995
- break;
3996
- }
3997
- default: {
3998
- result[key] = value;
3999
- }
3879
+ // 'i'
3880
+ case 105: {
3881
+ result += line.slice(lastPos, idx - 1);
3882
+ result += Math.floor(Number(args[argsIndex]));
3883
+ lastPos = idx + 1;
3884
+ argsIndex++;
3885
+ break;
3886
+ }
3887
+ // 'O'
3888
+ case 79:
3889
+ // 'o'
3890
+ case 111:
3891
+ // 'j'
3892
+ case 106: {
3893
+ result += line.slice(lastPos, idx - 1);
3894
+ result += tryStringify(args[argsIndex]);
3895
+ lastPos = idx + 1;
3896
+ argsIndex++;
3897
+ break;
3898
+ }
3899
+ // 's'
3900
+ case 115: {
3901
+ result += line.slice(lastPos, idx - 1);
3902
+ result += String(args[argsIndex]);
3903
+ lastPos = idx + 1;
3904
+ argsIndex++;
3905
+ break;
4000
3906
  }
4001
3907
  }
3908
+ if (argsIndex >= argsLen) break;
3909
+ }
3910
+ if (lastPos < lineLen) {
3911
+ result += line.slice(lastPos, lineLen);
3912
+ }
3913
+ if (argsIndex < argsLen) {
3914
+ unusedArgs.push(...args.slice(argsIndex, argsLen));
4002
3915
  }
4003
3916
  return result;
4004
3917
  }
4005
- function stringify(obj, options) {
4006
- return new URLSearchParams(toParams(obj, options)).toString();
4007
- }
4008
- function toParams(obj, options) {
4009
- const result = {};
4010
- const excludeEmpty = options?.excludeEmpty !== false;
4011
- const excludeDefaults = options?.excludeDefaults;
4012
- for (const [key, value] of Object.entries(obj)) {
4013
- if (excludeEmpty && isEmpty(value)) continue;
4014
- if (excludeDefaults && key in excludeDefaults) {
4015
- const defValue = excludeDefaults[key];
4016
- if (isEqual(value, defValue)) continue;
3918
+ function tryStringify(o) {
3919
+ switch (typeof o) {
3920
+ case "function": {
3921
+ return o.name || "<anonymous>";
4017
3922
  }
4018
- const strValue = stringifyValue(value);
4019
- if (excludeEmpty && strValue === "") {
4020
- continue;
3923
+ case "string": {
3924
+ return "'" + o + "'";
3925
+ }
3926
+ default: {
3927
+ try {
3928
+ return JSON.stringify(o);
3929
+ } catch (e) {
3930
+ return '"[Circular]"';
3931
+ }
4021
3932
  }
4022
- result[key] = strValue;
4023
3933
  }
4024
- return result;
4025
3934
  }
4026
- function parse(value, defaults) {
4027
- const objValue = isString(value) ? Object.fromEntries(new URLSearchParams(value).entries()) : value;
4028
- if (!defaults) {
4029
- return { ...objValue };
3935
+
3936
+ const LEVEL_NUM = {
3937
+ debug: 0,
3938
+ log: 1,
3939
+ info: 2,
3940
+ warn: 3,
3941
+ error: 4
3942
+ };
3943
+ let currentLogLevel = LEVEL_NUM.log;
3944
+ const loggerSetLevel = (level) => {
3945
+ number$1(LEVEL_NUM[level], `Invalid log level: ${level}`);
3946
+ currentLogLevel = LEVEL_NUM[level];
3947
+ };
3948
+ const logger = (...baseArgs) => {
3949
+ if (isString(baseArgs[0]?.url)) {
3950
+ baseArgs[0] = baseArgs[0]?.url;
4030
3951
  }
4031
- const result = {};
4032
- for (const [key, defValue] of Object.entries(defaults)) {
4033
- const defType = typeOf(defValue);
4034
- let parsedValue = parseValue(objValue[key], defType);
4035
- if (parsedValue !== void 0 || defType === "undefined") {
4036
- if (defType === "array" && defValue[0] !== void 0) {
4037
- const itemValue = typeOf(defValue[0]);
4038
- parsedValue = parsedValue.map((v) => parseValue(v, itemValue));
4039
- }
4040
- result[key] = parsedValue;
4041
- } else {
4042
- result[key] = defValue;
3952
+ if (typeof baseArgs[0] === "string" && baseArgs[0][0] !== "[") {
3953
+ baseArgs[0] = `[${baseArgs[0].split("/").at(-1).split("?", 1)[0]}]`;
3954
+ }
3955
+ const writeLog = (level, ...[pattern, ...args]) => {
3956
+ const levelNum = LEVEL_NUM[level];
3957
+ if (levelNum < currentLogLevel) {
3958
+ return;
3959
+ }
3960
+ if (!isString(pattern)) {
3961
+ console[level](...baseArgs, pattern, ...args);
3962
+ return;
3963
+ }
3964
+ const unusedArgs = [];
3965
+ const formatted = sprintf(pattern, args, unusedArgs);
3966
+ console[level](...baseArgs, formatted, ...unusedArgs);
3967
+ };
3968
+ const log = writeLog.bind(null, "log");
3969
+ const info = writeLog.bind(null, "info");
3970
+ const warn = writeLog.bind(null, "warn");
3971
+ const error = writeLog.bind(null, "error");
3972
+ const debug = writeLog.bind(null, "debug");
3973
+ const extend = (...args) => {
3974
+ return logger(...baseArgs, ...args);
3975
+ };
3976
+ const instance = {
3977
+ log,
3978
+ info,
3979
+ warn,
3980
+ error,
3981
+ debug,
3982
+ extend
3983
+ };
3984
+ return instance;
3985
+ };
3986
+
3987
+ async function asyncFilter(array, predicate) {
3988
+ const result = [];
3989
+ const cooldown = nextTickIteration(10);
3990
+ for (let idx = 0; idx < array.length; idx++) {
3991
+ await cooldown();
3992
+ const value = array[idx];
3993
+ const valid = await predicate(value, idx, array);
3994
+ if (valid) {
3995
+ result.push(value);
4043
3996
  }
4044
3997
  }
4045
3998
  return result;
4046
3999
  }
4047
- function stringifyValue(value) {
4048
- const valueType = typeOf(value);
4049
- switch (valueType) {
4050
- case "undefined": {
4051
- return "";
4052
- }
4053
- case "null": {
4054
- return "";
4055
- }
4056
- case "array": {
4057
- let result = "";
4058
- let sep = "";
4059
- for (const item of value) {
4060
- if (item === void 0) continue;
4061
- if (isObject(item) || Array.isArray(item) || isString(item) && item.includes(",")) {
4062
- result = JSON.stringify(value);
4063
- break;
4000
+
4001
+ function nextTickIteration(amount, delay = "tick") {
4002
+ let counter = 0;
4003
+ const tickInterval = delay === "tick";
4004
+ return () => {
4005
+ counter++;
4006
+ if (counter >= amount) {
4007
+ counter = 0;
4008
+ return new Promise((resolve) => {
4009
+ if (tickInterval) {
4010
+ fastIdle(resolve);
4064
4011
  } else {
4065
- result += sep + stringifyValue(item);
4066
- sep = ",";
4012
+ setTimeout(resolve, delay);
4067
4013
  }
4068
- }
4069
- return result;
4070
- }
4071
- case "date": {
4072
- return value.toISOString();
4014
+ });
4073
4015
  }
4074
- case "map": {
4075
- return JSON.stringify(Array.from(value.entries()));
4016
+ return Promise.resolve();
4017
+ };
4018
+ }
4019
+
4020
+ async function asyncFind(array, callbackfn) {
4021
+ const cooldown = nextTickIteration(10);
4022
+ let i = 0;
4023
+ while (i < array.length) {
4024
+ await cooldown();
4025
+ const result = await callbackfn(array[i], i, array);
4026
+ if (Boolean(result)) {
4027
+ return array[i];
4076
4028
  }
4077
- case "set": {
4078
- return JSON.stringify(Array.from(value.values()));
4029
+ i++;
4030
+ }
4031
+ return void 0;
4032
+ }
4033
+
4034
+ async function asyncForEach(array, callbackfn, { concurrency = 1 } = {}) {
4035
+ const cooldown = nextTickIteration(10);
4036
+ let i = 0;
4037
+ const handle = (value, index) => {
4038
+ return callbackfn(value, i + index, array);
4039
+ };
4040
+ while (i < array.length) {
4041
+ await cooldown();
4042
+ const batch = await Promise.all(
4043
+ array.slice(i, i + concurrency).map(handle)
4044
+ );
4045
+ i += batch.length;
4046
+ }
4047
+ }
4048
+
4049
+ const onError = (error) => {
4050
+ console.error(error);
4051
+ };
4052
+ class SimpleEventEmitter {
4053
+ #listeners = /* @__PURE__ */ new Map();
4054
+ constructor() {
4055
+ this.on("error", onError);
4056
+ }
4057
+ static once(emitter, eventName) {
4058
+ const q = defer();
4059
+ emitter.once(eventName, (...args) => q.resolve(args));
4060
+ return q.promise;
4061
+ }
4062
+ emit(eventName, ...args) {
4063
+ const set = this.#listeners.get(eventName);
4064
+ if (!set) return false;
4065
+ set.forEach((fn) => {
4066
+ try {
4067
+ const result = fn();
4068
+ if (isPromise(result)) {
4069
+ result.catch((err) => {
4070
+ this.emit("error", err);
4071
+ });
4072
+ }
4073
+ } catch (err) {
4074
+ this.emit("error", err);
4075
+ }
4076
+ });
4077
+ return true;
4078
+ }
4079
+ on(eventName, listener) {
4080
+ if (!this.#listeners.has(eventName)) {
4081
+ this.#listeners.set(eventName, /* @__PURE__ */ new Set());
4079
4082
  }
4080
- case "boolean":
4081
- case "number":
4082
- case "string":
4083
- case "bigint": {
4084
- return String(value);
4083
+ const set = this.#listeners.get(eventName);
4084
+ set.add(listener);
4085
+ return this;
4086
+ }
4087
+ once(eventName, listener) {
4088
+ const wrapped = (...args) => {
4089
+ this.off(eventName, wrapped);
4090
+ listener(...args);
4091
+ };
4092
+ this.on(eventName, wrapped);
4093
+ return this;
4094
+ }
4095
+ off(eventName, listener) {
4096
+ const set = this.#listeners.get(eventName);
4097
+ if (set) {
4098
+ set.delete(listener);
4099
+ if (set.size === 0) {
4100
+ this.#listeners.delete(eventName);
4101
+ }
4085
4102
  }
4086
- case "object": {
4087
- return JSON.stringify(value);
4103
+ return this;
4104
+ }
4105
+ removeAllListeners(eventName) {
4106
+ if (eventName === void 0) {
4107
+ this.#listeners.clear();
4108
+ return this;
4088
4109
  }
4089
- case "unknown": {
4090
- if (isFunction(value?.toString)) {
4091
- return value.toString();
4092
- }
4110
+ this.#listeners.delete(eventName);
4111
+ return this;
4112
+ }
4113
+ }
4114
+
4115
+ class Queue {
4116
+ items = [];
4117
+ #limit;
4118
+ #events = new SimpleEventEmitter();
4119
+ constructor(limit) {
4120
+ this.#limit = limit;
4121
+ }
4122
+ async get() {
4123
+ if (this.items.length === 0) {
4124
+ await SimpleEventEmitter.once(this.#events, "put");
4093
4125
  }
4094
- default: {
4095
- throw new Error("Attempt to stringify unsupported type: " + valueType);
4126
+ const item = this.items.shift();
4127
+ this.#events.emit("get");
4128
+ return item;
4129
+ }
4130
+ async put(item) {
4131
+ if (this.#limit && this.items.length >= this.#limit) {
4132
+ await SimpleEventEmitter.once(this.#events, "get");
4096
4133
  }
4134
+ this.items.push(item);
4135
+ this.#events.emit("put");
4097
4136
  }
4098
4137
  }
4099
- function parseValue(value, asType) {
4100
- const type = typeOf(value);
4101
- if (type === asType) {
4102
- return value;
4103
- } else if (type !== "string") {
4104
- return void 0;
4138
+
4139
+ class AsyncIterableQueue {
4140
+ _queue;
4141
+ _closed = false;
4142
+ static QUEUE_END_MARKER = Symbol("QUEUE_END_MARKER");
4143
+ constructor() {
4144
+ this._queue = new Queue();
4105
4145
  }
4106
- try {
4107
- switch (asType) {
4108
- case "undefined": {
4109
- return void 0;
4110
- }
4111
- case "array": {
4112
- if (value.startsWith("[") && value.endsWith("]")) {
4113
- return JSON.parse(value);
4146
+ get closed() {
4147
+ return this._closed;
4148
+ }
4149
+ put(item) {
4150
+ if (this._closed) {
4151
+ throw new Error("Queue is closed");
4152
+ }
4153
+ this._queue.put(item);
4154
+ }
4155
+ close() {
4156
+ if (this._closed) return;
4157
+ this._closed = true;
4158
+ this._queue.put(AsyncIterableQueue.QUEUE_END_MARKER);
4159
+ }
4160
+ [Symbol.asyncIterator]() {
4161
+ return {
4162
+ next: async () => {
4163
+ if (this._closed && this._queue.items.length === 0) {
4164
+ return { value: void 0, done: true };
4114
4165
  }
4115
- return value.split(",");
4116
- }
4117
- case "boolean": {
4118
- return value === "true";
4119
- }
4120
- case "date": {
4121
- const parsed = new Date(value);
4122
- return isDate(parsed) ? parsed : void 0;
4123
- }
4124
- case "map": {
4125
- return new Map(JSON.parse(value));
4126
- }
4127
- case "number": {
4128
- const parsed = parseFloat(value);
4129
- return isNumber(parsed) ? parsed : void 0;
4130
- }
4131
- case "object": {
4132
- return JSON.parse(value);
4133
- }
4134
- case "set": {
4135
- return new Set(JSON.parse(value));
4136
- }
4137
- case "null": {
4138
- return value === "" || value === void 0 ? null : void 0;
4139
- }
4140
- case "string": {
4141
- return value;
4142
- }
4143
- case "bigint": {
4144
- return BigInt(value);
4166
+ const item = await this._queue.get();
4167
+ if (item === AsyncIterableQueue.QUEUE_END_MARKER && this._closed) {
4168
+ return { value: void 0, done: true };
4169
+ }
4170
+ return { value: item, done: false };
4145
4171
  }
4172
+ };
4173
+ }
4174
+ }
4175
+
4176
+ async function asyncMap(array, callbackfn, { concurrency = 1 } = {}) {
4177
+ let result = [];
4178
+ concurrency = Math.max(concurrency, 1);
4179
+ const cooldown = nextTickIteration(10);
4180
+ let i = 0;
4181
+ const handle = (value, index) => {
4182
+ return callbackfn(value, i + index, array);
4183
+ };
4184
+ while (i < array.length) {
4185
+ await cooldown();
4186
+ const batch = await Promise.all(
4187
+ array.slice(i, i + concurrency).map(handle)
4188
+ );
4189
+ result = result.concat(batch);
4190
+ i += batch.length;
4191
+ }
4192
+ return result;
4193
+ }
4194
+
4195
+ class CancellablePromise {
4196
+ #promise;
4197
+ #cancelFns;
4198
+ #isCancelled = false;
4199
+ #error = null;
4200
+ constructor(executor) {
4201
+ this.#cancelFns = [];
4202
+ this.#promise = new Promise((resolve, reject) => {
4203
+ executor(
4204
+ resolve,
4205
+ (reason) => {
4206
+ this.#error = toError(reason, "Unknown rejection reason.");
4207
+ reject(reason);
4208
+ },
4209
+ (fn) => {
4210
+ this.#cancelFns.push(fn);
4211
+ }
4212
+ );
4213
+ });
4214
+ }
4215
+ get [Symbol.toStringTag]() {
4216
+ return this.#promise[Symbol.toStringTag] + (this.isCancelled ? " (Cancelled)" : "");
4217
+ }
4218
+ get isCancelled() {
4219
+ return this.#isCancelled;
4220
+ }
4221
+ get error() {
4222
+ return this.#error;
4223
+ }
4224
+ then(onfulfilled, onrejected) {
4225
+ return this.#promise.then(onfulfilled, onrejected);
4226
+ }
4227
+ catch(onrejected) {
4228
+ return this.#promise.catch(onrejected);
4229
+ }
4230
+ finally(onfinally) {
4231
+ return this.#promise.finally(onfinally);
4232
+ }
4233
+ cancel() {
4234
+ if (this.#isCancelled) return;
4235
+ this.#isCancelled = true;
4236
+ for (const fn of this.#cancelFns) {
4237
+ catchError(fn);
4146
4238
  }
4147
- } catch (_) {
4148
4239
  }
4149
- return void 0;
4240
+ static from(promise) {
4241
+ return new CancellablePromise((resolve, reject) => {
4242
+ promise.then(resolve).catch(reject);
4243
+ });
4244
+ }
4150
4245
  }
4151
4246
 
4152
- const noopShouldRetryBasedOnError = () => true;
4153
- function retryOnError({
4154
- beforeRetryCallback,
4155
- shouldRetryBasedOnError = noopShouldRetryBasedOnError,
4156
- maxRetriesNumber,
4157
- delayFactor = 0,
4158
- delayMaxMs = 1e3,
4159
- delayMinMs = 100
4160
- }, fn) {
4161
- let retryCount = maxRetriesNumber;
4162
- let delayMs = 0;
4163
- delayMinMs = Math.max(delayMinMs, 1);
4164
- delayMaxMs = Math.max(delayMaxMs, 1);
4165
- const run = async (...args) => {
4166
- if (delayFactor >= 1 && delayMs > 0) {
4167
- await delay(delayMs);
4247
+ const FAST_RAF_TIMEOUT_FALLBACK_MS = 300;
4248
+ const defaultWindow = globalThis?.window;
4249
+ const raf = defaultWindow?.requestAnimationFrame || ((cb) => setTimeout(cb, 0));
4250
+ let fastRafCallbacks;
4251
+ let fastRafFallbackCallbacks;
4252
+ let fastRafFallbackTimeout;
4253
+ function fastRaf(callback, withTimeoutFallback = false) {
4254
+ if (!fastRafCallbacks) {
4255
+ fastRafCallbacks = /* @__PURE__ */ new Set([callback]);
4256
+ raf(() => {
4257
+ const currentCallbacks = fastRafCallbacks;
4258
+ fastRafCallbacks = void 0;
4259
+ fastRafFallbackCallbacks = void 0;
4260
+ if (fastRafFallbackTimeout) {
4261
+ clearTimeout(fastRafFallbackTimeout);
4262
+ fastRafFallbackTimeout = void 0;
4263
+ }
4264
+ currentCallbacks.forEach((cb) => cb());
4265
+ });
4266
+ } else {
4267
+ fastRafCallbacks.add(callback);
4268
+ }
4269
+ if (withTimeoutFallback) {
4270
+ if (!fastRafFallbackCallbacks) {
4271
+ fastRafFallbackCallbacks = /* @__PURE__ */ new Set([callback]);
4272
+ } else {
4273
+ fastRafFallbackCallbacks.add(callback);
4168
4274
  }
4169
- const currentAttempt = 1 + maxRetriesNumber - retryCount;
4170
- try {
4171
- const res = await fn(...args);
4172
- return res;
4173
- } catch (e) {
4174
- if (retryCount > 1 && shouldRetryBasedOnError(e, currentAttempt)) {
4175
- retryCount--;
4176
- delayMs = Math.floor(
4177
- Math.min(Math.max(delayMs, delayMinMs) * delayFactor, delayMaxMs)
4178
- );
4179
- if (beforeRetryCallback) {
4180
- const newParams = await beforeRetryCallback(
4181
- currentAttempt,
4182
- retryCount === 0
4275
+ if (!fastRafFallbackTimeout) {
4276
+ fastRafFallbackTimeout = setTimeout(() => {
4277
+ const currentTimeoutCallbacks = fastRafFallbackCallbacks;
4278
+ if (fastRafCallbacks) {
4279
+ currentTimeoutCallbacks.forEach(
4280
+ fastRafCallbacks.delete,
4281
+ fastRafCallbacks
4183
4282
  );
4184
- if (newParams) {
4185
- return run(newParams);
4186
- }
4187
4283
  }
4188
- return run(...args);
4189
- }
4190
- throw e;
4284
+ fastRafFallbackCallbacks = void 0;
4285
+ if (fastRafFallbackTimeout) {
4286
+ clearTimeout(fastRafFallbackTimeout);
4287
+ fastRafFallbackTimeout = void 0;
4288
+ }
4289
+ currentTimeoutCallbacks.forEach((cb) => cb());
4290
+ }, FAST_RAF_TIMEOUT_FALLBACK_MS);
4191
4291
  }
4192
- };
4193
- return run;
4292
+ }
4293
+ }
4294
+ function rafPromise() {
4295
+ return new Promise((resolve) => {
4296
+ fastRaf(resolve);
4297
+ });
4298
+ }
4299
+
4300
+ function timeout(ms, promiseOrCallback, timeoutError = new AppError(408)) {
4301
+ const abortController = new AbortController();
4302
+ let taskResult;
4303
+ if (isFunction(promiseOrCallback)) {
4304
+ taskResult = promiseOrCallback(abortController.signal);
4305
+ } else if (isPromise(promiseOrCallback)) {
4306
+ taskResult = promiseOrCallback;
4307
+ } else {
4308
+ throw new TypeError(
4309
+ "Expected promise or callback as second argument, received: " + String(promiseOrCallback)
4310
+ );
4311
+ }
4312
+ if (!isPromise(taskResult)) {
4313
+ return Promise.resolve(taskResult);
4314
+ }
4315
+ let timer;
4316
+ return Promise.race([
4317
+ taskResult,
4318
+ new Promise((_, reject) => {
4319
+ timer = setTimeout(() => {
4320
+ abortController.abort();
4321
+ reject(timeoutError);
4322
+ }, ms);
4323
+ })
4324
+ ]).finally(() => {
4325
+ timer && clearTimeout(timer);
4326
+ timer = void 0;
4327
+ });
4194
4328
  }
4195
4329
 
4196
4330
  function capitalize(str) {
@@ -4497,6 +4631,7 @@ exports.createWithCache = createWithCache;
4497
4631
  exports.cssVariable = cssVariable;
4498
4632
  exports.dateInDays = dateInDays;
4499
4633
  exports.dateInSeconds = dateInSeconds;
4634
+ exports.debounce = debounce;
4500
4635
  exports.deepAssign = deepAssign;
4501
4636
  exports.deepClone = deepClone;
4502
4637
  exports.deepCloneWith = deepCloneWith;
@@ -4561,6 +4696,7 @@ exports.isOneEmoji = isOneEmoji;
4561
4696
  exports.isPlainObject = isPlainObject;
4562
4697
  exports.isPrimitive = isPrimitive;
4563
4698
  exports.isPromise = isPromise;
4699
+ exports.isRegExp = isRegExp;
4564
4700
  exports.isSet = isSet;
4565
4701
  exports.isSkip = isSkip;
4566
4702
  exports.isString = isString;
@@ -4610,6 +4746,7 @@ exports.sprintf = sprintf;
4610
4746
  exports.startCase = startCase;
4611
4747
  exports.strAssign = strAssign;
4612
4748
  exports.sum = sum;
4749
+ exports.throttle = throttle;
4613
4750
  exports.timeFromMinutes = timeFromMinutes;
4614
4751
  exports.timeStringify = timeStringify;
4615
4752
  exports.timeToMinutes = timeToMinutes;