@whitesev/utils 2.6.6 → 2.6.7

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.umd.js CHANGED
@@ -3724,7 +3724,7 @@
3724
3724
  * 解锁
3725
3725
  */
3726
3726
  this.unlock = function () {
3727
- setTimeout(() => {
3727
+ utils.workerSetTimeout(() => {
3728
3728
  that.#flag = false;
3729
3729
  }, that.#delayTime);
3730
3730
  };
@@ -4607,6 +4607,251 @@
4607
4607
  }
4608
4608
  }
4609
4609
 
4610
+ const createCache = (lastNumberWeakMap) => {
4611
+ return (collection, nextNumber) => {
4612
+ lastNumberWeakMap.set(collection, nextNumber);
4613
+ return nextNumber;
4614
+ };
4615
+ };
4616
+
4617
+ /*
4618
+ * The value of the constant Number.MAX_SAFE_INTEGER equals (2 ** 53 - 1) but it
4619
+ * is fairly new.
4620
+ */
4621
+ const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER === undefined ? 9007199254740991 : Number.MAX_SAFE_INTEGER;
4622
+ const TWO_TO_THE_POWER_OF_TWENTY_NINE = 536870912;
4623
+ const TWO_TO_THE_POWER_OF_THIRTY = TWO_TO_THE_POWER_OF_TWENTY_NINE * 2;
4624
+ const createGenerateUniqueNumber = (cache, lastNumberWeakMap) => {
4625
+ return (collection) => {
4626
+ const lastNumber = lastNumberWeakMap.get(collection);
4627
+ /*
4628
+ * Let's try the cheapest algorithm first. It might fail to produce a new
4629
+ * number, but it is so cheap that it is okay to take the risk. Just
4630
+ * increase the last number by one or reset it to 0 if we reached the upper
4631
+ * bound of SMIs (which stands for small integers). When the last number is
4632
+ * unknown it is assumed that the collection contains zero based consecutive
4633
+ * numbers.
4634
+ */
4635
+ let nextNumber = lastNumber === undefined ? collection.size : lastNumber < TWO_TO_THE_POWER_OF_THIRTY ? lastNumber + 1 : 0;
4636
+ if (!collection.has(nextNumber)) {
4637
+ return cache(collection, nextNumber);
4638
+ }
4639
+ /*
4640
+ * If there are less than half of 2 ** 30 numbers stored in the collection,
4641
+ * the chance to generate a new random number in the range from 0 to 2 ** 30
4642
+ * is at least 50%. It's benifitial to use only SMIs because they perform
4643
+ * much better in any environment based on V8.
4644
+ */
4645
+ if (collection.size < TWO_TO_THE_POWER_OF_TWENTY_NINE) {
4646
+ while (collection.has(nextNumber)) {
4647
+ nextNumber = Math.floor(Math.random() * TWO_TO_THE_POWER_OF_THIRTY);
4648
+ }
4649
+ return cache(collection, nextNumber);
4650
+ }
4651
+ // Quickly check if there is a theoretical chance to generate a new number.
4652
+ if (collection.size > MAX_SAFE_INTEGER) {
4653
+ throw new Error('Congratulations, you created a collection of unique numbers which uses all available integers!');
4654
+ }
4655
+ // Otherwise use the full scale of safely usable integers.
4656
+ while (collection.has(nextNumber)) {
4657
+ nextNumber = Math.floor(Math.random() * MAX_SAFE_INTEGER);
4658
+ }
4659
+ return cache(collection, nextNumber);
4660
+ };
4661
+ };
4662
+
4663
+ const LAST_NUMBER_WEAK_MAP = new WeakMap();
4664
+ const cache = createCache(LAST_NUMBER_WEAK_MAP);
4665
+ const generateUniqueNumber = createGenerateUniqueNumber(cache, LAST_NUMBER_WEAK_MAP);
4666
+
4667
+ const isMessagePort = (sender) => {
4668
+ return typeof sender.start === 'function';
4669
+ };
4670
+
4671
+ const PORT_MAP = new WeakMap();
4672
+
4673
+ const extendBrokerImplementation = (partialBrokerImplementation) => ({
4674
+ ...partialBrokerImplementation,
4675
+ connect: ({ call }) => {
4676
+ return async () => {
4677
+ const { port1, port2 } = new MessageChannel();
4678
+ const portId = await call('connect', { port: port1 }, [port1]);
4679
+ PORT_MAP.set(port2, portId);
4680
+ return port2;
4681
+ };
4682
+ },
4683
+ disconnect: ({ call }) => {
4684
+ return async (port) => {
4685
+ const portId = PORT_MAP.get(port);
4686
+ if (portId === undefined) {
4687
+ throw new Error('The given port is not connected.');
4688
+ }
4689
+ await call('disconnect', { portId });
4690
+ };
4691
+ },
4692
+ isSupported: ({ call }) => {
4693
+ return () => call('isSupported');
4694
+ }
4695
+ });
4696
+
4697
+ const ONGOING_REQUESTS = new WeakMap();
4698
+ const createOrGetOngoingRequests = (sender) => {
4699
+ if (ONGOING_REQUESTS.has(sender)) {
4700
+ // @todo TypeScript needs to be convinced that has() works as expected.
4701
+ return ONGOING_REQUESTS.get(sender);
4702
+ }
4703
+ const ongoingRequests = new Map();
4704
+ ONGOING_REQUESTS.set(sender, ongoingRequests);
4705
+ return ongoingRequests;
4706
+ };
4707
+ const createBroker = (brokerImplementation) => {
4708
+ const fullBrokerImplementation = extendBrokerImplementation(brokerImplementation);
4709
+ return (sender) => {
4710
+ const ongoingRequests = createOrGetOngoingRequests(sender);
4711
+ sender.addEventListener('message', (({ data: message }) => {
4712
+ const { id } = message;
4713
+ if (id !== null && ongoingRequests.has(id)) {
4714
+ const { reject, resolve } = ongoingRequests.get(id);
4715
+ ongoingRequests.delete(id);
4716
+ if (message.error === undefined) {
4717
+ resolve(message.result);
4718
+ }
4719
+ else {
4720
+ reject(new Error(message.error.message));
4721
+ }
4722
+ }
4723
+ }));
4724
+ if (isMessagePort(sender)) {
4725
+ sender.start();
4726
+ }
4727
+ const call = (method, params = null, transferables = []) => {
4728
+ return new Promise((resolve, reject) => {
4729
+ const id = generateUniqueNumber(ongoingRequests);
4730
+ ongoingRequests.set(id, { reject, resolve });
4731
+ if (params === null) {
4732
+ sender.postMessage({ id, method }, transferables);
4733
+ }
4734
+ else {
4735
+ sender.postMessage({ id, method, params }, transferables);
4736
+ }
4737
+ });
4738
+ };
4739
+ const notify = (method, params, transferables = []) => {
4740
+ sender.postMessage({ id: null, method, params }, transferables);
4741
+ };
4742
+ let functions = {};
4743
+ for (const [key, handler] of Object.entries(fullBrokerImplementation)) {
4744
+ functions = { ...functions, [key]: handler({ call, notify }) };
4745
+ }
4746
+ return { ...functions };
4747
+ };
4748
+ };
4749
+
4750
+ // Prefilling the Maps with a function indexed by zero is necessary to be compliant with the specification.
4751
+ const scheduledIntervalsState = new Map([[0, null]]); // tslint:disable-line no-empty
4752
+ const scheduledTimeoutsState = new Map([[0, null]]); // tslint:disable-line no-empty
4753
+ const wrap = createBroker({
4754
+ clearInterval: ({ call }) => {
4755
+ return (timerId) => {
4756
+ if (typeof scheduledIntervalsState.get(timerId) === 'symbol') {
4757
+ scheduledIntervalsState.set(timerId, null);
4758
+ call('clear', { timerId, timerType: 'interval' }).then(() => {
4759
+ scheduledIntervalsState.delete(timerId);
4760
+ });
4761
+ }
4762
+ };
4763
+ },
4764
+ clearTimeout: ({ call }) => {
4765
+ return (timerId) => {
4766
+ if (typeof scheduledTimeoutsState.get(timerId) === 'symbol') {
4767
+ scheduledTimeoutsState.set(timerId, null);
4768
+ call('clear', { timerId, timerType: 'timeout' }).then(() => {
4769
+ scheduledTimeoutsState.delete(timerId);
4770
+ });
4771
+ }
4772
+ };
4773
+ },
4774
+ setInterval: ({ call }) => {
4775
+ return (func, delay = 0, ...args) => {
4776
+ const symbol = Symbol();
4777
+ const timerId = generateUniqueNumber(scheduledIntervalsState);
4778
+ scheduledIntervalsState.set(timerId, symbol);
4779
+ const schedule = () => call('set', {
4780
+ delay,
4781
+ now: performance.timeOrigin + performance.now(),
4782
+ timerId,
4783
+ timerType: 'interval'
4784
+ }).then(() => {
4785
+ const state = scheduledIntervalsState.get(timerId);
4786
+ if (state === undefined) {
4787
+ throw new Error('The timer is in an undefined state.');
4788
+ }
4789
+ if (state === symbol) {
4790
+ func(...args);
4791
+ // Doublecheck if the interval should still be rescheduled because it could have been cleared inside of func().
4792
+ if (scheduledIntervalsState.get(timerId) === symbol) {
4793
+ schedule();
4794
+ }
4795
+ }
4796
+ });
4797
+ schedule();
4798
+ return timerId;
4799
+ };
4800
+ },
4801
+ setTimeout: ({ call }) => {
4802
+ return (func, delay = 0, ...args) => {
4803
+ const symbol = Symbol();
4804
+ const timerId = generateUniqueNumber(scheduledTimeoutsState);
4805
+ scheduledTimeoutsState.set(timerId, symbol);
4806
+ call('set', {
4807
+ delay,
4808
+ now: performance.timeOrigin + performance.now(),
4809
+ timerId,
4810
+ timerType: 'timeout'
4811
+ }).then(() => {
4812
+ const state = scheduledTimeoutsState.get(timerId);
4813
+ if (state === undefined) {
4814
+ throw new Error('The timer is in an undefined state.');
4815
+ }
4816
+ if (state === symbol) {
4817
+ // A timeout can be savely deleted because it is only called once.
4818
+ scheduledTimeoutsState.delete(timerId);
4819
+ func(...args);
4820
+ }
4821
+ });
4822
+ return timerId;
4823
+ };
4824
+ }
4825
+ });
4826
+ const load = (url) => {
4827
+ const worker = new Worker(url);
4828
+ return wrap(worker);
4829
+ };
4830
+
4831
+ const createLoadOrReturnBroker = (loadBroker, worker) => {
4832
+ let broker = null;
4833
+ return () => {
4834
+ if (broker !== null) {
4835
+ return broker;
4836
+ }
4837
+ const blob = new Blob([worker], { type: 'application/javascript; charset=utf-8' });
4838
+ const url = URL.createObjectURL(blob);
4839
+ broker = loadBroker(url);
4840
+ // Bug #1: Edge up until v18 didn't like the URL to be revoked directly.
4841
+ setTimeout(() => URL.revokeObjectURL(url));
4842
+ return broker;
4843
+ };
4844
+ };
4845
+
4846
+ // This is the minified and stringified code of the worker-timers-worker package.
4847
+ const worker = `(()=>{var e={455:function(e,t){!function(e){"use strict";var t=function(e){return function(t){var r=e(t);return t.add(r),r}},r=function(e){return function(t,r){return e.set(t,r),r}},n=void 0===Number.MAX_SAFE_INTEGER?9007199254740991:Number.MAX_SAFE_INTEGER,o=536870912,s=2*o,a=function(e,t){return function(r){var a=t.get(r),i=void 0===a?r.size:a<s?a+1:0;if(!r.has(i))return e(r,i);if(r.size<o){for(;r.has(i);)i=Math.floor(Math.random()*s);return e(r,i)}if(r.size>n)throw new Error("Congratulations, you created a collection of unique numbers which uses all available integers!");for(;r.has(i);)i=Math.floor(Math.random()*n);return e(r,i)}},i=new WeakMap,u=r(i),c=a(u,i),d=t(c);e.addUniqueNumber=d,e.generateUniqueNumber=c}(t)}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var s=t[n]={exports:{}};return e[n].call(s.exports,s,s.exports,r),s.exports}(()=>{"use strict";const e=-32603,t=-32602,n=-32601,o=(e,t)=>Object.assign(new Error(e),{status:t}),s=t=>o('The handler of the method called "'.concat(t,'" returned an unexpected result.'),e),a=(t,r)=>async({data:{id:a,method:i,params:u}})=>{const c=r[i];try{if(void 0===c)throw(e=>o('The requested method called "'.concat(e,'" is not supported.'),n))(i);const r=void 0===u?c():c(u);if(void 0===r)throw(t=>o('The handler of the method called "'.concat(t,'" returned no required result.'),e))(i);const d=r instanceof Promise?await r:r;if(null===a){if(void 0!==d.result)throw s(i)}else{if(void 0===d.result)throw s(i);const{result:e,transferables:r=[]}=d;t.postMessage({id:a,result:e},r)}}catch(e){const{message:r,status:n=-32603}=e;t.postMessage({error:{code:n,message:r},id:a})}};var i=r(455);const u=new Map,c=(e,r,n)=>({...r,connect:({port:t})=>{t.start();const n=e(t,r),o=(0,i.generateUniqueNumber)(u);return u.set(o,(()=>{n(),t.close(),u.delete(o)})),{result:o}},disconnect:({portId:e})=>{const r=u.get(e);if(void 0===r)throw(e=>o('The specified parameter called "portId" with the given value "'.concat(e,'" does not identify a port connected to this worker.'),t))(e);return r(),{result:null}},isSupported:async()=>{if(await new Promise((e=>{const t=new ArrayBuffer(0),{port1:r,port2:n}=new MessageChannel;r.onmessage=({data:t})=>e(null!==t),n.postMessage(t,[t])}))){const e=n();return{result:e instanceof Promise?await e:e}}return{result:!1}}}),d=(e,t,r=()=>!0)=>{const n=c(d,t,r),o=a(e,n);return e.addEventListener("message",o),()=>e.removeEventListener("message",o)},l=e=>t=>{const r=e.get(t);if(void 0===r)return Promise.resolve(!1);const[n,o]=r;return clearTimeout(n),e.delete(t),o(!1),Promise.resolve(!0)},f=(e,t,r)=>(n,o,s)=>{const{expected:a,remainingDelay:i}=e(n,o);return new Promise((e=>{t.set(s,[setTimeout(r,i,a,t,e,s),e])}))},m=(e,t)=>{const r=performance.now(),n=e+t-r-performance.timeOrigin;return{expected:r+n,remainingDelay:n}},p=(e,t,r,n)=>{const o=e-performance.now();o>0?t.set(n,[setTimeout(p,o,e,t,r,n),r]):(t.delete(n),r(!0))},h=new Map,v=l(h),w=new Map,g=l(w),M=f(m,h,p),y=f(m,w,p);d(self,{clear:async({timerId:e,timerType:t})=>({result:await("interval"===t?v(e):g(e))}),set:async({delay:e,now:t,timerId:r,timerType:n})=>({result:await("interval"===n?M:y)(e,t,r)})})})()})();`; // tslint:disable-line:max-line-length
4848
+
4849
+ const loadOrReturnBroker = createLoadOrReturnBroker(load, worker);
4850
+ const clearInterval = (timerId) => loadOrReturnBroker().clearInterval(timerId);
4851
+ const clearTimeout = (timerId) => loadOrReturnBroker().clearTimeout(timerId);
4852
+ const setInterval = (...args) => loadOrReturnBroker().setInterval(...args);
4853
+ const setTimeout$1 = (...args) => loadOrReturnBroker().setTimeout(...args);
4854
+
4610
4855
  // ==UserScript==
4611
4856
  // @name ModuleRaid.js
4612
4857
  // @namespace http://tampermonkey.net/
@@ -5011,7 +5256,7 @@
5011
5256
  this.windowApi = new WindowApi(option);
5012
5257
  }
5013
5258
  /** 版本号 */
5014
- version = "2025.4.11";
5259
+ version = "2025.5.26";
5015
5260
  addStyle(cssText) {
5016
5261
  if (typeof cssText !== "string") {
5017
5262
  throw new Error("Utils.addStyle 参数cssText 必须为String类型");
@@ -5256,11 +5501,11 @@
5256
5501
  }
5257
5502
  debounce(fn, delay = 0) {
5258
5503
  let timer = null;
5259
- const context = this;
5504
+ let UtilsContext = this;
5260
5505
  return function (...args) {
5261
- clearTimeout(timer);
5262
- timer = setTimeout(function () {
5263
- fn.apply(context, args);
5506
+ UtilsContext.workerClearTimeout(timer);
5507
+ timer = UtilsContext.workerSetTimeout(function () {
5508
+ fn.apply(UtilsContext, args);
5264
5509
  }, delay);
5265
5510
  };
5266
5511
  }
@@ -5297,6 +5542,7 @@
5297
5542
  **/
5298
5543
  Dictionary = UtilsDictionary;
5299
5544
  dispatchEvent(element, eventName, details) {
5545
+ // let UtilsContext = this;
5300
5546
  let eventNameList = [];
5301
5547
  if (typeof eventName === "string") {
5302
5548
  eventNameList = [eventName];
@@ -5313,6 +5559,7 @@
5313
5559
  });
5314
5560
  }
5315
5561
  downloadBase64(base64Data, fileName, isIFrame = false) {
5562
+ let UtilsContext = this;
5316
5563
  if (typeof base64Data !== "string") {
5317
5564
  throw new Error("Utils.downloadBase64 参数 base64Data 必须为 string 类型");
5318
5565
  }
@@ -5325,7 +5572,7 @@
5325
5572
  iframeElement.style.display = "none";
5326
5573
  iframeElement.src = base64Data;
5327
5574
  this.windowApi.document.body.appendChild(iframeElement);
5328
- setTimeout(() => {
5575
+ UtilsContext.workerSetTimeout(() => {
5329
5576
  iframeElement.contentWindow.document.execCommand("SaveAs", true, fileName);
5330
5577
  this.windowApi.document.body.removeChild(iframeElement);
5331
5578
  }, 100);
@@ -7283,17 +7530,18 @@
7283
7530
  throw new TypeError("Utils.setTimeout 参数 delayTime 必须为 number 类型");
7284
7531
  }
7285
7532
  return new Promise((resolve) => {
7286
- setTimeout(() => {
7533
+ UtilsContext.workerSetTimeout(() => {
7287
7534
  resolve(UtilsContext.tryCatch().run(callback));
7288
7535
  }, delayTime);
7289
7536
  });
7290
7537
  }
7291
7538
  sleep(delayTime = 0) {
7539
+ let UtilsContext = this;
7292
7540
  if (typeof delayTime !== "number") {
7293
7541
  throw new Error("Utils.sleep 参数 delayTime 必须为 number 类型");
7294
7542
  }
7295
7543
  return new Promise((resolve) => {
7296
- setTimeout(() => {
7544
+ UtilsContext.workerSetTimeout(() => {
7297
7545
  resolve(undefined);
7298
7546
  }, delayTime);
7299
7547
  });
@@ -7657,7 +7905,7 @@
7657
7905
  },
7658
7906
  });
7659
7907
  if (__timeout__ > 0) {
7660
- setTimeout(() => {
7908
+ UtilsContext.workerSetTimeout(() => {
7661
7909
  // 取消观察器
7662
7910
  if (typeof observer?.disconnect === "function") {
7663
7911
  observer.disconnect();
@@ -7979,12 +8227,13 @@
7979
8227
  });
7980
8228
  }
7981
8229
  waitPropertyByInterval(checkObj, checkPropertyName, intervalTimer = 250, maxTime = -1) {
8230
+ let UtilsContext = this;
7982
8231
  if (checkObj == null) {
7983
8232
  throw new TypeError("checkObj 不能为空对象 ");
7984
8233
  }
7985
8234
  let isResolve = false;
7986
8235
  return new Promise((resolve, reject) => {
7987
- let interval = setInterval(() => {
8236
+ let interval = UtilsContext.workerSetInterval(() => {
7988
8237
  let obj = checkObj;
7989
8238
  if (typeof checkObj === "function") {
7990
8239
  obj = checkObj();
@@ -7998,14 +8247,14 @@
7998
8247
  if ((typeof checkPropertyName === "function" && checkPropertyName(obj)) ||
7999
8248
  Reflect.has(obj, checkPropertyName)) {
8000
8249
  isResolve = true;
8001
- clearInterval(interval);
8250
+ UtilsContext.workerClearInterval(interval);
8002
8251
  resolve(obj[checkPropertyName]);
8003
8252
  }
8004
8253
  }, intervalTimer);
8005
8254
  if (maxTime !== -1) {
8006
- setTimeout(() => {
8255
+ UtilsContext.workerSetTimeout(() => {
8007
8256
  if (!isResolve) {
8008
- clearInterval(interval);
8257
+ UtilsContext.workerClearInterval(interval);
8009
8258
  reject();
8010
8259
  }
8011
8260
  }, maxTime);
@@ -8216,6 +8465,64 @@
8216
8465
  */
8217
8466
  Vue = Vue;
8218
8467
  ModuleRaid = ModuleRaid;
8468
+ /**
8469
+ * 自动使用 Worker 执行 setTimeout
8470
+ * @param callback 回调函数
8471
+ * @param [timeout=0] 延迟时间,默认为0
8472
+ */
8473
+ workerSetTimeout(callback, timeout = 0) {
8474
+ try {
8475
+ return setTimeout$1(callback, timeout);
8476
+ }
8477
+ catch (error) {
8478
+ return globalThis.setTimeout(callback, timeout);
8479
+ }
8480
+ }
8481
+ /**
8482
+ * 配合 .setTimeout 使用
8483
+ * @param timeId setTimeout 返回的`id`
8484
+ */
8485
+ workerClearTimeout(timeId) {
8486
+ try {
8487
+ if (timeId != null) {
8488
+ clearTimeout(timeId);
8489
+ }
8490
+ }
8491
+ catch (error) {
8492
+ }
8493
+ finally {
8494
+ globalThis.clearTimeout(timeId);
8495
+ }
8496
+ }
8497
+ /**
8498
+ * 自动使用 Worker 执行 setInterval
8499
+ * @param callback 回调函数
8500
+ * @param timeout 间隔时间,默认为0
8501
+ */
8502
+ workerSetInterval(callback, timeout = 0) {
8503
+ try {
8504
+ return setInterval(callback, timeout);
8505
+ }
8506
+ catch (error) {
8507
+ return globalThis.setInterval(callback, timeout);
8508
+ }
8509
+ }
8510
+ /**
8511
+ * 配合 .setInterval 使用
8512
+ * @param timeId setInterval 返回的`id`
8513
+ */
8514
+ workerClearInterval(timeId) {
8515
+ try {
8516
+ if (timeId != null) {
8517
+ clearInterval(timeId);
8518
+ }
8519
+ }
8520
+ catch (error) {
8521
+ }
8522
+ finally {
8523
+ globalThis.clearInterval(timeId);
8524
+ }
8525
+ }
8219
8526
  }
8220
8527
  let utils = new Utils();
8221
8528