@sv443-network/coreutils 1.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -2
- package/README.md +24 -8
- package/dist/CoreUtils.cjs +203 -58
- package/dist/CoreUtils.min.cjs +2 -2
- package/dist/CoreUtils.min.mjs +2 -2
- package/dist/CoreUtils.min.umd.js +2 -2
- package/dist/CoreUtils.mjs +203 -58
- package/dist/CoreUtils.umd.js +510 -480
- package/dist/lib/DataStore.d.ts +19 -11
- package/dist/lib/DataStoreEngine.d.ts +35 -14
- package/dist/lib/NanoEmitter.d.ts +33 -1
- package/dist/lib/TieredCache.d.ts +1 -1
- package/dist/lib/crypto.d.ts +15 -15
- package/dist/lib/math.d.ts +4 -0
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,13 +1,36 @@
|
|
|
1
1
|
# @sv443-network/coreutils
|
|
2
2
|
|
|
3
|
+
## 2.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- a011cb3: Fix FileStorageEngine path problems on Windows
|
|
8
|
+
|
|
9
|
+
## 2.0.0
|
|
10
|
+
|
|
11
|
+
### Major Changes
|
|
12
|
+
|
|
13
|
+
- 273fa5a: Removed the boolean property `__ds-${id}-enc` from the `DataStore` and `DataStoreEngine` classes.
|
|
14
|
+
Now the key `__ds-${id}-enf` will hold the encoding format identifier string, or `null` if not set (will get created on the next write call).
|
|
15
|
+
This will make it possible to switch the encoding format without compatibility issues.
|
|
16
|
+
This functionality is not officially supported yet, but can be achieved manually by calling the storage API methods of `storeInstance.engine`
|
|
17
|
+
|
|
18
|
+
### Minor Changes
|
|
19
|
+
|
|
20
|
+
- 29fb048: Added `overflowVal()` to conform a value to an over- & undeflowing range
|
|
21
|
+
- 91cbe9c: Added optional abstract method `DataStoreEngine.deleteStorage()` for deleting the data storage container itself. If implemented in subclasses, it will be called from the method `DataStore.deleteData()`
|
|
22
|
+
- 3cae1cb: Added `dataStoreOptions` constructor prop to the DataStoreEngine subclasses to enable them to be used standalone.
|
|
23
|
+
- f6465b5: Added method `NanoEmitter.onMulti()` to listen to when multiple events have emitted, with fine grained options
|
|
24
|
+
|
|
3
25
|
## 1.0.0
|
|
4
26
|
|
|
5
27
|
This is the initial release of CoreUtils. Most features have been originally ported from [version 9.4.1 of `@sv443-network/userutils`](https://github.com/Sv443-Network/UserUtils/tree/v9.4.1)
|
|
6
28
|
Parts of the code have been overhauled, and some features have been added:
|
|
29
|
+
|
|
7
30
|
- Additions:
|
|
8
31
|
- Added [`capitalize()`](https://github.com/Sv443-Network/CoreUtils/blob/main/docs.md#function-capitalize) to capitalize the first letter of a string.
|
|
9
|
-
- Added [`setImmediateInterval()`](https://github.com/Sv443-Network/CoreUtils/blob/main/docs.md#function-setimmediateinterval) to set an interval that runs immediately, then again on a fixed
|
|
10
|
-
- Added [`setImmediateTimeoutLoop()`](https://github.com/Sv443-Network/CoreUtils/blob/main/docs.md#function-setimmediatetimeoutloop) to set a recursive `setTimeout()` loop with a fixed
|
|
32
|
+
- Added [`setImmediateInterval()`](https://github.com/Sv443-Network/CoreUtils/blob/main/docs.md#function-setimmediateinterval) to set an interval that runs immediately, then again on a fixed _interval._
|
|
33
|
+
- Added [`setImmediateTimeoutLoop()`](https://github.com/Sv443-Network/CoreUtils/blob/main/docs.md#function-setimmediatetimeoutloop) to set a recursive `setTimeout()` loop with a fixed _delay._
|
|
11
34
|
- Added [`takeRandomItemIndex()`](https://github.com/Sv443-Network/CoreUtils/blob/main/docs.md#function-takerandomitemindex), as a mutating counterpart to [`randomItemIndex()`](https://github.com/Sv443-Network/CoreUtils/blob/main/docs.md#function-randomitemindex)
|
|
12
35
|
- Added [`truncStr()`](https://github.com/Sv443-Network/CoreUtils/blob/main/docs.md#function-truncstr) to truncate a string to a given length, optionally adding an ellipsis.
|
|
13
36
|
- Added [`valsWithin()`](https://github.com/Sv443-Network/CoreUtils/blob/main/docs.md#function-valswithin) to check if two values, rounded at the given decimal, are within a certain range of each other.
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
Cross-platform, general-purpose, JavaScript core library for Node, Deno and the browser.
|
|
5
5
|
Intended to be used in conjunction with [`@sv443-network/userutils`](https://github.com/Sv443-Network/UserUtils) and [`@sv443-network/djsutils`](https://github.com/Sv443-Network/DJSUtils), but can be used independently as well.
|
|
6
6
|
|
|
7
|
-
### [Documentation](./docs.md#readme) • [Features](#features) • [Installation](#installation) • [License](
|
|
7
|
+
### [Documentation](./docs.md#readme) • [Features](#features) • [Installation](#installation) • [License](./LICENSE.txt) • [Changelog](./CHANGELOG.md)
|
|
8
8
|
|
|
9
9
|
</div>
|
|
10
10
|
<br>
|
|
@@ -34,12 +34,14 @@ Intended to be used in conjunction with [`@sv443-network/userutils`](https://git
|
|
|
34
34
|
- 🟧 [`class DataStore`](./docs.md#class-datastore) - The main class for the data store
|
|
35
35
|
- 🔷 [`type DataStoreOptions`](./docs.md#type-datastoreoptions) - Options for the data store
|
|
36
36
|
- 🔷 [`type DataMigrationsDict`](./docs.md#type-datamigrationsdict) - Dictionary of data migration functions
|
|
37
|
+
- 🔷 [`type DataStoreData`](./docs.md#type-datastoredata) - The type of the serializable data
|
|
37
38
|
- 🟧 [`class DataStoreSerializer`](./docs.md#class-datastoreserializer) - Serializes and deserializes data for multiple DataStore instances
|
|
38
39
|
- 🔷 [`type DataStoreSerializerOptions`](./docs.md#type-datastoreserializeroptions) - Options for the DataStoreSerializer
|
|
39
40
|
- 🔷 [`type LoadStoresDataResult`](./docs.md#type-loadstoresdataresult) - Result of calling [`loadStoresData()`](./docs.md#datastoreserializer-loadstoresdata)
|
|
40
41
|
- 🔷 [`type SerializedDataStore`](./docs.md#type-serializeddatastore) - Meta object and serialized data of a DataStore instance
|
|
41
42
|
- 🔷 [`type StoreFilter`](./docs.md#type-storefilter) - Filter for selecting data stores
|
|
42
43
|
- 🟧 [`class DataStoreEngine`](./docs.md#class-datastoreengine) - Base class for DataStore storage engines, which handle the data storage
|
|
44
|
+
- 🔷 [`type DataStoreEngineDSOptions`](./docs.md#type-datastoreenginedsoptions) - Reduced version of [`DataStoreOptions`](./docs.md#type-datastoreoptions)
|
|
43
45
|
- [Storage Engines:](./docs.md#storage-engines)
|
|
44
46
|
- 🟧 [`class BrowserStorageEngine`](./docs.md#class-browserstorageengine) - Storage engine for browser environments (localStorage, sessionStorage)
|
|
45
47
|
- 🔷 [`type BrowserStorageEngineOptions`](./docs.md#browserstorageengineoptions) - Options for the browser storage engine
|
|
@@ -63,6 +65,7 @@ Intended to be used in conjunction with [`@sv443-network/userutils`](https://git
|
|
|
63
65
|
- 🟣 [`function formatNumber()`](./docs.md#function-formatnumber) - Formats a number to a string using the given locale and format identifier
|
|
64
66
|
- 🔷 [`type NumberFormat`](./docs.md#type-numberformat) - Number format identifier
|
|
65
67
|
- 🟣 [`function mapRange()`](./docs.md#function-maprange) - Maps a number from one range to another
|
|
68
|
+
- 🟣 [`function overflowVal()`](./docs.md#function-overflowVal) - Makes sure a number is in a range by over- & underflowing it
|
|
66
69
|
- 🟣 [`function randRange()`](./docs.md#function-randrange) - Returns a random number in the given range
|
|
67
70
|
- 🟣 [`function roundFixed()`](./docs.md#function-roundfixed) - Rounds the given number to the given number of decimal places
|
|
68
71
|
- 🟣 [`function valsWithin()`](./docs.md#function-valswithin) - Checks if the given numbers are within a certain range of each other
|
|
@@ -90,7 +93,7 @@ Intended to be used in conjunction with [`@sv443-network/userutils`](https://git
|
|
|
90
93
|
- 🟩 [`const defaultPbChars`](./docs.md#const-defaultpbchars) - Default characters for the progress bar
|
|
91
94
|
- 🔷 [`type ProgressBarChars`](./docs.md#type-progressbarchars) - Type for the progress bar characters object
|
|
92
95
|
- 🟣 [`function joinArrayReadable()`](./docs.md#function-joinarrayreadable) - Joins the given array into a string, using the given separators and last separator
|
|
93
|
-
- 🟣 [`function secsToTimeStr()`](./docs.md#function-
|
|
96
|
+
- 🟣 [`function secsToTimeStr()`](./docs.md#function-secstotimestr) - Turns the given number of seconds into a string in the format `(hh:)mm:ss` with intelligent zero-padding
|
|
94
97
|
- 🟣 [`function truncStr()`](./docs.md#function-truncstr) - Truncates the given string to the given length
|
|
95
98
|
<!-- - *[**TieredCache:**](./docs.md#tieredcache)
|
|
96
99
|
- 🟧 *[`class TieredCache`](./docs.md#class-tieredcache) - A multi-tier cache that uses multiple storage engines with different expiration times
|
|
@@ -122,7 +125,7 @@ Intended to be used in conjunction with [`@sv443-network/userutils`](https://git
|
|
|
122
125
|
> 🟣 = function
|
|
123
126
|
> 🟧 = class
|
|
124
127
|
> 🔷 = type
|
|
125
|
-
>
|
|
128
|
+
> 🟩 = const
|
|
126
129
|
|
|
127
130
|
<br>
|
|
128
131
|
|
|
@@ -135,11 +138,11 @@ yarn add @sv443-network/coreutils
|
|
|
135
138
|
npx jsr install @sv443-network/coreutils
|
|
136
139
|
deno add jsr:@sv443-network/coreutils
|
|
137
140
|
```
|
|
138
|
-
- If you are in a DOM environment, you can include the UMD bundle using your favorite CDN:
|
|
141
|
+
- If you are in a DOM environment, you can include the UMD bundle using your favorite CDN (after inserting the version number):
|
|
139
142
|
```html
|
|
140
|
-
<script src="https://cdn.jsdelivr.net/npm/@sv443-network/coreutils@
|
|
141
|
-
<script src="https://unpkg.com/@sv443-network/coreutils@
|
|
142
|
-
<script src="https://esm.sh/@sv443-network/coreutils@
|
|
143
|
+
<script src="https://cdn.jsdelivr.net/npm/@sv443-network/coreutils@INSERT_VERSION_HERE/dist/CoreUtils.min.umd.js"></script>
|
|
144
|
+
<script src="https://unpkg.com/@sv443-network/coreutils@INSERT_VERSION_HERE/dist/CoreUtils.min.umd.js"></script>
|
|
145
|
+
<script src="https://esm.sh/@sv443-network/coreutils@INSERT_VERSION_HERE/dist/CoreUtils.min.umd.js"></script>
|
|
143
146
|
```
|
|
144
147
|
- Then, import parts of the library as needed:
|
|
145
148
|
```ts
|
|
@@ -164,5 +167,18 @@ const CoreUtils = require("@sv443-network/coreutils");
|
|
|
164
167
|
// - to make the global variable `CoreUtils` available, import this file:
|
|
165
168
|
// "@sv443-network/coreutils/dist/CoreUtils.min.umd.js"
|
|
166
169
|
// - or import the library on your HTML page:
|
|
167
|
-
// <script src="https://cdn.jsdelivr.net/npm/@sv443-network/coreutils@
|
|
170
|
+
// <script src="https://cdn.jsdelivr.net/npm/@sv443-network/coreutils@INSERT_VERSION_HERE/dist/CoreUtils.min.umd.js"></script>
|
|
171
|
+
// (make sure to insert the version number above. Use 'latest' (not recommended) or a specific version, e.g. '9.4.3')
|
|
168
172
|
```
|
|
173
|
+
|
|
174
|
+
<br><br>
|
|
175
|
+
|
|
176
|
+
<div align="center" style="text-align: center;">
|
|
177
|
+
|
|
178
|
+
Made with ❤️ by [Sv443](https://github.com/Sv443)
|
|
179
|
+
If you like this userscript, please consider [supporting the development](https://github.com/sponsors/Sv443)
|
|
180
|
+
|
|
181
|
+
© 2025 Sv443 & Sv443 Network
|
|
182
|
+
[MIT license](./LICENSE.txt)
|
|
183
|
+
|
|
184
|
+
</div>
|
package/dist/CoreUtils.cjs
CHANGED
|
@@ -65,6 +65,7 @@ __export(lib_exports, {
|
|
|
65
65
|
joinArrayReadable: () => joinArrayReadable,
|
|
66
66
|
lightenColor: () => lightenColor,
|
|
67
67
|
mapRange: () => mapRange,
|
|
68
|
+
overflowVal: () => overflowVal,
|
|
68
69
|
pauseFor: () => pauseFor,
|
|
69
70
|
pureObj: () => pureObj,
|
|
70
71
|
randRange: () => randRange,
|
|
@@ -128,6 +129,19 @@ function mapRange(value, range1min, range1max, range2min, range2max) {
|
|
|
128
129
|
return value * (range2max / range1max);
|
|
129
130
|
return (value - range1min) * ((range2max - range2min) / (range1max - range1min)) + range2min;
|
|
130
131
|
}
|
|
132
|
+
function overflowVal(value, minOrMax, max) {
|
|
133
|
+
const min = typeof max === "number" ? minOrMax : 0;
|
|
134
|
+
max = typeof max === "number" ? max : minOrMax;
|
|
135
|
+
if (min > max)
|
|
136
|
+
throw new RangeError(`Parameter "min" can't be bigger than "max"`);
|
|
137
|
+
if (isNaN(value) || isNaN(min) || isNaN(max) || !isFinite(value) || !isFinite(min) || !isFinite(max))
|
|
138
|
+
return NaN;
|
|
139
|
+
if (value >= min && value <= max)
|
|
140
|
+
return value;
|
|
141
|
+
const range = max - min + 1;
|
|
142
|
+
const wrappedValue = ((value - min) % range + range) % range + min;
|
|
143
|
+
return wrappedValue;
|
|
144
|
+
}
|
|
131
145
|
function randRange(...args) {
|
|
132
146
|
let min, max, enhancedEntropy = false;
|
|
133
147
|
if (typeof args[0] === "number" && typeof args[1] === "number")
|
|
@@ -223,10 +237,8 @@ function darkenColor(color, percent, upperCase = false) {
|
|
|
223
237
|
return rgbToHex(r, g, b, a, color.startsWith("#"), upperCase);
|
|
224
238
|
else if (color.startsWith("rgba"))
|
|
225
239
|
return `rgba(${r}, ${g}, ${b}, ${a ?? NaN})`;
|
|
226
|
-
else if (color.startsWith("rgb"))
|
|
227
|
-
return `rgb(${r}, ${g}, ${b})`;
|
|
228
240
|
else
|
|
229
|
-
|
|
241
|
+
return `rgb(${r}, ${g}, ${b})`;
|
|
230
242
|
}
|
|
231
243
|
function hexToRgb(hex) {
|
|
232
244
|
hex = (hex.startsWith("#") ? hex.slice(1) : hex).trim();
|
|
@@ -259,22 +271,22 @@ function atoab(str) {
|
|
|
259
271
|
return Uint8Array.from(atob(str), (c) => c.charCodeAt(0));
|
|
260
272
|
}
|
|
261
273
|
async function compress(input, compressionFormat, outputType = "string") {
|
|
262
|
-
const byteArray = input instanceof
|
|
274
|
+
const byteArray = input instanceof Uint8Array ? input : new TextEncoder().encode((input == null ? void 0 : input.toString()) ?? String(input));
|
|
263
275
|
const comp = new CompressionStream(compressionFormat);
|
|
264
276
|
const writer = comp.writable.getWriter();
|
|
265
277
|
writer.write(byteArray);
|
|
266
278
|
writer.close();
|
|
267
|
-
const
|
|
268
|
-
return outputType === "arrayBuffer" ?
|
|
279
|
+
const uintArr = new Uint8Array(await new Response(comp.readable).arrayBuffer());
|
|
280
|
+
return outputType === "arrayBuffer" ? uintArr : abtoa(uintArr);
|
|
269
281
|
}
|
|
270
282
|
async function decompress(input, compressionFormat, outputType = "string") {
|
|
271
|
-
const byteArray = input instanceof
|
|
283
|
+
const byteArray = input instanceof Uint8Array ? input : atoab((input == null ? void 0 : input.toString()) ?? String(input));
|
|
272
284
|
const decomp = new DecompressionStream(compressionFormat);
|
|
273
285
|
const writer = decomp.writable.getWriter();
|
|
274
286
|
writer.write(byteArray);
|
|
275
287
|
writer.close();
|
|
276
|
-
const
|
|
277
|
-
return outputType === "arrayBuffer" ?
|
|
288
|
+
const uintArr = new Uint8Array(await new Response(decomp.readable).arrayBuffer());
|
|
289
|
+
return outputType === "arrayBuffer" ? uintArr : new TextDecoder().decode(uintArr);
|
|
278
290
|
}
|
|
279
291
|
async function computeHash(input, algorithm = "SHA-256") {
|
|
280
292
|
let data;
|
|
@@ -520,7 +532,14 @@ var DataStore = class {
|
|
|
520
532
|
decodeData;
|
|
521
533
|
compressionFormat = "deflate-raw";
|
|
522
534
|
engine;
|
|
535
|
+
options;
|
|
536
|
+
/**
|
|
537
|
+
* Whether all first-init checks should be done.
|
|
538
|
+
* This includes migrating the internal DataStore format, migrating data from the UserUtils format, and anything similar.
|
|
539
|
+
* This is set to `true` by default. Create a subclass and set it to `false` before calling {@linkcode loadData()} if you want to explicitly skip these checks.
|
|
540
|
+
*/
|
|
523
541
|
firstInit = true;
|
|
542
|
+
/** In-memory cached copy of the data that is saved in persistent storage used for synchronous read access. */
|
|
524
543
|
cachedData;
|
|
525
544
|
migrations;
|
|
526
545
|
migrateIds = [];
|
|
@@ -528,13 +547,13 @@ var DataStore = class {
|
|
|
528
547
|
* Creates an instance of DataStore to manage a sync & async database that is cached in memory and persistently saved across sessions.
|
|
529
548
|
* Supports migrating data from older versions to newer ones and populating the cache with default data if no persistent data is found.
|
|
530
549
|
*
|
|
531
|
-
* - ⚠️ Requires the directives `@grant GM.getValue` and `@grant GM.setValue` if the storageMethod is left as the default of `"GM"`
|
|
532
550
|
* - ⚠️ Make sure to call {@linkcode loadData()} at least once after creating an instance, or the returned data will be the same as `options.defaultData`
|
|
533
551
|
*
|
|
534
552
|
* @template TData The type of the data that is saved in persistent storage for the currently set format version (will be automatically inferred from `defaultData` if not provided) - **This has to be a JSON-compatible object!** (no undefined, circular references, etc.)
|
|
535
553
|
* @param opts The options for this DataStore instance
|
|
536
554
|
*/
|
|
537
555
|
constructor(opts) {
|
|
556
|
+
var _a;
|
|
538
557
|
this.id = opts.id;
|
|
539
558
|
this.formatVersion = opts.formatVersion;
|
|
540
559
|
this.defaultData = opts.defaultData;
|
|
@@ -545,8 +564,9 @@ var DataStore = class {
|
|
|
545
564
|
this.encodeData = opts.encodeData;
|
|
546
565
|
this.decodeData = opts.decodeData;
|
|
547
566
|
this.engine = typeof opts.engine === "function" ? opts.engine() : opts.engine;
|
|
567
|
+
this.options = opts;
|
|
548
568
|
if (typeof opts.compressionFormat === "undefined")
|
|
549
|
-
opts.compressionFormat = "deflate-raw";
|
|
569
|
+
opts.compressionFormat = ((_a = opts.encodeData) == null ? void 0 : _a[0]) ?? "deflate-raw";
|
|
550
570
|
if (typeof opts.compressionFormat === "string") {
|
|
551
571
|
this.encodeData = [opts.compressionFormat, async (data) => await compress(data, opts.compressionFormat, "string")];
|
|
552
572
|
this.decodeData = [opts.compressionFormat, async (data) => await compress(data, opts.compressionFormat, "string")];
|
|
@@ -581,9 +601,14 @@ var DataStore = class {
|
|
|
581
601
|
promises.push(this.engine.setValue(newKey, value));
|
|
582
602
|
promises.push(this.engine.deleteValue(oldKey));
|
|
583
603
|
};
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
604
|
+
if (oldData)
|
|
605
|
+
migrateFmt(`_uucfg-${this.id}`, `__ds-${this.id}-dat`, oldData);
|
|
606
|
+
if (!isNaN(oldVer))
|
|
607
|
+
migrateFmt(`_uucfgver-${this.id}`, `__ds-${this.id}-ver`, oldVer);
|
|
608
|
+
if (typeof oldEnc === "boolean")
|
|
609
|
+
migrateFmt(`_uucfgenc-${this.id}`, `__ds-${this.id}-enf`, oldEnc === true ? Boolean(this.compressionFormat) || null : null);
|
|
610
|
+
else
|
|
611
|
+
promises.push(this.engine.setValue(`__ds-${this.id}-enf`, this.compressionFormat));
|
|
587
612
|
await Promise.allSettled(promises);
|
|
588
613
|
}
|
|
589
614
|
await this.engine.setValue("__ds_fmt_ver", dsFmtVer);
|
|
@@ -593,21 +618,22 @@ var DataStore = class {
|
|
|
593
618
|
await this.migrateId(this.migrateIds);
|
|
594
619
|
this.migrateIds = [];
|
|
595
620
|
}
|
|
596
|
-
const
|
|
597
|
-
let
|
|
598
|
-
if (typeof
|
|
621
|
+
const storedData = await this.engine.getValue(`__ds-${this.id}-dat`, JSON.stringify(this.defaultData));
|
|
622
|
+
let storedFmtVer = Number(await this.engine.getValue(`__ds-${this.id}-ver`, NaN));
|
|
623
|
+
if (typeof storedData !== "string") {
|
|
599
624
|
await this.saveDefaultData();
|
|
600
625
|
return { ...this.defaultData };
|
|
601
626
|
}
|
|
602
|
-
const
|
|
627
|
+
const encodingFmt = String(await this.engine.getValue(`__ds-${this.id}-enf`, null));
|
|
628
|
+
const isEncoded = encodingFmt !== "null" && encodingFmt !== "false";
|
|
603
629
|
let saveData = false;
|
|
604
|
-
if (isNaN(
|
|
605
|
-
await this.engine.setValue(`__ds-${this.id}-ver`,
|
|
630
|
+
if (isNaN(storedFmtVer)) {
|
|
631
|
+
await this.engine.setValue(`__ds-${this.id}-ver`, storedFmtVer = this.formatVersion);
|
|
606
632
|
saveData = true;
|
|
607
633
|
}
|
|
608
|
-
let parsed = await this.engine.deserializeData(
|
|
609
|
-
if (
|
|
610
|
-
parsed = await this.runMigrations(parsed,
|
|
634
|
+
let parsed = await this.engine.deserializeData(storedData, isEncoded);
|
|
635
|
+
if (storedFmtVer < this.formatVersion && this.migrations)
|
|
636
|
+
parsed = await this.runMigrations(parsed, storedFmtVer);
|
|
611
637
|
if (saveData)
|
|
612
638
|
await this.setData(parsed);
|
|
613
639
|
return this.cachedData = this.engine.deepCopy(parsed);
|
|
@@ -627,12 +653,11 @@ var DataStore = class {
|
|
|
627
653
|
/** Saves the data synchronously to the in-memory cache and asynchronously to the persistent storage */
|
|
628
654
|
setData(data) {
|
|
629
655
|
this.cachedData = data;
|
|
630
|
-
const useEncoding = this.encodingEnabled();
|
|
631
656
|
return new Promise(async (resolve) => {
|
|
632
657
|
await Promise.allSettled([
|
|
633
|
-
this.engine.setValue(`__ds-${this.id}-dat`, await this.engine.serializeData(data,
|
|
658
|
+
this.engine.setValue(`__ds-${this.id}-dat`, await this.engine.serializeData(data, this.encodingEnabled())),
|
|
634
659
|
this.engine.setValue(`__ds-${this.id}-ver`, this.formatVersion),
|
|
635
|
-
this.engine.setValue(`__ds-${this.id}-
|
|
660
|
+
this.engine.setValue(`__ds-${this.id}-enf`, this.compressionFormat)
|
|
636
661
|
]);
|
|
637
662
|
resolve();
|
|
638
663
|
});
|
|
@@ -640,30 +665,29 @@ var DataStore = class {
|
|
|
640
665
|
/** Saves the default data passed in the constructor synchronously to the in-memory cache and asynchronously to persistent storage */
|
|
641
666
|
async saveDefaultData() {
|
|
642
667
|
this.cachedData = this.defaultData;
|
|
643
|
-
const useEncoding = this.encodingEnabled();
|
|
644
668
|
await Promise.allSettled([
|
|
645
|
-
this.engine.setValue(`__ds-${this.id}-dat`, await this.engine.serializeData(this.defaultData,
|
|
669
|
+
this.engine.setValue(`__ds-${this.id}-dat`, await this.engine.serializeData(this.defaultData, this.encodingEnabled())),
|
|
646
670
|
this.engine.setValue(`__ds-${this.id}-ver`, this.formatVersion),
|
|
647
|
-
this.engine.setValue(`__ds-${this.id}-
|
|
671
|
+
this.engine.setValue(`__ds-${this.id}-enf`, this.compressionFormat)
|
|
648
672
|
]);
|
|
649
673
|
}
|
|
650
674
|
/**
|
|
651
|
-
* Call this method to clear all persistently stored data associated with this DataStore instance.
|
|
675
|
+
* Call this method to clear all persistently stored data associated with this DataStore instance, including the storage container (if supported by the DataStoreEngine).
|
|
652
676
|
* The in-memory cache will be left untouched, so you may still access the data with {@linkcode getData()}
|
|
653
|
-
* Calling {@linkcode loadData()} or {@linkcode setData()} after this method was called will recreate persistent storage with the cached or default data.
|
|
654
|
-
*
|
|
655
|
-
* - ⚠️ This requires the additional directive `@grant GM.deleteValue` if the storageMethod is left as the default of `"GM"`
|
|
677
|
+
* Calling {@linkcode loadData()} or {@linkcode setData()} after this method was called will recreate persistent storage with the cached or default data.
|
|
656
678
|
*/
|
|
657
679
|
async deleteData() {
|
|
680
|
+
var _a, _b;
|
|
658
681
|
await Promise.allSettled([
|
|
659
682
|
this.engine.deleteValue(`__ds-${this.id}-dat`),
|
|
660
683
|
this.engine.deleteValue(`__ds-${this.id}-ver`),
|
|
661
|
-
this.engine.deleteValue(`__ds-${this.id}-
|
|
684
|
+
this.engine.deleteValue(`__ds-${this.id}-enf`)
|
|
662
685
|
]);
|
|
686
|
+
await ((_b = (_a = this.engine).deleteStorage) == null ? void 0 : _b.call(_a));
|
|
663
687
|
}
|
|
664
688
|
/** Returns whether encoding and decoding are enabled for this DataStore instance */
|
|
665
689
|
encodingEnabled() {
|
|
666
|
-
return Boolean(this.encodeData && this.decodeData);
|
|
690
|
+
return Boolean(this.encodeData && this.decodeData) && this.compressionFormat !== null || Boolean(this.compressionFormat);
|
|
667
691
|
}
|
|
668
692
|
//#region migrations
|
|
669
693
|
/**
|
|
@@ -697,7 +721,7 @@ var DataStore = class {
|
|
|
697
721
|
await Promise.allSettled([
|
|
698
722
|
this.engine.setValue(`__ds-${this.id}-dat`, await this.engine.serializeData(newData)),
|
|
699
723
|
this.engine.setValue(`__ds-${this.id}-ver`, lastFmtVer),
|
|
700
|
-
this.engine.setValue(`__ds-${this.id}-
|
|
724
|
+
this.engine.setValue(`__ds-${this.id}-enf`, this.compressionFormat)
|
|
701
725
|
]);
|
|
702
726
|
return this.cachedData = { ...newData };
|
|
703
727
|
}
|
|
@@ -708,19 +732,24 @@ var DataStore = class {
|
|
|
708
732
|
async migrateId(oldIds) {
|
|
709
733
|
const ids = Array.isArray(oldIds) ? oldIds : [oldIds];
|
|
710
734
|
await Promise.all(ids.map(async (id) => {
|
|
711
|
-
const data = await
|
|
712
|
-
|
|
713
|
-
|
|
735
|
+
const [data, fmtVer, isEncoded] = await (async () => {
|
|
736
|
+
const [d, f, e] = await Promise.all([
|
|
737
|
+
this.engine.getValue(`__ds-${id}-dat`, JSON.stringify(this.defaultData)),
|
|
738
|
+
this.engine.getValue(`__ds-${id}-ver`, NaN),
|
|
739
|
+
this.engine.getValue(`__ds-${id}-enf`, null)
|
|
740
|
+
]);
|
|
741
|
+
return [d, Number(f), Boolean(e) && String(e) !== "null"];
|
|
742
|
+
})();
|
|
714
743
|
if (data === void 0 || isNaN(fmtVer))
|
|
715
744
|
return;
|
|
716
745
|
const parsed = await this.engine.deserializeData(data, isEncoded);
|
|
717
746
|
await Promise.allSettled([
|
|
718
747
|
this.engine.setValue(`__ds-${this.id}-dat`, await this.engine.serializeData(parsed)),
|
|
719
748
|
this.engine.setValue(`__ds-${this.id}-ver`, fmtVer),
|
|
720
|
-
this.engine.setValue(`__ds-${this.id}-
|
|
749
|
+
this.engine.setValue(`__ds-${this.id}-enf`, this.compressionFormat),
|
|
721
750
|
this.engine.deleteValue(`__ds-${id}-dat`),
|
|
722
751
|
this.engine.deleteValue(`__ds-${id}-ver`),
|
|
723
|
-
this.engine.deleteValue(`__ds-${id}-
|
|
752
|
+
this.engine.deleteValue(`__ds-${id}-enf`)
|
|
724
753
|
]);
|
|
725
754
|
}));
|
|
726
755
|
}
|
|
@@ -730,7 +759,11 @@ var DataStore = class {
|
|
|
730
759
|
var DataStoreEngine = class {
|
|
731
760
|
dataStoreOptions;
|
|
732
761
|
// setDataStoreOptions() is called from inside the DataStore constructor to set this value
|
|
733
|
-
|
|
762
|
+
constructor(options) {
|
|
763
|
+
if (options)
|
|
764
|
+
this.dataStoreOptions = options;
|
|
765
|
+
}
|
|
766
|
+
/** Called by DataStore on creation, to pass its options. Only call this if you are using this instance standalone! */
|
|
734
767
|
setDataStoreOptions(dataStoreOptions) {
|
|
735
768
|
this.dataStoreOptions = dataStoreOptions;
|
|
736
769
|
}
|
|
@@ -738,6 +771,7 @@ var DataStoreEngine = class {
|
|
|
738
771
|
/** Serializes the given object to a string, optionally encoded with `options.encodeData` if {@linkcode useEncoding} is set to true */
|
|
739
772
|
async serializeData(data, useEncoding) {
|
|
740
773
|
var _a, _b, _c, _d, _e;
|
|
774
|
+
this.ensureDataStoreOptions();
|
|
741
775
|
const stringData = JSON.stringify(data);
|
|
742
776
|
if (!useEncoding || !((_a = this.dataStoreOptions) == null ? void 0 : _a.encodeData) || !((_b = this.dataStoreOptions) == null ? void 0 : _b.decodeData))
|
|
743
777
|
return stringData;
|
|
@@ -749,12 +783,20 @@ var DataStoreEngine = class {
|
|
|
749
783
|
/** Deserializes the given string to a JSON object, optionally decoded with `options.decodeData` if {@linkcode useEncoding} is set to true */
|
|
750
784
|
async deserializeData(data, useEncoding) {
|
|
751
785
|
var _a, _b, _c;
|
|
786
|
+
this.ensureDataStoreOptions();
|
|
752
787
|
let decRes = ((_a = this.dataStoreOptions) == null ? void 0 : _a.decodeData) && useEncoding ? (_c = (_b = this.dataStoreOptions.decodeData) == null ? void 0 : _b[1]) == null ? void 0 : _c.call(_b, data) : void 0;
|
|
753
788
|
if (decRes instanceof Promise)
|
|
754
789
|
decRes = await decRes;
|
|
755
790
|
return JSON.parse(decRes ?? data);
|
|
756
791
|
}
|
|
757
792
|
//#region misc api
|
|
793
|
+
/** Throws an error if the DataStoreOptions are not set or invalid */
|
|
794
|
+
ensureDataStoreOptions() {
|
|
795
|
+
if (!this.dataStoreOptions)
|
|
796
|
+
throw new DatedError("DataStoreEngine must be initialized with DataStore options before use. If you are using this instance standalone, set them in the constructor or call `setDataStoreOptions()` with the DataStore options.");
|
|
797
|
+
if (!this.dataStoreOptions.id)
|
|
798
|
+
throw new DatedError("DataStoreEngine must be initialized with a valid DataStore ID");
|
|
799
|
+
}
|
|
758
800
|
/**
|
|
759
801
|
* Copies a JSON-compatible object and loses all its internal references in the process.
|
|
760
802
|
* Uses [`structuredClone()`](https://developer.mozilla.org/en-US/docs/Web/API/structuredClone) if available, otherwise falls back to `JSON.parse(JSON.stringify(obj))`.
|
|
@@ -773,11 +815,11 @@ var BrowserStorageEngine = class extends DataStoreEngine {
|
|
|
773
815
|
/**
|
|
774
816
|
* Creates an instance of `BrowserStorageEngine`.
|
|
775
817
|
*
|
|
776
|
-
* ⚠️ Requires a DOM environment
|
|
777
|
-
* ⚠️ Don't reuse
|
|
818
|
+
* - ⚠️ Requires a DOM environment
|
|
819
|
+
* - ⚠️ Don't reuse engines across multiple {@linkcode DataStore} instances
|
|
778
820
|
*/
|
|
779
821
|
constructor(options) {
|
|
780
|
-
super();
|
|
822
|
+
super(options == null ? void 0 : options.dataStoreOptions);
|
|
781
823
|
this.options = {
|
|
782
824
|
type: "localStorage",
|
|
783
825
|
...options
|
|
@@ -809,11 +851,11 @@ var FileStorageEngine = class extends DataStoreEngine {
|
|
|
809
851
|
/**
|
|
810
852
|
* Creates an instance of `FileStorageEngine`.
|
|
811
853
|
*
|
|
812
|
-
* ⚠️ Requires Node.js or Deno with Node compatibility (v1.31+)
|
|
813
|
-
* ⚠️ Don't reuse
|
|
854
|
+
* - ⚠️ Requires Node.js or Deno with Node compatibility (v1.31+)
|
|
855
|
+
* - ⚠️ Don't reuse engines across multiple {@linkcode DataStore} instances
|
|
814
856
|
*/
|
|
815
857
|
constructor(options) {
|
|
816
|
-
super();
|
|
858
|
+
super(options == null ? void 0 : options.dataStoreOptions);
|
|
817
859
|
this.options = {
|
|
818
860
|
filePath: (id) => `.ds-${id}`,
|
|
819
861
|
...options
|
|
@@ -822,30 +864,32 @@ var FileStorageEngine = class extends DataStoreEngine {
|
|
|
822
864
|
//#region json file
|
|
823
865
|
/** Reads the file contents */
|
|
824
866
|
async readFile() {
|
|
825
|
-
var _a, _b, _c;
|
|
867
|
+
var _a, _b, _c, _d;
|
|
868
|
+
this.ensureDataStoreOptions();
|
|
826
869
|
try {
|
|
827
870
|
if (!fs)
|
|
828
|
-
fs = (await import("fs/promises")).default;
|
|
871
|
+
fs = (_a = await import("fs/promises")) == null ? void 0 : _a.default;
|
|
829
872
|
if (!fs)
|
|
830
873
|
throw new DatedError("FileStorageEngine requires Node.js or Deno with Node compatibility (v1.31+)", { cause: new Error("'node:fs/promises' module not available") });
|
|
831
874
|
const path = typeof this.options.filePath === "string" ? this.options.filePath : this.options.filePath(this.dataStoreOptions.id);
|
|
832
875
|
const data = await fs.readFile(path, "utf-8");
|
|
833
|
-
return data ? JSON.parse(await ((
|
|
876
|
+
return data ? JSON.parse(await ((_d = (_c = (_b = this.dataStoreOptions) == null ? void 0 : _b.decodeData) == null ? void 0 : _c[1]) == null ? void 0 : _d.call(_c, data)) ?? data) : void 0;
|
|
834
877
|
} catch {
|
|
835
878
|
return void 0;
|
|
836
879
|
}
|
|
837
880
|
}
|
|
838
881
|
/** Overwrites the file contents */
|
|
839
882
|
async writeFile(data) {
|
|
840
|
-
var _a, _b, _c;
|
|
883
|
+
var _a, _b, _c, _d;
|
|
884
|
+
this.ensureDataStoreOptions();
|
|
841
885
|
try {
|
|
842
886
|
if (!fs)
|
|
843
|
-
fs = (await import("fs/promises")).default;
|
|
887
|
+
fs = (_a = await import("fs/promises")) == null ? void 0 : _a.default;
|
|
844
888
|
if (!fs)
|
|
845
889
|
throw new DatedError("FileStorageEngine requires Node.js or Deno with Node compatibility (v1.31+)", { cause: new Error("'node:fs/promises' module not available") });
|
|
846
890
|
const path = typeof this.options.filePath === "string" ? this.options.filePath : this.options.filePath(this.dataStoreOptions.id);
|
|
847
|
-
await fs.mkdir(path.slice(0, path.lastIndexOf("/")), { recursive: true });
|
|
848
|
-
await fs.writeFile(path, await ((
|
|
891
|
+
await fs.mkdir(path.slice(0, path.lastIndexOf(path.includes("/") ? "/" : "\\")), { recursive: true });
|
|
892
|
+
await fs.writeFile(path, await ((_d = (_c = (_b = this.dataStoreOptions) == null ? void 0 : _b.encodeData) == null ? void 0 : _c[1]) == null ? void 0 : _d.call(_c, JSON.stringify(data))) ?? JSON.stringify(data, void 0, 2), "utf-8");
|
|
849
893
|
} catch (err) {
|
|
850
894
|
console.error("Error writing file:", err);
|
|
851
895
|
}
|
|
@@ -879,6 +923,21 @@ var FileStorageEngine = class extends DataStoreEngine {
|
|
|
879
923
|
delete data[name];
|
|
880
924
|
await this.writeFile(data);
|
|
881
925
|
}
|
|
926
|
+
/** Deletes the file that contains the data of this DataStore. */
|
|
927
|
+
async deleteStorage() {
|
|
928
|
+
var _a;
|
|
929
|
+
this.ensureDataStoreOptions();
|
|
930
|
+
try {
|
|
931
|
+
if (!fs)
|
|
932
|
+
fs = (_a = await import("fs/promises")) == null ? void 0 : _a.default;
|
|
933
|
+
if (!fs)
|
|
934
|
+
throw new DatedError("FileStorageEngine requires Node.js or Deno with Node compatibility (v1.31+)", { cause: new Error("'node:fs/promises' module not available") });
|
|
935
|
+
const path = typeof this.options.filePath === "string" ? this.options.filePath : this.options.filePath(this.dataStoreOptions.id);
|
|
936
|
+
await fs.unlink(path);
|
|
937
|
+
} catch (err) {
|
|
938
|
+
console.error("Error deleting file:", err);
|
|
939
|
+
}
|
|
940
|
+
}
|
|
882
941
|
};
|
|
883
942
|
|
|
884
943
|
// lib/DataStoreSerializer.ts
|
|
@@ -906,14 +965,16 @@ var DataStoreSerializer = class _DataStoreSerializer {
|
|
|
906
965
|
* @param stringified Whether to return the result as a string or as an array of `SerializedDataStore` objects
|
|
907
966
|
*/
|
|
908
967
|
async serializePartial(stores, useEncoding = true, stringified = true) {
|
|
968
|
+
var _a;
|
|
909
969
|
const serData = [];
|
|
910
970
|
for (const storeInst of this.stores.filter((s) => typeof stores === "function" ? stores(s.id) : stores.includes(s.id))) {
|
|
911
|
-
const
|
|
971
|
+
const encoded = Boolean(useEncoding && storeInst.encodingEnabled() && ((_a = storeInst.encodeData) == null ? void 0 : _a[1]));
|
|
972
|
+
const data = encoded ? await storeInst.encodeData[1](JSON.stringify(storeInst.getData())) : JSON.stringify(storeInst.getData());
|
|
912
973
|
serData.push({
|
|
913
974
|
id: storeInst.id,
|
|
914
975
|
data,
|
|
915
976
|
formatVersion: storeInst.formatVersion,
|
|
916
|
-
encoded
|
|
977
|
+
encoded,
|
|
917
978
|
checksum: this.options.addChecksum ? await this.calcChecksum(data) : void 0
|
|
918
979
|
});
|
|
919
980
|
}
|
|
@@ -1037,6 +1098,7 @@ var NanoEmitter = class {
|
|
|
1037
1098
|
...options
|
|
1038
1099
|
};
|
|
1039
1100
|
}
|
|
1101
|
+
//#region on
|
|
1040
1102
|
/**
|
|
1041
1103
|
* Subscribes to an event and calls the callback when it's emitted.
|
|
1042
1104
|
* @param event The event to subscribe to. Use `as "_"` in case your event names aren't thoroughly typed (like when using a template literal, e.g. \`event-${val}\` as "_")
|
|
@@ -1070,6 +1132,7 @@ var NanoEmitter = class {
|
|
|
1070
1132
|
this.eventUnsubscribes.push(unsub);
|
|
1071
1133
|
return unsubProxy;
|
|
1072
1134
|
}
|
|
1135
|
+
//#region once
|
|
1073
1136
|
/**
|
|
1074
1137
|
* Subscribes to an event and calls the callback or resolves the Promise only once when it's emitted.
|
|
1075
1138
|
* @param event The event to subscribe to. Use `as "_"` in case your event names aren't thoroughly typed (like when using a template literal, e.g. \`event-${val}\` as "_")
|
|
@@ -1100,9 +1163,90 @@ var NanoEmitter = class {
|
|
|
1100
1163
|
this.eventUnsubscribes.push(unsub);
|
|
1101
1164
|
});
|
|
1102
1165
|
}
|
|
1166
|
+
//#region onMulti
|
|
1167
|
+
/**
|
|
1168
|
+
* Allows subscribing to multiple events and calling the callback only when one of, all of, or a subset of the events are emitted, either continuously or only once.
|
|
1169
|
+
* @param options An object or array of objects with the following properties:
|
|
1170
|
+
* `callback` (required) is the function that will be called when the conditions are met.
|
|
1171
|
+
*
|
|
1172
|
+
* Set `once` to true to call the callback only once for the first event (or set of events) that match the criteria, then stop listening.
|
|
1173
|
+
* If `signal` is provided, the subscription will be aborted when the given signal is aborted.
|
|
1174
|
+
*
|
|
1175
|
+
* If `oneOf` is used, the callback will be called when any of the matching events are emitted.
|
|
1176
|
+
* If `allOf` is used, the callback will be called after all of the matching events are emitted at least once, then any time any of them are emitted.
|
|
1177
|
+
* You may use a combination of the above two options, but at least one of them must be provided.
|
|
1178
|
+
*
|
|
1179
|
+
* @returns Returns a function that can be called to unsubscribe all listeners created by this call. Alternatively, pass an `AbortSignal` to all options objects to achieve the same effect or for finer control.
|
|
1180
|
+
*/
|
|
1181
|
+
onMulti(options) {
|
|
1182
|
+
const allUnsubs = [];
|
|
1183
|
+
const unsubAll = () => {
|
|
1184
|
+
for (const unsub of allUnsubs)
|
|
1185
|
+
unsub();
|
|
1186
|
+
allUnsubs.splice(0, allUnsubs.length);
|
|
1187
|
+
this.eventUnsubscribes = this.eventUnsubscribes.filter((u) => !allUnsubs.includes(u));
|
|
1188
|
+
};
|
|
1189
|
+
for (const opts of Array.isArray(options) ? options : [options]) {
|
|
1190
|
+
const optsWithDefaults = {
|
|
1191
|
+
allOf: [],
|
|
1192
|
+
oneOf: [],
|
|
1193
|
+
once: false,
|
|
1194
|
+
...opts
|
|
1195
|
+
};
|
|
1196
|
+
const {
|
|
1197
|
+
oneOf,
|
|
1198
|
+
allOf,
|
|
1199
|
+
once,
|
|
1200
|
+
signal,
|
|
1201
|
+
callback
|
|
1202
|
+
} = optsWithDefaults;
|
|
1203
|
+
if (signal == null ? void 0 : signal.aborted)
|
|
1204
|
+
return unsubAll;
|
|
1205
|
+
const curEvtUnsubs = [];
|
|
1206
|
+
const checkUnsubAllEvt = (force = false) => {
|
|
1207
|
+
if (!(signal == null ? void 0 : signal.aborted) && !force)
|
|
1208
|
+
return;
|
|
1209
|
+
for (const unsub of curEvtUnsubs)
|
|
1210
|
+
unsub();
|
|
1211
|
+
curEvtUnsubs.splice(0, curEvtUnsubs.length);
|
|
1212
|
+
this.eventUnsubscribes = this.eventUnsubscribes.filter((u) => !curEvtUnsubs.includes(u));
|
|
1213
|
+
};
|
|
1214
|
+
for (const event of oneOf) {
|
|
1215
|
+
const unsub = this.events.on(event, (...args) => {
|
|
1216
|
+
checkUnsubAllEvt();
|
|
1217
|
+
callback(event, ...args);
|
|
1218
|
+
if (once)
|
|
1219
|
+
checkUnsubAllEvt(true);
|
|
1220
|
+
});
|
|
1221
|
+
curEvtUnsubs.push(unsub);
|
|
1222
|
+
}
|
|
1223
|
+
const allOfEmitted = /* @__PURE__ */ new Set();
|
|
1224
|
+
const checkAllOf = (event, ...args) => {
|
|
1225
|
+
checkUnsubAllEvt();
|
|
1226
|
+
allOfEmitted.add(event);
|
|
1227
|
+
if (allOfEmitted.size === allOf.length) {
|
|
1228
|
+
callback(event, ...args);
|
|
1229
|
+
if (once)
|
|
1230
|
+
checkUnsubAllEvt(true);
|
|
1231
|
+
}
|
|
1232
|
+
};
|
|
1233
|
+
for (const event of allOf) {
|
|
1234
|
+
const unsub = this.events.on(event, (...args) => {
|
|
1235
|
+
checkUnsubAllEvt();
|
|
1236
|
+
checkAllOf(event, ...args);
|
|
1237
|
+
});
|
|
1238
|
+
curEvtUnsubs.push(unsub);
|
|
1239
|
+
}
|
|
1240
|
+
if (oneOf.length === 0 && allOf.length === 0)
|
|
1241
|
+
throw new TypeError("NanoEmitter.onMulti(): Either `oneOf` or `allOf` or both must be provided in the options");
|
|
1242
|
+
allUnsubs.push(() => checkUnsubAllEvt(true));
|
|
1243
|
+
}
|
|
1244
|
+
return unsubAll;
|
|
1245
|
+
}
|
|
1246
|
+
//#region emit
|
|
1103
1247
|
/**
|
|
1104
1248
|
* Emits an event on this instance.
|
|
1105
|
-
* ⚠️ Needs `publicEmit` to be set to true in the NanoEmitter constructor or super() call!
|
|
1249
|
+
* - ⚠️ Needs `publicEmit` to be set to true in the NanoEmitter constructor or super() call!
|
|
1106
1250
|
* @param event The event to emit
|
|
1107
1251
|
* @param args The arguments to pass to the event listeners
|
|
1108
1252
|
* @returns Returns true if `publicEmit` is true and the event was emitted successfully
|
|
@@ -1114,6 +1258,7 @@ var NanoEmitter = class {
|
|
|
1114
1258
|
}
|
|
1115
1259
|
return false;
|
|
1116
1260
|
}
|
|
1261
|
+
//#region unsubscribeAll
|
|
1117
1262
|
/** Unsubscribes all event listeners from this instance */
|
|
1118
1263
|
unsubscribeAll() {
|
|
1119
1264
|
for (const unsub of this.eventUnsubscribes)
|