@sv443-network/userutils 6.0.0 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @sv443-network/userutils
2
2
 
3
+ ## 6.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - a11ed77: Added parameter to switch `debounce()` to trigger on the rising edge, instead of just the falling edge [(see docs)](https://github.com/Sv443-Network/UserUtils#debounce)
8
+
9
+ ## 6.0.1
10
+
11
+ ### Patch Changes
12
+
13
+ - 08248c1: Fixed terminology in JSDoc comments of the `DataStore` class
14
+
3
15
  ## 6.0.0
4
16
 
5
17
  ### Major Changes
package/README.md CHANGED
@@ -8,9 +8,12 @@ Contains builtin TypeScript declarations. Fully web compatible and supports ESM
8
8
  If you like using this library, please consider [supporting the development ❤️](https://github.com/sponsors/Sv443)
9
9
 
10
10
  <br>
11
+ <sup>
12
+ View the documentation of previous major releases:
13
+ </sup>
11
14
  <sub>
12
15
 
13
- View the documentation of previous major releases: [4.2.1](https://github.com/Sv443-Network/UserUtils/blob/v4.2.1/README.md), [3.0.0](https://github.com/Sv443-Network/UserUtils/blob/v3.0.0/README.md), [2.0.1](https://github.com/Sv443-Network/UserUtils/blob/v2.0.1/README.md), [1.2.0](https://github.com/Sv443-Network/UserUtils/blob/v1.2.0/README.md), [0.5.3](https://github.com/Sv443-Network/UserUtils/blob/v0.5.3/README.md)
16
+ <a href="https://github.com/Sv443-Network/UserUtils/blob/v5.0.1/README.md" rel="noopener noreferrer">5.0.1</a>, <a href="https://github.com/Sv443-Network/UserUtils/blob/v4.2.1/README.md" rel="noopener noreferrer">4.2.1</a>, <a href="https://github.com/Sv443-Network/UserUtils/blob/v3.0.0/README.md" rel="noopener noreferrer">3.0.0</a>, <a href="https://github.com/Sv443-Network/UserUtils/blob/v2.0.1/README.md" rel="noopener noreferrer">2.0.1</a>, <a href="https://github.com/Sv443-Network/UserUtils/blob/v1.2.0/README.md" rel="noopener noreferrer">1.2.0</a>, <a href="https://github.com/Sv443-Network/UserUtils/blob/v0.5.3/README.md" rel="noopener noreferrer">0.5.3</a>
14
17
 
15
18
  </sub>
16
19
  </div>
@@ -44,7 +47,7 @@ View the documentation of previous major releases: [4.2.1](https://github.com/Sv
44
47
  - [DataStore](#datastore) - class that manages a sync & async persistent JSON database, including data migration
45
48
  - [autoPlural()](#autoplural) - automatically pluralize a string
46
49
  - [pauseFor()](#pausefor) - pause the execution of a function for a given amount of time
47
- - [debounce()](#debounce) - call a function only once, after a given amount of time
50
+ - [debounce()](#debounce) - call a function only once in a series of calls, after or before a given timeout
48
51
  - [fetchAdvanced()](#fetchadvanced) - wrapper around the fetch API with a timeout option
49
52
  - [insertValues()](#insertvalues) - insert values into a string at specified placeholders
50
53
  - [compress()](#compress) - compress a string with Gzip or Deflate
@@ -1177,22 +1180,43 @@ async function run() {
1177
1180
  ### debounce()
1178
1181
  Usage:
1179
1182
  ```ts
1180
- debounce(func: Function, timeout?: number): Function
1183
+ debounce(func: Function, timeout?: number, edge?: "falling" | "rising"): Function
1181
1184
  ```
1182
1185
 
1183
- Debounces a function, meaning that it will only be called once after a given amount of time.
1184
- This is very useful for functions that are called repeatedly, like event listeners, to remove extraneous calls.
1185
- All passed properties will be passed down to the debounced function.
1186
- The timeout will default to 300ms if left undefined.
1186
+ Returns a debounced wrapper function, meaning that the given `func` will only be called once after or before a given amount of time.
1187
+ This is very useful for functions that are called repeatedly, like event listeners, to remove a substantial amount of unnecessary calls.
1188
+ All parameters passed to the returned function will be passed along to the input `func`
1189
+
1190
+ The `timeout` will default to 300ms if left undefined.
1191
+
1192
+ The `edge` ("falling" by default) determines if the function should be called after the timeout has passed or before it.
1193
+ In simpler terms, this results in "falling" edge functions being called once at the very end of a sequence of calls, and "rising" edge functions being called once at the beginning and possibly multiple times following that, but at the very least they're spaced apart by what's passed in `timeout`.
1194
+
1195
+ This diagram can hopefully help bring the difference across:
1196
+ <details><summary><b>Click to view the diagram</b></summary>
1197
+
1198
+ ![debounce function edge diagram](./.github/assets/debounce.png)
1199
+
1200
+ </details>
1201
+
1202
+ <br>
1187
1203
 
1188
1204
  <details><summary><b>Example - click to view</b></summary>
1189
1205
 
1190
1206
  ```ts
1191
1207
  import { debounce } from "@sv443-network/userutils";
1192
1208
 
1209
+ // uses "falling" edge by default:
1193
1210
  window.addEventListener("resize", debounce((event) => {
1194
1211
  console.log("Window was resized:", event);
1195
1212
  }, 500)); // 500ms timeout
1213
+
1214
+ // using "rising" edge:
1215
+ const myFunc = debounce((event) => {
1216
+ console.log("Body was scrolled:", event);
1217
+ }, 100, "rising"); // 100ms timeout
1218
+
1219
+ document.body.addEventListener("scroll", myFunc);
1196
1220
  ```
1197
1221
 
1198
1222
  </details>
@@ -8,7 +8,7 @@
8
8
  // ==UserLibrary==
9
9
  // @name UserUtils
10
10
  // @description Library with various utilities for userscripts - register listeners for when CSS selectors exist, intercept events, manage persistent user configurations, modify the DOM more easily and more
11
- // @version 6.0.0
11
+ // @version 6.1.0
12
12
  // @license MIT
13
13
  // @copyright Sv443 (https://github.com/Sv443)
14
14
 
@@ -145,7 +145,7 @@ var UserUtils = (function (exports) {
145
145
  * ⚠️ Requires the directives `@grant GM.getValue` and `@grant GM.setValue`
146
146
  * ⚠️ Make sure to call {@linkcode loadData()} at least once after creating an instance, or the returned data will be the same as `options.defaultData`
147
147
  *
148
- * @template TData The type of the data that is saved in persistent storage (will be automatically inferred from `config.defaultData`) - this should also be the type of the data format associated with the current `options.formatVersion`
148
+ * @template TData The type of the data that is saved in persistent storage (will be automatically inferred from `options.defaultData`) - this should also be the type of the data format associated with the current `options.formatVersion`
149
149
  * @param options The options for this DataStore instance
150
150
  */
151
151
  constructor(options) {
@@ -212,7 +212,7 @@ var UserUtils = (function (exports) {
212
212
  resolve();
213
213
  }));
214
214
  }
215
- /** Saves the default configuration data passed in the constructor synchronously to the in-memory cache and asynchronously to persistent storage */
215
+ /** Saves the default data passed in the constructor synchronously to the in-memory cache and asynchronously to persistent storage */
216
216
  saveDefaultData() {
217
217
  return __async(this, null, function* () {
218
218
  this.cachedData = this.defaultData;
@@ -432,11 +432,18 @@ var UserUtils = (function (exports) {
432
432
  setTimeout(() => res(), time);
433
433
  });
434
434
  }
435
- function debounce(func, timeout = 300) {
435
+ function debounce(func, timeout = 300, edge = "falling") {
436
436
  let timer;
437
437
  return function(...args) {
438
- clearTimeout(timer);
439
- timer = setTimeout(() => func.apply(this, args), timeout);
438
+ if (edge === "rising") {
439
+ if (!timer) {
440
+ func.apply(this, args);
441
+ timer = setTimeout(() => timer = void 0, timeout);
442
+ }
443
+ } else {
444
+ clearTimeout(timer);
445
+ timer = setTimeout(() => func.apply(this, args), timeout);
446
+ }
440
447
  };
441
448
  }
442
449
  function fetchAdvanced(_0) {
package/dist/index.js CHANGED
@@ -125,7 +125,7 @@ var DataStore = class {
125
125
  * ⚠️ Requires the directives `@grant GM.getValue` and `@grant GM.setValue`
126
126
  * ⚠️ Make sure to call {@linkcode loadData()} at least once after creating an instance, or the returned data will be the same as `options.defaultData`
127
127
  *
128
- * @template TData The type of the data that is saved in persistent storage (will be automatically inferred from `config.defaultData`) - this should also be the type of the data format associated with the current `options.formatVersion`
128
+ * @template TData The type of the data that is saved in persistent storage (will be automatically inferred from `options.defaultData`) - this should also be the type of the data format associated with the current `options.formatVersion`
129
129
  * @param options The options for this DataStore instance
130
130
  */
131
131
  constructor(options) {
@@ -192,7 +192,7 @@ var DataStore = class {
192
192
  resolve();
193
193
  }));
194
194
  }
195
- /** Saves the default configuration data passed in the constructor synchronously to the in-memory cache and asynchronously to persistent storage */
195
+ /** Saves the default data passed in the constructor synchronously to the in-memory cache and asynchronously to persistent storage */
196
196
  saveDefaultData() {
197
197
  return __async(this, null, function* () {
198
198
  this.cachedData = this.defaultData;
@@ -412,11 +412,18 @@ function pauseFor(time) {
412
412
  setTimeout(() => res(), time);
413
413
  });
414
414
  }
415
- function debounce(func, timeout = 300) {
415
+ function debounce(func, timeout = 300, edge = "falling") {
416
416
  let timer;
417
417
  return function(...args) {
418
- clearTimeout(timer);
419
- timer = setTimeout(() => func.apply(this, args), timeout);
418
+ if (edge === "rising") {
419
+ if (!timer) {
420
+ func.apply(this, args);
421
+ timer = setTimeout(() => timer = void 0, timeout);
422
+ }
423
+ } else {
424
+ clearTimeout(timer);
425
+ timer = setTimeout(() => func.apply(this, args), timeout);
426
+ }
420
427
  };
421
428
  }
422
429
  function fetchAdvanced(_0) {
package/dist/index.mjs CHANGED
@@ -123,7 +123,7 @@ var DataStore = class {
123
123
  * ⚠️ Requires the directives `@grant GM.getValue` and `@grant GM.setValue`
124
124
  * ⚠️ Make sure to call {@linkcode loadData()} at least once after creating an instance, or the returned data will be the same as `options.defaultData`
125
125
  *
126
- * @template TData The type of the data that is saved in persistent storage (will be automatically inferred from `config.defaultData`) - this should also be the type of the data format associated with the current `options.formatVersion`
126
+ * @template TData The type of the data that is saved in persistent storage (will be automatically inferred from `options.defaultData`) - this should also be the type of the data format associated with the current `options.formatVersion`
127
127
  * @param options The options for this DataStore instance
128
128
  */
129
129
  constructor(options) {
@@ -190,7 +190,7 @@ var DataStore = class {
190
190
  resolve();
191
191
  }));
192
192
  }
193
- /** Saves the default configuration data passed in the constructor synchronously to the in-memory cache and asynchronously to persistent storage */
193
+ /** Saves the default data passed in the constructor synchronously to the in-memory cache and asynchronously to persistent storage */
194
194
  saveDefaultData() {
195
195
  return __async(this, null, function* () {
196
196
  this.cachedData = this.defaultData;
@@ -410,11 +410,18 @@ function pauseFor(time) {
410
410
  setTimeout(() => res(), time);
411
411
  });
412
412
  }
413
- function debounce(func, timeout = 300) {
413
+ function debounce(func, timeout = 300, edge = "falling") {
414
414
  let timer;
415
415
  return function(...args) {
416
- clearTimeout(timer);
417
- timer = setTimeout(() => func.apply(this, args), timeout);
416
+ if (edge === "rising") {
417
+ if (!timer) {
418
+ func.apply(this, args);
419
+ timer = setTimeout(() => timer = void 0, timeout);
420
+ }
421
+ } else {
422
+ clearTimeout(timer);
423
+ timer = setTimeout(() => func.apply(this, args), timeout);
424
+ }
418
425
  };
419
426
  }
420
427
  function fetchAdvanced(_0) {
@@ -1,7 +1,7 @@
1
1
  /** Function that takes the data in the old format and returns the data in the new format. Also supports an asynchronous migration. */
2
2
  type MigrationFunc = (oldData: any) => any | Promise<any>;
3
3
  /** Dictionary of format version numbers and the function that migrates to them from the previous whole integer */
4
- export type ConfigMigrationsDict = Record<number, MigrationFunc>;
4
+ export type DataMigrationsDict = Record<number, MigrationFunc>;
5
5
  /** Options for the DataStore instance */
6
6
  export type DataStoreOptions<TData> = {
7
7
  /** A unique internal ID for this data store - choose wisely as changing it is not supported yet. */
@@ -27,7 +27,7 @@ export type DataStoreOptions<TData> = {
27
27
  * The functions will be run in order from the oldest to the newest version.
28
28
  * If the current format version is not in the dictionary, no migrations will be run.
29
29
  */
30
- migrations?: ConfigMigrationsDict;
30
+ migrations?: DataMigrationsDict;
31
31
  } & ({
32
32
  /**
33
33
  * Function to use to encode the data prior to saving it in persistent storage.
@@ -51,7 +51,7 @@ export type DataStoreOptions<TData> = {
51
51
  });
52
52
  /**
53
53
  * Manages a sync & async persistent JSON database that is cached in memory and persistently saved across sessions.
54
- * Supports migrating data from older versions of the configuration to newer ones and populating the cache with default data if no persistent data is found.
54
+ * Supports migrating data from older format versions to newer ones and populating the cache with default data if no persistent data is found.
55
55
  *
56
56
  * ⚠️ Requires the directives `@grant GM.getValue` and `@grant GM.setValue`
57
57
  * ⚠️ Make sure to call {@linkcode loadData()} at least once after creating an instance, or the returned data will be the same as `options.defaultData`
@@ -73,7 +73,7 @@ export declare class DataStore<TData = any> {
73
73
  * ⚠️ Requires the directives `@grant GM.getValue` and `@grant GM.setValue`
74
74
  * ⚠️ Make sure to call {@linkcode loadData()} at least once after creating an instance, or the returned data will be the same as `options.defaultData`
75
75
  *
76
- * @template TData The type of the data that is saved in persistent storage (will be automatically inferred from `config.defaultData`) - this should also be the type of the data format associated with the current `options.formatVersion`
76
+ * @template TData The type of the data that is saved in persistent storage (will be automatically inferred from `options.defaultData`) - this should also be the type of the data format associated with the current `options.formatVersion`
77
77
  * @param options The options for this DataStore instance
78
78
  */
79
79
  constructor(options: DataStoreOptions<TData>);
@@ -90,7 +90,7 @@ export declare class DataStore<TData = any> {
90
90
  getData(): TData;
91
91
  /** Saves the data synchronously to the in-memory cache and asynchronously to the persistent storage */
92
92
  setData(data: TData): Promise<void>;
93
- /** Saves the default configuration data passed in the constructor synchronously to the in-memory cache and asynchronously to persistent storage */
93
+ /** Saves the default data passed in the constructor synchronously to the in-memory cache and asynchronously to persistent storage */
94
94
  saveDefaultData(): Promise<void>;
95
95
  /**
96
96
  * Call this method to clear all persistently stored data associated with this DataStore instance.
package/dist/lib/dom.d.ts CHANGED
@@ -67,7 +67,7 @@ export declare function observeElementProp<TElem extends Element = HTMLElement,
67
67
  * @param siblingAmount The amount of siblings to return
68
68
  * @param refElementAlignment Can be set to `center-top` (default), `center-bottom`, `top`, or `bottom`, which will determine where the relative location of the provided {@linkcode refElement} is in the returned array
69
69
  * @param includeRef If set to `true` (default), the provided {@linkcode refElement} will be included in the returned array at the corresponding position
70
- * @template TSiblingType The type of the sibling elements that are returned
70
+ * @template TSibling The type of the sibling elements that are returned
71
71
  * @returns An array of sibling elements
72
72
  */
73
- export declare function getSiblingsFrame<TSiblingType extends Element = HTMLElement>(refElement: Element, siblingAmount: number, refElementAlignment?: "center-top" | "center-bottom" | "top" | "bottom", includeRef?: boolean): TSiblingType[];
73
+ export declare function getSiblingsFrame<TSibling extends Element = HTMLElement>(refElement: Element, siblingAmount: number, refElementAlignment?: "center-top" | "center-bottom" | "top" | "bottom", includeRef?: boolean): TSibling[];
@@ -26,8 +26,11 @@ export declare function pauseFor(time: number): Promise<void>;
26
26
  /**
27
27
  * Calls the passed {@linkcode func} after the specified {@linkcode timeout} in ms (defaults to 300).
28
28
  * Any subsequent calls to this function will reset the timer and discard all previous calls.
29
+ * @param func The function to call after the timeout
30
+ * @param timeout The time in ms to wait before calling the function
31
+ * @param edge Whether to call the function at the very first call ("rising" edge) or the very last call ("falling" edge, default)
29
32
  */
30
- export declare function debounce<TFunc extends (...args: TArgs[]) => void, TArgs = any>(func: TFunc, timeout?: number): (...args: TArgs[]) => void;
33
+ export declare function debounce<TFunc extends (...args: TArgs[]) => void, TArgs = any>(func: TFunc, timeout?: number, edge?: "rising" | "falling"): (...args: TArgs[]) => void;
31
34
  /** Options for the `fetchAdvanced()` function */
32
35
  export type FetchAdvancedOpts = Omit<RequestInit & Partial<{
33
36
  /** Timeout in milliseconds after which the fetch call will be canceled with an AbortController signal */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sv443-network/userutils",
3
3
  "libName": "UserUtils",
4
- "version": "6.0.0",
4
+ "version": "6.1.0",
5
5
  "description": "Library with various utilities for userscripts - register listeners for when CSS selectors exist, intercept events, manage persistent user configurations, modify the DOM more easily and more",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.mjs",
@@ -10,7 +10,7 @@
10
10
  "lint": "tsc --noEmit && eslint .",
11
11
  "build-types": "tsc --emitDeclarationOnly --declaration --outDir dist",
12
12
  "build-common": "tsup lib/index.ts --format cjs,esm --clean --treeshake",
13
- "build-global": "tsup lib/index.ts --format cjs,esm,iife --treeshake --onSuccess \"npm run post-build-global && echo Finished building.\"",
13
+ "build-all": "tsup lib/index.ts --format cjs,esm,iife --treeshake --onSuccess \"npm run post-build-global && echo Finished building.\"",
14
14
  "build": "npm run build-common -- && npm run build-types",
15
15
  "post-build-global": "npm run node-ts -- ./tools/post-build-global.mts",
16
16
  "dev": "npm run build-common -- --sourcemap --watch --onSuccess \"npm run build-types && echo Finished building.\"",