tiny-essentials 1.19.2 → 1.19.3
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/v1/TinyEssentials.js +109 -21
- package/dist/v1/TinyEssentials.min.js +1 -1
- package/dist/v1/TinyLocalStorage.js +109 -21
- package/dist/v1/TinyLocalStorage.min.js +1 -1
- package/dist/v1/TinyUploadClicker.js +109 -21
- package/dist/v1/TinyUploadClicker.min.js +1 -1
- package/dist/v1/libs/TinyLocalStorage.cjs +109 -21
- package/dist/v1/libs/TinyLocalStorage.d.mts +29 -0
- package/dist/v1/libs/TinyLocalStorage.mjs +97 -21
- package/docs/v1/libs/TinyLocalStorage.md +53 -0
- package/package.json +1 -1
|
@@ -19272,6 +19272,12 @@ class TinyLocalStorage {
|
|
|
19272
19272
|
/** @type {Storage} */
|
|
19273
19273
|
#localStorage = window.localStorage;
|
|
19274
19274
|
|
|
19275
|
+
/** @type {string|null} */
|
|
19276
|
+
#dbKey = null;
|
|
19277
|
+
|
|
19278
|
+
/** @type {number} */
|
|
19279
|
+
#version = 0;
|
|
19280
|
+
|
|
19275
19281
|
/** @type {(ev: StorageEvent) => any} */
|
|
19276
19282
|
#storageEvent = (ev) => this.emit('storage', ev);
|
|
19277
19283
|
|
|
@@ -19279,11 +19285,84 @@ class TinyLocalStorage {
|
|
|
19279
19285
|
* Initializes the TinyLocalStorage instance and sets up cross-tab sync.
|
|
19280
19286
|
*
|
|
19281
19287
|
* Adds listener for the native `storage` event to support tab synchronization.
|
|
19288
|
+
* @param {string} [dbName] - Unique database name.
|
|
19282
19289
|
*/
|
|
19283
|
-
constructor() {
|
|
19290
|
+
constructor(dbName) {
|
|
19291
|
+
if (typeof dbName !== 'undefined' && typeof dbName !== 'string')
|
|
19292
|
+
throw new TypeError('TinyLocalStorage: dbName must be a string if provided.');
|
|
19293
|
+
if (typeof dbName === 'string') this.#dbKey = `LSDB::${dbName}`;
|
|
19284
19294
|
window.addEventListener('storage', this.#storageEvent);
|
|
19285
19295
|
}
|
|
19286
19296
|
|
|
19297
|
+
/**
|
|
19298
|
+
* Validates that a given key does not conflict with internal database keys.
|
|
19299
|
+
*
|
|
19300
|
+
* This method is used to prevent accidental overwriting of reserved `LSDB::` keys
|
|
19301
|
+
* in `localStorage`, which are used internally by TinyLocalStorage for versioning
|
|
19302
|
+
* and data management.
|
|
19303
|
+
*
|
|
19304
|
+
* @param {string} name - The key to validate before writing to localStorage.
|
|
19305
|
+
* @throws {Error} If the key starts with `LSDB::`.
|
|
19306
|
+
*/
|
|
19307
|
+
#isProtectedDbKey(name) {
|
|
19308
|
+
if (typeof name === 'string' && name.startsWith('LSDB::'))
|
|
19309
|
+
throw new Error(`TinyLocalStorage: Key "${name}" may conflict with reserved dbKeys.`);
|
|
19310
|
+
}
|
|
19311
|
+
|
|
19312
|
+
/**
|
|
19313
|
+
* Updates the version of the storage and triggers migration if needed.
|
|
19314
|
+
*
|
|
19315
|
+
* @param {number} version - Desired version of the database.
|
|
19316
|
+
* @param {(oldVersion: number, newVersion: number) => void} onUpgrade - Callback to perform migration logic.
|
|
19317
|
+
* @throws {Error} If the database key has not been initialized.
|
|
19318
|
+
* @throws {TypeError} If `version` is not a valid positive number.
|
|
19319
|
+
* @throws {TypeError} If `onUpgrade` is not a function.
|
|
19320
|
+
*/
|
|
19321
|
+
updateStorageVersion(version, onUpgrade) {
|
|
19322
|
+
if (typeof this.#dbKey !== 'string')
|
|
19323
|
+
throw new Error(
|
|
19324
|
+
'TinyLocalStorage: Database key is not initialized. Set a valid dbName in the constructor.',
|
|
19325
|
+
);
|
|
19326
|
+
if (typeof version !== 'number' || Number.isNaN(version) || version < 1)
|
|
19327
|
+
throw new TypeError('TinyLocalStorage: version must be a positive number.');
|
|
19328
|
+
if (typeof onUpgrade !== 'function')
|
|
19329
|
+
throw new TypeError('TinyLocalStorage: onUpgrade must be a function.');
|
|
19330
|
+
|
|
19331
|
+
// @ts-ignore
|
|
19332
|
+
const savedVersion = parseInt(localStorage.getItem(this.#dbKey), 10) || 0;
|
|
19333
|
+
if (typeof savedVersion !== 'number' || Number.isNaN(savedVersion) || savedVersion < 0)
|
|
19334
|
+
throw new TypeError('TinyLocalStorage: saved version in localStorage is not a valid number.');
|
|
19335
|
+
|
|
19336
|
+
if (version < savedVersion)
|
|
19337
|
+
throw new Error(
|
|
19338
|
+
`TinyLocalStorage: Cannot downgrade database version from ${savedVersion} to ${version}.`,
|
|
19339
|
+
);
|
|
19340
|
+
|
|
19341
|
+
if (version > savedVersion) {
|
|
19342
|
+
onUpgrade(savedVersion, version);
|
|
19343
|
+
localStorage.setItem(this.#dbKey, String(version));
|
|
19344
|
+
this.#version = version;
|
|
19345
|
+
}
|
|
19346
|
+
}
|
|
19347
|
+
|
|
19348
|
+
/**
|
|
19349
|
+
* Gets the current database key used in localStorage.
|
|
19350
|
+
*
|
|
19351
|
+
* @returns {string|null} The database key, or null if not set.
|
|
19352
|
+
*/
|
|
19353
|
+
getDbKey() {
|
|
19354
|
+
return this.#dbKey;
|
|
19355
|
+
}
|
|
19356
|
+
|
|
19357
|
+
/**
|
|
19358
|
+
* Gets the current version of the database.
|
|
19359
|
+
*
|
|
19360
|
+
* @returns {number} The current version number.
|
|
19361
|
+
*/
|
|
19362
|
+
getVersion() {
|
|
19363
|
+
return this.#version;
|
|
19364
|
+
}
|
|
19365
|
+
|
|
19287
19366
|
/**
|
|
19288
19367
|
* Defines a custom storage interface (e.g. `sessionStorage`).
|
|
19289
19368
|
*
|
|
@@ -19291,7 +19370,7 @@ class TinyLocalStorage {
|
|
|
19291
19370
|
*/
|
|
19292
19371
|
setLocalStorage(localstorage) {
|
|
19293
19372
|
if (!(localstorage instanceof Storage))
|
|
19294
|
-
throw new
|
|
19373
|
+
throw new TypeError('Argument must be a valid instance of Storage.');
|
|
19295
19374
|
this.#localStorage = localstorage;
|
|
19296
19375
|
}
|
|
19297
19376
|
|
|
@@ -19313,7 +19392,7 @@ class TinyLocalStorage {
|
|
|
19313
19392
|
*/
|
|
19314
19393
|
#setJson(name, data) {
|
|
19315
19394
|
if (typeof name !== 'string' || !name.length)
|
|
19316
|
-
throw new
|
|
19395
|
+
throw new TypeError('Key must be a non-empty string.');
|
|
19317
19396
|
return TinyLocalStorage.encodeSpecialJson(data);
|
|
19318
19397
|
}
|
|
19319
19398
|
|
|
@@ -19326,13 +19405,14 @@ class TinyLocalStorage {
|
|
|
19326
19405
|
* @param {LocalStorageJsonValue} data - The data to be serialized and stored.
|
|
19327
19406
|
*/
|
|
19328
19407
|
setJson(name, data) {
|
|
19408
|
+
this.#isProtectedDbKey(name);
|
|
19329
19409
|
if (
|
|
19330
19410
|
!isJsonObject(data) &&
|
|
19331
19411
|
!Array.isArray(data) &&
|
|
19332
19412
|
!(data instanceof Map) &&
|
|
19333
19413
|
!(data instanceof Set)
|
|
19334
19414
|
) {
|
|
19335
|
-
throw new
|
|
19415
|
+
throw new TypeError('The storage value is not a valid JSON-compatible structure.');
|
|
19336
19416
|
}
|
|
19337
19417
|
const encoded = this.#setJson(name, data);
|
|
19338
19418
|
this.emit('setJson', name, data);
|
|
@@ -19350,7 +19430,7 @@ class TinyLocalStorage {
|
|
|
19350
19430
|
*/
|
|
19351
19431
|
#getJson(name, defaultData) {
|
|
19352
19432
|
if (typeof name !== 'string' || !name.length)
|
|
19353
|
-
throw new
|
|
19433
|
+
throw new TypeError('Key must be a non-empty string.');
|
|
19354
19434
|
|
|
19355
19435
|
const raw = this.#localStorage.getItem(name);
|
|
19356
19436
|
const fallbackTypes = {
|
|
@@ -19404,7 +19484,8 @@ class TinyLocalStorage {
|
|
|
19404
19484
|
* @param {Date} data
|
|
19405
19485
|
*/
|
|
19406
19486
|
setDate(name, data) {
|
|
19407
|
-
|
|
19487
|
+
this.#isProtectedDbKey(name);
|
|
19488
|
+
if (!(data instanceof Date)) throw new TypeError('Value must be a Date.');
|
|
19408
19489
|
const encoded = this.#setJson(name, data);
|
|
19409
19490
|
this.emit('setDate', name, data);
|
|
19410
19491
|
return this.#localStorage.setItem(name, JSON.stringify(encoded));
|
|
@@ -19426,7 +19507,8 @@ class TinyLocalStorage {
|
|
|
19426
19507
|
* @param {RegExp} data
|
|
19427
19508
|
*/
|
|
19428
19509
|
setRegExp(name, data) {
|
|
19429
|
-
|
|
19510
|
+
this.#isProtectedDbKey(name);
|
|
19511
|
+
if (!(data instanceof RegExp)) throw new TypeError('Value must be a RegExp.');
|
|
19430
19512
|
const encoded = this.#setJson(name, data);
|
|
19431
19513
|
this.emit('setRegExp', name, data);
|
|
19432
19514
|
return this.#localStorage.setItem(name, JSON.stringify(encoded));
|
|
@@ -19448,7 +19530,8 @@ class TinyLocalStorage {
|
|
|
19448
19530
|
* @param {bigint} data
|
|
19449
19531
|
*/
|
|
19450
19532
|
setBigInt(name, data) {
|
|
19451
|
-
|
|
19533
|
+
this.#isProtectedDbKey(name);
|
|
19534
|
+
if (typeof data !== 'bigint') throw new TypeError('Value must be a BigInt.');
|
|
19452
19535
|
const encoded = this.#setJson(name, data);
|
|
19453
19536
|
this.emit('setBigInt', name, data);
|
|
19454
19537
|
return this.#localStorage.setItem(name, JSON.stringify(encoded));
|
|
@@ -19471,7 +19554,8 @@ class TinyLocalStorage {
|
|
|
19471
19554
|
* @param {symbol} data
|
|
19472
19555
|
*/
|
|
19473
19556
|
setSymbol(name, data) {
|
|
19474
|
-
|
|
19557
|
+
this.#isProtectedDbKey(name);
|
|
19558
|
+
if (typeof data !== 'symbol') throw new TypeError('Value must be a Symbol.');
|
|
19475
19559
|
const encoded = this.#setJson(name, data);
|
|
19476
19560
|
this.emit('setSymbol', name, data);
|
|
19477
19561
|
return this.#localStorage.setItem(name, JSON.stringify(encoded));
|
|
@@ -19504,8 +19588,9 @@ class TinyLocalStorage {
|
|
|
19504
19588
|
* @param {any} data - The data to store.
|
|
19505
19589
|
*/
|
|
19506
19590
|
setItem(name, data) {
|
|
19591
|
+
this.#isProtectedDbKey(name);
|
|
19507
19592
|
if (typeof name !== 'string' || !name.length)
|
|
19508
|
-
throw new
|
|
19593
|
+
throw new TypeError('Key must be a non-empty string.');
|
|
19509
19594
|
this.emit('setItem', name, data);
|
|
19510
19595
|
return this.#localStorage.setItem(name, data);
|
|
19511
19596
|
}
|
|
@@ -19518,7 +19603,7 @@ class TinyLocalStorage {
|
|
|
19518
19603
|
*/
|
|
19519
19604
|
getItem(name) {
|
|
19520
19605
|
if (typeof name !== 'string' || !name.length)
|
|
19521
|
-
throw new
|
|
19606
|
+
throw new TypeError('Key must be a non-empty string.');
|
|
19522
19607
|
return this.#localStorage.getItem(name);
|
|
19523
19608
|
}
|
|
19524
19609
|
|
|
@@ -19529,9 +19614,10 @@ class TinyLocalStorage {
|
|
|
19529
19614
|
* @param {string} data - The string to store.
|
|
19530
19615
|
*/
|
|
19531
19616
|
setString(name, data) {
|
|
19617
|
+
this.#isProtectedDbKey(name);
|
|
19532
19618
|
if (typeof name !== 'string' || !name.length)
|
|
19533
|
-
throw new
|
|
19534
|
-
if (typeof data !== 'string') throw new
|
|
19619
|
+
throw new TypeError('Key must be a non-empty string.');
|
|
19620
|
+
if (typeof data !== 'string') throw new TypeError('Value must be a string.');
|
|
19535
19621
|
|
|
19536
19622
|
this.emit('setString', name, data);
|
|
19537
19623
|
return this.#localStorage.setItem(
|
|
@@ -19551,7 +19637,7 @@ class TinyLocalStorage {
|
|
|
19551
19637
|
*/
|
|
19552
19638
|
getString(name) {
|
|
19553
19639
|
if (typeof name !== 'string' || !name.length)
|
|
19554
|
-
throw new
|
|
19640
|
+
throw new TypeError('Key must be a non-empty string.');
|
|
19555
19641
|
let value = this.#localStorage.getItem(name);
|
|
19556
19642
|
try {
|
|
19557
19643
|
/** @type {{ value: string; __string__: boolean }} */
|
|
@@ -19573,9 +19659,10 @@ class TinyLocalStorage {
|
|
|
19573
19659
|
* @param {number} data - The number to store.
|
|
19574
19660
|
*/
|
|
19575
19661
|
setNumber(name, data) {
|
|
19662
|
+
this.#isProtectedDbKey(name);
|
|
19576
19663
|
if (typeof name !== 'string' || !name.length)
|
|
19577
|
-
throw new
|
|
19578
|
-
if (typeof data !== 'number') throw new
|
|
19664
|
+
throw new TypeError('Key must be a non-empty string.');
|
|
19665
|
+
if (typeof data !== 'number') throw new TypeError('Value must be a number.');
|
|
19579
19666
|
this.emit('setNumber', name, data);
|
|
19580
19667
|
return this.#localStorage.setItem(name, String(data));
|
|
19581
19668
|
}
|
|
@@ -19588,7 +19675,7 @@ class TinyLocalStorage {
|
|
|
19588
19675
|
*/
|
|
19589
19676
|
getNumber(name) {
|
|
19590
19677
|
if (typeof name !== 'string' || !name.length)
|
|
19591
|
-
throw new
|
|
19678
|
+
throw new TypeError('Key must be a non-empty string.');
|
|
19592
19679
|
|
|
19593
19680
|
/** @type {number|string|null} */
|
|
19594
19681
|
let number = this.#localStorage.getItem(name);
|
|
@@ -19607,9 +19694,10 @@ class TinyLocalStorage {
|
|
|
19607
19694
|
* @param {boolean} data - The boolean value to store.
|
|
19608
19695
|
*/
|
|
19609
19696
|
setBool(name, data) {
|
|
19697
|
+
this.#isProtectedDbKey(name);
|
|
19610
19698
|
if (typeof name !== 'string' || !name.length)
|
|
19611
|
-
throw new
|
|
19612
|
-
if (typeof data !== 'boolean') throw new
|
|
19699
|
+
throw new TypeError('Key must be a non-empty string.');
|
|
19700
|
+
if (typeof data !== 'boolean') throw new TypeError('Value must be a boolean.');
|
|
19613
19701
|
this.emit('setBool', name, data);
|
|
19614
19702
|
return this.#localStorage.setItem(name, String(data));
|
|
19615
19703
|
}
|
|
@@ -19622,7 +19710,7 @@ class TinyLocalStorage {
|
|
|
19622
19710
|
*/
|
|
19623
19711
|
getBool(name) {
|
|
19624
19712
|
if (typeof name !== 'string' || !name.length)
|
|
19625
|
-
throw new
|
|
19713
|
+
throw new TypeError('Key must be a non-empty string.');
|
|
19626
19714
|
|
|
19627
19715
|
const value = this.#localStorage.getItem(name);
|
|
19628
19716
|
if (typeof value === 'boolean') return value;
|
|
@@ -19641,7 +19729,7 @@ class TinyLocalStorage {
|
|
|
19641
19729
|
*/
|
|
19642
19730
|
removeItem(name) {
|
|
19643
19731
|
if (typeof name !== 'string' || !name.length)
|
|
19644
|
-
throw new
|
|
19732
|
+
throw new TypeError('Key must be a non-empty string.');
|
|
19645
19733
|
|
|
19646
19734
|
this.emit('removeItem', name);
|
|
19647
19735
|
return this.#localStorage.removeItem(name);
|